hepmc - Blame information for rev 43

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