EICrecon
JANA based reconstruction for the EPIC detector
Loading...
Searching...
No Matches
datamodel_glue.h
Go to the documentation of this file.
1// SPDX-License-Identifier: LGPL-3.0-or-later
2// Copyright (C) 2025 Wouter Deconinck
3//
4// Modern datamodel glue for podio >= 1.3
5// This file uses podio's built-in TypeList support instead of code generation
6
7#pragma once
8
9#include <stdexcept>
10#include <string_view>
11#include <unordered_map>
12#include <type_traits>
13#include <fmt/format.h>
14#include <podio/CollectionBase.h>
15#include <podio/utilities/TypeHelpers.h>
16
17// Use umbrella headers if available (podio >= 1.3)
19
20// PodioTypeMap provides type traits for podio types
21// This mirrors the structure written by the legacy python generator,
22// and puts the types in the format expected by JANA2.
23template <typename T> struct PodioTypeMap {
24 using collection_t = typename T::collection_type;
25 using mutable_t = typename T::mutable_type;
26};
27
28// CollectionVisitorMap builds a dispatch table from podio collection type names
29// to type-safe visitor functions for a given Visitor type.
30//
31// The Visitor template parameter is expected to be a callable type (e.g. a
32// functor, lambda, or class with operator()) that can be invoked for each
33// supported concrete collection type:
34//
35// void operator()(const ConcreteCollectionType&);
36//
37// CollectionVisitorMap is instantiated once per Visitor (see VisitPodioCollection
38// below). At construction time it registers all EDM4hep and EDM4eic data and
39// link collection types by mapping their static typeName to a function that
40// will:
41// 1. downcast the generic podio::CollectionBase reference to the concrete
42// collection type, and
43// 2. call the Visitor with that concrete collection.
44//
45// This map is then used by VisitPodioCollection to look up the correct
46// handler at runtime based on collection.getTypeName(), providing a
47// type-safe implementation of the visitor pattern over podio collections.
48template <typename Visitor> class CollectionVisitorMap {
49public:
50 using FunctionType = void (*)(Visitor&, const podio::CollectionBase&);
51
52private:
53 std::unordered_map<std::string_view, FunctionType> m_map;
54
55 template <typename CollectionT>
56 static void visitCollection(Visitor& visitor, const podio::CollectionBase& collection) {
57 static_assert(std::is_base_of_v<podio::CollectionBase, CollectionT>,
58 "CollectionT must be derived from podio::CollectionBase");
59 visitor(*static_cast<const CollectionT*>(&collection));
60 }
61
62 template <typename CollectionT> void addToMap() {
63 m_map[CollectionT::typeName] = &visitCollection<CollectionT>;
64 }
65
66 template <typename DataT> void addDataTypeToMap() { addToMap<typename DataT::collection_type>(); }
67
68 template <typename... DataTypes>
69 void addAllDataCollections(podio::utils::TypeList<DataTypes...>) {
70 (addDataTypeToMap<DataTypes>(), ...);
71 }
72
73 template <typename... LinkTypes>
74 void addAllLinkCollections(podio::utils::TypeList<LinkTypes...>) {
75 (addDataTypeToMap<LinkTypes>(), ...);
76 }
77
78public:
80 // Add all EDM4hep and EDM4eic data collection types
81 addAllDataCollections(typename edm4hep::edm4hepDataTypes{});
82 addAllDataCollections(typename edm4eic::edm4eicDataTypes{});
83
84 // Add all EDM4hep and EDM4eic link collections
85 addAllLinkCollections(typename edm4hep::edm4hepLinkTypes{});
86 addAllLinkCollections(typename edm4eic::edm4eicLinkTypes{});
87 }
88
89 const auto& getMap() const { return m_map; }
90};
91
92// VisitPodioCollection is a visitor adaptor for type-safe processing of podio collections.
93//
94// This template implements a runtime-dispatch visitor pattern for
95// podio::CollectionBase instances. It uses the collection's
96// runtime type name together with CollectionVisitorMap to look up the
97// concrete collection type and call the provided @p Visitor on it.
98//
99// template parameter Visitor
100// A type that models a callable taking a const reference to each
101// supported concrete podio collection type. In practice, this means
102// that for every collection type CollectionT registered in
103// CollectionVisitorMap, the following expression must be well-formed:
104//
105// visitor(const CollectionT&);
106//
107// This can be satisfied either by giving Visitor a suitable
108// operator() overload, or by providing free / member functions
109// that are invocable with const CollectionT&.
110//
111// Usage:
112// - Construct or obtain a Visitor instance.
113// - Call VisitPodioCollection<Visitor>::operator() with the visitor
114// and a podio::CollectionBase reference. The adaptor will:
115// 1. Look up the collection's concrete type by getTypeName().
116// 2. Cast the podio::CollectionBase to the matching concrete
117// collection type.
118// 3. Invoke the visitor with a const CollectionT& argument.
119//
120// If the collection type name is not known to the registered EDM4hep or
121// EDM4eic datamodels, operator() throws std::runtime_error with a
122// descriptive error message.
123template <typename Visitor> struct VisitPodioCollection {
124 void operator()(Visitor& visitor, const podio::CollectionBase& collection) {
125 // Build the map once (static initialization)
126 static const CollectionVisitorMap<Visitor> visitorMap;
127
128 auto typeName = collection.getTypeName();
129 auto it = visitorMap.getMap().find(typeName);
130
131 if (it != visitorMap.getMap().end()) {
132 it->second(visitor, collection);
133 } else {
134 throw std::runtime_error(fmt::format(
135 "Unrecognized podio typename: {}.\n"
136 "This type was not found in the supported datamodels (EDM4hep, EDM4eic).\n"
137 "Possible causes:\n"
138 " - The type is not defined in EDM4hep or EDM4eic datamodels.\n"
139 " - You may be using an incompatible or outdated version of the datamodels.\n"
140 " - There may be a typo in the type name.\n"
141 "Please check your datamodel installation and ensure you are using compatible versions.",
142 typeName));
143 }
144 }
145};
Definition datamodel_glue.h:48
void(*)(Visitor &, const podio::CollectionBase &) FunctionType
Definition datamodel_glue.h:50
CollectionVisitorMap()
Definition datamodel_glue.h:79
const auto & getMap() const
Definition datamodel_glue.h:89
Definition datamodel_glue.h:23
typename T::mutable_type mutable_t
Definition datamodel_glue.h:25
typename T::collection_type collection_t
Definition datamodel_glue.h:24
Definition datamodel_glue.h:123
void operator()(Visitor &visitor, const podio::CollectionBase &collection)
Definition datamodel_glue.h:124