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

Generated on Wed Jun 3 16:53:01 2009 for HepMC by  doxygen 1.5.1-3