Subversion Repositories hepmc

Rev

Rev 264 | Rev 282 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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