Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:06:26

0001 // LHEF3.h is a part of the PYTHIA event generator.
0002 // Copyright (C) 2024 Torbjorn Sjostrand.
0003 // PYTHIA is licenced under the GNU GPL v2 or later, see COPYING for details.
0004 // Please respect the MCnet Guidelines, see GUIDELINES for details.
0005 
0006 // This file is written by Stefan Prestel. The code evolved from
0007 // a LHEF 2.0 reader supplied by Leif Lonnblad.
0008 // LHEF3.h contains the main class for LHEF 3.0 functionalities.
0009 // Header file.
0010 
0011 #ifndef Pythia8_LHEF3_H
0012 #define Pythia8_LHEF3_H
0013 
0014 #include "Pythia8/PythiaStdlib.h"
0015 #include "Pythia8/Streams.h"
0016 #include <stdexcept>
0017 
0018 namespace Pythia8 {
0019 
0020 //==========================================================================
0021 
0022 // The XMLTag struct is used to represent all information within an XML tag.
0023 // It contains the attributes as a map, any sub-tags as a vector of pointers
0024 // to other XMLTag objects, and any other information as a single string.
0025 // The XMLTag struct written by Leif Lonnblad.
0026 
0027 struct XMLTag {
0028 
0029   // Convenient typdef.
0030   typedef string::size_type pos_t;
0031 
0032   // Convenient alias for npos.
0033   static const pos_t end;
0034 
0035   // The destructor also destroys any sub-tags.
0036   ~XMLTag() {
0037     for ( int i = 0, N = tags.size(); i < N; ++i )
0038       if (tags[i]) delete tags[i];
0039   }
0040 
0041   // The name of this tag.
0042   string name;
0043 
0044   // The attributes of this tag.
0045   map<string,string> attr;
0046 
0047   // A vector of sub-tags.
0048   vector<XMLTag*> tags;
0049 
0050   // The contents of this tag.
0051   string contents;
0052 
0053   // Find an attribute named n and set the double variable v to
0054   // the corresponding value. Return false if no attribute was found.
0055   bool getattr(string n, double & v) const {
0056     map<string,string>::const_iterator it = attr.find(n);
0057     if ( it == attr.end() ) return false;
0058     v = atof(it->second.c_str());
0059     return true;
0060   }
0061 
0062   // Find an attribute named n and set the bool variable v to true if the
0063   // corresponding value is "yes". Return false if no attribute was found.
0064   bool getattr(string n, bool & v) const {
0065     map<string,string>::const_iterator it = attr.find(n);
0066     if ( it == attr.end() ) return false;
0067     if ( it->second == "yes" ) v = true;
0068     return true;
0069   }
0070 
0071   // Find an attribute named n and set the long variable v to the
0072   // corresponding value. Return false if no attribute was found.
0073   bool getattr(string n, long & v) const {
0074     map<string,string>::const_iterator it = attr.find(n);
0075     if ( it == attr.end() ) return false;
0076     v = atoi(it->second.c_str());
0077     return true;
0078   }
0079 
0080   // Find an attribute named n and set the long variable v to the
0081   // corresponding value. Return false if no attribute was found.
0082   bool getattr(string n, int & v) const {
0083     map<string,string>::const_iterator it = attr.find(n);
0084     if ( it == attr.end() ) return false;
0085     v = int(atoi(it->second.c_str()));
0086     return true;
0087   }
0088 
0089   // Find an attribute named n and set the string variable v to the
0090   // corresponding value. Return false if no attribute was found.
0091   bool getattr(string n, string & v) const {
0092     map<string,string>::const_iterator it = attr.find(n);
0093     if ( it == attr.end() ) return false;
0094     v = it->second;
0095     return true;
0096   }
0097 
0098   // Scan the given string and return all XML tags found as a vector
0099   // of pointers to XMLTag objects.
0100   static vector<XMLTag*> findXMLTags(string str,
0101     string * leftover = 0) {
0102     vector<XMLTag*> tags;
0103     pos_t curr = 0;
0104 
0105     while ( curr != end ) {
0106 
0107       // Find the first tag.
0108       pos_t begin = str.find("<", curr);
0109 
0110       // Skip tags in lines beginning with #.
0111       pos_t lastbreak_before_begin = str.find_last_of("\n",begin);
0112       pos_t lastpound_before_begin = str.find_last_of("#",begin);
0113       // Logic: Last newline before begin was before last pound sign (or there
0114       // was no last newline at all, i.e. this is the special case of the
0115       // first line), and hence the pound sign was before the tag was opened
0116       // (at begin) with '<'. Thus, skip forward to next new line.
0117       if ( (lastbreak_before_begin < lastpound_before_begin
0118          || lastbreak_before_begin == end)
0119         && begin > lastpound_before_begin) {
0120         pos_t endcom = str.find_first_of("\n",begin);
0121         if ( endcom == end ) {
0122           if ( leftover ) *leftover += str.substr(curr);
0123              return tags;
0124         }
0125         if ( leftover ) *leftover += str.substr(curr, endcom - curr);
0126         curr = endcom;
0127         continue;
0128       }
0129 
0130       // Skip xml-style comments.
0131       if ( begin != end && str.find("<!--", curr) == begin ) {
0132         pos_t endcom = str.find("-->", begin);
0133         if ( endcom == end ) {
0134           if ( leftover ) *leftover += str.substr(curr);
0135              return tags;
0136         }
0137         if ( leftover ) *leftover += str.substr(curr, endcom - curr);
0138         curr = endcom;
0139         continue;
0140       }
0141 
0142       // Also skip CDATA statements.
0143       // Used for text data that should not be parsed by the XML parser.
0144       // (e.g., JavaScript code contains a lot of "<" or "&" characters
0145       // which XML would erroneously interpret as the start of a new
0146       // element or the start of a character entity, respectively.)
0147       // See eg http://www.w3schools.com/xml/xml_cdata.asp
0148       if ( str.find("<![CDATA[", curr) == begin ) {
0149         pos_t endcom = str.find("]]>", begin);
0150         if ( endcom == end ) {
0151           if ( leftover ) *leftover += str.substr(curr);
0152              return tags;
0153         }
0154         if ( leftover ) *leftover += str.substr(curr, endcom - curr);
0155         curr = endcom;
0156         continue;
0157       }
0158 
0159       if ( leftover ) *leftover += str.substr(curr, begin - curr);
0160       if ( begin == end || begin > str.length() - 3 || str[begin + 1] == '/' )
0161         return tags;
0162 
0163       pos_t close = str.find(">", curr);
0164       if ( close == end ) return tags;
0165 
0166       // Find the tag name.
0167       curr = str.find_first_of(" \t\n/>", begin);
0168       tags.push_back(new XMLTag());
0169       tags.back()->name = str.substr(begin + 1, curr - begin - 1);
0170 
0171       while ( true ) {
0172 
0173         // Now skip some white space to see if we can find an attribute.
0174         curr = str.find_first_not_of(" \t\n", curr);
0175         if ( curr == end || curr >= close ) break;
0176 
0177         pos_t tend = str.find_first_of("= \t\n", curr);
0178         if ( tend == end || tend >= close ) break;
0179 
0180         string name = str.substr(curr, tend - curr);
0181         curr = str.find("=", curr) + 1;
0182 
0183         // OK now find the beginning and end of the atribute.
0184         curr = str.find("\"", curr);
0185         if ( curr == end || curr >= close ) break;
0186         pos_t bega = ++curr;
0187         curr = str.find("\"", curr);
0188         while ( curr != end && str[curr - 1] == '\\' )
0189           curr = str.find("\"", curr + 1);
0190 
0191         string value = str.substr(bega, curr == end? end: curr - bega);
0192 
0193         tags.back()->attr[name] = value;
0194 
0195         ++curr;
0196 
0197       }
0198 
0199       curr = close + 1;
0200       if ( str[close - 1] == '/' ) continue;
0201 
0202       pos_t endtag = str.find("</" + tags.back()->name + ">", curr);
0203       if ( endtag == end ) {
0204         tags.back()->contents = str.substr(curr);
0205         curr = endtag;
0206       } else {
0207         tags.back()->contents = str.substr(curr, endtag - curr);
0208         curr = endtag + tags.back()->name.length() + 3;
0209       }
0210 
0211       string leftovers;
0212       tags.back()->tags = findXMLTags(tags.back()->contents, &leftovers);
0213       if ( leftovers.find_first_not_of(" \t\n") == end ) leftovers="";
0214       tags.back()->contents = leftovers;
0215 
0216     }
0217 
0218     return tags;
0219 
0220   }
0221 
0222   // Print out this tag to a stream.
0223   void list(ostream & os) const {
0224     os << "<" << name;
0225     for ( map<string,string>::const_iterator it = attr.begin();
0226           it != attr.end(); ++it )
0227       os << " " << it->first << "=\"" << it->second << "\"";
0228     if ( contents.empty() && tags.empty() ) {
0229       os << "/>" << endl;
0230       return;
0231     }
0232     os << ">" << endl;
0233     for ( int i = 0, N = tags.size(); i < N; ++i )
0234       tags[i]->list(os);
0235 
0236     os << "````" << contents << "''''</" << name << ">" << endl;
0237   }
0238 
0239 };
0240 
0241 //==========================================================================
0242 
0243 // The LHAweights struct represents the information in a weights tag.
0244 
0245 struct LHAweights {
0246 
0247   // Initialize default values.
0248   LHAweights() {}
0249 
0250   // Construct from XML tag
0251   LHAweights(const XMLTag & tag);
0252 
0253   // Print out an XML tag.
0254   void list(ostream & file) const;
0255 
0256   // Function to reset this object.
0257   void clear() {
0258     contents="";
0259     weights.clear();
0260     attributes.clear();
0261   }
0262 
0263   // The weights of this event.
0264   vector<double> weights;
0265 
0266   // Any other attributes.
0267   map<string,string> attributes;
0268 
0269   // The contents of the tag.
0270   string contents;
0271 
0272   // Return number of weights.
0273   int size() const { return int(weights.size()); }
0274 
0275 };
0276 
0277 //==========================================================================
0278 
0279 // Collect different scales relevant for an event.
0280 
0281 struct LHAscales {
0282 
0283   // Empty constructor.
0284   LHAscales(double defscale = -1.0)
0285   : muf(defscale), mur(defscale), mups(defscale), SCALUP(defscale) {}
0286 
0287   // Construct from an XML-tag
0288   LHAscales(const XMLTag & tag, double defscale = -1.0);
0289 
0290   // Print out the corresponding XML-tag.
0291   void list(ostream & file) const;
0292 
0293   // Function to reset this object.
0294   void clear() {
0295     contents="";
0296     muf=mur=mups=SCALUP;
0297     attributes.clear();
0298   }
0299 
0300   // The factorization scale used for this event.
0301   double muf;
0302 
0303   // The renormalization scale used for this event.
0304   double mur;
0305 
0306   // The starting scale for the parton shower as suggested by the
0307   // matrix element generator.
0308   double mups;
0309 
0310   // Any other scales reported by the matrix element generator.
0311   map<string,double> attributes;
0312 
0313   // The default scale in this event.
0314   double SCALUP;
0315 
0316   // The contents of the tag.
0317   string contents;
0318 
0319 };
0320 
0321 //==========================================================================
0322 
0323 // Collect generator information for an event file.
0324 
0325 struct LHAgenerator {
0326 
0327   // Empty constructor.
0328   LHAgenerator()
0329   : name(""), version(""), contents("") {}
0330 
0331   // Construct from an XML-tag
0332   LHAgenerator(const XMLTag & tag, string defname = "");
0333 
0334   // Print out the corresponding XML-tag.
0335   void list(ostream & file) const;
0336 
0337   // Function to reset this object.
0338   void clear() {
0339     contents="";
0340     name="";
0341     version="";
0342     attributes.clear();
0343   }
0344 
0345   // The generator name used for this file.
0346   string name;
0347 
0348   // The generator version used for this file.
0349   string version;
0350 
0351   // Any other attributes.
0352   map<string,string> attributes;
0353 
0354   // The contents of the tag.
0355   string contents;
0356 
0357 };
0358 
0359 //==========================================================================
0360 
0361 // Collect the wgt information.
0362 
0363 struct LHAwgt {
0364 
0365   // Empty constructor.
0366   LHAwgt(double defwgt = 1.0)
0367   : id(""), contents(defwgt) {}
0368 
0369   // Construct from an XML-tag
0370   LHAwgt(const XMLTag & tag, double defwgt = 1.0);
0371 
0372   // Print out the corresponding XML-tag.
0373   void list(ostream & file) const;
0374 
0375   // Function to reset this object.
0376   void clear() {
0377     contents=0.0;
0378     id="";
0379     attributes.clear();
0380   }
0381 
0382   // The identification number of this wgt tag.
0383   string id;
0384 
0385   // Any other attributes.
0386   map<string,string> attributes;
0387 
0388   // The weight associated to this tag.
0389   double contents;
0390 
0391 };
0392 
0393 //==========================================================================
0394 
0395 // Collect the wgt information.
0396 
0397 struct LHAweight {
0398 
0399   // Empty constructor.
0400   LHAweight(string defname = "")
0401   : id(defname), contents(defname) {}
0402 
0403   // Construct from an XML-tag
0404   LHAweight(const XMLTag & tag, string defname = "");
0405 
0406   // Print out the corresponding XML-tag.
0407   void list(ostream & file) const;
0408 
0409   // Function to reset this object.
0410   void clear() {
0411     contents="";
0412     id="";
0413     attributes.clear();
0414   }
0415 
0416   // The identification number of this weight tag.
0417   string id;
0418 
0419   // Any other attributes.
0420   map<string,string> attributes;
0421 
0422   // The weight description associated to this tag.
0423   string contents;
0424 
0425 };
0426 
0427 //==========================================================================
0428 
0429 // The LHAweightgroup assigns a group-name to a set of LHAweight objects.
0430 
0431 struct LHAweightgroup {
0432 
0433   // Default constructor;
0434   LHAweightgroup() {}
0435 
0436   // Construct a group of LHAweight objects from an XML tag and
0437   // insert them in the given vector.
0438   LHAweightgroup(const XMLTag & tag);
0439 
0440   // Print out the corresponding XML-tag.
0441   void list(ostream & file) const;
0442 
0443   // Function to reset this object.
0444   void clear() {
0445     contents="";
0446     name="";
0447     weights.clear();
0448     attributes.clear();
0449   }
0450 
0451   // The contents of the tag.
0452   string contents;
0453 
0454   // The name.
0455   string name;
0456 
0457   // The vector of weights.
0458   map<string, LHAweight> weights;
0459   vector<string> weightsKeys;
0460 
0461   // Any other attributes.
0462   map<string,string> attributes;
0463 
0464   // Return number of weights.
0465   int size() const { return int(weights.size()); }
0466 
0467 };
0468 
0469 //==========================================================================
0470 
0471 // The LHArwgt assigns a group-name to a set of LHAwgt objects.
0472 
0473 struct LHArwgt {
0474 
0475   // Default constructor;
0476   LHArwgt() {}
0477 
0478   // Construct a group of LHAwgt objects from an XML tag and
0479   // insert them in the given vector.
0480   LHArwgt(const XMLTag & tag);
0481 
0482   // Print out the corresponding XML-tag.
0483   void list(ostream & file) const;
0484 
0485   // Function to reset this object.
0486   void clear() {
0487     contents="";
0488     wgts.clear();
0489     attributes.clear();
0490   }
0491 
0492   // The contents of the tag.
0493   string contents;
0494 
0495   // The map of weights.
0496   map<string, LHAwgt> wgts;
0497   vector<string> wgtsKeys;
0498 
0499   // Any other attributes.
0500   map<string,string> attributes;
0501 
0502   // Return number of weights.
0503   int size() const { return int(wgts.size()); }
0504 
0505 };
0506 
0507 //==========================================================================
0508 
0509 // The LHAinitrwgt assigns a group-name to a set of LHAweightgroup objects.
0510 
0511 struct LHAinitrwgt {
0512 
0513   // Default constructor;
0514   LHAinitrwgt() {}
0515 
0516   // Construct a group of LHAweightgroup objects from an XML tag and
0517   // insert them in the given vector.
0518   LHAinitrwgt(const XMLTag & tag);
0519 
0520   // Print out the corresponding XML-tag.
0521   void list(ostream & file) const;
0522 
0523   // Function to reset this object.
0524   void clear() {
0525     contents="";
0526     weights.clear();
0527     weightgroups.clear();
0528     attributes.clear();
0529   }
0530 
0531   // The contents of the tag.
0532   string contents;
0533 
0534   // The vector of weight's.
0535   map<string, LHAweight> weights;
0536   vector<string> weightsKeys;
0537 
0538   // The vector of weightgroup's.
0539   map<string, LHAweightgroup> weightgroups;
0540   vector<string> weightgroupsKeys;
0541 
0542   // Any other attributes.
0543   map<string,string> attributes;
0544 
0545   // Return number of weights.
0546   int size() const { return int(weights.size());}
0547 
0548   // Return number of weights.
0549   int sizeWeightGroups() const { return int(weightgroups.size()); }
0550 
0551 };
0552 
0553 //==========================================================================
0554 
0555 // The HEPRUP class is a simple container corresponding to the Les Houches
0556 // accord (<A HREF="http://arxiv.org/abs/hep-ph/0109068">hep-ph/0109068</A>)
0557 // common block with the same name. The members are named in the same
0558 // way as in the common block. However, fortran arrays are represented
0559 // by vectors, except for the arrays of length two which are
0560 // represented by pair objects.
0561 
0562 class HEPRUP {
0563 
0564 public:
0565 
0566   // Default constructor.
0567   HEPRUP() : IDWTUP(0), NPRUP(0) {}
0568 
0569   // Assignment operator.
0570   HEPRUP & operator=(const HEPRUP & x) {
0571     IDBMUP = x.IDBMUP;
0572     EBMUP = x.EBMUP;
0573     PDFGUP = x.PDFGUP;
0574     PDFSUP = x.PDFSUP;
0575     IDWTUP = x.IDWTUP;
0576     NPRUP = x.NPRUP;
0577     XSECUP = x.XSECUP;
0578     XERRUP = x.XERRUP;
0579     XMAXUP = x.XMAXUP;
0580     LPRUP = x.LPRUP;
0581     initrwgt = x.initrwgt;
0582     generators = x.generators;
0583     weightgroups = x.weightgroups;
0584     weights = x.weights;
0585     return *this;
0586   }
0587 
0588   // Destructor.
0589   ~HEPRUP() {}
0590 
0591   // Set the NPRUP variable, corresponding to the number of
0592   // sub-processes, to \a nrup, and resize all relevant vectors
0593   // accordingly.
0594   void resize(int nrup) {
0595     NPRUP = nrup;
0596     resize();
0597   }
0598 
0599   // Assuming the NPRUP variable, corresponding to the number of
0600   // sub-processes, is correctly set, resize the relevant vectors
0601   // accordingly.
0602   void resize() {
0603     XSECUP.resize(NPRUP);
0604     XERRUP.resize(NPRUP);
0605     XMAXUP.resize(NPRUP);
0606     LPRUP.resize(NPRUP);
0607   }
0608 
0609   // Clear all members.
0610   void clear();
0611 
0612   // PDG id's of beam particles. (first/second is in +/-z direction).
0613   pair<long,long> IDBMUP;
0614 
0615   // Energy of beam particles given in GeV.
0616   pair<double,double> EBMUP;
0617 
0618   // The author group for the PDF used for the beams according to the
0619   // PDFLib specification.
0620   pair<int,int> PDFGUP;
0621 
0622   // The id number the PDF used for the beams according to the
0623   // PDFLib specification.
0624   pair<int,int> PDFSUP;
0625 
0626   // Master switch indicating how the ME generator envisages the
0627   // events weights should be interpreted according to the Les Houches
0628   // accord.
0629   int IDWTUP;
0630 
0631   // The number of different subprocesses in this file.
0632   int NPRUP;
0633 
0634   // The cross sections for the different subprocesses in pb.
0635   vector<double> XSECUP;
0636 
0637   // The statistical error in the cross sections for the different
0638   // subprocesses in pb.
0639   vector<double> XERRUP;
0640 
0641   // The maximum event weights (in HEPEUP::XWGTUP) for different
0642   // subprocesses.
0643   vector<double> XMAXUP;
0644 
0645   // The subprocess code for the different subprocesses.
0646   vector<int> LPRUP;
0647 
0648   // Contents of the LHAinitrwgt tag
0649   LHAinitrwgt initrwgt;
0650 
0651   // Contents of the LHAgenerator tags.
0652   vector<LHAgenerator> generators;
0653 
0654   // A map of the LHAweightgroup tags, indexed by name.
0655   map<string,LHAweightgroup> weightgroups;
0656 
0657   // A map of the LHAweight tags, indexed by name.
0658   map<string,LHAweight> weights;
0659 
0660 };
0661 
0662 //==========================================================================
0663 
0664 // The HEPEUP class is a simple container corresponding to the Les Houches
0665 // accord (<A HREF="http://arxiv.org/abs/hep-ph/0109068">hep-ph/0109068</A>)
0666 // common block with the same name. The members are named in the same
0667 // way as in the common block. However, fortran arrays are represented
0668 // by vectors, except for the arrays of length two which are
0669 // represented by pair objects.
0670 
0671 class HEPEUP {
0672 
0673 public:
0674 
0675   // Default constructor.
0676   HEPEUP()
0677     : NUP(0), IDPRUP(0), XWGTUP(0.0), XPDWUP(0.0, 0.0),
0678       SCALUP(0.0), AQEDUP(0.0), AQCDUP(0.0), heprup(0) {}
0679 
0680   // Copy constructor
0681   HEPEUP(const HEPEUP & x) { operator=(x); }
0682 
0683   // Copy information from the given HEPEUP.
0684   HEPEUP & setEvent(const HEPEUP & x);
0685 
0686   // Assignment operator.
0687   HEPEUP & operator=(const HEPEUP & x) {
0688     clear();
0689     setEvent(x);
0690     return *this;
0691   }
0692 
0693   // Destructor.
0694   ~HEPEUP() {
0695     clear();
0696   };
0697 
0698   // Reset the HEPEUP object.
0699   void reset();
0700 
0701   // Clear the HEPEUP object.
0702   void clear() {
0703     reset();
0704   }
0705 
0706   // Set the NUP variable, corresponding to the number of particles in
0707   // the current event, to \a nup, and resize all relevant vectors
0708   // accordingly.
0709   void resize(int nup) {
0710     NUP = nup;
0711     resize();
0712   }
0713 
0714   // Return the main weight for this event.
0715   double weight() const {
0716       return XWGTUP;
0717   }
0718 
0719   // Assuming the NUP variable, corresponding to the number of
0720   // particles in the current event, is correctly set, resize the
0721   // relevant vectors accordingly.
0722   void resize();
0723 
0724   // The number of particle entries in the current event.
0725   int NUP;
0726 
0727   // The subprocess code for this event (as given in LPRUP).
0728   int IDPRUP;
0729 
0730   // The weight for this event.
0731   double XWGTUP;
0732 
0733   // The PDF weights for the two incoming partons. Note that this
0734   // variable is not present in the current LesHouches accord
0735   // (<A HREF="http://arxiv.org/abs/hep-ph/0109068">hep-ph/0109068</A>),
0736   // hopefully it will be present in a future accord.
0737   pair<double,double> XPDWUP;
0738 
0739   // The scale in GeV used in the calculation of the PDF's in this
0740   // event.
0741   double SCALUP;
0742 
0743   // The value of the QED coupling used in this event.
0744   double AQEDUP;
0745 
0746   // The value of the QCD coupling used in this event.
0747   double AQCDUP;
0748 
0749   // The PDG id's for the particle entries in this event.
0750   vector<long> IDUP;
0751 
0752   // The status codes for the particle entries in this event.
0753   vector<int> ISTUP;
0754 
0755   // Indices for the first and last mother for the particle entries in
0756   // this event.
0757   vector< pair<int,int> > MOTHUP;
0758 
0759   // The colour-line indices (first(second) is (anti)colour) for the
0760   // particle entries in this event.
0761   vector< pair<int,int> > ICOLUP;
0762 
0763   // Lab frame momentum (Px, Py, Pz, E and M in GeV) for the particle
0764   // entries in this event.
0765   vector< vector<double> > PUP;
0766 
0767   // Invariant lifetime (c*tau, distance from production to decay in
0768   // mm) for the particle entries in this event.
0769   vector<double> VTIMUP;
0770 
0771   // Spin info for the particle entries in this event given as the
0772   // cosine of the angle between the spin vector of a particle and the
0773   // 3-momentum of the decaying particle, specified in the lab frame.
0774   vector<double> SPINUP;
0775 
0776   // A pointer to the current HEPRUP object.
0777   HEPRUP * heprup;
0778 
0779   // The weights associated with this event, as given by the LHAwgt tags.
0780   map<string,double> weights_detailed;
0781 
0782   // The weights associated with this event, as given by the LHAweights tags.
0783   vector<double> weights_compressed;
0784 
0785   // Contents of the LHAscales tag
0786   LHAscales scalesSave;
0787 
0788   // Contents of the LHAweights tag (compressed format)
0789   LHAweights weightsSave;
0790 
0791   // Contents of the LHArwgt tag (detailed format)
0792   LHArwgt rwgtSave;
0793 
0794   // Any other attributes.
0795   map<string,string> attributes;
0796 
0797 };
0798 
0799 //==========================================================================
0800 
0801 // The Reader class is initialized with a stream from which to read a
0802 // version 1/3 Les Houches Accord event file. In the constructor of
0803 // the Reader object the optional header information is read and then
0804 // the mandatory init is read. After this the whole header block
0805 // including the enclosing lines with tags are available in the public
0806 // headerBlock member variable. Also the information from the init
0807 // block is available in the heprup member variable and any additional
0808 // comment lines are available in initComments. After each successful
0809 // call to the readEvent() function the standard Les Houches Accord
0810 // information about the event is available in the hepeup member
0811 // variable and any additional comments in the eventComments
0812 // variable. A typical reading sequence would look as follows:
0813 
0814 class Reader {
0815 
0816 public:
0817 
0818   // Initialize the Reader with a filename from which to read an event
0819   // file. After the constructor is called the whole header block
0820   // including the enclosing lines with tags are available in the
0821   // public headerBlock member variable. Also the information from the
0822   // init block is available in the heprup member variable and any
0823   // additional comment lines are available in initComments.
0824   //
0825   // filename: the name of the file to read from.
0826   //
0827   Reader(string filenameIn)
0828     : filename(filenameIn), intstream(nullptr), file(nullptr), version() {
0829     intstream = new igzstream(filename.c_str());
0830     file = intstream;
0831     isGood = init();
0832   }
0833 
0834   Reader(istream* is)
0835     : filename(""), intstream(nullptr), file(is), version() {
0836     isGood = init();
0837   }
0838 
0839   // Clean up
0840   ~Reader() {
0841     if (intstream) delete intstream;
0842   }
0843 
0844 
0845 
0846   // (Re)initialize the Reader with a filename from which to read an event
0847   // file. After this, all information from the header and init block is
0848   // available.
0849   //
0850   // filename: File name (not used as the input file stream is given)
0851   // isIn    : Name of the input file stream.
0852   bool setup(string filenameIn) {
0853     filename = filenameIn;
0854     if (intstream) delete intstream;
0855     intstream = new igzstream(filename.c_str());
0856     file = intstream;
0857     isGood = init();
0858     return isGood;
0859   }
0860 
0861 private:
0862 
0863   // Used internally in the constructors to read header and init blocks.
0864   bool init();
0865 
0866 public:
0867 
0868   // Read an event from the file and store it in the hepeup
0869   // object. Optional comment lines are stored in the eventComments
0870   // member variable.
0871   bool readEvent(HEPEUP * peup = 0);
0872 
0873   // Reset values of all event-related members to their defaults.
0874   void clearEvent() {
0875    currentLine = "";
0876    hepeup.clear();
0877    eventComments = "";
0878    weights_detailed_vec.resize(0);
0879    weightnames_detailed_vec.resize(0);
0880   }
0881 
0882 protected:
0883 
0884   // Used internally to read a single line from the stream.
0885   bool getLine() {
0886     currentLine = "";
0887     if(!getline(*file, currentLine)) return false;
0888     // Replace single by double quotes
0889     replace(currentLine.begin(),currentLine.end(),'\'','\"');
0890     return true;
0891   }
0892 
0893 protected:
0894 
0895   // Name of file-to-be-read.
0896   string filename;
0897 
0898   // A local stream which is unused if a stream is supplied from the
0899   // outside.
0900   igzstream* intstream;
0901 
0902   // The stream we are reading from. This may be a pointer to an
0903   // external stream or the internal intstream.
0904   istream * file;
0905 
0906   // The last line read in from the stream in getline().
0907   string currentLine;
0908 
0909 public:
0910 
0911   // Save if the initialisation worked.
0912   bool isGood;
0913 
0914   // XML file version
0915   int version;
0916 
0917   // All lines (since the last readEvent()) outside the header, init
0918   // and event tags.
0919   string outsideBlock;
0920 
0921   // All lines from the header block.
0922   string headerBlock;
0923   string headerComments;
0924 
0925   // The standard init information.
0926   HEPRUP heprup;
0927 
0928   // Additional comments found in the init block.
0929   string initComments;
0930 
0931   // The standard information about the last read event.
0932   HEPEUP hepeup;
0933 
0934   // Additional comments found with the last read event.
0935   string eventComments;
0936 
0937   // The detailed weights associated with this event, linearized to a vector.
0938   vector<double> weights_detailed_vec;
0939   vector<double> weights_detailed_vector()
0940     { return weights_detailed_vec; }
0941   vector<string> weightnames_detailed_vec;
0942   vector<string> weightnames_detailed_vector()
0943     { return weightnames_detailed_vec; }
0944 
0945 private:
0946 
0947   // The default constructor should never be used.
0948   Reader();
0949 
0950   // The copy constructor should never be used.
0951   Reader(const Reader &);
0952 
0953   // The Reader cannot be assigned to.
0954   Reader & operator=(const Reader &);
0955 
0956 };
0957 
0958 //==========================================================================
0959 
0960 // The Writer class is initialized with a stream to which to write a
0961 // version 1.0 or 3.0 Les Houches Accord event file. In the init() function of
0962 // the Writer object the main XML tag, header and init blocks are written,
0963 // with the corresponding end tag is written by list_end_tag().
0964 // After a Writer object (in the following called "writer") has been created,
0965 // it is possible to assign version (3 by default) information by
0966 //
0967 //   writer.version = <value>;
0968 //
0969 // The header block (called "someHeaderString" below) is assigned by
0970 //
0971 //   writer.headerBlock() << someHeaderString;
0972 //
0973 // and the init block comments (called "someInitString" below) are assigned via
0974 //
0975 //   writer.initComments() << someInitString;
0976 //
0977 // The standard init information (including amendments for LHEF 3.0) can
0978 // be assigned by the heprup member variable:
0979 //
0980 //   writer.heprup = heprup;
0981 //
0982 // where heprup is an object of type HEPRUP. All of the above information
0983 // will be writen by calling the init() function.
0984 //
0985 // Before each event is written out with the writeEvent() function,
0986 // the standard event information can be assigned to the hepeup
0987 // variable by
0988 //
0989 //   writer.hepeup = hepeup;
0990 //
0991 // where hepeup is of type HEPEUP. Event comments (called
0992 // "someCommentString" below) can be assigned through
0993 //
0994 //   writer.eventComments() << someCommentString;
0995 //
0996 // All of this event information is written by the writeEvent() function.
0997 
0998 class Writer {
0999 
1000 public:
1001 
1002   // Create a Writer object giving a stream to write to.
1003   // @param os the stream where the event file is written.
1004   Writer(ostream & os)
1005     : file(os), version(3) {}
1006 
1007   // Create a Writer object giving a filename to write to.
1008   // @param filename the name of the event file to be written.
1009   Writer(string filename)
1010     : intstream(filename.c_str()), file(intstream), version(3) {}
1011 
1012   // The destructor.
1013   ~Writer() {}
1014 
1015   // Add header lines consisting of XML code with this stream.
1016   ostream & headerBlock() {
1017     return headerStream;
1018   }
1019 
1020   // Add comment lines to the init block with this stream.
1021   ostream & initComments() {
1022     return initStream;
1023   }
1024 
1025   // Add comment lines to the next event to be written out with this stream.
1026   ostream & eventComments() {
1027     return eventStream;
1028   }
1029 
1030   // Write out the final XML end-tag.
1031   void list_end_tag() {
1032     file << "</LesHouchesEvents>" << endl;
1033   }
1034 
1035   // Write out an optional header block followed by the standard init
1036   // block information together with any comment lines.
1037   void init();
1038 
1039   // Write out the event stored in hepeup, followed by optional
1040   // comment lines.
1041   bool writeEvent(HEPEUP * peup = 0, int pDigits = 15);
1042   // Write out an event as a string.
1043   string getEventString(HEPEUP * peup = 0);
1044 
1045 protected:
1046 
1047   // Make sure that each line in the string \a s starts with a
1048   // #-character and that the string ends with a new-line.
1049   string hashline(string s, bool comment = false);
1050 
1051 protected:
1052 
1053   // A local stream which is unused if a stream is supplied from the
1054   // outside.
1055   ofstream intstream;
1056 
1057   // The stream we are writing to. This may be a reference to an
1058   // external stream or the internal intstream.
1059   ostream & file;
1060 
1061 public:
1062 
1063   // Stream to add all lines in the header block.
1064   ostringstream headerStream;
1065 
1066   // The standard init information.
1067   HEPRUP heprup;
1068 
1069   // Stream to add additional comments to be put in the init block.
1070   ostringstream initStream;
1071 
1072   // The standard information about the event we will write next.
1073   HEPEUP hepeup;
1074 
1075   // Stream to add additional comments to be written together the next event.
1076   ostringstream eventStream;
1077 
1078   // XML file version
1079   int version;
1080 
1081 private:
1082 
1083   // The default constructor should never be used.
1084   Writer();
1085 
1086   // The copy constructor should never be used.
1087   Writer(const Writer &);
1088 
1089   // The Writer cannot be assigned to.
1090   Writer & operator=(const Writer &);
1091 
1092 };
1093 
1094 //==========================================================================
1095 
1096 } // end namespace Pythia8
1097 
1098 #endif // end Pythia8_LHEF3_H