R3BROOT
R3B analysis software
Loading...
Searching...
No Matches
R3BShared.h
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) 2019 GSI Helmholtzzentrum für Schwerionenforschung GmbH *
3 * Copyright (C) 2019-2025 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#include "R3BException.h"
16#include "R3BLogger.h"
17#include <FairLogger.h>
18#include <R3BValueError.h>
19#include <TFile.h>
20#include <filesystem>
21#include <fmt/std.h>
22#include <regex>
23#include <type_traits>
24#include <utility>
25
26class TF1;
27class TH1;
28class TTree;
29
30namespace R3B
31{
32 // -------------------------------------------------------------------------
33 // root_owned:
34 // ROOT types owned by ROOT: TH1, TF1;
35 template <typename... Types>
37 {
38 };
39
41
42 template <typename Type, typename>
43 inline constexpr bool is_based_on = false;
44
45 template <typename Type, typename... BaseTypes>
46 inline constexpr bool is_based_on<Type, TypeCollection<BaseTypes...>> = (std::is_base_of_v<BaseTypes, Type> || ...);
47
48 template <typename Type>
50
51 template <typename RootType, typename... Args>
52 inline auto root_owned(Args&&... args)
53 {
54 static_assert(is_root_owned<RootType>, "root_owned: such type cannot be owned by ROOT!");
55 return new RootType(std::forward<Args>(args)...); // NOLINT
56 }
57
58 // -------------------------------------------------------------------------
59 // make owned historgam
60
61 template <typename Hist, typename... Args>
62 inline auto make_hist(Args&&... args)
63 {
64 static_assert(std::is_base_of_v<TH1, Hist>, "make_hist: not a histogram type!");
65 auto hist = std::make_unique<Hist>(std::forward<Args>(args)...);
66 hist->SetDirectory(nullptr);
67 return hist;
68 }
69
70 // -------------------------------------------------------------------------
71 // make_rootfile:
73 {
74 void operator()(TFile* rootfile)
75 {
76 LOG(debug2) << "Closing file " << rootfile->GetName();
77 rootfile->Close();
78 delete rootfile; // NOLINT
79 }
80 };
81
82 using unique_rootfile = std::unique_ptr<TFile, TFileDeleter>;
83
84 // make a root file that closes automatically
85 template <typename... Args>
86 inline auto make_rootfile(Args&&... args)
87 {
88 return unique_rootfile{ new TFile(std::forward<Args>(args)...) };
89 }
90
91 // -------------------------------------------------------------------------
92 // sides enum class:
93 // clang-format off
94 // Get the length of a C array:
95 template <typename DataType, std::size_t size>
96 constexpr std::size_t GetSize(const DataType (&/*unused*/)[size]) // NOLINT
97 {
98 return size;
99 }
100 // clang-format on
101
102 // -------------------------------------------------------------------------
103 // side enums:
104 enum class Side : bool
105 {
108 };
109
110 // convert sides to indices: left -> 0, right -> 1
111 constexpr auto toIndex(Side side) -> size_t
112 {
113 if (side == Side::left)
114 {
115 return 0;
116 }
117 return 1;
118 }
119
120 // convert indices to sides: 0 -> left, 1 -> right
121 constexpr auto IndexToSide(size_t index) -> Side
122 {
123 if (index == 0)
124 {
125 return Side::left;
126 }
127 return Side::right;
128 }
129 // -------------------------------------------------------------------------
130 // left and right pair
131 template <typename DataType>
132 class LRPair
133 {
134 public:
135 LRPair() = default;
136 LRPair(const DataType& left, const DataType& right)
137 : data_{ std::make_pair(left, right) }
138 , is_valid(true)
139 {
140 }
141
142 auto left() -> DataType& { return data_.first; }
143 auto right() -> DataType& { return data_.second; }
144 auto left() const -> const DataType& { return data_.first; }
145 auto right() const -> const DataType& { return data_.second; }
146 auto get(Side side) const -> const DataType& { return (side == Side::left) ? data_.first : data_.second; }
147 auto get(Side side) -> DataType& { return (side == Side::left) ? data_.first : data_.second; }
148 void set_left(const DataType& value) { data_.first = value; }
149 void set_right(const DataType& value) { data_.second = value; }
150
151 private:
152 std::pair<DataType, DataType> data_;
153 bool is_valid = false;
154
155 public:
157 };
158
159 // -------------------------------------------------------------------------
160 // fast exponential function:
161 static const uint8_t DEFAULT_ITERATION = 8U;
162 template <uint8_t iterations = DEFAULT_ITERATION>
163 auto FastExp(const float val) -> float
164 {
165 auto exp = 1.F + val / (1U << iterations);
166 for (auto i = 0; i < iterations; ++i)
167 {
168 exp *= exp;
169 }
170 return exp;
171 }
172
173 // -------------------------------------------------------------------------
174 // File handling
175 namespace fs = std::filesystem;
176 inline auto GetParentDir(std::string_view filename) -> fs::path
177 {
178 auto path = fs::path{ filename };
179 auto parent_folder = path.parent_path();
180 if (parent_folder.empty())
181 {
182 return ".";
183 }
184
185 if (not fs::exists(parent_folder))
186 {
187 R3BLOG(
188 error,
189 fmt::format(R"(Cannot get the parent folder of the regex path "{}"! Setting it to the current folder)",
190 filename));
191 return ".";
192 }
193
194 return parent_folder;
195 }
196
197 inline auto GetFilesFromRegex(std::string_view filename_regex) -> std::vector<std::string>
198 {
199 if (filename_regex.empty())
200 {
201 return {};
202 }
203 auto regex_path = fs::path{ filename_regex };
204 auto parent_folder = GetParentDir(filename_regex);
205 const auto regex_string = regex_path.filename().string();
206 auto filelist = std::vector<std::string>{};
207 for (const auto& dir_entry : fs::directory_iterator(parent_folder))
208 {
209 if (std::regex_match(dir_entry.path().filename().string(), std::regex{ regex_string }))
210 {
211 filelist.emplace_back(fs::absolute(dir_entry.path()));
212 }
213 }
214 if (filelist.empty())
215 {
216 R3BLOG(error, fmt::format(R"(Cannot find any files with regex "{}")", regex_string));
217 }
218 std::sort(filelist.begin(), filelist.end());
219 return filelist;
220 }
221} // namespace R3B
#define R3BLOG(severity, x)
Definition R3BLogger.h:35
LRPair()=default
void set_left(const DataType &value)
Definition R3BShared.h:148
auto right() const -> const DataType &
Definition R3BShared.h:145
LRPair(const DataType &left, const DataType &right)
Definition R3BShared.h:136
auto left() const -> const DataType &
Definition R3BShared.h:144
auto get(Side side) const -> const DataType &
Definition R3BShared.h:146
auto left() -> DataType &
Definition R3BShared.h:142
ClassDefNV(LRPair, 2)
void set_right(const DataType &value)
Definition R3BShared.h:149
auto get(Side side) -> DataType &
Definition R3BShared.h:147
auto right() -> DataType &
Definition R3BShared.h:143
auto make_hist(Args &&... args)
Definition R3BShared.h:62
auto make_rootfile(Args &&... args)
Definition R3BShared.h:86
static const uint8_t DEFAULT_ITERATION
Definition R3BShared.h:161
auto GetParentDir(std::string_view filename) -> fs::path
Definition R3BShared.h:176
constexpr bool is_root_owned
Definition R3BShared.h:49
constexpr std::size_t GetSize(const DataType(&)[size])
Definition R3BShared.h:96
auto GetFilesFromRegex(std::string_view filename_regex) -> std::vector< std::string >
Definition R3BShared.h:197
constexpr auto toIndex(Side side) -> size_t
Definition R3BShared.h:111
auto FastExp(const float val) -> float
Definition R3BShared.h:163
TypeCollection< TF1, TH1, TTree > RootTypes
Definition R3BShared.h:40
constexpr bool is_based_on
Definition R3BShared.h:43
auto root_owned(Args &&... args)
Definition R3BShared.h:52
constexpr auto IndexToSide(size_t index) -> Side
Definition R3BShared.h:121
std::unique_ptr< TFile, TFileDeleter > unique_rootfile
Definition R3BShared.h:82
void operator()(TFile *rootfile)
Definition R3BShared.h:74