File indexing completed on 2025-12-18 09:27:38
0001
0002
0003
0004
0005
0006
0007
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
0031 if (boundsEntrySplit[0u] == "cyl") {
0032
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
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
0059 for (const auto& sbe : binningEntry) {
0060 if (sbe.empty()) {
0061 continue;
0062 } else if (sbe.size() > 2u && sbe.substr(0, 3u) == "exp") {
0063
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
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
0095
0096 VolumeBounds::BoundsType boundsType = VolumeBounds::BoundsType::eOther;
0097 Extent extent;
0098
0099 if (boundsEntrySplit[0u] == "cyl") {
0100
0101 boundsType = VolumeBounds::BoundsType::eCylinder;
0102
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
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
0116 AxisDirection bValue = bvCyl.at(iv);
0117 double val = std::numeric_limits<double>::max();
0118 bool isMin = (iv % 2 == 0);
0119
0120 if (value == "e") {
0121
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
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
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
0144 } else {
0145 val = std::stod(value);
0146 }
0147
0148 if (isMin) {
0149 extent.setMin(bValue, val);
0150 } else {
0151 extent.setMax(bValue, val);
0152 }
0153 }
0154 }
0155
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 }