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