diff --git a/src/classes/PMsrHandler.cpp b/src/classes/PMsrHandler.cpp index cafb2637..e851b315 100644 --- a/src/classes/PMsrHandler.cpp +++ b/src/classes/PMsrHandler.cpp @@ -3165,15 +3165,19 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) if (tokens->GetEntries() < 2) { error = true; } else { - PIntVector group; + PUIntVector group; str = iter->fLine; - if (ParseDetectorGrouping(str, group)) { + PStringNumberList *rl = new PStringNumberList(str.Data()); + string errorMsg(""); + if (rl->Parse(errorMsg, true)) { + group = rl->GetList(); for (UInt_t i=0; iGetEntries() < 2) { error = true; } else { - PIntVector group; + PUIntVector group; str = iter->fLine; - if (ParseDetectorGrouping(str, group)) { + PStringNumberList *rl = new PStringNumberList(str.Data()); + string errorMsg(""); + if (rl->Parse(errorMsg, true)) { + group = rl->GetList(); for (UInt_t i=0; ifLine.Contains("runs", TString::kIgnoreCase)) { // handle plot runs TComplex run; + PStringNumberList *rl; + string errorMsg; + PUIntVector runList; switch (param.fPlotType) { case -1: error = true; @@ -3900,31 +3911,21 @@ Bool_t PMsrHandler::HandlePlotEntry(PMsrLines &lines) case MSR_PLOT_ASYM: case MSR_PLOT_NON_MUSR: case MSR_PLOT_MU_MINUS: - tokens = iter1->fLine.Tokenize(" \t"); - if (!tokens) { + rl = new PStringNumberList(iter1->fLine.Data()); + if (!rl->Parse(errorMsg, true)) { cerr << endl << ">> PMsrHandler::HandlePlotEntry: **SEVERE ERROR** Couldn't tokenize PLOT in line " << iter1->fLineNo; + cerr << endl << ">> Error Message: " << errorMsg; cerr << endl << endl; return false; } - if (tokens->GetEntries() < 2) { // runs missing - error = true; - } else { - for (Int_t i=1; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); - if (str.IsDigit()) { - run = TComplex(str.Atoi(),-1.0); - param.fRuns.push_back(run); - } else { - error = true; - } - } + runList = rl->GetList(); + for (UInt_t i=0; i - * - * \param str forward/backward string to be decoded - * \param group decoded detector grouping vector - * - * return: true if parsing was successful, false otherwise. - */ -Bool_t PMsrHandler::ParseDetectorGrouping(TString str, PIntVector &group) -{ - TObjArray *tok=0, *tok1=0; - TObjString *ostr=0; - Int_t first=0, last=0; - - // change cn - cm to cn-cm. Will *NOT* handle cn - cm etc - str = str.ReplaceAll(" - ", "-"); - - group.clear(); - tok = str.Tokenize(" \t"); - - // check that there are indeed enough tokens - if (tok->GetEntries() < 2) { - delete tok; - return false; - } - - for (Int_t i=1; iGetEntries(); i++) { - ostr = dynamic_cast(tok->At(i)); - if (ostr->GetString().Contains("-")) { // hopefully a cn-cm token - tok1 = ostr->GetString().Tokenize("-"); - if (tok1->GetEntries() == 2) { - ostr = dynamic_cast(tok1->At(0)); - if (ostr->GetString().IsDigit()) { - first = ostr->GetString().Atoi(); - } else { - if (tok) delete tok; - if (tok1) delete tok1; - return false; - } - ostr = dynamic_cast(tok1->At(1)); - if (ostr->GetString().IsDigit()) { - last = ostr->GetString().Atoi(); - } else { - if (tok) delete tok; - if (tok1) delete tok1; - return false; - } - - if (last < first) { - if (tok) delete tok; - return false; - } - - for (Int_t i=first; i<=last; i++) - group.push_back(i); - } else { - if (tok) delete tok; - if (tok1) delete tok1; - return false; - } - } else { // hopefully a number - if (ostr->GetString().IsDigit()) { - group.push_back(ostr->GetString().Atoi()); - } else { - if (tok) delete tok; - return false; - } - } - } - - // clean up - if (tok) delete tok; - if (tok1) delete tok1; - - return true; -} - //-------------------------------------------------------------------------- // MakeDetectorGroupingString (private) //-------------------------------------------------------------------------- diff --git a/src/classes/PMusr.cpp b/src/classes/PMusr.cpp index ee618411..478db109 100644 --- a/src/classes/PMusr.cpp +++ b/src/classes/PMusr.cpp @@ -28,10 +28,12 @@ ***************************************************************************/ #include - #include using namespace std; +#include +using namespace boost; + #include "PMusr.h" //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -1741,3 +1743,167 @@ void PMsrRunBlock::SetMapGlobal(UInt_t idx, Int_t ival) // else do nothing at the moment return; } + +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ +// implementation PStringNumberList +//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + +//-------------------------------------------------------------------------- +// Parse (public) +//-------------------------------------------------------------------------- +/** + *

Helper class which parses list of numbers of the following 3 forms and its combination. + * (i) list of integers separted by spaces, e.g. 1 3 7 14 + * (ii) a range of integers of the form nS-nE, e.g. 13-27 which will generate 13, 14, 15, .., 26, 27 + * (iii) a sequence of integers of the form nS:nE:nStep, e.g. 10:20:2 which will generate 10, 12, 14, .., 18, 20 + * + * \param errorMsg error message + * \param ignoreFirstToken if true, the first parse token will be ignored + * + * @return true if parse has been successful, otherwise false + */ +bool PStringNumberList::Parse(string &errorMsg, bool ignoreFirstToken) +{ + bool result=true; + vector splitVec; + int ival; + + // before checking tokens, remove 'forbidden' " - " and " : " + StripSpaces(); + + // split string into space separated tokens + split(splitVec, fString, is_any_of(" "), token_compress_on); + + unsigned int start=0; + if (ignoreFirstToken) + start=1; + + for (unsigned int i=start; i subSplitVec; + // split potential nS-nE token + split(subSplitVec, splitVec[i], is_any_of("-"), token_compress_on); + + int start=-1, end=-1; + unsigned int count=0; + for (unsigned int j=0; j end) { + int swap = end; + cerr << "**WARNING** start=" << start << " > end=" << end << ", hence I will swap them" << endl; + end = start; + start = swap; + } + for (int j=start; j<=end; j++) + fList.push_back(j); + } + } else if (splitVec[i].find(":") != string::npos) { // check for potential sequence + vector subSplitVec; + // split potential rStart:rEnd:rStep token + split(subSplitVec, splitVec[i], is_any_of(":"), token_compress_on); + + int start=-1, end=-1, step=-1; + unsigned int count=0; + for (unsigned int j=0; j end) { + int swap = end; + cerr << "**WARNING** start=" << start << " > end=" << end << ", hence I will swap them" << endl; + end = start; + start = swap; + } + for (int j=start; j<=end; j+=step) + fList.push_back(j); + } + } else if (IsNumber(splitVec[i])) { + ival = atoi(splitVec[i].c_str()); + fList.push_back(ival); + } else { + errorMsg = "**ERROR** invalid token: " + splitVec[i]; + result = false; + } + } + } + + return result; +} + +//-------------------------------------------------------------------------- +// StripSpaces (private) +//-------------------------------------------------------------------------- +/** + *

This routine removes arbitray number of spaces between '-' and ':', + * e.g. 123 - 125 will be converted to 123-125, etc. + */ +void PStringNumberList::StripSpaces() +{ + string str=fString; + int pos=-1; + + // backward scan + for (int i=str.size(); i>=0; --i) { // check if first space is found + if ((str[i] == ' ') && (pos == -1)) { + pos = i; + } else if ((str[i] == '-') || (str[i] == ':')) { // check for '-' or ':' + if (pos != -1) { + str.erase(i+1, pos-i); + } + } else if (str[i] != ' ') { // anything but different than a space leads to a reset of the pos counter + pos = -1; + } + } + // forward scan + for (unsigned int i=0; iHelper class which parses list of numbers of the following 3 forms and its combination. + * (i) list of integers separted by spaces, e.g. 1 3 7 14 + * (ii) a range of integers of the form nS-nE, e.g. 13-27 which will generate 13, 14, 15, .., 26, 27 + * (iii) a sequence of integers of the form nS:nE:nStep, e.g. 10:20:2 which will generate 10, 12, 14, .., 18, 20 + */ +class PStringNumberList { + public: + PStringNumberList(char *str) { fString = str; } + PStringNumberList(string str) { fString = str; } + virtual ~PStringNumberList() { fList.clear(); } + + virtual bool Parse(string &errorMsg, bool ignoreFirstToken=false); + virtual PUIntVector GetList() { return fList; } + + private: + string fString; + bool fIsValid; + PUIntVector fList; + + virtual bool IsNumber(string &str) { return (str.find_first_not_of("0123456789") == string::npos); } + virtual void StripSpaces(); +}; + #endif // _PMUSR_H_ diff --git a/src/msr2data.cpp b/src/msr2data.cpp index ec2d43ba..58babb8b 100644 --- a/src/msr2data.cpp +++ b/src/msr2data.cpp @@ -37,6 +37,7 @@ #endif #include "git-revision.h" +#include "PMusr.h" #include "PMsr2Data.h" #include @@ -87,12 +88,17 @@ void msr2data_syntax() cout << endl << " [fit [-k] [-t] | fit-