Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-12-16 10:24:04

0001 #ifndef PODIO_RNTUPLEWRITER_H
0002 #define PODIO_RNTUPLEWRITER_H
0003 
0004 #include "podio/Frame.h"
0005 #include "podio/utilities/DatamodelRegistryIOHelpers.h"
0006 #include "podio/utilities/RootHelpers.h"
0007 
0008 #include "TFile.h"
0009 #include <ROOT/RNTuple.hxx>
0010 #include <ROOT/RNTupleModel.hxx>
0011 #include <ROOT/RNTupleWriter.hxx>
0012 #include <ROOT/RVersion.hxx>
0013 
0014 #include <string>
0015 #include <unordered_map>
0016 #include <vector>
0017 
0018 namespace podio {
0019 
0020 namespace root_compat {
0021 #if ROOT_VERSION_CODE < ROOT_VERSION(6, 35, 0)
0022   using REntry = ROOT::Experimental::REntry;
0023   using RNTupleModel = ROOT::Experimental::RNTupleModel;
0024   using RNTupleWriter = ROOT::Experimental::RNTupleWriter;
0025 #else
0026   using REntry = ROOT::REntry;
0027   using RNTupleModel = ROOT::RNTupleModel;
0028   using RNTupleWriter = ROOT::RNTupleWriter;
0029 #endif
0030 } // namespace root_compat
0031 
0032 /// The RNTupleWriter writes podio files into ROOT files using the new RNTuple
0033 /// format.
0034 ///
0035 /// Each category gets its own RNTuple. Additionally, there is a podio_metadata
0036 /// RNTuple that contains metadata that is necessary for interpreting the files
0037 /// for reading.
0038 ///
0039 /// Files written with the RNTupleWriter can be read with the RNTupleReader.
0040 class RNTupleWriter {
0041 public:
0042   /// Create a RNTupleWriter to write to a file.
0043   ///
0044   /// @note Existing files will be overwritten without warning.
0045   ///
0046   /// @param filename The path to the file that will be created.
0047   RNTupleWriter(const std::string& filename);
0048 
0049   /// RNTupleWriter destructor
0050   ///
0051   /// This also takes care of writing all the necessary metadata in order to be
0052   /// able to read files back again.
0053   ~RNTupleWriter();
0054 
0055   /// The RNTupleWriter is not copy-able
0056   RNTupleWriter(const RNTupleWriter&) = delete;
0057   /// The RNTupleWriter is not copy-able
0058   RNTupleWriter& operator=(const RNTupleWriter&) = delete;
0059 
0060   /// Store the given frame with the given category.
0061   ///
0062   /// This stores all available collections from the Frame.
0063   ///
0064   /// @note The contents of the first Frame that is written in this way
0065   /// determines the contents that will be written for all subsequent Frames.
0066   ///
0067   /// @param frame    The Frame to store
0068   /// @param category The category name under which this Frame should be stored
0069   void writeFrame(const podio::Frame& frame, const std::string& category);
0070 
0071   /// Store the given Frame with the given category.
0072   ///
0073   /// This stores only the desired collections and not the complete frame.
0074   ///
0075   /// @note The contents of the first Frame that is written in this way
0076   /// determines the contents that will be written for all subsequent Frames.
0077   ///
0078   /// @param frame        The Frame to store
0079   /// @param category     The category name under which this Frame should be
0080   ///                     stored
0081   /// @param collsToWrite The collection names that should be written
0082   void writeFrame(const podio::Frame& frame, const std::string& category, const std::vector<std::string>& collsToWrite);
0083 
0084   /// Write the current file, including all the necessary metadata to read it
0085   /// again.
0086   ///
0087   /// @note The destructor will also call this, so letting a RNTupleWriter go out
0088   /// of scope is also a viable way to write a readable file
0089   void finish();
0090 
0091   /// Check whether the collsToWrite are consistent with the state of the passed
0092   /// category.
0093   ///
0094   /// @note This will only be a meaningful check if the first Frame of the passed
0095   /// category has already been written. Also, this check is rather expensive as
0096   /// it has to effectively do two set differences.
0097   ///
0098   ///
0099   /// @param collsToWrite The collection names that should be checked for
0100   ///                     consistency
0101   /// @param category     The category name for which consistency should be
0102   ///                     checked
0103   ///
0104   /// @returns two vectors of collection names. The first one contains all the
0105   /// names that were missing from the collsToWrite but were present in the
0106   /// category. The second one contains the names that are present in the
0107   /// collsToWrite only. If both vectors are empty the category and the passed
0108   /// collsToWrite are consistent.
0109   std::tuple<std::vector<std::string>, std::vector<std::string>>
0110   checkConsistency(const std::vector<std::string>& collsToWrite, const std::string& category) const;
0111 
0112 private:
0113   std::unique_ptr<root_compat::RNTupleModel> createModels(const std::vector<root_utils::StoreCollection>& collections);
0114 
0115   /// Helper struct to group all the necessary information for one category.
0116   struct CategoryInfo {
0117     std::unique_ptr<root_compat::RNTupleWriter> writer{nullptr}; ///< The RNTupleWriter for this category
0118 
0119     /// Collection info for this category
0120     std::vector<root_utils::CollectionWriteInfo> collInfo{};
0121     std::vector<std::string> names{}; ///< The names of all collections to write
0122 
0123     // Storage for the keys & values of all the parameters of this category
0124     // (resp. at least the current entry)
0125     root_utils::ParamStorage<int> intParams{};
0126     root_utils::ParamStorage<float> floatParams{};
0127     root_utils::ParamStorage<double> doubleParams{};
0128     root_utils::ParamStorage<std::string> stringParams{};
0129   };
0130   CategoryInfo& getCategoryInfo(const std::string& category);
0131 
0132   template <typename T>
0133   void fillParams(const GenericParameters& params, CategoryInfo& catInfo, root_compat::REntry* entry);
0134 
0135   template <typename T>
0136   root_utils::ParamStorage<T>& getParamStorage(CategoryInfo& catInfo);
0137 
0138   std::unique_ptr<TFile> m_file{};
0139 
0140   DatamodelDefinitionCollector m_datamodelCollector{};
0141 
0142   std::unordered_map<std::string, CategoryInfo> m_categories{};
0143 };
0144 
0145 } // namespace podio
0146 
0147 #endif // PODIO_RNTUPLEWRITER_H