hepmc - Blame information for rev 43

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