REST-for-Physics  v2.3
Rare Event Searches ToolKit for Physics
Loading...
Searching...
No Matches
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 delete fInputEvent;
1188 fInputEvent = nullptr;
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 fEntriesSaved;
1372 // return REST_MAXIMUM_EVENTS;
1373}
1374
1375// Getters
1376TRestEvent* TRestRun::GetEventWithID(Int_t eventID, Int_t subEventID, const TString& tag) {
1377 if (fAnalysisTree != nullptr) {
1378 int nEntries = fAnalysisTree->GetEntries();
1379
1380 // set analysis tree to read only three branches
1381 fAnalysisTree->SetBranchStatus("*", false);
1382 fAnalysisTree->SetBranchStatus("eventID", true);
1383 fAnalysisTree->SetBranchStatus("subEventID", true);
1384 fAnalysisTree->SetBranchStatus("subEventTag", true);
1385
1386 // just look through the whole analysis tree and find the entry
1387 // this is not good!
1388 for (int i = 0; i < nEntries; i++) {
1389 fAnalysisTree->GetEntry(i);
1390 if (fAnalysisTree->GetEventID() == eventID) {
1391 if (subEventID != -1 && fAnalysisTree->GetSubEventID() != subEventID) continue;
1392 if (tag != "" && fAnalysisTree->GetSubEventTag() != tag) continue;
1393 if (fEventTree != nullptr) fEventTree->GetEntry(i);
1394 fAnalysisTree->SetBranchStatus("*", true);
1395 fAnalysisTree->GetEntry(i);
1396 fCurrentEvent = i;
1397 return fInputEvent;
1398 }
1399 }
1400 // reset the branch status
1401 fAnalysisTree->SetBranchStatus("*", true);
1402 }
1403 return nullptr;
1404}
1405
1406std::vector<int> TRestRun::GetEventEntriesWithConditions(const string& cuts, int startingIndex,
1407 int maxNumber) {
1408 int max = maxNumber;
1409 if (max < 0) max = GetEntries();
1410
1411 std::vector<int> eventIds;
1412 // parsing cuts
1413 std::vector<string> observables;
1414 std::vector<string> operators;
1415 std::vector<Double_t> values;
1416 // it is necessary that this vector is sorted from longest to shortest
1417 const std::vector<string> validOperators = {"==", "<=", ">=", "=", ">", "<"};
1418
1419 vector<string> cutsVector = Split(cuts, "&&", false, true);
1420
1421 for (unsigned int i = 0; i < cutsVector.size(); i++) {
1422 string cut = cutsVector[i];
1423 for (unsigned int j = 0; j < validOperators.size(); j++) {
1424 if (cut.find(validOperators[j]) != string::npos) {
1425 operators.push_back(validOperators[j]);
1426 observables.push_back((string)cut.substr(0, cut.find(validOperators[j])));
1427 values.push_back(std::stod((string)cut.substr(
1428 cut.find(validOperators[j]) + validOperators[j].length(), string::npos)));
1429 break;
1430 }
1431 }
1432 }
1433
1434 // check if observable name corresponds to a valid observable on the tree
1435 if (fAnalysisTree == nullptr) {
1436 return eventIds;
1437 }
1438 Int_t nEntries = fAnalysisTree->GetEntries();
1439 auto branches = fAnalysisTree->GetListOfBranches();
1440 std::set<string> branchNames;
1441 for (int i = 0; i < branches->GetEntries(); i++) {
1442 branchNames.insert((string)branches->At(i)->GetName());
1443 }
1444 // verify all observables in cuts are branch names
1445 for (unsigned int i = 0; i < observables.size(); i++) {
1446 // verify operators
1447 if (std::find(validOperators.begin(), validOperators.end(), operators[i]) == validOperators.end()) {
1448 // invalid operation
1449 cout << "invalid operation '" << operators[i] << "' for 'TRestRun::GetEventIdsWithConditions'"
1450 << endl;
1451 return eventIds;
1452 }
1453 // verify observables
1454 if (branchNames.count(observables[i]) == 0) {
1455 // invalid observable name
1456 cout << "invalid observable '" << observables[i] << "' for 'TRestRun::GetEventIdsWithConditions'"
1457 << endl;
1458 cout << "valid branch names: ";
1459 for (auto branchName : branchNames) {
1460 cout << branchName << " ";
1461 }
1462 cout << endl;
1463 return eventIds;
1464 }
1465 }
1466 // read only the necessary branches
1467 fAnalysisTree->SetBranchStatus("*", false);
1468 for (unsigned int i = 0; i < observables.size(); i++) {
1469 fAnalysisTree->SetBranchStatus(observables[i].c_str(), true);
1470 }
1471 // comparison code
1472 Double_t valueToCompareFrom;
1473 bool comparisonResult;
1474 int i;
1475 for (int iNoOffset = 0; iNoOffset < nEntries; iNoOffset++) {
1476 i = (iNoOffset + startingIndex) % nEntries;
1477 fAnalysisTree->GetEntry(i);
1478 comparisonResult = true;
1479 for (unsigned int j = 0; j < observables.size(); j++) {
1480 valueToCompareFrom = fAnalysisTree->GetDblObservableValue(observables[j].c_str());
1481 if (operators[j] == "=" || operators[j] == "==") {
1482 comparisonResult = comparisonResult && (valueToCompareFrom == values[j]);
1483 } else if (operators[j] == "<") {
1484 comparisonResult = comparisonResult && (valueToCompareFrom < values[j]);
1485 } else if (operators[j] == "<=") {
1486 comparisonResult = comparisonResult && (valueToCompareFrom <= values[j]);
1487 } else if (operators[j] == ">") {
1488 comparisonResult = comparisonResult && (valueToCompareFrom > values[j]);
1489 } else if (operators[j] == ">=") {
1490 comparisonResult = comparisonResult && (valueToCompareFrom >= values[j]);
1491 }
1492 }
1493
1494 if (comparisonResult) {
1495 if ((int)eventIds.size() < max) {
1496 eventIds.push_back(i);
1497 } else {
1498 break;
1499 }
1500 }
1501 }
1502 // reset branch status
1503 fAnalysisTree->SetBranchStatus("*", true);
1504 return eventIds;
1505}
1506
1507std::vector<int> TRestRun::GetEventIdsWithConditions(const string& cuts, int startingIndex, int maxNumber) {
1508 int max = maxNumber;
1509 if (max < 0) max = GetEntries();
1510
1511 auto indices = GetEventEntriesWithConditions(cuts, startingIndex, max);
1512 std::vector<int> ids;
1513 for (unsigned int i = 0; i < indices.size(); i++) {
1514 GetEntry(indices[i]);
1515 ids.push_back(fAnalysisTree->GetEventID());
1516 }
1517 return ids;
1518}
1519
1527 // we retrieve only one index starting from position set by the counter and increase by one
1528 if (fEventIndexCounter >= GetEntries()) {
1529 fEventIndexCounter = 0;
1530 }
1531 auto indices = GetEventEntriesWithConditions(cuts, fEventIndexCounter++, 1);
1532 if (indices.size() == 0) {
1533 // no events found
1534 return nullptr;
1535 } else {
1536 fAnalysisTree->GetEntry(indices[0]);
1537 fEventTree->GetEntry(indices[0]);
1538 fCurrentEvent = indices[0];
1539 return fInputEvent;
1540 }
1541}
1542
1543string TRestRun::GetRunInformation(const string& info) {
1544 string result = GetParameter(info, "");
1545 if (result != "") {
1546 return result;
1547 }
1548
1549 result = GetDataMemberValue(info);
1550 if (result != "") {
1551 return result;
1552 }
1553
1555 if (result != "") {
1556 return result;
1557 }
1558
1559 if (fHostmgr && fHostmgr->GetProcessRunner() != nullptr) {
1560 result = fHostmgr->GetProcessRunner()->GetProcInfo(info);
1561 if (result != "") {
1562 return result;
1563 }
1564 }
1565
1566 return info;
1567}
1568
1569TRestMetadata* TRestRun::GetMetadataClass(const TString& type, TFile* file) {
1570 if (file != nullptr) {
1571 TIter nextkey(file->GetListOfKeys());
1572 TKey* key;
1573 while ((key = (TKey*)nextkey())) {
1574 string kName = key->GetClassName();
1575
1576 if (REST_Reflection::GetClassQuick(kName.c_str()) != nullptr &&
1577 REST_Reflection::GetClassQuick(kName.c_str())->InheritsFrom(type)) {
1578 TRestMetadata* metadata = file->Get<TRestMetadata>(key->GetName());
1579
1580 if (metadata != nullptr && metadata->InheritsFrom("TRestMetadata")) {
1581 return metadata;
1582 } else {
1583 RESTWarning << "TRestRun::GetMetadataClass() : The object to import is "
1584 "not inherited from TRestMetadata"
1585 << RESTendl;
1586 }
1587 }
1588 }
1589 } else {
1590 for (unsigned int i = 0; i < fMetadata.size(); i++)
1591 if (fMetadata[i]->InheritsFrom(type)) return fMetadata[i];
1592
1593 if (fInputFile != nullptr && this->GetVersionCode() >= TRestTools::ConvertVersionCode("2.2.1")) {
1594 return GetMetadataClass(type, fInputFile);
1595 }
1596 }
1597
1598 return nullptr;
1599}
1600
1601TRestMetadata* TRestRun::GetMetadata(const TString& name, TFile* file) {
1602 if (file != nullptr) {
1603 TIter nextkey(file->GetListOfKeys());
1604 TKey* key;
1605 while ((key = (TKey*)nextkey())) {
1606 string kName = key->GetName();
1607
1608 if (kName == name) {
1609 TRestMetadata* metadata = file->Get<TRestMetadata>(name);
1610
1611 if (metadata->InheritsFrom("TRestMetadata")) {
1612 return metadata;
1613 } else {
1614 RESTWarning << "TRestRun::GetMetadata() : The object to import is not "
1615 "inherited from TRestMetadata"
1616 << RESTendl;
1617 }
1618 }
1619 }
1620 } else {
1621 for (unsigned int i = 0; i < fMetadata.size(); i++) {
1622 if (fMetadata[i]->GetName() == name) {
1623 return fMetadata[i];
1624 }
1625 }
1626 }
1627
1628 return nullptr;
1629}
1630
1631std::vector<std::string> TRestRun::GetMetadataNames() {
1632 std::vector<std::string> strings;
1633
1634 for (int n = 0; n < GetNumberOfMetadata(); n++) strings.push_back(fMetadata[n]->GetName());
1635
1636 return strings;
1637}
1638
1639std::vector<std::string> TRestRun::GetMetadataTitles() {
1640 std::vector<std::string> strings;
1641
1642 for (int n = 0; n < GetNumberOfMetadata(); n++) strings.push_back(fMetadata[n]->GetTitle());
1643
1644 return strings;
1645}
1646
1653string TRestRun::ReplaceMetadataMembers(const string& instr, Int_t precision) {
1654 if (instr.find("[", 0) == string::npos) return instr;
1655 string outstring = instr;
1656
1657 int startPosition = 0;
1658 int endPosition = 0;
1659 while ((startPosition = outstring.find("[", endPosition)) != (int)string::npos) {
1660 endPosition = outstring.find("]", startPosition + 1);
1661 string s = outstring.substr(startPosition + 1, endPosition - startPosition - 1);
1662 int cont = count(s.begin(), s.end(), '[') - count(s.begin(), s.end(), ']');
1663
1664 if (cont < 0) RESTError << "This is a coding error at ReplaceMetadataMembers!" << RESTendl;
1665
1666 // We search for the enclosing ']'. Since we might find a vector index inside.
1667 while (cont > 0) {
1668 endPosition = outstring.find("]", endPosition + 1);
1669 s = outstring.substr(startPosition + 1, endPosition - startPosition - 1);
1670 cont = count(s.begin(), s.end(), '[') - count(s.begin(), s.end(), ']');
1671 if (endPosition == (int)string::npos) break;
1672 }
1673 if (endPosition == (int)string::npos) break;
1674
1675 string expressionToReplace = outstring.substr(startPosition + 1, endPosition - startPosition - 1);
1676 string value = ReplaceMetadataMember(expressionToReplace);
1677
1678 outstring.replace(startPosition, endPosition - startPosition + 1, value);
1679 endPosition = 0;
1680 }
1681
1682 outstring = Replace(outstring, "{{", "[");
1683 outstring = Replace(outstring, "}}", "]");
1684
1685 return REST_StringHelper::ReplaceMathematicalExpressions(outstring, precision);
1686}
1687
1691//
1704string TRestRun::ReplaceMetadataMember(const string& instr, Int_t precision) {
1705 if (instr.find("::") == string::npos && instr.find("->") == string::npos) {
1706 return "{{" + instr + "}}";
1707 }
1708 vector<string> results = Split(instr, "::", false, true);
1709 if (results.size() == 1) results = Split(instr, "->", false, true);
1710
1711 if (results.size() == 2) {
1712 size_t index = 0;
1713 int pos1 = results[1].find("[", 0);
1714 int pos2 = results[1].find("]", pos1);
1715 if (pos1 > 0 && pos2 > 0) {
1716 string indexStr = results[1].substr(pos1 + 1, pos2 - pos1 - 1); // without []
1717
1718 index = StringToInteger(indexStr);
1719 if (index < 0) index = 0;
1720
1721 results[1] = results[1].substr(0, pos1);
1722 }
1723
1724 if (GetMetadata(results[0])) {
1725 if (index >= this->GetMetadata(results[0])->GetDataMemberValues(results[1], precision).size()) {
1726 RESTWarning << "TRestRun::ReplaceMetadataMember. Index out of range!" << RESTendl;
1727 RESTWarning << "Returning the first element" << RESTendl;
1728 index = 0;
1729 }
1730 return this->GetMetadata(results[0])->GetDataMemberValues(results[1], precision)[index];
1731 }
1732
1733 if (GetMetadataClass(results[0])) {
1734 if (index >=
1735 this->GetMetadataClass(results[0])->GetDataMemberValues(results[1], precision).size()) {
1736 RESTWarning << "TRestRun::ReplaceMetadataMember. Index out of range!" << RESTendl;
1737 RESTWarning << "Returning the first element" << RESTendl;
1738 index = 0;
1739 }
1740 return this->GetMetadataClass(results[0])->GetDataMemberValues(results[1], precision)[index];
1741 }
1742
1743 } else
1744 RESTError << "TRestRun::ReplaceMetadataMember. Wrong number of elements found" << RESTendl;
1745
1746 RESTWarning << "TRestRun::ReplaceMetadataMember. " << instr << " not found!" << RESTendl;
1747 return "";
1748}
1749
1753//
1769Bool_t TRestRun::EvaluateMetadataMember(const string& instr) {
1770 if (instr == "") return true;
1771
1772 std::vector<string> oper = {"=", "==", "<=", "<", ">=", ">", "!="};
1773
1774 string expOp = "";
1775 std::vector<string> results;
1776 for (unsigned int n = 0; n < oper.size(); n++) {
1777 size_t pos = 0;
1778 if (instr.find("->") != string::npos) pos = instr.find("->") + 2;
1779
1780 if (instr.find(oper[n], pos) != string::npos) {
1781 expOp = oper[n];
1782 results = Split(instr, oper[n], false, true, pos);
1783 break;
1784 }
1785 }
1786
1787 if (expOp == "") {
1788 RESTWarning << "TRestRun::EvaluateMetadataMember. Not valid operator found in expression : " << instr
1789 << RESTendl;
1790 return false;
1791 }
1792
1793 if (results.size() != 2) {
1794 RESTWarning << "TRestRun::EvaluateMetadataMember. Not valid expression : " << instr << RESTendl;
1795 return false;
1796 }
1797
1798 if (!isANumber(results[1])) {
1799 if (ReplaceMetadataMember(results[0]).find(results[1]) != string::npos)
1800 return true;
1801 else
1802 return false;
1803 }
1804
1805 Double_t lvalue = StringToDouble(ReplaceMetadataMember(results[0]));
1806 Double_t rvalue = StringToDouble(results[1]);
1807
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 if (expOp == "!=" && lvalue != rvalue) return true;
1815
1816 return false;
1817}
1818
1823 // cout.precision(10);
1825
1826 RESTMetadata << "Version : " << this->GetVersion() << RESTendl;
1827 RESTMetadata << "Parent run number : " << GetParentRunNumber() << RESTendl;
1828 RESTMetadata << "Run number : " << GetRunNumber() << RESTendl;
1829 RESTMetadata << "Experiment/project : " << GetExperimentName() << RESTendl;
1830 RESTMetadata << "Run type : " << GetRunType() << RESTendl;
1831 RESTMetadata << "Run tag : " << GetRunTag() << RESTendl;
1832 RESTMetadata << "Run user : " << GetRunUser() << RESTendl;
1833 RESTMetadata << "Run description : " << GetRunDescription() << RESTendl;
1834 RESTMetadata << "Start Date/Time : " << ToDateTimeString(GetStartTimestamp()) << " ("
1835 << GetStartTimestamp() << ")" << RESTendl;
1836 RESTMetadata << "End Date/Time : " << ToDateTimeString(GetEndTimestamp()) << " (" << GetEndTimestamp()
1837 << ")" << RESTendl;
1838 RESTMetadata << "Input file : " << TRestTools::GetPureFileName((string)GetInputFileNamePattern())
1839 << RESTendl;
1840 RESTMetadata << "Output file : " << TRestTools::GetPureFileName((string)GetOutputFileName()) << RESTendl;
1841 if (fInputFile != nullptr) {
1842 RESTMetadata << "Data file : " << fInputFile->GetName();
1843 if (fNFilesSplit > 0) {
1844 RESTMetadata << " (Splitted into " << fNFilesSplit + 1 << " files)" << RESTendl;
1845 } else {
1846 RESTMetadata << RESTendl;
1847 }
1848 }
1849 RESTMetadata << "Number of events : " << fEntriesSaved << RESTendl;
1850 // metadata << "Input filename : " << fInputFilename << endl;
1851 // metadata << "Output filename : " << fOutputFilename << endl;
1852 // metadata << "Number of initial events : " << GetNumberOfEvents() << endl;
1853 // metadata << "Number of processed events : " << fProcessedEvents << endl;
1854 RESTMetadata << "---------------------------------------" << RESTendl;
1855 RESTMetadata << RESTendl;
1856}
1857
1862 cout.precision(10);
1863
1864 cout << "------------------------" << endl;
1865 cout << "---- Run start date ----" << endl;
1866 cout << "------------------------" << endl;
1867 cout << "Unix time : " << fStartTime << endl;
1868 time_t tt = (time_t)fStartTime;
1869 struct tm* tm = localtime(&tt);
1870
1871 char date[20];
1872 strftime(date, sizeof(date), "%Y-%m-%d", tm);
1873 cout << "Date : " << date << endl;
1874
1875 char time[20];
1876 strftime(time, sizeof(time), "%H:%M:%S", tm);
1877 cout << "Time : " << time << endl;
1878 cout << "++++++++++++++++++++++++" << endl;
1879}
1880
1881void TRestRun::PrintEndDate() {
1882 cout << "----------------------" << endl;
1883 cout << "---- Run end date ----" << endl;
1884 cout << "----------------------" << endl;
1885 cout << "Unix time : " << fEndTime << endl;
1886 time_t tt = (time_t)fEndTime;
1887 struct tm* tm = localtime(&tt);
1888
1889 char date[20];
1890 strftime(date, sizeof(date), "%Y-%m-%d", tm);
1891 cout << "Date : " << date << endl;
1892
1893 char time[20];
1894 strftime(time, sizeof(time), "%H:%M:%S", tm);
1895 cout << "Time : " << time << endl;
1896 cout << "++++++++++++++++++++++++" << endl;
1897}
1898
1904 Int_t nErrors = 0;
1905 for (unsigned int n = 0; n < fMetadata.size(); n++)
1906 if (fMetadata[n]->GetError()) nErrors++;
1907
1908 if (nErrors) {
1909 cout << endl;
1910 RESTError << "Found a total of " << nErrors << " metadata errors" << RESTendl;
1911 for (unsigned int n = 0; n < fMetadata.size(); n++)
1912 if (fMetadata[n]->GetError()) {
1913 cout << endl;
1914 RESTError << "Class: " << fMetadata[n]->ClassName() << " Name: " << fMetadata[n]->GetName()
1915 << RESTendl;
1916 RESTError << "Number of errors: " << fMetadata[n]->GetNumberOfErrors() << RESTendl;
1917 RESTError << "Message: " << fMetadata[n]->GetErrorMessage() << RESTendl;
1918 }
1919 cout << endl;
1920 } else {
1921 cout << "No errors found!" << endl;
1922 }
1923}
1924
1930 Int_t nWarnings = 0;
1931 for (unsigned int n = 0; n < fMetadata.size(); n++)
1932 if (fMetadata[n]->GetWarning()) nWarnings++;
1933
1934 if (nWarnings) {
1935 cout << endl;
1936 RESTWarning << "Found a total of " << nWarnings << " metadata warnings" << RESTendl;
1937 for (unsigned int n = 0; n < fMetadata.size(); n++)
1938 if (fMetadata[n]->GetWarning()) {
1939 cout << endl;
1940 RESTWarning << "Class: " << fMetadata[n]->ClassName() << " Name: " << fMetadata[n]->GetName()
1941 << RESTendl;
1942 RESTWarning << "Number of warnings: " << fMetadata[n]->GetNumberOfWarnings() << RESTendl;
1943 RESTWarning << "Message: " << fMetadata[n]->GetWarningMessage() << RESTendl;
1944 }
1945 cout << endl;
1946 } else {
1947 cout << "No warnings found!" << endl;
1948 }
1949}
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.
virtual void CloneTo(TRestEvent *target)
Clone the content of this TRestEvent object to another.
virtual void Initialize()=0
A base class for any REST metadata class.
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,...
void AddEventBranch(TRestEvent *event)
Add an event branch in output EventTree.
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.
TFile * FormOutputFile()
Create a new TFile as REST output file. Writing metadata objects into it.
void ResetEntry()
Reset file reading progress.
Definition TRestRun.cxx:781
TString FormFormat(const TString &filenameFormat)
Form output file name according to file info list, proc info list and run data.
Definition TRestRun.cxx:940
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.
std::string ReplaceMetadataMember(const std::string &instr, Int_t precision=0)
It will replace the data member from the corresponding metadata class type or name defined in the inp...
void GetEntry(Long64_t entry)
Calls GetEntry() for both AnalysisTree and EventTree.
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,...
std::string ReplaceMetadataMembers(const std::string &instr, Int_t precision=8)
It will replace the data members contained inside the string given as input. The data members in the ...
void PrintMetadata() override
Prints the basic run information.
TFile * MergeToOutputFile(std::vector< std::string > fileFullNames, std::string outputFileName="")
Form REST output file by merging a list of files together.
Definition TRestRun.cxx:985
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.
Bool_t EvaluateMetadataMember(const std::string &instr)
It will evaluate the expression given including the data member from the corresponding metadata class...
void SetExtProcess(TRestEventProcess *p)
Set external file process.
void PrintStartDate()
Prints the run start date and time in human format.
Double_t fStartTime
Event absolute starting time/date (unix timestamp)
Definition TRestRun.h:36
void WriteWithDataBase()
Write this object into TFile and add a new entry in database.
Int_t Write(const char *name=nullptr, Int_t option=0, Int_t bufsize=0) override
overwriting the write() method with fStore considered
void ReadFileInfo(const std::string &filename)
Extract file info from a file, and save it in the file info list.
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.
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.
static std::string GetPureFileName(const std::string &fullPathFileName)
Removes all directories in the full path filename description given in the argument.
static bool fileExists(const std::string &filename)
Returns true if the file (or directory) with path filename exists.
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....
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.
static bool isAbsolutePath(const std::string &path)
Check if the path is absolute path or not.
static std::string RemoveMultipleSlash(std::string)
Returns the input string but without multiple slashes ("/")
static bool isRootFile(const std::string &filename)
Returns true if the filename has *.root* extension.
TClass * GetClassQuick()
Get the type of a "class" object, returning the wrapped type identifier "TClass".
TRestReflector Assembly(const std::string &typeName)
Assembly an object of type: typeName, returning the allocated memory address and size.
Int_t GetChar(std::string hint="Press a KEY to continue ...")
Helps to pause the program, printing a message before pausing.
std::vector< std::string > Split(std::string in, std::string separator, bool allowBlankString=false, bool removeWhiteSpaces=false, int startPos=-1)
Split the input string according to the given separator. Returning a vector of fragments.
Double_t StringToDouble(std::string in)
Gets a double from a string.
std::string ToUpper(std::string in)
Convert string to its upper case. Alternative of TString::ToUpper.
Int_t StringToInteger(std::string in)
Gets an integer from a string.
Int_t Count(std::string s, std::string sbstring)
Counts the number of occurences of substring inside the input string in.
std::string ParameterNameToDataMemberName(std::string name)
Convert parameter name to datamember name, following REST parameter naming convention.
std::string DataMemberNameToParameterName(std::string name)
Convert data member name to parameter name, following REST parameter naming convention.
Int_t isANumber(std::string in)
Returns 1 only if a valid number is found in the string in. If not it returns 0.
std::string RemoveWhiteSpaces(std::string in)
Returns the input string removing all white spaces.
std::string ToDateTimeString(time_t time)
Format time_t into string.
std::string Replace(std::string in, std::string thisString, std::string byThisString, size_t fromPosition=0, Int_t N=0)
Replace any occurences of thisSring by byThisString inside string in.
std::string ReplaceMathematicalExpressions(std::string buffer, Int_t precision=0, std::string errorMessage="")
Evaluates and replaces valid mathematical expressions found in the input string buffer.