]>
Commit | Line | Data |
---|---|---|
0ca57c2f | 1 | //-------------------------------------------------------------------------- |
2 | #ifndef HEPMC_GEN_VERTEX_H | |
3 | #define HEPMC_GEN_VERTEX_H | |
4 | ||
5 | ////////////////////////////////////////////////////////////////////////// | |
6 | // Matt.Dobbs@Cern.CH, September 1999, refer to: | |
7 | // M. Dobbs and J.B. Hansen, "The HepMC C++ Monte Carlo Event Record for | |
8 | // High Energy Physics", Computer Physics Communications (to be published). | |
9 | // | |
10 | // GenVertex within an event | |
11 | // A vertex is indirectly (via particle "edges") linked to other | |
12 | // vertices ("nodes") to form a composite "graph" | |
13 | ////////////////////////////////////////////////////////////////////////// | |
14 | ||
15 | // --> HANDLE COMPILER INCONSISTENCIES | |
16 | // This pre-compiler directive is included (2002-01-16) to allow compatibility | |
17 | // with several compilers. | |
18 | // Mar 27, 2004: HepMC is now standard compliant only. | |
19 | // I've removed forward_iterator, and it will no longer compile on gcc < 3. | |
20 | #ifdef __SUNPRO_CC // Solaris CC 5.2 | |
21 | #define NEED_SOLARIS_FRIEND_FEATURE | |
22 | #endif // Platform | |
23 | ||
24 | #include "HepMC/WeightContainer.h" | |
25 | #include "HepMC/SimpleVector.h" | |
26 | #include "HepMC/IteratorRange.h" | |
27 | #include <iostream> | |
28 | #include <iterator> | |
29 | #include <vector> | |
30 | #include <set> | |
31 | #include <algorithm> | |
32 | #include <cstddef> | |
33 | ||
34 | namespace HepMC { | |
35 | ||
36 | class GenVertexParticleRange; | |
37 | class GenParticleProductionRange; | |
38 | class ConstGenParticleProductionRange; | |
39 | class GenParticleEndRange; | |
40 | class ConstGenParticleEndRange; | |
41 | ||
42 | class GenParticle; | |
43 | class GenEvent; | |
44 | ||
45 | //! GenVertex contains information about decay vertices. | |
46 | ||
47 | /// | |
48 | /// \class GenVertex | |
49 | /// HepMC::GenVertex contains the position in space and time of a decay. | |
50 | /// It also contains lists of incoming and outgoing particles. | |
51 | /// | |
52 | class GenVertex { | |
53 | ||
54 | /// print vertex information | |
55 | friend std::ostream& operator<<( std::ostream&, const GenVertex& ); | |
56 | friend class GenEvent; | |
57 | ||
58 | #ifdef NEED_SOLARIS_FRIEND_FEATURE | |
59 | // This bit of ugly code is only for CC-5.2 compiler. | |
60 | // M.Dobbs 2002/02/19 | |
61 | // It is not needed by linux gcc, nor Windows Visual C++. | |
62 | public: | |
63 | class vertex_iterator; | |
64 | friend class vertex_iterator; | |
65 | class particle_iterator; | |
66 | friend class particle_iterator; | |
67 | #endif // NEED_SOLARIS_FRIEND_FEATURE | |
68 | ||
69 | public: | |
70 | /// default constructor | |
71 | GenVertex( const FourVector& position =FourVector(0,0,0,0), | |
72 | int id = 0, | |
73 | const WeightContainer& weights = std::vector<double>() ); | |
74 | GenVertex( const GenVertex& invertex ); //!< shallow copy | |
75 | virtual ~GenVertex(); | |
76 | ||
77 | void swap( GenVertex & other); //!< swap | |
78 | GenVertex& operator= ( const GenVertex& invertex ); //!< shallow | |
79 | bool operator==( const GenVertex& a ) const; //!< equality | |
80 | bool operator!=( const GenVertex& a ) const; //!< inequality | |
81 | void print( std::ostream& ostr = std::cout ) const; //!< print vertex information | |
82 | ||
83 | double check_momentum_conservation() const;//!< |Sum (three_mom_in-three_mom_out)| | |
84 | ||
85 | /// add incoming particle | |
86 | void add_particle_in( GenParticle* inparticle ); | |
87 | /// add outgoing particle | |
88 | void add_particle_out( GenParticle* outparticle ); | |
89 | /// remove_particle finds *particle in the in and/or out list and | |
90 | /// removes it from these lists ... it DOES NOT DELETE THE PARTICLE | |
91 | /// or its relations. You could delete the particle too as follows: | |
92 | /// delete vtx->remove_particle( particle ); | |
93 | GenParticle* remove_particle( GenParticle* particle ); //!< remove a particle | |
94 | ||
95 | operator HepMC::FourVector() const; //!< conversion operator | |
96 | operator HepMC::ThreeVector() const; //!< conversion operator | |
97 | ||
98 | //////////////////// | |
99 | // access methods // | |
100 | //////////////////// | |
101 | ||
102 | /// pointer to the event that owns this vertex | |
103 | GenEvent* parent_event() const; | |
104 | /// vertex position | |
105 | ThreeVector point3d() const; | |
106 | /// vertex position and time | |
107 | const FourVector & position() const; | |
108 | /// set vertex position and time | |
109 | void set_position( const FourVector& position = FourVector(0,0,0,0) ); | |
110 | /// we don't define what you use the id for -- but we imagine, | |
111 | /// for example it might code the meaning of the weights() | |
112 | int id() const; //!< vertex ID | |
113 | void set_id( int id ); //!< set vertex ID | |
114 | ||
115 | /// | |
116 | /// The barcode is the vertex's reference number, every vertex in the | |
117 | /// event has a unique barcode. Vertex barcodes are negative numbers, | |
118 | /// particle barcodes are positive numbers. | |
119 | /// | |
120 | /// Please note that the barcodes are intended for internal use within | |
121 | /// HepMC as a unique identifier for the particles and vertices. | |
122 | /// Using the barcode to encode extra information is an abuse of | |
123 | /// the barcode data member and causes confusion among users. | |
124 | /// | |
125 | int barcode() const; //!< unique identifier | |
126 | ||
127 | /// In general there is no reason to "suggest_barcode" | |
128 | bool suggest_barcode( int the_bar_code ); | |
129 | ||
130 | /// direct access to the weights container is allowed. | |
131 | WeightContainer& weights(); | |
132 | /// const direct access to the weights container | |
133 | const WeightContainer& weights() const; | |
134 | ||
135 | /// particle range | |
136 | GenVertexParticleRange particles( IteratorRange range = relatives ); | |
137 | /// incoming particle range | |
138 | GenParticleProductionRange particles_in( GenParticle&, IteratorRange range = relatives ); | |
139 | /// incoming particle range | |
140 | ConstGenParticleProductionRange particles_in( GenParticle const &, IteratorRange range = relatives ) const; | |
141 | /// outgoing particle range | |
142 | GenParticleEndRange particles_out( GenParticle&, IteratorRange range = relatives ); | |
143 | /// outgoing particle range | |
144 | ConstGenParticleEndRange particles_out( GenParticle const &, IteratorRange range = relatives ) const; | |
145 | ||
146 | //////////////////// | |
147 | // Iterators // users should use prefer to use particle_iterator | |
148 | //////////////////// | |
149 | ||
150 | /// const iterator for incoming particles | |
151 | typedef std::vector<HepMC::GenParticle*>::const_iterator | |
152 | particles_in_const_iterator; | |
153 | /// const iterator for outgoing particles | |
154 | typedef std::vector<HepMC::GenParticle*>::const_iterator | |
155 | particles_out_const_iterator; | |
156 | /// begin iteration of incoming particles | |
157 | particles_in_const_iterator particles_in_const_begin() const; | |
158 | /// end iteration of incoming particles | |
159 | particles_in_const_iterator particles_in_const_end() const; | |
160 | /// begin iteration of outgoing particles | |
161 | particles_out_const_iterator particles_out_const_begin() const; | |
162 | /// end iteration of outgoing particles | |
163 | particles_out_const_iterator particles_out_const_end() const; | |
164 | /// number of incoming particles | |
165 | int particles_in_size() const; | |
166 | /// number of outgoing particles | |
167 | int particles_out_size() const; | |
168 | ||
169 | protected: | |
170 | //static unsigned int counter(); //!< temporary for debugging | |
171 | ||
172 | /// only the GenEvent (friend) is allowed to set the parent_event, | |
173 | /// and barcode. It is done automatically anytime you add a | |
174 | /// vertex to an event | |
175 | void set_parent_event_( GenEvent* evt ); //!< set parent event | |
176 | void set_barcode_( int the_bar_code ); //!< set identifier | |
177 | void change_parent_event_( GenEvent* evt ); //!< for use with swap | |
178 | ||
179 | ///////////////////////////// | |
180 | // edge_iterator // (protected - for internal use only) | |
181 | ///////////////////////////// | |
182 | // If the user wants the functionality of the edge_iterator, he should | |
183 | // use particle_iterator with IteratorRange = family, parents, children | |
184 | // | |
185 | ||
186 | //! edge iterator | |
187 | ||
188 | /// \class edge_iterator | |
189 | /// iterate over the family of edges connected to m_vertex begins | |
190 | /// with parents (incoming particles) then children (outgoing) | |
191 | /// This is not a recursive iterator ... it is a building block | |
192 | /// for the public iterators and is intended for internal use only. | |
193 | /// The acceptable Iterator Ranges are: family, parents, children | |
194 | class edge_iterator : | |
195 | public std::iterator<std::forward_iterator_tag,HepMC::GenParticle*,ptrdiff_t>{ | |
196 | public: | |
197 | edge_iterator(); | |
198 | /// used to set limits on the iteration | |
199 | edge_iterator( const GenVertex& vtx, IteratorRange range =family ); | |
200 | /// copy | |
201 | edge_iterator( const edge_iterator& p ); | |
202 | virtual ~edge_iterator(); | |
203 | /// make a copy | |
204 | edge_iterator& operator=( const edge_iterator& p ); | |
205 | /// return a pointer to a particle | |
206 | GenParticle* operator*(void) const; | |
207 | /// Pre-fix increment | |
208 | edge_iterator& operator++(void); // Pre-fix increment | |
209 | /// Post-fix increment | |
210 | edge_iterator operator++(int); // Post-fix increment | |
211 | /// equality | |
212 | bool operator==( const edge_iterator& a ) const; | |
213 | /// inequality | |
214 | bool operator!=( const edge_iterator& a ) const; | |
215 | /// true if parent of root vtx | |
216 | bool is_parent() const; | |
217 | /// true if child of root vtx | |
218 | bool is_child() const; | |
219 | /// root vertex of this iteration | |
220 | const GenVertex* vertex_root() const; | |
221 | private: | |
222 | /// Pre-fix increment -- is not allowed | |
223 | edge_iterator& operator--(void); | |
224 | /// Post-fix increment -- is not allowed | |
225 | edge_iterator operator--(int); | |
226 | private: | |
227 | const GenVertex* m_vertex; | |
228 | IteratorRange m_range; | |
229 | std::vector<HepMC::GenParticle*>::const_iterator m_set_iter; | |
230 | bool m_is_inparticle_iter; | |
231 | bool m_is_past_end; | |
232 | }; | |
233 | friend class edge_iterator; | |
234 | /// size | |
235 | int edges_size( IteratorRange range = family ) const; | |
236 | /// begin range | |
237 | edge_iterator edges_begin( IteratorRange range = family) const; | |
238 | /// end range | |
239 | edge_iterator edges_end( IteratorRange /* dummy_range */ ) const; | |
240 | ||
241 | public: | |
242 | /////////////////////////////// | |
243 | // vertex_iterator // | |
244 | /////////////////////////////// | |
245 | ||
246 | //! vertex iterator | |
247 | ||
248 | /// \class vertex_iterator | |
249 | /// Iterates over all vertices connected via a graph to this vertex. | |
250 | /// this is made friend to that it can access protected edge | |
251 | /// iterator the range can be IteratorRange= ( parents, children, | |
252 | /// family, ancestors, descendants, relatives ) | |
253 | /// example for range=descendants the iterator | |
254 | /// will return all vertices | |
255 | /// which are children (connected by an outgoing particle edge), | |
256 | /// grandchildren, great-grandchildren, etc. of this vertex | |
257 | /// In all cases the iterator always returns this vertex | |
258 | /// (returned last). | |
259 | /// The algorithm is accomplished by converting the graph to a tree | |
260 | /// (by "chopping" the edges connecting to an already visited | |
261 | /// vertex) and returning the vertices in POST ORDER traversal. | |
262 | /// | |
263 | class vertex_iterator : | |
264 | public std::iterator<std::forward_iterator_tag,HepMC::GenVertex*,ptrdiff_t>{ | |
265 | public: | |
266 | vertex_iterator(); | |
267 | /// used to set limits on the iteration | |
268 | vertex_iterator( GenVertex& vtx_root, IteratorRange range ); | |
269 | /// next constructor is intended for internal use only | |
270 | vertex_iterator( GenVertex& vtx_root, IteratorRange range, | |
271 | std::set<const HepMC::GenVertex*>& visited_vertices ); | |
272 | /// copy | |
273 | vertex_iterator( const vertex_iterator& v_iter ); | |
274 | virtual ~vertex_iterator(); | |
275 | /// make a copy | |
276 | vertex_iterator& operator=( const vertex_iterator& ); | |
277 | /// return a pointer to a vertex | |
278 | GenVertex* operator*(void) const; | |
279 | /// Pre-fix increment | |
280 | vertex_iterator& operator++(void); //Pre-fix increment | |
281 | /// Post-fix increment | |
282 | vertex_iterator operator++(int); //Post-fix increment | |
283 | /// equality | |
284 | bool operator==( const vertex_iterator& ) const; | |
285 | /// inequality | |
286 | bool operator!=( const vertex_iterator& ) const; | |
287 | /// vertex that this iterator begins from | |
288 | GenVertex* vertex_root() const; | |
289 | /// iterator range | |
290 | IteratorRange range() const; | |
291 | /// intended for internal use only. | |
292 | void copy_with_own_set( const vertex_iterator& | |
293 | v_iter, | |
294 | std::set<const HepMC::GenVertex*>& | |
295 | visited_vertices ); | |
296 | ||
297 | protected: // intended for internal use only | |
298 | /// non-null if recursive iter. created | |
299 | GenVertex* follow_edge_(); | |
300 | /// copy recursive iterator | |
301 | void copy_recursive_iterator_( const vertex_iterator* | |
302 | recursive_v_iter ); | |
303 | private: | |
304 | /// Pre-fix increment -- is not allowed | |
305 | vertex_iterator& operator--(void); | |
306 | /// Post-fix increment -- is not allowed | |
307 | vertex_iterator operator--(int); | |
308 | ||
309 | private: | |
310 | GenVertex* m_vertex; // the vertex associated to this iter | |
311 | IteratorRange m_range; | |
312 | std::set<const HepMC::GenVertex*>* m_visited_vertices; | |
313 | bool m_it_owns_set; // true if it is responsible for | |
314 | // deleting the visited vertex set | |
315 | edge_iterator m_edge; // particle edge pointing to return vtx | |
316 | vertex_iterator* m_recursive_iterator; | |
317 | }; | |
318 | friend class vertex_iterator; | |
319 | /// begin vertex range | |
320 | vertex_iterator vertices_begin( IteratorRange range = relatives ); | |
321 | /// end vertex range | |
322 | vertex_iterator vertices_end( IteratorRange /* dummy_range */ ); | |
323 | ||
324 | public: | |
325 | /////////////////////////////// | |
326 | // particle_iterator // | |
327 | /////////////////////////////// | |
328 | ||
329 | //! particle iterator | |
330 | ||
331 | /// \class particle_iterator | |
332 | /// Iterates over all particles connected via a graph. | |
333 | /// by iterating through all vertices in the m_range. For each | |
334 | /// vertex it returns orphaned parent particles | |
335 | /// (i.e. parents without production vertices) | |
336 | /// then children ... in this way each particle is associated | |
337 | /// to exactly one vertex and so it is returned exactly once. | |
338 | /// Is made friend so that it can access protected edge iterator | |
339 | class particle_iterator : | |
340 | public std::iterator<std::forward_iterator_tag,GenParticle*,ptrdiff_t>{ | |
341 | public: | |
342 | particle_iterator(); | |
343 | /// used to set limits on the iteration | |
344 | particle_iterator( GenVertex& vertex_root, IteratorRange range ); | |
345 | /// copy | |
346 | particle_iterator( const particle_iterator& ); | |
347 | virtual ~particle_iterator(); | |
348 | /// make a copy | |
349 | particle_iterator& operator=( const particle_iterator& ); | |
350 | /// return a pointer to a particle | |
351 | GenParticle* operator*(void) const; | |
352 | /// Pre-fix increment | |
353 | particle_iterator& operator++(void); | |
354 | /// Post-fix increment | |
355 | particle_iterator operator++(int); | |
356 | /// equality | |
357 | bool operator==( const particle_iterator& ) const; | |
358 | /// inequality | |
359 | bool operator!=( const particle_iterator& ) const; | |
360 | protected: | |
361 | GenParticle* advance_to_first_(); //!< "first" particle | |
362 | private: | |
363 | vertex_iterator m_vertex_iterator; | |
364 | edge_iterator m_edge; // points to the return | |
365 | }; | |
366 | friend class particle_iterator; | |
367 | /// begin particle range | |
368 | particle_iterator particles_begin( IteratorRange range | |
369 | = relatives ); | |
370 | /// end particle range | |
371 | particle_iterator particles_end( IteratorRange | |
372 | /* dummy_range */ ); | |
373 | ||
374 | //////////////////////////////////////////////// | |
375 | protected: | |
376 | /// for internal use only | |
377 | void delete_adopted_particles(); | |
378 | /// for internal use only - remove particle from incoming list | |
379 | void remove_particle_in( GenParticle* ); | |
380 | /// for internal use only - remove particle from outgoing list | |
381 | void remove_particle_out( GenParticle* ); | |
382 | /// scale the position vector | |
383 | /// this method is only for use by GenEvent | |
384 | void convert_position( const double& ); | |
385 | ||
386 | private: // GenVertex data members | |
387 | FourVector m_position; //4-vec of vertex [mm] | |
388 | std::vector<HepMC::GenParticle*> m_particles_in; //all incoming particles | |
389 | std::vector<HepMC::GenParticle*> m_particles_out; //all outgoing particles | |
390 | int m_id; | |
391 | WeightContainer m_weights; // weights for this vtx | |
392 | GenEvent* m_event; | |
393 | int m_barcode; // unique identifier in the event | |
394 | ||
395 | //static unsigned int s_counter; | |
396 | }; | |
397 | ||
398 | //////////////////////////// | |
399 | // INLINES access methods // | |
400 | //////////////////////////// | |
401 | ||
402 | inline GenVertex::operator HepMC::FourVector() const { return position(); } | |
403 | ||
404 | inline GenVertex::operator HepMC::ThreeVector() const { return point3d(); } | |
405 | ||
406 | inline const FourVector & GenVertex::position() const { return m_position; } | |
407 | ||
408 | inline GenEvent* GenVertex::parent_event() const { return m_event; } | |
409 | ||
410 | inline ThreeVector GenVertex::point3d() const { | |
411 | return ThreeVector(m_position.x(),m_position.y(),m_position.z()); | |
412 | } | |
413 | ||
414 | inline int GenVertex::id() const { return m_id; } | |
415 | ||
416 | inline int GenVertex::barcode() const { return m_barcode; } | |
417 | inline void GenVertex::set_barcode_( int bc ) { m_barcode = bc; } | |
418 | ||
419 | inline WeightContainer& GenVertex::weights() { return m_weights; } | |
420 | ||
421 | inline const WeightContainer& GenVertex::weights() const | |
422 | { return m_weights; } | |
423 | ||
424 | inline void GenVertex::set_position( const FourVector& pos ) { | |
425 | m_position = pos; | |
426 | } | |
427 | ||
428 | inline void GenVertex::set_id( int pid ) { m_id = pid; } | |
429 | ||
430 | ////////////// | |
431 | // INLINES // | |
432 | ////////////// | |
433 | ||
434 | inline GenVertex::particles_in_const_iterator | |
435 | GenVertex::particles_in_const_begin() const { | |
436 | return m_particles_in.begin(); | |
437 | } | |
438 | ||
439 | inline GenVertex::particles_in_const_iterator | |
440 | GenVertex::particles_in_const_end() const { | |
441 | return m_particles_in.end(); | |
442 | } | |
443 | ||
444 | inline GenVertex::particles_out_const_iterator | |
445 | GenVertex::particles_out_const_begin() const { | |
446 | return m_particles_out.begin(); | |
447 | } | |
448 | ||
449 | inline GenVertex::particles_out_const_iterator | |
450 | GenVertex::particles_out_const_end() const { | |
451 | return m_particles_out.end(); | |
452 | } | |
453 | ||
454 | inline int GenVertex::particles_in_size() const { | |
455 | return m_particles_in.size(); | |
456 | } | |
457 | ||
458 | inline int GenVertex::particles_out_size() const { | |
459 | return m_particles_out.size(); | |
460 | } | |
461 | ||
462 | inline bool GenVertex::edge_iterator::operator==( | |
463 | const edge_iterator& a ) const { | |
464 | return **this == *a; | |
465 | } | |
466 | ||
467 | inline bool GenVertex::edge_iterator::operator!=( | |
468 | const edge_iterator& a ) const { | |
469 | return !(**this == *a); | |
470 | } | |
471 | ||
472 | inline const GenVertex* GenVertex::edge_iterator::vertex_root() const { | |
473 | return m_vertex; | |
474 | } | |
475 | ||
476 | inline GenVertex::edge_iterator GenVertex::edges_begin( IteratorRange | |
477 | range ) const { | |
478 | return GenVertex::edge_iterator(*this, range); | |
479 | } | |
480 | ||
481 | inline GenVertex::edge_iterator GenVertex::edges_end( IteratorRange | |
482 | /* dummy_range */ ) const { | |
483 | return GenVertex::edge_iterator(); | |
484 | } | |
485 | ||
486 | inline bool GenVertex::vertex_iterator::operator==( | |
487 | const vertex_iterator& a ) const { | |
488 | return **this == *a; | |
489 | } | |
490 | ||
491 | inline bool GenVertex::vertex_iterator::operator!=( | |
492 | const vertex_iterator& a ) const { | |
493 | return !(**this == *a); | |
494 | } | |
495 | ||
496 | inline GenVertex* GenVertex::vertex_iterator::vertex_root() const { | |
497 | return m_vertex; | |
498 | } | |
499 | ||
500 | inline IteratorRange GenVertex::vertex_iterator::range() const { | |
501 | return m_range; | |
502 | } | |
503 | ||
504 | inline GenVertex::vertex_iterator GenVertex::vertices_begin( | |
505 | IteratorRange range ){ | |
506 | // this is not const because the it could return itself | |
507 | return vertex_iterator( *this, range ); | |
508 | } | |
509 | ||
510 | inline GenVertex::vertex_iterator GenVertex::vertices_end( | |
511 | IteratorRange /* dummy_range */ ) { | |
512 | return vertex_iterator(); | |
513 | } | |
514 | ||
515 | inline bool GenVertex::particle_iterator::operator==( | |
516 | const particle_iterator& a ) const { | |
517 | return **this == *a; | |
518 | } | |
519 | ||
520 | inline bool GenVertex::particle_iterator::operator!=( | |
521 | const particle_iterator& a ) const { | |
522 | return !(**this == *a); | |
523 | } | |
524 | ||
525 | inline GenVertex::particle_iterator GenVertex::particles_begin( | |
526 | IteratorRange range ) { | |
527 | return particle_iterator( *this, range ); | |
528 | } | |
529 | ||
530 | inline GenVertex::particle_iterator GenVertex::particles_end( | |
531 | IteratorRange /* dummy_range */ ){ | |
532 | return particle_iterator(); | |
533 | } | |
534 | ||
535 | } // HepMC | |
536 | ||
537 | #endif // HEPMC_GEN_VERTEX_H | |
538 | //-------------------------------------------------------------------------- | |
539 | ||
540 | ||
541 | ||
542 |