hepmc - Blame information for rev 48
Subversion Repositories:
| Rev | Author | Line No. | Line |
|---|---|---|---|
| 40 | garren | 1 | //-------------------------------------------------------------------------- |
| 2 | |||
| 3 | ////////////////////////////////////////////////////////////////////////// | ||
| 4 | // garren@fnal.gov, July 2006 | ||
| 5 | // event input/output in ascii format for machine reading | ||
| 6 | // extended format contains HeavyIon and PdfInfo classes | ||
| 7 | ////////////////////////////////////////////////////////////////////////// | ||
| 8 | |||
| 9 | #include "HepMC/IO_ExtendedAscii.h" | ||
| 10 | #include "HepMC/GenEvent.h" | ||
| 11 | #include "HepMC/ParticleDataTable.h" | ||
| 12 | #include "HepMC/HeavyIon.h" | ||
| 13 | #include "HepMC/PdfInfo.h" | ||
| 14 | |||
| 15 | namespace HepMC { | ||
| 16 | |||
| 17 | IO_ExtendedAscii::IO_ExtendedAscii( const char* filename, std::ios::openmode mode ) | ||
| 18 | : m_mode(mode), m_file(filename, mode), m_finished_first_event_io(0) | ||
| 19 | { | ||
| 20 | if ( (m_mode&std::ios::out && m_mode&std::ios::in) || | ||
| 21 | (m_mode&std::ios::app && m_mode&std::ios::in) ) { | ||
| 22 | std::cerr << "IO_ExtendedAscii::IO_ExtendedAscii Error, open of file requested " | ||
| 23 | << "of input AND output type. Not allowed. Closing file." | ||
| 24 | << std::endl; | ||
| 25 | m_file.close(); | ||
| 26 | } | ||
| 27 | // precision 16 (# digits following decimal point) is the minimum that | ||
| 28 | // will capture the full information stored in a double | ||
| 29 | m_file.precision(16); | ||
| 30 | // we use decimal to store integers, because it is smaller than hex! | ||
| 31 | m_file.setf(std::ios::dec,std::ios::basefield); | ||
| 32 | m_file.setf(std::ios::scientific,std::ios::floatfield); | ||
| 33 | } | ||
| 34 | |||
| 35 | IO_ExtendedAscii::~IO_ExtendedAscii() { | ||
| 36 | write_end_listing(); | ||
| 37 | m_file.close(); | ||
| 38 | } | ||
| 39 | |||
| 40 | void IO_ExtendedAscii::print( std::ostream& ostr ) const { | ||
| 41 | ostr << "IO_ExtendedAscii: unformated ascii file IO for machine reading.\n" | ||
| 42 | << "\tFile openmode: " << m_mode | ||
| 43 | << " file state: " << m_file.rdstate() | ||
| 44 | << " bad:" << (m_file.rdstate()&std::ios::badbit) | ||
| 45 | << " eof:" << (m_file.rdstate()&std::ios::eofbit) | ||
| 46 | << " fail:" << (m_file.rdstate()&std::ios::failbit) | ||
| 47 | << " good:" << (m_file.rdstate()&std::ios::goodbit) << std::endl; | ||
| 48 | } | ||
| 49 | |||
| 50 | void IO_ExtendedAscii::write_event( const GenEvent* evt ) { | ||
| 51 | // Writes evt to m_file. It does NOT delete the event after writing. | ||
| 52 | // | ||
| 53 | // check the state of m_file is good, and that it is in output mode | ||
| 54 | if ( !evt || !m_file ) return; | ||
| 55 | if ( !m_mode&std::ios::out ) { | ||
| 56 | std::cerr << "HepMC::IO_ExtendedAscii::write_event " | ||
| 57 | << " attempt to write to input file." << std::endl; | ||
| 58 | return; | ||
| 59 | } | ||
| 60 | // | ||
| 61 | // write event listing key before first event only. | ||
| 62 | if ( !m_finished_first_event_io ) { | ||
| 63 | m_finished_first_event_io = 1; | ||
| 64 | m_file << "\n" << "HepMC::IO_ExtendedAscii-START_EVENT_LISTING\n"; | ||
| 65 | } | ||
| 66 | // | ||
| 67 | // output the event data including the number of primary vertices | ||
| 68 | // and the total number of vertices | ||
| 69 | std::vector<long int> random_states = evt->random_states(); | ||
| 70 | m_file << 'E'; | ||
| 71 | output( evt->event_number() ); | ||
| 72 | output( evt->event_scale() ); | ||
| 73 | output( evt->alphaQCD() ); | ||
| 74 | output( evt->alphaQED() ); | ||
| 75 | output( evt->signal_process_id() ); | ||
| 76 | output( ( evt->signal_process_vertex() ? | ||
| 77 | evt->signal_process_vertex()->barcode() : 0 ) ); | ||
| 78 | output( evt->vertices_size() ); // total number of vertices. | ||
| 79 | output( (int)random_states.size() ); | ||
| 80 | for ( std::vector<long int>::iterator rs = random_states.begin(); | ||
| 81 | rs != random_states.end(); ++rs ) { | ||
| 82 | output( *rs ); | ||
| 83 | } | ||
| 84 | output( (int)evt->weights().size() ); | ||
| 85 | for ( WeightContainer::const_iterator w = evt->weights().begin(); | ||
| 86 | w != evt->weights().end(); ++w ) { | ||
| 87 | output( *w ); | ||
| 88 | } | ||
| 89 | output('\n'); | ||
| 90 | write_heavy_ion( evt->heavy_ion() ); | ||
| 91 | write_pdf_info( evt->pdf_info() ); | ||
| 92 | // | ||
| 93 | // Output all of the vertices - note there is no real order. | ||
| 94 | for ( GenEvent::vertex_const_iterator v = evt->vertices_begin(); | ||
| 95 | v != evt->vertices_end(); ++v ) { | ||
| 96 | write_vertex( *v ); | ||
| 97 | } | ||
| 98 | } | ||
| 99 | |||
| 100 | bool IO_ExtendedAscii::fill_next_event( GenEvent* evt ){ | ||
| 101 | // | ||
| 102 | // | ||
| 103 | // test that evt pointer is not null | ||
| 104 | if ( !evt ) { | ||
| 105 | std::cerr | ||
| 106 | << "IO_ExtendedAscii::fill_next_event error - passed null event." | ||
| 107 | << std::endl; | ||
| 108 | return 0; | ||
| 109 | } | ||
| 110 | // check the state of m_file is good, and that it is in input mode | ||
| 111 | if ( !m_file ) return 0; | ||
| 112 | if ( !(m_mode&std::ios::in) ) { | ||
| 113 | std::cerr << "HepMC::IO_ExtendedAscii::fill_next_event " | ||
| 114 | << " attempt to read from output file." << std::endl; | ||
| 115 | return 0; | ||
| 116 | } | ||
| 117 | // | ||
| 118 | // search for event listing key before first event only. | ||
| 119 | // | ||
| 120 | // skip through the file just after first occurence of the start_key | ||
| 121 | if ( !m_finished_first_event_io ) { | ||
| 122 | m_file.seekg( 0 ); // go to position zero in the file. | ||
| 123 | if (!search_for_key_end( m_file, | ||
| 124 | "HepMC::IO_ExtendedAscii-START_EVENT_LISTING\n")){ | ||
| 125 | std::cerr << "IO_ExtendedAscii::fill_next_event start key not found " | ||
| 126 | << "setting badbit." << std::endl; | ||
| 127 | m_file.clear(std::ios::badbit); | ||
| 128 | return 0; | ||
| 129 | } | ||
| 130 | m_finished_first_event_io = 1; | ||
| 131 | } | ||
| 132 | // | ||
| 133 | // test to be sure the next entry is of type "E" then ignore it | ||
| 134 | if ( !m_file || m_file.peek()!='E' ) { | ||
| 135 | // if the E is not the next entry, then check to see if it is | ||
| 136 | // the end event listing key - if yes, search for another start key | ||
| 137 | if ( eat_key(m_file, "HepMC::IO_ExtendedAscii-END_EVENT_LISTING\n") ) { | ||
| 138 | bool search_result = search_for_key_end(m_file, | ||
| 139 | "HepMC::IO_ExtendedAscii-START_EVENT_LISTING\n"); | ||
| 140 | if ( !search_result ) { | ||
| 141 | // this is the only case where we set an EOF state | ||
| 142 | m_file.clear(std::ios::eofbit); | ||
| 143 | return 0; | ||
| 144 | } | ||
| 145 | } else { | ||
| 146 | std::cerr << "IO_ExtendedAscii::fill_next_event end key not found " | ||
| 147 | << "setting badbit." << std::endl; | ||
| 148 | m_file.clear(std::ios::badbit); | ||
| 149 | return 0; | ||
| 150 | } | ||
| 151 | } | ||
| 152 | m_file.ignore(); | ||
| 153 | // read values into temp variables, then create a new GenEvent | ||
| 154 | int event_number = 0, signal_process_id = 0, signal_process_vertex = 0, | ||
| 155 | num_vertices = 0, random_states_size = 0, weights_size = 0; | ||
| 156 | double eventScale = 0, alpha_qcd = 0, alpha_qed = 0; | ||
| 157 | m_file >> event_number >> eventScale >> alpha_qcd >> alpha_qed | ||
| 158 | >> signal_process_id >> signal_process_vertex | ||
| 159 | >> num_vertices >> random_states_size; | ||
| 160 | std::vector<long int> random_states(random_states_size); | ||
| 161 | for ( int i = 0; i < random_states_size; ++i ) { | ||
| 162 | m_file >> random_states[i]; | ||
| 163 | } | ||
| 164 | m_file >> weights_size; | ||
| 165 | WeightContainer weights(weights_size); | ||
| 166 | for ( int ii = 0; ii < weights_size; ++ii ) m_file >> weights[ii]; | ||
| 167 | m_file.ignore(2,'\n'); | ||
| 168 | // | ||
| 169 | // fill signal_process_id, event_number, weights, random_states | ||
| 170 | evt->set_signal_process_id( signal_process_id ); | ||
| 171 | evt->set_event_number( event_number ); | ||
| 172 | evt->weights() = weights; | ||
| 173 | evt->set_random_states( random_states ); | ||
| 174 | // get HeavyIon and PdfInfo | ||
| 175 | evt->set_heavy_ion( read_heavy_ion() ); | ||
| 176 | evt->set_pdf_info( read_pdf_info() ); | ||
| 177 | // | ||
| 178 | // the end vertices of the particles are not connected until | ||
| 179 | // after the event is read --- we store the values in a map until then | ||
| 180 | std::map<GenParticle*,int> particle_to_end_vertex; | ||
| 181 | // | ||
| 182 | // read in the vertices | ||
| 183 | for ( int iii = 1; iii <= num_vertices; ++iii ) { | ||
| 184 | GenVertex* v = read_vertex(particle_to_end_vertex); | ||
| 185 | evt->add_vertex( v ); | ||
| 186 | } | ||
| 187 | // set the signal process vertex | ||
| 188 | if ( signal_process_vertex ) { | ||
| 189 | evt->set_signal_process_vertex( | ||
| 190 | evt->barcode_to_vertex(signal_process_vertex) ); | ||
| 191 | } | ||
| 192 | // | ||
| 193 | // last connect particles to their end vertices | ||
| 194 | for ( std::map<GenParticle*,int>::iterator pmap | ||
| 195 | = particle_to_end_vertex.begin(); | ||
| 196 | pmap != particle_to_end_vertex.end(); ++pmap ) { | ||
| 197 | GenVertex* itsDecayVtx = evt->barcode_to_vertex(pmap->second); | ||
| 198 | if ( itsDecayVtx ) itsDecayVtx->add_particle_in( pmap->first ); | ||
| 199 | else { | ||
| 200 | std::cerr << "IO_ExtendedAscii::fill_next_event ERROR particle points" | ||
| 201 | << "\n to null end vertex. " <<std::endl; | ||
| 202 | } | ||
| 203 | } | ||
| 204 | return 1; | ||
| 205 | } | ||
| 206 | |||
| 207 | void IO_ExtendedAscii::write_comment( const std::string comment ) { | ||
| 208 | // check the state of m_file is good, and that it is in output mode | ||
| 209 | if ( !m_file ) return; | ||
| 210 | if ( !m_mode&std::ios::out ) { | ||
| 211 | std::cerr << "HepMC::IO_ExtendedAscii::write_comment " | ||
| 212 | << " attempt to write to input file." << std::endl; | ||
| 213 | return; | ||
| 214 | } | ||
| 215 | // write end of event listing key if events have already been written | ||
| 216 | write_end_listing(); | ||
| 217 | // insert the comment key before the comment | ||
| 218 | m_file << "\n" << "HepMC::IO_ExtendedAscii-COMMENT\n"; | ||
| 219 | m_file << comment << std::endl; | ||
| 220 | } | ||
| 221 | |||
| 222 | void IO_ExtendedAscii::write_particle_data_table( const ParticleDataTable* pdt) { | ||
| 223 | // | ||
| 224 | // check the state of m_file is good, and that it is in output mode | ||
| 225 | if ( !m_file ) return; | ||
| 226 | if ( !m_mode&std::ios::out ) { | ||
| 227 | std::cerr << "HepMC::IO_ExtendedAscii::write_particle_data_table " | ||
| 228 | << " attempt to write to input file." << std::endl; | ||
| 229 | return; | ||
| 230 | } | ||
| 231 | // write end of event listing key if events have already been written | ||
| 232 | write_end_listing(); | ||
| 233 | // | ||
| 234 | m_file << "\n" << "HepMC::IO_ExtendedAscii-START_PARTICLE_DATA\n"; | ||
| 235 | for ( ParticleDataTable::const_iterator pd = pdt->begin(); | ||
| 236 | pd != pdt->end(); pd++ ) { | ||
| 237 | write_particle_data( pd->second ); | ||
| 238 | } | ||
| 239 | m_file << "HepMC::IO_ExtendedAscii-END_PARTICLE_DATA\n" << std::flush; | ||
| 240 | } | ||
| 241 | |||
| 242 | bool IO_ExtendedAscii::fill_particle_data_table( ParticleDataTable* pdt ) { | ||
| 243 | // | ||
| 244 | // test that pdt pointer is not null | ||
| 245 | if ( !pdt ) { | ||
| 246 | std::cerr | ||
| 247 | << "IO_ExtendedAscii::fill_particle_data_table - passed null table." | ||
| 248 | << std::endl; | ||
| 249 | return 0; | ||
| 250 | } | ||
| 251 | // | ||
| 252 | // check the state of m_file is good, and that it is in input mode | ||
| 253 | if ( !m_file ) return 0; | ||
| 254 | if ( !m_mode&std::ios::in ) { | ||
| 255 | std::cerr << "HepMC::IO_ExtendedAscii::fill_particle_data_table " | ||
| 256 | << " attempt to read from output file." << std::endl; | ||
| 257 | return 0; | ||
| 258 | } | ||
| 259 | // position to beginning of file | ||
| 260 | int initial_file_position = m_file.tellg(); | ||
| 261 | std::ios::iostate initial_state = m_file.rdstate(); | ||
| 262 | m_file.seekg( 0 ); | ||
| 263 | // skip through the file just after first occurence of the start_key | ||
| 264 | if (!search_for_key_end( m_file, | ||
| 265 | "HepMC::IO_ExtendedAscii-START_PARTICLE_DATA\n")) { | ||
| 266 | m_file.seekg( initial_file_position ); | ||
| 267 | std::cerr << "IO_ExtendedAscii::fill_particle_data_table start key not " | ||
| 268 | << "found setting badbit." << std::endl; | ||
| 269 | m_file.clear(std::ios::badbit); | ||
| 270 | return 0; | ||
| 271 | } | ||
| 272 | // | ||
| 273 | pdt->set_description("Read with IO_ExtendedAscii"); | ||
| 274 | // | ||
| 275 | // read Individual GenParticle data entries | ||
| 276 | while ( read_particle_data( pdt ) ); | ||
| 277 | // | ||
| 278 | // eat end_key | ||
| 279 | if ( !eat_key(m_file,"HepMC::IO_ExtendedAscii-END_PARTICLE_DATA\n") ){ | ||
| 280 | std::cerr << "IO_ExtendedAscii::fill_particle_data_table end key not " | ||
| 281 | << "found setting badbit." << std::endl; | ||
| 282 | m_file.clear(std::ios::badbit); | ||
| 283 | } | ||
| 284 | // put the file back into its original state and position | ||
| 285 | m_file.clear( initial_state ); | ||
| 286 | m_file.seekg( initial_file_position ); | ||
| 287 | return 1; | ||
| 288 | } | ||
| 289 | |||
| 290 | void IO_ExtendedAscii::write_vertex( GenVertex* v ) { | ||
| 291 | // assumes mode has already been checked | ||
| 292 | if ( !v || !m_file ) { | ||
| 293 | std::cerr << "IO_ExtendedAscii::write_vertex !v||!m_file, " | ||
| 294 | << "v="<< v << " setting badbit" << std::endl; | ||
| 295 | m_file.clear(std::ios::badbit); | ||
| 296 | return; | ||
| 297 | } | ||
| 298 | // First collect info we need | ||
| 299 | // count the number of orphan particles going into v | ||
| 300 | int num_orphans_in = 0; | ||
| 301 | for ( GenVertex::particles_in_const_iterator p1 | ||
| 302 | = v->particles_in_const_begin(); | ||
| 303 | p1 != v->particles_in_const_end(); ++p1 ) { | ||
| 304 | if ( !(*p1)->production_vertex() ) ++num_orphans_in; | ||
| 305 | } | ||
| 306 | // | ||
| 307 | m_file << 'V'; | ||
| 308 | output( v->barcode() ); // v's unique identifier | ||
| 309 | output( v->id() ); | ||
| 310 | output( v->position().x() ); | ||
| 311 | output( v->position().y() ); | ||
| 312 | output( v->position().z() ); | ||
| 313 | output( v->position().t() ); | ||
| 314 | output( num_orphans_in ); | ||
| 315 | output( (int)v->particles_out_size() ); | ||
| 316 | output( (int)v->weights().size() ); | ||
| 317 | for ( WeightContainer::iterator w = v->weights().begin(); | ||
| 318 | w != v->weights().end(); ++w ) { | ||
| 319 | output( *w ); | ||
| 320 | } | ||
| 321 | output('\n'); | ||
| 322 | for ( GenVertex::particles_in_const_iterator p2 | ||
| 323 | = v->particles_in_const_begin(); | ||
| 324 | p2 != v->particles_in_const_end(); ++p2 ) { | ||
| 325 | if ( !(*p2)->production_vertex() ) { | ||
| 326 | write_particle( *p2 ); | ||
| 327 | } | ||
| 328 | } | ||
| 329 | for ( GenVertex::particles_out_const_iterator p3 | ||
| 330 | = v->particles_out_const_begin(); | ||
| 331 | p3 != v->particles_out_const_end(); ++p3 ) { | ||
| 332 | write_particle( *p3 ); | ||
| 333 | } | ||
| 334 | } | ||
| 335 | |||
| 336 | void IO_ExtendedAscii::write_heavy_ion( HeavyIon* ion ) { | ||
| 337 | // assumes mode has already been checked | ||
| 338 | if ( !m_file ) { | ||
| 339 | std::cerr << "IO_ExtendedAscii::write_heavy_ion !m_file, " | ||
| 340 | << " setting badbit" << std::endl; | ||
| 341 | m_file.clear(std::ios::badbit); | ||
| 342 | return; | ||
| 343 | } | ||
| 344 | // HeavyIon* is set to 0 by default | ||
| 345 | if ( !ion ) { | ||
| 346 | return; | ||
| 347 | } | ||
| 348 | // | ||
| 349 | m_file << 'H'; | ||
| 350 | output( ion->Ncoll_hard() ); | ||
| 351 | output( ion->Npart_proj() ); | ||
| 352 | output( ion->Npart_targ() ); | ||
| 353 | output( ion->Ncoll() ); | ||
| 354 | output( ion->spectator_neutrons() ); | ||
| 355 | output( ion->spectator_protons() ); | ||
| 356 | output( ion->N_Nwounded_collisions() ); | ||
| 357 | output( ion->Nwounded_N_collisions() ); | ||
| 358 | output( ion->Nwounded_Nwounded_collisions() ); | ||
| 359 | output( ion->impact_parameter() ); | ||
| 360 | output( ion->event_plane_angle() ); | ||
| 361 | output( ion->eccentricity() ); | ||
| 362 | output( ion->sigma_inel_NN() ); | ||
| 363 | output('\n'); | ||
| 364 | } | ||
| 365 | |||
| 366 | void IO_ExtendedAscii::write_pdf_info( PdfInfo* pdf ) { | ||
| 367 | // assumes mode has already been checked | ||
| 368 | if ( !m_file ) { | ||
| 369 | std::cerr << "IO_ExtendedAscii::write_pdf_info !m_file, " | ||
| 370 | << " setting badbit" << std::endl; | ||
| 371 | m_file.clear(std::ios::badbit); | ||
| 372 | return; | ||
| 373 | } | ||
| 374 | // PdfInfo* is set to 0 by default | ||
| 375 | if ( !pdf ) { | ||
| 376 | return; | ||
| 377 | } | ||
| 378 | // | ||
| 379 | m_file << 'F'; | ||
| 380 | output( pdf->id1() ); | ||
| 381 | output( pdf->id2() ); | ||
| 382 | output( pdf->x1() ); | ||
| 383 | output( pdf->x2() ); | ||
| 384 | output( pdf->scalePDF() ); | ||
| 385 | output( pdf->pdf1() ); | ||
| 386 | output( pdf->pdf2() ); | ||
| 387 | output('\n'); | ||
| 388 | } | ||
| 389 | |||
| 390 | void IO_ExtendedAscii::write_particle( GenParticle* p ) { | ||
| 391 | // assumes mode has already been checked | ||
| 392 | if ( !p || !m_file ) { | ||
| 393 | std::cerr << "IO_ExtendedAscii::write_particle !p||!m_file, " | ||
| 394 | << "v="<< p << " setting badbit" << std::endl; | ||
| 395 | m_file.clear(std::ios::badbit); | ||
| 396 | return; | ||
| 397 | } | ||
| 398 | m_file << 'P'; | ||
| 399 | output( p->barcode() ); | ||
| 400 | output( p->pdg_id() ); | ||
| 401 | output( p->momentum().px() ); | ||
| 402 | output( p->momentum().py() ); | ||
| 403 | output( p->momentum().pz() ); | ||
| 404 | output( p->momentum().e() ); | ||
| 48 | garren | 405 | output( p->generated_mass() ); |
| 40 | garren | 406 | output( p->status() ); |
| 407 | output( p->polarization().theta() ); | ||
| 408 | output( p->polarization().phi() ); | ||
| 409 | // since end_vertex is oftentimes null, this CREATES a null vertex | ||
| 410 | // in the map | ||
| 411 | output( ( p->end_vertex() ? p->end_vertex()->barcode() : 0 ) ); | ||
| 412 | m_file << ' ' << p->flow() << "\n"; | ||
| 413 | } | ||
| 414 | |||
| 415 | void IO_ExtendedAscii::write_particle_data( const ParticleData* pdata ) { | ||
| 416 | // assumes mode has already been checked | ||
| 417 | if ( !pdata || !m_file ) { | ||
| 418 | std::cerr << "IO_ExtendedAscii::write_particle_data !pdata||!m_file, " | ||
| 419 | << "pdata="<< pdata << " setting badbit" << std::endl; | ||
| 420 | m_file.clear(std::ios::badbit); | ||
| 421 | return; | ||
| 422 | } | ||
| 423 | m_file << 'D'; | ||
| 424 | output( pdata->pdg_id() ); | ||
| 425 | output( pdata->charge() ); | ||
| 426 | output( pdata->mass() ); | ||
| 427 | output( pdata->clifetime() ); | ||
| 428 | output( (int)(pdata->spin()*2.+.1) ); | ||
| 429 | // writes the first 21 characters starting with 0 | ||
| 430 | m_file << " " << pdata->name().substr(0,21) << "\n"; | ||
| 431 | } | ||
| 432 | |||
| 433 | GenVertex* IO_ExtendedAscii::read_vertex | ||
| 434 | ( std::map<GenParticle*,int>& particle_to_end_vertex ) | ||
| 435 | { | ||
| 436 | // assumes mode has already been checked | ||
| 437 | // | ||
| 438 | // test to be sure the next entry is of type "V" then ignore it | ||
| 439 | if ( !m_file || m_file.peek()!='V' ) { | ||
| 440 | std::cerr << "IO_ExtendedAscii::read_vertex setting badbit." << std::endl; | ||
| 441 | m_file.clear(std::ios::badbit); | ||
| 442 | return 0; | ||
| 443 | } | ||
| 444 | m_file.ignore(); | ||
| 445 | // read values into temp variables, then create a new GenVertex object | ||
| 446 | int identifier =0, id =0, num_orphans_in =0, | ||
| 447 | num_particles_out = 0, weights_size = 0; | ||
| 448 | double x = 0., y = 0., z = 0., t = 0.; | ||
| 449 | m_file >> identifier >> id >> x >> y >> z >> t | ||
| 450 | >> num_orphans_in >> num_particles_out >> weights_size; | ||
| 451 | WeightContainer weights(weights_size); | ||
| 452 | for ( int i1 = 0; i1 < weights_size; ++i1 ) m_file >> weights[i1]; | ||
| 453 | m_file.ignore(2,'\n'); | ||
| 43 | garren | 454 | GenVertex* v = new GenVertex( FourVector(x,y,z,t), |
| 40 | garren | 455 | id, weights); |
| 456 | v->suggest_barcode( identifier ); | ||
| 457 | // | ||
| 458 | // read and create the associated particles. outgoing particles are | ||
| 459 | // added to their production vertices immediately, while incoming | ||
| 460 | // particles are added to a map and handles later. | ||
| 461 | for ( int i2 = 1; i2 <= num_orphans_in; ++i2 ) { | ||
| 462 | read_particle(particle_to_end_vertex); | ||
| 463 | } | ||
| 464 | for ( int i3 = 1; i3 <= num_particles_out; ++i3 ) { | ||
| 465 | v->add_particle_out( read_particle(particle_to_end_vertex) ); | ||
| 466 | } | ||
| 467 | return v; | ||
| 468 | } | ||
| 469 | |||
| 470 | HeavyIon* IO_ExtendedAscii::read_heavy_ion() | ||
| 471 | { | ||
| 472 | // assumes mode has already been checked | ||
| 473 | // | ||
| 474 | // test to be sure the next entry is of type "H" then ignore it | ||
| 475 | if ( !m_file || m_file.peek()!='H' ) { | ||
| 476 | std::cerr << "IO_ExtendedAscii::read_heavy_ion setting badbit." << std::endl; | ||
| 477 | m_file.clear(std::ios::badbit); | ||
| 478 | return 0; | ||
| 479 | } | ||
| 480 | m_file.ignore(); | ||
| 481 | // read values into temp variables, then create a new HeavyIon object | ||
| 482 | int nh =0, np =0, nt =0, nc =0, | ||
| 483 | neut = 0, prot = 0, nw =0, nwn =0, nwnw =0; | ||
| 484 | float impact = 0., plane = 0., xcen = 0., inel = 0.; | ||
| 485 | m_file >> nh >> np >> nt >> nc >> neut >> prot | ||
| 486 | >> nw >> nwn >> nwnw >> impact >> plane >> xcen >> inel; | ||
| 487 | m_file.ignore(2,'\n'); | ||
| 488 | HeavyIon* ion = new HeavyIon(nh, np, nt, nc, neut, prot, | ||
| 489 | nw, nwn, nwnw, | ||
| 490 | impact, plane, xcen, inel ); | ||
| 491 | // | ||
| 492 | return ion; | ||
| 493 | } | ||
| 494 | |||
| 495 | PdfInfo* IO_ExtendedAscii::read_pdf_info() | ||
| 496 | { | ||
| 497 | // assumes mode has already been checked | ||
| 498 | // | ||
| 499 | // test to be sure the next entry is of type "F" then ignore it | ||
| 500 | if ( !m_file || m_file.peek()!='F' ) { | ||
| 501 | std::cerr << "IO_ExtendedAscii::read_pdf_info setting badbit." << std::endl; | ||
| 502 | m_file.clear(std::ios::badbit); | ||
| 503 | return 0; | ||
| 504 | } | ||
| 505 | m_file.ignore(); | ||
| 506 | // read values into temp variables, then create a new PdfInfo object | ||
| 507 | int id1 =0, id2 =0; | ||
| 508 | double x1 = 0., x2 = 0., scale = 0., pdf1 = 0., pdf2 = 0.; | ||
| 509 | m_file >> id1 >> id2 >> x1 >> x2 >> scale >> pdf1 >> pdf2; | ||
| 510 | m_file.ignore(2,'\n'); | ||
| 511 | PdfInfo* pdf = new PdfInfo( id1, id2, x1, x2, scale, pdf1, pdf2); | ||
| 512 | // | ||
| 513 | return pdf; | ||
| 514 | } | ||
| 515 | |||
| 516 | GenParticle* IO_ExtendedAscii::read_particle( | ||
| 517 | std::map<GenParticle*,int>& particle_to_end_vertex ){ | ||
| 518 | // assumes mode has already been checked | ||
| 519 | // | ||
| 520 | // test to be sure the next entry is of type "P" then ignore it | ||
| 521 | if ( !m_file || m_file.peek()!='P' ) { | ||
| 522 | std::cerr << "IO_ExtendedAscii::read_particle setting badbit." | ||
| 523 | << std::endl; | ||
| 524 | m_file.clear(std::ios::badbit); | ||
| 525 | return 0; | ||
| 526 | } | ||
| 527 | m_file.ignore(); | ||
| 528 | // | ||
| 529 | // declare variables to be read in to, and read everything except flow | ||
| 48 | garren | 530 | double px = 0., py = 0., pz = 0., e = 0., m = 0., theta = 0., phi = 0.; |
| 40 | garren | 531 | int bar_code = 0, id = 0, status = 0, end_vtx_code = 0, flow_size = 0; |
| 48 | garren | 532 | m_file >> bar_code >> id >> px >> py >> pz >> e >> m >> status |
| 40 | garren | 533 | >> theta >> phi >> end_vtx_code >> flow_size; |
| 534 | // | ||
| 535 | // read flow patterns if any exist | ||
| 536 | Flow flow; | ||
| 537 | int code_index, code; | ||
| 538 | for ( int i = 1; i <= flow_size; ++i ) { | ||
| 539 | m_file >> code_index >> code; | ||
| 540 | flow.set_icode( code_index,code); | ||
| 541 | } | ||
| 542 | m_file.ignore(2,'\n'); // '\n' at end of entry | ||
| 43 | garren | 543 | GenParticle* p = new GenParticle( FourVector(px,py,pz,e), |
| 40 | garren | 544 | id, status, flow, |
| 545 | Polarization(theta,phi) ); | ||
| 48 | garren | 546 | p->set_generated_mass( m ); |
| 40 | garren | 547 | p->suggest_barcode( bar_code ); |
| 548 | // | ||
| 549 | // all particles are connected to their end vertex separately | ||
| 550 | // after all particles and vertices have been created - so we keep | ||
| 551 | // a map of all particles that have end vertices | ||
| 552 | if ( end_vtx_code != 0 ) particle_to_end_vertex[p] = end_vtx_code; | ||
| 553 | return p; | ||
| 554 | } | ||
| 555 | |||
| 556 | ParticleData* IO_ExtendedAscii::read_particle_data( ParticleDataTable* pdt ) { | ||
| 557 | // assumes mode has already been checked | ||
| 558 | // | ||
| 559 | // test to be sure the next entry is of type "D" then ignore it | ||
| 560 | if ( !m_file || m_file.peek()!='D' ) return 0; | ||
| 561 | m_file.ignore(); | ||
| 562 | // | ||
| 563 | // read values into temp variables then create new ParticleData object | ||
| 564 | char its_name[22]; | ||
| 565 | int its_id = 0, its_spin = 0; | ||
| 566 | double its_charge = 0, its_mass = 0, its_clifetime = 0; | ||
| 567 | m_file >> its_id >> its_charge >> its_mass | ||
| 568 | >> its_clifetime >> its_spin; | ||
| 569 | m_file.ignore(1); // eat the " " | ||
| 570 | m_file.getline( its_name, 22, '\n' ); | ||
| 571 | ParticleData* pdata = new ParticleData( its_name, its_id, its_charge, | ||
| 572 | its_mass, its_clifetime, | ||
| 573 | double(its_spin)/2.); | ||
| 574 | pdt->insert(pdata); | ||
| 575 | return pdata; | ||
| 576 | } | ||
| 577 | |||
| 578 | bool IO_ExtendedAscii::write_end_listing() { | ||
| 579 | if ( m_finished_first_event_io && m_mode&std::ios::out ) { | ||
| 580 | m_file << "HepMC::IO_ExtendedAscii-END_EVENT_LISTING\n" << std::flush; | ||
| 581 | m_finished_first_event_io = 0; | ||
| 582 | return 1; | ||
| 583 | } | ||
| 584 | return 0; | ||
| 585 | } | ||
| 586 | |||
| 587 | bool IO_ExtendedAscii::search_for_key_end( std::istream& in, const char* key ) { | ||
| 588 | // reads characters from in until the string of characters matching | ||
| 589 | // key is found (success) or EOF is reached (failure). | ||
| 590 | // It stops immediately thereafter. Returns T/F for success/fail | ||
| 591 | // | ||
| 592 | char c[1]; | ||
| 593 | unsigned int index = 0; | ||
| 594 | while ( in.get(c[0]) ) { | ||
| 595 | if ( c[0] == key[index] ) { | ||
| 596 | ++index; | ||
| 597 | } else { index = 0; } | ||
| 598 | if ( index == strlen(key) ) return 1; | ||
| 599 | } | ||
| 600 | return 0; | ||
| 601 | } | ||
| 602 | |||
| 603 | bool IO_ExtendedAscii::search_for_key_beginning( std::istream& in, | ||
| 604 | const char* key ) { | ||
| 605 | // not tested and NOT used anywhere! | ||
| 606 | if ( search_for_key_end( in, key) ) { | ||
| 607 | int i = strlen(key); | ||
| 608 | while ( i>=0 ) in.putback(key[i--]); | ||
| 609 | return 1; | ||
| 610 | } else { | ||
| 611 | in.putback(EOF); | ||
| 612 | in.clear(); | ||
| 613 | return 0; | ||
| 614 | } | ||
| 615 | } | ||
| 616 | |||
| 617 | bool IO_ExtendedAscii::eat_key( std::iostream& in, const char* key ) { | ||
| 618 | // eats the character string key from istream in - only if the key | ||
| 619 | // is the very next occurence in the stream | ||
| 620 | // if the key is not the next occurence, it eats nothing ... i.e. | ||
| 621 | // it puts back whatever it would have eaten. | ||
| 622 | int key_length = strlen(key); | ||
| 623 | // below is the only way I know of to get a variable length string | ||
| 624 | // conforming to ansi standard. | ||
| 625 | char* c = new char[key_length +1]; | ||
| 626 | int i=0; | ||
| 627 | // read the stream until get fails (because of EOF), a character | ||
| 628 | // doesn't match a character in the string, or all characters in | ||
| 629 | // the string have been checked and match. | ||
| 630 | while ( in.get(c[i]) && c[i]==key[i] && i<key_length ) { | ||
| 631 | ++i; | ||
| 632 | } | ||
| 633 | if ( i == key_length ) { | ||
| 634 | delete c; | ||
| 635 | return 1; | ||
| 636 | } | ||
| 637 | // | ||
| 638 | // if we get here, then we have eaten the wrong this and we must put it | ||
| 639 | // back | ||
| 640 | while ( i>=0 ) in.putback(c[i--]); | ||
| 641 | delete c; | ||
| 642 | return 0; | ||
| 643 | } | ||
| 644 | |||
| 645 | int IO_ExtendedAscii::find_in_map( const std::map<GenVertex*,int>& m, | ||
| 646 | GenVertex* v ) const { | ||
| 647 | std::map<GenVertex*,int>::const_iterator iter = m.find(v); | ||
| 648 | if ( iter == m.end() ) return 0; | ||
| 649 | return iter->second; | ||
| 650 | } | ||
| 651 | |||
| 652 | } // HepMC |
