Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //--------------------------------------------------------------------------
0002 #ifndef HEPMC_GEN_EVENT_H
0003 #define HEPMC_GEN_EVENT_H
0004 
0005 //////////////////////////////////////////////////////////////////////////
0006 // Matt.Dobbs@Cern.CH, September 1999, refer to:
0007 // M. Dobbs and J.B. Hansen, "The HepMC C++ Monte Carlo Event Record for
0008 // High Energy Physics", Computer Physics Communications (to be published).
0009 //
0010 // Event record for MC generators (for use at any stage of generation)
0011 //////////////////////////////////////////////////////////////////////////
0012 //
0013 // This class is intended as both a "container class" ( to store a MC
0014 //  event for interface between MC generators and detector simulation )
0015 //  and also as a "work in progress class" ( that could be used inside
0016 //  a generator and modified as the event is built ).
0017 //
0018 // Iterators are provided which allow the user to easily obtain a
0019 //  list of particles or vertices in an event --- this list can be filled
0020 //  subject to some sort of selection criteria. Examples are given below
0021 //  ( see HepMC::copy_if and std::copy )
0022 
0023 ///
0024 /// \namespace HepMC
0025 /// All classes in the HepMC packages are in the HepMC namespace 
0026 ///
0027 namespace HepMC {
0028 
0029     // To create a list from an iterator, use: (i.e. for a list of particles);
0030     // #include <algorithm>
0031     //     list<GenParticle*> thelist;
0032     //     copy( evt->particles_begin(), evt->particles_end(), 
0033     //           back_inserter(thelist) );
0034     // to create a list subject to a condition (predicate) use:
0035     //     list<GenParticle*> thelist;
0036     //     HepMC::copy_if( evt->particles_begin(), evt->particles_end(), 
0037     //                     back_inserter(thelist), is_photon() );
0038     // where is_photon() is a predicate like:
0039     //     class is_photon {
0040     //       public:
0041     //         bool operator() ( GenParticle const * p ) {
0042     //             if ( p && p->pdg_id() == 22 ) return true;
0043     //             return false;
0044     //         }
0045     //     };
0046     // which the user defines herself.
0047 
0048     /// define the type of iterator to use
0049     template <class InputIterator, class OutputIterator, class Predicate>
0050     void copy_if( InputIterator first, InputIterator last, OutputIterator out,
0051           Predicate pred ) {
0052     for ( ; first != last; ++first ) { if ( pred(*first) ) out = *first; }
0053     }
0054 } // HepMC
0055 
0056 // Since a container of all vertices in the event is maintained, the time
0057 //  required to loop over all vertices (or particles) is very fast -- and 
0058 //  the user does not gain much by first making his own list.
0059 //  (this is not true for the GenVertex:: versions of these iterators, which
0060 //   allow you to specify the vertex starting point and range)
0061 
0062 // Data Members:
0063 // signal_process_id()   The integer ID that uniquely specifies this signal
0064 //                       process, i.e. MSUB in Pythia. It is necessary to
0065 //                       package this with each event rather than with the run
0066 //                       because many processes may be generated within one
0067 //                       run.
0068 // event_number()        Strictly speaking we cannot think of any reason that
0069 //                       an event would need to know its own event number, it
0070 //                       is more likely something that would be assigned by
0071 //                       a database. It is included anyway (tradition?) since
0072 //                       we expect it may be useful for debugging. It can
0073 //                       be reset later by a database.
0074 // mpi()                 The number of multi parton interactions in the event.
0075 //                       This is NOT beam pileup.  Set to -1 by default.
0076 // beam_particles()      A pair of pointers to the incoming beam particles.
0077 // signal_process_vertex() pointer to the vertex containing the signal process
0078 // weights()             Vector of doubles which specify th weight of the evnt,
0079 //                       the first entry will be the "event weight" used for
0080 //                       hit and miss etc., but a general vector is used to
0081 //                       allow for reweighting etc. We envision a list of
0082 //                       WeightTags to be included with a run class which
0083 //                       would specify the meaning of the Weights .
0084 // random_states()       Vector of integers which specify the random number 
0085 //                       generator's state for this event. It is left to the
0086 //                       generator to make use of this. We envision a vector of
0087 //                       RndmStatesTags to be included with a run class which
0088 //                       would specify the meaning of the random_states.
0089 //
0090 ///////////////////////
0091 // Memory allocation //
0092 ///////////////////////
0093 // -When a vertex (particle) is added to a event (vertex), it is "adopted" 
0094 //  and becomes the responsibility of the event (vertex) to delete that 
0095 //  particle. 
0096 // -objects responsible for deleting memory:
0097 //    -events delete included vertices
0098 //    -each vertex deletes its outgoing particles which do not have decay
0099 //     vertices
0100 //    -each vertex deletes its incoming particles which do not
0101 //     have creation vertices 
0102 //
0103 ////////////////////////
0104 // About the Barcodes //
0105 ////////////////////////
0106 // - each vertex or particle has a barcode, which is just an integer which
0107 //   uniquely identifies it inside the event (i.e. there is a one to one
0108 //   mapping between particle memory addresses and particle barcodes... and 
0109 //   the same applied for vertices)
0110 // - The value of a barcode has NO MEANING and NO ORDER!
0111 //   For the user's convenience, when an event is read in via an IO_method
0112 //   from an indexed list (like the HEPEVT common block), then the index will
0113 //   become the barcode for that particle.
0114 // - particle barcodes are always positive integers
0115 //   vertex barcodes are always negative integers
0116 //   The barcodes are chosen and set automatically when a vertex or particle
0117 //   comes under the ownership of an event (i.e. it is contained in an event).
0118 // - You can tell when a particle or vertex is owned, because its 
0119 //   parent_event() return value will return a pointer to the event which owns
0120 //   it (or null if its an orphan).
0121 // - Please note that the barcodes are intended for internal use within HepMC 
0122 //   as a unique identifier for the particles and vertices.
0123 //   Using the barcode to encode extra information is an abuse of 
0124 //   the barcode data member and causes confusion among users. 
0125 // 
0126 
0127 #include "HepMC/GenVertex.h"
0128 #include "HepMC/GenParticle.h"
0129 #include "HepMC/WeightContainer.h"
0130 #include "HepMC/GenCrossSection.h"
0131 #include "HepMC/HeavyIon.h"
0132 #include "HepMC/PdfInfo.h"
0133 #include "HepMC/Units.h"
0134 #include "HepMC/HepMCDefs.h"
0135 #include <map>
0136 #include <string>
0137 #include <vector>
0138 #include <algorithm>
0139 #include <iostream>
0140 
0141 namespace HepMC {
0142 
0143     class GenEventVertexRange;
0144     class ConstGenEventVertexRange;
0145     class GenEventParticleRange;
0146     class ConstGenEventParticleRange;
0147 
0148     //! The GenEvent class is the core of HepMC
0149 
0150     ///
0151     /// \class GenEvent 
0152     /// HepMC::GenEvent contains information about generated particles.
0153     /// GenEvent is structured as a set of vertices which contain the particles.
0154     ///
0155     class GenEvent {
0156     friend class GenParticle;
0157     friend class GenVertex;  
0158     public:
0159         /// default constructor creates null pointers to HeavyIon, PdfInfo, and GenCrossSection
0160     GenEvent( int signal_process_id = 0, int event_number = 0,
0161           GenVertex* signal_vertex = 0,
0162           const WeightContainer& weights = std::vector<double>(),
0163           const std::vector<long>& randomstates = std::vector<long>(),
0164           Units::MomentumUnit = Units::default_momentum_unit(), 
0165           Units::LengthUnit = Units::default_length_unit() );
0166         /// explicit constructor that takes HeavyIon and PdfInfo
0167     GenEvent( int signal_process_id, int event_number,
0168           GenVertex* signal_vertex, const WeightContainer& weights,
0169           const std::vector<long>& randomstates,
0170           const HeavyIon& ion, const PdfInfo& pdf,
0171           Units::MomentumUnit = Units::default_momentum_unit(), 
0172           Units::LengthUnit = Units::default_length_unit() );
0173         /// constructor requiring units - all else is default
0174     GenEvent( Units::MomentumUnit, Units::LengthUnit,
0175               int signal_process_id = 0, int event_number = 0,
0176           GenVertex* signal_vertex = 0,
0177           const WeightContainer& weights = std::vector<double>(),
0178           const std::vector<long>& randomstates = std::vector<long>() );
0179         /// explicit constructor with units first that takes HeavyIon and PdfInfo
0180     GenEvent( Units::MomentumUnit, Units::LengthUnit,
0181               int signal_process_id, int event_number,
0182           GenVertex* signal_vertex, const WeightContainer& weights,
0183           const std::vector<long>& randomstates,
0184           const HeavyIon& ion, const PdfInfo& pdf );
0185     GenEvent( const GenEvent& inevent );          //!< deep copy
0186     GenEvent& operator=( const GenEvent& inevent ); //!< make a deep copy
0187     virtual ~GenEvent(); //!<deletes all vertices/particles in this evt
0188 
0189         void swap( GenEvent & other );  //!< swap
0190     
0191     void print( std::ostream& ostr = std::cout ) const; //!< dumps to ostr
0192     void print_version( std::ostream& ostr = std::cout ) const; //!< dumps release version to ostr
0193 
0194         /// assign a barcode to a particle
0195     GenParticle* barcode_to_particle( int barCode ) const;
0196         /// assign a barcode to a vertex
0197     GenVertex*   barcode_to_vertex(   int barCode ) const;
0198 
0199     ////////////////////
0200     // access methods //
0201     ////////////////////
0202 
0203     int signal_process_id() const; //!<  unique signal process id
0204     int event_number() const; //!<  event number
0205     int mpi() const;          //!<  number of multi parton interactions
0206     double event_scale() const; //!< energy scale, see hep-ph/0109068
0207     double alphaQCD() const; //!<  QCD coupling, see hep-ph/0109068
0208     double alphaQED() const; //!<  QED coupling, see hep-ph/0109068
0209         /// pointer to the vertex containing the signal process
0210     GenVertex* signal_process_vertex() const;
0211     /// test to see if we have two valid beam particles
0212     bool valid_beam_particles() const;
0213     /// pair of pointers to the two incoming beam particles
0214     std::pair<HepMC::GenParticle*,HepMC::GenParticle*> beam_particles() const;
0215     /// check GenEvent for validity
0216     /// A GenEvent is presumed valid if it has particles and/or vertices.
0217     bool is_valid() const;
0218 
0219     /// direct access to the weights container is allowed. 
0220     /// Thus you can use myevt.weights()[2];
0221     /// to access element 2 of the weights.
0222     /// or use myevt.weights().push_back( mywgt ); to add an element.
0223     /// and you can set the weights with myevt.weights() = myvector;
0224     WeightContainer&        weights(); //!< direct access to WeightContainer
0225     const WeightContainer&  weights() const; //!< direct access to WeightContainer
0226 
0227     /// access the GenCrossSection container if it exists
0228     GenCrossSection const *     cross_section() const;
0229     GenCrossSection*            cross_section();
0230     /// access the HeavyIon container if it exists
0231     HeavyIon const *         heavy_ion() const;
0232     HeavyIon*                heavy_ion();
0233     /// access the PdfInfo container if it exists
0234     PdfInfo const *          pdf_info() const;
0235     PdfInfo*                 pdf_info();
0236 
0237     /// vector of integers containing information about the random state
0238     const std::vector<long>& random_states() const;
0239 
0240         /// how many particle barcodes exist?
0241     int     particles_size() const;
0242         /// return true if there are no particle barcodes
0243     bool    particles_empty() const;
0244         /// how many vertex barcodes exist?
0245     int     vertices_size() const;
0246         /// return true if there are no vertex barcodes
0247     bool    vertices_empty() const;
0248 
0249     /// Write the unit information to an output stream.  
0250     /// If the output stream is not defined, use std::cout.
0251         void write_units( std::ostream & os = std::cout ) const; 
0252     /// If the cross section is defined,
0253     /// write the cross section information to an output stream.  
0254     /// If the output stream is not defined, use std::cout.
0255     void write_cross_section( std::ostream& ostr = std::cout ) const;
0256 
0257     /// Units used by the GenParticle momentum FourVector.
0258     Units::MomentumUnit momentum_unit() const;
0259     /// Units used by the GenVertex position FourVector.
0260     Units::LengthUnit   length_unit()   const;
0261     
0262     std::ostream& write(std::ostream&);
0263     std::istream& read(std::istream&);
0264 
0265     /////////////////////
0266     // mutator methods //
0267     /////////////////////
0268 
0269     bool    add_vertex( GenVertex* vtx );    //!< adds to evt and adopts
0270     bool    remove_vertex( GenVertex* vtx ); //!< erases vtx from evt
0271     void    clear();                         //!< empties the entire event
0272     
0273     void set_signal_process_id( int id ); //!< set unique signal process id
0274     void set_event_number( int eventno ); //!< set event number
0275     void set_mpi( int  ); //!< set number of multi parton interactions
0276     void set_event_scale( double scale ); //!< set energy scale
0277     void set_alphaQCD( double a ); //!< set QCD coupling
0278     void set_alphaQED( double a ); //!< set QED coupling
0279 
0280         /// set pointer to the vertex containing the signal process
0281     void set_signal_process_vertex( GenVertex* );
0282     /// set incoming beam particles
0283     bool set_beam_particles(GenParticle*, GenParticle*);
0284         /// use a pair of GenParticle*'s to set incoming beam particles
0285     bool set_beam_particles(std::pair<HepMC::GenParticle*,HepMC::GenParticle*> const &);
0286     /// provide random state information
0287     void set_random_states( const std::vector<long>& randomstates );
0288 
0289     /// provide a pointer to the GenCrossSection container
0290     void set_cross_section( const GenCrossSection& );
0291     /// provide a pointer to the HeavyIon container
0292     void set_heavy_ion( const HeavyIon& ion );
0293     /// provide a pointer to the PdfInfo container
0294     void set_pdf_info( const PdfInfo& p );
0295     
0296     /// set the units using enums
0297     /// This method will convert momentum and position data if necessary
0298     void use_units( Units::MomentumUnit, Units::LengthUnit );
0299     /// set the units using strings
0300     /// the string must match the enum exactly
0301     /// This method will convert momentum and position data if necessary
0302         void use_units( std::string&, std::string& );
0303     
0304     /// set the units using enums
0305     /// This method will NOT convert momentum and position data
0306     void define_units( Units::MomentumUnit, Units::LengthUnit );
0307     /// set the units using strings
0308     /// the string must match the enum exactly
0309     /// This method will NOT convert momentum and position data
0310         void define_units( std::string&, std::string& );
0311     
0312     /// vertex range
0313     GenEventVertexRange vertex_range();
0314     /// vertex range
0315     ConstGenEventVertexRange vertex_range() const;
0316     /// particle range
0317     GenEventParticleRange particle_range();
0318     /// particle range
0319     ConstGenEventParticleRange particle_range() const;
0320 
0321     public:
0322     ///////////////////////////////
0323     // vertex_iterators          //
0324     ///////////////////////////////
0325     // Note:  the XXX_iterator is "resolvable" as XXX_const_iterator, but 
0326     //  not the reverse, which is consistent with STL, 
0327     //  see Musser, Derge, Saini 2ndEd. p. 69,70.
0328 
0329     //!  const vertex iterator
0330 
0331     /// \class  vertex_const_iterator
0332     /// HepMC::GenEvent::vertex_const_iterator
0333     /// is used to iterate over all vertices in the event.
0334     class vertex_const_iterator :
0335       public std::iterator<std::forward_iterator_tag,HepMC::GenVertex*,ptrdiff_t>{
0336         // Iterates over all vertices in this event
0337     public:
0338         /// constructor requiring vertex information
0339         vertex_const_iterator(
0340         const 
0341         std::map<int,HepMC::GenVertex*,std::greater<int> >::const_iterator& i)
0342         : m_map_iterator(i) {}
0343         vertex_const_iterator() {}
0344         /// copy constructor
0345         vertex_const_iterator( const vertex_const_iterator& i )
0346         { *this = i; }
0347         virtual ~vertex_const_iterator() {}
0348         /// make a copy
0349         vertex_const_iterator&  operator=( const vertex_const_iterator& i )
0350         { m_map_iterator = i.m_map_iterator; return *this; }
0351         /// return a pointer to a GenVertex
0352         GenVertex* operator*(void) const { return m_map_iterator->second; }
0353         /// Pre-fix increment
0354         vertex_const_iterator&  operator++(void)  //Pre-fix increment 
0355         { ++m_map_iterator; return *this; }
0356         /// Post-fix increment
0357         vertex_const_iterator   operator++(int)   //Post-fix increment
0358         { vertex_const_iterator out(*this); ++(*this); return out; }
0359         /// equality
0360         bool  operator==( const vertex_const_iterator& a ) const
0361         { return m_map_iterator == a.m_map_iterator; }
0362         /// inequality
0363         bool  operator!=( const vertex_const_iterator& a ) const
0364         { return !(m_map_iterator == a.m_map_iterator); }
0365     protected:
0366         /// const iterator to a vertex map
0367         std::map<int,HepMC::GenVertex*,std::greater<int> >::const_iterator 
0368                                                             m_map_iterator;
0369     private:
0370         /// Pre-fix increment -- is not allowed
0371         vertex_const_iterator&  operator--(void);
0372         /// Post-fix increment -- is not allowed
0373         vertex_const_iterator   operator--(int);
0374     };
0375     friend class vertex_const_iterator;
0376     /// begin vertex iteration
0377     vertex_const_iterator      vertices_begin() const
0378         { return GenEvent::vertex_const_iterator( 
0379         m_vertex_barcodes.begin() ); }
0380     /// end vertex iteration
0381     vertex_const_iterator      vertices_end() const
0382         { return GenEvent::vertex_const_iterator(
0383         m_vertex_barcodes.end() ); }
0384 
0385 
0386     //!  non-const vertex iterator
0387 
0388     /// \class  vertex_iterator
0389     /// HepMC::GenEvent::vertex_iterator
0390     /// is used to iterate over all vertices in the event.
0391     class vertex_iterator :
0392       public std::iterator<std::forward_iterator_tag,HepMC::GenVertex*,ptrdiff_t>{
0393         // Iterates over all vertices in this event
0394     public:
0395         /// constructor requiring vertex information
0396         vertex_iterator( 
0397         const 
0398         std::map<int,HepMC::GenVertex*,std::greater<int> >::iterator& i )
0399         : m_map_iterator( i ) {}
0400         vertex_iterator() {}
0401         /// copy constructor
0402         vertex_iterator( const vertex_iterator& i ) { *this = i; }
0403         virtual ~vertex_iterator() {}
0404         /// make a copy
0405         vertex_iterator&  operator=( const vertex_iterator& i ) {
0406         m_map_iterator = i.m_map_iterator;
0407         return *this;
0408         }
0409         /// const vertex iterator
0410         operator vertex_const_iterator() const
0411         { return vertex_const_iterator(m_map_iterator); }
0412         /// return a pointer to a GenVertex
0413         GenVertex*        operator*(void) const
0414         { return m_map_iterator->second; }
0415         /// Pre-fix increment
0416         vertex_iterator&  operator++(void)  //Pre-fix increment 
0417         { ++m_map_iterator;     return *this; }
0418         /// Post-fix increment
0419         vertex_iterator   operator++(int)   //Post-fix increment
0420         { vertex_iterator out(*this); ++(*this); return out; }
0421         /// equality
0422         bool              operator==( const vertex_iterator& a ) const
0423         { return m_map_iterator == a.m_map_iterator; }
0424         /// inequality
0425         bool              operator!=( const vertex_iterator& a ) const
0426         { return !(m_map_iterator == a.m_map_iterator); }
0427     protected:
0428         /// iterator to the vertex map
0429         std::map<int,HepMC::GenVertex*,std::greater<int> >::iterator 
0430                                                            m_map_iterator;
0431     private:
0432         /// Pre-fix increment
0433         vertex_iterator&  operator--(void);
0434         /// Post-fix increment
0435         vertex_iterator   operator--(int);
0436 
0437     };
0438     friend class vertex_iterator;
0439     /// begin vertex iteration
0440     vertex_iterator            vertices_begin() 
0441         { return GenEvent::vertex_iterator( 
0442         m_vertex_barcodes.begin() ); }
0443     /// end vertex iteration
0444         vertex_iterator            vertices_end()
0445         { return GenEvent::vertex_iterator(
0446         m_vertex_barcodes.end() ); }
0447 
0448     public:
0449     ///////////////////////////////
0450     // particle_iterator         //
0451     ///////////////////////////////
0452     // Example of iterating over all particles in the event:
0453     //      for ( GenEvent::particle_const_iterator p = particles_begin();
0454     //            p != particles_end(); ++p ) {
0455     //         (*p)->print();
0456     //      }
0457     //
0458 
0459     //!  const particle iterator
0460 
0461     /// \class  particle_const_iterator
0462     /// HepMC::GenEvent::particle_const_iterator 
0463     /// is used to iterate over all particles in the event.
0464     class particle_const_iterator :
0465       public std::iterator<std::forward_iterator_tag,HepMC::GenParticle*,ptrdiff_t>{
0466         // Iterates over all vertices in this event
0467     public:
0468         /// iterate over particles
0469         particle_const_iterator(
0470         const std::map<int,HepMC::GenParticle*>::const_iterator& i )
0471         : m_map_iterator(i) {}
0472         particle_const_iterator() {}
0473         /// copy constructor
0474         particle_const_iterator( const particle_const_iterator& i )
0475         { *this = i; }
0476         virtual ~particle_const_iterator() {}
0477         /// make a copy
0478         particle_const_iterator& operator=(
0479         const particle_const_iterator& i )
0480         { m_map_iterator = i.m_map_iterator; return *this; }
0481         /// return a pointer to GenParticle
0482         GenParticle*        operator*(void) const
0483         { return m_map_iterator->second; }
0484         /// Pre-fix increment
0485         particle_const_iterator&  operator++(void)  //Pre-fix increment 
0486         { ++m_map_iterator; return *this; }
0487         /// Post-fix increment
0488         particle_const_iterator   operator++(int)   //Post-fix increment
0489         { particle_const_iterator out(*this); ++(*this); return out; }
0490         /// equality
0491         bool  operator==( const particle_const_iterator& a ) const
0492         { return m_map_iterator == a.m_map_iterator; }
0493         /// inequality
0494         bool  operator!=( const particle_const_iterator& a ) const
0495         { return !(m_map_iterator == a.m_map_iterator); }
0496     protected:
0497         /// const iterator to the GenParticle map
0498         std::map<int,HepMC::GenParticle*>::const_iterator m_map_iterator;
0499     private:
0500         /// Pre-fix increment
0501         particle_const_iterator&  operator--(void);
0502         /// Post-fix increment
0503         particle_const_iterator   operator--(int);
0504     };  
0505     friend class particle_const_iterator;
0506     /// begin particle iteration
0507     particle_const_iterator      particles_begin() const
0508         { return GenEvent::particle_const_iterator( 
0509         m_particle_barcodes.begin() ); }
0510     /// end particle iteration
0511     particle_const_iterator      particles_end() const
0512         { return GenEvent::particle_const_iterator(
0513         m_particle_barcodes.end() ); }
0514 
0515     //!  non-const particle iterator
0516 
0517     /// \class  particle_iterator
0518     /// HepMC::GenEvent::particle_iterator 
0519     /// is used to iterate over all particles in the event.
0520     class particle_iterator :
0521       public std::iterator<std::forward_iterator_tag,HepMC::GenParticle*,ptrdiff_t>{
0522         // Iterates over all vertices in this event
0523     public:
0524         /// iterate over particles
0525         particle_iterator( const std::map<int,HepMC::GenParticle*>::iterator& i )
0526         : m_map_iterator( i ) {}
0527         particle_iterator() {}
0528         /// copy constructor
0529         particle_iterator( const particle_iterator& i ) { *this = i; }
0530         virtual ~particle_iterator() {}
0531         /// make a copy
0532         particle_iterator&  operator=( const particle_iterator& i ) {
0533         m_map_iterator = i.m_map_iterator;
0534         return *this;
0535         }
0536         /// const particle iterator
0537         operator particle_const_iterator() const
0538         { return particle_const_iterator(m_map_iterator); }
0539         /// return pointer to GenParticle
0540         GenParticle*        operator*(void) const
0541         { return m_map_iterator->second; }
0542             /// Pre-fix increment
0543         particle_iterator&  operator++(void) 
0544         { ++m_map_iterator;     return *this; }
0545             /// Post-fix increment
0546         particle_iterator   operator++(int)   
0547         { particle_iterator out(*this); ++(*this); return out; }
0548             /// equality
0549         bool              operator==( const particle_iterator& a ) const
0550         { return m_map_iterator == a.m_map_iterator; }
0551             /// inequality
0552         bool              operator!=( const particle_iterator& a ) const
0553         { return !(m_map_iterator == a.m_map_iterator); }
0554     protected:
0555         /// iterator for GenParticle map
0556         std::map<int,HepMC::GenParticle*>::iterator m_map_iterator;
0557     private:
0558             /// Pre-fix increment
0559         particle_iterator&  operator--(void);
0560             /// Post-fix increment
0561         particle_iterator   operator--(int);
0562     };
0563     friend class particle_iterator;
0564     /// begin particle iteration
0565     particle_iterator particles_begin() 
0566         { return GenEvent::particle_iterator(
0567         m_particle_barcodes.begin() ); }
0568     /// end particle iteration
0569         particle_iterator particles_end()
0570         { return GenEvent::particle_iterator(
0571         m_particle_barcodes.end() ); }
0572 
0573     ////////////////////////////////////////////////
0574     protected:
0575     //
0576     // Following methods intended for use by GenParticle/Vertex classes:
0577     // In general there is no reason they should be used elsewhere.
0578     /// set the barcode - intended for use by GenParticle
0579     bool         set_barcode( GenParticle* p, int suggested_barcode =false );
0580     /// set the barcode - intended for use by GenVertex
0581     bool         set_barcode( GenVertex*   v, int suggested_barcode =false );
0582     ///  intended for use by GenParticle
0583     void         remove_barcode( GenParticle* p );
0584     ///  intended for use by GenVertex
0585     void         remove_barcode( GenVertex*   v );
0586 
0587     void delete_all_vertices(); //!<delete all vertices owned by this event
0588 
0589      private: // methods
0590         /// internal method used when converting momentum units
0591         bool use_momentum_unit( Units::MomentumUnit );
0592         bool use_momentum_unit( std::string& );
0593         /// internal method used when converting length units
0594     bool use_length_unit( Units::LengthUnit );
0595     bool use_length_unit( std::string& );
0596     
0597     // the following internal methods are used by read() and write()
0598 
0599     /// send the beam particles to ASCII output
0600     std::ostream & write_beam_particles( std::ostream &, 
0601                          std::pair<HepMC::GenParticle *,HepMC::GenParticle *> );
0602     /// send a GenVertex to ASCII output
0603     std::ostream & write_vertex( std::ostream &, GenVertex const * );
0604     /// send a GenParticle to ASCII output
0605     std::ostream & write_particle( std::ostream&, GenParticle const * );
0606     /// find the file type
0607     std::istream & find_file_type( std::istream & );
0608     /// find the key at the end of the block
0609     std::istream & find_end_key( std::istream &, int & );
0610         /// get unit information from ASCII input
0611         std::istream & read_units( std::istream & );
0612     /// get weight names from ASCII input
0613         std::istream & read_weight_names( std::istream & );
0614     /// read the event header line
0615         std::istream & process_event_line( std::istream &, int &, int &, int &, int & );
0616 
0617     private: // data members
0618     int                   m_signal_process_id;
0619     int                   m_event_number;  
0620     int                   m_mpi;        // number of multi paricle interactions
0621     double                m_event_scale;// energy scale, see hep-ph/0109068
0622     double                m_alphaQCD;   // QCD coupling, see hep-ph/0109068
0623     double                m_alphaQED;   // QED coupling, see hep-ph/0109068
0624     GenVertex*            m_signal_process_vertex;
0625     GenParticle*          m_beam_particle_1;
0626     GenParticle*          m_beam_particle_2;
0627     WeightContainer       m_weights; // weights for this event first weight
0628                                      // is used by default for hit and miss
0629     std::vector<long> m_random_states; // container of rndm num 
0630                                            // generator states
0631 
0632     std::map< int,HepMC::GenVertex*,std::greater<int> >   m_vertex_barcodes;
0633     std::map< int,HepMC::GenParticle*,std::less<int> >    m_particle_barcodes;
0634     GenCrossSection*         m_cross_section;         // undefined by default
0635     HeavyIon*             m_heavy_ion;        // undefined by default
0636     PdfInfo*              m_pdf_info;         // undefined by default
0637     Units::MomentumUnit   m_momentum_unit;    // default value set by configure switch
0638     Units::LengthUnit     m_position_unit;    // default value set by configure switch
0639 
0640     };
0641 
0642 
0643     ///////////////////////////
0644     // IO Free Functions     //
0645     ///////////////////////////
0646   
0647     /// standard streaming IO output operator
0648     std::ostream & operator << (std::ostream &, GenEvent &);
0649     /// standard streaming IO input operator
0650     std::istream & operator >> (std::istream &, GenEvent &);
0651     /// set the units for this input stream
0652     std::istream & set_input_units(std::istream &, 
0653                                    Units::MomentumUnit, Units::LengthUnit);
0654     /// Explicitly write the begin block lines that IO_GenEvent uses
0655     std::ostream & write_HepMC_IO_block_begin(std::ostream & );
0656     /// Explicitly write the end block line that IO_GenEvent uses
0657     std::ostream & write_HepMC_IO_block_end(std::ostream & );
0658 
0659 
0660     ///////////////////////////
0661     // INLINE Free Functions //
0662     ///////////////////////////
0663 
0664     // Implemented in terms of GenEvent::use_...
0665     inline GenEvent& convert_units(GenEvent & evt, Units::MomentumUnit m, Units::LengthUnit l)
0666     {
0667       evt.use_units(m, l);
0668       return evt;
0669     }
0670 
0671     ///////////////////////////
0672     // INLINE Access Methods //
0673     ///////////////////////////
0674 
0675     ///  The integer ID that uniquely specifies this signal
0676     ///  process, i.e. MSUB in Pythia. It is necessary to
0677     ///  package this with each event rather than with the run
0678     ///  because many processes may be generated within one run.
0679     inline int GenEvent::signal_process_id() const 
0680     { return m_signal_process_id; }
0681 
0682     inline int GenEvent::event_number() const { return m_event_number; }
0683 
0684     /// Returns the number of multi parton interactions in the event.
0685     /// This number is -1 if it is not set.
0686     inline int GenEvent::mpi() const { return m_mpi; }
0687 
0688     inline double GenEvent::event_scale() const { return m_event_scale; }
0689 
0690     inline double GenEvent::alphaQCD() const { return m_alphaQCD; }
0691 
0692     inline double GenEvent::alphaQED() const { return m_alphaQED; }
0693  
0694     inline GenVertex* GenEvent::signal_process_vertex() const {
0695     /// returns a (mutable) pointer to the signal process vertex
0696     return m_signal_process_vertex;
0697     }  
0698 
0699     inline WeightContainer& GenEvent::weights() { return m_weights; }
0700 
0701     inline const WeightContainer& GenEvent::weights() const 
0702     { return m_weights; }
0703 
0704     inline GenCrossSection const * GenEvent::cross_section() const 
0705     { return m_cross_section; }
0706 
0707     inline GenCrossSection*  GenEvent::cross_section()  
0708     { return m_cross_section; }
0709 
0710     inline HeavyIon const * GenEvent::heavy_ion() const 
0711     { return m_heavy_ion; }
0712 
0713     inline HeavyIon*  GenEvent::heavy_ion()  
0714     { return m_heavy_ion; }
0715 
0716     inline PdfInfo const * GenEvent::pdf_info() const 
0717     { return m_pdf_info; }
0718 
0719     inline PdfInfo*  GenEvent::pdf_info()  
0720     { return m_pdf_info; }
0721 
0722     ///  Vector of integers which specify the random number 
0723     ///  generator's state for this event. It is left to the
0724     ///  generator to make use of this. We envision a vector of
0725     ///  RndmStatesTags to be included with a run class which
0726     ///  would specify the meaning of the random_states.
0727     inline const std::vector<long>& GenEvent::random_states() const 
0728     { return m_random_states; }
0729 
0730     inline void GenEvent::set_signal_process_id( int id )
0731     { m_signal_process_id = id; }
0732 
0733     inline void GenEvent::set_event_number( int eventno )
0734     { m_event_number = eventno; }
0735 
0736     /// Use this to set the number of multi parton interactions in each event.
0737     inline void GenEvent::set_mpi( int nmpi )
0738     { m_mpi = nmpi; }
0739 
0740 
0741     inline void GenEvent::set_event_scale( double sc ) { m_event_scale = sc; }
0742 
0743     inline void GenEvent::set_alphaQCD( double a ) { m_alphaQCD = a; }
0744 
0745     inline void GenEvent::set_alphaQED( double a ) { m_alphaQED = a; }
0746 
0747     inline void GenEvent::set_signal_process_vertex( GenVertex* vtx ) {
0748     m_signal_process_vertex = vtx;
0749     if ( m_signal_process_vertex ) add_vertex( m_signal_process_vertex );
0750     }
0751 
0752     inline void GenEvent::set_cross_section( const GenCrossSection& xs )
0753     { 
0754         delete m_cross_section;
0755         m_cross_section = new GenCrossSection(xs); 
0756     }
0757 
0758     inline void GenEvent::set_heavy_ion( const HeavyIon& ion )
0759     { 
0760         delete m_heavy_ion;
0761         m_heavy_ion = new HeavyIon(ion); 
0762     }
0763 
0764     inline void GenEvent::set_pdf_info( const PdfInfo& p )
0765     { 
0766         delete m_pdf_info;
0767         m_pdf_info = new PdfInfo(p); 
0768     }
0769 
0770     inline void GenEvent::set_random_states( const std::vector<long>&
0771                          randomstates )
0772     { m_random_states = randomstates; }
0773 
0774     inline void GenEvent::remove_barcode( GenParticle* p )
0775     { m_particle_barcodes.erase( p->barcode() ); }
0776 
0777     inline void GenEvent::remove_barcode( GenVertex* v )
0778     { m_vertex_barcodes.erase( v->barcode() ); }
0779 
0780     /// Each vertex or particle has a barcode, which is just an integer which
0781     /// uniquely identifies it inside the event (i.e. there is a one to one
0782     /// mapping between particle memory addresses and particle barcodes... and 
0783     /// the same applied for vertices).
0784     ///
0785     /// The value of a barcode has NO MEANING and NO ORDER!
0786     /// For the user's convenience, when an event is read in via an IO_method
0787     /// from an indexed list (like the HEPEVT common block), then the index will
0788     /// become the barcode for that particle.
0789     ///
0790     /// Particle barcodes are always positive integers.
0791     /// The barcodes are chosen and set automatically when a vertex or particle
0792     /// comes under the ownership of an event (i.e. it is contained in an event).
0793     /// 
0794     /// Please note that the barcodes are intended for internal use within 
0795     /// HepMC as a unique identifier for the particles and vertices.
0796     /// Using the barcode to encode extra information is an abuse of 
0797     /// the barcode data member and causes confusion among users. 
0798     inline GenParticle* GenEvent::barcode_to_particle( int barCode ) const
0799     { 
0800     std::map<int,HepMC::GenParticle*>::const_iterator i 
0801         = m_particle_barcodes.find(barCode);
0802     return ( i != m_particle_barcodes.end() ) ? (*i).second : 0;
0803     }
0804 
0805     /// Each vertex or particle has a barcode, which is just an integer which
0806     /// uniquely identifies it inside the event (i.e. there is a one to one
0807     /// mapping between particle memory addresses and particle barcodes... and 
0808     /// the same applied for vertices).
0809     ///
0810     /// The value of a barcode has NO MEANING and NO ORDER!
0811     /// For the user's convenience, when an event is read in via an IO_method
0812     /// from an indexed list (like the HEPEVT common block), then the index will
0813     /// become the barcode for that particle.
0814     ///
0815     /// Vertex barcodes are always negative integers.
0816     /// The barcodes are chosen and set automatically when a vertex or particle
0817     /// comes under the ownership of an event (i.e. it is contained in an event).
0818     /// 
0819     /// Please note that the barcodes are intended for internal use within 
0820     /// HepMC as a unique identifier for the particles and vertices.
0821     /// Using the barcode to encode extra information is an abuse of 
0822     /// the barcode data member and causes confusion among users. 
0823     inline GenVertex* GenEvent::barcode_to_vertex( int barCode ) const
0824     {
0825     std::map<int,GenVertex*,std::greater<int> >::const_iterator i 
0826         = m_vertex_barcodes.find(barCode);
0827     return ( i != m_vertex_barcodes.end() ) ? (*i).second : 0;
0828     }
0829 
0830     inline int GenEvent::particles_size() const {
0831     return (int)m_particle_barcodes.size();
0832     }
0833     inline bool GenEvent::particles_empty() const {
0834     return (bool)m_particle_barcodes.empty();
0835     }
0836     inline int GenEvent::vertices_size() const {
0837     return (int)m_vertex_barcodes.size();
0838     }
0839     inline bool GenEvent::vertices_empty() const {
0840     return (bool)m_vertex_barcodes.empty();
0841     }
0842     
0843     // beam particles
0844     inline std::pair<HepMC::GenParticle *,HepMC::GenParticle *> GenEvent::beam_particles() const {
0845         return std::pair<GenParticle *,GenParticle *> (m_beam_particle_1, m_beam_particle_2);
0846     }
0847 
0848     // units
0849     inline Units::MomentumUnit GenEvent::momentum_unit() const {
0850         return m_momentum_unit; 
0851     }
0852     inline Units::LengthUnit   GenEvent::length_unit()   const {
0853         return m_position_unit; 
0854     }
0855     
0856     inline void GenEvent::use_units( Units::MomentumUnit new_m, Units::LengthUnit new_l ) { 
0857        use_momentum_unit( new_m );
0858        use_length_unit( new_l );
0859     }
0860     
0861     inline void GenEvent::use_units( std::string& new_m, std::string& new_l ) { 
0862        use_momentum_unit( new_m );
0863        use_length_unit( new_l );
0864     }
0865     
0866     inline void GenEvent::define_units( Units::MomentumUnit new_m, Units::LengthUnit new_l ) { 
0867     m_momentum_unit = new_m; 
0868     m_position_unit = new_l; 
0869     }
0870 
0871 } // HepMC
0872 
0873 #endif  // HEPMC_GEN_EVENT_H
0874 
0875 //--------------------------------------------------------------------------
0876 
0877