Merge remote-tracking branch 'origin/refactor-pmsrhandler-cpp17-tokenizer' into root6

This commit is contained in:
2026-07-22 08:03:49 +02:00
24 changed files with 1665 additions and 2034 deletions
+5 -1
View File
@@ -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
$<BUILD_INTERFACE:${CMAKE_SOURCE_DIR}/src/include>
)
target_link_libraries(msr2msr ${ROOT_LIBRARIES})
add_executable(musrfit musrfit.cpp)
+2
View File
@@ -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}
+61 -239
View File
@@ -64,10 +64,9 @@
#include <TFile.h>
#include <TDatime.h>
#include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#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; i<theo->size(); 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<std::string> tok = PStringUtils::Split(line.Data(), " \t");
if (static_cast<int>(tok.size()) > pos) {
str = tok[pos].c_str();
}
if (tok->GetEntries() > pos) {
ostr = dynamic_cast<TObjString*>(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; i<funList->size(); 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<std::string> tok = PStringUtils::Split(funList->at(i).fLine.Data(), " =+-*/");
for (int j=1; j<tok->GetEntries(); j++) {
ostr = dynamic_cast<TObjString*>(tok->At(j));
str = ostr->GetString();
for (int j=1; j<static_cast<int>(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<std::string> tokens;
TString str;
UInt_t ival;
tokens = line.Tokenize(", \t");
tokens = PStringUtils::Split(line.Data(), ", \t");
for (Int_t i=0; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i));
str = ostr->GetString();
for (Int_t i=0; i<static_cast<int>(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<std::string> tokens;
TString str;
tokens = line.Tokenize(", \t");
tokens = PStringUtils::Split(line.Data(), ", \t");
if (tokens->GetEntries() == 2) { // should only be RESET
ostr = dynamic_cast<TObjString*>(tokens->At(1));
str = ostr->GetString();
if (static_cast<int>(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<UInt_t>(tokens->GetEntries()) % 2) == 1) {
if ((tokens->GetEntries() > 3) && ((static_cast<UInt_t>(tokens->GetEntries())-1)) != 2*fRunInfo->GetMsrRunList()->size()) {
} else if ((static_cast<int>(tokens.size()) > 1) && (static_cast<UInt_t>(static_cast<int>(tokens.size())) % 2) == 1) {
if ((static_cast<int>(tokens.size()) > 3) && ((static_cast<UInt_t>(static_cast<int>(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 <start> <end> | FIT_RANGE <s1> <e1> <s2> <e2> .. <sN> <eN> |";
std::cerr << std::endl << ">> FIT_RANGE fgb+<n0> lgb-<n1> | FIT_RANGE fgb+<n00> lgb-<n01> fgb+<n10> lgb-<n11> ... fgb+<nN0> lgb-<nN1>,";
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<int>(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; n<tokens->GetEntries(); n++) {
ostr = dynamic_cast<TObjString*>(tokens->At(n));
str = ostr->GetString();
for (Int_t n=1; n<static_cast<int>(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+<n0> lgb-<n1> | FIT_RANGE fgb+<n00> lgb-<n01> fgb+<n10> lgb-<n11> ... fgb+<nN0> lgb-<nN1>,";
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<std::string> tokens;
TString str;
UInt_t ival;
tokens = line.Tokenize(", \t");
tokens = PStringUtils::Split(line.Data(), ", \t");
for (Int_t i=1; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i));
str = ostr->GetString();
for (Int_t i=1; i<static_cast<int>(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<std::string> tokens;
TString str;
UInt_t ival;
tokens = line.Tokenize(", \t");
tokens = PStringUtils::Split(line.Data(), ", \t");
for (Int_t i=1; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i));
str = ostr->GetString();
for (Int_t i=1; i<static_cast<int>(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<std::string> tokens;
TString str;
UInt_t ival;
tokens = line.Tokenize(", \t");
tokens = PStringUtils::Split(line.Data(), ", \t");
for (Int_t i=0; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i));
str = ostr->GetString();
for (Int_t i=0; i<static_cast<int>(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<std::string> tokens;
TString str;
tokens = line.Tokenize(" \t");
if (tokens->GetEntries() == 2) {
ostr = dynamic_cast<TObjString*>(tokens->At(1));
str = ostr->GetString();
tokens = PStringUtils::Split(line.Data(), " \t");
if (static_cast<int>(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<std::string> 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<int>(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; i<tokens->GetEntries(); i++) {
for (Int_t i=1; i<static_cast<int>(tokens.size()); i++) {
// keep time range of sector
PSectorChisq sec(fRunInfo->GetNoOfRuns());
// get parse tokens
ostr = dynamic_cast<TObjString*>(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<std::string> 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<int>(tokens.size()) == 2) { // reset command
fRunListCollection->SetFitRange(fOriginalFitRange);
} else if (tokens->GetEntries() == 3) { // single fit range for all runs
} else if (static_cast<int>(tokens.size()) == 3) { // single fit range for all runs
Double_t start = 0.0, end = 0.0;
PDoublePair fitRange;
PDoublePairVector fitRangeVector;
ostr = dynamic_cast<TObjString*>(tokens->At(1));
str = ostr->GetString();
str = tokens[1].c_str();
start = str.Atof();
ostr = dynamic_cast<TObjString*>(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; i<runList->size(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(2*i+1));
str = ostr->GetString();
str = tokens[2*i+1].c_str();
start = str.Atof();
ostr = dynamic_cast<TObjString*>(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<std::string> tokens;
TString str;
tokens = fCmdLines[lineNo].fLine.Tokenize(", \t");
tokens = PStringUtils::Split(fCmdLines[lineNo].fLine.Data(), ", \t");
for (Int_t i=1; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i));
str = ostr->GetString();
for (Int_t i=1; i<static_cast<int>(tokens.size()); i++) {
str = tokens[i].c_str();
if (str.IsDigit()) { // token is a parameter number
fMnUserParams.Fix(static_cast<UInt_t>(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<std::string> tokens;
TString str;
tokens = fCmdLines[lineNo].fLine.Tokenize(", \t");
tokens = PStringUtils::Split(fCmdLines[lineNo].fLine.Data(), ", \t");
if (tokens->GetEntries() < 2) {
if (static_cast<int>(tokens.size()) < 2) {
std::cerr << std::endl << "**ERROR** from PFitter::ExecutePrintLevel(): SYNTAX: PRINT_LEVEL <N>, where <N>=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<std::string> 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; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i));
str = ostr->GetString();
for (Int_t i=1; i<static_cast<int>(tokens.size()); i++) {
str = tokens[i].c_str();
if (str.IsDigit()) { // token is a parameter number
fMnUserParams.Release(static_cast<UInt_t>(str.Atoi())-1);
@@ -2203,11 +2030,6 @@ Bool_t PFitter::ExecuteRelease(UInt_t lineNo)
}
}
// clean up
if (tokens) {
delete tokens;
tokens = nullptr;
}
return true;
}
File diff suppressed because it is too large Load Diff
+4 -12
View File
@@ -34,11 +34,11 @@
#include <TColor.h>
#include <TRandom.h>
#include <TROOT.h>
#include <TObjString.h>
#include <TGFileDialog.h>
#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; i<cmd->size(); 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<std::string> 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<TObjString*>(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;
}
}
+12 -22
View File
@@ -38,12 +38,13 @@
#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>
#include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#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<std::string> 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<TObjString*>(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<TObjString*>(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<TObjString*>(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<TObjString*>(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;
}
}
//--------------------------------------------------------------------------
+12 -22
View File
@@ -39,12 +39,13 @@
#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>
#include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#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<std::string> 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<TObjString*>(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<TObjString*>(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<TObjString*>(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<TObjString*>(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;
}
}
//--------------------------------------------------------------------------
+12 -22
View File
@@ -39,12 +39,13 @@
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#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<std::string> 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<TObjString*>(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<TObjString*>(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<TObjString*>(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<TObjString*>(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;
}
}
//--------------------------------------------------------------------------
-2
View File
@@ -32,8 +32,6 @@
#include <TROOT.h>
#include <TSystem.h>
#include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#include <TFolder.h>
#include "PRunBase.h"
+126 -417
View File
@@ -42,6 +42,7 @@
#include <string>
#include <sstream>
#include <memory>
#include <vector>
#include <TROOT.h>
#include <TSystem.h>
@@ -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; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i));
str = ostr->GetString() + TString("/") + *runInfo.GetRunName(idx);
std::vector<std::string> tokens = PStringUtils::Split(str.Data(), ":");
for (UInt_t i=0; i<tokens.size(); i++) {
str = TString(tokens[i]) + TString("/") + *runInfo.GetRunName(idx);
TestFileName(str, ext);
if (!str.IsNull()) {
pathName = str;
break;
}
}
// cleanup
if (tokens) {
delete tokens;
tokens = nullptr;
}
}
// check if the file is found in the generated default path
if (pathName.CompareTo("???") == 0) { // not found in MUSRFULLDATAPATH search
str = TString(musrpath);
// MUSRFULLDATAPATH has the structure: path_1:path_2:...:path_n
TObjArray *tokens = str.Tokenize(":");
TObjString *ostr;
std::vector<std::string> 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; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i));
str = ostr->GetString() + TString("/DATA/") +
for (UInt_t i=0; i<tokens.size(); i++) {
str = TString(tokens[i]) + TString("/DATA/") +
*runInfo.GetInstitute(idx) + TString("/") +
*runInfo.GetBeamline(idx) + TString("/") +
*runInfo.GetRunName(idx);
@@ -1218,11 +1211,6 @@ Bool_t PRunDataHandler::FileExistsCheck(PMsrRunBlock &runInfo, const UInt_t idx)
break;
}
}
// clean up
if (tokens) {
delete tokens;
tokens = nullptr;
}
}
// no proper path name found
@@ -1307,21 +1295,14 @@ Bool_t PRunDataHandler::FileExistsCheck(const Bool_t fileName, const Int_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; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i));
str = ostr->GetString() + TString("/") + fln;
std::vector<std::string> tokens = PStringUtils::Split(str.Data(), ":");
for (UInt_t i=0; i<tokens.size(); i++) {
str = TString(tokens[i]) + TString("/") + fln;
if (gSystem->AccessPathName(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; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i));
str = ostr->GetString() + TString("/") + fileName;
std::vector<std::string> tokens = PStringUtils::Split(str.Data(), ":");
for (UInt_t i=0; i<tokens.size(); i++) {
str = TString(tokens[i]) + TString("/") + fileName;
if (gSystem->AccessPathName(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<TObjString*>(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<TObjString*>(lineIter.Next());
while (objTok != nullptr) {
if (!objTok->GetString().CompareTo("RA-L")) {
objTok = dynamic_cast<TObjString*>(lineIter.Next()); // "="
if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) {
objTok = dynamic_cast<TObjString*>(lineIter.Next()); // HV value
runData.SetRingAnode(0, objTok->GetString().Atof()); // fill RA-R value into the runData structure
break;
}
}
objTok = dynamic_cast<TObjString*>(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<TObjString*>(lineIter.Next());
while (objTok != nullptr){
if (!objTok->GetString().CompareTo("RA-R")) {
objTok = dynamic_cast<TObjString*>(lineIter.Next()); // "="
if (objTok != nullptr && !objTok->GetString().CompareTo("=")) {
objTok = dynamic_cast<TObjString*>(lineIter.Next()); // HV value
runData.SetRingAnode(1, objTok->GetString().Atof()); // fill RA-R value into the runData structure
break;
}
}
objTok = dynamic_cast<TObjString*>(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<TObjString*>(lineIter.Next());
while (objTok != nullptr){
if (!objTok->GetString().CompareTo("RA-T")) {
objTok = dynamic_cast<TObjString*>(lineIter.Next()); // "="
if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) {
objTok = dynamic_cast<TObjString*>(lineIter.Next()); // HV value
runData.SetRingAnode(2, objTok->GetString().Atof()); // fill RA-T value into the runData structure
break;
}
}
objTok = dynamic_cast<TObjString*>(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<TObjString*>(lineIter.Next());
while (objTok != nullptr){
if (!objTok->GetString().CompareTo("RA-B")) {
objTok = dynamic_cast<TObjString*>(lineIter.Next()); // "="
if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) {
objTok = dynamic_cast<TObjString*>(lineIter.Next()); // HV value
runData.SetRingAnode(3, objTok->GetString().Atof()); // fill RA-B value into the runData structure
break;
}
}
objTok = dynamic_cast<TObjString*>(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<std::string> 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<TObjString*>(summIter.Next()); // next summary line...
@@ -1962,97 +1861,22 @@ Bool_t PRunDataHandler::ReadRootFile()
TString s;
TObjArrayIter summIter(runSummary);
TObjString *os(dynamic_cast<TObjString*>(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<TObjString*>(lineIter.Next());
while (objTok != nullptr) {
if (!objTok->GetString().CompareTo("RA-L")) {
objTok = dynamic_cast<TObjString*>(lineIter.Next()); // "="
if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) {
objTok = dynamic_cast<TObjString*>(lineIter.Next()); // HV value
runData.SetRingAnode(0, objTok->GetString().Atof()); // fill RA-R value into the runData structure
break;
}
}
objTok = dynamic_cast<TObjString*>(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<TObjString*>(lineIter.Next());
while (objTok != nullptr){
if (!objTok->GetString().CompareTo("RA-R")) {
objTok = dynamic_cast<TObjString*>(lineIter.Next()); // "="
if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) {
objTok = dynamic_cast<TObjString*>(lineIter.Next()); // HV value
runData.SetRingAnode(1, objTok->GetString().Atof()); // fill RA-R value into the runData structure
break;
}
}
objTok = dynamic_cast<TObjString*>(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<TObjString*>(lineIter.Next());
while (objTok != nullptr){
if (!objTok->GetString().CompareTo("RA-T")) {
objTok = dynamic_cast<TObjString*>(lineIter.Next()); // "="
if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) {
objTok = dynamic_cast<TObjString*>(lineIter.Next()); // HV value
runData.SetRingAnode(2, objTok->GetString().Atof()); // fill RA-T value into the runData structure
break;
}
}
objTok = dynamic_cast<TObjString*>(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<TObjString*>(lineIter.Next());
while (objTok != nullptr){
if (!objTok->GetString().CompareTo("RA-B")) {
objTok = dynamic_cast<TObjString*>(lineIter.Next()); // "="
if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) {
objTok = dynamic_cast<TObjString*>(lineIter.Next()); // HV value
runData.SetRingAnode(3, objTok->GetString().Atof()); // fill RA-B value into the runData structure
break;
}
}
objTok = dynamic_cast<TObjString*>(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<std::string> 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<TObjString*>(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<std::string> 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; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i));
str = ostr->GetString();
for (UInt_t i=0; i<tokens.size(); i++) {
str = tokens[i];
val = ToInt(str, ok);
if (ok) {
histoData.push_back(val);
} else {
std::cerr << std::endl << ">> 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; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i));
str = ostr->GetString();
for (UInt_t i=0; i<tokens.size(); i++) {
str = tokens[i];
val = ToInt(str, ok);
if (ok) {
histoData.push_back(val);
} else {
std::cerr << std::endl << ">> 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<std::string> 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<TObjString*>(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<TObjString*>(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<TObjString*>(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<TObjString*>(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<TObjString*>(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<Int_t>(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; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(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.size(); i++) {
data[i-1].push_back(TString(tokens[i]).Atof());
}
}
}
@@ -3638,16 +3414,14 @@ Bool_t PRunDataHandler::ReadAsciiFile()
} else if (dataTag) {
if (line.IsWhitespace()) // ignore empty lines
continue;
TObjString *ostr;
TObjArray *tokens;
// Remove trailing end of line
line.Remove(TString::kTrailing, '\r');
line.Remove(TString::kTrailing, '\r');
// check if data have x, y [, error y] structure, and that x, y, and error y are numbers
tokens = line.Tokenize(" ,\t");
std::vector<std::string> 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<TObjString*>(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<TObjString*>(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<TObjString*>(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<std::string> 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; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(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.size(); i++) {
runData.fDataNonMusr.AppendDataTag(TString(tokens[i]));
}
continue;
}
@@ -3954,18 +3711,12 @@ Bool_t PRunDataHandler::ReadDBFile()
// check if first real data line
if (firstData) {
// check if data are given just as rows are as labelled columns (see description above)
tokens = workStr.Tokenize(",");
ostr = dynamic_cast<TObjString*>(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<TObjString*>(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<TObjString*>(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<TObjString*>(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<TObjString*>(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<TObjString*>(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<Int_t>(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; i<tokens->GetEntries()-1; i+=3) {
for (UInt_t i=0; i+1<tokens.size(); i+=3) {
// handle value
ostr = dynamic_cast<TObjString*>(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<TObjString*>(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<std::string> 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<noOfEntries; i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i));
tstr = ostr->GetString();
noOfEntries = tokens.size();
for (UInt_t i=0; i<noOfEntries; i++) {
tstr = TString(tokens[i]);
if (!tstr.EndsWith("Err", TString::kExact)) {
noOfDataSets++;
isData.push_back(true);
@@ -4274,8 +3996,8 @@ Bool_t PRunDataHandler::ReadDatFile()
std::cerr << std::endl;
return false;
}
if (tokens->GetEntries() != noOfEntries) { // error
std::cerr << std::endl << ">> PRunDataHandler::ReadDatFile **ERROR** data set with wrong number of entries: " << tokens->GetEntries() << ", should be " << noOfEntries << ".";
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<noOfEntries; i++) {
// 1st: check that entry is indeed a number
ostr = dynamic_cast<TObjString*>(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<std::string> 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; i<tok->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(tok->At(i));
str = ostr->GetString();
for (UInt_t i=0; i<tok.size(); i++) {
str = TString(tok[i]);
// check tokens
if (!str.CompareTo("yy", TString::kExact)) { // check for 'yy'
@@ -6700,10 +6413,6 @@ TString PRunDataHandler::FileNameFromTemplate(TString &fileNameTemplate, Int_t r
}
}
// clean up
if (tok)
delete tok;
// everything fine here
ok = true;
+13 -23
View File
@@ -36,11 +36,12 @@
#endif
#include <iostream>
#include <string>
#include <vector>
#include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#include "PStringUtils.h"
#include "PRunMuMinus.h"
//--------------------------------------------------------------------------
@@ -383,7 +384,7 @@ Double_t PRunMuMinus::CalcMaxLikelihood(const std::vector<Double_t>& 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<Double_t>(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<std::string> 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<TObjString*>(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<TObjString*>(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<TObjString*>(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<TObjString*>(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;
}
}
//--------------------------------------------------------------------------
+18 -36
View File
@@ -38,12 +38,13 @@
#include <cmath>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#include "PMusr.h"
#include "PStringUtils.h"
#include "PRunSingleHisto.h"
//--------------------------------------------------------------------------
@@ -439,7 +440,7 @@ Double_t PRunSingleHisto::CalcChiSquareExpected(const std::vector<Double_t>& par
* <b>OpenMP Parallelization:</b>
* - 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))
*
* <b>When to Use Maximum Likelihood vs. χ²:</b>
* - <b>Use likelihood:</b> Low count rates (< 100 counts/bin), asymmetric errors
@@ -515,7 +516,7 @@ Double_t PRunSingleHisto::CalcMaxLikelihood(const std::vector<Double_t>& 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<Double_t>(i)*fData.GetDataTimeStep();
@@ -650,7 +651,7 @@ Double_t PRunSingleHisto::CalcMaxLikelihoodExpected(const std::vector<Double_t>&
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<Double_t>(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<std::string> 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<TObjString*>(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<TObjString*>(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<TObjString*>(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<TObjString*>(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; i<cmd->size(); 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<std::string> 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<TObjString*>(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;
}
}
+12 -22
View File
@@ -39,13 +39,14 @@
#include <iostream>
#include <fstream>
#include <memory>
#include <string>
#include <vector>
#include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#include <TH1F.h>
#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<std::string> 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<TObjString*>(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<TObjString*>(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<TObjString*>(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<TObjString*>(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;
}
}
//--------------------------------------------------------------------------
+38 -57
View File
@@ -34,13 +34,12 @@
#include <iostream>
#include <fstream>
#include <TObjArray.h>
#include <TObjString.h>
#include <TColor.h>
#include <TList.h>
#include <TXMLAttr.h>
#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<std::string> 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<TObjString*>(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<TObjString*>(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<TObjString*>(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);
+275
View File
@@ -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 <cctype>
#include <cerrno>
#include <charconv>
#include <cstdlib>
#include "PStringUtils.h"
//--------------------------------------------------------------------------
// Split (static)
//--------------------------------------------------------------------------
/**
* <p>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<std::string> PStringUtils::Split(const std::string &str, const std::string &delimiters)
{
std::vector<std::string> 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)
//--------------------------------------------------------------------------
/**
* <p>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<unsigned char>(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<unsigned char>(c))) {
return false;
}
}
return hasDigit;
}
//--------------------------------------------------------------------------
// IsFloat (static)
//--------------------------------------------------------------------------
/**
* <p>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<unsigned char>(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)
//--------------------------------------------------------------------------
/**
* <p>Converts the leading part of the string to an int (base 10), mirroring
* TString::Atoi(). Returns 0 if no conversion is possible.
*
* <p>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<unsigned char>(*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)
//--------------------------------------------------------------------------
/**
* <p>Converts the leading part of the string to a double, mirroring
* TString::Atof(). Returns 0.0 if no conversion is possible.
*
* <p>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)
//--------------------------------------------------------------------------
/**
* <p>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<unsigned char>(a[i])) !=
std::tolower(static_cast<unsigned char>(b[i])))
return false;
}
return true;
}
//--------------------------------------------------------------------------
// ContainsNoCase (static)
//--------------------------------------------------------------------------
/**
* <p>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)
//--------------------------------------------------------------------------
/**
* <p>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<unsigned char>(str[i])) !=
std::tolower(static_cast<unsigned char>(prefix[i])))
return false;
}
return true;
}
+24 -72
View File
@@ -29,19 +29,19 @@
#include <iostream>
#include <vector>
#include <string>
#include <cmath>
#include <TObject.h>
#include <TString.h>
#include <TF1.h>
#include <TObjString.h>
#include <TObjArray.h>
#include <TClass.h>
#include <TMath.h>
#include <Math/SpecFuncMathMore.h>
#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<std::string> 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<TObjString*>(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<UInt_t>(tokens->GetEntries()-1) < fNoOfParam) &&
if ((static_cast<UInt_t>(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; i<tokens->GetEntries(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i));
str = ostr->GetString();
for (UInt_t i=1; i<tokens.size(); i++) {
str = tokens[i];
// if userFcn, the first entry is the function name and needs to be handled specially
if ((fType == THEORY_USER_FCN) && ((i == 1) || (i == 2))) {
@@ -304,11 +299,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;
} 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; i<fullTheoryBlock->size(); 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<std::string> tokens = PStringUtils::Split(str.Data(), " \t");
if (tokens.empty())
continue;
// make a handable string out of the asymmetry token
ostr = dynamic_cast<TObjString*>(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<UInt_t>(tokens->GetEntries()) < fgTheoDataBase[idx].fNoOfParam + 1)
if (static_cast<UInt_t>(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; j<tokens->GetEntries(); j++) {
ostr = dynamic_cast<TObjString*>(tokens->At(j));
str = ostr->GetString();
for (UInt_t j=1; j<tokens.size(); j++) {
str = tokens[j];
snprintf(substr, sizeof(substr), "%6s", str.Data());
tidy += TString(substr);
}
@@ -1005,19 +982,13 @@ void PTheory::MakeCleanAndTidyTheoryBlock(PMsrLines *fullTheoryBlock)
} else {
tidy += TString(" ");
}
if (static_cast<UInt_t>(tokens->GetEntries()) == fgTheoDataBase[idx].fNoOfParam + 1) // no tshift
if (static_cast<UInt_t>(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<std::string> 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<Int_t>(tokens.size());
for (Int_t j=1; j<max; j++) {
ostr = dynamic_cast<TObjString*>(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<max; j++) {
ostr = dynamic_cast<TObjString*>(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<std::string> tokens = PStringUtils::Split(str.Data(), " \t");
for (Int_t j=1; j<tokens->GetEntries(); j++) {
ostr = dynamic_cast<TObjString*>(tokens->At(j));
str = ostr->GetString();
for (UInt_t j=1; j<tokens.size(); j++) {
str = tokens[j];
tidy += TString(" ") + str;
}
// write tidy string back into theory block
(*fullTheoryBlock)[i].fLine = tidy;
// clean up
if (tokens) {
delete tokens;
tokens = nullptr;
}
}
//--------------------------------------------------------------------------
+2 -1
View File
@@ -102,7 +102,8 @@ static inline void SobolIni(This *t)
int inibits = -1, bit;
for( j = powers; j; 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 ) {
+150
View File
@@ -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 <string>
#include <vector>
//-------------------------------------------------------------
/**
* \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:
/**
* <p>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<std::string> Split(const std::string &str, const std::string &delimiters);
/**
* <p>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);
/**
* <p>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);
/**
* <p>Converts the leading part of the string to an int (base 10).
* Mirrors TString::Atoi(). Returns 0 if no conversion is possible.
*
* <p>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);
/**
* <p>Converts the leading part of the string to a double.
* Mirrors TString::Atof(). Returns 0.0 if no conversion is possible.
*
* <p>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);
/**
* <p>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);
/**
* <p>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);
/**
* <p>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_
+52 -86
View File
@@ -35,8 +35,8 @@
#include <cstdlib>
#include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#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<std::string> 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 <msr-file-out> 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<TObjString*>(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<TObjString*>(tokens->At(1)); // file name
ostr[1] = dynamic_cast<TObjString*>(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<TObjString*>(tokens->At(1)); // file name
ostr[1] = dynamic_cast<TObjString*>(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<TObjString*>(tokens->At(1)); // file name
ostr[1] = dynamic_cast<TObjString*>(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<std::string> 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<TObjString*>(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<TObjString*>(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<std::string> 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<TObjString*>(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<TObjString*>(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<TObjString*>(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<TObjString*>(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<TObjString*>(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<TObjString*>(tokens->At(i));
strcat(sstr, ostr->GetString().Data());
strcat(sstr, tokens[i].c_str());
}
strcat(sstr, " (fraction phase frequency Trate Lrate)");
strcpy(str, sstr);
+6 -13
View File
@@ -36,13 +36,12 @@
#include <iostream>
#include <fstream>
#include <vector>
#include <string>
#include <memory>
#include <TApplication.h>
#include <TROOT.h>
#include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#include <TSAXParser.h>
#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<std::string> 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 <h0>-<hN>." << std::endl;
startupParam.histo.clear();
return false;
}
TObjString *ostr;
TString sstr("");
Int_t first=0, last=0;
ostr = dynamic_cast<TObjString*>(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<TObjString*>(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;
}
}
+3 -3
View File
@@ -2046,7 +2046,7 @@ void PTextEdit::musrWiz()
// handle return status of musrWiz
connect(proc, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&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<int, QProcess::ExitStatus>::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<void(QProcess::*)(int, QProcess::ExitStatus)>(&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();
+3 -3
View File
@@ -2160,7 +2160,7 @@ void PTextEdit::musrWiz()
// handle return status of musrWiz
connect(proc, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&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<int, QProcess::ExitStatus>::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<void(QProcess::*)(int, QProcess::ExitStatus)>(&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();
+37
View File
@@ -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}
)
+304
View File
@@ -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 <string> -> 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 <cmath>
#include <iostream>
#include <string>
#include <vector>
#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<std::string> &v)
{
std::string s = "{";
for (std::vector<std::string>::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<std::string> 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;
}