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

Generated on Tue Feb 5 13:25:45 2008 for HepMC by  doxygen 1.5.1-3