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