StRoot  1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
GenEvent.cc
1 // Matt.Dobbs@Cern.CH, September 1999
3 // Updated: 7.1.2000 iterators complete and working!
4 // Updated: 10.1.2000 GenEvent::vertex, particle iterators are made
5 // constant WRT this event ... note that
6 // GenVertex::***_iterator is not const, since it must
7 // be able to return a mutable pointer to itself.
8 // Updated: 08.2.2000 the event now holds a set of all attached vertices
9 // rather than just the roots of the graph
10 // Event record for MC generators (for use at any stage of generation)
12 
13 #include <iomanip>
14 
15 #include "HepMC/GenEvent.h"
16 #include "HepMC/GenCrossSection.h"
17 #include "HepMC/Version.h"
18 #include "HepMC/StreamHelpers.h"
19 
20 namespace HepMC {
21 
22  GenEvent::GenEvent( int signal_process_id,
23  int event_number,
24  GenVertex* signal_vertex,
25  const WeightContainer& weights,
26  const std::vector<long>& random_states,
27  Units::MomentumUnit mom,
28  Units::LengthUnit len ) :
29  m_signal_process_id(signal_process_id),
30  m_event_number(event_number),
31  m_mpi(-1),
32  m_event_scale(-1),
33  m_alphaQCD(-1),
34  m_alphaQED(-1),
35  m_signal_process_vertex(signal_vertex),
36  m_beam_particle_1(0),
37  m_beam_particle_2(0),
38  m_weights(weights),
39  m_random_states(random_states),
40  m_vertex_barcodes(),
41  m_particle_barcodes(),
42  m_cross_section(0),
43  m_heavy_ion(0),
44  m_pdf_info(0),
45  m_momentum_unit(mom),
46  m_position_unit(len)
47  {
53  }
54 
55  GenEvent::GenEvent( int signal_process_id, int event_number,
56  GenVertex* signal_vertex,
57  const WeightContainer& weights,
58  const std::vector<long>& random_states,
59  const HeavyIon& ion,
60  const PdfInfo& pdf,
61  Units::MomentumUnit mom,
62  Units::LengthUnit len ) :
63  m_signal_process_id(signal_process_id),
64  m_event_number(event_number),
65  m_mpi(-1),
66  m_event_scale(-1),
67  m_alphaQCD(-1),
68  m_alphaQED(-1),
69  m_signal_process_vertex(signal_vertex),
70  m_beam_particle_1(0),
71  m_beam_particle_2(0),
72  m_weights(weights),
73  m_random_states(random_states),
74  m_vertex_barcodes(),
75  m_particle_barcodes(),
76  m_cross_section(0),
77  m_heavy_ion( new HeavyIon(ion) ),
78  m_pdf_info( new PdfInfo(pdf) ),
79  m_momentum_unit(mom),
80  m_position_unit(len)
81  {
86  }
87 
88  GenEvent::GenEvent( Units::MomentumUnit mom,
89  Units::LengthUnit len,
90  int signal_process_id,
91  int event_number,
92  GenVertex* signal_vertex,
93  const WeightContainer& weights,
94  const std::vector<long>& random_states ) :
95  m_signal_process_id(signal_process_id),
96  m_event_number(event_number),
97  m_mpi(-1),
98  m_event_scale(-1),
99  m_alphaQCD(-1),
100  m_alphaQED(-1),
101  m_signal_process_vertex(signal_vertex),
102  m_beam_particle_1(0),
103  m_beam_particle_2(0),
104  m_weights(weights),
105  m_random_states(random_states),
106  m_vertex_barcodes(),
107  m_particle_barcodes(),
108  m_cross_section(0),
109  m_heavy_ion(0),
110  m_pdf_info(0),
111  m_momentum_unit(mom),
112  m_position_unit(len)
113  {
120  }
121 
122  GenEvent::GenEvent( Units::MomentumUnit mom,
123  Units::LengthUnit len,
124  int signal_process_id, int event_number,
125  GenVertex* signal_vertex,
126  const WeightContainer& weights,
127  const std::vector<long>& random_states,
128  const HeavyIon& ion,
129  const PdfInfo& pdf ) :
130  m_signal_process_id(signal_process_id),
131  m_event_number(event_number),
132  m_mpi(-1),
133  m_event_scale(-1),
134  m_alphaQCD(-1),
135  m_alphaQED(-1),
136  m_signal_process_vertex(signal_vertex),
137  m_beam_particle_1(0),
138  m_beam_particle_2(0),
139  m_weights(weights),
140  m_random_states(random_states),
141  m_vertex_barcodes(),
142  m_particle_barcodes(),
143  m_cross_section(0),
144  m_heavy_ion( new HeavyIon(ion) ),
145  m_pdf_info( new PdfInfo(pdf) ),
146  m_momentum_unit(mom),
147  m_position_unit(len)
148  {
154  }
155 
156  GenEvent::GenEvent( const GenEvent& inevent )
157  : m_signal_process_id ( inevent.signal_process_id() ),
158  m_event_number ( inevent.event_number() ),
159  m_mpi ( inevent.mpi() ),
160  m_event_scale ( inevent.event_scale() ),
161  m_alphaQCD ( inevent.alphaQCD() ),
162  m_alphaQED ( inevent.alphaQED() ),
163  m_signal_process_vertex( /* inevent.m_signal_process_vertex */ ),
164  m_beam_particle_1 ( /* inevent.m_beam_particle_1 */ ),
165  m_beam_particle_2 ( /* inevent.m_beam_particle_2 */ ),
166  m_weights ( /* inevent.m_weights */ ),
167  m_random_states ( /* inevent.m_random_states */ ),
168  m_vertex_barcodes ( /* inevent.m_vertex_barcodes */ ),
169  m_particle_barcodes ( /* inevent.m_particle_barcodes */ ),
170  m_cross_section ( inevent.cross_section() ? new GenCrossSection(*inevent.cross_section()) : 0 ),
171  m_heavy_ion ( inevent.heavy_ion() ? new HeavyIon(*inevent.heavy_ion()) : 0 ),
172  m_pdf_info ( inevent.pdf_info() ? new PdfInfo(*inevent.pdf_info()) : 0 ),
173  m_momentum_unit ( inevent.momentum_unit() ),
174  m_position_unit ( inevent.length_unit() )
175  {
177  //
178 
179  // 1. create a NEW copy of all vertices from inevent
180  // taking care to map new vertices onto the vertices being copied
181  // and add these new vertices to this event.
182  // We do not use GenVertex::operator= because that would copy
183  // the attached particles as well.
184  std::map<const GenVertex*,GenVertex*> map_in_to_new;
186  v != inevent.vertices_end(); ++v ) {
187  GenVertex* newvertex = new GenVertex(
188  (*v)->position(), (*v)->id(), (*v)->weights() );
189  newvertex->suggest_barcode( (*v)->barcode() );
190  map_in_to_new[*v] = newvertex;
191  add_vertex( newvertex );
192  }
193  // 2. copy the signal process vertex info.
194  if ( inevent.signal_process_vertex() ) {
196  map_in_to_new[inevent.signal_process_vertex()] );
197  } else set_signal_process_vertex( 0 );
198  //
199  // 3. create a NEW copy of all particles from inevent
200  // taking care to attach them to the appropriate vertex
201  GenParticle* beam1(0);
202  GenParticle* beam2(0);
204  p != inevent.particles_end(); ++p )
205  {
206  GenParticle* oldparticle = *p;
207  GenParticle* newparticle = new GenParticle(*oldparticle);
208  if ( oldparticle->end_vertex() ) {
209  map_in_to_new[ oldparticle->end_vertex() ]->
210  add_particle_in(newparticle);
211  }
212  if ( oldparticle->production_vertex() ) {
213  map_in_to_new[ oldparticle->production_vertex() ]->
214  add_particle_out(newparticle);
215  }
216  if ( oldparticle == inevent.beam_particles().first ) beam1 = newparticle;
217  if ( oldparticle == inevent.beam_particles().second ) beam2 = newparticle;
218  }
219  set_beam_particles( beam1, beam2 );
220  //
221  // 4. now that vtx/particles are copied, copy weights and random states
222  set_random_states( inevent.random_states() );
223  weights() = inevent.weights();
224  }
225 
226  void GenEvent::swap( GenEvent & other )
227  {
228  // if a container has a swap method, use that for improved performance
229  std::swap(m_signal_process_id , other.m_signal_process_id );
230  std::swap(m_event_number , other.m_event_number );
231  std::swap(m_mpi , other.m_mpi );
232  std::swap(m_event_scale , other.m_event_scale );
233  std::swap(m_alphaQCD , other.m_alphaQCD );
234  std::swap(m_alphaQED , other.m_alphaQED );
235  std::swap(m_signal_process_vertex, other.m_signal_process_vertex);
236  std::swap(m_beam_particle_1 , other.m_beam_particle_1 );
237  std::swap(m_beam_particle_2 , other.m_beam_particle_2 );
238  m_weights.swap( other.m_weights );
239  m_random_states.swap( other.m_random_states );
240  m_vertex_barcodes.swap( other.m_vertex_barcodes );
241  m_particle_barcodes.swap( other.m_particle_barcodes );
242  std::swap(m_cross_section , other.m_cross_section );
243  std::swap(m_heavy_ion , other.m_heavy_ion );
244  std::swap(m_pdf_info , other.m_pdf_info );
245  std::swap(m_momentum_unit , other.m_momentum_unit );
246  std::swap(m_position_unit , other.m_position_unit );
247  // must now adjust GenVertex back pointers
249  vthis != vertices_end(); ++vthis ) {
250  (*vthis)->change_parent_event_( this );
251  }
252  for ( GenEvent::vertex_const_iterator voth = other.vertices_begin();
253  voth != other.vertices_end(); ++voth ) {
254  (*voth)->change_parent_event_( &other );
255  }
256  }
257 
259  {
264  delete m_cross_section;
265  delete m_heavy_ion;
266  delete m_pdf_info;
267  }
268 
270  {
272  GenEvent tmp( inevent );
273  swap( tmp );
274  return *this;
275  }
276 
277  void GenEvent::print( std::ostream& ostr ) const {
282  ostr << "________________________________________"
283  << "________________________________________\n";
284  ostr << "GenEvent: #" << event_number()
285  << " ID=" << signal_process_id()
286  << " SignalProcessGenVertex Barcode: "
288  : 0 )
289  << "\n";
290  write_units( ostr );
291  write_cross_section(ostr);
292  ostr << " Entries this event: " << vertices_size() << " vertices, "
293  << particles_size() << " particles.\n";
294  if( m_beam_particle_1 && m_beam_particle_2 ) {
295  ostr << " Beam Particle barcodes: " << beam_particles().first->barcode() << " "
296  << beam_particles().second->barcode() << " \n";
297  } else {
298  ostr << " Beam Particles are not defined.\n";
299  }
300  // Random State
301  ostr << " RndmState(" << m_random_states.size() << ")=";
302  for ( std::vector<long>::const_iterator rs
303  = m_random_states.begin();
304  rs != m_random_states.end(); ++rs ) { ostr << *rs << " "; }
305  ostr << "\n";
306  // Weights
307  ostr << " Wgts(" << weights().size() << ")=";
308  weights().print(ostr);
309  ostr << " EventScale " << event_scale()
310  << " [energy] \t alphaQCD=" << alphaQCD()
311  << "\t alphaQED=" << alphaQED() << std::endl;
312  // print a legend to describe the particle info
313  ostr << " GenParticle Legend\n";
314  ostr << " Barcode PDG ID "
315  << "( Px, Py, Pz, E )"
316  << " Stat DecayVtx\n";
317  ostr << "________________________________________"
318  << "________________________________________\n";
319  // Print all Vertices
321  vtx != this->vertices_end(); ++vtx ) {
322  (*vtx)->print(ostr);
323  }
324  ostr << "________________________________________"
325  << "________________________________________" << std::endl;
326  }
327 
328  void GenEvent::print_version( std::ostream& ostr ) const {
329  ostr << "---------------------------------------------" << std::endl;
330  writeVersion( ostr );
331  ostr << "---------------------------------------------" << std::endl;
332  }
333 
337  if ( !vtx ) return false;
338  // if vtx previously pointed to another GenEvent, remove it from that
339  // GenEvent's list
340  if ( vtx->parent_event() && vtx->parent_event() != this ) {
341  bool remove_status = vtx->parent_event()->remove_vertex( vtx );
342  if ( !remove_status ) {
343  std::cerr << "GenEvent::add_vertex ERROR "
344  << "GenVertex::parent_event points to \n"
345  << "an event that does not point back to the "
346  << "GenVertex. \n This probably indicates a deeper "
347  << "problem. " << std::endl;
348  }
349  }
350  //
351  // setting the vertex parent also inserts the vertex into this
352  // event
353  vtx->set_parent_event_( this );
354  return ( m_vertex_barcodes.count(vtx->barcode()) ? true : false );
355  }
356 
360  if ( m_signal_process_vertex == vtx ) m_signal_process_vertex = 0;
361  if ( vtx->parent_event() == this ) vtx->set_parent_event_( 0 );
362  return ( m_vertex_barcodes.count(vtx->barcode()) ? false : true );
363  }
364 
366  {
371  // remove existing objects and set pointers to null
372  delete m_cross_section;
373  m_cross_section = 0;
374  delete m_heavy_ion;
375  m_heavy_ion = 0;
376  delete m_pdf_info;
377  m_pdf_info = 0;
378  m_signal_process_id = 0;
379  m_beam_particle_1 = 0;
380  m_beam_particle_2 = 0;
381  m_event_number = 0;
382  m_mpi = -1;
383  m_event_scale = -1;
384  m_alphaQCD = -1;
385  m_alphaQED = -1;
386  m_weights = std::vector<double>();
387  m_random_states = std::vector<long>();
388  // resetting unit information
389  m_momentum_unit = Units::default_momentum_unit();
390  m_position_unit = Units::default_length_unit();
391  // error check just to be safe
392  if ( m_vertex_barcodes.size() != 0
393  || m_particle_barcodes.size() != 0 ) {
394  std::cerr << "GenEvent::clear() strange result ... \n"
395  << "either the particle and/or the vertex map isn't empty" << std::endl;
396  std::cerr << "Number vtx,particle the event after deleting = "
397  << m_vertex_barcodes.size() << " "
398  << m_particle_barcodes.size() << std::endl;
399  }
400  return;
401  }
402 
409 
410  // delete each vertex individually (this deletes particles as well)
411  while ( !vertices_empty() ) {
412  GenVertex* vtx = ( m_vertex_barcodes.begin() )->second;
413  m_vertex_barcodes.erase( m_vertex_barcodes.begin() );
414  delete vtx;
415  }
416  //
417  // Error checking:
418  if ( !vertices_empty() || ! particles_empty() ) {
419  std::cerr << "GenEvent::delete_all_vertices strange result ... "
420  << "after deleting all vertices, \nthe particle and "
421  << "vertex maps aren't empty.\n This probably "
422  << "indicates deeper problems or memory leak in the "
423  << "code." << std::endl;
424  std::cerr << "Number vtx,particle the event after deleting = "
425  << m_vertex_barcodes.size() << " "
426  << m_particle_barcodes.size() << std::endl;
427  }
428  }
429 
430  bool GenEvent::set_barcode( GenParticle* p, int suggested_barcode )
431  {
432  if ( p->parent_event() != this ) {
433  std::cerr << "GenEvent::set_barcode attempted, but the argument's"
434  << "\n parent_event is not this ... request rejected."
435  << std::endl;
436  return false;
437  }
438  // M.Dobbs Nov 4, 2002
439  // First we must check to see if the particle already has a
440  // barcode which is different from the suggestion. If yes, we
441  // remove it from the particle map.
442  if ( p->barcode() != 0 && p->barcode() != suggested_barcode ) {
443  if ( m_particle_barcodes.count(p->barcode()) &&
444  m_particle_barcodes[p->barcode()] == p ) {
445  m_particle_barcodes.erase( p->barcode() );
446  }
447  // At this point either the particle is NOT in
448  // m_particle_barcodes, or else it is in the map, but
449  // already with the suggested barcode.
450  }
451  //
452  // First case --- a valid barcode has been suggested
453  // (valid barcodes are numbers greater than zero)
454  bool insert_success = true;
455  if ( suggested_barcode > 0 ) {
456  if ( m_particle_barcodes.count(suggested_barcode) ) {
457  // the suggested_barcode is already used.
458  if ( m_particle_barcodes[suggested_barcode] == p ) {
459  // but it was used for this particle ... so everythings ok
460  p->set_barcode_( suggested_barcode );
461  return true;
462  }
463  insert_success = false;
464  suggested_barcode = 0;
465  } else { // suggested barcode is OK, proceed to insert
466  m_particle_barcodes[suggested_barcode] = p;
467  p->set_barcode_( suggested_barcode );
468  return true;
469  }
470  }
471  //
472  // Other possibility -- a valid barcode has not been suggested,
473  // so one is automatically generated
474  if ( suggested_barcode < 0 ) insert_success = false;
475  if ( suggested_barcode <= 0 ) {
476  if ( !m_particle_barcodes.empty() ) {
477  // in this case we find the highest barcode that was used,
478  // and increment it by 1
479  suggested_barcode = m_particle_barcodes.rbegin()->first;
480  ++suggested_barcode;
481  }
482  // For the automatically assigned barcodes, the first one
483  // we use is 10001 ... this is just because when we read
484  // events from HEPEVT, we will suggest their index as the
485  // barcode, and that index has maximum value 10000.
486  // This way we will immediately be able to recognize the hepevt
487  // particles from the auto-assigned ones.
488  if ( suggested_barcode <= 10000 ) suggested_barcode = 10001;
489  }
490  // At this point we should have a valid barcode
491  if ( m_particle_barcodes.count(suggested_barcode) ) {
492  std::cerr << "GenEvent::set_barcode ERROR, this should never "
493  << "happen \n report bug to matt.dobbs@cern.ch"
494  << std::endl;
495  }
496  m_particle_barcodes[suggested_barcode] = p;
497  p->set_barcode_( suggested_barcode );
498  return insert_success;
499  }
500 
501  bool GenEvent::set_barcode( GenVertex* v, int suggested_barcode )
502  {
503  if ( v->parent_event() != this ) {
504  std::cerr << "GenEvent::set_barcode attempted, but the argument's"
505  << "\n parent_event is not this ... request rejected."
506  << std::endl;
507  return false;
508  }
509  // M.Dobbs Nov 4, 2002
510  // First we must check to see if the vertex already has a
511  // barcode which is different from the suggestion. If yes, we
512  // remove it from the vertex map.
513  if ( v->barcode() != 0 && v->barcode() != suggested_barcode ) {
514  if ( m_vertex_barcodes.count(v->barcode()) &&
515  m_vertex_barcodes[v->barcode()] == v ) {
516  m_vertex_barcodes.erase( v->barcode() );
517  }
518  // At this point either the vertex is NOT in
519  // m_vertex_barcodes, or else it is in the map, but
520  // already with the suggested barcode.
521  }
522 
523  //
524  // First case --- a valid barcode has been suggested
525  // (valid barcodes are numbers greater than zero)
526  bool insert_success = true;
527  if ( suggested_barcode < 0 ) {
528  if ( m_vertex_barcodes.count(suggested_barcode) ) {
529  // the suggested_barcode is already used.
530  if ( m_vertex_barcodes[suggested_barcode] == v ) {
531  // but it was used for this vertex ... so everythings ok
532  v->set_barcode_( suggested_barcode );
533  return true;
534  }
535  insert_success = false;
536  suggested_barcode = 0;
537  } else { // suggested barcode is OK, proceed to insert
538  m_vertex_barcodes[suggested_barcode] = v;
539  v->set_barcode_( suggested_barcode );
540  return true;
541  }
542  }
543  //
544  // Other possibility -- a valid barcode has not been suggested,
545  // so one is automatically generated
546  if ( suggested_barcode > 0 ) insert_success = false;
547  if ( suggested_barcode >= 0 ) {
548  if ( !m_vertex_barcodes.empty() ) {
549  // in this case we find the highest barcode that was used,
550  // and increment it by 1, (vertex barcodes are negative)
551  suggested_barcode = m_vertex_barcodes.rbegin()->first;
552  --suggested_barcode;
553  }
554  if ( suggested_barcode >= 0 ) suggested_barcode = -1;
555  }
556  // At this point we should have a valid barcode
557  if ( m_vertex_barcodes.count(suggested_barcode) ) {
558  std::cerr << "GenEvent::set_barcode ERROR, this should never "
559  << "happen \n report bug to matt.dobbs@cern.ch"
560  << std::endl;
561  }
562  m_vertex_barcodes[suggested_barcode] = v;
563  v->set_barcode_( suggested_barcode );
564  return insert_success;
565  }
566 
569  bool have1 = false;
570  bool have2 = false;
571  // first check that both are defined
572  if(m_beam_particle_1 && m_beam_particle_2) {
573  // now look for a match with the particle "list"
575  p != particles_end(); ++p ) {
576  if( m_beam_particle_1 == *p ) have1 = true;
577  if( m_beam_particle_2 == *p ) have2 = true;
578  }
579  }
580  if( have1 && have2 ) return true;
581  return false;
582  }
583 
587  m_beam_particle_1 = bp1;
588  m_beam_particle_2 = bp2;
589  if( m_beam_particle_1 && m_beam_particle_2 ) return true;
590  return false;
591  }
592 
595  bool GenEvent::set_beam_particles(std::pair<HepMC::GenParticle*, HepMC::GenParticle*> const & bp) {
596  return set_beam_particles(bp.first,bp.second);
597  }
598 
599  void GenEvent::write_units( std::ostream & os ) const {
600  os << " Momenutm units:" << std::setw(8) << name(momentum_unit());
601  os << " Position units:" << std::setw(8) << name(length_unit());
602  os << std::endl;
603  }
604 
605  void GenEvent::write_cross_section( std::ostream& os ) const
606  {
607  // write the GenCrossSection information if the cross section was set
608  if( !cross_section() ) return;
609  if( cross_section()->is_set() ) {
610  os << " Cross Section: " << cross_section()->cross_section() ;
611  os << " +/- " << cross_section()->cross_section_error() ;
612  os << std::endl;
613  }
614  }
615 
616  bool GenEvent::use_momentum_unit( Units::MomentumUnit newunit ) {
617  // currently not exception-safe.
618  // Easy to fix, though, if needed.
619  if ( m_momentum_unit != newunit ) {
620  const double factor = Units::conversion_factor( m_momentum_unit, newunit );
621  // multiply all momenta by 'factor',
622  // loop is entered only if particle list is not empty
624  p != particles_end(); ++p )
625  {
626  (*p)->convert_momentum(factor);
627  }
628  // ...
629  m_momentum_unit = newunit;
630  }
631  return true;
632  }
633 
634  bool GenEvent::use_length_unit( Units::LengthUnit newunit ) {
635  // currently not exception-safe.
636  // Easy to fix, though, if needed.
637  if ( m_position_unit != newunit ) {
638  const double factor = Units::conversion_factor( m_position_unit, newunit );
639  // multiply all lengths by 'factor',
640  // loop is entered only if vertex list is not empty
641  for ( GenEvent::vertex_iterator vtx = vertices_begin();
642  vtx != vertices_end(); ++vtx ) {
643  (*vtx)->convert_position(factor);
644  }
645  // ...
646  m_position_unit = newunit;
647  }
648  return true;
649  }
650 
651  bool GenEvent::use_momentum_unit( std::string& newunit ) {
652  if ( newunit == "MEV" ) return use_momentum_unit( Units::MEV );
653  else if( newunit == "GEV" ) return use_momentum_unit( Units::GEV );
654  else std::cerr << "GenEvent::use_momentum_unit ERROR: use either MEV or GEV\n";
655  return false;
656  }
657 
658  bool GenEvent::use_length_unit( std::string& newunit ) {
659  if ( newunit == "MM" ) return use_length_unit( Units::MM );
660  else if( newunit == "CM" ) return use_length_unit( Units::CM );
661  else std::cerr << "GenEvent::use_length_unit ERROR: use either MM or CM\n";
662  return false;
663  }
664 
665  void GenEvent::define_units( std::string& new_m, std::string& new_l ) {
666 
667  if ( new_m == "MEV" ) m_momentum_unit = Units::MEV ;
668  else if( new_m == "GEV" ) m_momentum_unit = Units::GEV ;
669  else std::cerr << "GenEvent::define_units ERROR: use either MEV or GEV\n";
670 
671  if ( new_l == "MM" ) m_position_unit = Units::MM ;
672  else if( new_l == "CM" ) m_position_unit = Units::CM ;
673  else std::cerr << "GenEvent::define_units ERROR: use either MM or CM\n";
674 
675  }
676 
677  bool GenEvent::is_valid() const {
680  if ( vertices_empty() ) return false;
681  if ( particles_empty() ) return false;
682  return true;
683  }
684 
685  std::ostream & GenEvent::write_beam_particles(std::ostream & os,
686  std::pair<HepMC::GenParticle *,HepMC::GenParticle *> pr )
687  {
688  GenParticle* p = pr.first;
689  if(!p) {
690  detail::output( os, 0 );
691  } else {
692  detail::output( os, p->barcode() );
693  }
694  p = pr.second;
695  if(!p) {
696  detail::output( os, 0 );
697  } else {
698  detail::output( os, p->barcode() );
699  }
700 
701  return os;
702  }
703 
704  std::ostream & GenEvent::write_vertex(std::ostream & os, GenVertex const * v)
705  {
706  if ( !v || !os ) {
707  std::cerr << "GenEvent::write_vertex !v||!os, "
708  << "v="<< v << " setting badbit" << std::endl;
709  os.clear(std::ios::badbit);
710  return os;
711  }
712  // First collect info we need
713  // count the number of orphan particles going into v
714  int num_orphans_in = 0;
716  = v->particles_in_const_begin();
717  p1 != v->particles_in_const_end(); ++p1 ) {
718  if ( !(*p1)->production_vertex() ) ++num_orphans_in;
719  }
720  //
721  os << 'V';
722  detail::output( os, v->barcode() ); // v's unique identifier
723  detail::output( os, v->id() );
724  detail::output( os, v->position().x() );
725  detail::output( os, v->position().y() );
726  detail::output( os, v->position().z() );
727  detail::output( os, v->position().t() );
728  detail::output( os, num_orphans_in );
729  detail::output( os, (int)v->particles_out_size() );
730  detail::output( os, (int)v->weights().size() );
731  for ( WeightContainer::const_iterator w = v->weights().begin();
732  w != v->weights().end(); ++w ) {
733  detail::output( os, *w );
734  }
735  detail::output( os,'\n');
736  // incoming particles
738  = v->particles_in_const_begin();
739  p2 != v->particles_in_const_end(); ++p2 ) {
740  if ( !(*p2)->production_vertex() ) {
741  write_particle( os, *p2 );
742  }
743  }
744  // outgoing particles
746  = v->particles_out_const_begin();
747  p3 != v->particles_out_const_end(); ++p3 ) {
748  write_particle( os, *p3 );
749  }
750  return os;
751  }
752 
753  std::ostream & GenEvent::write_particle( std::ostream & os, GenParticle const * p )
754  {
755  if ( !p || !os ) {
756  std::cerr << "GenEvent::write_particle !p||!os, "
757  << "p="<< p << " setting badbit" << std::endl;
758  os.clear(std::ios::badbit);
759  return os;
760  }
761  os << 'P';
762  detail::output( os, p->barcode() );
763  detail::output( os, p->pdg_id() );
764  detail::output( os, p->momentum().px() );
765  detail::output( os, p->momentum().py() );
766  detail::output( os, p->momentum().pz() );
767  detail::output( os, p->momentum().e() );
768  detail::output( os, p->generated_mass() );
769  detail::output( os, p->status() );
770  detail::output( os, p->polarization().theta() );
771  detail::output( os, p->polarization().phi() );
772  // since end_vertex is oftentimes null, this CREATES a null vertex
773  // in the map
774  detail::output( os, ( p->end_vertex() ? p->end_vertex()->barcode() : 0 ) );
775  os << ' ' << p->flow() << "\n";
776 
777  return os;
778  }
779 
780 } // HepMC
bool remove_vertex(GenVertex *vtx)
erases vtx from evt
Definition: GenEvent.cc:357
GenEvent * parent_event() const
pointer to the event that owns this particle
Definition: GenParticle.cc:123
void writeVersion(std::ostream &os)
write HepMC version to os
Definition: Version.h:33
bool particles_empty() const
return true if there are no particle barcodes
Definition: GenEvent.h:833
void print(std::ostream &ostr=std::cout) const
print weights
bool vertices_empty() const
return true if there are no vertex barcodes
Definition: GenEvent.h:839
int barcode() const
unique identifier
Definition: GenVertex.h:416
std::vector< HepMC::GenParticle * >::const_iterator particles_in_const_iterator
const iterator for incoming particles
Definition: GenVertex.h:152
The GenCrossSection class stores the generated cross section.
bool is_valid() const
Definition: GenEvent.cc:677
bool set_barcode(GenParticle *p, int suggested_barcode=false)
set the barcode - intended for use by GenParticle
Definition: GenEvent.cc:430
void set_signal_process_vertex(GenVertex *)
set pointer to the vertex containing the signal process
Definition: GenEvent.h:747
const particle iterator
Definition: GenEvent.h:464
int particles_size() const
how many particle barcodes exist?
Definition: GenEvent.h:830
int barcode() const
particle barcode
Definition: GenParticle.h:252
particle_const_iterator particles_begin() const
begin particle iteration
Definition: GenEvent.h:507
std::vector< HepMC::GenParticle * >::const_iterator particles_out_const_iterator
const iterator for outgoing particles
Definition: GenVertex.h:155
bool suggest_barcode(int the_bar_code)
In general there is no reason to &quot;suggest_barcode&quot;.
Definition: GenVertex.cc:363
non-const particle iterator
Definition: GenEvent.h:520
std::pair< HepMC::GenParticle *, HepMC::GenParticle * > beam_particles() const
pair of pointers to the two incoming beam particles
Definition: GenEvent.h:844
void delete_all_vertices()
delete all vertices owned by this event
Definition: GenEvent.cc:403
GenCrossSection const * cross_section() const
access the GenCrossSection container if it exists
Definition: GenEvent.h:704
GenVertex * production_vertex() const
pointer to the production vertex
Definition: GenParticle.h:218
void set_barcode_(int the_bar_code)
set identifier
Definition: GenVertex.h:417
GenVertex contains information about decay vertices.
Definition: GenVertex.h:52
std::vector< double >::const_iterator const_iterator
const iterator for the weight container
void write_units(std::ostream &os=std::cout) const
Definition: GenEvent.cc:599
double alphaQED() const
Definition: GenEvent.h:692
The GenEvent class is the core of HepMC.
Definition: GenEvent.h:155
GenVertex * signal_process_vertex() const
pointer to the vertex containing the signal process
Definition: GenEvent.h:694
Units::MomentumUnit momentum_unit() const
Units used by the GenParticle momentum FourVector.
Definition: GenEvent.h:849
void swap(GenEvent &other)
swap
Definition: GenEvent.cc:226
void set_random_states(const std::vector< long > &randomstates)
provide random state information
Definition: GenEvent.h:770
GenEvent(int signal_process_id=0, int event_number=0, GenVertex *signal_vertex=0, const WeightContainer &weights=std::vector< double >(), const std::vector< long > &randomstates=std::vector< long >(), Units::MomentumUnit=Units::default_momentum_unit(), Units::LengthUnit=Units::default_length_unit())
default constructor creates null pointers to HeavyIon, PdfInfo, and GenCrossSection ...
Definition: GenEvent.cc:22
bool add_vertex(GenVertex *vtx)
adds to evt and adopts
Definition: GenEvent.cc:334
void print_version(std::ostream &ostr=std::cout) const
dumps release version to ostr
Definition: GenEvent.cc:328
vertex_const_iterator vertices_end() const
end vertex iteration
Definition: GenEvent.h:381
void set_barcode_(int the_bar_code)
for use by GenEvent only
Definition: GenParticle.h:254
WeightContainer & weights()
direct access to WeightContainer
Definition: GenEvent.h:699
void write_cross_section(std::ostream &ostr=std::cout) const
Definition: GenEvent.cc:605
int vertices_size() const
how many vertex barcodes exist?
Definition: GenEvent.h:836
bool valid_beam_particles() const
test to see if we have two valid beam particles
Definition: GenEvent.cc:568
GenEvent * parent_event() const
pointer to the event that owns this vertex
Definition: GenVertex.h:408
bool set_beam_particles(GenParticle *, GenParticle *)
set incoming beam particles
Definition: GenEvent.cc:586
double cross_section_error() const
error associated with this cross section in pb
double cross_section() const
cross section in pb
void print(std::ostream &ostr=std::cout) const
dumps to ostr
Definition: GenEvent.cc:277
void clear()
empties the entire event
Definition: GenEvent.cc:365
particle_const_iterator particles_end() const
end particle iteration
Definition: GenEvent.h:511
void define_units(Units::MomentumUnit, Units::LengthUnit)
Definition: GenEvent.h:866
GenEvent & operator=(const GenEvent &inevent)
make a deep copy
Definition: GenEvent.cc:269
void set_parent_event_(GenEvent *evt)
set parent event
Definition: GenVertex.cc:388
vertex_const_iterator vertices_begin() const
begin vertex iteration
Definition: GenEvent.h:377
GenVertex * end_vertex() const
pointer to the decay vertex
Definition: GenParticle.h:221
int event_number() const
event number
Definition: GenEvent.h:682
int signal_process_id() const
unique signal process id
Definition: GenEvent.h:679
The HeavyIon class stores information about heavy ions.
Definition: HeavyIon.h:45
Container for the Weights associated with an event or vertex.
void swap(WeightContainer &other)
swap
const std::vector< long > & random_states() const
vector of integers containing information about the random state
Definition: GenEvent.h:727
virtual ~GenEvent()
deletes all vertices/particles in this evt
Definition: GenEvent.cc:258
double event_scale() const
energy scale, see hep-ph/0109068
Definition: GenEvent.h:688
size_type size() const
size of weight container
The GenParticle class contains information about generated particles.
Definition: GenParticle.h:60
double alphaQCD() const
QCD coupling, see hep-ph/0109068.
Definition: GenEvent.h:690
The PdfInfo class stores PDF information.
Definition: PdfInfo.h:37
Units::LengthUnit length_unit() const
Units used by the GenVertex position FourVector.
Definition: GenEvent.h:852