HepMC3 event record library
Relatives.h
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // This file is part of HepMC
4 // Copyright (C) 2014-2019 The HepMC collaboration (see AUTHORS for details)
5 //
6 ///
7 /// @file Relatives.h
8 /// @brief Defines helper classes to extract relatives of an input GenParticle or GenVertex
9 ///
10 #ifndef HEPMC3_RELATIVES_H
11 #define HEPMC3_RELATIVES_H
12 
13 #include "HepMC3/GenParticle.h"
14 #include "HepMC3/GenVertex.h"
15 
16 namespace HepMC3{
17 
18  // forward declare the Relatives interface in which _parents and _children are wrapped
19  template<typename T>
21  // forward declare the recursion wrapper
22  template<typename T>
23  class Recursive;
24 
25  // forward declare _parents class
26  class _parents;
27  // forward declare _children class
28  class _children;
29 
30  /// alias of _parents wrapped in the Relatives interface
32  /// alias of _children wrapped in the Relatives interface
34  /// Ancestors is an alias to Recursion applied to the _parents and wrapped in the Relatives interface
36  /// Descendants is an alias to Recursion applied to the _children and wrapped in the Relatives interface
38 
39  /** @brief Define a common interface that all Relatives objects will satisfy
40  * Relatives provides an operator to get the relatives of a range of different
41  * GenObject types. The following are examples
42  *
43  * Relatives::ANCESTORS(GenParticlePtr);// returns ancestors of the particle
44  * Descendants descendants;
45  * descendants(GenVertexPtr);// descendants of the vertex
46  * vector<Relatives*> relations = {&Relatives::CHILDREN, &Relatives::DESCENDANTS, &Relatives::PARENTS, new Ancestors()}; // make a vector of Relatives
47  *
48  * You can also define your own relation and wrap it in the Relatives interface using
49  * Relatives * relo = new RelativesInterface<MyRelationClass>();
50  */
51  class Relatives{
52 
53  public:
54 
55  virtual std::vector<GenParticlePtr> operator()(GenParticlePtr input) const = 0;
56  virtual std::vector<ConstGenParticlePtr> operator()(ConstGenParticlePtr input) const = 0;
57  virtual std::vector<GenParticlePtr> operator()(GenVertexPtr input) const = 0;
58  virtual std::vector<ConstGenParticlePtr> operator()(ConstGenVertexPtr input) const = 0;
59 
60  static const Parents PARENTS;
61  static const Children CHILDREN;
62  static const Ancestors ANCESTORS;
63  static const Descendants DESCENDANTS;
64  };
65 
66  /** @brief wrap a templated class that implements Relatives
67  * Since we need to template the functionality on the input
68  * type (GenParticlePtr, ConstGenVertexPtr etc.) we must wrap a
69  * class that has a templated operator in this that provides the
70  * Relatives interface and calls through to the underlying template
71  * method.
72  */
73  template<typename Relative_type>
74  class RelativesInterface : public Relatives{
75 
76  public:
77 
78  //RelativesInterface(Relative_type relatives): _internal(relatives){}
79 
80  constexpr RelativesInterface(){}
81 
82  GenParticles_type<GenParticlePtr> operator()(GenParticlePtr input) const override {return _internal(input);}
83  GenParticles_type<ConstGenParticlePtr> operator()(ConstGenParticlePtr input) const override {return _internal(input);}
84  GenParticles_type<GenVertexPtr> operator()(GenVertexPtr input) const override {return _internal(input);}
85  GenParticles_type<ConstGenVertexPtr> operator()(ConstGenVertexPtr input) const override {return _internal(input);}
86 
87  private:
88 
89  Relative_type _internal;
90 
91  };
92 
93  template<typename Relation_type>
94  class Recursive{
95 
96  public:
97 
98  template<typename GenObject_type>
99  GenParticles_type<GenObject_type> operator()(GenObject_type input) const {
100  for(auto obj: m_checkedObjects){
101  delete obj;
102  }
103  m_checkedObjects.clear();
104  return _recursive(input);
105  }
106 
107  private:
108 
109  template<typename GenObject_type, typename dummy>
110  GenParticles_type<GenObject_type> _recursive(GenObject_type input) const ;
111 
112  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>
113  GenParticles_type<GenObject_type> _recursive(GenObject_type input) const {
114 
115  GenParticles_type <GenObject_type> results;
116  for(auto v: m_checkedObjects){
117  if(v->id() == input->id()) return results;
118  }
119 
120  m_checkedObjects.emplace_back(new idInterface<GenObject_type>(input));
121 
122  for(auto p: m_applyRelation(input)){
123  results.emplace_back(p);
124  GenParticles_type <GenObject_type> tmp = _recursive(p);
125  results.insert(results.end(),
126  std::make_move_iterator(tmp.begin()),
127  std::make_move_iterator(tmp.end()));
128  }
129 
130  return results;
131  }
132 
133  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>
134  GenParticles_type<GenObject_type> _recursive(GenObject_type input) const {
135  return _recursive(m_applyRelation.vertex(input));
136  }
137 
138  class hasId{
139 
140  public:
141  virtual ~hasId(){}
142  virtual int id() const = 0;
143  };
144 
145  template<typename ID_type>
146  class idInterface : public hasId{
147 
148  public:
149  constexpr idInterface(ID_type genObject): m_object(genObject){}
150  int id() const {return m_object->id();}
151 
152  private:
153 
154  ID_type m_object;
155 
156  };
157 
158  Relation_type m_applyRelation;
159  mutable std::vector<hasId*> m_checkedObjects;
160 
161  };
162 
163  /** @brief Provides operator to find the parent particles of a Vertex or Particle
164  *
165  * Note you would usually not instantiate this directly, but wrap it in a RelativesInterface
166  */
167  class _parents{
168 
169  public:
170 
171  template<typename GenObject_type, typename dummy>
172  GenParticles_type<GenObject_type> operator()(GenObject_type input) const;
173 
174  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>
175  GenParticles_type<GenObject_type> operator()(GenObject_type input) const {return input->particles_in();}
176 
177  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>
178  GenParticles_type<GenObject_type> operator()(GenObject_type input) const {return (*this)(vertex(input));}
179 
180  template<typename GenObject_type>
181  GenVertex_type<GenObject_type> vertex(GenObject_type input) const {return input->production_vertex();}
182 
183  };
184 
185  /** @brief Provides operator to find the child particles of a Vertex or Particle
186  *
187  * Note you would usually not instantiate this directly, but wrap it in a RelativesInterface
188  */
189  class _children{
190 
191  public:
192 
193  template<typename GenObject_type, typename dummy>
194  GenParticles_type<GenObject_type> operator()(GenObject_type input) const;
195 
196  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>
197  GenParticles_type<GenObject_type> operator()(GenObject_type input) const {return input->particles_out();}
198 
199  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>
200  GenParticles_type<GenObject_type> operator()(GenObject_type input) const {return (*this)(vertex(input));}
201 
202  template<typename GenObject_type>
203  GenVertex_type<GenObject_type> vertex(GenObject_type input) const {return input->end_vertex();}
204 
205  };
206 
207 }
208 
209 #endif
210 
Provides operator to find the child particles of a Vertex or Particle.
Definition: Relatives.h:189
Definition of class GenParticle.
typename std::conditional< std::is_const< typename T::element_type >::value, ConstGenParticles, GenParticles >::type GenParticles_type
Provides operator to find the parent particles of a Vertex or Particle.
Definition: Relatives.h:167
wrap a templated class that implements Relatives Since we need to template the functionality on the i...
Definition: Relatives.h:20
Definition of class GenVertex.
Define a common interface that all Relatives objects will satisfy Relatives provides an operator to g...
Definition: Relatives.h:51