258#include "TRestDataSet.h"
261#include "TRestTools.h"
306 if (
fTree !=
nullptr) {
307 RESTWarning <<
"Tree has already been loaded. Skipping TRestDataSet::GenerateDataSet ... "
316 RESTError <<
"File selection is empty " <<
RESTendl;
322 std::vector<std::string> finalList;
323 finalList.push_back(
"runOrigin");
324 finalList.push_back(
"eventID");
325 finalList.push_back(
"timeStamp");
329 if (std::find(obsNames.begin(), obsNames.end(), obs) != obsNames.end()) {
330 finalList.push_back(obs);
332 RESTWarning <<
" Observable " << obs <<
" not found in observable list, skipping..." <<
RESTendl;
336 for (
const auto& name : obsNames) {
338 if (name.find(pcs) == 0) finalList.push_back(name);
343 std::sort(finalList.begin(), finalList.end());
344 finalList.erase(std::unique(finalList.begin(), finalList.end()), finalList.end());
346 ROOT::EnableImplicitMT();
348 RESTInfo <<
"Initializing dataset" <<
RESTendl;
351 RESTInfo <<
"Making cuts" <<
RESTendl;
356 RESTInfo <<
"Adding column to dataset: " << cName <<
RESTendl;
357 finalList.emplace_back(cName);
361 RESTInfo <<
"Generating snapshot." <<
RESTendl;
362 std::string user = getenv(
"USER");
363 std::string fOutName =
"/tmp/rest_output_" + user +
".root";
364 fDataSet.Snapshot(
"AnalysisTree", fOutName, finalList);
366 RESTInfo <<
"Re-importing analysis tree." <<
RESTendl;
367 fDataSet = ROOT::RDataFrame(
"AnalysisTree", fOutName);
369 TFile* f = TFile::Open(fOutName.c_str());
370 fTree = (TChain*)f->Get(
"AnalysisTree");
372 RESTInfo <<
" - Dataset generated!" <<
RESTendl;
384 if (!time_stamp_end || !time_stamp_start) {
385 RESTError <<
"TRestDataSet::FileSelect. Start or end dates not properly formed. Please, check "
386 "REST_StringHelper::StringToTimeStamp documentation for valid formats"
393 if (!fileNames.empty()) {
394 RESTInfo <<
"TRestDataSet::FileSelection. Starting file selection." <<
RESTendl;
395 RESTInfo <<
"Total files : " << fileNames.size() <<
RESTendl;
396 RESTInfo <<
"This process may take long computation time in case there are many files." <<
RESTendl;
400 std::cout <<
"Total files : " << fileNames.size() << std::endl;
401 std::cout <<
"Processing file selection .";
403 for (
const auto& file : fileNames) {
404 if (cnt % 100 == 0) {
405 std::cout << std::endl;
406 std::cout <<
"Files processed: " << cnt <<
" ." << std::flush;
410 std::cout <<
"." << std::flush;
411 double runStart = run.GetStartTimestamp();
412 double runEnd = run.GetEndTimestamp();
414 if (runStart < time_stamp_start || runEnd > time_stamp_end) {
421 std::string mdValue = run.GetMetadataMember(md);
424 if (mdValue.find(
fFilterContains[n]) == std::string::npos) accept =
false;
439 if (!accept)
continue;
442 for (
auto& [name, properties] :
fQuantity) {
446 if (properties.strategy ==
"accumulate") {
448 properties.value = StringWithPrecision(val, 2);
451 if (properties.strategy ==
"max")
453 properties.value = value;
455 if (properties.strategy ==
"min")
457 properties.value = value;
459 if (properties.strategy ==
"unique") {
460 if (properties.value.empty())
461 properties.value = value;
462 else if (properties.value != value) {
463 RESTWarning <<
"TRestDataSet::FileSelection. Relevant quantity retrieval." <<
RESTendl;
464 RESTWarning <<
"A unique metadata member used for the `" << name
465 <<
"` quantity is not unique!!" <<
RESTendl;
466 RESTWarning <<
"Pre-registered value : " << properties.value <<
" New value : " << value
471 if (properties.strategy ==
"last") properties.value = value;
478 fTotalDuration += run.GetEndTimestamp() - run.GetStartTimestamp();
481 std::cout << std::endl;
495 if (cut ==
nullptr)
return df;
497 auto paramCut = cut->GetParamCut();
498 auto obsList = df.GetColumnNames();
499 for (
const auto& [param, condition] : paramCut) {
500 if (std::find(obsList.begin(), obsList.end(), param) != obsList.end()) {
501 std::string pCut = param + condition;
502 RESTDebug <<
"Applying cut " << pCut <<
RESTendl;
503 df = df.Filter(pCut);
505 RESTWarning <<
" Cut observable " << param <<
" not found in observable list, skipping..."
510 auto cutString = cut->GetCutStrings();
511 for (
const auto& pCut : cutString) {
513 for (
const auto& obs : obsList) {
514 if (pCut.find(obs) != std::string::npos) {
515 RESTDebug <<
"Applying cut " << pCut <<
RESTendl;
516 df = df.Filter(pCut);
523 RESTWarning <<
" Cut string " << pCut <<
" not found in observable list, skipping..." <<
RESTendl;
545 std::string evalFormula = formula;
546 for (
auto const& [name, properties] :
fQuantity)
549 df = df.Define(columnName, evalFormula);
572 RESTMetadata <<
" Single observables added:" <<
RESTendl;
573 RESTMetadata <<
" -------------------------" <<
RESTendl;
580 RESTMetadata <<
" Process observables added: " <<
RESTendl;
581 RESTMetadata <<
" -------------------------- " <<
RESTendl;
588 RESTMetadata <<
" Metadata filters: " <<
RESTendl;
589 RESTMetadata <<
" ----------------- " <<
RESTendl;
594 RESTMetadata <<
" - " << mdFilter <<
".";
609 RESTMetadata <<
" Relevant quantities: " <<
RESTendl;
610 RESTMetadata <<
" -------------------- " <<
RESTendl;
612 for (
auto const& [name, properties] :
fQuantity) {
613 RESTMetadata <<
" - Name : " << name <<
". Value : " << properties.value
614 <<
". Strategy: " << properties.strategy <<
RESTendl;
615 RESTMetadata <<
" - Metadata: " << properties.metadata <<
RESTendl;
616 RESTMetadata <<
" - Description: " << properties.description <<
RESTendl;
622 RESTMetadata <<
" New columns added to generated dataframe: " <<
RESTendl;
623 RESTMetadata <<
" ---------------------------------------- " <<
RESTendl;
625 RESTMetadata <<
" - Name : " << cName <<
" Expression: " << cExpression <<
RESTendl;
630 RESTMetadata <<
"This is a combined dataset." <<
RESTendl;
631 RESTMetadata <<
" -------------------- " <<
RESTendl;
632 RESTMetadata <<
" - Relevant quantities have been removed!" <<
RESTendl;
633 RESTMetadata <<
" - Dataset metadata properties correspond to the first file in the list."
636 RESTMetadata <<
"List of imported files: " <<
RESTendl;
637 RESTMetadata <<
" -------------------- " <<
RESTendl;
651 TiXmlElement* filterDefinition =
GetElement(
"filter");
652 while (filterDefinition !=
nullptr) {
653 std::string metadata =
GetFieldValue(
"metadata", filterDefinition);
654 if (metadata.empty() || metadata ==
"Not defined") {
655 RESTError <<
"Filter key defined without metadata member!" <<
RESTendl;
661 std::string contains =
GetFieldValue(
"contains", filterDefinition);
662 if (contains ==
"Not defined") contains =
"";
676 TiXmlElement* observablesDefinition =
GetElement(
"observables");
677 while (observablesDefinition !=
nullptr) {
678 std::string observables =
GetFieldValue(
"list", observablesDefinition);
679 if (observables.empty() || observables ==
"Not defined") {
680 RESTError <<
"<observables key does not contain a list!" <<
RESTendl;
692 TiXmlElement* obsProcessDefinition =
GetElement(
"processObservables");
693 while (obsProcessDefinition !=
nullptr) {
694 std::string observables =
GetFieldValue(
"list", obsProcessDefinition);
695 if (observables.empty() || observables ==
"Not defined") {
696 RESTError <<
"<processObservables key does not contain a list!" <<
RESTendl;
708 TiXmlElement* quantityDefinition =
GetElement(
"quantity");
709 while (quantityDefinition !=
nullptr) {
710 std::string name =
GetFieldValue(
"name", quantityDefinition);
711 if (name.empty() || name ==
"Not defined") {
712 RESTError <<
"<quantity key does not contain a name!" <<
RESTendl;
716 std::string metadata =
GetFieldValue(
"metadata", quantityDefinition);
717 if (metadata.empty() || metadata ==
"Not defined") {
718 RESTError <<
"<quantity key does not contain a metadata value!" <<
RESTendl;
722 std::string strategy =
GetFieldValue(
"strategy", quantityDefinition);
723 if (strategy.empty() || strategy ==
"Not defined") {
727 std::string description =
GetFieldValue(
"description", quantityDefinition);
741 TiXmlElement* columnDefinition =
GetElement(
"addColumn");
742 while (columnDefinition !=
nullptr) {
744 if (name.empty() || name ==
"Not defined") {
745 RESTError <<
"<define key does not contain a name name!" <<
RESTendl;
749 std::string expression =
GetFieldValue(
"expression", columnDefinition);
750 if (expression.empty() || expression ==
"Not defined") {
751 RESTError <<
"<addColumn key does not contain a expression value!" <<
RESTendl;
777 RESTInfo <<
"Exporting dataset" <<
RESTendl;
780 std::vector<std::string> dataTypes;
781 for (
int n = 0; n <
fTree->GetListOfBranches()->GetEntries(); n++) {
782 std::string bName =
fTree->GetListOfBranches()->At(n)->GetName();
783 std::string type =
fTree->GetLeaf((TString)bName)->GetTypeName();
784 dataTypes.push_back(type);
785 if (type !=
"Double_t" && type !=
"Int_t") {
786 RESTError <<
"Branch name : " << bName <<
" is type : " << type <<
RESTendl;
787 RESTError <<
"Only Int_t and Double_t types are allowed for "
788 "exporting to ASCII table"
790 RESTError <<
"File will not be generated" <<
RESTendl;
795 FILE* f = fopen(filename.c_str(),
"wt");
797 fprintf(f,
"### TRestDataSet generated file\n");
798 fprintf(f,
"### \n");
802 fprintf(f,
"### Accumulated run time (seconds) : %lf\n",
fTotalDuration);
803 fprintf(f,
"### Accumulated run time (hours) : %lf\n",
fTotalDuration / 3600.);
804 fprintf(f,
"### Accumulated run time (days) : %lf\n",
fTotalDuration / 3600. / 24.);
810 fprintf(f,
"### Metadata filters : \n");
813 fprintf(f,
"### - %s.", md.c_str());
823 fprintf(f,
"### Relevant quantities: \n");
824 for (
auto& [name, properties] :
fQuantity) {
825 fprintf(f,
"### - %s : %s - %s\n", name.c_str(), properties.value.c_str(),
826 properties.description.c_str());
829 fprintf(f,
"### Observables list: ");
830 for (
int n = 0; n <
fTree->GetListOfBranches()->GetEntries(); n++) {
831 std::string bName =
fTree->GetListOfBranches()->At(n)->GetName();
832 fprintf(f,
" %s", bName.c_str());
836 fprintf(f,
"### Data starts here\n");
838 auto obsNames =
fDataSet.GetColumnNames();
839 std::string obsListStr =
"";
840 for (
const auto& l : obsNames) {
841 if (!obsListStr.empty()) obsListStr +=
":";
846 fTree->Draw((TString)obsListStr,
"",
"goff");
848 for (
unsigned int n = 0; n <
fTree->GetEntries(); n++) {
850 std::string bName =
fTree->GetListOfBranches()->At(m)->GetName();
851 if (m > 0) fprintf(f,
"\t");
852 if (dataTypes[m] ==
"Double_t")
853 if (bName ==
"timeStamp")
854 fprintf(f,
"%010.0lf",
fTree->GetVal(m)[n]);
856 fprintf(f,
"%05.3e",
fTree->GetVal(m)[n]);
858 fprintf(f,
"%06d", (Int_t)
fTree->GetVal(m)[n]);
866 fDataSet.Snapshot(
"AnalysisTree", filename);
868 TFile* f = TFile::Open(filename.c_str(),
"UPDATE");
881 SetName(dS.GetName());
910 RESTError <<
"Datasets can only be imported from root files" <<
RESTendl;
915 TFile* file = TFile::Open(fileName.c_str(),
"READ");
916 if (file !=
nullptr) {
917 TIter nextkey(file->GetListOfKeys());
919 while ((key = (TKey*)nextkey())) {
920 std::string kName = key->GetClassName();
932 RESTError << fileName <<
" is not a valid dataSet" <<
RESTendl;
936 ROOT::EnableImplicitMT();
938 fDataSet = ROOT::RDataFrame(
"AnalysisTree", fileName);
940 fTree = (TChain*)file->Get(
"AnalysisTree");
953 for (
const auto& fN : fileNames)
955 RESTError <<
"Datasets can only be imported from root files" <<
RESTendl;
959 if (fileNames.size() == 0)
return;
961 TFile* file = TFile::Open(fileNames[0].c_str(),
"READ");
962 if (file !=
nullptr) {
963 TIter nextkey(file->GetListOfKeys());
965 while ((key = (TKey*)nextkey())) {
966 std::string kName = key->GetClassName();
976 RESTError <<
"Cannot open " << fileNames[0] <<
RESTendl;
980 RESTInfo <<
"Opening list of files. First file: " << fileNames[0] <<
RESTendl;
981 fDataSet = ROOT::RDataFrame(
"AnalysisTree", fileNames);
983 if (
fTree !=
nullptr) {
987 fTree =
new TChain(
"AnalysisTree");
989 for (
const auto& fN : fileNames)
fTree->Add((TString)fN);
std::vector< std::string > GetObservableNames()
It returns a vector with strings containing all the observables that exist in the analysis tree.
A class to help on cuts definitions. To be used with TRestAnalysisTree.
It allows to group a number of runs that satisfy given metadata conditions.
std::vector< std::string > fFilterContains
If not empty it will check if the metadata member contains the string.
virtual std::vector< std::string > FileSelection()
Function to determine the filenames that satisfy the dataset conditions.
std::vector< Double_t > fFilterLowerThan
If the corresponding element is not empty it will check if the metadata member is lower.
void PrintMetadata() override
Prints on screen the information about the metadata members of TRestDataSet.
TChain * fTree
A pointer to the generated tree.
std::vector< std::string > fProcessObservablesList
It contains a list of the process where all observables should be added.
void Import(const std::string &fileName)
This function imports metadata from a root file it import metadata info from the previous dataSet whi...
std::map< std::string, RelevantQuantity > fQuantity
The properties of a relevant quantity that we want to store together with the dataset.
ROOT::RDF::RNode fDataSet
The resulting RDF::RNode object after initialization.
std::vector< std::pair< std::string, std::string > > fColumnNameExpressions
A list of new columns together with its corresponding expressions added to the dataset.
ROOT::RDF::RNode DefineColumn(const std::string &columnName, const std::string &formula)
This function will add a new column to the RDataFrame using the same scheme as the usual RDF::Define ...
Double_t fEndTime
TimeStamp for the end time of the last file.
size_t GetNumberOfBranches()
Number of variables (or observables)
TRestDataSet()
Default constructor.
Double_t GetTotalTimeInSeconds() const
It returns the accumulated run time in seconds.
ROOT::RDF::RNode MakeCut(const TRestCut *cut)
This function apply a TRestCut to the dataframe and returns a dataframe with the applied cuts....
void GenerateDataSet()
This function generates the data frame with the filelist and column names (or observables) that have ...
TRestCut * fCut
Parameter cuts over the selected dataset.
std::string fFilterStartTime
All the selected runs will have a starting date after fStartTime.
std::vector< std::string > fFilterMetadata
A list of metadata members where filters will be applied.
std::vector< std::string > fFileSelection
A list populated by the FileSelection method using the conditions of the dataset.
std::vector< std::string > GetFileSelection()
It returns a list of the files that have been finally selected.
std::string fFilterEndTime
All the selected runs will have an ending date before fEndTime.
Double_t fStartTime
TimeStamp for the start time of the first file.
std::vector< std::string > fObservablesList
It contains a list of the observables that will be added to the final tree or exported file.
Bool_t fMergedDataset
It keeps track if the generated dataset is a pure dataset or a merged one.
void Initialize() override
This function initialize different parameters from the TRestDataSet.
std::vector< std::string > fImportedFiles
The list of dataset files imported.
Double_t fTotalDuration
The total integrated run time of selected files.
std::string fFilePattern
A glob file pattern that must be satisfied by all files.
std::vector< Double_t > fFilterGreaterThan
If the corresponding element is not empty it will check if the metadata member is greater.
std::vector< Double_t > fFilterEqualsTo
If the corresponding element is not empty it will check if the metadata member is equal.
void InitFromConfigFile() override
Initialization of specific TRestDataSet members through an RML file.
void Export(const std::string &filename)
It will generate an output file with the dataset compilation. Only the selected branches and the file...
TRestDataSet & operator=(TRestDataSet &dS)
Operator to copy TRestDataSet metadata.
~TRestDataSet()
Default destructor.
Data provider and manager in REST.
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 ...
@ REST_Info
+show most of the information for each steps
TClass * GetClassQuick(std::string type)
time_t StringToTimeStamp(std::string time)
A method to convert a date/time formatted string to a timestamp.
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 ToDateTimeString(time_t time)
Format time_t into string.
std::string Replace(std::string in, std::string thisString, std::string byThisString, size_t fromPosition=0, Int_t N=0)
Replace every occurences of thisSring by byThisString inside string in.
std::string metadata
The associated metadata member used to register the relevant quantity.
std::string description
A user given description that can be used to define the relevant quantity.
std::string strategy
It determines how to produce the relevant quantity (accumulate/unique/last/max/min)
std::string value
The quantity value.