Back to home page

EIC code displayed by LXR

 
 

    


Warning, file /include/Acts/Detector/ProtoBinning.hpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 // This file is part of the Acts project.
0002 //
0003 // Copyright (C) 2023 CERN for the benefit of the Acts project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at http://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include "Acts/Definitions/Algebra.hpp"
0012 #include "Acts/Definitions/Common.hpp"
0013 #include "Acts/Utilities/BinUtility.hpp"
0014 #include "Acts/Utilities/BinningType.hpp"
0015 #include "Acts/Utilities/detail/AxisFwd.hpp"
0016 
0017 #include <sstream>
0018 #include <stdexcept>
0019 #include <string>
0020 #include <vector>
0021 
0022 namespace Acts::Experimental {
0023 
0024 /// @brief  Simple helper class to define a binning structure
0025 ///
0026 /// @note no checks are performed on the consistency, this is
0027 /// only for convenience that the binning can be defined and then
0028 /// translated into concrete axis types
0029 struct ProtoBinning {
0030   /// The binning value of this
0031   BinningValue binValue = BinningValue::binValues;
0032   /// The axis type: equidistant or variable
0033   Acts::detail::AxisType axisType = Acts::detail::AxisType::Equidistant;
0034   /// The axis boundary type: Open, Bound or Closed
0035   Acts::detail::AxisBoundaryType boundaryType =
0036       Acts::detail::AxisBoundaryType::Bound;
0037   /// The binning edges
0038   std::vector<ActsScalar> edges = {};
0039   /// An expansion for the filling (in bins)
0040   std::size_t expansion = 0u;
0041   /// Indication if this is an auto-range binning
0042   bool autorange = false;
0043 
0044   /// Convenience constructors - for variable binning
0045   ///
0046   /// @param bValue the value/cast in which this is binned
0047   /// @param bType the axis boundary type
0048   /// @param e the bin edges (variable binning)
0049   /// @param exp the expansion (in bins)
0050   ProtoBinning(BinningValue bValue, Acts::detail::AxisBoundaryType bType,
0051                const std::vector<ActsScalar>& e, std::size_t exp = 0u)
0052       : binValue(bValue),
0053         axisType(Acts::detail::AxisType::Variable),
0054         boundaryType(bType),
0055         edges(e),
0056         expansion(exp) {
0057     if (edges.size() < 2u) {
0058       throw std::invalid_argument(
0059           "ProtoBinning: Invalid binning, at least two edges are needed.");
0060     }
0061   }
0062 
0063   /// Convenience constructors - for equidistant binning
0064   ///
0065   /// @param bValue the value/cast in which this is binned
0066   /// @param bType the axis boundary type
0067   /// @param minE the lowest edge of the binning
0068   /// @param maxE the highest edge of the binning
0069   /// @param nbins the number of bins
0070   /// @param exp the expansion (in bins)
0071   ProtoBinning(BinningValue bValue, Acts::detail::AxisBoundaryType bType,
0072                ActsScalar minE, ActsScalar maxE, std::size_t nbins,
0073                std::size_t exp = 0u)
0074       : binValue(bValue), boundaryType(bType), expansion(exp) {
0075     if (minE >= maxE) {
0076       std::string msg = "ProtoBinning: Invalid binning for value '";
0077       msg += binningValueNames()[bValue];
0078       msg += "', min edge (" + std::to_string(minE) + ") ";
0079       msg += " needs to be smaller than max edge (";
0080       msg += std::to_string(maxE) + ").";
0081       throw std::invalid_argument(msg);
0082     }
0083     if (nbins < 1u) {
0084       throw std::invalid_argument(
0085           "ProtoBinning: Invalid binning, at least one bin is needed.");
0086     }
0087 
0088     ActsScalar stepE = (maxE - minE) / nbins;
0089     edges.reserve(nbins + 1);
0090     for (std::size_t i = 0; i <= nbins; i++) {
0091       edges.push_back(minE + i * stepE);
0092     }
0093   }
0094 
0095   /// Placeholder constructors - for equidistant binning
0096   ///
0097   /// @note this is designed to give a binning prescription
0098   /// when the actual extent is not yet evaluated, only works
0099   /// for equidistant binning obviously
0100   ///
0101   /// @param bValue the value/cast in which this is binned
0102   /// @param bType the axis boundary type
0103   /// @param nbins the number of bins
0104   /// @param exp the expansion (in bins)
0105   ProtoBinning(BinningValue bValue, Acts::detail::AxisBoundaryType bType,
0106                std::size_t nbins, std::size_t exp = 0u)
0107       : binValue(bValue),
0108         boundaryType(bType),
0109         edges(nbins + 1, 0.),
0110         expansion(exp),
0111         autorange(true) {}
0112 
0113   // Return the number of bins
0114   std::size_t bins() const { return edges.size() - 1u; }
0115 
0116   // Screen output
0117   std::string toString() const {
0118     std::stringstream ss;
0119     ss << "ProtoBinning: " << bins() << " bins in "
0120        << binningValueNames()[binValue];
0121     ss << (axisType == Acts::detail::AxisType::Variable ? ", variable "
0122                                                         : ", equidistant ");
0123     if (!autorange) {
0124       ss << "within [" << edges.front() << ", " << edges.back() << "] ";
0125     } else {
0126       ss << "within automatic range";
0127     }
0128     return ss.str();
0129   }
0130 };
0131 
0132 /// @brief A binning description, it helps for screen output
0133 struct BinningDescription {
0134   /// Convert the binning description into a bin utility
0135   ///
0136   /// @param binUtility the bin utility to be converted into a BinningDescription
0137   static BinningDescription fromBinUtility(const BinUtility& binUtility) {
0138     BinningDescription bDesc;
0139     for (const auto& bData : binUtility.binningData()) {
0140       // One proto binning per binning data
0141       Acts::detail::AxisBoundaryType boundaryType =
0142           bData.option == open ? Acts::detail::AxisBoundaryType::Bound
0143                                : Acts::detail::AxisBoundaryType::Closed;
0144       std::vector<ActsScalar> edges;
0145       if (bData.type == equidistant) {
0146         bDesc.binning.push_back(ProtoBinning(bData.binvalue, boundaryType,
0147                                              bData.min, bData.max, bData.bins(),
0148                                              0u));
0149 
0150       } else {
0151         std::for_each(bData.boundaries().begin(), bData.boundaries().end(),
0152                       [&](ActsScalar edge) { edges.push_back(edge); });
0153         bDesc.binning.push_back(
0154             ProtoBinning(bData.binvalue, boundaryType, edges, 0u));
0155       }
0156     }
0157     return bDesc;
0158   }
0159 
0160   /// Convert to a BinUtility - only basic types are supported
0161   ///
0162   BinUtility toBinUtility() const {
0163     BinUtility binUtility;
0164     for (const auto& b : binning) {
0165       Acts::BinningOption bOption =
0166           b.boundaryType == Acts::detail::AxisBoundaryType::Bound
0167               ? Acts::open
0168               : Acts::closed;
0169       if (b.axisType == Acts::detail::AxisType::Equidistant) {
0170         binUtility += BinUtility(b.bins(), b.edges.front(), b.edges.back(),
0171                                  bOption, b.binValue);
0172       } else {
0173         std::vector<float> edges;
0174         std::for_each(b.edges.begin(), b.edges.end(),
0175                       [&](ActsScalar edge) { edges.push_back(edge); });
0176         binUtility += BinUtility(edges, bOption, b.binValue);
0177       }
0178     }
0179     return binUtility;
0180   }
0181 
0182   /// The contained binnings
0183   std::vector<ProtoBinning> binning;
0184 
0185   // Screen output
0186   std::string toString() const {
0187     std::stringstream ss;
0188     ss << "BinningDescription: " << binning.size() << "D" << std::endl;
0189     for (const auto& b : binning) {
0190       ss << "  " << b.toString() << std::endl;
0191     }
0192     return ss.str();
0193   }
0194 };
0195 
0196 }  // namespace Acts::Experimental