Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-16 08:30:29

0001 //
0002 // ********************************************************************
0003 // * License and Disclaimer                                           *
0004 // *                                                                  *
0005 // * The  Geant4 software  is  copyright of the Copyright Holders  of *
0006 // * the Geant4 Collaboration.  It is provided  under  the terms  and *
0007 // * conditions of the Geant4 Software License,  included in the file *
0008 // * LICENSE and available at  http://cern.ch/geant4/license .  These *
0009 // * include a list of copyright holders.                             *
0010 // *                                                                  *
0011 // * Neither the authors of this software system, nor their employing *
0012 // * institutes,nor the agencies providing financial support for this *
0013 // * work  make  any representation or  warranty, express or implied, *
0014 // * regarding  this  software system or assume any liability for its *
0015 // * use.  Please see the license in the file  LICENSE  and URL above *
0016 // * for the full disclaimer and the limitation of liability.         *
0017 // *                                                                  *
0018 // * This  code  implementation is the result of  the  scientific and *
0019 // * technical work of the GEANT4 collaboration.                      *
0020 // * By using,  copying,  modifying or  distributing the software (or *
0021 // * any work based  on the software)  you  agree  to acknowledge its *
0022 // * use  in  resulting  scientific  publications,  and indicate your *
0023 // * acceptance of all terms of the Geant4 Software license.          *
0024 // ********************************************************************
0025 //
0026 /// \file WLSSteppingAction.cc
0027 /// \brief Implementation of the WLSSteppingAction class
0028 
0029 #include "WLSSteppingAction.hh"
0030 
0031 #include "WLSDetectorConstruction.hh"
0032 #include "WLSEventAction.hh"
0033 #include "WLSPhotonDetSD.hh"
0034 #include "WLSSteppingActionMessenger.hh"
0035 #include "WLSUserTrackInformation.hh"
0036 
0037 #include "G4OpBoundaryProcess.hh"
0038 #include "G4OpticalPhoton.hh"
0039 #include "G4ProcessManager.hh"
0040 #include "G4Run.hh"
0041 #include "G4SDManager.hh"
0042 #include "G4Step.hh"
0043 #include "G4StepPoint.hh"
0044 #include "G4SystemOfUnits.hh"
0045 #include "G4ThreeVector.hh"
0046 #include "G4Track.hh"
0047 #include "G4TrackStatus.hh"
0048 #include "G4UImanager.hh"
0049 #include "G4VPhysicalVolume.hh"
0050 #include "G4ios.hh"
0051 
0052 // Purpose: Save relevant information into User Track Information
0053 
0054 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0055 
0056 WLSSteppingAction::WLSSteppingAction(WLSDetectorConstruction* detector, WLSEventAction* event)
0057   : fDetector(detector), fEventAction(event)
0058 {
0059   fSteppingMessenger = new WLSSteppingActionMessenger(this);
0060   ResetCounters();
0061 }
0062 
0063 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0064 
0065 WLSSteppingAction::~WLSSteppingAction()
0066 {
0067   delete fSteppingMessenger;
0068 }
0069 
0070 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0071 
0072 void WLSSteppingAction::SetBounceLimit(G4int i)
0073 {
0074   fBounceLimit = i;
0075 }
0076 
0077 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0078 
0079 G4int WLSSteppingAction::GetNumberOfBounces()
0080 {
0081   return fCounterBounce;
0082 }
0083 
0084 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0085 
0086 G4int WLSSteppingAction::GetNumberOfClad1Bounces()
0087 {
0088   return fCounterClad1Bounce;
0089 }
0090 
0091 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0092 
0093 G4int WLSSteppingAction::GetNumberOfClad2Bounces()
0094 {
0095   return fCounterClad2Bounce;
0096 }
0097 
0098 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0099 
0100 G4int WLSSteppingAction::GetNumberOfWLSBounces()
0101 {
0102   return fCounterWLSBounce;
0103 }
0104 
0105 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0106 
0107 G4int WLSSteppingAction::ResetSuccessCounter()
0108 {
0109   G4int temp = fCounterEnd;
0110   fCounterEnd = 0;
0111   return temp;
0112 }
0113 
0114 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0115 
0116 void WLSSteppingAction::UserSteppingAction(const G4Step* theStep)
0117 {
0118   G4Track* theTrack = theStep->GetTrack();
0119   auto trackInformation = (WLSUserTrackInformation*)theTrack->GetUserInformation();
0120 
0121   G4StepPoint* thePrePoint = theStep->GetPreStepPoint();
0122   G4StepPoint* thePostPoint = theStep->GetPostStepPoint();
0123 
0124   G4VPhysicalVolume* thePrePV = thePrePoint->GetPhysicalVolume();
0125   G4VPhysicalVolume* thePostPV = thePostPoint->GetPhysicalVolume();
0126 
0127   G4String thePrePVname = " ";
0128   G4String thePostPVname = " ";
0129 
0130   if (thePostPV) {
0131     thePrePVname = thePrePV->GetName();
0132     thePostPVname = thePostPV->GetName();
0133   }
0134 
0135   // Recording data for start
0136   // static const G4ThreeVector ZHat = G4ThreeVector(0.0,0.0,1.0);
0137   if (theTrack->GetParentID() == 0) {
0138     // This is a primary track
0139     if (theTrack->GetCurrentStepNumber() == 1) {
0140       //        G4double x  = theTrack->GetVertexPosition().x();
0141       //        G4double y  = theTrack->GetVertexPosition().y();
0142       //        G4double z  = theTrack->GetVertexPosition().z();
0143       //        G4double pz = theTrack->GetVertexMomentumDirection().z();
0144       //        G4double fInitTheta =
0145       //                         theTrack->GetVertexMomentumDirection().angle(ZHat);
0146     }
0147   }
0148 
0149   // Retrieve the status of the photon
0150   G4OpBoundaryProcessStatus theStatus = Undefined;
0151 
0152   static G4ThreadLocal G4ProcessManager* OpManager =
0153     G4OpticalPhoton::OpticalPhoton()->GetProcessManager();
0154 
0155   if (OpManager) {
0156     G4int nproc = OpManager->GetPostStepProcessVector()->entries();
0157     G4ProcessVector* fPostStepDoItVector = OpManager->GetPostStepProcessVector(typeDoIt);
0158 
0159     for (G4int i = 0; i < nproc; ++i) {
0160       G4VProcess* fCurrentProcess = (*fPostStepDoItVector)[i];
0161       fOpProcess = dynamic_cast<G4OpBoundaryProcess*>(fCurrentProcess);
0162       if (fOpProcess) {
0163         theStatus = fOpProcess->GetStatus();
0164         break;
0165       }
0166     }
0167   }
0168 
0169   // Find the skewness of the ray at first change of boundary
0170   if (fInitGamma == -1
0171       && (theStatus == TotalInternalReflection || theStatus == FresnelReflection
0172           || theStatus == FresnelRefraction)
0173       && trackInformation->IsStatus(InsideOfFiber))
0174   {
0175     G4double px = theTrack->GetVertexMomentumDirection().x();
0176     G4double py = theTrack->GetVertexMomentumDirection().y();
0177     G4double x = theTrack->GetPosition().x();
0178     G4double y = theTrack->GetPosition().y();
0179 
0180     fInitGamma = x * px + y * py;
0181 
0182     fInitGamma = fInitGamma / std::sqrt(px * px + py * py) / std::sqrt(x * x + y * y);
0183 
0184     fInitGamma = std::acos(fInitGamma * rad);
0185 
0186     if (fInitGamma / deg > 90.0) {
0187       fInitGamma = 180 * deg - fInitGamma;
0188     }
0189   }
0190   // Record Photons that missed the photon detector but escaped from readout
0191   if (!thePostPV && trackInformation->IsStatus(EscapedFromReadOut)) {
0192     // G4cout << "SteppingAction: status = EscapedFromReadOut" << G4endl;
0193     fEventAction->AddEscaped();
0194     // UpdateHistogramSuccess(thePostPoint,theTrack);
0195     ResetCounters();
0196 
0197     return;
0198   }
0199 
0200   // Assumed photons are originated at the fiber OR
0201   // the fiber is the first material the photon hits
0202   switch (theStatus) {
0203     // Exiting the fiber
0204     case FresnelRefraction:
0205     case SameMaterial:
0206       fEventAction->AddExiting();
0207 
0208       if (thePostPVname == "WLSFiber" || thePostPVname == "Clad1" || thePostPVname == "Clad2") {
0209         if (trackInformation->IsStatus(OutsideOfFiber))
0210           trackInformation->AddStatusFlag(InsideOfFiber);
0211 
0212         // Set the Exit flag when the photon refracted out of the fiber
0213       }
0214       else if (trackInformation->IsStatus(InsideOfFiber)) {
0215         // EscapedFromReadOut if the z position is the same as fiber's end
0216         if (theTrack->GetPosition().z() == fDetector->GetWLSFiberEnd()) {
0217           trackInformation->AddStatusFlag(EscapedFromReadOut);
0218           fCounterEnd++;
0219           fEventAction->AddEscapedEnd();
0220         }
0221         else  // Escaped from side
0222         {
0223           trackInformation->AddStatusFlag(EscapedFromSide);
0224           trackInformation->SetExitPosition(theTrack->GetPosition());
0225           //  UpdateHistogramEscape(thePostPoint,theTrack);
0226 
0227           fCounterMid++;
0228           fEventAction->AddEscapedMid();
0229           ResetCounters();
0230         }
0231 
0232         trackInformation->AddStatusFlag(OutsideOfFiber);
0233         trackInformation->SetExitPosition(theTrack->GetPosition());
0234       }
0235 
0236       return;
0237 
0238     // Internal Reflections
0239     case TotalInternalReflection:
0240 
0241       fEventAction->AddTIR();
0242 
0243       // Kill the track if it's number of bounces exceeded the limit
0244       if (fBounceLimit > 0 && fCounterBounce >= fBounceLimit) {
0245         theTrack->SetTrackStatus(fStopAndKill);
0246         trackInformation->AddStatusFlag(murderee);
0247         ResetCounters();
0248         G4cout << "\n Bounce Limit Exceeded" << G4endl;
0249         return;
0250       }
0251       break;
0252 
0253     case FresnelReflection:
0254 
0255       fCounterBounce++;
0256       fEventAction->AddBounce();
0257 
0258       if (thePrePVname == "WLSFiber") {
0259         fCounterWLSBounce++;
0260         fEventAction->AddWLSBounce();
0261       }
0262       else if (thePrePVname == "Clad1") {
0263         fCounterClad1Bounce++;
0264         fEventAction->AddClad1Bounce();
0265       }
0266       else if (thePrePVname == "Clad2") {
0267         fCounterClad2Bounce++;
0268         fEventAction->AddClad1Bounce();
0269       }
0270 
0271       // Determine if the photon has reflected off the read-out end
0272       if (theTrack->GetPosition().z() == fDetector->GetWLSFiberEnd()) {
0273         if (!trackInformation->IsStatus(ReflectedAtReadOut)
0274             && trackInformation->IsStatus(InsideOfFiber))
0275         {
0276           trackInformation->AddStatusFlag(ReflectedAtReadOut);
0277 
0278           if (fDetector->IsPerfectFiber() && theStatus == TotalInternalReflection) {
0279             theTrack->SetTrackStatus(fStopAndKill);
0280             trackInformation->AddStatusFlag(murderee);
0281             // UpdateHistogramReflect(thePostPoint,theTrack);
0282             ResetCounters();
0283             return;
0284           }
0285         }
0286       }
0287       return;
0288 
0289     // Reflection off the mirror
0290     case LambertianReflection:
0291     case LobeReflection:
0292     case SpikeReflection:
0293 
0294       fEventAction->AddReflected();
0295       // Check if it hits the mirror
0296       if (thePostPVname == "Mirror") {
0297         trackInformation->AddStatusFlag(ReflectedAtMirror);
0298         fEventAction->AddMirror();
0299       }
0300       return;
0301 
0302     // Detected by a detector
0303     case Detection:
0304       // Detected automatically with G4OpBoundaryProcess->InvokeSD set true
0305 
0306       // Stop Tracking when it hits the detector's surface
0307       ResetCounters();
0308       theTrack->SetTrackStatus(fStopAndKill);
0309       return;
0310 
0311     default:
0312       break;
0313   }
0314 
0315   // Check for absorbed photons
0316   if (theTrack->GetTrackStatus() != fAlive && trackInformation->IsStatus(InsideOfFiber)) {
0317     // UpdateHistogramAbsorb(thePostPoint,theTrack);
0318     ResetCounters();
0319     return;
0320   }
0321 }