44 #include "TRestTools.h"
55 #include <curl/curl.h>
75 #include "TRestStringHelper.h"
76 #include "TRestStringOutput.h"
96 const set<string> libraryExtension{
".so",
".dylib",
".dll"};
97 const set<string> excludedLibraries{
100 vector<string> ldPaths;
102 ldPaths.push_back(REST_PATH +
"/bin/");
104 ldPaths.push_back(REST_PATH +
"/bin/");
106 ldPaths.push_back(REST_PATH +
"/lib/");
108 ldPaths.push_back(REST_USER_PATH +
"/userlib/");
110 vector<string> fileList;
111 for (
const std::filesystem::path path : ldPaths) {
116 for (
const auto& it : std::filesystem::directory_iterator(path)) {
117 if (!it.is_regular_file()) {
120 if (libraryExtension.count(it.path().extension().string()) == 0) {
124 const TString pathRootString = it.path().string();
126 if (!libName.Contains(
"Rest", TString::kExact)) {
131 bool excluded =
false;
132 for (
const TString excludedLibrary : excludedLibraries) {
133 if (libName.Contains(excludedLibrary, TString::kExact)) {
142 fileList.emplace_back(it.path().string());
147 if (!silent) cout <<
"= Loading libraries ..." << endl;
148 for (
const auto& library : fileList) {
149 if (!silent) cout <<
" - " << library << endl;
150 gSystem->Load(library.c_str());
152 if (!silent) cout << endl;
162 template <
typename T>
164 Int_t size = data.size();
165 if (end > 0 && size > end) size = end;
166 for (
int n = start; n < size; n++) {
167 for (
unsigned int m = 0; m < data[n].size(); m++) cout << data[n][m] <<
"\t";
173 template int TRestTools::PrintTable<Int_t>(std::vector<std::vector<Int_t>> data, Int_t start, Int_t end);
174 template int TRestTools::PrintTable<Float_t>(std::vector<std::vector<Float_t>> data, Int_t start, Int_t end);
175 template int TRestTools::PrintTable<Double_t>(std::vector<std::vector<Double_t>> data, Int_t start,
177 template int TRestTools::PrintTable<std::string>(std::vector<std::vector<std::string>> data, Int_t start,
184 template <
typename T>
186 ofstream file(fname);
187 if (!file.is_open()) {
188 RESTError <<
"Unable to open file for writing : " << fname << RESTendl;
192 for (
unsigned int n = 0; n < data.size(); n++)
193 for (
unsigned int m = 0; m < data[n].size(); m++) {
195 if (m + 1 < data[n].size()) file <<
"\t";
196 if (m + 1 == data[n].size()) file <<
"\n";
203 template int TRestTools::ExportASCIITable<Int_t>(std::string fname, std::vector<std::vector<Int_t>>& data);
204 template int TRestTools::ExportASCIITable<Float_t>(std::string fname,
205 std::vector<std::vector<Float_t>>& data);
206 template int TRestTools::ExportASCIITable<Double_t>(std::string fname,
207 std::vector<std::vector<Double_t>>& data);
213 template <
typename T>
215 ofstream file(fname, ios::out | ios::binary);
216 if (!file.is_open()) {
217 RESTError <<
"Unable to open file for writing : " << fname << RESTendl;
221 for (
unsigned int n = 0; n < data.size(); n++)
222 for (
unsigned int m = 0; m < data[n].size(); m++) {
223 file.write((
char*)&data[n][m],
sizeof(T));
230 template int TRestTools::ExportBinaryTable<Int_t>(std::string fname, std::vector<std::vector<Int_t>>& data);
231 template int TRestTools::ExportBinaryTable<Float_t>(std::string fname,
232 std::vector<std::vector<Float_t>>& data);
233 template int TRestTools::ExportBinaryTable<Double_t>(std::string fname,
234 std::vector<std::vector<Double_t>>& data);
252 template <
typename T>
255 RESTError <<
"TRestTools::ReadBinaryTable. Error." << RESTendl;
256 RESTError <<
"Cannot open file : " << fName << RESTendl;
261 columns = GetBinaryFileColumns(fName);
263 RESTError <<
"TRestTools::ReadBinaryTable. Format extension error." << RESTendl;
264 RESTError <<
"Please, specify the number of columns at the method 3rd argument" << RESTendl;
269 std::ifstream fin(fName, std::ios::binary);
270 fin.seekg(0, std::ios::end);
271 const size_t num_elements = fin.tellg() /
sizeof(T);
272 fin.seekg(0, std::ios::beg);
274 if (num_elements % columns != 0) {
275 cout <<
"TRestTools::ReadBinaryTable. Error." << endl;
276 cout <<
"Number of elements : " << num_elements
277 <<
" is not compatible with the number of columns : " << columns << endl;
282 std::vector<T> dataArray(columns);
283 fin.read(
reinterpret_cast<char*
>(&dataArray[0]), columns *
sizeof(T));
285 data.push_back(dataArray);
286 fin.read(
reinterpret_cast<char*
>(&dataArray[0]), columns *
sizeof(T));
291 template int TRestTools::ReadBinaryTable<Int_t>(
string fName, std::vector<std::vector<Int_t>>& data,
293 template int TRestTools::ReadBinaryTable<Float_t>(
string fName, std::vector<std::vector<Float_t>>& data,
295 template int TRestTools::ReadBinaryTable<Double_t>(
string fName, std::vector<std::vector<Double_t>>& data,
304 if (GetBinaryFileColumns(fname) > 0)
return true;
316 string extension = GetFileNameExtension(fname);
317 if (extension.find(
"N") != 0) {
321 size_t pos = extension.find(
"i");
322 if (pos != string::npos) {
326 pos = extension.find(
"f");
327 if (pos != string::npos) {
331 pos = extension.find(
"d");
332 if (pos != string::npos) {
336 RESTError <<
"Format " <<
ToUpper(extension) <<
" not recognized" << RESTendl;
344 template <
typename T>
346 if (data.size() == 0)
return;
348 std::vector<std::vector<T>> trans_vec(data[0].size(), std::vector<T>());
350 for (
unsigned int i = 0; i < data.size(); i++)
351 for (
unsigned int j = 0; j < data[i].size(); j++) trans_vec[j].push_back(data[i][j]);
356 template void TRestTools::TransposeTable<Double_t>(std::vector<std::vector<Double_t>>& data);
358 template void TRestTools::TransposeTable<Float_t>(std::vector<std::vector<Float_t>>& data);
360 template void TRestTools::TransposeTable<Int_t>(std::vector<std::vector<Int_t>>& data);
369 template <
typename T>
371 if (data.size() == 0)
return 0;
372 if (column > -1 && data[0].size() <= (
unsigned int)column)
return 0;
374 T maxValue = data[0][0];
376 for (
unsigned int n = 0; n < data.size(); n++)
377 for (
unsigned int c = 0; c < data[n].size(); c++)
378 if (maxValue < data[n][c]) maxValue = data[n][c];
380 maxValue = data[0][column];
381 for (
unsigned int n = 0; n < data.size(); n++)
382 if (maxValue < data[n][column]) maxValue = data[n][column];
388 template Int_t TRestTools::GetMaxValueFromTable<Int_t>(
const std::vector<std::vector<Int_t>>& data,
391 template Float_t TRestTools::GetMaxValueFromTable<Float_t>(
const std::vector<std::vector<Float_t>>& data,
394 template Double_t TRestTools::GetMaxValueFromTable<Double_t>(
const std::vector<std::vector<Double_t>>& data,
404 template <
typename T>
406 if (data.empty())
return 0;
407 if (column != -1 && data[0].size() <= (
unsigned int)column)
return 0;
409 T minValue = data[0][0];
411 for (
unsigned int n = 0; n < data.size(); n++)
412 for (
unsigned int c = 0; c < data[n].size(); c++)
413 if (minValue > data[n][c]) minValue = data[n][c];
415 minValue = data[0][column];
416 for (
unsigned int n = 0; n < data.size(); n++)
417 if (minValue > data[n][column]) minValue = data[n][column];
423 template Int_t TRestTools::GetMinValueFromTable<Int_t>(
const std::vector<std::vector<Int_t>>& data,
426 template Float_t TRestTools::GetMinValueFromTable<Float_t>(
const std::vector<std::vector<Float_t>>& data,
429 template Double_t TRestTools::GetMinValueFromTable<Double_t>(
const std::vector<std::vector<Double_t>>& data,
441 template <
typename T>
443 if (data.size() == 0 || data[0].size() <= (
unsigned int)column)
return 0;
444 T lowestIncrease = abs(data[0][column] - data[1][column]);
445 for (
unsigned int n = 1; n < data.size(); n++) {
446 T value = abs(data[n - 1][column] - data[n][column]);
447 if (lowestIncrease == 0) lowestIncrease = value;
448 if (value > 0 && value < lowestIncrease) lowestIncrease = value;
450 return lowestIncrease;
453 template Int_t TRestTools::GetLowestIncreaseFromTable<Int_t>(std::vector<std::vector<Int_t>> data,
456 template Float_t TRestTools::GetLowestIncreaseFromTable<Float_t>(std::vector<std::vector<Float_t>> data,
459 template Double_t TRestTools::GetLowestIncreaseFromTable<Double_t>(std::vector<std::vector<Double_t>> data,
471 template <
typename T>
473 if (data.size() == 0)
return 0;
475 for (
unsigned int n = 0; n < data.size(); n++) {
476 for (
unsigned int m = 0; m < data[n].size(); m++) sum += data[n][m];
481 template Int_t TRestTools::GetIntegralFromTable<Int_t>(
const std::vector<std::vector<Int_t>>& data);
483 template Float_t TRestTools::GetIntegralFromTable<Float_t>(
const std::vector<std::vector<Float_t>>& data);
485 template Double_t TRestTools::GetIntegralFromTable<Double_t>(
const std::vector<std::vector<Double_t>>& data);
493 template <
typename T>
495 std::vector<T> columnData;
496 if (data.size() == 0 || data[0].size() <= column)
return columnData;
498 for (
unsigned int n = 0; n < data.size(); n++) columnData.push_back(data[n][column]);
503 template std::vector<Int_t> TRestTools::GetColumnFromTable<Int_t>(
const std::vector<std::vector<Int_t>>& data,
504 unsigned int column);
506 template std::vector<Float_t> TRestTools::GetColumnFromTable<Float_t>(
507 const std::vector<std::vector<Float_t>>& data,
unsigned int column);
509 template std::vector<Double_t> TRestTools::GetColumnFromTable<Double_t>(
510 const std::vector<std::vector<Double_t>>& data,
unsigned int column);
512 template std::vector<std::string> TRestTools::GetColumnFromTable<std::string>(
513 const std::vector<std::vector<std::string>>& data,
unsigned int column);
529 std::string separator) {
531 cout <<
"TRestTools::ReadASCIITable. Error" << endl;
532 cout <<
"Cannot open file : " << fName << endl;
538 std::ifstream fin(fName);
541 std::vector<std::vector<string>> values;
543 for (
string line; std::getline(fin, line);) {
549 if (line.find(
"#") == string::npos) {
550 std::istringstream in(line);
553 std::vector<std::string> tokens;
554 while (std::getline(in, token, (
char)separator[0])) {
555 tokens.push_back(token);
557 data.push_back(tokens);
578 std::string separator) {
580 cout <<
"TRestTools::ReadASCIITable. Error" << endl;
581 cout <<
"Cannot open file : " << fName << endl;
587 std::ifstream fin(fName);
590 std::vector<std::vector<string>> values;
592 for (
string line; std::getline(fin, line);) {
598 if (line.find(
"#") == string::npos) {
599 std::istringstream in(line);
602 std::vector<std::string> tokens;
603 while (std::getline(in, token, (
char)separator[0])) {
604 tokens.push_back(token);
606 values.push_back(tokens);
611 for (
unsigned int n = 0; n < values.size(); n++) {
612 std::vector<Double_t> dblTmp;
615 for (
unsigned int m = 0; m < values[n].size(); m++) dblTmp.push_back(
StringToDouble(values[n][m]));
617 data.push_back(dblTmp);
637 std::string separator) {
639 cout <<
"TRestTools::ReadASCIITable. Error" << endl;
640 cout <<
"Cannot open file : " << fName << endl;
646 std::ifstream fin(fName);
649 std::vector<std::vector<string>> values;
651 for (
string line; std::getline(fin, line);) {
657 if (line.find(
"#") == string::npos) {
658 std::istringstream in(line);
661 std::vector<std::string> tokens;
662 while (std::getline(in, token, (
char)separator[0])) {
663 tokens.push_back(token);
665 values.push_back(tokens);
670 for (
unsigned int n = 0; n < values.size(); n++) {
671 std::vector<Float_t> dblTmp;
674 for (
unsigned int m = 0; m < values[n].size(); m++) dblTmp.push_back(
StringToFloat(values[n][m]));
676 data.push_back(dblTmp);
696 return ReadASCIITable(fName, data, skipLines,
",");
713 return ReadASCIITable(fName, data, skipLines,
",");
739 if (!isRootFile(filename))
return false;
741 TFile* f = TFile::Open((TString)filename);
743 TIter nextkey(f->GetListOfKeys());
745 while ((key = (TKey*)nextkey())) {
746 if ((std::string)key->GetClassName() ==
"TRestRun")
return true;
755 if (!isRootFile(filename))
return false;
757 TFile* f = TFile::Open((TString)filename);
759 TIter nextkey(f->GetListOfKeys());
761 while ((key = (TKey*)nextkey())) {
762 if ((std::string)key->GetClassName() ==
"TRestDataSet")
return true;
771 std::regex pattern(
"^https?://(.+)");
772 return std::regex_match(s, pattern);
781 result = _access(path.c_str(), 2);
783 result = access(path.c_str(), 2);
796 if (path[0] ==
'/' || path[0] ==
'~' || path.find(
':') != string::npos) {
814 filesystem::path path(fullname);
815 return {path.parent_path().string(), path.filename().string()};
824 string extension = filesystem::path(fullname).extension().string();
825 if (extension.size() > 1)
return extension.substr(1);
835 return filesystem::path(fullname).stem().string();
846 string to_replace =
"//";
847 size_t start_pos = str.find(to_replace);
848 while (start_pos != string::npos) {
849 str.replace(start_pos, to_replace.length(),
"/");
850 start_pos = str.find(to_replace);
869 filesystem::path path;
870 for (
const auto& directory : filesystem::path(filename)) {
871 if (path.empty() && directory ==
"~") {
873 const auto envVariableHome = getenv(
"HOME");
874 if (envVariableHome ==
nullptr) {
875 cout <<
"TRestTools::ToAbsoluteName - ERROR - "
876 "cannot resolve ~ because 'HOME' env variable does not exist"
880 const auto userHomePath = filesystem::path(envVariableHome);
881 if (userHomePath.empty()) {
882 cout <<
"TRestTools::ToAbsoluteName - ERROR - "
883 "cannot resolve ~ because 'HOME' env variable is not set to a valid value"
887 path /= userHomePath;
892 return filesystem::weakly_canonical(path).string();
905 vector<string> result;
907 std::filesystem::path path(_path);
909 std::filesystem::directory_iterator iter(path);
910 for (
auto& it : iter) {
911 if (it.is_directory()) {
912 result.push_back(it.path().string());
914 if (recursion != 0) {
915 vector<string> subD = GetSubdirectories(it.path().string(), recursion - 1);
916 result.insert(result.begin(), subD.begin(), subD.end());
930 if (fileExists(filename)) {
933 for (
unsigned int i = 0; i < paths.size(); i++) {
934 string path = paths[i];
935 if (path[path.size() - 1] !=
'/') {
939 if (fileExists(path + filename)) {
940 return path + filename;
944 vector<string> pathsExpanded = GetSubdirectories(paths[i], 5);
945 for (
unsigned int j = 0; j < pathsExpanded.size(); j++)
946 if (fileExists(pathsExpanded[j] +
"/" + filename))
return pathsExpanded[j] +
"/" + filename;
958 ifs.open(filename.c_str());
977 std::vector<string> outputFileNames;
979 vector<string> items =
Split(pattern,
"\n");
980 for (
auto item : items) {
981 if (item.find_first_of(
"*?") != string::npos) {
983 item =
Replace(item,
"/",
"\\");
985 item.substr(0, item.find_first_of(
"*?"));
986 auto path_name = SeparatePathAndName(item_trim);
987 string _path = path_name.first;
988 if (!std::filesystem::exists(_path)) {
989 RESTError <<
"TRestTools::GetFilesMatchingPattern(): path " << _path <<
" does not exist!"
991 return outputFileNames;
994 std::filesystem::path path(_path);
995 std::filesystem::recursive_directory_iterator iter(path);
996 for (
auto& it : iter) {
997 if (it.is_regular_file()) {
998 string filename = it.path().string();
1000 outputFileNames.push_back(it.path().string());
1005 auto path_name = SeparatePathAndName(item);
1007 std::string currentDir = filesystem::current_path();
1008 ChangeDirectory(path_name.first);
1009 string a = Execute(
"find -type f -name \'" + path_name.second +
"\'");
1010 ChangeDirectory(currentDir);
1011 auto b =
Split(a,
"\n");
1013 for (
unsigned int i = 0; i < b.size(); i++) {
1014 outputFileNames.push_back(path_name.first +
"/" + b[i]);
1018 string a = Execute(
"find " + item);
1019 auto b =
Split(a,
"\n");
1021 for (
unsigned int i = 0; i < b.size(); i++) {
1022 outputFileNames.push_back(b[i]);
1028 if (fileExists(item)) outputFileNames.push_back(item);
1032 return outputFileNames;
1039 #ifndef REST_Version
1040 #define REST_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
1042 vector<string> ver =
Split(in,
".");
1043 if (ver.size() == 3) {
1045 for (
auto v : ver) {
1046 int n =
StringToInteger(v.substr(0, v.find_first_not_of(
"0123456789")));
1048 verint.push_back(n);
1053 return REST_VERSION(verint[0], verint[1], verint[2]);
1062 std::array<char, 128> buffer;
1065 std::unique_ptr<FILE, decltype(&_pclose)> pipe(_popen((
"powershell.exe " + cmd).c_str(),
"r"), _pclose);
1067 std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(cmd.c_str(),
"r"), pclose);
1071 throw std::runtime_error(
"popen() failed!");
1073 while (fgets(buffer.data(), buffer.size(), pipe.get()) !=
nullptr) {
1074 result += buffer.data();
1077 if (result.size() > 0 && result[result.size() - 1] ==
'\n')
1078 result = result.substr(0, result.size() - 1);
1096 std::istream::sentry se(is,
true);
1097 std::streambuf* sb = is.rdbuf();
1100 int c = sb->sbumpc();
1105 if (sb->sgetc() ==
'\n') sb->sbumpc();
1107 case std::streambuf::traits_type::eof():
1109 if (t.empty()) is.setstate(std::ios::eofbit);
1126 if (pureName.empty()) {
1127 RESTWarning <<
"error! (TRestTools::DownloadRemoteFile): url is not a file!" << RESTendl;
1128 RESTWarning <<
"please specify a concrete file name in this url" << RESTendl;
1129 RESTWarning <<
"url: " << url << RESTendl;
1133 if (url.find(
"local:") == 0) {
1134 return Replace(url,
"local:",
"");
1137 REST_USER_PATH +
"/download/" + (pidPrefix ?
"PID_" + ToString(getpid()) +
"_" :
"") + pureName;
1143 RESTWarning <<
"Retrying download in 5 seconds" << RESTendl;
1144 std::this_thread::sleep_for(std::chrono::seconds(5));
1145 }
else if (attempts < 10) {
1146 RESTSuccess <<
"Download succeeded after " << 10 - attempts <<
" attempts" << RESTendl;
1149 }
while (out == 1024 && attempts > 0);
1166 TUrl url(remoteFile.c_str());
1168 RESTInfo <<
"Downloading remote file : " << remoteFile << RESTendl;
1169 RESTInfo <<
"To local file : " << localFile << RESTendl;
1171 string localFiletmp = localFile +
".restdownload";
1172 if ((
string)url.GetProtocol() ==
"https" || (
string)url.GetProtocol() ==
"http") {
1175 if (!filesystem::create_directories(path)) {
1176 std::cerr <<
"mkdir failed to create directory: " << path << std::endl;
1181 string cmd =
"wget --no-check-certificate " + EscapeSpecialLetters(remoteFile) +
" -O " +
1182 EscapeSpecialLetters(localFiletmp) +
" -q";
1183 RESTDebug << cmd << RESTendl;
1184 int a = system(cmd.c_str());
1187 rename(localFiletmp.c_str(), localFile.c_str());
1190 RESTError <<
"download failed! (" << remoteFile <<
")" << RESTendl;
1192 RESTError <<
"Network connection problem?" << RESTendl;
1196 RESTError <<
"File does NOT exist in remotely?" << RESTendl;
1200 }
else if ((
string)url.GetProtocol() ==
"ssh") {
1201 string cmd =
"scp -P " + ToString(url.GetPort() == 0 ? 22 : url.GetPort()) +
" " + url.GetUser() +
1202 "@" + url.GetHost() +
":" + EscapeSpecialLetters(url.GetFile()) +
" " + localFiletmp;
1203 cout << cmd << endl;
1204 int a = system(cmd.c_str());
1206 rename(localFiletmp.c_str(), localFile.c_str());
1211 RESTWarning <<
"Trying to download: " << remoteFile << RESTendl;
1212 RESTWarning <<
"Unknown protocol!" << RESTendl;
1224 std::string file_content =
"";
1229 string filename = REST_USER_PATH +
"/download/curl.out";
1232 curl_global_init(CURL_GLOBAL_ALL);
1234 FILE* f = fopen(filename.c_str(),
"wt");
1236 std::string request =
"";
1238 for (
auto const& x : keys) {
1239 if (n > 0) request +=
"&";
1240 request += x.first +
"=" + x.second;
1244 curl = curl_easy_init();
1249 curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
1250 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (
void*)f);
1252 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request.c_str());
1255 res = curl_easy_perform(curl);
1257 if (res != CURLE_OK)
1258 RESTError <<
"curl_easy_perform() failed: " << curl_easy_strerror(res) << RESTendl;
1261 curl_easy_cleanup(curl);
1264 curl_global_cleanup();
1266 std::getline(std::ifstream(filename), file_content,
'\0');
1268 RESTError <<
"TRestTools::POSTRequest. REST framework was compiled without CURL support" << RESTendl;
1269 RESTError <<
"Please recompile REST after installing curl development libraries." << RESTendl;
1270 RESTError <<
"Depending on your system this might be: curl-dev, curl-devel or libcurl-openssl-dev. "
1272 RESTError <<
"No file will be downloaded" << RESTendl;
1275 return file_content;
1287 cout <<
"error! local file not exist!" << endl;
1292 TUrl url(remoteFile.c_str());
1293 TUrl method(methodUrl.c_str());
1294 if (method.GetProtocol() != (
string)
"") url.SetProtocol(method.GetProtocol());
1295 if (method.GetPort() != 0) url.SetPort(method.GetPort());
1296 if (method.GetUser() != (
string)
"") url.SetUser(method.GetUser());
1297 if (method.GetPasswd() != (
string)
"") url.SetPasswd(method.GetPasswd());
1299 if ((
string)url.GetProtocol() ==
"https" || (
string)url.GetProtocol() ==
"http") {
1301 }
else if ((
string)url.GetProtocol() ==
"ssh") {
1302 string cmd =
"scp -P " + ToString(url.GetPort() == 0 ? 22 : url.GetPort()) +
" " +
1303 EscapeSpecialLetters(localFile) +
" " + url.GetUser() +
"@" + url.GetHost() +
":" +
1304 EscapeSpecialLetters(url.GetFile());
1305 cout << cmd << endl;
1306 int a = system(cmd.c_str());
1309 RESTError << __PRETTY_FUNCTION__ << RESTendl;
1310 RESTError <<
"problem copying gases definitions to remote server" << RESTendl;
1311 RESTError <<
"Please report this problem at "
1312 "http://gifna.unizar.es/rest-forum/"
1322 void TRestTools::ChangeDirectory(
const string& toDirectory) { filesystem::current_path(toDirectory); }
1334 for (
int i = 2; i * i <= n; i += 1 + (i > 2)) {
1335 while ((n % i) == 0) {
1340 if (n != 1) r.push_back(n);
1342 while (r.size() > 2) {
1345 auto min1 = std::min_element(r.begin(), r.end());
1349 auto it = std::find(r.begin(), r.end(), low1);
1350 if (it != r.end()) {
1351 std::iter_swap(it, r.end() - 1);
1352 r.erase(r.end() - 1);
1355 auto min2 = std::min_element(r.begin(), r.end());
1359 it = std::find(r.begin(), r.end(), low2);
1360 if (it != r.end()) {
1361 std::iter_swap(it, r.end() - 1);
1362 r.erase(r.end() - 1);
1365 int resultado = low1 * low2;
1366 r.push_back(resultado);
1369 std::sort(r.begin(), r.end());
1371 if (r.size() == 1) r.push_back(1);
1376 string ValueWithQuantity::ToString()
const {
1378 auto value = fValue;
1379 if (fQuantity == ENERGY) {
1382 }
else if (fQuantity == TIME) {
1385 }
else if (fQuantity == LENGTH) {
1392 const auto abs = TMath::Abs(value);
1394 return TString::Format(
"%d", 0).Data();
1395 }
else if (abs < 1E-6) {
1396 return TString::Format(
"%.2f %s%s", value * 1E9,
"n", unit.c_str()).Data();
1397 }
else if (abs < 1E-3) {
1398 return TString::Format(
"%.2f %s%s", value * 1E6,
"u", unit.c_str()).Data();
1399 }
else if (abs < 1E0) {
1400 return TString::Format(
"%.2f %s%s", value * 1E3,
"m", unit.c_str()).Data();
1401 }
else if (abs < 1E3) {
1402 return TString::Format(
"%.2f %s%s", value * 1E0,
"", unit.c_str()).Data();
1403 }
else if (abs < 1E6) {
1404 return TString::Format(
"%.2f %s%s", value * 1E-3,
"k", unit.c_str()).Data();
1405 }
else if (abs < 1E9) {
1406 return TString::Format(
"%.2f %s%s", value * 1E-6,
"M", unit.c_str()).Data();
1407 }
else if (abs < 1E12) {
1408 return TString::Format(
"%.2f %s%s", value * 1E-9,
"G", unit.c_str()).Data();
1410 return TString::Format(
"%.2f %s%s", value * 1E-12,
"T", unit.c_str()).Data();
1414 string ToTimeStringLong(
double seconds) {
1415 const auto abs = TMath::Abs(seconds);
1417 return TString::Format(
"%.2f %s", seconds,
"seconds").Data();
1418 }
else if (abs < 60 * 60) {
1419 return TString::Format(
"%.2f %s", seconds / 60.0,
"minutes").Data();
1420 }
else if (abs < 60 * 60 * 24) {
1421 return TString::Format(
"%.2f %s", seconds / (60.0 * 60.0),
"hours").Data();
1423 return TString::Format(
"%.2f %s", seconds / (60.0 * 60.0 * 24.0),
"days").Data();
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...
Double_t StringToDouble(std::string in)
Gets a double from a string.
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.
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.