hepmc - Blame information for rev 117

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