yoda is hosted by Hepforge, IPPP Durham
YODA - Yet more Objects for Data Analysis 2.0.0
Bin.h
Go to the documentation of this file.
1// -*- C++ -*-
2//
3// This file is part of YODA -- Yet more Objects for Data Analysis
4// Copyright (C) 2008-2023 The YODA collaboration (see AUTHORS for details)
5//
6#ifndef YODA_Bin_h
7#define YODA_Bin_h
8
10#include "YODA/Utils/Traits.h"
11#include <iostream>
12
13namespace YODA {
14
16 template <typename T>
19 // {
20 ArithmeticWrapper() : _storedNumber(0) {}
21
22 ArithmeticWrapper(T num) : _storedNumber(num) {}
23 // }
24
26 // {
27
29 _storedNumber += std::forward<T>(rhs);
30 return *this;
31 }
33 _storedNumber -= std::forward<T>(rhs);
34 return *this;
35 }
37 _storedNumber /= std::forward<T>(rhs);
38 return *this;
39 }
41 _storedNumber *= std::forward<T>(rhs);
42 return *this;
43 }
44
46 template<typename RetT = ArithmeticWrapper<T>>
47 auto operator%=(T&& rhs)
48 -> std::enable_if_t<std::is_integral<T>::value, RetT&> {
49 _storedNumber %= std::forward<T>(rhs);
50 return *this;
51 }
52 // }
53
58 operator T() { return _storedNumber; }
59
63 operator const T&() const { return _storedNumber; }
64
65 T _storedNumber;
66 };
67
79 template <typename T, typename BinningT>
80 class BinBase : public std::conditional_t<std::is_arithmetic<T>::value,
81 ArithmeticWrapper<T>, T> {
82 protected:
83
85 // {
86 using isArithmetic = std::conditional_t<std::is_arithmetic<T>::value,
87 std::true_type, std::false_type>;
88
89 using BaseT = std::conditional_t<isArithmetic::value,
91
92 template <size_t axisNum>
93 using axisEdgeT = typename BinningT::template getAxisT<axisNum>::EdgeT;
94
95 // }
96
97 public:
99 // {
100
101 // For self-consistency, the user should
102 // always pass the parent binning!
103 BinBase() = delete;
104
105 // Default copy constructor for STL vector
106 BinBase(const BinBase& rhs) = default;
107
108 // Default move constructor for STL vector
109 BinBase(BinBase&& rhs) = default;
110
111
112 BinBase(size_t binIndex, const BinningT& binning)
113 : _binIndex(binIndex), _binning(&binning) { }
114
116 BinBase(const T& storedVal, size_t binIndex, const BinningT& binning)
117 : BaseT(storedVal), _binIndex(binIndex), _binning(&binning) { }
118
119 BinBase(T&& storedVal, size_t binIndex, const BinningT& binning)
120 : BaseT(std::move(storedVal)), _binIndex(binIndex), _binning(&binning) { }
121
122 BinBase(const BinBase& other, const BinningT& binning)
123 : BaseT(other), _binIndex(other._binIndex), _binning(&binning) { }
124
128 BinBase& operator=(BaseT&& rhs) noexcept {
129 //BaseT::operator=(std::forward<BaseT>(rhs));
130 BaseT::operator=(std::move(rhs));
131 return *this;
132 }
133
135 BinBase& operator=(const BaseT& rhs) noexcept {
136 BaseT::operator=(rhs);
137 return *this;
138 }
139
144 BinBase& operator=(const BinBase& rhs) noexcept {
145 if (this != &rhs) {
146 BaseT::operator=(rhs);
147 }
148 return *this;
149 }
150
155 BinBase& operator=(BinBase&& rhs) noexcept {
156 if (this != &rhs) {
157 BaseT::operator=(std::move(rhs));
158 }
159 return *this;
160 }
161
162 // @}
163
165 // @{
166
168 const T& raw() const noexcept {
169 return *this;
170 }
171
173 size_t index() const noexcept {
174 return _binIndex;
175 }
176
177 bool isMasked() const noexcept {
178 return _binning->isMasked(_binIndex);
179 }
180
181 bool isVisible() const noexcept {
182 return _binning->isVisible(_binIndex);
183 }
184
185 // @}
186
188 // @{
189
191 double dVol() const noexcept {
192 return _binning->dVol(_binIndex);
193 }
194
206 template <size_t dimNum>
208 const auto& axis = _binning->template axis<dimNum>();
209 size_t binIdx = _binning->globalToLocalIndices(_binIndex)[dimNum];
210 return axis.width(binIdx);
211 }
212
216 template <size_t dimNum>
218 const auto& axis = _binning->template axis<dimNum>();
219 size_t binIdx = _binning->globalToLocalIndices(_binIndex)[dimNum];
220 return axis.max(binIdx);
221 }
222
226 template <size_t dimNum>
228 const auto& axis = _binning->template axis<dimNum>();
229 size_t binIdx = _binning->globalToLocalIndices(_binIndex)[dimNum];
230 return axis.min(binIdx);
231 }
232
236 template <size_t dimNum>
238 const auto& axis = _binning->template axis<dimNum>();
239 size_t binIdx = _binning->globalToLocalIndices(_binIndex)[dimNum];
240 return axis.mid(binIdx);
241 }
242
246 template <size_t dimNum>
248 const auto& axis = _binning->template axis<dimNum>();
249 size_t binIdx = _binning->globalToLocalIndices(_binIndex)[dimNum];
250 return axis.edge(binIdx);
251 }
252
253 // @}
254
255 protected:
256
257 const size_t _binIndex;
258
259 const BinningT* _binning;
260 };
261
262
264 template <size_t N, typename T, typename BinningT>
265 class Bin : public BinBase<T, BinningT> {
266
267 protected:
268
270
271 public:
272
273 using BaseT::BaseT;
274 using BaseT::operator=;
275
276 // For self-consistency, the user should
277 // always pass the parent binning!
278 Bin() = delete;
279
280 /* This would have been a nice idea, except we cannot guarantee
281 that the content type even has the concept of a value.
282 double value(const bool divbyvol = false) const noexcept {
283 const double scale = divbyvol? BaseT::dVol() : 1.0;
284 if constexpr (hasFillDim<T>::value) {
285 if constexpr (T::FillDim::value > N) {
286 return BaseT::mean(T::FillDim::value) / scale;// profiles
287 }
288 return BaseT::sumW() / scale; // histograms
289 }
290 return BaseT::value() / scale; // other
291 }
292
294 double valueErr(const bool divbyvol = false) const noexcept {
295 const double scale = divbyvol? BaseT::dVol() : 1.0;
296 if constexpr (hasFillDim<T>::value) {
297 if constexpr (T::FillDim::value > N) { // profiles
298 return BaseT::stdErr(T::FillDim::value) / scale;
299 }
300 return BaseT::errW() / scale; // histograms
301 }
302 return BaseT::valueErr() / scale; // other
303 }
304
306 double relErr() const noexcept {
307 return value()? valueErr() / value() : std::numeric_limits<double>::quiet_NaN();
308 }
309
311 double density() const noexcept {
312 return value() / BaseT::dVol();
313 }
314
316 double densityErr() const noexcept {
317 return valueErr() / BaseT::dVol();
318 }*/
319
320 };
321
322
324 template<typename T, typename BinningT>
325 class Bin<1, T, BinningT>
326 : public BinBase<T, BinningT>,
327 public XBinMixin<Bin<1, T, BinningT>,
328 typename BinningT::template getEdgeT<0>> {
329 protected:
330
332
333 template <size_t axisNum>
334 using axisEdgeT = typename BinningT::template getAxisT<axisNum>::EdgeT;
335
336 public:
337
338 using BaseT::BaseT;
339 using BaseT::operator=;
340
341 // For self-consistency, the user should
342 // always pass the parent binning!
343 Bin() = delete;
344
346 double dLen() const noexcept { return BaseT::dVol(); }
347
348 };
349
350
352 template<typename T, typename BinningT>
353 class Bin<2, T, BinningT>
354 : public BinBase<T, BinningT>,
355 public XBinMixin<Bin<2, T, BinningT>,
356 typename BinningT::template getEdgeT<0>>,
357 public YBinMixin<Bin<2, T, BinningT>,
358 typename BinningT::template getEdgeT<1>> {
359
360 protected:
361
363
364 template <size_t axisNum>
365 using axisEdgeT = typename BinningT::template getAxisT<axisNum>::EdgeT;
366
367 public:
368
369 using BaseT::BaseT;
370 using BaseT::operator=;
371
372 // For self-consistency, the user should
373 // always pass the parent binning!
374 Bin() = delete;
375
377 double dArea() const noexcept { return BaseT::dVol(); }
378
379 };
380
381
383 template<typename T, typename BinningT>
384 class Bin<3, T, BinningT>
385 : public BinBase<T, BinningT>,
386 public XBinMixin<Bin<3, T, BinningT>,
387 typename BinningT::template getEdgeT<0>>,
388 public YBinMixin<Bin<3, T, BinningT>,
389 typename BinningT::template getEdgeT<1>>,
390 public ZBinMixin<Bin<3, T, BinningT>,
391 typename BinningT::template getEdgeT<2>> {
392
393 protected:
394
396
397 template <size_t axisNum>
398 using axisEdgeT = typename BinningT::template getAxisT<axisNum>::EdgeT;
399
400 public:
401
402 using BaseT::BaseT;
403 using BaseT::operator=;
404
405 // For self-consistency, the user should
406 // always pass the parent binning!
407 Bin() = delete;
408
409 };
410
411}
412
413#endif
Bin base class consisting of mix of histogram bin content and space characteristics of this bin (widt...
Definition Bin.h:81
BinBase & operator=(BaseT &&rhs) noexcept
Assignment operator of an rvalue content type.
Definition Bin.h:128
std::conditional_t< isArithmetic::value, ArithmeticWrapper< T >, T > BaseT
Definition Bin.h:90
enable_if_CAxisT< axisEdgeT< dimNum > > min() const noexcept
Minimum of this bin interval.
Definition Bin.h:227
BinBase(const BinBase &rhs)=default
BinBase(T &&storedVal, size_t binIndex, const BinningT &binning)
Definition Bin.h:119
typename BinningT::template getAxisT< axisNum >::EdgeT axisEdgeT
Definition Bin.h:93
enable_if_DAxisT< axisEdgeT< dimNum > > edge() const noexcept
Edge of this bin.
Definition Bin.h:247
const T & raw() const noexcept
return stored content
Definition Bin.h:168
BinBase & operator=(const BaseT &rhs) noexcept
Assignment operator of a content type.
Definition Bin.h:135
std::conditional_t< std::is_arithmetic< T >::value, std::true_type, std::false_type > isArithmetic
Definition Bin.h:87
bool isMasked() const noexcept
Definition Bin.h:177
enable_if_CAxisT< axisEdgeT< dimNum > > width() const noexcept
Width of this bin along a specific axis.
Definition Bin.h:207
double dVol() const noexcept
Differential volume of this bin (i.e. product of bin widths)
Definition Bin.h:191
size_t index() const noexcept
return stored index
Definition Bin.h:173
BinBase(size_t binIndex, const BinningT &binning)
Definition Bin.h:112
bool isVisible() const noexcept
Definition Bin.h:181
BinBase()=delete
BinBase(const T &storedVal, size_t binIndex, const BinningT &binning)
Setting constructor.
Definition Bin.h:116
enable_if_CAxisT< axisEdgeT< dimNum > > mid() const noexcept
Middle of this bin interval.
Definition Bin.h:237
BinBase(const BinBase &other, const BinningT &binning)
Definition Bin.h:122
BinBase(BinBase &&rhs)=default
BinBase & operator=(const BinBase &rhs) noexcept
Copy assignment operator.
Definition Bin.h:144
BinBase & operator=(BinBase &&rhs) noexcept
Move assignment operator.
Definition Bin.h:155
enable_if_CAxisT< axisEdgeT< dimNum > > max() const noexcept
Maximum of this bin interval.
Definition Bin.h:217
double dLen() const noexcept
Differential length of this bin (i.e. the bin width)
Definition Bin.h:346
typename BinningT::template getAxisT< axisNum >::EdgeT axisEdgeT
Definition Bin.h:334
double dArea() const noexcept
Differential area of this bin (i.e. product of bin widths)
Definition Bin.h:377
typename BinningT::template getAxisT< axisNum >::EdgeT axisEdgeT
Definition Bin.h:365
typename BinningT::template getAxisT< axisNum >::EdgeT axisEdgeT
Definition Bin.h:398
generic Bin version that derives from BinBase
Definition Bin.h:265
Bin()=delete
Anonymous namespace to limit visibility.
std::enable_if_t<!std::is_floating_point< EdgeT >::value, EdgeT > enable_if_DAxisT
Checks if edge type is discrete and returns edge type.
std::enable_if_t< std::is_floating_point< EdgeT >::value, EdgeT > enable_if_CAxisT
Checks if edge type is continuous and returns edge type.
Arithmetic wrapper to emulate inheritance from arithmetic types.
Definition Bin.h:17
ArithmeticWrapper(T num)
Definition Bin.h:22
auto operator%=(T &&rhs) -> std::enable_if_t< std::is_integral< T >::value, RetT & >
Definition Bin.h:47
ArithmeticWrapper< T > & operator*=(T &&rhs)
Definition Bin.h:40
ArithmeticWrapper< T > & operator/=(T &&rhs)
Definition Bin.h:36
ArithmeticWrapper< T > & operator+=(T &&rhs)
Definition Bin.h:28
ArithmeticWrapper< T > & operator-=(T &&rhs)
Definition Bin.h:32
CRTP mixin introducing convenience aliases along X axis.
Definition BinUtils.h:18
CRTP mixin introducing convenience aliases along Y axis.
Definition BinUtils.h:70
CRTP mixin introducing convenience aliases along Z axis.
Definition BinUtils.h:122