hepmc - Diff between revs 455 and 523

Subversion Repositories:
Rev:
Only display areas with differences - Ignore whitespace
Rev 455 Rev 523
1 //-------------------------------------------------------------------------- 1 //--------------------------------------------------------------------------
2 // 2 //
3 // GenEventStreamIO.cc 3 // GenEventStreamIO.cc
4 // Author:  Lynn Garren 4 // Author:  Lynn Garren
5 // 5 //
6 // Implement operator >> and operator << 6 // Implement operator >> and operator <<
7 // 7 //
8 // ---------------------------------------------------------------------- 8 // ----------------------------------------------------------------------
9 9
10 #include <iostream> 10 #include <iostream>
11 #include <ostream> 11 #include <ostream>
12 #include <istream> 12 #include <istream>
13 #include <sstream> 13 #include <sstream>
14 14
15 #include "HepMC/GenEvent.h" 15 #include "HepMC/GenEvent.h"
16 #include "HepMC/GenCrossSection.h" 16 #include "HepMC/GenCrossSection.h"
17 #include "HepMC/StreamInfo.h" 17 #include "HepMC/StreamInfo.h"
18 #include "HepMC/StreamHelpers.h" 18 #include "HepMC/StreamHelpers.h"
19 #include "HepMC/Version.h" 19 #include "HepMC/Version.h"
20 #include "HepMC/IO_Exception.h" 20 #include "HepMC/IO_Exception.h"
21 21
22 namespace HepMC { 22 namespace HepMC {
23 23
24 // ------------------------- local methods ---------------- 24 // ------------------------- local methods ----------------
25 25
26 /// This method is called by the stream destructor. 26 /// This method is called by the stream destructor.
27 /// It does cleanup on stored user data (StreamInfo) 27 /// It does cleanup on stored user data (StreamInfo)
28 /// and is registered by the first call to get_stream_info(). 28 /// and is registered by the first call to get_stream_info().
29 void HepMCStreamCallback(std::ios_base::event e, std::ios_base& b, int i) 29 void HepMCStreamCallback(std::ios_base::event e, std::ios_base& b, int i)
30 { 30 {
31   // only clean up if the stream object is going away. 31   // only clean up if the stream object is going away.
32   if(i!=0 && e!= std::ios_base::erase_event) return; 32   if(i!=0 && e!= std::ios_base::erase_event) return;
33 33
34   // retrieve the pointer to the object 34   // retrieve the pointer to the object
35   StreamInfo* hd = (StreamInfo*)b.pword(i); 35   StreamInfo* hd = (StreamInfo*)b.pword(i);
36   b.pword(i) = 0; 36   b.pword(i) = 0;
37   b.iword(i) = 0; 37   b.iword(i) = 0;
38 #ifdef HEPMC_DEBUG 38 #ifdef HEPMC_DEBUG
39   // the following line is just for sanity checking 39   // the following line is just for sanity checking
40   if(hd) std::cerr << "deleted StreamInfo " << hd->stream_id() << "\n"; 40   if(hd) std::cerr << "deleted StreamInfo " << hd->stream_id() << "\n";
41 #endif 41 #endif
42   delete hd; 42   delete hd;
43 } 43 }
44 44
45 // ------------------------- iomanip ---------------- 45 // ------------------------- iomanip ----------------
46 46
47 /// A custom iomanip that allows us to store and access user data (StreamInfo) 47 /// A custom iomanip that allows us to store and access user data (StreamInfo)
48 /// associated with the stream. 48 /// associated with the stream.
49 /// This method creates the StreamInfo object the first time it is called. 49 /// This method creates the StreamInfo object the first time it is called.
50 template <class IO> 50 template <class IO>
51 StreamInfo& get_stream_info(IO& iost) 51 StreamInfo& get_stream_info(IO& iost)
52 { 52 {
53   if(iost.iword(0) == 0) 53   if(iost.iword(0) == 0)
54     { 54     {
55       // make sure we add the callback if this is the first time through 55       // make sure we add the callback if this is the first time through
56       iost.iword(0)=1; 56       iost.iword(0)=1;
57       iost.register_callback(&HepMCStreamCallback, 0); 57       iost.register_callback(&HepMCStreamCallback, 0);
58       // this is our special "context" record. 58       // this is our special "context" record.
59       // there is one of these at the head of each IO block. 59       // there is one of these at the head of each IO block.
60       // allocate room for a StreamInfo in the userdata area 60       // allocate room for a StreamInfo in the userdata area
61       iost.pword(0) = new StreamInfo; 61       iost.pword(0) = new StreamInfo;
62 #ifdef HEPMC_DEBUG 62 #ifdef HEPMC_DEBUG
63       // the following line is just for sanity checking 63       // the following line is just for sanity checking
64       std::cerr << "created StreamInfo " << ((StreamInfo*)iost.pword(0))->stream_id() << "\n"; 64       std::cerr << "created StreamInfo " << ((StreamInfo*)iost.pword(0))->stream_id() << "\n";
65 #endif 65 #endif
66     } 66     }
67   return *(StreamInfo*)iost.pword(0); 67   return *(StreamInfo*)iost.pword(0);
68 } 68 }
69         69        
70 // ------------------------- GenEvent member functions ---------------- 70 // ------------------------- GenEvent member functions ----------------
71 71
72 std::ostream& GenEvent::write( std::ostream& os ) 72 std::ostream& GenEvent::write( std::ostream& os )
73 { 73 {
74     /// Writes evt to an output stream. 74     /// Writes evt to an output stream.
75 75
76     // 76     //
77     StreamInfo & info = get_stream_info(os); 77     StreamInfo & info = get_stream_info(os);
78     // 78     //
79     // if this is the first event, set precision 79     // if this is the first event, set precision
80     if ( !info.finished_first_event() ) { 80     if ( !info.finished_first_event() ) {
81         // precision 16 (# digits following decimal point) is the minimum that 81         // precision 16 (# digits following decimal point) is the minimum that
82         //  will capture the full information stored in a double 82         //  will capture the full information stored in a double
83         //  However, we let the user set precision, since that is the expected functionality 83         //  However, we let the user set precision, since that is the expected functionality
84         // we use decimal to store integers, because it is smaller than hex! 84         // we use decimal to store integers, because it is smaller than hex!
85         os.setf(std::ios::dec,std::ios::basefield); 85         os.setf(std::ios::dec,std::ios::basefield);
86         os.setf(std::ios::scientific,std::ios::floatfield); 86         os.setf(std::ios::scientific,std::ios::floatfield);
87         // 87         //
88         info.set_finished_first_event(true); 88         info.set_finished_first_event(true);
89     } 89     }
90     // 90     //
91     // output the event data including the number of primary vertices 91     // output the event data including the number of primary vertices
92     //  and the total number of vertices 92     //  and the total number of vertices
93     //std::vector<long> random_states = random_states(); 93     //std::vector<long> random_states = random_states();
94     os << 'E'; 94     os << 'E';
95     detail::output( os, event_number() ); 95     detail::output( os, event_number() );
96     detail::output( os, mpi() ); 96     detail::output( os, mpi() );
97     detail::output( os, event_scale() ); 97     detail::output( os, event_scale() );
98     detail::output( os, alphaQCD() ); 98     detail::output( os, alphaQCD() );
99     detail::output( os, alphaQED() ); 99     detail::output( os, alphaQED() );
100     detail::output( os, signal_process_id() ); 100     detail::output( os, signal_process_id() );
101     detail::output( os,   ( signal_process_vertex() ? 101     detail::output( os,   ( signal_process_vertex() ?
102                 signal_process_vertex()->barcode() : 0 )   ); 102                 signal_process_vertex()->barcode() : 0 )   );
103     detail::output( os, vertices_size() ); // total number of vertices. 103     detail::output( os, vertices_size() ); // total number of vertices.
104     write_beam_particles( os, beam_particles() ); 104     write_beam_particles( os, beam_particles() );
105     // random state 105     // random state
106     detail::output( os, (int)m_random_states.size() ); 106     detail::output( os, (int)m_random_states.size() );
107     for ( std::vector<long>::iterator rs = m_random_states.begin(); 107     for ( std::vector<long>::iterator rs = m_random_states.begin();
108           rs != m_random_states.end(); ++rs ) { 108           rs != m_random_states.end(); ++rs ) {
109          detail::output( os, *rs ); 109          detail::output( os, *rs );
110     } 110     }
111     // weights 111     // weights
112     // we need to iterate over the map so that the weights printed 112     // we need to iterate over the map so that the weights printed
113     // here will be in the same order as the names printed next 113     // here will be in the same order as the names printed next
114     os << ' ' << (int)weights().size() ; 114     os << ' ' << (int)weights().size() ;
115     for ( WeightContainer::const_map_iterator w = weights().map_begin(); 115     for ( WeightContainer::const_map_iterator w = weights().map_begin();
116           w != weights().map_end(); ++w ) { 116           w != weights().map_end(); ++w ) {
117         detail::output( os, m_weights[w->second] ); 117         detail::output( os, m_weights[w->second] );
118     } 118     }
119     detail::output( os,'\n'); 119     detail::output( os,'\n');
120     // now add names for weights 120     // now add names for weights
121     // note that this prints a new line if and only if the weight container 121     // note that this prints a new line if and only if the weight container
122     // is not empty 122     // is not empty
123     if ( ! weights().empty() ) { 123     if ( ! weights().empty() ) {
124         os << "N " << weights().size() << " " ; 124         os << "N " << weights().size() << " " ;
125         for ( WeightContainer::const_map_iterator w = weights().map_begin(); 125         for ( WeightContainer::const_map_iterator w = weights().map_begin();
126               w != weights().map_end(); ++w ) { 126               w != weights().map_end(); ++w ) {
127             detail::output( os,'"'); 127             detail::output( os,'"');
128             os << w->first; 128             os << w->first;
129             detail::output( os,'"'); 129             detail::output( os,'"');
130             detail::output( os,' '); 130             detail::output( os,' ');
131         } 131         }
132         detail::output( os,'\n'); 132         detail::output( os,'\n');
133     } 133     }
134     // 134     //
135     // Units 135     // Units
136     os << "U " << name(momentum_unit()); 136     os << "U " << name(momentum_unit());
137     os << " " << name(length_unit()); 137     os << " " << name(length_unit());
138     detail::output( os,'\n'); 138     detail::output( os,'\n');
139     // 139     //
140     // write GenCrossSection if it has been set 140     // write GenCrossSection if it has been set
141     if( m_cross_section ) m_cross_section->write(os); 141     if( m_cross_section ) m_cross_section->write(os);
142     // 142     //
143     // write HeavyIon and PdfInfo if they have been set 143     // write HeavyIon and PdfInfo if they have been set
144     if( m_heavy_ion ) os << heavy_ion() ; 144     if( m_heavy_ion ) os << heavy_ion() ;
145     if( m_pdf_info ) os << pdf_info() ; 145     if( m_pdf_info ) os << pdf_info() ;
146     // 146     //
147     // Output all of the vertices - note there is no real order. 147     // Output all of the vertices - note there is no real order.
148     for ( GenEvent::vertex_const_iterator v = vertices_begin(); 148     for ( GenEvent::vertex_const_iterator v = vertices_begin();
149           v != vertices_end(); ++v ) { 149           v != vertices_end(); ++v ) {
150         write_vertex(os, *v); 150         write_vertex(os, *v);
151     } 151     }
152     return os; 152     return os;
153 } 153 }
154 154
155 std::istream& GenEvent::read( std::istream& is ) 155 std::istream& GenEvent::read( std::istream& is )
156 { 156 {
157     /// read a GenEvent from streaming input 157     /// read a GenEvent from streaming input
158     // 158     //
159     StreamInfo & info = get_stream_info(is); 159     StreamInfo & info = get_stream_info(is);
160     clear(); 160     clear();
161     // 161     //
162     // search for event listing key before first event only. 162     // search for event listing key before first event only.
163     if ( !info.finished_first_event() ) { 163     if ( !info.finished_first_event() ) {
164         // 164         //
165         find_file_type(is); 165         find_file_type(is);
166         info.set_finished_first_event(true); 166         info.set_finished_first_event(true);
167     } 167     }
168     // 168     //
169     // make sure the stream is good 169     // make sure the stream is good
170     if ( !is ) { 170     if ( !is ) {
171         std::cerr << "streaming input: end of stream found " 171         std::cerr << "streaming input: end of stream found "
172                   << "setting badbit." << std::endl; 172                   << "setting badbit." << std::endl;
173         is.clear(std::ios::badbit); 173         is.clear(std::ios::badbit);
174         return is; 174         return is;
175     } 175     }
176 176
177     // 177     //
178     // test to be sure the next entry is of type "E" then ignore it 178     // test to be sure the next entry is of type "E" then ignore it
179     if ( is.peek()!='E' ) { 179     if ( is.peek()!='E' ) {
180         // if the E is not the next entry, then check to see if it is 180         // if the E is not the next entry, then check to see if it is
181         // the end event listing key - if yes, search for another start key 181         // the end event listing key - if yes, search for another start key
182         int ioendtype; 182         int ioendtype;
183         find_end_key(is,ioendtype); 183         find_end_key(is,ioendtype);
184         if ( ioendtype == info.io_type() ) { 184         if ( ioendtype == info.io_type() ) {
185             find_file_type(is); 185             find_file_type(is);
186             // are we at the end of the file? 186             // are we at the end of the file?
187             if( !is ) return is; 187             if( !is ) return is;
188         } else if ( ioendtype > 0 ) { 188         } else if ( ioendtype > 0 ) {
189             std::cerr << "streaming input: end key does not match start key " 189             std::cerr << "streaming input: end key does not match start key "
190                       << "setting badbit." << std::endl; 190                       << "setting badbit." << std::endl;
191             is.clear(std::ios::badbit); 191             is.clear(std::ios::badbit);
192             return is; 192             return is;
193         } else if ( !info.has_key() ) { 193         } else if ( !info.has_key() ) {
194             find_file_type(is); 194             find_file_type(is);
195             // are we at the end of the file? 195             // are we at the end of the file?
196             if( !is ) return is; 196             if( !is ) return is;
197         } else { 197         } else {
198             std::cerr << "streaming input: end key not found " 198             std::cerr << "streaming input: end key not found "
199                       << "setting badbit." << std::endl; 199                       << "setting badbit." << std::endl;
200             is.clear(std::ios::badbit); 200             is.clear(std::ios::badbit);
201             return is; 201             return is;
202         } 202         }
203     } 203     }
204 204
205     int signal_process_vertex = 0; 205     int signal_process_vertex = 0;
206     int num_vertices = 0, bp1 = 0, bp2 = 0; 206     int num_vertices = 0, bp1 = 0, bp2 = 0;
-   207     bool units_line = false;
207     // OK - now ready to start reading the event, so set the header flag 208     // OK - now ready to start reading the event, so set the header flag
208     info.set_reading_event_header(true); 209     info.set_reading_event_header(true);
209     // The flag will be set to false when we reach the end of the header 210     // The flag will be set to false when we reach the end of the header
210     while(info.reading_event_header()) { 211     while(info.reading_event_header()) {
211         switch(is.peek()) { 212         switch(is.peek()) {
212             case 'E': 213             case 'E':
213             {   // deal with the event line 214             {   // deal with the event line
214                 process_event_line( is, num_vertices, bp1, bp2, signal_process_vertex ); 215                 process_event_line( is, num_vertices, bp1, bp2, signal_process_vertex );
215             } break; 216             } break;
216             case 'N': 217             case 'N':
217             {   // get weight names 218             {   // get weight names
218                 read_weight_names( is ); 219                 read_weight_names( is );
219             } break; 220             } break;
220             case 'U': 221             case 'U':
221             {   // get unit information if it exists 222             {   // get unit information if it exists
-   223                 units_line = true;
222                 if( info.io_type() == gen ) { 224                 if( info.io_type() == gen ) {
223                     read_units( is ); 225                     read_units( is );
224                 } 226                 }
225             } break; 227             } break;
226             case 'C': 228             case 'C':
227             {   // we have a GenCrossSection line 229             {   // we have a GenCrossSection line
228                 // create cross section 230                 // create cross section
229                 GenCrossSection xs; 231                 GenCrossSection xs;
230                 // check for invalid data 232                 // check for invalid data
231                 try { 233                 try {
232                     // read the line 234                     // read the line
233                     xs.read(is); 235                     xs.read(is);
234                 } 236                 }
235                 catch (IO_Exception& e) { 237                 catch (IO_Exception& e) {
236                     detail::find_event_end( is ); 238                     detail::find_event_end( is );
237                 } 239                 }
238                 if(xs.is_set()) { 240                 if(xs.is_set()) {
239                     set_cross_section( xs ); 241                     set_cross_section( xs );
240                 } 242                 }
241             } break; 243             } break;
242             case 'H': 244             case 'H':
243             {   // we have a HeavyIon line OR an unexpected HepMC... line 245             {   // we have a HeavyIon line OR an unexpected HepMC... line
244                 if( info.io_type() == gen || info.io_type() == extascii ) { 246                 if( info.io_type() == gen || info.io_type() == extascii ) {
245                     // get HeavyIon 247                     // get HeavyIon
246                     HeavyIon ion; 248                     HeavyIon ion;
247                     // check for invalid data 249                     // check for invalid data
248                     try { 250                     try {
249                         is >> &ion; 251                         is >> &ion;
250                     } 252                     }
251                     catch (IO_Exception& e) { 253                     catch (IO_Exception& e) {
252                         detail::find_event_end( is ); 254                         detail::find_event_end( is );
253                     } 255                     }
254                     if(ion.is_valid()) { 256                     if(ion.is_valid()) {
255                         set_heavy_ion( ion ); 257                         set_heavy_ion( ion );
256                     } 258                     }
257                 } 259                 }
258             } break; 260             } break;
259             case 'F': 261             case 'F':
260             {   // we have a PdfInfo line 262             {   // we have a PdfInfo line
261                 if( info.io_type() == gen || info.io_type() == extascii ) { 263                 if( info.io_type() == gen || info.io_type() == extascii ) {
262                     // get PdfInfo 264                     // get PdfInfo
263                     PdfInfo pdf; 265                     PdfInfo pdf;
264                     // check for invalid data 266                     // check for invalid data
265                     try { 267                     try {
266                         is >> &pdf; 268                         is >> &pdf;
267                     } 269                     }
268                     catch (IO_Exception& e) { 270                     catch (IO_Exception& e) {
269                         detail::find_event_end( is ); 271                         detail::find_event_end( is );
270                     } 272                     }
271                     if(pdf.is_valid()) { 273                     if(pdf.is_valid()) {
272                         set_pdf_info( pdf ); 274                         set_pdf_info( pdf );
273                     } 275                     }
274                 } 276                 }
275             } break; 277             } break;
276             case 'V': 278             case 'V':
277             {   279             {  
278                 // this should be the first vertex line - exit this loop 280                 // this should be the first vertex line - exit this loop
279                 info.set_reading_event_header(false); 281                 info.set_reading_event_header(false);
280             } break; 282             } break;
281             case 'P': 283             case 'P':
282             {   // we should not find this line 284             {   // we should not find this line
283                 std::cerr << "streaming input: found unexpected line P" << std::endl; 285                 std::cerr << "streaming input: found unexpected line P" << std::endl;
284                 info.set_reading_event_header(false); 286                 info.set_reading_event_header(false);
285             } break; 287             } break;
286             default: 288             default:
287                 // ignore everything else 289                 // ignore everything else
288                 break; 290                 break;
289         } // switch on line type 291         } // switch on line type
290     } // while reading_event_header 292     } // while reading_event_header
-   293     // before proceeding - did we find a units line?
-   294     if( !units_line ) {
-   295         use_units( info.io_momentum_unit(),
-   296                        info.io_position_unit() );
-   297     }
291     // 298     //
292     // the end vertices of the particles are not connected until 299     // the end vertices of the particles are not connected until
293     //  after the event is read --- we store the values in a map until then 300     //  after the event is read --- we store the values in a map until then
294     TempParticleMap particle_to_end_vertex; 301     TempParticleMap particle_to_end_vertex;
295     // 302     //
296     // read in the vertices 303     // read in the vertices
297     for ( int iii = 1; iii <= num_vertices; ++iii ) { 304     for ( int iii = 1; iii <= num_vertices; ++iii ) {
298         GenVertex* v = new GenVertex(); 305         GenVertex* v = new GenVertex();
299         try { 306         try {
300             detail::read_vertex(is,particle_to_end_vertex,v); 307             detail::read_vertex(is,particle_to_end_vertex,v);
301         } 308         }
302         catch (IO_Exception& e) { 309         catch (IO_Exception& e) {
303             for( TempParticleMap::orderIterator it = particle_to_end_vertex.order_begin(); 310             for( TempParticleMap::orderIterator it = particle_to_end_vertex.order_begin();
304                  it != particle_to_end_vertex.order_end(); ++it ) { 311                  it != particle_to_end_vertex.order_end(); ++it ) {
305                 GenParticle* p = it->second; 312                 GenParticle* p = it->second;
306                 // delete particles only if they are not already owned by a vertex 313                 // delete particles only if they are not already owned by a vertex
307                 if( p->production_vertex() ) { 314                 if( p->production_vertex() ) {
308                 } else if( p->end_vertex() ) { 315                 } else if( p->end_vertex() ) {
309                 } else { 316                 } else {
310                      delete p; 317                      delete p;
311                 } 318                 }
312             } 319             }
313             delete v; 320             delete v;
314             detail::find_event_end( is ); 321             detail::find_event_end( is );
315         } 322         }
316         add_vertex( v ); 323         add_vertex( v );
317     } 324     }
318     // set the signal process vertex 325     // set the signal process vertex
319     if ( signal_process_vertex ) { 326     if ( signal_process_vertex ) {
320         set_signal_process_vertex( 327         set_signal_process_vertex(
321             barcode_to_vertex(signal_process_vertex) ); 328             barcode_to_vertex(signal_process_vertex) );
322     } 329     }
323     // 330     //
324     // last connect particles to their end vertices 331     // last connect particles to their end vertices
325     GenParticle* beam1(0); 332     GenParticle* beam1(0);
326     GenParticle* beam2(0); 333     GenParticle* beam2(0);
327     for ( TempParticleMap::orderIterator pmap 334     for ( TempParticleMap::orderIterator pmap
328               = particle_to_end_vertex.order_begin(); 335               = particle_to_end_vertex.order_begin();
329           pmap != particle_to_end_vertex.order_end(); ++pmap ) { 336           pmap != particle_to_end_vertex.order_end(); ++pmap ) {
330         GenParticle* p =  pmap->second; 337         GenParticle* p =  pmap->second;
331         int vtx = particle_to_end_vertex.end_vertex( p ); 338         int vtx = particle_to_end_vertex.end_vertex( p );
332         GenVertex* itsDecayVtx = barcode_to_vertex(vtx); 339         GenVertex* itsDecayVtx = barcode_to_vertex(vtx);
333         if ( itsDecayVtx ) itsDecayVtx->add_particle_in( p ); 340         if ( itsDecayVtx ) itsDecayVtx->add_particle_in( p );
334         else { 341         else {
335             std::cerr << "read_io_genevent: ERROR particle points" 342             std::cerr << "read_io_genevent: ERROR particle points"
336                       << " to null end vertex. " <<std::endl; 343                       << " to null end vertex. " <<std::endl;
337         } 344         }
338         // also look for the beam particles 345         // also look for the beam particles
339         if( p->barcode() == bp1 ) beam1 = p; 346         if( p->barcode() == bp1 ) beam1 = p;
340         if( p->barcode() == bp2 ) beam2 = p; 347         if( p->barcode() == bp2 ) beam2 = p;
341     } 348     }
342     set_beam_particles(beam1,beam2); 349     set_beam_particles(beam1,beam2);
343     return is; 350     return is;
344 } 351 }
345 352
346 // ------------------------- operator << and operator >> ---------------- 353 // ------------------------- operator << and operator >> ----------------
347 354
348 std::ostream & operator << (std::ostream & os, GenEvent & evt) 355 std::ostream & operator << (std::ostream & os, GenEvent & evt)
349 { 356 {
350     /// Writes evt to an output stream. 357     /// Writes evt to an output stream.
351     evt.write(os); 358     evt.write(os);
352     return os; 359     return os;
353 } 360 }
354 361
355 std::istream & operator >> (std::istream & is, GenEvent & evt) 362 std::istream & operator >> (std::istream & is, GenEvent & evt)
356 { 363 {
357     evt.read(is); 364     evt.read(is);
358     return is; 365     return is;
359 } 366 }
360 367
361 // ------------------------- set units ---------------- 368 // ------------------------- set units ----------------
362 369
363 std::istream & set_input_units(std::istream & is, 370 std::istream & set_input_units(std::istream & is,
364                                Units::MomentumUnit mom, 371                                Units::MomentumUnit mom,
365                                Units::LengthUnit len ) 372                                Units::LengthUnit len )
366 { 373 {
367     // 374     //
368     StreamInfo & info = get_stream_info(is); 375     StreamInfo & info = get_stream_info(is);
369     info.use_input_units( mom, len ); 376     info.use_input_units( mom, len );
370     return is; 377     return is;
371 } 378 }
372 379
373 // ------------------------- begin and end block lines ---------------- 380 // ------------------------- begin and end block lines ----------------
374 381
375 std::ostream & write_HepMC_IO_block_begin(std::ostream & os ) 382 std::ostream & write_HepMC_IO_block_begin(std::ostream & os )
376 { 383 {
377     // 384     //
378     StreamInfo & info = get_stream_info(os); 385     StreamInfo & info = get_stream_info(os);
379 386
380     if( !info.finished_first_event() ) { 387     if( !info.finished_first_event() ) {
381     os << "\n" << "HepMC::Version " << versionName(); 388     os << "\n" << "HepMC::Version " << versionName();
382     os << "\n"; 389     os << "\n";
383     os << info.IO_GenEvent_Key() << "\n"; 390     os << info.IO_GenEvent_Key() << "\n";
384     } 391     }
385     return os; 392     return os;
386 } 393 }
387 394
388 std::ostream & write_HepMC_IO_block_end(std::ostream & os ) 395 std::ostream & write_HepMC_IO_block_end(std::ostream & os )
389 { 396 {
390     // 397     //
391     StreamInfo & info = get_stream_info(os); 398     StreamInfo & info = get_stream_info(os);
392 399
393     if( info.finished_first_event() ) { 400     if( info.finished_first_event() ) {
394         os << info.IO_GenEvent_End() << "\n"; 401         os << info.IO_GenEvent_End() << "\n";
395         os << std::flush; 402         os << std::flush;
396     } 403     }
397     return os; 404     return os;
398 } 405 }
399 406
400 std::istream & GenEvent::process_event_line( std::istream & is, 407 std::istream & GenEvent::process_event_line( std::istream & is,
401                                              int & num_vertices, 408                                              int & num_vertices,
402                                              int & bp1, int & bp2, 409                                              int & bp1, int & bp2,
403                                              int & signal_process_vertex ) 410                                              int & signal_process_vertex )
404 { 411 {
405     // 412     //
406     if ( !is ) { 413     if ( !is ) {
407         std::cerr << "GenEvent::process_event_line setting badbit." << std::endl; 414         std::cerr << "GenEvent::process_event_line setting badbit." << std::endl;
408         is.clear(std::ios::badbit); 415         is.clear(std::ios::badbit);
409         return is; 416         return is;
410     } 417     }
411     // 418     //
412     StreamInfo & info = get_stream_info(is); 419     StreamInfo & info = get_stream_info(is);
413     std::string line; 420     std::string line;
414     std::getline(is,line); 421     std::getline(is,line);
415     std::istringstream iline(line); 422     std::istringstream iline(line);
416     std::string firstc; 423     std::string firstc;
417     iline >> firstc; 424     iline >> firstc;
418     // 425     //
419     // read values into temp variables, then fill GenEvent 426     // read values into temp variables, then fill GenEvent
420     int event_number = 0, signal_process_id = 0, 427     int event_number = 0, signal_process_id = 0,
421         random_states_size = 0, nmpi = -1; 428         random_states_size = 0, nmpi = -1;
422     double eventScale = 0, alpha_qcd = 0, alpha_qed = 0; 429     double eventScale = 0, alpha_qcd = 0, alpha_qed = 0;
423     iline >> event_number; 430     iline >> event_number;
424     if(!iline) detail::find_event_end( is ); 431     if(!iline) detail::find_event_end( is );
425     if( info.io_type() == gen || info.io_type() == extascii ) { 432     if( info.io_type() == gen || info.io_type() == extascii ) {
426         iline >> nmpi; 433         iline >> nmpi;
427         if(!iline) detail::find_event_end( is ); 434         if(!iline) detail::find_event_end( is );
428         set_mpi( nmpi ); 435         set_mpi( nmpi );
429     } 436     }
430     iline >> eventScale ; 437     iline >> eventScale ;
431     if(!iline) detail::find_event_end( is ); 438     if(!iline) detail::find_event_end( is );
432     iline >> alpha_qcd ; 439     iline >> alpha_qcd ;
433     if(!iline) detail::find_event_end( is ); 440     if(!iline) detail::find_event_end( is );
434     iline >> alpha_qed; 441     iline >> alpha_qed;
435     if(!iline) detail::find_event_end( is ); 442     if(!iline) detail::find_event_end( is );
436     iline >> signal_process_id ; 443     iline >> signal_process_id ;
437     if(!iline) detail::find_event_end( is ); 444     if(!iline) detail::find_event_end( is );
438     iline >> signal_process_vertex; 445     iline >> signal_process_vertex;
439     if(!iline) detail::find_event_end( is ); 446     if(!iline) detail::find_event_end( is );
440     iline >> num_vertices; 447     iline >> num_vertices;
441     if(!iline) detail::find_event_end( is ); 448     if(!iline) detail::find_event_end( is );
442     if( info.io_type() == gen || info.io_type() == extascii ) { 449     if( info.io_type() == gen || info.io_type() == extascii ) {
443         iline >> bp1 ; 450         iline >> bp1 ;
444         if(!iline) detail::find_event_end( is ); 451         if(!iline) detail::find_event_end( is );
445         iline >> bp2; 452         iline >> bp2;
446         if(!iline) detail::find_event_end( is ); 453         if(!iline) detail::find_event_end( is );
447     } 454     }
448     iline >> random_states_size; 455     iline >> random_states_size;
449     if(!iline) detail::find_event_end( is ); 456     if(!iline) detail::find_event_end( is );
450     std::vector<long> random_states(random_states_size); 457     std::vector<long> random_states(random_states_size);
451     for ( int i = 0; i < random_states_size; ++i ) { 458     for ( int i = 0; i < random_states_size; ++i ) {
452         iline >> random_states[i]; 459         iline >> random_states[i];
453         if(!iline) detail::find_event_end( is ); 460         if(!iline) detail::find_event_end( is );
454     } 461     }
455     WeightContainer::size_type weights_size = 0; 462     WeightContainer::size_type weights_size = 0;
456     iline >> weights_size; 463     iline >> weights_size;
457     if(!iline) detail::find_event_end( is ); 464     if(!iline) detail::find_event_end( is );
458     std::vector<double> wgt(weights_size); 465     std::vector<double> wgt(weights_size);
459     for ( WeightContainer::size_type ii = 0; ii < weights_size; ++ii ) { 466     for ( WeightContainer::size_type ii = 0; ii < weights_size; ++ii ) {
460         iline >> wgt[ii]; 467         iline >> wgt[ii];
461         if(!iline) detail::find_event_end( is ); 468         if(!iline) detail::find_event_end( is );
462     } 469     }
463     // weight names will be added later if they exist 470     // weight names will be added later if they exist
464     if( weights_size > 0 ) m_weights = wgt; 471     if( weights_size > 0 ) m_weights = wgt;
465     // 472     //
466     // fill signal_process_id, event_number, random_states, etc. 473     // fill signal_process_id, event_number, random_states, etc.
467     set_signal_process_id( signal_process_id ); 474     set_signal_process_id( signal_process_id );
468     set_event_number( event_number ); 475     set_event_number( event_number );
469     set_random_states( random_states ); 476     set_random_states( random_states );
470     set_event_scale( eventScale ); 477     set_event_scale( eventScale );
471     set_alphaQCD( alpha_qcd ); 478     set_alphaQCD( alpha_qcd );
472     set_alphaQED( alpha_qed ); 479     set_alphaQED( alpha_qed );
473     // 480     //
474     return is; 481     return is;
475 } 482 }
476 483
477 std::istream & GenEvent::read_weight_names( std::istream & is ) 484 std::istream & GenEvent::read_weight_names( std::istream & is )
478 { 485 {
479     // now check for a named weight line 486     // now check for a named weight line
480     if ( !is ) { 487     if ( !is ) {
481         std::cerr << "GenEvent::read_weight_names setting badbit." << std::endl; 488         std::cerr << "GenEvent::read_weight_names setting badbit." << std::endl;
482         is.clear(std::ios::badbit); 489         is.clear(std::ios::badbit);
483         return is; 490         return is;
484     } 491     }
485     // Test to be sure the next entry is of type "N" 492     // Test to be sure the next entry is of type "N"
486     // If we have no named weight line, this is not an error 493     // If we have no named weight line, this is not an error
487     // releases prior to 2.06.00 do not have named weights 494     // releases prior to 2.06.00 do not have named weights
488     if ( is.peek() !='N') { 495     if ( is.peek() !='N') {
489         return is; 496         return is;
490     } 497     }
491     // now get this line and process it 498     // now get this line and process it
492     std::string line; 499     std::string line;
493     std::getline(is,line); 500     std::getline(is,line);
494     std::istringstream wline(line); 501     std::istringstream wline(line);
495     std::string firstc; 502     std::string firstc;
496     WeightContainer::size_type name_size = 0; 503     WeightContainer::size_type name_size = 0;
497     wline >> firstc >> name_size; 504     wline >> firstc >> name_size;
498     if(!wline) detail::find_event_end( is ); 505     if(!wline) detail::find_event_end( is );
499     if( firstc != "N") { 506     if( firstc != "N") {
500         std::cout << "debug: first character of named weights is " << firstc << std::endl; 507         std::cout << "debug: first character of named weights is " << firstc << std::endl;
501         std::cout << "debug: We should never get here" << std::endl; 508         std::cout << "debug: We should never get here" << std::endl;
502         is.clear(std::ios::badbit); 509         is.clear(std::ios::badbit);
503         return is; 510         return is;
504     } 511     }
505     if( m_weights.size() != name_size ) { 512     if( m_weights.size() != name_size ) {
506         std::cout << "debug: weight sizes do not match "<< std::endl; 513         std::cout << "debug: weight sizes do not match "<< std::endl;
507         std::cout << "debug: weight vector size is " << m_weights.size() << std::endl; 514         std::cout << "debug: weight vector size is " << m_weights.size() << std::endl;
508         std::cout << "debug: weight name size is " << name_size << std::endl; 515         std::cout << "debug: weight name size is " << name_size << std::endl;
509         is.clear(std::ios::badbit); 516         is.clear(std::ios::badbit);
510         return is; 517         return is;
511     } 518     }
512     std::string name; 519     std::string name;
513     std::string::size_type i1 = line.find("\""); 520     std::string::size_type i1 = line.find("\"");
514     std::string::size_type i2; 521     std::string::size_type i2;
515     std::string::size_type len = line.size(); 522     std::string::size_type len = line.size();
516     WeightContainer namedWeight; 523     WeightContainer namedWeight;
517     for ( WeightContainer::size_type ii = 0; ii < name_size; ++ii ) { 524     for ( WeightContainer::size_type ii = 0; ii < name_size; ++ii ) {
518         // weight names may contain blanks 525         // weight names may contain blanks
519         if(i1 >= len) { 526         if(i1 >= len) {
520             std::cout << "debug: attempting to read past the end of the named weight line " << std::endl; 527             std::cout << "debug: attempting to read past the end of the named weight line " << std::endl;
521             std::cout << "debug: We should never get here" << std::endl; 528             std::cout << "debug: We should never get here" << std::endl;
522             std::cout << "debug: Looking for the end of this event" << std::endl; 529             std::cout << "debug: Looking for the end of this event" << std::endl;
523             detail::find_event_end( is ); 530             detail::find_event_end( is );
524         } 531         }
525         i2 = line.find("\"",i1+1); 532         i2 = line.find("\"",i1+1);
526         name = line.substr(i1+1,i2-i1-1); 533         name = line.substr(i1+1,i2-i1-1);
527         namedWeight[name] = m_weights[ii]; 534         namedWeight[name] = m_weights[ii];
528         i1 = line.find("\"",i2+1); 535         i1 = line.find("\"",i2+1);
529     } 536     }
530     m_weights = namedWeight; 537     m_weights = namedWeight;
531     return is; 538     return is;
532 } 539 }
533 540
534 std::istream & GenEvent::read_units( std::istream & is ) 541 std::istream & GenEvent::read_units( std::istream & is )
535 { 542 {
536     // 543     //
537     if ( !is ) { 544     if ( !is ) {
538         std::cerr << "GenEvent::read_units setting badbit." << std::endl; 545         std::cerr << "GenEvent::read_units setting badbit." << std::endl;
539         is.clear(std::ios::badbit); 546         is.clear(std::ios::badbit);
540         return is; 547         return is;
541     } 548     }
542     // 549     //
543     StreamInfo & info = get_stream_info(is); 550     StreamInfo & info = get_stream_info(is);
544     // test to be sure the next entry is of type "U" then ignore it 551     // test to be sure the next entry is of type "U" then ignore it
545     // if we have no units, this is not an error 552     // if we have no units, this is not an error
546     // releases prior to 2.04.00 did not write unit information 553     // releases prior to 2.04.00 did not write unit information
547     if ( is.peek() !='U') { 554     if ( is.peek() !='U') {
548         use_units( info.io_momentum_unit(), 555         use_units( info.io_momentum_unit(),
549                        info.io_position_unit() ); 556                        info.io_position_unit() );
550         return is; 557         return is;
551     } 558     }
552     is.ignore();        // ignore the first character in the line 559     is.ignore();        // ignore the first character in the line
553     std::string mom, pos; 560     std::string mom, pos;
554     is >> mom >> pos; 561     is >> mom >> pos;
555     is.ignore(1);      // eat the extra whitespace 562     is.ignore(1);      // eat the extra whitespace
556     use_units(mom,pos); 563     use_units(mom,pos);
557     // 564     //
558     return is; 565     return is;
559 } 566 }
560 567
561 std::istream & GenEvent::find_file_type( std::istream & istr ) 568 std::istream & GenEvent::find_file_type( std::istream & istr )
562 { 569 {
563     // 570     //
564     // make sure the stream is good 571     // make sure the stream is good
565     if ( !istr ) return istr; 572     if ( !istr ) return istr;
566 573
567     // 574     //
568     StreamInfo & info = get_stream_info(istr); 575     StreamInfo & info = get_stream_info(istr);
569 576
570     // if there is no input block line, then we assume this stream 577     // if there is no input block line, then we assume this stream
571     // is in the IO_GenEvent format 578     // is in the IO_GenEvent format
572     if ( istr.peek()=='E' ) { 579     if ( istr.peek()=='E' ) {
573         info.set_io_type( gen ); 580         info.set_io_type( gen );
574         info.set_has_key(false); 581         info.set_has_key(false);
575         return istr; 582         return istr;
576     } 583     }
577     584    
578     std::string line; 585     std::string line;
579     while ( std::getline(istr,line) ) { 586     while ( std::getline(istr,line) ) {
580         // 587         //
581         // search for event listing key before first event only. 588         // search for event listing key before first event only.
582         // 589         //
583         if( line == info.IO_GenEvent_Key() ) { 590         if( line == info.IO_GenEvent_Key() ) {
584             info.set_io_type( gen ); 591             info.set_io_type( gen );
585             info.set_has_key(true); 592             info.set_has_key(true);
586             return istr; 593             return istr;
587         } else if( line == info.IO_Ascii_Key() ) { 594         } else if( line == info.IO_Ascii_Key() ) {
588             info.set_io_type( ascii ); 595             info.set_io_type( ascii );
589             info.set_has_key(true); 596             info.set_has_key(true);
590             return istr; 597             return istr;
591         } else if( line == info.IO_ExtendedAscii_Key() ) { 598         } else if( line == info.IO_ExtendedAscii_Key() ) {
592             info.set_io_type( extascii ); 599             info.set_io_type( extascii );
593             info.set_has_key(true); 600             info.set_has_key(true);
594             return istr; 601             return istr;
595         } else if( line == info.IO_Ascii_PDT_Key() ) { 602         } else if( line == info.IO_Ascii_PDT_Key() ) {
596             info.set_io_type( ascii_pdt ); 603             info.set_io_type( ascii_pdt );
597             info.set_has_key(true); 604             info.set_has_key(true);
598             return istr; 605             return istr;
599         } else if( line == info.IO_ExtendedAscii_PDT_Key() ) { 606         } else if( line == info.IO_ExtendedAscii_PDT_Key() ) {
600             info.set_io_type( extascii_pdt ); 607             info.set_io_type( extascii_pdt );
601             info.set_has_key(true); 608             info.set_has_key(true);
602             return istr; 609             return istr;
603         } 610         }
604     } 611     }
605     info.set_io_type( 0 ); 612     info.set_io_type( 0 );
606     info.set_has_key(false); 613     info.set_has_key(false);
607     return istr; 614     return istr;
608 } 615 }
609 616
610 std::istream & GenEvent::find_end_key( std::istream & istr, int & iotype ) 617 std::istream & GenEvent::find_end_key( std::istream & istr, int & iotype )
611 { 618 {
612     iotype = 0; 619     iotype = 0;
613     // peek at the first character before proceeding 620     // peek at the first character before proceeding
614     if( istr.peek()!='H' ) return istr; 621     if( istr.peek()!='H' ) return istr;
615     // 622     //
616     // we only check the next line 623     // we only check the next line
617     std::string line; 624     std::string line;
618     std::getline(istr,line); 625     std::getline(istr,line);
619     // 626     //
620     StreamInfo & info = get_stream_info(istr); 627     StreamInfo & info = get_stream_info(istr);
621     // 628     //
622     // check to see if this is an end key 629     // check to see if this is an end key
623     if( line == info.IO_GenEvent_End() ) { 630     if( line == info.IO_GenEvent_End() ) {
624         iotype = gen; 631         iotype = gen;
625     } else if( line == info.IO_Ascii_End() ) { 632     } else if( line == info.IO_Ascii_End() ) {
626         iotype = ascii; 633         iotype = ascii;
627     } else if( line == info.IO_ExtendedAscii_End() ) { 634     } else if( line == info.IO_ExtendedAscii_End() ) {
628         iotype = extascii; 635         iotype = extascii;
629     } else if( line == info.IO_Ascii_PDT_End() ) { 636     } else if( line == info.IO_Ascii_PDT_End() ) {
630         iotype = ascii_pdt; 637         iotype = ascii_pdt;
631     } else if( line == info.IO_ExtendedAscii_PDT_End() ) { 638     } else if( line == info.IO_ExtendedAscii_PDT_End() ) {
632         iotype = extascii_pdt; 639         iotype = extascii_pdt;
633     } 640     }
634     if( iotype != 0 && info.io_type() != iotype ) { 641     if( iotype != 0 && info.io_type() != iotype ) {
635         std::cerr << "GenEvent::find_end_key: iotype keys have changed" << std::endl; 642         std::cerr << "GenEvent::find_end_key: iotype keys have changed" << std::endl;
636     } else { 643     } else {
637         return istr; 644         return istr;
638     } 645     }
639     // 646     //
640     // if we get here, then something has gotten badly confused 647     // if we get here, then something has gotten badly confused
641     std::cerr << "GenEvent::find_end_key: MALFORMED INPUT" << std::endl; 648     std::cerr << "GenEvent::find_end_key: MALFORMED INPUT" << std::endl;
642     istr.clear(std::ios::badbit); 649     istr.clear(std::ios::badbit);
643     return istr; 650     return istr;
644 } 651 }
645 652
646 std::ostream & establish_output_stream_info( std::ostream & os ) 653 std::ostream & establish_output_stream_info( std::ostream & os )
647 { 654 {
648     StreamInfo & info = get_stream_info(os); 655     StreamInfo & info = get_stream_info(os);
649     if ( !info.finished_first_event() ) { 656     if ( !info.finished_first_event() ) {
650         // precision 16 (# digits following decimal point) is the minimum that 657         // precision 16 (# digits following decimal point) is the minimum that
651         //  will capture the full information stored in a double 658         //  will capture the full information stored in a double
652         os.precision(16); 659         os.precision(16);
653         // we use decimal to store integers, because it is smaller than hex! 660         // we use decimal to store integers, because it is smaller than hex!
654         os.setf(std::ios::dec,std::ios::basefield); 661         os.setf(std::ios::dec,std::ios::basefield);
655         os.setf(std::ios::scientific,std::ios::floatfield); 662         os.setf(std::ios::scientific,std::ios::floatfield);
656     } 663     }
657     return os; 664     return os;
658 } 665 }
659 666
660 std::istream & establish_input_stream_info( std::istream & is ) 667 std::istream & establish_input_stream_info( std::istream & is )
661 { 668 {
662     StreamInfo & info = get_stream_info(is); 669     StreamInfo & info = get_stream_info(is);
663     if ( !info.finished_first_event() ) { 670     if ( !info.finished_first_event() ) {
664         // precision 16 (# digits following decimal point) is the minimum that 671         // precision 16 (# digits following decimal point) is the minimum that
665         //  will capture the full information stored in a double 672         //  will capture the full information stored in a double
666         is.precision(16); 673         is.precision(16);
667         // we use decimal to store integers, because it is smaller than hex! 674         // we use decimal to store integers, because it is smaller than hex!
668         is.setf(std::ios::dec,std::ios::basefield); 675         is.setf(std::ios::dec,std::ios::basefield);
669         is.setf(std::ios::scientific,std::ios::floatfield); 676         is.setf(std::ios::scientific,std::ios::floatfield);
670     } 677     }
671     return is; 678     return is;
672 } 679 }
673 680
674 681
675 // ------------------------- helper functions ---------------- 682 // ------------------------- helper functions ----------------
676 683
677 namespace detail { 684 namespace detail {
678 685
679 // The functions defined here need to use get_stream_info 686 // The functions defined here need to use get_stream_info
680 687
681 std::istream & read_particle( std::istream & is, 688 std::istream & read_particle( std::istream & is,
682                               TempParticleMap & particle_to_end_vertex, 689                               TempParticleMap & particle_to_end_vertex,
683                               GenParticle * p ) 690                               GenParticle * p )
684 { 691 {
685     // get the next line 692     // get the next line
686     std::string line; 693     std::string line;
687     std::getline(is,line); 694     std::getline(is,line);
688     std::istringstream iline(line); 695     std::istringstream iline(line);
689     std::string firstc; 696     std::string firstc;
690     iline >> firstc; 697     iline >> firstc;
691     if( firstc != "P" ) { 698     if( firstc != "P" ) {
692         std::cerr << "StreamHelpers::detail::read_particle invalid line type: " 699         std::cerr << "StreamHelpers::detail::read_particle invalid line type: "
693                   << firstc << std::endl; 700                   << firstc << std::endl;
694         std::cerr << "StreamHelpers::detail::read_particle setting badbit." 701         std::cerr << "StreamHelpers::detail::read_particle setting badbit."
695                   << std::endl; 702                   << std::endl;
696         is.clear(std::ios::badbit); 703         is.clear(std::ios::badbit);
697         return is; 704         return is;
698     } 705     }
699     // 706     //
700     StreamInfo & info = get_stream_info(is); 707     StreamInfo & info = get_stream_info(is);
701     //testHepMC.cc 708     //testHepMC.cc
702     // declare variables to be read in to, and read everything except flow 709     // declare variables to be read in to, and read everything except flow
703     double px = 0., py = 0., pz = 0., e = 0., m = 0., theta = 0., phi = 0.; 710     double px = 0., py = 0., pz = 0., e = 0., m = 0., theta = 0., phi = 0.;
704     int bar_code = 0, id = 0, status = 0, end_vtx_code = 0, flow_size = 0; 711     int bar_code = 0, id = 0, status = 0, end_vtx_code = 0, flow_size = 0;
705     // check that the input stream is still OK after reading item 712     // check that the input stream is still OK after reading item
706     iline >> bar_code ; 713     iline >> bar_code ;
707     if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); } 714     if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); }
708     iline >> id ; 715     iline >> id ;
709     if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); } 716     if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); }
710     iline >> px ; 717     iline >> px ;
711     if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); } 718     if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); }
712     iline >> py ; 719     iline >> py ;
713     if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); } 720     if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); }
714     iline >> pz ; 721     iline >> pz ;
715     if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); } 722     if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); }
716     iline >> e ; 723     iline >> e ;
717     if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); } 724     if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); }
718     if( info.io_type() != ascii ) { 725     if( info.io_type() != ascii ) {
719         iline >> m ; 726         iline >> m ;
720         if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); } 727         if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); }
721     } 728     }
722     iline >> status ; 729     iline >> status ;
723     if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); } 730     if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); }
724     iline >> theta ; 731     iline >> theta ;
725     if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); } 732     if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); }
726     iline >> phi ; 733     iline >> phi ;
727     if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); } 734     if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); }
728     iline >> end_vtx_code ; 735     iline >> end_vtx_code ;
729     if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); } 736     if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); }
730     iline >> flow_size; 737     iline >> flow_size;
731     if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); } 738     if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); }
732     // 739     //
733     // read flow patterns if any exist 740     // read flow patterns if any exist
734     Flow flow; 741     Flow flow;
735     int code_index, code; 742     int code_index, code;
736     for ( int i = 1; i <= flow_size; ++i ) { 743     for ( int i = 1; i <= flow_size; ++i ) {
737         iline >> code_index >> code; 744         iline >> code_index >> code;
738         if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); } 745         if(!iline) {  delete p; throw IO_Exception("read_particle input stream encounterd invalid data"); }
739         flow.set_icode( code_index,code); 746         flow.set_icode( code_index,code);
740     } 747     }
741     p->set_momentum( FourVector(px,py,pz,e) ); 748     p->set_momentum( FourVector(px,py,pz,e) );
742     p->set_pdg_id( id ); 749     p->set_pdg_id( id );
743     p->set_status( status ); 750     p->set_status( status );
744     p->set_flow( flow ); 751     p->set_flow( flow );
745     p->set_polarization( Polarization(theta,phi) ); 752     p->set_polarization( Polarization(theta,phi) );
746     if( info.io_type() == ascii ) { 753     if( info.io_type() == ascii ) {
747         p->set_generated_mass( p->momentum().m() ); 754         p->set_generated_mass( p->momentum().m() );
748     } else { 755     } else {
749         p->set_generated_mass( m ); 756         p->set_generated_mass( m );
750     } 757     }
751     p->suggest_barcode( bar_code ); 758     p->suggest_barcode( bar_code );
752     // 759     //
753     // all particles are connected to their end vertex separately 760     // all particles are connected to their end vertex separately
754     // after all particles and vertices have been created - so we keep 761     // after all particles and vertices have been created - so we keep
755     // a map of all particles that have end vertices 762     // a map of all particles that have end vertices
756     if ( end_vtx_code != 0 ) { 763     if ( end_vtx_code != 0 ) {
757         particle_to_end_vertex.addEndParticle(p,end_vtx_code); 764         particle_to_end_vertex.addEndParticle(p,end_vtx_code);
758     } 765     }
759     return is; -  
760 } -  
761 -  
762 std::istream & read_units( std::istream & is, GenEvent & evt ) -  
763 { -  
764     // -  
765     if ( !is ) { -  
766         std::cerr << "StreamHelpers read_units setting badbit." << std::endl; -  
767         is.clear(std::ios::badbit); -  
768         return is; -  
769     } -  
770     // -  
771     StreamInfo & info = get_stream_info(is); -  
772     // test to be sure the next entry is of type "U" then ignore it -  
773     // if we have no units, this is not an error -  
774     // releases prior to 2.04.00 did not write unit information -  
775     if ( is.peek() !='U') { -  
776         evt.use_units( info.io_momentum_unit(), -  
777                        info.io_position_unit() ); -  
778         return is; -  
779     } -  
780     is.ignore();        // ignore the first character in the line -  
781     std::string mom, pos; -  
782     is >> mom >> pos; -  
783     is.ignore(1);      // eat the extra whitespace -  
784     evt.use_units(mom,pos); -  
785     // -  
786     return is; 766     return is;
787 } 767 }
788 768
789 std::ostream & establish_output_stream_info( std::ostream & os ) 769 std::ostream & establish_output_stream_info( std::ostream & os )
790 { 770 {
791     StreamInfo & info = get_stream_info(os); 771     StreamInfo & info = get_stream_info(os);
792     if ( !info.finished_first_event() ) { 772     if ( !info.finished_first_event() ) {
793         // precision 16 (# digits following decimal point) is the minimum that 773         // precision 16 (# digits following decimal point) is the minimum that
794         //  will capture the full information stored in a double 774         //  will capture the full information stored in a double
795         os.precision(16); 775         os.precision(16);
796         // we use decimal to store integers, because it is smaller than hex! 776         // we use decimal to store integers, because it is smaller than hex!
797         os.setf(std::ios::dec,std::ios::basefield); 777         os.setf(std::ios::dec,std::ios::basefield);
798         os.setf(std::ios::scientific,std::ios::floatfield); 778         os.setf(std::ios::scientific,std::ios::floatfield);
799     } 779     }
800     return os; 780     return os;
801 } 781 }
802 782
803 std::istream & establish_input_stream_info( std::istream & is ) 783 std::istream & establish_input_stream_info( std::istream & is )
804 { 784 {
805     StreamInfo & info = get_stream_info(is); 785     StreamInfo & info = get_stream_info(is);
806     if ( !info.finished_first_event() ) { 786     if ( !info.finished_first_event() ) {
807         // precision 16 (# digits following decimal point) is the minimum that 787         // precision 16 (# digits following decimal point) is the minimum that
808         //  will capture the full information stored in a double 788         //  will capture the full information stored in a double
809         is.precision(16); 789         is.precision(16);
810         // we use decimal to store integers, because it is smaller than hex! 790         // we use decimal to store integers, because it is smaller than hex!
811         is.setf(std::ios::dec,std::ios::basefield); 791         is.setf(std::ios::dec,std::ios::basefield);
812         is.setf(std::ios::scientific,std::ios::floatfield); 792         is.setf(std::ios::scientific,std::ios::floatfield);
813     } 793     }
814     return is; 794     return is;
815 } 795 }
816 796
817 } // detail 797 } // detail
818 798
819 } // HepMC 799 } // HepMC
820   800