261#include "TRestDataSetPlot.h"
264#include "TDirectory.h"
317 TiXmlElement* cutele =
GetElement(
"addCut", ele);
318 while (cutele !=
nullptr) {
320 if (!cutName.empty()) {
321 if (cut ==
nullptr) {
339 RESTWarning <<
"Plot metadata already initialized" <<
RESTendl;
343 while (panelele !=
nullptr) {
344 std::string active =
GetParameter(
"value", panelele,
"ON");
345 if (
ToUpper(active) !=
"ON")
continue;
351 panel.panelCut =
ReadCut(panel.panelCut, panelele);
353 TiXmlElement* labelele =
GetElement(
"variable", panelele);
354 while (labelele !=
nullptr) {
355 std::array<std::string, 3> label;
362 panel.variablePos.push_back(std::make_pair(label, TVector2(posX, posY)));
366 TiXmlElement* metadata =
GetElement(
"metadata", panelele);
367 while (metadata !=
nullptr) {
368 std::array<std::string, 3> label;
375 panel.metadataPos.push_back(std::make_pair(label, TVector2(posX, posY)));
379 TiXmlElement* observable =
GetElement(
"observable", panelele);
380 while (observable !=
nullptr) {
381 std::array<std::string, 3> label;
388 panel.obsPos.push_back(std::make_pair(label, TVector2(posX, posY)));
404 RESTWarning <<
"Plot metadata already initialized" <<
RESTendl;
409 while (plotele !=
nullptr) {
410 std::string active =
GetParameter(
"value", plotele,
"ON");
411 if (
ToUpper(active) !=
"ON")
continue;
416 plot.logX = StringToBool(
GetParameter(
"logX", plotele,
"false"));
417 plot.logY = StringToBool(
GetParameter(
"logY", plotele,
"false"));
418 plot.logZ = StringToBool(
GetParameter(
"logZ", plotele,
"false"));
419 plot.gridY = StringToBool(
GetParameter(
"gridY", plotele,
"false"));
420 plot.gridX = StringToBool(
GetParameter(
"gridX", plotele,
"false"));
429 plot.legendOn = StringToBool(
GetParameter(
"legend", plotele,
"OFF"));
430 plot.stackDrawOption =
GetParameter(
"stackOption", plotele,
"nostack");
434 plot.timeDisplay = StringToBool(
GetParameter(
"timeDisplay", plotele,
"OFF"));
437 TiXmlElement* histele =
GetElement(
"histo", plotele);
438 if (histele ==
nullptr) {
441 while (histele !=
nullptr) {
444 hist.drawOption =
GetParameter(
"option", histele,
"colz");
445 TiXmlElement* varele =
GetElement(
"variable", histele);
446 while (varele !=
nullptr) {
459 hist.statistics = StringToBool(
GetParameter(
"stats", histele,
"OFF"));
461 hist.histoCut =
ReadCut(hist.histoCut, histele);
462 plot.histos.push_back(hist);
464 if (histele == plotele) {
481 std::vector<std::string> obsList;
484 if (
fCut !=
nullptr) {
485 const auto paramCut =
fCut->GetParamCut();
486 for (
const auto& [param, condition] : paramCut) {
487 obsList.push_back(param);
492 for (
const auto& plots :
fPlots) {
493 for (
const auto& hist : plots.histos) {
494 for (
const auto& var : hist.variable) {
495 obsList.push_back(var);
497 if (hist.histoCut ==
nullptr)
continue;
498 const auto paramCut = hist.histoCut->GetParamCut();
499 for (
const auto& [param, condition] : paramCut) {
500 obsList.push_back(param);
505 std::map<std::string, TRestDataSet::RelevantQuantity> quantity;
509 for (
auto& [key, posLabel] : panel.obsPos) {
510 auto&& [obs, label,
units] = key;
511 obsList.push_back(obs);
514 for (
auto& [key, posLabel] : panel.metadataPos) {
515 auto&& [metadata, label,
units] = key;
519 quantity[label] = quant;
524 std::sort(obsList.begin(), obsList.end());
525 obsList.erase(std::unique(obsList.begin(), obsList.end()), obsList.end());
527 dataSet.SetObservablesList(obsList);
528 dataSet.SetQuantity(quantity);
543 if (dataSet.
GetTree() ==
nullptr) {
544 RESTWarning <<
"Cannot import dataSet, trying to generate it with pattern " <<
fDataSetName
546 RESTWarning <<
"Note that the generation of a dataSet inside TRestDataSetPlot is deplecated. Check "
547 "TRestDataSet documentation to generate a dataSet"
550 if (dataSet.
GetTree() ==
nullptr) {
551 RESTError <<
"Cannot generate dataSet " <<
RESTendl;
560 combinedCanvas.Divide((Int_t)fCanvasDivisions.X(), (Int_t)fCanvasDivisions.Y(),
561 fCanvasDivisionMargins.X(), fCanvasDivisionMargins.Y());
566 const double startTime = dataSet.GetStartTime();
567 const double endTime = dataSet.GetEndTime();
570 std::map<std::string, std::string> paramMap;
575 const auto quantity = dataSet.GetQuantity();
580 combinedCanvas.cd(canvasIndex);
582 auto dataFrame = dataSet.
MakeCut(panel.panelCut);
583 const int entries = *dataFrame.Count();
584 const double meanRate = entries / duration;
585 const double runLength = duration / 3600.;
586 paramMap[
"[[runLength]]"] = StringWithPrecision(runLength, panel.precision);
587 paramMap[
"[[entries]]"] = StringWithPrecision(entries, panel.precision);
588 paramMap[
"[[meanRate]]"] = StringWithPrecision(meanRate, panel.precision);
590 for (
const auto& [key, posLabel] : panel.variablePos) {
591 auto&& [variable, label,
units] = key;
593 std::string var = variable;
595 for (
const auto& [param, val] : paramMap) {
598 var =
Replace(var, param, val, pos);
603 if (!found) RESTWarning <<
"Variable " << variable <<
" not found" <<
RESTendl;
605 std::string lab = label +
": " + StringWithPrecision(var, panel.precision) +
" " +
units;
606 panel.text.emplace_back(
new TLatex(posLabel.X(), posLabel.Y(), lab.c_str()));
610 for (
const auto& [key, posLabel] : panel.metadataPos) {
611 auto&& [metadata, label,
units] = key;
612 std::string value =
"";
614 for (
const auto& [name, quant] : quantity) {
615 if (quant.metadata == metadata) value = quant.value;
619 RESTWarning <<
"Metadata quantity " << metadata <<
" not found in dataSet" <<
RESTendl;
623 std::string lab = label +
": " + StringWithPrecision(value, panel.precision) +
" " +
units;
624 panel.text.emplace_back(
new TLatex(posLabel.X(), posLabel.Y(), lab.c_str()));
628 for (
const auto& [key, posLabel] : panel.obsPos) {
629 auto&& [obs, label,
units] = key;
630 auto value = *dataFrame.Mean(obs);
632 std::string lab = label +
": " + StringWithPrecision(value, panel.precision) +
" " +
units;
633 panel.text.emplace_back(
new TLatex(posLabel.X(), posLabel.Y(), lab.c_str()));
637 for (
const auto& text : panel.text) {
638 text->SetTextColor(1);
639 text->SetTextSize(panel.font_size);
645 for (
auto& plots :
fPlots) {
647 combinedCanvas.cd(canvasIndex);
648 plots.hs =
new THStack(plots.name.c_str(), plots.title.c_str());
649 if (plots.legendOn) plots.legend =
new TLegend(
fLegendX1, fLegendY1, fLegendX2, fLegendY2);
651 for (
auto& hist : plots.histos) {
652 auto dataFrame = dataSet.
MakeCut(hist.histoCut);
653 if (hist.variable.front() ==
"timeStamp") {
654 hist.range.front().SetX(startTime);
655 hist.range.front().SetY(endTime);
658 if (hist.variable.size() == 1) {
659 auto histo = dataFrame.Histo1D({hist.name.c_str(), hist.name.c_str(), hist.nBins.front(),
660 hist.range.front().X(), hist.range.front().Y()},
661 hist.variable.front());
662 hist.histo =
static_cast<TH1*
>(histo->DrawClone());
664 }
else if (hist.variable.size() == 2) {
665 auto histo = dataFrame.Histo2D(
666 {hist.name.c_str(), hist.name.c_str(), hist.nBins.front(), hist.range.front().X(),
667 hist.range.front().Y(), hist.nBins.back(), hist.range.back().X(), hist.range.back().Y()},
668 hist.variable.front(), hist.variable.back());
669 hist.histo =
static_cast<TH1*
>(histo->DrawClone());
671 RESTError <<
"Only 1D or 2D histograms are supported " <<
RESTendl;
674 hist.histo->SetLineColor(hist.lineColor);
675 hist.histo->SetLineWidth(hist.lineWidth);
676 hist.histo->SetLineStyle(hist.lineStyle);
677 hist.histo->SetFillColor(hist.fillColor);
678 hist.histo->SetFillStyle(hist.fillStyle);
680 if (hist.statistics) {
681 hist.histo->SetStats(
true);
683 combinedCanvas.Update();
685 hist.histo->SetStats(
false);
688 if (plots.normalize > 0) {
689 const double integral = hist.histo->Integral();
690 if (integral > 0) hist.histo->Scale(plots.normalize / integral);
693 if (plots.scale !=
"") {
695 if (plots.scale ==
"binSize") {
696 scale = 1. / hist.histo->GetXaxis()->GetBinWidth(1);
700 hist.histo->Scale(scale);
704 plots.hs->Add(hist.histo, hist.drawOption.c_str());
706 if (plots.legend !=
nullptr) plots.legend->AddEntry(hist.histo, hist.histo->GetName(),
"lf");
711 for (
auto& plots :
fPlots) {
712 if (plots.hs ==
nullptr)
continue;
714 TPad* targetPad = (TPad*)combinedCanvas.cd(canvasIndex);
715 targetPad->SetLogx(plots.logX);
716 targetPad->SetLogy(plots.logY);
717 targetPad->SetLogz(plots.logZ);
718 targetPad->SetGridx(plots.gridX);
719 targetPad->SetGridy(plots.gridY);
720 targetPad->SetLeftMargin(plots.marginLeft);
721 targetPad->SetRightMargin(plots.marginRight);
722 targetPad->SetBottomMargin(plots.marginBottom);
723 targetPad->SetTopMargin(plots.marginTop);
726 plots.hs->Draw(plots.stackDrawOption.c_str());
727 plots.hs->GetXaxis()->SetTitle(plots.labelX.c_str());
728 plots.hs->GetYaxis()->SetTitle(plots.labelY.c_str());
729 plots.hs->GetXaxis()->SetLabelSize(1.1 * plots.hs->GetXaxis()->GetLabelSize());
730 plots.hs->GetYaxis()->SetLabelSize(1.1 * plots.hs->GetYaxis()->GetLabelSize());
731 plots.hs->GetXaxis()->SetTitleSize(1.1 * plots.hs->GetXaxis()->GetTitleSize());
732 plots.hs->GetYaxis()->SetTitleSize(1.1 * plots.hs->GetYaxis()->GetTitleSize());
734 if (plots.timeDisplay) plots.hs->GetXaxis()->SetTimeDisplay(1);
735 if (plots.legend !=
nullptr) plots.legend->Draw();
738 combinedCanvas.Update();
744 combinedCanvas.Resize();
749 for (
auto& plots :
fPlots) {
750 if (plots.save.empty())
continue;
751 std::unique_ptr<TCanvas> canvas(
new TCanvas());
752 canvas->SetLogx(plots.logX);
753 canvas->SetLogy(plots.logY);
754 canvas->SetLogz(plots.logZ);
755 canvas->SetGridx(plots.gridX);
756 canvas->SetGridy(plots.gridY);
757 canvas->SetLeftMargin(plots.marginLeft);
758 canvas->SetRightMargin(plots.marginRight);
759 canvas->SetBottomMargin(plots.marginBottom);
760 canvas->SetTopMargin(plots.marginTop);
761 plots.hs->Draw(plots.stackDrawOption.c_str());
762 canvas->Print(plots.save.c_str());
767 for (
const auto& [name, quant] : quantity) {
774 std::unique_ptr<TFile> f(TFile::Open(
fOutputFileName.c_str(),
"UPDATE"));
775 for (
auto& plots :
fPlots) {
776 for (
auto& hist : plots.histos) {
792 for (
auto& plots :
fPlots) {
793 for (
auto& hist : plots.histos) {
801 for (
auto& text : panel.text) {
814 if (in.find_first_not_of(
"0123456789") == std::string::npos) {
817 auto it = mapStr.find(in);
818 if (it != mapStr.end()) {
821 RESTWarning <<
"cannot find ID with name \"" << in <<
"\"" <<
RESTendl;
836 RESTMetadata <<
"Canvas divisions: (" << fCanvasDivisions.X() <<
" ," << fCanvasDivisions.Y() <<
")"
838 RESTMetadata <<
"-------------------" <<
RESTendl;
839 for (
const auto& plot :
fPlots) {
840 RESTMetadata <<
"-------------------" <<
RESTendl;
841 RESTMetadata <<
"Plot name/title: " << plot.name <<
" " << plot.title <<
RESTendl;
842 RESTMetadata <<
"Save string: " << plot.save <<
RESTendl;
843 RESTMetadata <<
"Set log X,Y,Z: " << plot.logX <<
", " << plot.logY <<
", " << plot.logZ <<
RESTendl;
844 RESTMetadata <<
"Stack draw Option: " << plot.stackDrawOption <<
RESTendl;
845 if (plot.legend) RESTMetadata <<
"Legend is ON" <<
RESTendl;
846 if (plot.timeDisplay) RESTMetadata <<
"Time display is ON" <<
RESTendl;
847 RESTMetadata <<
"Labels X,Y: " << plot.labelX <<
", " << plot.labelY <<
RESTendl;
848 for (
const auto& hist : plot.histos) {
849 RESTMetadata <<
"****************" <<
RESTendl;
850 RESTMetadata <<
"Histo name: " << hist.name <<
RESTendl;
851 RESTMetadata <<
"Draw Option: " << hist.drawOption <<
RESTendl;
852 RESTMetadata <<
"Histogram size: " << hist.variable.size() <<
" with parameters:" <<
RESTendl;
853 for (
size_t i = 0; i < hist.variable.size(); i++) {
854 RESTMetadata <<
"\t" << i <<
" " << hist.variable[i] <<
", " << hist.nBins[i] <<
", "
855 << hist.range[i].X() <<
", " << hist.range[i].Y() <<
RESTendl;
857 RESTMetadata <<
"****************" <<
RESTendl;
860 RESTMetadata <<
"-------------------" <<
RESTendl;
862 RESTMetadata <<
"-------------------" <<
RESTendl;
863 RESTMetadata <<
"Panel font size/precision " << panel.font_size <<
", " << panel.precision
865 RESTMetadata <<
"****************" <<
RESTendl;
866 for (
auto& [key, posLabel] : panel.variablePos) {
867 auto&& [obs, label,
units] = key;
868 RESTMetadata <<
"Label variable " << obs <<
", label " << label <<
", units " <<
units <<
" Pos ("
869 << posLabel.X() <<
", " << posLabel.Y() <<
")" <<
RESTendl;
871 RESTMetadata <<
"****************" <<
RESTendl;
872 for (
auto& [key, posLabel] : panel.metadataPos) {
873 auto&& [obs, label,
units] = key;
874 RESTMetadata <<
"Label metadata " << obs <<
", label " << label <<
", units " <<
units <<
" Pos ("
875 << posLabel.X() <<
", " << posLabel.Y() <<
")" <<
RESTendl;
877 RESTMetadata <<
"****************" <<
RESTendl;
878 for (
auto& [key, posLabel] : panel.obsPos) {
879 auto&& [obs, label,
units] = key;
880 RESTMetadata <<
"Label Observable " << obs <<
", label " << label <<
", units " <<
units
881 <<
" Pos (" << posLabel.X() <<
", " << posLabel.Y() <<
")" <<
RESTendl;
883 RESTMetadata <<
"****************" <<
RESTendl;
885 RESTMetadata <<
"-------------------" <<
RESTendl;
A class to help on cuts definitions. To be used with TRestAnalysisTree.
Perform the plot over datasets.
Int_t GetIDFromMapString(const std::map< std::string, int > &mapStr, const std::string &in)
This functions gets the ID from a map string that is passed by reference. It is used to translate col...
std::vector< PanelInfo > fPanels
Vector with panels/label options.
TRestCut * ReadCut(TRestCut *cut, TiXmlElement *ele=nullptr)
this function is used to add the different cuts provided in different metadata sections,...
void Initialize() override
Function to initialize input/output event members and define the section name.
void PlotCombinedCanvas()
This functions performs the plot of the combined canvas with the different panels and plots.
const std::map< std::string, int > LineStyleMap
LineStyleMap as enum "ELineStyle" defined in TAttLine.h.
std::string fDataSetName
Name of the dataset to be imported.
void ReadPlotInfo()
This function reads the config file plot info and stores it in a vector of PlotInfo.
void ReadPanelInfo()
This function reads the config file panel info and stores it in a vector of PanelInfo.
void GenerateDataSetFromFilePattern(TRestDataSet &dataSet)
This functions generates a dataSet based on the information of the rml file. A TRestDataSet is pased ...
Int_t fPaletteStyle
Palette style.
const std::map< std::string, int > FillStyleMap
FillStyleMap as enum "EFillStyle" defined in TAttFill.h.
TRestDataSetPlot()
Default constructor.
TRestCut * fCut
Global cut for the entire dataSet.
Bool_t fPreviewPlot
Preview plot.
const std::map< std::string, int > ColorIdMap
Maps for internal use only.
void PrintMetadata() override
Prints on screen the information about the metadata members of TRestDataSetPlot.
TVector2 fCanvasSize
Canvas options, size, divisions and margins.
std::string fOutputFileName
OutputFileName.
~TRestDataSetPlot()
Default destructor.
Double_t fLegendX1
Legend position and size.
std::vector< PlotInfo > fPlots
Vector with plots/pads options.
void InitFromConfigFile() override
Initialization of specific TRestDataSetPlot members through an RML file.
void CleanUp()
Clean up histos and text but note that the metadata is unchanged.
It allows to group a number of runs that satisfy given metadata conditions.
void Import(const std::string &fileName)
This function imports metadata from a root file it import metadata info from the previous dataSet whi...
Double_t GetTotalTimeInSeconds() const
It returns the accumulated run time in seconds.
ROOT::RDF::RNode MakeCut(const TRestCut *cut)
This function applies 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 ...
TTree * GetTree() const
Gives access to the tree.
@ REST_Info
+show most of the information for each steps
Int_t GetChar(std::string hint="Press a KEY to continue ...")
Helps to pause the program, printing a message before pausing.
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.
TVector2 StringTo2DVector(std::string in)
Gets a 2D-vector from a string.
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.
Nested classes for internal use only.
Auxiliary class for panels/labels.
Auxiliary struct for plots/pads.
std::string metadata
The associated metadata member used to register the relevant quantity.
std::string strategy
It determines how to produce the relevant quantity (accumulate/unique/last/max/min)