Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // -*- C++ -*-
0002 //
0003 // This file is part of HepMC
0004 // Copyright (C) 2014-2023 The HepMC collaboration (see AUTHORS for details)
0005 //
0006 ///
0007 /// @file Relatives.h
0008 /// @brief Defines helper classes to extract relatives of an input GenParticle or GenVertex
0009 ///
0010 #ifndef HEPMC3_RELATIVES_H
0011 #define HEPMC3_RELATIVES_H
0012 #if defined(WIN32)&&(!defined(HEPMC3search_NO_Relatives_EXPORTS))
0013 #ifdef HepMC3search_EXPORTS
0014 #define HEPMC3search_Relatives_EXPORT_API  __declspec(dllexport)
0015 #else
0016 #define HEPMC3search_Relatives_EXPORT_API  __declspec(dllimport)
0017 #endif
0018 #else
0019 #define HEPMC3search_Relatives_EXPORT_API
0020 #endif
0021 
0022 
0023 #include <vector>
0024 #include "HepMC3/GenParticle.h"
0025 #include "HepMC3/GenVertex.h"
0026 namespace HepMC3 {
0027 std::vector<HepMC3::GenParticlePtr>      children_particles(const HepMC3::GenVertexPtr& O);   ///< Return children particles
0028 std::vector<HepMC3::ConstGenParticlePtr> children_particles(const HepMC3::ConstGenVertexPtr& O); ///< Return children particles
0029 std::vector<HepMC3::GenVertexPtr>        children_vertices(const HepMC3::GenParticlePtr& O); ///< Return children vertices
0030 std::vector<HepMC3::ConstGenVertexPtr>   children_vertices(const HepMC3::ConstGenParticlePtr& O); ///< Return children vertices
0031 std::vector<HepMC3::GenParticlePtr>      grandchildren_particles(const HepMC3::GenParticlePtr& O);  ///< Return grandchildren particles
0032 std::vector<HepMC3::ConstGenParticlePtr> grandchildren_particles(const HepMC3::ConstGenParticlePtr& O);  ///< Return grandchildren particles
0033 std::vector<HepMC3::GenVertexPtr>        grandchildren_vertices(const HepMC3::GenVertexPtr& O);   ///< Return grandchildren vertices
0034 std::vector<HepMC3::ConstGenVertexPtr>   grandchildren_vertices(const HepMC3::ConstGenVertexPtr& O); ///< Return grandchildren vertices
0035 std::vector<HepMC3::GenParticlePtr>      parent_particles(const HepMC3::GenVertexPtr& O);  ///< Return parent particles
0036 std::vector<HepMC3::ConstGenParticlePtr> parent_particles(const HepMC3::ConstGenVertexPtr& O);   ///< Return parent particles
0037 std::vector<HepMC3::GenVertexPtr>        parent_vertices(const HepMC3::GenParticlePtr& O);   ///< Return parent vertices
0038 std::vector<HepMC3::ConstGenVertexPtr>   parent_vertices(const HepMC3::ConstGenParticlePtr& O);    ///< Return parent vertices
0039 std::vector<HepMC3::GenParticlePtr>      grandparent_particles(const HepMC3::GenParticlePtr& O);    ///< Return grandparent particles
0040 std::vector<HepMC3::ConstGenParticlePtr> grandparent_particles(const HepMC3::ConstGenParticlePtr& O);     ///< Return grandparent particles
0041 std::vector<HepMC3::GenVertexPtr>        grandparent_vertices(const HepMC3::GenVertexPtr& O);      ///< Return grandparent vertices
0042 std::vector<HepMC3::ConstGenVertexPtr>   grandparent_vertices(const HepMC3::ConstGenVertexPtr& O);       ///< Return grandparent vertices
0043 std::vector<HepMC3::ConstGenParticlePtr> descendant_particles(const HepMC3::ConstGenVertexPtr& obj);       ///< Return descendant particles
0044 std::vector<HepMC3::GenParticlePtr>      descendant_particles(const HepMC3::GenVertexPtr& obj);       ///< Return descendant particles
0045 std::vector<HepMC3::ConstGenParticlePtr> descendant_particles(const HepMC3::ConstGenParticlePtr& obj);       ///< Return descendant particles
0046 std::vector<HepMC3::GenParticlePtr>      descendant_particles(const HepMC3::GenParticlePtr& obj);       ///< Return descendant particles
0047 std::vector<HepMC3::ConstGenVertexPtr>   descendant_vertices(const HepMC3::ConstGenParticlePtr& obj);       ///< Return descendant vertices
0048 std::vector<HepMC3::GenVertexPtr>        descendant_vertices(const HepMC3::GenParticlePtr& obj);       ///< Return descendant vertices
0049 std::vector<HepMC3::ConstGenVertexPtr>   descendant_vertices(const HepMC3::ConstGenVertexPtr& obj);       ///< Return descendant vertices
0050 std::vector<HepMC3::GenVertexPtr>        descendant_vertices(const HepMC3::GenVertexPtr& obj);       ///< Return descendant vertices
0051 std::vector<HepMC3::ConstGenParticlePtr> ancestor_particles(const HepMC3::ConstGenVertexPtr& obj);       ///< Return ancestor particles
0052 std::vector<HepMC3::GenParticlePtr>      ancestor_particles(const HepMC3::GenVertexPtr& obj);      ///< Return ancestor particles
0053 std::vector<HepMC3::ConstGenParticlePtr> ancestor_particles(const HepMC3::ConstGenParticlePtr& obj);      ///< Return ancestor particles
0054 std::vector<HepMC3::GenParticlePtr>      ancestor_particles(const HepMC3::GenParticlePtr& obj);      ///< Return ancestor particles
0055 std::vector<HepMC3::ConstGenVertexPtr>   ancestor_vertices(const HepMC3::ConstGenParticlePtr& obj);      ///< Return ancestor vertices
0056 std::vector<HepMC3::GenVertexPtr>        ancestor_vertices(const HepMC3::GenParticlePtr& obj);      ///< Return ancestor vertices
0057 std::vector<HepMC3::ConstGenVertexPtr>   ancestor_vertices(const HepMC3::ConstGenVertexPtr& obj);      ///< Return ancestor vertices
0058 std::vector<HepMC3::GenVertexPtr>        ancestor_vertices(const HepMC3::GenVertexPtr& obj);      ///< Return ancestor vertices
0059 }
0060 
0061 
0062 
0063 namespace HepMC3 {
0064 
0065 /// forward declare the Relatives interface in which _parents and _children are wrapped
0066 template<typename T>
0067 class RelativesInterface;
0068 /// forward declare the recursion wrapper
0069 template<typename T>
0070 class Recursive;
0071 
0072 /** @brief Provides operator to find the parent particles of a Vertex or Particle
0073  *
0074  * Note you would usually not instantiate this directly, but wrap it in a RelativesInterface
0075  */
0076 class _parents {
0077 public:
0078     /** @brief  operator */
0079     template<typename GenObject_type, typename dummy>
0080     GenParticles_type<GenObject_type> operator()(GenObject_type input) const;
0081 
0082     /** @brief  operator */
0083     template<typename GenObject_type, typename std::enable_if<std::is_same<GenVertex, typename std::remove_const<typename GenObject_type::element_type>::type>::value, int*>::type = nullptr>
0084     GenParticles_type<GenObject_type> operator()(GenObject_type input) const {return input->particles_in();}
0085 
0086     /** @brief  operator */
0087     template<typename GenObject_type, typename std::enable_if<std::is_same<GenParticle, typename std::remove_const<typename GenObject_type::element_type>::type>::value, int*>::type = nullptr>
0088     GenParticles_type<GenObject_type> operator()(GenObject_type input) const {return (*this)(vertex(input));}
0089 
0090     /** @brief  vertex */
0091     template<typename GenObject_type>
0092     GenVertex_type<GenObject_type> vertex(GenObject_type input) const {return input->production_vertex();}
0093 };
0094 
0095 /** @brief Provides operator to find the child particles of a Vertex or Particle
0096  *
0097  * Note you would usually not instantiate this directly, but wrap it in a RelativesInterface
0098  */
0099 class _children {
0100 public:
0101     /// @brief operator
0102     template<typename GenObject_type, typename dummy>
0103     GenParticles_type<GenObject_type> operator()(GenObject_type input) const;
0104 
0105     /// @brief operator
0106     template<typename GenObject_type, typename std::enable_if<std::is_same<GenVertex, typename std::remove_const<typename GenObject_type::element_type>::type>::value, int*>::type = nullptr>
0107     GenParticles_type<GenObject_type> operator()(GenObject_type input) const {return input->particles_out();}
0108 
0109     /// @brief operator
0110     template<typename GenObject_type, typename std::enable_if<std::is_same<GenParticle, typename std::remove_const<typename GenObject_type::element_type>::type>::value, int*>::type = nullptr>
0111     GenParticles_type<GenObject_type> operator()(GenObject_type input) const {return (*this)(vertex(input));}
0112 
0113     /// @brief operator
0114     template<typename GenObject_type>
0115     GenVertex_type<GenObject_type> vertex(GenObject_type input) const {return input->end_vertex();}
0116 };
0117 #ifdef _MSC_VER
0118 /// The thread_local will not work with DLLs, so the replacement should be thread-safe
0119 class SearchParents {
0120 public:
0121  std::vector<ConstGenParticlePtr> operator()(ConstGenVertexPtr input) { return parent_particles(input);}
0122  std::vector<GenParticlePtr> operator()(GenVertexPtr input) { return parent_particles(input);}
0123  std::vector<ConstGenParticlePtr> operator()(ConstGenParticlePtr input) { return grandparent_particles(input);}
0124  std::vector<GenParticlePtr> operator()(GenParticlePtr input) { return grandparent_particles(input);}
0125 };
0126 
0127 class SearchChildren {
0128 public:
0129  std::vector<ConstGenParticlePtr> operator()(ConstGenVertexPtr input)const  { return children_particles(input);}
0130  std::vector<GenParticlePtr> operator()(GenVertexPtr input)const  { return children_particles(input);}
0131  std::vector<ConstGenParticlePtr> operator()(ConstGenParticlePtr input)const  { return grandchildren_particles(input);}
0132  std::vector<GenParticlePtr> operator()(GenParticlePtr input)const  { return grandchildren_particles(input);}
0133 };
0134 
0135 class SearchAncestors {
0136 public:
0137  std::vector<ConstGenParticlePtr> operator()(ConstGenVertexPtr input) const { return ancestor_particles(input);}
0138  std::vector<GenParticlePtr> operator()(GenVertexPtr input)const  { return ancestor_particles(input);}
0139  std::vector<ConstGenParticlePtr> operator()(ConstGenParticlePtr input)const  { return ancestor_particles(input);}
0140  std::vector<GenParticlePtr> operator()(GenParticlePtr input)const  { return ancestor_particles(input);}
0141 };
0142 
0143 class SearchDescendants {
0144 public:
0145  std::vector<ConstGenParticlePtr> operator()(ConstGenVertexPtr input)const  { return descendant_particles(input);}
0146  std::vector<GenParticlePtr> operator()(GenVertexPtr input)const  { return descendant_particles(input);}
0147  std::vector<ConstGenParticlePtr> operator()(ConstGenParticlePtr input)const  { return descendant_particles(input);}
0148  std::vector<GenParticlePtr> operator()(GenParticlePtr input) const { return descendant_particles(input);}
0149 };
0150 
0151 /// alias
0152 using Parents  = SearchParents;
0153 /// alias
0154 using Children = SearchChildren;
0155 /// Ancestors
0156 using Ancestors = SearchAncestors;
0157 /// Descendants
0158 using Descendants = SearchDescendants;
0159 
0160 #else
0161 /// alias of _parents wrapped in the Relatives interface
0162 using Parents  = RelativesInterface<_parents>;
0163 /// alias of _children wrapped in the Relatives interface
0164 using Children = RelativesInterface<_children>;
0165 /// Ancestors is an alias to Recursion applied to the _parents and wrapped in the Relatives interface
0166 using Ancestors = RelativesInterface<Recursive<_parents> >;
0167 /// Descendants is an alias to Recursion applied to the _children and wrapped in the Relatives interface
0168 using Descendants = RelativesInterface<Recursive<_children> >;
0169 #endif
0170 /** @brief  Define a common interface that all Relatives objects will satisfy
0171  *         Relatives provides an operator to get the relatives of a range of different
0172  *         GenObject types.  The following are examples
0173  *
0174  *         Relatives::ANCESTORS(GenParticlePtr);// returns ancestors of the particle
0175  *         Descendants descendants;
0176  *         descendants(GenVertexPtr);// descendants of the vertex
0177  *         vector<Relatives*> relations = {&Relatives::CHILDREN, &Relatives::DESCENDANTS, &Relatives::PARENTS, new Ancestors()}; // make a vector of Relatives
0178  *
0179  *         You can also define your own relation and wrap it in the Relatives interface using
0180  *         Relatives * relo = new RelativesInterface<MyRelationClass>();
0181  */
0182 class Relatives {
0183 public:
0184     /// @brief Operator
0185     virtual std::vector<GenParticlePtr> operator()(GenParticlePtr input) const = 0;
0186     /// @brief Operator
0187     virtual std::vector<ConstGenParticlePtr> operator()(ConstGenParticlePtr input) const = 0;
0188     /// @brief Operator
0189     virtual std::vector<GenParticlePtr> operator()(GenVertexPtr input) const = 0;
0190     /// @brief Operator
0191     virtual std::vector<ConstGenParticlePtr> operator()(ConstGenVertexPtr input) const = 0;
0192 
0193 #ifdef _MSC_VER
0194 /// The thread_local will not work with VS, see https://docs.microsoft.com/en-us/cpp/error-messages/compiler-errors-1/compiler-error-c2492?redirectedfrom=MSDN&view=msvc-170
0195 /// Dropping the thread_local is not what was intended initially, so instead an implementation with free functions should be used.
0196     HEPMC3search_Relatives_EXPORT_API static const Parents PARENTS;  ///< Parents
0197     HEPMC3search_Relatives_EXPORT_API static const Children CHILDREN;  ///< Children
0198     HEPMC3search_Relatives_EXPORT_API static const Ancestors ANCESTORS;  ///< Ancestors
0199     HEPMC3search_Relatives_EXPORT_API static const Descendants DESCENDANTS;  ///< Descendants
0200 #else
0201     HEPMC3search_Relatives_EXPORT_API static const Parents PARENTS;  ///< Parents
0202     HEPMC3search_Relatives_EXPORT_API static const Children CHILDREN;  ///< Children
0203     HEPMC3search_Relatives_EXPORT_API static thread_local const Ancestors ANCESTORS;  ///< Ancestors
0204     HEPMC3search_Relatives_EXPORT_API static thread_local const Descendants DESCENDANTS;  ///< Descendants
0205 #endif
0206 
0207 };
0208 
0209 /** @brief wrap a templated class that implements Relatives
0210  *  Since we need to template the functionality on the input
0211  *  type (GenParticlePtr, ConstGenVertexPtr etc.) we must wrap a
0212  *  class that has a templated operator in this that provides the
0213  *  Relatives interface and calls through to the underlying template
0214  *  method.
0215  */
0216 template<typename Relative_type>
0217 class RelativesInterface : public Relatives {
0218 public:
0219     //RelativesInterface(Relative_type relatives): _internal(relatives){}
0220     constexpr RelativesInterface() {}
0221 
0222     /// @brief Operator
0223     GenParticles_type<GenParticlePtr> operator()(GenParticlePtr input) const override {return _internal(input);}
0224     /// @brief Operator
0225     GenParticles_type<ConstGenParticlePtr> operator()(ConstGenParticlePtr input) const override {return _internal(input);}
0226     /// @brief Operator
0227     GenParticles_type<GenVertexPtr> operator()(GenVertexPtr input) const override {return _internal(input);}
0228     /// @brief Operator
0229     GenParticles_type<ConstGenVertexPtr> operator()(ConstGenVertexPtr input) const override {return _internal(input);}
0230 
0231 private:
0232     /// Internal relatives code 
0233     Relative_type _internal;
0234 };
0235 /** @brief  Recursive */
0236 template<typename Relation_type>
0237 class Recursive {
0238 public:
0239     /// @brief Operator
0240     template<typename GenObject_type>
0241     GenParticles_type<GenObject_type> operator()(GenObject_type input) const {
0242         for (auto obj: m_checkedObjects) {
0243             delete obj;
0244         }
0245         m_checkedObjects.clear();
0246         return _recursive(input);
0247     }
0248     ~Recursive() { 
0249         for (auto obj: m_checkedObjects) {
0250             delete obj;
0251         }
0252         m_checkedObjects.clear();
0253     }
0254 private:
0255     /// @brief recursive
0256     template<typename GenObject_type, typename dummy>
0257     GenParticles_type<GenObject_type> _recursive(GenObject_type input) const;
0258 
0259     /// @brief recursive
0260     GenParticles_type<GenVertexPtr> _recursive(GenVertexPtr input) const {
0261         GenParticles_type <GenVertexPtr> results;
0262         if ( !input ) return results;
0263         for (auto v: m_checkedObjects) {
0264             if (v->id() == input->id()) return results;
0265         }
0266 
0267         m_checkedObjects.emplace_back(new idInterface<GenVertexPtr>(input));
0268 
0269         for (auto p: m_applyRelation(input)) {
0270             results.emplace_back(p);
0271             GenParticles_type <GenVertexPtr> tmp = _recursive(p);
0272             results.insert(results.end(),
0273                            std::make_move_iterator(tmp.begin()),
0274                            std::make_move_iterator(tmp.end()));
0275         }
0276 
0277         return results;
0278     }
0279 
0280     /// @brief recursive
0281     GenParticles_type<ConstGenVertexPtr> _recursive(ConstGenVertexPtr input) const {
0282         GenParticles_type <ConstGenVertexPtr> results;
0283         if ( !input ) return results;
0284         for (auto v: m_checkedObjects) {
0285             if (v->id() == input->id()) return results;
0286         }
0287 
0288         m_checkedObjects.emplace_back(new idInterface<ConstGenVertexPtr>(input));
0289 
0290         for (auto p: m_applyRelation(input)) {
0291             results.emplace_back(p);
0292             GenParticles_type <ConstGenVertexPtr> tmp = _recursive(p);
0293             results.insert(results.end(),
0294                            std::make_move_iterator(tmp.begin()),
0295                            std::make_move_iterator(tmp.end()));
0296         }
0297 
0298         return results;
0299     }
0300 
0301     /** @brief  recursive */
0302     GenParticles_type<GenParticlePtr> _recursive(GenParticlePtr input) const {
0303         return _recursive(m_applyRelation.vertex(input));
0304     }
0305     /** @brief  recursive */
0306     GenParticles_type<ConstGenParticlePtr> _recursive(ConstGenParticlePtr input) const {
0307         return _recursive(m_applyRelation.vertex(input));
0308     }
0309 
0310 
0311     /** @brief  hasID */
0312     class hasId {
0313     public:
0314         /// @brief destructor
0315         virtual ~hasId() {}
0316         /// @brief id
0317         virtual int id() const = 0;
0318     };
0319     /** @brief  iDinterface */
0320     template<typename ID_type>
0321     class idInterface : public hasId {
0322     public:
0323         /** @brief  idInterface */
0324         constexpr idInterface(ID_type genObject): m_object(genObject) {}
0325         /** @brief  id */
0326         int id() const override {return m_object->id();}
0327 
0328     private:
0329         ID_type m_object;  ///< id of object
0330     };
0331 
0332     Relation_type m_applyRelation;   ///< applyRelation
0333     mutable std::vector<hasId*> m_checkedObjects; ///< Checked objects
0334 };
0335 
0336 }
0337 #endif
0338