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