musrfit/src/external/MusrRoot/TMusrRunHeader.cpp

1700 lines
58 KiB
C++

/***************************************************************************
TMusrRunHeader.cpp
Author: Andreas Suter
e-mail: andreas.suter@psi.ch
***************************************************************************/
/***************************************************************************
* Copyright (C) 2007-2014 by Andreas Suter *
* andreas.suter@psi.ch *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
#include <cstdlib>
#include <ctime>
#include <iostream>
#include <iomanip>
using namespace std;
#include "TMusrRunHeader.h"
#include <TPaveText.h>
#include <TCanvas.h>
#include <TObjArray.h>
#include <TObjString.h>
#include <TString.h>
#include <TList.h>
#include <TMap.h>
ClassImp(TMusrRunPhysicalQuantity)
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>Constructor.
*/
TMusrRunPhysicalQuantity::TMusrRunPhysicalQuantity() : TObject()
{
fLabel = "n/a";
fDemand = MRH_UNDEFINED;
fValue = MRH_UNDEFINED;
fError = MRH_UNDEFINED;
fUnit = "n/a";
fDescription = "n/a";
}
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>Constructor.
*
* \param label of the physical quantity, e.g. 'Sample Temperature'
* \param demand value of the physical quantity
* \param value measured value of the physical quantity
* \param error estimated error of the physical quantity
* \param unit of the physical quantity, e.g. 'K'.
* \param description additional more detailed description of the physical quantity
*/
TMusrRunPhysicalQuantity::TMusrRunPhysicalQuantity(TString label, Double_t demand, Double_t value, Double_t error, TString unit, TString description) :
TObject(), fLabel(label), fDemand(demand), fValue(value), fError(error), fUnit(unit)
{
if (description.IsWhitespace())
fDescription = "n/a";
else
fDescription = description;
}
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>Constructor.
*
* \param label of the physical quantity, e.g. 'Sample Temperature'
* \param demand value of the physical quantity
* \param value measured value of the physical quantity
* \param unit of the physical quantity, e.g. 'K'.
* \param description additional more detailed description of the physical quantity
*/
TMusrRunPhysicalQuantity::TMusrRunPhysicalQuantity(TString label, Double_t demand, Double_t value, TString unit, TString description) :
TObject(), fLabel(label), fDemand(demand), fValue(value), fUnit(unit)
{
fError = MRH_UNDEFINED;
if (description.IsWhitespace())
fDescription = "n/a";
else
fDescription = description;
}
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>Constructor.
*
* \param label of the physical quantity, e.g. 'Sample Temperature'
* \param value measured value of the physical quantity
* \param unit of the physical quantity, e.g. 'K'.
* \param description additional more detailed description of the physical quantity
*/
TMusrRunPhysicalQuantity::TMusrRunPhysicalQuantity(TString label, Double_t value, TString unit, TString description) :
TObject(), fLabel(label), fValue(value), fUnit(unit)
{
fDemand = MRH_UNDEFINED;
fError = MRH_UNDEFINED;
if (description.IsWhitespace())
fDescription = "n/a";
else
fDescription = description;
}
//--------------------------------------------------------------------------
// Set (public)
//--------------------------------------------------------------------------
/**
* <p>set a physical quantity.
*
* \param label of the physical quantity, e.g. 'Sample Temperature'
* \param demand value of the physical quantity
* \param value measured value of the physical quantity
* \param error estimated error of the physical quantity
* \param unit of the physical quantity, e.g. 'K'.
* \param description additional more detailed description of the physical quantity
*/
void TMusrRunPhysicalQuantity::Set(TString label, Double_t demand, Double_t value, Double_t error, TString unit, TString description)
{
fLabel = label;
fDemand = demand;
fValue = value;
fError = error;
fUnit = unit;
if (description.IsWhitespace())
fDescription = "n/a";
else
fDescription = description;
}
//--------------------------------------------------------------------------
// Set (public)
//--------------------------------------------------------------------------
/**
* <p>set a physical quantity.
*
* \param label of the physical quantity, e.g. 'Sample Temperature'
* \param demand value of the physical quantity
* \param value measured value of the physical quantity
* \param unit of the physical quantity, e.g. 'K'.
* \param description additional more detailed description of the physical quantity
*/
void TMusrRunPhysicalQuantity::Set(TString label, Double_t demand, Double_t value, TString unit, TString description)
{
fLabel = label;
fDemand = demand;
fValue = value;
fError = MRH_UNDEFINED;
fUnit = unit;
if (description.IsWhitespace())
fDescription = "n/a";
else
fDescription = description;
}
//--------------------------------------------------------------------------
// Set (public)
//--------------------------------------------------------------------------
/**
* <p>set a physical quantity.
*
* \param label of the physical quantity, e.g. 'Sample Temperature'
* \param value measured value of the physical quantity
* \param unit of the physical quantity, e.g. 'K'.
* \param description additional more detailed description of the physical quantity
*/
void TMusrRunPhysicalQuantity::Set(TString label, Double_t value, TString unit, TString description)
{
fLabel = label;
fDemand = MRH_UNDEFINED;
fValue = value;
fError = MRH_UNDEFINED;
fUnit = unit;
if (description.IsWhitespace())
fDescription = "n/a";
else
fDescription = description;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
ClassImp(TMusrRunHeader)
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>Constructor.
*
* \param quiet if set to true, warnings will be omited. Default is false.
*/
TMusrRunHeader::TMusrRunHeader(bool quiet) : TObject(), fQuiet(quiet)
{
Init();
}
//--------------------------------------------------------------------------
// Constructor
//--------------------------------------------------------------------------
/**
* <p>Constructor.
*
* \param fileName file name of the MusrRoot file.
* \param quiet if set to true, warnings will be omited. Default is false.
*/
TMusrRunHeader::TMusrRunHeader(const char *fileName, bool quiet) : TObject()
{
fQuiet = quiet;
Init(TString(fileName));
}
//--------------------------------------------------------------------------
// Init (private)
//--------------------------------------------------------------------------
/**
* <p>Initializer
*
* \param fileName file name of the caller.
*/
void TMusrRunHeader::Init(TString fileName)
{
TMusrRunPhysicalQuantity prop;
fFileName = fileName;
fVersion = TString("$Id: TMusrRunHeader.cpp 5092 2012-03-13 07:47:00Z nemu $");
Set("RunInfo/Version", fVersion);
Set("RunInfo/Generic Validator URL", "http://lmu.web.psi.ch/facilities/software/MusrRoot/validation/MusrRoot.xsd");
Set("RunInfo/Specific Validator URL", "n/a");
Set("RunInfo/Generator", "n/a");
Set("RunInfo/File Name", "n/a");
Set("RunInfo/Run Title", "n/a");
Set("RunInfo/Run Number", -1);
Set("RunInfo/Run Start Time", "1970-01-01 00:00:00");
Set("RunInfo/Run Stop Time", "1970-01-01 00:00:00");
prop.Set("Run Duration", 0.0, "sec");
Set("RunInfo/Run Duration", prop);
Set("RunInfo/Laboratory", "n/a");
Set("RunInfo/Instrument", "n/a");
prop.Set("Muon Beam Momentum", 0.0, "MeV/c");
Set("RunInfo/Muon Beam Momentum", prop);
Set("RunInfo/Muon Species", "n/a");
Set("RunInfo/Muon Source", "n/a");
Set("RunInfo/Setup", "n/a");
Set("RunInfo/Comment", "n/a");
Set("RunInfo/Sample Name", "n/a");
prop.Set("Sample Temperature", 0.0, "K");
Set("RunInfo/Sample Temperature", prop);
prop.Set("Sample Magnetic Field", 1000.0, "T");
Set("RunInfo/Sample Magnetic Field", prop);
Set("RunInfo/No of Histos", 0);
prop.Set("Time Resolution", 0.0, "ns");
Set("RunInfo/Time Resolution", prop);
vector<int> ivec;
ivec.push_back(0);
Set("RunInfo/RedGreen Offsets", ivec);
Set("DetectorInfo/Detector001/Name", "n/a");
Set("DetectorInfo/Detector001/Histo Number", 0);
Set("DetectorInfo/Detector001/Histo Length", 0);
Set("DetectorInfo/Detector001/Time Zero Bin", (Double_t)0.0);
Set("DetectorInfo/Detector001/First Good Bin", 0);
Set("DetectorInfo/Detector001/Last Good Bin", 0);
Set("SampleEnvironmentInfo/Cryo", "n/a");
Set("MagneticFieldEnvironmentInfo/Magnet Name", "n/a");
Set("BeamlineInfo/Name", "n/a");
}
//--------------------------------------------------------------------------
// Destructor
//--------------------------------------------------------------------------
/**
* <p>Destructor.
*/
TMusrRunHeader::~TMusrRunHeader()
{
CleanUp();
}
//--------------------------------------------------------------------------
// CleanUp (private)
//--------------------------------------------------------------------------
/**
* <p>Clean up internal stuff.
*/
void TMusrRunHeader::CleanUp()
{
fStringObj.clear();
fIntObj.clear();
fDoubleObj.clear();
fMusrRunPhysQuantityObj.clear();
fStringVectorObj.clear();
fIntVectorObj.clear();
fDoubleVectorObj.clear();
fPathNameOrder.clear();
}
//--------------------------------------------------------------------------
// FillFolder (public)
//--------------------------------------------------------------------------
/**
* <p>Fills the RunHeader folder. This is needed to write it to a ROOT file.
* It walks through all information and attaches it to the folder or replaces
* it, if it is already present.
*
* \param folder to be filled
*/
Bool_t TMusrRunHeader::FillFolder(TFolder *folder)
{
TObjArray *oarray;
TObjString ostr, *p_ostr;
TString path, name, str;
Ssiz_t pos=0;
bool found=false;
if (folder == 0) {
cerr << endl << ">> TMusrRunHeader::FillFolder(): **ERROR** folder == 0!!" << endl;
return false;
}
folder->SetOwner(); // folder takes ownership of all added objects! This means that the folder object does the cleanup
// update/generate tree structure in folder
for (UInt_t i=0; i<fPathNameOrder.size(); i++) {
path=fPathNameOrder[i];
if (!UpdateFolder(folder, path))
return false;
}
// update/generate tree content
for (UInt_t i=0; i<fPathNameOrder.size(); i++) {
path=fPathNameOrder[i];
pos = path.Last('/');
if (pos == -1) {
cerr << endl << ">> TMusrRunHeader::FillFolder(): **ERROR** somethig is wrong with the path=" << path << " !!" << endl;
return false;
}
path.Remove(pos); // remove the value from the path
oarray = (TObjArray*)FindObject(folder, path);
if (!oarray) {
cerr << endl << ">> TMusrRunHeader::FillFolder(): **ERROR** couldn't create header structure!!" << endl;
return false;
}
// check if <value> is already found in oarray
ostr = GetHeaderString(i); // encode the string for the MusrRoot file
name = ostr.GetString(); // convert to TString
str = GetFirst(name, ':'); // get the first part of the encoded string, i.e. <nnn> - <name>
found = false;
for (Int_t j=0; j<oarray->GetEntriesFast(); j++) {
p_ostr = (TObjString*) oarray->At(j);
if (p_ostr->GetString().BeginsWith(str)) { // present hence replace
oarray->AddAt(ostr.Clone(), j);
found = true;
break;
}
}
if (!found) {
oarray->AddLast(ostr.Clone());
}
}
return true;
}
//--------------------------------------------------------------------------
// Get (public)
//--------------------------------------------------------------------------
/**
* <p>Get TString 'value'.
*
* \param pathName path/name within the header, e.g. RunInfo/Run Title
* \param value TString return value
* \param ok flag telling if the TString value was found
*/
void TMusrRunHeader::Get(TString pathName, TString &value, Bool_t &ok)
{
ok = false;
for (UInt_t i=0; i<fStringObj.size(); i++) {
if (fStringObj[i].GetPathName() == pathName) {
value = fStringObj[i].GetValue();
ok = true;
}
}
}
//--------------------------------------------------------------------------
// Get (public)
//--------------------------------------------------------------------------
/**
* <p>Get Int_t 'value'.
*
* \param pathName path/name within the header, e.g. RunInfo/Run Number
* \param value Int_t return value
* \param ok flag telling if the Int_t value was found
*/
void TMusrRunHeader::Get(TString pathName, Int_t &value, Bool_t &ok)
{
ok = false;
for (UInt_t i=0; i<fIntObj.size(); i++) {
if (fIntObj[i].GetPathName() == pathName) {
value = fIntObj[i].GetValue();
ok = true;
}
}
}
//--------------------------------------------------------------------------
// Get (public)
//--------------------------------------------------------------------------
/**
* <p>Get Double_t 'value'.
*
* \param pathName path/name within the header, e.g. RunInfo/Time Zero Bin
* \param value Double_t return value
* \param ok flag telling if the Double_t value was found
*/
void TMusrRunHeader::Get(TString pathName, Double_t &value, Bool_t &ok)
{
ok = false;
for (UInt_t i=0; i<fDoubleObj.size(); i++) {
if (fDoubleObj[i].GetPathName() == pathName) {
value = fDoubleObj[i].GetValue();
ok = true;
}
}
}
//--------------------------------------------------------------------------
// Get (public)
//--------------------------------------------------------------------------
/**
* <p>Get TMusrRunPhysicalQuantity 'value'.
*
* \param pathName path/name within the header, e.g. RunInfo/Run Title
* \param value TMusrRunPhysicalQuantity return value
* \param ok flag telling if the TMusrRunPhysicalQuantity value was found
*/
void TMusrRunHeader::Get(TString pathName, TMusrRunPhysicalQuantity &value, Bool_t &ok)
{
ok = false;
for (UInt_t i=0; i<fMusrRunPhysQuantityObj.size(); i++) {
if (fMusrRunPhysQuantityObj[i].GetPathName() == pathName) {
value = fMusrRunPhysQuantityObj[i].GetValue();
ok = true;
}
}
}
//--------------------------------------------------------------------------
// Get (public)
//--------------------------------------------------------------------------
/**
* <p>Get TStringVector 'value'.
*
* \param pathName path/name within the header, e.g. RunInfo/Run Title
* \param value TStringVector return value
* \param ok flag telling if the TStringVector value was found
*/
void TMusrRunHeader::Get(TString pathName, TStringVector &value, Bool_t &ok)
{
ok = false;
for (UInt_t i=0; i<fStringVectorObj.size(); i++) {
if (fStringVectorObj[i].GetPathName() == pathName) {
value = fStringVectorObj[i].GetValue();
ok = true;
}
}
}
//--------------------------------------------------------------------------
// Get (public)
//--------------------------------------------------------------------------
/**
* <p>Get TIntVector 'value'.
*
* \param pathName path/name within the header, e.g. RunInfo/Run Title
* \param value TIntVector return value
* \param ok flag telling if the TIntVector value was found
*/
void TMusrRunHeader::Get(TString pathName, TIntVector &value, Bool_t &ok)
{
ok = false;
for (UInt_t i=0; i<fIntVectorObj.size(); i++) {
if (fIntVectorObj[i].GetPathName() == pathName) {
value = fIntVectorObj[i].GetValue();
ok = true;
}
}
}
//--------------------------------------------------------------------------
// Get (public)
//--------------------------------------------------------------------------
/**
* <p>Get TDoubleVector 'value'.
*
* \param pathName path/name within the header, e.g. RunInfo/Run Title
* \param value TDoubleVector return value
* \param ok flag telling if the TDoubleVector value was found
*/
void TMusrRunHeader::Get(TString pathName, TDoubleVector &value, Bool_t &ok)
{
ok = false;
for (UInt_t i=0; i<fDoubleVectorObj.size(); i++) {
if (fDoubleVectorObj[i].GetPathName() == pathName) {
value = fDoubleVectorObj[i].GetValue();
ok = true;
}
}
}
//--------------------------------------------------------------------------
// Set (public)
//--------------------------------------------------------------------------
/**
* <p>Set TString 'value'.
*
* \param pathName path/name within the header, e.g. RunInfo/Run Title
* \param value of the entry
*/
void TMusrRunHeader::Set(TString pathName, TString value)
{
// check if pathName is already set, if not add it as a new entry, otherwise replace it
UInt_t i=0;
for (i=0; i<fStringObj.size(); i++) {
if (!fStringObj[i].GetPathName().CompareTo(pathName, TString::kIgnoreCase)) {
if (!fQuiet)
cerr << endl << ">> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl;
fStringObj[i].SetType("TString");
fStringObj[i].SetValue(value);
break;
}
}
// if not found in the previous loop, it is a new object
if (i == fStringObj.size()) {
// feed object
TMusrRunObject<TString> obj(pathName, "TString", value);
fStringObj.push_back(obj);
// feed path-name to keep track of the order
fPathNameOrder.push_back(pathName);
}
}
//--------------------------------------------------------------------------
// Set (public)
//--------------------------------------------------------------------------
/**
* <p>Set Int_t 'value'.
*
* \param pathName path/name within the header, e.g. RunInfo/Run number
* \param value of the entry
*/
void TMusrRunHeader::Set(TString pathName, Int_t value)
{
// check if pathName is already set, if not add it as a new entry, otherwise replace it
UInt_t i=0;
for (i=0; i<fIntObj.size(); i++) {
if (!fIntObj[i].GetPathName().CompareTo(pathName, TString::kIgnoreCase)) {
if (!fQuiet)
cerr << endl << ">> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl;
fIntObj[i].SetType("Int_t");
fIntObj[i].SetValue(value);
break;
}
}
// if not found in the previous loop, it is a new object
if (i == fIntObj.size()) {
// feed object
TMusrRunObject<Int_t> obj(pathName, "Int_t", value);
fIntObj.push_back(obj);
// feed path-name to keep track of the order
fPathNameOrder.push_back(pathName);
}
}
//--------------------------------------------------------------------------
// Set (public)
//--------------------------------------------------------------------------
/**
* <p>Set Double_t 'value'.
*
* \param pathName path/name within the header, e.g. RunInfo/DoubleValue
* \param value of the entry
*/
void TMusrRunHeader::Set(TString pathName, Double_t value)
{
// check if pathName is already set, if not add it as a new entry, otherwise replace it
UInt_t i=0;
for (i=0; i<fDoubleObj.size(); i++) {
if (!fDoubleObj[i].GetPathName().CompareTo(pathName, TString::kIgnoreCase)) {
if (!fQuiet)
cerr << endl << ">> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl;
fDoubleObj[i].SetType("Double_t");
fDoubleObj[i].SetValue(value);
break;
}
}
// if not found in the previous loop, it is a new object
if (i == fDoubleObj.size()) {
// feed object
TMusrRunObject<Double_t> obj(pathName, "Double_t", value);
fDoubleObj.push_back(obj);
// feed path-name to keep track of the order
fPathNameOrder.push_back(pathName);
}
}
//--------------------------------------------------------------------------
// Set (public)
//--------------------------------------------------------------------------
/**
* <p>Set TMusrRunPhysicalQuantity 'value'.
*
* \param pathName path/name within the header, e.g. RunInfo/Muon Beam Momentum
* \param value of the entry
*/
void TMusrRunHeader::Set(TString pathName, TMusrRunPhysicalQuantity value)
{
// check if pathName is already set, if not add it as a new entry, otherwise replace it
UInt_t i=0;
for (i=0; i<fMusrRunPhysQuantityObj.size(); i++) {
if (!fMusrRunPhysQuantityObj[i].GetPathName().CompareTo(pathName, TString::kIgnoreCase)) {
if (!fQuiet)
cerr << endl << ">> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl;
fMusrRunPhysQuantityObj[i].SetType("TMusrRunHeader");
fMusrRunPhysQuantityObj[i].SetValue(value);
break;
}
}
// if not found in the previous loop, it is a new object
if (i == fMusrRunPhysQuantityObj.size()) {
// feed object
TMusrRunObject<TMusrRunPhysicalQuantity> obj(pathName, "TMusrRunPhysicalQuantity", value);
fMusrRunPhysQuantityObj.push_back(obj);
// feed path-name to keep track of the order
fPathNameOrder.push_back(pathName);
}
}
//--------------------------------------------------------------------------
// Set (public)
//--------------------------------------------------------------------------
/**
* <p>Set TStringVector 'value'.
*
* \param pathName path/name within the header, e.g. RunInfo/Histo names
* \param value of the entry
*/
void TMusrRunHeader::Set(TString pathName, TStringVector value)
{
// check if pathName is already set, if not add it as a new entry, otherwise replace it
UInt_t i=0;
for (i=0; i<fStringVectorObj.size(); i++) {
if (!fStringVectorObj[i].GetPathName().CompareTo(pathName, TString::kIgnoreCase)) {
if (!fQuiet)
cerr << endl << ">> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl;
fStringVectorObj[i].SetType("TStringVector");
fStringVectorObj[i].SetValue(value);
break;
}
}
// if not found in the previous loop, it is a new object
if (i == fStringVectorObj.size()) {
// feed object
TMusrRunObject<TStringVector> obj(pathName, "TStringVector", value);
fStringVectorObj.push_back(obj);
// feed path-name to keep track of the order
fPathNameOrder.push_back(pathName);
}
}
//--------------------------------------------------------------------------
// Set (public)
//--------------------------------------------------------------------------
/**
* <p>Set TIntVector 'value'.
*
* \param pathName path/name within the header, e.g. RunInfo/Time Zero Bin
* \param value of the entry
*/
void TMusrRunHeader::Set(TString pathName, TIntVector value)
{
// check if pathName is already set, if not add it as a new entry, otherwise replace it
UInt_t i=0;
for (i=0; i<fIntVectorObj.size(); i++) {
if (!fIntVectorObj[i].GetPathName().CompareTo(pathName, TString::kIgnoreCase)) {
if (!fQuiet)
cerr << endl << ">> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl;
fIntVectorObj[i].SetType("TIntVector");
fIntVectorObj[i].SetValue(value);
break;
}
}
// if not found in the previous loop, it is a new object
if (i == fIntVectorObj.size()) {
// feed object
TMusrRunObject<TIntVector> obj(pathName, "TIntVector", value);
fIntVectorObj.push_back(obj);
// feed path-name to keep track of the order
fPathNameOrder.push_back(pathName);
}
}
//--------------------------------------------------------------------------
// Set (public)
//--------------------------------------------------------------------------
/**
* <p>Set TDoubleVector 'value'.
*
* \param pathName path/name within the header, e.g. RunInfo/Time Zero Bin
* \param value of the entry
*/
void TMusrRunHeader::Set(TString pathName, TDoubleVector value)
{
// check if pathName is already set, if not add it as a new entry, otherwise replace it
UInt_t i=0;
for (i=0; i<fDoubleVectorObj.size(); i++) {
if (!fDoubleVectorObj[i].GetPathName().CompareTo(pathName, TString::kIgnoreCase)) {
if (!fQuiet)
cerr << endl << ">> **WARNING** " << pathName.Data() << " already exists, will replace it." << endl;
fDoubleVectorObj[i].SetType("TDoubleVector");
fDoubleVectorObj[i].SetValue(value);
break;
}
}
// if not found in the previous loop, it is a new object
if (i == fDoubleVectorObj.size()) {
// feed object
TMusrRunObject<TDoubleVector> obj(pathName, "TDoubleVector", value);
fDoubleVectorObj.push_back(obj);
// feed path-name to keep track of the order
fPathNameOrder.push_back(pathName);
}
}
//--------------------------------------------------------------------------
// ExtractAll (public)
//--------------------------------------------------------------------------
/**
* <p>Reads all data from an open ROOT-file structure and feeds all the necessary
* internal data objects.
*
* \param folder
*/
Bool_t TMusrRunHeader::ExtractAll(TFolder *folder)
{
TIter next(folder->GetListOfFolders());
TObjArray* entry;
// clean up all internal structures - just in case this is called multiple times
CleanUp();
while ((entry = (TObjArray*)next())) {
ExtractHeaderInformation(entry, entry->GetName());
}
return true;
}
//--------------------------------------------------------------------------
// ExtractHeaderInformation (public)
//--------------------------------------------------------------------------
/**
* <p>
*
* \param headerInfo
* \param requestedPath
*/
Bool_t TMusrRunHeader::ExtractHeaderInformation(TObjArray *headerInfo, TString requestedPath)
{
TString label(""), path(""), pathName(""), str(""), strValue(""), type("");
TObjString *ostr = 0;
TObjArray *tokens = 0;
Ssiz_t idx1;
Int_t intValue;
Double_t dval;
// go through all entries of this header information from the MUSR-ROOT file
for (Int_t i=0; i<headerInfo->GetEntries(); i++) {
// check if entry is a TObjArray, i.e. a sub tree
str = TString(headerInfo->At(i)->ClassName());
if (str == "TObjArray") { // sub tree
path = requestedPath + "/" + TString(headerInfo->At(i)->GetName());
ExtractHeaderInformation((TObjArray*)headerInfo->At(i), path);
} else { // handle all the rest, i.e. already data
ostr = dynamic_cast<TObjString*>(headerInfo->At(i));
str = ostr->GetString();
// get the run header label
label = GetLabel(str);
if (label == "n/a") // not a TMusrRunHeader object, hence ignore it
continue;
// get the run header 'value'
strValue = GetStrValue(str);
// construct path name
pathName = requestedPath + TString("/") + label;
// get type from map
type = GetType(str);
if (type == "n/a") // not a TMusrRunHeader object, hence ignore it
continue;
if (type == "TString") {
Set(pathName, strValue);
} else if (type == "Int_t") {
intValue = strValue.Atoi();
Set(pathName, intValue);
} else if (type == "Double_t") {
dval = strValue.Atof();
Set(pathName, dval);
} else if (type == "TMusrRunPhysicalQuantity") {
TMusrRunPhysicalQuantity prop;
prop.SetLabel(label);
// 1st get the description if present
tokens = strValue.Tokenize(";");
if (tokens == 0) {
cerr << endl << ">> **ERROR** Couldn't tokenize entry in Bool_t TMusrRunHeader::ExtractHeaderInformation(TObjArray *headerInfo, TString requestedPath)" << endl;
return false;
}
switch (tokens->GetEntries()) {
case 2:
ostr = dynamic_cast<TObjString*>(tokens->At(1));
str = ostr->GetString();
if (!str.Contains("SP:")) { // make sure that it is not a demand value token
prop.SetDescription(str);
}
break;
case 3:
ostr = dynamic_cast<TObjString*>(tokens->At(2));
str = ostr->GetString();
break;
default:
break;
}
if (tokens) {
delete tokens;
tokens = 0;
}
// 2nd collect all the other properties, this is easier when first a potential description is removed
idx1 = strValue.Last(';');
if (idx1 > 0) {
TString last("");
for (Int_t i=idx1+2; i<strValue.Length(); i++)
last += strValue[i];
// check if last is <description> or SP: <demand>
if (!last.Contains("SP:")) {
str = "";
for (Int_t i=0; i<idx1; i++)
str += strValue[i];
strValue = str;
}
}
tokens = strValue.Tokenize(" +;");
if (tokens == 0) {
cerr << endl << ">> **ERROR** Couldn't tokenize entry in Bool_t TMusrRunHeader::ExtractHeaderInformation(TObjArray *headerInfo, TString requestedPath)" << endl;
return false;
}
switch (tokens->GetEntries()) {
case 2: // <val> <unit>
ostr = dynamic_cast<TObjString*>(tokens->At(0));
str = ostr->GetString();
prop.SetValue(str.Atof());
ostr = dynamic_cast<TObjString*>(tokens->At(1));
str = ostr->GetString();
prop.SetUnit(str);
break;
case 4: // <val> +- <err> <unit>, or <val> <unit>; SP: <demand>
ostr = dynamic_cast<TObjString*>(tokens->At(0));
str = ostr->GetString();
prop.SetValue(str.Atof());
ostr = dynamic_cast<TObjString*>(tokens->At(1));
str = ostr->GetString();
if (str == "-") { // <val> +- <err> <unit>
ostr = dynamic_cast<TObjString*>(tokens->At(2));
str = ostr->GetString();
prop.SetError(str.Atof());
ostr = dynamic_cast<TObjString*>(tokens->At(3));
str = ostr->GetString();
prop.SetUnit(str);
} else { // <val> <unit>; SP: <demand>
prop.SetUnit(str);
ostr = dynamic_cast<TObjString*>(tokens->At(3));
str = ostr->GetString();
prop.SetDemand(str.Atof());
}
break;
case 6: // <val> +- <err> <unit>; SP: <demand>
ostr = dynamic_cast<TObjString*>(tokens->At(0));
str = ostr->GetString();
prop.SetValue(str.Atof());
ostr = dynamic_cast<TObjString*>(tokens->At(2));
str = ostr->GetString();
prop.SetError(str.Atof());
ostr = dynamic_cast<TObjString*>(tokens->At(3));
str = ostr->GetString();
prop.SetUnit(str);
ostr = dynamic_cast<TObjString*>(tokens->At(5));
str = ostr->GetString();
prop.SetDemand(str.Atof());
break;
default:
break;
}
if (tokens) {
delete tokens;
tokens = 0;
}
Set(pathName, prop);
} else if (type == "TStringVector") {
TStringVector svec;
tokens = strValue.Tokenize(";");
if (tokens == 0) {
cerr << endl << ">> **ERROR** Couldn't tokenize entry in Bool_t TMusrRunHeader::ExtractHeaderInformation(TObjArray *headerInfo, TString requestedPath)" << endl;
return false;
}
for (Int_t i=0; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i));
str = ostr->GetString();
str.Remove(TString::kBoth, ' ');
svec.push_back(str);
}
if (tokens) {
delete tokens;
tokens = 0;
}
Set(pathName, svec);
} else if (type == "TIntVector") {
TIntVector ivec;
tokens = strValue.Tokenize(";");
if (tokens == 0) {
cerr << endl << ">> **ERROR** Couldn't tokenize entry in Bool_t TMusrRunHeader::ExtractHeaderInformation(TObjArray *headerInfo, TString requestedPath)" << endl;
return false;
}
for (Int_t i=0; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i));
ivec.push_back(ostr->GetString().Atoi());
}
if (tokens) {
delete tokens;
tokens = 0;
}
Set(pathName, ivec);
} else if (type == "TDoubleVector") {
TDoubleVector dvec;
tokens = strValue.Tokenize(";");
if (tokens == 0) {
cerr << endl << ">> **ERROR** Couldn't tokenize entry in Bool_t TMusrRunHeader::ExtractHeaderInformation(TObjArray *headerInfo, TString requestedPath)" << endl;
return false;
}
for (Int_t i=0; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i));
dvec.push_back(ostr->GetString().Atoi());
}
if (tokens) {
delete tokens;
tokens = 0;
}
Set(pathName, dvec);
}
}
}
return true;
}
//--------------------------------------------------------------------------
// DumpHeader (public)
//--------------------------------------------------------------------------
/**
* <p>
*/
void TMusrRunHeader::DumpHeader()
{
cout << endl << "***************************************";
cout << endl << "header info of file : " << fFileName;
cout << endl << "***************************************";
TString str(""), tstr(""), fmt(""), path(""), name(""), currentPath("");
TMusrRunPhysicalQuantity prop;
for (UInt_t i=0; i<fPathNameOrder.size(); i++) {
// print path if new
SplitPathName(fPathNameOrder[i], path, name);
if (path != currentPath) {
currentPath = path;
cout << endl << currentPath;
}
// go through all objects and try to find it
// 1st check TString
for (UInt_t j=0; j<fStringObj.size(); j++) {
if (fStringObj[j].GetPathName() == fPathNameOrder[i]) { // found correct object
SplitPathName(fStringObj[j].GetPathName(), path, name);
str.Form(" %03d - %s: %s -@%d", i, name.Data(), fStringObj[j].GetValue().Data(), MRH_TSTRING);
cout << endl << str;
}
}
// 2nd check Int_t
for (UInt_t j=0; j<fIntObj.size(); j++) {
if (fIntObj[j].GetPathName() == fPathNameOrder[i]) { // found correct object
SplitPathName(fIntObj[j].GetPathName(), path, name);
str.Form(" %03d - %s: %d -@%d", i, name.Data(), fIntObj[j].GetValue(), MRH_INT);
cout << endl << str;
}
}
// 3rd check Double_t
for (UInt_t j=0; j<fDoubleObj.size(); j++) {
if (fDoubleObj[j].GetPathName() == fPathNameOrder[i]) { // found correct object
SplitPathName(fDoubleObj[j].GetPathName(), path, name);
fmt.Form(" %%03d - %%s: %%.%dlf -@%%d", MRH_DOUBLE_PREC);
str.Form(fmt, i, name.Data(), fDoubleObj[j].GetValue(), MRH_DOUBLE);
cout << endl << str;
}
}
// 4th check TMusrRunPhysicalQuantity
for (UInt_t j=0; j<fMusrRunPhysQuantityObj.size(); j++) {
if (fMusrRunPhysQuantityObj[j].GetPathName() == fPathNameOrder[i]) { // found correct object
prop = fMusrRunPhysQuantityObj[j].GetValue();
Int_t digit, digit_d;
if ((prop.GetDemand() != MRH_UNDEFINED) && (prop.GetValue() != MRH_UNDEFINED) && (prop.GetError() != MRH_UNDEFINED) &&
(prop.GetUnit() != "n/a")) { // <value> +- <error> <unit>; SP: <demand> [; <description>]
digit = GetDecimalPlace(prop.GetError());
digit_d = GetLeastSignificantDigit(prop.GetDemand());
if (prop.GetDescription() != "n/a") {
fmt.Form("%%s: %%.%dlf +- %%.%dlf %%s; SP: %%.%dlf; %%s", digit, digit, digit_d);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetError(), prop.GetUnit().Data(), prop.GetDemand(), prop.GetDescription().Data());
} else {
fmt.Form("%%s: %%.%dlf +- %%.%dlf %%s; SP: %%.%dlf", digit, digit, digit_d);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetError(), prop.GetUnit().Data(), prop.GetDemand());
}
} else if ((prop.GetDemand() == MRH_UNDEFINED) && (prop.GetValue() != MRH_UNDEFINED) && (prop.GetError() != MRH_UNDEFINED) &&
(prop.GetUnit() != "n/a")) { // <value> +- <error> <unit> [; <description>]
digit = GetDecimalPlace(prop.GetError());
if (prop.GetDescription() != "n/a") {
fmt.Form("%%s: %%.%dlf +- %%.%dlf %%s; %%s", digit, digit);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetError(), prop.GetUnit().Data(), prop.GetDescription().Data());
} else {
fmt.Form("%%s: %%.%dlf +- %%.%dlf %%s", digit, digit);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetError(), prop.GetUnit().Data());
}
} else if ((prop.GetDemand() == MRH_UNDEFINED) && (prop.GetValue() != MRH_UNDEFINED) && (prop.GetError() == MRH_UNDEFINED) &&
(prop.GetUnit() != "n/a")) { // <value> <unit> [; <description>]
digit = GetLeastSignificantDigit(prop.GetValue());
if (prop.GetDescription() != "n/a") {
fmt.Form("%%s: %%.%dlf %%s; %%s", digit);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetUnit().Data(), prop.GetDescription().Data());
} else {
fmt.Form("%%s: %%.%dlf %%s", digit);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetUnit().Data());
}
} else if ((prop.GetDemand() != MRH_UNDEFINED) && (prop.GetValue() != MRH_UNDEFINED) && (prop.GetError() == MRH_UNDEFINED) &&
(prop.GetUnit() != "n/a")) { // <value> <unit>; SP: <demand> [; <description>]
digit = GetLeastSignificantDigit(prop.GetValue());
digit_d = GetLeastSignificantDigit(prop.GetDemand());
if (prop.GetDescription() != "n/a") {
fmt.Form("%%s: %%.%dlf %%s; SP: %%.%dlf; %%s", digit, digit_d);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetUnit().Data(), prop.GetDemand(), prop.GetDescription().Data());
} else {
fmt.Form("%%s: %%.%dlf %%s; SP: %%.%dlf", digit, digit_d);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetUnit().Data(), prop.GetDemand());
}
}
str.Form(" %03d - %s -@%d", i, tstr.Data(), MRH_TMUSR_RUN_PHYSICAL_QUANTITY);
cout << endl << str;
}
}
// 5th check TStringVector
for (UInt_t j=0; j<fStringVectorObj.size(); j++) {
if (fStringVectorObj[j].GetPathName() == fPathNameOrder[i]) { // found correct object
SplitPathName(fStringVectorObj[j].GetPathName(), path, name);
str.Form(" %03d - %s: ", i, name.Data());
TStringVector vstr = fStringVectorObj[j].GetValue();
for (UInt_t k=0; k<vstr.size()-1; k++)
str += vstr[k] + "; ";
str += vstr[vstr.size()-1];
str += " -@";
str += MRH_TSTRING_VECTOR;
cout << endl << str;
}
}
// 6th check TIntVector
for (UInt_t j=0; j<fIntVectorObj.size(); j++) {
if (fIntVectorObj[j].GetPathName() == fPathNameOrder[i]) { // found correct object
SplitPathName(fIntVectorObj[j].GetPathName(), path, name);
str.Form(" %03d - %s: ", i, name.Data());
TIntVector vint = fIntVectorObj[j].GetValue();
for (UInt_t k=0; k<vint.size()-1; k++) {
str += vint[k];
str += "; ";
}
str += vint[vint.size()-1];
str += " -@";
str += MRH_INT_VECTOR;
cout << endl << str;
}
}
// 7th check TDoubleVector
for (UInt_t j=0; j<fDoubleVectorObj.size(); j++) {
if (fDoubleVectorObj[j].GetPathName() == fPathNameOrder[i]) { // found correct object
SplitPathName(fDoubleVectorObj[j].GetPathName(), path, name);
str.Form(" %03d - %s: ", i, name.Data());
TDoubleVector dvec = fDoubleVectorObj[j].GetValue();
TString subStr("");
fmt.Form("%%.%dlf", MRH_DOUBLE_PREC);
for (UInt_t k=0; k<dvec.size()-1; k++) {
subStr.Form(fmt, dvec[k]);
str += subStr;
str += "; ";
}
subStr.Form(fmt, dvec.size()-1);
str += subStr;
str += " -@";
str += MRH_DOUBLE_VECTOR;
cout << endl << str;
}
}
}
cout << endl;
}
//--------------------------------------------------------------------------
// DrawHeader (public)
//--------------------------------------------------------------------------
/**
* <p>
*/
void TMusrRunHeader::DrawHeader()
{
TPaveText *pt;
TCanvas *ca;
ca = new TCanvas("MusrRoot RunHeader","MusrRoot RunHeader", 147,37,699,527);
ca->Range(0., 0., 100., 100.);
pt = new TPaveText(10.,10.,90.,90.,"br");
pt->SetFillColor(19);
pt->SetTextAlign(12);
pt->Draw();
ca->Modified(kTRUE);
}
//--------------------------------------------------------------------------
// GetDecimalPlace (private)
//--------------------------------------------------------------------------
/**
* <p>Check decimal place of val. If val > 1.0, the function will return 0, otherwise
* the first decimal place found will be returned.
*
* \param val value from which the first significant digit shall be determined
*/
UInt_t TMusrRunHeader::GetDecimalPlace(Double_t val)
{
UInt_t digit = 0;
if (val < 1.0) {
UInt_t count=1;
do {
val *= 10.0;
if (val > 1.0)
digit = count;
count++;
} while ((digit == 0) && (count < 20));
}
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 TMusrRunHeader::GetLeastSignificantDigit(Double_t val) const
{
char cstr[1024];
snprintf(cstr, sizeof(cstr), "%.10lf", 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;
}
//--------------------------------------------------------------------------
// SplitPathName (private)
//--------------------------------------------------------------------------
/**
* <p>splits a path name string into the path and the name.
*
* \param pathName path name to be split
* \param path of pathName
* \param name of pathName
*/
void TMusrRunHeader::SplitPathName(TString pathName, TString &path, TString &name)
{
path = TString("");
name = TString("");
Ssiz_t idx = pathName.Last('/');
for (Int_t i=0; i<idx; i++)
path += pathName[i];
for (Int_t i=idx+1; i<pathName.Length(); i++)
name += pathName[i];
}
//--------------------------------------------------------------------------
// GetLabel (private)
//--------------------------------------------------------------------------
/**
* <p>extracts form the run header line, as written to the MusrROOT file, the run header label, e.g. Run Number.
*
* \param str runHeader string as written to the MusrROOT file.
*/
TString TMusrRunHeader::GetLabel(TString str)
{
// get run header label
// the string 'str' should have the structure
// <number> - <runHeader label>: <runHeader string value> -@<encoded data type>
TString label = TString("n/a");
Ssiz_t idx1 = str.First('-');
Ssiz_t idx2 = str.First(':');
if ((idx1 == -1) || (idx2 == -1)) {
if (!fQuiet) {
cerr << endl << ">> TMusrRunHeader::GetLabel(): **WARNING** str='" << str << "', seems not correctly encoded.";
cerr << endl << ">> Will omit it." << endl;
}
return label;
}
label = TString("");
for (Int_t j=idx1+2; j<idx2; j++)
label += str[j];
return label;
}
//--------------------------------------------------------------------------
// GetStrValue (private)
//--------------------------------------------------------------------------
/**
* <p>extracts form the run header line, as written to the MusrROOT file, the run header str value, e.g. 557 (for Run Number).
*
* \param str runHeader string as written to the MusrROOT file.
*/
TString TMusrRunHeader::GetStrValue(TString str)
{
// get run header string value
// the string 'str' should have the structure
// <number> - <runHeader label>: <runHeader string value> -@<encoded data type>
TString strValue = TString("n/a");
Ssiz_t idx1 = str.First(':');
Ssiz_t idx2 = str.Last('-');
if ((idx1 == -1) || (idx2 == -1)) {
if (!fQuiet) {
cerr << endl << ">> TMusrRunHeader::GetStrValue(): **WARNING** str='" << str << "', seems not correctly encoded.";
cerr << endl << ">> Will omit it." << endl;
}
return strValue;
}
strValue = TString("");
for (Int_t j=idx1+2; j<idx2-1; j++)
strValue += str[j];
return strValue;
}
//--------------------------------------------------------------------------
// GetType (private)
//--------------------------------------------------------------------------
/**
* <p>extracts form the run header line, as written to the MusrROOT file, the encoded type and retruns it.
*
* \param str runHeader string with encoded type
*/
TString TMusrRunHeader::GetType(TString str)
{
TString result = "n/a";
// the string 'str' should have the structure
// <number> - <runHeader label>: <runHeader string value> -@<encoded data type>
Ssiz_t pos = str.Last('@');
if (pos == -1) { // i.e. NOT found
if (!fQuiet) {
cerr << endl << ">> TMusrRunHeader::GetType(): **WARNING** str=" << str << " seems to be an invalid MusrROOT run header string.";
cerr << endl << ">> Will omit it." << endl;
}
return result;
}
// filter out the encoded type declaration, i.e. -@<num>, where <num> is the encoded type
TString typeStr(str);
typeStr.Remove(0, pos+1);
Int_t typeVal;
if (!typeStr.IsDigit()) {
cerr << endl << ">> TMusrRunHeader::GetType(): **ERROR** typeStr=" << typeStr << " is not supported." << endl;
return result;
}
typeVal = typeStr.Atoi();
switch (typeVal) {
case MRH_TSTRING:
result = "TString";
break;
case MRH_INT:
result = "Int_t";
break;
case MRH_DOUBLE:
result = "Double_t";
break;
case MRH_TMUSR_RUN_PHYSICAL_QUANTITY:
result = "TMusrRunPhysicalQuantity";
break;
case MRH_TSTRING_VECTOR:
result = "TStringVector";
break;
case MRH_INT_VECTOR:
result = "TIntVector";
break;
case MRH_DOUBLE_VECTOR:
result = "TDoubleVector";
break;
default:
cerr << endl << ">> TMusrRunHeader::GetType(): **ERROR** found unsupport type encoded with: " << typeVal << "." << endl;
break;
}
return result;
}
//--------------------------------------------------------------------------
// UpdateFolder (private)
//--------------------------------------------------------------------------
/**
* <p>Update folder structure
*
* <p><b>return:</b>
* - true if everything is all right
* - false otherwise
*
* \param treeObj to be updated
* \param path to be added within 'treeObj'
*/
bool TMusrRunHeader::UpdateFolder(TObject *treeObj, TString path)
{
if (path.First('/') == -1) // only value element left, hence nothing to be done
return true;
TString str = GetFirst(path, '/');
TObject *obj = treeObj->FindObject(str);
// remove the first path element
if (!RemoveFirst(path, '/')) {
cerr << endl << ">> TMusrRunHeader::UpdateFolder(): **ERROR** couldn't tokenize path!!" << endl;
return false;
}
if (!obj) { // required object not present, create it
TObjArray *oarray = new TObjArray();
if (!oarray) {
cerr << endl << ">> TMusrRunHeader::UpdateFolder(): **ERROR** couldn't create header structure!!" << endl;
return false;
}
// set the name of the new TObjArray
oarray->SetName(str);
if (!strcmp(treeObj->ClassName(), "TFolder"))
((TFolder*)treeObj)->Add(oarray);
else // it is a TObjArray
((TObjArray*)treeObj)->AddLast(oarray);
return UpdateFolder(oarray, path);
} else { // object present, hence check rest of the path
return UpdateFolder(obj, path);
}
}
//--------------------------------------------------------------------------
// FindObject (private)
//--------------------------------------------------------------------------
/**
* <p>Check if 'path' is present in 'treeObj'
*
* <p><b>return:</b>
* - pointer to the 'path' object if present
* - otherwise return 0
*
* \param treeObj to be searched
* \param path searched for within 'treeObj'
*/
TObject* TMusrRunHeader::FindObject(TObject *treeObj, TString path)
{
Ssiz_t pos;
TObject *obj=0;
// make sure that treeObj is either TFolder or TObjArray
if (strcmp(treeObj->ClassName(), "TFolder") && strcmp(treeObj->ClassName(), "TObjArray"))
return obj;
pos = path.First('/');
if (pos == -1) { // i.e. no sub-paths anymore
obj = treeObj->FindObject(path);
return obj;
} else { // sub-paths present
TString objName = GetFirst(path, '/'); // get first token of the path <objName0>/<objName1>/.../<objNameN>
obj = treeObj->FindObject(objName);
if (obj) { // object found, check for subPath object
RemoveFirst(path, '/'); // remove first tokens of the path
return FindObject(obj, path);
} else { // object not found
return obj;
}
}
}
//--------------------------------------------------------------------------
// GetHeaderString (private)
//--------------------------------------------------------------------------
/**
* <p>
*
* \param pathName
*/
TObjString TMusrRunHeader::GetHeaderString(UInt_t idx)
{
TObjString tostr("n/a");
TString str(""), path(""), name(""), fmt(""), tstr("");
TMusrRunPhysicalQuantity prop;
// go through all objects and try to find it
// 1st check TString
for (UInt_t j=0; j<fStringObj.size(); j++) {
if (fStringObj[j].GetPathName() == fPathNameOrder[idx]) { // found correct object
SplitPathName(fStringObj[j].GetPathName(), path, name);
str.Form("%03d - %s: %s -@%d", idx, name.Data(), fStringObj[j].GetValue().Data(), MRH_TSTRING);
tostr.SetString(str);
}
}
// 2nd check Int_t
for (UInt_t j=0; j<fIntObj.size(); j++) {
if (fIntObj[j].GetPathName() == fPathNameOrder[idx]) { // found correct object
SplitPathName(fIntObj[j].GetPathName(), path, name);
str.Form("%03d - %s: %d -@%d", idx, name.Data(), fIntObj[j].GetValue(), MRH_INT);
tostr.SetString(str);
}
}
// 3rd check Double_t
for (UInt_t j=0; j<fDoubleObj.size(); j++) {
if (fDoubleObj[j].GetPathName() == fPathNameOrder[idx]) { // found correct object
SplitPathName(fDoubleObj[j].GetPathName(), path, name);
fmt.Form("%%03d - %%s: %%.%dlf -@%%d", MRH_DOUBLE_PREC);
str.Form(fmt, idx, name.Data(), fDoubleObj[j].GetValue(), MRH_DOUBLE);
tostr.SetString(str);
}
}
// 4th check TMusrRunPhysicalQuantity
for (UInt_t j=0; j<fMusrRunPhysQuantityObj.size(); j++) {
if (fMusrRunPhysQuantityObj[j].GetPathName() == fPathNameOrder[idx]) { // found correct object
prop = fMusrRunPhysQuantityObj[j].GetValue();
Int_t digit, digit_d;
if ((prop.GetDemand() != MRH_UNDEFINED) && (prop.GetValue() != MRH_UNDEFINED) && (prop.GetError() != MRH_UNDEFINED) &&
(prop.GetUnit() != "n/a")) { // <value> +- <error> <unit>; SP: <demand> [; <description>]
digit = GetDecimalPlace(prop.GetError());
digit_d = GetLeastSignificantDigit(prop.GetDemand());
if (prop.GetDescription() != "n/a") {
fmt.Form("%%s: %%.%dlf +- %%.%dlf %%s; SP: %%.%dlf; %%s", digit, digit, digit_d);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetError(), prop.GetUnit().Data(), prop.GetDemand(), prop.GetDescription().Data());
} else {
fmt.Form("%%s: %%.%dlf +- %%.%dlf %%s; SP: %%.%dlf", digit, digit, digit_d);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetError(), prop.GetUnit().Data(), prop.GetDemand());
}
} else if ((prop.GetDemand() == MRH_UNDEFINED) && (prop.GetValue() != MRH_UNDEFINED) && (prop.GetError() != MRH_UNDEFINED) &&
(prop.GetUnit() != "n/a")) { // <value> +- <error> <unit> [; <description>]
digit = GetDecimalPlace(prop.GetError());
if (prop.GetDescription() != "n/a") {
fmt.Form("%%s: %%.%dlf +- %%.%dlf %%s; %%s", digit, digit);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetError(), prop.GetUnit().Data(), prop.GetDescription().Data());
} else {
fmt.Form("%%s: %%.%dlf +- %%.%dlf %%s", digit, digit);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetError(), prop.GetUnit().Data());
}
} else if ((prop.GetDemand() == MRH_UNDEFINED) && (prop.GetValue() != MRH_UNDEFINED) && (prop.GetError() == MRH_UNDEFINED) &&
(prop.GetUnit() != "n/a")) { // <value> <unit> [; <description>]
digit = GetLeastSignificantDigit(prop.GetValue());
if (prop.GetDescription() != "n/a") {
fmt.Form("%%s: %%.%dlf %%s; %%s", digit);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetUnit().Data(), prop.GetDescription().Data());
} else {
fmt.Form("%%s: %%.%dlf %%s", digit);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetUnit().Data());
}
} else if ((prop.GetDemand() != MRH_UNDEFINED) && (prop.GetValue() != MRH_UNDEFINED) && (prop.GetError() == MRH_UNDEFINED) &&
(prop.GetUnit() != "n/a")) { // <value> <unit>; SP: <demand> [; <description>]
digit = GetLeastSignificantDigit(prop.GetValue());
digit_d = GetLeastSignificantDigit(prop.GetDemand());
if (prop.GetDescription() != "n/a") {
fmt.Form("%%s: %%.%dlf %%s; SP: %%.%dlf; %%s", digit, digit_d);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetUnit().Data(), prop.GetDemand(), prop.GetDescription().Data());
} else {
fmt.Form("%%s: %%.%dlf %%s; SP: %%.%dlf", digit, digit_d);
tstr.Form(fmt, prop.GetLabel().Data(), prop.GetValue(), prop.GetUnit().Data(), prop.GetDemand());
}
}
str.Form("%03d - %s -@%d", idx, tstr.Data(), MRH_TMUSR_RUN_PHYSICAL_QUANTITY);
tostr.SetString(str);
}
}
// 5th check TStringVector
for (UInt_t j=0; j<fStringVectorObj.size(); j++) {
if (fStringVectorObj[j].GetPathName() == fPathNameOrder[idx]) { // found correct object
SplitPathName(fStringVectorObj[j].GetPathName(), path, name);
str.Form("%03d - %s: ", idx, name.Data());
TStringVector vstr = fStringVectorObj[j].GetValue();
for (UInt_t k=0; k<vstr.size()-1; k++)
str += vstr[k] + "; ";
str += vstr[vstr.size()-1];
str += " -@";
str += MRH_TSTRING_VECTOR;
tostr.SetString(str);
}
}
// 6th check TIntVector
for (UInt_t j=0; j<fIntVectorObj.size(); j++) {
if (fIntVectorObj[j].GetPathName() == fPathNameOrder[idx]) { // found correct object
SplitPathName(fIntVectorObj[j].GetPathName(), path, name);
str.Form("%03d - %s: ", idx, name.Data());
TIntVector vint = fIntVectorObj[j].GetValue();
for (UInt_t k=0; k<vint.size()-1; k++) {
str += vint[k];
str += "; ";
}
str += vint[vint.size()-1];
str += " -@";
str += MRH_INT_VECTOR;
tostr.SetString(str);
}
}
// 7th check TDoubleVector
for (UInt_t j=0; j<fDoubleVectorObj.size(); j++) {
if (fDoubleVectorObj[j].GetPathName() == fPathNameOrder[idx]) { // found correct object
SplitPathName(fDoubleVectorObj[j].GetPathName(), path, name);
str.Form("%03d - %s: ", idx, name.Data());
TDoubleVector dvec = fDoubleVectorObj[j].GetValue();
TString subStr("");
fmt.Form("%%.%dlf", MRH_DOUBLE_PREC);
for (UInt_t k=0; k<dvec.size()-1; k++) {
subStr.Form(fmt, dvec[k]);
str += subStr;
str += "; ";
}
subStr.Form(fmt, dvec[dvec.size()-1]);
str += subStr;
str += " -@";
str += MRH_DOUBLE_VECTOR;
tostr.SetString(str);
}
}
return tostr;
}
//--------------------------------------------------------------------------
// RemoveFirst (private)
//--------------------------------------------------------------------------
/**
* <p>Removes the first junk of a string up to 'splitter'. If 'splitter' is
* NOT present in the string, the string stays untouched and the routine
* returns false.
*
* \param str string to be truncated
* \param splitter the start of the string up to the splitter character removed
*/
bool TMusrRunHeader::RemoveFirst(TString &str, const char splitter)
{
Ssiz_t idx = str.First(splitter);
if (idx == -1)
return false;
str.Remove(0, idx+1);
return true;
}
//--------------------------------------------------------------------------
// GetFirst (private)
//--------------------------------------------------------------------------
/**
* <p>Assuming a string built like 'this/is/a/string:with:diffrent:splitters'.
* Using as splitter '/', this routine would return 'this', it means get from str
* everything up to the first occurance of splitter. If splitter would be ':'
* in this example, the return string would be 'this/is/a/string'.
*
* <p>If splitter is <b>not</b> present in str the original str is returned.
*
* <p><b>return:</b> first part of up to the splitter in struct
*
* \param str
* \param splitter
*/
TString TMusrRunHeader::GetFirst(TString &str, const char splitter)
{
TString result = str;
Ssiz_t idx = str.First(splitter);
if (idx != -1)
result.Remove(idx, str.Length());
return result;
}
// end ---------------------------------------------------------------------