Compare commits

..

25 Commits

Author SHA1 Message Date
suter_a f2ab8dbeb9 add missing path to CMakeLists.txt. 2026-06-06 17:52:59 +02:00
suter_a 017be1fc9c musrFT: replace TObjArray/TObjString with PStringUtils
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 16:59:58 +02:00
suter_a 41301bd988 PRunDataHandler: replace tokenizer TObjArray/TObjString with PStringUtils
Convert all TString::Tokenize() call sites to PStringUtils::Split. The
persisted RunSummary TObjArray (read from the MusrRoot file via
FindObjectAny and iterated with TObjArrayIter) and the run-title TObjString
returned by TLemRunHeader::GetRunTitle() remain ROOT types, since they come
from external interfaces / on-disk format, not from tokenization.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 16:54:46 +02:00
suter_a 6cb69a78a7 PRunSingleHistoRRF: replace TObjArray/TObjString with PStringUtils
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 16:32:08 +02:00
suter_a 5dbd3c74f1 PRunSingleHisto: replace TObjArray/TObjString with PStringUtils
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 16:32:08 +02:00
suter_a 6a93932f90 PRunMuMinus: replace TObjArray/TObjString with PStringUtils
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 16:32:08 +02:00
suter_a 5939db2722 PRunAsymmetryRRF: replace TObjArray/TObjString with PStringUtils
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 16:26:00 +02:00
suter_a 850fb6bbc6 PRunAsymmetry: replace TObjArray/TObjString with PStringUtils
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 16:26:00 +02:00
suter_a f3abe77e14 PRunAsymmetryBNMR: replace TObjArray/TObjString with PStringUtils
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 16:23:11 +02:00
suter_a df58b81997 PRunBase: drop unused TObjArray/TObjString includes
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 16:20:42 +02:00
suter_a 82f668c140 PTheory: replace TObjArray/TObjString with PStringUtils
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 16:17:05 +02:00
suter_a 5bbcb37370 PMusrCanvas: replace TObjArray/TObjString with PStringUtils
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 15:45:24 +02:00
suter_a 66aa847b58 PFitter: replace TObjArray/TObjString with PStringUtils
Replace ROOT's TString::Tokenize() + TObjArray/TObjString token
handling with the dependency-free PStringUtils::Split() across all
command/theory parsing in PFitter (GetPhaseParams, GetParFromFun,
CheckCommands and the Execute* helpers). Split() mirrors Tokenize()
semantics (delimiter-set, skips empty tokens), so token counts and
indices are unchanged. Each token is still copied into a TString,
so the downstream Atoi/Atof/IsFloat/IsDigit/Contains/CompareTo logic
stays as-is.

Using a std::vector<std::string> removes the manual TObjArray
cleanup and incidentally fixes three pre-existing leaks: the
tokens array in ExecuteFitRange was never freed, and the early
return paths in ExecutePrintLevel and the SECTOR check in
CheckCommands skipped the cleanup.

Build of libPMusr and musrfit is clean; full ctest suite passes
(85/85).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 15:38:15 +02:00
suter_a 76070f2098 msr2msr: replace TObjArray/TObjString with PStringUtils
Replace ROOT's TString::Tokenize() + TObjArray/TObjString token
handling with the dependency-free PStringUtils::Split() across
msr2msr_run, msr2msr_param and msr2msr_theory. Split() mirrors
Tokenize() semantics (skips empty tokens), so token counts and
indices are unchanged.

Using a std::vector<std::string> removes the manual TObjArray
cleanup and incidentally fixes a pre-existing leak in
msr2msr_theory, which tokenized in every branch but never deleted
the TObjArray.

Since msr2msr links only against ROOT (not PMusr, where
PStringUtils lives) and PStringUtils is pure C++17, compile
classes/PStringUtils.cpp directly into the msr2msr executable
rather than pulling in the whole PMusr library.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 15:16:50 +02:00
suter_a e7af0a781e libCuba: guard memcpy in SobolIni against negative length
GCC's -Wstringop-overflow flagged the memcpy in SobolIni() with a bound
of (size_t)(-4): on the (in practice unreachable) path where the Sobol
generator polynomial 'powers' is 0, the bit-count loop leaves inibits at
its initial -1, so inibits*sizeof underflows. The generator-polynomial
table always has a non-zero first column, so this never happens at run
time, but the compiler cannot prove it.

Guard the copy with 'if (inibits > 0)', which silences the false-positive
warning and hardens the edge case without changing behaviour for valid
input.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 15:02:17 +02:00
suter_a 8cdbb24929 PRun*: use reduction(+:mllh) instead of deprecated reduction(-:mllh)
OpenMP 5.2 deprecates the '-' reduction operator (-Wdeprecated-openmp)
because it is functionally identical to '+': the private reduction copy
is initialised to 0 and partial results are combined by addition in both
cases. All affected loops accumulate with 'mllh += ...', so switching to
reduction(+:mllh) is results-identical and silences the warning.

Fixes the pragma in PRunMuMinus.cpp and the two in PRunSingleHisto.cpp,
and corrects the now-inaccurate "for subtraction" doc comment.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 14:50:12 +02:00
suter_a b2db41194f musredit: capture 'this' explicitly to silence C++20 [-Wdeprecated]
The QProcess::finished lambdas used [=], which implicitly captures 'this'
to call member functions (exitStatusMusrWiz, fileReload,
exitStatusMusrSetSteps). Implicit 'this' capture via [=] is deprecated in
C++20; name it explicitly with [=, this]. Applied to both the qt6 and qt5
copies.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 14:43:11 +02:00
suter_a e3e84a6e56 PMsrHandler: escape '?' to avoid trigraph warning in date placeholder
The fallback date placeholder string contained the sequence '??-', which
the compiler interprets as a trigraph for '~' (-Wtrigraphs warning).
Escape the question marks (\?) so the literal string is unchanged while
the warning is silenced.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 14:37:35 +02:00
suter_a 1a85444763 PStartupHandler: replace TObjArray/TObjString with PStringUtils
Replace the ROOT TString::Tokenize()/TObjArray/TObjString machinery used
for parsing the RGB color code in OnCharacters() with the C++17
PStringUtils helpers (Split/IsInt/ToInt). Drops the manual heap cleanup
and the <TObjArray.h>/<TObjString.h> includes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 14:32:17 +02:00
suter_a 07f9c744b3 PStringUtils::IsInt: accept an optional leading sign
IsInt now recognises (possibly signed) integers such as "-5" or "+42",
making it slightly more permissive than TString::IsDigit(). A lone sign,
a double sign, or a sign following a digit are still rejected. strToNum
test expectations updated accordingly.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 14:14:11 +02:00
suter_a aa5cdf8d6a add strToNum test driver for PStringUtils
Stand-alone test under src/tests/strToNum exercising every PStringUtils
method (Split / IsInt / IsFloat / ToInt / ToDouble / IsEqualNoCase /
ContainsNoCase / BeginsWithNoCase). Three modes: built-in pass/fail
suite, ad-hoc inspection of command-line strings, and an interactive
prompt. Adds -h/--help and -i/--interactive options. Pure C++17, no
ROOT dependency.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 14:08:25 +02:00
suter_a bb32426005 PStringUtils::ToDouble: signal conversion errors like ToInt
ToDouble() had the same shortcoming as ToInt(): wrapping strtod() with a
nullptr endptr made a failed conversion indistinguishable from a
legitimate 0.0. Add an optional `bool *ok` out-parameter that reports
success. strtod() (with endptr + errno) is kept instead of
std::from_chars so the accepted input set stays identical to
TString::Atof() (leading whitespace skipped, leading '+' honoured,
trailing characters ignored); ok is set false on a non-numeric string or
an ERANGE overflow. The parameter defaults to nullptr, so existing call
sites keep compiling unchanged.

Convert the IsFloat-guarded ToDouble call sites in PMsrHandler to the
single-parse ToDouble(token, &ok) form (replacing the IsFloat() guard +
separate ToDouble() that parsed every token twice). All downstream
>=0 / <=0 / range checks are preserved, and push_back sites only append
on success so no spurious 0.0 is stored on error. Number-vs-keyword
discriminators (pos.error/boundary "none", rrf_phase/fourier-phase parX)
are restructured so the keyword branch is taken when ok is false.

As a side effect this fixes a latent gap in the GLOBAL rrf_freq handler,
where a non-numeric frequency previously slipped through with a stale
value instead of raising an error.

The IsFloat-guarded ToInt fit-range offsets (fgb/lgb) are intentionally
left untouched, as there the guard type differs from the conversion.

All 85 integration tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 12:08:01 +02:00
suter_a 4319b4ad69 PStringUtils::ToInt: signal conversion errors via from_chars
ToInt() previously wrapped strtol() with a nullptr endptr, so a failed
conversion was indistinguishable from a legitimate 0 (matching the old
TString::Atoi() behaviour). Switch the implementation to std::from_chars
and add an optional `bool *ok` out-parameter that reports success: it is
set to false on a non-numeric string or an out-of-range value, true
otherwise. Leading whitespace is skipped and trailing characters are
ignored, preserving the Atoi-like prefix semantics. The parameter
defaults to nullptr, so existing call sites keep compiling unchanged.

Convert the parse-validation call sites in PMsrHandler to the single
-parse ToInt(token, &ok) form, replacing the IsInt() guard + separate
ToInt() (which parsed every token twice). All downstream >0 / >=0 /
range / enum checks are preserved.

Left untouched the call sites where IsInt() acts as a structural
discriminator rather than a numeric validator (write path, xy-data
index-vs-label, fParamInUse usage scans) and the IsFloat-guarded ToInt
offsets, where switching to ToInt(&ok) would change parsing semantics.

All 85 integration tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 11:54:33 +02:00
suter_a b072a481ba PMsrHandler: replace ROOT tokenizer machinery with C++17 PStringUtils
Reduce the ROOT footprint of the MSR parser by removing the pervasive
TString::Tokenize / TObjArray / TObjString / dynamic_cast pattern (28
tokenize sites, 14 TObjArray, 106 TObjString) used to split lines into
tokens, together with the manual `delete tokens` cleanup.

Add a new dependency-free C++17 utility class PStringUtils (Split, IsInt,
IsFloat, ToInt, ToDouble, IsEqualNoCase, ContainsNoCase, BeginsWithNoCase)
that replicates the relevant TString semantics exactly, so it can be reused
elsewhere in the suite. IsInt/IsFloat tolerate surrounding whitespace to
match TString::IsDigit/IsFloat (needed for tokens split on ',' / ';' only).

The public API and the PMusr.h data structures keep TString unchanged; only
the internal tokenizing logic is rewritten. Net -451 lines in
PMsrHandler.cpp. All 85 integration tests pass.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-06 11:15:02 +02:00
suter_a dd604d4bf6 add mupp/Qt6 python option.
Build and Deploy Documentation / build-and-deploy (push) Successful in 31s
2026-05-28 09:30:52 +02:00
26 changed files with 1673 additions and 2035 deletions
+1 -1
View File
@@ -6,7 +6,7 @@ if (CMAKE_VERSION GREATER_EQUAL "3.3")
cmake_policy(SET CMP0167 NEW) cmake_policy(SET CMP0167 NEW)
endif () endif ()
project(musrfit VERSION 1.10.0 LANGUAGES C CXX) project(musrfit VERSION 1.11.0 LANGUAGES C CXX)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
+7
View File
@@ -12,6 +12,13 @@ or
https://bitbucket.org/muonspin/musrfit https://bitbucket.org/muonspin/musrfit
Release of V1.11.0, 2026/05/28
==============================
add to the mupp/Qt6 version the option to handle variables not only via the
Spirit/X3 interface, but also via Python3. It requires that ROOT is compiled
with Python support. For details see the musrfit-manual section mupp.
Release of V1.10.0, 2026/02/21 Release of V1.10.0, 2026/02/21
============================== ==============================
+5 -1
View File
@@ -75,7 +75,11 @@ target_include_directories(msr2data
) )
target_link_libraries(msr2data ${ROOT_LIBRARIES} ${MUSRFIT_LIBS}) 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}) target_link_libraries(msr2msr ${ROOT_LIBRARIES})
add_executable(musrfit musrfit.cpp) add_executable(musrfit musrfit.cpp)
+2
View File
@@ -106,6 +106,7 @@ add_library(PMusr SHARED
PMsgBoxDict.cxx PMsgBoxDict.cxx
PMsr2Data.cpp PMsr2Data.cpp
PMsrHandler.cpp PMsrHandler.cpp
PStringUtils.cpp
PMusrCanvas.cpp PMusrCanvas.cpp
PMusrCanvasDict.cxx PMusrCanvasDict.cxx
PMusr.cpp PMusr.cpp
@@ -270,6 +271,7 @@ install(
${MUSRFIT_INC}/PRunSingleHisto.h ${MUSRFIT_INC}/PRunSingleHisto.h
${MUSRFIT_INC}/PRunSingleHistoRRF.h ${MUSRFIT_INC}/PRunSingleHistoRRF.h
${MUSRFIT_INC}/PStartupHandler.h ${MUSRFIT_INC}/PStartupHandler.h
${MUSRFIT_INC}/PStringUtils.h
${MUSRFIT_INC}/PTheory.h ${MUSRFIT_INC}/PTheory.h
${MUSRFIT_INC}/PUserFcnBase.h ${MUSRFIT_INC}/PUserFcnBase.h
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
+61 -239
View File
@@ -64,10 +64,9 @@
#include <TFile.h> #include <TFile.h>
#include <TDatime.h> #include <TDatime.h>
#include <TString.h> #include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#include "PFitter.h" #include "PFitter.h"
#include "PStringUtils.h"
//+++ PSectorChisq class +++++++++++++++++++++++++++++++++++++++++++++++++++ //+++ PSectorChisq class +++++++++++++++++++++++++++++++++++++++++++++++++++
@@ -397,8 +396,6 @@ void PFitter::GetPhaseParams()
// default functions: // default functions:
// user functions cannot be checked! // user functions cannot be checked!
PMsrLines *theo = fRunInfo->GetMsrTheory(); PMsrLines *theo = fRunInfo->GetMsrTheory();
TObjArray *tok = nullptr;
TObjString *ostr = nullptr;
TString str; TString str;
int pos = -1; int pos = -1;
for (unsigned int i=0; i<theo->size(); i++) { for (unsigned int i=0; i<theo->size(); i++) {
@@ -423,18 +420,10 @@ void PFitter::GetPhaseParams()
continue; continue;
// extract phase token // extract phase token
tok = line.Tokenize(" \t"); std::vector<std::string> tok = PStringUtils::Split(line.Data(), " \t");
if (tok == nullptr) { if (static_cast<int>(tok.size()) > pos) {
std::cerr << "PFitter::GetPhaseParams(): **ERROR** couldn't tokenize theory line string." << std::endl; str = tok[pos].c_str();
return;
} }
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 // decode phase token. It can be funX, mapX, or a number
if (str.Contains("fun")) { // function if (str.Contains("fun")) { // function
@@ -491,22 +480,15 @@ PIntVector PFitter::GetParFromFun(const TString funStr)
PIntVector parVec; PIntVector parVec;
PMsrLines *funList = fRunInfo->GetMsrFunctions(); PMsrLines *funList = fRunInfo->GetMsrFunctions();
TObjArray *tok = nullptr;
TObjString *ostr = nullptr;
TString str; TString str;
for (int i=0; i<funList->size(); i++) { for (int i=0; i<funList->size(); i++) {
if (funList->at(i).fLine.Contains(funStr)) { if (funList->at(i).fLine.Contains(funStr)) {
// tokenize function string // tokenize function string
tok = funList->at(i).fLine.Tokenize(" =+-*/"); std::vector<std::string> tok = PStringUtils::Split(funList->at(i).fLine.Data(), " =+-*/");
if (tok == nullptr) {
std::cerr << "PFitter::GetParFromFun(): **ERROR** couldn't tokenize function string." << std::endl;
return parVec;
}
for (int j=1; j<tok->GetEntries(); j++) { for (int j=1; j<static_cast<int>(tok.size()); j++) {
ostr = dynamic_cast<TObjString*>(tok->At(j)); str = tok[j].c_str();
str = ostr->GetString();
// parse tok for parX // parse tok for parX
if (str.Contains("par")) { if (str.Contains("par")) {
// find start idx of par in token // 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; cmd.second = cmdLineNo;
fCmdList.push_back(cmd); fCmdList.push_back(cmd);
// filter out possible parameters for scan // filter out possible parameters for scan
TObjArray *tokens = nullptr; std::vector<std::string> tokens;
TObjString *ostr;
TString str; TString str;
UInt_t ival; UInt_t ival;
tokens = line.Tokenize(", \t"); tokens = PStringUtils::Split(line.Data(), ", \t");
for (Int_t i=0; i<tokens->GetEntries(); i++) { for (Int_t i=0; i<static_cast<int>(tokens.size()); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i)); str = tokens[i].c_str();
str = ostr->GetString();
if ((i==1) || (i==2)) { // parX / parY if ((i==1) || (i==2)) { // parX / parY
// check that token is a UInt_t // 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 << ">> command syntax for CONTOURS is: CONTOURS parameter-X parameter-Y [# of points]";
std::cerr << std::endl; std::cerr << std::endl;
fIsValid = false; fIsValid = false;
if (tokens) {
delete tokens;
tokens = nullptr;
}
break; break;
} }
ival = str.Atoi(); 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 << ">> command syntax for CONTOURS is: CONTOURS parameter-X parameter-Y [# of points]";
std::cerr << std::endl; std::cerr << std::endl;
fIsValid = false; fIsValid = false;
if (tokens) {
delete tokens;
tokens = nullptr;
}
break; break;
} }
// keep parameter // 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 << ">> command syntax for CONTOURS is: CONTOURS parameter-X parameter-Y [# of points]";
std::cerr << std::endl; std::cerr << std::endl;
fIsValid = false; fIsValid = false;
if (tokens) {
delete tokens;
tokens = nullptr;
}
break; break;
} }
ival = str.Atoi(); 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 << ">> command syntax for CONTOURS is: CONTOURS parameter-X parameter-Y [# of points]";
std::cerr << std::endl; std::cerr << std::endl;
fIsValid = false; fIsValid = false;
if (tokens) {
delete tokens;
tokens = nullptr;
}
break; break;
} }
fScanNoPoints = ival; fScanNoPoints = ival;
} }
} }
if (tokens) {
delete tokens;
tokens = nullptr;
}
} else if (line.Contains("EIGEN", TString::kIgnoreCase)) { } else if (line.Contains("EIGEN", TString::kIgnoreCase)) {
cmd.first = PMN_EIGEN; cmd.first = PMN_EIGEN;
cmd.second = cmdLineNo; cmd.second = cmdLineNo;
@@ -1090,15 +1046,13 @@ Bool_t PFitter::CheckCommands()
// (iii) FIT_RANGE start1 end1 start2 end2 ... startN endN // (iii) FIT_RANGE start1 end1 start2 end2 ... startN endN
// (iv) FIT_RANGE fgb+n0 lgb-n1 // (iv) FIT_RANGE fgb+n0 lgb-n1
// (v) FIT_RANGE fgb+n00 lgb-n01 fgb+n10 lgb-n11 ... fgb+nN0 lgb-nN1 // (v) FIT_RANGE fgb+n00 lgb-n01 fgb+n10 lgb-n11 ... fgb+nN0 lgb-nN1
TObjArray *tokens = nullptr; std::vector<std::string> tokens;
TObjString *ostr;
TString str; TString str;
tokens = line.Tokenize(", \t"); tokens = PStringUtils::Split(line.Data(), ", \t");
if (tokens->GetEntries() == 2) { // should only be RESET if (static_cast<int>(tokens.size()) == 2) { // should only be RESET
ostr = dynamic_cast<TObjString*>(tokens->At(1)); str = tokens[1].c_str();
str = ostr->GetString();
if (str.Contains("RESET", TString::kIgnoreCase)) { if (str.Contains("RESET", TString::kIgnoreCase)) {
cmd.first = PMN_FIT_RANGE; cmd.first = PMN_FIT_RANGE;
cmd.second = cmdLineNo; 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 << ">> with N the number of runs in the msr-file." << std::endl;
std::cerr << std::endl << ">> Found " << str.Data() << ", instead of RESET" << std::endl; std::cerr << std::endl << ">> Found " << str.Data() << ", instead of RESET" << std::endl;
fIsValid = false; fIsValid = false;
if (tokens) {
delete tokens;
tokens = nullptr;
}
break; break;
} }
} else if ((tokens->GetEntries() > 1) && (static_cast<UInt_t>(tokens->GetEntries()) % 2) == 1) { } else if ((static_cast<int>(tokens.size()) > 1) && (static_cast<UInt_t>(static_cast<int>(tokens.size())) % 2) == 1) {
if ((tokens->GetEntries() > 3) && ((static_cast<UInt_t>(tokens->GetEntries())-1)) != 2*fRunInfo->GetMsrRunList()->size()) { 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 << ">> PFitter::CheckCommands: **ERROR** in line " << it->fLineNo;
std::cerr << std::endl << ">> " << line.Data(); 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 << ">> 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 << ">> 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 << ">> 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; fIsValid = false;
if (tokens) {
delete tokens;
tokens = nullptr;
}
break; break;
} else { } else {
// check that all range entries are numbers or fgb+n0 / lgb-n1 // check that all range entries are numbers or fgb+n0 / lgb-n1
Bool_t ok = true; Bool_t ok = true;
for (Int_t n=1; n<tokens->GetEntries(); n++) { for (Int_t n=1; n<static_cast<int>(tokens.size()); n++) {
ostr = dynamic_cast<TObjString*>(tokens->At(n)); str = tokens[n].c_str();
str = ostr->GetString();
if (!str.IsFloat()) { if (!str.IsFloat()) {
if ((n%2 == 1) && (!str.Contains("fgb", TString::kIgnoreCase))) if ((n%2 == 1) && (!str.Contains("fgb", TString::kIgnoreCase)))
ok = false; 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 << ">> 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; std::cerr << std::endl << ">> Found token '" << str.Data() << "', which is not a floating point number." << std::endl;
fIsValid = false; fIsValid = false;
if (tokens) {
delete tokens;
tokens = nullptr;
}
break; 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 << ">> 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 << ">> with N the number of runs in the msr-file.";
fIsValid = false; fIsValid = false;
if (tokens) {
delete tokens;
tokens = nullptr;
}
break; break;
} }
if (tokens) {
delete tokens;
tokens = nullptr;
}
} else if (line.Contains("FIX", TString::kIgnoreCase)) { } else if (line.Contains("FIX", TString::kIgnoreCase)) {
// check if the given set of parameters (number or names) is present // check if the given set of parameters (number or names) is present
TObjArray *tokens = nullptr; std::vector<std::string> tokens;
TObjString *ostr;
TString str; TString str;
UInt_t ival; UInt_t ival;
tokens = line.Tokenize(", \t"); tokens = PStringUtils::Split(line.Data(), ", \t");
for (Int_t i=1; i<tokens->GetEntries(); i++) { for (Int_t i=1; i<static_cast<int>(tokens.size()); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i)); str = tokens[i].c_str();
str = ostr->GetString();
if (str.IsDigit()) { // token might be a parameter number if (str.IsDigit()) { // token might be a parameter number
ival = str.Atoi(); 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 << ">> Parameter " << ival << " is out of the Parameter Range [1," << fParams.size() << "]";
std::cerr << std::endl; std::cerr << std::endl;
fIsValid = false; fIsValid = false;
if (tokens) {
delete tokens;
tokens = nullptr;
}
break; break;
} }
} else { // token might be a parameter name } 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 << ">> Parameter '" << str.Data() << "' is NOT present as a parameter name";
std::cerr << std::endl; std::cerr << std::endl;
fIsValid = false; fIsValid = false;
if (tokens) {
delete tokens;
tokens = nullptr;
}
break; break;
} }
} }
} }
if (tokens) {
delete tokens;
tokens = nullptr;
}
// everything looks fine, feed the command list // everything looks fine, feed the command list
cmd.first = PMN_FIX; cmd.first = PMN_FIX;
@@ -1278,16 +1197,14 @@ Bool_t PFitter::CheckCommands()
fCmdList.push_back(cmd); fCmdList.push_back(cmd);
} else if (line.Contains("RELEASE", TString::kIgnoreCase)) { } else if (line.Contains("RELEASE", TString::kIgnoreCase)) {
// check if the given set of parameters (number or names) is present // check if the given set of parameters (number or names) is present
TObjArray *tokens = nullptr; std::vector<std::string> tokens;
TObjString *ostr;
TString str; TString str;
UInt_t ival; UInt_t ival;
tokens = line.Tokenize(", \t"); tokens = PStringUtils::Split(line.Data(), ", \t");
for (Int_t i=1; i<tokens->GetEntries(); i++) { for (Int_t i=1; i<static_cast<int>(tokens.size()); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i)); str = tokens[i].c_str();
str = ostr->GetString();
if (str.IsDigit()) { // token might be a parameter number if (str.IsDigit()) { // token might be a parameter number
ival = str.Atoi(); 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 << ">> Parameter " << ival << " is out of the Parameter Range [1," << fParams.size() << "]";
std::cerr << std::endl; std::cerr << std::endl;
fIsValid = false; fIsValid = false;
if (tokens) {
delete tokens;
tokens = nullptr;
}
break; break;
} }
} else { // token might be a parameter name } 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 << ">> Parameter '" << str.Data() << "' is NOT present as a parameter name";
std::cerr << std::endl; std::cerr << std::endl;
fIsValid = false; fIsValid = false;
if (tokens) {
delete tokens;
tokens = nullptr;
}
break; break;
} }
} }
} }
if (tokens) {
delete tokens;
tokens = nullptr;
}
cmd.first = PMN_RELEASE; cmd.first = PMN_RELEASE;
cmd.second = cmdLineNo; cmd.second = cmdLineNo;
fCmdList.push_back(cmd); fCmdList.push_back(cmd);
@@ -1348,16 +1253,14 @@ Bool_t PFitter::CheckCommands()
cmd.second = cmdLineNo; cmd.second = cmdLineNo;
fCmdList.push_back(cmd); fCmdList.push_back(cmd);
// filter out possible parameters for scan // filter out possible parameters for scan
TObjArray *tokens = nullptr; std::vector<std::string> tokens;
TObjString *ostr;
TString str; TString str;
UInt_t ival; UInt_t ival;
tokens = line.Tokenize(", \t"); tokens = PStringUtils::Split(line.Data(), ", \t");
for (Int_t i=0; i<tokens->GetEntries(); i++) { for (Int_t i=0; i<static_cast<int>(tokens.size()); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i)); str = tokens[i].c_str();
str = ostr->GetString();
if (i==1) { // get parameter number if (i==1) { // get parameter number
// check that token is a UInt_t // check that token is a UInt_t
if (!str.IsDigit()) { 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 << ">> command syntax for SCAN is: SCAN [parameter no [# of points [low high]]]";
std::cerr << std::endl; std::cerr << std::endl;
fIsValid = false; fIsValid = false;
if (tokens) {
delete tokens;
tokens = nullptr;
}
break; break;
} }
ival = str.Atoi(); 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 << ">> command syntax for SCAN is: SCAN [parameter no [# of points [low high]]]";
std::cerr << std::endl; std::cerr << std::endl;
fIsValid = false; fIsValid = false;
if (tokens) {
delete tokens;
tokens = nullptr;
}
break; break;
} }
// keep parameter // 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 << ">> command syntax for SCAN is: SCAN [parameter no [# of points [low high]]]";
std::cerr << std::endl; std::cerr << std::endl;
fIsValid = false; fIsValid = false;
if (tokens) {
delete tokens;
tokens = nullptr;
}
break; break;
} }
ival = str.Atoi(); 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 << ">> command syntax for SCAN is: SCAN [parameter no [# of points [low high]]]";
std::cerr << std::endl; std::cerr << std::endl;
fIsValid = false; fIsValid = false;
if (tokens) {
delete tokens;
tokens = nullptr;
}
break; break;
} }
fScanNoPoints = ival; 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 << ">> command syntax for SCAN is: SCAN [parameter no [# of points [low high]]]";
std::cerr << std::endl; std::cerr << std::endl;
fIsValid = false; fIsValid = false;
if (tokens) {
delete tokens;
tokens = nullptr;
}
break; break;
} }
fScanLow = str.Atof(); 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 << ">> command syntax for SCAN is: SCAN [parameter no [# of points [low high]]]";
std::cerr << std::endl; std::cerr << std::endl;
fIsValid = false; fIsValid = false;
if (tokens) {
delete tokens;
tokens = nullptr;
}
break; break;
} }
fScanHigh = str.Atof(); fScanHigh = str.Atof();
} }
} }
if (tokens) {
delete tokens;
tokens = nullptr;
}
} else if (line.Contains("SIMPLEX", TString::kIgnoreCase)) { } else if (line.Contains("SIMPLEX", TString::kIgnoreCase)) {
cmd.first = PMN_SIMPLEX; cmd.first = PMN_SIMPLEX;
cmd.second = cmdLineNo; cmd.second = cmdLineNo;
fCmdList.push_back(cmd); fCmdList.push_back(cmd);
} else if (line.Contains("STRATEGY", TString::kIgnoreCase)) { } else if (line.Contains("STRATEGY", TString::kIgnoreCase)) {
TObjArray *tokens = nullptr; std::vector<std::string> tokens;
TObjString *ostr;
TString str; TString str;
tokens = line.Tokenize(" \t"); tokens = PStringUtils::Split(line.Data(), " \t");
if (tokens->GetEntries() == 2) { if (static_cast<int>(tokens.size()) == 2) {
ostr = dynamic_cast<TObjString*>(tokens->At(1)); str = tokens[1].c_str();
str = ostr->GetString();
if (str.CompareTo("0") == 0) { // low if (str.CompareTo("0") == 0) { // low
fStrategy = 0; fStrategy = 0;
} else if (str.CompareTo("1") == 0) { // default } 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)) { } else if (line.Contains("USER_COVARIANCE", TString::kIgnoreCase)) {
cmd.first = PMN_USER_COVARIANCE; cmd.first = PMN_USER_COVARIANCE;
cmd.second = cmdLineNo; cmd.second = cmdLineNo;
@@ -1513,35 +1382,28 @@ Bool_t PFitter::CheckCommands()
fCmdList.push_back(cmd); fCmdList.push_back(cmd);
// check if the given sector arguments are valid time stamps, i.e. doubles and value < lgb time stamp // check if the given sector arguments are valid time stamps, i.e. doubles and value < lgb time stamp
TObjArray *tokens = nullptr; std::vector<std::string> tokens;
TObjString *ostr;
TString str; 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 << ">> PFitter::CheckCommands(): **FATAL ERROR** in line " << it->fLineNo;
std::cerr << std::endl << ">> " << line.Data(); std::cerr << std::endl << ">> " << line.Data();
std::cerr << std::endl << ">> At least one sector time stamp is expected."; std::cerr << std::endl << ">> At least one sector time stamp is expected.";
std::cerr << std::endl << ">> Will stop ..."; std::cerr << std::endl << ">> Will stop ...";
std::cerr << std::endl; std::cerr << std::endl;
// cleanup
if (tokens) {
delete tokens;
tokens = nullptr;
}
fIsValid = false; fIsValid = false;
fSectorFlag = false; fSectorFlag = false;
break; break;
} }
Double_t dval; 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 // keep time range of sector
PSectorChisq sec(fRunInfo->GetNoOfRuns()); PSectorChisq sec(fRunInfo->GetNoOfRuns());
// get parse tokens // get parse tokens
ostr = dynamic_cast<TObjString*>(tokens->At(i)); str = tokens[i].c_str();
str = ostr->GetString();
if (str.IsFloat()) { if (str.IsFloat()) {
dval = str.Atof(); dval = str.Atof();
// check that the sector time stamp is smaller than all lgb time stamps // 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 << ">> 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 << ">> Will stop ...";
std::cerr << std::endl; std::cerr << std::endl;
// cleanup
if (tokens) {
delete tokens;
tokens = nullptr;
}
fIsValid = false; fIsValid = false;
fSectorFlag = false; fSectorFlag = false;
return fIsValid; 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 << ">> The sector time stamp '" << str << "' is not a number.";
std::cerr << std::endl << ">> Will stop ..."; std::cerr << std::endl << ">> Will stop ...";
std::cerr << std::endl; std::cerr << std::endl;
// cleanup
if (tokens) {
delete tokens;
tokens = nullptr;
}
fIsValid = false; fIsValid = false;
fSectorFlag = false; fSectorFlag = false;
break; break;
} }
} }
if (tokens) {
delete tokens;
tokens = nullptr;
}
} else { // unkown command } else { // unkown command
std::cerr << std::endl << ">> PFitter::CheckCommands(): **FATAL ERROR** in line " << it->fLineNo << " an unkown command is found:"; std::cerr << std::endl << ">> PFitter::CheckCommands(): **FATAL ERROR** in line " << it->fLineNo << " an unkown command is found:";
std::cerr << std::endl << ">> " << line.Data(); std::cerr << std::endl << ">> " << line.Data();
@@ -1729,27 +1577,24 @@ Bool_t PFitter::ExecuteFitRange(UInt_t lineNo)
return true; return true;
} }
TObjArray *tokens = nullptr; std::vector<std::string> tokens;
TObjString *ostr;
TString str; TString str;
tokens = fCmdLines[lineNo].fLine.Tokenize(", \t"); tokens = PStringUtils::Split(fCmdLines[lineNo].fLine.Data(), ", \t");
PMsrRunList *runList = fRunInfo->GetMsrRunList(); PMsrRunList *runList = fRunInfo->GetMsrRunList();
// execute command, no error checking needed since this has been already carried out in CheckCommands() // 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); 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; Double_t start = 0.0, end = 0.0;
PDoublePair fitRange; PDoublePair fitRange;
PDoublePairVector fitRangeVector; PDoublePairVector fitRangeVector;
ostr = dynamic_cast<TObjString*>(tokens->At(1)); str = tokens[1].c_str();
str = ostr->GetString();
start = str.Atof(); start = str.Atof();
ostr = dynamic_cast<TObjString*>(tokens->At(2)); str = tokens[2].c_str();
str = ostr->GetString();
end = str.Atof(); end = str.Atof();
fitRange.first = start; fitRange.first = start;
@@ -1763,11 +1608,9 @@ Bool_t PFitter::ExecuteFitRange(UInt_t lineNo)
PDoublePairVector fitRangeVector; PDoublePairVector fitRangeVector;
for (UInt_t i=0; i<runList->size(); i++) { for (UInt_t i=0; i<runList->size(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(2*i+1)); str = tokens[2*i+1].c_str();
str = ostr->GetString();
start = str.Atof(); start = str.Atof();
ostr = dynamic_cast<TObjString*>(tokens->At(2*i+2)); str = tokens[2*i+2].c_str();
str = ostr->GetString();
end = str.Atof(); end = str.Atof();
fitRange.first = start; fitRange.first = start;
@@ -1795,15 +1638,13 @@ Bool_t PFitter::ExecuteFix(UInt_t lineNo)
{ {
std::cout << ">> PFitter::ExecuteFix(): " << fCmdLines[lineNo].fLine.Data() << std::endl; std::cout << ">> PFitter::ExecuteFix(): " << fCmdLines[lineNo].fLine.Data() << std::endl;
TObjArray *tokens = nullptr; std::vector<std::string> tokens;
TObjString *ostr;
TString str; 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++) { for (Int_t i=1; i<static_cast<int>(tokens.size()); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i)); str = tokens[i].c_str();
str = ostr->GetString();
if (str.IsDigit()) { // token is a parameter number if (str.IsDigit()) { // token is a parameter number
fMnUserParams.Fix(static_cast<UInt_t>(str.Atoi())-1); 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; return true;
} }
@@ -2124,19 +1960,17 @@ Bool_t PFitter::ExecutePrintLevel(UInt_t lineNo)
{ {
std::cout << ">> PFitter::ExecutePrintLevel(): " << fCmdLines[lineNo].fLine.Data() << std::endl; std::cout << ">> PFitter::ExecutePrintLevel(): " << fCmdLines[lineNo].fLine.Data() << std::endl;
TObjArray *tokens = nullptr; std::vector<std::string> tokens;
TObjString *ostr;
TString str; 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; std::cerr << std::endl << "**ERROR** from PFitter::ExecutePrintLevel(): SYNTAX: PRINT_LEVEL <N>, where <N>=0-3" << std::endl << std::endl;
return false; return false;
} }
ostr = (TObjString*)tokens->At(1); str = tokens[1].c_str();
str = ostr->GetString();
Int_t ival; Int_t ival;
if (str.IsDigit()) { if (str.IsDigit()) {
@@ -2159,11 +1993,6 @@ Bool_t PFitter::ExecutePrintLevel(UInt_t lineNo)
ROOT::Minuit2::MnPrint::SetLevel(fPrintLevel); ROOT::Minuit2::MnPrint::SetLevel(fPrintLevel);
#endif #endif
// clean up
if (tokens) {
delete tokens;
tokens = nullptr;
}
return true; return true;
} }
@@ -2180,17 +2009,15 @@ Bool_t PFitter::ExecutePrintLevel(UInt_t lineNo)
*/ */
Bool_t PFitter::ExecuteRelease(UInt_t lineNo) Bool_t PFitter::ExecuteRelease(UInt_t lineNo)
{ {
TObjArray *tokens = nullptr; std::vector<std::string> tokens;
TObjString *ostr;
TString str; 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; std::cout << ">> PFitter::ExecuteRelease(): " << fCmdLines[lineNo].fLine.Data() << std::endl;
for (Int_t i=1; i<tokens->GetEntries(); i++) { for (Int_t i=1; i<static_cast<int>(tokens.size()); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i)); str = tokens[i].c_str();
str = ostr->GetString();
if (str.IsDigit()) { // token is a parameter number if (str.IsDigit()) { // token is a parameter number
fMnUserParams.Release(static_cast<UInt_t>(str.Atoi())-1); 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; return true;
} }
File diff suppressed because it is too large Load Diff
+4 -12
View File
@@ -34,11 +34,11 @@
#include <TColor.h> #include <TColor.h>
#include <TRandom.h> #include <TRandom.h>
#include <TROOT.h> #include <TROOT.h>
#include <TObjString.h>
#include <TGFileDialog.h> #include <TGFileDialog.h>
#include "PMusrCanvas.h" #include "PMusrCanvas.h"
#include "PFourier.h" #include "PFourier.h"
#include "PStringUtils.h"
static const char *gFiletypes[] = { "Data files", "*.dat", static const char *gFiletypes[] = { "Data files", "*.dat",
"All files", "*", "All files", "*",
@@ -6408,23 +6408,15 @@ Bool_t PMusrCanvas::IsScaleN0AndBkg()
PMsrLines *cmd = fMsrHandler->GetMsrCommands(); PMsrLines *cmd = fMsrHandler->GetMsrCommands();
for (UInt_t i=0; i<cmd->size(); i++) { for (UInt_t i=0; i<cmd->size(); i++) {
if (cmd->at(i).fLine.Contains("SCALE_N0_BKG", TString::kIgnoreCase)) { if (cmd->at(i).fLine.Contains("SCALE_N0_BKG", TString::kIgnoreCase)) {
TObjArray *tokens = nullptr; std::vector<std::string> tokens = PStringUtils::Split(cmd->at(i).fLine.Data(), " \t");
TObjString *ostr = nullptr; if (tokens.size() != 2) {
TString str;
tokens = cmd->at(i).fLine.Tokenize(" \t");
if (tokens->GetEntries() != 2) {
std::cerr << std::endl << ">> PRunSingleHisto::IsScaleN0AndBkg(): **WARNING** Found uncorrect 'SCALE_N0_BKG' command, will ignore it."; 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; std::cerr << std::endl << ">> Allowed commands: SCALE_N0_BKG TRUE | FALSE" << std::endl;
return willScale; return willScale;
} }
ostr = dynamic_cast<TObjString*>(tokens->At(1)); if (PStringUtils::IsEqualNoCase(tokens[1], "FALSE")) {
str = ostr->GetString();
if (!str.CompareTo("FALSE", TString::kIgnoreCase)) {
willScale = false; willScale = false;
} }
// clean up
if (tokens)
delete tokens;
} }
} }
+12 -22
View File
@@ -38,12 +38,13 @@
#include <stdio.h> #include <stdio.h>
#include <iostream> #include <iostream>
#include <string>
#include <vector>
#include <TString.h> #include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#include "PMusr.h" #include "PMusr.h"
#include "PStringUtils.h"
#include "PRunAsymmetry.h" #include "PRunAsymmetry.h"
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
@@ -404,18 +405,15 @@ UInt_t PRunAsymmetry::GetNoOfFitBins()
*/ */
void PRunAsymmetry::SetFitRangeBin(const TString fitRange) void PRunAsymmetry::SetFitRangeBin(const TString fitRange)
{ {
TObjArray *tok = nullptr;
TObjString *ostr = nullptr;
TString str; TString str;
Ssiz_t idx = -1; Ssiz_t idx = -1;
Int_t offset = 0; 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 // handle fgb+n0 entry
ostr = dynamic_cast<TObjString*>(tok->At(1)); str = tok[1];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("+"); idx = str.First("+");
if (idx != -1) { // offset present if (idx != -1) { // offset present
@@ -426,8 +424,7 @@ void PRunAsymmetry::SetFitRangeBin(const TString fitRange)
fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
// handle lgb-n1 entry // handle lgb-n1 entry
ostr = dynamic_cast<TObjString*>(tok->At(2)); str = tok[2];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("-"); idx = str.First("-");
if (idx != -1) { // offset present if (idx != -1) { // offset present
@@ -436,16 +433,15 @@ void PRunAsymmetry::SetFitRangeBin(const TString fitRange)
offset = str.Atoi(); offset = str.Atoi();
} }
fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution; 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]] } else if ((tok.size() > 3) && (tok.size() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]]
Int_t pos = 2*(fRunNo+1)-1; 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 << ">> PRunAsymmetry::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl;
} else { } else {
// handle fgb+n0 entry // handle fgb+n0 entry
ostr = static_cast<TObjString*>(tok->At(pos)); str = tok[pos];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("+"); idx = str.First("+");
if (idx != -1) { // offset present if (idx != -1) { // offset present
@@ -456,8 +452,7 @@ void PRunAsymmetry::SetFitRangeBin(const TString fitRange)
fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
// handle lgb-n1 entry // handle lgb-n1 entry
ostr = static_cast<TObjString*>(tok->At(pos+1)); str = tok[pos+1];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("-"); idx = str.First("-");
if (idx != -1) { // offset present 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 << ">> PRunAsymmetry::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; 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 <stdio.h>
#include <iostream> #include <iostream>
#include <string>
#include <vector>
#include <TString.h> #include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#include "PMusr.h" #include "PMusr.h"
#include "PStringUtils.h"
#include "PRunAsymmetryBNMR.h" #include "PRunAsymmetryBNMR.h"
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
@@ -406,18 +407,15 @@ UInt_t PRunAsymmetryBNMR::GetNoOfFitBins()
*/ */
void PRunAsymmetryBNMR::SetFitRangeBin(const TString fitRange) void PRunAsymmetryBNMR::SetFitRangeBin(const TString fitRange)
{ {
TObjArray *tok = nullptr;
TObjString *ostr = nullptr;
TString str; TString str;
Ssiz_t idx = -1; Ssiz_t idx = -1;
Int_t offset = 0; 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 // handle fgb+n0 entry
ostr = dynamic_cast<TObjString*>(tok->At(1)); str = tok[1];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("+"); idx = str.First("+");
if (idx != -1) { // offset present if (idx != -1) { // offset present
@@ -428,8 +426,7 @@ void PRunAsymmetryBNMR::SetFitRangeBin(const TString fitRange)
fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
// handle lgb-n1 entry // handle lgb-n1 entry
ostr = dynamic_cast<TObjString*>(tok->At(2)); str = tok[2];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("-"); idx = str.First("-");
if (idx != -1) { // offset present if (idx != -1) { // offset present
@@ -438,16 +435,15 @@ void PRunAsymmetryBNMR::SetFitRangeBin(const TString fitRange)
offset = str.Atoi(); offset = str.Atoi();
} }
fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution; 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]] } else if ((tok.size() > 3) && (tok.size() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]]
Int_t pos = 2*(fRunNo+1)-1; 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 << ">> PRunAsymmetryBNMR::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl;
} else { } else {
// handle fgb+n0 entry // handle fgb+n0 entry
ostr = static_cast<TObjString*>(tok->At(pos)); str = tok[pos];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("+"); idx = str.First("+");
if (idx != -1) { // offset present if (idx != -1) { // offset present
@@ -458,8 +454,7 @@ void PRunAsymmetryBNMR::SetFitRangeBin(const TString fitRange)
fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
// handle lgb-n1 entry // handle lgb-n1 entry
ostr = static_cast<TObjString*>(tok->At(pos+1)); str = tok[pos+1];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("-"); idx = str.First("-");
if (idx != -1) { // offset present 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 << ">> PRunAsymmetryBNMR::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; 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 <iostream>
#include <fstream> #include <fstream>
#include <string>
#include <vector>
#include <TString.h> #include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#include "PMusr.h" #include "PMusr.h"
#include "PStringUtils.h"
#include "PRunAsymmetryRRF.h" #include "PRunAsymmetryRRF.h"
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
@@ -393,18 +394,15 @@ UInt_t PRunAsymmetryRRF::GetNoOfFitBins()
*/ */
void PRunAsymmetryRRF::SetFitRangeBin(const TString fitRange) void PRunAsymmetryRRF::SetFitRangeBin(const TString fitRange)
{ {
TObjArray *tok = nullptr;
TObjString *ostr = nullptr;
TString str; TString str;
Ssiz_t idx = -1; Ssiz_t idx = -1;
Int_t offset = 0; 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 // handle fgb+n0 entry
ostr = static_cast<TObjString*>(tok->At(1)); str = tok[1];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("+"); idx = str.First("+");
if (idx != -1) { // offset present if (idx != -1) { // offset present
@@ -415,8 +413,7 @@ void PRunAsymmetryRRF::SetFitRangeBin(const TString fitRange)
fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
// handle lgb-n1 entry // handle lgb-n1 entry
ostr = static_cast<TObjString*>(tok->At(2)); str = tok[2];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("-"); idx = str.First("-");
if (idx != -1) { // offset present if (idx != -1) { // offset present
@@ -425,16 +422,15 @@ void PRunAsymmetryRRF::SetFitRangeBin(const TString fitRange)
offset = str.Atoi(); offset = str.Atoi();
} }
fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution; 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]] } else if ((tok.size() > 3) && (tok.size() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]]
Int_t pos = 2*(fRunNo+1)-1; 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 << ">> PRunSingleHisto::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl;
} else { } else {
// handle fgb+n0 entry // handle fgb+n0 entry
ostr = static_cast<TObjString*>(tok->At(pos)); str = tok[pos];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("+"); idx = str.First("+");
if (idx != -1) { // offset present if (idx != -1) { // offset present
@@ -445,8 +441,7 @@ void PRunAsymmetryRRF::SetFitRangeBin(const TString fitRange)
fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
// handle lgb-n1 entry // handle lgb-n1 entry
ostr = static_cast<TObjString*>(tok->At(pos+1)); str = tok[pos+1];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("-"); idx = str.First("-");
if (idx != -1) { // offset present 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 << ">> PRunSingleHisto::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; 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 <TROOT.h>
#include <TSystem.h> #include <TSystem.h>
#include <TString.h> #include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#include <TFolder.h> #include <TFolder.h>
#include "PRunBase.h" #include "PRunBase.h"
+121 -412
View File
@@ -42,6 +42,7 @@
#include <string> #include <string>
#include <sstream> #include <sstream>
#include <memory> #include <memory>
#include <vector>
#include <TROOT.h> #include <TROOT.h>
#include <TSystem.h> #include <TSystem.h>
@@ -58,6 +59,7 @@
#include "TLemRunHeader.h" #include "TLemRunHeader.h"
#include "MuSR_td_PSI_bin.h" #include "MuSR_td_PSI_bin.h"
#include "mud.h" #include "mud.h"
#include "PStringUtils.h"
#ifdef PNEXUS_ENABLED #ifdef PNEXUS_ENABLED
#include "PNeXus.h" #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 if (pathName.CompareTo("???") == 0) { // not found in local directory and xml path
str = TString(musrpath); str = TString(musrpath);
// MUSRFULLDATAPATH has the structure: path_1:path_2:...:path_n // MUSRFULLDATAPATH has the structure: path_1:path_2:...:path_n
TObjArray *tokens = str.Tokenize(":"); std::vector<std::string> tokens = PStringUtils::Split(str.Data(), ":");
TObjString *ostr; for (UInt_t i=0; i<tokens.size(); i++) {
for (Int_t i=0; i<tokens->GetEntries(); i++) { str = TString(tokens[i]) + TString("/") + *runInfo.GetRunName(idx);
ostr = dynamic_cast<TObjString*>(tokens->At(i));
str = ostr->GetString() + TString("/") + *runInfo.GetRunName(idx);
TestFileName(str, ext); TestFileName(str, ext);
if (!str.IsNull()) { if (!str.IsNull()) {
pathName = str; pathName = str;
break; break;
} }
} }
// cleanup
if (tokens) {
delete tokens;
tokens = nullptr;
}
} }
// check if the file is found in the generated default path // check if the file is found in the generated default path
if (pathName.CompareTo("???") == 0) { // not found in MUSRFULLDATAPATH search if (pathName.CompareTo("???") == 0) { // not found in MUSRFULLDATAPATH search
str = TString(musrpath); str = TString(musrpath);
// MUSRFULLDATAPATH has the structure: path_1:path_2:...:path_n // MUSRFULLDATAPATH has the structure: path_1:path_2:...:path_n
TObjArray *tokens = str.Tokenize(":"); std::vector<std::string> tokens = PStringUtils::Split(str.Data(), ":");
TObjString *ostr;
pstr = runInfo.GetInstitute(idx); pstr = runInfo.GetInstitute(idx);
if (pstr == nullptr) { if (pstr == nullptr) {
std::cerr << std::endl << ">> PRunDataHandler::FileExistsCheck: **ERROR** Couldn't obtain institute data." << std::endl; 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(); pstr->ToUpper();
runInfo.SetBeamline(*pstr, idx); runInfo.SetBeamline(*pstr, idx);
for (Int_t i=0; i<tokens->GetEntries(); i++) { for (UInt_t i=0; i<tokens.size(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i)); str = TString(tokens[i]) + TString("/DATA/") +
str = ostr->GetString() + TString("/DATA/") +
*runInfo.GetInstitute(idx) + TString("/") + *runInfo.GetInstitute(idx) + TString("/") +
*runInfo.GetBeamline(idx) + TString("/") + *runInfo.GetBeamline(idx) + TString("/") +
*runInfo.GetRunName(idx); *runInfo.GetRunName(idx);
@@ -1218,11 +1211,6 @@ Bool_t PRunDataHandler::FileExistsCheck(PMsrRunBlock &runInfo, const UInt_t idx)
break; break;
} }
} }
// clean up
if (tokens) {
delete tokens;
tokens = nullptr;
}
} }
// no proper path name found // 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 if (pathName.CompareTo("???") == 0) { // not found in local directory and xml path
str = TString(musrpath); str = TString(musrpath);
// MUSRFULLDATAPATH has the structure: path_1:path_2:...:path_n // MUSRFULLDATAPATH has the structure: path_1:path_2:...:path_n
TObjArray *tokens = str.Tokenize(":"); std::vector<std::string> tokens = PStringUtils::Split(str.Data(), ":");
TObjString *ostr; for (UInt_t i=0; i<tokens.size(); i++) {
for (Int_t i=0; i<tokens->GetEntries(); i++) { str = TString(tokens[i]) + TString("/") + fln;
ostr = dynamic_cast<TObjString*>(tokens->At(i));
str = ostr->GetString() + TString("/") + fln;
if (gSystem->AccessPathName(str.Data())!=true) { // found if (gSystem->AccessPathName(str.Data())!=true) { // found
pathName = str; pathName = str;
break; break;
} }
} }
// cleanup
if (tokens) {
delete tokens;
tokens = nullptr;
}
} }
// no proper path name found // no proper path name found
if (pathName.CompareTo("???") == 0) { 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 if (pathName.CompareTo("???") == 0) { // not found in local directory and xml path
str = TString(musrpath); str = TString(musrpath);
// MUSRFULLDATAPATH has the structure: path_1:path_2:...:path_n // MUSRFULLDATAPATH has the structure: path_1:path_2:...:path_n
TObjArray *tokens = str.Tokenize(":"); std::vector<std::string> tokens = PStringUtils::Split(str.Data(), ":");
TObjString *ostr; for (UInt_t i=0; i<tokens.size(); i++) {
for (Int_t i=0; i<tokens->GetEntries(); i++) { str = TString(tokens[i]) + TString("/") + fileName;
ostr = dynamic_cast<TObjString*>(tokens->At(i));
str = ostr->GetString() + TString("/") + fileName;
if (gSystem->AccessPathName(str.Data())!=true) { // found if (gSystem->AccessPathName(str.Data())!=true) { // found
pathName = str; pathName = str;
break; break;
} }
} }
// cleanup
if (tokens) {
delete tokens;
tokens = nullptr;
}
} }
// no proper path name found // no proper path name found
if (pathName.CompareTo("???") == 0) { if (pathName.CompareTo("???") == 0) {
@@ -1544,97 +1518,22 @@ Bool_t PRunDataHandler::ReadRootFile()
TString s; TString s;
TObjArrayIter summIter(runSummary); TObjArrayIter summIter(runSummary);
TObjString *os(dynamic_cast<TObjString*>(summIter.Next())); TObjString *os(dynamic_cast<TObjString*>(summIter.Next()));
TObjArray *oa(nullptr);
TObjString *objTok(nullptr);
while (os != nullptr) { while (os != nullptr) {
s = os->GetString(); s = os->GetString();
// will put four parallel if's since it may be that more than one RA-values are on one line // a summary line has the structure 'RA-L = val RA-R = val ...', i.e. the value
if (s.Contains("RA-L")) { // follows two tokens after the tag. More than one RA-value may be on one line.
oa = s.Tokenize(" "); std::vector<std::string> oa = PStringUtils::Split(s.Data(), " ");
TObjArrayIter lineIter(oa); for (UInt_t k=0; k+2 < oa.size(); k++) {
objTok = dynamic_cast<TObjString*>(lineIter.Next()); if (oa[k+1] != "=")
while (objTok != nullptr) { continue;
if (!objTok->GetString().CompareTo("RA-L")) { if (oa[k] == "RA-L")
objTok = dynamic_cast<TObjString*>(lineIter.Next()); // "=" runData.SetRingAnode(0, TString(oa[k+2]).Atof());
if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) { else if (oa[k] == "RA-R")
objTok = dynamic_cast<TObjString*>(lineIter.Next()); // HV value runData.SetRingAnode(1, TString(oa[k+2]).Atof());
runData.SetRingAnode(0, objTok->GetString().Atof()); // fill RA-R value into the runData structure else if (oa[k] == "RA-T")
break; runData.SetRingAnode(2, TString(oa[k+2]).Atof());
} else if (oa[k] == "RA-B")
} runData.SetRingAnode(3, TString(oa[k+2]).Atof());
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;
}
} }
os = dynamic_cast<TObjString*>(summIter.Next()); // next summary line... os = dynamic_cast<TObjString*>(summIter.Next()); // next summary line...
@@ -1962,97 +1861,22 @@ Bool_t PRunDataHandler::ReadRootFile()
TString s; TString s;
TObjArrayIter summIter(runSummary); TObjArrayIter summIter(runSummary);
TObjString *os(dynamic_cast<TObjString*>(summIter.Next())); TObjString *os(dynamic_cast<TObjString*>(summIter.Next()));
TObjArray *oa(nullptr);
TObjString *objTok(nullptr);
while (os != nullptr) { while (os != nullptr) {
s = os->GetString(); s = os->GetString();
// will put four parallel if's since it may be that more than one RA-values are on one line // a summary line has the structure 'RA-L = val RA-R = val ...', i.e. the value
if (s.Contains("RA-L")) { // follows two tokens after the tag. More than one RA-value may be on one line.
oa = s.Tokenize(" "); std::vector<std::string> oa = PStringUtils::Split(s.Data(), " ");
TObjArrayIter lineIter(oa); for (UInt_t k=0; k+2 < oa.size(); k++) {
objTok = dynamic_cast<TObjString*>(lineIter.Next()); if (oa[k+1] != "=")
while (objTok != nullptr) { continue;
if (!objTok->GetString().CompareTo("RA-L")) { if (oa[k] == "RA-L")
objTok = dynamic_cast<TObjString*>(lineIter.Next()); // "=" runData.SetRingAnode(0, TString(oa[k+2]).Atof());
if ((objTok != nullptr) && !objTok->GetString().CompareTo("=")) { else if (oa[k] == "RA-R")
objTok = dynamic_cast<TObjString*>(lineIter.Next()); // HV value runData.SetRingAnode(1, TString(oa[k+2]).Atof());
runData.SetRingAnode(0, objTok->GetString().Atof()); // fill RA-R value into the runData structure else if (oa[k] == "RA-T")
break; runData.SetRingAnode(2, TString(oa[k+2]).Atof());
} else if (oa[k] == "RA-B")
} runData.SetRingAnode(3, TString(oa[k+2]).Atof());
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;
}
} }
os = dynamic_cast<TObjString*>(summIter.Next()); // next summary line... os = dynamic_cast<TObjString*>(summIter.Next()); // next summary line...
@@ -2454,8 +2278,7 @@ Bool_t PRunDataHandler::ReadWkmFile()
// read data --------------------------------------------------------- // read data ---------------------------------------------------------
UInt_t group_counter = 0; UInt_t group_counter = 0;
Int_t val; Int_t val;
TObjArray *tokens; std::vector<std::string> tokens;
TObjString *ostr;
TString str; TString str;
UInt_t histoNo = 0; UInt_t histoNo = 0;
PRawRunDataSet dataSet; PRawRunDataSet dataSet;
@@ -2489,30 +2312,22 @@ Bool_t PRunDataHandler::ReadWkmFile()
f.getline(instr, sizeof(instr)); f.getline(instr, sizeof(instr));
continue; 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."; std::cerr << std::endl << ">> PRunDataHandler::ReadWkmFile(): **ERROR** while reading data: coulnd't tokenize run data.";
return false; return false;
} }
for (Int_t i=0; i<tokens->GetEntries(); i++) { for (UInt_t i=0; i<tokens.size(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i)); str = tokens[i];
str = ostr->GetString();
val = ToInt(str, ok); val = ToInt(str, ok);
if (ok) { if (ok) {
histoData.push_back(val); histoData.push_back(val);
} else { } else {
std::cerr << std::endl << ">> PRunDataHandler::ReadWkmFile(): **ERROR** while reading data: data line contains non-integer values."; std::cerr << std::endl << ">> PRunDataHandler::ReadWkmFile(): **ERROR** while reading data: data line contains non-integer values.";
// clean up
delete tokens;
return false; return false;
} }
} }
// clean up
if (tokens) {
delete tokens;
tokens = nullptr;
}
} }
f.getline(instr, sizeof(instr)); f.getline(instr, sizeof(instr));
@@ -2523,29 +2338,21 @@ Bool_t PRunDataHandler::ReadWkmFile()
if (strlen(instr) != 0) { if (strlen(instr) != 0) {
// extract values // extract values
line = TString(instr); line = TString(instr);
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."; std::cerr << std::endl << ">> PRunDataHandler::ReadWkmFile(): **ERROR** while reading data: coulnd't tokenize run data.";
return false; return false;
} }
for (Int_t i=0; i<tokens->GetEntries(); i++) { for (UInt_t i=0; i<tokens.size(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i)); str = tokens[i];
str = ostr->GetString();
val = ToInt(str, ok); val = ToInt(str, ok);
if (ok) { if (ok) {
histoData.push_back(val); histoData.push_back(val);
} else { } else {
std::cerr << std::endl << ">> PRunDataHandler::ReadWkmFile(): **ERROR** while reading data: data line contains non-integer values."; std::cerr << std::endl << ">> PRunDataHandler::ReadWkmFile(): **ERROR** while reading data: data line contains non-integer values.";
// clean up
delete tokens;
return false; return false;
} }
} }
// clean up
if (tokens) {
delete tokens;
tokens = nullptr;
}
} }
// save the last histo if not empty // save the last histo if not empty
@@ -3242,8 +3049,7 @@ Bool_t PRunDataHandler::ReadMduAsciiFile()
Bool_t headerTag = false; Bool_t headerTag = false;
Bool_t dataTag = false; Bool_t dataTag = false;
Int_t dataLineCounter = 0; Int_t dataLineCounter = 0;
TObjString *ostr; std::vector<std::string> tokens;
TObjArray *tokens = nullptr;
TString str; TString str;
Int_t groups = 0; Int_t groups = 0;
Int_t channels = 0; Int_t channels = 0;
@@ -3287,9 +3093,9 @@ Bool_t PRunDataHandler::ReadMduAsciiFile()
if (workStr.BeginsWith("title:", TString::kIgnoreCase)) { if (workStr.BeginsWith("title:", TString::kIgnoreCase)) {
runData.SetRunTitle(TString(workStr.Data()+workStr.First(":")+2)); runData.SetRunTitle(TString(workStr.Data()+workStr.First(":")+2));
} else if (workStr.BeginsWith("field:", TString::kIgnoreCase)) { } 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 // 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 << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", invalid field entry in header.";
std::cerr << std::endl << ">> " << line.Data(); std::cerr << std::endl << ">> " << line.Data();
std::cerr << std::endl; std::cerr << std::endl;
@@ -3297,9 +3103,8 @@ Bool_t PRunDataHandler::ReadMduAsciiFile()
break; break;
} }
// check if field value is a number // check if field value is a number
ostr = dynamic_cast<TObjString*>(tokens->At(1)); if (TString(tokens[1]).IsFloat()) {
if (ostr->GetString().IsFloat()) { dval = TString(tokens[1]).Atof();
dval = ostr->GetString().Atof();
} else { } else {
std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", field value is not float/doulbe."; std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", field value is not float/doulbe.";
std::cerr << std::endl << ">> " << line.Data(); std::cerr << std::endl << ">> " << line.Data();
@@ -3308,10 +3113,9 @@ Bool_t PRunDataHandler::ReadMduAsciiFile()
break; break;
} }
// check units, accept (G), (T) // check units, accept (G), (T)
ostr = dynamic_cast<TObjString*>(tokens->At(2)); if (TString(tokens[2]).Contains("G"))
if (ostr->GetString().Contains("G"))
unitScaling = 1.0; unitScaling = 1.0;
else if (ostr->GetString().Contains("T")) else if (TString(tokens[2]).Contains("T"))
unitScaling = 1.0e4; unitScaling = 1.0e4;
else { else {
std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", unkown field units."; std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", unkown field units.";
@@ -3321,16 +3125,10 @@ Bool_t PRunDataHandler::ReadMduAsciiFile()
break; break;
} }
runData.SetField(dval*unitScaling); runData.SetField(dval*unitScaling);
// clean up tokens
if (tokens) {
delete tokens;
tokens = nullptr;
}
} else if (workStr.BeginsWith("temp:", TString::kIgnoreCase)) { } 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 // 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 << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", invalid temperatue entry in header.";
std::cerr << std::endl << ">> " << line.Data(); std::cerr << std::endl << ">> " << line.Data();
std::cerr << std::endl; std::cerr << std::endl;
@@ -3338,9 +3136,8 @@ Bool_t PRunDataHandler::ReadMduAsciiFile()
break; break;
} }
// check if field value is a number // check if field value is a number
ostr = dynamic_cast<TObjString*>(tokens->At(1)); if (TString(tokens[1]).IsFloat()) {
if (ostr->GetString().IsFloat()) { dval = TString(tokens[1]).Atof();
dval = ostr->GetString().Atof();
} else { } else {
std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", temperature value is not float/doulbe."; std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", temperature value is not float/doulbe.";
std::cerr << std::endl << ">> " << line.Data(); std::cerr << std::endl << ">> " << line.Data();
@@ -3349,12 +3146,6 @@ Bool_t PRunDataHandler::ReadMduAsciiFile()
break; break;
} }
runData.SetTemperature(0, dval, 0.0); runData.SetTemperature(0, dval, 0.0);
// clean up tokens
if (tokens) {
delete tokens;
tokens = nullptr;
}
} else if (workStr.BeginsWith("setup:", TString::kIgnoreCase)) { } else if (workStr.BeginsWith("setup:", TString::kIgnoreCase)) {
runData.SetSetup(TString(workStr.Data()+workStr.First(":")+2)); runData.SetSetup(TString(workStr.Data()+workStr.First(":")+2));
} else if (workStr.BeginsWith("groups:", TString::kIgnoreCase)) { } else if (workStr.BeginsWith("groups:", TString::kIgnoreCase)) {
@@ -3377,9 +3168,9 @@ Bool_t PRunDataHandler::ReadMduAsciiFile()
break; break;
} }
} else if (workStr.BeginsWith("resolution:", TString::kIgnoreCase)) { } 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 // 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 << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", invalid time resolution entry in header.";
std::cerr << std::endl << line.Data(); std::cerr << std::endl << line.Data();
std::cerr << std::endl; std::cerr << std::endl;
@@ -3387,9 +3178,8 @@ Bool_t PRunDataHandler::ReadMduAsciiFile()
break; break;
} }
// check if timeresolution value is a number // check if timeresolution value is a number
ostr = dynamic_cast<TObjString*>(tokens->At(1)); if (TString(tokens[1]).IsFloat()) {
if (ostr->GetString().IsFloat()) { dval = TString(tokens[1]).Atof();
dval = ostr->GetString().Atof();
} else { } else {
std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", time resolution value is not float/doulbe."; std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", time resolution value is not float/doulbe.";
std::cerr << std::endl << ">> " << line.Data(); std::cerr << std::endl << ">> " << line.Data();
@@ -3398,14 +3188,13 @@ Bool_t PRunDataHandler::ReadMduAsciiFile()
break; break;
} }
// check units, accept (fs), (ps), (ns), (us) // check units, accept (fs), (ps), (ns), (us)
ostr = dynamic_cast<TObjString*>(tokens->At(2)); if (TString(tokens[2]).Contains("fs"))
if (ostr->GetString().Contains("fs"))
unitScaling = 1.0e-6; unitScaling = 1.0e-6;
else if (ostr->GetString().Contains("ps")) else if (TString(tokens[2]).Contains("ps"))
unitScaling = 1.0e-3; unitScaling = 1.0e-3;
else if (ostr->GetString().Contains("ns")) else if (TString(tokens[2]).Contains("ns"))
unitScaling = 1.0; unitScaling = 1.0;
else if (ostr->GetString().Contains("us")) else if (TString(tokens[2]).Contains("us"))
unitScaling = 1.0e3; unitScaling = 1.0e3;
else { else {
std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", unkown time resolution units."; std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", unkown time resolution units.";
@@ -3415,12 +3204,6 @@ Bool_t PRunDataHandler::ReadMduAsciiFile()
break; break;
} }
runData.SetTimeResolution(dval*unitScaling); runData.SetTimeResolution(dval*unitScaling);
// clean up tokens
if (tokens) {
delete tokens;
tokens = nullptr;
}
} else { // error } else { // error
std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", illegal header line."; std::cerr << std::endl << ">> PRunDataHandler::ReadMduAsciiFile **ERROR** line no " << lineNo << ", illegal header line.";
std::cerr << std::endl; std::cerr << std::endl;
@@ -3429,9 +3212,9 @@ Bool_t PRunDataHandler::ReadMduAsciiFile()
} }
} else if (dataTag) { } else if (dataTag) {
dataLineCounter++; dataLineCounter++;
tokens = line.Tokenize(" ,\t"); tokens = PStringUtils::Split(line.Data(), " ,\t");
// check if the number of data line entries is correct // 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 << ">> 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:";
std::cerr << std::endl << ">> " << line.Data(); std::cerr << std::endl << ">> " << line.Data();
@@ -3440,15 +3223,8 @@ Bool_t PRunDataHandler::ReadMduAsciiFile()
break; break;
} }
for (Int_t i=1; i<tokens->GetEntries(); i++) { for (UInt_t i=1; i<tokens.size(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i)); data[i-1].push_back(TString(tokens[i]).Atof());
data[i-1].push_back(ostr->GetString().Atof());
}
// clean up tokens
if (tokens) {
delete tokens;
tokens = nullptr;
} }
} }
} }
@@ -3638,16 +3414,14 @@ Bool_t PRunDataHandler::ReadAsciiFile()
} else if (dataTag) { } else if (dataTag) {
if (line.IsWhitespace()) // ignore empty lines if (line.IsWhitespace()) // ignore empty lines
continue; continue;
TObjString *ostr;
TObjArray *tokens;
// Remove trailing end of line // 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 // 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 // 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 << ">> 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; std::cerr << std::endl;
success = false; success = false;
@@ -3655,35 +3429,32 @@ Bool_t PRunDataHandler::ReadAsciiFile()
} }
// get x // get x
ostr = dynamic_cast<TObjString*>(tokens->At(0)); if (!TString(tokens[0]).IsFloat()) {
if (!ostr->GetString().IsFloat()) { std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ": x = " << tokens[0] << " is not a number, sorry.";
std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ": x = " << ostr->GetString().Data() << " is not a number, sorry.";
std::cerr << std::endl; std::cerr << std::endl;
success = false; success = false;
break; break;
} }
x = ostr->GetString().Atof(); x = TString(tokens[0]).Atof();
// get y // get y
ostr = dynamic_cast<TObjString*>(tokens->At(1)); if (!TString(tokens[1]).IsFloat()) {
if (!ostr->GetString().IsFloat()) { std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ": y = " << tokens[1] << " is not a number, sorry.";
std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ": y = " << ostr->GetString().Data() << " is not a number, sorry.";
std::cerr << std::endl; std::cerr << std::endl;
success = false; success = false;
break; break;
} }
y = ostr->GetString().Atof(); y = TString(tokens[1]).Atof();
// get error y if present // get error y if present
if (tokens->GetEntries() == 3) { if (tokens.size() == 3) {
ostr = dynamic_cast<TObjString*>(tokens->At(2)); if (!TString(tokens[2]).IsFloat()) {
if (!ostr->GetString().IsFloat()) { std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ": error y = " << tokens[2] << " is not a number, sorry.";
std::cerr << std::endl << ">> PRunDataHandler::ReadAsciiFile **ERROR** line no " << lineNo << ": error y = " << ostr->GetString().Data() << " is not a number, sorry.";
std::cerr << std::endl; std::cerr << std::endl;
success = false; success = false;
break; break;
} }
ey = ostr->GetString().Atof(); ey = TString(tokens[2]).Atof();
if (ey == 0) { 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 << ">> 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; std::cerr << std::endl;
@@ -3695,12 +3466,6 @@ Bool_t PRunDataHandler::ReadAsciiFile()
ey = 1.0; ey = 1.0;
} }
// clean up tokens
if (tokens) {
delete tokens;
tokens = nullptr;
}
// keep values // keep values
xVec.push_back(x); xVec.push_back(x);
exVec.push_back(1.0); exVec.push_back(1.0);
@@ -3878,8 +3643,7 @@ Bool_t PRunDataHandler::ReadDBFile()
// variables needed to tokenize strings // variables needed to tokenize strings
TString tstr; TString tstr;
TObjString *ostr; std::vector<std::string> tokens;
TObjArray *tokens = nullptr;
while (!f.eof()) { while (!f.eof()) {
// get next line from file // get next line from file
@@ -3915,16 +3679,9 @@ Bool_t PRunDataHandler::ReadDBFile()
dbTag = 4; dbTag = 4;
// filter out all data tags // filter out all data tags
tokens = workStr.Tokenize(" ,\t"); tokens = PStringUtils::Split(workStr.Data(), " ,\t");
for (Int_t i=1; i<tokens->GetEntries(); i++) { for (UInt_t i=1; i<tokens.size(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i)); runData.fDataNonMusr.AppendDataTag(TString(tokens[i]));
runData.fDataNonMusr.AppendDataTag(ostr->GetString());
}
// clean up tokens
if (tokens) {
delete tokens;
tokens = nullptr;
} }
continue; continue;
} }
@@ -3954,18 +3711,12 @@ Bool_t PRunDataHandler::ReadDBFile()
// check if first real data line // check if first real data line
if (firstData) { if (firstData) {
// check if data are given just as rows are as labelled columns (see description above) // check if data are given just as rows are as labelled columns (see description above)
tokens = workStr.Tokenize(","); tokens = PStringUtils::Split(workStr.Data(), ",");
ostr = dynamic_cast<TObjString*>(tokens->At(0)); if (!TString(tokens[0]).IsFloat()) {
if (!ostr->GetString().IsFloat()) {
labelledFormat = true; labelledFormat = true;
} else { } else {
labelledFormat = false; labelledFormat = false;
} }
// clean up tokens
if (tokens) {
delete tokens;
tokens = nullptr;
}
// prepare data vector for use // prepare data vector for use
PDoubleVector dummy; PDoubleVector dummy;
@@ -3990,15 +3741,13 @@ Bool_t PRunDataHandler::ReadDBFile()
return false; return false;
} }
// split string in tokens // split string in tokens
tokens = workStr.Tokenize(","); // line has structure: runNo,,, runTitle tokens = PStringUtils::Split(workStr.Data(), ","); // line has structure: runNo,,, runTitle
ostr = dynamic_cast<TObjString*>(tokens->At(0)); tstr = TString(tokens[0]);
tstr = ostr->GetString();
if (!tstr.IsFloat()) { if (!tstr.IsFloat()) {
std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":";
std::cerr << std::endl << ">> " << workStr.Data(); std::cerr << std::endl << ">> " << workStr.Data();
std::cerr << std::endl << ">> Expected db-data line with structure: runNo,,, runTitle"; 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."; std::cerr << std::endl << ">> runNo = " << tstr.Data() << ", seems to be not a number.";
delete tokens;
return false; return false;
} }
val = tstr.Atof(); val = tstr.Atof();
@@ -4008,35 +3757,30 @@ Bool_t PRunDataHandler::ReadDBFile()
// remove all possible spaces // remove all possible spaces
workStr.ReplaceAll(" ", ""); workStr.ReplaceAll(" ", "");
// split string in tokens // split string in tokens
tokens = workStr.Tokenize("=,"); // line has structure: tag = val,err1,err2, tokens = PStringUtils::Split(workStr.Data(), "=,"); // line has structure: tag = val,err1,err2,
if (tokens->GetEntries() < 3) { if (tokens.size() < 3) {
std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":";
std::cerr << std::endl << ">> " << workStr.Data(); std::cerr << std::endl << ">> " << workStr.Data();
std::cerr << std::endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\"; std::cerr << std::endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\";
delete tokens;
return false; return false;
} }
ostr = dynamic_cast<TObjString*>(tokens->At(0)); tstr = TString(tokens[0]);
tstr = ostr->GetString();
idx = GetDataTagIndex(tstr, runData.fDataNonMusr.GetDataTags()); idx = GetDataTagIndex(tstr, runData.fDataNonMusr.GetDataTags());
if (idx == -1) { if (idx == -1) {
std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":";
std::cerr << std::endl << ">> " << workStr.Data(); std::cerr << std::endl << ">> " << workStr.Data();
std::cerr << std::endl << ">> data tag error: " << tstr.Data() << " seems not present in the data tag list"; std::cerr << std::endl << ">> data tag error: " << tstr.Data() << " seems not present in the data tag list";
delete tokens;
return false; return false;
} }
switch (tokens->GetEntries()) { switch (tokens.size()) {
case 3: // tag = val,,, case 3: // tag = val,,,
ostr = dynamic_cast<TObjString*>(tokens->At(1)); tstr = TString(tokens[1]);
tstr = ostr->GetString();
if (!tstr.IsFloat()) { if (!tstr.IsFloat()) {
std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":";
std::cerr << std::endl << ">> " << workStr.Data(); std::cerr << std::endl << ">> " << workStr.Data();
std::cerr << std::endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\"; 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."; std::cerr << std::endl << ">> val = " << tstr.Data() << ", seems to be not a number.";
delete tokens;
return false; return false;
} }
val = tstr.Atof(); val = tstr.Atof();
@@ -4046,27 +3790,23 @@ Bool_t PRunDataHandler::ReadDBFile()
case 4: // tag = val,err,, case 4: // tag = val,err,,
case 5: // tag = val,err1,err2, case 5: // tag = val,err1,err2,
// handle val // handle val
ostr = dynamic_cast<TObjString*>(tokens->At(1)); tstr = TString(tokens[1]);
tstr = ostr->GetString();
if (!tstr.IsFloat()) { if (!tstr.IsFloat()) {
std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":";
std::cerr << std::endl << ">> " << workStr.Data(); std::cerr << std::endl << ">> " << workStr.Data();
std::cerr << std::endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\"; 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."; std::cerr << std::endl << ">> val = " << tstr.Data() << ", seems to be not a number.";
delete tokens;
return false; return false;
} }
val = tstr.Atof(); val = tstr.Atof();
runData.fDataNonMusr.AppendSubData(idx, val); runData.fDataNonMusr.AppendSubData(idx, val);
// handle err1 (err2 will be ignored for the time being) // handle err1 (err2 will be ignored for the time being)
ostr = dynamic_cast<TObjString*>(tokens->At(2)); tstr = TString(tokens[2]);
tstr = ostr->GetString();
if (!tstr.IsFloat()) { if (!tstr.IsFloat()) {
std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":";
std::cerr << std::endl << ">> " << workStr.Data(); std::cerr << std::endl << ">> " << workStr.Data();
std::cerr << std::endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\"; 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."; std::cerr << std::endl << ">> err1 = " << tstr.Data() << ", seems to be not a number.";
delete tokens;
return false; return false;
} }
val = tstr.Atof(); 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 << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":";
std::cerr << std::endl << ">> " << workStr.Data(); std::cerr << std::endl << ">> " << workStr.Data();
std::cerr << std::endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\"; std::cerr << std::endl << ">> Expected db-data line with structure: tag = val,err1,err2,\\";
delete tokens;
return false; return false;
} }
} }
} else { // handle row formated data } else { // handle row formated data
// split string in tokens // split string in tokens
tokens = workStr.Tokenize(","); // line has structure: val1, err11, err12, ..., valn, errn1, errn2, runNo, , , , runTitle tokens = PStringUtils::Split(workStr.Data(), ","); // line has structure: val1, err11, err12, ..., valn, errn1, errn2, runNo, , , , runTitle
if (tokens->GetEntries() != static_cast<Int_t>(3*runData.fDataNonMusr.GetDataTags()->size()+1)) { if (tokens.size() != 3*runData.fDataNonMusr.GetDataTags()->size()+1) {
std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":";
std::cerr << std::endl << ">> " << workStr.Data(); 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 << ">> 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,..."; std::cerr << std::endl << ">> Perhaps there are commas without space inbetween, like 12.3,, 3.2,...";
delete tokens;
return false; return false;
} }
// extract data // extract data
Int_t j=0; 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 // handle value
ostr = dynamic_cast<TObjString*>(tokens->At(i)); tstr = TString(tokens[i]);
tstr = ostr->GetString();
if (!tstr.IsFloat()) { if (!tstr.IsFloat()) {
std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":"; std::cerr << std::endl << ">> PRunDataHandler::ReadDBFile **ERROR** in line no " << lineNo << ":";
std::cerr << std::endl << ">> " << workStr.Data(); 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 << ">> 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"; std::cerr << std::endl << ">> value=" << tstr.Data() << " seems not to be a number";
delete tokens;
return false; return false;
} }
runData.fDataNonMusr.AppendSubData(j, tstr.Atof()); runData.fDataNonMusr.AppendSubData(j, tstr.Atof());
// handle 1st error if present (2nd will be ignored for now) // handle 1st error if present (2nd will be ignored for now)
ostr = dynamic_cast<TObjString*>(tokens->At(i+1)); tstr = TString(tokens[i+1]);
tstr = ostr->GetString();
if (tstr.IsWhitespace()) { if (tstr.IsWhitespace()) {
runData.fDataNonMusr.AppendSubErrData(j, 1.0); runData.fDataNonMusr.AppendSubErrData(j, 1.0);
} else if (tstr.IsFloat()) { } else if (tstr.IsFloat()) {
@@ -4121,7 +3856,6 @@ Bool_t PRunDataHandler::ReadDBFile()
std::cerr << std::endl << ">> " << workStr.Data(); 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 << ">> 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"; std::cerr << std::endl << ">> error1=" << tstr.Data() << " seems not to be a number";
delete tokens;
return false; return false;
} }
j++; 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 LABELS found = " << runData.fDataNonMusr.GetLabels()->size();
std::cerr << std::endl << ">> number of Data tags found = " << runData.fDataNonMusr.GetDataTags()->size(); std::cerr << std::endl << ">> number of Data tags found = " << runData.fDataNonMusr.GetDataTags()->size();
std::cerr << std::endl << ">> They have to be equal!!"; std::cerr << std::endl << ">> They have to be equal!!";
if (tokens) {
delete tokens;
tokens = nullptr;
}
return false; return false;
} }
@@ -4168,12 +3898,6 @@ Bool_t PRunDataHandler::ReadDBFile()
} }
} }
// clean up tokens
if (tokens) {
delete tokens;
tokens = nullptr;
}
// keep run name // keep run name
runData.SetRunName(fRunName); runData.SetRunName(fRunName);
@@ -4218,8 +3942,7 @@ Bool_t PRunDataHandler::ReadDatFile()
// variables needed to tokenize strings // variables needed to tokenize strings
TString tstr; TString tstr;
TObjString *ostr; std::vector<std::string> tokens;
TObjArray *tokens = nullptr;
UInt_t noOfDataSets = 0, noOfEntries = 0; UInt_t noOfDataSets = 0, noOfEntries = 0;
PBoolVector isData; PBoolVector isData;
@@ -4239,8 +3962,8 @@ Bool_t PRunDataHandler::ReadDatFile()
if (line.IsWhitespace()) if (line.IsWhitespace())
continue; continue;
tokens = line.Tokenize(" \t"); tokens = PStringUtils::Split(line.Data(), " \t");
if (tokens == nullptr) { // error if (tokens.empty()) { // error
std::cerr << std::endl << ">> PRunDataHandler::ReadDatFile **ERROR** couldn't tokenize the line, in lineNo: " << lineNo; 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 << ">> line: '" << line << "'.";
std::cerr << std::endl; 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 // 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 // for the dat-files, label and dataTag are the same
noOfEntries = tokens->GetEntries(); noOfEntries = tokens.size();
for (Int_t i=0; i<noOfEntries; i++) { for (UInt_t i=0; i<noOfEntries; i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i)); tstr = TString(tokens[i]);
tstr = ostr->GetString();
if (!tstr.EndsWith("Err", TString::kExact)) { if (!tstr.EndsWith("Err", TString::kExact)) {
noOfDataSets++; noOfDataSets++;
isData.push_back(true); isData.push_back(true);
@@ -4274,8 +3996,8 @@ Bool_t PRunDataHandler::ReadDatFile()
std::cerr << std::endl; std::cerr << std::endl;
return false; return false;
} }
if (tokens->GetEntries() != noOfEntries) { // error if (tokens.size() != noOfEntries) { // error
std::cerr << std::endl << ">> PRunDataHandler::ReadDatFile **ERROR** data set with wrong number of entries: " << tokens->GetEntries() << ", should be " << noOfEntries << "."; std::cerr << std::endl << ">> 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 << ">> in line: " << lineNo;
std::cerr << std::endl << ">> line: '" << line << "'."; std::cerr << std::endl << ">> line: '" << line << "'.";
std::cerr << std::endl; std::cerr << std::endl;
@@ -4285,8 +4007,7 @@ Bool_t PRunDataHandler::ReadDatFile()
UInt_t idx = 0; UInt_t idx = 0;
for (UInt_t i=0; i<noOfEntries; i++) { for (UInt_t i=0; i<noOfEntries; i++) {
// 1st: check that entry is indeed a number // 1st: check that entry is indeed a number
ostr = dynamic_cast<TObjString*>(tokens->At(i)); tstr = TString(tokens[i]);
tstr = ostr->GetString();
if (!tstr.IsFloat()) { // make sure it is a number 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 << ">> PRunDataHandler::ReadDatFile **ERROR** data set entry is not a number: " << tstr.Data();
std::cerr << std::endl << ">> in line: " << lineNo; std::cerr << std::endl << ">> in line: " << lineNo;
@@ -4310,11 +4031,6 @@ Bool_t PRunDataHandler::ReadDatFile()
} }
} }
} }
// cleanup
if (tokens) {
delete tokens;
tokens = nullptr;
}
} }
f.close(); f.close();
@@ -6636,8 +6352,6 @@ TString PRunDataHandler::FileNameFromTemplate(TString &fileNameTemplate, Int_t r
{ {
TString result(""); TString result("");
TObjArray *tok=nullptr;
TObjString *ostr;
TString str; TString str;
// check year string // check year string
@@ -6660,19 +6374,18 @@ TString PRunDataHandler::FileNameFromTemplate(TString &fileNameTemplate, Int_t r
} }
// tokenize template string // tokenize template string
tok = fileNameTemplate.Tokenize("[]"); std::vector<std::string> tok = PStringUtils::Split(fileNameTemplate.Data(), "[]");
if (tok == nullptr) { if (tok.empty()) {
std::cerr << std::endl << ">> PRunDataHandler::FileNameFromTemplate: **ERROR** couldn't tokenize template!" << std::endl; std::cerr << std::endl << ">> PRunDataHandler::FileNameFromTemplate: **ERROR** couldn't tokenize template!" << std::endl;
return result; return result;
} }
if (tok->GetEntries()==1) { if (tok.size()==1) {
std::cerr << std::endl << ">> PRunDataHandler::FileNameFromTemplate: **WARNING** template without tags." << std::endl; std::cerr << std::endl << ">> PRunDataHandler::FileNameFromTemplate: **WARNING** template without tags." << std::endl;
} }
// go through the tokens and generate the result string // go through the tokens and generate the result string
for (Int_t i=0; i<tok->GetEntries(); i++) { for (UInt_t i=0; i<tok.size(); i++) {
ostr = dynamic_cast<TObjString*>(tok->At(i)); str = TString(tok[i]);
str = ostr->GetString();
// check tokens // check tokens
if (!str.CompareTo("yy", TString::kExact)) { // check for 'yy' 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 // everything fine here
ok = true; ok = true;
+13 -23
View File
@@ -36,11 +36,12 @@
#endif #endif
#include <iostream> #include <iostream>
#include <string>
#include <vector>
#include <TString.h> #include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#include "PStringUtils.h"
#include "PRunMuMinus.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(); Int_t chunk = (fEndTimeBin - fStartTimeBin)/omp_get_num_procs();
if (chunk < 10) if (chunk < 10)
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 #endif
for (i=fStartTimeBin; i < fEndTimeBin; ++i) { for (i=fStartTimeBin; i < fEndTimeBin; ++i) {
time = fData.GetDataTimeStart() + static_cast<Double_t>(i)*fData.GetDataTimeStep(); time = fData.GetDataTimeStart() + static_cast<Double_t>(i)*fData.GetDataTimeStep();
@@ -448,18 +449,15 @@ UInt_t PRunMuMinus::GetNoOfFitBins()
*/ */
void PRunMuMinus::SetFitRangeBin(const TString fitRange) void PRunMuMinus::SetFitRangeBin(const TString fitRange)
{ {
TObjArray *tok = nullptr;
TObjString *ostr = nullptr;
TString str; TString str;
Ssiz_t idx = -1; Ssiz_t idx = -1;
Int_t offset = 0; 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 // handle fgb+n0 entry
ostr = dynamic_cast<TObjString*>(tok->At(1)); str = tok[1];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("+"); idx = str.First("+");
if (idx != -1) { // offset present if (idx != -1) { // offset present
@@ -470,8 +468,7 @@ void PRunMuMinus::SetFitRangeBin(const TString fitRange)
fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
// handle lgb-n1 entry // handle lgb-n1 entry
ostr = dynamic_cast<TObjString*>(tok->At(2)); str = tok[2];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("-"); idx = str.First("-");
if (idx != -1) { // offset present if (idx != -1) { // offset present
@@ -480,16 +477,15 @@ void PRunMuMinus::SetFitRangeBin(const TString fitRange)
offset = str.Atoi(); offset = str.Atoi();
} }
fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution; 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]] } else if ((tok.size() > 3) && (tok.size() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]]
Int_t pos = 2*(fRunNo+1)-1; 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 << ">> PRunMuMinus::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl;
} else { } else {
// handle fgb+n0 entry // handle fgb+n0 entry
ostr = dynamic_cast<TObjString*>(tok->At(pos)); str = tok[pos];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("+"); idx = str.First("+");
if (idx != -1) { // offset present if (idx != -1) { // offset present
@@ -500,8 +496,7 @@ void PRunMuMinus::SetFitRangeBin(const TString fitRange)
fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
// handle lgb-n1 entry // handle lgb-n1 entry
ostr = dynamic_cast<TObjString*>(tok->At(pos+1)); str = tok[pos+1];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("-"); idx = str.First("-");
if (idx != -1) { // offset present 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 << ">> PRunMuMinus::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; 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 <cmath>
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <string>
#include <vector>
#include <TString.h> #include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#include "PMusr.h" #include "PMusr.h"
#include "PStringUtils.h"
#include "PRunSingleHisto.h" #include "PRunSingleHisto.h"
//-------------------------------------------------------------------------- //--------------------------------------------------------------------------
@@ -439,7 +440,7 @@ Double_t PRunSingleHisto::CalcChiSquareExpected(const std::vector<Double_t>& par
* <b>OpenMP Parallelization:</b> * <b>OpenMP Parallelization:</b>
* - Dynamic scheduling with chunk size = (N_bins / N_processors), minimum 10 * - Dynamic scheduling with chunk size = (N_bins / N_processors), minimum 10
* - Private variables per thread: i, time, theo, data * - 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>When to Use Maximum Likelihood vs. χ²:</b>
* - <b>Use likelihood:</b> Low count rates (< 100 counts/bin), asymmetric errors * - <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(); Int_t chunk = (fEndTimeBin - fStartTimeBin)/omp_get_num_procs();
if (chunk < 10) if (chunk < 10)
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 #endif
for (i=fStartTimeBin; i<fEndTimeBin; ++i) { for (i=fStartTimeBin; i<fEndTimeBin; ++i) {
time = fData.GetDataTimeStart() + static_cast<Double_t>(i)*fData.GetDataTimeStep(); 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(); Int_t chunk = (fEndTimeBin - fStartTimeBin)/omp_get_num_procs();
if (chunk < 10) if (chunk < 10)
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 #endif
for (i=fStartTimeBin; i<fEndTimeBin; ++i) { for (i=fStartTimeBin; i<fEndTimeBin; ++i) {
time = fData.GetDataTimeStart() + static_cast<Double_t>(i)*fData.GetDataTimeStep(); time = fData.GetDataTimeStart() + static_cast<Double_t>(i)*fData.GetDataTimeStep();
@@ -844,18 +845,15 @@ UInt_t PRunSingleHisto::GetNoOfFitBins()
*/ */
void PRunSingleHisto::SetFitRangeBin(const TString fitRange) void PRunSingleHisto::SetFitRangeBin(const TString fitRange)
{ {
TObjArray *tok = nullptr;
TObjString *ostr = nullptr;
TString str; TString str;
Ssiz_t idx = -1; Ssiz_t idx = -1;
Int_t offset = 0; 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 // handle fgb+n0 entry
ostr = dynamic_cast<TObjString*>(tok->At(1)); str = tok[1];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("+"); idx = str.First("+");
if (idx != -1) { // offset present if (idx != -1) { // offset present
@@ -866,8 +864,7 @@ void PRunSingleHisto::SetFitRangeBin(const TString fitRange)
fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
// handle lgb-n1 entry // handle lgb-n1 entry
ostr = dynamic_cast<TObjString*>(tok->At(2)); str = tok[2];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("-"); idx = str.First("-");
if (idx != -1) { // offset present if (idx != -1) { // offset present
@@ -876,16 +873,15 @@ void PRunSingleHisto::SetFitRangeBin(const TString fitRange)
offset = str.Atoi(); offset = str.Atoi();
} }
fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution; 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]] } else if ((tok.size() > 3) && (tok.size() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]]
Int_t pos = 2*(fRunNo+1)-1; 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 << ">> PRunSingleHisto::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl;
} else { } else {
// handle fgb+n0 entry // handle fgb+n0 entry
ostr = dynamic_cast<TObjString*>(tok->At(pos)); str = tok[pos];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("+"); idx = str.First("+");
if (idx != -1) { // offset present if (idx != -1) { // offset present
@@ -896,8 +892,7 @@ void PRunSingleHisto::SetFitRangeBin(const TString fitRange)
fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
// handle lgb-n1 entry // handle lgb-n1 entry
ostr = dynamic_cast<TObjString*>(tok->At(pos+1)); str = tok[pos+1];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("-"); idx = str.First("-");
if (idx != -1) { // offset present 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 << ">> PRunSingleHisto::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; 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(); PMsrLines *cmd = fMsrInfo->GetMsrCommands();
for (UInt_t i=0; i<cmd->size(); i++) { for (UInt_t i=0; i<cmd->size(); i++) {
if (cmd->at(i).fLine.Contains("SCALE_N0_BKG", TString::kIgnoreCase)) { if (cmd->at(i).fLine.Contains("SCALE_N0_BKG", TString::kIgnoreCase)) {
TObjArray *tokens = nullptr; std::vector<std::string> tokens = PStringUtils::Split(cmd->at(i).fLine.Data(), " \t");
TObjString *ostr = nullptr; if (tokens.size() != 2) {
TString str;
tokens = cmd->at(i).fLine.Tokenize(" \t");
if (tokens->GetEntries() != 2) {
std::cerr << std::endl << ">> PRunSingleHisto::IsScaleN0AndBkg(): **WARNING** Found uncorrect 'SCALE_N0_BKG' command, will ignore it."; 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; std::cerr << std::endl << ">> Allowed commands: SCALE_N0_BKG TRUE | FALSE" << std::endl;
return willScale; return willScale;
} }
ostr = dynamic_cast<TObjString*>(tokens->At(1)); if (PStringUtils::IsEqualNoCase(tokens[1], "FALSE")) {
str = ostr->GetString();
if (!str.CompareTo("FALSE", TString::kIgnoreCase)) {
willScale = false; willScale = false;
} }
// clean up
if (tokens)
delete tokens;
} }
} }
+12 -22
View File
@@ -39,13 +39,14 @@
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <memory> #include <memory>
#include <string>
#include <vector>
#include <TString.h> #include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#include <TH1F.h> #include <TH1F.h>
#include "PMusr.h" #include "PMusr.h"
#include "PStringUtils.h"
#include "PFourier.h" #include "PFourier.h"
#include "PRunSingleHistoRRF.h" #include "PRunSingleHistoRRF.h"
@@ -528,18 +529,15 @@ UInt_t PRunSingleHistoRRF::GetNoOfFitBins()
*/ */
void PRunSingleHistoRRF::SetFitRangeBin(const TString fitRange) void PRunSingleHistoRRF::SetFitRangeBin(const TString fitRange)
{ {
TObjArray *tok = nullptr;
TObjString *ostr = nullptr;
TString str; TString str;
Ssiz_t idx = -1; Ssiz_t idx = -1;
Int_t offset = 0; 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 // handle fgb+n0 entry
ostr = dynamic_cast<TObjString*>(tok->At(1)); str = tok[1];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("+"); idx = str.First("+");
if (idx != -1) { // offset present if (idx != -1) { // offset present
@@ -550,8 +548,7 @@ void PRunSingleHistoRRF::SetFitRangeBin(const TString fitRange)
fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
// handle lgb-n1 entry // handle lgb-n1 entry
ostr = dynamic_cast<TObjString*>(tok->At(2)); str = tok[2];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("-"); idx = str.First("-");
if (idx != -1) { // offset present if (idx != -1) { // offset present
@@ -560,16 +557,15 @@ void PRunSingleHistoRRF::SetFitRangeBin(const TString fitRange)
offset = str.Atoi(); offset = str.Atoi();
} }
fFitEndTime = (fGoodBins[1] - offset - fT0s[0]) * fTimeResolution; 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]] } else if ((tok.size() > 3) && (tok.size() % 2 == 1)) { // structure FIT_RANGE fgb[+n00] lgb[-n01] [fgb[+n10] lgb[-n11] ... fgb[+nN0] lgb[-nN1]]
Int_t pos = 2*(fRunNo+1)-1; 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 << ">> PRunSingleHistoRRF::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl;
} else { } else {
// handle fgb+n0 entry // handle fgb+n0 entry
ostr = dynamic_cast<TObjString*>(tok->At(pos)); str = tok[pos];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("+"); idx = str.First("+");
if (idx != -1) { // offset present if (idx != -1) { // offset present
@@ -580,8 +576,7 @@ void PRunSingleHistoRRF::SetFitRangeBin(const TString fitRange)
fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution; fFitStartTime = (fGoodBins[0] + offset - fT0s[0]) * fTimeResolution;
// handle lgb-n1 entry // handle lgb-n1 entry
ostr = dynamic_cast<TObjString*>(tok->At(pos+1)); str = tok[pos+1];
str = ostr->GetString();
// check if there is an offset present // check if there is an offset present
idx = str.First("-"); idx = str.First("-");
if (idx != -1) { // offset present 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 << ">> PRunSingleHistoRRF::SetFitRangeBin(): **ERROR** invalid FIT_RANGE command found: '" << fitRange << "'";
std::cerr << std::endl << ">> will ignore it. Sorry ..." << std::endl; 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 <iostream>
#include <fstream> #include <fstream>
#include <TObjArray.h>
#include <TObjString.h>
#include <TColor.h> #include <TColor.h>
#include <TList.h> #include <TList.h>
#include <TXMLAttr.h> #include <TXMLAttr.h>
#include "PStartupHandler.h" #include "PStartupHandler.h"
#include "PStringUtils.h"
ClassImpQ(PStartupHandler) ClassImpQ(PStartupHandler)
@@ -451,8 +450,6 @@ void PStartupHandler::OnEndElement(const Char_t *str)
*/ */
void PStartupHandler::OnCharacters(const Char_t *str) void PStartupHandler::OnCharacters(const Char_t *str)
{ {
TObjArray *tokens;
TObjString *ostr;
TString tstr; TString tstr;
Int_t color, r, g, b, ival; Int_t color, r, g, b, ival;
@@ -481,60 +478,44 @@ void PStartupHandler::OnCharacters(const Char_t *str)
} }
break; break;
case eColor: case eColor:
// check that str is a rbg code {
tstr = TString(str); // check that str is a rbg code
tokens = tstr.Tokenize(","); std::vector<std::string> rgb = PStringUtils::Split(str, ",");
// check that there any tokens // check there is the right number of tokens
if (!tokens) { if (rgb.size() != 3) {
std::cerr << std::endl << "PStartupHandler **WARNING** '" << str << "' is not a rbg code, will ignore it"; std::cerr << std::endl << "PStartupHandler **WARNING** '" << str << "' is not a rbg code, will ignore it";
std::cerr << std::endl; std::cerr << std::endl;
return; 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; break;
case eUnits: case eUnits:
tstr = TString(str); 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 <iostream>
#include <vector> #include <vector>
#include <string>
#include <cmath> #include <cmath>
#include <TObject.h> #include <TObject.h>
#include <TString.h> #include <TString.h>
#include <TF1.h> #include <TF1.h>
#include <TObjString.h>
#include <TObjArray.h>
#include <TClass.h> #include <TClass.h>
#include <TMath.h> #include <TMath.h>
#include <Math/SpecFuncMathMore.h> #include <Math/SpecFuncMathMore.h>
#include "PMsrHandler.h" #include "PMsrHandler.h"
#include "PStringUtils.h"
#include "PTheory.h" #include "PTheory.h"
#define SQRT_TWO 1.41421356237 #define SQRT_TWO 1.41421356237
@@ -169,18 +169,14 @@ PTheory::PTheory(PMsrHandler *msrInfo, UInt_t runNo, const Bool_t hasParent) : f
str.Resize(index); str.Resize(index);
// tokenize line // tokenize line
TObjArray *tokens; std::vector<std::string> tokens = PStringUtils::Split(str.Data(), " \t");
TObjString *ostr; if (tokens.empty()) {
tokens = str.Tokenize(" \t");
if (!tokens) {
std::cerr << std::endl << ">> PTheory::PTheory: **SEVERE ERROR** Couldn't tokenize theory block line " << line->fLineNo << "."; 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 << ">> line content: " << line->fLine.Data();
std::cerr << std::endl; std::cerr << std::endl;
exit(0); exit(0);
} }
ostr = dynamic_cast<TObjString*>(tokens->At(0)); str = tokens[0];
str = ostr->GetString();
// search the theory function // search the theory function
UInt_t idx = SearchDataBase(str); 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 // 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))) { ((idx != THEORY_USER_FCN) && (idx != THEORY_POLYNOM))) {
std::cerr << std::endl << ">> PTheory::PTheory: **ERROR** Theory line '" << line->fLine.Data() << "'"; 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 << ">> 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; std::cerr << std::endl;
fValid = false; fValid = false;
} }
@@ -209,9 +205,8 @@ PTheory::PTheory(PMsrHandler *msrInfo, UInt_t runNo, const Bool_t hasParent) : f
Int_t status; Int_t status;
UInt_t value; UInt_t value;
Bool_t ok = false; Bool_t ok = false;
for (Int_t i=1; i<tokens->GetEntries(); i++) { for (UInt_t i=1; i<tokens.size(); i++) {
ostr = dynamic_cast<TObjString*>(tokens->At(i)); str = tokens[i];
str = ostr->GetString();
// if userFcn, the first entry is the function name and needs to be handled specially // if userFcn, the first entry is the function name and needs to be handled specially
if ((fType == THEORY_USER_FCN) && ((i == 1) || (i == 2))) { 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 << ">> See line no " << line->fLineNo;
std::cerr << std::endl; std::cerr << std::endl;
fValid = false; fValid = false;
// clean up
if (tokens) {
delete tokens;
tokens = nullptr;
}
return; return;
} else if (!TClass::GetDict(fUserFcnClassName.Data())) { } else if (!TClass::GetDict(fUserFcnClassName.Data())) {
std::cerr << std::endl << ">> PTheory::PTheory: **ERROR** user function class '" << fUserFcnClassName.Data() << "' not found."; 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 << ">> See line no " << line->fLineNo;
std::cerr << std::endl; std::cerr << std::endl;
fValid = false; fValid = false;
// clean up
if (tokens) {
delete tokens;
tokens = nullptr;
}
return; 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; PMsrLineStructure *line;
TString str, tidy; TString str, tidy;
Char_t substr[256]; Char_t substr[256];
TObjArray *tokens = nullptr;
TObjString *ostr = nullptr;
Int_t idx = THEORY_UNDEFINED; Int_t idx = THEORY_UNDEFINED;
for (UInt_t i=1; i<fullTheoryBlock->size(); i++) { 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 if (index > 0) // theory line comment present
str.Resize(index); str.Resize(index);
// tokenize line // 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 // make a handable string out of the asymmetry token
ostr = dynamic_cast<TObjString*>(tokens->At(0)); str = tokens[0];
str = ostr->GetString();
// check if the line is just a '+' if so nothing to be done // check if the line is just a '+' if so nothing to be done
if (str.Contains("+")) if (str.Contains("+"))
continue; continue;
@@ -987,14 +965,13 @@ void PTheory::MakeCleanAndTidyTheoryBlock(PMsrLines *fullTheoryBlock)
if (idx == THEORY_UNDEFINED) if (idx == THEORY_UNDEFINED)
return; return;
// check that there enough tokens. This should not be necessay at this point but ... // 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; return;
// make tidy string // make tidy string
snprintf(substr, sizeof(substr), "%-10s", fgTheoDataBase[idx].fName.Data()); snprintf(substr, sizeof(substr), "%-10s", fgTheoDataBase[idx].fName.Data());
tidy = TString(substr); tidy = TString(substr);
for (Int_t j=1; j<tokens->GetEntries(); j++) { for (UInt_t j=1; j<tokens.size(); j++) {
ostr = dynamic_cast<TObjString*>(tokens->At(j)); str = tokens[j];
str = ostr->GetString();
snprintf(substr, sizeof(substr), "%6s", str.Data()); snprintf(substr, sizeof(substr), "%6s", str.Data());
tidy += TString(substr); tidy += TString(substr);
} }
@@ -1005,19 +982,13 @@ void PTheory::MakeCleanAndTidyTheoryBlock(PMsrLines *fullTheoryBlock)
} else { } else {
tidy += TString(" "); 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; tidy += fgTheoDataBase[idx].fComment;
else else
tidy += fgTheoDataBase[idx].fCommentTimeShift; tidy += fgTheoDataBase[idx].fCommentTimeShift;
} }
// write tidy string back into theory block // write tidy string back into theory block
(*fullTheoryBlock)[i].fLine = tidy; (*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; PMsrLineStructure *line;
TString str, tidy; TString str, tidy;
TObjArray *tokens = nullptr;
TObjString *ostr;
Char_t substr[256]; Char_t substr[256];
// init tidy // init tidy
@@ -1052,13 +1021,12 @@ void PTheory::MakeCleanAndTidyPolynom(UInt_t i, PMsrLines *fullTheoryBlock)
// copy line content to str in order to remove comments // copy line content to str in order to remove comments
str = line->fLine.Copy(); str = line->fLine.Copy();
// tokenize line // 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 // 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++) { for (Int_t j=1; j<max; j++) {
ostr = dynamic_cast<TObjString*>(tokens->At(j)); str = tokens[j];
str = ostr->GetString();
if (str.Contains("(")) { // comment present if (str.Contains("(")) { // comment present
max=j; max=j;
break; break;
@@ -1066,8 +1034,7 @@ void PTheory::MakeCleanAndTidyPolynom(UInt_t i, PMsrLines *fullTheoryBlock)
} }
for (Int_t j=1; j<max; j++) { for (Int_t j=1; j<max; j++) {
ostr = dynamic_cast<TObjString*>(tokens->At(j)); str = tokens[j];
str = ostr->GetString();
snprintf(substr, sizeof(substr), "%6s", str.Data()); snprintf(substr, sizeof(substr), "%6s", str.Data());
tidy += TString(substr); tidy += TString(substr);
} }
@@ -1077,12 +1044,6 @@ void PTheory::MakeCleanAndTidyPolynom(UInt_t i, PMsrLines *fullTheoryBlock)
// write tidy string back into theory block // write tidy string back into theory block
(*fullTheoryBlock)[i].fLine = tidy; (*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; PMsrLineStructure *line;
TString str, tidy; TString str, tidy;
TObjArray *tokens = nullptr;
TObjString *ostr;
// init tidy // init tidy
tidy = TString("userFcn "); 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 // copy line content to str in order to remove comments
str = line->fLine.Copy(); str = line->fLine.Copy();
// tokenize line // 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++) { for (UInt_t j=1; j<tokens.size(); j++) {
ostr = dynamic_cast<TObjString*>(tokens->At(j)); str = tokens[j];
str = ostr->GetString();
tidy += TString(" ") + str; tidy += TString(" ") + str;
} }
// write tidy string back into theory block // write tidy string back into theory block
(*fullTheoryBlock)[i].fLine = tidy; (*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; int inibits = -1, bit;
for( j = powers; j; j >>= 1 ) ++inibits; for( j = powers; j; j >>= 1 ) ++inibits;
memcpy(pv, pini, inibits*sizeof *pini); if( inibits > 0 )
memcpy(pv, pini, inibits*sizeof *pini);
pini += 8; pini += 8;
for( bit = inibits; bit <= nbits; ++bit ) { 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 <cstdlib>
#include <TString.h> #include <TString.h>
#include <TObjArray.h>
#include <TObjString.h> #include "PStringUtils.h"
//------------------------------------------------------------- //-------------------------------------------------------------
// msr block header tags // msr block header tags
@@ -88,8 +88,6 @@ bool msr2msr_run(char *str, const std::size_t size)
TString run(str); TString run(str);
TString line(str); TString line(str);
TObjArray *tokens;
TObjString *ostr[2];
// for filtering // for filtering
run.ToUpper(); run.ToUpper();
@@ -100,8 +98,8 @@ bool msr2msr_run(char *str, const std::size_t size)
line.Remove(idx); line.Remove(idx);
// tokenize run // tokenize run
tokens = line.Tokenize(" \t"); std::vector<std::string> tokens = PStringUtils::Split(line.Data(), " \t");
if (tokens->GetEntries() < 4) { if (tokens.size() < 4) {
std::cout << std::endl << "**ERROR**: Something is wrong with the RUN block header:"; std::cout << std::endl << "**ERROR**: Something is wrong with the RUN block header:";
std::cout << std::endl << " >> " << str; std::cout << std::endl << " >> " << str;
std::cout << std::endl << " >> no <msr-file-out> is created"; 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; 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()); snprintf(str, size, "%s (name beamline institute data-file-format)", line.Data());
return true; return true;
} }
if (run.Contains("NEMU")) { 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)", tokens[1].c_str());
snprintf(str, size, "RUN %s MUE4 PSI WKM (name beamline institute data-file-format)", ostr[0]->GetString().Data());
} else if (run.Contains("PSI")) { } 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)", 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")) { } 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)", 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")) { } 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)", snprintf(str, size, "RUN %s %s RAL NEXUS (name beamline institute data-file-format)",
ostr[0]->GetString().Data(), ostr[1]->GetString().Data()); tokens[1].c_str(), tokens[2].c_str());
}
// clean up
if (tokens) {
delete tokens;
tokens = nullptr;
} }
return true; return true;
@@ -165,38 +150,34 @@ bool msr2msr_param(char *str)
// handle parameter line // handle parameter line
TString line(str); TString line(str);
TObjArray *tokens;
TObjString *ostr[6];
char sstr[256]; char sstr[256];
char spaces[256]; char spaces[256];
tokens = line.Tokenize(" \t"); std::vector<std::string> tokens = PStringUtils::Split(line.Data(), " \t");
Int_t noTokens = tokens->GetEntries(); std::size_t noTokens = tokens.size();
if (noTokens == 4) { if (noTokens == 4) {
for (unsigned int i=0; i<4; i++)
ostr[i] = dynamic_cast<TObjString*>(tokens->At(i));
// number // number
snprintf(sstr, sizeof(sstr), "%10s", ostr[0]->GetString().Data()); snprintf(sstr, sizeof(sstr), "%10s", tokens[0].c_str());
// name // name
strcat(sstr, " "); strcat(sstr, " ");
strcat(sstr, ostr[1]->GetString().Data()); strcat(sstr, tokens[1].c_str());
memset(spaces, 0, sizeof(spaces)); memset(spaces, 0, sizeof(spaces));
memset(spaces, ' ', 12-strlen(ostr[1]->GetString().Data())); memset(spaces, ' ', 12-strlen(tokens[1].c_str()));
strcat(sstr, spaces); strcat(sstr, spaces);
// value // value
strcat(sstr, ostr[2]->GetString().Data()); strcat(sstr, tokens[2].c_str());
if (strlen(ostr[2]->GetString().Data()) < 10) { if (strlen(tokens[2].c_str()) < 10) {
memset(spaces, 0, sizeof(spaces)); memset(spaces, 0, sizeof(spaces));
memset(spaces, ' ', 10-strlen(ostr[2]->GetString().Data())); memset(spaces, ' ', 10-strlen(tokens[2].c_str()));
strcat(sstr, spaces); strcat(sstr, spaces);
} else { } else {
strcat(sstr, " "); strcat(sstr, " ");
} }
// step // step
strcat(sstr, ostr[3]->GetString().Data()); strcat(sstr, tokens[3].c_str());
if (strlen(ostr[3]->GetString().Data()) < 12) { if (strlen(tokens[3].c_str()) < 12) {
memset(spaces, 0, sizeof(spaces)); memset(spaces, 0, sizeof(spaces));
memset(spaces, ' ', 12-strlen(ostr[3]->GetString().Data())); memset(spaces, ' ', 12-strlen(tokens[3].c_str()));
strcat(sstr, spaces); strcat(sstr, spaces);
} else { } else {
strcat(sstr, " "); strcat(sstr, " ");
@@ -204,30 +185,28 @@ bool msr2msr_param(char *str)
strcat(sstr, "none"); strcat(sstr, "none");
strcpy(str, sstr); strcpy(str, sstr);
} else if (noTokens == 6) { } else if (noTokens == 6) {
for (unsigned int i=0; i<6; i++)
ostr[i] = dynamic_cast<TObjString*>(tokens->At(i));
// number // number
snprintf(sstr, sizeof(sstr), "%10s", ostr[0]->GetString().Data()); snprintf(sstr, sizeof(sstr), "%10s", tokens[0].c_str());
// name // name
strcat(sstr, " "); strcat(sstr, " ");
strcat(sstr, ostr[1]->GetString().Data()); strcat(sstr, tokens[1].c_str());
memset(spaces, 0, sizeof(spaces)); memset(spaces, 0, sizeof(spaces));
memset(spaces, ' ', 12-strlen(ostr[1]->GetString().Data())); memset(spaces, ' ', 12-strlen(tokens[1].c_str()));
strcat(sstr, spaces); strcat(sstr, spaces);
// value // value
strcat(sstr, ostr[2]->GetString().Data()); strcat(sstr, tokens[2].c_str());
if (strlen(ostr[2]->GetString().Data()) < 10) { if (strlen(tokens[2].c_str()) < 10) {
memset(spaces, 0, sizeof(spaces)); memset(spaces, 0, sizeof(spaces));
memset(spaces, ' ', 10-strlen(ostr[2]->GetString().Data())); memset(spaces, ' ', 10-strlen(tokens[2].c_str()));
strcat(sstr, spaces); strcat(sstr, spaces);
} else { } else {
strcat(sstr, " "); strcat(sstr, " ");
} }
// step // step
strcat(sstr, ostr[3]->GetString().Data()); strcat(sstr, tokens[3].c_str());
if (strlen(ostr[3]->GetString().Data()) < 12) { if (strlen(tokens[3].c_str()) < 12) {
memset(spaces, 0, sizeof(spaces)); memset(spaces, 0, sizeof(spaces));
memset(spaces, ' ', 12-strlen(ostr[3]->GetString().Data())); memset(spaces, ' ', 12-strlen(tokens[3].c_str()));
strcat(sstr, spaces); strcat(sstr, spaces);
} else { } else {
strcat(sstr, " "); strcat(sstr, " ");
@@ -235,25 +214,19 @@ bool msr2msr_param(char *str)
// pos. error // pos. error
strcat(sstr, "none "); strcat(sstr, "none ");
// lower boundary // lower boundary
strcat(sstr, ostr[4]->GetString().Data()); strcat(sstr, tokens[4].c_str());
if (strlen(ostr[4]->GetString().Data()) < 8) { if (strlen(tokens[4].c_str()) < 8) {
memset(spaces, 0, sizeof(spaces)); memset(spaces, 0, sizeof(spaces));
memset(spaces, ' ', 8-strlen(ostr[4]->GetString().Data())); memset(spaces, ' ', 8-strlen(tokens[4].c_str()));
strcat(sstr, spaces); strcat(sstr, spaces);
} else { } else {
strcat(sstr, " "); strcat(sstr, " ");
} }
// upper boundary // upper boundary
strcat(sstr, ostr[5]->GetString().Data()); strcat(sstr, tokens[5].c_str());
strcpy(str, sstr); strcpy(str, sstr);
} }
// clean up
if (tokens) {
delete tokens;
tokens = nullptr;
}
return true; return true;
} }
@@ -274,8 +247,7 @@ bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams)
{ {
// handle theory line // handle theory line
TString line(str); TString line(str);
TObjArray *tokens; std::vector<std::string> tokens;
TObjString *ostr;
char sstr[256]; char sstr[256];
if ((line.Contains("sktt") || line.Contains("statKTTab")) && line.Contains("glf")) { // static Gauss KT LF table 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 "); strcpy(sstr, "statGssKTLF ");
// tokenize the rest and extract the first two parameters // tokenize the rest and extract the first two parameters
tokens = line.Tokenize(" \t"); tokens = PStringUtils::Split(line.Data(), " \t");
Int_t noTokens = tokens->GetEntries(); std::size_t noTokens = tokens.size();
if (noTokens < 3) { if (noTokens < 3) {
std::cout << std::endl << "**ERROR** in THEORY block"; std::cout << std::endl << "**ERROR** in THEORY block";
std::cout << std::endl << " Line: '" << str << "' is not a valid statKTTab statement."; 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++) { for (Int_t i=1; i<3; i++) {
strcat(sstr, " "); strcat(sstr, " ");
ostr = dynamic_cast<TObjString*>(tokens->At(i)); strcat(sstr, tokens[i].c_str());
strcat(sstr, ostr->GetString().Data());
} }
strcat(sstr, " (frequency damping)"); strcat(sstr, " (frequency damping)");
strcpy(str, sstr); strcpy(str, sstr);
@@ -303,8 +274,8 @@ bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams)
strcpy(sstr, "statExpKTLF "); strcpy(sstr, "statExpKTLF ");
// tokenize the rest and extract the first two parameters // tokenize the rest and extract the first two parameters
tokens = line.Tokenize(" \t"); tokens = PStringUtils::Split(line.Data(), " \t");
Int_t noTokens = tokens->GetEntries(); std::size_t noTokens = tokens.size();
if (noTokens < 3) { if (noTokens < 3) {
std::cout << std::endl << "**ERROR** in THEORY block"; std::cout << std::endl << "**ERROR** in THEORY block";
std::cout << std::endl << " Line: '" << str << "' is not a valid statKTTab statement."; 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++) { for (Int_t i=1; i<3; i++) {
strcat(sstr, " "); strcat(sstr, " ");
ostr = dynamic_cast<TObjString*>(tokens->At(i)); strcat(sstr, tokens[i].c_str());
strcat(sstr, ostr->GetString().Data());
} }
strcat(sstr, " (frequency damping)"); strcat(sstr, " (frequency damping)");
strcpy(str, sstr); strcpy(str, sstr);
@@ -323,8 +293,8 @@ bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams)
strcpy(sstr, "dynGssKTLF "); strcpy(sstr, "dynGssKTLF ");
// tokenize the rest and extract the first three parameters // tokenize the rest and extract the first three parameters
tokens = line.Tokenize(" \t"); tokens = PStringUtils::Split(line.Data(), " \t");
Int_t noTokens = tokens->GetEntries(); std::size_t noTokens = tokens.size();
if (noTokens < 4) { if (noTokens < 4) {
std::cout << std::endl << "**ERROR** in THEORY block"; std::cout << std::endl << "**ERROR** in THEORY block";
std::cout << std::endl << " Line: '" << str << "' is not a valid dynmKTTab statement."; 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++) { for (Int_t i=1; i<4; i++) {
strcat(sstr, " "); strcat(sstr, " ");
ostr = dynamic_cast<TObjString*>(tokens->At(i)); strcat(sstr, tokens[i].c_str());
strcat(sstr, ostr->GetString().Data());
} }
strcat(sstr, " (frequency damping hopping-rate)"); strcat(sstr, " (frequency damping hopping-rate)");
strcpy(str, sstr); strcpy(str, sstr);
@@ -343,8 +312,8 @@ bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams)
strcpy(sstr, "dynExpKTLF "); strcpy(sstr, "dynExpKTLF ");
// tokenize the rest and extract the first three parameters // tokenize the rest and extract the first three parameters
tokens = line.Tokenize(" \t"); tokens = PStringUtils::Split(line.Data(), " \t");
Int_t noTokens = tokens->GetEntries(); std::size_t noTokens = tokens.size();
if (noTokens < 4) { if (noTokens < 4) {
std::cout << std::endl << "**ERROR** in THEORY block"; std::cout << std::endl << "**ERROR** in THEORY block";
std::cout << std::endl << " Line: '" << str << "' is not a valid dynmKTTab statement."; 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++) { for (Int_t i=1; i<4; i++) {
strcat(sstr, " "); strcat(sstr, " ");
ostr = dynamic_cast<TObjString*>(tokens->At(i)); strcat(sstr, tokens[i].c_str());
strcat(sstr, ostr->GetString().Data());
} }
strcat(sstr, " (frequency damping hopping-rate)"); strcat(sstr, " (frequency damping hopping-rate)");
strcpy(str, sstr); strcpy(str, sstr);
@@ -366,8 +334,8 @@ bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams)
strcpy(sstr, "internFld "); strcpy(sstr, "internFld ");
// tokenize the rest and extract the first three parameters // tokenize the rest and extract the first three parameters
tokens = line.Tokenize(" \t"); tokens = PStringUtils::Split(line.Data(), " \t");
Int_t noTokens = tokens->GetEntries(); std::size_t noTokens = tokens.size();
if (noTokens < 4) { if (noTokens < 4) {
std::cout << std::endl << "**ERROR** in THEORY block"; std::cout << std::endl << "**ERROR** in THEORY block";
std::cout << std::endl << " Line: '" << str << "' is not a valid internFld statement."; 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_"); strcat(sstr, " _x_");
for (Int_t i=1; i<4; i++) { for (Int_t i=1; i<4; i++) {
strcat(sstr, " "); strcat(sstr, " ");
ostr = dynamic_cast<TObjString*>(tokens->At(i)); strcat(sstr, tokens[i].c_str());
strcat(sstr, ostr->GetString().Data());
} }
strcat(sstr, " (fraction phase frequency Trate Lrate)"); strcat(sstr, " (fraction phase frequency Trate Lrate)");
strcpy(str, sstr); strcpy(str, sstr);
@@ -390,8 +357,8 @@ bool msr2msr_theory(char *str, int &tag, int &noOfAddionalParams)
strcpy(sstr, "internBsl "); strcpy(sstr, "internBsl ");
// tokenize the rest and extract the first three parameters // tokenize the rest and extract the first three parameters
tokens = line.Tokenize(" \t"); tokens = PStringUtils::Split(line.Data(), " \t");
Int_t noTokens = tokens->GetEntries(); std::size_t noTokens = tokens.size();
if (noTokens < 4) { if (noTokens < 4) {
std::cout << std::endl << "**ERROR** in THEORY block"; std::cout << std::endl << "**ERROR** in THEORY block";
std::cout << std::endl << " Line: '" << str << "' is not a valid internBsl statement."; 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_"); strcat(sstr, " _x_");
for (Int_t i=1; i<4; i++) { for (Int_t i=1; i<4; i++) {
strcat(sstr, " "); strcat(sstr, " ");
ostr = dynamic_cast<TObjString*>(tokens->At(i)); strcat(sstr, tokens[i].c_str());
strcat(sstr, ostr->GetString().Data());
} }
strcat(sstr, " (fraction phase frequency Trate Lrate)"); strcat(sstr, " (fraction phase frequency Trate Lrate)");
strcpy(str, sstr); strcpy(str, sstr);
+6 -13
View File
@@ -36,13 +36,12 @@
#include <iostream> #include <iostream>
#include <fstream> #include <fstream>
#include <vector> #include <vector>
#include <string>
#include <memory> #include <memory>
#include <TApplication.h> #include <TApplication.h>
#include <TROOT.h> #include <TROOT.h>
#include <TString.h> #include <TString.h>
#include <TObjArray.h>
#include <TObjString.h>
#include <TSAXParser.h> #include <TSAXParser.h>
#ifdef HAVE_GIT_REV_H #ifdef HAVE_GIT_REV_H
@@ -50,6 +49,7 @@
#endif #endif
#include "PMusr.h" #include "PMusr.h"
#include "PStringUtils.h"
#include "PStartupHandler.h" #include "PStartupHandler.h"
#include "PMsrHandler.h" #include "PMsrHandler.h"
#include "PRunDataHandler.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; return false;
} }
} else { // should be something like h0-hN with h0, hN numbers } else { // should be something like h0-hN with h0, hN numbers
TObjArray *tok = tstr.Tokenize("-"); std::vector<std::string> tok = PStringUtils::Split(tstr.Data(), "-");
if (tok->GetEntries() != 2) { if (tok.size() != 2) {
std::cerr << std::endl << ">> musrFT **ERROR** found --histo argument '" << tstr << "' which is not of the form <h0>-<hN>." << std::endl; std::cerr << std::endl << ">> musrFT **ERROR** found --histo argument '" << tstr << "' which is not of the form <h0>-<hN>." << std::endl;
startupParam.histo.clear(); startupParam.histo.clear();
return false; return false;
} }
TObjString *ostr;
TString sstr(""); TString sstr("");
Int_t first=0, last=0; Int_t first=0, last=0;
ostr = dynamic_cast<TObjString*>(tok->At(0)); sstr = tok[0];
sstr = ostr->GetString();
if (sstr.IsDigit()) { if (sstr.IsDigit()) {
first = sstr.Atoi(); first = sstr.Atoi();
} else { } else {
@@ -253,8 +251,7 @@ Bool_t musrFT_filter_histo(Int_t &i, Int_t argc, Char_t *argv[], musrFT_startup_
startupParam.histo.clear(); startupParam.histo.clear();
return false; return false;
} }
ostr = dynamic_cast<TObjString*>(tok->At(1)); sstr = tok[1];
sstr = ostr->GetString();
if (sstr.IsDigit()) { if (sstr.IsDigit()) {
last = sstr.Atoi(); last = sstr.Atoi();
} else { } 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++) { for (Int_t k=first; k<=last; k++) {
startupParam.histo.push_back(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 // handle return status of musrWiz
connect(proc, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), 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 // make sure that the system environment variables are properly set
QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
@@ -2761,7 +2761,7 @@ void PTextEdit::musrT0()
proc->setWorkingDirectory(workDir); proc->setWorkingDirectory(workDir);
connect(proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), 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); proc->start(cmd, arg);
if (!proc->waitForStarted()) { if (!proc->waitForStarted()) {
@@ -2921,7 +2921,7 @@ void PTextEdit::musrSetSteps()
// handle return status of musrStep // handle return status of musrStep
connect(proc, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), 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 // make sure that the system environment variables are properly set
QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
+3 -3
View File
@@ -2160,7 +2160,7 @@ void PTextEdit::musrWiz()
// handle return status of musrWiz // handle return status of musrWiz
connect(proc, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), 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 // make sure that the system environment variables are properly set
QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
@@ -2868,7 +2868,7 @@ void PTextEdit::musrT0()
proc->setWorkingDirectory(workDir); proc->setWorkingDirectory(workDir);
connect(proc, QOverload<int, QProcess::ExitStatus>::of(&QProcess::finished), 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); proc->start(cmd, arg);
if (!proc->waitForStarted()) { if (!proc->waitForStarted()) {
@@ -3022,7 +3022,7 @@ void PTextEdit::musrSetSteps()
// handle return status of musrStep // handle return status of musrStep
connect(proc, static_cast<void(QProcess::*)(int, QProcess::ExitStatus)>(&QProcess::finished), 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 // make sure that the system environment variables are properly set
QProcessEnvironment env = QProcessEnvironment::systemEnvironment(); 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;
}