hepmc - Blame information for rev 432

Subversion Repositories:
Rev:
Rev Author Line No. Line
2 garren 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"
43 garren 25 #include "HepMC/SimpleVector.h"
432 garren 26 #include "HepMC/IteratorRange.h"
2 garren 27 #include <iostream>
28 #include <iterator>
29 #include <vector>
30 #include <set>
31 #include <algorithm>
32  
33 namespace HepMC {
34  
432 garren 35     class GenVertexParticleRange;
36     class ConstGenVertexParticleRange;
37     class GenParticleProductionRange;
38     class ConstGenParticleProductionRange;
39     class GenParticleEndRange;
40     class ConstGenParticleEndRange;
41  
2 garren 42     class GenParticle;
43     class GenEvent;
44  
65 garren 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     ///
2 garren 52     class GenVertex {
53  
65 garren 54         /// print vertex information
2 garren 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:
65 garren 70         /// default constructor
43 garren 71         GenVertex( const FourVector& position =FourVector(0,0,0,0),
2 garren 72                    int id = 0,
73                    const WeightContainer& weights = std::vector<double>() );
65 garren 74         GenVertex( const GenVertex& invertex );            //!< shallow copy
2 garren 75         virtual    ~GenVertex();
76  
147 garren 77         void swap( GenVertex & other); //!< swap
65 garren 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
2 garren 82  
65 garren 83         double     check_momentum_conservation() const;//!< |Sum (mom_in-mom_out)|
2 garren 84  
65 garren 85         /// add incoming particle
2 garren 86         void       add_particle_in( GenParticle* inparticle );
65 garren 87         /// add outgoing particle
2 garren 88         void       add_particle_out( GenParticle* outparticle );
65 garren 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
2 garren 94  
173 garren 95         operator    HepMC::FourVector() const; //!< conversion operator
96         operator   HepMC::ThreeVector() const; //!< conversion operator
2 garren 97  
98         ////////////////////
99         // access methods //
100         ////////////////////
101  
65 garren 102         /// pointer to the event that owns this vertex
2 garren 103         GenEvent*               parent_event() const;
65 garren 104         /// vertex position
43 garren 105         ThreeVector             point3d() const;
65 garren 106         /// vertex position and time
282 garren 107         const FourVector &      position() const;
65 garren 108         /// set vertex position and time
43 garren 109         void                    set_position( const FourVector& position = FourVector(0,0,0,0) );
65 garren 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
2 garren 114  
65 garren 115         ///
116         /// The barcode is the vertex's reference number, every vertex in the
403 garren 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         ///
65 garren 125         int                     barcode() const; //!< unique identifier
126  
127         /// In general there is no reason to "suggest_barcode"
2 garren 128         bool                    suggest_barcode( int the_bar_code );
129  
65 garren 130         /// direct access to the weights container is allowed.
2 garren 131         WeightContainer&        weights();
65 garren 132         /// const direct access to the weights container
2 garren 133         const WeightContainer&  weights() const;
134  
432 garren 135         /// particle range
136         GenVertexParticleRange particles( IteratorRange range = relatives );
137         /// particle range
138         ConstGenVertexParticleRange particles( IteratorRange range = relatives ) const;
139         /// incoming particle range
140         GenParticleProductionRange particles_in( GenParticle&, IteratorRange range = relatives );
141         /// incoming particle range
142         ConstGenParticleProductionRange particles_in( GenParticle const &, IteratorRange range = relatives ) const;
143         /// outgoing particle range
144         GenParticleEndRange particles_out( GenParticle&, IteratorRange range = relatives );
145         /// outgoing particle range
146         ConstGenParticleEndRange particles_out( GenParticle const &, IteratorRange range = relatives ) const;
147  
2 garren 148         ////////////////////
149         // Iterators      // users should use prefer to use particle_iterator
150         ////////////////////    
151  
65 garren 152         /// const iterator for incoming particles
173 garren 153         typedef std::vector<HepMC::GenParticle*>::const_iterator
2 garren 154         particles_in_const_iterator;
65 garren 155         /// const iterator for outgoing particles
173 garren 156         typedef std::vector<HepMC::GenParticle*>::const_iterator
2 garren 157         particles_out_const_iterator;
65 garren 158         /// begin iteration of incoming particles
2 garren 159         particles_in_const_iterator         particles_in_const_begin() const;
65 garren 160         /// end iteration of incoming particles
2 garren 161         particles_in_const_iterator         particles_in_const_end() const;
65 garren 162         /// begin iteration of outgoing particles
2 garren 163         particles_out_const_iterator        particles_out_const_begin() const;
65 garren 164         /// end iteration of outgoing particles
2 garren 165         particles_out_const_iterator        particles_out_const_end() const;
65 garren 166         /// number of incoming particles
2 garren 167         int                                 particles_in_size() const;
65 garren 168         /// number of outgoing particles
2 garren 169         int                                 particles_out_size() const;
170  
171     protected:
255 garren 172         //static unsigned int     counter(); //!< temporary for debugging
2 garren 173  
65 garren 174         /// only the GenEvent (friend) is allowed to set the parent_event,
175         ///  and barcode. It is done automatically anytime you add a
176         ///  vertex to an event
177         void                    set_parent_event_( GenEvent* evt ); //!< set parent event
178         void                    set_barcode_( int the_bar_code ); //!< set identifier
264 garren 179         void                    change_parent_event_( GenEvent* evt ); //!< for use with swap
2 garren 180  
181         /////////////////////////////
182         // edge_iterator           // (protected - for internal use only)
183         /////////////////////////////
184         // If the user wants the functionality of the edge_iterator, he should
185         // use particle_iterator with IteratorRange = family, parents, children
186         //
65 garren 187  
188         //!  edge iterator
189  
190         /// \class  edge_iterator
191         /// iterate over the family of edges connected to m_vertex begins
192         /// with parents (incoming particles) then children (outgoing)
193         /// This is not a recursive iterator ... it is a building block
194         /// for the public iterators and is intended for internal use only.
195         /// The acceptable Iterator Ranges are: family, parents, children
2 garren 196         class edge_iterator :
173 garren 197           public std::iterator<std::forward_iterator_tag,HepMC::GenParticle*,ptrdiff_t>{
2 garren 198         public:
199             edge_iterator();
65 garren 200             /// used to set limits on the iteration
2 garren 201             edge_iterator( const GenVertex& vtx, IteratorRange range =family );
65 garren 202             /// copy
2 garren 203             edge_iterator( const edge_iterator& p );
204             virtual        ~edge_iterator();
65 garren 205             /// make a copy
2 garren 206             edge_iterator& operator=( const edge_iterator& p );
65 garren 207             /// return a pointer to a particle
2 garren 208             GenParticle*      operator*(void) const;
65 garren 209             /// Pre-fix increment
2 garren 210             edge_iterator& operator++(void); // Pre-fix increment
65 garren 211             /// Post-fix increment
2 garren 212             edge_iterator  operator++(int);   // Post-fix increment
65 garren 213             /// equality
2 garren 214             bool           operator==( const edge_iterator& a ) const;
65 garren 215             /// inequality
2 garren 216             bool           operator!=( const edge_iterator& a ) const;
65 garren 217             /// true if parent of root vtx
218             bool           is_parent() const;
219             /// true if child of root vtx
220             bool           is_child() const;
221             /// root vertex of this iteration
2 garren 222             const GenVertex*  vertex_root() const;
223         private:
390 garren 224             /// Pre-fix increment -- is not allowed
225             edge_iterator& operator--(void);
226             /// Post-fix increment -- is not allowed
227             edge_iterator  operator--(int);
228         private:
2 garren 229             const GenVertex*  m_vertex;
230             IteratorRange  m_range;
173 garren 231             std::vector<HepMC::GenParticle*>::const_iterator m_set_iter;
2 garren 232             bool           m_is_inparticle_iter;
233             bool           m_is_past_end;
234         };
235         friend class edge_iterator;
65 garren 236         /// size
2 garren 237         int              edges_size( IteratorRange range = family ) const;
65 garren 238         /// begin range
2 garren 239         edge_iterator    edges_begin( IteratorRange range = family) const;
65 garren 240         /// end range
2 garren 241         edge_iterator    edges_end( IteratorRange /* dummy_range */ ) const;
242  
243     public:
244         ///////////////////////////////
245         // vertex_iterator           //
246         ///////////////////////////////
65 garren 247  
248         //!  vertex iterator
249  
250         /// \class  vertex_iterator
251         /// Iterates over all vertices connected via a graph to this vertex.
252         /// this is made friend to that it can access protected edge
253         /// iterator the range can be IteratorRange= ( parents, children,
254         /// family, ancestors, descendants, relatives )
255         /// example for range=descendants the iterator
256         /// will return all vertices
257         /// which are children (connected by an outgoing particle edge),
258         /// grandchildren, great-grandchildren, etc. of this vertex
259         /// In all cases the iterator always returns this vertex
260         /// (returned last).
261         /// The algorithm is accomplished by converting the graph to a tree
262         /// (by "chopping" the edges connecting to an already visited
263         /// vertex) and returning the vertices in POST ORDER traversal.
264         ///
2 garren 265         class vertex_iterator :
173 garren 266           public std::iterator<std::forward_iterator_tag,HepMC::GenVertex*,ptrdiff_t>{
2 garren 267         public:
268             vertex_iterator();
65 garren 269             /// used to set limits on the iteration
2 garren 270             vertex_iterator( GenVertex& vtx_root, IteratorRange range );
65 garren 271             /// next constructor is intended for internal use only
2 garren 272             vertex_iterator( GenVertex& vtx_root, IteratorRange range,
173 garren 273                              std::set<const HepMC::GenVertex*>& visited_vertices );
65 garren 274             /// copy
2 garren 275             vertex_iterator( const vertex_iterator& v_iter );
276             virtual             ~vertex_iterator();
65 garren 277             /// make a copy
2 garren 278             vertex_iterator&    operator=( const vertex_iterator& );
65 garren 279             /// return a pointer to a vertex
2 garren 280             GenVertex*          operator*(void) const;
65 garren 281             /// Pre-fix increment
2 garren 282             vertex_iterator&    operator++(void);  //Pre-fix increment
65 garren 283             /// Post-fix increment
2 garren 284             vertex_iterator     operator++(int);   //Post-fix increment
65 garren 285             /// equality
2 garren 286             bool                operator==( const vertex_iterator& ) const;
65 garren 287             /// inequality
2 garren 288             bool                operator!=( const vertex_iterator& ) const;
65 garren 289             /// vertex that this iterator begins from
2 garren 290             GenVertex*          vertex_root() const;
65 garren 291             /// iterator range
2 garren 292             IteratorRange       range() const;
65 garren 293             /// intended for internal use only.
2 garren 294             void                copy_with_own_set( const vertex_iterator&
295                                                    v_iter,
173 garren 296                                                    std::set<const HepMC::GenVertex*>&
2 garren 297                                                    visited_vertices );
65 garren 298  
2 garren 299         protected:                  // intended for internal use only
65 garren 300             /// non-null if recursive iter. created
301             GenVertex* follow_edge_();
302             /// copy recursive iterator
2 garren 303             void    copy_recursive_iterator_( const vertex_iterator*
304                                               recursive_v_iter );
305         private:
390 garren 306             /// Pre-fix increment -- is not allowed
307             vertex_iterator&    operator--(void);
308             /// Post-fix increment -- is not allowed
309             vertex_iterator     operator--(int);
310  
311         private:
2 garren 312             GenVertex*       m_vertex;   // the vertex associated to this iter
313             IteratorRange    m_range;
173 garren 314             std::set<const HepMC::GenVertex*>* m_visited_vertices;
2 garren 315             bool             m_it_owns_set;  // true if it is responsible for
316                                              // deleting the visited vertex set
317             edge_iterator    m_edge; // particle edge pointing to return vtx
318             vertex_iterator* m_recursive_iterator;
319         };     
320         friend class vertex_iterator;
65 garren 321         /// begin vertex range
2 garren 322         vertex_iterator     vertices_begin( IteratorRange range = relatives );
65 garren 323         /// end vertex range
2 garren 324         vertex_iterator     vertices_end( IteratorRange /* dummy_range */ );
325  
326     public:
327         ///////////////////////////////
328         // particle_iterator         //
329         ///////////////////////////////
65 garren 330  
331         //!  particle iterator
332  
333         /// \class  particle_iterator
334         /// Iterates over all particles connected via a graph.
335         /// by iterating through all vertices in the m_range. For each
336         /// vertex it returns orphaned parent particles
337         /// (i.e. parents without production vertices)
338         /// then children ... in this way each particle is associated
339         /// to exactly one vertex and so it is returned exactly once.
340         /// Is made friend so that it can access protected edge iterator
341         class particle_iterator :
2 garren 342           public std::iterator<std::forward_iterator_tag,GenParticle*,ptrdiff_t>{
343         public:
344             particle_iterator();
65 garren 345             /// used to set limits on the iteration
2 garren 346             particle_iterator( GenVertex& vertex_root, IteratorRange range );
65 garren 347             /// copy
2 garren 348             particle_iterator( const particle_iterator& );
349             virtual             ~particle_iterator();
65 garren 350             /// make a copy
2 garren 351             particle_iterator&  operator=( const particle_iterator& );
65 garren 352             /// return a pointer to a particle
2 garren 353             GenParticle*        operator*(void) const;
65 garren 354             /// Pre-fix increment
355             particle_iterator&  operator++(void);
356             /// Post-fix increment
357             particle_iterator   operator++(int);
358             /// equality
2 garren 359             bool                operator==( const particle_iterator& ) const;
65 garren 360             /// inequality
2 garren 361             bool                operator!=( const particle_iterator& ) const;
362         protected:
65 garren 363             GenParticle*        advance_to_first_(); //!< "first" particle
2 garren 364         private:
365             vertex_iterator     m_vertex_iterator;
366             edge_iterator       m_edge;     // points to the return
367         };
368         friend class particle_iterator;
65 garren 369         /// begin particle range
2 garren 370         particle_iterator       particles_begin( IteratorRange range
371                                                  = relatives );
65 garren 372         /// end particle range
2 garren 373         particle_iterator       particles_end( IteratorRange
374                                                /* dummy_range */ );
375  
376         ////////////////////////////////////////////////
65 garren 377     protected:
378         /// for internal use only
2 garren 379         void delete_adopted_particles();
173 garren 380         /// for internal use only - remove particle from incoming list
381         void remove_particle_in( GenParticle* );
382         /// for internal use only - remove particle from outgoing list
383         void remove_particle_out( GenParticle* );
274 garren 384         /// scale the position vector
385         /// this method is only for use by GenEvent
386         void convert_position( const double& );
387  
2 garren 388     private: // GenVertex data members
46 garren 389         FourVector              m_position;      //4-vec of vertex [mm]
173 garren 390         std::vector<HepMC::GenParticle*>  m_particles_in;  //all incoming particles
391         std::vector<HepMC::GenParticle*>  m_particles_out; //all outgoing particles
2 garren 392         int                  m_id;
393         WeightContainer      m_weights;       // weights for this vtx
394         GenEvent*            m_event;
395         int                  m_barcode;   // unique identifier in the event
396  
255 garren 397         //static unsigned int  s_counter;
2 garren 398     };  
399  
400     ////////////////////////////
401     // INLINES access methods //
402     ////////////////////////////
403  
173 garren 404     inline GenVertex::operator HepMC::FourVector() const { return position(); }
2 garren 405  
173 garren 406     inline GenVertex::operator HepMC::ThreeVector() const { return point3d(); }
2 garren 407  
282 garren 408     inline const FourVector & GenVertex::position() const { return m_position; }
2 garren 409  
410     inline GenEvent* GenVertex::parent_event() const { return m_event; }
411  
43 garren 412     inline ThreeVector GenVertex::point3d() const {
413         return ThreeVector(m_position.x(),m_position.y(),m_position.z());
2 garren 414     }
415  
416     inline int GenVertex::id() const { return m_id; }
417  
418     inline int  GenVertex::barcode() const { return m_barcode; }
419     inline void GenVertex::set_barcode_( int bc ) { m_barcode = bc; }
420  
421     inline WeightContainer& GenVertex::weights() { return m_weights; }
422  
423     inline const WeightContainer& GenVertex::weights() const
424     { return m_weights; }
425  
43 garren 426     inline void GenVertex::set_position( const FourVector& position ) {
2 garren 427         m_position = position;
428     }
429  
430     inline void GenVertex::set_id( int id ) { m_id = id; }
431  
432     //////////////
433     // INLINES  //
434     //////////////
435  
436     inline GenVertex::particles_in_const_iterator
437     GenVertex::particles_in_const_begin() const {
438         return m_particles_in.begin();
439     }
440  
441     inline GenVertex::particles_in_const_iterator
442     GenVertex::particles_in_const_end() const {
443         return m_particles_in.end();
444     }
445  
446     inline GenVertex::particles_out_const_iterator
447     GenVertex::particles_out_const_begin() const {
448         return m_particles_out.begin();
449     }
450  
451     inline GenVertex::particles_out_const_iterator
452     GenVertex::particles_out_const_end() const {       
453         return m_particles_out.end();
454     }
455  
456     inline int GenVertex::particles_in_size() const {
457         return m_particles_in.size();
458     }
459  
460     inline int GenVertex::particles_out_size() const {
461         return m_particles_out.size();
462     }  
463  
464     inline bool GenVertex::edge_iterator::operator==(
465         const edge_iterator& a ) const {
466         return **this == *a;
467     }
468  
469     inline bool GenVertex::edge_iterator::operator!=(
470         const edge_iterator& a ) const {
471         return !(**this == *a);
472     }
473  
474     inline const GenVertex* GenVertex::edge_iterator::vertex_root() const {
475         return m_vertex;
476     }
477  
478     inline GenVertex::edge_iterator GenVertex::edges_begin( IteratorRange
479                                                       range ) const {
480         return GenVertex::edge_iterator(*this, range);
481     }
482  
483     inline GenVertex::edge_iterator GenVertex::edges_end( IteratorRange
484                                                     /* dummy_range */ ) const {
485         return GenVertex::edge_iterator();
486     }
487  
488     inline bool GenVertex::vertex_iterator::operator==(
489         const vertex_iterator& a ) const {
490         return **this == *a;
491     }
492  
493     inline bool GenVertex::vertex_iterator::operator!=(
494         const vertex_iterator& a ) const {
495         return !(**this == *a);
496     }
497  
498     inline GenVertex* GenVertex::vertex_iterator::vertex_root() const {
499         return m_vertex;
500     }
501  
502     inline IteratorRange GenVertex::vertex_iterator::range() const {
503         return m_range;
504     }
505  
506     inline GenVertex::vertex_iterator GenVertex::vertices_begin(
507         IteratorRange range ){
508         // this is not const because the it could return itself
509         return vertex_iterator( *this, range );
510     }
511  
512     inline GenVertex::vertex_iterator GenVertex::vertices_end(
513         IteratorRange /* dummy_range */ ) {
514         return vertex_iterator();
515     }
516  
517     inline bool GenVertex::particle_iterator::operator==(
518         const particle_iterator& a ) const {
519         return **this == *a;
520     }
521  
522     inline bool GenVertex::particle_iterator::operator!=(
523         const particle_iterator& a ) const {
524         return !(**this == *a);
525     }
526  
527     inline GenVertex::particle_iterator GenVertex::particles_begin(
528         IteratorRange range ) {
529         return particle_iterator( *this, range );
530     }
531  
532     inline GenVertex::particle_iterator GenVertex::particles_end(
533         IteratorRange /* dummy_range */ ){
534         return particle_iterator();
535     }
536  
537 } // HepMC
538  
539 #endif  // HEPMC_GEN_VERTEX_H
540 //--------------------------------------------------------------------------
541  
542  
543  
544