R3BROOT
R3B analysis software
Loading...
Searching...
No Matches
R3BValueError.h
Go to the documentation of this file.
1/******************************************************************************
2 * Copyright (C) 2024 GSI Helmholtzzentrum für Schwerionenforschung GmbH *
3 * Copyright (C) 2024-2026 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 <Math/GenVector/Cartesian3D.h>
16#include <Math/GenVector/CoordinateSystemTags.h>
17#include <Math/GenVector/DisplacementVector3D.h>
18#include <Rtypes.h>
19#include <TObject.h>
20#include <cmath>
21#ifndef __CLING__
22#include <fmt/base.h>
23#include <fmt/core.h>
24#endif
25#include <nlohmann/json.hpp>
26#include <nlohmann/json_fwd.hpp>
27#ifndef HAS_CPP_STANDARD_17
28#else
29#include <type_traits>
30#endif
31
32namespace R3B
33{
34
35#ifndef HAS_CPP_STANDARD_17
36 template <typename T>
37 concept Arithmetic = std::is_arithmetic_v<T>;
38#endif
39
40 template <typename DataType>
42 {
43 bool valid = true;
44 DataType value{};
45 DataType error{};
46
47 constexpr ValueError(DataType val, DataType err)
48 : value{ val }
49 , error{ err }
50 {
51 }
52
53 constexpr explicit ValueError(DataType val)
54 : ValueError{ val, DataType{} }
55 {
56 }
57 // ValueError(const DataType& val, const DataType& err)
58 // : value{ val }
59 // , error{ err }
60 // {
61 // }
62
64 : valid{ false }
65 {
66 }
67
68 auto operator-() const -> ValueError<DataType> { return { -value, error }; }
69
70#ifndef HAS_CPP_STANDARD_17
71 auto operator+(Arithmetic auto other) const -> ValueError<DataType>
72#else
73 template <typename OtherType, typename = std::enable_if_t<std::is_arithmetic_v<OtherType>>>
74 auto operator+(OtherType other) const -> ValueError<DataType>
75#endif
76 {
77 return { value + other, error };
78 }
79
80#ifndef HAS_CPP_STANDARD_17
81 auto operator*(Arithmetic auto other) const -> ValueError<DataType>
82#else
83 template <typename OtherType, typename = std::enable_if_t<std::is_arithmetic_v<OtherType>>>
84 auto operator*(OtherType other) const -> ValueError<DataType>
85#endif
86 {
87 return { value * other, error * other };
88 }
89
90#ifndef HAS_CPP_STANDARD_17
91 auto operator/(Arithmetic auto other) const -> ValueError<DataType>
92#else
93 template <typename OtherType, typename = std::enable_if_t<std::is_arithmetic_v<OtherType>>>
94 auto operator/(OtherType other) const -> ValueError<DataType>
95#endif
96 {
97 return { value / other, error / other };
98 }
99
100#ifndef HAS_CPP_STANDARD_17
102#else
103 template <typename OtherType, typename = std::enable_if_t<std::is_arithmetic_v<OtherType>>>
104 auto operator-(OtherType val) const -> ValueError<DataType>
105#endif
106 {
107 return { value - val, error };
108 }
109
110#ifndef HAS_CPP_STANDARD_17
111 void operator-=(Arithmetic auto val)
112#else
113 template <typename OtherType, typename = std::enable_if_t<std::is_arithmetic_v<OtherType>>>
114 void operator-=(OtherType val)
115#endif
116 {
117 value -= val;
118 }
119
120#ifndef HAS_CPP_STANDARD_17
121 auto operator>(Arithmetic auto val) -> bool
122#else
123 template <typename OtherType, typename = std::enable_if_t<std::is_arithmetic_v<OtherType>>>
124 auto operator>(OtherType val) -> bool
125#endif
126 {
127 return value > val;
128 }
129
130#ifndef HAS_CPP_STANDARD_17
131 auto operator<(Arithmetic auto val) -> bool
132#else
133 template <typename OtherType, typename = std::enable_if_t<std::is_arithmetic_v<OtherType>>>
134 auto operator<(OtherType val) -> bool
135#endif
136 {
137 return value < val;
138 }
139
140 public:
142 };
143
148 ROOT::Math::DisplacementVector3D<ROOT::Math::Cartesian3D<ValueErrorD>, ROOT::Math::DefaultCoordinateSystemTag>;
149
150 template <typename DataType>
152 {
153 auto new_value = left.value * right.value;
154 auto new_error = std::sqrt(right.value * right.value * left.error * left.error +
155 left.value * left.value * right.error * right.error);
156 return { new_value, new_error };
157 }
158
159 template <typename DataType>
161 {
162 auto new_value = numerator.value / denominator.value;
163 auto new_error = std::sqrt(numerator.error * numerator.error +
164 denominator.error * denominator.error * new_value * new_value) /
165 denominator.value;
166 return { new_value, std::abs(new_error) };
167 }
168
169 template <typename DataType>
171 {
172 auto new_value = left.value + right.value;
173 // TODO: not the fastest way
174 auto new_err = std::sqrt(left.error * left.error + right.error * right.error);
175 return { new_value, new_err };
176 }
177
178 template <typename DataType>
180 {
181 auto new_value = left.value - right.value;
182 // TODO: not the fastest way
183 auto new_err = std::sqrt(left.error * left.error + right.error * right.error);
184 return { new_value, new_err };
185 }
186
187 template <typename DataType>
193
194 template <typename DataType>
200
201 template <typename DataType>
203 {
204 return left.value > right.value;
205 }
206
207 template <typename DataType>
209 {
210 return left.value < right.value;
211 }
212
213 template <typename DataType>
214 void to_json(nlohmann::ordered_json& json_obj, const ValueError<DataType>& value)
215 {
216 json_obj = nlohmann::ordered_json{
217 { "value", value.value },
218 { "error", value.error },
219 };
220 }
221
222 template <typename DataType>
223 void from_json(const nlohmann::ordered_json& json_obj, ValueError<DataType>& value)
224 {
225 json_obj.at("value").get_to(value.value);
226 json_obj.at("error").get_to(value.error);
227 }
228} // namespace R3B
229
230#ifndef __CLING__
231template <typename DataType>
232class fmt::formatter<R3B::ValueError<DataType>>
233{
234 public:
235 // TODO: add more options
236 static constexpr auto parse(format_parse_context& ctx) { return ctx.end(); }
237 template <typename FmtContent>
238 constexpr auto format(const R3B::ValueError<DataType>& value_error, FmtContent& ctn) const
239 {
240 return fmt::format_to(ctn.out(), "{}+/-{}", value_error.value, value_error.error);
241 }
242};
243
244template <>
245class fmt::formatter<R3B::XYZVectorValueErrorD>
246{
247 public:
248 static constexpr auto parse(fmt::format_parse_context& ctx) { return ctx.end(); }
249 template <typename FmtContent>
250 constexpr auto format(const R3B::XYZVectorValueErrorD& hit, FmtContent& ctn) const
251 {
252 return fmt::format_to(ctn.out(), "[x: {}, y: {}, z: {}]", hit.X(), hit.Y(), hit.Z());
253 }
254};
255#endif
constexpr auto format(const R3B::ValueError< DataType > &value_error, FmtContent &ctn) const
static constexpr auto parse(format_parse_context &ctx)
constexpr auto format(const R3B::XYZVectorValueErrorD &hit, FmtContent &ctn) const
static constexpr auto parse(fmt::format_parse_context &ctx)
auto operator*(ValueError< DataType > left, ValueError< DataType > right) -> ValueError< DataType >
auto operator+(ValueError< DataType > left, ValueError< DataType > right) -> ValueError< DataType >
auto operator>(ValueError< DataType > &left, const ValueError< DataType > &right) -> bool
ValueError< float > ValueErrorF
void from_json(const nlohmann::ordered_json &json_obj, MinMaxValue< DataType > &value)
auto operator<(ValueError< DataType > &left, const ValueError< DataType > &right) -> bool
auto operator/(ValueError< DataType > numerator, ValueError< DataType > denominator) -> ValueError< DataType >
auto operator-=(ValueError< DataType > &left, const ValueError< DataType > &right) -> ValueError< DataType > &
ValueError< int > ValueErrorI
void to_json(nlohmann::ordered_json &json_obj, const MinMaxValue< DataType > &value)
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< ValueErrorD >, ROOT::Math::DefaultCoordinateSystemTag > XYZVectorValueErrorD
auto operator+=(ValueError< DataType > &left, const ValueError< DataType > &right) -> ValueError< DataType > &
auto operator-(ValueError< DataType > left, ValueError< DataType > right) -> ValueError< DataType >
ValueError< double > ValueErrorD
auto operator>(Arithmetic auto val) -> bool
void operator-=(Arithmetic auto val)
auto operator/(Arithmetic auto other) const -> ValueError< DataType >
auto operator-() const -> ValueError< DataType >
ClassDefNV(ValueError, 1)
auto operator+(Arithmetic auto other) const -> ValueError< DataType >
auto operator-(Arithmetic auto val) const -> ValueError< DataType >
auto operator<(Arithmetic auto val) -> bool
constexpr ValueError(DataType val)
constexpr ValueError(DataType val, DataType err)
auto operator*(Arithmetic auto other) const -> ValueError< DataType >