diff --git a/src/classes/PRunDataHandler.cpp b/src/classes/PRunDataHandler.cpp
index b95e46e9..814ecc94 100644
--- a/src/classes/PRunDataHandler.cpp
+++ b/src/classes/PRunDataHandler.cpp
@@ -164,6 +164,8 @@ Bool_t PRunDataHandler::ReadFile()
success = ReadMudFile();
else if (!runList->at(i).fFileFormat[j].CompareTo("wkm"))
success = ReadWkmFile();
+ else if (!runList->at(i).fFileFormat[j].CompareTo("mdu-ascii"))
+ success = ReadMduAsciiFile();
else if (!runList->at(i).fFileFormat[j].CompareTo("ascii"))
success = ReadAsciiFile();
else if (!runList->at(i).fFileFormat[j].CompareTo("db"))
@@ -238,6 +240,8 @@ Bool_t PRunDataHandler::FileExistsCheck(PMsrRunStructure &runInfo, const UInt_t
else
ext = runInfo.fBeamline[idx];
}
+ else if (!runInfo.fFileFormat[idx].CompareTo("mdu-ascii"))
+ ext = TString("mdua");
else if (!runInfo.fFileFormat[idx].CompareTo("ascii"))
ext = TString("dat");
else if (!runInfo.fFileFormat[idx].CompareTo("db"))
@@ -251,14 +255,15 @@ Bool_t PRunDataHandler::FileExistsCheck(PMsrRunStructure &runInfo, const UInt_t
str.ToUpper();
cout << endl << "File Format '" << str.Data() << "' unsupported.";
cout << endl << " support file formats are:";
- cout << endl << " ROOT-NPP -> root not post pileup corrected for lem";
- cout << endl << " ROOT-PPC -> root post pileup corrected for lem";
- cout << endl << " NEXUS -> nexus file format";
- cout << endl << " PSI-BIN -> psi bin file format";
- cout << endl << " MUD -> triumf mud file format";
- cout << endl << " WKM -> wkm ascii file format";
- cout << endl << " ASCII -> column like file format";
- cout << endl << " DB -> triumf db file \"format\"";
+ cout << endl << " ROOT-NPP -> root not post pileup corrected for lem";
+ cout << endl << " ROOT-PPC -> root post pileup corrected for lem";
+ cout << endl << " NEXUS -> nexus file format";
+ cout << endl << " PSI-BIN -> psi bin file format";
+ cout << endl << " MUD -> triumf mud file format";
+ cout << endl << " WKM -> wkm ascii file format";
+ cout << endl << " MDU-ASCII -> psi mdu ascii file format";
+ cout << endl << " ASCII -> column like file format";
+ cout << endl << " DB -> triumf db file \"format\"";
cout << endl;
return success;
}
@@ -1211,6 +1216,291 @@ cout << endl;
return true;
}
+//--------------------------------------------------------------------------
+// ReadMduAsciiFile
+//--------------------------------------------------------------------------
+/**
+ *
Reads the mdu ascii files (PSI). Needed to work around PSI-BIN limitations.
+ *
+ *
Lines starting with '#' or '%' are considered as comment lines. The file has
+ * the following structure:
+ * \verbatim
+ * HEADER
+ * TITLE: title-string
+ * SETUP: setup-string
+ * FIELD: val-string (G) or (T) (e.g. 123456 (G))
+ * TEMP: val-string (K)
+ * GROUPS: # of histograms written
+ * CHANNELS: # of bins per histogram written
+ * RESOLUTION: timeresolution (fs) or (ps) or (ns) or (us)
+ * \endverbatim
+ * followed by the data, which are written in column format, starting with the DATA
+ * tag, i.e.
+ * \verbatim
+ * DATA
+ *
+ * \endverbatim
+ *
+ */
+Bool_t PRunDataHandler::ReadMduAsciiFile()
+{
+ Bool_t success = true;
+
+ // open file
+ ifstream f;
+
+ // open data-file
+ f.open(fRunPathName.Data(), ifstream::in);
+ if (!f.is_open()) {
+ cerr << endl << "PRunDataHandler::ReadMduAsciiFile **ERROR** Couldn't open data file (" << fRunPathName.Data() << ") for reading, sorry ...";
+ cerr << endl;
+ return false;
+ }
+
+ PRawRunData runData;
+
+ // keep run name
+ runData.SetRunName(fRunName);
+
+ Int_t lineNo = 0;
+ Char_t instr[512];
+ TString line, workStr;
+ Bool_t headerTag = false;
+ Bool_t dataTag = false;
+ Int_t dataLineCounter = 0;
+ TObjString *ostr;
+ TObjArray *tokens = 0;
+ TString str;
+ Int_t groups = 0;
+ Int_t channels = 0;
+ Double_t dval = 0.0, unitScaling = 0.0;
+ vector data;
+
+ while (!f.eof()) {
+ f.getline(instr, sizeof(instr));
+ line = TString(instr);
+ lineNo++;
+
+ // ignore comment lines
+ if (line.BeginsWith("#") || line.BeginsWith("%"))
+ continue;
+
+ // ignore empty lines
+ if (line.IsWhitespace())
+ continue;
+
+ // check if header tag
+ workStr = line;
+ workStr.Remove(TString::kLeading, ' '); // remove spaces from the begining
+ if (workStr.BeginsWith("header", TString::kIgnoreCase)) {
+ headerTag = true;
+ dataTag = false;
+ continue;
+ }
+
+ // check if data tag
+ workStr = line;
+ workStr.Remove(TString::kLeading, ' '); // remove spaces from the beining
+ if (workStr.BeginsWith("data", TString::kIgnoreCase)) {
+ headerTag = false;
+ dataTag = true;
+ continue;
+ }
+
+ if (headerTag) {
+ workStr = line;
+ workStr.Remove(TString::kLeading, ' '); // remove spaces from the beining
+ if (workStr.BeginsWith("title:", TString::kIgnoreCase)) {
+ runData.SetRunTitle(TString(workStr.Data()+workStr.First(":")+2));
+ } else if (workStr.BeginsWith("field:", TString::kIgnoreCase)) {
+ tokens = workStr.Tokenize(":("); // field: val (units)
+ // check if expected number of tokens present
+ if (tokens->GetEntries() != 3) {
+ cerr << endl << "PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", invalid field entry in header.";
+ cerr << endl << line.Data();
+ cerr << endl;
+ success = false;
+ break;
+ }
+ // check if field value is a number
+ ostr = dynamic_cast(tokens->At(1));
+ if (ostr->GetString().IsFloat()) {
+ dval = ostr->GetString().Atof();
+ } else {
+ cerr << endl << "PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", field value is not float/doulbe.";
+ cerr << endl << line.Data();
+ cerr << endl;
+ success = false;
+ break;
+ }
+ // check units, accept (G), (T)
+ ostr = dynamic_cast(tokens->At(2));
+ if (ostr->GetString().Contains("G"))
+ unitScaling = 1.0;
+ else if (ostr->GetString().Contains("T"))
+ unitScaling = 1.0e4;
+ else {
+ cerr << endl << "PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", unkown field units.";
+ cerr << endl << line.Data();
+ cerr << endl;
+ success = false;
+ break;
+ }
+ runData.SetField(dval*unitScaling);
+
+ // clean up tokens
+ if (tokens) {
+ delete tokens;
+ tokens = 0;
+ }
+ } else if (workStr.BeginsWith("temp:", TString::kIgnoreCase)) {
+ tokens = workStr.Tokenize(":("); // temp: val (units)
+ // check if expected number of tokens present
+ if (tokens->GetEntries() != 3) {
+ cerr << endl << "PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", invalid temperatue entry in header.";
+ cerr << endl << line.Data();
+ cerr << endl;
+ success = false;
+ break;
+ }
+ // check if field value is a number
+ ostr = dynamic_cast(tokens->At(1));
+ if (ostr->GetString().IsFloat()) {
+ dval = ostr->GetString().Atof();
+ } else {
+ cerr << endl << "PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", temperature value is not float/doulbe.";
+ cerr << endl << line.Data();
+ cerr << endl;
+ success = false;
+ break;
+ }
+ runData.SetTemperature(0, dval, 0.0);
+
+ // clean up tokens
+ if (tokens) {
+ delete tokens;
+ tokens = 0;
+ }
+ } else if (workStr.BeginsWith("setup:", TString::kIgnoreCase)) {
+ runData.SetSetup(TString(workStr.Data()+workStr.First(":")+2));
+ } else if (workStr.BeginsWith("groups:", TString::kIgnoreCase)) {
+ workStr = TString(workStr.Data()+workStr.First(":")+2);
+ groups = workStr.Atoi();
+ if (groups == 0) {
+ cerr << endl << "PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", groups is not a number or 0.";
+ cerr << endl;
+ success = false;
+ break;
+ }
+ data.resize(groups);
+ } else if (workStr.BeginsWith("channels:", TString::kIgnoreCase)) {
+ workStr = TString(workStr.Data()+workStr.First(":")+2);
+ channels = workStr.Atoi();
+ if (channels == 0) {
+ cerr << endl << "PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", channels is not a number or 0.";
+ cerr << endl;
+ success = false;
+ break;
+ }
+ } else if (workStr.BeginsWith("resolution:", TString::kIgnoreCase)) {
+ tokens = workStr.Tokenize(":("); // resolution: val (units)
+ // check if expected number of tokens present
+ if (tokens->GetEntries() != 3) {
+ cerr << endl << "PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", invalid time resolution entry in header.";
+ cerr << endl << line.Data();
+ cerr << endl;
+ success = false;
+ break;
+ }
+ // check if timeresolution value is a number
+ ostr = dynamic_cast(tokens->At(1));
+ if (ostr->GetString().IsFloat()) {
+ dval = ostr->GetString().Atof();
+ } else {
+ cerr << endl << "PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", time resolution value is not float/doulbe.";
+ cerr << endl << line.Data();
+ cerr << endl;
+ success = false;
+ break;
+ }
+ // check units, accept (fs), (ps), (ns), (us)
+ ostr = dynamic_cast(tokens->At(2));
+ if (ostr->GetString().Contains("fs"))
+ unitScaling = 1.0e-6;
+ else if (ostr->GetString().Contains("ps"))
+ unitScaling = 1.0e-3;
+ else if (ostr->GetString().Contains("ns"))
+ unitScaling = 1.0;
+ else if (ostr->GetString().Contains("us"))
+ unitScaling = 1.0e3;
+ else {
+ cerr << endl << "PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", unkown time resolution units.";
+ cerr << endl << line.Data();
+ cerr << endl;
+ success = false;
+ break;
+ }
+ runData.SetTimeResolution(dval*unitScaling);
+
+ // clean up tokens
+ if (tokens) {
+ delete tokens;
+ tokens = 0;
+ }
+ } else { // error
+ cerr << endl << "PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", illegal header line.";
+ cerr << endl;
+ success = false;
+ break;
+ }
+ } else if (dataTag) {
+ dataLineCounter++;
+ tokens = line.Tokenize(" ,\t");
+ // check if the number of data line entries is correct
+ if (tokens->GetEntries() != groups+1) {
+ cerr << endl << "PRunDataHandler::ReadMduAsciiFile **ERROR** found data line with a wrong data format, cannot be handled (line no " << lineNo << ")";
+ cerr << endl << "line:";
+ cerr << endl << line.Data();
+ cerr << endl;
+ success = false;
+ break;
+ }
+
+ for (Int_t i=1; iGetEntries(); i++) {
+ ostr = dynamic_cast(tokens->At(i));
+ data[i-1].push_back(ostr->GetString().Atof());
+ }
+
+ // clean up tokens
+ if (tokens) {
+ delete tokens;
+ tokens = 0;
+ }
+ }
+ }
+
+ f.close();
+
+ // keep data
+ for (UInt_t i=0; i