42#include "TDirectoryFile.h"
46#include "TObjString.h"
47#include "TSystemFile.h"
49#include <libxml/xmlreader.h>
50#include <libxml/parser.h>
51#include <libxml/xmlschemas.h>
54#include "git-revision.h"
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);
119 std::cerr << std::endl <<
"**ERROR** couldn't open file " <<
fFileName << std::endl;
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\">");
126 TIter next = f.GetListOfKeys();
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());
140 }
else if (str ==
"TDirectoryFile") {
141 dir =
dynamic_cast<TDirectoryFile*
>(key->ReadObj());
145 if (!
fQuiet) std::cout << std::endl;
161 for (UInt_t i=0; i<
fXmlData.size(); i++)
191 std::vector<std::string> temp_xml_data;
194 for (
unsigned int i=0; i<
fXmlData.size(); i++)
195 temp_xml_data.push_back(
fXmlData[i]);
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)
202 if (temp_xml_data[i].find(
"</SCAnaModule>") != std::string::npos)
205 if ((start > 0) && (end > 0))
206 temp_xml_data.erase(temp_xml_data.begin()+start, temp_xml_data.begin()+end);
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) {
221 temp_xml_data.insert(temp_xml_data.begin()+pos,
fXmlData.begin()+start,
fXmlData.begin()+end);
225 for (
unsigned int i=0; i<temp_xml_data.size(); i++)
226 fXmlData.push_back(temp_xml_data[i]);
229 temp_xml_data.clear();
241 TString offsetStr=
"";
242 for (UInt_t i=0; i<offset; i++)
245 TList *ll = dir->GetListOfKeys();
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"))
267 TString offsetStr=
"";
268 for (UInt_t i=0; i<offset; i++)
271 TIter next = folder->GetListOfFolders();
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();
290 TString offsetStr=
"";
291 for (UInt_t i=0; i<offset; i++)
295 TString str, xmlStr, type, label, xmlLabel;
298 xmlLabel = TString(obj->GetName());
299 if (xmlLabel.BeginsWith(
"Detector")) {
300 xmlLabel.Remove(0, 8);
301 if (xmlLabel.IsDigit())
302 xmlLabel =
"Detector";
304 xmlLabel = TString(obj->GetName());
307 if (!
fQuiet) std::cout << std::endl << offsetStr << obj->GetName() <<
" (# " << obj->GetEntries() <<
")";
308 if (!strcmp(obj->GetName(),
"DetectorInfo"))
311 xmlStr = offsetStr +
"<" + xmlLabel +
">";
314 for (UInt_t i=0; i<static_cast<UInt_t>(obj->GetEntries()); i++) {
316 type = obj->At(i)->ClassName();
317 if (type ==
"TObjArray") {
318 DumpObjArray(
dynamic_cast<TObjArray*
>(obj->At(i)), offset+2);
320 tstr =
static_cast<TObjString*
>(obj->At(i));
321 str = tstr->GetString();
322 str.Remove(TString::kTrailing,
'\n');
327 if (!
fQuiet) std::cout << std::endl << offsetStr << i <<
": " << str;
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);
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(
";");
349 if (tokens)
delete tokens;
352 xmlStr = offsetStr +
" " +
"<" + label +
">" + type +
"</" + label +
">" ;
357 xmlStr = offsetStr +
"</" + xmlLabel +
">";
370 TString offsetStr=
"";
371 for (UInt_t i=0; i<offset; i++)
374 TString nameTag(
""), typeTag(
"");
377 nameTag =
"HistoName";
378 typeTag =
"HistoType";
381 nameTag =
"SlowControlName";
382 typeTag =
"SlowControlType";
396 str = offsetStr +
"<" + nameTag +
">";
397 str += obj->GetName();
398 str +=
"</" + nameTag +
">";
401 str = offsetStr +
"<" + typeTag +
">";
402 str += obj->ClassName();
403 str +=
"</" + typeTag +
">";
417 TString offsetStr=
"";
418 for (UInt_t i=0; i<offset; i++)
421 if ((str ==
"TFolder") || (str ==
"TDirectoryFile")) {
422 TString xmlTagName(TString(obj->GetName()));
425 if (!xmlTagName.CompareTo(
"DecayAnaModule"))
427 else if (!xmlTagName.CompareTo(
"SCAnaModule"))
429 else if (!xmlTagName.CompareTo(
"SCAnaModule"))
435 TString sstr = offsetStr +
"<" + xmlTagName +
">";
438 if (str ==
"TFolder")
439 DumpFolder(
dynamic_cast<TFolder*
>(obj), offset);
443 sstr = offsetStr +
"</" + xmlTagName +
">";
445 }
else if (str ==
"TObjArray") {
448 }
else if (str ==
"TObjString") {
449 TObjString *ostr =
dynamic_cast<TObjString*
>(obj);
450 TString tstr = ostr->GetString();
451 tstr.Remove(TString::kTrailing,
'\n');
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);
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(
";");
477 if (tokens)
delete tokens;
481 TString entryTag(
"");
484 entryTag = TString(
"DecayHistoEntry");
487 entryTag = TString(
"SlowControlHistoEntry");
491 entryTag = TString(
"Entry");
496 str = offsetStr +
"<" + entryTag +
">";
498 DumpEntry(
dynamic_cast<TObject*
>(obj), offset);
499 str = offsetStr +
"</" + entryTag +
">";
513 if (entry.Contains(
"-@0")) {
515 }
else if (entry.Contains(
"-@1")) {
517 }
else if (entry.Contains(
"-@2")) {
519 }
else if (entry.Contains(
"-@3")) {
520 type =
"TMusrRunPhysicalQuantity";
521 }
else if (entry.Contains(
"-@4")) {
522 type =
"TStringVector";
523 }
else if (entry.Contains(
"-@5")) {
525 }
else if (entry.Contains(
"-@6")) {
526 type =
"TDoubleVector";
543 Ssiz_t start = entry.First(
'-');
544 Ssiz_t end = entry.First(
':');
546 if ((start == -1) || (end == -1))
553 Ssiz_t pos = entry.First(
'@');
556 if (entry(pos-1) !=
'-')
561 label.Remove(0, start+2);
562 label.Remove(end-start-2, label.Length());
564 label.ReplaceAll(
' ',
'_');
565 label.ReplaceAll(
'(',
'_');
566 label.ReplaceAll(
')',
'_');
567 label.ReplaceAll(
'[',
'_');
568 label.ReplaceAll(
']',
'_');
569 label.ReplaceAll(
'{',
'_');
570 label.ReplaceAll(
'}',
'_');
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;
594int is_valid(
const xmlDocPtr doc,
const char *schema_filename)
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;
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);
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);
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);
622 int is_valid = (xmlSchemaValidateDoc(valid_ctxt, doc) == 0);
623 xmlSchemaFreeValidCtxt(valid_ctxt);
624 xmlSchemaFree(schema);
625 xmlSchemaFreeParserCtxt(parser_ctxt);
626 xmlFreeDoc(schema_doc);
635int main(
int argc,
char *argv[])
640 }
else if (argc==2) {
641 if (!strcmp(argv[1],
"--version")) {
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;
646 std::cout << std::endl <<
"musrRootValidation version: " << PACKAGE_VERSION <<
" (" << BUILD_TYPE <<
"), ROOT version: " << ROOT_VERSION_USED << std::endl << std::endl;
650 std::cout << std::endl <<
"musrRootValidation git-branch: " << GIT_BRANCH <<
", git-rev: " << GIT_CURRENT_SHA1 << std::endl << std::endl;
652 std::cout << std::endl <<
"musrRootValidation version: unknown." << std::endl << std::endl;
663 bool quiet=
false, keep=
false;
664 for (
int i=1; i<argc; i++) {
665 if (!strcmp(argv[i],
"--quiet"))
667 if (!strcmp(argv[i],
"--keep"))
673 std::cerr << std::endl <<
"**ERROR** " << argv[1] <<
" is not a valid MusrRoot file." << std::endl << std::endl;
678 if (doc ==
nullptr) {
679 std::cerr << std::endl <<
"**ERROR** couldn't get xmlDocPtr for xml-file " << argv[1] <<
"." << std::endl << std::endl;
684 std::cout << std::endl <<
"xml-file " << argv[1] <<
" validates against xml-schema " << argv[2] << std::endl << std::endl;
686 std::cerr << std::endl <<
"**ERROR** xml-file " << argv[1] <<
" fails to validate against xml-schema " << argv[2] << std::endl << std::endl;
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,";
694 std::cerr << std::endl << std::endl;
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;
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 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[])
int is_valid(const xmlDocPtr doc, const char *schema_filename)