diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b0a6d836..0fc2ef82 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -75,7 +75,11 @@ target_include_directories(msr2data ) target_link_libraries(msr2data ${ROOT_LIBRARIES} ${MUSRFIT_LIBS}) -add_executable(msr2msr msr2msr.cpp) +add_executable(msr2msr msr2msr.cpp classes/PStringUtils.cpp) +target_include_directories(msr2msr + BEFORE PRIVATE + $ +) target_link_libraries(msr2msr ${ROOT_LIBRARIES}) add_executable(musrfit musrfit.cpp) diff --git a/src/classes/CMakeLists.txt b/src/classes/CMakeLists.txt index 4ff45fa6..54954072 100644 --- a/src/classes/CMakeLists.txt +++ b/src/classes/CMakeLists.txt @@ -106,6 +106,7 @@ add_library(PMusr SHARED PMsgBoxDict.cxx PMsr2Data.cpp PMsrHandler.cpp + PStringUtils.cpp PMusrCanvas.cpp PMusrCanvasDict.cxx PMusr.cpp @@ -270,6 +271,7 @@ install( ${MUSRFIT_INC}/PRunSingleHisto.h ${MUSRFIT_INC}/PRunSingleHistoRRF.h ${MUSRFIT_INC}/PStartupHandler.h + ${MUSRFIT_INC}/PStringUtils.h ${MUSRFIT_INC}/PTheory.h ${MUSRFIT_INC}/PUserFcnBase.h DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} diff --git a/src/classes/PFitter.cpp b/src/classes/PFitter.cpp index a25e1d69..2d339433 100644 --- a/src/classes/PFitter.cpp +++ b/src/classes/PFitter.cpp @@ -64,10 +64,9 @@ #include #include #include -#include -#include #include "PFitter.h" +#include "PStringUtils.h" //+++ PSectorChisq class +++++++++++++++++++++++++++++++++++++++++++++++++++ @@ -397,8 +396,6 @@ void PFitter::GetPhaseParams() // default functions: // user functions cannot be checked! PMsrLines *theo = fRunInfo->GetMsrTheory(); - TObjArray *tok = nullptr; - TObjString *ostr = nullptr; TString str; int pos = -1; for (unsigned int i=0; isize(); i++) { @@ -423,18 +420,10 @@ void PFitter::GetPhaseParams() continue; // extract phase token - tok = line.Tokenize(" \t"); - if (tok == nullptr) { - std::cerr << "PFitter::GetPhaseParams(): **ERROR** couldn't tokenize theory line string." << std::endl; - return; + std::vector tok = PStringUtils::Split(line.Data(), " \t"); + if (static_cast(tok.size()) > pos) { + str = tok[pos].c_str(); } - if (tok->GetEntries() > pos) { - ostr = dynamic_cast(tok->At(pos)); - str = ostr->GetString(); - } - // clean up - delete tok; - tok = nullptr; // decode phase token. It can be funX, mapX, or a number if (str.Contains("fun")) { // function @@ -491,22 +480,15 @@ PIntVector PFitter::GetParFromFun(const TString funStr) PIntVector parVec; PMsrLines *funList = fRunInfo->GetMsrFunctions(); - TObjArray *tok = nullptr; - TObjString *ostr = nullptr; TString str; for (int i=0; isize(); i++) { if (funList->at(i).fLine.Contains(funStr)) { // tokenize function string - tok = funList->at(i).fLine.Tokenize(" =+-*/"); - if (tok == nullptr) { - std::cerr << "PFitter::GetParFromFun(): **ERROR** couldn't tokenize function string." << std::endl; - return parVec; - } + std::vector tok = PStringUtils::Split(funList->at(i).fLine.Data(), " =+-*/"); - for (int j=1; jGetEntries(); j++) { - ostr = dynamic_cast(tok->At(j)); - str = ostr->GetString(); + for (int j=1; j(tok.size()); j++) { + str = tok[j].c_str(); // parse tok for parX if (str.Contains("par")) { // find start idx of par in token @@ -533,10 +515,6 @@ PIntVector PFitter::GetParFromFun(const TString funStr) } } } - - // clean up - delete tok; - tok = nullptr; } } @@ -996,16 +974,14 @@ Bool_t PFitter::CheckCommands() cmd.second = cmdLineNo; fCmdList.push_back(cmd); // filter out possible parameters for scan - TObjArray *tokens = nullptr; - TObjString *ostr; + std::vector tokens; TString str; UInt_t ival; - tokens = line.Tokenize(", \t"); + tokens = PStringUtils::Split(line.Data(), ", \t"); - for (Int_t i=0; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); + for (Int_t i=0; i(tokens.size()); i++) { + str = tokens[i].c_str(); if ((i==1) || (i==2)) { // parX / parY // check that token is a UInt_t @@ -1016,10 +992,6 @@ Bool_t PFitter::CheckCommands() std::cerr << std::endl << ">> command syntax for CONTOURS is: CONTOURS parameter-X parameter-Y [# of points]"; std::cerr << std::endl; fIsValid = false; - if (tokens) { - delete tokens; - tokens = nullptr; - } break; } ival = str.Atoi(); @@ -1031,10 +1003,6 @@ Bool_t PFitter::CheckCommands() std::cerr << std::endl << ">> command syntax for CONTOURS is: CONTOURS parameter-X parameter-Y [# of points]"; std::cerr << std::endl; fIsValid = false; - if (tokens) { - delete tokens; - tokens = nullptr; - } break; } // keep parameter @@ -1051,10 +1019,6 @@ Bool_t PFitter::CheckCommands() std::cerr << std::endl << ">> command syntax for CONTOURS is: CONTOURS parameter-X parameter-Y [# of points]"; std::cerr << std::endl; fIsValid = false; - if (tokens) { - delete tokens; - tokens = nullptr; - } break; } ival = str.Atoi(); @@ -1065,20 +1029,12 @@ Bool_t PFitter::CheckCommands() std::cerr << std::endl << ">> command syntax for CONTOURS is: CONTOURS parameter-X parameter-Y [# of points]"; std::cerr << std::endl; fIsValid = false; - if (tokens) { - delete tokens; - tokens = nullptr; - } break; } fScanNoPoints = ival; } } - if (tokens) { - delete tokens; - tokens = nullptr; - } } else if (line.Contains("EIGEN", TString::kIgnoreCase)) { cmd.first = PMN_EIGEN; cmd.second = cmdLineNo; @@ -1090,15 +1046,13 @@ Bool_t PFitter::CheckCommands() // (iii) FIT_RANGE start1 end1 start2 end2 ... startN endN // (iv) FIT_RANGE fgb+n0 lgb-n1 // (v) FIT_RANGE fgb+n00 lgb-n01 fgb+n10 lgb-n11 ... fgb+nN0 lgb-nN1 - TObjArray *tokens = nullptr; - TObjString *ostr; + std::vector tokens; TString str; - tokens = line.Tokenize(", \t"); + tokens = PStringUtils::Split(line.Data(), ", \t"); - if (tokens->GetEntries() == 2) { // should only be RESET - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); + if (static_cast(tokens.size()) == 2) { // should only be RESET + str = tokens[1].c_str(); if (str.Contains("RESET", TString::kIgnoreCase)) { cmd.first = PMN_FIT_RANGE; cmd.second = cmdLineNo; @@ -1110,32 +1064,23 @@ Bool_t PFitter::CheckCommands() std::cerr << std::endl << ">> with N the number of runs in the msr-file." << std::endl; std::cerr << std::endl << ">> Found " << str.Data() << ", instead of RESET" << std::endl; fIsValid = false; - if (tokens) { - delete tokens; - tokens = nullptr; - } break; } - } else if ((tokens->GetEntries() > 1) && (static_cast(tokens->GetEntries()) % 2) == 1) { - if ((tokens->GetEntries() > 3) && ((static_cast(tokens->GetEntries())-1)) != 2*fRunInfo->GetMsrRunList()->size()) { + } else if ((static_cast(tokens.size()) > 1) && (static_cast(static_cast(tokens.size())) % 2) == 1) { + if ((static_cast(tokens.size()) > 3) && ((static_cast(static_cast(tokens.size()))-1)) != 2*fRunInfo->GetMsrRunList()->size()) { std::cerr << std::endl << ">> PFitter::CheckCommands: **ERROR** in line " << it->fLineNo; std::cerr << std::endl << ">> " << line.Data(); std::cerr << std::endl << ">> Syntax: FIT_RANGE RESET | FIT_RANGE | FIT_RANGE .. |"; std::cerr << std::endl << ">> FIT_RANGE fgb+ lgb- | FIT_RANGE fgb+ lgb- fgb+ lgb- ... fgb+ lgb-,"; std::cerr << std::endl << ">> with N the number of runs in the msr-file."; - std::cerr << std::endl << ">> Found N=" << (tokens->GetEntries()-1)/2 << ", # runs in msr-file=" << fRunInfo->GetMsrRunList()->size() << std::endl; + std::cerr << std::endl << ">> Found N=" << (static_cast(tokens.size())-1)/2 << ", # runs in msr-file=" << fRunInfo->GetMsrRunList()->size() << std::endl; fIsValid = false; - if (tokens) { - delete tokens; - tokens = nullptr; - } break; } else { // check that all range entries are numbers or fgb+n0 / lgb-n1 Bool_t ok = true; - for (Int_t n=1; nGetEntries(); n++) { - ostr = dynamic_cast(tokens->At(n)); - str = ostr->GetString(); + for (Int_t n=1; n(tokens.size()); n++) { + str = tokens[n].c_str(); if (!str.IsFloat()) { if ((n%2 == 1) && (!str.Contains("fgb", TString::kIgnoreCase))) ok = false; @@ -1158,10 +1103,6 @@ Bool_t PFitter::CheckCommands() std::cerr << std::endl << ">> with N the number of runs in the msr-file."; std::cerr << std::endl << ">> Found token '" << str.Data() << "', which is not a floating point number." << std::endl; fIsValid = false; - if (tokens) { - delete tokens; - tokens = nullptr; - } break; } } @@ -1172,29 +1113,19 @@ Bool_t PFitter::CheckCommands() std::cerr << std::endl << ">> FIT_RANGE fgb+ lgb- | FIT_RANGE fgb+ lgb- fgb+ lgb- ... fgb+ lgb-,"; std::cerr << std::endl << ">> with N the number of runs in the msr-file."; fIsValid = false; - if (tokens) { - delete tokens; - tokens = nullptr; - } break; } - if (tokens) { - delete tokens; - tokens = nullptr; - } } else if (line.Contains("FIX", TString::kIgnoreCase)) { // check if the given set of parameters (number or names) is present - TObjArray *tokens = nullptr; - TObjString *ostr; + std::vector tokens; TString str; UInt_t ival; - tokens = line.Tokenize(", \t"); + tokens = PStringUtils::Split(line.Data(), ", \t"); - for (Int_t i=1; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); + for (Int_t i=1; i(tokens.size()); i++) { + str = tokens[i].c_str(); if (str.IsDigit()) { // token might be a parameter number ival = str.Atoi(); @@ -1205,10 +1136,6 @@ Bool_t PFitter::CheckCommands() std::cerr << std::endl << ">> Parameter " << ival << " is out of the Parameter Range [1," << fParams.size() << "]"; std::cerr << std::endl; fIsValid = false; - if (tokens) { - delete tokens; - tokens = nullptr; - } break; } } else { // token might be a parameter name @@ -1226,19 +1153,11 @@ Bool_t PFitter::CheckCommands() std::cerr << std::endl << ">> Parameter '" << str.Data() << "' is NOT present as a parameter name"; std::cerr << std::endl; fIsValid = false; - if (tokens) { - delete tokens; - tokens = nullptr; - } break; } } } - if (tokens) { - delete tokens; - tokens = nullptr; - } // everything looks fine, feed the command list cmd.first = PMN_FIX; @@ -1278,16 +1197,14 @@ Bool_t PFitter::CheckCommands() fCmdList.push_back(cmd); } else if (line.Contains("RELEASE", TString::kIgnoreCase)) { // check if the given set of parameters (number or names) is present - TObjArray *tokens = nullptr; - TObjString *ostr; + std::vector tokens; TString str; UInt_t ival; - tokens = line.Tokenize(", \t"); + tokens = PStringUtils::Split(line.Data(), ", \t"); - for (Int_t i=1; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); + for (Int_t i=1; i(tokens.size()); i++) { + str = tokens[i].c_str(); if (str.IsDigit()) { // token might be a parameter number ival = str.Atoi(); @@ -1298,10 +1215,6 @@ Bool_t PFitter::CheckCommands() std::cerr << std::endl << ">> Parameter " << ival << " is out of the Parameter Range [1," << fParams.size() << "]"; std::cerr << std::endl; fIsValid = false; - if (tokens) { - delete tokens; - tokens = nullptr; - } break; } } else { // token might be a parameter name @@ -1319,19 +1232,11 @@ Bool_t PFitter::CheckCommands() std::cerr << std::endl << ">> Parameter '" << str.Data() << "' is NOT present as a parameter name"; std::cerr << std::endl; fIsValid = false; - if (tokens) { - delete tokens; - tokens = nullptr; - } break; } } } - if (tokens) { - delete tokens; - tokens = nullptr; - } cmd.first = PMN_RELEASE; cmd.second = cmdLineNo; fCmdList.push_back(cmd); @@ -1348,16 +1253,14 @@ Bool_t PFitter::CheckCommands() cmd.second = cmdLineNo; fCmdList.push_back(cmd); // filter out possible parameters for scan - TObjArray *tokens = nullptr; - TObjString *ostr; + std::vector tokens; TString str; UInt_t ival; - tokens = line.Tokenize(", \t"); + tokens = PStringUtils::Split(line.Data(), ", \t"); - for (Int_t i=0; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); + for (Int_t i=0; i(tokens.size()); i++) { + str = tokens[i].c_str(); if (i==1) { // get parameter number // check that token is a UInt_t if (!str.IsDigit()) { @@ -1367,10 +1270,6 @@ Bool_t PFitter::CheckCommands() std::cerr << std::endl << ">> command syntax for SCAN is: SCAN [parameter no [# of points [low high]]]"; std::cerr << std::endl; fIsValid = false; - if (tokens) { - delete tokens; - tokens = nullptr; - } break; } ival = str.Atoi(); @@ -1382,10 +1281,6 @@ Bool_t PFitter::CheckCommands() std::cerr << std::endl << ">> command syntax for SCAN is: SCAN [parameter no [# of points [low high]]]"; std::cerr << std::endl; fIsValid = false; - if (tokens) { - delete tokens; - tokens = nullptr; - } break; } // keep parameter @@ -1402,10 +1297,6 @@ Bool_t PFitter::CheckCommands() std::cerr << std::endl << ">> command syntax for SCAN is: SCAN [parameter no [# of points [low high]]]"; std::cerr << std::endl; fIsValid = false; - if (tokens) { - delete tokens; - tokens = nullptr; - } break; } ival = str.Atoi(); @@ -1416,10 +1307,6 @@ Bool_t PFitter::CheckCommands() std::cerr << std::endl << ">> command syntax for SCAN is: SCAN [parameter no [# of points [low high]]]"; std::cerr << std::endl; fIsValid = false; - if (tokens) { - delete tokens; - tokens = nullptr; - } break; } fScanNoPoints = ival; @@ -1434,10 +1321,6 @@ Bool_t PFitter::CheckCommands() std::cerr << std::endl << ">> command syntax for SCAN is: SCAN [parameter no [# of points [low high]]]"; std::cerr << std::endl; fIsValid = false; - if (tokens) { - delete tokens; - tokens = nullptr; - } break; } fScanLow = str.Atof(); @@ -1452,33 +1335,23 @@ Bool_t PFitter::CheckCommands() std::cerr << std::endl << ">> command syntax for SCAN is: SCAN [parameter no [# of points [low high]]]"; std::cerr << std::endl; fIsValid = false; - if (tokens) { - delete tokens; - tokens = nullptr; - } break; } fScanHigh = str.Atof(); } } - if (tokens) { - delete tokens; - tokens = nullptr; - } } else if (line.Contains("SIMPLEX", TString::kIgnoreCase)) { cmd.first = PMN_SIMPLEX; cmd.second = cmdLineNo; fCmdList.push_back(cmd); } else if (line.Contains("STRATEGY", TString::kIgnoreCase)) { - TObjArray *tokens = nullptr; - TObjString *ostr; + std::vector tokens; TString str; - tokens = line.Tokenize(" \t"); - if (tokens->GetEntries() == 2) { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); + tokens = PStringUtils::Split(line.Data(), " \t"); + if (static_cast(tokens.size()) == 2) { + str = tokens[1].c_str(); if (str.CompareTo("0") == 0) { // low fStrategy = 0; } else if (str.CompareTo("1") == 0) { // default @@ -1494,10 +1367,6 @@ Bool_t PFitter::CheckCommands() } } - if (tokens) { - delete tokens; - tokens = nullptr; - } } else if (line.Contains("USER_COVARIANCE", TString::kIgnoreCase)) { cmd.first = PMN_USER_COVARIANCE; cmd.second = cmdLineNo; @@ -1513,35 +1382,28 @@ Bool_t PFitter::CheckCommands() fCmdList.push_back(cmd); // check if the given sector arguments are valid time stamps, i.e. doubles and value < lgb time stamp - TObjArray *tokens = nullptr; - TObjString *ostr; + std::vector tokens; TString str; - tokens = line.Tokenize(" ,\t"); + tokens = PStringUtils::Split(line.Data(), " ,\t"); - if (tokens->GetEntries() == 1) { // no sector time stamps given -> issue an error + if (static_cast(tokens.size()) == 1) { // no sector time stamps given -> issue an error std::cerr << std::endl << ">> PFitter::CheckCommands(): **FATAL ERROR** in line " << it->fLineNo; std::cerr << std::endl << ">> " << line.Data(); std::cerr << std::endl << ">> At least one sector time stamp is expected."; std::cerr << std::endl << ">> Will stop ..."; std::cerr << std::endl; - // cleanup - if (tokens) { - delete tokens; - tokens = nullptr; - } fIsValid = false; fSectorFlag = false; break; } Double_t dval; - for (Int_t i=1; iGetEntries(); i++) { + for (Int_t i=1; i(tokens.size()); i++) { // keep time range of sector PSectorChisq sec(fRunInfo->GetNoOfRuns()); // get parse tokens - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); + str = tokens[i].c_str(); if (str.IsFloat()) { dval = str.Atof(); // check that the sector time stamp is smaller than all lgb time stamps @@ -1552,11 +1414,6 @@ Bool_t PFitter::CheckCommands() std::cerr << std::endl << ">> The sector time stamp " << dval << " is > as the lgb time stamp (" << fOriginalFitRange[j].second << ") of run " << j << "."; std::cerr << std::endl << ">> Will stop ..."; std::cerr << std::endl; - // cleanup - if (tokens) { - delete tokens; - tokens = nullptr; - } fIsValid = false; fSectorFlag = false; return fIsValid; @@ -1571,21 +1428,12 @@ Bool_t PFitter::CheckCommands() std::cerr << std::endl << ">> The sector time stamp '" << str << "' is not a number."; std::cerr << std::endl << ">> Will stop ..."; std::cerr << std::endl; - // cleanup - if (tokens) { - delete tokens; - tokens = nullptr; - } fIsValid = false; fSectorFlag = false; break; } } - if (tokens) { - delete tokens; - tokens = nullptr; - } } else { // unkown command std::cerr << std::endl << ">> PFitter::CheckCommands(): **FATAL ERROR** in line " << it->fLineNo << " an unkown command is found:"; std::cerr << std::endl << ">> " << line.Data(); @@ -1729,27 +1577,24 @@ Bool_t PFitter::ExecuteFitRange(UInt_t lineNo) return true; } - TObjArray *tokens = nullptr; - TObjString *ostr; + std::vector tokens; TString str; - tokens = fCmdLines[lineNo].fLine.Tokenize(", \t"); + tokens = PStringUtils::Split(fCmdLines[lineNo].fLine.Data(), ", \t"); PMsrRunList *runList = fRunInfo->GetMsrRunList(); // execute command, no error checking needed since this has been already carried out in CheckCommands() - if (tokens->GetEntries() == 2) { // reset command + if (static_cast(tokens.size()) == 2) { // reset command fRunListCollection->SetFitRange(fOriginalFitRange); - } else if (tokens->GetEntries() == 3) { // single fit range for all runs + } else if (static_cast(tokens.size()) == 3) { // single fit range for all runs Double_t start = 0.0, end = 0.0; PDoublePair fitRange; PDoublePairVector fitRangeVector; - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); + str = tokens[1].c_str(); start = str.Atof(); - ostr = dynamic_cast(tokens->At(2)); - str = ostr->GetString(); + str = tokens[2].c_str(); end = str.Atof(); fitRange.first = start; @@ -1763,11 +1608,9 @@ Bool_t PFitter::ExecuteFitRange(UInt_t lineNo) PDoublePairVector fitRangeVector; for (UInt_t i=0; isize(); i++) { - ostr = dynamic_cast(tokens->At(2*i+1)); - str = ostr->GetString(); + str = tokens[2*i+1].c_str(); start = str.Atof(); - ostr = dynamic_cast(tokens->At(2*i+2)); - str = ostr->GetString(); + str = tokens[2*i+2].c_str(); end = str.Atof(); fitRange.first = start; @@ -1795,15 +1638,13 @@ Bool_t PFitter::ExecuteFix(UInt_t lineNo) { std::cout << ">> PFitter::ExecuteFix(): " << fCmdLines[lineNo].fLine.Data() << std::endl; - TObjArray *tokens = nullptr; - TObjString *ostr; + std::vector tokens; TString str; - tokens = fCmdLines[lineNo].fLine.Tokenize(", \t"); + tokens = PStringUtils::Split(fCmdLines[lineNo].fLine.Data(), ", \t"); - for (Int_t i=1; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); + for (Int_t i=1; i(tokens.size()); i++) { + str = tokens[i].c_str(); if (str.IsDigit()) { // token is a parameter number fMnUserParams.Fix(static_cast(str.Atoi())-1); @@ -1812,11 +1653,6 @@ Bool_t PFitter::ExecuteFix(UInt_t lineNo) } } - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; - } return true; } @@ -2124,19 +1960,17 @@ Bool_t PFitter::ExecutePrintLevel(UInt_t lineNo) { std::cout << ">> PFitter::ExecutePrintLevel(): " << fCmdLines[lineNo].fLine.Data() << std::endl; - TObjArray *tokens = nullptr; - TObjString *ostr; + std::vector tokens; TString str; - tokens = fCmdLines[lineNo].fLine.Tokenize(", \t"); + tokens = PStringUtils::Split(fCmdLines[lineNo].fLine.Data(), ", \t"); - if (tokens->GetEntries() < 2) { + if (static_cast(tokens.size()) < 2) { std::cerr << std::endl << "**ERROR** from PFitter::ExecutePrintLevel(): SYNTAX: PRINT_LEVEL , where =0-3" << std::endl << std::endl; return false; } - ostr = (TObjString*)tokens->At(1); - str = ostr->GetString(); + str = tokens[1].c_str(); Int_t ival; if (str.IsDigit()) { @@ -2159,11 +1993,6 @@ Bool_t PFitter::ExecutePrintLevel(UInt_t lineNo) ROOT::Minuit2::MnPrint::SetLevel(fPrintLevel); #endif - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; - } return true; } @@ -2180,17 +2009,15 @@ Bool_t PFitter::ExecutePrintLevel(UInt_t lineNo) */ Bool_t PFitter::ExecuteRelease(UInt_t lineNo) { - TObjArray *tokens = nullptr; - TObjString *ostr; + std::vector tokens; TString str; - tokens = fCmdLines[lineNo].fLine.Tokenize(", \t"); + tokens = PStringUtils::Split(fCmdLines[lineNo].fLine.Data(), ", \t"); std::cout << ">> PFitter::ExecuteRelease(): " << fCmdLines[lineNo].fLine.Data() << std::endl; - for (Int_t i=1; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); + for (Int_t i=1; i(tokens.size()); i++) { + str = tokens[i].c_str(); if (str.IsDigit()) { // token is a parameter number fMnUserParams.Release(static_cast(str.Atoi())-1); @@ -2203,11 +2030,6 @@ Bool_t PFitter::ExecuteRelease(UInt_t lineNo) } } - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; - } return true; } diff --git a/src/classes/PMsrHandler.cpp b/src/classes/PMsrHandler.cpp index 8194546b..4c8b3cf3 100644 --- a/src/classes/PMsrHandler.cpp +++ b/src/classes/PMsrHandler.cpp @@ -30,16 +30,16 @@ #include #include +#include #include #include #include -#include -#include #include #include "PMusr.h" #include "PMsrHandler.h" +#include "PStringUtils.h" //-------------------------------------------------------------------------- // Constructor @@ -451,8 +451,6 @@ Int_t PMsrHandler::WriteMsrLogFile(const Bool_t messages) Int_t plotNo = -1; std::string line; TString logFileName, str, sstr, *pstr; - TObjArray *tokens = nullptr; - TObjString *ostr = nullptr; Bool_t found = false; Bool_t statisticBlockFound = false; Bool_t partialStatisticBlockFound = true; @@ -593,15 +591,13 @@ Int_t PMsrHandler::WriteMsrLogFile(const Bool_t messages) else fout << str.Data() << std::endl; break; - case MSR_TAG_FITPARAMETER: - tokens = str.Tokenize(" \t"); - if (tokens->GetEntries() == 0) { // not a parameter line + case MSR_TAG_FITPARAMETER: { + std::vector tokens = PStringUtils::Split(str.Data(), " \t"); + if (tokens.empty()) { // not a parameter line fout << str.Data() << std::endl; } else { - ostr = dynamic_cast(tokens->At(0)); - sstr = ostr->GetString(); - if (sstr.IsDigit()) { // parameter - number = sstr.Atoi(); + if (PStringUtils::IsInt(tokens[0])) { // parameter + number = PStringUtils::ToInt(tokens[0]); number--; // make sure number makes sense assert ((number >= 0) && (number < (Int_t)fParam.size())); @@ -670,10 +666,9 @@ Int_t PMsrHandler::WriteMsrLogFile(const Bool_t messages) } else { // not a parameter, hence just copy it fout << str.Data() << std::endl; } - // clean up tokens - delete tokens; } break; + } case MSR_TAG_THEORY: found = false; for (UInt_t i=0; i tokens; // fill param structure iter = lines.begin(); @@ -2865,99 +2858,72 @@ Bool_t PMsrHandler::HandleFitParameterEntry(PMsrLines &lines) param.fUpperBoundaryPresent = false; param.fUpperBoundary = 0.0; - tokens = iter->fLine.Tokenize(" \t"); - if (!tokens) { - fLastErrorMsg.str(""); - fLastErrorMsg.clear(); - fLastErrorMsg << ">> PMsrHandler::HandleFitParameterEntry: **SEVERE ERROR** Couldn't tokenize Parameters in line " << iter->fLineNo << "\n"; - std::cerr << fLastErrorMsg.str(); - return false; - } + tokens = PStringUtils::Split(iter->fLine.Data(), " \t"); // handle various input possiblities - if ((tokens->GetEntries() < 4) || (tokens->GetEntries() > 7) || (tokens->GetEntries() == 6)) { + if ((tokens.size() < 4) || (tokens.size() > 7) || (tokens.size() == 6)) { error = true; } else { // handle the first 4 parameter since they are always the same // parameter number - ostr = dynamic_cast(tokens->At(0)); - str = ostr->GetString(); - if (str.IsDigit()) - param.fNo = str.Atoi(); - else + bool ok = false; + param.fNo = PStringUtils::ToInt(tokens[0], &ok); + if (!ok) error = true; // parameter name - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - param.fName = str; + param.fName = tokens[1].c_str(); // parameter value - ostr = dynamic_cast(tokens->At(2)); - str = ostr->GetString(); - if (str.IsFloat()) - param.fValue = static_cast(str.Atof()); - else + param.fValue = PStringUtils::ToDouble(tokens[2], &ok); + if (!ok) error = true; - // parameter value - ostr = dynamic_cast(tokens->At(3)); - str = ostr->GetString(); - if (str.IsFloat()) - param.fStep = static_cast(str.Atof()); - else + // parameter step + param.fStep = PStringUtils::ToDouble(tokens[3], &ok); + if (!ok) error = true; // 4 values, i.e. No Name Value Step - if (tokens->GetEntries() == 4) { + if (tokens.size() == 4) { param.fNoOfParams = 4; } // 5 values, i.e. No Name Value Neg_Error Pos_Error - if (tokens->GetEntries() == 5) { + if (tokens.size() == 5) { param.fNoOfParams = 5; // positive error - ostr = dynamic_cast(tokens->At(4)); - str = ostr->GetString(); - if (str.IsFloat()) { + param.fPosError = PStringUtils::ToDouble(tokens[4], &ok); + if (ok) { param.fPosErrorPresent = true; - param.fPosError = static_cast(str.Atof()); + } else if (PStringUtils::IsEqualNoCase(tokens[4], "none")) { + param.fPosErrorPresent = false; } else { - str.ToLower(); - if (!str.CompareTo("none", TString::kIgnoreCase)) - param.fPosErrorPresent = false; - else - error = true; + error = true; } } // 7 values, i.e. No Name Value Neg_Error Pos_Error Lower_Boundary Upper_Boundary - if (tokens->GetEntries() == 7) { + if (tokens.size() == 7) { param.fNoOfParams = 7; // positive error - ostr = dynamic_cast(tokens->At(4)); - str = ostr->GetString(); - if (str.IsFloat()) { + param.fPosError = PStringUtils::ToDouble(tokens[4], &ok); + if (ok) { param.fPosErrorPresent = true; - param.fPosError = static_cast(str.Atof()); + } else if (PStringUtils::IsEqualNoCase(tokens[4], "none")) { + param.fPosErrorPresent = false; } else { - str.ToLower(); - if (!str.CompareTo("none", TString::kIgnoreCase)) - param.fPosErrorPresent = false; - else - error = true; + error = true; } // lower boundary - ostr = dynamic_cast(tokens->At(5)); - str = ostr->GetString(); // check if lower boundary is "none", i.e. upper boundary limited only - if (!str.CompareTo("none", TString::kIgnoreCase)) { // none + if (PStringUtils::IsEqualNoCase(tokens[5], "none")) { // none param.fLowerBoundaryPresent = false; } else { // assuming that the lower boundary is a number - if (str.IsFloat()) { - param.fLowerBoundary = static_cast(str.Atof()); + param.fLowerBoundary = PStringUtils::ToDouble(tokens[5], &ok); + if (ok) { param.fLowerBoundaryPresent = true; } else { error = true; @@ -2965,14 +2931,12 @@ Bool_t PMsrHandler::HandleFitParameterEntry(PMsrLines &lines) } // upper boundary - ostr = dynamic_cast(tokens->At(6)); - str = ostr->GetString(); // check if upper boundary is "none", i.e. lower boundary limited only - if (!str.CompareTo("none", TString::kIgnoreCase)) { // none + if (PStringUtils::IsEqualNoCase(tokens[6], "none")) { // none param.fUpperBoundaryPresent = false; } else { // assuming a number - if (str.IsFloat()) { - param.fUpperBoundary = static_cast(str.Atof()); + param.fUpperBoundary = PStringUtils::ToDouble(tokens[6], &ok); + if (ok) { param.fUpperBoundaryPresent = true; } else { error = true; @@ -3012,12 +2976,6 @@ Bool_t PMsrHandler::HandleFitParameterEntry(PMsrLines &lines) fParam.push_back(param); } - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; - } - iter++; } @@ -3122,8 +3080,7 @@ Bool_t PMsrHandler::HandleGlobalEntry(PMsrLines &lines) Bool_t error = false; TString str; - TObjArray *tokens = nullptr; - TObjString *ostr = nullptr; + std::vector tokens; Int_t ival = 0; Double_t dval = 0.0; UInt_t addT0Counter = 0; @@ -3140,157 +3097,116 @@ Bool_t PMsrHandler::HandleGlobalEntry(PMsrLines &lines) str.Remove(idx); // tokenize line - tokens = str.Tokenize(" \t"); - if (!tokens) { - fLastErrorMsg.str(""); - fLastErrorMsg.clear(); - fLastErrorMsg << ">> PMsrHandler::HandleGlobalEntry: **SEVERE ERROR** Couldn't tokenize line " << iter->fLineNo << "\n\n"; - std::cerr << fLastErrorMsg.str(); - return false; - } + tokens = PStringUtils::Split(str.Data(), " \t"); if (iter->fLine.BeginsWith("fittype", TString::kIgnoreCase)) { // fittype - if (tokens->GetEntries() < 2) { + if (tokens.size() < 2) { error = true; } else { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (str.IsDigit()) { - Int_t fittype = str.Atoi(); - if ((fittype == MSR_FITTYPE_SINGLE_HISTO) || - (fittype == MSR_FITTYPE_SINGLE_HISTO_RRF) || - (fittype == MSR_FITTYPE_ASYM) || - (fittype == MSR_FITTYPE_ASYM_RRF) || - (fittype == MSR_FITTYPE_MU_MINUS) || - (fittype == MSR_FITTYPE_BNMR) || - (fittype == MSR_FITTYPE_NON_MUSR)) { - global.SetFitType(fittype); - } else { - error = true; - } + bool ok = false; + Int_t fittype = PStringUtils::ToInt(tokens[1], &ok); + if (ok && ((fittype == MSR_FITTYPE_SINGLE_HISTO) || + (fittype == MSR_FITTYPE_SINGLE_HISTO_RRF) || + (fittype == MSR_FITTYPE_ASYM) || + (fittype == MSR_FITTYPE_ASYM_RRF) || + (fittype == MSR_FITTYPE_MU_MINUS) || + (fittype == MSR_FITTYPE_BNMR) || + (fittype == MSR_FITTYPE_NON_MUSR))) { + global.SetFitType(fittype); } else { error = true; } } } else if (iter->fLine.BeginsWith("rrf_freq", TString::kIgnoreCase)) { - if (tokens->GetEntries() < 3) { + if (tokens.size() < 3) { error = true; } else { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (str.IsFloat()) { - dval = str.Atof(); - if (dval <= 0.0) - error = true; - } + bool ok = false; + dval = PStringUtils::ToDouble(tokens[1], &ok); + if (!ok || dval <= 0.0) + error = true; if (!error) { - ostr = dynamic_cast(tokens->At(2)); - str = ostr->GetString(); - global.SetRRFFreq(dval, str.Data()); - if (global.GetRRFFreq(str.Data()) == RRF_FREQ_UNDEF) + global.SetRRFFreq(dval, tokens[2].c_str()); + if (global.GetRRFFreq(tokens[2].c_str()) == RRF_FREQ_UNDEF) error = true; } } } else if (iter->fLine.BeginsWith("rrf_packing", TString::kIgnoreCase)) { - if (tokens->GetEntries() < 2) { + if (tokens.size() < 2) { error = true; } else { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (str.IsDigit()) { - ival = str.Atoi(); - if (ival > 0) { - global.SetRRFPacking(ival); - } else { - error = true; - } + bool ok = false; + ival = PStringUtils::ToInt(tokens[1], &ok); + if (ok && ival > 0) { + global.SetRRFPacking(ival); } else { error = true; } } } else if (iter->fLine.BeginsWith("rrf_phase", TString::kIgnoreCase)) { - if (tokens->GetEntries() < 2) { + if (tokens.size() < 2) { error = true; } else { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (str.IsFloat()) { - dval = str.Atof(); + bool ok = false; + dval = PStringUtils::ToDouble(tokens[1], &ok); + if (ok) global.SetRRFPhase(dval); - } else { + else error = true; - } } } else if (iter->fLine.BeginsWith("data", TString::kIgnoreCase)) { // data - if (tokens->GetEntries() < 3) { + if (tokens.size() < 3) { error = true; } else { - for (Int_t i=1; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); - if (str.IsDigit()) { - ival = str.Atoi(); - if (ival >= 0) { - global.SetDataRange(ival, i-1); - } else { - error = true; - } + for (UInt_t i=1; i= 0) { + global.SetDataRange(ival, i-1); } else { error = true; } } } } else if (iter->fLine.BeginsWith("t0", TString::kIgnoreCase)) { // t0 - if (tokens->GetEntries() < 2) { + if (tokens.size() < 2) { error = true; } else { - for (Int_t i=1; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); - if (str.IsFloat()) { - dval = str.Atof(); - if (dval >= 0.0) - global.SetT0Bin(dval); - else - error = true; - } else { + for (UInt_t i=1; i= 0.0) + global.SetT0Bin(dval); + else error = true; - } } } } else if (iter->fLine.BeginsWith("addt0", TString::kIgnoreCase)) { // addt0 - if (tokens->GetEntries() < 2) { + if (tokens.size() < 2) { error = true; } else { - for (Int_t i=1; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); - if (str.IsFloat()) { - dval = str.Atof(); - if (dval >= 0.0) - global.SetAddT0Bin(dval, addT0Counter, i-1); - else - error = true; - } else { + for (UInt_t i=1; i= 0.0) + global.SetAddT0Bin(dval, addT0Counter, i-1); + else error = true; - } } } addT0Counter++; } else if (iter->fLine.BeginsWith("fit", TString::kIgnoreCase)) { // fit range - if (tokens->GetEntries() < 3) { + if (tokens.size() < 3) { error = true; } else { // fit given in time, i.e. fit , where , are given as doubles if (iter->fLine.Contains("fgb", TString::kIgnoreCase)) { // fit given in bins, i.e. fit fgb+n0 lgb-n1 // check 1st entry, i.e. fgb[+n0] - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - Ssiz_t idx = str.First("+"); - TString numStr = str; - if (idx > -1) { // '+' present hence extract n0 - numStr.Remove(0,idx+1); - if (numStr.IsFloat()) { - global.SetFitRangeOffset(numStr.Atoi(), 0); + std::string numStr = tokens[1]; + std::string::size_type pos = numStr.find('+'); + if (pos != std::string::npos) { // '+' present hence extract n0 + numStr = numStr.substr(pos+1); + if (PStringUtils::IsFloat(numStr)) { + global.SetFitRangeOffset(PStringUtils::ToInt(numStr), 0); } else { error = true; } @@ -3298,14 +3214,12 @@ Bool_t PMsrHandler::HandleGlobalEntry(PMsrLines &lines) global.SetFitRangeOffset(0, 0); } // check 2nd entry, i.e. lgb[-n1] - ostr = dynamic_cast(tokens->At(2)); - str = ostr->GetString(); - idx = str.First("-"); - numStr = str; - if (idx > -1) { // '-' present hence extract n1 - numStr.Remove(0,idx+1); - if (numStr.IsFloat()) { - global.SetFitRangeOffset(numStr.Atoi(), 1); + numStr = tokens[2]; + pos = numStr.find('-'); + if (pos != std::string::npos) { // '-' present hence extract n1 + numStr = numStr.substr(pos+1); + if (PStringUtils::IsFloat(numStr)) { + global.SetFitRangeOffset(PStringUtils::ToInt(numStr), 1); } else { error = true; } @@ -3315,55 +3229,42 @@ Bool_t PMsrHandler::HandleGlobalEntry(PMsrLines &lines) if (!error) global.SetFitRangeInBins(true); } else { // fit given in time, i.e. fit , where , are given as doubles - for (Int_t i=1; i<3; i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); - if (str.IsFloat()) - global.SetFitRange(str.Atof(), i-1); + for (UInt_t i=1; i<3; i++) { + bool ok = false; + const double range = PStringUtils::ToDouble(tokens[i], &ok); + if (ok) + global.SetFitRange(range, i-1); else error = true; } } } } else if (iter->fLine.BeginsWith("packing", TString::kIgnoreCase)) { // packing - if (tokens->GetEntries() < 2) { + if (tokens.size() < 2) { error = true; } else { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (str.IsDigit()) { - ival = str.Atoi(); - if (ival >= 0) { - global.SetPacking(ival); - } else { - error = true; - } + bool ok = false; + ival = PStringUtils::ToInt(tokens[1], &ok); + if (ok && ival >= 0) { + global.SetPacking(ival); } else { error = true; } } } else if (iter->fLine.BeginsWith("deadtime-cor", TString::kIgnoreCase)) { // deadtime correction - if (tokens->GetEntries() < 2) { + if (tokens.size() < 2) { error = true; } else { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (!str.CompareTo("no", TString::kIgnoreCase) || - !str.CompareTo("file", TString::kIgnoreCase) || - !str.CompareTo("estimate", TString::kIgnoreCase)) { - global.SetDeadTimeCorrection(str); + if (PStringUtils::IsEqualNoCase(tokens[1], "no") || + PStringUtils::IsEqualNoCase(tokens[1], "file") || + PStringUtils::IsEqualNoCase(tokens[1], "estimate")) { + global.SetDeadTimeCorrection(tokens[1].c_str()); } else { error = true; } } } - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; - } - ++iter; } @@ -3403,8 +3304,7 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) Bool_t runLinePresent = false; TString str, line; - TObjArray *tokens = nullptr; - TObjString *ostr = nullptr; + std::vector tokens; UInt_t addT0Counter = 0; @@ -3423,14 +3323,7 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) str.Remove(idx); // tokenize line - tokens = str.Tokenize(" \t"); - if (!tokens) { - fLastErrorMsg.str(""); - fLastErrorMsg.clear(); - fLastErrorMsg << ">> PMsrHandler::HandleRunEntry: **SEVERE ERROR** Couldn't tokenize Parameters in line " << iter->fLineNo << "\n\n"; - std::cerr << fLastErrorMsg.str(); - return false; - } + tokens = PStringUtils::Split(str.Data(), " \t"); // copy of the current line line = iter->fLine; @@ -3451,29 +3344,26 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) // get run name, beamline, institute, and file-format // the path/filename could potentially contain spaces! Hence the run name needs to be reconstructed from the parsing - if (tokens->GetEntries() < 5) { + if (tokens.size() < 5) { error = true; } else { // run name - str = TString(""); - for (Int_t i=1; iGetEntries()-3; i++) { - ostr = dynamic_cast(tokens->At(i)); - str += ostr->GetString(); - if (iGetEntries()-4) - str += TString(" "); + std::string runName(""); + for (UInt_t i=1; i(tokens->At(tokens->GetEntries()-3)); - str = ostr->GetString(); + str = tokens[tokens.size()-3].c_str(); param.SetBeamline(str); // institute - ostr = dynamic_cast(tokens->At(tokens->GetEntries()-2)); - str = ostr->GetString(); + str = tokens[tokens.size()-2].c_str(); param.SetInstitute(str); // data file format - ostr = dynamic_cast(tokens->At(tokens->GetEntries()-1)); - str = ostr->GetString(); + str = tokens[tokens.size()-1].c_str(); param.SetFileFormat(str); } @@ -3495,24 +3385,20 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) } // get run name, beamline, institute, and file-format - if (tokens->GetEntries() < 5) { + if (tokens.size() < 5) { error = true; } else { // run name - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); + str = tokens[1].c_str(); param.SetRunName(str); // beamline - ostr = dynamic_cast(tokens->At(2)); - str = ostr->GetString(); + str = tokens[2].c_str(); param.SetBeamline(str); // institute - ostr = dynamic_cast(tokens->At(3)); - str = ostr->GetString(); + str = tokens[3].c_str(); param.SetInstitute(str); // data file format - ostr = dynamic_cast(tokens->At(4)); - str = ostr->GetString(); + str = tokens[4].c_str(); param.SetFileFormat(str); } } @@ -3522,24 +3408,19 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following - if (tokens->GetEntries() < 2) { + if (tokens.size() < 2) { error = true; } else { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (str.IsDigit()) { - Int_t fittype = str.Atoi(); - if ((fittype == MSR_FITTYPE_SINGLE_HISTO) || - (fittype == MSR_FITTYPE_SINGLE_HISTO_RRF) || - (fittype == MSR_FITTYPE_ASYM) || - (fittype == MSR_FITTYPE_ASYM_RRF) || - (fittype == MSR_FITTYPE_MU_MINUS) || - (fittype == MSR_FITTYPE_BNMR) || - (fittype == MSR_FITTYPE_NON_MUSR)) { - param.SetFitType(fittype); - } else { - error = true; - } + bool ok = false; + Int_t fittype = PStringUtils::ToInt(tokens[1], &ok); + if (ok && ((fittype == MSR_FITTYPE_SINGLE_HISTO) || + (fittype == MSR_FITTYPE_SINGLE_HISTO_RRF) || + (fittype == MSR_FITTYPE_ASYM) || + (fittype == MSR_FITTYPE_ASYM_RRF) || + (fittype == MSR_FITTYPE_MU_MINUS) || + (fittype == MSR_FITTYPE_BNMR) || + (fittype == MSR_FITTYPE_NON_MUSR))) { + param.SetFitType(fittype); } else { error = true; } @@ -3551,20 +3432,19 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following - if (tokens->GetEntries() < 2) { + if (tokens.size() < 2) { error = true; } else { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (str.IsDigit()) { - ival = str.Atoi(); + bool ok = false; + ival = PStringUtils::ToInt(tokens[1], &ok); + if (ok) { if (ival > 0) param.SetAlphaParamNo(ival); else error = true; - } else if (str.Contains("fun")) { + } else if (tokens[1].find("fun") != std::string::npos) { Int_t no; - if (FilterNumber(str, "fun", MSR_PARAM_FUN_OFFSET, no)) + if (FilterNumber(tokens[1].c_str(), "fun", MSR_PARAM_FUN_OFFSET, no)) param.SetAlphaParamNo(no); else error = true; @@ -3579,20 +3459,19 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following - if (tokens->GetEntries() < 2) { + if (tokens.size() < 2) { error = true; } else { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (str.IsDigit()) { - ival = str.Atoi(); + bool ok = false; + ival = PStringUtils::ToInt(tokens[1], &ok); + if (ok) { if (ival > 0) param.SetBetaParamNo(ival); else - error = true; - } else if (str.Contains("fun")) { + error = true; + } else if (tokens[1].find("fun") != std::string::npos) { Int_t no; - if (FilterNumber(str, "fun", MSR_PARAM_FUN_OFFSET, no)) + if (FilterNumber(tokens[1].c_str(), "fun", MSR_PARAM_FUN_OFFSET, no)) param.SetBetaParamNo(no); else error = true; @@ -3607,16 +3486,16 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following - if (tokens->GetEntries() < 2) { + if (tokens.size() < 2) { error = true; } else { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (str.IsDigit()) { - param.SetNormParamNo(str.Atoi()); - } else if (str.Contains("fun")) { + bool ok = false; + ival = PStringUtils::ToInt(tokens[1], &ok); + if (ok) { + param.SetNormParamNo(ival); + } else if (tokens[1].find("fun") != std::string::npos) { Int_t no; - if (FilterNumber(str, "fun", MSR_PARAM_FUN_OFFSET, no)) + if (FilterNumber(tokens[1].c_str(), "fun", MSR_PARAM_FUN_OFFSET, no)) param.SetNormParamNo(no); else error = true; @@ -3631,20 +3510,15 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following - if (tokens->GetEntries() < 2) { + if (tokens.size() < 2) { error = true; } else { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (str.IsDigit()) { - ival = str.Atoi(); - if (ival > 0) - param.SetBkgFitParamNo(ival); - else - error = true; - } else { + bool ok = false; + ival = PStringUtils::ToInt(tokens[1], &ok); + if (ok && ival > 0) + param.SetBkgFitParamNo(ival); + else error = true; - } } } @@ -3653,20 +3527,15 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following - if (tokens->GetEntries() < 2) { + if (tokens.size() < 2) { error = true; } else { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (str.IsDigit()) { - ival = str.Atoi(); - if (ival > 0) - param.SetLifetimeParamNo(ival); - else - error = true; - } else { + bool ok = false; + ival = PStringUtils::ToInt(tokens[1], &ok); + if (ok && ival > 0) + param.SetLifetimeParamNo(ival); + else error = true; - } } } @@ -3683,18 +3552,13 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following - for (Int_t i=1; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); - if (str.IsDigit()) { - ival = str.Atoi(); - if (ival >= 0) - param.SetMap(ival); - else - error = true; - } else { + for (UInt_t i=1; i= 0) + param.SetMap(ival); + else error = true; - } } // check map entries, i.e. if the map values are within parameter bounds if (!fFourierOnly) { @@ -3716,7 +3580,7 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following - if (tokens->GetEntries() < 2) { + if (tokens.size() < 2) { error = true; } else { PUIntVector group; @@ -3740,7 +3604,7 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following - if (tokens->GetEntries() < 2) { + if (tokens.size() < 2) { error = true; } else { PUIntVector group; @@ -3764,14 +3628,14 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following - if (tokens->GetEntries() < 2) { + if (tokens.size() < 2) { error = true; } else { - for (Int_t i=1; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); - if (str.IsFloat()) - param.SetBkgFix(str.Atof(), i-1); + for (UInt_t i=1; iGetEntries() < 3) || (tokens->GetEntries() % 2 != 1)) { // odd number (>=3) of entries needed + if ((tokens.size() < 3) || (tokens.size() % 2 != 1)) { // odd number (>=3) of entries needed error = true; } else { - for (Int_t i=1; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); - if (str.IsDigit()) { - ival = str.Atoi(); - if (ival > 0) - param.SetBkgRange(ival, i-1); - else - error = true; - } else { + for (UInt_t i=1; i 0) + param.SetBkgRange(ival, i-1); + else error = true; - } } } } @@ -3807,21 +3666,16 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following - if ((tokens->GetEntries() < 3) || (tokens->GetEntries() % 2 != 1)) { // odd number (>=3) of entries needed + if ((tokens.size() < 3) || (tokens.size() % 2 != 1)) { // odd number (>=3) of entries needed error = true; } else { - for (Int_t i=1; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); - if (str.IsDigit()) { - ival = str.Atoi(); - if (ival > 0) - param.SetDataRange(ival, i-1); - else - error = true; - } else { + for (UInt_t i=1; i 0) + param.SetDataRange(ival, i-1); + else error = true; - } } } } @@ -3831,21 +3685,16 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following - if (tokens->GetEntries() < 2) { + if (tokens.size() < 2) { error = true; } else { - for (Int_t i=1; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); - if (str.IsFloat()) { - dval = str.Atof(); - if (dval >= 0.0) - param.SetT0Bin(dval); - else - error = true; - } else { + for (UInt_t i=1; i= 0.0) + param.SetT0Bin(dval); + else error = true; - } } } } @@ -3855,21 +3704,16 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following - if (tokens->GetEntries() < 2) { + if (tokens.size() < 2) { error = true; } else { - for (Int_t i=1; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); - if (str.IsFloat()) { - dval = str.Atof(); - if (dval >= 0.0) - param.SetAddT0Bin(dval, addT0Counter, i-1); - else - error = true; - } else { + for (UInt_t i=1; i= 0.0) + param.SetAddT0Bin(dval, addT0Counter, i-1); + else error = true; - } } } @@ -3881,19 +3725,17 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following - if (tokens->GetEntries() < 3) { + if (tokens.size() < 3) { error = true; } else { if (iter->fLine.Contains("fgb", TString::kIgnoreCase)) { // fit given in bins, i.e. fit fgb+n0 lgb-n1 // check 1st entry, i.e. fgb[+n0] - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - Ssiz_t idx = str.First("+"); - TString numStr = str; - if (idx > -1) { // '+' present hence extract n0 - numStr.Remove(0,idx+1); - if (numStr.IsFloat()) { - param.SetFitRangeOffset(numStr.Atoi(), 0); + std::string numStr = tokens[1]; + std::string::size_type pos = numStr.find('+'); + if (pos != std::string::npos) { // '+' present hence extract n0 + numStr = numStr.substr(pos+1); + if (PStringUtils::IsFloat(numStr)) { + param.SetFitRangeOffset(PStringUtils::ToInt(numStr), 0); } else { error = true; } @@ -3901,14 +3743,12 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) param.SetFitRangeOffset(0, 0); } // check 2nd entry, i.e. lgb[-n1] - ostr = dynamic_cast(tokens->At(2)); - str = ostr->GetString(); - idx = str.First("-"); - numStr = str; - if (idx > -1) { // '-' present hence extract n1 - numStr.Remove(0,idx+1); - if (numStr.IsFloat()) { - param.SetFitRangeOffset(numStr.Atoi(), 1); + numStr = tokens[2]; + pos = numStr.find('-'); + if (pos != std::string::npos) { // '-' present hence extract n1 + numStr = numStr.substr(pos+1); + if (PStringUtils::IsFloat(numStr)) { + param.SetFitRangeOffset(PStringUtils::ToInt(numStr), 1); } else { error = true; } @@ -3919,11 +3759,11 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) if (!error) param.SetFitRangeInBins(true); } else { // fit given in time, i.e. fit , where , are given as doubles - for (Int_t i=1; i<3; i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); - if (str.IsFloat()) - param.SetFitRange(str.Atof(), i-1); + for (UInt_t i=1; i<3; i++) { + bool ok = false; + const double range = PStringUtils::ToDouble(tokens[i], &ok); + if (ok) + param.SetFitRange(range, i-1); else error = true; } @@ -3936,20 +3776,15 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following - if (tokens->GetEntries() != 2) { + if (tokens.size() != 2) { error = true; } else { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (str.IsDigit()) { - ival = str.Atoi(); - if (ival > 0) - param.SetPacking(ival); - else - error = true; - } else { + bool ok = false; + ival = PStringUtils::ToInt(tokens[1], &ok); + if (ok && ival > 0) + param.SetPacking(ival); + else error = true; - } } } @@ -3958,15 +3793,13 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following - if (tokens->GetEntries() < 2) { + if (tokens.size() < 2) { error = true; } else { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (!str.CompareTo("no", TString::kIgnoreCase) || - !str.CompareTo("file", TString::kIgnoreCase) || - !str.CompareTo("estimate", TString::kIgnoreCase)) { - param.SetDeadTimeCorrection(str); + if (PStringUtils::IsEqualNoCase(tokens[1], "no") || + PStringUtils::IsEqualNoCase(tokens[1], "file") || + PStringUtils::IsEqualNoCase(tokens[1], "estimate")) { + param.SetDeadTimeCorrection(tokens[1].c_str()); } else { error = true; } @@ -3979,17 +3812,13 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) runLinePresent = false; // this is needed to make sure that a run line is present before and ADDRUN is following - if (tokens->GetEntries() != 3) { // xy-data x-label y-label + if (tokens.size() != 3) { // xy-data x-label y-label error = true; } else { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (str.IsDigit()) { // xy-data indices given - param.SetXDataIndex(str.Atoi()); // x-index - ostr = dynamic_cast(tokens->At(2)); - str = ostr->GetString(); - if (str.IsDigit()) { - ival = str.Atoi(); + if (PStringUtils::IsInt(tokens[1])) { // xy-data indices given + param.SetXDataIndex(PStringUtils::ToInt(tokens[1])); // x-index + if (PStringUtils::IsInt(tokens[2])) { + ival = PStringUtils::ToInt(tokens[2]); if (ival > 0) param.SetYDataIndex(ival); // y-index else @@ -3998,20 +3827,14 @@ Bool_t PMsrHandler::HandleRunEntry(PMsrLines &lines) error = true; } } else { // xy-data labels given + str = tokens[1].c_str(); param.SetXDataLabel(str); // x-label - ostr = dynamic_cast(tokens->At(2)); - str = ostr->GetString(); + str = tokens[2].c_str(); param.SetYDataLabel(str); // y-label } } } - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; - } - ++iter; } @@ -4173,34 +3996,25 @@ Bool_t PMsrHandler::ParseFourierPhaseValueVector(PMsrFourierStructure &fourier, { Bool_t result = true; - TObjArray *tok = str.Tokenize(" ,;\t"); - if (tok == nullptr) { - fLastErrorMsg.str(""); - fLastErrorMsg.clear(); - fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseValueVector: **ERROR** couldn't tokenize Fourier phase line.\n\n"; - std::cerr << fLastErrorMsg.str(); - return false; - } + std::vector tok = PStringUtils::Split(str.Data(), " ,;\t"); // make sure there are enough tokens - if (tok->GetEntries() < 2) { + if (tok.size() < 2) { error = true; return false; } // convert all acceptable tokens - TObjString *ostr = nullptr; - TString sstr(""); - for (Int_t i=1; iGetEntries(); i++) { - ostr = dynamic_cast(tok->At(i)); - sstr = ostr->GetString(); - if (sstr.IsFloat()) { - fourier.fPhase.push_back(sstr.Atof()); + for (UInt_t i=1; i1) { // make sure that no 'phase val, parX' mixture is present fLastErrorMsg.str(""); - fLastErrorMsg.clear(); + fLastErrorMsg.clear(); fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseValueVector: **ERROR** in Fourier phase line.\n"; fLastErrorMsg << ">> Attempt to mix val, parX? This is currently not supported.\n\n"; std::cerr << fLastErrorMsg.str(); @@ -4210,11 +4024,6 @@ Bool_t PMsrHandler::ParseFourierPhaseValueVector(PMsrFourierStructure &fourier, } } - // clean up - if (tok) { - delete tok; - } - return result; } @@ -4239,42 +4048,32 @@ Bool_t PMsrHandler::ParseFourierPhaseParVector(PMsrFourierStructure &fourier, co Bool_t result = true; Int_t refCount = 0; - TObjArray *tok = str.Tokenize(" ,;\t"); - if (tok == nullptr) { - fLastErrorMsg.str(""); - fLastErrorMsg.clear(); - fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseParVector: **ERROR** couldn't tokenize Fourier phase line.\n\n"; - std::cerr << fLastErrorMsg.str(); - return false; - } + std::vector tok = PStringUtils::Split(str.Data(), " ,;\t"); // make sure there are enough tokens - if (tok->GetEntries() < 2) { + if (tok.size() < 2) { error = true; return false; } // check that all tokens start with par - TString sstr; - for (Int_t i=1; iGetEntries(); i++) { - TObjString *ostr = dynamic_cast(tok->At(i)); - sstr = ostr->GetString(); - if (!sstr.BeginsWith("par")) { + for (UInt_t i=1; i> PMsrHandler::ParseFourierPhaseParVector: **ERROR** found unhandable token '" << sstr << "'\n"; + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseParVector: **ERROR** found unhandable token '" << tok[i] << "'\n"; std::cerr << fLastErrorMsg.str(); error = true; result = false; break; } - if (sstr.BeginsWith("parR")) { + if (tok[i].rfind("parR", 0) == 0) { refCount++; } // rule out par(X, offset, #Param) syntax - if (sstr.BeginsWith("par(")) { + if (tok[i].rfind("par(", 0) == 0) { result = false; break; } @@ -4282,7 +4081,7 @@ Bool_t PMsrHandler::ParseFourierPhaseParVector(PMsrFourierStructure &fourier, co if (refCount > 1) { fLastErrorMsg.str(""); - fLastErrorMsg.clear(); + fLastErrorMsg.clear(); fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseParVector: **ERROR** found multiple parR's! Only one reference phase is accepted.\n"; std::cerr << fLastErrorMsg.str(); result = false; @@ -4291,22 +4090,23 @@ Bool_t PMsrHandler::ParseFourierPhaseParVector(PMsrFourierStructure &fourier, co // check that token has the form parX, where X is an int Int_t rmNoOf = 3; if (result != false) { - for (Int_t i=1; iGetEntries(); i++) { - TObjString *ostr = dynamic_cast(tok->At(i)); - sstr = ostr->GetString(); + for (UInt_t i=1; i> PMsrHandler::ParseFourierPhaseParVector: **ERROR** found token '" << ostr->GetString() << "' which is not parX with X an integer.\n"; + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseParVector: **ERROR** found token '" << tok[i] << "' which is not parX with X an integer.\n"; std::cerr << fLastErrorMsg.str(); fourier.fPhaseParamNo.clear(); error = true; @@ -4315,17 +4115,12 @@ Bool_t PMsrHandler::ParseFourierPhaseParVector(PMsrFourierStructure &fourier, co } } - if (fourier.fPhaseParamNo.size() == tok->GetEntries()-1) { // everything as expected + if (fourier.fPhaseParamNo.size() == tok.size()-1) { // everything as expected result = true; } else { result = false; } - // clean up - if (tok) { - delete tok; - } - return result; } @@ -4376,71 +4171,51 @@ Bool_t PMsrHandler::ParseFourierPhaseParIterVector(PMsrFourierStructure &fourier wstr.Remove(idx, wstr.Length()-idx); // tokenize rest which should have the form 'X0, offset, #Param' - TObjArray *tok = wstr.Tokenize(",;"); - if (tok == nullptr) { - fLastErrorMsg.str(""); - fLastErrorMsg.clear(); - fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseParIterVector: **ERROR** tokenize failed.\n"; - std::cerr << fLastErrorMsg.str(); - error = true; - return false; - } + std::vector tok = PStringUtils::Split(wstr.Data(), ",;"); // check for proper number of expected elements - if (tok->GetEntries() != 3) { + if (tok.size() != 3) { fLastErrorMsg.str(""); - fLastErrorMsg.clear(); + fLastErrorMsg.clear(); fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseParIterVector: **ERROR** wrong syntax for the expected par(X0, offset, #param).\n"; std::cerr << fLastErrorMsg.str(); error = true; - delete tok; return false; } Int_t x0, offset, noParam; // get X0 - TObjString *ostr = dynamic_cast(tok->At(0)); - wstr = ostr->GetString(); - if (wstr.IsDigit()) { - x0 = wstr.Atoi(); - } else { + bool ok = false; + x0 = PStringUtils::ToInt(tok[0], &ok); + if (!ok) { fLastErrorMsg.str(""); - fLastErrorMsg.clear(); - fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseParIterVector: **ERROR** X0='" << wstr << "' is not an integer.\n"; + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseParIterVector: **ERROR** X0='" << tok[0] << "' is not an integer.\n"; std::cerr << fLastErrorMsg.str(); error = true; - delete tok; return false; } // get offset - ostr = dynamic_cast(tok->At(1)); - wstr = ostr->GetString(); - if (wstr.IsDigit()) { - offset = wstr.Atoi(); - } else { + offset = PStringUtils::ToInt(tok[1], &ok); + if (!ok) { fLastErrorMsg.str(""); - fLastErrorMsg.clear(); - fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseParIterVector: **ERROR** offset='" << wstr << "' is not an integer.\n"; + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseParIterVector: **ERROR** offset='" << tok[1] << "' is not an integer.\n"; std::cerr << fLastErrorMsg.str(); error = true; - delete tok; return false; } // get noParam - ostr = dynamic_cast(tok->At(2)); - wstr = ostr->GetString(); - if (wstr.IsDigit()) { - noParam = wstr.Atoi(); - } else { + noParam = PStringUtils::ToInt(tok[2], &ok); + if (!ok) { fLastErrorMsg.str(""); - fLastErrorMsg.clear(); - fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseParIterVector: **ERROR** #Param='" << wstr << "' is not an integer.\n"; + fLastErrorMsg.clear(); + fLastErrorMsg << ">> PMsrHandler::ParseFourierPhaseParIterVector: **ERROR** #Param='" << tok[2] << "' is not an integer.\n"; std::cerr << fLastErrorMsg.str(); error = true; - delete tok; return false; } @@ -4453,11 +4228,6 @@ Bool_t PMsrHandler::ParseFourierPhaseParIterVector(PMsrFourierStructure &fourier for (Int_t i=0; i tokens; + TString pcStr=TString(""); Int_t ival; iter = lines.begin(); while ((iter != lines.end()) && !error) { // tokenize line - tokens = iter->fLine.Tokenize(" \t"); - if (!tokens) { - fLastErrorMsg.str(""); - fLastErrorMsg.clear(); - fLastErrorMsg << ">> PMsrHandler::HandleFourierEntry: **SEVERE ERROR** Couldn't tokenize Parameters in line " << iter->fLineNo << "\n\n"; - std::cerr << fLastErrorMsg.str(); - return false; - } + tokens = PStringUtils::Split(iter->fLine.Data(), " \t"); if (iter->fLine.BeginsWith("units", TString::kIgnoreCase)) { // units - if (tokens->GetEntries() < 2) { // units are missing + if (tokens.size() < 2) { // units are missing error = true; continue; } else { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (!str.CompareTo("gauss", TString::kIgnoreCase)) { + if (PStringUtils::IsEqualNoCase(tokens[1], "gauss")) { fourier.fUnits = FOURIER_UNIT_GAUSS; - } else if (!str.CompareTo("tesla", TString::kIgnoreCase)) { + } else if (PStringUtils::IsEqualNoCase(tokens[1], "tesla")) { fourier.fUnits = FOURIER_UNIT_TESLA; - } else if (!str.CompareTo("mhz", TString::kIgnoreCase)) { + } else if (PStringUtils::IsEqualNoCase(tokens[1], "mhz")) { fourier.fUnits = FOURIER_UNIT_FREQ; - } else if (!str.CompareTo("mc/s", TString::kIgnoreCase)) { + } else if (PStringUtils::IsEqualNoCase(tokens[1], "mc/s")) { fourier.fUnits = FOURIER_UNIT_CYCLES; } else { error = true; @@ -4527,35 +4287,27 @@ Bool_t PMsrHandler::HandleFourierEntry(PMsrLines &lines) } } } else if (iter->fLine.BeginsWith("fourier_power", TString::kIgnoreCase)) { // fourier power (zero padding) - if (tokens->GetEntries() < 2) { // fourier power exponent is missing + if (tokens.size() < 2) { // fourier power exponent is missing error = true; continue; } else { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (str.IsDigit()) { - ival = str.Atoi(); - if ((ival >= 0) && (ival <= 20)) { - fourier.fFourierPower = ival; - } else { // fourier power out of range - error = true; - continue; - } - } else { // fourier power not a number + bool ok = false; + ival = PStringUtils::ToInt(tokens[1], &ok); + if (ok && (ival >= 0) && (ival <= 20)) { + fourier.fFourierPower = ival; + } else { // fourier power not a number or out of range error = true; continue; } } } else if (iter->fLine.BeginsWith("dc-corrected", TString::kIgnoreCase)) { // dc-corrected - if (tokens->GetEntries() < 2) { // dc-corrected tag is missing + if (tokens.size() < 2) { // dc-corrected tag is missing error = true; continue; } else { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (!str.CompareTo("true", TString::kIgnoreCase) || !str.CompareTo("1")) { + if (PStringUtils::IsEqualNoCase(tokens[1], "true") || (tokens[1] == "1")) { fourier.fDCCorrected = true; - } else if (!str.CompareTo("false", TString::kIgnoreCase) || !str.CompareTo("0")) { + } else if (PStringUtils::IsEqualNoCase(tokens[1], "false") || (tokens[1] == "0")) { fourier.fDCCorrected = false; } else { // unrecognized dc-corrected tag error = true; @@ -4563,19 +4315,17 @@ Bool_t PMsrHandler::HandleFourierEntry(PMsrLines &lines) } } } else if (iter->fLine.BeginsWith("apodization", TString::kIgnoreCase)) { // apodization - if (tokens->GetEntries() < 2) { // apodization tag is missing + if (tokens.size() < 2) { // apodization tag is missing error = true; continue; } else { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (!str.CompareTo("none", TString::kIgnoreCase)) { + if (PStringUtils::IsEqualNoCase(tokens[1], "none")) { fourier.fApodization = FOURIER_APOD_NONE; - } else if (!str.CompareTo("weak", TString::kIgnoreCase)) { + } else if (PStringUtils::IsEqualNoCase(tokens[1], "weak")) { fourier.fApodization = FOURIER_APOD_WEAK; - } else if (!str.CompareTo("medium", TString::kIgnoreCase)) { + } else if (PStringUtils::IsEqualNoCase(tokens[1], "medium")) { fourier.fApodization = FOURIER_APOD_MEDIUM; - } else if (!str.CompareTo("strong", TString::kIgnoreCase)) { + } else if (PStringUtils::IsEqualNoCase(tokens[1], "strong")) { fourier.fApodization = FOURIER_APOD_STRONG; } else { // unrecognized apodization tag error = true; @@ -4583,23 +4333,21 @@ Bool_t PMsrHandler::HandleFourierEntry(PMsrLines &lines) } } } else if (iter->fLine.BeginsWith("plot", TString::kIgnoreCase)) { // plot tag - if (tokens->GetEntries() < 2) { // plot tag is missing + if (tokens.size() < 2) { // plot tag is missing error = true; continue; } else { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (!str.CompareTo("real", TString::kIgnoreCase)) { + if (PStringUtils::IsEqualNoCase(tokens[1], "real")) { fourier.fPlotTag = FOURIER_PLOT_REAL; - } else if (!str.CompareTo("imag", TString::kIgnoreCase)) { + } else if (PStringUtils::IsEqualNoCase(tokens[1], "imag")) { fourier.fPlotTag = FOURIER_PLOT_IMAG; - } else if (!str.CompareTo("real_and_imag", TString::kIgnoreCase)) { + } else if (PStringUtils::IsEqualNoCase(tokens[1], "real_and_imag")) { fourier.fPlotTag = FOURIER_PLOT_REAL_AND_IMAG; - } else if (!str.CompareTo("power", TString::kIgnoreCase)) { + } else if (PStringUtils::IsEqualNoCase(tokens[1], "power")) { fourier.fPlotTag = FOURIER_PLOT_POWER; - } else if (!str.CompareTo("phase", TString::kIgnoreCase)) { + } else if (PStringUtils::IsEqualNoCase(tokens[1], "phase")) { fourier.fPlotTag = FOURIER_PLOT_PHASE; - } else if (!str.CompareTo("phase_opt_real", TString::kIgnoreCase)) { + } else if (PStringUtils::IsEqualNoCase(tokens[1], "phase_opt_real")) { fourier.fPlotTag = FOURIER_PLOT_PHASE_OPT_REAL; } else { // unrecognized plot tag error = true; @@ -4607,7 +4355,7 @@ Bool_t PMsrHandler::HandleFourierEntry(PMsrLines &lines) } } } else if (iter->fLine.BeginsWith("phase", TString::kIgnoreCase)) { // phase - if (tokens->GetEntries() < 2) { // phase value(s)/par(s) is(are) missing + if (tokens.size() < 2) { // phase value(s)/par(s) is(are) missing error = true; continue; } else { @@ -4678,16 +4426,14 @@ Bool_t PMsrHandler::HandleFourierEntry(PMsrLines &lines) // available at this point. pcStr = iter->fLine; } else if (iter->fLine.BeginsWith("range", TString::kIgnoreCase)) { // fourier plot range - if (tokens->GetEntries() < 3) { // plot range values are missing + if (tokens.size() < 3) { // plot range values are missing error = true; continue; } else { for (UInt_t i=0; i<2; i++) { - ostr = dynamic_cast(tokens->At(i+1)); - str = ostr->GetString(); - if (str.IsFloat()) { - fourier.fPlotRange[i] = str.Atof(); - } else { + bool ok = false; + fourier.fPlotRange[i] = PStringUtils::ToDouble(tokens[i+1], &ok); + if (!ok) { error = true; continue; } @@ -4699,31 +4445,17 @@ Bool_t PMsrHandler::HandleFourierEntry(PMsrLines &lines) continue; } - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; - } - ++iter; } - // clean up after error - if (tokens) { - delete tokens; - tokens = nullptr; - } - // handle range_for_phase_correction if present if ((pcStr.Length() != 0) && !error) { // tokenize line - tokens = pcStr.Tokenize(" \t"); + tokens = PStringUtils::Split(pcStr.Data(), " \t"); - switch (tokens->GetEntries()) { + switch (tokens.size()) { case 2: - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (!str.CompareTo("all", TString::kIgnoreCase)) { + if (PStringUtils::IsEqualNoCase(tokens[1], "all")) { fourier.fRangeForPhaseCorrection[0] = fourier.fPlotRange[0]; fourier.fRangeForPhaseCorrection[1] = fourier.fPlotRange[1]; } else { @@ -4732,25 +4464,16 @@ Bool_t PMsrHandler::HandleFourierEntry(PMsrLines &lines) break; case 3: for (UInt_t i=0; i<2; i++) { - ostr = dynamic_cast(tokens->At(i+1)); - str = ostr->GetString(); - if (str.IsFloat()) { - fourier.fRangeForPhaseCorrection[i] = str.Atof(); - } else { + bool ok = false; + fourier.fRangeForPhaseCorrection[i] = PStringUtils::ToDouble(tokens[i+1], &ok); + if (!ok) error = true; - } } break; default: error = true; break; } - - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; - } } if (error) { @@ -4803,9 +4526,7 @@ Bool_t PMsrHandler::HandlePlotEntry(PMsrLines &lines) PMsrLines::iterator iter1; PMsrLines::iterator iter2; - TObjArray *tokens = nullptr; - TObjString *ostr = nullptr; - TString str; + std::vector tokens; if (lines.empty()) { std::cerr << std::endl << ">> PMsrHandler::HandlePlotEntry(): **WARNING**: There is no PLOT block! Do you really want this?"; @@ -4848,29 +4569,15 @@ Bool_t PMsrHandler::HandlePlotEntry(PMsrLines &lines) line.Resize(line.First('#')); if (line.Contains("PLOT")) { // handle plot header - tokens = line.Tokenize(" \t"); - if (!tokens) { - fLastErrorMsg.str(""); - fLastErrorMsg.clear(); - fLastErrorMsg << ">> PMsrHandler::HandlePlotEntry: **SEVERE ERROR** Couldn't tokenize PLOT in line " << iter1->fLineNo << "\n\n"; - std::cerr << fLastErrorMsg.str(); - return false; - } - if (tokens->GetEntries() < 2) { // plot type missing + tokens = PStringUtils::Split(line.Data(), " \t"); + if (tokens.size() < 2) { // plot type missing error = true; } else { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (str.IsDigit()) - param.fPlotType = str.Atoi(); - else + bool ok = false; + param.fPlotType = PStringUtils::ToInt(tokens[1], &ok); + if (!ok) error = true; } - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; - } } else if (line.Contains("lifetimecorrection", TString::kIgnoreCase)) { param.fLifeTimeCorrection = true; } else if (line.Contains("runs", TString::kIgnoreCase)) { // handle plot runs @@ -4917,56 +4624,43 @@ Bool_t PMsrHandler::HandlePlotEntry(PMsrLines &lines) param.fYmin.clear(); param.fYmax.clear(); - tokens = line.Tokenize(" \t"); - if (!tokens) { - std::cerr << std::endl << ">> PMsrHandler::HandlePlotEntry: **SEVERE ERROR** Couldn't tokenize PLOT in line " << iter1->fLineNo; - std::cerr << std::endl << std::endl; - return false; - } - if ((tokens->GetEntries() != 3) && (tokens->GetEntries() != 5)) { + tokens = PStringUtils::Split(line.Data(), " \t"); + if ((tokens.size() != 3) && (tokens.size() != 5)) { error = true; } else { // handle t_min - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (str.IsFloat()) - param.fTmin.push_back(static_cast(str.Atof())); + bool ok = false; + const double tmin = PStringUtils::ToDouble(tokens[1], &ok); + if (ok) + param.fTmin.push_back(tmin); else error = true; // handle t_max - ostr = dynamic_cast(tokens->At(2)); - str = ostr->GetString(); - if (str.IsFloat()) - param.fTmax.push_back(static_cast(str.Atof())); + const double tmax = PStringUtils::ToDouble(tokens[2], &ok); + if (ok) + param.fTmax.push_back(tmax); else error = true; - if (tokens->GetEntries() == 5) { // y-axis interval given as well + if (tokens.size() == 5) { // y-axis interval given as well // handle y_min - ostr = dynamic_cast(tokens->At(3)); - str = ostr->GetString(); - if (str.IsFloat()) - param.fYmin.push_back(static_cast(str.Atof())); + const double ymin = PStringUtils::ToDouble(tokens[3], &ok); + if (ok) + param.fYmin.push_back(ymin); else error = true; // handle y_max - ostr = dynamic_cast(tokens->At(4)); - str = ostr->GetString(); - if (str.IsFloat()) - param.fYmax.push_back(static_cast(str.Atof())); + const double ymax = PStringUtils::ToDouble(tokens[4], &ok); + if (ok) + param.fYmax.push_back(ymax); else error = true; } } - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; - } } else if (line.Contains("sub_ranges", TString::kIgnoreCase)) { // remove previous entries param.fTmin.clear(); @@ -4974,102 +4668,77 @@ Bool_t PMsrHandler::HandlePlotEntry(PMsrLines &lines) param.fYmin.clear(); param.fYmax.clear(); - tokens = line.Tokenize(" \t"); - if (!tokens) { - std::cerr << std::endl << ">> PMsrHandler::HandlePlotEntry: **SEVERE ERROR** Couldn't tokenize PLOT in line " << iter1->fLineNo; - std::cerr << std::endl << std::endl; - return false; - } - if ((tokens->GetEntries() != static_cast(2*param.fRuns.size() + 1)) && (tokens->GetEntries() != static_cast(2*param.fRuns.size() + 3))) { + tokens = PStringUtils::Split(line.Data(), " \t"); + if ((tokens.size() != 2*param.fRuns.size() + 1) && (tokens.size() != 2*param.fRuns.size() + 3)) { error = true; } else { // get all the times for (UInt_t i=0; i(tokens->At(2*i+1)); - str = ostr->GetString(); - if (str.IsFloat()) - param.fTmin.push_back(static_cast(str.Atof())); + bool ok = false; + const double tmin = PStringUtils::ToDouble(tokens[2*i+1], &ok); + if (ok) + param.fTmin.push_back(tmin); else error = true; // handle t_max - ostr = dynamic_cast(tokens->At(2*i+2)); - str = ostr->GetString(); - if (str.IsFloat()) - param.fTmax.push_back(static_cast(str.Atof())); + const double tmax = PStringUtils::ToDouble(tokens[2*i+2], &ok); + if (ok) + param.fTmax.push_back(tmax); else error = true; } // get y-range if present - if (tokens->GetEntries() == static_cast(2*param.fRuns.size() + 3)) { + if (tokens.size() == 2*param.fRuns.size() + 3) { // handle y_min - ostr = dynamic_cast(tokens->At(2*param.fRuns.size()+1)); - str = ostr->GetString(); - if (str.IsFloat()) - param.fYmin.push_back(static_cast(str.Atof())); + bool ok = false; + const double ymin = PStringUtils::ToDouble(tokens[2*param.fRuns.size()+1], &ok); + if (ok) + param.fYmin.push_back(ymin); else error = true; // handle y_max - ostr = dynamic_cast(tokens->At(2*param.fRuns.size()+2)); - str = ostr->GetString(); - if (str.IsFloat()) - param.fYmax.push_back(static_cast(str.Atof())); + const double ymax = PStringUtils::ToDouble(tokens[2*param.fRuns.size()+2], &ok); + if (ok) + param.fYmax.push_back(ymax); else error = true; } } - - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; - } } else if (line.Contains("use_fit_ranges", TString::kIgnoreCase)) { param.fUseFitRanges = true; // check if y-ranges are given - tokens = line.Tokenize(" \t"); - if (!tokens) { - std::cerr << std::endl << ">> PMsrHandler::HandlePlotEntry: **SEVERE ERROR** Couldn't tokenize PLOT in line " << iter1->fLineNo; - std::cerr << std::endl << std::endl; - return false; - } + tokens = PStringUtils::Split(line.Data(), " \t"); - if (tokens->GetEntries() == 3) { // i.e. use_fit_ranges ymin ymax + if (tokens.size() == 3) { // i.e. use_fit_ranges ymin ymax // handle y_min - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (str.IsFloat()) - param.fYmin.push_back(static_cast(str.Atof())); + bool ok = false; + const double ymin = PStringUtils::ToDouble(tokens[1], &ok); + if (ok) + param.fYmin.push_back(ymin); else error = true; // handle y_max - ostr = dynamic_cast(tokens->At(2)); - str = ostr->GetString(); - if (str.IsFloat()) - param.fYmax.push_back(static_cast(str.Atof())); + const double ymax = PStringUtils::ToDouble(tokens[2], &ok); + if (ok) + param.fYmax.push_back(ymax); else error = true; } - if ((tokens->GetEntries() != 1) && (tokens->GetEntries() != 3)) { + if ((tokens.size() != 1) && (tokens.size() != 3)) { std::cerr << std::endl << ">> PMsrHandler::HandlePlotEntry: **WARNING** use_fit_ranges with undefined additional parameters in line " << iter1->fLineNo; std::cerr << std::endl << ">> Will ignore this PLOT block command line, sorry."; std::cerr << std::endl << ">> Proper syntax: use_fit_ranges [ymin ymax]"; std::cerr << std::endl << ">> Found: '" << iter1->fLine.Data() << "'" << std::endl; } - - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; - } } else if (iter1->fLine.Contains("logx", TString::kIgnoreCase)) { param.fLogX = true; } else if (iter1->fLine.Contains("logy", TString::kIgnoreCase)) { @@ -5077,139 +4746,83 @@ Bool_t PMsrHandler::HandlePlotEntry(PMsrLines &lines) } else if (iter1->fLine.Contains("lifetimecorrection", TString::kIgnoreCase)) { param.fLifeTimeCorrection = true; } else if (iter1->fLine.Contains("view_packing", TString::kIgnoreCase)) { - tokens = iter1->fLine.Tokenize(" \t"); - if (!tokens) { - std::cerr << std::endl << ">> PMsrHandler::HandlePlotEntry: **SEVERE ERROR** Couldn't tokenize view_packing in line " << iter1->fLineNo; - std::cerr << std::endl << std::endl; - return false; - } - if (tokens->GetEntries() != 2) { + tokens = PStringUtils::Split(iter1->fLine.Data(), " \t"); + if (tokens.size() != 2) { error = true; } else { - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (str.IsDigit()) { - Int_t val = str.Atoi(); - if (val > 0) - param.fViewPacking = val; - else - error = true; - } else { + bool ok = false; + Int_t val = PStringUtils::ToInt(tokens[1], &ok); + if (ok && val > 0) + param.fViewPacking = val; + else error = true; - } - } - - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; } } else if (iter1->fLine.Contains("rrf_freq", TString::kIgnoreCase)) { // expected entry: rrf_freq value unit // allowed units: kHz, MHz, Mc/s, G, T - tokens = iter1->fLine.Tokenize(" \t"); - if (!tokens) { - std::cerr << std::endl << ">> PMsrHandler::HandlePlotEntry: **SEVERE ERROR** Couldn't tokenize rrf_freq in line " << iter1->fLineNo; - std::cerr << std::endl << std::endl; - return false; - } - if (tokens->GetEntries() != 3) { + tokens = PStringUtils::Split(iter1->fLine.Data(), " \t"); + if (tokens.size() != 3) { error = true; } else { // get rrf frequency - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (str.IsFloat()) { - param.fRRFFreq = str.Atof(); - } else { + bool ok = false; + param.fRRFFreq = PStringUtils::ToDouble(tokens[1], &ok); + if (!ok) error = true; - } // get unit - ostr = dynamic_cast(tokens->At(2)); - str = ostr->GetString(); - if (str.Contains("kHz", TString::kIgnoreCase)) + if (PStringUtils::ContainsNoCase(tokens[2], "kHz")) param.fRRFUnit = RRF_UNIT_kHz; - else if (str.Contains("MHz", TString::kIgnoreCase)) + else if (PStringUtils::ContainsNoCase(tokens[2], "MHz")) param.fRRFUnit = RRF_UNIT_MHz; - else if (str.Contains("Mc/s", TString::kIgnoreCase)) + else if (PStringUtils::ContainsNoCase(tokens[2], "Mc/s")) param.fRRFUnit = RRF_UNIT_Mcs; - else if (str.Contains("G", TString::kIgnoreCase)) + else if (PStringUtils::ContainsNoCase(tokens[2], "G")) param.fRRFUnit = RRF_UNIT_G; - else if (str.Contains("T", TString::kIgnoreCase)) + else if (PStringUtils::ContainsNoCase(tokens[2], "T")) param.fRRFUnit = RRF_UNIT_T; else error = true; } - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; - } } else if (iter1->fLine.Contains("rrf_phase", TString::kIgnoreCase)) { // expected entry: rrf_phase value. value given in units of degree. or // rrf_phase parX. where X is the parameter number, e.g. par3 - tokens = iter1->fLine.Tokenize(" \t"); - if (!tokens) { - std::cerr << std::endl << ">> PMsrHandler::HandlePlotEntry: **SEVERE ERROR** Couldn't tokenize rrf_phase in line " << iter1->fLineNo; - std::cerr << std::endl << std::endl; - return false; - } - if (tokens->GetEntries() != 2) { + tokens = PStringUtils::Split(iter1->fLine.Data(), " \t"); + if (tokens.size() != 2) { error = true; } else { // get rrf phase - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (str.IsFloat()) { - param.fRRFPhase = str.Atof(); - } else { - if (str.BeginsWith("par", TString::kIgnoreCase)) { // parameter value - Int_t no = 0; - if (FilterNumber(str, "par", 0, no)) { - // check that the parameter is in range - if (static_cast(fParam.size()) < no) { - error = true; - } else { - // keep the parameter number in case parX was used - param.fRRFPhaseParamNo = no; - // get parameter value - param.fRRFPhase = fParam[no-1].fValue; - } + bool ok = false; + const double rrfPhase = PStringUtils::ToDouble(tokens[1], &ok); + if (ok) { + param.fRRFPhase = rrfPhase; + } else if (PStringUtils::BeginsWithNoCase(tokens[1], "par")) { // parameter value + Int_t no = 0; + if (FilterNumber(tokens[1].c_str(), "par", 0, no)) { + // check that the parameter is in range + if (static_cast(fParam.size()) < no) { + error = true; + } else { + // keep the parameter number in case parX was used + param.fRRFPhaseParamNo = no; + // get parameter value + param.fRRFPhase = fParam[no-1].fValue; } - } else { - error = true; } - } - } - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; - } - } else if (iter1->fLine.Contains("rrf_packing", TString::kIgnoreCase)) { - // expected entry: rrf_phase value. value given in units of degree - tokens = iter1->fLine.Tokenize(" \t"); - if (!tokens) { - std::cerr << std::endl << ">> PMsrHandler::HandlePlotEntry: **SEVERE ERROR** Couldn't tokenize rrf_packing in line " << iter1->fLineNo; - std::cerr << std::endl << std::endl; - return false; - } - if (tokens->GetEntries() != 2) { - error = true; - } else { - // get rrf packing - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (str.IsDigit()) { - param.fRRFPacking = str.Atoi(); } else { error = true; } } - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; + } else if (iter1->fLine.Contains("rrf_packing", TString::kIgnoreCase)) { + // expected entry: rrf_phase value. value given in units of degree + tokens = PStringUtils::Split(iter1->fLine.Data(), " \t"); + if (tokens.size() != 2) { + error = true; + } else { + // get rrf packing + bool ok = false; + param.fRRFPacking = PStringUtils::ToInt(tokens[1], &ok); + if (!ok) + error = true; } } else { error = true; @@ -5381,7 +4994,7 @@ Bool_t PMsrHandler::HandleStatisticEntry(PMsrLines &lines) if (status == 2) { fStatistic.fDate = TString(date)+TString(", ")+TString(time); } else { - fStatistic.fDate = TString("????-??-??, ??:??:??"); + fStatistic.fDate = TString("\?\?\?\?-\?\?-\?\?, \?\?:\?\?:\?\?"); } } // extract chisq @@ -5448,8 +5061,7 @@ UInt_t PMsrHandler::GetNoOfFitParameters(UInt_t idx) PUIntVector paramVector; PUIntVector funVector; PUIntVector mapVector; - TObjArray *tokens = nullptr; - TObjString *ostr = nullptr; + std::vector tokens; TString str; UInt_t k, dval; Int_t status, pos; @@ -5498,42 +5110,31 @@ UInt_t PMsrHandler::GetNoOfFitParameters(UInt_t idx) if (pos >= 0) str.Resize(pos); // tokenize - tokens = str.Tokenize(" \t"); - if (!tokens) { - mapVector.clear(); - funVector.clear(); - paramVector.clear(); - return 0; - } + tokens = PStringUtils::Split(str.Data(), " \t"); - for (Int_t j=0; jGetEntries(); j++) { - ostr = dynamic_cast(tokens->At(j)); - str = ostr->GetString(); + for (UInt_t j=0; jGetEntries(); j++) { - ostr = dynamic_cast(tokens->At(j)); - str = ostr->GetString(); + for (UInt_t j=0; j tokens; TString str; Int_t ival, funNo; @@ -5664,33 +5256,23 @@ void PMsrHandler::FillParameterInUse(PMsrLines &theory, PMsrLines &funcs, PMsrLi str.ToLower(); // tokenize string - tokens = str.Tokenize(" \t"); - if (!tokens) - continue; + tokens = PStringUtils::Split(str.Data(), " \t"); // filter param no, map no, and fun no - for (Int_t i=0; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); - if (str.IsDigit()) { // parameter number - ival = str.Atoi(); + for (UInt_t i=0; i 0) && (ival < static_cast(fParam.size())+1)) { fParamInUse[ival-1]++; } - } else if (str.Contains("map")) { // map - if (FilterNumber(str, "map", MSR_PARAM_MAP_OFFSET, ival)) + } else if (tokens[i].find("map") != std::string::npos) { // map + if (FilterNumber(tokens[i].c_str(), "map", MSR_PARAM_MAP_OFFSET, ival)) map.push_back(ival-MSR_PARAM_MAP_OFFSET); - } else if (str.Contains("fun")) { // fun - if (FilterNumber(str, "fun", MSR_PARAM_FUN_OFFSET, ival)) + } else if (tokens[i].find("fun") != std::string::npos) { // fun + if (FilterNumber(tokens[i].c_str(), "fun", MSR_PARAM_FUN_OFFSET, ival)) fun.push_back(ival-MSR_PARAM_FUN_OFFSET); } } - - // delete tokens - if (tokens) { - delete tokens; - tokens = nullptr; - } } // go through all the function lines: 1st time ----------------------------- @@ -5703,14 +5285,12 @@ void PMsrHandler::FillParameterInUse(PMsrLines &theory, PMsrLines &funcs, PMsrLi // everything to lower case str.ToLower(); - tokens = str.Tokenize(" /t"); - if (!tokens) + tokens = PStringUtils::Split(str.Data(), " /t"); + if (tokens.empty()) continue; // filter fun number - ostr = dynamic_cast(tokens->At(0)); - str = ostr->GetString(); - if (!FilterNumber(str, "fun", MSR_PARAM_FUN_OFFSET, funNo)) + if (!FilterNumber(tokens[0].c_str(), "fun", MSR_PARAM_FUN_OFFSET, funNo)) continue; funNo -= MSR_PARAM_FUN_OFFSET; @@ -5759,12 +5339,6 @@ void PMsrHandler::FillParameterInUse(PMsrLines &theory, PMsrLines &funcs, PMsrLi break; // since function was found, break the loop } } - - // delete tokens - if (tokens) { - delete tokens; - tokens = nullptr; - } } // go through all the run block lines ------------------------------------- @@ -5783,61 +5357,42 @@ void PMsrHandler::FillParameterInUse(PMsrLines &theory, PMsrLines &funcs, PMsrLi str.Contains("norm") || str.Contains("backgr.fit") || str.Contains("lifetime ")) { // tokenize string - tokens = str.Tokenize(" \t"); - if (!tokens) - continue; - if (tokens->GetEntries()<2) + tokens = PStringUtils::Split(str.Data(), " \t"); + if (tokens.size()<2) continue; - ostr = dynamic_cast(tokens->At(1)); // parameter number or function - str = ostr->GetString(); + std::string tok1 = tokens[1]; // parameter number or function // check if parameter number - if (str.IsDigit()) { - ival = str.Atoi(); + if (PStringUtils::IsInt(tok1)) { + ival = PStringUtils::ToInt(tok1); fParamInUse[ival-1]++; } // check if fun - if (str.Contains("fun")) { - if (FilterNumber(str, "fun", MSR_PARAM_FUN_OFFSET, ival)) { + if (tok1.find("fun") != std::string::npos) { + if (FilterNumber(tok1.c_str(), "fun", MSR_PARAM_FUN_OFFSET, ival)) { fun.push_back(ival-MSR_PARAM_FUN_OFFSET); } } - - // delete tokens - if (tokens) { - delete tokens; - tokens = nullptr; - } } // handle the maps if (str.Contains("map")) { // tokenize string - tokens = str.Tokenize(" \t"); - if (!tokens) - continue; + tokens = PStringUtils::Split(str.Data(), " \t"); // get the parameter number via map for (UInt_t i=0; iGetEntries()) { - ostr = dynamic_cast(tokens->At(map[i])); - str = ostr->GetString(); - if (str.IsDigit()) { - ival = str.Atoi(); + if (map[i] < static_cast(tokens.size())) { + if (PStringUtils::IsInt(tokens[map[i]])) { + ival = PStringUtils::ToInt(tokens[map[i]]); if (ival > 0) { fParamInUse[ival-1]++; // this is OK since map is ranging from 1 .. } } } } - - // delete tokens - if (tokens) { - delete tokens; - tokens = nullptr; - } } } @@ -5851,14 +5406,12 @@ void PMsrHandler::FillParameterInUse(PMsrLines &theory, PMsrLines &funcs, PMsrLi // everything to lower case str.ToLower(); - tokens = str.Tokenize(" /t"); - if (!tokens) + tokens = PStringUtils::Split(str.Data(), " /t"); + if (tokens.empty()) continue; // filter fun number - ostr = dynamic_cast(tokens->At(0)); - str = ostr->GetString(); - if (!FilterNumber(str, "fun", MSR_PARAM_FUN_OFFSET, funNo)) + if (!FilterNumber(tokens[0].c_str(), "fun", MSR_PARAM_FUN_OFFSET, funNo)) continue; funNo -= MSR_PARAM_FUN_OFFSET; @@ -5906,12 +5459,6 @@ void PMsrHandler::FillParameterInUse(PMsrLines &theory, PMsrLines &funcs, PMsrLi } } } - - // delete tokens - if (tokens) { - delete tokens; - tokens = nullptr; - } } // go through all the run block lines 2nd time to filter remaining maps @@ -5927,31 +5474,21 @@ void PMsrHandler::FillParameterInUse(PMsrLines &theory, PMsrLines &funcs, PMsrLi // handle the maps if (str.Contains("map")) { // tokenize string - tokens = str.Tokenize(" \t"); - if (!tokens) - continue; + tokens = PStringUtils::Split(str.Data(), " \t"); // get the parameter number via map for (UInt_t i=0; iGetEntries()) { - ostr = dynamic_cast(tokens->At(map[i])); - str = ostr->GetString(); - if (str.IsDigit()) { - ival = str.Atoi(); + if (map[i] < static_cast(tokens.size())) { + if (PStringUtils::IsInt(tokens[map[i]])) { + ival = PStringUtils::ToInt(tokens[map[i]]); if (ival > 0) { fParamInUse[ival-1]++; // this is OK since map is ranging from 1 .. } } } } - - // delete tokens - if (tokens) { - delete tokens; - tokens = nullptr; - } } } @@ -6367,9 +5904,7 @@ Bool_t PMsrHandler::CheckMaps() PIntVector mapBlock; PIntVector mapLineNo; - TObjArray *tokens = nullptr; - TObjString *ostr = nullptr; - TString str; + std::vector tokens; Int_t no; @@ -6377,23 +5912,16 @@ Bool_t PMsrHandler::CheckMaps() for (UInt_t i=0; iGetEntries(); j++) { - ostr = dynamic_cast(tokens->At(j)); - str = ostr->GetString(); - if (str.Contains("map", TString::kIgnoreCase)) { - if (FilterNumber(str, "map", MSR_PARAM_MAP_OFFSET, no)) { + tokens = PStringUtils::Split(fTheory[i].fLine.Data(), " \t"); + for (UInt_t j=0; jGetEntries(); j++) { - ostr = dynamic_cast(tokens->At(j)); - str = ostr->GetString(); - if (str.Contains("map", TString::kIgnoreCase)) { - if (FilterNumber(str, "map", MSR_PARAM_MAP_OFFSET, no)) { + tokens = PStringUtils::Split(fFunctions[i].fLine.Data(), " \t"); + for (UInt_t j=0; j tokens; TString str; Int_t no; @@ -6490,23 +6010,16 @@ Bool_t PMsrHandler::CheckFuncs() for (UInt_t i=0; iGetEntries(); j++) { - ostr = dynamic_cast(tokens->At(j)); - str = ostr->GetString(); - if (str.Contains("fun", TString::kIgnoreCase)) { - if (FilterNumber(str, "fun", MSR_PARAM_FUN_OFFSET, no)) { + tokens = PStringUtils::Split(fTheory[i].fLine.Data(), " \t"); + for (UInt_t j=0; j #include #include -#include #include #include "PMusrCanvas.h" #include "PFourier.h" +#include "PStringUtils.h" static const char *gFiletypes[] = { "Data files", "*.dat", "All files", "*", @@ -6408,23 +6408,15 @@ Bool_t PMusrCanvas::IsScaleN0AndBkg() PMsrLines *cmd = fMsrHandler->GetMsrCommands(); for (UInt_t i=0; isize(); i++) { if (cmd->at(i).fLine.Contains("SCALE_N0_BKG", TString::kIgnoreCase)) { - TObjArray *tokens = nullptr; - TObjString *ostr = nullptr; - TString str; - tokens = cmd->at(i).fLine.Tokenize(" \t"); - if (tokens->GetEntries() != 2) { + std::vector tokens = PStringUtils::Split(cmd->at(i).fLine.Data(), " \t"); + if (tokens.size() != 2) { std::cerr << std::endl << ">> PRunSingleHisto::IsScaleN0AndBkg(): **WARNING** Found uncorrect 'SCALE_N0_BKG' command, will ignore it."; std::cerr << std::endl << ">> Allowed commands: SCALE_N0_BKG TRUE | FALSE" << std::endl; return willScale; } - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (!str.CompareTo("FALSE", TString::kIgnoreCase)) { + if (PStringUtils::IsEqualNoCase(tokens[1], "FALSE")) { willScale = false; } - // clean up - if (tokens) - delete tokens; } } diff --git a/src/classes/PRunAsymmetry.cpp b/src/classes/PRunAsymmetry.cpp index cdafa3d6..6c3b2038 100644 --- a/src/classes/PRunAsymmetry.cpp +++ b/src/classes/PRunAsymmetry.cpp @@ -38,12 +38,13 @@ #include #include +#include +#include #include -#include -#include #include "PMusr.h" +#include "PStringUtils.h" #include "PRunAsymmetry.h" //-------------------------------------------------------------------------- @@ -404,18 +405,15 @@ UInt_t PRunAsymmetry::GetNoOfFitBins() */ void PRunAsymmetry::SetFitRangeBin(const TString fitRange) { - TObjArray *tok = nullptr; - TObjString *ostr = nullptr; TString str; Ssiz_t idx = -1; Int_t offset = 0; - tok = fitRange.Tokenize(" \t"); + std::vector tok = PStringUtils::Split(fitRange.Data(), " \t"); - if (tok->GetEntries() == 3) { // structure FIT_RANGE fgb+n0 lgb-n1 + if (tok.size() == 3) { // structure FIT_RANGE fgb+n0 lgb-n1 // handle fgb+n0 entry - ostr = dynamic_cast(tok->At(1)); - str = ostr->GetString(); + str = tok[1]; // check if there is an offset present idx = str.First("+"); if (idx != -1) { // offset present @@ -426,8 +424,7 @@ void PRunAsymmetry::SetFitRangeBin(const TString fitRange) fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; // handle lgb-n1 entry - ostr = dynamic_cast(tok->At(2)); - str = ostr->GetString(); + str = tok[2]; // check if there is an offset present idx = str.First("-"); if (idx != -1) { // offset present @@ -436,16 +433,15 @@ void PRunAsymmetry::SetFitRangeBin(const TString fitRange) offset = str.Atoi(); } fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution; - } else if ((tok->GetEntries() > 3) && (tok->GetEntries() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]] - Int_t pos = 2*(fRunNo+1)-1; + } else if ((tok.size() > 3) && (tok.size() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]] + UInt_t pos = 2*(fRunNo+1)-1; - if (pos + 1 >= tok->GetEntries()) { + if (pos + 1 >= tok.size()) { std::cerr << std::endl << ">> PRunAsymmetry::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'"; std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; } else { // handle fgb+n0 entry - ostr = static_cast(tok->At(pos)); - str = ostr->GetString(); + str = tok[pos]; // check if there is an offset present idx = str.First("+"); if (idx != -1) { // offset present @@ -456,8 +452,7 @@ void PRunAsymmetry::SetFitRangeBin(const TString fitRange) fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; // handle lgb-n1 entry - ostr = static_cast(tok->At(pos+1)); - str = ostr->GetString(); + str = tok[pos+1]; // check if there is an offset present idx = str.First("-"); if (idx != -1) { // offset present @@ -471,11 +466,6 @@ void PRunAsymmetry::SetFitRangeBin(const TString fitRange) std::cerr << std::endl << ">> PRunAsymmetry::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'"; std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; } - - // clean up - if (tok) { - delete tok; - } } //-------------------------------------------------------------------------- diff --git a/src/classes/PRunAsymmetryBNMR.cpp b/src/classes/PRunAsymmetryBNMR.cpp index 78f8d90e..353ac9e3 100644 --- a/src/classes/PRunAsymmetryBNMR.cpp +++ b/src/classes/PRunAsymmetryBNMR.cpp @@ -39,12 +39,13 @@ #include #include +#include +#include #include -#include -#include #include "PMusr.h" +#include "PStringUtils.h" #include "PRunAsymmetryBNMR.h" //-------------------------------------------------------------------------- @@ -406,18 +407,15 @@ UInt_t PRunAsymmetryBNMR::GetNoOfFitBins() */ void PRunAsymmetryBNMR::SetFitRangeBin(const TString fitRange) { - TObjArray *tok = nullptr; - TObjString *ostr = nullptr; TString str; Ssiz_t idx = -1; Int_t offset = 0; - tok = fitRange.Tokenize(" \t"); + std::vector tok = PStringUtils::Split(fitRange.Data(), " \t"); - if (tok->GetEntries() == 3) { // structure FIT_RANGE fgb+n0 lgb-n1 + if (tok.size() == 3) { // structure FIT_RANGE fgb+n0 lgb-n1 // handle fgb+n0 entry - ostr = dynamic_cast(tok->At(1)); - str = ostr->GetString(); + str = tok[1]; // check if there is an offset present idx = str.First("+"); if (idx != -1) { // offset present @@ -428,8 +426,7 @@ void PRunAsymmetryBNMR::SetFitRangeBin(const TString fitRange) fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; // handle lgb-n1 entry - ostr = dynamic_cast(tok->At(2)); - str = ostr->GetString(); + str = tok[2]; // check if there is an offset present idx = str.First("-"); if (idx != -1) { // offset present @@ -438,16 +435,15 @@ void PRunAsymmetryBNMR::SetFitRangeBin(const TString fitRange) offset = str.Atoi(); } fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution; - } else if ((tok->GetEntries() > 3) && (tok->GetEntries() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]] - Int_t pos = 2*(fRunNo+1)-1; + } else if ((tok.size() > 3) && (tok.size() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]] + UInt_t pos = 2*(fRunNo+1)-1; - if (pos + 1 >= tok->GetEntries()) { + if (pos + 1 >= tok.size()) { std::cerr << std::endl << ">> PRunAsymmetryBNMR::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'"; std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; } else { // handle fgb+n0 entry - ostr = static_cast(tok->At(pos)); - str = ostr->GetString(); + str = tok[pos]; // check if there is an offset present idx = str.First("+"); if (idx != -1) { // offset present @@ -458,8 +454,7 @@ void PRunAsymmetryBNMR::SetFitRangeBin(const TString fitRange) fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; // handle lgb-n1 entry - ostr = static_cast(tok->At(pos+1)); - str = ostr->GetString(); + str = tok[pos+1]; // check if there is an offset present idx = str.First("-"); if (idx != -1) { // offset present @@ -473,11 +468,6 @@ void PRunAsymmetryBNMR::SetFitRangeBin(const TString fitRange) std::cerr << std::endl << ">> PRunAsymmetryBNMR::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'"; std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; } - - // clean up - if (tok) { - delete tok; - } } //-------------------------------------------------------------------------- diff --git a/src/classes/PRunAsymmetryRRF.cpp b/src/classes/PRunAsymmetryRRF.cpp index a73720cc..c961f951 100644 --- a/src/classes/PRunAsymmetryRRF.cpp +++ b/src/classes/PRunAsymmetryRRF.cpp @@ -39,12 +39,13 @@ #include #include +#include +#include #include -#include -#include #include "PMusr.h" +#include "PStringUtils.h" #include "PRunAsymmetryRRF.h" //-------------------------------------------------------------------------- @@ -393,18 +394,15 @@ UInt_t PRunAsymmetryRRF::GetNoOfFitBins() */ void PRunAsymmetryRRF::SetFitRangeBin(const TString fitRange) { - TObjArray *tok = nullptr; - TObjString *ostr = nullptr; TString str; Ssiz_t idx = -1; Int_t offset = 0; - tok = fitRange.Tokenize(" \t"); + std::vector tok = PStringUtils::Split(fitRange.Data(), " \t"); - if (tok->GetEntries() == 3) { // structure FIT_RANGE fgb+n0 lgb-n1 + if (tok.size() == 3) { // structure FIT_RANGE fgb+n0 lgb-n1 // handle fgb+n0 entry - ostr = static_cast(tok->At(1)); - str = ostr->GetString(); + str = tok[1]; // check if there is an offset present idx = str.First("+"); if (idx != -1) { // offset present @@ -415,8 +413,7 @@ void PRunAsymmetryRRF::SetFitRangeBin(const TString fitRange) fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; // handle lgb-n1 entry - ostr = static_cast(tok->At(2)); - str = ostr->GetString(); + str = tok[2]; // check if there is an offset present idx = str.First("-"); if (idx != -1) { // offset present @@ -425,16 +422,15 @@ void PRunAsymmetryRRF::SetFitRangeBin(const TString fitRange) offset = str.Atoi(); } fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution; - } else if ((tok->GetEntries() > 3) && (tok->GetEntries() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]] - Int_t pos = 2*(fRunNo+1)-1; + } else if ((tok.size() > 3) && (tok.size() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]] + UInt_t pos = 2*(fRunNo+1)-1; - if (pos + 1 >= tok->GetEntries()) { + if (pos + 1 >= tok.size()) { std::cerr << std::endl << ">> PRunSingleHisto::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'"; std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; } else { // handle fgb+n0 entry - ostr = static_cast(tok->At(pos)); - str = ostr->GetString(); + str = tok[pos]; // check if there is an offset present idx = str.First("+"); if (idx != -1) { // offset present @@ -445,8 +441,7 @@ void PRunAsymmetryRRF::SetFitRangeBin(const TString fitRange) fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; // handle lgb-n1 entry - ostr = static_cast(tok->At(pos+1)); - str = ostr->GetString(); + str = tok[pos+1]; // check if there is an offset present idx = str.First("-"); if (idx != -1) { // offset present @@ -460,11 +455,6 @@ void PRunAsymmetryRRF::SetFitRangeBin(const TString fitRange) std::cerr << std::endl << ">> PRunSingleHisto::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'"; std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; } - - // clean up - if (tok) { - delete tok; - } } //-------------------------------------------------------------------------- diff --git a/src/classes/PRunBase.cpp b/src/classes/PRunBase.cpp index a3f2d467..4bb89453 100644 --- a/src/classes/PRunBase.cpp +++ b/src/classes/PRunBase.cpp @@ -32,8 +32,6 @@ #include #include #include -#include -#include #include #include "PRunBase.h" diff --git a/src/classes/PRunDataHandler.cpp b/src/classes/PRunDataHandler.cpp index 5131dd1c..9011b10c 100644 --- a/src/classes/PRunDataHandler.cpp +++ b/src/classes/PRunDataHandler.cpp @@ -42,6 +42,7 @@ #include #include #include +#include #include #include @@ -58,6 +59,7 @@ #include "TLemRunHeader.h" #include "MuSR_td_PSI_bin.h" #include "mud.h" +#include "PStringUtils.h" #ifdef PNEXUS_ENABLED #include "PNeXus.h" @@ -1168,30 +1170,22 @@ Bool_t PRunDataHandler::FileExistsCheck(PMsrRunBlock &runInfo, const UInt_t idx) if (pathName.CompareTo("???") == 0) { // not found in local directory and xml path str = TString(musrpath); // MUSRFULLDATAPATH has the structure: path_1:path_2:...:path_n - TObjArray *tokens = str.Tokenize(":"); - TObjString *ostr; - for (Int_t i=0; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString() + TString("/") + *runInfo.GetRunName(idx); + std::vector tokens = PStringUtils::Split(str.Data(), ":"); + for (UInt_t i=0; i tokens = PStringUtils::Split(str.Data(), ":"); pstr = runInfo.GetInstitute(idx); if (pstr == nullptr) { std::cerr << std::endl << ">> PRunDataHandler::FileExistsCheck: **ERROR** Couldn't obtain institute data." << std::endl; @@ -1206,9 +1200,8 @@ Bool_t PRunDataHandler::FileExistsCheck(PMsrRunBlock &runInfo, const UInt_t idx) } pstr->ToUpper(); runInfo.SetBeamline(*pstr, idx); - for (Int_t i=0; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString() + TString("/DATA/") + + for (UInt_t i=0; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString() + TString("/") + fln; + std::vector tokens = PStringUtils::Split(str.Data(), ":"); + for (UInt_t i=0; iAccessPathName(str.Data())!=true) { // found pathName = str; break; } } - // cleanup - if (tokens) { - delete tokens; - tokens = nullptr; - } } // no proper path name found if (pathName.CompareTo("???") == 0) { @@ -1374,21 +1355,14 @@ Bool_t PRunDataHandler::FileExistsCheck(const TString fileName) if (pathName.CompareTo("???") == 0) { // not found in local directory and xml path str = TString(musrpath); // MUSRFULLDATAPATH has the structure: path_1:path_2:...:path_n - TObjArray *tokens = str.Tokenize(":"); - TObjString *ostr; - for (Int_t i=0; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString() + TString("/") + fileName; + std::vector tokens = PStringUtils::Split(str.Data(), ":"); + for (UInt_t i=0; iAccessPathName(str.Data())!=true) { // found pathName = str; break; } } - // cleanup - if (tokens) { - delete tokens; - tokens = nullptr; - } } // no proper path name found if (pathName.CompareTo("???") == 0) { @@ -1544,97 +1518,22 @@ Bool_t PRunDataHandler::ReadRootFile() TString s; TObjArrayIter summIter(runSummary); TObjString *os(dynamic_cast(summIter.Next())); - TObjArray *oa(nullptr); - TObjString *objTok(nullptr); while (os != nullptr) { 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")) { - oa = s.Tokenize(" "); - TObjArrayIter lineIter(oa); - objTok = dynamic_cast(lineIter.Next()); - while (objTok != nullptr) { - if (!objTok->GetString().CompareTo("RA-L")) { - objTok = dynamic_cast(lineIter.Next()); // "=" - if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) { - objTok = dynamic_cast(lineIter.Next()); // HV value - runData.SetRingAnode(0, objTok->GetString().Atof()); // fill RA-R value into the runData structure - break; - } - } - objTok = dynamic_cast(lineIter.Next()); // next token... - } - // clean up - if (oa) { - delete oa; - oa = nullptr; - } - } - - if (s.Contains("RA-R")) { - oa = s.Tokenize(" "); - TObjArrayIter lineIter(oa); - objTok = dynamic_cast(lineIter.Next()); - while (objTok != nullptr){ - if (!objTok->GetString().CompareTo("RA-R")) { - objTok = dynamic_cast(lineIter.Next()); // "=" - if (objTok != nullptr && !objTok->GetString().CompareTo("=")) { - objTok = dynamic_cast(lineIter.Next()); // HV value - runData.SetRingAnode(1, objTok->GetString().Atof()); // fill RA-R value into the runData structure - break; - } - } - objTok = dynamic_cast(lineIter.Next()); // next token... - } - // clean up - if (oa) { - delete oa; - oa = nullptr; - } - } - - if (s.Contains("RA-T")) { - oa = s.Tokenize(" "); - TObjArrayIter lineIter(oa); - objTok = dynamic_cast(lineIter.Next()); - while (objTok != nullptr){ - if (!objTok->GetString().CompareTo("RA-T")) { - objTok = dynamic_cast(lineIter.Next()); // "=" - if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) { - objTok = dynamic_cast(lineIter.Next()); // HV value - runData.SetRingAnode(2, objTok->GetString().Atof()); // fill RA-T value into the runData structure - break; - } - } - objTok = dynamic_cast(lineIter.Next()); // next token... - } - // clean up - if (oa) { - delete oa; - oa = nullptr; - } - } - - if (s.Contains("RA-B")) { - oa = s.Tokenize(" "); - TObjArrayIter lineIter(oa); - objTok = dynamic_cast(lineIter.Next()); - while (objTok != nullptr){ - if (!objTok->GetString().CompareTo("RA-B")) { - objTok = dynamic_cast(lineIter.Next()); // "=" - if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) { - objTok = dynamic_cast(lineIter.Next()); // HV value - runData.SetRingAnode(3, objTok->GetString().Atof()); // fill RA-B value into the runData structure - break; - } - } - objTok = dynamic_cast(lineIter.Next()); // next token... - } - // clean up - if (oa) { - delete oa; - oa = nullptr; - } + // a summary line has the structure 'RA-L = val RA-R = val ...', i.e. the value + // follows two tokens after the tag. More than one RA-value may be on one line. + std::vector oa = PStringUtils::Split(s.Data(), " "); + for (UInt_t k=0; k+2 < oa.size(); k++) { + if (oa[k+1] != "=") + continue; + if (oa[k] == "RA-L") + runData.SetRingAnode(0, TString(oa[k+2]).Atof()); + else if (oa[k] == "RA-R") + runData.SetRingAnode(1, TString(oa[k+2]).Atof()); + else if (oa[k] == "RA-T") + runData.SetRingAnode(2, TString(oa[k+2]).Atof()); + else if (oa[k] == "RA-B") + runData.SetRingAnode(3, TString(oa[k+2]).Atof()); } os = dynamic_cast(summIter.Next()); // next summary line... @@ -1962,97 +1861,22 @@ Bool_t PRunDataHandler::ReadRootFile() TString s; TObjArrayIter summIter(runSummary); TObjString *os(dynamic_cast(summIter.Next())); - TObjArray *oa(nullptr); - TObjString *objTok(nullptr); while (os != nullptr) { 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")) { - oa = s.Tokenize(" "); - TObjArrayIter lineIter(oa); - objTok = dynamic_cast(lineIter.Next()); - while (objTok != nullptr) { - if (!objTok->GetString().CompareTo("RA-L")) { - objTok = dynamic_cast(lineIter.Next()); // "=" - if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) { - objTok = dynamic_cast(lineIter.Next()); // HV value - runData.SetRingAnode(0, objTok->GetString().Atof()); // fill RA-R value into the runData structure - break; - } - } - objTok = dynamic_cast(lineIter.Next()); // next token... - } - // clean up - if (oa) { - delete oa; - oa = nullptr; - } - } - - if (s.Contains("RA-R")) { - oa = s.Tokenize(" "); - TObjArrayIter lineIter(oa); - objTok = dynamic_cast(lineIter.Next()); - while (objTok != nullptr){ - if (!objTok->GetString().CompareTo("RA-R")) { - objTok = dynamic_cast(lineIter.Next()); // "=" - if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) { - objTok = dynamic_cast(lineIter.Next()); // HV value - runData.SetRingAnode(1, objTok->GetString().Atof()); // fill RA-R value into the runData structure - break; - } - } - objTok = dynamic_cast(lineIter.Next()); // next token... - } - // clean up - if (oa) { - delete oa; - oa = nullptr; - } - } - - if (s.Contains("RA-T")) { - oa = s.Tokenize(" "); - TObjArrayIter lineIter(oa); - objTok = dynamic_cast(lineIter.Next()); - while (objTok != nullptr){ - if (!objTok->GetString().CompareTo("RA-T")) { - objTok = dynamic_cast(lineIter.Next()); // "=" - if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) { - objTok = dynamic_cast(lineIter.Next()); // HV value - runData.SetRingAnode(2, objTok->GetString().Atof()); // fill RA-T value into the runData structure - break; - } - } - objTok = dynamic_cast(lineIter.Next()); // next token... - } - // clean up - if (oa) { - delete oa; - oa = nullptr; - } - } - - if (s.Contains("RA-B")) { - oa = s.Tokenize(" "); - TObjArrayIter lineIter(oa); - objTok = dynamic_cast(lineIter.Next()); - while (objTok != nullptr){ - if (!objTok->GetString().CompareTo("RA-B")) { - objTok = dynamic_cast(lineIter.Next()); // "=" - if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) { - objTok = dynamic_cast(lineIter.Next()); // HV value - runData.SetRingAnode(3, objTok->GetString().Atof()); // fill RA-B value into the runData structure - break; - } - } - objTok = dynamic_cast(lineIter.Next()); // next token... - } - // clean up - if (oa) { - delete oa; - oa = nullptr; - } + // a summary line has the structure 'RA-L = val RA-R = val ...', i.e. the value + // follows two tokens after the tag. More than one RA-value may be on one line. + std::vector oa = PStringUtils::Split(s.Data(), " "); + for (UInt_t k=0; k+2 < oa.size(); k++) { + if (oa[k+1] != "=") + continue; + if (oa[k] == "RA-L") + runData.SetRingAnode(0, TString(oa[k+2]).Atof()); + else if (oa[k] == "RA-R") + runData.SetRingAnode(1, TString(oa[k+2]).Atof()); + else if (oa[k] == "RA-T") + runData.SetRingAnode(2, TString(oa[k+2]).Atof()); + else if (oa[k] == "RA-B") + runData.SetRingAnode(3, TString(oa[k+2]).Atof()); } os = dynamic_cast(summIter.Next()); // next summary line... @@ -2454,8 +2278,7 @@ Bool_t PRunDataHandler::ReadWkmFile() // read data --------------------------------------------------------- UInt_t group_counter = 0; Int_t val; - TObjArray *tokens; - TObjString *ostr; + std::vector tokens; TString str; UInt_t histoNo = 0; PRawRunDataSet dataSet; @@ -2489,30 +2312,22 @@ Bool_t PRunDataHandler::ReadWkmFile() f.getline(instr, sizeof(instr)); continue; } - tokens = line.Tokenize(" "); + tokens = PStringUtils::Split(line.Data(), " "); - if (!tokens) { // no tokens found + if (tokens.empty()) { // no tokens found std::cerr << std::endl << ">> PRunDataHandler::ReadWkmFile(): **ERROR** while reading data: coulnd't tokenize run data."; return false; } - for (Int_t i=0; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); + for (UInt_t i=0; i> PRunDataHandler::ReadWkmFile(): **ERROR** while reading data: data line contains non-integer values."; - // clean up - delete tokens; return false; } } - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; - } } f.getline(instr, sizeof(instr)); @@ -2523,29 +2338,21 @@ Bool_t PRunDataHandler::ReadWkmFile() if (strlen(instr) != 0) { // extract values line = TString(instr); - tokens = line.Tokenize(" "); - if (!tokens) { // no tokens found + tokens = PStringUtils::Split(line.Data(), " "); + if (tokens.empty()) { // no tokens found std::cerr << std::endl << ">> PRunDataHandler::ReadWkmFile(): **ERROR** while reading data: coulnd't tokenize run data."; return false; } - for (Int_t i=0; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); + for (UInt_t i=0; i> PRunDataHandler::ReadWkmFile(): **ERROR** while reading data: data line contains non-integer values."; - // clean up - delete tokens; return false; } } - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; - } } // save the last histo if not empty @@ -3242,8 +3049,7 @@ Bool_t PRunDataHandler::ReadMduAsciiFile() Bool_t headerTag = false; Bool_t dataTag = false; Int_t dataLineCounter = 0; - TObjString *ostr; - TObjArray *tokens = nullptr; + std::vector tokens; TString str; Int_t groups = 0; Int_t channels = 0; @@ -3287,9 +3093,9 @@ Bool_t PRunDataHandler::ReadMduAsciiFile() 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) + tokens = PStringUtils::Split(workStr.Data(), ":("); // field: val (units) // check if expected number of tokens present - if (tokens->GetEntries() != 3) { + if (tokens.size() != 3) { std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", invalid field entry in header."; std::cerr << std::endl << ">> " << line.Data(); std::cerr << std::endl; @@ -3297,9 +3103,8 @@ Bool_t PRunDataHandler::ReadMduAsciiFile() break; } // check if field value is a number - ostr = dynamic_cast(tokens->At(1)); - if (ostr->GetString().IsFloat()) { - dval = ostr->GetString().Atof(); + if (TString(tokens[1]).IsFloat()) { + dval = TString(tokens[1]).Atof(); } else { std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", field value is not float/doulbe."; std::cerr << std::endl << ">> " << line.Data(); @@ -3308,10 +3113,9 @@ Bool_t PRunDataHandler::ReadMduAsciiFile() break; } // check units, accept (G), (T) - ostr = dynamic_cast(tokens->At(2)); - if (ostr->GetString().Contains("G")) + if (TString(tokens[2]).Contains("G")) unitScaling = 1.0; - else if (ostr->GetString().Contains("T")) + else if (TString(tokens[2]).Contains("T")) unitScaling = 1.0e4; else { std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", unkown field units."; @@ -3320,17 +3124,11 @@ Bool_t PRunDataHandler::ReadMduAsciiFile() success = false; break; } - runData.SetField(dval*unitScaling); - - // clean up tokens - if (tokens) { - delete tokens; - tokens = nullptr; - } + runData.SetField(dval*unitScaling); } else if (workStr.BeginsWith("temp:", TString::kIgnoreCase)) { - tokens = workStr.Tokenize(":("); // temp: val (units) + tokens = PStringUtils::Split(workStr.Data(), ":("); // temp: val (units) // check if expected number of tokens present - if (tokens->GetEntries() != 3) { + if (tokens.size() != 3) { std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", invalid temperatue entry in header."; std::cerr << std::endl << ">> " << line.Data(); std::cerr << std::endl; @@ -3338,9 +3136,8 @@ Bool_t PRunDataHandler::ReadMduAsciiFile() break; } // check if field value is a number - ostr = dynamic_cast(tokens->At(1)); - if (ostr->GetString().IsFloat()) { - dval = ostr->GetString().Atof(); + if (TString(tokens[1]).IsFloat()) { + dval = TString(tokens[1]).Atof(); } else { std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", temperature value is not float/doulbe."; std::cerr << std::endl << ">> " << line.Data(); @@ -3348,13 +3145,7 @@ Bool_t PRunDataHandler::ReadMduAsciiFile() success = false; break; } - runData.SetTemperature(0, dval, 0.0); - - // clean up tokens - if (tokens) { - delete tokens; - tokens = nullptr; - } + runData.SetTemperature(0, dval, 0.0); } else if (workStr.BeginsWith("setup:", TString::kIgnoreCase)) { runData.SetSetup(TString(workStr.Data()+workStr.First(":")+2)); } else if (workStr.BeginsWith("groups:", TString::kIgnoreCase)) { @@ -3377,9 +3168,9 @@ Bool_t PRunDataHandler::ReadMduAsciiFile() break; } } else if (workStr.BeginsWith("resolution:", TString::kIgnoreCase)) { - tokens = workStr.Tokenize(":("); // resolution: val (units) + tokens = PStringUtils::Split(workStr.Data(), ":("); // resolution: val (units) // check if expected number of tokens present - if (tokens->GetEntries() != 3) { + if (tokens.size() != 3) { std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", invalid time resolution entry in header."; std::cerr << std::endl << line.Data(); std::cerr << std::endl; @@ -3387,9 +3178,8 @@ Bool_t PRunDataHandler::ReadMduAsciiFile() break; } // check if timeresolution value is a number - ostr = dynamic_cast(tokens->At(1)); - if (ostr->GetString().IsFloat()) { - dval = ostr->GetString().Atof(); + if (TString(tokens[1]).IsFloat()) { + dval = TString(tokens[1]).Atof(); } else { std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", time resolution value is not float/doulbe."; std::cerr << std::endl << ">> " << line.Data(); @@ -3398,14 +3188,13 @@ Bool_t PRunDataHandler::ReadMduAsciiFile() break; } // check units, accept (fs), (ps), (ns), (us) - ostr = dynamic_cast(tokens->At(2)); - if (ostr->GetString().Contains("fs")) + if (TString(tokens[2]).Contains("fs")) unitScaling = 1.0e-6; - else if (ostr->GetString().Contains("ps")) + else if (TString(tokens[2]).Contains("ps")) unitScaling = 1.0e-3; - else if (ostr->GetString().Contains("ns")) + else if (TString(tokens[2]).Contains("ns")) unitScaling = 1.0; - else if (ostr->GetString().Contains("us")) + else if (TString(tokens[2]).Contains("us")) unitScaling = 1.0e3; else { std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", unkown time resolution units."; @@ -3414,13 +3203,7 @@ Bool_t PRunDataHandler::ReadMduAsciiFile() success = false; break; } - runData.SetTimeResolution(dval*unitScaling); - - // clean up tokens - if (tokens) { - delete tokens; - tokens = nullptr; - } + runData.SetTimeResolution(dval*unitScaling); } else { // error std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", illegal header line."; std::cerr << std::endl; @@ -3429,9 +3212,9 @@ Bool_t PRunDataHandler::ReadMduAsciiFile() } } else if (dataTag) { dataLineCounter++; - tokens = line.Tokenize(" ,\t"); + tokens = PStringUtils::Split(line.Data(), " ,\t"); // check if the number of data line entries is correct - if (tokens->GetEntries() != groups+1) { + if (static_cast(tokens.size()) != groups+1) { std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** found data line with a wrong data format, cannot be handled (line no " << lineNo << ")"; std::cerr << std::endl << ">> line:"; std::cerr << std::endl << ">> " << line.Data(); @@ -3439,16 +3222,9 @@ Bool_t PRunDataHandler::ReadMduAsciiFile() 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 = nullptr; + + for (UInt_t i=1; i tokens = PStringUtils::Split(line.Data(), " ,\t"); // check if the number of data line entries is 2 or 3 - if ((tokens->GetEntries() != 2) && (tokens->GetEntries() != 3)) { + if ((tokens.size() != 2) && (tokens.size() != 3)) { std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** found data line with a structure different than \"x, y [, error y]\", cannot be handled (line no " << lineNo << ")"; std::cerr << std::endl; success = false; @@ -3655,35 +3429,32 @@ Bool_t PRunDataHandler::ReadAsciiFile() } // get x - ostr = dynamic_cast(tokens->At(0)); - if (!ostr->GetString().IsFloat()) { - std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ": x = " << ostr->GetString().Data() << " is not a number, sorry."; + if (!TString(tokens[0]).IsFloat()) { + std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ": x = " << tokens[0] << " is not a number, sorry."; std::cerr << std::endl; success = false; break; } - x = ostr->GetString().Atof(); + x = TString(tokens[0]).Atof(); // get y - ostr = dynamic_cast(tokens->At(1)); - if (!ostr->GetString().IsFloat()) { - std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ": y = " << ostr->GetString().Data() << " is not a number, sorry."; + if (!TString(tokens[1]).IsFloat()) { + std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ": y = " << tokens[1] << " is not a number, sorry."; std::cerr << std::endl; success = false; break; } - y = ostr->GetString().Atof(); + y = TString(tokens[1]).Atof(); // get error y if present - if (tokens->GetEntries() == 3) { - ostr = dynamic_cast(tokens->At(2)); - if (!ostr->GetString().IsFloat()) { - std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ": error y = " << ostr->GetString().Data() << " is not a number, sorry."; + if (tokens.size() == 3) { + if (!TString(tokens[2]).IsFloat()) { + std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ": error y = " << tokens[2] << " is not a number, sorry."; std::cerr << std::endl; success = false; break; } - ey = ostr->GetString().Atof(); + ey = TString(tokens[2]).Atof(); if (ey == 0) { std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **WARNING** line no " << lineNo << ": error y = 0 which doesn't make sense. Will set it to 1.0. Please check!!"; std::cerr << std::endl; @@ -3695,12 +3466,6 @@ Bool_t PRunDataHandler::ReadAsciiFile() ey = 1.0; } - // clean up tokens - if (tokens) { - delete tokens; - tokens = nullptr; - } - // keep values xVec.push_back(x); exVec.push_back(1.0); @@ -3878,8 +3643,7 @@ Bool_t PRunDataHandler::ReadDBFile() // variables needed to tokenize strings TString tstr; - TObjString *ostr; - TObjArray *tokens = nullptr; + std::vector tokens; while (!f.eof()) { // get next line from file @@ -3915,16 +3679,9 @@ Bool_t PRunDataHandler::ReadDBFile() dbTag = 4; // filter out all data tags - tokens = workStr.Tokenize(" ,\t"); - for (Int_t i=1; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - runData.fDataNonMusr.AppendDataTag(ostr->GetString()); - } - - // clean up tokens - if (tokens) { - delete tokens; - tokens = nullptr; + tokens = PStringUtils::Split(workStr.Data(), " ,\t"); + for (UInt_t i=1; i(tokens->At(0)); - if (!ostr->GetString().IsFloat()) { + tokens = PStringUtils::Split(workStr.Data(), ","); + if (!TString(tokens[0]).IsFloat()) { labelledFormat = true; } else { labelledFormat = false; } - // clean up tokens - if (tokens) { - delete tokens; - tokens = nullptr; - } // prepare data vector for use PDoubleVector dummy; @@ -3990,15 +3741,13 @@ Bool_t PRunDataHandler::ReadDBFile() return false; } // split string in tokens - tokens = workStr.Tokenize(","); // line has structure: runNo,,, runTitle - ostr = dynamic_cast(tokens->At(0)); - tstr = ostr->GetString(); + tokens = PStringUtils::Split(workStr.Data(), ","); // line has structure: runNo,,, runTitle + tstr = TString(tokens[0]); if (!tstr.IsFloat()) { std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; std::cerr << std::endl << ">> " << workStr.Data(); std::cerr << std::endl << ">> Expected db-data line with structure: runNo,,, runTitle"; std::cerr << std::endl << ">> runNo = " << tstr.Data() << ", seems to be not a number."; - delete tokens; return false; } val = tstr.Atof(); @@ -4008,35 +3757,30 @@ Bool_t PRunDataHandler::ReadDBFile() // remove all possible spaces workStr.ReplaceAll(" ", ""); // split string in tokens - tokens = workStr.Tokenize("=,"); // line has structure: tag = val,err1,err2, - if (tokens->GetEntries() < 3) { + tokens = PStringUtils::Split(workStr.Data(), "=,"); // line has structure: tag = val,err1,err2, + if (tokens.size() < 3) { std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; std::cerr << std::endl << ">> " << workStr.Data(); std::cerr << std::endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\"; - delete tokens; return false; } - ostr = dynamic_cast(tokens->At(0)); - tstr = ostr->GetString(); + tstr = TString(tokens[0]); idx = GetDataTagIndex(tstr, runData.fDataNonMusr.GetDataTags()); if (idx == -1) { std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; std::cerr << std::endl << ">> " << workStr.Data(); std::cerr << std::endl << ">> data tag error: " << tstr.Data() << " seems not present in the data tag list"; - delete tokens; return false; } - switch (tokens->GetEntries()) { + switch (tokens.size()) { case 3: // tag = val,,, - ostr = dynamic_cast(tokens->At(1)); - tstr = ostr->GetString(); + tstr = TString(tokens[1]); if (!tstr.IsFloat()) { std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; std::cerr << std::endl << ">> " << workStr.Data(); std::cerr << std::endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\"; std::cerr << std::endl << ">> val = " << tstr.Data() << ", seems to be not a number."; - delete tokens; return false; } val = tstr.Atof(); @@ -4046,27 +3790,23 @@ Bool_t PRunDataHandler::ReadDBFile() case 4: // tag = val,err,, case 5: // tag = val,err1,err2, // handle val - ostr = dynamic_cast(tokens->At(1)); - tstr = ostr->GetString(); + tstr = TString(tokens[1]); if (!tstr.IsFloat()) { std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; std::cerr << std::endl << ">> " << workStr.Data(); std::cerr << std::endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\"; std::cerr << std::endl << ">> val = " << tstr.Data() << ", seems to be not a number."; - delete tokens; return false; } val = tstr.Atof(); runData.fDataNonMusr.AppendSubData(idx, val); // handle err1 (err2 will be ignored for the time being) - ostr = dynamic_cast(tokens->At(2)); - tstr = ostr->GetString(); + tstr = TString(tokens[2]); if (!tstr.IsFloat()) { std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; std::cerr << std::endl << ">> " << workStr.Data(); std::cerr << std::endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\"; std::cerr << std::endl << ">> err1 = " << tstr.Data() << ", seems to be not a number."; - delete tokens; return false; } val = tstr.Atof(); @@ -4076,42 +3816,37 @@ Bool_t PRunDataHandler::ReadDBFile() std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; std::cerr << std::endl << ">> " << workStr.Data(); std::cerr << std::endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\"; - delete tokens; return false; } } } 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() != static_cast(3*runData.fDataNonMusr.GetDataTags()->size()+1)) { + tokens = PStringUtils::Split(workStr.Data(), ","); // line has structure: val1, err11, err12, ..., valn, errn1, errn2, runNo, , , , runTitle + if (tokens.size() != 3*runData.fDataNonMusr.GetDataTags()->size()+1) { std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; std::cerr << std::endl << ">> " << workStr.Data(); std::cerr << std::endl << ">> Expected db-data line with structure: val1, err11, err12, ..., valn, errn1, errn2, runNo, , , , runTitle"; - std::cerr << std::endl << ">> found = " << tokens->GetEntries() << " tokens, however expected " << 3*runData.fDataNonMusr.GetDataTags()->size()+1; + std::cerr << std::endl << ">> found = " << tokens.size() << " tokens, however expected " << 3*runData.fDataNonMusr.GetDataTags()->size()+1; std::cerr << std::endl << ">> Perhaps there are commas without space inbetween, like 12.3,, 3.2,..."; - delete tokens; return false; } // extract data Int_t j=0; - for (Int_t i=0; iGetEntries()-1; i+=3) { + for (UInt_t i=0; i+1(tokens->At(i)); - tstr = ostr->GetString(); + tstr = TString(tokens[i]); if (!tstr.IsFloat()) { std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; std::cerr << std::endl << ">> " << workStr.Data(); std::cerr << std::endl << ">> Expected db-data line with structure: val1, err11, err12, ..., valn, errn1, errn2, runNo, , , , runTitle"; std::cerr << std::endl << ">> value=" << tstr.Data() << " seems not to be a number"; - delete tokens; return false; } runData.fDataNonMusr.AppendSubData(j, tstr.Atof()); // handle 1st error if present (2nd will be ignored for now) - ostr = dynamic_cast(tokens->At(i+1)); - tstr = ostr->GetString(); + tstr = TString(tokens[i+1]); if (tstr.IsWhitespace()) { runData.fDataNonMusr.AppendSubErrData(j, 1.0); } else if (tstr.IsFloat()) { @@ -4121,7 +3856,6 @@ Bool_t PRunDataHandler::ReadDBFile() std::cerr << std::endl << ">> " << workStr.Data(); std::cerr << std::endl << ">> Expected db-data line with structure: val1, err11, err12, ..., valn, errn1, errn2, runNo, , , , runTitle"; std::cerr << std::endl << ">> error1=" << tstr.Data() << " seems not to be a number"; - delete tokens; return false; } j++; @@ -4141,10 +3875,6 @@ Bool_t PRunDataHandler::ReadDBFile() std::cerr << std::endl << ">> number of LABELS found = " << runData.fDataNonMusr.GetLabels()->size(); std::cerr << std::endl << ">> number of Data tags found = " << runData.fDataNonMusr.GetDataTags()->size(); std::cerr << std::endl << ">> They have to be equal!!"; - if (tokens) { - delete tokens; - tokens = nullptr; - } return false; } @@ -4168,12 +3898,6 @@ Bool_t PRunDataHandler::ReadDBFile() } } - // clean up tokens - if (tokens) { - delete tokens; - tokens = nullptr; - } - // keep run name runData.SetRunName(fRunName); @@ -4218,8 +3942,7 @@ Bool_t PRunDataHandler::ReadDatFile() // variables needed to tokenize strings TString tstr; - TObjString *ostr; - TObjArray *tokens = nullptr; + std::vector tokens; UInt_t noOfDataSets = 0, noOfEntries = 0; PBoolVector isData; @@ -4239,8 +3962,8 @@ Bool_t PRunDataHandler::ReadDatFile() if (line.IsWhitespace()) continue; - tokens = line.Tokenize(" \t"); - if (tokens == nullptr) { // error + tokens = PStringUtils::Split(line.Data(), " \t"); + if (tokens.empty()) { // 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; @@ -4253,10 +3976,9 @@ Bool_t PRunDataHandler::ReadDatFile() // 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(); + noOfEntries = tokens.size(); + for (UInt_t i=0; iGetEntries() != noOfEntries) { // error - std::cerr << std::endl << ">> PRunDataHandler::ReadDatFile **ERROR** data set with wrong number of entries: " << tokens->GetEntries() << ", should be " << noOfEntries << "."; + if (tokens.size() != noOfEntries) { // error + std::cerr << std::endl << ">> PRunDataHandler::ReadDatFile **ERROR** data set with wrong number of entries: " << tokens.size() << ", should be " << noOfEntries << "."; std::cerr << std::endl << ">> in line: " << lineNo; std::cerr << std::endl << ">> line: '" << line << "'."; std::cerr << std::endl; @@ -4285,8 +4007,7 @@ Bool_t PRunDataHandler::ReadDatFile() UInt_t idx = 0; for (UInt_t i=0; i(tokens->At(i)); - tstr = ostr->GetString(); + tstr = TString(tokens[i]); 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; @@ -4310,11 +4031,6 @@ Bool_t PRunDataHandler::ReadDatFile() } } } - // cleanup - if (tokens) { - delete tokens; - tokens = nullptr; - } } f.close(); @@ -6636,8 +6352,6 @@ TString PRunDataHandler::FileNameFromTemplate(TString &fileNameTemplate, Int_t r { TString result(""); - TObjArray *tok=nullptr; - TObjString *ostr; TString str; // check year string @@ -6660,19 +6374,18 @@ TString PRunDataHandler::FileNameFromTemplate(TString &fileNameTemplate, Int_t r } // tokenize template string - tok = fileNameTemplate.Tokenize("[]"); - if (tok == nullptr) { + std::vector tok = PStringUtils::Split(fileNameTemplate.Data(), "[]"); + if (tok.empty()) { std::cerr << std::endl << ">> PRunDataHandler::FileNameFromTemplate: **ERROR** couldn't tokenize template!" << std::endl; return result; } - if (tok->GetEntries()==1) { + if (tok.size()==1) { std::cerr << std::endl << ">> PRunDataHandler::FileNameFromTemplate: **WARNING** template without tags." << std::endl; } // go through the tokens and generate the result string - for (Int_t i=0; iGetEntries(); i++) { - ostr = dynamic_cast(tok->At(i)); - str = ostr->GetString(); + for (UInt_t i=0; i +#include +#include #include -#include -#include +#include "PStringUtils.h" #include "PRunMuMinus.h" //-------------------------------------------------------------------------- @@ -383,7 +384,7 @@ Double_t PRunMuMinus::CalcMaxLikelihood(const std::vector& par) Int_t chunk = (fEndTimeBin - fStartTimeBin)/omp_get_num_procs(); if (chunk < 10) chunk = 10; - #pragma omp parallel for default(shared) private(i,time,theo,data) schedule(dynamic,chunk) reduction(-:mllh) + #pragma omp parallel for default(shared) private(i,time,theo,data) schedule(dynamic,chunk) reduction(+:mllh) #endif for (i=fStartTimeBin; i < fEndTimeBin; ++i) { time = fData.GetDataTimeStart() + static_cast(i)*fData.GetDataTimeStep(); @@ -448,18 +449,15 @@ UInt_t PRunMuMinus::GetNoOfFitBins() */ void PRunMuMinus::SetFitRangeBin(const TString fitRange) { - TObjArray *tok = nullptr; - TObjString *ostr = nullptr; TString str; Ssiz_t idx = -1; Int_t offset = 0; - tok = fitRange.Tokenize(" \t"); + std::vector tok = PStringUtils::Split(fitRange.Data(), " \t"); - if (tok->GetEntries() == 3) { // structure FIT_RANGE fgb+n0 lgb-n1 + if (tok.size() == 3) { // structure FIT_RANGE fgb+n0 lgb-n1 // handle fgb+n0 entry - ostr = dynamic_cast(tok->At(1)); - str = ostr->GetString(); + str = tok[1]; // check if there is an offset present idx = str.First("+"); if (idx != -1) { // offset present @@ -470,8 +468,7 @@ void PRunMuMinus::SetFitRangeBin(const TString fitRange) fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; // handle lgb-n1 entry - ostr = dynamic_cast(tok->At(2)); - str = ostr->GetString(); + str = tok[2]; // check if there is an offset present idx = str.First("-"); if (idx != -1) { // offset present @@ -480,16 +477,15 @@ void PRunMuMinus::SetFitRangeBin(const TString fitRange) offset = str.Atoi(); } fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution; - } else if ((tok->GetEntries() > 3) && (tok->GetEntries() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]] - Int_t pos = 2*(fRunNo+1)-1; + } else if ((tok.size() > 3) && (tok.size() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]] + UInt_t pos = 2*(fRunNo+1)-1; - if (pos + 1 >= tok->GetEntries()) { + if (pos + 1 >= tok.size()) { std::cerr << std::endl << ">> PRunMuMinus::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'"; std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; } else { // handle fgb+n0 entry - ostr = dynamic_cast(tok->At(pos)); - str = ostr->GetString(); + str = tok[pos]; // check if there is an offset present idx = str.First("+"); if (idx != -1) { // offset present @@ -500,8 +496,7 @@ void PRunMuMinus::SetFitRangeBin(const TString fitRange) fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; // handle lgb-n1 entry - ostr = dynamic_cast(tok->At(pos+1)); - str = ostr->GetString(); + str = tok[pos+1]; // check if there is an offset present idx = str.First("-"); if (idx != -1) { // offset present @@ -515,11 +510,6 @@ void PRunMuMinus::SetFitRangeBin(const TString fitRange) std::cerr << std::endl << ">> PRunMuMinus::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'"; std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; } - - // clean up - if (tok) { - delete tok; - } } //-------------------------------------------------------------------------- diff --git a/src/classes/PRunSingleHisto.cpp b/src/classes/PRunSingleHisto.cpp index ebe601ea..83deca84 100644 --- a/src/classes/PRunSingleHisto.cpp +++ b/src/classes/PRunSingleHisto.cpp @@ -38,12 +38,13 @@ #include #include #include +#include +#include #include -#include -#include #include "PMusr.h" +#include "PStringUtils.h" #include "PRunSingleHisto.h" //-------------------------------------------------------------------------- @@ -439,7 +440,7 @@ Double_t PRunSingleHisto::CalcChiSquareExpected(const std::vector& par * OpenMP Parallelization: * - Dynamic scheduling with chunk size = (N_bins / N_processors), minimum 10 * - Private variables per thread: i, time, theo, data - * - Reduction performed on mllh sum (note: reduction(-:mllh) for subtraction) + * - Reduction performed on mllh sum (reduction(+:mllh)) * * When to Use Maximum Likelihood vs. χ²: * - Use likelihood: Low count rates (< 100 counts/bin), asymmetric errors @@ -515,7 +516,7 @@ Double_t PRunSingleHisto::CalcMaxLikelihood(const std::vector& par) Int_t chunk = (fEndTimeBin - fStartTimeBin)/omp_get_num_procs(); if (chunk < 10) chunk = 10; - #pragma omp parallel for default(shared) private(i,time,theo,data) schedule(dynamic,chunk) reduction(-:mllh) + #pragma omp parallel for default(shared) private(i,time,theo,data) schedule(dynamic,chunk) reduction(+:mllh) #endif for (i=fStartTimeBin; i(i)*fData.GetDataTimeStep(); @@ -650,7 +651,7 @@ Double_t PRunSingleHisto::CalcMaxLikelihoodExpected(const std::vector& Int_t chunk = (fEndTimeBin - fStartTimeBin)/omp_get_num_procs(); if (chunk < 10) chunk = 10; - #pragma omp parallel for default(shared) private(i,time,theo,data) schedule(dynamic,chunk) reduction(-:mllh) + #pragma omp parallel for default(shared) private(i,time,theo,data) schedule(dynamic,chunk) reduction(+:mllh) #endif for (i=fStartTimeBin; i(i)*fData.GetDataTimeStep(); @@ -844,18 +845,15 @@ UInt_t PRunSingleHisto::GetNoOfFitBins() */ void PRunSingleHisto::SetFitRangeBin(const TString fitRange) { - TObjArray *tok = nullptr; - TObjString *ostr = nullptr; TString str; Ssiz_t idx = -1; Int_t offset = 0; - tok = fitRange.Tokenize(" \t"); + std::vector tok = PStringUtils::Split(fitRange.Data(), " \t"); - if (tok->GetEntries() == 3) { // structure FIT_RANGE fgb+n0 lgb-n1 + if (tok.size() == 3) { // structure FIT_RANGE fgb+n0 lgb-n1 // handle fgb+n0 entry - ostr = dynamic_cast(tok->At(1)); - str = ostr->GetString(); + str = tok[1]; // check if there is an offset present idx = str.First("+"); if (idx != -1) { // offset present @@ -866,8 +864,7 @@ void PRunSingleHisto::SetFitRangeBin(const TString fitRange) fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; // handle lgb-n1 entry - ostr = dynamic_cast(tok->At(2)); - str = ostr->GetString(); + str = tok[2]; // check if there is an offset present idx = str.First("-"); if (idx != -1) { // offset present @@ -876,16 +873,15 @@ void PRunSingleHisto::SetFitRangeBin(const TString fitRange) offset = str.Atoi(); } fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution; - } else if ((tok->GetEntries() > 3) && (tok->GetEntries() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]] - Int_t pos = 2*(fRunNo+1)-1; + } else if ((tok.size() > 3) && (tok.size() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]] + UInt_t pos = 2*(fRunNo+1)-1; - if (pos + 1 >= tok->GetEntries()) { + if (pos + 1 >= tok.size()) { std::cerr << std::endl << ">> PRunSingleHisto::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'"; std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; } else { // handle fgb+n0 entry - ostr = dynamic_cast(tok->At(pos)); - str = ostr->GetString(); + str = tok[pos]; // check if there is an offset present idx = str.First("+"); if (idx != -1) { // offset present @@ -896,8 +892,7 @@ void PRunSingleHisto::SetFitRangeBin(const TString fitRange) fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; // handle lgb-n1 entry - ostr = dynamic_cast(tok->At(pos+1)); - str = ostr->GetString(); + str = tok[pos+1]; // check if there is an offset present idx = str.First("-"); if (idx != -1) { // offset present @@ -911,11 +906,6 @@ void PRunSingleHisto::SetFitRangeBin(const TString fitRange) std::cerr << std::endl << ">> PRunSingleHisto::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'"; std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; } - - // clean up - if (tok) { - delete tok; - } } //-------------------------------------------------------------------------- @@ -2430,23 +2420,15 @@ Bool_t PRunSingleHisto::IsScaleN0AndBkg() PMsrLines *cmd = fMsrInfo->GetMsrCommands(); for (UInt_t i=0; isize(); i++) { if (cmd->at(i).fLine.Contains("SCALE_N0_BKG", TString::kIgnoreCase)) { - TObjArray *tokens = nullptr; - TObjString *ostr = nullptr; - TString str; - tokens = cmd->at(i).fLine.Tokenize(" \t"); - if (tokens->GetEntries() != 2) { + std::vector tokens = PStringUtils::Split(cmd->at(i).fLine.Data(), " \t"); + if (tokens.size() != 2) { std::cerr << std::endl << ">> PRunSingleHisto::IsScaleN0AndBkg(): **WARNING** Found uncorrect 'SCALE_N0_BKG' command, will ignore it."; std::cerr << std::endl << ">> Allowed commands: SCALE_N0_BKG TRUE | FALSE" << std::endl; return willScale; } - ostr = dynamic_cast(tokens->At(1)); - str = ostr->GetString(); - if (!str.CompareTo("FALSE", TString::kIgnoreCase)) { + if (PStringUtils::IsEqualNoCase(tokens[1], "FALSE")) { willScale = false; } - // clean up - if (tokens) - delete tokens; } } diff --git a/src/classes/PRunSingleHistoRRF.cpp b/src/classes/PRunSingleHistoRRF.cpp index c5119c2d..8d160656 100644 --- a/src/classes/PRunSingleHistoRRF.cpp +++ b/src/classes/PRunSingleHistoRRF.cpp @@ -39,13 +39,14 @@ #include #include #include +#include +#include #include -#include -#include #include #include "PMusr.h" +#include "PStringUtils.h" #include "PFourier.h" #include "PRunSingleHistoRRF.h" @@ -528,18 +529,15 @@ UInt_t PRunSingleHistoRRF::GetNoOfFitBins() */ void PRunSingleHistoRRF::SetFitRangeBin(const TString fitRange) { - TObjArray *tok = nullptr; - TObjString *ostr = nullptr; TString str; Ssiz_t idx = -1; Int_t offset = 0; - tok = fitRange.Tokenize(" \t"); + std::vector tok = PStringUtils::Split(fitRange.Data(), " \t"); - if (tok->GetEntries() == 3) { // structure FIT_RANGE fgb+n0 lgb-n1 + if (tok.size() == 3) { // structure FIT_RANGE fgb+n0 lgb-n1 // handle fgb+n0 entry - ostr = dynamic_cast(tok->At(1)); - str = ostr->GetString(); + str = tok[1]; // check if there is an offset present idx = str.First("+"); if (idx != -1) { // offset present @@ -550,8 +548,7 @@ void PRunSingleHistoRRF::SetFitRangeBin(const TString fitRange) fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; // handle lgb-n1 entry - ostr = dynamic_cast(tok->At(2)); - str = ostr->GetString(); + str = tok[2]; // check if there is an offset present idx = str.First("-"); if (idx != -1) { // offset present @@ -560,16 +557,15 @@ void PRunSingleHistoRRF::SetFitRangeBin(const TString fitRange) offset = str.Atoi(); } fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution; - } else if ((tok->GetEntries() > 3) && (tok->GetEntries() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]] - Int_t pos = 2*(fRunNo+1)-1; + } else if ((tok.size() > 3) && (tok.size() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]] + UInt_t pos = 2*(fRunNo+1)-1; - if (pos + 1 >= tok->GetEntries()) { + if (pos + 1 >= tok.size()) { std::cerr << std::endl << ">> PRunSingleHistoRRF::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'"; std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; } else { // handle fgb+n0 entry - ostr = dynamic_cast(tok->At(pos)); - str = ostr->GetString(); + str = tok[pos]; // check if there is an offset present idx = str.First("+"); if (idx != -1) { // offset present @@ -580,8 +576,7 @@ void PRunSingleHistoRRF::SetFitRangeBin(const TString fitRange) fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; // handle lgb-n1 entry - ostr = dynamic_cast(tok->At(pos+1)); - str = ostr->GetString(); + str = tok[pos+1]; // check if there is an offset present idx = str.First("-"); if (idx != -1) { // offset present @@ -595,11 +590,6 @@ void PRunSingleHistoRRF::SetFitRangeBin(const TString fitRange) std::cerr << std::endl << ">> PRunSingleHistoRRF::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'"; std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; } - - // clean up - if (tok) { - delete tok; - } } //-------------------------------------------------------------------------- diff --git a/src/classes/PStartupHandler.cpp b/src/classes/PStartupHandler.cpp index 47bb48ca..7907e0ec 100644 --- a/src/classes/PStartupHandler.cpp +++ b/src/classes/PStartupHandler.cpp @@ -34,13 +34,12 @@ #include #include -#include -#include #include #include #include #include "PStartupHandler.h" +#include "PStringUtils.h" ClassImpQ(PStartupHandler) @@ -451,8 +450,6 @@ void PStartupHandler::OnEndElement(const Char_t *str) */ void PStartupHandler::OnCharacters(const Char_t *str) { - TObjArray *tokens; - TObjString *ostr; TString tstr; Int_t color, r, g, b, ival; @@ -481,60 +478,44 @@ void PStartupHandler::OnCharacters(const Char_t *str) } break; case eColor: - // check that str is a rbg code - tstr = TString(str); - tokens = tstr.Tokenize(","); - // check that there any tokens - if (!tokens) { - std::cerr << std::endl << "PStartupHandler **WARNING** '" << str << "' is not a rbg code, will ignore it"; - std::cerr << std::endl; - return; + { + // check that str is a rbg code + std::vector rgb = PStringUtils::Split(str, ","); + // check there is the right number of tokens + if (rgb.size() != 3) { + std::cerr << std::endl << "PStartupHandler **WARNING** '" << str << "' is not a rbg code, will ignore it"; + std::cerr << std::endl; + return; + } + // get r + if (PStringUtils::IsInt(rgb[0])) { + r = PStringUtils::ToInt(rgb[0]); + } else { + std::cerr << std::endl << "PStartupHandler **WARNING** r within the rgb code is not a number, will ignore it"; + std::cerr << std::endl; + return; + } + // get g + if (PStringUtils::IsInt(rgb[1])) { + g = PStringUtils::ToInt(rgb[1]); + } else { + std::cerr << std::endl << "PStartupHandler **WARNING** g within the rgb code is not a number, will ignore it"; + std::cerr << std::endl; + return; + } + // get b + if (PStringUtils::IsInt(rgb[2])) { + b = PStringUtils::ToInt(rgb[2]); + } else { + std::cerr << std::endl << "PStartupHandler **WARNING** b within the rgb code is not a number, will ignore it"; + std::cerr << std::endl; + return; + } + // generate the ROOT color code based on str + color = TColor::GetColor(r,g,b); + // add the color code to the color list + fColorList.push_back(color); } - // check there is the right number of tokens - if (tokens->GetEntries() != 3) { - std::cerr << std::endl << "PStartupHandler **WARNING** '" << str << "' is not a rbg code, will ignore it"; - std::cerr << std::endl; - return; - } - // get r - ostr = dynamic_cast(tokens->At(0)); - tstr = ostr->GetString(); - if (tstr.IsDigit()) { - r = tstr.Atoi(); - } else { - std::cerr << std::endl << "PStartupHandler **WARNING** r within the rgb code is not a number, will ignore it"; - std::cerr << std::endl; - return; - } - // get g - ostr = dynamic_cast(tokens->At(1)); - tstr = ostr->GetString(); - if (tstr.IsDigit()) { - g = tstr.Atoi(); - } else { - std::cerr << std::endl << "PStartupHandler **WARNING** g within the rgb code is not a number, will ignore it"; - std::cerr << std::endl; - return; - } - // get b - ostr = dynamic_cast(tokens->At(2)); - tstr = ostr->GetString(); - if (tstr.IsDigit()) { - b = tstr.Atoi(); - } else { - std::cerr << std::endl << "PStartupHandler **WARNING** b within the rgb code is not a number, will ignore it"; - std::cerr << std::endl; - return; - } - // clean up tokens - if (tokens) { - delete tokens; - tokens = nullptr; - } - // generate the ROOT color code based on str - color = TColor::GetColor(r,g,b); - // add the color code to the color list - fColorList.push_back(color); break; case eUnits: tstr = TString(str); diff --git a/src/classes/PStringUtils.cpp b/src/classes/PStringUtils.cpp new file mode 100644 index 00000000..2a588c7a --- /dev/null +++ b/src/classes/PStringUtils.cpp @@ -0,0 +1,275 @@ +/*************************************************************************** + + PStringUtils.cpp + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007-2026 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 +#include +#include +#include + +#include "PStringUtils.h" + +//-------------------------------------------------------------------------- +// Split (static) +//-------------------------------------------------------------------------- +/** + *

Splits a string into tokens on any character contained in delimiters, + * skipping empty tokens. Mirrors the semantics of TString::Tokenize(). + * + * \param str input string to be tokenized + * \param delimiters set of delimiter characters + * \return vector of tokens (without the delimiters) + */ +std::vector PStringUtils::Split(const std::string &str, const std::string &delimiters) +{ + std::vector tokens; + std::string::size_type start = str.find_first_not_of(delimiters); + while (start != std::string::npos) { + std::string::size_type end = str.find_first_of(delimiters, start); + if (end == std::string::npos) { + tokens.push_back(str.substr(start)); + break; + } + tokens.push_back(str.substr(start, end - start)); + start = str.find_first_not_of(delimiters, end); + } + return tokens; +} + +//-------------------------------------------------------------------------- +// IsInt (static) +//-------------------------------------------------------------------------- +/** + *

Returns true if the string is an integer literal, i.e. a non-empty + * sequence of decimal digits with an optional single leading sign (+/-). + * This is slightly more permissive than TString::IsDigit(), which rejects a + * sign, so that negative/positive integers such as "-5" or "+42" are also + * recognised. + * + * \param str string to be checked + * \return true if str is a (possibly signed) integer + */ +bool PStringUtils::IsInt(const std::string &str) +{ + // all characters must be digits or whitespace, with an optional single + // leading sign (+/-) preceding the digits, and there must be at least one + // digit (surrounding/embedded whitespace is tolerated, e.g. for tokens + // split on ',' or ';' only). + bool hasDigit = false; + bool hasSign = false; + for (char c : str) { + if (std::isdigit(static_cast(c))) { + hasDigit = true; + } else if (c == '+' || c == '-') { + // a sign is only valid before any digit and may appear at most once + if (hasDigit || hasSign) + return false; + hasSign = true; + } else if (!std::isspace(static_cast(c))) { + return false; + } + } + return hasDigit; +} + +//-------------------------------------------------------------------------- +// IsFloat (static) +//-------------------------------------------------------------------------- +/** + *

Returns true if the string is a complete integer or floating point + * literal (optionally signed, with decimal point and/or exponent). Mirrors + * the semantics of TString::IsFloat() for the relevant cases. + * + * \param str string to be checked + * \return true if str is a valid number + */ +bool PStringUtils::IsFloat(const std::string &str) +{ + // mirror TString::IsFloat(): surrounding whitespace is ignored (e.g. for + // tokens split on ',' or ';' only), then a complete number is required. + const std::string ws(" \t\n\r\f\v"); + std::string::size_type b = str.find_first_not_of(ws); + if (b == std::string::npos) + return false; + std::string::size_type e = str.find_last_not_of(ws); + const std::string t = str.substr(b, e - b + 1); + + std::string::size_type i = 0; + if (t[i] == '+' || t[i] == '-') + ++i; + // reject things like "inf"/"nan" which strtod would otherwise accept + if (i >= t.size() || !(std::isdigit(static_cast(t[i])) || t[i] == '.')) + return false; + const char *begin = t.c_str(); + char *end = nullptr; + std::strtod(begin, &end); + return end == begin + t.size(); +} + +//-------------------------------------------------------------------------- +// ToInt (static) +//-------------------------------------------------------------------------- +/** + *

Converts the leading part of the string to an int (base 10), mirroring + * TString::Atoi(). Returns 0 if no conversion is possible. + * + *

Uses std::from_chars so that conversion errors can be reported through + * the optional \a ok out-parameter: it is set to true when a valid integer + * was parsed (leading whitespace is skipped) and to false otherwise (no + * digits present, or the value is out of int range). Trailing non-numeric + * characters are ignored, as with TString::Atoi(). A null \a ok preserves the + * historic fire-and-forget behaviour. + * + * \param str string to be converted + * \param ok optional out-parameter signalling conversion success + * \return converted integer value (0 on error) + */ +int PStringUtils::ToInt(const std::string &str, bool *ok) +{ + // mirror TString::Atoi(): skip leading whitespace, then parse the leading + // integer (a possible sign followed by decimal digits). + const char *begin = str.c_str(); + const char *end = begin + str.size(); + while (begin != end && std::isspace(static_cast(*begin))) + ++begin; + + int value = 0; + const std::from_chars_result res = std::from_chars(begin, end, value); + if (ok != nullptr) + *ok = (res.ec == std::errc{}); + + return value; +} + +//-------------------------------------------------------------------------- +// ToDouble (static) +//-------------------------------------------------------------------------- +/** + *

Converts the leading part of the string to a double, mirroring + * TString::Atof(). Returns 0.0 if no conversion is possible. + * + *

Like ToInt(), conversion errors can be reported through the optional + * \a ok out-parameter: it is set to true when a value was parsed and to + * false otherwise (no number present, or the value is out of range). This + * lets callers distinguish a legitimate 0.0 from a failed conversion. + * strtod() (rather than std::from_chars) is used so that the accepted input + * set stays identical to TString::Atof() (leading whitespace is skipped, a + * leading '+' is honoured, trailing characters are ignored). A null \a ok + * preserves the historic fire-and-forget behaviour. + * + * \param str string to be converted + * \param ok optional out-parameter signalling conversion success + * \return converted double value (0.0 on error) + */ +double PStringUtils::ToDouble(const std::string &str, bool *ok) +{ + const char *begin = str.c_str(); + char *end = nullptr; + errno = 0; + const double value = std::strtod(begin, &end); + if (ok != nullptr) + *ok = (end != begin) && (errno != ERANGE); + + return value; +} + +//-------------------------------------------------------------------------- +// IsEqualNoCase (static) +//-------------------------------------------------------------------------- +/** + *

Case-insensitive full-string equality, mirroring + * TString::CompareTo(..., TString::kIgnoreCase) == 0. + * + * \param a first string + * \param b second string + * \return true if a and b are equal ignoring case + */ +bool PStringUtils::IsEqualNoCase(const std::string &a, const std::string &b) +{ + if (a.size() != b.size()) + return false; + for (std::string::size_type i = 0; i < a.size(); ++i) { + if (std::tolower(static_cast(a[i])) != + std::tolower(static_cast(b[i]))) + return false; + } + return true; +} + +//-------------------------------------------------------------------------- +// ContainsNoCase (static) +//-------------------------------------------------------------------------- +/** + *

Case-insensitive substring search, mirroring + * TString::Contains(..., TString::kIgnoreCase). + * + * \param haystack string to be searched in + * \param needle substring to be searched for + * \return true if needle is contained in haystack ignoring case + */ +bool PStringUtils::ContainsNoCase(const std::string &haystack, const std::string &needle) +{ + if (needle.empty()) + return true; + if (needle.size() > haystack.size()) + return false; + auto toLower = [](unsigned char c) { return std::tolower(c); }; + for (std::string::size_type i = 0; i + needle.size() <= haystack.size(); ++i) { + std::string::size_type j = 0; + for (; j < needle.size(); ++j) { + if (toLower(haystack[i+j]) != toLower(needle[j])) + break; + } + if (j == needle.size()) + return true; + } + return false; +} + +//-------------------------------------------------------------------------- +// BeginsWithNoCase (static) +//-------------------------------------------------------------------------- +/** + *

Case-insensitive prefix test, mirroring + * TString::BeginsWith(..., TString::kIgnoreCase). + * + * \param str string to be tested + * \param prefix prefix to be searched for + * \return true if str starts with prefix ignoring case + */ +bool PStringUtils::BeginsWithNoCase(const std::string &str, const std::string &prefix) +{ + if (prefix.size() > str.size()) + return false; + for (std::string::size_type i = 0; i < prefix.size(); ++i) { + if (std::tolower(static_cast(str[i])) != + std::tolower(static_cast(prefix[i]))) + return false; + } + return true; +} diff --git a/src/classes/PTheory.cpp b/src/classes/PTheory.cpp index 9ad72837..1bed428c 100644 --- a/src/classes/PTheory.cpp +++ b/src/classes/PTheory.cpp @@ -29,19 +29,19 @@ #include #include +#include #include #include #include #include -#include -#include #include #include #include #include "PMsrHandler.h" +#include "PStringUtils.h" #include "PTheory.h" #define SQRT_TWO 1.41421356237 @@ -169,18 +169,14 @@ PTheory::PTheory(PMsrHandler *msrInfo, UInt_t runNo, const Bool_t hasParent) : f str.Resize(index); // tokenize line - TObjArray *tokens; - TObjString *ostr; - - tokens = str.Tokenize(" \t"); - if (!tokens) { + std::vector tokens = PStringUtils::Split(str.Data(), " \t"); + if (tokens.empty()) { std::cerr << std::endl << ">> PTheory::PTheory: **SEVERE ERROR** Couldn't tokenize theory block line " << line->fLineNo << "."; std::cerr << std::endl << ">> line content: " << line->fLine.Data(); std::cerr << std::endl; exit(0); } - ostr = dynamic_cast(tokens->At(0)); - str = ostr->GetString(); + str = tokens[0]; // search the theory function UInt_t idx = SearchDataBase(str); @@ -195,11 +191,11 @@ PTheory::PTheory(PMsrHandler *msrInfo, UInt_t runNo, const Bool_t hasParent) : f } // line is a valid function, hence analyze parameters - if ((static_cast(tokens->GetEntries()-1) < fNoOfParam) && + if ((static_cast(tokens.size()-1) < fNoOfParam) && ((idx != THEORY_USER_FCN) && (idx != THEORY_POLYNOM))) { std::cerr << std::endl << ">> PTheory::PTheory: **ERROR** Theory line '" << line->fLine.Data() << "'"; std::cerr << std::endl << ">> in line no " << line->fLineNo; - std::cerr << std::endl << ">> expecting " << fgTheoDataBase[idx].fNoOfParam << ", but found " << tokens->GetEntries()-1; + std::cerr << std::endl << ">> expecting " << fgTheoDataBase[idx].fNoOfParam << ", but found " << tokens.size()-1; std::cerr << std::endl; fValid = false; } @@ -209,9 +205,8 @@ PTheory::PTheory(PMsrHandler *msrInfo, UInt_t runNo, const Bool_t hasParent) : f Int_t status; UInt_t value; Bool_t ok = false; - for (Int_t i=1; iGetEntries(); i++) { - ostr = dynamic_cast(tokens->At(i)); - str = ostr->GetString(); + for (UInt_t i=1; i> See line no " << line->fLineNo; std::cerr << std::endl; fValid = false; - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; - } return; } else if (!TClass::GetDict(fUserFcnClassName.Data())) { std::cerr << std::endl << ">> PTheory::PTheory: **ERROR** user function class '" << fUserFcnClassName.Data() << "' not found."; @@ -316,11 +306,6 @@ PTheory::PTheory(PMsrHandler *msrInfo, UInt_t runNo, const Bool_t hasParent) : f std::cerr << std::endl << ">> See line no " << line->fLineNo; std::cerr << std::endl; fValid = false; - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; - } return; } } @@ -347,12 +332,6 @@ PTheory::PTheory(PMsrHandler *msrInfo, UInt_t runNo, const Bool_t hasParent) : f } } } - - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; - } } //-------------------------------------------------------------------------- @@ -945,8 +924,6 @@ void PTheory::MakeCleanAndTidyTheoryBlock(PMsrLines *fullTheoryBlock) PMsrLineStructure *line; TString str, tidy; Char_t substr[256]; - TObjArray *tokens = nullptr; - TObjString *ostr = nullptr; Int_t idx = THEORY_UNDEFINED; for (UInt_t i=1; isize(); i++) { @@ -959,10 +936,11 @@ void PTheory::MakeCleanAndTidyTheoryBlock(PMsrLines *fullTheoryBlock) if (index > 0) // theory line comment present str.Resize(index); // tokenize line - tokens = str.Tokenize(" \t"); + std::vector tokens = PStringUtils::Split(str.Data(), " \t"); + if (tokens.empty()) + continue; // make a handable string out of the asymmetry token - ostr = dynamic_cast(tokens->At(0)); - str = ostr->GetString(); + str = tokens[0]; // check if the line is just a '+' if so nothing to be done if (str.Contains("+")) continue; @@ -987,14 +965,13 @@ void PTheory::MakeCleanAndTidyTheoryBlock(PMsrLines *fullTheoryBlock) if (idx == THEORY_UNDEFINED) return; // check that there enough tokens. This should not be necessay at this point but ... - if (static_cast(tokens->GetEntries()) < fgTheoDataBase[idx].fNoOfParam + 1) + if (static_cast(tokens.size()) < fgTheoDataBase[idx].fNoOfParam + 1) return; // make tidy string snprintf(substr, sizeof(substr), "%-10s", fgTheoDataBase[idx].fName.Data()); tidy = TString(substr); - for (Int_t j=1; jGetEntries(); j++) { - ostr = dynamic_cast(tokens->At(j)); - str = ostr->GetString(); + for (UInt_t j=1; j(tokens->GetEntries()) == fgTheoDataBase[idx].fNoOfParam + 1) // no tshift + if (static_cast(tokens.size()) == fgTheoDataBase[idx].fNoOfParam + 1) // no tshift tidy += fgTheoDataBase[idx].fComment; else tidy += fgTheoDataBase[idx].fCommentTimeShift; } // write tidy string back into theory block (*fullTheoryBlock)[i].fLine = tidy; - - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; - } } } @@ -1041,8 +1012,6 @@ void PTheory::MakeCleanAndTidyPolynom(UInt_t i, PMsrLines *fullTheoryBlock) { PMsrLineStructure *line; TString str, tidy; - TObjArray *tokens = nullptr; - TObjString *ostr; Char_t substr[256]; // init tidy @@ -1052,13 +1021,12 @@ void PTheory::MakeCleanAndTidyPolynom(UInt_t i, PMsrLines *fullTheoryBlock) // copy line content to str in order to remove comments str = line->fLine.Copy(); // tokenize line - tokens = str.Tokenize(" \t"); + std::vector tokens = PStringUtils::Split(str.Data(), " \t"); // check if comment is already present, and if yes ignore it by setting max correctly - Int_t max = tokens->GetEntries(); + Int_t max = static_cast(tokens.size()); for (Int_t j=1; j(tokens->At(j)); - str = ostr->GetString(); + str = tokens[j]; if (str.Contains("(")) { // comment present max=j; break; @@ -1066,8 +1034,7 @@ void PTheory::MakeCleanAndTidyPolynom(UInt_t i, PMsrLines *fullTheoryBlock) } for (Int_t j=1; j(tokens->At(j)); - str = ostr->GetString(); + str = tokens[j]; snprintf(substr, sizeof(substr), "%6s", str.Data()); tidy += TString(substr); } @@ -1077,12 +1044,6 @@ void PTheory::MakeCleanAndTidyPolynom(UInt_t i, PMsrLines *fullTheoryBlock) // write tidy string back into theory block (*fullTheoryBlock)[i].fLine = tidy; - - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; - } } //-------------------------------------------------------------------------- @@ -1104,8 +1065,6 @@ void PTheory::MakeCleanAndTidyUserFcn(UInt_t i, PMsrLines *fullTheoryBlock) { PMsrLineStructure *line; TString str, tidy; - TObjArray *tokens = nullptr; - TObjString *ostr; // init tidy tidy = TString("userFcn "); @@ -1114,22 +1073,15 @@ void PTheory::MakeCleanAndTidyUserFcn(UInt_t i, PMsrLines *fullTheoryBlock) // copy line content to str in order to remove comments str = line->fLine.Copy(); // tokenize line - tokens = str.Tokenize(" \t"); + std::vector tokens = PStringUtils::Split(str.Data(), " \t"); - for (Int_t j=1; jGetEntries(); j++) { - ostr = dynamic_cast(tokens->At(j)); - str = ostr->GetString(); + for (UInt_t j=1; j>= 1 ) ++inibits; - memcpy(pv, pini, inibits*sizeof *pini); + if( inibits > 0 ) + memcpy(pv, pini, inibits*sizeof *pini); pini += 8; for( bit = inibits; bit <= nbits; ++bit ) { diff --git a/src/include/PStringUtils.h b/src/include/PStringUtils.h new file mode 100644 index 00000000..01eeb4f0 --- /dev/null +++ b/src/include/PStringUtils.h @@ -0,0 +1,150 @@ +/*************************************************************************** + + PStringUtils.h + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007-2026 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. * + ***************************************************************************/ + +#ifndef _PSTRINGUTILS_H_ +#define _PSTRINGUTILS_H_ + +#include +#include + +//------------------------------------------------------------- +/** + * \brief Lightweight, dependency-free string utilities (pure C++17). + * + * PStringUtils collects small string helpers used throughout the musrfit + * suite, in particular for tokenizing and parsing the plain-text MSR file + * format. The implementation deliberately relies only on the C++ standard + * library (no ROOT) so that it can be reused freely. + * + * The provided helpers replicate the semantics of the corresponding + * ROOT TString methods that were previously used: + * - Split replaces TString::Tokenize() (+ TObjArray/TObjString) + * - IsInt replaces TString::IsDigit() + * - IsFloat replaces TString::IsFloat() + * - ToInt replaces TString::Atoi() + * - ToDouble replaces TString::Atof() + * - IsEqualNoCase replaces TString::CompareTo(..., TString::kIgnoreCase) + * + * All methods are static; the class is a pure namespace-like utility. + */ +class PStringUtils +{ + public: + /** + *

Splits a string into tokens on any character contained in + * delimiters, skipping empty tokens. Mirrors TString::Tokenize(). + * + * @param str input string to be tokenized + * @param delimiters set of delimiter characters + * @return vector of tokens (without the delimiters) + */ + static std::vector Split(const std::string &str, const std::string &delimiters); + + /** + *

Returns true if the string is a (possibly signed) integer literal, + * i.e. a non-empty sequence of decimal digits with an optional single + * leading sign (+/-). Slightly more permissive than TString::IsDigit(), + * which rejects a sign, so that e.g. "-5" is also recognised. + * + * @param str string to be checked + * @return true if str is a (possibly signed) integer + */ + static bool IsInt(const std::string &str); + + /** + *

Returns true if the string is a complete integer or floating point + * literal (optionally signed, with decimal point and/or exponent). + * Mirrors TString::IsFloat() for the relevant cases. + * + * @param str string to be checked + * @return true if str is a valid number + */ + static bool IsFloat(const std::string &str); + + /** + *

Converts the leading part of the string to an int (base 10). + * Mirrors TString::Atoi(). Returns 0 if no conversion is possible. + * + *

If \a ok is non-null it is set to true when a valid integer was + * parsed and to false on error (no digits, or value out of int range). + * This allows callers to distinguish a legitimate 0 from a failed + * conversion, which the bare return value cannot express. + * + * @param str string to be converted + * @param ok optional out-parameter signalling conversion success + * @return converted integer value (0 on error) + */ + static int ToInt(const std::string &str, bool *ok = nullptr); + + /** + *

Converts the leading part of the string to a double. + * Mirrors TString::Atof(). Returns 0.0 if no conversion is possible. + * + *

If \a ok is non-null it is set to true when a value was parsed and + * to false on error (no number, or value out of range), allowing callers + * to distinguish a legitimate 0.0 from a failed conversion. + * + * @param str string to be converted + * @param ok optional out-parameter signalling conversion success + * @return converted double value (0.0 on error) + */ + static double ToDouble(const std::string &str, bool *ok = nullptr); + + /** + *

Case-insensitive full-string equality. + * Mirrors TString::CompareTo(..., TString::kIgnoreCase) == 0. + * + * @param a first string + * @param b second string + * @return true if a and b are equal ignoring case + */ + static bool IsEqualNoCase(const std::string &a, const std::string &b); + + /** + *

Case-insensitive substring search. + * Mirrors TString::Contains(..., TString::kIgnoreCase). + * + * @param haystack string to be searched in + * @param needle substring to be searched for + * @return true if needle is contained in haystack ignoring case + */ + static bool ContainsNoCase(const std::string &haystack, const std::string &needle); + + /** + *

Case-insensitive prefix test. + * Mirrors TString::BeginsWith(..., TString::kIgnoreCase). + * + * @param str string to be tested + * @param prefix prefix to be searched for + * @return true if str starts with prefix ignoring case + */ + static bool BeginsWithNoCase(const std::string &str, const std::string &prefix); +}; + +#endif // _PSTRINGUTILS_H_ diff --git a/src/msr2msr.cpp b/src/msr2msr.cpp index d7f93e77..6852485c 100644 --- a/src/msr2msr.cpp +++ b/src/msr2msr.cpp @@ -35,8 +35,8 @@ #include #include -#include -#include + +#include "PStringUtils.h" //------------------------------------------------------------- // msr block header tags @@ -88,8 +88,6 @@ bool msr2msr_run(char *str, const std::size_t size) TString run(str); TString line(str); - TObjArray *tokens; - TObjString *ostr[2]; // for filtering run.ToUpper(); @@ -100,8 +98,8 @@ bool msr2msr_run(char *str, const std::size_t size) line.Remove(idx); // tokenize run - tokens = line.Tokenize(" \t"); - if (tokens->GetEntries() < 4) { + std::vector tokens = PStringUtils::Split(line.Data(), " \t"); + if (tokens.size() < 4) { std::cout << std::endl << "**ERROR**: Something is wrong with the RUN block header:"; std::cout << std::endl << " >> " << str; std::cout << std::endl << " >> no is created"; @@ -109,35 +107,22 @@ bool msr2msr_run(char *str, const std::size_t size) return false; } - if (tokens->GetEntries() == 5) { // already a new msr file, do only add the proper run comment + if (tokens.size() == 5) { // already a new msr file, do only add the proper run comment snprintf(str, size, "%s (name beamline institute data-file-format)", line.Data()); return true; } if (run.Contains("NEMU")) { - ostr[0] = dynamic_cast(tokens->At(1)); // file name - snprintf(str, size, "RUN %s MUE4 PSI WKM (name beamline institute data-file-format)", ostr[0]->GetString().Data()); + snprintf(str, size, "RUN %s MUE4 PSI WKM (name beamline institute data-file-format)", tokens[1].c_str()); } else if (run.Contains("PSI")) { - ostr[0] = dynamic_cast(tokens->At(1)); // file name - ostr[1] = dynamic_cast(tokens->At(2)); // beamline snprintf(str, size, "RUN %s %s PSI PSI-BIN (name beamline institute data-file-format)", - ostr[0]->GetString().Data(), ostr[1]->GetString().Data()); + tokens[1].c_str(), tokens[2].c_str()); } else if (run.Contains("TRIUMF")) { - ostr[0] = dynamic_cast(tokens->At(1)); // file name - ostr[1] = dynamic_cast(tokens->At(2)); // beamline snprintf(str, size, "RUN %s %s TRIUMF MUD (name beamline institute data-file-format)", - ostr[0]->GetString().Data(), ostr[1]->GetString().Data()); + tokens[1].c_str(), tokens[2].c_str()); } else if (run.Contains("RAL")) { - ostr[0] = dynamic_cast(tokens->At(1)); // file name - ostr[1] = dynamic_cast(tokens->At(2)); // beamline snprintf(str, size, "RUN %s %s RAL NEXUS (name beamline institute data-file-format)", - ostr[0]->GetString().Data(), ostr[1]->GetString().Data()); - } - - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; + tokens[1].c_str(), tokens[2].c_str()); } return true; @@ -165,38 +150,34 @@ bool msr2msr_param(char *str) // handle parameter line TString line(str); - TObjArray *tokens; - TObjString *ostr[6]; char sstr[256]; char spaces[256]; - tokens = line.Tokenize(" \t"); - Int_t noTokens = tokens->GetEntries(); + std::vector tokens = PStringUtils::Split(line.Data(), " \t"); + std::size_t noTokens = tokens.size(); if (noTokens == 4) { - for (unsigned int i=0; i<4; i++) - ostr[i] = dynamic_cast(tokens->At(i)); // number - snprintf(sstr, sizeof(sstr), "%10s", ostr[0]->GetString().Data()); + snprintf(sstr, sizeof(sstr), "%10s", tokens[0].c_str()); // name strcat(sstr, " "); - strcat(sstr, ostr[1]->GetString().Data()); + strcat(sstr, tokens[1].c_str()); memset(spaces, 0, sizeof(spaces)); - memset(spaces, ' ', 12-strlen(ostr[1]->GetString().Data())); + memset(spaces, ' ', 12-strlen(tokens[1].c_str())); strcat(sstr, spaces); // value - strcat(sstr, ostr[2]->GetString().Data()); - if (strlen(ostr[2]->GetString().Data()) < 10) { + strcat(sstr, tokens[2].c_str()); + if (strlen(tokens[2].c_str()) < 10) { memset(spaces, 0, sizeof(spaces)); - memset(spaces, ' ', 10-strlen(ostr[2]->GetString().Data())); + memset(spaces, ' ', 10-strlen(tokens[2].c_str())); strcat(sstr, spaces); } else { strcat(sstr, " "); } // step - strcat(sstr, ostr[3]->GetString().Data()); - if (strlen(ostr[3]->GetString().Data()) < 12) { + strcat(sstr, tokens[3].c_str()); + if (strlen(tokens[3].c_str()) < 12) { memset(spaces, 0, sizeof(spaces)); - memset(spaces, ' ', 12-strlen(ostr[3]->GetString().Data())); + memset(spaces, ' ', 12-strlen(tokens[3].c_str())); strcat(sstr, spaces); } else { strcat(sstr, " "); @@ -204,30 +185,28 @@ bool msr2msr_param(char *str) strcat(sstr, "none"); strcpy(str, sstr); } else if (noTokens == 6) { - for (unsigned int i=0; i<6; i++) - ostr[i] = dynamic_cast(tokens->At(i)); // number - snprintf(sstr, sizeof(sstr), "%10s", ostr[0]->GetString().Data()); + snprintf(sstr, sizeof(sstr), "%10s", tokens[0].c_str()); // name strcat(sstr, " "); - strcat(sstr, ostr[1]->GetString().Data()); + strcat(sstr, tokens[1].c_str()); memset(spaces, 0, sizeof(spaces)); - memset(spaces, ' ', 12-strlen(ostr[1]->GetString().Data())); + memset(spaces, ' ', 12-strlen(tokens[1].c_str())); strcat(sstr, spaces); // value - strcat(sstr, ostr[2]->GetString().Data()); - if (strlen(ostr[2]->GetString().Data()) < 10) { + strcat(sstr, tokens[2].c_str()); + if (strlen(tokens[2].c_str()) < 10) { memset(spaces, 0, sizeof(spaces)); - memset(spaces, ' ', 10-strlen(ostr[2]->GetString().Data())); + memset(spaces, ' ', 10-strlen(tokens[2].c_str())); strcat(sstr, spaces); } else { strcat(sstr, " "); } // step - strcat(sstr, ostr[3]->GetString().Data()); - if (strlen(ostr[3]->GetString().Data()) < 12) { + strcat(sstr, tokens[3].c_str()); + if (strlen(tokens[3].c_str()) < 12) { memset(spaces, 0, sizeof(spaces)); - memset(spaces, ' ', 12-strlen(ostr[3]->GetString().Data())); + memset(spaces, ' ', 12-strlen(tokens[3].c_str())); strcat(sstr, spaces); } else { strcat(sstr, " "); @@ -235,25 +214,19 @@ bool msr2msr_param(char *str) // pos. error strcat(sstr, "none "); // lower boundary - strcat(sstr, ostr[4]->GetString().Data()); - if (strlen(ostr[4]->GetString().Data()) < 8) { + strcat(sstr, tokens[4].c_str()); + if (strlen(tokens[4].c_str()) < 8) { memset(spaces, 0, sizeof(spaces)); - memset(spaces, ' ', 8-strlen(ostr[4]->GetString().Data())); + memset(spaces, ' ', 8-strlen(tokens[4].c_str())); strcat(sstr, spaces); } else { strcat(sstr, " "); } // upper boundary - strcat(sstr, ostr[5]->GetString().Data()); + strcat(sstr, tokens[5].c_str()); strcpy(str, sstr); } - // clean up - if (tokens) { - delete tokens; - tokens = nullptr; - } - return true; } @@ -274,8 +247,7 @@ bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams) { // handle theory line TString line(str); - TObjArray *tokens; - TObjString *ostr; + std::vector tokens; char sstr[256]; if ((line.Contains("sktt") || line.Contains("statKTTab")) && line.Contains("glf")) { // static Gauss KT LF table @@ -283,8 +255,8 @@ bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams) strcpy(sstr, "statGssKTLF "); // tokenize the rest and extract the first two parameters - tokens = line.Tokenize(" \t"); - Int_t noTokens = tokens->GetEntries(); + tokens = PStringUtils::Split(line.Data(), " \t"); + std::size_t noTokens = tokens.size(); if (noTokens < 3) { std::cout << std::endl << "**ERROR** in THEORY block"; std::cout << std::endl << " Line: '" << str << "' is not a valid statKTTab statement."; @@ -293,8 +265,7 @@ bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams) } for (Int_t i=1; i<3; i++) { strcat(sstr, " "); - ostr = dynamic_cast(tokens->At(i)); - strcat(sstr, ostr->GetString().Data()); + strcat(sstr, tokens[i].c_str()); } strcat(sstr, " (frequency damping)"); strcpy(str, sstr); @@ -303,8 +274,8 @@ bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams) strcpy(sstr, "statExpKTLF "); // tokenize the rest and extract the first two parameters - tokens = line.Tokenize(" \t"); - Int_t noTokens = tokens->GetEntries(); + tokens = PStringUtils::Split(line.Data(), " \t"); + std::size_t noTokens = tokens.size(); if (noTokens < 3) { std::cout << std::endl << "**ERROR** in THEORY block"; std::cout << std::endl << " Line: '" << str << "' is not a valid statKTTab statement."; @@ -313,8 +284,7 @@ bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams) } for (Int_t i=1; i<3; i++) { strcat(sstr, " "); - ostr = dynamic_cast(tokens->At(i)); - strcat(sstr, ostr->GetString().Data()); + strcat(sstr, tokens[i].c_str()); } strcat(sstr, " (frequency damping)"); strcpy(str, sstr); @@ -323,8 +293,8 @@ bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams) strcpy(sstr, "dynGssKTLF "); // tokenize the rest and extract the first three parameters - tokens = line.Tokenize(" \t"); - Int_t noTokens = tokens->GetEntries(); + tokens = PStringUtils::Split(line.Data(), " \t"); + std::size_t noTokens = tokens.size(); if (noTokens < 4) { std::cout << std::endl << "**ERROR** in THEORY block"; std::cout << std::endl << " Line: '" << str << "' is not a valid dynmKTTab statement."; @@ -333,8 +303,7 @@ bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams) } for (Int_t i=1; i<4; i++) { strcat(sstr, " "); - ostr = dynamic_cast(tokens->At(i)); - strcat(sstr, ostr->GetString().Data()); + strcat(sstr, tokens[i].c_str()); } strcat(sstr, " (frequency damping hopping-rate)"); strcpy(str, sstr); @@ -343,8 +312,8 @@ bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams) strcpy(sstr, "dynExpKTLF "); // tokenize the rest and extract the first three parameters - tokens = line.Tokenize(" \t"); - Int_t noTokens = tokens->GetEntries(); + tokens = PStringUtils::Split(line.Data(), " \t"); + std::size_t noTokens = tokens.size(); if (noTokens < 4) { std::cout << std::endl << "**ERROR** in THEORY block"; std::cout << std::endl << " Line: '" << str << "' is not a valid dynmKTTab statement."; @@ -353,8 +322,7 @@ bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams) } for (Int_t i=1; i<4; i++) { strcat(sstr, " "); - ostr = dynamic_cast(tokens->At(i)); - strcat(sstr, ostr->GetString().Data()); + strcat(sstr, tokens[i].c_str()); } strcat(sstr, " (frequency damping hopping-rate)"); strcpy(str, sstr); @@ -366,8 +334,8 @@ bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams) strcpy(sstr, "internFld "); // tokenize the rest and extract the first three parameters - tokens = line.Tokenize(" \t"); - Int_t noTokens = tokens->GetEntries(); + tokens = PStringUtils::Split(line.Data(), " \t"); + std::size_t noTokens = tokens.size(); if (noTokens < 4) { std::cout << std::endl << "**ERROR** in THEORY block"; std::cout << std::endl << " Line: '" << str << "' is not a valid internFld statement."; @@ -377,8 +345,7 @@ bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams) strcat(sstr, " _x_"); for (Int_t i=1; i<4; i++) { strcat(sstr, " "); - ostr = dynamic_cast(tokens->At(i)); - strcat(sstr, ostr->GetString().Data()); + strcat(sstr, tokens[i].c_str()); } strcat(sstr, " (fraction phase frequency Trate Lrate)"); strcpy(str, sstr); @@ -390,8 +357,8 @@ bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams) strcpy(sstr, "internBsl "); // tokenize the rest and extract the first three parameters - tokens = line.Tokenize(" \t"); - Int_t noTokens = tokens->GetEntries(); + tokens = PStringUtils::Split(line.Data(), " \t"); + std::size_t noTokens = tokens.size(); if (noTokens < 4) { std::cout << std::endl << "**ERROR** in THEORY block"; std::cout << std::endl << " Line: '" << str << "' is not a valid internBsl statement."; @@ -401,8 +368,7 @@ bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams) strcat(sstr, " _x_"); for (Int_t i=1; i<4; i++) { strcat(sstr, " "); - ostr = dynamic_cast(tokens->At(i)); - strcat(sstr, ostr->GetString().Data()); + strcat(sstr, tokens[i].c_str()); } strcat(sstr, " (fraction phase frequency Trate Lrate)"); strcpy(str, sstr); diff --git a/src/musrFT.cpp b/src/musrFT.cpp index e55855ff..ae8f9e5f 100644 --- a/src/musrFT.cpp +++ b/src/musrFT.cpp @@ -36,13 +36,12 @@ #include #include #include +#include #include #include #include #include -#include -#include #include #ifdef HAVE_GIT_REV_H @@ -50,6 +49,7 @@ #endif #include "PMusr.h" +#include "PStringUtils.h" #include "PStartupHandler.h" #include "PMsrHandler.h" #include "PRunDataHandler.h" @@ -234,17 +234,15 @@ Bool_t musrFT_filter_histo(Int_t &i, Int_t argc, Char_t *argv[], musrFT_startup_ return false; } } else { // should be something like h0-hN with h0, hN numbers - TObjArray *tok = tstr.Tokenize("-"); - if (tok->GetEntries() != 2) { + std::vector tok = PStringUtils::Split(tstr.Data(), "-"); + if (tok.size() != 2) { std::cerr << std::endl << ">> musrFT **ERROR** found --histo argument '" << tstr << "' which is not of the form -." << std::endl; startupParam.histo.clear(); return false; } - TObjString *ostr; TString sstr(""); Int_t first=0, last=0; - ostr = dynamic_cast(tok->At(0)); - sstr = ostr->GetString(); + sstr = tok[0]; if (sstr.IsDigit()) { first = sstr.Atoi(); } else { @@ -253,8 +251,7 @@ Bool_t musrFT_filter_histo(Int_t &i, Int_t argc, Char_t *argv[], musrFT_startup_ startupParam.histo.clear(); return false; } - ostr = dynamic_cast(tok->At(1)); - sstr = ostr->GetString(); + sstr = tok[1]; if (sstr.IsDigit()) { last = sstr.Atoi(); } else { @@ -273,10 +270,6 @@ Bool_t musrFT_filter_histo(Int_t &i, Int_t argc, Char_t *argv[], musrFT_startup_ for (Int_t k=first; k<=last; k++) { startupParam.histo.push_back(k); } - - // clean up - if (tok) - delete tok; } } diff --git a/src/musredit_qt5/musredit/PTextEdit.cpp b/src/musredit_qt5/musredit/PTextEdit.cpp index 3bc450f8..ab3c8115 100644 --- a/src/musredit_qt5/musredit/PTextEdit.cpp +++ b/src/musredit_qt5/musredit/PTextEdit.cpp @@ -2046,7 +2046,7 @@ void PTextEdit::musrWiz() // handle return status of musrWiz connect(proc, static_cast(&QProcess::finished), - [=](int exitCode, QProcess::ExitStatus exitStatus){ exitStatusMusrWiz(exitCode, exitStatus); }); + [=, this](int exitCode, QProcess::ExitStatus exitStatus){ exitStatusMusrWiz(exitCode, exitStatus); }); // make sure that the system environment variables are properly set QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); @@ -2766,7 +2766,7 @@ void PTextEdit::musrT0() proc->setWorkingDirectory(workDir); connect(proc, QOverload::of(&QProcess::finished), - [=](int exitCode, QProcess::ExitStatus exitStatus){ fileReload(); }); + [=, this](int exitCode, QProcess::ExitStatus exitStatus){ fileReload(); }); proc->start(cmd, arg); if (!proc->waitForStarted()) { @@ -2926,7 +2926,7 @@ void PTextEdit::musrSetSteps() // handle return status of musrStep connect(proc, static_cast(&QProcess::finished), - [=](int exitCode, QProcess::ExitStatus exitStatus){ exitStatusMusrSetSteps(exitCode, exitStatus); }); + [=, this](int exitCode, QProcess::ExitStatus exitStatus){ exitStatusMusrSetSteps(exitCode, exitStatus); }); // make sure that the system environment variables are properly set QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); diff --git a/src/musredit_qt6/musredit/PTextEdit.cpp b/src/musredit_qt6/musredit/PTextEdit.cpp index d1a1db9c..d47258ff 100644 --- a/src/musredit_qt6/musredit/PTextEdit.cpp +++ b/src/musredit_qt6/musredit/PTextEdit.cpp @@ -2160,7 +2160,7 @@ void PTextEdit::musrWiz() // handle return status of musrWiz connect(proc, static_cast(&QProcess::finished), - [=](int exitCode, QProcess::ExitStatus exitStatus){ exitStatusMusrWiz(exitCode, exitStatus); }); + [=, this](int exitCode, QProcess::ExitStatus exitStatus){ exitStatusMusrWiz(exitCode, exitStatus); }); // make sure that the system environment variables are properly set QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); @@ -2873,7 +2873,7 @@ void PTextEdit::musrT0() proc->setWorkingDirectory(workDir); connect(proc, QOverload::of(&QProcess::finished), - [=](int exitCode, QProcess::ExitStatus exitStatus){ fileReload(); }); + [=, this](int exitCode, QProcess::ExitStatus exitStatus){ fileReload(); }); proc->start(cmd, arg); if (!proc->waitForStarted()) { @@ -3027,7 +3027,7 @@ void PTextEdit::musrSetSteps() // handle return status of musrStep connect(proc, static_cast(&QProcess::finished), - [=](int exitCode, QProcess::ExitStatus exitStatus){ exitStatusMusrSetSteps(exitCode, exitStatus); }); + [=, this](int exitCode, QProcess::ExitStatus exitStatus){ exitStatusMusrSetSteps(exitCode, exitStatus); }); // make sure that the system environment variables are properly set QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); diff --git a/src/tests/strToNum/CMakeLists.txt b/src/tests/strToNum/CMakeLists.txt new file mode 100644 index 00000000..613bb0cc --- /dev/null +++ b/src/tests/strToNum/CMakeLists.txt @@ -0,0 +1,37 @@ +#------------------------------------------------------ +# CMakeLists.txt for strToNum +# +# little stand-alone test driver for the dependency-free +# PStringUtils class (pure C++17, no ROOT needed). +# +# build (stand-alone): +# cmake -S . -B build +# cmake --build build +# ./build/strToNum +# +# Andreas Suter, 2026/06/06 +#------------------------------------------------------ +cmake_minimum_required(VERSION 3.9) + +project(strToNum VERSION 0.1 LANGUAGES CXX) + +set(CMAKE_CXX_STANDARD 17) +set(CMAKE_CXX_STANDARD_REQUIRED ON) +set(CMAKE_CXX_EXTENSIONS OFF) + +if (NOT CMAKE_BUILD_TYPE) + set(CMAKE_BUILD_TYPE Debug) +endif (NOT CMAKE_BUILD_TYPE) + +#--- the class under test lives in src/classes, its header in src/include ----- +set(MUSRFIT_SRC ${CMAKE_CURRENT_SOURCE_DIR}/../../classes) +set(MUSRFIT_INC ${CMAKE_CURRENT_SOURCE_DIR}/../../include) + +add_executable(strToNum + strToNum.cpp + ${MUSRFIT_SRC}/PStringUtils.cpp +) + +target_include_directories(strToNum + PRIVATE ${MUSRFIT_INC} +) diff --git a/src/tests/strToNum/strToNum.cpp b/src/tests/strToNum/strToNum.cpp new file mode 100644 index 00000000..993e029f --- /dev/null +++ b/src/tests/strToNum/strToNum.cpp @@ -0,0 +1,304 @@ +/*************************************************************************** + + strToNum.cpp + + Author: Andreas Suter + e-mail: andreas.suter@psi.ch + + Little stand-alone test driver for the PStringUtils class. It exercises + Split / IsInt / IsFloat / ToInt / ToDouble / IsEqualNoCase / + ContainsNoCase / BeginsWithNoCase and reports a pass/fail summary. + + Usage: + strToNum -> run the built-in test suite + strToNum -> show what PStringUtils makes of the given + string(s) on the command line (ad-hoc checks) + strToNum -i -> interactive mode: type a string at the prompt + and see the result of every PStringUtils method + (empty line or 'quit' to leave) + +***************************************************************************/ + +/*************************************************************************** + * Copyright (C) 2007-2026 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 +#include +#include +#include + +#include "PStringUtils.h" + +//-------------------------------------------------------------------------- +// tiny test bookkeeping +//-------------------------------------------------------------------------- +static int gPassed = 0; +static int gFailed = 0; + +static void check(const std::string &what, bool ok) +{ + if (ok) { + ++gPassed; + std::cout << " [ ok ] " << what << std::endl; + } else { + ++gFailed; + std::cout << " [FAIL] " << what << std::endl; + } +} + +//-------------------------------------------------------------------------- +static std::string vecToStr(const std::vector &v) +{ + std::string s = "{"; + for (std::vector::size_type i = 0; i < v.size(); ++i) { + s += "'" + v[i] + "'"; + if (i + 1 < v.size()) + s += ", "; + } + s += "}"; + return s; +} + +//-------------------------------------------------------------------------- +static void testSplit() +{ + std::cout << "Split:" << std::endl; + + std::vector r = PStringUtils::Split("alpha beta gamma", " "); + std::cout << " input: 'alpha beta gamma', delim: ' '" << std::endl; + check("3 tokens on single space delimiter", + r.size() == 3 && r[0] == "alpha" && r[1] == "beta" && r[2] == "gamma"); + std::cout << "----" << std::endl; + r = PStringUtils::Split(" , 1 , 2 ,, 3 ,", " ,"); + std::cout << " input: ' , 1 , 2 ,, 3 ,', delim: ' ,'" << std::endl; + std::cout << " -> "; + for (auto i: r) + std::cout << i << ", "; + std::cout << std::endl; + check("mixed/repeated delimiters, empty tokens skipped", + r.size() == 3 && r[0] == "1" && r[1] == "2" && r[2] == "3"); + std::cout << "----" << std::endl; + + r = PStringUtils::Split("", " "); + check("empty input -> no tokens", r.empty()); + + r = PStringUtils::Split(" ", " "); + check("delimiters only -> no tokens", r.empty()); + + r = PStringUtils::Split("nodelim", ",;"); + check("no delimiter present -> single token", + r.size() == 1 && r[0] == "nodelim"); +} + +//-------------------------------------------------------------------------- +static void testIsInt() +{ + std::cout << "IsInt:" << std::endl; + + check("'12345' is int", PStringUtils::IsInt("12345")); + check("' 42 ' (surrounding ws) is int", PStringUtils::IsInt(" 42 ")); + check("'-5' is int (negative)", PStringUtils::IsInt("-5")); + check("'+42' is int (positive sign)", PStringUtils::IsInt("+42")); + check("'' is not int", !PStringUtils::IsInt("")); + check("' ' (ws only) is not int", !PStringUtils::IsInt(" ")); + check("'-' (sign only) is not int", !PStringUtils::IsInt("-")); + check("'+-5' (double sign) is not int", !PStringUtils::IsInt("+-5")); + check("'5-3' (sign after digit) is not int", !PStringUtils::IsInt("5-3")); + check("'3.14' is not int", !PStringUtils::IsInt("3.14")); + check("'12a' is not int", !PStringUtils::IsInt("12a")); +} + +//-------------------------------------------------------------------------- +static void testIsFloat() +{ + std::cout << "IsFloat:" << std::endl; + + check("'3.14' is float", PStringUtils::IsFloat("3.14")); + check("'-1.2e-3' is float", PStringUtils::IsFloat("-1.2e-3")); + check("'+42' is float", PStringUtils::IsFloat("+42")); + check("'.5' is float", PStringUtils::IsFloat(".5")); + check("' 6.022e23 ' (surrounding ws) is float", + PStringUtils::IsFloat(" 6.022e23 ")); + check("'' is not float", !PStringUtils::IsFloat("")); + check("'nan' is not float", !PStringUtils::IsFloat("nan")); + check("'inf' is not float", !PStringUtils::IsFloat("inf")); + check("'1.2.3' is not float", !PStringUtils::IsFloat("1.2.3")); + check("'12abc' is not float", !PStringUtils::IsFloat("12abc")); +} + +//-------------------------------------------------------------------------- +static void testToInt() +{ + std::cout << "ToInt:" << std::endl; + + bool ok = false; + check("'42' -> 42, ok", PStringUtils::ToInt("42", &ok) == 42 && ok); + check("' -7' -> -7, ok", PStringUtils::ToInt(" -7", &ok) == -7 && ok); + check("'123abc' -> 123, ok (trailing ignored)", + PStringUtils::ToInt("123abc", &ok) == 123 && ok); + check("'abc' -> 0, !ok", PStringUtils::ToInt("abc", &ok) == 0 && !ok); + check("'' -> 0, !ok", PStringUtils::ToInt("", &ok) == 0 && !ok); + check("'99999999999999999999' -> out of range, !ok", + (PStringUtils::ToInt("99999999999999999999", &ok), !ok)); + check("null ok pointer is tolerated", PStringUtils::ToInt("17") == 17); +} + +//-------------------------------------------------------------------------- +static void testToDouble() +{ + std::cout << "ToDouble:" << std::endl; + + bool ok = false; + check("'3.14' -> 3.14, ok", + std::fabs(PStringUtils::ToDouble("3.14", &ok) - 3.14) < 1e-12 && ok); + check("' +1.5e2' -> 150, ok", + std::fabs(PStringUtils::ToDouble(" +1.5e2", &ok) - 150.0) < 1e-9 && ok); + check("'2.5xyz' -> 2.5, ok (trailing ignored)", + std::fabs(PStringUtils::ToDouble("2.5xyz", &ok) - 2.5) < 1e-12 && ok); + check("'abc' -> 0.0, !ok", PStringUtils::ToDouble("abc", &ok) == 0.0 && !ok); + check("'' -> 0.0, !ok", PStringUtils::ToDouble("", &ok) == 0.0 && !ok); + check("'1e400' -> out of range, !ok", + (PStringUtils::ToDouble("1e400", &ok), !ok)); + check("null ok pointer is tolerated", + std::fabs(PStringUtils::ToDouble("0.25") - 0.25) < 1e-12); +} + +//-------------------------------------------------------------------------- +static void testCaseHelpers() +{ + std::cout << "IsEqualNoCase / ContainsNoCase / BeginsWithNoCase:" << std::endl; + + check("'Fit' == 'fIT' (no case)", PStringUtils::IsEqualNoCase("Fit", "fIT")); + check("'Fit' != 'Fits'", !PStringUtils::IsEqualNoCase("Fit", "Fits")); + check("'' == ''", PStringUtils::IsEqualNoCase("", "")); + + check("'Hello World' contains 'LO WO' (no case)", + PStringUtils::ContainsNoCase("Hello World", "LO WO")); + check("empty needle is contained", + PStringUtils::ContainsNoCase("abc", "")); + check("needle longer than haystack is not contained", + !PStringUtils::ContainsNoCase("ab", "abc")); + + check("'THEORY' begins with 'the' (no case)", + PStringUtils::BeginsWithNoCase("THEORY", "the")); + check("'THEORY' does not begin with 'ory'", + !PStringUtils::BeginsWithNoCase("THEORY", "ory")); +} + +//-------------------------------------------------------------------------- +static void inspect(const std::string &str) +{ + std::cout << "Inspecting '" << str << "':" << std::endl; + std::cout << " Split(' \\t,;') = " + << vecToStr(PStringUtils::Split(str, " \t,;")) << std::endl; + std::cout << " IsInt = " << (PStringUtils::IsInt(str) ? "true" : "false") << std::endl; + std::cout << " IsFloat = " << (PStringUtils::IsFloat(str) ? "true" : "false") << std::endl; + + bool ok = false; + int i = PStringUtils::ToInt(str, &ok); + std::cout << " ToInt = " << i << " (ok=" << (ok ? "true" : "false") << ")" << std::endl; + double d = PStringUtils::ToDouble(str, &ok); + std::cout << " ToDouble = " << d << " (ok=" << (ok ? "true" : "false") << ")" << std::endl; +} + +//-------------------------------------------------------------------------- +static void usage(const char *prog) +{ + std::cout + << "usage: " << prog << " [options] [string ...]\n" + << "\n" + << "Little stand-alone test driver for the PStringUtils class. It exercises\n" + << "Split / IsInt / IsFloat / ToInt / ToDouble / IsEqualNoCase /\n" + << "ContainsNoCase / BeginsWithNoCase.\n" + << "\n" + << "options:\n" + << " -h, --help show this help and exit\n" + << " -i, --interactive interactive mode: type a string at the prompt and\n" + << " see the result of every PStringUtils method\n" + << " (empty line, 'quit'/'exit' or Ctrl-D leaves)\n" + << "\n" + << "arguments:\n" + << " string ... one or more strings to inspect; the result of every\n" + << " PStringUtils method is printed for each of them\n" + << "\n" + << "with no options and no arguments the built-in test suite is run; the exit\n" + << "code is 0 if all checks pass and 1 otherwise.\n" + << "\n" + << "examples:\n" + << " " << prog << " run the built-in test suite\n" + << " " << prog << " \" -42xyz\" 1.5e-3 inspect the given strings\n" + << " " << prog << " -i interactive mode\n"; +} + +//-------------------------------------------------------------------------- +static void interactive() +{ + std::cout << "==== PStringUtils interactive mode ====" << std::endl; + std::cout << "Enter a string to test the methods on it." << std::endl; + std::cout << "An empty line or 'quit' leaves." << std::endl << std::endl; + + std::string line; + while (true) { + std::cout << "strToNum> " << std::flush; + if (!std::getline(std::cin, line)) // EOF (e.g. Ctrl-D) + break; + if (line.empty() || line == "quit" || line == "exit") + break; + inspect(line); + std::cout << std::endl; + } +} + +//-------------------------------------------------------------------------- +int main(int argc, char *argv[]) +{ + if (argc > 1) { + const std::string arg1 = argv[1]; + if (arg1 == "-h" || arg1 == "--help") { + usage(argv[0]); + return 0; + } + if (arg1 == "-i" || arg1 == "--interactive") { + interactive(); + return 0; + } + // ad-hoc mode: inspect the strings given on the command line + for (int i = 1; i < argc; ++i) { + inspect(argv[i]); + std::cout << std::endl; + } + return 0; + } + + std::cout << "==== PStringUtils test suite ====" << std::endl << std::endl; + + testSplit(); + testIsInt(); + testIsFloat(); + testToInt(); + testToDouble(); + testCaseHelpers(); + + std::cout << std::endl + << "==== summary: " << gPassed << " passed, " + << gFailed << " failed ====" << std::endl; + + return (gFailed == 0) ? 0 : 1; +}