BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSPhysicsMuonSplitting.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2023.
4
5This file is part of BDSIM.
6
7BDSIM is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published
9by the Free Software Foundation version 3 of the License.
10
11BDSIM is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
18*/
19#include "BDSDebug.hh"
20#include "BDSException.hh"
21#include "BDSPhysicsMuonSplitting.hh"
22#include "BDSWrapperMuonSplitting.hh"
23
24#include "G4ParticleDefinition.hh"
25#include "G4ParticleTable.hh"
26#include "G4PhysicsListHelper.hh"
27#include "G4ProcessManager.hh"
28#include "G4ProcessVector.hh"
29#include "G4String.hh"
30#include "G4TrackFastVector.hh"
31#include "G4Types.hh"
32#include "G4Version.hh"
33
34#include "CLHEP/Units/SystemOfUnits.h"
35
36#include <map>
37#include <set>
38
39BDSPhysicsMuonSplitting::BDSPhysicsMuonSplitting(G4int splittingFactorIn,
40 G4double splittingThresholdEKIn,
41 G4int splittingFactor2In,
42 G4double splittingThresholdEK2In,
43 G4bool excludeWeight1ParticlesIn,
44 G4double muonSplittingExclusionWeightIn):
45 G4VPhysicsConstructor("BDSPhysicsMuonSplitting"),
46 splittingFactor(splittingFactorIn),
47 splittingThresholdEK(splittingThresholdEKIn),
48 splittingFactor2(splittingFactor2In),
49 splittingThresholdEK2(splittingThresholdEK2In),
50 excludeWeight1Particles(excludeWeight1ParticlesIn),
51 muonSplittingExclusionWeight(muonSplittingExclusionWeightIn)
52{
53 if (splittingFactorIn < 1)
54 {throw BDSException(__METHOD_NAME__, "the splitting factor must be an integer 1 or greater.");}
55 if (splittingFactor2In < 1)
56 {throw BDSException(__METHOD_NAME__, "the splitting factor #2 must be an integer 1 or greater.");}
57 G4int maxSize = G4TrackFastVectorSize/2;
58 if (splittingFactorIn > maxSize)
59 {
60 G4String msg = "the maximum safe splitting factor is " + std::to_string(maxSize);
61 msg += " based on the G4TrackFastVectorSize in Geant4";
62 throw BDSException(__METHOD_NAME__, msg);
63 }
64 if (splittingFactor2In > maxSize)
65 {
66 G4String msg = "(for factor #2) the maximum safe splitting factor is " + std::to_string(maxSize);
67 msg += " based on the G4TrackFastVectorSize in Geant4";
68 throw BDSException(__METHOD_NAME__, msg);
69 }
70}
71
72BDSPhysicsMuonSplitting::~BDSPhysicsMuonSplitting()
73{;}
74
76{;}
77
79{
80 if (Activated())
81 {return;}
82
83 if (excludeWeight1Particles)
84 {G4cout << "Bias> muon splitting> excluding weight=1 parents from splitting." << G4endl;}
85
86 // "hPairProduction" includes "MuPairProduction" but this is in fact nothing to do with producing
87 // muons. It's for producing e+e- pairs by modelling the interaction of high energy muons. This
88 // model is used to make e+e- pairs also with protons, pions, kaons. But has nothing really to
89 // do with producing muons. Red herring by name.
90 // I designed this to be able to find more than one process per particle that produces muons
91 // but in the end it looks like only 1 really. Leave for future. Micro-overhead only at setup.
92
93 // These can also potentially produce muons (from inspection of the Geant4 source code). However,
94 // this is practically quite rare and (in BDSIM at least) we don't have any final state biasing
95 // so keeping this in could invoke a very long loop to find more muons and likely unsuccessfully,
96 // so ignore these two.
97 // {"proton", {"protonInelastic"}},
98 // {"anti_proton", {"anti_protonInelastic"}},
99 std::map<G4String, std::set<G4String> > particleProcesses = {{"e+", {"AnnihiToMuPair"}},
100 {"pi+", {"Decay"}},
101 {"pi-", {"Decay"}},
102 {"kaon+", {"Decay"}},
103 {"kaon-", {"Decay"}},
104 {"kaon0L", {"Decay"}} };
105
106#if G4VERSION_NUMBER > 1029
107 auto aParticleIterator = G4ParticleTable::GetParticleTable()->GetIterator();
108#endif
109 aParticleIterator->reset();
110
111 G4PhysicsListHelper* ph = G4PhysicsListHelper::GetPhysicsListHelper();
112
113 while( (*aParticleIterator)() )
114 {
115 G4ParticleDefinition* particle = aParticleIterator->value();
116 G4String particleName = particle->GetParticleName();
117 const auto& search = particleProcesses.find(particleName);
118 if (search == particleProcesses.end())
119 {continue;}
120
121 // else it's in the set
122 G4ProcessManager* pManager = particle->GetProcessManager();
123 G4ProcessVector* processVector = pManager->GetProcessList();
124 const std::set<G4String>& processNamesToLookFor = search->second;
125 for (G4int i=0; i < (G4int)processVector->entries(); ++i)
126 {
127 G4VProcess* process = (*processVector)[i];
128 G4String processName = process->GetProcessName();
129 if (processNamesToLookFor.count(processName) == 0)
130 {continue;}
131
132 auto wrappedProcess = new BDSWrapperMuonSplitting(process, splittingFactor, splittingThresholdEK,
133 splittingFactor2, splittingThresholdEK2, excludeWeight1Particles,
134 muonSplittingExclusionWeight);
135 pManager->RemoveProcess(process);
136 ph->RegisterProcess(wrappedProcess, particle);
137 G4cout << "Bias> muon splitting> wrapping \"" << process->GetProcessName()
138 << "\" for particle \"" << particle->GetParticleName() << "\": x" << splittingFactor
139 << " for parent Ek > " << splittingThresholdEK / CLHEP::GeV << " GeV" << G4endl;
140 if (splittingFactor2 > 1)
141 {
142 G4cout << "Bias> muon splitting> wrapping \"" << process->GetProcessName()
143 << "\" for particle \"" << particle->GetParticleName() << "\": (2nd band) x" << splittingFactor2
144 << " for parent Ek > " << splittingThresholdEK2 / CLHEP::GeV << " GeV" << G4endl;
145 }
146 }
147 }
148
149 SetActivated();
150}
General exception with possible name of object and message.
Definition: BDSException.hh:35
virtual void ConstructParticle()
Construct all leptons, photons (inc optical), and pion +- just in case.
virtual void ConstructProcess()
Construct and attach the processes to the relevant particles.
G4bool Activated() const
Get whether this instance has been activated.
Definition: BDSSingleUse.hh:37
void SetActivated()
Flag this instance as activated for later querying.
Definition: BDSSingleUse.hh:40
Wrapper process to produce more muons by resampling the process.