00001
00002
00003
00005
00006 #include "HepMC/IO_HEPEVT.h"
00007 #include "HepMC/GenEvent.h"
00008 #include <cstdio>
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
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
00056
00057
00058
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
00068
00069 if( trust_beam_particles() ) {
00070 evt->set_beam_particles( hepevt_particle[1], hepevt_particle[2] );
00071 }
00072
00073
00074 for ( int i = 1; i <= HEPEVT_Wrapper::number_entries(); ++i ) {
00075
00076
00077
00078
00080
00081
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
00088
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
00095
00096
00097
00098
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
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
00128
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
00139
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
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
00168
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
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
00206 if ( ++mother > HEPEVT_Wrapper::last_parent(i) ) mother = 0;
00207 }
00208
00209
00210
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
00222 if ( prod_vtx && prod_vtx->position()==FourVector(0,0,0,0) ) {
00223 prod_vtx->set_position( prod_pos );
00224 }
00225
00226
00227 mother = HEPEVT_Wrapper::first_parent(i);
00228 while ( prod_vtx && mother > 0 ) {
00229 if ( !hepevt_particle[mother]->end_vertex() ) {
00230
00231 prod_vtx->add_particle_in( hepevt_particle[mother] );
00232 } else if (hepevt_particle[mother]->end_vertex() != prod_vtx ) {
00233
00234
00235
00236
00237
00238
00239
00240
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
00263 GenParticle* p = hepevt_particle[i];
00264
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
00273
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
00280
00281
00282 daughter = HEPEVT_Wrapper::first_child(i);
00283 while ( end_vtx && daughter > 0 ) {
00284 if ( !hepevt_particle[daughter]->production_vertex() ) {
00285
00286 end_vtx->add_particle_out( hepevt_particle[daughter] );
00287
00288
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
00302
00303
00304
00305
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
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 }
00348
00349
00350