From b94cc639b884356b8eb43b017586d86ed513558a Mon Sep 17 00:00:00 2001 From: Thomas Madlener Date: Tue, 9 Apr 2024 10:21:28 +0200 Subject: [PATCH] [doc] Homogenize the format of the c++ docstrings and add more doxygen tags in some places (#574) * Improve and homogenize docstrings for the Frame * Improve and homogenize the docstrings for the ROOT / SIO readers & writers * Make internally used only fillParams private * Remove unimplemented public method * Homogenize the RNTuple reader/writer docstrings * Homogenize docstrings * Homogenize the docstrings for the legacy readers * Properly pass environment to sphinx * Use the @note tag for highlighting notes in documentation * Use Note tag also for python API doc * Fix a few more typos and param argument name mismatches * Add not about invalidating references to Frame destructor --------- Co-authored-by: Mateusz Jakub Fila <37295697+m-fila@users.noreply.github.com> Co-authored-by: Andre Sailer --- cmake/podioDoxygen.cmake | 4 +- doc/conf.py | 6 +- include/podio/CollectionBranches.h | 8 +- include/podio/CollectionBufferFactory.h | 68 +++--- include/podio/CollectionBuffers.h | 6 +- include/podio/DatamodelRegistry.h | 140 ++++++----- include/podio/Frame.h | 219 ++++++++++++------ include/podio/FrameCategories.h | 38 ++- include/podio/GenericParameters.h | 20 +- include/podio/RNTupleReader.h | 76 ++++-- include/podio/RNTupleWriter.h | 84 +++++-- include/podio/ROOTLegacyReader.h | 84 ++++--- include/podio/ROOTReader.h | 138 +++++------ include/podio/ROOTWriter.h | 96 +++++--- include/podio/RelationRange.h | 6 +- include/podio/SIOBlock.h | 42 ++-- include/podio/SIOFrameData.h | 18 +- include/podio/SIOLegacyReader.h | 70 +++--- include/podio/SIOReader.h | 60 +++-- include/podio/SIOWriter.h | 47 +++- include/podio/SchemaEvolution.h | 130 +++++------ include/podio/UserDataCollection.h | 31 ++- .../utilities/DatamodelRegistryIOHelpers.h | 42 ++-- include/podio/utilities/TypeHelpers.h | 164 +++++-------- podioVersion.in.h | 16 +- python/podio/frame.py | 10 +- 26 files changed, 910 insertions(+), 713 deletions(-) diff --git a/cmake/podioDoxygen.cmake b/cmake/podioDoxygen.cmake index c92e77883..2597a5daf 100644 --- a/cmake/podioDoxygen.cmake +++ b/cmake/podioDoxygen.cmake @@ -6,7 +6,9 @@ if(DOXYGEN_FOUND AND SPHINX_FOUND) add_custom_target(documentation COMMAND - ${CMAKE_COMMAND} -E env "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/src/:$ENV{LD_LIBRARY_PATH};ROOT_INCLUDE_PATH=${CMAKE_SOURCE_DIR}/include;" + ${CMAKE_COMMAND} -E env + "LD_LIBRARY_PATH=${CMAKE_BINARY_DIR}/src/:$ENV{LD_LIBRARY_PATH}" + "ROOT_INCLUDE_PATH=${CMAKE_SOURCE_DIR}/include:$ENV{ROOT_INCLUDE_PATH}" ${SPHINX_BUILD_EXECUTABLE} -M html ${CMAKE_SOURCE_DIR}/doc ${SPHINX_OUTPUT_DIRECTORY} COMMENT "Building documentation" VERBATIM diff --git a/doc/conf.py b/doc/conf.py index 7f0727036..afb0d83ec 100644 --- a/doc/conf.py +++ b/doc/conf.py @@ -146,7 +146,11 @@ "../python", "../*/*test_*.py", # exclude tests "../python/podio_version.py", # exclude convenience module - ] + ], + stdout=subprocess.PIPE, + stderr=subprocess.PIPE, + env=env, + cwd=doc_dir, ) print("Done with python API doc generation") diff --git a/include/podio/CollectionBranches.h b/include/podio/CollectionBranches.h index 9b20016aa..3ab3e8129 100644 --- a/include/podio/CollectionBranches.h +++ b/include/podio/CollectionBranches.h @@ -7,11 +7,9 @@ #include namespace podio::root_utils { -/** - * Small helper struct to collect all branches that are necessary to read or - * write a collection. Needed to cache the branch pointers and avoid having to - * get them from a TTree/TChain for every event. - */ +/// Small helper struct to collect all branches that are necessary to read or +/// write a collection. Needed to cache the branch pointers and avoid having to +/// get them from a TTree/TChain for every event. struct CollectionBranches { TBranch* data{nullptr}; std::vector refs{}; diff --git a/include/podio/CollectionBufferFactory.h b/include/podio/CollectionBufferFactory.h index 0e753775b..531e54150 100644 --- a/include/podio/CollectionBufferFactory.h +++ b/include/podio/CollectionBufferFactory.h @@ -11,20 +11,19 @@ namespace podio { -/** - * The CollectionBufferFactory allows to create buffers of known datatypes, - * which can then be populated by e.g. readers. In order to support schema - * evolution, the buffers have a version and this factory will also require a - * schema version to create buffers. - * - * It is implemented as a singleton, which is populated at the time a shared - * datamodel library is loaded. It is assumed that that happens early on in the - * startup of an application, such that only a single thread will access the - * factory instance for registering datatypes. Since the necessary creation - * functions are part of the core datamodel library, this should be very easy to - * achieve by simply linking to that library. Once the factory is populated it - * can be safely accessed from multiple threads concurrently to obtain buffers. - */ +/// The CollectionBufferFactory allows one to create buffers of known datatypes, +/// which can then be populated by e.g. readers. In order to support schema +/// evolution, the buffers have a version and this factory will also require a +/// schema version to create buffers. +/// +/// It is implemented as a singleton, which is populated at the time a shared +/// datamodel library is loaded. It is assumed that that happens early on in the +/// startup of an application, such that only a single thread will access the +/// factory instance for registering datatypes. Since the necessary creation +/// functions are part of the core datamodel library, this should be very easy +/// to achieve by simply linking to that library. Once the factory is populated +/// it can be safely accessed from multiple threads concurrently to obtain +/// buffers. class CollectionBufferFactory { /// Internal storage is a map to an array of creation functions, where the /// version determines the place in that array. This should be a viable @@ -48,29 +47,28 @@ class CollectionBufferFactory { /// Get the factory instance static CollectionBufferFactory const& instance(); - /** - * Create buffers for a given collection type of a given schema version. - * - * @param collType The collection type name (e.g. from collection->getTypeName()) - * @param version The schema version the created buffers should have - * @param subsetColl Should the buffers be for a subset collection or not - * - * @return CollectionReadBuffers if a creation function for this collection - * type has been registered, otherwise an empty optional - */ + /// Create buffers for a given collection type of a given schema version. + /// + /// @param collType The collection type name (e.g. from collection->getTypeName()) + /// @param version The schema version the created buffers should have + /// @param subsetColl Should the buffers be for a subset collection or not + /// + /// @return CollectionReadBuffers if a creation function for this collection + /// type has been registered, otherwise an empty optional std::optional createBuffers(const std::string& collType, SchemaVersionT version, bool subsetColl) const; - /** - * Register a creation function for a given collection type and schema version. - * - * @param collType The collection type name (i.e. what - * collection->getTypeName() returns) - * @param version The schema version for which this creation function is valid - * @param creationFunc The function that when invoked returns buffers for this - * collection type and schema version. The signature has to be - * podio::CollectionReadBuffers(bool) where the boolean parameter steers - * whether the buffers are for a subset collection or not. - */ + /// Register a creation function for a given collection type and schema version. + /// + /// @param collType The collection type name (i.e. what + /// collection->getTypeName() returns) + /// @param version The schema version for which this creation function is + /// valid + /// @param creationFunc The function that when invoked returns buffers for + /// this collection type and schema version. The + /// signature has to be + /// podio::CollectionReadBuffers(bool) where the boolean + /// parameter steers whether the buffers are for a subset + /// collection or not. void registerCreationFunc(const std::string& collType, SchemaVersionT version, const CreationFuncT& creationFunc); private: diff --git a/include/podio/CollectionBuffers.h b/include/podio/CollectionBuffers.h index 834c465c9..d761c3916 100644 --- a/include/podio/CollectionBuffers.h +++ b/include/podio/CollectionBuffers.h @@ -21,10 +21,8 @@ using UVecPtr = std::unique_ptr>; using CollRefCollection = std::vector>; using VectorMembersInfo = std::vector>; -/** - * Simple helper struct that bundles all the potentially necessary buffers that - * are necessary to represent a collection for I/O purposes. - */ +/// Simple helper struct that bundles all the potentially necessary buffers that +/// are necessary to represent a collection for I/O purposes. struct CollectionWriteBuffers { void* data{nullptr}; void* vecPtr{nullptr}; diff --git a/include/podio/DatamodelRegistry.h b/include/podio/DatamodelRegistry.h index 2d642c118..cbfa294cd 100644 --- a/include/podio/DatamodelRegistry.h +++ b/include/podio/DatamodelRegistry.h @@ -10,25 +10,21 @@ namespace podio { -/** - * Type alias for storing the names of all Relations and VectorMembers for all - * datatypes of an EDM. Populated for each EDM at code generation time. - * The structure is of each element in the outer vector is: - * - get<0>: The name of the datatype - * - get<1>: The names of all Relations, where OneToManyRelations comes before - * OneToOneRelations (in the order as they appear in the YAML file) - * - get<2>: The names of all VectorMembers (in the order of the file YAML) - */ +/// Type alias for storing the names of all Relations and VectorMembers for all +/// datatypes of an EDM. Populated for each EDM at code generation time. +/// The structure is of each element in the outer vector is: +/// - get<0>: The name of the datatype +/// - get<1>: The names of all Relations, where OneToManyRelations comes before +/// OneToOneRelations (in the order as they appear in the YAML file) +/// - get<2>: The names of all VectorMembers (in the order of the file YAML) using RelationNameMapping = std::vector, std::vector>>; -/** - * Information on the names of the OneTo[One|Many]Relations as well as the - * VectorMembers of a datatype - * - * The contents are populated by the code generation, where we simply generate - * static vectors that we make available as const& here. - */ +/// Information on the names of the OneTo[One|Many]Relations as well as the +/// VectorMembers of a datatype +/// +/// The contents are populated by the code generation, where we simply generate +/// static vectors that we make available as const& here. struct RelationNames { /// The names of the relations (OneToMany before OneToOne) const std::vector& relations; @@ -36,20 +32,18 @@ struct RelationNames { const std::vector& vectorMembers; }; -/** - * Global registry holding information about datamodels and datatypes defined - * therein that are currently known by podio (i.e. which have been dynamically - * loaded). - * - * This is a singleton which is (statically) populated during dynamic loading of - * generated EDMs. In this context an **EDM refers to the shared library** that - * is compiled from the generated code from a datamodel definition in YAML - * format. When we refer to a **datamodel** in this context we talk about the - * entity as a whole, i.e. its definition in a YAML file, but also the concrete - * implementation as an EDM, as well as all other information that is related to - * it. In the API of this registry this will be used, unless we want to - * highlight that we are referring to a specific part of a datamodel. - */ +/// Global registry holding information about datamodels and datatypes defined +/// therein that are currently known by podio (i.e. which have been dynamically +/// loaded). +/// +/// This is a singleton which is (statically) populated during dynamic loading +/// of generated EDMs. In this context an **EDM refers to the shared library** +/// that is compiled from the generated code from a datamodel definition in YAML +/// format. When we refer to a **datamodel** in this context we talk about the +/// entity as a whole, i.e. its definition in a YAML file, but also the concrete +/// implementation as an EDM, as well as all other information that is related +/// to it. In the API of this registry this will be used, unless we want to +/// highlight that we are referring to a specific part of a datamodel. class DatamodelRegistry { public: /// Get the registry @@ -70,59 +64,57 @@ class DatamodelRegistry { /// Dedicated index value for error checking, used to default init the generated RegistryIndex static constexpr size_t NoDefinitionAvailable = -2; - /** - * Get the definition (in JSON format) of the datamodel with the given - * edmName. - * - * If no datamodel with the given name can be found, an empty datamodel - * definition, i.e. an empty JSON object ("{}"), is returned. - * - * @param name The name of the datamodel - */ + /// Get the definition (in JSON format) of the datamodel with the given + /// edmName. + /// + /// If no datamodel with the given name can be found, an empty datamodel + /// definition, i.e. an empty JSON object ("{}"), is returned. + /// + /// @param name The name of the datamodel + /// + /// @returns The high level definition of the datamodel in JSON format const std::string_view getDatamodelDefinition(std::string_view name) const; - /** - * Get the definition (in JSON format) of the datamodel with the given index. - * - * If no datamodel is found under the given index, an empty datamodel - * definition, i.e. an empty JSON object ("{}"), is returned. - * - * @param index The datamodel definition index that can be obtained from each - * collection - */ + /// Get the definition (in JSON format) of the datamodel with the given + /// index. + /// + /// If no datamodel is found under the given index, an empty datamodel + /// definition, i.e. an empty JSON object ("{}"), is returned. + /// + /// @param index The datamodel definition index that can be obtained from each + /// collection + /// + /// @returns The high level definition of the datamodel in JSON format const std::string_view getDatamodelDefinition(size_t index) const; - /** - * Get the name of the datamodel that is stored under the given index. - * - * If no datamodel is found under the given index, an empty string is returned - * - * @param index The datamodel definition index that can be obtained from each - * collection - */ + /// Get the name of the datamodel that is stored under the given index. + /// + /// If no datamodel is found under the given index, an empty string is returned + /// + /// @param index The datamodel definition index that can be obtained from each + /// collection + /// + /// @returns The name of the datamodel const std::string& getDatamodelName(size_t index) const; - /** - * Register a datamodel return the index in the registry. - * - * This is the hook that is called during dynamic loading of an EDM to - * register information for this EDM. If an EDM has already been registered - * under this name, than the index to the existing EDM in the registry will be - * returned. - * - * @param name The name of the EDM that should be registered - * @param definition The datamodel definition from which this EDM has been - * generated in JSON format - * @param relationNames the names of the relations and vector members for all - * datatypes that are defined for this EDM - * - */ + /// Register a datamodel and return its index in the registry. + /// + /// This is the hook that is called during dynamic loading of an EDM to + /// register information for this EDM. If an EDM has already been registered + /// under this name, than the index to the existing EDM in the registry will be + /// returned. + /// + /// @param name The name of the EDM that should be registered + /// @param definition The datamodel definition from which this EDM has been + /// generated in JSON format + /// @param relationNames the names of the relations and vector members for all + /// datatypes that are defined for this EDM + /// + /// @returns The index of this datamodel in the registry size_t registerDatamodel(std::string name, std::string_view definition, const podio::RelationNameMapping& relationNames); - /** - * Get the names of the relations and vector members of a datatype - */ + /// Get the names of the relations and vector members of a datatype RelationNames getRelationNames(std::string_view typeName) const; private: diff --git a/include/podio/Frame.h b/include/podio/Frame.h index e41137923..d7b712703 100644 --- a/include/podio/Frame.h +++ b/include/podio/Frame.h @@ -36,25 +36,23 @@ template using EnableIfRValue = typename std::enable_if_t>; namespace detail { - /** The minimal interface for raw data types - */ + /// The minimal interface for raw data types struct EmptyFrameData { podio::CollectionIDTable getIDTable() const { return {}; } + /// Try to get the buffers for a collection std::optional getCollectionBuffers(const std::string&) { return std::nullopt; } - /** Get the still available, i.e. yet unpacked, collections from the raw data - */ + /// Get the **still available**, i.e. yet unpacked, collections from the raw data std::vector getAvailableCollections() const { return {}; } - /** Get the parameters that are stored in the raw data - */ + /// Get the parameters that are stored in the raw data std::unique_ptr getParameters() { return std::make_unique(); } @@ -66,14 +64,14 @@ std::optional unpack(FrameDataT* data, const std:: return data->getCollectionBuffers(name); } -/** - * Frame class that serves as a container of collection and meta data. - */ +/// The Frame is a generalized (event) data container that aggregates all +/// relevant data. +/// +/// It is possible to store collections as well as parameters / meta data in a +/// Frame and all I/O facilities of podio operate on Frames. class Frame { - /** - * Internal abstract interface for the type-erased implementation of the Frame - * class - */ + /// Internal abstract interface for the type-erased implementation of the + /// Frame class struct FrameConcept { virtual ~FrameConcept() = default; virtual const podio::CollectionBase* get(const std::string& name) const = 0; @@ -88,10 +86,8 @@ class Frame { virtual podio::CollectionIDTable getIDTable() const = 0; }; - /** - * The interface implementation of the abstract FrameConcept that is necessary - * for a type-erased implementation of the Frame class - */ + /// The interface implementation of the abstract FrameConcept that is + /// necessary for a type-erased implementation of the Frame class template struct FrameModel final : FrameConcept, public ICollectionProvider { @@ -102,24 +98,20 @@ class Frame { FrameModel(FrameModel&&) = default; FrameModel& operator=(FrameModel&&) = default; - /** Try and get the collection from the internal storage and return a - * pointer to it if found. Otherwise return a nullptr - */ + /// Try and get the collection from the internal storage and return a + /// pointer to it if found. Otherwise return a nullptr const podio::CollectionBase* get(const std::string& name) const final; - /** Try and place the collection into the internal storage and return a - * pointer to it. If a collection already exists or insertion fails, return - * a nullptr - */ + /// Try and place the collection into the internal storage and return a + /// pointer to it. If a collection already exists or insertion fails, return + /// a nullptr const podio::CollectionBase* put(std::unique_ptr coll, const std::string& name) final; - /** Get a reference to the internally used GenericParameters - */ + /// Get a reference to the internally used GenericParameters podio::GenericParameters& parameters() override { return *m_parameters; } - /** Get a const reference to the internally used GenericParameters - */ + /// Get a const reference to the internally used GenericParameters const podio::GenericParameters& parameters() const override { return *m_parameters; }; @@ -151,117 +143,186 @@ class Frame { std::unique_ptr m_self; ///< The internal concept pointer through which all the work is done public: - /** Empty Frame constructor - */ + /// Empty Frame constructor Frame(); - /** Frame constructor from (almost) arbitrary raw data - */ + /// Frame constructor from (almost) arbitrary raw data. + /// + /// @tparam FrameDataT Arbitrary data container that provides access to the + /// collection buffers as well as the metadata, when + /// requested by the Frame. template Frame(std::unique_ptr); - /** Frame constructor from (almost) arbitrary raw data. - * - * This r-value overload is mainly present for enabling the python bindings, - * where cppyy seems to strip the std::unique_ptr somewhere in the process - */ + /// Frame constructor from (almost) arbitrary raw data. + /// + /// This r-value overload is mainly present for enabling the python bindings, + /// where cppyy seems to strip the std::unique_ptr somewhere in the process + /// + /// @tparam FrameDataT Arbitrary data container that provides access to the + /// collection buffers as well as the metadata, when + /// requested by the Frame. template > Frame(FrameDataT&&); - // The frame is a non-copyable type + /// A Frame is move-only Frame(const Frame&) = delete; + /// A Frame is move-only Frame& operator=(const Frame&) = delete; + /// Frame move constructor Frame(Frame&&) = default; + + /// Frame move assignment operator Frame& operator=(Frame&&) = default; - /** Frame destructor */ + /// Frame destructor + /// + /// @note Since the Frame owns all the collections that have been put into it, + /// or that can be obtained from it, this invalidates all references to these + /// collections. ~Frame() = default; - /** Get a collection from the Frame - */ + /// Get a collection from the Frame by name. + /// + /// @tparam CollT The type of the desired collection + /// @param name The name of the collection + /// + /// @returns A const reference to the collection if it is available or to + /// an empty (static) collection template > const CollT& get(const std::string& name) const; - /** Get a collection from the Frame. This is the pointer-to-base version for - * type-erased access (e.g. python interface) - */ + /// Get a collection pointer from the Frame by name. + /// + /// This is a type-erased version that is also used by the python bindings. + /// + /// @returns A const pointer to a collection if it is available or a nullptr + /// if it is not const podio::CollectionBase* get(const std::string& name) const; - /** (Destructively) move a collection into the Frame and get a const reference - * back for further use - */ + /// (Destructively) move a collection into the Frame and get a reference to + /// the inserted collection back for further use. + /// + /// The collection that is passed into the Frame has to be moved into it + /// explicitly and the moved-from collection will be in the typical *valid but + /// undefined state* in c++. + /// + /// @tparam CollT The type of the collection + /// @param coll An rvalue reference to the collection to put into the Frame. + /// @param name The name under which this collection should be stored in the + /// Frame + /// + /// @returns A const reference to the collection that has just been + /// inserted template > const CollT& put(CollT&& coll, const std::string& name); - /** Move a collection into the Frame handing over ownership to the Frame - */ + /// (Destructively) move a collection into the Frame. + /// + /// @param coll The collection that should be moved into the Frame + /// @param name The name under which this collection should be stored in the + /// Frame void put(std::unique_ptr coll, const std::string& name); - /** Add a value to the parameters of the Frame (if the type is supported). - * Copy the value into the internal store - */ + /// Add a value to the parameters of the Frame (if the type is supported). + /// + /// @tparam T The type of the parameter. Has to be one of the types that + /// is supported by GenericParameters + /// @param key The name under which this parameter should be stored + /// @param value The value of the parameter. A copy will be put into the Frame template > inline void putParameter(const std::string& key, T value) { m_self->parameters().setValue(key, std::move(value)); } - /** Add a string value to the parameters of the Frame by copying it. Dedicated - * overload for enabling the on-the-fly conversion on the string literals. - */ + /// Add a string value to the parameters of the Frame. + /// + /// This is a dedicated overload for enabling on-the-fly conversion from + /// string literals. + /// + /// @param key The name under which this parameter should be stored + /// @param value The value of the parameter. A copy will be put into the Frame inline void putParameter(const std::string& key, std::string value) { putParameter(key, std::move(value)); } - /** Add a vector of strings to the parameters of the Frame (via copy). - * Dedicated overload for enabling on-the-fly conversions of initializer_list - * of string literals. - */ + /// Add a vector of strings value the parameters of the Frame. + /// + /// This is a dedicated overload for enabling on-the-fly conversion from + /// an initializer_list of string literals + /// + /// @param key The name under which this parameter should be stored + /// @param values The values of the parameter. A copy will be put into the Frame inline void putParameter(const std::string& key, std::vector values) { putParameter>(key, std::move(values)); } - /** Add a vector of values into the parameters of the Frame. Overload for - * catching on-the-fly conversions of initializer_lists of values. - */ + /// Add a vector of values to the parameters of the Frame (if the type is + /// supported). + /// + /// This is a dedicated overload for enabling on-the-fly conversions of + /// initializer_list of values + /// + /// @tparam T The type of the parameter. Has to be one of the types that + /// is supported by GenericParameters + /// @param key The name under which this parameter should be stored + /// @param values The values of the parameter. A copy will be put into the Frame template >> inline void putParameter(const std::string& key, std::initializer_list&& values) { putParameter>(key, std::move(values)); } - /** Retrieve parameters via key from the internal store. Return type will - * either by a const reference or a value depending on the desired type. - */ + /// Retrieve parameters via key from the internal store. + /// + /// The return type will either be a const reference or a value depending on + /// the desired type. See podio::GenericParameters for more details. + /// + /// @tparam T The desired type of the parameter (can also be std::vector) + /// @param key The key under which the value is stored + /// + /// @returns The value of the parameter or an empty default value template > inline podio::GenericDataReturnType getParameter(const std::string& key) const { return m_self->parameters().getValue(key); } - /** Get all parameters that are stored in this Frame - */ + /// Retrieve all parameters stored in this Frame. + /// + /// This is mainly intended for I/O purposes and we encourage to use the Frame + /// functionality of getParameters or getParameterKeys in general. + /// + /// @returns The internally used GenericParameters inline const podio::GenericParameters& getParameters() const { return m_self->parameters(); } - /** Get the keys of all stored parameters for a given type - */ + /// Get the keys of all stored parameters for a given type + /// + /// @tparam T The desired parameter type + /// + /// @returns A vector of keys for this parameter type template > inline std::vector getParameterKeys() const { return m_self->parameters().getKeys(); } - /** Get all **currently** available collections (including potentially - * unpacked ones from raw data) - */ + /// Get all **currently** available collection names. + /// + /// @returns The names of all collections, including those that might still + /// need unpacking from the internal FrameData std::vector getAvailableCollections() const { return m_self->availableCollections(); } // Interfaces for writing below - // TODO: Hide this from the public interface somehow? - /** - * Get a collection for writing (in a prepared and "ready-to-write" state) - */ + + /// Get a collection for writing. + /// + /// @note This method is intended for I/O purposes only and should not be used + /// in other code. + /// + /// @returns The collection pointer in a prepared and "ready-to-write" state const podio::CollectionBase* getCollectionForWrite(const std::string& name) const { const auto* coll = m_self->get(name); if (coll) { @@ -271,6 +332,12 @@ class Frame { return coll; } + /// Get the internal CollectionIDTable for writing. + /// + /// @note This method is intended for I/O purposes only and should not be used + /// in other code. + /// + /// @returns A copy of the internal collection id table podio::CollectionIDTable getCollectionIDTableForWrite() const { return m_self->getIDTable(); } diff --git a/include/podio/FrameCategories.h b/include/podio/FrameCategories.h index 80f16a8fb..30237fe7f 100644 --- a/include/podio/FrameCategories.h +++ b/include/podio/FrameCategories.h @@ -5,37 +5,33 @@ namespace podio { -/** - * Create a parameterName that encodes the collection name and the parameter - * Name into one string. - * - * This codifies a convention that was decided on to store collection level - * parameters. These are parameters / metadata that are valid for all - * collections of a given name in a file, e.g. CellID encoding strings. These - * parameters are usually stored in a dedicated metadata Frame inside a file, - * see the predefined category names in the Category namespace. - * - * @param collName the name of the collection - * @param paramName the name of the parameter - * - * @returns A single key string that combines the collection and parameter name - */ +/// Create a parameterName that encodes the collection name and the parameter +/// Name into one string. +/// +/// This codifies a convention that was decided on to store collection level +/// parameters. These are parameters / metadata that are valid for all +/// collections of a given name in a file, e.g. CellID encoding strings. These +/// parameters are usually stored in a dedicated metadata Frame inside a file, +/// see the predefined category names in the Category namespace. +/// +/// @param collName the name of the collection +/// @param paramName the name of the parameter +/// +/// @returns A single key string that combines the collection and parameter name inline std::string collMetadataParamName(const std::string& collName, const std::string& paramName) { return collName + "__" + paramName; } -/** - * This namespace mimics an enum (at least in its usage) and simply defines - * either commonly used category names, or category names that form a - * convention. - */ +/// This namespace mimics an enum (at least in its usage) and simply defines +/// either commonly used category names, or category names that form a +/// convention. namespace Category { /// The event category constexpr const auto Event = "events"; /// The run category constexpr const auto Run = "runs"; /// The metadata category that is used to store a single Frame that holds data - /// that is valid for a whole file, e.g. collection level parameters + /// that is valid for a whole file, for example collection level parameters constexpr const auto Metadata = "metadata"; } // namespace Category } // namespace podio diff --git a/include/podio/GenericParameters.h b/include/podio/GenericParameters.h index b82a7869e..3e1700549 100644 --- a/include/podio/GenericParameters.h +++ b/include/podio/GenericParameters.h @@ -66,16 +66,14 @@ namespace detail { template using GenericDataReturnType = typename detail::GenericDataReturnTypeHelper::type; -/** GenericParameters objects allow to store generic named parameters of type - * int, float and string or vectors of these types. - * They can be used to store (user) meta data that is - * run, event or collection dependent. - * (based on lcio::LCParameters) - * - * @author F. Gaede, DESY - * @date Apr 2020 - */ - +/// GenericParameters objects allow one to store generic named parameters of type +/// int, float and string or vectors of these types. +/// They can be used to store (user) meta data that is +/// run, event or collection dependent. +/// (based on lcio::LCParameters) +/// +/// @author F. Gaede, DESY +/// @date Apr 2020 class GenericParameters { public: template @@ -89,7 +87,7 @@ class GenericParameters { GenericParameters(); /// GenericParameters are copyable - /// NOTE: This is currently mainly done to keep the ROOT I/O happy, because + /// @note This is currently mainly done to keep the ROOT I/O happy, because /// that needs a copy constructor GenericParameters(const GenericParameters&); GenericParameters& operator=(const GenericParameters&) = delete; diff --git a/include/podio/RNTupleReader.h b/include/podio/RNTupleReader.h index 9eecfce58..1cffa149f 100644 --- a/include/podio/RNTupleReader.h +++ b/include/podio/RNTupleReader.h @@ -26,55 +26,95 @@ namespace podio { This class has the function to read available data from disk and to prepare collections and buffers. **/ +/// The RNTupleReader can be used to read files that have been written with the +/// RNTuple backend. +/// +/// The RNTupleReader provides the data as ROOTFrameData from which a podio::Frame +/// can be constructed. It can be used to read files written by the RNTupleWriter. class RNTupleReader { public: + /// Create a RNTupleReader RNTupleReader() = default; + /// Destructor ~RNTupleReader() = default; - + /// The RNTupleReader is not copy-able RNTupleReader(const RNTupleReader&) = delete; + /// The RNTupleReader is not copy-able RNTupleReader& operator=(const RNTupleReader&) = delete; + /// Open a single file for reading. + /// + /// @param filename The name of the input file void openFile(const std::string& filename); - void openFiles(const std::vector& filename); - /** - * Read the next data entry from which a Frame can be constructed for the - * given name. In case there are no more entries left for this name or in - * case there is no data for this name, this returns a nullptr. - */ + /// Open multiple files for reading and then treat them as if they are one file + /// + /// @note All of the files are assumed to have the same structure. Specifically + /// this means: + /// - The same categories are available from all files + /// - The collections that are contained in the individual categories are the + /// same across all files + /// - This usually boils down to "the files have been written with the same + /// "settings", e.g. they are outputs of a batched process. + /// + /// @param filenames The filenames of all input files that should be read + void openFiles(const std::vector& filenames); + + /// Read the next data entry for a given category. + /// + /// @param name The category name for which to read the next entry + /// + /// @returns FrameData from which a podio::Frame can be constructed if the + /// category exists and if there are still entries left to read. + /// Otherwise a nullptr std::unique_ptr readNextEntry(const std::string& name); - /** - * Read the specified data entry from which a Frame can be constructed for - * the given name. In case the entry does not exist for this name or in case - * there is no data for this name, this returns a nullptr. - */ + /// Read the desired data entry for a given category. + /// + /// @param name The category name for which to read the next entry + /// @param entry The entry number to read + /// + /// @returns FrameData from which a podio::Frame can be constructed if the + /// category and the desired entry exist. Otherwise a nullptr std::unique_ptr readEntry(const std::string& name, const unsigned entry); - /// Get the names of all the available Frame categories in the current file(s) + /// Get the names of all the available Frame categories in the current file(s). + /// + /// @returns The names of the available categores from the file std::vector getAvailableCategories() const; - /// Returns number of entries for the given name + /// Get the number of entries for the given name + /// + /// @param name The name of the category + /// + /// @returns The number of entries that are available for the category unsigned getEntries(const std::string& name); - /// Get the build version of podio that has been used to write the current file + /// Get the build version of podio that has been used to write the current + /// file + /// + /// @returns The podio build version podio::version::Version currentFileVersion() const { return m_fileVersion; } /// Get the datamodel definition for the given name + /// + /// @param name The name of the datamodel + /// + /// @returns The high level definition of the datamodel in JSON format const std::string_view getDatamodelDefinition(const std::string& name) const { return m_datamodelHolder.getDatamodelDefinition(name); } - /// Get all names of the datamodels that ara available from this reader + /// Get all names of the datamodels that are available from this reader + /// + /// @returns The names of the datamodels std::vector getAvailableDatamodels() const { return m_datamodelHolder.getAvailableDatamodels(); } - void closeFile(); - private: /** * Initialize the given category by filling the maps with metadata information diff --git a/include/podio/RNTupleWriter.h b/include/podio/RNTupleWriter.h index 83beeb7c5..ed0f3012c 100644 --- a/include/podio/RNTupleWriter.h +++ b/include/podio/RNTupleWriter.h @@ -21,38 +21,90 @@ namespace podio { +/// The RNTupleWriter writes podio files into ROOT files using the new RNTuple +/// format. +/// +/// Each category gets its own RNTuple. Additionally, there is a podio_metadata +/// RNTuple that contains metadata that is necessary for interpreting the files +/// for reading. +/// +/// Files written with the RNTupleWriter can be read with the RNTupleReader. class RNTupleWriter { public: + /// Create a RNTupleWriter to write to a file. + /// + /// @note Existing files will be overwritten without warning. + /// + /// @param filename The path to the file that will be created. RNTupleWriter(const std::string& filename); + + /// RNTupleWriter destructor + /// + /// This also takes care of writing all the necessary metadata in order to be + /// able to read files back again. ~RNTupleWriter(); + /// The RNTupleWriter is not copy-able RNTupleWriter(const RNTupleWriter&) = delete; + /// The RNTupleWriter is not copy-able RNTupleWriter& operator=(const RNTupleWriter&) = delete; - template - void fillParams(GenericParameters& params, ROOT::Experimental::REntry* entry); - + /// Store the given frame with the given category. + /// + /// This stores all available collections from the Frame. + /// + /// @note The contents of the first Frame that is written in this way + /// determines the contents that will be written for all subsequent Frames. + /// + /// @param frame The Frame to store + /// @param category The category name under which this Frame should be stored void writeFrame(const podio::Frame& frame, const std::string& category); + + /// Store the given Frame with the given category. + /// + /// This stores only the desired collections and not the complete frame. + /// + /// @note The contents of the first Frame that is written in this way + /// determines the contents that will be written for all subsequent Frames. + /// + /// @param frame The Frame to store + /// @param category The category name under which this Frame should be + /// stored + /// @param collsToWrite The collection names that should be written void writeFrame(const podio::Frame& frame, const std::string& category, const std::vector& collsToWrite); + + /// Write the current file, including all the necessary metadata to read it + /// again. + /// + /// @note The destructor will also call this, so letting a RNTupleWriter go out + /// of scope is also a viable way to write a readable file void finish(); - /** Check whether the collsToWrite are consistent with the state of the passed - * category. - * - * Return two vectors of collection names. The first one contains all the - * names that were missing from the collsToWrite but were present in the - * category. The second one contains the names that are present in the - * collsToWrite only. If both vectors are empty the category and the passed - * collsToWrite are consistent. - * - * NOTE: This will only be a meaningful check if the first Frame of the passed - * category has already been written. Also, this check is rather expensive as - * it has to effectively do two set differences. - */ + /// Check whether the collsToWrite are consistent with the state of the passed + /// category. + /// + /// @note This will only be a meaningful check if the first Frame of the passed + /// category has already been written. Also, this check is rather expensive as + /// it has to effectively do two set differences. + /// + /// + /// @param collsToWrite The collection names that should be checked for + /// consistency + /// @param category The category name for which consistency should be + /// checked + /// + /// @returns two vectors of collection names. The first one contains all the + /// names that were missing from the collsToWrite but were present in the + /// category. The second one contains the names that are present in the + /// collsToWrite only. If both vectors are empty the category and the passed + /// collsToWrite are consistent. std::tuple, std::vector> checkConsistency(const std::vector& collsToWrite, const std::string& category) const; private: + template + void fillParams(GenericParameters& params, ROOT::Experimental::REntry* entry); + using StoreCollection = std::pair; std::unique_ptr createModels(const std::vector& collections); diff --git a/include/podio/ROOTLegacyReader.h b/include/podio/ROOTLegacyReader.h index 9600e046a..c379eea1c 100644 --- a/include/podio/ROOTLegacyReader.h +++ b/include/podio/ROOTLegacyReader.h @@ -34,57 +34,81 @@ class CollectionIDTable; class GenericParameters; struct CollectionReadBuffers; -/** - * A root reader for reading legacy podio root files that have been written - * using the legacy, non Frame based I/O model. This reader grants Frame based - * access to those files, by mimicking the Frame I/O functionality and the - * interfaces of those readers. - * - * NOTE: Since there was only one category ("events") for those legacy podio - * files this reader will really only work if you try to read that category, and - * will simply return no data if you try to read anything else. - */ +/// A root reader for reading legacy podio root files that have been written +/// using the legacy, non Frame based I/O model. This reader grants Frame based +/// access to those files, by mimicking the Frame I/O functionality and the +/// interfaces of those readers. +/// +/// @note Since there was only one category ("events") for those legacy podio +/// files this reader will really only work if you try to read that category, and +/// will simply return no data if you try to read anything else. class ROOTLegacyReader { public: + /// Create a SIOLegacyReader ROOTLegacyReader() = default; + /// Destructor ~ROOTLegacyReader() = default; - // non-copyable + /// The SIOLegacyReader is not copy-able ROOTLegacyReader(const ROOTLegacyReader&) = delete; + /// The SIOLegacyReader is not copy-able ROOTLegacyReader& operator=(const ROOTLegacyReader&) = delete; + /// Open a single file for reading. + /// + /// @param filename The name of the input file void openFile(const std::string& filename); + /// Open multiple files for reading and then treat them as if they are one file + /// + /// @note All of the files are assumed to have the same structure. Specifically + /// this means: + /// - The collections that are contained in the individual event are always the + /// same + /// + /// This usually boils down to "the files have been written with the same + /// "settings", e.g. they are outputs of a batched process. + /// + /// @param filenames The filenames of all input files that should be read void openFiles(const std::vector& filenames); - /** - * Read the next data entry from which a Frame can be constructed. In case - * there are no more entries left, this returns a nullptr. - * - * NOTE: the category name has to be "events" in this case, as only that - * category is available for legacy files. - */ + /// Read the next data entry from which a Frame can be constructed. + /// + /// @note the category name has to be "events" in this case, as only that + /// category is available for legacy files. + /// + /// @returns FrameData from which a podio::Frame can be constructed if there + /// are still entries left to read. Otherwise a nullptr std::unique_ptr readNextEntry(const std::string&); - /** - * Read the specified data entry from which a Frame can be constructed In case - * the entry does not exist, this returns a nullptr. - * - * NOTE: the category name has to be "events" in this case, as only that - * category is available for legacy files. - */ + /// Read the desired data entry from which a Frame can be constructed. + /// + /// @note the category name has to be "events" in this case, as only that + /// category is available for legacy files. + /// + /// @returns FrameData from which a podio::Frame can be constructed if the + /// desired entry exists. Otherwise a nullptr std::unique_ptr readEntry(const std::string&, const unsigned entry); - /// Returns number of entries for a given category - unsigned getEntries(const std::string&) const; - - /// Get the build version of podio that has been used to write the current file + /// Get the number of entries for the given name + /// + /// @param name The name of the category + /// + /// @returns The number of entries that are available for the category + unsigned getEntries(const std::string& name) const; + + /// Get the build version of podio that has been used to write the current + /// file + /// + /// @returns The podio build version podio::version::Version currentFileVersion() const { return m_fileVersion; } - /// Get the names of all the available Frame categories in the current file(s) + /// Get the names of all the available Frame categories in the current file(s). + /// + /// @returns The names of the available categories from the file std::vector getAvailableCategories() const; private: diff --git a/include/podio/ROOTReader.h b/include/podio/ROOTReader.h index e41753a74..b14a08d17 100644 --- a/include/podio/ROOTReader.h +++ b/include/podio/ROOTReader.h @@ -36,86 +36,102 @@ class CollectionIDTable; class GenericParameters; struct CollectionReadBuffers; -/** - * This class has the function to read available data from disk - * and to prepare collections and buffers. - **/ +/// This class has the function to read available data from disk in ROOTs TTree +/// format. +/// +/// The ROOTReader provides the data as ROOTFrameData from which a podio::Frame +/// can be constructed. It can be used to read files written by the ROOTWriter. class ROOTReader { public: + /// Create a ROOTReader ROOTReader() = default; + /// Destructor ~ROOTReader() = default; - // non-copyable + /// The ROOTReader is not copy-able ROOTReader(const ROOTReader&) = delete; + /// The ROOTReader is not copy-able ROOTReader& operator=(const ROOTReader&) = delete; - /** - * Open a single file for reading. - * - * @param filename The name of the input file - */ + /// Open a single file for reading. + /// + /// @param filename The name of the input file void openFile(const std::string& filename); - /** - * Open multiple files for reading and then treat them as if they are one file - * - * NOTE: All of the files are assumed to have the same structure. Specifically - * this means: - * - The same categories are available from all files - * - The collections that are contained in the individual categories are the - * same across all files - * - * This usually boils down to "the files have been written with the same - * settings", e.g. they are outputs of a batched process. - * - * @param filenames The filenames of all input files that should be read - */ + /// Open multiple files for reading and then treat them as if they are one file + /// + /// @note All of the files are assumed to have the same structure. Specifically + /// this means: + /// - The same categories are available from all files + /// - The collections that are contained in the individual categories are the + /// same across all files + /// - This usually boils down to "the files have been written with the same + /// "settings", e.g. they are outputs of a batched process. + /// + /// @param filenames The filenames of all input files that should be read void openFiles(const std::vector& filenames); - /** - * Read the next data entry from which a Frame can be constructed for the - * given name. In case there are no more entries left for this name or in - * case there is no data for this name, this returns a nullptr. - */ + /// Read the next data entry for a given category. + /// + /// @param name The category name for which to read the next entry + /// + /// @returns FrameData from which a podio::Frame can be constructed if the + /// category exists and if there are still entries left to read. + /// Otherwise a nullptr std::unique_ptr readNextEntry(const std::string& name); - /** - * Read the specified data entry from which a Frame can be constructed for - * the given name. In case the entry does not exist for this name or in case - * there is no data for this name, this returns a nullptr. - */ + /// Read the desired data entry for a given category. + /// + /// @param name The category name for which to read the next entry + /// @param entry The entry number to read + /// + /// @returns FrameData from which a podio::Frame can be constructed if the + /// category and the desired entry exist. Otherwise a nullptr std::unique_ptr readEntry(const std::string& name, const unsigned entry); - /// Returns number of entries for the given name + /// Get the number of entries for the given name + /// + /// @param name The name of the category + /// + /// @returns The number of entries that are available for the category unsigned getEntries(const std::string& name) const; - /// Get the build version of podio that has been used to write the current file + /// Get the build version of podio that has been used to write the current + /// file + /// + /// @returns The podio build version podio::version::Version currentFileVersion() const { return m_fileVersion; } - /// Get the names of all the available Frame categories in the current file(s) + /// Get the names of all the available Frame categories in the current file(s). + /// + /// @returns The names of the available categories from the file std::vector getAvailableCategories() const; /// Get the datamodel definition for the given name + /// + /// @param name The name of the datamodel + /// + /// @returns The high level definition of the datamodel in JSON format const std::string_view getDatamodelDefinition(const std::string& name) const { return m_datamodelHolder.getDatamodelDefinition(name); } - /// Get all names of the datamodels that ara available from this reader + /// Get all names of the datamodels that are available from this reader + /// + /// @returns The names of the datamodels std::vector getAvailableDatamodels() const { return m_datamodelHolder.getAvailableDatamodels(); } private: - /** - * Helper struct to group together all the necessary state to read / process a - * given category. A "category" in this case describes all frames with the - * same name which are constrained by the ROOT file structure that we use to - * have the same contents. It encapsulates all state that is necessary for - * reading from a TTree / TChain (i.e. collection infos, branches, ...) - */ + /// Helper struct to group together all the necessary state to read / process + /// a given category. A "category" in this case describes all frames with the + /// same name which are constrained by the ROOT file structure that we use to + /// have the same contents. It encapsulates all state that is necessary for + /// reading from a TTree / TChain (i.e. collection infos, branches, ...) struct CategoryInfo { /// constructor from chain for more convenient map insertion CategoryInfo(std::unique_ptr&& c) : chain(std::move(c)) { @@ -128,35 +144,25 @@ class ROOTReader { std::shared_ptr table{nullptr}; ///< The collection ID table for this category }; - /** - * Initialize the passed CategoryInfo by setting up the necessary branches, - * collection infos and all necessary meta data to be able to read entries - * with this name - */ + /// Initialize the passed CategoryInfo by setting up the necessary branches, + /// collection infos and all necessary meta data to be able to read entries + /// with this name void initCategory(CategoryInfo& catInfo, const std::string& name); - /** - * Get the category information for the given name. In case there is no TTree - * with contents for the given name this will return a CategoryInfo with an - * uninitialized chain (nullptr) member - */ + /// Get the category information for the given name. In case there is no TTree + /// with contents for the given name this will return a CategoryInfo with an + /// uninitialized chain (nullptr) member CategoryInfo& getCategoryInfo(const std::string& name); - /** - * Read the parameters for the entry specified in the passed CategoryInfo - */ + /// Read the parameters for the entry specified in the passed CategoryInfo GenericParameters readEntryParameters(CategoryInfo& catInfo, bool reloadBranches, unsigned int localEntry); - /** - * Read the data entry specified in the passed CategoryInfo, and increase the - * counter afterwards. In case the requested entry is larger than the - * available number of entries, return a nullptr. - */ + /// Read the data entry specified in the passed CategoryInfo, and increase the + /// counter afterwards. In case the requested entry is larger than the + /// available number of entries, return a nullptr. std::unique_ptr readEntry(ROOTReader::CategoryInfo& catInfo); - /** - * Get / read the buffers at index iColl in the passed category information - */ + /// Get / read the buffers at index iColl in the passed category information podio::CollectionReadBuffers getCollectionBuffers(CategoryInfo& catInfo, size_t iColl, bool reloadBranches, unsigned int localEntry); diff --git a/include/podio/ROOTWriter.h b/include/podio/ROOTWriter.h index 7bee952d3..06aa61a46 100644 --- a/include/podio/ROOTWriter.h +++ b/include/podio/ROOTWriter.h @@ -21,47 +21,81 @@ class Frame; class CollectionBase; class GenericParameters; +/// The ROOTWriter writes podio files into ROOT files using TTrees. +/// +/// Each category gets its own TTree. Additionally, there is a podio_metadata +/// TTree that contains metadata that is necessary for interpreting the files +/// for reading. +/// +/// Files written with the ROOTWriter can be read with the ROOTReader. class ROOTWriter { public: + /// Create a ROOTWriter to write to a file. + /// + /// @note Existing files will be overwritten without warning. + /// + /// @param filename The path to the file that will be created. ROOTWriter(const std::string& filename); + + /// ROOTWriter destructor + /// + /// This also takes care of writing all the necessary metadata to read files back again. ~ROOTWriter(); + /// The ROOTWriter is not copy-able ROOTWriter(const ROOTWriter&) = delete; + /// The ROOTWriter is not copy-able ROOTWriter& operator=(const ROOTWriter&) = delete; - /** Store the given frame with the given category. Store all available - * collections from the Frame. - * - * NOTE: The contents of the first Frame that is written in this way - * determines the contents that will be written for all subsequent Frames. - */ + /// Store the given frame with the given category. + /// + /// This stores all available collections from the Frame. + /// + /// @note The contents of the first Frame that is written in this way + /// determines the contents that will be written for all subsequent Frames. + /// + /// @param frame The Frame to store + /// @param category The category name under which this Frame should be stored void writeFrame(const podio::Frame& frame, const std::string& category); - /** Store the given Frame with the given category. Store only the - * collections that are passed. - * - * NOTE: The contents of the first Frame that is written in this way - * determines the contents that will be written for all subsequent Frames. - */ + /// Store the given Frame with the given category. + /// + /// This stores only the desired collections and not the complete frame. + /// + /// @note The contents of the first Frame that is written in this way + /// determines the contents that will be written for all subsequent Frames. + /// + /// @param frame The Frame to store + /// @param category The category name under which this Frame should be + /// stored + /// @param collsToWrite The collection names that should be written void writeFrame(const podio::Frame& frame, const std::string& category, const std::vector& collsToWrite); - /** Write the current file, including all the necessary metadata to read it again. - */ + /// Write the current file, including all the necessary metadata to read it + /// again. + /// + /// @note The destructor will also call this, so letting a ROOTWriter go out + /// of scope is also a viable way to write a readable file void finish(); - /** Check whether the collsToWrite are consistent with the state of the passed - * category. - * - * Return two vectors of collection names. The first one contains all the - * names that were missing from the collsToWrite but were present in the - * category. The second one contains the names that are present in the - * collsToWrite only. If both vectors are empty the category and the passed - * collsToWrite are consistent. - * - * NOTE: This will only be a meaningful check if the first Frame of the passed - * category has already been written. Also, this check is rather expensive as - * it has to effectively do two set differences. - */ + /// Check whether the collsToWrite are consistent with the state of the passed + /// category. + /// + /// @note This will only be a meaningful check if the first Frame of the passed + /// category has already been written. Also, this check is rather expensive as + /// it has to effectively do two set differences. + /// + /// + /// @param collsToWrite The collection names that should be checked for + /// consistency + /// @param category The category name for which consistency should be + /// checked + /// + /// @returns two vectors of collection names. The first one contains all the + /// names that were missing from the collsToWrite but were present in the + /// category. The second one contains the names that are present in the + /// collsToWrite only. If both vectors are empty the category and the passed + /// collsToWrite are consistent. std::tuple, std::vector> checkConsistency(const std::vector& collsToWrite, const std::string& category) const; @@ -69,13 +103,11 @@ class ROOTWriter { using StoreCollection = std::pair; // collectionID, collectionType, subsetCollection - // NOTE: same as in rootUtils.h private header! + // @note same as in rootUtils.h private header! using CollectionInfoT = std::tuple; - /** - * Helper struct to group together all necessary state to write / process a - * given category. Created during the first writing of a category - */ + /// Helper struct to group together all necessary state to write / process a + /// given category. Created during the first writing of a category struct CategoryInfo { TTree* tree{nullptr}; ///< The TTree to which this category is written std::vector branches{}; ///< The branches for this category diff --git a/include/podio/RelationRange.h b/include/podio/RelationRange.h index f0c6383d3..42f885f44 100644 --- a/include/podio/RelationRange.h +++ b/include/podio/RelationRange.h @@ -5,10 +5,8 @@ #include namespace podio { -/** - * A simple helper class that allows to return related objects in a way that - * makes it possible to use the return type in a range-based for loop. - */ +/// A simple helper class that allows one to return related objects in a way that +/// makes it possible to use the return type in a range-based for loop. template class RelationRange { public: diff --git a/include/podio/SIOBlock.h b/include/podio/SIOBlock.h index 49d800f08..3ae41651e 100644 --- a/include/podio/SIOBlock.h +++ b/include/podio/SIOBlock.h @@ -93,9 +93,7 @@ class SIOBlock : public sio::block { podio::CollectionReadBuffers m_buffers{}; }; -/** - * A dedicated block for handling the I/O of the CollectionIDTable - */ +/// A dedicated block for handling the I/O of the CollectionIDTable class SIOCollectionIDTableBlock : public sio::block { public: SIOCollectionIDTableBlock() : sio::block("CollectionIDs", sio::version::encode_version(0, 4)) { @@ -152,9 +150,7 @@ struct SIOVersionBlock : public sio::block { podio::version::Version version{}; }; -/** - * A block for handling the EventMeta data - */ +/// A block for handling the EventMeta data class SIOEventMetaDataBlock : public sio::block { public: SIOEventMetaDataBlock() : sio::block("EventMetaData", sio::version::encode_version(0, 2)) { @@ -169,11 +165,9 @@ class SIOEventMetaDataBlock : public sio::block { podio::GenericParameters* metadata{nullptr}; }; -/** - * A block to serialize anything that behaves similar in iterating as a - * map, e.g. vector>, which is what is used - * internally to represent the data to be written. - */ +/// A block to serialize anything that behaves similar in iterating as a +/// map, e.g. vector>, which is what is used +/// internally to represent the data to be written. template struct SIOMapBlock : public sio::block { SIOMapBlock() : sio::block("SIOMapBlock", sio::version::encode_version(0, 1)) { @@ -195,9 +189,7 @@ struct SIOMapBlock : public sio::block { std::vector> mapData{}; }; -/** - * A block for handling the run and collection meta data - */ +/// A block for handling the run and collection meta data class SIONumberedMetaDataBlock : public sio::block { public: SIONumberedMetaDataBlock(const std::string& name) : sio::block(name, sio::version::encode_version(0, 2)) { @@ -244,15 +236,11 @@ class SIOBlockLibraryLoader { /// Status code for loading shared SIOBlocks libraries enum class LoadStatus : short { Success = 0, AlreadyLoaded = 1, Error = 2 }; - /** - * Load a library with the given name via dlopen - */ + /// Load a library with the given name via dlopen LoadStatus loadLib(const std::string& libname); - /** - * Get all files that are found on LD_LIBRARY_PATH and that have "SioBlocks" - * in their name together with the directory they are in - */ + /// Get all files that are found on LD_LIBRARY_PATH and that have "SioBlocks" + /// in their name together with the directory they are in static std::vector> getLibNames(); std::map _loadedLibs{}; @@ -287,15 +275,13 @@ class SIOFileTOCRecord { size_t getNRecords(const std::string& name) const; - /** Get the position of the iEntry-th record with the given name. If no entry - * with the given name is recorded, return 0. Note there is no internal check - * on whether the given name actually has iEntry records. Use getNRecords to - * check for that if necessary. - */ + /// Get the position of the iEntry-th record with the given name. If no entry + /// with the given name is recorded, return 0. Note there is no internal check + /// on whether the given name actually has iEntry records. Use getNRecords to + /// check for that if necessary. PositionType getPosition(const std::string& name, unsigned iEntry = 0) const; - /** Get all the record names that are stored in this TOC record - */ + /// Get all the record names that are stored in this TOC record std::vector getRecordNames() const; private: diff --git a/include/podio/SIOFrameData.h b/include/podio/SIOFrameData.h index 9cbc8a724..95b09d927 100644 --- a/include/podio/SIOFrameData.h +++ b/include/podio/SIOFrameData.h @@ -16,11 +16,9 @@ #include namespace podio { -/** - * The Frame data container for the SIO backend. It is constructed from the - * compressed sio::buffers that is read from file and does all the necessary - * unpacking and decompressing internally after construction. - */ +/// The Frame data container for the SIO backend. It is constructed from the +/// compressed sio::buffers that is read from file and does all the necessary +/// unpacking and decompressing internally after construction. class SIOFrameData { public: @@ -33,12 +31,10 @@ class SIOFrameData { SIOFrameData(SIOFrameData&&) = default; SIOFrameData& operator=(SIOFrameData&&) = default; - /** - * Constructor from the collBuffers containing the collection data and a - * tableBuffer containing the necessary information for unpacking the - * collections. The two size parameters denote the uncompressed size of the - * respective buffers. - */ + /// Constructor from the collBuffers containing the collection data and a + /// tableBuffer containing the necessary information for unpacking the + /// collections. The two size parameters denote the uncompressed size of the + /// respective buffers. SIOFrameData(sio::buffer&& collBuffers, std::size_t dataSize, sio::buffer&& tableBuffer, std::size_t tableSize) : m_recBuffer(std::move(collBuffers)), m_tableBuffer(std::move(tableBuffer)), diff --git a/include/podio/SIOLegacyReader.h b/include/podio/SIOLegacyReader.h index fc083abfb..d490fcd5e 100644 --- a/include/podio/SIOLegacyReader.h +++ b/include/podio/SIOLegacyReader.h @@ -15,55 +15,69 @@ namespace podio { class CollectionIDTable; -/** - * A SIO reader for reading legacy podio .sio files that have been written using - * the legacy, non Frame based I/O model. This reader grants Frame based access - * to those files, by mimicking Frame I/O functionality and the interfaces of - * those readers. - * - * NOTE: Since there was only one category ("events") for those legacy podio - * files this reader will really only work if you try to read that category, and - * will simply return no data if you try to read anything else. - */ +/// A SIO reader for reading legacy podio .sio files that have been written using +/// the legacy, non Frame based I/O model. This reader grants Frame based access +/// to those files, by mimicking Frame I/O functionality and the interfaces of +/// those readers. +/// +/// @note Since there was only one category ("events") for those legacy podio +/// files this reader will really only work if you try to read that category, and +/// will simply return no data if you try to read anything else. class SIOLegacyReader { public: + /// Create a SIOLegacyReader SIOLegacyReader(); + /// Destructor ~SIOLegacyReader() = default; - // non copy-able + /// The SIOLegacyReader is not copy-able SIOLegacyReader(const SIOLegacyReader&) = delete; + /// The SIOLegacyReader is not copy-able SIOLegacyReader& operator=(const SIOLegacyReader&) = delete; - /** - * Read the next data entry from which a Frame can be constructed. In case - * there are no more entries left, this returns a nullptr. - * - * NOTE: the category name has to be "events" in this case, as only that - * category is available for legacy files. - */ + /// Read the next data entry from which a Frame can be constructed. In case + /// there are no more entries left, this returns a nullptr. + /// + /// @note the category name has to be "events" in this case, as only that + /// category is available for legacy files. + /// + /// @returns FrameData from which a podio::Frame can be constructed if there + /// are still entries left to read. Otherwise a nullptr std::unique_ptr readNextEntry(const std::string&); - /** - * Read the specified data entry from which a Frame can be constructed In case - * the entry does not exist, this returns a nullptr. - * - * NOTE: the category name has to be "events" in this case, as only that - * category is available for legacy files. - */ + /// Read the desired data entry from which a Frame can be constructed. + /// + /// @note the category name has to be "events" in this case, as only that + /// category is available for legacy files. + /// + /// @returns FrameData from which a podio::Frame can be constructed if the + /// desired entry exists. Otherwise a nullptr std::unique_ptr readEntry(const std::string&, const unsigned entry); - /// Returns the number of + /// Get the number of entries for the given name + /// + /// @param name The name of the category + /// + /// @returns The number of entries that are available for the category unsigned getEntries(const std::string& name) const; + /// Open a single file for reading. + /// + /// @param filename The name of the input file void openFile(const std::string& filename); - /// Get the build version of podio that has been used to write the current file + /// Get the build version of podio that has been used to write the current + /// file + /// + /// @returns The podio build version podio::version::Version currentFileVersion() const { return m_fileVersion; } - /// Get the names of all the available Frame categories in the current file(s) + /// Get the names of all the available Frame categories in the current file(s). + /// + /// @returns The names of the available categores from the file std::vector getAvailableCategories() const; private: diff --git a/include/podio/SIOReader.h b/include/podio/SIOReader.h index 5b16fbe79..80970abbb 100644 --- a/include/podio/SIOReader.h +++ b/include/podio/SIOReader.h @@ -17,49 +17,79 @@ namespace podio { class CollectionIDTable; +/// The SIOReader can be used to read files that have been written with the SIO +/// backend. +/// +/// The SIOReader provides the data as SIOFrameData from which a podio::Frame +/// can be constructed. It can be used to read files written by the SIOWriter. class SIOReader { public: + /// Create an SIOReader SIOReader(); + /// SIOReader destructor ~SIOReader() = default; - // non copyable + /// The SIOReader is not copy-able SIOReader(const SIOReader&) = delete; + /// The SIOReader is not copy-able SIOReader& operator=(const SIOReader&) = delete; - /** - * Read the next data entry from which a Frame can be constructed for the - * given name. In case there are no more entries left for this name or in - * case there is no data for this name, this returns a nullptr. - */ + /// Read the next data entry for a given category. + /// + /// @param name The category name for which to read the next entry + /// + /// @returns FrameData from which a podio::Frame can be constructed if the + /// category exists and if there are still entries left to read. + /// Otherwise a nullptr std::unique_ptr readNextEntry(const std::string& name); - /** - * Read the specified data entry from which a Frame can be constructed for - * the given name. In case the entry does not exist for this name or in - * case there is no data for this name, this returns a nullptr. - */ + /// Read the desired data entry for a given category. + /// + /// @param name The category name for which to read the next entry + /// @param entry The entry number to read + /// + /// @returns FrameData from which a podio::Frame can be constructed if the + /// category and the desired entry exist. Otherwise a nullptr std::unique_ptr readEntry(const std::string& name, const unsigned entry); - /// Returns number of entries for the given name + /// Get the number of entries for the given name + /// + /// @param name The name of the category + /// + /// @returns The number of entries that are available for the category unsigned getEntries(const std::string& name) const; + /// Open the passed file for reading. + /// + /// @param filename The path to the file to read from void openFile(const std::string& filename); - /// Get the build version of podio that has been used to write the current file + /// Get the build version of podio that has been used to write the current + /// file + /// + /// @returns The podio build version podio::version::Version currentFileVersion() const { return m_fileVersion; } - /// Get the names of all the available Frame categories in the current file(s) + /// Get the names of all the available Frame categories in the current file. + /// + /// @returns The names of the available categores from the file std::vector getAvailableCategories() const; /// Get the datamodel definition for the given name + /// + /// @param name The name of the datamodel + /// + /// @returns The high level definition of the datamodel in JSON format const std::string_view getDatamodelDefinition(const std::string& name) const { return m_datamodelHolder.getDatamodelDefinition(name); } - /// Get all names of the datamodels that ara available from this reader + /// Get all names of the datamodels that are available from this reader + /// + /// @returns The names of the datamodels std::vector getAvailableDatamodels() const { return m_datamodelHolder.getAvailableDatamodels(); } diff --git a/include/podio/SIOWriter.h b/include/podio/SIOWriter.h index 2cd02118b..6f680ffb8 100644 --- a/include/podio/SIOWriter.h +++ b/include/podio/SIOWriter.h @@ -14,23 +14,60 @@ namespace podio { class Frame; +/// The SIOWriter writes podio files into SIO files. +/// +/// Each Frame is stored into an SIO record which are written in the order in +/// which Frames are written. As part of the metadata a table of content record +/// is written which is used in the reader to more quickly access the different +/// records. +/// +/// Files written with the SIOWriter can be read with the SIOReader class SIOWriter { public: + /// Create a SIOWriter to write to a file. + /// + /// @note Existing files will be overwritten without warning. + /// + /// @param filename The path to the file that will be created. SIOWriter(const std::string& filename); + + /// SIOWriter destructor + /// + /// This also takes care of writing all the necessary metadata to read files back again. ~SIOWriter(); + /// The SIOWriter is not copy-able SIOWriter(const SIOWriter&) = delete; + /// The SIOWriter is not copy-able SIOWriter& operator=(const SIOWriter&) = delete; - /** Write the given Frame with the given category - */ + /// Store the given frame with the given category. + /// + /// This stores all available collections from the Frame. Frames of the same + /// category can be independent of each other, i.e. they can have different + /// collection contents. + /// + /// @param frame The Frame to store + /// @param category The category name under which this Frame should be stored void writeFrame(const podio::Frame& frame, const std::string& category); - /** Write the given Frame with the given category only storing the collections - * that are desired via collsToWrite - */ + /// Store the given Frame with the given category. + /// + /// This stores only the desired collections and not the complete frame. + /// Frames of the same category can be independent of each other, i.e. they + /// can have different collection contents. + /// + /// @param frame The Frame to store + /// @param category The category name under which this Frame should be + /// stored + /// @param collsToWrite The collection names that should be written void writeFrame(const podio::Frame& frame, const std::string& category, const std::vector& collsToWrite); + /// Write the current file, including all the necessary metadata to read it + /// again. + /// + /// @note The destructor will also call this, so letting a SIOWriter go out + /// of scope is also a viable way to write a readable file void finish(); private: diff --git a/include/podio/SchemaEvolution.h b/include/podio/SchemaEvolution.h index a98af89ff..cb8803d26 100644 --- a/include/podio/SchemaEvolution.h +++ b/include/podio/SchemaEvolution.h @@ -16,18 +16,16 @@ using SchemaVersionT = uint32_t; struct CollectionReadBuffers; -/** - * The SchemaEvolution holds evolution functions that allow to transform - * CollectionReadBuffers of known datatypes from a previous schema version to - * the current schema version. From the evolved buffers it is then possible to - * create collections. - * - * It is implemented as a singleton that is populated at the time shared - * datamodel libraries (or their schema evolution libraries) are loaded. It is - * assumed that this happens early on in the startup of any application, such - * that the registration still happens on a single thread. After this - * initialization evolutions can be done from multiple threads. - */ +/// The SchemaEvolution holds evolution functions that allow to transform +/// CollectionReadBuffers of known datatypes from a previous schema version to +/// the current schema version. From the evolved buffers it is then possible to +/// create collections. +/// +/// It is implemented as a singleton that is populated at the time shared +/// datamodel libraries (or their schema evolution libraries) are loaded. It is +/// assumed that this happens early on in the startup of any application, such +/// that the registration still happens on a single thread. After this +/// initialization evolutions can be done from multiple threads. class SchemaEvolution { /// The interface of any evolution function takes buffers and a version and /// returns buffers. @@ -37,10 +35,8 @@ class SchemaEvolution { /// current version using EvolFuncVersionMapT = std::vector; - /** - * Helper struct combining the current schema version of each type and an - * index into the schema evolution "map" below - */ + /// Helper struct combining the current schema version of each type and an + /// index into the schema evolution "map" below struct MapIndex { SchemaVersionT currentVersion; ///< The current schema version for each type size_t index; ///< The index in the evolution function map @@ -55,10 +51,8 @@ class SchemaEvolution { using EvolutionMapT = std::vector; public: - /** - * Enum to make it possible to prioritize evolution functions during - * registration, making AutoGenerated lower priority than UserDefined - */ + /// Enum to make it possible to prioritize evolution functions during + /// registration, making AutoGenerated lower priority than UserDefined enum class Priority { AutoGenerated = 0, UserDefined = 1 }; /// The SchemaEvolution is a singleton so we disable all copy and move @@ -75,63 +69,57 @@ class SchemaEvolution { /// Get the instance for evolving buffers static SchemaEvolution const& instance(); - /** - * Evolve the passed in buffers to the current version of the datatype that - * can be constructed from them. - * - * Internally this will first check if the schema version of the buffers is - * already the current one and in that case immediately return the passed in - * buffers again as they do not need schema evolution. If that is not the case - * it will look up the correct evolution function for the passed in version - * and call that on the passed in buffers. - * - * @param oldBuffers The buffers to be evolved - * @param fromVersion The schema version of the buffers - * @param collType The fully qualified collection type - * - * @returns CollectionReadBuffers that have been evolved to the current - * version. NOTE that these could also be the input buffers. - */ + /// Evolve the passed in buffers to the current version of the datatype that + /// can be constructed from them. + /// + /// Internally this will first check if the schema version of the buffers is + /// already the current one and in that case immediately return the passed in + /// buffers again as they do not need schema evolution. If that is not the case + /// it will look up the correct evolution function for the passed in version + /// and call that on the passed in buffers. + /// + /// @param oldBuffers The buffers to be evolved + /// @param fromVersion The schema version of the buffers + /// @param collType The fully qualified collection type + /// + /// @returns CollectionReadBuffers that have been evolved to the current + /// version. @note that these could also be the unchanged input buffers. podio::CollectionReadBuffers evolveBuffers(const podio::CollectionReadBuffers& oldBuffers, SchemaVersionT fromVersion, const std::string& collType) const; - /** - * Register an evolution function for a given collection type and given - * versions from where to where the evolution applies. - * - * Several assumptions are in place here: - * - * - The current version has to be the same for all invocations for a given - * datatype. - * - An evolution function has to be registered for all possible versions from - * 1 to N - 1, where N is the current version - * - An evolution function can only be registered once for a given datatype and - * fromVersion - * - For auto generated code the passed in priority has to be AutoGenerated - * otherwise it might override user defined functions - * - Even if a datatype does not require schema evolution it has to register - * an evolution function (e.g. the noOpSchemaEvolution below) in order to be - * known to the internal map. - * - * @param collType The fully qualified collection data type - * @param fromVersion The version from which this evolution function should - * apply - * @param currentVersion The current schema version for the data type - * @param evolutionFunc The evolution function that evolves passed in buffers - * from fromVersion to currentVersion - * @param priority The priority of this evolution function. Defaults to - * UserDefined which overrides auto generated functionality. - */ + /// Register an evolution function for a given collection type and given + /// versions from where to where the evolution applies. + /// + /// Several assumptions are in place here: + /// + /// - The current version has to be the same for all invocations for a given + /// datatype. + /// - An evolution function has to be registered for all possible versions from + /// 1 to N - 1, where N is the current version + /// - An evolution function can only be registered once for a given datatype and + /// fromVersion + /// - For auto generated code the passed in priority has to be AutoGenerated + /// otherwise it might override user defined functions + /// - Even if a datatype does not require schema evolution it has to register + /// an evolution function (e.g. the noOpSchemaEvolution below) in order to be + /// known to the internal map. + /// + /// @param collType The fully qualified collection data type + /// @param fromVersion The version from which this evolution function should + /// apply + /// @param currentVersion The current schema version for the data type + /// @param evolutionFunc The evolution function that evolves passed in buffers + /// from fromVersion to currentVersion + /// @param priority The priority of this evolution function. Defaults to + /// UserDefined which overrides auto generated functionality. void registerEvolutionFunc(const std::string& collType, SchemaVersionT fromVersion, SchemaVersionT currentVersion, const EvolutionFuncT& evolutionFunc, Priority priority = Priority::UserDefined); - /** - * A no-op schema evolution function that returns the buffers unchanged. - * - * This can be used for registering an evolution function for datatypes that - * do not require schema evolution, but need to register themselves with - * SchemaEvolution - */ + /// A no-op schema evolution function that returns the buffers unchanged. + /// + /// This can be used for registering an evolution function for datatypes that + /// do not require schema evolution, but need to register themselves with + /// SchemaEvolution static podio::CollectionReadBuffers noOpSchemaEvolution(podio::CollectionReadBuffers&& buffers, SchemaVersionT); private: diff --git a/include/podio/UserDataCollection.h b/include/podio/UserDataCollection.h index dd1b47ee5..0b2c9a092 100644 --- a/include/podio/UserDataCollection.h +++ b/include/podio/UserDataCollection.h @@ -25,26 +25,22 @@ namespace podio { -/** tuple of basic types supported in user vector - */ +/// tuple of basic types supported in user vector using SupportedUserDataTypes = std::tuple; -/** - * Alias template to be used to enable template specializations only for the types listed in the - * SupportedUserDataTypes list - */ +/// Alias template to be used to enable template specializations only for the types listed in the +/// SupportedUserDataTypes list template using EnableIfSupportedUserType = std::enable_if_t>; -/** helper template to provide readable type names for basic types with macro PODIO_ADD_USER_TYPE(type) - */ +/// helper template to provide readable type names for basic types with macro +/// PODIO_ADD_USER_TYPE(type) template > constexpr const char* userDataTypeName(); -/** Helper template to provide the fully qualified name of a UserDataCollection. - * Implementations are populated by the PODIO_ADD_USER_TYPE macro. - */ +/// Helper template to provide the fully qualified name of a UserDataCollection. +/// Implementations are populated by the PODIO_ADD_USER_TYPE macro. template > constexpr const char* userDataCollTypeName(); @@ -60,12 +56,13 @@ PODIO_ADD_USER_TYPE(uint16_t) PODIO_ADD_USER_TYPE(uint32_t) PODIO_ADD_USER_TYPE(uint64_t) -/** Collection of basic types for additional user data not defined in the EDM. - * The data is stored in an std::vector. Supported are all basic types supported in - * PODIO, i.e. float, double and 8-64 bit fixed size signed and unsigned integers - @see SupportedUserDataTypes. - * @author F.Gaede, DESY - * @date Sep 2021 - */ +/// Collection of basic types for additional user data not defined in the EDM. +/// The data is stored in an std::vector. Supported are all basic +/// types supported in PODIO, i.e. float, double and 8-64 bit fixed size signed +/// and unsigned integers - @see SupportedUserDataTypes. +/// +/// @author F.Gaede, DESY +/// @date Sep 2021 template > class UserDataCollection : public CollectionBase { diff --git a/include/podio/utilities/DatamodelRegistryIOHelpers.h b/include/podio/utilities/DatamodelRegistryIOHelpers.h index 4ca996ae6..77416a839 100644 --- a/include/podio/utilities/DatamodelRegistryIOHelpers.h +++ b/include/podio/utilities/DatamodelRegistryIOHelpers.h @@ -11,19 +11,15 @@ namespace podio { -/** - * Helper class to collect the datamodel (JSON) definitions that should be - * written. - */ +/// Helper class to collect the datamodel (JSON) definitions that should be +/// written. class DatamodelDefinitionCollector { public: - /** - * Register the datamodel definition of the EDM this collection is from to be - * written. - * - * @param coll A collection of an EDM - * @param name The name under which this collection is stored on file - */ + /// Register the datamodel definition of the EDM this collection is from to be + /// written. + /// + /// @param coll A collection of an EDM + /// @param name The name under which this collection is stored on file void registerDatamodelDefinition(const podio::CollectionBase* coll, const std::string& name); /// Get all the names and JSON definitions that need to be written @@ -33,10 +29,8 @@ class DatamodelDefinitionCollector { std::set m_edmDefRegistryIdcs{}; ///< The indices in the EDM definition registry that need to be written }; -/** - * Helper class to hold and provide the datamodel (JSON) definitions for reader - * classes. - */ +/// Helper class to hold and provide the datamodel (JSON) definitions for reader +/// classes. class DatamodelDefinitionHolder { public: /// The "map" type that is used internally @@ -52,19 +46,15 @@ class DatamodelDefinitionHolder { DatamodelDefinitionHolder(DatamodelDefinitionHolder&&) = default; DatamodelDefinitionHolder& operator=(DatamodelDefinitionHolder&&) = default; - /** - * Get the datamodel definition for the given datamodel name. - * - * Returns an empty model definition if no model is stored under the given - * name. - * - * @param name The name of the datamodel - */ + /// Get the datamodel definition for the given datamodel name. + /// + /// Returns an empty model definition if no model is stored under the given + /// name. + /// + /// @param name The name of the datamodel const std::string_view getDatamodelDefinition(const std::string& name) const; - /** - * Get all names of the datamodels that have been read from file - */ + /// Get all names of the datamodels that have been read from file std::vector getAvailableDatamodels() const; protected: diff --git a/include/podio/utilities/TypeHelpers.h b/include/podio/utilities/TypeHelpers.h index 41bbf641c..6af8a729d 100644 --- a/include/podio/utilities/TypeHelpers.h +++ b/include/podio/utilities/TypeHelpers.h @@ -50,35 +50,29 @@ namespace det { namespace detail { - /** - * Helper struct to determine whether a given type T is in a tuple of types - * that act as a type list in this case - */ + /// Helper struct to determine whether a given type T is in a tuple of types + /// that act as a type list in this case template struct TypeInTupleHelper : std::false_type {}; template struct TypeInTupleHelper> : std::bool_constant<(std::is_same_v || ...)> {}; - /** - * variable template for determining whether type T is in a tuple with types - * Ts - */ + /// variable template for determining whether type T is in a tuple with types + /// Ts template static constexpr bool isInTuple = TypeInTupleHelper::value; - /** - * Helper struct to turn a tuple of types into a tuple of a template of types, e.g. - * - * std::tuple -> std::tuple, std::vector> - * if the passed template is std::vector - * - * NOTE: making the template template parameter to Template variadic because - * clang will not be satisfied otherwise if we use it with, e.g. std::vector. - * This will also make root dictionary generation fail. GCC works without this - * small workaround and is standard compliant in this case, whereas clang is - * not. - */ + /// Helper struct to turn a tuple of types into a tuple of a template of types, e.g. + /// + /// std::tuple -> std::tuple, std::vector> + /// if the passed template is std::vector + /// + /// @note making the template template parameter to Template variadic because + /// clang will not be satisfied otherwise if we use it with, e.g. std::vector. + /// This will also make root dictionary generation fail. GCC works without this + /// small workaround and is standard compliant in this case, whereas clang is + /// not. template