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 // Implementation of a custom tracking manager 26 // Implementation of a custom tracking manager for e-/e+ and gamma, using 27 // the same processes as defined in G4EmStanda 27 // the same processes as defined in G4EmStandardPhysics. 28 // 28 // 29 // Original author: Jonas Hahnfeld, 2021 29 // Original author: Jonas Hahnfeld, 2021 30 30 31 #include "EmStandardPhysicsTrackingManager.hh" 31 #include "EmStandardPhysicsTrackingManager.hh" 32 32 33 #include "TrackingManagerHelper.hh" << 34 << 35 #include "G4ComptonScattering.hh" 33 #include "G4ComptonScattering.hh" 36 #include "G4CoulombScattering.hh" 34 #include "G4CoulombScattering.hh" 37 #include "G4Electron.hh" 35 #include "G4Electron.hh" 38 #include "G4EmParameters.hh" 36 #include "G4EmParameters.hh" 39 #include "G4Gamma.hh" 37 #include "G4Gamma.hh" 40 #include "G4GammaConversion.hh" 38 #include "G4GammaConversion.hh" 41 #include "G4KleinNishinaModel.hh" 39 #include "G4KleinNishinaModel.hh" 42 #include "G4LivermorePhotoElectricModel.hh" 40 #include "G4LivermorePhotoElectricModel.hh" 43 #include "G4LivermorePolarizedRayleighModel.hh 41 #include "G4LivermorePolarizedRayleighModel.hh" 44 #include "G4PhotoElectricAngularGeneratorPolar 42 #include "G4PhotoElectricAngularGeneratorPolarized.hh" 45 #include "G4PhotoElectricEffect.hh" 43 #include "G4PhotoElectricEffect.hh" 46 #include "G4Positron.hh" 44 #include "G4Positron.hh" 47 #include "G4RayleighScattering.hh" 45 #include "G4RayleighScattering.hh" 48 #include "G4SystemOfUnits.hh" 46 #include "G4SystemOfUnits.hh" 49 #include "G4UrbanMscModel.hh" 47 #include "G4UrbanMscModel.hh" 50 #include "G4WentzelVIModel.hh" 48 #include "G4WentzelVIModel.hh" 51 #include "G4eBremsstrahlung.hh" 49 #include "G4eBremsstrahlung.hh" 52 #include "G4eCoulombScatteringModel.hh" 50 #include "G4eCoulombScatteringModel.hh" 53 #include "G4eIonisation.hh" 51 #include "G4eIonisation.hh" 54 #include "G4eMultipleScattering.hh" 52 #include "G4eMultipleScattering.hh" 55 #include "G4eplusAnnihilation.hh" 53 #include "G4eplusAnnihilation.hh" 56 54 57 //....oooOO0OOooo........oooOO0OOooo........oo << 55 #include "TrackingManagerHelper.hh" 58 56 59 EmStandardPhysicsTrackingManager* EmStandardPh 57 EmStandardPhysicsTrackingManager* EmStandardPhysicsTrackingManager::fMasterTrackingManager = 60 nullptr; 58 nullptr; 61 59 62 //....oooOO0OOooo........oooOO0OOooo........oo << 63 << 64 EmStandardPhysicsTrackingManager::EmStandardPh 60 EmStandardPhysicsTrackingManager::EmStandardPhysicsTrackingManager() 65 { 61 { 66 G4EmParameters* param = G4EmParameters::Inst 62 G4EmParameters* param = G4EmParameters::Instance(); 67 G4double highEnergyLimit = param->MscEnergyL 63 G4double highEnergyLimit = param->MscEnergyLimit(); 68 G4bool polar = param->EnablePolarisation(); 64 G4bool polar = param->EnablePolarisation(); 69 65 70 // e- 66 // e- 71 { 67 { 72 G4eMultipleScattering* msc = new G4eMultip 68 G4eMultipleScattering* msc = new G4eMultipleScattering; 73 G4UrbanMscModel* msc1 = new G4UrbanMscMode 69 G4UrbanMscModel* msc1 = new G4UrbanMscModel; 74 G4WentzelVIModel* msc2 = new G4WentzelVIMo 70 G4WentzelVIModel* msc2 = new G4WentzelVIModel; 75 msc1->SetHighEnergyLimit(highEnergyLimit); 71 msc1->SetHighEnergyLimit(highEnergyLimit); 76 msc2->SetLowEnergyLimit(highEnergyLimit); 72 msc2->SetLowEnergyLimit(highEnergyLimit); 77 msc->SetEmModel(msc1); 73 msc->SetEmModel(msc1); 78 msc->SetEmModel(msc2); 74 msc->SetEmModel(msc2); 79 fElectronProcs.msc = msc; 75 fElectronProcs.msc = msc; 80 76 81 fElectronProcs.ioni = new G4eIonisation; 77 fElectronProcs.ioni = new G4eIonisation; 82 fElectronProcs.brems = new G4eBremsstrahlu 78 fElectronProcs.brems = new G4eBremsstrahlung; 83 79 84 G4CoulombScattering* ss = new G4CoulombSca 80 G4CoulombScattering* ss = new G4CoulombScattering; 85 G4eCoulombScatteringModel* ssm = new G4eCo 81 G4eCoulombScatteringModel* ssm = new G4eCoulombScatteringModel; 86 ssm->SetLowEnergyLimit(highEnergyLimit); 82 ssm->SetLowEnergyLimit(highEnergyLimit); 87 ssm->SetActivationLowEnergyLimit(highEnerg 83 ssm->SetActivationLowEnergyLimit(highEnergyLimit); 88 ss->SetEmModel(ssm); 84 ss->SetEmModel(ssm); 89 ss->SetMinKinEnergy(highEnergyLimit); 85 ss->SetMinKinEnergy(highEnergyLimit); 90 fElectronProcs.ss = ss; 86 fElectronProcs.ss = ss; 91 } 87 } 92 88 93 // e+ 89 // e+ 94 { 90 { 95 G4eMultipleScattering* msc = new G4eMultip 91 G4eMultipleScattering* msc = new G4eMultipleScattering; 96 G4UrbanMscModel* msc1 = new G4UrbanMscMode 92 G4UrbanMscModel* msc1 = new G4UrbanMscModel; 97 G4WentzelVIModel* msc2 = new G4WentzelVIMo 93 G4WentzelVIModel* msc2 = new G4WentzelVIModel; 98 msc1->SetHighEnergyLimit(highEnergyLimit); 94 msc1->SetHighEnergyLimit(highEnergyLimit); 99 msc2->SetLowEnergyLimit(highEnergyLimit); 95 msc2->SetLowEnergyLimit(highEnergyLimit); 100 msc->SetEmModel(msc1); 96 msc->SetEmModel(msc1); 101 msc->SetEmModel(msc2); 97 msc->SetEmModel(msc2); 102 fPositronProcs.msc = msc; 98 fPositronProcs.msc = msc; 103 99 104 fPositronProcs.ioni = new G4eIonisation; 100 fPositronProcs.ioni = new G4eIonisation; 105 fPositronProcs.brems = new G4eBremsstrahlu 101 fPositronProcs.brems = new G4eBremsstrahlung; 106 fPositronProcs.annihilation = new G4eplusA 102 fPositronProcs.annihilation = new G4eplusAnnihilation; 107 103 108 G4CoulombScattering* ss = new G4CoulombSca 104 G4CoulombScattering* ss = new G4CoulombScattering; 109 G4eCoulombScatteringModel* ssm = new G4eCo 105 G4eCoulombScatteringModel* ssm = new G4eCoulombScatteringModel; 110 ssm->SetLowEnergyLimit(highEnergyLimit); 106 ssm->SetLowEnergyLimit(highEnergyLimit); 111 ssm->SetActivationLowEnergyLimit(highEnerg 107 ssm->SetActivationLowEnergyLimit(highEnergyLimit); 112 ss->SetEmModel(ssm); 108 ss->SetEmModel(ssm); 113 ss->SetMinKinEnergy(highEnergyLimit); 109 ss->SetMinKinEnergy(highEnergyLimit); 114 fPositronProcs.ss = ss; 110 fPositronProcs.ss = ss; 115 } 111 } 116 112 117 { 113 { 118 G4PhotoElectricEffect* pe = new G4PhotoEle 114 G4PhotoElectricEffect* pe = new G4PhotoElectricEffect; 119 G4VEmModel* peModel = new G4LivermorePhoto 115 G4VEmModel* peModel = new G4LivermorePhotoElectricModel; 120 if (polar) { 116 if (polar) { 121 peModel->SetAngularDistribution(new G4Ph 117 peModel->SetAngularDistribution(new G4PhotoElectricAngularGeneratorPolarized); 122 } 118 } 123 pe->SetEmModel(peModel); 119 pe->SetEmModel(peModel); 124 fGammaProcs.pe = pe; 120 fGammaProcs.pe = pe; 125 121 126 G4ComptonScattering* cs = new G4ComptonSca 122 G4ComptonScattering* cs = new G4ComptonScattering; 127 if (polar) { 123 if (polar) { 128 cs->SetEmModel(new G4KleinNishinaModel); 124 cs->SetEmModel(new G4KleinNishinaModel); 129 } 125 } 130 fGammaProcs.compton = cs; 126 fGammaProcs.compton = cs; 131 127 132 fGammaProcs.conversion = new G4GammaConver 128 fGammaProcs.conversion = new G4GammaConversion; 133 129 134 G4RayleighScattering* rl = new G4RayleighS 130 G4RayleighScattering* rl = new G4RayleighScattering; 135 if (polar) { 131 if (polar) { 136 rl->SetEmModel(new G4LivermorePolarizedR 132 rl->SetEmModel(new G4LivermorePolarizedRayleighModel); 137 } 133 } 138 fGammaProcs.rayleigh = rl; 134 fGammaProcs.rayleigh = rl; 139 } 135 } 140 136 141 if (fMasterTrackingManager == nullptr) { 137 if (fMasterTrackingManager == nullptr) { 142 fMasterTrackingManager = this; 138 fMasterTrackingManager = this; 143 } 139 } 144 else { 140 else { 145 fElectronProcs.msc->SetMasterProcess(fMast 141 fElectronProcs.msc->SetMasterProcess(fMasterTrackingManager->fElectronProcs.msc); 146 fElectronProcs.ss->SetMasterProcess(fMaste 142 fElectronProcs.ss->SetMasterProcess(fMasterTrackingManager->fElectronProcs.ss); 147 fElectronProcs.ioni->SetMasterProcess(fMas 143 fElectronProcs.ioni->SetMasterProcess(fMasterTrackingManager->fElectronProcs.ioni); 148 fElectronProcs.brems->SetMasterProcess(fMa 144 fElectronProcs.brems->SetMasterProcess(fMasterTrackingManager->fElectronProcs.brems); 149 145 150 fPositronProcs.msc->SetMasterProcess(fMast 146 fPositronProcs.msc->SetMasterProcess(fMasterTrackingManager->fPositronProcs.msc); 151 fPositronProcs.ss->SetMasterProcess(fMaste 147 fPositronProcs.ss->SetMasterProcess(fMasterTrackingManager->fPositronProcs.ss); 152 fPositronProcs.ioni->SetMasterProcess(fMas 148 fPositronProcs.ioni->SetMasterProcess(fMasterTrackingManager->fPositronProcs.ioni); 153 fPositronProcs.brems->SetMasterProcess(fMa 149 fPositronProcs.brems->SetMasterProcess(fMasterTrackingManager->fPositronProcs.brems); 154 fPositronProcs.annihilation->SetMasterProc 150 fPositronProcs.annihilation->SetMasterProcess( 155 fMasterTrackingManager->fPositronProcs.a 151 fMasterTrackingManager->fPositronProcs.annihilation); 156 152 157 fGammaProcs.pe->SetMasterProcess(fMasterTr 153 fGammaProcs.pe->SetMasterProcess(fMasterTrackingManager->fGammaProcs.pe); 158 fGammaProcs.compton->SetMasterProcess(fMas 154 fGammaProcs.compton->SetMasterProcess(fMasterTrackingManager->fGammaProcs.compton); 159 fGammaProcs.conversion->SetMasterProcess(f 155 fGammaProcs.conversion->SetMasterProcess(fMasterTrackingManager->fGammaProcs.conversion); 160 fGammaProcs.rayleigh->SetMasterProcess(fMa 156 fGammaProcs.rayleigh->SetMasterProcess(fMasterTrackingManager->fGammaProcs.rayleigh); 161 } 157 } 162 } 158 } 163 159 164 //....oooOO0OOooo........oooOO0OOooo........oo << 165 << 166 EmStandardPhysicsTrackingManager::~EmStandardP 160 EmStandardPhysicsTrackingManager::~EmStandardPhysicsTrackingManager() 167 { 161 { 168 if (fMasterTrackingManager == this) { 162 if (fMasterTrackingManager == this) { 169 fMasterTrackingManager = nullptr; 163 fMasterTrackingManager = nullptr; 170 } 164 } 171 } 165 } 172 166 173 //....oooOO0OOooo........oooOO0OOooo........oo << 174 << 175 void EmStandardPhysicsTrackingManager::BuildPh 167 void EmStandardPhysicsTrackingManager::BuildPhysicsTable(const G4ParticleDefinition& part) 176 { 168 { 177 if (&part == G4Electron::Definition()) { 169 if (&part == G4Electron::Definition()) { 178 fElectronProcs.msc->BuildPhysicsTable(part 170 fElectronProcs.msc->BuildPhysicsTable(part); 179 fElectronProcs.ioni->BuildPhysicsTable(par 171 fElectronProcs.ioni->BuildPhysicsTable(part); 180 fElectronProcs.brems->BuildPhysicsTable(pa 172 fElectronProcs.brems->BuildPhysicsTable(part); 181 fElectronProcs.ss->BuildPhysicsTable(part) 173 fElectronProcs.ss->BuildPhysicsTable(part); 182 } 174 } 183 else if (&part == G4Positron::Definition()) 175 else if (&part == G4Positron::Definition()) { 184 fPositronProcs.msc->BuildPhysicsTable(part 176 fPositronProcs.msc->BuildPhysicsTable(part); 185 fPositronProcs.ioni->BuildPhysicsTable(par 177 fPositronProcs.ioni->BuildPhysicsTable(part); 186 fPositronProcs.brems->BuildPhysicsTable(pa 178 fPositronProcs.brems->BuildPhysicsTable(part); 187 fPositronProcs.annihilation->BuildPhysicsT 179 fPositronProcs.annihilation->BuildPhysicsTable(part); 188 fPositronProcs.ss->BuildPhysicsTable(part) 180 fPositronProcs.ss->BuildPhysicsTable(part); 189 } 181 } 190 else if (&part == G4Gamma::Definition()) { 182 else if (&part == G4Gamma::Definition()) { 191 fGammaProcs.pe->BuildPhysicsTable(part); 183 fGammaProcs.pe->BuildPhysicsTable(part); 192 fGammaProcs.compton->BuildPhysicsTable(par 184 fGammaProcs.compton->BuildPhysicsTable(part); 193 fGammaProcs.conversion->BuildPhysicsTable( 185 fGammaProcs.conversion->BuildPhysicsTable(part); 194 fGammaProcs.rayleigh->BuildPhysicsTable(pa 186 fGammaProcs.rayleigh->BuildPhysicsTable(part); 195 } 187 } 196 } 188 } 197 189 198 //....oooOO0OOooo........oooOO0OOooo........oo << 199 << 200 void EmStandardPhysicsTrackingManager::Prepare 190 void EmStandardPhysicsTrackingManager::PreparePhysicsTable(const G4ParticleDefinition& part) 201 { 191 { 202 if (&part == G4Electron::Definition()) { 192 if (&part == G4Electron::Definition()) { 203 fElectronProcs.msc->PreparePhysicsTable(pa 193 fElectronProcs.msc->PreparePhysicsTable(part); 204 fElectronProcs.ioni->PreparePhysicsTable(p 194 fElectronProcs.ioni->PreparePhysicsTable(part); 205 fElectronProcs.brems->PreparePhysicsTable( 195 fElectronProcs.brems->PreparePhysicsTable(part); 206 fElectronProcs.ss->PreparePhysicsTable(par 196 fElectronProcs.ss->PreparePhysicsTable(part); 207 } 197 } 208 else if (&part == G4Positron::Definition()) 198 else if (&part == G4Positron::Definition()) { 209 fPositronProcs.msc->PreparePhysicsTable(pa 199 fPositronProcs.msc->PreparePhysicsTable(part); 210 fPositronProcs.ioni->PreparePhysicsTable(p 200 fPositronProcs.ioni->PreparePhysicsTable(part); 211 fPositronProcs.brems->PreparePhysicsTable( 201 fPositronProcs.brems->PreparePhysicsTable(part); 212 fPositronProcs.annihilation->PreparePhysic 202 fPositronProcs.annihilation->PreparePhysicsTable(part); 213 fPositronProcs.ss->PreparePhysicsTable(par 203 fPositronProcs.ss->PreparePhysicsTable(part); 214 } 204 } 215 else if (&part == G4Gamma::Definition()) { 205 else if (&part == G4Gamma::Definition()) { 216 fGammaProcs.pe->PreparePhysicsTable(part); 206 fGammaProcs.pe->PreparePhysicsTable(part); 217 fGammaProcs.compton->PreparePhysicsTable(p 207 fGammaProcs.compton->PreparePhysicsTable(part); 218 fGammaProcs.conversion->PreparePhysicsTabl 208 fGammaProcs.conversion->PreparePhysicsTable(part); 219 fGammaProcs.rayleigh->PreparePhysicsTable( 209 fGammaProcs.rayleigh->PreparePhysicsTable(part); 220 } 210 } 221 } 211 } 222 212 223 //....oooOO0OOooo........oooOO0OOooo........oo << 224 << 225 void EmStandardPhysicsTrackingManager::TrackEl 213 void EmStandardPhysicsTrackingManager::TrackElectron(G4Track* aTrack) 226 { 214 { 227 class ElectronPhysics final : public Trackin 215 class ElectronPhysics final : public TrackingManagerHelper::Physics 228 { 216 { 229 public: << 217 public: 230 ElectronPhysics(EmStandardPhysicsTrackin << 218 ElectronPhysics(EmStandardPhysicsTrackingManager& mgr) : fMgr(mgr) {} 231 << 232 void StartTracking(G4Track* aTrack) over << 233 { << 234 auto& electronProcs = fMgr.fElectronPr << 235 << 236 electronProcs.msc->StartTracking(aTrac << 237 electronProcs.ioni->StartTracking(aTra << 238 electronProcs.brems->StartTracking(aTr << 239 electronProcs.ss->StartTracking(aTrack << 240 << 241 fPreviousStepLength = 0; << 242 } << 243 void EndTracking() override << 244 { << 245 auto& electronProcs = fMgr.fElectronPr << 246 << 247 electronProcs.msc->EndTracking(); << 248 electronProcs.ioni->EndTracking(); << 249 electronProcs.brems->EndTracking(); << 250 electronProcs.ss->EndTracking(); << 251 } << 252 << 253 G4double GetPhysicalInteractionLength(co << 254 { << 255 auto& electronProcs = fMgr.fElectronPr << 256 G4double physIntLength, proposedSafety << 257 G4ForceCondition condition; << 258 G4GPILSelection selection; << 259 << 260 fProposedStep = DBL_MAX; << 261 fSelected = -1; << 262 219 263 physIntLength = electronProcs.ss->Post << 220 void StartTracking(G4Track* aTrack) override 264 if (physIntLength < fProposedStep) { << 221 { 265 fProposedStep = physIntLength; << 222 auto& electronProcs = fMgr.fElectronProcs; 266 fSelected = 0; << 223 267 } << 224 electronProcs.msc->StartTracking(aTrack); >> 225 electronProcs.ioni->StartTracking(aTrack); >> 226 electronProcs.brems->StartTracking(aTrack); >> 227 electronProcs.ss->StartTracking(aTrack); 268 228 269 physIntLength = electronProcs.brems->P << 229 fPreviousStepLength = 0; 270 if (physIntLength < fProposedStep) { << 230 } 271 fProposedStep = physIntLength; << 231 void EndTracking() override 272 fSelected = 1; << 232 { 273 } << 233 auto& electronProcs = fMgr.fElectronProcs; 274 << 234 275 physIntLength = electronProcs.ioni->Po << 235 electronProcs.msc->EndTracking(); 276 if (physIntLength < fProposedStep) { << 236 electronProcs.ioni->EndTracking(); 277 fProposedStep = physIntLength; << 237 electronProcs.brems->EndTracking(); 278 fSelected = 2; << 238 electronProcs.ss->EndTracking(); 279 } << 239 } 280 << 281 physIntLength = electronProcs.ioni->Al << 282 << 283 if (physIntLength < fProposedStep) { << 284 fProposedStep = physIntLength; << 285 fSelected = -1; << 286 } << 287 << 288 physIntLength = electronProcs.msc->Alo << 289 << 290 if (physIntLength < fProposedStep) { << 291 fProposedStep = physIntLength; << 292 // Check if MSC actually wants to wi << 293 // step size. << 294 if (selection == CandidateForSelecti << 295 fSelected = -1; << 296 } << 297 } << 298 240 299 return fProposedStep; << 241 G4double GetPhysicalInteractionLength(const G4Track& track) override >> 242 { >> 243 auto& electronProcs = fMgr.fElectronProcs; >> 244 G4double physIntLength, proposedSafety = DBL_MAX; >> 245 G4ForceCondition condition; >> 246 G4GPILSelection selection; >> 247 >> 248 fProposedStep = DBL_MAX; >> 249 fSelected = -1; >> 250 >> 251 physIntLength = electronProcs.ss->PostStepGPIL(track, fPreviousStepLength, &condition); >> 252 if (physIntLength < fProposedStep) { >> 253 fProposedStep = physIntLength; >> 254 fSelected = 0; >> 255 } >> 256 >> 257 physIntLength = electronProcs.brems->PostStepGPIL(track, fPreviousStepLength, &condition); >> 258 if (physIntLength < fProposedStep) { >> 259 fProposedStep = physIntLength; >> 260 fSelected = 1; >> 261 } >> 262 >> 263 physIntLength = electronProcs.ioni->PostStepGPIL(track, fPreviousStepLength, &condition); >> 264 if (physIntLength < fProposedStep) { >> 265 fProposedStep = physIntLength; >> 266 fSelected = 2; >> 267 } >> 268 >> 269 physIntLength = electronProcs.ioni->AlongStepGPIL( >> 270 track, fPreviousStepLength, fProposedStep, proposedSafety, &selection); >> 271 if (physIntLength < fProposedStep) { >> 272 fProposedStep = physIntLength; >> 273 fSelected = -1; 300 } 274 } 301 275 302 void AlongStepDoIt(G4Track& track, G4Ste << 276 physIntLength = electronProcs.msc->AlongStepGPIL( 303 { << 277 track, fPreviousStepLength, fProposedStep, proposedSafety, &selection); 304 if (step.GetStepLength() == fProposedS << 278 if (physIntLength < fProposedStep) { 305 step.GetPostStepPoint()->SetStepStat << 279 fProposedStep = physIntLength; 306 } << 280 // Check if MSC actually wants to win, in most cases it only limits the 307 else { << 281 // step size. 308 // Remember that the step was limite << 282 if (selection == CandidateForSelection) { 309 fSelected = -1; 283 fSelected = -1; 310 } 284 } 311 auto& electronProcs = fMgr.fElectronPr << 285 } 312 G4VParticleChange* particleChange; << 313 286 314 particleChange = electronProcs.msc->Al << 287 return fProposedStep; 315 particleChange->UpdateStepForAlongStep << 288 } 316 track.SetTrackStatus(particleChange->G << 317 particleChange->Clear(); << 318 << 319 particleChange = electronProcs.ioni->A << 320 particleChange->UpdateStepForAlongStep << 321 track.SetTrackStatus(particleChange->G << 322 particleChange->Clear(); << 323 << 324 fPreviousStepLength = step.GetStepLeng << 325 } << 326 << 327 void PostStepDoIt(G4Track& track, G4Step << 328 { << 329 if (fSelected < 0) { << 330 return; << 331 } << 332 step.GetPostStepPoint()->SetStepStatus << 333 289 334 auto& electronProcs = fMgr.fElectronPr << 290 void AlongStepDoIt(G4Track& track, G4Step& step, G4TrackVector&) override 335 G4VProcess* process = nullptr; << 291 { 336 G4VParticleChange* particleChange = nu << 292 if (step.GetStepLength() == fProposedStep) { 337 << 293 step.GetPostStepPoint()->SetStepStatus(fAlongStepDoItProc); 338 switch (fSelected) { << 294 } 339 case 0: << 295 else { 340 process = electronProcs.ss; << 296 // Remember that the step was limited by geometry. 341 particleChange = electronProcs.ss- << 297 fSelected = -1; 342 break; << 298 } 343 case 1: << 299 auto& electronProcs = fMgr.fElectronProcs; 344 process = electronProcs.brems; << 300 G4VParticleChange* particleChange; 345 particleChange = electronProcs.bre << 346 break; << 347 case 2: << 348 process = electronProcs.ioni; << 349 particleChange = electronProcs.ion << 350 break; << 351 } << 352 301 353 particleChange->UpdateStepForPostStep( << 302 particleChange = electronProcs.msc->AlongStepDoIt(track, step); 354 step.UpdateTrack(); << 303 particleChange->UpdateStepForAlongStep(&step); >> 304 track.SetTrackStatus(particleChange->GetTrackStatus()); >> 305 particleChange->Clear(); >> 306 >> 307 particleChange = electronProcs.ioni->AlongStepDoIt(track, step); >> 308 particleChange->UpdateStepForAlongStep(&step); >> 309 track.SetTrackStatus(particleChange->GetTrackStatus()); >> 310 particleChange->Clear(); 355 311 356 G4int numSecondaries = particleChange- << 312 fPreviousStepLength = step.GetStepLength(); 357 for (G4int i = 0; i < numSecondaries; << 313 } 358 G4Track* secondary = particleChange- << 359 secondary->SetParentID(track.GetTrac << 360 secondary->SetCreatorProcess(process << 361 secondaries.push_back(secondary); << 362 } << 363 314 364 track.SetTrackStatus(particleChange->G << 315 void PostStepDoIt(G4Track& track, G4Step& step, G4TrackVector& secondaries) override 365 particleChange->Clear(); << 316 { >> 317 if (fSelected < 0) { >> 318 return; >> 319 } >> 320 step.GetPostStepPoint()->SetStepStatus(fPostStepDoItProc); >> 321 >> 322 auto& electronProcs = fMgr.fElectronProcs; >> 323 G4VProcess* process = nullptr; >> 324 G4VParticleChange* particleChange = nullptr; >> 325 >> 326 switch (fSelected) { >> 327 case 0: >> 328 process = electronProcs.ss; >> 329 particleChange = electronProcs.ss->PostStepDoIt(track, step); >> 330 break; >> 331 case 1: >> 332 process = electronProcs.brems; >> 333 particleChange = electronProcs.brems->PostStepDoIt(track, step); >> 334 break; >> 335 case 2: >> 336 process = electronProcs.ioni; >> 337 particleChange = electronProcs.ioni->PostStepDoIt(track, step); >> 338 break; >> 339 } >> 340 >> 341 particleChange->UpdateStepForPostStep(&step); >> 342 step.UpdateTrack(); >> 343 >> 344 int numSecondaries = particleChange->GetNumberOfSecondaries(); >> 345 for (int i = 0; i < numSecondaries; i++) { >> 346 G4Track* secondary = particleChange->GetSecondary(i); >> 347 secondary->SetParentID(track.GetTrackID()); >> 348 secondary->SetCreatorProcess(process); >> 349 secondaries.push_back(secondary); 366 } 350 } 367 351 368 private: << 352 track.SetTrackStatus(particleChange->GetTrackStatus()); 369 EmStandardPhysicsTrackingManager& fMgr; << 353 particleChange->Clear(); 370 G4double fPreviousStepLength; << 354 } 371 G4double fProposedStep; << 355 372 G4int fSelected; << 356 private: >> 357 EmStandardPhysicsTrackingManager& fMgr; >> 358 G4double fPreviousStepLength; >> 359 G4double fProposedStep; >> 360 G4int fSelected; 373 }; 361 }; 374 362 375 ElectronPhysics physics(*this); 363 ElectronPhysics physics(*this); 376 TrackingManagerHelper::TrackChargedParticle( 364 TrackingManagerHelper::TrackChargedParticle(aTrack, physics); 377 } 365 } 378 366 379 //....oooOO0OOooo........oooOO0OOooo........oo << 380 << 381 void EmStandardPhysicsTrackingManager::TrackPo 367 void EmStandardPhysicsTrackingManager::TrackPositron(G4Track* aTrack) 382 { 368 { 383 class PositronPhysics final : public Trackin 369 class PositronPhysics final : public TrackingManagerHelper::Physics 384 { 370 { 385 public: << 371 public: 386 PositronPhysics(EmStandardPhysicsTrackin << 372 PositronPhysics(EmStandardPhysicsTrackingManager& mgr) : fMgr(mgr) {} 387 373 388 void StartTracking(G4Track* aTrack) over << 374 void StartTracking(G4Track* aTrack) override 389 { << 375 { 390 auto& positronProcs = fMgr.fPositronPr << 376 auto& positronProcs = fMgr.fPositronProcs; 391 << 377 392 positronProcs.msc->StartTracking(aTrac << 378 positronProcs.msc->StartTracking(aTrack); 393 positronProcs.ioni->StartTracking(aTra << 379 positronProcs.ioni->StartTracking(aTrack); 394 positronProcs.brems->StartTracking(aTr << 380 positronProcs.brems->StartTracking(aTrack); 395 positronProcs.annihilation->StartTrack << 381 positronProcs.annihilation->StartTracking(aTrack); 396 positronProcs.ss->StartTracking(aTrack << 382 positronProcs.ss->StartTracking(aTrack); 397 << 398 fPreviousStepLength = 0; << 399 } << 400 void EndTracking() override << 401 { << 402 auto& positronProcs = fMgr.fPositronPr << 403 << 404 positronProcs.msc->EndTracking(); << 405 positronProcs.ioni->EndTracking(); << 406 positronProcs.brems->EndTracking(); << 407 positronProcs.annihilation->EndTrackin << 408 positronProcs.ss->EndTracking(); << 409 } << 410 << 411 G4double GetPhysicalInteractionLength(co << 412 { << 413 auto& positronProcs = fMgr.fPositronPr << 414 G4double physIntLength, proposedSafety << 415 G4ForceCondition condition; << 416 G4GPILSelection selection; << 417 383 418 fProposedStep = DBL_MAX; << 384 fPreviousStepLength = 0; 419 fSelected = -1; << 385 } >> 386 void EndTracking() override >> 387 { >> 388 auto& positronProcs = fMgr.fPositronProcs; >> 389 >> 390 positronProcs.msc->EndTracking(); >> 391 positronProcs.ioni->EndTracking(); >> 392 positronProcs.brems->EndTracking(); >> 393 positronProcs.annihilation->EndTracking(); >> 394 positronProcs.ss->EndTracking(); >> 395 } 420 396 421 physIntLength = positronProcs.ss->Post << 397 G4double GetPhysicalInteractionLength(const G4Track& track) override 422 if (physIntLength < fProposedStep) { << 398 { 423 fProposedStep = physIntLength; << 399 auto& positronProcs = fMgr.fPositronProcs; 424 fSelected = 0; << 400 G4double physIntLength, proposedSafety = DBL_MAX; 425 } << 401 G4ForceCondition condition; >> 402 G4GPILSelection selection; 426 403 427 physIntLength = << 404 fProposedStep = DBL_MAX; 428 positronProcs.annihilation->PostStep << 405 fSelected = -1; 429 if (physIntLength < fProposedStep) { << 430 fProposedStep = physIntLength; << 431 fSelected = 1; << 432 } << 433 406 434 physIntLength = positronProcs.brems->P << 407 physIntLength = positronProcs.ss->PostStepGPIL(track, fPreviousStepLength, &condition); 435 if (physIntLength < fProposedStep) { << 408 if (physIntLength < fProposedStep) { 436 fProposedStep = physIntLength; << 409 fProposedStep = physIntLength; 437 fSelected = 2; << 410 fSelected = 0; 438 } << 411 } 439 412 440 physIntLength = positronProcs.ioni->Po << 413 physIntLength = 441 if (physIntLength < fProposedStep) { << 414 positronProcs.annihilation->PostStepGPIL(track, fPreviousStepLength, &condition); 442 fProposedStep = physIntLength; << 415 if (physIntLength < fProposedStep) { 443 fSelected = 3; << 416 fProposedStep = physIntLength; 444 } << 417 fSelected = 1; >> 418 } 445 419 446 physIntLength = positronProcs.ioni->Al << 420 physIntLength = positronProcs.brems->PostStepGPIL(track, fPreviousStepLength, &condition); 447 << 421 if (physIntLength < fProposedStep) { 448 if (physIntLength < fProposedStep) { << 422 fProposedStep = physIntLength; 449 fProposedStep = physIntLength; << 423 fSelected = 2; 450 fSelected = -1; << 424 } 451 } << 452 425 453 physIntLength = positronProcs.msc->Alo << 426 physIntLength = positronProcs.ioni->PostStepGPIL(track, fPreviousStepLength, &condition); 454 << 427 if (physIntLength < fProposedStep) { 455 if (physIntLength < fProposedStep) { << 428 fProposedStep = physIntLength; 456 fProposedStep = physIntLength; << 429 fSelected = 3; 457 // Check if MSC actually wants to wi << 430 } 458 // step size. << 459 if (selection == CandidateForSelecti << 460 fSelected = -1; << 461 } << 462 } << 463 431 464 return fProposedStep; << 432 physIntLength = positronProcs.ioni->AlongStepGPIL( >> 433 track, fPreviousStepLength, fProposedStep, proposedSafety, &selection); >> 434 if (physIntLength < fProposedStep) { >> 435 fProposedStep = physIntLength; >> 436 fSelected = -1; 465 } 437 } 466 438 467 void AlongStepDoIt(G4Track& track, G4Ste << 439 physIntLength = positronProcs.msc->AlongStepGPIL( 468 { << 440 track, fPreviousStepLength, fProposedStep, proposedSafety, &selection); 469 if (step.GetStepLength() == fProposedS << 441 if (physIntLength < fProposedStep) { 470 step.GetPostStepPoint()->SetStepStat << 442 fProposedStep = physIntLength; 471 } << 443 // Check if MSC actually wants to win, in most cases it only limits the 472 else { << 444 // step size. 473 // Remember that the step was limite << 445 if (selection == CandidateForSelection) { 474 fSelected = -1; 446 fSelected = -1; 475 } 447 } 476 auto& positronProcs = fMgr.fPositronPr << 448 } 477 G4VParticleChange* particleChange; << 478 449 479 particleChange = positronProcs.msc->Al << 450 return fProposedStep; 480 particleChange->UpdateStepForAlongStep << 451 } 481 track.SetTrackStatus(particleChange->G << 482 particleChange->Clear(); << 483 << 484 particleChange = positronProcs.ioni->A << 485 particleChange->UpdateStepForAlongStep << 486 track.SetTrackStatus(particleChange->G << 487 particleChange->Clear(); << 488 << 489 fPreviousStepLength = step.GetStepLeng << 490 } << 491 << 492 void PostStepDoIt(G4Track& track, G4Step << 493 { << 494 if (fSelected < 0) { << 495 return; << 496 } << 497 step.GetPostStepPoint()->SetStepStatus << 498 452 499 auto& positronProcs = fMgr.fPositronPr << 453 void AlongStepDoIt(G4Track& track, G4Step& step, G4TrackVector&) override 500 G4VProcess* process = nullptr; << 454 { 501 G4VParticleChange* particleChange = nu << 455 if (step.GetStepLength() == fProposedStep) { 502 << 456 step.GetPostStepPoint()->SetStepStatus(fAlongStepDoItProc); 503 switch (fSelected) { << 457 } 504 case 0: << 458 else { 505 process = positronProcs.ss; << 459 // Remember that the step was limited by geometry. 506 particleChange = positronProcs.ss- << 460 fSelected = -1; 507 break; << 461 } 508 case 1: << 462 auto& positronProcs = fMgr.fPositronProcs; 509 process = positronProcs.annihilati << 463 G4VParticleChange* particleChange; 510 particleChange = positronProcs.ann << 511 break; << 512 case 2: << 513 process = positronProcs.brems; << 514 particleChange = positronProcs.bre << 515 break; << 516 case 3: << 517 process = positronProcs.ioni; << 518 particleChange = positronProcs.ion << 519 break; << 520 } << 521 464 522 particleChange->UpdateStepForPostStep( << 465 particleChange = positronProcs.msc->AlongStepDoIt(track, step); 523 step.UpdateTrack(); << 466 particleChange->UpdateStepForAlongStep(&step); >> 467 track.SetTrackStatus(particleChange->GetTrackStatus()); >> 468 particleChange->Clear(); >> 469 >> 470 particleChange = positronProcs.ioni->AlongStepDoIt(track, step); >> 471 particleChange->UpdateStepForAlongStep(&step); >> 472 track.SetTrackStatus(particleChange->GetTrackStatus()); >> 473 particleChange->Clear(); 524 474 525 G4int numSecondaries = particleChange- << 475 fPreviousStepLength = step.GetStepLength(); 526 for (G4int i = 0; i < numSecondaries; << 476 } 527 G4Track* secondary = particleChange- << 528 secondary->SetParentID(track.GetTrac << 529 secondary->SetCreatorProcess(process << 530 secondaries.push_back(secondary); << 531 } << 532 477 533 track.SetTrackStatus(particleChange->G << 478 void PostStepDoIt(G4Track& track, G4Step& step, G4TrackVector& secondaries) override 534 particleChange->Clear(); << 479 { >> 480 if (fSelected < 0) { >> 481 return; >> 482 } >> 483 step.GetPostStepPoint()->SetStepStatus(fPostStepDoItProc); >> 484 >> 485 auto& positronProcs = fMgr.fPositronProcs; >> 486 G4VProcess* process; >> 487 G4VParticleChange* particleChange = nullptr; >> 488 >> 489 switch (fSelected) { >> 490 case 0: >> 491 process = positronProcs.ss; >> 492 particleChange = positronProcs.ss->PostStepDoIt(track, step); >> 493 break; >> 494 case 1: >> 495 process = positronProcs.annihilation; >> 496 particleChange = positronProcs.annihilation->PostStepDoIt(track, step); >> 497 break; >> 498 case 2: >> 499 process = positronProcs.brems; >> 500 particleChange = positronProcs.brems->PostStepDoIt(track, step); >> 501 break; >> 502 case 3: >> 503 process = positronProcs.ioni; >> 504 particleChange = positronProcs.ioni->PostStepDoIt(track, step); >> 505 break; >> 506 } >> 507 >> 508 particleChange->UpdateStepForPostStep(&step); >> 509 step.UpdateTrack(); >> 510 >> 511 int numSecondaries = particleChange->GetNumberOfSecondaries(); >> 512 for (int i = 0; i < numSecondaries; i++) { >> 513 G4Track* secondary = particleChange->GetSecondary(i); >> 514 secondary->SetParentID(track.GetTrackID()); >> 515 secondary->SetCreatorProcess(process); >> 516 secondaries.push_back(secondary); 535 } 517 } 536 518 537 G4bool HasAtRestProcesses() override { r << 519 track.SetTrackStatus(particleChange->GetTrackStatus()); >> 520 particleChange->Clear(); >> 521 } 538 522 539 void AtRestDoIt(G4Track& track, G4Step& << 523 G4bool HasAtRestProcesses() override { return true; } 540 { << 541 auto& positronProcs = fMgr.fPositronPr << 542 // Annihilate the positron at rest. << 543 G4VParticleChange* particleChange = po << 544 particleChange->UpdateStepForAtRest(&s << 545 step.UpdateTrack(); << 546 << 547 G4int numSecondaries = particleChange- << 548 for (G4int i = 0; i < numSecondaries; << 549 G4Track* secondary = particleChange- << 550 secondary->SetParentID(track.GetTrac << 551 secondary->SetCreatorProcess(positro << 552 secondaries.push_back(secondary); << 553 } << 554 524 555 track.SetTrackStatus(particleChange->G << 525 void AtRestDoIt(G4Track& track, G4Step& step, G4TrackVector& secondaries) override 556 particleChange->Clear(); << 526 { >> 527 auto& positronProcs = fMgr.fPositronProcs; >> 528 // Annihilate the positron at rest. >> 529 G4VParticleChange* particleChange = positronProcs.annihilation->AtRestDoIt(track, step); >> 530 particleChange->UpdateStepForAtRest(&step); >> 531 step.UpdateTrack(); >> 532 >> 533 int numSecondaries = particleChange->GetNumberOfSecondaries(); >> 534 for (int i = 0; i < numSecondaries; i++) { >> 535 G4Track* secondary = particleChange->GetSecondary(i); >> 536 secondary->SetParentID(track.GetTrackID()); >> 537 secondary->SetCreatorProcess(positronProcs.annihilation); >> 538 secondaries.push_back(secondary); 557 } 539 } 558 540 559 private: << 541 track.SetTrackStatus(particleChange->GetTrackStatus()); 560 EmStandardPhysicsTrackingManager& fMgr; << 542 particleChange->Clear(); 561 G4double fPreviousStepLength; << 543 } 562 G4double fProposedStep; << 544 563 G4int fSelected; << 545 private: >> 546 EmStandardPhysicsTrackingManager& fMgr; >> 547 G4double fPreviousStepLength; >> 548 G4double fProposedStep; >> 549 G4int fSelected; 564 }; 550 }; 565 551 566 PositronPhysics physics(*this); 552 PositronPhysics physics(*this); 567 TrackingManagerHelper::TrackChargedParticle( 553 TrackingManagerHelper::TrackChargedParticle(aTrack, physics); 568 } 554 } 569 555 570 //....oooOO0OOooo........oooOO0OOooo........oo << 571 << 572 void EmStandardPhysicsTrackingManager::TrackGa 556 void EmStandardPhysicsTrackingManager::TrackGamma(G4Track* aTrack) 573 { 557 { 574 class GammaPhysics final : public TrackingMa 558 class GammaPhysics final : public TrackingManagerHelper::Physics 575 { 559 { 576 public: << 560 public: 577 GammaPhysics(EmStandardPhysicsTrackingMa << 561 GammaPhysics(EmStandardPhysicsTrackingManager& mgr) : fMgr(mgr) {} 578 << 579 void StartTracking(G4Track* aTrack) over << 580 { << 581 auto& gammaProcs = fMgr.fGammaProcs; << 582 << 583 gammaProcs.pe->StartTracking(aTrack); << 584 gammaProcs.compton->StartTracking(aTra << 585 gammaProcs.conversion->StartTracking(a << 586 gammaProcs.rayleigh->StartTracking(aTr << 587 562 588 fPreviousStepLength = 0; << 563 void StartTracking(G4Track* aTrack) override 589 } << 564 { 590 void EndTracking() override << 565 auto& gammaProcs = fMgr.fGammaProcs; 591 { << 566 592 auto& gammaProcs = fMgr.fGammaProcs; << 567 gammaProcs.pe->StartTracking(aTrack); 593 << 568 gammaProcs.compton->StartTracking(aTrack); 594 gammaProcs.pe->EndTracking(); << 569 gammaProcs.conversion->StartTracking(aTrack); 595 gammaProcs.compton->EndTracking(); << 570 gammaProcs.rayleigh->StartTracking(aTrack); 596 gammaProcs.conversion->EndTracking(); << 597 gammaProcs.rayleigh->EndTracking(); << 598 } << 599 << 600 G4double GetPhysicalInteractionLength(co << 601 { << 602 auto& gammaProcs = fMgr.fGammaProcs; << 603 G4double physIntLength; << 604 G4ForceCondition condition; << 605 << 606 fProposedStep = DBL_MAX; << 607 fSelected = -1; << 608 571 609 physIntLength = gammaProcs.rayleigh->P << 572 fPreviousStepLength = 0; 610 if (physIntLength < fProposedStep) { << 573 } 611 fProposedStep = physIntLength; << 574 void EndTracking() override 612 fSelected = 0; << 575 { 613 } << 576 auto& gammaProcs = fMgr.fGammaProcs; 614 << 577 615 physIntLength = gammaProcs.conversion- << 578 gammaProcs.pe->EndTracking(); 616 if (physIntLength < fProposedStep) { << 579 gammaProcs.compton->EndTracking(); 617 fProposedStep = physIntLength; << 580 gammaProcs.conversion->EndTracking(); 618 fSelected = 1; << 581 gammaProcs.rayleigh->EndTracking(); 619 } << 582 } 620 583 621 physIntLength = gammaProcs.compton->Po << 584 G4double GetPhysicalInteractionLength(const G4Track& track) override 622 if (physIntLength < fProposedStep) { << 585 { 623 fProposedStep = physIntLength; << 586 auto& gammaProcs = fMgr.fGammaProcs; 624 fSelected = 2; << 587 G4double physIntLength; 625 } << 588 G4ForceCondition condition; 626 589 627 physIntLength = gammaProcs.pe->PostSte << 590 fProposedStep = DBL_MAX; 628 if (physIntLength < fProposedStep) { << 591 fSelected = -1; 629 fProposedStep = physIntLength; << 630 fSelected = 3; << 631 } << 632 592 633 return fProposedStep; << 593 physIntLength = gammaProcs.rayleigh->PostStepGPIL(track, fPreviousStepLength, &condition); >> 594 if (physIntLength < fProposedStep) { >> 595 fProposedStep = physIntLength; >> 596 fSelected = 0; 634 } 597 } 635 598 636 void AlongStepDoIt(G4Track&, G4Step& ste << 599 physIntLength = gammaProcs.conversion->PostStepGPIL(track, fPreviousStepLength, &condition); 637 { << 600 if (physIntLength < fProposedStep) { 638 if (step.GetStepLength() == fProposedS << 601 fProposedStep = physIntLength; 639 step.GetPostStepPoint()->SetStepStat << 602 fSelected = 1; 640 } << 641 else { << 642 // Remember that the step was limite << 643 fSelected = -1; << 644 } << 645 fPreviousStepLength = step.GetStepLeng << 646 } 603 } 647 604 648 void PostStepDoIt(G4Track& track, G4Step << 605 physIntLength = gammaProcs.compton->PostStepGPIL(track, fPreviousStepLength, &condition); 649 { << 606 if (physIntLength < fProposedStep) { 650 if (fSelected < 0) { << 607 fProposedStep = physIntLength; 651 return; << 608 fSelected = 2; 652 } << 609 } 653 step.GetPostStepPoint()->SetStepStatus << 654 610 655 auto& gammaProcs = fMgr.fGammaProcs; << 611 physIntLength = gammaProcs.pe->PostStepGPIL(track, fPreviousStepLength, &condition); 656 G4VProcess* process = nullptr; << 612 if (physIntLength < fProposedStep) { 657 G4VParticleChange* particleChange = nu << 613 fProposedStep = physIntLength; 658 << 614 fSelected = 3; 659 switch (fSelected) { << 615 } 660 case 0: << 661 process = gammaProcs.rayleigh; << 662 particleChange = gammaProcs.raylei << 663 break; << 664 case 1: << 665 process = gammaProcs.conversion; << 666 particleChange = gammaProcs.conver << 667 break; << 668 case 2: << 669 process = gammaProcs.compton; << 670 particleChange = gammaProcs.compto << 671 break; << 672 case 3: << 673 process = gammaProcs.pe; << 674 particleChange = gammaProcs.pe->Po << 675 break; << 676 } << 677 616 678 particleChange->UpdateStepForPostStep( << 617 return fProposedStep; 679 step.UpdateTrack(); << 618 } 680 619 681 G4int numSecondaries = particleChange- << 620 void AlongStepDoIt(G4Track&, G4Step& step, G4TrackVector&) override 682 for (G4int i = 0; i < numSecondaries; << 621 { 683 G4Track* secondary = particleChange- << 622 if (step.GetStepLength() == fProposedStep) { 684 secondary->SetParentID(track.GetTrac << 623 step.GetPostStepPoint()->SetStepStatus(fAlongStepDoItProc); 685 secondary->SetCreatorProcess(process << 624 } 686 secondaries.push_back(secondary); << 625 else { 687 } << 626 // Remember that the step was limited by geometry. >> 627 fSelected = -1; >> 628 } >> 629 fPreviousStepLength = step.GetStepLength(); >> 630 } 688 631 689 track.SetTrackStatus(particleChange->G << 632 void PostStepDoIt(G4Track& track, G4Step& step, G4TrackVector& secondaries) override 690 particleChange->Clear(); << 633 { >> 634 if (fSelected < 0) { >> 635 return; >> 636 } >> 637 step.GetPostStepPoint()->SetStepStatus(fPostStepDoItProc); >> 638 >> 639 auto& gammaProcs = fMgr.fGammaProcs; >> 640 G4VProcess* process = nullptr; >> 641 G4VParticleChange* particleChange = nullptr; >> 642 >> 643 switch (fSelected) { >> 644 case 0: >> 645 process = gammaProcs.rayleigh; >> 646 particleChange = gammaProcs.rayleigh->PostStepDoIt(track, step); >> 647 break; >> 648 case 1: >> 649 process = gammaProcs.conversion; >> 650 particleChange = gammaProcs.conversion->PostStepDoIt(track, step); >> 651 break; >> 652 case 2: >> 653 process = gammaProcs.compton; >> 654 particleChange = gammaProcs.compton->PostStepDoIt(track, step); >> 655 break; >> 656 case 3: >> 657 process = gammaProcs.pe; >> 658 particleChange = gammaProcs.pe->PostStepDoIt(track, step); >> 659 break; >> 660 } >> 661 >> 662 particleChange->UpdateStepForPostStep(&step); >> 663 step.UpdateTrack(); >> 664 >> 665 int numSecondaries = particleChange->GetNumberOfSecondaries(); >> 666 for (int i = 0; i < numSecondaries; i++) { >> 667 G4Track* secondary = particleChange->GetSecondary(i); >> 668 secondary->SetParentID(track.GetTrackID()); >> 669 secondary->SetCreatorProcess(process); >> 670 secondaries.push_back(secondary); 691 } 671 } 692 672 693 private: << 673 track.SetTrackStatus(particleChange->GetTrackStatus()); 694 EmStandardPhysicsTrackingManager& fMgr; << 674 particleChange->Clear(); 695 G4double fPreviousStepLength; << 675 } 696 G4double fProposedStep; << 676 697 G4int fSelected; << 677 private: >> 678 EmStandardPhysicsTrackingManager& fMgr; >> 679 G4double fPreviousStepLength; >> 680 G4double fProposedStep; >> 681 G4int fSelected; 698 }; 682 }; 699 683 700 GammaPhysics physics(*this); 684 GammaPhysics physics(*this); 701 TrackingManagerHelper::TrackNeutralParticle( 685 TrackingManagerHelper::TrackNeutralParticle(aTrack, physics); 702 } 686 } 703 687 704 //....oooOO0OOooo........oooOO0OOooo........oo << 705 << 706 void EmStandardPhysicsTrackingManager::HandOve 688 void EmStandardPhysicsTrackingManager::HandOverOneTrack(G4Track* aTrack) 707 { 689 { 708 const G4ParticleDefinition* part = aTrack->G 690 const G4ParticleDefinition* part = aTrack->GetParticleDefinition(); 709 691 710 if (part == G4Electron::Definition()) { 692 if (part == G4Electron::Definition()) { 711 TrackElectron(aTrack); 693 TrackElectron(aTrack); 712 } 694 } 713 else if (part == G4Positron::Definition()) { 695 else if (part == G4Positron::Definition()) { 714 TrackPositron(aTrack); 696 TrackPositron(aTrack); 715 } 697 } 716 else if (part == G4Gamma::Definition()) { 698 else if (part == G4Gamma::Definition()) { 717 TrackGamma(aTrack); 699 TrackGamma(aTrack); 718 } 700 } 719 701 720 aTrack->SetTrackStatus(fStopAndKill); 702 aTrack->SetTrackStatus(fStopAndKill); 721 delete aTrack; 703 delete aTrack; 722 } 704 } 723 << 724 //....oooOO0OOooo........oooOO0OOooo........oo << 725 705