handles now updating properly
This commit is contained in:
parent
fb5c5541f1
commit
59df2224ba
@ -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"/>
|
||||
|
221
src/tests/MusrRoot/MusrRootLEM.xsd
Normal file
221
src/tests/MusrRoot/MusrRootLEM.xsd
Normal 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>
|
@ -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 ---------------------------------------------------------------------
|
||||
|
@ -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)
|
||||
};
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user