hepmc - Blame information for rev 109

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