diff --git a/src/classes/PMusr.cpp b/src/classes/PMusr.cpp
index 5eae027c..994cf6b6 100644
--- a/src/classes/PMusr.cpp
+++ b/src/classes/PMusr.cpp
@@ -150,6 +150,32 @@ PNonMusrRawRunData::~PNonMusrRawRunData()
fErrData.clear();
}
+//--------------------------------------------------------------------------
+// SetSize (public)
+//--------------------------------------------------------------------------
+/**
+ *
Allows to set the number of data sets before filling it. This is
+ * needed when reading dat-files generated from msr2data.
+ *
+ * @param size number of data sets
+ */
+void PNonMusrRawRunData::SetSize(const UInt_t size)
+{
+ // first clean up
+ for (UInt_t i=0; iReads column like data sets as generated by msr2data with the option
+ * 'data'. This can be used for the 'non muSR fit' type.
+ *
+ * return:
+ * - true at successful reading,
+ * - otherwise false.
+ */
Bool_t PRunDataHandler::ReadDatFile()
{
Bool_t success = true;
- std::cerr << "debug> in PRunDataHandler::ReadDatFile(). Not yet implemented..." << std::endl;
+ // open file
+ std::ifstream f;
+
+ // open db-file
+ f.open(fRunPathName.Data(), std::ifstream::in);
+ if (!f.is_open()) {
+ std::cerr << std::endl << ">> PRunDataHandler::ReadDatFile **ERROR** Couldn't open data file (" << fRunPathName.Data() << ") for reading, sorry ...";
+ std::cerr << std::endl;
+ return false;
+ }
+
+ PRawRunData runData;
+ runData.fDataNonMusr.SetFromAscii(false);
+
+ Int_t lineNo = 0;
+ Char_t instr[4096];
+ TString line;
+ Bool_t headerInfo=true;
+
+ // variables needed to tokenize strings
+ TString tstr;
+ TObjString *ostr;
+ TObjArray *tokens = nullptr;
+
+ UInt_t noOfDataSets = 0, noOfEntries = 0;
+ PBoolVector isData;
+ Double_t dval;
+
+ while (!f.eof()) {
+ // get next line from file
+ f.getline(instr, sizeof(instr));
+ line = TString(instr);
+ lineNo++;
+
+ // check if comment line
+ if (line.BeginsWith("#") || line.BeginsWith("%"))
+ continue;
+
+ // ignore empty lines
+ if (line.IsWhitespace())
+ continue;
+
+ tokens = line.Tokenize(" \t");
+ if (tokens == nullptr) { // error
+ std::cerr << std::endl << ">> PRunDataHandler::ReadDatFile **ERROR** couldn't tokenize the line, in lineNo: " << lineNo;
+ std::cerr << std::endl << ">> line: '" << line << "'.";
+ std::cerr << std::endl;
+ return false;
+ }
+
+ // filter header information
+ if (headerInfo) {
+ headerInfo = false;
+
+ // filter out all data tags: this labels are used in the msr-file to select the proper data set
+ // for the dat-files, label and dataTag are the same
+ noOfEntries = tokens->GetEntries();
+ for (Int_t i=0; i(tokens->At(i));
+ tstr = ostr->GetString();
+ if (!tstr.EndsWith("Err", TString::kExact)) {
+ noOfDataSets++;
+ isData.push_back(true);
+ runData.fDataNonMusr.AppendDataTag(tstr);
+ runData.fDataNonMusr.AppendLabel(tstr);
+ } else {
+ isData.push_back(false);
+ }
+ }
+ // set the size for the data
+ runData.fDataNonMusr.SetSize(noOfDataSets);
+ } else { // deal with data
+ if (noOfEntries == 0) {
+ std::cerr << std::endl << ">> PRunDataHandler::ReadDatFile **ERROR** header information is missing.";
+ std::cerr << std::endl;
+ return false;
+ }
+ if (tokens->GetEntries() != noOfEntries) { // error
+ std::cerr << std::endl << ">> PRunDataHandler::ReadDatFile **ERROR** data set with wrong number of entries: " << tokens->GetEntries() << ", should be " << noOfEntries << ".";
+ std::cerr << std::endl << ">> in line: " << lineNo;
+ std::cerr << std::endl << ">> line: '" << line << "'.";
+ std::cerr << std::endl;
+ return false;
+ }
+ // fill data and dataErr sets
+ UInt_t idx = 0;
+ for (UInt_t i=0; i(tokens->At(i));
+ tstr = ostr->GetString();
+ if (!tstr.IsFloat()) { // make sure it is a number
+ std::cerr << std::endl << ">> PRunDataHandler::ReadDatFile **ERROR** data set entry is not a number: " << tstr.Data();
+ std::cerr << std::endl << ">> in line: " << lineNo;
+ std::cerr << std::endl;
+ return false;
+ }
+ dval = tstr.Atof();
+ if (isData[i]) {
+ runData.fDataNonMusr.AppendSubData(idx, dval);
+ idx++;
+ } else { // error value
+ if (isData[i-1] == 1) { // Err or PosErr hence keep it
+ runData.fDataNonMusr.AppendSubErrData(idx-1, dval);
+ }
+ }
+ }
+ }
+ // cleanup
+ if (tokens) {
+ delete tokens;
+ tokens = nullptr;
+ }
+ }
+
+ f.close();
+
+ // got through all the data sets and if there is NO error vector set it to '0.0'
+ for (UInt_t i=0; iat(i).size() == 0) {
+ for (UInt_t j=0; jat(i).size(); j++) {
+ runData.fDataNonMusr.AppendSubErrData(i, 0.0);
+ }
+ }
+ }
+
+ // keep run name
+ runData.SetRunName(fRunName);
+
+ fData.push_back(runData);
return success;
}
diff --git a/src/include/PMusr.h b/src/include/PMusr.h
index 8b834da3..289a658c 100644
--- a/src/include/PMusr.h
+++ b/src/include/PMusr.h
@@ -301,6 +301,7 @@ class PNonMusrRawRunData {
virtual const std::vector* GetErrData() { return &fErrData; }
virtual void SetFromAscii(const Bool_t bval) { fFromAscii = bval; }
+ virtual void SetSize(const UInt_t size);
virtual void AppendLabel(const TString str) { fLabels.push_back(str); }
virtual void SetLabel(const UInt_t idx, const TString str);
virtual void AppendDataTag(const TString str) { fDataTags.push_back(str); }
@@ -310,7 +311,7 @@ class PNonMusrRawRunData {
virtual void AppendSubErrData(const UInt_t idx, const Double_t dval);
private:
- Bool_t fFromAscii; ///< if true: data file was an ascii input file, otherwise it is a db input file
+ Bool_t fFromAscii; ///< if true: data file was an ascii input file, otherwise it is a db/dat input file
PStringVector fLabels; ///< vector of all labels (used for x-, y-axis title in view)
PStringVector fDataTags; ///< vector of all data tags
std::vector fData; ///< vector of all data