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;
00094         //
00095 
00096         // 1. create a NEW copy of all vertices from inevent
00097         //    taking care to map new vertices onto the vertices being copied
00098         //    and add these new vertices to this event.
00099         //    We do not use GenVertex::operator= because that would copy
00100         //    the attached particles as well.
00101         std::map<const GenVertex*,GenVertex*> map_in_to_new;
00102         for ( GenEvent::vertex_const_iterator v = inevent.vertices_begin();
00103               v != inevent.vertices_end(); ++v ) {
00104             GenVertex* newvertex = new GenVertex(
00105                 (*v)->position(), (*v)->id(), (*v)->weights() );
00106             newvertex->suggest_barcode( (*v)->barcode() );
00107             map_in_to_new[*v] = newvertex;
00108             add_vertex( newvertex );
00109         }
00110         // 2. copy the signal process vertex info.
00111         if ( inevent.signal_process_vertex() ) {
00112             set_signal_process_vertex( 
00113                 map_in_to_new[inevent.signal_process_vertex()] );
00114         } else set_signal_process_vertex( 0 );
00115         //
00116         // 3. create a NEW copy of all particles from inevent
00117         //    taking care to attach them to the appropriate vertex
00118         GenParticle* beam1(0);
00119         GenParticle* beam2(0);
00120         for ( GenEvent::particle_const_iterator p = inevent.particles_begin();
00121               p != inevent.particles_end(); ++p ) 
00122         {
00123             GenParticle* oldparticle = *p;
00124             GenParticle* newparticle = new GenParticle(*oldparticle);
00125             if ( oldparticle->end_vertex() ) {
00126                 map_in_to_new[ oldparticle->end_vertex() ]->
00127                                          add_particle_in(newparticle);
00128             }
00129             if ( oldparticle->production_vertex() ) {
00130                 map_in_to_new[ oldparticle->production_vertex() ]->
00131                                          add_particle_out(newparticle);
00132             }
00133             if ( oldparticle == inevent.beam_particles().first ) beam1 = newparticle;
00134             if ( oldparticle == inevent.beam_particles().second ) beam2 = newparticle;
00135         }
00136         set_beam_particles( beam1, beam2 );
00137         //
00138         // 4. now that vtx/particles are copied, copy weights and random states
00139         set_random_states( inevent.random_states() );
00140         weights() = inevent.weights();
00141     }
00142 
00143     void GenEvent::swap( GenEvent & other )
00144     {
00145         // if a container has a swap method, use that for improved performance
00146         std::swap(m_signal_process_id    , other.m_signal_process_id    );
00147         std::swap(m_event_number         , other.m_event_number         );
00148         std::swap(m_mpi                  , other.m_mpi                  );
00149         std::swap(m_event_scale          , other.m_event_scale          );
00150         std::swap(m_alphaQCD             , other.m_alphaQCD             );
00151         std::swap(m_alphaQED             , other.m_alphaQED             );
00152         std::swap(m_signal_process_vertex, other.m_signal_process_vertex);
00153         std::swap(m_beam_particle_1      , other.m_beam_particle_1      );
00154         std::swap(m_beam_particle_2      , other.m_beam_particle_2      );
00155         m_weights.swap(           other.m_weights  );
00156         m_random_states.swap(     other.m_random_states  );
00157         m_vertex_barcodes.swap(   other.m_vertex_barcodes );
00158         m_particle_barcodes.swap( other.m_particle_barcodes );
00159         std::swap(m_heavy_ion            , other.m_heavy_ion            );
00160         std::swap(m_pdf_info             , other.m_pdf_info             );
00161         // must now adjust GenVertex back pointers
00162         for ( GenEvent::vertex_const_iterator vthis = vertices_begin();
00163               vthis != vertices_end(); ++vthis ) {
00164             (*vthis)->change_parent_event_( this );
00165         }
00166         for ( GenEvent::vertex_const_iterator voth = other.vertices_begin();
00167               voth != other.vertices_end(); ++voth ) {
00168             (*voth)->change_parent_event_( &other );
00169         }
00170     }
00171 
00172     GenEvent::~GenEvent() 
00173     {
00177         delete_all_vertices();
00178         delete m_heavy_ion;
00179         delete m_pdf_info;
00180         //--s_counter;
00181     }
00182 
00183     GenEvent& GenEvent::operator=( const GenEvent& inevent ) 
00184     {
00186         GenEvent tmp( inevent );
00187         swap( tmp );
00188         return *this;
00189     }
00190 
00191     void GenEvent::print( std::ostream& ostr ) const {
00196         ostr << "________________________________________"
00197              << "________________________________________\n";
00198         ostr << "GenEvent: #" << event_number() 
00199              << " ID=" << signal_process_id() 
00200              << " SignalProcessGenVertex Barcode: " 
00201              << ( signal_process_vertex() ? signal_process_vertex()->barcode()
00202                   : 0 )
00203              << "\n";
00204         //ostr << " Current Memory Usage: " 
00205         //     << GenEvent::counter() << " events, "
00206         //     << GenVertex::counter() << " vertices, "
00207         //     << GenParticle::counter() << " particles.\n"; 
00208         ostr << " Entries this event: " << vertices_size() << " vertices, "
00209              << particles_size() << " particles.\n"; 
00210         if( m_beam_particle_1 && m_beam_particle_2 ) {
00211           ostr << " Beam Particle barcodes: " << beam_particles().first->barcode() << " "
00212                << beam_particles().second->barcode() << " \n";
00213         } else {
00214           ostr << " Beam Particles are not defined.\n";
00215         }
00216         // Random State
00217         ostr << " RndmState(" << m_random_states.size() << ")=";
00218         for ( std::vector<long>::const_iterator rs 
00219                   = m_random_states.begin();
00220               rs != m_random_states.end(); ++rs ) { ostr << *rs << " "; }
00221         ostr << "\n";
00222         // Weights
00223         ostr << " Wgts(" << weights().size() << ")=";
00224         for ( WeightContainer::const_iterator wgt = weights().begin();
00225               wgt != weights().end(); ++wgt ) { ostr << *wgt << " "; }
00226         ostr << "\n";
00227         ostr << " EventScale " << event_scale() 
00228              << " [energy] \t alphaQCD=" << alphaQCD() 
00229              << "\t alphaQED=" << alphaQED() << std::endl;
00230         // print a legend to describe the particle info
00231         ostr << "                                    GenParticle Legend\n";
00232         ostr  << "        Barcode   PDG ID      "
00233               << "( Px,       Py,       Pz,     E )"
00234               << " Stat  DecayVtx\n";
00235         ostr << "________________________________________"
00236              << "________________________________________\n";
00237         // Print all Vertices
00238         for ( GenEvent::vertex_const_iterator vtx = this->vertices_begin();
00239               vtx != this->vertices_end(); ++vtx ) {
00240             (*vtx)->print(ostr); 
00241         }
00242         ostr << "________________________________________"
00243              << "________________________________________" << std::endl;
00244     }
00245 
00246     void GenEvent::print_version( std::ostream& ostr ) const {
00247         ostr << "---------------------------------------------" << std::endl;
00248         writeVersion( ostr );
00249         ostr << "---------------------------------------------" << std::endl;
00250     }
00251 
00252     bool GenEvent::add_vertex( GenVertex* vtx ) {
00255         if ( !vtx ) return false;
00256         // if vtx previously pointed to another GenEvent, remove it from that
00257         // GenEvent's list
00258         if ( vtx->parent_event() && vtx->parent_event() != this ) {
00259             bool remove_status = vtx->parent_event()->remove_vertex( vtx );
00260             if ( !remove_status ) {            
00261                 std::cerr << "GenEvent::add_vertex ERROR "
00262                           << "GenVertex::parent_event points to \n"
00263                           << "an event that does not point back to the "
00264                           << "GenVertex. \n This probably indicates a deeper "
00265                           << "problem. " << std::endl;
00266             }
00267         }
00268         //
00269         // setting the vertex parent also inserts the vertex into this
00270         // event
00271         vtx->set_parent_event_( this );
00272         return ( m_vertex_barcodes.count(vtx->barcode()) ? true : false );
00273     }
00274 
00275     bool GenEvent::remove_vertex( GenVertex* vtx ) {
00278         if ( m_signal_process_vertex == vtx ) m_signal_process_vertex = 0;
00279         if ( vtx->parent_event() == this ) vtx->set_parent_event_( 0 );
00280         return ( m_vertex_barcodes.count(vtx->barcode()) ? false : true );
00281     }
00282 
00283     void GenEvent::clear() 
00284     {
00288         delete_all_vertices();
00289         delete m_heavy_ion;
00290         delete m_pdf_info;
00291         m_signal_process_id = 0;
00292         m_beam_particle_1 = 0;
00293         m_beam_particle_2 = 0;
00294         m_event_number = 0;
00295         m_event_scale = -1;
00296         m_alphaQCD = -1;
00297         m_alphaQED = -1;
00298         m_weights = std::vector<double>();
00299         m_random_states = std::vector<long>();
00300         // error check just to be safe
00301         if ( m_vertex_barcodes.size() != 0 
00302              || m_particle_barcodes.size() != 0 ) {
00303             std::cerr << "GenEvent::clear() strange result ... \n"
00304                       << "either the particle and/or the vertex map isn't empty" << std::endl;
00305             std::cerr << "Number vtx,particle the event after deleting = "
00306                       << m_vertex_barcodes.size() << "  " 
00307                       << m_particle_barcodes.size() << std::endl;
00308             //std::cerr << "Total Number vtx,particle in memory "
00309              //         << "after method called = "
00310              //         << GenVertex::counter() << "\t"
00311                 //      << GenParticle::counter() << std::endl;
00312         }
00313         return;
00314     }
00315     
00316     void GenEvent::delete_all_vertices() {
00322 
00323         // delete each vertex individually (this deletes particles as well)
00324         while ( !vertices_empty() ) {
00325             GenVertex* vtx = ( m_vertex_barcodes.begin() )->second;
00326             m_vertex_barcodes.erase( m_vertex_barcodes.begin() );
00327             delete vtx;
00328         }
00329         //
00330         // Error checking:
00331         if ( !vertices_empty() || ! particles_empty() ) {
00332             std::cerr << "GenEvent::delete_all_vertices strange result ... "
00333                       << "after deleting all vertices, \nthe particle and "
00334                       << "vertex maps aren't empty.\n  This probably " 
00335                       << "indicates deeper problems or memory leak in the "
00336                       << "code." << std::endl;
00337             std::cerr << "Number vtx,particle the event after deleting = "
00338                       << m_vertex_barcodes.size() << "  " 
00339                       << m_particle_barcodes.size() << std::endl;
00340             //std::cerr << "Total Number vtx,particle in memory "
00341             //          << "after method called = "
00342             //          << GenVertex::counter() << "\t"
00343                 //      << GenParticle::counter() << std::endl;
00344         }
00345     }
00346     
00347     bool GenEvent::set_barcode( GenParticle* p, int suggested_barcode )
00348     {
00349         if ( p->parent_event() != this ) {
00350             std::cerr << "GenEvent::set_barcode attempted, but the argument's"
00351                       << "\n parent_event is not this ... request rejected."
00352                       << std::endl;
00353             return false;
00354         }
00355         // M.Dobbs  Nov 4, 2002
00356         // First we must check to see if the particle already has a
00357         // barcode which is different from the suggestion. If yes, we
00358         // remove it from the particle map.
00359         if ( p->barcode() != 0 && p->barcode() != suggested_barcode ) {
00360             if ( m_particle_barcodes.count(p->barcode()) &&
00361                  m_particle_barcodes[p->barcode()] == p ) {
00362                 m_particle_barcodes.erase( p->barcode() );
00363             }
00364             // At this point either the particle is NOT in
00365             // m_particle_barcodes, or else it is in the map, but
00366             // already with the suggested barcode.
00367         }
00368         //
00369         // First case --- a valid barcode has been suggested
00370         //     (valid barcodes are numbers greater than zero)
00371         bool insert_success = true;
00372         if ( suggested_barcode > 0 ) {
00373             if ( m_particle_barcodes.count(suggested_barcode) ) {
00374                 // the suggested_barcode is already used.
00375                 if ( m_particle_barcodes[suggested_barcode] == p ) {
00376                     // but it was used for this particle ... so everythings ok
00377                     p->set_barcode_( suggested_barcode );
00378                     return true;
00379                 }
00380                 insert_success = false;
00381                 suggested_barcode = 0;
00382             } else { // suggested barcode is OK, proceed to insert
00383                 m_particle_barcodes[suggested_barcode] = p;
00384                 p->set_barcode_( suggested_barcode );
00385                 return true;
00386             }
00387         }
00388         //
00389         // Other possibility -- a valid barcode has not been suggested,
00390         //    so one is automatically generated
00391         if ( suggested_barcode < 0 ) insert_success = false;
00392         if ( suggested_barcode <= 0 ) {
00393             if ( !m_particle_barcodes.empty() ) {
00394                 // in this case we find the highest barcode that was used,
00395                 // and increment it by 1
00396                 suggested_barcode = m_particle_barcodes.rbegin()->first;
00397                 ++suggested_barcode;
00398             }
00399             // For the automatically assigned barcodes, the first one
00400             //   we use is 10001 ... this is just because when we read 
00401             //   events from HEPEVT, we will suggest their index as the
00402             //   barcode, and that index has maximum value 10000.
00403             //  This way we will immediately be able to recognize the hepevt
00404             //   particles from the auto-assigned ones.
00405             if ( suggested_barcode <= 10000 ) suggested_barcode = 10001;
00406         }
00407         // At this point we should have a valid barcode
00408         if ( m_particle_barcodes.count(suggested_barcode) ) {
00409             std::cerr << "GenEvent::set_barcode ERROR, this should never "
00410                       << "happen \n report bug to matt.dobbs@cern.ch" 
00411                       << std::endl;
00412         }
00413         m_particle_barcodes[suggested_barcode] = p;
00414         p->set_barcode_( suggested_barcode );
00415         return insert_success;
00416     }
00417 
00418     bool GenEvent::set_barcode( GenVertex* v, int suggested_barcode )
00419     {
00420         if ( v->parent_event() != this ) {
00421             std::cerr << "GenEvent::set_barcode attempted, but the argument's"
00422                       << "\n parent_event is not this ... request rejected."
00423                       << std::endl;
00424             return false;
00425         }
00426         // M.Dobbs Nov 4, 2002
00427         // First we must check to see if the vertex already has a
00428         // barcode which is different from the suggestion. If yes, we
00429         // remove it from the vertex map.
00430         if ( v->barcode() != 0 && v->barcode() != suggested_barcode ) {
00431             if ( m_vertex_barcodes.count(v->barcode()) &&
00432                  m_vertex_barcodes[v->barcode()] == v ) {
00433                 m_vertex_barcodes.erase( v->barcode() );
00434             }
00435             // At this point either the vertex is NOT in
00436             // m_vertex_barcodes, or else it is in the map, but
00437             // already with the suggested barcode.
00438         }
00439         
00440         //
00441         // First case --- a valid barcode has been suggested
00442         //     (valid barcodes are numbers greater than zero)
00443         bool insert_success = true;
00444         if ( suggested_barcode < 0 ) {
00445             if ( m_vertex_barcodes.count(suggested_barcode) ) {
00446                 // the suggested_barcode is already used.
00447                 if ( m_vertex_barcodes[suggested_barcode] == v ) {
00448                     // but it was used for this vertex ... so everythings ok
00449                     v->set_barcode_( suggested_barcode );
00450                     return true;
00451                 }
00452                 insert_success = false;
00453                 suggested_barcode = 0;
00454             } else { // suggested barcode is OK, proceed to insert
00455                 m_vertex_barcodes[suggested_barcode] = v;
00456                 v->set_barcode_( suggested_barcode );
00457                 return true;
00458             }
00459         }
00460         //
00461         // Other possibility -- a valid barcode has not been suggested,
00462         //    so one is automatically generated
00463         if ( suggested_barcode > 0 ) insert_success = false;
00464         if ( suggested_barcode >= 0 ) {
00465             if ( !m_vertex_barcodes.empty() ) {
00466                 // in this case we find the highest barcode that was used,
00467                 // and increment it by 1, (vertex barcodes are negative)
00468                 suggested_barcode = m_vertex_barcodes.rbegin()->first;
00469                 --suggested_barcode;
00470             }
00471             if ( suggested_barcode >= 0 ) suggested_barcode = -1;
00472         }
00473         // At this point we should have a valid barcode
00474         if ( m_vertex_barcodes.count(suggested_barcode) ) {
00475             std::cerr << "GenEvent::set_barcode ERROR, this should never "
00476                       << "happen \n report bug to matt.dobbs@cern.ch" 
00477                       << std::endl;
00478         }
00479         m_vertex_barcodes[suggested_barcode] = v;
00480         v->set_barcode_( suggested_barcode );
00481         return insert_success;
00482     }
00483 
00485     bool  GenEvent::valid_beam_particles() const {
00486         bool have1 = false;
00487         bool have2 = false;
00488         // first check that both are defined
00489         if(m_beam_particle_1 && m_beam_particle_2) {
00490             // now look for a match with the particle "list"
00491             for ( particle_const_iterator p = particles_begin();
00492                   p != particles_end(); ++p ) {
00493                 if( m_beam_particle_1 == *p ) have1 = true;
00494                 if( m_beam_particle_2 == *p ) have2 = true;
00495             }
00496         }
00497         if( have1 && have2 ) return true;
00498         return false;
00499     }
00500     
00503     bool  GenEvent::set_beam_particles(GenParticle* bp1, GenParticle* bp2) {
00504         m_beam_particle_1 = bp1;
00505         m_beam_particle_2 = bp2;
00506         if( m_beam_particle_1 && m_beam_particle_2 ) return true;
00507         return false;
00508     }
00509 
00512     bool  GenEvent::set_beam_particles(std::pair<HepMC::GenParticle*, HepMC::GenParticle*> const & bp) {
00513         return set_beam_particles(bp.first,bp.second);
00514     }
00515 
00517     // Static  //
00519     //unsigned int GenEvent::counter() { return s_counter; }
00520     //unsigned int GenEvent::s_counter = 0; 
00521 
00522 } // HepMC

Generated on Wed Mar 12 13:08:08 2008 for HepMC by  doxygen 1.5.1-3