From bbbab12a1a01c4e662edc97bc11ab05de5606b5d Mon Sep 17 00:00:00 2001 From: nemu Date: Mon, 19 Sep 2011 14:51:15 +0000 Subject: [PATCH] some improvement on new PSI-ROOT header --- src/tests/PsiRoot/Makefile | 25 +- src/tests/PsiRoot/TPsiRunHeader.cpp | 770 ++++++++++++++++++---- src/tests/PsiRoot/TPsiRunHeader.h | 32 +- src/tests/PsiRoot/psi_root.xml | 88 ++- src/tests/PsiRoot/psi_root_test.xml | 85 +++ src/tests/PsiRoot/psi_runHeader_test.cpp | 169 +++-- src/tests/PsiRoot/read_psi_runHeader.cpp | 132 ++++ src/tests/PsiRoot/write_psi_runHeader.cpp | 233 +++++++ 8 files changed, 1358 insertions(+), 176 deletions(-) create mode 100644 src/tests/PsiRoot/psi_root_test.xml create mode 100644 src/tests/PsiRoot/read_psi_runHeader.cpp create mode 100644 src/tests/PsiRoot/write_psi_runHeader.cpp diff --git a/src/tests/PsiRoot/Makefile b/src/tests/PsiRoot/Makefile index a58f77ba..fe2d6bc2 100644 --- a/src/tests/PsiRoot/Makefile +++ b/src/tests/PsiRoot/Makefile @@ -63,19 +63,34 @@ GLIBS = $(ROOTGLIBS) -lXMLParser # PSI libs PSILIBS = -lTPsiRunHeader -EXEC = psi_runHeader_test +EXEC = +EXEC += psi_runHeader_test +EXEC += write_psi_runHeader +EXEC += read_psi_runHeader # some definitions: headers (used to generate *Dict* stuff), sources, objects,... OBJS = -OBJS += $(EXEC).o +OBJS += psi_runHeader_test.o +OBJS += write_psi_runHeader.o +OBJS += read_psi_runHeader.o # make the executable: # all: $(EXEC) -$(EXEC): $(OBJS) - @echo "---> Building $(EXEC) ..." - $(LD) $(OBJS) -o $(EXEC) $(GLIBS) $(PSILIBS) +psi_runHeader_test: psi_runHeader_test.o + @echo "---> Building psi_runHeader_test ..." + $(LD) psi_runHeader_test.o -o psi_runHeader_test $(GLIBS) $(PSILIBS) + @echo "done" + +write_psi_runHeader: write_psi_runHeader.o + @echo "---> Building write_psi_runHeader ..." + $(LD) write_psi_runHeader.o -o write_psi_runHeader $(GLIBS) $(PSILIBS) + @echo "done" + +read_psi_runHeader: read_psi_runHeader.o + @echo "---> Building read_psi_runHeader ..." + $(LD) read_psi_runHeader.o -o read_psi_runHeader $(GLIBS) $(PSILIBS) @echo "done" # clean up: remove all object file (and core files) diff --git a/src/tests/PsiRoot/TPsiRunHeader.cpp b/src/tests/PsiRoot/TPsiRunHeader.cpp index 9ec7113b..1ccf7ee6 100644 --- a/src/tests/PsiRoot/TPsiRunHeader.cpp +++ b/src/tests/PsiRoot/TPsiRunHeader.cpp @@ -70,12 +70,12 @@ TPsiRunProperty::TPsiRunProperty() /** *

Constructor. * - * \param name - * \param demand - * \param value - * \param error - * \param unit - * \param description + * \param label of the physical property, e.g. 'Sample Temperature' + * \param demand value of the physical property + * \param value measured value of the physical property + * \param error estimated error of the physical property + * \param unit of the physical property, e.g. 'K'. + * \param description additional more detailed description of the physical property */ TPsiRunProperty::TPsiRunProperty(TString label, Double_t demand, Double_t value, Double_t error, TString unit, TString description) : fLabel(label), fDemand(demand), fValue(value), fError(error), fUnit(unit) @@ -92,16 +92,117 @@ TPsiRunProperty::TPsiRunProperty(TString label, Double_t demand, Double_t value, /** *

Constructor. * - * \param name - * \param value - * \param unit + * \param label of the physical property, e.g. 'Sample Temperature' + * \param demand value of the physical property + * \param value measured value of the physical property + * \param unit of the physical property, e.g. 'K'. + * \param description additional more detailed description of the physical property */ -TPsiRunProperty::TPsiRunProperty(TString label, Double_t value, TString unit) : +TPsiRunProperty::TPsiRunProperty(TString label, Double_t demand, Double_t value, TString unit, TString description) : + fLabel(label), fDemand(demand), fValue(value), fUnit(unit) +{ + fError = PRH_UNDEFINED; + if (description.IsWhitespace()) + fDescription = "n/a"; + else + fDescription = description; +} + +//-------------------------------------------------------------------------- +// Constructor +//-------------------------------------------------------------------------- +/** + *

Constructor. + * + * \param label of the physical property, e.g. 'Sample Temperature' + * \param value measured value of the physical property + * \param unit of the physical property, e.g. 'K'. + * \param description additional more detailed description of the physical property + */ +TPsiRunProperty::TPsiRunProperty(TString label, Double_t value, TString unit, TString description) : fLabel(label), fValue(value), fUnit(unit) { fDemand = PRH_UNDEFINED; fError = PRH_UNDEFINED; - fDescription = "n/a"; + if (description.IsWhitespace()) + fDescription = "n/a"; + else + fDescription = description; +} + +//-------------------------------------------------------------------------- +// Set (public) +//-------------------------------------------------------------------------- +/** + *

set a physical property. + * + * \param label of the physical property, e.g. 'Sample Temperature' + * \param demand value of the physical property + * \param value measured value of the physical property + * \param error estimated error of the physical property + * \param unit of the physical property, e.g. 'K'. + * \param description additional more detailed description of the physical property + */ +void TPsiRunProperty::Set(TString label, Double_t demand, Double_t value, Double_t error, TString unit, TString description) +{ + fLabel = label; + fDemand = demand; + fValue = value; + fError = error; + fUnit = unit; + if (description.IsWhitespace()) + fDescription = "n/a"; + else + fDescription = description; +} + +//-------------------------------------------------------------------------- +// Set (public) +//-------------------------------------------------------------------------- +/** + *

set a physical property. + * + * \param label of the physical property, e.g. 'Sample Temperature' + * \param demand value of the physical property + * \param value measured value of the physical property + * \param unit of the physical property, e.g. 'K'. + * \param description additional more detailed description of the physical property + */ +void TPsiRunProperty::Set(TString label, Double_t demand, Double_t value, TString unit, TString description) +{ + fLabel = label; + fDemand = demand; + fValue = value; + fError = PRH_UNDEFINED; + fUnit = unit; + if (description.IsWhitespace()) + fDescription = "n/a"; + else + fDescription = description; +} + +//-------------------------------------------------------------------------- +// Set (public) +//-------------------------------------------------------------------------- +/** + *

set a physical property. + * + * \param label of the physical property, e.g. 'Sample Temperature' + * \param value measured value of the physical property + * \param unit of the physical property, e.g. 'K'. + * \param description additional more detailed description of the physical property + */ +void TPsiRunProperty::Set(TString label, Double_t value, TString unit, TString description) +{ + fLabel = label; + fDemand = PRH_UNDEFINED; + fValue = value; + fError = PRH_UNDEFINED; + fUnit = unit; + if (description.IsWhitespace()) + fDescription = "n/a"; + else + fDescription = description; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -319,13 +420,13 @@ ClassImp(TPsiRunHeader) /** *

Constructor. */ -TPsiRunHeader::TPsiRunHeader() +TPsiRunHeader::TPsiRunHeader(const char *headerDefinition) : fHeaderDefinition(headerDefinition) { TSAXParser *saxParser = new TSAXParser(); TPsiStartupHandler *startupHandler = new TPsiStartupHandler(); saxParser->ConnectToHandler("TPsiStartupHandler", startupHandler); - Int_t status = saxParser->ParseFile("./psi_root.xml"); + Int_t status = saxParser->ParseFile(headerDefinition); if (status) { // error // not clear what to do yet ... @@ -379,16 +480,23 @@ TPsiRunHeader::~TPsiRunHeader() Bool_t TPsiRunHeader::IsValid(Bool_t strict) { Bool_t result = true; + TIntVector found; Int_t count = 0; + found.resize(fEntry.size()); + for (UInt_t i=0; i> **ERROR** found entry: " << fEntry[i].GetPathName() << " should be a 'TString' but is defined as " << fEntry[i].GetType().Data() << endl; + cerr << endl << ">> **ERROR** found entry: " << fEntry[i].GetPathName() << " is 'TString' (according to header/root-file) but is defined as '" << fEntry[i].GetType().Data() << "' (XML)" << endl; return false; } } @@ -396,10 +504,11 @@ Bool_t TPsiRunHeader::IsValid(Bool_t strict) for (UInt_t j=0; j> **ERROR** found entry: " << fEntry[i].GetPathName() << " should be a 'Int_t' but is defined as " << fEntry[i].GetType().Data() << endl; + cerr << endl << ">> **ERROR** found entry: " << fEntry[i].GetPathName() << " is 'Int_t' (according to header/root-file) but is defined as '" << fEntry[i].GetType().Data() << "' (XML)" << endl; return false; } } @@ -407,10 +516,11 @@ Bool_t TPsiRunHeader::IsValid(Bool_t strict) for (UInt_t j=0; j> **ERROR** found entry: " << fEntry[i].GetPathName() << " should be a 'TPsiRunProperty' but is defined as " << fEntry[i].GetType().Data() << endl; + cerr << endl << ">> **ERROR** found entry: " << fEntry[i].GetPathName() << " is 'TPsiRunProperty' (according to header/root-file) but is defined as '" << fEntry[i].GetType().Data() << "' (XML)" << endl; return false; } } @@ -418,10 +528,11 @@ Bool_t TPsiRunHeader::IsValid(Bool_t strict) for (UInt_t j=0; j> **ERROR** found entry: " << fEntry[i].GetPathName() << " should be a 'TStringVector' but is defined as " << fEntry[i].GetType().Data() << endl; + cerr << endl << ">> **ERROR** found entry: " << fEntry[i].GetPathName() << " is 'TStringVector' (according to header/root-file) but is defined as '" << fEntry[i].GetType().Data() << "' (XML)" << endl; return false; } } @@ -429,10 +540,11 @@ Bool_t TPsiRunHeader::IsValid(Bool_t strict) for (UInt_t j=0; j> **ERROR** found entry: " << fEntry[i].GetPathName() << " should be a 'TIntVector' but is defined as " << fEntry[i].GetType().Data() << endl; + cerr << endl << ">> **ERROR** found entry: " << fEntry[i].GetPathName() << " is 'TIntVector' (according to header/root-file) but is defined as '" << fEntry[i].GetType().Data() << "' (XML)" << endl; return false; } } @@ -441,17 +553,30 @@ Bool_t TPsiRunHeader::IsValid(Bool_t strict) if (count != (Int_t)fEntry.size()) { if (strict) { result = false; - cerr << endl << ">> **ERROR** only found " << count << " entries. " << fEntry.size() << " are required!" << endl; + cerr << endl << ">> **ERROR** in validation: only found " << count << " entries. " << fEntry.size() << " are required!" << endl; } else { - cerr << endl << ">> **WARNING** only found " << count << " entries. " << fEntry.size() << " are required!" << endl; + cerr << endl << ">> **WARNING** in validation: only found " << count << " entries. " << fEntry.size() << " are required!" << endl; } } + for (UInt_t i=0; i> **ERROR** "; + } else { + cerr << endl << ">> **WARNING** "; + } + cerr << "Missing required entry: " << fEntry[i].GetPathName().Data() << ", type=" << fEntry[i].GetType().Data(); + } + } + + found.clear(); + return result; } //-------------------------------------------------------------------------- -// Get (public) +// GetHeaderInfo (public) //-------------------------------------------------------------------------- /** *

Get PSI-ROOT header information of 'path'. @@ -459,7 +584,7 @@ Bool_t TPsiRunHeader::IsValid(Bool_t strict) * \param requestedPath of the PSI-ROOT header, e.g. RunInfo * \param content of the requested PSI-ROOT header. */ -void TPsiRunHeader::Get(TString requestedPath, TObjArray &content) +void TPsiRunHeader::GetHeaderInfo(TString requestedPath, TObjArray &content) { // make sure content is initialized content.Delete(); @@ -494,29 +619,49 @@ void TPsiRunHeader::Get(TString requestedPath, TObjArray &content) prop = fPsiRunPropertyObj[j].GetValue(); Int_t digit, digit_d; if ((prop.GetDemand() != PRH_UNDEFINED) && (prop.GetValue() != PRH_UNDEFINED) && (prop.GetError() != PRH_UNDEFINED) && - (prop.GetUnit() != "n/a") && (prop.GetDescription() != "n/a")) { + (prop.GetUnit() != "n/a")) { // +- ; SP: [; ] digit = GetDecimalPlace(prop.GetError()); digit_d = GetLeastSignificantDigit(prop.GetDemand()); - 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 if ((prop.GetDemand() != PRH_UNDEFINED) && (prop.GetValue() != PRH_UNDEFINED) && (prop.GetError() != PRH_UNDEFINED) && - (prop.GetUnit() != "n/a") && (prop.GetDescription() == "n/a")) { - digit = GetDecimalPlace(prop.GetError()); - digit_d = GetLeastSignificantDigit(prop.GetDemand()); - 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()); + 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() == PRH_UNDEFINED) && (prop.GetValue() != PRH_UNDEFINED) && (prop.GetError() != PRH_UNDEFINED) && - (prop.GetUnit() != "n/a") && (prop.GetDescription() == "n/a")) { + (prop.GetUnit() != "n/a")) { // +- ; [; ] digit = GetDecimalPlace(prop.GetError()); - fmt.Form("%%s: %%.%dlf +- %%.%dlf %%s", digit, digit); - tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetError(), prop.GetUnit().Data()); + 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() == PRH_UNDEFINED) && (prop.GetValue() != PRH_UNDEFINED) && (prop.GetError() == PRH_UNDEFINED) && - (prop.GetUnit() != "n/a") && (prop.GetDescription() == "n/a")) { + (prop.GetUnit() != "n/a")) { // [; ] digit = GetLeastSignificantDigit(prop.GetValue()); - fmt.Form("%%s: %%.%dlf %%s", digit); - tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetUnit().Data()); + 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() != PRH_UNDEFINED) && (prop.GetValue() != PRH_UNDEFINED) && (prop.GetError() == PRH_UNDEFINED) && + (prop.GetUnit() != "n/a")) { // ; SP: [; ] + 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", count++, tstr.Data()); tostr = new TObjString(str); @@ -598,29 +743,47 @@ void TPsiRunHeader::Get(TString requestedPath, TObjArray &content) prop = fPsiRunPropertyObj[i].GetValue(); Int_t digit, digit_d; if ((prop.GetDemand() != PRH_UNDEFINED) && (prop.GetValue() != PRH_UNDEFINED) && (prop.GetError() != PRH_UNDEFINED) && - (prop.GetUnit() != "n/a") && (prop.GetDescription() != "n/a")) { + (prop.GetUnit() != "n/a")) { // +- ; SP: [; ] digit = GetDecimalPlace(prop.GetError()); digit_d = GetLeastSignificantDigit(prop.GetDemand()); - 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 if ((prop.GetDemand() != PRH_UNDEFINED) && (prop.GetValue() != PRH_UNDEFINED) && (prop.GetError() != PRH_UNDEFINED) && - (prop.GetUnit() != "n/a") && (prop.GetDescription() == "n/a")) { - digit = GetDecimalPlace(prop.GetError()); - digit_d = GetLeastSignificantDigit(prop.GetDemand()); - 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()); + 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() == PRH_UNDEFINED) && (prop.GetValue() != PRH_UNDEFINED) && (prop.GetError() != PRH_UNDEFINED) && - (prop.GetUnit() != "n/a") && (prop.GetDescription() == "n/a")) { + (prop.GetUnit() != "n/a")) { // +- [; ] digit = GetDecimalPlace(prop.GetError()); - fmt.Form("%%s: %%.%dlf +- %%.%dlf %%s", digit, digit); - tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetError(), prop.GetUnit().Data()); + 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() == PRH_UNDEFINED) && (prop.GetValue() != PRH_UNDEFINED) && (prop.GetError() == PRH_UNDEFINED) && - (prop.GetUnit() != "n/a") && (prop.GetDescription() == "n/a")) { + (prop.GetUnit() != "n/a") && (prop.GetDescription() == "n/a")) { // [; ] digit = GetLeastSignificantDigit(prop.GetValue()); - fmt.Form("%%s: %%.%dlf %%s", digit); - tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetUnit().Data()); + 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() != PRH_UNDEFINED) && (prop.GetValue() != PRH_UNDEFINED) && (prop.GetError() == PRH_UNDEFINED) && + (prop.GetUnit() != "n/a")) { // ; SP: [; ] + 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", count++, tstr.Data()); tostr = new TObjString(str); @@ -674,6 +837,116 @@ void TPsiRunHeader::Get(TString requestedPath, TObjArray &content) content.SetName(requestedPath); } +//-------------------------------------------------------------------------- +// GetValue (public) +//-------------------------------------------------------------------------- +/** + *

Get TString 'value'. + * + * \param pathName path/name within the header, e.g. RunInfo/Run Title + * \param value TString return value + * \param ok flag telling if the TString value was found + */ +void TPsiRunHeader::GetValue(TString pathName, TString &value, Bool_t &ok) +{ + ok = false; + + for (UInt_t i=0; iGet Int_t 'value'. + * + * \param pathName path/name within the header, e.g. RunInfo/Run Title + * \param value Int_t return value + * \param ok flag telling if the Int_t value was found + */ +void TPsiRunHeader::GetValue(TString pathName, Int_t &value, Bool_t &ok) +{ + ok = false; + + for (UInt_t i=0; iGet TPsiRunProperty 'value'. + * + * \param pathName path/name within the header, e.g. RunInfo/Run Title + * \param value TPsiRunProperty return value + * \param ok flag telling if the TPsiRunProperty value was found + */ +void TPsiRunHeader::GetValue(TString pathName, TPsiRunProperty &value, Bool_t &ok) +{ + ok = false; + + for (UInt_t i=0; iGet TStringVector 'value'. + * + * \param pathName path/name within the header, e.g. RunInfo/Run Title + * \param value TStringVector return value + * \param ok flag telling if the TStringVector value was found + */ +void TPsiRunHeader::GetValue(TString pathName, TStringVector &value, Bool_t &ok) +{ + ok = false; + + for (UInt_t i=0; iGet TIntVector 'value'. + * + * \param pathName path/name within the header, e.g. RunInfo/Run Title + * \param value TIntVector return value + * \param ok flag telling if the TIntVector value was found + */ +void TPsiRunHeader::GetValue(TString pathName, TIntVector &value, Bool_t &ok) +{ + ok = false; + + for (UInt_t i=0; iSet TString 'value'. * * \param pathName path/name within the header, e.g. RunInfo/Run Title - * \param type of the object * \param value of the entry */ -void TPsiRunHeader::Set(TString pathName, TString type, TString value) +void TPsiRunHeader::Set(TString pathName, TString value) { // check if pathName is already set, and if not add it as a new entry UInt_t i=0; for (i=0; i> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl; - fStringObj[i].SetType(type); + fStringObj[i].SetType("TString"); fStringObj[i].SetValue(value); break; } @@ -699,7 +971,7 @@ void TPsiRunHeader::Set(TString pathName, TString type, TString value) // if not found in the previous loop, it is a new object if (i == fStringObj.size()) { - TPsiRunObject obj(pathName, type, value); + TPsiRunObject obj(pathName, "TString", value); fStringObj.push_back(obj); } } @@ -711,17 +983,16 @@ void TPsiRunHeader::Set(TString pathName, TString type, TString value) *

Set Int_t 'value'. * * \param pathName path/name within the header, e.g. RunInfo/Run number - * \param type of the object * \param value of the entry */ -void TPsiRunHeader::Set(TString pathName, TString type, Int_t value) +void TPsiRunHeader::Set(TString pathName, Int_t value) { // check if pathName is already set, and if not add it as a new entry UInt_t i=0; for (i=0; i> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl; - fIntObj[i].SetType(type); + fIntObj[i].SetType("Int_t"); fIntObj[i].SetValue(value); break; } @@ -729,7 +1000,7 @@ void TPsiRunHeader::Set(TString pathName, TString type, Int_t value) // if not found in the previous loop, it is a new object if (i == fIntObj.size()) { - TPsiRunObject obj(pathName, type, value); + TPsiRunObject obj(pathName, "Int_t", value); fIntObj.push_back(obj); } } @@ -741,17 +1012,16 @@ void TPsiRunHeader::Set(TString pathName, TString type, Int_t value) *

Set TPsiRunProperty 'value'. * * \param pathName path/name within the header, e.g. RunInfo/Muon Beam Momentum - * \param type of the object * \param value of the entry */ -void TPsiRunHeader::Set(TString pathName, TString type, TPsiRunProperty value) +void TPsiRunHeader::Set(TString pathName, TPsiRunProperty value) { // check if pathName is already set, and if not add it as a new entry UInt_t i=0; for (i=0; i> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl; - fPsiRunPropertyObj[i].SetType(type); + fPsiRunPropertyObj[i].SetType("TPsiRunProperty"); fPsiRunPropertyObj[i].SetValue(value); break; } @@ -759,7 +1029,7 @@ void TPsiRunHeader::Set(TString pathName, TString type, TPsiRunProperty value) // if not found in the previous loop, it is a new object if (i == fPsiRunPropertyObj.size()) { - TPsiRunObject obj(pathName, type, value); + TPsiRunObject obj(pathName, "TPsiRunProperty", value); fPsiRunPropertyObj.push_back(obj); } } @@ -771,17 +1041,16 @@ void TPsiRunHeader::Set(TString pathName, TString type, TPsiRunProperty value) *

Set TStringVector 'value'. * * \param pathName path/name within the header, e.g. RunInfo/Histo names - * \param type of the object * \param value of the entry */ -void TPsiRunHeader::Set(TString pathName, TString type, TStringVector value) +void TPsiRunHeader::Set(TString pathName, TStringVector value) { // check if pathName is already set, and if not add it as a new entry UInt_t i=0; for (i=0; i> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl; - fStringVectorObj[i].SetType(type); + fStringVectorObj[i].SetType("TStringVector"); fStringVectorObj[i].SetValue(value); break; } @@ -789,7 +1058,7 @@ void TPsiRunHeader::Set(TString pathName, TString type, TStringVector value) // if not found in the previous loop, it is a new object if (i == fStringVectorObj.size()) { - TPsiRunObject obj(pathName, type, value); + TPsiRunObject obj(pathName, "TStringVector", value); fStringVectorObj.push_back(obj); } } @@ -801,17 +1070,16 @@ void TPsiRunHeader::Set(TString pathName, TString type, TStringVector value) *

Set TIntVector 'value'. * * \param pathName path/name within the header, e.g. RunInfo/Time Zero Bin - * \param type of the object * \param value of the entry */ -void TPsiRunHeader::Set(TString pathName, TString type, TIntVector value) +void TPsiRunHeader::Set(TString pathName, TIntVector value) { // check if pathName is already set, and if not add it as a new entry UInt_t i=0; for (i=0; i> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl; - fIntVectorObj[i].SetType(type); + fIntVectorObj[i].SetType("TIntVector"); fIntVectorObj[i].SetValue(value); break; } @@ -819,11 +1087,245 @@ void TPsiRunHeader::Set(TString pathName, TString type, TIntVector value) // if not found in the previous loop, it is a new object if (i == fIntVectorObj.size()) { - TPsiRunObject obj(pathName, type, value); + TPsiRunObject obj(pathName, "TIntVector", value); fIntVectorObj.push_back(obj); } } +//-------------------------------------------------------------------------- +// ExtractHeaderInformation (public) +//-------------------------------------------------------------------------- +/** + *

+ * + * \param headerInfo + * \param requestedPath + */ +Bool_t TPsiRunHeader::ExtractHeaderInformation(TObjArray *headerInfo, TString requestedPath) +{ + TString name(""), path(""), pathName(""), str(""), strValue(""); + TObjString *ostr = 0; + TObjArray *tokens = 0; + Bool_t required=false; + UInt_t idx; + Int_t intValue; + + // go through all entries of this header information from the PSI-ROOT file + for (Int_t i=0; iGetEntries(); i++) { + required=false; + ostr = dynamic_cast(headerInfo->At(i)); + str = ostr->GetString(); + // handle required entry + for (UInt_t j=0; j> **ERROR** Couldn't tokenize entry in Bool_t TPsiRunHeader::ExtractHeaderInformation(TObjArray *headerInfo, TString requestedPath)" << endl; + return false; + } + + switch (tokens->GetEntries()) { + case 2: + ostr = dynamic_cast(tokens->At(1)); + str = ostr->GetString(); + if (!str.Contains("SP:")) { // make sure that it is not a demand value token + prop.SetDescription(str); + } + break; + case 3: + ostr = dynamic_cast(tokens->At(2)); + str = ostr->GetString(); + break; + default: + break; + } + + if (tokens) { + delete tokens; + tokens = 0; + } + + // 2nd collect all the other properties, this is easier when first a potential description is removed + idx1 = strValue.Last(';'); + if (idx1 > 0) { + TString last(""); + for (Int_t i=idx1+2; i or SP: + if (!last.Contains("SP:")) { + str = ""; + for (Int_t i=0; i> **ERROR** Couldn't tokenize entry in Bool_t TPsiRunHeader::ExtractHeaderInformation(TObjArray *headerInfo, TString requestedPath)" << endl; + return false; + } + + switch (tokens->GetEntries()) { + case 2: // + ostr = dynamic_cast(tokens->At(0)); + str = ostr->GetString(); + prop.SetValue(str.Atof()); + ostr = dynamic_cast(tokens->At(1)); + str = ostr->GetString(); + prop.SetUnit(str); + break; + case 4: // +- , or ; SP: + ostr = dynamic_cast(tokens->At(0)); + str = ostr->GetString(); + prop.SetValue(str.Atof()); + ostr = dynamic_cast(tokens->At(1)); + str = ostr->GetString(); + if (str == "-") { // +- + ostr = dynamic_cast(tokens->At(2)); + str = ostr->GetString(); + prop.SetError(str.Atof()); + ostr = dynamic_cast(tokens->At(3)); + str = ostr->GetString(); + prop.SetUnit(str); + } else { // ; SP: + prop.SetUnit(str); + ostr = dynamic_cast(tokens->At(3)); + str = ostr->GetString(); + prop.SetDemand(str.Atof()); + } + break; + case 6: // +- ; SP: + ostr = dynamic_cast(tokens->At(0)); + str = ostr->GetString(); + prop.SetValue(str.Atof()); + ostr = dynamic_cast(tokens->At(2)); + str = ostr->GetString(); + prop.SetError(str.Atof()); + ostr = dynamic_cast(tokens->At(3)); + str = ostr->GetString(); + prop.SetUnit(str); + ostr = dynamic_cast(tokens->At(5)); + str = ostr->GetString(); + prop.SetDemand(str.Atof()); + break; + default: + break; + } + + if (tokens) { + delete tokens; + tokens = 0; + } + + Set(pathName, prop); + } else if (fEntry[idx].GetType() == "TStringVector") { + TStringVector svec; + tokens = strValue.Tokenize(";"); + if (tokens == 0) { + cerr << endl << ">> **ERROR** Couldn't tokenize entry in Bool_t TPsiRunHeader::ExtractHeaderInformation(TObjArray *headerInfo, TString requestedPath)" << endl; + return false; + } + for (Int_t i=0; iGetEntries(); i++) { + ostr = dynamic_cast(tokens->At(i)); + str = ostr->GetString(); + str.Remove(TString::kBoth, ' '); + svec.push_back(str); + } + if (tokens) { + delete tokens; + tokens = 0; + } + Set(pathName, svec); + } else if (fEntry[idx].GetType() == "TIntVector") { + TIntVector ivec; + tokens = strValue.Tokenize(";"); + if (tokens == 0) { + cerr << endl << ">> **ERROR** Couldn't tokenize entry in Bool_t TPsiRunHeader::ExtractHeaderInformation(TObjArray *headerInfo, TString requestedPath)" << endl; + return false; + } + for (Int_t i=0; iGetEntries(); i++) { + ostr = dynamic_cast(tokens->At(i)); + ivec.push_back(ostr->GetString().Atoi()); + } + if (tokens) { + delete tokens; + tokens = 0; + } + Set(pathName, ivec); + } + } + } + + // go through all entries of this header information from the PSI-ROOT file + for (Int_t i=0; iGetEntries(); i++) { + required=false; + ostr = dynamic_cast(headerInfo->At(i)); + str = ostr->GetString(); + // handle additional entries, i.e. not required entries + for (UInt_t j=0; j > fStringObj; vector< TPsiRunObject > fIntObj; vector< TPsiRunObject > fPsiRunPropertyObj; diff --git a/src/tests/PsiRoot/psi_root.xml b/src/tests/PsiRoot/psi_root.xml index aff18bd2..a63c9bb0 100644 --- a/src/tests/PsiRoot/psi_root.xml +++ b/src/tests/PsiRoot/psi_root.xml @@ -45,32 +45,104 @@ Int_t - RunInfo/Sample Temperature - TPsiRunProperty + RunInfo/Run Start Time + TString - RunInfo/Time Resolution - TPsiRunProperty + RunInfo/Run Stop Time + TString + + + RunInfo/Run Duration + Int_t + + + RunInfo/Laboratory + TString + + + RunInfo/Area + TString + + + RunInfo/Instrument + TString RunInfo/Muon Beam Momentum TPsiRunProperty + + RunInfo/Muon Species + TString + + + RunInfo/Setup + TString + + + RunInfo/Comment + TString + + + RunInfo/Sample Name + TString + + + RunInfo/Sample Temperature + TPsiRunProperty + + + RunInfo/Sample Magnetic Field + TPsiRunProperty + + + RunInfo/No of Histos + Int_t + RunInfo/Histo Names TStringVector + + RunInfo/Histo Length + Int_t + + + RunInfo/Time Resolution + TPsiRunProperty + RunInfo/Time Zero Bin TIntVector + + RunInfo/First Good Bin + TIntVector + + + RunInfo/Last Good Bin + TIntVector + + + RunInfo/Red-Green Offsets + TIntVector + + + RunInfo/Red-Green Description + TStringVector + SampleEnv/Cryo TString - SampleEnv/CF2 - TPsiRunProperty + SampleEnv/Insert + TString + + + SampleEnv/Orientation + TString MagFieldEnv/Name @@ -80,6 +152,10 @@ MagFieldEnv/Current TPsiRunProperty + + Scaler/Ip + Int_t + diff --git a/src/tests/PsiRoot/psi_root_test.xml b/src/tests/PsiRoot/psi_root_test.xml new file mode 100644 index 00000000..4b53c33c --- /dev/null +++ b/src/tests/PsiRoot/psi_root_test.xml @@ -0,0 +1,85 @@ + + + + This is a test PSI-ROOT header definition. + $Id$ + + + + + RunInfo + + + SampleEnv + + + MagFieldEnv + + + Beamline + + + Scaler + + + + + + RunInfo/Version + TString + + + RunInfo/Generator + TString + + + RunInfo/File Name + TString + + + RunInfo/Run Title + TString + + + RunInfo/Run Number + Int_t + + + RunInfo/Sample Temperature + TPsiRunProperty + + + RunInfo/Time Resolution + TPsiRunProperty + + + RunInfo/Muon Beam Momentum + TPsiRunProperty + + + RunInfo/Histo Names + TStringVector + + + RunInfo/Time Zero Bin + TIntVector + + + SampleEnv/Cryo + TString + + + SampleEnv/CF2 + TPsiRunProperty + + + MagFieldEnv/Name + TString + + + MagFieldEnv/Current + TPsiRunProperty + + + + diff --git a/src/tests/PsiRoot/psi_runHeader_test.cpp b/src/tests/PsiRoot/psi_runHeader_test.cpp index 808186ff..99e3119c 100644 --- a/src/tests/PsiRoot/psi_runHeader_test.cpp +++ b/src/tests/PsiRoot/psi_runHeader_test.cpp @@ -40,40 +40,48 @@ using namespace std; void psi_runHeader_test_syntax() { - cout << endl << "usage: psi_runHeader_test "; + cout << endl << "usage: psi_runHeader_test []"; cout << endl << " is the file name including the extention root, e.g. test.root"; + cout << endl << " is the header definition XML-file."; + cout << endl << " 'strict'=strict validation; otherwise=less strict validation."; cout << endl << endl; } int main(int argc, char *argv[]) { - if (argc != 2) { + if ((argc != 3) && (argc != 4)) { psi_runHeader_test_syntax(); return 1; } + Bool_t strict = false; + if (argc == 4) { + if (!strcmp(argv[3], "strict")) + strict = true; + } + // PSI Run Header object - TPsiRunHeader *header = new TPsiRunHeader(); - TPsiRunProperty *prop; + TPsiRunHeader *header = new TPsiRunHeader(argv[2]); + TPsiRunProperty prop; // run info - header->Set("RunInfo/Version", "TString", "$Id$"); - header->Set("RunInfo/Generator", "TString", "any2many"); - header->Set("RunInfo/File Name", "TString", "thisIsAFileName"); - header->Set("RunInfo/Run Title", "TString", "here comes the run title"); - header->Set("RunInfo/Run Number", "Int_t", 576); - header->Set("RunInfo/Run Number", "Int_t", 577); - header->Set("RunInfo/Run Start Time", "TString", "2011-04-19 14:25:22"); - header->Set("RunInfo/Run Stop Time", "TString", "2011-04-19 19:13:47"); + header->Set("RunInfo/Version", "$Id$"); + header->Set("RunInfo/Generator", "any2many"); + header->Set("RunInfo/File Name", "thisIsAFileName"); +// header->Set("RunInfo/Run Title", "here comes the run title"); + header->Set("RunInfo/Run Number", 576); + header->Set("RunInfo/Run Number", 577); + header->Set("RunInfo/Run Start Time", "2011-04-19 14:25:22"); + header->Set("RunInfo/Run Stop Time", "2011-04-19 19:13:47"); - prop = new TPsiRunProperty("Time Resolution", 0.193525, "ns"); - header->Set("RunInfo/Time Resolution", "TPsiRunProperty", *prop); + prop.Set("Time Resolution", 0.193525, "ns", "TDC 9999"); + header->Set("RunInfo/Time Resolution", prop); - prop = new TPsiRunProperty("Sample Temperature", 3.2, 3.20, 0.05, "K", "CF1"); - header->Set("RunInfo/Sample Temperature", "TPsiRunProperty", *prop); + prop.Set("Sample Temperature", 3.2, 3.21, 0.05, "K", "CF1"); + header->Set("RunInfo/Sample Temperature", prop); - prop = new TPsiRunProperty("Muon Beam Momentum", PRH_UNDEFINED, 28.1, PRH_UNDEFINED, "MeV/c"); - header->Set("RunInfo/Muon Beam Momentum", "TPsiRunProperty", *prop); + prop.Set("Muon Beam Momentum", PRH_UNDEFINED, 28.1, PRH_UNDEFINED, "MeV/c"); + header->Set("RunInfo/Muon Beam Momentum", prop); TStringVector detectorName; detectorName.push_back("left_down"); @@ -84,44 +92,58 @@ int main(int argc, char *argv[]) detectorName.push_back("right_up"); detectorName.push_back("bottom_down"); detectorName.push_back("bottom_up"); - header->Set("RunInfo/Histo Names", "TStringVector", detectorName); + header->Set("RunInfo/Histo Names", detectorName); TIntVector t0; for (UInt_t i=0; i<8; i++) t0.push_back(3419); - header->Set("RunInfo/Time Zero Bin", "TIntVector", t0); + header->Set("RunInfo/Time Zero Bin", t0); TStringVector dummyTest; dummyTest.push_back("dummy1"); dummyTest.push_back("dummy2"); dummyTest.push_back("dummy3"); - header->Set("RunInfo/Dummy Test", "TStringVector", dummyTest); + header->Set("RunInfo/Dummy Test", dummyTest); // sample environment - header->Set("SampleEnv/Cryo", "TString", "Konti-1"); - prop = new TPsiRunProperty("CF2", 3.2, 3.22, 0.04, "A"); - header->Set("SampleEnv/CF2", "TPsiRunProperty", *prop); + header->Set("SampleEnv/Cryo", "Konti-1"); - prop = new TPsiRunProperty("Dummy Prop", -2.0, -2.001, 0.002, "SI unit"); - header->Set("SampleEnv/Dummy Prop", "TPsiRunProperty", *prop); + prop.Set("CF2", 3.2, 3.22, 0.04, "K"); + header->Set("SampleEnv/CF2", prop); + + prop.Set("CF3", PRH_UNDEFINED, 3.27, 0.09, "K", "strange temperature"); + header->Set("SampleEnv/CF3", prop); + + prop.Set("CF4", 3.25, 3.28, "K"); + header->Set("SampleEnv/CF4", prop); + + prop.Set("CF5", 3.26, 3.29, "K", "another strange temperature"); + header->Set("SampleEnv/CF5", prop); + + prop.Set("Dummy Prop", -2.0, -2.001, 0.002, "SI-unit"); + header->Set("SampleEnv/Dummy Prop", prop); // magnetic field environment - header->Set("MagFieldEnv/Name", "TString", "Bpar"); - prop = new TPsiRunProperty("Current", 1.34, "A"); - header->Set("MagFieldEnv/Current", "TPsiRunProperty", *prop); + header->Set("MagFieldEnv/Name", "Bpar"); + prop.Set("Current", 1.34, "A"); + header->Set("MagFieldEnv/Current", prop); // beamline - header->Set("Beamline/WSX61a", "TString", "DAC = 3289, ADC = 0.800"); + header->Set("Beamline/WSX61a", "DAC = 3289, ADC = 0.800"); TIntVector dummyInt; for (UInt_t i=0; i<3; i++) dummyInt.push_back(i+1000); - header->Set("Beamline/Dummy Int", "TIntVector", dummyInt); + header->Set("Beamline/Dummy Int", dummyInt); // scaler - header->Set("Scaler/Ip", "Int_t", 12332123); + header->Set("Scaler/Ip", 12332123); - if (!header->IsValid()) { + if (!header->IsValid(strict)) { cerr << endl << ">> **ERROR** run header validation failed." << endl; + if (strict) { // clean up and quit + delete header; + return -1; + } } TFile *f = new TFile(argv[1], "RECREATE", "psi_runHeader_test"); @@ -135,23 +157,23 @@ int main(int argc, char *argv[]) gROOT->GetListOfBrowsables()->Add(runHeader, "RunHeaderInfo"); TObjArray runInfo; - header->Get("RunInfo", runInfo); + header->GetHeaderInfo("RunInfo", runInfo); runHeader->Add(&runInfo); TObjArray sampleEnv; - header->Get("SampleEnv", sampleEnv); + header->GetHeaderInfo("SampleEnv", sampleEnv); runHeader->Add(&sampleEnv); TObjArray magFieldEnv; - header->Get("MagFieldEnv", magFieldEnv); + header->GetHeaderInfo("MagFieldEnv", magFieldEnv); runHeader->Add(&magFieldEnv); TObjArray beamline; - header->Get("Beamline", beamline); + header->GetHeaderInfo("Beamline", beamline); runHeader->Add(&beamline); TObjArray scaler; - header->Get("Scaler", scaler); + header->GetHeaderInfo("Scaler", scaler); runHeader->Add(&scaler); runHeader->Write(); @@ -177,7 +199,7 @@ int main(int argc, char *argv[]) return -1; } - runInfo = 0; + runHeader = 0; f->GetObject("RunHeaderInfo", runHeader); if (runHeader == 0) { cerr << endl << ">> **ERROR** Couldn't get top folder RunHeaderInfo"; @@ -186,7 +208,7 @@ int main(int argc, char *argv[]) } TObjArray *oarray = 0; - header = new TPsiRunHeader(); + header = new TPsiRunHeader(argv[2]); // get RunHeader oarray = (TObjArray*) runHeader->FindObjectAny("RunInfo"); @@ -223,10 +245,73 @@ int main(int argc, char *argv[]) } header->ExtractHeaderInformation(oarray, "Scaler"); - header->DumpHeader(); - f->Close(); delete f; + if (!header->IsValid(strict)) { + cerr << endl << ">> **ERROR** run header validation failed." << endl; + if (strict) { // clean up and quit + delete header; + return -1; + } + } + + header->DumpHeader(); + + // get some information from the read file + cout << endl << "++++++++++++++++++++++++++++"; + cout << endl << ">> get header infos " << argv[1]; + cout << endl << "++++++++++++++++++++++++++++" << endl; + + TString str(""); + TStringVector strVec; + Int_t ival; + TIntVector ivec; + TPsiRunProperty prop1; + Bool_t ok; + + header->GetValue("RunInfo/Run Title", str, ok); + if (ok) + cout << endl << "Run Title: " << str.Data(); + else + cout << endl << "**ERROR** Couldn't obtain the 'Run Title'."; + + header->GetValue("RunInfo/Run Number", ival, ok); + if (ok) + cout << endl << "Run Number: " << ival; + 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; iGetValue("RunInfo/Time Zero Bin", ivec, ok); + if (ok) { + cout << endl << "Time Zero Bin: "; + for (UInt_t i=0; iGetValue("RunInfo/Sample Temperature", prop1, ok); + if (ok) { + cout << endl << "Sample Temperature: " << prop1.GetValue() << " +- " << prop1.GetError() << " " << prop1.GetUnit().Data() << "; SP: " << prop1.GetDemand() << "; " << prop1.GetDescription().Data(); + } else { + cout << endl << "**ERROR** Couldn't obtain the 'Sample Temperature'."; + } + + cout << endl << endl; + return 0; } diff --git a/src/tests/PsiRoot/read_psi_runHeader.cpp b/src/tests/PsiRoot/read_psi_runHeader.cpp new file mode 100644 index 00000000..0b26f50f --- /dev/null +++ b/src/tests/PsiRoot/read_psi_runHeader.cpp @@ -0,0 +1,132 @@ +/*************************************************************************** + + read_psi_runHeader.cpp + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007-2011 by Andreas Suter * + * andreas.suter@psi.ch * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +using namespace std; + +#include +#include +#include + +#include "TPsiRunHeader.h" + +void read_psi_runHeader_syntax() +{ + cout << endl << "usage: read_psi_runHeader []"; + cout << endl << " is the file name including the extention root, e.g. test.root"; + cout << endl << " is the header definition XML-file."; + cout << endl << " 'strict'=strict validation; otherwise=less strict validation."; + cout << endl << endl; +} + +int main(int argc, char *argv[]) +{ + if ((argc != 3) && (argc != 4)) { + read_psi_runHeader_syntax(); + return 1; + } + + Bool_t strict = false; + if (argc == 4) { + if (!strcmp(argv[3], "strict")) + strict = true; + } + + // read the file back and extract the header info + TFile *f = new TFile(argv[1], "READ", "read_psi_runHeader"); + if (f->IsZombie()) { + delete f; + return -1; + } + + TFolder *runHeader = 0; + f->GetObject("RunHeaderInfo", runHeader); + if (runHeader == 0) { + cerr << endl << ">> **ERROR** Couldn't get top folder RunHeaderInfo"; + f->Close(); + return -1; + } + + TObjArray *oarray = 0; + TPsiRunHeader *header = new TPsiRunHeader(argv[2]); + + // get RunHeader + oarray = (TObjArray*) runHeader->FindObjectAny("RunInfo"); + if (oarray == 0) { + cerr << endl << ">> **ERROR** Couldn't get RunInfo" << endl; + } + header->ExtractHeaderInformation(oarray, "RunInfo"); + + // get SampleEnv + oarray = (TObjArray*) runHeader->FindObjectAny("SampleEnv"); + if (oarray == 0) { + cerr << endl << ">> **ERROR** Couldn't get SampleEnv" << endl; + } + header->ExtractHeaderInformation(oarray, "SampleEnv"); + + // get MagFieldEnv + oarray = (TObjArray*) runHeader->FindObjectAny("MagFieldEnv"); + if (oarray == 0) { + cerr << endl << ">> **ERROR** Couldn't get MagFieldEnv" << endl; + } + header->ExtractHeaderInformation(oarray, "MagFieldEnv"); + + // get Beamline + oarray = (TObjArray*) runHeader->FindObjectAny("Beamline"); + if (oarray == 0) { + cerr << endl << ">> **ERROR** Couldn't get Beamline" << endl; + } + header->ExtractHeaderInformation(oarray, "Beamline"); + + // get Scaler + oarray = (TObjArray*) runHeader->FindObjectAny("Scaler"); + if (oarray == 0) { + cerr << endl << ">> **ERROR** Couldn't get Scaler" << endl; + } + header->ExtractHeaderInformation(oarray, "Scaler"); + + f->Close(); + delete f; + + if (!header->IsValid(strict)) { + cerr << endl << ">> **ERROR** run header validation failed." << endl; + if (strict) { // clean up and quit + delete header; + return -1; + } + } + + header->DumpHeader(); + + cout << endl << endl; + + return 0; +} diff --git a/src/tests/PsiRoot/write_psi_runHeader.cpp b/src/tests/PsiRoot/write_psi_runHeader.cpp new file mode 100644 index 00000000..3644548a --- /dev/null +++ b/src/tests/PsiRoot/write_psi_runHeader.cpp @@ -0,0 +1,233 @@ +/*************************************************************************** + + write_runHeader.cpp + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + $Id$ + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007-2011 by Andreas Suter * + * andreas.suter@psi.ch * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ + +#include +#include +#include + +#include +using namespace std; + +#include +#include +#include + +#include "TPsiRunHeader.h" + +void write_psi_runHeader_syntax() +{ + cout << endl << "usage: write_psi_runHeader []"; + cout << endl << " is the file name including the extention root, e.g. test.root"; + cout << endl << " is the header definition XML-file."; + cout << endl << " 'strict'=strict validation; otherwise=less strict validation."; + cout << endl << endl; +} + +int main(int argc, char *argv[]) +{ + if ((argc != 3) && (argc != 4)) { + write_psi_runHeader_syntax(); + return 1; + } + + Bool_t strict = false; + if (argc == 4) { + if (!strcmp(argv[3], "strict")) + strict = true; + } + + // PSI Run Header object + TPsiRunHeader *header = new TPsiRunHeader(argv[2]); + TPsiRunProperty prop; + + // run info + header->Set("RunInfo/Version", "$Id$"); + header->Set("RunInfo/Generator", "any2many"); + header->Set("RunInfo/File Name", "thisIsAFileName"); + header->Set("RunInfo/Run Title", "here comes the run title"); + header->Set("RunInfo/Run Number", 577); + + // run info - start/stop time and duration + TString startTime("2011-04-19 14:25:22"), stopTime("2011-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); + // calculate run duration + memset(&tm_start, 0, sizeof(tm_start)); + strptime(startTime.Data(), "%Y-%m-%d %H:%M:%S", &tm_start); + 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); + + 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/Comment", "nothing more to be said"); + header->Set("RunInfo/Sample Name", "the best ever"); + + prop.Set("Sample Temperature", 3.2, 3.21, 0.05, "K", "CF1"); + header->Set("RunInfo/Sample Temperature", prop); + + prop.Set("Sample Magnetic Field", 350.0, 350.002, 0.005, "G", "WXY"); + header->Set("RunInfo/Sample Magnetic Field", prop); + + 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.193525, "ns", "TDC 9999"); + header->Set("RunInfo/Time Resolution", prop); + + TIntVector t0; + for (UInt_t i=0; i<4; i++) t0.push_back(215+(Int_t)(5.0*(Double_t)rand()/(Double_t)RAND_MAX)); + header->Set("RunInfo/Time Zero Bin", t0); + for (UInt_t i=0; i<4; i++) t0[i] += 12; + header->Set("RunInfo/First Good Bin", t0); + for (UInt_t i=0; i<4; i++) t0[i] = 8191; + header->Set("RunInfo/Last Good Bin", t0); + + 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); + + 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); + + TStringVector dummyTest; + dummyTest.push_back("dummy1"); + dummyTest.push_back("dummy2"); + dummyTest.push_back("dummy3"); + header->Set("RunInfo/Dummy Test", dummyTest); + + // sample environment + header->Set("SampleEnv/Cryo", "Konti-1"); + header->Set("SampleEnv/Insert", "X123"); + header->Set("SampleEnv/Orientation", "c-axis perp spin, perp field. spin perp field"); + + prop.Set("CF2", 3.2, 3.22, 0.04, "K"); + header->Set("SampleEnv/CF2", prop); + + prop.Set("CF3", PRH_UNDEFINED, 3.27, 0.09, "K", "strange temperature"); + header->Set("SampleEnv/CF3", prop); + + prop.Set("CF4", 3.25, 3.28, "K"); + header->Set("SampleEnv/CF4", prop); + + prop.Set("CF5", 3.26, 3.29, "K", "another strange temperature"); + header->Set("SampleEnv/CF5", prop); + + prop.Set("Dummy Prop", -2.0, -2.001, 0.002, "SI-unit"); + header->Set("SampleEnv/Dummy Prop", prop); + + // magnetic field environment + header->Set("MagFieldEnv/Name", "Bpar"); + prop.Set("Current", 1.34, "A"); + header->Set("MagFieldEnv/Current", prop); + + // beamline + header->Set("Beamline/WSX61a", "DAC = 3289, ADC = 0.800"); + + TIntVector dummyInt; + for (UInt_t i=0; i<3; i++) dummyInt.push_back(i+1000); + header->Set("Beamline/Dummy Int", dummyInt); + + + // scaler + header->Set("Scaler/Ip", 12332123); + + if (!header->IsValid(strict)) { + cerr << endl << ">> **ERROR** run header validation failed." << endl; + if (strict) { // clean up and quit + delete header; + return -1; + } + } + + TFile *f = new TFile(argv[1], "RECREATE", "psi_runHeader_test"); + if (f->IsZombie()) { + delete f; + return -1; + } + + // root file header related things + TFolder *runHeader = gROOT->GetRootFolder()->AddFolder("RunHeaderInfo", "PSI Run Header Info"); + gROOT->GetListOfBrowsables()->Add(runHeader, "RunHeaderInfo"); + + TObjArray runInfo; + header->GetHeaderInfo("RunInfo", runInfo); + runHeader->Add(&runInfo); + + TObjArray sampleEnv; + header->GetHeaderInfo("SampleEnv", sampleEnv); + runHeader->Add(&sampleEnv); + + TObjArray magFieldEnv; + header->GetHeaderInfo("MagFieldEnv", magFieldEnv); + runHeader->Add(&magFieldEnv); + + TObjArray beamline; + header->GetHeaderInfo("Beamline", beamline); + runHeader->Add(&beamline); + + TObjArray scaler; + header->GetHeaderInfo("Scaler", scaler); + runHeader->Add(&scaler); + + runHeader->Write(); + + f->Close(); + + delete f; + f = 0; + + return 0; +}