19#include "BDSException.hh"
20#include "BDSExtent.hh"
21#include "BDSGlobalConstants.hh"
22#include "BDSPhysicalConstants.hh"
23#include "BDSRunManager.hh"
24#include "BDSUtilities.hh"
28#include "G4ThreeVector.hh"
30#include "G4TwoVector.hh"
31#include "G4UserLimits.hh"
32#include "G4Version.hh"
34#include "CLHEP/Units/SystemOfUnits.h"
53#include <sys/resource.h>
57#include <mach-o/dyld.h>
62 const G4int bdsimLibraryAnchor = 0;
66G4bool BDS::non_alpha::operator()(
char c)
73#if G4VERSION_NUMBER > 1099
74 return G4StrUtil::contains(str, test);
76 return str.contains(test);
79#if G4VERSION_NUMBER > 1099
80G4int
BDS::StrCompare(
const G4String& str,
const G4String& test, G4String::caseCompare)
82G4int
BDS::StrCompare(
const G4String& str,
const G4String& test, G4String::caseCompare mode)
85#if G4VERSION_NUMBER > 1099
86 return G4StrUtil::icompare(str, test);
88 return str.compareTo(test, mode);
94 G4String result = str;
95#if G4VERSION_NUMBER > 1099
96 G4StrUtil::to_lower(result);
107 G4String result = str;
110#if G4VERSION_NUMBER > 1099
111 case StringStripType::leading:
112 {G4StrUtil::lstrip(result, ch);
break;}
113 case StringStripType::trailing:
114 {G4StrUtil::rstrip(result, ch);
break;}
115 case StringStripType::both:
116 {G4StrUtil::strip(result, ch);
break;}
118 case StringStripType::leading:
119 {result.strip(G4String::stripType::leading, ch);
break;}
120 case StringStripType::trailing:
121 {result.strip(G4String::stripType::trailing, ch);
break;}
122 case StringStripType::both:
123 {result.strip(G4String::stripType::both, ch);
break;}
132 name.erase(std::remove_if(name.begin(),name.end(),isspace),name.end());
141 return angle < 0 ? 1 : -1;
152 G4double in_z = std::cos(std::abs(angleIn));
153 G4double in_x = std::sin(std::abs(angleIn));
154 G4double out_z = std::cos(std::abs(angleOut));
155 G4double out_x = std::sin(std::abs(angleOut));
156 G4ThreeVector inputface = G4ThreeVector(orientationIn*in_x, 0.0, -1.0*in_z);
157 G4ThreeVector outputface = G4ThreeVector(orientationOut*out_x, 0.0, out_z);
158 return std::make_pair(inputface,outputface);
163 if (value < lowerLimit)
164 {value = lowerLimit;}
165 if (value > upperLimit)
166 {value = upperLimit;}
171 std::ifstream infile(fileName.c_str());
172 return infile.good();
179 bool result = (stat(path.c_str(), &sb) == 0) && S_ISDIR(sb.st_mode);
180 return G4bool(result);
185 char currentPath[PATH_MAX];
186 std::string currentPathString;
188 if (getcwd(currentPath,
sizeof(currentPath)) !=
nullptr)
189 {currentPathString = std::string(currentPath);}
191 {
throw BDSException(__METHOD_NAME__,
"Cannot determine current working directory");}
193 return currentPathString;
202 ssize_t len = ::readlink(
"/proc/self/exe", path,
sizeof(path) - 1);
206 uint32_t size =
sizeof(path);
207 if (_NSGetExecutablePath(path, &size) != 0)
208 {std::cout <<
"buffer too small; need size " << size << std::endl;}
210 std::string bdsimPath(path);
212 std::string::size_type found = bdsimPath.rfind(
'/');
213 if (found != std::string::npos)
214 {bdsimPath = bdsimPath.substr(0,found+1);}
221 if (dladdr(&bdsimLibraryAnchor, &libraryInfo) == 0 || !libraryInfo.dli_fname)
222 {
throw BDSException(__METHOD_NAME__,
"Cannot determine BDSIM library path");}
224 std::string bdsimPath(libraryInfo.dli_fname);
225 std::string::size_type found = bdsimPath.rfind(
'/');
226 if (found != std::string::npos)
227 {bdsimPath = bdsimPath.substr(0,found+1);}
231G4String
BDS::GetFullPath(G4String fileName,
bool excludeNameFromPath,
bool useCWDForPrefix)
234 G4cout << __METHOD_NAME__ << fileName <<
" strip name off?: " << excludeNameFromPath << G4endl;
247 if (fileName.substr(0,2) ==
"./")
248 {fileName = fileName.substr(2);}
251 G4String inputFilepath, inputFilename;
255 if ((fileName.substr(0,1)) ==
"/")
256 {fullPath = inputFilepath;}
260 fullPath = prefixPath;
261 if (inputFilepath !=
"./")
262 {fullPath +=
"/" + inputFilepath;}
265 if (fullPath.back() !=
'/')
269 if (!excludeNameFromPath)
270 {fullPath += inputFilename;}
272 G4cout << __METHOD_NAME__ <<
"determined full path to be: " << fullPath << G4endl;
281 G4String::size_type found = filePath.rfind(
'/');
282 if (found != G4String::npos)
284 path = filePath.substr(0,found) +
"/";
285 fileName = filePath.substr(found+1);
298 G4String::size_type found = fileName.rfind(
".");
299 if (found != G4String::npos)
301 file = fileName.substr(0, found);
302 extension = fileName.substr(found);
318 static int nrOfCalls=0;
322 std::cout << std::endl <<
"BDSIM is about to crash or was interrupted! " << std::endl;
323 std::cout <<
"With signal: " << strsignal(signal_number) << std::endl;
325 BDSRunManager::GetRunManager()->AbortRun();
326 std::cout <<
"Ave, Imperator, morituri te salutant!" << std::endl;
332 return std::abs(value) > tolerance;
337 return std::abs(value) > std::numeric_limits<double>::min();
351 return resultX || resultY || resultZ;
359 if(s.empty() || ((!std::isdigit(s[0])) && (s[0] !=
'-') && (s[0] !=
'+')))
363 convertedInteger = std::strtol(ch, &p, 10);
373 if(s.empty() || ((!std::isdigit(s[0])) && (s[0] !=
'-') && (s[0] !=
'+')))
377 convertedNumber = std::strtod(ch, &p);
384 G4cout <<
"Rotation matrix - reference: \"" << keyName <<
"\"" << *rm << G4endl;
385 G4cout <<
"unit x -> " << G4ThreeVector(1,0,0).transform(*rm) << G4endl;
386 G4cout <<
"unit y -> " << G4ThreeVector(0,1,0).transform(*rm) << G4endl;
387 G4cout <<
"unit z -> " << G4ThreeVector(0,0,1).transform(*rm) << G4endl;
392#if G4VERSION_NUMBER > 1102
394 std::string entireDataDir =
"GEANT4_DATA_DIR";
395 const char* envVar = std::getenv( entireDataDir.c_str() );
400 std::vector<G4String> variables = {
404#if G4VERSION_NUMBER < 1049
415 G4bool result =
true;
416 for (
const auto& variable : variables)
418 const char* env_p = std::getenv( variable.c_str() );
422 G4cerr <<
"Variable: \"" << variable <<
"\" not found." << G4endl;
430 const char* envHPData = std::getenv(
"G4PARTICLEHPDATA");
433 std::string msg =
"The G4TENDL low energy data is not available!\n";
434 msg +=
"G4TENDL data is required through the environmental variable \"G4PARTICLEHPDATA\"\n;";
435 msg +=
"This is required for the \"" + physicsListName +
"\" physics list.\n";
436 msg +=
"This data is an optional download from the Geant4 website. Please\n";
437 msg +=
"download from the Geant4 website and export the environmental variable.";
444 const char* envHPData = std::getenv(
"G4LENDDATA");
447 std::string msg =
"The Low Energy Neutron Data ('LEND') is not available!\n";
448 msg +=
"Data is required through the environmental variable \"G4LENDDATA\"\n";
449 msg +=
"This is required for the \"" + physicsListName +
"\" physics list.\n";
450 msg +=
"This data is an optional download from the Geant4 website. Please\n";
451 msg +=
"download from the Geant4 website and export the environmental variable.";
460 catch(
const std::invalid_argument& e)
468 catch (
const std::invalid_argument& e)
475 std::string param = name +
"=";
477 int pos = spec.find(param);
480 int pos2 = spec.find(
"&",pos);
481 int pos3 = spec.length();
482 int tend = pos2 < 0 ? pos3 : pos2;
483 int llen = tend - pos - param.length();
485 value = spec.substr(pos + param.length(), llen);
492 std::vector<G4String> result;
496 std::istringstream ss(input);
500 {result.push_back(word);}
504G4TwoVector
BDS::Rotate(
const G4TwoVector& vec,
const G4double& angle)
506 G4double xp = vec.x()*std::cos(angle) - vec.y()*std::sin(angle);
507 G4double yp = vec.x()*std::sin(angle) + vec.y()*std::cos(angle);
508 return G4TwoVector(xp,yp);
512 const G4ThreeVector& outgoingNormal,
513 const G4double& zSeparation,
520 G4ThreeVector cross = incomingNormal.cross(outgoingNormal);
521 G4double det = cross.mag2();
540 G4bool xNegYNegFail = xNegYNegIC > (zSeparation + xNegYNegOG);
541 G4bool xNegYPosFail = xNegYPosIC > (zSeparation + xNegYPosOG);
542 G4bool xPosYPosFail = xPosYPosIC > (zSeparation + xPosYPosOG);
543 G4bool xPosYNegFail = xPosYNegIC > (zSeparation + xPosYNegOG);
545 if (xNegYNegFail || xNegYPosFail || xPosYPosFail || xPosYNegFail)
552 const G4double& angleOut,
553 const G4double& horizontalWidth,
554 const G4double& length)
558 G4double dzIn = horizontalWidth * std::tan(angleIn);
559 G4double dzOut = horizontalWidth * std::tan(angleOut);
560 if (dzIn > length - dzOut)
577 return (-normal.x()*x - normal.y()*y) / normal.z();
584 G4RotationMatrix rm = G4RotationMatrix();
585 rm.rotateY(fullAngle*0.5);
586 return faceNormal.transform(rm);
591 if(!formatAndPath.empty())
593 std::size_t found = formatAndPath.find(
":");
594 if (found == std::string::npos)
596 throw BDSException(__METHOD_NAME__,
"invalid specifier \"" + formatAndPath +
"\"\n"
597 +
"Missing \":\" to separate format and file path");
601 G4String format = formatAndPath.substr(0,found);
602 G4String filePath = formatAndPath.substr(found+1);
603 return std::make_pair(format,filePath);
606 return std::make_pair(
"",
"");
613 G4UserLimits* result = defaultUL;
615 G4Track t = G4Track();
616 if (defaultUL->GetMaxAllowedStep(t) > length)
618 result =
new G4UserLimits(*defaultUL);
619 G4double lengthScale = length * fraction;
620 lengthScale = std::max(lengthScale, 1.0*CLHEP::um);
622 {lengthScale = 1*CLHEP::mm;}
623 result->SetMaxAllowedStep(lengthScale);
630 struct rusage r_usage;
631 int itWorked = getrusage(RUSAGE_SELF, &r_usage);
636 G4double maxMemory = (G4double)r_usage.ru_maxrss;
638 maxMemory /= 1048*1048;
650 std::istringstream iss(userParameters);
651 std::vector<std::string> paramaterPairs(std::istream_iterator<std::string>{iss},
652 std::istream_iterator<std::string>{});
654 std::map<G4String, G4String> result;
655 for (
auto& pair : paramaterPairs)
657 auto index = pair.find(delimiter);
658 std::string key = pair.substr(0, index);
659 std::string value = pair.substr(index+1);
660 result[G4String(key)] = G4String(value);
666 G4int verboseEventContinueFor)
668 G4int verboseEventStop = 0;
669 if (verboseEventContinueFor < 1)
670 {verboseEventStop = std::numeric_limits<int>::max();}
672 {verboseEventStop = verboseEventStart + verboseEventContinueFor;}
673 return verboseEventStop;
680 return eventIndex >= eventStart && eventIndex < eventStop;
686 return momentumMagnitude / CLHEP::GeV /
BDS::cOverGeV / charge;
690 G4ThreeVector outputfaceIn,
692 G4double containerWidth,
693 G4double containerHeight)
695 G4double angleIn = inputfaceIn.angle();
696 G4double angleOut = outputfaceIn.angle();
703 G4double containerWidth,
704 G4double containerHeight)
706 G4double sLength = length;
708 {containerHeight = containerWidth;}
717 G4double hypotenuse = std::hypot(containerWidth, containerHeight);
718 G4double dzIn = std::tan(std::abs(angleIn)) * 1.2 * hypotenuse;
719 G4double dzOut = std::tan(std::abs(angleOut)) * 1.2 * hypotenuse;
721 sLength = std::max(2 * length, 1.5 * length + dzIn + dzOut);
729 {
return chordLength;}
730 G4double radiusOfCurvature = 0.5*chordLength / std::sin(0.5*std::abs(angle));
731 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)
std::string GetBDSIMLibraryPath()
Returns the path from which the BDSIM library is loaded.
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.