6 #include "CLHEP/Units/PhysicalConstants.h"
12 #include <unordered_map>
22 size_t startPos = input.find_first_not_of(
" \t");
23 size_t endPos = input.find_last_not_of(
" \t");
26 if (startPos == std::string::npos || endPos == std::string::npos) {
return ""; }
29 return input.substr(startPos, endPos - startPos + 1);
34 result.erase(std::remove(result.begin(), result.end(),
' '), result.end());
39 std::size_t lastSlashPos = path.find_last_of(
'/');
40 if (lastSlashPos == std::string::npos) {
44 return path.substr(lastSlashPos + 1);
48 auto lastSlash = path.find_last_of(
'/');
49 if (lastSlash == std::string::npos)
return ".";
50 return path.substr(0, lastSlash);
53 namespace fs = std::filesystem;
68 namespace fs = std::filesystem;
73 return fs::weakly_canonical(p);
76 if (p.has_parent_path())
77 return fs::weakly_canonical(fs::current_path() / p);
80 const char* env_path = std::getenv(
"PATH");
83 const char delim =
';';
85 const char delim =
':';
87 std::stringstream ss(env_path);
89 while (std::getline(ss, dir, delim)) {
90 fs::path candidate = fs::path(dir) / p;
91 if (fs::exists(candidate))
92 return fs::weakly_canonical(candidate);
96 throw std::runtime_error(
"cannot resolve executable path from '" + path +
"'");
100 std::vector<std::string> pvalues;
101 std::stringstream plist(input);
103 while (plist >> tmp) {
105 if (!trimmed.empty()) { pvalues.push_back(trimmed); }
112 const std::string& replacement) {
114 for (
const char& ch : input) {
115 if (toReplace.find(ch) != std::string::npos) { output.append(replacement); }
116 else { output.push_back(ch); }
122 if (from.empty())
return source;
126 size_t findPos = source.find(from, lastPos);
128 while (findPos != string::npos) {
130 newString.append(source, lastPos, findPos - lastPos);
132 lastPos = findPos + from.length();
133 findPos = source.find(from, lastPos);
137 newString += source.substr(lastPos);
143 string fillDigits(
const string& word,
const string& c,
int ndigits) {
144 if (c.empty() || ndigits <=
static_cast<int>(word.size()))
return word;
148 int toFill = ndigits -
static_cast<int>(word.size());
149 filled.reserve(ndigits);
151 filled.append(toFill, c[0]);
162 if (value.find(
'*') == string::npos) {
163 if (!value.empty() && warnIfNotUnit && stod(value) != 0) { std::cerr <<
" ! Warning: value " << v <<
" does not contain units." << std::endl; }
165 try {
return stod(value); }
166 catch (
const std::exception& e) {
167 std::cerr <<
FATALERRORL <<
"stod exception in gutilities: could not convert string to double. "
168 <<
"Value: >" << v <<
"<, error: " << e.what() << std::endl;
174 size_t pos = value.find(
'*');
175 string rootValue = value.substr(0, pos);
176 string units = value.substr(pos + 1);
179 try { answer = stod(rootValue); }
180 catch (
const std::exception& e) {
181 std::cerr <<
FATALERRORL <<
"stod exception in gutilities: could not convert string to double. "
182 <<
"Value: >" << v <<
"<, error: " << e.what() << std::endl;
187 static const std::unordered_map<string, double> unitConversion = {
191 {
"um", 1E-6 * CLHEP::m},
192 {
"fm", 1E-15 * CLHEP::m},
193 {
"inches", 2.54 * CLHEP::cm},
194 {
"inch", 2.54 * CLHEP::cm},
196 {
"degrees", CLHEP::deg},
197 {
"arcmin", CLHEP::deg / 60.0},
199 {
"mrad", CLHEP::mrad},
202 {
"KeV", 0.001 * CLHEP::MeV},
205 {
"T/m", CLHEP::tesla / CLHEP::m},
206 {
"Tesla", CLHEP::tesla},
207 {
"gauss", CLHEP::gauss},
208 {
"kilogauss", CLHEP::gauss * 1000},
216 auto it = unitConversion.find(units);
217 if (it != unitConversion.end()) { answer *= it->second; }
218 else { std::cerr <<
GWARNING <<
">" << units <<
"<: unit not recognized for string <" << v <<
">" << std::endl; }
230 vector<double> output;
231 output.reserve(vstring.size());
233 for (
const auto& s : vstring) { output.push_back(
getG4Number(s, warnIfNotUnit)); }
245 std::ifstream in(filename);
247 std::cerr <<
FATALERRORL <<
"can't open input file " << filename <<
". Check your spelling. " << std::endl;
251 std::stringstream strStream;
252 if (verbosity > 0) { std::cout << std::endl <<
CIRCLEITEM <<
" Loading string from " << filename << std::endl; }
253 strStream << in.rdbuf();
256 string parsedString = strStream.str();
260 while ((nFPos = parsedString.find(commentChars)) != string::npos) {
261 size_t firstNL = parsedString.rfind(
'\n', nFPos);
262 size_t secondNL = parsedString.find(
'\n', nFPos);
263 parsedString.erase(firstNL, secondNL - firstNL);
270 size_t firstpos = input.find(firstDelimiter);
271 size_t secondpos = input.find(secondDelimiter);
273 if (firstpos == string::npos || secondpos == string::npos) {
return ""; }
274 return input.substr(firstpos + firstDelimiter.length(), secondpos - firstpos - firstDelimiter.length());
278 vector<string> pvalues;
281 for (
char ch : input) {
282 if (ch != x[0]) { tmp += ch; }
331 #include <sys/stat.h>
335 if (stat(path.c_str(), &info) != 0) {
338 return (info.st_mode & S_IFDIR) != 0;
342 for (
const auto& trialLocation : possibleLocations) {
343 string possibleDir = trialLocation +
"/" + dirName;
346 return "UNINITIALIZEDSTRINGQUANTITY";
350 bool hasExtension(
const std::string& filename,
const std::vector<std::string>& extensions) {
351 for (
const auto& ext : extensions) {
352 if (filename.size() >= ext.size() &&
353 filename.compare(filename.size() - ext.size(), ext.size(), ext) == 0) {
return true; }
359 vector<string> fileList;
361 DIR* dir = opendir(dirName.c_str());
363 struct dirent* entry;
364 while ((entry = readdir(dir)) !=
nullptr) {
366 string filepath = dirName +
"/" + entry->d_name;
367 if (stat(filepath.c_str(), &info) == 0 && S_ISREG(info.st_mode)) {
368 string filename = entry->d_name;
369 if (
hasExtension(filename, extensions)) { fileList.push_back(filename); }
380 transform(lower.begin(), lower.end(), lower.begin(), ::tolower);
385 template <
class KEY,
class VALUE>
386 vector<KEY>
getKeys(
const map<KEY, VALUE>& map) {
388 keys.reserve(map.size());
390 for (
const auto& it : map) { keys.push_back(it.first); }
396 static const std::unordered_map<std::string, randomModel> strToEnum = {
403 auto it = strToEnum.find(str);
404 if (it != strToEnum.end()) {
return it->second; }
405 else {
throw std::invalid_argument(
"Invalid string for randomModel: " + str); }
410 if (code.empty())
throw std::invalid_argument(
"empty colour string");
411 if (code.front() ==
'#') code.remove_prefix(1);
412 if (code.size() != 6 && code.size() != 7)
413 throw std::invalid_argument(
"colour must have 6 or 7 hex digits");
415 auto hexNibble = [](
char c) ->
unsigned {
416 if (
'0' <= c && c <=
'9')
return c -
'0';
417 c =
static_cast<char>(std::toupper(
static_cast<unsigned char>(c)));
418 if (
'A' <= c && c <=
'F')
return c -
'A' + 10;
419 throw std::invalid_argument(
"invalid hex digit");
424 for (
int i = 0; i < 6; ++i)
425 rgb = (rgb << 4) | hexNibble(code[i]);
427 auto byteToDouble = [](
unsigned byte) {
return byte / 255.0; };
428 double r = byteToDouble((rgb >> 16) & 0xFF);
429 double g = byteToDouble((rgb >> 8) & 0xFF);
430 double b = byteToDouble(rgb & 0xFF);
434 if (code.size() == 7)
435 a = hexNibble(code[6]) / 15.0;
#define GWARNING
Warning label.
#define EC__FILENOTFOUND
File not found error code.
#define CIRCLEITEM
Symbol for circle item.
#define EC__G4NUMBERERROR
G4 number error code.
#define FATALERRORL
Fatal error label.
string replaceAllStringsWithString(const string &source, const string &from, const string &to)
Replaces all occurrences of a substring with another string.
double getG4Number(const string &v, bool warnIfNotUnit)
Converts a string representation of a number with optional units to a double.
bool hasExtension(const std::string &filename, const std::vector< std::string > &extensions)
Checks if a filename has one of the specified extensions.
vector< double > getG4NumbersFromString(const string &vstring, bool warnIfNotUnit)
Converts a comma-separated string of numbers with units to a vector of doubles.
string removeAllSpacesFromString(const std::string &str)
Removes all spaces from a string.
vector< string > getStringVectorFromStringWithDelimiter(const string &input, const string &x)
Splits a string into a vector of substrings using a specified delimiter.
randomModel stringToRandomModel(const std::string &str)
Converts a string to a corresponding randomModel enum value.
constexpr const char * to_string(randomModel m) noexcept
vector< string > getListOfFilesInDirectory(const string &dirName, const vector< string > &extensions)
Retrieves a list of files with specific extensions from a directory.
vector< double > getG4NumbersFromStringVector(const vector< string > &vstring, bool warnIfNotUnit)
Converts a vector of strings representing numbers with units to a vector of doubles.
string retrieveStringBetweenChars(const string &input, const string &firstDelimiter, const string &secondDelimiter)
Retrieves a substring between two specified delimiters in a string.
string replaceCharInStringWithChars(const std::string &input, const std::string &toReplace, const std::string &replacement)
Replaces all occurrences of specified characters in a string with another string.
string fillDigits(const string &word, const string &c, int ndigits)
Pads a string with a specified character until it reaches a desired length.
randomModel
Enumeration of random models.
@ gaussian
Gaussian distribution.
@ uniform
Uniform distribution.
@ sphere
Sphere distribution.
@ cosine
Cosine distribution.
string getDirFromPath(const std::string &path)
Extracts the directory path from a given file path.
string convertToLowercase(const string &str)
Converts a string to lowercase.
bool directoryExists(const std::string &path)
Checks if a directory exists at the given path.
G4Colour makeColour(std::string_view code)
Convert a hex colour string to G4Colour.
vector< KEY > getKeys(const map< KEY, VALUE > &map)
Retrieves all keys from a map.
string removeLeadingAndTrailingSpacesFromString(const std::string &input)
Removes leading and trailing spaces and tabs from a string.
string getFullPathFromPath(const std::string &path)
string searchForDirInLocations(const string &dirName, const vector< string > &possibleLocations)
Searches for a directory within a list of possible locations.
string parseFileAndRemoveComments(const string &filename, const string &commentChars, int verbosity)
Parses a file and removes all lines containing specified comment characters.
string getFileFromPath(const std::string &path)
Extracts the filename from a given file path.
vector< std::string > getStringVectorFromString(const std::string &input)
Splits a string into a vector of strings using spaces as delimiters.