REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestGDMLParser.cxx
1#include "TRestGDMLParser.h"
2
3#include <filesystem>
4#ifdef __APPLE__
5#include <unistd.h>
6#endif
7
8using namespace std;
9
10string TRestGDMLParser::GetEntityVersion(const string& name) const {
11 for (auto& [entityName, entityVersion] : fEntityVersionMap) {
12 if (entityName == name) {
13 return entityVersion;
14 }
15 }
16 return "0.0";
17}
18
19void TRestGDMLParser::Load(const string& filename) {
20 const string filenameAbsolute = TRestTools::ToAbsoluteName(filename);
21 if (!TRestTools::fileExists(filenameAbsolute)) {
22 RESTError << "TRestGDMLParser: Input GDML file: \"" << filenameAbsolute
23 << "\" does not exist. Please double check your current path and filename" << RESTendl;
24 exit(1);
25 }
26
27 fConfigFileName = filenameAbsolute;
28 fPath = TRestTools::SeparatePathAndName(filenameAbsolute).first;
29
30 std::ifstream t(filenameAbsolute);
31 std::string str((std::istreambuf_iterator<char>(t)), std::istreambuf_iterator<char>());
32 fFileString = str;
33 t.close();
34
35 size_t pp = fFileString.find("##VERSION", 0);
36 if (pp != string::npos) {
37 size_t pp2 = fFileString.find("##", pp + 4);
38 if (pp2 != string::npos) fGdmlVersion = fFileString.substr(pp + 9, pp2 - pp - 9);
40 }
41
42 fFileString = ReplaceConstants(ReplaceVariables(fFileString));
43
44 cout << "TRestGDMLParser: Initializing variables" << endl;
45 int pos = fFileString.find("<gdml", 0);
46 if (pos != -1) {
47 string elementString = fFileString.substr(pos, -1);
48
49 fElement = StringToElement(elementString);
51
53 }
54
55 cout << "TRestGDMLParser: Replacing expressions in GDML" << endl;
56 ReplaceEntity();
57 fFileString = Replace(fFileString, "= \"", "=\"");
58 fFileString = Replace(fFileString, " =\"", "=\"");
59 fFileString = Replace(fFileString, " = \"", "=\"");
60
61 ReplaceAttributeWithKeyWord("cos(");
62 ReplaceAttributeWithKeyWord("sin(");
63 ReplaceAttributeWithKeyWord("tan(");
64 ReplaceAttributeWithKeyWord("sqrt(");
65 ReplaceAttributeWithKeyWord("log(");
66 ReplaceAttributeWithKeyWord("exp(");
67
68 string filenameNoPath = TRestTools::SeparatePathAndName(filenameAbsolute).second;
69 // we have to use a unique identifier on the file to prevent collision when launching multiple jobs
70 fOutputGdmlFilename = fOutputGdmlDirectory + "PID" + std::to_string(getpid()) + "_" + filenameNoPath;
71 cout << "TRestGDMLParser: Creating temporary file at: \"" << fOutputGdmlFilename << "\"" << endl;
72
73 filesystem::create_directories(fOutputGdmlDirectory);
74
75 ofstream outputFile;
76 outputFile.open(fOutputGdmlFilename, ios::trunc);
77 outputFile << fFileString << endl;
78 outputFile.close();
79
80 std::ifstream fileToCheckExistence(fOutputGdmlFilename);
81 if (!fileToCheckExistence) {
82 std::cout << "TRestGDMLParser: Problem writing temporary file." << std::endl;
83 exit(1);
84 }
85}
86
87TGeoManager* TRestGDMLParser::CreateGeoManager() {
88 // We must change to the gdml file directory, otherwise ROOT cannot load.
89 if (!fOutputGdmlFilename.empty()) {
90 const auto currentPath = filesystem::current_path();
91 filesystem::current_path(fOutputGdmlDirectory);
92 auto geoManager = new TGeoManager();
93 geoManager->Import(fOutputGdmlFilename.c_str());
94 filesystem::current_path(currentPath);
95 return geoManager;
96 }
97 return nullptr;
98}
99
100void TRestGDMLParser::PrintContent() { cout << fFileString << endl; }
101
102void TRestGDMLParser::ReplaceEntity() {
103 int pos = 0;
104 while ((pos = fFileString.find("<!ENTITY", pos)) != -1) {
105 int pos1 = fFileString.find_first_not_of(" ", pos + 8);
106 int pos2 = fFileString.find("SYSTEM", pos1);
107 string entityName = RemoveWhiteSpaces(fFileString.substr(pos1, pos2 - pos1));
108
109 int pos3 = fFileString.find("\"", pos2) + 1;
110 int pos4 = fFileString.find("\"", pos3);
111 string entityFile = RemoveWhiteSpaces(fFileString.substr(pos3, pos4 - pos3));
112
113 cout << "TRestGDMLParser: Replacing entity: " << entityName << ", file: " << entityFile << endl;
114
115 if ((int)entityFile.find("http") != -1) {
116 string entityField =
117 fOutputGdmlDirectory + "PID" + std::to_string(getpid()) + "_" + entityName + ".xml";
118 int a = TRestTools::DownloadRemoteFile(entityFile, entityField);
119 if (a != 0) {
120 cout << "TRestGDMLParser: Download failed!" << endl;
121 exit(1);
122 }
123 entityFile = entityField;
124 } else {
125 entityFile = fPath + "/" + entityFile;
126 }
127
128 int pos5 = 0;
129 if ((pos5 = fFileString.find("&" + entityName + ";")) != -1) {
130 if (TRestTools::fileExists(entityFile)) {
131 std::ifstream entityFileRead(entityFile);
132 std::string str((std::istreambuf_iterator<char>(entityFileRead)),
133 std::istreambuf_iterator<char>());
134 entityFileRead.close();
135
137
138 fEntityVersionMap[entityName] = "";
139 size_t pp = str.find("##VERSION", 0);
140 if (pp != string::npos) {
141 size_t pp2 = str.find("##", pp + 4);
142 if (pp2 != string::npos) {
143 fEntityVersionMap[entityName] = str.substr(pp + 9, pp2 - pp - 9);
144 }
145 }
146
147 fFileString.replace(pos5, entityName.length() + 2, str);
148 } else {
149 cout << "GDML ERROR! No matching reference file for entity: \"" << entityName << "\"" << endl;
150 cout << "file name: \"" << entityFile << "\"" << endl;
151 exit(1);
152 }
153 } else {
154 cout << "TRestGDMLParser: Warning! redundant entity: \"" << entityName << "\"" << endl;
155 }
156 pos++;
157 }
158}
159
160void TRestGDMLParser::ReplaceAttributeWithKeyWord(const string& keyword) {
161 int n;
162 while ((n = fFileString.find(keyword, 0)) != -1) {
163 int pos1 = 0, pos2 = 0;
164 for (int i = n; i >= 0; i--) {
165 if (fFileString[i] == '"') {
166 pos1 = i + 1;
167 break;
168 }
169 }
170
171 for (unsigned int i = n; i < fFileString.size(); i++) {
172 if (fFileString[i] == '"') {
173 pos2 = i;
174 break;
175 }
176 }
177 string target = fFileString.substr(pos1, pos2 - pos1);
179
180 if (replace == target) {
181 cout << "Error! failed to replace mathematical expressions! check the file!" << endl;
182 cout << replace << endl;
183 exit(1);
184 }
185 fFileString.replace(pos1, pos2 - pos1, replace);
186 }
187}
endl_t RESTendl
Termination flag object for TRestStringOutput.
TiXmlElement * GetElement(std::string eleDeclare, TiXmlElement *e=nullptr)
Get an xml element from a given parent element, according to its declaration.
TiXmlElement * fElementGlobal
Saving the global element, to be passed to the resident class, if necessary.
TiXmlElement * StringToElement(std::string definition)
Parsing a string into TiXmlElement object.
std::string ReplaceVariables(const std::string buffer)
Identifies environmental variable replacing marks in the input buffer, and replace them with correspo...
virtual Int_t LoadSectionMetadata()
This method does some preparation of xml section.
std::string fConfigFileName
Full name of the rml file.
std::string ReplaceConstants(const std::string buffer)
Identifies "constants" in the input buffer, and replace them with corresponding value.
TiXmlElement * fElement
Saving the sectional element together with global element.
static std::pair< std::string, std::string > SeparatePathAndName(const std::string &fullname)
Separate path and filename in a full path+filename string, returns a pair of string.
Definition: TRestTools.cxx:813
static bool fileExists(const std::string &filename)
Returns true if the file (or directory) with path filename exists.
Definition: TRestTools.cxx:728
static std::string DownloadRemoteFile(const std::string &remoteFile, bool pidPrefix=false)
download the remote file automatically, returns the downloaded file name.
static std::string ToAbsoluteName(const std::string &filename)
It takes a path and returns its absolute path.
Definition: TRestTools.cxx:868
std::string RemoveWhiteSpaces(std::string in)
Returns the input string removing all white spaces.
std::string Replace(std::string in, std::string thisString, std::string byThisString, size_t fromPosition=0, Int_t N=0)
Replace any occurences of thisSring by byThisString inside string in.
std::string ReplaceMathematicalExpressions(std::string buffer, Int_t precision=0, std::string errorMessage="")
Evaluates and replaces valid mathematical expressions found in the input string buffer.