Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-02-23 09:15:34

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