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