added a validator program (musrRootValidation) for MusrRoot files.
This commit is contained in:
parent
01696e3994
commit
5db90af1dc
@ -6,6 +6,7 @@
|
|||||||
|
|
||||||
changes since 0.10.0
|
changes since 0.10.0
|
||||||
===================================
|
===================================
|
||||||
|
NEW 2012-03-28 added a validator program (musrRootValidation) for MusrRoot files.
|
||||||
NEW 2012-03-22 added a first version of MusrRoot, the next muSR file format at PSI. At the same time a rewrite of
|
NEW 2012-03-22 added a first version of MusrRoot, the next muSR file format at PSI. At the same time a rewrite of
|
||||||
the low run data handling has been done which enables a proper Red/Green handling with histogram sets addressable
|
the low run data handling has been done which enables a proper Red/Green handling with histogram sets addressable
|
||||||
either via the histogram number or the index in the data vector.
|
either via the histogram number or the index in the data vector.
|
||||||
|
56
configure.ac
56
configure.ac
@ -366,6 +366,57 @@ AC_SUBST(BOOST_LIBS)
|
|||||||
AC_SUBST(BOOST_CFLAGS)
|
AC_SUBST(BOOST_CFLAGS)
|
||||||
|
|
||||||
|
|
||||||
|
dnl -----------------------------------------------
|
||||||
|
dnl Ask user for path to libxml2
|
||||||
|
dnl -----------------------------------------------
|
||||||
|
LIBXML2_FOUND=0
|
||||||
|
AC_ARG_WITH([libxml2],
|
||||||
|
[AC_HELP_STRING([--with-libxml2],[path to the header files of the libxml2 installation, e.g. /usr/local/include])],
|
||||||
|
[LIBXML2_INCLUDE=$with_libxml2
|
||||||
|
AC_MSG_CHECKING([whether libxml2 can be found at the specified location])
|
||||||
|
if !(test -r ${LIBXML2_INCLUDE}/libxml/xmlreader.h) && !(test -r ${LIBXML2_INCLUDE}/libxml/parser.h) && !(test -r ${LIBXML2_INCLUDE}/libxml/xmlschemas.h); then
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
AC_MSG_ERROR([libxml2 cannot be found at the specified path!])
|
||||||
|
fi
|
||||||
|
AC_MSG_RESULT([${LIBXML2_INCLUDE}])],
|
||||||
|
[PKG_CHECK_MODULES(LIBXML2, libxml2 >= 2.6.26, [LIBXML2_FOUND=1],
|
||||||
|
[AC_MSG_CHECKING([whether libxml2 is installed in a standard location])
|
||||||
|
if test -r /usr/local/include/libxml2/libxml/xmlreader.h || test -r /usr/local/include/libxml2/libxml/parser.h || \
|
||||||
|
test -r /usr/local/include/libxml2/libxml/xmlschemas.h; then
|
||||||
|
LIBXML2_INCLUDE="/usr/local/include/libxml2"
|
||||||
|
AC_MSG_RESULT([${LIBXML2_INCLUDE}])
|
||||||
|
elif test -r /usr/include/libxml2/libxml/xmlreader.h || test -r /usr/include/libxml2/libxml/parser.h || \
|
||||||
|
test -r /usr/include/libxml2/libxml/xmlschemas.h; then
|
||||||
|
LIBXML2_INCLUDE="/usr/include/libxml2"
|
||||||
|
AC_MSG_RESULT([${LIBXML2_INCLUDE}])
|
||||||
|
elif test -r /sw/include/libxml2/libxml/xmlreader.h || test -r /sw/include/libxml2/libxml/parser.h || \
|
||||||
|
test -r /sw/include/libxml2/libxml/xmlschemas.h; then
|
||||||
|
LIBXML2_INCLUDE="/sw/include/libxml2"
|
||||||
|
AC_MSG_RESULT([${LIBXML2_INCLUDE}])
|
||||||
|
elif test -r /opt/local/include/libxml2/libxml/xmlreader.h || test -r /opt/local/include/libxml2/libxml/parser.h || \
|
||||||
|
test -r /opt/local/include/libxml2/libxml/xmlschemas.h; then
|
||||||
|
LIBXML2_INCLUDE="/opt/local/include/libxml2"
|
||||||
|
AC_MSG_RESULT([${LIBXML2_INCLUDE}])
|
||||||
|
else
|
||||||
|
AC_MSG_RESULT([no])
|
||||||
|
AC_MSG_ERROR(
|
||||||
|
[libxml2 not found. Please call configure with the --with-libxml2 option.
|
||||||
|
This tells configure where to find the libxml2 headers,
|
||||||
|
e.g. --with-libxml2=/usr/local/include or --with-libxml2=/usr/include/libxml2]
|
||||||
|
)
|
||||||
|
fi
|
||||||
|
]
|
||||||
|
)
|
||||||
|
]
|
||||||
|
)
|
||||||
|
AC_SUBST(LIBXML2_INCLUDE)
|
||||||
|
if test "${LIBXML2_FOUND}" != "1"; then
|
||||||
|
LIBXML2_LIBS=""
|
||||||
|
LIBXML2_CFLAGS="-I${LIBXML2_INCLUDE}"
|
||||||
|
fi
|
||||||
|
AC_SUBST(LIBXML2_LIBS)
|
||||||
|
AC_SUBST(LIBXML2_CFLAGS)
|
||||||
|
|
||||||
dnl -----------------------------------------------
|
dnl -----------------------------------------------
|
||||||
dnl Check for ROOT
|
dnl Check for ROOT
|
||||||
dnl -----------------------------------------------
|
dnl -----------------------------------------------
|
||||||
@ -1119,6 +1170,11 @@ if test "${BOOST_FOUND}" = "1"; then
|
|||||||
else
|
else
|
||||||
echo " BOOST header files found in ${BOOST_INCLUDE}"
|
echo " BOOST header files found in ${BOOST_INCLUDE}"
|
||||||
fi
|
fi
|
||||||
|
if test "${LIBXML2_FOUND}" = "1"; then
|
||||||
|
echo " LIBXML2 found in $(pkg-config --variable=prefix libxml2)"
|
||||||
|
else
|
||||||
|
echo " LIBXML2 found in ${LIBXML2_INCLUDE}"
|
||||||
|
fi
|
||||||
echo " ROOT found in ${ROOTLIBDIR%/lib}"
|
echo " ROOT found in ${ROOTLIBDIR%/lib}"
|
||||||
echo ""
|
echo ""
|
||||||
if test "${PNEXUS_ENABLED}" -eq 1; then
|
if test "${PNEXUS_ENABLED}" -eq 1; then
|
||||||
|
@ -34,7 +34,7 @@ bin_PROGRAMS = musrfit musrview musrt0 msr2msr msr2data any2many
|
|||||||
if PNEXUS_ENABLED
|
if PNEXUS_ENABLED
|
||||||
bin_PROGRAMS += nexus_dump
|
bin_PROGRAMS += nexus_dump
|
||||||
endif
|
endif
|
||||||
bin_PROGRAMS += read_musrRoot_runHeader write_musrRoot_runHeader
|
bin_PROGRAMS += read_musrRoot_runHeader write_musrRoot_runHeader musrRootValidation
|
||||||
|
|
||||||
musrfit_SOURCES = musrfit.cpp
|
musrfit_SOURCES = musrfit.cpp
|
||||||
musrview_SOURCES = musrview.cpp
|
musrview_SOURCES = musrview.cpp
|
||||||
@ -47,6 +47,7 @@ nexus_dump_SOURCES = nexus_dump.cpp
|
|||||||
endif
|
endif
|
||||||
read_musrRoot_runHeader_SOURCES = read_musrRoot_runHeader.cpp
|
read_musrRoot_runHeader_SOURCES = read_musrRoot_runHeader.cpp
|
||||||
write_musrRoot_runHeader_SOURCES = write_musrRoot_runHeader.cpp
|
write_musrRoot_runHeader_SOURCES = write_musrRoot_runHeader.cpp
|
||||||
|
musrRootValidation_SOURCES = musrRootValidation.cpp
|
||||||
|
|
||||||
xmldir = $(bindir)
|
xmldir = $(bindir)
|
||||||
xml_DATA = musrfit_startup.xml
|
xml_DATA = musrfit_startup.xml
|
||||||
@ -55,13 +56,14 @@ LIBADD = $(PMUSR_LIBS) $(MUSR_ROOT_LIBS) $(LEM_LIBS) $(PSIBIN_LIBS) $(MUD_LIBS)
|
|||||||
|
|
||||||
AM_CXXFLAGS = $(LOCAL_BIN_CXXFLAGS)
|
AM_CXXFLAGS = $(LOCAL_BIN_CXXFLAGS)
|
||||||
AM_LDFLAGS = $(LOCAL_BIN_LDFLAGS)
|
AM_LDFLAGS = $(LOCAL_BIN_LDFLAGS)
|
||||||
INCLUDES = $(MUSR_ROOT_CFLAGS) $(PMUSR_CFLAGS) $(FFTW3_CFLAGS) $(GSL_CFLAGS) $(BOOST_CFLAGS) $(ROOT_CFLAGS)
|
INCLUDES = $(MUSR_ROOT_CFLAGS) $(PMUSR_CFLAGS) $(FFTW3_CFLAGS) $(GSL_CFLAGS) $(BOOST_CFLAGS) $(ROOT_CFLAGS) \
|
||||||
|
$(LIBXML2_CFLAGS)
|
||||||
if PNEXUS_ENABLED
|
if PNEXUS_ENABLED
|
||||||
INCLUDES += $(HDF5_CFLAGS) $(NEXUS_CFLAGS) $(PNEXUS_CXXFLAGS)
|
INCLUDES += $(HDF5_CFLAGS) $(NEXUS_CFLAGS) $(PNEXUS_CXXFLAGS)
|
||||||
endif
|
endif
|
||||||
|
|
||||||
LIBS = $(PMUSR_LIBS) $(USERFCN_LIBS) $(MUSR_ROOT_LIBS) $(LEM_LIBS) $(PSIBIN_LIBS) $(MUD_LIBS) $(PNEXUS_LIBS) \
|
LIBS = $(PMUSR_LIBS) $(USERFCN_LIBS) $(MUSR_ROOT_LIBS) $(LEM_LIBS) $(PSIBIN_LIBS) $(MUD_LIBS) $(PNEXUS_LIBS) \
|
||||||
$(FFTW3_LIBS) $(GSL_LIBS) $(ROOT_LIBS)
|
$(FFTW3_LIBS) $(GSL_LIBS) $(ROOT_LIBS) $(LIBXML2_LIBS)
|
||||||
|
|
||||||
install-xmlDATA: $(xml_DATA)
|
install-xmlDATA: $(xml_DATA)
|
||||||
test -z "$(xmldir)" || $(mkdir_p) "$(DESTDIR)$(xmldir)"
|
test -z "$(xmldir)" || $(mkdir_p) "$(DESTDIR)$(xmldir)"
|
||||||
|
318
src/external/MusrRoot/root2xml.C
vendored
318
src/external/MusrRoot/root2xml.C
vendored
@ -1,318 +0,0 @@
|
|||||||
// quick and dirty ROOT -> XML converter for MusrRoot
|
|
||||||
// needs to be rewritten as proper program.
|
|
||||||
//
|
|
||||||
// Andreas Suter
|
|
||||||
//
|
|
||||||
// $Id: root2xml.C 5092 2012-03-13 07:47:00Z nemu $
|
|
||||||
|
|
||||||
vector<string> xml_data;
|
|
||||||
|
|
||||||
enum EFolderTag {eUnkown, eDecayAnaModule, eSlowControlAnaModule};
|
|
||||||
enum ERunHeaderTag {eUnkown, eRunInfo, eSampleEnvironmentInfo, eMagneticFieldEnvironmentInfo, eBeamlineInfo, eScalerInfo};
|
|
||||||
EFolderTag folderTag = eUnkown;
|
|
||||||
ERunHeaderTag runHeaderTag = eUnkown;
|
|
||||||
|
|
||||||
void root2xml(const char *filename, const char *xmlFilename)
|
|
||||||
{
|
|
||||||
TFile f(filename);
|
|
||||||
|
|
||||||
if (f.IsZombie()) {
|
|
||||||
cout << endl << "**ERROR** couldn't open file " << filename << endl;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
xml_data.clear();
|
|
||||||
|
|
||||||
xml_data.push_back("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
|
||||||
xml_data.push_back("<MusrRoot xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"file:MusrRoot.xsd\">");
|
|
||||||
|
|
||||||
TIter next = f.GetListOfKeys();
|
|
||||||
TKey *key;
|
|
||||||
TFolder *folder;
|
|
||||||
TString str, tag;
|
|
||||||
|
|
||||||
UInt_t offset = 2;
|
|
||||||
|
|
||||||
while (key = (TKey*) next()) {
|
|
||||||
cout << endl << "name: " << key->GetName() << ", class name: " << key->GetClassName();
|
|
||||||
str = key->GetClassName();
|
|
||||||
if (str == "TFolder") {
|
|
||||||
folder = (TFolder*)key->ReadObj();
|
|
||||||
checkClass(folder, str, offset);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cout << endl;
|
|
||||||
|
|
||||||
f.Close();
|
|
||||||
|
|
||||||
xml_data.push_back("</MusrRoot>");
|
|
||||||
|
|
||||||
// the sort_histo_folders is needed since XML-Schema is not flexible enough to handle
|
|
||||||
// histos -|
|
|
||||||
// |- DecayAnaModule
|
|
||||||
// ... (any other analyzer module sub-folder
|
|
||||||
// |- SCAnaModule
|
|
||||||
// Hence SCAnaModule has artificially moved up, just to follow DecayAnaModule
|
|
||||||
sort_histo_folders();
|
|
||||||
|
|
||||||
ofstream fout(xmlFilename);
|
|
||||||
|
|
||||||
for (UInt_t i=0; i<xml_data.size(); i++)
|
|
||||||
fout << xml_data[i] << endl;
|
|
||||||
fout.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
void sort_histo_folders()
|
|
||||||
{
|
|
||||||
vector<string> temp_xml_data;
|
|
||||||
|
|
||||||
// first make a copy of the original xml_data
|
|
||||||
for (unsigned int i=0; i<xml_data.size(); i++)
|
|
||||||
temp_xml_data.push_back(xml_data[i]);
|
|
||||||
|
|
||||||
// remove SCAnaModule from temp_xml_data
|
|
||||||
unsigned int start = 0, end = 0;
|
|
||||||
for (unsigned int i=0; i<temp_xml_data.size(); i++) {
|
|
||||||
if (temp_xml_data[i].find("<SCAnaModule>") != string::npos)
|
|
||||||
start = i;
|
|
||||||
if (temp_xml_data[i].find("</SCAnaModule>") != string::npos)
|
|
||||||
end = i+1;
|
|
||||||
}
|
|
||||||
if ((start > 0) && (end > 0))
|
|
||||||
temp_xml_data.erase(temp_xml_data.begin()+start, temp_xml_data.begin()+end);
|
|
||||||
else // no SCAnaModule present, hence nothing to be done
|
|
||||||
return;
|
|
||||||
|
|
||||||
// insert SCAnaModule just after DecayAnaModule
|
|
||||||
// 1st find end of DecayAnaModule
|
|
||||||
unsigned int pos = 0;
|
|
||||||
for (unsigned int i=0; i<temp_xml_data.size(); i++) {
|
|
||||||
if (temp_xml_data[i].find("</DecayAnaModule>") != string::npos) {
|
|
||||||
pos = i+1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pos == 0) // something is wrong, hence to not do anything
|
|
||||||
return;
|
|
||||||
temp_xml_data.insert(temp_xml_data.begin()+pos, xml_data.begin()+start, xml_data.begin()+end);
|
|
||||||
|
|
||||||
// copy temp_xml_data back into xml_data
|
|
||||||
xml_data.clear();
|
|
||||||
for (unsigned int i=0; i<temp_xml_data.size(); i++)
|
|
||||||
xml_data.push_back(temp_xml_data[i]);
|
|
||||||
|
|
||||||
// clean up
|
|
||||||
temp_xml_data.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void dumpFolder(TFolder *folder, UInt_t offset)
|
|
||||||
{
|
|
||||||
TString offsetStr="";
|
|
||||||
for (UInt_t i=0; i<offset; i++)
|
|
||||||
offsetStr += " ";
|
|
||||||
|
|
||||||
TIter next = folder->GetListOfFolders();
|
|
||||||
TObject *obj;
|
|
||||||
TString str;
|
|
||||||
while (obj = (TObject*) next()) {
|
|
||||||
cout << endl << offsetStr << "name: " << obj->GetName() << ", class name: " << obj->ClassName();
|
|
||||||
str = obj->ClassName();
|
|
||||||
checkClass(obj, str, offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void dumpObjArray(TObjArray *obj, UInt_t offset)
|
|
||||||
{
|
|
||||||
TString offsetStr="";
|
|
||||||
for (UInt_t i=0; i<offset; i++)
|
|
||||||
offsetStr += " ";
|
|
||||||
|
|
||||||
TObjString *tstr;
|
|
||||||
TString str, xmlStr, type, label, xmlLabel;
|
|
||||||
|
|
||||||
// check if the obj name is anything like DetectorXXX, where XXX is a number
|
|
||||||
xmlLabel = TString(obj->GetName());
|
|
||||||
if (xmlLabel.BeginsWith("Detector")) {
|
|
||||||
xmlLabel.Remove(0, 8); // remove 'Detector'
|
|
||||||
if (xmlLabel.IsDigit())
|
|
||||||
xmlLabel = "Detector";
|
|
||||||
else
|
|
||||||
xmlLabel = TString(obj->GetName());
|
|
||||||
}
|
|
||||||
|
|
||||||
cout << endl << offsetStr << obj->GetName() << " (# " << obj->GetEntries() << ")";
|
|
||||||
|
|
||||||
xmlStr = offsetStr + "<" + xmlLabel + ">";
|
|
||||||
xml_data.push_back(xmlStr.Data());
|
|
||||||
|
|
||||||
for (UInt_t i=0; i<obj->GetEntries(); i++) {
|
|
||||||
// check if entry is a TObjArray
|
|
||||||
type = obj->At(i)->ClassName();
|
|
||||||
if (type == "TObjArray") {
|
|
||||||
dumpObjArray((TObjArray*)(obj->At(i)), offset+2);
|
|
||||||
} else { // not a TObjArray
|
|
||||||
tstr = (TObjString*) obj->At(i);
|
|
||||||
str = tstr->GetString();
|
|
||||||
str.Remove(TString::kTrailing, '\n');
|
|
||||||
|
|
||||||
getType(str, type);
|
|
||||||
getLabel(str, label);
|
|
||||||
|
|
||||||
cout << endl << offsetStr << i << ": " << str;
|
|
||||||
|
|
||||||
xmlStr = offsetStr + " " + "<" + label + ">" + type + "</" + label + ">" ;
|
|
||||||
xml_data.push_back(xmlStr.Data());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
xmlStr = offsetStr + "</" + xmlLabel + ">";
|
|
||||||
xml_data.push_back(xmlStr.Data());
|
|
||||||
}
|
|
||||||
|
|
||||||
void dumpEntry(TObject *obj, UInt_t offset)
|
|
||||||
{
|
|
||||||
TString offsetStr="";
|
|
||||||
for (UInt_t i=0; i<offset; i++)
|
|
||||||
offsetStr += " ";
|
|
||||||
|
|
||||||
TString nameTag(""), typeTag("");
|
|
||||||
switch (folderTag) {
|
|
||||||
case eDecayAnaModule:
|
|
||||||
nameTag = "HistoName";
|
|
||||||
typeTag = "HistoType";
|
|
||||||
break;
|
|
||||||
case eSlowControlAnaModule:
|
|
||||||
nameTag = "SlowControlName";
|
|
||||||
typeTag = "SlowControlType";
|
|
||||||
break;
|
|
||||||
case eUnkown:
|
|
||||||
default:
|
|
||||||
nameTag = "Name";
|
|
||||||
typeTag = "Type";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
TString str;
|
|
||||||
|
|
||||||
str = offsetStr + "<" + nameTag + ">";
|
|
||||||
str += obj->GetName();
|
|
||||||
str += "</" + nameTag + ">";
|
|
||||||
xml_data.push_back(str.Data());
|
|
||||||
|
|
||||||
str = offsetStr + "<" + typeTag + ">";
|
|
||||||
str += obj->ClassName();
|
|
||||||
str += "</" + typeTag + ">";
|
|
||||||
xml_data.push_back(str.Data());
|
|
||||||
}
|
|
||||||
|
|
||||||
void checkClass(TObject *obj, TString str, UInt_t offset)
|
|
||||||
{
|
|
||||||
TString offsetStr="";
|
|
||||||
for (UInt_t i=0; i<offset; i++)
|
|
||||||
offsetStr += " ";
|
|
||||||
|
|
||||||
if (str == "TFolder") {
|
|
||||||
TString xmlTagName(TString(obj->GetName()));
|
|
||||||
|
|
||||||
// set folder tag
|
|
||||||
if (!xmlTagName.CompareTo("DecayAnaModule"))
|
|
||||||
folderTag = eDecayAnaModule;
|
|
||||||
else if (!xmlTagName.CompareTo("SCAnaModule"))
|
|
||||||
folderTag = eSlowControlAnaModule;
|
|
||||||
else if (!xmlTagName.CompareTo("SCAnaModule"))
|
|
||||||
folderTag = eSlowControlAnaModule;
|
|
||||||
else
|
|
||||||
folderTag = eUnkown;
|
|
||||||
|
|
||||||
offset += 2;
|
|
||||||
str = offsetStr + "<" + xmlTagName + ">";
|
|
||||||
xml_data.push_back(str.Data());
|
|
||||||
|
|
||||||
dumpFolder((TFolder*)obj, offset);
|
|
||||||
|
|
||||||
str = offsetStr + "</" + xmlTagName + ">";
|
|
||||||
xml_data.push_back(str.Data());
|
|
||||||
} else if (str == "TObjArray") {
|
|
||||||
offset += 2;
|
|
||||||
dumpObjArray((TObjArray*)obj, offset);
|
|
||||||
} else {
|
|
||||||
// filter out the proper entry tag
|
|
||||||
TString entryTag("");
|
|
||||||
switch (folderTag) {
|
|
||||||
case eDecayAnaModule:
|
|
||||||
entryTag = TString("DecayHistoEntry");
|
|
||||||
break;
|
|
||||||
case eSlowControlAnaModule:
|
|
||||||
entryTag = TString("SlowControlHistoEntry");
|
|
||||||
break;
|
|
||||||
case eUnkown:
|
|
||||||
default:
|
|
||||||
entryTag = TString("Entry");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
offset += 2;
|
|
||||||
str = offsetStr + "<" + entryTag + ">";
|
|
||||||
xml_data.push_back(str.Data());
|
|
||||||
dumpEntry((TObjArray*)obj, offset);
|
|
||||||
str = offsetStr + "</" + entryTag + ">";
|
|
||||||
xml_data.push_back(str.Data());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void getType(TString entry, TString &type)
|
|
||||||
{
|
|
||||||
if (entry.Contains("-@0")) {
|
|
||||||
type = "TString";
|
|
||||||
} else if (entry.Contains("-@1")) {
|
|
||||||
type = "Int_t";
|
|
||||||
} else if (entry.Contains("-@2")) {
|
|
||||||
type = "Double_t";
|
|
||||||
} else if (entry.Contains("-@3")) {
|
|
||||||
type = "TMusrRunPhysicalQuantity";
|
|
||||||
} else if (entry.Contains("-@4")) {
|
|
||||||
type = "TStringVector";
|
|
||||||
} else if (entry.Contains("-@5")) {
|
|
||||||
type = "TIntVector";
|
|
||||||
} else if (entry.Contains("-@6")) {
|
|
||||||
type = "TDoubleVector";
|
|
||||||
} else {
|
|
||||||
type = "TString";
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void getLabel(TString entry, TString &label)
|
|
||||||
{
|
|
||||||
label="no_idea";
|
|
||||||
|
|
||||||
Ssiz_t start = entry.First('-');
|
|
||||||
Ssiz_t end = entry.First(':');
|
|
||||||
|
|
||||||
if ((start == -1) || (end == -1))
|
|
||||||
return;
|
|
||||||
|
|
||||||
if (end - start < 2)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// check that '-@' is present in the string, otherwise it is NOT a known label
|
|
||||||
Ssiz_t pos = entry.First('@');
|
|
||||||
if (pos < 1)
|
|
||||||
return;
|
|
||||||
if (entry(pos-1) != '-')
|
|
||||||
return;
|
|
||||||
|
|
||||||
// cut out value
|
|
||||||
label = entry;
|
|
||||||
label.Remove(0, start+2);
|
|
||||||
label.Remove(end-start-2, label.Length());
|
|
||||||
|
|
||||||
label.ReplaceAll(' ', '_'); // replace spaces through underscores
|
|
||||||
label.ReplaceAll('(', '_'); // replace '(' through underscores
|
|
||||||
label.ReplaceAll(')', '_'); // replace ')' through underscores
|
|
||||||
label.ReplaceAll('[', '_'); // replace '[' through underscores
|
|
||||||
label.ReplaceAll(']', '_'); // replace ']' through underscores
|
|
||||||
label.ReplaceAll('{', '_'); // replace '[' through underscores
|
|
||||||
label.ReplaceAll('}', '_'); // replace ']' through underscores
|
|
||||||
}
|
|
626
src/musrRootValidation.cpp
Normal file
626
src/musrRootValidation.cpp
Normal file
@ -0,0 +1,626 @@
|
|||||||
|
/***************************************************************************
|
||||||
|
|
||||||
|
musrRootValidation.cpp
|
||||||
|
|
||||||
|
Author: Andreas Suter
|
||||||
|
e-mail: andreas.suter@psi.ch
|
||||||
|
|
||||||
|
$Id$
|
||||||
|
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* Copyright (C) 2007-2012 by Andreas Suter *
|
||||||
|
* andreas.suter@psi.ch *
|
||||||
|
* *
|
||||||
|
* This program is free software; you can redistribute it and/or modify *
|
||||||
|
* it under the terms of the GNU General Public License as published by *
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or *
|
||||||
|
* (at your option) any later version. *
|
||||||
|
* *
|
||||||
|
* This program is distributed in the hope that it will be useful, *
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||||
|
* GNU General Public License for more details. *
|
||||||
|
* *
|
||||||
|
* You should have received a copy of the GNU General Public License *
|
||||||
|
* along with this program; if not, write to the *
|
||||||
|
* Free Software Foundation, Inc., *
|
||||||
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||||
|
***************************************************************************/
|
||||||
|
|
||||||
|
#include <iostream>
|
||||||
|
#include <fstream>
|
||||||
|
#include <vector>
|
||||||
|
#include <string>
|
||||||
|
using namespace std;
|
||||||
|
|
||||||
|
#include "TString.h"
|
||||||
|
#include "TFile.h"
|
||||||
|
#include "TFolder.h"
|
||||||
|
#include "TKey.h"
|
||||||
|
#include "TObjArray.h"
|
||||||
|
#include "TObjString.h"
|
||||||
|
#include "TSystemFile.h"
|
||||||
|
|
||||||
|
#include <libxml/xmlreader.h>
|
||||||
|
#include <libxml/parser.h>
|
||||||
|
#include <libxml/xmlschemas.h>
|
||||||
|
|
||||||
|
#include "PMusr.h"
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* <p>class which converts the structure of a ROOT file into a XML file.
|
||||||
|
*/
|
||||||
|
class PMusrRoot2Xml
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
PMusrRoot2Xml(const char *fileName, bool quiet, bool keep);
|
||||||
|
virtual ~PMusrRoot2Xml();
|
||||||
|
|
||||||
|
virtual Bool_t IsValid() { return fValid; }
|
||||||
|
virtual TString GetXmlDumpFileName() { return fXmlDumpFileName; }
|
||||||
|
virtual UInt_t GetNoOfDecayHistos() { return fNoOfDecayHistos; }
|
||||||
|
virtual UInt_t GetNoOfExpectedHistos() { return fNoOfRedGreenOffsets*fNoOfHistos; }
|
||||||
|
virtual UInt_t GetNoOfHistos() { return fNoOfHistos; }
|
||||||
|
virtual UInt_t GetNoOfRedGreenOffsets() { return fNoOfRedGreenOffsets; }
|
||||||
|
virtual UInt_t GetNoOfDetectors() { return fNoOfDetectors; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
enum EFolderTag {eUnkown, eDecayAnaModule, eSlowControlAnaModule};
|
||||||
|
|
||||||
|
vector<string> fXmlData; ///< keeps the XML structure dump of the ROOT file
|
||||||
|
|
||||||
|
Bool_t fQuiet; ///< true = suppress output while converting
|
||||||
|
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
|
||||||
|
TString fXmlDumpFileName; ///< file name of the XML dump file
|
||||||
|
EFolderTag fFolderTag; ///< switch indicating which kind of TFolder object is found
|
||||||
|
|
||||||
|
UInt_t fNoOfDecayHistos; ///< number of decay histos in the DecayAnaModule
|
||||||
|
UInt_t fNoOfHistos; ///< number of histos from run header
|
||||||
|
UInt_t fNoOfRedGreenOffsets; ///< number of RedGreen offsets
|
||||||
|
UInt_t fNoOfDetectors; ///< number of detector entries in the header
|
||||||
|
|
||||||
|
virtual void SortHistoFolders();
|
||||||
|
virtual void DumpFolder(TFolder *folder, UInt_t offset);
|
||||||
|
virtual void DumpObjArray(TObjArray *obj, UInt_t offset);
|
||||||
|
virtual void DumpEntry(TObject *obj, UInt_t offset);
|
||||||
|
virtual void CheckClass(TObject *obj, TString str, UInt_t offset);
|
||||||
|
virtual void GetType(TString entry, TString &type);
|
||||||
|
virtual void GetLabel(TString entry, TString &label);
|
||||||
|
};
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* <p>Constructor. Reads the ROOT file and converts its structure to an XML dump file.
|
||||||
|
*/
|
||||||
|
PMusrRoot2Xml::PMusrRoot2Xml(const char *fileName, bool quiet, bool keep) : fQuiet(quiet), fKeep(keep), fFileName(fileName)
|
||||||
|
{
|
||||||
|
fXmlDumpFileName = "__MusrRootXmlDump.xml";
|
||||||
|
fFolderTag = eUnkown;
|
||||||
|
fValid = false;
|
||||||
|
fXmlData.clear();
|
||||||
|
fNoOfDecayHistos = 0;
|
||||||
|
fNoOfHistos = 0;
|
||||||
|
fNoOfRedGreenOffsets = 0;
|
||||||
|
fNoOfDetectors = 0;
|
||||||
|
|
||||||
|
// read assumed MusrRoot file
|
||||||
|
TFile f(fFileName.Data());
|
||||||
|
|
||||||
|
if (f.IsZombie()) {
|
||||||
|
cerr << endl << "**ERROR** couldn't open file " << fFileName << endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fXmlData.push_back("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
|
||||||
|
fXmlData.push_back("<MusrRoot xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"file:MusrRoot.xsd\">");
|
||||||
|
|
||||||
|
TIter next = f.GetListOfKeys();
|
||||||
|
TKey *key;
|
||||||
|
TFolder *folder;
|
||||||
|
TString str, tag;
|
||||||
|
|
||||||
|
UInt_t offset = 2;
|
||||||
|
|
||||||
|
while ((key = (TKey*) next()) != 0) {
|
||||||
|
if (!fQuiet) cout << endl << "name: " << key->GetName() << ", class name: " << key->GetClassName();
|
||||||
|
str = key->GetClassName();
|
||||||
|
if (str == "TFolder") {
|
||||||
|
folder = (TFolder*)key->ReadObj();
|
||||||
|
CheckClass(folder, str, offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!fQuiet) cout << endl;
|
||||||
|
|
||||||
|
f.Close();
|
||||||
|
|
||||||
|
fXmlData.push_back("</MusrRoot>");
|
||||||
|
|
||||||
|
// the sort_histo_folders is needed since XML-Schema is not flexible enough to handle
|
||||||
|
// histos -|
|
||||||
|
// |- DecayAnaModule
|
||||||
|
// ... (any other analyzer module sub-folder
|
||||||
|
// |- SCAnaModule
|
||||||
|
// Hence SCAnaModule has artificially moved up, just to follow DecayAnaModule
|
||||||
|
SortHistoFolders();
|
||||||
|
|
||||||
|
ofstream fout(fXmlDumpFileName.Data());
|
||||||
|
|
||||||
|
for (UInt_t i=0; i<fXmlData.size(); i++)
|
||||||
|
fout << fXmlData[i] << endl;
|
||||||
|
fout.close();
|
||||||
|
|
||||||
|
fValid = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* <p>Destructor.
|
||||||
|
*/
|
||||||
|
PMusrRoot2Xml::~PMusrRoot2Xml()
|
||||||
|
{
|
||||||
|
if (!fKeep) {
|
||||||
|
TSystemFile sf(fXmlDumpFileName.Data(), "./");
|
||||||
|
sf.Delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* <p>Sorts the folders of the 'histos' TFolder in order to enforce the order
|
||||||
|
* according to:
|
||||||
|
* -# DecayAnaModule
|
||||||
|
* -# SCAnaModule
|
||||||
|
* -# all the rest
|
||||||
|
* <p>This is needed to the limited abilities of XML-Schema validation.
|
||||||
|
*/
|
||||||
|
void PMusrRoot2Xml::SortHistoFolders()
|
||||||
|
{
|
||||||
|
vector<string> temp_xml_data;
|
||||||
|
|
||||||
|
// first make a copy of the original fXmlData
|
||||||
|
for (unsigned int i=0; i<fXmlData.size(); i++)
|
||||||
|
temp_xml_data.push_back(fXmlData[i]);
|
||||||
|
|
||||||
|
// remove SCAnaModule from temp_xml_data
|
||||||
|
unsigned int start = 0, end = 0;
|
||||||
|
for (unsigned int i=0; i<temp_xml_data.size(); i++) {
|
||||||
|
if (temp_xml_data[i].find("<SCAnaModule>") != string::npos)
|
||||||
|
start = i;
|
||||||
|
if (temp_xml_data[i].find("</SCAnaModule>") != string::npos)
|
||||||
|
end = i+1;
|
||||||
|
}
|
||||||
|
if ((start > 0) && (end > 0))
|
||||||
|
temp_xml_data.erase(temp_xml_data.begin()+start, temp_xml_data.begin()+end);
|
||||||
|
else // no SCAnaModule present, hence nothing to be done
|
||||||
|
return;
|
||||||
|
|
||||||
|
// insert SCAnaModule just after DecayAnaModule
|
||||||
|
// 1st find end of DecayAnaModule
|
||||||
|
unsigned int pos = 0;
|
||||||
|
for (unsigned int i=0; i<temp_xml_data.size(); i++) {
|
||||||
|
if (temp_xml_data[i].find("</DecayAnaModule>") != string::npos) {
|
||||||
|
pos = i+1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pos == 0) // something is wrong, hence to not do anything
|
||||||
|
return;
|
||||||
|
temp_xml_data.insert(temp_xml_data.begin()+pos, fXmlData.begin()+start, fXmlData.begin()+end);
|
||||||
|
|
||||||
|
// copy temp_xml_data back into fXmlData
|
||||||
|
fXmlData.clear();
|
||||||
|
for (unsigned int i=0; i<temp_xml_data.size(); i++)
|
||||||
|
fXmlData.push_back(temp_xml_data[i]);
|
||||||
|
|
||||||
|
// clean up
|
||||||
|
temp_xml_data.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* <p>Dump folder structure.
|
||||||
|
*
|
||||||
|
* \param folder TFolder object found in the ROOT file
|
||||||
|
* \param offset needed to indent dump info
|
||||||
|
*/
|
||||||
|
void PMusrRoot2Xml::DumpFolder(TFolder *folder, UInt_t offset)
|
||||||
|
{
|
||||||
|
TString offsetStr="";
|
||||||
|
for (UInt_t i=0; i<offset; i++)
|
||||||
|
offsetStr += " ";
|
||||||
|
|
||||||
|
TIter next = folder->GetListOfFolders();
|
||||||
|
TObject *obj;
|
||||||
|
TString str;
|
||||||
|
while ((obj = (TObject*) next()) != 0) {
|
||||||
|
if (!fQuiet) cout << endl << offsetStr << "name: " << obj->GetName() << ", class name: " << obj->ClassName();
|
||||||
|
str = obj->ClassName();
|
||||||
|
CheckClass(obj, str, offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* <p>Dump object array content structure.
|
||||||
|
*
|
||||||
|
* \param obj object array found in the ROOT file
|
||||||
|
* \param offset needed to indent dump info
|
||||||
|
*/
|
||||||
|
void PMusrRoot2Xml::DumpObjArray(TObjArray *obj, UInt_t offset)
|
||||||
|
{
|
||||||
|
TString offsetStr="";
|
||||||
|
for (UInt_t i=0; i<offset; i++)
|
||||||
|
offsetStr += " ";
|
||||||
|
|
||||||
|
TObjString *tstr;
|
||||||
|
TString str, xmlStr, type, label, xmlLabel;
|
||||||
|
|
||||||
|
// check if the obj name is anything like DetectorXXX, where XXX is a number
|
||||||
|
xmlLabel = TString(obj->GetName());
|
||||||
|
if (xmlLabel.BeginsWith("Detector")) {
|
||||||
|
xmlLabel.Remove(0, 8); // remove 'Detector'
|
||||||
|
if (xmlLabel.IsDigit())
|
||||||
|
xmlLabel = "Detector";
|
||||||
|
else
|
||||||
|
xmlLabel = TString(obj->GetName());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fQuiet) cout << endl << offsetStr << obj->GetName() << " (# " << obj->GetEntries() << ")";
|
||||||
|
if (!strcmp(obj->GetName(), "DetectorInfo"))
|
||||||
|
fNoOfDetectors = obj->GetEntries();
|
||||||
|
|
||||||
|
xmlStr = offsetStr + "<" + xmlLabel + ">";
|
||||||
|
fXmlData.push_back(xmlStr.Data());
|
||||||
|
|
||||||
|
for (UInt_t i=0; i<(UInt_t)obj->GetEntries(); i++) {
|
||||||
|
// check if entry is a TObjArray
|
||||||
|
type = obj->At(i)->ClassName();
|
||||||
|
if (type == "TObjArray") {
|
||||||
|
DumpObjArray((TObjArray*)(obj->At(i)), offset+2);
|
||||||
|
} else { // not a TObjArray
|
||||||
|
tstr = (TObjString*) obj->At(i);
|
||||||
|
str = tstr->GetString();
|
||||||
|
str.Remove(TString::kTrailing, '\n');
|
||||||
|
|
||||||
|
GetType(str, type);
|
||||||
|
GetLabel(str, label);
|
||||||
|
|
||||||
|
if (!fQuiet) cout << endl << offsetStr << i << ": " << str;
|
||||||
|
|
||||||
|
// filter out the number of histograms according to the RunInfo
|
||||||
|
if (str.Contains("- No of Histos: ")) {
|
||||||
|
TString histoStr = str;
|
||||||
|
Ssiz_t pos = histoStr.Last(':');
|
||||||
|
histoStr.Remove(0, pos+1);
|
||||||
|
pos = histoStr.Last('-');
|
||||||
|
histoStr.Remove(pos);
|
||||||
|
fNoOfHistos = histoStr.Atoi();
|
||||||
|
}
|
||||||
|
|
||||||
|
// filter out the number of Red/Green offsets
|
||||||
|
if (str.Contains("- RedGreen Offsets: ")) {
|
||||||
|
TString redGreenStr = str;
|
||||||
|
Ssiz_t pos = redGreenStr.Last(':');
|
||||||
|
redGreenStr.Remove(0, pos+1);
|
||||||
|
pos = redGreenStr.Last('-');
|
||||||
|
redGreenStr.Remove(pos);
|
||||||
|
TObjArray *tokens = redGreenStr.Tokenize(";");
|
||||||
|
if (tokens)
|
||||||
|
fNoOfRedGreenOffsets = tokens->GetEntries();
|
||||||
|
if (tokens) delete tokens;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlStr = offsetStr + " " + "<" + label + ">" + type + "</" + label + ">" ;
|
||||||
|
fXmlData.push_back(xmlStr.Data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlStr = offsetStr + "</" + xmlLabel + ">";
|
||||||
|
fXmlData.push_back(xmlStr.Data());
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* <p>Dump content.
|
||||||
|
*
|
||||||
|
* \param obj object found in the ROOT file to be dumped
|
||||||
|
* \param offset needed to indent dump info
|
||||||
|
*/
|
||||||
|
void PMusrRoot2Xml::DumpEntry(TObject *obj, UInt_t offset)
|
||||||
|
{
|
||||||
|
TString offsetStr="";
|
||||||
|
for (UInt_t i=0; i<offset; i++)
|
||||||
|
offsetStr += " ";
|
||||||
|
|
||||||
|
TString nameTag(""), typeTag("");
|
||||||
|
switch (fFolderTag) {
|
||||||
|
case eDecayAnaModule:
|
||||||
|
nameTag = "HistoName";
|
||||||
|
typeTag = "HistoType";
|
||||||
|
break;
|
||||||
|
case eSlowControlAnaModule:
|
||||||
|
nameTag = "SlowControlName";
|
||||||
|
typeTag = "SlowControlType";
|
||||||
|
break;
|
||||||
|
case eUnkown:
|
||||||
|
default:
|
||||||
|
nameTag = "Name";
|
||||||
|
typeTag = "Type";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fFolderTag == eDecayAnaModule)
|
||||||
|
fNoOfDecayHistos++;
|
||||||
|
|
||||||
|
TString str;
|
||||||
|
|
||||||
|
str = offsetStr + "<" + nameTag + ">";
|
||||||
|
str += obj->GetName();
|
||||||
|
str += "</" + nameTag + ">";
|
||||||
|
fXmlData.push_back(str.Data());
|
||||||
|
|
||||||
|
str = offsetStr + "<" + typeTag + ">";
|
||||||
|
str += obj->ClassName();
|
||||||
|
str += "</" + typeTag + ">";
|
||||||
|
fXmlData.push_back(str.Data());
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
*
|
||||||
|
* \param obj object to be checked
|
||||||
|
* \param str tag telling what kind of object it is
|
||||||
|
* \param offset needed to indent dump info
|
||||||
|
*/
|
||||||
|
void PMusrRoot2Xml::CheckClass(TObject *obj, TString str, UInt_t offset)
|
||||||
|
{
|
||||||
|
TString offsetStr="";
|
||||||
|
for (UInt_t i=0; i<offset; i++)
|
||||||
|
offsetStr += " ";
|
||||||
|
|
||||||
|
if (str == "TFolder") {
|
||||||
|
TString xmlTagName(TString(obj->GetName()));
|
||||||
|
|
||||||
|
// set folder tag
|
||||||
|
if (!xmlTagName.CompareTo("DecayAnaModule"))
|
||||||
|
fFolderTag = eDecayAnaModule;
|
||||||
|
else if (!xmlTagName.CompareTo("SCAnaModule"))
|
||||||
|
fFolderTag = eSlowControlAnaModule;
|
||||||
|
else if (!xmlTagName.CompareTo("SCAnaModule"))
|
||||||
|
fFolderTag = eSlowControlAnaModule;
|
||||||
|
else
|
||||||
|
fFolderTag = eUnkown;
|
||||||
|
|
||||||
|
offset += 2;
|
||||||
|
str = offsetStr + "<" + xmlTagName + ">";
|
||||||
|
fXmlData.push_back(str.Data());
|
||||||
|
|
||||||
|
DumpFolder((TFolder*)obj, offset);
|
||||||
|
|
||||||
|
str = offsetStr + "</" + xmlTagName + ">";
|
||||||
|
fXmlData.push_back(str.Data());
|
||||||
|
} else if (str == "TObjArray") {
|
||||||
|
offset += 2;
|
||||||
|
DumpObjArray((TObjArray*)obj, offset);
|
||||||
|
} else {
|
||||||
|
// filter out the proper entry tag
|
||||||
|
TString entryTag("");
|
||||||
|
switch (fFolderTag) {
|
||||||
|
case eDecayAnaModule:
|
||||||
|
entryTag = TString("DecayHistoEntry");
|
||||||
|
break;
|
||||||
|
case eSlowControlAnaModule:
|
||||||
|
entryTag = TString("SlowControlHistoEntry");
|
||||||
|
break;
|
||||||
|
case eUnkown:
|
||||||
|
default:
|
||||||
|
entryTag = TString("Entry");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += 2;
|
||||||
|
str = offsetStr + "<" + entryTag + ">";
|
||||||
|
fXmlData.push_back(str.Data());
|
||||||
|
DumpEntry((TObjArray*)obj, offset);
|
||||||
|
str = offsetStr + "</" + entryTag + ">";
|
||||||
|
fXmlData.push_back(str.Data());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* <p>Checks to TMusrRunHeader type of the RunHeader entries.
|
||||||
|
*
|
||||||
|
* \param entry to be checked.
|
||||||
|
* \param type repesentation of the entry
|
||||||
|
*/
|
||||||
|
void PMusrRoot2Xml::GetType(TString entry, TString &type)
|
||||||
|
{
|
||||||
|
if (entry.Contains("-@0")) {
|
||||||
|
type = "TString";
|
||||||
|
} else if (entry.Contains("-@1")) {
|
||||||
|
type = "Int_t";
|
||||||
|
} else if (entry.Contains("-@2")) {
|
||||||
|
type = "Double_t";
|
||||||
|
} else if (entry.Contains("-@3")) {
|
||||||
|
type = "TMusrRunPhysicalQuantity";
|
||||||
|
} else if (entry.Contains("-@4")) {
|
||||||
|
type = "TStringVector";
|
||||||
|
} else if (entry.Contains("-@5")) {
|
||||||
|
type = "TIntVector";
|
||||||
|
} else if (entry.Contains("-@6")) {
|
||||||
|
type = "TDoubleVector";
|
||||||
|
} else {
|
||||||
|
type = "TString";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* <p>Filters from a TMusrRunHeader RunHeader entry the label.
|
||||||
|
*
|
||||||
|
* \param entry to be filtered
|
||||||
|
* \param label extracted from entry
|
||||||
|
*/
|
||||||
|
void PMusrRoot2Xml::GetLabel(TString entry, TString &label)
|
||||||
|
{
|
||||||
|
label="no_idea";
|
||||||
|
|
||||||
|
Ssiz_t start = entry.First('-');
|
||||||
|
Ssiz_t end = entry.First(':');
|
||||||
|
|
||||||
|
if ((start == -1) || (end == -1))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (end - start < 2)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// check that '-@' is present in the string, otherwise it is NOT a known label
|
||||||
|
Ssiz_t pos = entry.First('@');
|
||||||
|
if (pos < 1)
|
||||||
|
return;
|
||||||
|
if (entry(pos-1) != '-')
|
||||||
|
return;
|
||||||
|
|
||||||
|
// cut out value
|
||||||
|
label = entry;
|
||||||
|
label.Remove(0, start+2);
|
||||||
|
label.Remove(end-start-2, label.Length());
|
||||||
|
|
||||||
|
label.ReplaceAll(' ', '_'); // replace spaces through underscores
|
||||||
|
label.ReplaceAll('(', '_'); // replace '(' through underscores
|
||||||
|
label.ReplaceAll(')', '_'); // replace ')' through underscores
|
||||||
|
label.ReplaceAll('[', '_'); // replace '[' through underscores
|
||||||
|
label.ReplaceAll(']', '_'); // replace ']' through underscores
|
||||||
|
label.ReplaceAll('{', '_'); // replace '[' through underscores
|
||||||
|
label.ReplaceAll('}', '_'); // replace ']' through underscores
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* <p>Dump help information.
|
||||||
|
*/
|
||||||
|
void mrv_syntax()
|
||||||
|
{
|
||||||
|
cout << endl << "usage: musrRootValidation <musrRootFile> <musrRootSchema> [--quiet] [--keep] | --help | --version";
|
||||||
|
cout << endl << " --quiet: do not dump the MusrRoot file info while validating";
|
||||||
|
cout << endl << " --keep: do NOT delete the intermediate XML-file";
|
||||||
|
cout << endl << " --help: shows this help";
|
||||||
|
cout << endl << " --version: shows the current version";
|
||||||
|
cout << endl << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* <p>Validates an XML file against a Schema.
|
||||||
|
*
|
||||||
|
* \param doc XML file object representation
|
||||||
|
* \param schema_filename Schema file name
|
||||||
|
*/
|
||||||
|
int is_valid(const xmlDocPtr doc, const char *schema_filename)
|
||||||
|
{
|
||||||
|
xmlDocPtr schema_doc = xmlReadFile(schema_filename, NULL, XML_PARSE_NONET);
|
||||||
|
if (schema_doc == NULL) {
|
||||||
|
cerr << endl << "**ERROR** the schema (" << schema_filename << ") cannot be loaded or is not well-formed" << endl << endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
xmlSchemaParserCtxtPtr parser_ctxt = xmlSchemaNewDocParserCtxt(schema_doc);
|
||||||
|
if (parser_ctxt == NULL) {
|
||||||
|
cerr << endl << "**ERROR** unable to create a parser context for the schema." << endl << endl;
|
||||||
|
xmlFreeDoc(schema_doc);
|
||||||
|
return -2;
|
||||||
|
}
|
||||||
|
xmlSchemaPtr schema = xmlSchemaParse(parser_ctxt);
|
||||||
|
if (schema == NULL) {
|
||||||
|
cerr << endl << "**ERROR** the schema itself is not valid." << endl << endl;
|
||||||
|
xmlSchemaFreeParserCtxt(parser_ctxt);
|
||||||
|
xmlFreeDoc(schema_doc);
|
||||||
|
return -3;
|
||||||
|
}
|
||||||
|
xmlSchemaValidCtxtPtr valid_ctxt = xmlSchemaNewValidCtxt(schema);
|
||||||
|
if (valid_ctxt == NULL) {
|
||||||
|
cerr << endl << "**ERROR** unable to create a validation context for the schema." << endl << endl;
|
||||||
|
xmlSchemaFree(schema);
|
||||||
|
xmlSchemaFreeParserCtxt(parser_ctxt);
|
||||||
|
xmlFreeDoc(schema_doc);
|
||||||
|
return -4;
|
||||||
|
}
|
||||||
|
int is_valid = (xmlSchemaValidateDoc(valid_ctxt, doc) == 0);
|
||||||
|
xmlSchemaFreeValidCtxt(valid_ctxt);
|
||||||
|
xmlSchemaFree(schema);
|
||||||
|
xmlSchemaFreeParserCtxt(parser_ctxt);
|
||||||
|
xmlFreeDoc(schema_doc);
|
||||||
|
// force the return value to be non-negative on success
|
||||||
|
return is_valid ? 1 : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
//-----------------------------------------------------------------------
|
||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
*/
|
||||||
|
int main(int argc, char *argv[])
|
||||||
|
{
|
||||||
|
if (argc==1) {
|
||||||
|
mrv_syntax();
|
||||||
|
return -1;
|
||||||
|
} else if (argc==2) {
|
||||||
|
if (!strcmp(argv[1], "--version")) {
|
||||||
|
cout << endl << "musrRootValidation version: " << PMUSR_VERSION << " / $Id$" << endl << endl;
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
mrv_syntax();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// filter out possible options
|
||||||
|
bool quiet=false, keep=false;
|
||||||
|
for (int i=1; i<argc; i++) {
|
||||||
|
if (!strcmp(argv[i], "--quiet"))
|
||||||
|
quiet = true;
|
||||||
|
if (!strcmp(argv[i], "--keep"))
|
||||||
|
keep = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
PMusrRoot2Xml dump(argv[1], quiet, keep);
|
||||||
|
if (!dump.IsValid()) {
|
||||||
|
cerr << endl << "**ERROR** " << argv[1] << " is not a valid MusrRoot file." << endl << endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
xmlDocPtr doc = xmlParseFile(dump.GetXmlDumpFileName().Data());
|
||||||
|
if (doc == 0) {
|
||||||
|
cerr << endl << "**ERROR** couldn't get xmlDocPtr for xml-file " << argv[1] << "." << endl << endl;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_valid(doc, argv[2])) {
|
||||||
|
cout << endl << "xml-file " << argv[1] << " validates against xml-schema " << argv[2] << endl << endl;
|
||||||
|
} else {
|
||||||
|
cerr << endl << "**ERROR** xml-file " << argv[1] << " fails to validate against xml-schema " << argv[2] << endl << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
// do some further consistency checks
|
||||||
|
if (dump.GetNoOfDecayHistos() != dump.GetNoOfExpectedHistos()) {
|
||||||
|
cerr << endl << "**ERROR** number of histogram found in the DecayAnaModule is inconsistent";
|
||||||
|
cerr << endl << " with the header; found " << dump.GetNoOfDecayHistos() << " histograms in the DecayAnaModule,";
|
||||||
|
cerr << endl << " but in the header: No of Histos = " << dump.GetNoOfHistos() << "; # RedGreen Offsets = " << dump.GetNoOfRedGreenOffsets();
|
||||||
|
cerr << endl << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (dump.GetNoOfDecayHistos() != dump.GetNoOfDetectors()) {
|
||||||
|
cerr << endl << "**ERROR** number of histogram found in the DecayAnaModule is inconsistent";
|
||||||
|
cerr << endl << " with number of Detector entries in the RunHeader.";
|
||||||
|
cerr << endl << " Found " << dump.GetNoOfDecayHistos() << " histograms in the DecayAnaModule,";
|
||||||
|
cerr << endl << " but " << dump.GetNoOfDetectors() << " number of Detector entries.";
|
||||||
|
cerr << endl << endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
@ -47,12 +47,12 @@ void analyticFakeData(const TString type)
|
|||||||
gROOT->GetListOfBrowsables()->Add(histosFolder, "histos");
|
gROOT->GetListOfBrowsables()->Add(histosFolder, "histos");
|
||||||
decayAnaModule = histosFolder->AddFolder("DecayAnaModule", "muSR decay histograms");
|
decayAnaModule = histosFolder->AddFolder("DecayAnaModule", "muSR decay histograms");
|
||||||
|
|
||||||
UInt_t runNo = 3000;
|
UInt_t runNo = 2001;
|
||||||
TString fileName, tstr, label, tstr1;
|
TString fileName, tstr, label, tstr1;
|
||||||
fileName.Form("0%d.root", (Int_t)runNo);
|
fileName.Form("0%d.root", (Int_t)runNo);
|
||||||
|
|
||||||
Double_t t0[8] = {3419.0, 3520.0, 3520.0, 3421.0, 3517.0, 3418.0, 3522.0, 3623.0}; // runNo: 1000 & 2000
|
// Double_t t0[8] = {3419.0, 3520.0, 3520.0, 3421.0, 3517.0, 3418.0, 3522.0, 3623.0}; // runNo: 1000 & 2000
|
||||||
// Double_t t0[8] = {3519.0, 3420.0, 3520.0, 3621.0, 3417.0, 3518.0, 3422.0, 3423.0}; // runNo: 1001 & 2001
|
Double_t t0[8] = {3519.0, 3420.0, 3520.0, 3621.0, 3417.0, 3518.0, 3422.0, 3423.0}; // runNo: 1001 & 2001
|
||||||
|
|
||||||
if (!type.CompareTo("TLemRunHeader")) {
|
if (!type.CompareTo("TLemRunHeader")) {
|
||||||
// feed run info header
|
// feed run info header
|
||||||
@ -169,8 +169,10 @@ void analyticFakeData(const TString type)
|
|||||||
const Double_t tau = 2197.019; // ns
|
const Double_t tau = 2197.019; // ns
|
||||||
// asymmetry related stuff
|
// asymmetry related stuff
|
||||||
const Double_t timeResolution = 0.1953125; // ns
|
const Double_t timeResolution = 0.1953125; // ns
|
||||||
Double_t a0[8] = {0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12};
|
// Double_t a0[8] = {0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12, 0.12};
|
||||||
Double_t a1[8] = {0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05};
|
Double_t a0[8] = {0.22, 0.22, 0.22, 0.22, 0.22, 0.22, 0.22, 0.22};
|
||||||
|
// Double_t a1[8] = {0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05, 0.05};
|
||||||
|
Double_t a1[8] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
|
||||||
Double_t phase[8] = {5.0*TMath::Pi()/180.0, 50.0*TMath::Pi()/180.0, 95.0*TMath::Pi()/180.0, 140.0*TMath::Pi()/180.0,
|
Double_t phase[8] = {5.0*TMath::Pi()/180.0, 50.0*TMath::Pi()/180.0, 95.0*TMath::Pi()/180.0, 140.0*TMath::Pi()/180.0,
|
||||||
185.0*TMath::Pi()/180.0, 230.0*TMath::Pi()/180.0, 275.0*TMath::Pi()/180.0, 320.0*TMath::Pi()/180.0,};
|
185.0*TMath::Pi()/180.0, 230.0*TMath::Pi()/180.0, 275.0*TMath::Pi()/180.0, 320.0*TMath::Pi()/180.0,};
|
||||||
const Double_t gamma = 0.00001355; // gamma/(2pi)
|
const Double_t gamma = 0.00001355; // gamma/(2pi)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user