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         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

Generated on Thu Jan 7 13:10:15 2010 for HepMC by  doxygen 1.4.7