Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-16 09:03:29

0001 #ifndef PODIO_RNTUPLEREADER_H
0002 #define PODIO_RNTUPLEREADER_H
0003 
0004 #include "podio/ROOTFrameData.h"
0005 #include "podio/podioVersion.h"
0006 #include "podio/utilities/DatamodelRegistryIOHelpers.h"
0007 #include "podio/utilities/RootHelpers.h"
0008 
0009 #include <string>
0010 #include <string_view>
0011 #include <unordered_map>
0012 #include <vector>
0013 
0014 #include <ROOT/RNTuple.hxx>
0015 #include <ROOT/RNTupleReader.hxx>
0016 #include <RVersion.h>
0017 
0018 namespace podio {
0019 
0020 /// Introduce a new namespace instead of potentially opening and polluting the
0021 /// ROOT namespace
0022 namespace root_compat {
0023 #if ROOT_VERSION_CODE < ROOT_VERSION(6, 35, 0)
0024   using RNTupleReader = ROOT::Experimental::RNTupleReader;
0025 #else
0026   using RNTupleReader = ROOT::RNTupleReader;
0027 #endif
0028 } // namespace root_compat
0029 
0030 /// The RNTupleReader can be used to read files that have been written with the
0031 /// RNTuple backend.
0032 ///
0033 /// The RNTupleReader provides the data as ROOTFrameData from which a podio::Frame
0034 /// can be constructed. It can be used to read files written by the RNTupleWriter.
0035 class RNTupleReader {
0036 
0037 public:
0038   /// Create a RNTupleReader
0039   RNTupleReader() = default;
0040   /// Destructor
0041   ~RNTupleReader() = default;
0042   /// The RNTupleReader is not copy-able
0043   RNTupleReader(const RNTupleReader&) = delete;
0044   /// The RNTupleReader is not copy-able
0045   RNTupleReader& operator=(const RNTupleReader&) = delete;
0046 
0047   /// Open a single file for reading.
0048   ///
0049   /// @param filename The name of the input file
0050   void openFile(const std::string& filename);
0051 
0052   /// Open multiple files for reading and then treat them as if they are one file
0053   ///
0054   /// @note All of the files are assumed to have the same structure. Specifically
0055   /// this means:
0056   /// - The same categories are available from all files
0057   /// - The collections that are contained in the individual categories are the
0058   ///   same across all files
0059   /// - This usually boils down to "the files have been written with the same
0060   ///   "settings", e.g. they are outputs of a batched process.
0061   ///
0062   /// @param filenames The filenames of all input files that should be read
0063   void openFiles(const std::vector<std::string>& filenames);
0064 
0065   /// Read the next data entry for a given category.
0066   ///
0067   /// @param name The category name for which to read the next entry
0068   /// @param collsToRead (optional) the collection names that should be read. If
0069   ///             not provided (or empty) all collections will be read
0070   ///
0071   /// @returns FrameData from which a podio::Frame can be constructed if the
0072   ///          category exists and if there are still entries left to read.
0073   ///          Otherwise a nullptr
0074   ///
0075   /// @throws std::invalid_argument in case collsToRead contains collection
0076   /// names that are not available
0077   std::unique_ptr<podio::ROOTFrameData> readNextEntry(const std::string& name,
0078                                                       const std::vector<std::string>& collsToRead = {});
0079 
0080   /// Read the desired data entry for a given category.
0081   ///
0082   /// @param name  The category name for which to read the next entry
0083   /// @param entry The entry number to read
0084   /// @param collsToRead (optional) the collection names that should be read. If
0085   ///             not provided (or empty) all collections will be read
0086   ///
0087   /// @returns FrameData from which a podio::Frame can be constructed if the
0088   ///          category and the desired entry exist. Otherwise a nullptr
0089   ///
0090   /// @throws std::invalid_argument in case collsToRead contains collection
0091   /// names that are not available
0092   std::unique_ptr<podio::ROOTFrameData> readEntry(const std::string& name, const unsigned entry,
0093                                                   const std::vector<std::string>& collsToRead = {});
0094 
0095   /// Get the names of all the available Frame categories in the current file(s).
0096   ///
0097   /// @returns The names of the available categores from the file
0098   std::vector<std::string_view> getAvailableCategories() const;
0099 
0100   /// Get the number of entries for the given name
0101   ///
0102   /// @param name The name of the category
0103   ///
0104   /// @returns The number of entries that are available for the category
0105   unsigned getEntries(const std::string& name);
0106 
0107   /// Get the build version of podio that has been used to write the current
0108   /// file
0109   ///
0110   /// @returns The podio build version
0111   podio::version::Version currentFileVersion() const {
0112     return m_fileVersion;
0113   }
0114 
0115   /// Get the (build) version of a datamodel that has been used to write the
0116   /// current file
0117   ///
0118   /// @param name The name of the datamodel
0119   ///
0120   /// @returns The (build) version of the datamodel if available or an empty
0121   ///          optional
0122   std::optional<podio::version::Version> currentFileVersion(const std::string& name) const {
0123     return m_datamodelHolder.getDatamodelVersion(name);
0124   }
0125 
0126   /// Get the datamodel definition for the given name
0127   ///
0128   /// @param name The name of the datamodel
0129   ///
0130   /// @returns The high level definition of the datamodel in JSON format
0131   const std::string_view getDatamodelDefinition(const std::string& name) const {
0132     return m_datamodelHolder.getDatamodelDefinition(name);
0133   }
0134 
0135   /// Get all names of the datamodels that are available from this reader
0136   ///
0137   /// @returns The names of the datamodels
0138   std::vector<std::string> getAvailableDatamodels() const {
0139     return m_datamodelHolder.getAvailableDatamodels();
0140   }
0141 
0142 private:
0143   /**
0144    * Initialize the given category by filling the maps with metadata information
0145    * that will be used later
0146    */
0147   bool initCategory(const std::string& category);
0148 
0149   /**
0150    * Read and reconstruct the generic parameters of the Frame
0151    */
0152   GenericParameters readEventMetaData(const std::string& name, const unsigned localEntry, const unsigned readerIndex);
0153 
0154   template <typename T>
0155   void readParams(const std::string& name, const unsigned entNum, const unsigned readerIndex,
0156                   GenericParameters& params);
0157 
0158   std::unique_ptr<root_compat::RNTupleReader> m_metadata{};
0159 
0160   podio::version::Version m_fileVersion{};
0161   DatamodelDefinitionHolder m_datamodelHolder{};
0162 
0163   std::unordered_map<std::string, std::vector<std::unique_ptr<root_compat::RNTupleReader>>> m_readers{};
0164   std::unordered_map<std::string, std::unique_ptr<root_compat::RNTupleReader>> m_metadata_readers{};
0165   std::vector<std::string> m_filenames{};
0166 
0167   std::unordered_map<std::string, unsigned> m_entries{};
0168   // Map category to a vector that contains at how many entries each reader starts
0169   // For example, if we have 3 readers and the first one has 10 entries, the second one 20 and the third one 30
0170   // then the vector will be {0, 10, 30}
0171   // 60 is not needed because anything after 30 will be in the last reader
0172   std::unordered_map<std::string, std::vector<unsigned>> m_readerEntries{};
0173   std::unordered_map<std::string, unsigned> m_totalEntries{};
0174 
0175   /// Map each category to the collections that have been written and are available
0176   std::unordered_map<std::string, std::vector<podio::root_utils::CollectionWriteInfo>> m_collectionInfo{};
0177 
0178   std::vector<std::string> m_availableCategories{};
0179 
0180   std::unordered_map<std::string, std::shared_ptr<podio::CollectionIDTable>> m_idTables{};
0181 };
0182 
0183 } // namespace podio
0184 
0185 #endif