Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-23 09:22:47

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 //
0027 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0028 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0029 
0030 #include "SpecializedTrackingManager.hh"
0031 
0032 #include "G4EventManager.hh"
0033 #include "G4ProcessManager.hh"
0034 #include "G4RegionStore.hh"
0035 #include "G4StackManager.hh"
0036 #include "G4SystemOfUnits.hh"
0037 #include "G4TrackingManager.hh"
0038 
0039 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0040 
0041 SpecializedTrackingManager::SpecializedTrackingManager() {}
0042 
0043 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0044 
0045 SpecializedTrackingManager::~SpecializedTrackingManager() {}
0046 
0047 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0048 
0049 void SpecializedTrackingManager::BuildPhysicsTable(const G4ParticleDefinition& part)
0050 {
0051   if (fBackRegion == nullptr) {
0052     fBackRegion = G4RegionStore::GetInstance()->GetRegion("Back", false);
0053   }
0054 
0055   G4ProcessManager* pManager = part.GetProcessManager();
0056   G4ProcessManager* pManagerShadow = part.GetMasterProcessManager();
0057 
0058   G4ProcessVector* pVector = pManager->GetProcessList();
0059   for (std::size_t j = 0; j < pVector->size(); ++j) {
0060     if (pManagerShadow == pManager) {
0061       (*pVector)[j]->BuildPhysicsTable(part);
0062     }
0063     else {
0064       (*pVector)[j]->BuildWorkerPhysicsTable(part);
0065     }
0066   }
0067 }
0068 
0069 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0070 
0071 void SpecializedTrackingManager::PreparePhysicsTable(const G4ParticleDefinition& part)
0072 {
0073   G4ProcessManager* pManager = part.GetProcessManager();
0074   G4ProcessManager* pManagerShadow = part.GetMasterProcessManager();
0075 
0076   G4ProcessVector* pVector = pManager->GetProcessList();
0077   for (std::size_t j = 0; j < pVector->size(); ++j) {
0078     if (pManagerShadow == pManager) {
0079       (*pVector)[j]->PreparePhysicsTable(part);
0080     }
0081     else {
0082       (*pVector)[j]->PrepareWorkerPhysicsTable(part);
0083     }
0084   }
0085 }
0086 
0087 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0088 
0089 void SpecializedTrackingManager::HandOverOneTrack(G4Track* aTrack)
0090 {
0091   if (aTrack->GetKineticEnergy() < 100 * MeV) {
0092     // If the particle energy is lower than 100 MeV, track it immediately by
0093     // passing to the generic G4TrackingManager. This avoids storing lower
0094     // energy particles in the buffer and feeding it through the specialized
0095     // tracking.
0096     G4EventManager* eventManager = G4EventManager::GetEventManager();
0097     G4TrackingManager* trackManager = eventManager->GetTrackingManager();
0098 
0099     trackManager->ProcessOneTrack(aTrack);
0100     if (aTrack->GetTrackStatus() != fStopAndKill) {
0101       G4Exception("SpecializedTrackingManager::HandOverOneTrack", "NotStopped", FatalException,
0102                   "track was not stopped");
0103     }
0104 
0105     G4TrackVector* secondaries = trackManager->GimmeSecondaries();
0106     eventManager->StackTracks(secondaries);
0107     delete aTrack;
0108     return;
0109   }
0110 
0111   fBufferedTracks.push_back(aTrack);
0112 }
0113 
0114 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0115 
0116 void SpecializedTrackingManager::FlushEvent()
0117 {
0118   G4EventManager* eventManager = G4EventManager::GetEventManager();
0119   G4TrackingManager* trackManager = eventManager->GetTrackingManager();
0120   G4SteppingManager* steppingManager = trackManager->GetSteppingManager();
0121   G4TrackVector* secondaries = trackManager->GimmeSecondaries();
0122 
0123   for (G4Track* aTrack : fBufferedTracks) {
0124     // Clear secondary particle vector
0125     for (std::size_t itr = 0; itr < secondaries->size(); ++itr) {
0126       delete (*secondaries)[itr];
0127     }
0128     secondaries->clear();
0129 
0130     steppingManager->SetInitialStep(aTrack);
0131 
0132     G4UserTrackingAction* userTrackingAction = trackManager->GetUserTrackingAction();
0133     if (userTrackingAction != nullptr) {
0134       userTrackingAction->PreUserTrackingAction(aTrack);
0135     }
0136 
0137     // Give SteppingManger the maxmimum number of processes
0138     steppingManager->GetProcessNumber();
0139 
0140     // Give track the pointer to the Step
0141     aTrack->SetStep(steppingManager->GetStep());
0142 
0143     // Inform beginning of tracking to physics processes
0144     aTrack->GetDefinition()->GetProcessManager()->StartTracking(aTrack);
0145 
0146     // Track the particle Step-by-Step while it is alive
0147     while ((aTrack->GetTrackStatus() == fAlive) || (aTrack->GetTrackStatus() == fStopButAlive)) {
0148       G4Region* region = aTrack->GetVolume()->GetLogicalVolume()->GetRegion();
0149       if (region == fBackRegion) {
0150         StepInBackRegion(aTrack);
0151       }
0152       else {
0153         StepOutside(aTrack);
0154       }
0155     }
0156 
0157     aTrack->GetDefinition()->GetProcessManager()->EndTracking();
0158 
0159     if (userTrackingAction != nullptr) {
0160       userTrackingAction->PostUserTrackingAction(aTrack);
0161     }
0162 
0163     eventManager->StackTracks(secondaries);
0164     delete aTrack;
0165   }
0166 
0167   fBufferedTracks.clear();
0168 }
0169 
0170 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0171 
0172 void SpecializedTrackingManager::StepInBackRegion(G4Track* aTrack)
0173 {
0174   G4EventManager* eventManager = G4EventManager::GetEventManager();
0175   G4TrackingManager* trackManager = eventManager->GetTrackingManager();
0176   G4SteppingManager* steppingManager = trackManager->GetSteppingManager();
0177 
0178   // Track the particle Step-by-Step while it is alive and inside the "Back"
0179   // region of the detector. Implement a low-energy cut-off for particles
0180   // below 100 MeV. More specialized handling would also be possible, such
0181   // as only killing particles in non-sensitive materials / volumes.
0182   while ((aTrack->GetTrackStatus() == fAlive) || (aTrack->GetTrackStatus() == fStopButAlive)) {
0183     aTrack->IncrementCurrentStepNumber();
0184     steppingManager->Stepping();
0185 
0186     if (aTrack->GetTrackStatus() != fStopAndKill) {
0187       // Switch the touchable to update the volume, which is checked in the
0188       // condition below and at the call site.
0189       aTrack->SetTouchableHandle(aTrack->GetNextTouchableHandle());
0190       G4Region* region = aTrack->GetVolume()->GetLogicalVolume()->GetRegion();
0191       if (region != fBackRegion) {
0192         return;
0193       }
0194 
0195       if (aTrack->GetKineticEnergy() < 100 * MeV) {
0196         // Kill the particle.
0197         aTrack->SetTrackStatus(fStopAndKill);
0198       }
0199     }
0200   }
0201 }
0202 
0203 //....oooOO0OOooo........oooOO0OOooo........oooOO0OOooo........oooOO0OOooo......
0204 
0205 void SpecializedTrackingManager::StepOutside(G4Track* aTrack)
0206 {
0207   G4EventManager* eventManager = G4EventManager::GetEventManager();
0208   G4TrackingManager* trackManager = eventManager->GetTrackingManager();
0209   G4SteppingManager* steppingManager = trackManager->GetSteppingManager();
0210 
0211   // Track the particle Step-by-Step while it is alive and still outside of
0212   // the "Back" region.
0213   while ((aTrack->GetTrackStatus() == fAlive) || (aTrack->GetTrackStatus() == fStopButAlive)) {
0214     aTrack->IncrementCurrentStepNumber();
0215     steppingManager->Stepping();
0216 
0217     if (aTrack->GetTrackStatus() != fStopAndKill) {
0218       // Switch the touchable to update the volume, which is checked in the
0219       // condition below and at the call site.
0220       aTrack->SetTouchableHandle(aTrack->GetNextTouchableHandle());
0221       G4Region* region = aTrack->GetVolume()->GetLogicalVolume()->GetRegion();
0222       if (region == fBackRegion) {
0223         return;
0224       }
0225     }
0226   }
0227 }