Line data Source code
1 : // LHEF3.h is a part of the PYTHIA event generator.
2 : // Copyright (C) 2015 Torbjorn Sjostrand.
3 : // PYTHIA is licenced under the GNU GPL version 2, see COPYING for details.
4 : // Please respect the MCnet Guidelines, see GUIDELINES for details.
5 :
6 : // This file is written by Stefan Prestel. The code evolved from
7 : // a LHEF 2.0 reader supplied by Leif Lonnblad.
8 : // LHEF3.h contains the main class for LHEF 3.0 functionalities.
9 : // Header file.
10 :
11 : #ifndef Pythia8_LHEF3_H
12 : #define Pythia8_LHEF3_H
13 :
14 : #include "Pythia8/PythiaStdlib.h"
15 : #include "Pythia8/Streams.h"
16 : #include <stdexcept>
17 :
18 : namespace Pythia8 {
19 :
20 : //==========================================================================
21 :
22 : // The XMLTag struct is used to represent all information within an XML tag.
23 : // It contains the attributes as a map, any sub-tags as a vector of pointers
24 : // to other XMLTag objects, and any other information as a single string.
25 : // The XMLTag struct written by Leif Lonnblad.
26 :
27 0 : struct XMLTag {
28 :
29 : // Convenient typdef.
30 : typedef string::size_type pos_t;
31 :
32 : // Convenient alias for npos.
33 : static const pos_t end = string::npos;
34 :
35 : // The destructor also destroys any sub-tags.
36 0 : ~XMLTag() {
37 0 : for ( int i = 0, N = tags.size(); i < N; ++i )
38 0 : if (tags[i]) delete tags[i];
39 0 : }
40 :
41 : // The name of this tag.
42 : string name;
43 :
44 : // The attributes of this tag.
45 : map<string,string> attr;
46 :
47 : // A vector of sub-tags.
48 : vector<XMLTag*> tags;
49 :
50 : // The contents of this tag.
51 : string contents;
52 :
53 : // Find an attribute named n and set the double variable v to
54 : // the corresponding value. Return false if no attribute was found.
55 : bool getattr(string n, double & v) const {
56 : map<string,string>::const_iterator it = attr.find(n);
57 : if ( it == attr.end() ) return false;
58 : v = atof(it->second.c_str());
59 : return true;
60 : }
61 :
62 : // Find an attribute named n and set the bool variable v to true if the
63 : // corresponding value is "yes". Return false if no attribute was found.
64 : bool getattr(string n, bool & v) const {
65 : map<string,string>::const_iterator it = attr.find(n);
66 : if ( it == attr.end() ) return false;
67 : if ( it->second == "yes" ) v = true;
68 : return true;
69 : }
70 :
71 : // Find an attribute named n and set the long variable v to the
72 : // corresponding value. Return false if no attribute was found.
73 : bool getattr(string n, long & v) const {
74 : map<string,string>::const_iterator it = attr.find(n);
75 : if ( it == attr.end() ) return false;
76 : v = atoi(it->second.c_str());
77 : return true;
78 : }
79 :
80 : // Find an attribute named n and set the long variable v to the
81 : // corresponding value. Return false if no attribute was found.
82 : bool getattr(string n, int & v) const {
83 : map<string,string>::const_iterator it = attr.find(n);
84 : if ( it == attr.end() ) return false;
85 : v = int(atoi(it->second.c_str()));
86 : return true;
87 : }
88 :
89 : // Find an attribute named n and set the string variable v to the
90 : // corresponding value. Return false if no attribute was found.
91 : bool getattr(string n, string & v) const {
92 : map<string,string>::const_iterator it = attr.find(n);
93 : if ( it == attr.end() ) return false;
94 : v = it->second;
95 : return true;
96 : }
97 :
98 : // Scan the given string and return all XML tags found as a vector
99 : // of pointers to XMLTag objects.
100 : static vector<XMLTag*> findXMLTags(string str,
101 : string * leftover = 0) {
102 0 : vector<XMLTag*> tags;
103 : pos_t curr = 0;
104 :
105 0 : while ( curr != end ) {
106 :
107 : // Find the first tag.
108 0 : pos_t begin = str.find("<", curr);
109 :
110 : // Skip comments.
111 0 : if ( str.find("<!--", curr) == begin ) {
112 0 : pos_t endcom = str.find("-->", begin);
113 0 : if ( endcom == end ) {
114 0 : if ( leftover ) *leftover += str.substr(curr);
115 0 : return tags;
116 : }
117 0 : if ( leftover ) *leftover += str.substr(curr, endcom - curr);
118 : curr = endcom;
119 0 : continue;
120 : }
121 :
122 : // Also skip CDATA statements.
123 : // Used for text data that should not be parsed by the XML parser.
124 : // (e.g., JavaScript code contains a lot of "<" or "&" characters
125 : // which XML would erroneously interpret as the start of a new
126 : // element or the start of a character entity, respectively.)
127 : // See eg http://www.w3schools.com/xml/xml_cdata.asp
128 0 : if ( str.find("<![CDATA[", curr) == begin ) {
129 0 : pos_t endcom = str.find("]]>", begin);
130 0 : if ( endcom == end ) {
131 0 : if ( leftover ) *leftover += str.substr(curr);
132 0 : return tags;
133 : }
134 0 : if ( leftover ) *leftover += str.substr(curr, endcom - curr);
135 : curr = endcom;
136 0 : continue;
137 : }
138 :
139 0 : if ( leftover ) *leftover += str.substr(curr, begin - curr);
140 0 : if ( begin == end || begin > str.length() - 3 || str[begin + 1] == '/' )
141 0 : return tags;
142 :
143 0 : pos_t close = str.find(">", curr);
144 0 : if ( close == end ) return tags;
145 :
146 : // Find the tag name.
147 0 : curr = str.find_first_of(" \t\n/>", begin);
148 0 : tags.push_back(new XMLTag());
149 0 : tags.back()->name = str.substr(begin + 1, curr - begin - 1);
150 :
151 0 : while ( true ) {
152 :
153 : // Now skip some white space to see if we can find an attribute.
154 0 : curr = str.find_first_not_of(" \t\n", curr);
155 0 : if ( curr == end || curr >= close ) break;
156 :
157 0 : pos_t tend = str.find_first_of("= \t\n", curr);
158 0 : if ( tend == end || tend >= close ) break;
159 :
160 0 : string name = str.substr(curr, tend - curr);
161 0 : curr = str.find("=", curr) + 1;
162 :
163 : // OK now find the beginning and end of the atribute.
164 0 : curr = str.find("\"", curr);
165 0 : if ( curr == end || curr >= close ) break;
166 0 : pos_t bega = ++curr;
167 0 : curr = str.find("\"", curr);
168 0 : while ( curr != end && str[curr - 1] == '\\' )
169 0 : curr = str.find("\"", curr + 1);
170 :
171 0 : string value = str.substr(bega, curr == end? end: curr - bega);
172 :
173 0 : tags.back()->attr[name] = value;
174 :
175 0 : ++curr;
176 :
177 0 : }
178 :
179 0 : curr = close + 1;
180 0 : if ( str[close - 1] == '/' ) continue;
181 :
182 0 : pos_t endtag = str.find("</" + tags.back()->name + ">", curr);
183 0 : if ( endtag == end ) {
184 0 : tags.back()->contents = str.substr(curr);
185 : curr = endtag;
186 0 : } else {
187 0 : tags.back()->contents = str.substr(curr, endtag - curr);
188 0 : curr = endtag + tags.back()->name.length() + 3;
189 : }
190 :
191 0 : string leftovers;
192 0 : tags.back()->tags = findXMLTags(tags.back()->contents, &leftovers);
193 0 : if ( leftovers.find_first_not_of(" \t\n") == end ) leftovers="";
194 0 : tags.back()->contents = leftovers;
195 :
196 0 : }
197 :
198 0 : return tags;
199 :
200 0 : }
201 :
202 : // Print out this tag to a stream.
203 : void print(ostream & os) const {
204 : os << "<" << name;
205 : for ( map<string,string>::const_iterator it = attr.begin();
206 : it != attr.end(); ++it )
207 : os << " " << it->first << "=\"" << it->second << "\"";
208 : if ( contents.empty() && tags.empty() ) {
209 : os << "/>" << endl;
210 : return;
211 : }
212 : os << ">" << endl;
213 : for ( int i = 0, N = tags.size(); i < N; ++i )
214 : tags[i]->print(os);
215 :
216 : os << "````" << contents << "''''</" << name << ">" << endl;
217 : }
218 :
219 : };
220 :
221 : //==========================================================================
222 :
223 : // The LHAweights struct represents the information in a weights tag.
224 :
225 0 : struct LHAweights {
226 :
227 : // Initialize default values.
228 0 : LHAweights() {}
229 :
230 : // Construct from XML tag
231 : LHAweights(const XMLTag & tag);
232 :
233 : // Print out an XML tag.
234 : void print(ostream & file) const;
235 :
236 : // Function to reset this object.
237 : void clear() {
238 0 : contents="";
239 0 : weights.clear();
240 0 : attributes.clear();
241 0 : }
242 :
243 : // The weights of this event.
244 : vector<double> weights;
245 :
246 : // Any other attributes.
247 : map<string,string> attributes;
248 :
249 : // The contents of the tag.
250 : string contents;
251 :
252 : };
253 :
254 : //==========================================================================
255 :
256 : // Collect different scales relevant for an event.
257 :
258 0 : struct LHAscales {
259 :
260 : // Empty constructor.
261 0 : LHAscales(double defscale = -1.0)
262 0 : : muf(defscale), mur(defscale), mups(defscale), SCALUP(defscale) {}
263 :
264 : // Construct from an XML-tag
265 : LHAscales(const XMLTag & tag, double defscale = -1.0);
266 :
267 : // Print out the corresponding XML-tag.
268 : void print(ostream & file) const;
269 :
270 : // Function to reset this object.
271 : void clear() {
272 0 : contents="";
273 0 : muf=mur=mups=SCALUP;
274 0 : attributes.clear();
275 0 : }
276 :
277 : // The factorization scale used for this event.
278 : double muf;
279 :
280 : // The renormalization scale used for this event.
281 : double mur;
282 :
283 : // The starting scale for the parton shower as suggested by the
284 : // matrix element generator.
285 : double mups;
286 :
287 : // Any other scales reported by the matrix element generator.
288 : map<string,double> attributes;
289 :
290 : // The default scale in this event.
291 : double SCALUP;
292 :
293 : // The contents of the tag.
294 : string contents;
295 :
296 : };
297 :
298 : //==========================================================================
299 :
300 : // Collect generator information for an event file.
301 :
302 0 : struct LHAgenerator {
303 :
304 : // Empty constructor.
305 : LHAgenerator()
306 : : name(""), version(""), contents("") {}
307 :
308 : // Construct from an XML-tag
309 : LHAgenerator(const XMLTag & tag, string defname = "");
310 :
311 : // Print out the corresponding XML-tag.
312 : void print(ostream & file) const;
313 :
314 : // Function to reset this object.
315 : void clear() {
316 : contents="";
317 : name="";
318 : version="";
319 : attributes.clear();
320 : }
321 :
322 : // The generator name used for this file.
323 : string name;
324 :
325 : // The generator version used for this file.
326 : string version;
327 :
328 : // Any other attributes.
329 : map<string,string> attributes;
330 :
331 : // The contents of the tag.
332 : string contents;
333 :
334 : };
335 :
336 : //==========================================================================
337 :
338 : // Collect the wgt information.
339 :
340 0 : struct LHAwgt {
341 :
342 : // Empty constructor.
343 0 : LHAwgt(double defwgt = 1.0)
344 0 : : id(""), contents(defwgt) {}
345 :
346 : // Construct from an XML-tag
347 : LHAwgt(const XMLTag & tag, double defwgt = 1.0);
348 :
349 : // Print out the corresponding XML-tag.
350 : void print(ostream & file) const;
351 :
352 : // Function to reset this object.
353 : void clear() {
354 : contents=0.0;
355 : id="";
356 : attributes.clear();
357 : }
358 :
359 : // The identification number of this wgt tag.
360 : string id;
361 :
362 : // Any other attributes.
363 : map<string,string> attributes;
364 :
365 : // The weight associated to this tag.
366 : double contents;
367 :
368 : };
369 :
370 : //==========================================================================
371 :
372 : // Collect the wgt information.
373 :
374 0 : struct LHAweight {
375 :
376 : // Empty constructor.
377 : LHAweight(string defname = "")
378 : : id(defname), contents(defname) {}
379 :
380 : // Construct from an XML-tag
381 : LHAweight(const XMLTag & tag, string defname = "");
382 :
383 : // Print out the corresponding XML-tag.
384 : void print(ostream & file) const;
385 :
386 : // Function to reset this object.
387 : void clear() {
388 : contents="";
389 : id="";
390 : attributes.clear();
391 : }
392 :
393 : // The identification number of this weight tag.
394 : string id;
395 :
396 : // Any other attributes.
397 : map<string,string> attributes;
398 :
399 : // The weight description associated to this tag.
400 : string contents;
401 :
402 : };
403 :
404 : //==========================================================================
405 :
406 : // The LHAweightgroup assigns a group-name to a set of LHAweight objects.
407 :
408 0 : struct LHAweightgroup {
409 :
410 : // Default constructor;
411 : LHAweightgroup() {}
412 :
413 : // Construct a group of LHAweight objects from an XML tag and
414 : // insert them in the given vector.
415 : LHAweightgroup(const XMLTag & tag);
416 :
417 : // Print out the corresponding XML-tag.
418 : void print(ostream & file) const;
419 :
420 : // Function to reset this object.
421 : void clear() {
422 : contents="";
423 : name="";
424 : weights.clear();
425 : attributes.clear();
426 : }
427 :
428 : // The contents of the tag.
429 : string contents;
430 :
431 : // The name.
432 : string name;
433 :
434 : // The vector of weights.
435 : map<string, LHAweight> weights;
436 :
437 : // Any other attributes.
438 : map<string,string> attributes;
439 :
440 : };
441 :
442 : //==========================================================================
443 :
444 : // The LHArwgt assigns a group-name to a set of LHAwgt objects.
445 :
446 0 : struct LHArwgt {
447 :
448 : // Default constructor;
449 0 : LHArwgt() {}
450 :
451 : // Construct a group of LHAwgt objects from an XML tag and
452 : // insert them in the given vector.
453 : LHArwgt(const XMLTag & tag);
454 :
455 : // Print out the corresponding XML-tag.
456 : void print(ostream & file) const;
457 :
458 : // Function to reset this object.
459 : void clear() {
460 0 : contents="";
461 0 : wgts.clear();
462 0 : attributes.clear();
463 0 : }
464 :
465 : // The contents of the tag.
466 : string contents;
467 :
468 : // The map of weights.
469 : map<string, LHAwgt> wgts;
470 :
471 : // Any other attributes.
472 : map<string,string> attributes;
473 :
474 : };
475 :
476 : //==========================================================================
477 :
478 : // The LHAinitrwgt assigns a group-name to a set of LHAweightgroup objects.
479 :
480 0 : struct LHAinitrwgt {
481 :
482 : // Default constructor;
483 0 : LHAinitrwgt() {}
484 :
485 : // Construct a group of LHAweightgroup objects from an XML tag and
486 : // insert them in the given vector.
487 : LHAinitrwgt(const XMLTag & tag);
488 :
489 : // Print out the corresponding XML-tag.
490 : void print(ostream & file) const;
491 :
492 : // Function to reset this object.
493 : void clear() {
494 : contents="";
495 : weights.clear();
496 : weightgroups.clear();
497 : attributes.clear();
498 : }
499 :
500 : // The contents of the tag.
501 : string contents;
502 :
503 : // The vector of weight's.
504 : map<string, LHAweight> weights;
505 :
506 : // The vector of weightgroup's.
507 : map<string, LHAweightgroup> weightgroups;
508 :
509 : // Any other attributes.
510 : map<string,string> attributes;
511 :
512 : };
513 :
514 : //==========================================================================
515 :
516 : // The HEPRUP class is a simple container corresponding to the Les Houches
517 : // accord (<A HREF="http://arxiv.org/abs/hep-ph/0109068">hep-ph/0109068</A>)
518 : // common block with the same name. The members are named in the same
519 : // way as in the common block. However, fortran arrays are represented
520 : // by vectors, except for the arrays of length two which are
521 : // represented by pair objects.
522 :
523 : class HEPRUP {
524 :
525 : public:
526 :
527 : // Default constructor.
528 0 : HEPRUP() : IDWTUP(0), NPRUP(0) {}
529 :
530 : // Assignment operator.
531 : HEPRUP & operator=(const HEPRUP & x) {
532 : IDBMUP = x.IDBMUP;
533 : EBMUP = x.EBMUP;
534 : PDFGUP = x.PDFGUP;
535 : PDFSUP = x.PDFSUP;
536 : IDWTUP = x.IDWTUP;
537 : NPRUP = x.NPRUP;
538 : XSECUP = x.XSECUP;
539 : XERRUP = x.XERRUP;
540 : XMAXUP = x.XMAXUP;
541 : LPRUP = x.LPRUP;
542 : initrwgt = x.initrwgt;
543 : generators = x.generators;
544 : weightgroups = x.weightgroups;
545 : weights = x.weights;
546 : return *this;
547 : }
548 :
549 : // Destructor.
550 0 : ~HEPRUP() {}
551 :
552 : // Set the NPRUP variable, corresponding to the number of
553 : // sub-processes, to \a nrup, and resize all relevant vectors
554 : // accordingly.
555 : void resize(int nrup) {
556 : NPRUP = nrup;
557 : resize();
558 : }
559 :
560 : // Assuming the NPRUP variable, corresponding to the number of
561 : // sub-processes, is correctly set, resize the relevant vectors
562 : // accordingly.
563 : void resize() {
564 0 : XSECUP.resize(NPRUP);
565 0 : XERRUP.resize(NPRUP);
566 0 : XMAXUP.resize(NPRUP);
567 0 : LPRUP.resize(NPRUP);
568 0 : }
569 :
570 : // PDG id's of beam particles. (first/second is in +/-z direction).
571 : pair<long,long> IDBMUP;
572 :
573 : // Energy of beam particles given in GeV.
574 : pair<double,double> EBMUP;
575 :
576 : // The author group for the PDF used for the beams according to the
577 : // PDFLib specification.
578 : pair<int,int> PDFGUP;
579 :
580 : // The id number the PDF used for the beams according to the
581 : // PDFLib specification.
582 : pair<int,int> PDFSUP;
583 :
584 : // Master switch indicating how the ME generator envisages the
585 : // events weights should be interpreted according to the Les Houches
586 : // accord.
587 : int IDWTUP;
588 :
589 : // The number of different subprocesses in this file.
590 : int NPRUP;
591 :
592 : // The cross sections for the different subprocesses in pb.
593 : vector<double> XSECUP;
594 :
595 : // The statistical error in the cross sections for the different
596 : // subprocesses in pb.
597 : vector<double> XERRUP;
598 :
599 : // The maximum event weights (in HEPEUP::XWGTUP) for different
600 : // subprocesses.
601 : vector<double> XMAXUP;
602 :
603 : // The subprocess code for the different subprocesses.
604 : vector<int> LPRUP;
605 :
606 : // Contents of the LHAinitrwgt tag
607 : LHAinitrwgt initrwgt;
608 :
609 : // Contents of the LHAgenerator tags.
610 : vector<LHAgenerator> generators;
611 :
612 : // A map of the LHAweightgroup tags, indexed by name.
613 : map<string,LHAweightgroup> weightgroups;
614 :
615 : // A map of the LHAweight tags, indexed by name.
616 : map<string,LHAweight> weights;
617 :
618 : };
619 :
620 : //==========================================================================
621 :
622 : // The HEPEUP class is a simple container corresponding to the Les Houches
623 : // accord (<A HREF="http://arxiv.org/abs/hep-ph/0109068">hep-ph/0109068</A>)
624 : // common block with the same name. The members are named in the same
625 : // way as in the common block. However, fortran arrays are represented
626 : // by vectors, except for the arrays of length two which are
627 : // represented by pair objects.
628 :
629 : class HEPEUP {
630 :
631 : public:
632 :
633 : // Default constructor.
634 0 : HEPEUP()
635 0 : : NUP(0), IDPRUP(0), XWGTUP(0.0), XPDWUP(0.0, 0.0),
636 0 : SCALUP(0.0), AQEDUP(0.0), AQCDUP(0.0), heprup(0) {}
637 :
638 : // Copy constructor
639 : HEPEUP(const HEPEUP & x) {
640 : operator=(x);
641 : }
642 :
643 : // Copy information from the given HEPEUP.
644 : HEPEUP & setEvent(const HEPEUP & x);
645 :
646 : // Assignment operator.
647 : HEPEUP & operator=(const HEPEUP & x) {
648 : clear();
649 : setEvent(x);
650 : return *this;
651 : }
652 :
653 : // Destructor.
654 0 : ~HEPEUP() {
655 0 : clear();
656 0 : };
657 :
658 : // Reset the HEPEUP object.
659 : void reset();
660 :
661 : // Clear the HEPEUP object.
662 : void clear() {
663 0 : reset();
664 0 : }
665 :
666 : // Set the NUP variable, corresponding to the number of particles in
667 : // the current event, to \a nup, and resize all relevant vectors
668 : // accordingly.
669 : void resize(int nup) {
670 : NUP = nup;
671 : resize();
672 : }
673 :
674 : // Return the main weight for this event.
675 : double weight() const {
676 : return XWGTUP;
677 : }
678 :
679 : // Assuming the NUP variable, corresponding to the number of
680 : // particles in the current event, is correctly set, resize the
681 : // relevant vectors accordingly.
682 : void resize();
683 :
684 : // The number of particle entries in the current event.
685 : int NUP;
686 :
687 : // The subprocess code for this event (as given in LPRUP).
688 : int IDPRUP;
689 :
690 : // The weight for this event.
691 : double XWGTUP;
692 :
693 : // The PDF weights for the two incoming partons. Note that this
694 : // variable is not present in the current LesHouches accord
695 : // (<A HREF="http://arxiv.org/abs/hep-ph/0109068">hep-ph/0109068</A>),
696 : // hopefully it will be present in a future accord.
697 : pair<double,double> XPDWUP;
698 :
699 : // The scale in GeV used in the calculation of the PDF's in this
700 : // event.
701 : double SCALUP;
702 :
703 : // The value of the QED coupling used in this event.
704 : double AQEDUP;
705 :
706 : // The value of the QCD coupling used in this event.
707 : double AQCDUP;
708 :
709 : // The PDG id's for the particle entries in this event.
710 : vector<long> IDUP;
711 :
712 : // The status codes for the particle entries in this event.
713 : vector<int> ISTUP;
714 :
715 : // Indices for the first and last mother for the particle entries in
716 : // this event.
717 : vector< pair<int,int> > MOTHUP;
718 :
719 : // The colour-line indices (first(second) is (anti)colour) for the
720 : // particle entries in this event.
721 : vector< pair<int,int> > ICOLUP;
722 :
723 : // Lab frame momentum (Px, Py, Pz, E and M in GeV) for the particle
724 : // entries in this event.
725 : vector< vector<double> > PUP;
726 :
727 : // Invariant lifetime (c*tau, distance from production to decay in
728 : // mm) for the particle entries in this event.
729 : vector<double> VTIMUP;
730 :
731 : // Spin info for the particle entries in this event given as the
732 : // cosine of the angle between the spin vector of a particle and the
733 : // 3-momentum of the decaying particle, specified in the lab frame.
734 : vector<double> SPINUP;
735 :
736 : // A pointer to the current HEPRUP object.
737 : HEPRUP * heprup;
738 :
739 : // The weights associated with this event, as given by the LHAwgt tags.
740 : map<string,double> weights_detailed;
741 :
742 : // The weights associated with this event, as given by the LHAweights tags.
743 : vector<double> weights_compressed;
744 :
745 : // Contents of the LHAscales tag
746 : LHAscales scales;
747 :
748 : // Contents of the LHAweights tag (compressed format)
749 : LHAweights weights;
750 :
751 : // Contents of the LHArwgt tag (detailed format)
752 : LHArwgt rwgt;
753 :
754 : // Any other attributes.
755 : map<string,string> attributes;
756 :
757 : };
758 :
759 : //==========================================================================
760 :
761 : // The Reader class is initialized with a stream from which to read a
762 : // version 1/3 Les Houches Accord event file. In the constructor of
763 : // the Reader object the optional header information is read and then
764 : // the mandatory init is read. After this the whole header block
765 : // including the enclosing lines with tags are available in the public
766 : // headerBlock member variable. Also the information from the init
767 : // block is available in the heprup member variable and any additional
768 : // comment lines are available in initComments. After each successful
769 : // call to the readEvent() function the standard Les Houches Accord
770 : // information about the event is available in the hepeup member
771 : // variable and any additional comments in the eventComments
772 : // variable. A typical reading sequence would look as follows:
773 :
774 0 : class Reader {
775 :
776 : public:
777 :
778 : // Initialize the Reader with a filename from which to read an event
779 : // file. After the constructor is called the whole header block
780 : // including the enclosing lines with tags are available in the
781 : // public headerBlock member variable. Also the information from the
782 : // init block is available in the heprup member variable and any
783 : // additional comment lines are available in initComments.
784 : //
785 : // filename: the name of the file to read from.
786 : //
787 0 : Reader(string filenameIn)
788 0 : : filename(filenameIn), intstream(filename.c_str()), file(&intstream) {
789 0 : isGood = init();
790 0 : }
791 :
792 : private:
793 :
794 : // Used internally in the constructors to read header and init blocks.
795 : bool init();
796 :
797 : public:
798 :
799 : // Read an event from the file and store it in the hepeup
800 : // object. Optional comment lines are stored in the eventComments
801 : // member variable.
802 : bool readEvent(HEPEUP * peup = 0);
803 :
804 : protected:
805 :
806 : // Used internally to read a single line from the stream.
807 : bool getLine() {
808 0 : currentLine = "";
809 0 : if(!getline(*file, currentLine)) return false;
810 : // Replace single by double quotes
811 0 : replace(currentLine.begin(),currentLine.end(),'\'','\"');
812 0 : return true;
813 0 : }
814 :
815 : protected:
816 :
817 : // Name of file-to-be-read.
818 : string filename;
819 :
820 : // A local stream which is unused if a stream is supplied from the
821 : // outside.
822 : igzstream intstream;
823 :
824 : // The stream we are reading from. This may be a pointer to an
825 : // external stream or the internal intstream.
826 : istream * file;
827 :
828 : // The last line read in from the stream in getline().
829 : string currentLine;
830 :
831 : public:
832 :
833 : // Save if the initialisation worked.
834 : bool isGood;
835 :
836 : // XML file version
837 : int version;
838 :
839 : // All lines (since the last readEvent()) outside the header, init
840 : // and event tags.
841 : string outsideBlock;
842 :
843 : // All lines from the header block.
844 : string headerBlock;
845 : string headerComments;
846 :
847 : // The standard init information.
848 : HEPRUP heprup;
849 :
850 : // Additional comments found in the init block.
851 : string initComments;
852 :
853 : // The standard information about the last read event.
854 : HEPEUP hepeup;
855 :
856 : // Additional comments found with the last read event.
857 : string eventComments;
858 :
859 : private:
860 :
861 : // The default constructor should never be used.
862 : Reader();
863 :
864 : // The copy constructor should never be used.
865 : Reader(const Reader &);
866 :
867 : // The Reader cannot be assigned to.
868 : Reader & operator=(const Reader &);
869 :
870 : };
871 :
872 : //==========================================================================
873 :
874 : // The Writer class is initialized with a stream to which to write a
875 : // version 1.0 or 3.0 Les Houches Accord event file. In the init() function of
876 : // the Writer object the main XML tag, header and init blocks are written,
877 : // with the corresponding end tag is written by print_end_tag().
878 : // After a Writer object (in the following called "writer") has been created,
879 : // it is possible to assign version (3 by default) information by
880 : //
881 : // writer.version = <value>;
882 : //
883 : // The header block (called "someHeaderString" below) is assigned by
884 : //
885 : // writer.headerBlock() << someHeaderString;
886 : //
887 : // and the init block comments (called "someInitString" below) are assigned via
888 : //
889 : // writer.initComments() << someInitString;
890 : //
891 : // The standard init information (including amendments for LHEF 3.0) can
892 : // be assigned by the heprup member variable:
893 : //
894 : // writer.heprup = heprup;
895 : //
896 : // where heprup is an object of type HEPRUP. All of the above information
897 : // will be writen by calling the init() function.
898 : //
899 : // Before each event is written out with the writeEvent() function,
900 : // the standard event information can be assigned to the hepeup
901 : // variable by
902 : //
903 : // writer.hepeup = hepeup;
904 : //
905 : // where hepeup is of type HEPEUP. Event comments (called
906 : // "someCommentString" below) can be assigned through
907 : //
908 : // writer.eventComments() << someCommentString;
909 : //
910 : // All of this event information is written by the writeEvent() function.
911 :
912 : class Writer {
913 :
914 : public:
915 :
916 : // Create a Writer object giving a stream to write to.
917 : // @param os the stream where the event file is written.
918 : Writer(ostream & os)
919 : : file(os), version(3) {}
920 :
921 : // Create a Writer object giving a filename to write to.
922 : // @param filename the name of the event file to be written.
923 : Writer(string filename)
924 : : intstream(filename.c_str()), file(intstream), version(3) {}
925 :
926 : // The destructor.
927 : ~Writer() {}
928 :
929 : // Add header lines consisting of XML code with this stream.
930 : ostream & headerBlock() {
931 : return headerStream;
932 : }
933 :
934 : // Add comment lines to the init block with this stream.
935 : ostream & initComments() {
936 : return initStream;
937 : }
938 :
939 : // Add comment lines to the next event to be written out with this stream.
940 : ostream & eventComments() {
941 : return eventStream;
942 : }
943 :
944 : // Write out the final XML end-tag.
945 : void print_end_tag() {
946 : file << "</LesHouchesEvents>" << endl;
947 : }
948 :
949 : // Write out an optional header block followed by the standard init
950 : // block information together with any comment lines.
951 : void init();
952 :
953 : // Write out the event stored in hepeup, followed by optional
954 : // comment lines.
955 : bool writeEvent(HEPEUP * peup = 0);
956 :
957 : protected:
958 :
959 : // Make sure that each line in the string \a s starts with a
960 : // #-character and that the string ends with a new-line.
961 : string hashline(string s, bool comment = false);
962 :
963 : protected:
964 :
965 : // A local stream which is unused if a stream is supplied from the
966 : // outside.
967 : ofstream intstream;
968 :
969 : // The stream we are writing to. This may be a reference to an
970 : // external stream or the internal intstream.
971 : ostream & file;
972 :
973 : public:
974 :
975 : // Stream to add all lines in the header block.
976 : ostringstream headerStream;
977 :
978 : // The standard init information.
979 : HEPRUP heprup;
980 :
981 : // Stream to add additional comments to be put in the init block.
982 : ostringstream initStream;
983 :
984 : // The standard information about the event we will write next.
985 : HEPEUP hepeup;
986 :
987 : // Stream to add additional comments to be written together the next event.
988 : ostringstream eventStream;
989 :
990 : // XML file version
991 : int version;
992 :
993 : private:
994 :
995 : // The default constructor should never be used.
996 : Writer();
997 :
998 : // The copy constructor should never be used.
999 : Writer(const Writer &);
1000 :
1001 : // The Writer cannot be assigned to.
1002 : Writer & operator=(const Writer &);
1003 :
1004 : };
1005 :
1006 : //==========================================================================
1007 :
1008 : } // end namespace Pythia8
1009 :
1010 : #endif // end Pythia8_LHEF3_H
|