19#include "BDSAcceleratorModel.hh"
20#include "BDSBeamline.hh"
23#include "BDSException.hh"
24#include "BDSGlobalConstants.hh"
25#include "BDSIonDefinition.hh"
26#include "BDSParticleCoords.hh"
27#include "BDSParticleCoordsFull.hh"
28#include "BDSParticleCoordsFullGlobal.hh"
29#include "BDSParticleDefinition.hh"
30#include "BDSPhysicsUtilities.hh"
31#include "BDSUtilities.hh"
33#include "parser/beam.h"
35#include "G4IonTable.hh"
36#include "G4ParticleTable.hh"
37#include "G4ThreeVector.hh"
38#include "G4Transform3D.hh"
39#include "G4TwoVector.hh"
40#include "G4Version.hh"
42#include "CLHEP/Geometry/Point3D.h"
54BDSBunch::BDSBunch(
const G4String& nameIn):
56 X0(0.0), Y0(0.0), Z0(0.0), S0(0.0), T0(0.0),
57 Xp0(0.0), Yp0(0.0), Zp0(0.0), E0(0.0), P0(0.0),
59 sigmaT(0.0), sigmaP(0.0), sigmaE(0.0), sigmaEk(0.0),
60 useBunchTiming(false),
64 useCurvilinear(false),
65 particleDefinition(nullptr),
66 particleDefinitionHasBeenUpdated(false),
70 generatePrimariesOnly(false),
71 beamlineTransform(G4Transform3D()),
85 G4Transform3D beamlineTransformIn,
91 G4ThreeVector unitZBeamline = G4ThreeVector(0,0,-1).transform(beamlineTransformIn.getRotation());
93 beamlineTransform = G4Transform3D(beamlineTransformIn.getRotation(), beamlineTransformIn.getTranslation()+translation);
97 X0 = beam.
X0 * CLHEP::m;
98 Y0 = beam.
Y0 * CLHEP::m;
99 Z0 = beam.
Z0 * CLHEP::m;
100 S0 = beam.
S0 * CLHEP::m;
101 T0 = beam.
T0 * CLHEP::s;
102 Xp0 = beam.
Xp0 * CLHEP::rad;
103 Yp0 = beam.
Yp0 * CLHEP::rad;
116 {
throw BDSException(__METHOD_NAME__,
"only one of \"bunchFrequency\" and \"bunchPeriod\" can be set");}
122 {
throw BDSException(__METHOD_NAME__,
"\"eventsPerBunch\" <= 0. Must be > 0");}
126 {
throw BDSException(__METHOD_NAME__,
"one of \"bunchFrequency\" or \"bunchPeriod\" must be specified if \"eventsPerBunch\" > 0");}
134 std::set<std::string> keysDesign = {
"sigmaE",
"sigmaEk",
"sigmaP"};
142 else if (finiteSigmaP)
147 else if (finiteSigmaEk)
157 G4cout <<
"Beam> sigmaP: " <<
sigmaP << G4endl;
158 G4cout <<
"Beam> sigmaE: " <<
sigmaE << G4endl;
159 G4cout <<
"Beam> sigmaEk: " <<
sigmaEk << G4endl;
167 G4cout << __METHOD_NAME__ <<
"using curvilinear transform" << G4endl;
170 {
throw BDSException(__METHOD_NAME__,
"both Z0 and S0 are defined - please define only one!");}
177 G4double& emittGeometricX,
178 G4double& emittGeometricY,
179 G4double& emittNormalisedX,
180 G4double& emittNormalisedY)
182 std::set<std::string> keysDesignX = {
"emitx",
"emitnx"};
187 emittNormalisedX = G4double(beam.
emitNX);
188 emittGeometricX = G4double(beam.
emitNX) / beamParticle->
Gamma();
192 emittGeometricX = G4double(beam.
emitx);
193 emittNormalisedX = G4double(beam.
emitx) * beamParticle->
Gamma();
196 std::set<std::string> keysDesignY = {
"emity",
"emitny"};
201 emittNormalisedY = G4double(beam.
emitNY);
202 emittGeometricY = G4double(beam.
emitNY) / beamParticle->
Gamma();}
205 emittGeometricY = G4double(beam.
emity);
206 emittNormalisedY = G4double(beam.
emity) * beamParticle->
Gamma();
209 G4cout << __METHOD_NAME__ <<
"Geometric (x): " << emittGeometricX
210 <<
", Normalised (x): " << emittNormalisedX << G4endl;
211 G4cout << __METHOD_NAME__ <<
"Geometric (y): " << emittGeometricY
212 <<
", Normalised (y): " << emittNormalisedY << G4endl;
256 {
throw BDSException(__METHOD_NAME__,
"unable to generate coordinates above rest mass after 100 attempts.");}
306 G4TwoVector xy(localIn.x, localIn.y);
307 G4TwoVector xpyp(localIn.xp, localIn.yp);
312 localIn.xp = xpyp.x();
313 localIn.yp = xpyp.y();
319 coordsIn.global.T += tOffset;
331 {
throw BDSException(__METHOD_NAME__,
"no beamline constructed!");}
335 G4int beamlineIndex = 0;
336 G4double S =
S0 + localIn.z;
337 G4double sMin =
beamline->GetSMinimum();
338 G4double sMax =
beamline->GetSMaximum();
339 if (S < sMin - 1*CLHEP::m)
340 {
throw BDSException(__METHOD_NAME__,
"S less than minimum S (" + std::to_string(sMin) +
") - 1m for particle.");}
341 if (S > sMax + 1*CLHEP::m)
342 {
throw BDSException(__METHOD_NAME__,
"S greater than maximum S (" + std::to_string(sMax) +
") + 1m for particle.");}
349 G4ThreeVector cMom = G4ThreeVector(localIn.xp, localIn.yp, localIn.zp).transform(cTrans.getRotation());
351 G4ThreeVector cPos = cTrans.getTranslation();
353 G4double tOffset = S / CLHEP::c_light;
356 cMom.x(), cMom.y(), cMom.z(),
357 localIn.T + tOffset);
362 G4cout << __METHOD_NAME__ << result << G4endl;
370 G4double transMom = std::pow(xp, 2) + std::pow(yp, 2);
372 if (transMom > (1 - std::numeric_limits<double>::epsilon()))
373 {
throw BDSException(__METHOD_NAME__,
"xp, yp too large, xp: " + std::to_string(xp) +
" yp: " + std::to_string(yp));}
375 {zp = -std::sqrt(1.0 - transMom);}
377 {zp = std::sqrt(1.0 - transMom);}
387 G4IonTable* ionTable = G4ParticleTable::GetParticleTable()->GetIonTable();
389 G4ParticleDefinition* ionParticleDef = ionTable->GetIon(ionDefinition->
Z(),
398#if G4VERSION_NUMBER > 1049
const BDSBeamline * BeamlineMain() const
Accessor.
G4Transform3D GetGlobalEuclideanTransform(G4double s, G4double x=0, G4double y=0, G4int *indexOfFoundElement=nullptr) const
The base class for bunch distribution generators.
BDSParticleCoordsFullGlobal ApplyCurvilinearTransform(const BDSParticleCoordsFull &localIn) const
Calculate the global coordinates from curvilinear coordinates of a beam line.
G4double sigmaE
Centre of distributions.
virtual void BeginOfRunAction(G4int numberOfEvents, G4bool batchMode)
const BDSBeamline * beamline
A reference to the fully constructed beamline that's lazily instantiated.
bool useBunchTiming
Bunch offset in time parameters.
G4double Yp0
Centre of distributions.
G4double T0
Centre of distributions.
G4bool finiteSigmaE
Flags to ignore random number generator in case of no finite E or T.
G4double tilt
Centre of distributions.
BDSParticleCoordsFullGlobal ApplyTransform(const BDSParticleCoordsFull &localIn) const
virtual void RecreateAdvanceToEvent(G4int eventOffset)
void ApplyTilt(BDSParticleCoordsFull &localIn) const
Apply a rotation about unitZ for the local coordinates according to member variable tilt.
G4double S0
Centre of distributions.
G4int currentBunchIndex
Bunch offset in time parameters.
G4double P0
central momentum
G4bool particleDefinitionHasBeenUpdated
G4bool generatePrimariesOnly
virtual void SetGeneratePrimariesOnly(G4bool generatePrimariesOnlyIn)
G4double sigmaP
Centre of distributions.
G4bool useCurvilinear
Whether to ignore z and use s and transform for curvilinear coordinates.
G4Transform3D beamlineTransform
Transform that beam line starts with that will also be applied to coordinates.
void ApplyBunchTiming(BDSParticleCoordsFullGlobal &localIn) const
Add on the offset in T for the current bunch number (i*bunchPeriod).
G4double sigmaT
Centre of distributions.
G4double Z0
Centre of distributions.
void CalculateBunchIndex(G4int eventIndex)
Calculate which bunch index we should be at given an event index.
virtual BDSParticleCoordsFull GetNextParticleLocal()
G4double bunchPeriod
Bunch offset in time parameters.
G4double X0
Centre of distributions.
G4double Zp0
Centre of distributions.
virtual void Initialise()
Any initialisation - to be used after SetOptions, then CheckParameters.
G4double Xp0
Centre of distributions.
G4double E0
Centre of distributions.
G4double sigmaEk
Centre of distributions.
static void SetEmittances(const BDSParticleDefinition *beamParticle, const GMAD::Beam &beam, G4double &emittGeometricX, G4double &emittGeometricY, G4double &emittNormalisedX, G4double &emittNormalisedY)
G4double Y0
Centre of distributions.
virtual void SetOptions(const BDSParticleDefinition *beamParticle, const GMAD::Beam &beam, const BDSBunchType &distrType, G4Transform3D beamlineTransformIn=G4Transform3D::Identity, const G4double beamlineS=0)
virtual void UpdateIonDefinition()
G4double beamlineS
Beamline initial S position.
BDSParticleCoordsFullGlobal GetNextParticle()
G4bool finiteSigmaT
Flags to ignore random number generator in case of no finite E or T.
static G4double CalculateZp(G4double xp, G4double yp, G4double Zp0)
Calculate zp safely based on other components.
BDSParticleDefinition * particleDefinition
Particle definition for bunch - this class owns it.
virtual BDSParticleCoordsFullGlobal GetNextParticleValid(G4int maxTries=100)
G4int eventsPerBunch
Bunch offset in time parameters.
virtual void CheckParameters()
General exception with possible name of object and message.
static BDSGlobalConstants * Instance()
Access method.
Class to parse an ion particle definition.
G4double ExcitationEnergy() const
Accessor.
A set of particle coordinates in both local and global.
G4int beamlineIndex
Optional index for where transform was found.
A set of particle coordinates including energy and weight.
A set of particle coordinates.
BDSParticleCoords ApplyTransform(const G4Transform3D &transform) const
Apply a transform to the coordinates and return a copy of them transformed.
Wrapper for particle definition.
G4double Mass() const
Accessor.
G4double Momentum() const
Accessor.
G4double KineticEnergy() const
Accessor.
G4double Beta() const
Accessor.
G4double Gamma() const
Accessor.
BDSIonDefinition * IonDefinition() const
Accessor.
G4double TotalEnergy() const
Accessor.
G4bool IsAnIon() const
Accessor.
void UpdateG4ParticleDefinition(G4ParticleDefinition *particleIn)
Improve type-safety of native enum data type in C++.
double sigmaE
for the gaussian, elliptic shell, ring distributions
double emity
initial twiss parameters
double bunchFrequency
Bunch offsets in time.
double emitNY
initial twiss parameters
int eventsPerBunch
Bunch offsets in time.
double tilt
tilt of beam applied as rotation about unit local z
double emitNX
initial twiss parameters
double S0
initial beam centroid
double bunchPeriod
Bunch offsets in time.
double emitx
initial twiss parameters
double sigmaT
bunch length
double Zp0
initial beam centroid
double Z0
initial beam centroid
double X0
initial beam centroid
double Xp0
initial beam centroid
double Yp0
initial beam centroid
double Y0
initial beam centroid
double T0
initial beam centroid
void ConflictingParametersSet(const GMAD::Beam &beamDefinition, const std::set< std::string > &keys, G4int nSet, G4bool warnZeroParamsSet=true, const G4String &unitString="")
Throw an exception if too few or too many parameters are set for the supplied keys.
void FixGeant105ThreshholdsForParticle(const G4ParticleDefinition *particleDefinition)
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())
G4int NBeamParametersSet(const GMAD::Beam &beamDefinition, const std::set< std::string > &keys)
Count how many out of the set of keys in a beam instance are set.