Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:06:10

0001 #ifndef PODIO_ROOTREADER_H
0002 #define PODIO_ROOTREADER_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 "TChain.h"
0010 
0011 #include <memory>
0012 #include <string>
0013 #include <string_view>
0014 #include <tuple>
0015 #include <utility>
0016 #include <vector>
0017 
0018 // forward declarations
0019 class TClass;
0020 class TFile;
0021 class TTree;
0022 
0023 namespace podio {
0024 
0025 namespace detail {
0026   // Information about the collection class type, whether it is a subset, the
0027   // schema version on file and the index in the collection branches cache
0028   // vector
0029   using CollectionInfo = std::tuple<std::string, bool, SchemaVersionT, size_t>;
0030 
0031 } // namespace detail
0032 
0033 class CollectionBase;
0034 class CollectionIDTable;
0035 class GenericParameters;
0036 struct CollectionReadBuffers;
0037 
0038 /// This class has the function to read available data from disk in ROOTs TTree
0039 /// format.
0040 ///
0041 /// The ROOTReader provides the data as ROOTFrameData from which a podio::Frame
0042 /// can be constructed. It can be used to read files written by the ROOTWriter.
0043 class ROOTReader {
0044 
0045 public:
0046   /// Create a ROOTReader
0047   ROOTReader() = default;
0048   /// Destructor
0049   ~ROOTReader() = default;
0050 
0051   /// The ROOTReader is not copy-able
0052   ROOTReader(const ROOTReader&) = delete;
0053   /// The ROOTReader is not copy-able
0054   ROOTReader& operator=(const ROOTReader&) = delete;
0055 
0056   /// Open a single file for reading.
0057   ///
0058   /// @param filename The name of the input file
0059   void openFile(const std::string& filename);
0060 
0061   /// Open multiple files for reading and then treat them as if they are one file
0062   ///
0063   /// @note All of the files are assumed to have the same structure. Specifically
0064   /// this means:
0065   /// - The same categories are available from all files
0066   /// - The collections that are contained in the individual categories are the
0067   ///   same across all files
0068   /// - This usually boils down to "the files have been written with the same
0069   ///   "settings", e.g. they are outputs of a batched process.
0070   ///
0071   /// @param filenames The filenames of all input files that should be read
0072   void openFiles(const std::vector<std::string>& filenames);
0073 
0074   /// Read the next data entry for a given category.
0075   ///
0076   /// @param name The category name for which to read the next entry
0077   ///
0078   /// @returns FrameData from which a podio::Frame can be constructed if the
0079   ///          category exists and if there are still entries left to read.
0080   ///          Otherwise a nullptr
0081   std::unique_ptr<podio::ROOTFrameData> readNextEntry(const std::string& name);
0082 
0083   /// Read the desired data entry for a given category.
0084   ///
0085   /// @param name  The category name for which to read the next entry
0086   /// @param entry The entry number to read
0087   ///
0088   /// @returns FrameData from which a podio::Frame can be constructed if the
0089   ///          category and the desired entry exist. Otherwise a nullptr
0090   std::unique_ptr<podio::ROOTFrameData> readEntry(const std::string& name, const unsigned entry);
0091 
0092   /// Get the number of entries for the given name
0093   ///
0094   /// @param name The name of the category
0095   ///
0096   /// @returns The number of entries that are available for the category
0097   unsigned getEntries(const std::string& name) const;
0098 
0099   /// Get the build version of podio that has been used to write the current
0100   /// file
0101   ///
0102   /// @returns The podio build version
0103   podio::version::Version currentFileVersion() const {
0104     return m_fileVersion;
0105   }
0106 
0107   /// Get the (build) version of a datamodel that has been used to write the
0108   /// current file
0109   ///
0110   /// @param name The name of the datamodel
0111   ///
0112   /// @returns The (build) version of the datamodel if available or an empty
0113   ///          optional
0114   std::optional<podio::version::Version> currentFileVersion(const std::string& name) const {
0115     return m_datamodelHolder.getDatamodelVersion(name);
0116   }
0117 
0118   /// Get the names of all the available Frame categories in the current file(s).
0119   ///
0120   /// @returns The names of the available categories from the file
0121   std::vector<std::string_view> getAvailableCategories() const;
0122 
0123   /// Get the datamodel definition for the given name
0124   ///
0125   /// @param name The name of the datamodel
0126   ///
0127   /// @returns The high level definition of the datamodel in JSON format
0128   const std::string_view getDatamodelDefinition(const std::string& name) const {
0129     return m_datamodelHolder.getDatamodelDefinition(name);
0130   }
0131 
0132   /// Get all names of the datamodels that are available from this reader
0133   ///
0134   /// @returns The names of the datamodels
0135   std::vector<std::string> getAvailableDatamodels() const {
0136     return m_datamodelHolder.getAvailableDatamodels();
0137   }
0138 
0139 private:
0140   /// Helper struct to group together all the necessary state to read / process
0141   /// a given category. A "category" in this case describes all frames with the
0142   /// same name which are constrained by the ROOT file structure that we use to
0143   /// have the same contents. It encapsulates all state that is necessary for
0144   /// reading from a TTree / TChain (i.e. collection infos, branches, ...)
0145   struct CategoryInfo {
0146     /// constructor from chain for more convenient map insertion
0147     CategoryInfo(std::unique_ptr<TChain>&& c) : chain(std::move(c)) {
0148     }
0149     std::unique_ptr<TChain> chain{nullptr};                                      ///< The TChain with the data
0150     unsigned entry{0};                                                           ///< The next entry to read
0151     std::vector<std::pair<std::string, detail::CollectionInfo>> storedClasses{}; ///< The stored collections in this
0152                                                                                  ///< category
0153     std::vector<root_utils::CollectionBranches> branches{};                      ///< The branches for this category
0154     std::shared_ptr<CollectionIDTable> table{nullptr}; ///< The collection ID table for this category
0155   };
0156 
0157   /// Initialize the passed CategoryInfo by setting up the necessary branches,
0158   /// collection infos and all necessary meta data to be able to read entries
0159   /// with this name
0160   void initCategory(CategoryInfo& catInfo, const std::string& name);
0161 
0162   /// Get the category information for the given name. In case there is no TTree
0163   /// with contents for the given name this will return a CategoryInfo with an
0164   /// uninitialized chain (nullptr) member
0165   CategoryInfo& getCategoryInfo(const std::string& name);
0166 
0167   /// Read the parameters for the entry specified in the passed CategoryInfo
0168   GenericParameters readEntryParameters(CategoryInfo& catInfo, bool reloadBranches, unsigned int localEntry);
0169 
0170   template <typename T>
0171   static void readParams(CategoryInfo& catInfo, podio::GenericParameters& params, bool reloadBranches,
0172                          unsigned int localEntry);
0173 
0174   /// Read the data entry specified in the passed CategoryInfo, and increase the
0175   /// counter afterwards. In case the requested entry is larger than the
0176   /// available number of entries, return a nullptr.
0177   std::unique_ptr<podio::ROOTFrameData> readEntry(ROOTReader::CategoryInfo& catInfo);
0178 
0179   /// Get / read the buffers at index iColl in the passed category information
0180   podio::CollectionReadBuffers getCollectionBuffers(CategoryInfo& catInfo, size_t iColl, bool reloadBranches,
0181                                                     unsigned int localEntry);
0182 
0183   std::unique_ptr<TChain> m_metaChain{nullptr};                 ///< The metadata tree
0184   std::unordered_map<std::string, CategoryInfo> m_categories{}; ///< All categories
0185   std::vector<std::string> m_availCategories{};                 ///< All available categories from this file
0186 
0187   podio::version::Version m_fileVersion{0, 0, 0};
0188   DatamodelDefinitionHolder m_datamodelHolder{};
0189 };
0190 
0191 } // namespace podio
0192 
0193 #endif // PODIO_ROOTREADER_H