461 #include "TRestMetadata.h"
463 #include <TFormula.h>
465 #include <TStreamerInfo.h>
469 #include "TRestDataBase.h"
487 map<string, string> TRestMetadata_UpdatedConfigFile;
504 RESTMetadata.setlength(100);
507 fOfficialRelease =
true;
526 RESTMetadata.setlength(100);
529 fOfficialRelease =
true;
551 RESTMetadata.setlength(100);
554 fOfficialRelease =
true;
577 const string thisSectionName = sectionName.empty() ? this->ClassName() : sectionName;
584 if (Sectional ==
nullptr) {
585 RESTError <<
"cannot find xml section \"" << ClassName() <<
"\" with name \"" << sectionName
593 TiXmlElement* Global =
GetElement(
"globals", rootEle);
595 if (Global !=
nullptr && Global->NextSiblingElement(
"globals") !=
nullptr) {
596 TiXmlElement* ele = Global->NextSiblingElement(
"globals");
598 while (ele !=
nullptr) {
599 TiXmlElement* e = ele->FirstChildElement();
600 while (e !=
nullptr) {
601 Global->InsertEndChild(*e);
602 e = e->NextSiblingElement();
604 ele = ele->NextSiblingElement(
"globals");
615 RESTError <<
"Config File does not exist. Right path/filename?" <<
RESTendl;
622 if (sectional ==
nullptr) {
623 RESTError <<
"cannot find xml section \"" << ClassName() <<
"\" with name \"" << thisSectionName
631 TiXmlElement* global =
GetElement(
"globals", rootEle);
633 if (global !=
nullptr && global->NextSiblingElement(
"globals") !=
nullptr) {
634 TiXmlElement* ele = global->NextSiblingElement(
"globals");
636 while (ele !=
nullptr) {
637 TiXmlElement* e = ele->FirstChildElement();
638 while (e !=
nullptr) {
639 global->InsertEndChild(*e);
640 e = e->NextSiblingElement();
642 ele = ele->NextSiblingElement(
"globals");
661 map<string, string> envs) {
663 TiXmlElement* theElement;
664 if (eSectional !=
nullptr && eGlobal !=
nullptr) {
666 theElement = (TiXmlElement*)eSectional->Clone();
667 TiXmlElement* echild = eGlobal->FirstChildElement();
668 while (echild !=
nullptr) {
669 theElement->LinkEndChild(echild->Clone());
670 echild = echild->NextSiblingElement();
675 }
else if (eSectional !=
nullptr) {
676 theElement = (TiXmlElement*)eSectional->Clone();
677 }
else if (eGlobal !=
nullptr) {
678 theElement = (TiXmlElement*)eGlobal->Clone();
683 fElementGlobal = eGlobal ? (TiXmlElement*)eGlobal->Clone() :
nullptr;
688 RESTDebug << ClassName() <<
" has finished preparing config data" <<
RESTendl;
736 auto paraele =
fElement->FirstChildElement();
737 while (paraele !=
nullptr) {
738 std::string xmlChild = paraele->Value();
739 if (xmlChild.find(
"TRest") == 0) {
740 if (pattern ==
"" || xmlChild.find(pattern) != string::npos) {
741 if (count == index) {
742 TClass* c = TClass::GetClass(xmlChild.c_str());
746 if (!md)
return nullptr;
749 TiXmlElement* Global =
GetElement(
"globals", rootEle);
758 paraele = paraele->NextSiblingElement();
789 auto paraele =
fElement->FirstChildElement();
790 while (paraele !=
nullptr) {
791 std::string xmlChild = paraele->Value();
792 if (xmlChild.find(
"TRest") == 0) {
793 if (pattern.empty() || xmlChild.find(pattern) != string::npos) {
794 if (name.empty() || (!name.empty() && name == (
string)paraele->Attribute(
"name"))) {
795 TClass* c = TClass::GetClass(xmlChild.c_str());
800 TiXmlElement* Global =
GetElement(
"globals", rootEle);
808 paraele = paraele->NextSiblingElement();
827 RESTDebug <<
"Loading Config for : " << this->ClassName() <<
RESTendl;
832 while (e !=
nullptr) {
835 e = e->NextSiblingElement();
840 TiXmlElement* e =
fElement->FirstChildElement();
841 while (e !=
nullptr) {
844 e = e->NextSiblingElement();
855 this->SetName(
GetParameter(
"name",
"default" +
string(this->ClassName())).c_str());
856 this->SetTitle(
GetParameter(
"title",
"Default " +
string(this->ClassName())).c_str());
871 if (e ==
nullptr)
return nullptr;
873 RESTDebug <<
"Entering ... TRestMetadata::ReplaceElementAttributes" <<
RESTendl;
875 std::string parName =
"";
876 TiXmlAttribute* attr = e->FirstAttribute();
877 while (attr !=
nullptr) {
878 const char* val = attr->Value();
879 const char* name = attr->Name();
880 RESTDebug <<
"Element name : " << name <<
" value : " << val <<
RESTendl;
882 string newVal = val !=
nullptr ? val :
"";
911 if (e ==
nullptr)
return;
913 const char* name = e->Attribute(
"name");
914 if (name ==
nullptr)
return;
915 const char* value = e->Attribute(
"value");
916 if (value ==
nullptr)
return;
918 if ((
string)e->Value() ==
"variable") {
920 const char* overwritesysenv = e->Attribute(
"overwrite");
921 if (overwritesysenv ==
nullptr) overwritesysenv =
"false";
922 if (!StringToBool(overwritesysenv)) {
923 char* sysenv = getenv(name);
924 if (sysenv !=
nullptr) value = sysenv;
926 if (!overwrite &&
fVariables.count(name) > 0)
return;
928 }
else if ((
string)e->Value() ==
"constant") {
929 if (!overwrite &&
fVariables.count(name) > 0)
return;
931 }
else if ((
string)e->Value() ==
"myParameter") {
932 RESTWarning <<
"myParameter is obsolete now! use \"constant\" instead" <<
RESTendl;
933 if (!overwrite &&
fVariables.count(name) > 0)
return;
947 RESTDebug << ClassName() <<
"::ReadElement(<" << e->Value() <<
")" <<
RESTendl;
948 if (e ==
nullptr)
return;
953 if ((
string)e->Value() ==
"for") {
955 }
else if (e->Attribute(
"file") !=
nullptr) {
957 }
else if ((
string)e->Value() ==
"if") {
959 }
else if (e->FirstChildElement() !=
nullptr) {
960 TiXmlElement* contentelement = e->FirstChildElement();
963 while (contentelement !=
nullptr) {
964 TiXmlElement* nxt = contentelement->NextSiblingElement();
965 if (recursive || ((
string)contentelement->Value()).find(
"TRest") == string::npos) {
966 RESTDebug <<
"into child element \"" << contentelement->Value() <<
"\" of \"" << e->Value()
970 RESTDebug <<
"skipping child element \"" << contentelement->Value() <<
"\" of \""
973 contentelement = nxt;
1004 if (e ==
nullptr)
return;
1005 if ((
string)e->Value() !=
"if")
return;
1007 const char* evaluate = e->Attribute(
"evaluate");
1008 const char* condition = e->Attribute(
"condition");
1010 if (condition ==
nullptr ||
string(condition).find_first_of(
"=!<>") == string::npos) {
1011 RESTWarning <<
"Invalid \"IF\" structure!" <<
RESTendl;
1015 int p1 = string(condition).find_first_of(
"=!<>");
1016 int p2 = string(condition).find_first_not_of(
"=!<>", p1);
1019 bool matches =
false;
1020 if (evaluate !=
nullptr) {
1022 }
else if (p1 > 0) {
1023 v1 = string(condition).substr(0, p1);
1025 RESTWarning <<
"Invalid \"IF\" structure!" <<
RESTendl;
1029 string con = string(condition).substr(p1, p2 - p1);
1030 string v2 = string(condition).substr(p2, -1);
1034 if (atof(v1.c_str()) == atof(v2.c_str())) matches =
true;
1036 if (v1 == v2) matches =
true;
1038 }
else if (con ==
"!=") {
1040 if (atof(v1.c_str()) != atof(v2.c_str())) matches =
true;
1042 if (v1 != v2) matches =
true;
1044 }
else if (con ==
">") {
1046 if (atof(v1.c_str()) > atof(v2.c_str())) matches =
true;
1048 if (v1 > v2) matches =
true;
1050 }
else if (con ==
"<") {
1052 if (atof(v1.c_str()) < atof(v2.c_str())) matches =
true;
1054 if (v1 < v2) matches =
true;
1056 }
else if (con ==
">=") {
1058 if (atof(v1.c_str()) >= atof(v2.c_str())) matches =
true;
1060 if (v1 >= v2) matches =
true;
1062 }
else if (con ==
"<=") {
1064 if (atof(v1.c_str()) <= atof(v2.c_str())) matches =
true;
1066 if (v1 <= v2) matches =
true;
1069 RESTWarning <<
"Invalid \"IF\" structure!" <<
RESTendl;
1074 TiXmlElement* parele = (TiXmlElement*)e->Parent();
1075 if (parele ==
nullptr)
return;
1076 TiXmlElement* contentelement = e->FirstChildElement();
1077 while (contentelement !=
nullptr) {
1078 TiXmlElement* attachedelement = (TiXmlElement*)contentelement->Clone();
1081 parele->InsertBeforeChild(e, *attachedelement);
1082 delete attachedelement;
1083 contentelement = contentelement->NextSiblingElement();
1095 TiXmlElement* parele = (TiXmlElement*)e->Parent();
1096 TiXmlElement* contentelement = e->FirstChildElement();
1097 while (contentelement !=
nullptr) {
1098 if ((
string)contentelement->Value() ==
"for") {
1099 TiXmlElement* newforloop = (TiXmlElement*)contentelement->Clone();
1101 TiXmlElement* tempnew = (TiXmlElement*)parele->InsertBeforeChild(e, *newforloop);
1103 newforloop = tempnew;
1105 contentelement = contentelement->NextSiblingElement();
1107 TiXmlElement* attachedelement = (TiXmlElement*)contentelement->Clone();
1111 parele->InsertBeforeChild(e, *attachedelement);
1112 delete attachedelement;
1113 contentelement = contentelement->NextSiblingElement();
1122 if (e ==
nullptr)
return;
1124 RESTDebug <<
"Entering ... TRestMetadata::ReplaceForLoopVars" <<
RESTendl;
1125 std::string parName;
1126 TiXmlAttribute* attr = e->FirstAttribute();
1127 while (attr !=
nullptr) {
1128 const char* val = attr->Value();
1129 const char* name = attr->Name();
1130 RESTDebug <<
"Attribute name : " << name <<
" value : " << val <<
RESTendl;
1132 if (strcmp(name,
"name") == 0) parName = (string)val;
1135 if (strcmp(name,
"name") != 0) {
1136 string outputBuffer = val;
1138 if (outputBuffer.find(
'[') != string::npos || outputBuffer.find(
']') != string::npos) {
1139 RESTError <<
"TRestMetadata::ReplaceForLoopVars. Old for-loop construction identified"
1141 RESTError <<
"Please, replace [] variable nomenclature by ${}." <<
RESTendl;
1146 int startPosition = 0;
1147 int endPosition = 0;
1148 while ((startPosition = outputBuffer.find(
"{", endPosition)) != (
int)string::npos) {
1149 endPosition = outputBuffer.find(
"}", startPosition + 1);
1150 if (endPosition == (
int)string::npos)
break;
1151 if (startPosition >= 1 && outputBuffer[startPosition - 1] ==
'$')
1154 string expression = outputBuffer.substr(startPosition + 1, endPosition - startPosition - 1);
1156 int replacePos = startPosition;
1157 int replaceLen = endPosition - startPosition + 1;
1159 string proenv = forLoopVar.count(expression) > 0 ? forLoopVar[expression] :
"";
1161 if (!proenv.empty()) {
1162 outputBuffer.replace(replacePos, replaceLen, proenv);
1165 RESTError << this->ClassName() <<
", replace for loop env : cannot find \"{" << expression
1173 "Please, check parameter name: " + parName +
" (ReplaceForLoopVars)")
1177 attr = attr->Next();
1189 if (e ==
nullptr)
return;
1190 if ((
string)e->Value() !=
"for")
return;
1191 RESTDebug <<
"Entering ... ExpandForLoops" <<
RESTendl;
1194 TString varname = TString(e->Attribute(
"variable"));
1195 TString varfrom = TString(e->Attribute(
"from"));
1196 TString varto = TString(e->Attribute(
"to"));
1197 TString varstep = TString(e->Attribute(
"step"));
1198 TString varin = TString(e->Attribute(
"in"));
1200 RESTDebug <<
"variable: " << varname <<
" from: " << varfrom <<
" to: " << varto <<
" step: " << varstep
1203 if ((varin ==
"") && (varname ==
"" || varfrom ==
"" || varto ==
""))
return;
1204 if (varstep ==
"") varstep =
"1";
1205 TiXmlElement* parele = (TiXmlElement*)e->Parent();
1206 if (parele ==
nullptr)
return;
1208 string _name = (string)varname;
1209 string _from = (string)varfrom;
1210 string _to = (string)varto;
1211 string _step = (string)varstep;
1212 string _in = (string)varin;
1213 RESTDebug <<
"_from: " << _from <<
" _to: " << _to <<
" _step: " << _step <<
RESTendl;
1219 RESTDebug <<
"----expanding for loop----" <<
RESTendl;
1221 for (i = from; i <= to; i = i + step) {
1222 forloopvar[_name] = ToString(i);
1226 parele->RemoveChild(e);
1229 RESTDebug <<
"----end of for loop----" <<
RESTendl;
1230 }
else if (!_in.empty()) {
1231 vector<string> loopvars =
Split(_in,
":");
1233 RESTDebug <<
"----expanding for loop----" <<
RESTendl;
1234 for (
const string& loopvar : loopvars) {
1235 forloopvar[_name] = loopvar;
1239 parele->RemoveChild(e);
1242 RESTDebug <<
"----end of for loop----" <<
RESTendl;
1269 RESTDebug <<
"Entering ... " << __PRETTY_FUNCTION__ <<
RESTendl;
1270 if (e ==
nullptr)
return;
1273 const char* _filename = e->Attribute(
"file");
1274 if (_filename ==
nullptr)
return;
1281 auto url = gDataBase->
query_data(DBEntry(0,
"META_RML", e->Value())).value;
1292 if (filename.empty()) {
1293 RESTError <<
"TRestMetadata::ExpandIncludeFile. Include file \"" << _filename <<
"\" does not exist!"
1300 RESTDebug <<
"----expanding include file----" <<
RESTendl;
1303 TiXmlElement* remoteele =
nullptr;
1304 TiXmlElement* localele =
nullptr;
1316 if ((
string)e->Value() ==
"include") {
1317 localele = (TiXmlElement*)e->Parent();
1318 if (localele ==
nullptr)
return;
1319 if (localele->Attribute(
"expanded") ==
nullptr
1321 : ((string)localele->Attribute(
"expanded") ==
"true")) {
1322 RESTDebug <<
"----already expanded----" <<
RESTendl;
1326 remoteele =
new TiXmlElement(
"Config");
1329 if (ele ==
nullptr) {
1330 RESTError <<
"TRestMetadata::ExpandIncludeFile. No xml elements contained in the include "
1335 while (ele !=
nullptr) {
1336 remoteele->InsertEndChild(*ele);
1337 ele = ele->NextSiblingElement();
1357 if (localele->Attribute(
"expanded") ==
nullptr
1359 : ((
string)localele->Attribute(
"expanded") ==
"true")) {
1360 RESTDebug <<
"----already expanded----" <<
RESTendl;
1364 type = e->Attribute(
"type") !=
nullptr ? e->Attribute(
"type") : e->Value();
1365 name = localele->Attribute(
"name") ==
nullptr ?
"" : localele->Attribute(
"name");
1369 if (rootele ==
nullptr) {
1370 RESTError <<
"TRestMetaddata::ExpandIncludeFile. Include file " << filename
1371 <<
" is of wrong xml format!" <<
RESTendl;
1375 if ((
string)rootele->Value() == type) {
1378 remoteele = rootele;
1381 if (type !=
"globals" &&
GetElement(
"globals", rootele) !=
nullptr) {
1382 TiXmlElement* globaldef =
GetElement(
"globals", rootele)->FirstChildElement();
1383 while (globaldef !=
nullptr) {
1385 globaldef = globaldef->NextSiblingElement();
1392 vector<TiXmlElement*> eles;
1393 TiXmlElement* ele = rootele->FirstChildElement();
1394 while (ele !=
nullptr) {
1395 if (ele->Attribute(
"name") !=
nullptr && (
string)ele->Attribute(
"name") == name) {
1396 eles.push_back(ele);
1398 ele = ele->NextSiblingElement();
1401 if (eles.size() > 1) {
1402 RESTWarning <<
"(expand include file): find multiple xml sections with same name!"
1404 RESTWarning <<
"Using the first one!" <<
RESTendl;
1407 if (eles.size() > 0) remoteele = (TiXmlElement*)eles[0]->Clone();
1408 }
else if (type !=
"") {
1409 remoteele = (TiXmlElement*)
GetElement(type, rootele)->Clone();
1412 if (remoteele ==
nullptr) {
1413 RESTWarning <<
"Cannot find the needed xml section in "
1416 RESTWarning <<
"type: \"" << type <<
"\" , name: \"" << name <<
"\" . Skipping"
1425 RESTDebug <<
"Target xml element spotted" <<
RESTendl;
1432 TiXmlAttribute* attr = remoteele->FirstAttribute();
1433 while (attr !=
nullptr) {
1434 if (localele->Attribute(attr->Name()) ==
nullptr) {
1435 localele->SetAttribute(attr->Name(), attr->Value());
1438 attr = attr->Next();
1440 TiXmlElement* ele = remoteele->FirstChildElement();
1441 while (ele !=
nullptr) {
1443 if ((
string)ele->Value() !=
"for") {
1444 localele->InsertEndChild(*ele);
1447 ele = ele->NextSiblingElement();
1450 localele->SetAttribute(
"expanded",
"true");
1452 localele->Print(stdout, 0);
1456 RESTDebug << nattr <<
" attributes and " << nele <<
" xml elements added by inclusion" <<
RESTendl;
1457 RESTDebug <<
"----end of expansion file----" <<
RESTendl;
1474 if (REST_ARGS.count(parName) != 0) {
1475 return REST_ARGS[parName];
1480 if (result != PARAMETER_NOT_FOUND_STR) {
1484 return (
string)defaultValue;
1513 RESTDebug <<
"Element is null" <<
RESTendl;
1514 return (
string)defaultValue;
1516 string result = (string)defaultValue;
1518 if (e->Attribute(parName.c_str()) !=
nullptr) {
1519 result = e->Attribute(parName.c_str());
1524 if (element !=
nullptr && element->Attribute(
"value") !=
nullptr) {
1525 result = element->Attribute(
"value");
1527 RESTDebug << ClassName() <<
": Parameter : " << parName <<
" not found!" <<
RESTendl;
1532 "Please, check parameter name: " + parName);
1535 Double_t TRestMetadata::GetDblParameterWithUnits(std::string parName, TiXmlElement* ele,
1536 Double_t defaultVal) {
1537 if (ele ==
nullptr)
return defaultVal;
1539 string val = val_unit.first;
1540 string unit = val_unit.second;
1541 if (val == PARAMETER_NOT_FOUND_STR) {
1551 TVector2 TRestMetadata::Get2DVectorParameterWithUnits(std::string parName, TiXmlElement* ele,
1552 TVector2 defaultVal) {
1553 if (ele ==
nullptr)
return defaultVal;
1555 string val = val_unit.first;
1556 string unit = val_unit.second;
1557 if (val == PARAMETER_NOT_FOUND_STR) {
1563 return TVector2(valueX, valueY);
1569 TVector3 TRestMetadata::Get3DVectorParameterWithUnits(std::string parName, TiXmlElement* ele,
1570 TVector3 defaultVal) {
1571 if (ele ==
nullptr)
return defaultVal;
1573 string val = val_unit.first;
1574 string unit = val_unit.second;
1575 if (val == PARAMETER_NOT_FOUND_STR) {
1582 return TVector3(valueX, valueY, valueZ);
1597 RESTDebug <<
"Element is null" <<
RESTendl;
1598 return "Not defined";
1600 const char* val = e->Attribute(parName.c_str());
1601 if (val ==
nullptr) {
1602 return "Not defined";
1605 string result = (string)val;
1606 result =
Replace(result,
" AND ",
" && ");
1607 result =
Replace(result,
" OR ",
" || ");
1641 Double_t TRestMetadata::GetDblParameterWithUnits(std::string parName, Double_t defaultVal) {
1643 string val = val_unit.first;
1644 string unit = val_unit.second;
1645 if (val == PARAMETER_NOT_FOUND_STR) {
1654 TVector2 TRestMetadata::Get2DVectorParameterWithUnits(std::string parName, TVector2 defaultVal) {
1656 string val = val_unit.first;
1657 string unit = val_unit.second;
1658 if (val == PARAMETER_NOT_FOUND_STR) {
1664 return TVector2(valueX, valueY);
1669 TVector3 TRestMetadata::Get3DVectorParameterWithUnits(std::string parName, TVector3 defaultVal) {
1671 string val = val_unit.first;
1672 string unit = val_unit.second;
1673 if (val == PARAMETER_NOT_FOUND_STR) {
1680 return TVector3(valueX, valueY, valueZ);
1702 TiXmlElement* rootele;
1704 string filename = configFilename;
1705 if (TRestMetadata_UpdatedConfigFile.count(filename) > 0)
1706 filename = TRestMetadata_UpdatedConfigFile[filename];
1709 RESTError <<
"Config file does not exist. The file is: " << filename <<
RESTendl;
1713 if (!doc.LoadFile(filename.c_str())) {
1714 RESTError <<
"Failed to load xml file, syntax maybe wrong. The file is: " << filename <<
RESTendl;
1718 rootele = doc.RootElement();
1719 if (rootele ==
nullptr) {
1720 RESTError <<
"The rml file \"" << configFilename <<
"\" does not contain any valid elements!"
1724 if (NameOrDeclare ==
"") {
1725 return (TiXmlElement*)rootele->Clone();
1729 while (rootele !=
nullptr) {
1730 if (rootele->Value() !=
nullptr && (
string)rootele->Value() == NameOrDeclare) {
1731 return (TiXmlElement*)rootele->Clone();
1734 if (rootele->Attribute(
"name") !=
nullptr && (
string)rootele->Attribute(
"name") == NameOrDeclare) {
1735 return (TiXmlElement*)rootele->Clone();
1738 TiXmlElement* etemp =
GetElement(NameOrDeclare, rootele);
1739 if (etemp !=
nullptr) {
1740 return (TiXmlElement*)etemp->Clone();
1745 if (etemp !=
nullptr) {
1746 return (TiXmlElement*)etemp->Clone();
1749 rootele = rootele->NextSiblingElement();
1763 return e->FirstChildElement(eleDeclare.c_str());
1770 if (e ==
nullptr)
return nullptr;
1771 return e->NextSiblingElement(e->Value());
1788 if (e ==
nullptr)
return nullptr;
1789 if (eleDeclare ==
"")
1791 TiXmlElement* ele = e->FirstChildElement();
1792 while (ele !=
nullptr) {
1793 if (ele->Attribute(
"name") !=
nullptr) {
1794 std::string nameValue = (string)ele->Attribute(
"name");
1796 if (nameValue == eleName) {
1800 ele = ele->NextSiblingElement();
1805 TiXmlElement* ele = e->FirstChildElement(eleDeclare.c_str());
1806 while (ele !=
nullptr) {
1807 if (ele->Attribute(
"name") !=
nullptr) {
1808 std::string nameValue = (string)ele->Attribute(
"name");
1810 if (nameValue == eleName) {
1814 ele = ele->NextSiblingElement(eleDeclare.c_str());
1831 RESTWarning <<
"TRestMetadata::GetUnits(): NULL element given!" <<
RESTendl;
1835 string valstr = e->Attribute(
"value") ==
nullptr ?
"" : e->Attribute(
"value");
1836 string unitattr = e->Attribute(
"units") ==
nullptr ?
"" : e->Attribute(
"units");
1839 if (
IsUnit(unitembeded)) {
1867 if (parvalue == PARAMETER_NOT_FOUND_STR) {
1868 return {parvalue,
""};
1875 if (paraele !=
nullptr) {
1885 return {parvalue,
""};
1894 TiXmlElement* ele =
new TiXmlElement(
"temp");
1896 ele->Parse(definition.c_str(),
nullptr, TIXML_ENCODING_UTF8);
1906 if (ele !=
nullptr) {
1908 TiXmlNode* n = ele->FirstChild();
1909 while (n !=
nullptr) {
1910 TiXmlComment* cmt = n->ToComment();
1911 if (cmt !=
nullptr) {
1913 n = n->NextSibling();
1914 ele->RemoveChild(nn);
1917 n = n->NextSibling();
1922 string s = ss.str();
1952 size_t Position = 0;
1954 if (result ==
"") result =
"NotFound";
1959 if (result ==
"") result =
"NotFound";
1963 size_t Position = 0;
1965 if (result ==
"") result =
"NotFound";
1975 RESTDebug <<
"Finding " << fromPosition <<
"th appearance of KEY Structure \"" << keyName <<
"\"..."
1978 TiXmlElement* childele = ele->FirstChildElement(keyName);
1979 for (
unsigned int i = 0; childele !=
nullptr && i < fromPosition; i++) {
1980 childele = childele->NextSiblingElement(keyName);
1982 if (childele !=
nullptr) {
1984 fromPosition = fromPosition + 1;
1985 RESTDebug <<
"Found Key : " << result <<
RESTendl;
1989 RESTDebug <<
"Finding hit the end, KEY Structure not found!!" <<
RESTendl;
2005 size_t Position = 0;
2013 size_t Position = 0;
2017 string key =
"<" + keyName;
2018 size_t startPos = buffer.find(key, fromPosition);
2019 if (startPos == string::npos)
return "";
2020 size_t endPos = buffer.find(
">", startPos);
2021 if (endPos == string::npos)
return "";
2023 fromPosition = endPos;
2025 Int_t notDefinitionEnd = 1;
2027 while (notDefinitionEnd) {
2035 if ((TString)def[def.length() - 1] ==
"\"" && (TString)def[def.length() - 2] ==
"=")
2036 endPos = buffer.find(
">", endPos + 1);
2038 notDefinitionEnd = 0;
2041 string result = buffer.substr(startPos, endPos - startPos + 1);
2042 if (result[result.size() - 2] !=
'/') result.insert(result.size() - 1, 1,
'/');
2054 string result = definition;
2056 if (e ==
nullptr)
return nullptr;
2058 TiXmlAttribute* attr = e->FirstAttribute();
2059 while (attr !=
nullptr) {
2060 string parName = std::string(attr->Name());
2065 attr = attr->Next();
2090 pos = inputString.find(parName, pos);
2109 RESTDebug <<
"Entering ... TRestMetadata::ReplaceVariables (" << buffer <<
")" <<
RESTendl;
2110 string outputBuffer = buffer;
2113 int startPosition = 0;
2114 int endPosition = 0;
2115 while ((startPosition = outputBuffer.find(
"${", endPosition)) != (
int)string::npos) {
2116 endPosition = outputBuffer.find(
"}", startPosition + 2);
2117 if (endPosition == (
int)string::npos)
break;
2119 string expression = outputBuffer.substr(startPosition + 2, endPosition - startPosition - 2);
2121 int replacePos = startPosition;
2122 int replaceLen = endPosition - startPosition + 1;
2124 string sysenv = getenv(expression.c_str()) !=
nullptr ? getenv(expression.c_str()) :
"";
2126 string argenv = REST_ARGS.count(expression) > 0 ? REST_ARGS[expression] :
"";
2129 outputBuffer.replace(replacePos, replaceLen, sysenv);
2131 }
else if (argenv !=
"") {
2132 outputBuffer.replace(replacePos, replaceLen, argenv);
2134 }
else if (proenv !=
"") {
2135 outputBuffer.replace(replacePos, replaceLen, proenv);
2138 RESTError << this->ClassName() <<
", replace env : cannot find \"${" << expression
2139 <<
"}\" in either system or program env, exiting..." <<
RESTendl;
2144 if (buffer != outputBuffer) RESTDebug <<
"Replaced by : " << outputBuffer <<
RESTendl;
2145 return outputBuffer;
2153 RESTDebug <<
"Entering ... TRestMetadata::ReplaceConstants (" << buffer <<
")" <<
RESTendl;
2154 string outputBuffer = buffer;
2159 int pos = outputBuffer.find(iter.first, 0);
2162 (pos + iter.first.size()) >= outputBuffer.size() ? 0 : outputBuffer[pos + iter.first.size()];
2163 char prev = pos == 0 ? 0 : outputBuffer[pos - 1];
2164 if (!isalpha(next) && !isalpha(prev)) {
2165 outputBuffer.replace(pos, iter.first.size(), iter.second);
2166 pos = outputBuffer.find(iter.first, pos + iter.second.size());
2168 pos = outputBuffer.find(iter.first, pos + iter.first.size());
2173 if (buffer != outputBuffer) RESTDebug <<
"Replaced by : " << outputBuffer <<
RESTendl;
2174 return outputBuffer;
2188 auto paths =
Split((
string)pathString,
":");
2199 time_t tt = (time_t)timeStamp;
2200 struct tm* tm = localtime(&tt);
2203 strftime(date,
sizeof(date),
"%Y-%m-%d", tm);
2204 cout <<
"Date : " << date << endl;
2207 strftime(time,
sizeof(time),
"%H:%M:%S", tm);
2208 cout <<
"Time : " << time << endl;
2209 cout <<
"++++++++++++++++++++++++" << endl;
2222 ele->Print(stdout, 0);
2226 cout <<
"N/A" << endl;
2233 FILE* f = fopen(fname.c_str(),
"at");
2238 FILE* f = fopen(fname.c_str(),
"at");
2246 RESTError <<
"Something missing here. Call the police" <<
RESTendl;
2256 RESTMetadata <<
"+++++++++++++++++++++++++++++++++++++++++++++" <<
RESTendl;
2257 RESTMetadata << this->ClassName() <<
" content" <<
RESTendl;
2259 RESTMetadata <<
"+++++++++++++++++++++++++++++++++++++++++++++" <<
RESTendl;
2260 RESTMetadata <<
"Name : " << GetName() <<
RESTendl;
2261 RESTMetadata <<
"Title : " << GetTitle() <<
RESTendl;
2263 if (fOfficialRelease)
2264 RESTMetadata <<
"REST Official release: Yes" <<
RESTendl;
2266 RESTMetadata <<
"REST Official release: No" <<
RESTendl;
2268 RESTMetadata <<
"Clean state: Yes" <<
RESTendl;
2270 RESTMetadata <<
"Clean state: No" <<
RESTendl;
2274 RESTMetadata <<
"---------------------------------------" <<
RESTendl;
2296 if (!this->InheritsFrom(
"TRestRun"))
2297 RESTError <<
"version is a static value, you cannot set version "
2309 if (!this->InheritsFrom(
"TRestRun"))
2310 RESTError <<
"version is a static value, you cannot set version "
2331 if (a != string::npos)
return fSectionName.substr(0, a);
2365 result =
Replace(result,
"{",
"");
2366 result =
Replace(result,
"}",
"");
2367 result =
Replace(result,
"(",
"");
2368 result =
Replace(result,
")",
"");
2381 TString level =
"unknown";
2418 TiXmlElement* ele =
fElement->FirstChildElement(
"searchPath");
2419 while (ele !=
nullptr) {
2420 if (ele->Attribute(
"value") !=
nullptr) {
2421 result += (string)ele->Attribute(
"value") +
":";
2423 ele = ele->NextSiblingElement(
"searchPath");
2427 if (getenv(
"configPath")) result += getenv(
"configPath") + (string)
":";
2428 result += REST_PATH +
"/data/:";
2429 result += REST_PATH +
"/examples/:";
2431 result += REST_USER_PATH +
":";
2432 if (result.back() ==
':') result.erase(result.size() - 1);
2440 return TNamed::Write(name, option, bufsize);
2483 for (
auto i : list) {
2484 ReadOneParameter(i.first, i.second);
2494 map<string, string> parameters;
2497 auto iter = REST_ARGS.begin();
2498 while (iter != REST_ARGS.end()) {
2500 parameters[iter->first] = iter->second;
2506 auto paraattr =
fElement->FirstAttribute();
2507 while (paraattr !=
nullptr) {
2508 string name = paraattr->Name();
2509 string value = paraattr->Value();
2511 if (parameters.count(name) == 0) {
2512 parameters[name] = value;
2515 paraattr = paraattr->Next();
2519 auto paraele =
fElement->FirstChildElement(
"parameter");
2520 while (paraele !=
nullptr) {
2521 string name = paraele->Attribute(
"name");
2522 string value = paraele->Attribute(
"value");
2526 TString
units = paraele->Attribute(
"units");
2529 RESTWarning <<
"bad <parameter section: " << *paraele <<
RESTendl;
2531 if (parameters.count(name) == 0) {
2532 parameters[name] = value +
units;
2536 paraele = paraele->NextSiblingElement(
"parameter");
2542 void TRestMetadata::ReadOneParameter(
string name,
string value) {
2543 if (name ==
"name" || name ==
"title" || name ==
"verboseLevel" || name ==
"type" || name ==
"value" ||
2547 RESTValue thisactual(
this, this->ClassName());
2549 if (datamembername !=
"") {
2552 RESTDebug << this->ClassName() <<
"::ReadAllParameters(): parsing value \"" << value
2553 <<
"\" to data member \"" << datamembername <<
"\"" <<
RESTendl;
2560 if (datamember.
type ==
"double") {
2563 }
else if (datamember.
type ==
"TVector2") {
2567 *(TVector2*)datamember = TVector2(valueX, valueY);
2568 }
else if (datamember.
type ==
"TVector3") {
2573 *(TVector3*)datamember = TVector3(valueX, valueY, valueZ);
2574 }
else if (datamember.
type ==
"string") {
2577 RESTWarning << this->ClassName() <<
" find unit definition in parameter: " << name
2578 <<
", but the corresponding data member doesn't support it. Data "
2586 }
else if (datamember.
name !=
"") {
2590 RESTDebug << this->ClassName() <<
"::ReadAllParameters(): parameter \"" << name
2591 <<
"\" not recognized for automatic load" <<
RESTendl;
2592 vector<string> availableparameters;
2594 vector<string> datamembers = thisactual.GetListOfDataMembers();
2595 for (
unsigned int i = 0; i < datamembers.size(); i++) {
2597 if (parameter !=
"") {
2598 if (parameter ==
"name" || parameter ==
"title" || parameter ==
"verboseLevel" ||
2599 parameter ==
"type" || parameter ==
"value" || parameter ==
"store") {
2601 availableparameters.push_back(parameter);
2607 string hintParameter =
"";
2608 for (
auto parameter : availableparameters) {
2610 if (diff < mindiff) {
2612 hintParameter = parameter;
2618 if (hintParameter !=
"" && mindiff <= 2) {
2619 RESTWarning << this->ClassName() <<
"::ReadAllParameters(): parameter \"" << name
2620 <<
"\" not recognized for automatic load, did you mean \"" << hintParameter
2631 et.TRestMetadataPtr->AddLog(this->buf.str());
2634 if (this->iserror) {
2635 if (this->verbose == TRestStringOutput::REST_Verbose_Level::REST_Warning) {
2636 et.TRestMetadataPtr->SetWarning(this->buf.str(),
false);
2639 et.TRestMetadataPtr->SetError(this->buf.str(),
false);
2643 if (et.TRestMetadataPtr->GetVerboseLevel() >= this->verbose) {
2644 this->flushstring();
2646 this->resetstring();
2662 if (message !=
"") {
2664 if (print &&
fNErrors < maxPrint) {
2665 cout << message << endl;
2673 if (message !=
"") {
2676 RESTWarning << message <<
RESTendl;
2692 return "No warning!";
2696 if (!metadata.InheritsFrom(ClassName())) {
2697 RESTError <<
"TRestMetadata::Merge. Metadata is not of type " << ClassName() <<
RESTendl;
2701 if (fName.IsNull()) {
2702 fName = metadata.GetName();
2706 UInt_t TRestMetadata::GetVersionMajor()
const {
2708 return major.Atoi();
2711 UInt_t TRestMetadata::GetVersionMinor()
const {
2713 return minor.Atoi();
2716 UInt_t TRestMetadata::GetVersionPatch()
const {
2718 return patch.Atoi();
std::string GetDataMemberValueString(const std::string &name)
Get the value of datamember as std::string.
std::string type
Type of the wrapped object.
bool IsZombie() const
If this object type wrapper is invalid.
std::string name
Name field.
TRestReflector GetDataMember(const std::string &name)
Find the class's datamember as TRestReflector object, including those from base class.
void ParseString(const std::string &str) const
Set the value of the wrapped object from std::string.
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 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.
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.