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 {}
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
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
00055
00056
00057
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
00067
00068 evt->set_beam_particles( hepevt_particle[1], hepevt_particle[2] );
00069
00070
00071 for ( int i = 1; i <= HEPEVT_Wrapper::number_entries(); ++i ) {
00072
00073
00074
00075
00077
00078
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
00085
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
00092
00093
00094
00095
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
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
00125
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
00136
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
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
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
00200 if ( ++mother > HEPEVT_Wrapper::last_parent(i) ) mother = 0;
00201 }
00202
00203
00204
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
00216 if ( prod_vtx && prod_vtx->position()==FourVector(0,0,0,0) ) {
00217 prod_vtx->set_position( prod_pos );
00218 }
00219
00220
00221 mother = HEPEVT_Wrapper::first_parent(i);
00222 while ( prod_vtx && mother > 0 ) {
00223 if ( !hepevt_particle[mother]->end_vertex() ) {
00224
00225 prod_vtx->add_particle_in( hepevt_particle[mother] );
00226 } else if (hepevt_particle[mother]->end_vertex() != prod_vtx ) {
00227
00228
00229
00230
00231
00232
00233
00234
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
00257 GenParticle* p = hepevt_particle[i];
00258
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
00267
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
00274
00275
00276 daughter = HEPEVT_Wrapper::first_child(i);
00277 while ( end_vtx && daughter > 0 ) {
00278 if ( !hepevt_particle[daughter]->production_vertex() ) {
00279
00280 end_vtx->add_particle_out( hepevt_particle[daughter] );
00281
00282
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
00296
00297
00298
00299
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
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 }
00342
00343
00344