HepMC Reference Documentation

HepMC

IO_GenEvent.cc

Go to the documentation of this file.
00001 //--------------------------------------------------------------------------
00002 
00004 // garren@fnal.gov, July 2006
00005 // event input/output in ascii format for machine reading
00006 // extended format contains HeavyIon and PdfInfo classes
00008 
00009 #include "HepMC/IO_GenEvent.h"
00010 #include "HepMC/GenEvent.h"
00011 #include "HepMC/ParticleDataTable.h"
00012 #include "HepMC/HeavyIon.h"
00013 #include "HepMC/PdfInfo.h"
00014 #include "HepMC/CommonIO.h"
00015 #include "HepMC/Version.h"
00016 
00017 namespace HepMC {
00018 
00019     IO_GenEvent::IO_GenEvent( const char* filename, std::ios::openmode mode ) 
00020     : m_mode(mode), 
00021       m_file(filename, mode), 
00022       m_ostr(0),
00023       m_istr(0),
00024       m_iostr(0),
00025       m_finished_first_event_io(false),
00026       m_have_file(false),
00027       m_common_io()
00028     {
00029         if ( (m_mode&std::ios::out && m_mode&std::ios::in) ||
00030              (m_mode&std::ios::app && m_mode&std::ios::in) ) {
00031             std::cerr << "IO_GenEvent::IO_GenEvent Error, open of file requested "
00032                       << "of input AND output type. Not allowed. Closing file."
00033                       << std::endl;
00034             m_file.close();
00035             return;
00036         }
00037         // precision 16 (# digits following decimal point) is the minimum that
00038         //  will capture the full information stored in a double
00039         m_file.precision(16);
00040         // we use decimal to store integers, because it is smaller than hex!
00041         m_file.setf(std::ios::dec,std::ios::basefield);
00042         m_file.setf(std::ios::scientific,std::ios::floatfield);
00043         // now we set the streams
00044         m_iostr = &m_file;
00045         if ( m_mode&std::ios::in ) {
00046             m_istr = &m_file;
00047             m_ostr = NULL;
00048         }
00049         if ( m_mode&std::ios::out ) {
00050             m_ostr = &m_file;
00051             m_istr = NULL;
00052         }
00053         m_have_file = true;
00054     }
00055 
00056     IO_GenEvent::IO_GenEvent( std::istream & istr ) 
00057     : m_ostr(0),
00058       m_istr(&istr),
00059       m_iostr(&istr),
00060       m_finished_first_event_io(false),
00061       m_have_file(false),
00062       m_common_io()
00063     { }
00064 
00065     IO_GenEvent::IO_GenEvent( std::ostream & ostr )
00066     : m_ostr(&ostr),
00067       m_istr(0),
00068       m_iostr(&ostr),
00069       m_finished_first_event_io(false),
00070       m_have_file(false),
00071       m_common_io()
00072     {
00073         // precision 16 (# digits following decimal point) is the minimum that
00074         //  will capture the full information stored in a double
00075         m_ostr->precision(16);
00076         // we use decimal to store integers, because it is smaller than hex!
00077         m_ostr->setf(std::ios::dec,std::ios::basefield);
00078         m_ostr->setf(std::ios::scientific,std::ios::floatfield);
00079     }
00080 
00081     IO_GenEvent::~IO_GenEvent() {
00082         write_end_listing();
00083         if(m_have_file) m_file.close();
00084     }
00085 
00086     void IO_GenEvent::print( std::ostream& ostr ) const { 
00087         ostr << "IO_GenEvent: unformated ascii file IO for machine reading.\n"; 
00088         if(m_have_file)    ostr  << "\tFile openmode: " << m_mode ;
00089         ostr << " stream state: " << m_ostr->rdstate()
00090              << " bad:" << (m_ostr->rdstate()&std::ios::badbit)
00091              << " eof:" << (m_ostr->rdstate()&std::ios::eofbit)
00092              << " fail:" << (m_ostr->rdstate()&std::ios::failbit)
00093              << " good:" << (m_ostr->rdstate()&std::ios::goodbit) << std::endl;
00094     }
00095 
00096     void IO_GenEvent::write_event( const GenEvent* evt ) {
00098         //
00099         // make sure the state is good, and that it is in output mode
00100         if ( !evt  ) return;
00101         if ( m_ostr == NULL ) {
00102             std::cerr << "HepMC::IO_GenEvent::write_event "
00103                       << " attempt to write to input file." << std::endl;
00104             return;
00105         }
00106         //
00107         // write event listing key before first event only.
00108         if ( !m_finished_first_event_io ) {
00109             m_finished_first_event_io = 1;
00110             *m_ostr << "\n" << "HepMC::Version " << versionName();
00111             *m_ostr << "\n";
00112             m_common_io.write_IO_GenEvent_Key(*m_ostr);
00113         }
00114         //
00115         // output the event data including the number of primary vertices
00116         //  and the total number of vertices
00117         std::vector<long> random_states = evt->random_states();
00118         *m_ostr << 'E';
00119         output( evt->event_number() );
00120         output( evt->mpi() );
00121         output( evt->event_scale() );
00122         output( evt->alphaQCD() );
00123         output( evt->alphaQED() );
00124         output( evt->signal_process_id() );
00125         output(   ( evt->signal_process_vertex() ?
00126                     evt->signal_process_vertex()->barcode() : 0 )   );
00127         output( evt->vertices_size() ); // total number of vertices.
00128         write_beam_particles( evt->beam_particles() );
00129         output( (int)random_states.size() );
00130         for ( std::vector<long>::iterator rs = random_states.begin(); 
00131               rs != random_states.end(); ++rs ) {
00132             output( *rs );
00133         }
00134         output( (int)evt->weights().size() );
00135         for ( WeightContainer::const_iterator w = evt->weights().begin(); 
00136               w != evt->weights().end(); ++w ) {
00137             output( *w );
00138         }
00139         output('\n');
00140         write_heavy_ion( evt->heavy_ion() );
00141         write_pdf_info( evt->pdf_info() );
00142         //
00143         // Output all of the vertices - note there is no real order.
00144         for ( GenEvent::vertex_const_iterator v = evt->vertices_begin();
00145               v != evt->vertices_end(); ++v ) {
00146             write_vertex( *v );
00147         }
00148     }
00149 
00150     bool IO_GenEvent::fill_next_event( GenEvent* evt ){
00151         //
00152         //
00153         // test that evt pointer is not null
00154         if ( !evt ) {
00155             std::cerr 
00156                 << "IO_GenEvent::fill_next_event error - passed null event." 
00157                 << std::endl;
00158             return false;
00159         }
00160         // make sure the stream is good, and that it is in input mode
00161         if ( !(*m_istr) ) return false;
00162         if ( !m_istr ) {
00163             std::cerr << "HepMC::IO_GenEvent::fill_next_event "
00164                       << " attempt to read from output file." << std::endl;
00165             return false;
00166         }
00167         //
00168         // search for event listing key before first event only.
00169         //
00170         // skip through the file just after first occurence of the start_key
00171         int iotype = 0;
00172         if ( !m_finished_first_event_io ) {
00173             iotype = m_common_io.find_file_type(*m_istr);
00174             if( iotype <= 0 ) {
00175                 std::cerr << "IO_GenEvent::fill_next_event start key not found "
00176                           << "setting badbit." << std::endl;
00177                 m_istr->clear(std::ios::badbit); 
00178                 return false;
00179             }
00180             m_finished_first_event_io = 1;
00181         }
00182         //
00183         // test to be sure the next entry is of type "E" then ignore it
00184         if ( !(*m_istr) ) { 
00185                 std::cerr << "IO_GenEvent::fill_next_event end of stream found "
00186                           << "setting badbit." << std::endl;
00187                 m_istr->clear(std::ios::badbit); 
00188                 return false;
00189         }
00190         if ( !(*m_istr) || m_istr->peek()!='E' ) { 
00191             // if the E is not the next entry, then check to see if it is
00192             // the end event listing key - if yes, search for another start key
00193             int ioendtype = m_common_io.find_end_key(*m_istr);
00194             if ( ioendtype == iotype ) {
00195                 iotype = m_common_io.find_file_type(*m_istr);
00196                 if( iotype <= 0 ) {
00197                     // this is the only case where we set an EOF state
00198                     m_istr->clear(std::ios::eofbit);
00199                     return false;
00200                 }
00201             } else if ( ioendtype > 0 ) {
00202                 std::cerr << "IO_GenEvent::fill_next_event end key does not match start key "
00203                           << "setting badbit." << std::endl;
00204                 m_istr->clear(std::ios::badbit); 
00205                 return false;
00206             } else {
00207                 std::cerr << "IO_GenEvent::fill_next_event end key not found "
00208                           << "setting badbit." << std::endl;
00209                 m_istr->clear(std::ios::badbit); 
00210                 return false;
00211             }
00212         }
00213         m_istr->ignore();
00214         // call the appropriate read method
00215         if( m_common_io.io_type() == gen ) {
00216             return m_common_io.read_io_genevent(m_istr, evt);
00217         } else if( m_common_io.io_type() == ascii ) { 
00218             return m_common_io.read_io_ascii(m_istr, evt);
00219         } else if( m_common_io.io_type() == extascii ) { 
00220             return m_common_io.read_io_extendedascii(m_istr, evt);
00221         } else if( m_common_io.io_type() == ascii_pdt ) { 
00222         } else if( m_common_io.io_type() == extascii_pdt ) { 
00223         }
00224         // should not get to this statement
00225         return false;
00226     }
00227 
00228     void IO_GenEvent::write_comment( const std::string comment ) {
00229         // make sure the stream is good, and that it is in output mode
00230         if ( !(*m_ostr) ) return;
00231         if ( m_ostr == NULL ) {
00232             std::cerr << "HepMC::IO_GenEvent::write_comment "
00233                       << " attempt to write to input file." << std::endl;
00234             return;
00235         }
00236         // write end of event listing key if events have already been written
00237         write_end_listing();
00238         // insert the comment key before the comment
00239         *m_ostr << "\n" << "HepMC::IO_GenEvent-COMMENT\n";
00240         *m_ostr << comment << std::endl;
00241     }
00242 
00243     void IO_GenEvent::write_vertex( GenVertex* v ) {
00244         // assumes mode has already been checked
00245         if ( !v || !(*m_ostr) ) {
00246             std::cerr << "IO_GenEvent::write_vertex !v||!(*m_ostr), "
00247                       << "v="<< v << " setting badbit" << std::endl;
00248             m_ostr->clear(std::ios::badbit); 
00249             return;
00250         }
00251         // First collect info we need
00252         // count the number of orphan particles going into v
00253         int num_orphans_in = 0;
00254         for ( GenVertex::particles_in_const_iterator p1
00255                   = v->particles_in_const_begin();
00256               p1 != v->particles_in_const_end(); ++p1 ) {
00257             if ( !(*p1)->production_vertex() ) ++num_orphans_in;
00258         }
00259         //
00260         *m_ostr << 'V';
00261         output( v->barcode() ); // v's unique identifier
00262         output( v->id() );
00263         output( v->position().x() );
00264         output( v->position().y() );
00265         output( v->position().z() );
00266         output( v->position().t() );
00267         output( num_orphans_in );
00268         output( (int)v->particles_out_size() );
00269         output( (int)v->weights().size() );
00270         for ( WeightContainer::iterator w = v->weights().begin(); 
00271               w != v->weights().end(); ++w ) {
00272             output( *w );
00273         }
00274         output('\n');
00275         for ( GenVertex::particles_in_const_iterator p2 
00276                   = v->particles_in_const_begin();
00277               p2 != v->particles_in_const_end(); ++p2 ) {
00278             if ( !(*p2)->production_vertex() ) {
00279                 write_particle( *p2 );
00280             }
00281         }
00282         for ( GenVertex::particles_out_const_iterator p3 
00283                   = v->particles_out_const_begin();
00284               p3 != v->particles_out_const_end(); ++p3 ) {
00285             write_particle( *p3 );
00286         }
00287     }
00288 
00289     void IO_GenEvent::write_beam_particles( 
00290         std::pair<HepMC::GenParticle *,HepMC::GenParticle *> pr ) {
00291         GenParticle* p = pr.first;
00292         //m_file << 'B';
00293         if(!p) {
00294            output( 0 );
00295         } else {
00296            output( p->barcode() );
00297         }
00298         p = pr.second;
00299         if(!p) {
00300            output( 0 );
00301         } else {
00302            output( p->barcode() );
00303         }
00304     }
00305 
00306     void IO_GenEvent::write_heavy_ion( HeavyIon* ion ) {
00307         // assumes mode has already been checked
00308         if ( !(*m_ostr) ) {
00309             std::cerr << "IO_GenEvent::write_heavy_ion !(*m_ostr), "
00310                       << " setting badbit" << std::endl;
00311             m_ostr->clear(std::ios::badbit); 
00312             return;
00313         }
00314         *m_ostr << 'H';
00315         // HeavyIon* is set to 0 by default
00316         if ( !ion  ) {
00317             output( 0 );
00318             output( 0 );
00319             output( 0 );
00320             output( 0 );
00321             output( 0 );
00322             output( 0 );
00323             output( 0 );
00324             output( 0 );
00325             output( 0 );
00326             output( 0. );
00327             output( 0. );
00328             output( 0. );
00329             output( 0. );
00330             output('\n');
00331             return;
00332         }
00333         //
00334         output( ion->Ncoll_hard() );
00335         output( ion->Npart_proj() );
00336         output( ion->Npart_targ() );
00337         output( ion->Ncoll() );
00338         output( ion->spectator_neutrons() );
00339         output( ion->spectator_protons() );
00340         output( ion->N_Nwounded_collisions() );
00341         output( ion->Nwounded_N_collisions() );
00342         output( ion->Nwounded_Nwounded_collisions() );
00343         output( ion->impact_parameter() );
00344         output( ion->event_plane_angle() );
00345         output( ion->eccentricity() );
00346         output( ion->sigma_inel_NN() );
00347         output('\n');
00348     }
00349 
00350     void IO_GenEvent::write_pdf_info( PdfInfo* pdf ) {
00351         // assumes mode has already been checked
00352         if ( !(*m_ostr) ) {
00353             std::cerr << "IO_GenEvent::write_pdf_info !(*m_ostr), "
00354                       << " setting badbit" << std::endl;
00355             m_ostr->clear(std::ios::badbit); 
00356             return;
00357         }
00358         *m_ostr << 'F';
00359         // PdfInfo* is set to 0 by default
00360         if ( !pdf ) {
00361             output( 0 );
00362             output( 0 );
00363             output( 0. );
00364             output( 0. );
00365             output( 0. );
00366             output( 0. );
00367             output( 0. );
00368             output('\n');
00369             return;
00370         }
00371         //
00372         output( pdf->id1() );
00373         output( pdf->id2() );
00374         output( pdf->x1() );
00375         output( pdf->x2() );
00376         output( pdf->scalePDF() );
00377         output( pdf->pdf1() );
00378         output( pdf->pdf2() );
00379         output('\n');
00380     }
00381 
00382     void IO_GenEvent::write_particle( GenParticle* p ) {
00383         // assumes mode has already been checked
00384         if ( !p || !(*m_ostr) ) {
00385             std::cerr << "IO_GenEvent::write_particle !p||!(*m_ostr), "
00386                       << "v="<< p << " setting badbit" << std::endl;
00387             m_ostr->clear(std::ios::badbit); 
00388             return;
00389         }
00390         *m_ostr << 'P';
00391         output( p->barcode() );
00392         output( p->pdg_id() );
00393         output( p->momentum().px() );
00394         output( p->momentum().py() );
00395         output( p->momentum().pz() );
00396         output( p->momentum().e() );
00397         output( p->generated_mass() );
00398         output( p->status() );
00399         output( p->polarization().theta() );
00400         output( p->polarization().phi() );
00401         // since end_vertex is oftentimes null, this CREATES a null vertex
00402         // in the map
00403         output(   ( p->end_vertex() ? p->end_vertex()->barcode() : 0 )  );
00404         *m_ostr << ' ' << p->flow() << "\n";
00405     }
00406 
00407     void IO_GenEvent::write_particle_data( const ParticleData* pdata ) {
00408         // assumes mode has already been checked
00409         if ( !pdata || !(*m_ostr) ) {
00410             std::cerr << "IO_GenEvent::write_particle_data !pdata||!(*m_ostr), "
00411                       << "pdata="<< pdata << " setting badbit" << std::endl;
00412             m_ostr->clear(std::ios::badbit); 
00413             return;
00414         }
00415         *m_ostr << 'D';
00416         output( pdata->pdg_id() );
00417         output( pdata->charge() );
00418         output( pdata->mass() );
00419         output( pdata->clifetime() );
00420         output( (int)(pdata->spin()*2.+.1) );
00421         // writes the first 21 characters starting with 0
00422         *m_ostr << " " << pdata->name().substr(0,21) << "\n";
00423     }
00424 
00425     HeavyIon* IO_GenEvent::read_heavy_ion()
00426     {
00427         // assumes mode has already been checked
00428         //
00429         // test to be sure the next entry is of type "H" then ignore it
00430         if ( !(*m_istr) || m_istr->peek()!='H' ) {
00431             std::cerr << "IO_GenEvent::read_heavy_ion setting badbit." << std::endl;
00432             m_istr->clear(std::ios::badbit); 
00433             return false;
00434         } 
00435         m_istr->ignore();
00436         // read values into temp variables, then create a new HeavyIon object
00437         int nh =0, np =0, nt =0, nc =0, 
00438             neut = 0, prot = 0, nw =0, nwn =0, nwnw =0;
00439         float impact = 0., plane = 0., xcen = 0., inel = 0.; 
00440         *m_istr >> nh >> np >> nt >> nc >> neut >> prot
00441                >> nw >> nwn >> nwnw >> impact >> plane >> xcen >> inel;
00442         m_istr->ignore(2,'\n');
00443         if( nh == 0 ) return false;
00444         HeavyIon* ion = new HeavyIon(nh, np, nt, nc, neut, prot,
00445                                      nw, nwn, nwnw, 
00446                                      impact, plane, xcen, inel );
00447         //
00448         return ion;
00449     }
00450 
00451     PdfInfo* IO_GenEvent::read_pdf_info()
00452     {
00453         // assumes mode has already been checked
00454         //
00455         // test to be sure the next entry is of type "F" then ignore it
00456         if ( !(*m_istr) || m_istr->peek() !='F') {
00457             std::cerr << "IO_GenEvent::read_pdf_info setting badbit." << std::endl;
00458             m_istr->clear(std::ios::badbit); 
00459             return false;
00460         } 
00461         m_istr->ignore();
00462         // read values into temp variables, then create a new PdfInfo object
00463         int id1 =0, id2 =0;
00464         double  x1 = 0., x2 = 0., scale = 0., pdf1 = 0., pdf2 = 0.; 
00465         *m_istr >> id1 >> id2 >> x1 >> x2 >> scale >> pdf1 >> pdf2;
00466         m_istr->ignore(2,'\n');
00467         if( id1 == 0 ) return false;
00468         PdfInfo* pdf = new PdfInfo( id1, id2, x1, x2, scale, pdf1, pdf2);
00469         //
00470         return pdf;
00471     }
00472 
00473     GenParticle* IO_GenEvent::read_particle(
00474         TempParticleMap& particle_to_end_vertex ){
00475         // assumes mode has already been checked
00476         //
00477         // test to be sure the next entry is of type "P" then ignore it
00478         if ( !(*m_istr) || m_istr->peek()!='P' ) { 
00479             std::cerr << "IO_GenEvent::read_particle setting badbit." 
00480                       << std::endl;
00481             m_istr->clear(std::ios::badbit); 
00482             return false;
00483         } 
00484         m_istr->ignore();
00485         //
00486         // declare variables to be read in to, and read everything except flow
00487         double px = 0., py = 0., pz = 0., e = 0., m = 0., theta = 0., phi = 0.;
00488         int bar_code = 0, id = 0, status = 0, end_vtx_code = 0, flow_size = 0;
00489         *m_istr >> bar_code >> id >> px >> py >> pz >> e >> m >> status 
00490                >> theta >> phi >> end_vtx_code >> flow_size;
00491         //
00492         // read flow patterns if any exist
00493         Flow flow;
00494         int code_index, code;
00495         for ( int i = 1; i <= flow_size; ++i ) {
00496             *m_istr >> code_index >> code;
00497             flow.set_icode( code_index,code);
00498         }
00499         m_istr->ignore(2,'\n'); // '\n' at end of entry
00500         GenParticle* p = new GenParticle( FourVector(px,py,pz,e), 
00501                                     id, status, flow, 
00502                                     Polarization(theta,phi) );
00503         p->set_generated_mass( m );
00504         p->suggest_barcode( bar_code );
00505         //
00506         // all particles are connected to their end vertex separately 
00507         // after all particles and vertices have been created - so we keep
00508         // a map of all particles that have end vertices
00509         if ( end_vtx_code != 0 ) {
00510             particle_to_end_vertex.addEndParticle(p,end_vtx_code);
00511         }
00512         return p;
00513     }
00514 
00515     ParticleData* IO_GenEvent::read_particle_data( ParticleDataTable* pdt ) {
00516         // assumes mode has already been checked
00517         //
00518         // test to be sure the next entry is of type "D" then ignore it
00519         if ( !(*m_istr) || m_istr->peek()!='D' ) return false;
00520         m_istr->ignore();
00521         //
00522         // read values into temp variables then create new ParticleData object
00523         char its_name[22];
00524         int its_id = 0, its_spin = 0;  
00525         double its_charge = 0, its_mass = 0, its_clifetime = 0;
00526         *m_istr >> its_id >> its_charge >> its_mass 
00527                >> its_clifetime >> its_spin;
00528         m_istr->ignore(1); // eat the " "
00529         m_istr->getline( its_name, 22, '\n' );
00530         ParticleData* pdata = new ParticleData( its_name, its_id, its_charge, 
00531                                                 its_mass, its_clifetime, 
00532                                                 double(its_spin)/2.);
00533         pdt->insert(pdata);
00534         return pdata;
00535     }
00536 
00537     bool IO_GenEvent::write_end_listing() {
00538         if ( m_finished_first_event_io && (m_ostr != NULL) ) {
00539             m_common_io.write_IO_GenEvent_End(*m_ostr);
00540             *m_ostr << std::flush;
00541             m_finished_first_event_io = 0;
00542             return true;
00543         }
00544         return false;
00545     }
00546         
00547 } // HepMC

Generated on Wed Mar 12 13:08:09 2008 for HepMC by  doxygen 1.5.1-3