1#include "TRestStringHelper.h"
4#include <TApplication.h>
8#if ROOT_VERSION_CODE < ROOT_VERSION(6, 0, 0)
11#include <v5/TFormula.h>
33 vector<string> funcs{
"sqrt",
"log",
"exp",
"gaus",
"cos",
"sin",
"tan",
"atan",
"acos",
"asin"};
34 for (
const auto& item : funcs) {
35 if (in.find(item) != string::npos) {
42 size_t pos = in.substr(1, in.length() - 2).find_first_of(
"+-*/e^%");
43 if (pos != string::npos) {
49 size_t pos = in.find_first_of(
"%");
50 if (pos == in.size() - 1) {
57 for (
const auto& item : funcs) {
58 temp =
Replace(temp, item,
"0", 0);
60 if (temp.find_first_not_of(
"-0123456789e+*/.,)( ^%") == string::npos) {
61 if (temp.find(
"/") == 0 || temp.find(
"./") == 0 || temp.find(
"../") == 0)
79 if (precision == 0)
return in;
82 size_t newPrecision = precision;
83 if (in.find(
"e") != string::npos) {
84 rootStr = in.substr(in.find(
"e"), -1);
85 newPrecision = std::min((
int)newPrecision, (
int)in.find(
"e") - (
int)in.find(
".") - 1);
87 std::string rr = in.substr(0, in.find(
".") + newPrecision + 1) + rootStr;
103 string errorMessage) {
104 buffer =
Replace(buffer,
" AND ",
" && ");
105 buffer =
Replace(buffer,
" OR ",
" || ");
107 if (buffer.find(
"'") != string::npos && count(buffer.begin(), buffer.end(),
'\'') % 2 == 0) {
108 size_t pos1 = buffer.find(
"'");
109 size_t pos2 = buffer.find(
"'", pos1 + 1);
110 string expr = buffer.substr(pos1 + 1, pos2 - pos1 - 1);
115 expr =
"'" + expr +
"'";
116 string newbuff =
Replace(buffer, expr, evalExpr);
122 int pos = buffer.find_last_of(
"1234567890().");
124 string unit = buffer.substr(pos + 1, -1);
125 string temp = buffer.substr(0, pos + 1);
130 vector<string> Expressions =
Split(temp,
",");
132 if (Expressions.size() > 1 && Expressions[0][0] ==
'(' &&
133 Expressions[Expressions.size() - 1][Expressions[Expressions.size() - 1].size() - 1] ==
')') {
134 Expressions[0].erase(0, 1);
135 Expressions[Expressions.size() - 1].erase(Expressions[Expressions.size() - 1].size() - 1, 1);
139 for (
size_t i = 0; i < Expressions.size(); i++) {
141 result += Expressions[i] +
",";
145 if (evaluated ==
"RESTerror") {
146 result += Expressions[i] +
",";
147 RESTError <<
"ReplaceMathematicalExpressions. Error on RML syntax!" << RESTendl;
148 if (errorMessage !=
"") RESTError << errorMessage << RESTendl;
150 result += evaluated +
",";
152 if (Expressions.size() > 0) result.erase(result.size() - 1, 1);
155 result =
"(" + result +
")";
159 return result + unit;
174#if ROOT_VERSION_CODE < ROOT_VERSION(6, 0, 0)
175 TFormula formula(
"tmp", exp.c_str());
177 ROOT::v5::TFormula formula(
"tmp", exp.c_str());
181 Double_t number = formula.EvalPar(0);
182 if (number > 0 && number < 1.e-300) {
183 RESTWarning <<
"REST_StringHelper::EvaluateExpresssion. Expression not recognized --> " << exp
185 return (
string)
"RESTerror";
189 string out = sss.str();
199 cout << hint << endl;
201 if (gApplication !=
nullptr && !gApplication->IsRunning()) {
202 auto timer = std::make_unique<TTimer>(
"gSystem->ProcessEvents();", 50, kFALSE);
207 result = REST_Display_CompatibilityMode ? 1 : getchar();
212 result = REST_Display_CompatibilityMode ? 1 : getchar();
222 std::string inTrim =
Trim(in);
223 return (inTrim.find_first_not_of(
"-+0123456789.eE") == string::npos && !inTrim.empty());
237 bool removeWhiteSpaces,
int startPos) {
238 vector<string> result;
243 pos = in.find(separator.c_str(), pos + 1);
244 string sub = in.substr(front, pos - front);
246 if (allowBlankString || sub !=
"") {
247 result.push_back(sub);
249 front = pos + separator.size();
250 if (pos == -1)
break;
262 vector<double> result;
264 for (
unsigned int i = 0; i < vec_str.size(); i++) {
266 result.push_back(temp);
281 vector<double> result;
282 size_t startPos = in.find(headChar);
283 size_t endPos = in.find(tailChar);
284 if (startPos == string::npos || endPos == string::npos) {
287 vector<string> values =
Split(in.substr(startPos + 1, endPos - startPos - 1),
",");
289 for (
unsigned int i = 0; i < values.size(); i++) {
291 result.push_back(temp);
303 while ((pos = out.find(
" ", pos)) != string::npos) {
310ULong64_t REST_StringHelper::ToHash(
string str) {
311 ULong64_t prime = 0x100000001B3ull;
312 ULong64_t basis = 0xCBF29CE484222325ull;
313 ULong64_t ret{basis};
315 for (
unsigned int i = 0; i < str.size(); i++) {
329 size_t nPos = in.find(substring, 0);
330 while (nPos != string::npos) {
332 nPos = in.find(substring, nPos + 1);
343 size_t found_pos = in.find(strToFind, pos);
344 if (nth == 0 || string::npos == found_pos)
return found_pos;
367 if (str.size() > 256 || matcher.size() > 256) {
368 RESTError <<
"REST_StringHelper::MatchString(): string size too large" << RESTendl;
372 vector<vector<bool>> dp(256, vector<bool>(256));
374 int n1 = matcher.size();
377 for (
int i = 0; i < n1; i++) {
378 if (matcher[i] !=
'*') {
381 if (i == n1 - 1 && matcher[i] ==
'*') {
385 for (i = 1; matcher.at(i - 1) ==
'*'; i++) {
388 for (i = 1; i <= n1; i++) {
389 for (j = 1; j <= n2; j++) {
390 if (matcher.at(i - 1) ==
'*' && (dp[i - 1][j - 1] || dp[i][j - 1] || dp[i - 1][j])) {
392 }
else if (matcher.at(i - 1) ==
'?' && dp[i - 1][j - 1]) {
394 }
else if (matcher.at(i - 1) == str.at(j - 1) && dp[i - 1][j - 1]) {
429 int n = source.length();
430 int m = target.length();
431 if (m == 0)
return n;
432 if (n == 0)
return m;
434 typedef vector<vector<int>> Tmatrix;
435 Tmatrix matrix(n + 1);
436 for (
int i = 0; i <= n; i++) matrix[i].resize(m + 1);
440 for (
int i = 1; i <= n; i++) matrix[i][0] = i;
441 for (
int i = 1; i <= m; i++) matrix[0][i] = i;
444 for (
int i = 1; i <= n; i++) {
445 const char si = source[i - 1];
447 for (
int j = 1; j <= m; j++) {
448 const char dj = target[j - 1];
457 const int above = matrix[i - 1][j] + 1;
458 const int left = matrix[i][j - 1] + 1;
459 const int diag = matrix[i - 1][j - 1] + cost;
460 matrix[i][j] = min(above, min(left, diag));
473 size_t pos = fromPosition;
475 while ((pos = out.find(thisString, pos)) != string::npos) {
476 out.replace(pos, thisString.length(), byThisString);
477 pos = pos + byThisString.length();
480 if (N > 0 && cont == N)
return out;
486string REST_StringHelper::EscapeSpecialLetters(
string in) {
487 string result =
Replace(in,
"(",
"\\(", 0);
488 result =
Replace(result,
")",
"\\)", 0);
489 result =
Replace(result,
"$",
"\\$", 0);
490 result =
Replace(result,
"#",
"\\#", 0);
491 result =
Replace(result,
"{",
"\\{", 0);
492 result =
Replace(result,
"}",
"\\}", 0);
493 result =
Replace(result,
"<",
"\\<", 0);
494 result =
Replace(result,
">",
"\\>", 0);
509 tm* tm_ = localtime(&time);
510 int year, month, day, hour, minute, second;
511 year = tm_->tm_year + 1900;
512 month = tm_->tm_mon + 1;
515 minute = tm_->tm_min;
516 second = tm_->tm_sec;
526 yearStr +
"/" + monthStr +
"/" + dayStr +
" " + hourStr +
":" + minuteStr +
":" + secondStr;
551 if (time.find(
":") != string::npos) {
552 if (time.find(
"/") != string::npos)
553 sscanf(time.c_str(),
"%d/%d/%d %d:%d:%d", &(tm1.tm_year), &(tm1.tm_mon), &(tm1.tm_mday),
554 &(tm1.tm_hour), &(tm1.tm_min), &(tm1.tm_sec));
556 sscanf(time.c_str(),
"%d-%d-%d %d:%d:%d", &(tm1.tm_year), &(tm1.tm_mon), &(tm1.tm_mday),
557 &(tm1.tm_hour), &(tm1.tm_min), &(tm1.tm_sec));
559 if (time.find(
"/") != string::npos)
560 sscanf(time.c_str(),
"%d/%d/%d", &(tm1.tm_year), &(tm1.tm_mon), &(tm1.tm_mday));
562 sscanf(time.c_str(),
"%d-%d-%d", &(tm1.tm_year), &(tm1.tm_mon), &(tm1.tm_mday));
568 time1 = mktime(&tm1);
575 if (
ToUpper(in) ==
"ESSENTIAL" ||
ToUpper(in) ==
"WARNING" || in ==
"1")
611 if (in.find(
"0x") != string::npos)
return (Int_t)stoul(in,
nullptr, 16);
626Bool_t REST_StringHelper::StringToBool(
string booleanString) {
627 const auto booleanStringUpper =
ToUpper(booleanString);
628 return booleanStringUpper ==
"TRUE" || booleanStringUpper ==
"ON" ||
629 booleanStringUpper == to_string(
true);
632Long64_t REST_StringHelper::StringToLong(
string in) {
633 if (in.find_first_of(
"eE") != string::npos) {
650 size_t startVector = in.find_first_of(
"(");
651 if (startVector == string::npos)
return a;
653 size_t endVector = in.find_first_of(
")");
654 if (endVector == string::npos)
return a;
656 size_t n = count(in.begin(), in.end(),
',');
657 if (n != 2)
return a;
659 size_t firstComma = in.find_first_of(
",");
660 size_t secondComma = in.find(
",", firstComma + 1);
662 if (firstComma >= endVector || firstComma <= startVector)
return a;
663 if (secondComma >= endVector || secondComma <= startVector)
return a;
665 string X = in.substr(startVector + 1, firstComma - startVector - 1);
666 string Y = in.substr(firstComma + 1, secondComma - firstComma - 1);
667 string Z = in.substr(secondComma + 1, endVector - secondComma - 1);
680 size_t startVector = in.find_first_of(
"(");
681 if (startVector == string::npos)
return a;
683 size_t endVector = in.find_first_of(
")");
684 if (endVector == string::npos)
return a;
686 size_t n = count(in.begin(), in.end(),
',');
687 if (n != 1)
return a;
689 size_t firstComma = in.find_first_of(
",");
691 if (firstComma >= endVector || firstComma <= startVector)
return a;
693 string X = in.substr(startVector + 1, firstComma - startVector - 1);
694 string Y = in.substr(firstComma + 1, endVector - firstComma - 1);
705 transform(s.begin(), s.end(), s.begin(), (int (*)(
int))toupper);
713 if (s.length() == 0)
return s;
722 transform(s.begin(), s.end(), s.begin(), (int (*)(
int))tolower);
731 s.erase(s.find_last_not_of(t) + 1);
740 s.erase(0, s.find_first_not_of(t));
779 if (name[0] ==
'f' && name.size() > 1 && (name[1] >= 65 && name[1] <= 90)) {
780 return string(1, tolower(name[1])) + name.substr(2, -1);
797 if (islower(name[0])) {
798 return "f" + string(1, toupper(name[0])) + name.substr(1, -1);
839 size_t n = count(func.begin(), func.end(),
'[');
842 vector<int> optPos(n);
843 vector<string> options(n);
844 for (
unsigned int i = 0; i < n; i++) {
845 optPos[i] = func.find(
"[", a);
847 func.substr(func.find(
"[", a) + 1, func.find(
"]", func.find(
"[", a)) - func.find(
"[", a) - 1);
848 a = func.find(
"[", a) + 1;
851 for (
unsigned int i = 0; i < n; i++) {
852 tf1.replace(optPos[n - 1 - i] + 1, (func.find(
"]", optPos[n - 1 - i]) - optPos[n - 1 - i] - 1),
853 string(1, func[optPos[n - 1 - i] + 1]));
857 const char* tf1c = tf1.c_str();
858 TF1* f =
new TF1(
"f", tf1c, init, end);
861 for (
unsigned int i = 0; i < n; i++) {
862 if (options[i].find(
"=") != string::npos) {
863 string op = options[i].substr(options[i].find_last_of(
"=") + 1,
864 options[i].find(
"(") - options[i].find_last_of(
"=") - 1);
866 f->SetParameter(i, stod(op));
868 cout <<
"Initial condition for parameter " << i <<
" is not a number: " << op << endl;
871 cout <<
"No initial condition given for parameter " << i <<
"!" << endl;
876 for (
unsigned int i = 0; i < n; i++) {
877 if (count(options[i].begin(), options[i].end(),
'=') == 2) {
878 string op = options[i].substr(options[i].find_last_of(
"=") + 1,
879 options[i].find(
"(") - options[i].find_last_of(
"=") - 1);
881 f->FixParameter(i, stod(op));
888 for (
unsigned int i = 0; i < n; i++) {
889 if (options[i].find(
"(") != string::npos) {
891 options[i].substr(options[i].find(
"(") + 1, options[i].find(
")") - options[i].find(
"(") - 1);
892 f->SetParLimits(i, stod(op.substr(0, op.find(
","))),
893 stod(op.substr(op.find(
",") + 1, op.size() - 1 - op.find(
","))));
REST_Verbose_Level
Enumerate of verbose level, containing five levels.
@ REST_Essential
+show some essential information, as well as warnings
@ REST_Extreme
show everything
@ REST_Info
+show most of the information for each steps
@ REST_Debug
+show the defined debug messages
@ REST_Silent
show minimum information of the software, as well as error messages
Int_t GetChar(std::string hint="Press a KEY to continue ...")
Helps to pause the program, printing a message before pausing.
std::string IntegerToString(Int_t n, std::string format="%d")
Gets a string from an integer.
std::string FirstToUpper(std::string s)
Convert the first character of a string to upper case.
time_t StringToTimeStamp(std::string time)
A method to convert a date/time formatted string to a timestamp.
Float_t StringToFloat(std::string in)
Gets a float from a string.
std::vector< std::string > Split(std::string in, std::string separator, bool allowBlankString=false, bool removeWhiteSpaces=false, int startPos=-1)
Split the input string according to the given separator. Returning a vector of fragments.
Bool_t MatchString(std::string str, std::string matcher)
This method matches a string with certain matcher. Returns true if matched. Supports wildcard charact...
std::string RightTrim(std::string s, const char *t=" \t\n\r\f\v")
Removes all white spaces found at the end of the string (https://stackoverflow.com/questions/216823/w...
Double_t StringToDouble(std::string in)
Gets a double from a string.
TF1 * CreateTF1FromString(std::string func, double init, double end)
Reads a function with parameter options from string and returns it as TF1*.
std::string ToUpper(std::string in)
Convert string to its upper case. Alternative of TString::ToUpper.
Int_t StringToInteger(std::string in)
Gets an integer from a string.
Int_t isAExpression(const std::string &in)
Returns 1 only if valid mathematical expression keywords (or numbers) are found in the string in....
std::string TrimAndUpper(std::string s)
It trims and uppers the string.
TVector2 StringTo2DVector(std::string in)
Gets a 2D-vector from a string.
std::string LeftTrim(std::string s, const char *t=" \t\n\r\f\v")
Removes all white spaces found at the beginning of the string (https://stackoverflow....
std::string EvaluateExpression(std::string exp)
Evaluates a complex numerical expression and returns the resulting value using TFormula.
std::string TrimAndLower(std::string s)
It trims and lowers the string.
Int_t Count(std::string s, std::string sbstring)
Counts the number of occurences of substring inside the input string in.
Int_t DiffString(const std::string &source, const std::string &target)
Returns the number of different characters between two strings.
std::string Trim(std::string s, const char *t=" \t\n\r\f\v")
Removes all white spaces found at the beginning and the end of the string (https://stackoverflow....
std::string ParameterNameToDataMemberName(std::string name)
Convert parameter name to datamember name, following REST parameter naming convention.
std::string ToLower(std::string in)
Convert string to its lower case. Alternative of TString::ToLower.
std::string DataMemberNameToParameterName(std::string name)
Convert data member name to parameter name, following REST parameter naming convention.
Int_t isANumber(std::string in)
Returns 1 only if a valid number is found in the string in. If not it returns 0.
TVector3 StringTo3DVector(std::string in)
Gets a 3D-vector from a string. Format should be : (X,Y,Z).
Int_t FindNthStringPosition(const std::string &in, size_t pos, const std::string &strToFind, size_t nth)
Returns the position of the nth occurence of the string strToFind inside the string in.
std::string RemoveWhiteSpaces(std::string in)
Returns the input string removing all white spaces.
std::string CropWithPrecision(std::string in, Int_t precision)
It crops a floating number given inside the string in with the given precision. I....
std::vector< double > StringToElements(std::string in, std::string separator)
Convert the input string into a vector of double elements.
std::string ToDateTimeString(time_t time)
Format time_t into string.
std::string DoubleToString(Double_t d, std::string format="%4.2lf")
Gets a string from a double.
std::string Replace(std::string in, std::string thisString, std::string byThisString, size_t fromPosition=0, Int_t N=0)
Replace every occurences of thisSring by byThisString inside string in.
std::string ReplaceMathematicalExpressions(std::string buffer, Int_t precision=0, std::string errorMessage="")
Evaluates and replaces valid mathematical expressions found in the input string buffer.