Back to home page

EIC code displayed by LXR

 
 

    


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