22#include "CLHEP/Units/SystemOfUnits.h"
23#include "CLHEP/Units/PhysicalConstants.h"
25#include "G4ParticleTable.hh"
26#include "G4IonTable.hh"
27#include "G4Electron.hh"
29#include "BDSLinkTrackerInterface.hh"
30#include "BDSLinkBunch.hh"
31#include "BDSIMLink.hh"
32#include "BDSParticleDefinition.hh"
33#include "BDSException.hh"
39 int referenceParticlePDGIn,
40 double referenceKineticEnergyIn,
41 double relativeEnergyCutIn,
43 int referenceIonChargeIn,
51 referenceParticlePDGIn,
52 referenceKineticEnergyIn,
62 int referenceParticlePDGIn,
63 double referenceKineticEnergyIn,
64 double relativeEnergyCutIn,
66 int referenceIonChargeIn,
74 referenceParticlePDGIn,
75 referenceKineticEnergyIn,
90 std::cout <<
"BDSLinkTrackerInterface not initialised" << std::endl;
95BDSLinkTrackerInterface::BDSLinkTrackerInterface(std::string bdsimConfigFileIn,
96 int referenceParticlePDGIn,
97 double referenceKineticEnergyIn,
98 double relativeEnergyCutIn,
100 int referenceIonChargeIn,
102 bdsimConfigFile(bdsimConfigFileIn),
103 referenceParticlePDG(referenceParticlePDGIn),
104 referenceKineticEnergy(referenceKineticEnergyIn),
105 relativeEnergyCut(relativeEnergyCutIn),
107 referenceIonCharge(referenceIonChargeIn),
108 batchMode(batchModeIn)
111 g4particle_table = G4ParticleTable::GetParticleTable();
112 g4ion_table = g4particle_table->GetIonTable();
118 std::vector<std::string> bdsim_args;
119 bdsim_args.push_back(
"bdsim");
120 bdsim_args.push_back(
"--file="+bdsimConfigFile);
121 bdsim_args.push_back(
"--seed="+std::to_string(seed));
122 bdsim_args.push_back(
"--output=None");
126 {bdsim_args.push_back(std::string(
"--batch"));}
128 {bdsim_args.push_back(std::string(
"--vis_mac=vis.mac"));}
131 if (relativeEnergyCut < 1e-6)
132 {relativeEnergyCut = 1.0;}
133 minimumKineticEnergy = relativeEnergyCut * referenceKineticEnergy;
136 std::vector<char*> c_args;
137 for (
auto& arg : bdsim_args)
138 {c_args.push_back(
const_cast<char*
>(arg.c_str()));}
141 linkBDSIM->Initialise((
int)c_args.size(),
144 minimumKineticEnergy/CLHEP::GeV,
147 referenceParticleDefinition = PrepareBDSParticleDefinition(referenceParticlePDG,
149 referenceKineticEnergy,
151 static_cast<int>(referenceIonCharge));
155BDSLinkTrackerInterface::BDSLinkTrackerInterface(
BDSParser *parserIn,
156 int referenceParticlePDGIn,
157 double referenceKineticEnergyIn,
158 double relativeEnergyCutIn,
160 int referenceIonChargeIn,
163 referenceParticlePDG(referenceParticlePDGIn),
164 referenceKineticEnergy(referenceKineticEnergyIn),
165 relativeEnergyCut(relativeEnergyCutIn),
167 referenceIonCharge(referenceIonChargeIn),
168 batchMode(batchModeIn)
171 g4particle_table = G4ParticleTable::GetParticleTable();
172 g4ion_table = g4particle_table->GetIonTable();
176 linkBDSIM =
new BDSIMLink(linkBunch, parserIn);
178 std::vector<std::string> bdsim_args;
179 bdsim_args.push_back(
"bdsim");
180 bdsim_args.push_back(
"--seed="+std::to_string(seed));
181 bdsim_args.push_back(
"--output=None");
185 {bdsim_args.push_back(std::string(
"--batch"));}
187 {bdsim_args.push_back(std::string(
"--vis_mac=vis.mac"));}
190 if (relativeEnergyCut < 1e-6)
191 {relativeEnergyCut = 1.0;}
192 minimumKineticEnergy = relativeEnergyCut * referenceKineticEnergy;
195 std::vector<char*> c_args;
196 for (
auto& arg : bdsim_args)
197 {c_args.push_back(
const_cast<char*
>(arg.c_str()));}
200 linkBDSIM->Initialise((
int)c_args.size(),
203 minimumKineticEnergy/CLHEP::GeV,
206 referenceParticleDefinition = PrepareBDSParticleDefinition(referenceParticlePDG,
208 referenceKineticEnergy,
210 static_cast<int>(referenceIonCharge));
213BDSLinkTrackerInterface::~BDSLinkTrackerInterface()
215 std::cout <<
"BDSLinkTrackerInterface::~BDSLinkTrackerInterface" << std::endl;
220void BDSLinkTrackerInterface::Reset()
229 double kineticEnergy,
233 G4ParticleDefinition *particleDefGeant =
nullptr;
237 if (pdg < 1000000000)
239 particleDefGeant = g4particle_table->FindParticle(pdg);
248 particleDefGeant = g4ion_table->GetIon(pdg);
251 {ionCharge = particleDefGeant->GetAtomicNumber();}
254 particleDefGeant->GetAtomicNumber(),
257 auto mass = g4ion_table->GetIonMass(ionDef->
Z(), ionDef->
A());
258 auto charge = ionDef->
Charge();
260 auto bdsimPartName =
"ion " + std::to_string(ionDef->
A()) +
261 " " + std::to_string(ionDef->
Z()) +
262 " " + std::to_string(charge);
270 return particleDefinition;
275 double kineticEnergyIn,
278 G4int pdgID = (G4int) pdgIDIn;
280 G4ParticleTable* particleTable = G4ParticleTable::GetParticleTable();
281 G4ParticleDefinition* particleDefGeant;
289 if (pdgID > 1000000000)
291 G4IonTable* ionTable = particleTable->GetIonTable();
292 particleDefGeant = ionTable->GetIon(pdgID);
293 if (!particleDefGeant)
294 {
throw BDSException(
"BDSXtrackInterface> Ion \"" + std::to_string(pdgID) +
"\" not found");}
296 G4int ionCharge = ionChargeIn==0 ? particleDefGeant->GetAtomicNumber() : (G4int) ionChargeIn;
298 particleDefGeant->GetAtomicNumber(),
302 G4double mass = ionTable->GetIonMass(ionDef->
Z(), ionDef->
A());
303 G4double charge = ionDef->
Charge();
304 mass += ionDef->
NElectrons()*G4Electron::Definition()->GetPDGMass();
306 std::string bdsimPartName =
"ion " + std::to_string(
static_cast<int>(ionDef->
A()))
307 +
" " + std::to_string(
static_cast<int>(ionDef->
Z()))
308 +
" " + std::to_string(
static_cast<int>(charge));
311 kineticEnergyIn, 0, 1, ionDef, pdgID);
315 particleDefGeant = particleTable->FindParticle(pdgID);
316 if (!particleDefGeant)
317 {
throw BDSException(
"BDSLinkTrackerInterface> Particle \"" + std::to_string(pdgID) +
"\" not found");}
321 return particleDefinition;
325 double ct,
double deltap,
double chi,
326 double chargeRatio,
double ,
327 int trackid,
int pdgid)
329 auto q = chargeRatio * referenceParticleDefinition->
Charge();
330 auto mass_ratio = chargeRatio / chi;
331 auto p = referenceParticleDefinition->
Momentum() * (deltap + 1) * mass_ratio;
335 {pdg = referenceParticleDefinition->
PDGID();}
339 auto partDef = PrepareBDSParticleDefinition(pdg, 0, 0, p, (
int)q);
340 auto t = - ct * CLHEP::m / (referenceParticleDefinition->
Beta() * CLHEP::c_light);
341 auto oneplusdelta = (1 + deltap);
342 auto xp = px / oneplusdelta;
343 auto yp = py / oneplusdelta;
344 auto sqrtarg = 1 - std::pow(xp,2) - std::pow(yp,2);
349 {zp = std::sqrt(sqrtarg);}
359 partDef->TotalEnergy(),
362 linkBunch->
AddParticle(partDef, coords, trackid, trackid);
366 double px,
double py,
double pz,
368 int trackid,
int pdgid)
375 pdg = referenceParticleDefinition->
PDGID();
376 q = referenceParticleDefinition->
Charge();
381 q = G4ParticleTable::GetParticleTable()->FindParticle(pdg)->GetPDGCharge();
384 auto p = std::sqrt(std::pow(px,2) +
387 auto partDef = PrepareBDSParticleDefinition(pdg, 0, 0, p, q);
400 partDef->TotalEnergy(),
403 linkBunch->
AddParticle(partDef, coords, trackid, trackid);
406void BDSLinkTrackerInterface::AddParticles(std::vector<double>& x, std::vector<double>& y,
407 std::vector<double>& xp, std::vector<double>& yp,
408 std::vector<double>& ct, std::vector<double>& deltap,
409 std::vector<double>& chi, std::vector<double>& chargeRatio,
410 std::vector<double>& s, std::vector<int>& trackid,
411 std::vector<int>& pdgid)
413 for (
size_t i=0; i<x.size(); i++)
415 AddParticle(x[i], y[i], xp[i], yp[i], ct[i], deltap[i],
416 chi[i], chargeRatio[i], s[i], trackid[i], pdgid[i]);
420void BDSLinkTrackerInterface::AddParticles(std::vector<double>& x, std::vector<double>& y,
421 std::vector<double>& px, std::vector<double>&py,
422 std::vector<double>& pz, std::vector<double> &t,
423 std::vector<double>& s, std::vector<int> &trackid,
424 std::vector<int> &pdgid)
426 for(
size_t i=0; i<x.size(); i++)
431 trackid[i], pdgid[i]);
435void BDSLinkTrackerInterface::ClearData()
437 auto* link = GetBDSIMLink();
438 link->ClearSamplerHits();
439 auto* bunch = GetBunchLink();
440 bunch->ClearParticles();
441 auto& active_state = GetParticleActiveState();
442 std::vector<bool>().swap(active_state);
445G4ParticleDefinition* BDSLinkTrackerInterface::GetParticleDefinition(
int pdgid)
447 G4ParticleDefinition* particleDefGeant =
nullptr;
448 if (pdgid < 1000000000)
449 {particleDefGeant = g4particle_table->FindParticle(pdgid);}
451 {particleDefGeant = g4ion_table->GetIon(pdgid);}
452 return particleDefGeant;
455double BDSLinkTrackerInterface::GetParticlePDGMass(
int pdgid)
457 return GetParticleDefinition(pdgid)->GetPDGMass();
460double BDSLinkTrackerInterface::GetParticlePDGCharge(
int pdgid)
462 return GetParticleDefinition(pdgid)->GetPDGCharge();
467 return GetParticlePDGCharge(pdgid)/referenceParticleDefinition->
Charge();
472 return GetParticlePDGMass(pdgid)/referenceParticleDefinition->
Mass();
General exception with possible name of object and message.
Interface class to use BDSIM with trackers.
Class to parse an ion particle definition.
G4int NElectrons() const
Accessor.
G4double Charge() const
Accessor.
A bunch distribution that holds a bunch from a Link.
void AddParticle(BDSParticleDefinition *particleDefinitionIn, const BDSParticleCoordsFull &coordsIn, int externalParticleID, int externalParentID)
Append particle to the bunch for tracking.
double GetChi(int pdgid)
Ratio of charge ratio to mass ratio between pdgid particle and reference particle.
double GetMassRatio(int pdgid)
Ratio of mass between pdgid particle and reference particle.
double GetChargeRatio(int pdgid)
Ratio of charge between pdgid particle and reference particle.
void AddParticle(double x, double y, double px, double py, double ct, double deltap, double chi, double chargeRatio, double s, int trackid, int pdgid)
Const entry to parser objects.
A set of particle coordinates including energy and weight.
Wrapper for particle definition.
G4double Mass() const
Accessor.
G4double Momentum() const
Accessor.
G4double Charge() const
Accessor.
G4double Beta() const
Accessor.