19#include "BDSBunchPtc.hh"
21#include "BDSException.hh"
22#include "BDSGlobalConstants.hh"
23#include "BDSParticleCoordsFull.hh"
24#include "BDSUtilities.hh"
26#include "parser/beam.h"
32#include "CLHEP/Units/PhysicalConstants.h"
41BDSBunchPtc::BDSBunchPtc():
43 matchDistrFileLength(false),
51BDSBunchPtc::~BDSBunchPtc()
58 G4cout <<
"BDSBunchPtc::LoadPtcFile> opening " <<
fileName << G4endl;
64 {
throw BDSException(__METHOD_NAME__,
"\"" +
fileName +
"\" file doesn't exist - exiting as no input");}
69 for (G4int i = 0; i < nlinesSkip; i++)
71 std::getline(ifstr, line);
76 G4String msg =
"end of file reached on line " + std::to_string(lineCounter) +
" before nlinesSkip + nlinesIgnore (";
77 msg += std::to_string(nlinesSkip) +
" reached.";
81 IncrementNEventsInFileSkipped((
unsigned long long int)nlinesSkip);
84 std::regex rex(
"\\sx\\s*=\\s*([0-9eE.+-]+)");
85 std::regex rey(
"\\sy\\s*=\\s*([0-9eE.+-]+)");
86 std::regex repx(
"px\\s*=\\s*([0-9eE.+-]+)");
87 std::regex repy(
"py\\s*=\\s*([0-9eE.+-]+)");
88 std::regex ret(
"\\st\\s*=\\s*([0-9eE.+-]+)");
89 std::regex rept(
"pt\\s*=\\s*([0-9eE.+-]+)");
92 while (std::getline(ifstr,line))
95 int isComment = line.compare(0, 1,
"!");
117 std::regex_search(line,smx, rex);
118 std::regex_search(line,smy, rey);
119 std::regex_search(line,smpx,repx);
120 std::regex_search(line,smpy,repy);
121 std::regex_search(line,smt, ret);
122 std::regex_search(line,smpt, rept);
124 if(smx.size() == 2) x = std::stod(smx[1]);
125 if(smy.size() == 2) y = std::stod(smy[1]);
126 if(smpx.size() == 2) px = std::stod(smpx[1]);
127 if(smpy.size() == 2) py = std::stod(smpy[1]);
128 if(smt.size() == 2) t = std::stod(smt[1]);
129 if(smpt.size() == 2) pt = std::stod(smpt[1]);
132 G4cout << __METHOD_NAME__ <<
"read line " << line << G4endl;
133 G4cout << __METHOD_NAME__ <<
"values " << x <<
" " << px <<
" " << y <<
" " << py <<
" " << t <<
" " << pt << G4endl;
135 ptcData.emplace_back(std::array<double, 6>{x, px, y, py, t, pt});
146 G4Transform3D beamlineTransformIn,
147 const G4double beamlineSIn)
162 std::string msg =
"\nError on line " + std::to_string(lineCounter);
163 e.AppendToMessage(msg);
166 catch (std::exception& e)
168 std::string msg =
"Error on line " + std::to_string(lineCounter);
173 G4bool nGenerateHasBeenSet = g->NGenerateSet();
174 G4int nEventsPerLoop =
nRays;
176 G4int nAvailable = nEventsPerLoop * distrFileLoopNTimes;
177 G4int nGenerate = g->NGenerate();
180 if (!nGenerateHasBeenSet)
182 g->SetNumberToGenerate(nAvailable);
183 G4cout <<
"BDSBunchPtc::Initialise> distrFileMatchLength is true -> simulating " <<
nRays <<
" events";
184 if (distrFileLoopNTimes > 1)
185 {G4cout <<
" " << distrFileLoopNTimes <<
" times";}
189 G4int nEventsRemaining = nAvailable - g->StartFromEvent();
190 g->SetNumberToGenerate(nEventsRemaining);
191 G4cout <<
"BDSBunchPtc::Initialise> distrFileMatchLength + recreation -> simulate the "
192 << nEventsRemaining <<
" lines left given startFromEvent including possible looping" << G4endl;
197 G4cout <<
"BDSBunchPtc::Initialise> matchDistrFileLength has been requested "
198 <<
"but ngenerate has been specified -> use ngenerate" << G4endl;
200 if (nGenerate > nAvailable)
202 G4String msg =
"ngenerate (" + std::to_string(nGenerate) +
") is greater than the number of valid lines (";
203 msg += std::to_string(
nRays) +
") and distrFileMatchLength is on.\nChange ngenerate to <= # lines";
204 msg +=
", or don't specifcy ngenerate.\n";
205 msg +=
"This includes nlinesSkip.";
206 throw BDSException(
"BDSBunchUserFile::Initialise>", msg);
212 if ( (nGenerate >
nRays) && !distrFileLoop )
214 G4String msg =
"ngenerate (" + std::to_string(nGenerate) +
") is greater than the number of inrays (";
215 msg += std::to_string(
nRays) +
") but distrFileLoop is false in the beam command";
228 G4cout << __METHOD_NAME__ <<
"End of file reached. Returning to beginning of file." << G4endl;
231 {
throw BDSException(__METHOD_NAME__,
"unable to read another event as file finished");}
239 G4double t = (z-
Z0)*CLHEP::m / CLHEP::c_light +
T0 * CLHEP::s;
242 G4double betaSquared = std::pow(
beta,2.0);
244 G4double E =
E0 * (ptcVal + 1.0);
255 G4int nAvailable =
nRays * distrFileLoopNTimes;
256 G4int nEventsRemaining = nAvailable - eventOffset;
257 if (eventOffset >=
nRays)
261 G4int nToRoll = eventOffset %
nRays;
262 eventOffset = nToRoll;
266 G4String msg =
"eventOffset (" + std::to_string(eventOffset);
267 msg +=
") is greater than the number of inrays in the PTC file";
274 if (nGenerate > nEventsRemaining && !distrFileLoop)
276 G4String msg =
"ngenerate (" + std::to_string(nGenerate) +
") requested in recreate mode is greater than number\n";
277 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)