File indexing completed on 2024-10-04 22:55:05
0001 #include "SimG4Core/PhysicsLists/interface/CMSEmStandardPhysicsTrackingManager.h"
0002 #include "TrackingManagerHelper.h"
0003
0004 #include "G4CoulombScattering.hh"
0005 #include "G4UrbanMscModel.hh"
0006 #include "G4WentzelVIModel.hh"
0007 #include "G4eBremsstrahlung.hh"
0008 #include "G4eCoulombScatteringModel.hh"
0009 #include "G4eIonisation.hh"
0010 #include "G4eMultipleScattering.hh"
0011 #include "G4eplusAnnihilation.hh"
0012
0013 #include "G4ElectroVDNuclearModel.hh"
0014 #include "G4ElectronNuclearProcess.hh"
0015 #include "G4PositronNuclearProcess.hh"
0016
0017 #include "G4ComptonScattering.hh"
0018 #include "G4GammaConversion.hh"
0019 #include "G4PhotoElectricEffect.hh"
0020
0021 #include "G4CascadeInterface.hh"
0022 #include "G4CrossSectionDataSetRegistry.hh"
0023 #include "G4ExcitedStringDecay.hh"
0024 #include "G4GammaNuclearXS.hh"
0025 #include "G4GammaParticipants.hh"
0026 #include "G4GeneratorPrecompoundInterface.hh"
0027 #include "G4HadronInelasticProcess.hh"
0028 #include "G4HadronicParameters.hh"
0029 #include "G4LowEGammaNuclearModel.hh"
0030 #include "G4PhotoNuclearCrossSection.hh"
0031 #include "G4QGSMFragmentation.hh"
0032 #include "G4QGSModel.hh"
0033 #include "G4TheoFSGenerator.hh"
0034
0035 #include "G4GammaGeneralProcess.hh"
0036 #include "G4LossTableManager.hh"
0037
0038 #include "G4EmParameters.hh"
0039 #include <CLHEP/Units/SystemOfUnits.h>
0040
0041 #include "G4Electron.hh"
0042 #include "G4Gamma.hh"
0043 #include "G4Positron.hh"
0044
0045 #include "G4RegionStore.hh"
0046 #include "G4Region.hh"
0047 #include <string>
0048
0049 CMSEmStandardPhysicsTrackingManager *CMSEmStandardPhysicsTrackingManager::masterTrackingManager = nullptr;
0050
0051 CMSEmStandardPhysicsTrackingManager::CMSEmStandardPhysicsTrackingManager(const edm::ParameterSet &p) {
0052 fRangeFactor = p.getParameter<double>("G4MscRangeFactor");
0053 fGeomFactor = p.getParameter<double>("G4MscGeomFactor");
0054 fSafetyFactor = p.getParameter<double>("G4MscSafetyFactor");
0055 fLambdaLimit = p.getParameter<double>("G4MscLambdaLimit") * CLHEP::mm;
0056 std::string msc = p.getParameter<std::string>("G4MscStepLimit");
0057 fStepLimitType = fUseSafety;
0058 if (msc == "UseSafetyPlus") {
0059 fStepLimitType = fUseSafetyPlus;
0060 } else if (msc == "Minimal") {
0061 fStepLimitType = fMinimal;
0062 }
0063
0064 G4EmParameters *param = G4EmParameters::Instance();
0065 G4double highEnergyLimit = param->MscEnergyLimit();
0066
0067 const G4Region *aRegion = G4RegionStore::GetInstance()->GetRegion("HcalRegion", false);
0068 const G4Region *bRegion = G4RegionStore::GetInstance()->GetRegion("HGCalRegion", false);
0069
0070
0071 {
0072 G4eMultipleScattering *msc = new G4eMultipleScattering;
0073 G4UrbanMscModel *msc1 = new G4UrbanMscModel;
0074 G4WentzelVIModel *msc2 = new G4WentzelVIModel;
0075 msc1->SetHighEnergyLimit(highEnergyLimit);
0076 msc2->SetLowEnergyLimit(highEnergyLimit);
0077 msc->SetEmModel(msc1);
0078 msc->SetEmModel(msc2);
0079
0080
0081 if (nullptr != aRegion || nullptr != bRegion) {
0082 G4UrbanMscModel *msc3 = new G4UrbanMscModel();
0083 msc3->SetHighEnergyLimit(highEnergyLimit);
0084 msc3->SetRangeFactor(fRangeFactor);
0085 msc3->SetGeomFactor(fGeomFactor);
0086 msc3->SetSafetyFactor(fSafetyFactor);
0087 msc3->SetLambdaLimit(fLambdaLimit);
0088 msc3->SetStepLimitType(fStepLimitType);
0089 msc3->SetLocked(true);
0090 if (nullptr != aRegion) {
0091 msc->AddEmModel(-1, msc3, aRegion);
0092 }
0093 if (nullptr != bRegion) {
0094 msc->AddEmModel(-1, msc3, bRegion);
0095 }
0096 }
0097
0098 electron.msc = msc;
0099
0100 electron.ioni = new G4eIonisation;
0101 electron.brems = new G4eBremsstrahlung;
0102
0103 G4CoulombScattering *ss = new G4CoulombScattering;
0104 G4eCoulombScatteringModel *ssm = new G4eCoulombScatteringModel;
0105 ssm->SetLowEnergyLimit(highEnergyLimit);
0106 ssm->SetActivationLowEnergyLimit(highEnergyLimit);
0107 ss->SetEmModel(ssm);
0108 ss->SetMinKinEnergy(highEnergyLimit);
0109 electron.ss = ss;
0110 }
0111
0112
0113 {
0114 G4eMultipleScattering *msc = new G4eMultipleScattering;
0115 G4UrbanMscModel *msc1 = new G4UrbanMscModel;
0116 G4WentzelVIModel *msc2 = new G4WentzelVIModel;
0117 msc1->SetHighEnergyLimit(highEnergyLimit);
0118 msc2->SetLowEnergyLimit(highEnergyLimit);
0119 msc->SetEmModel(msc1);
0120 msc->SetEmModel(msc2);
0121
0122
0123 if (nullptr != aRegion || nullptr != bRegion) {
0124 G4UrbanMscModel *msc3 = new G4UrbanMscModel();
0125 msc3->SetHighEnergyLimit(highEnergyLimit);
0126 msc3->SetRangeFactor(fRangeFactor);
0127 msc3->SetGeomFactor(fGeomFactor);
0128 msc3->SetSafetyFactor(fSafetyFactor);
0129 msc3->SetLambdaLimit(fLambdaLimit);
0130 msc3->SetStepLimitType(fStepLimitType);
0131 msc3->SetLocked(true);
0132 if (nullptr != aRegion) {
0133 msc->AddEmModel(-1, msc3, aRegion);
0134 }
0135 if (nullptr != bRegion) {
0136 msc->AddEmModel(-1, msc3, bRegion);
0137 }
0138 }
0139
0140 positron.msc = msc;
0141
0142 positron.ioni = new G4eIonisation;
0143 positron.brems = new G4eBremsstrahlung;
0144 positron.annihilation = new G4eplusAnnihilation;
0145
0146 G4CoulombScattering *ss = new G4CoulombScattering;
0147 G4eCoulombScatteringModel *ssm = new G4eCoulombScatteringModel;
0148 ssm->SetLowEnergyLimit(highEnergyLimit);
0149 ssm->SetActivationLowEnergyLimit(highEnergyLimit);
0150 ss->SetEmModel(ssm);
0151 ss->SetMinKinEnergy(highEnergyLimit);
0152 positron.ss = ss;
0153 }
0154
0155
0156 {
0157 gammaProc = new G4GammaGeneralProcess;
0158
0159 gammaProc->AddEmProcess(new G4PhotoElectricEffect);
0160 gammaProc->AddEmProcess(new G4ComptonScattering);
0161 gammaProc->AddEmProcess(new G4GammaConversion);
0162
0163 G4HadronInelasticProcess *nuc = new G4HadronInelasticProcess("photonNuclear", G4Gamma::Definition());
0164 auto xsreg = G4CrossSectionDataSetRegistry::Instance();
0165 G4VCrossSectionDataSet *xs = nullptr;
0166 bool useGammaNuclearXS = true;
0167 if (useGammaNuclearXS) {
0168 xs = xsreg->GetCrossSectionDataSet("GammaNuclearXS");
0169 if (nullptr == xs)
0170 xs = new G4GammaNuclearXS;
0171 } else {
0172 xs = xsreg->GetCrossSectionDataSet("PhotoNuclearXS");
0173 if (nullptr == xs)
0174 xs = new G4PhotoNuclearCrossSection;
0175 }
0176 nuc->AddDataSet(xs);
0177
0178 G4QGSModel<G4GammaParticipants> *theStringModel = new G4QGSModel<G4GammaParticipants>;
0179 G4QGSMFragmentation *theFrag = new G4QGSMFragmentation;
0180 G4ExcitedStringDecay *theStringDecay = new G4ExcitedStringDecay(theFrag);
0181 theStringModel->SetFragmentationModel(theStringDecay);
0182
0183 G4GeneratorPrecompoundInterface *theCascade = new G4GeneratorPrecompoundInterface;
0184
0185 G4TheoFSGenerator *theModel = new G4TheoFSGenerator;
0186 theModel->SetTransport(theCascade);
0187 theModel->SetHighEnergyGenerator(theStringModel);
0188
0189 G4HadronicParameters *param = G4HadronicParameters::Instance();
0190
0191 G4CascadeInterface *cascade = new G4CascadeInterface;
0192
0193
0194 G4double gnLowEnergyLimit = 200 * CLHEP::MeV;
0195 if (gnLowEnergyLimit > 0.0) {
0196 G4LowEGammaNuclearModel *lemod = new G4LowEGammaNuclearModel;
0197 lemod->SetMaxEnergy(gnLowEnergyLimit);
0198 nuc->RegisterMe(lemod);
0199 cascade->SetMinEnergy(gnLowEnergyLimit - CLHEP::MeV);
0200 }
0201 cascade->SetMaxEnergy(param->GetMaxEnergyTransitionFTF_Cascade());
0202 nuc->RegisterMe(cascade);
0203 theModel->SetMinEnergy(param->GetMinEnergyTransitionFTF_Cascade());
0204 theModel->SetMaxEnergy(param->GetMaxEnergy());
0205 nuc->RegisterMe(theModel);
0206
0207 gammaProc->AddHadProcess(nuc);
0208 G4LossTableManager::Instance()->SetGammaGeneralProcess(gammaProc);
0209 }
0210
0211
0212
0213 G4ElectroVDNuclearModel *eModel = new G4ElectroVDNuclearModel;
0214
0215 {
0216 G4ElectronNuclearProcess *nuc = new G4ElectronNuclearProcess;
0217 nuc->RegisterMe(eModel);
0218 electron.nuc = nuc;
0219 }
0220 {
0221 G4PositronNuclearProcess *nuc = new G4PositronNuclearProcess;
0222 nuc->RegisterMe(eModel);
0223 positron.nuc = nuc;
0224 }
0225
0226 if (masterTrackingManager == nullptr) {
0227 masterTrackingManager = this;
0228 } else {
0229 electron.msc->SetMasterProcess(masterTrackingManager->electron.msc);
0230 electron.ss->SetMasterProcess(masterTrackingManager->electron.ss);
0231 electron.ioni->SetMasterProcess(masterTrackingManager->electron.ioni);
0232 electron.brems->SetMasterProcess(masterTrackingManager->electron.brems);
0233 electron.nuc->SetMasterProcess(masterTrackingManager->electron.nuc);
0234
0235 positron.msc->SetMasterProcess(masterTrackingManager->positron.msc);
0236 positron.ss->SetMasterProcess(masterTrackingManager->positron.ss);
0237 positron.ioni->SetMasterProcess(masterTrackingManager->positron.ioni);
0238 positron.brems->SetMasterProcess(masterTrackingManager->positron.brems);
0239 positron.annihilation->SetMasterProcess(masterTrackingManager->positron.annihilation);
0240 positron.nuc->SetMasterProcess(masterTrackingManager->positron.nuc);
0241
0242 gammaProc->SetMasterProcess(masterTrackingManager->gammaProc);
0243 }
0244 }
0245
0246 CMSEmStandardPhysicsTrackingManager::~CMSEmStandardPhysicsTrackingManager() {
0247 if (masterTrackingManager == this) {
0248 masterTrackingManager = nullptr;
0249 }
0250 }
0251
0252 void CMSEmStandardPhysicsTrackingManager::BuildPhysicsTable(const G4ParticleDefinition &part) {
0253 if (&part == G4Electron::Definition()) {
0254 electron.msc->BuildPhysicsTable(part);
0255 electron.ioni->BuildPhysicsTable(part);
0256 electron.brems->BuildPhysicsTable(part);
0257 electron.ss->BuildPhysicsTable(part);
0258 electron.nuc->BuildPhysicsTable(part);
0259 } else if (&part == G4Positron::Definition()) {
0260 positron.msc->BuildPhysicsTable(part);
0261 positron.ioni->BuildPhysicsTable(part);
0262 positron.brems->BuildPhysicsTable(part);
0263 positron.annihilation->BuildPhysicsTable(part);
0264 positron.ss->BuildPhysicsTable(part);
0265 positron.nuc->BuildPhysicsTable(part);
0266 } else if (&part == G4Gamma::Definition()) {
0267 gammaProc->BuildPhysicsTable(part);
0268 }
0269 }
0270
0271 void CMSEmStandardPhysicsTrackingManager::PreparePhysicsTable(const G4ParticleDefinition &part) {
0272 if (&part == G4Electron::Definition()) {
0273 electron.msc->PreparePhysicsTable(part);
0274 electron.ioni->PreparePhysicsTable(part);
0275 electron.brems->PreparePhysicsTable(part);
0276 electron.ss->PreparePhysicsTable(part);
0277 electron.nuc->PreparePhysicsTable(part);
0278 } else if (&part == G4Positron::Definition()) {
0279 positron.msc->PreparePhysicsTable(part);
0280 positron.ioni->PreparePhysicsTable(part);
0281 positron.brems->PreparePhysicsTable(part);
0282 positron.annihilation->PreparePhysicsTable(part);
0283 positron.ss->PreparePhysicsTable(part);
0284 positron.nuc->PreparePhysicsTable(part);
0285 } else if (&part == G4Gamma::Definition()) {
0286 gammaProc->PreparePhysicsTable(part);
0287 }
0288 }
0289
0290 void CMSEmStandardPhysicsTrackingManager::TrackElectron(G4Track *aTrack) {
0291 class ElectronPhysics final : public TrackingManagerHelper::Physics {
0292 public:
0293 ElectronPhysics(CMSEmStandardPhysicsTrackingManager &mgr) : fMgr(mgr) {}
0294
0295 void StartTracking(G4Track *aTrack) override {
0296 auto &electron = fMgr.electron;
0297
0298 electron.msc->StartTracking(aTrack);
0299 electron.ioni->StartTracking(aTrack);
0300 electron.brems->StartTracking(aTrack);
0301 electron.ss->StartTracking(aTrack);
0302 electron.nuc->StartTracking(aTrack);
0303
0304 fPreviousStepLength = 0;
0305 }
0306 void EndTracking() override {
0307 auto &electron = fMgr.electron;
0308
0309 electron.msc->EndTracking();
0310 electron.ioni->EndTracking();
0311 electron.brems->EndTracking();
0312 electron.ss->EndTracking();
0313 electron.nuc->EndTracking();
0314 }
0315
0316 G4double GetPhysicalInteractionLength(const G4Track &track) override {
0317 auto &electron = fMgr.electron;
0318 G4double physIntLength, proposedSafety = DBL_MAX;
0319 G4ForceCondition condition;
0320 G4GPILSelection selection;
0321
0322 fProposedStep = DBL_MAX;
0323 fSelected = -1;
0324
0325 physIntLength = electron.nuc->PostStepGPIL(track, fPreviousStepLength, &condition);
0326 if (physIntLength < fProposedStep) {
0327 fProposedStep = physIntLength;
0328 fSelected = 3;
0329 }
0330
0331 physIntLength = electron.ss->PostStepGPIL(track, fPreviousStepLength, &condition);
0332 if (physIntLength < fProposedStep) {
0333 fProposedStep = physIntLength;
0334 fSelected = 0;
0335 }
0336
0337 physIntLength = electron.brems->PostStepGPIL(track, fPreviousStepLength, &condition);
0338 if (physIntLength < fProposedStep) {
0339 fProposedStep = physIntLength;
0340 fSelected = 1;
0341 }
0342
0343 physIntLength = electron.ioni->PostStepGPIL(track, fPreviousStepLength, &condition);
0344 if (physIntLength < fProposedStep) {
0345 fProposedStep = physIntLength;
0346 fSelected = 2;
0347 }
0348
0349 physIntLength =
0350 electron.ioni->AlongStepGPIL(track, fPreviousStepLength, fProposedStep, proposedSafety, &selection);
0351 if (physIntLength < fProposedStep) {
0352 fProposedStep = physIntLength;
0353 fSelected = -1;
0354 }
0355
0356 physIntLength =
0357 electron.msc->AlongStepGPIL(track, fPreviousStepLength, fProposedStep, proposedSafety, &selection);
0358 if (physIntLength < fProposedStep) {
0359 fProposedStep = physIntLength;
0360
0361
0362 if (selection == CandidateForSelection) {
0363 fSelected = -1;
0364 }
0365 }
0366
0367 return fProposedStep;
0368 }
0369
0370 void AlongStepDoIt(G4Track &track, G4Step &step, G4TrackVector &) override {
0371 if (step.GetStepLength() == fProposedStep) {
0372 step.GetPostStepPoint()->SetStepStatus(fAlongStepDoItProc);
0373 } else {
0374
0375 fSelected = -1;
0376 }
0377 auto &electron = fMgr.electron;
0378 G4VParticleChange *particleChange;
0379
0380 particleChange = electron.msc->AlongStepDoIt(track, step);
0381 particleChange->UpdateStepForAlongStep(&step);
0382 track.SetTrackStatus(particleChange->GetTrackStatus());
0383 particleChange->Clear();
0384
0385 particleChange = electron.ioni->AlongStepDoIt(track, step);
0386 particleChange->UpdateStepForAlongStep(&step);
0387 track.SetTrackStatus(particleChange->GetTrackStatus());
0388 particleChange->Clear();
0389
0390 fPreviousStepLength = step.GetStepLength();
0391 }
0392
0393 void PostStepDoIt(G4Track &track, G4Step &step, G4TrackVector &secondaries) override {
0394 if (fSelected < 0) {
0395 return;
0396 }
0397 step.GetPostStepPoint()->SetStepStatus(fPostStepDoItProc);
0398
0399 auto &electron = fMgr.electron;
0400 G4VProcess *process = nullptr;
0401 G4VParticleChange *particleChange = nullptr;
0402
0403 switch (fSelected) {
0404 case 3:
0405 process = electron.nuc;
0406 particleChange = electron.nuc->PostStepDoIt(track, step);
0407 break;
0408 case 0:
0409 process = electron.ss;
0410 particleChange = electron.ss->PostStepDoIt(track, step);
0411 break;
0412 case 1:
0413 process = electron.brems;
0414 particleChange = electron.brems->PostStepDoIt(track, step);
0415 break;
0416 case 2:
0417 process = electron.ioni;
0418 particleChange = electron.ioni->PostStepDoIt(track, step);
0419 break;
0420 }
0421 assert(particleChange);
0422 particleChange->UpdateStepForPostStep(&step);
0423 step.UpdateTrack();
0424
0425 int numSecondaries = particleChange->GetNumberOfSecondaries();
0426 for (int i = 0; i < numSecondaries; i++) {
0427 G4Track *secondary = particleChange->GetSecondary(i);
0428 secondary->SetParentID(track.GetTrackID());
0429 secondary->SetCreatorProcess(process);
0430 secondaries.push_back(secondary);
0431 }
0432
0433 track.SetTrackStatus(particleChange->GetTrackStatus());
0434 particleChange->Clear();
0435 }
0436
0437 private:
0438 CMSEmStandardPhysicsTrackingManager &fMgr;
0439 G4double fPreviousStepLength;
0440 G4double fProposedStep;
0441 G4int fSelected;
0442 };
0443
0444 ElectronPhysics physics(*this);
0445 TrackingManagerHelper::TrackChargedParticle(aTrack, physics);
0446 }
0447
0448 void CMSEmStandardPhysicsTrackingManager::TrackPositron(G4Track *aTrack) {
0449 class PositronPhysics final : public TrackingManagerHelper::Physics {
0450 public:
0451 PositronPhysics(CMSEmStandardPhysicsTrackingManager &mgr) : fMgr(mgr) {}
0452
0453 void StartTracking(G4Track *aTrack) override {
0454 auto &positron = fMgr.positron;
0455
0456 positron.msc->StartTracking(aTrack);
0457 positron.ioni->StartTracking(aTrack);
0458 positron.brems->StartTracking(aTrack);
0459 positron.annihilation->StartTracking(aTrack);
0460 positron.ss->StartTracking(aTrack);
0461 positron.nuc->StartTracking(aTrack);
0462
0463 fPreviousStepLength = 0;
0464 }
0465 void EndTracking() override {
0466 auto &positron = fMgr.positron;
0467
0468 positron.msc->EndTracking();
0469 positron.ioni->EndTracking();
0470 positron.brems->EndTracking();
0471 positron.annihilation->EndTracking();
0472 positron.ss->EndTracking();
0473 positron.nuc->EndTracking();
0474 }
0475
0476 G4double GetPhysicalInteractionLength(const G4Track &track) override {
0477 auto &positron = fMgr.positron;
0478 G4double physIntLength, proposedSafety = DBL_MAX;
0479 G4ForceCondition condition;
0480 G4GPILSelection selection;
0481
0482 fProposedStep = DBL_MAX;
0483 fSelected = -1;
0484
0485 physIntLength = positron.nuc->PostStepGPIL(track, fPreviousStepLength, &condition);
0486 if (physIntLength < fProposedStep) {
0487 fProposedStep = physIntLength;
0488 fSelected = 4;
0489 }
0490
0491 physIntLength = positron.ss->PostStepGPIL(track, fPreviousStepLength, &condition);
0492 if (physIntLength < fProposedStep) {
0493 fProposedStep = physIntLength;
0494 fSelected = 0;
0495 }
0496
0497 physIntLength = positron.annihilation->PostStepGPIL(track, fPreviousStepLength, &condition);
0498 if (physIntLength < fProposedStep) {
0499 fProposedStep = physIntLength;
0500 fSelected = 1;
0501 }
0502
0503 physIntLength = positron.brems->PostStepGPIL(track, fPreviousStepLength, &condition);
0504 if (physIntLength < fProposedStep) {
0505 fProposedStep = physIntLength;
0506 fSelected = 2;
0507 }
0508
0509 physIntLength = positron.ioni->PostStepGPIL(track, fPreviousStepLength, &condition);
0510 if (physIntLength < fProposedStep) {
0511 fProposedStep = physIntLength;
0512 fSelected = 3;
0513 }
0514
0515 physIntLength =
0516 positron.ioni->AlongStepGPIL(track, fPreviousStepLength, fProposedStep, proposedSafety, &selection);
0517 if (physIntLength < fProposedStep) {
0518 fProposedStep = physIntLength;
0519 fSelected = -1;
0520 }
0521
0522 physIntLength =
0523 positron.msc->AlongStepGPIL(track, fPreviousStepLength, fProposedStep, proposedSafety, &selection);
0524 if (physIntLength < fProposedStep) {
0525 fProposedStep = physIntLength;
0526
0527
0528 if (selection == CandidateForSelection) {
0529 fSelected = -1;
0530 }
0531 }
0532
0533 return fProposedStep;
0534 }
0535
0536 void AlongStepDoIt(G4Track &track, G4Step &step, G4TrackVector &) override {
0537 if (step.GetStepLength() == fProposedStep) {
0538 step.GetPostStepPoint()->SetStepStatus(fAlongStepDoItProc);
0539 } else {
0540
0541 fSelected = -1;
0542 }
0543 auto &positron = fMgr.positron;
0544 G4VParticleChange *particleChange;
0545
0546 particleChange = positron.msc->AlongStepDoIt(track, step);
0547 particleChange->UpdateStepForAlongStep(&step);
0548 track.SetTrackStatus(particleChange->GetTrackStatus());
0549 particleChange->Clear();
0550
0551 particleChange = positron.ioni->AlongStepDoIt(track, step);
0552 particleChange->UpdateStepForAlongStep(&step);
0553 track.SetTrackStatus(particleChange->GetTrackStatus());
0554 particleChange->Clear();
0555
0556 fPreviousStepLength = step.GetStepLength();
0557 }
0558
0559 void PostStepDoIt(G4Track &track, G4Step &step, G4TrackVector &secondaries) override {
0560 if (fSelected < 0) {
0561 return;
0562 }
0563 step.GetPostStepPoint()->SetStepStatus(fPostStepDoItProc);
0564
0565 auto &positron = fMgr.positron;
0566 G4VProcess *process;
0567 G4VParticleChange *particleChange = nullptr;
0568
0569 switch (fSelected) {
0570 case 4:
0571 process = positron.nuc;
0572 particleChange = positron.nuc->PostStepDoIt(track, step);
0573 break;
0574 case 0:
0575 process = positron.ss;
0576 particleChange = positron.ss->PostStepDoIt(track, step);
0577 break;
0578 case 1:
0579 process = positron.annihilation;
0580 particleChange = positron.annihilation->PostStepDoIt(track, step);
0581 break;
0582 case 2:
0583 process = positron.brems;
0584 particleChange = positron.brems->PostStepDoIt(track, step);
0585 break;
0586 case 3:
0587 process = positron.ioni;
0588 particleChange = positron.ioni->PostStepDoIt(track, step);
0589 break;
0590 }
0591 assert(particleChange);
0592 particleChange->UpdateStepForPostStep(&step);
0593 step.UpdateTrack();
0594
0595 int numSecondaries = particleChange->GetNumberOfSecondaries();
0596 for (int i = 0; i < numSecondaries; i++) {
0597 G4Track *secondary = particleChange->GetSecondary(i);
0598 secondary->SetParentID(track.GetTrackID());
0599 secondary->SetCreatorProcess(process);
0600 secondaries.push_back(secondary);
0601 }
0602
0603 track.SetTrackStatus(particleChange->GetTrackStatus());
0604 particleChange->Clear();
0605 }
0606
0607 G4bool HasAtRestProcesses() override { return true; }
0608
0609 void AtRestDoIt(G4Track &track, G4Step &step, G4TrackVector &secondaries) override {
0610 auto &positron = fMgr.positron;
0611
0612 G4VParticleChange *particleChange = positron.annihilation->AtRestDoIt(track, step);
0613 particleChange->UpdateStepForAtRest(&step);
0614 step.UpdateTrack();
0615
0616 int numSecondaries = particleChange->GetNumberOfSecondaries();
0617 for (int i = 0; i < numSecondaries; i++) {
0618 G4Track *secondary = particleChange->GetSecondary(i);
0619 secondary->SetParentID(track.GetTrackID());
0620 secondary->SetCreatorProcess(positron.annihilation);
0621 secondaries.push_back(secondary);
0622 }
0623
0624 track.SetTrackStatus(particleChange->GetTrackStatus());
0625 particleChange->Clear();
0626 }
0627
0628 private:
0629 CMSEmStandardPhysicsTrackingManager &fMgr;
0630 G4double fPreviousStepLength;
0631 G4double fProposedStep;
0632 G4int fSelected;
0633 };
0634
0635 PositronPhysics physics(*this);
0636 TrackingManagerHelper::TrackChargedParticle(aTrack, physics);
0637 }
0638
0639 void CMSEmStandardPhysicsTrackingManager::TrackGamma(G4Track *aTrack) {
0640 class GammaPhysics final : public TrackingManagerHelper::Physics {
0641 public:
0642 GammaPhysics(CMSEmStandardPhysicsTrackingManager &mgr) : fMgr(mgr) {}
0643
0644 void StartTracking(G4Track *aTrack) override {
0645 fMgr.gammaProc->StartTracking(aTrack);
0646
0647 fPreviousStepLength = 0;
0648 }
0649 void EndTracking() override { fMgr.gammaProc->EndTracking(); }
0650
0651 G4double GetPhysicalInteractionLength(const G4Track &track) override {
0652 G4double physIntLength;
0653 G4ForceCondition condition;
0654
0655 fProposedStep = DBL_MAX;
0656 fSelected = -1;
0657
0658 physIntLength = fMgr.gammaProc->PostStepGPIL(track, fPreviousStepLength, &condition);
0659 if (physIntLength < fProposedStep) {
0660 fProposedStep = physIntLength;
0661 fSelected = 0;
0662 }
0663
0664 return fProposedStep;
0665 }
0666
0667 void AlongStepDoIt(G4Track &, G4Step &step, G4TrackVector &) override {
0668 if (step.GetStepLength() == fProposedStep) {
0669 step.GetPostStepPoint()->SetStepStatus(fAlongStepDoItProc);
0670 } else {
0671
0672 fSelected = -1;
0673 }
0674 fPreviousStepLength = step.GetStepLength();
0675 }
0676
0677 void PostStepDoIt(G4Track &track, G4Step &step, G4TrackVector &secondaries) override {
0678 if (fSelected < 0) {
0679 return;
0680 }
0681 step.GetPostStepPoint()->SetStepStatus(fPostStepDoItProc);
0682
0683 G4VProcess *process = fMgr.gammaProc;
0684 G4VParticleChange *particleChange = fMgr.gammaProc->PostStepDoIt(track, step);
0685
0686 particleChange->UpdateStepForPostStep(&step);
0687 step.UpdateTrack();
0688
0689 int numSecondaries = particleChange->GetNumberOfSecondaries();
0690 for (int i = 0; i < numSecondaries; i++) {
0691 G4Track *secondary = particleChange->GetSecondary(i);
0692 secondary->SetParentID(track.GetTrackID());
0693 secondary->SetCreatorProcess(process);
0694 secondaries.push_back(secondary);
0695 }
0696
0697 track.SetTrackStatus(particleChange->GetTrackStatus());
0698 particleChange->Clear();
0699 }
0700
0701 private:
0702 CMSEmStandardPhysicsTrackingManager &fMgr;
0703 G4double fPreviousStepLength;
0704 G4double fProposedStep;
0705 G4int fSelected;
0706 };
0707
0708 GammaPhysics physics(*this);
0709 TrackingManagerHelper::TrackNeutralParticle(aTrack, physics);
0710 }
0711
0712 void CMSEmStandardPhysicsTrackingManager::HandOverOneTrack(G4Track *aTrack) {
0713 const G4ParticleDefinition *part = aTrack->GetParticleDefinition();
0714
0715 if (part == G4Electron::Definition()) {
0716 TrackElectron(aTrack);
0717 } else if (part == G4Positron::Definition()) {
0718 TrackPositron(aTrack);
0719 } else if (part == G4Gamma::Definition()) {
0720 TrackGamma(aTrack);
0721 }
0722
0723 aTrack->SetTrackStatus(fStopAndKill);
0724 delete aTrack;
0725 }