diff --git a/src/tests/PsiRoot/TPsiRunHeader.cpp b/src/tests/PsiRoot/TPsiRunHeader.cpp
index fa1d5dc4..48baf852 100644
--- a/src/tests/PsiRoot/TPsiRunHeader.cpp
+++ b/src/tests/PsiRoot/TPsiRunHeader.cpp
@@ -65,9 +65,11 @@ ClassImp(TPsiRunProperty)
TPsiRunProperty::TPsiRunProperty()
{
fLabel = "n/a";
+ fDemand = 0.0;
fValue = 0.0;
fError = 0.0;
fUnit = "n/a";
+ fDescription = "n/a";
}
//--------------------------------------------------------------------------
@@ -81,9 +83,13 @@ TPsiRunProperty::TPsiRunProperty()
* \param error
* \param unit
*/
-TPsiRunProperty::TPsiRunProperty(TString &label, Double_t value, Double_t error, TString &unit) :
- fLabel(label), fValue(value), fError(error), fUnit(unit)
+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)
{
+ if (description.IsWhitespace())
+ fDescription = "n/a";
+ else
+ fDescription = description;
}
//--------------------------------------------------------------------------
@@ -132,6 +138,30 @@ TPsiRunHeader::~TPsiRunHeader()
fHeader.Delete();
}
+//--------------------------------------------------------------------------
+// GetProperty
+//--------------------------------------------------------------------------
+/**
+ *
Searches the property given by 'name'. If it is found, this property is
+ * returned, otherwise 0 is returned.
+ *
+ * \param name property name to look for.
+ */
+TPsiRunProperty* TPsiRunHeader::GetProperty(TString name)
+{
+ UInt_t i=0;
+
+ for (i=0; iGetEntries(); i++) {
- ostr = dynamic_cast(runHeader->At(i));
- str = ostr->GetString();
-
- name = TString("");
- unit = TString("");
-
- // 1st get the name
- idx = str.Index("-");
- str.Remove(0, idx+2);
- idx = str.Index(":");
- str.Remove(idx, str.Length());
- name = str;
-
- // 2nd get the value
- str = ostr->GetString();
- idx = str.Index(":");
- str.Remove(0, idx+2);
- idx = str.Index("+-");
- str.Remove(idx, str.Length());
- if (!str.IsFloat()) {
- cerr << endl << ">> TPsiRunHeader::ExtractHeaderInformation(..) **ERROR** in TPsiRunProperty:";
- cerr << endl << ">> found " << ostr->GetString().Data() << ", which has an invalid format." << endl << endl;
+ if (DecodePhyscialPorperty(dynamic_cast(runHeader->At(i)), prop)) {
+ AddProperty(prop);
+ } else {
return false;
}
- dval = str.Atof();
-
- // 3rd get the error, and unit
- str = ostr->GetString();
- idx = str.Index("+-");
- str.Remove(0, idx+3);
- memset(cstr, 0, sizeof(cstr));
- status = sscanf(str.Data(), "%lf %s", &derr, cstr);
- if (status < 2) {
- cerr << endl << ">> TPsiRunHeader::ExtractHeaderInformation(..) **ERROR** in TPsiRunProperty:";
- cerr << endl << ">> found " << ostr->GetString().Data() << ", which has an invalid format." << endl << endl;
- return false;
- }
- if (strlen(cstr) > 0)
- unit = TString(cstr);
-
- AddProperty(name, dval, derr, unit);
}
return true;
@@ -359,9 +354,9 @@ void TPsiRunHeader::AddProperty(TPsiRunProperty &property)
* \param error
* \param unit
*/
-void TPsiRunHeader::AddProperty(TString name, Double_t value, Double_t error, TString unit)
+void TPsiRunHeader::AddProperty(TString name, Double_t demand, Double_t value, Double_t error, TString unit, TString description)
{
- TPsiRunProperty property(name, value, error, unit);
+ TPsiRunProperty property(name, demand, value, error, unit, description);
fProperties.push_back(property);
}
@@ -408,9 +403,15 @@ void TPsiRunHeader::DumpHeader() const
cout << endl << setw(name_width) << left << "Orientation" << setw(old_width) << ": " << GetOrientation().Data();
for (UInt_t i=0; iModified(kTRUE);
}
+//--------------------------------------------------------------------------
+// DecodePhyscialPorperty (private)
+//--------------------------------------------------------------------------
+/**
+ *
+ *
+ * \param ostr
+ * \param prop
+ */
+Bool_t TPsiRunHeader::DecodePhyscialPorperty(TObjString *oprop, TPsiRunProperty &prop)
+{
+ TObjArray *tokens = oprop->GetString().Tokenize("-:");
+ TObjArray *tokens1 = 0;
+ TObjString *ostr = 0;
+ TString str("");
+
+ if (tokens == 0) {
+ cerr << endl << ">> **ERROR** Couldn't tokenize physical property string '" << ostr->GetString().Data() << "' (1)." << endl;
+ return false;
+ }
+
+ // get property name
+ ostr = dynamic_cast(tokens->At(1));
+ str = ostr->GetString();
+ str.Remove(TString::kLeading, ' ');
+ prop.SetLabel(str);
+
+ if (tokens) {
+ delete tokens;
+ tokens = 0;
+ }
+
+ // get measured value
+ tokens = oprop->GetString().Tokenize(":");
+ if (tokens == 0) {
+ cerr << endl << ">> **ERROR** Couldn't tokenize physical property string '" << ostr->GetString().Data() << "' (2)." << endl;
+ return false;
+ }
+ ostr = dynamic_cast(tokens->At(1));
+ str = ostr->GetString();
+ tokens1 = str.Tokenize(" ;");
+ if (tokens1 == 0) {
+ cerr << endl << ">> **ERROR** Couldn't tokenize physical property string '" << ostr->GetString().Data() << "' (3)." << endl;
+ if (tokens) {
+ delete tokens;
+ tokens = 0;
+ }
+ return false;
+ }
+ if (tokens1->GetEntries() < 4) {
+ cerr << endl << ">> **ERROR** not enough tokens from physical property string '" << ostr->GetString().Data() << "' (4)." << endl;
+ if (tokens) {
+ delete tokens;
+ tokens = 0;
+ }
+ return false;
+ }
+
+ // get measured value
+ ostr = dynamic_cast(tokens1->At(0));
+ if (ostr->GetString().IsFloat()) {
+ prop.SetValue(ostr->GetString().Atof());
+ } else {
+ cerr << endl << ">> **ERROR** unexpected measured value. Found " << ostr->GetString().Data() << ", expected float." << endl;
+ if (tokens) {
+ delete tokens;
+ }
+ return false;
+ }
+
+ // get estimated err
+ ostr = dynamic_cast(tokens1->At(2));
+ if (ostr->GetString().IsFloat()) {
+ prop.SetError(ostr->GetString().Atof());
+ } else {
+ cerr << endl << ">> **ERROR** unexpected estimated error. Found " << ostr->GetString().Data() << ", expected float." << endl;
+ if (tokens) {
+ delete tokens;
+ }
+ return false;
+ }
+
+ // get unit
+ ostr = dynamic_cast(tokens1->At(3));
+ str = ostr->GetString();
+ str.Remove(TString::kLeading, ' ');
+ prop.SetUnit(str);
+
+ if (tokens1) {
+ delete tokens1;
+ tokens1 = 0;
+ }
+
+ ostr = dynamic_cast(tokens->At(2));
+ str = ostr->GetString();
+ tokens1 = str.Tokenize(";");
+ if (tokens1 == 0) {
+ cerr << endl << ">> **ERROR** Couldn't tokenize physical property string '" << ostr->GetString().Data() << "' (4)." << endl;
+ if (tokens) {
+ delete tokens;
+ tokens = 0;
+ }
+ return false;
+ }
+
+ // get demand value
+ ostr = dynamic_cast(tokens1->At(0));
+ if (ostr->GetString().IsFloat()) {
+ prop.SetDemand(ostr->GetString().Atof());
+ } else {
+ cerr << endl << ">> **ERROR** unexpected demand value. Found " << ostr->GetString().Data() << ", expected float." << endl;
+ if (tokens) {
+ delete tokens;
+ }
+ return false;
+ }
+
+ if (tokens1->GetEntries() > 1) { // with description
+ ostr = dynamic_cast(tokens1->At(1));
+ str = ostr->GetString();
+ str.Remove(TString::kLeading, ' ');
+ prop.SetDescription(str);
+ }
+
+
+ if (tokens1) {
+ delete tokens1;
+ }
+ if (tokens) {
+ delete tokens;
+ }
+
+ return true;
+}
+
//--------------------------------------------------------------------------
// GetDecimalPlace (private)
//--------------------------------------------------------------------------
@@ -464,3 +600,32 @@ UInt_t TPsiRunHeader::GetDecimalPlace(Double_t val)
return digit;
}
+
+//--------------------------------------------------------------------------
+// GetLeastSignificantDigit (private)
+//--------------------------------------------------------------------------
+/**
+ * returns the number of significant digits
+ *
+ * \param val value from which the lowest significant digit shall be determined
+ */
+UInt_t TPsiRunHeader::GetLeastSignificantDigit(Double_t val) const
+{
+ char cstr[1024];
+ sprintf(cstr, "%lf", val);
+
+ int i=0, j=0;
+ for (i=strlen(cstr)-1; i>=0; i--) {
+ if (cstr[i] != '0')
+ break;
+ }
+
+ for (j=strlen(cstr)-1; j>=0; j--) {
+ if (cstr[j] == '.')
+ break;
+ }
+ if (j==0) // no decimal point present, e.g. 321
+ j=i;
+
+ return i-j;
+}
diff --git a/src/tests/PsiRoot/TPsiRunHeader.h b/src/tests/PsiRoot/TPsiRunHeader.h
index 1a7680a8..d3147145 100644
--- a/src/tests/PsiRoot/TPsiRunHeader.h
+++ b/src/tests/PsiRoot/TPsiRunHeader.h
@@ -40,26 +40,33 @@ class TPsiRunProperty : public TObject
{
public:
TPsiRunProperty();
- TPsiRunProperty(TString &name, Double_t value, Double_t error, TString &unit);
+ TPsiRunProperty(TString &name, Double_t demand, Double_t value, Double_t error, TString &unit, TString &description);
virtual ~TPsiRunProperty();
virtual TString GetLabel() const { return fLabel; }
+ virtual Double_t GetDemand() const { return fDemand; }
virtual Double_t GetValue() const { return fValue; }
virtual Double_t GetError() const { return fError; }
virtual TString GetUnit() const { return fUnit; }
+ virtual TString GetDescription() const { return fDescription; }
virtual void SetLabel(TString &label) { fLabel = label; }
virtual void SetLabel(const char *label) { fLabel = label; }
+ virtual void SetDemand(Double_t val) { fDemand = val; }
virtual void SetValue(Double_t val) { fValue = val; }
virtual void SetError(Double_t err) { fError = err; }
virtual void SetUnit(TString &unit) { fUnit = unit.Data(); }
virtual void SetUnit(const char *unit) { fUnit = unit; }
+ virtual void SetDescription(TString &str) { fDescription = str.Data(); }
+ virtual void SetDescription(const char *str) { fDescription = str; }
private:
- TString fLabel;
- Double_t fValue;
- Double_t fError;
- TString fUnit;
+ TString fLabel; ///< property label, like ’Sample Temperature’ etc.
+ Double_t fDemand; ///< demand value of the property, e.g. temperature setpoint
+ Double_t fValue; ///< measured value of the property
+ Double_t fError; ///< estimated error (standard deviation) of the measured property value
+ TString fUnit; ///< unit of the property
+ TString fDescription; ///< a more detailed description of the property
ClassDef(TPsiRunProperty, 1)
};
@@ -78,6 +85,7 @@ public:
virtual TString GetSetup() const { return fSetup; }
virtual TString GetSample() const { return fSample; }
virtual TString GetOrientation() const { return fOrientation; }
+ virtual TPsiRunProperty* GetProperty(TString name);
virtual vector *GetProperties() { return &fProperties; }
virtual TObjArray *GetHeader();
@@ -91,7 +99,7 @@ public:
virtual void SetSample(TString sample) { fSample = sample; }
virtual void SetOrientation(TString orientation) { fOrientation = orientation; }
virtual void AddProperty(TPsiRunProperty &property);
- virtual void AddProperty(TString name, Double_t value, Double_t error, TString unit);
+ virtual void AddProperty(TString name, Double_t demand, Double_t value, Double_t error, TString unit, TString desciption=TString(""));
virtual void DumpHeader() const;
@@ -110,7 +118,10 @@ private:
TObjArray fHeader; /// header as TObjString array for dumping into a ROOT file
- UInt_t GetDecimalPlace(Double_t val);
+ virtual Bool_t DecodePhyscialPorperty(TObjString *ostr, TPsiRunProperty &prop);
+
+ virtual UInt_t GetDecimalPlace(Double_t val);
+ virtual UInt_t GetLeastSignificantDigit(Double_t val) const;
ClassDef(TPsiRunHeader, 1)
};
diff --git a/src/tests/PsiRoot/psi_runHeader_test.cpp b/src/tests/PsiRoot/psi_runHeader_test.cpp
index d3e3a9e3..b8a367da 100644
--- a/src/tests/PsiRoot/psi_runHeader_test.cpp
+++ b/src/tests/PsiRoot/psi_runHeader_test.cpp
@@ -63,12 +63,12 @@ int main(int argc, char *argv[])
header->SetSample("Eu2CuO4 MOD thin film");
header->SetOrientation("c-axis perp to spin");
- header->AddProperty("T0", 30.01, 0.05, "K");
- header->AddProperty("T1", 30.03, 0.03, "K");
- header->AddProperty("Field", 3.00003, 0.0003, "T");
- header->AddProperty("BigError", 13.2, 1.2, "Something");
- header->AddProperty("ThisIsAVeryLongPropertyName", 3.03, 0.03, "SI-Unit");
- header->AddProperty("This Is A Property With Spaces", 3.03, 0.03, "SI-Unit");
+ header->AddProperty("Sample Temperature", 30.0, 30.01, 0.05, "K");
+ header->AddProperty("T1", 30.0, 30.003, 0.003, "K", "sample stick temperature");
+ header->AddProperty("Field", 3.0, 3.0003, 0.000025, "T");
+ header->AddProperty("BigError", 12.5, 13.2, 1.2, "Something", "Explain it");
+ header->AddProperty("ThisIsAVeryLongPropertyName", 3.001, 3.03, 0.03, "SI-Unit", "another interesting property");
+ header->AddProperty("This Is A Property With Spaces", 3.0, 3.03, 0.03, "SI-Unit", "yet another interesting property");
TFile *f = new TFile(argv[1], "RECREATE", "psi_runHeader_test");
if (f->IsZombie()) {
@@ -77,16 +77,16 @@ int main(int argc, char *argv[])
}
// root file header related things
-/*
TFolder *runInfo = gROOT->GetRootFolder()->AddFolder("RunInfo", "PSI RunInfo");
gROOT->GetListOfBrowsables()->Add(runInfo, "RunInfo");
runInfo->Add(header->GetHeader());
runInfo->Write();
-*/
+/*
f->mkdir("RunInfo");
f->cd("RunInfo");
header->GetHeader()->Write();
+*/
f->Close();