00001
00002
00004
00005
00007
00008 #include "HepMC/IO_Ascii.h"
00009 #include "HepMC/GenEvent.h"
00010 #include "HepMC/ParticleDataTable.h"
00011 #include "HepMC/Version.h"
00012
00013 namespace HepMC {
00014
00015 IO_Ascii::IO_Ascii( const char* filename, std::ios::openmode mode )
00016 : m_mode(mode), m_file(filename, mode), m_finished_first_event_io(0)
00017 {
00018 if ( (m_mode&std::ios::out && m_mode&std::ios::in) ||
00019 (m_mode&std::ios::app && m_mode&std::ios::in) ) {
00020 std::cerr << "IO_Ascii::IO_Ascii Error, open of file requested "
00021 << "of input AND output type. Not allowed. Closing file."
00022 << std::endl;
00023 m_file.close();
00024 return;
00025 }
00026
00027
00028 m_file.precision(16);
00029
00030 m_file.setf(std::ios::dec,std::ios::basefield);
00031 m_file.setf(std::ios::scientific,std::ios::floatfield);
00032 }
00033
00034 IO_Ascii::~IO_Ascii() {
00035 write_end_listing();
00036 m_file.close();
00037 }
00038
00039 void IO_Ascii::print( std::ostream& ostr ) const {
00040 ostr << "IO_Ascii: unformated ascii file IO for machine reading.\n"
00041 << "\tFile openmode: " << m_mode
00042 << " file state: " << m_file.rdstate()
00043 << " bad:" << (m_file.rdstate()&std::ios::badbit)
00044 << " eof:" << (m_file.rdstate()&std::ios::eofbit)
00045 << " fail:" << (m_file.rdstate()&std::ios::failbit)
00046 << " good:" << (m_file.rdstate()&std::ios::goodbit) << std::endl;
00047 }
00048
00049 void IO_Ascii::write_event( const GenEvent* evt ) {
00051
00052
00053 if ( !evt || !m_file ) return;
00054 if ( !m_mode&std::ios::out ) {
00055 std::cerr << "HepMC::IO_Ascii::write_event "
00056 << " attempt to write to input file." << std::endl;
00057 return;
00058 }
00059
00060
00061 if ( !m_finished_first_event_io ) {
00062 m_finished_first_event_io = 1;
00063 m_file << "\n" << "HepMC::Version " << versionName();
00064 m_file << "\n" << "HepMC::IO_Ascii-START_EVENT_LISTING\n";
00065 }
00066
00067
00068
00069 std::vector<long int> random_states = evt->random_states();
00070 m_file << 'E';
00071 output( evt->event_number() );
00072 output( evt->event_scale() );
00073 output( evt->alphaQCD() );
00074 output( evt->alphaQED() );
00075 output( evt->signal_process_id() );
00076 output( ( evt->signal_process_vertex() ?
00077 evt->signal_process_vertex()->barcode() : 0 ) );
00078 output( evt->vertices_size() );
00079 output( (int)random_states.size() );
00080 for ( std::vector<long int>::iterator rs = random_states.begin();
00081 rs != random_states.end(); ++rs ) {
00082 output( *rs );
00083 }
00084 output( (int)evt->weights().size() );
00085 for ( WeightContainer::const_iterator w = evt->weights().begin();
00086 w != evt->weights().end(); ++w ) {
00087 output( *w );
00088 }
00089 output('\n');
00090
00091
00092 for ( GenEvent::vertex_const_iterator v = evt->vertices_begin();
00093 v != evt->vertices_end(); ++v ) {
00094 write_vertex( *v );
00095 }
00096 }
00097
00098 bool IO_Ascii::fill_next_event( GenEvent* evt ){
00099
00100
00101
00102 if ( !evt ) {
00103 std::cerr
00104 << "IO_Ascii::fill_next_event error - passed null event."
00105 << std::endl;
00106 return 0;
00107 }
00108
00109 if ( !m_file ) return 0;
00110 if ( !(m_mode&std::ios::in) ) {
00111 std::cerr << "HepMC::IO_Ascii::fill_next_event "
00112 << " attempt to read from output file." << std::endl;
00113 return 0;
00114 }
00115
00116
00117
00118
00119 if ( !m_finished_first_event_io ) {
00120 m_file.seekg( 0 );
00121 if (!search_for_key_end( m_file,
00122 "HepMC::IO_Ascii-START_EVENT_LISTING\n")){
00123 std::cerr << "IO_Ascii::fill_next_event start key not found "
00124 << "setting badbit." << std::endl;
00125 m_file.clear(std::ios::badbit);
00126 return 0;
00127 }
00128 m_finished_first_event_io = 1;
00129 }
00130
00131
00132 if ( !m_file || m_file.peek()!='E' ) {
00133
00134
00135 if ( eat_key(m_file, "HepMC::IO_Ascii-END_EVENT_LISTING\n") ) {
00136 bool search_result = search_for_key_end(m_file,
00137 "HepMC::IO_Ascii-START_EVENT_LISTING\n");
00138 if ( !search_result ) {
00139
00140 m_file.clear(std::ios::eofbit);
00141 return 0;
00142 }
00143 } else {
00144 std::cerr << "IO_Ascii::fill_next_event end key not found "
00145 << "setting badbit." << std::endl;
00146 m_file.clear(std::ios::badbit);
00147 return 0;
00148 }
00149 }
00150 m_file.ignore();
00151
00152 int event_number = 0, signal_process_id = 0, signal_process_vertex = 0,
00153 num_vertices = 0, random_states_size = 0, weights_size = 0;
00154 double eventScale = 0, alpha_qcd = 0, alpha_qed = 0;
00155 m_file >> event_number >> eventScale >> alpha_qcd >> alpha_qed
00156 >> signal_process_id >> signal_process_vertex
00157 >> num_vertices >> random_states_size;
00158 std::vector<long int> random_states(random_states_size);
00159 for ( int i = 0; i < random_states_size; ++i ) {
00160 m_file >> random_states[i];
00161 }
00162 m_file >> weights_size;
00163 WeightContainer weights(weights_size);
00164 for ( int ii = 0; ii < weights_size; ++ii ) m_file >> weights[ii];
00165 m_file.ignore(2,'\n');
00166
00167
00168 evt->set_signal_process_id( signal_process_id );
00169 evt->set_event_number( event_number );
00170 evt->weights() = weights;
00171 evt->set_random_states( random_states );
00172
00173
00174
00175 TempParticleMap particle_to_end_vertex;
00176
00177
00178 for ( int iii = 1; iii <= num_vertices; ++iii ) {
00179 GenVertex* v = read_vertex(particle_to_end_vertex);
00180 evt->add_vertex( v );
00181 }
00182
00183 if ( signal_process_vertex ) {
00184 evt->set_signal_process_vertex(
00185 evt->barcode_to_vertex(signal_process_vertex) );
00186 }
00187
00188
00189 for ( std::map<int,GenParticle*>::iterator pmap
00190 = particle_to_end_vertex.order_begin();
00191 pmap != particle_to_end_vertex.order_end(); ++pmap ) {
00192 GenParticle* p = pmap->second;
00193 int vtx = particle_to_end_vertex.end_vertex( p );
00194 GenVertex* itsDecayVtx = evt->barcode_to_vertex(vtx);
00195 if ( itsDecayVtx ) itsDecayVtx->add_particle_in( p );
00196 else {
00197 std::cerr << "IO_Ascii::fill_next_event ERROR particle points"
00198 << "\n to null end vertex. " <<std::endl;
00199 }
00200 }
00201 return 1;
00202 }
00203
00204 void IO_Ascii::write_comment( const std::string comment ) {
00205
00206 if ( !m_file ) return;
00207 if ( !m_mode&std::ios::out ) {
00208 std::cerr << "HepMC::IO_Ascii::write_particle_data_table "
00209 << " attempt to write to input file." << std::endl;
00210 return;
00211 }
00212
00213 write_end_listing();
00214
00215 m_file << "\n" << "HepMC::IO_Ascii-COMMENT\n";
00216 m_file << comment << std::endl;
00217 }
00218
00219 void IO_Ascii::write_particle_data_table( const ParticleDataTable* pdt) {
00220
00221
00222 if ( !m_file ) return;
00223 if ( !m_mode&std::ios::out ) {
00224 std::cerr << "HepMC::IO_Ascii::write_particle_data_table "
00225 << " attempt to write to input file." << std::endl;
00226 return;
00227 }
00228
00229 write_end_listing();
00230
00231 m_file << "\n" << "HepMC::IO_Ascii-START_PARTICLE_DATA\n";
00232 for ( ParticleDataTable::const_iterator pd = pdt->begin();
00233 pd != pdt->end(); pd++ ) {
00234 write_particle_data( pd->second );
00235 }
00236 m_file << "HepMC::IO_Ascii-END_PARTICLE_DATA\n" << std::flush;
00237 }
00238
00239 bool IO_Ascii::fill_particle_data_table( ParticleDataTable* pdt ) {
00240
00241
00242 if ( !pdt ) {
00243 std::cerr
00244 << "IO_Ascii::fill_particle_data_table - passed null table."
00245 << std::endl;
00246 return 0;
00247 }
00248
00249
00250 if ( !m_file ) return 0;
00251 if ( !m_mode&std::ios::in ) {
00252 std::cerr << "HepMC::IO_Ascii::fill_particle_data_table "
00253 << " attempt to read from output file." << std::endl;
00254 return 0;
00255 }
00256
00257 int initial_file_position = m_file.tellg();
00258 std::ios::iostate initial_state = m_file.rdstate();
00259 m_file.seekg( 0 );
00260
00261 if (!search_for_key_end( m_file,
00262 "HepMC::IO_Ascii-START_PARTICLE_DATA\n")) {
00263 m_file.seekg( initial_file_position );
00264 std::cerr << "IO_Ascii::fill_particle_data_table start key not "
00265 << "found setting badbit." << std::endl;
00266 m_file.clear(std::ios::badbit);
00267 return 0;
00268 }
00269
00270 pdt->set_description("Read with IO_Ascii");
00271
00272
00273 while ( read_particle_data( pdt ) );
00274
00275
00276 if ( !eat_key(m_file,"HepMC::IO_Ascii-END_PARTICLE_DATA\n") ){
00277 std::cerr << "IO_Ascii::fill_particle_data_table end key not "
00278 << "found setting badbit." << std::endl;
00279 m_file.clear(std::ios::badbit);
00280 }
00281
00282 m_file.clear( initial_state );
00283 m_file.seekg( initial_file_position );
00284 return 1;
00285 }
00286
00287 void IO_Ascii::write_vertex( GenVertex* v ) {
00288
00289 if ( !v || !m_file ) {
00290 std::cerr << "IO_Ascii::write_vertex !v||!m_file, "
00291 << "v="<< v << " setting badbit" << std::endl;
00292 m_file.clear(std::ios::badbit);
00293 return;
00294 }
00295
00296
00297 int num_orphans_in = 0;
00298 for ( GenVertex::particles_in_const_iterator p1
00299 = v->particles_in_const_begin();
00300 p1 != v->particles_in_const_end(); ++p1 ) {
00301 if ( !(*p1)->production_vertex() ) ++num_orphans_in;
00302 }
00303
00304 m_file << 'V';
00305 output( v->barcode() );
00306 output( v->id() );
00307 output( v->position().x() );
00308 output( v->position().y() );
00309 output( v->position().z() );
00310 output( v->position().t() );
00311 output( num_orphans_in );
00312 output( (int)v->particles_out_size() );
00313 output( (int)v->weights().size() );
00314 for ( WeightContainer::iterator w = v->weights().begin();
00315 w != v->weights().end(); ++w ) {
00316 output( *w );
00317 }
00318 output('\n');
00319 for ( GenVertex::particles_in_const_iterator p2
00320 = v->particles_in_const_begin();
00321 p2 != v->particles_in_const_end(); ++p2 ) {
00322 if ( !(*p2)->production_vertex() ) {
00323 write_particle( *p2 );
00324 }
00325 }
00326 for ( GenVertex::particles_out_const_iterator p3
00327 = v->particles_out_const_begin();
00328 p3 != v->particles_out_const_end(); ++p3 ) {
00329 write_particle( *p3 );
00330 }
00331 }
00332
00333 void IO_Ascii::write_particle( GenParticle* p ) {
00334
00335 if ( !p || !m_file ) {
00336 std::cerr << "IO_Ascii::write_vertex !p||!m_file, "
00337 << "v="<< p << " setting badbit" << std::endl;
00338 m_file.clear(std::ios::badbit);
00339 return;
00340 }
00341 m_file << 'P';
00342 output( p->barcode() );
00343 output( p->pdg_id() );
00344 output( p->momentum().px() );
00345 output( p->momentum().py() );
00346 output( p->momentum().pz() );
00347 output( p->momentum().e() );
00348 output( p->status() );
00349 output( p->polarization().theta() );
00350 output( p->polarization().phi() );
00351
00352
00353 output( ( p->end_vertex() ? p->end_vertex()->barcode() : 0 ) );
00354 m_file << ' ' << p->flow() << "\n";
00355 }
00356
00357 void IO_Ascii::write_particle_data( const ParticleData* pdata ) {
00358
00359 if ( !pdata || !m_file ) {
00360 std::cerr << "IO_Ascii::write_vertex !pdata||!m_file, "
00361 << "pdata="<< pdata << " setting badbit" << std::endl;
00362 m_file.clear(std::ios::badbit);
00363 return;
00364 }
00365 m_file << 'D';
00366 output( pdata->pdg_id() );
00367 output( pdata->charge() );
00368 output( pdata->mass() );
00369 output( pdata->clifetime() );
00370 output( (int)(pdata->spin()*2.+.1) );
00371
00372 m_file << " " << pdata->name().substr(0,21) << "\n";
00373 }
00374
00375 GenVertex* IO_Ascii::read_vertex
00376 ( TempParticleMap& particle_to_end_vertex )
00377 {
00378
00379
00380
00381 if ( !m_file || m_file.peek()!='V' ) {
00382 std::cerr << "IO_Ascii::read_vertex setting badbit." << std::endl;
00383 m_file.clear(std::ios::badbit);
00384 return 0;
00385 }
00386 m_file.ignore();
00387
00388 int identifier =0, id =0, num_orphans_in =0,
00389 num_particles_out = 0, weights_size = 0;
00390 double x = 0., y = 0., z = 0., t = 0.;
00391 m_file >> identifier >> id >> x >> y >> z >> t
00392 >> num_orphans_in >> num_particles_out >> weights_size;
00393 WeightContainer weights(weights_size);
00394 for ( int i1 = 0; i1 < weights_size; ++i1 ) m_file >> weights[i1];
00395 m_file.ignore(2,'\n');
00396 GenVertex* v = new GenVertex( FourVector(x,y,z,t),
00397 id, weights);
00398 v->suggest_barcode( identifier );
00399
00400
00401
00402
00403
00404 for ( int i2 = 1; i2 <= num_orphans_in; ++i2 ) {
00405 read_particle(particle_to_end_vertex);
00406 }
00407 for ( int i3 = 1; i3 <= num_particles_out; ++i3 ) {
00408 v->add_particle_out( read_particle(particle_to_end_vertex) );
00409 }
00410 return v;
00411 }
00412
00413 GenParticle* IO_Ascii::read_particle(
00414 TempParticleMap& particle_to_end_vertex ){
00415
00416
00417
00418 if ( !m_file || m_file.peek()!='P' ) {
00419 std::cerr << "IO_Ascii::read_particle setting badbit."
00420 << std::endl;
00421 m_file.clear(std::ios::badbit);
00422 return 0;
00423 }
00424 m_file.ignore();
00425
00426
00427 double px = 0., py = 0., pz = 0., e = 0., theta = 0., phi = 0.;
00428 int bar_code = 0, id = 0, status = 0, end_vtx_code = 0, flow_size = 0;
00429 m_file >> bar_code >> id >> px >> py >> pz >> e >> status
00430 >> theta >> phi >> end_vtx_code >> flow_size;
00431
00432
00433 Flow flow;
00434 int code_index, code;
00435 for ( int i = 1; i <= flow_size; ++i ) {
00436 m_file >> code_index >> code;
00437 flow.set_icode( code_index,code);
00438 }
00439 m_file.ignore(2,'\n');
00440 GenParticle* p = new GenParticle( FourVector(px,py,pz,e),
00441 id, status, flow,
00442 Polarization(theta,phi) );
00443 p->suggest_barcode( bar_code );
00444
00445
00446
00447
00448 if ( end_vtx_code != 0 ) {
00449 particle_to_end_vertex.addEndParticle(p,end_vtx_code);
00450 }
00451 return p;
00452 }
00453
00454 ParticleData* IO_Ascii::read_particle_data( ParticleDataTable* pdt ) {
00455
00456
00457
00458 if ( !m_file || m_file.peek()!='D' ) return 0;
00459 m_file.ignore();
00460
00461
00462 char its_name[22];
00463 int its_id = 0, its_spin = 0;
00464 double its_charge = 0, its_mass = 0, its_clifetime = 0;
00465 m_file >> its_id >> its_charge >> its_mass
00466 >> its_clifetime >> its_spin;
00467 m_file.ignore(1);
00468 m_file.getline( its_name, 22, '\n' );
00469 ParticleData* pdata = new ParticleData( its_name, its_id, its_charge,
00470 its_mass, its_clifetime,
00471 double(its_spin)/2.);
00472 pdt->insert(pdata);
00473 return pdata;
00474 }
00475
00476 bool IO_Ascii::write_end_listing() {
00477 if ( m_finished_first_event_io && m_mode&std::ios::out ) {
00478 m_file << "HepMC::IO_Ascii-END_EVENT_LISTING\n" << std::flush;
00479 m_finished_first_event_io = 0;
00480 return 1;
00481 }
00482 return 0;
00483 }
00484
00485 bool IO_Ascii::search_for_key_end( std::istream& in, const char* key ) {
00489
00490 char c[1];
00491 unsigned int index = 0;
00492 while ( in.get(c[0]) ) {
00493 if ( c[0] == key[index] ) {
00494 ++index;
00495 } else { index = 0; }
00496 if ( index == strlen(key) ) return 1;
00497 }
00498 return 0;
00499 }
00500
00501 bool IO_Ascii::search_for_key_beginning( std::istream& in,
00502 const char* key ) {
00504 if ( search_for_key_end( in, key) ) {
00505 int i = strlen(key);
00506 while ( i>=0 ) in.putback(key[i--]);
00507 return 1;
00508 } else {
00509 in.putback(EOF);
00510 in.clear();
00511 return 0;
00512 }
00513 }
00514
00515 bool IO_Ascii::eat_key( std::iostream& in, const char* key ) {
00520 int key_length = strlen(key);
00521
00522
00523 char* c = new char[key_length +1];
00524 int i=0;
00525
00526
00527
00528 while ( in.get(c[i]) && c[i]==key[i] && i<key_length ) {
00529 ++i;
00530 }
00531 if ( i == key_length ) {
00532 delete [] c;
00533 return 1;
00534 }
00535
00536
00537
00538
00539 while ( i>=0 ) in.putback(c[i--]);
00540 delete c;
00541 return 0;
00542 }
00543
00544 int IO_Ascii::find_in_map( const std::map<GenVertex*,int>& m,
00545 GenVertex* v ) const {
00546 std::map<GenVertex*,int>::const_iterator iter = m.find(v);
00547 if ( iter == m.end() ) return 0;
00548 return iter->second;
00549 }
00550
00551 }
00552
00553
00554
00555
00556
00557