hepmc - Blame information for rev 128

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