27#define M_PI 3.14159265358979323846264338327950288 
   77  os << 
" " << oa.
name << 
"=\"" << oa.
val << 
"\"";
 
 
   92  typedef std::string::size_type 
pos_t;
 
  113    for ( 
int i = 0, N = 
tags.size(); i < N; ++i ) 
delete tags[i];
 
 
  140  bool getattr(std::string n, 
double & v)
 const {
 
  141    AttributeMap::const_iterator it = 
attr.find(n);
 
  142    if ( it == 
attr.end() ) 
return false;
 
  143    v = std::atof(it->second.c_str());
 
 
  153    AttributeMap::const_iterator it = 
attr.find(n);
 
  154    if ( it == 
attr.end() ) 
return false;
 
  155    if ( it->second == 
"yes" ) v = 
true;
 
 
  164    AttributeMap::const_iterator it = 
attr.find(n);
 
  165    if ( it == 
attr.end() ) 
return false;
 
  166    v = std::atoi(it->second.c_str());
 
 
  175    AttributeMap::const_iterator it = 
attr.find(n);
 
  176    if ( it == 
attr.end() ) 
return false;
 
  177    v = int(std::atoi(it->second.c_str()));
 
 
  185  bool getattr(std::string n, std::string & v)
 const {
 
  186    AttributeMap::const_iterator it = 
attr.find(n);
 
  187    if ( it == 
attr.end() ) 
return false;
 
 
  199                      std::string * leftover = 0) {
 
  200    std::vector<XMLTag*> 
tags;
 
  203    while ( curr != 
end ) {
 
  206      pos_t begin = str.find(
"<", curr);
 
  209      if ( begin != 
end && str.find(
"<!--", curr) == begin ) {
 
  210    pos_t endcom = str.find(
"-->", begin);
 
  212    if ( endcom == 
end ) {
 
  213      tags.back()->contents = str.substr(curr);
 
  214      if ( leftover ) *leftover += str.substr(curr);
 
  217    tags.back()->contents = str.substr(curr, endcom - curr);
 
  218    if ( leftover ) *leftover += str.substr(curr, endcom - curr);
 
  223      if ( begin != curr ) {
 
  225    tags.back()->contents = str.substr(curr, begin - curr);
 
  226    if ( leftover ) *leftover += str.substr(curr, begin - curr);
 
  228      if ( begin == 
end || begin > str.length() - 3 || str[begin + 1] == 
'/' )
 
  231      pos_t close = str.find(
">", curr);
 
  232      if ( close == 
end ) 
return tags;
 
  235      curr = str.find_first_of(
" \t\n/>", begin);
 
  237      tags.back()->name = str.substr(begin + 1, curr - begin - 1);
 
  242    curr = str.find_first_not_of(
" \t\n", curr);
 
  243    if ( curr == 
end || curr >= close ) 
break;
 
  245    pos_t tend = str.find_first_of(
"= \t\n", curr);
 
  246    if ( tend == 
end || tend >= close ) 
break;
 
  248    std::string namex = str.substr(curr, tend - curr);
 
  249    curr = str.find(
"=", curr) + 1;
 
  252    curr = str.find_first_of(
"\"'", curr);
 
  253    if ( curr == 
end || curr >= close ) 
break;
 
  254    char quote = str[curr];
 
  256    curr = str.find(quote, curr);
 
  257    while ( curr != 
end && str[curr - 1] == 
'\\' )
 
  258      curr = str.find(quote, curr + 1);
 
  260    std::string value = str.substr(bega, curr == 
end? 
end: curr - bega);
 
  262    tags.back()->attr[namex] = value;
 
  269      if ( str[close - 1] == 
'/' ) 
continue;
 
  271      pos_t endtag = str.find(
"</" + 
tags.back()->name + 
">", curr);
 
  272      if ( endtag == 
end ) {
 
  273    tags.back()->contents = str.substr(curr);
 
  276    tags.back()->contents = str.substr(curr, endtag - curr);
 
  277    curr = endtag + 
tags.back()->name.length() + 3;
 
  280      std::string leftovers;
 
  282      if ( leftovers.find_first_not_of(
" \t\n") == 
end ) leftovers=
"";
 
  283      tags.back()->contents = leftovers;
 
 
  294    while ( 
tags.size() && 
tags.back() ) {
 
 
  302  void print(std::ostream & os)
 const {
 
  303    if ( 
name.empty() ) {
 
  308    for ( AttributeMap::const_iterator it = 
attr.begin();
 
  309      it != 
attr.end(); ++it )
 
  310      os << 
oattr(it->first, it->second);
 
  312      os << 
"/>" << std::endl;
 
  316    for ( 
int i = 0, N = 
tags.size(); i < N; ++i )
 
 
 
  330  std::istringstream is(s);
 
  332  while ( getline(is, ss) ) {
 
  333    if ( ss.empty() ) 
continue;
 
  334    if ( ss.find_first_not_of(
" \t") == std::string::npos ) 
continue;
 
  335    if ( ss.find(
'#') == std::string::npos ||
 
  336     ss.find(
'#') != ss.find_first_not_of(
" \t") ) ss = 
"# " + ss;
 
 
  368  bool getattr(std::string n, 
double & v, 
bool erase = 
true) {
 
  369    AttributeMap::iterator it = 
attributes.find(n);
 
  371    v = std::atof(it->second.c_str());
 
 
  382  bool getattr(std::string n, 
bool & v, 
bool erase = 
true) {
 
  383    AttributeMap::iterator it = 
attributes.find(n);
 
  385    if ( it->second == 
"yes" ) v = 
true;
 
 
  396  bool getattr(std::string n, 
long & v, 
bool erase = 
true) {
 
  397    AttributeMap::iterator it = 
attributes.find(n);
 
  399    v = std::atoi(it->second.c_str());
 
 
  410  bool getattr(std::string n, 
int & v, 
bool erase = 
true) {
 
  411    AttributeMap::iterator it = 
attributes.find(n);
 
  413    v = int(std::atoi(it->second.c_str()));
 
 
  424  bool getattr(std::string n, std::string & v, 
bool erase = 
true) {
 
  425    AttributeMap::iterator it = 
attributes.find(n);
 
 
  436    for ( AttributeMap::const_iterator it = 
attributes.begin();
 
  438      file << 
oattr(it->first, it->second);
 
 
  445  void closetag(std::ostream & file, std::string tag)
 const {
 
  448    else if ( 
contents.find(
'\n') != std::string::npos )
 
  449      file << 
">\n" << 
contents << 
"\n</" << tag << 
">\n";
 
  451      file << 
">" << 
contents << 
"</" << tag << 
">\n";
 
 
  467  static std::string 
yes() { 
return "yes"; }
 
 
  488  void print(std::ostream & file)
 const {
 
  489    file << 
"<generator";
 
 
 
  527      throw std::runtime_error(
"Found xsecinfo tag without neve attribute " 
  528                   "in Les Houches Event File.");
 
  532      throw std::runtime_error(
"Found xsecinfo tag without totxsec " 
  533                   "attribute in Les Houches Event File.");
 
 
  546  void print(std::ostream & file)
 const {
 
  547    file << 
"<xsecinfo" << 
oattr(
"neve", 
neve)
 
 
 
  630      throw std::runtime_error(
"Found eventfile tag without name attribute " 
  631                   "in Les Houches Event File.");
 
 
  640  void print(std::ostream & file)
 const {
 
 
 
  675     max(0.99*std::numeric_limits<double>::
max()) {}
 
 
  681      const std::map<std::string,std::set<long> >& ptypes)
 
  683      min(-0.99*std::numeric_limits<double>::
max()),
 
  684      max(0.99*std::numeric_limits<double>::
max()) {
 
  686      throw std::runtime_error(
"Found cut tag without type attribute " 
  687                   "in Les Houches file");
 
  690      if ( ptypes.find(np1) != ptypes.end() ) {
 
  691    p1 =  ptypes.find(np1)->second;
 
  692    attributes.erase(
"p1");
 
  699    if ( tag.getattr(
"p2", 
np2) ) {
 
  700      if ( ptypes.find(np2) != ptypes.end() ) {
 
  701    p2 =  ptypes.find(np2)->second;
 
  702    attributes.erase(
"p2");
 
  710    std::istringstream iss(tag.contents);
 
  714    min = -0.99*std::numeric_limits<double>::max();
 
  716      max = 0.99*std::numeric_limits<double>::max();
 
 
  722  void print(std::ostream & file)
 const {
 
  727      if ( 
p1.size() == 1 ) file << 
oattr(
"p1", *
p1.begin());
 
  731      if ( 
p2.size() == 1 ) file << 
oattr(
"p2", *
p2.begin());
 
  735    if ( 
min > -0.9*std::numeric_limits<double>::max() )
 
  739    if ( 
max < 0.9*std::numeric_limits<double>::max() )
 
  742    file << 
"</cut>" << std::endl;
 
 
  749  bool match(
long id1, 
long id2 = 0)
 const {
 
  750    std::pair<bool,bool> ret(
false, 
false);
 
  751    if ( !id2 ) ret.second = 
true;
 
  752    if ( !id1 ) ret.first = 
true;
 
  753    if ( 
p1.find(0) != 
p1.end() ) ret.first = 
true;
 
  754    if ( 
p1.find(id1) != 
p1.end() ) ret.first = 
true;
 
  755    if ( 
p2.find(0) != 
p2.end() ) ret.second = 
true;
 
  756    if ( 
p2.find(id2) != 
p2.end() ) ret.second = 
true;
 
  757    return ret.first && ret.second;
 
 
  766        const std::vector< std::vector<double> >& p )
 const {
 
  767    if ( ( 
type == 
"m" && !
p2.size() ) || 
type == 
"kt" || 
type == 
"eta" ||
 
  769      for ( 
int i = 0, N = 
id.size(); i < N; ++i )
 
  770    if ( 
match(
id[i]) ) {
 
  772        double v = p[i][4]*p[i][4] - p[i][3]*p[i][3] - p[i][2]*p[i][2]
 
  774        v = v >= 0.0? std::sqrt(v): -std::sqrt(-v);
 
  775        if ( 
outside(v) ) 
return false;
 
  777      else if ( 
type == 
"kt" ) {
 
  778        if ( 
outside(std::sqrt(p[i][2]*p[i][2] + p[i][1]*p[i][1])) )
 
  781      else if ( 
type == 
"E" ) {
 
  782        if ( 
outside(p[i][4]) ) 
return false;
 
  784      else if ( 
type == 
"eta" ) {
 
  787      else if ( 
type == 
"y" ) {
 
  792    else if ( 
type == 
"m"  || 
type == 
"deltaR" ) {
 
  793      for ( 
int i = 1, N = 
id.size(); i < N; ++i )
 
  794    for ( 
int j = 0; j < i; ++j )
 
  795      if ( 
match(
id[i], 
id[j]) || 
match(
id[j], 
id[i]) ) {
 
  797          double v = (p[i][4] + p[j][4])*(p[i][4] + p[j][4])
 
  798        - (p[i][3] + p[j][3])*(p[i][3] + p[j][3])
 
  799        - (p[i][2] + p[j][2])*(p[i][2] + p[j][2])
 
  800        - (p[i][1] + p[j][1])*(p[i][1] + p[j][1]);
 
  801          v = v >= 0.0? std::sqrt(v): -std::sqrt(-v);
 
  802          if ( 
outside(v) ) 
return false;
 
  804        else if ( 
type == 
"deltaR" ) {
 
  809    else if ( 
type == 
"ETmiss" ) {
 
  812      for ( 
int i = 0, N = 
id.size(); i < N; ++i )
 
  817      if ( 
outside(std::sqrt(x*x + y*y)) ) 
return false;
 
  819    else if ( 
type == 
"HT" ) {
 
  821      for ( 
int i = 0, N = 
id.size(); i < N; ++i )
 
  823          pt += std::sqrt(p[i][1]*p[i][1] + p[i][2]*p[i][2]);
 
  824      if ( 
outside(pt) ) 
return false;
 
 
  832  static double eta(
const std::vector<double> & p) {
 
  833    double pt2 = p[2]*p[2] + p[1]*p[1];
 
  835      double dum = std::sqrt(pt2 + p[3]*p[3]) + p[3];
 
  837    return std::log(dum/std::sqrt(pt2));
 
  839    return p[3] < 0.0? -std::numeric_limits<double>::max():
 
  840      std::numeric_limits<double>::max();
 
 
  846  static double rap(
const std::vector<double> & p) {
 
  847    double pt2 = p[5]*p[5] + p[2]*p[2] + p[1]*p[1];
 
  849      double dum = std::sqrt(pt2 + p[3]*p[3]) + p[3];
 
  851    return std::log(dum/std::sqrt(pt2));
 
  853    return p[3] < 0.0? -std::numeric_limits<double>::max():
 
  854      std::numeric_limits<double>::max();
 
 
  860  static double deltaR(
const std::vector<double> & 
p1,
 
  861               const std::vector<double> & 
p2) {
 
  863    double dphi = std::atan2(
p1[1], 
p1[2]) - std::atan2(
p2[1], 
p2[2]);
 
  864    if ( dphi > 
M_PI ) dphi -= 2.0*
M_PI;
 
  865    if ( dphi < -
M_PI ) dphi += 2.0*
M_PI;
 
  866    return std::sqrt(dphi*dphi + deta*deta);
 
 
  873    return value < min || value >= 
max;
 
 
 
  940  void print(std::ostream & file)
 const {
 
 
 
 1014    file << 
"<mergeinfo" << 
oattr(
"iproc", 
iproc);
 
 
 
 1075      file << 
"<weightinfo" << 
oattr(
"name", 
name);
 
 
 
 1143    for ( 
int i = 0, N = tag.
tags.size(); i < N; ++i ) {
 
 1144      if ( tag.
tags[i]->name == 
"weight" ||
 
 1145       tag.
tags[i]->name == 
"weightinfo" ) {
 
 
 
 1188    std::istringstream iss(tag.
contents);
 
 1190    while ( iss >> w ) 
weights.push_back(w);
 
 
 1207    for ( 
int j = 0, M = 
weights.size(); j < M; ++j ) file << 
" " << 
weights[j];
 
 1209      file << 
"</wgt>" << std::endl;
 
 1211      file << 
"</weight>" << std::endl;
 
 
 
 1264    std::istringstream iss(tag.
contents);
 
 1266    if ( !( iss >> 
p0 ) ) 
p0 = 
p1;
 
 
 1276    file << 
">" << 
p1 << 
" " << 
p2;
 
 1277    if ( 
p1 != 
p0 ) file << 
" " << 
p0;
 
 1278    file << 
"</clus>" << std::endl;
 
 
 
 1318  Scale(std::string st = 
"veto", 
int emtr = 0, 
double sc = 0.0)
 
 
 1327      throw std::runtime_error(
"Found scale tag without stype attribute " 
 1328                   "in Les Houches Event File.");
 
 1330    if ( 
getattr(
"pos", pattr) ) {
 
 1331      std::istringstream pis(pattr);
 
 1335        while ( pis >> rec ) 
recoilers.insert(rec);
 
 1340    if ( 
getattr(
"etype", eattr) ) {
 
 1341      if ( eattr == 
"QCD" ) eattr = 
"-5 -4  -3 -2 -1 1 2 3 4 5 21";
 
 1342      if ( eattr == 
"EW" ) eattr = 
"-13 -12 -11 11 12 13 22 23 24";
 
 1343      std::istringstream eis(eattr);
 
 1345      while ( eis >> pdg ) 
emitted.insert(pdg);
 
 1347    std::istringstream cis(tag.
contents);
 
 
 1358      std::ostringstream pos;
 
 1360      for ( std::set<int>::iterator it = 
recoilers.begin();
 
 1363      file << 
oattr(
"pos", pos.str());
 
 1366      std::set<int>::iterator it = 
emitted.begin();
 
 1367      std::ostringstream eos;
 
 1369      while ( ++it != 
emitted.end() ) eos << 
" " << *it;
 
 1370      if ( eos.str() == 
"-5 -4  -3 -2 -1 1 2 3 4 5 21" )
 
 1371        file << 
oattr(
"etype", std::string(
"QCD"));
 
 1372      else if ( eos.str() == 
"-13 -12 -11 11 12 13 22 23 24" )
 
 1373        file << 
oattr(
"etype", std::string(
"EW"));
 
 1375        file << 
oattr(
"etype", eos.str());
 
 1377    std::ostringstream os;
 
 
 
 1421  Scales(
double defscale = -1.0, 
int npart = 0)
 
 
 1431      muf(defscale), 
mur(defscale), 
mups(defscale),
 
 1436    for ( 
int i = 0, N = tag.
tags.size(); i < N; ++i )
 
 1437      if ( tag.
tags[i]->name == 
"scale" )
 
 1439    for ( 
int i = 0; i < npart; ++i ) {
 
 1440      std::ostringstream pttag;
 
 1441      pttag << 
"pt_start_" << i + 1;
 
 1443      if ( 
getattr(pttag.str(), sc) )
 
 
 1469      std::ostringstream os;
 
 1470      for ( 
int i = 0, N = 
scales.size(); i < N; ++i )
 
 
 1489  double getScale(std::string st, 
int pdgem, 
int emr, 
int rec)
 const {
 
 1490    for ( 
int i = 0, N = 
scales.size(); i < N; ++i ) {
 
 1491      if ( 
scales[i].emitter == emr && st == 
scales[i].stype &&
 
 1493             scales[i].recoilers.find(rec) != 
scales[i].recoilers.end() ) &&
 
 1494           scales[i].emitted.find(pdgem) != 
scales[i].emitted.end()  )
 
 1497    for ( 
int i = 0, N = 
scales.size(); i < N; ++i ) {
 
 1498      if ( 
scales[i].emitter == emr && st == 
scales[i].stype &&
 
 1500             scales[i].recoilers.find(rec) != 
scales[i].recoilers.end() ) &&
 
 1501           scales[i].emitted.empty() )
 
 1504    if ( emr != rec ) 
return getScale(st, pdgem, emr, emr);
 
 1505    if ( emr == rec ) 
return getScale(st, pdgem, 0, 0);
 
 
 
 1566    if ( 
xf1 <= 0 ) 
return;
 
 1574    file << 
">" << 
xf1 << 
" " << 
xf2 << 
"</pdfinfo>" << std::endl;
 
 
 
 1638      dprec(std::numeric_limits<double>::digits10) {}
 
 
 1655      dprec(std::numeric_limits<double>::digits10) {
 
 1657    std::vector<XMLTag*> tags = tagin.
tags;
 
 1660    std::istringstream iss(tags[0]->
contents);
 
 1664      throw std::runtime_error(
"Could not parse init block " 
 1665                   "in Les Houches Event File.");
 
 1669    for ( 
int i = 0; i < 
NPRUP; ++i ) {
 
 1671      throw std::runtime_error(
"Could not parse processes in init block " 
 1672                   "in Les Houches Event File.");
 
 1676    for ( 
int i = 1, N = tags.size(); i < N; ++i ) {
 
 1677      const XMLTag & tag = *tags[i];
 
 1681      if ( tag.
name == 
"initrwgt" ) {
 
 1682    for ( 
int j = 0, M = tag.
tags.size(); j < M; ++j ) {
 
 1683      if ( tag.
tags[j]->name == 
"weightgroup" )
 
 1686      if ( tag.
tags[j]->name == 
"weight" )
 
 1691      if ( tag.
name == 
"weightinfo" ) {
 
 1694      if ( tag.
name == 
"weightgroup" ) {
 
 1698      if ( tag.
name == 
"eventfiles" ) {
 
 1699    for ( 
int j = 0, M = tag.
tags.size(); j < M; ++j ) {
 
 1701          if ( eftag.
name == 
"eventfile" )
 
 1705      if ( tag.
name == 
"xsecinfo" ) {
 
 1709      if ( tag.
name == 
"generator" ) {
 
 1712      else if ( tag.
name == 
"cutsinfo" ) {
 
 1713    for ( 
int j = 0, M = tag.
tags.size(); j < M; ++j ) {
 
 1716      if ( ctag.
name == 
"ptype" ) {
 
 1717        std::string tname = ctag.
attr[
"name"];
 
 1719        std::istringstream isss(ctag.
contents);
 
 1720        while ( isss >> 
id ) 
ptypes[tname].insert(
id);
 
 1722      else if ( ctag.
name == 
"cut" )
 
 1726      else if ( tag.
name == 
"procinfo" ) {
 
 1730      else if ( tag.
name == 
"mergeinfo" ) {
 
 1738    for ( 
int i = 0, N = 
weightinfo.size(); i < N; ++i )
 
 
 1753    if ( i < 0 || i >= (
int)
weightinfo.size() ) 
return name;
 
 
 1767    file << std::setprecision(
dprec);
 
 1770     << 
" " << std::setw(8) << 
IDBMUP.first
 
 1771     << 
" " << std::setw(8) << 
IDBMUP.second
 
 1772     << 
" " << std::setw(14) << 
EBMUP.first
 
 1773     << 
" " << std::setw(14) << 
EBMUP.second
 
 1774     << 
" " << std::setw(4) << 
PDFGUP.first
 
 1775     << 
" " << std::setw(4) << 
PDFGUP.second
 
 1776     << 
" " << std::setw(4) << 
PDFSUP.first
 
 1777     << 
" " << std::setw(4) << 
PDFSUP.second
 
 1778     << 
" " << std::setw(4) << 
IDWTUP 
 1779     << 
" " << std::setw(4) << 
NPRUP << std::endl;
 
 1781    for ( 
int i = 0; i < 
NPRUP; ++i )
 
 1782      file << 
" " << std::setw(14) << 
XSECUP[i]
 
 1783       << 
" " << std::setw(14) << 
XERRUP[i]
 
 1784       << 
" " << std::setw(14) << 
XMAXUP[i]
 
 1785       << 
" " << std::setw(6) << 
LPRUP[i] << std::endl;
 
 1787    for ( 
int i = 0, N = 
generators.size(); i < N; ++i )
 
 1791      file << 
"<eventfiles>\n";
 
 1792      for ( 
int i = 0, N = 
eventfiles.size(); i < N; ++i )
 
 1794      file << 
"</eventfiles>\n";
 
 1798      for ( XSecInfos::const_iterator it = 
xsecinfos.begin();
 
 1800        if ( it->second.neve > 0 ) it->second.print(file);
 
 1802    if ( 
cuts.size() > 0 ) {
 
 1803      file << 
"<cutsinfo>" << std::endl;
 
 1805      for ( std::map<std::string, std::set<long> >::const_iterator ptit =
 
 1807    file << 
"<ptype" << 
oattr(
"name", ptit->first) << 
">";
 
 1808    for ( std::set<long>::const_iterator it = ptit->second.begin();
 
 1809          it != ptit->second.end(); ++it )
 
 1811    file << 
"</ptype>" << std::endl;
 
 1814      for ( 
int i = 0, N = 
cuts.size(); i < N; ++i )
 
 1815    cuts[i].print(file);
 
 1816      file << 
"</cutsinfo>" << std::endl;
 
 1819    for ( std::map<long,ProcInfo>::const_iterator it = 
procinfo.begin();
 
 1821      it->second.print(file);
 
 1823    for ( std::map<long,MergeInfo>::const_iterator it = 
mergeinfo.begin();
 
 1825      it->second.print(file);
 
 1827    bool isrwgt = 
false;
 
 1829    for ( 
int i = 0, N = 
weightinfo.size(); i < N; ++i ) {
 
 1831    if ( !isrwgt ) file << 
"<initrwgt>\n";
 
 1834    if ( isrwgt ) file << 
"</initrwgt>\n";
 
 1838      if ( group != ingroup ) {
 
 1839    if ( ingroup != -1 ) file << 
"</weightgroup>\n";
 
 1840    if ( group != -1 ) {
 
 1841      file << 
"<weightgroup" 
 1851    if ( ingroup != -1 ) file << 
"</weightgroup>\n";
 
 1852    if ( isrwgt ) file << 
"</initrwgt>\n";
 
 
 1898    std::map<std::string, int>::const_iterator it = 
weightmap.find(name);
 
 1899    if ( it != 
weightmap.end() ) 
return it->second;
 
 
 1927    XSecInfos::const_iterator it = 
xsecinfos.find(weightname);
 
 1928    if ( it != 
xsecinfos.end() ) 
return it->second;
 
 
 2010  std::map<std::string, std::set<long> > 
ptypes;
 
 
 2089  inline void clear();
 
 
 2176    if ( &x == 
this ) 
return *
this;
 
 2177    TagBase::operator=(x);
 
 
 2205      throw std::runtime_error(
"Tried to read events but no processes defined " 
 2206                   "in init block of Les Houches file.");
 
 2208    std::vector<XMLTag*> tags = tagin.
tags;
 
 2213      for ( 
int i = 0, N = tags.size(); i < N; ++i )
 
 2214        if ( tags[i]->name == 
"event" )
 
 2223    std::istringstream iss(tags[0]->
contents);
 
 2225      throw std::runtime_error(
"Failed to parse event in Les Houches file.");
 
 2230    for ( 
int i = 0; i < 
NUP; ++i ) {
 
 2234              >> 
PUP[i][3] >> 
PUP[i][4]
 
 2236    throw std::runtime_error(
"Failed to parse event in Les Houches file.");
 
 2241    while ( getline(iss, ss) ) 
junk += ss + 
'\n';
 
 2250    for ( 
int i = 1, N = 
weights.size(); i < N; ++i )
 
 2253    for ( 
int i = 1, N = tags.size(); i < N; ++i ) {
 
 2258      if ( tag.
name == 
"weights" ) {
 
 2262    for ( 
int ii = 1, NN = 
weights.size(); ii < NN; ++ii )
 
 2266    std::istringstream isss(tag.
contents);
 
 2268      if ( ++iii < 
int(
weights.size()) )
 
 2273      if ( tag.
name == 
"weight" ) {
 
 2276      if ( tag.
name == 
"rwgt" ) {
 
 2277    for ( 
int j = 0, M = tag.
tags.size(); j < M; ++j ) {
 
 2278      if ( tag.
tags[j]->name == 
"wgt" ) {
 
 2283      else if ( tag.
name == 
"clustering" ) {
 
 2284    for ( 
int j = 0, M= tag.
tags.size(); j < M; ++j ) {
 
 2285      if ( tag.
tags[j]->name == 
"clus" )
 
 2289      else if ( tag.
name == 
"pdfinfo" ) {
 
 2292      else if ( tag.
name == 
"scales" ) {
 
 2298    for ( 
int i = 0, N = 
namedweights.size(); i < N; ++i ) {
 
 
 2322    file << std::setprecision(
heprup->dprec);
 
 2326      file << 
"<eventgroup";
 
 2333      for ( 
int i = 0, N = 
subevents.size(); i < N; ++i )
 
 2335      file << 
"</eventgroup>\n";
 
 2343    file << 
" " << std::setw(4) << 
NUP 
 2344     << 
" " << std::setw(6) << 
IDPRUP 
 2345     << 
" " << std::setw(14) << 
XWGTUP 
 2346     << 
" " << std::setw(14) << 
SCALUP 
 2347     << 
" " << std::setw(14) << 
AQEDUP 
 2348     << 
" " << std::setw(14) << 
AQCDUP << 
"\n";
 
 2350    for ( 
int i = 0; i < 
NUP; ++i )
 
 2351      file << 
" " << std::setw(8) << 
IDUP[i]
 
 2352       << 
" " << std::setw(2) << 
ISTUP[i]
 
 2353       << 
" " << std::setw(4) << 
MOTHUP[i].first
 
 2354       << 
" " << std::setw(4) << 
MOTHUP[i].second
 
 2355       << 
" " << std::setw(4) << 
ICOLUP[i].first
 
 2356       << 
" " << std::setw(4) << 
ICOLUP[i].second
 
 2357       << 
" " << std::setw(14) << 
PUP[i][0]
 
 2358       << 
" " << std::setw(14) << 
PUP[i][1]
 
 2359       << 
" " << std::setw(14) << 
PUP[i][2]
 
 2360       << 
" " << std::setw(14) << 
PUP[i][3]
 
 2361       << 
" " << std::setw(14) << 
PUP[i][4]
 
 2362       << 
" " << std::setw(1) << 
VTIMUP[i]
 
 2363       << 
" " << std::setw(1) << 
SPINUP[i] << std::endl;
 
 2366      file << 
"<weights>";
 
 2367      for ( 
int i = 1, N = 
weights.size(); i < N; ++i )
 
 2368        file << 
" " << 
weights[i].first;
 
 2369      file << 
"</weights>\n";
 
 2373    for ( 
int i = 0, N = 
namedweights.size(); i < N; ++i ) {
 
 2375        if ( !iswgt ) file << 
"<rwgt>\n";
 
 2378        if ( iswgt ) file << 
"</rwgt>\n";
 
 2381      for ( 
int j = 0, M = 
namedweights[i].indices.size(); j < M; ++j )
 
 2385    if ( iswgt ) file << 
"</rwgt>\n";
 
 2388      file << 
"<clustering>" << std::endl;
 
 2389      for ( 
int i = 0, N = 
clustering.size(); i < N; ++i )
 
 2391      file << 
"</clustering>" << std::endl;
 
 
 2436    for ( 
int ii = 0, N = 
subevents.size(); ii < N; ++ii )
 
 
 2473    int i = 
heprup->weightIndex(name);
 
 2474    if ( i >= 
int(
weights.size()) ) 
return false;
 
 
 2490    PUP.resize(
NUP, std::vector<double>(5));
 
 
 2500    if ( i >= 
weights.size() ) 
return false;
 
 
 2535      for ( 
int ii = 1, N = 
subevents.size(); ii < N; ++ii )
 
 2536        for ( 
int j = 0, M = 
weights.size(); j < M; ++j )
 
 
 2612  std::vector< std::vector<double> > 
PUP;
 
 2645  std::vector< std::pair<double, const WeightInfo *> > 
weights;
 
 
 2701  while ( size() > 0 ) {
 
 
 2713  for ( 
int i = 0, N = eg.size(); i < N; ++i ) at(i) = 
new HEPEUP(*eg.at(i));
 
 
 2717  if ( &x == 
this ) 
return *
this;
 
 2721  for ( 
int i = 0, N = x.size(); i < N; ++i ) push_back(
new HEPEUP(*x.at(i)));
 
 
 2776    size_t slash = filename.find_last_of(
'/');
 
 2777    if ( slash != std::string::npos ) 
dirpath = filename.substr(0, slash + 1);
 
 
 2792    bool readingHeader = 
false;
 
 2793    bool readingInit = 
false;
 
 2798      throw std::runtime_error
 
 2799    (
"Tried to read a file which does not start with the " 
 2800     "LesHouchesEvents tag.");
 
 2807      throw std::runtime_error
 
 2808    (
"Tried to read a LesHouchesEvents file which is above version 3.");
 
 2816    readingHeader = 
true;
 
 2827    readingHeader = 
false;
 
 2830      else if ( readingHeader ) {
 
 2835      else if ( readingInit ) {
 
 2845          throw std::runtime_error(
"Found incomplete init tag in " 
 2846                 "Les Houches file.");
 
 2849    for ( 
int i = 0, N = tags.size(); i < N; ++i )
 
 2850      if ( tags[i]->name == 
"init" ) {
 
 
 2872    if ( 
heprup.NPRUP < 0 ) 
return false;
 
 2874    std::string eventLines;
 
 2881    if ( inEvent == 1 && 
currentFind(
"</event>") ) 
break;
 
 2882    if ( inEvent == 2 && 
currentFind(
"</eventgroup>") ) 
break;
 
 2896    if ( ( inEvent == 1 && !
currentFind(
"</event>") ) ||
 
 2897         ( inEvent == 2 && !
currentFind(
"</eventgroup>") ) ) {
 
 2898      if ( 
heprup.eventfiles.empty() ||
 
 2906    for ( 
int i = 0, N = tags.size(); i < N ; ++i ) {
 
 2907      if ( tags[i]->name == 
"event" || tags[i]->name == 
"eventgroup" ) {
 
 2916    if ( !
heprup.eventfiles.empty() &&
 
 
 2934    std::cerr << 
"opening file " << ifile << std::endl;
 
 2936    std::string fname = 
heprup.eventfiles[ifile].filename;
 
 2937    if ( fname[0] != 
'/' ) fname = 
dirpath + fname;
 
 2938    efile.open(fname.c_str());
 
 2939    if ( !
efile ) 
throw std::runtime_error(
"Could not open event file " +
 
 
 2959    return currentLine.find(str) != std::string::npos;
 
 
 
 3118    size_t slash = filename.find_last_of(
'/');
 
 3119    if ( slash != std::string::npos ) 
dirpath = filename.substr(0, slash + 1);
 
 
 3127    if ( !
heprup.eventfiles.empty() ) {
 
 3134    *
file << 
"</LesHouchesEvents>" << std::endl;
 
 
 3191    if ( 
heprup.eventfiles.empty() ) 
return false;
 
 3192    if ( ifile < 0 || ifile >= 
int(
heprup.eventfiles.size()) ) 
return false;
 
 3196        std::cerr << 
"LHEF::Writer number of events in event file " 
 3197                  << ef.
filename << 
" does not match the given number." 
 3202    std::string fname = 
heprup.eventfiles[ifile].filename;
 
 3203    if ( fname[0] != 
'/' ) fname = 
dirpath + fname;
 
 3204    efile.open(fname.c_str());
 
 3205    if ( !
efile ) 
throw std::runtime_error(
"Could not open event file " +
 
 3207    std::cerr << 
"Opened event file " << fname << std::endl;
 
 
 3222    if ( 
heprup.version == 3 )
 
 3223      *
file << 
"<LesHouchesEvents version=\"3.0\">\n";
 
 3224    else if ( 
heprup.version == 2 )
 
 3225      *
file << 
"<LesHouchesEvents version=\"2.0\">\n";
 
 3227      *
file << 
"<LesHouchesEvents version=\"1.0\">\n";
 
 3230    *
file << std::setprecision(10);
 
 3233    if ( headBlock.length() ) {
 
 3234      if ( headBlock.find(
"<header>") == std::string::npos )
 
 3235    *
file << 
"<header>\n";
 
 3236      if ( headBlock[headBlock.length() - 1] != 
'\n' )
 
 3239      if ( headBlock.find(
"</header>") == std::string::npos )
 
 3240    *
file << 
"</header>\n";
 
 
 3252    if ( !
heprup.eventfiles.empty() ) {
 
 
 
 
#define M_PI
Definition of PI. Needed on some platforms.
std::vector< double > VTIMUP
double totalWeight(int i=0) const
double weight(std::string name) const
void print(std::ostream &file) const
std::pair< int, int > PDFGUPsave
HEPEUP & operator=(const HEPEUP &x)
std::vector< std::pair< int, int > > MOTHUP
HEPEUP & setEvent(const HEPEUP &x)
const WeightInfo * currentWeight
std::pair< int, int > PDFSUPsave
std::vector< Clus > clustering
bool setWeightInfo(unsigned int i)
std::vector< std::pair< double, const WeightInfo * > > weights
bool setWeight(std::string name, double w)
HEPEUP(const XMLTag &tagin, HEPRUP &heprupin)
double totalWeight(std::string name) const
bool setSubEvent(unsigned int i)
void setWeight(int i, double w)
std::vector< Weight > namedweights
double weight(int i=0) const
std::vector< double > SPINUP
std::vector< std::pair< int, int > > ICOLUP
std::pair< double, double > XPDWUP
std::vector< std::vector< double > > PUP
std::vector< double > XMAXUP
std::vector< WeightGroup > weightgroup
std::vector< Generator > generators
void print(std::ostream &file) const
int weightIndex(std::string name) const
XSecInfo & getXSecInfo(std::string weightname="")
HEPRUP(const HEPRUP &)=default
std::pair< double, double > EBMUP
std::vector< EventFile > eventfiles
std::pair< int, int > PDFGUP
std::map< long, MergeInfo > mergeinfo
HEPRUP & operator=(const HEPRUP &)=default
std::vector< WeightInfo > weightinfo
std::map< long, ProcInfo > procinfo
std::map< std::string, int > weightmap
HEPRUP(const XMLTag &tagin, int versin)
std::map< std::string, std::set< long > > ptypes
std::pair< int, int > PDFSUP
std::pair< long, long > IDBMUP
std::vector< double > XSECUP
const XSecInfo & getXSecInfo(std::string weightname="") const
std::vector< double > XERRUP
std::string weightNameHepMC(int i) const
std::ios_base::iostate file_rdstate() const
std::string eventComments
void openeventfile(int ifile)
bool currentFind(std::string str) const
Reader & operator=(const Reader &)
Reader(std::string filename)
std::ios_base::iostate initfile_rdstate() const
std::ostream & initComments()
void initComments(const std::string &a)
void eventComments(const std::string &a)
std::ostream & headerBlock()
std::ostringstream initStream
std::ostringstream eventStream
std::ostream & eventComments()
void headerBlock(const std::string &a)
Writer(std::string filename)
std::ostringstream headerStream
bool openeventfile(int ifile)
Writer & operator=(const Writer &)
Les Houches event file classes.
std::string hashline(std::string s)
std::map< std::string, XSecInfo > XSecInfos
OAttr< T > oattr(std::string name, const T &value)
std::ostream & operator<<(std::ostream &os, const OAttr< T > &oa)
void print(std::ostream &file) const
void print(std::ostream &file) const
bool match(long id1, long id2=0) const
Cut(const XMLTag &tag, const std::map< std::string, std::set< long > > &ptypes)
bool outside(double value) const
bool passCuts(const std::vector< long > &id, const std::vector< std::vector< double > > &p) const
static double rap(const std::vector< double > &p)
static double eta(const std::vector< double > &p)
static double deltaR(const std::vector< double > &p1, const std::vector< double > &p2)
EventFile(const XMLTag &tag)
void print(std::ostream &file) const
EventGroup & operator=(const EventGroup &)
void print(std::ostream &file) const
Generator(const XMLTag &tag)
void print(std::ostream &file) const
MergeInfo(const XMLTag &tag)
OAttr(std::string n, const T &v)
void print(std::ostream &file) const
PDFInfo(const XMLTag &tag, double defscale=-1.0)
PDFInfo(double defscale=-1.0)
ProcInfo(const XMLTag &tag)
void print(std::ostream &file) const
void print(std::ostream &file) const
Scale(std::string st="veto", int emtr=0, double sc=0.0)
std::set< int > recoilers
double getScale(std::string st, int pdgem, int emr, int rec) const
void print(std::ostream &file) const
Scales(double defscale=-1.0, int npart=0)
Scales(const XMLTag &tag, double defscale=-1.0, int npart=0)
std::vector< Scale > scales
bool getattr(std::string n, double &v, bool erase=true)
bool getattr(std::string n, bool &v, bool erase=true)
void closetag(std::ostream &file, std::string tag) const
TagBase(const AttributeMap &attr, std::string conts=std::string())
XMLTag::AttributeMap attributes
void printattrs(std::ostream &file) const
bool getattr(std::string n, int &v, bool erase=true)
XMLTag::AttributeMap AttributeMap
bool getattr(std::string n, long &v, bool erase=true)
bool getattr(std::string n, std::string &v, bool erase=true)
WeightGroup(const XMLTag &tag, int groupIndex, std::vector< WeightInfo > &wiv)
void print(std::ostream &file) const
WeightInfo(const XMLTag &tag)
Weight(const XMLTag &tag)
std::vector< int > indices
void print(std::ostream &file) const
std::vector< double > weights
bool getattr(std::string n, double &v) const
std::map< std::string, std::string > AttributeMap
bool getattr(std::string n, bool &v) const
static std::vector< XMLTag * > findXMLTags(std::string str, std::string *leftover=0)
std::string::size_type pos_t
bool getattr(std::string n, int &v) const
static void deleteAll(std::vector< XMLTag * > &tags)
bool getattr(std::string n, long &v) const
void print(std::ostream &os) const
std::vector< XMLTag * > tags
bool getattr(std::string n, std::string &v) const
void print(std::ostream &file) const
XSecInfo(const XMLTag &tag)