Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 09:41:48

0001 // This file is part of the ACTS project.
0002 //
0003 // Copyright (C) 2016 CERN for the benefit of the ACTS project
0004 //
0005 // This Source Code Form is subject to the terms of the Mozilla Public
0006 // License, v. 2.0. If a copy of the MPL was not distributed with this
0007 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
0008 
0009 #pragma once
0010 
0011 #include "ActsExamples/Framework/SequenceElement.hpp"
0012 #include "ActsExamples/Framework/WhiteBoard.hpp"
0013 
0014 #include <stdexcept>
0015 #include <typeinfo>
0016 #include <unordered_map>
0017 
0018 namespace Acts {
0019 class Logger;
0020 }
0021 
0022 namespace ActsExamples {
0023 
0024 /// Base class for all data handles.
0025 ///
0026 /// Provides common functionality for tracking the parent sequence element
0027 /// and key name. The key is optional until explicitly initialized.
0028 class DataHandleBase {
0029  private:
0030   struct StringHash {
0031     using is_transparent = void;  // Enables heterogeneous operations.
0032 
0033     std::size_t operator()(std::string_view sv) const {
0034       std::hash<std::string_view> hasher;
0035       return hasher(sv);
0036     }
0037   };
0038 
0039  protected:
0040   DataHandleBase(SequenceElement* parent, const std::string& name)
0041       : m_parent(parent), m_name(name) {}
0042 
0043   // We can't change addresses after construction
0044   DataHandleBase(const DataHandleBase&) = delete;
0045   DataHandleBase(DataHandleBase&&) = default;
0046 
0047  public:
0048   virtual ~DataHandleBase() = default;
0049 
0050   const std::string& key() const { return m_key.value(); }
0051 
0052   virtual const std::type_info& typeInfo() const = 0;
0053 
0054   bool isInitialized() const { return m_key.has_value(); }
0055 
0056   const std::string& name() const { return m_name; }
0057 
0058   void maybeInitialize(std::optional<std::string_view> key);
0059 
0060   virtual bool isCompatible(const DataHandleBase& other) const = 0;
0061 
0062   using StateMapType = std::unordered_map<std::string, const DataHandleBase*,
0063                                           StringHash, std::equal_to<>>;
0064 
0065   virtual void emulate(StateMapType& state, WhiteBoard::AliasMapType& aliases,
0066                        const Acts::Logger& logger) const = 0;
0067 
0068   std::string fullName() const { return m_parent->name() + "." + name(); }
0069 
0070  protected:
0071   void registerAsWriteHandle();
0072   void registerAsReadHandle();
0073 
0074   // Trampoline functions to avoid having the WhiteBoard as a friend
0075   template <typename T>
0076   void add(WhiteBoard& wb, T&& object) const {
0077     wb.add(m_key.value(), std::forward<T>(object));
0078   }
0079 
0080   template <typename T>
0081   const T& get(const WhiteBoard& wb) const {
0082     return wb.get<T>(m_key.value());
0083   }
0084 
0085   template <typename T>
0086   T pop(WhiteBoard& wb) const {
0087     return wb.pop<T>(m_key.value());
0088   }
0089 
0090   SequenceElement* m_parent{nullptr};
0091   std::string m_name;
0092   std::optional<std::string> m_key{};
0093 };
0094 
0095 /// Base class for write data handles.
0096 ///
0097 /// Write handles are used to store data in the WhiteBoard. They ensure that:
0098 /// - Each key can only be written once
0099 /// - The key must be non-empty
0100 /// - The data type is consistent for each key
0101 class WriteDataHandleBase : public DataHandleBase {
0102  protected:
0103   WriteDataHandleBase(SequenceElement* parent, const std::string& name)
0104       : DataHandleBase{parent, name} {}
0105 
0106  public:
0107   void initialize(std::string_view key);
0108 
0109   bool isCompatible(const DataHandleBase& other) const final;
0110 
0111   void emulate(StateMapType& state, WhiteBoard::AliasMapType& aliases,
0112                const Acts::Logger& logger) const final;
0113 };
0114 
0115 /// Base class for read data handles.
0116 ///
0117 /// Read handles are used to access data from the WhiteBoard. They ensure that:
0118 /// - The data exists before reading
0119 /// - The data type matches the expected type
0120 /// - The data can be read multiple times
0121 class ReadDataHandleBase : public DataHandleBase {
0122  protected:
0123   using DataHandleBase::DataHandleBase;
0124 
0125  public:
0126   void initialize(std::string_view key);
0127 
0128   bool isCompatible(const DataHandleBase& other) const final;
0129 
0130   void emulate(StateMapType& state, WhiteBoard::AliasMapType& aliases,
0131                const Acts::Logger& logger) const override;
0132 };
0133 
0134 /// Base class for consume data handles.
0135 ///
0136 /// Consume handles are used to take ownership of data from the WhiteBoard.
0137 /// They ensure that:
0138 /// - The data exists before consuming
0139 /// - The data type matches the expected type
0140 /// - The data can only be consumed once
0141 /// - The data is removed from the WhiteBoard after consumption
0142 class ConsumeDataHandleBase : public ReadDataHandleBase {
0143  protected:
0144   using ReadDataHandleBase::ReadDataHandleBase;
0145 
0146  public:
0147   void emulate(StateMapType& state, WhiteBoard::AliasMapType& aliases,
0148                const Acts::Logger& logger) const override;
0149 };
0150 
0151 /// A write handle for storing data in the WhiteBoard.
0152 ///
0153 /// @tparam T The type of data to store
0154 ///
0155 /// Example usage:
0156 /// @code
0157 /// WriteDataHandle<int> handle(parent, "my_data");
0158 /// handle.initialize("my_key");
0159 /// handle(wb, 42);  // Store value
0160 /// @endcode
0161 template <typename T>
0162 class WriteDataHandle final : public WriteDataHandleBase {
0163  public:
0164   WriteDataHandle(SequenceElement* parent, const std::string& name)
0165       : WriteDataHandleBase{parent, name} {
0166     registerAsWriteHandle();
0167   }
0168 
0169   void operator()(const AlgorithmContext& ctx, T&& value) const {
0170     (*this)(ctx.eventStore, std::move(value));
0171   }
0172 
0173   void operator()(WhiteBoard& wb, T&& value) const {
0174     if (!isInitialized()) {
0175       throw std::runtime_error{"WriteDataHandle '" + fullName() +
0176                                "' not initialized"};
0177     }
0178     add(wb, std::move(value));
0179   }
0180 
0181   const std::type_info& typeInfo() const override { return typeid(T); };
0182 };
0183 
0184 /// A read handle for accessing data from the WhiteBoard.
0185 ///
0186 /// @tparam T The type of data to read
0187 ///
0188 /// Example usage:
0189 /// @code
0190 /// ReadDataHandle<int> handle(parent, "my_data");
0191 /// handle.initialize("my_key");
0192 /// const auto& value = handle(wb);  // Access value
0193 /// @endcode
0194 template <typename T>
0195 class ReadDataHandle final : public ReadDataHandleBase {
0196  public:
0197   ReadDataHandle(SequenceElement* parent, const std::string& name)
0198       : ReadDataHandleBase{parent, name} {
0199     registerAsReadHandle();
0200   }
0201 
0202   const T& operator()(const AlgorithmContext& ctx) const {
0203     return (*this)(ctx.eventStore);
0204   }
0205 
0206   const T& operator()(const WhiteBoard& wb) const {
0207     if (!isInitialized()) {
0208       throw std::runtime_error{"ReadDataHandle '" + fullName() +
0209                                "' not initialized"};
0210     }
0211     return get<T>(wb);
0212   }
0213 
0214   const std::type_info& typeInfo() const override { return typeid(T); };
0215 };
0216 
0217 /// A consume handle for taking ownership of data from the WhiteBoard.
0218 ///
0219 /// @tparam T The type of data to consume
0220 ///
0221 /// Example usage:
0222 /// @code
0223 /// ConsumeDataHandle<int> handle(parent, "my_data");
0224 /// handle.initialize("my_key");
0225 /// auto value = handle(wb);  // Take ownership of value
0226 /// // value is no longer in WhiteBoard
0227 /// @endcode
0228 template <typename T>
0229 class ConsumeDataHandle final : public ConsumeDataHandleBase {
0230  public:
0231   ConsumeDataHandle(SequenceElement* parent, const std::string& name)
0232       : ConsumeDataHandleBase{parent, name} {
0233     registerAsReadHandle();
0234   }
0235 
0236   T operator()(const AlgorithmContext& ctx) const {
0237     return (*this)(ctx.eventStore);
0238   }
0239 
0240   T operator()(WhiteBoard& wb) const {
0241     if (!isInitialized()) {
0242       throw std::runtime_error{"ConsumeDataHandle '" + fullName() +
0243                                "' not initialized"};
0244     }
0245     return pop<T>(wb);
0246   }
0247 
0248   const std::type_info& typeInfo() const override { return typeid(T); };
0249 };
0250 
0251 }  // namespace ActsExamples