Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-09-16 09:20:01

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