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/Surfaces/CylinderBounds.hpp"
0013 #include "Acts/Surfaces/RadialBounds.hpp"
0014 #include "Acts/Surfaces/RectangleBounds.hpp"
0015 #include "Acts/Surfaces/Surface.hpp"
0016 #include "Acts/Surfaces/TrapezoidBounds.hpp"
0017 #include "Acts/Utilities/AxisDefinitions.hpp"
0018 #include "Acts/Utilities/BinUtility.hpp"
0019
0020 #include <stdexcept>
0021
0022 namespace Acts {
0023
0024
0025
0026
0027
0028
0029
0030
0031 static inline BinUtility adjustBinUtility(const BinUtility& bu,
0032 const RadialBounds& rBounds,
0033 const Transform3& transform) {
0034
0035 BinUtility uBinUtil(transform);
0036
0037
0038 double minR = rBounds.get(RadialBounds::eMinR);
0039 double maxR = rBounds.get(RadialBounds::eMaxR);
0040 double minPhi = rBounds.get(RadialBounds::eAveragePhi) -
0041 rBounds.get(RadialBounds::eHalfPhiSector);
0042 double maxPhi = rBounds.get(RadialBounds::eAveragePhi) +
0043 rBounds.get(RadialBounds::eHalfPhiSector);
0044
0045 const std::vector<BinningData>& bData = bu.binningData();
0046
0047 for (auto& bd : bData) {
0048
0049 AxisDirection bval = bd.binvalue;
0050
0051
0052
0053 if (bd.type == arbitrary) {
0054 throw std::invalid_argument("Arbitrary binning can not be adjusted.");
0055 } else if (bval != AxisDirection::AxisR && bval != AxisDirection::AxisPhi) {
0056 throw std::invalid_argument("Disc binning must be: phi, r");
0057 }
0058 float min = 0., max = 0.;
0059
0060 if (bval == AxisDirection::AxisPhi) {
0061 min = minPhi;
0062 max = maxPhi;
0063 } else {
0064 min = minR;
0065 max = maxR;
0066 }
0067
0068 BinningData uBinData(bd.option, bval, bd.bins(), min, max);
0069 uBinUtil += BinUtility(uBinData);
0070 }
0071 return uBinUtil;
0072 }
0073
0074
0075
0076
0077
0078
0079
0080
0081 static inline BinUtility adjustBinUtility(const BinUtility& bu,
0082 const CylinderBounds& cBounds,
0083 const Transform3& transform) {
0084
0085 BinUtility uBinUtil(transform);
0086
0087
0088 double cR = cBounds.get(CylinderBounds::eR);
0089 double cHz = cBounds.get(CylinderBounds::eHalfLengthZ);
0090 double avgPhi = cBounds.get(CylinderBounds::eAveragePhi);
0091 double halfPhi = cBounds.get(CylinderBounds::eHalfPhiSector);
0092 double minPhi = avgPhi - halfPhi;
0093 double maxPhi = avgPhi + halfPhi;
0094
0095
0096 const std::vector<BinningData>& bData = bu.binningData();
0097
0098 for (auto& bd : bData) {
0099
0100 AxisDirection bval = bd.binvalue;
0101
0102
0103
0104 if (bd.type == arbitrary) {
0105 throw std::invalid_argument("Arbitrary binning can not be adjusted.");
0106 } else if (bval != AxisDirection::AxisRPhi &&
0107 bval != AxisDirection::AxisPhi && bval != AxisDirection::AxisZ) {
0108 throw std::invalid_argument("Cylinder binning must be: rphi, phi, z");
0109 }
0110 float min = 0., max = 0.;
0111
0112 if (bval == AxisDirection::AxisPhi) {
0113 min = minPhi;
0114 max = maxPhi;
0115 } else if (bval == AxisDirection::AxisRPhi) {
0116 min = cR * minPhi;
0117 max = cR * maxPhi;
0118 } else {
0119 min = -cHz;
0120 max = cHz;
0121 }
0122
0123 BinningData uBinData(bd.option, bval, bd.bins(), min, max);
0124 uBinUtil += BinUtility(uBinData);
0125 }
0126 return uBinUtil;
0127 }
0128
0129
0130
0131
0132
0133
0134
0135
0136 static inline BinUtility adjustBinUtility(const BinUtility& bu,
0137 const RectangleBounds& pBounds,
0138 const Transform3& transform) {
0139
0140 BinUtility uBinUtil(transform);
0141
0142
0143 double minX = pBounds.get(RectangleBounds::eMinX);
0144 double minY = pBounds.get(RectangleBounds::eMinY);
0145 double maxX = pBounds.get(RectangleBounds::eMaxX);
0146 double maxY = pBounds.get(RectangleBounds::eMaxY);
0147
0148
0149 const std::vector<BinningData>& bData = bu.binningData();
0150
0151 for (auto& bd : bData) {
0152
0153 AxisDirection bval = bd.binvalue;
0154
0155
0156
0157 if (bd.type == arbitrary) {
0158 throw std::invalid_argument("Arbitrary binning can not be adjusted.");
0159 } else if (bval != AxisDirection::AxisX && bval != AxisDirection::AxisY) {
0160 throw std::invalid_argument("Rectangle binning must be: x, y. ");
0161 }
0162 float min = 0., max = 0.;
0163
0164 if (bval == AxisDirection::AxisX) {
0165 min = minX;
0166 max = maxX;
0167 } else {
0168 min = minY;
0169 max = maxY;
0170 }
0171
0172 BinningData uBinData(bd.option, bval, bd.bins(), min, max);
0173 uBinUtil += BinUtility(uBinData);
0174 }
0175
0176 return uBinUtil;
0177 }
0178
0179
0180
0181
0182
0183
0184
0185
0186 static inline BinUtility adjustBinUtility(const BinUtility& bu,
0187 const TrapezoidBounds& pBounds,
0188 const Transform3& transform) {
0189
0190 BinUtility uBinUtil(transform);
0191
0192
0193
0194 double halfX = std::max(pBounds.get(Acts::TrapezoidBounds::eHalfLengthXnegY),
0195 pBounds.get(Acts::TrapezoidBounds::eHalfLengthXposY));
0196 double halfY = pBounds.get(Acts::TrapezoidBounds::eHalfLengthY);
0197
0198
0199 const std::vector<BinningData>& bData = bu.binningData();
0200
0201 for (auto& bd : bData) {
0202
0203 AxisDirection bval = bd.binvalue;
0204
0205
0206
0207 if (bd.type == arbitrary) {
0208 throw std::invalid_argument("Arbitrary binning can not be adjusted.");
0209 } else if (bval != AxisDirection::AxisX && bval != AxisDirection::AxisY) {
0210 throw std::invalid_argument("Rectangle binning must be: x, y. ");
0211 }
0212 float min = 0., max = 0.;
0213
0214 if (bval == AxisDirection::AxisX) {
0215 min = -1 * halfX;
0216 max = halfX;
0217 } else {
0218 min = -1 * halfY;
0219 max = halfY;
0220 }
0221
0222 BinningData uBinData(bd.option, bval, bd.bins(), min, max);
0223 uBinUtil += BinUtility(uBinData);
0224 }
0225
0226 return uBinUtil;
0227 }
0228
0229
0230
0231
0232
0233
0234
0235
0236 static inline BinUtility adjustBinUtility(const BinUtility& bu,
0237 const Surface& surface,
0238 const GeometryContext& gctx) {
0239 if (auto b = dynamic_cast<const CylinderBounds*>(&(surface.bounds()));
0240 b != nullptr) {
0241 return adjustBinUtility(bu, *b, surface.transform(gctx));
0242 }
0243 if (auto b = dynamic_cast<const RadialBounds*>(&(surface.bounds()));
0244 b != nullptr) {
0245 return adjustBinUtility(bu, *b, surface.transform(gctx));
0246 }
0247 if (surface.type() == Surface::Plane) {
0248 if (auto b = dynamic_cast<const RectangleBounds*>(&(surface.bounds()));
0249 b != nullptr) {
0250 return adjustBinUtility(bu, *b, surface.transform(gctx));
0251 }
0252 if (auto b = dynamic_cast<const TrapezoidBounds*>(&(surface.bounds()));
0253 b != nullptr) {
0254 return adjustBinUtility(bu, *b, surface.transform(gctx));
0255 }
0256 }
0257
0258 std::stringstream ss;
0259 ss << surface.toStream({});
0260 throw std::invalid_argument(
0261 "Bin adjustment not implemented for this surface yet:\n" + ss.str());
0262 }
0263
0264 }