File indexing completed on 2025-01-18 09:10:46
0001
0002
0003
0004
0005
0006
0007
0008
0009 #pragma once
0010
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/Common.hpp"
0013 #include "Acts/Utilities/AxisDefinitions.hpp"
0014 #include "Acts/Utilities/BinUtility.hpp"
0015
0016 #include <sstream>
0017 #include <stdexcept>
0018 #include <string>
0019 #include <vector>
0020
0021 namespace Acts::Experimental {
0022
0023
0024
0025
0026
0027
0028 struct ProtoBinning {
0029
0030 AxisDirection axisDir;
0031
0032 Acts::AxisType axisType = Acts::AxisType::Equidistant;
0033
0034 Acts::AxisBoundaryType boundaryType = Acts::AxisBoundaryType::Bound;
0035
0036 std::vector<double> edges = {};
0037
0038 std::size_t expansion = 0u;
0039
0040 bool autorange = false;
0041
0042
0043
0044
0045
0046
0047
0048 ProtoBinning(AxisDirection aDir, Acts::AxisBoundaryType bType,
0049 const std::vector<double>& e, std::size_t exp = 0u)
0050 : axisDir(aDir),
0051 axisType(Acts::AxisType::Variable),
0052 boundaryType(bType),
0053 edges(e),
0054 expansion(exp) {
0055 if (edges.size() < 2u) {
0056 throw std::invalid_argument(
0057 "ProtoBinning: Invalid binning, at least two edges are needed.");
0058 }
0059 }
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069 ProtoBinning(AxisDirection aDir, Acts::AxisBoundaryType bType, double minE,
0070 double maxE, std::size_t nbins, std::size_t exp = 0u)
0071 : axisDir(aDir), boundaryType(bType), expansion(exp) {
0072 if (minE >= maxE) {
0073 std::string msg = "ProtoBinning: Invalid axis range for direction '";
0074 msg += axisDirectionName(axisDir);
0075 msg += "', min edge (" + std::to_string(minE) + ") ";
0076 msg += " needs to be smaller than max edge (";
0077 msg += std::to_string(maxE) + ").";
0078 throw std::invalid_argument(msg);
0079 }
0080 if (nbins < 1u) {
0081 throw std::invalid_argument(
0082 "ProtoBinning: Invalid binning, at least one bin is needed.");
0083 }
0084
0085 double stepE = (maxE - minE) / nbins;
0086 edges.reserve(nbins + 1);
0087 for (std::size_t i = 0; i <= nbins; i++) {
0088 edges.push_back(minE + i * stepE);
0089 }
0090 }
0091
0092
0093
0094
0095
0096
0097
0098
0099
0100
0101
0102 ProtoBinning(AxisDirection aDir, Acts::AxisBoundaryType bType,
0103 std::size_t nbins, std::size_t exp = 0u)
0104 : axisDir(aDir),
0105 boundaryType(bType),
0106 edges(nbins + 1, 0.),
0107 expansion(exp),
0108 autorange(true) {}
0109
0110
0111 std::size_t bins() const { return edges.size() - 1u; }
0112
0113
0114 std::string toString() const {
0115 std::stringstream ss;
0116 ss << "ProtoBinning: " << bins() << " bins in "
0117 << axisDirectionName(axisDir);
0118 ss << (axisType == Acts::AxisType::Variable ? ", variable "
0119 : ", equidistant ");
0120 if (!autorange) {
0121 ss << "within [" << edges.front() << ", " << edges.back() << "] ";
0122 } else {
0123 ss << "within automatic range";
0124 }
0125 return ss.str();
0126 }
0127 };
0128
0129
0130 struct BinningDescription {
0131
0132
0133
0134 static BinningDescription fromBinUtility(const BinUtility& binUtility) {
0135 BinningDescription bDesc;
0136 for (const auto& bData : binUtility.binningData()) {
0137
0138 Acts::AxisBoundaryType boundaryType =
0139 bData.option == open ? Acts::AxisBoundaryType::Bound
0140 : Acts::AxisBoundaryType::Closed;
0141 std::vector<double> edges;
0142 if (bData.type == equidistant) {
0143 bDesc.binning.push_back(ProtoBinning(bData.binvalue, boundaryType,
0144 bData.min, bData.max, bData.bins(),
0145 0u));
0146
0147 } else {
0148 std::for_each(bData.boundaries().begin(), bData.boundaries().end(),
0149 [&](double edge) { edges.push_back(edge); });
0150 bDesc.binning.push_back(
0151 ProtoBinning(bData.binvalue, boundaryType, edges, 0u));
0152 }
0153 }
0154 return bDesc;
0155 }
0156
0157
0158
0159 BinUtility toBinUtility() const {
0160 BinUtility binUtility;
0161 for (const auto& b : binning) {
0162 Acts::BinningOption bOption =
0163 b.boundaryType == Acts::AxisBoundaryType::Bound ? Acts::open
0164 : Acts::closed;
0165 if (b.axisType == Acts::AxisType::Equidistant) {
0166 binUtility += BinUtility(b.bins(), b.edges.front(), b.edges.back(),
0167 bOption, b.axisDir);
0168 } else {
0169 std::vector<float> edges;
0170 std::for_each(b.edges.begin(), b.edges.end(),
0171 [&](double edge) { edges.push_back(edge); });
0172 binUtility += BinUtility(edges, bOption, b.axisDir);
0173 }
0174 }
0175 return binUtility;
0176 }
0177
0178
0179 std::vector<ProtoBinning> binning;
0180
0181
0182 std::string toString() const {
0183 std::stringstream ss;
0184 ss << "BinningDescription: " << binning.size() << "D" << std::endl;
0185 for (const auto& b : binning) {
0186 ss << " " << b.toString() << std::endl;
0187 }
0188 return ss.str();
0189 }
0190 };
0191
0192 }