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 - 2024.
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
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,
133 splittingFactor,
134 splittingThresholdEK,
135 splittingFactor2,
136 splittingThresholdEK2,
137 excludeWeight1Particles,
138 muonSplittingExclusionWeight);
139 pManager->RemoveProcess(process);
140 ph->RegisterProcess(wrappedProcess, particle);
141 G4cout << "Bias> muon splitting> wrapping \"" << process->GetProcessName()
142 << "\" for particle \"" << particle->GetParticleName() << "\": x" << splittingFactor
143 << " for parent Ek > " << splittingThresholdEK / CLHEP::GeV << " GeV" << G4endl;
144 if (splittingFactor2 > 1)
145 {
146 G4cout << "Bias> muon splitting> wrapping \"" << process->GetProcessName()
147 << "\" for particle \"" << particle->GetParticleName() << "\": (2nd band) x" << splittingFactor2
148 << " for parent Ek > " << splittingThresholdEK2 / CLHEP::GeV << " GeV" << G4endl;
149 }
150 }
151 }
152
153 SetActivated();
154}
General exception with possible name of object and message.
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.
void SetActivated()
Flag this instance as activated for later querying.
Wrapper process to produce more muons by resampling the process.