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,
44 std::string_view canvas_title,
45 Args&&... args) -> DataMonitorCanvas&;
46
47 // Use R3B::make_hist to create unique_ptr<TH1>
48 auto add_hist(std::unique_ptr<TH1> hist) -> TH1* { return add_to_map(std::move(hist), histograms_); }
49
50 template <typename Hist, typename... Args>
51 auto add_hist(std::string_view histName, std::string_view histTitle, Args&&... args) -> Hist*;
52
53 template <typename GraphType>
54 auto add_graph(std::string_view graph_name, std::unique_ptr<GraphType> graph) -> GraphType*
55 {
56 graph->SetName(graph_name.data());
57 return add_to_map(std::move(graph), graphs_);
58 }
59
60 template <typename... Args>
61 auto add_graph(std::string_view graph_name, Args&&... args) -> TGraph*
62 {
63 return add_graph(graph_name, std::make_unique<TGraph>(std::forward<Args>(args)...));
64 }
65
66 auto get(const std::string& histName) -> TH1*;
67
68 auto get_canvas(const std::string& histName) -> DataMonitorCanvas&;
69
70 // Save plots to FairSink
71 void save_to_sink(std::string_view folderName = "", FairSink* sinkFile = FairRun::Instance()->GetSink());
72 // Save plots to any root file
73 void save_to_file(std::string_view filename = "");
74
75 // Used for online monitoring
76 void draw_canvases();
77 void register_canvases(FairRun* run);
78 void reset_all_hists();
79
80 private:
81 std::string save_filename_{ "histograms_save" };
82 std::map<std::string, std::unique_ptr<TH1>> histograms_;
83 std::map<std::string, std::unique_ptr<TGraph>> graphs_;
84 std::map<std::string, DataMonitorCanvas> canvases_;
85 static auto get_hist_dir(FairSink* sinkFile) -> TDirectory*;
86 void write_all(TDirectory* dir);
87
88 template <typename ElementType, typename ContainerType>
89 static auto add_to_map(std::unique_ptr<ElementType> element, ContainerType& container) -> ElementType*;
90 template <typename ElementType, typename ContainerType>
91 static auto add_to_vector(std::unique_ptr<ElementType> element, ContainerType& container) -> ElementType*
92 {
93 auto* ptr = element.get();
94 container.emplace_back(std::move(element));
95 return ptr;
96 }
97 };
98
99 template <typename ElementType, typename ContainerType>
100 auto DataMonitor::add_to_map(std::unique_ptr<ElementType> element, ContainerType& container) -> ElementType*
101 {
102 const auto* element_name = element->GetName();
103 auto* element_ptr = element.get();
104 const auto [it, is_success] = container.emplace(std::string{ element_name }, std::move(element));
105 if (not is_success)
106 {
107 throw R3B::logic_error(fmt::format(
108 "Element with the name {} has been already added. Please use different name!", element_name));
109 }
110 return element_ptr;
111 }
112
113 template <typename Hist, typename... Args>
114 auto DataMonitor::add_hist(std::string_view histName, std::string_view histTitle, Args&&... args) -> Hist*
115 {
116 auto hist = R3B::make_hist<Hist>(histName.data(), histTitle.data(), std::forward<Args>(args)...);
117 return static_cast<Hist*>(add_hist(std::move(hist)));
118 }
119
120 template <typename... Args>
121 auto DataMonitor::create_canvas(std::string_view canvas_name,
122 std::string_view canvas_title,
123 Args&&... args) -> DataMonitorCanvas&
124 {
125 if (canvases_.find(std::string{ canvas_name }) != canvases_.end())
126 {
127 throw R3B::logic_error(fmt::format(
128 "A canvas with the name {} has been already added. Please use different name!", canvas_name));
129 }
130 const auto [it, is_success] = canvases_.insert(
131 { std::string{ canvas_name },
132 DataMonitorCanvas(this, canvas_name.data(), canvas_title.data(), std::forward<Args>(args)...) });
133 return it->second;
134 }
135
136 template <typename... Args>
138 : monitor_{ monitor }
139 , canvas_(std::make_unique<TCanvas>(std::forward<Args>(args)...))
140 {
141 }
142
143 template <int div_num, typename ElementType, typename... Args>
144 constexpr auto DataMonitorCanvas::add(Args&&... args) -> CanvasElement<ElementType>
145 {
146 static_assert(div_num > 0, "Division number of the histogram must be larger than 0!");
147 return add<ElementType>(div_num, std::forward<Args>(args)...);
148 }
149
150 template <typename ElementType, typename... Args>
151 constexpr auto DataMonitorCanvas::add(int div_num, Args&&... args) -> CanvasElement<ElementType>
152 {
153 ElementType* figure = nullptr;
154 if constexpr (std::is_same_v<TGraph, ElementType>)
155 {
156 figure = monitor_->add_graph<ElementType>(std::forward<Args>(args)...);
157 }
158 else
159 {
160 figure = monitor_->add_hist<ElementType>(std::forward<Args>(args)...);
161 }
162
163 if (figures_.find(div_num) != figures_.end())
164 {
165 figures_[div_num].emplace_back(figure);
166 }
167 else
168 {
169 figures_.emplace(div_num, std::vector<DrawableElementPtr>{ figure });
170 }
171 if constexpr (std::is_base_of_v<TH2, ElementType>)
172 {
173 const auto* option = figure->GetOption();
174 figure->SetOption(fmt::format("{} COLZ", option).c_str());
175 }
176 auto* pad = canvas_->GetPad(div_num);
177 return CanvasElement{ figure, pad };
178 }
179
180} // 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:70
constexpr auto DEFAULT_HIST_MONITOR_DIR