18#include "BDSBunchPtc.hh"
20#include "BDSException.hh"
21#include "BDSGlobalConstants.hh"
22#include "BDSParticleCoordsFull.hh"
23#include "BDSUtilities.hh"
25#include "parser/beam.h"
31#include "CLHEP/Units/PhysicalConstants.h"
40BDSBunchPtc::BDSBunchPtc():
42 matchDistrFileLength(false),
50BDSBunchPtc::~BDSBunchPtc()
57 G4cout <<
"BDSBunchPtc::LoadPtcFile> opening " <<
fileName << G4endl;
63 {
throw BDSException(__METHOD_NAME__,
"\"" +
fileName +
"\" file doesn't exist - exiting as no input");}
68 for (G4int i = 0; i < nlinesSkip; i++)
70 std::getline(ifstr, line);
75 G4String msg =
"end of file reached on line " + std::to_string(lineCounter) +
" before nlinesSkip + nlinesIgnore (";
76 msg += std::to_string(nlinesSkip) +
" reached.";
80 IncrementNEventsInFileSkipped((
unsigned long long int)nlinesSkip);
83 std::regex rex(
"\\sx\\s*=\\s*([0-9eE.+-]+)");
84 std::regex rey(
"\\sy\\s*=\\s*([0-9eE.+-]+)");
85 std::regex repx(
"px\\s*=\\s*([0-9eE.+-]+)");
86 std::regex repy(
"py\\s*=\\s*([0-9eE.+-]+)");
87 std::regex ret(
"\\st\\s*=\\s*([0-9eE.+-]+)");
88 std::regex rept(
"pt\\s*=\\s*([0-9eE.+-]+)");
91 while (std::getline(ifstr,line))
94 int isComment = line.compare(0, 1,
"!");
116 std::regex_search(line,smx, rex);
117 std::regex_search(line,smy, rey);
118 std::regex_search(line,smpx,repx);
119 std::regex_search(line,smpy,repy);
120 std::regex_search(line,smt, ret);
121 std::regex_search(line,smpt, rept);
123 if(smx.size() == 2) x = std::stod(smx[1]);
124 if(smy.size() == 2) y = std::stod(smy[1]);
125 if(smpx.size() == 2) px = std::stod(smpx[1]);
126 if(smpy.size() == 2) py = std::stod(smpy[1]);
127 if(smt.size() == 2) t = std::stod(smt[1]);
128 if(smpt.size() == 2) pt = std::stod(smpt[1]);
131 G4cout << __METHOD_NAME__ <<
"read line " << line << G4endl;
132 G4cout << __METHOD_NAME__ <<
"values " << x <<
" " << px <<
" " << y <<
" " << py <<
" " << t <<
" " << pt << G4endl;
134 ptcData.emplace_back(std::array<double, 6>{x, px, y, py, t, pt});
145 G4Transform3D beamlineTransformIn,
146 const G4double beamlineSIn)
161 std::string msg =
"\nError on line " + std::to_string(lineCounter);
162 e.AppendToMessage(msg);
165 catch (std::exception& e)
167 std::string msg =
"Error on line " + std::to_string(lineCounter);
172 G4bool nGenerateHasBeenSet = g->NGenerateSet();
173 G4int nEventsPerLoop =
nRays;
175 G4int nAvailable = nEventsPerLoop * distrFileLoopNTimes;
176 G4int nGenerate = g->NGenerate();
179 if (!nGenerateHasBeenSet)
181 g->SetNumberToGenerate(nAvailable);
182 G4cout <<
"BDSBunchPtc::Initialise> distrFileMatchLength is true -> simulating " <<
nRays <<
" events";
183 if (distrFileLoopNTimes > 1)
184 {G4cout <<
" " << distrFileLoopNTimes <<
" times";}
188 G4int nEventsRemaining = nAvailable - g->StartFromEvent();
189 g->SetNumberToGenerate(nEventsRemaining);
190 G4cout <<
"BDSBunchPtc::Initialise> distrFileMatchLength + recreation -> simulate the "
191 << nEventsRemaining <<
" lines left given startFromEvent including possible looping" << G4endl;
196 G4cout <<
"BDSBunchPtc::Initialise> matchDistrFileLength has been requested "
197 <<
"but ngenerate has been specified -> use ngenerate" << G4endl;
199 if (nGenerate > nAvailable)
201 G4String msg =
"ngenerate (" + std::to_string(nGenerate) +
") is greater than the number of valid lines (";
202 msg += std::to_string(
nRays) +
") and distrFileMatchLength is on.\nChange ngenerate to <= # lines";
203 msg +=
", or don't specifcy ngenerate.\n";
204 msg +=
"This includes nlinesSkip.";
205 throw BDSException(
"BDSBunchUserFile::Initialise>", msg);
211 if ( (nGenerate >
nRays) && !distrFileLoop )
213 G4String msg =
"ngenerate (" + std::to_string(nGenerate) +
") is greater than the number of inrays (";
214 msg += std::to_string(
nRays) +
") but distrFileLoop is false in the beam command";
227 G4cout << __METHOD_NAME__ <<
"End of file reached. Returning to beginning of file." << G4endl;
230 {
throw BDSException(__METHOD_NAME__,
"unable to read another event as file finished");}
238 G4double t = (z-
Z0)*CLHEP::m / CLHEP::c_light +
T0 * CLHEP::s;
241 G4double betaSquared = std::pow(
beta,2.0);
243 G4double E =
E0 * (ptcVal + 1.0);
254 G4int nAvailable =
nRays * distrFileLoopNTimes;
255 G4int nEventsRemaining = nAvailable - eventOffset;
256 if (eventOffset >=
nRays)
260 G4int nToRoll = eventOffset %
nRays;
261 eventOffset = nToRoll;
265 G4String msg =
"eventOffset (" + std::to_string(eventOffset);
266 msg +=
") is greater than the number of inrays in the PTC file";
273 if (nGenerate > nEventsRemaining && !distrFileLoop)
275 G4String msg =
"ngenerate (" + std::to_string(nGenerate) +
") requested in recreate mode is greater than number\n";
276 msg +=
"of remaining valid lines in file (" + std::to_string(nEventsRemaining) +
") and distrFileLoop is turned off.";
An intermediate layer for any bunch classes that are file based.
unsigned long long int nEventsInFile
The number of entries in the file loaded.
virtual void SetOptions(const BDSParticleDefinition *beamParticle, const GMAD::Beam &beam, const BDSBunchType &distrType, G4Transform3D beamlineTransformIn=G4Transform3D::Identity, const G4double beamlineS=0)
Pull out the relevant options and then pass through to BDSBunch::SetOptions().
G4String fileName
File name.
virtual void RecreateAdvanceToEvent(G4int eventOffset)
void LoadPtcFile()
Load the PTC file into memory.
G4bool matchDistrFileLength
Whether to only run the number of particles in the file.
virtual BDSParticleCoordsFull GetNextParticleLocal()
G4int nRays
Number of rays in file (1 counting).
G4double beta
Velocity w.r.t. speed of light. Needed to convert mom. to energy.
virtual void Initialise()
Any initialisation - to be used after SetOptions, then CheckParameters.
G4int iRay
Iterator counter for current ray.
virtual void SetOptions(const BDSParticleDefinition *beamParticle, const GMAD::Beam &beam, const BDSBunchType &distrType, G4Transform3D beamlineTransformIn=G4Transform3D::Identity, const G4double beamlineS=0)
Pull out the relevant options and then pass through to BDSBunch::SetOptions().
std::vector< std::array< double, 6 > > ptcData
Data.
G4double Yp0
Centre of distributions.
G4double T0
Centre of distributions.
G4double S0
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.
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.
static BDSGlobalConstants * Instance()
Access method.
A set of particle coordinates including energy and weight.
Wrapper for particle definition.
G4double Beta() const
Accessor.
Improve type-safety of native enum data type in C++.
std::string distrFile
beam parameters
int nlinesIgnore
Ignore first lines in the input bunch file.
int nlinesSkip
Number of event lines to skip after the ignore lines.
bool distrFileMatchLength
beam parameters
G4String GetFullPath(G4String filename, bool excludeNameFromPath=false, bool useCWDForPrefix=false)