41#include "TRestDataBase.h" 
   42#include "TRestEventProcess.h" 
   43#include "TRestManager.h" 
   44#include "TRestVersion.h" 
   54TRestRun::TRestRun(
const string& filename) {
 
   55    if (filename.find(
".root") != string::npos) {
 
   58    } 
else if (filename.find(
".rml") != string::npos) {
 
   62        RESTError << 
"TRestRun::TRestRun(): input file error!" << 
RESTendl;
 
   84    fExperimentName = 
"Null";
 
   86    fRunDescription = 
"Null";
 
   88    fInputFileName = 
"null";
 
   89    fOutputFileName = 
"rest_default.root";
 
   97    fInputMetadata.clear();
 
   99    fInputFileNames.clear();
 
  100    fInputFile = 
nullptr;
 
  101    fOutputFile = 
nullptr;
 
  102    fInputEvent = 
nullptr;
 
  103    fAnalysisTree = 
nullptr;
 
  104    fEventTree = 
nullptr;
 
  106    fEventBranchLoc = -1;
 
  107    fFileProcess = 
nullptr;
 
  108    fSaveHistoricData = 
true;
 
 
  123    RESTDebug << 
"Initializing TRestRun from config file, version: " << REST_RELEASE << 
RESTendl;
 
  128    fRunUser = REST_USER;
 
  141    string inputNameOld = 
GetParameter(
"inputFile", 
"default");
 
  142    if (inputNameOld != 
"default") {
 
  143        RESTWarning << 
"Parameter \"inputFile\" in rml is obsolete! Please update it to \"inputFileName\"" 
  145        if (inputName.empty()) {
 
  146            inputName = inputNameOld;
 
  150        RESTError << 
"TRestRun: run number and input file name cannot both be " 
  156    if (
ToUpper(inputName) != 
"AUTO") {
 
  157        fInputFileName = inputName;
 
  161    if (
ToUpper(runNstr) != 
"AUTO") {
 
  162        fRunNumber = atoi(runNstr.c_str());
 
  165    if (
ToUpper(inputName) == 
"AUTO") {
 
  168        fInputFileName = db->
query_run(fRunNumber).value;  
 
  169        fInputFileNames = Vector_cast<DBFile, TString>(files);
 
  172    if (
ToUpper(runNstr) == 
"AUTO") {
 
  176            fRunNumber = runs[0];
 
  182        if (fRunNumber == 0) {
 
  185            entry.runNr = fRunNumber;
 
  186            entry.description = fRunDescription;
 
  188            entry.type = fRunType;
 
  189            entry.version = REST_RELEASE;
 
  195    if (fRunNumber != -1) {
 
  196        DBEntry entry = gDataBase->
query_run(fRunNumber);
 
  197        if (!entry.IsZombie()) {
 
  200            fRunDescription = entry.description;
 
  202            fRunType = entry.type;
 
  206    if (fInputFileNames.empty()) {
 
  207        if (fInputFileName != 
"") {
 
  208            RESTError << 
"cannot find the input file!" << 
RESTendl;
 
  211            RESTWarning << 
"no input file added" << 
RESTendl;
 
  218    string outputName = 
GetParameter(
"outputFileName", 
"default");
 
  219    string outputNameOld = 
GetParameter(
"outputFile", 
"default");
 
  220    if (outputNameOld != 
"default") {
 
  221        RESTWarning << 
"Parameter \"outputFile\" in rml is obsolete! Please update it to \"outputFileName\"" 
  223        if (outputName == 
"default") {
 
  224            outputName = outputNameOld;
 
  227    if (
ToUpper(outputName) == 
"DEFAULT") {
 
  230        char runParentStr[256];
 
  232        char runNumberStr[256];
 
  233        sprintf(runNumberStr, 
"%05d", fRunNumber);
 
  235        fOutputFileName = outputDir + 
"Run_" + expName + 
"_" + fRunUser + 
"_" + runType + 
"_" + fRunTag +
 
  236                          "_" + (TString)runNumberStr + 
"_" + (TString)runParentStr + 
"_V" + REST_RELEASE +
 
  243            fOutputFileName = outputDir + 
"Run_" + expName + 
"_" + fRunUser + 
"_" + runType + 
"_" + fRunTag +
 
  244                              "_" + (TString)runNumberStr + 
"_" + (TString)runParentStr + 
"_V" +
 
  245                              REST_RELEASE + 
".root";
 
  247    } 
else if (
ToUpper(outputName) == 
"NULL" || outputName == 
"/dev/null") {
 
  248        fOutputFileName = 
"/dev/null";
 
  250        fOutputFileName = outputName;
 
  253        fOutputFileName = outputDir + 
"/" + outputName;
 
  259        int z = system((TString) 
"mkdir -p " + outputDir);
 
  260        if (z != 0) RESTError << 
"Problem creating directory : " << outputDir << 
RESTendl;
 
  263        RESTWarning << 
"TRestRun: Output path '" << outputDir << 
"' does not exist or it is not writable." 
  268    TiXmlElement* e = 
fElement->FirstChildElement();
 
  269    while (e != 
nullptr) {
 
  270        string key = e->Value();
 
  271        if (key == 
"addMetadata") {
 
  272            if (e->Attribute(
"file") != 
nullptr) {
 
  273                ImportMetadata(e->Attribute(
"file"), e->Attribute(
"name"), e->Attribute(
"type"), 
true);
 
  275                RESTWarning << 
"Wrong definition of addMetadata! Metadata name or file name " 
  279        } 
else if (
Count(key, 
"TRest") > 0) {
 
  281                RESTWarning << 
"TRestRun: A root file is being included in section <" << key
 
  282                            << 
" ! To import metadata from this file, use <addMetadata" << 
RESTendl;
 
  283                RESTWarning << 
"Skipping..." << 
RESTendl;
 
  287            if (meta == 
nullptr) {
 
  288                RESTWarning << 
"failed to add metadata \"" << key << 
"\"" << 
RESTendl;
 
  289                e = e->NextSiblingElement();
 
  294            fMetadata.push_back(meta);
 
  297        e = e->NextSiblingElement();
 
  303    RESTDebug << 
"TRestRun::EndOfInit. InputFile pattern: \"" << fInputFileName << 
"\"" << 
RESTendl;
 
  304    RESTInfo << 
"which matches :" << 
RESTendl;
 
  305    for (
const auto& inputFileName : fInputFileNames) {
 
  306        RESTInfo << inputFileName << 
RESTendl;
 
  308    RESTEssential << 
"(" << fInputFileNames.size() << 
" added files)" << 
RESTendl;
 
 
  315    if (fInputFileNames.size() > (
unsigned int)i) {
 
  316        TString Filename = fInputFileNames[i];
 
  317        RESTInfo << 
"opening... " << Filename << 
RESTendl;
 
 
  334        RESTError << 
"input file \"" << filename << 
"\" does not exist!" << 
RESTendl;
 
  338    if (!filename.Contains(
"http")) 
ReadFileInfo((
string)filename);
 
  342    for (
const auto& inputFileName : fInputFileNames) {
 
  343        if (inputFileName == filename) {
 
  350        fInputFileNames.push_back(filename);
 
  354        fInputFile = TFile::Open(filename, mode.c_str());
 
  356        if (GetMetadataClass(
"TRestRun", fInputFile)) {
 
  358            TString runTypeTmp = fRunType;
 
  360            TString runTagTmp = fRunTag;
 
  361            TString runDescriptionTmp = fRunDescription;
 
  362            TString experimentNameTmp = fExperimentName;
 
  363            TString outputFileNameTmp = fOutputFileName;
 
  364            TString inputFileNameTmp = fInputFileName;
 
  374            this->Read(GetMetadataClass(
"TRestRun", fInputFile)->GetName());
 
  376            if (inputFileNameTmp != 
"null") fInputFileName = inputFileNameTmp;
 
  377            if (outputFileNameTmp != 
"rest_default.root") fOutputFileName = outputFileNameTmp;
 
  383                if (runTypeTmp != 
"Null" && runTypeTmp != 
"preserve") fRunType = runTypeTmp;
 
  390                if (runTagTmp != 
"Null" && runTagTmp != 
"preserve") fRunTag = runTagTmp;
 
  391                if (runDescriptionTmp != 
"Null" && runDescriptionTmp != 
"preserve")
 
  392                    fRunDescription = runDescriptionTmp;
 
  393                if (experimentNameTmp != 
"Null" && experimentNameTmp != 
"preserve")
 
  394                    fExperimentName = experimentNameTmp;
 
  401            if (fSaveHistoricData) {
 
  402                if (this->GetVersionCode() >= REST_VERSION(2, 2, 1) ||
 
  403                    this->GetVersionCode() <= REST_VERSION(2, 1, 8)) {
 
  404                    ReadInputFileMetadata();
 
  406                    RESTWarning << 
"-- W : The metadata version found on input file is lower " 
  409                    RESTWarning << 
"-- W : metadata from input file will not be read" << 
RESTendl;
 
  413            RESTDebug << 
"Initializing input file : version code : " << this->GetVersionCode() << 
RESTendl;
 
  415            ReadInputFileTrees();
 
  418            RESTWarning << 
"TRestRun object not found in file! The input file may be incomplete!" << 
RESTendl;
 
  419            ReadInputFileTrees();
 
  422        fInputFile = 
nullptr;
 
  423        fAnalysisTree = 
nullptr;
 
  424        if (fFileProcess != 
nullptr) {
 
  425            fFileProcess->OpenInputFiles(Vector_cast<TString, string>(fInputFileNames));
 
  430    if (fAnalysisTree == 
nullptr && fFileProcess == 
nullptr)
 
  431        RESTInfo << 
"Input file is not REST root file, an external process is needed!" << 
RESTendl;
 
 
  434void TRestRun::AddInputFileExternal(
const string& file) {
 
  436    if (fFileProcess != 
nullptr) {
 
  437        bool add = fFileProcess->AddInputFile(file);
 
  439            RESTError << 
"failed to add input file!" << 
RESTendl;
 
  441        fInputFileNames.emplace_back(file);
 
  446void TRestRun::ReadInputFileMetadata() {
 
  447    TFile* f = fInputFile;
 
  449        fInputMetadata.clear();
 
  451        TIter nextkey(f->GetListOfKeys());
 
  454        set<string> addedNames;
 
  455        while ((key = (TKey*)nextkey())) {
 
  456            RESTDebug << 
"Reading key with name : " << key->GetName() << 
RESTendl;
 
  457            RESTDebug << 
"Key type (class) : " << key->GetClassName() << 
RESTendl;
 
  459            if (!TClass::GetClass(key->GetClassName()) ||
 
  460                !TClass::GetClass(key->GetClassName())->IsLoaded()) {
 
  461                RESTError << 
"-- Class " << key->GetClassName() << 
" has no dictionary!" << 
RESTendl;
 
  462                RESTError << 
"- Any relevant REST library missing? " << 
RESTendl;
 
  463                RESTError << 
"- File reading will continue without loading key: " << key->GetName()
 
  468            if (addedNames.count(key->GetName()) != 0) {
 
  473            RESTDebug << 
"Key of type : " << a->ClassName() << 
"(" << a << 
")" << 
RESTendl;
 
  476                RESTError << 
"TRestRun::ReadInputFileMetadata." << 
RESTendl;
 
  477                RESTError << 
"Key name : " << key->GetName() << 
RESTendl;
 
  478                RESTError << 
"Hidden key? Please, report this problem." << 
RESTendl;
 
  479            } 
else if (a->InheritsFrom(
"TRestMetadata") && a->ClassName() != (TString) 
"TRestRun") {
 
  499                fInputMetadata.push_back(a);
 
  500                fMetadata.push_back(a);
 
  501                addedNames.insert(key->GetName());
 
  507void TRestRun::ReadInputFileTrees() {
 
  508    if (fInputFile != 
nullptr) {
 
  509        RESTDebug << 
"Finding TRestAnalysisTree.." << 
RESTendl;
 
  510        TTree* _eventTree = 
nullptr;
 
  511        string filename = fInputFile->GetName();
 
  513        if (fInputFile->Get(
"AnalysisTree") != 
nullptr) {
 
  516            if (fNFilesSplit > 0) {  
 
  517                RESTEssential << 
"Linking analysis tree from split data files" << 
RESTendl;
 
  520                for (
int i = 1; i <= fNFilesSplit; i++) {
 
  521                    string filename = fInputFile->GetName() + (string) 
"." + ToString(i);
 
  522                    RESTInfo << filename << 
" --> ";
 
  525                if (fAnalysisTree->GetChain() == 
nullptr ||
 
  526                    fAnalysisTree->GetChain()->GetNtrees() != fNFilesSplit + 1) {
 
  527                    RESTError << 
"Error adding split files, files missing?" << 
RESTendl;
 
  528                    RESTError << 
"Your data could be incomplete!" << 
RESTendl;
 
  535            fAnalysisTree->GetEntries();
 
  537            fAnalysisTree->GetEntry(0);
 
  539            _eventTree = (TTree*)fInputFile->Get(
"EventTree");
 
  540        } 
else if (fInputFile->FindKey(
"TRestAnalysisTree") != 
nullptr) {
 
  544            RESTWarning << 
"Loading root file from old version REST!" << 
RESTendl;
 
  546            fAnalysisTree->GetEntry(0);
 
  548            TIter nextkey(fInputFile->GetListOfKeys());
 
  550            while ((key = (TKey*)nextkey())) {
 
  552                if (((
string)key->GetName()).find(
"EventTree") != string::npos) {
 
  553                    _eventTree = (TTree*)fInputFile->Get(key->GetName());
 
  554                    string eventName = 
Replace(key->GetName(), 
"Tree", 
"", 0);
 
  555                    TBranch* br = _eventTree->GetBranch(
"eventBranch");
 
  556                    br->SetName((eventName + 
"Branch").c_str());
 
  557                    br->SetTitle((eventName + 
"Branch").c_str());
 
  561            RESTDebug << 
"Old REST file successfully recovered!" << 
RESTendl;
 
  563            RESTWarning << 
"(OpenInputFile) : AnalysisTree was not found" << 
RESTendl;
 
  564            RESTWarning << 
"Inside file : " << filename << 
RESTendl;
 
  565            RESTWarning << 
"This may not be a REST output file!" << 
RESTendl;
 
  568        if (_eventTree != 
nullptr) {
 
  569            if (fNFilesSplit > 0) {
 
  572                RESTEssential << 
"Linking event tree from split data files" << 
RESTendl;
 
  573                TChain* _fEventTree = 
new TChain(
"EventTree");
 
  574                RESTInfo << fInputFile->GetName() << 
" --> ";
 
  575                RESTInfo << (_fEventTree->Add(fInputFile->GetName()) ? 
"success" : 
"failed") << 
RESTendl;
 
  577                for (
int i = 1; i <= fNFilesSplit; i++) {
 
  578                    string filename = fInputFile->GetName() + (string) 
"." + ToString(i);
 
  579                    RESTInfo << filename << 
" --> ";
 
  580                    RESTInfo << (_fEventTree->Add(filename.c_str()) ? 
"success" : 
"failed") << 
RESTendl;
 
  582                fEventTree = _fEventTree;
 
  584                fEventTree = _eventTree;
 
  587            RESTDebug << 
"Finding event branch.." << 
RESTendl;
 
  588            if (fInputEvent == 
nullptr) {
 
  589                TObjArray* branches = fEventTree->GetListOfBranches();
 
  591                if (branches->GetLast() > -1) {
 
  592                    TBranch* br = (TBranch*)branches->At(branches->GetLast());
 
  594                    if (br == 
nullptr || 
Count(br->GetName(), 
"EventBranch") == 0) {
 
  595                        RESTInfo << 
"No event branch inside file : " << filename << 
RESTendl;
 
  596                        RESTInfo << 
"This file may be a pure analysis file" << 
RESTendl;
 
  598                        string type = 
Replace(br->GetName(), 
"Branch", 
"", 0);
 
  599                        TClass* cl = TClass::GetClass(type.c_str());
 
  600                        if (cl->HasDictionary()) {
 
  602                        } 
else if (fInputEvent != 
nullptr) {
 
  604                            fInputEvent = 
nullptr;
 
  607                        if (fInputEvent == 
nullptr) {
 
  608                            RESTError << 
"TRestRun:OpenInputFile. Cannot initialize input event, event " 
  612                                << 
"Please install corresponding libraries to provide root dictionaries for " 
  618                        fInputEvent->InitializeWithMetadata(
this);
 
  619                        fEventTree->SetBranchAddress(br->GetName(), &fInputEvent);
 
  620                        fEventBranchLoc = branches->GetLast();
 
  621                        RESTDebug << 
"found event branch of event type: " << fInputEvent->ClassName()
 
  626                string brname = (string)fInputEvent->ClassName() + 
"Branch";
 
  627                if (fEventTree->GetBranch(brname.c_str()) == 
nullptr) {
 
  628                    RESTWarning << 
"REST WARNING (OpenInputFile) : No matched event branch " 
  631                    RESTWarning << 
"Branch required: " << brname << 
RESTendl;
 
  633                    fEventTree->SetBranchAddress(brname.c_str(), &fInputEvent);
 
  634                    RESTDebug << brname << 
" is found and set!" << 
RESTendl;
 
  638            RESTDebug << 
"TRestRun:OpenInputFile. EventTree was not found" << 
RESTendl;
 
  639            RESTDebug << 
"This is a pure analysis file!" << 
RESTendl;
 
  640            fInputEvent = 
nullptr;
 
  653    RESTDebug << 
"begin collecting basic file info..." << filename << 
RESTendl;
 
  657    FILE* fp = fopen(filename.c_str(), 
"rb");
 
  659        RESTError << 
"TRestRun::ReadFileInfo. Something went wrong with fopen()!" << strerror(errno)
 
  671        fTotalBytes = buf.st_size;
 
  674    RESTDebug << 
"begin matching file name pattern for more file info..." << 
RESTendl;
 
  682    vector<string> formatSectionList;
 
  683    vector<string> formatPrefixList;
 
  689        pos1 = format.find(
"[", pos + 1);
 
  690        pos2 = format.find(
"]", pos1);
 
  691        if (pos1 == -1 || pos2 == -1) {
 
  692            formatPrefixList.push_back(format.substr(pos + 1, -1));
 
  696        formatSectionList.push_back(format.substr(pos1 + 1, pos2 - pos1 - 1));
 
  697        formatPrefixList.push_back(format.substr(pos + 1, pos1 - pos - 1));
 
  703    for (
unsigned int i = 0; i < formatSectionList.size() && i < formatPrefixList.size() - 1; i++) {
 
  704        if (i != 0 && formatPrefixList[i].empty()) {
 
  705            RESTWarning << 
"file format reference contains error!" << 
RESTendl;
 
  708        int pos1 = name.find(formatPrefixList[i], pos + 1) + formatPrefixList[i].size();
 
  709        if (formatPrefixList[i].empty()) pos1 = 0;
 
  710        int pos2 = name.find(formatPrefixList[i + 1], pos1);
 
  711        if (formatPrefixList[i + 1].empty()) pos2 = name.length();
 
  712        if (pos1 == -1 || pos2 == -1) {
 
  713            RESTWarning << 
"File pattern matching: file format mismatch!" << 
RESTendl;
 
  717        string infoFromFileName = name.substr(pos1, pos2 - pos1);
 
  719        RESTDebug << 
"File pattern matching. key: " << formatSectionList[i] << 
" (between the mark \"" 
  720                  << formatPrefixList[i] << 
"\" and \"" << formatPrefixList[i + 1]
 
  721                  << 
"\"), value: " << infoFromFileName << 
RESTendl;
 
  724        bool inforead = 
false;
 
  733                    RESTWarning << 
"TRestRun: file name format field \"" << formatSectionList[i]
 
  734                                << 
"\"(value = " << infoFromFileName
 
  735                                << 
") not registered, data member does not exist in TRestRun!" << 
RESTendl;
 
  743            vector<string> classDataMember = 
Split(formatSectionList[i], 
"::");
 
  744            if (classDataMember.size() > 1) {
 
  746                if (meta != 
nullptr) {
 
  753                        RESTWarning << 
"TRestRun: file name format field \"" << formatSectionList[i]
 
  754                                    << 
"\"(value = " << infoFromFileName
 
  755                                    << 
") not registered, metadata exist but without such datamember field!" 
  759                    RESTWarning << 
"TRestRun: file name format field \"" << formatSectionList[i]
 
  760                                << 
"\"(value = " << infoFromFileName
 
  761                                << 
") not registered, metadata does not exist!" << 
RESTendl;
 
 
  783    if (fFileProcess != 
nullptr) {
 
  784        fFileProcess->ResetEntry();
 
 
  797    bool messageShown = 
false;
 
  800    if (fFileProcess != 
nullptr) {
 
  801        RESTDebug << 
"TRestRun: getting next event from external process" << 
RESTendl;
 
  815        if (eve == 
nullptr) {
 
  816            RESTDebug << 
"TRestRun::GetNextEvent(): input event has not been initialized!" << 
RESTendl;
 
  818            RESTDebug << 
"TRestRun: getting next event from root file" << 
RESTendl;
 
  819            if (fAnalysisTree == 
nullptr) {
 
  820                RESTWarning << 
"error to get event from input file, missing analysis tree from input file" 
  824                if (fCurrentEvent >= fAnalysisTree->
GetTree()->GetEntriesFast()) {
 
  827                    if (targetTree != 
nullptr) {
 
  830                        fBytesRead += fAnalysisTree->GetEntry(fCurrentEvent);
 
  831                        targetTree->SetEventInfo(fAnalysisTree);
 
  832                        for (
int n = 0; n < fAnalysisTree->GetNumberOfObservables(); n++)
 
  833                            targetTree->
SetObservable(n, fAnalysisTree->GetObservable(n));
 
  835                    if (fEventTree != 
nullptr) {
 
  836                        if (fEventTree->IsA() == TChain::Class()) {
 
  837                            Long64_t entry = fEventTree->LoadTree(fCurrentEvent);
 
  838                            fBytesRead += ((TBranch*)fEventTree->GetTree()->GetListOfBranches()->UncheckedAt(
 
  843                                ((TBranch*)fEventTree->GetListOfBranches()->UncheckedAt(fEventBranchLoc))
 
  855    if (eve == 
nullptr) {
 
  856        if (fHangUpEndFile && fFileProcess != 
nullptr) {
 
  860                RESTEssential << 
"external process file reading reaches end, waiting for more files" 
  875    if (fInputEvent->GetID() == 0 && fInputEvent->GetSubID() == 0) {
 
  876        fInputEvent->SetID(fCurrentEvent - 1);
 
  879    if (fInputEvent->GetRunOrigin() == 0) {
 
  880        fInputEvent->SetRunOrigin(fRunNumber);
 
  884    fInputEvent->
CloneTo(targetEvent);
 
 
  893    std::vector<std::string> list;
 
  894    TObjArray* branches = GetEventTree()->GetListOfBranches();
 
  895    for (
int i = 0; i <= branches->GetLast(); i++) {
 
  896        auto branch = (TBranch*)branches->At(i);
 
  897        if (((std::string)branch->GetName()).find(
"EventBranch") != string::npos) {
 
  898            std::string eventType = 
Replace((
string)branch->GetName(), 
"Branch", 
"");
 
  899            list.emplace_back(eventType);
 
 
  909    if (entry >= GetEntries()) {
 
  910        RESTWarning << 
"TRestRun::GetEntry. Entry requested out of limits" << 
RESTendl;
 
  911        RESTWarning << 
"Total number of entries is : " << GetEntries() << 
RESTendl;
 
  914    if (fAnalysisTree != 
nullptr) {
 
  915        fAnalysisTree->GetEntry(entry);
 
  917    if (fEventTree != 
nullptr) {
 
  918        fEventTree->GetEntry(entry);
 
  921    if (fInputEvent != 
nullptr) {
 
  925    fCurrentEvent = entry;
 
 
  941    string inString = (string)FilenameFormat;
 
  942    string outString = (string)FilenameFormat;
 
  944    RESTDebug << 
"TRestRun::FormFormat. In string : " << inString << 
RESTendl;
 
  948        int pos1 = inString.find(
"[", pos);
 
  949        int pos2 = inString.find(
"]", pos1);
 
  950        if (pos1 == -1 || pos2 == -1) 
break;
 
  952        string targetstr = inString.substr(pos1, pos2 - pos1 + 1);   
 
  953        string target = inString.substr(pos1 + 1, pos2 - pos1 - 1);  
 
  954        string replacestr = GetRunInformation(target);
 
  956        RESTDebug << 
"TRestRun::FormFormat. target : " << target << 
RESTendl;
 
  957        RESTDebug << 
"TRestRun::FormFormat. replacestr : " << replacestr << 
RESTendl;
 
  962        if (target == 
"fVersion") replacestr = (string)REST_RELEASE;
 
  963        if (target == 
"fCommit") replacestr = (string)REST_COMMIT;
 
  965        if (replacestr != target) {
 
  966            if (target == 
"fRunNumber" || target == 
"fParentRunNumber") {
 
  969            outString = 
Replace(outString, targetstr, replacestr, 0);
 
 
  986    RESTDebug << 
"TRestRun::FormOutputFile. target : " << outputfilename << 
RESTendl;
 
  988    TFileMerger* m = 
new TFileMerger(
false);
 
  989    if (outputfilename.empty()) {
 
  990        filename = fOutputFileName;
 
  991        RESTInfo << 
"Creating file : " << filename << 
RESTendl;
 
  992        m->OutputFile(filename.c_str(), 
"RECREATE");
 
  994        filename = outputfilename;
 
  995        RESTInfo << 
"Updating file : " << filename << 
RESTendl;
 
  996        m->OutputFile(filename.c_str(), 
"UPDATE");
 
  999    RESTDebug << 
"TRestRun::FormOutputFile. Starting to add files" << 
RESTendl;
 
 1001    for (
unsigned int i = 0; i < filenames.size(); i++) {
 
 1002        m->AddFile(filenames[i].c_str(), 
false);
 
 1006        for (
unsigned int i = 0; i < filenames.size(); i++) {
 
 1007            remove(filenames[i].c_str());
 
 1010        fOutputFileName = 
"";
 
 1011        RESTError << 
"(Merge files) failed to merge process files." << 
RESTendl;
 
 1019    rename(filename.c_str(), fOutputFileName);
 
 1022    fOutputFile = 
new TFile(fOutputFileName, 
"update");
 
 1023    RESTDebug << 
"TRestRun::FormOutputFile. Calling WriteWithDataBase()" << 
RESTendl;
 
 1026    RESTcout << this->ClassName() << 
" Created ..." << 
RESTendl;
 
 
 1039    fOutputFileName = 
FormFormat(fOutputFileName);
 
 1041    fOutputFileName = std::filesystem::weakly_canonical(fOutputFileName.Data());
 
 1043    fOutputFile = 
new TFile(fOutputFileName, 
"recreate");
 
 1045    fEventTree = 
new TTree(
"EventTree", 
"EventTree");
 
 1047    fAnalysisTree->Write(
nullptr, TObject::kOverwrite);
 
 1048    fEventTree->Write(
nullptr, TObject::kOverwrite);
 
 1051    RESTcout << 
"TRestRun: Output File Created." << 
RESTendl;
 
 
 1058TFile* TRestRun::UpdateOutputFile() {
 
 1059    if (fOutputFile != 
nullptr) {
 
 1060        if (fOutputFile->IsOpen()) {
 
 1061            fOutputFile->ReOpen(
"update");
 
 1066        fAnalysisTree->Write(
nullptr, kOverwrite);
 
 1067        fEventTree->Write(
nullptr, kOverwrite);
 
 1071        RESTcout << 
"TRestRun: Output File Updated." << 
RESTendl;
 
 1078        RESTError << 
"TRestRun::UpdateOutputFile(): output file is closed" << 
RESTendl;
 
 1095    RESTDebug << 
"TRestRun::WriteWithDataBase. Getting entries in analysisTree" << 
RESTendl;
 
 1099    if (fOutputFile != 
nullptr) {
 
 1101        if (tree != 
nullptr) {
 
 1102            fEntriesSaved = tree->GetEntries();
 
 1105    RESTDebug << 
"TRestRun::WriteWithDataBase. Entries found : " << fEntriesSaved << 
RESTendl;
 
 1114    fRunUser = REST_USER;
 
 1118    RESTDebug << 
"TRestRun::WriteWithDataBase. Calling this->Write(0, kOverwrite)" << 
RESTendl;
 
 1119    this->
Write(
nullptr, kOverwrite);
 
 1121    RESTDebug << 
"TRestRun::WriteWithDataBase. Succeed" << 
RESTendl;
 
 1122    RESTDebug << 
"TRestRun::WriteWithDataBase. fMetadata.size() == " << fMetadata.size() << 
RESTendl;
 
 1123    for (
auto& metadata : fMetadata) {
 
 1124        bool historic = 
false;
 
 1125        RESTDebug << 
"TRestRun::WriteWithDataBase. fInputMetadata.size() == " << fInputMetadata.size()
 
 1127        for (
const auto& inputMetadata : fInputMetadata) {
 
 1128            RESTDebug << metadata->GetName() << 
" == " << inputMetadata->GetName() << 
RESTendl;
 
 1129            if (metadata == inputMetadata) {
 
 1136            RESTDebug << 
"NO historic" << 
RESTendl;
 
 1137            metadata->Write(metadata->GetName(), kOverwrite);
 
 1139            RESTDebug << 
"IS historic" << 
RESTendl;
 
 1140            if (fSaveHistoricData) metadata->Write(metadata->GetName(), kOverwrite);
 
 1145    RESTDebug << 
"TResRun::WriteWithDataBase. Run number is : " << fRunNumber << 
RESTendl;
 
 1146    if (fRunNumber != -1) {
 
 1147        int fileid = gDataBase->
set_runfile(fRunNumber, (
string)fOutputFileName);
 
 1148        RESTcout << 
"DataBase Entry Added! Run Number: " << fRunNumber << 
", File ID: " << fileid << 
RESTendl;
 
 
 1157    if (fAnalysisTree != 
nullptr) {
 
 1158        fEntriesSaved = fAnalysisTree->GetEntries();
 
 1159        if (fAnalysisTree->GetEntries() > 0 && fInputFile == 
nullptr) {
 
 1160            if (fOutputFile != 
nullptr) {
 
 1162                fAnalysisTree->Write(
nullptr, kOverwrite);
 
 1163                this->
Write(
nullptr, kOverwrite);
 
 1166        delete fAnalysisTree;
 
 1167        fAnalysisTree = 
nullptr;
 
 1170    if (fEventTree != 
nullptr) {
 
 1171        if (fEventTree->GetEntries() > 0 && fInputFile == 
nullptr) fEventTree->Write(
nullptr, kOverwrite);
 
 1173        fEventTree = 
nullptr;
 
 1176    for (
unsigned int i = 0; i < fMetadata.size(); i++) {
 
 1177        for (
unsigned int j = 0; j < fInputMetadata.size(); j++) {
 
 1178            if (fMetadata[i] == fInputMetadata[j]) {
 
 1179                delete fMetadata[i];
 
 1180                fMetadata.erase(fMetadata.begin() + i);
 
 1182                fInputMetadata.erase(fInputMetadata.begin() + j);
 
 1188    if (fOutputFile != 
nullptr) {
 
 1189        fOutputFile->Write(0, TObject::kOverwrite);
 
 1190        fOutputFile->Close();
 
 1192        fOutputFile = 
nullptr;
 
 1194    if (fInputFile != 
nullptr) {
 
 1195        fInputFile->Close();
 
 1196        fInputFile = 
nullptr;
 
 
 1204    if (fFileProcess == 
nullptr && p != 
nullptr) {
 
 1207        fFileProcess->OpenInputFiles(Vector_cast<TString, string>(fInputFileNames));
 
 1210        if (fInputEvent == 
nullptr) {
 
 1211            RESTError << 
"The external process \"" << p->GetName() << 
"\" doesn't yield any output event!" 
 1215            fInputEvent->SetRunOrigin(fRunNumber);
 
 1219        fInputFile = 
nullptr;
 
 1221        fAnalysisTree = 
new TRestAnalysisTree(
"externalProcessAna", 
"externalProcessAna");
 
 1227        RESTInfo << 
"The external file process has been set! Name : " << fFileProcess->GetName() << 
RESTendl;
 
 1229        if (fFileProcess != 
nullptr) {
 
 1230            RESTError << 
"There can only be one file process!" << 
RESTendl;
 
 1234            RESTWarning << 
"Given file process is null, skipping..." << 
RESTendl;
 
 
 1246    if (event != 
nullptr) {
 
 1247        if (fEventTree != 
nullptr) {
 
 1248            if (fInputEvent != 
nullptr) {
 
 1249                fEventTree->SetBranchAddress((TString)fInputEvent->ClassName() + 
"Branch", 
nullptr);
 
 1250                fEventTree->SetBranchStatus((TString)fInputEvent->ClassName() + 
"Branch", 
false);
 
 1252            TObjArray* branches = fEventTree->GetListOfBranches();
 
 1253            string branchName = (string)event->ClassName() + 
"Branch";
 
 1254            for (
int i = 0; i <= branches->GetLast(); i++) {
 
 1255                auto branch = (TBranch*)branches->At(i);
 
 1256                if ((
string)branch->GetName() == branchName) {
 
 1257                    RESTDebug << 
"Setting input event.. Type: " << 
event->ClassName() << 
" Address: " << 
event 
 1259                    fInputEvent = event;
 
 1260                    fEventTree->SetBranchAddress(branchName.c_str(), &fInputEvent);
 
 1261                    fEventTree->SetBranchStatus(branchName.c_str(), 
false);
 
 1262                    fEventBranchLoc = i;
 
 1264                } 
else if (i == branches->GetLast()) {
 
 1265                    RESTWarning << 
"REST Warning : (TRestRun) cannot find corresponding " 
 1266                                   "branch in event tree!" 
 1268                    RESTWarning << 
"Event Type : " << 
event->ClassName() << 
RESTendl;
 
 1269                    RESTWarning << 
"Input event not set!" << 
RESTendl;
 
 1273            fInputEvent = event;
 
 
 1283    if (event != 
nullptr) {
 
 1284        if (fEventTree != 
nullptr) {
 
 1285            string eventName = (string)event->ClassName();
 
 1286            string branchName = eventName + 
"Branch";
 
 1287            fEventTree->Branch(branchName.c_str(), event);
 
 1288            fEventTree->SetTitle((eventName + 
"Tree").c_str());
 
 
 1299    const TString thisFile = 
SearchFile(File.Data());
 
 1300    if (thisFile == 
"") {
 
 1301        RESTError << 
"(ImportMetadata): The file " << thisFile << 
" does not exist!" << 
RESTendl;
 
 1306        RESTError << 
"(ImportMetadata) : The file " << thisFile << 
" is not root file!" << 
RESTendl;
 
 1307        RESTError << 
"If you want to initialize metadata from rml file, use <TRest section!" << 
RESTendl;
 
 1311    TFile* file = TFile::Open(thisFile);
 
 1313    if (type == 
"" && name == 
"") {
 
 1314        RESTError << 
"(ImportMetadata) : metadata type and name is not " 
 1322        meta = GetMetadata(name, file);
 
 1323    } 
else if (type != 
"") {
 
 1324        meta = GetMetadataClass(type, file);
 
 1327    if (meta == 
nullptr) {
 
 1328        cout << 
"REST ERROR (ImportMetadata) : " << name << 
" does not exist." << endl;
 
 1329        cout << 
"Inside root file : " << File << endl;
 
 1341    fMetadata.push_back(meta);
 
 
 1352Double_t TRestRun::GetRunLength()
 const {
 
 1354        cout << 
"Run time is not set\n";
 
 1359Long64_t TRestRun::GetTotalBytes() {
 
 1360    if (fFileProcess != 
nullptr) {
 
 1366Long64_t TRestRun::GetEntries()
 const {
 
 1367    if (fAnalysisTree != 
nullptr) {
 
 1368        return fAnalysisTree->GetEntries();
 
 1370    return fEntriesSaved;
 
 1375TRestEvent* TRestRun::GetEventWithID(Int_t eventID, Int_t subEventID, 
const TString& tag) {
 
 1376    if (fAnalysisTree != 
nullptr) {
 
 1377        int nEntries = fAnalysisTree->GetEntries();
 
 1380        fAnalysisTree->SetBranchStatus(
"*", 
false);
 
 1381        fAnalysisTree->SetBranchStatus(
"eventID", 
true);
 
 1382        fAnalysisTree->SetBranchStatus(
"subEventID", 
true);
 
 1383        fAnalysisTree->SetBranchStatus(
"subEventTag", 
true);
 
 1387        for (
int i = 0; i < nEntries; i++) {
 
 1388            fAnalysisTree->GetEntry(i);
 
 1389            if (fAnalysisTree->GetEventID() == eventID) {
 
 1390                if (subEventID != -1 && fAnalysisTree->GetSubEventID() != subEventID) 
continue;
 
 1391                if (tag != 
"" && fAnalysisTree->GetSubEventTag() != tag) 
continue;
 
 1392                if (fEventTree != 
nullptr) fEventTree->GetEntry(i);
 
 1393                fAnalysisTree->SetBranchStatus(
"*", 
true);
 
 1394                fAnalysisTree->GetEntry(i);
 
 1400        fAnalysisTree->SetBranchStatus(
"*", 
true);
 
 1405std::vector<int> TRestRun::GetEventEntriesWithConditions(
const string& cuts, 
int startingIndex,
 
 1407    int max = maxNumber;
 
 1408    if (max < 0) max = GetEntries();
 
 1410    std::vector<int> eventIds;
 
 1412    std::vector<string> observables;
 
 1413    std::vector<string> operators;
 
 1414    std::vector<Double_t> values;
 
 1416    const std::vector<string> validOperators = {
"==", 
"<=", 
">=", 
"=", 
">", 
"<"};
 
 1418    vector<string> cutsVector = 
Split(cuts, 
"&&", 
false, 
true);
 
 1420    for (
unsigned int i = 0; i < cutsVector.size(); i++) {
 
 1421        string cut = cutsVector[i];
 
 1422        for (
unsigned int j = 0; j < validOperators.size(); j++) {
 
 1423            if (cut.find(validOperators[j]) != string::npos) {
 
 1424                operators.push_back(validOperators[j]);
 
 1425                observables.push_back((
string)cut.substr(0, cut.find(validOperators[j])));
 
 1426                values.push_back(std::stod((
string)cut.substr(
 
 1427                    cut.find(validOperators[j]) + validOperators[j].length(), string::npos)));
 
 1434    if (fAnalysisTree == 
nullptr) {
 
 1437    Int_t nEntries = fAnalysisTree->GetEntries();
 
 1438    auto branches = fAnalysisTree->GetListOfBranches();
 
 1439    std::set<string> branchNames;
 
 1440    for (
int i = 0; i < branches->GetEntries(); i++) {
 
 1441        branchNames.insert((
string)branches->At(i)->GetName());
 
 1444    for (
unsigned int i = 0; i < observables.size(); i++) {
 
 1446        if (std::find(validOperators.begin(), validOperators.end(), operators[i]) == validOperators.end()) {
 
 1448            cout << 
"invalid operation '" << operators[i] << 
"' for 'TRestRun::GetEventIdsWithConditions'" 
 1453        if (branchNames.count(observables[i]) == 0) {
 
 1455            cout << 
"invalid observable '" << observables[i] << 
"' for 'TRestRun::GetEventIdsWithConditions'" 
 1457            cout << 
"valid branch names: ";
 
 1458            for (
auto branchName : branchNames) {
 
 1459                cout << branchName << 
" ";
 
 1466    fAnalysisTree->SetBranchStatus(
"*", 
false);
 
 1467    for (
unsigned int i = 0; i < observables.size(); i++) {
 
 1468        fAnalysisTree->SetBranchStatus(observables[i].c_str(), 
true);
 
 1471    Double_t valueToCompareFrom;
 
 1472    bool comparisonResult;
 
 1474    for (
int iNoOffset = 0; iNoOffset < nEntries; iNoOffset++) {
 
 1475        i = (iNoOffset + startingIndex) % nEntries;
 
 1476        fAnalysisTree->GetEntry(i);
 
 1477        comparisonResult = 
true;
 
 1478        for (
unsigned int j = 0; j < observables.size(); j++) {
 
 1480            if (operators[j] == 
"=" || operators[j] == 
"==") {
 
 1481                comparisonResult = comparisonResult && (valueToCompareFrom == values[j]);
 
 1482            } 
else if (operators[j] == 
"<") {
 
 1483                comparisonResult = comparisonResult && (valueToCompareFrom < values[j]);
 
 1484            } 
else if (operators[j] == 
"<=") {
 
 1485                comparisonResult = comparisonResult && (valueToCompareFrom <= values[j]);
 
 1486            } 
else if (operators[j] == 
">") {
 
 1487                comparisonResult = comparisonResult && (valueToCompareFrom > values[j]);
 
 1488            } 
else if (operators[j] == 
">=") {
 
 1489                comparisonResult = comparisonResult && (valueToCompareFrom >= values[j]);
 
 1493        if (comparisonResult) {
 
 1494            if ((
int)eventIds.size() < max) {
 
 1495                eventIds.push_back(i);
 
 1502    fAnalysisTree->SetBranchStatus(
"*", 
true);
 
 1506std::vector<int> TRestRun::GetEventIdsWithConditions(
const string& cuts, 
int startingIndex, 
int maxNumber) {
 
 1507    int max = maxNumber;
 
 1508    if (max < 0) max = GetEntries();
 
 1510    auto indices = GetEventEntriesWithConditions(cuts, startingIndex, max);
 
 1511    std::vector<int> ids;
 
 1512    for (
unsigned int i = 0; i < indices.size(); i++) {
 
 1514        ids.push_back(fAnalysisTree->GetEventID());
 
 1527    if (fEventIndexCounter >= GetEntries()) {
 
 1528        fEventIndexCounter = 0;
 
 1530    auto indices = GetEventEntriesWithConditions(cuts, fEventIndexCounter++, 1);
 
 1531    if (indices.size() == 0) {
 
 1535        fAnalysisTree->GetEntry(indices[0]);
 
 1536        fEventTree->GetEntry(indices[0]);
 
 1537        fCurrentEvent = indices[0];
 
 
 1542string TRestRun::GetRunInformation(
const string& info) {
 
 1559        result = 
fHostmgr->GetProcessRunner()->GetProcInfo(info);
 
 1568TRestMetadata* TRestRun::GetMetadataClass(
const TString& type, TFile* file) {
 
 1569    if (file != 
nullptr) {
 
 1570        TIter nextkey(file->GetListOfKeys());
 
 1572        while ((key = (TKey*)nextkey())) {
 
 1573            string kName = key->GetClassName();
 
 1579                if (metadata != 
nullptr && metadata->InheritsFrom(
"TRestMetadata")) {
 
 1582                    RESTWarning << 
"TRestRun::GetMetadataClass() : The object to import is " 
 1583                                   "not inherited from TRestMetadata" 
 1589        for (
unsigned int i = 0; i < fMetadata.size(); i++)
 
 1590            if (fMetadata[i]->InheritsFrom(type)) 
return fMetadata[i];
 
 1593            return GetMetadataClass(type, fInputFile);
 
 1600TRestMetadata* TRestRun::GetMetadata(
const TString& name, TFile* file) {
 
 1601    if (file != 
nullptr) {
 
 1602        TIter nextkey(file->GetListOfKeys());
 
 1604        while ((key = (TKey*)nextkey())) {
 
 1605            string kName = key->GetName();
 
 1607            if (kName == name) {
 
 1610                if (metadata->InheritsFrom(
"TRestMetadata")) {
 
 1613                    RESTWarning << 
"TRestRun::GetMetadata() : The object to import is not " 
 1614                                   "inherited from TRestMetadata" 
 1620        for (
unsigned int i = 0; i < fMetadata.size(); i++) {
 
 1621            if (fMetadata[i]->GetName() == name) {
 
 1622                return fMetadata[i];
 
 1630std::vector<std::string> TRestRun::GetMetadataNames() {
 
 1631    std::vector<std::string> strings;
 
 1633    for (
int n = 0; n < GetNumberOfMetadata(); n++) strings.push_back(fMetadata[n]->GetName());
 
 1638std::vector<std::string> TRestRun::GetMetadataTitles() {
 
 1639    std::vector<std::string> strings;
 
 1641    for (
int n = 0; n < GetNumberOfMetadata(); n++) strings.push_back(fMetadata[n]->GetTitle());
 
 1653    if (instr.find(
"[", 0) == string::npos) 
return instr;
 
 1654    string outstring = instr;
 
 1656    int startPosition = 0;
 
 1657    int endPosition = 0;
 
 1658    while ((startPosition = outstring.find(
"[", endPosition)) != (
int)string::npos) {
 
 1659        endPosition = outstring.find(
"]", startPosition + 1);
 
 1660        string s = outstring.substr(startPosition + 1, endPosition - startPosition - 1);
 
 1661        int cont = count(s.begin(), s.end(), 
'[') - count(s.begin(), s.end(), 
']');
 
 1663        if (cont < 0) RESTError << 
"This is a coding error at ReplaceMetadataMembers!" << 
RESTendl;
 
 1667            endPosition = outstring.find(
"]", endPosition + 1);
 
 1668            s = outstring.substr(startPosition + 1, endPosition - startPosition - 1);
 
 1669            cont = count(s.begin(), s.end(), 
'[') - count(s.begin(), s.end(), 
']');
 
 1670            if (endPosition == (
int)string::npos) 
break;
 
 1672        if (endPosition == (
int)string::npos) 
break;
 
 1674        string expressionToReplace = outstring.substr(startPosition + 1, endPosition - startPosition - 1);
 
 1677        outstring.replace(startPosition, endPosition - startPosition + 1, value);
 
 1681    outstring = 
Replace(outstring, 
"{{", 
"[");
 
 1682    outstring = 
Replace(outstring, 
"}}", 
"]");
 
 
 1704    if (instr.find(
"::") == string::npos && instr.find(
"->") == string::npos) {
 
 1705        return "{{" + instr + 
"}}";
 
 1707    vector<string> results = 
Split(instr, 
"::", 
false, 
true);
 
 1708    if (results.size() == 1) results = 
Split(instr, 
"->", 
false, 
true);
 
 1710    if (results.size() == 2) {
 
 1712        int pos1 = results[1].find(
"[", 0);
 
 1713        int pos2 = results[1].find(
"]", pos1);
 
 1714        if (pos1 > 0 && pos2 > 0) {
 
 1715            string indexStr = results[1].substr(pos1 + 1, pos2 - pos1 - 1);  
 
 1718            if (index < 0) index = 0;
 
 1720            results[1] = results[1].substr(0, pos1);
 
 1723        if (GetMetadata(results[0])) {
 
 1724            if (index >= this->GetMetadata(results[0])->
GetDataMemberValues(results[1], precision).size()) {
 
 1725                RESTWarning << 
"TRestRun::ReplaceMetadataMember. Index out of range!" << 
RESTendl;
 
 1726                RESTWarning << 
"Returning the first element" << 
RESTendl;
 
 1732        if (GetMetadataClass(results[0])) {
 
 1735                RESTWarning << 
"TRestRun::ReplaceMetadataMember. Index out of range!" << 
RESTendl;
 
 1736                RESTWarning << 
"Returning the first element" << 
RESTendl;
 
 1739            return this->GetMetadataClass(results[0])->
GetDataMemberValues(results[1], precision)[index];
 
 1743        RESTError << 
"TRestRun::ReplaceMetadataMember. Wrong number of elements found" << 
RESTendl;
 
 1745    RESTWarning << 
"TRestRun::ReplaceMetadataMember. " << instr << 
" not found!" << 
RESTendl;
 
 
 1769    if (instr == 
"") 
return true;
 
 1771    std::vector<string> oper = {
"=", 
"==", 
"<=", 
"<", 
">=", 
">", 
"!="};
 
 1774    std::vector<string> results;
 
 1775    for (
unsigned int n = 0; n < oper.size(); n++) {
 
 1777        if (instr.find(
"->") != string::npos) pos = instr.find(
"->") + 2;
 
 1779        if (instr.find(oper[n], pos) != string::npos) {
 
 1781            results = 
Split(instr, oper[n], 
false, 
true, pos);
 
 1787        RESTWarning << 
"TRestRun::EvaluateMetadataMember. Not valid operator found in expression : " << instr
 
 1792    if (results.size() != 2) {
 
 1793        RESTWarning << 
"TRestRun::EvaluateMetadataMember. Not valid expression : " << instr << 
RESTendl;
 
 1807    if (expOp == 
"=" && lvalue == rvalue) 
return true;
 
 1808    if (expOp == 
"==" && lvalue == rvalue) 
return true;
 
 1809    if (expOp == 
"<=" && lvalue <= rvalue) 
return true;
 
 1810    if (expOp == 
"<" && lvalue < rvalue) 
return true;
 
 1811    if (expOp == 
">=" && lvalue >= rvalue) 
return true;
 
 1812    if (expOp == 
">" && lvalue > rvalue) 
return true;
 
 1813    if (expOp == 
"!=" && lvalue != rvalue) 
return true;
 
 
 1826    RESTMetadata << 
"Parent run number : " << GetParentRunNumber() << 
RESTendl;
 
 1827    RESTMetadata << 
"Run number : " << GetRunNumber() << 
RESTendl;
 
 1828    RESTMetadata << 
"Experiment/project : " << GetExperimentName() << 
RESTendl;
 
 1829    RESTMetadata << 
"Run type : " << GetRunType() << 
RESTendl;
 
 1830    RESTMetadata << 
"Run tag : " << GetRunTag() << 
RESTendl;
 
 1831    RESTMetadata << 
"Run user : " << GetRunUser() << 
RESTendl;
 
 1832    RESTMetadata << 
"Run description : " << GetRunDescription() << 
RESTendl;
 
 1833    RESTMetadata << 
"Start Date/Time : " << 
ToDateTimeString(GetStartTimestamp()) << 
" (" 
 1834                 << GetStartTimestamp() << 
")" << 
RESTendl;
 
 1835    RESTMetadata << 
"End Date/Time : " << 
ToDateTimeString(GetEndTimestamp()) << 
" (" << GetEndTimestamp()
 
 1840    if (fInputFile != 
nullptr) {
 
 1841        RESTMetadata << 
"Data file : " << fInputFile->GetName();
 
 1842        if (fNFilesSplit > 0) {
 
 1843            RESTMetadata << 
" (Splitted into " << fNFilesSplit + 1 << 
" files)" << 
RESTendl;
 
 1848    RESTMetadata << 
"Number of events : " << fEntriesSaved << 
RESTendl;
 
 1853    RESTMetadata << 
"---------------------------------------" << 
RESTendl;
 
 
 1863    cout << 
"------------------------" << endl;
 
 1864    cout << 
"---- Run start date ----" << endl;
 
 1865    cout << 
"------------------------" << endl;
 
 1866    cout << 
"Unix time : " << 
fStartTime << endl;
 
 1868    struct tm* tm = localtime(&tt);
 
 1871    strftime(date, 
sizeof(date), 
"%Y-%m-%d", tm);
 
 1872    cout << 
"Date : " << date << endl;
 
 1875    strftime(time, 
sizeof(time), 
"%H:%M:%S", tm);
 
 1876    cout << 
"Time : " << time << endl;
 
 1877    cout << 
"++++++++++++++++++++++++" << endl;
 
 
 1880void TRestRun::PrintEndDate() {
 
 1881    cout << 
"----------------------" << endl;
 
 1882    cout << 
"---- Run end date ----" << endl;
 
 1883    cout << 
"----------------------" << endl;
 
 1884    cout << 
"Unix time : " << 
fEndTime << endl;
 
 1886    struct tm* tm = localtime(&tt);
 
 1889    strftime(date, 
sizeof(date), 
"%Y-%m-%d", tm);
 
 1890    cout << 
"Date : " << date << endl;
 
 1893    strftime(time, 
sizeof(time), 
"%H:%M:%S", tm);
 
 1894    cout << 
"Time : " << time << endl;
 
 1895    cout << 
"++++++++++++++++++++++++" << endl;
 
 1904    for (
unsigned int n = 0; n < fMetadata.size(); n++)
 
 1905        if (fMetadata[n]->
GetError()) nErrors++;
 
 1909        RESTError << 
"Found a total of " << nErrors << 
" metadata errors" << 
RESTendl;
 
 1910        for (
unsigned int n = 0; n < fMetadata.size(); n++)
 
 1913                RESTError << 
"Class: " << fMetadata[n]->ClassName() << 
" Name: " << fMetadata[n]->GetName()
 
 1915                RESTError << 
"Number of errors: " << fMetadata[n]->GetNumberOfErrors() << 
RESTendl;
 
 1916                RESTError << 
"Message: " << fMetadata[n]->GetErrorMessage() << 
RESTendl;
 
 1920        cout << 
"No errors found!" << endl;
 
 
 1929    Int_t nWarnings = 0;
 
 1930    for (
unsigned int n = 0; n < fMetadata.size(); n++)
 
 1935        RESTWarning << 
"Found a total of " << nWarnings << 
" metadata warnings" << 
RESTendl;
 
 1936        for (
unsigned int n = 0; n < fMetadata.size(); n++)
 
 1939                RESTWarning << 
"Class: " << fMetadata[n]->ClassName() << 
" Name: " << fMetadata[n]->GetName()
 
 1941                RESTWarning << 
"Number of warnings: " << fMetadata[n]->GetNumberOfWarnings() << 
RESTendl;
 
 1942                RESTWarning << 
"Message: " << fMetadata[n]->GetWarningMessage() << 
RESTendl;
 
 1946        cout << 
"No warnings found!" << endl;
 
 
bool IsZombie() const
If this object type wrapper is invalid.
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.
REST core data-saving helper based on TTree.
Bool_t AddChainFile(const std::string &file)
Add a series output file like TChain.
TTree * GetTree() const
Overrides TTree::GetTree(), to get the actual tree used in case of chain operation(fCurrentTree !...
Double_t GetDblObservableValue(const std::string &obsName)
Get double value of the observable, according to the name.
void SetObservable(Int_t id, RESTValue obs)
Set the value of observable whose id is as specified.
virtual std::vector< int > search_run_with_file(std::string filepattern)
search runs according to the file name. return a list of run numbers
virtual int get_lastrun()
get the latest run id in database
virtual int set_run(DBEntry info, bool overwrite=true)
add/update a run, with run info as struct DBEntry. returns the added run id
virtual int set_runfile(int runnumber, std::string filename)
add/update a runfile to the specified run
virtual DBEntry query_run(int runnumber)
virtual std::vector< DBFile > query_run_files(int runnumber)
return all the files of the run
A base class for any REST event process.
virtual void EndOfEventProcess(TRestEvent *inputEvent=nullptr)
End of event process. Nothing to do. Called directly after ProcessEvent()
void SetAnalysisTree(TRestAnalysisTree *tree)
Set analysis tree of this process, then add observables to it.
virtual Long64_t GetTotalBytes() const
virtual void BeginOfEventProcess(TRestEvent *inputEvent=nullptr)
Begin of event process, preparation work. Called right before ProcessEvent()
virtual TRestEvent * ProcessEvent(TRestEvent *inputEvent)=0
Process one event.
virtual RESTValue GetOutputEvent() const =0
Get pointer to output event. Must be implemented in the derived class.
virtual void InitProcess()
To be executed at the beginning of the run (outside event loop)
virtual Long64_t GetTotalBytesRead() const
Interface to external file reading, get the read bytes. To be implemented in external processes.
A base class for any REST event.
virtual void InitializeReferences(TRestRun *run)
Initialize dynamical references when loading the event from a root file.
virtual void CloneTo(TRestEvent *target)
Clone the content of this TRestEvent object to another.
virtual void Initialize()=0
Data provider and manager in REST.
void PrintWarnings()
Prints out all the warnings registered by metadata classes accessible to TRestRun,...
void AddEventBranch(TRestEvent *event)
Add an event branch in output EventTree.
void OpenInputFile(int i)
Open the i th file in the file list.
void CloseFile()
Close both input file and output file, setting trees to nullptr also.
TFile * FormOutputFile()
Create a new TFile as REST output file. Writing metadata objects into it.
void ResetEntry()
Reset file reading progress.
TString FormFormat(const TString &filenameFormat)
Form output file name according to file info list, proc info list and run data.
Int_t fParentRunNumber
It can be used as parent number of subrun number.
void SetInputEvent(TRestEvent *event)
Retarget input event in the tree.
std::string ReplaceMetadataMember(const std::string &instr, Int_t precision=0)
It will replace the data member from the corresponding metadata class type or name defined in the inp...
void GetEntry(Long64_t entry)
Calls GetEntry() for both AnalysisTree and EventTree.
void InitFromConfigFile() override
Initialize logic of TRestRun.
void Initialize() override
REST run class.
void PrintErrors()
Prints out all the warnings registered by metadata classes accessible to TRestRun,...
std::string ReplaceMetadataMembers(const std::string &instr, Int_t precision=8)
It will replace the data members contained inside the string given as input. The data members in the ...
void PrintMetadata() override
Prints the basic run information.
TFile * MergeToOutputFile(std::vector< std::string > fileFullNames, std::string outputFileName="")
Form REST output file by merging a list of files together.
std::vector< std::string > GetEventTypesList()
It returns a list of available event types inside the file.
void ImportMetadata(const TString &rootFile, const TString &name, const TString &type, Bool_t store)
Open the root file and import the metadata of the given name.
Bool_t EvaluateMetadataMember(const std::string &instr)
It will evaluate the expression given including the data member from the corresponding metadata class...
void SetExtProcess(TRestEventProcess *p)
Set external file process.
void PrintStartDate()
Prints the run start date and time in human format.
Double_t fStartTime
Event absolute starting time/date (unix timestamp)
void WriteWithDataBase()
Write this object into TFile and add a new entry in database.
Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0) override
overwriting the write() method with fStore considered
void ReadFileInfo(const std::string &filename)
Extract file info from a file, and save it in the file info list.
Double_t fEndTime
Event absolute ending time/date (unix timestamp)
Int_t GetNextEvent(TRestEvent *targetEvent, TRestAnalysisTree *targetTree)
Get next event by writing event data into target event and target tree.
TRestEvent * GetNextEventWithConditions(const std::string &)
Load the next event that satisfies the conditions specified by a string.
TClass * GetClassQuick()
Get the type of a "class" object, returning the wrapped type identifier "TClass".
TRestReflector Assembly(const std::string &typeName)
Assembly an object of type: typeName, returning the allocated memory address and size.
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.
Int_t StringToInteger(std::string in)
Gets an integer from a string.
Int_t Count(std::string s, std::string sbstring)
Counts the number of occurences of substring inside the input string in.
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.
std::string RemoveWhiteSpaces(std::string in)
Returns the input string removing all white spaces.
std::string ToDateTimeString(time_t time)
Format time_t into string.
std::string Replace(std::string in, std::string thisString, std::string byThisString, size_t fromPosition=0, Int_t N=0)
Replace any occurences of thisSring by byThisString inside string in.
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.