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