some more work on the MusrRoot run header

This commit is contained in:
2012-01-21 17:41:46 +00:00
parent 2243c8e7dc
commit ad383bad60
6 changed files with 595 additions and 239 deletions

View File

@ -0,0 +1,192 @@
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:annotation>
<xs:documentation>
This XSD document describes the muSR file structure for CERN/ROOT based files.
In the following it will be called MusrROOT.
It is currently the default standard for writting muSR data files at the
Paul Scherrer Institute.
Author: Andreas Suter, andreas.suter@psi.ch
$Id$
</xs:documentation>
</xs:annotation>
<xs:element name="MusrRoot" type="musrRoot"/>
<xs:complexType name="musrRoot">
<xs:sequence>
<xs:element name="histos" type="histosFolder"/>
<xs:element name="RunHeader" type="runHeaderFolder"/>
<xs:any processContents="skip" minOccurs="0" maxOccurs="unbounded"/> <!-- here can go any additional stuff you like -->
</xs:sequence>
</xs:complexType>
<xs:complexType name="histosFolder">
<xs:annotation>
<xs:documentation>
The histos folder is containing potentially various subfolders.
At least one subfolder, called DecayAnaModule, which holds the
muSR decay histograms, must be present.
</xs:documentation>
</xs:annotation>
<xs:sequence>
<xs:element name="DecayAnaModule" type="decayHistoData"/>
<xs:element name="SlowControlAnaModule" type="slowControlHistoData"/>
<xs:any processContents="skip" minOccurs="0" maxOccurs="unbounded"/> <!-- here can go any additional stuff you like -->
</xs:sequence>
</xs:complexType>
<xs:complexType name="decayHistoData">
<xs:sequence>
<xs:element name="DecayHistoEntry" type="decayHistoEntry" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="decayHistoEntry">
<xs:sequence>
<xs:element name="HistoName" type="histoName"/>
<xs:element name="HistoType" type="histoType"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="histoName">
<xs:restriction base="xs:string">
<xs:pattern value="hDecay([0-9]){3}"/> <!-- this means hDecayXXX, where XXX are 3 digits -->
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="histoType">
<xs:restriction base="xs:string">
<xs:pattern value="TH1F"></xs:pattern>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="slowControlHistoData">
<xs:sequence>
<xs:element name="SlowControlHistoEntry" type="slowControlHistoEntry" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="slowControlHistoEntry">
<xs:sequence>
<xs:element name="SlowControlName" type="slowControlName"/>
<xs:element name="SlowControlType" type="slowControlType"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="slowControlName">
<xs:restriction base="xs:string">
<xs:pattern value="h(\S)+"/> <!-- this means 'h' followed by one or more characters without space, e.g. 'hTemperature1', but NOT 'hTemp 1'-->
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="slowControlType">
<xs:restriction base="xs:string">
<xs:pattern value="TH1F"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="runHeaderFolder">
<xs:sequence>
<xs:element name="RunInfo" type="runInfo"/>
<xs:element name="DetectorInfo" type="detectorInfo"/>
<xs:element name="SampleEnvironmentInfo" type="sampleEnvironmentInfo"/>
<xs:element name="MagneticFieldEnvironmentInfo" type="magneticFieldEnvironmentInfo"/>
<xs:element name="BeamlineInfo" type="beamlineInfo"/>
<xs:any processContents="skip" minOccurs="0" maxOccurs="unbounded"/> <!-- here can go any additional stuff you like -->
</xs:sequence>
</xs:complexType>
<xs:complexType name="runInfo">
<xs:sequence>
<xs:element name="Version" type="TString"/>
<xs:element name="Generic_Validator_URL" type="TString"/>
<xs:element name="Specific_Validator_URL" type="TString"/>
<xs:element name="Generator" type="TString"/>
<xs:element name="File_Name" type="TString"/>
<xs:element name="Run_Title" type="TString"/>
<xs:element name="Run_Number" type="Int_t"/>
<xs:element name="Run_Start_Time" type="TString"/>
<xs:element name="Run_Stop_Time" type="TString"/>
<xs:element name="Run_Duration" type="TMusrRunPhysicalQuantity"/>
<xs:element name="Laboratory" type="TString"/>
<xs:element name="Instrument" type="TString"/>
<xs:element name="Muon_Beam_Momentum" type="TMusrRunPhysicalQuantity"/>
<xs:element name="Muon_Species" type="TString"/>
<xs:element name="Muon_Source" type="TString"/>
<xs:element name="Setup" type="TString"/>
<xs:element name="Comment" type="TString"/>
<xs:element name="Sample_Name" type="TString"/>
<xs:element name="Sample_Temperature" type="TMusrRunPhysicalQuantity"/>
<xs:element name="Sample_Magnetic_Field" type="TMusrRunPhysicalQuantity"/>
<xs:element name="No_of_Histos" type="Int_t"/>
<xs:element name="Time_Resolution" type="TMusrRunPhysicalQuantity"/>
<xs:any processContents="skip" minOccurs="0" maxOccurs="unbounded"/> <!-- here can go any additional stuff you like -->
</xs:sequence>
</xs:complexType>
<xs:simpleType name="Int_t">
<xs:restriction base="xs:string">
<xs:pattern value="Int_t"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="Double_t">
<xs:restriction base="xs:string">
<xs:pattern value="Double_t"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="TString">
<xs:restriction base="xs:string">
<xs:pattern value="TString"/>
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="TMusrRunPhysicalQuantity">
<xs:restriction base="xs:string">
<xs:pattern value="TMusrRunPhysicalQuantity"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="sampleEnvironmentInfo">
<xs:sequence>
<xs:element name="Cryo" type="TString"/>
<xs:any processContents="skip" minOccurs="0" maxOccurs="unbounded"/> <!-- here can go any additional stuff you like -->
</xs:sequence>
</xs:complexType>
<xs:complexType name="magneticFieldEnvironmentInfo">
<xs:sequence>
<xs:element name="Magnet_Name" type="TString"/>
<xs:any processContents="skip" minOccurs="0" maxOccurs="unbounded"/> <!-- here can go any additional stuff you like -->
</xs:sequence>
</xs:complexType>
<xs:complexType name="detectorInfo">
<xs:sequence>
<xs:element name="Detector" type="detector" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="detector">
<xs:sequence>
<xs:element name="Name" type="TString"/>
<xs:element name="Histo_Number" type="Int_t"/>
<xs:element name="Histo_Length" type="Int_t"/>
<xs:element name="Time_Zero_Bin" type="Double_t"/>
<xs:element name="First_Good_Bin" type="Int_t"/>
<xs:element name="Last_Good_Bin" type="Int_t"/>
<xs:any processContents="skip" minOccurs="0" maxOccurs="unbounded"/> <!-- here can go any additional stuff you like -->
</xs:sequence>
</xs:complexType>
<xs:complexType name="beamlineInfo">
<xs:sequence>
<xs:element name="Name" type="TString"/>
<xs:any processContents="skip" minOccurs="0" maxOccurs="unbounded"/> <!-- here can go any additional stuff you like -->
</xs:sequence>
</xs:complexType>
</xs:schema>

View File

@ -216,7 +216,7 @@ ClassImp(TMusrRunHeader)
*/
TMusrRunHeader::TMusrRunHeader()
{
fFileName = TString("n/a");
Init();
}
//--------------------------------------------------------------------------
@ -227,7 +227,22 @@ TMusrRunHeader::TMusrRunHeader()
*/
TMusrRunHeader::TMusrRunHeader(const char *fileName)
{
fFileName = TString(fileName);
Init(TString(fileName));
}
//--------------------------------------------------------------------------
// Init (private)
//--------------------------------------------------------------------------
/**
* <p>Initializer
*
* \param fileName file name of the caller.
*/
void TMusrRunHeader::Init(TString fileName)
{
fFileName = fileName;
fVersion = TString("$Id$");
Set("RunInfo/Version", fVersion);
}
//--------------------------------------------------------------------------
@ -237,6 +252,17 @@ TMusrRunHeader::TMusrRunHeader(const char *fileName)
* <p>Destructor.
*/
TMusrRunHeader::~TMusrRunHeader()
{
CleanUp();
}
//--------------------------------------------------------------------------
// CleanUp (private)
//--------------------------------------------------------------------------
/**
* <p>Clean up internal stuff.
*/
void TMusrRunHeader::CleanUp()
{
fStringObj.clear();
fIntObj.clear();
@ -334,172 +360,6 @@ Bool_t TMusrRunHeader::FillFolder(TFolder *folder)
return true;
}
//--------------------------------------------------------------------------
// GetHeaderInfo (public)
//--------------------------------------------------------------------------
/**
* <p>Get MUSR-ROOT header information of 'path'.
*
* \param requestedPath of the MUSR-ROOT header, e.g. RunInfo
* \param content of the requested MUSR-ROOT header.
*/
/*
void TMusrRunHeader::GetHeaderInfo(TString requestedPath, TObjArray &content)
{
// make sure content is initialized
content.Delete();
content.Expand(0);
content.SetOwner(); // takes ownership of the attached objects!!
TString str(""), path(""), name(""), fmt(""), tstr("");
TObjString *tostr;
TMusrRunPhysicalQuantity prop;
for (UInt_t i=0; i<fPathNameOrder.size(); i++) {
if (fPathNameOrder[i].Contains(requestedPath)) {
// go through all objects and try to find it
// 1st check TString
for (UInt_t j=0; j<fStringObj.size(); j++) {
if (fStringObj[j].GetPathName() == fPathNameOrder[i]) { // found correct object
SplitPathName(fStringObj[j].GetPathName(), path, name);
str.Form("%03d - %s: %s -@%d", i, name.Data(), fStringObj[j].GetValue().Data(), MRH_TSTRING);
tostr = new TObjString(str);
content.AddLast(tostr);
}
}
// 2nd check Int_t
for (UInt_t j=0; j<fIntObj.size(); j++) {
if (fIntObj[j].GetPathName() == fPathNameOrder[i]) { // found correct object
SplitPathName(fIntObj[j].GetPathName(), path, name);
str.Form("%03d - %s: %d -@%d", i, name.Data(), fIntObj[j].GetValue(), MRH_INT);
tostr = new TObjString(str);
content.AddLast(tostr);
}
}
// 3rd check Double_t
for (UInt_t j=0; j<fDoubleObj.size(); j++) {
if (fDoubleObj[j].GetPathName() == fPathNameOrder[i]) { // found correct object
SplitPathName(fDoubleObj[j].GetPathName(), path, name);
fmt.Form("%%03d - %%s: %%.%dlf -@%%d", MRH_DOUBLE_PREC);
str.Form(fmt, i, name.Data(), fDoubleObj[j].GetValue(), MRH_DOUBLE);
tostr = new TObjString(str);
content.AddLast(tostr);
}
}
// 4th check TMusrRunPhysicalQuantity
for (UInt_t j=0; j<fMusrRunPhysQuantityObj.size(); j++) {
if (fMusrRunPhysQuantityObj[j].GetPathName() == fPathNameOrder[i]) { // found correct object
prop = fMusrRunPhysQuantityObj[j].GetValue();
Int_t digit, digit_d;
if ((prop.GetDemand() != MRH_UNDEFINED) && (prop.GetValue() != MRH_UNDEFINED) && (prop.GetError() != MRH_UNDEFINED) &&
(prop.GetUnit() != "n/a")) { // <value> +- <error> <unit>; SP: <demand> [; <description>]
digit = GetDecimalPlace(prop.GetError());
digit_d = GetLeastSignificantDigit(prop.GetDemand());
if (prop.GetDescription() != "n/a") {
fmt.Form("%%s: %%.%dlf +- %%.%dlf %%s; SP: %%.%dlf; %%s", digit, digit, digit_d);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetError(), prop.GetUnit().Data(), prop.GetDemand(), prop.GetDescription().Data());
} else {
fmt.Form("%%s: %%.%dlf +- %%.%dlf %%s; SP: %%.%dlf", digit, digit, digit_d);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetError(), prop.GetUnit().Data(), prop.GetDemand());
}
} else if ((prop.GetDemand() == MRH_UNDEFINED) && (prop.GetValue() != MRH_UNDEFINED) && (prop.GetError() != MRH_UNDEFINED) &&
(prop.GetUnit() != "n/a")) { // <value> +- <error> <unit> [; <description>]
digit = GetDecimalPlace(prop.GetError());
if (prop.GetDescription() != "n/a") {
fmt.Form("%%s: %%.%dlf +- %%.%dlf %%s; %%s", digit, digit);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetError(), prop.GetUnit().Data(), prop.GetDescription().Data());
} else {
fmt.Form("%%s: %%.%dlf +- %%.%dlf %%s", digit, digit);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetError(), prop.GetUnit().Data());
}
} else if ((prop.GetDemand() == MRH_UNDEFINED) && (prop.GetValue() != MRH_UNDEFINED) && (prop.GetError() == MRH_UNDEFINED) &&
(prop.GetUnit() != "n/a")) { // <value> <unit> [; <description>]
digit = GetLeastSignificantDigit(prop.GetValue());
if (prop.GetDescription() != "n/a") {
fmt.Form("%%s: %%.%dlf %%s; %%s", digit);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetUnit().Data(), prop.GetDescription().Data());
} else {
fmt.Form("%%s: %%.%dlf %%s", digit);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetUnit().Data());
}
} else if ((prop.GetDemand() != MRH_UNDEFINED) && (prop.GetValue() != MRH_UNDEFINED) && (prop.GetError() == MRH_UNDEFINED) &&
(prop.GetUnit() != "n/a")) { // <value> <unit>; SP: <demand> [; <description>]
digit = GetLeastSignificantDigit(prop.GetValue());
digit_d = GetLeastSignificantDigit(prop.GetDemand());
if (prop.GetDescription() != "n/a") {
fmt.Form("%%s: %%.%dlf %%s; SP: %%.%dlf; %%s", digit, digit_d);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetUnit().Data(), prop.GetDemand(), prop.GetDescription().Data());
} else {
fmt.Form("%%s: %%.%dlf %%s; SP: %%.%dlf", digit, digit_d);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetUnit().Data(), prop.GetDemand());
}
}
str.Form("%03d - %s -@%d", i, tstr.Data(), MRH_TMUSR_RUN_PHYSICAL_QUANTITY);
tostr = new TObjString(str);
content.AddLast(tostr);
}
}
// 5th check TStringVector
for (UInt_t j=0; j<fStringVectorObj.size(); j++) {
if (fStringVectorObj[j].GetPathName() == fPathNameOrder[i]) { // found correct object
SplitPathName(fStringVectorObj[j].GetPathName(), path, name);
str.Form("%03d - %s: ", i, name.Data());
TStringVector vstr = fStringVectorObj[j].GetValue();
for (UInt_t k=0; k<vstr.size()-1; k++)
str += vstr[k] + "; ";
str += vstr[vstr.size()-1];
str += " -@";
str += MRH_TSTRING_VECTOR;
tostr = new TObjString(str);
content.AddLast(tostr);
}
}
// 6th check TIntVector
for (UInt_t j=0; j<fIntVectorObj.size(); j++) {
if (fIntVectorObj[j].GetPathName() == fPathNameOrder[i]) { // found correct object
SplitPathName(fIntVectorObj[j].GetPathName(), path, name);
str.Form("%03d - %s: ", i, name.Data());
TIntVector vint = fIntVectorObj[j].GetValue();
for (UInt_t k=0; k<vint.size()-1; k++) {
str += vint[k];
str += "; ";
}
str += vint[vint.size()-1];
str += " -@";
str += MRH_INT_VECTOR;
tostr = new TObjString(str);
content.AddLast(tostr);
}
}
// 7th check TDoubleVector
for (UInt_t j=0; j<fDoubleVectorObj.size(); j++) {
if (fDoubleVectorObj[j].GetPathName() == fPathNameOrder[i]) { // found correct object
SplitPathName(fDoubleVectorObj[j].GetPathName(), path, name);
str.Form("%03d - %s: ", i, name.Data());
TDoubleVector dvec = fDoubleVectorObj[j].GetValue();
TString subStr("");
fmt.Form("%%.%dlf", MRH_DOUBLE_PREC);
for (UInt_t k=0; k<dvec.size()-1; k++) {
subStr.Form(fmt, dvec[k]);
str += subStr;
str += "; ";
}
subStr.Form(fmt, dvec.size()-1);
str += subStr;
str += " -@";
str += MRH_DOUBLE_VECTOR;
tostr = new TObjString(str);
content.AddLast(tostr);
}
}
}
}
content.SetName(requestedPath);
}
*/
//--------------------------------------------------------------------------
// GetValue (public)
//--------------------------------------------------------------------------
@ -900,6 +760,9 @@ Bool_t TMusrRunHeader::ExtractAll(TFolder *folder)
TIter next(folder->GetListOfFolders());
TObjArray* entry;
// clean up all internal structures - just in case this is called multiple times
CleanUp();
while ((entry = (TObjArray*)next())) {
ExtractHeaderInformation(entry, entry->GetName());
}

View File

@ -156,6 +156,7 @@ public:
private:
TString fFileName;
TString fVersion;
vector< TMusrRunObject<TString> > fStringObj;
vector< TMusrRunObject<Int_t> > fIntObj;
@ -167,6 +168,9 @@ private:
vector< TString > fPathNameOrder; ///< keeps the path-name as they or set and hence its ordering
virtual void Init(TString str="n/a");
virtual void CleanUp();
virtual UInt_t GetDecimalPlace(Double_t val);
virtual UInt_t GetLeastSignificantDigit(Double_t val) const;
virtual void SplitPathName(TString pathName, TString &path, TString &name);

View File

@ -84,6 +84,7 @@ int main(int argc, char *argv[])
TString str("");
TStringVector strVec;
Int_t ival;
Double_t dval;
TDoubleVector dvec;
TMusrRunPhysicalQuantity prop;
Bool_t ok;
@ -100,28 +101,6 @@ int main(int argc, char *argv[])
else
cout << endl << "**ERROR** Couldn't obtain the 'Run Number'.";
header->GetValue("RunInfo/Histo Names", strVec, ok);
if (ok) {
cout << endl << "Histo Names: ";
for (UInt_t i=0; i<strVec.size()-1; i++) {
cout << strVec[i].Data() << ", ";
}
cout << strVec[strVec.size()-1].Data();
} else {
cout << endl << "**ERROR** Couldn't obtain the 'Histo Names'.";
}
header->GetValue("RunInfo/Time Zero Bin", dvec, ok);
if (ok) {
cout << endl << "Time Zero Bin: ";
for (UInt_t i=0; i<dvec.size()-1; i++) {
cout << dvec[i] << ", ";
}
cout << dvec[dvec.size()-1];
} else {
cout << endl << "**ERROR** Couldn't obtain the 'Time Zero Bin'.";
}
header->GetValue("RunInfo/Sample Temperature", prop, ok);
if (ok) {
cout << endl << "Sample Temperature: " << prop.GetValue() << " +- " << prop.GetError() << " " << prop.GetUnit().Data() << "; SP: " << prop.GetDemand() << "; " << prop.GetDescription().Data();
@ -129,13 +108,48 @@ int main(int argc, char *argv[])
cout << endl << "**ERROR** Couldn't obtain the 'Sample Temperature'.";
}
header->GetValue("Detectors/Detector000/Name", str, ok);
header->GetValue("DetectorInfo/Detector000/Name", str, ok);
if (ok) {
cout << endl << "Detectors/Detector000: Name=" << str;
cout << endl << "DetectorInfo/Detector000: Name=" << str;
} else {
cout << endl << "**ERROR** Couldn't obtain 'Detector/Detector000/Name'.";
}
header->GetValue("DetectorInfo/Detector000/Histo Number", ival, ok);
if (ok) {
cout << endl << "DetectorInfo/Detector000: Histo Number=" << ival;
} else {
cout << endl << "**ERROR** Couldn't obtain 'Detector/Detector000/Histo Number'.";
}
header->GetValue("DetectorInfo/Detector000/Histo Length", ival, ok);
if (ok) {
cout << endl << "DetectorInfo/Detector000: Histo Length=" << ival;
} else {
cout << endl << "**ERROR** Couldn't obtain 'Detector/Detector000/Histo Length'.";
}
header->GetValue("DetectorInfo/Detector000/Time Zero Bin", dval, ok);
if (ok) {
cout << endl << "DetectorInfo/Detector000: Time Zero Bin=" << dval;
} else {
cout << endl << "**ERROR** Couldn't obtain 'Detector/Detector000/Time Zero Bin'.";
}
header->GetValue("DetectorInfo/Detector000/First Good Bin", ival, ok);
if (ok) {
cout << endl << "DetectorInfo/Detector000: First Good Bin=" << ival;
} else {
cout << endl << "**ERROR** Couldn't obtain 'Detector/Detector000/First Good Bin'.";
}
header->GetValue("DetectorInfo/Detector000/Last Good Bin", ival, ok);
if (ok) {
cout << endl << "DetectorInfo/Detector000: Last Good Bin=" << ival;
} else {
cout << endl << "**ERROR** Couldn't obtain 'Detector/Detector000/Last Good Bin'.";
}
cout << endl << endl;
delete header;

View File

@ -0,0 +1,263 @@
// quick and dirty ROOT -> XML converter for MusrRoot
// needs to be rewritten as proper program.
//
// Andreas Suter
//
// $Id$
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>");
ofstream fout(xmlFilename);
for (UInt_t i=0; i<xml_data.size(); i++)
fout << xml_data[i] << endl;
fout.close();
}
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'
cout << endl << "debug>> xmlLablel=" << xmlLabel;
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());
// replace spaces through underscores
label.ReplaceAll(' ', '_');
}

View File

@ -61,14 +61,15 @@ int main(int argc, char *argv[])
TMusrRunPhysicalQuantity prop;
// run info
header->Set("RunInfo/Version", "$Id$");
header->Set("RunInfo/Generic Validator URL", "http://lmu.web.psi.ch/facilities/software/MusrRoot/Validation/MusrRoot.xsd");
header->Set("RunInfo/Specific Validator URL", "http://lmu.web.psi.ch/facilities/software/MusrRoot/Validation/MusrRootGPS.xsd");
header->Set("RunInfo/Generator", "any2many");
header->Set("RunInfo/File Name", "thisIsAFileName");
header->Set("RunInfo/File Name", "deltat_tdc_gps_2871.root");
header->Set("RunInfo/Run Title", "here comes the run title");
header->Set("RunInfo/Run Number", 577);
header->Set("RunInfo/Run Number", 2871);
// run info - start/stop time and duration
TString startTime("2011-04-19 14:25:22"), stopTime("2011-04-19 19:13:47");
TString startTime("2012-04-19 14:25:22"), stopTime("2012-04-19 19:13:47");
struct tm tm_start, tm_stop;
header->Set("RunInfo/Run Start Time", startTime);
header->Set("RunInfo/Run Stop Time", stopTime);
@ -78,17 +79,18 @@ int main(int argc, char *argv[])
memset(&tm_stop, 0, sizeof(tm_stop));
strptime(stopTime.Data(), "%Y-%m-%d %H:%M:%S", &tm_stop);
Double_t duration = difftime(mktime(&tm_stop), mktime(&tm_start));
header->Set("RunInfo/Run Duration", (Int_t)duration);
prop.Set("Run Duration", (Int_t)duration, "sec");
header->Set("RunInfo/Run Duration", prop);
header->Set("RunInfo/Laboratory", "PSI");
header->Set("RunInfo/Area", "piM3.2");
header->Set("RunInfo/Instrument", "GPS");
prop.Set("Muon Beam Momentum", 28.1, "MeV/c");
header->Set("RunInfo/Muon Beam Momentum", prop);
header->Set("RunInfo/Muon Species", "positive muon");
header->Set("RunInfo/Setup", "a very special setup");
header->Set("RunInfo/Muon Source", "target M");
header->Set("RunInfo/Setup", "a very special setup with Heliox");
header->Set("RunInfo/Comment", "nothing more to be said");
header->Set("RunInfo/Sample Name", "the best ever");
@ -100,40 +102,64 @@ int main(int argc, char *argv[])
header->Set("RunInfo/No of Histos", 4);
TStringVector detectorName;
detectorName.push_back("forward");
detectorName.push_back("top");
detectorName.push_back("backward");
detectorName.push_back("bottom");
header->Set("RunInfo/Histo Names", detectorName);
header->Set("RunInfo/Histo Length", 8192);
prop.Set("Time Resolution", 0.1953125, "ns", "TDC 9999");
header->Set("RunInfo/Time Resolution", prop);
TDoubleVector t0;
TIntVector ivec;
for (UInt_t i=0; i<4; i++) t0.push_back(215.0+5.0*(Double_t)rand()/(Double_t)RAND_MAX);
header->Set("RunInfo/Time Zero Bin", t0);
for (UInt_t i=0; i<4; i++) ivec.push_back((Int_t)t0[i] + 12);
header->Set("RunInfo/First Good Bin", ivec);
for (UInt_t i=0; i<4; i++) ivec[i] = 8191;
header->Set("RunInfo/Last Good Bin", ivec);
header->Set("DetectorInfo/Detector000/Name", "Left - NPP");
header->Set("DetectorInfo/Detector000/Histo Number", 0);
header->Set("DetectorInfo/Detector000/Histo Length", 66661);
header->Set("DetectorInfo/Detector000/Time Zero Bin", 3419.0);
header->Set("DetectorInfo/Detector000/First Good Bin", 3419);
header->Set("DetectorInfo/Detector000/Last Good Bin", 66661);
TIntVector readGreenOffset;
readGreenOffset.push_back(0);
readGreenOffset.push_back(10);
readGreenOffset.push_back(20);
readGreenOffset.push_back(30);
header->Set("RunInfo/Red-Green Offsets", readGreenOffset);
header->Set("DetectorInfo/Detector001/Name", "Top - NPP");
header->Set("DetectorInfo/Detector001/Histo Number", 1);
header->Set("DetectorInfo/Detector001/Histo Length", 66661);
header->Set("DetectorInfo/Detector001/Time Zero Bin", 3419.0);
header->Set("DetectorInfo/Detector001/First Good Bin", 3419);
header->Set("DetectorInfo/Detector001/Last Good Bin", 66661);
TStringVector redGreenDescription;
redGreenDescription.push_back("E-field/light off/off");
redGreenDescription.push_back("E-field/light on/off");
redGreenDescription.push_back("E-field/light off/on");
redGreenDescription.push_back("E-field/light on/on");
header->Set("RunInfo/Red-Green Description", redGreenDescription);
header->Set("DetectorInfo/Detector002/Name", "Right - NPP");
header->Set("DetectorInfo/Detector002/Histo Number", 2);
header->Set("DetectorInfo/Detector002/Histo Length", 66661);
header->Set("DetectorInfo/Detector002/Time Zero Bin", 3419.0);
header->Set("DetectorInfo/Detector002/First Good Bin", 3419);
header->Set("DetectorInfo/Detector002/Last Good Bin", 66661);
header->Set("DetectorInfo/Detector003/Name", "Bottom - NPP");
header->Set("DetectorInfo/Detector003/Histo Number", 3);
header->Set("DetectorInfo/Detector003/Histo Length", 66661);
header->Set("DetectorInfo/Detector003/Time Zero Bin", 3419.0);
header->Set("DetectorInfo/Detector003/First Good Bin", 3419);
header->Set("DetectorInfo/Detector003/Last Good Bin", 66661);
header->Set("DetectorInfo/Detector004/Name", "Left - PPC");
header->Set("DetectorInfo/Detector004/Histo Number", 20);
header->Set("DetectorInfo/Detector004/Histo Length", 66661);
header->Set("DetectorInfo/Detector004/Time Zero Bin", 3419.0);
header->Set("DetectorInfo/Detector004/First Good Bin", 3419);
header->Set("DetectorInfo/Detector004/Last Good Bin", 66661);
header->Set("DetectorInfo/Detector005/Name", "Top - PPC");
header->Set("DetectorInfo/Detector005/Histo Number", 21);
header->Set("DetectorInfo/Detector005/Histo Length", 66661);
header->Set("DetectorInfo/Detector005/Time Zero Bin", 3419.0);
header->Set("DetectorInfo/Detector005/First Good Bin", 3419);
header->Set("DetectorInfo/Detector005/Last Good Bin", 66661);
header->Set("DetectorInfo/Detector006/Name", "Right - PPC");
header->Set("DetectorInfo/Detector006/Histo Number", 22);
header->Set("DetectorInfo/Detector006/Histo Length", 66661);
header->Set("DetectorInfo/Detector006/Time Zero Bin", 3419.0);
header->Set("DetectorInfo/Detector006/First Good Bin", 3419);
header->Set("DetectorInfo/Detector006/Last Good Bin", 66661);
header->Set("DetectorInfo/Detector007/Name", "Bottom - PPC");
header->Set("DetectorInfo/Detector007/Histo Number", 23);
header->Set("DetectorInfo/Detector007/Histo Length", 66661);
header->Set("DetectorInfo/Detector007/Time Zero Bin", 3419.0);
header->Set("DetectorInfo/Detector007/First Good Bin", 3419);
header->Set("DetectorInfo/Detector007/Last Good Bin", 66661);
TStringVector scHistoNames;
scHistoNames.push_back("Sample Temperature");
@ -167,21 +193,12 @@ int main(int argc, char *argv[])
header->Set("SampleEnvironmentInfo/Dummy Prop", prop);
// magnetic field environment
header->Set("MagneticFieldEnvironmentInfo/Name", "Bpar");
header->Set("MagneticFieldEnvironmentInfo/Magnet Name", "Bpar");
prop.Set("Current", 1.34, "A");
header->Set("MagneticFieldEnvironmentInfo/Current", prop);
// detector forward
header->Set("Detectors/Detector000/Name", "forward");
header->Set("Detectors/Detector000/Histo Number", 0);
header->Set("Detectors/Detector000/Histo Length", 8192);
// detector backward
header->Set("Detectors/Detector001/Name", "backward");
header->Set("Detectors/Detector001/Histo Number", 0);
header->Set("Detectors/Detector001/Histo Length", 8192);
// beamline
header->Set("BeamlineInfo/Name", "piM3.2");
header->Set("BeamlineInfo/WSX61a", "DAC = 3289, ADC = 0.800");
TIntVector dummyInt;
@ -203,8 +220,11 @@ int main(int argc, char *argv[])
}
// root file header related things
/*
TFolder *runHeader = gROOT->GetRootFolder()->AddFolder("RunHeader", "MusrRoot Run Header Info");
gROOT->GetListOfBrowsables()->Add(runHeader, "RunHeader");
*/
TFolder *runHeader = new TFolder("RunHeader", "MusrRoot Run Header Info");
if (header->FillFolder(runHeader)) {
runHeader->Write();