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 = (TRestAnalysisTree*)fAnalysisTree->Clone(); // we must make a copy to have
519 // TBrowser correctly browsed.
520 for (int i = 1; i <= fNFilesSplit; i++) {
521 string filename = fInputFile->GetName() + (string) "." + ToString(i);
522 RESTInfo << filename << " --> ";
523 RESTInfo << (fAnalysisTree->AddChainFile(filename) ? "success" : "failed") << RESTendl;
524 }
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;
529 }
530 }
531
532 // Note: we call GetEntries() to initialize total entry number
533 // Otherwise the child analysis tree's observables will be reset
534 // on the next call of GetEntries()
535 fAnalysisTree->GetEntries();
536 // Call GetEntry() to initialize observables and connect branches
537 fAnalysisTree->GetEntry(0);
538
539 _eventTree = (TTree*)fInputFile->Get("EventTree");
540 } else if (fInputFile->FindKey("TRestAnalysisTree") != nullptr) {
541 // This is v2.1.6- version of input file, we directly find EventTree and
542 // AnalysisTree. The old name pattern is "TRestXXXEventTree-eventBranch"
543 // and "TRestAnalysisTree"
544 RESTWarning << "Loading root file from old version REST!" << RESTendl;
545 fAnalysisTree = (TRestAnalysisTree*)fInputFile->Get("TRestAnalysisTree");
546 fAnalysisTree->GetEntry(0);
547
548 TIter nextkey(fInputFile->GetListOfKeys());
549 TKey* key;
550 while ((key = (TKey*)nextkey())) {
551 // cout << key->GetName() << endl;
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());
558 break;
559 }
560 }
561 RESTDebug << "Old REST file successfully recovered!" << RESTendl;
562 } else {
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;
566 }
567
568 if (_eventTree != nullptr) {
569 if (fNFilesSplit > 0) {
570 // eventTree shall be initialized as TChain
571 delete _eventTree;
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;
576
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;
581 }
582 fEventTree = _fEventTree;
583 } else {
584 fEventTree = _eventTree;
585 }
586
587 RESTDebug << "Finding event branch.." << RESTendl;
588 if (fInputEvent == nullptr) {
589 TObjArray* branches = fEventTree->GetListOfBranches();
590 // get the last event branch as input event branch
591 if (branches->GetLast() > -1) {
592 TBranch* br = (TBranch*)branches->At(branches->GetLast());
593
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;
597 } else {
598 string type = Replace(br->GetName(), "Branch", "", 0);
599 TClass* cl = TClass::GetClass(type.c_str());
600 if (cl->HasDictionary()) {
601 fInputEvent = REST_Reflection::Assembly(type);
602 } else if (fInputEvent != nullptr) {
603 delete fInputEvent;
604 fInputEvent = nullptr;
605 }
606
607 if (fInputEvent == nullptr) {
608 RESTError << "TRestRun:OpenInputFile. Cannot initialize input event, event "
609 "tree not read"
610 << RESTendl;
611 RESTError
612 << "Please install corresponding libraries to provide root dictionaries for "
613 "class reading."
614 << RESTendl;
615 return;
616 }
617
618 fInputEvent->InitializeWithMetadata(this);
619 fEventTree->SetBranchAddress(br->GetName(), &fInputEvent);
620 fEventBranchLoc = branches->GetLast();
621 RESTDebug << "found event branch of event type: " << fInputEvent->ClassName()
622 << RESTendl;
623 }
624 }
625 } else {
626 string brname = (string)fInputEvent->ClassName() + "Branch";
627 if (fEventTree->GetBranch(brname.c_str()) == nullptr) {
628 RESTWarning << "REST WARNING (OpenInputFile) : No matched event branch "
629 "inside file : "
630 << filename << RESTendl;
631 RESTWarning << "Branch required: " << brname << RESTendl;
632 } else {
633 fEventTree->SetBranchAddress(brname.c_str(), &fInputEvent);
634 RESTDebug << brname << " is found and set!" << RESTendl;
635 }
636 }
637 } else {
638 RESTDebug << "TRestRun:OpenInputFile. EventTree was not found" << RESTendl;
639 RESTDebug << "This is a pure analysis file!" << RESTendl;
640 fInputEvent = nullptr;
641 }
642 }
643}
644
652void TRestRun::ReadFileInfo(const string& filename) {
653 RESTDebug << "begin collecting basic file info..." << filename << RESTendl;
654
655 // basic file info: modify time, total bytes, etc.
656 struct stat buf;
657 FILE* fp = fopen(filename.c_str(), "rb");
658 if (!fp) {
659 RESTError << "TRestRun::ReadFileInfo. Something went wrong with fopen()!" << strerror(errno)
660 << RESTendl;
661 exit(1);
662 }
663 int fd = fileno(fp);
664 fstat(fd, &buf);
665 fclose(fp);
666 if (fEndTime == 0) {
667 fEndTime = buf.st_mtime;
668 }
669
670 if (TRestTools::isRootFile((string)filename)) {
671 fTotalBytes = buf.st_size;
672 }
673
674 RESTDebug << "begin matching file name pattern for more file info..." << RESTendl;
675 // format example:
676 // run[fRunNumber]_cobo[aaa]_frag[bbb]_Vm[TRestDetector::fAmplificationVoltage].graw
677 // we are going to match it with inputfile:
678 // run00042_cobo1_frag0000_Vm350.graw
679 string format = GetParameter("inputFormat", "");
680 string name = TRestTools::SeparatePathAndName(filename).second;
681
682 vector<string> formatSectionList;
683 vector<string> formatPrefixList;
684
685 int pos = -1;
686 int pos1 = 0;
687 int pos2 = 0;
688 while (true) {
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));
693 break;
694 }
695
696 formatSectionList.push_back(format.substr(pos1 + 1, pos2 - pos1 - 1));
697 formatPrefixList.push_back(format.substr(pos + 1, pos1 - pos - 1));
698
699 pos = pos2;
700 }
701
702 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;
706 return;
707 }
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;
714 return;
715 }
716
717 string infoFromFileName = name.substr(pos1, pos2 - pos1);
718
719 RESTDebug << "File pattern matching. key: " << formatSectionList[i] << " (between the mark \""
720 << formatPrefixList[i] << "\" and \"" << formatPrefixList[i + 1]
721 << "\"), value: " << infoFromFileName << RESTendl;
722
723 // run[fRunNumber]_cobo[aaa]_frag[bbb]_Vm[TRestDetector::fAmplificationVoltage].graw
724 bool inforead = false;
725 if (!inforead) {
726 // 1. store special file pattern parameters as TRestRun data member: fRunNumber
727 if (DataMemberNameToParameterName(formatSectionList[i]) != "") {
728 RESTValue member = RESTValue(this, this->ClassName()).GetDataMember(formatSectionList[i]);
729 if (!member.IsZombie()) {
730 member.ParseString(infoFromFileName);
731 inforead = true;
732 } else {
733 RESTWarning << "TRestRun: file name format field \"" << formatSectionList[i]
734 << "\"(value = " << infoFromFileName
735 << ") not registered, data member does not exist in TRestRun!" << RESTendl;
736 }
737 }
738 }
739
740 if (!inforead) {
741 // 2. store special file pattern parameters as data member of the loaded
742 // metadata class, e.g., TRestDetector::fAmplificationVoltage
743 vector<string> classDataMember = Split(formatSectionList[i], "::");
744 if (classDataMember.size() > 1) {
745 TRestMetadata* meta = GetMetadataClass(classDataMember[0]);
746 if (meta != nullptr) {
747 RESTValue member = RESTValue(meta, meta->ClassName()).GetDataMember(classDataMember[1]);
748 if (!member.IsZombie()) {
749 member.ParseString(infoFromFileName);
750 meta->UpdateMetadataMembers();
751 inforead = true;
752 } else {
753 RESTWarning << "TRestRun: file name format field \"" << formatSectionList[i]
754 << "\"(value = " << infoFromFileName
755 << ") not registered, metadata exist but without such datamember field!"
756 << RESTendl;
757 }
758 } else {
759 RESTWarning << "TRestRun: file name format field \"" << formatSectionList[i]
760 << "\"(value = " << infoFromFileName
761 << ") not registered, metadata does not exist!" << RESTendl;
762 }
763 }
764 }
765
766 // if (!inforead) {
767 // 3. store file format fields to REST_ARGS as global parameter: aaa, bbb
768 // REST_ARGS[formatsectionlist[i]] = infoFromFileName;
769 // }
770
771 pos = pos2 - 1;
772 }
773}
774
782 fCurrentEvent = 0;
783 if (fFileProcess != nullptr) {
784 fFileProcess->ResetEntry();
785 }
786}
787
796Int_t TRestRun::GetNextEvent(TRestEvent* targetEvent, TRestAnalysisTree* targetTree) {
797 bool messageShown = false;
798 TRestEvent* eve = fInputEvent;
799
800 if (fFileProcess != nullptr) {
801 RESTDebug << "TRestRun: getting next event from external process" << RESTendl;
802 GetEventExt:
803 mutex_read.lock();
804 fFileProcess->BeginOfEventProcess();
805 eve = fFileProcess->ProcessEvent(nullptr);
806 fFileProcess->EndOfEventProcess();
807 mutex_read.unlock();
808 fBytesRead = fFileProcess->GetTotalBytesRead();
809 // if (targettree != nullptr) {
810 // for (int n = 0; n < fAnalysisTree->GetNumberOfObservables(); n++)
811 // targettree->SetObservable(n, fAnalysisTree->GetObservable(n));
812 //}
813 fCurrentEvent++;
814 } else {
815 if (eve == nullptr) {
816 RESTDebug << "TRestRun::GetNextEvent(): input event has not been initialized!" << RESTendl;
817 } else {
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"
821 << RESTendl;
822 eve = nullptr;
823 } else {
824 if (fCurrentEvent >= fAnalysisTree->GetTree()->GetEntriesFast()) {
825 eve = nullptr;
826 } else {
827 if (targetTree != nullptr) {
828 // normal reading procedure
829 eve->Initialize();
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));
834 }
835 if (fEventTree != nullptr) {
836 if (fEventTree->IsA() == TChain::Class()) {
837 Long64_t entry = fEventTree->LoadTree(fCurrentEvent);
838 fBytesRead += ((TBranch*)fEventTree->GetTree()->GetListOfBranches()->UncheckedAt(
839 fEventBranchLoc))
840 ->GetEntry(entry);
841 } else {
842 fBytesRead +=
843 ((TBranch*)fEventTree->GetListOfBranches()->UncheckedAt(fEventBranchLoc))
844 ->GetEntry(fCurrentEvent);
845 }
846 }
847 fCurrentEvent++;
848 }
849 }
850 }
851 }
852
853 // cout << fHangUpEndFile << endl;
854
855 if (eve == nullptr) {
856 if (fHangUpEndFile && fFileProcess != nullptr) {
857 // if hangup is set, we continue calling ProcessEvent() of the
858 // external process, until there is non-null event yielded
859 if (!messageShown) {
860 RESTEssential << "external process file reading reaches end, waiting for more files"
861 << RESTendl;
862 }
863 usleep(1000000);
864 messageShown = true;
865 fCurrentEvent--;
866 goto GetEventExt;
867 }
868 fInputEvent = eve;
869 // if (fFileProcess != nullptr) fFileProcess->EndProcess();
870 return -1;
871 }
872
873 fInputEvent = eve;
874
875 if (fInputEvent->GetID() == 0 && fInputEvent->GetSubID() == 0) {
876 fInputEvent->SetID(fCurrentEvent - 1);
877 }
878
879 if (fInputEvent->GetRunOrigin() == 0) {
880 fInputEvent->SetRunOrigin(fRunNumber);
881 }
882
883 targetEvent->Initialize();
884 fInputEvent->CloneTo(targetEvent);
885
886 return 0;
887}
888
892std::vector<std::string> TRestRun::GetEventTypesList() {
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);
900 }
901 }
902 return list;
903}
904
908void TRestRun::GetEntry(Long64_t entry) {
909 if (entry >= GetEntries()) {
910 RESTWarning << "TRestRun::GetEntry. Entry requested out of limits" << RESTendl;
911 RESTWarning << "Total number of entries is : " << GetEntries() << RESTendl;
912 }
913
914 if (fAnalysisTree != nullptr) {
915 fAnalysisTree->GetEntry(entry);
916 }
917 if (fEventTree != nullptr) {
918 fEventTree->GetEntry(entry);
919 }
920
921 if (fInputEvent != nullptr) {
922 fInputEvent->InitializeReferences(this);
923 }
924
925 fCurrentEvent = entry;
926}
927
940TString TRestRun::FormFormat(const TString& FilenameFormat) {
941 string inString = (string)FilenameFormat;
942 string outString = (string)FilenameFormat;
943
944 RESTDebug << "TRestRun::FormFormat. In string : " << inString << RESTendl;
945
946 int pos = 0;
947 while (true) {
948 int pos1 = inString.find("[", pos);
949 int pos2 = inString.find("]", pos1);
950 if (pos1 == -1 || pos2 == -1) break;
951
952 string targetstr = inString.substr(pos1, pos2 - pos1 + 1); // with []
953 string target = inString.substr(pos1 + 1, pos2 - pos1 - 1); // without []
954 string replacestr = GetRunInformation(target);
955
956 RESTDebug << "TRestRun::FormFormat. target : " << target << RESTendl;
957 RESTDebug << "TRestRun::FormFormat. replacestr : " << replacestr << RESTendl;
958
959 // If we form an output file we are willing to form the output filename
960 // using the latest version. But the version is set just before we
961 // call Write.
962 if (target == "fVersion") replacestr = (string)REST_RELEASE;
963 if (target == "fCommit") replacestr = (string)REST_COMMIT;
964
965 if (replacestr != target) {
966 if (target == "fRunNumber" || target == "fParentRunNumber") {
967 replacestr = Form("%05d", StringToInteger(replacestr));
968 }
969 outString = Replace(outString, targetstr, replacestr, 0);
970 }
971 pos = pos2 + 1;
972 }
973
974 return outString;
975}
976
985TFile* TRestRun::MergeToOutputFile(vector<string> filenames, string outputfilename) {
986 RESTDebug << "TRestRun::FormOutputFile. target : " << outputfilename << RESTendl;
987 string filename;
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");
993 } else {
994 filename = outputfilename;
995 RESTInfo << "Updating file : " << filename << RESTendl;
996 m->OutputFile(filename.c_str(), "UPDATE");
997 }
998
999 RESTDebug << "TRestRun::FormOutputFile. Starting to add files" << RESTendl;
1000
1001 for (unsigned int i = 0; i < filenames.size(); i++) {
1002 m->AddFile(filenames[i].c_str(), false);
1003 }
1004
1005 if (m->Merge()) {
1006 for (unsigned int i = 0; i < filenames.size(); i++) {
1007 remove(filenames[i].c_str());
1008 }
1009 } else {
1010 fOutputFileName = "";
1011 RESTError << "(Merge files) failed to merge process files." << RESTendl;
1012 exit(1);
1013 }
1014
1015 delete m;
1016
1017 // we rename the created output file
1018 fOutputFileName = FormFormat(filename);
1019 rename(filename.c_str(), fOutputFileName);
1020
1021 // write metadata into the output file
1022 fOutputFile = new TFile(fOutputFileName, "update");
1023 RESTDebug << "TRestRun::FormOutputFile. Calling WriteWithDataBase()" << RESTendl;
1024 this->WriteWithDataBase();
1025
1026 RESTcout << this->ClassName() << " Created ..." << RESTendl;
1027 RESTcout << "- Path : " << TRestTools::SeparatePathAndName((string)fOutputFileName).first << RESTendl;
1028 RESTcout << "- Filename : " << TRestTools::SeparatePathAndName((string)fOutputFileName).second
1029 << RESTendl;
1030 return fOutputFile;
1031}
1032
1037 CloseFile();
1038
1039 fOutputFileName = FormFormat(fOutputFileName);
1040 // remove unwanted "./" etc. from the path while resolving them
1041 fOutputFileName = std::filesystem::weakly_canonical(fOutputFileName.Data());
1042
1043 fOutputFile = new TFile(fOutputFileName, "recreate");
1044 fAnalysisTree = new TRestAnalysisTree("AnalysisTree", "AnalysisTree");
1045 fEventTree = new TTree("EventTree", "EventTree");
1046
1047 fAnalysisTree->Write(nullptr, TObject::kOverwrite);
1048 fEventTree->Write(nullptr, TObject::kOverwrite);
1049 this->WriteWithDataBase();
1050
1051 RESTcout << "TRestRun: Output File Created." << RESTendl;
1052 RESTcout << "- Path : " << TRestTools::SeparatePathAndName((string)fOutputFileName).first << RESTendl;
1053 RESTcout << "- Filename : " << TRestTools::SeparatePathAndName((string)fOutputFileName).second
1054 << RESTendl;
1055 return fOutputFile;
1056}
1057
1058TFile* TRestRun::UpdateOutputFile() {
1059 if (fOutputFile != nullptr) {
1060 if (fOutputFile->IsOpen()) {
1061 fOutputFile->ReOpen("update");
1062 }
1063
1064 fOutputFile->cd();
1065
1066 fAnalysisTree->Write(nullptr, kOverwrite);
1067 fEventTree->Write(nullptr, kOverwrite);
1068
1069 this->WriteWithDataBase();
1070
1071 RESTcout << "TRestRun: Output File Updated." << RESTendl;
1072 RESTcout << "- Path : " << TRestTools::SeparatePathAndName((string)fOutputFileName).first << RESTendl;
1073 RESTcout << "- Filename : " << TRestTools::SeparatePathAndName((string)fOutputFileName).second
1074 << RESTendl;
1075 return fOutputFile;
1076
1077 } else {
1078 RESTError << "TRestRun::UpdateOutputFile(): output file is closed" << RESTendl;
1079 }
1080 return nullptr;
1081}
1082
1093 TRestAnalysisTree* tree = nullptr;
1094
1095 RESTDebug << "TRestRun::WriteWithDataBase. Getting entries in analysisTree" << RESTendl;
1096
1097 // record the entries saved
1098 fEntriesSaved = -1;
1099 if (fOutputFile != nullptr) {
1100 tree = (TRestAnalysisTree*)fOutputFile->Get("AnalysisTree");
1101 if (tree != nullptr) {
1102 fEntriesSaved = tree->GetEntries();
1103 }
1104 }
1105 RESTDebug << "TRestRun::WriteWithDataBase. Entries found : " << fEntriesSaved << RESTendl;
1106
1107 // If time was not written by any other process we record the current time
1108 if (fEndTime == 0) {
1109 time_t timev;
1110 time(&timev);
1111 fEndTime = (Double_t)timev;
1112 }
1113
1114 fRunUser = REST_USER;
1115
1116 // save metadata objects in file
1117
1118 RESTDebug << "TRestRun::WriteWithDataBase. Calling this->Write(0, kOverwrite)" << RESTendl;
1119 this->Write(nullptr, kOverwrite);
1120
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()
1126 << RESTendl;
1127 for (const auto& inputMetadata : fInputMetadata) {
1128 RESTDebug << metadata->GetName() << " == " << inputMetadata->GetName() << RESTendl;
1129 if (metadata == inputMetadata) {
1130 historic = true;
1131 break;
1132 }
1133 }
1134
1135 if (!historic) {
1136 RESTDebug << "NO historic" << RESTendl;
1137 metadata->Write(metadata->GetName(), kOverwrite);
1138 } else {
1139 RESTDebug << "IS historic" << RESTendl;
1140 if (fSaveHistoricData) metadata->Write(metadata->GetName(), kOverwrite);
1141 }
1142 }
1143
1144 // write to database
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;
1149 }
1150}
1151
1156 fEntriesSaved = -1;
1157 if (fAnalysisTree != nullptr) {
1158 fEntriesSaved = fAnalysisTree->GetEntries();
1159 if (fAnalysisTree->GetEntries() > 0 && fInputFile == nullptr) {
1160 if (fOutputFile != nullptr) {
1161 fOutputFile->cd();
1162 fAnalysisTree->Write(nullptr, kOverwrite);
1163 this->Write(nullptr, kOverwrite);
1164 }
1165 }
1166 delete fAnalysisTree;
1167 fAnalysisTree = nullptr;
1168 }
1169
1170 if (fEventTree != nullptr) {
1171 if (fEventTree->GetEntries() > 0 && fInputFile == nullptr) fEventTree->Write(nullptr, kOverwrite);
1172 delete fEventTree;
1173 fEventTree = nullptr;
1174 }
1175
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);
1181 i--;
1182 fInputMetadata.erase(fInputMetadata.begin() + j);
1183 break;
1184 }
1185 }
1186 }
1187
1188 if (fOutputFile != nullptr) {
1189 fOutputFile->Write(0, TObject::kOverwrite);
1190 fOutputFile->Close();
1191 delete fOutputFile;
1192 fOutputFile = nullptr;
1193 }
1194 if (fInputFile != nullptr) {
1195 fInputFile->Close();
1196 fInputFile = nullptr;
1197 }
1198}
1199
1204 if (fFileProcess == nullptr && p != nullptr) {
1205 fFileProcess = p;
1206
1207 fFileProcess->OpenInputFiles(Vector_cast<TString, string>(fInputFileNames));
1208 fFileProcess->InitProcess();
1209 fInputEvent = fFileProcess->GetOutputEvent();
1210 if (fInputEvent == nullptr) {
1211 RESTError << "The external process \"" << p->GetName() << "\" doesn't yield any output event!"
1212 << RESTendl;
1213 exit(1);
1214 } else {
1215 fInputEvent->SetRunOrigin(fRunNumber);
1216 fInputEvent->SetSubRunOrigin(fParentRunNumber);
1217 fInputEvent->SetTimeStamp(fStartTime);
1218 }
1219 fInputFile = nullptr;
1220 // we make sure external processes can access to analysis tree
1221 fAnalysisTree = new TRestAnalysisTree("externalProcessAna", "externalProcessAna");
1222 p->SetAnalysisTree(fAnalysisTree);
1223 fTotalBytes = p->GetTotalBytes();
1224
1225 GetNextEvent(fInputEvent, nullptr);
1226 // fAnalysisTree->CreateBranches();
1227 RESTInfo << "The external file process has been set! Name : " << fFileProcess->GetName() << RESTendl;
1228 } else {
1229 if (fFileProcess != nullptr) {
1230 RESTError << "There can only be one file process!" << RESTendl;
1231 exit(1);
1232 }
1233 if (p == nullptr) {
1234 RESTWarning << "Given file process is null, skipping..." << RESTendl;
1235 }
1236 }
1237}
1238
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);
1251 }
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
1258 << RESTendl;
1259 fInputEvent = event;
1260 fEventTree->SetBranchAddress(branchName.c_str(), &fInputEvent);
1261 fEventTree->SetBranchStatus(branchName.c_str(), false);
1262 fEventBranchLoc = i;
1263 break;
1264 } else if (i == branches->GetLast()) {
1265 RESTWarning << "REST Warning : (TRestRun) cannot find corresponding "
1266 "branch in event tree!"
1267 << RESTendl;
1268 RESTWarning << "Event Type : " << event->ClassName() << RESTendl;
1269 RESTWarning << "Input event not set!" << RESTendl;
1270 }
1271 }
1272 } else {
1273 fInputEvent = event;
1274 }
1275 this->GetEntry(fCurrentEvent);
1276 }
1277}
1278
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());
1289 }
1290 }
1291}
1292
1298void TRestRun::ImportMetadata(const TString& File, const TString& name, const TString& type, Bool_t store) {
1299 const TString thisFile = SearchFile(File.Data());
1300 if (thisFile == "") {
1301 RESTError << "(ImportMetadata): The file " << thisFile << " does not exist!" << RESTendl;
1302 RESTError << RESTendl;
1303 return;
1304 }
1305 if (!TRestTools::isRootFile(thisFile.Data())) {
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;
1308 return;
1309 }
1310
1311 TFile* file = TFile::Open(thisFile);
1312 // TODO give error in case we try to obtain a class that is not TRestMetadata
1313 if (type == "" && name == "") {
1314 RESTError << "(ImportMetadata) : metadata type and name is not "
1315 "specified!"
1316 << RESTendl;
1317 return;
1318 }
1319
1320 TRestMetadata* meta = nullptr;
1321 if (name != "") {
1322 meta = GetMetadata(name, file);
1323 } else if (type != "") {
1324 meta = GetMetadataClass(type, file);
1325 }
1326
1327 if (meta == nullptr) {
1328 cout << "REST ERROR (ImportMetadata) : " << name << " does not exist." << endl;
1329 cout << "Inside root file : " << File << endl;
1330 GetChar();
1331 file->Close();
1332 delete file;
1333 return;
1334 }
1335
1336 if (store)
1337 meta->Store();
1338 else
1339 meta->DoNotStore();
1340
1341 fMetadata.push_back(meta);
1342 meta->LoadConfigFromBuffer();
1343 file->Close();
1344 delete file;
1345}
1346
1347Int_t TRestRun::Write(const char* name, Int_t option, Int_t bufsize) {
1348 ReSetVersion();
1349 return TRestMetadata::Write(name, option, bufsize);
1350}
1351
1352Double_t TRestRun::GetRunLength() const {
1353 if (fEndTime - fStartTime == -1) {
1354 cout << "Run time is not set\n";
1355 }
1356 return fEndTime - fStartTime;
1357}
1358
1359Long64_t TRestRun::GetTotalBytes() {
1360 if (fFileProcess != nullptr) {
1361 fTotalBytes = fFileProcess->GetTotalBytes();
1362 }
1363 return fTotalBytes;
1364}
1365
1366Long64_t TRestRun::GetEntries() const {
1367 if (fAnalysisTree != nullptr) {
1368 return fAnalysisTree->GetEntries();
1369 }
1370 return fEntriesSaved;
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}
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.
Definition: TRestEvent.h:38
virtual void InitializeReferences(TRestRun *run)
Initialize dynamical references when loading the event from a root file.
Definition: TRestEvent.cxx:175
virtual void CloneTo(TRestEvent *target)
Clone the content of this TRestEvent object to another.
Definition: TRestEvent.cxx:98
virtual void Initialize()=0
Definition: TRestEvent.cxx:73
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:1282
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:1155
TFile * FormOutputFile()
Create a new TFile as REST output file. Writing metadata objects into it.
Definition: TRestRun.cxx:1036
void ResetEntry()
Reset file reading progress.
Definition: TRestRun.cxx:781
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:1245
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:908
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:892
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:1298
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:1203
TString FormFormat(const TString &FilenameFormat)
Form output file name according to file info list, proc info list and run data.
Definition: TRestRun.cxx:940
TFile * MergeToOutputFile(std::vector< std::string > filefullnames, std::string outputfilename="")
Form REST output file by merging a list of files together.
Definition: TRestRun.cxx:985
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:1092
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:1347
void ReadFileInfo(const std::string &filename)
Extract file info from a file, and save it in the file info list.
Definition: TRestRun.cxx:652
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:796
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:813
static std::string GetPureFileName(const std::string &fullPathFileName)
Removes all directories in the full path filename description given in the argument.
Definition: TRestTools.cxx:863
static bool fileExists(const std::string &filename)
Returns true if the file (or directory) with path filename exists.
Definition: TRestTools.cxx:728
static std::vector< std::string > GetFilesMatchingPattern(std::string pattern, bool unlimited=false)
Returns a list of files whose name match the pattern string. Key word is "*". e.g....
Definition: TRestTools.cxx:976
static int ConvertVersionCode(std::string in)
Convert version to a unique string.
static bool isPathWritable(const std::string &path)
Returns true if the path given by argument is writable.
Definition: TRestTools.cxx:778
static bool isAbsolutePath(const std::string &path)
Check if the path is absolute path or not.
Definition: TRestTools.cxx:795
static std::string RemoveMultipleSlash(std::string)
Returns the input string but without multiple slashes ("/")
Definition: TRestTools.cxx:844
static bool isRootFile(const std::string &filename)
Returns true if the filename has *.root* extension.
Definition: TRestTools.cxx:733
TClass * GetClassQuick(std::string type)
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.