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