BDSIM
BDSIM is a Geant4 extension toolkit for simulation of particle transport in accelerator beamlines.
Loading...
Searching...
No Matches
BDSGlobalConstants.cc
1/*
2Beam Delivery Simulation (BDSIM) Copyright (C) Royal Holloway,
3University of London 2001 - 2023.
4
5This file is part of BDSIM.
6
7BDSIM is free software: you can redistribute it and/or modify
8it under the terms of the GNU General Public License as published
9by the Free Software Foundation version 3 of the License.
10
11BDSIM is distributed in the hope that it will be useful, but
12WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with BDSIM. If not, see <http://www.gnu.org/licenses/>.
18*/
19#include "BDSBeamPipeInfo.hh"
20#include "BDSDebug.hh"
21#include "BDSException.hh"
22#include "BDSGlobalConstants.hh"
23#include "BDSFieldInfo.hh"
24#include "BDSIntegratorSetType.hh"
25#include "BDSOutputType.hh"
26#include "BDSPTCOneTurnMap.hh"
27#include "BDSParser.hh"
28#include "BDSSamplerCustom.hh"
29#include "BDSSamplerPlane.hh"
30#include "BDSSamplerRegistry.hh"
31#include "BDSTrajectoryFilter.hh"
32#include "BDSTrajectoryOptions.hh"
33#include "BDSTunnelInfo.hh"
34#include "BDSUtilities.hh"
35#include "BDSWarning.hh"
36
37#include "parser/options.h"
38
39#include "globals.hh"
40#include "G4Colour.hh"
41#include "G4RotationMatrix.hh"
42#include "G4ThreeVector.hh"
43#include "G4Transform3D.hh"
44#include "G4UserLimits.hh"
45#include "G4Version.hh"
46#include "G4VisAttributes.hh"
47
48#include "CLHEP/Units/SystemOfUnits.h"
49#include "CLHEP/Vector/EulerAngles.h"
50
51#include <cstdlib>
52#include <limits>
53#include <sstream>
54#include <string>
55#include <stdexcept>
56#include <utility>
57
59
61{
62 if (!instance)
63 {
65 {instance = new BDSGlobalConstants(BDSParser::Instance()->GetOptions());}
66 else
68 }
69 return instance;
70}
71
73 options(opt),
74 turnsTaken(0)
75{
78
80
81 samplerDiameter = G4double(options.samplerDiameter)*CLHEP::m;
82 curvilinearDiameter = 5*CLHEP::m;
83 curvilinearDiameterShrunkForBends = false;
84
85 // beam pipe
87 options.aper1 * CLHEP::m,
88 options.aper2 * CLHEP::m,
89 options.aper3 * CLHEP::m,
90 options.aper4 * CLHEP::m,
92 options.beampipeThickness * CLHEP::m,
94
95 // magnet geometry
96 G4double horizontalWidth = options.horizontalWidth * CLHEP::m;
98 {
99 G4cerr << __METHOD_NAME__ << "Error: option \"horizontalWidth\" " << horizontalWidth
100 << " must be greater than 2x (\"aper1\" + \"beamPipeThickness\") ("
101 << defaultBeamPipeModel->aper1 << " + " << defaultBeamPipeModel->beamPipeThickness << ")" << G4endl;
102 throw BDSException(__METHOD_NAME__,"error in beam pipe defaults");
103 }
105
106 // tunnel
108 options.tunnelThickness * CLHEP::m,
109 options.tunnelSoilThickness * CLHEP::m,
113 options.tunnelFloorOffset * CLHEP::m,
114 options.tunnelAper1 * CLHEP::m,
115 options.tunnelAper2 * CLHEP::m,
116 options.storeElossTunnel,
118
119 // defaults - parameters of the laserwire process
120 itsLaserwireWavelength = 0.532 * CLHEP::micrometer;
121 itsLaserwireDir = G4ThreeVector(1,0,0);
122 itsLaserwireTrackPhotons = true;
123 itsLaserwireTrackElectrons = true;
124
125 // initialise the default vis attributes and user limits that
126 // can be copied by various bits of geometry
127 InitVisAttributes();
128 InitDefaultUserLimits();
129
131
133
134 if (options.lengthSafetyLarge <= options.lengthSafety)
135 {throw BDSException(__METHOD_NAME__, "\"lengthSafetyLarge\" must be > \"lengthSafety\"");}
136
137 BDSSamplerPlane::chordLength = 10*LengthSafety();
138 BDSSamplerCustom::chordLength = 10*BDSSamplerPlane::chordLength;
139
141
142 // mark which trajectory filters have been set
143 trajectoryFiltersSet[BDSTrajectoryFilter::depth] = options.HasBeenSet("storeTrajectoryDepth");
144 trajectoryFiltersSet[BDSTrajectoryFilter::particle] = options.HasBeenSet("storeTrajectoryParticle") ||
145 options.HasBeenSet("storeTrajectoryParticleID");
146 trajectoryFiltersSet[BDSTrajectoryFilter::energyThreshold] = options.HasBeenSet("storeTrajectoryEnergyThreshold");
147 trajectoryFiltersSet[BDSTrajectoryFilter::sampler] = options.HasBeenSet("storeTrajectorySamplerID");
148 trajectoryFiltersSet[BDSTrajectoryFilter::elossSRange] = options.HasBeenSet("storeTrajectoryElossSRange");
149 trajectoryFiltersSet[BDSTrajectoryFilter::minimumZ] = options.HasBeenSet("trajCutGTZ");
150 trajectoryFiltersSet[BDSTrajectoryFilter::maximumR] = options.HasBeenSet("trajCutLTR");
151 trajectoryFiltersSet[BDSTrajectoryFilter::secondary] = options.HasBeenSet("storeTrajectorySecondaryParticles");
152
153 if (StoreMinimalData())
154 {
155 G4cout << "\nGlobal option> storing minimal data\n" << G4endl;
156 // these options are made with respect to the defaults in parser/optionsBase.cc - i.e. no need ot set false
157 // for a default that is false -> saves code
158 // the one on the right MUST be the one returned by this class in the getter function in the header
159 auto& o = options;
160 std::map<std::string, bool*> otc = {
161 {"storeApertureImpacts", &o.storeApertureImpacts},
162 {"storeApertureImpactsHistograms", &o.storeApertureImpactsHistograms},
163 {"storeCollimatorInfo", &o.storeCollimatorInfo},
164 {"storeCollimatorHits", &o.storeCollimatorHits},
165 {"storeCollimatorHitsLinks", &o.storeCollimatorHitsLinks},
166 {"storeCollimatorHitsIons", &o.storeCollimatorHitsIons},
167 {"storeCollimatorHitsAll", &o.storeCollimatorHitsAll},
168 {"storePrimaryHistograms", &o.storePrimaryHistograms},
169 {"storeTrajectoryTransportationSteps", &o.storeTrajectoryTransportationSteps},
170 {"storeModel", &o.storeModel}
171 };
172 for (auto& no : otc)
173 {
174 if (!options.HasBeenSet(no.first))
175 {*no.second = false;}
176 }
177 // try again for options that have multiple versions and check if any are set
178 // even though there's only one member bool we turn on / off in the options
179 std::map<std::set<std::string>, bool*> otcMultiple = {
180 {{"storeELoss", "storeEloss"}, &o.storeEloss},
181 {{"storeELoss","storeEloss"}, &o.storeEloss},
182 {{"storeELossHistograms", "storeElossHistograms"}, &o.storeElossHistograms},
183 {{"storeTrajectory", "storeTrajectories"}, &o.storeTrajectory},
184 {{"storeParticleData","storeGeant4Data"}, &o.storeParticleData},
185 {{"storePrimaries", "writePrimaries"}, &o.storePrimaries},
186 };
187 for (auto& no : otcMultiple)
188 {
189 bool hasBeenSet = false;
190 for (auto& op : no.first)
191 {hasBeenSet = hasBeenSet || options.HasBeenSet(op);}
192 if (!hasBeenSet)
193 {*no.second = false;}
194 }
195 }
196
197 // TBC
198 if (options.HasBeenSet("fieldModulator"))
199 {throw BDSException(__METHOD_NAME__, "the option \"fieldModulator\" cannot be used currently - in development");}
200
201
202 // uproot
203 if (options.uprootCompatible == 1)
204 {
205 options.samplersSplitLevel = 1;
206 options.modelSplitLevel = 2;
207 }
208
209#if G4VERSION_NUMBER > 1079
210 if (options.HasBeenSet("scintYieldFactor"))
211 {BDS::Warning("The option \"scintYieldFactor\" has no effect with Geant4 11.0 onwards");}
212#endif
213}
214
216{
217 G4ThreeVector offset = G4ThreeVector(options.beamlineX * CLHEP::m,
218 options.beamlineY * CLHEP::m,
219 options.beamlineZ * CLHEP::m);
220
221 G4RotationMatrix rm;
223 {
224 G4ThreeVector axis = G4ThreeVector(options.beamlineAxisX,
227
228 rm = G4RotationMatrix(axis, options.beamlineAngle * CLHEP::rad);
229 }
230 else
231 {
232 G4double phi = options.beamlinePhi * CLHEP::rad;
233 G4double theta = options.beamlineTheta * CLHEP::rad;
234 G4double psi = options.beamlinePsi * CLHEP::rad;
235 CLHEP::HepEulerAngles ang = CLHEP::HepEulerAngles(phi, theta, psi);
236 rm = G4RotationMatrix(ang);
237 }
238
239 beamlineTransform = G4Transform3D(rm, offset);
240}
241
242void BDSGlobalConstants::InitVisAttributes()
243{
244 //for vacuum volumes
245 invisibleVisAttr = new G4VisAttributes(G4Colour::Black());
246 invisibleVisAttr->SetVisibility(false);
247 invisibleVisAttr->SetForceLineSegmentsPerCircle(options.nSegmentsPerCircle);
248
249 //for normally invisible volumes like marker / container volumes in debug mode
250 visibleDebugVisAttr = new G4VisAttributes(); //green
251 visibleDebugVisAttr->SetColour(0,0.6,0,0.1);
252 visibleDebugVisAttr->SetVisibility(true);
253 visibleDebugVisAttr->SetForceLineSegmentsPerCircle(options.nSegmentsPerCircle);
254}
255
256void BDSGlobalConstants::InitDefaultUserLimits()
257{
258 auto pteAsVector = BDS::SplitOnWhiteSpace(ParticlesToExcludeFromCuts());
259 // construct the set of PDG IDs
260 for (G4int i = 0; i < (G4int)pteAsVector.size(); i++)
261 {
262 try
263 {
264 G4int pdgID = std::stoi(pteAsVector[i]);
265 particlesToExcludeFromCutsAsSet.insert(pdgID);
266 }
267 catch (std::logic_error& e)
268 {
269 G4String msg = "Particle ID " + pteAsVector[i] + " at index " + std::to_string(i);
270 msg += " in the option particlesToExcludeFromCutsAsSet cannot be converted to an integer";
271 throw BDSException(__METHOD_NAME__, msg);
272 }
273 }
274
275 defaultUserLimits = new G4UserLimits("default_cuts");
276 const G4double maxTime = MaxTime();
277 if (maxTime > 0)
278 {
279 G4cout << __METHOD_NAME__ << "Setting maximum tracking time to " << maxTime << " ns" << G4endl;
280 defaultUserLimits->SetUserMaxTime(maxTime);
281 }
282 defaultUserLimits->SetMaxAllowedStep(MaxStepLength());
283 defaultUserLimits->SetUserMaxTrackLength(MaxTrackLength());
284 G4double minEK = MinimumKineticEnergy();
285 defaultUserLimits->SetUserMinEkine(minEK);
286 if (minEK > 0)
287 {G4cout << __METHOD_NAME__ << "Default minimum kinetic energy for model: " << minEK/CLHEP::GeV << " GeV" << G4endl;}
288 G4double minR = MinimumRange();
289 defaultUserLimits->SetUserMinRange(minR);
290 if (minR > 0)
291 {G4cout << __METHOD_NAME__ << "Default minimum range for user limits: " << minR/CLHEP::mm << " mm" << G4endl;}
292
293
294 BDSFieldInfo::defaultUL = defaultUserLimits; // update static member for field definitions
295
296 defaultUserLimitsTunnel = new G4UserLimits(*defaultUserLimits);
297 defaultUserLimitsTunnel->SetType("default_cuts_tunnel");
298 if (BDS::IsFinite(MinimumKineticEnergyTunnel()))
299 {defaultUserLimitsTunnel->SetUserMinEkine(MinimumKineticEnergyTunnel());}
300 if (TunnelIsInfiniteAbsorber())
301 {defaultUserLimitsTunnel->SetUserMinEkine(std::numeric_limits<double>::max());}
302}
303
304G4int BDSGlobalConstants::PrintModuloEvents() const
305{
306 G4int nGenerate = NGenerate();
307 G4double fraction = PrintFractionEvents();
308 G4int printModulo = (G4int)ceil(nGenerate * fraction);
309 if (printModulo < 0)
310 {printModulo = 1;}
311
312 if (!Batch())
313 {printModulo = 1;} // interactive -> print every event
314 return printModulo;
315}
316
317G4int BDSGlobalConstants::PrintModuloTurns() const
318{
319 G4int nTurns = TurnsToTake();
320 G4double fraction = PrintFractionTurns();
321 G4int printModulo = (G4int)ceil(nTurns * fraction);
322 if (printModulo < 0)
323 {printModulo = 1;}
324
325 if (!Batch())
326 {printModulo = 1;} // interactive -> print every turn
327 return printModulo;
328}
329
330BDSGlobalConstants::~BDSGlobalConstants()
331{
333 delete tunnelInfo;
334 delete defaultUserLimits;
335 delete defaultUserLimitsTunnel;
336 delete invisibleVisAttr;
337 delete visibleDebugVisAttr;
338
339 instance = nullptr;
340}
341
343{
344 if (options.storeTrajectoryELossSRange.empty())
345 {return;}
346 std::istringstream is(options.storeTrajectoryELossSRange);
347 std::string tok;
348 while (is >> tok)
349 {
350 std::size_t loc = tok.find(':',0);
351 if (loc == std::string::npos)
352 {throw BDSException(__METHOD_NAME__, "Error: no ':' character found in option storeTrajectoryELossSRange \"" + options.storeTrajectoryELossSRange + "\" - invalid range.");}
353 G4double rstart = 0;
354 G4double rend = 0;
355 try
356 {
357 rstart = std::stod(tok.substr(0, loc));
358 rend = std::stod(tok.substr(loc+1,tok.size()));
359 }
360 catch (const std::invalid_argument& e)
361 {
362 G4cerr << "Invalid value \"" << tok << "\" in option storeTrajectoryELossSRange." << G4endl;
363 throw BDSException(__METHOD_NAME__, "Error: can't convert string to number for option storeTrajectoryELossSRange.");
364 }
365 if (rend < rstart)
366 {
367 G4String message = "Error in option storeTrajectoryElossSRange - end point "
368 + std::to_string(rend) + " is less than beginning " + std::to_string(rstart) + ".";
369 throw BDSException(__METHOD_NAME__, message);
370 }
371 elossSRange.emplace_back(rstart*CLHEP::m, rend*CLHEP::m);
372 }
373}
374
376{
377 // only if true we let this option take precedence
379 {return false;}
380 else
381 {return options.storeTrajectoryTransportationSteps;}
382}
383
385{
387 StoreTrajectoryKineticEnergy(),
388 StoreTrajectoryMomentumVector(),
389 StoreTrajectoryProcesses(),
390 StoreTrajectoryTime(),
391 StoreTrajectoryLocal(),
392 StoreTrajectoryLinks(),
393 StoreTrajectoryIon(),
394 StoreTrajectoryMaterial()};
395
396 if (StoreTrajectoryAllVariables())
397 {
398 result.storeKineticEnergy = true;
399 result.storeMomentumVector = true;
400 result.storeProcesses = true;
401 result.storeTime = true;
402 result.storeLocal = true;
403 result.storeLinks = true;
404 result.storeIon = true;
405 result.storeMaterial = true;
406 }
407 return result;
408}
Holder class for all information required to describe a beam pipe model.
G4double aper1
Public member for direct access.
G4double beamPipeThickness
Public member for direct access.
General exception with possible name of object and message.
Definition: BDSException.hh:35
static G4UserLimits * defaultUL
Cache of default user limits.
A class that holds global options and constants.
GMAD::Options options
Options instance that this is largely based on and extends.
void ProcessTrajectoryELossSRange()
Process the option string and fill the below vector.
G4double curvilinearDiameter
Curvilinear diameter for CL volumes - defaults to samplerDiameter.
BDSTunnelInfo * tunnelInfo
Tunnel model.
std::bitset< BDS::NTrajectoryFilters > trajectoryFiltersSet
Which filters were used in the options.
static BDSGlobalConstants * Instance()
Access method.
BDSOutputType outputType
Output type enum for output format to be used.
BDSIntegratorSetType integratorSet
Integrator type enum for integrator set to be used.
std::vector< std::pair< G4double, G4double > > elossSRange
Pairs of S ranges to link trajectories to.
BDS::TrajectoryOptions StoreTrajectoryOptions() const
options that require some implementation.
BDSBeamPipeInfo * defaultBeamPipeModel
Default beam pipe model information.
void InitialiseBeamlineTransform()
Prepare the G4Transform3D instance from the options for the initial beam line transform.
BDSGlobalConstants()=delete
Unused default constructors.
BDSMagnetGeometryType magnetGeometryType
Magnet geometry.
G4double samplerDiameter
Cache of sampler diameter in this class so it can be updated.
G4Transform3D beamlineTransform
Transform for start of beam line.
G4int numberToGenerate
Number of particles to generate can be set from outside (by e.g. BDSBunchPtc)
G4bool StoreTrajectoryTransportationSteps() const
options that require some implementation.
void ResetTurnNumber()
Setter.
static BDSGlobalConstants * instance
Singleton instance.
static BDSParser * Instance()
Access method.
Definition: BDSParser.cc:28
static bool IsInitialised()
Returns if parser is initialised.
Definition: BDSParser.cc:49
static G4double chordLength
The chord length for all is fixed and can be static.
Holder struct of all information required to create a section of tunnel.
std::string magnetGeometryType
default magnet geometry parameters
Definition: optionsBase.h:154
double beamlineZ
Initial beam line transform w.r.t. the world coordinate frame.
Definition: optionsBase.h:134
int nGenerate
The number of primary events to simulate.
Definition: optionsBase.h:93
double beamlineAngle
Initial beam line transform w.r.t. the world coordinate frame.
Definition: optionsBase.h:141
double tunnelSoilThickness
tunnel geometry parameters
Definition: optionsBase.h:209
std::string outputFormat
Parameter for output format.
Definition: optionsBase.h:49
bool beamlineAxisAngle
Initial beam line transform w.r.t. the world coordinate frame.
Definition: optionsBase.h:142
double tunnelFloorOffset
tunnel geometry parameters
Definition: optionsBase.h:213
std::string tunnelMaterial
tunnel geometry parameters
Definition: optionsBase.h:210
int nSegmentsPerCircle
Number of facets per 2pi in visualisation.
Definition: optionsBase.h:401
std::string soilMaterial
tunnel geometry parameters
Definition: optionsBase.h:211
double aper1
default beampipe parameters
Definition: optionsBase.h:183
double aper2
default beampipe parameters
Definition: optionsBase.h:184
double beamlinePhi
Initial beam line transform w.r.t. the world coordinate frame.
Definition: optionsBase.h:135
std::string vacMaterial
vacuum material
Definition: optionsBase.h:191
bool buildTunnelFloor
tunnel geometry parameters
Definition: optionsBase.h:212
double beamlineAxisY
Initial beam line transform w.r.t. the world coordinate frame.
Definition: optionsBase.h:139
double tunnelAper1
tunnel geometry parameters
Definition: optionsBase.h:214
std::string beampipeMaterial
default beampipe parameters
Definition: optionsBase.h:187
double beampipeThickness
default beampipe parameters
Definition: optionsBase.h:181
double beamlineX
Initial beam line transform w.r.t. the world coordinate frame.
Definition: optionsBase.h:132
std::string apertureType
default beampipe parameters
Definition: optionsBase.h:182
double tunnelAper2
tunnel geometry parameters
Definition: optionsBase.h:215
double beamlineY
Initial beam line transform w.r.t. the world coordinate frame.
Definition: optionsBase.h:133
double beamlineAxisX
Initial beam line transform w.r.t. the world coordinate frame.
Definition: optionsBase.h:138
double tunnelThickness
tunnel geometry parameters
Definition: optionsBase.h:208
double aper4
default beampipe parameters
Definition: optionsBase.h:186
double aper3
default beampipe parameters
Definition: optionsBase.h:185
std::string tunnelType
tunnel geometry parameters
Definition: optionsBase.h:207
double beamlineAxisZ
Initial beam line transform w.r.t. the world coordinate frame.
Definition: optionsBase.h:140
double beamlinePsi
Initial beam line transform w.r.t. the world coordinate frame.
Definition: optionsBase.h:137
bool trajNoTransportation
kept only for backwards compatibility.
Definition: optionsBase.h:360
bool tunnelVisible
tunnel geometry parameters
Definition: optionsBase.h:216
double beamlineTheta
Initial beam line transform w.r.t. the world coordinate frame.
Definition: optionsBase.h:136
Options class.
Definition: options.h:44
bool HasBeenSet(const std::string &name) const
Whether a parameter has been set using the set_value method or not.
Definition: options.cc:139
BDSMagnetGeometryType DetermineMagnetGeometryType(G4String geometryType)
function to determine the enum type of the magnet geometry (case-insensitive)
BDSIntegratorSetType DetermineIntegratorSetType(G4String integratorSet)
Function that gives corresponding enum value for string (case-insensitive)
BDSOutputType DetermineOutputType(G4String outputType)
Determine the output format to be used from the input string.
std::vector< G4String > SplitOnWhiteSpace(const G4String &input)
Split a string on whitespace and return a vector of these 'words'.
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())