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