![]() |
HepMC Reference DocumentationHepMC |
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