19#include "BDSAperturePointsLoader.hh"
21#include "BDSException.hh"
22#include "BDSUtilities.hh"
25#include "G4TwoVector.hh"
27#include "G4UnitsTable.hh"
28#include "G4Version.hh"
38#include "src-external/gzstream/gzstream.h"
55 G4String functionName =
"BDSAperturePointsLoader::Load> ";
59 {
throw BDSException(functionName,
"empty file name given");}
65 bool validFile = file.rdbuf()->is_open();
67 bool validFile = file.is_open();
71 {
throw BDSException(functionName,
"Cannot open file \"" + fileName +
"\"");}
73 {G4cout << functionName <<
"loading \"" << fileName <<
"\"" << G4endl;}
76 auto result =
new std::vector<G4TwoVector>();
77 std::array<G4double, 2> values({0,0});
79 std::regex commentLine(
"^\\s*[\\#!]");
80 while (std::getline(file, line))
83 if (std::all_of(line.begin(), line.end(), isspace))
89 if (std::regex_search(line, commentLine))
97 if ((G4int)wordsInLine.size() != 2)
98 {
throw BDSException(functionName,
"invalid number of coordinates on line " + std::to_string(lineNo));}
100 for (G4int i = 0; i < (G4int)values.size(); i++)
104 {coord = std::stod(wordsInLine[i]);}
105 catch (std::exception& e)
106 {
throw BDSException(functionName,
"Error on line> " + std::to_string(lineNo) +
"> cannot convert to number");}
107 (values[i]) = coord * unit;
110 result->emplace_back(G4TwoVector(values[0], values[1]));
117 G4cout << functionName <<
"loaded " << result->size() <<
" points" << G4endl;
119 if (result->size() < 3)
120 {
throw BDSException(functionName,
"require at least 3 points to make an enclosed volume");}
126 const G4String& unit)
128 G4String functionName =
"BDS::LoadAperturePoints>";
130 G4double unitAsNumber = 1.0;
133#if G4VERSION_NUMBER > 1029
134 if (!G4UnitDefinition::IsUnitDefined(unit))
135 {
throw BDSException(functionName,
"no such unit \"" + unit +
"\"");}
137 {unitAsNumber = G4UnitDefinition::GetValueOf(unit);}
140 if (unitLower ==
"mm")
141 {unitAsNumber = 1.0;}
142 else if (unitLower ==
"cm")
144 else if (unitLower ==
"m")
145 {unitAsNumber = 1000;}
147 {
throw BDSException(functionName,
"Unknown unit \"" + unit +
"\" (for this version of Geant4/BDSIM) - use one of (mm, cm, m)");}
153 {
return cachedResult;}
157 {
throw BDSException(functionName,
"no such file: \"" + fullFilePath +
"\"");}
159 std::vector<G4TwoVector>* result;
160 if (fullFilePath.rfind(
"gz") != std::string::npos)
164 result = loader.
Load(fullFilePath, unitAsNumber);
166 throw BDSException(functionName,
"Compressed file loading - but BDSIM not compiled with ZLIB.");
172 result = loader.
Load(fullFilePath, unitAsNumber);
188BDSAperturePointsCache::~BDSAperturePointsCache()
195 for (
auto& v : cachedFiles)
202 std::vector<G4TwoVector>* result =
nullptr;
203 auto search = cachedFiles.find(fileNameAndUnits);
204 if (search != cachedFiles.end())
205 {
return search->second;}
211 std::vector<G4TwoVector>* contents)
213 auto search = cachedFiles.find(fileNameAndUnits);
214 if (search != cachedFiles.end())
216 if (contents != search->second)
217 {
throw BDSException(__METHOD_NAME__,
"overwriting cache of aperture points with different contents for file name: "+fileNameAndUnits);}
221 {cachedFiles[fileNameAndUnits] = contents;}
A holder for loaded aperture points files.
void CacheFile(const G4String &fileNameAndUnits, std::vector< G4TwoVector > *contents)
Add an entry to the cache.
static BDSAperturePointsCache * Instance()
Access the singleton instance.
void ClearCachedFiles()
Delete all cached points from memory and clear the map of files loaded.
std::vector< G4TwoVector > * FindCachedFile(const G4String &fileNameAndUnits) const
Retrieve a cached files. Will return nullptr if not found.
A loader for up to set of XY points for an aperture.
std::vector< G4TwoVector > * Load(const G4String &fileName, G4double unit=1.0) const
General exception with possible name of object and message.
G4String GetFullPath(G4String filename, bool excludeNameFromPath=false, bool useCWDForPrefix=false)
G4String LowerCase(const G4String &str)
Utility function to simplify lots of syntax changes for pedantic g4 changes.
std::vector< G4TwoVector > * LoadAperturePoints(const G4String &fileName, const G4String &unit="")
G4bool FileExists(const G4String &filename)
Checks if filename exists.
std::vector< G4String > SplitOnWhiteSpace(const G4String &input)
Split a string on whitespace and return a vector of these 'words'.