musrfit 1.10.0
musrRootValidation.cpp
Go to the documentation of this file.
1/***************************************************************************
2
3 musrRootValidation.cpp
4
5 Author: Andreas Suter
6 e-mail: andreas.suter@psi.ch
7
8***************************************************************************/
9
10/***************************************************************************
11 * Copyright (C) 2007-2026 by Andreas Suter *
12 * andreas.suter@psi.ch *
13 * *
14 * This program is free software; you can redistribute it and/or modify *
15 * it under the terms of the GNU General Public License as published by *
16 * the Free Software Foundation; either version 2 of the License, or *
17 * (at your option) any later version. *
18 * *
19 * This program is distributed in the hope that it will be useful, *
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
22 * GNU General Public License for more details. *
23 * *
24 * You should have received a copy of the GNU General Public License *
25 * along with this program; if not, write to the *
26 * Free Software Foundation, Inc., *
27 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
28 ***************************************************************************/
29
30#ifdef HAVE_CONFIG_H
31#include "config.h"
32#endif
33
34#include <iostream>
35#include <fstream>
36#include <vector>
37#include <string>
38
39#include "TString.h"
40#include "TFile.h"
41#include "TFolder.h"
42#include "TDirectoryFile.h"
43#include "TKey.h"
44#include "TList.h"
45#include "TObjArray.h"
46#include "TObjString.h"
47#include "TSystemFile.h"
48
49#include <libxml/xmlreader.h>
50#include <libxml/parser.h>
51#include <libxml/xmlschemas.h>
52
53#ifdef HAVE_GIT_REV_H
54#include "git-revision.h"
55#endif
56
57#include "PMusr.h"
58
59//-----------------------------------------------------------------------
64{
65 public:
66 PMusrRoot2Xml(const char *fileName, bool quiet, bool keep);
67 virtual ~PMusrRoot2Xml();
68
69 virtual Bool_t IsValid() { return fValid; }
70 virtual TString GetXmlDumpFileName() { return fXmlDumpFileName; }
71 virtual UInt_t GetNoOfDecayHistos() { return fNoOfDecayHistos; }
73 virtual UInt_t GetNoOfHistos() { return fNoOfHistos; }
74 virtual UInt_t GetNoOfRedGreenOffsets() { return fNoOfRedGreenOffsets; }
75 virtual UInt_t GetNoOfDetectors() { return fNoOfDetectors; }
76
77 private:
79
80 std::vector<std::string> fXmlData;
81
82 Bool_t fQuiet;
83 Bool_t fKeep;
84 Bool_t fValid;
85 TString fFileName;
88
89 UInt_t fNoOfDecayHistos{0};
90 UInt_t fNoOfHistos{0};
92 UInt_t fNoOfDetectors{0};
93
94 virtual void SortHistoFolders();
95 virtual void DumpDirectory(TDirectoryFile *dir, UInt_t offset);
96 virtual void DumpFolder(TFolder *folder, UInt_t offset);
97 virtual void DumpObjArray(TObjArray *obj, UInt_t offset);
98 virtual void DumpEntry(TObject *obj, UInt_t offset);
99 virtual void CheckClass(TObject *obj, TString str, UInt_t offset);
100 virtual void GetType(TString entry, TString &type);
101 virtual void GetLabel(TString entry, TString &label);
102};
103
104//-----------------------------------------------------------------------
108PMusrRoot2Xml::PMusrRoot2Xml(const char *fileName, bool quiet, bool keep) : fQuiet(quiet), fKeep(keep), fFileName(fileName)
109{
110 fXmlDumpFileName = "__MusrRootXmlDump.xml";
112 fValid = false;
113 fXmlData.clear();
114
115 // read assumed MusrRoot file
116 TFile f(fFileName.Data());
117
118 if (f.IsZombie()) {
119 std::cerr << std::endl << "**ERROR** couldn't open file " << fFileName << std::endl;
120 return;
121 }
122
123 fXmlData.push_back("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
124 fXmlData.push_back("<MusrRoot xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"file:MusrRoot.xsd\">");
125
126 TIter next = f.GetListOfKeys();
127 TKey *key;
128 TFolder *folder;
129 TDirectoryFile *dir;
130 TString str;
131
132 UInt_t offset = 2;
133
134 while ((key = dynamic_cast<TKey*>(next())) != nullptr) {
135 if (!fQuiet) std::cout << std::endl << "name: " << key->GetName() << ", class name: " << key->GetClassName();
136 str = key->GetClassName();
137 if (str == "TFolder") {
138 folder = dynamic_cast<TFolder*>(key->ReadObj());
139 CheckClass(folder, str, offset);
140 } else if (str == "TDirectoryFile") {
141 dir = dynamic_cast<TDirectoryFile*>(key->ReadObj());
142 CheckClass(dir, str, offset);
143 }
144 }
145 if (!fQuiet) std::cout << std::endl;
146
147 f.Close();
148
149 fXmlData.push_back("</MusrRoot>");
150
151 // the sort_histo_folders is needed since XML-Schema is not flexible enough to handle
152 // histos -|
153 // |- DecayAnaModule
154 // ... (any other analyzer module sub-folder
155 // |- SCAnaModule
156 // Hence SCAnaModule has artificially moved up, just to follow DecayAnaModule
158
159 std::ofstream fout(fXmlDumpFileName.Data());
160
161 for (UInt_t i=0; i<fXmlData.size(); i++)
162 fout << fXmlData[i] << std::endl;
163 fout.close();
164
165 fValid = true;
166}
167
168//-----------------------------------------------------------------------
173{
174 if (!fKeep) {
175 TSystemFile sf(fXmlDumpFileName.Data(), "./");
176 sf.Delete();
177 }
178}
179
180//-----------------------------------------------------------------------
190{
191 std::vector<std::string> temp_xml_data;
192
193 // first make a copy of the original fXmlData
194 for (unsigned int i=0; i<fXmlData.size(); i++)
195 temp_xml_data.push_back(fXmlData[i]);
196
197 // remove SCAnaModule from temp_xml_data
198 unsigned int start = 0, end = 0;
199 for (unsigned int i=0; i<temp_xml_data.size(); i++) {
200 if (temp_xml_data[i].find("<SCAnaModule>") != std::string::npos)
201 start = i;
202 if (temp_xml_data[i].find("</SCAnaModule>") != std::string::npos)
203 end = i+1;
204 }
205 if ((start > 0) && (end > 0))
206 temp_xml_data.erase(temp_xml_data.begin()+start, temp_xml_data.begin()+end);
207 else // no SCAnaModule present, hence nothing to be done
208 return;
209
210 // insert SCAnaModule just after DecayAnaModule
211 // 1st find end of DecayAnaModule
212 unsigned int pos = 0;
213 for (unsigned int i=0; i<temp_xml_data.size(); i++) {
214 if (temp_xml_data[i].find("</DecayAnaModule>") != std::string::npos) {
215 pos = i+1;
216 break;
217 }
218 }
219 if (pos == 0) // something is wrong, hence to not do anything
220 return;
221 temp_xml_data.insert(temp_xml_data.begin()+pos, fXmlData.begin()+start, fXmlData.begin()+end);
222
223 // copy temp_xml_data back into fXmlData
224 fXmlData.clear();
225 for (unsigned int i=0; i<temp_xml_data.size(); i++)
226 fXmlData.push_back(temp_xml_data[i]);
227
228 // clean up
229 temp_xml_data.clear();
230}
231
232//-----------------------------------------------------------------------
239void PMusrRoot2Xml::DumpDirectory(TDirectoryFile *dir, UInt_t offset)
240{
241 TString offsetStr="";
242 for (UInt_t i=0; i<offset; i++)
243 offsetStr += " ";
244
245 TList *ll = dir->GetListOfKeys();
246 TString str;
247 TObject *oo;
248 for (TObject *obj: *ll) {
249 oo = static_cast<TKey*>(obj)->ReadObj();
250 if (!fQuiet) std::cout << std::endl << offsetStr << "name: " << oo->GetName() << ", class name: " << oo->ClassName();
251 str = oo->ClassName();
252 if (TString(oo->GetName()).Contains("Detector0"))
254 CheckClass(oo, str, offset);
255 }
256}
257
258//-----------------------------------------------------------------------
265void PMusrRoot2Xml::DumpFolder(TFolder *folder, UInt_t offset)
266{
267 TString offsetStr="";
268 for (UInt_t i=0; i<offset; i++)
269 offsetStr += " ";
270
271 TIter next = folder->GetListOfFolders();
272 TObject *obj;
273 TString str;
274 while ((obj = dynamic_cast<TObject*>(next())) != nullptr) {
275 if (!fQuiet) std::cout << std::endl << offsetStr << "name: " << obj->GetName() << ", class name: " << obj->ClassName();
276 str = obj->ClassName();
277 CheckClass(obj, str, offset);
278 }
279}
280
281//-----------------------------------------------------------------------
288void PMusrRoot2Xml::DumpObjArray(TObjArray *obj, UInt_t offset)
289{
290 TString offsetStr="";
291 for (UInt_t i=0; i<offset; i++)
292 offsetStr += " ";
293
294 TObjString *tstr;
295 TString str, xmlStr, type, label, xmlLabel;
296
297 // check if the obj name is anything like DetectorXXX, where XXX is a number
298 xmlLabel = TString(obj->GetName());
299 if (xmlLabel.BeginsWith("Detector")) {
300 xmlLabel.Remove(0, 8); // remove 'Detector'
301 if (xmlLabel.IsDigit())
302 xmlLabel = "Detector";
303 else
304 xmlLabel = TString(obj->GetName());
305 }
306
307 if (!fQuiet) std::cout << std::endl << offsetStr << obj->GetName() << " (# " << obj->GetEntries() << ")";
308 if (!strcmp(obj->GetName(), "DetectorInfo"))
309 fNoOfDetectors = obj->GetEntries();
310
311 xmlStr = offsetStr + "<" + xmlLabel + ">";
312 fXmlData.push_back(xmlStr.Data());
313
314 for (UInt_t i=0; i<static_cast<UInt_t>(obj->GetEntries()); i++) {
315 // check if entry is a TObjArray
316 type = obj->At(i)->ClassName();
317 if (type == "TObjArray") {
318 DumpObjArray(dynamic_cast<TObjArray*>(obj->At(i)), offset+2);
319 } else { // not a TObjArray
320 tstr = static_cast<TObjString*>(obj->At(i));
321 str = tstr->GetString();
322 str.Remove(TString::kTrailing, '\n');
323
324 GetType(str, type);
325 GetLabel(str, label);
326
327 if (!fQuiet) std::cout << std::endl << offsetStr << i << ": " << str;
328
329 // filter out the number of histograms according to the RunInfo
330 if (str.Contains("- No of Histos: ")) {
331 TString histoStr = str;
332 Ssiz_t pos = histoStr.Last(':');
333 histoStr.Remove(0, pos+1);
334 pos = histoStr.Last('-');
335 histoStr.Remove(pos);
336 fNoOfHistos = histoStr.Atoi();
337 }
338
339 // filter out the number of Red/Green offsets
340 if (str.Contains("- RedGreen Offsets: ")) {
341 TString redGreenStr = str;
342 Ssiz_t pos = redGreenStr.Last(':');
343 redGreenStr.Remove(0, pos+1);
344 pos = redGreenStr.Last('-');
345 redGreenStr.Remove(pos);
346 TObjArray *tokens = redGreenStr.Tokenize(";");
347 if (tokens)
348 fNoOfRedGreenOffsets = tokens->GetEntries();
349 if (tokens) delete tokens;
350 }
351
352 xmlStr = offsetStr + " " + "<" + label + ">" + type + "</" + label + ">" ;
353 fXmlData.push_back(xmlStr.Data());
354 }
355 }
356
357 xmlStr = offsetStr + "</" + xmlLabel + ">";
358 fXmlData.push_back(xmlStr.Data());
359}
360
361//-----------------------------------------------------------------------
368void PMusrRoot2Xml::DumpEntry(TObject *obj, UInt_t offset)
369{
370 TString offsetStr="";
371 for (UInt_t i=0; i<offset; i++)
372 offsetStr += " ";
373
374 TString nameTag(""), typeTag("");
375 switch (fNodeTag) {
376 case eDecayAnaModule:
377 nameTag = "HistoName";
378 typeTag = "HistoType";
379 break;
381 nameTag = "SlowControlName";
382 typeTag = "SlowControlType";
383 break;
384 case eUnkown:
385 default:
386 nameTag = "Name";
387 typeTag = "Type";
388 break;
389 }
390
393
394 TString str;
395
396 str = offsetStr + "<" + nameTag + ">";
397 str += obj->GetName();
398 str += "</" + nameTag + ">";
399 fXmlData.push_back(str.Data());
400
401 str = offsetStr + "<" + typeTag + ">";
402 str += obj->ClassName();
403 str += "</" + typeTag + ">";
404 fXmlData.push_back(str.Data());
405}
406
407//-----------------------------------------------------------------------
415void PMusrRoot2Xml::CheckClass(TObject *obj, TString str, UInt_t offset)
416{
417 TString offsetStr="";
418 for (UInt_t i=0; i<offset; i++)
419 offsetStr += " ";
420
421 if ((str == "TFolder") || (str == "TDirectoryFile")) {
422 TString xmlTagName(TString(obj->GetName()));
423
424 // set folder tag
425 if (!xmlTagName.CompareTo("DecayAnaModule"))
427 else if (!xmlTagName.CompareTo("SCAnaModule"))
429 else if (!xmlTagName.CompareTo("SCAnaModule"))
431 else
433
434 offset += 2;
435 TString sstr = offsetStr + "<" + xmlTagName + ">";
436 fXmlData.push_back(sstr.Data());
437
438 if (str == "TFolder")
439 DumpFolder(dynamic_cast<TFolder*>(obj), offset);
440 else
441 DumpDirectory(dynamic_cast<TDirectoryFile*>(obj), offset);
442
443 sstr = offsetStr + "</" + xmlTagName + ">";
444 fXmlData.push_back(sstr.Data());
445 } else if (str == "TObjArray") {
446 offset += 2;
447 DumpObjArray(dynamic_cast<TObjArray*>(obj), offset);
448 } else if (str == "TObjString") {
449 TObjString *ostr = dynamic_cast<TObjString*>(obj);
450 TString tstr = ostr->GetString();
451 tstr.Remove(TString::kTrailing, '\n');
452
453 TString type, label;
454 GetType(tstr, type);
455 GetLabel(tstr, label);
456
457 // filter out the number of histograms according to the RunInfo
458 if (tstr.Contains("- No of Histos: ")) {
459 TString histoStr = tstr;
460 Ssiz_t pos = histoStr.Last(':');
461 histoStr.Remove(0, pos+1);
462 pos = histoStr.Last('-');
463 histoStr.Remove(pos);
464 fNoOfHistos = histoStr.Atoi();
465 }
466
467 // filter out the number of Red/Green offsets
468 if (tstr.Contains("- RedGreen Offsets: ")) {
469 TString redGreenStr = tstr;
470 Ssiz_t pos = redGreenStr.Last(':');
471 redGreenStr.Remove(0, pos+1);
472 pos = redGreenStr.Last('-');
473 redGreenStr.Remove(pos);
474 TObjArray *tokens = redGreenStr.Tokenize(";");
475 if (tokens)
476 fNoOfRedGreenOffsets = tokens->GetEntries();
477 if (tokens) delete tokens;
478 }
479 } else {
480 // filter out the proper entry tag
481 TString entryTag("");
482 switch (fNodeTag) {
483 case eDecayAnaModule:
484 entryTag = TString("DecayHistoEntry");
485 break;
487 entryTag = TString("SlowControlHistoEntry");
488 break;
489 case eUnkown:
490 default:
491 entryTag = TString("Entry");
492 break;
493 }
494
495 offset += 2;
496 str = offsetStr + "<" + entryTag + ">";
497 fXmlData.push_back(str.Data());
498 DumpEntry(dynamic_cast<TObject*>(obj), offset);
499 str = offsetStr + "</" + entryTag + ">";
500 fXmlData.push_back(str.Data());
501 }
502}
503
504//-----------------------------------------------------------------------
511void PMusrRoot2Xml::GetType(TString entry, TString &type)
512{
513 if (entry.Contains("-@0")) {
514 type = "TString";
515 } else if (entry.Contains("-@1")) {
516 type = "Int_t";
517 } else if (entry.Contains("-@2")) {
518 type = "Double_t";
519 } else if (entry.Contains("-@3")) {
520 type = "TMusrRunPhysicalQuantity";
521 } else if (entry.Contains("-@4")) {
522 type = "TStringVector";
523 } else if (entry.Contains("-@5")) {
524 type = "TIntVector";
525 } else if (entry.Contains("-@6")) {
526 type = "TDoubleVector";
527 } else {
528 type = "TString";
529 }
530}
531
532//-----------------------------------------------------------------------
539void PMusrRoot2Xml::GetLabel(TString entry, TString &label)
540{
541 label="no_idea";
542
543 Ssiz_t start = entry.First('-');
544 Ssiz_t end = entry.First(':');
545
546 if ((start == -1) || (end == -1))
547 return;
548
549 if (end - start < 2)
550 return;
551
552 // check that '-@' is present in the string, otherwise it is NOT a known label
553 Ssiz_t pos = entry.First('@');
554 if (pos < 1)
555 return;
556 if (entry(pos-1) != '-')
557 return;
558
559 // cut out value
560 label = entry;
561 label.Remove(0, start+2);
562 label.Remove(end-start-2, label.Length());
563
564 label.ReplaceAll(' ', '_'); // replace spaces through underscores
565 label.ReplaceAll('(', '_'); // replace '(' through underscores
566 label.ReplaceAll(')', '_'); // replace ')' through underscores
567 label.ReplaceAll('[', '_'); // replace '[' through underscores
568 label.ReplaceAll(']', '_'); // replace ']' through underscores
569 label.ReplaceAll('{', '_'); // replace '[' through underscores
570 label.ReplaceAll('}', '_'); // replace ']' through underscores
571}
572
573//-----------------------------------------------------------------------
578{
579 std::cout << std::endl << "usage: musrRootValidation <musrRootFile> <musrRootSchema> [--quiet] [--keep] | --help | --version";
580 std::cout << std::endl << " --quiet: do not dump the MusrRoot file info while validating";
581 std::cout << std::endl << " --keep: do NOT delete the intermediate XML-file";
582 std::cout << std::endl << " --help: shows this help";
583 std::cout << std::endl << " --version: shows the current version";
584 std::cout << std::endl << std::endl;
585}
586
587//-----------------------------------------------------------------------
594int is_valid(const xmlDocPtr doc, const char *schema_filename)
595{
596 xmlDocPtr schema_doc = xmlReadFile(schema_filename, nullptr, XML_PARSE_NONET);
597 if (schema_doc == nullptr) {
598 std::cerr << std::endl << "**ERROR** the schema (" << schema_filename << ") cannot be loaded or is not well-formed" << std::endl << std::endl;
599 return -1;
600 }
601 xmlSchemaParserCtxtPtr parser_ctxt = xmlSchemaNewDocParserCtxt(schema_doc);
602 if (parser_ctxt == nullptr) {
603 std::cerr << std::endl << "**ERROR** unable to create a parser context for the schema." << std::endl << std::endl;
604 xmlFreeDoc(schema_doc);
605 return -2;
606 }
607 xmlSchemaPtr schema = xmlSchemaParse(parser_ctxt);
608 if (schema == nullptr) {
609 std::cerr << std::endl << "**ERROR** the schema itself is not valid." << std::endl << std::endl;
610 xmlSchemaFreeParserCtxt(parser_ctxt);
611 xmlFreeDoc(schema_doc);
612 return -3;
613 }
614 xmlSchemaValidCtxtPtr valid_ctxt = xmlSchemaNewValidCtxt(schema);
615 if (valid_ctxt == nullptr) {
616 std::cerr << std::endl << "**ERROR** unable to create a validation context for the schema." << std::endl << std::endl;
617 xmlSchemaFree(schema);
618 xmlSchemaFreeParserCtxt(parser_ctxt);
619 xmlFreeDoc(schema_doc);
620 return -4;
621 }
622 int is_valid = (xmlSchemaValidateDoc(valid_ctxt, doc) == 0);
623 xmlSchemaFreeValidCtxt(valid_ctxt);
624 xmlSchemaFree(schema);
625 xmlSchemaFreeParserCtxt(parser_ctxt);
626 xmlFreeDoc(schema_doc);
627 // force the return value to be non-negative on success
628 return is_valid ? 1 : 0;
629}
630
631//-----------------------------------------------------------------------
635int main(int argc, char *argv[])
636{
637 if (argc==1) {
638 mrv_syntax();
639 return -1;
640 } else if (argc==2) {
641 if (!strcmp(argv[1], "--version")) {
642#ifdef HAVE_CONFIG_H
643#ifdef HAVE_GIT_REV_H
644 std::cout << std::endl << "musrRootValidation version: " << PACKAGE_VERSION << ", git-branch: " << GIT_BRANCH << ", git-rev: " << GIT_CURRENT_SHA1 << " (" << BUILD_TYPE << "), ROOT version: " << ROOT_VERSION_USED << std::endl << std::endl;
645#else
646 std::cout << std::endl << "musrRootValidation version: " << PACKAGE_VERSION << " (" << BUILD_TYPE << "), ROOT version: " << ROOT_VERSION_USED << std::endl << std::endl;
647#endif
648#else
649#ifdef HAVE_GIT_REV_H
650 std::cout << std::endl << "musrRootValidation git-branch: " << GIT_BRANCH << ", git-rev: " << GIT_CURRENT_SHA1 << std::endl << std::endl;
651#else
652 std::cout << std::endl << "musrRootValidation version: unknown." << std::endl << std::endl;
653#endif
654#endif
655 return 0;
656 } else {
657 mrv_syntax();
658 return -1;
659 }
660 }
661
662 // filter out possible options
663 bool quiet=false, keep=false;
664 for (int i=1; i<argc; i++) {
665 if (!strcmp(argv[i], "--quiet"))
666 quiet = true;
667 if (!strcmp(argv[i], "--keep"))
668 keep = true;
669 }
670
671 PMusrRoot2Xml dump(argv[1], quiet, keep);
672 if (!dump.IsValid()) {
673 std::cerr << std::endl << "**ERROR** " << argv[1] << " is not a valid MusrRoot file." << std::endl << std::endl;
674 return -1;
675 }
676
677 xmlDocPtr doc = xmlParseFile(dump.GetXmlDumpFileName().Data());
678 if (doc == nullptr) {
679 std::cerr << std::endl << "**ERROR** couldn't get xmlDocPtr for xml-file " << argv[1] << "." << std::endl << std::endl;
680 return -1;
681 }
682
683 if (is_valid(doc, argv[2])) {
684 std::cout << std::endl << "xml-file " << argv[1] << " validates against xml-schema " << argv[2] << std::endl << std::endl;
685 } else {
686 std::cerr << std::endl << "**ERROR** xml-file " << argv[1] << " fails to validate against xml-schema " << argv[2] << std::endl << std::endl;
687 }
688
689 // do some further consistency checks
690 if (dump.GetNoOfDecayHistos() != dump.GetNoOfExpectedHistos()) {
691 std::cerr << std::endl << "**ERROR** number of histogram found in the DecayAnaModule is inconsistent";
692 std::cerr << std::endl << " with the header; found " << dump.GetNoOfDecayHistos() << " histograms in the DecayAnaModule,";
693 std::cerr << std::endl << " but in the header: No of Histos = " << dump.GetNoOfHistos() << "; # RedGreen Offsets = " << dump.GetNoOfRedGreenOffsets();
694 std::cerr << std::endl << std::endl;
695 }
696
697 if (dump.GetNoOfDecayHistos() != dump.GetNoOfDetectors()) {
698 std::cerr << std::endl << "**ERROR** number of histogram found in the DecayAnaModule is inconsistent";
699 std::cerr << std::endl << " with number of Detector entries in the RunHeader.";
700 std::cerr << std::endl << " Found " << dump.GetNoOfDecayHistos() << " histograms in the DecayAnaModule,";
701 std::cerr << std::endl << " but " << dump.GetNoOfDetectors() << " number of Detector entries.";
702 std::cerr << std::endl << std::endl;
703 }
704
705 return 0;
706}
virtual TString GetXmlDumpFileName()
virtual UInt_t GetNoOfHistos()
virtual void DumpDirectory(TDirectoryFile *dir, UInt_t offset)
virtual UInt_t GetNoOfRedGreenOffsets()
virtual void DumpEntry(TObject *obj, UInt_t offset)
virtual Bool_t IsValid()
virtual UInt_t GetNoOfExpectedHistos()
PMusrRoot2Xml(const char *fileName, bool quiet, bool keep)
virtual UInt_t GetNoOfDetectors()
Bool_t fKeep
true = keep the XML dump file
Bool_t fValid
true if the conversion was fine
TString fFileName
file name of the ROOT file
Bool_t fQuiet
true = suppress output while converting
UInt_t fNoOfDetectors
number of detector entries in the header
UInt_t fNoOfHistos
number of histos from run header
std::vector< std::string > fXmlData
keeps the XML structure dump of the ROOT file
virtual void CheckClass(TObject *obj, TString str, UInt_t offset)
UInt_t fNoOfDecayHistos
number of decay histos in the DecayAnaModule
virtual void SortHistoFolders()
virtual void GetLabel(TString entry, TString &label)
UInt_t fNoOfRedGreenOffsets
number of RedGreen offsets
virtual void DumpObjArray(TObjArray *obj, UInt_t offset)
virtual UInt_t GetNoOfDecayHistos()
virtual void DumpFolder(TFolder *folder, UInt_t offset)
virtual void GetType(TString entry, TString &type)
TString fXmlDumpFileName
file name of the XML dump file
int main(int argc, char *argv[])
void mrv_syntax()
int is_valid(const xmlDocPtr doc, const char *schema_filename)