handles now updating properly

This commit is contained in:
nemu 2012-03-13 07:47:00 +00:00
parent fb5c5541f1
commit 59df2224ba
6 changed files with 420 additions and 167 deletions

View File

@ -3,7 +3,7 @@
<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.
In the following it will be called MusrRoot.
It is currently the default standard for writting muSR data files at the
Paul Scherrer Institute.
@ -55,7 +55,7 @@
<xs:simpleType name="histoName">
<xs:restriction base="xs:string">
<xs:pattern value="hDecay([0-9]){4}"/> <!-- this means hDecayXXX, where XXX are 3 digits -->
<xs:pattern value="hDecay([0-9]){3,}"/> <!-- this means hDecayXXX, where XXX are 3 digits -->
</xs:restriction>
</xs:simpleType>
@ -118,7 +118,8 @@
<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:element name="Time_Resolution" type="TMusrRunPhysicalQuantity"/>
<xs:element name="RedGreen_Offsets" type="TIntVector"/>
<xs:any processContents="skip" minOccurs="0" maxOccurs="unbounded"/> <!-- here can go any additional stuff you like -->
</xs:sequence>
</xs:complexType>
@ -147,6 +148,12 @@
</xs:restriction>
</xs:simpleType>
<xs:simpleType name="TIntVector">
<xs:restriction base="xs:string">
<xs:pattern value="TIntVector"/>
</xs:restriction>
</xs:simpleType>
<xs:complexType name="sampleEnvironmentInfo">
<xs:sequence>
<xs:element name="Cryo" type="TString"/>

View File

@ -0,0 +1,221 @@
<?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 of CERN/ROOT based files for LEM.
In the following it will be called MusrRootLEM.
It is an extension of MusrRoot.xsd and describes the additional LEM specific entries.
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 ref="histos"/>
<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:element name="histos">
<xs:annotation>
<xs:documentation>
The histos folder is containing potentially various subfolders.
At least two subfolders, called DecayAnaModule, and SlowControlAnaModule,
which holds the muSR decay histograms, must be present.
</xs:documentation>
</xs:annotation>
<xs:complexType>
<xs:sequence>
<xs:element name="DecayAnaModule" type="decayHistoData"/>
<xs:element name="SCAnaModule" type="slowControlHistoData"/>
<xs:element name="TOFAnaModule" type="histoData"/>
<xs:element name="PileUpAnaModule" type="histoData"/>
<xs:any processContents="skip" minOccurs="0" maxOccurs="unbounded"/> <!-- here can go any additional stuff you like -->
</xs:sequence>
</xs:complexType>
</xs:element>
<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 or more -->
</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="xs:string"/>
<xs:element name="SlowControlType" type="slowControlType"/>
</xs:sequence>
</xs:complexType>
<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:element name="RedGreen_Offsets" type="TIntVector"/>
<xs:element name="Moderator" type="TString"/>
<xs:element name="Moderator_HV" type="TMusrRunPhysicalQuantity"/>
<xs:element name="Sample_HV" type="TMusrRunPhysicalQuantity"/>
<xs:element name="Implantation_Energy" type="TMusrRunPhysicalQuantity"/>
<xs:element name="Cuts" type="TString"/>
<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:simpleType name="TIntVector">
<xs:restriction base="xs:string">
<xs:pattern value="TIntVector"/>
</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:element name="Beamline_Settings" 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="histoData">
<xs:sequence>
<xs:element name="Entry" type="histoEntry" minOccurs="1" maxOccurs="unbounded"/>
</xs:sequence>
</xs:complexType>
<xs:complexType name="histoEntry">
<xs:sequence>
<xs:element name="Name" type="xs:string"/>
<xs:element name="Type" type="rootHistoType"/>
</xs:sequence>
</xs:complexType>
<xs:simpleType name="rootHistoType">
<xs:restriction base="xs:string">
<xs:pattern value="TH([1-2])F"/> <!-- this means TH1F or TH2F -->
</xs:restriction>
</xs:simpleType>
</xs:schema>

View File

@ -213,8 +213,10 @@ ClassImp(TMusrRunHeader)
//--------------------------------------------------------------------------
/**
* <p>Constructor.
*
* \param quite if set to true, warnings will be omited. Default is false.
*/
TMusrRunHeader::TMusrRunHeader()
TMusrRunHeader::TMusrRunHeader(bool quite) : fQuite(quite)
{
Init();
}
@ -224,9 +226,13 @@ TMusrRunHeader::TMusrRunHeader()
//--------------------------------------------------------------------------
/**
* <p>Constructor.
*
* \param fileName file name of the MusrRoot file.
* \param quite if set to true, warnings will be omited. Default is false.
*/
TMusrRunHeader::TMusrRunHeader(const char *fileName)
TMusrRunHeader::TMusrRunHeader(const char *fileName, bool quite)
{
fQuite = quite;
Init(TString(fileName));
}
@ -243,6 +249,11 @@ void TMusrRunHeader::Init(TString fileName)
fFileName = fileName;
fVersion = TString("$Id$");
Set("RunInfo/Version", fVersion);
Set("RunInfo/Generic Validator URL", "http://lmu.web.psi.ch/facilities/software/MusrRoot/validation/MusrRoot.xsd");
Set("DetectorInfo/Detector000/Name", "n/a");
Set("SampleEnvironmentInfo/Cryo", "n/a");
Set("MagneticFieldEnvironmentInfo/Magnet Name", "n/a");
Set("BeamlineInfo/Name", "n/a");
}
//--------------------------------------------------------------------------
@ -280,83 +291,68 @@ void TMusrRunHeader::CleanUp()
//--------------------------------------------------------------------------
/**
* <p>Fills the RunHeader folder. This is needed to write it to a ROOT file.
* It walks through all information and attaches it to folder.
* It walks through all information and attaches it to the folder or replaces
* it, if it is already present.
*
* \param folder to be filled
*/
Bool_t TMusrRunHeader::FillFolder(TFolder *folder)
{
TObjArray *oarray, *tokens;
vector<TObjArray*> content;
TObjString ostr;
TString path, name, pathName;
TObjArray *oarray;
TObjString ostr, *p_ostr;
TString path, name, str;
Ssiz_t pos=0;
bool found=false;
if (folder == 0) {
cerr << endl << ">> TMusrRunHeader::FillFolder(): **ERROR** folder == 0!!" << endl;
return false;
}
folder->SetOwner(); // folder takes ownership of all added objects!
folder->SetOwner(); // folder takes ownership of all added objects! This means that the folder object does the cleanup
// update/generate tree structure in folder
for (UInt_t i=0; i<fPathNameOrder.size(); i++) {
tokens = fPathNameOrder[i].Tokenize('/');
if (tokens == 0) {
cout << endl << ">> TMusrRunHeader::FillFolder(): **ERROR** couldn't tokenize string " << fPathNameOrder[i] << endl;
path=fPathNameOrder[i];
if (!UpdateFolder(folder, path))
return false;
}
// update/generate tree content
for (UInt_t i=0; i<fPathNameOrder.size(); i++) {
path=fPathNameOrder[i];
pos = path.Last('/');
if (pos == -1) {
cerr << endl << ">> TMusrRunHeader::FillFolder(): **ERROR** somethig is wrong with the path=" << path << " !!" << endl;
return false;
}
path.Remove(pos); // remove the value from the path
oarray = (TObjArray*)FindObject(folder, path);
if (!oarray) {
cerr << endl << ">> TMusrRunHeader::FillFolder(): **ERROR** couldn't create header structure!!" << endl;
return false;
}
Int_t idx;
if (tokens->GetEntries() == 2) { // <path>/<value>
path = ((TObjString*)tokens->At(0))->GetString();
idx = ObjectPresent(content, path);
if (idx == -1) {
// add object array
oarray = new TObjArray();
oarray->SetName(path);
content.push_back(oarray);
idx = content.size()-1;
// check if <value> is already found in oarray
ostr = GetHeaderString(i); // encode the string for the MusrRoot file
name = ostr.GetString(); // convert to TString
str = GetFirst(name, ':'); // get the first part of the encoded string, i.e. <nnn> - <name>
found = false;
for (Int_t j=0; j<oarray->GetEntriesFast(); j++) {
p_ostr = (TObjString*) oarray->At(j);
if (p_ostr->GetString().BeginsWith(str)) { // present hence replace
oarray->AddAt(ostr.Clone(), j);
found = true;
break;
}
// add value
ostr = GetHeaderString(i);
content[idx]->AddLast(ostr.Clone());
} else { // <path>/../<path>/<value>
path = ((TObjString*)tokens->At(0))->GetString();
idx = ObjectPresent(content, path);
if (idx == -1) {
// add object array
oarray = new TObjArray();
oarray->SetName(path);
content.push_back(oarray);
idx = content.size()-1;
}
// add necessary sub object arrays
pathName = fPathNameOrder[i];
RemoveFirst(pathName, '/');
AddSubTrees(content[idx], pathName);
// get header string
ostr = GetHeaderString(i);
// set object string on the right position within content
SetSubTreeObject(content[idx], ostr, i);
}
// clean up
if (tokens) {
delete tokens;
tokens = 0;
if (!found) {
oarray->AddLast(ostr.Clone());
}
}
// fill folder with all run header information
for (UInt_t i=0; i<content.size(); i++) {
folder->Add(content[i]);
}
// clean up
content.clear();
return true;
}
@ -525,11 +521,12 @@ void TMusrRunHeader::GetValue(TString pathName, TDoubleVector &value, Bool_t &ok
*/
void TMusrRunHeader::Set(TString pathName, TString value)
{
// check if pathName is already set, and if not add it as a new entry
// check if pathName is already set, if not add it as a new entry, otherwise replace it
UInt_t i=0;
for (i=0; i<fStringObj.size(); i++) {
if (!fStringObj[i].GetPathName().CompareTo(pathName, TString::kIgnoreCase)) {
cerr << endl << ">> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl;
if (!fQuite)
cerr << endl << ">> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl;
fStringObj[i].SetType("TString");
fStringObj[i].SetValue(value);
break;
@ -558,11 +555,12 @@ void TMusrRunHeader::Set(TString pathName, TString value)
*/
void TMusrRunHeader::Set(TString pathName, Int_t value)
{
// check if pathName is already set, and if not add it as a new entry
// check if pathName is already set, if not add it as a new entry, otherwise replace it
UInt_t i=0;
for (i=0; i<fIntObj.size(); i++) {
if (!fIntObj[i].GetPathName().CompareTo(pathName, TString::kIgnoreCase)) {
cerr << endl << ">> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl;
if (!fQuite)
cerr << endl << ">> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl;
fIntObj[i].SetType("Int_t");
fIntObj[i].SetValue(value);
break;
@ -591,11 +589,12 @@ void TMusrRunHeader::Set(TString pathName, Int_t value)
*/
void TMusrRunHeader::Set(TString pathName, Double_t value)
{
// check if pathName is already set, and if not add it as a new entry
// check if pathName is already set, if not add it as a new entry, otherwise replace it
UInt_t i=0;
for (i=0; i<fDoubleObj.size(); i++) {
if (!fDoubleObj[i].GetPathName().CompareTo(pathName, TString::kIgnoreCase)) {
cerr << endl << ">> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl;
if (!fQuite)
cerr << endl << ">> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl;
fDoubleObj[i].SetType("Double_t");
fDoubleObj[i].SetValue(value);
break;
@ -624,11 +623,12 @@ void TMusrRunHeader::Set(TString pathName, Double_t value)
*/
void TMusrRunHeader::Set(TString pathName, TMusrRunPhysicalQuantity value)
{
// check if pathName is already set, and if not add it as a new entry
// check if pathName is already set, if not add it as a new entry, otherwise replace it
UInt_t i=0;
for (i=0; i<fMusrRunPhysQuantityObj.size(); i++) {
if (!fMusrRunPhysQuantityObj[i].GetPathName().CompareTo(pathName, TString::kIgnoreCase)) {
cerr << endl << ">> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl;
if (!fQuite)
cerr << endl << ">> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl;
fMusrRunPhysQuantityObj[i].SetType("TMusrRunHeader");
fMusrRunPhysQuantityObj[i].SetValue(value);
break;
@ -657,11 +657,12 @@ void TMusrRunHeader::Set(TString pathName, TMusrRunPhysicalQuantity value)
*/
void TMusrRunHeader::Set(TString pathName, TStringVector value)
{
// check if pathName is already set, and if not add it as a new entry
// check if pathName is already set, if not add it as a new entry, otherwise replace it
UInt_t i=0;
for (i=0; i<fStringVectorObj.size(); i++) {
if (!fStringVectorObj[i].GetPathName().CompareTo(pathName, TString::kIgnoreCase)) {
cerr << endl << ">> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl;
if (!fQuite)
cerr << endl << ">> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl;
fStringVectorObj[i].SetType("TStringVector");
fStringVectorObj[i].SetValue(value);
break;
@ -690,11 +691,12 @@ void TMusrRunHeader::Set(TString pathName, TStringVector value)
*/
void TMusrRunHeader::Set(TString pathName, TIntVector value)
{
// check if pathName is already set, and if not add it as a new entry
// check if pathName is already set, if not add it as a new entry, otherwise replace it
UInt_t i=0;
for (i=0; i<fIntVectorObj.size(); i++) {
if (!fIntVectorObj[i].GetPathName().CompareTo(pathName, TString::kIgnoreCase)) {
cerr << endl << ">> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl;
if (!fQuite)
cerr << endl << ">> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl;
fIntVectorObj[i].SetType("TIntVector");
fIntVectorObj[i].SetValue(value);
break;
@ -723,11 +725,12 @@ void TMusrRunHeader::Set(TString pathName, TIntVector value)
*/
void TMusrRunHeader::Set(TString pathName, TDoubleVector value)
{
// check if pathName is already set, and if not add it as a new entry
// check if pathName is already set, if not add it as a new entry, otherwise replace it
UInt_t i=0;
for (i=0; i<fDoubleVectorObj.size(); i++) {
if (!fDoubleVectorObj[i].GetPathName().CompareTo(pathName, TString::kIgnoreCase)) {
cerr << endl << ">> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl;
if (!fQuite)
cerr << endl << ">> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl;
fDoubleVectorObj[i].SetType("TDoubleVector");
fDoubleVectorObj[i].SetValue(value);
break;
@ -1365,23 +1368,89 @@ TString TMusrRunHeader::GetType(TString str)
}
//--------------------------------------------------------------------------
// ObjectPresent (private)
// UpdateFolder (private)
//--------------------------------------------------------------------------
/**
* <p>
* <p>Update folder structure
*
* \param content
* \param path
* <p><b>return:</b>
* - true if everything is all right
* - false otherwise
*
* \param treeObj to be updated
* \param path to be added within 'treeObj'
*/
Int_t TMusrRunHeader::ObjectPresent(vector<TObjArray*> &content, TString &path)
bool TMusrRunHeader::UpdateFolder(TObject *treeObj, TString path)
{
for (UInt_t i=0; i<content.size(); i++) {
if (content[i]->GetName() == path) {
return (Int_t)i;
}
if (path.First('/') == -1) // only value element left, hence nothing to be done
return true;
TString str = GetFirst(path, '/');
TObject *obj = treeObj->FindObject(str);
// remove the first path element
if (!RemoveFirst(path, '/')) {
cerr << endl << ">> TMusrRunHeader::FillFolder(): **ERROR** couldn't tokenize path!!" << endl;
return false;
}
return -1;
if (!obj) { // required object not present, create it
TObjArray *oarray = new TObjArray();
if (!oarray) {
cerr << endl << ">> TMusrRunHeader::FillFolder(): **ERROR** couldn't create header structure!!" << endl;
return false;
}
// set the name of the new TObjArray
oarray->SetName(str);
if (!strcmp(treeObj->ClassName(), "TFolder"))
((TFolder*)treeObj)->Add(oarray);
else // it is a TObjArray
((TObjArray*)treeObj)->AddLast(oarray);
return UpdateFolder(oarray, path);
} else { // object present, hence check rest of the path
return UpdateFolder(obj, path);
}
}
//--------------------------------------------------------------------------
// FindObject (private)
//--------------------------------------------------------------------------
/**
* <p>Check if 'path' is present in 'treeObj'
*
* <p><b>return:</b>
* - pointer to the 'path' object if present
* - otherwise return 0
*
* \param treeObj to be searched
* \param path searched for within 'treeObj'
*/
TObject* TMusrRunHeader::FindObject(TObject *treeObj, TString path)
{
Ssiz_t pos;
TObject *obj=0;
// make sure that treeObj is either TFolder or TObjArray
if (strcmp(treeObj->ClassName(), "TFolder") && strcmp(treeObj->ClassName(), "TObjArray"))
return obj;
pos = path.First('/');
if (pos == -1) { // i.e. no sub-paths anymore
obj = treeObj->FindObject(path);
return obj;
} else { // sub-paths present
TString objName = GetFirst(path, '/'); // get first token of the path <objName0>/<objName1>/.../<objNameN>
obj = treeObj->FindObject(objName);
if (obj) { // object found, check for subPath object
RemoveFirst(path, '/'); // remove first tokens of the path
return FindObject(obj, path);
} else { // object not found
return obj;
}
}
}
//--------------------------------------------------------------------------
@ -1536,22 +1605,36 @@ TObjString TMusrRunHeader::GetHeaderString(UInt_t idx)
// RemoveFirst (private)
//--------------------------------------------------------------------------
/**
* <p>
* <p>Removes the first junk of a string up to 'splitter'. If 'splitter' is
* NOT present in the string, the string stays untouched and the routine
* returns false.
*
* \param str
* \param splitter
* \param str string to be truncated
* \param splitter the start of the string up to the splitter character removed
*/
void TMusrRunHeader::RemoveFirst(TString &str, const char splitter)
bool TMusrRunHeader::RemoveFirst(TString &str, const char splitter)
{
Ssiz_t idx = str.First(splitter);
if (idx == -1)
return false;
str.Remove(0, idx+1);
return true;
}
//--------------------------------------------------------------------------
// GetFirst (private)
//--------------------------------------------------------------------------
/**
* <p>
* <p>Assuming a string built like 'this/is/a/string:with:diffrent:splitters'.
* Using as splitter '/', this routine would return 'this', it means get from str
* everything up to the first occurance of splitter. If splitter would be ':'
* in this example, the return string would be 'this/is/a/string'.
*
* <p>If splitter is <b>not</b> present in str the original str is returned.
*
* <p><b>return:</b> first part of up to the splitter in struct
*
* \param str
* \param splitter
@ -1561,71 +1644,10 @@ TString TMusrRunHeader::GetFirst(TString &str, const char splitter)
TString result = str;
Ssiz_t idx = str.First(splitter);
result.Remove(idx, str.Length());
if (idx != -1)
result.Remove(idx, str.Length());
return result;
}
//--------------------------------------------------------------------------
// AddSubTrees (private)
//--------------------------------------------------------------------------
/**
* <p>
*
* \param content
* \param pathName
*/
void TMusrRunHeader::AddSubTrees(TObjArray *content, TString pathName)
{
// check if element is already present
TString objName = GetFirst(pathName, '/');
if (!content->FindObject(objName.Data())) { // object array not present yet, add it
TObjArray *oarray = new TObjArray();
oarray->SetName(objName);
content->AddLast(oarray);
}
// check if more sub trees are needed
TObjArray *tok = pathName.Tokenize('/');
if (tok->GetEntries() > 2) { // still sub trees present
RemoveFirst(pathName, '/');
AddSubTrees((TObjArray*)content->FindObject(objName.Data()), pathName);
}
if (tok)
delete tok;
}
//--------------------------------------------------------------------------
// SetSubTreeObject (private)
//--------------------------------------------------------------------------
/**
* <p>
*
* \param content
* \param ostr
*/
void TMusrRunHeader::SetSubTreeObject(TObjArray *content, TObjString ostr, Int_t idx)
{
TObjArray *tok = fPathNameOrder[idx].Tokenize('/');
TObjArray *pos = content;
for (Int_t i=1; i<tok->GetEntries()-1; i++) {
pos = (TObjArray*)pos->FindObject(((TObjString*)tok->At(i))->GetString()); // go down the proper tree
if (pos == 0) {
cerr << endl << "TMusrRunHeader::SetSubTreeObject(): **ERROR** couldn't reach requested path: " << fPathNameOrder[idx];
if (tok)
delete tok;
return;
}
}
TObjString *value = new TObjString();
value = (TObjString*)ostr.Clone();
pos->AddLast(value);
if (tok)
delete tok;
}
// end ---------------------------------------------------------------------

View File

@ -32,6 +32,9 @@
#ifndef TMUSRRUNHEADER_H
#define TMUSRRUNHEADER_H
#include <vector>
using namespace std;
#include <TDatime.h>
#include <TObject.h>
#include <TQObject.h>
@ -122,8 +125,8 @@ private:
class TMusrRunHeader : public TObject
{
public:
TMusrRunHeader();
TMusrRunHeader(const char *fileName);
TMusrRunHeader(bool quite=false);
TMusrRunHeader(const char *fileName, bool quite=false);
virtual ~TMusrRunHeader();
virtual TString GetFileName() { return fFileName; }
@ -155,6 +158,7 @@ public:
virtual void DrawHeader();
private:
bool fQuite;
TString fFileName;
TString fVersion;
@ -166,7 +170,7 @@ private:
vector< TMusrRunObject<TIntVector> > fIntVectorObj;
vector< TMusrRunObject<TDoubleVector> > fDoubleVectorObj;
vector< TString > fPathNameOrder; ///< keeps the path-name as they or set and hence its ordering
vector< TString > fPathNameOrder; ///< keeps the path-name as they were created in ordered to keep ordering
virtual void Init(TString str="n/a");
virtual void CleanUp();
@ -179,13 +183,12 @@ private:
virtual TString GetStrValue(TString str);
virtual TString GetType(TString str);
virtual Int_t ObjectPresent(vector<TObjArray*> &content, TString &path);
virtual bool UpdateFolder(TObject *treeObj, TString path);
virtual TObject* FindObject(TObject *treeObj, TString path);
virtual TObjString GetHeaderString(UInt_t idx);
virtual void RemoveFirst(TString &str, const char splitter);
virtual bool RemoveFirst(TString &str, const char splitter);
virtual TString GetFirst(TString &str, const char splitter);
virtual void AddSubTrees(TObjArray *content, TString pathName);
virtual void SetSubTreeObject(TObjArray *content, TObjString ostr, Int_t idx);
ClassDef(TMusrRunHeader, 1)
};

View File

@ -135,7 +135,6 @@ void dumpObjArray(TObjArray *obj, UInt_t offset)
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
@ -309,6 +308,11 @@ void getLabel(TString entry, TString &label)
label.Remove(0, start+2);
label.Remove(end-start-2, label.Length());
// replace spaces through underscores
label.ReplaceAll(' ', '_');
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
}

View File

@ -220,10 +220,6 @@ 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)) {