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 thread_local const Ancestors ANCESTORS;
63  static thread_local 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 /** @brief Recursive */
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  /** @brief hasID */
140  class hasId {
141 
142  public:
143  virtual ~hasId() {}
144  virtual int id() const = 0;
145  };
146  /** @brief iDinterface */
147  template<typename ID_type>
148  class idInterface : public hasId {
149 
150  public:
151  constexpr idInterface(ID_type genObject): m_object(genObject) {}
152  int id() const {return m_object->id();}
153 
154  private:
155 
156  ID_type m_object;
157 
158  };
159 
160  Relation_type m_applyRelation;
161  mutable std::vector<hasId*> m_checkedObjects;
162 
163 };
164 
165 /** @brief Provides operator to find the parent particles of a Vertex or Particle
166  *
167  * Note you would usually not instantiate this directly, but wrap it in a RelativesInterface
168  */
169 class _parents {
170 
171 public:
172 
173  template<typename GenObject_type, typename dummy>
174  GenParticles_type<GenObject_type> operator()(GenObject_type input) const;
175 
176  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>
177  GenParticles_type<GenObject_type> operator()(GenObject_type input) const {return input->particles_in();}
178 
179  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>
180  GenParticles_type<GenObject_type> operator()(GenObject_type input) const {return (*this)(vertex(input));}
181 
182  template<typename GenObject_type>
183  GenVertex_type<GenObject_type> vertex(GenObject_type input) const {return input->production_vertex();}
184 
185 };
186 
187 /** @brief Provides operator to find the child particles of a Vertex or Particle
188  *
189  * Note you would usually not instantiate this directly, but wrap it in a RelativesInterface
190  */
191 class _children {
192 
193 public:
194 
195  template<typename GenObject_type, typename dummy>
196  GenParticles_type<GenObject_type> operator()(GenObject_type input) const;
197 
198  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>
199  GenParticles_type<GenObject_type> operator()(GenObject_type input) const {return input->particles_out();}
200 
201  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>
202  GenParticles_type<GenObject_type> operator()(GenObject_type input) const {return (*this)(vertex(input));}
203 
204  template<typename GenObject_type>
205  GenVertex_type<GenObject_type> vertex(GenObject_type input) const {return input->end_vertex();}
206 
207 };
208 
209 }
210 
211 #endif
212 
HepMC3::Recursive::idInterface
iDinterface
Definition: Relatives.h:148
GenVertex.h
Definition of class GenVertex.
HepMC3
HepMC3 main namespace.
Definition: AnalysisExample.h:18
GenParticle.h
Definition of class GenParticle.
HepMC3::_children
Provides operator to find the child particles of a Vertex or Particle.
Definition: Relatives.h:191
HepMC3::Recursive
forward declare the recursion wrapper
Definition: Relatives.h:23
HepMC3::RelativesInterface
forward declare the Relatives interface in which _parents and _children are wrapped
Definition: Relatives.h:20
HepMC3::_parents
Provides operator to find the parent particles of a Vertex or Particle.
Definition: Relatives.h:169
HepMC3::Relatives
Define a common interface that all Relatives objects will satisfy Relatives provides an operator to g...
Definition: Relatives.h:51
HepMC3::Recursive::hasId
hasID
Definition: Relatives.h:140