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