Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-18 09:25:09

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