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