![]() |
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 <iomanip> 00014 00015 #include "HepMC/GenEvent.h" 00016 #include "HepMC/GenCrossSection.h" 00017 #include "HepMC/Version.h" 00018 #include "HepMC/StreamHelpers.h" 00019 00020 namespace HepMC { 00021 00022 GenEvent::GenEvent( int signal_process_id, 00023 int event_number, 00024 GenVertex* signal_vertex, 00025 const WeightContainer& weights, 00026 const std::vector<long>& random_states, 00027 Units::MomentumUnit mom, 00028 Units::LengthUnit len ) : 00029 m_signal_process_id(signal_process_id), 00030 m_event_number(event_number), 00031 m_mpi(-1), 00032 m_event_scale(-1), 00033 m_alphaQCD(-1), 00034 m_alphaQED(-1), 00035 m_signal_process_vertex(signal_vertex), 00036 m_beam_particle_1(0), 00037 m_beam_particle_2(0), 00038 m_weights(weights), 00039 m_random_states(random_states), 00040 m_vertex_barcodes(), 00041 m_particle_barcodes(), 00042 m_cross_section(0), 00043 m_heavy_ion(0), 00044 m_pdf_info(0), 00045 m_momentum_unit(mom), 00046 m_position_unit(len) 00047 { 00053 } 00054 00055 GenEvent::GenEvent( int signal_process_id, int event_number, 00056 GenVertex* signal_vertex, 00057 const WeightContainer& weights, 00058 const std::vector<long>& random_states, 00059 const HeavyIon& ion, 00060 const PdfInfo& pdf, 00061 Units::MomentumUnit mom, 00062 Units::LengthUnit len ) : 00063 m_signal_process_id(signal_process_id), 00064 m_event_number(event_number), 00065 m_mpi(-1), 00066 m_event_scale(-1), 00067 m_alphaQCD(-1), 00068 m_alphaQED(-1), 00069 m_signal_process_vertex(signal_vertex), 00070 m_beam_particle_1(0), 00071 m_beam_particle_2(0), 00072 m_weights(weights), 00073 m_random_states(random_states), 00074 m_vertex_barcodes(), 00075 m_particle_barcodes(), 00076 m_cross_section(0), 00077 m_heavy_ion( new HeavyIon(ion) ), 00078 m_pdf_info( new PdfInfo(pdf) ), 00079 m_momentum_unit(mom), 00080 m_position_unit(len) 00081 { 00086 } 00087 00088 GenEvent::GenEvent( Units::MomentumUnit mom, 00089 Units::LengthUnit len, 00090 int signal_process_id, 00091 int event_number, 00092 GenVertex* signal_vertex, 00093 const WeightContainer& weights, 00094 const std::vector<long>& random_states ) : 00095 m_signal_process_id(signal_process_id), 00096 m_event_number(event_number), 00097 m_mpi(-1), 00098 m_event_scale(-1), 00099 m_alphaQCD(-1), 00100 m_alphaQED(-1), 00101 m_signal_process_vertex(signal_vertex), 00102 m_beam_particle_1(0), 00103 m_beam_particle_2(0), 00104 m_weights(weights), 00105 m_random_states(random_states), 00106 m_vertex_barcodes(), 00107 m_particle_barcodes(), 00108 m_cross_section(0), 00109 m_heavy_ion(0), 00110 m_pdf_info(0), 00111 m_momentum_unit(mom), 00112 m_position_unit(len) 00113 { 00120 } 00121 00122 GenEvent::GenEvent( Units::MomentumUnit mom, 00123 Units::LengthUnit len, 00124 int signal_process_id, int event_number, 00125 GenVertex* signal_vertex, 00126 const WeightContainer& weights, 00127 const std::vector<long>& random_states, 00128 const HeavyIon& ion, 00129 const PdfInfo& pdf ) : 00130 m_signal_process_id(signal_process_id), 00131 m_event_number(event_number), 00132 m_mpi(-1), 00133 m_event_scale(-1), 00134 m_alphaQCD(-1), 00135 m_alphaQED(-1), 00136 m_signal_process_vertex(signal_vertex), 00137 m_beam_particle_1(0), 00138 m_beam_particle_2(0), 00139 m_weights(weights), 00140 m_random_states(random_states), 00141 m_vertex_barcodes(), 00142 m_particle_barcodes(), 00143 m_cross_section(0), 00144 m_heavy_ion( new HeavyIon(ion) ), 00145 m_pdf_info( new PdfInfo(pdf) ), 00146 m_momentum_unit(mom), 00147 m_position_unit(len) 00148 { 00154 } 00155 00156 GenEvent::GenEvent( const GenEvent& inevent ) 00157 : m_signal_process_id ( inevent.signal_process_id() ), 00158 m_event_number ( inevent.event_number() ), 00159 m_mpi ( inevent.mpi() ), 00160 m_event_scale ( inevent.event_scale() ), 00161 m_alphaQCD ( inevent.alphaQCD() ), 00162 m_alphaQED ( inevent.alphaQED() ), 00163 m_signal_process_vertex( /* inevent.m_signal_process_vertex */ ), 00164 m_beam_particle_1 ( /* inevent.m_beam_particle_1 */ ), 00165 m_beam_particle_2 ( /* inevent.m_beam_particle_2 */ ), 00166 m_weights ( /* inevent.m_weights */ ), 00167 m_random_states ( /* inevent.m_random_states */ ), 00168 m_vertex_barcodes ( /* inevent.m_vertex_barcodes */ ), 00169 m_particle_barcodes ( /* inevent.m_particle_barcodes */ ), 00170 m_cross_section ( inevent.cross_section() ? new GenCrossSection(*inevent.cross_section()) : 0 ), 00171 m_heavy_ion ( inevent.heavy_ion() ? new HeavyIon(*inevent.heavy_ion()) : 0 ), 00172 m_pdf_info ( inevent.pdf_info() ? new PdfInfo(*inevent.pdf_info()) : 0 ), 00173 m_momentum_unit ( inevent.momentum_unit() ), 00174 m_position_unit ( inevent.length_unit() ) 00175 { 00177 // 00178 00179 // 1. create a NEW copy of all vertices from inevent 00180 // taking care to map new vertices onto the vertices being copied 00181 // and add these new vertices to this event. 00182 // We do not use GenVertex::operator= because that would copy 00183 // the attached particles as well. 00184 std::map<const GenVertex*,GenVertex*> map_in_to_new; 00185 for ( GenEvent::vertex_const_iterator v = inevent.vertices_begin(); 00186 v != inevent.vertices_end(); ++v ) { 00187 GenVertex* newvertex = new GenVertex( 00188 (*v)->position(), (*v)->id(), (*v)->weights() ); 00189 newvertex->suggest_barcode( (*v)->barcode() ); 00190 map_in_to_new[*v] = newvertex; 00191 add_vertex( newvertex ); 00192 } 00193 // 2. copy the signal process vertex info. 00194 if ( inevent.signal_process_vertex() ) { 00195 set_signal_process_vertex( 00196 map_in_to_new[inevent.signal_process_vertex()] ); 00197 } else set_signal_process_vertex( 0 ); 00198 // 00199 // 3. create a NEW copy of all particles from inevent 00200 // taking care to attach them to the appropriate vertex 00201 GenParticle* beam1(0); 00202 GenParticle* beam2(0); 00203 for ( GenEvent::particle_const_iterator p = inevent.particles_begin(); 00204 p != inevent.particles_end(); ++p ) 00205 { 00206 GenParticle* oldparticle = *p; 00207 GenParticle* newparticle = new GenParticle(*oldparticle); 00208 if ( oldparticle->end_vertex() ) { 00209 map_in_to_new[ oldparticle->end_vertex() ]-> 00210 add_particle_in(newparticle); 00211 } 00212 if ( oldparticle->production_vertex() ) { 00213 map_in_to_new[ oldparticle->production_vertex() ]-> 00214 add_particle_out(newparticle); 00215 } 00216 if ( oldparticle == inevent.beam_particles().first ) beam1 = newparticle; 00217 if ( oldparticle == inevent.beam_particles().second ) beam2 = newparticle; 00218 } 00219 set_beam_particles( beam1, beam2 ); 00220 // 00221 // 4. now that vtx/particles are copied, copy weights and random states 00222 set_random_states( inevent.random_states() ); 00223 weights() = inevent.weights(); 00224 } 00225 00226 void GenEvent::swap( GenEvent & other ) 00227 { 00228 // if a container has a swap method, use that for improved performance 00229 std::swap(m_signal_process_id , other.m_signal_process_id ); 00230 std::swap(m_event_number , other.m_event_number ); 00231 std::swap(m_mpi , other.m_mpi ); 00232 std::swap(m_event_scale , other.m_event_scale ); 00233 std::swap(m_alphaQCD , other.m_alphaQCD ); 00234 std::swap(m_alphaQED , other.m_alphaQED ); 00235 std::swap(m_signal_process_vertex, other.m_signal_process_vertex); 00236 std::swap(m_beam_particle_1 , other.m_beam_particle_1 ); 00237 std::swap(m_beam_particle_2 , other.m_beam_particle_2 ); 00238 m_weights.swap( other.m_weights ); 00239 m_random_states.swap( other.m_random_states ); 00240 m_vertex_barcodes.swap( other.m_vertex_barcodes ); 00241 m_particle_barcodes.swap( other.m_particle_barcodes ); 00242 std::swap(m_cross_section , other.m_cross_section ); 00243 std::swap(m_heavy_ion , other.m_heavy_ion ); 00244 std::swap(m_pdf_info , other.m_pdf_info ); 00245 std::swap(m_momentum_unit , other.m_momentum_unit ); 00246 std::swap(m_position_unit , other.m_position_unit ); 00247 // must now adjust GenVertex back pointers 00248 for ( GenEvent::vertex_const_iterator vthis = vertices_begin(); 00249 vthis != vertices_end(); ++vthis ) { 00250 (*vthis)->change_parent_event_( this ); 00251 } 00252 for ( GenEvent::vertex_const_iterator voth = other.vertices_begin(); 00253 voth != other.vertices_end(); ++voth ) { 00254 (*voth)->change_parent_event_( &other ); 00255 } 00256 } 00257 00258 GenEvent::~GenEvent() 00259 { 00263 delete_all_vertices(); 00264 delete m_cross_section; 00265 delete m_heavy_ion; 00266 delete m_pdf_info; 00267 } 00268 00269 GenEvent& GenEvent::operator=( const GenEvent& inevent ) 00270 { 00272 GenEvent tmp( inevent ); 00273 swap( tmp ); 00274 return *this; 00275 } 00276 00277 void GenEvent::print( std::ostream& ostr ) const { 00282 ostr << "________________________________________" 00283 << "________________________________________\n"; 00284 ostr << "GenEvent: #" << event_number() 00285 << " ID=" << signal_process_id() 00286 << " SignalProcessGenVertex Barcode: " 00287 << ( signal_process_vertex() ? signal_process_vertex()->barcode() 00288 : 0 ) 00289 << "\n"; 00290 write_units( ostr ); 00291 write_cross_section(ostr); 00292 ostr << " Entries this event: " << vertices_size() << " vertices, " 00293 << particles_size() << " particles.\n"; 00294 if( m_beam_particle_1 && m_beam_particle_2 ) { 00295 ostr << " Beam Particle barcodes: " << beam_particles().first->barcode() << " " 00296 << beam_particles().second->barcode() << " \n"; 00297 } else { 00298 ostr << " Beam Particles are not defined.\n"; 00299 } 00300 // Random State 00301 ostr << " RndmState(" << m_random_states.size() << ")="; 00302 for ( std::vector<long>::const_iterator rs 00303 = m_random_states.begin(); 00304 rs != m_random_states.end(); ++rs ) { ostr << *rs << " "; } 00305 ostr << "\n"; 00306 // Weights 00307 ostr << " Wgts(" << weights().size() << ")="; 00308 for ( WeightContainer::const_iterator wgt = weights().begin(); 00309 wgt != weights().end(); ++wgt ) { ostr << *wgt << " "; } 00310 ostr << "\n"; 00311 ostr << " EventScale " << event_scale() 00312 << " [energy] \t alphaQCD=" << alphaQCD() 00313 << "\t alphaQED=" << alphaQED() << std::endl; 00314 // print a legend to describe the particle info 00315 ostr << " GenParticle Legend\n"; 00316 ostr << " Barcode PDG ID " 00317 << "( Px, Py, Pz, E )" 00318 << " Stat DecayVtx\n"; 00319 ostr << "________________________________________" 00320 << "________________________________________\n"; 00321 // Print all Vertices 00322 for ( GenEvent::vertex_const_iterator vtx = this->vertices_begin(); 00323 vtx != this->vertices_end(); ++vtx ) { 00324 (*vtx)->print(ostr); 00325 } 00326 ostr << "________________________________________" 00327 << "________________________________________" << std::endl; 00328 } 00329 00330 void GenEvent::print_version( std::ostream& ostr ) const { 00331 ostr << "---------------------------------------------" << std::endl; 00332 writeVersion( ostr ); 00333 ostr << "---------------------------------------------" << std::endl; 00334 } 00335 00336 bool GenEvent::add_vertex( GenVertex* vtx ) { 00339 if ( !vtx ) return false; 00340 // if vtx previously pointed to another GenEvent, remove it from that 00341 // GenEvent's list 00342 if ( vtx->parent_event() && vtx->parent_event() != this ) { 00343 bool remove_status = vtx->parent_event()->remove_vertex( vtx ); 00344 if ( !remove_status ) { 00345 std::cerr << "GenEvent::add_vertex ERROR " 00346 << "GenVertex::parent_event points to \n" 00347 << "an event that does not point back to the " 00348 << "GenVertex. \n This probably indicates a deeper " 00349 << "problem. " << std::endl; 00350 } 00351 } 00352 // 00353 // setting the vertex parent also inserts the vertex into this 00354 // event 00355 vtx->set_parent_event_( this ); 00356 return ( m_vertex_barcodes.count(vtx->barcode()) ? true : false ); 00357 } 00358 00359 bool GenEvent::remove_vertex( GenVertex* vtx ) { 00362 if ( m_signal_process_vertex == vtx ) m_signal_process_vertex = 0; 00363 if ( vtx->parent_event() == this ) vtx->set_parent_event_( 0 ); 00364 return ( m_vertex_barcodes.count(vtx->barcode()) ? false : true ); 00365 } 00366 00367 void GenEvent::clear() 00368 { 00372 delete_all_vertices(); 00373 // remove existing objects and set pointers to null 00374 delete m_cross_section; 00375 m_cross_section = 0; 00376 delete m_heavy_ion; 00377 m_heavy_ion = 0; 00378 delete m_pdf_info; 00379 m_pdf_info = 0; 00380 m_signal_process_id = 0; 00381 m_beam_particle_1 = 0; 00382 m_beam_particle_2 = 0; 00383 m_event_number = 0; 00384 m_mpi = -1; 00385 m_event_scale = -1; 00386 m_alphaQCD = -1; 00387 m_alphaQED = -1; 00388 m_weights = std::vector<double>(); 00389 m_random_states = std::vector<long>(); 00390 // resetting unit information 00391 m_momentum_unit = Units::default_momentum_unit(); 00392 m_position_unit = Units::default_length_unit(); 00393 // error check just to be safe 00394 if ( m_vertex_barcodes.size() != 0 00395 || m_particle_barcodes.size() != 0 ) { 00396 std::cerr << "GenEvent::clear() strange result ... \n" 00397 << "either the particle and/or the vertex map isn't empty" << std::endl; 00398 std::cerr << "Number vtx,particle the event after deleting = " 00399 << m_vertex_barcodes.size() << " " 00400 << m_particle_barcodes.size() << std::endl; 00401 } 00402 return; 00403 } 00404 00405 void GenEvent::delete_all_vertices() { 00411 00412 // delete each vertex individually (this deletes particles as well) 00413 while ( !vertices_empty() ) { 00414 GenVertex* vtx = ( m_vertex_barcodes.begin() )->second; 00415 m_vertex_barcodes.erase( m_vertex_barcodes.begin() ); 00416 delete vtx; 00417 } 00418 // 00419 // Error checking: 00420 if ( !vertices_empty() || ! particles_empty() ) { 00421 std::cerr << "GenEvent::delete_all_vertices strange result ... " 00422 << "after deleting all vertices, \nthe particle and " 00423 << "vertex maps aren't empty.\n This probably " 00424 << "indicates deeper problems or memory leak in the " 00425 << "code." << std::endl; 00426 std::cerr << "Number vtx,particle the event after deleting = " 00427 << m_vertex_barcodes.size() << " " 00428 << m_particle_barcodes.size() << std::endl; 00429 } 00430 } 00431 00432 bool GenEvent::set_barcode( GenParticle* p, int suggested_barcode ) 00433 { 00434 if ( p->parent_event() != this ) { 00435 std::cerr << "GenEvent::set_barcode attempted, but the argument's" 00436 << "\n parent_event is not this ... request rejected." 00437 << std::endl; 00438 return false; 00439 } 00440 // M.Dobbs Nov 4, 2002 00441 // First we must check to see if the particle already has a 00442 // barcode which is different from the suggestion. If yes, we 00443 // remove it from the particle map. 00444 if ( p->barcode() != 0 && p->barcode() != suggested_barcode ) { 00445 if ( m_particle_barcodes.count(p->barcode()) && 00446 m_particle_barcodes[p->barcode()] == p ) { 00447 m_particle_barcodes.erase( p->barcode() ); 00448 } 00449 // At this point either the particle is NOT in 00450 // m_particle_barcodes, or else it is in the map, but 00451 // already with the suggested barcode. 00452 } 00453 // 00454 // First case --- a valid barcode has been suggested 00455 // (valid barcodes are numbers greater than zero) 00456 bool insert_success = true; 00457 if ( suggested_barcode > 0 ) { 00458 if ( m_particle_barcodes.count(suggested_barcode) ) { 00459 // the suggested_barcode is already used. 00460 if ( m_particle_barcodes[suggested_barcode] == p ) { 00461 // but it was used for this particle ... so everythings ok 00462 p->set_barcode_( suggested_barcode ); 00463 return true; 00464 } 00465 insert_success = false; 00466 suggested_barcode = 0; 00467 } else { // suggested barcode is OK, proceed to insert 00468 m_particle_barcodes[suggested_barcode] = p; 00469 p->set_barcode_( suggested_barcode ); 00470 return true; 00471 } 00472 } 00473 // 00474 // Other possibility -- a valid barcode has not been suggested, 00475 // so one is automatically generated 00476 if ( suggested_barcode < 0 ) insert_success = false; 00477 if ( suggested_barcode <= 0 ) { 00478 if ( !m_particle_barcodes.empty() ) { 00479 // in this case we find the highest barcode that was used, 00480 // and increment it by 1 00481 suggested_barcode = m_particle_barcodes.rbegin()->first; 00482 ++suggested_barcode; 00483 } 00484 // For the automatically assigned barcodes, the first one 00485 // we use is 10001 ... this is just because when we read 00486 // events from HEPEVT, we will suggest their index as the 00487 // barcode, and that index has maximum value 10000. 00488 // This way we will immediately be able to recognize the hepevt 00489 // particles from the auto-assigned ones. 00490 if ( suggested_barcode <= 10000 ) suggested_barcode = 10001; 00491 } 00492 // At this point we should have a valid barcode 00493 if ( m_particle_barcodes.count(suggested_barcode) ) { 00494 std::cerr << "GenEvent::set_barcode ERROR, this should never " 00495 << "happen \n report bug to matt.dobbs@cern.ch" 00496 << std::endl; 00497 } 00498 m_particle_barcodes[suggested_barcode] = p; 00499 p->set_barcode_( suggested_barcode ); 00500 return insert_success; 00501 } 00502 00503 bool GenEvent::set_barcode( GenVertex* v, int suggested_barcode ) 00504 { 00505 if ( v->parent_event() != this ) { 00506 std::cerr << "GenEvent::set_barcode attempted, but the argument's" 00507 << "\n parent_event is not this ... request rejected." 00508 << std::endl; 00509 return false; 00510 } 00511 // M.Dobbs Nov 4, 2002 00512 // First we must check to see if the vertex already has a 00513 // barcode which is different from the suggestion. If yes, we 00514 // remove it from the vertex map. 00515 if ( v->barcode() != 0 && v->barcode() != suggested_barcode ) { 00516 if ( m_vertex_barcodes.count(v->barcode()) && 00517 m_vertex_barcodes[v->barcode()] == v ) { 00518 m_vertex_barcodes.erase( v->barcode() ); 00519 } 00520 // At this point either the vertex is NOT in 00521 // m_vertex_barcodes, or else it is in the map, but 00522 // already with the suggested barcode. 00523 } 00524 00525 // 00526 // First case --- a valid barcode has been suggested 00527 // (valid barcodes are numbers greater than zero) 00528 bool insert_success = true; 00529 if ( suggested_barcode < 0 ) { 00530 if ( m_vertex_barcodes.count(suggested_barcode) ) { 00531 // the suggested_barcode is already used. 00532 if ( m_vertex_barcodes[suggested_barcode] == v ) { 00533 // but it was used for this vertex ... so everythings ok 00534 v->set_barcode_( suggested_barcode ); 00535 return true; 00536 } 00537 insert_success = false; 00538 suggested_barcode = 0; 00539 } else { // suggested barcode is OK, proceed to insert 00540 m_vertex_barcodes[suggested_barcode] = v; 00541 v->set_barcode_( suggested_barcode ); 00542 return true; 00543 } 00544 } 00545 // 00546 // Other possibility -- a valid barcode has not been suggested, 00547 // so one is automatically generated 00548 if ( suggested_barcode > 0 ) insert_success = false; 00549 if ( suggested_barcode >= 0 ) { 00550 if ( !m_vertex_barcodes.empty() ) { 00551 // in this case we find the highest barcode that was used, 00552 // and increment it by 1, (vertex barcodes are negative) 00553 suggested_barcode = m_vertex_barcodes.rbegin()->first; 00554 --suggested_barcode; 00555 } 00556 if ( suggested_barcode >= 0 ) suggested_barcode = -1; 00557 } 00558 // At this point we should have a valid barcode 00559 if ( m_vertex_barcodes.count(suggested_barcode) ) { 00560 std::cerr << "GenEvent::set_barcode ERROR, this should never " 00561 << "happen \n report bug to matt.dobbs@cern.ch" 00562 << std::endl; 00563 } 00564 m_vertex_barcodes[suggested_barcode] = v; 00565 v->set_barcode_( suggested_barcode ); 00566 return insert_success; 00567 } 00568 00570 bool GenEvent::valid_beam_particles() const { 00571 bool have1 = false; 00572 bool have2 = false; 00573 // first check that both are defined 00574 if(m_beam_particle_1 && m_beam_particle_2) { 00575 // now look for a match with the particle "list" 00576 for ( particle_const_iterator p = particles_begin(); 00577 p != particles_end(); ++p ) { 00578 if( m_beam_particle_1 == *p ) have1 = true; 00579 if( m_beam_particle_2 == *p ) have2 = true; 00580 } 00581 } 00582 if( have1 && have2 ) return true; 00583 return false; 00584 } 00585 00588 bool GenEvent::set_beam_particles(GenParticle* bp1, GenParticle* bp2) { 00589 m_beam_particle_1 = bp1; 00590 m_beam_particle_2 = bp2; 00591 if( m_beam_particle_1 && m_beam_particle_2 ) return true; 00592 return false; 00593 } 00594 00597 bool GenEvent::set_beam_particles(std::pair<HepMC::GenParticle*, HepMC::GenParticle*> const & bp) { 00598 return set_beam_particles(bp.first,bp.second); 00599 } 00600 00601 void GenEvent::write_units( std::ostream & os ) const { 00602 os << " Momenutm units:" << std::setw(8) << name(momentum_unit()); 00603 os << " Position units:" << std::setw(8) << name(length_unit()); 00604 os << std::endl; 00605 } 00606 00607 void GenEvent::write_cross_section( std::ostream& os ) const 00608 { 00609 // write the GenCrossSection information if the cross section was set 00610 if( !cross_section() ) return; 00611 if( cross_section()->is_set() ) { 00612 os << " Cross Section: " << cross_section()->cross_section() ; 00613 os << " +/- " << cross_section()->cross_section_error() ; 00614 os << std::endl; 00615 } 00616 } 00617 00618 bool GenEvent::use_momentum_unit( Units::MomentumUnit newunit ) { 00619 // currently not exception-safe. 00620 // Easy to fix, though, if needed. 00621 if ( m_momentum_unit != newunit ) { 00622 const double factor = Units::conversion_factor( m_momentum_unit, newunit ); 00623 // multiply all momenta by 'factor', 00624 // loop is entered only if particle list is not empty 00625 for ( GenEvent::particle_iterator p = particles_begin(); 00626 p != particles_end(); ++p ) 00627 { 00628 (*p)->convert_momentum(factor); 00629 } 00630 // ... 00631 m_momentum_unit = newunit; 00632 } 00633 return true; 00634 } 00635 00636 bool GenEvent::use_length_unit( Units::LengthUnit newunit ) { 00637 // currently not exception-safe. 00638 // Easy to fix, though, if needed. 00639 if ( m_position_unit != newunit ) { 00640 const double factor = Units::conversion_factor( m_position_unit, newunit ); 00641 // multiply all lengths by 'factor', 00642 // loop is entered only if vertex list is not empty 00643 for ( GenEvent::vertex_iterator vtx = vertices_begin(); 00644 vtx != vertices_end(); ++vtx ) { 00645 (*vtx)->convert_position(factor); 00646 } 00647 // ... 00648 m_position_unit = newunit; 00649 } 00650 return true; 00651 } 00652 00653 bool GenEvent::use_momentum_unit( std::string& newunit ) { 00654 if ( newunit == "MEV" ) return use_momentum_unit( Units::MEV ); 00655 else if( newunit == "GEV" ) return use_momentum_unit( Units::GEV ); 00656 else std::cerr << "GenEvent::use_momentum_unit ERROR: use either MEV or GEV\n"; 00657 return false; 00658 } 00659 00660 bool GenEvent::use_length_unit( std::string& newunit ) { 00661 if ( newunit == "MM" ) return use_length_unit( Units::MM ); 00662 else if( newunit == "CM" ) return use_length_unit( Units::CM ); 00663 else std::cerr << "GenEvent::use_length_unit ERROR: use either MEV or GEV\n"; 00664 return false; 00665 } 00666 00667 bool GenEvent::is_valid() const { 00670 if ( vertices_empty() ) return false; 00671 if ( particles_empty() ) return false; 00672 return true; 00673 } 00674 00675 std::ostream & GenEvent::write_beam_particles(std::ostream & os, 00676 std::pair<HepMC::GenParticle *,HepMC::GenParticle *> pr ) 00677 { 00678 GenParticle* p = pr.first; 00679 if(!p) { 00680 detail::output( os, 0 ); 00681 } else { 00682 detail::output( os, p->barcode() ); 00683 } 00684 p = pr.second; 00685 if(!p) { 00686 detail::output( os, 0 ); 00687 } else { 00688 detail::output( os, p->barcode() ); 00689 } 00690 00691 return os; 00692 } 00693 00694 std::ostream & GenEvent::write_vertex(std::ostream & os, GenVertex const * v) 00695 { 00696 if ( !v || !os ) { 00697 std::cerr << "GenEvent::write_vertex !v||!os, " 00698 << "v="<< v << " setting badbit" << std::endl; 00699 os.clear(std::ios::badbit); 00700 return os; 00701 } 00702 // First collect info we need 00703 // count the number of orphan particles going into v 00704 int num_orphans_in = 0; 00705 for ( GenVertex::particles_in_const_iterator p1 00706 = v->particles_in_const_begin(); 00707 p1 != v->particles_in_const_end(); ++p1 ) { 00708 if ( !(*p1)->production_vertex() ) ++num_orphans_in; 00709 } 00710 // 00711 os << 'V'; 00712 detail::output( os, v->barcode() ); // v's unique identifier 00713 detail::output( os, v->id() ); 00714 detail::output( os, v->position().x() ); 00715 detail::output( os, v->position().y() ); 00716 detail::output( os, v->position().z() ); 00717 detail::output( os, v->position().t() ); 00718 detail::output( os, num_orphans_in ); 00719 detail::output( os, (int)v->particles_out_size() ); 00720 detail::output( os, (int)v->weights().size() ); 00721 for ( WeightContainer::const_iterator w = v->weights().begin(); 00722 w != v->weights().end(); ++w ) { 00723 detail::output( os, *w ); 00724 } 00725 detail::output( os,'\n'); 00726 // incoming particles 00727 for ( GenVertex::particles_in_const_iterator p2 00728 = v->particles_in_const_begin(); 00729 p2 != v->particles_in_const_end(); ++p2 ) { 00730 if ( !(*p2)->production_vertex() ) { 00731 write_particle( os, *p2 ); 00732 } 00733 } 00734 // outgoing particles 00735 for ( GenVertex::particles_out_const_iterator p3 00736 = v->particles_out_const_begin(); 00737 p3 != v->particles_out_const_end(); ++p3 ) { 00738 write_particle( os, *p3 ); 00739 } 00740 return os; 00741 } 00742 00743 std::ostream & GenEvent::write_particle( std::ostream & os, GenParticle const * p ) 00744 { 00745 if ( !p || !os ) { 00746 std::cerr << "GenEvent::write_particle !p||!os, " 00747 << "p="<< p << " setting badbit" << std::endl; 00748 os.clear(std::ios::badbit); 00749 return os; 00750 } 00751 os << 'P'; 00752 detail::output( os, p->barcode() ); 00753 detail::output( os, p->pdg_id() ); 00754 detail::output( os, p->momentum().px() ); 00755 detail::output( os, p->momentum().py() ); 00756 detail::output( os, p->momentum().pz() ); 00757 detail::output( os, p->momentum().e() ); 00758 detail::output( os, p->generated_mass() ); 00759 detail::output( os, p->status() ); 00760 detail::output( os, p->polarization().theta() ); 00761 detail::output( os, p->polarization().phi() ); 00762 // since end_vertex is oftentimes null, this CREATES a null vertex 00763 // in the map 00764 detail::output( os, ( p->end_vertex() ? p->end_vertex()->barcode() : 0 ) ); 00765 os << ' ' << p->flow() << "\n"; 00766 00767 return os; 00768 } 00769 00770 } // HepMC