00001
00002
00003
00004 #include "GeneratorInterface/ReggeGribovPartonMCInterface/interface/IO_EPOS.h"
00005 #include "HepMC/GenEvent.h"
00006 #include <cstdio>
00007
00008 using namespace HepMC;
00009
00010 namespace EPOS {
00011
00012 unsigned int EPOS_Wrapper::s_sizeof_int = 4;
00013 unsigned int EPOS_Wrapper::s_sizeof_real = sizeof(double);
00014 unsigned int EPOS_Wrapper::s_max_number_entries = 99900;
00015
00016 IO_EPOS::IO_EPOS() : m_trust_mothers_before_daughters(1),
00017 m_trust_both_mothers_and_daughters(0),
00018 m_print_inconsistency_errors(1),
00019 m_trust_beam_particles(true),
00020 m_skip_nucl_frag(false)
00021 {}
00022
00023 IO_EPOS::~IO_EPOS(){}
00024
00025 void IO_EPOS::print( std::ostream& ostr ) const {
00026 ostr << "IO_EPOS: reads an event from the FORTRAN EPOS g "
00027 << "common block. \n"
00028 << " trust_mothers_before_daughters = "
00029 << m_trust_mothers_before_daughters
00030 << " trust_both_mothers_and_daughters = "
00031 << m_trust_both_mothers_and_daughters
00032 << ", print_inconsistency_errors = "
00033 << m_print_inconsistency_errors << std::endl;
00034 }
00035
00036 bool IO_EPOS::fill_next_event( HepMC::GenEvent* evt ) {
00037
00038
00039 if ( !evt ) {
00040 std::cerr
00041 << "IO_EPOS::fill_next_event error - passed null event."
00042 << std::endl;
00043 return false;
00044 }
00045 evt->set_event_number( EPOS_Wrapper::event_number() );
00046
00047
00048
00049
00050
00051 std::vector<HepMC::GenParticle*> hepevt_particle(
00052 EPOS_Wrapper::number_entries()+1 );
00053 hepevt_particle[0] = 0;
00054 for ( int i1 = 1; i1 <= EPOS_Wrapper::number_entries(); ++i1 ) {
00055 hepevt_particle[i1] = build_particle(i1);
00056 }
00057
00058 HepMC::GenVertex* primaryVertex = new HepMC::GenVertex(HepMC::FourVector(0,0,0,0),0);
00059 evt->add_vertex(primaryVertex);
00060 if(!evt->signal_process_vertex()) evt->set_signal_process_vertex(primaryVertex);
00061
00062 std::set<HepMC::GenVertex*> new_vertices;
00063
00064
00065
00066 if( trust_beam_particles() ) {
00067 evt->set_beam_particles( hepevt_particle[1], hepevt_particle[2] );
00068 }
00069
00070
00071
00072 for ( int i = 1; i <= EPOS_Wrapper::number_entries(); ++i ) {
00073 if (m_skip_nucl_frag && abs(hepevt_particle[i]->pdg_id())>=1000000000)
00074 continue;
00075
00076
00077
00078
00079
00080
00081 if ( m_trust_mothers_before_daughters ||
00082 m_trust_both_mothers_and_daughters ) {
00083 build_production_vertex( i, hepevt_particle, evt );
00084 }
00085
00086
00087
00088 if ( !m_trust_mothers_before_daughters ||
00089 m_trust_both_mothers_and_daughters ) {
00090 build_end_vertex( i, hepevt_particle, evt );
00091 }
00092 }
00093
00094
00095
00096
00097
00098
00099 for ( int i3 = 1; i3 <= EPOS_Wrapper::number_entries(); ++i3 ) {
00100 if (m_skip_nucl_frag && abs(hepevt_particle[i3]->pdg_id())>=1000000000)
00101 continue;
00102 if ( !hepevt_particle[i3]->end_vertex() &&
00103 !hepevt_particle[i3]->production_vertex() ) {
00104 HepMC::GenVertex* prod_vtx = new GenVertex();
00105 prod_vtx->add_particle_out( hepevt_particle[i3] );
00106 evt->add_vertex( prod_vtx );
00107 }
00108 }
00109 return true;
00110 }
00111
00112 void IO_EPOS::write_event( const GenEvent* evt ) {
00113
00114 if ( !evt ) return;
00115
00116
00117 std::vector<HepMC::GenParticle*> index_to_particle(
00118 EPOS_Wrapper::max_number_entries()+1 );
00119 index_to_particle[0]=0;
00120 std::map<HepMC::GenParticle*,int> particle_to_index;
00121 int particle_counter=0;
00122 for ( HepMC::GenEvent::vertex_const_iterator v = evt->vertices_begin();
00123 v != evt->vertices_end(); ++v ) {
00124
00125
00126 for ( HepMC::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 EPOS_Wrapper::max_number_entries() ) break;
00132 index_to_particle[particle_counter] = *p1;
00133 particle_to_index[*p1] = particle_counter;
00134 }
00135
00136
00137 for ( HepMC::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 EPOS_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 > EPOS_Wrapper::max_number_entries() ) {
00152 particle_counter = EPOS_Wrapper::max_number_entries();
00153 }
00154
00155
00156 EPOS_Wrapper::set_event_number( evt->event_number() );
00157 EPOS_Wrapper::set_number_entries( particle_counter );
00158 for ( int i = 1; i <= particle_counter; ++i ) {
00159 EPOS_Wrapper::set_status( i, index_to_particle[i]->status() );
00160 EPOS_Wrapper::set_id( i, index_to_particle[i]->pdg_id() );
00161 FourVector m = index_to_particle[i]->momentum();
00162 EPOS_Wrapper::set_momentum( i, m.px(), m.py(), m.pz(), m.e() );
00163 EPOS_Wrapper::set_mass( i, index_to_particle[i]->generatedMass() );
00164
00165
00166 if ( index_to_particle[i]->production_vertex() &&
00167 index_to_particle[i]->production_vertex()->particles_in_size()) {
00168 FourVector p = index_to_particle[i]->
00169 production_vertex()->position();
00170 EPOS_Wrapper::set_position( i, p.x(), p.y(), p.z(), p.t() );
00171 int num_mothers = index_to_particle[i]->production_vertex()->
00172 particles_in_size();
00173 int first_mother = find_in_map( particle_to_index,
00174 *(index_to_particle[i]->
00175 production_vertex()->
00176 particles_in_const_begin()));
00177 int last_mother = first_mother + num_mothers - 1;
00178 if ( first_mother == 0 ) last_mother = 0;
00179 EPOS_Wrapper::set_parents( i, first_mother, last_mother );
00180 } else {
00181 EPOS_Wrapper::set_position( i, 0, 0, 0, 0 );
00182 EPOS_Wrapper::set_parents( i, 0, 0 );
00183 }
00184 EPOS_Wrapper::set_children( i, 0, 0 );
00185 }
00186 }
00187
00188 void IO_EPOS::build_production_vertex(int i,
00189 std::vector<HepMC::GenParticle*>&
00190 hepevt_particle,
00191 GenEvent* evt ) {
00192 HepMC::GenParticle* p = hepevt_particle[i];
00193
00194 int mother = EPOS_Wrapper::first_parent(i);
00195 HepMC::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 > EPOS_Wrapper::last_parent(i) ) mother = 0;
00201 }
00202
00203
00204
00205 HepMC::FourVector prod_pos( EPOS_Wrapper::x(i), EPOS_Wrapper::y(i),
00206 EPOS_Wrapper::z(i), EPOS_Wrapper::t(i)
00207 );
00208 if ( !prod_vtx && (EPOS_Wrapper::number_parents(i)>0
00209 || prod_pos!=FourVector(0,0,0,0)) )
00210 {
00211 prod_vtx = new HepMC::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 = EPOS_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_EPOS: inconsistent mother/daugher "
00237 << "information in EPOS event "
00238 << EPOS_Wrapper::event_number()
00239 << ". \n I recommend you try "
00240 << "inspecting the event first with "
00241 << "\n\tEPOS_Wrapper::check_hepevt_consistency()"
00242 << "\n This warning can be turned off with the "
00243 << "IO_EPOS::print_inconsistency_errors switch."
00244 << std::endl;
00245 }
00246 if ( ++mother > EPOS_Wrapper::last_parent(i) ) mother = 0;
00247 }
00248 }
00249
00250 void IO_EPOS::build_end_vertex
00251 ( int i, std::vector<HepMC::GenParticle*>& hepevt_particle, GenEvent* evt )
00252 {
00253
00254 HepMC::GenParticle* p = hepevt_particle[i];
00255
00256 int daughter = EPOS_Wrapper::first_child(i);
00257 HepMC::GenVertex* end_vtx = p->end_vertex();
00258 while ( !end_vtx && daughter > 0 ) {
00259 end_vtx = hepevt_particle[daughter]->production_vertex();
00260 if ( end_vtx ) end_vtx->add_particle_in( p );
00261 if ( ++daughter > EPOS_Wrapper::last_child(i) ) daughter = 0;
00262 }
00263
00264
00265 if ( !end_vtx && EPOS_Wrapper::number_children(i)>0 ) {
00266 end_vtx = new GenVertex();
00267 end_vtx->add_particle_in( p );
00268 evt->add_vertex( end_vtx );
00269 }
00270
00271
00272
00273 daughter = EPOS_Wrapper::first_child(i);
00274 while ( end_vtx && daughter > 0 ) {
00275 if ( !hepevt_particle[daughter]->production_vertex() ) {
00276
00277 end_vtx->add_particle_out( hepevt_particle[daughter] );
00278
00279
00280 if ( end_vtx->position()==FourVector(0,0,0,0) ) {
00281
00282 FourVector prod_pos( EPOS_Wrapper::x(daughter),
00283 EPOS_Wrapper::y(daughter),
00284 EPOS_Wrapper::z(daughter),
00285 EPOS_Wrapper::t(daughter)
00286 );
00287 if ( prod_pos != FourVector(0,0,0,0) ) {
00288 end_vtx->set_position( prod_pos );
00289 }
00290 }
00291 } else if (hepevt_particle[daughter]->production_vertex()
00292 != end_vtx){
00293
00294
00295
00296
00297
00298 if ( m_print_inconsistency_errors ) std::cerr
00299 << "HepMC::IO_EPOS: inconsistent mother/daugher "
00300 << "information in EPOS event "
00301 << EPOS_Wrapper::event_number()
00302 << ". \n I recommend you try "
00303 << "inspecting the event first with "
00304 << "\n\tEPOS_Wrapper::check_hepevt_consistency()"
00305 << "\n This warning can be turned off with the "
00306 << "IO_EPOS::print_inconsistency_errors switch."
00307 << std::endl;
00308 }
00309 if ( ++daughter > EPOS_Wrapper::last_child(i) ) daughter = 0;
00310 }
00311 if ( !p->end_vertex() && !p->production_vertex() ) {
00312
00313 build_production_vertex( i, hepevt_particle, evt );
00314 }
00315 }
00316
00317 HepMC::GenParticle* IO_EPOS::build_particle( int index ) {
00318
00319 HepMC::GenParticle* p
00320 = new GenParticle( FourVector( EPOS_Wrapper::px(index),
00321 EPOS_Wrapper::py(index),
00322 EPOS_Wrapper::pz(index),
00323 EPOS_Wrapper::e(index) ),
00324 EPOS_Wrapper::id(index),
00325 EPOS_Wrapper::status(index) );
00326 p->setGeneratedMass( EPOS_Wrapper::m(index) );
00327 p->suggest_barcode( index );
00328 return p;
00329 }
00330
00331 int IO_EPOS::find_in_map( const std::map<HepMC::GenParticle*,int>& m,
00332 HepMC::GenParticle* p) const {
00333 std::map<HepMC::GenParticle*,int>::const_iterator iter = m.find(p);
00334 if ( iter == m.end() ) return 0;
00335 return iter->second;
00336 }
00337
00338 }
00339
00340
00341