Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-08-16 09:15:50

0001 #ifndef PODIO_READER_H
0002 #define PODIO_READER_H
0003 
0004 #include "podio/Frame.h"
0005 #include "podio/podioVersion.h"
0006 #include "podio/utilities/ReaderUtils.h"
0007 
0008 namespace podio {
0009 
0010 /// Generic (type erased) reader class that can handle different I/O backends
0011 /// transparently
0012 ///
0013 /// Offers some more high level functionality compared to the lower level
0014 /// backend specific readers that this class wraps. In contrast to the lower
0015 /// level readers that usually return arbitrary FrameData, this interface class
0016 /// will return fully constructed Frames. In addition, it provides convenience
0017 /// methods to deal specifically with the "events" frame category.
0018 ///
0019 /// @note The recommended way to construct is to use the makeReader() functions
0020 /// since they handle the instantiation of the correct low level readers
0021 class Reader {
0022 private:
0023   struct ReaderConcept {
0024     virtual ~ReaderConcept() = default;
0025 
0026     virtual podio::Frame readNextFrame(const std::string& name, const std::vector<std::string>& collsToRead) = 0;
0027     virtual podio::Frame readFrame(const std::string& name, size_t index,
0028                                    const std::vector<std::string>& collsToRead) = 0;
0029     virtual size_t getEntries(const std::string& name) const = 0;
0030     virtual podio::version::Version currentFileVersion() const = 0;
0031     virtual std::optional<podio::version::Version> currentFileVersion(const std::string& name) const = 0;
0032     virtual std::vector<std::string_view> getAvailableCategories() const = 0;
0033     virtual const std::string_view getDatamodelDefinition(const std::string& name) const = 0;
0034     virtual std::vector<std::string> getAvailableDatamodels() const = 0;
0035   };
0036 
0037 private:
0038   template <typename T>
0039   struct ReaderModel final : ReaderConcept {
0040     ReaderModel(std::unique_ptr<T> reader) : m_reader(std::move(reader)) {
0041     }
0042     ReaderModel(const ReaderModel&) = delete;
0043     ReaderModel& operator=(const ReaderModel&) = delete;
0044     ReaderModel(ReaderModel&&) = default;
0045     ReaderModel& operator=(ReaderModel&&) = default;
0046 
0047     ~ReaderModel() override = default;
0048 
0049     podio::Frame readNextFrame(const std::string& name, const std::vector<std::string>& collsToRead) override {
0050       auto maybeFrame = m_reader->readNextEntry(name, collsToRead);
0051       if (maybeFrame) {
0052         return maybeFrame;
0053       }
0054       throw std::runtime_error("Failed reading category " + name + " (reading beyond bounds?)");
0055     }
0056 
0057     podio::Frame readFrame(const std::string& name, size_t index,
0058                            const std::vector<std::string>& collsToRead) override {
0059       auto maybeFrame = m_reader->readEntry(name, index, collsToRead);
0060       if (maybeFrame) {
0061         return maybeFrame;
0062       }
0063       throw std::runtime_error("Failed reading category " + name + " at frame " + std::to_string(index) +
0064                                " (reading beyond bounds?)");
0065     }
0066     size_t getEntries(const std::string& name) const override {
0067       return m_reader->getEntries(name);
0068     }
0069     podio::version::Version currentFileVersion() const override {
0070       return m_reader->currentFileVersion();
0071     }
0072 
0073     std::optional<podio::version::Version> currentFileVersion(const std::string& name) const override {
0074       return m_reader->currentFileVersion(name);
0075     }
0076 
0077     std::vector<std::string_view> getAvailableCategories() const override {
0078       return m_reader->getAvailableCategories();
0079     }
0080 
0081     const std::string_view getDatamodelDefinition(const std::string& name) const override {
0082       return m_reader->getDatamodelDefinition(name);
0083     }
0084 
0085     std::vector<std::string> getAvailableDatamodels() const override {
0086       return m_reader->getAvailableDatamodels();
0087     }
0088 
0089     std::unique_ptr<T> m_reader;
0090   };
0091 
0092   std::unique_ptr<ReaderConcept> m_self{nullptr};
0093 
0094 public:
0095   /// Create a reader from a low level reader
0096   ///
0097   /// @tparam T The type of the low level reader (will be deduced)
0098   /// @param actualReader a low level reader that provides access to FrameDataT
0099   template <typename T>
0100   Reader(std::unique_ptr<T> actualReader);
0101 
0102   Reader(const Reader&) = delete;
0103   Reader& operator=(const Reader&) = delete;
0104   Reader(Reader&&) = default;
0105   Reader& operator=(Reader&&) = default;
0106   ~Reader() = default;
0107 
0108   /// Read the next frame of a given category
0109   ///
0110   /// @param name The category name for which to read the next frame
0111   /// @param collsToRead (optional) the collection names that should be read. If
0112   ///             not provided (or empty) all collections will be read
0113   ///
0114   /// @returns A fully constructed Frame with the contents read from file
0115   ///
0116   /// @throws std::invalid_argument in case the category is not available or in
0117   ///         case no more entries are available
0118   podio::Frame readNextFrame(const std::string& name, const std::vector<std::string>& collsToRead = {}) {
0119     return m_self->readNextFrame(name, collsToRead);
0120   }
0121 
0122   /// Read the next frame of the "events" category
0123   ///
0124   /// @param collsToRead (optional) the collection names that should be read. If
0125   ///             not provided (or empty) all collections will be read
0126   ///
0127   /// @returns A fully constructed Frame with the contents read from file
0128   ///
0129   /// @throws std::invalid_argument in case no (more) events are available
0130   podio::Frame readNextEvent(const std::vector<std::string>& collsToRead = {}) {
0131     return readNextFrame(podio::Category::Event, collsToRead);
0132   }
0133 
0134   /// Read a specific frame for a given category
0135   ///
0136   /// @param name  The category name for which to read the next entry
0137   /// @param index The entry number to read
0138   /// @param collsToRead (optional) the collection names that should be read. If
0139   ///             not provided (or empty) all collections will be read
0140   ///
0141   /// @returns A fully constructed Frame with the contents read from file
0142   ///
0143   /// @throws std::invalid_argument in case the category is not available or in
0144   ///         case the specified entry is not available
0145   podio::Frame readFrame(const std::string& name, size_t index, const std::vector<std::string>& collsToRead = {}) {
0146     return m_self->readFrame(name, index, collsToRead);
0147   }
0148 
0149   /// Read a specific frame of the "events" category
0150   ///
0151   /// @param index The event number to read
0152   /// @param collsToRead (optional) the collection names that should be read. If
0153   ///             not provided (or empty) all collections will be read
0154   ///
0155   /// @returns A fully constructed Frame with the contents read from file
0156   ///
0157   /// @throws std::invalid_argument in case the desired event is not available
0158   podio::Frame readEvent(size_t index, const std::vector<std::string>& collsToRead = {}) {
0159     return readFrame(podio::Category::Event, index, collsToRead);
0160   }
0161 
0162   /// Get the number of entries for the given name
0163   ///
0164   /// @param name The name of the category
0165   ///
0166   /// @returns The number of entries that are available for the category
0167   size_t getEntries(const std::string& name) const {
0168     return m_self->getEntries(name);
0169   }
0170 
0171   /// Get the number of events
0172   ///
0173   /// @returns The number of entries that are available for the category
0174   size_t getEvents() const {
0175     return getEntries(podio::Category::Event);
0176   }
0177 
0178   /// Get the build version of podio that has been used to write the current
0179   /// file
0180   ///
0181   /// @returns The podio build version
0182   podio::version::Version currentFileVersion() const {
0183     return m_self->currentFileVersion();
0184   }
0185 
0186   /// Get the (build) version of a datamodel that has been used to write the
0187   /// current file
0188   ///
0189   /// @param name The name of the datamodel
0190   ///
0191   /// @returns The (build) version of the datamodel if available or an empty
0192   ///          optional
0193   std::optional<podio::version::Version> currentFileVersion(const std::string& name) const {
0194     return m_self->currentFileVersion(name);
0195   }
0196 
0197   /// Get the names of all the available Frame categories in the current file(s).
0198   ///
0199   /// @returns The names of the available categories from the file
0200   std::vector<std::string_view> getAvailableCategories() const {
0201     return m_self->getAvailableCategories();
0202   }
0203 
0204   /// Get the datamodel definition for the given name
0205   ///
0206   /// @param name The name of the datamodel
0207   ///
0208   /// @returns The high level definition of the datamodel in JSON format
0209   const std::string_view getDatamodelDefinition(const std::string& name) const {
0210     return m_self->getDatamodelDefinition(name);
0211   }
0212 
0213   /// Get all names of the datamodels that are available from this reader
0214   ///
0215   /// @returns The names of the datamodels
0216   std::vector<std::string> getAvailableDatamodels() const {
0217     return m_self->getAvailableDatamodels();
0218   }
0219 
0220   std::optional<std::map<std::string, SizeStats>> getSizeStats(std::string_view category);
0221 };
0222 
0223 /// Create a Reader that is able to read the file or files matching a glob pattern
0224 ///
0225 /// This will inspect the filename as well as peek at the file contents to
0226 /// instantiate the correct low level reader to open and read the file
0227 ///
0228 /// @param filename The (path to the) file to read from.
0229 ///                 The file path can include glob patterns to match multiple files.
0230 ///
0231 /// @returns A Reader that has been initialized and that can be used for reading
0232 ///          data from the passed file
0233 Reader makeReader(const std::string& filename);
0234 
0235 /// Create a Reader that is able to read the files
0236 ///
0237 /// This will inspect the filenames as well as peek into the **first file only**
0238 /// to decide based on the contents which low level reader to instantiate for
0239 /// reading. All files are assumed to be of the same I/O format, no switching
0240 /// between formats is possible.
0241 ///
0242 /// @note For SIO files this will only work with exactly one file!
0243 ///
0244 /// @param filenames The (paths to the) files to read from
0245 ///
0246 /// @returns A Reader that has been initialized and that can be used for reading
0247 ///          data from the passed files
0248 ///
0249 /// @throws std::runtime_error in case the file extensions differ or in case
0250 ///         support for the necessary I/O backend has not been built or in case
0251 ///         multiple files for the SIO backend are passed
0252 Reader makeReader(const std::vector<std::string>& filenames);
0253 
0254 } // namespace podio
0255 
0256 #endif // PODIO_READER_H