HepMC Reference Documentation

HepMC

GenEvent.cc

Go to the documentation of this file.
00001 
00002 // Matt.Dobbs@Cern.CH, September 1999
00003 // Updated: 7.1.2000 iterators complete and working!
00004 // Updated: 10.1.2000 GenEvent::vertex, particle iterators are made 
00005 //                    constant WRT this event ... note that 
00006 //                    GenVertex::***_iterator is not const, since it must
00007 //                    be able to return a mutable pointer to itself.
00008 // Updated: 08.2.2000 the event now holds a set of all attached vertices
00009 //                    rather than just the roots of the graph
00010 // Event record for MC generators (for use at any stage of generation)
00012 
00013 #include "HepMC/GenEvent.h"
00014 #include "HepMC/Version.h"
00015 
00016 namespace HepMC {
00017 
00018     GenEvent::GenEvent( int signal_process_id, 
00019                         int event_number,
00020                         GenVertex* signal_vertex,
00021                         const WeightContainer& weights,
00022                         const std::vector<long>& random_states ) :
00023         m_signal_process_id(signal_process_id), 
00024         m_event_number(event_number),
00025         m_mpi(-1),
00026         m_event_scale(-1), 
00027         m_alphaQCD(-1), 
00028         m_alphaQED(-1),
00029         m_signal_process_vertex(signal_vertex), 
00030         m_beam_particle_1(0),
00031         m_beam_particle_2(0),
00032         m_weights(weights),
00033         m_random_states(random_states),
00034         m_vertex_barcodes(),
00035         m_particle_barcodes(),
00036         m_heavy_ion(0), 
00037         m_pdf_info(0)
00038     {
00043         ++s_counter;
00044     }
00045 
00046     GenEvent::GenEvent( int signal_process_id, int event_number,
00047                         GenVertex* signal_vertex,
00048                         const WeightContainer& weights,
00049                         const std::vector<long>& random_states,
00050                         const HeavyIon& ion, 
00051                         const PdfInfo& pdf ) :
00052         m_signal_process_id(signal_process_id), 
00053         m_event_number(event_number),
00054         m_mpi(-1),
00055         m_event_scale(-1), 
00056         m_alphaQCD(-1), 
00057         m_alphaQED(-1),
00058         m_signal_process_vertex(signal_vertex), 
00059         m_beam_particle_1(0),
00060         m_beam_particle_2(0),
00061         m_weights(weights),
00062         m_random_states(random_states), 
00063         m_vertex_barcodes(),
00064         m_particle_barcodes(),
00065         m_heavy_ion( new HeavyIon(ion) ), 
00066         m_pdf_info( new PdfInfo(pdf) )
00067     {
00072         ++s_counter;
00073     }
00074 
00075     GenEvent::GenEvent( const GenEvent& inevent ) 
00076       : m_signal_process_id    ( inevent.signal_process_id() ),
00077         m_event_number         ( inevent.event_number() ),
00078         m_mpi                  ( inevent.mpi() ),
00079         m_event_scale          ( inevent.event_scale() ),
00080         m_alphaQCD             ( inevent.alphaQCD() ),
00081         m_alphaQED             ( inevent.alphaQED() ),
00082         m_signal_process_vertex( /* inevent.m_signal_process_vertex */ ),
00083         m_beam_particle_1      ( /* inevent.m_beam_particle_1 */ ),
00084         m_beam_particle_2      ( /* inevent.m_beam_particle_2 */ ),
00085         m_weights              ( /* inevent.m_weights */ ),
00086         m_random_states        ( /* inevent.m_random_states */ ),
00087         m_vertex_barcodes      ( /* inevent.m_vertex_barcodes */ ),
00088         m_particle_barcodes    ( /* inevent.m_particle_barcodes */ ),
00089         m_heavy_ion            ( inevent.heavy_ion() ? new HeavyIon(*inevent.heavy_ion()) : 0 ),
00090         m_pdf_info             ( inevent.pdf_info() ? new PdfInfo(*inevent.pdf_info()) : 0 )
00091     {
00093         ++s_counter;
00095         //
00096 
00097         // 1. create a NEW copy of all vertices from inevent
00098         //    taking care to map new vertices onto the vertices being copied
00099         //    and add these new vertices to this event.
00100         //    We do not use GenVertex::operator= because that would copy
00101         //    the attached particles as well.
00102         std::map<const GenVertex*,GenVertex*> map_in_to_new;
00103         for ( GenEvent::vertex_const_iterator v = inevent.vertices_begin();
00104               v != inevent.vertices_end(); ++v ) {
00105             GenVertex* newvertex = new GenVertex(
00106                 (*v)->position(), (*v)->id(), (*v)->weights() );
00107             newvertex->suggest_barcode( (*v)->barcode() );
00108             map_in_to_new[*v] = newvertex;
00109             add_vertex( newvertex );
00110         }
00111         // 2. copy the signal process vertex info.
00112         if ( inevent.signal_process_vertex() ) {
00113             set_signal_process_vertex( 
00114                 map_in_to_new[inevent.signal_process_vertex()] );
00115         } else set_signal_process_vertex( 0 );
00116         //
00117         // 3. create a NEW copy of all particles from inevent
00118         //    taking care to attach them to the appropriate vertex
00119         GenParticle* beam1(0);
00120         GenParticle* beam2(0);
00121         for ( GenEvent::particle_const_iterator p = inevent.particles_begin();
00122               p != inevent.particles_end(); ++p ) 
00123         {
00124             GenParticle* oldparticle = *p;
00125             GenParticle* newparticle = new GenParticle(*oldparticle);
00126             if ( oldparticle->end_vertex() ) {
00127                 map_in_to_new[ oldparticle->end_vertex() ]->
00128                                          add_particle_in(newparticle);
00129             }
00130             if ( oldparticle->production_vertex() ) {
00131                 map_in_to_new[ oldparticle->production_vertex() ]->
00132                                          add_particle_out(newparticle);
00133             }
00134             if ( oldparticle == inevent.beam_particles().first ) beam1 = newparticle;
00135             if ( oldparticle == inevent.beam_particles().second ) beam2 = newparticle;
00136         }
00137         set_beam_particles( beam1, beam2 );
00138         //
00139         // 4. now that vtx/particles are copied, copy weights and random states
00140         set_random_states( inevent.random_states() );
00141         weights() = inevent.weights();
00142     }
00143 
00144     void GenEvent::swap( GenEvent & other )
00145     {
00146         // if a container has a swap method, use that for improved performance
00147         std::swap(m_signal_process_id    , other.m_signal_process_id    );
00148         std::swap(m_event_number         , other.m_event_number         );
00149         std::swap(m_mpi                  , other.m_mpi                  );
00150         std::swap(m_event_scale          , other.m_event_scale          );
00151         std::swap(m_alphaQCD             , other.m_alphaQCD             );
00152         std::swap(m_alphaQED             , other.m_alphaQED             );
00153         std::swap(m_signal_process_vertex, other.m_signal_process_vertex);
00154         std::swap(m_beam_particle_1      , other.m_beam_particle_1      );
00155         std::swap(m_beam_particle_2      , other.m_beam_particle_2      );
00156         m_weights.swap(           other.m_weights  );
00157         m_random_states.swap(     other.m_random_states  );
00158         m_vertex_barcodes.swap(   other.m_vertex_barcodes );
00159         m_particle_barcodes.swap( other.m_particle_barcodes );
00160         std::swap(m_heavy_ion            , other.m_heavy_ion            );
00161         std::swap(m_pdf_info             , other.m_pdf_info             );
00162     }
00163 
00164     GenEvent::~GenEvent() 
00165     {
00169         delete_all_vertices();
00170         delete m_heavy_ion;
00171         delete m_pdf_info;
00172         --s_counter;
00173     }
00174 
00175     GenEvent& GenEvent::operator=( const GenEvent& inevent ) 
00176     {
00178         GenEvent tmp( inevent );
00179         swap( tmp );
00180         return *this;
00181     }
00182 
00183     void GenEvent::print( std::ostream& ostr ) const {
00188         ostr << "________________________________________"
00189              << "________________________________________\n";
00190         ostr << "GenEvent: #" << event_number() 
00191              << " ID=" << signal_process_id() 
00192              << " SignalProcessGenVertex Barcode: " 
00193              << ( signal_process_vertex() ? signal_process_vertex()->barcode()
00194                   : 0 )
00195              << "\n";
00196         ostr << " Current Memory Usage: " 
00197              << GenEvent::counter() << " events, "
00198              << GenVertex::counter() << " vertices, "
00199              << GenParticle::counter() << " particles.\n"; 
00200         ostr << " Entries this event: " << vertices_size() << " vertices, "
00201              << particles_size() << " particles.\n"; 
00202         if( m_beam_particle_1 && m_beam_particle_2 ) {
00203           ostr << " Beam Particle barcodes: " << beam_particles().first->barcode() << " "
00204                << beam_particles().second->barcode() << " \n";
00205         } else {
00206           ostr << " Beam Particles are not defined.\n";
00207         }
00208         // Random State
00209         ostr << " RndmState(" << m_random_states.size() << ")=";
00210         for ( std::vector<long>::const_iterator rs 
00211                   = m_random_states.begin();
00212               rs != m_random_states.end(); ++rs ) { ostr << *rs << " "; }
00213         ostr << "\n";
00214         // Weights
00215         ostr << " Wgts(" << weights().size() << ")=";
00216         for ( WeightContainer::const_iterator wgt = weights().begin();
00217               wgt != weights().end(); ++wgt ) { ostr << *wgt << " "; }
00218         ostr << "\n";
00219         ostr << " EventScale " << event_scale() 
00220              << " [energy] \t alphaQCD=" << alphaQCD() 
00221              << "\t alphaQED=" << alphaQED() << std::endl;
00222         // print a legend to describe the particle info
00223         ostr << "                                    GenParticle Legend\n";
00224         ostr  << "        Barcode   PDG ID      "
00225               << "( Px,       Py,       Pz,     E )"
00226               << " Stat  DecayVtx\n";
00227         ostr << "________________________________________"
00228              << "________________________________________\n";
00229         // Print all Vertices
00230         for ( GenEvent::vertex_const_iterator vtx = this->vertices_begin();
00231               vtx != this->vertices_end(); ++vtx ) {
00232             (*vtx)->print(ostr); 
00233         }
00234         ostr << "________________________________________"
00235              << "________________________________________" << std::endl;
00236     }
00237 
00238     void GenEvent::print_version( std::ostream& ostr ) const {
00239         ostr << "---------------------------------------------" << std::endl;
00240         writeVersion( ostr );
00241         ostr << "---------------------------------------------" << std::endl;
00242     }
00243 
00244     bool GenEvent::add_vertex( GenVertex* vtx ) {
00247         if ( !vtx ) return false;
00248         // if vtx previously pointed to another GenEvent, remove it from that
00249         // GenEvent's list
00250         if ( vtx->parent_event() && vtx->parent_event() != this ) {
00251             bool remove_status = vtx->parent_event()->remove_vertex( vtx );
00252             if ( !remove_status ) {            
00253                 std::cerr << "GenEvent::add_vertex ERROR "
00254                           << "GenVertex::parent_event points to \n"
00255                           << "an event that does not point back to the "
00256                           << "GenVertex. \n This probably indicates a deeper "
00257                           << "problem. " << std::endl;
00258             }
00259         }
00260         //
00261         // setting the vertex parent also inserts the vertex into this
00262         // event
00263         vtx->set_parent_event_( this );
00264         return ( m_vertex_barcodes.count(vtx->barcode()) ? true : false );
00265     }
00266 
00267     bool GenEvent::remove_vertex( GenVertex* vtx ) {
00270         if ( m_signal_process_vertex == vtx ) m_signal_process_vertex = 0;
00271         if ( vtx->parent_event() == this ) vtx->set_parent_event_( 0 );
00272         return ( m_vertex_barcodes.count(vtx->barcode()) ? false : true );
00273     }
00274 
00275     void GenEvent::clear() 
00276     {
00280         delete_all_vertices();
00281         delete m_heavy_ion;
00282         delete m_pdf_info;
00283         m_signal_process_id = 0;
00284         m_beam_particle_1 = 0;
00285         m_beam_particle_2 = 0;
00286         m_event_number = 0;
00287         m_event_scale = -1;
00288         m_alphaQCD = -1;
00289         m_alphaQED = -1;
00290         m_weights = std::vector<double>();
00291         m_random_states = std::vector<long>();
00292         // error check just to be safe
00293         if ( m_vertex_barcodes.size() != 0 
00294              || m_particle_barcodes.size() != 0 ) {
00295             std::cerr << "GenEvent::clear() strange result ... \n"
00296                       << "either the particle and/or the vertex map isn't empty" << std::endl;
00297             std::cerr << "Number vtx,particle the event after deleting = "
00298                       << m_vertex_barcodes.size() << "  " 
00299                       << m_particle_barcodes.size() << std::endl;
00300             std::cerr << "Total Number vtx,particle in memory "
00301                       << "after method called = "
00302                       << GenVertex::counter() << "\t"
00303                       << GenParticle::counter() << std::endl;
00304         }
00305         return;
00306     }
00307     
00308     void GenEvent::delete_all_vertices() {
00314 
00315         // delete each vertex individually (this deletes particles as well)
00316         while ( !vertices_empty() ) {
00317             GenVertex* vtx = ( m_vertex_barcodes.begin() )->second;
00318             m_vertex_barcodes.erase( m_vertex_barcodes.begin() );
00319             delete vtx;
00320         }
00321         //
00322         // Error checking:
00323         if ( !vertices_empty() || ! particles_empty() ) {
00324             std::cerr << "GenEvent::delete_all_vertices strange result ... "
00325                       << "after deleting all vertices, \nthe particle and "
00326                       << "vertex maps aren't empty.\n  This probably " 
00327                       << "indicates deeper problems or memory leak in the "
00328                       << "code." << std::endl;
00329             std::cerr << "Number vtx,particle the event after deleting = "
00330                       << m_vertex_barcodes.size() << "  " 
00331                       << m_particle_barcodes.size() << std::endl;
00332             std::cerr << "Total Number vtx,particle in memory "
00333                       << "after method called = "
00334                       << GenVertex::counter() << "\t"
00335                       << GenParticle::counter() << std::endl;
00336         }
00337     }
00338     
00339     bool GenEvent::set_barcode( GenParticle* p, int suggested_barcode )
00340     {
00341         if ( p->parent_event() != this ) {
00342             std::cerr << "GenEvent::set_barcode attempted, but the argument's"
00343                       << "\n parent_event is not this ... request rejected."
00344                       << std::endl;
00345             return false;
00346         }
00347         // M.Dobbs  Nov 4, 2002
00348         // First we must check to see if the particle already has a
00349         // barcode which is different from the suggestion. If yes, we
00350         // remove it from the particle map.
00351         if ( p->barcode() != 0 && p->barcode() != suggested_barcode ) {
00352             if ( m_particle_barcodes.count(p->barcode()) &&
00353                  m_particle_barcodes[p->barcode()] == p ) {
00354                 m_particle_barcodes.erase( p->barcode() );
00355             }
00356             // At this point either the particle is NOT in
00357             // m_particle_barcodes, or else it is in the map, but
00358             // already with the suggested barcode.
00359         }
00360         //
00361         // First case --- a valid barcode has been suggested
00362         //     (valid barcodes are numbers greater than zero)
00363         bool insert_success = true;
00364         if ( suggested_barcode > 0 ) {
00365             if ( m_particle_barcodes.count(suggested_barcode) ) {
00366                 // the suggested_barcode is already used.
00367                 if ( m_particle_barcodes[suggested_barcode] == p ) {
00368                     // but it was used for this particle ... so everythings ok
00369                     p->set_barcode_( suggested_barcode );
00370                     return true;
00371                 }
00372                 insert_success = false;
00373                 suggested_barcode = 0;
00374             } else { // suggested barcode is OK, proceed to insert
00375                 m_particle_barcodes[suggested_barcode] = p;
00376                 p->set_barcode_( suggested_barcode );
00377                 return true;
00378             }
00379         }
00380         //
00381         // Other possibility -- a valid barcode has not been suggested,
00382         //    so one is automatically generated
00383         if ( suggested_barcode < 0 ) insert_success = false;
00384         if ( suggested_barcode <= 0 ) {
00385             if ( !m_particle_barcodes.empty() ) {
00386                 // in this case we find the highest barcode that was used,
00387                 // and increment it by 1
00388                 suggested_barcode = m_particle_barcodes.rbegin()->first;
00389                 ++suggested_barcode;
00390             }
00391             // For the automatically assigned barcodes, the first one
00392             //   we use is 10001 ... this is just because when we read 
00393             //   events from HEPEVT, we will suggest their index as the
00394             //   barcode, and that index has maximum value 10000.
00395             //  This way we will immediately be able to recognize the hepevt
00396             //   particles from the auto-assigned ones.
00397             if ( suggested_barcode <= 10000 ) suggested_barcode = 10001;
00398         }
00399         // At this point we should have a valid barcode
00400         if ( m_particle_barcodes.count(suggested_barcode) ) {
00401             std::cerr << "GenEvent::set_barcode ERROR, this should never "
00402                       << "happen \n report bug to matt.dobbs@cern.ch" 
00403                       << std::endl;
00404         }
00405         m_particle_barcodes[suggested_barcode] = p;
00406         p->set_barcode_( suggested_barcode );
00407         return insert_success;
00408     }
00409 
00410     bool GenEvent::set_barcode( GenVertex* v, int suggested_barcode )
00411     {
00412         if ( v->parent_event() != this ) {
00413             std::cerr << "GenEvent::set_barcode attempted, but the argument's"
00414                       << "\n parent_event is not this ... request rejected."
00415                       << std::endl;
00416             return false;
00417         }
00418         // M.Dobbs Nov 4, 2002
00419         // First we must check to see if the vertex already has a
00420         // barcode which is different from the suggestion. If yes, we
00421         // remove it from the vertex map.
00422         if ( v->barcode() != 0 && v->barcode() != suggested_barcode ) {
00423             if ( m_vertex_barcodes.count(v->barcode()) &&
00424                  m_vertex_barcodes[v->barcode()] == v ) {
00425                 m_vertex_barcodes.erase( v->barcode() );
00426             }
00427             // At this point either the vertex is NOT in
00428             // m_vertex_barcodes, or else it is in the map, but
00429             // already with the suggested barcode.
00430         }
00431         
00432         //
00433         // First case --- a valid barcode has been suggested
00434         //     (valid barcodes are numbers greater than zero)
00435         bool insert_success = true;
00436         if ( suggested_barcode < 0 ) {
00437             if ( m_vertex_barcodes.count(suggested_barcode) ) {
00438                 // the suggested_barcode is already used.
00439                 if ( m_vertex_barcodes[suggested_barcode] == v ) {
00440                     // but it was used for this vertex ... so everythings ok
00441                     v->set_barcode_( suggested_barcode );
00442                     return true;
00443                 }
00444                 insert_success = false;
00445                 suggested_barcode = 0;
00446             } else { // suggested barcode is OK, proceed to insert
00447                 m_vertex_barcodes[suggested_barcode] = v;
00448                 v->set_barcode_( suggested_barcode );
00449                 return true;
00450             }
00451         }
00452         //
00453         // Other possibility -- a valid barcode has not been suggested,
00454         //    so one is automatically generated
00455         if ( suggested_barcode > 0 ) insert_success = false;
00456         if ( suggested_barcode >= 0 ) {
00457             if ( !m_vertex_barcodes.empty() ) {
00458                 // in this case we find the highest barcode that was used,
00459                 // and increment it by 1, (vertex barcodes are negative)
00460                 suggested_barcode = m_vertex_barcodes.rbegin()->first;
00461                 --suggested_barcode;
00462             }
00463             if ( suggested_barcode >= 0 ) suggested_barcode = -1;
00464         }
00465         // At this point we should have a valid barcode
00466         if ( m_vertex_barcodes.count(suggested_barcode) ) {
00467             std::cerr << "GenEvent::set_barcode ERROR, this should never "
00468                       << "happen \n report bug to matt.dobbs@cern.ch" 
00469                       << std::endl;
00470         }
00471         m_vertex_barcodes[suggested_barcode] = v;
00472         v->set_barcode_( suggested_barcode );
00473         return insert_success;
00474     }
00475 
00477     bool  GenEvent::valid_beam_particles() const {
00478         bool have1 = false;
00479         bool have2 = false;
00480         // first check that both are defined
00481         if(m_beam_particle_1 && m_beam_particle_2) {
00482             // now look for a match with the particle "list"
00483             for ( particle_const_iterator p = particles_begin();
00484                   p != particles_end(); ++p ) {
00485                 if( m_beam_particle_1 == *p ) have1 = true;
00486                 if( m_beam_particle_2 == *p ) have2 = true;
00487             }
00488         }
00489         if( have1 && have2 ) return true;
00490         return false;
00491     }
00492     
00495     bool  GenEvent::set_beam_particles(GenParticle* bp1, GenParticle* bp2) {
00496         m_beam_particle_1 = bp1;
00497         m_beam_particle_2 = bp2;
00498         if( m_beam_particle_1 && m_beam_particle_2 ) return true;
00499         return false;
00500     }
00501 
00504     bool  GenEvent::set_beam_particles(std::pair<HepMC::GenParticle*, HepMC::GenParticle*> const & bp) {
00505         return set_beam_particles(bp.first,bp.second);
00506     }
00507 
00509     // Static  //
00511     unsigned int GenEvent::counter() { return s_counter; }
00512     unsigned int GenEvent::s_counter = 0; 
00513 
00514 } // HepMC

Generated on Tue Feb 5 13:25:44 2008 for HepMC by  doxygen 1.5.1-3