|
|
|||
File indexing completed on 2025-12-16 10:12:57
0001 #ifndef EDM4HEP_UTILS_PARTICLEIDUTILS_H 0002 #define EDM4HEP_UTILS_PARTICLEIDUTILS_H 0003 0004 #include <edm4hep/ParticleIDCollection.h> 0005 #include <edm4hep/ReconstructedParticle.h> 0006 0007 #include <podio/Frame.h> 0008 0009 #include <map> 0010 #include <optional> 0011 #include <string> 0012 #include <vector> 0013 0014 namespace edm4hep::utils { 0015 0016 /// A simple struct bundling relevant metadata for a ParticleID collection 0017 /// 0018 /// This is the recommended class to use for storing ParticleID related 0019 /// metadata. Most importantly it contains the name of an algorithm as well as 0020 /// the names of the parameters (if any). Additionally, it can also 0021 /// automatically determine an algorithm type (to be used in 0022 /// edm4hep::PartilceID::setAlgorithmType) given a name. This is a 32 bit hash 0023 /// of the algorithm name. 0024 /// 0025 /// @note Given that this structure and the actual contents of the corresponding 0026 /// ParticleIDCollection are disjoint it is your responsibility to set the 0027 /// information accordingly. We offer some utility functionality to ensure 0028 /// consistent setting, but the tools can in principle also be used without 0029 /// that. 0030 struct ParticleIDMeta { 0031 /// Constructor for I/O purposes or with a pre-defined algorithm type 0032 /// 0033 /// @note We generally recommend not using pre-defined algorithm types, but 0034 /// rather to use the automatically determined ones from the 0035 /// 0036 /// @param algName The name of the PID algorithm 0037 /// @param algType The (encoded) algorithm type (stored in the ParticleID 0038 /// algorithmType) field 0039 /// @param parNames The (optional) parameter names for this PID algorithms. 0040 /// There should be a parameter name for each parameter that 0041 /// is stored in the ParticleID parameters field 0042 ParticleIDMeta(const std::string& algName, int32_t algType, const std::vector<std::string>& parNames = {}); 0043 0044 /// Main constructor for creating a ParticleIDMeta object without parameters 0045 /// 0046 /// @param algName The name of the PID algorithm 0047 ParticleIDMeta(const std::string& algName); 0048 0049 /// Main constructor for creating a ParticleIDMeta object with parameters 0050 /// 0051 /// @param algName The name of the PID algorithm 0052 /// @param parNames The (optional) parameter names for this PID algorithms. 0053 /// There should be a parameter name for each parameter that 0054 /// is stored in the ParticleID parameters field 0055 ParticleIDMeta(const std::string& algName, const std::vector<std::string>& parNames); 0056 0057 ~ParticleIDMeta() = default; 0058 /// Default constructor 0059 /// 0060 /// @note It is not possible to change the algorithm type when this 0061 /// constructor is used 0062 ParticleIDMeta() = default; 0063 ParticleIDMeta(const ParticleIDMeta&) = default; 0064 ParticleIDMeta& operator=(const ParticleIDMeta&) = default; 0065 ParticleIDMeta(ParticleIDMeta&&) = default; 0066 ParticleIDMeta& operator=(ParticleIDMeta&&) = default; 0067 0068 std::string algoName{}; ///< The name of the algorithm 0069 std::vector<std::string> paramNames{}; ///< The names of the parameters 0070 0071 /// Get the encoded algorithm type for the PID algorithm that is described by 0072 /// this meta object 0073 /// 0074 /// @returns the algorithm type (usually a 32 bit hash of the algorithm name) 0075 int32_t algoType() const { return m_algoType; } 0076 0077 private: 0078 int32_t m_algoType{0}; ///< The (potentially user defined) algorithm type 0079 }; 0080 0081 /// Get the index of a parameter for a given PID algorithm 0082 /// 0083 /// @param pidMetaInfo A metadata object describig a ParticleID algorithm 0084 /// @param param The name of the parameter 0085 /// 0086 /// @returns The index of the parameter which can be used to index into the 0087 /// ParticleID::getParameters() values or an empty optional in case the 0088 /// parameter name could not be found in the metadata that were passed. 0089 std::optional<int> getParamIndex(const ParticleIDMeta& pidMetaInfo, const std::string& param); 0090 0091 /// Utility class to invert the ParticleID to ReconstructedParticle relation 0092 /// 0093 /// This is the main utility class to use when trying to obtain ParticleID 0094 /// objects related to ReconstructedParticles. Basic functionality (i.e. 0095 /// retrieving the related ParticleIDs) can be done without any additional 0096 /// metadata. The full functionality is enabled by also passing in metadata (in 0097 /// the form of ParticleIDMeta) or alternatively adding it after the initial 0098 /// construction. 0099 /// 0100 /// This uses an internal map that is updated whenever a new 0101 /// ParticleIDCollection is added. Hence, lookup of related ParticleID objects 0102 /// for a given ReconstructedParticle avoids looping over all collections. 0103 /// 0104 /// @note there are no checks in place that ensure that the metadata that has 0105 /// been added to a given PIDHandler actually correspond to any of the stored 0106 /// ParticleIDs. It is in fact even possible to use the PIDHandler without any 0107 /// PartileID objects to simply query meta information about ParticleID 0108 /// algorithms. 0109 /// 0110 /// See [this page](@ref md_doc_2_p_i_d_handler) for example usage and more information. 0111 class PIDHandler { 0112 0113 using RecoPidMapT = std::multimap<edm4hep::ReconstructedParticle, edm4hep::ParticleID>; 0114 0115 RecoPidMapT m_recoPidMap{}; ///< The internal map from recos to pids 0116 0117 std::map<std::string, int> m_algoTypes{}; ///< Maps algo names to algo types 0118 0119 /// Maps algo types to the full particle id meta information 0120 std::map<int, edm4hep::utils::ParticleIDMeta> m_algoPidMeta{}; 0121 0122 public: 0123 PIDHandler() = default; 0124 ~PIDHandler() = default; 0125 // Copies are not allowed to avoid copying the internal maps 0126 PIDHandler(const PIDHandler&) = delete; 0127 PIDHandler& operator=(const PIDHandler&) = delete; 0128 PIDHandler(PIDHandler&&) = default; 0129 PIDHandler& operator=(PIDHandler&&) = default; 0130 0131 /// Construct a PIDHandler from an arbitrary number of ParticleIDCollections 0132 /// 0133 /// This constructor does not retrieve any metadata and on its own will only 0134 /// enable the basic functionality. For the full functionality add the 0135 /// necessary metadata in a follow up call to @ref addMetaInfos or @ref 0136 /// addMetaInfo 0137 /// 0138 /// @tparam PIDColls A variadic template that we use to enable passing 0139 /// arbitrary numbers of collections 0140 /// 0141 /// @param coll A ParticleIDCollection for constructing a PIDHandler 0142 /// @param pidColls An arbitrary number of additional ParticleIDCollections 0143 /// that will also be added to the internal map 0144 /// 0145 /// @returns A PIDHandler that is able to handle relations between 0146 /// ReconstructedParticles and all ParticleID objects that are part 0147 /// of the passed collection 0148 template <typename... PIDColls> 0149 static PIDHandler from(const ParticleIDCollection& coll, const PIDColls&... pidColls) { 0150 static_assert((std::is_same_v<PIDColls, edm4hep::ParticleIDCollection> && ...), 0151 "PIDHandler can only be constructed from ParticleIDCollections"); 0152 PIDHandler handler{}; 0153 handler.addColl(coll); 0154 (handler.addColl(pidColls), ...); 0155 return handler; 0156 } 0157 0158 /// Create a PIDHandler from a Frame potentially also populating some metadata information. 0159 /// 0160 /// Create a PIDHandler using all ParticleIDCollections that can be found. If 0161 /// metadata is passed automatically also load all related metadata (if 0162 /// available). 0163 /// 0164 /// @note This constructor does not guarantee that **all** 0165 /// ParticleIDCollections will have valid metadata loaded. Only if such 0166 /// metadata is actually present and found will it be ingested, otherwise only 0167 /// the ParticleID objects will be added to the internal map. 0168 /// 0169 /// @param event The event Frame from which all ParticleIDCollections will be 0170 /// retrieved 0171 /// @param metadata An (optional) metadata Frame from which ParticleIDMeta will 0172 /// be automatically retrieved for all ParticleIDCollections 0173 /// for which it is actually available. 0174 /// 0175 /// @returns A PIDHandler that is able to handle relations between 0176 /// ReconstructedParticles and all ParticleID objects that were found 0177 /// in the event Frame. If metadata is found on top of that, also 0178 /// that has been ingested and can now be queried through this handler. 0179 static PIDHandler from(const podio::Frame& event, const podio::Frame& metadata = {}); 0180 0181 /// Add the information from one ParticleIDCollection to the handler 0182 /// 0183 /// @note This will only add the collection to enable basic functionality. In 0184 /// order to enable the full functionality it is also necessary to add the 0185 /// necessary ParticleIDMeta information that corresponds to the added 0186 /// collection. 0187 /// 0188 /// This is the main function for adding new collections. All other methods 0189 /// that add ParticleID collections will eventually call this in one way or 0190 /// another. 0191 /// 0192 /// @param coll A ParticleIDCollection that should be added to the internal map 0193 void addColl(const edm4hep::ParticleIDCollection& coll); 0194 0195 /// Add the information from one ParticleIDCollection to the handler together 0196 /// with its meta data 0197 /// 0198 /// @note This method does no check in any form whether the passed collection 0199 /// and metadata are actually related in any form. 0200 /// 0201 /// @param coll A ParticleIDCollection that should be added to the internal 0202 /// map 0203 /// @param pidInfo The metadata describing the algorithm that has been used to 0204 /// determine the ParticleIDs of the coll 0205 void addColl(const edm4hep::ParticleIDCollection& coll, const edm4hep::utils::ParticleIDMeta& pidInfo); 0206 0207 /// Add (arbitrary) metadata describing a PID algorithm. 0208 /// 0209 /// This is the main function for ingesting metadata. All other methods that 0210 /// add ParticleID algorithm metadata will eventually call this in one way or 0211 /// another. 0212 /// 0213 /// @param pidInfo The metadata describing an algorithm that has been used to 0214 /// determine ParticleID objects 0215 void addMetaInfo(const edm4hep::utils::ParticleIDMeta& pidInfo); 0216 0217 /// Add several (arbitrary) meta informations simultaneously 0218 /// 0219 /// @tparam PIDMetas A variadic template that we use to enable calling this 0220 /// with an arbitrary number of ParticleIDMeta objects 0221 /// 0222 /// @param pidMetas An arbitrary number of metadata objects describing 0223 /// algorithms that have been used to determine ParticleID 0224 /// objects 0225 template <typename... PIDMetas> 0226 void addMetaInfos(const PIDMetas&... pidMetas) { 0227 static_assert((std::is_same_v<PIDMetas, edm4hep::utils::ParticleIDMeta> && ...), 0228 "Only ParticleIDMeta can be used to add metadata to a PIDHandler"); 0229 (addMetaInfo(pidMetas), ...); 0230 } 0231 0232 /// Retrieve all ParticleIDs that are related to the passed 0233 /// ReconstructedParticle 0234 /// 0235 /// @param reco The ReconstructedParticle for which ParticleIDs should be 0236 /// looked up 0237 /// 0238 /// @returns All ParticleID objects (that this PIDHandler knows about) that 0239 /// point to the passed ReconstructedParticle 0240 std::vector<edm4hep::ParticleID> getPIDs(const edm4hep::ReconstructedParticle& reco) const; 0241 0242 /// Retrieve the ParticleID for a given PID algorithm 0243 /// 0244 /// @param reco The ReconstructedParticle for which a ParticleID should be 0245 /// looked up 0246 /// @param algoType The (encoded) algorithm type that corresponds to the 0247 /// desired algorithm. See also @ref getAlgoType 0248 /// 0249 /// @returns The ParticleID object for this PID algorithm that points to the 0250 /// passed ReconstrucedParticle if found or an empty optional 0251 /// otherwise 0252 std::optional<edm4hep::ParticleID> getPID(const edm4hep::ReconstructedParticle& reco, int algoType) const; 0253 0254 /// Retrieve the index in the parameters for a given parameter name and 0255 /// algoType 0256 /// 0257 /// @param algoType The (encoded) algorithm type that corresponds to the 0258 /// desired algorithm. See also @ref getAlgoType 0259 /// @param paramName The name of the parameter 0260 /// 0261 /// @returns The index of the parameter which can be used to index into the 0262 /// ParticleID::getParameters() values or an empty optional in case the 0263 /// parameter name could not be found for the passed algorithm type 0264 /// 0265 /// See also @ref edm4hep::utils::getParamIndex 0266 std::optional<int> getParamIndex(int32_t algoType, const std::string& paramName) const; 0267 0268 /// Retrieve the algoType for a given algorithm name 0269 /// 0270 /// @param algoName 0271 /// 0272 /// @returns The (encoded) algorithm type for the desired algorithm if known 0273 /// to the PIDHandler otherwise an empty optional. 0274 std::optional<int32_t> getAlgoType(const std::string& algoName) const; 0275 0276 /// Set the metadata information for the passed collection in the metadata Frame. 0277 /// 0278 /// This also sets the algorithmType of all elements in the collection to the 0279 /// one that is found in the meta information. 0280 /// 0281 /// @param metadata The metadata Frame into which the information should be 0282 /// stored 0283 /// @param pidcoll A ParticleIDCollection for which the corresponding 0284 /// algorithm type will be set (consistent with what is found 0285 /// in the @p pidMetaInfo) 0286 /// @param pidMetaInfo The metadata object that corresponds to the ParticleID 0287 /// algorithm that has been used for creating the @p 0288 /// pidcoll 0289 static void setAlgoInfo(podio::Frame& metadata, edm4hep::ParticleIDCollection& pidcoll, const std::string& collname, 0290 const edm4hep::utils::ParticleIDMeta& pidMetaInfo); 0291 0292 /// Set the metadata information for a given collection name in the metadata Frame. 0293 /// 0294 /// @note It is user responsibility to ensure that the meta information that 0295 /// is passed here and the one that is present in the collection with the 0296 /// given name is consistent 0297 /// 0298 /// @param metadata The metadata Frame into which the information should be 0299 /// stored 0300 /// @param collname The name of the (ParticleID) collection for which this 0301 /// meta information should be stored 0302 /// @param pidMetaInfo The metadata object that corresponds to the ParticleID 0303 /// algorithm that has been used for creating the 0304 /// ParticleID objects stored in the collection with the @p 0305 /// collname 0306 static void setAlgoInfo(podio::Frame& metadata, const std::string& collname, 0307 const edm4hep::utils::ParticleIDMeta& pidMetaInfo); 0308 0309 /// Get the ParticleID meta information for a given collection name from the metadata Frame. 0310 /// 0311 /// @param metadata The metadata frame in which to search for ParticleID 0312 /// related metadata 0313 /// @param collName The (ParticleID) collection name for which to obtain metadata 0314 /// 0315 /// @returns The metadata related to the PID algorithm that has been used to 0316 /// create the @p collName collection if available, otherwise an 0317 /// empty optional. 0318 static std::optional<edm4hep::utils::ParticleIDMeta> getAlgoInfo(const podio::Frame& metadata, 0319 const std::string& collName); 0320 }; 0321 } // namespace edm4hep::utils 0322 0323 #endif // EDM4HEP_UTILS_PARTICLEIDUTILS_H
| [ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
|
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |
|