319 lines
8.5 KiB
C
319 lines
8.5 KiB
C
// 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
|
|
}
|