/*************************************************************************** PRunDataHandler.cpp Author: Andreas Suter e-mail: andreas.suter@psi.ch $Id$ ***************************************************************************/ /*************************************************************************** * Copyright (C) 2007 by Andreas Suter * * andreas.suter@psi.c * * * * 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 #include #include using namespace std; #include #include #include #include #include #include #include #include #include #include "TLemRunHeader.h" #include "MuSR_td_PSI_bin.h" #include "mud.h" #include "PRunDataHandler.h" //-------------------------------------------------------------------------- // Constructor //-------------------------------------------------------------------------- /** *

Constructor, reading the data histogramm files. * */ PRunDataHandler::PRunDataHandler(PMsrHandler *msrInfo) : fMsrInfo(msrInfo) { // read files if (!ReadFile()) // couldn't read file fAllDataAvailable = false; else fAllDataAvailable = true; } //-------------------------------------------------------------------------- // Constructor //-------------------------------------------------------------------------- /** *

Constructor, reading the data histogramm files, and keeping a copy * of potential search paths. */ PRunDataHandler::PRunDataHandler(PMsrHandler *msrInfo, const PStringVector dataPath) : fMsrInfo(msrInfo), fDataPath(dataPath) { // read files if (!ReadFile()) // couldn't read file fAllDataAvailable = false; else fAllDataAvailable = true; } //-------------------------------------------------------------------------- // Destructor //-------------------------------------------------------------------------- /** *

Destructor. * */ PRunDataHandler::~PRunDataHandler() { for (unsigned int i=0; i Checks if runName is found. * * return: if data are found: pointer to the data. * otherwise the null pointer will be returned. * * \param runName run name, e.g. 2009/lem09_his_1234 */ PRawRunData* PRunDataHandler::GetRunData(const TString &runName) { unsigned int i; for (i=0; i The main read file routine which is filtering what read sub-routine * needs to be called. * * return: true if reading was successful, false if reading failed. */ bool PRunDataHandler::ReadFile() { bool success = true; // loop over the full RUN list to see what needs to be read PMsrRunList *runList = 0; runList = fMsrInfo->GetMsrRunList(); if (runList == 0) { cout << endl << "PRunDataHandler::ReadFile(): Couldn't obtain run list from PMsrHandler: something VERY fishy"; return false; } for (unsigned int i=0; isize(); i++) { for (unsigned int j=0; jat(i).fRunName.size(); j++) { fRunName = runList->at(i).fRunName[j]; // check is file is already read if (FileAlreadyRead(runList->at(i).fRunName[j])) continue; // check if file actually exists if (!FileExistsCheck(runList->at(i), j)) return false; // everything looks fine, hence try to read the data file if (!runList->at(i).fFileFormat[j].CompareTo("root-npp")) // not post pile up corrected histos success = ReadRootFile(true); else if (!runList->at(i).fFileFormat[j].CompareTo("root-ppc")) // post pile up corrected histos success = ReadRootFile(false); else if (!runList->at(i).fFileFormat[j].CompareTo("nexus")) success = ReadNexusFile(); else if (!runList->at(i).fFileFormat[j].CompareTo("psi-bin")) success = ReadPsiBinFile(); else if (!runList->at(i).fFileFormat[j].CompareTo("mud")) success = ReadMudFile(); else if (!runList->at(i).fFileFormat[j].CompareTo("wkm")) success = ReadWkmFile(); else if (!runList->at(i).fFileFormat[j].CompareTo("ascii")) success = ReadAsciiFile(); else if (!runList->at(i).fFileFormat[j].CompareTo("db")) success = ReadDBFile(); else success = false; } } return success; } //-------------------------------------------------------------------------- // FileAlreadyRead //-------------------------------------------------------------------------- /** *

Checks if a file has been already read in order to prevent multiple * reading of data files. * * return: true if the file has been read before, otherwise false. */ bool PRunDataHandler::FileAlreadyRead(TString runName) { for (unsigned int i=0; i Checks if a given data file exists. * * \param runInfo reference to the msr-run-structure * \param idx index of the run (needed for ADDRUN feature). * * return: true if data file exists, otherwise false. */ bool PRunDataHandler::FileExistsCheck(PMsrRunStructure &runInfo, const unsigned int idx) { bool success = true; // local init TROOT root("PRunBase", "PRunBase", 0); TString pathName = "???"; TString str; TString ext; runInfo.fBeamline[idx].ToLower(); runInfo.fInstitute[idx].ToLower(); runInfo.fFileFormat[idx].ToLower(); // file extensions for the various formats if (!runInfo.fFileFormat[idx].CompareTo("root-npp")) // not post pile up corrected histos ext = TString("root"); else if (!runInfo.fFileFormat[idx].CompareTo("root-ppc")) // post pile up corrected histos ext = TString("root"); else if (!runInfo.fFileFormat[idx].CompareTo("nexus")) ext = TString("nexus"); else if (!runInfo.fFileFormat[idx].CompareTo("psi-bin")) ext = TString("bin"); else if (!runInfo.fFileFormat[idx].CompareTo("mud")) ext = TString("mud"); else if (!runInfo.fFileFormat[idx].CompareTo("wkm")) { if (!runInfo.fBeamline[idx].CompareTo("mue4")) ext = TString("nemu"); else ext = runInfo.fBeamline[idx]; } else if (!runInfo.fFileFormat[idx].CompareTo("ascii")) ext = TString("dat"); else if (!runInfo.fFileFormat[idx].CompareTo("db")) ext = TString("db"); else success = false; // unkown file format found if (!success) { str = runInfo.fFileFormat[idx]; 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; return success; } // check if the file is in the local directory str = runInfo.fRunName[idx] + TString(".") + ext; if (gSystem->AccessPathName(str.Data())!=true) { // found in the local dir pathName = str; } // check if the file is found in the if (pathName.CompareTo("???") == 0) { // not found in local directory search str = *fMsrInfo->GetMsrFileDirectoryPath(); str += runInfo.fRunName[idx] + TString(".") + ext; if (gSystem->AccessPathName(str.Data())!=true) { // found pathName = str; } } // check if the file is found in the directory given in the startup file if (pathName.CompareTo("???") == 0) { // not found in local directory search for (unsigned int i=0; iAccessPathName(str.Data())!=true) { // found pathName = str; break; } } } // check if the file is found in the directories given by WKMFULLDATAPATH const char *wkmpath = gSystem->Getenv("WKMFULLDATAPATH"); if (pathName.CompareTo("???") == 0) { // not found in local directory and xml path str = TString(wkmpath); // WKMFULLDATAPATH has the structure: path_1:path_2:...:path_n TObjArray *tokens = str.Tokenize(":"); TObjString *ostr; for (int i=0; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString() + TString("/") + runInfo.fRunName[idx] + TString(".") + ext; if (gSystem->AccessPathName(str.Data())!=true) { // found pathName = str; break; } } } // check if the file is found in the WKM generated default path if (pathName.CompareTo("???") == 0) { // not found in WKMFULLDATAPATH search str = TString(wkmpath); // WKMFULLDATAPATH has the structure: path_1:path_2:...:path_n TObjArray *tokens = str.Tokenize(":"); TObjString *ostr; runInfo.fInstitute[idx].ToUpper(); runInfo.fBeamline[idx].ToUpper(); TDatime datetime; TString dt; dt += datetime.GetYear(); for (int i=0; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString() + TString("/DATA/") + runInfo.fInstitute[idx] + TString("/") + runInfo.fBeamline[idx] + TString("/") + dt + TString("/") + runInfo.fRunName[idx] + TString(".") + ext; if (gSystem->AccessPathName(str.Data())!=true) { // found pathName = str; break; } } } // no proper path name found if (pathName.CompareTo("???") == 0) { cerr << endl << "**ERROR** Couldn't find '" << runInfo.fRunName[idx] << "' in any standard path."; cerr << endl << " standard search pathes are:"; cerr << endl << " 1. the local directory"; cerr << endl << " 2. the data directory given in the startup XML file"; cerr << endl << " 3. the directories listed in WKMFULLDATAPATH"; cerr << endl << " 4. default path construct which is described in the manual"; return false; } fRunPathName = pathName; return true; } //-------------------------------------------------------------------------- // ReadRootFile //-------------------------------------------------------------------------- /** *

Reads the LEM-data ROOT-files. * * \param notPostPileup This flag is used as a switch between "Not Post Pileup Corrected" * and "Post Pileup Corrected" histogramms. * * return: true at successful reading, otherwise false. */ bool PRunDataHandler::ReadRootFile(bool notPostPileup) { PDoubleVector histoData; PRawRunData runData; TFile f(fRunPathName.Data()); if (f.IsZombie()) { return false; } TFolder *folder; f.GetObject("RunInfo", folder); if (!folder) { cout << endl << "Couldn't obtain RunInfo from " << fRunPathName.Data() << endl; f.Close(); return false; } // read header and check if some missing run info need to be fed TLemRunHeader *runHeader = dynamic_cast(folder->FindObjectAny("TLemRunHeader")); // check if run header is valid if (!runHeader) { cout << endl << "Couldn't obtain run header info from ROOT file " << fRunPathName.Data() << endl; f.Close(); return false; } // get run title TObjString ostr = runHeader->GetRunTitle(); runData.fRunTitle = ostr.GetString(); // get temperature runData.fTemp.resize(1); runData.fTemp[0].first = runHeader->GetSampleTemperature(); runData.fTemp[0].second = runHeader->GetSampleTemperatureError(); // get field runData.fField = runHeader->GetSampleBField(); // get implantation energy runData.fEnergy = runHeader->GetImpEnergy(); // get moderator HV runData.fTransport = runHeader->GetModeratorHV(); // get setup runData.fSetup = runHeader->GetLemSetup().GetString(); // get time resolution runData.fTimeResolution = runHeader->GetTimeResolution(); // get number of histogramms int noOfHistos = runHeader->GetNHist(); // get t0's Double_t *t0 = runHeader->GetTimeZero(); // check if t0's are there if (t0[0] != -1) { // ugly, but at the moment there is no other way // copy t0's so they are not lost for (int i=0; i(folder->FindObjectAny("RunSummary")); // check if run summary is valid if (!runSummary) { cout << endl << "Couldn't obtain run summary info from ROOT file " << fRunPathName.Data() << endl; // this is not fatal... only RA-HV values are not available } else { // it follows a (at least) little bit strange extraction of the RA values from Thomas' TObjArray... //streaming of a ASCII-file would be more easy TString s, tok; TObjArrayIter summIter(runSummary); TObjString *os(dynamic_cast(summIter.Next())); TObjArray *oa(0); TObjString *objTok(0); while(os != 0){ s = os->GetString(); // will put four parallel if's since it may be that more than one RA-values are on one line if(s.Contains("RA-L")){ if(runData.fRingAnode.empty() || runData.fRingAnode.size() == 2) runData.fRingAnode.resize(2); oa = s.Tokenize(" "); TObjArrayIter lineIter(oa); objTok = dynamic_cast(lineIter.Next()); while (objTok != 0){ if(!objTok->GetString().CompareTo("RA-L")){ objTok = dynamic_cast(lineIter.Next()); // "=" if(objTok != 0 && !objTok->GetString().CompareTo("=")){ objTok = dynamic_cast(lineIter.Next()); // HV value runData.fRingAnode[0] = objTok->GetString().Atof(); // fill RA-R value into the runData structure break; } } objTok = dynamic_cast(lineIter.Next()); // next token... } } if(s.Contains("RA-R")){ if(runData.fRingAnode.empty() || runData.fRingAnode.size() == 2) runData.fRingAnode.resize(2); oa = s.Tokenize(" "); TObjArrayIter lineIter(oa); objTok = dynamic_cast(lineIter.Next()); while (objTok != 0){ if(!objTok->GetString().CompareTo("RA-R")){ objTok = dynamic_cast(lineIter.Next()); // "=" if(objTok != 0 && !objTok->GetString().CompareTo("=")){ objTok = dynamic_cast(lineIter.Next()); // HV value runData.fRingAnode[1] = objTok->GetString().Atof(); // fill RA-R value into the runData structure break; } } objTok = dynamic_cast(lineIter.Next()); // next token... } } if(s.Contains("RA-T")){ if(runData.fRingAnode.empty() || runData.fRingAnode.size() == 2) runData.fRingAnode.resize(4); oa = s.Tokenize(" "); TObjArrayIter lineIter(oa); objTok = dynamic_cast(lineIter.Next()); while (objTok != 0){ if(!objTok->GetString().CompareTo("RA-T")){ objTok = dynamic_cast(lineIter.Next()); // "=" if(objTok != 0 && !objTok->GetString().CompareTo("=")){ objTok = dynamic_cast(lineIter.Next()); // HV value runData.fRingAnode[2] = objTok->GetString().Atof(); // fill RA-T value into the runData structure break; } } objTok = dynamic_cast(lineIter.Next()); // next token... } } if(s.Contains("RA-B")){ if(runData.fRingAnode.empty() || runData.fRingAnode.size() == 2) runData.fRingAnode.resize(4); oa = s.Tokenize(" "); TObjArrayIter lineIter(oa); objTok = dynamic_cast(lineIter.Next()); while (objTok != 0){ if(!objTok->GetString().CompareTo("RA-B")){ objTok = dynamic_cast(lineIter.Next()); // "=" if(objTok != 0 && !objTok->GetString().CompareTo("=")){ objTok = dynamic_cast(lineIter.Next()); // HV value runData.fRingAnode[3] = objTok->GetString().Atof(); // fill RA-B value into the runData structure break; } } objTok = dynamic_cast(lineIter.Next()); // next token... } } os = dynamic_cast(summIter.Next()); // next summary line... } } // read data --------------------------------------------------------- // check if histos folder is found f.GetObject("histos", folder); if (!folder) { cout << endl << "Couldn't obtain histos from " << fRunPathName.Data() << endl; f.Close(); return false; } // get all the data char histoName[32]; if (notPostPileup) { // read the data which are NOT post pileup corrected for (int i=0; i(folder->FindObjectAny(histoName)); if (!histo) { cout << endl << "PRunDataHandler::ReadRootFile: Couldn't get histo " << histoName; return false; } // fill data for (int j=1; jGetNbinsX(); j++) histoData.push_back(histo->GetBinContent(j)); // store them in runData vector runData.fDataBin.push_back(histoData); // clear histoData for the next histo histoData.clear(); } } else { // read the data which ARE post pileup corrected for (int i=0; i(folder->FindObjectAny(histoName)); if (!histo) { cout << endl << "PRunDataHandler::ReadRootFile: Couldn't get histo " << histoName; return false; } // fill data for (int j=1; jGetNbinsX(); j++) histoData.push_back(histo->GetBinContent(j)); // store them in runData vector runData.fDataBin.push_back(histoData); // clear histoData for the next histo histoData.clear(); } } f.Close(); // keep run name runData.fRunName = fRunName; // add run to the run list fData.push_back(runData); // clean up for (unsigned int i=0; i Will read the NeXuS File Format as soon as PSI will have an implementation. * * * return: true at successful reading, otherwise false. */ bool PRunDataHandler::ReadNexusFile() { cout << endl << "PRunDataHandler::ReadNexusFile(): Sorry, not yet implemented, ask Alex Amato ..."; return false; } //-------------------------------------------------------------------------- // ReadWkmFile //-------------------------------------------------------------------------- /** *

Reads, for backwards compatibility, the ascii-wkm-file data format. * The routine is clever enough to distinguish the different wkm-flavours (argh). * * return: true at successful reading, otherwise false. */ bool PRunDataHandler::ReadWkmFile() { PDoubleVector histoData; PRawRunData runData; // init runData header info runData.fRunName = TString(""); runData.fRunTitle = TString(""); runData.fSetup = TString(""); runData.fField = -9.9e99; runData.fTemp.clear(); runData.fEnergy = -999.0; // standard LEM values... runData.fTransport = -999.0; // standard LEM values... runData.fRingAnode.clear(); runData.fTimeResolution = 0.0; // open file ifstream f; // open wkm-file f.open(fRunPathName.Data(), ifstream::in); if (!f.is_open()) { cout << endl << "Couldn't open run data (" << fRunPathName.Data() << ") file for reading, sorry ..."; cout << endl; return false; } // read header bool headerInfo = true; char instr[512]; TString line, linecp; double dval; int ival; bool ok; int groups = 0, channels = 0; // skip leading empty lines do { f.getline(instr, sizeof(instr)); line = TString(instr); if (!line.IsWhitespace()) break; } while (!f.eof()); // real header data should start here Ssiz_t idx; do { line = TString(instr); if (line.IsDigit()) { // end of header reached headerInfo = false; } else { // real stuff, hence filter data if (line.Contains("Title") || line.Contains("Titel")) { idx = line.Index(":"); line.Replace(0, idx+1, 0, 0); // remove 'Title:' StripWhitespace(line); runData.fRunTitle = line; } else if (line.Contains("Field")) { idx = line.Index(":"); line.Replace(0, idx+1, 0, 0); // remove 'Field:' StripWhitespace(line); idx = line.Index("G"); // check if unit is given if (idx > 0) // unit is indeed given line.Resize(idx); dval = ToDouble(line, ok); if (ok) runData.fField = dval; } else if (line.Contains("Setup")) { idx = line.Index(":"); line.Replace(0, idx+1, 0, 0); // remove 'Setup:' StripWhitespace(line); runData.fSetup = line; } else if (line.Contains("Temp:") || line.Contains("Temp(meas1):")) { linecp = line; idx = line.Index(":"); line.Replace(0, idx+1, 0, 0); // remove 'Temp:' StripWhitespace(line); idx = line.Index("+/-"); // remove "+/- ..." part if (idx > 0) line.Resize(idx); idx = line.Index("K"); // remove "K ..." part if (idx > 0) line.Resize(idx); dval = ToDouble(line, ok); if (ok){ runData.fTemp.resize(1); runData.fTemp[0].first = dval; runData.fTemp[0].second = 0.0; } idx = linecp.Index("+/-"); // get the error linecp.Replace(0, idx+3, 0, 0); StripWhitespace(linecp); dval = ToDouble(linecp, ok); if (ok && !runData.fTemp.empty()){ runData.fTemp[0].second = dval; } } else if (line.Contains("Temp(meas2):")) { linecp = line; idx = line.Index(":"); line.Replace(0, idx+1, 0, 0); // remove 'Temp(meas2):' StripWhitespace(line); idx = line.Index("+/-"); // remove "+/- ..." part if (idx > 0) line.Resize(idx); idx = line.Index("K"); // remove "K ..." part if (idx > 0) line.Resize(idx); dval = ToDouble(line, ok); if (ok){ runData.fTemp.resize(2); runData.fTemp[1].first = dval; runData.fTemp[1].second = 0.0; } idx = linecp.Index("+/-"); // get the error linecp.Replace(0, idx+3, 0, 0); StripWhitespace(linecp); dval = ToDouble(linecp, ok); if (ok && runData.fTemp.size() > 1){ runData.fTemp[1].second = dval; } } else if (line.Contains("Groups")) { idx = line.Index(":"); line.Replace(0, idx+1, 0, 0); // remove 'Groups:' StripWhitespace(line); ival = ToInt(line, ok); if (ok) groups = ival; } else if (line.Contains("Channels")) { idx = line.Index(":"); line.Replace(0, idx+1, 0, 0); // remove 'Channels:' StripWhitespace(line); ival = ToInt(line, ok); if (ok) channels = ival; } else if (line.Contains("Resolution")) { idx = line.Index(":"); line.Replace(0, idx+1, 0, 0); // remove 'Resolution:' StripWhitespace(line); dval = ToDouble(line, ok); if (ok) runData.fTimeResolution = dval * 1000.0; } } if (headerInfo) f.getline(instr, sizeof(instr)); } while (headerInfo && !f.eof()); if ((groups == 0) || (channels == 0) || runData.fTimeResolution == 0.0) { cerr << endl << "PRunDataHandler::ReadWkmFile(): **ERROR** essential header informations are missing!"; cerr << endl << " >> groups = " << groups; cerr << endl << " >> channels = " << channels; cerr << endl << " >> time resolution = " << runData.fTimeResolution; cerr << endl; f.close(); return false; } // read data --------------------------------------------------------- unsigned int group_counter = 0; int val; TObjArray *tokens; TObjString *ostr; TString str; do { // check if empty line, i.e. new group if (IsWhitespace(instr)) { runData.fDataBin.push_back(histoData); histoData.clear(); group_counter++; } else { // extract values line = TString(instr); // check if line starts with character. Needed for RAL WKM format if (!line.IsDigit()) { f.getline(instr, sizeof(instr)); continue; } tokens = line.Tokenize(" "); if (!tokens) { // no tokens found cerr << endl << "PRunDataHandler::ReadWkmFile(): **ERROR** while reading data: coulnd't tokenize run data."; // clean up for (unsigned int i=0; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString(); val = ToInt(str, ok); if (ok) { histoData.push_back(val); } else { cerr << endl << "PRunDataHandler::ReadWkmFile(): **ERROR** while reading data: data line contains non-integer values."; // clean up for (unsigned int i=0; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); str = ostr->GetString(); val = ToInt(str, ok); if (ok) { histoData.push_back(val); } else { cerr << endl << "PRunDataHandler::ReadWkmFile(): **ERROR** while reading data: data line contains non-integer values."; // clean up for (unsigned int i=0; i 0) { runData.fDataBin.push_back(histoData); histoData.clear(); } // close file f.close(); // check if all groups are found if ((int) runData.fDataBin.size() != groups) { cerr << endl << "PRunDataHandler::ReadWkmFile(): **ERROR**"; cerr << endl << " expected " << groups << " histos, but found " << runData.fDataBin.size(); // clean up for (unsigned int i=0; i Reads the old-fashioned PSI-BIN data-files. The MuSR_td_PSI_bin class * of Alex Amato is used. In case of problems, please contact alex.amato@psi.ch. * * return: true at successful reading, otherwise false. */ bool PRunDataHandler::ReadPsiBinFile() { MuSR_td_PSI_bin psiBin; int status; bool success; // read psi bin file status = psiBin.read(fRunPathName.Data()); switch (status) { case 0: // everything perfect success = true; break; case 1: // couldn't open file, or failed while reading the header cerr << endl << "**ERROR** couldn't open psibin file, or failed while reading the header"; cerr << endl; success = false; break; case 2: // unsupported version of the data cerr << endl << "**ERROR** psibin file: unsupported version of the data"; cerr << endl; success = false; break; case 3: // error when allocating data buffer cerr << endl << "**ERROR** psibin file: error when allocating data buffer"; cerr << endl; success = false; break; case 4: // number of histograms/record not equals 1 cerr << endl << "**ERROR** psibin file: number of histograms/record not equals 1"; cerr << endl; success = false; break; default: // you never should have reached this point success = false; break; } // if any reading error happend, get out of here if (!success) return success; // fill necessary header informations PIntVector ivec; PRawRunData runData; double dval; // keep run name runData.fRunName = fRunName; // get run title runData.fRunTitle = TString(psiBin.get_comment().c_str()); // run title // get setup runData.fSetup = TString(psiBin.get_orient().c_str()); // set LEM specific information to default value since it is not in the file and not used... runData.fEnergy = -999.0; runData.fTransport = -999.0; runData.fRingAnode.clear(); // get field status = sscanf(psiBin.get_field().c_str(), "%lfG", &dval); if (status == 1) runData.fField = dval; // get temperature PDoubleVector tempVec(psiBin.get_temperatures_vector()); PDoubleVector tempDevVec(psiBin.get_devTemperatures_vector()); if(tempVec.size() > 1 && tempDevVec.size() > 1 && tempVec[0] && tempVec[1]) { runData.fTemp.resize(2); // take only the first two values for now... //maybe that's not enough - e.g. in older GPD data I saw the "correct values in the second and third entry..." for (unsigned int i(0); i<2; i++){ runData.fTemp[i].first = tempVec[i]; runData.fTemp[i].second = tempDevVec[i]; } tempVec.clear(); tempDevVec.clear(); } else { status = sscanf(psiBin.get_temp().c_str(), "%lfK", &dval); if (status == 1) runData.fTemp.resize(1); runData.fTemp[0].first = dval; runData.fTemp[0].second = 0.0; } // get time resolution (ns) runData.fTimeResolution = psiBin.get_binWidth_ns(); // get t0's ivec = psiBin.get_t0_vector(); if (ivec.empty()) { cerr << endl << "**ERROR** psibin file: couldn't obtain any t0's"; cerr << endl; return false; } for (unsigned int i=0; i Reads the triumf mud-file format. Not yet implemented, sorry. * * return: true at successful reading, otherwise false. */ bool PRunDataHandler::ReadMudFile() { Int_t fh; UINT32 type; fh = MUD_openRead((char *)fRunPathName.Data(), &type); if (fh == -1) { cerr << endl << "**ERROR** Couldn't open mud-file " << fRunPathName.Data() << ", sorry."; cerr << endl; return false; } // read necessary header information // STILL MISSING // read histograms // STILL MISSING MUD_closeRead(fh); return true; } //-------------------------------------------------------------------------- // ReadAsciiFile //-------------------------------------------------------------------------- /** *

Reads ascii files. Intended for the nonMuSR data. * * The file format definition is: * Comment lines start with a '#' or '%' character. * The file can start with some header info. The header is optional, as all its tags, but * if present it has the following format: * * \verbatim * HEADER * TITLE: title * X-AXIS-TITLE: x-axis title * Y-AXIS-TITLE: y-axis title * SETUP: setup * FIELD: field * TEMP: temperature * ENERGY: energy * \endverbatim * * field is assumed to be given in (G), the temperature in (K), the energy in (keV) * * The data are read column like and start with the data tag DATA, followed by the * data columns, i.e.: * * \verbatim * DATA * x, y [, error y] * \endverbatim * * where spaces, column, are a tab are possible separations. * If no error in y is present, the weighting in the fit will be equal. * * return: true at successful reading, otherwise false. */ bool PRunDataHandler::ReadAsciiFile() { bool success = true; // open file ifstream f; // open data-file f.open(fRunPathName.Data(), ifstream::in); if (!f.is_open()) { cerr << endl << "PRunDataHandler::ReadAsciiFile **ERROR** Couldn't open data file (" << fRunPathName.Data() << ") for reading, sorry ..."; cerr << endl; return false; } PRawRunData runData; // init some stuff runData.fDataNonMusr.fFromAscii = true; runData.fDataNonMusr.fLabels.push_back("??"); // x default label runData.fDataNonMusr.fLabels.push_back("??"); // y default label runData.fRunName = fRunName; // keep the run name int lineNo = 0; char instr[512]; TString line, workStr; bool headerTag = false; bool dataTag = false; double x, y, ey; PDoubleVector xVec, exVec, yVec, eyVec; while (!f.eof()) { f.getline(instr, sizeof(instr)); line = TString(instr); lineNo++; // check if comment line if (line.BeginsWith("#") || line.BeginsWith("%")) 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) { if (line.IsWhitespace()) // ignore empty lines continue; workStr = line; workStr.Remove(TString::kLeading, ' '); // remove spaces from the beining if (workStr.BeginsWith("title:", TString::kIgnoreCase)) { runData.fRunTitle = TString(workStr.Data()+workStr.First(":")+2); } else if (workStr.BeginsWith("setup:", TString::kIgnoreCase)) { runData.fSetup = TString(workStr.Data()+workStr.First(":")+2); } else if (workStr.BeginsWith("field:", TString::kIgnoreCase)) { workStr = TString(workStr.Data()+workStr.First(":")+2); if (!workStr.IsFloat()) { cerr << endl << "PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ", field is not a number."; cerr << endl; success = false; break; } runData.fField = workStr.Atof(); } else if (workStr.BeginsWith("x-axis-title:", TString::kIgnoreCase)) { runData.fDataNonMusr.fLabels[0] = TString(workStr.Data()+workStr.First(":")+2); } else if (workStr.BeginsWith("y-axis-title:", TString::kIgnoreCase)) { runData.fDataNonMusr.fLabels[1] = TString(workStr.Data()+workStr.First(":")+2); } else if (workStr.BeginsWith("temp:", TString::kIgnoreCase)) { workStr = TString(workStr.Data()+workStr.First(":")+2); if (!workStr.IsFloat()) { cerr << endl << "PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ", temperature is not a number."; cerr << endl; success = false; break; } runData.fTemp.resize(1); runData.fTemp[0].first = workStr.Atof(); runData.fTemp[0].second = 0.0; } else if (workStr.BeginsWith("energy:", TString::kIgnoreCase)) { workStr = TString(workStr.Data()+workStr.First(":")+2); if (!workStr.IsFloat()) { cerr << endl << "PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ", energy is not a number."; cerr << endl; success = false; break; } runData.fEnergy = workStr.Atof(); runData.fTransport = -999.0; // just to initialize the variables to some "meaningful" value runData.fRingAnode.clear(); } else { // error cerr << endl << "PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ", illegal header line."; cerr << endl; success = false; break; } } else if (dataTag) { if (line.IsWhitespace()) // ignore empty lines continue; TObjString *ostr; TObjArray *tokens; // check if data have x, y [, error y] structure, and that x, y, and error y are numbers tokens = line.Tokenize(" ,\t"); // check if the number of data line entries is 2 or 3 if ((tokens->GetEntries() != 2) && (tokens->GetEntries() != 3)) { cerr << endl << "PRunDataHandler::ReadAsciiFile **ERROR** found data line with a structure different than \"x, y [, error y]\", cannot be handled (line no " << lineNo << ")"; cerr << endl; success = false; break; } // get x ostr = dynamic_cast(tokens->At(0)); if (!ostr->GetString().IsFloat()) { cerr << endl << "PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ": x = " << ostr->GetString().Data() << " is not a number, sorry."; cerr << endl; success = false; break; } x = ostr->GetString().Atof(); // get y ostr = dynamic_cast(tokens->At(1)); if (!ostr->GetString().IsFloat()) { cerr << endl << "PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ": y = " << ostr->GetString().Data() << " is not a number, sorry."; cerr << endl; success = false; break; } y = ostr->GetString().Atof(); // get error y if present if (tokens->GetEntries() == 3) { ostr = dynamic_cast(tokens->At(2)); if (!ostr->GetString().IsFloat()) { cerr << endl << "PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ": error y = " << ostr->GetString().Data() << " is not a number, sorry."; cerr << endl; success = false; break; } ey = ostr->GetString().Atof(); } else { ey = 1.0; } // clean up tokens if (tokens) { delete tokens; tokens = 0; } // keep values xVec.push_back(x); exVec.push_back(1.0); yVec.push_back(y); eyVec.push_back(ey); } else { cerr << endl << "PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << " neither header nor data line. No idea how to handle it!"; cerr << endl; success = false; break; } } f.close(); // keep values runData.fDataNonMusr.fData.push_back(xVec); runData.fDataNonMusr.fErrData.push_back(exVec); runData.fDataNonMusr.fData.push_back(yVec); runData.fDataNonMusr.fErrData.push_back(eyVec); fData.push_back(runData); // clean up xVec.clear(); exVec.clear(); yVec.clear(); eyVec.clear(); runData.fDataNonMusr.fData.clear(); runData.fDataNonMusr.fErrData.clear(); return success; } //-------------------------------------------------------------------------- // ReadDBFile //-------------------------------------------------------------------------- /** *

Reads triumf db-files. Intended for the nonMuSR data. * *

The file format definition is: * The following is a description of the features of the TRIUMF .db file format that are * currently recognized by musrfit/musrview. The available commands include: title, abstract, * comments, labels, and data. * * \verbatim * TITLE * The following line must contain the title. * * * ABSTRACT * The abstract is read in starting with the following line until an empty line is reached. * * COMMENTS * The comments are read in starting with the following line until an empty line is reached. * * * LABELS * One label must occupy each subsequent line until an empty line is reached. The number * of labels should preferably match the number of variables in the data. * * DATA * On the same line as the DATA command, there must appear a comma-delimited list of variable * names. These names should be kept short (some applications truncate to 4 characters). The * numerical data is read in beginning with the following line until an empty line is reached. * * In every line, there must appear exactly 3 comma-delimited fields for each specified name. * The first field is the value, the second is the positive error, and the third is the negative * error. If you leave the last field blank (the comma is still required), then the positive error * will be interpreted as a symmetric error. If you include only the value, then the errors will be * set to zero. * * To reiterate, if you provide a DATA command with 2 names, e.g. "DATA 1st, 2nd", then every subsequent * line must contain 2*3 - 1 = 5 commas. If you give 3 names, then there must be 3*3 - 1 = 8 commas. * * Example * TITLE * Most Excellent Fake Data * * ABSTRACT * This data was collected over * many minutes of light work * that was required to make it up. * * COMMENTS * This data was generated using C++. * The file was formatted with Emacs. * * LABEL * Randomized Linear * Randomized Gaussian * Randomized Lorentzian * Run * * DATA line, gauss, lrntz, run * -1.966, -0.168, -0.106, 0.048, 0.002, 0.005, 0.184, 0.010, 0.017, 1001, , , run 1001 title * -1.895, -0.151, -0.128, 0.014, 0.001, 0.001, 0.259, 0.017, 0.015, 1002, , , run 1002 title * -1.836, -0.127, -0.184, 0.013, 0.001, 0.001, 0.202, 0.017, 0.020, 1003, , , run 1003 title * -1.739, -0.064, -0.166, 0.057, 0.003, 0.004, 0.237, 0.016, 0.018, 1004, , , run 1004 title * -1.601, -0.062, -0.147, 0.104, 0.008, 0.006, 0.271, 0.012, 0.025, 1005, , , run 1005 title * . . . . . . . . . * . . . . . . . . . * . . . . . . . . . * Alternatively, the data often utilizes the continuation character ('\') and is labelled like * DATA line, gauss, lrntz * linear = -1.966, -0.168, -0.106, \ * gaussn = 0.048, 0.002, 0.005, \ * lorntz = 0.184, 0.010, 0.017, \ * 1001,,, run 1001 title * linear = -1.895, -0.151, -0.128, \ * gaussn = 0.014, 0.001, 0.001, \ * lorntz = 0.259, 0.017, 0.015, | * 1002,,, run 1002 title * linear = -1.836, -0.127, -0.184, \ * gaussn = 0.013, 0.001, 0.001, \ * lorntz = 0.202, 0.017, 0.020, | * 1003,,, run 1003 title * . . . . * . . . . * . . . . * If there is a run line as in the above examples, it must be at the end of the data and given * in this just slight odd manner (do not blame me, I haven't invented this format ;-) ). * \endverbatim * *

WARNING:For the row like data representation (the top DATA representation shown) * it is essential that there are always at least one space inbetween commas (the reason is that * I am too lazy to write my own tokenizer), e.g. * * \verbatim * -1.966, -0.168, , 0.048, , , 0.184, 0.010, 0.017, 1001, , , run 1001 title * \endverbatim * *

which is ok, but * * \verbatim * -1.966, -0.168,, 0.048,,, 0.184, 0.010, 0.017, 1001,,, run 1001 title * \endverbatim * *

will not work! * *

Some db-files do have a '\-e' or '\e' label just between the DATA tag line and the real data. * This tag will just be ignored. */ bool PRunDataHandler::ReadDBFile() { bool success = true; // open file ifstream f; // open db-file f.open(fRunPathName.Data(), ifstream::in); if (!f.is_open()) { cerr << endl << "PRunDataHandler::ReadDBFile **ERROR** Couldn't open data file (" << fRunPathName.Data() << ") for reading, sorry ..."; cerr << endl; return false; } PRawRunData runData; runData.fDataNonMusr.fFromAscii = false; int lineNo = 0; int idx; int dbTag = -1; char instr[512]; TString line, workStr; double val; bool firstData = true; // needed as a switch to check in which format the data are given. bool labelledFormat = true; // flag showing if the data are given in row format, or as labelled format (see description above, default is labelled format) // variables needed to tokenize strings TString tstr; TObjString *ostr; TObjArray *tokens = 0; 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; // check for db specific tags workStr = line; workStr.Remove(TString::kLeading, ' '); // remove spaces from the begining if (workStr.BeginsWith("title", TString::kIgnoreCase)) { dbTag = 0; continue; } else if (workStr.BeginsWith("abstract", TString::kIgnoreCase)) { dbTag = 1; continue; } else if (workStr.BeginsWith("comments", TString::kIgnoreCase)) { dbTag = 2; continue; } else if (workStr.BeginsWith("label", TString::kIgnoreCase)) { dbTag = 3; continue; } else if (workStr.BeginsWith("data", TString::kIgnoreCase)) { dbTag = 4; // filter out all data tags tokens = workStr.Tokenize(" ,\t"); for (int i=1; iGetEntries(); i++) { ostr = dynamic_cast(tokens->At(i)); runData.fDataNonMusr.fDataTags.push_back(ostr->GetString()); } // clean up tokens if (tokens) { delete tokens; tokens = 0; } continue; } switch (dbTag) { case 0: // TITLE runData.fRunTitle = workStr; break; case 1: // ABSTRACT // nothing to be done for now break; case 2: // COMMENTS // nothing to be done for now break; case 3: // LABEL runData.fDataNonMusr.fLabels.push_back(workStr); break; case 4: // DATA // filter out potential start data tag if (workStr.BeginsWith("\\-e", TString::kIgnoreCase) || workStr.BeginsWith("\\e", TString::kIgnoreCase) || workStr.BeginsWith("/-e", TString::kIgnoreCase) || workStr.BeginsWith("/e", TString::kIgnoreCase)) { continue; } // check if first real data line if (firstData) { // check if data are given just as rows are as labelled columns (see description above) tokens = workStr.Tokenize(","); ostr = dynamic_cast(tokens->At(0)); if (!ostr->GetString().IsFloat()) { labelledFormat = true; } else { labelledFormat = false; } // clean up tokens if (tokens) { delete tokens; tokens = 0; } // prepare data vector for use PDoubleVector dummy; for (unsigned int i=0; i> " << workStr.Data(); cerr << endl << ">> found potential run data line without run data tag."; return false; } // split string in tokens tokens = workStr.Tokenize(","); // line has structure: runNo,,, runTitle ostr = dynamic_cast(tokens->At(0)); tstr = ostr->GetString(); if (!tstr.IsFloat()) { cerr << endl << "PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; cerr << endl << ">> " << workStr.Data(); cerr << endl << ">> Expected db-data line with structure: runNo,,, runTitle"; cerr << endl << ">> runNo = " << tstr.Data() << ", seems to be not a number."; delete tokens; return false; } val = tstr.Atof(); runData.fDataNonMusr.fData[idx].push_back(val); runData.fDataNonMusr.fErrData[idx].push_back(1.0); } else { // tag = data line // remove all possible spaces workStr.ReplaceAll(" ", ""); // split string in tokens tokens = workStr.Tokenize("=,"); // line has structure: tag = val,err1,err2, if (tokens->GetEntries() < 3) { cerr << endl << "PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; cerr << endl << ">> " << workStr.Data(); cerr << endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\"; delete tokens; return false; } ostr = dynamic_cast(tokens->At(0)); tstr = ostr->GetString(); idx = GetDataTagIndex(tstr, runData.fDataNonMusr.fDataTags); if (idx == -1) { cerr << endl << "PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; cerr << endl << ">> " << workStr.Data(); cerr << endl << ">> data tag error: " << tstr.Data() << " seems not present in the data tag list"; delete tokens; return false; } switch (tokens->GetEntries()) { case 3: // tag = val,,, ostr = dynamic_cast(tokens->At(1)); tstr = ostr->GetString(); if (!tstr.IsFloat()) { cerr << endl << "PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; cerr << endl << ">> " << workStr.Data(); cerr << endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\"; cerr << endl << ">> val = " << tstr.Data() << ", seems to be not a number."; delete tokens; return false; } val = tstr.Atof(); runData.fDataNonMusr.fData[idx].push_back(val); runData.fDataNonMusr.fErrData[idx].push_back(1.0); break; case 4: // tag = val,err,, case 5: // tag = val,err1,err2, // handle val ostr = dynamic_cast(tokens->At(1)); tstr = ostr->GetString(); if (!tstr.IsFloat()) { cerr << endl << "PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; cerr << endl << ">> " << workStr.Data(); cerr << endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\"; cerr << endl << ">> val = " << tstr.Data() << ", seems to be not a number."; delete tokens; return false; } val = tstr.Atof(); runData.fDataNonMusr.fData[idx].push_back(val); // handle err1 (err2 will be ignored for the time being) ostr = dynamic_cast(tokens->At(2)); tstr = ostr->GetString(); if (!tstr.IsFloat()) { cerr << endl << "PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; cerr << endl << ">> " << workStr.Data(); cerr << endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\"; cerr << endl << ">> err1 = " << tstr.Data() << ", seems to be not a number."; delete tokens; return false; } val = tstr.Atof(); runData.fDataNonMusr.fErrData[idx].push_back(val); break; default: cerr << endl << "PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; cerr << endl << ">> " << workStr.Data(); cerr << endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\"; delete tokens; return false; break; } } } else { // handle row formated data // split string in tokens tokens = workStr.Tokenize(","); // line has structure: val1, err11, err12, ..., valn, errn1, errn2, runNo, , , , runTitle if (tokens->GetEntries() != (int)(3*runData.fDataNonMusr.fDataTags.size()+1)) { cerr << endl << "PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; cerr << endl << ">> " << workStr.Data(); cerr << endl << ">> Expected db-data line with structure: val1, err11, err12, ..., valn, errn1, errn2, runNo, , , , runTitle"; cerr << endl << ">> found = " << tokens->GetEntries() << " tokens, however expected " << 3*runData.fDataNonMusr.fDataTags.size()+1; cerr << endl << ">> Perhaps there are commas without space inbetween, like 12.3,, 3.2,..."; delete tokens; return false; } // extract data int j=0; for (int i=0; iGetEntries()-1; i+=3) { // handle value ostr = dynamic_cast(tokens->At(i)); tstr = ostr->GetString(); if (!tstr.IsFloat()) { cerr << endl << "PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; cerr << endl << ">> " << workStr.Data(); cerr << endl << ">> Expected db-data line with structure: val1, err11, err12, ..., valn, errn1, errn2, runNo, , , , runTitle"; cerr << endl << ">> value=" << tstr.Data() << " seems not to be a number"; delete tokens; return false; } runData.fDataNonMusr.fData[j].push_back(tstr.Atof()); // handle 1st error if present (2nd will be ignored for now) ostr = dynamic_cast(tokens->At(i+1)); tstr = ostr->GetString(); if (tstr.IsWhitespace()) { runData.fDataNonMusr.fErrData[j].push_back(1.0); } else if (tstr.IsFloat()) { runData.fDataNonMusr.fErrData[j].push_back(tstr.Atof()); } else { cerr << endl << "PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; cerr << endl << ">> " << workStr.Data(); cerr << endl << ">> Expected db-data line with structure: val1, err11, err12, ..., valn, errn1, errn2, runNo, , , , runTitle"; cerr << endl << ">> error1=" << tstr.Data() << " seems not to be a number"; delete tokens; return false; } j++; } } break; default: break; } } f.close(); // check that the number of labels == the number of data tags if (runData.fDataNonMusr.fLabels.size() != runData.fDataNonMusr.fDataTags.size()) { cerr << endl << "PRunDataHandler::ReadDBFile **ERROR**"; cerr << endl << ">> number of LABELS found = " << runData.fDataNonMusr.fLabels.size(); cerr << endl << ">> number of Data tags found = " << runData.fDataNonMusr.fDataTags.size(); cerr << endl << ">> They have to be equal!!"; if (tokens) { delete tokens; tokens = 0; } return false; } // check if all vectors have the same size for (unsigned int i=1; i> label: " << runData.fDataNonMusr.fDataTags[i-1].Data() << ", number data elements = " << runData.fDataNonMusr.fData[i-1].size(); cerr << endl << ">> label: " << runData.fDataNonMusr.fDataTags[i].Data() << ", number data elements = " << runData.fDataNonMusr.fData[i].size(); cerr << endl << ">> They have to be equal!!"; success = false; break; } if (runData.fDataNonMusr.fErrData[i].size() != runData.fDataNonMusr.fErrData[i-1].size()) { cerr << endl << "PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo; cerr << endl << ">> label: " << runData.fDataNonMusr.fDataTags[i-1].Data() << ", number data elements = " << runData.fDataNonMusr.fData[i-1].size(); cerr << endl << ">> label: " << runData.fDataNonMusr.fDataTags[i].Data() << ", number error data elements = " << runData.fDataNonMusr.fErrData[i].size(); cerr << endl << ">> They have to be equal!!"; success = false; break; } } // clean up tokens if (tokens) { delete tokens; tokens = 0; } // keep run name runData.fRunName = fRunName; fData.push_back(runData); return success; } //-------------------------------------------------------------------------- // StripWhitespace (private) //-------------------------------------------------------------------------- /** *

Strip white spaces from a string. The hope is that future TString * implementations of ROOT will make this routine obsolate. * * \param str string to be stripped. It will be modified directly on success. * * return: true at success, otherwise false. */ bool PRunDataHandler::StripWhitespace(TString &str) { char *s = 0; char *subs = 0; int i; int start; int end; int size; size = (int)str.Length(); s = new char[size+1]; if (!s) return false; for (int i=0; i Check is a string consists only of white spaces, i.e. spaces and/or * ctrl-characters. * * \param str string to be checked * * return: true if string consist only of white spaces, otherwise false. */ bool PRunDataHandler::IsWhitespace(const char *str) { unsigned int i=0; while (isblank(str[i]) || iscntrl(str[i])) { if (str[i] == 0) break; i++; } if (i == strlen(str)) return true; else return false; } //-------------------------------------------------------------------------- // ToDouble (private) //-------------------------------------------------------------------------- /** *

Convert a string to a double. * * \param str string to be converted * \param ok true on success, otherwise false. * * return: returns the converted string, or 0.0 in case of ok==false */ double PRunDataHandler::ToDouble(TString &str, bool &ok) { char *s; double value; int size, status; ok = true; size = (int)str.Length(); s = new char[size+1]; if (!s) { ok = false; return 0.0; } // copy string; stupid way but it works for (int i=0; i Convert a string to an int. * * \param str string to be converted * \param ok true on success, otherwise false. * * return: returns the converted string, or 0 in case of ok==false */ int PRunDataHandler::ToInt(TString &str, bool &ok) { char *s; int value; int size, status; ok = true; size = (int)str.Length(); s = new char[size+1]; if (!s) { ok = false; return 0; } // copy string; stupid way but it works for (int i=0; i Checks is str is in a list of data tags * * \param str data tag string (see description of nonMusr db-data) * \param dataTags vector of all data tags * * return: if found returns the data tag index (from the dataTags vector), otherwise -1 */ int PRunDataHandler::GetDataTagIndex(TString &str, PStringVector &dataTags) { int result = -1; // check all the other possible data tags for (unsigned int i=0; i