File indexing completed on 2025-01-18 09:11:09
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Utilities/AxisDefinitions.hpp"
0013 #include "Acts/Utilities/BinningData.hpp"
0014 #include "Acts/Utilities/BinningType.hpp"
0015 #include "Acts/Utilities/Enumerate.hpp"
0016
0017 #include <array>
0018 #include <cstddef>
0019 #include <iostream>
0020 #include <iterator>
0021 #include <memory>
0022 #include <stdexcept>
0023 #include <string>
0024 #include <vector>
0025
0026 namespace Acts {
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038 class BinUtility {
0039 public:
0040
0041 BinUtility()
0042 : m_binningData(),
0043 m_transform(Transform3::Identity()),
0044 m_itransform(Transform3::Identity()) {
0045 m_binningData.reserve(3);
0046 }
0047
0048
0049
0050
0051 explicit BinUtility(const Transform3& tForm)
0052 : m_binningData(), m_transform(tForm), m_itransform(tForm.inverse()) {
0053 m_binningData.reserve(3);
0054 }
0055
0056
0057
0058
0059
0060 explicit BinUtility(const BinningData& bData,
0061 const Transform3& tForm = Transform3::Identity())
0062 : m_binningData(), m_transform(tForm), m_itransform(tForm.inverse()) {
0063 m_binningData.reserve(3);
0064 m_binningData.push_back(bData);
0065 }
0066
0067
0068
0069
0070
0071
0072
0073
0074
0075 BinUtility(std::size_t bins, float min, float max, BinningOption opt = open,
0076 AxisDirection value = AxisDirection::AxisX,
0077 const Transform3& tForm = Transform3::Identity())
0078 : m_binningData(), m_transform(tForm), m_itransform(tForm.inverse()) {
0079 m_binningData.reserve(3);
0080 m_binningData.push_back(BinningData(opt, value, bins, min, max));
0081 }
0082
0083
0084
0085
0086
0087
0088
0089 BinUtility(std::vector<float>& bValues, BinningOption opt = open,
0090 AxisDirection value = AxisDirection::AxisPhi,
0091 const Transform3& tForm = Transform3::Identity())
0092 : m_binningData(), m_transform(tForm), m_itransform(tForm.inverse()) {
0093 m_binningData.reserve(3);
0094 m_binningData.push_back(BinningData(opt, value, bValues));
0095 }
0096
0097
0098
0099
0100 BinUtility(const BinUtility& sbu) = default;
0101
0102 BinUtility(BinUtility&& sbu) = default;
0103
0104
0105
0106
0107 BinUtility& operator=(const BinUtility& sbu) {
0108 if (this != &sbu) {
0109 m_binningData = sbu.m_binningData;
0110 m_transform = sbu.m_transform;
0111 m_itransform = sbu.m_itransform;
0112 }
0113 return (*this);
0114 }
0115
0116 BinUtility& operator=(BinUtility&&) = default;
0117
0118
0119
0120
0121 BinUtility& operator+=(const BinUtility& gbu) {
0122 const std::vector<BinningData>& bData = gbu.binningData();
0123
0124 m_transform = m_transform * gbu.transform();
0125 m_itransform = m_transform.inverse();
0126 if (m_binningData.size() + bData.size() > 3) {
0127 throw std::runtime_error{"BinUtility does not support dim > 3"};
0128 }
0129 m_binningData.insert(m_binningData.end(), bData.begin(), bData.end());
0130 return (*this);
0131 }
0132
0133
0134 ~BinUtility() = default;
0135
0136
0137 bool operator==(const BinUtility& other) const {
0138 return (m_transform.isApprox(other.m_transform) &&
0139 m_binningData == other.binningData());
0140 }
0141
0142
0143 const std::vector<BinningData>& binningData() const { return m_binningData; }
0144
0145
0146 std::size_t bins() const { return bins(0) * bins(1) * bins(2); }
0147
0148
0149
0150
0151
0152
0153
0154
0155 std::array<std::size_t, 3> binTriple(const Vector3& position) const {
0156
0157 const Vector3 bPosition = m_itransform * position;
0158
0159 std::size_t mdim = m_binningData.size();
0160
0161 std::size_t bin0 = m_binningData[0].searchGlobal(bPosition);
0162 std::size_t bin1 = mdim > 1 ? m_binningData[1].searchGlobal(bPosition) : 0;
0163 std::size_t bin2 = mdim > 2 ? m_binningData[2].searchGlobal(bPosition) : 0;
0164
0165 return {{bin0, bin1, bin2}};
0166 }
0167
0168
0169
0170
0171
0172
0173
0174 std::size_t bin(const Vector3& position, std::size_t ba = 0) const {
0175 if (ba >= m_binningData.size()) {
0176 return 0;
0177 }
0178 std::size_t bEval = m_binningData[ba].searchGlobal(m_itransform * position);
0179 return bEval;
0180 }
0181
0182
0183
0184
0185
0186
0187
0188
0189
0190
0191 int nextDirection(const Vector3& position, const Vector3& direction,
0192 std::size_t ba = 0) const {
0193 if (ba >= m_binningData.size()) {
0194 return 0;
0195 }
0196 return m_binningData[ba].nextDirection(position, direction);
0197 }
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209
0210 std::size_t bin(const Vector2& lposition, std::size_t ba = 0) const {
0211 if (ba >= m_binningData.size()) {
0212 return 0;
0213 }
0214 return m_binningData[ba].searchLocal(lposition);
0215 }
0216
0217
0218
0219
0220 bool inside(const Vector3& position) const {
0221
0222 const Vector3& bPosition = m_itransform * position;
0223
0224 for (auto& bData : m_binningData) {
0225 if (!(bData.inside(bPosition))) {
0226 return false;
0227 }
0228 }
0229
0230 return true;
0231 }
0232
0233
0234
0235 std::size_t dimensions() const { return m_binningData.size(); }
0236
0237
0238
0239
0240
0241
0242 std::size_t max(std::size_t ba = 0) const {
0243 if (ba >= m_binningData.size()) {
0244 return 0;
0245 }
0246 return (m_binningData[ba].bins() - 1);
0247 }
0248
0249
0250
0251
0252
0253
0254 std::size_t bins(std::size_t ba) const {
0255 if (ba >= m_binningData.size()) {
0256 return 1;
0257 }
0258 return (m_binningData[ba].bins());
0259 }
0260
0261
0262
0263
0264 const Transform3& transform() const { return m_transform; }
0265
0266
0267
0268
0269
0270
0271 AxisDirection binningValue(std::size_t ba = 0) const {
0272 if (ba >= m_binningData.size()) {
0273 throw std::runtime_error{"Dimension out of bounds"};
0274 }
0275 return (m_binningData[ba].binvalue);
0276 }
0277
0278
0279
0280
0281
0282 std::size_t serialize(const std::array<std::size_t, 3>& bin) const {
0283 std::size_t serializedBin = bin[0];
0284 if (m_binningData.size() == 2) {
0285 serializedBin += bin[1] * m_binningData[0].bins();
0286 } else if (m_binningData.size() == 3) {
0287 serializedBin +=
0288 (bin[1] * m_binningData[0].bins() * bin[2] * m_binningData[1].bins());
0289 }
0290 return serializedBin;
0291 }
0292
0293
0294
0295
0296
0297
0298
0299 std::ostream& toStream(std::ostream& sl,
0300 const std::string& indent = "") const {
0301 sl << indent << "BinUtility for " << m_binningData.size()
0302 << "- dimensional array:" << std::endl;
0303 for (auto [ibd, bd] : enumerate(m_binningData)) {
0304 sl << indent << "dimension : " << ibd << std::endl;
0305 sl << bd.toString(indent) << std::endl;
0306 }
0307 return sl;
0308 }
0309
0310
0311
0312
0313
0314
0315 std::string toString(const std::string& indent = "") const {
0316 std::stringstream ss;
0317 toStream(ss, indent);
0318 return ss.str();
0319 }
0320
0321
0322 friend std::ostream& operator<<(std::ostream& sl, const BinUtility& bgen) {
0323 return bgen.toStream(sl);
0324 }
0325
0326 private:
0327 std::vector<BinningData> m_binningData;
0328 Transform3 m_transform;
0329 Transform3 m_itransform;
0330 };
0331
0332 }