Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-11-14 10:38:13

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