Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:01:09

0001 //--------------------------------------------------------------------------
0002 #ifndef HEPMC_GEN_VERTEX_H
0003 #define HEPMC_GEN_VERTEX_H
0004 
0005 //////////////////////////////////////////////////////////////////////////
0006 // Matt.Dobbs@Cern.CH, September 1999, refer to:
0007 // M. Dobbs and J.B. Hansen, "The HepMC C++ Monte Carlo Event Record for
0008 // High Energy Physics", Computer Physics Communications (to be published).
0009 //
0010 // GenVertex within an event
0011 // A vertex is indirectly (via particle "edges") linked to other 
0012 //   vertices ("nodes") to form a composite "graph"
0013 //////////////////////////////////////////////////////////////////////////
0014 
0015 // --> HANDLE COMPILER INCONSISTENCIES
0016 // This pre-compiler directive is included (2002-01-16) to allow compatibility
0017 // with several compilers.
0018 // Mar 27, 2004: HepMC is now standard compliant only. 
0019 //   I've removed forward_iterator, and it will no longer compile on gcc < 3. 
0020 #ifdef __SUNPRO_CC    // Solaris CC 5.2
0021 #define NEED_SOLARIS_FRIEND_FEATURE
0022 #endif // Platform
0023 
0024 #include "HepMC/WeightContainer.h"
0025 #include "HepMC/SimpleVector.h"
0026 #include "HepMC/IteratorRange.h"
0027 #include <iostream>
0028 #include <iterator>
0029 #include <vector>
0030 #include <set>
0031 #include <algorithm>
0032 #include <cstddef>
0033 
0034 namespace HepMC {
0035 
0036     class GenVertexParticleRange;
0037     class GenParticleProductionRange;
0038     class ConstGenParticleProductionRange;
0039     class GenParticleEndRange;
0040     class ConstGenParticleEndRange;
0041 
0042     class GenParticle;
0043     class GenEvent;
0044 
0045     //! GenVertex contains information about decay vertices.
0046 
0047     ///
0048     /// \class GenVertex 
0049     /// HepMC::GenVertex contains the position in space and time of a decay.
0050     /// It also contains lists of incoming and outgoing particles.  
0051     ///
0052     class GenVertex {
0053 
0054         /// print vertex information
0055     friend std::ostream& operator<<( std::ostream&, const GenVertex& );
0056     friend class GenEvent;
0057 
0058 #ifdef NEED_SOLARIS_FRIEND_FEATURE
0059     // This bit of ugly code is only for CC-5.2 compiler. 
0060     // M.Dobbs 2002/02/19 
0061     // It is not needed by linux gcc, nor Windows Visual C++.
0062     public: 
0063     class vertex_iterator;
0064     friend class vertex_iterator;
0065     class particle_iterator;
0066     friend class particle_iterator;
0067 #endif // NEED_SOLARIS_FRIEND_FEATURE
0068 
0069     public:
0070         /// default constructor
0071     GenVertex( const FourVector& position =FourVector(0,0,0,0),
0072            int id = 0, 
0073            const WeightContainer& weights = std::vector<double>() );
0074     GenVertex( const GenVertex& invertex );            //!< shallow copy
0075     virtual    ~GenVertex();
0076 
0077         void swap( GenVertex & other); //!< swap
0078     GenVertex& operator= ( const GenVertex& invertex ); //!< shallow
0079     bool       operator==( const GenVertex& a ) const; //!< equality
0080     bool       operator!=( const GenVertex& a ) const; //!< inequality
0081     void       print( std::ostream& ostr = std::cout ) const; //!< print vertex information
0082 
0083     double     check_momentum_conservation() const;//!< |Sum (three_mom_in-three_mom_out)|
0084 
0085     /// add incoming particle
0086     void       add_particle_in( GenParticle* inparticle );
0087     /// add outgoing particle
0088     void       add_particle_out( GenParticle* outparticle );
0089     /// remove_particle finds *particle in the in and/or out list and
0090     ///  removes it from these lists ... it DOES NOT DELETE THE PARTICLE 
0091     ///  or its relations. You could delete the particle too as follows:
0092     ///      delete vtx->remove_particle( particle );
0093     GenParticle* remove_particle( GenParticle* particle ); //!< remove a particle
0094 
0095     operator    HepMC::FourVector() const; //!< conversion operator
0096     operator   HepMC::ThreeVector() const; //!< conversion operator
0097 
0098     ////////////////////
0099     // access methods //
0100     ////////////////////
0101 
0102     /// pointer to the event that owns this vertex
0103     GenEvent*               parent_event() const;
0104     /// vertex position
0105     ThreeVector             point3d() const;
0106     /// vertex position and time
0107     const FourVector &      position() const;
0108     /// set vertex position and time
0109     void                    set_position( const FourVector& position = FourVector(0,0,0,0) );
0110     /// we don't define what you use the id for -- but we imagine,
0111     /// for example it might code the meaning of the weights()
0112     int                     id() const;  //!< vertex ID
0113     void                    set_id( int id );  //!< set vertex ID
0114 
0115     ///
0116     /// The barcode is the vertex's reference number, every vertex in the
0117     /// event has a unique barcode. Vertex barcodes are negative numbers,
0118     /// particle barcodes are positive numbers.
0119     /// 
0120     /// Please note that the barcodes are intended for internal use within 
0121     /// HepMC as a unique identifier for the particles and vertices.
0122     /// Using the barcode to encode extra information is an abuse of 
0123     /// the barcode data member and causes confusion among users. 
0124     /// 
0125     int                     barcode() const; //!< unique identifier
0126 
0127     /// In general there is no reason to "suggest_barcode"
0128     bool                    suggest_barcode( int the_bar_code );
0129     
0130     /// direct access to the weights container is allowed. 
0131     WeightContainer&        weights();
0132     /// const direct access to the weights container
0133     const WeightContainer&  weights() const;
0134 
0135     /// particle range
0136     GenVertexParticleRange particles( IteratorRange range = relatives );
0137     /// incoming particle range
0138     GenParticleProductionRange particles_in( GenParticle&, IteratorRange range = relatives );
0139     /// incoming particle range
0140     ConstGenParticleProductionRange particles_in( GenParticle const &, IteratorRange range = relatives ) const;
0141     /// outgoing particle range
0142     GenParticleEndRange particles_out( GenParticle&, IteratorRange range = relatives );
0143     /// outgoing particle range
0144     ConstGenParticleEndRange particles_out( GenParticle const &, IteratorRange range = relatives ) const;
0145 
0146     ////////////////////
0147     // Iterators      // users should use prefer to use particle_iterator
0148     ////////////////////    
0149 
0150     /// const iterator for incoming particles
0151     typedef std::vector<HepMC::GenParticle*>::const_iterator 
0152     particles_in_const_iterator;
0153     /// const iterator for outgoing particles
0154     typedef std::vector<HepMC::GenParticle*>::const_iterator 
0155     particles_out_const_iterator;
0156     /// begin iteration of incoming particles
0157     particles_in_const_iterator         particles_in_const_begin() const;
0158     /// end iteration of incoming particles
0159     particles_in_const_iterator         particles_in_const_end() const;
0160     /// begin iteration of outgoing particles
0161     particles_out_const_iterator        particles_out_const_begin() const;
0162     /// end iteration of outgoing particles
0163     particles_out_const_iterator        particles_out_const_end() const;
0164     /// number of incoming particles
0165     int                                 particles_in_size() const;
0166     /// number of outgoing particles
0167     int                                 particles_out_size() const;
0168 
0169     protected:
0170     //static unsigned int     counter(); //!< temporary for debugging
0171 
0172     /// only the GenEvent (friend) is allowed to set the parent_event,
0173     ///  and barcode. It is done automatically anytime you add a 
0174     ///  vertex to an event
0175     void                    set_parent_event_( GenEvent* evt ); //!< set parent event
0176     void                    set_barcode_( int the_bar_code ); //!< set identifier
0177     void                    change_parent_event_( GenEvent* evt ); //!< for use with swap
0178 
0179     /////////////////////////////
0180     // edge_iterator           // (protected - for internal use only)
0181     /////////////////////////////
0182     // If the user wants the functionality of the edge_iterator, he should
0183     // use particle_iterator with IteratorRange = family, parents, children
0184     //
0185 
0186     //!  edge iterator
0187 
0188     /// \class  edge_iterator
0189     /// iterate over the family of edges connected to m_vertex begins 
0190     /// with parents (incoming particles) then children (outgoing)
0191     /// This is not a recursive iterator ... it is a building block
0192     /// for the public iterators and is intended for internal use only.
0193     /// The acceptable Iterator Ranges are: family, parents, children
0194     class edge_iterator :
0195       public std::iterator<std::forward_iterator_tag,HepMC::GenParticle*,ptrdiff_t>{
0196     public:
0197         edge_iterator();
0198         /// used to set limits on the iteration
0199         edge_iterator( const GenVertex& vtx, IteratorRange range =family );
0200         /// copy
0201         edge_iterator( const edge_iterator& p );
0202         virtual        ~edge_iterator();
0203         /// make a copy
0204         edge_iterator& operator=( const edge_iterator& p );
0205         /// return a pointer to a particle
0206         GenParticle*      operator*(void) const;
0207         /// Pre-fix increment 
0208         edge_iterator& operator++(void); // Pre-fix increment 
0209         /// Post-fix increment
0210         edge_iterator  operator++(int);   // Post-fix increment
0211         /// equality
0212         bool           operator==( const edge_iterator& a ) const;
0213         /// inequality
0214         bool           operator!=( const edge_iterator& a ) const;
0215         /// true if parent of root vtx
0216         bool           is_parent() const;
0217         /// true if child of root vtx
0218         bool           is_child() const;
0219         /// root vertex of this iteration
0220         const GenVertex*  vertex_root() const;
0221     private:
0222         /// Pre-fix increment -- is not allowed
0223         edge_iterator& operator--(void);
0224         /// Post-fix increment -- is not allowed
0225         edge_iterator  operator--(int);
0226     private:
0227         const GenVertex*  m_vertex;
0228         IteratorRange  m_range;
0229         std::vector<HepMC::GenParticle*>::const_iterator m_set_iter;
0230         bool           m_is_inparticle_iter;
0231         bool           m_is_past_end;
0232     };
0233     friend class edge_iterator;
0234     /// size
0235     int              edges_size( IteratorRange range = family ) const;
0236     /// begin range
0237     edge_iterator    edges_begin( IteratorRange range = family) const;
0238     /// end range
0239     edge_iterator    edges_end( IteratorRange /* dummy_range */ ) const;
0240 
0241     public:
0242     ///////////////////////////////
0243     // vertex_iterator           //
0244     ///////////////////////////////
0245 
0246     //!  vertex iterator
0247 
0248     /// \class  vertex_iterator
0249     /// Iterates over all vertices connected via a graph to this vertex.
0250     /// this is made friend to that it can access protected edge
0251     /// iterator the range can be IteratorRange= ( parents, children, 
0252     /// family, ancestors, descendants, relatives )
0253     /// example for range=descendants the iterator 
0254     /// will return all vertices
0255     /// which are children (connected by an outgoing particle edge),
0256     /// grandchildren, great-grandchildren, etc. of this vertex
0257     /// In all cases the iterator always returns this vertex
0258     /// (returned last).
0259     /// The algorithm is accomplished by converting the graph to a tree
0260     /// (by "chopping" the edges connecting to an already visited
0261     /// vertex) and returning the vertices in POST ORDER traversal.
0262     ///
0263     class vertex_iterator :
0264       public std::iterator<std::forward_iterator_tag,HepMC::GenVertex*,ptrdiff_t>{
0265     public:
0266         vertex_iterator();
0267         /// used to set limits on the iteration
0268         vertex_iterator( GenVertex& vtx_root, IteratorRange range );
0269         /// next constructor is intended for internal use only
0270         vertex_iterator( GenVertex& vtx_root, IteratorRange range,
0271                  std::set<const HepMC::GenVertex*>& visited_vertices );
0272             /// copy
0273         vertex_iterator( const vertex_iterator& v_iter );
0274         virtual             ~vertex_iterator();
0275         /// make a copy
0276         vertex_iterator&    operator=( const vertex_iterator& );
0277         /// return a pointer to a vertex
0278         GenVertex*          operator*(void) const;
0279         /// Pre-fix increment 
0280         vertex_iterator&    operator++(void);  //Pre-fix increment 
0281         /// Post-fix increment
0282         vertex_iterator     operator++(int);   //Post-fix increment
0283         /// equality
0284         bool                operator==( const vertex_iterator& ) const;
0285         /// inequality
0286         bool                operator!=( const vertex_iterator& ) const;
0287         /// vertex that this iterator begins from
0288         GenVertex*          vertex_root() const;
0289         /// iterator range
0290         IteratorRange       range() const;
0291         /// intended for internal use only.
0292         void                copy_with_own_set( const vertex_iterator& 
0293                            v_iter,
0294                            std::set<const HepMC::GenVertex*>& 
0295                            visited_vertices );
0296 
0297     protected:                  // intended for internal use only
0298         /// non-null if recursive iter. created
0299         GenVertex* follow_edge_(); 
0300         /// copy recursive iterator
0301         void    copy_recursive_iterator_( const vertex_iterator* 
0302                           recursive_v_iter );
0303     private:
0304         /// Pre-fix increment -- is not allowed 
0305         vertex_iterator&    operator--(void);
0306         /// Post-fix increment -- is not allowed 
0307         vertex_iterator     operator--(int);
0308 
0309     private:
0310         GenVertex*       m_vertex;   // the vertex associated to this iter
0311         IteratorRange    m_range;
0312         std::set<const HepMC::GenVertex*>* m_visited_vertices;
0313         bool             m_it_owns_set;  // true if it is responsible for 
0314                                          // deleting the visited vertex set
0315         edge_iterator    m_edge; // particle edge pointing to return vtx
0316         vertex_iterator* m_recursive_iterator;
0317     };  
0318     friend class vertex_iterator;
0319     /// begin vertex range
0320     vertex_iterator     vertices_begin( IteratorRange range = relatives );
0321     /// end vertex range
0322     vertex_iterator     vertices_end( IteratorRange /* dummy_range */ );
0323  
0324     public:
0325     ///////////////////////////////
0326     // particle_iterator         //
0327     ///////////////////////////////
0328 
0329     //!  particle iterator
0330 
0331     /// \class  particle_iterator
0332     /// Iterates over all particles connected via a graph.
0333     /// by iterating through all vertices in the m_range. For each
0334     /// vertex it returns orphaned parent particles 
0335     /// (i.e. parents without production vertices) 
0336     /// then children ... in this way each particle is associated
0337     /// to exactly one vertex and so it is returned exactly once.
0338     /// Is made friend so that it can access protected edge iterator
0339     class particle_iterator :
0340       public std::iterator<std::forward_iterator_tag,GenParticle*,ptrdiff_t>{
0341     public:
0342         particle_iterator();
0343         /// used to set limits on the iteration
0344         particle_iterator( GenVertex& vertex_root, IteratorRange range );
0345         /// copy
0346         particle_iterator( const particle_iterator& );
0347         virtual             ~particle_iterator();
0348         /// make a copy
0349         particle_iterator&  operator=( const particle_iterator& );
0350         /// return a pointer to a particle
0351         GenParticle*        operator*(void) const;
0352         /// Pre-fix increment 
0353         particle_iterator&  operator++(void); 
0354         /// Post-fix increment
0355         particle_iterator   operator++(int); 
0356         /// equality
0357         bool                operator==( const particle_iterator& ) const;
0358         /// inequality
0359         bool                operator!=( const particle_iterator& ) const;
0360     protected:
0361         GenParticle*        advance_to_first_(); //!< "first" particle
0362     private:
0363         vertex_iterator     m_vertex_iterator;
0364         edge_iterator       m_edge;     // points to the return
0365     };
0366     friend class particle_iterator;
0367     /// begin particle range
0368     particle_iterator       particles_begin( IteratorRange range 
0369                          = relatives );
0370     /// end particle range
0371     particle_iterator       particles_end( IteratorRange 
0372                            /* dummy_range */ );
0373 
0374     ////////////////////////////////////////////////
0375     protected: 
0376         /// for internal use only
0377     void delete_adopted_particles();
0378     /// for internal use only - remove particle from incoming list
0379     void remove_particle_in( GenParticle* );
0380     /// for internal use only - remove particle from outgoing list
0381     void remove_particle_out( GenParticle* );
0382     /// scale the position vector
0383         /// this method is only for use by GenEvent
0384     void convert_position( const double& );
0385 
0386     private: // GenVertex data members
0387     FourVector              m_position;      //4-vec of vertex [mm]
0388     std::vector<HepMC::GenParticle*>  m_particles_in;  //all incoming particles
0389     std::vector<HepMC::GenParticle*>  m_particles_out; //all outgoing particles
0390     int                  m_id;
0391     WeightContainer      m_weights;       // weights for this vtx
0392     GenEvent*            m_event;
0393     int                  m_barcode;   // unique identifier in the event
0394 
0395     //static unsigned int  s_counter;
0396     };  
0397 
0398     ////////////////////////////
0399     // INLINES access methods //
0400     ////////////////////////////
0401 
0402     inline GenVertex::operator HepMC::FourVector() const { return position(); }
0403 
0404     inline GenVertex::operator HepMC::ThreeVector() const { return point3d(); }
0405 
0406     inline const FourVector & GenVertex::position() const { return m_position; }
0407 
0408     inline GenEvent* GenVertex::parent_event() const { return m_event; }
0409 
0410     inline ThreeVector GenVertex::point3d() const { 
0411     return ThreeVector(m_position.x(),m_position.y(),m_position.z()); 
0412     }
0413 
0414     inline int GenVertex::id() const { return m_id; }
0415 
0416     inline int  GenVertex::barcode() const { return m_barcode; }
0417     inline void GenVertex::set_barcode_( int bc ) { m_barcode = bc; }
0418 
0419     inline WeightContainer& GenVertex::weights() { return m_weights; }
0420 
0421     inline const WeightContainer& GenVertex::weights() const 
0422     { return m_weights; }
0423 
0424     inline void GenVertex::set_position( const FourVector& pos ) {
0425     m_position = pos;
0426     }
0427 
0428     inline void GenVertex::set_id( int pid ) { m_id = pid; }
0429 
0430     //////////////
0431     // INLINES  //
0432     //////////////
0433 
0434     inline GenVertex::particles_in_const_iterator 
0435     GenVertex::particles_in_const_begin() const { 
0436     return m_particles_in.begin(); 
0437     }
0438 
0439     inline GenVertex::particles_in_const_iterator 
0440     GenVertex::particles_in_const_end() const { 
0441     return m_particles_in.end(); 
0442     }
0443 
0444     inline GenVertex::particles_out_const_iterator 
0445     GenVertex::particles_out_const_begin() const { 
0446     return m_particles_out.begin();
0447     }
0448 
0449     inline GenVertex::particles_out_const_iterator 
0450     GenVertex::particles_out_const_end() const {    
0451     return m_particles_out.end(); 
0452     }
0453 
0454     inline int GenVertex::particles_in_size() const {
0455     return m_particles_in.size(); 
0456     }
0457 
0458     inline int GenVertex::particles_out_size() const {
0459     return m_particles_out.size(); 
0460     }   
0461 
0462     inline bool GenVertex::edge_iterator::operator==( 
0463     const edge_iterator& a ) const { 
0464     return **this == *a; 
0465     }
0466 
0467     inline bool GenVertex::edge_iterator::operator!=(
0468     const edge_iterator& a ) const { 
0469     return !(**this == *a); 
0470     }
0471 
0472     inline const GenVertex* GenVertex::edge_iterator::vertex_root() const {
0473     return m_vertex;
0474     }
0475 
0476     inline GenVertex::edge_iterator GenVertex::edges_begin( IteratorRange 
0477                               range ) const {
0478     return GenVertex::edge_iterator(*this, range);
0479     }
0480 
0481     inline GenVertex::edge_iterator GenVertex::edges_end( IteratorRange 
0482                             /* dummy_range */ ) const {
0483     return GenVertex::edge_iterator();
0484     }
0485 
0486     inline bool GenVertex::vertex_iterator::operator==( 
0487     const vertex_iterator& a ) const {
0488     return **this == *a; 
0489     }
0490 
0491     inline bool GenVertex::vertex_iterator::operator!=( 
0492     const vertex_iterator& a ) const {
0493     return !(**this == *a); 
0494     }
0495 
0496     inline GenVertex* GenVertex::vertex_iterator::vertex_root() const {
0497     return m_vertex; 
0498     }
0499 
0500     inline IteratorRange GenVertex::vertex_iterator::range() const {
0501     return m_range; 
0502     }
0503 
0504     inline GenVertex::vertex_iterator GenVertex::vertices_begin( 
0505     IteratorRange range ){
0506     // this is not const because the it could return itself
0507     return vertex_iterator( *this, range );
0508     }
0509 
0510     inline GenVertex::vertex_iterator GenVertex::vertices_end( 
0511     IteratorRange /* dummy_range */ ) {
0512     return vertex_iterator();
0513     }
0514 
0515     inline bool GenVertex::particle_iterator::operator==( 
0516     const particle_iterator& a ) const {
0517     return **this == *a; 
0518     }
0519 
0520     inline bool GenVertex::particle_iterator::operator!=( 
0521     const particle_iterator& a ) const {
0522     return !(**this == *a); 
0523     }
0524 
0525     inline GenVertex::particle_iterator GenVertex::particles_begin( 
0526     IteratorRange range ) {
0527     return particle_iterator( *this, range );
0528     }
0529 
0530     inline GenVertex::particle_iterator GenVertex::particles_end(
0531     IteratorRange /* dummy_range */ ){
0532     return particle_iterator();
0533     }
0534 
0535 } // HepMC
0536 
0537 #endif  // HEPMC_GEN_VERTEX_H
0538 //--------------------------------------------------------------------------
0539 
0540 
0541 
0542