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
16namespace HepMC3 {
17
18/// forward declare the Relatives interface in which _parents and _children are wrapped
19template<typename T>
20class RelativesInterface;
21/// forward declare the recursion wrapper
22template<typename T>
23class Recursive;
24
25// forward declare _parents class
26class _parents;
27// forward declare _children class
28class _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 */
51class Relatives {
52
53public:
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 */
73template<typename Relative_type>
75
76public:
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
87private:
88
89 Relative_type _internal;
90
91};
92/** @brief Recursive */
93template<typename Relation_type>
94class Recursive {
95
96public:
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
107private:
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 */
169class _parents {
170
171public:
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 */
192
193public:
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
Definition of class GenParticle.
Definition of class GenVertex.
forward declare the recursion wrapper
Definition: Relatives.h:94
forward declare the Relatives interface in which _parents and _children are wrapped
Definition: Relatives.h:74
Define a common interface that all Relatives objects will satisfy Relatives provides an operator to g...
Definition: Relatives.h:51
Provides operator to find the child particles of a Vertex or Particle.
Definition: Relatives.h:191
Provides operator to find the parent particles of a Vertex or Particle.
Definition: Relatives.h:169
HepMC3 main namespace.
Definition: ReaderGZ.h:28