BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
BDSOutputROOTParticleData.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2022.
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
20#include "BDSOutputROOTParticleData.hh"
21
22#include <map>
23
24#ifndef __ROOTBUILD__
25#include "G4IonTable.hh"
26#include "G4NuclideTable.hh"
27#include "G4ParticleDefinition.hh"
28#include "G4ParticleTable.hh"
29#include "globals.hh"
30
31#include <string>
32#endif
33
35
36BDSOutputROOTParticleData::BDSOutputROOTParticleData()
37{;}
38
40{
41 particles.clear();
42 ions.clear();
43}
44
45const BDSOutputROOTParticleData::ParticleInfo BDSOutputROOTParticleData::GetParticleInfo(const int& pdgID) const
46{
47 auto result = particles.find(pdgID);
48 if (result != particles.end())
49 {return result->second;}
50 else
51 {return ParticleInfo();}
52}
53
54const BDSOutputROOTParticleData::IonInfo BDSOutputROOTParticleData::GetIonInfo(const int& pdgID) const
55{
56 auto result = ions.find(pdgID);
57 if (result != ions.end())
58 {return result->second;}
59 else
60 {return IonInfo();}
61}
62
63int BDSOutputROOTParticleData::Charge(const int& pdgID) const
64{
65 if (IsIon(pdgID))
66 {
67 auto result = ions.find(pdgID);
68 if (result != ions.end())
69 {return result->second.charge;}
70 else
71 {return 0;}
72 }
73 else
74 {
75 auto result = particles.find(pdgID);
76 if (result != particles.end())
77 {return result->second.charge;}
78 else
79 {return 0;}
80 }
81}
82
83double BDSOutputROOTParticleData::Mass(const int& pdgID) const
84{
85 if (IsIon(pdgID))
86 {
87 auto result = ions.find(pdgID);
88 if (result != ions.end())
89 {return result->second.mass;}
90 else
91 {return 0;}
92 }
93 else
94 {
95 auto result = particles.find(pdgID);
96 if (result != particles.end())
97 {return result->second.mass;}
98 else
99 {return 0;}
100 }
101}
102
104 const double& totalEnergy) const
105{
106 if (IsIon(pdgID))
107 {
108 auto result = ions.find(pdgID);
109 if (result != ions.end())
110 {return result->second.rigidity(totalEnergy);}
111 else
112 {return 0;}
113 }
114 else
115 {
116 auto result = particles.find(pdgID);
117 if (result != particles.end())
118 {return result->second.rigidity(totalEnergy);}
119 else
120 {return 0;}
121 }
122}
123
125 const double& totalEnergy) const
126{
127 if (IsIon(pdgID))
128 {
129 auto result = ions.find(pdgID);
130 if (result != ions.end())
131 {return totalEnergy - result->second.mass;}
132 else
133 {return 0;}
134 }
135 else
136 {
137 auto result = particles.find(pdgID);
138 if (result != particles.end())
139 {return totalEnergy - result->second.mass;}
140 else
141 {return 0;}
142 }
143}
144
145std::string BDSOutputROOTParticleData::Name(const int& pdgID) const
146{
147 if (IsIon(pdgID))
148 {
149 auto result = ions.find(pdgID);
150 if (result != ions.end())
151 {return result->second.name;}
152 else
153 {return "";}
154 }
155 else
156 {
157 auto result = particles.find(pdgID);
158 if (result != particles.end())
159 {return result->second.name;}
160 else
161 {return "";}
162 }
163}
164
165int BDSOutputROOTParticleData::IonA(const int& pdgID) const
166{
167 if (IsIon(pdgID))
168 {
169 auto result = ions.find(pdgID);
170 if (result != ions.end())
171 {return result->second.a;}
172 else
173 {return 0;}
174 }
175 else if (pdgID == 2212)
176 {return 1;}
177 else
178 {return 0;}
179}
180
181int BDSOutputROOTParticleData::IonZ(const int& pdgID) const
182{
183 if (IsIon(pdgID))
184 {
185 auto result = ions.find(pdgID);
186 if (result != ions.end())
187 {return result->second.z;}
188 else
189 {return 0;}
190 }
191 else if (pdgID == 2212)
192 {return 1;}
193 else
194 {return 0;}
195}
196
197#ifndef __ROOTBUILD__
199{
200 G4ParticleTable* pt = G4ParticleTable::GetParticleTable();
201
202 // iterator over particles - non-standard iterator type
203 auto it = pt->GetIterator();
204 it->reset();
205 while ((*it)() )
206 {
207 const G4ParticleDefinition* particle = it->value();
208 const G4String& particleName = particle->GetParticleName();
209
210 int pdgID = static_cast<int>(particle->GetPDGEncoding());
211
212 BDSOutputROOTParticleData::ParticleInfo info = {(std::string)particleName,
213 (int)particle->GetPDGCharge(),
214 (double)particle->GetPDGMass()/CLHEP::GeV};
215 particles[pdgID] = info;
216 }
217
218 if (fillIons)
219 {// proceed to fill ion information as it was used in the simulation
220 // A frankly ridiculous interface to get all possible ions with pdg encoding and mass.
221 // G4IonTable uses G4NuclideTable that loads file data with Geant4. We then iterate
222 // over the nuclide table and query the ion table, which in turn creates the definitions
223 // of the ions required as we query them and can then calcualte and provide the mass
224 // and pdg encoding. Normally, the ion table would only provide just a few light ions.
225 G4IonTable* ionTable = pt->GetIonTable();
226 G4NuclideTable* table = G4NuclideTable::GetInstance();
227 unsigned int number = (unsigned int)table->GetSizeOfIsotopeList();
228 for (unsigned int i = 0; i < number; i++)
229 {
230 G4IsotopeProperty* iso = table->GetIsotopeByIndex(i);
231 int atmass = iso->GetAtomicMass();
232 int atnum = iso->GetAtomicNumber();
233 double eng = iso->GetEnergy();
234 // using the excited energy always works. using the (int)lvl doesn't
235 G4ParticleDefinition* def = ionTable->GetIon(atnum, atmass, eng);
236
237 // package the information we need
238 BDSOutputROOTParticleData::IonInfo ionDef = {(std::string)def->GetParticleName(),
239 (int)def->GetPDGCharge(),
240 (double)def->GetPDGMass()/CLHEP::GeV,
241 (int)def->GetAtomicMass(),
242 (int)def->GetAtomicNumber()};
243 ions[def->GetPDGEncoding()] = ionDef;
244 }
245 }
246
247}
248#endif
Geant4 particle data for particles used in simulation.
bool IsIon(const int &pdgID) const
This doesn't count a proton (even with electrons) as an ion.
void Fill(G4bool fillIons)
Fill maps of particle information from Geant4.
double KineticEnergy(const int &pdgID, const double &totalEnergy) const
Calculate kinetic energy of particle given PDG ID and total energy in GeV.
virtual void Flush()
Clear maps.
double Rigidity(const int &pdgID, const double &totalEnergy) const
Calculate rigidity of particle given PDG ID and total energy in GeV.
Simple particle information to be stored per ion specifically.
Simple particle information to be stored per particle.