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;
+}