SSO Logout

Subversion Repositories hepmc

Rev

Rev 2 | Rev 22 | 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_EVENT_H
3
#define HEPMC_GEN_EVENT_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
// Event record for MC generators (for use at any stage of generation)
11
//////////////////////////////////////////////////////////////////////////
12
//
13
// This class is intended as both a "container class" ( to store a MC
14
//  event for interface between MC generators and detector simulation )
15
//  and also as a "work in progress class" ( that could be used inside
16
//  a generator and modified as the event is built ).
17
//
18
// Iterators are provided which allow the user to easily obtain a
19
//  list of particles or vertices in an event --- this list can be filled
20
//  subject to some sort of selection criteria. Examples are given below
21
//  ( see HepMC::copy_if and std::copy )
22
 
23
namespace HepMC {
24
    // To create a list from an iterator, use: (i.e. for a list of particles);
25
    // #include <algorithm>
26
    //     list<GenParticle*> thelist;
27
    //     copy( evt->particles_begin(), evt->particles_end(), 
28
    //           back_inserter(thelist) );
29
    // to create a list subject to a condition (predicate) use:
30
    //     list<GenParticle*> thelist;
31
    //     HepMC::copy_if( evt->particles_begin(), evt->particles_end(), 
32
    //                     back_inserter(thelist), is_photon() );
33
    // where is_photon() is a predicate like:
34
    //     class is_photon {
35
    //       public:
36
    //         bool operator() ( const GenParticle* p ) {
37
    //             if ( p && p->pdg_id() == 22 ) return 1;
38
    //             return 0;
39
    //         }
40
    //     };
41
    // which the user defines herself.
42
    template <class InputIterator, class OutputIterator, class Predicate>
43
    void copy_if( InputIterator first, InputIterator last, OutputIterator out,
44
                  Predicate pred ) {
45
        for ( ; first != last; ++first ) { if ( pred(*first) ) out = *first; }
46
    }
47
} // HepMC
48
 
49
// Since a container of all vertices in the event is maintained, the time
50
//  required to loop over all vertices (or particles) is very fast -- and 
51
//  the user does not gain much by first making his own list.
52
//  (this is not true for the GenVertex:: versions of these iterators, which
53
//   allow you to specify the vertex starting point and range)
54
 
55
// Data Members:
56
// signal_process_id()   The integer ID that uniquely specifies this signal
57
//                       process, i.e. MSUB in Pythia. It is necessary to
58
//                       package this with each event rather than with the run
59
//                       because many processes may be generated within one
60
//                       run.
61
// event_number()        Strictly speaking we cannot think of any reason that
62
//                       an event would need to know its own event number, it
63
//                       is more likely something that would be assigned by
64
//                       a database. It is included anyway (tradition?) since
65
//                       we expect it may be useful for debugging. It can
66
//                       be reset later by a database.
67
// signal_process_vertex() pointer to the vertex containing the signal process
68
// weights()             Vector of doubles which specify th weight of the evnt,
69
//                       the first entry will be the "event weight" used for
70
//                       hit and miss etc., but a general vector is used to
71
//                       allow for reweighting etc. We envision a list of
72
//                       WeightTags to be included with a run class which
73
//                       would specify the meaning of the Weights .
74
// random_states()       Vector of integers which specify the random number 
75
//                       generator's state for this event. It is left to the
76
//                       generator to make use of this. We envision a vector of
77
//                       RndmStatesTags to be included with a run class which
78
//                       would specify the meaning of the random_states.
79
//
80
///////////////////////
81
// Memory allocation //
82
///////////////////////
83
// -When a vertex (particle) is added to a event (vertex), it is "adopted" 
84
//  and becomes the responsibility of the event (vertex) to delete that 
85
//  particle. 
86
// -objects responsible for deleting memory:
87
//    -events delete included vertices
88
//    -each vertex deletes its outgoing particles which do not have decay
89
//     vertices
90
//    -each vertex deletes its incoming particles which do not
91
//     have creation vertices 
92
//
93
////////////////////////
94
// About the Barcodes //
95
////////////////////////
96
// - each vertex or particle has a barcode, which is just an integer which
97
//   uniquely identifies it inside the event (i.e. there is a one to one
98
//   mapping between particle memory addresses and particle barcodes... and 
99
//   the same applied for vertices)
100
// - The value of a barcode has NO MEANING and NO ORDER!
101
//   For the user's convenience, when an event is read in via an IO_method
102
//   from an indexed list (like the HEPEVT common block), then the index will
103
//   become the barcode for that particle.
104
// - particle barcodes are always positive integers
105
//   vertex barcodes are always negative integers
106
//   The barcodes are chosen and set automatically when a vertex or particle
107
//   comes under the ownership of an event (i.e. it is contained in an event).
108
// - You can tell when a particle or vertex is owned, because its 
109
//   parent_event() return value will return a pointer to the event which owns
110
//   it (or null if its an orphan).
111
// 
112
 
113
#include "HepMC/GenVertex.h"
114
#include "HepMC/GenParticle.h"
115
#include "HepMC/WeightContainer.h"
14 garren 116
#include "HepMC/HeavyIon.h"
2 garren 117
#include <map>
118
#include <vector>
119
#include <algorithm>
120
#include <iostream>
121
 
122
namespace HepMC {
123
 
124
    class GenEvent {
125
        friend class GenParticle;
126
        friend class GenVertex;  
127
    public:
128
        GenEvent( int signal_process_id = 0, int event_number = 0,
129
                  GenVertex* signal_vertex = 0,
130
                  const WeightContainer& weights = std::vector<double>(),
131
                  const std::vector<long int>& randomstates
132
                  = std::vector<long int>() );
133
        GenEvent( const GenEvent& inevent );          // deep copy
134
        GenEvent& operator=( const GenEvent& inevent ); // deep.
135
        virtual ~GenEvent(); //deletes all vertices/particles in this evt
136
 
137
        void print( std::ostream& ostr = std::cout ) const; // dumps to ostr
138
 
139
        GenParticle* barcode_to_particle( int barCode ) const;
140
        GenVertex*   barcode_to_vertex(   int barCode ) const;
141
 
142
        ////////////////////
143
        // access methods //
144
        ////////////////////
145
 
146
        int signal_process_id() const;
147
        int event_number() const;
148
        double event_scale() const;
149
        double alphaQCD() const;
150
        double alphaQED() const;
151
        GenVertex* signal_process_vertex() const;
152
 
153
        // direct access to the weights container is allowed. 
154
        // Thus you can user myevt.weights()[2];
155
        // to access element 2 of the weights.
156
        // or use myevt.weights().push_back( mywgt ); to add an element.
157
        // and you can set the weights with myevt.weights() = myvector;
158
        WeightContainer&        weights();
159
        const WeightContainer&  weights() const;
160
 
14 garren 161
        HeavyIon*            heavy_ion() const;
162
 
2 garren 163
        std::vector<long int> random_states() const;
164
 
165
        void set_signal_process_id( int id );
166
        void set_event_number( int eventno );
167
        void set_event_scale( double scale );
168
        void set_alphaQCD( double a );
169
        void set_alphaQED( double a );
170
        void set_signal_process_vertex( GenVertex* );
171
        void set_random_states( const std::vector<long int>& randomstates );
172
 
14 garren 173
        void set_heavy_ion( HeavyIon* ion );
174
 
2 garren 175
        int     particles_size() const;
176
        bool    particles_empty() const;
177
        int     vertices_size() const;
178
        bool    vertices_empty() const;
179
 
180
        bool    add_vertex( GenVertex* vtx );    // adds to evt and adopts
181
        bool    remove_vertex( GenVertex* vtx ); // erases vtx from evt, 
182
 
183
    public:
184
        ///////////////////////////////
185
        // vertex_iterators          //
186
        ///////////////////////////////
187
        // Note:  the XXX_iterator is "resolvable" as XXX_const_iterator, but 
188
        //  not the reverse, which is consistent with STL, 
189
        //  see Musser, Derge, Saini 2ndEd. p. 69,70.
190
        class vertex_const_iterator :
191
          public std::iterator<std::forward_iterator_tag,GenVertex*,ptrdiff_t>{
192
            // Iterates over all vertices in this event
193
        public:
194
            vertex_const_iterator(
195
                const
196
                std::map<int,GenVertex*,std::greater<int> >::const_iterator& i)
197
                : m_map_iterator(i) {}
198
            vertex_const_iterator() {}
199
            vertex_const_iterator( const vertex_const_iterator& i )
200
                { *this = i; }
201
            virtual ~vertex_const_iterator() {}
202
            vertex_const_iterator&  operator=( const vertex_const_iterator& i )
203
                { m_map_iterator = i.m_map_iterator; return *this; }
204
            GenVertex* operator*(void) const { return m_map_iterator->second; }
205
            vertex_const_iterator&  operator++(void)  //Pre-fix increment 
206
                { ++m_map_iterator; return *this; }
207
            vertex_const_iterator   operator++(int)   //Post-fix increment
208
                { vertex_const_iterator out(*this); ++(*this); return out; }
209
            bool  operator==( const vertex_const_iterator& a ) const
210
                { return m_map_iterator == a.m_map_iterator; }
211
            bool  operator!=( const vertex_const_iterator& a ) const
212
                { return !(m_map_iterator == a.m_map_iterator); }
213
        protected:
214
            std::map<int,GenVertex*,std::greater<int> >::const_iterator
215
                                                                m_map_iterator;
216
        };
217
        friend class vertex_const_iterator;
218
        vertex_const_iterator      vertices_begin() const
219
            { return GenEvent::vertex_const_iterator(
220
                m_vertex_barcodes.begin() ); }
221
        vertex_const_iterator      vertices_end() const
222
            { return GenEvent::vertex_const_iterator(
223
                m_vertex_barcodes.end() ); }
224
 
225
        class vertex_iterator :
226
          public std::iterator<std::forward_iterator_tag,GenVertex*,ptrdiff_t>{
227
            // Iterates over all vertices in this event
228
        public:
229
            vertex_iterator(
230
                const
231
                std::map<int,GenVertex*,std::greater<int> >::iterator& i )
232
                : m_map_iterator( i ) {}
233
            vertex_iterator() {}
234
            vertex_iterator( const vertex_iterator& i ) { *this = i; }
235
            virtual ~vertex_iterator() {}
236
            vertex_iterator&  operator=( const vertex_iterator& i ) {
237
                m_map_iterator = i.m_map_iterator;
238
                return *this;
239
            }
240
            operator vertex_const_iterator() const
241
                { return vertex_const_iterator(m_map_iterator); }
242
            GenVertex*        operator*(void) const
243
                { return m_map_iterator->second; }
244
            vertex_iterator&  operator++(void)  //Pre-fix increment 
245
                { ++m_map_iterator;     return *this; }
246
            vertex_iterator   operator++(int)   //Post-fix increment
247
                { vertex_iterator out(*this); ++(*this); return out; }
248
            bool              operator==( const vertex_iterator& a ) const
249
                { return m_map_iterator == a.m_map_iterator; }
250
            bool              operator!=( const vertex_iterator& a ) const
251
                { return !(m_map_iterator == a.m_map_iterator); }
252
        protected:
253
            std::map<int,GenVertex*,std::greater<int> >::iterator
254
                                                               m_map_iterator;
255
        };
256
        friend class vertex_iterator;
257
        vertex_iterator            vertices_begin()
258
            { return GenEvent::vertex_iterator(
259
                m_vertex_barcodes.begin() ); }
260
        vertex_iterator            vertices_end()
261
            { return GenEvent::vertex_iterator(
262
                m_vertex_barcodes.end() ); }
263
 
264
    public:
265
        ///////////////////////////////
266
        // particle_iterator         //
267
        ///////////////////////////////
268
        // Example of iterating over all particles in the event:
269
        //      for ( GenEvent::particle_const_iterator p = particles_begin();
270
        //            p != particles_end(); ++p ) {
271
        //         (*p)->print();
272
        //      }
273
        //
274
        class particle_const_iterator :
275
          public std::iterator<std::forward_iterator_tag,GenParticle*,ptrdiff_t>{
276
            // Iterates over all vertices in this event
277
        public:
278
            particle_const_iterator(
279
                const std::map<int,GenParticle*>::const_iterator& i )
280
                : m_map_iterator(i) {}
281
            particle_const_iterator() {}
282
            particle_const_iterator( const particle_const_iterator& i )
283
                { *this = i; }
284
            virtual ~particle_const_iterator() {}
285
            particle_const_iterator& operator=(
286
                const particle_const_iterator& i )
287
                { m_map_iterator = i.m_map_iterator; return *this; }
288
            GenParticle*        operator*(void) const
289
                { return m_map_iterator->second; }
290
            particle_const_iterator&  operator++(void)  //Pre-fix increment 
291
                { ++m_map_iterator; return *this; }
292
            particle_const_iterator   operator++(int)   //Post-fix increment
293
                { particle_const_iterator out(*this); ++(*this); return out; }
294
            bool  operator==( const particle_const_iterator& a ) const
295
                { return m_map_iterator == a.m_map_iterator; }
296
            bool  operator!=( const particle_const_iterator& a ) const
297
                { return !(m_map_iterator == a.m_map_iterator); }
298
        protected:
299
            std::map<int,GenParticle*>::const_iterator m_map_iterator;
300
        };     
301
        friend class particle_const_iterator;
302
        particle_const_iterator      particles_begin() const
303
            { return GenEvent::particle_const_iterator(
304
                m_particle_barcodes.begin() ); }
305
        particle_const_iterator      particles_end() const
306
            { return GenEvent::particle_const_iterator(
307
                m_particle_barcodes.end() ); }
308
 
309
        class particle_iterator :
310
          public std::iterator<std::forward_iterator_tag,GenParticle*,ptrdiff_t>{
311
            // Iterates over all vertices in this event
312
        public:
313
            particle_iterator( const std::map<int,GenParticle*>::iterator& i )
314
                : m_map_iterator( i ) {}
315
            particle_iterator() {}
316
            particle_iterator( const particle_iterator& i ) { *this = i; }
317
            virtual ~particle_iterator() {}
318
            particle_iterator&  operator=( const particle_iterator& i ) {
319
                m_map_iterator = i.m_map_iterator;
320
                return *this;
321
            }
322
            operator particle_const_iterator() const
323
                { return particle_const_iterator(m_map_iterator); }
324
            GenParticle*        operator*(void) const
325
                { return m_map_iterator->second; }
326
            particle_iterator&  operator++(void)  //Pre-fix increment 
327
                { ++m_map_iterator;     return *this; }
328
            particle_iterator   operator++(int)   //Post-fix increment
329
                { particle_iterator out(*this); ++(*this); return out; }
330
            bool              operator==( const particle_iterator& a ) const
331
                { return m_map_iterator == a.m_map_iterator; }
332
            bool              operator!=( const particle_iterator& a ) const
333
                { return !(m_map_iterator == a.m_map_iterator); }
334
        protected:
335
            std::map<int,GenParticle*>::iterator m_map_iterator;
336
        };
337
        friend class particle_iterator;
338
        particle_iterator particles_begin()
339
            { return GenEvent::particle_iterator(
340
                m_particle_barcodes.begin() ); }
341
        particle_iterator particles_end()
342
            { return GenEvent::particle_iterator(
343
                m_particle_barcodes.end() ); }
344
 
345
        ////////////////////////////////////////////////
346
    protected:
347
        //
348
        // Following methods intended for use by GenParticle/Vertex classes:
349
        // In general there is no reason they should be used elsewhere.
350
        bool         set_barcode( GenParticle* p, int suggested_barcode =0 );
351
        bool         set_barcode( GenVertex*   v, int suggested_barcode =0 );
352
        void         remove_barcode( GenParticle* p );
353
        void         remove_barcode( GenVertex*   v );
354
 
355
        static unsigned int counter(); //num GenEvent objects in memory
356
        void delete_all_vertices();
357
 
358
    private: // data members
359
        int                   m_signal_process_id;
360
        int                   m_event_number;  
361
        double                m_event_scale;// energy scale, see hep-ph/0109068
362
        double                m_alphaQCD;   // QCD coupling, see hep-ph/0109068
363
        double                m_alphaQED;   // QED coupling, see hep-ph/0109068
364
        GenVertex*            m_signal_process_vertex;
365
        WeightContainer       m_weights; // weights for this event first weight
366
                                         // is used by default for hit and miss
367
        std::vector<long int> m_random_states; // container of rndm num 
368
                                               // generator states
369
 
370
        std::map< int,GenVertex*,std::greater<int> >   m_vertex_barcodes;
371
        std::map< int,GenParticle*,std::less<int> >    m_particle_barcodes;
14 garren 372
        HeavyIon*        m_heavy_ion;         // undefined by default
2 garren 373
 
374
        static unsigned int   s_counter;
375
    };
376
 
377
    ///////////////////////////
378
    // INLINE Access Methods //
379
    ///////////////////////////
380
 
381
    inline int GenEvent::signal_process_id() const
382
    { return m_signal_process_id; }
383
 
384
    inline int GenEvent::event_number() const { return m_event_number; }
385
 
386
    inline double GenEvent::event_scale() const { return m_event_scale; }
387
 
388
    inline double GenEvent::alphaQCD() const { return m_alphaQCD; }
389
 
390
    inline double GenEvent::alphaQED() const { return m_alphaQED; }
391
 
392
    inline GenVertex* GenEvent::signal_process_vertex() const {
393
        // returns a (mutable) pointer to the signal process vertex
394
        return m_signal_process_vertex;
395
    }  
396
 
397
    inline WeightContainer& GenEvent::weights() { return m_weights; }
398
 
399
    inline const WeightContainer& GenEvent::weights() const
400
    { return m_weights; }
401
 
14 garren 402
    inline HeavyIon* GenEvent::heavy_ion() const
403
    { return m_heavy_ion; }
404
 
2 garren 405
    inline std::vector<long int> GenEvent::random_states() const
406
    { return m_random_states; }
407
 
408
    inline void GenEvent::set_signal_process_id( int id )
409
    { m_signal_process_id = id; }
410
 
411
    inline void GenEvent::set_event_number( int eventno )
412
    { m_event_number = eventno; }
413
 
414
 
415
    inline void GenEvent::set_event_scale( double sc ) { m_event_scale = sc; }
416
 
417
    inline void GenEvent::set_alphaQCD( double a ) { m_alphaQCD = a; }
418
 
419
    inline void GenEvent::set_alphaQED( double a ) { m_alphaQED = a; }
420
 
421
    inline void GenEvent::set_signal_process_vertex( GenVertex* vtx ) {
422
        m_signal_process_vertex = vtx;
423
        if ( m_signal_process_vertex ) add_vertex( m_signal_process_vertex );
424
    }
425
 
14 garren 426
    inline void GenEvent::set_heavy_ion( HeavyIon* ion )
427
    { m_heavy_ion = ion; }
428
 
2 garren 429
    inline void GenEvent::set_random_states( const std::vector<long int>&
430
                                             randomstates )
431
    { m_random_states = randomstates; }
432
 
433
    inline void GenEvent::remove_barcode( GenParticle* p )
434
    { m_particle_barcodes.erase( p->barcode() ); }
435
 
436
    inline void GenEvent::remove_barcode( GenVertex* v )
437
    { m_vertex_barcodes.erase( v->barcode() ); }
438
 
439
    inline GenParticle* GenEvent::barcode_to_particle( int barCode ) const
440
    {
441
        std::map<int,GenParticle*>::const_iterator i
442
            = m_particle_barcodes.find(barCode);
443
        return ( i != m_particle_barcodes.end() ) ? (*i).second : 0;
444
    }
445
 
446
    inline GenVertex* GenEvent::barcode_to_vertex( int barCode ) const
447
    {
448
        std::map<int,GenVertex*,std::greater<int> >::const_iterator i
449
            = m_vertex_barcodes.find(barCode);
450
        return ( i != m_vertex_barcodes.end() ) ? (*i).second : 0;
451
    }
452
 
453
    inline int GenEvent::particles_size() const {
454
        return (int)m_particle_barcodes.size();
455
    }
456
    inline bool GenEvent::particles_empty() const {
457
        return (bool)m_particle_barcodes.empty();
458
    }
459
    inline int GenEvent::vertices_size() const {
460
        return (int)m_vertex_barcodes.size();
461
    }
462
    inline bool GenEvent::vertices_empty() const {
463
        return (bool)m_vertex_barcodes.empty();
464
    }
465
 
466
} // HepMC
467
 
468
#endif  // HEPMC_GEN_EVENT_H
469
 
470
//--------------------------------------------------------------------------
471
 
472