HepMC Reference Documentation

HepMC

IO_HEPEVT.cc

Go to the documentation of this file.
00001 
00002 // Matt.Dobbs@Cern.CH, January 2000
00003 // HEPEVT IO class
00005 
00006 #include "HepMC/IO_HEPEVT.h"
00007 #include "HepMC/GenEvent.h"
00008 #include <cstdio>       // needed for formatted output using sprintf 
00009 
00010 namespace HepMC {
00011 
00012     IO_HEPEVT::IO_HEPEVT() : m_trust_mothers_before_daughters(1),
00013                              m_trust_both_mothers_and_daughters(0),
00014                              m_print_inconsistency_errors(1),
00015                              m_trust_beam_particles(true)
00016     {}
00017 
00018     IO_HEPEVT::~IO_HEPEVT(){}
00019 
00020     void IO_HEPEVT::print( std::ostream& ostr ) const { 
00021         ostr << "IO_HEPEVT: reads an event from the FORTRAN HEPEVT "
00022              << "common block. \n" 
00023              << " trust_mothers_before_daughters = " 
00024              << m_trust_mothers_before_daughters
00025              << " trust_both_mothers_and_daughters = "
00026              << m_trust_both_mothers_and_daughters
00027              << ", print_inconsistency_errors = " 
00028              << m_print_inconsistency_errors << std::endl;
00029     }
00030 
00031     bool IO_HEPEVT::fill_next_event( GenEvent* evt ) {
00045         //
00046         // 1. test that evt pointer is not null and set event number
00047         if ( !evt ) {
00048             std::cerr 
00049                 << "IO_HEPEVT::fill_next_event error - passed null event." 
00050                 << std::endl;
00051             return false;
00052         }
00053         evt->set_event_number( HEPEVT_Wrapper::event_number() );
00054         //
00055         // 2. create a particle instance for each HEPEVT entry and fill a map
00056         //    create a vector which maps from the HEPEVT particle index to the 
00057         //    GenParticle address
00058         //    (+1 in size accounts for hepevt_particle[0] which is unfilled)
00059         std::vector<GenParticle*> hepevt_particle( 
00060                                         HEPEVT_Wrapper::number_entries()+1 );
00061         hepevt_particle[0] = 0;
00062         for ( int i1 = 1; i1 <= HEPEVT_Wrapper::number_entries(); ++i1 ) {
00063             hepevt_particle[i1] = build_particle(i1);
00064         }
00065         std::set<GenVertex*> new_vertices;
00066         //
00067         // Here we assume that the first two particles in the list 
00068         // are the incoming beam particles.
00069         if( trust_beam_particles() ) {
00070         evt->set_beam_particles( hepevt_particle[1], hepevt_particle[2] );
00071         }
00072         //
00073         // 3.+4. loop over HEPEVT particles AGAIN, this time creating vertices
00074         for ( int i = 1; i <= HEPEVT_Wrapper::number_entries(); ++i ) {
00075             // We go through and build EITHER the production or decay 
00076             // vertex for each entry in hepevt, depending on the switch
00077             // m_trust_mothers_before_daughters (new 2001-02-28)
00078             // Note: since the HEPEVT pointers are bi-directional, it is
00080             //
00081             // 3. Build the production_vertex (if necessary)
00082             if ( m_trust_mothers_before_daughters || 
00083                  m_trust_both_mothers_and_daughters ) {
00084                 build_production_vertex( i, hepevt_particle, evt );
00085             }
00086             //
00087             // 4. Build the end_vertex (if necessary) 
00088             //    Identical steps as for production vertex
00089             if ( !m_trust_mothers_before_daughters || 
00090                  m_trust_both_mothers_and_daughters ) {
00091                 build_end_vertex( i, hepevt_particle, evt );
00092             }
00093         }
00094         // 5.             01.02.2000
00095         // handle the case of particles in HEPEVT which come from nowhere -
00096         //  i.e. particles without mothers or daughters.
00097         //  These particles need to be attached to a vertex, or else they
00098         //  will never become part of the event. check for this situation
00099         for ( int i3 = 1; i3 <= HEPEVT_Wrapper::number_entries(); ++i3 ) {
00100             if ( !hepevt_particle[i3]->end_vertex() && 
00101                         !hepevt_particle[i3]->production_vertex() ) {
00102                 GenVertex* prod_vtx = new GenVertex();
00103                 prod_vtx->add_particle_out( hepevt_particle[i3] );
00104                 evt->add_vertex( prod_vtx );
00105             }
00106         }
00107         return true;
00108     }
00109 
00110     void IO_HEPEVT::write_event( const GenEvent* evt ) {
00116         //
00117         if ( !evt ) return;
00118         //
00119         // map all particles onto a unique index
00120         std::vector<GenParticle*> index_to_particle(
00121             HEPEVT_Wrapper::max_number_entries()+1 );
00122         index_to_particle[0]=0;
00123         std::map<GenParticle*,int> particle_to_index;
00124         int particle_counter=0;
00125         for ( GenEvent::vertex_const_iterator v = evt->vertices_begin();
00126               v != evt->vertices_end(); ++v ) {
00127             // all "mothers" or particles_in are kept adjacent in the list
00128             // so that the mother indices in hepevt can be filled properly
00129             for ( GenVertex::particles_in_const_iterator p1 
00130                       = (*v)->particles_in_const_begin();
00131                   p1 != (*v)->particles_in_const_end(); ++p1 ) {
00132                 ++particle_counter;
00133                 if ( particle_counter > 
00134                      HEPEVT_Wrapper::max_number_entries() ) break; 
00135                 index_to_particle[particle_counter] = *p1;
00136                 particle_to_index[*p1] = particle_counter;
00137             }
00138             // daughters are entered only if they aren't a mother of 
00139             // another vtx
00140             for ( GenVertex::particles_out_const_iterator p2 
00141                       = (*v)->particles_out_const_begin();
00142                   p2 != (*v)->particles_out_const_end(); ++p2 ) {
00143                 if ( !(*p2)->end_vertex() ) {
00144                     ++particle_counter;
00145                     if ( particle_counter > 
00146                          HEPEVT_Wrapper::max_number_entries() ) {
00147                         break;
00148                     }
00149                     index_to_particle[particle_counter] = *p2;
00150                     particle_to_index[*p2] = particle_counter;
00151                 }
00152             }
00153         }
00154         if ( particle_counter > HEPEVT_Wrapper::max_number_entries() ) {
00155             particle_counter = HEPEVT_Wrapper::max_number_entries();
00156         }
00157         //      
00158         // fill the HEPEVT event record
00159         HEPEVT_Wrapper::set_event_number( evt->event_number() );
00160         HEPEVT_Wrapper::set_number_entries( particle_counter );
00161         for ( int i = 1; i <= particle_counter; ++i ) {
00162             HEPEVT_Wrapper::set_status( i, index_to_particle[i]->status() );
00163             HEPEVT_Wrapper::set_id( i, index_to_particle[i]->pdg_id() );
00164             FourVector m = index_to_particle[i]->momentum();
00165             HEPEVT_Wrapper::set_momentum( i, m.px(), m.py(), m.pz(), m.e() );
00166             HEPEVT_Wrapper::set_mass( i, index_to_particle[i]->generatedMass() );
00167             // there should ALWAYS be particles in any vertex, but some generators
00168             // are making non-kosher HepMC events
00169             if ( index_to_particle[i]->production_vertex() && 
00170                  index_to_particle[i]->production_vertex()->particles_in_size()) {
00171                 FourVector p = index_to_particle[i]->
00172                                      production_vertex()->position();
00173                 HEPEVT_Wrapper::set_position( i, p.x(), p.y(), p.z(), p.t() );
00174                 int num_mothers = index_to_particle[i]->production_vertex()->
00175                                   particles_in_size();
00176                 int first_mother = find_in_map( particle_to_index,
00177                                                 *(index_to_particle[i]->
00178                                                   production_vertex()->
00179                                                   particles_in_const_begin()));
00180                 int last_mother = first_mother + num_mothers - 1;
00181                 if ( first_mother == 0 ) last_mother = 0;
00182                 HEPEVT_Wrapper::set_parents( i, first_mother, last_mother );
00183             } else {
00184                 HEPEVT_Wrapper::set_position( i, 0, 0, 0, 0 );
00185                 HEPEVT_Wrapper::set_parents( i, 0, 0 );
00186             }
00187             HEPEVT_Wrapper::set_children( i, 0, 0 );
00188         }
00189     }
00190 
00191     void IO_HEPEVT::build_production_vertex(int i, 
00192                                             std::vector<HepMC::GenParticle*>& 
00193                                             hepevt_particle,
00194                                             GenEvent* evt ) {
00198         GenParticle* p = hepevt_particle[i];
00199         // a. search to see if a production vertex already exists
00200         int mother = HEPEVT_Wrapper::first_parent(i);
00201         GenVertex* prod_vtx = p->production_vertex();
00202         while ( !prod_vtx && mother > 0 ) {
00203             prod_vtx = hepevt_particle[mother]->end_vertex();
00204             if ( prod_vtx ) prod_vtx->add_particle_out( p );
00205             // increment mother for next iteration
00206             if ( ++mother > HEPEVT_Wrapper::last_parent(i) ) mother = 0;
00207         }
00208         // b. if no suitable production vertex exists - and the particle
00209         // has atleast one mother or position information to store - 
00210         // make one
00211         FourVector prod_pos( HEPEVT_Wrapper::x(i), HEPEVT_Wrapper::y(i), 
00212                                    HEPEVT_Wrapper::z(i), HEPEVT_Wrapper::t(i) 
00213                                  ); 
00214         if ( !prod_vtx && (HEPEVT_Wrapper::number_parents(i)>0 
00215                            || prod_pos!=FourVector(0,0,0,0)) )
00216         {
00217             prod_vtx = new GenVertex();
00218             prod_vtx->add_particle_out( p );
00219             evt->add_vertex( prod_vtx );
00220         }
00221         // c. if prod_vtx doesn't already have position specified, fill it
00222         if ( prod_vtx && prod_vtx->position()==FourVector(0,0,0,0) ) {
00223             prod_vtx->set_position( prod_pos );
00224         }
00225         // d. loop over mothers to make sure their end_vertices are
00226         //     consistent
00227         mother = HEPEVT_Wrapper::first_parent(i);
00228         while ( prod_vtx && mother > 0 ) {
00229             if ( !hepevt_particle[mother]->end_vertex() ) {
00230                 // if end vertex of the mother isn't specified, do it now
00231                 prod_vtx->add_particle_in( hepevt_particle[mother] );
00232             } else if (hepevt_particle[mother]->end_vertex() != prod_vtx ) {
00233                 // problem scenario --- the mother already has a decay
00234                 // vertex which differs from the daughter's produciton 
00235                 // vertex. This means there is internal
00236                 // inconsistency in the HEPEVT event record. Print an
00237                 // error
00238                 // Note: we could provide a fix by joining the two 
00239                 //       vertices with a dummy particle if the problem
00240                 //       arrises often with any particular generator.
00241                 if ( m_print_inconsistency_errors ) std::cerr
00242                     << "HepMC::IO_HEPEVT: inconsistent mother/daugher "
00243                     << "information in HEPEVT event " 
00244                     << HEPEVT_Wrapper::event_number()
00245                     << ". \n I recommend you try "
00246                     << "inspecting the event first with "
00247                     << "\n\tHEPEVT_Wrapper::check_hepevt_consistency()"
00248                     << "\n This warning can be turned off with the "
00249                     << "IO_HEPEVT::print_inconsistency_errors switch."
00250                     << std::endl;
00251             }
00252             if ( ++mother > HEPEVT_Wrapper::last_parent(i) ) mother = 0;
00253         }
00254     }
00255 
00256     void IO_HEPEVT::build_end_vertex
00257     ( int i, std::vector<HepMC::GenParticle*>& hepevt_particle, GenEvent* evt ) 
00258     {
00262         //    Identical steps as for build_production_vertex
00263         GenParticle* p = hepevt_particle[i];
00264         // a.
00265         int daughter = HEPEVT_Wrapper::first_child(i);
00266         GenVertex* end_vtx = p->end_vertex();
00267         while ( !end_vtx && daughter > 0 ) {
00268             end_vtx = hepevt_particle[daughter]->production_vertex();
00269             if ( end_vtx ) end_vtx->add_particle_in( p );
00270             if ( ++daughter > HEPEVT_Wrapper::last_child(i) ) daughter = 0;
00271         }
00272         // b. (different from 3c. because HEPEVT particle can not know its
00273         //        decay position )
00274         if ( !end_vtx && HEPEVT_Wrapper::number_children(i)>0 ) {
00275             end_vtx = new GenVertex();
00276             end_vtx->add_particle_in( p );
00277             evt->add_vertex( end_vtx );
00278         }
00279         // c+d. loop over daughters to make sure their production vertices 
00280         //    point back to the current vertex.
00281         //    We get the vertex position from the daughter as well.
00282         daughter = HEPEVT_Wrapper::first_child(i);
00283         while ( end_vtx && daughter > 0 ) {
00284             if ( !hepevt_particle[daughter]->production_vertex() ) {
00285                 // if end vertex of the mother isn't specified, do it now
00286                 end_vtx->add_particle_out( hepevt_particle[daughter] );
00287                 // 
00288                 // 2001-03-29 M.Dobbs, fill vertex the position.
00289                 if ( end_vtx->position()==FourVector(0,0,0,0) ) {
00290                     FourVector prod_pos( HEPEVT_Wrapper::x(daughter), 
00291                                                HEPEVT_Wrapper::y(daughter), 
00292                                                HEPEVT_Wrapper::z(daughter), 
00293                                                HEPEVT_Wrapper::t(daughter) 
00294                         );
00295                     if ( prod_pos != FourVector(0,0,0,0) ) {
00296                         end_vtx->set_position( prod_pos );
00297                     }
00298                 }
00299             } else if (hepevt_particle[daughter]->production_vertex() 
00300                        != end_vtx){
00301                 // problem scenario --- the daughter already has a prod
00302                 // vertex which differs from the mother's end 
00303                 // vertex. This means there is internal
00304                 // inconsistency in the HEPEVT event record. Print an
00305                 // error
00306                 if ( m_print_inconsistency_errors ) std::cerr
00307                     << "HepMC::IO_HEPEVT: inconsistent mother/daugher "
00308                     << "information in HEPEVT event " 
00309                     << HEPEVT_Wrapper::event_number()
00310                     << ". \n I recommend you try "
00311                     << "inspecting the event first with "
00312                     << "\n\tHEPEVT_Wrapper::check_hepevt_consistency()"
00313                     << "\n This warning can be turned off with the "
00314                     << "IO_HEPEVT::print_inconsistency_errors switch."
00315                     << std::endl;
00316             }
00317             if ( ++daughter > HEPEVT_Wrapper::last_child(i) ) daughter = 0;
00318         }
00319         if ( !p->end_vertex() && !p->production_vertex() ) {
00320             // Added 2001-11-04, to try and handle Isajet problems.
00321             build_production_vertex( i, hepevt_particle, evt );
00322         }
00323     }
00324 
00325     GenParticle* IO_HEPEVT::build_particle( int index ) {
00327         // 
00328         GenParticle* p 
00329             = new GenParticle( FourVector( HEPEVT_Wrapper::px(index), 
00330                                                  HEPEVT_Wrapper::py(index), 
00331                                                  HEPEVT_Wrapper::pz(index), 
00332                                                  HEPEVT_Wrapper::e(index) ),
00333                                HEPEVT_Wrapper::id(index), 
00334                                HEPEVT_Wrapper::status(index) );
00335         p->setGeneratedMass( HEPEVT_Wrapper::m(index) );
00336         p->suggest_barcode( index );
00337         return p;
00338     }
00339 
00340     int IO_HEPEVT::find_in_map( const std::map<HepMC::GenParticle*,int>& m, 
00341                                 GenParticle* p) const {
00342         std::map<GenParticle*,int>::const_iterator iter = m.find(p);
00343         if ( iter == m.end() ) return 0;
00344         return iter->second;
00345     }
00346 
00347 } // HepMC
00348 
00349 
00350 

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