Line data Source code
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 0 : inline const FourVector & GenVertex::position() const { return m_position; }
407 :
408 0 : 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 0 : inline int GenVertex::id() const { return m_id; }
415 :
416 0 : inline int GenVertex::barcode() const { return m_barcode; }
417 0 : inline void GenVertex::set_barcode_( int bc ) { m_barcode = bc; }
418 :
419 0 : inline WeightContainer& GenVertex::weights() { return m_weights; }
420 :
421 : inline const WeightContainer& GenVertex::weights() const
422 0 : { return m_weights; }
423 :
424 : inline void GenVertex::set_position( const FourVector& pos ) {
425 0 : m_position = pos;
426 0 : }
427 :
428 0 : 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 0 : return m_particles_in.begin();
437 : }
438 :
439 : inline GenVertex::particles_in_const_iterator
440 : GenVertex::particles_in_const_end() const {
441 0 : return m_particles_in.end();
442 : }
443 :
444 : inline GenVertex::particles_out_const_iterator
445 : GenVertex::particles_out_const_begin() const {
446 0 : return m_particles_out.begin();
447 : }
448 :
449 : inline GenVertex::particles_out_const_iterator
450 : GenVertex::particles_out_const_end() const {
451 0 : return m_particles_out.end();
452 : }
453 :
454 : inline int GenVertex::particles_in_size() const {
455 0 : return m_particles_in.size();
456 : }
457 :
458 : inline int GenVertex::particles_out_size() const {
459 0 : return m_particles_out.size();
460 : }
461 :
462 : inline bool GenVertex::edge_iterator::operator==(
463 : const edge_iterator& a ) const {
464 0 : return **this == *a;
465 : }
466 :
467 : inline bool GenVertex::edge_iterator::operator!=(
468 : const edge_iterator& a ) const {
469 0 : 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 0 : return GenVertex::edge_iterator(*this, range);
479 : }
480 :
481 : inline GenVertex::edge_iterator GenVertex::edges_end( IteratorRange
482 : /* dummy_range */ ) const {
483 0 : 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 0 : 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 0 : return !(**this == *a);
523 : }
524 :
525 : inline GenVertex::particle_iterator GenVertex::particles_begin(
526 : IteratorRange range ) {
527 0 : return particle_iterator( *this, range );
528 : }
529 :
530 : inline GenVertex::particle_iterator GenVertex::particles_end(
531 : IteratorRange /* dummy_range */ ){
532 0 : return particle_iterator();
533 : }
534 :
535 : } // HepMC
536 :
537 : #endif // HEPMC_GEN_VERTEX_H
538 : //--------------------------------------------------------------------------
539 :
540 :
541 :
542 :
|