// 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 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_data.push_back(""); 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(""); // 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 temp_xml_data; // first make a copy of the original xml_data for (unsigned int i=0; i") != string::npos) start = i; if (temp_xml_data[i].find("") != 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") != 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; iGetListOfFolders(); 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; iGetName()); 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; iGetEntries(); 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 + "" ; xml_data.push_back(xmlStr.Data()); } } xmlStr = offsetStr + ""; xml_data.push_back(xmlStr.Data()); } void dumpEntry(TObject *obj, UInt_t offset) { TString offsetStr=""; for (UInt_t i=0; i"; str += obj->GetName(); str += ""; xml_data.push_back(str.Data()); str = offsetStr + "<" + typeTag + ">"; str += obj->ClassName(); str += ""; xml_data.push_back(str.Data()); } void checkClass(TObject *obj, TString str, UInt_t offset) { TString offsetStr=""; for (UInt_t i=0; iGetName())); // 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 + ""; 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 + ""; 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 }