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 <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         weights().print(ostr);
00309         ostr << " EventScale " << event_scale() 
00310              << " [energy] \t alphaQCD=" << alphaQCD() 
00311              << "\t alphaQED=" << alphaQED() << std::endl;
00312         // print a legend to describe the particle info
00313         ostr << "                                    GenParticle Legend\n";
00314         ostr  << "        Barcode   PDG ID      "
00315               << "( Px,       Py,       Pz,     E )"
00316               << " Stat  DecayVtx\n";
00317         ostr << "________________________________________"
00318              << "________________________________________\n";
00319         // Print all Vertices
00320         for ( GenEvent::vertex_const_iterator vtx = this->vertices_begin();
00321               vtx != this->vertices_end(); ++vtx ) {
00322             (*vtx)->print(ostr); 
00323         }
00324         ostr << "________________________________________"
00325              << "________________________________________" << std::endl;
00326     }
00327 
00328     void GenEvent::print_version( std::ostream& ostr ) const {
00329         ostr << "---------------------------------------------" << std::endl;
00330         writeVersion( ostr );
00331         ostr << "---------------------------------------------" << std::endl;
00332     }
00333 
00334     bool GenEvent::add_vertex( GenVertex* vtx ) {
00337         if ( !vtx ) return false;
00338         // if vtx previously pointed to another GenEvent, remove it from that
00339         // GenEvent's list
00340         if ( vtx->parent_event() && vtx->parent_event() != this ) {
00341             bool remove_status = vtx->parent_event()->remove_vertex( vtx );
00342             if ( !remove_status ) {            
00343                 std::cerr << "GenEvent::add_vertex ERROR "
00344                           << "GenVertex::parent_event points to \n"
00345                           << "an event that does not point back to the "
00346                           << "GenVertex. \n This probably indicates a deeper "
00347                           << "problem. " << std::endl;
00348             }
00349         }
00350         //
00351         // setting the vertex parent also inserts the vertex into this
00352         // event
00353         vtx->set_parent_event_( this );
00354         return ( m_vertex_barcodes.count(vtx->barcode()) ? true : false );
00355     }
00356 
00357     bool GenEvent::remove_vertex( GenVertex* vtx ) {
00360         if ( m_signal_process_vertex == vtx ) m_signal_process_vertex = 0;
00361         if ( vtx->parent_event() == this ) vtx->set_parent_event_( 0 );
00362         return ( m_vertex_barcodes.count(vtx->barcode()) ? false : true );
00363     }
00364 
00365     void GenEvent::clear() 
00366     {
00370         delete_all_vertices();
00371         // remove existing objects and set pointers to null
00372         delete m_cross_section;
00373         m_cross_section = 0;
00374         delete m_heavy_ion;
00375         m_heavy_ion = 0;
00376         delete m_pdf_info;
00377         m_pdf_info = 0;
00378         m_signal_process_id = 0;
00379         m_beam_particle_1 = 0;
00380         m_beam_particle_2 = 0;
00381         m_event_number = 0;
00382         m_mpi = -1;
00383         m_event_scale = -1;
00384         m_alphaQCD = -1;
00385         m_alphaQED = -1;
00386         m_weights = std::vector<double>();
00387         m_random_states = std::vector<long>();
00388         // resetting unit information
00389         m_momentum_unit = Units::default_momentum_unit();
00390         m_position_unit = Units::default_length_unit();
00391         // error check just to be safe
00392         if ( m_vertex_barcodes.size() != 0 
00393              || m_particle_barcodes.size() != 0 ) {
00394             std::cerr << "GenEvent::clear() strange result ... \n"
00395                       << "either the particle and/or the vertex map isn't empty" << std::endl;
00396             std::cerr << "Number vtx,particle the event after deleting = "
00397                       << m_vertex_barcodes.size() << "  " 
00398                       << m_particle_barcodes.size() << std::endl;
00399         }
00400         return;
00401     }
00402     
00403     void GenEvent::delete_all_vertices() {
00409 
00410         // delete each vertex individually (this deletes particles as well)
00411         while ( !vertices_empty() ) {
00412             GenVertex* vtx = ( m_vertex_barcodes.begin() )->second;
00413             m_vertex_barcodes.erase( m_vertex_barcodes.begin() );
00414             delete vtx;
00415         }
00416         //
00417         // Error checking:
00418         if ( !vertices_empty() || ! particles_empty() ) {
00419             std::cerr << "GenEvent::delete_all_vertices strange result ... "
00420                       << "after deleting all vertices, \nthe particle and "
00421                       << "vertex maps aren't empty.\n  This probably " 
00422                       << "indicates deeper problems or memory leak in the "
00423                       << "code." << std::endl;
00424             std::cerr << "Number vtx,particle the event after deleting = "
00425                       << m_vertex_barcodes.size() << "  " 
00426                       << m_particle_barcodes.size() << std::endl;
00427         }
00428     }
00429     
00430     bool GenEvent::set_barcode( GenParticle* p, int suggested_barcode )
00431     {
00432         if ( p->parent_event() != this ) {
00433             std::cerr << "GenEvent::set_barcode attempted, but the argument's"
00434                       << "\n parent_event is not this ... request rejected."
00435                       << std::endl;
00436             return false;
00437         }
00438         // M.Dobbs  Nov 4, 2002
00439         // First we must check to see if the particle already has a
00440         // barcode which is different from the suggestion. If yes, we
00441         // remove it from the particle map.
00442         if ( p->barcode() != 0 && p->barcode() != suggested_barcode ) {
00443             if ( m_particle_barcodes.count(p->barcode()) &&
00444                  m_particle_barcodes[p->barcode()] == p ) {
00445                 m_particle_barcodes.erase( p->barcode() );
00446             }
00447             // At this point either the particle is NOT in
00448             // m_particle_barcodes, or else it is in the map, but
00449             // already with the suggested barcode.
00450         }
00451         //
00452         // First case --- a valid barcode has been suggested
00453         //     (valid barcodes are numbers greater than zero)
00454         bool insert_success = true;
00455         if ( suggested_barcode > 0 ) {
00456             if ( m_particle_barcodes.count(suggested_barcode) ) {
00457                 // the suggested_barcode is already used.
00458                 if ( m_particle_barcodes[suggested_barcode] == p ) {
00459                     // but it was used for this particle ... so everythings ok
00460                     p->set_barcode_( suggested_barcode );
00461                     return true;
00462                 }
00463                 insert_success = false;
00464                 suggested_barcode = 0;
00465             } else { // suggested barcode is OK, proceed to insert
00466                 m_particle_barcodes[suggested_barcode] = p;
00467                 p->set_barcode_( suggested_barcode );
00468                 return true;
00469             }
00470         }
00471         //
00472         // Other possibility -- a valid barcode has not been suggested,
00473         //    so one is automatically generated
00474         if ( suggested_barcode < 0 ) insert_success = false;
00475         if ( suggested_barcode <= 0 ) {
00476             if ( !m_particle_barcodes.empty() ) {
00477                 // in this case we find the highest barcode that was used,
00478                 // and increment it by 1
00479                 suggested_barcode = m_particle_barcodes.rbegin()->first;
00480                 ++suggested_barcode;
00481             }
00482             // For the automatically assigned barcodes, the first one
00483             //   we use is 10001 ... this is just because when we read 
00484             //   events from HEPEVT, we will suggest their index as the
00485             //   barcode, and that index has maximum value 10000.
00486             //  This way we will immediately be able to recognize the hepevt
00487             //   particles from the auto-assigned ones.
00488             if ( suggested_barcode <= 10000 ) suggested_barcode = 10001;
00489         }
00490         // At this point we should have a valid barcode
00491         if ( m_particle_barcodes.count(suggested_barcode) ) {
00492             std::cerr << "GenEvent::set_barcode ERROR, this should never "
00493                       << "happen \n report bug to matt.dobbs@cern.ch" 
00494                       << std::endl;
00495         }
00496         m_particle_barcodes[suggested_barcode] = p;
00497         p->set_barcode_( suggested_barcode );
00498         return insert_success;
00499     }
00500 
00501     bool GenEvent::set_barcode( GenVertex* v, int suggested_barcode )
00502     {
00503         if ( v->parent_event() != this ) {
00504             std::cerr << "GenEvent::set_barcode attempted, but the argument's"
00505                       << "\n parent_event is not this ... request rejected."
00506                       << std::endl;
00507             return false;
00508         }
00509         // M.Dobbs Nov 4, 2002
00510         // First we must check to see if the vertex already has a
00511         // barcode which is different from the suggestion. If yes, we
00512         // remove it from the vertex map.
00513         if ( v->barcode() != 0 && v->barcode() != suggested_barcode ) {
00514             if ( m_vertex_barcodes.count(v->barcode()) &&
00515                  m_vertex_barcodes[v->barcode()] == v ) {
00516                 m_vertex_barcodes.erase( v->barcode() );
00517             }
00518             // At this point either the vertex is NOT in
00519             // m_vertex_barcodes, or else it is in the map, but
00520             // already with the suggested barcode.
00521         }
00522         
00523         //
00524         // First case --- a valid barcode has been suggested
00525         //     (valid barcodes are numbers greater than zero)
00526         bool insert_success = true;
00527         if ( suggested_barcode < 0 ) {
00528             if ( m_vertex_barcodes.count(suggested_barcode) ) {
00529                 // the suggested_barcode is already used.
00530                 if ( m_vertex_barcodes[suggested_barcode] == v ) {
00531                     // but it was used for this vertex ... so everythings ok
00532                     v->set_barcode_( suggested_barcode );
00533                     return true;
00534                 }
00535                 insert_success = false;
00536                 suggested_barcode = 0;
00537             } else { // suggested barcode is OK, proceed to insert
00538                 m_vertex_barcodes[suggested_barcode] = v;
00539                 v->set_barcode_( suggested_barcode );
00540                 return true;
00541             }
00542         }
00543         //
00544         // Other possibility -- a valid barcode has not been suggested,
00545         //    so one is automatically generated
00546         if ( suggested_barcode > 0 ) insert_success = false;
00547         if ( suggested_barcode >= 0 ) {
00548             if ( !m_vertex_barcodes.empty() ) {
00549                 // in this case we find the highest barcode that was used,
00550                 // and increment it by 1, (vertex barcodes are negative)
00551                 suggested_barcode = m_vertex_barcodes.rbegin()->first;
00552                 --suggested_barcode;
00553             }
00554             if ( suggested_barcode >= 0 ) suggested_barcode = -1;
00555         }
00556         // At this point we should have a valid barcode
00557         if ( m_vertex_barcodes.count(suggested_barcode) ) {
00558             std::cerr << "GenEvent::set_barcode ERROR, this should never "
00559                       << "happen \n report bug to matt.dobbs@cern.ch" 
00560                       << std::endl;
00561         }
00562         m_vertex_barcodes[suggested_barcode] = v;
00563         v->set_barcode_( suggested_barcode );
00564         return insert_success;
00565     }
00566 
00568     bool  GenEvent::valid_beam_particles() const {
00569         bool have1 = false;
00570         bool have2 = false;
00571         // first check that both are defined
00572         if(m_beam_particle_1 && m_beam_particle_2) {
00573             // now look for a match with the particle "list"
00574             for ( particle_const_iterator p = particles_begin();
00575                   p != particles_end(); ++p ) {
00576                 if( m_beam_particle_1 == *p ) have1 = true;
00577                 if( m_beam_particle_2 == *p ) have2 = true;
00578             }
00579         }
00580         if( have1 && have2 ) return true;
00581         return false;
00582     }
00583     
00586     bool  GenEvent::set_beam_particles(GenParticle* bp1, GenParticle* bp2) {
00587         m_beam_particle_1 = bp1;
00588         m_beam_particle_2 = bp2;
00589         if( m_beam_particle_1 && m_beam_particle_2 ) return true;
00590         return false;
00591     }
00592 
00595     bool  GenEvent::set_beam_particles(std::pair<HepMC::GenParticle*, HepMC::GenParticle*> const & bp) {
00596         return set_beam_particles(bp.first,bp.second);
00597     }
00598 
00599     void GenEvent::write_units( std::ostream & os ) const {
00600         os << " Momenutm units:" << std::setw(8) << name(momentum_unit());
00601         os << "     Position units:" << std::setw(8) << name(length_unit());
00602         os << std::endl;
00603     }
00604 
00605     void GenEvent::write_cross_section( std::ostream& os ) const
00606     {
00607         // write the GenCrossSection information if the cross section was set
00608         if( !cross_section() ) return;
00609         if( cross_section()->is_set() ) {
00610             os << " Cross Section: " << cross_section()->cross_section() ;
00611             os << " +/- " << cross_section()->cross_section_error() ;
00612             os << std::endl;
00613         }
00614     }
00615 
00616    bool GenEvent::use_momentum_unit( Units::MomentumUnit newunit ) { 
00617         // currently not exception-safe. 
00618         // Easy to fix, though, if needed.
00619         if ( m_momentum_unit != newunit ) { 
00620             const double factor = Units::conversion_factor( m_momentum_unit, newunit );
00621             // multiply all momenta by 'factor',  
00622             // loop is entered only if particle list is not empty
00623             for ( GenEvent::particle_iterator p = particles_begin();
00624                                               p != particles_end(); ++p ) 
00625             {
00626                 (*p)->convert_momentum(factor);
00627             }
00628             // ... 
00629             m_momentum_unit = newunit; 
00630         }
00631         return true; 
00632     }
00633     
00634     bool GenEvent::use_length_unit( Units::LengthUnit newunit ) { 
00635         // currently not exception-safe. 
00636         // Easy to fix, though, if needed.
00637         if ( m_position_unit != newunit ) { 
00638             const double factor = Units::conversion_factor( m_position_unit, newunit );
00639             // multiply all lengths by 'factor', 
00640             // loop is entered only if vertex list is not empty
00641             for ( GenEvent::vertex_iterator vtx = vertices_begin();
00642                                             vtx != vertices_end(); ++vtx ) {
00643                 (*vtx)->convert_position(factor);
00644             }
00645             // ... 
00646             m_position_unit = newunit; 
00647         } 
00648         return true; 
00649     }  
00650 
00651     bool GenEvent::use_momentum_unit( std::string& newunit ) { 
00652         if     ( newunit == "MEV" ) return use_momentum_unit( Units::MEV );
00653         else if( newunit == "GEV" ) return use_momentum_unit( Units::GEV );
00654         else std::cerr << "GenEvent::use_momentum_unit ERROR: use either MEV or GEV\n";
00655         return false;
00656     }
00657     
00658     bool GenEvent::use_length_unit( std::string& newunit ) { 
00659         if     ( newunit == "MM" ) return use_length_unit( Units::MM );
00660         else if( newunit == "CM" ) return use_length_unit( Units::CM );
00661         else std::cerr << "GenEvent::use_length_unit ERROR: use either MM or CM\n";
00662         return false;
00663     }  
00664     
00665     void GenEvent::define_units( std::string& new_m, std::string& new_l ) { 
00666 
00667         if     ( new_m == "MEV" ) m_momentum_unit = Units::MEV ;
00668         else if( new_m == "GEV" ) m_momentum_unit = Units::GEV ;
00669         else std::cerr << "GenEvent::define_units ERROR: use either MEV or GEV\n";
00670 
00671         if     ( new_l == "MM" ) m_position_unit = Units::MM ;
00672         else if( new_l == "CM" ) m_position_unit = Units::CM ;
00673         else std::cerr << "GenEvent::define_units ERROR: use either MM or CM\n";
00674 
00675     }
00676 
00677     bool GenEvent::is_valid() const {
00680         if ( vertices_empty() ) return false;
00681         if ( particles_empty() ) return false;
00682         return true;
00683     }
00684 
00685     std::ostream & GenEvent::write_beam_particles(std::ostream & os, 
00686                          std::pair<HepMC::GenParticle *,HepMC::GenParticle *> pr )
00687     {
00688         GenParticle* p = pr.first;
00689         if(!p) {
00690            detail::output( os, 0 );
00691         } else {
00692            detail::output( os, p->barcode() );
00693         }
00694         p = pr.second;
00695         if(!p) {
00696            detail::output( os, 0 );
00697         } else {
00698            detail::output( os, p->barcode() );
00699         }
00700 
00701         return os;
00702     }
00703 
00704     std::ostream & GenEvent::write_vertex(std::ostream & os, GenVertex const * v)
00705     {
00706         if ( !v || !os ) {
00707             std::cerr << "GenEvent::write_vertex !v||!os, "
00708                       << "v="<< v << " setting badbit" << std::endl;
00709             os.clear(std::ios::badbit); 
00710             return os;
00711         }
00712         // First collect info we need
00713         // count the number of orphan particles going into v
00714         int num_orphans_in = 0;
00715         for ( GenVertex::particles_in_const_iterator p1
00716                   = v->particles_in_const_begin();
00717               p1 != v->particles_in_const_end(); ++p1 ) {
00718             if ( !(*p1)->production_vertex() ) ++num_orphans_in;
00719         }
00720         //
00721         os << 'V';
00722         detail::output( os, v->barcode() ); // v's unique identifier
00723         detail::output( os, v->id() );
00724         detail::output( os, v->position().x() );
00725         detail::output( os, v->position().y() );
00726         detail::output( os, v->position().z() );
00727         detail::output( os, v->position().t() );
00728         detail::output( os, num_orphans_in );
00729         detail::output( os, (int)v->particles_out_size() );
00730         detail::output( os, (int)v->weights().size() );
00731         for ( WeightContainer::const_iterator w = v->weights().begin(); 
00732               w != v->weights().end(); ++w ) {
00733             detail::output( os, *w );
00734         }
00735         detail::output( os,'\n');
00736         // incoming particles
00737         for ( GenVertex::particles_in_const_iterator p2 
00738                   = v->particles_in_const_begin();
00739               p2 != v->particles_in_const_end(); ++p2 ) {
00740             if ( !(*p2)->production_vertex() ) {
00741                 write_particle( os, *p2 );
00742             }
00743         }
00744         // outgoing particles
00745         for ( GenVertex::particles_out_const_iterator p3 
00746                   = v->particles_out_const_begin();
00747               p3 != v->particles_out_const_end(); ++p3 ) {
00748             write_particle( os, *p3 );
00749         }
00750         return os;
00751     }
00752 
00753     std::ostream & GenEvent::write_particle( std::ostream & os, GenParticle const * p )
00754     {
00755         if ( !p || !os ) {
00756             std::cerr << "GenEvent::write_particle !p||!os, "
00757                       << "p="<< p << " setting badbit" << std::endl;
00758             os.clear(std::ios::badbit); 
00759             return os;
00760         }
00761         os << 'P';
00762         detail::output( os, p->barcode() );
00763         detail::output( os, p->pdg_id() );
00764         detail::output( os, p->momentum().px() );
00765         detail::output( os, p->momentum().py() );
00766         detail::output( os, p->momentum().pz() );
00767         detail::output( os, p->momentum().e() );
00768         detail::output( os, p->generated_mass() );
00769         detail::output( os, p->status() );
00770         detail::output( os, p->polarization().theta() );
00771         detail::output( os, p->polarization().phi() );
00772         // since end_vertex is oftentimes null, this CREATES a null vertex
00773         // in the map
00774         detail::output( os,   ( p->end_vertex() ? p->end_vertex()->barcode() : 0 )  );
00775         os << ' ' << p->flow() << "\n";
00776 
00777         return os;
00778     }
00779 
00780 } // HepMC

Generated on Fri Feb 17 00:31:25 2012 for HepMC by  doxygen 1.4.7