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