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-2023 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(const HepMC3::GenVertexPtr& O); ///< Return children particles
28std::vector<HepMC3::ConstGenParticlePtr> children_particles(const HepMC3::ConstGenVertexPtr& O); ///< Return children particles
29std::vector<HepMC3::GenVertexPtr> children_vertices(const HepMC3::GenParticlePtr& O); ///< Return children vertices
30std::vector<HepMC3::ConstGenVertexPtr> children_vertices(const HepMC3::ConstGenParticlePtr& O); ///< Return children vertices
31std::vector<HepMC3::GenParticlePtr> grandchildren_particles(const HepMC3::GenParticlePtr& O); ///< Return grandchildren particles
32std::vector<HepMC3::ConstGenParticlePtr> grandchildren_particles(const HepMC3::ConstGenParticlePtr& O); ///< Return grandchildren particles
33std::vector<HepMC3::GenVertexPtr> grandchildren_vertices(const HepMC3::GenVertexPtr& O); ///< Return grandchildren vertices
34std::vector<HepMC3::ConstGenVertexPtr> grandchildren_vertices(const HepMC3::ConstGenVertexPtr& O); ///< Return grandchildren vertices
35std::vector<HepMC3::GenParticlePtr> parent_particles(const HepMC3::GenVertexPtr& O); ///< Return parent particles
36std::vector<HepMC3::ConstGenParticlePtr> parent_particles(const HepMC3::ConstGenVertexPtr& O); ///< Return parent particles
37std::vector<HepMC3::GenVertexPtr> parent_vertices(const HepMC3::GenParticlePtr& O); ///< Return parent vertices
38std::vector<HepMC3::ConstGenVertexPtr> parent_vertices(const HepMC3::ConstGenParticlePtr& O); ///< Return parent vertices
39std::vector<HepMC3::GenParticlePtr> grandparent_particles(const HepMC3::GenParticlePtr& O); ///< Return grandparent particles
40std::vector<HepMC3::ConstGenParticlePtr> grandparent_particles(const HepMC3::ConstGenParticlePtr& O); ///< Return grandparent particles
41std::vector<HepMC3::GenVertexPtr> grandparent_vertices(const HepMC3::GenVertexPtr& O); ///< Return grandparent vertices
42std::vector<HepMC3::ConstGenVertexPtr> grandparent_vertices(const HepMC3::ConstGenVertexPtr& O); ///< Return grandparent vertices
43std::vector<HepMC3::ConstGenParticlePtr> descendant_particles(const HepMC3::ConstGenVertexPtr& obj); ///< Return descendant particles
44std::vector<HepMC3::GenParticlePtr> descendant_particles(const HepMC3::GenVertexPtr& obj); ///< Return descendant particles
45std::vector<HepMC3::ConstGenParticlePtr> descendant_particles(const HepMC3::ConstGenParticlePtr& obj); ///< Return descendant particles
46std::vector<HepMC3::GenParticlePtr> descendant_particles(const HepMC3::GenParticlePtr& obj); ///< Return descendant particles
47std::vector<HepMC3::ConstGenVertexPtr> descendant_vertices(const HepMC3::ConstGenParticlePtr& obj); ///< Return descendant vertices
48std::vector<HepMC3::GenVertexPtr> descendant_vertices(const HepMC3::GenParticlePtr& obj); ///< Return descendant vertices
49std::vector<HepMC3::ConstGenVertexPtr> descendant_vertices(const HepMC3::ConstGenVertexPtr& obj); ///< Return descendant vertices
50std::vector<HepMC3::GenVertexPtr> descendant_vertices(const HepMC3::GenVertexPtr& obj); ///< Return descendant vertices
51std::vector<HepMC3::ConstGenParticlePtr> ancestor_particles(const HepMC3::ConstGenVertexPtr& obj); ///< Return ancestor particles
52std::vector<HepMC3::GenParticlePtr> ancestor_particles(const HepMC3::GenVertexPtr& obj); ///< Return ancestor particles
53std::vector<HepMC3::ConstGenParticlePtr> ancestor_particles(const HepMC3::ConstGenParticlePtr& obj); ///< Return ancestor particles
54std::vector<HepMC3::GenParticlePtr> ancestor_particles(const HepMC3::GenParticlePtr& obj); ///< Return ancestor particles
55std::vector<HepMC3::ConstGenVertexPtr> ancestor_vertices(const HepMC3::ConstGenParticlePtr& obj); ///< Return ancestor vertices
56std::vector<HepMC3::GenVertexPtr> ancestor_vertices(const HepMC3::GenParticlePtr& obj); ///< Return ancestor vertices
57std::vector<HepMC3::ConstGenVertexPtr> ancestor_vertices(const HepMC3::ConstGenVertexPtr& obj); ///< Return ancestor vertices
58std::vector<HepMC3::GenVertexPtr> ancestor_vertices(const 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>
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>
217class RelativesInterface : public Relatives {
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 /// Internal relatives code
233 Relative_type _internal;
234};
235/** @brief Recursive */
236template<typename Relation_type>
238public:
239 /// @brief Operator
240 template<typename GenObject_type>
241 GenParticles_type<GenObject_type> operator()(GenObject_type input) const {
242 for (auto obj: m_checkedObjects) {
243 delete obj;
244 }
245 m_checkedObjects.clear();
246 return _recursive(input);
247 }
248 ~Recursive() {
249 for (auto obj: m_checkedObjects) {
250 delete obj;
251 }
252 m_checkedObjects.clear();
253 }
254private:
255 /// @brief recursive
256 template<typename GenObject_type, typename dummy>
257 GenParticles_type<GenObject_type> _recursive(GenObject_type input) const;
258
259 /// @brief recursive
260 GenParticles_type<GenVertexPtr> _recursive(GenVertexPtr input) const {
261 GenParticles_type <GenVertexPtr> results;
262 if ( !input ) return results;
263 for (auto v: m_checkedObjects) {
264 if (v->id() == input->id()) return results;
265 }
266
267 m_checkedObjects.emplace_back(new idInterface<GenVertexPtr>(input));
268
269 for (auto p: m_applyRelation(input)) {
270 results.emplace_back(p);
271 GenParticles_type <GenVertexPtr> tmp = _recursive(p);
272 results.insert(results.end(),
273 std::make_move_iterator(tmp.begin()),
274 std::make_move_iterator(tmp.end()));
275 }
276
277 return results;
278 }
279
280 /// @brief recursive
281 GenParticles_type<ConstGenVertexPtr> _recursive(ConstGenVertexPtr input) const {
282 GenParticles_type <ConstGenVertexPtr> results;
283 if ( !input ) return results;
284 for (auto v: m_checkedObjects) {
285 if (v->id() == input->id()) return results;
286 }
287
288 m_checkedObjects.emplace_back(new idInterface<ConstGenVertexPtr>(input));
289
290 for (auto p: m_applyRelation(input)) {
291 results.emplace_back(p);
292 GenParticles_type <ConstGenVertexPtr> tmp = _recursive(p);
293 results.insert(results.end(),
294 std::make_move_iterator(tmp.begin()),
295 std::make_move_iterator(tmp.end()));
296 }
297
298 return results;
299 }
300
301 /** @brief recursive */
302 GenParticles_type<GenParticlePtr> _recursive(GenParticlePtr input) const {
303 return _recursive(m_applyRelation.vertex(input));
304 }
305 /** @brief recursive */
306 GenParticles_type<ConstGenParticlePtr> _recursive(ConstGenParticlePtr input) const {
307 return _recursive(m_applyRelation.vertex(input));
308 }
309
310
311 /** @brief hasID */
312 class hasId {
313 public:
314 /// @brief destructor
315 virtual ~hasId() {}
316 /// @brief id
317 virtual int id() const = 0;
318 };
319 /** @brief iDinterface */
320 template<typename ID_type>
321 class idInterface : public hasId {
322 public:
323 /** @brief idInterface */
324 constexpr idInterface(ID_type genObject): m_object(genObject) {}
325 /** @brief id */
326 int id() const override {return m_object->id();}
327
328 private:
329 ID_type m_object; ///< id of object
330 };
331
332 Relation_type m_applyRelation; ///< applyRelation
333 mutable std::vector<hasId*> m_checkedObjects; ///< Checked objects
334};
335
336}
337#endif
338
Definition of class GenParticle.
Definition of class GenVertex.
virtual ~hasId()
destructor
Definition Relatives.h:315
virtual int id() const =0
id
ID_type m_object
id of object
Definition Relatives.h:329
constexpr idInterface(ID_type genObject)
idInterface
Definition Relatives.h:324
int id() const override
id
Definition Relatives.h:326
forward declare the recursion wrapper
Definition Relatives.h:237
GenParticles_type< GenObject_type > _recursive(GenObject_type input) const
recursive
std::vector< hasId * > m_checkedObjects
Checked objects.
Definition Relatives.h:333
GenParticles_type< ConstGenVertexPtr > _recursive(ConstGenVertexPtr input) const
recursive
Definition Relatives.h:281
GenParticles_type< ConstGenParticlePtr > _recursive(ConstGenParticlePtr input) const
recursive
Definition Relatives.h:306
Relation_type m_applyRelation
applyRelation
Definition Relatives.h:332
GenParticles_type< GenVertexPtr > _recursive(GenVertexPtr input) const
recursive
Definition Relatives.h:260
GenParticles_type< GenParticlePtr > _recursive(GenParticlePtr input) const
recursive
Definition Relatives.h:302
GenParticles_type< GenObject_type > operator()(GenObject_type input) const
Operator.
Definition Relatives.h:241
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
Relative_type _internal
Internal relatives code.
Definition Relatives.h:233
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(const HepMC3::GenVertexPtr &O)
Return parent particles.
Definition Relatives.cc:221
std::vector< HepMC3::GenParticlePtr > grandparent_particles(const HepMC3::GenParticlePtr &O)
Return grandparent particles.
Definition Relatives.cc:225
std::vector< HepMC3::ConstGenParticlePtr > ancestor_particles(const HepMC3::ConstGenVertexPtr &obj)
Return ancestor particles.
Definition Relatives.cc:190
std::vector< HepMC3::ConstGenParticlePtr > descendant_particles(const HepMC3::ConstGenVertexPtr &obj)
Return descendant particles.
Definition Relatives.cc:176
std::vector< HepMC3::GenVertexPtr > grandchildren_vertices(const HepMC3::GenVertexPtr &O)
Return grandchildren vertices.
Definition Relatives.cc:219
std::vector< HepMC3::GenVertexPtr > grandparent_vertices(const HepMC3::GenVertexPtr &O)
Return grandparent vertices.
Definition Relatives.cc:227
std::vector< HepMC3::GenParticlePtr > children_particles(const HepMC3::GenVertexPtr &O)
Return children particles.
Definition Relatives.cc:213
std::vector< HepMC3::GenVertexPtr > parent_vertices(const HepMC3::GenParticlePtr &O)
Return parent vertices.
Definition Relatives.cc:223
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::GenParticlePtr > grandchildren_particles(const HepMC3::GenParticlePtr &O)
Return grandchildren particles.
Definition Relatives.cc:217
std::vector< HepMC3::GenVertexPtr > children_vertices(const HepMC3::GenParticlePtr &O)
Return children vertices.
Definition Relatives.cc:215
std::vector< HepMC3::ConstGenVertexPtr > ancestor_vertices(const HepMC3::ConstGenParticlePtr &obj)
Return ancestor vertices.
Definition Relatives.cc:197
RelativesInterface< _parents > Parents
alias of _parents wrapped in the Relatives interface
Definition Relatives.h:162
std::vector< HepMC3::ConstGenVertexPtr > descendant_vertices(const HepMC3::ConstGenParticlePtr &obj)
Return descendant vertices.
Definition Relatives.cc:183
RelativesInterface< _children > Children
alias of _children wrapped in the Relatives interface
Definition Relatives.h:164