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-2021 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 #if defined(WIN32)&&(!defined(HEPMC3search_NO_Relatives_EXPORTS))
13 #ifdef HepMC3search_EXPORTS
14 #define HEPMC3search_Relatives_EXPORT_API __declspec(dllexport)
15 #else
16 #define HEPMC3search_Relatives_EXPORT_API __declspec(dllimport)
17 #endif
18 #else
19 #define HEPMC3search_Relatives_EXPORT_API
20 #endif
21 
22 
23 #include <vector>
24 #include "HepMC3/GenParticle.h"
25 #include "HepMC3/GenVertex.h"
26 namespace HepMC3 {
27 std::vector<HepMC3::GenParticlePtr> children_particles(HepMC3::GenVertexPtr O); ///< Return children particles
28 std::vector<HepMC3::ConstGenParticlePtr> children_particles(HepMC3::ConstGenVertexPtr O); ///< Return children particles
29 std::vector<HepMC3::GenVertexPtr> children_vertices(HepMC3::GenParticlePtr O); ///< Return children vertices
30 std::vector<HepMC3::ConstGenVertexPtr> children_vertices(HepMC3::ConstGenParticlePtr O); ///< Return children vertices
31 std::vector<HepMC3::GenParticlePtr> grandchildren_particles(HepMC3::GenParticlePtr O); ///< Return grandchildren particles
32 std::vector<HepMC3::ConstGenParticlePtr> grandchildren_particles(HepMC3::ConstGenParticlePtr O); ///< Return grandchildren particles
33 std::vector<HepMC3::GenVertexPtr> grandchildren_vertices(HepMC3::GenVertexPtr O); ///< Return grandchildren vertices
34 std::vector<HepMC3::ConstGenVertexPtr> grandchildren_vertices(HepMC3::ConstGenVertexPtr O); ///< Return grandchildren vertices
35 std::vector<HepMC3::GenParticlePtr> parent_particles(HepMC3::GenVertexPtr O); ///< Return parent particles
36 std::vector<HepMC3::ConstGenParticlePtr> parent_particles(HepMC3::ConstGenVertexPtr O); ///< Return parent particles
37 std::vector<HepMC3::GenVertexPtr> parent_vertices(HepMC3::GenParticlePtr O); ///< Return parent vertices
38 std::vector<HepMC3::ConstGenVertexPtr> parent_vertices(HepMC3::ConstGenParticlePtr O); ///< Return parent vertices
39 std::vector<HepMC3::GenParticlePtr> grandparent_particles(HepMC3::GenParticlePtr O); ///< Return grandparent particles
40 std::vector<HepMC3::ConstGenParticlePtr> grandparent_particles(HepMC3::ConstGenParticlePtr O); ///< Return grandparent particles
41 std::vector<HepMC3::GenVertexPtr> grandparent_vertices(HepMC3::GenVertexPtr O); ///< Return grandparent vertices
42 std::vector<HepMC3::ConstGenVertexPtr> grandparent_vertices(HepMC3::ConstGenVertexPtr O); ///< Return grandparent vertices
43 std::vector<HepMC3::ConstGenParticlePtr> descendant_particles(HepMC3::ConstGenVertexPtr obj); ///< Return descendant particles
44 std::vector<HepMC3::GenParticlePtr> descendant_particles(HepMC3::GenVertexPtr obj); ///< Return descendant particles
45 std::vector<HepMC3::ConstGenParticlePtr> descendant_particles(HepMC3::ConstGenParticlePtr obj); ///< Return descendant particles
46 std::vector<HepMC3::GenParticlePtr> descendant_particles(HepMC3::GenParticlePtr obj); ///< Return descendant particles
47 std::vector<HepMC3::ConstGenVertexPtr> descendant_vertices(HepMC3::ConstGenParticlePtr obj); ///< Return descendant vertices
48 std::vector<HepMC3::GenVertexPtr> descendant_vertices(HepMC3::GenParticlePtr obj); ///< Return descendant vertices
49 std::vector<HepMC3::ConstGenVertexPtr> descendant_vertices(HepMC3::ConstGenVertexPtr obj); ///< Return descendant vertices
50 std::vector<HepMC3::GenVertexPtr> descendant_vertices(HepMC3::GenVertexPtr obj); ///< Return descendant vertices
51 std::vector<HepMC3::ConstGenParticlePtr> ancestor_particles(HepMC3::ConstGenVertexPtr obj); ///< Return ancestor particles
52 std::vector<HepMC3::GenParticlePtr> ancestor_particles(HepMC3::GenVertexPtr obj); ///< Return ancestor particles
53 std::vector<HepMC3::ConstGenParticlePtr> ancestor_particles(HepMC3::ConstGenParticlePtr obj); ///< Return ancestor particles
54 std::vector<HepMC3::GenParticlePtr> ancestor_particles(HepMC3::GenParticlePtr obj); ///< Return ancestor particles
55 std::vector<HepMC3::ConstGenVertexPtr> ancestor_vertices(HepMC3::ConstGenParticlePtr obj); ///< Return ancestor vertices
56 std::vector<HepMC3::GenVertexPtr> ancestor_vertices(HepMC3::GenParticlePtr obj); ///< Return ancestor vertices
57 std::vector<HepMC3::ConstGenVertexPtr> ancestor_vertices(HepMC3::ConstGenVertexPtr obj); ///< Return ancestor vertices
58 std::vector<HepMC3::GenVertexPtr> ancestor_vertices(HepMC3::GenVertexPtr obj); ///< Return ancestor vertices
59 }
60 
61 
62 
63 namespace HepMC3 {
64 
65 /// forward declare the Relatives interface in which _parents and _children are wrapped
66 template<typename T>
68 /// forward declare the recursion wrapper
69 template<typename T>
70 class Recursive;
71 
72 /** @brief Provides operator to find the parent particles of a Vertex or Particle
73  *
74  * Note you would usually not instantiate this directly, but wrap it in a RelativesInterface
75  */
76 class _parents {
77 public:
78  /** @brief operator */
79  template<typename GenObject_type, typename dummy>
80  GenParticles_type<GenObject_type> operator()(GenObject_type input) const;
81 
82  /** @brief operator */
83  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>
84  GenParticles_type<GenObject_type> operator()(GenObject_type input) const {return input->particles_in();}
85 
86  /** @brief operator */
87  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>
88  GenParticles_type<GenObject_type> operator()(GenObject_type input) const {return (*this)(vertex(input));}
89 
90  /** @brief vertex */
91  template<typename GenObject_type>
92  GenVertex_type<GenObject_type> vertex(GenObject_type input) const {return input->production_vertex();}
93 };
94 
95 /** @brief Provides operator to find the child particles of a Vertex or Particle
96  *
97  * Note you would usually not instantiate this directly, but wrap it in a RelativesInterface
98  */
99 class _children {
100 public:
101  /// @brief operator
102  template<typename GenObject_type, typename dummy>
103  GenParticles_type<GenObject_type> operator()(GenObject_type input) const;
104 
105  /// @brief operator
106  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>
107  GenParticles_type<GenObject_type> operator()(GenObject_type input) const {return input->particles_out();}
108 
109  /// @brief operator
110  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>
111  GenParticles_type<GenObject_type> operator()(GenObject_type input) const {return (*this)(vertex(input));}
112 
113  /// @brief operator
114  template<typename GenObject_type>
115  GenVertex_type<GenObject_type> vertex(GenObject_type input) const {return input->end_vertex();}
116 };
117 #ifdef _MSC_VER
118 /// The thread_local will not work with DLLs, so the replacement should be thread-safe
119 class SearchParents {
120 public:
121  std::vector<ConstGenParticlePtr> operator()(ConstGenVertexPtr input) { return parent_particles(input);}
122  std::vector<GenParticlePtr> operator()(GenVertexPtr input) { return parent_particles(input);}
123  std::vector<ConstGenParticlePtr> operator()(ConstGenParticlePtr input) { return grandparent_particles(input);}
124  std::vector<GenParticlePtr> operator()(GenParticlePtr input) { return grandparent_particles(input);}
125 };
126 
127 class SearchChildren {
128 public:
129  std::vector<ConstGenParticlePtr> operator()(ConstGenVertexPtr input)const { return children_particles(input);}
130  std::vector<GenParticlePtr> operator()(GenVertexPtr input)const { return children_particles(input);}
131  std::vector<ConstGenParticlePtr> operator()(ConstGenParticlePtr input)const { return grandchildren_particles(input);}
132  std::vector<GenParticlePtr> operator()(GenParticlePtr input)const { return grandchildren_particles(input);}
133 };
134 
135 class SearchAncestors {
136 public:
137  std::vector<ConstGenParticlePtr> operator()(ConstGenVertexPtr input) const { return ancestor_particles(input);}
138  std::vector<GenParticlePtr> operator()(GenVertexPtr input)const { return ancestor_particles(input);}
139  std::vector<ConstGenParticlePtr> operator()(ConstGenParticlePtr input)const { return ancestor_particles(input);}
140  std::vector<GenParticlePtr> operator()(GenParticlePtr input)const { return ancestor_particles(input);}
141 };
142 
143 class SearchDescendants {
144 public:
145  std::vector<ConstGenParticlePtr> operator()(ConstGenVertexPtr input)const { return descendant_particles(input);}
146  std::vector<GenParticlePtr> operator()(GenVertexPtr input)const { return descendant_particles(input);}
147  std::vector<ConstGenParticlePtr> operator()(ConstGenParticlePtr input)const { return descendant_particles(input);}
148  std::vector<GenParticlePtr> operator()(GenParticlePtr input) const { return descendant_particles(input);}
149 };
150 
151 /// alias
152 using Parents = SearchParents;
153 /// alias
154 using Children = SearchChildren;
155 /// Ancestors
156 using Ancestors = SearchAncestors;
157 /// Descendants
158 using Descendants = SearchDescendants;
159 
160 #else
161 /// alias of _parents wrapped in the Relatives interface
163 /// alias of _children wrapped in the Relatives interface
165 /// Ancestors is an alias to Recursion applied to the _parents and wrapped in the Relatives interface
167 /// Descendants is an alias to Recursion applied to the _children and wrapped in the Relatives interface
169 #endif
170 /** @brief Define a common interface that all Relatives objects will satisfy
171  * Relatives provides an operator to get the relatives of a range of different
172  * GenObject types. The following are examples
173  *
174  * Relatives::ANCESTORS(GenParticlePtr);// returns ancestors of the particle
175  * Descendants descendants;
176  * descendants(GenVertexPtr);// descendants of the vertex
177  * vector<Relatives*> relations = {&Relatives::CHILDREN, &Relatives::DESCENDANTS, &Relatives::PARENTS, new Ancestors()}; // make a vector of Relatives
178  *
179  * You can also define your own relation and wrap it in the Relatives interface using
180  * Relatives * relo = new RelativesInterface<MyRelationClass>();
181  */
182 class Relatives {
183 public:
184  /// @brief Operator
185  virtual std::vector<GenParticlePtr> operator()(GenParticlePtr input) const = 0;
186  /// @brief Operator
187  virtual std::vector<ConstGenParticlePtr> operator()(ConstGenParticlePtr input) const = 0;
188  /// @brief Operator
189  virtual std::vector<GenParticlePtr> operator()(GenVertexPtr input) const = 0;
190  /// @brief Operator
191  virtual std::vector<ConstGenParticlePtr> operator()(ConstGenVertexPtr input) const = 0;
192 
193 #ifdef _MSC_VER
194 /// 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
195 /// Dropping the thread_local is not what was intended initially, so instead an implementation with free functions should be used.
196  HEPMC3search_Relatives_EXPORT_API static const Parents PARENTS; ///< Parents
197  HEPMC3search_Relatives_EXPORT_API static const Children CHILDREN; ///< Children
198  HEPMC3search_Relatives_EXPORT_API static const Ancestors ANCESTORS; ///< Ancestors
199  HEPMC3search_Relatives_EXPORT_API static const Descendants DESCENDANTS; ///< Descendants
200 #else
201  HEPMC3search_Relatives_EXPORT_API static const Parents PARENTS; ///< Parents
202  HEPMC3search_Relatives_EXPORT_API static const Children CHILDREN; ///< Children
203  HEPMC3search_Relatives_EXPORT_API static thread_local const Ancestors ANCESTORS; ///< Ancestors
204  HEPMC3search_Relatives_EXPORT_API static thread_local const Descendants DESCENDANTS; ///< Descendants
205 #endif
206 
207 };
208 
209 /** @brief wrap a templated class that implements Relatives
210  * Since we need to template the functionality on the input
211  * type (GenParticlePtr, ConstGenVertexPtr etc.) we must wrap a
212  * class that has a templated operator in this that provides the
213  * Relatives interface and calls through to the underlying template
214  * method.
215  */
216 template<typename Relative_type>
217 class RelativesInterface : public Relatives {
218 public:
219  //RelativesInterface(Relative_type relatives): _internal(relatives){}
220  constexpr RelativesInterface() {}
221 
222  /// @brief Operator
223  GenParticles_type<GenParticlePtr> operator()(GenParticlePtr input) const override {return _internal(input);}
224  /// @brief Operator
225  GenParticles_type<ConstGenParticlePtr> operator()(ConstGenParticlePtr input) const override {return _internal(input);}
226  /// @brief Operator
227  GenParticles_type<GenVertexPtr> operator()(GenVertexPtr input) const override {return _internal(input);}
228  /// @brief Operator
229  GenParticles_type<ConstGenVertexPtr> operator()(ConstGenVertexPtr input) const override {return _internal(input);}
230 
231 private:
232  Relative_type _internal;
233 };
234 /** @brief Recursive */
235 template<typename Relation_type>
236 class Recursive {
237 public:
238  /// @brief Operator
239  template<typename GenObject_type>
240  GenParticles_type<GenObject_type> operator()(GenObject_type input) const {
241  for (auto obj: m_checkedObjects) {
242  delete obj;
243  }
244  m_checkedObjects.clear();
245  return _recursive(input);
246  }
247 
248 private:
249  /// @brief recursive
250  template<typename GenObject_type, typename dummy>
251  GenParticles_type<GenObject_type> _recursive(GenObject_type input) const;
252 
253  /// @brief recursive
254  GenParticles_type<GenVertexPtr> _recursive(GenVertexPtr input) const {
255  GenParticles_type <GenVertexPtr> results;
256  if ( !input ) return results;
257  for (auto v: m_checkedObjects) {
258  if (v->id() == input->id()) return results;
259  }
260 
261  m_checkedObjects.emplace_back(new idInterface<GenVertexPtr>(input));
262 
263  for (auto p: m_applyRelation(input)) {
264  results.emplace_back(p);
265  GenParticles_type <GenVertexPtr> tmp = _recursive(p);
266  results.insert(results.end(),
267  std::make_move_iterator(tmp.begin()),
268  std::make_move_iterator(tmp.end()));
269  }
270 
271  return results;
272  }
273 
274  /// @brief recursive
275  GenParticles_type<ConstGenVertexPtr> _recursive(ConstGenVertexPtr input) const {
276  GenParticles_type <ConstGenVertexPtr> results;
277  if ( !input ) return results;
278  for (auto v: m_checkedObjects) {
279  if (v->id() == input->id()) return results;
280  }
281 
282  m_checkedObjects.emplace_back(new idInterface<ConstGenVertexPtr>(input));
283 
284  for (auto p: m_applyRelation(input)) {
285  results.emplace_back(p);
286  GenParticles_type <ConstGenVertexPtr> tmp = _recursive(p);
287  results.insert(results.end(),
288  std::make_move_iterator(tmp.begin()),
289  std::make_move_iterator(tmp.end()));
290  }
291 
292  return results;
293  }
294 
295  /** @brief recursive */
296  GenParticles_type<GenParticlePtr> _recursive(GenParticlePtr input) const {
297  return _recursive(m_applyRelation.vertex(input));
298  }
299  /** @brief recursive */
300  GenParticles_type<ConstGenParticlePtr> _recursive(ConstGenParticlePtr input) const {
301  return _recursive(m_applyRelation.vertex(input));
302  }
303 
304 
305  /** @brief hasID */
306  class hasId {
307  public:
308  /// @brief destructor
309  virtual ~hasId() {}
310  /// @brief id
311  virtual int id() const = 0;
312  };
313  /** @brief iDinterface */
314  template<typename ID_type>
315  class idInterface : public hasId {
316  public:
317  /** @brief idInterface */
318  constexpr idInterface(ID_type genObject): m_object(genObject) {}
319  /** @brief id */
320  int id() const override {return m_object->id();}
321 
322  private:
323  ID_type m_object; ///< id of object
324  };
325 
326  Relation_type m_applyRelation; ///< applyRelation
327  mutable std::vector<hasId*> m_checkedObjects; ///< Checked objects
328 };
329 
330 }
331 #endif
332 
std::vector< HepMC3::GenVertexPtr > grandchildren_vertices(HepMC3::GenVertexPtr O)
Return grandchildren vertices.
Definition: Relatives.cc:217
Provides operator to find the child particles of a Vertex or Particle.
Definition: Relatives.h:99
HepMC3 main namespace.
std::vector< HepMC3::GenVertexPtr > grandparent_vertices(HepMC3::GenVertexPtr O)
Return grandparent vertices.
Definition: Relatives.cc:225
std::vector< HepMC3::GenParticlePtr > grandchildren_particles(HepMC3::GenParticlePtr O)
Return grandchildren particles.
Definition: Relatives.cc:215
Definition of class GenParticle.
GenParticles_type< ConstGenVertexPtr > operator()(ConstGenVertexPtr input) const override
Operator.
Definition: Relatives.h:229
GenParticles_type< ConstGenVertexPtr > _recursive(ConstGenVertexPtr input) const
recursive
Definition: Relatives.h:275
static HEPMC3search_Relatives_EXPORT_API const Children CHILDREN
Children.
Definition: Relatives.h:202
std::vector< hasId * > m_checkedObjects
Checked objects.
Definition: Relatives.h:327
std::vector< HepMC3::GenParticlePtr > children_particles(HepMC3::GenVertexPtr O)
Return children particles.
Definition: Relatives.cc:211
std::vector< HepMC3::ConstGenVertexPtr > ancestor_vertices(HepMC3::ConstGenParticlePtr obj)
Return ancestor vertices.
Definition: Relatives.cc:195
Provides operator to find the parent particles of a Vertex or Particle.
Definition: Relatives.h:76
forward declare the Relatives interface in which _parents and _children are wrapped ...
Definition: Relatives.h:67
RelativesInterface< _parents > Parents
alias of _parents wrapped in the Relatives interface
Definition: Relatives.h:162
std::vector< HepMC3::GenVertexPtr > children_vertices(HepMC3::GenParticlePtr O)
Return children vertices.
Definition: Relatives.cc:213
static HEPMC3search_Relatives_EXPORT_API thread_local const Ancestors ANCESTORS
Ancestors.
Definition: Relatives.h:203
Definition of class GenVertex.
GenVertex_type< GenObject_type > vertex(GenObject_type input) const
operator
Definition: Relatives.h:115
GenParticles_type< GenObject_type > operator()(GenObject_type input) const
Operator.
Definition: Relatives.h:240
GenParticles_type< GenObject_type > operator()(GenObject_type input) const
operator
Define a common interface that all Relatives objects will satisfy Relatives provides an operator to g...
Definition: Relatives.h:182
constexpr idInterface(ID_type genObject)
idInterface
Definition: Relatives.h:318
static HEPMC3search_Relatives_EXPORT_API thread_local const Descendants DESCENDANTS
Descendants.
Definition: Relatives.h:204
GenParticles_type< GenObject_type > operator()(GenObject_type input) const
operator
GenParticles_type< ConstGenParticlePtr > _recursive(ConstGenParticlePtr input) const
recursive
Definition: Relatives.h:300
std::vector< HepMC3::GenVertexPtr > parent_vertices(HepMC3::GenParticlePtr O)
Return parent vertices.
Definition: Relatives.cc:221
GenParticles_type< GenParticlePtr > _recursive(GenParticlePtr input) const
recursive
Definition: Relatives.h:296
RelativesInterface< Recursive< _parents > > Ancestors
Ancestors is an alias to Recursion applied to the _parents and wrapped in the Relatives interface...
Definition: Relatives.h:166
GenParticles_type< GenVertexPtr > operator()(GenVertexPtr input) const override
Operator.
Definition: Relatives.h:227
forward declare the recursion wrapper
Definition: Relatives.h:70
std::vector< HepMC3::GenParticlePtr > parent_particles(HepMC3::GenVertexPtr O)
Return parent particles.
Definition: Relatives.cc:219
GenVertex_type< GenObject_type > vertex(GenObject_type input) const
vertex
Definition: Relatives.h:92
GenParticles_type< GenParticlePtr > operator()(GenParticlePtr input) const override
Operator.
Definition: Relatives.h:223
RelativesInterface< _children > Children
alias of _children wrapped in the Relatives interface
Definition: Relatives.h:164
GenParticles_type< GenVertexPtr > _recursive(GenVertexPtr input) const
recursive
Definition: Relatives.h:254
std::vector< HepMC3::ConstGenVertexPtr > descendant_vertices(HepMC3::ConstGenParticlePtr obj)
Return descendant vertices.
Definition: Relatives.cc:181
Relation_type m_applyRelation
applyRelation
Definition: Relatives.h:326
static HEPMC3search_Relatives_EXPORT_API const Parents PARENTS
Parents.
Definition: Relatives.h:201
int id() const override
id
Definition: Relatives.h:320
ID_type m_object
id of object
Definition: Relatives.h:323
std::vector< HepMC3::ConstGenParticlePtr > descendant_particles(HepMC3::ConstGenVertexPtr obj)
Return descendant particles.
Definition: Relatives.cc:174
std::vector< HepMC3::GenParticlePtr > grandparent_particles(HepMC3::GenParticlePtr O)
Return grandparent particles.
Definition: Relatives.cc:223
virtual std::vector< GenParticlePtr > operator()(GenParticlePtr input) const =0
Operator.
virtual int id() const =0
id
GenParticles_type< ConstGenParticlePtr > operator()(ConstGenParticlePtr input) const override
Operator.
Definition: Relatives.h:225
RelativesInterface< Recursive< _children > > Descendants
Descendants is an alias to Recursion applied to the _children and wrapped in the Relatives interface...
Definition: Relatives.h:168
GenParticles_type< GenObject_type > _recursive(GenObject_type input) const
recursive
virtual ~hasId()
destructor
Definition: Relatives.h:309
std::vector< HepMC3::ConstGenParticlePtr > ancestor_particles(HepMC3::ConstGenVertexPtr obj)
Return ancestor particles.
Definition: Relatives.cc:188