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