diff --git a/src/tests/PsiRoot/TPsiRunHeader.cpp b/src/tests/PsiRoot/TPsiRunHeader.cpp index 48baf852..35ef6dfe 100644 --- a/src/tests/PsiRoot/TPsiRunHeader.cpp +++ b/src/tests/PsiRoot/TPsiRunHeader.cpp @@ -29,6 +29,7 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ +#include #include #include using namespace std; @@ -41,19 +42,6 @@ using namespace std; #include #include -#define TPRH_VERSION_IDX 0 -#define TPRH_RUN_TITLE_IDX 1 -#define TPRH_RUN_NUMBER_IDX 2 -#define TPRH_LABORATORY_IDX 3 -#define TPRH_INSTRUMENT_IDX 4 -#define TPRH_SETUP_IDX 5 -#define TPRH_SAMPLE_IDX 6 -#define TPRH_ORIENTATION_IDX 7 - -#define TPRH_OFFSET 9 - -#define TPRH_MIN_NO_REQUIRED_ENTRIES 10 - ClassImp(TPsiRunProperty) //-------------------------------------------------------------------------- @@ -70,6 +58,7 @@ TPsiRunProperty::TPsiRunProperty() fError = 0.0; fUnit = "n/a"; fDescription = "n/a"; + fPath = "n/a"; } //-------------------------------------------------------------------------- @@ -83,23 +72,17 @@ TPsiRunProperty::TPsiRunProperty() * \param error * \param unit */ -TPsiRunProperty::TPsiRunProperty(TString &label, Double_t demand, Double_t value, Double_t error, TString &unit, TString &description) : +TPsiRunProperty::TPsiRunProperty(TString &label, Double_t demand, Double_t value, Double_t error, TString &unit, TString &description, TString &path) : fLabel(label), fDemand(demand), fValue(value), fError(error), fUnit(unit) { if (description.IsWhitespace()) fDescription = "n/a"; else fDescription = description; -} -//-------------------------------------------------------------------------- -// Destructor -//-------------------------------------------------------------------------- -/** - *

Destructor. - */ -TPsiRunProperty::~TPsiRunProperty() -{ + fPath = path; + if (path.IsWhitespace()) + fPath = "/"; } //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -115,15 +98,31 @@ ClassImp(TPsiRunHeader) TPsiRunHeader::TPsiRunHeader() { fVersion = TString("$Id$"); + fGenerator = TString("n/a"); + fFileName = TString("n/a"); fRunTitle = TString("n/a"); fRunNumber = -1; + fStartTime = TDatime("1995-01-01 00:00:00"); + fStopTime = TDatime("1995-01-01 00:00:00"); fLaboratory = TString("n/a"); + fArea = TString("n/a"); fInstrument = TString("n/a"); + fMuonSpecies = TString("n/a"); fSetup = TString("n/a"); fSample = TString("n/a"); fOrientation = TString("n/a"); + fSampleCryo = TString("n/a"); + fSampleCryoInsert = TString("n/a"); + fMagnetName = TString("n/a"); + fNoOfHistos = -1; + fHistoLength = -1; + fTimeResolution = 0.0; - fHeader.Expand(0); // init to size 0 + fHeader.Expand(0); // init to size 0 + fSampleEnv.Expand(0); // init to size 0 + fMagFieldEnv.Expand(0); // init to size 0 + fBeamline.Expand(0); // init to size 0 + fScalers.Expand(0); // init to size 0 } //-------------------------------------------------------------------------- @@ -134,12 +133,419 @@ TPsiRunHeader::TPsiRunHeader() */ TPsiRunHeader::~TPsiRunHeader() { + fHistoName.clear(); + fTimeZeroBin.clear(); + fFirstGoodBin.clear(); + fLastGoodBin.clear(); + fRedGreenOffset.clear(); + fRedGreenDescription.clear(); fProperties.clear(); fHeader.Delete(); + fSampleEnv.Delete(); + fMagFieldEnv.Delete(); + fBeamline.Delete(); + fScalers.Delete(); } //-------------------------------------------------------------------------- -// GetProperty +// IsValid (public) +//-------------------------------------------------------------------------- +/** + *

validates the currently set header information. If strict is set to true + * a strict validation is carried out, otherwise a more sloppy one. + * + *

return: + * - true, if valid header information are present. + * - false, otherwise + * + * \param strict flag needed to tell on which level the validation has to be carried out. + */ +Bool_t TPsiRunHeader::IsValid(Bool_t strict) +{ + TString startTime = TString(fStartTime.AsSQLString()); + TString stopTime = TString(fStopTime.AsSQLString()); + + if (strict) { + if (!fGenerator.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Generator' not set." << endl; + return false; + } else if (!fFileName.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'File Name' not set." << endl; + return false; + } else if (!fRunTitle.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Run Title' not set." << endl; + return false; + } else if (fRunNumber == -1) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Run Number' not set." << endl; + return false; + } else if (!startTime.CompareTo("1995-01-01 00:00:00", TString::kIgnoreCase)) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Run Start Times' not set." << endl; + return false; + } else if (!stopTime.CompareTo("1995-01-01 00:00:00", TString::kIgnoreCase)) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Run Stop Times' not set." << endl; + return false; + } else if (!fLaboratory.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Laboratory' not set." << endl; + return false; + } else if (!fArea.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Area' not set." << endl; + return false; + } else if (!fInstrument.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Instrument' not set." << endl; + return false; + } else if (!fMuonSpecies.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Muon Species' not set." << endl; + return false; + } else if (!fSetup.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Setup' not set." << endl; + return false; + } else if (!fSample.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Sample' not set." << endl; + return false; + } else if (!fOrientation.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'SampleEnv/Orientation' not set." << endl; + return false; + } else if (!fSampleCryo.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'SampleEnv/Cryo' not set." << endl; + return false; + } else if (!fSampleCryoInsert.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'SampleEnv/Insert' not set." << endl; + return false; + } else if (!fMagnetName.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'MagFieldEnv/Name' not set." << endl; + return false; + } else if (fNoOfHistos == -1) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'No of Histos' not set." << endl; + return false; + } else if (fHistoName.size() == 0) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Histo Names' not set." << endl; + return false; + } else if ((Int_t)fHistoName.size() != fNoOfHistos) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): No of 'Histo Names' != 'No of Histos'!" << endl; + return false; + } else if (fHistoLength == -1) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Histo Length' not set." << endl; + return false; + } else if (fTimeResolution == 0.0) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Time Resolution' not set." << endl; + return false; + } else if (fTimeZeroBin.size() == 0) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Time Zero Bin' not set." << endl; + return false; + } else if ((Int_t)fTimeZeroBin.size() != fNoOfHistos) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): No of 'Time Zero Bin' != 'No Of Histos'." << endl; + return false; + } else if (fFirstGoodBin.size() == 0) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'First Good Bin' not set." << endl; + return false; + } else if ((Int_t)fFirstGoodBin.size() != fNoOfHistos) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): No of 'First Good Bin' != 'No Of Histos'." << endl; + return false; + } else if (fLastGoodBin.size() == 0) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Last Good Bin' not set." << endl; + return false; + } else if ((Int_t)fLastGoodBin.size() != fNoOfHistos) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): No of 'Last Good Bin' != 'No Of Histos'." << endl; + return false; + } else if (fRedGreenOffset.size() != fRedGreenDescription.size()) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): No of 'Red/Green offsets' != 'Red/Green descriptions'." << endl; + return false; + } + + // check all the required physical properties + + // check 'Sample Temperature' + if (GetProperty("Muon Beam Momentum") == 0) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Muon Beam Momentum' not set." << endl; + return false; + } else if (GetProperty("Sample Temperature") == 0) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Sample Temperature' not set." << endl; + return false; + } else if (GetProperty("Sample Magnetic Field") == 0) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Sample Magnetic Field' not set." << endl; + return false; + } else if (GetProperty("Current") == 0) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'MagFieldEnv/Current' not set." << endl; + return false; + } + } else { // not quite so strict + if (!fGenerator.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **WARNING** TPsiRunHeader::IsValid(): 'Generator' not set." << endl; + } + if (!fFileName.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'File Name' not set." << endl; + return false; + } + if (!fRunTitle.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Run Title' not set." << endl; + return false; + } + if (fRunNumber == -1) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Run Number' not set." << endl; + return false; + } + if (!startTime.CompareTo("1995-01-01 00:00:00", TString::kIgnoreCase)) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Run Start Times' not set." << endl; + return false; + } + if (!stopTime.CompareTo("1995-01-01 00:00:00", TString::kIgnoreCase)) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Run Stop Times' not set." << endl; + return false; + } + if (!fLaboratory.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **WARNING** TPsiRunHeader::IsValid(): 'Laboratory' not set." << endl; + } + if (!fArea.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **WARNING** TPsiRunHeader::IsValid(): 'Area' not set." << endl; + } + if (!fInstrument.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **WARNING** TPsiRunHeader::IsValid(): 'Instrument' not set." << endl; + } + if (!fMuonSpecies.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **WARNING** TPsiRunHeader::IsValid(): 'Muon Species' not set." << endl; + } + if (!fSetup.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **WARNING** TPsiRunHeader::IsValid(): 'Setup' not set." << endl; + } + if (!fSample.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **WARNING** TPsiRunHeader::IsValid(): 'Sample' not set." << endl; + } + if (!fOrientation.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **WARNING** TPsiRunHeader::IsValid(): 'SampleEnv/Orientation' not set." << endl; + } + if (!fSampleCryo.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **WARNING** TPsiRunHeader::IsValid(): 'SampleEnv/Cryo' not set." << endl; + } + if (!fSampleCryoInsert.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **WARNING** TPsiRunHeader::IsValid(): 'SampleEnv/Insert' not set." << endl; + } + if (!fMagnetName.CompareTo("n/a", TString::kIgnoreCase)) { + cerr << endl << ">> **WARNING** TPsiRunHeader::IsValid(): 'MagFieldEnv/Name' not set." << endl; + } + if (fNoOfHistos == -1) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'No of Histos' not set." << endl; + return false; + } + if (fHistoName.size() == 0) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Histo Names' not set." << endl; + return false; + } + if ((Int_t)fHistoName.size() != fNoOfHistos) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): No of 'Histo Names' != 'No of Histos'!" << endl; + return false; + } + if (fHistoLength == -1) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Histo Length' not set." << endl; + return false; + } + if (fTimeResolution == 0.0) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Time Resolution' not set." << endl; + return false; + } + if (fTimeZeroBin.size() == 0) { + cerr << endl << ">> **WARNING** TPsiRunHeader::IsValid(): 'Time Zero Bin' not set." << endl; + } + if ((fTimeZeroBin.size() > 0) && ((Int_t)fTimeZeroBin.size() != fNoOfHistos)) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): No of 'Time Zero Bin' != 'No Of Histos'." << endl; + return false; + } + if (fFirstGoodBin.size() == 0) { + cerr << endl << ">> **WARNING** TPsiRunHeader::IsValid(): 'First Good Bin' not set." << endl; + } + if ((fFirstGoodBin.size() > 0) && ((Int_t)fFirstGoodBin.size() != fNoOfHistos)) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): No of 'First Good Bin' != 'No Of Histos'." << endl; + return false; + } + if (fLastGoodBin.size() == 0) { + cerr << endl << ">> **WARNING** TPsiRunHeader::IsValid(): 'Last Good Bin' not set." << endl; + } + if ((fLastGoodBin.size() > 0) && ((Int_t)fLastGoodBin.size() != fNoOfHistos)) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): No of 'Last Good Bin' != 'No Of Histos'." << endl; + return false; + } + if (fRedGreenOffset.size() != fRedGreenDescription.size()) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): No of 'Red/Green offsets' != 'Red/Green descriptions'." << endl; + return false; + } + + // check all the required physical properties + + // check 'Sample Temperature' + if (GetProperty("Muon Beam Momentum") == 0) { + cerr << endl << ">> **WARNING** TPsiRunHeader::IsValid(): 'Muon Beam Momentum' not set." << endl; + } + if (GetProperty("Sample Temperature") == 0) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Sample Temperature' not set." << endl; + return false; + } + if (GetProperty("Sample Magnetic Field") == 0) { + cerr << endl << ">> **ERROR** TPsiRunHeader::IsValid(): 'Sample Magnetic Field' not set." << endl; + return false; + } + if (GetProperty("Current") == 0) { + cerr << endl << ">> **WARNING** TPsiRunHeader::IsValid(): 'MagFieldEnv/Current' not set." << endl; + } + } + + return true; +} + +//-------------------------------------------------------------------------- +// GetHistoName (public) +//-------------------------------------------------------------------------- +/** + *

returns the histogram name at index 'idx'. If 'idx' is out of range, + * an empty string is returned and 'ok' is set to false. + * + * \param idx index for which the histogram name is whished + * \param ok true, if a valid name was found, false otherwise + */ +TString TPsiRunHeader::GetHistoName(UInt_t idx, Bool_t &ok) const +{ + if (idx >= fHistoName.size()) { + ok = false; + return TString(""); + } + + ok = true; + return fHistoName[idx]; +} + +//-------------------------------------------------------------------------- +// GetTimeResolution (public) +//-------------------------------------------------------------------------- +/** + *

returns the time resolution in the requested 'units'. Allowed 'units' + * are: fs, ps, ns, us + * + * \param units in which the time resolution shall be returned. + */ +Double_t TPsiRunHeader::GetTimeResolution(const char *units) const +{ + Double_t factor = 1.0; + TString str(units); + + if (!str.CompareTo("fs", TString::kIgnoreCase)) + factor = 1.0e3; + else if (!str.CompareTo("ps", TString::kIgnoreCase)) + factor = 1.0; + else if (!str.CompareTo("ns", TString::kIgnoreCase)) + factor = 1.0e-3; + else if (!str.CompareTo("us", TString::kIgnoreCase)) + factor = 1.0e-6; + else + factor = 0.0; + + return factor*fTimeResolution; +} + +//-------------------------------------------------------------------------- +// GetTimeZeroBin (public) +//-------------------------------------------------------------------------- +/** + *

returns the time zero bin of index 'idx'. If 'idx' is out of range, + * 'ok' is set to false. + * + * \param idx index for which time zero bin shall be returned + * \param ok flag showing if the returned value is valid + */ +UInt_t TPsiRunHeader::GetTimeZeroBin(UInt_t idx, Bool_t &ok) const +{ + if (idx >= fTimeZeroBin.size()) { + ok = false; + return 0; + } + + ok = true; + return fTimeZeroBin[idx]; +} + +//-------------------------------------------------------------------------- +// GetFirstGoodBin (public) +//-------------------------------------------------------------------------- +/** + *

returns the first good bin of index 'idx'. If 'idx' is out of range, + * 'ok' is set to false. + * + * \param idx index for which first good bin shall be returned + * \param ok flag showing if the returned value is valid + */ +UInt_t TPsiRunHeader::GetFirstGoodBin(UInt_t idx, Bool_t &ok) const +{ + if (idx >= fFirstGoodBin.size()) { + ok = false; + return 0; + } + + ok = true; + return fFirstGoodBin[idx]; +} + +//-------------------------------------------------------------------------- +// GetLastGoodBin (public) +//-------------------------------------------------------------------------- +/** + *

returns the last good bin of index 'idx'. If 'idx' is out of range, + * 'ok' is set to false. + * + * \param idx index for which last good bin shall be returned + * \param ok flag showing if the returned value is valid + */ +UInt_t TPsiRunHeader::GetLastGoodBin(UInt_t idx, Bool_t &ok) const +{ + if (idx >= fLastGoodBin.size()) { + ok = false; + return 0; + } + + ok = true; + return fLastGoodBin[idx]; +} + +//-------------------------------------------------------------------------- +// GetRedGreenHistoOffset (public) +//-------------------------------------------------------------------------- +/** + *

returns the red/green mode histogram offset at index 'idx'. If 'idx' is out of range, + * 'ok' is set to false. + * + * \param idx index for which red/green mode histogram offset shall be returned + * \param ok flag showing if the returned value is valid + */ +UInt_t TPsiRunHeader::GetRedGreenHistoOffset(UInt_t idx, Bool_t &ok) const +{ + if (idx >= fRedGreenOffset.size()) { + ok = false; + return 0; + } + + ok = true; + return fRedGreenOffset[idx]; +} + +//-------------------------------------------------------------------------- +// GetRedGreenHistoDescription (public) +//-------------------------------------------------------------------------- +/** + *

returns the red/green mode description at index 'idx'. If 'idx' is out of range, + * 'ok' is set to false. + * + * \param idx index for which red/green mode description shall be returned + * \param ok flag showing if the returned value is valid + */ +TString TPsiRunHeader::GetRedGreenHistoDescription(UInt_t idx, Bool_t &ok) const +{ + if (idx >= fRedGreenDescription.size()) { + ok = false; + return TString(""); + } + + ok = true; + return fRedGreenDescription[idx]; +} + +//-------------------------------------------------------------------------- +// GetProperty (public) //-------------------------------------------------------------------------- /** *

Searches the property given by 'name'. If it is found, this property is @@ -147,7 +553,7 @@ TPsiRunHeader::~TPsiRunHeader() * * \param name property name to look for. */ -TPsiRunProperty* TPsiRunHeader::GetProperty(TString name) +const TPsiRunProperty* TPsiRunHeader::GetProperty(TString name) const { UInt_t i=0; @@ -169,78 +575,374 @@ TPsiRunProperty* TPsiRunHeader::GetProperty(TString name) *

* */ -TObjArray* TPsiRunHeader::GetHeader() +TObjArray* TPsiRunHeader::GetHeader(UInt_t &count) { // make sure that previous header is removed fHeader.Delete(); fHeader.Expand(0); - char str[1024], fmt[1024]; + TString str, fmt; TObjString *tostr; + const TPsiRunProperty *prop; + UInt_t digit=0, digit_d=0; // add version - sprintf(str, "%02d - Version: %s", TPRH_VERSION_IDX+1, fVersion.Data()); + str.Form("%02d - Version: %s", count++, fVersion.Data()); + tostr = new TObjString(str); + fHeader.AddLast(tostr); + + // add generator + str.Form("%02d - Generator: %s", count++, fGenerator.Data()); + tostr = new TObjString(str); + fHeader.AddLast(tostr); + + // add file name + str.Form("%02d - File Name: %s", count++, fFileName.Data()); tostr = new TObjString(str); fHeader.AddLast(tostr); // add run title - sprintf(str, "%02d - Run Title: %s", TPRH_RUN_TITLE_IDX+1, fRunTitle.Data()); + str.Form("%02d - Run Title: %s", count++, fRunTitle.Data()); tostr = new TObjString(str); fHeader.AddLast(tostr); // add run number - sprintf(str, "%02d - Run Number: %d", TPRH_RUN_NUMBER_IDX+1, fRunNumber); + str.Form("%02d - Run Number: %d", count++, fRunNumber); + tostr = new TObjString(str); + fHeader.AddLast(tostr); + + // add run start time + str.Form("%02d - Run Start Time: %s", count++, fStartTime.AsSQLString()); + tostr = new TObjString(str); + fHeader.AddLast(tostr); + + // add run stop time + str.Form("%02d - Run Stop Time: %s", count++, fStopTime.AsSQLString()); tostr = new TObjString(str); fHeader.AddLast(tostr); // add laboratory - sprintf(str, "%02d - Laboratory: %s", TPRH_LABORATORY_IDX+1, fLaboratory.Data()); + str.Form("%02d - Laboratory: %s", count++, fLaboratory.Data()); + tostr = new TObjString(str); + fHeader.AddLast(tostr); + + // add area + str.Form("%02d - Area: %s", count++, fArea.Data()); tostr = new TObjString(str); fHeader.AddLast(tostr); // add instrument - sprintf(str, "%02d - Instrument: %s", TPRH_INSTRUMENT_IDX+1, fInstrument.Data()); + str.Form("%02d - Instrument: %s", count++, fInstrument.Data()); tostr = new TObjString(str); fHeader.AddLast(tostr); + // add muon momentum + prop = GetProperty("Muon Momentum"); + if (prop) { + digit = GetDecimalPlace(prop->GetError()); + digit_d = GetLeastSignificantDigit(prop->GetDemand()); + if (prop->GetDescription().CompareTo("n/a")) { + fmt.Form("%%02d - %%s: %%.%dlf +- %%.%dlf %%s; SP: %%.%dlf; %%s", digit, digit, digit_d); + str.Form(fmt.Data(), count++, prop->GetLabel().Data(), prop->GetValue(), prop->GetError(), + prop->GetUnit().Data(), prop->GetDemand(), prop->GetDescription().Data()); + } else { + fmt.Form("%%02d - %%s: %%.%dlf +- %%.%dlf %%s; SP: %%.%dlf", digit, digit, digit_d); + str.Form(fmt.Data(), count++, prop->GetLabel().Data(), prop->GetValue(), prop->GetError(), + prop->GetUnit().Data(), prop->GetDemand()); + } + tostr = new TObjString(str); + fHeader.AddLast(tostr); + } + + // add muon species + str.Form("%02d - Muon Species: %s", count++, fMuonSpecies.Data()); + tostr = new TObjString(str); + fHeader.AddLast(tostr); + + // add setup - sprintf(str, "%02d - Setup: %s", TPRH_SETUP_IDX+1, fSetup.Data()); + str.Form("%02d - Setup: %s", count++, fSetup.Data()); tostr = new TObjString(str); fHeader.AddLast(tostr); // add sample - sprintf(str, "%02d - Sample: %s", TPRH_SAMPLE_IDX+1, fSample.Data()); + str.Form("%02d - Sample: %s", count++, fSample.Data()); tostr = new TObjString(str); fHeader.AddLast(tostr); - // add orientation - sprintf(str, "%02d - Orientation: %s", TPRH_ORIENTATION_IDX+1, fOrientation.Data()); - tostr = new TObjString(str); - fHeader.AddLast(tostr); - - // add properties - UInt_t digit=0, digit_d=0; - for (UInt_t i=0; iGetError()); + digit_d = GetLeastSignificantDigit(prop->GetDemand()); + if (prop->GetDescription().CompareTo("n/a")) { + fmt.Form("%%02d - %%s: %%.%dlf +- %%.%dlf %%s; SP: %%.%dlf; %%s", digit, digit, digit_d); + str.Form(fmt.Data(), count++, prop->GetLabel().Data(), prop->GetValue(), prop->GetError(), + prop->GetUnit().Data(), prop->GetDemand(), prop->GetDescription().Data()); } else { - 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()); + fmt.Form("%%02d - %%s: %%.%dlf +- %%.%dlf %%s; SP: %%.%dlf", digit, digit, digit_d); + str.Form(fmt.Data(), count++, prop->GetLabel().Data(), prop->GetValue(), prop->GetError(), + prop->GetUnit().Data(), prop->GetDemand()); } tostr = new TObjString(str); fHeader.AddLast(tostr); } + // add sample magnetic field + prop = GetProperty("Sample Magnetic Field"); + if (prop) { + digit = GetDecimalPlace(prop->GetError()); + digit_d = GetLeastSignificantDigit(prop->GetDemand()); + if (prop->GetDescription().CompareTo("n/a")) { + fmt.Form("%%02d - %%s: %%.%dlf +- %%.%dlf %%s; SP: %%.%dlf; %%s", digit, digit, digit_d); + str.Form(fmt.Data(), count++, prop->GetLabel().Data(), prop->GetValue(), prop->GetError(), + prop->GetUnit().Data(), prop->GetDemand(), prop->GetDescription().Data()); + } else { + fmt.Form("%%02d - %%s: %%.%dlf +- %%.%dlf %%s; SP: %%.%dlf", digit, digit, digit_d); + str.Form(fmt.Data(), count++, prop->GetLabel().Data(), prop->GetValue(), prop->GetError(), + prop->GetUnit().Data(), prop->GetDemand()); + } + tostr = new TObjString(str); + fHeader.AddLast(tostr); + } + + // add number of histograms + str.Form("%02d - No of Histos: %d", count++, fNoOfHistos); + tostr = new TObjString(str); + fHeader.AddLast(tostr); + + // add histogram names + str.Form("%02d - Histo Names: ", count++); + for (UInt_t i=0; i 0) { + str.Form("%02d - Red/Green offsets: ", count++); + for (UInt_t i=0; i 0) { + str.Form("%02d - Red/Green description: ", count++); + for (UInt_t i=0; i + * + */ +TObjArray* TPsiRunHeader::GetSampleEnv(UInt_t &count) +{ + // make sure that previous sample environment info is removed + fSampleEnv.Delete(); + fSampleEnv.Expand(0); + + TString str, fmt; + TObjString *tostr; + UInt_t digit=0, digit_d=0; + + // add cryo + str.Form("%02d - Cryo: %s", count++, fSampleCryo.Data()); + tostr = new TObjString(str); + fSampleEnv.AddLast(tostr); + + // add insert + str.Form("%02d - Insert: %s", count++, fSampleCryoInsert.Data()); + tostr = new TObjString(str); + fSampleEnv.AddLast(tostr); + + // add orientation + str.Form("%02d - Orientation: %s", count++, fOrientation.Data()); + tostr = new TObjString(str); + fSampleEnv.AddLast(tostr); + + // check if there are additional physical properties present + for (UInt_t i=0; i + * + */ +TObjArray* TPsiRunHeader::GetMagFieldEnv(UInt_t &count) +{ + // make sure that previous sample magnetic field environment info is removed + fMagFieldEnv.Delete(); + fMagFieldEnv.Expand(0); + + TString str, fmt; + TObjString *tostr; + UInt_t digit=0, digit_d=0; + + // add version + str.Form("%02d - Magnet Name: %s", count++, fMagnetName.Data()); + tostr = new TObjString(str); + fMagFieldEnv.AddLast(tostr); + + // check if there are additional physical properties present + for (UInt_t i=0; i + * + */ +TObjArray* TPsiRunHeader::GetBeamline(UInt_t &count) +{ + // make sure that previous beamline info is removed + fBeamline.Delete(); + fBeamline.Expand(0); + + TString str, fmt; + TObjString *tostr; + + // add version + str.Form("%02d - To Be Defined Yet.", count++); + tostr = new TObjString(str); + fBeamline.AddLast(tostr); + + fBeamline.SetName("Beamline"); + + return &fBeamline; +} + +//-------------------------------------------------------------------------- +// GetScaler (public) +//-------------------------------------------------------------------------- +/** + *

+ * + */ +TObjArray* TPsiRunHeader::GetScaler(UInt_t &count) +{ + // make sure that previous scaler info is removed + fScalers.Delete(); + fScalers.Expand(0); + + TString str, fmt; + TObjString *tostr; + + // add version + str.Form("%02d - To Be Defined Yet.", count++); + tostr = new TObjString(str); + fScalers.AddLast(tostr); + + fScalers.SetName("Scalers"); + + return &fScalers; +} + //-------------------------------------------------------------------------- // ExtractHeaderInformation (public) //-------------------------------------------------------------------------- @@ -248,88 +950,497 @@ TObjArray* TPsiRunHeader::GetHeader() *

Extracts from an array of TObjStrings containing the header information * all the necessary parameters. * - * \param runHeader an array of TObjStrings containing the header information + * \param headerInfo an array of TObjStrings containing the header information + * \param path */ -Bool_t TPsiRunHeader::ExtractHeaderInformation(TObjArray *runHeader) +Bool_t TPsiRunHeader::ExtractHeaderInformation(TObjArray *headerInfo, TString path) { // check if there is an object pointer is present - if (runHeader == 0) { - cerr << endl << ">> TPsiRunHeader::ExtractHeaderInformation(..) **ERROR** runHeader object pointer is 0" << endl << endl; - return false; - } - - // check if the minimum of required entries is present - if (runHeader->GetEntries() < TPRH_MIN_NO_REQUIRED_ENTRIES) { - cerr << endl << ">> TPsiRunHeader::ExtractHeaderInformation(..) **ERROR** runHeader object has " << runHeader->GetEntries() << " entries."; - cerr << endl << ">> minimum number of required entries = " << TPRH_MIN_NO_REQUIRED_ENTRIES << "!" << endl << endl; + if (headerInfo == 0) { + cerr << endl << ">> TPsiRunHeader::ExtractHeaderInformation(..) **ERROR** headerInfo object pointer is 0" << endl << endl; return false; } // start extracting entries + TObjArray *tokens, *tokens1; TObjString *ostr; TString str(""); - Int_t idx, status, ival; + Int_t idx; + Double_t dval; // not TPsiRunProperty header variables - for (Int_t i=0; i(runHeader->At(i)); + for (Int_t i=0; iGetEntries(); i++) { + ostr = dynamic_cast(headerInfo->At(i)); str = ostr->GetString(); - if (str.BeginsWith("01 - Version: ")) { + if (str.Contains("- Version: ")) { idx = str.Index(":"); str.Remove(0, idx+2); fVersion = str; - } else if (str.BeginsWith("02 - Run Title: ")) { + } else if (str.Contains("- Generator: ")) { + idx = str.Index(":"); + str.Remove(0, idx+2); + fGenerator = str; + } else if (str.Contains("- File Name: ")) { + idx = str.Index(":"); + str.Remove(0, idx+2); + fFileName = str; + } else if (str.Contains("- Run Title: ")) { idx = str.Index(":"); str.Remove(0, idx+2); fRunTitle = str; - } else if (str.BeginsWith("03 - Run Number: ")) { - status = sscanf(str.Data(), "03 - Run Number: %d", &ival); - if (status != 1) { + } else if (str.Contains("- Run Number: ")) { + tokens = str.Tokenize(":"); + if (tokens->GetEntries() < 2) { + cerr << endl << ">> TPsiRunHeader::ExtractHeaderInformation(..) **ERROR** " << str.Data() << " couldn't tokenize it." << endl << endl; + return false; + } + ostr = dynamic_cast(tokens->At(1)); + if (!ostr->GetString().IsDigit()) { cerr << endl << ">> TPsiRunHeader::ExtractHeaderInformation(..) **ERROR** " << str.Data() << " doesn't contain a valid run number" << endl << endl; return false; } - fRunNumber = ival; - } else if (str.BeginsWith("04 - Laboratory: ")) { + fRunNumber = ostr->GetString().Atoi(); + // clean up + CleanUp(tokens); + } else if (str.Contains("- Run Start Time: ")) { + idx = str.Index(":"); + str.Remove(0, idx+2); + fStartTime = TDatime(str); + } else if (str.Contains("- Run Stop Time: ")) { + idx = str.Index(":"); + str.Remove(0, idx+2); + fStopTime = TDatime(str); + } else if (str.Contains("- Laboratory: ")) { idx = str.Index(":"); str.Remove(0, idx+2); fLaboratory = str; - } else if (str.BeginsWith("05 - Instrument: ")) { + } else if (str.Contains("- Area: ")) { + idx = str.Index(":"); + str.Remove(0, idx+2); + fArea = str; + } else if (str.Contains("- Instrument: ")) { idx = str.Index(":"); str.Remove(0, idx+2); fInstrument = str; - } else if (str.BeginsWith("06 - Setup: ")) { + } else if (str.Contains("- Muon Species: ")) { + idx = str.Index(":"); + str.Remove(0, idx+2); + fMuonSpecies = str; + } else if (str.Contains("- Setup: ")) { idx = str.Index(":"); str.Remove(0, idx+2); fSetup = str; - } else if (str.BeginsWith("07 - Sample: ")) { + } else if (str.Contains("- Sample: ")) { idx = str.Index(":"); str.Remove(0, idx+2); fSample = str; - } else if (str.BeginsWith("08 - Orientation: ")) { + } else if (str.Contains("- Cryo: ")) { + idx = str.Index(":"); + str.Remove(0, idx+2); + fSampleCryo = str; + } else if (str.Contains("- Orientation: ")) { idx = str.Index(":"); str.Remove(0, idx+2); fOrientation = str; + } else if (str.Contains("- Insert: ")) { + idx = str.Index(":"); + str.Remove(0, idx+2); + fSampleCryoInsert = str; + } else if (str.Contains("- No of Histos: ")) { + tokens = str.Tokenize(":"); + if (tokens->GetEntries() < 2) { + cerr << endl << ">> TPsiRunHeader::ExtractHeaderInformation(..) **ERROR** " << str.Data() << " couldn't tokenize it." << endl << endl; + // clean up + CleanUp(tokens); + return false; + } + ostr = dynamic_cast(tokens->At(1)); + if (!ostr->GetString().IsDigit()) { + cerr << endl << ">> TPsiRunHeader::ExtractHeaderInformation(..) **ERROR** " << str.Data() << " doesn't contain a valid number" << endl << endl; + return false; + } + fNoOfHistos = ostr->GetString().Atoi(); + // clean up + CleanUp(tokens); + } else if (str.Contains("- Histo Names: ")) { + tokens = str.Tokenize(":"); + if (tokens->GetEntries() < 2) { + cerr << endl << ">> TPsiRunHeader::ExtractHeaderInformation(..) **ERROR** " << str.Data() << " couldn't tokenize it." << endl << endl; + // clean up + CleanUp(tokens); + return false; + } + ostr = dynamic_cast(tokens->At(1)); + tokens1 = ostr->GetString().Tokenize(";"); + for (Int_t i=0; iGetEntries(); i++) { + ostr = dynamic_cast(tokens1->At(i)); + str = ostr->GetString(); + str.Remove(TString::kBoth, ' '); + fHistoName.push_back(str); + } + // clean up + CleanUp(tokens1); + CleanUp(tokens); + } else if (str.Contains("- Histo Length: ")) { + tokens = str.Tokenize(":"); + if (tokens->GetEntries() < 2) { + cerr << endl << ">> TPsiRunHeader::ExtractHeaderInformation(..) **ERROR** " << str.Data() << " couldn't tokenize it." << endl << endl; + // clean up + CleanUp(tokens); + return false; + } + ostr = dynamic_cast(tokens->At(1)); + if (!ostr->GetString().IsDigit()) { + cerr << endl << ">> TPsiRunHeader::ExtractHeaderInformation(..) **ERROR** " << str.Data() << " doesn't contain a valid number" << endl << endl; + return false; + } + fHistoLength = ostr->GetString().Atoi(); + // clean up + CleanUp(tokens); + } else if (str.Contains("- Time Resolution: ")) { + tokens = str.Tokenize(":"); + if (tokens->GetEntries() < 2) { + cerr << endl << ">> TPsiRunHeader::ExtractHeaderInformation(..) **ERROR** " << str.Data() << " couldn't tokenize it." << endl << endl; + // clean up + CleanUp(tokens); + return false; + } + ostr = dynamic_cast(tokens->At(1)); // + tokens1 = ostr->GetString().Tokenize(" "); + if (tokens1->GetEntries() < 2) { + cerr << endl << ">> TPsiRunHeader::ExtractHeaderInformation(..) **ERROR** " << str.Data() << " couldn't tokenize it." << endl << endl; + // clean up + CleanUp(tokens1); + CleanUp(tokens); + return false; + } + ostr = dynamic_cast(tokens1->At(0)); // + if (!ostr->GetString().IsFloat()) { + cerr << endl << ">> TPsiRunHeader::ExtractHeaderInformation(..) **ERROR** " << str.Data() << " seems not be a valid time resolution." << endl << endl; + // clean up + CleanUp(tokens1); + CleanUp(tokens); + return false; + } + dval = ostr->GetString().Atof(); + ostr = dynamic_cast(tokens1->At(1)); // + SetTimeResolution(dval, ostr->GetString()); + // clean up + CleanUp(tokens1); + CleanUp(tokens); + } else if (str.Contains("- Time Zero Bin: ")) { + tokens = str.Tokenize(":"); + if (tokens->GetEntries() < 2) { + cerr << endl << ">> TPsiRunHeader::ExtractHeaderInformation(..) **ERROR** " << str.Data() << " couldn't tokenize it." << endl << endl; + // clean up + CleanUp(tokens); + return false; + } + ostr = dynamic_cast(tokens->At(1)); + tokens1 = ostr->GetString().Tokenize(";"); + for (Int_t i=0; iGetEntries(); i++) { + ostr = dynamic_cast(tokens1->At(i)); + fTimeZeroBin.push_back(ostr->GetString().Atoi()); + } + // clean up + CleanUp(tokens1); + CleanUp(tokens); + } else if (str.Contains("- First Good Bin: ")) { + tokens = str.Tokenize(":"); + if (tokens->GetEntries() < 2) { + cerr << endl << ">> TPsiRunHeader::ExtractHeaderInformation(..) **ERROR** " << str.Data() << " couldn't tokenize it." << endl << endl; + // clean up + CleanUp(tokens); + return false; + } + ostr = dynamic_cast(tokens->At(1)); + tokens1 = ostr->GetString().Tokenize(";"); + for (Int_t i=0; iGetEntries(); i++) { + ostr = dynamic_cast(tokens1->At(i)); + fFirstGoodBin.push_back(ostr->GetString().Atoi()); + } + // clean up + CleanUp(tokens1); + CleanUp(tokens); + } else if (str.Contains("- Last Good Bin: ")) { + tokens = str.Tokenize(":"); + if (tokens->GetEntries() < 2) { + cerr << endl << ">> TPsiRunHeader::ExtractHeaderInformation(..) **ERROR** " << str.Data() << " couldn't tokenize it." << endl << endl; + // clean up + CleanUp(tokens); + return false; + } + ostr = dynamic_cast(tokens->At(1)); + tokens1 = ostr->GetString().Tokenize(";"); + for (Int_t i=0; iGetEntries(); i++) { + ostr = dynamic_cast(tokens1->At(i)); + fLastGoodBin.push_back(ostr->GetString().Atoi()); + } + // clean up + CleanUp(tokens1); + CleanUp(tokens); + } else if (str.Contains("- Red/Green offsets: ")) { + tokens = str.Tokenize(":"); + if (tokens->GetEntries() < 2) { + cerr << endl << ">> TPsiRunHeader::ExtractHeaderInformation(..) **ERROR** " << str.Data() << " couldn't tokenize it." << endl << endl; + // clean up + CleanUp(tokens); + return false; + } + ostr = dynamic_cast(tokens->At(1)); + tokens1 = ostr->GetString().Tokenize(";"); + for (Int_t i=0; iGetEntries(); i++) { + ostr = dynamic_cast(tokens1->At(i)); + fRedGreenOffset.push_back(ostr->GetString().Atoi()); + } + // clean up + CleanUp(tokens1); + CleanUp(tokens); + } else if (str.Contains("- Red/Green description: ")) { + tokens = str.Tokenize(":"); + if (tokens->GetEntries() < 2) { + cerr << endl << ">> TPsiRunHeader::ExtractHeaderInformation(..) **ERROR** " << str.Data() << " couldn't tokenize it." << endl << endl; + // clean up + CleanUp(tokens); + return false; + } + ostr = dynamic_cast(tokens->At(1)); + tokens1 = ostr->GetString().Tokenize(";"); + for (Int_t i=0; iGetEntries(); i++) { + ostr = dynamic_cast(tokens1->At(i)); + str = ostr->GetString(); + str.Remove(TString::kBoth, ' '); + fRedGreenDescription.push_back(str); + } + // clean up + CleanUp(tokens1); + CleanUp(tokens); } } // TPsiRunProperty header variables - - // remove potential left over properties - fProperties.clear(); - TPsiRunProperty prop; - for (Int_t i=TPRH_OFFSET-1; iGetEntries(); i++) { - if (DecodePhyscialPorperty(dynamic_cast(runHeader->At(i)), prop)) { - AddProperty(prop); - } else { - return false; + for (Int_t i=0; iGetEntries(); i++) { + ostr = dynamic_cast(headerInfo->At(i)); + if (ostr->GetString().Contains("+-")) { + if (DecodePhyscialPorperty(ostr, prop, path)) { + AddProperty(prop); + } else { + return false; + } } } - return true; } +//-------------------------------------------------------------------------- +// SetStartTime (public) +//-------------------------------------------------------------------------- +/** + *

Sets the run start time. It validates that the 'startTime' is a ISO 8601 + * time/date. If 'startTime' is not ISO 8601 compatible, an error message is + * sent to stderr but the run start time is not set. + * + * \param startTime ISO 8601 run start time + */ +void TPsiRunHeader::SetStartTime(TString startTime) +{ + // check that startTime is ISO 8601 compatible + struct tm tm; + memset(&tm, 0, sizeof(tm)); + strptime(startTime.Data(), "%Y-%m-%d %H:%M:S", &tm); + if (tm.tm_year == 0) + strptime(startTime.Data(), "%Y-%m-%dT%H:%M:S", &tm); + if (tm.tm_year == 0) { + cerr << endl << ">> **ERRO** TPsiRunHeader::SetStartTime(): " << startTime.Data() << " is not a ISO 8601 compatible date/time. Will not set it." << endl; + return; + } + + fStartTime.Set(startTime); +} + +//-------------------------------------------------------------------------- +// SetStopTime (public) +//-------------------------------------------------------------------------- +/** + *

Sets the run stop time. It validates that the 'stopTime' is a ISO 8601 + * time/date. If 'stopTime' is not ISO 8601 compatible, an error message is + * sent to stderr but the run stop time is not set. + * + * \param stopTime ISO 8601 run stop time + */ +void TPsiRunHeader::SetStopTime(TString stopTime) +{ + // check that stopTime is ISO 8601 compatible + struct tm tm; + memset(&tm, 0, sizeof(tm)); + strptime(stopTime.Data(), "%Y-%m-%d %H:%M:S", &tm); + if (tm.tm_year == 0) + strptime(stopTime.Data(), "%Y-%m-%dT%H:%M:S", &tm); + if (tm.tm_year == 0) { + cerr << endl << ">> **ERRO** TPsiRunHeader::SetStopTime(): " << stopTime.Data() << " is not a ISO 8601 compatible date/time. Will not set it." << endl; + return; + } + + fStopTime.Set(stopTime); +} + +//-------------------------------------------------------------------------- +// SetHistoName (public) +//-------------------------------------------------------------------------- +/** + *

Set the histogram name at index 'idx'. If 'idx' == -1, the name is appended. + * + * \param name histogram name + * \param idx histogram index + */ +void TPsiRunHeader::SetHistoName(TString name, Int_t idx) +{ + if (idx == -1) { + fHistoName.push_back(name); + } else if (idx >= (Int_t)fHistoName.size()) { + fHistoName.resize(idx+1); + fHistoName[idx] = name; + } else { + fHistoName[idx] = name; + } +} + +//-------------------------------------------------------------------------- +// SetTimeResolution (public) +//-------------------------------------------------------------------------- +/** + *

Set the time resolution. 'value' is given in 'units'. Allowed 'units' + * are fs, ps, ns, us. + * + * \param value time resolution value + * \param unit time resolution units + */ +void TPsiRunHeader::SetTimeResolution(Double_t value, TString units) +{ + Double_t factor = 0.0; + + if (!units.CompareTo("fs", TString::kIgnoreCase)) { + factor = 1.0e-3; + } else if (!units.CompareTo("ps", TString::kIgnoreCase)) { + factor = 1.0; + } else if (!units.CompareTo("ns", TString::kIgnoreCase)) { + factor = 1.0e3; + } else if (!units.CompareTo("us", TString::kIgnoreCase)) { + factor = 1.0e6; + } else { + factor = 0.0; + } + + fTimeResolution = factor * value; +} + +//-------------------------------------------------------------------------- +// SetTimeZeroBin (public) +//-------------------------------------------------------------------------- +/** + *

Set the time zero bin at index 'idx'. If 'idx' == -1, the time zero bin is appended. + * + * \param timeZeroBin time zero bin + * \param idx histogram index + */ +void TPsiRunHeader::SetTimeZeroBin(UInt_t timeZeroBin, Int_t idx) +{ + if (idx == -1) { + fTimeZeroBin.push_back(timeZeroBin); + } else if (idx >= (Int_t)fTimeZeroBin.size()) { + fTimeZeroBin.resize(idx+1); + fTimeZeroBin[idx] = timeZeroBin; + } else { + fTimeZeroBin[idx] = timeZeroBin; + } +} + +//-------------------------------------------------------------------------- +// SetFirstGoodBin (public) +//-------------------------------------------------------------------------- +/** + *

Set the first good bin at index 'idx'. If 'idx' == -1, the first good bin is appended. + * + * \param fgb first good bin + * \param idx histogram index + */ +void TPsiRunHeader::SetFirstGoodBin(UInt_t fgb, Int_t idx) +{ + if (idx == -1) { + fFirstGoodBin.push_back(fgb); + } else if (idx >= (Int_t)fFirstGoodBin.size()) { + fFirstGoodBin.resize(idx+1); + fFirstGoodBin[idx] = fgb; + } else { + fFirstGoodBin[idx] = fgb; + } +} + +//-------------------------------------------------------------------------- +// SetLastGoodBin (public) +//-------------------------------------------------------------------------- +/** + *

Set the last good bin at index 'idx'. If 'idx' == -1, the last good bin is appended. + * + * \param lgb last good bin + * \param idx histogram index + */ +void TPsiRunHeader::SetLastGoodBin(UInt_t lgb, Int_t idx) +{ + if (idx == -1) { + fLastGoodBin.push_back(lgb); + } else if (idx >= (Int_t)fLastGoodBin.size()) { + fLastGoodBin.resize(idx+1); + fLastGoodBin[idx] = lgb; + } else { + fLastGoodBin[idx] = lgb; + } +} + +//-------------------------------------------------------------------------- +// SetRedGreenHistogramOffset (public) +//-------------------------------------------------------------------------- +/** + *

Set the red/green mode histogram offset at index 'idx'. If 'idx' == -1, the red/green mode histogram offset is appended. + * + * \param offset red/green mode histogram offset + * \param idx histogram index + */ +void TPsiRunHeader::SetRedGreenHistogramOffset(UInt_t offset, Int_t idx) +{ + if (idx == -1) { + fRedGreenOffset.push_back(offset); + } else if (idx >= (Int_t)fRedGreenOffset.size()) { + fRedGreenOffset.resize(idx+1); + fRedGreenOffset[idx] = offset; + } else { + fRedGreenOffset[idx] = offset; + } +} + +//-------------------------------------------------------------------------- +// SetRedGreenDescription (public) +//-------------------------------------------------------------------------- +/** + *

Set the red/green mode description at index 'idx'. If 'idx' == -1, the red/green mode description is appended. + * + * \param description red/green mode description + * \param idx histogram index + */ +void TPsiRunHeader::SetRedGreenDescription(TString description, Int_t idx) +{ + if (idx == -1) { + fRedGreenDescription.push_back(description); + } else if (idx >= (Int_t)fRedGreenDescription.size()) { + fRedGreenDescription.resize(idx+1); + fRedGreenDescription[idx] = description; + } else { + fRedGreenDescription[idx] = description; + } +} + //-------------------------------------------------------------------------- // AddProperty (public) //-------------------------------------------------------------------------- @@ -354,10 +1465,10 @@ void TPsiRunHeader::AddProperty(TPsiRunProperty &property) * \param error * \param unit */ -void TPsiRunHeader::AddProperty(TString name, Double_t demand, Double_t value, Double_t error, TString unit, TString description) +void TPsiRunHeader::AddProperty(TString name, Double_t demand, Double_t value, Double_t error, TString unit, TString description, TString path) { - TPsiRunProperty property(name, demand, value, error, unit, description); - fProperties.push_back(property); + TPsiRunProperty prop(name, demand, value, error, unit, description, path); + fProperties.push_back(prop); } //-------------------------------------------------------------------------- @@ -368,6 +1479,8 @@ void TPsiRunHeader::AddProperty(TString name, Double_t demand, Double_t value, D */ void TPsiRunHeader::DumpHeader() const { + const TPsiRunProperty *prop; + int old_width = cout.width(); // get maximal length of the property names @@ -381,39 +1494,182 @@ void TPsiRunHeader::DumpHeader() const // write SVN versions cout << endl << setw(name_width) << left << "Version" << setw(old_width) << ": " << GetVersion().Data(); + // write generator + cout << endl << setw(name_width) << left << "Generator" << setw(old_width) << ": " << GetGenerator().Data(); + + // write file name + cout << endl << setw(name_width) << left << "File Name" << setw(old_width) << ": " << GetFileName().Data(); + // write run title cout << endl << setw(name_width) << left << "Run Title" << setw(old_width) << ": " << GetRunTitle().Data(); // write run number cout << endl << setw(name_width) << left << "Run Number" << setw(old_width) << ": " << GetRunNumber(); + // write start time + cout << endl << setw(name_width) << left << "Run Start Time" << setw(old_width) << ": " << GetStartTimeString(); + + // write stop time + cout << endl << setw(name_width) << left << "Run Stop Time" << setw(old_width) << ": " << GetStopTimeString(); + // write laboratory - cout << endl << setw(name_width) << left << "Laboratory" << setw(old_width) << ": " << GetLab().Data(); + cout << endl << setw(name_width) << left << "Laboratory" << setw(old_width) << ": " << GetLaboratory().Data(); + + // write area + cout << endl << setw(name_width) << left << "Area" << setw(old_width) << ": " << GetArea().Data(); // write instrument cout << endl << setw(name_width) << left << "Instrument" << setw(old_width) << ": " << GetInstrument().Data(); + // write muon species + cout << endl << setw(name_width) << left << "Muon Species" << setw(old_width) << ": " << GetMuonSpecies().Data(); + // write setup cout << endl << setw(name_width) << left << "Setup" << setw(old_width) << ": " << GetSetup().Data(); // write sample cout << endl << setw(name_width) << left << "Sample" << setw(old_width) << ": " << GetSample().Data(); - // write orientation - cout << endl << setw(name_width) << left << "Orientation" << setw(old_width) << ": " << GetOrientation().Data(); - - for (UInt_t i=0; iGetLabel().Data() << setw(old_width) << ": " << prop->GetValue() << " +- " << prop->GetError() << " " << prop->GetUnit().Data(); + cout << "; SP: " << prop->GetDemand(); + if (prop->GetDescription().CompareTo("n/a", TString::kIgnoreCase)) { + cout << "; " << prop->GetDescription().Data(); } } + + // write sample magnetic field + prop = GetProperty("Sample Magnetic Field"); + if (prop != 0) { + cout << endl << setw(name_width) << left << prop->GetLabel().Data() << setw(old_width) << ": " << prop->GetValue() << " +- " << prop->GetError() << " " << prop->GetUnit().Data(); + cout << "; SP: " << prop->GetDemand(); + if (prop->GetDescription().CompareTo("n/a", TString::kIgnoreCase)) { + cout << "; " << prop->GetDescription().Data(); + } + } + + // write number of histograms + cout << endl << setw(name_width) << left << "No of Histos" << setw(old_width) << ": " << GetNoOfHistos(); + + // write histogram names + if (fHistoName.size() > 0) { + cout << endl << setw(name_width) << left << "Histo Names" << setw(old_width) << ": "; + for (UInt_t i=0; i 0) { + cout << endl << setw(name_width) << left << "Time Zero Bin" << setw(old_width) << ": "; + for (UInt_t i=0; i 0) { + cout << endl << setw(name_width) << left << "First Good Bin" << setw(old_width) << ": "; + for (UInt_t i=0; i 0) { + cout << endl << setw(name_width) << left << "Last Good Bin" << setw(old_width) << ": "; + for (UInt_t i=0; i 0) { + cout << endl << setw(name_width) << left << "Red/Green offsets" << setw(old_width) << ": "; + for (UInt_t i=0; i 0) { + cout << endl << setw(name_width) << left << "Red/Green description" << setw(old_width) << ": "; + for (UInt_t i=0; iGetString().Tokenize("-:"); TObjArray *tokens1 = 0; @@ -467,10 +1724,7 @@ Bool_t TPsiRunHeader::DecodePhyscialPorperty(TObjString *oprop, TPsiRunProperty str.Remove(TString::kLeading, ' '); prop.SetLabel(str); - if (tokens) { - delete tokens; - tokens = 0; - } + CleanUp(tokens); // get measured value tokens = oprop->GetString().Tokenize(":"); @@ -483,18 +1737,13 @@ Bool_t TPsiRunHeader::DecodePhyscialPorperty(TObjString *oprop, TPsiRunProperty 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; - } + CleanUp(tokens); 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; - } + CleanUp(tokens1); + CleanUp(tokens); return false; } @@ -504,9 +1753,7 @@ Bool_t TPsiRunHeader::DecodePhyscialPorperty(TObjString *oprop, TPsiRunProperty prop.SetValue(ostr->GetString().Atof()); } else { cerr << endl << ">> **ERROR** unexpected measured value. Found " << ostr->GetString().Data() << ", expected float." << endl; - if (tokens) { - delete tokens; - } + CleanUp(tokens); return false; } @@ -516,9 +1763,7 @@ Bool_t TPsiRunHeader::DecodePhyscialPorperty(TObjString *oprop, TPsiRunProperty prop.SetError(ostr->GetString().Atof()); } else { cerr << endl << ">> **ERROR** unexpected estimated error. Found " << ostr->GetString().Data() << ", expected float." << endl; - if (tokens) { - delete tokens; - } + CleanUp(tokens); return false; } @@ -528,20 +1773,14 @@ Bool_t TPsiRunHeader::DecodePhyscialPorperty(TObjString *oprop, TPsiRunProperty str.Remove(TString::kLeading, ' '); prop.SetUnit(str); - if (tokens1) { - delete tokens1; - tokens1 = 0; - } + CleanUp(tokens1); 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; - } + CleanUp(tokens); return false; } @@ -551,9 +1790,7 @@ Bool_t TPsiRunHeader::DecodePhyscialPorperty(TObjString *oprop, TPsiRunProperty prop.SetDemand(ostr->GetString().Atof()); } else { cerr << endl << ">> **ERROR** unexpected demand value. Found " << ostr->GetString().Data() << ", expected float." << endl; - if (tokens) { - delete tokens; - } + CleanUp(tokens); return false; } @@ -564,13 +1801,11 @@ Bool_t TPsiRunHeader::DecodePhyscialPorperty(TObjString *oprop, TPsiRunProperty prop.SetDescription(str); } + prop.SetPath(path); - if (tokens1) { - delete tokens1; - } - if (tokens) { - delete tokens; - } + // clean up + CleanUp(tokens1); + CleanUp(tokens); return true; } @@ -612,7 +1847,7 @@ UInt_t TPsiRunHeader::GetDecimalPlace(Double_t val) UInt_t TPsiRunHeader::GetLeastSignificantDigit(Double_t val) const { char cstr[1024]; - sprintf(cstr, "%lf", val); + snprintf(cstr, sizeof(cstr), "%.20lf", val); int i=0, j=0; for (i=strlen(cstr)-1; i>=0; i--) { @@ -629,3 +1864,19 @@ UInt_t TPsiRunHeader::GetLeastSignificantDigit(Double_t val) const return i-j; } + +//-------------------------------------------------------------------------- +// CleanUp (private) +//-------------------------------------------------------------------------- +/** + *

Cleans up ROOT objects. + * + * \param obj pointer to the object to be cleaned up. + */ +void TPsiRunHeader::CleanUp(TObject *obj) +{ + if (obj) { + delete obj; + obj = 0; + } +} diff --git a/src/tests/PsiRoot/TPsiRunHeader.h b/src/tests/PsiRoot/TPsiRunHeader.h index d3147145..761e79a3 100644 --- a/src/tests/PsiRoot/TPsiRunHeader.h +++ b/src/tests/PsiRoot/TPsiRunHeader.h @@ -32,6 +32,7 @@ #ifndef TPSIRUNHEADER_H #define TPSIRUNHEADER_H +#include #include #include #include @@ -40,25 +41,28 @@ class TPsiRunProperty : public TObject { public: TPsiRunProperty(); - TPsiRunProperty(TString &name, Double_t demand, Double_t value, Double_t error, TString &unit, TString &description); - virtual ~TPsiRunProperty(); + TPsiRunProperty(TString &name, Double_t demand, Double_t value, Double_t error, TString &unit, TString &description, TString &path); + virtual ~TPsiRunProperty() {} - virtual TString GetLabel() const { return fLabel; } + 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 TString GetPath() const { return fPath; } 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(TString &unit) { fUnit = unit; } virtual void SetUnit(const char *unit) { fUnit = unit; } - virtual void SetDescription(TString &str) { fDescription = str.Data(); } + virtual void SetDescription(TString &str) { fDescription = str; } virtual void SetDescription(const char *str) { fDescription = str; } + virtual void SetPath(TString &str) { fPath = str; } + virtual void SetPath(const char *str) { fPath = str; } private: TString fLabel; ///< property label, like ’Sample Temperature’ etc. @@ -67,6 +71,7 @@ private: 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 + TString fPath; ///< ROOT file path where to place the physical property ClassDef(TPsiRunProperty, 1) }; @@ -77,52 +82,136 @@ public: TPsiRunHeader(); virtual ~TPsiRunHeader(); + virtual Bool_t IsValid(Bool_t strict = false); + virtual TString GetVersion() const { return fVersion; } + virtual TString GetGenerator() const { return fGenerator; } + virtual TString GetFileName() const { return fFileName; } virtual TString GetRunTitle() const { return fRunTitle; } virtual Int_t GetRunNumber() const { return fRunNumber; } - virtual TString GetLab() const { return fLaboratory; } + virtual TDatime GetStartTime() const { return fStartTime; } + virtual const char* GetStartTimeString() const { return fStartTime.AsSQLString(); } + virtual TDatime GetStopTime() const { return fStopTime; } + virtual const char* GetStopTimeString() const { return fStopTime.AsSQLString(); } + virtual TString GetLaboratory() const { return fLaboratory; } + virtual TString GetArea() const { return fArea; } virtual TString GetInstrument() const { return fInstrument; } + virtual TString GetMuonSpecies() const { return fMuonSpecies; } 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 TString GetSampleCryo() const { return fSampleCryo; } + virtual TString GetSampleCryoInsert() const { return fSampleCryoInsert; } + virtual TString GetSampleMagnetName() const { return fMagnetName; } + virtual Int_t GetNoOfHistos() const { return fNoOfHistos; } + virtual UInt_t GetNoOfHistoNames() const { return fHistoName.size(); } + virtual const vector* GetHistoNames() const { return &fHistoName; } + virtual TString GetHistoName(UInt_t idx, Bool_t &ok) const; + virtual Int_t GetHistoLength() const { return fHistoLength; } + virtual Double_t GetTimeResolution(const char *units) const; + virtual UInt_t GetNoOfTimeZeroBins() const { return fTimeZeroBin.size(); } + virtual const vector* GetTimeZeroBins() const { return &fTimeZeroBin; } + virtual UInt_t GetTimeZeroBin(UInt_t idx, Bool_t &ok) const; + virtual const vector* GetFirstGoodBins() const { return &fFirstGoodBin;} + virtual UInt_t GetFirstGoodBin(UInt_t idx, Bool_t &ok) const; + virtual const vector* GetLastGoodBins() const { return &fLastGoodBin;} + virtual UInt_t GetLastGoodBin(UInt_t idx, Bool_t &ok) const; + virtual UInt_t GetNoOfRedGreenHistoOffsets() const { return fRedGreenOffset.size(); } + virtual const vector* GetRedGreenHistoOffsets() const { return &fRedGreenOffset; } + virtual UInt_t GetRedGreenHistoOffset(UInt_t idx, Bool_t &ok) const; + virtual const vector* GetRedGreenHistoDescriptions() const { return &fRedGreenDescription; } + virtual TString GetRedGreenHistoDescription(UInt_t idx, Bool_t &ok) const; + virtual const TPsiRunProperty* GetProperty(TString name) const; + virtual const vector *GetProperties() const { return &fProperties; } - virtual TObjArray *GetHeader(); - virtual Bool_t ExtractHeaderInformation(TObjArray *runHeader); + virtual TObjArray *GetHeader(UInt_t &count); + virtual TObjArray *GetSampleEnv(UInt_t &count); + virtual TObjArray *GetMagFieldEnv(UInt_t &count); + virtual TObjArray *GetBeamline(UInt_t &count); + virtual TObjArray *GetScaler(UInt_t &count); + virtual Bool_t ExtractHeaderInformation(TObjArray *headerInfo, TString path="/"); + + virtual void SetGenerator(TString generator) { fGenerator = generator; } + virtual void SetFileName(TString fileName) { fFileName = fileName; } virtual void SetRunTitle(TString runTitle) { fRunTitle = runTitle; } virtual void SetRunNumber(Int_t runNumber) { fRunNumber = runNumber; } - virtual void SetLab(TString lab) { fLaboratory = lab; } + virtual void SetStartTime(TString startTime); + virtual void SetStopTime(TString stopTime); + virtual void SetLaboratory(TString lab) { fLaboratory = lab; } + virtual void SetArea(TString area) { fArea = area;} virtual void SetInstrument(TString insturment) { fInstrument = insturment; } + virtual void SetMuonSpecies(TString muonSpecies) { fMuonSpecies = muonSpecies; } virtual void SetSetup(TString setup) { fSetup = setup; } virtual void SetSample(TString sample) { fSample = sample; } virtual void SetOrientation(TString orientation) { fOrientation = orientation; } + virtual void SetSampleCryo(TString cryoName) { fSampleCryo = cryoName; } + virtual void SetSampleCryoInsert(TString cryoInsert) { fSampleCryoInsert = cryoInsert; } + virtual void SetSampleMagnetName(TString name) { fMagnetName = name; } + virtual void SetNoOfHistos(UInt_t noHistos) { fNoOfHistos = noHistos; } + virtual void SetHistoNames(vector names) { fHistoName = names; } + virtual void SetHistoName(TString name, Int_t idx=-1); + virtual void SetHistoLength(UInt_t length) { fHistoLength = (Int_t)length; } + virtual void SetTimeResolution(Double_t value, TString units); + virtual void SetTimeZeroBins(vector timeZeroBins) { fTimeZeroBin = timeZeroBins; } + virtual void SetTimeZeroBin(UInt_t timeZeroBin, Int_t idx=-1); + virtual void SetFirstGoodBins(vector fgb) { fFirstGoodBin = fgb; } + virtual void SetFirstGoodBin(UInt_t fgb, Int_t idx=-1); + virtual void SetLastGoodBins(vector lgb) { fLastGoodBin = lgb; } + virtual void SetLastGoodBin(UInt_t lgb, Int_t idx=-1); + virtual void SetRedGreenHistogramOffsets(vector offsets) { fRedGreenOffset = offsets; } + virtual void SetRedGreenHistogramOffset(UInt_t offset, Int_t idx=-1); + virtual void SetRedGreenDescriptions(vector description) { fRedGreenDescription = description; } + virtual void SetRedGreenDescription(TString description, Int_t idx=-1); virtual void AddProperty(TPsiRunProperty &property); - virtual void AddProperty(TString name, Double_t demand, Double_t value, Double_t error, TString unit, TString desciption=TString("")); + virtual void AddProperty(TString name, Double_t demand, Double_t value, Double_t error, TString unit, TString desciption=TString(""), TString path=TString("/")); virtual void DumpHeader() const; virtual void DrawHeader() const; private: - TString fVersion; /// SVN version of the TPsiRunHeader - TString fRunTitle; /// run title - Int_t fRunNumber; /// run number - TString fLaboratory; /// laboratory: PSI - TString fInstrument; /// instrument name like: GPS, LEM, .... - TString fSetup; /// setup - TString fSample; /// sample name - TString fOrientation; /// sample orientation + TString fVersion; ///< SVN version of the TPsiRunHeader + TString fGenerator; ///< program which generated the PSI-ROOT file + TString fFileName; ///< file name of the PSI-ROOT file + TString fRunTitle; ///< run title + Int_t fRunNumber; ///< run number + TDatime fStartTime; ///< run start time + TDatime fStopTime; ///< run stop time + TString fLaboratory; ///< laboratory: PSI + TString fArea; ///< secondary beamline label, e.g. piM3.2 + TString fInstrument; ///< instrument name like: GPS, LEM, .... + TString fMuonSpecies; ///< postive muon or negative muon + TString fSetup; ///< setup + TString fSample; ///< sample name + TString fOrientation; ///< sample orientation + TString fSampleCryo; ///< sample cryo + TString fSampleCryoInsert; ///< sample cryo insert + TString fMagnetName; ///< name of the magnet used + Int_t fNoOfHistos; ///< number of histos + vector fHistoName; ///< names of the individual histograms + Int_t fHistoLength; ///< length of the histograms in bins + Double_t fTimeResolution; ///< time resolution in ps + vector fTimeZeroBin; ///< time zero bins + vector fFirstGoodBin; ///< first good bins + vector fLastGoodBin; ///< last good bins + vector fRedGreenOffset; ///< red/green mode histogram offsets + vector fRedGreenDescription; ///< red/green mode description vector fProperties; - TObjArray fHeader; /// header as TObjString array for dumping into a ROOT file + TObjArray fHeader; ///< header as TObjString array for dumping into a ROOT file + TObjArray fSampleEnv; ///< sample environment as TObjString array for dumping into a ROOT file + TObjArray fMagFieldEnv; ///< sample magnetic field environment as TObjString array for dumping into a ROOT file + TObjArray fBeamline; ///< beamline info as TObjString array for dumping into a ROOT file + TObjArray fScalers; ///< scaler info as TObjString array for dumping into a ROOT file - virtual Bool_t DecodePhyscialPorperty(TObjString *ostr, TPsiRunProperty &prop); + virtual Bool_t DecodePhyscialPorperty(TObjString *ostr, TPsiRunProperty &prop, TString &path); virtual UInt_t GetDecimalPlace(Double_t val); virtual UInt_t GetLeastSignificantDigit(Double_t val) const; + virtual void CleanUp(TObject *obj); + ClassDef(TPsiRunHeader, 1) }; diff --git a/src/tests/PsiRoot/psi_runHeader_test.cpp b/src/tests/PsiRoot/psi_runHeader_test.cpp index b8a367da..f25d2c7c 100644 --- a/src/tests/PsiRoot/psi_runHeader_test.cpp +++ b/src/tests/PsiRoot/psi_runHeader_test.cpp @@ -55,20 +55,56 @@ int main(int argc, char *argv[]) // PSI Run Header object TPsiRunHeader *header = new TPsiRunHeader(); + header->SetGenerator("psi_runHeader_test"); + header->SetFileName(argv[1]); header->SetRunTitle("This is a run title"); header->SetRunNumber(12345); - header->SetLab("PSI"); + header->SetStartTime("2011-08-31 08:03:23"); + header->SetStopTime("2011-08-31 10:46:48"); + header->SetLaboratory("PSI"); header->SetInstrument("LEM"); + header->SetArea("muE4"); + header->AddProperty("Muon Beam Momentum", 28.0, 28.0, 0.7, "MeV/c"); + header->SetMuonSpecies("positive Muon"); header->SetSetup("Konti-4, WEW"); header->SetSample("Eu2CuO4 MOD thin film"); - header->SetOrientation("c-axis perp to spin"); - 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"); + header->AddProperty("Sample Magnetic Field", 3.0, 3.0003, 0.000025, "T"); + header->SetOrientation("c-axis perp to spin"); + header->AddProperty("T1", 30.0, 30.003, 0.003, "K", "sample stick temperature", "/SampleEnv/"); + header->SetSampleCryo("Konti-4"); + header->SetSampleCryoInsert("n/a"); + header->SetSampleMagnetName("Bpar"); + header->AddProperty("Current", 1.54, 1.54, 0.003, "A", "Danfysik", "/MagFieldEnv/"); + + header->SetNoOfHistos(8); + header->SetHistoName("left/forward"); + header->SetHistoName("top/forward"); + header->SetHistoName("right/forward"); + header->SetHistoName("bottom/forward"); + header->SetHistoName("left/backward"); + header->SetHistoName("top/backward"); + header->SetHistoName("right/backward"); + header->SetHistoName("bottom/backward"); + header->SetHistoLength(66601); + header->SetTimeResolution(0.1953125, "ns"); + + for (Int_t i=0; iGetNoOfHistos(); i++) { + header->SetTimeZeroBin(3419); + header->SetFirstGoodBin(3419); + header->SetLastGoodBin(65000); + } + + header->SetRedGreenHistogramOffset(0); + header->SetRedGreenHistogramOffset(20); + header->SetRedGreenDescription("NPP"); + header->SetRedGreenDescription("PPC"); + + if (!header->IsValid()) { + cerr << endl << ">> **ERROR** PSI-ROOT run header is not valid/complete." << endl; + delete header; + return -1; + } TFile *f = new TFile(argv[1], "RECREATE", "psi_runHeader_test"); if (f->IsZombie()) { @@ -77,25 +113,85 @@ int main(int argc, char *argv[]) } // root file header related things + UInt_t count = 1; TFolder *runInfo = gROOT->GetRootFolder()->AddFolder("RunInfo", "PSI RunInfo"); gROOT->GetListOfBrowsables()->Add(runInfo, "RunInfo"); - runInfo->Add(header->GetHeader()); + runInfo->Add(header->GetHeader(count)); + runInfo->Add(header->GetSampleEnv(count)); + runInfo->Add(header->GetMagFieldEnv(count)); + runInfo->Add(header->GetBeamline(count)); + runInfo->Add(header->GetScaler(count)); runInfo->Write(); -/* - f->mkdir("RunInfo"); - f->cd("RunInfo"); - header->GetHeader()->Write(); -*/ - f->Close(); delete f; + f = 0; - header->ExtractHeaderInformation(header->GetHeader()); header->DumpHeader(); delete header; + header = 0; + + cout << endl << ">> read back " << argv[1] << endl; + + // read the file back and extract the header info + f = new TFile(argv[1], "READ", "psi_runHeader_test"); + if (f->IsZombie()) { + delete f; + return -1; + } + + runInfo = 0; + f->GetObject("RunInfo", runInfo); + if (runInfo == 0) { + cerr << endl << ">> **ERROR** Couldn't get top folder RunInfo"; + f->Close(); + return -1; + } + + TObjArray *oarray = 0; + header = new TPsiRunHeader(); + + // get RunHeader + oarray = (TObjArray*) runInfo->FindObjectAny("RunHeader"); + if (oarray == 0) { + cerr << endl << ">> **ERROR** Couldn't get RunHeader" << endl; + } + header->ExtractHeaderInformation(oarray); + + // get SampleEnv + oarray = (TObjArray*) runInfo->FindObjectAny("SampleEnv"); + if (oarray == 0) { + cerr << endl << ">> **ERROR** Couldn't get SampleEnv" << endl; + } + header->ExtractHeaderInformation(oarray, "/SampleEnv/"); + + // get MagFieldEnv + oarray = (TObjArray*) runInfo->FindObjectAny("MagFieldEnv"); + if (oarray == 0) { + cerr << endl << ">> **ERROR** Couldn't get MagFieldEnv" << endl; + } + header->ExtractHeaderInformation(oarray, "/MagFieldEnv/"); + + // get Beamline + oarray = (TObjArray*) runInfo->FindObjectAny("Beamline"); + if (oarray == 0) { + cerr << endl << ">> **ERROR** Couldn't get Beamline" << endl; + } + header->ExtractHeaderInformation(oarray, "/Beamline/"); + + // get Scaler + oarray = (TObjArray*) runInfo->FindObjectAny("Scalers"); + if (oarray == 0) { + cerr << endl << ">> **ERROR** Couldn't get Scalers" << endl; + } + header->ExtractHeaderInformation(oarray, "/Scalers/"); + + header->DumpHeader(); + + f->Close(); + delete f; return 0; }