File indexing completed on 2025-08-05 08:10:20
0001
0002
0003
0004
0005
0006
0007
0008
0009 #include "Acts/Plugins/Podio//PodioUtil.hpp"
0010
0011 #include "Acts/Geometry/GeometryContext.hpp"
0012 #include "Acts/Geometry/GeometryIdentifier.hpp"
0013 #include "Acts/Plugins/Identification/Identifier.hpp"
0014 #include "Acts/Surfaces/AnnulusBounds.hpp"
0015 #include "Acts/Surfaces/ConeSurface.hpp"
0016 #include "Acts/Surfaces/ConvexPolygonBounds.hpp"
0017 #include "Acts/Surfaces/CylinderBounds.hpp"
0018 #include "Acts/Surfaces/CylinderSurface.hpp"
0019 #include "Acts/Surfaces/DiamondBounds.hpp"
0020 #include "Acts/Surfaces/DiscBounds.hpp"
0021 #include "Acts/Surfaces/DiscSurface.hpp"
0022 #include "Acts/Surfaces/DiscTrapezoidBounds.hpp"
0023 #include "Acts/Surfaces/EllipseBounds.hpp"
0024 #include "Acts/Surfaces/PerigeeSurface.hpp"
0025 #include "Acts/Surfaces/PlanarBounds.hpp"
0026 #include "Acts/Surfaces/PlaneSurface.hpp"
0027 #include "Acts/Surfaces/RadialBounds.hpp"
0028 #include "Acts/Surfaces/StrawSurface.hpp"
0029 #include "Acts/Surfaces/Surface.hpp"
0030 #include "Acts/Utilities/ThrowAssert.hpp"
0031 #include "Acts/Utilities/TypeList.hpp"
0032 #include "ActsPodioEdm/Surface.h"
0033
0034 #include <limits>
0035 #include <memory>
0036
0037 namespace Acts {
0038 namespace PodioUtil {
0039
0040 namespace {
0041 template <typename bounds_t>
0042 std::shared_ptr<const bounds_t> createBounds(
0043 const ActsPodioEdm::Surface& surface) {
0044 constexpr std::size_t S = bounds_t::eSize;
0045 throw_assert(surface.boundValuesSize == S,
0046 "Unexpected number of bound values");
0047
0048 std::array<double, S> values{};
0049 for (std::size_t i = 0; i < S; i++) {
0050 values.at(i) = surface.boundValues.at(i);
0051 }
0052 return std::make_shared<bounds_t>(values);
0053 }
0054 }
0055
0056 ActsPodioEdm::Surface convertSurfaceToPodio(const ConversionHelper& helper,
0057 const Acts::Surface& surface) {
0058 ActsPodioEdm::Surface result;
0059
0060 std::optional<Identifier> identifier = helper.surfaceToIdentifier(surface);
0061 if (identifier.has_value()) {
0062 result.identifier = identifier.value();
0063 } else {
0064 result.identifier = kNoIdentifier;
0065 assert(surface.associatedDetectorElement() == nullptr &&
0066 "Unidentified surface does not have detector element");
0067
0068 result.surfaceType = surface.type();
0069
0070 result.boundsType = surface.bounds().type();
0071 result.geometryId = surface.geometryId().value();
0072 auto values = surface.bounds().values();
0073
0074 if (values.size() > result.boundValues.size()) {
0075 throw std::runtime_error{"Too many bound values to store"};
0076 }
0077
0078 for (std::size_t i = 0; i < values.size(); i++) {
0079 result.boundValues.at(i) = values.at(i);
0080 }
0081 result.boundValuesSize = values.size();
0082
0083 Eigen::Map<ActsSquareMatrix<4>> trf{result.transform.data()};
0084
0085
0086
0087 Acts::GeometryContext gctx;
0088 trf = surface.transform(gctx).matrix();
0089 }
0090
0091 return result;
0092 }
0093
0094 std::shared_ptr<const Surface> convertSurfaceFromPodio(
0095 const ConversionHelper& helper, const ActsPodioEdm::Surface& surface) {
0096 if (surface.surfaceType == kNoSurface) {
0097 return nullptr;
0098 }
0099
0100 Eigen::Map<const ActsSquareMatrix<4>> mat{surface.transform.data()};
0101 Transform3 transform{mat};
0102
0103 using T = Surface::SurfaceType;
0104 using B = SurfaceBounds;
0105
0106 std::shared_ptr<const Surface> result;
0107
0108 if (const Surface* srf = helper.identifierToSurface(surface.identifier);
0109 srf != nullptr) {
0110 result = srf->getSharedPtr();
0111 }
0112
0113 if (result) {
0114 return result;
0115 }
0116
0117 switch (surface.surfaceType) {
0118 default:
0119 throw std::runtime_error{"Invalid surface type encountered"};
0120
0121 case T::Cone:
0122 throw_assert(surface.boundsType == B::eCone, "Unexpected bounds type");
0123 result = Acts::Surface::makeShared<ConeSurface>(
0124 transform, createBounds<ConeBounds>(surface));
0125 break;
0126
0127 case T::Cylinder:
0128 throw_assert(surface.boundsType == B::eCylinder,
0129 "Unexpected bounds type");
0130 result = Acts::Surface::makeShared<CylinderSurface>(
0131 transform, createBounds<CylinderBounds>(surface));
0132 break;
0133
0134 case T::Disc: {
0135 std::shared_ptr<const DiscBounds> dBounds;
0136 switch (surface.boundsType) {
0137 default:
0138 throw std::runtime_error{"Invalid bounds type encountered"};
0139
0140 case B::eDisc:
0141 dBounds = createBounds<RadialBounds>(surface);
0142 break;
0143
0144 case B::eAnnulus:
0145 dBounds = createBounds<AnnulusBounds>(surface);
0146 break;
0147
0148 case B::eDiscTrapezoid:
0149 dBounds = createBounds<DiscTrapezoidBounds>(surface);
0150 break;
0151 }
0152 result = Acts::Surface::makeShared<DiscSurface>(transform, dBounds);
0153 break;
0154 }
0155
0156 case T::Perigee:
0157 throw_assert(surface.boundsType == B::eBoundless,
0158 "Unexpected bounds type");
0159 result = Acts::Surface::makeShared<PerigeeSurface>(transform);
0160 break;
0161
0162 case T::Plane: {
0163 std::shared_ptr<const PlanarBounds> pBounds;
0164 switch (surface.boundsType) {
0165 default:
0166 throw std::runtime_error{"Invalid bounds type encountered"};
0167
0168 case B::eDiamond:
0169 pBounds = createBounds<DiamondBounds>(surface);
0170 break;
0171 case B::eEllipse:
0172 pBounds = createBounds<EllipseBounds>(surface);
0173 break;
0174 case B::eRectangle:
0175 pBounds = createBounds<RectangleBounds>(surface);
0176 break;
0177 case B::eConvexPolygon:
0178 template_switch_lambda<6, 32>(surface.boundValuesSize, [&](auto N) {
0179 constexpr std::size_t nValues = decltype(N)::value;
0180 constexpr std::size_t nVertices = nValues / 2;
0181 pBounds = createBounds<ConvexPolygonBounds<nVertices>>(surface);
0182 });
0183
0184 break;
0185 }
0186 assert(pBounds && "No PlanarBounds");
0187 result = Acts::Surface::makeShared<PlaneSurface>(transform, pBounds);
0188
0189 break;
0190 }
0191
0192 case T::Straw:
0193 throw_assert(surface.boundsType == B::eLine, "Unexpected bounds type");
0194 result = Acts::Surface::makeShared<StrawSurface>(
0195 transform, createBounds<LineBounds>(surface));
0196 break;
0197
0198 case T::Curvilinear:
0199 throw_assert(surface.boundsType == B::eBoundless,
0200 "Unexpected bounds type");
0201 result = Acts::Surface::makeShared<PlaneSurface>(transform);
0202 break;
0203 }
0204
0205 return result;
0206 }
0207
0208 }
0209 namespace podio_detail {
0210
0211 template <typename F, typename... Args>
0212 void apply(F&& f, TypeList<Args...> ) {
0213 f(Args{}...);
0214 }
0215
0216 void recoverDynamicColumns(
0217 const podio::Frame& frame, const std::string& stem,
0218 std::unordered_map<HashedString,
0219 std::unique_ptr<podio_detail::ConstDynamicColumnBase>>&
0220 dynamic) {
0221 using load_type = std::unique_ptr<podio_detail::DynamicColumnBase> (*)(
0222 const podio::CollectionBase*);
0223
0224
0225
0226 using types = TypeList<float, double, int8_t, int16_t, int32_t, int64_t,
0227 uint8_t, uint16_t, uint32_t, uint64_t>;
0228
0229 std::vector<std::string> available = frame.getAvailableCollections();
0230
0231 for (const auto& col : available) {
0232 std::string prefix = stem + "_extra__";
0233 std::size_t p = col.find(prefix);
0234 if (p == std::string::npos) {
0235 continue;
0236 }
0237 std::string dynName = col.substr(prefix.size());
0238 const podio::CollectionBase* coll = frame.get(col);
0239
0240 std::unique_ptr<podio_detail::ConstDynamicColumnBase> up;
0241
0242 apply(
0243 [&](auto... args) {
0244 auto inner = [&](auto arg) {
0245 if (up) {
0246 return;
0247 }
0248 using T = decltype(arg);
0249 const auto* dyn =
0250 dynamic_cast<const podio::UserDataCollection<T>*>(coll);
0251 if (dyn == nullptr) {
0252 return;
0253 }
0254 up = std::make_unique<podio_detail::ConstDynamicColumn<T>>(dynName,
0255 *dyn);
0256 };
0257
0258 ((inner(args)), ...);
0259 },
0260 types{});
0261
0262 if (!up) {
0263 throw std::runtime_error{"Dynamic column '" + dynName +
0264 "' is not of allowed type"};
0265 }
0266
0267 HashedString hashedKey = hashString(dynName);
0268 dynamic.insert({hashedKey, std::move(up)});
0269 }
0270 }
0271
0272 }
0273 }