19#include "BDSBunchGaussian.hh"
21#include "BDSException.hh"
22#include "BDSGlobalConstants.hh"
24#include "parser/beam.h"
26#include "Randomize.hh"
27#include "CLHEP/Matrix/SymMatrix.h"
28#include "CLHEP/Matrix/Vector.h"
29#include "CLHEP/RandomObjects/RandMultiGauss.h"
30#include "CLHEP/Units/PhysicalConstants.h"
38 bool isPositiveDefinite(CLHEP::HepSymMatrix& S)
40 CLHEP::HepSymMatrix temp (S);
42 CLHEP::HepMatrix U = diagonalize ( &temp );
43 CLHEP::HepSymMatrix D = S.similarityT(U);
44 for (G4int i = 1; i <= S.num_row(); i++)
54BDSBunchGaussian::BDSBunchGaussian(
const G4String& nameIn):
56 meansGM(CLHEP::HepVector(6)),
57 sigmaGM(CLHEP::HepSymMatrix(6)),
58 gaussMultiGen(nullptr),
59 offsetSampleMean(false),
62 coordinates = {&x0_v, &xp_v, &y0_v, &yp_v, &z0_v, &zp_v, &E_v, &t_v, &weight_v};
65BDSBunchGaussian::~BDSBunchGaussian()
73 G4Transform3D beamlineTransformIn,
74 const G4double beamlineSIn)
90 meansGM[0] =
X0 / CLHEP::m;
92 meansGM[2] =
Y0 / CLHEP::m;
94 meansGM[4] =
T0 / CLHEP::s;
112 const CLHEP::HepVector& mu,
113 CLHEP::HepSymMatrix& sigma)
117 G4cout << __METHOD_NAME__ <<
"checking 6x6 sigma matrix is positive definite" << G4endl;
118 if (!isPositiveDefinite(sigma))
120 G4cout << __METHOD_NAME__ <<
"WARNING bunch generator sigma matrix is not positive definite" << G4endl;
121 G4cout << sigma << G4endl;
122 G4cout << __METHOD_NAME__ <<
"adding a small error to zero diagonal elements" << G4endl;
125 G4double small_error = 1e-50;
127 for (G4int i=0; i<6; i++)
130 {sigma[i][i] += small_error;}
133 if (!isPositiveDefinite(sigma))
135 G4cout << __METHOD_NAME__ <<
"WARNING bunch generator sigma matrix is still not positive definite" << G4endl;
136 G4cout << sigma << G4endl;
137 G4cout << __METHOD_NAME__ <<
"adding a small error to all elements" << G4endl;
138 for (G4int i=0; i<6; i++)
140 for (G4int j=0; j<6; j++)
143 {sigma[i][j] += small_error;}
146 if (!isPositiveDefinite(sigma))
148 G4cout << sigma << G4endl;
149 throw BDSException(__METHOD_NAME__,
"bunch generator sigma matrix is still not positive definite, giving up");
155 G4cout << __METHOD_NAME__ <<
"mean " << G4endl
157 << __METHOD_NAME__ <<
"sigma " << G4endl
160 G4cout << __METHOD_NAME__ <<
"confirmed: positive definite matrix" << G4endl;
161 return new CLHEP::RandMultiGauss(anEngine,mu,sigma);
166 G4cout << __METHOD_NAME__ <<
"Pregenerating " << nGenerate <<
" events." << G4endl;
168 G4double x_a = 0.0, xp_a = 0.0, y_a = 0.0, yp_a = 0.0;
169 G4double z_a = 0.0, zp_a = 0.0, E_a = 0.0, t_a = 0.0;
171 for (G4int iParticle = 0; iParticle < nGenerate; ++iParticle)
175 G4double nT = (G4double)iParticle + 1;
180 xp_a = xp_a + (d/nT);
184 yp_a = yp_a + (d/nT);
188 zp_a = zp_a + (d/nT);
189 d = fire.totalEnergy - E_a;
194 x0_v.push_back(fire.x);
195 xp_v.push_back(fire.xp);
196 y0_v.push_back(fire.y);
197 yp_v.push_back(fire.yp);
198 z0_v.push_back(fire.z);
199 zp_v.push_back(fire.zp);
200 E_v.push_back(fire.totalEnergy);
201 t_v.push_back(fire.T);
216 for (G4int iParticle = 0; iParticle < nGenerate; ++iParticle)
218 x0_v[iParticle] -= x_a;
219 xp_v[iParticle] -= xp_a;
220 y0_v[iParticle] -= y_a;
221 yp_v[iParticle] -= yp_a;
222 z0_v[iParticle] -= z_a;
223 zp_v[iParticle] -= zp_a;
224 E_v[iParticle] -= E_a;
225 t_v[iParticle] -= t_a;
257 G4double x = v[0] * CLHEP::m;
259 G4double y = v[2] * CLHEP::m;
270 dz = t * CLHEP::c_light;
CLHEP::RandMultiGauss * CreateMultiGauss(CLHEP::HepRandomEngine &anEngine, const CLHEP::HepVector &mu, CLHEP::HepSymMatrix &sigma)
std::vector< G4double > z0_v
Holder for pre-calculated coordinates.
std::vector< G4double > y0_v
Holder for pre-calculated coordinates.
std::vector< G4double > xp_v
Holder for pre-calculated coordinates.
virtual BDSParticleCoordsFull GetNextParticleLocal()
std::vector< G4double > t_v
Holder for pre-calculated coordinates.
CLHEP::RandMultiGauss * gaussMultiGen
Randon number generator with sigma matrix and mean.
virtual void SetOptions(const BDSParticleDefinition *beamParticle, const GMAD::Beam &beam, const BDSBunchType &distrType, G4Transform3D beamlineTransformIn=G4Transform3D::Identity, const G4double beamlineS=0)
std::vector< std::vector< G4double > * > coordinates
Convenience vector of vectors for clearing up.
std::vector< G4double > weight_v
Holder for pre-calculated coordinates.
std::vector< G4double > zp_v
Holder for pre-calculated coordinates.
G4int iPartIteration
Iterator for reading out pre-calculate coordinates.
std::vector< G4double > yp_v
Holder for pre-calculated coordinates.
virtual void BeginOfRunAction(G4int numberOfEvents, G4bool batchMode)
virtual BDSParticleCoordsFull GetNextParticleLocalCoords()
Fire random number generator and get coordinates. Can be overloaded if required.
std::vector< G4double > E_v
Holder for pre-calculated coordinates.
void PreGenerateEvents(G4int nGenerate)
Pre-generate all the particle coordinates and subtract the sample mean.
G4bool offsetSampleMean
Whether to offset the sample mean.
std::vector< G4double > x0_v
Holder for pre-calculated coordinates.
The base class for bunch distribution generators.
G4double sigmaE
Centre of distributions.
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 S0
Centre of distributions.
G4double sigmaT
Centre of distributions.
G4double Z0
Centre of distributions.
G4double X0
Centre of distributions.
G4double Zp0
Centre of distributions.
G4double Xp0
Centre of distributions.
G4double E0
Centre of distributions.
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)
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.
General exception with possible name of object and message.
A set of particle coordinates including energy and weight.
Wrapper for particle definition.
Improve type-safety of native enum data type in C++.