Skip to content

Commit

Permalink
refactor: Centralize PODIO dynamic columns recovery and use typelist (#…
Browse files Browse the repository at this point in the history
…2750)

This makes sense for code deduplication, and after #2656 was merged.
  • Loading branch information
paulgessinger authored Dec 6, 2023
1 parent fcbab62 commit 8c2fed8
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 93 deletions.
43 changes: 1 addition & 42 deletions Plugins/Podio/include/Acts/Plugins/Podio/PodioTrackContainer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -289,48 +289,7 @@ class ConstPodioTrackContainer : public PodioTrackContainerBase {

populateSurfaceBuffer(m_helper, *m_collection, m_surfaces);

// let's find dynamic columns
using types =
std::tuple<int32_t, int64_t, uint32_t, uint64_t, float, double>;

for (const auto& col : available) {
std::string prefix = tracksKey + "_extra__";
std::size_t p = col.find(prefix);
if (p == std::string::npos) {
continue;
}
std::string dynName = col.substr(prefix.size());
const podio::CollectionBase* coll = frame.get(col);

std::unique_ptr<podio_detail::ConstDynamicColumnBase> up;

std::apply(
[&](auto... args) {
auto inner = [&](auto arg) {
if (up) {
return;
}
using T = decltype(arg);
const auto* dyn =
dynamic_cast<const podio::UserDataCollection<T>*>(coll);
if (dyn == nullptr) {
return;
}
up = std::make_unique<podio_detail::ConstDynamicColumn<T>>(
dynName, *dyn);
};

((inner(args)), ...);
},
types{});

if (!up) {
throw std::runtime_error{"Dynamic column '" + dynName +
"' is not of allowed type"};
}

m_dynamic.insert({hashString(dynName), std::move(up)});
}
podio_detail::recoverDynamicColumns(frame, tracksKey, m_dynamic);
}

std::any component_impl(HashedString key, IndexType itrack) const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -236,52 +236,7 @@ class ConstPodioTrackStateContainer final

populateSurfaceBuffer(m_helper, *m_collection, m_surfaces);

// let's find dynamic columns

using load_type = std::unique_ptr<podio_detail::DynamicColumnBase> (*)(
const podio::CollectionBase*);

using types =
std::tuple<int32_t, int64_t, uint32_t, uint64_t, float, double>;

for (const auto& col : available) {
std::string prefix = trackStatesKey + "_extra__";
std::size_t p = col.find(prefix);
if (p == std::string::npos) {
continue;
}
std::string dynName = col.substr(prefix.size());
const podio::CollectionBase* coll = frame.get(col);

std::unique_ptr<podio_detail::ConstDynamicColumnBase> up;

std::apply(
[&](auto... args) {
auto inner = [&](auto arg) {
if (up) {
return;
}
using T = decltype(arg);
const auto* dyn =
dynamic_cast<const podio::UserDataCollection<T>*>(coll);
if (dyn == nullptr) {
return;
}
up = std::make_unique<podio_detail::ConstDynamicColumn<T>>(
dynName, *dyn);
};

((inner(args)), ...);
},
types{});

if (!up) {
throw std::runtime_error{"Dynamic column '" + dynName +
"' is not of allowed type"};
}

m_dynamic.insert({hashString(dynName), std::move(up)});
}
podio_detail::recoverDynamicColumns(frame, trackStatesKey, m_dynamic);
}

private:
Expand Down
21 changes: 18 additions & 3 deletions Plugins/Podio/include/Acts/Plugins/Podio/PodioUtil.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,16 +11,21 @@
#include "Acts/EventData/SourceLink.hpp"
#include "Acts/Geometry/GeometryIdentifier.hpp"
#include "Acts/Geometry/TrackingGeometry.hpp"
#include "Acts/Plugins/Podio/PodioDynamicColumns.hpp"
#include "Acts/Utilities/HashedString.hpp"
#include "Acts/Utilities/Helpers.hpp"

#include <limits>
#include <memory>

#include <podio/Frame.h>

namespace ActsPodioEdm {
class Surface;
}

namespace Acts::PodioUtil {
namespace Acts {
namespace PodioUtil {

using Identifier = uint64_t;
constexpr Identifier kNoIdentifier = std::numeric_limits<Identifier>::max();
Expand All @@ -42,5 +47,15 @@ std::shared_ptr<const Surface> convertSurfaceFromPodio(

ActsPodioEdm::Surface convertSurfaceToPodio(const ConversionHelper& helper,
const Acts::Surface& surface);

} // namespace Acts::PodioUtil
} // namespace PodioUtil

namespace podio_detail {
/// This is used by both the track and track state container, so the
/// implementation is shared here
void recoverDynamicColumns(
const podio::Frame& frame, const std::string& stem,
std::unordered_map<HashedString,
std::unique_ptr<podio_detail::ConstDynamicColumnBase>>&
dynamic);
} // namespace podio_detail
} // namespace Acts
71 changes: 69 additions & 2 deletions Plugins/Podio/src/PodioUtil.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,14 @@
#include "Acts/Surfaces/StrawSurface.hpp"
#include "Acts/Surfaces/Surface.hpp"
#include "Acts/Utilities/ThrowAssert.hpp"
#include "Acts/Utilities/TypeList.hpp"
#include "ActsPodioEdm/Surface.h"

#include <limits>
#include <memory>

namespace Acts::PodioUtil {
namespace Acts {
namespace PodioUtil {

namespace {
template <typename bounds_t>
Expand Down Expand Up @@ -203,4 +205,69 @@ std::shared_ptr<const Surface> convertSurfaceFromPodio(
return result;
}

} // namespace Acts::PodioUtil
} // namespace PodioUtil
namespace podio_detail {

template <typename F, typename... Args>
void apply(F&& f, TypeList<Args...> /*unused*/) {
f(Args{}...);
}

void recoverDynamicColumns(
const podio::Frame& frame, const std::string& stem,
std::unordered_map<HashedString,
std::unique_ptr<podio_detail::ConstDynamicColumnBase>>&
dynamic) {
using load_type = std::unique_ptr<podio_detail::DynamicColumnBase> (*)(
const podio::CollectionBase*);

// See
// https://github.com/AIDASoft/podio/blob/858c0ff0b841705d1b18aafd57569fcbd1beda91/include/podio/UserDataCollection.h#L30-L31
using types = TypeList<float, double, int8_t, int16_t, int32_t, int64_t,
uint8_t, uint16_t, uint32_t, uint64_t>;

std::vector<std::string> available = frame.getAvailableCollections();

for (const auto& col : available) {
std::string prefix = stem + "_extra__";
std::size_t p = col.find(prefix);
if (p == std::string::npos) {
continue;
}
std::string dynName = col.substr(prefix.size());
const podio::CollectionBase* coll = frame.get(col);

std::unique_ptr<podio_detail::ConstDynamicColumnBase> up;

apply(
[&](auto... args) {
auto inner = [&](auto arg) {
if (up) {
return;
}
using T = decltype(arg);
const auto* dyn =
dynamic_cast<const podio::UserDataCollection<T>*>(coll);
if (dyn == nullptr) {
return;
}
up = std::make_unique<podio_detail::ConstDynamicColumn<T>>(dynName,
*dyn);
};

((inner(args)), ...);
},
types{});

if (!up) {
throw std::runtime_error{"Dynamic column '" + dynName +
"' is not of allowed type"};
}

HashedString hashedKey = hashString(dynName);
dynamic.insert({hashedKey, std::move(up)});
}
}

} // namespace podio_detail
} // namespace Acts

0 comments on commit 8c2fed8

Please sign in to comment.