some more stuff towards PSI-ROOT

This commit is contained in:
nemu
2011-08-26 14:44:07 +00:00
parent db5d877e11
commit cac1b33085
3 changed files with 246 additions and 70 deletions

View File

@ -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
//--------------------------------------------------------------------------
/**
* <p>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; i<fProperties.size(); i++) {
if (!fProperties[i].GetLabel().CompareTo(name, TString::kIgnoreCase))
break;
}
if (i<fProperties.size())
return &fProperties[i];
else
return 0;
}
//--------------------------------------------------------------------------
// GetHeader (public)
//--------------------------------------------------------------------------
@ -189,15 +219,18 @@ TObjArray* TPsiRunHeader::GetHeader()
fHeader.AddLast(tostr);
// add properties
UInt_t digit=0;
UInt_t digit=0, digit_d=0;
for (UInt_t i=0; i<fProperties.size(); i++) {
digit = GetDecimalPlace(fProperties[i].GetError());
if (fProperties[i].GetUnit().CompareTo("n/a", TString::kIgnoreCase)) {
sprintf(fmt, "%%02d - %%s: %%.%dlf +- %%.%dlf %%s", digit, digit);
sprintf(str, fmt, TPRH_OFFSET+i, fProperties[i].GetLabel().Data(), fProperties[i].GetValue(), fProperties[i].GetError(), fProperties[i].GetUnit().Data());
digit_d = GetLeastSignificantDigit(fProperties[i].GetDemand());
if (fProperties[i].GetDescription().CompareTo("n/a")) {
sprintf(fmt, "%%02d - %%s: %%.%dlf +- %%.%dlf %%s; SP: %%.%dlf; %%s", digit, digit, digit_d);
sprintf(str, fmt, TPRH_OFFSET+i, fProperties[i].GetLabel().Data(), fProperties[i].GetValue(), fProperties[i].GetError(),
fProperties[i].GetUnit().Data(), fProperties[i].GetDemand(), fProperties[i].GetDescription().Data());
} else {
sprintf(fmt, "%%02d - %%s: %%.%dlf +- %%.%dlf", digit, digit);
sprintf(str, fmt, TPRH_OFFSET+i, fProperties[i].GetLabel().Data(), fProperties[i].GetValue(), fProperties[i].GetError());
sprintf(fmt, "%%02d - %%s: %%.%dlf +- %%.%dlf %%s; SP: %%.%dlf", digit, digit, digit_d);
sprintf(str, fmt, TPRH_OFFSET+i, fProperties[i].GetLabel().Data(), fProperties[i].GetValue(), fProperties[i].GetError(),
fProperties[i].GetUnit().Data(), fProperties[i].GetDemand());
}
tostr = new TObjString(str);
fHeader.AddLast(tostr);
@ -285,51 +318,13 @@ Bool_t TPsiRunHeader::ExtractHeaderInformation(TObjArray *runHeader)
// remove potential left over properties
fProperties.clear();
Double_t dval, derr;
TString name(""), unit("");
char cstr[128];
TPsiRunProperty prop;
for (Int_t i=TPRH_OFFSET-1; i<runHeader->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(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<TObjString*>(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; i<fProperties.size(); i++) {
cout << endl << setw(name_width) << left << fProperties[i].GetLabel().Data() << setw(old_width) << ": " << fProperties[i].GetValue() << " +- " << fProperties[i].GetError();
if (fProperties[i].GetUnit().CompareTo("n/a", TString::kIgnoreCase)) {
cout << " " << fProperties[i].GetUnit().Data();
cout << endl << setw(name_width) << left << fProperties[i].GetLabel().Data() << setw(old_width) << ": ";
/*
cout.precision(GetLeastSignificantDigit(fProperties[i].GetValue()));
cout.setf(ios::fixed,ios::floatfield);
*/
cout << fProperties[i].GetValue() << " +- " << fProperties[i].GetError() << " " << fProperties[i].GetUnit().Data();
cout << "; SP: " << fProperties[i].GetDemand();
if (fProperties[i].GetDescription().CompareTo("n/a", TString::kIgnoreCase)) {
cout << "; " << fProperties[i].GetDescription().Data();
}
}
cout << endl << endl;
@ -439,6 +440,141 @@ void TPsiRunHeader::DrawHeader() const
ca->Modified(kTRUE);
}
//--------------------------------------------------------------------------
// DecodePhyscialPorperty (private)
//--------------------------------------------------------------------------
/**
* <p>
*
* \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<TObjString*>(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<TObjString*>(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<TObjString*>(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<TObjString*>(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<TObjString*>(tokens1->At(3));
str = ostr->GetString();
str.Remove(TString::kLeading, ' ');
prop.SetUnit(str);
if (tokens1) {
delete tokens1;
tokens1 = 0;
}
ostr = dynamic_cast<TObjString*>(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<TObjString*>(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<TObjString*>(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)
//--------------------------------------------------------------------------
/**
* <p>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;
}

View File

@ -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<TPsiRunProperty> *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)
};

View File

@ -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();