File indexing completed on 2025-02-23 09:15:34
0001
0002
0003
0004
0005
0006
0007
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
0029 if (boundsEntrySplit[0u] == "cyl") {
0030
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
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
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
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
0090
0091 VolumeBounds::BoundsType boundsType = VolumeBounds::BoundsType::eOther;
0092 Extent extent;
0093
0094 if (boundsEntrySplit[0u] == "cyl") {
0095
0096 boundsType = VolumeBounds::BoundsType::eCylinder;
0097
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
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
0111 AxisDirection bValue = bvCyl.at(iv);
0112 double val = std::numeric_limits<double>::max();
0113 bool isMin = (iv % 2 == 0);
0114
0115 if (value == "e") {
0116
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
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
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
0139 } else {
0140 val = std::stod(value);
0141 }
0142
0143 if (isMin) {
0144 extent.setMin(bValue, val);
0145 } else {
0146 extent.setMax(bValue, val);
0147 }
0148 }
0149 }
0150
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 }