![]() |
HepMC Reference DocumentationHepMC |
00001 //-------------------------------------------------------------------------- 00002 00004 // garren@fnal.gov, July 2006 00005 // event input/output in ascii format for machine reading 00006 // extended format contains HeavyIon and PdfInfo classes 00008 00009 #include "HepMC/IO_GenEvent.h" 00010 #include "HepMC/GenEvent.h" 00011 #include "HepMC/ParticleDataTable.h" 00012 #include "HepMC/HeavyIon.h" 00013 #include "HepMC/PdfInfo.h" 00014 #include "HepMC/CommonIO.h" 00015 #include "HepMC/Version.h" 00016 00017 namespace HepMC { 00018 00019 IO_GenEvent::IO_GenEvent( const char* filename, std::ios::openmode mode ) 00020 : m_mode(mode), 00021 m_file(filename, mode), 00022 m_ostr(0), 00023 m_istr(0), 00024 m_iostr(0), 00025 m_finished_first_event_io(false), 00026 m_have_file(false), 00027 m_common_io() 00028 { 00029 if ( (m_mode&std::ios::out && m_mode&std::ios::in) || 00030 (m_mode&std::ios::app && m_mode&std::ios::in) ) { 00031 std::cerr << "IO_GenEvent::IO_GenEvent Error, open of file requested " 00032 << "of input AND output type. Not allowed. Closing file." 00033 << std::endl; 00034 m_file.close(); 00035 return; 00036 } 00037 // precision 16 (# digits following decimal point) is the minimum that 00038 // will capture the full information stored in a double 00039 m_file.precision(16); 00040 // we use decimal to store integers, because it is smaller than hex! 00041 m_file.setf(std::ios::dec,std::ios::basefield); 00042 m_file.setf(std::ios::scientific,std::ios::floatfield); 00043 // now we set the streams 00044 m_iostr = &m_file; 00045 if ( m_mode&std::ios::in ) { 00046 m_istr = &m_file; 00047 m_ostr = NULL; 00048 } 00049 if ( m_mode&std::ios::out ) { 00050 m_ostr = &m_file; 00051 m_istr = NULL; 00052 } 00053 m_have_file = true; 00054 } 00055 00056 IO_GenEvent::IO_GenEvent( std::istream & istr ) 00057 : m_ostr(0), 00058 m_istr(&istr), 00059 m_iostr(&istr), 00060 m_finished_first_event_io(false), 00061 m_have_file(false), 00062 m_common_io() 00063 { } 00064 00065 IO_GenEvent::IO_GenEvent( std::ostream & ostr ) 00066 : m_ostr(&ostr), 00067 m_istr(0), 00068 m_iostr(&ostr), 00069 m_finished_first_event_io(false), 00070 m_have_file(false), 00071 m_common_io() 00072 { 00073 // precision 16 (# digits following decimal point) is the minimum that 00074 // will capture the full information stored in a double 00075 m_ostr->precision(16); 00076 // we use decimal to store integers, because it is smaller than hex! 00077 m_ostr->setf(std::ios::dec,std::ios::basefield); 00078 m_ostr->setf(std::ios::scientific,std::ios::floatfield); 00079 } 00080 00081 IO_GenEvent::~IO_GenEvent() { 00082 write_end_listing(); 00083 if(m_have_file) m_file.close(); 00084 } 00085 00086 void IO_GenEvent::print( std::ostream& ostr ) const { 00087 ostr << "IO_GenEvent: unformated ascii file IO for machine reading.\n"; 00088 if(m_have_file) ostr << "\tFile openmode: " << m_mode ; 00089 ostr << " stream state: " << m_ostr->rdstate() 00090 << " bad:" << (m_ostr->rdstate()&std::ios::badbit) 00091 << " eof:" << (m_ostr->rdstate()&std::ios::eofbit) 00092 << " fail:" << (m_ostr->rdstate()&std::ios::failbit) 00093 << " good:" << (m_ostr->rdstate()&std::ios::goodbit) << std::endl; 00094 } 00095 00096 void IO_GenEvent::write_event( const GenEvent* evt ) { 00098 // 00099 // make sure the state is good, and that it is in output mode 00100 if ( !evt ) return; 00101 if ( m_ostr == NULL ) { 00102 std::cerr << "HepMC::IO_GenEvent::write_event " 00103 << " attempt to write to input file." << std::endl; 00104 return; 00105 } 00106 // 00107 // write event listing key before first event only. 00108 if ( !m_finished_first_event_io ) { 00109 m_finished_first_event_io = 1; 00110 *m_ostr << "\n" << "HepMC::Version " << versionName(); 00111 *m_ostr << "\n"; 00112 m_common_io.write_IO_GenEvent_Key(*m_ostr); 00113 } 00114 // 00115 // output the event data including the number of primary vertices 00116 // and the total number of vertices 00117 std::vector<long> random_states = evt->random_states(); 00118 *m_ostr << 'E'; 00119 output( evt->event_number() ); 00120 output( evt->mpi() ); 00121 output( evt->event_scale() ); 00122 output( evt->alphaQCD() ); 00123 output( evt->alphaQED() ); 00124 output( evt->signal_process_id() ); 00125 output( ( evt->signal_process_vertex() ? 00126 evt->signal_process_vertex()->barcode() : 0 ) ); 00127 output( evt->vertices_size() ); // total number of vertices. 00128 write_beam_particles( evt->beam_particles() ); 00129 output( (int)random_states.size() ); 00130 for ( std::vector<long>::iterator rs = random_states.begin(); 00131 rs != random_states.end(); ++rs ) { 00132 output( *rs ); 00133 } 00134 output( (int)evt->weights().size() ); 00135 for ( WeightContainer::const_iterator w = evt->weights().begin(); 00136 w != evt->weights().end(); ++w ) { 00137 output( *w ); 00138 } 00139 output('\n'); 00140 write_heavy_ion( evt->heavy_ion() ); 00141 write_pdf_info( evt->pdf_info() ); 00142 // 00143 // Output all of the vertices - note there is no real order. 00144 for ( GenEvent::vertex_const_iterator v = evt->vertices_begin(); 00145 v != evt->vertices_end(); ++v ) { 00146 write_vertex( *v ); 00147 } 00148 } 00149 00150 bool IO_GenEvent::fill_next_event( GenEvent* evt ){ 00151 // 00152 // 00153 // test that evt pointer is not null 00154 if ( !evt ) { 00155 std::cerr 00156 << "IO_GenEvent::fill_next_event error - passed null event." 00157 << std::endl; 00158 return false; 00159 } 00160 // make sure the stream is good, and that it is in input mode 00161 if ( !(*m_istr) ) return false; 00162 if ( !m_istr ) { 00163 std::cerr << "HepMC::IO_GenEvent::fill_next_event " 00164 << " attempt to read from output file." << std::endl; 00165 return false; 00166 } 00167 // 00168 // search for event listing key before first event only. 00169 // 00170 // skip through the file just after first occurence of the start_key 00171 int iotype = 0; 00172 if ( !m_finished_first_event_io ) { 00173 iotype = m_common_io.find_file_type(*m_istr); 00174 if( iotype <= 0 ) { 00175 std::cerr << "IO_GenEvent::fill_next_event start key not found " 00176 << "setting badbit." << std::endl; 00177 m_istr->clear(std::ios::badbit); 00178 return false; 00179 } 00180 m_finished_first_event_io = 1; 00181 } 00182 // 00183 // test to be sure the next entry is of type "E" then ignore it 00184 if ( !(*m_istr) ) { 00185 std::cerr << "IO_GenEvent::fill_next_event end of stream found " 00186 << "setting badbit." << std::endl; 00187 m_istr->clear(std::ios::badbit); 00188 return false; 00189 } 00190 if ( !(*m_istr) || m_istr->peek()!='E' ) { 00191 // if the E is not the next entry, then check to see if it is 00192 // the end event listing key - if yes, search for another start key 00193 int ioendtype = m_common_io.find_end_key(*m_istr); 00194 if ( ioendtype == iotype ) { 00195 iotype = m_common_io.find_file_type(*m_istr); 00196 if( iotype <= 0 ) { 00197 // this is the only case where we set an EOF state 00198 m_istr->clear(std::ios::eofbit); 00199 return false; 00200 } 00201 } else if ( ioendtype > 0 ) { 00202 std::cerr << "IO_GenEvent::fill_next_event end key does not match start key " 00203 << "setting badbit." << std::endl; 00204 m_istr->clear(std::ios::badbit); 00205 return false; 00206 } else { 00207 std::cerr << "IO_GenEvent::fill_next_event end key not found " 00208 << "setting badbit." << std::endl; 00209 m_istr->clear(std::ios::badbit); 00210 return false; 00211 } 00212 } 00213 m_istr->ignore(); 00214 // call the appropriate read method 00215 if( m_common_io.io_type() == gen ) { 00216 return m_common_io.read_io_genevent(m_istr, evt); 00217 } else if( m_common_io.io_type() == ascii ) { 00218 return m_common_io.read_io_ascii(m_istr, evt); 00219 } else if( m_common_io.io_type() == extascii ) { 00220 return m_common_io.read_io_extendedascii(m_istr, evt); 00221 } else if( m_common_io.io_type() == ascii_pdt ) { 00222 } else if( m_common_io.io_type() == extascii_pdt ) { 00223 } 00224 // should not get to this statement 00225 return false; 00226 } 00227 00228 void IO_GenEvent::write_comment( const std::string comment ) { 00229 // make sure the stream is good, and that it is in output mode 00230 if ( !(*m_ostr) ) return; 00231 if ( m_ostr == NULL ) { 00232 std::cerr << "HepMC::IO_GenEvent::write_comment " 00233 << " attempt to write to input file." << std::endl; 00234 return; 00235 } 00236 // write end of event listing key if events have already been written 00237 write_end_listing(); 00238 // insert the comment key before the comment 00239 *m_ostr << "\n" << "HepMC::IO_GenEvent-COMMENT\n"; 00240 *m_ostr << comment << std::endl; 00241 } 00242 00243 void IO_GenEvent::write_vertex( GenVertex* v ) { 00244 // assumes mode has already been checked 00245 if ( !v || !(*m_ostr) ) { 00246 std::cerr << "IO_GenEvent::write_vertex !v||!(*m_ostr), " 00247 << "v="<< v << " setting badbit" << std::endl; 00248 m_ostr->clear(std::ios::badbit); 00249 return; 00250 } 00251 // First collect info we need 00252 // count the number of orphan particles going into v 00253 int num_orphans_in = 0; 00254 for ( GenVertex::particles_in_const_iterator p1 00255 = v->particles_in_const_begin(); 00256 p1 != v->particles_in_const_end(); ++p1 ) { 00257 if ( !(*p1)->production_vertex() ) ++num_orphans_in; 00258 } 00259 // 00260 *m_ostr << 'V'; 00261 output( v->barcode() ); // v's unique identifier 00262 output( v->id() ); 00263 output( v->position().x() ); 00264 output( v->position().y() ); 00265 output( v->position().z() ); 00266 output( v->position().t() ); 00267 output( num_orphans_in ); 00268 output( (int)v->particles_out_size() ); 00269 output( (int)v->weights().size() ); 00270 for ( WeightContainer::iterator w = v->weights().begin(); 00271 w != v->weights().end(); ++w ) { 00272 output( *w ); 00273 } 00274 output('\n'); 00275 for ( GenVertex::particles_in_const_iterator p2 00276 = v->particles_in_const_begin(); 00277 p2 != v->particles_in_const_end(); ++p2 ) { 00278 if ( !(*p2)->production_vertex() ) { 00279 write_particle( *p2 ); 00280 } 00281 } 00282 for ( GenVertex::particles_out_const_iterator p3 00283 = v->particles_out_const_begin(); 00284 p3 != v->particles_out_const_end(); ++p3 ) { 00285 write_particle( *p3 ); 00286 } 00287 } 00288 00289 void IO_GenEvent::write_beam_particles( 00290 std::pair<HepMC::GenParticle *,HepMC::GenParticle *> pr ) { 00291 GenParticle* p = pr.first; 00292 //m_file << 'B'; 00293 if(!p) { 00294 output( 0 ); 00295 } else { 00296 output( p->barcode() ); 00297 } 00298 p = pr.second; 00299 if(!p) { 00300 output( 0 ); 00301 } else { 00302 output( p->barcode() ); 00303 } 00304 } 00305 00306 void IO_GenEvent::write_heavy_ion( HeavyIon* ion ) { 00307 // assumes mode has already been checked 00308 if ( !(*m_ostr) ) { 00309 std::cerr << "IO_GenEvent::write_heavy_ion !(*m_ostr), " 00310 << " setting badbit" << std::endl; 00311 m_ostr->clear(std::ios::badbit); 00312 return; 00313 } 00314 *m_ostr << 'H'; 00315 // HeavyIon* is set to 0 by default 00316 if ( !ion ) { 00317 output( 0 ); 00318 output( 0 ); 00319 output( 0 ); 00320 output( 0 ); 00321 output( 0 ); 00322 output( 0 ); 00323 output( 0 ); 00324 output( 0 ); 00325 output( 0 ); 00326 output( 0. ); 00327 output( 0. ); 00328 output( 0. ); 00329 output( 0. ); 00330 output('\n'); 00331 return; 00332 } 00333 // 00334 output( ion->Ncoll_hard() ); 00335 output( ion->Npart_proj() ); 00336 output( ion->Npart_targ() ); 00337 output( ion->Ncoll() ); 00338 output( ion->spectator_neutrons() ); 00339 output( ion->spectator_protons() ); 00340 output( ion->N_Nwounded_collisions() ); 00341 output( ion->Nwounded_N_collisions() ); 00342 output( ion->Nwounded_Nwounded_collisions() ); 00343 output( ion->impact_parameter() ); 00344 output( ion->event_plane_angle() ); 00345 output( ion->eccentricity() ); 00346 output( ion->sigma_inel_NN() ); 00347 output('\n'); 00348 } 00349 00350 void IO_GenEvent::write_pdf_info( PdfInfo* pdf ) { 00351 // assumes mode has already been checked 00352 if ( !(*m_ostr) ) { 00353 std::cerr << "IO_GenEvent::write_pdf_info !(*m_ostr), " 00354 << " setting badbit" << std::endl; 00355 m_ostr->clear(std::ios::badbit); 00356 return; 00357 } 00358 *m_ostr << 'F'; 00359 // PdfInfo* is set to 0 by default 00360 if ( !pdf ) { 00361 output( 0 ); 00362 output( 0 ); 00363 output( 0. ); 00364 output( 0. ); 00365 output( 0. ); 00366 output( 0. ); 00367 output( 0. ); 00368 output('\n'); 00369 return; 00370 } 00371 // 00372 output( pdf->id1() ); 00373 output( pdf->id2() ); 00374 output( pdf->x1() ); 00375 output( pdf->x2() ); 00376 output( pdf->scalePDF() ); 00377 output( pdf->pdf1() ); 00378 output( pdf->pdf2() ); 00379 output('\n'); 00380 } 00381 00382 void IO_GenEvent::write_particle( GenParticle* p ) { 00383 // assumes mode has already been checked 00384 if ( !p || !(*m_ostr) ) { 00385 std::cerr << "IO_GenEvent::write_particle !p||!(*m_ostr), " 00386 << "v="<< p << " setting badbit" << std::endl; 00387 m_ostr->clear(std::ios::badbit); 00388 return; 00389 } 00390 *m_ostr << 'P'; 00391 output( p->barcode() ); 00392 output( p->pdg_id() ); 00393 output( p->momentum().px() ); 00394 output( p->momentum().py() ); 00395 output( p->momentum().pz() ); 00396 output( p->momentum().e() ); 00397 output( p->generated_mass() ); 00398 output( p->status() ); 00399 output( p->polarization().theta() ); 00400 output( p->polarization().phi() ); 00401 // since end_vertex is oftentimes null, this CREATES a null vertex 00402 // in the map 00403 output( ( p->end_vertex() ? p->end_vertex()->barcode() : 0 ) ); 00404 *m_ostr << ' ' << p->flow() << "\n"; 00405 } 00406 00407 void IO_GenEvent::write_particle_data( const ParticleData* pdata ) { 00408 // assumes mode has already been checked 00409 if ( !pdata || !(*m_ostr) ) { 00410 std::cerr << "IO_GenEvent::write_particle_data !pdata||!(*m_ostr), " 00411 << "pdata="<< pdata << " setting badbit" << std::endl; 00412 m_ostr->clear(std::ios::badbit); 00413 return; 00414 } 00415 *m_ostr << 'D'; 00416 output( pdata->pdg_id() ); 00417 output( pdata->charge() ); 00418 output( pdata->mass() ); 00419 output( pdata->clifetime() ); 00420 output( (int)(pdata->spin()*2.+.1) ); 00421 // writes the first 21 characters starting with 0 00422 *m_ostr << " " << pdata->name().substr(0,21) << "\n"; 00423 } 00424 00425 HeavyIon* IO_GenEvent::read_heavy_ion() 00426 { 00427 // assumes mode has already been checked 00428 // 00429 // test to be sure the next entry is of type "H" then ignore it 00430 if ( !(*m_istr) || m_istr->peek()!='H' ) { 00431 std::cerr << "IO_GenEvent::read_heavy_ion setting badbit." << std::endl; 00432 m_istr->clear(std::ios::badbit); 00433 return false; 00434 } 00435 m_istr->ignore(); 00436 // read values into temp variables, then create a new HeavyIon object 00437 int nh =0, np =0, nt =0, nc =0, 00438 neut = 0, prot = 0, nw =0, nwn =0, nwnw =0; 00439 float impact = 0., plane = 0., xcen = 0., inel = 0.; 00440 *m_istr >> nh >> np >> nt >> nc >> neut >> prot 00441 >> nw >> nwn >> nwnw >> impact >> plane >> xcen >> inel; 00442 m_istr->ignore(2,'\n'); 00443 if( nh == 0 ) return false; 00444 HeavyIon* ion = new HeavyIon(nh, np, nt, nc, neut, prot, 00445 nw, nwn, nwnw, 00446 impact, plane, xcen, inel ); 00447 // 00448 return ion; 00449 } 00450 00451 PdfInfo* IO_GenEvent::read_pdf_info() 00452 { 00453 // assumes mode has already been checked 00454 // 00455 // test to be sure the next entry is of type "F" then ignore it 00456 if ( !(*m_istr) || m_istr->peek() !='F') { 00457 std::cerr << "IO_GenEvent::read_pdf_info setting badbit." << std::endl; 00458 m_istr->clear(std::ios::badbit); 00459 return false; 00460 } 00461 m_istr->ignore(); 00462 // read values into temp variables, then create a new PdfInfo object 00463 int id1 =0, id2 =0; 00464 double x1 = 0., x2 = 0., scale = 0., pdf1 = 0., pdf2 = 0.; 00465 *m_istr >> id1 >> id2 >> x1 >> x2 >> scale >> pdf1 >> pdf2; 00466 m_istr->ignore(2,'\n'); 00467 if( id1 == 0 ) return false; 00468 PdfInfo* pdf = new PdfInfo( id1, id2, x1, x2, scale, pdf1, pdf2); 00469 // 00470 return pdf; 00471 } 00472 00473 GenParticle* IO_GenEvent::read_particle( 00474 TempParticleMap& particle_to_end_vertex ){ 00475 // assumes mode has already been checked 00476 // 00477 // test to be sure the next entry is of type "P" then ignore it 00478 if ( !(*m_istr) || m_istr->peek()!='P' ) { 00479 std::cerr << "IO_GenEvent::read_particle setting badbit." 00480 << std::endl; 00481 m_istr->clear(std::ios::badbit); 00482 return false; 00483 } 00484 m_istr->ignore(); 00485 // 00486 // declare variables to be read in to, and read everything except flow 00487 double px = 0., py = 0., pz = 0., e = 0., m = 0., theta = 0., phi = 0.; 00488 int bar_code = 0, id = 0, status = 0, end_vtx_code = 0, flow_size = 0; 00489 *m_istr >> bar_code >> id >> px >> py >> pz >> e >> m >> status 00490 >> theta >> phi >> end_vtx_code >> flow_size; 00491 // 00492 // read flow patterns if any exist 00493 Flow flow; 00494 int code_index, code; 00495 for ( int i = 1; i <= flow_size; ++i ) { 00496 *m_istr >> code_index >> code; 00497 flow.set_icode( code_index,code); 00498 } 00499 m_istr->ignore(2,'\n'); // '\n' at end of entry 00500 GenParticle* p = new GenParticle( FourVector(px,py,pz,e), 00501 id, status, flow, 00502 Polarization(theta,phi) ); 00503 p->set_generated_mass( m ); 00504 p->suggest_barcode( bar_code ); 00505 // 00506 // all particles are connected to their end vertex separately 00507 // after all particles and vertices have been created - so we keep 00508 // a map of all particles that have end vertices 00509 if ( end_vtx_code != 0 ) { 00510 particle_to_end_vertex.addEndParticle(p,end_vtx_code); 00511 } 00512 return p; 00513 } 00514 00515 ParticleData* IO_GenEvent::read_particle_data( ParticleDataTable* pdt ) { 00516 // assumes mode has already been checked 00517 // 00518 // test to be sure the next entry is of type "D" then ignore it 00519 if ( !(*m_istr) || m_istr->peek()!='D' ) return false; 00520 m_istr->ignore(); 00521 // 00522 // read values into temp variables then create new ParticleData object 00523 char its_name[22]; 00524 int its_id = 0, its_spin = 0; 00525 double its_charge = 0, its_mass = 0, its_clifetime = 0; 00526 *m_istr >> its_id >> its_charge >> its_mass 00527 >> its_clifetime >> its_spin; 00528 m_istr->ignore(1); // eat the " " 00529 m_istr->getline( its_name, 22, '\n' ); 00530 ParticleData* pdata = new ParticleData( its_name, its_id, its_charge, 00531 its_mass, its_clifetime, 00532 double(its_spin)/2.); 00533 pdt->insert(pdata); 00534 return pdata; 00535 } 00536 00537 bool IO_GenEvent::write_end_listing() { 00538 if ( m_finished_first_event_io && (m_ostr != NULL) ) { 00539 m_common_io.write_IO_GenEvent_End(*m_ostr); 00540 *m_ostr << std::flush; 00541 m_finished_first_event_io = 0; 00542 return true; 00543 } 00544 return false; 00545 } 00546 00547 } // HepMC