20#include "BDSException.hh"
21#include "BDSExtent.hh"
22#include "BDSGlobalConstants.hh"
23#include "BDSPhysicalConstants.hh"
24#include "BDSRunManager.hh"
25#include "BDSUtilities.hh"
29#include "G4ThreeVector.hh"
31#include "G4TwoVector.hh"
32#include "G4UserLimits.hh"
33#include "G4Version.hh"
35#include "CLHEP/Units/SystemOfUnits.h"
53#include <sys/resource.h>
57#include <mach-o/dyld.h>
61G4bool BDS::non_alpha::operator()(
char c)
68#if G4VERSION_NUMBER > 1099
69 return G4StrUtil::contains(str, test);
71 return str.contains(test);
74#if G4VERSION_NUMBER > 1099
75G4int
BDS::StrCompare(
const G4String& str,
const G4String& test, G4String::caseCompare)
77G4int
BDS::StrCompare(
const G4String& str,
const G4String& test, G4String::caseCompare mode)
80#if G4VERSION_NUMBER > 1099
81 return G4StrUtil::icompare(str, test);
83 return str.compareTo(test, mode);
89 G4String result = str;
90#if G4VERSION_NUMBER > 1099
91 G4StrUtil::to_lower(result);
102 G4String result = str;
105#if G4VERSION_NUMBER > 1099
106 case StringStripType::leading:
107 {G4StrUtil::lstrip(result, ch);
break;}
108 case StringStripType::trailing:
109 {G4StrUtil::rstrip(result, ch);
break;}
110 case StringStripType::both:
111 {G4StrUtil::strip(result, ch);
break;}
113 case StringStripType::leading:
114 {result.strip(G4String::stripType::leading, ch);
break;}
115 case StringStripType::trailing:
116 {result.strip(G4String::stripType::trailing, ch);
break;}
117 case StringStripType::both:
118 {result.strip(G4String::stripType::both, ch);
break;}
127 name.erase(std::remove_if(name.begin(),name.end(),isspace),name.end());
136 return angle < 0 ? 1 : -1;
147 G4double in_z = std::cos(std::abs(angleIn));
148 G4double in_x = std::sin(std::abs(angleIn));
149 G4double out_z = std::cos(std::abs(angleOut));
150 G4double out_x = std::sin(std::abs(angleOut));
151 G4ThreeVector inputface = G4ThreeVector(orientationIn*in_x, 0.0, -1.0*in_z);
152 G4ThreeVector outputface = G4ThreeVector(orientationOut*out_x, 0.0, out_z);
153 return std::make_pair(inputface,outputface);
158 if (value < lowerLimit)
159 {value = lowerLimit;}
160 if (value > upperLimit)
161 {value = upperLimit;}
166 std::ifstream infile(fileName.c_str());
167 return infile.good();
174 bool result = (stat(path.c_str(), &sb) == 0) && S_ISDIR(sb.st_mode);
175 return G4bool(result);
180 char currentPath[PATH_MAX];
181 std::string currentPathString;
183 if (getcwd(currentPath,
sizeof(currentPath)) !=
nullptr)
184 {currentPathString = std::string(currentPath);}
186 {
throw BDSException(__METHOD_NAME__,
"Cannot determine current working directory");}
188 return currentPathString;
197 ssize_t len = ::readlink(
"/proc/self/exe", path,
sizeof(path) - 1);
201 uint32_t size =
sizeof(path);
202 if (_NSGetExecutablePath(path, &size) != 0)
203 {std::cout <<
"buffer too small; need size " << size << std::endl;}
205 std::string bdsimPath(path);
207 std::string::size_type found = bdsimPath.rfind(
'/');
208 if (found != std::string::npos)
209 {bdsimPath = bdsimPath.substr(0,found+1);}
213G4String
BDS::GetFullPath(G4String fileName,
bool excludeNameFromPath,
bool useCWDForPrefix)
216 G4cout << __METHOD_NAME__ << fileName <<
" strip name off?: " << excludeNameFromPath << G4endl;
229 if (fileName.substr(0,2) ==
"./")
230 {fileName = fileName.substr(2);}
233 G4String inputFilepath, inputFilename;
237 if ((fileName.substr(0,1)) ==
"/")
238 {fullPath = inputFilepath;}
242 fullPath = prefixPath;
243 if (inputFilepath !=
"./")
244 {fullPath +=
"/" + inputFilepath;}
247 if (fullPath.back() !=
'/')
251 if (!excludeNameFromPath)
252 {fullPath += inputFilename;}
254 G4cout << __METHOD_NAME__ <<
"determined full path to be: " << fullPath << G4endl;
263 G4String::size_type found = filePath.rfind(
'/');
264 if (found != G4String::npos)
266 path = filePath.substr(0,found) +
"/";
267 fileName = filePath.substr(found+1);
280 G4String::size_type found = fileName.rfind(
".");
281 if (found != G4String::npos)
283 file = fileName.substr(0, found);
284 extension = fileName.substr(found);
300 static int nrOfCalls=0;
304 std::cout << std::endl <<
"BDSIM is about to crash or was interrupted! " << std::endl;
305 std::cout <<
"With signal: " << strsignal(signal_number) << std::endl;
307 BDSRunManager::GetRunManager()->AbortRun();
308 std::cout <<
"Ave, Imperator, morituri te salutant!" << std::endl;
314 return std::abs(value) > tolerance;
319 return std::abs(value) > std::numeric_limits<double>::min();
333 return resultX || resultY || resultZ;
341 if(s.empty() || ((!std::isdigit(s[0])) && (s[0] !=
'-') && (s[0] !=
'+')))
345 convertedInteger = std::strtol(ch, &p, 10);
355 if(s.empty() || ((!std::isdigit(s[0])) && (s[0] !=
'-') && (s[0] !=
'+')))
359 convertedNumber = std::strtod(ch, &p);
366 G4cout <<
"Rotation matrix - reference: \"" << keyName <<
"\"" << *rm << G4endl;
367 G4cout <<
"unit x -> " << G4ThreeVector(1,0,0).transform(*rm) << G4endl;
368 G4cout <<
"unit y -> " << G4ThreeVector(0,1,0).transform(*rm) << G4endl;
369 G4cout <<
"unit z -> " << G4ThreeVector(0,0,1).transform(*rm) << G4endl;
374#if G4VERSION_NUMBER > 1102
376 std::string entireDataDir =
"GEANT4_DATA_DIR";
377 const char* envVar = std::getenv( entireDataDir.c_str() );
382 std::vector<G4String> variables = {
386#if G4VERSION_NUMBER < 1049
397 G4bool result =
true;
398 for (
const auto& variable : variables)
400 const char* env_p = std::getenv( variable.c_str() );
404 G4cerr <<
"Variable: \"" << variable <<
"\" not found." << G4endl;
412 const char* envHPData = std::getenv(
"G4PARTICLEHPDATA");
415 std::string msg =
"The G4TENDL low energy data is not available!\n";
416 msg +=
"G4TENDL data is required through the environmental variable \"G4PARTICLEHPDATA\"\n;";
417 msg +=
"This is required for the \"" + physicsListName +
"\" physics list.\n";
418 msg +=
"This data is an optional download from the Geant4 website. Please\n";
419 msg +=
"download from the Geant4 website and export the environmental variable.";
426 const char* envHPData = std::getenv(
"G4LENDDATA");
429 std::string msg =
"The Low Energy Neutron Data ('LEND') is not available!\n";
430 msg +=
"Data is required through the environmental variable \"G4LENDDATA\"\n";
431 msg +=
"This is required for the \"" + physicsListName +
"\" physics list.\n";
432 msg +=
"This data is an optional download from the Geant4 website. Please\n";
433 msg +=
"download from the Geant4 website and export the environmental variable.";
442 catch(
const std::invalid_argument& e)
450 catch (
const std::invalid_argument& e)
457 std::string param = name +
"=";
459 int pos = spec.find(param);
462 int pos2 = spec.find(
"&",pos);
463 int pos3 = spec.length();
464 int tend = pos2 < 0 ? pos3 : pos2;
465 int llen = tend - pos - param.length();
467 value = spec.substr(pos + param.length(), llen);
474 std::vector<G4String> result;
478 std::istringstream ss(input);
482 {result.push_back(word);}
486G4TwoVector
BDS::Rotate(
const G4TwoVector& vec,
const G4double& angle)
488 G4double xp = vec.x()*std::cos(angle) - vec.y()*std::sin(angle);
489 G4double yp = vec.x()*std::sin(angle) + vec.y()*std::cos(angle);
490 return G4TwoVector(xp,yp);
494 const G4ThreeVector& outgoingNormal,
495 const G4double& zSeparation,
502 G4ThreeVector cross = incomingNormal.cross(outgoingNormal);
503 G4double det = cross.mag2();
522 G4bool xNegYNegFail = xNegYNegIC > (zSeparation + xNegYNegOG);
523 G4bool xNegYPosFail = xNegYPosIC > (zSeparation + xNegYPosOG);
524 G4bool xPosYPosFail = xPosYPosIC > (zSeparation + xPosYPosOG);
525 G4bool xPosYNegFail = xPosYNegIC > (zSeparation + xPosYNegOG);
527 if (xNegYNegFail || xNegYPosFail || xPosYPosFail || xPosYNegFail)
534 const G4double& angleOut,
535 const G4double& horizontalWidth,
536 const G4double& length)
540 G4double dzIn = horizontalWidth * std::tan(angleIn);
541 G4double dzOut = horizontalWidth * std::tan(angleOut);
542 if (dzIn > length - dzOut)
559 return (-normal.x()*x - normal.y()*y) / normal.z();
566 G4RotationMatrix rm = G4RotationMatrix();
567 rm.rotateY(fullAngle*0.5);
568 return faceNormal.transform(rm);
573 if(!formatAndPath.empty())
575 std::size_t found = formatAndPath.find(
":");
576 if (found == std::string::npos)
578 throw BDSException(__METHOD_NAME__,
"invalid specifier \"" + formatAndPath +
"\"\n"
579 +
"Missing \":\" to separate format and file path");
583 G4String format = formatAndPath.substr(0,found);
584 G4String filePath = formatAndPath.substr(found+1);
585 return std::make_pair(format,filePath);
588 return std::make_pair(
"",
"");
595 G4UserLimits* result = defaultUL;
597 G4Track t = G4Track();
598 if (defaultUL->GetMaxAllowedStep(t) > length)
600 result =
new G4UserLimits(*defaultUL);
601 G4double lengthScale = length * fraction;
602 lengthScale = std::max(lengthScale, 1.0*CLHEP::um);
604 {lengthScale = 1*CLHEP::mm;}
605 result->SetMaxAllowedStep(lengthScale);
612 struct rusage r_usage;
613 int itWorked = getrusage(RUSAGE_SELF, &r_usage);
618 G4double maxMemory = (G4double)r_usage.ru_maxrss;
620 maxMemory /= 1048*1048;
632 std::istringstream iss(userParameters);
633 std::vector<std::string> paramaterPairs(std::istream_iterator<std::string>{iss},
634 std::istream_iterator<std::string>{});
636 std::map<G4String, G4String> result;
637 for (
auto& pair : paramaterPairs)
639 auto index = pair.find(delimiter);
640 std::string key = pair.substr(0, index);
641 std::string value = pair.substr(index+1);
642 result[G4String(key)] = G4String(value);
648 G4int verboseEventContinueFor)
650 G4int verboseEventStop = 0;
651 if (verboseEventContinueFor < 1)
652 {verboseEventStop = std::numeric_limits<int>::max();}
654 {verboseEventStop = verboseEventStart + verboseEventContinueFor;}
655 return verboseEventStop;
662 return eventIndex >= eventStart && eventIndex < eventStop;
668 return momentumMagnitude / CLHEP::GeV /
BDS::cOverGeV / charge;
672 G4ThreeVector outputfaceIn,
674 G4double containerWidth,
675 G4double containerHeight)
677 G4double angleIn = inputfaceIn.angle();
678 G4double angleOut = outputfaceIn.angle();
685 G4double containerWidth,
686 G4double containerHeight)
688 G4double sLength = length;
690 {containerHeight = containerWidth;}
699 G4double hypotenuse = std::hypot(containerWidth, containerHeight);
700 G4double dzIn = std::tan(std::abs(angleIn)) * 1.2 * hypotenuse;
701 G4double dzOut = std::tan(std::abs(angleOut)) * 1.2 * hypotenuse;
703 sLength = std::max(2 * length, 1.5 * length + dzIn + dzOut);
711 {
return chordLength;}
712 G4double radiusOfCurvature = 0.5*chordLength / std::sin(0.5*std::abs(angle));
713 G4double arcLength = radiusOfCurvature * std::abs(angle);
General exception with possible name of object and message.
Holder for +- extents in 3 dimensions.
G4double XPos() const
Accessor.
G4double XNeg() const
Accessor.
G4double YNeg() const
Accessor.
G4double YPos() const
Accessor.
static BDSGlobalConstants * Instance()
Access method.
G4double Rigidity(G4double momentumMagnitude, G4double charge)
Calculate the rigidity for a total momentum and charge.
G4TwoVector Rotate(const G4TwoVector &vec, const G4double &angle)
Rotate a two vector in polar coordinates by an angle.
G4bool WillIntersect(const G4ThreeVector &incomingNormal, const G4ThreeVector &outgoingNormal, const G4double &zSeparation, const BDSExtent &incomingExtent, const BDSExtent &outgoingExtent)
G4String GetParameterValueString(G4String spec, G4String name)
Get parameter value from the specification ('spec') string.
std::pair< G4String, G4String > SplitOnColon(const G4String &formatAndPath)
void SplitFileAndExtension(const G4String &fileName, G4String &file, G4String &extension)
Split a filename.ext into filename and extension. Extension includes '.'.
std::string GetCurrentDir()
Get the current dir the program was executed from.
G4String PrepareSafeName(G4String name)
Remove white space and special characters in the name.
G4bool NonZero(G4double value)
Test whether a number is non-zero - ie abs(number) > minimum number.
G4bool StrContains(const G4String &str, const G4String &test)
Utility function to simplify lots of syntax changes for pedantic g4 changes.
G4ThreeVector RotateToReferenceFrame(G4ThreeVector faceNormal, G4double fullAngle)
static const G4double cOverGeV
speed of light / 1 GeV, used for scaling in brho calculation
G4String GetFullPath(G4String filename, bool excludeNameFromPath=false, bool useCWDForPrefix=false)
G4double GetZOfPointOnPlane(const G4ThreeVector &normal, G4double x, G4double y)
G4double GetMemoryUsage()
Get the current memory usage.
G4String LowerCase(const G4String &str)
Utility function to simplify lots of syntax changes for pedantic g4 changes.
G4UserLimits * CreateUserLimits(G4UserLimits *defaultUL, G4double length, G4double fraction=1.6)
G4bool DirectoryExists(const G4String &path)
Check if directory exists.
void PrintRotationMatrix(G4RotationMatrix *rm, G4String keyName="unknown")
G4bool Geant4EnvironmentIsSet()
Check if the geant4 environmental variables necessary for a run are set.
void EnsureInLimits(G4double &value, G4double lowerLimit, G4double upperLimit)
G4bool FileExists(const G4String &filename)
Checks if filename exists.
void CheckHighPrecisionDataExists(const G4String &physicsListName)
G4bool VerboseThisEvent(G4int eventIndex, G4int eventStart, G4int eventStop)
Logic of whether this event should be verbose or not. Code here so it's not duplicated.
void HandleAborts(int signal_number)
std::vector< G4String > SplitOnWhiteSpace(const G4String &input)
Split a string on whitespace and return a vector of these 'words'.
G4double CalculateSafeAngledVolumeLength(G4double angleIn, G4double angleOut, G4double length, G4double containerWidth, G4double containerHeight=0)
Calculate safe length of an angled volume so it fills the length of its container.
G4bool IsNumber(const char *s, double &convertedNumber)
Check if character array is an integer, and returns the double by reference.
G4int VerboseEventStop(G4int verboseEventStart, G4int verboseEventContinueFor)
void CheckLowEnergyNeutronDataExists(const G4String &phhysicsListName)
G4bool IsFinite(G4double value, G4double tolerance=std::numeric_limits< double >::epsilon())
G4bool IsFiniteStrength(G4double variable)
G4double ArcLengthFromChordLength(G4double chordLength, G4double angle)
Calculate the arc length from the chord length for a given angle.
void SplitPathAndFileName(const G4String &filePath, G4String &path, G4String &filename)
std::string GetBDSIMExecPath()
G4bool IsInteger(const char *s, int &convertedInteger)
Check if character array is an integer, and returns the integer by reference.
G4int GetParameterValueInt(G4String spec, G4String name)
Get parameter value from the specification ('spec') string.
std::map< G4String, G4String > GetUserParametersMap(const G4String &userParameters, char delimiter=':')
Take one long string and split on space and then on colon. "key1:value1 key2:value2" etc.
G4int StrCompare(const G4String &str, const G4String &, G4String::caseCompare mode=G4String::ignoreCase)
Utility function to simplify lots of syntax changes for pedantic g4 changes.
G4String StrStrip(const G4String &str, char ch, StringStripType stripType=StringStripType::both)
Utility function to simplify lots of syntax changes for pedantic g4 changes.
G4int CalculateOrientation(G4double angle)
std::pair< G4ThreeVector, G4ThreeVector > CalculateFaces(G4double angleInIn, G4double angleOutIn)
Calculate input and output normal vector.
G4double GetParameterValueDouble(G4String spec, G4String name)
Get parameter value from the specification ('spec') string.
Logical not for isalpha UnaryPredicate as needed for string manipulations.