GENIEGenerator
Loading...
Searching...
No Matches
XmlParserUtils.cxx
Go to the documentation of this file.
1//____________________________________________________________________________
2/*
3 Copyright (c) 2003-2025, The GENIE Collaboration
4 For the full text of the license visit http://copyright.genie-mc.org
5
6 Costas Andreopoulos <c.andreopoulos \at cern.ch>
7 University of Liverpool
8*/
9//____________________________________________________________________________
10
11#include <sstream>
12
13#include <TFile.h>
14#include <TH1F.h>
15#include <TH1D.h>
16#include <TH2D.h>
17#include <TVectorD.h>
18
21
24#include "libxml/xmlmemory.h"
25
26
27using std::ostringstream;
28
29string genie::utils::xml::TrimSpaces(xmlChar * xmls) {
30
31 // trim the leading/trailing spaces from an parsed xml string like in:
32 //
33 // " I am a string with lots of spaces " ---->
34 // "I am a string with lots of spaces"
35 //
36 // In this method, "\n" is treated as 'empty space' so as to trim not only
37 // empty spaces in the line that contains the string but also all leading
38 // and trailing empty lines
39
40 string str = string( (const char *) xmls );
42}
43
45 // Does the same work as TrimSpaces, and cleans up the xmlChar memory
46 string str = TrimSpaces(xmls);
47 xmlFree(xmls);
48 return str;
49}
50
51//_________________________________________________________________________
52string genie::utils::xml::GetAttribute(xmlNodePtr xml_cur, string attr_name) {
53 xmlChar * xmls = xmlGetProp(xml_cur, (const xmlChar *) attr_name.c_str());
54 string str = TrimSpaces(xmls);
55 xmlFree(xmls);
56 return str;
57}
58
59
60//_________________________________________________________________________
61string genie::utils::xml::GetXMLPathList( bool add_tune ) {
62
63 // Get a colon separated list of potential locations for xml files
64 // e.g. ".:$MYSITEXML:/path/to/exp/version:$GALGCONF:$GENIE/config"
65 // user additions should be in $GXMLPATH
66 // All of the environment variaables have lower priority than the --xml-path command line argument
67
68 string pathlist;
69 std::string p0 = RunOpt::Instance()->XMLPath();
70 if ( p0.size() ) { pathlist += std::string(p0) + ":" ; }
71 const char* p1 = std::getenv( "GXMLPATH" );
72 if ( p1 ) { pathlist += std::string(p1) + ":" ; }
73 const char* p2 = std::getenv( "GXMLPATHS" ); // handle extra 's'
74 if ( p2 ) { pathlist += std::string(p2) + ":" ; }
75
76 // add originally supported alternative path
77 const char* p3 = std::getenv( "GALGCONF" );
78 if ( p3 ) { pathlist += std::string(p3) + ":" ; }
79
80 if ( add_tune && RunOpt::Instance() -> Tune() ) {
81
82 if ( RunOpt::Instance() -> Tune() -> IsConfigured() ) {
83
84 if ( ! RunOpt::Instance() -> Tune() -> IsValidated() ) {
85 LOG( "XmlParser", pFATAL) << "Tune not validated" ;
86 exit(0) ;
87 }
88
89 if ( ! RunOpt::Instance() -> Tune() -> OnlyConfiguration() )
90 pathlist += RunOpt::Instance() -> Tune() -> TuneDirectory() + ":" ;
91
92 pathlist += RunOpt::Instance() -> Tune() -> CMCDirectory() + ':' ;
93
94 } //tune not set in run option
95 } // requested tune and there is a tune
96
97 pathlist += GetXMLDefaultPath() ; // standard path in case no env
98 auto GENIE_REWEIGHT = std::getenv("GENIE_REWEIGHT");
99 if (GENIE_REWEIGHT)
100 pathlist += ":" + (std::string(GENIE_REWEIGHT) + "/config");
101 pathlist += ":$GENIE/src/Tools/Flux/GNuMINtuple"; // special case
102 return pathlist;
103}
104
105//_________________________________________________________________________
106string genie::utils::xml::GetXMLFilePath(string basename) {
107 // return a full path to a real XML file
108 // e.g. passing in "GNuMIFlux.xml"
109 // will return "/blah/GENIE/HEAD/config/GNuMIFlux.xml"
110 // allow ::colon:: ::semicolon:: and ::comma:: as path item separators
111
112 // empty basename should just be returned
113 // otherwise one will end up with a directory rather than a file
114 // as AccessPathName() isn't checking file vs. directory
115 if ( basename == "" ) return basename;
116
117 std::string pathlist = genie::utils::xml::GetXMLPathList();
118 std::vector<std::string> paths = genie::utils::str::Split(pathlist,":;,");
119 // expand any wildcards, etc.
120 size_t np = paths.size();
121 for ( size_t i=0; i< np; ++i ) {
122 const char* tmppath = paths[i].c_str();
123 auto expanded_path = gSystem->ExpandPathName(tmppath);
124 std::string onepath (expanded_path);
125 delete[] expanded_path;
126 onepath += "/";
127 onepath += basename;
128 bool noAccess = gSystem->AccessPathName(onepath.c_str());
129 if ( ! noAccess ) {
130 // LOG("XmlParserUtils", pDEBUG ) << onepath ;
131 return onepath; // found one
132 }
133 }
134 // didn't find any, return basename in case it is in "." and that
135 // wasn't listed in the XML path list. If you want "." to take
136 // precedence then it needs to be explicitly listed in $GXMLPATH.
137 return basename;
138}
139//____________________________________________________________________________
140xmlNodePtr genie::utils::xml::FindNode(xmlDocPtr xml_doc, string node_path)
141{
142 xmlNodePtr root_node = xmlDocGetRootElement(xml_doc);
143 if(root_node==NULL) {
144 LOG("XML", pERROR) << "Null root XML node";
145 return NULL;
146 }
147
148 vector<string> node_path_vec = genie::utils::str::Split(node_path,"/");
149
150 unsigned int ndepth = node_path_vec.size();
151 unsigned int idepth = 0;
152
153 xmlNodePtr curr_node = root_node;
154
155 while (curr_node != NULL) {
156 if( (!xmlStrcmp(
157 curr_node->name, (const xmlChar *) node_path_vec[idepth].c_str())) )
158 {
159 idepth++;
160 if(idepth == ndepth) {
161 return curr_node;
162 } else {
163 curr_node = curr_node->xmlChildrenNode;
164 }
165 }
166 curr_node = curr_node->next;
167 }
168
169 xmlFree(curr_node);
170 return NULL;
171}
172//____________________________________________________________________________
173bool genie::utils::xml::GetBool(xmlDocPtr xml_doc, string node_path)
174{
175 xmlNodePtr node = genie::utils::xml::FindNode(xml_doc, node_path);
176 if(node==NULL) {
177 return false;
178 }
179 string content = genie::utils::xml::TrimSpacesClean(
180 xmlNodeListGetString(xml_doc, node->xmlChildrenNode, 1) );
181
182 if(content == "true" ||
183 content == "TRUE" ||
184 content == "True" ||
185 content == "on" ||
186 content == "ON" ||
187 content == "On" ||
188 content == "1" ||
189 content == "I") return true;
190
191 if(content == "false" ||
192 content == "FALSE" ||
193 content == "False" ||
194 content == "off" ||
195 content == "OFF" ||
196 content == "Off" ||
197 content == "0" ||
198 content == "O") return false;
199
200 LOG("XML", pERROR)
201 << "Could not interpret content (" << content
202 << ") found at node_path: " << node_path << " as a boolean!";
203 return false;
204}
205//____________________________________________________________________________
206int genie::utils::xml::GetInt(xmlDocPtr xml_doc, string node_path)
207{
208 xmlNodePtr node = genie::utils::xml::FindNode(xml_doc, node_path);
209 if(node==NULL) {
210 return -999999;
211 }
212 string content = genie::utils::xml::TrimSpacesClean(
213 xmlNodeListGetString(xml_doc, node->xmlChildrenNode, 1) );
214 int value = atoi(content.c_str());
215 return value;
216}
217//____________________________________________________________________________
218vector<int> genie::utils::xml::GetIntArray(xmlDocPtr xml_doc, string node_path)
219{
220 vector<int> array;
221
222 xmlNodePtr node = genie::utils::xml::FindNode(xml_doc, node_path);
223 if(node==NULL) {
224 return array;
225 }
226
227 string content = genie::utils::xml::TrimSpacesClean(
228 xmlNodeListGetString(xml_doc, node->xmlChildrenNode, 1) );
229
230 vector<string> str_tokens = genie::utils::str::Split(content, ",");
231 vector<string>::const_iterator str_tokens_iter = str_tokens.begin();
232 for( ; str_tokens_iter != str_tokens.end(); ++str_tokens_iter) {
233 string token = genie::utils::str::TrimSpaces(*str_tokens_iter);
234 if (not token.size() ) continue;
235 array.push_back( atoi(token.c_str()) );
236 }
237 return array;
238}
239//____________________________________________________________________________
240double genie::utils::xml::GetDouble(xmlDocPtr xml_doc, string node_path)
241{
242 xmlNodePtr node = genie::utils::xml::FindNode(xml_doc, node_path);
243 if(node==NULL) {
244 return -999999;
245 }
246 string content = genie::utils::xml::TrimSpacesClean(
247 xmlNodeListGetString(xml_doc, node->xmlChildrenNode, 1) );
248 double value = atof(content.c_str());
249 return value;
250}
251//____________________________________________________________________________
252vector<double>
253 genie::utils::xml::GetDoubleArray(xmlDocPtr xml_doc, string node_path)
254{
255 vector<double> array;
256
257 xmlNodePtr node = genie::utils::xml::FindNode(xml_doc, node_path);
258 if(node==NULL) {
259 return array;
260 }
261
262 string content = genie::utils::xml::TrimSpacesClean(
263 xmlNodeListGetString(xml_doc, node->xmlChildrenNode, 1) );
264
265 vector<string> str_tokens = genie::utils::str::Split(content, ",");
266 vector<string>::const_iterator str_tokens_iter = str_tokens.begin();
267 for( ; str_tokens_iter != str_tokens.end(); ++str_tokens_iter) {
268 string token = genie::utils::str::TrimSpaces(*str_tokens_iter);
269 if (not token.size() ) continue;
270 array.push_back( atof(token.c_str()) );
271 }
272 return array;
273}
274//____________________________________________________________________________
275string genie::utils::xml::GetString(xmlDocPtr xml_doc, string node_path)
276{
277 xmlNodePtr node = genie::utils::xml::FindNode(xml_doc, node_path);
278 if(node==NULL) {
279 return "";
280 }
281 string content = genie::utils::xml::TrimSpacesClean(
282 xmlNodeListGetString(xml_doc, node->xmlChildrenNode, 1) );
283 return content;
284}
285//____________________________________________________________________________
286string genie::utils::xml::GetROOTFileName(xmlDocPtr xml_doc, string node_path)
287{
288 return genie::utils::xml::GetString(xml_doc, node_path+"/filename");
289}
290//____________________________________________________________________________
291string genie::utils::xml::GetROOTObjName (xmlDocPtr xml_doc, string node_path)
292{
293 return genie::utils::xml::GetString(xml_doc, node_path+"/objname");
294}
295//____________________________________________________________________________
296string genie::utils::xml::GetROOTObjType (xmlDocPtr xml_doc, string node_path)
297{
298 return genie::utils::xml::GetString(xml_doc, node_path+"/objtype");
299}
300//____________________________________________________________________________
302 xmlDocPtr xml_doc, string node_path, string base_dir)
303{
304 LOG("XML", pINFO) << "Reading info at XML node node_path: " << node_path;
305
306 string filename = genie::utils::xml::GetROOTFileName(xml_doc,node_path);
307
308 string used_base_dir = base_dir;
309 if(base_dir.find("<env>") != string::npos) {
310 used_base_dir = gSystem->Getenv("GENIE");
311 }
312
313 const char * full_filename =
314 Form("%s/%s", used_base_dir.c_str(), filename.c_str());
315 TFile * file = new TFile(full_filename,"read");
316 if(!file) {
317 LOG("XML",pERROR) << "No file: " << full_filename << " found";
318 return 0;
319 }
320 if(file->IsZombie()) {
321 LOG("XML",pERROR) << "File is a zombie: " << full_filename;
322 return 0;
323 }
324
325 return file;
326}
327//____________________________________________________________________________
329 xmlDocPtr xml_doc, string node_path, string base_dir)
330{
331 TFile * file = genie::utils::xml::GetTFile(xml_doc,node_path,base_dir);
332 if(!file) return 0;
333
334 string objname = genie::utils::xml::GetROOTObjName(xml_doc,node_path);
335 TH1F * h = (TH1F*)file->Get(objname.c_str());
336 if(!h) {
337 LOG("XML",pERROR) << "No " << objname;
338 file->Close();
339 delete file;
340 return 0;
341 }
342
343 TH1F * hcopy = new TH1F(*h);
344 hcopy->SetDirectory(0);
345 file->Close();
346 delete file;
347
348 return hcopy;
349}
350//____________________________________________________________________________
352 xmlDocPtr xml_doc, string node_path, string base_dir)
353{
354 TFile * file = genie::utils::xml::GetTFile(xml_doc,node_path,base_dir);
355 if(!file) return 0;
356
357 string objname = genie::utils::xml::GetROOTObjName(xml_doc,node_path);
358 TH1D * h = (TH1D*)file->Get(objname.c_str());
359 if(!h) {
360 LOG("XML",pERROR) << "No " << objname;
361 file->Close();
362 delete file;
363 return 0;
364 }
365
366 TH1D * hcopy = new TH1D(*h);
367 hcopy->SetDirectory(0);
368 file->Close();
369 delete file;
370
371 return hcopy;
372}
373//____________________________________________________________________________
375 xmlDocPtr xml_doc, string node_path, string base_dir)
376{
377 TFile * file = genie::utils::xml::GetTFile(xml_doc,node_path,base_dir);
378 if(!file) return 0;
379
380 string objname = genie::utils::xml::GetROOTObjName(xml_doc,node_path);
381 TH2D * h = (TH2D*)file->Get(objname.c_str());
382 if(!h) {
383 LOG("XML",pERROR) << "No " << objname;
384 file->Close();
385 delete file;
386 return 0;
387 }
388
389 TH2D * hcopy = new TH2D(*h);
390 hcopy->SetDirectory(0);
391 file->Close();
392 delete file;
393
394 return hcopy;
395}
396//____________________________________________________________________________
398 xmlDocPtr xml_doc, string node_path, string base_dir)
399{
400 TFile * file = genie::utils::xml::GetTFile(xml_doc,node_path,base_dir);
401 if(!file) return 0;
402
403 string objname = genie::utils::xml::GetROOTObjName(xml_doc,node_path);
404 TVectorD * vec = (TVectorD*)file->Get(objname.c_str());
405 if(!vec) {
406 LOG("XML",pERROR) << "No " << objname;
407 file->Close();
408 delete file;
409 return 0;
410 }
411
412 TVectorD * veccopy = new TVectorD(*vec);
413 file->Close();
414 delete file;
415
416 return veccopy;
417}
418//____________________________________________________________________________
419/*
420TMatrixDSym * genie::utils::xml::GetTMatrixDSym(
421 xmlDocPtr xml_doc, string node_path, string base_dir)
422{
423 return 0;
424}
425//____________________________________________________________________________
426TMatrixD * genie::utils::xml::GetTMatrixD(
427 xmlDocPtr xml_doc, string node_path, string base_dir)
428{
429 return 0;
430}
431//____________________________________________________________________________
432TSpline3 * genie::utils::xml::GetTSpline3(
433 xmlDocPtr xml_doc, string node_path, string base_dir)
434{
435 return 0;
436}
437//____________________________________________________________________________
438*/
#define pINFO
Definition Messenger.h:62
#define pERROR
Definition Messenger.h:59
#define pFATAL
Definition Messenger.h:56
#define LOG(stream, priority)
A macro that returns the requested log4cpp::Category appending a string (using the FILE,...
Definition Messenger.h:96
Is a concrete implementation of the QELFormFactorsModelI: Form Factors for Quasi Elastic CC vN Delta ...
static RunOpt * Instance(void)
Definition RunOpt.cxx:54
Utilities for string manipulation.
string TrimSpaces(string input)
vector< string > Split(string input, string delim)
TVectorD * GetTVectorD(xmlDocPtr xml_doc, string node_path, string base_dir="<env>")
TH2D * GetTH2D(xmlDocPtr xml_doc, string node_path, string base_dir="<env>")
vector< double > GetDoubleArray(xmlDocPtr xml_doc, string node_path)
string GetXMLPathList(bool add_tune=true)
double GetDouble(xmlDocPtr xml_doc, string node_path)
string TrimSpaces(xmlChar *xmls)
string GetString(xmlDocPtr xml_doc, string node_path)
bool GetBool(xmlDocPtr xml_doc, string node_path)
xmlNodePtr FindNode(xmlDocPtr xml_doc, string node_path)
string GetROOTObjName(xmlDocPtr xml_doc, string node_path)
int GetInt(xmlDocPtr xml_doc, string node_path)
string GetAttribute(xmlNodePtr xml_cur, string attr_name)
string TrimSpacesClean(xmlChar *xmls)
vector< int > GetIntArray(xmlDocPtr xml_doc, string node_path)
string GetROOTFileName(xmlDocPtr xml_doc, string node_path)
string GetROOTObjType(xmlDocPtr xml_doc, string node_path)
string GetXMLDefaultPath()
string GetXMLFilePath(string basename)
TH1F * GetTH1F(xmlDocPtr xml_doc, string node_path, string base_dir="<env>")
TH1D * GetTH1D(xmlDocPtr xml_doc, string node_path, string base_dir="<env>")
TFile * GetTFile(xmlDocPtr xml_doc, string node_path, string base_dir="<env>")