File indexing completed on 2025-04-19 09:13:37
0001
0002
0003
0004
0005
0006 #ifndef YODA_Bin_h
0007 #define YODA_Bin_h
0008
0009 #include "YODA/Utils/BinUtils.h"
0010 #include "YODA/Utils/Traits.h"
0011 #include <iostream>
0012
0013 namespace YODA {
0014
0015
0016 template <typename T>
0017 struct ArithmeticWrapper {
0018
0019
0020 ArithmeticWrapper() : _storedNumber(0) {}
0021
0022 ArithmeticWrapper(T num) : _storedNumber(num) {}
0023
0024
0025
0026
0027
0028 ArithmeticWrapper<T>& operator+=(T&& rhs) {
0029 _storedNumber += std::forward<T>(rhs);
0030 return *this;
0031 }
0032 ArithmeticWrapper<T>& operator-=(T&& rhs) {
0033 _storedNumber -= std::forward<T>(rhs);
0034 return *this;
0035 }
0036 ArithmeticWrapper<T>& operator/=(T&& rhs) {
0037 _storedNumber /= std::forward<T>(rhs);
0038 return *this;
0039 }
0040 ArithmeticWrapper<T>& operator*=(T&& rhs) {
0041 _storedNumber *= std::forward<T>(rhs);
0042 return *this;
0043 }
0044
0045
0046 template<typename RetT = ArithmeticWrapper<T>>
0047 auto operator%=(T&& rhs)
0048 -> std::enable_if_t<std::is_integral<T>::value, RetT&> {
0049 _storedNumber %= std::forward<T>(rhs);
0050 return *this;
0051 }
0052
0053
0054
0055
0056
0057
0058 operator T() { return _storedNumber; }
0059
0060
0061
0062
0063 operator const T&() const { return _storedNumber; }
0064
0065 T _storedNumber;
0066 };
0067
0068
0069
0070
0071
0072
0073
0074
0075
0076
0077
0078
0079 template <typename T, typename BinningT>
0080 class BinBase : public std::conditional_t<std::is_arithmetic<T>::value,
0081 ArithmeticWrapper<T>, T> {
0082 protected:
0083
0084
0085
0086 using isArithmetic = std::conditional_t<std::is_arithmetic<T>::value,
0087 std::true_type, std::false_type>;
0088
0089 using BaseT = std::conditional_t<isArithmetic::value,
0090 ArithmeticWrapper<T>, T>;
0091
0092 template <size_t axisNum>
0093 using axisEdgeT = typename BinningT::template getAxisT<axisNum>::EdgeT;
0094
0095
0096
0097 public:
0098
0099
0100
0101
0102
0103 BinBase() = delete;
0104
0105
0106 BinBase(const BinBase& rhs) = default;
0107
0108
0109 BinBase(BinBase&& rhs) = default;
0110
0111
0112 BinBase(size_t binIndex, const BinningT& binning)
0113 : _binIndex(binIndex), _binning(&binning) { }
0114
0115
0116 BinBase(const T& storedVal, size_t binIndex, const BinningT& binning)
0117 : BaseT(storedVal), _binIndex(binIndex), _binning(&binning) { }
0118
0119 BinBase(T&& storedVal, size_t binIndex, const BinningT& binning)
0120 : BaseT(std::move(storedVal)), _binIndex(binIndex), _binning(&binning) { }
0121
0122 BinBase(const BinBase& other, const BinningT& binning)
0123 : BaseT(other), _binIndex(other._binIndex), _binning(&binning) { }
0124
0125
0126
0127
0128 BinBase& operator=(BaseT&& rhs) noexcept {
0129
0130 BaseT::operator=(std::move(rhs));
0131 return *this;
0132 }
0133
0134
0135 BinBase& operator=(const BaseT& rhs) noexcept {
0136 BaseT::operator=(rhs);
0137 return *this;
0138 }
0139
0140
0141
0142
0143
0144 BinBase& operator=(const BinBase& rhs) noexcept {
0145 if (this != &rhs) {
0146 BaseT::operator=(rhs);
0147 }
0148 return *this;
0149 }
0150
0151
0152
0153
0154
0155 BinBase& operator=(BinBase&& rhs) noexcept {
0156 if (this != &rhs) {
0157 BaseT::operator=(std::move(rhs));
0158 }
0159 return *this;
0160 }
0161
0162
0163
0164
0165
0166
0167
0168 const T& raw() const noexcept {
0169 return *this;
0170 }
0171
0172
0173 size_t index() const noexcept {
0174 return _binIndex;
0175 }
0176
0177 bool isMasked() const noexcept {
0178 return _binning->isMasked(_binIndex);
0179 }
0180
0181 bool isVisible() const noexcept {
0182 return _binning->isVisible(_binIndex);
0183 }
0184
0185
0186
0187
0188
0189
0190
0191 double dVol() const noexcept {
0192 return _binning->dVol(_binIndex);
0193 }
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206 template <size_t dimNum>
0207 enable_if_CAxisT<axisEdgeT<dimNum>> width() const noexcept {
0208 const auto& axis = _binning->template axis<dimNum>();
0209 size_t binIdx = _binning->globalToLocalIndices(_binIndex)[dimNum];
0210 return axis.width(binIdx);
0211 }
0212
0213
0214
0215
0216 template <size_t dimNum>
0217 enable_if_CAxisT<axisEdgeT<dimNum>> max() const noexcept {
0218 const auto& axis = _binning->template axis<dimNum>();
0219 size_t binIdx = _binning->globalToLocalIndices(_binIndex)[dimNum];
0220 return axis.max(binIdx);
0221 }
0222
0223
0224
0225
0226 template <size_t dimNum>
0227 enable_if_CAxisT<axisEdgeT<dimNum>> min() const noexcept {
0228 const auto& axis = _binning->template axis<dimNum>();
0229 size_t binIdx = _binning->globalToLocalIndices(_binIndex)[dimNum];
0230 return axis.min(binIdx);
0231 }
0232
0233
0234
0235
0236 template <size_t dimNum>
0237 enable_if_CAxisT<axisEdgeT<dimNum>> mid() const noexcept {
0238 const auto& axis = _binning->template axis<dimNum>();
0239 size_t binIdx = _binning->globalToLocalIndices(_binIndex)[dimNum];
0240 return axis.mid(binIdx);
0241 }
0242
0243
0244
0245
0246 template <size_t dimNum>
0247 enable_if_DAxisT<axisEdgeT<dimNum>> edge() const noexcept {
0248 const auto& axis = _binning->template axis<dimNum>();
0249 size_t binIdx = _binning->globalToLocalIndices(_binIndex)[dimNum];
0250 return axis.edge(binIdx);
0251 }
0252
0253
0254
0255 protected:
0256
0257 const size_t _binIndex;
0258
0259 const BinningT* _binning;
0260 };
0261
0262
0263
0264 template <size_t N, typename T, typename BinningT>
0265 class Bin : public BinBase<T, BinningT> {
0266
0267 protected:
0268
0269 using BaseT = BinBase<T, BinningT>;
0270
0271 public:
0272
0273 using BaseT::BaseT;
0274 using BaseT::operator=;
0275
0276
0277
0278 Bin() = delete;
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288
0289
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313
0314
0315
0316
0317
0318
0319
0320 };
0321
0322
0323
0324 template<typename T, typename BinningT>
0325 class Bin<1, T, BinningT>
0326 : public BinBase<T, BinningT>,
0327 public XBinMixin<Bin<1, T, BinningT>,
0328 typename BinningT::template getEdgeT<0>> {
0329 protected:
0330
0331 using BaseT = BinBase<T, BinningT>;
0332
0333 template <size_t axisNum>
0334 using axisEdgeT = typename BinningT::template getAxisT<axisNum>::EdgeT;
0335
0336 public:
0337
0338 using BaseT::BaseT;
0339 using BaseT::operator=;
0340
0341
0342
0343 Bin() = delete;
0344
0345
0346 double dLen() const noexcept { return BaseT::dVol(); }
0347
0348 };
0349
0350
0351
0352 template<typename T, typename BinningT>
0353 class Bin<2, T, BinningT>
0354 : public BinBase<T, BinningT>,
0355 public XBinMixin<Bin<2, T, BinningT>,
0356 typename BinningT::template getEdgeT<0>>,
0357 public YBinMixin<Bin<2, T, BinningT>,
0358 typename BinningT::template getEdgeT<1>> {
0359
0360 protected:
0361
0362 using BaseT = BinBase<T, BinningT>;
0363
0364 template <size_t axisNum>
0365 using axisEdgeT = typename BinningT::template getAxisT<axisNum>::EdgeT;
0366
0367 public:
0368
0369 using BaseT::BaseT;
0370 using BaseT::operator=;
0371
0372
0373
0374 Bin() = delete;
0375
0376
0377 double dArea() const noexcept { return BaseT::dVol(); }
0378
0379 };
0380
0381
0382
0383 template<typename T, typename BinningT>
0384 class Bin<3, T, BinningT>
0385 : public BinBase<T, BinningT>,
0386 public XBinMixin<Bin<3, T, BinningT>,
0387 typename BinningT::template getEdgeT<0>>,
0388 public YBinMixin<Bin<3, T, BinningT>,
0389 typename BinningT::template getEdgeT<1>>,
0390 public ZBinMixin<Bin<3, T, BinningT>,
0391 typename BinningT::template getEdgeT<2>> {
0392
0393 protected:
0394
0395 using BaseT = BinBase<T, BinningT>;
0396
0397 template <size_t axisNum>
0398 using axisEdgeT = typename BinningT::template getAxisT<axisNum>::EdgeT;
0399
0400 public:
0401
0402 using BaseT::BaseT;
0403 using BaseT::operator=;
0404
0405
0406
0407 Bin() = delete;
0408
0409 };
0410
0411 }
0412
0413 #endif