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