R3BROOT
R3B analysis software
Loading...
Searching...
No Matches
R3BDataMonitor.cxx
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#include "R3BDataMonitor.h"
16#include "R3BException.h"
17#include "R3BLogger.h"
18#include <FairRootFileSink.h>
19#include <FairRunOnline.h>
20#include <FairRuntimeDb.h>
21#include <FairSink.h>
22#include <TDirectory.h>
23#include <TFile.h>
24#include <TH1.h>
25#include <chrono>
26#include <fmt/chrono.h>
27#include <fmt/core.h>
28#include <fmt/format.h>
29#include <memory>
30#include <string>
31#include <string_view>
32
33namespace
34{
35 auto create_datatime_rootfile(std::string_view base_filename) -> std::unique_ptr<TFile>
36 {
37 auto time = std::chrono::system_clock::now();
38 const auto file_name = fmt::format("{}-{:%Y-%m-%d-%Hh-%Mm-%Ss}.root", base_filename, time);
39 auto* root_file = TFile::Open(file_name.data(), "RECREATE");
40 return std::unique_ptr<TFile>{ root_file };
41 }
42
43} // namespace
44
45namespace R3B
46{
47 auto DataMonitor::get(const std::string& histName) -> TH1*
48 {
49 if (auto hist = histograms_.find(histName); hist != histograms_.end())
50 {
51 return hist->second.get();
52 }
53 throw R3B::logic_error(fmt::format("Histogram with the name {} doesn't exist!", histName));
54 }
55
56 auto DataMonitor::get_canvas(const std::string& histName) -> DataMonitorCanvas&
57 {
58 if (auto canvas = canvases_.find(histName); canvas != canvases_.end())
59 {
60 return canvas->second;
61 }
62 throw R3B::logic_error(fmt::format("Canvas with the name {} doesn't exist!", histName));
63 }
64
65 void DataMonitor::save_to_sink(std::string_view folderName, FairSink* sinkFile)
66 {
67 auto* hist_dir = get_hist_dir(sinkFile);
68 auto* new_dir = folderName.empty() ? hist_dir : hist_dir->mkdir(folderName.data(), "", true);
69 if (new_dir == nullptr)
70 {
72 fmt::format("Failed to create a sub directory {} for the histrogams!", folderName));
73 }
74 R3BLOG(info,
75 fmt::format("Saving figures to the directory {:?} in the root file {:?}",
76 new_dir->GetName(),
77 new_dir->GetFile()->GetName()));
78
79 write_all(new_dir);
80 // old_dir->cd();
81 }
82
83 auto DataMonitor::get_hist_dir(FairSink* sinkFile) -> TDirectory*
84 {
85 auto* rootSinkFile = dynamic_cast<FairRootFileSink*>(sinkFile);
86 if (rootSinkFile == nullptr)
87 {
88 throw R3B::logic_error("Cannot save the histograms as the output file is not a root file!");
89 }
90 auto* rootFile = rootSinkFile->GetRootFile();
91 auto* hist_dir = rootFile->mkdir(DEFAULT_HIST_MONITOR_DIR, "", true);
92 if (hist_dir == nullptr)
93 {
94 throw R3B::runtime_error("Cannot create a directory for the histrogams!");
95 }
96 return hist_dir;
97 }
98
100 {
101 for (auto& [canvas_name, canvas] : canvases_)
102 {
103 canvas.draw();
104 }
105 }
106
108 {
109 if (auto* run_online = dynamic_cast<FairRunOnline*>(run); run_online != nullptr)
110 {
111 for (auto& [name, canvas] : canvases_)
112 {
113 run_online->AddObject(canvas.get_canvas());
114 }
115 }
116 }
117
119 {
120 for (auto& [name, hist] : histograms_)
121 {
122 hist->Reset();
123 }
124 }
125
126 void DataMonitor::save_to_file(std::string_view filename)
127 {
128 if (filename.empty())
129 {
130 filename = save_filename_;
131 }
132 auto rootfile = create_datatime_rootfile(filename);
133 R3BLOG(info, fmt::format("Saving histograms to {}", rootfile->GetName()));
134 write_all(rootfile.get());
135 }
136
137 void DataMonitor::write_all(TDirectory* dir)
138 {
139 for (auto& [name, hist] : histograms_)
140 {
141 if (hist->GetEntries() == 0)
142 {
143 R3BLOG(warn, fmt::format("Histogram {} is empty while written to the file!", hist->GetName()));
144 }
145 dir->WriteObject(hist.get(), hist->GetName());
146 }
147 for (auto& [name, graph] : graphs_)
148 {
149 dir->WriteObject(graph.get(), graph->GetName(), "overwrite");
150 }
151 }
152} // namespace R3B
#define R3BLOG(severity, x)
Definition R3BLogger.h:32
void write_all(TDirectory *dir)
std::map< std::string, std::unique_ptr< TH1 > > histograms_
std::string save_filename_
void save_to_sink(std::string_view folderName="", FairSink *sinkFile=FairRun::Instance() ->GetSink())
void register_canvases(FairRun *run)
std::map< std::string, DataMonitorCanvas > canvases_
std::map< std::string, std::unique_ptr< TGraph > > graphs_
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 *
constexpr auto DEFAULT_HIST_MONITOR_DIR