![]() |
HepMC Reference DocumentationHepMC |
00001 //-------------------------------------------------------------------------- 00002 00004 // Matt.Dobbs@Cern.CH, January 2000 00005 // event input/output in ascii format for machine reading 00007 00008 #include "HepMC/IO_Ascii.h" 00009 #include "HepMC/GenEvent.h" 00010 #include "HepMC/ParticleDataTable.h" 00011 #include "HepMC/CommonIO.h" 00012 #include "HepMC/Version.h" 00013 00014 namespace HepMC { 00015 00016 IO_Ascii::IO_Ascii( const char* filename, std::ios::openmode mode ) 00017 : m_mode(mode), m_file(filename, mode), m_finished_first_event_io(0), 00018 m_common_io() 00019 { 00020 std::cout << "-------------------------------------------------------" << std::endl; 00021 std::cout << "Use of HepMC/IO_Ascii is deprecated" << std::endl; 00022 std::cout << "-------------------------------------------------------" << std::endl; 00023 if ( (m_mode&std::ios::out && m_mode&std::ios::in) || 00024 (m_mode&std::ios::app && m_mode&std::ios::in) ) { 00025 std::cerr << "IO_Ascii::IO_Ascii Error, open of file requested " 00026 << "of input AND output type. Not allowed. Closing file." 00027 << std::endl; 00028 m_file.close(); 00029 return; 00030 } 00031 // precision 16 (# digits following decimal point) is the minimum that 00032 // will capture the full information stored in a double 00033 m_file.precision(16); 00034 // we use decimal to store integers, because it is smaller than hex! 00035 m_file.setf(std::ios::dec,std::ios::basefield); 00036 m_file.setf(std::ios::scientific,std::ios::floatfield); 00037 } 00038 00039 IO_Ascii::~IO_Ascii() { 00040 write_end_listing(); 00041 m_file.close(); 00042 } 00043 00044 void IO_Ascii::print( std::ostream& ostr ) const { 00045 ostr << "IO_Ascii: unformated ascii file IO for machine reading.\n" 00046 << "\tFile openmode: " << m_mode 00047 << " file state: " << m_file.rdstate() 00048 << " bad:" << (m_file.rdstate()&std::ios::badbit) 00049 << " eof:" << (m_file.rdstate()&std::ios::eofbit) 00050 << " fail:" << (m_file.rdstate()&std::ios::failbit) 00051 << " good:" << (m_file.rdstate()&std::ios::goodbit) << std::endl; 00052 } 00053 00054 void IO_Ascii::write_event( const GenEvent* evt ) { 00056 // 00057 // check the state of m_file is good, and that it is in output mode 00058 if ( !evt || !m_file ) return; 00059 if ( !m_mode&std::ios::out ) { 00060 std::cerr << "HepMC::IO_Ascii::write_event " 00061 << " attempt to write to input file." << std::endl; 00062 return; 00063 } 00064 // 00065 // write event listing key before first event only. 00066 if ( !m_finished_first_event_io ) { 00067 m_finished_first_event_io = 1; 00068 m_file << "\n" << "HepMC::Version " << versionName(); 00069 m_file << "\n" << "HepMC::IO_Ascii-START_EVENT_LISTING\n"; 00070 } 00071 // 00072 // output the event data including the number of primary vertices 00073 // and the total number of vertices 00074 std::vector<long int> random_states = evt->random_states(); 00075 m_file << 'E'; 00076 output( evt->event_number() ); 00077 output( evt->event_scale() ); 00078 output( evt->alphaQCD() ); 00079 output( evt->alphaQED() ); 00080 output( evt->signal_process_id() ); 00081 output( ( evt->signal_process_vertex() ? 00082 evt->signal_process_vertex()->barcode() : 0 ) ); 00083 output( evt->vertices_size() ); // total number of vertices. 00084 output( (int)random_states.size() ); 00085 for ( std::vector<long int>::iterator rs = random_states.begin(); 00086 rs != random_states.end(); ++rs ) { 00087 output( *rs ); 00088 } 00089 output( (int)evt->weights().size() ); 00090 for ( WeightContainer::const_iterator w = evt->weights().begin(); 00091 w != evt->weights().end(); ++w ) { 00092 output( *w ); 00093 } 00094 output('\n'); 00095 // 00096 // Output all of the vertices - note there is no real order. 00097 for ( GenEvent::vertex_const_iterator v = evt->vertices_begin(); 00098 v != evt->vertices_end(); ++v ) { 00099 write_vertex( *v ); 00100 } 00101 } 00102 00103 bool IO_Ascii::fill_next_event( GenEvent* evt ){ 00104 // 00105 // 00106 // test that evt pointer is not null 00107 if ( !evt ) { 00108 std::cerr 00109 << "IO_Ascii::fill_next_event error - passed null event." 00110 << std::endl; 00111 return false; 00112 } 00113 // check the state of m_file is good, and that it is in input mode 00114 if ( !m_file ) return false; 00115 if ( !(m_mode&std::ios::in) ) { 00116 std::cerr << "HepMC::IO_Ascii::fill_next_event " 00117 << " attempt to read from output file." << std::endl; 00118 return false; 00119 } 00120 // 00121 // search for event listing key before first event only. 00122 // 00123 // skip through the file just after first occurence of the start_key 00124 int iotype; 00125 if ( !m_finished_first_event_io ) { 00126 m_file.seekg( 0 ); // go to position zero in the file. 00127 iotype = m_common_io.find_file_type(m_file); 00128 if( iotype != ascii ) { 00129 std::cerr << "IO_Ascii::fill_next_event start key not found " 00130 << "setting badbit." << std::endl; 00131 m_file.clear(std::ios::badbit); 00132 return false; 00133 } 00134 m_finished_first_event_io = 1; 00135 } 00136 // 00137 // test to be sure the next entry is of type "E" then ignore it 00138 if ( !m_file ) { 00139 std::cerr << "IO_Ascii::fill_next_event end of stream found " 00140 << "setting badbit." << std::endl; 00141 m_file.clear(std::ios::badbit); 00142 return false; 00143 } 00144 if ( !m_file || m_file.peek()!='E' ) { 00145 // if the E is not the next entry, then check to see if it is 00146 // the end event listing key - if yes, search for another start key 00147 if ( m_common_io.find_end_key(m_file) ) { 00148 iotype = m_common_io.find_file_type(m_file); 00149 if( iotype != ascii ) { 00150 // this is the only case where we set an EOF state 00151 m_file.clear(std::ios::eofbit); 00152 return false; 00153 } 00154 } else { 00155 std::cerr << "IO_Ascii::fill_next_event end key not found " 00156 << "setting badbit." << std::endl; 00157 m_file.clear(std::ios::badbit); 00158 return false; 00159 } 00160 } 00161 m_file.ignore(); 00162 // call the read method 00163 return m_common_io.read_io_ascii(&m_file, evt); 00164 } 00165 00166 void IO_Ascii::write_comment( const std::string comment ) { 00167 // check the state of m_file is good, and that it is in output mode 00168 if ( !m_file ) return; 00169 if ( !m_mode&std::ios::out ) { 00170 std::cerr << "HepMC::IO_Ascii::write_particle_data_table " 00171 << " attempt to write to input file." << std::endl; 00172 return; 00173 } 00174 // write end of event listing key if events have already been written 00175 write_end_listing(); 00176 // insert the comment key before the comment 00177 m_file << "\n" << "HepMC::IO_Ascii-COMMENT\n"; 00178 m_file << comment << std::endl; 00179 } 00180 00181 void IO_Ascii::write_particle_data_table( const ParticleDataTable* pdt) { 00182 // 00183 // check the state of m_file is good, and that it is in output mode 00184 if ( !m_file ) return; 00185 if ( !m_mode&std::ios::out ) { 00186 std::cerr << "HepMC::IO_Ascii::write_particle_data_table " 00187 << " attempt to write to input file." << std::endl; 00188 return; 00189 } 00190 // write end of event listing key if events have already been written 00191 write_end_listing(); 00192 // 00193 m_file << "\n" << "HepMC::IO_Ascii-START_PARTICLE_DATA\n"; 00194 for ( ParticleDataTable::const_iterator pd = pdt->begin(); 00195 pd != pdt->end(); pd++ ) { 00196 write_particle_data( pd->second ); 00197 } 00198 m_file << "HepMC::IO_Ascii-END_PARTICLE_DATA\n" << std::flush; 00199 } 00200 00201 bool IO_Ascii::fill_particle_data_table( ParticleDataTable* pdt ) { 00202 // 00203 // test that pdt pointer is not null 00204 if ( !pdt ) { 00205 std::cerr 00206 << "IO_Ascii::fill_particle_data_table - passed null table." 00207 << std::endl; 00208 return false; 00209 } 00210 // 00211 // check the state of m_file is good, and that it is in input mode 00212 if ( !m_file ) return false; 00213 if ( !m_mode&std::ios::in ) { 00214 std::cerr << "HepMC::IO_Ascii::fill_particle_data_table " 00215 << " attempt to read from output file." << std::endl; 00216 return false; 00217 } 00218 // position to beginning of file 00219 int initial_file_position = m_file.tellg(); 00220 std::ios::iostate initial_state = m_file.rdstate(); 00221 m_file.seekg( 0 ); 00222 // skip through the file just after first occurence of the start_key 00223 int iotype; 00224 iotype = m_common_io.find_file_type(m_file); 00225 if( iotype != ascii_pdt ) { 00226 m_file.seekg( initial_file_position ); 00227 std::cerr << "IO_Ascii::fill_particle_data_table start key not " 00228 << "found setting badbit." << std::endl; 00229 m_file.clear(std::ios::badbit); 00230 return false; 00231 } 00232 // 00233 pdt->set_description("Read with IO_Ascii"); 00234 m_common_io.read_io_particle_data_table( &m_file, pdt ); 00235 // 00236 // check for the end event listing key 00237 iotype = m_common_io.find_end_key(m_file); 00238 if( iotype != ascii_pdt ) { 00239 std::cerr << "IO_Ascii::fill_particle_data_table end key not " 00240 << "found setting badbit." << std::endl; 00241 m_file.clear(std::ios::badbit); 00242 } 00243 // put the file back into its original state and position 00244 m_file.clear( initial_state ); 00245 m_file.seekg( initial_file_position ); 00246 return true; 00247 } 00248 00249 void IO_Ascii::write_vertex( GenVertex* v ) { 00250 // assumes mode has already been checked 00251 if ( !v || !m_file ) { 00252 std::cerr << "IO_Ascii::write_vertex !v||!m_file, " 00253 << "v="<< v << " setting badbit" << std::endl; 00254 m_file.clear(std::ios::badbit); 00255 return; 00256 } 00257 // First collect info we need 00258 // count the number of orphan particles going into v 00259 int num_orphans_in = 0; 00260 for ( GenVertex::particles_in_const_iterator p1 00261 = v->particles_in_const_begin(); 00262 p1 != v->particles_in_const_end(); ++p1 ) { 00263 if ( !(*p1)->production_vertex() ) ++num_orphans_in; 00264 } 00265 // 00266 m_file << 'V'; 00267 output( v->barcode() ); // v's unique identifier 00268 output( v->id() ); 00269 output( v->position().x() ); 00270 output( v->position().y() ); 00271 output( v->position().z() ); 00272 output( v->position().t() ); 00273 output( num_orphans_in ); 00274 output( (int)v->particles_out_size() ); 00275 output( (int)v->weights().size() ); 00276 for ( WeightContainer::iterator w = v->weights().begin(); 00277 w != v->weights().end(); ++w ) { 00278 output( *w ); 00279 } 00280 output('\n'); 00281 for ( GenVertex::particles_in_const_iterator p2 00282 = v->particles_in_const_begin(); 00283 p2 != v->particles_in_const_end(); ++p2 ) { 00284 if ( !(*p2)->production_vertex() ) { 00285 write_particle( *p2 ); 00286 } 00287 } 00288 for ( GenVertex::particles_out_const_iterator p3 00289 = v->particles_out_const_begin(); 00290 p3 != v->particles_out_const_end(); ++p3 ) { 00291 write_particle( *p3 ); 00292 } 00293 } 00294 00295 void IO_Ascii::write_particle( GenParticle* p ) { 00296 // assumes mode has already been checked 00297 if ( !p || !m_file ) { 00298 std::cerr << "IO_Ascii::write_vertex !p||!m_file, " 00299 << "v="<< p << " setting badbit" << std::endl; 00300 m_file.clear(std::ios::badbit); 00301 return; 00302 } 00303 m_file << 'P'; 00304 output( p->barcode() ); 00305 output( p->pdg_id() ); 00306 output( p->momentum().px() ); 00307 output( p->momentum().py() ); 00308 output( p->momentum().pz() ); 00309 output( p->momentum().e() ); 00310 output( p->status() ); 00311 output( p->polarization().theta() ); 00312 output( p->polarization().phi() ); 00313 // since end_vertex is oftentimes null, this CREATES a null vertex 00314 // in the map 00315 output( ( p->end_vertex() ? p->end_vertex()->barcode() : 0 ) ); 00316 m_file << ' ' << p->flow() << "\n"; 00317 } 00318 00319 void IO_Ascii::write_particle_data( const ParticleData* pdata ) { 00320 // assumes mode has already been checked 00321 if ( !pdata || !m_file ) { 00322 std::cerr << "IO_Ascii::write_vertex !pdata||!m_file, " 00323 << "pdata="<< pdata << " setting badbit" << std::endl; 00324 m_file.clear(std::ios::badbit); 00325 return; 00326 } 00327 m_file << 'D'; 00328 output( pdata->pdg_id() ); 00329 output( pdata->charge() ); 00330 output( pdata->mass() ); 00331 output( pdata->clifetime() ); 00332 output( (int)(pdata->spin()*2.+.1) ); 00333 // writes the first 21 characters starting with 0 00334 m_file << " " << pdata->name().substr(0,21) << "\n"; 00335 } 00336 00337 bool IO_Ascii::write_end_listing() { 00338 if ( m_finished_first_event_io && m_mode&std::ios::out ) { 00339 m_common_io.write_IO_Ascii_End(m_file); 00340 m_file << std::flush; 00341 m_finished_first_event_io = 0; 00342 return true; 00343 } 00344 return false; 00345 } 00346 00347 } // HepMC 00348