CLHEP/HepMC/GenVertex.h

00001 //--------------------------------------------------------------------------
00002 #ifndef HEPMC_GEN_VERTEX_H
00003 #define HEPMC_GEN_VERTEX_H
00004 
00006 // Matt.Dobbs@Cern.CH, September 1999, refer to:
00007 // M. Dobbs and J.B. Hansen, "The HepMC C++ Monte Carlo Event Record for
00008 // High Energy Physics", Computer Physics Communications (to be published).
00009 //
00010 // GenVertex within an event
00011 // A vertex is indirectly (via particle "edges") linked to other 
00012 //   vertices ("nodes") to form a composite "graph"
00014 //
00015 // L. Garren
00016 // replace std::forward_iterator with the standards compliant 
00017 // std::iterator<std::forward_iterator_tag, ...> using typedefs
00018 // 
00020 
00021 #include "CLHEP/HepMC/WeightContainer.h"
00022 #include "CLHEP/Vector/LorentzVector.h"
00023 #include "CLHEP/Geometry/Point3D.h"
00024 #include "CLHEP/config/CLHEP.h"
00025 #include "CLHEP/config/iostream.h"
00026 #include <iterator>
00027 #include <vector>
00028 #include <set>
00029 #include <algorithm>
00030 
00031 namespace HepMC {
00032 
00033     enum IteratorRange { parents, children, family, 
00034                          ancestors, descendants, relatives };
00035     class GenParticle;
00036     class GenEvent;
00037 
00042     class GenVertex {
00043 
00044         friend class GenEvent;
00045         friend std::ostream& operator<<( std::ostream&, const GenVertex& );
00046 
00047     public:
00048 
00049 #if defined __GNUG__ && ( __GNUG__ < 3 )
00050         typedef std::forward_iterator<GenVertex*,ptrdiff_t> forwardVertexIterType;
00051 #else
00052         typedef std::iterator<std::forward_iterator_tag,GenVertex*,ptrdiff_t> forwardVertexIterType;
00053 #endif
00054 
00055         GenVertex( const HepLorentzVector& position =HepLorentzVector(0,0,0,0),
00056                    int id = 0, 
00057                    const WeightContainer& weights = std::vector<double>() );
00058         GenVertex( const GenVertex& invertex );            // shallow copy
00059         virtual    ~GenVertex();
00060 
00061         GenVertex& operator= ( const GenVertex& invertex ); // shallow
00062         bool       operator==( const GenVertex& a ) const;
00063         bool       operator!=( const GenVertex& a ) const;
00064         void       print( std::ostream& ostr = std::cout ) const;
00065 
00066         double     check_momentum_conservation() const;//|Sum (mom_in-mom_out)|
00067 
00068         void       add_particle_in( GenParticle* inparticle );
00069         void       add_particle_out( GenParticle* outparticle );
00070         // remove_particle finds *particle in the in and/or out list and
00071         //  removes it from these lists ... it DOES NOT DELETE THE PARTICLE 
00072         //  or its relations. You could delete the particle too as follows:
00073         //      delete vtx->remove_particle( particle );
00074         // or if the particle has an end vertex, you could:
00075         //      delete vtx->remove_particle( particle )->end_vertex();
00076         GenParticle* remove_particle( GenParticle* particle );
00077 
00078         operator HepLorentzVector() const; // conversion operator
00079         operator HepPoint3D() const; // conversion operator
00080 
00082         // access methods //
00084 
00085         GenEvent*               parent_event() const;
00086         HepPoint3D              point3d() const;
00087         HepLorentzVector        position() const;
00088         void                    set_position( const HepLorentzVector& position 
00089                                               = HepLorentzVector(0,0,0,0) );
00090         // we don't define what you use the id for -- but we imagine,
00091         // for example it might code the meaning of the weights()
00092         int                     id() const;
00093         void                    set_id( int id );
00094 
00095         //
00096         // The barcode is the vertex's reference number, every vertex in the
00097         //  event has a unique barcode. Vertex barcodes are negative numbers,
00098         //  particle barcodes are positive numbers.
00099         // In general there is no reason to "suggest_barcode", if a vertex is
00100         //  added to the event without a suggested barcode, the event will
00101         //  assign one for it.
00102         int                     barcode() const;
00103         bool                    suggest_barcode( int the_bar_code );
00104         
00105         // direct access to the weights container is allowed. 
00106         WeightContainer&        weights();
00107         const WeightContainer&  weights() const;
00108         
00109         // get pointers to mothers and daughters
00110         GenParticle *      mother()         const;
00111         GenParticle *      secondMother()   const;
00112         GenParticle *      beginDaughters() const;
00113         GenParticle *      endDaughters()   const;
00114         // get vectors of pointers to particles
00115         std::vector<GenParticle*> listChildren() const;
00116         std::vector<GenParticle*> listDescendants();
00117         std::vector<GenParticle*> listParents() const;
00118         std::vector<GenParticle*> listAncestors();
00119         // more utility methods
00120         bool hasParents() const;
00121         bool hasChildren() const;
00122         int  numParents() const;
00123         int  numChildren() const;
00124 
00126         // Iterators      // users should use prefer to use particle_iterator
00128 
00129         typedef std::set<GenParticle*>::const_iterator 
00130         particles_in_const_iterator;
00131         typedef std::set<GenParticle*>::const_iterator 
00132         particles_out_const_iterator;
00133         particles_in_const_iterator         particles_in_const_begin() const;
00134         particles_in_const_iterator         particles_in_const_end() const;
00135         particles_out_const_iterator        particles_out_const_begin() const;
00136         particles_out_const_iterator        particles_out_const_end() const;
00137         int                                 particles_in_size() const;
00138         int                                 particles_out_size() const;
00139 
00140     protected:
00141         static unsigned int     counter(); // temporary for debugging
00142 
00143         // only the GenEvent (friend) is allowed to set the parent_event,
00144         //  and barcode. It is done automatically anytime you add a 
00145         //  vertex to an event
00146         void                    set_parent_event_( GenEvent* evt );
00147         void                    set_barcode_( int the_bar_code );
00148 
00149     public:
00151         // edge_iterator           // (protected - for internal use only)
00153         // If the user wants the functionality of the edge_iterator, he should
00154         // use particle_iterator with IteratorRange = family, parents, children
00155         //
00156         class edge_iterator :
00157             public forwardVertexIterType {
00158             // iterate over the family of edges connected to m_vertex begins 
00159             // with parents (incoming particles) then children (outgoing)
00160             // This is not a recursive iterator ... it is a building block
00161             // for the public iterators and is intended for internal use only.
00162             // The acceptable Iterator Ranges are: family, parents, children
00163         public:
00164             edge_iterator();
00165             edge_iterator( const GenVertex& vtx, IteratorRange range =family );
00166             edge_iterator( const edge_iterator& p );
00167             virtual        ~edge_iterator();
00168             edge_iterator& operator=( const edge_iterator& p );
00169             GenParticle*      operator*(void) const;
00170             edge_iterator& operator++(void); // Pre-fix increment 
00171             edge_iterator  operator++(int);   // Post-fix increment
00172             bool           operator==( const edge_iterator& a ) const;
00173             bool           operator!=( const edge_iterator& a ) const;
00174             bool           is_parent() const; // true if parent of root vtx
00175             bool           is_child() const;  // true if child of root vtx
00176             const GenVertex*  vertex_root() const;
00177         private:
00178             const GenVertex*  m_vertex;
00179             IteratorRange  m_range;
00180             std::set<GenParticle*>::const_iterator m_set_iter;
00181             bool           m_is_inparticle_iter;
00182             bool           m_is_past_end;
00183         };
00184         friend class edge_iterator;
00185         int              edges_size( IteratorRange range = family ) const;
00186         edge_iterator    edges_begin( IteratorRange range = family) const;
00187         edge_iterator    edges_end( IteratorRange /* dummy_range */ ) const;
00188 
00189     public:
00191         // vertex_iterator           //
00193         class vertex_iterator :
00194             public forwardVertexIterType {
00195             // Iterates over all vertices connected via a graph to this vertex.
00196             // this is made friend to that it can access protected edge
00197             // iterator the range can be IteratorRange= ( parents, children, 
00198             // family, ancestors, descendants, relatives )
00199             // example for range=descendants the iterator 
00200             // will return all vertices
00201             // which are children (connected by an outgoing particle edge),
00202             // grandchildren, great-grandchildren, etc. of this vertex
00203             // In all cases the iterator always returns this vertex
00204             // (returned last).
00205             // The algorithm is accomplished by converting the graph to a tree
00206             // (by "chopping" the edges connecting to an already visited
00207             // vertex) and returning the vertices in POST ORDER traversal.
00208             //
00209         public:
00210             vertex_iterator();
00211             vertex_iterator( GenVertex& vtx_root, IteratorRange range );
00212             // next constructor is intended for internal use only
00213             vertex_iterator( GenVertex& vtx_root, IteratorRange range,
00214                              std::set<const GenVertex*>& visited_vertices );
00215             vertex_iterator( const vertex_iterator& v_iter );
00216             virtual             ~vertex_iterator();
00217             vertex_iterator&    operator=( const vertex_iterator& );
00218             GenVertex*          operator*(void) const;
00219             vertex_iterator&    operator++(void);  //Pre-fix increment 
00220             vertex_iterator     operator++(int);   //Post-fix increment
00221             bool                operator==( const vertex_iterator& ) const;
00222             bool                operator!=( const vertex_iterator& ) const;
00223             GenVertex*          vertex_root() const;
00224             IteratorRange       range() const;
00225             void                copy_with_own_set( const vertex_iterator& 
00226                                                    v_iter,
00227                                                    std::set<const GenVertex*>& 
00228                                                    visited_vertices );
00229         protected:                  // intended for internal use only
00230             GenVertex* follow_edge_(); // non-null if recursive iter. created
00231             void    copy_recursive_iterator_( const vertex_iterator* 
00232                                               recursive_v_iter );
00233         private:
00234             GenVertex*       m_vertex;   // the vertex associated to this iter
00235             IteratorRange    m_range;
00236             std::set<const GenVertex*>* m_visited_vertices;
00237             bool             m_it_owns_set;  // true if it is responsible for 
00238                                              // deleting the visited vertex set
00239             edge_iterator    m_edge; // particle edge pointing to return vtx
00240             vertex_iterator* m_recursive_iterator;
00241         };      
00242         friend class vertex_iterator;
00243         vertex_iterator     vertices_begin( IteratorRange range = relatives );
00244         vertex_iterator     vertices_end( IteratorRange /* dummy_range */ );
00245 
00246     public:
00248         // particle_iterator         //
00250         class particle_iterator :
00251             public forwardVertexIterType {
00252             // Iterates over all particles connected via a graph.
00253             // by iterating through all vertices in the m_range. For each
00254             // vertex it returns orphaned parent particles 
00255             // (i.e. parents without production vertices) 
00256             // then children ... in this way each particle is associated
00257             // to exactly one vertex and so it is returned exactly once.
00258             // Is made friend so that it can access protected edge iterator
00259         public:
00260             particle_iterator();
00261             particle_iterator( GenVertex& vertex_root, IteratorRange range );
00262             particle_iterator( const particle_iterator& );
00263             virtual             ~particle_iterator();
00264             particle_iterator&  operator=( const particle_iterator& );
00265             GenParticle*        operator*(void) const;
00266             particle_iterator&  operator++(void);  //Pre-fix increment 
00267             particle_iterator   operator++(int);   //Post-fix increment
00268             bool                operator==( const particle_iterator& ) const;
00269             bool                operator!=( const particle_iterator& ) const;
00270         protected:
00271             GenParticle*        advance_to_first_();
00272         private:
00273             vertex_iterator     m_vertex_iterator;
00274             edge_iterator       m_edge;     // points to the return
00275         };      
00276         friend class particle_iterator; 
00277         particle_iterator       particles_begin( IteratorRange range 
00278                                                  = relatives );
00279         particle_iterator       particles_end( IteratorRange 
00280                                                /* dummy_range */ );
00281 
00283     protected: // for internal use only
00284         void delete_adopted_particles();
00285         
00286     private: // GenVertex data members
00287         HepLorentzVector     m_position;      //4-vec of vertex [mm]
00288         std::set<GenParticle*>  m_particles_in;  //all incoming particles
00289         std::set<GenParticle*>  m_particles_out; //all outgoing particles
00290         int                  m_id;
00291         WeightContainer      m_weights;       // weights for this vtx
00292         GenEvent*            m_event;
00293         int                  m_barcode;   // unique identifier in the event
00294 
00295         static unsigned int  s_counter;
00296     };  
00297 
00299     // INLINES access methods //
00301 
00302     inline GenVertex::operator HepLorentzVector() const { return position(); }
00303 
00304     inline GenVertex::operator HepPoint3D() const { return point3d(); }
00305 
00306     inline HepLorentzVector GenVertex::position() const { return m_position; }
00307 
00308     inline GenEvent* GenVertex::parent_event() const { return m_event; }
00309 
00310     inline HepPoint3D GenVertex::point3d() const { 
00311         return (HepPoint3D)m_position; 
00312     }
00313 
00314     inline int GenVertex::id() const { return m_id; }
00315 
00316     inline int  GenVertex::barcode() const { return m_barcode; }
00317     inline void GenVertex::set_barcode_( int bc ) { m_barcode = bc; }
00318 
00319     inline WeightContainer& GenVertex::weights() { return m_weights; }
00320 
00321     inline const WeightContainer& GenVertex::weights() const 
00322     { return m_weights; }
00323 
00324     inline void GenVertex::set_position( const HepLorentzVector& position ) {
00325         m_position = position;
00326     }
00327 
00328     inline void GenVertex::set_id( int id ) { m_id = id; }
00329 
00331     // INLINES  //
00333 
00334     inline GenVertex::particles_in_const_iterator 
00335     GenVertex::particles_in_const_begin() const { 
00336         return m_particles_in.begin(); 
00337     }
00338 
00339     inline GenVertex::particles_in_const_iterator 
00340     GenVertex::particles_in_const_end() const { 
00341         return m_particles_in.end(); 
00342     }
00343 
00344     inline GenVertex::particles_out_const_iterator 
00345     GenVertex::particles_out_const_begin() const { 
00346         return m_particles_out.begin();
00347     }
00348 
00349     inline GenVertex::particles_out_const_iterator 
00350     GenVertex::particles_out_const_end() const {        
00351         return m_particles_out.end(); 
00352     }
00353 
00354     inline int GenVertex::particles_in_size() const {
00355         return m_particles_in.size(); 
00356     }
00357 
00358     inline int GenVertex::particles_out_size() const {
00359         return m_particles_out.size(); 
00360     }   
00361 
00362     inline bool GenVertex::edge_iterator::operator==( 
00363         const edge_iterator& a ) const { 
00364         return **this == *a; 
00365     }
00366 
00367     inline bool GenVertex::edge_iterator::operator!=(
00368         const edge_iterator& a ) const { 
00369         return !(**this == *a); 
00370     }
00371 
00372     inline const GenVertex* GenVertex::edge_iterator::vertex_root() const {
00373         return m_vertex;
00374     }
00375 
00376     inline GenVertex::edge_iterator GenVertex::edges_begin( IteratorRange 
00377                                                       range ) const {
00378         return GenVertex::edge_iterator(*this, range);
00379     }
00380 
00381     inline GenVertex::edge_iterator GenVertex::edges_end( IteratorRange 
00382                                                     /* dummy_range */ ) const {
00383         return GenVertex::edge_iterator();
00384     }
00385 
00386     inline bool GenVertex::vertex_iterator::operator==( 
00387         const vertex_iterator& a ) const {
00388         return **this == *a; 
00389     }
00390 
00391     inline bool GenVertex::vertex_iterator::operator!=( 
00392         const vertex_iterator& a ) const {
00393         return !(**this == *a); 
00394     }
00395 
00396     inline GenVertex* GenVertex::vertex_iterator::vertex_root() const {
00397         return m_vertex; 
00398     }
00399 
00400     inline IteratorRange GenVertex::vertex_iterator::range() const {
00401         return m_range; 
00402     }
00403 
00404     inline GenVertex::vertex_iterator GenVertex::vertices_begin( 
00405         IteratorRange range ){
00406         // this is not const because the it could return itself
00407         return vertex_iterator( *this, range );
00408     }
00409 
00410     inline GenVertex::vertex_iterator GenVertex::vertices_end( 
00411         IteratorRange /* dummy_range */ ) {
00412         return vertex_iterator();
00413     }
00414 
00415     inline bool GenVertex::particle_iterator::operator==( 
00416         const particle_iterator& a ) const {
00417         return **this == *a; 
00418     }
00419 
00420     inline bool GenVertex::particle_iterator::operator!=( 
00421         const particle_iterator& a ) const {
00422         return !(**this == *a); 
00423     }
00424 
00425     inline GenVertex::particle_iterator GenVertex::particles_begin( 
00426         IteratorRange range ) {
00427         return particle_iterator( *this, range );
00428     }
00429 
00430     inline GenVertex::particle_iterator GenVertex::particles_end(
00431         IteratorRange /* dummy_range */ ){
00432         return particle_iterator();
00433     }
00434 
00435 } // HepMC
00436 
00437 #endif  // HEPMC_GEN_VERTEX_H
00438 //--------------------------------------------------------------------------
00439 
00440 
00441 
00442 

Class Library for High Energy Physics (version 1.8)