Geant4 Cross Reference |
1 // 1 // 2 // ******************************************* 2 // ******************************************************************** 3 // * License and Disclaimer 3 // * License and Disclaimer * 4 // * 4 // * * 5 // * The Geant4 software is copyright of th 5 // * The Geant4 software is copyright of the Copyright Holders of * 6 // * the Geant4 Collaboration. It is provided 6 // * the Geant4 Collaboration. It is provided under the terms and * 7 // * conditions of the Geant4 Software License 7 // * conditions of the Geant4 Software License, included in the file * 8 // * LICENSE and available at http://cern.ch/ 8 // * LICENSE and available at http://cern.ch/geant4/license . These * 9 // * include a list of copyright holders. 9 // * include a list of copyright holders. * 10 // * 10 // * * 11 // * Neither the authors of this software syst 11 // * Neither the authors of this software system, nor their employing * 12 // * institutes,nor the agencies providing fin 12 // * institutes,nor the agencies providing financial support for this * 13 // * work make any representation or warran 13 // * work make any representation or warranty, express or implied, * 14 // * regarding this software system or assum 14 // * regarding this software system or assume any liability for its * 15 // * use. Please see the license in the file 15 // * use. Please see the license in the file LICENSE and URL above * 16 // * for the full disclaimer and the limitatio 16 // * for the full disclaimer and the limitation of liability. * 17 // * 17 // * * 18 // * This code implementation is the result 18 // * This code implementation is the result of the scientific and * 19 // * technical work of the GEANT4 collaboratio 19 // * technical work of the GEANT4 collaboration. * 20 // * By using, copying, modifying or distri 20 // * By using, copying, modifying or distributing the software (or * 21 // * any work based on the software) you ag 21 // * any work based on the software) you agree to acknowledge its * 22 // * use in resulting scientific publicati 22 // * use in resulting scientific publications, and indicate your * 23 // * acceptance of all terms of the Geant4 Sof 23 // * acceptance of all terms of the Geant4 Software license. * 24 // ******************************************* 24 // ******************************************************************** 25 // 25 // 26 // 26 // 27 /// \file optical/wls/src/WLSSteppingAction.cc << 28 /// \brief Implementation of the WLSSteppingAc << 29 // 27 // 30 // << 31 #include "WLSSteppingAction.hh" << 32 28 >> 29 #include "G4Run.hh" >> 30 #include "G4Step.hh" >> 31 #include "G4Track.hh" >> 32 #include "G4StepPoint.hh" >> 33 #include "G4TrackStatus.hh" >> 34 #include "G4VPhysicalVolume.hh" >> 35 #include "G4ParticleDefinition.hh" >> 36 >> 37 #include "WLSSteppingAction.hh" 33 #include "WLSDetectorConstruction.hh" 38 #include "WLSDetectorConstruction.hh" 34 #include "WLSEventAction.hh" << 35 #include "WLSPhotonDetSD.hh" << 36 #include "WLSSteppingActionMessenger.hh" 39 #include "WLSSteppingActionMessenger.hh" >> 40 #include "WLSPhotonDetSD.hh" >> 41 >> 42 #include "G4ParticleTypes.hh" >> 43 37 #include "WLSUserTrackInformation.hh" 44 #include "WLSUserTrackInformation.hh" 38 45 39 #include "G4OpBoundaryProcess.hh" << 40 #include "G4OpticalPhoton.hh" << 41 #include "G4ProcessManager.hh" 46 #include "G4ProcessManager.hh" 42 #include "G4Run.hh" << 47 #include "G4OpBoundaryProcess.hh" >> 48 >> 49 #include "G4RunManager.hh" 43 #include "G4SDManager.hh" 50 #include "G4SDManager.hh" 44 #include "G4Step.hh" << 45 #include "G4StepPoint.hh" << 46 #include "G4SystemOfUnits.hh" << 47 #include "G4ThreeVector.hh" << 48 #include "G4Track.hh" << 49 #include "G4TrackStatus.hh" << 50 #include "G4UImanager.hh" 51 #include "G4UImanager.hh" 51 #include "G4VPhysicalVolume.hh" << 52 >> 53 #include "G4ThreeVector.hh" 52 #include "G4ios.hh" 54 #include "G4ios.hh" >> 55 #include <sstream> 53 56 54 // Purpose: Save relevant information into Use 57 // Purpose: Save relevant information into User Track Information 55 58 56 //....oooOO0OOooo........oooOO0OOooo........oo << 59 static const G4ThreeVector ZHat = G4ThreeVector(0.0,0.0,1.0); 57 60 58 WLSSteppingAction::WLSSteppingAction(WLSDetect << 61 G4int WLSSteppingAction::maxRndmSave = 10000; 59 : fDetector(detector), fEventAction(event) << 62 >> 63 WLSSteppingAction::WLSSteppingAction(WLSDetectorConstruction* DC) >> 64 : detector(DC) 60 { 65 { 61 fSteppingMessenger = new WLSSteppingActionMe << 66 steppingMessenger = new WLSSteppingActionMessenger(this); >> 67 >> 68 counterEnd = 0; >> 69 counterMid = 0; >> 70 bounceLimit = 100000; >> 71 62 ResetCounters(); 72 ResetCounters(); 63 } 73 } 64 74 65 //....oooOO0OOooo........oooOO0OOooo........oo << 66 << 67 WLSSteppingAction::~WLSSteppingAction() 75 WLSSteppingAction::~WLSSteppingAction() 68 { 76 { 69 delete fSteppingMessenger; << 77 delete steppingMessenger; 70 } 78 } 71 79 72 //....oooOO0OOooo........oooOO0OOooo........oo << 80 void WLSSteppingAction::SetBounceLimit(G4int i) {bounceLimit = i;} 73 << 81 G4int WLSSteppingAction::GetNumberOfBounces() {return counterBounce;} 74 void WLSSteppingAction::SetBounceLimit(G4int i << 82 G4int WLSSteppingAction::GetNumberOfClad1Bounces() {return counterClad1Bounce;} 75 { << 83 G4int WLSSteppingAction::GetNumberOfClad2Bounces() {return counterClad2Bounce;} 76 fBounceLimit = i; << 84 G4int WLSSteppingAction::GetNumberOfWLSBounces() {return counterWLSBounce;} >> 85 G4int WLSSteppingAction::ResetSuccessCounter() { >> 86 G4int temp = counterEnd; counterEnd = 0; return temp; 77 } 87 } 78 88 79 //....oooOO0OOooo........oooOO0OOooo........oo << 89 // save the random status into a sub-directory >> 90 // Pre: subDir must be empty or ended with "/" >> 91 inline void WLSSteppingAction::saveRandomStatus(G4String subDir) { >> 92 >> 93 // don't save if the maximum amount has been reached >> 94 if (WLSSteppingAction::maxRndmSave == 0) return; 80 95 81 G4int WLSSteppingAction::GetNumberOfBounces() << 96 G4RunManager* theRunManager = G4RunManager::GetRunManager(); 82 { << 97 G4String randomNumberStatusDir = theRunManager->GetRandomNumberStoreDir(); 83 return fCounterBounce; << 98 84 } << 99 G4String fileIn = randomNumberStatusDir + "currentEvent.rndm"; 85 100 86 //....oooOO0OOooo........oooOO0OOooo........oo << 101 std::ostringstream os; 87 102 88 G4int WLSSteppingAction::GetNumberOfClad1Bounc << 103 os << "run" << theRunManager->GetCurrentRun()->GetRunID() << "evt" 89 { << 104 << theRunManager->GetCurrentEvent()->GetEventID() << ".rndm" << '\0'; 90 return fCounterClad1Bounce; << 91 } << 92 << 93 //....oooOO0OOooo........oooOO0OOooo........oo << 94 105 95 G4int WLSSteppingAction::GetNumberOfClad2Bounc << 106 G4String fileOut = randomNumberStatusDir + subDir + os.str(); 96 { << 97 return fCounterClad2Bounce; << 98 } << 99 107 100 //....oooOO0OOooo........oooOO0OOooo........oo << 108 G4String copCmd = "/control/shell cp "+fileIn+" "+fileOut; >> 109 G4UImanager::GetUIpointer()->ApplyCommand(copCmd); 101 110 102 G4int WLSSteppingAction::GetNumberOfWLSBounces << 111 WLSSteppingAction::maxRndmSave--; 103 { << 104 return fCounterWLSBounce; << 105 } 112 } 106 113 107 //....oooOO0OOooo........oooOO0OOooo........oo << 114 void WLSSteppingAction::UpdateHistogramSuccess(G4StepPoint* ,G4Track* ) {} 108 115 109 G4int WLSSteppingAction::ResetSuccessCounter() << 116 void WLSSteppingAction::UpdateHistogramReflect(G4StepPoint* ,G4Track* ) {} 110 { << 117 111 G4int temp = fCounterEnd; << 118 void WLSSteppingAction::UpdateHistogramEscape(G4StepPoint* , G4Track* ) {} 112 fCounterEnd = 0; << 113 return temp; << 114 } << 115 119 116 //....oooOO0OOooo........oooOO0OOooo........oo << 120 void WLSSteppingAction::UpdateHistogramAbsorb(G4StepPoint* , G4Track* ) {} 117 121 118 void WLSSteppingAction::UserSteppingAction(con 122 void WLSSteppingAction::UserSteppingAction(const G4Step* theStep) 119 { 123 { 120 G4Track* theTrack = theStep->GetTrack(); 124 G4Track* theTrack = theStep->GetTrack(); 121 auto trackInformation = (WLSUserTrackInforma << 125 WLSUserTrackInformation* trackInformation 122 << 126 = (WLSUserTrackInformation*)theTrack->GetUserInformation(); 123 G4StepPoint* thePrePoint = theStep->GetPreSt << 127 >> 128 G4StepPoint* thePrePoint = theStep->GetPreStepPoint(); 124 G4StepPoint* thePostPoint = theStep->GetPost 129 G4StepPoint* thePostPoint = theStep->GetPostStepPoint(); 125 130 126 G4VPhysicalVolume* thePrePV = thePrePoint->G << 131 G4VPhysicalVolume* thePrePV = thePrePoint->GetPhysicalVolume(); 127 G4VPhysicalVolume* thePostPV = thePostPoint- 132 G4VPhysicalVolume* thePostPV = thePostPoint->GetPhysicalVolume(); 128 133 129 G4String thePrePVname = " "; << 134 G4String thePrePVname = " "; 130 G4String thePostPVname = " "; 135 G4String thePostPVname = " "; 131 136 132 if (thePostPV) { 137 if (thePostPV) { 133 thePrePVname = thePrePV->GetName(); << 138 thePrePVname = thePrePV->GetName(); 134 thePostPVname = thePostPV->GetName(); << 139 thePostPVname = thePostPV->GetName(); 135 } 140 } 136 141 137 // Recording data for start << 142 //Recording data for start 138 // static const G4ThreeVector ZHat = G4Three << 143 if (theTrack->GetParentID()==0) { 139 if (theTrack->GetParentID() == 0) { << 144 //This is a primary track 140 // This is a primary track << 145 if ( theTrack->GetCurrentStepNumber() == 1 ) { 141 if (theTrack->GetCurrentStepNumber() == 1) << 146 // G4double x = theTrack->GetVertexPosition().x(); 142 // G4double x = theTrack->GetVer << 147 // G4double y = theTrack->GetVertexPosition().y(); 143 // G4double y = theTrack->GetVer << 148 G4double z = theTrack->GetVertexPosition().z(); 144 // G4double z = theTrack->GetVer << 149 // G4double pz = theTrack->GetVertexMomentumDirection().z(); 145 // G4double pz = theTrack->GetVer << 150 initTheta = theTrack->GetVertexMomentumDirection().angle(ZHat); 146 // G4double fInitTheta = << 151 initZ = z; 147 // theTrack->Get << 152 } 148 } << 149 } 153 } 150 154 151 // Retrieve the status of the photon 155 // Retrieve the status of the photon 152 G4OpBoundaryProcessStatus theStatus = Undefi 156 G4OpBoundaryProcessStatus theStatus = Undefined; 153 157 154 static G4ThreadLocal G4ProcessManager* OpMan << 158 G4ProcessManager* OpManager = 155 G4OpticalPhoton::OpticalPhoton()->GetProce << 159 G4OpticalPhoton::OpticalPhoton()->GetProcessManager(); 156 160 157 if (OpManager) { 161 if (OpManager) { 158 G4int nproc = OpManager->GetPostStepProces << 162 G4int MAXofPostStepLoops = 159 G4ProcessVector* fPostStepDoItVector = OpM << 163 OpManager->GetPostStepProcessVector()->entries(); 160 << 164 G4ProcessVector* fPostStepDoItVector = 161 for (G4int i = 0; i < nproc; ++i) { << 165 OpManager->GetPostStepProcessVector(typeDoIt); 162 G4VProcess* fCurrentProcess = (*fPostSte << 166 163 fOpProcess = dynamic_cast<G4OpBoundaryPr << 167 for ( G4int i=0; i<MAXofPostStepLoops; i++) { 164 if (fOpProcess) { << 168 G4VProcess* fCurrentProcess = (*fPostStepDoItVector)[i]; 165 theStatus = fOpProcess->GetStatus(); << 169 opProcess = dynamic_cast<G4OpBoundaryProcess*>(fCurrentProcess); 166 break; << 170 if (opProcess) { theStatus = opProcess->GetStatus(); break;} 167 } << 171 } 168 } << 169 } 172 } 170 173 171 // Find the skewness of the ray at first cha 174 // Find the skewness of the ray at first change of boundary 172 if (fInitGamma == -1 << 175 if ( initGamma == -1 && 173 && (theStatus == TotalInternalReflection << 176 (theStatus == TotalInternalReflection 174 || theStatus == FresnelRefraction) << 177 || theStatus == FresnelReflection 175 && trackInformation->IsStatus(InsideOfFi << 178 || theStatus == FresnelRefraction) 176 { << 179 && trackInformation->isStatus(InsideOfFiber) ) { 177 G4double px = theTrack->GetVertexMomentumD << 178 G4double py = theTrack->GetVertexMomentumD << 179 G4double x = theTrack->GetPosition().x(); << 180 G4double y = theTrack->GetPosition().y(); << 181 180 182 fInitGamma = x * px + y * py; << 181 G4double px = theTrack->GetVertexMomentumDirection().x(); >> 182 G4double py = theTrack->GetVertexMomentumDirection().y(); >> 183 G4double x = theTrack->GetPosition().x(); >> 184 G4double y = theTrack->GetPosition().y(); 183 185 184 fInitGamma = fInitGamma / std::sqrt(px * p << 186 initGamma = x * px + y * py; 185 187 186 fInitGamma = std::acos(fInitGamma * rad); << 188 initGamma = initGamma / std::sqrt(px*px + py*py) / std::sqrt(x*x + y*y); 187 189 188 if (fInitGamma / deg > 90.0) { << 190 initGamma = std::acos(initGamma*rad); 189 fInitGamma = 180 * deg - fInitGamma; << 191 190 } << 192 if ( initGamma / deg > 90.0) { initGamma = 180 * deg - initGamma;} 191 } 193 } 192 // Record Photons that missed the photon det 194 // Record Photons that missed the photon detector but escaped from readout 193 if (!thePostPV && trackInformation->IsStatus << 195 if ( !thePostPV && trackInformation->isStatus(EscapedFromReadOut) ) { 194 // G4cout << "SteppingAction: status = Esc << 196 // UpdateHistogramSuccess(thePostPoint,theTrack); 195 fEventAction->AddEscaped(); << 197 ResetCounters(); 196 // UpdateHistogramSuccess(thePostPoint,the << 198 197 ResetCounters(); << 199 return; 198 << 199 return; << 200 } 200 } 201 201 202 // Assumed photons are originated at the fib 202 // Assumed photons are originated at the fiber OR 203 // the fiber is the first material the photo 203 // the fiber is the first material the photon hits 204 switch (theStatus) { 204 switch (theStatus) { 205 // Exiting the fiber << 205 206 case FresnelRefraction: << 206 // Exiting the fiber 207 case SameMaterial: << 207 case FresnelRefraction: 208 fEventAction->AddExiting(); << 208 case SameMaterial: 209 << 209 210 if (thePostPVname == "WLSFiber" || thePo << 210 G4bool isFiber; 211 if (trackInformation->IsStatus(Outside << 211 isFiber = thePostPVname == "WLSFiber" 212 trackInformation->AddStatusFlag(Insi << 212 || thePostPVname == "Clad1" 213 << 213 || thePostPVname == "Clad2"; 214 // Set the Exit flag when the photon r << 214 215 } << 215 if ( isFiber ) { 216 else if (trackInformation->IsStatus(Insi << 216 217 // EscapedFromReadOut if the z positio << 217 if (trackInformation->isStatus(OutsideOfFiber)) 218 if (theTrack->GetPosition().z() == fDe << 218 trackInformation->AddStatusFlag(InsideOfFiber); 219 trackInformation->AddStatusFlag(Esca << 219 220 fCounterEnd++; << 220 // Set the Exit flag when the photon refracted out of the fiber 221 fEventAction->AddEscapedEnd(); << 221 } else if (trackInformation->isStatus(InsideOfFiber)) { 222 } << 222 223 else // Escaped from side << 223 // EscapedFromReadOut if the z position is the same as fiber's end 224 { << 224 if (theTrack->GetPosition().z() == detector->GetWLSFiberEnd()) 225 trackInformation->AddStatusFlag(Esca << 225 { 226 trackInformation->SetExitPosition(th << 226 trackInformation->AddStatusFlag(EscapedFromReadOut); 227 // UpdateHistogramEscape(thePostPoi << 227 counterEnd++; >> 228 } >> 229 else // Escaped from side >> 230 { >> 231 trackInformation->AddStatusFlag(EscapedFromSide); >> 232 trackInformation->SetExitPosition(theTrack->GetPosition()); >> 233 >> 234 // UpdateHistogramEscape(thePostPoint,theTrack); >> 235 >> 236 counterMid++; >> 237 ResetCounters(); >> 238 } >> 239 >> 240 trackInformation->AddStatusFlag(OutsideOfFiber); >> 241 trackInformation->SetExitPosition(theTrack->GetPosition()); >> 242 >> 243 } >> 244 >> 245 return; >> 246 >> 247 // Internal Reflections >> 248 case TotalInternalReflection: >> 249 >> 250 // Kill the track if it's number of bounces exceeded the limit >> 251 if (bounceLimit > 0 && counterBounce >= bounceLimit) >> 252 { >> 253 theTrack->SetTrackStatus(fStopAndKill); >> 254 trackInformation->AddStatusFlag(murderee); >> 255 ResetCounters(); >> 256 G4cout << "\n Bounce Limit Exceeded" << G4endl; >> 257 return; >> 258 } >> 259 >> 260 case FresnelReflection: >> 261 >> 262 counterBounce++; >> 263 >> 264 if ( thePrePVname == "WLSFiber") counterWLSBounce++; >> 265 >> 266 else if ( thePrePVname == "Clad1") counterClad1Bounce++; >> 267 >> 268 else if ( thePrePVname == "Clad2") counterClad2Bounce++; >> 269 >> 270 // Determine if the photon has reflected off the read-out end >> 271 if (theTrack->GetPosition().z() == detector->GetWLSFiberEnd()) >> 272 { >> 273 if (!trackInformation->isStatus(ReflectedAtReadOut) && >> 274 trackInformation->isStatus(InsideOfFiber)) >> 275 { >> 276 trackInformation->AddStatusFlag(ReflectedAtReadOut); >> 277 >> 278 if (detector->IsPerfectFiber() && >> 279 theStatus == TotalInternalReflection) >> 280 { >> 281 theTrack->SetTrackStatus(fStopAndKill); >> 282 trackInformation->AddStatusFlag(murderee); >> 283 // UpdateHistogramReflect(thePostPoint,theTrack); >> 284 ResetCounters(); >> 285 return; >> 286 } >> 287 } >> 288 } >> 289 return; >> 290 >> 291 // Reflection of the mirror >> 292 case LambertianReflection: >> 293 case LobeReflection: >> 294 case SpikeReflection: >> 295 >> 296 // Check if it hits the mirror >> 297 if ( thePostPVname == "Mirror" ) >> 298 trackInformation->AddStatusFlag(ReflectedAtMirror); >> 299 >> 300 return; >> 301 >> 302 // Detected by a detector >> 303 case Detection: >> 304 >> 305 // Check if the photon hits the detector and process the hit if it does >> 306 if ( thePostPVname == "PhotonDet" ) { >> 307 >> 308 G4SDManager* SDman = G4SDManager::GetSDMpointer(); >> 309 G4String SDname="WLS/PhotonDet"; >> 310 WLSPhotonDetSD* mppcSD = >> 311 (WLSPhotonDetSD*)SDman->FindSensitiveDetector(SDname); >> 312 >> 313 if (mppcSD) mppcSD->ProcessHits_constStep(theStep,NULL); >> 314 >> 315 // Record Photons that escaped at the end >> 316 // if (trackInformation->isStatus(EscapedFromReadOut)) >> 317 // UpdateHistogramSuccess(thePostPoint,theTrack); 228 318 229 fCounterMid++; << 319 // Stop Tracking when it hits the detector's surface 230 fEventAction->AddEscapedMid(); << 231 ResetCounters(); 320 ResetCounters(); 232 } << 321 theTrack->SetTrackStatus(fStopAndKill); 233 322 234 trackInformation->AddStatusFlag(Outsid << 323 return; 235 trackInformation->SetExitPosition(theT << 324 } 236 } << 237 << 238 return; << 239 << 240 // Internal Reflections << 241 case TotalInternalReflection: << 242 << 243 fEventAction->AddTIR(); << 244 << 245 // Kill the track if it's number of boun << 246 if (fBounceLimit > 0 && fCounterBounce > << 247 theTrack->SetTrackStatus(fStopAndKill) << 248 trackInformation->AddStatusFlag(murder << 249 ResetCounters(); << 250 G4cout << "\n Bounce Limit Exceeded" < << 251 return; << 252 } << 253 break; << 254 << 255 case FresnelReflection: << 256 << 257 fCounterBounce++; << 258 fEventAction->AddBounce(); << 259 << 260 if (thePrePVname == "WLSFiber") { << 261 fCounterWLSBounce++; << 262 fEventAction->AddWLSBounce(); << 263 } << 264 else if (thePrePVname == "Clad1") { << 265 fCounterClad1Bounce++; << 266 fEventAction->AddClad1Bounce(); << 267 } << 268 else if (thePrePVname == "Clad2") { << 269 fCounterClad2Bounce++; << 270 fEventAction->AddClad1Bounce(); << 271 } << 272 << 273 // Determine if the photon has reflected << 274 if (theTrack->GetPosition().z() == fDete << 275 if (!trackInformation->IsStatus(Reflec << 276 && trackInformation->IsStatus(Insi << 277 { << 278 trackInformation->AddStatusFlag(Refl << 279 << 280 if (fDetector->IsPerfectFiber() && t << 281 theTrack->SetTrackStatus(fStopAndK << 282 trackInformation->AddStatusFlag(mu << 283 // UpdateHistogramReflect(thePostP << 284 ResetCounters(); << 285 return; << 286 } << 287 } << 288 } << 289 return; << 290 << 291 // Reflection off the mirror << 292 case LambertianReflection: << 293 case LobeReflection: << 294 case SpikeReflection: << 295 << 296 fEventAction->AddReflected(); << 297 // Check if it hits the mirror << 298 if (thePostPVname == "Mirror") { << 299 trackInformation->AddStatusFlag(Reflec << 300 fEventAction->AddMirror(); << 301 } << 302 return; << 303 << 304 // Detected by a detector << 305 case Detection: << 306 // Detected automatically with G4OpBound << 307 << 308 // Stop Tracking when it hits the detect << 309 ResetCounters(); << 310 theTrack->SetTrackStatus(fStopAndKill); << 311 return; << 312 325 313 default: << 326 break; 314 break; << 315 } << 316 327 >> 328 default: break; >> 329 >> 330 } >> 331 317 // Check for absorbed photons 332 // Check for absorbed photons 318 if (theTrack->GetTrackStatus() != fAlive && << 333 if (theTrack->GetTrackStatus() != fAlive && 319 // UpdateHistogramAbsorb(thePostPoint,theT << 334 trackInformation->isStatus(InsideOfFiber)) 320 ResetCounters(); << 335 { 321 return; << 336 // UpdateHistogramAbsorb(thePostPoint,theTrack); >> 337 ResetCounters(); >> 338 return; 322 } 339 } >> 340 323 } 341 } 324 342