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  if ( !input ) return results;
117  for(auto v: m_checkedObjects){
118  if(v->id() == input->id()) return results;
119  }
120 
121  m_checkedObjects.emplace_back(new idInterface<GenObject_type>(input));
122 
123  for(auto p: m_applyRelation(input)){
124  results.emplace_back(p);
125  GenParticles_type <GenObject_type> tmp = _recursive(p);
126  results.insert(results.end(),
127  std::make_move_iterator(tmp.begin()),
128  std::make_move_iterator(tmp.end()));
129  }
130 
131  return results;
132  }
133 
134  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>
135  GenParticles_type<GenObject_type> _recursive(GenObject_type input) const {
136  return _recursive(m_applyRelation.vertex(input));
137  }
138 
139  class hasId{
140 
141  public:
142  virtual ~hasId(){}
143  virtual int id() const = 0;
144  };
145 
146  template<typename ID_type>
147  class idInterface : public hasId{
148 
149  public:
150  constexpr idInterface(ID_type genObject): m_object(genObject){}
151  int id() const {return m_object->id();}
152 
153  private:
154 
155  ID_type m_object;
156 
157  };
158 
159  Relation_type m_applyRelation;
160  mutable std::vector<hasId*> m_checkedObjects;
161 
162  };
163 
164  /** @brief Provides operator to find the parent particles of a Vertex or Particle
165  *
166  * Note you would usually not instantiate this directly, but wrap it in a RelativesInterface
167  */
168  class _parents{
169 
170  public:
171 
172  template<typename GenObject_type, typename dummy>
173  GenParticles_type<GenObject_type> operator()(GenObject_type input) const;
174 
175  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>
176  GenParticles_type<GenObject_type> operator()(GenObject_type input) const {return input->particles_in();}
177 
178  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>
179  GenParticles_type<GenObject_type> operator()(GenObject_type input) const {return (*this)(vertex(input));}
180 
181  template<typename GenObject_type>
182  GenVertex_type<GenObject_type> vertex(GenObject_type input) const {return input->production_vertex();}
183 
184  };
185 
186  /** @brief Provides operator to find the child particles of a Vertex or Particle
187  *
188  * Note you would usually not instantiate this directly, but wrap it in a RelativesInterface
189  */
190  class _children{
191 
192  public:
193 
194  template<typename GenObject_type, typename dummy>
195  GenParticles_type<GenObject_type> operator()(GenObject_type input) const;
196 
197  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>
198  GenParticles_type<GenObject_type> operator()(GenObject_type input) const {return input->particles_out();}
199 
200  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>
201  GenParticles_type<GenObject_type> operator()(GenObject_type input) const {return (*this)(vertex(input));}
202 
203  template<typename GenObject_type>
204  GenVertex_type<GenObject_type> vertex(GenObject_type input) const {return input->end_vertex();}
205 
206  };
207 
208 }
209 
210 #endif
211 
Provides operator to find the child particles of a Vertex or Particle.
Definition: Relatives.h:190
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:168
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