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;
264 vector<double> result;
266 for (
unsigned int i = 0; i < vec_str.size(); i++) {
268 result.push_back(temp);
283 vector<double> result;
284 size_t startPos = in.find(headChar);
285 size_t endPos = in.find(tailChar);
286 if (startPos == string::npos || endPos == string::npos) {
289 vector<string> values =
Split(in.substr(startPos + 1, endPos - startPos - 1),
",");
291 for (
unsigned int i = 0; i < values.size(); i++) {
293 result.push_back(temp);
304 size_t pos = out.find_first_of(
"+-*/e^%");
305 while ((pos = out.find_first_of(
"({[]})")) != string::npos) {
318 while ((pos = out.find(
" ", pos)) != string::npos) {
325ULong64_t REST_StringHelper::ToHash(
string str) {
326 ULong64_t prime = 0x100000001B3ull;
327 ULong64_t basis = 0xCBF29CE484222325ull;
328 ULong64_t ret{basis};
330 for (
unsigned int i = 0; i < str.size(); i++) {
344 size_t nPos = in.find(substring, 0);
345 while (nPos != string::npos) {
347 nPos = in.find(substring, nPos + 1);
358 size_t found_pos = in.find(strToFind, pos);
359 if (nth == 0 || string::npos == found_pos)
return found_pos;
382 if (str.size() > 256 || matcher.size() > 256) {
383 RESTError <<
"REST_StringHelper::MatchString(): string size too large" << RESTendl;
387 vector<vector<bool>> dp(256, vector<bool>(256));
389 int n1 = matcher.size();
392 for (
int i = 0; i < n1; i++) {
393 if (matcher[i] !=
'*') {
396 if (i == n1 - 1 && matcher[i] ==
'*') {
400 for (i = 1; matcher.at(i - 1) ==
'*'; i++) {
403 for (i = 1; i <= n1; i++) {
404 for (j = 1; j <= n2; j++) {
405 if (matcher.at(i - 1) ==
'*' && (dp[i - 1][j - 1] || dp[i][j - 1] || dp[i - 1][j])) {
407 }
else if (matcher.at(i - 1) ==
'?' && dp[i - 1][j - 1]) {
409 }
else if (matcher.at(i - 1) == str.at(j - 1) && dp[i - 1][j - 1]) {
444 int n = source.length();
445 int m = target.length();
446 if (m == 0)
return n;
447 if (n == 0)
return m;
449 typedef vector<vector<int>> Tmatrix;
450 Tmatrix matrix(n + 1);
451 for (
int i = 0; i <= n; i++) matrix[i].resize(m + 1);
455 for (
int i = 1; i <= n; i++) matrix[i][0] = i;
456 for (
int i = 1; i <= m; i++) matrix[0][i] = i;
459 for (
int i = 1; i <= n; i++) {
460 const char si = source[i - 1];
462 for (
int j = 1; j <= m; j++) {
463 const char dj = target[j - 1];
472 const int above = matrix[i - 1][j] + 1;
473 const int left = matrix[i][j - 1] + 1;
474 const int diag = matrix[i - 1][j - 1] + cost;
475 matrix[i][j] = min(above, min(left, diag));
488 size_t pos = fromPosition;
490 while ((pos = out.find(thisString, pos)) != string::npos) {
491 out.replace(pos, thisString.length(), byThisString);
492 pos = pos + byThisString.length();
495 if (N > 0 && cont == N)
return out;
501string REST_StringHelper::EscapeSpecialLetters(
string in) {
502 string result =
Replace(in,
"(",
"\\(", 0);
503 result =
Replace(result,
")",
"\\)", 0);
504 result =
Replace(result,
"$",
"\\$", 0);
505 result =
Replace(result,
"#",
"\\#", 0);
506 result =
Replace(result,
"{",
"\\{", 0);
507 result =
Replace(result,
"}",
"\\}", 0);
508 result =
Replace(result,
"<",
"\\<", 0);
509 result =
Replace(result,
">",
"\\>", 0);
524 tm* tm_ = localtime(&time);
525 int year, month, day, hour, minute, second;
526 year = tm_->tm_year + 1900;
527 month = tm_->tm_mon + 1;
530 minute = tm_->tm_min;
531 second = tm_->tm_sec;
541 yearStr +
"/" + monthStr +
"/" + dayStr +
" " + hourStr +
":" + minuteStr +
":" + secondStr;
566 if (time.find(
":") != string::npos) {
567 if (time.find(
"/") != string::npos)
568 sscanf(time.c_str(),
"%d/%d/%d %d:%d:%d", &(tm1.tm_year), &(tm1.tm_mon), &(tm1.tm_mday),
569 &(tm1.tm_hour), &(tm1.tm_min), &(tm1.tm_sec));
571 sscanf(time.c_str(),
"%d-%d-%d %d:%d:%d", &(tm1.tm_year), &(tm1.tm_mon), &(tm1.tm_mday),
572 &(tm1.tm_hour), &(tm1.tm_min), &(tm1.tm_sec));
574 if (time.find(
"/") != string::npos)
575 sscanf(time.c_str(),
"%d/%d/%d", &(tm1.tm_year), &(tm1.tm_mon), &(tm1.tm_mday));
577 sscanf(time.c_str(),
"%d-%d-%d", &(tm1.tm_year), &(tm1.tm_mon), &(tm1.tm_mday));
583 time1 = mktime(&tm1);
590 if (
ToUpper(in) ==
"ESSENTIAL" ||
ToUpper(in) ==
"WARNING" || in ==
"1")
626 if (in.find(
"0x") != string::npos)
return (Int_t)stoul(in,
nullptr, 16);
647 std::vector<int> binaryNumber;
650 binaryNumber.insert(binaryNumber.begin(), dimension, 0);
651 if (binaryNumber.empty()) binaryNumber.push_back(0);
656 int digit = number % 2;
657 binaryNumber.insert(binaryNumber.begin(), digit);
661 if (dimension > binaryNumber.size())
662 binaryNumber.insert(binaryNumber.begin(), dimension - binaryNumber.size(), 0);
672Bool_t REST_StringHelper::StringToBool(
string booleanString) {
673 const auto booleanStringUpper =
ToUpper(booleanString);
674 return booleanStringUpper ==
"TRUE" || booleanStringUpper ==
"ON" ||
675 booleanStringUpper == to_string(
true);
678Long64_t REST_StringHelper::StringToLong(
string in) {
679 if (in.find_first_of(
"eE") != string::npos) {
696 size_t startVector = in.find_first_of(
"(");
697 if (startVector == string::npos)
return a;
699 size_t endVector = in.find_first_of(
")");
700 if (endVector == string::npos)
return a;
702 size_t n = count(in.begin(), in.end(),
',');
703 if (n != 2)
return a;
705 size_t firstComma = in.find_first_of(
",");
706 size_t secondComma = in.find(
",", firstComma + 1);
708 if (firstComma >= endVector || firstComma <= startVector)
return a;
709 if (secondComma >= endVector || secondComma <= startVector)
return a;
711 string X = in.substr(startVector + 1, firstComma - startVector - 1);
712 string Y = in.substr(firstComma + 1, secondComma - firstComma - 1);
713 string Z = in.substr(secondComma + 1, endVector - secondComma - 1);
726 size_t startVector = in.find_first_of(
"(");
727 if (startVector == string::npos)
return a;
729 size_t endVector = in.find_first_of(
")");
730 if (endVector == string::npos)
return a;
732 size_t n = count(in.begin(), in.end(),
',');
733 if (n != 1)
return a;
735 size_t firstComma = in.find_first_of(
",");
737 if (firstComma >= endVector || firstComma <= startVector)
return a;
739 string X = in.substr(startVector + 1, firstComma - startVector - 1);
740 string Y = in.substr(firstComma + 1, endVector - firstComma - 1);
751 transform(s.begin(), s.end(), s.begin(), (int (*)(
int))toupper);
759 if (s.length() == 0)
return s;
768 transform(s.begin(), s.end(), s.begin(), (int (*)(
int))tolower);
777 s.erase(s.find_last_not_of(t) + 1);
786 s.erase(0, s.find_first_not_of(t));
825 if (name[0] ==
'f' && name.size() > 1 && (name[1] >= 65 && name[1] <= 90)) {
826 return string(1, tolower(name[1])) + name.substr(2, -1);
843 if (islower(name[0])) {
844 return "f" + string(1, toupper(name[0])) + name.substr(1, -1);
885 size_t n = count(func.begin(), func.end(),
'[');
888 vector<int> optPos(n);
889 vector<string> options(n);
890 for (
unsigned int i = 0; i < n; i++) {
891 optPos[i] = func.find(
"[", a);
893 func.substr(func.find(
"[", a) + 1, func.find(
"]", func.find(
"[", a)) - func.find(
"[", a) - 1);
894 a = func.find(
"[", a) + 1;
897 for (
unsigned int i = 0; i < n; i++) {
898 tf1.replace(optPos[n - 1 - i] + 1, (func.find(
"]", optPos[n - 1 - i]) - optPos[n - 1 - i] - 1),
899 string(1, func[optPos[n - 1 - i] + 1]));
903 const char* tf1c = tf1.c_str();
904 TF1* f =
new TF1(
"f", tf1c, init, end);
907 for (
unsigned int i = 0; i < n; i++) {
908 if (options[i].find(
"=") != string::npos) {
909 string op = options[i].substr(options[i].find_last_of(
"=") + 1,
910 options[i].find(
"(") - options[i].find_last_of(
"=") - 1);
912 f->SetParameter(i, stod(op));
914 cout <<
"Initial condition for parameter " << i <<
" is not a number: " << op << endl;
917 cout <<
"No initial condition given for parameter " << i <<
"!" << endl;
922 for (
unsigned int i = 0; i < n; i++) {
923 if (count(options[i].begin(), options[i].end(),
'=') == 2) {
924 string op = options[i].substr(options[i].find_last_of(
"=") + 1,
925 options[i].find(
"(") - options[i].find_last_of(
"=") - 1);
927 f->FixParameter(i, stod(op));
934 for (
unsigned int i = 0; i < n; i++) {
935 if (options[i].find(
"(") != string::npos) {
937 options[i].substr(options[i].find(
"(") + 1, options[i].find(
")") - options[i].find(
"(") - 1);
938 f->SetParLimits(i, stod(op.substr(0, op.find(
","))),
939 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 DoubleToString(Double_t d, std::string format="%8.6e")
Gets a string from a double.
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::vector< int > IntegerToBinary(int number, size_t dimension=0)
It returns an integer vector with the binary digits decomposed.
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 RemoveDelimiters(std::string in)
Returns the input string removing any delimiters ({[]})
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 Replace(std::string in, std::string thisString, std::string byThisString, size_t fromPosition=0, Int_t N=0)
Replace any 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.