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