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 
00121         // Iterators      // users should use prefer to use particle_iterator
00123 
00124         typedef std::set<GenParticle*>::const_iterator 
00125         particles_in_const_iterator;
00126         typedef std::set<GenParticle*>::const_iterator 
00127         particles_out_const_iterator;
00128         particles_in_const_iterator         particles_in_const_begin() const;
00129         particles_in_const_iterator         particles_in_const_end() const;
00130         particles_out_const_iterator        particles_out_const_begin() const;
00131         particles_out_const_iterator        particles_out_const_end() const;
00132         int                                 particles_in_size() const;
00133         int                                 particles_out_size() const;
00134 
00135     protected:
00136         static unsigned int     counter(); // temporary for debugging
00137 
00138         // only the GenEvent (friend) is allowed to set the parent_event,
00139         //  and barcode. It is done automatically anytime you add a 
00140         //  vertex to an event
00141         void                    set_parent_event_( GenEvent* evt );
00142         void                    set_barcode_( int the_bar_code );
00143 
00144     public:
00146         // edge_iterator           // (protected - for internal use only)
00148         // If the user wants the functionality of the edge_iterator, he should
00149         // use particle_iterator with IteratorRange = family, parents, children
00150         //
00151         class edge_iterator :
00152             public forwardVertexIterType {
00153             // iterate over the family of edges connected to m_vertex begins 
00154             // with parents (incoming particles) then children (outgoing)
00155             // This is not a recursive iterator ... it is a building block
00156             // for the public iterators and is intended for internal use only.
00157             // The acceptable Iterator Ranges are: family, parents, children
00158         public:
00159             edge_iterator();
00160             edge_iterator( const GenVertex& vtx, IteratorRange range =family );
00161             edge_iterator( const edge_iterator& p );
00162             virtual        ~edge_iterator();
00163             edge_iterator& operator=( const edge_iterator& p );
00164             GenParticle*      operator*(void) const;
00165             edge_iterator& operator++(void); // Pre-fix increment 
00166             edge_iterator  operator++(int);   // Post-fix increment
00167             bool           operator==( const edge_iterator& a ) const;
00168             bool           operator!=( const edge_iterator& a ) const;
00169             bool           is_parent() const; // true if parent of root vtx
00170             bool           is_child() const;  // true if child of root vtx
00171             const GenVertex*  vertex_root() const;
00172         private:
00173             const GenVertex*  m_vertex;
00174             IteratorRange  m_range;
00175             std::set<GenParticle*>::const_iterator m_set_iter;
00176             bool           m_is_inparticle_iter;
00177             bool           m_is_past_end;
00178         };
00179         friend class edge_iterator;
00180         int              edges_size( IteratorRange range = family ) const;
00181         edge_iterator    edges_begin( IteratorRange range = family) const;
00182         edge_iterator    edges_end( IteratorRange /* dummy_range */ ) const;
00183 
00184     public:
00186         // vertex_iterator           //
00188         class vertex_iterator :
00189             public forwardVertexIterType {
00190             // Iterates over all vertices connected via a graph to this vertex.
00191             // this is made friend to that it can access protected edge
00192             // iterator the range can be IteratorRange= ( parents, children, 
00193             // family, ancestors, descendants, relatives )
00194             // example for range=descendants the iterator 
00195             // will return all vertices
00196             // which are children (connected by an outgoing particle edge),
00197             // grandchildren, great-grandchildren, etc. of this vertex
00198             // In all cases the iterator always returns this vertex
00199             // (returned last).
00200             // The algorithm is accomplished by converting the graph to a tree
00201             // (by "chopping" the edges connecting to an already visited
00202             // vertex) and returning the vertices in POST ORDER traversal.
00203             //
00204         public:
00205             vertex_iterator();
00206             vertex_iterator( GenVertex& vtx_root, IteratorRange range );
00207             // next constructor is intended for internal use only
00208             vertex_iterator( GenVertex& vtx_root, IteratorRange range,
00209                              std::set<const GenVertex*>& visited_vertices );
00210             vertex_iterator( const vertex_iterator& v_iter );
00211             virtual             ~vertex_iterator();
00212             vertex_iterator&    operator=( const vertex_iterator& );
00213             GenVertex*          operator*(void) const;
00214             vertex_iterator&    operator++(void);  //Pre-fix increment 
00215             vertex_iterator     operator++(int);   //Post-fix increment
00216             bool                operator==( const vertex_iterator& ) const;
00217             bool                operator!=( const vertex_iterator& ) const;
00218             GenVertex*          vertex_root() const;
00219             IteratorRange       range() const;
00220             void                copy_with_own_set( const vertex_iterator& 
00221                                                    v_iter,
00222                                                    std::set<const GenVertex*>& 
00223                                                    visited_vertices );
00224         protected:                  // intended for internal use only
00225             GenVertex* follow_edge_(); // non-null if recursive iter. created
00226             void    copy_recursive_iterator_( const vertex_iterator* 
00227                                               recursive_v_iter );
00228         private:
00229             GenVertex*       m_vertex;   // the vertex associated to this iter
00230             IteratorRange    m_range;
00231             std::set<const GenVertex*>* m_visited_vertices;
00232             bool             m_it_owns_set;  // true if it is responsible for 
00233                                              // deleting the visited vertex set
00234             edge_iterator    m_edge; // particle edge pointing to return vtx
00235             vertex_iterator* m_recursive_iterator;
00236         };      
00237         friend class vertex_iterator;
00238         vertex_iterator     vertices_begin( IteratorRange range = relatives );
00239         vertex_iterator     vertices_end( IteratorRange /* dummy_range */ );
00240 
00241     public:
00243         // particle_iterator         //
00245         class particle_iterator :
00246             public forwardVertexIterType {
00247             // Iterates over all particles connected via a graph.
00248             // by iterating through all vertices in the m_range. For each
00249             // vertex it returns orphaned parent particles 
00250             // (i.e. parents without production vertices) 
00251             // then children ... in this way each particle is associated
00252             // to exactly one vertex and so it is returned exactly once.
00253             // Is made friend so that it can access protected edge iterator
00254         public:
00255             particle_iterator();
00256             particle_iterator( GenVertex& vertex_root, IteratorRange range );
00257             particle_iterator( const particle_iterator& );
00258             virtual             ~particle_iterator();
00259             particle_iterator&  operator=( const particle_iterator& );
00260             GenParticle*        operator*(void) const;
00261             particle_iterator&  operator++(void);  //Pre-fix increment 
00262             particle_iterator   operator++(int);   //Post-fix increment
00263             bool                operator==( const particle_iterator& ) const;
00264             bool                operator!=( const particle_iterator& ) const;
00265         protected:
00266             GenParticle*        advance_to_first_();
00267         private:
00268             vertex_iterator     m_vertex_iterator;
00269             edge_iterator       m_edge;     // points to the return
00270         };      
00271         friend class particle_iterator; 
00272         particle_iterator       particles_begin( IteratorRange range 
00273                                                  = relatives );
00274         particle_iterator       particles_end( IteratorRange 
00275                                                /* dummy_range */ );
00276 
00278     protected: // for internal use only
00279         void delete_adopted_particles();
00280         
00281     private: // GenVertex data members
00282         HepLorentzVector     m_position;      //4-vec of vertex [mm]
00283         std::set<GenParticle*>  m_particles_in;  //all incoming particles
00284         std::set<GenParticle*>  m_particles_out; //all outgoing particles
00285         int                  m_id;
00286         WeightContainer      m_weights;       // weights for this vtx
00287         GenEvent*            m_event;
00288         int                  m_barcode;   // unique identifier in the event
00289 
00290         static unsigned int  s_counter;
00291     };  
00292 
00294     // INLINES access methods //
00296 
00297     inline GenVertex::operator HepLorentzVector() const { return position(); }
00298 
00299     inline GenVertex::operator HepPoint3D() const { return point3d(); }
00300 
00301     inline HepLorentzVector GenVertex::position() const { return m_position; }
00302 
00303     inline GenEvent* GenVertex::parent_event() const { return m_event; }
00304 
00305     inline HepPoint3D GenVertex::point3d() const { 
00306         return (HepPoint3D)m_position; 
00307     }
00308 
00309     inline int GenVertex::id() const { return m_id; }
00310 
00311     inline int  GenVertex::barcode() const { return m_barcode; }
00312     inline void GenVertex::set_barcode_( int bc ) { m_barcode = bc; }
00313 
00314     inline WeightContainer& GenVertex::weights() { return m_weights; }
00315 
00316     inline const WeightContainer& GenVertex::weights() const 
00317     { return m_weights; }
00318 
00319     inline void GenVertex::set_position( const HepLorentzVector& position ) {
00320         m_position = position;
00321     }
00322 
00323     inline void GenVertex::set_id( int id ) { m_id = id; }
00324 
00326     // INLINES  //
00328 
00329     inline GenVertex::particles_in_const_iterator 
00330     GenVertex::particles_in_const_begin() const { 
00331         return m_particles_in.begin(); 
00332     }
00333 
00334     inline GenVertex::particles_in_const_iterator 
00335     GenVertex::particles_in_const_end() const { 
00336         return m_particles_in.end(); 
00337     }
00338 
00339     inline GenVertex::particles_out_const_iterator 
00340     GenVertex::particles_out_const_begin() const { 
00341         return m_particles_out.begin();
00342     }
00343 
00344     inline GenVertex::particles_out_const_iterator 
00345     GenVertex::particles_out_const_end() const {        
00346         return m_particles_out.end(); 
00347     }
00348 
00349     inline int GenVertex::particles_in_size() const {
00350         return m_particles_in.size(); 
00351     }
00352 
00353     inline int GenVertex::particles_out_size() const {
00354         return m_particles_out.size(); 
00355     }   
00356 
00357     inline bool GenVertex::edge_iterator::operator==( 
00358         const edge_iterator& a ) const { 
00359         return **this == *a; 
00360     }
00361 
00362     inline bool GenVertex::edge_iterator::operator!=(
00363         const edge_iterator& a ) const { 
00364         return !(**this == *a); 
00365     }
00366 
00367     inline const GenVertex* GenVertex::edge_iterator::vertex_root() const {
00368         return m_vertex;
00369     }
00370 
00371     inline GenVertex::edge_iterator GenVertex::edges_begin( IteratorRange 
00372                                                       range ) const {
00373         return GenVertex::edge_iterator(*this, range);
00374     }
00375 
00376     inline GenVertex::edge_iterator GenVertex::edges_end( IteratorRange 
00377                                                     /* dummy_range */ ) const {
00378         return GenVertex::edge_iterator();
00379     }
00380 
00381     inline bool GenVertex::vertex_iterator::operator==( 
00382         const vertex_iterator& a ) const {
00383         return **this == *a; 
00384     }
00385 
00386     inline bool GenVertex::vertex_iterator::operator!=( 
00387         const vertex_iterator& a ) const {
00388         return !(**this == *a); 
00389     }
00390 
00391     inline GenVertex* GenVertex::vertex_iterator::vertex_root() const {
00392         return m_vertex; 
00393     }
00394 
00395     inline IteratorRange GenVertex::vertex_iterator::range() const {
00396         return m_range; 
00397     }
00398 
00399     inline GenVertex::vertex_iterator GenVertex::vertices_begin( 
00400         IteratorRange range ){
00401         // this is not const because the it could return itself
00402         return vertex_iterator( *this, range );
00403     }
00404 
00405     inline GenVertex::vertex_iterator GenVertex::vertices_end( 
00406         IteratorRange /* dummy_range */ ) {
00407         return vertex_iterator();
00408     }
00409 
00410     inline bool GenVertex::particle_iterator::operator==( 
00411         const particle_iterator& a ) const {
00412         return **this == *a; 
00413     }
00414 
00415     inline bool GenVertex::particle_iterator::operator!=( 
00416         const particle_iterator& a ) const {
00417         return !(**this == *a); 
00418     }
00419 
00420     inline GenVertex::particle_iterator GenVertex::particles_begin( 
00421         IteratorRange range ) {
00422         return particle_iterator( *this, range );
00423     }
00424 
00425     inline GenVertex::particle_iterator GenVertex::particles_end(
00426         IteratorRange /* dummy_range */ ){
00427         return particle_iterator();
00428     }
00429 
00430 } // HepMC
00431 
00432 #endif  // HEPMC_GEN_VERTEX_H
00433 //--------------------------------------------------------------------------
00434 
00435 
00436 
00437 

Class Library for High Energy Physics (version 1.8)