REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
TRestRun.cxx
1
9//
27
28#include "TRestRun.h"
29#ifdef WIN32
30#include <io.h>
31#include <process.h>
32#include <windows.h>
33#undef GetClassName
34#else
35#include <sys/stat.h>
36#include <unistd.h>
37#endif // !WIN32
38
39#include <filesystem>
40
41#include "TRestDataBase.h"
42#include "TRestEventProcess.h"
43#include "TRestManager.h"
44#include "TRestVersion.h"
45
46using namespace std;
47
48std::mutex mutex_read;
49
50ClassImp(TRestRun);
51
52TRestRun::TRestRun() { Initialize(); }
53
54TRestRun::TRestRun(const string& filename) {
55 if (filename.find(".root") != string::npos) {
56 Initialize();
57 OpenInputFile(filename);
58 } else if (filename.find(".rml") != string::npos) {
59 Initialize();
60 LoadConfigFromFile(filename);
61 } else {
62 RESTError << "TRestRun::TRestRun(): input file error!" << RESTendl;
63 }
64}
65
66TRestRun::~TRestRun() { CloseFile(); }
67
72 SetSectionName(this->ClassName());
73
74 time_t timev;
75 time(&timev);
76 fStartTime = (Double_t)timev;
77 fEndTime = 0; // We need a static value to avoid overwriting the time if another process sets the time
78
79 fRunUser = REST_USER;
80 fRunNumber = 0; // run number where input file is from and where output file
81 // will be saved
82 fParentRunNumber = 0; // subrun number where input file is from
83 fRunType = "Null";
84 fExperimentName = "Null";
85 fRunTag = "Null";
86 fRunDescription = "Null";
87
88 fInputFileName = "null";
89 fOutputFileName = "rest_default.root";
90
91 fBytesRead = 0;
92 fTotalBytes = -1;
93 fOverwrite = true;
94 fEntriesSaved = -1;
95 fNFilesSplit = 0;
96
97 fInputMetadata.clear();
98 fMetadata.clear();
99 fInputFileNames.clear();
100 fInputFile = nullptr;
101 fOutputFile = nullptr;
102 fInputEvent = nullptr;
103 fAnalysisTree = nullptr;
104 fEventTree = nullptr;
105 fCurrentEvent = 0;
106 fEventBranchLoc = -1;
107 fFileProcess = nullptr;
108 fSaveHistoricData = true;
109}
110
123 RESTDebug << "Initializing TRestRun from config file, version: " << REST_RELEASE << RESTendl;
124 fFromRML = true;
125 ReSetVersion();
126
127 // 1. Read basic parameter
128 fRunUser = REST_USER;
129 // fRunType = GetParameter("runType", "ANALYSIS").c_str();
130 // fRunDescription = GetParameter("runDescription", "").c_str();
131 // fExperimentName = GetParameter("experiment", "preserve").c_str();
132 // fRunTag = GetParameter("runTag", "noTag").c_str();
134
135 // 2. Initialize runnumber and input file name. They follow non-trivial logic
136 fRunNumber = -1;
138 string runNstr = GetParameter("runNumber", "-1");
139 string inputName = GetParameter("inputFileName", "");
140 inputName = TRestTools::RemoveMultipleSlash(inputName);
141 string inputNameOld = GetParameter("inputFile", "default");
142 if (inputNameOld != "default") {
143 RESTWarning << "Parameter \"inputFile\" in rml is obsolete! Please update it to \"inputFileName\""
144 << RESTendl;
145 if (inputName.empty()) {
146 inputName = inputNameOld;
147 }
148 }
149 if (ToUpper(runNstr) == "AUTO" && ToUpper(inputName) == "AUTO") {
150 RESTError << "TRestRun: run number and input file name cannot both be "
151 "\"AUTO\""
152 << RESTendl;
153 exit(1);
154 }
155
156 if (ToUpper(inputName) != "AUTO") {
157 fInputFileName = inputName;
158 fInputFileNames = Vector_cast<string, TString>(TRestTools::GetFilesMatchingPattern(inputName));
159 }
160
161 if (ToUpper(runNstr) != "AUTO") {
162 fRunNumber = atoi(runNstr.c_str());
163 }
164
165 if (ToUpper(inputName) == "AUTO") {
166 TRestDataBase* db = gDataBase;
167 auto files = db->query_run_files(fRunNumber);
168 fInputFileName = db->query_run(fRunNumber).value; // run entry value is file pattern
169 fInputFileNames = Vector_cast<DBFile, TString>(files);
170 }
171
172 if (ToUpper(runNstr) == "AUTO") {
173 TRestDataBase* db = gDataBase;
174 auto runs = db->search_run_with_file((string)fInputFileName);
175 if (!runs.empty()) {
176 fRunNumber = runs[0];
177 } else {
178 fRunNumber = -1;
179 }
180
181 // add a new run
182 if (fRunNumber == 0) {
183 fRunNumber = db->get_lastrun() + 1;
184 DBEntry entry;
185 entry.runNr = fRunNumber;
186 entry.description = fRunDescription;
187 entry.tag = fRunTag;
188 entry.type = fRunType;
189 entry.version = REST_RELEASE;
190 db->set_run(entry);
191 }
192 }
193
194 // get some run information
195 if (fRunNumber != -1) {
196 DBEntry entry = gDataBase->query_run(fRunNumber);
197 if (!entry.IsZombie()) {
198 fStartTime = entry.tstart;
199 fEndTime = entry.tend;
200 fRunDescription = entry.description;
201 fRunTag = entry.tag;
202 fRunType = entry.type;
203 }
204 }
205
206 if (fInputFileNames.empty()) {
207 if (fInputFileName != "") {
208 RESTError << "cannot find the input file!" << RESTendl;
209 exit(1);
210 } else {
211 RESTWarning << "no input file added" << RESTendl;
212 }
213 // throw;
214 }
215
216 // 3. Construct output file name
217 string outputDir = (string)GetDataPath();
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\""
222 << RESTendl;
223 if (outputName == "default") {
224 outputName = outputNameOld;
225 }
226 }
227 if (ToUpper(outputName) == "DEFAULT") {
228 string expName = RemoveWhiteSpaces((string)GetExperimentName());
229 string runType = RemoveWhiteSpaces((string)GetRunType());
230 char runParentStr[256];
231 sprintf(runParentStr, "%05d", fParentRunNumber);
232 char runNumberStr[256];
233 sprintf(runNumberStr, "%05d", fRunNumber);
234
235 fOutputFileName = outputDir + "Run_" + expName + "_" + fRunUser + "_" + runType + "_" + fRunTag +
236 "_" + (TString)runNumberStr + "_" + (TString)runParentStr + "_V" + REST_RELEASE +
237 ".root";
238
239 // fOverwrite = ToUpper(GetParameter("overwrite", "on")) != "OFF";
240 while (!fOverwrite && TRestTools::fileExists((string)fOutputFileName)) {
242 sprintf(runParentStr, "%05d", fParentRunNumber);
243 fOutputFileName = outputDir + "Run_" + expName + "_" + fRunUser + "_" + runType + "_" + fRunTag +
244 "_" + (TString)runNumberStr + "_" + (TString)runParentStr + "_V" +
245 REST_RELEASE + ".root";
246 }
247 } else if (ToUpper(outputName) == "NULL" || outputName == "/dev/null") {
248 fOutputFileName = "/dev/null";
249 } else if (TRestTools::isAbsolutePath(outputName)) {
250 fOutputFileName = outputName;
251 outputDir = TRestTools::SeparatePathAndName((string)fOutputFileName).first;
252 } else {
253 fOutputFileName = outputDir + "/" + outputName;
254 }
255 // remove multiple slashes from fOutputFileName
256 fOutputFileName = (TString)TRestTools::RemoveMultipleSlash((string)fOutputFileName);
257
258 if (!TRestTools::fileExists(outputDir)) {
259 int z = system((TString) "mkdir -p " + outputDir);
260 if (z != 0) RESTError << "Problem creating directory : " << outputDir << RESTendl;
261 }
262 if (!TRestTools::isPathWritable(outputDir)) {
263 RESTWarning << "TRestRun: Output path '" << outputDir << "' does not exist or it is not writable."
264 << RESTendl;
265 }
266
267 // 4. Loop over sections to initialize metadata
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);
274 } else {
275 RESTWarning << "Wrong definition of addMetadata! Metadata name or file name "
276 "is not given!"
277 << RESTendl;
278 }
279 } else if (Count(key, "TRest") > 0) {
280 if (e->Attribute("file") != nullptr && TRestTools::isRootFile(e->Attribute("file"))) {
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;
284 }
285
287 if (meta == nullptr) {
288 RESTWarning << "failed to add metadata \"" << key << "\"" << RESTendl;
289 e = e->NextSiblingElement();
290 continue;
291 }
293 meta->SetHostmgr(fHostmgr);
294 fMetadata.push_back(meta);
296 }
297 e = e->NextSiblingElement();
298 }
299
300 // 5. Open input file(s). We open input file at the last stage in case the file name pattern
301 // reading requires TRestDetector
302 OpenInputFile(0);
303 RESTDebug << "TRestRun::EndOfInit. InputFile pattern: \"" << fInputFileName << "\"" << RESTendl;
304 RESTInfo << "which matches :" << RESTendl;
305 for (const auto& inputFileName : fInputFileNames) {
306 RESTInfo << inputFileName << RESTendl;
307 }
308 RESTEssential << "(" << fInputFileNames.size() << " added files)" << RESTendl;
309}
310
315 if (fInputFileNames.size() > (unsigned int)i) {
316 TString Filename = fInputFileNames[i];
317 RESTInfo << "opening... " << Filename << RESTendl;
318 OpenInputFile((string)Filename);
319 }
320}
321
331void TRestRun::OpenInputFile(const TString& filename, const string& mode) {
332 CloseFile();
333 if (!filename.Contains("http") && !TRestTools::fileExists((string)filename)) {
334 RESTError << "input file \"" << filename << "\" does not exist!" << RESTendl;
335 exit(1);
336 }
337
338 if (!filename.Contains("http")) ReadFileInfo((string)filename);
339
340 // add to fInputFileNames in case it is opening a new file
341 bool inList = false;
342 for (const auto& inputFileName : fInputFileNames) {
343 if (inputFileName == filename) {
344 inList = true;
345 break;
346 }
347 }
348
349 if (!inList) {
350 fInputFileNames.push_back(filename);
351 }
352
353 if (TRestTools::isRootFile((string)filename)) {
354 fInputFile = TFile::Open(filename, mode.c_str());
355
356 if (GetMetadataClass("TRestRun", fInputFile)) {
357 // This should be the values in RML (if it was initialized using RML)
358 TString runTypeTmp = fRunType;
359 // TString runUserTmp = fRunUser;
360 TString runTagTmp = fRunTag;
361 TString runDescriptionTmp = fRunDescription;
362 TString experimentNameTmp = fExperimentName;
363 TString outputFileNameTmp = fOutputFileName;
364 TString inputFileNameTmp = fInputFileName;
365 TString cFileNameTmp = fConfigFileName;
366
367 // We define fVersion to -1 to identify old REST files that did not have yet
368 // versioning system
369 this->UnSetVersion();
370
371 // Now we load the values in the previous run file
372 // If successfully read the input file, the version code will be changed
373 // from -1 --> certain number
374 this->Read(GetMetadataClass("TRestRun", fInputFile)->GetName());
375
376 if (inputFileNameTmp != "null") fInputFileName = inputFileNameTmp;
377 if (outputFileNameTmp != "rest_default.root") fOutputFileName = outputFileNameTmp;
378 if (cFileNameTmp != "null") fConfigFileName = cFileNameTmp;
379
380 // If the value was initialized from RML and is not preserve, we recover
381 // back the value in RML
382 if (fFromRML) {
383 if (runTypeTmp != "Null" && runTypeTmp != "preserve") fRunType = runTypeTmp;
384
385 // We should not recover the user. Only when writing. If not when I open a file
386 // with restRoot just to read, and Print the run content from other user in my
387 // own account, it will say it was me!
388 // if (runUserTmp != "Null" && runTypeTmp != "preserve") fRunUser = runUserTmp;
389
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;
395 }
396
397 // If version is lower than 2.2.1 we do not read/transfer the metadata to
398 // output file?
399 // Actually g4 files from v2.1.x is all compatible with the v2.2.x version
400 // Only 2.2.0 is without auto schema evolution, whose metadata cannot be read
401 if (fSaveHistoricData) {
402 if (this->GetVersionCode() >= REST_VERSION(2, 2, 1) ||
403 this->GetVersionCode() <= REST_VERSION(2, 1, 8)) {
404 ReadInputFileMetadata();
405 } else {
406 RESTWarning << "-- W : The metadata version found on input file is lower "
407 "than 2.2.1!"
408 << RESTendl;
409 RESTWarning << "-- W : metadata from input file will not be read" << RESTendl;
410 }
411 }
412
413 RESTDebug << "Initializing input file : version code : " << this->GetVersionCode() << RESTendl;
414 RESTDebug << "Input file version : " << this->GetVersion() << RESTendl;
415 ReadInputFileTrees();
416 fCurrentEvent = 0;
417 } else {
418 RESTWarning << "TRestRun object not found in file! The input file may be incomplete!" << RESTendl;
419 ReadInputFileTrees();
420 }
421 } else {
422 fInputFile = nullptr;
423 fAnalysisTree = nullptr;
424 if (fFileProcess != nullptr) {
425 fFileProcess->OpenInputFiles(Vector_cast<TString, string>(fInputFileNames));
426 fFileProcess->InitProcess();
427 }
428 }
429
430 if (fAnalysisTree == nullptr && fFileProcess == nullptr)
431 RESTInfo << "Input file is not REST root file, an external process is needed!" << RESTendl;
432}
433
434void TRestRun::AddInputFileExternal(const string& file) {
435 mutex_read.lock();
436 if (fFileProcess != nullptr) {
437 bool add = fFileProcess->AddInputFile(file);
438 if (!add) {
439 RESTError << "failed to add input file!" << RESTendl;
440 }
441 fInputFileNames.emplace_back(file);
442 }
443 mutex_read.unlock();
444}
445
446void TRestRun::ReadInputFileMetadata() {
447 TFile* f = fInputFile;
448 if (f != nullptr) {
449 fInputMetadata.clear();
450
451 TIter nextkey(f->GetListOfKeys());
452 TKey* key;
453 // we should make sure the input metadata has unique names
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;
458
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()
464 << RESTendl;
465 continue;
466 }
467
468 if (addedNames.count(key->GetName()) != 0) {
469 continue;
470 }
471
472 TRestMetadata* a = (TRestMetadata*)f->Get(key->GetName());
473 RESTDebug << "Key of type : " << a->ClassName() << "(" << a << ")" << RESTendl;
474
475 if (!a) {
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") {
480 /*
481 //we make sure there is no repeated class added
482 // However, we might have two processes with the same class name
483 operating at different steps of the data chain
484 // We just avoid to write TRestRun from previous file to the list of
485 metadata structures
486
487 bool flag = false;
488 for (int i = 0; i < fInputMetadata.size(); i++) {
489 if (a->ClassName() == fInputMetadata[i]->ClassName()) {
490 flag = true;
491 break;
492 }
493 }
494 if (!flag) {
495 fInputMetadata.push_back(a);
496 }
497 */
499 fInputMetadata.push_back(a);
500 fMetadata.push_back(a);
501 addedNames.insert(key->GetName());
502 }
503 }
504 }
505}
506
507void TRestRun::ReadInputFileTrees() {
508 if (fInputFile != nullptr) {
509 RESTDebug << "Finding TRestAnalysisTree.." << RESTendl;
510 TTree* _eventTree = nullptr;
511 string filename = fInputFile->GetName();
512
513 if (fInputFile->Get("AnalysisTree") != nullptr) {
514 fAnalysisTree = (TRestAnalysisTree*)fInputFile->Get("AnalysisTree");
515
516 if (fNFilesSplit > 0) { // fNFilesSplit=1: split to 1 additional file
517 RESTEssential << "Linking analysis tree from split data files" << RESTendl;
518 fAnalysisTree =
520 fAnalysisTree->Clone(); // we must make a copy to have TBrowser correctly browsed.
521 for (int i = 1; i <= fNFilesSplit; i++) {
522 string filename = fInputFile->GetName() + (string) "." + ToString(i);
523 RESTInfo << filename << " --> ";
524 RESTInfo << (fAnalysisTree->AddChainFile(filename) ? "success" : "failed") << RESTendl;
525 }
526 if (fAnalysisTree->GetChain() == nullptr ||
527 fAnalysisTree->GetChain()->GetNtrees() != fNFilesSplit + 1) {
528 RESTError << "Error adding split files, files missing?" << RESTendl;
529 RESTError << "Your data could be incomplete!" << RESTendl;
530 }
531 }
532
533 // Note: we call GetEntries() to initialize total entry number
534 // Otherwise the child analysis tree's observables will be reset
535 // on the next call of GetEntries()
536 fAnalysisTree->GetEntries();
537 // Call GetEntry() to initialize observables and connect branches
538 fAnalysisTree->GetEntry(0);
539
540 _eventTree = (TTree*)fInputFile->Get("EventTree");
541 } else if (fInputFile->FindKey("TRestAnalysisTree") != nullptr) {
542 // This is v2.1.6- version of input file, we directly find EventTree and
543 // AnalysisTree. The old name pattern is "TRestXXXEventTree-eventBranch"
544 // and "TRestAnalysisTree"
545 RESTWarning << "Loading root file from old version REST!" << RESTendl;
546 fAnalysisTree = (TRestAnalysisTree*)fInputFile->Get("TRestAnalysisTree");
547 fAnalysisTree->GetEntry(0);
548
549 TIter nextkey(fInputFile->GetListOfKeys());
550 TKey* key;
551 while ((key = (TKey*)nextkey())) {
552 // cout << key->GetName() << endl;
553 if (((string)key->GetName()).find("EventTree") != string::npos) {
554 _eventTree = (TTree*)fInputFile->Get(key->GetName());
555 string eventName = Replace(key->GetName(), "Tree", "", 0);
556 TBranch* br = _eventTree->GetBranch("eventBranch");
557 br->SetName((eventName + "Branch").c_str());
558 br->SetTitle((eventName + "Branch").c_str());
559 break;
560 }
561 }
562 RESTDebug << "Old REST file successfully recovered!" << RESTendl;
563 } else {
564 RESTWarning << "(OpenInputFile) : AnalysisTree was not found" << RESTendl;
565 RESTWarning << "Inside file : " << filename << RESTendl;
566 RESTWarning << "This may not be a REST output file!" << RESTendl;
567 }
568
569 if (_eventTree != nullptr) {
570 if (fNFilesSplit > 0) {
571 // eventTree shall be initialized as TChain
572 delete _eventTree;
573 RESTEssential << "Linking event tree from split data files" << RESTendl;
574 TChain* _fEventTree = new TChain("EventTree");
575 RESTInfo << fInputFile->GetName() << " --> ";
576 RESTInfo << (_fEventTree->Add(fInputFile->GetName()) ? "success" : "failed") << RESTendl;
577
578 for (int i = 1; i <= fNFilesSplit; i++) {
579 string filename = fInputFile->GetName() + (string) "." + ToString(i);
580 RESTInfo << filename << " --> ";
581 RESTInfo << (_fEventTree->Add(filename.c_str()) ? "success" : "failed") << RESTendl;
582 }
583 fEventTree = _fEventTree;
584 } else {
585 fEventTree = _eventTree;
586 }
587
588 RESTDebug << "Finding event branch.." << RESTendl;
589 if (fInputEvent == nullptr) {
590 TObjArray* branches = fEventTree->GetListOfBranches();
591 // get the last event branch as input event branch
592 if (branches->GetLast() > -1) {
593 TBranch* br = (TBranch*)branches->At(branches->GetLast());
594
595 if (br == nullptr || Count(br->GetName(), "EventBranch") == 0) {
596 RESTInfo << "No event branch inside file : " << filename << RESTendl;
597 RESTInfo << "This file may be a pure analysis file" << RESTendl;
598 } else {
599 string type = Replace(br->GetName(), "Branch", "", 0);
600 TClass* cl = TClass::GetClass(type.c_str());
601 if (cl->HasDictionary()) {
602 fInputEvent = REST_Reflection::Assembly(type);
603 } else if (fInputEvent != nullptr) {
604 delete fInputEvent;
605 fInputEvent = nullptr;
606 }
607
608 if (fInputEvent == nullptr) {
609 RESTError << "TRestRun:OpenInputFile. Cannot initialize input event, event "
610 "tree not read"
611 << RESTendl;
612 RESTError
613 << "Please install corresponding libraries to provide root dictionaries for "
614 "class reading."
615 << RESTendl;
616 return;
617 }
618
619 fInputEvent->InitializeWithMetadata(this);
620 fEventTree->SetBranchAddress(br->GetName(), &fInputEvent);
621 fEventBranchLoc = branches->GetLast();
622 RESTDebug << "found event branch of event type: " << fInputEvent->ClassName()
623 << RESTendl;
624 }
625 }
626 } else {
627 string brname = (string)fInputEvent->ClassName() + "Branch";
628 if (fEventTree->GetBranch(brname.c_str()) == nullptr) {
629 RESTWarning << "REST WARNING (OpenInputFile) : No matched event branch "
630 "inside file : "
631 << filename << RESTendl;
632 RESTWarning << "Branch required: " << brname << RESTendl;
633 } else {
634 fEventTree->SetBranchAddress(brname.c_str(), &fInputEvent);
635 RESTDebug << brname << " is found and set!" << RESTendl;
636 }
637 }
638 } else {
639 RESTDebug << "TRestRun:OpenInputFile. EventTree was not found" << RESTendl;
640 RESTDebug << "This is a pure analysis file!" << RESTendl;
641 fInputEvent = nullptr;
642 }
643 }
644}
645
653void TRestRun::ReadFileInfo(const string& filename) {
654 RESTDebug << "begin collecting basic file info..." << filename << RESTendl;
655
656 // basic file info: modify time, total bytes, etc.
657 struct stat buf;
658 FILE* fp = fopen(filename.c_str(), "rb");
659 if (!fp) {
660 RESTError << "TRestRun::ReadFileInfo. Something went wrong with fopen()!" << strerror(errno)
661 << RESTendl;
662 exit(1);
663 }
664 int fd = fileno(fp);
665 fstat(fd, &buf);
666 fclose(fp);
667 if (fEndTime == 0) {
668 fEndTime = buf.st_mtime;
669 }
670
671 if (TRestTools::isRootFile((string)filename)) {
672 fTotalBytes = buf.st_size;
673 }
674
675 RESTDebug << "begin matching file name pattern for more file info..." << RESTendl;
676 // format example:
677 // run[fRunNumber]_cobo[aaa]_frag[bbb]_Vm[TRestDetector::fAmplificationVoltage].graw
678 // we are going to match it with inputfile:
679 // run00042_cobo1_frag0000_Vm350.graw
680 string format = GetParameter("inputFormat", "");
681 string name = TRestTools::SeparatePathAndName(filename).second;
682
683 vector<string> formatSectionList;
684 vector<string> formatPrefixList;
685
686 int pos = -1;
687 int pos1 = 0;
688 int pos2 = 0;
689 while (true) {
690 pos1 = format.find("[", pos + 1);
691 pos2 = format.find("]", pos1);
692 if (pos1 == -1 || pos2 == -1) {
693 formatPrefixList.push_back(format.substr(pos + 1, -1));
694 break;
695 }
696
697 formatSectionList.push_back(format.substr(pos1 + 1, pos2 - pos1 - 1));
698 formatPrefixList.push_back(format.substr(pos + 1, pos1 - pos - 1));
699
700 pos = pos2;
701 }
702
703 pos = -1;
704 for (unsigned int i = 0; i < formatSectionList.size() && i < formatPrefixList.size() - 1; i++) {
705 if (i != 0 && formatPrefixList[i].empty()) {
706 RESTWarning << "file format reference contains error!" << RESTendl;
707 return;
708 }
709 int pos1 = name.find(formatPrefixList[i], pos + 1) + formatPrefixList[i].size();
710 if (formatPrefixList[i].empty()) pos1 = 0;
711 int pos2 = name.find(formatPrefixList[i + 1], pos1);
712 if (formatPrefixList[i + 1].empty()) pos2 = name.length();
713 if (pos1 == -1 || pos2 == -1) {
714 RESTWarning << "File pattern matching: file format mismatch!" << RESTendl;
715 return;
716 }
717
718 string infoFromFileName = name.substr(pos1, pos2 - pos1);
719
720 RESTDebug << "File pattern matching. key: " << formatSectionList[i] << " (between the mark \""
721 << formatPrefixList[i] << "\" and \"" << formatPrefixList[i + 1]
722 << "\"), value: " << infoFromFileName << RESTendl;
723
724 // run[fRunNumber]_cobo[aaa]_frag[bbb]_Vm[TRestDetector::fAmplificationVoltage].graw
725 bool inforead = false;
726 if (!inforead) {
727 // 1. store special file pattern parameters as TRestRun data member: fRunNumber
728 if (DataMemberNameToParameterName(formatSectionList[i]) != "") {
729 RESTValue member = RESTValue(this, this->ClassName()).GetDataMember(formatSectionList[i]);
730 if (!member.IsZombie()) {
731 member.ParseString(infoFromFileName);
732 inforead = true;
733 } else {
734 RESTWarning << "TRestRun: file name format field \"" << formatSectionList[i]
735 << "\"(value = " << infoFromFileName
736 << ") not registered, data member does not exist in TRestRun!" << RESTendl;
737 }
738 }
739 }
740
741 if (!inforead) {
742 // 2. store special file pattern parameters as data member of the loaded
743 // metadata class, e.g., TRestDetector::fAmplificationVoltage
744 vector<string> classDataMember = Split(formatSectionList[i], "::");
745 if (classDataMember.size() > 1) {
746 TRestMetadata* meta = GetMetadataClass(classDataMember[0]);
747 if (meta != nullptr) {
748 RESTValue member = RESTValue(meta, meta->ClassName()).GetDataMember(classDataMember[1]);
749 if (!member.IsZombie()) {
750 member.ParseString(infoFromFileName);
751 meta->UpdateMetadataMembers();
752 inforead = true;
753 } else {
754 RESTWarning << "TRestRun: file name format field \"" << formatSectionList[i]
755 << "\"(value = " << infoFromFileName
756 << ") not registered, metadata exist but without such datamember field!"
757 << RESTendl;
758 }
759 } else {
760 RESTWarning << "TRestRun: file name format field \"" << formatSectionList[i]
761 << "\"(value = " << infoFromFileName
762 << ") not registered, metadata does not exist!" << RESTendl;
763 }
764 }
765 }
766
767 // if (!inforead) {
768 // 3. store file format fields to REST_ARGS as global parameter: aaa, bbb
769 // REST_ARGS[formatsectionlist[i]] = infoFromFileName;
770 // }
771
772 pos = pos2 - 1;
773 }
774}
775
783 fCurrentEvent = 0;
784 if (fFileProcess != nullptr) {
785 fFileProcess->ResetEntry();
786 }
787}
788
797Int_t TRestRun::GetNextEvent(TRestEvent* targetEvent, TRestAnalysisTree* targetTree) {
798 bool messageShown = false;
799 TRestEvent* eve = fInputEvent;
800
801 if (fFileProcess != nullptr) {
802 RESTDebug << "TRestRun: getting next event from external process" << RESTendl;
803 GetEventExt:
804 mutex_read.lock();
805 fFileProcess->BeginOfEventProcess();
806 eve = fFileProcess->ProcessEvent(nullptr);
807 fFileProcess->EndOfEventProcess();
808 mutex_read.unlock();
809 fBytesRead = fFileProcess->GetTotalBytesRead();
810 // if (targettree != nullptr) {
811 // for (int n = 0; n < fAnalysisTree->GetNumberOfObservables(); n++)
812 // targettree->SetObservable(n, fAnalysisTree->GetObservable(n));
813 //}
814 fCurrentEvent++;
815 } else {
816 if (eve == nullptr) {
817 RESTDebug << "TRestRun::GetNextEvent(): input event has not been initialized!" << RESTendl;
818 } else {
819 RESTDebug << "TRestRun: getting next event from root file" << RESTendl;
820 if (fAnalysisTree == nullptr) {
821 RESTWarning << "error to get event from input file, missing analysis tree from input file"
822 << RESTendl;
823 eve = nullptr;
824 } else {
825 if (fCurrentEvent >= fAnalysisTree->GetTree()->GetEntriesFast()) {
826 eve = nullptr;
827 } else {
828 if (targetTree != nullptr) {
829 // normal reading procedure
830 eve->Initialize();
831 fBytesRead += fAnalysisTree->GetEntry(fCurrentEvent);
832 targetTree->SetEventInfo(fAnalysisTree);
833 for (int n = 0; n < fAnalysisTree->GetNumberOfObservables(); n++)
834 targetTree->SetObservable(n, fAnalysisTree->GetObservable(n));
835 }
836 if (fEventTree != nullptr) {
837 if (fEventTree->IsA() == TChain::Class()) {
838 Long64_t entry = fEventTree->LoadTree(fCurrentEvent);
839 fBytesRead += ((TBranch*)fEventTree->GetTree()->GetListOfBranches()->UncheckedAt(
840 fEventBranchLoc))
841 ->GetEntry(entry);
842 } else {
843 fBytesRead +=
844 ((TBranch*)fEventTree->GetListOfBranches()->UncheckedAt(fEventBranchLoc))
845 ->GetEntry(fCurrentEvent);
846 }
847 }
848 fCurrentEvent++;
849 }
850 }
851 }
852 }
853
854 // cout << fHangUpEndFile << endl;
855
856 if (eve == nullptr) {
857 if (fHangUpEndFile && fFileProcess != nullptr) {
858 // if hangup is set, we continue calling ProcessEvent() of the
859 // external process, until there is non-null event yielded
860 if (!messageShown) {
861 RESTEssential << "external process file reading reaches end, waiting for more files"
862 << RESTendl;
863 }
864 usleep(1000000);
865 messageShown = true;
866 fCurrentEvent--;
867 goto GetEventExt;
868 }
869 fInputEvent = eve;
870 // if (fFileProcess != nullptr) fFileProcess->EndProcess();
871 return -1;
872 }
873
874 fInputEvent = eve;
875
876 if (fInputEvent->GetID() == 0 && fInputEvent->GetSubID() == 0) {
877 fInputEvent->SetID(fCurrentEvent - 1);
878 }
879
880 if (fInputEvent->GetRunOrigin() == 0) {
881 fInputEvent->SetRunOrigin(fRunNumber);
882 }
883
884 targetEvent->Initialize();
885 fInputEvent->CloneTo(targetEvent);
886
887 return 0;
888}
889
893std::vector<std::string> TRestRun::GetEventTypesList() {
894 std::vector<std::string> list;
895 TObjArray* branches = GetEventTree()->GetListOfBranches();
896 for (int i = 0; i <= branches->GetLast(); i++) {
897 auto branch = (TBranch*)branches->At(i);
898 if (((std::string)branch->GetName()).find("EventBranch") != string::npos) {
899 std::string eventType = Replace((string)branch->GetName(), "Branch", "");
900 list.emplace_back(eventType);
901 }
902 }
903 return list;
904}
905
909void TRestRun::GetEntry(Long64_t entry) {
910 if (entry >= GetEntries()) {
911 RESTWarning << "TRestRun::GetEntry. Entry requested out of limits" << RESTendl;
912 RESTWarning << "Total number of entries is : " << GetEntries() << RESTendl;
913 }
914
915 if (fAnalysisTree != nullptr) {
916 fAnalysisTree->GetEntry(entry);
917 }
918 if (fEventTree != nullptr) {
919 fEventTree->GetEntry(entry);
920 }
921
922 if (fInputEvent != nullptr) {
923 fInputEvent->InitializeReferences(this);
924 }
925
926 fCurrentEvent = entry;
927}
928
941TString TRestRun::FormFormat(const TString& FilenameFormat) {
942 string inString = (string)FilenameFormat;
943 string outString = (string)FilenameFormat;
944
945 RESTDebug << "TRestRun::FormFormat. In string : " << inString << RESTendl;
946
947 int pos = 0;
948 while (true) {
949 int pos1 = inString.find("[", pos);
950 int pos2 = inString.find("]", pos1);
951 if (pos1 == -1 || pos2 == -1) break;
952
953 string targetstr = inString.substr(pos1, pos2 - pos1 + 1); // with []
954 string target = inString.substr(pos1 + 1, pos2 - pos1 - 1); // without []
955 string replacestr = GetRunInformation(target);
956
957 RESTDebug << "TRestRun::FormFormat. target : " << target << RESTendl;
958 RESTDebug << "TRestRun::FormFormat. replacestr : " << replacestr << RESTendl;
959
960 // If we form an output file we are willing to form the output filename
961 // using the latest version. But the version is set just before we
962 // call Write.
963 if (target == "fVersion") replacestr = (string)REST_RELEASE;
964 if (target == "fCommit") replacestr = (string)REST_COMMIT;
965
966 if (replacestr != target) {
967 if (target == "fRunNumber" || target == "fParentRunNumber") {
968 replacestr = Form("%05d", StringToInteger(replacestr));
969 }
970 outString = Replace(outString, targetstr, replacestr, 0);
971 }
972 pos = pos2 + 1;
973 }
974
975 return outString;
976}
977
986TFile* TRestRun::MergeToOutputFile(vector<string> filenames, string outputfilename) {
987 RESTDebug << "TRestRun::FormOutputFile. target : " << outputfilename << RESTendl;
988 string filename;
989 TFileMerger* m = new TFileMerger(false);
990 if (outputfilename.empty()) {
991 filename = fOutputFileName;
992 RESTInfo << "Creating file : " << filename << RESTendl;
993 m->OutputFile(filename.c_str(), "RECREATE");
994 } else {
995 filename = outputfilename;
996 RESTInfo << "Updating file : " << filename << RESTendl;
997 m->OutputFile(filename.c_str(), "UPDATE");
998 }
999
1000 RESTDebug << "TRestRun::FormOutputFile. Starting to add files" << RESTendl;
1001
1002 for (unsigned int i = 0; i < filenames.size(); i++) {
1003 m->AddFile(filenames[i].c_str(), false);
1004 }
1005
1006 if (m->Merge()) {
1007 for (unsigned int i = 0; i < filenames.size(); i++) {
1008 remove(filenames[i].c_str());
1009 }
1010 } else {
1011 fOutputFileName = "";
1012 RESTError << "(Merge files) failed to merge process files." << RESTendl;
1013 exit(1);
1014 }
1015
1016 delete m;
1017
1018 // we rename the created output file
1019 fOutputFileName = FormFormat(filename);
1020 rename(filename.c_str(), fOutputFileName);
1021
1022 // write metadata into the output file
1023 fOutputFile = new TFile(fOutputFileName, "update");
1024 RESTDebug << "TRestRun::FormOutputFile. Calling WriteWithDataBase()" << RESTendl;
1025 this->WriteWithDataBase();
1026
1027 RESTcout << this->ClassName() << " Created ..." << RESTendl;
1028 RESTcout << "- Path : " << TRestTools::SeparatePathAndName((string)fOutputFileName).first << RESTendl;
1029 RESTcout << "- Filename : " << TRestTools::SeparatePathAndName((string)fOutputFileName).second
1030 << RESTendl;
1031 return fOutputFile;
1032}
1033
1038 CloseFile();
1039
1040 fOutputFileName = FormFormat(fOutputFileName);
1041 // remove unwanted "./" etc. from the path while resolving them
1042 fOutputFileName = std::filesystem::weakly_canonical(fOutputFileName.Data());
1043
1044 fOutputFile = new TFile(fOutputFileName, "recreate");
1045 fAnalysisTree = new TRestAnalysisTree("AnalysisTree", "AnalysisTree");
1046 fEventTree = new TTree("EventTree", "EventTree");
1047
1048 fAnalysisTree->Write(nullptr, TObject::kOverwrite);
1049 fEventTree->Write(nullptr, TObject::kOverwrite);
1050 this->WriteWithDataBase();
1051
1052 RESTcout << "TRestRun: Output File Created." << RESTendl;
1053 RESTcout << "- Path : " << TRestTools::SeparatePathAndName((string)fOutputFileName).first << RESTendl;
1054 RESTcout << "- Filename : " << TRestTools::SeparatePathAndName((string)fOutputFileName).second
1055 << RESTendl;
1056 return fOutputFile;
1057}
1058
1059TFile* TRestRun::UpdateOutputFile() {
1060 if (fOutputFile != nullptr) {
1061 if (fOutputFile->IsOpen()) {
1062 fOutputFile->ReOpen("update");
1063 }
1064
1065 fOutputFile->cd();
1066
1067 fAnalysisTree->Write(nullptr, kOverwrite);
1068 fEventTree->Write(nullptr, kOverwrite);
1069
1070 this->WriteWithDataBase();
1071
1072 RESTcout << "TRestRun: Output File Updated." << RESTendl;
1073 RESTcout << "- Path : " << TRestTools::SeparatePathAndName((string)fOutputFileName).first << RESTendl;
1074 RESTcout << "- Filename : " << TRestTools::SeparatePathAndName((string)fOutputFileName).second
1075 << RESTendl;
1076 return fOutputFile;
1077
1078 } else {
1079 RESTError << "TRestRun::UpdateOutputFile(): output file is closed" << RESTendl;
1080 }
1081 return nullptr;
1082}
1083
1094 TRestAnalysisTree* tree = nullptr;
1095
1096 RESTDebug << "TRestRun::WriteWithDataBase. Getting entries in analysisTree" << RESTendl;
1097
1098 // record the entries saved
1099 fEntriesSaved = -1;
1100 if (fOutputFile != nullptr) {
1101 tree = (TRestAnalysisTree*)fOutputFile->Get("AnalysisTree");
1102 if (tree != nullptr) {
1103 fEntriesSaved = tree->GetEntries();
1104 }
1105 }
1106 RESTDebug << "TRestRun::WriteWithDataBase. Entries found : " << fEntriesSaved << RESTendl;
1107
1108 // If time was not written by any other process we record the current time
1109 if (fEndTime == 0) {
1110 time_t timev;
1111 time(&timev);
1112 fEndTime = (Double_t)timev;
1113 }
1114
1115 fRunUser = REST_USER;
1116
1117 // save metadata objects in file
1118
1119 RESTDebug << "TRestRun::WriteWithDataBase. Calling this->Write(0, kOverwrite)" << RESTendl;
1120 this->Write(nullptr, kOverwrite);
1121
1122 RESTDebug << "TRestRun::WriteWithDataBase. Succeed" << RESTendl;
1123 RESTDebug << "TRestRun::WriteWithDataBase. fMetadata.size() == " << fMetadata.size() << RESTendl;
1124 for (auto& metadata : fMetadata) {
1125 bool historic = false;
1126 RESTDebug << "TRestRun::WriteWithDataBase. fInputMetadata.size() == " << fInputMetadata.size()
1127 << RESTendl;
1128 for (const auto& inputMetadata : fInputMetadata) {
1129 RESTDebug << metadata->GetName() << " == " << inputMetadata->GetName() << RESTendl;
1130 if (metadata == inputMetadata) {
1131 historic = true;
1132 break;
1133 }
1134 }
1135
1136 if (!historic) {
1137 RESTDebug << "NO historic" << RESTendl;
1138 metadata->Write(metadata->GetName(), kOverwrite);
1139 } else {
1140 RESTDebug << "IS historic" << RESTendl;
1141 if (fSaveHistoricData) metadata->Write(metadata->GetName(), kOverwrite);
1142 }
1143 }
1144
1145 // write to database
1146 RESTDebug << "TResRun::WriteWithDataBase. Run number is : " << fRunNumber << RESTendl;
1147 if (fRunNumber != -1) {
1148 int fileid = gDataBase->set_runfile(fRunNumber, (string)fOutputFileName);
1149 RESTcout << "DataBase Entry Added! Run Number: " << fRunNumber << ", File ID: " << fileid << RESTendl;
1150 }
1151}
1152
1157 fEntriesSaved = -1;
1158 if (fAnalysisTree != nullptr) {
1159 fEntriesSaved = fAnalysisTree->GetEntries();
1160 if (fAnalysisTree->GetEntries() > 0 && fInputFile == nullptr) {
1161 if (fOutputFile != nullptr) {
1162 fOutputFile->cd();
1163 fAnalysisTree->Write(nullptr, kOverwrite);
1164 this->Write(nullptr, kOverwrite);
1165 }
1166 }
1167 delete fAnalysisTree;
1168 fAnalysisTree = nullptr;
1169 }
1170
1171 if (fEventTree != nullptr) {
1172 if (fEventTree->GetEntries() > 0 && fInputFile == nullptr) fEventTree->Write(nullptr, kOverwrite);
1173 delete fEventTree;
1174 fEventTree = nullptr;
1175 }
1176
1177 for (unsigned int i = 0; i < fMetadata.size(); i++) {
1178 for (unsigned int j = 0; j < fInputMetadata.size(); j++) {
1179 if (fMetadata[i] == fInputMetadata[j]) {
1180 delete fMetadata[i];
1181 fMetadata.erase(fMetadata.begin() + i);
1182 i--;
1183 fInputMetadata.erase(fInputMetadata.begin() + j);
1184 break;
1185 }
1186 }
1187 }
1188
1189 if (fOutputFile != nullptr) {
1190 fOutputFile->Write(0, TObject::kOverwrite);
1191 fOutputFile->Close();
1192 delete fOutputFile;
1193 fOutputFile = nullptr;
1194 }
1195 if (fInputFile != nullptr) {
1196 fInputFile->Close();
1197 fInputFile = nullptr;
1198 }
1199}
1200
1205 if (fFileProcess == nullptr && p != nullptr) {
1206 fFileProcess = p;
1207
1208 fFileProcess->OpenInputFiles(Vector_cast<TString, string>(fInputFileNames));
1209 fFileProcess->InitProcess();
1210 fInputEvent = fFileProcess->GetOutputEvent();
1211 if (fInputEvent == nullptr) {
1212 RESTError << "The external process \"" << p->GetName() << "\" doesn't yield any output event!"
1213 << RESTendl;
1214 exit(1);
1215 } else {
1216 fInputEvent->SetRunOrigin(fRunNumber);
1217 fInputEvent->SetSubRunOrigin(fParentRunNumber);
1218 fInputEvent->SetTimeStamp(fStartTime);
1219 }
1220 fInputFile = nullptr;
1221 // we make sure external processes can access to analysis tree
1222 fAnalysisTree = new TRestAnalysisTree("externalProcessAna", "externalProcessAna");
1223 p->SetAnalysisTree(fAnalysisTree);
1224 fTotalBytes = p->GetTotalBytes();
1225
1226 GetNextEvent(fInputEvent, nullptr);
1227 // fAnalysisTree->CreateBranches();
1228 RESTInfo << "The external file process has been set! Name : " << fFileProcess->GetName() << RESTendl;
1229 } else {
1230 if (fFileProcess != nullptr) {
1231 RESTError << "There can only be one file process!" << RESTendl;
1232 exit(1);
1233 }
1234 if (p == nullptr) {
1235 RESTWarning << "Given file process is null, skipping..." << RESTendl;
1236 }
1237 }
1238}
1239
1247 if (event != nullptr) {
1248 if (fEventTree != nullptr) {
1249 if (fInputEvent != nullptr) {
1250 fEventTree->SetBranchAddress((TString)fInputEvent->ClassName() + "Branch", nullptr);
1251 fEventTree->SetBranchStatus((TString)fInputEvent->ClassName() + "Branch", false);
1252 }
1253 TObjArray* branches = fEventTree->GetListOfBranches();
1254 string branchName = (string)event->ClassName() + "Branch";
1255 for (int i = 0; i <= branches->GetLast(); i++) {
1256 auto branch = (TBranch*)branches->At(i);
1257 if ((string)branch->GetName() == branchName) {
1258 RESTDebug << "Setting input event.. Type: " << event->ClassName() << " Address: " << event
1259 << RESTendl;
1260 fInputEvent = event;
1261 fEventTree->SetBranchAddress(branchName.c_str(), &fInputEvent);
1262 fEventTree->SetBranchStatus(branchName.c_str(), false);
1263 fEventBranchLoc = i;
1264 break;
1265 } else if (i == branches->GetLast()) {
1266 RESTWarning << "REST Warning : (TRestRun) cannot find corresponding "
1267 "branch in event tree!"
1268 << RESTendl;
1269 RESTWarning << "Event Type : " << event->ClassName() << RESTendl;
1270 RESTWarning << "Input event not set!" << RESTendl;
1271 }
1272 }
1273 } else {
1274 fInputEvent = event;
1275 }
1276 this->GetEntry(fCurrentEvent);
1277 }
1278}
1279
1284 if (event != nullptr) {
1285 if (fEventTree != nullptr) {
1286 string eventName = (string)event->ClassName();
1287 string branchName = eventName + "Branch";
1288 fEventTree->Branch(branchName.c_str(), event);
1289 fEventTree->SetTitle((eventName + "Tree").c_str());
1290 }
1291 }
1292}
1293
1299void TRestRun::ImportMetadata(const TString& File, const TString& name, const TString& type, Bool_t store) {
1300 const TString thisFile = SearchFile(File.Data());
1301 if (thisFile == "") {
1302 RESTError << "(ImportMetadata): The file " << thisFile << " does not exist!" << RESTendl;
1303 RESTError << RESTendl;
1304 return;
1305 }
1306 if (!TRestTools::isRootFile(thisFile.Data())) {
1307 RESTError << "(ImportMetadata) : The file " << thisFile << " is not root file!" << RESTendl;
1308 RESTError << "If you want to initialize metadata from rml file, use <TRest section!" << RESTendl;
1309 return;
1310 }
1311
1312 TFile* file = TFile::Open(thisFile);
1313 // TODO give error in case we try to obtain a class that is not TRestMetadata
1314 if (type == "" && name == "") {
1315 RESTError << "(ImportMetadata) : metadata type and name is not "
1316 "specified!"
1317 << RESTendl;
1318 return;
1319 }
1320
1321 TRestMetadata* meta = nullptr;
1322 if (name != "") {
1323 meta = GetMetadata(name, file);
1324 } else if (type != "") {
1325 meta = GetMetadataClass(type, file);
1326 }
1327
1328 if (meta == nullptr) {
1329 cout << "REST ERROR (ImportMetadata) : " << name << " does not exist." << endl;
1330 cout << "Inside root file : " << File << endl;
1331 GetChar();
1332 file->Close();
1333 delete file;
1334 return;
1335 }
1336
1337 if (store)
1338 meta->Store();
1339 else
1340 meta->DoNotStore();
1341
1342 fMetadata.push_back(meta);
1343 meta->LoadConfigFromBuffer();
1344 file->Close();
1345 delete file;
1346}
1347
1348Int_t TRestRun::Write(const char* name, Int_t option, Int_t bufsize) {
1349 ReSetVersion();
1350 return TRestMetadata::Write(name, option, bufsize);
1351}
1352
1353Double_t TRestRun::GetRunLength() const {
1354 if (fEndTime - fStartTime == -1) {
1355 cout << "Run time is not set\n";
1356 }
1357 return fEndTime - fStartTime;
1358}
1359
1360Long64_t TRestRun::GetTotalBytes() {
1361 if (fFileProcess != nullptr) {
1362 fTotalBytes = fFileProcess->GetTotalBytes();
1363 }
1364 return fTotalBytes;
1365}
1366
1367Long64_t TRestRun::GetEntries() const {
1368 if (fAnalysisTree != nullptr) {
1369 return fAnalysisTree->GetEntries();
1370 }
1371 return REST_MAXIMUM_EVENTS;
1372}
1373
1374// Getters
1375TRestEvent* TRestRun::GetEventWithID(Int_t eventID, Int_t subEventID, const TString& tag) {
1376 if (fAnalysisTree != nullptr) {
1377 int nEntries = fAnalysisTree->GetEntries();
1378
1379 // set analysis tree to read only three branches
1380 fAnalysisTree->SetBranchStatus("*", false);
1381 fAnalysisTree->SetBranchStatus("eventID", true);
1382 fAnalysisTree->SetBranchStatus("subEventID", true);
1383 fAnalysisTree->SetBranchStatus("subEventTag", true);
1384
1385 // just look through the whole analysis tree and find the entry
1386 // this is not good!
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);
1395 fCurrentEvent = i;
1396 return fInputEvent;
1397 }
1398 }
1399 // reset the branch status
1400 fAnalysisTree->SetBranchStatus("*", true);
1401 }
1402 return nullptr;
1403}
1404
1405std::vector<int> TRestRun::GetEventEntriesWithConditions(const string& cuts, int startingIndex,
1406 int maxNumber) {
1407 int max = maxNumber;
1408 if (max < 0) max = GetEntries();
1409
1410 std::vector<int> eventIds;
1411 // parsing cuts
1412 std::vector<string> observables;
1413 std::vector<string> operators;
1414 std::vector<Double_t> values;
1415 // it is necessary that this vector is sorted from longest to shortest
1416 const std::vector<string> validOperators = {"==", "<=", ">=", "=", ">", "<"};
1417
1418 vector<string> cutsVector = Split(cuts, "&&", false, true);
1419
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)));
1428 break;
1429 }
1430 }
1431 }
1432
1433 // check if observable name corresponds to a valid observable on the tree
1434 if (fAnalysisTree == nullptr) {
1435 return eventIds;
1436 }
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());
1442 }
1443 // verify all observables in cuts are branch names
1444 for (unsigned int i = 0; i < observables.size(); i++) {
1445 // verify operators
1446 if (std::find(validOperators.begin(), validOperators.end(), operators[i]) == validOperators.end()) {
1447 // invalid operation
1448 cout << "invalid operation '" << operators[i] << "' for 'TRestRun::GetEventIdsWithConditions'"
1449 << endl;
1450 return eventIds;
1451 }
1452 // verify observables
1453 if (branchNames.count(observables[i]) == 0) {
1454 // invalid observable name
1455 cout << "invalid observable '" << observables[i] << "' for 'TRestRun::GetEventIdsWithConditions'"
1456 << endl;
1457 cout << "valid branch names: ";
1458 for (auto branchName : branchNames) {
1459 cout << branchName << " ";
1460 }
1461 cout << endl;
1462 return eventIds;
1463 }
1464 }
1465 // read only the necessary branches
1466 fAnalysisTree->SetBranchStatus("*", false);
1467 for (unsigned int i = 0; i < observables.size(); i++) {
1468 fAnalysisTree->SetBranchStatus(observables[i].c_str(), true);
1469 }
1470 // comparison code
1471 Double_t valueToCompareFrom;
1472 bool comparisonResult;
1473 int i;
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++) {
1479 valueToCompareFrom = fAnalysisTree->GetDblObservableValue(observables[j].c_str());
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]);
1490 }
1491 }
1492
1493 if (comparisonResult) {
1494 if ((int)eventIds.size() < max) {
1495 eventIds.push_back(i);
1496 } else {
1497 break;
1498 }
1499 }
1500 }
1501 // reset branch status
1502 fAnalysisTree->SetBranchStatus("*", true);
1503 return eventIds;
1504}
1505
1506std::vector<int> TRestRun::GetEventIdsWithConditions(const string& cuts, int startingIndex, int maxNumber) {
1507 int max = maxNumber;
1508 if (max < 0) max = GetEntries();
1509
1510 auto indices = GetEventEntriesWithConditions(cuts, startingIndex, max);
1511 std::vector<int> ids;
1512 for (unsigned int i = 0; i < indices.size(); i++) {
1513 GetEntry(indices[i]);
1514 ids.push_back(fAnalysisTree->GetEventID());
1515 }
1516 return ids;
1517}
1518
1526 // we retrieve only one index starting from position set by the counter and increase by one
1527 if (fEventIndexCounter >= GetEntries()) {
1528 fEventIndexCounter = 0;
1529 }
1530 auto indices = GetEventEntriesWithConditions(cuts, fEventIndexCounter++, 1);
1531 if (indices.size() == 0) {
1532 // no events found
1533 return nullptr;
1534 } else {
1535 fAnalysisTree->GetEntry(indices[0]);
1536 fEventTree->GetEntry(indices[0]);
1537 fCurrentEvent = indices[0];
1538 return fInputEvent;
1539 }
1540}
1541
1542string TRestRun::GetRunInformation(const string& info) {
1543 string result = GetParameter(info, "");
1544 if (result != "") {
1545 return result;
1546 }
1547
1548 result = GetDataMemberValue(info);
1549 if (result != "") {
1550 return result;
1551 }
1552
1554 if (result != "") {
1555 return result;
1556 }
1557
1558 if (fHostmgr && fHostmgr->GetProcessRunner() != nullptr) {
1559 result = fHostmgr->GetProcessRunner()->GetProcInfo(info);
1560 if (result != "") {
1561 return result;
1562 }
1563 }
1564
1565 return info;
1566}
1567
1568TRestMetadata* TRestRun::GetMetadataClass(const TString& type, TFile* file) {
1569 if (file != nullptr) {
1570 TIter nextkey(file->GetListOfKeys());
1571 TKey* key;
1572 while ((key = (TKey*)nextkey())) {
1573 string kName = key->GetClassName();
1574
1575 if (REST_Reflection::GetClassQuick(kName.c_str()) != nullptr &&
1576 REST_Reflection::GetClassQuick(kName.c_str())->InheritsFrom(type)) {
1577 TRestMetadata* metadata = file->Get<TRestMetadata>(key->GetName());
1578
1579 if (metadata != nullptr && metadata->InheritsFrom("TRestMetadata")) {
1580 return metadata;
1581 } else {
1582 RESTWarning << "TRestRun::GetMetadataClass() : The object to import is "
1583 "not inherited from TRestMetadata"
1584 << RESTendl;
1585 }
1586 }
1587 }
1588 } else {
1589 for (unsigned int i = 0; i < fMetadata.size(); i++)
1590 if (fMetadata[i]->InheritsFrom(type)) return fMetadata[i];
1591
1592 if (fInputFile != nullptr && this->GetVersionCode() >= TRestTools::ConvertVersionCode("2.2.1")) {
1593 return GetMetadataClass(type, fInputFile);
1594 }
1595 }
1596
1597 return nullptr;
1598}
1599
1600TRestMetadata* TRestRun::GetMetadata(const TString& name, TFile* file) {
1601 if (file != nullptr) {
1602 TIter nextkey(file->GetListOfKeys());
1603 TKey* key;
1604 while ((key = (TKey*)nextkey())) {
1605 string kName = key->GetName();
1606
1607 if (kName == name) {
1608 TRestMetadata* metadata = file->Get<TRestMetadata>(name);
1609
1610 if (metadata->InheritsFrom("TRestMetadata")) {
1611 return metadata;
1612 } else {
1613 RESTWarning << "TRestRun::GetMetadata() : The object to import is not "
1614 "inherited from TRestMetadata"
1615 << RESTendl;
1616 }
1617 }
1618 }
1619 } else {
1620 for (unsigned int i = 0; i < fMetadata.size(); i++) {
1621 if (fMetadata[i]->GetName() == name) {
1622 return fMetadata[i];
1623 }
1624 }
1625 }
1626
1627 return nullptr;
1628}
1629
1630std::vector<std::string> TRestRun::GetMetadataNames() {
1631 std::vector<std::string> strings;
1632
1633 for (int n = 0; n < GetNumberOfMetadata(); n++) strings.push_back(fMetadata[n]->GetName());
1634
1635 return strings;
1636}
1637
1638std::vector<std::string> TRestRun::GetMetadataTitles() {
1639 std::vector<std::string> strings;
1640
1641 for (int n = 0; n < GetNumberOfMetadata(); n++) strings.push_back(fMetadata[n]->GetTitle());
1642
1643 return strings;
1644}
1645
1652string TRestRun::ReplaceMetadataMembers(const string& instr, Int_t precision) {
1653 if (instr.find("[", 0) == string::npos) return instr;
1654 string outstring = instr;
1655
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(), ']');
1662
1663 if (cont < 0) RESTError << "This is a coding error at ReplaceMetadataMembers!" << RESTendl;
1664
1665 // We search for the enclosing ']'. Since we might find a vector index inside.
1666 while (cont > 0) {
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;
1671 }
1672 if (endPosition == (int)string::npos) break;
1673
1674 string expressionToReplace = outstring.substr(startPosition + 1, endPosition - startPosition - 1);
1675 string value = ReplaceMetadataMember(expressionToReplace);
1676
1677 outstring.replace(startPosition, endPosition - startPosition + 1, value);
1678 endPosition = 0;
1679 }
1680
1681 outstring = Replace(outstring, "{{", "[");
1682 outstring = Replace(outstring, "}}", "]");
1683
1684 return REST_StringHelper::ReplaceMathematicalExpressions(outstring, precision);
1685}
1686
1690//
1703string TRestRun::ReplaceMetadataMember(const string& instr, Int_t precision) {
1704 if (instr.find("::") == string::npos && instr.find("->") == string::npos) {
1705 return "{{" + instr + "}}";
1706 }
1707 vector<string> results = Split(instr, "::", false, true);
1708 if (results.size() == 1) results = Split(instr, "->", false, true);
1709
1710 if (results.size() == 2) {
1711 size_t index = 0;
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); // without []
1716
1717 index = StringToInteger(indexStr);
1718 if (index < 0) index = 0;
1719
1720 results[1] = results[1].substr(0, pos1);
1721 }
1722
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;
1727 index = 0;
1728 }
1729 return this->GetMetadata(results[0])->GetDataMemberValues(results[1], precision)[index];
1730 }
1731
1732 if (GetMetadataClass(results[0])) {
1733 if (index >=
1734 this->GetMetadataClass(results[0])->GetDataMemberValues(results[1], precision).size()) {
1735 RESTWarning << "TRestRun::ReplaceMetadataMember. Index out of range!" << RESTendl;
1736 RESTWarning << "Returning the first element" << RESTendl;
1737 index = 0;
1738 }
1739 return this->GetMetadataClass(results[0])->GetDataMemberValues(results[1], precision)[index];
1740 }
1741
1742 } else
1743 RESTError << "TRestRun::ReplaceMetadataMember. Wrong number of elements found" << RESTendl;
1744
1745 RESTWarning << "TRestRun::ReplaceMetadataMember. " << instr << " not found!" << RESTendl;
1746 return "";
1747}
1748
1752//
1768Bool_t TRestRun::EvaluateMetadataMember(const string& instr) {
1769 if (instr == "") return true;
1770
1771 std::vector<string> oper = {"=", "==", "<=", "<", ">=", ">", "!="};
1772
1773 string expOp = "";
1774 std::vector<string> results;
1775 for (unsigned int n = 0; n < oper.size(); n++) {
1776 size_t pos = 0;
1777 if (instr.find("->") != string::npos) pos = instr.find("->") + 2;
1778
1779 if (instr.find(oper[n], pos) != string::npos) {
1780 expOp = oper[n];
1781 results = Split(instr, oper[n], false, true, pos);
1782 break;
1783 }
1784 }
1785
1786 if (expOp == "") {
1787 RESTWarning << "TRestRun::EvaluateMetadataMember. Not valid operator found in expression : " << instr
1788 << RESTendl;
1789 return false;
1790 }
1791
1792 if (results.size() != 2) {
1793 RESTWarning << "TRestRun::EvaluateMetadataMember. Not valid expression : " << instr << RESTendl;
1794 return false;
1795 }
1796
1797 if (!isANumber(results[1])) {
1798 if (ReplaceMetadataMember(results[0]).find(results[1]) != string::npos)
1799 return true;
1800 else
1801 return false;
1802 }
1803
1804 Double_t lvalue = StringToDouble(ReplaceMetadataMember(results[0]));
1805 Double_t rvalue = StringToDouble(results[1]);
1806
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;
1814
1815 return false;
1816}
1817
1822 // cout.precision(10);
1824
1825 RESTMetadata << "Version : " << this->GetVersion() << RESTendl;
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()
1836 << ")" << RESTendl;
1837 RESTMetadata << "Input file : " << TRestTools::GetPureFileName((string)GetInputFileNamePattern())
1838 << RESTendl;
1839 RESTMetadata << "Output file : " << TRestTools::GetPureFileName((string)GetOutputFileName()) << RESTendl;
1840 if (fInputFile != nullptr) {
1841 RESTMetadata << "Data file : " << fInputFile->GetName();
1842 if (fNFilesSplit > 0) {
1843 RESTMetadata << " (Splitted into " << fNFilesSplit + 1 << " files)" << RESTendl;
1844 } else {
1845 RESTMetadata << RESTendl;
1846 }
1847 }
1848 RESTMetadata << "Number of events : " << fEntriesSaved << RESTendl;
1849 // metadata << "Input filename : " << fInputFilename << endl;
1850 // metadata << "Output filename : " << fOutputFilename << endl;
1851 // metadata << "Number of initial events : " << GetNumberOfEvents() << endl;
1852 // metadata << "Number of processed events : " << fProcessedEvents << endl;
1853 RESTMetadata << "---------------------------------------" << RESTendl;
1854 RESTMetadata << RESTendl;
1855}
1856
1861 cout.precision(10);
1862
1863 cout << "------------------------" << endl;
1864 cout << "---- Run start date ----" << endl;
1865 cout << "------------------------" << endl;
1866 cout << "Unix time : " << fStartTime << endl;
1867 time_t tt = (time_t)fStartTime;
1868 struct tm* tm = localtime(&tt);
1869
1870 char date[20];
1871 strftime(date, sizeof(date), "%Y-%m-%d", tm);
1872 cout << "Date : " << date << endl;
1873
1874 char time[20];
1875 strftime(time, sizeof(time), "%H:%M:%S", tm);
1876 cout << "Time : " << time << endl;
1877 cout << "++++++++++++++++++++++++" << endl;
1878}
1879
1880void TRestRun::PrintEndDate() {
1881 cout << "----------------------" << endl;
1882 cout << "---- Run end date ----" << endl;
1883 cout << "----------------------" << endl;
1884 cout << "Unix time : " << fEndTime << endl;
1885 time_t tt = (time_t)fEndTime;
1886 struct tm* tm = localtime(&tt);
1887
1888 char date[20];
1889 strftime(date, sizeof(date), "%Y-%m-%d", tm);
1890 cout << "Date : " << date << endl;
1891
1892 char time[20];
1893 strftime(time, sizeof(time), "%H:%M:%S", tm);
1894 cout << "Time : " << time << endl;
1895 cout << "++++++++++++++++++++++++" << endl;
1896}
1897
1903 Int_t nErrors = 0;
1904 for (unsigned int n = 0; n < fMetadata.size(); n++)
1905 if (fMetadata[n]->GetError()) nErrors++;
1906
1907 if (nErrors) {
1908 cout << endl;
1909 RESTError << "Found a total of " << nErrors << " metadata errors" << RESTendl;
1910 for (unsigned int n = 0; n < fMetadata.size(); n++)
1911 if (fMetadata[n]->GetError()) {
1912 cout << endl;
1913 RESTError << "Class: " << fMetadata[n]->ClassName() << " Name: " << fMetadata[n]->GetName()
1914 << RESTendl;
1915 RESTError << "Number of errors: " << fMetadata[n]->GetNumberOfErrors() << RESTendl;
1916 RESTError << "Message: " << fMetadata[n]->GetErrorMessage() << RESTendl;
1917 }
1918 cout << endl;
1919 } else {
1920 cout << "No errors found!" << endl;
1921 }
1922}
1923
1929 Int_t nWarnings = 0;
1930 for (unsigned int n = 0; n < fMetadata.size(); n++)
1931 if (fMetadata[n]->GetWarning()) nWarnings++;
1932
1933 if (nWarnings) {
1934 cout << endl;
1935 RESTWarning << "Found a total of " << nWarnings << " metadata warnings" << RESTendl;
1936 for (unsigned int n = 0; n < fMetadata.size(); n++)
1937 if (fMetadata[n]->GetWarning()) {
1938 cout << endl;
1939 RESTWarning << "Class: " << fMetadata[n]->ClassName() << " Name: " << fMetadata[n]->GetName()
1940 << RESTendl;
1941 RESTWarning << "Number of warnings: " << fMetadata[n]->GetNumberOfWarnings() << RESTendl;
1942 RESTWarning << "Message: " << fMetadata[n]->GetWarningMessage() << RESTendl;
1943 }
1944 cout << endl;
1945 } else {
1946 cout << "No warnings found!" << endl;
1947 }
1948}
void ParseString(std::string str)
Set the value of the wrapped object from std::string.
TRestReflector GetDataMember(std::string name)
Find the class's datamember as TRestReflector object, including those from base class.
bool IsZombie()
If this object type wrapper is invalid.
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.
Definition: TRestEvent.h:38
virtual void InitializeReferences(TRestRun *run)
Initialize dynamical references when loading the event from a root file.
Definition: TRestEvent.cxx:173
virtual void CloneTo(TRestEvent *target)
Clone the content of this TRestEvent object to another.
Definition: TRestEvent.cxx:96
virtual void Initialize()=0
Definition: TRestEvent.cxx:71
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 ...
virtual void PrintMetadata()
Implemented it in the derived metadata class to print out specific metadata information.
endl_t RESTendl
Termination flag object for TRestStringOutput.
void DoNotStore()
If this method is called the metadata information will not be stored in disk.
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 SetHostmgr(TRestManager *m)
Set the host manager for this class.
Int_t LoadConfigFromBuffer()
Initialize data from a string element buffer.
TString GetDataPath()
Returns a std::string with the path used for data storage.
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.
void SetConfigFile(std::string configFilename)
set config file path from external
void ReadAllParameters()
Reflection methods, Set value of a datamember in class according to TRestMetadata::fElement.
void SetSectionName(std::string sName)
set the section name, clear the section content
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.
std::vector< std::string > GetDataMemberValues(std::string memberName, Int_t precision=0)
Get the value of datamember as a vector of strings.
TRestManager * fHostmgr
All metadata classes can be initialized and managed by TRestManager.
std::string GetDataMemberValue(std::string memberName)
Get the value of data member as string.
std::string fConfigFileName
Full name of the rml file.
void Store()
If this method is called the metadata information will be stored in disk.
virtual void UpdateMetadataMembers()
Method to allow implementation of specific metadata members updates at inherited classes.
virtual Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0)
overwriting the write() method with fStore considered
Bool_t GetWarning() const
It returns true if an error was identified by a derived metadata class.
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.
TiXmlElement * fElement
Saving the sectional element together with global element.
Data provider and manager in REST.
Definition: TRestRun.h:18
void PrintWarnings()
Prints out all the warnings registered by metadata classes accessible to TRestRun,...
Definition: TRestRun.cxx:1928
void AddEventBranch(TRestEvent *event)
Add an event branch in output EventTree.
Definition: TRestRun.cxx:1283
void OpenInputFile(int i)
Open the i th file in the file list.
Definition: TRestRun.cxx:314
void CloseFile()
Close both input file and output file, setting trees to nullptr also.
Definition: TRestRun.cxx:1156
TFile * FormOutputFile()
Create a new TFile as REST output file. Writing metadata objects into it.
Definition: TRestRun.cxx:1037
void ResetEntry()
Reset file reading progress.
Definition: TRestRun.cxx:782
Int_t fParentRunNumber
It can be used as parent number of subrun number.
Definition: TRestRun.h:23
void SetInputEvent(TRestEvent *event)
Retarget input event in the tree.
Definition: TRestRun.cxx:1246
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...
Definition: TRestRun.cxx:1703
void GetEntry(Long64_t entry)
Calls GetEntry() for both AnalysisTree and EventTree.
Definition: TRestRun.cxx:909
void InitFromConfigFile() override
Initialize logic of TRestRun.
Definition: TRestRun.cxx:122
void Initialize() override
REST run class.
Definition: TRestRun.cxx:71
void PrintErrors()
Prints out all the warnings registered by metadata classes accessible to TRestRun,...
Definition: TRestRun.cxx:1902
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 ...
Definition: TRestRun.cxx:1652
void PrintMetadata() override
Prints the basic run information.
Definition: TRestRun.cxx:1821
std::vector< std::string > GetEventTypesList()
It returns a list of available event types inside the file.
Definition: TRestRun.cxx:893
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.
Definition: TRestRun.cxx:1299
Bool_t EvaluateMetadataMember(const std::string &instr)
It will evaluate the expression given including the data member from the corresponding metadata class...
Definition: TRestRun.cxx:1768
void SetExtProcess(TRestEventProcess *p)
Set external file process.
Definition: TRestRun.cxx:1204
TString FormFormat(const TString &FilenameFormat)
Form output file name according to file info list, proc info list and run data.
Definition: TRestRun.cxx:941
TFile * MergeToOutputFile(std::vector< std::string > filefullnames, std::string outputfilename="")
Form REST output file by merging a list of files together.
Definition: TRestRun.cxx:986
void PrintStartDate()
Prints the run start date and time in human format.
Definition: TRestRun.cxx:1860
Double_t fStartTime
Event absolute starting time/date (unix timestamp)
Definition: TRestRun.h:36
void WriteWithDataBase()
Write this object into TFile and add a new entry in database.
Definition: TRestRun.cxx:1093
Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0) override
overwriting the write() method with fStore considered
Definition: TRestRun.cxx:1348
void ReadFileInfo(const std::string &filename)
Extract file info from a file, and save it in the file info list.
Definition: TRestRun.cxx:653
Double_t fEndTime
Event absolute ending time/date (unix timestamp)
Definition: TRestRun.h:37
Int_t GetNextEvent(TRestEvent *targetEvent, TRestAnalysisTree *targetTree)
Get next event by writing event data into target event and target tree.
Definition: TRestRun.cxx:797
TRestEvent * GetNextEventWithConditions(const std::string &)
Load the next event that satisfies the conditions specified by a string.
Definition: TRestRun.cxx:1525
static std::pair< std::string, std::string > SeparatePathAndName(const std::string &fullname)
Separate path and filename in a full path+filename string, returns a pair of string.
Definition: TRestTools.cxx:759
static std::string GetPureFileName(const std::string &fullPathFileName)
Removes all directories in the full path filename description given in the argument.
Definition: TRestTools.cxx:809
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 bool isPathWritable(const std::string &path)
Returns true if the path given by argument is writable.
Definition: TRestTools.cxx:724
static bool isAbsolutePath(const std::string &path)
Check if the path is absolute path or not.
Definition: TRestTools.cxx:741
static std::vector< std::string > GetFilesMatchingPattern(std::string pattern)
Returns a list of files whose name match the pattern string. Key word is "*". e.g....
Definition: TRestTools.cxx:918
static std::string RemoveMultipleSlash(std::string)
Returns the input string but without multiple slashes ("/")
Definition: TRestTools.cxx:790
static bool isRootFile(const std::string &filename)
Returns true if the filename has *.root* extension.
Definition: TRestTools.cxx:679
TClass * GetClassQuick(std::string type)
TRestReflector Assembly(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 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.