REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestMetadata.cxx
1/*************************************************************************
2 * This file is part of the REST software framework. *
3 * *
4 * Copyright (C) 2016 GIFNA/TREX (University of Zaragoza) *
5 * For more information see http://gifna.unizar.es/trex *
6 * *
7 * REST is free software: you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation, either version 3 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * REST is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have a copy of the GNU General Public License along with *
18 * REST in $REST_PATH/LICENSE. *
19 * If not, see http://www.gnu.org/licenses/. *
20 * For the list of contributors see $REST_PATH/CREDITS. *
21 *************************************************************************/
22
460
461#include "TRestMetadata.h"
462
463#include <TFormula.h>
464#include <TMath.h>
465#include <TStreamerInfo.h>
466
467#include <iomanip>
468
469#include "TRestDataBase.h"
470
471// implementation of version methods in namespace rest_version
472/*
473namespace REST_VersionGlob {
474 inline TString GetRESTVersion() const { return REST_RELEASE; }
475 inline int GetRESTVersionCode() const { return ConvertVersionCode(REST_RELEASE); }
476}
477*/
478using namespace std;
479using namespace REST_Units;
480using namespace REST_Physics;
481
482// We introduce the gases file here.
483// But, should we have a corner somewhere to define hard-coded globals?
484// nkx, 20200228: We now define the global data servers in database file
485// const char* gasesFile = "https://sultan.unizar.es/gasFiles/gases.rml";
486
487map<string, string> TRestMetadata_UpdatedConfigFile;
488
489ClassImp(TRestMetadata);
494 fStore = true;
495 fElementGlobal = nullptr;
496 fElement = nullptr;
497 fVerboseLevel = gVerbose;
498 fVariables.clear();
499 fConstants.clear();
500 fHostmgr = nullptr;
501
502 fConfigFileName = "null";
503 configBuffer = "";
504 RESTMetadata.setlength(100);
505
506#ifdef WIN32
507 fOfficialRelease = true;
508 fCleanState = true;
509#else
510 if (TRestTools::Execute("rest-config --release") == "Yes") fOfficialRelease = true;
511 if (TRestTools::Execute("rest-config --clean") == "Yes") fCleanState = true;
512#endif
513}
514
518TRestMetadata::TRestMetadata(const char* configFilename) : RESTendl(this) {
519 fStore = true;
520 fElementGlobal = nullptr;
521 fElement = nullptr;
522 fVerboseLevel = gVerbose;
523 fVariables.clear();
524 fConstants.clear();
525 fHostmgr = nullptr;
526
527 fConfigFileName = configFilename;
528 configBuffer = "";
529 RESTMetadata.setlength(100);
530
531#ifdef WIN32
532 fOfficialRelease = true;
533 fCleanState = true;
534#else
535 if (TRestTools::Execute("rest-config --release") == "Yes") fOfficialRelease = true;
536 if (TRestTools::Execute("rest-config --clean") == "Yes") fCleanState = true;
537#endif
538}
539
544 delete fElementGlobal;
545 delete fElement;
546}
547
552Int_t TRestMetadata::LoadConfigFromFile(const string& configFilename, const string& sectionName) {
553 fConfigFileName = configFilename;
554
555 const string thisSectionName = sectionName.empty() ? this->ClassName() : sectionName;
556
558
560 // find the xml section corresponding to the sectionName
561 TiXmlElement* Sectional = GetElementFromFile(fConfigFileName, thisSectionName);
562 if (Sectional == nullptr) {
563 RESTError << "cannot find xml section \"" << ClassName() << "\" with name \"" << sectionName
564 << "\"" << RESTendl;
565 RESTError << "in config file: " << fConfigFileName << RESTendl;
566 exit(1);
567 }
568
569 // find the "globals" section. Multiple sections are supported.
570 TiXmlElement* rootEle = GetElementFromFile(fConfigFileName);
571 TiXmlElement* Global = GetElement("globals", rootEle);
572 if (Global != nullptr) ReadElement(Global);
573 if (Global != nullptr && Global->NextSiblingElement("globals") != nullptr) {
574 TiXmlElement* ele = Global->NextSiblingElement("globals");
575 if (ele != nullptr) ReadElement(ele);
576 while (ele != nullptr) {
577 TiXmlElement* e = ele->FirstChildElement();
578 while (e != nullptr) {
579 Global->InsertEndChild(*e);
580 e = e->NextSiblingElement();
581 }
582 ele = ele->NextSiblingElement("globals");
583 }
584 }
585
586 // call the real loading method
587 int result = LoadConfigFromElement(Sectional, Global, {});
588 delete Sectional;
589 delete rootEle;
590 return result;
591 } else {
592 RESTError << "Filename: " << fConfigFileName << RESTendl;
593 RESTError << "Config File does not exist. Right path/filename?" << RESTendl;
594 GetChar();
595 return -1;
596 }
597
598 // find the xml section corresponding to the sectionName
599 TiXmlElement* sectional = GetElementFromFile(fConfigFileName, thisSectionName);
600 if (sectional == nullptr) {
601 RESTError << "cannot find xml section \"" << ClassName() << "\" with name \"" << thisSectionName
602 << "\"" << RESTendl;
603 RESTError << "in config file: " << fConfigFileName << RESTendl;
604 exit(1);
605 }
606
607 // find the "globals" section. Multiple sections are supported.
608 TiXmlElement* rootEle = GetElementFromFile(fConfigFileName);
609 TiXmlElement* global = GetElement("globals", rootEle);
610 if (global != nullptr) ReadElement(global);
611 if (global != nullptr && global->NextSiblingElement("globals") != nullptr) {
612 TiXmlElement* ele = global->NextSiblingElement("globals");
613 if (ele != nullptr) ReadElement(ele);
614 while (ele != nullptr) {
615 TiXmlElement* e = ele->FirstChildElement();
616 while (e != nullptr) {
617 global->InsertEndChild(*e);
618 e = e->NextSiblingElement();
619 }
620 ele = ele->NextSiblingElement("globals");
621 }
622 }
623
624 // call the real loading method
625 int result = LoadConfigFromElement(sectional, global, {});
626 delete sectional;
627 delete rootEle;
628 return result;
629}
630
638Int_t TRestMetadata::LoadConfigFromElement(TiXmlElement* eSectional, TiXmlElement* eGlobal,
639 map<string, string> envs) {
640 Initialize();
641 TiXmlElement* theElement;
642 if (eSectional != nullptr && eGlobal != nullptr) {
643 // Sectional and global elements are first combined.
644 theElement = (TiXmlElement*)eSectional->Clone();
645 TiXmlElement* echild = eGlobal->FirstChildElement();
646 while (echild != nullptr) {
647 theElement->LinkEndChild(echild->Clone());
648 echild = echild->NextSiblingElement();
649 }
650 // for (int i = 0; i < eEnv.size(); i++) {
651 // theElement->LinkEndChild(eEnv[i]->Clone());
652 //}
653 } else if (eSectional != nullptr) {
654 theElement = (TiXmlElement*)eSectional->Clone();
655 } else if (eGlobal != nullptr) {
656 theElement = (TiXmlElement*)eGlobal->Clone();
657 } else {
658 return 0;
659 }
660 fElement = theElement;
661 fElementGlobal = eGlobal ? (TiXmlElement*)eGlobal->Clone() : nullptr;
662 fVariables = envs;
663
664 int result = LoadSectionMetadata();
665 if (result == 0) InitFromConfigFile();
666 RESTDebug << ClassName() << " has finished preparing config data" << RESTendl;
667 return result;
668}
669
676 if (configBuffer != "") {
678 configBuffer = "";
680 return 0;
681 }
682 return -1;
683}
684
713 int count = 0;
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());
721 if (c) // this means that the metadata class was found
722 {
723 TRestMetadata* md = (TRestMetadata*)c->New();
724 if (!md) return nullptr;
726 TiXmlElement* rootEle = GetElementFromFile(fConfigFileName);
727 TiXmlElement* Global = GetElement("globals", rootEle);
728 md->LoadConfigFromElement(paraele, Global, {});
729 md->Initialize();
730 return md;
731 }
732 }
733 count++;
734 }
735 }
736 paraele = paraele->NextSiblingElement();
737 }
738 return nullptr;
739}
740
766TRestMetadata* TRestMetadata::InstantiateChildMetadata(std::string pattern, std::string name) {
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());
774 if (c) // this means we have the metadata class was found
775 {
776 TRestMetadata* md = (TRestMetadata*)c->New();
777 TiXmlElement* rootEle = GetElementFromFile(fConfigFileName);
778 TiXmlElement* Global = GetElement("globals", rootEle);
779 md->LoadConfigFromElement(paraele, Global, {});
780 md->Initialize();
781 return md;
782 }
783 }
784 }
785 }
786 paraele = paraele->NextSiblingElement();
787 }
788 return nullptr;
789}
790
801 // get debug level
802 string debugStr = GetParameter("verboseLevel", ToString(static_cast<int>(fVerboseLevel)));
803 fVerboseLevel = StringToVerboseLevel(debugStr);
804
805 RESTDebug << "Loading Config for : " << this->ClassName() << RESTendl;
806
807 // set env first from global section
808 if (fElementGlobal != nullptr) {
809 TiXmlElement* e = fElementGlobal->FirstChildElement();
810 while (e != nullptr) {
813 e = e->NextSiblingElement();
814 }
815 }
816
817 // then from local section
818 TiXmlElement* e = fElement->FirstChildElement();
819 while (e != nullptr) {
822 e = e->NextSiblingElement();
823 }
824
825 // look through the elements and expand for, include, etc. structures
827
828 // get debug level again in case it is defined in the included file
829 debugStr = GetParameter("verboseLevel", ToString(static_cast<int>(fVerboseLevel)));
830 fVerboseLevel = StringToVerboseLevel(debugStr);
831
832 // fill the general metadata info: name, title, fstore
833 this->SetName(GetParameter("name", "default" + string(this->ClassName())).c_str());
834 this->SetTitle(GetParameter("title", "Default " + string(this->ClassName())).c_str());
835 this->SetSectionName(this->ClassName());
836
837 fStore = StringToBool(GetParameter("store", to_string(true)));
838
839 return 0;
840}
841
848TiXmlElement* TRestMetadata::ReplaceElementAttributes(TiXmlElement* e) {
849 if (e == nullptr) return nullptr;
850
851 RESTDebug << "Entering ... TRestMetadata::ReplaceElementAttributes" << RESTendl;
852
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;
859
860 string newVal = val != nullptr ? val : "";
861 newVal = ReplaceVariables(newVal);
862
863 // for name attribute, don't replace constants
864 if (strcmp(name, "name") != 0) newVal = ReplaceConstants(newVal);
865
866 e->SetAttribute(name, ReplaceMathematicalExpressions(newVal));
867
868 attr = attr->Next();
869 }
870
871 return e;
872}
873
888void TRestMetadata::ReadEnvInElement(TiXmlElement* e, bool overwrite) {
889 if (e == nullptr) return;
890
891 const char* name = e->Attribute("name");
892 if (name == nullptr) return;
893 const char* value = e->Attribute("value");
894 if (value == nullptr) return;
895
896 if ((string)e->Value() == "variable") {
897 // if overwrite is false, try to replace the value from system env.
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;
903 }
904 if (!overwrite && fVariables.count(name) > 0) return;
905 fVariables[name] = value;
906 } else if ((string)e->Value() == "constant") {
907 if (!overwrite && fVariables.count(name) > 0) return;
908 fConstants[name] = value;
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;
912 fConstants[name] = value;
913 }
914}
915
924void TRestMetadata::ReadElement(TiXmlElement* e, bool recursive) {
925 RESTDebug << ClassName() << "::ReadElement(<" << e->Value() << ")" << RESTendl;
926 if (e == nullptr) return;
927
930
931 if ((string)e->Value() == "for") {
932 ExpandForLoops(e, {});
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();
939 // we won't expand child TRestXXX sections unless forced recursive. The expansion of
940 // these sections will be executed individually by the corresponding TRestXXX class
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()
945 << "\"" << RESTendl;
946 ReadElement(contentelement, recursive);
947 } else {
948 RESTDebug << "skipping child element \"" << contentelement->Value() << "\" of \""
949 << e->Value() << "\"" << RESTendl;
950 }
951 contentelement = nxt;
952 }
953 }
954}
955
981void TRestMetadata::ExpandIfSections(TiXmlElement* e) {
982 if (e == nullptr) return;
983 if ((string)e->Value() != "if") return;
984
985 const char* evaluate = e->Attribute("evaluate");
986 const char* condition = e->Attribute("condition");
987
988 if (condition == nullptr || string(condition).find_first_of("=!<>") == string::npos) {
989 RESTWarning << "Invalid \"IF\" structure!" << RESTendl;
990 return;
991 }
992
993 int p1 = string(condition).find_first_of("=!<>");
994 int p2 = string(condition).find_first_not_of("=!<>", p1);
995
996 string v1 = "";
997 bool matches = false;
998 if (evaluate != nullptr) {
999 v1 = TRestTools::Execute(evaluate);
1000 } else if (p1 > 0) {
1001 v1 = string(condition).substr(0, p1);
1002 } else {
1003 RESTWarning << "Invalid \"IF\" structure!" << RESTendl;
1004 return;
1005 }
1006
1007 string con = string(condition).substr(p1, p2 - p1);
1008 string v2 = string(condition).substr(p2, -1);
1009
1010 if (con == "==") {
1011 if (isANumber(v1) && isANumber(v2)) {
1012 if (atof(v1.c_str()) == atof(v2.c_str())) matches = true;
1013 } else {
1014 if (v1 == v2) matches = true;
1015 }
1016 } else if (con == "!=") {
1017 if (isANumber(v1) && isANumber(v2)) {
1018 if (atof(v1.c_str()) != atof(v2.c_str())) matches = true;
1019 } else {
1020 if (v1 != v2) matches = true;
1021 }
1022 } else if (con == ">") {
1023 if (isANumber(v1) && isANumber(v2)) {
1024 if (atof(v1.c_str()) > atof(v2.c_str())) matches = true;
1025 } else {
1026 if (v1 > v2) matches = true;
1027 }
1028 } else if (con == "<") {
1029 if (isANumber(v1) && isANumber(v2)) {
1030 if (atof(v1.c_str()) < atof(v2.c_str())) matches = true;
1031 } else {
1032 if (v1 < v2) matches = true;
1033 }
1034 } else if (con == ">=") {
1035 if (isANumber(v1) && isANumber(v2)) {
1036 if (atof(v1.c_str()) >= atof(v2.c_str())) matches = true;
1037 } else {
1038 if (v1 >= v2) matches = true;
1039 }
1040 } else if (con == "<=") {
1041 if (isANumber(v1) && isANumber(v2)) {
1042 if (atof(v1.c_str()) <= atof(v2.c_str())) matches = true;
1043 } else {
1044 if (v1 <= v2) matches = true;
1045 }
1046 } else {
1047 RESTWarning << "Invalid \"IF\" structure!" << RESTendl;
1048 return;
1049 }
1050
1051 if (matches) {
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();
1057 ReadElement(attachedelement, true);
1058 // RESTDebug << *attachedelement << RESTendl;
1059 parele->InsertBeforeChild(e, *attachedelement);
1060 delete attachedelement;
1061 contentelement = contentelement->NextSiblingElement();
1062 }
1063 }
1064}
1065
1068void TRestMetadata::ExpandForLoopOnce(TiXmlElement* e, const map<string, string>& forLoopVar) {
1069 if (e == nullptr) {
1070 return;
1071 }
1072
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();
1078 // ReplaceElementAttributes(newforloop);
1079 TiXmlElement* tempnew = (TiXmlElement*)parele->InsertBeforeChild(e, *newforloop);
1080 delete newforloop;
1081 newforloop = tempnew;
1082 ExpandForLoops(newforloop, forLoopVar);
1083 contentelement = contentelement->NextSiblingElement();
1084 } else {
1085 TiXmlElement* attachedelement = (TiXmlElement*)contentelement->Clone();
1086 ReplaceForLoopVars(attachedelement, forLoopVar);
1087 ReadElement(attachedelement, true);
1088 // RESTDebug << *attachedelement << RESTendl;
1089 parele->InsertBeforeChild(e, *attachedelement);
1090 delete attachedelement;
1091 contentelement = contentelement->NextSiblingElement();
1092 }
1093 }
1094}
1095
1099void TRestMetadata::ReplaceForLoopVars(TiXmlElement* e, map<string, string> forLoopVar) {
1100 if (e == nullptr) return;
1101
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;
1109
1110 if (strcmp(name, "name") == 0) parName = (string)val;
1111
1112 // set attribute except name field
1113 if (strcmp(name, "name") != 0) {
1114 string outputBuffer = val;
1115
1116 if (outputBuffer.find('[') != string::npos || outputBuffer.find(']') != string::npos) {
1117 RESTError << "TRestMetadata::ReplaceForLoopVars. Old for-loop construction identified"
1118 << RESTendl;
1119 RESTError << "Please, replace [] variable nomenclature by ${}." << RESTendl;
1120 exit(1);
1121 }
1122
1123 // replace variables with mark ${}
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] == '$')
1130 break; // to prevent replacing ${} mark
1131
1132 string expression = outputBuffer.substr(startPosition + 1, endPosition - startPosition - 1);
1133
1134 int replacePos = startPosition;
1135 int replaceLen = endPosition - startPosition + 1;
1136
1137 string proenv = forLoopVar.count(expression) > 0 ? forLoopVar[expression] : "";
1138
1139 if (!proenv.empty()) {
1140 outputBuffer.replace(replacePos, replaceLen, proenv);
1141 endPosition = 0;
1142 } else {
1143 RESTError << this->ClassName() << ", replace for loop env : cannot find \"{" << expression
1144 << "}\"" << RESTendl;
1145 exit(1);
1146 }
1147 }
1148
1149 e->SetAttribute(name, ReplaceMathematicalExpressions(
1150 outputBuffer, 0,
1151 "Please, check parameter name: " + parName + " (ReplaceForLoopVars)")
1152 .c_str());
1153 }
1154
1155 attr = attr->Next();
1156 }
1157}
1158
1166void TRestMetadata::ExpandForLoops(TiXmlElement* e, map<string, string> forloopvar) {
1167 if (e == nullptr) return;
1168 if ((string)e->Value() != "for") return;
1169 RESTDebug << "Entering ... ExpandForLoops" << RESTendl;
1171
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"));
1177
1178 RESTDebug << "variable: " << varname << " from: " << varfrom << " to: " << varto << " step: " << varstep
1179 << " in: " << varin << RESTendl;
1180
1181 if ((varin == "") && (varname == "" || varfrom == "" || varto == "")) return;
1182 if (varstep == "") varstep = "1";
1183 TiXmlElement* parele = (TiXmlElement*)e->Parent();
1184 if (parele == nullptr) return;
1185
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;
1192 if (isANumber(_from) && isANumber(_to) && isANumber(_step)) {
1193 double from = StringToDouble(_from);
1194 double to = StringToDouble(_to);
1195 double step = StringToDouble(_step);
1196
1197 RESTDebug << "----expanding for loop----" << RESTendl;
1198 double i = 0;
1199 for (i = from; i <= to; i = i + step) {
1200 forloopvar[_name] = ToString(i);
1201 fVariables[_name] = ToString(i);
1202 ExpandForLoopOnce(e, forloopvar);
1203 }
1204 parele->RemoveChild(e);
1205
1207 RESTDebug << "----end of for loop----" << RESTendl;
1208 } else if (!_in.empty()) {
1209 vector<string> loopvars = Split(_in, ":");
1210
1211 RESTDebug << "----expanding for loop----" << RESTendl;
1212 for (const string& loopvar : loopvars) {
1213 forloopvar[_name] = loopvar;
1214 fVariables[_name] = loopvar;
1215 ExpandForLoopOnce(e, forloopvar);
1216 }
1217 parele->RemoveChild(e);
1218
1220 RESTDebug << "----end of for loop----" << RESTendl;
1221 }
1222 // variable defined in for loop should be temporal
1223 fVariables.erase(_name);
1224}
1225
1247 RESTDebug << "Entering ... " << __PRETTY_FUNCTION__ << RESTendl;
1248 if (e == nullptr) return;
1249
1251 const char* _filename = e->Attribute("file");
1252 if (_filename == nullptr) return;
1253
1254 string filename;
1255 if (string(_filename) == "server" || TRestTools::isURL(_filename)) {
1256 // Let TRestRun to retrieve data according to run number later-on
1257
1258 // match the database, runNumber=0(default data), type="META_RML", tag=<section name>
1259 auto url = gDataBase->query_data(DBEntry(0, "META_RML", e->Value())).value;
1260 if (url.empty()) {
1261 // don't really understand this "database" code, this just works
1262 url = _filename;
1263 }
1264
1265 filename = TRestTools::DownloadRemoteFile(url);
1266 } else {
1267 filename = SearchFile(_filename);
1268 }
1269
1270 if (filename.empty()) {
1271 RESTError << "TRestMetadata::ExpandIncludeFile. Include file \"" << _filename << "\" does not exist!"
1272 << RESTendl;
1273 exit(1);
1274 return;
1275 }
1276 if (!TRestTools::isRootFile(filename)) // root file inclusion is implemented in TRestRun
1277 {
1278 RESTDebug << "----expanding include file----" << RESTendl;
1279 // we find the local element(the element to receive content)
1280 // and the remote element(the element to provide content)
1281 TiXmlElement* remoteele = nullptr;
1282 TiXmlElement* localele = nullptr;
1283 string type;
1284 string name;
1285
1287 // condition 1(raw file include):
1288 // <TRestXXX name="" .....>
1289 // <include file="aaa.rml"/>
1290 // ....
1291 // </TRestXXX>
1292 //
1293 // We will insert all the xml elements in aaa.rml into this section
1294 if ((string)e->Value() == "include") {
1295 localele = (TiXmlElement*)e->Parent();
1296 if (localele == nullptr) return;
1297 if (localele->Attribute("expanded") == nullptr
1298 ? false
1299 : ((string)localele->Attribute("expanded") == "true")) {
1300 RESTDebug << "----already expanded----" << RESTendl;
1301 return;
1302 }
1303
1304 remoteele = new TiXmlElement("Config");
1305
1306 TiXmlElement* ele = GetElementFromFile(filename);
1307 if (ele == nullptr) {
1308 RESTError << "TRestMetadata::ExpandIncludeFile. No xml elements contained in the include "
1309 "file \""
1310 << filename << "\"" << RESTendl;
1311 exit(1);
1312 }
1313 while (ele != nullptr) {
1314 remoteele->InsertEndChild(*ele);
1315 ele = ele->NextSiblingElement();
1316 }
1317
1318 }
1319
1321 // condition 2(auto insert):
1322 // <TRestXXX file=""/>
1323 // or
1324 // <TRestXXX name="" ... file="aaa.rml" .../>
1325 // or
1326 // <addXXX name="" ... file="aaa.rml" .../>
1327 // or
1328 // <addXXX type="" name="" ... file="aaa.rml" .../>
1329 //
1330 // Here TRestXXX will be "type". we will find the corresponding section, and
1331 // insert all its attributes and child elements into this section. "name"
1332 // overwrites "type"
1333 else {
1334 localele = e;
1335 if (localele->Attribute("expanded") == nullptr
1336 ? false
1337 : ((string)localele->Attribute("expanded") == "true")) {
1338 RESTDebug << "----already expanded----" << RESTendl;
1339 return;
1340 }
1341
1342 type = e->Attribute("type") != nullptr ? e->Attribute("type") : e->Value();
1343 name = localele->Attribute("name") == nullptr ? "" : localele->Attribute("name");
1344
1345 // get the root element
1346 TiXmlElement* rootele = GetElementFromFile(filename);
1347 if (rootele == nullptr) {
1348 RESTError << "TRestMetaddata::ExpandIncludeFile. Include file " << filename
1349 << " is of wrong xml format!" << RESTendl;
1350 exit(1);
1351 return;
1352 }
1353 if ((string)rootele->Value() == type) {
1354 // if root element in the included file is of given type, directly use
1355 // it
1356 remoteele = rootele;
1357 } else {
1358 // import env first
1359 if (type != "globals" && GetElement("globals", rootele) != nullptr) {
1360 TiXmlElement* globaldef = GetElement("globals", rootele)->FirstChildElement();
1361 while (globaldef != nullptr) {
1362 ReadEnvInElement(globaldef, false);
1363 globaldef = globaldef->NextSiblingElement();
1364 }
1365 }
1366
1367 // find its child section according to type and name
1368 if (name != "") {
1369 // we find only according to the name
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);
1375 }
1376 ele = ele->NextSiblingElement();
1377 }
1378 // more than 1 element found
1379 if (eles.size() > 1) {
1380 RESTWarning << "(expand include file): find multiple xml sections with same name!"
1381 << RESTendl;
1382 RESTWarning << "Using the first one!" << RESTendl;
1383 }
1384
1385 if (eles.size() > 0) remoteele = (TiXmlElement*)eles[0]->Clone();
1386 } else if (type != "") {
1387 remoteele = (TiXmlElement*)GetElement(type, rootele)->Clone();
1388 }
1389
1390 if (remoteele == nullptr) {
1391 RESTWarning << "Cannot find the needed xml section in "
1392 "include file!"
1393 << RESTendl;
1394 RESTWarning << "type: \"" << type << "\" , name: \"" << name << "\" . Skipping"
1395 << RESTendl;
1396 RESTWarning << RESTendl;
1397 return;
1398 }
1399 delete rootele;
1400 }
1401 }
1402
1403 RESTDebug << "Target xml element spotted" << RESTendl;
1404
1406 // begin inserting remote element into local element
1407 ReadElement(remoteele, true);
1408 int nattr = 0;
1409 int nele = 0;
1410 TiXmlAttribute* attr = remoteele->FirstAttribute();
1411 while (attr != nullptr) {
1412 if (localele->Attribute(attr->Name()) == nullptr) {
1413 localele->SetAttribute(attr->Name(), attr->Value());
1414 nattr++;
1415 }
1416 attr = attr->Next();
1417 }
1418 TiXmlElement* ele = remoteele->FirstChildElement();
1419 while (ele != nullptr) {
1420 // ReadElement(ele);
1421 if ((string)ele->Value() != "for") {
1422 localele->InsertEndChild(*ele);
1423 nele++;
1424 }
1425 ele = ele->NextSiblingElement();
1426 }
1427
1428 localele->SetAttribute("expanded", "true");
1430 localele->Print(stdout, 0);
1431 cout << endl;
1432 }
1433 delete remoteele;
1434 RESTDebug << nattr << " attributes and " << nele << " xml elements added by inclusion" << RESTendl;
1435 RESTDebug << "----end of expansion file----" << RESTendl;
1436 }
1437}
1438
1450string TRestMetadata::GetParameter(std::string parName, TString defaultValue) {
1451 // first search the parameter in REST args
1452 if (REST_ARGS.count(parName) != 0) {
1453 return REST_ARGS[parName];
1454 }
1455
1456 // then look within local xml element
1457 string result = GetParameter(parName, fElement);
1458 if (result != PARAMETER_NOT_FOUND_STR) {
1459 return result;
1460 }
1461
1462 return (string)defaultValue;
1463}
1464
1489string TRestMetadata::GetParameter(std::string parName, TiXmlElement* e, TString defaultValue) {
1490 if (e == nullptr) {
1491 RESTDebug << "Element is null" << RESTendl;
1492 return (string)defaultValue;
1493 }
1494 string result = (string)defaultValue;
1495 // first find in attribute
1496 if (e->Attribute(parName.c_str()) != nullptr) {
1497 result = e->Attribute(parName.c_str());
1498 }
1499 // then find in child sections/elements
1500 else {
1501 TiXmlElement* element = GetElementWithName("parameter", parName, e);
1502 if (element != nullptr && element->Attribute("value") != nullptr) {
1503 result = element->Attribute("value");
1504 } else {
1505 RESTDebug << ClassName() << ": Parameter : " << parName << " not found!" << RESTendl;
1506 }
1507 }
1508
1510 "Please, check parameter name: " + parName);
1511}
1512
1513Double_t TRestMetadata::GetDblParameterWithUnits(std::string parName, TiXmlElement* ele,
1514 Double_t defaultVal) {
1515 if (ele == nullptr) return defaultVal;
1516 pair<string, string> val_unit = GetParameterAndUnits(parName, ele);
1517 string val = val_unit.first;
1518 string unit = val_unit.second;
1519 if (val == PARAMETER_NOT_FOUND_STR) {
1520 return defaultVal;
1521 } else {
1522 Double_t value = StringToDouble(val);
1523 return REST_Units::ConvertValueToRESTUnits(value, unit);
1524 }
1525
1526 return defaultVal;
1527}
1528
1529TVector2 TRestMetadata::Get2DVectorParameterWithUnits(std::string parName, TiXmlElement* ele,
1530 TVector2 defaultVal) {
1531 if (ele == nullptr) return defaultVal;
1532 pair<string, string> val_unit = GetParameterAndUnits(parName, ele);
1533 string val = val_unit.first;
1534 string unit = val_unit.second;
1535 if (val == PARAMETER_NOT_FOUND_STR) {
1536 return defaultVal;
1537 } else {
1538 TVector2 value = StringTo2DVector(val);
1539 Double_t valueX = REST_Units::ConvertValueToRESTUnits(value.X(), unit);
1540 Double_t valueY = REST_Units::ConvertValueToRESTUnits(value.Y(), unit);
1541 return TVector2(valueX, valueY);
1542 }
1543
1544 return defaultVal;
1545}
1546
1547TVector3 TRestMetadata::Get3DVectorParameterWithUnits(std::string parName, TiXmlElement* ele,
1548 TVector3 defaultVal) {
1549 if (ele == nullptr) return defaultVal;
1550 pair<string, string> val_unit = GetParameterAndUnits(parName, ele);
1551 string val = val_unit.first;
1552 string unit = val_unit.second;
1553 if (val == PARAMETER_NOT_FOUND_STR) {
1554 return defaultVal;
1555 } else {
1556 TVector3 value = StringTo3DVector(val);
1557 Double_t valueX = REST_Units::ConvertValueToRESTUnits(value.X(), unit);
1558 Double_t valueY = REST_Units::ConvertValueToRESTUnits(value.Y(), unit);
1559 Double_t valueZ = REST_Units::ConvertValueToRESTUnits(value.Z(), unit);
1560 return TVector3(valueX, valueY, valueZ);
1561 }
1562
1563 return defaultVal;
1564}
1565
1573std::string TRestMetadata::GetFieldValue(std::string parName, TiXmlElement* e) {
1574 if (e == nullptr) {
1575 RESTDebug << "Element is null" << RESTendl;
1576 return "Not defined";
1577 }
1578 const char* val = e->Attribute(parName.c_str());
1579 if (val == nullptr) {
1580 return "Not defined";
1581 }
1582
1583 string result = (string)val;
1584 result = Replace(result, " AND ", " && ");
1585 result = Replace(result, " OR ", " || ");
1586
1587 return result;
1588}
1589
1619Double_t TRestMetadata::GetDblParameterWithUnits(std::string parName, Double_t defaultVal) {
1620 pair<string, string> val_unit = GetParameterAndUnits(parName);
1621 string val = val_unit.first;
1622 string unit = val_unit.second;
1623 if (val == PARAMETER_NOT_FOUND_STR) {
1624 return defaultVal;
1625 } else {
1626 Double_t value = StringToDouble(val);
1627 return REST_Units::ConvertValueToRESTUnits(value, unit);
1628 }
1629 return defaultVal;
1630}
1631
1632TVector2 TRestMetadata::Get2DVectorParameterWithUnits(std::string parName, TVector2 defaultVal) {
1633 pair<string, string> val_unit = GetParameterAndUnits(parName);
1634 string val = val_unit.first;
1635 string unit = val_unit.second;
1636 if (val == PARAMETER_NOT_FOUND_STR) {
1637 return defaultVal;
1638 } else {
1639 TVector2 value = StringTo2DVector(val);
1640 Double_t valueX = REST_Units::ConvertValueToRESTUnits(value.X(), unit);
1641 Double_t valueY = REST_Units::ConvertValueToRESTUnits(value.Y(), unit);
1642 return TVector2(valueX, valueY);
1643 }
1644 return defaultVal;
1645}
1646
1647TVector3 TRestMetadata::Get3DVectorParameterWithUnits(std::string parName, TVector3 defaultVal) {
1648 pair<string, string> val_unit = GetParameterAndUnits(parName);
1649 string val = val_unit.first;
1650 string unit = val_unit.second;
1651 if (val == PARAMETER_NOT_FOUND_STR) {
1652 return defaultVal;
1653 } else {
1654 TVector3 value = StringTo3DVector(val);
1655 Double_t valueX = REST_Units::ConvertValueToRESTUnits(value.X(), unit);
1656 Double_t valueY = REST_Units::ConvertValueToRESTUnits(value.Y(), unit);
1657 Double_t valueZ = REST_Units::ConvertValueToRESTUnits(value.Z(), unit);
1658 return TVector3(valueX, valueY, valueZ);
1659 }
1660 return defaultVal;
1661}
1662
1678TiXmlElement* TRestMetadata::GetElementFromFile(std::string configFilename, std::string NameOrDeclare) {
1679 TiXmlDocument doc;
1680 TiXmlElement* rootele;
1681
1682 string filename = configFilename;
1683 if (TRestMetadata_UpdatedConfigFile.count(filename) > 0)
1684 filename = TRestMetadata_UpdatedConfigFile[filename];
1685
1686 if (!TRestTools::fileExists(filename)) {
1687 RESTError << "Config file does not exist. The file is: " << filename << RESTendl;
1688 exit(1);
1689 }
1690
1691 if (!doc.LoadFile(filename.c_str())) {
1692 RESTError << "Failed to load xml file, syntax maybe wrong. The file is: " << filename << RESTendl;
1693 exit(1);
1694 }
1695
1696 rootele = doc.RootElement();
1697 if (rootele == nullptr) {
1698 RESTError << "The rml file \"" << configFilename << "\" does not contain any valid elements!"
1699 << RESTendl;
1700 exit(1);
1701 }
1702 if (NameOrDeclare == "") {
1703 return (TiXmlElement*)rootele->Clone();
1704 }
1705 // search with either name or declare in either root element or sub-root
1706 // element
1707 while (rootele != nullptr) {
1708 if (rootele->Value() != nullptr && (string)rootele->Value() == NameOrDeclare) {
1709 return (TiXmlElement*)rootele->Clone();
1710 }
1711
1712 if (rootele->Attribute("name") != nullptr && (string)rootele->Attribute("name") == NameOrDeclare) {
1713 return (TiXmlElement*)rootele->Clone();
1714 }
1715
1716 TiXmlElement* etemp = GetElement(NameOrDeclare, rootele);
1717 if (etemp != nullptr) {
1718 return (TiXmlElement*)etemp->Clone();
1719 }
1720
1721 etemp = GetElementWithName("", NameOrDeclare, rootele);
1722
1723 if (etemp != nullptr) {
1724 return (TiXmlElement*)etemp->Clone();
1725 }
1726
1727 rootele = rootele->NextSiblingElement();
1728 }
1729
1730 return nullptr;
1731 /*ferr << "Cannot find xml element with name \""<< NameOrDeclare <<"\" in rml
1732 file \"" << configFilename << endl; GetChar(); exit(1);*/
1733}
1734
1739TiXmlElement* TRestMetadata::GetElement(std::string eleDeclare, TiXmlElement* e) {
1740 if (e == nullptr) e = fElement;
1741 return e->FirstChildElement(eleDeclare.c_str());
1742}
1743
1747TiXmlElement* TRestMetadata::GetNextElement(TiXmlElement* e) {
1748 if (e == nullptr) return nullptr;
1749 return e->NextSiblingElement(e->Value());
1750}
1751
1756TiXmlElement* TRestMetadata::GetElementWithName(std::string eleDeclare, std::string eleName) {
1757 return GetElementWithName(eleDeclare, eleName, fElement);
1758}
1759
1764TiXmlElement* TRestMetadata::GetElementWithName(std::string eleDeclare, std::string eleName,
1765 TiXmlElement* e) {
1766 if (e == nullptr) return nullptr;
1767 if (eleDeclare == "") // find only with name
1768 {
1769 TiXmlElement* ele = e->FirstChildElement();
1770 while (ele != nullptr) {
1771 if (ele->Attribute("name") != nullptr) {
1772 std::string nameValue = (string)ele->Attribute("name");
1773 nameValue = ReplaceVariables(nameValue);
1774 if (nameValue == eleName) {
1775 return ele;
1776 }
1777 }
1778 ele = ele->NextSiblingElement();
1779 }
1780 return ele;
1781 } else // find with name and declare
1782 {
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");
1787 nameValue = ReplaceVariables(nameValue);
1788 if (nameValue == eleName) {
1789 return ele;
1790 }
1791 }
1792 ele = ele->NextSiblingElement(eleDeclare.c_str());
1793 }
1794 return ele;
1795 }
1796
1797 return nullptr;
1798}
1799
1807string TRestMetadata::GetUnits(TiXmlElement* e) {
1808 if (e == nullptr) {
1809 RESTWarning << "TRestMetadata::GetUnits(): NULL element given!" << RESTendl;
1810 return "";
1811 }
1812
1813 string valstr = e->Attribute("value") == nullptr ? "" : e->Attribute("value");
1814 string unitattr = e->Attribute("units") == nullptr ? "" : e->Attribute("units");
1815
1816 string unitembeded = REST_Units::FindRESTUnitsInString(valstr);
1817 if (IsUnit(unitembeded)) {
1818 return unitembeded;
1819 }
1820 if (IsUnit(unitattr)) {
1821 return unitattr;
1822 }
1823 return "";
1824}
1825
1836pair<string, string> TRestMetadata::GetParameterAndUnits(string parName, TiXmlElement* e) {
1837 string parvalue;
1838 if (e == nullptr) {
1839 parvalue = GetParameter(parName);
1840 e = fElement;
1841 } else {
1842 parvalue = GetParameter(parName, e);
1843 }
1844
1845 if (parvalue == PARAMETER_NOT_FOUND_STR) {
1846 return {parvalue, ""};
1847 } else {
1848 // first try to use unit embeded in parvalue
1849 string unit = REST_Units::FindRESTUnitsInString(parvalue);
1850 // then try to find unit in corresponding "parameter" section
1851 if (unit == "") {
1852 TiXmlElement* paraele = GetElementWithName("parameter", parName, e);
1853 if (paraele != nullptr) {
1854 unit = GetUnits(paraele);
1855 }
1856 }
1857 // finally try to find unit in local section attribute
1858 if (unit == "") {
1859 unit = GetUnits(e);
1860 }
1861 return {REST_Units::RemoveUnitsFromString(parvalue), unit};
1862 }
1863 return {parvalue, ""};
1864}
1865
1871TiXmlElement* TRestMetadata::StringToElement(string definition) {
1872 TiXmlElement* ele = new TiXmlElement("temp");
1873 // TiXmlDocument*doc = new TiXmlDocument();
1874 ele->Parse(definition.c_str(), nullptr, TIXML_ENCODING_UTF8);
1875 return ele;
1876}
1877
1883string TRestMetadata::ElementToString(TiXmlElement* ele) {
1884 if (ele != nullptr) {
1885 // remove comments
1886 TiXmlNode* n = ele->FirstChild();
1887 while (n != nullptr) {
1888 TiXmlComment* cmt = n->ToComment();
1889 if (cmt != nullptr) {
1890 TiXmlNode* nn = n;
1891 n = n->NextSibling();
1892 ele->RemoveChild(nn);
1893 continue;
1894 }
1895 n = n->NextSibling();
1896 }
1897
1898 stringstream ss;
1899 ss << (*ele);
1900 string s = ss.str();
1901
1902 // int pos = 0;
1903 // int pos2 = 0;
1904 // while ((pos = s.find("<!--", pos)) != -1 && (pos2 = s.find("-->", pos))
1905 // != -1)
1906 //{
1907 // s.replace(pos, pos2 - pos + 3, "");//3 is the length of "-->"
1908 // pos = pos + 1;
1909 //}
1910
1911 return s;
1912 }
1913
1914 return " ";
1915}
1916
1929string TRestMetadata::GetKEYStructure(std::string keyName) {
1930 size_t Position = 0;
1931 string result = GetKEYStructure(keyName, Position, fElement);
1932 if (result == "") result = "NotFound";
1933 return result;
1934}
1935string TRestMetadata::GetKEYStructure(std::string keyName, size_t& Position) {
1936 string result = GetKEYStructure(keyName, Position, fElement);
1937 if (result == "") result = "NotFound";
1938 return result;
1939}
1940string TRestMetadata::GetKEYStructure(std::string keyName, string buffer) {
1941 size_t Position = 0;
1942 string result = GetKEYStructure(keyName, Position, buffer);
1943 if (result == "") result = "NotFound";
1944 return result;
1945}
1946string TRestMetadata::GetKEYStructure(std::string keyName, size_t& fromPosition, string buffer) {
1947 TiXmlElement* ele = StringToElement(buffer);
1948 string result = GetKEYStructure(keyName, fromPosition, ele);
1949 delete ele;
1950 return result;
1951}
1952string TRestMetadata::GetKEYStructure(std::string keyName, size_t& fromPosition, TiXmlElement* ele) {
1953 RESTDebug << "Finding " << fromPosition << "th appearance of KEY Structure \"" << keyName << "\"..."
1954 << RESTendl;
1955
1956 TiXmlElement* childele = ele->FirstChildElement(keyName);
1957 for (unsigned int i = 0; childele != nullptr && i < fromPosition; i++) {
1958 childele = childele->NextSiblingElement(keyName);
1959 }
1960 if (childele != nullptr) {
1961 string result = ElementToString(childele);
1962 fromPosition = fromPosition + 1;
1963 RESTDebug << "Found Key : " << result << RESTendl;
1964 return result;
1965 }
1966
1967 RESTDebug << "Finding hit the end, KEY Structure not found!!" << RESTendl;
1968 return "";
1969}
1970
1981string TRestMetadata::GetKEYDefinition(string keyName) {
1982 string buffer = ElementToString(fElement);
1983 size_t Position = 0;
1984 return GetKEYDefinition(keyName, Position, buffer);
1985}
1986string TRestMetadata::GetKEYDefinition(string keyName, size_t& fromPosition) {
1987 string buffer = ElementToString(fElement);
1988 return GetKEYDefinition(keyName, fromPosition, buffer);
1989}
1990string TRestMetadata::GetKEYDefinition(string keyName, string buffer) {
1991 size_t Position = 0;
1992 return GetKEYDefinition(keyName, Position, buffer);
1993}
1994string TRestMetadata::GetKEYDefinition(string keyName, size_t& fromPosition, string buffer) {
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 "";
2000
2001 fromPosition = endPos;
2002
2003 Int_t notDefinitionEnd = 1;
2004
2005 while (notDefinitionEnd) {
2006 // We might find a problem when we insert > symbol inside a field value.
2007 // As for example: condition=">100" This patch checks if the definition
2008 // finishes in "= If it is the case it searches the next > symbol ending
2009 // the definition.
2010
2011 string def = RemoveWhiteSpaces(buffer.substr(startPos, endPos - startPos));
2012
2013 if ((TString)def[def.length() - 1] == "\"" && (TString)def[def.length() - 2] == "=")
2014 endPos = buffer.find(">", endPos + 1);
2015 else
2016 notDefinitionEnd = 0;
2017 }
2018
2019 string result = buffer.substr(startPos, endPos - startPos + 1);
2020 if (result[result.size() - 2] != '/') result.insert(result.size() - 1, 1, '/');
2021 // cout << result << endl << endl;
2022 // getchar();
2023 return result;
2024}
2025
2031string TRestMetadata::FieldNamesToUpper(string definition) {
2032 string result = definition;
2033 TiXmlElement* e = StringToElement(definition);
2034 if (e == nullptr) return nullptr;
2035
2036 TiXmlAttribute* attr = e->FirstAttribute();
2037 while (attr != nullptr) {
2038 string parName = std::string(attr->Name());
2039
2040 size_t pos = 0;
2041 result = Replace(result, parName, ToUpper(parName), pos);
2042
2043 attr = attr->Next();
2044 }
2045
2046 return result;
2047}
2048
2053std::string TRestMetadata::GetFieldValue(std::string fieldName, std::string definition, size_t fromPosition) {
2054 TiXmlElement* ele = StringToElement(FieldNamesToUpper(definition));
2055 string value = GetFieldValue(ToUpper(fieldName), ele);
2056 delete ele;
2057 return value;
2058}
2059
2067string TRestMetadata::GetParameter(string parName, size_t& pos, string inputString) {
2068 pos = inputString.find(parName, pos);
2069
2070 TiXmlElement* ele = StringToElement(inputString);
2071 string value = GetParameter(parName, ele);
2072
2073 delete ele;
2074 return value;
2075}
2076
2086string TRestMetadata::ReplaceVariables(const string buffer) {
2087 RESTDebug << "Entering ... TRestMetadata::ReplaceVariables (" << buffer << ")" << RESTendl;
2088 string outputBuffer = buffer;
2089
2090 // replace variables with mark ${}
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;
2096
2097 string expression = outputBuffer.substr(startPosition + 2, endPosition - startPosition - 2);
2098
2099 int replacePos = startPosition;
2100 int replaceLen = endPosition - startPosition + 1;
2101
2102 string sysenv = getenv(expression.c_str()) != nullptr ? getenv(expression.c_str()) : "";
2103 string proenv = fVariables.count(expression) > 0 ? fVariables[expression] : "";
2104 string argenv = REST_ARGS.count(expression) > 0 ? REST_ARGS[expression] : "";
2105
2106 if (sysenv != "") {
2107 outputBuffer.replace(replacePos, replaceLen, sysenv);
2108 endPosition = 0;
2109 } else if (argenv != "") {
2110 outputBuffer.replace(replacePos, replaceLen, argenv);
2111 endPosition = 0;
2112 } else if (proenv != "") {
2113 outputBuffer.replace(replacePos, replaceLen, proenv);
2114 endPosition = 0;
2115 } else {
2116 RESTError << this->ClassName() << ", replace env : cannot find \"${" << expression
2117 << "}\" in either system or program env, exiting..." << RESTendl;
2118 exit(1);
2119 }
2120 }
2121
2122 if (buffer != outputBuffer) RESTDebug << "Replaced by : " << outputBuffer << RESTendl;
2123 return outputBuffer;
2124}
2125
2130string TRestMetadata::ReplaceConstants(const string buffer) {
2131 RESTDebug << "Entering ... TRestMetadata::ReplaceConstants (" << buffer << ")" << RESTendl;
2132 string outputBuffer = buffer;
2133
2134 // replace bare constant name. ignore sub strings.
2135 // e.g. variable "nCh" with value "3" cannot replace the string "nChannels+1"
2136 for (auto iter : fConstants) {
2137 int pos = outputBuffer.find(iter.first, 0);
2138 while (pos != -1) {
2139 char next =
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());
2145 } else {
2146 pos = outputBuffer.find(iter.first, pos + iter.first.size());
2147 }
2148 }
2149 }
2150
2151 if (buffer != outputBuffer) RESTDebug << "Replaced by : " << outputBuffer << RESTendl;
2152 return outputBuffer;
2153}
2154
2161string TRestMetadata::SearchFile(string filename) {
2162 if (TRestTools::fileExists(filename)) {
2163 return filename;
2164 } else {
2165 auto pathString = GetSearchPath();
2166 auto paths = Split((string)pathString, ":");
2167 return TRestTools::SearchFileInPath(paths, filename);
2168 }
2169}
2170
2174void TRestMetadata::PrintTimeStamp(Double_t timeStamp) {
2175 cout.precision(10);
2176
2177 time_t tt = (time_t)timeStamp;
2178 struct tm* tm = localtime(&tt);
2179
2180 char date[20];
2181 strftime(date, sizeof(date), "%Y-%m-%d", tm);
2182 cout << "Date : " << date << endl;
2183
2184 char time[20];
2185 strftime(time, sizeof(time), "%H:%M:%S", tm);
2186 cout << "Time : " << time << endl;
2187 cout << "++++++++++++++++++++++++" << endl;
2188}
2189
2194 if (fElement != nullptr) {
2195 fElement->Print(stdout, 0);
2196 cout << endl;
2197 } else {
2198 if (configBuffer != "") {
2199 auto ele = StringToElement(configBuffer);
2200 ele->Print(stdout, 0);
2201 cout << endl;
2202 delete ele;
2203 } else {
2204 cout << "N/A" << endl;
2205 }
2206 }
2207}
2208
2210 if (fElement != nullptr) {
2211 FILE* f = fopen(fname.c_str(), "at");
2212 fElement->Print(f, 0);
2213 fclose(f);
2214 return;
2215 } else if (configBuffer != "") {
2216 FILE* f = fopen(fname.c_str(), "at");
2217 auto ele = StringToElement(configBuffer);
2218 ele->Print(f, 0);
2219 fclose(f);
2220 delete ele;
2221 return;
2222 }
2223
2224 RESTError << "Something missing here. Call the police" << RESTendl;
2225}
2226
2228
2234 RESTMetadata << "+++++++++++++++++++++++++++++++++++++++++++++" << RESTendl;
2235 RESTMetadata << this->ClassName() << " content" << RESTendl;
2236 RESTMetadata << "Config file : " << fConfigFileName << RESTendl;
2237 RESTMetadata << "+++++++++++++++++++++++++++++++++++++++++++++" << RESTendl;
2238 RESTMetadata << "Name : " << GetName() << RESTendl;
2239 RESTMetadata << "Title : " << GetTitle() << RESTendl;
2240 RESTMetadata << "REST Version : " << GetVersion() << RESTendl;
2241 if (fOfficialRelease)
2242 RESTMetadata << "REST Official release: Yes" << RESTendl;
2243 else
2244 RESTMetadata << "REST Official release: No" << RESTendl;
2245 if (fCleanState)
2246 RESTMetadata << "Clean state: Yes" << RESTendl;
2247 else
2248 RESTMetadata << "Clean state: No" << RESTendl;
2249 RESTMetadata << "REST Commit : " << GetCommit() << RESTendl;
2250 if (GetLibraryVersion() != "0.0")
2251 RESTMetadata << "REST Library version : " << GetLibraryVersion() << RESTendl;
2252 RESTMetadata << "---------------------------------------" << RESTendl;
2253}
2254
2259
2263TString TRestMetadata::GetCommit() { return fCommit; }
2264
2268TString TRestMetadata::GetLibraryVersion() { return fLibraryVersion; }
2269
2274 if (!this->InheritsFrom("TRestRun"))
2275 RESTError << "version is a static value, you cannot set version "
2276 "for a class!"
2277 << RESTendl;
2278 else {
2279 fVersion = REST_RELEASE;
2280 }
2281}
2282
2287 if (!this->InheritsFrom("TRestRun"))
2288 RESTError << "version is a static value, you cannot set version "
2289 "for a class!"
2290 << RESTendl;
2291 else {
2292 fVersion = -1;
2293 fCommit = -1;
2294 }
2295}
2296
2300void TRestMetadata::SetLibraryVersion(TString version) { fLibraryVersion = version; }
2301
2302Int_t TRestMetadata::GetVersionCode() { return TRestTools::ConvertVersionCode((string)GetVersion()); }
2303
2308 auto a = fSectionName.find('\n', 0);
2309 if (a != string::npos) return fSectionName.substr(0, a);
2310 return fSectionName;
2311}
2312
2316
2322string TRestMetadata::GetDataMemberValue(string memberName) {
2323 return RESTValue(this, this->ClassName()).GetDataMemberValueString(memberName);
2324}
2325
2340std::vector<string> TRestMetadata::GetDataMemberValues(string memberName, Int_t precision) {
2341 string result = GetDataMemberValue(memberName);
2342
2343 result = Replace(result, "{", "");
2344 result = Replace(result, "}", "");
2345 result = Replace(result, "(", "");
2346 result = Replace(result, ")", "");
2347
2348 std::vector<std::string> results = REST_StringHelper::Split(result, ",");
2349
2350 for (auto& x : results) x = REST_StringHelper::CropWithPrecision(x, precision);
2351
2352 return results;
2353}
2354
2359 TString level = "unknown";
2364
2365 return level;
2366}
2367
2391 string result = "";
2392
2393 // If fElement=0 we haven't initialized the class from RML.
2394 // Then we skip adding user paths
2395 if (fElement) {
2396 TiXmlElement* ele = fElement->FirstChildElement("searchPath");
2397 while (ele != nullptr) {
2398 if (ele->Attribute("value") != nullptr) {
2399 result += (string)ele->Attribute("value") + ":";
2400 }
2401 ele = ele->NextSiblingElement("searchPath");
2402 }
2403 }
2404
2405 if (getenv("configPath")) result += getenv("configPath") + (string) ":";
2406 result += REST_PATH + "/data/:";
2407 result += REST_PATH + "/examples/:";
2408 // We give priority to the official /data/ and /examples/ path.
2409 result += REST_USER_PATH + ":";
2410 if (result.back() == ':') result.erase(result.size() - 1);
2411
2412 return ReplaceConstants(ReplaceVariables(result));
2413}
2414
2415Int_t TRestMetadata::Write(const char* name, Int_t option, Int_t bufsize) {
2416 if (fStore) {
2418 return TNamed::Write(name, option, bufsize);
2419 }
2420 return -1;
2421}
2422
2449 // we shall first add all the parameters to a temporary map to avoid
2450 // first parameter being overriden by the repeated parameter section
2451 map<string, string> parameters = GetParametersList();
2452
2453 ReadParametersList(parameters);
2454}
2455
2460void TRestMetadata::ReadParametersList(std::map<string, string>& list) {
2461 for (auto i : list) {
2462 ReadOneParameter(i.first, i.second);
2463 }
2464}
2465
2469std::map<string, string> TRestMetadata::GetParametersList() {
2470 // we shall first add all the parameters to a temporary map to avoid
2471 // first parameter being overriden by the repeated parameter section
2472 map<string, string> parameters;
2473
2474 // Loop over REST_ARGS
2475 auto iter = REST_ARGS.begin();
2476 while (iter != REST_ARGS.end()) {
2477 // if (parameters.count(iter->first) == 0) {
2478 parameters[iter->first] = iter->second;
2479 //}
2480 iter++;
2481 }
2482
2483 // Loop over attribute set
2484 auto paraattr = fElement->FirstAttribute();
2485 while (paraattr != nullptr) {
2486 string name = paraattr->Name();
2487 string value = paraattr->Value();
2488
2489 if (parameters.count(name) == 0) {
2490 parameters[name] = value;
2491 }
2492 // ReadOneParameter((string)name, (string)value);
2493 paraattr = paraattr->Next();
2494 }
2495
2496 // Loop over <parameter section
2497 auto paraele = fElement->FirstChildElement("parameter");
2498 while (paraele != nullptr) {
2499 string name = paraele->Attribute("name");
2500 string value = paraele->Attribute("value");
2501 // In case <parameter section contains units definitions in extra attribute field,
2502 // not together with "value" attribute field
2503 // We should concat the value and units together.
2504 TString units = paraele->Attribute("units");
2505
2506 if (name == "") {
2507 RESTWarning << "bad <parameter section: " << *paraele << RESTendl;
2508 } else {
2509 if (parameters.count(name) == 0) {
2510 parameters[name] = value + units;
2511 }
2512 // ReadOneParameter((string)name, (string)value);
2513 }
2514 paraele = paraele->NextSiblingElement("parameter");
2515 }
2516
2517 return parameters;
2518}
2519
2520void TRestMetadata::ReadOneParameter(string name, string value) {
2521 if (name == "name" || name == "title" || name == "verboseLevel" || name == "type" || name == "value" ||
2522 name == "store") {
2523 // we omit these parameters since they are already loaded in LoadSectionMetadata()
2524 } else {
2525 RESTValue thisactual(this, this->ClassName());
2526 string datamembername = ParameterNameToDataMemberName(name);
2527 if (datamembername != "") {
2528 RESTValue datamember = thisactual.GetDataMember(datamembername);
2529 if (!datamember.IsZombie()) {
2530 RESTDebug << this->ClassName() << "::ReadAllParameters(): parsing value \"" << value
2531 << "\" to data member \"" << datamembername << "\"" << RESTendl;
2532
2533 if (REST_Units::FindRESTUnitsInString(value) != "") {
2534 // there is units contained in this parameter.
2535 string val = REST_Units::RemoveUnitsFromString(value);
2536 string unit = REST_Units::FindRESTUnitsInString(value);
2537
2538 if (datamember.type == "double") {
2539 Double_t value = StringToDouble(val);
2540 *(double*)datamember = REST_Units::ConvertValueToRESTUnits(value, unit);
2541 } else if (datamember.type == "TVector2") {
2542 TVector2 value = StringTo2DVector(val);
2543 Double_t valueX = REST_Units::ConvertValueToRESTUnits(value.X(), unit);
2544 Double_t valueY = REST_Units::ConvertValueToRESTUnits(value.Y(), unit);
2545 *(TVector2*)datamember = TVector2(valueX, valueY);
2546 } else if (datamember.type == "TVector3") {
2547 TVector3 value = StringTo3DVector(val);
2548 Double_t valueX = REST_Units::ConvertValueToRESTUnits(value.X(), unit);
2549 Double_t valueY = REST_Units::ConvertValueToRESTUnits(value.Y(), unit);
2550 Double_t valueZ = REST_Units::ConvertValueToRESTUnits(value.Z(), unit);
2551 *(TVector3*)datamember = TVector3(valueX, valueY, valueZ);
2552 } else {
2553 RESTWarning << this->ClassName() << " find unit definition in parameter: " << name
2554 << ", but the corresponding data member doesn't support it. Data "
2555 "member type: "
2556 << datamember.type << RESTendl;
2557 datamember.ParseString(value);
2558 }
2559 } else {
2560 datamember.ParseString(value);
2561 }
2562 } else if (datamember.name != "") {
2563 // this mean the datamember is found with type not recognized.
2564 // We won't try to find the misspelling
2565 } else {
2566 RESTDebug << this->ClassName() << "::ReadAllParameters(): parameter \"" << name
2567 << "\" not recognized for automatic load" << RESTendl;
2568 vector<string> availableparameters;
2569
2570 vector<string> datamembers = thisactual.GetListOfDataMembers();
2571 for (unsigned int i = 0; i < datamembers.size(); i++) {
2572 string parameter = DataMemberNameToParameterName(datamembers[i]);
2573 if (parameter != "") {
2574 if (parameter == "name" || parameter == "title" || parameter == "verboseLevel" ||
2575 parameter == "type" || parameter == "value" || parameter == "store") {
2576 } else {
2577 availableparameters.push_back(parameter);
2578 }
2579 }
2580 }
2581
2582 int mindiff = 100;
2583 string hintParameter = "";
2584 for (auto parameter : availableparameters) {
2585 int diff = DiffString(name, parameter);
2586 if (diff < mindiff) {
2587 mindiff = diff;
2588 hintParameter = parameter;
2589 }
2590 }
2591
2592 // we regard the unset parameter with less than 2 characters different from
2593 // the data member as "misspelling" parameter. We prompt a warning for it.
2594 if (hintParameter != "" && mindiff <= 2) {
2595 RESTWarning << this->ClassName() << "::ReadAllParameters(): parameter \"" << name
2596 << "\" not recognized for automatic load, did you mean \"" << hintParameter
2597 << "\" ?" << RESTendl;
2598 GetChar();
2599 }
2600 }
2601 }
2602 }
2603}
2604
2605TRestStringOutput& TRestStringOutput::operator<<(endl_t et) {
2606 if (et.TRestMetadataPtr->GetVerboseLevel() <= TRestStringOutput::REST_Verbose_Level::REST_Info) {
2607 et.TRestMetadataPtr->AddLog(this->buf.str());
2608 }
2609
2610 if (this->iserror) {
2611 if (this->verbose == TRestStringOutput::REST_Verbose_Level::REST_Warning) {
2612 et.TRestMetadataPtr->SetWarning(this->buf.str(), false);
2613 }
2615 et.TRestMetadataPtr->SetError(this->buf.str(), false);
2616 }
2617 }
2618
2619 if (et.TRestMetadataPtr->GetVerboseLevel() >= this->verbose) {
2620 this->flushstring();
2621 } else {
2622 this->resetstring();
2623 }
2624
2625 return *this;
2626}
2627
2628void TRestMetadata::AddLog(string log, bool print) {
2629 messageBuffer += log + "\n";
2630 if (messageBuffer.size() > 1000) {
2631 messageBuffer.erase(0, messageBuffer.size() - 1000);
2632 }
2633}
2634
2635void TRestMetadata::SetError(string message, bool print) {
2636 fError = true;
2637 fNErrors++;
2638 if (message != "") {
2639 fErrorMessage += message + "\n";
2640 if (print) {
2641 cout << message << endl;
2642 }
2643 }
2644}
2645
2646void TRestMetadata::SetWarning(string message, bool print) {
2647 fWarning = true;
2648 fNWarnings++;
2649 if (message != "") {
2650 fWarningMessage += message + "\n";
2651 if (print) {
2652 RESTWarning << message << RESTendl;
2653 }
2654 }
2655}
2656
2658 if (GetError())
2659 return fErrorMessage;
2660 else
2661 return "No error!";
2662}
2663
2665 if (GetWarning())
2666 return fWarningMessage;
2667 else
2668 return "No warning!";
2669}
2670
2672 if (!metadata.InheritsFrom(ClassName())) {
2673 RESTError << "TRestMetadata::Merge. Metadata is not of type " << ClassName() << RESTendl;
2674 exit(1);
2675 }
2676
2677 if (fName.IsNull()) {
2678 fName = metadata.GetName();
2679 }
2680}
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)
A base class for any REST metadata class.
Definition: TRestMetadata.h:70
void UnSetVersion()
Resets the version of TRestRun to -1, in case the file is old REST file. Only TRestRun is allowed to ...
std::map< std::string, std::string > fVariables
Saving a list of rml variables. name-value std::pair.
virtual void PrintMetadata()
Implemented it in the derived metadata class to print out specific metadata information.
endl_t RESTendl
Termination flag object for TRestStringOutput.
std::string ElementToString(TiXmlElement *ele)
Convert an TiXmlElement object to string.
TiXmlElement * GetElement(std::string eleDeclare, TiXmlElement *e=nullptr)
Get an xml element from a given parent element, according to its declaration.
virtual void Initialize()
Making default settings.
TString GetSearchPath()
Int_t LoadConfigFromFile(const std::string &configFilename, const std::string &sectionName="")
Give the file name, find out the corresponding section. Then call the main starter.
TiXmlElement * fElementGlobal
Saving the global element, to be passed to the resident class, if necessary.
void PrintMessageBuffer()
Print the buffered message.
std::map< std::string, std::string > GetParametersList()
It retrieves a map of all parameter:value found in the metadata class.
void PrintConfigBuffer()
Print the config xml section stored in the class.
std::string GetUnits(TiXmlElement *e)
Returns a string with the unit name given in the given xml element.
TiXmlElement * GetElementWithName(std::string eleDeclare, std::string eleName, TiXmlElement *e)
Get an xml element from a given parent element, according to its declaration and its field "name".
TRestStringOutput::REST_Verbose_Level fVerboseLevel
Verbose level used to print debug info.
TiXmlElement * StringToElement(std::string definition)
Parsing a string into TiXmlElement object.
TiXmlElement * GetElementFromFile(std::string configFilename, std::string NameOrDecalre="")
Open an xml encoded file and find its element.
TRestMetadata * InstantiateChildMetadata(int index, std::string pattern="")
This method will retrieve a new TRestMetadata instance of a child element of the present TRestMetadat...
Int_t fNErrors
It counts the number of errors notified.
TString GetCommit()
Returns the REST commit value stored in fCommit.
virtual void InitFromConfigFile()
To make settings from rml file. This method must be implemented in the derived class.
TString fErrorMessage
A std::string to store an optional error message through method SetError.
void SetLibraryVersion(TString version)
Set the library version of this metadata class.
void SetError(std::string message="", bool print=true)
A metadata class may use this method to signal that something went wrong.
TString GetVerboseLevelString()
returns the verbose level in type of TString
TRestStringOutput::REST_Verbose_Level GetVerboseLevel()
returns the verboselevel in type of REST_Verbose_Level enumerator
std::string ReplaceVariables(const std::string buffer)
Identifies environmental variable replacing marks in the input buffer, and replace them with correspo...
Int_t LoadConfigFromBuffer()
Initialize data from a string element buffer.
Int_t fNWarnings
It counts the number of warnings notified.
void ReplaceForLoopVars(TiXmlElement *e, std::map< std::string, std::string > forLoopVar)
Helper method for TRestMetadata::ExpandForLoops().
std::string GetFieldValue(std::string parName, TiXmlElement *e)
Returns the field value of an xml element which has the specified name.
std::string messageBuffer
The buffer to store the output message through TRestStringOutput in this class.
virtual void InitFromRootFile()
Method called after the object is retrieved from root file.
Bool_t GetError() const
It returns true if an error was identified by a derived metadata class.
Int_t LoadConfigFromElement(TiXmlElement *eSectional, TiXmlElement *eGlobal, std::map< std::string, std::string > envs={})
Main starter method.
void ReSetVersion()
Resets the version of TRestRun to REST_RELEASE. Only TRestRun is allowed to update version.
TString fWarningMessage
It can be used as a way to identify that something went wrong using SetWarning method.
TiXmlElement * ReplaceElementAttributes(TiXmlElement *e)
replace the field value(attribute) of the given xml element
void SetConfigFile(std::string configFilename)
set config file path from external
std::string GetKEYStructure(std::string keyName)
Gets the first key structure for keyName found inside buffer after fromPosition.
TString GetErrorMessage()
Returns a std::string containing the error message.
void ReadAllParameters()
Reflection methods, Set value of a datamember in class according to TRestMetadata::fElement.
void SetWarning(std::string message="", bool print=true)
A metadata class may use this method to signal that something went wrong.
void SetSectionName(std::string sName)
set the section name, clear the section content
void ExpandIncludeFile(TiXmlElement *e)
Open the given rml file and find the corresponding section.
TString GetWarningMessage()
Returns a std::string containing the warning message.
TString GetVersion()
Returns the REST version stored in fVersion.
std::string SearchFile(std::string filename)
Search files in current directory and directories specified in "searchPath" section.
TString fVersion
REST version std::string, only used for archive and retrieve.
Definition: TRestMetadata.h:85
void ExpandForLoopOnce(TiXmlElement *e, const std::map< std::string, std::string > &forLoopVar)
Helper method for TRestMetadata::ExpandForLoops().
void ReadParametersList(std::map< std::string, std::string > &list)
It reads a parameter list and associates it to its corresponding metadata member. par0 --> fPar0.
void AddLog(std::string log="", bool print=true)
Add logs to messageBuffer.
std::string GetSectionName()
Returns the section name of this class, defined at the beginning of fSectionName.
Bool_t fError
It can be used as a way to identify that something went wrong using SetError method.
std::vector< std::string > GetDataMemberValues(std::string memberName, Int_t precision=0)
Get the value of datamember as a vector of strings.
std::string GetConfigBuffer()
Returns the config section of this class.
virtual void Merge(const TRestMetadata &)
Bool_t fStore
This variable is used to determine if the metadata structure should be stored in the ROOT file.
void ExpandForLoops(TiXmlElement *e, std::map< std::string, std::string > forLoopVar)
Expands the loop structures found in the given xml section.
TRestManager * fHostmgr
All metadata classes can be initialized and managed by TRestManager.
void WriteConfigBuffer(std::string fName)
Writes the config buffer to a file in append mode.
std::string GetDataMemberValue(std::string memberName)
Get the value of data member as string.
void ReadEnvInElement(TiXmlElement *e, bool overwrite=true)
Identify an environmental variable section and add it into env section list.
virtual Int_t LoadSectionMetadata()
This method does some preparation of xml section.
std::string fConfigFileName
Full name of the rml file.
std::string FieldNamesToUpper(std::string inputString)
This method updates all the field names inside the definition string provided by argument to make the...
TString GetLibraryVersion()
Returns the REST libraty version stored in fLibraryVersion.
std::string ReplaceConstants(const std::string buffer)
Identifies "constants" in the input buffer, and replace them with corresponding value.
std::map< std::string, std::string > fConstants
Saving a list of rml constants. name-value std::pair. Constants are temporary for this class only.
std::pair< std::string, std::string > GetParameterAndUnits(std::string parname, TiXmlElement *e=nullptr)
Returns the unit string of the given parameter of the given xml section.
Bool_t fWarning
It can be used as a way to identify that something went wrong using SetWarning method.
TRestMetadata()
TRestMetadata default constructor.
void PrintTimeStamp(Double_t timeStamp)
Print the current time on local machine.
virtual Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0)
overwriting the write() method with fStore considered
void ExpandIfSections(TiXmlElement *e)
Judge the if condition and expands the elements inside it.
void ReadElement(TiXmlElement *e, bool recursive=false)
Read the given xml section, applying rml syntax(if, for, include, etc.)
Bool_t GetWarning() const
It returns true if an error was identified by a derived metadata class.
TiXmlElement * GetNextElement(TiXmlElement *e)
Get the next sibling xml element of this element, with same eleDeclare.
std::string GetParameter(std::string parName, TiXmlElement *e, TString defaultValue=PARAMETER_NOT_FOUND_STR)
Returns the value for the parameter named parName in the given section.
std::string GetKEYDefinition(std::string keyName)
Gets the first key definition for keyName found inside buffer starting at fromPosition.
std::string fSectionName
Section name given in the constructor of the derived metadata class.
std::string configBuffer
The buffer where the corresponding metadata section is stored. Filled only during Write()
TiXmlElement * fElement
Saving the sectional element together with global element.
~TRestMetadata()
TRestMetadata default destructor.
@ REST_Essential
+show some essential information, as well as warnings
@ 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
static std::string Execute(std::string cmd)
Executes a shell command and returns its output in a string.
Definition: TRestTools.cxx:989
static bool fileExists(const std::string &filename)
Returns true if the file (or directory) with path filename exists.
Definition: TRestTools.cxx:674
static int ConvertVersionCode(std::string in)
Convert version to a unique string.
Definition: TRestTools.cxx:966
static std::string DownloadRemoteFile(const std::string &remoteFile)
download the remote file automatically, returns the downloaded file name.
static bool isURL(const std::string &filename)
Returns true if filename is an http address.
Definition: TRestTools.cxx:716
static bool isRootFile(const std::string &filename)
Returns true if the filename has *.root* extension.
Definition: TRestTools.cxx:679
static std::string SearchFileInPath(std::vector< std::string > path, std::string filename)
Search file in the given vector of path strings, return a full name if found, return "" if not.
Definition: TRestTools.cxx:875
This namespace serves to define physics constants and other basic physical operations.
Definition: TRestPhysics.h:34
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.