hepmc - Blame information for rev 274

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