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