Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-18 09:27:38

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 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 https://mozilla.org/MPL/2.0/.
0008 
0009 #include "ActsPlugins/GeoModel/detail/GeoModelExtentHelper.hpp"
0010 
0011 #include "Acts/Utilities/BinningData.hpp"
0012 #include "Acts/Utilities/Enumerate.hpp"
0013 #include "ActsPlugins/GeoModel/detail/GeoModelBinningHelper.hpp"
0014 
0015 #include <boost/algorithm/string.hpp>
0016 
0017 using namespace Acts;
0018 
0019 std::vector<AxisDirection>
0020 ActsPlugins::detail::GeoModelExentHelper::readBoundsConstaints(
0021     const std::string& boundsEntry, const std::string& ctype) {
0022   std::vector<std::string> boundsEntrySplit;
0023   boost::split(boundsEntrySplit, boundsEntry, boost::is_any_of(","));
0024   if (boundsEntrySplit.size() < 2u) {
0025     throw std::invalid_argument(
0026         "GeoModelBlueprintCreater: Bounds entry has to have at least 2 "
0027         "entries (type, values)");
0028   }
0029   std::set<AxisDirection> constraints;
0030   // Switch on the bounds type
0031   if (boundsEntrySplit[0u] == "cyl") {
0032     // Capture the values
0033     std::vector<std::string> valuesEntry = {boundsEntrySplit.begin() + 1,
0034                                             boundsEntrySplit.end()};
0035     if (valuesEntry.size() < 4u) {
0036       throw std::invalid_argument(
0037           "GeoModelBlueprintCreater: Cylinder bounds entry has to have at "
0038           "least 4 entries (rmin, rmax, zmin, zmax)");
0039     }
0040     // Raw database values to extent entries
0041     constexpr std::array<AxisDirection, 6u> bvCyl = {
0042         AxisDirection::AxisR, AxisDirection::AxisR,   AxisDirection::AxisZ,
0043         AxisDirection::AxisZ, AxisDirection::AxisPhi, AxisDirection::AxisPhi};
0044 
0045     for (auto [iv, value] : enumerate(valuesEntry)) {
0046       if (value == ctype || value[0u] == ctype[0u]) {
0047         constraints.insert(bvCyl.at(iv));
0048       }
0049     }
0050   }
0051   return {constraints.begin(), constraints.end()};
0052 }
0053 
0054 std::vector<AxisDirection>
0055 ActsPlugins::detail::GeoModelExentHelper::readBinningConstraints(
0056     const std::vector<std::string>& binningEntry) {
0057   std::set<AxisDirection> constraints;
0058   // Loop over the single binning Entries
0059   for (const auto& sbe : binningEntry) {
0060     if (sbe.empty()) {
0061       continue;
0062     } else if (sbe.size() > 2u && sbe.substr(0, 3u) == "exp") {
0063       // Skip expansion entries
0064       continue;
0065     }
0066     std::vector<std::string> sbTokens;
0067     boost::split(sbTokens, sbe, boost::is_any_of(","));
0068     AxisDirection bv =
0069         detail::GeoModelBinningHelper::toAxisDirection(sbTokens[0]);
0070     if (sbTokens.size() > 1u) {
0071       std::vector<std::string> valueTokens = {sbTokens.begin() + 1,
0072                                               sbTokens.end()};
0073       if (!valueTokens.empty() && valueTokens[0] == "bound") {
0074         constraints.insert(bv);
0075       }
0076     }
0077   }
0078 
0079   return {constraints.begin(), constraints.end()};
0080 }
0081 
0082 std::tuple<VolumeBounds::BoundsType, Extent>
0083 ActsPlugins::detail::GeoModelExentHelper::extentFromTable(
0084     const std::vector<std::string>& boundsEntrySplit,
0085     const Extent& externalExtent, const Extent& internalExtent,
0086     bool roundInternalExtent) {
0087   // Check the bounds entry
0088   if (boundsEntrySplit.size() < 2u) {
0089     throw std::invalid_argument(
0090         "GeoModelBlueprintCreater: Bounds entry has to have at least 2 "
0091         "entries (type, values)");
0092   }
0093 
0094   // Start with the mother extent
0095   // -> and shrink it to size
0096   VolumeBounds::BoundsType boundsType = VolumeBounds::BoundsType::eOther;
0097   Extent extent;
0098   // Switch on the bounds type
0099   if (boundsEntrySplit[0u] == "cyl") {
0100     // Set the bounds type
0101     boundsType = VolumeBounds::BoundsType::eCylinder;
0102     // Capture the values
0103     std::vector<std::string> valuesEntry = {boundsEntrySplit.begin() + 1,
0104                                             boundsEntrySplit.end()};
0105     if (valuesEntry.size() < 4u) {
0106       throw std::invalid_argument(
0107           "GeoModelBlueprintCreater: Cylinder bounds entry has to have at "
0108           "least 4 entries (rmin, rmax, zmin, zmax)");
0109     }
0110     // Raw database values to extent entries
0111     constexpr std::array<AxisDirection, 6u> bvCyl = {
0112         AxisDirection::AxisR, AxisDirection::AxisR,   AxisDirection::AxisZ,
0113         AxisDirection::AxisZ, AxisDirection::AxisPhi, AxisDirection::AxisPhi};
0114     for (auto [iv, value] : enumerate(valuesEntry)) {
0115       // Get the binning value
0116       AxisDirection bValue = bvCyl.at(iv);
0117       double val = std::numeric_limits<double>::max();
0118       bool isMin = (iv % 2 == 0);
0119       // Case "e" : external extent
0120       if (value == "e") {
0121         // External parameters do not constrain it
0122         if (!externalExtent.constrains(bValue)) {
0123           throw std::invalid_argument(
0124               "GeoModelExtentHelper: External extent does not constrain. ");
0125         }
0126         val = isMin ? externalExtent.min(bValue) : externalExtent.max(bValue);
0127       } else if (value == "i" || value[0u] == 'i') {
0128         // Add the envelope
0129         double envelope = 0.;
0130         if (value.size() > 2u) {
0131           std::vector<std::string> valEntry;
0132           boost::split(valEntry, value, boost::is_any_of("+"));
0133           envelope = std::stod(valEntry[1]);
0134         }
0135 
0136         // Internals do not constrain it
0137         if (!internalExtent.constrains(bValue)) {
0138           throw std::invalid_argument(
0139               "GeoModelExtentHelper: Internals do not constrain.");
0140         }
0141         val = isMin ? internalExtent.min(bValue) - envelope
0142                     : internalExtent.max(bValue) + envelope;
0143         // Case "i" : Inherited from mother
0144       } else {
0145         val = std::stod(value);
0146       }
0147       // Case value is a number -> shrink mother to it or set it
0148       if (isMin) {
0149         extent.setMin(bValue, val);
0150       } else {
0151         extent.setMax(bValue, val);
0152       }
0153     }
0154   }
0155   // Round up / down if configured
0156   if (roundInternalExtent) {
0157     for (const auto& bv : allAxisDirections()) {
0158       if (internalExtent.constrains(bv)) {
0159         extent.setMin(bv, std::floor(extent.min(bv)));
0160         extent.setMax(bv, std::ceil(extent.max(bv)));
0161       }
0162     }
0163   }
0164 
0165   return {boundsType, extent};
0166 }