R3BROOT
R3B analysis software
Loading...
Searching...
No Matches
R3BDataMonitor.h
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) 2019 GSI Helmholtzzentrum für Schwerionenforschung GmbH *
3 * Copyright (C) 2019-2023 Members of R3B Collaboration *
4 * *
5 * This software is distributed under the terms of the *
6 * GNU General Public Licence (GPL) version 3, *
7 * copied verbatim in the file "LICENSE". *
8 * *
9 * In applying this license GSI does not waive the privileges and immunities *
10 * granted to it by virtue of its status as an Intergovernmental Organization *
11 * or submit itself to any jurisdiction. *
12 ******************************************************************************/
13
14#pragma once
15
17#include "R3BShared.h"
18#include <FairRun.h>
19#include <R3BException.h>
20#include <TCanvas.h>
21#include <TDirectory.h>
22#include <TGraph.h>
23#include <TH2.h>
24#include <fmt/core.h>
25#include <map>
26#include <memory>
27#include <string>
28#include <string_view>
29#include <utility>
30#include <vector>
31
32class FairRun;
33
34namespace R3B
35{
36 constexpr auto DEFAULT_HIST_MONITOR_DIR = "DataMonitor";
38 {
39 public:
40 DataMonitor() = default;
41
42 template <typename... Args>
43 auto create_canvas(std::string_view canvas_name, std::string_view canvas_title, Args&&... args)
45
46 // Use R3B::make_hist to create unique_ptr<TH1>
47 auto add_hist(std::unique_ptr<TH1> hist) -> TH1* { return add_to_map(std::move(hist), histograms_); }
48
49 template <typename Hist, typename... Args>
50 auto add_hist(std::string_view histName, std::string_view histTitle, Args&&... args) -> Hist*;
51
52 template <typename GraphType>
53 auto add_graph(std::string_view graph_name, std::unique_ptr<GraphType> graph) -> GraphType*
54 {
55 graph->SetName(graph_name.data());
56 return add_to_map(std::move(graph), graphs_);
57 }
58
59 template <typename... Args>
60 auto add_graph(std::string_view graph_name, Args&&... args) -> TGraph*
61 {
62 return add_graph(graph_name, std::make_unique<TGraph>(std::forward<Args>(args)...));
63 }
64
65 auto get(const std::string& histName) -> TH1*;
66
67 auto get_canvas(const std::string& histName) -> DataMonitorCanvas&;
68
69 // Save plots to FairSink
70 void save_to_sink(std::string_view folderName = "", FairSink* sinkFile = FairRun::Instance()->GetSink());
71 // Save plots to any root file
72 void save_to_file(std::string_view filename = "");
73
74 // Used for online monitoring
75 void draw_canvases();
76 void register_canvases(FairRun* run);
77 void reset_all_hists();
78
79 private:
80 std::string save_filename_{ "histograms_save" };
81 std::map<std::string, std::unique_ptr<TH1>> histograms_;
82 std::map<std::string, std::unique_ptr<TGraph>> graphs_;
83 std::map<std::string, DataMonitorCanvas> canvases_;
84 static auto get_hist_dir(FairSink* sinkFile) -> TDirectory*;
85 void write_all(TDirectory* dir);
86
87 template <typename ElementType, typename ContainerType>
88 static auto add_to_map(std::unique_ptr<ElementType> element, ContainerType& container) -> ElementType*;
89 template <typename ElementType, typename ContainerType>
90 static auto add_to_vector(std::unique_ptr<ElementType> element, ContainerType& container) -> ElementType*
91 {
92 auto* ptr = element.get();
93 container.emplace_back(std::move(element));
94 return ptr;
95 }
96 };
97
98 template <typename ElementType, typename ContainerType>
99 auto DataMonitor::add_to_map(std::unique_ptr<ElementType> element, ContainerType& container) -> ElementType*
100 {
101 const auto* element_name = element->GetName();
102 auto* element_ptr = element.get();
103 const auto [it, is_success] = container.emplace(std::string{ element_name }, std::move(element));
104 if (not is_success)
105 {
106 throw R3B::logic_error(fmt::format(
107 "Element with the name {} has been already added. Please use a different name!", element_name));
108 }
109 return element_ptr;
110 }
111
112 template <typename Hist, typename... Args>
113 auto DataMonitor::add_hist(std::string_view histName, std::string_view histTitle, Args&&... args) -> Hist*
114 {
115 auto hist = R3B::make_hist<Hist>(histName.data(), histTitle.data(), std::forward<Args>(args)...);
116 return static_cast<Hist*>(add_hist(std::move(hist)));
117 }
118
119 template <typename... Args>
120 auto DataMonitor::create_canvas(std::string_view canvas_name, std::string_view canvas_title, Args&&... args)
122 {
123 if (canvases_.find(std::string{ canvas_name }) != canvases_.end())
124 {
125 throw R3B::logic_error(fmt::format(
126 "A canvas with the name {} has been already added. Please use different name!", canvas_name));
127 }
128 const auto [it, is_success] = canvases_.insert(
129 { std::string{ canvas_name },
130 DataMonitorCanvas(this, canvas_name.data(), canvas_title.data(), std::forward<Args>(args)...) });
131 return it->second;
132 }
133
134 template <typename... Args>
136 : monitor_{ monitor }
137 , canvas_(std::make_unique<TCanvas>(std::forward<Args>(args)...))
138 {
139 }
140
141 template <int div_num, typename ElementType, typename... Args>
142 constexpr auto DataMonitorCanvas::add(Args&&... args) -> CanvasElement<ElementType>
143 {
144 static_assert(div_num > 0, "Division number of the histogram must be larger than 0!");
145 return add<ElementType>(div_num, std::forward<Args>(args)...);
146 }
147
148 template <typename ElementType, typename... Args>
149 constexpr auto DataMonitorCanvas::add(int div_num, Args&&... args) -> CanvasElement<ElementType>
150 {
151 ElementType* figure = nullptr;
152 if constexpr (std::is_same_v<TGraph, ElementType>)
153 {
154 figure = monitor_->add_graph<ElementType>(std::forward<Args>(args)...);
155 }
156 else
157 {
158 figure = monitor_->add_hist<ElementType>(std::forward<Args>(args)...);
159 }
160
161 if (figures_.find(div_num) != figures_.end())
162 {
163 figures_[div_num].emplace_back(figure);
164 }
165 else
166 {
167 figures_.emplace(div_num, std::vector<DrawableElementPtr>{ figure });
168 }
169 if constexpr (std::is_base_of_v<TH2, ElementType>)
170 {
171 const auto* option = figure->GetOption();
172 figure->SetOption(fmt::format("{} COLZ", option).c_str());
173 }
174 auto* pad = canvas_->GetPad(div_num);
175 return CanvasElement{ figure, pad };
176 }
177
178} // namespace R3B
DataMonitorCanvas(DataMonitor *monitor)
constexpr auto add(Args &&... args) -> CanvasElement< ElementType >
std::map< int, std::vector< DrawableElementPtr > > figures_
std::unique_ptr< TCanvas > canvas_
void write_all(TDirectory *dir)
std::map< std::string, std::unique_ptr< TH1 > > histograms_
std::string save_filename_
auto add_hist(std::unique_ptr< TH1 > hist) -> TH1 *
void save_to_sink(std::string_view folderName="", FairSink *sinkFile=FairRun::Instance() ->GetSink())
void register_canvases(FairRun *run)
static auto add_to_vector(std::unique_ptr< ElementType > element, ContainerType &container) -> ElementType *
auto add_graph(std::string_view graph_name, Args &&... args) -> TGraph *
auto add_graph(std::string_view graph_name, std::unique_ptr< GraphType > graph) -> GraphType *
std::map< std::string, DataMonitorCanvas > canvases_
static auto add_to_map(std::unique_ptr< ElementType > element, ContainerType &container) -> ElementType *
std::map< std::string, std::unique_ptr< TGraph > > graphs_
auto create_canvas(std::string_view canvas_name, std::string_view canvas_title, Args &&... args) -> DataMonitorCanvas &
DataMonitor()=default
static auto get_hist_dir(FairSink *sinkFile) -> TDirectory *
void save_to_file(std::string_view filename="")
auto get_canvas(const std::string &histName) -> DataMonitorCanvas &
auto get(const std::string &histName) -> TH1 *
auto make_hist(Args &&... args)
Definition R3BShared.h:69
constexpr auto DEFAULT_HIST_MONITOR_DIR