44#include "TRestTools.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;
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";
173template int TRestTools::PrintTable<Int_t>(std::vector<std::vector<Int_t>> data, Int_t start, Int_t end);
174template int TRestTools::PrintTable<Float_t>(std::vector<std::vector<Float_t>> data, Int_t start, Int_t end);
175template int TRestTools::PrintTable<Double_t>(std::vector<std::vector<Double_t>> data, Int_t start,
184 ofstream file(fname);
185 if (!file.is_open()) {
186 RESTError <<
"Unable to open file for writing : " << fname << RESTendl;
190 for (
unsigned int n = 0; n < data.size(); n++)
191 for (
unsigned int m = 0; m < data[n].size(); m++) {
193 if (m + 1 < data[n].size()) file <<
"\t";
194 if (m + 1 == data[n].size()) file <<
"\n";
201template int TRestTools::ExportASCIITable<Int_t>(std::string fname, std::vector<std::vector<Int_t>>& data);
202template int TRestTools::ExportASCIITable<Float_t>(std::string fname,
203 std::vector<std::vector<Float_t>>& data);
204template int TRestTools::ExportASCIITable<Double_t>(std::string fname,
205 std::vector<std::vector<Double_t>>& data);
213 ofstream file(fname, ios::out | ios::binary);
214 if (!file.is_open()) {
215 RESTError <<
"Unable to open file for writing : " << fname << RESTendl;
219 for (
unsigned int n = 0; n < data.size(); n++)
220 for (
unsigned int m = 0; m < data[n].size(); m++) {
221 file.write((
char*)&data[n][m],
sizeof(T));
228template int TRestTools::ExportBinaryTable<Int_t>(std::string fname, std::vector<std::vector<Int_t>>& data);
229template int TRestTools::ExportBinaryTable<Float_t>(std::string fname,
230 std::vector<std::vector<Float_t>>& data);
231template int TRestTools::ExportBinaryTable<Double_t>(std::string fname,
232 std::vector<std::vector<Double_t>>& data);
253 RESTError <<
"TRestTools::ReadBinaryTable. Error." << RESTendl;
254 RESTError <<
"Cannot open file : " << fName << RESTendl;
261 RESTError <<
"TRestTools::ReadBinaryTable. Format extension error." << RESTendl;
262 RESTError <<
"Please, specify the number of columns at the method 3rd argument" << RESTendl;
267 std::ifstream fin(fName, std::ios::binary);
268 fin.seekg(0, std::ios::end);
269 const size_t num_elements = fin.tellg() /
sizeof(T);
270 fin.seekg(0, std::ios::beg);
272 if (num_elements % columns != 0) {
273 cout <<
"TRestTools::ReadBinaryTable. Error." << endl;
274 cout <<
"Number of elements : " << num_elements
275 <<
" is not compatible with the number of columns : " << columns << endl;
280 std::vector<T> dataArray(columns);
281 fin.read(
reinterpret_cast<char*
>(&dataArray[0]), columns *
sizeof(T));
283 data.push_back(dataArray);
284 fin.read(
reinterpret_cast<char*
>(&dataArray[0]), columns *
sizeof(T));
289template int TRestTools::ReadBinaryTable<Int_t>(
string fName, std::vector<std::vector<Int_t>>& data,
291template int TRestTools::ReadBinaryTable<Float_t>(
string fName, std::vector<std::vector<Float_t>>& data,
293template int TRestTools::ReadBinaryTable<Double_t>(
string fName, std::vector<std::vector<Double_t>>& data,
315 if (extension.find(
"N") != 0) {
319 size_t pos = extension.find(
"i");
320 if (pos != string::npos) {
324 pos = extension.find(
"f");
325 if (pos != string::npos) {
329 pos = extension.find(
"d");
330 if (pos != string::npos) {
334 RESTError <<
"Format " <<
ToUpper(extension) <<
" not recognized" << RESTendl;
344 if (data.size() == 0)
return;
346 std::vector<std::vector<T>> trans_vec(data[0].size(), std::vector<T>());
348 for (
unsigned int i = 0; i < data.size(); i++)
349 for (
unsigned int j = 0; j < data[i].size(); j++) trans_vec[j].push_back(data[i][j]);
354template void TRestTools::TransposeTable<Double_t>(std::vector<std::vector<Double_t>>& data);
356template void TRestTools::TransposeTable<Float_t>(std::vector<std::vector<Float_t>>& data);
358template void TRestTools::TransposeTable<Int_t>(std::vector<std::vector<Int_t>>& data);
369 if (data.size() == 0)
return 0;
370 if (column > -1 && data[0].size() <= (
unsigned int)column)
return 0;
372 T maxValue = data[0][0];
374 for (
unsigned int n = 0; n < data.size(); n++)
375 for (
unsigned int c = 0; c < data[n].size(); c++)
376 if (maxValue < data[n][c]) maxValue = data[n][c];
378 maxValue = data[0][column];
379 for (
unsigned int n = 0; n < data.size(); n++)
380 if (maxValue < data[n][column]) maxValue = data[n][column];
386template Int_t TRestTools::GetMaxValueFromTable<Int_t>(
const std::vector<std::vector<Int_t>>& data,
389template Float_t TRestTools::GetMaxValueFromTable<Float_t>(
const std::vector<std::vector<Float_t>>& data,
392template Double_t TRestTools::GetMaxValueFromTable<Double_t>(
const std::vector<std::vector<Double_t>>& data,
404 if (data.empty())
return 0;
405 if (column != -1 && data[0].size() <= (
unsigned int)column)
return 0;
407 T minValue = data[0][0];
409 for (
unsigned int n = 0; n < data.size(); n++)
410 for (
unsigned int c = 0; c < data[n].size(); c++)
411 if (minValue > data[n][c]) minValue = data[n][c];
413 minValue = data[0][column];
414 for (
unsigned int n = 0; n < data.size(); n++)
415 if (minValue > data[n][column]) minValue = data[n][column];
421template Int_t TRestTools::GetMinValueFromTable<Int_t>(
const std::vector<std::vector<Int_t>>& data,
424template Float_t TRestTools::GetMinValueFromTable<Float_t>(
const std::vector<std::vector<Float_t>>& data,
427template Double_t TRestTools::GetMinValueFromTable<Double_t>(
const std::vector<std::vector<Double_t>>& data,
441 if (data.size() == 0 || data[0].size() <= (
unsigned int)column)
return 0;
442 T lowestIncrease = abs(data[0][column] - data[1][column]);
443 for (
unsigned int n = 1; n < data.size(); n++) {
444 T value = abs(data[n - 1][column] - data[n][column]);
445 if (lowestIncrease == 0) lowestIncrease = value;
446 if (value > 0 && value < lowestIncrease) lowestIncrease = value;
448 return lowestIncrease;
451template Int_t TRestTools::GetLowestIncreaseFromTable<Int_t>(std::vector<std::vector<Int_t>> data,
454template Float_t TRestTools::GetLowestIncreaseFromTable<Float_t>(std::vector<std::vector<Float_t>> data,
457template Double_t TRestTools::GetLowestIncreaseFromTable<Double_t>(std::vector<std::vector<Double_t>> data,
471 if (data.size() == 0)
return 0;
473 for (
unsigned int n = 0; n < data.size(); n++) {
474 for (
unsigned int m = 0; m < data[n].size(); m++) sum += data[n][m];
479template Int_t TRestTools::GetIntegralFromTable<Int_t>(
const std::vector<std::vector<Int_t>>& data);
481template Float_t TRestTools::GetIntegralFromTable<Float_t>(
const std::vector<std::vector<Float_t>>& data);
483template Double_t TRestTools::GetIntegralFromTable<Double_t>(
const std::vector<std::vector<Double_t>>& data);
493 std::vector<T> columnData;
494 if (data.size() == 0 || data[0].size() <= column)
return columnData;
496 for (
unsigned int n = 0; n < data.size(); n++) columnData.push_back(data[n][column]);
501template std::vector<Int_t> TRestTools::GetColumnFromTable<Int_t>(
const std::vector<std::vector<Int_t>>& data,
502 unsigned int column);
504template std::vector<Float_t> TRestTools::GetColumnFromTable<Float_t>(
505 const std::vector<std::vector<Float_t>>& data,
unsigned int column);
507template std::vector<Double_t> TRestTools::GetColumnFromTable<Double_t>(
508 const std::vector<std::vector<Double_t>>& data,
unsigned int column);
524 std::string separator) {
526 cout <<
"TRestTools::ReadASCIITable. Error" << endl;
527 cout <<
"Cannot open file : " << fName << endl;
533 std::ifstream fin(fName);
536 std::vector<std::vector<string>> values;
538 for (
string line; std::getline(fin, line);) {
544 if (line.find(
"#") == string::npos) {
545 std::istringstream in(line);
548 std::vector<std::string> tokens;
549 while (std::getline(in, token, (
char)separator[0])) {
550 tokens.push_back(token);
552 values.push_back(tokens);
557 for (
unsigned int n = 0; n < values.size(); n++) {
558 std::vector<Double_t> dblTmp;
561 for (
unsigned int m = 0; m < values[n].size(); m++) dblTmp.push_back(
StringToDouble(values[n][m]));
563 data.push_back(dblTmp);
583 std::string separator) {
585 cout <<
"TRestTools::ReadASCIITable. Error" << endl;
586 cout <<
"Cannot open file : " << fName << endl;
592 std::ifstream fin(fName);
595 std::vector<std::vector<string>> values;
597 for (
string line; std::getline(fin, line);) {
603 if (line.find(
"#") == string::npos) {
604 std::istringstream in(line);
607 std::vector<std::string> tokens;
608 while (std::getline(in, token, (
char)separator[0])) {
609 tokens.push_back(token);
611 values.push_back(tokens);
616 for (
unsigned int n = 0; n < values.size(); n++) {
617 std::vector<Float_t> dblTmp;
620 for (
unsigned int m = 0; m < values[n].size(); m++) dblTmp.push_back(
StringToFloat(values[n][m]));
622 data.push_back(dblTmp);
687 TFile* f = TFile::Open((TString)filename);
689 TIter nextkey(f->GetListOfKeys());
691 while ((key = (TKey*)nextkey())) {
692 if ((std::string)key->GetClassName() ==
"TRestRun")
return true;
703 TFile* f = TFile::Open((TString)filename);
705 TIter nextkey(f->GetListOfKeys());
707 while ((key = (TKey*)nextkey())) {
708 if ((std::string)key->GetClassName() ==
"TRestDataSet")
return true;
717 std::regex pattern(
"^https?://(.+)");
718 return std::regex_match(s, pattern);
727 result = _access(path.c_str(), 2);
729 result = access(path.c_str(), 2);
742 if (path[0] ==
'/' || path[0] ==
'~' || path.find(
':') != string::npos) {
760 filesystem::path path(fullname);
761 return {path.parent_path().string(), path.filename().string()};
770 string extension = filesystem::path(fullname).extension().string();
771 if (extension.size() > 1)
return extension.substr(1);
781 return filesystem::path(fullname).stem().string();
792 string to_replace =
"//";
793 size_t start_pos = str.find(to_replace);
794 while (start_pos != string::npos) {
795 str.replace(start_pos, to_replace.length(),
"/");
796 start_pos = str.find(to_replace);
815 filesystem::path path;
816 for (
const auto& directory : filesystem::path(filename)) {
817 if (path.empty() && directory ==
"~") {
819 const auto envVariableHome = getenv(
"HOME");
820 if (envVariableHome ==
nullptr) {
821 cout <<
"TRestTools::ToAbsoluteName - ERROR - "
822 "cannot resolve ~ because 'HOME' env variable does not exist"
826 const auto userHomePath = filesystem::path(envVariableHome);
827 if (userHomePath.empty()) {
828 cout <<
"TRestTools::ToAbsoluteName - ERROR - "
829 "cannot resolve ~ because 'HOME' env variable is not set to a valid value"
833 path /= userHomePath;
838 return filesystem::weakly_canonical(path).string();
851 vector<string> result;
853 std::filesystem::path path(_path);
855 std::filesystem::directory_iterator iter(path);
856 for (
auto& it : iter) {
857 if (it.is_directory()) {
858 result.push_back(it.path().string());
860 if (recursion != 0) {
862 result.insert(result.begin(), subD.begin(), subD.end());
879 for (
unsigned int i = 0; i < paths.size(); i++) {
880 string path = paths[i];
881 if (path[path.size() - 1] !=
'/') {
886 return path + filename;
891 for (
unsigned int j = 0; j < pathsExpanded.size(); j++)
892 if (
fileExists(pathsExpanded[j] +
"/" + filename))
return pathsExpanded[j] +
"/" + filename;
904 ifs.open(filename.c_str());
919 std::vector<string> outputFileNames;
921 vector<string> items =
Split(pattern,
"\n");
922 for (
auto item : items) {
923 if (item.find_first_of(
"*?") != string::npos) {
925 item =
Replace(item,
"/",
"\\");
927 item.substr(0, item.find_first_of(
"*?"));
929 string _path = path_name.first;
930 if (!std::filesystem::exists(_path)) {
931 RESTError <<
"TRestTools::GetFilesMatchingPattern(): path " << _path <<
" does not exist!"
933 return outputFileNames;
936 std::filesystem::path path(_path);
937 std::filesystem::recursive_directory_iterator iter(path);
938 for (
auto& it : iter) {
939 if (it.is_regular_file()) {
940 string filename = it.path().string();
942 outputFileNames.push_back(it.path().string());
947 string a =
Execute(
"find " + item);
948 auto b =
Split(a,
"\n");
950 for (
unsigned int i = 0; i < b.size(); i++) {
951 outputFileNames.push_back(b[i]);
956 if (
fileExists(item)) outputFileNames.push_back(item);
960 return outputFileNames;
968#define REST_VERSION(a, b, c) (((a) << 16) + ((b) << 8) + (c))
970 vector<string> ver =
Split(in,
".");
971 if (ver.size() == 3) {
974 int n =
StringToInteger(v.substr(0, v.find_first_not_of(
"0123456789")));
981 return REST_VERSION(verint[0], verint[1], verint[2]);
990 std::array<char, 128> buffer;
993 std::unique_ptr<FILE,
decltype(&_pclose)> pipe(_popen((
"powershell.exe " + cmd).c_str(),
"r"), _pclose);
995 std::unique_ptr<FILE,
decltype(&pclose)> pipe(popen(cmd.c_str(),
"r"), pclose);
999 throw std::runtime_error(
"popen() failed!");
1001 while (fgets(buffer.data(), buffer.size(), pipe.get()) !=
nullptr) {
1002 result += buffer.data();
1005 if (result.size() > 0 && result[result.size() - 1] ==
'\n')
1006 result = result.substr(0, result.size() - 1);
1024 std::istream::sentry se(is,
true);
1025 std::streambuf* sb = is.rdbuf();
1028 int c = sb->sbumpc();
1033 if (sb->sgetc() ==
'\n') sb->sbumpc();
1035 case std::streambuf::traits_type::eof():
1037 if (t.empty()) is.setstate(std::ios::eofbit);
1054 if (pureName.empty()) {
1055 RESTWarning <<
"error! (TRestTools::DownloadRemoteFile): url is not a file!" << RESTendl;
1056 RESTWarning <<
"please specify a concrete file name in this url" << RESTendl;
1057 RESTWarning <<
"url: " << url << RESTendl;
1061 if (url.find(
"local:") == 0) {
1062 return Replace(url,
"local:",
"");
1064 string fullpath = REST_USER_PATH +
"/download/" + pureName;
1070 RESTWarning <<
"Retrying download in 5 seconds" << RESTendl;
1071 std::this_thread::sleep_for(std::chrono::seconds(5));
1072 }
else if (attempts < 10) {
1073 RESTSuccess <<
"Download succeeded after " << 10 - attempts <<
" attempts" << RESTendl;
1076 }
while (out == 1024 && attempts > 0);
1094 TUrl url(remoteFile.c_str());
1096 RESTInfo <<
"Downloading remote file : " << remoteFile << RESTendl;
1097 RESTInfo <<
"To local file : " << localFile << RESTendl;
1099 string localFiletmp = localFile +
".restdownload";
1100 if ((
string)url.GetProtocol() ==
"https" || (
string)url.GetProtocol() ==
"http") {
1103 if (!filesystem::create_directories(path)) {
1104 std::cerr <<
"mkdir failed to create directory: " << path << std::endl;
1109 string cmd =
"wget --no-check-certificate " + EscapeSpecialLetters(remoteFile) +
" -O " +
1110 EscapeSpecialLetters(localFiletmp) +
" -q";
1111 RESTDebug << cmd << RESTendl;
1112 int a = system(cmd.c_str());
1115 rename(localFiletmp.c_str(), localFile.c_str());
1118 RESTError <<
"download failed! (" << remoteFile <<
")" << RESTendl;
1120 RESTError <<
"Network connection problem?" << RESTendl;
1124 RESTError <<
"File does NOT exist in remotely?" << RESTendl;
1128 }
else if ((
string)url.GetProtocol() ==
"ssh") {
1129 string cmd =
"scp -P " + ToString(url.GetPort() == 0 ? 22 : url.GetPort()) +
" " + url.GetUser() +
1130 "@" + url.GetHost() +
":" + EscapeSpecialLetters(url.GetFile()) +
" " + localFiletmp;
1131 cout << cmd << endl;
1132 int a = system(cmd.c_str());
1134 rename(localFiletmp.c_str(), localFile.c_str());
1139 RESTWarning <<
"Trying to download: " << remoteFile << RESTendl;
1140 RESTWarning <<
"Unknown protocol!" << RESTendl;
1152 std::string file_content =
"";
1157 string filename = REST_USER_PATH +
"/download/curl.out";
1160 curl_global_init(CURL_GLOBAL_ALL);
1162 FILE* f = fopen(filename.c_str(),
"wt");
1164 std::string request =
"";
1166 for (
auto const& x : keys) {
1167 if (n > 0) request +=
"&";
1168 request += x.first +
"=" + x.second;
1172 curl = curl_easy_init();
1177 curl_easy_setopt(curl, CURLOPT_URL, url.c_str());
1178 curl_easy_setopt(curl, CURLOPT_WRITEDATA, (
void*)f);
1180 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, request.c_str());
1183 res = curl_easy_perform(curl);
1185 if (res != CURLE_OK)
1186 RESTError <<
"curl_easy_perform() failed: " << curl_easy_strerror(res) << RESTendl;
1189 curl_easy_cleanup(curl);
1192 curl_global_cleanup();
1194 std::getline(std::ifstream(filename), file_content,
'\0');
1196 RESTError <<
"TRestTools::POSTRequest. REST framework was compiled without CURL support" << RESTendl;
1197 RESTError <<
"Please recompile REST after installing curl development libraries." << RESTendl;
1198 RESTError <<
"Depending on your system this might be: curl-dev, curl-devel or libcurl-openssl-dev. "
1200 RESTError <<
"No file will be downloaded" << RESTendl;
1203 return file_content;
1215 cout <<
"error! local file not exist!" << endl;
1220 TUrl url(remoteFile.c_str());
1221 TUrl method(methodUrl.c_str());
1222 if (method.GetProtocol() != (
string)
"") url.SetProtocol(method.GetProtocol());
1223 if (method.GetPort() != 0) url.SetPort(method.GetPort());
1224 if (method.GetUser() != (
string)
"") url.SetUser(method.GetUser());
1225 if (method.GetPasswd() != (
string)
"") url.SetPasswd(method.GetPasswd());
1227 if ((
string)url.GetProtocol() ==
"https" || (
string)url.GetProtocol() ==
"http") {
1229 }
else if ((
string)url.GetProtocol() ==
"ssh") {
1230 string cmd =
"scp -P " + ToString(url.GetPort() == 0 ? 22 : url.GetPort()) +
" " +
1231 EscapeSpecialLetters(localFile) +
" " + url.GetUser() +
"@" + url.GetHost() +
":" +
1232 EscapeSpecialLetters(url.GetFile());
1233 cout << cmd << endl;
1234 int a = system(cmd.c_str());
1237 RESTError << __PRETTY_FUNCTION__ << RESTendl;
1238 RESTError <<
"problem copying gases definitions to remote server" << RESTendl;
1239 RESTError <<
"Please report this problem at "
1240 "http://gifna.unizar.es/rest-forum/"
1250void TRestTools::ChangeDirectory(
const string& toDirectory) { filesystem::current_path(toDirectory); }
1252string ValueWithQuantity::ToString()
const {
1254 auto value = fValue;
1255 if (fQuantity == ENERGY) {
1258 }
else if (fQuantity == TIME) {
1261 }
else if (fQuantity == LENGTH) {
1268 const auto abs = TMath::Abs(value);
1270 return TString::Format(
"%d", 0).Data();
1271 }
else if (abs < 1E-6) {
1272 return TString::Format(
"%.2f %s%s", value * 1E9,
"n", unit.c_str()).Data();
1273 }
else if (abs < 1E-3) {
1274 return TString::Format(
"%.2f %s%s", value * 1E6,
"u", unit.c_str()).Data();
1275 }
else if (abs < 1E0) {
1276 return TString::Format(
"%.2f %s%s", value * 1E3,
"m", unit.c_str()).Data();
1277 }
else if (abs < 1E3) {
1278 return TString::Format(
"%.2f %s%s", value * 1E0,
"", unit.c_str()).Data();
1279 }
else if (abs < 1E6) {
1280 return TString::Format(
"%.2f %s%s", value * 1E-3,
"k", unit.c_str()).Data();
1281 }
else if (abs < 1E9) {
1282 return TString::Format(
"%.2f %s%s", value * 1E-6,
"M", unit.c_str()).Data();
1283 }
else if (abs < 1E12) {
1284 return TString::Format(
"%.2f %s%s", value * 1E-9,
"G", unit.c_str()).Data();
1286 return TString::Format(
"%.2f %s%s", value * 1E-12,
"T", unit.c_str()).Data();
1290string ToTimeStringLong(
double seconds) {
1291 const auto abs = TMath::Abs(seconds);
1293 return TString::Format(
"%.2f %s", seconds,
"seconds").Data();
1294 }
else if (abs < 60 * 60) {
1295 return TString::Format(
"%.2f %s", seconds / 60.0,
"minutes").Data();
1296 }
else if (abs < 60 * 60 * 24) {
1297 return TString::Format(
"%.2f %s", seconds / (60.0 * 60.0),
"hours").Data();
1299 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 every occurences of thisSring by byThisString inside string in.