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"
26namespace HepMC3 {
27std::vector<HepMC3::GenParticlePtr> children_particles(HepMC3::GenVertexPtr O); ///< Return children particles
28std::vector<HepMC3::ConstGenParticlePtr> children_particles(HepMC3::ConstGenVertexPtr O); ///< Return children particles
29std::vector<HepMC3::GenVertexPtr> children_vertices(HepMC3::GenParticlePtr O); ///< Return children vertices
30std::vector<HepMC3::ConstGenVertexPtr> children_vertices(HepMC3::ConstGenParticlePtr O); ///< Return children vertices
31std::vector<HepMC3::GenParticlePtr> grandchildren_particles(HepMC3::GenParticlePtr O); ///< Return grandchildren particles
32std::vector<HepMC3::ConstGenParticlePtr> grandchildren_particles(HepMC3::ConstGenParticlePtr O); ///< Return grandchildren particles
33std::vector<HepMC3::GenVertexPtr> grandchildren_vertices(HepMC3::GenVertexPtr O); ///< Return grandchildren vertices
34std::vector<HepMC3::ConstGenVertexPtr> grandchildren_vertices(HepMC3::ConstGenVertexPtr O); ///< Return grandchildren vertices
35std::vector<HepMC3::GenParticlePtr> parent_particles(HepMC3::GenVertexPtr O); ///< Return parent particles
36std::vector<HepMC3::ConstGenParticlePtr> parent_particles(HepMC3::ConstGenVertexPtr O); ///< Return parent particles
37std::vector<HepMC3::GenVertexPtr> parent_vertices(HepMC3::GenParticlePtr O); ///< Return parent vertices
38std::vector<HepMC3::ConstGenVertexPtr> parent_vertices(HepMC3::ConstGenParticlePtr O); ///< Return parent vertices
39std::vector<HepMC3::GenParticlePtr> grandparent_particles(HepMC3::GenParticlePtr O); ///< Return grandparent particles
40std::vector<HepMC3::ConstGenParticlePtr> grandparent_particles(HepMC3::ConstGenParticlePtr O); ///< Return grandparent particles
41std::vector<HepMC3::GenVertexPtr> grandparent_vertices(HepMC3::GenVertexPtr O); ///< Return grandparent vertices
42std::vector<HepMC3::ConstGenVertexPtr> grandparent_vertices(HepMC3::ConstGenVertexPtr O); ///< Return grandparent vertices
43std::vector<HepMC3::ConstGenParticlePtr> descendant_particles(HepMC3::ConstGenVertexPtr obj); ///< Return descendant particles
44std::vector<HepMC3::GenParticlePtr> descendant_particles(HepMC3::GenVertexPtr obj); ///< Return descendant particles
45std::vector<HepMC3::ConstGenParticlePtr> descendant_particles(HepMC3::ConstGenParticlePtr obj); ///< Return descendant particles
46std::vector<HepMC3::GenParticlePtr> descendant_particles(HepMC3::GenParticlePtr obj); ///< Return descendant particles
47std::vector<HepMC3::ConstGenVertexPtr> descendant_vertices(HepMC3::ConstGenParticlePtr obj); ///< Return descendant vertices
48std::vector<HepMC3::GenVertexPtr> descendant_vertices(HepMC3::GenParticlePtr obj); ///< Return descendant vertices
49std::vector<HepMC3::ConstGenVertexPtr> descendant_vertices(HepMC3::ConstGenVertexPtr obj); ///< Return descendant vertices
50std::vector<HepMC3::GenVertexPtr> descendant_vertices(HepMC3::GenVertexPtr obj); ///< Return descendant vertices
51std::vector<HepMC3::ConstGenParticlePtr> ancestor_particles(HepMC3::ConstGenVertexPtr obj); ///< Return ancestor particles
52std::vector<HepMC3::GenParticlePtr> ancestor_particles(HepMC3::GenVertexPtr obj); ///< Return ancestor particles
53std::vector<HepMC3::ConstGenParticlePtr> ancestor_particles(HepMC3::ConstGenParticlePtr obj); ///< Return ancestor particles
54std::vector<HepMC3::GenParticlePtr> ancestor_particles(HepMC3::GenParticlePtr obj); ///< Return ancestor particles
55std::vector<HepMC3::ConstGenVertexPtr> ancestor_vertices(HepMC3::ConstGenParticlePtr obj); ///< Return ancestor vertices
56std::vector<HepMC3::GenVertexPtr> ancestor_vertices(HepMC3::GenParticlePtr obj); ///< Return ancestor vertices
57std::vector<HepMC3::ConstGenVertexPtr> ancestor_vertices(HepMC3::ConstGenVertexPtr obj); ///< Return ancestor vertices
58std::vector<HepMC3::GenVertexPtr> ancestor_vertices(HepMC3::GenVertexPtr obj); ///< Return ancestor vertices
59}
60
61
62
63namespace HepMC3 {
64
65/// forward declare the Relatives interface in which _parents and _children are wrapped
66template<typename T>
67class RelativesInterface;
68/// forward declare the recursion wrapper
69template<typename T>
70class 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 */
76class _parents {
77public:
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 */
99class _children {
100public:
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
119class SearchParents {
120public:
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
127class SearchChildren {
128public:
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
135class SearchAncestors {
136public:
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
143class SearchDescendants {
144public:
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
152using Parents = SearchParents;
153/// alias
154using Children = SearchChildren;
155/// Ancestors
156using Ancestors = SearchAncestors;
157/// Descendants
158using 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 */
183public:
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 */
216template<typename Relative_type>
218public:
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
231private:
232 Relative_type _internal;
233};
234/** @brief Recursive */
235template<typename Relation_type>
237public:
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
248private:
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
Definition of class GenParticle.
Definition of class GenVertex.
virtual ~hasId()
destructor
Definition: Relatives.h:309
virtual int id() const =0
id
ID_type m_object
id of object
Definition: Relatives.h:323
constexpr idInterface(ID_type genObject)
idInterface
Definition: Relatives.h:318
int id() const override
id
Definition: Relatives.h:320
forward declare the recursion wrapper
Definition: Relatives.h:236
GenParticles_type< GenObject_type > _recursive(GenObject_type input) const
recursive
std::vector< hasId * > m_checkedObjects
Checked objects.
Definition: Relatives.h:327
GenParticles_type< ConstGenVertexPtr > _recursive(ConstGenVertexPtr input) const
recursive
Definition: Relatives.h:275
GenParticles_type< ConstGenParticlePtr > _recursive(ConstGenParticlePtr input) const
recursive
Definition: Relatives.h:300
Relation_type m_applyRelation
applyRelation
Definition: Relatives.h:326
GenParticles_type< GenVertexPtr > _recursive(GenVertexPtr input) const
recursive
Definition: Relatives.h:254
GenParticles_type< GenParticlePtr > _recursive(GenParticlePtr input) const
recursive
Definition: Relatives.h:296
GenParticles_type< GenObject_type > operator()(GenObject_type input) const
Operator.
Definition: Relatives.h:240
forward declare the Relatives interface in which _parents and _children are wrapped
Definition: Relatives.h:217
GenParticles_type< ConstGenParticlePtr > operator()(ConstGenParticlePtr input) const override
Operator.
Definition: Relatives.h:225
GenParticles_type< GenVertexPtr > operator()(GenVertexPtr input) const override
Operator.
Definition: Relatives.h:227
GenParticles_type< ConstGenVertexPtr > operator()(ConstGenVertexPtr input) const override
Operator.
Definition: Relatives.h:229
GenParticles_type< GenParticlePtr > operator()(GenParticlePtr input) const override
Operator.
Definition: Relatives.h:223
Define a common interface that all Relatives objects will satisfy Relatives provides an operator to g...
Definition: Relatives.h:182
static HEPMC3search_Relatives_EXPORT_API thread_local const Ancestors ANCESTORS
Ancestors.
Definition: Relatives.h:203
static HEPMC3search_Relatives_EXPORT_API const Parents PARENTS
Parents.
Definition: Relatives.h:201
virtual std::vector< ConstGenParticlePtr > operator()(ConstGenParticlePtr input) const =0
Operator.
virtual std::vector< ConstGenParticlePtr > operator()(ConstGenVertexPtr input) const =0
Operator.
virtual std::vector< GenParticlePtr > operator()(GenParticlePtr input) const =0
Operator.
static HEPMC3search_Relatives_EXPORT_API const Children CHILDREN
Children.
Definition: Relatives.h:202
virtual std::vector< GenParticlePtr > operator()(GenVertexPtr input) const =0
Operator.
static HEPMC3search_Relatives_EXPORT_API thread_local const Descendants DESCENDANTS
Descendants.
Definition: Relatives.h:204
Provides operator to find the child particles of a Vertex or Particle.
Definition: Relatives.h:99
GenParticles_type< GenObject_type > operator()(GenObject_type input) const
operator
GenVertex_type< GenObject_type > vertex(GenObject_type input) const
operator
Definition: Relatives.h:115
Provides operator to find the parent particles of a Vertex or Particle.
Definition: Relatives.h:76
GenParticles_type< GenObject_type > operator()(GenObject_type input) const
operator
GenVertex_type< GenObject_type > vertex(GenObject_type input) const
vertex
Definition: Relatives.h:92
HepMC3 main namespace.
std::vector< HepMC3::GenParticlePtr > parent_particles(HepMC3::GenVertexPtr O)
Return parent particles.
Definition: Relatives.cc:219
std::vector< HepMC3::ConstGenParticlePtr > ancestor_particles(HepMC3::ConstGenVertexPtr obj)
Return ancestor particles.
Definition: Relatives.cc:188
std::vector< HepMC3::GenParticlePtr > grandparent_particles(HepMC3::GenParticlePtr O)
Return grandparent particles.
Definition: Relatives.cc:223
std::vector< HepMC3::ConstGenVertexPtr > descendant_vertices(HepMC3::ConstGenParticlePtr obj)
Return descendant vertices.
Definition: Relatives.cc:181
std::vector< HepMC3::ConstGenVertexPtr > ancestor_vertices(HepMC3::ConstGenParticlePtr obj)
Return ancestor vertices.
Definition: Relatives.cc:195
RelativesInterface< Recursive< _children > > Descendants
Descendants is an alias to Recursion applied to the _children and wrapped in the Relatives interface.
Definition: Relatives.h:168
RelativesInterface< Recursive< _parents > > Ancestors
Ancestors is an alias to Recursion applied to the _parents and wrapped in the Relatives interface.
Definition: Relatives.h:166
std::vector< HepMC3::ConstGenParticlePtr > descendant_particles(HepMC3::ConstGenVertexPtr obj)
Return descendant particles.
Definition: Relatives.cc:174
std::vector< HepMC3::GenParticlePtr > children_particles(HepMC3::GenVertexPtr O)
Return children particles.
Definition: Relatives.cc:211
std::vector< HepMC3::GenVertexPtr > grandchildren_vertices(HepMC3::GenVertexPtr O)
Return grandchildren vertices.
Definition: Relatives.cc:217
std::vector< HepMC3::GenParticlePtr > grandchildren_particles(HepMC3::GenParticlePtr O)
Return grandchildren particles.
Definition: Relatives.cc:215
std::vector< HepMC3::GenVertexPtr > parent_vertices(HepMC3::GenParticlePtr O)
Return parent vertices.
Definition: Relatives.cc:221
std::vector< HepMC3::GenVertexPtr > children_vertices(HepMC3::GenParticlePtr O)
Return children vertices.
Definition: Relatives.cc:213
RelativesInterface< _parents > Parents
alias of _parents wrapped in the Relatives interface
Definition: Relatives.h:162
RelativesInterface< _children > Children
alias of _children wrapped in the Relatives interface
Definition: Relatives.h:164
std::vector< HepMC3::GenVertexPtr > grandparent_vertices(HepMC3::GenVertexPtr O)
Return grandparent vertices.
Definition: Relatives.cc:225