461#include "TRestMetadata.h"
465#include <TStreamerInfo.h>
469#include "TRestDataBase.h"
487map<string, string> TRestMetadata_UpdatedConfigFile;
504 RESTMetadata.setlength(100);
507 fOfficialRelease =
true;
529 RESTMetadata.setlength(100);
532 fOfficialRelease =
true;
555 const string thisSectionName = sectionName.empty() ? this->ClassName() : sectionName;
562 if (Sectional ==
nullptr) {
563 RESTError <<
"cannot find xml section \"" << ClassName() <<
"\" with name \"" << sectionName
571 TiXmlElement* Global =
GetElement(
"globals", rootEle);
573 if (Global !=
nullptr && Global->NextSiblingElement(
"globals") !=
nullptr) {
574 TiXmlElement* ele = Global->NextSiblingElement(
"globals");
576 while (ele !=
nullptr) {
577 TiXmlElement* e = ele->FirstChildElement();
578 while (e !=
nullptr) {
579 Global->InsertEndChild(*e);
580 e = e->NextSiblingElement();
582 ele = ele->NextSiblingElement(
"globals");
593 RESTError <<
"Config File does not exist. Right path/filename?" <<
RESTendl;
600 if (sectional ==
nullptr) {
601 RESTError <<
"cannot find xml section \"" << ClassName() <<
"\" with name \"" << thisSectionName
609 TiXmlElement* global =
GetElement(
"globals", rootEle);
611 if (global !=
nullptr && global->NextSiblingElement(
"globals") !=
nullptr) {
612 TiXmlElement* ele = global->NextSiblingElement(
"globals");
614 while (ele !=
nullptr) {
615 TiXmlElement* e = ele->FirstChildElement();
616 while (e !=
nullptr) {
617 global->InsertEndChild(*e);
618 e = e->NextSiblingElement();
620 ele = ele->NextSiblingElement(
"globals");
639 map<string, string> envs) {
641 TiXmlElement* theElement;
642 if (eSectional !=
nullptr && eGlobal !=
nullptr) {
644 theElement = (TiXmlElement*)eSectional->Clone();
645 TiXmlElement* echild = eGlobal->FirstChildElement();
646 while (echild !=
nullptr) {
647 theElement->LinkEndChild(echild->Clone());
648 echild = echild->NextSiblingElement();
653 }
else if (eSectional !=
nullptr) {
654 theElement = (TiXmlElement*)eSectional->Clone();
655 }
else if (eGlobal !=
nullptr) {
656 theElement = (TiXmlElement*)eGlobal->Clone();
661 fElementGlobal = eGlobal ? (TiXmlElement*)eGlobal->Clone() :
nullptr;
666 RESTDebug << ClassName() <<
" has finished preparing config data" <<
RESTendl;
714 auto paraele =
fElement->FirstChildElement();
715 while (paraele !=
nullptr) {
716 std::string xmlChild = paraele->Value();
717 if (xmlChild.find(
"TRest") == 0) {
718 if (pattern ==
"" || xmlChild.find(pattern) != string::npos) {
719 if (count == index) {
720 TClass* c = TClass::GetClass(xmlChild.c_str());
724 if (!md)
return nullptr;
727 TiXmlElement* Global =
GetElement(
"globals", rootEle);
736 paraele = paraele->NextSiblingElement();
767 auto paraele =
fElement->FirstChildElement();
768 while (paraele !=
nullptr) {
769 std::string xmlChild = paraele->Value();
770 if (xmlChild.find(
"TRest") == 0) {
771 if (pattern.empty() || xmlChild.find(pattern) != string::npos) {
772 if (name.empty() || (!name.empty() && name == (
string)paraele->Attribute(
"name"))) {
773 TClass* c = TClass::GetClass(xmlChild.c_str());
778 TiXmlElement* Global =
GetElement(
"globals", rootEle);
786 paraele = paraele->NextSiblingElement();
805 RESTDebug <<
"Loading Config for : " << this->ClassName() <<
RESTendl;
810 while (e !=
nullptr) {
813 e = e->NextSiblingElement();
818 TiXmlElement* e =
fElement->FirstChildElement();
819 while (e !=
nullptr) {
822 e = e->NextSiblingElement();
833 this->SetName(
GetParameter(
"name",
"default" +
string(this->ClassName())).c_str());
834 this->SetTitle(
GetParameter(
"title",
"Default " +
string(this->ClassName())).c_str());
849 if (e ==
nullptr)
return nullptr;
851 RESTDebug <<
"Entering ... TRestMetadata::ReplaceElementAttributes" <<
RESTendl;
853 std::string parName =
"";
854 TiXmlAttribute* attr = e->FirstAttribute();
855 while (attr !=
nullptr) {
856 const char* val = attr->Value();
857 const char* name = attr->Name();
858 RESTDebug <<
"Element name : " << name <<
" value : " << val <<
RESTendl;
860 string newVal = val !=
nullptr ? val :
"";
889 if (e ==
nullptr)
return;
891 const char* name = e->Attribute(
"name");
892 if (name ==
nullptr)
return;
893 const char* value = e->Attribute(
"value");
894 if (value ==
nullptr)
return;
896 if ((
string)e->Value() ==
"variable") {
898 const char* overwritesysenv = e->Attribute(
"overwrite");
899 if (overwritesysenv ==
nullptr) overwritesysenv =
"false";
900 if (!StringToBool(overwritesysenv)) {
901 char* sysenv = getenv(name);
902 if (sysenv !=
nullptr) value = sysenv;
904 if (!overwrite &&
fVariables.count(name) > 0)
return;
906 }
else if ((
string)e->Value() ==
"constant") {
907 if (!overwrite &&
fVariables.count(name) > 0)
return;
909 }
else if ((
string)e->Value() ==
"myParameter") {
910 RESTWarning <<
"myParameter is obsolete now! use \"constant\" instead" <<
RESTendl;
911 if (!overwrite &&
fVariables.count(name) > 0)
return;
925 RESTDebug << ClassName() <<
"::ReadElement(<" << e->Value() <<
")" <<
RESTendl;
926 if (e ==
nullptr)
return;
931 if ((
string)e->Value() ==
"for") {
933 }
else if (e->Attribute(
"file") !=
nullptr) {
935 }
else if ((
string)e->Value() ==
"if") {
937 }
else if (e->FirstChildElement() !=
nullptr) {
938 TiXmlElement* contentelement = e->FirstChildElement();
941 while (contentelement !=
nullptr) {
942 TiXmlElement* nxt = contentelement->NextSiblingElement();
943 if (recursive || ((
string)contentelement->Value()).find(
"TRest") == string::npos) {
944 RESTDebug <<
"into child element \"" << contentelement->Value() <<
"\" of \"" << e->Value()
948 RESTDebug <<
"skipping child element \"" << contentelement->Value() <<
"\" of \""
951 contentelement = nxt;
982 if (e ==
nullptr)
return;
983 if ((
string)e->Value() !=
"if")
return;
985 const char* evaluate = e->Attribute(
"evaluate");
986 const char* condition = e->Attribute(
"condition");
988 if (condition ==
nullptr ||
string(condition).find_first_of(
"=!<>") == string::npos) {
989 RESTWarning <<
"Invalid \"IF\" structure!" <<
RESTendl;
993 int p1 = string(condition).find_first_of(
"=!<>");
994 int p2 = string(condition).find_first_not_of(
"=!<>", p1);
997 bool matches =
false;
998 if (evaluate !=
nullptr) {
1000 }
else if (p1 > 0) {
1001 v1 = string(condition).substr(0, p1);
1003 RESTWarning <<
"Invalid \"IF\" structure!" <<
RESTendl;
1007 string con = string(condition).substr(p1, p2 - p1);
1008 string v2 = string(condition).substr(p2, -1);
1012 if (atof(v1.c_str()) == atof(v2.c_str())) matches =
true;
1014 if (v1 == v2) matches =
true;
1016 }
else if (con ==
"!=") {
1018 if (atof(v1.c_str()) != atof(v2.c_str())) matches =
true;
1020 if (v1 != v2) matches =
true;
1022 }
else if (con ==
">") {
1024 if (atof(v1.c_str()) > atof(v2.c_str())) matches =
true;
1026 if (v1 > v2) matches =
true;
1028 }
else if (con ==
"<") {
1030 if (atof(v1.c_str()) < atof(v2.c_str())) matches =
true;
1032 if (v1 < v2) matches =
true;
1034 }
else if (con ==
">=") {
1036 if (atof(v1.c_str()) >= atof(v2.c_str())) matches =
true;
1038 if (v1 >= v2) matches =
true;
1040 }
else if (con ==
"<=") {
1042 if (atof(v1.c_str()) <= atof(v2.c_str())) matches =
true;
1044 if (v1 <= v2) matches =
true;
1047 RESTWarning <<
"Invalid \"IF\" structure!" <<
RESTendl;
1052 TiXmlElement* parele = (TiXmlElement*)e->Parent();
1053 if (parele ==
nullptr)
return;
1054 TiXmlElement* contentelement = e->FirstChildElement();
1055 while (contentelement !=
nullptr) {
1056 TiXmlElement* attachedelement = (TiXmlElement*)contentelement->Clone();
1059 parele->InsertBeforeChild(e, *attachedelement);
1060 delete attachedelement;
1061 contentelement = contentelement->NextSiblingElement();
1073 TiXmlElement* parele = (TiXmlElement*)e->Parent();
1074 TiXmlElement* contentelement = e->FirstChildElement();
1075 while (contentelement !=
nullptr) {
1076 if ((
string)contentelement->Value() ==
"for") {
1077 TiXmlElement* newforloop = (TiXmlElement*)contentelement->Clone();
1079 TiXmlElement* tempnew = (TiXmlElement*)parele->InsertBeforeChild(e, *newforloop);
1081 newforloop = tempnew;
1083 contentelement = contentelement->NextSiblingElement();
1085 TiXmlElement* attachedelement = (TiXmlElement*)contentelement->Clone();
1089 parele->InsertBeforeChild(e, *attachedelement);
1090 delete attachedelement;
1091 contentelement = contentelement->NextSiblingElement();
1100 if (e ==
nullptr)
return;
1102 RESTDebug <<
"Entering ... TRestMetadata::ReplaceForLoopVars" <<
RESTendl;
1103 std::string parName;
1104 TiXmlAttribute* attr = e->FirstAttribute();
1105 while (attr !=
nullptr) {
1106 const char* val = attr->Value();
1107 const char* name = attr->Name();
1108 RESTDebug <<
"Attribute name : " << name <<
" value : " << val <<
RESTendl;
1110 if (strcmp(name,
"name") == 0) parName = (string)val;
1113 if (strcmp(name,
"name") != 0) {
1114 string outputBuffer = val;
1116 if (outputBuffer.find(
'[') != string::npos || outputBuffer.find(
']') != string::npos) {
1117 RESTError <<
"TRestMetadata::ReplaceForLoopVars. Old for-loop construction identified"
1119 RESTError <<
"Please, replace [] variable nomenclature by ${}." <<
RESTendl;
1124 int startPosition = 0;
1125 int endPosition = 0;
1126 while ((startPosition = outputBuffer.find(
"{", endPosition)) != (
int)string::npos) {
1127 endPosition = outputBuffer.find(
"}", startPosition + 1);
1128 if (endPosition == (
int)string::npos)
break;
1129 if (startPosition >= 1 && outputBuffer[startPosition - 1] ==
'$')
1132 string expression = outputBuffer.substr(startPosition + 1, endPosition - startPosition - 1);
1134 int replacePos = startPosition;
1135 int replaceLen = endPosition - startPosition + 1;
1137 string proenv = forLoopVar.count(expression) > 0 ? forLoopVar[expression] :
"";
1139 if (!proenv.empty()) {
1140 outputBuffer.replace(replacePos, replaceLen, proenv);
1143 RESTError << this->ClassName() <<
", replace for loop env : cannot find \"{" << expression
1151 "Please, check parameter name: " + parName +
" (ReplaceForLoopVars)")
1155 attr = attr->Next();
1167 if (e ==
nullptr)
return;
1168 if ((
string)e->Value() !=
"for")
return;
1169 RESTDebug <<
"Entering ... ExpandForLoops" <<
RESTendl;
1172 TString varname = TString(e->Attribute(
"variable"));
1173 TString varfrom = TString(e->Attribute(
"from"));
1174 TString varto = TString(e->Attribute(
"to"));
1175 TString varstep = TString(e->Attribute(
"step"));
1176 TString varin = TString(e->Attribute(
"in"));
1178 RESTDebug <<
"variable: " << varname <<
" from: " << varfrom <<
" to: " << varto <<
" step: " << varstep
1181 if ((varin ==
"") && (varname ==
"" || varfrom ==
"" || varto ==
""))
return;
1182 if (varstep ==
"") varstep =
"1";
1183 TiXmlElement* parele = (TiXmlElement*)e->Parent();
1184 if (parele ==
nullptr)
return;
1186 string _name = (string)varname;
1187 string _from = (string)varfrom;
1188 string _to = (string)varto;
1189 string _step = (string)varstep;
1190 string _in = (string)varin;
1191 RESTDebug <<
"_from: " << _from <<
" _to: " << _to <<
" _step: " << _step <<
RESTendl;
1197 RESTDebug <<
"----expanding for loop----" <<
RESTendl;
1199 for (i = from; i <= to; i = i + step) {
1200 forloopvar[_name] = ToString(i);
1204 parele->RemoveChild(e);
1207 RESTDebug <<
"----end of for loop----" <<
RESTendl;
1208 }
else if (!_in.empty()) {
1209 vector<string> loopvars =
Split(_in,
":");
1211 RESTDebug <<
"----expanding for loop----" <<
RESTendl;
1212 for (
const string& loopvar : loopvars) {
1213 forloopvar[_name] = loopvar;
1217 parele->RemoveChild(e);
1220 RESTDebug <<
"----end of for loop----" <<
RESTendl;
1247 RESTDebug <<
"Entering ... " << __PRETTY_FUNCTION__ <<
RESTendl;
1248 if (e ==
nullptr)
return;
1251 const char* _filename = e->Attribute(
"file");
1252 if (_filename ==
nullptr)
return;
1259 auto url = gDataBase->
query_data(DBEntry(0,
"META_RML", e->Value())).value;
1270 if (filename.empty()) {
1271 RESTError <<
"TRestMetadata::ExpandIncludeFile. Include file \"" << _filename <<
"\" does not exist!"
1278 RESTDebug <<
"----expanding include file----" <<
RESTendl;
1281 TiXmlElement* remoteele =
nullptr;
1282 TiXmlElement* localele =
nullptr;
1294 if ((
string)e->Value() ==
"include") {
1295 localele = (TiXmlElement*)e->Parent();
1296 if (localele ==
nullptr)
return;
1297 if (localele->Attribute(
"expanded") ==
nullptr
1299 : ((string)localele->Attribute(
"expanded") ==
"true")) {
1300 RESTDebug <<
"----already expanded----" <<
RESTendl;
1304 remoteele =
new TiXmlElement(
"Config");
1307 if (ele ==
nullptr) {
1308 RESTError <<
"TRestMetadata::ExpandIncludeFile. No xml elements contained in the include "
1313 while (ele !=
nullptr) {
1314 remoteele->InsertEndChild(*ele);
1315 ele = ele->NextSiblingElement();
1335 if (localele->Attribute(
"expanded") ==
nullptr
1337 : ((
string)localele->Attribute(
"expanded") ==
"true")) {
1338 RESTDebug <<
"----already expanded----" <<
RESTendl;
1342 type = e->Attribute(
"type") !=
nullptr ? e->Attribute(
"type") : e->Value();
1343 name = localele->Attribute(
"name") ==
nullptr ?
"" : localele->Attribute(
"name");
1347 if (rootele ==
nullptr) {
1348 RESTError <<
"TRestMetaddata::ExpandIncludeFile. Include file " << filename
1349 <<
" is of wrong xml format!" <<
RESTendl;
1353 if ((
string)rootele->Value() == type) {
1356 remoteele = rootele;
1359 if (type !=
"globals" &&
GetElement(
"globals", rootele) !=
nullptr) {
1360 TiXmlElement* globaldef =
GetElement(
"globals", rootele)->FirstChildElement();
1361 while (globaldef !=
nullptr) {
1363 globaldef = globaldef->NextSiblingElement();
1370 vector<TiXmlElement*> eles;
1371 TiXmlElement* ele = rootele->FirstChildElement();
1372 while (ele !=
nullptr) {
1373 if (ele->Attribute(
"name") !=
nullptr && (
string)ele->Attribute(
"name") == name) {
1374 eles.push_back(ele);
1376 ele = ele->NextSiblingElement();
1379 if (eles.size() > 1) {
1380 RESTWarning <<
"(expand include file): find multiple xml sections with same name!"
1382 RESTWarning <<
"Using the first one!" <<
RESTendl;
1385 if (eles.size() > 0) remoteele = (TiXmlElement*)eles[0]->Clone();
1386 }
else if (type !=
"") {
1387 remoteele = (TiXmlElement*)
GetElement(type, rootele)->Clone();
1390 if (remoteele ==
nullptr) {
1391 RESTWarning <<
"Cannot find the needed xml section in "
1394 RESTWarning <<
"type: \"" << type <<
"\" , name: \"" << name <<
"\" . Skipping"
1403 RESTDebug <<
"Target xml element spotted" <<
RESTendl;
1410 TiXmlAttribute* attr = remoteele->FirstAttribute();
1411 while (attr !=
nullptr) {
1412 if (localele->Attribute(attr->Name()) ==
nullptr) {
1413 localele->SetAttribute(attr->Name(), attr->Value());
1416 attr = attr->Next();
1418 TiXmlElement* ele = remoteele->FirstChildElement();
1419 while (ele !=
nullptr) {
1421 if ((
string)ele->Value() !=
"for") {
1422 localele->InsertEndChild(*ele);
1425 ele = ele->NextSiblingElement();
1428 localele->SetAttribute(
"expanded",
"true");
1430 localele->Print(stdout, 0);
1434 RESTDebug << nattr <<
" attributes and " << nele <<
" xml elements added by inclusion" <<
RESTendl;
1435 RESTDebug <<
"----end of expansion file----" <<
RESTendl;
1452 if (REST_ARGS.count(parName) != 0) {
1453 return REST_ARGS[parName];
1458 if (result != PARAMETER_NOT_FOUND_STR) {
1462 return (
string)defaultValue;
1491 RESTDebug <<
"Element is null" <<
RESTendl;
1492 return (
string)defaultValue;
1494 string result = (string)defaultValue;
1496 if (e->Attribute(parName.c_str()) !=
nullptr) {
1497 result = e->Attribute(parName.c_str());
1502 if (element !=
nullptr && element->Attribute(
"value") !=
nullptr) {
1503 result = element->Attribute(
"value");
1505 RESTDebug << ClassName() <<
": Parameter : " << parName <<
" not found!" <<
RESTendl;
1510 "Please, check parameter name: " + parName);
1513Double_t TRestMetadata::GetDblParameterWithUnits(std::string parName, TiXmlElement* ele,
1514 Double_t defaultVal) {
1515 if (ele ==
nullptr)
return defaultVal;
1517 string val = val_unit.first;
1518 string unit = val_unit.second;
1519 if (val == PARAMETER_NOT_FOUND_STR) {
1529TVector2 TRestMetadata::Get2DVectorParameterWithUnits(std::string parName, TiXmlElement* ele,
1530 TVector2 defaultVal) {
1531 if (ele ==
nullptr)
return defaultVal;
1533 string val = val_unit.first;
1534 string unit = val_unit.second;
1535 if (val == PARAMETER_NOT_FOUND_STR) {
1541 return TVector2(valueX, valueY);
1547TVector3 TRestMetadata::Get3DVectorParameterWithUnits(std::string parName, TiXmlElement* ele,
1548 TVector3 defaultVal) {
1549 if (ele ==
nullptr)
return defaultVal;
1551 string val = val_unit.first;
1552 string unit = val_unit.second;
1553 if (val == PARAMETER_NOT_FOUND_STR) {
1560 return TVector3(valueX, valueY, valueZ);
1575 RESTDebug <<
"Element is null" <<
RESTendl;
1576 return "Not defined";
1578 const char* val = e->Attribute(parName.c_str());
1579 if (val ==
nullptr) {
1580 return "Not defined";
1583 string result = (string)val;
1584 result =
Replace(result,
" AND ",
" && ");
1585 result =
Replace(result,
" OR ",
" || ");
1619Double_t TRestMetadata::GetDblParameterWithUnits(std::string parName, Double_t defaultVal) {
1621 string val = val_unit.first;
1622 string unit = val_unit.second;
1623 if (val == PARAMETER_NOT_FOUND_STR) {
1632TVector2 TRestMetadata::Get2DVectorParameterWithUnits(std::string parName, TVector2 defaultVal) {
1634 string val = val_unit.first;
1635 string unit = val_unit.second;
1636 if (val == PARAMETER_NOT_FOUND_STR) {
1642 return TVector2(valueX, valueY);
1647TVector3 TRestMetadata::Get3DVectorParameterWithUnits(std::string parName, TVector3 defaultVal) {
1649 string val = val_unit.first;
1650 string unit = val_unit.second;
1651 if (val == PARAMETER_NOT_FOUND_STR) {
1658 return TVector3(valueX, valueY, valueZ);
1680 TiXmlElement* rootele;
1682 string filename = configFilename;
1683 if (TRestMetadata_UpdatedConfigFile.count(filename) > 0)
1684 filename = TRestMetadata_UpdatedConfigFile[filename];
1687 RESTError <<
"Config file does not exist. The file is: " << filename <<
RESTendl;
1691 if (!doc.LoadFile(filename.c_str())) {
1692 RESTError <<
"Failed to load xml file, syntax maybe wrong. The file is: " << filename <<
RESTendl;
1696 rootele = doc.RootElement();
1697 if (rootele ==
nullptr) {
1698 RESTError <<
"The rml file \"" << configFilename <<
"\" does not contain any valid elements!"
1702 if (NameOrDeclare ==
"") {
1703 return (TiXmlElement*)rootele->Clone();
1707 while (rootele !=
nullptr) {
1708 if (rootele->Value() !=
nullptr && (
string)rootele->Value() == NameOrDeclare) {
1709 return (TiXmlElement*)rootele->Clone();
1712 if (rootele->Attribute(
"name") !=
nullptr && (
string)rootele->Attribute(
"name") == NameOrDeclare) {
1713 return (TiXmlElement*)rootele->Clone();
1716 TiXmlElement* etemp =
GetElement(NameOrDeclare, rootele);
1717 if (etemp !=
nullptr) {
1718 return (TiXmlElement*)etemp->Clone();
1723 if (etemp !=
nullptr) {
1724 return (TiXmlElement*)etemp->Clone();
1727 rootele = rootele->NextSiblingElement();
1741 return e->FirstChildElement(eleDeclare.c_str());
1748 if (e ==
nullptr)
return nullptr;
1749 return e->NextSiblingElement(e->Value());
1766 if (e ==
nullptr)
return nullptr;
1767 if (eleDeclare ==
"")
1769 TiXmlElement* ele = e->FirstChildElement();
1770 while (ele !=
nullptr) {
1771 if (ele->Attribute(
"name") !=
nullptr) {
1772 std::string nameValue = (string)ele->Attribute(
"name");
1774 if (nameValue == eleName) {
1778 ele = ele->NextSiblingElement();
1783 TiXmlElement* ele = e->FirstChildElement(eleDeclare.c_str());
1784 while (ele !=
nullptr) {
1785 if (ele->Attribute(
"name") !=
nullptr) {
1786 std::string nameValue = (string)ele->Attribute(
"name");
1788 if (nameValue == eleName) {
1792 ele = ele->NextSiblingElement(eleDeclare.c_str());
1809 RESTWarning <<
"TRestMetadata::GetUnits(): NULL element given!" <<
RESTendl;
1813 string valstr = e->Attribute(
"value") ==
nullptr ?
"" : e->Attribute(
"value");
1814 string unitattr = e->Attribute(
"units") ==
nullptr ?
"" : e->Attribute(
"units");
1817 if (
IsUnit(unitembeded)) {
1845 if (parvalue == PARAMETER_NOT_FOUND_STR) {
1846 return {parvalue,
""};
1853 if (paraele !=
nullptr) {
1863 return {parvalue,
""};
1872 TiXmlElement* ele =
new TiXmlElement(
"temp");
1874 ele->Parse(definition.c_str(),
nullptr, TIXML_ENCODING_UTF8);
1884 if (ele !=
nullptr) {
1886 TiXmlNode* n = ele->FirstChild();
1887 while (n !=
nullptr) {
1888 TiXmlComment* cmt = n->ToComment();
1889 if (cmt !=
nullptr) {
1891 n = n->NextSibling();
1892 ele->RemoveChild(nn);
1895 n = n->NextSibling();
1900 string s = ss.str();
1930 size_t Position = 0;
1932 if (result ==
"") result =
"NotFound";
1937 if (result ==
"") result =
"NotFound";
1941 size_t Position = 0;
1943 if (result ==
"") result =
"NotFound";
1953 RESTDebug <<
"Finding " << fromPosition <<
"th appearance of KEY Structure \"" << keyName <<
"\"..."
1956 TiXmlElement* childele = ele->FirstChildElement(keyName);
1957 for (
unsigned int i = 0; childele !=
nullptr && i < fromPosition; i++) {
1958 childele = childele->NextSiblingElement(keyName);
1960 if (childele !=
nullptr) {
1962 fromPosition = fromPosition + 1;
1963 RESTDebug <<
"Found Key : " << result <<
RESTendl;
1967 RESTDebug <<
"Finding hit the end, KEY Structure not found!!" <<
RESTendl;
1983 size_t Position = 0;
1991 size_t Position = 0;
1995 string key =
"<" + keyName;
1996 size_t startPos = buffer.find(key, fromPosition);
1997 if (startPos == string::npos)
return "";
1998 size_t endPos = buffer.find(
">", startPos);
1999 if (endPos == string::npos)
return "";
2001 fromPosition = endPos;
2003 Int_t notDefinitionEnd = 1;
2005 while (notDefinitionEnd) {
2013 if ((TString)def[def.length() - 1] ==
"\"" && (TString)def[def.length() - 2] ==
"=")
2014 endPos = buffer.find(
">", endPos + 1);
2016 notDefinitionEnd = 0;
2019 string result = buffer.substr(startPos, endPos - startPos + 1);
2020 if (result[result.size() - 2] !=
'/') result.insert(result.size() - 1, 1,
'/');
2032 string result = definition;
2034 if (e ==
nullptr)
return nullptr;
2036 TiXmlAttribute* attr = e->FirstAttribute();
2037 while (attr !=
nullptr) {
2038 string parName = std::string(attr->Name());
2043 attr = attr->Next();
2068 pos = inputString.find(parName, pos);
2087 RESTDebug <<
"Entering ... TRestMetadata::ReplaceVariables (" << buffer <<
")" <<
RESTendl;
2088 string outputBuffer = buffer;
2091 int startPosition = 0;
2092 int endPosition = 0;
2093 while ((startPosition = outputBuffer.find(
"${", endPosition)) != (
int)string::npos) {
2094 endPosition = outputBuffer.find(
"}", startPosition + 2);
2095 if (endPosition == (
int)string::npos)
break;
2097 string expression = outputBuffer.substr(startPosition + 2, endPosition - startPosition - 2);
2099 int replacePos = startPosition;
2100 int replaceLen = endPosition - startPosition + 1;
2102 string sysenv = getenv(expression.c_str()) !=
nullptr ? getenv(expression.c_str()) :
"";
2104 string argenv = REST_ARGS.count(expression) > 0 ? REST_ARGS[expression] :
"";
2107 outputBuffer.replace(replacePos, replaceLen, sysenv);
2109 }
else if (argenv !=
"") {
2110 outputBuffer.replace(replacePos, replaceLen, argenv);
2112 }
else if (proenv !=
"") {
2113 outputBuffer.replace(replacePos, replaceLen, proenv);
2116 RESTError << this->ClassName() <<
", replace env : cannot find \"${" << expression
2117 <<
"}\" in either system or program env, exiting..." <<
RESTendl;
2122 if (buffer != outputBuffer) RESTDebug <<
"Replaced by : " << outputBuffer <<
RESTendl;
2123 return outputBuffer;
2131 RESTDebug <<
"Entering ... TRestMetadata::ReplaceConstants (" << buffer <<
")" <<
RESTendl;
2132 string outputBuffer = buffer;
2137 int pos = outputBuffer.find(iter.first, 0);
2140 (pos + iter.first.size()) >= outputBuffer.size() ? 0 : outputBuffer[pos + iter.first.size()];
2141 char prev = pos == 0 ? 0 : outputBuffer[pos - 1];
2142 if (!isalpha(next) && !isalpha(prev)) {
2143 outputBuffer.replace(pos, iter.first.size(), iter.second);
2144 pos = outputBuffer.find(iter.first, pos + iter.second.size());
2146 pos = outputBuffer.find(iter.first, pos + iter.first.size());
2151 if (buffer != outputBuffer) RESTDebug <<
"Replaced by : " << outputBuffer <<
RESTendl;
2152 return outputBuffer;
2166 auto paths =
Split((
string)pathString,
":");
2177 time_t tt = (time_t)timeStamp;
2178 struct tm* tm = localtime(&tt);
2181 strftime(date,
sizeof(date),
"%Y-%m-%d", tm);
2182 cout <<
"Date : " << date << endl;
2185 strftime(time,
sizeof(time),
"%H:%M:%S", tm);
2186 cout <<
"Time : " << time << endl;
2187 cout <<
"++++++++++++++++++++++++" << endl;
2200 ele->Print(stdout, 0);
2204 cout <<
"N/A" << endl;
2211 FILE* f = fopen(fname.c_str(),
"at");
2216 FILE* f = fopen(fname.c_str(),
"at");
2224 RESTError <<
"Something missing here. Call the police" <<
RESTendl;
2234 RESTMetadata <<
"+++++++++++++++++++++++++++++++++++++++++++++" <<
RESTendl;
2235 RESTMetadata << this->ClassName() <<
" content" <<
RESTendl;
2237 RESTMetadata <<
"+++++++++++++++++++++++++++++++++++++++++++++" <<
RESTendl;
2238 RESTMetadata <<
"Name : " << GetName() <<
RESTendl;
2239 RESTMetadata <<
"Title : " << GetTitle() <<
RESTendl;
2241 if (fOfficialRelease)
2242 RESTMetadata <<
"REST Official release: Yes" <<
RESTendl;
2244 RESTMetadata <<
"REST Official release: No" <<
RESTendl;
2246 RESTMetadata <<
"Clean state: Yes" <<
RESTendl;
2248 RESTMetadata <<
"Clean state: No" <<
RESTendl;
2252 RESTMetadata <<
"---------------------------------------" <<
RESTendl;
2274 if (!this->InheritsFrom(
"TRestRun"))
2275 RESTError <<
"version is a static value, you cannot set version "
2287 if (!this->InheritsFrom(
"TRestRun"))
2288 RESTError <<
"version is a static value, you cannot set version "
2309 if (a != string::npos)
return fSectionName.substr(0, a);
2343 result =
Replace(result,
"{",
"");
2344 result =
Replace(result,
"}",
"");
2345 result =
Replace(result,
"(",
"");
2346 result =
Replace(result,
")",
"");
2359 TString level =
"unknown";
2396 TiXmlElement* ele =
fElement->FirstChildElement(
"searchPath");
2397 while (ele !=
nullptr) {
2398 if (ele->Attribute(
"value") !=
nullptr) {
2399 result += (string)ele->Attribute(
"value") +
":";
2401 ele = ele->NextSiblingElement(
"searchPath");
2405 if (getenv(
"configPath")) result += getenv(
"configPath") + (string)
":";
2406 result += REST_PATH +
"/data/:";
2407 result += REST_PATH +
"/examples/:";
2409 result += REST_USER_PATH +
":";
2410 if (result.back() ==
':') result.erase(result.size() - 1);
2418 return TNamed::Write(name, option, bufsize);
2461 for (
auto i : list) {
2462 ReadOneParameter(i.first, i.second);
2472 map<string, string> parameters;
2475 auto iter = REST_ARGS.begin();
2476 while (iter != REST_ARGS.end()) {
2478 parameters[iter->first] = iter->second;
2484 auto paraattr =
fElement->FirstAttribute();
2485 while (paraattr !=
nullptr) {
2486 string name = paraattr->Name();
2487 string value = paraattr->Value();
2489 if (parameters.count(name) == 0) {
2490 parameters[name] = value;
2493 paraattr = paraattr->Next();
2497 auto paraele =
fElement->FirstChildElement(
"parameter");
2498 while (paraele !=
nullptr) {
2499 string name = paraele->Attribute(
"name");
2500 string value = paraele->Attribute(
"value");
2504 TString
units = paraele->Attribute(
"units");
2507 RESTWarning <<
"bad <parameter section: " << *paraele <<
RESTendl;
2509 if (parameters.count(name) == 0) {
2510 parameters[name] = value +
units;
2514 paraele = paraele->NextSiblingElement(
"parameter");
2520void TRestMetadata::ReadOneParameter(
string name,
string value) {
2521 if (name ==
"name" || name ==
"title" || name ==
"verboseLevel" || name ==
"type" || name ==
"value" ||
2525 RESTValue thisactual(
this, this->ClassName());
2527 if (datamembername !=
"") {
2530 RESTDebug << this->ClassName() <<
"::ReadAllParameters(): parsing value \"" << value
2531 <<
"\" to data member \"" << datamembername <<
"\"" <<
RESTendl;
2538 if (datamember.
type ==
"double") {
2541 }
else if (datamember.
type ==
"TVector2") {
2545 *(TVector2*)datamember = TVector2(valueX, valueY);
2546 }
else if (datamember.
type ==
"TVector3") {
2551 *(TVector3*)datamember = TVector3(valueX, valueY, valueZ);
2553 RESTWarning << this->ClassName() <<
" find unit definition in parameter: " << name
2554 <<
", but the corresponding data member doesn't support it. Data "
2562 }
else if (datamember.
name !=
"") {
2566 RESTDebug << this->ClassName() <<
"::ReadAllParameters(): parameter \"" << name
2567 <<
"\" not recognized for automatic load" <<
RESTendl;
2568 vector<string> availableparameters;
2570 vector<string> datamembers = thisactual.GetListOfDataMembers();
2571 for (
unsigned int i = 0; i < datamembers.size(); i++) {
2573 if (parameter !=
"") {
2574 if (parameter ==
"name" || parameter ==
"title" || parameter ==
"verboseLevel" ||
2575 parameter ==
"type" || parameter ==
"value" || parameter ==
"store") {
2577 availableparameters.push_back(parameter);
2583 string hintParameter =
"";
2584 for (
auto parameter : availableparameters) {
2586 if (diff < mindiff) {
2588 hintParameter = parameter;
2594 if (hintParameter !=
"" && mindiff <= 2) {
2595 RESTWarning << this->ClassName() <<
"::ReadAllParameters(): parameter \"" << name
2596 <<
"\" not recognized for automatic load, did you mean \"" << hintParameter
2607 et.TRestMetadataPtr->AddLog(this->buf.str());
2610 if (this->iserror) {
2611 if (this->verbose == TRestStringOutput::REST_Verbose_Level::REST_Warning) {
2612 et.TRestMetadataPtr->SetWarning(this->buf.str(),
false);
2615 et.TRestMetadataPtr->SetError(this->buf.str(),
false);
2619 if (et.TRestMetadataPtr->GetVerboseLevel() >= this->verbose) {
2620 this->flushstring();
2622 this->resetstring();
2638 if (message !=
"") {
2641 cout << message << endl;
2649 if (message !=
"") {
2652 RESTWarning << message <<
RESTendl;
2668 return "No warning!";
2672 if (!metadata.InheritsFrom(ClassName())) {
2673 RESTError <<
"TRestMetadata::Merge. Metadata is not of type " << ClassName() <<
RESTendl;
2677 if (fName.IsNull()) {
2678 fName = metadata.GetName();
void ParseString(std::string str)
Set the value of the wrapped object from std::string.
std::string GetDataMemberValueString(std::string name)
Get the value of datamember as std::string.
std::string type
Type of the wrapped object.
TRestReflector GetDataMember(std::string name)
Find the class's datamember as TRestReflector object, including those from base class.
std::string name
Name field.
bool IsZombie()
If this object type wrapper is invalid.
virtual DBEntry query_data(DBEntry info)
@ 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
This namespace serves to define physics constants and other basic physical operations.
Int_t GetChar(std::string hint="Press a KEY to continue ...")
Helps to pause the program, printing a message before pausing.
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.
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.
TVector2 StringTo2DVector(std::string in)
Gets a 2D-vector from a string.
Int_t DiffString(const std::string &source, const std::string &target)
Returns the number of different characters between two strings.
std::string ParameterNameToDataMemberName(std::string name)
Convert parameter name to datamember name, following REST parameter naming convention.
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).
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::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.
This namespace defines the unit conversion for different units which are understood by REST.
std::string FindRESTUnitsInString(std::string InString)
Find and return the units definition in a string.
bool IsUnit(std::string in)
Checks if the string is a REST supported unit.
Double_t ConvertValueToRESTUnits(Double_t value, std::string unitsStr)
Convert value into REST units.
std::string RemoveUnitsFromString(std::string s)
It should remove all units found inside the input string.