File indexing completed on 2025-01-18 10:01:13
0001
0002 #ifndef HEPMC3_LHEF_H
0003 #define HEPMC3_LHEF_H
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #include <iostream>
0016 #include <iomanip>
0017 #include <sstream>
0018 #include <fstream>
0019 #include <string>
0020 #include <vector>
0021 #include <map>
0022 #include <set>
0023 #include <utility>
0024 #include <stdexcept>
0025 #include <cstdlib>
0026 #include <cmath>
0027 #include <limits>
0028 #ifndef M_PI
0029 #define M_PI 3.14159265358979323846264338327950288
0030 #endif
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041 namespace LHEF {
0042
0043
0044
0045
0046 template <typename T>
0047 struct OAttr {
0048
0049
0050
0051
0052 OAttr(const std::string & n, const T & v): name(n), val(v) {}
0053
0054
0055
0056
0057 std::string name;
0058
0059
0060
0061
0062 T val;
0063
0064 };
0065
0066
0067
0068
0069 template <typename T>
0070 OAttr<T> oattr(std::string name, const T & value) {
0071 return OAttr<T>(name, value);
0072 }
0073
0074
0075
0076
0077 template <typename T>
0078 std::ostream & operator<<(std::ostream & os, const OAttr<T> & oa) {
0079 os << " " << oa.name << "=\"" << oa.val << "\"";
0080 return os;
0081 }
0082
0083
0084
0085
0086
0087
0088
0089 struct XMLTag {
0090
0091
0092
0093
0094 typedef std::string::size_type pos_t;
0095
0096
0097
0098
0099 typedef std::map<std::string,std::string> AttributeMap;
0100
0101
0102
0103
0104 static const pos_t end = std::string::npos;
0105
0106
0107
0108
0109 XMLTag() {}
0110
0111
0112
0113
0114 ~XMLTag() {
0115 for ( int i = 0, N = tags.size(); i < N; ++i ) delete tags[i];
0116 }
0117
0118
0119
0120
0121 std::string name;
0122
0123
0124
0125
0126 AttributeMap attr;
0127
0128
0129
0130
0131 std::vector<XMLTag*> tags;
0132
0133
0134
0135
0136 std::string contents;
0137
0138
0139
0140
0141
0142 bool getattr(const std::string & n, double & v) const {
0143 AttributeMap::const_iterator it = attr.find(n);
0144 if ( it == attr.end() ) return false;
0145 v = std::atof(it->second.c_str());
0146 return true;
0147 }
0148
0149
0150
0151
0152
0153
0154 bool getattr(const std::string & n, bool & v) const {
0155 AttributeMap::const_iterator it = attr.find(n);
0156 if ( it == attr.end() ) return false;
0157 if ( it->second == "yes" ) v = true;
0158 return true;
0159 }
0160
0161
0162
0163
0164
0165 bool getattr(const std::string & n, long & v) const {
0166 AttributeMap::const_iterator it = attr.find(n);
0167 if ( it == attr.end() ) return false;
0168 v = std::atoi(it->second.c_str());
0169 return true;
0170 }
0171
0172
0173
0174
0175
0176 bool getattr(const std::string & n, int & v) const {
0177 AttributeMap::const_iterator it = attr.find(n);
0178 if ( it == attr.end() ) return false;
0179 v = int(std::atoi(it->second.c_str()));
0180 return true;
0181 }
0182
0183
0184
0185
0186
0187 bool getattr(const std::string &n, std::string & v) const {
0188 AttributeMap::const_iterator it = attr.find(n);
0189 if ( it == attr.end() ) return false;
0190 v = it->second;
0191 return true;
0192 }
0193
0194
0195
0196
0197
0198
0199
0200 static std::vector<XMLTag*> findXMLTags(std::string str,
0201 std::string * leftover = 0) {
0202 std::vector<XMLTag*> tags;
0203 pos_t curr = 0;
0204
0205 while ( curr != end ) {
0206
0207
0208 pos_t begin = str.find("<", curr);
0209
0210
0211 if ( begin != end && str.find("<!--", curr) == begin ) {
0212 pos_t endcom = str.find("-->", begin);
0213 tags.push_back(new XMLTag());
0214 if ( endcom == end ) {
0215 tags.back()->contents = str.substr(curr);
0216 if ( leftover ) *leftover += str.substr(curr);
0217 return tags;
0218 }
0219 tags.back()->contents = str.substr(curr, endcom - curr);
0220 if ( leftover ) *leftover += str.substr(curr, endcom - curr);
0221 curr = endcom;
0222 continue;
0223 }
0224
0225
0226 if ( begin != end && str.find("<![CDATA[", curr) == begin ) {
0227 pos_t endcom = str.find("]]>", begin);
0228 tags.push_back(new XMLTag());
0229 if ( endcom == end ) {
0230 tags.back()->contents = str.substr(curr);
0231 if ( leftover ) *leftover += str.substr(curr);
0232 return tags;
0233 }
0234 tags.back()->contents = str.substr(curr, endcom - curr);
0235 if ( leftover ) *leftover += str.substr(curr, endcom - curr);
0236 curr = endcom;
0237 continue;
0238 }
0239
0240 if ( begin != curr ) {
0241 tags.push_back(new XMLTag());
0242 tags.back()->contents = str.substr(curr, begin - curr);
0243 if ( leftover ) *leftover += str.substr(curr, begin - curr);
0244 }
0245 if ( begin == end || begin > str.length() - 3 || str[begin + 1] == '/' )
0246 return tags;
0247
0248 pos_t close = str.find(">", curr);
0249 if ( close == end ) return tags;
0250
0251
0252 curr = str.find_first_of(" \t\n/>", begin);
0253 tags.push_back(new XMLTag());
0254 tags.back()->name = str.substr(begin + 1, curr - begin - 1);
0255
0256 while ( true ) {
0257
0258
0259 curr = str.find_first_not_of(" \t\n", curr);
0260 if ( curr == end || curr >= close ) break;
0261
0262 pos_t tend = str.find_first_of("= \t\n", curr);
0263 if ( tend == end || tend >= close ) break;
0264
0265 std::string namex = str.substr(curr, tend - curr);
0266 curr = str.find("=", curr) + 1;
0267
0268
0269 curr = str.find_first_of("\"'", curr);
0270 if ( curr == end || curr >= close ) break;
0271 char quote = str[curr];
0272 pos_t bega = ++curr;
0273 curr = str.find(quote, curr);
0274 while ( curr != end && str[curr - 1] == '\\' )
0275 curr = str.find(quote, curr + 1);
0276
0277 std::string value = str.substr(bega, curr == end? end: curr - bega);
0278
0279 tags.back()->attr[namex] = value;
0280
0281 ++curr;
0282
0283 }
0284
0285 curr = close + 1;
0286 if ( str[close - 1] == '/' ) continue;
0287
0288 pos_t endtag = str.find("</" + tags.back()->name + ">", curr);
0289 if ( endtag == end ) {
0290 tags.back()->contents = str.substr(curr);
0291 curr = endtag;
0292 } else {
0293 tags.back()->contents = str.substr(curr, endtag - curr);
0294 curr = endtag + tags.back()->name.length() + 3;
0295 }
0296
0297 std::string leftovers;
0298 tags.back()->tags = findXMLTags(tags.back()->contents, &leftovers);
0299 if ( leftovers.find_first_not_of(" \t\n") == end ) leftovers="";
0300 tags.back()->contents = leftovers;
0301
0302 }
0303 return tags;
0304
0305 }
0306
0307
0308
0309
0310 static void deleteAll(std::vector<XMLTag*> & tags) {
0311 while ( tags.size() && tags.back() ) {
0312 delete tags.back();
0313 tags.pop_back();
0314 }
0315 }
0316
0317
0318
0319 void print(std::ostream & os) const {
0320 if ( name.empty() ) {
0321 os << contents;
0322 return;
0323 }
0324 os << "<" << name;
0325 for ( AttributeMap::const_iterator it = attr.begin();
0326 it != attr.end(); ++it )
0327 os << oattr(it->first, it->second);
0328 if ( contents.empty() && tags.empty() ) {
0329 os << "/>" << std::endl;
0330 return;
0331 }
0332 os << ">";
0333 for ( int i = 0, N = tags.size(); i < N; ++i )
0334 tags[i]->print(os);
0335
0336 os << contents << "</" << name << ">" << std::endl;
0337 }
0338
0339 };
0340
0341
0342
0343
0344
0345 inline std::string hashline(std::string s) {
0346 std::string ret;
0347 std::istringstream is(s);
0348 std::string ss;
0349 while ( getline(is, ss) ) {
0350 if ( ss.empty() ) continue;
0351 if ( ss.find_first_not_of(" \t") == std::string::npos ) continue;
0352 if ( ss.find('#') == std::string::npos ||
0353 ss.find('#') != ss.find_first_not_of(" \t") ) ss = "# " + ss;
0354 ret += ss + '\n';
0355 }
0356 return ret;
0357 }
0358
0359
0360
0361
0362 struct TagBase {
0363
0364
0365
0366
0367 typedef XMLTag::AttributeMap AttributeMap;
0368
0369
0370
0371
0372 TagBase() {}
0373
0374
0375
0376
0377 TagBase(const AttributeMap & attr, const std::string &conts = std::string())
0378 : attributes(attr), contents(conts) {}
0379
0380
0381
0382
0383
0384
0385
0386 bool getattr(const std::string & n, double & v, bool erase = true) {
0387 AttributeMap::iterator it = attributes.find(n);
0388 if ( it == attributes.end() ) return false;
0389 v = std::atof(it->second.c_str());
0390 if ( erase) attributes.erase(it);
0391 return true;
0392 }
0393
0394
0395
0396
0397
0398
0399
0400 bool getattr(const std::string & n, bool & v, bool erase = true) {
0401 AttributeMap::iterator it = attributes.find(n);
0402 if ( it == attributes.end() ) return false;
0403 if ( it->second == "yes" ) v = true;
0404 if ( erase) attributes.erase(it);
0405 return true;
0406 }
0407
0408
0409
0410
0411
0412
0413
0414 bool getattr(const std::string & n, long & v, bool erase = true) {
0415 AttributeMap::iterator it = attributes.find(n);
0416 if ( it == attributes.end() ) return false;
0417 v = std::atoi(it->second.c_str());
0418 if ( erase) attributes.erase(it);
0419 return true;
0420 }
0421
0422
0423
0424
0425
0426
0427
0428 bool getattr(const std::string & n, int & v, bool erase = true) {
0429 AttributeMap::iterator it = attributes.find(n);
0430 if ( it == attributes.end() ) return false;
0431 v = int(std::atoi(it->second.c_str()));
0432 if ( erase) attributes.erase(it);
0433 return true;
0434 }
0435
0436
0437
0438
0439
0440
0441
0442 bool getattr(const std::string & n, std::string & v, bool erase = true) {
0443 AttributeMap::iterator it = attributes.find(n);
0444 if ( it == attributes.end() ) return false;
0445 v = it->second;
0446 if ( erase) attributes.erase(it);
0447 return true;
0448 }
0449
0450
0451
0452
0453 void printattrs(std::ostream & file) const {
0454 for ( AttributeMap::const_iterator it = attributes.begin();
0455 it != attributes.end(); ++ it )
0456 file << oattr(it->first, it->second);
0457 }
0458
0459
0460
0461
0462
0463 void closetag(std::ostream & file, const std::string & tag) const {
0464 if ( contents.empty() )
0465 file << "/>\n";
0466 else if ( contents.find('\n') != std::string::npos )
0467 file << ">\n" << contents << "\n</" << tag << ">\n";
0468 else
0469 file << ">" << contents << "</" << tag << ">\n";
0470 }
0471
0472
0473
0474
0475 XMLTag::AttributeMap attributes;
0476
0477
0478
0479
0480 mutable std::string contents;
0481
0482
0483
0484
0485 static std::string yes() { return "yes"; }
0486
0487 };
0488
0489
0490
0491
0492 struct Generator : public TagBase {
0493
0494
0495
0496
0497 Generator(const XMLTag & tag)
0498 : TagBase(tag.attr, tag.contents) {
0499 getattr("name", name);
0500 getattr("version", version);
0501 }
0502
0503
0504
0505
0506 void print(std::ostream & file) const {
0507 file << "<generator";
0508 if ( !name.empty() ) file << oattr("name", name);
0509 if ( !version.empty() ) file << oattr("version", version);
0510 printattrs(file);
0511 closetag(file, "generator");
0512 }
0513
0514
0515
0516
0517 std::string name;
0518
0519
0520
0521
0522 std::string version;
0523
0524 };
0525
0526
0527
0528
0529 struct XSecInfo : public TagBase {
0530
0531
0532
0533
0534 XSecInfo(): neve(-1), ntries(-1), totxsec(0.0), xsecerr(0.0), maxweight(1.0),
0535 meanweight(1.0), negweights(false), varweights(false) {}
0536
0537
0538
0539
0540 XSecInfo(const XMLTag & tag)
0541 : TagBase(tag.attr, tag.contents), neve(-1), ntries(-1),
0542 totxsec(0.0), xsecerr(0.0), maxweight(1.0), meanweight(1.0),
0543 negweights(false), varweights(false) {
0544 if ( !getattr("neve", neve) )
0545 throw std::runtime_error("Found xsecinfo tag without neve attribute "
0546 "in Les Houches Event File.");
0547 ntries = neve;
0548 getattr("ntries", ntries);
0549 if ( !getattr("totxsec", totxsec) )
0550 throw std::runtime_error("Found xsecinfo tag without totxsec "
0551 "attribute in Les Houches Event File.");
0552 getattr("xsecerr", xsecerr);
0553 getattr("weightname", weightname);
0554 getattr("maxweight", maxweight);
0555 getattr("meanweight", meanweight);
0556 getattr("negweights", negweights);
0557 getattr("varweights", varweights);
0558
0559 }
0560
0561
0562
0563
0564 void print(std::ostream & file) const {
0565 file << "<xsecinfo" << oattr("neve", neve)
0566 << oattr("totxsec", totxsec);
0567 if ( maxweight != 1.0 )
0568 file << oattr("maxweight", maxweight)
0569 << oattr("meanweight", meanweight);
0570 if ( ntries > neve ) file << oattr("ntries", ntries);
0571 if ( xsecerr > 0.0 ) file << oattr("xsecerr", xsecerr);
0572 if ( !weightname.empty() ) file << oattr("weightname", weightname);
0573 if ( negweights ) file << oattr("negweights", yes());
0574 if ( varweights ) file << oattr("varweights", yes());
0575 printattrs(file);
0576 closetag(file, "xsecinfo");
0577 }
0578
0579
0580
0581
0582 long neve;
0583
0584
0585
0586
0587 long ntries;
0588
0589
0590
0591
0592 double totxsec;
0593
0594
0595
0596
0597 double xsecerr;
0598
0599
0600
0601
0602 double maxweight;
0603
0604
0605
0606
0607 double meanweight;
0608
0609
0610
0611
0612 bool negweights;
0613
0614
0615
0616
0617 bool varweights;
0618
0619
0620
0621
0622 std::string weightname;
0623
0624 };
0625
0626
0627
0628
0629 typedef std::map<std::string,XSecInfo> XSecInfos;
0630
0631
0632
0633
0634
0635 struct EventFile : public TagBase {
0636
0637
0638
0639
0640 EventFile(): filename(""), neve(-1), ntries(-1) {}
0641
0642
0643
0644
0645 EventFile(const XMLTag & tag)
0646 : TagBase(tag.attr, tag.contents), filename(""), neve(-1), ntries(-1) {
0647 if ( !getattr("name", filename) )
0648 throw std::runtime_error("Found eventfile tag without name attribute "
0649 "in Les Houches Event File.");
0650 getattr("neve", neve);
0651 ntries = neve;
0652 getattr("ntries", ntries);
0653 }
0654
0655
0656
0657
0658 void print(std::ostream & file) const {
0659 if ( filename.empty() ) return;
0660 file << " <eventfile" << oattr("name", filename);
0661 if ( neve > 0 ) file << oattr("neve", neve);
0662 if ( ntries > neve ) file << oattr("ntries", ntries);
0663 printattrs(file);
0664 closetag(file, "eventfile");
0665 }
0666
0667
0668
0669
0670 std::string filename;
0671
0672
0673
0674
0675 long neve;
0676
0677
0678
0679
0680 long ntries;
0681
0682 };
0683
0684
0685
0686
0687 struct Cut : public TagBase {
0688
0689
0690
0691
0692 Cut(): min(-0.99*std::numeric_limits<double>::max()),
0693 max(0.99*std::numeric_limits<double>::max()) {}
0694
0695
0696
0697
0698 Cut(const XMLTag & tag,
0699 const std::map<std::string,std::set<long> >& ptypes)
0700 : TagBase(tag.attr),
0701 min(-0.99*std::numeric_limits<double>::max()),
0702 max(0.99*std::numeric_limits<double>::max()) {
0703 if ( !getattr("type", type) )
0704 throw std::runtime_error("Found cut tag without type attribute "
0705 "in Les Houches file");
0706 long tmp;
0707 if ( tag.getattr("p1", np1) ) {
0708 if ( ptypes.find(np1) != ptypes.end() ) {
0709 p1 = ptypes.find(np1)->second;
0710 attributes.erase("p1");
0711 } else {
0712 getattr("p1", tmp);
0713 p1.insert(tmp);
0714 np1 = "";
0715 }
0716 }
0717 if ( tag.getattr("p2", np2) ) {
0718 if ( ptypes.find(np2) != ptypes.end() ) {
0719 p2 = ptypes.find(np2)->second;
0720 attributes.erase("p2");
0721 } else {
0722 getattr("p2", tmp);
0723 p2.insert(tmp);
0724 np2 = "";
0725 }
0726 }
0727
0728 std::istringstream iss(tag.contents);
0729 iss >> min;
0730 if ( iss >> max ) {
0731 if ( min >= max )
0732 min = -0.99*std::numeric_limits<double>::max();
0733 } else
0734 max = 0.99*std::numeric_limits<double>::max();
0735 }
0736
0737
0738
0739
0740 void print(std::ostream & file) const {
0741 file << "<cut" << oattr("type", type);
0742 if ( !np1.empty() )
0743 file << oattr("p1", np1);
0744 else
0745 if ( p1.size() == 1 ) file << oattr("p1", *p1.begin());
0746 if ( !np2.empty() )
0747 file << oattr("p2", np2);
0748 else
0749 if ( p2.size() == 1 ) file << oattr("p2", *p2.begin());
0750 printattrs(file);
0751
0752 file << ">";
0753 if ( min > -0.9*std::numeric_limits<double>::max() )
0754 file << min;
0755 else
0756 file << max;
0757 if ( max < 0.9*std::numeric_limits<double>::max() )
0758 file << " " << max;
0759 if ( !contents.empty() ) file << std::endl << contents << std::endl;
0760 file << "</cut>" << std::endl;
0761 }
0762
0763
0764
0765
0766
0767 bool match(long id1, long id2 = 0) const {
0768 std::pair<bool,bool> ret(false, false);
0769 if ( !id2 ) ret.second = true;
0770 if ( !id1 ) ret.first = true;
0771 if ( p1.find(0) != p1.end() ) ret.first = true;
0772 if ( p1.find(id1) != p1.end() ) ret.first = true;
0773 if ( p2.find(0) != p2.end() ) ret.second = true;
0774 if ( p2.find(id2) != p2.end() ) ret.second = true;
0775 return ret.first && ret.second;
0776 }
0777
0778
0779
0780
0781
0782
0783 bool passCuts(const std::vector<long> & id,
0784 const std::vector< std::vector<double> >& p ) const {
0785 if ( ( type == "m" && !p2.size() ) || type == "kt" || type == "eta" ||
0786 type == "y" || type == "E" ) {
0787 for ( int i = 0, N = id.size(); i < N; ++i )
0788 if ( match(id[i]) ) {
0789 if ( type == "m" ) {
0790 double v = p[i][4]*p[i][4] - p[i][3]*p[i][3] - p[i][2]*p[i][2]
0791 - p[i][1]*p[i][1];
0792 v = v >= 0.0? std::sqrt(v): -std::sqrt(-v);
0793 if ( outside(v) ) return false;
0794 }
0795 else if ( type == "kt" ) {
0796 if ( outside(std::sqrt(p[i][2]*p[i][2] + p[i][1]*p[i][1])) )
0797 return false;
0798 }
0799 else if ( type == "E" ) {
0800 if ( outside(p[i][4]) ) return false;
0801 }
0802 else if ( type == "eta" ) {
0803 if ( outside(eta(p[i])) ) return false;
0804 }
0805 else if ( type == "y" ) {
0806 if ( outside(rap(p[i])) ) return false;
0807 }
0808 }
0809 }
0810 else if ( type == "m" || type == "deltaR" ) {
0811 for ( int i = 1, N = id.size(); i < N; ++i )
0812 for ( int j = 0; j < i; ++j )
0813 if ( match(id[i], id[j]) || match(id[j], id[i]) ) {
0814 if ( type == "m" ) {
0815 double v = (p[i][4] + p[j][4])*(p[i][4] + p[j][4])
0816 - (p[i][3] + p[j][3])*(p[i][3] + p[j][3])
0817 - (p[i][2] + p[j][2])*(p[i][2] + p[j][2])
0818 - (p[i][1] + p[j][1])*(p[i][1] + p[j][1]);
0819 v = v >= 0.0? std::sqrt(v): -std::sqrt(-v);
0820 if ( outside(v) ) return false;
0821 }
0822 else if ( type == "deltaR" ) {
0823 if ( outside(deltaR(p[i], p[j])) ) return false;
0824 }
0825 }
0826 }
0827 else if ( type == "ETmiss" ) {
0828 double x = 0.0;
0829 double y = 0.0;
0830 for ( int i = 0, N = id.size(); i < N; ++i )
0831 if ( match(id[i]) && !match(0, id[i]) ) {
0832 x += p[i][1];
0833 y += p[i][2];
0834 }
0835 if ( outside(std::sqrt(x*x + y*y)) ) return false;
0836 }
0837 else if ( type == "HT" ) {
0838 double pt = 0.0;
0839 for ( int i = 0, N = id.size(); i < N; ++i )
0840 if ( match(id[i]) && !match(0, id[i]) )
0841 pt += std::sqrt(p[i][1]*p[i][1] + p[i][2]*p[i][2]);
0842 if ( outside(pt) ) return false;
0843 }
0844 return true;
0845 }
0846
0847
0848
0849
0850 static double eta(const std::vector<double> & p) {
0851 double pt2 = p[2]*p[2] + p[1]*p[1];
0852 if ( pt2 != 0.0 ) {
0853 double dum = std::sqrt(pt2 + p[3]*p[3]) + p[3];
0854 if ( dum != 0.0 )
0855 return std::log(dum/std::sqrt(pt2));
0856 }
0857 return p[3] < 0.0? -std::numeric_limits<double>::max():
0858 std::numeric_limits<double>::max();
0859 }
0860
0861
0862
0863
0864 static double rap(const std::vector<double> & p) {
0865 double pt2 = p[5]*p[5] + p[2]*p[2] + p[1]*p[1];
0866 if ( pt2 != 0.0 ) {
0867 double dum = std::sqrt(pt2 + p[3]*p[3]) + p[3];
0868 if ( dum != 0.0 )
0869 return std::log(dum/std::sqrt(pt2));
0870 }
0871 return p[3] < 0.0? -std::numeric_limits<double>::max():
0872 std::numeric_limits<double>::max();
0873 }
0874
0875
0876
0877
0878 static double deltaR(const std::vector<double> & p1,
0879 const std::vector<double> & p2) {
0880 double deta = eta(p1) - eta(p2);
0881 double dphi = std::atan2(p1[1], p1[2]) - std::atan2(p2[1], p2[2]);
0882 if ( dphi > M_PI ) dphi -= 2.0*M_PI;
0883 if ( dphi < -M_PI ) dphi += 2.0*M_PI;
0884 return std::sqrt(dphi*dphi + deta*deta);
0885 }
0886
0887
0888
0889
0890 bool outside(double value) const {
0891 return value < min || value >= max;
0892 }
0893
0894
0895
0896
0897 std::string type;
0898
0899
0900
0901
0902 std::set<long> p1;
0903
0904
0905
0906
0907 std::string np1;
0908
0909
0910
0911
0912 std::set<long> p2;
0913
0914
0915
0916
0917 std::string np2;
0918
0919
0920
0921
0922 double min;
0923
0924
0925
0926 double max;
0927
0928 };
0929
0930
0931
0932
0933 struct ProcInfo : public TagBase {
0934
0935
0936
0937
0938 ProcInfo(): iproc(0), loops(0), qcdorder(-1), eworder(-1) {}
0939
0940
0941
0942
0943 ProcInfo(const XMLTag & tag)
0944 : TagBase(tag.attr, tag.contents),
0945 iproc(0), loops(0), qcdorder(-1), eworder(-1) {
0946 getattr("iproc", iproc);
0947 getattr("loops", loops);
0948 getattr("qcdorder", qcdorder);
0949 getattr("eworder", eworder);
0950 getattr("rscheme", rscheme);
0951 getattr("fscheme", fscheme);
0952 getattr("scheme", scheme);
0953 }
0954
0955
0956
0957
0958 void print(std::ostream & file) const {
0959 file << "<procinfo" << oattr("iproc", iproc);
0960 if ( loops >= 0 ) file << oattr("loops", loops);
0961 if ( qcdorder >= 0 ) file << oattr("qcdorder", qcdorder);
0962 if ( eworder >= 0 ) file<< oattr("eworder", eworder);
0963 if ( !rscheme.empty() ) file << oattr("rscheme", rscheme);
0964 if ( !fscheme.empty() ) file << oattr("fscheme", fscheme);
0965 if ( !scheme.empty() ) file << oattr("scheme", scheme);
0966 printattrs(file);
0967 closetag(file, "procinfo");
0968 }
0969
0970
0971
0972
0973 int iproc;
0974
0975
0976
0977
0978 int loops;
0979
0980
0981
0982
0983 int qcdorder;
0984
0985
0986
0987
0988 int eworder;
0989
0990
0991
0992
0993 std::string fscheme;
0994
0995
0996
0997
0998 std::string rscheme;
0999
1000
1001
1002
1003 std::string scheme;
1004
1005 };
1006
1007
1008
1009
1010 struct MergeInfo : public TagBase {
1011
1012
1013
1014
1015 MergeInfo(): iproc(0), mergingscale(0.0), maxmult(false) {}
1016
1017
1018
1019
1020 MergeInfo(const XMLTag & tag)
1021 : TagBase(tag.attr, tag.contents),
1022 iproc(0), mergingscale(0.0), maxmult(false) {
1023 getattr("iproc", iproc);
1024 getattr("mergingscale", mergingscale);
1025 getattr("maxmult", maxmult);
1026 }
1027
1028
1029
1030
1031 void print(std::ostream & file) const {
1032 file << "<mergeinfo" << oattr("iproc", iproc);
1033 if ( mergingscale > 0.0 ) file << oattr("mergingscale", mergingscale);
1034 if ( maxmult ) file << oattr("maxmult", yes());
1035 printattrs(file);
1036 closetag(file, "mergeinfo");
1037 }
1038
1039
1040
1041
1042 int iproc;
1043
1044
1045
1046
1047 double mergingscale;
1048
1049
1050
1051
1052 bool maxmult;
1053
1054 };
1055
1056
1057
1058
1059
1060 struct WeightInfo : public TagBase {
1061
1062
1063
1064
1065 WeightInfo(): inGroup(-1), isrwgt(false),
1066 muf(1.0), mur(1.0), pdf(0), pdf2(0) {}
1067
1068
1069
1070
1071 WeightInfo(const XMLTag & tag)
1072 : TagBase(tag.attr, tag.contents),
1073 inGroup(-1), isrwgt(tag.name == "weight"),
1074 muf(1.0), mur(1.0), pdf(0), pdf2(0) {
1075 getattr("mur", mur);
1076 getattr("muf", muf);
1077 getattr("pdf", pdf);
1078 getattr("pdf2", pdf2);
1079 if ( isrwgt )
1080 getattr("id", name);
1081 else
1082 getattr("name", name);
1083 }
1084
1085
1086
1087
1088 void print(std::ostream & file) const {
1089
1090 if ( isrwgt )
1091 file << "<weight" << oattr("id", name);
1092 else
1093 file << "<weightinfo" << oattr("name", name);
1094 if ( mur != 1.0 ) file << oattr("mur", mur);
1095 if ( muf != 1.0 ) file << oattr("muf", muf);
1096 if ( pdf != 0 ) file << oattr("pdf", pdf);
1097 if ( pdf2 != 0 ) file << oattr("pdf2", pdf2);
1098 printattrs(file);
1099 if ( isrwgt )
1100 closetag(file, "weight");
1101 else
1102 closetag(file, "weightinfo");
1103 }
1104
1105
1106
1107
1108 int inGroup;
1109
1110
1111
1112
1113 bool isrwgt;
1114
1115
1116
1117
1118 std::string name;
1119
1120
1121
1122
1123 double muf;
1124
1125
1126
1127
1128 double mur;
1129
1130
1131
1132
1133 long pdf;
1134
1135
1136
1137
1138
1139 long pdf2;
1140
1141 };
1142
1143
1144
1145
1146 struct WeightGroup : public TagBase {
1147
1148
1149
1150
1151 WeightGroup() {}
1152
1153
1154
1155
1156
1157 WeightGroup(const XMLTag & tag, int groupIndex, std::vector<WeightInfo> & wiv)
1158 : TagBase(tag.attr) {
1159 getattr("type", type);
1160 getattr("combine", combine);
1161 for ( int i = 0, N = tag.tags.size(); i < N; ++i ) {
1162 if ( tag.tags[i]->name == "weight" ||
1163 tag.tags[i]->name == "weightinfo" ) {
1164 WeightInfo wi(*tag.tags[i]);
1165 wi.inGroup = groupIndex;
1166 wiv.push_back(wi);
1167 }
1168 }
1169 }
1170
1171
1172
1173
1174 std::string type;
1175
1176
1177
1178
1179 std::string combine;
1180
1181 };
1182
1183
1184
1185
1186
1187 struct Weight : public TagBase {
1188
1189
1190
1191
1192 Weight(): iswgt(false), born(0.0), sudakov(0.0) {}
1193
1194
1195
1196
1197 Weight(const XMLTag & tag)
1198 : TagBase(tag.attr, tag.contents),
1199 iswgt(tag.name == "wgt"), born(0.0), sudakov(0.0) {
1200 if ( iswgt )
1201 getattr("id", name);
1202 else
1203 getattr("name", name);
1204 getattr("born", born);
1205 getattr("sudakov", sudakov);
1206 std::istringstream iss(tag.contents);
1207 double w;
1208 while ( iss >> w ) weights.push_back(w);
1209 indices.resize(weights.size(), 0.0);
1210 }
1211
1212
1213
1214
1215 void print(std::ostream & file) const {
1216 if ( iswgt )
1217 file << "<wgt" << oattr("id", name);
1218 else {
1219 file << "<weight";
1220 if ( !name.empty() ) file << oattr("name", name);
1221 }
1222 if ( born != 0.0 ) file << oattr("born", born);
1223 if ( sudakov != 0.0 ) file << oattr("sudakov", sudakov);
1224 file << ">";
1225 for ( int j = 0, M = weights.size(); j < M; ++j ) file << " " << weights[j];
1226 if ( iswgt )
1227 file << "</wgt>" << std::endl;
1228 else
1229 file << "</weight>" << std::endl;
1230 }
1231
1232
1233
1234
1235 std::string name;
1236
1237
1238
1239
1240 bool iswgt;
1241
1242
1243
1244
1245 double born;
1246
1247
1248
1249
1250 double sudakov;
1251
1252
1253
1254
1255 mutable std::vector<double> weights;
1256
1257
1258
1259
1260 std::vector<int> indices;
1261
1262 };
1263
1264
1265
1266
1267
1268 struct Clus : public TagBase {
1269
1270
1271
1272
1273 Clus(): p1(0), p2(0), p0(0), scale(-1.0), alphas(-1.0) {}
1274
1275
1276
1277
1278 Clus(const XMLTag & tag)
1279 : TagBase(tag.attr, tag.contents), scale(-1.0), alphas(-1.0) {
1280 getattr("scale", scale);
1281 getattr("alphas", alphas);
1282 std::istringstream iss(tag.contents);
1283 iss >> p1 >> p2;
1284 if ( !( iss >> p0 ) ) p0 = p1;
1285 }
1286
1287
1288
1289
1290 void print(std::ostream & file) const {
1291 file << "<clus";
1292 if ( scale > 0.0 ) file << oattr("scale", scale);
1293 if ( alphas > 0.0 ) file << oattr("alphas", alphas);
1294 file << ">" << p1 << " " << p2;
1295 if ( p1 != p0 ) file << " " << p0;
1296 file << "</clus>" << std::endl;
1297 }
1298
1299
1300
1301
1302 int p1;
1303
1304
1305
1306
1307 int p2;
1308
1309
1310
1311
1312 int p0;
1313
1314
1315
1316
1317 double scale;
1318
1319
1320
1321
1322
1323 double alphas;
1324
1325 };
1326
1327
1328
1329
1330
1331 struct Scale : public TagBase {
1332
1333
1334
1335
1336 Scale(std::string st = "veto", int emtr = 0, double sc = 0.0)
1337 : stype(st), emitter(emtr), scale(sc) {}
1338
1339
1340
1341
1342 Scale(const XMLTag & tag)
1343 : TagBase(tag.attr, tag.contents),stype("veto"), emitter(0) {
1344 if ( !getattr("stype", stype) )
1345 throw std::runtime_error("Found scale tag without stype attribute "
1346 "in Les Houches Event File.");
1347 std::string pattr;
1348 if ( getattr("pos", pattr) ) {
1349 std::istringstream pis(pattr);
1350 if ( !(pis >> emitter) ) emitter = 0;
1351 else {
1352 int rec = 0;
1353 while ( pis >> rec ) recoilers.insert(rec);
1354 }
1355 }
1356
1357 std::string eattr;
1358 if ( getattr("etype", eattr) ) {
1359 if ( eattr == "QCD" ) eattr = "-5 -4 -3 -2 -1 1 2 3 4 5 21";
1360 if ( eattr == "EW" ) eattr = "-13 -12 -11 11 12 13 22 23 24";
1361 std::istringstream eis(eattr);
1362 int pdg = 0;
1363 while ( eis >> pdg ) emitted.insert(pdg);
1364 }
1365 std::istringstream cis(tag.contents);
1366 cis >> scale;
1367
1368 }
1369
1370
1371
1372
1373 void print(std::ostream & file) const {
1374 file << "<scale" << oattr("stype", stype);
1375 if ( emitter > 0 ) {
1376 std::ostringstream pos;
1377 pos << emitter;
1378 for ( std::set<int>::iterator it = recoilers.begin();
1379 it != recoilers.end(); ++it )
1380 pos << " " << *it;
1381 file << oattr("pos", pos.str());
1382 }
1383 if ( emitted.size() > 0 ) {
1384 std::set<int>::iterator it = emitted.begin();
1385 std::ostringstream eos;
1386 eos << *it;
1387 while ( ++it != emitted.end() ) eos << " " << *it;
1388 if ( eos.str() == "-5 -4 -3 -2 -1 1 2 3 4 5 21" )
1389 file << oattr("etype", std::string("QCD"));
1390 else if ( eos.str() == "-13 -12 -11 11 12 13 22 23 24" )
1391 file << oattr("etype", std::string("EW"));
1392 else
1393 file << oattr("etype", eos.str());
1394 }
1395 std::ostringstream os;
1396 os << scale;
1397 contents = os.str();
1398 closetag(file, "scale");
1399 }
1400
1401
1402
1403
1404
1405 std::string stype;
1406
1407
1408
1409
1410
1411
1412 int emitter;
1413
1414
1415
1416
1417 std::set<int> recoilers;
1418
1419
1420
1421
1422 std::set<int> emitted;
1423
1424
1425
1426
1427 double scale;
1428
1429 };
1430
1431
1432
1433
1434 struct Scales : public TagBase {
1435
1436
1437
1438
1439 Scales(double defscale = -1.0, int npart = 0)
1440 : muf(defscale), mur(defscale), mups(defscale), SCALUP(defscale) {
1441 (void) npart;
1442 }
1443
1444
1445
1446
1447 Scales(const XMLTag & tag, double defscale = -1.0, int npart = 0)
1448 : TagBase(tag.attr, tag.contents),
1449 muf(defscale), mur(defscale), mups(defscale),
1450 SCALUP(defscale) {
1451 getattr("muf", muf);
1452 getattr("mur", mur);
1453 getattr("mups", mups);
1454 for ( int i = 0, N = tag.tags.size(); i < N; ++i )
1455 if ( tag.tags[i]->name == "scale" )
1456 scales.push_back(Scale(*tag.tags[i]));
1457 for ( int i = 0; i < npart; ++i ) {
1458 std::ostringstream pttag;
1459 pttag << "pt_start_" << i + 1;
1460 double sc = 0.0;
1461 if ( getattr(pttag.str(), sc) )
1462 scales.push_back(Scale("start", i + 1, sc));
1463 }
1464
1465 }
1466
1467
1468
1469
1470 bool hasInfo() const {
1471 return muf != SCALUP || mur != SCALUP || mups != SCALUP ||
1472 !scales.empty();
1473 }
1474
1475
1476
1477
1478 void print(std::ostream & file) const {
1479 if ( !hasInfo() ) return;
1480 file << "<scales";
1481 if ( muf != SCALUP ) file << oattr("muf", muf);
1482 if ( mur != SCALUP ) file << oattr("mur", mur);
1483 if ( mups != SCALUP ) file << oattr("mups", mups);
1484 printattrs(file);
1485
1486 if ( !scales.empty() ) {
1487 std::ostringstream os;
1488 for ( int i = 0, N = scales.size(); i < N; ++i )
1489 scales[i].print(os);
1490 contents = os.str();
1491 }
1492 closetag(file, "scales");
1493 }
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507 double getScale(std::string st, int pdgem, int emr, int rec) const {
1508 for ( int i = 0, N = scales.size(); i < N; ++i ) {
1509 if ( scales[i].emitter == emr && st == scales[i].stype &&
1510 ( emr == rec ||
1511 scales[i].recoilers.find(rec) != scales[i].recoilers.end() ) &&
1512 scales[i].emitted.find(pdgem) != scales[i].emitted.end() )
1513 return scales[i].scale;
1514 }
1515 for ( int i = 0, N = scales.size(); i < N; ++i ) {
1516 if ( scales[i].emitter == emr && st == scales[i].stype &&
1517 ( emr == rec ||
1518 scales[i].recoilers.find(rec) != scales[i].recoilers.end() ) &&
1519 scales[i].emitted.empty() )
1520 return scales[i].scale;
1521 }
1522 if ( emr != rec ) return getScale(st, pdgem, emr, emr);
1523 if ( emr == rec ) return getScale(st, pdgem, 0, 0);
1524 return mups;
1525 }
1526
1527
1528
1529
1530 double muf;
1531
1532
1533
1534
1535 double mur;
1536
1537
1538
1539
1540
1541 double mups;
1542
1543
1544
1545
1546 double SCALUP;
1547
1548
1549
1550
1551 std::vector<Scale> scales;
1552
1553 };
1554
1555
1556
1557
1558 struct PDFInfo : public TagBase {
1559
1560
1561
1562
1563 PDFInfo(double defscale = -1.0)
1564 : p1(0), p2(0), x1(-1.0), x2(-1.0), xf1(-1.0), xf2(-1.0),
1565 scale(defscale), SCALUP(defscale) {}
1566
1567
1568
1569
1570 PDFInfo(const XMLTag & tag, double defscale = -1.0)
1571 : TagBase(tag.attr, tag.contents),
1572 p1(0), p2(0), x1(-1.0), x2(-1.0), xf1(-1.0), xf2(-1.0),
1573 scale(defscale), SCALUP(defscale) {
1574 getattr("scale", scale);
1575 getattr("p1", p1);
1576 getattr("p2", p2);
1577 getattr("x1", x1);
1578 getattr("x2", x2);
1579 }
1580
1581
1582
1583
1584 void print(std::ostream & file) const {
1585 if ( xf1 <= 0 ) return;
1586 file << "<pdfinfo";
1587 if ( p1 != 0 ) file << oattr("p1", p1);
1588 if ( p2 != 0 ) file << oattr("p2", p2);
1589 if ( x1 > 0 ) file << oattr("x1", x1);
1590 if ( x2 > 0 ) file << oattr("x2", x2);
1591 if ( scale != SCALUP ) file << oattr("scale", scale);
1592 printattrs(file);
1593 file << ">" << xf1 << " " << xf2 << "</pdfinfo>" << std::endl;
1594 }
1595
1596
1597
1598
1599 long p1;
1600
1601
1602
1603
1604 long p2;
1605
1606
1607
1608
1609 double x1;
1610
1611
1612
1613
1614 double x2;
1615
1616
1617
1618
1619 double xf1;
1620
1621
1622
1623
1624 double xf2;
1625
1626
1627
1628
1629 double scale;
1630
1631
1632
1633
1634 double SCALUP;
1635
1636 };
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646 class HEPRUP : public TagBase {
1647
1648 public:
1649
1650
1651
1652
1653
1654
1655 HEPRUP()
1656 : IDWTUP(0), NPRUP(0), version(3),
1657 dprec(std::numeric_limits<double>::digits10) {}
1658
1659
1660
1661
1662 HEPRUP(const HEPRUP &) = default;
1663
1664
1665
1666
1667 HEPRUP & operator=(const HEPRUP & ) = default;
1668
1669
1670
1671
1672 HEPRUP(const XMLTag & tagin, int versin)
1673 : TagBase(tagin.attr, tagin.contents), version(versin),
1674 dprec(std::numeric_limits<double>::digits10) {
1675
1676 std::vector<XMLTag*> tags = tagin.tags;
1677
1678
1679 std::istringstream iss(tags[0]->contents);
1680 if ( !( iss >> IDBMUP.first >> IDBMUP.second >> EBMUP.first >> EBMUP.second
1681 >> PDFGUP.first >> PDFGUP.second >> PDFSUP.first >> PDFSUP.second
1682 >> IDWTUP >> NPRUP ) ) {
1683 throw std::runtime_error("Could not parse init block "
1684 "in Les Houches Event File.");
1685 }
1686 resize();
1687
1688 for ( int i = 0; i < NPRUP; ++i ) {
1689 if ( !( iss >> XSECUP[i] >> XERRUP[i] >> XMAXUP[i] >> LPRUP[i] ) ) {
1690 throw std::runtime_error("Could not parse processes in init block "
1691 "in Les Houches Event File.");
1692 }
1693 }
1694
1695 for ( int i = 1, N = tags.size(); i < N; ++i ) {
1696 const XMLTag & tag = *tags[i];
1697
1698 if ( tag.name.empty() ) junk += tag.contents;
1699
1700 if ( tag.name == "initrwgt" ) {
1701 for ( int j = 0, M = tag.tags.size(); j < M; ++j ) {
1702 if ( tag.tags[j]->name == "weightgroup" )
1703 weightgroup.push_back(WeightGroup(*tag.tags[j], weightgroup.size(),
1704 weightinfo));
1705 if ( tag.tags[j]->name == "weight" )
1706 weightinfo.push_back(WeightInfo(*tag.tags[j]));
1707
1708 }
1709 }
1710 if ( tag.name == "weightinfo" ) {
1711 weightinfo.push_back(WeightInfo(tag));
1712 }
1713 if ( tag.name == "weightgroup" ) {
1714 weightgroup.push_back(WeightGroup(tag, weightgroup.size(),
1715 weightinfo));
1716 }
1717 if ( tag.name == "eventfiles" ) {
1718 for ( int j = 0, M = tag.tags.size(); j < M; ++j ) {
1719 XMLTag & eftag = *tag.tags[j];
1720 if ( eftag.name == "eventfile" )
1721 eventfiles.push_back(EventFile(eftag));
1722 }
1723 }
1724 if ( tag.name == "xsecinfo" ) {
1725 XSecInfo xsecinfo(tag);
1726 xsecinfos[xsecinfo.weightname] = xsecinfo;
1727 }
1728 if ( tag.name == "generator" ) {
1729 generators.push_back(Generator(tag));
1730 }
1731 else if ( tag.name == "cutsinfo" ) {
1732 for ( int j = 0, M = tag.tags.size(); j < M; ++j ) {
1733 XMLTag & ctag = *tag.tags[j];
1734
1735 if ( ctag.name == "ptype" ) {
1736 std::string tname = ctag.attr["name"];
1737 long id;
1738 std::istringstream isss(ctag.contents);
1739 while ( isss >> id ) ptypes[tname].insert(id);
1740 }
1741 else if ( ctag.name == "cut" )
1742 cuts.push_back(Cut(ctag, ptypes));
1743 }
1744 }
1745 else if ( tag.name == "procinfo" ) {
1746 ProcInfo proc(tag);
1747 procinfo[proc.iproc] = proc;
1748 }
1749 else if ( tag.name == "mergeinfo" ) {
1750 MergeInfo merge(tag);
1751 mergeinfo[merge.iproc] = merge;
1752 }
1753
1754 }
1755
1756 weightmap.clear();
1757 for ( int i = 0, N = weightinfo.size(); i < N; ++i )
1758 weightmap[weightinfo[i].name] = i + 1;
1759
1760 }
1761
1762
1763
1764 public:
1765
1766
1767
1768
1769
1770 std::string weightNameHepMC(int i) const {
1771 std::string name;
1772 if ( i < 0 || i >= (int)weightinfo.size() ) return name;
1773 if ( weightinfo[i].inGroup >= 0 )
1774 name = weightgroup[weightinfo[i].inGroup].type + "/"
1775 + weightgroup[weightinfo[i].inGroup].combine + "/";
1776 name += weightinfo[i].name;
1777 return name;
1778 }
1779
1780
1781
1782
1783
1784 void print(std::ostream & file) const {
1785
1786 file << std::setprecision(dprec);
1787
1788 file << "<init>\n"
1789 << " " << std::setw(8) << IDBMUP.first
1790 << " " << std::setw(8) << IDBMUP.second
1791 << " " << std::setw(14) << EBMUP.first
1792 << " " << std::setw(14) << EBMUP.second
1793 << " " << std::setw(4) << PDFGUP.first
1794 << " " << std::setw(4) << PDFGUP.second
1795 << " " << std::setw(4) << PDFSUP.first
1796 << " " << std::setw(4) << PDFSUP.second
1797 << " " << std::setw(4) << IDWTUP
1798 << " " << std::setw(4) << NPRUP << std::endl;
1799
1800 for ( int i = 0; i < NPRUP; ++i )
1801 file << " " << std::setw(14) << XSECUP[i]
1802 << " " << std::setw(14) << XERRUP[i]
1803 << " " << std::setw(14) << XMAXUP[i]
1804 << " " << std::setw(6) << LPRUP[i] << std::endl;
1805
1806 for ( int i = 0, N = generators.size(); i < N; ++i )
1807 generators[i].print(file);
1808
1809 if ( !eventfiles.empty() ) {
1810 file << "<eventfiles>\n";
1811 for ( int i = 0, N = eventfiles.size(); i < N; ++i )
1812 eventfiles[i].print(file);
1813 file << "</eventfiles>\n";
1814 }
1815
1816 if ( !xsecinfos.empty())
1817 for ( XSecInfos::const_iterator it = xsecinfos.begin();
1818 it != xsecinfos.end(); ++it )
1819 if ( it->second.neve > 0 ) it->second.print(file);
1820
1821 if ( cuts.size() > 0 ) {
1822 file << "<cutsinfo>" << std::endl;
1823
1824 for ( std::map<std::string, std::set<long> >::const_iterator ptit =
1825 ptypes.begin(); ptit != ptypes.end(); ++ptit ) {
1826 file << "<ptype" << oattr("name", ptit->first) << ">";
1827 for ( std::set<long>::const_iterator it = ptit->second.begin();
1828 it != ptit->second.end(); ++it )
1829 file << " " << *it;
1830 file << "</ptype>" << std::endl;
1831 }
1832
1833 for ( int i = 0, N = cuts.size(); i < N; ++i )
1834 cuts[i].print(file);
1835 file << "</cutsinfo>" << std::endl;
1836 }
1837
1838 for ( std::map<long,ProcInfo>::const_iterator it = procinfo.begin();
1839 it != procinfo.end(); ++it )
1840 it->second.print(file);
1841
1842 for ( std::map<long,MergeInfo>::const_iterator it = mergeinfo.begin();
1843 it != mergeinfo.end(); ++it )
1844 it->second.print(file);
1845
1846 bool isrwgt = false;
1847 int ingroup = -1;
1848 for ( int i = 0, N = weightinfo.size(); i < N; ++i ) {
1849 if ( weightinfo[i].isrwgt ) {
1850 if ( !isrwgt ) file << "<initrwgt>\n";
1851 isrwgt = true;
1852 } else {
1853 if ( isrwgt ) file << "</initrwgt>\n";
1854 isrwgt = false;
1855 }
1856 int group = weightinfo[i].inGroup;
1857 if ( group != ingroup ) {
1858 if ( ingroup != -1 ) file << "</weightgroup>\n";
1859 if ( group != -1 ) {
1860 file << "<weightgroup"
1861 << oattr("type", weightgroup[group].type);
1862 if ( !weightgroup[group].combine.empty() )
1863 file << oattr("combine", weightgroup[group].combine);
1864 file << ">\n";
1865 }
1866 ingroup = group;
1867 }
1868 weightinfo[i].print(file);
1869 }
1870 if ( ingroup != -1 ) file << "</weightgroup>\n";
1871 if ( isrwgt ) file << "</initrwgt>\n";
1872
1873
1874 file << hashline(junk) << "</init>" << std::endl;
1875
1876 }
1877
1878
1879
1880
1881 void clear() {
1882 procinfo.clear();
1883 mergeinfo.clear();
1884 weightinfo.clear();
1885 weightgroup.clear();
1886 cuts.clear();
1887 ptypes.clear();
1888 junk.clear();
1889 }
1890
1891
1892
1893
1894
1895
1896 void resize(int nrup) {
1897 NPRUP = nrup;
1898 resize();
1899 }
1900
1901
1902
1903
1904
1905
1906 void resize() {
1907 XSECUP.resize(NPRUP);
1908 XERRUP.resize(NPRUP);
1909 XMAXUP.resize(NPRUP);
1910 LPRUP.resize(NPRUP);
1911 }
1912
1913
1914
1915
1916 int weightIndex(const std::string & name) const {
1917 std::map<std::string, int>::const_iterator it = weightmap.find(name);
1918 if ( it != weightmap.end() ) return it->second;
1919 return 0;
1920 }
1921
1922
1923
1924
1925 int nWeights() const {
1926 return weightmap.size() + 1;
1927 }
1928
1929
1930
1931
1932
1933 XSecInfo & getXSecInfo(std::string weightname = "") {
1934 XSecInfo & xi = xsecinfos[weightname];
1935 xi.weightname = weightname;
1936 return xi;
1937 }
1938
1939
1940
1941
1942
1943
1944 const XSecInfo & getXSecInfo(std::string weightname = "") const {
1945 static XSecInfo noinfo;
1946 XSecInfos::const_iterator it = xsecinfos.find(weightname);
1947 if ( it != xsecinfos.end() ) return it->second;
1948 else return noinfo;
1949 }
1950
1951
1952 public:
1953
1954
1955
1956
1957 std::pair<long,long> IDBMUP;
1958
1959
1960
1961
1962 std::pair<double,double> EBMUP;
1963
1964
1965
1966
1967
1968 std::pair<int,int> PDFGUP;
1969
1970
1971
1972
1973
1974 std::pair<int,int> PDFSUP;
1975
1976
1977
1978
1979
1980
1981 int IDWTUP;
1982
1983
1984
1985
1986 int NPRUP;
1987
1988
1989
1990
1991 std::vector<double> XSECUP;
1992
1993
1994
1995
1996
1997 std::vector<double> XERRUP;
1998
1999
2000
2001
2002
2003 std::vector<double> XMAXUP;
2004
2005
2006
2007
2008 std::vector<int> LPRUP;
2009
2010
2011
2012
2013 XSecInfos xsecinfos;
2014
2015
2016
2017
2018
2019 std::vector<EventFile> eventfiles;
2020
2021
2022
2023
2024 std::vector<Cut> cuts;
2025
2026
2027
2028
2029 std::map<std::string, std::set<long> > ptypes;
2030
2031
2032
2033
2034 std::map<long,ProcInfo> procinfo;
2035
2036
2037
2038
2039 std::map<long,MergeInfo> mergeinfo;
2040
2041
2042
2043
2044
2045 std::vector<Generator> generators;
2046
2047
2048
2049
2050 std::vector<WeightInfo> weightinfo;
2051
2052
2053
2054
2055 std::map<std::string,int> weightmap;
2056
2057
2058
2059
2060 std::vector<WeightGroup> weightgroup;
2061
2062
2063
2064
2065 std::string junk;
2066
2067
2068
2069
2070 int version;
2071
2072
2073
2074
2075 int dprec;
2076
2077 };
2078
2079
2080
2081
2082 class HEPEUP;
2083
2084
2085
2086
2087
2088 struct EventGroup: public std::vector<HEPEUP*> {
2089
2090
2091
2092
2093 inline EventGroup(): nreal(-1), ncounter(-1) {}
2094
2095
2096
2097
2098 inline EventGroup(const EventGroup &);
2099
2100
2101
2102
2103 inline EventGroup & operator=(const EventGroup &);
2104
2105
2106
2107
2108 inline void clear();
2109
2110
2111
2112
2113 inline ~EventGroup();
2114
2115
2116
2117
2118 int nreal;
2119
2120
2121
2122
2123 int ncounter;
2124
2125 };
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136 class HEPEUP : public TagBase {
2137
2138 public:
2139
2140
2141
2142
2143
2144
2145 HEPEUP()
2146 : NUP(0), IDPRUP(0), XWGTUP(0.0), XPDWUP(0.0, 0.0),
2147 SCALUP(0.0), AQEDUP(0.0), AQCDUP(0.0), heprup(0), currentWeight(0),
2148 ntries(1), isGroup(false) {}
2149
2150
2151
2152
2153 HEPEUP(const HEPEUP & x)
2154 : TagBase(x), isGroup(false) {
2155 operator=(x);
2156 }
2157
2158
2159
2160
2161
2162 HEPEUP & setEvent(const HEPEUP & x) {
2163 NUP = x.NUP;
2164 IDPRUP = x.IDPRUP;
2165 XWGTUP = x.XWGTUP;
2166 XPDWUP = x.XPDWUP;
2167 SCALUP = x.SCALUP;
2168 AQEDUP = x.AQEDUP;
2169 AQCDUP = x.AQCDUP;
2170 IDUP = x.IDUP;
2171 ISTUP = x.ISTUP;
2172 MOTHUP = x.MOTHUP;
2173 ICOLUP = x.ICOLUP;
2174 PUP = x.PUP;
2175 VTIMUP = x.VTIMUP;
2176 SPINUP = x.SPINUP;
2177 heprup = x.heprup;
2178 namedweights = x.namedweights;
2179 weights = x.weights;
2180 pdfinfo = x.pdfinfo;
2181 PDFGUPsave = x.PDFGUPsave;
2182 PDFSUPsave = x.PDFSUPsave;
2183 clustering = x.clustering;
2184 scales = x.scales;
2185 junk = x.junk;
2186 currentWeight = x.currentWeight;
2187 ntries = x.ntries;
2188 return *this;
2189 }
2190
2191
2192
2193
2194 HEPEUP & operator=(const HEPEUP & x) {
2195 if ( &x == this ) return *this;
2196 TagBase::operator=(x);
2197 clear();
2198 setEvent(x);
2199 subevents = x.subevents;
2200 isGroup = x.isGroup;
2201 return *this;
2202 }
2203
2204
2205
2206
2207 ~HEPEUP() {
2208 clear();
2209 };
2210
2211
2212 public:
2213
2214
2215
2216
2217
2218 HEPEUP(const XMLTag & tagin, HEPRUP & heprupin)
2219 : TagBase(tagin.attr), NUP(0), IDPRUP(0), XWGTUP(0.0), XPDWUP(0.0, 0.0),
2220 SCALUP(0.0), AQEDUP(0.0), AQCDUP(0.0), heprup(&heprupin),
2221 currentWeight(0), ntries(1), isGroup(tagin.name == "eventgroup") {
2222
2223 if ( heprup->NPRUP < 0 )
2224 throw std::runtime_error("Tried to read events but no processes defined "
2225 "in init block of Les Houches file.");
2226
2227 std::vector<XMLTag*> tags = tagin.tags;
2228
2229 if ( isGroup ) {
2230 getattr("nreal", subevents.nreal);
2231 getattr("ncounter", subevents.ncounter);
2232 for ( int i = 0, N = tags.size(); i < N; ++i )
2233 if ( tags[i]->name == "event" )
2234 subevents.push_back(new HEPEUP(*tags[i], heprupin));
2235 return;
2236 } else
2237 getattr("ntries", ntries);
2238
2239
2240
2241
2242 std::istringstream iss(tags[0]->contents);
2243 if ( !( iss >> NUP >> IDPRUP >> XWGTUP >> SCALUP >> AQEDUP >> AQCDUP ) )
2244 throw std::runtime_error("Failed to parse event in Les Houches file.");
2245
2246 resize();
2247
2248
2249 for ( int i = 0; i < NUP; ++i ) {
2250 if ( !( iss >> IDUP[i] >> ISTUP[i] >> MOTHUP[i].first >> MOTHUP[i].second
2251 >> ICOLUP[i].first >> ICOLUP[i].second
2252 >> PUP[i][0] >> PUP[i][1] >> PUP[i][2]
2253 >> PUP[i][3] >> PUP[i][4]
2254 >> VTIMUP[i] >> SPINUP[i] ) )
2255 throw std::runtime_error("Failed to parse event in Les Houches file.");
2256 }
2257
2258 junk.clear();
2259 std::string ss;
2260 while ( getline(iss, ss) ) junk += ss + '\n';
2261
2262 scales = Scales(SCALUP, NUP);
2263 pdfinfo = PDFInfo(SCALUP);
2264 namedweights.clear();
2265 weights.clear();
2266 weights.resize(heprup->nWeights(),
2267 std::make_pair(XWGTUP, (WeightInfo*)(0)));
2268 weights.front().first = XWGTUP;
2269 for ( int i = 1, N = weights.size(); i < N; ++i )
2270 weights[i].second = &heprup->weightinfo[i - 1];
2271
2272 for ( int i = 1, N = tags.size(); i < N; ++i ) {
2273 XMLTag & tag = *tags[i];
2274
2275 if ( tag.name.empty() ) junk += tag.contents;
2276
2277 if ( tag.name == "weights" ) {
2278 weights.resize(heprup->nWeights(),
2279 std::make_pair(XWGTUP, (WeightInfo*)(0)));
2280 weights.front().first = XWGTUP;
2281 for ( int ii = 1, NN = weights.size(); ii < NN; ++ii )
2282 weights[ii].second = &heprup->weightinfo[ii - 1];
2283 double w = 0.0;
2284 int iii = 0;
2285 std::istringstream isss(tag.contents);
2286 while ( isss >> w )
2287 if ( ++iii < int(weights.size()) )
2288 weights[iii].first = w;
2289 else
2290 weights.push_back(std::make_pair(w, (WeightInfo*)(0)));
2291 }
2292 if ( tag.name == "weight" ) {
2293 namedweights.push_back(Weight(tag));
2294 }
2295 if ( tag.name == "rwgt" ) {
2296 for ( int j = 0, M = tag.tags.size(); j < M; ++j ) {
2297 if ( tag.tags[j]->name == "wgt" ) {
2298 namedweights.push_back(Weight(*tag.tags[j]));
2299 }
2300 }
2301 }
2302 else if ( tag.name == "clustering" ) {
2303 for ( int j = 0, M= tag.tags.size(); j < M; ++j ) {
2304 if ( tag.tags[j]->name == "clus" )
2305 clustering.push_back(Clus(*tag.tags[j]));
2306 }
2307 }
2308 else if ( tag.name == "pdfinfo" ) {
2309 pdfinfo = PDFInfo(tag, SCALUP);
2310 }
2311 else if ( tag.name == "scales" ) {
2312 scales = Scales(tag, SCALUP, NUP);
2313 }
2314
2315 }
2316
2317 for ( int i = 0, N = namedweights.size(); i < N; ++i ) {
2318 int indx = heprup->weightIndex(namedweights[i].name);
2319 if ( indx > 0 ) {
2320 weights[indx].first = namedweights[i].weights[0];
2321 namedweights[i].indices[0] = indx;
2322 } else {
2323 weights.push_back(std::make_pair(namedweights[i].weights[0],
2324 (WeightInfo*)(0)));
2325 namedweights[i].indices[0] = weights.size() - 1;
2326 }
2327 for ( int j = 1, M = namedweights[i].weights.size(); j < M; ++j ) {
2328 weights.push_back(std::make_pair(namedweights[i].weights[j],
2329 (WeightInfo*)(0)));
2330 namedweights[i].indices[j] = weights.size() - 1;
2331 }
2332 }
2333
2334 }
2335
2336
2337
2338
2339 void print(std::ostream & file) const {
2340
2341 file << std::setprecision(heprup->dprec);
2342
2343
2344 if ( isGroup ) {
2345 file << "<eventgroup";
2346 if ( subevents.nreal > 0 )
2347 file << oattr("nreal", subevents.nreal);
2348 if ( subevents.ncounter > 0 )
2349 file << oattr("ncounter", subevents.ncounter);
2350 printattrs(file);
2351 file << ">\n";
2352 for ( int i = 0, N = subevents.size(); i < N; ++i )
2353 subevents[i]->print(file);
2354 file << "</eventgroup>\n";
2355 return;
2356 }
2357
2358 file << "<event";
2359 if ( ntries > 1 ) file << oattr("ntries", ntries);
2360 printattrs(file);
2361 file << ">\n";
2362 file << " " << std::setw(4) << NUP
2363 << " " << std::setw(6) << IDPRUP
2364 << " " << std::setw(14) << XWGTUP
2365 << " " << std::setw(14) << SCALUP
2366 << " " << std::setw(14) << AQEDUP
2367 << " " << std::setw(14) << AQCDUP << "\n";
2368
2369 for ( int i = 0; i < NUP; ++i )
2370 file << " " << std::setw(8) << IDUP[i]
2371 << " " << std::setw(2) << ISTUP[i]
2372 << " " << std::setw(4) << MOTHUP[i].first
2373 << " " << std::setw(4) << MOTHUP[i].second
2374 << " " << std::setw(4) << ICOLUP[i].first
2375 << " " << std::setw(4) << ICOLUP[i].second
2376 << " " << std::setw(14) << PUP[i][0]
2377 << " " << std::setw(14) << PUP[i][1]
2378 << " " << std::setw(14) << PUP[i][2]
2379 << " " << std::setw(14) << PUP[i][3]
2380 << " " << std::setw(14) << PUP[i][4]
2381 << " " << std::setw(1) << VTIMUP[i]
2382 << " " << std::setw(1) << SPINUP[i] << std::endl;
2383
2384 if ( weights.size() > 0 ) {
2385 file << "<weights>";
2386 for ( int i = 1, N = weights.size(); i < N; ++i )
2387 file << " " << weights[i].first;
2388 file << "</weights>\n";
2389 }
2390
2391 bool iswgt = false;
2392 for ( int i = 0, N = namedweights.size(); i < N; ++i ) {
2393 if ( namedweights[i].iswgt ) {
2394 if ( !iswgt ) file << "<rwgt>\n";
2395 iswgt = true;
2396 } else {
2397 if ( iswgt ) file << "</rwgt>\n";
2398 iswgt = false;
2399 }
2400 for ( int j = 0, M = namedweights[i].indices.size(); j < M; ++j )
2401 namedweights[i].weights[j] = weight(namedweights[i].indices[j]);
2402 namedweights[i].print(file);
2403 }
2404 if ( iswgt ) file << "</rwgt>\n";
2405
2406 if ( !clustering.empty() ) {
2407 file << "<clustering>" << std::endl;
2408 for ( int i = 0, N = clustering.size(); i < N; ++i )
2409 clustering[i].print(file);
2410 file << "</clustering>" << std::endl;
2411 }
2412
2413 pdfinfo.print(file);
2414 scales.print(file);
2415
2416 file << hashline(junk) << "</event>\n";
2417
2418 }
2419
2420
2421
2422
2423 void reset() {
2424 setWeightInfo(0);
2425 NUP = 0;
2426 clustering.clear();
2427 weights.clear();
2428 }
2429
2430
2431
2432
2433 void clear() {
2434 reset();
2435 subevents.clear();
2436 }
2437
2438
2439
2440
2441
2442
2443 void resize(int nup) {
2444 NUP = nup;
2445 resize();
2446 }
2447
2448
2449
2450
2451
2452 double totalWeight(int i = 0) const {
2453 if ( subevents.empty() ) return weight(i);
2454 double w = 0.0;
2455 for ( int ii = 0, N = subevents.size(); ii < N; ++ii )
2456 w += subevents[ii]->weight(i);
2457 return w;
2458 }
2459
2460
2461
2462
2463
2464 double totalWeight(const std::string & name) const {
2465 return totalWeight(heprup->weightIndex(name));
2466 }
2467
2468
2469
2470
2471 double weight(int i = 0) const {
2472 return weights[i].first;
2473 }
2474
2475
2476
2477
2478 double weight(const std::string & name) const {
2479 return weight(heprup->weightIndex(name));
2480 }
2481
2482
2483
2484
2485 void setWeight(int i, double w) {
2486 weights[i].first = w;
2487 }
2488
2489
2490
2491 bool setWeight(const std::string & name, double w) {
2492 int i = heprup->weightIndex(name);
2493 if ( i >= int(weights.size()) ) return false;
2494 setWeight(i, w);
2495 return true;
2496 }
2497
2498
2499
2500
2501
2502
2503
2504 void resize() {
2505 IDUP.resize(NUP);
2506 ISTUP.resize(NUP);
2507 MOTHUP.resize(NUP);
2508 ICOLUP.resize(NUP);
2509 PUP.resize(NUP, std::vector<double>(5));
2510 VTIMUP.resize(NUP);
2511 SPINUP.resize(NUP);
2512 }
2513
2514
2515
2516
2517
2518 bool setWeightInfo(unsigned int i) {
2519 if ( i >= weights.size() ) return false;
2520 if ( currentWeight ) {
2521 scales.mur /= currentWeight->mur;
2522 scales.muf /= currentWeight->muf;
2523 heprup->PDFGUP = PDFGUPsave;
2524 heprup->PDFSUP = PDFSUPsave;
2525 }
2526 XWGTUP = weights[i].first;
2527 currentWeight = weights[i].second;
2528 if ( currentWeight ) {
2529 scales.mur *= currentWeight->mur;
2530 scales.muf *= currentWeight->muf;
2531 PDFGUPsave = heprup->PDFGUP;
2532 PDFSUPsave = heprup->PDFSUP;
2533 if ( currentWeight->pdf ) {
2534 heprup->PDFGUP.first = heprup->PDFGUP.second = 0;
2535 heprup->PDFSUP.first = heprup->PDFSUP.second = currentWeight->pdf;
2536 }
2537 if ( currentWeight->pdf2 ) {
2538 heprup->PDFSUP.second = currentWeight->pdf2;
2539 }
2540
2541 }
2542 return true;
2543 }
2544
2545
2546
2547
2548
2549 bool setSubEvent(unsigned int i) {
2550 if ( i > subevents.size() || subevents.empty() ) return false;
2551 if ( i == 0 ) {
2552 reset();
2553 weights = subevents[0]->weights;
2554 for ( int ii = 1, N = subevents.size(); ii < N; ++ii )
2555 for ( int j = 0, M = weights.size(); j < M; ++j )
2556 weights[j].first += subevents[ii]->weights[j].first;
2557 currentWeight = 0;
2558 } else {
2559 setEvent(*subevents[i - 1]);
2560 }
2561 return true;
2562 }
2563
2564 public:
2565
2566
2567
2568
2569 int NUP;
2570
2571
2572
2573
2574 int IDPRUP;
2575
2576
2577
2578
2579 double XWGTUP;
2580
2581
2582
2583
2584
2585
2586
2587 std::pair<double,double> XPDWUP;
2588
2589
2590
2591
2592
2593 double SCALUP;
2594
2595
2596
2597
2598 double AQEDUP;
2599
2600
2601
2602
2603 double AQCDUP;
2604
2605
2606
2607
2608 std::vector<long> IDUP;
2609
2610
2611
2612
2613 std::vector<int> ISTUP;
2614
2615
2616
2617
2618
2619 std::vector< std::pair<int,int> > MOTHUP;
2620
2621
2622
2623
2624
2625 std::vector< std::pair<int,int> > ICOLUP;
2626
2627
2628
2629
2630
2631 std::vector< std::vector<double> > PUP;
2632
2633
2634
2635
2636
2637 std::vector<double> VTIMUP;
2638
2639
2640
2641
2642
2643
2644 std::vector<double> SPINUP;
2645
2646
2647
2648
2649 HEPRUP * heprup;
2650
2651
2652
2653
2654 const WeightInfo * currentWeight;
2655
2656
2657
2658
2659 std::vector<Weight> namedweights;
2660
2661
2662
2663
2664 std::vector< std::pair<double, const WeightInfo *> > weights;
2665
2666
2667
2668
2669 std::vector<Clus> clustering;
2670
2671
2672
2673
2674 PDFInfo pdfinfo;
2675
2676
2677
2678
2679 std::pair<int,int> PDFGUPsave;
2680
2681
2682
2683
2684 std::pair<int,int> PDFSUPsave;
2685
2686
2687
2688
2689
2690 Scales scales;
2691
2692
2693
2694
2695
2696 int ntries;
2697
2698
2699
2700
2701 bool isGroup;
2702
2703
2704
2705
2706
2707 EventGroup subevents;
2708
2709
2710
2711
2712 std::string junk;
2713
2714 };
2715
2716
2717
2718
2719 inline void EventGroup::clear() {
2720 while ( size() > 0 ) {
2721 delete back();
2722 pop_back();
2723 }
2724 }
2725
2726 inline EventGroup::~EventGroup() {
2727 clear();
2728 }
2729
2730 inline EventGroup::EventGroup(const EventGroup & eg)
2731 : std::vector<HEPEUP*>(eg.size()),nreal(0),ncounter(0) {
2732 for ( int i = 0, N = eg.size(); i < N; ++i ) at(i) = new HEPEUP(*eg.at(i));
2733 }
2734
2735 inline EventGroup & EventGroup::operator=(const EventGroup & x) {
2736 if ( &x == this ) return *this;
2737 clear();
2738 nreal = x.nreal;
2739 ncounter = x.ncounter;
2740 for ( int i = 0, N = x.size(); i < N; ++i ) push_back(new HEPEUP(*x.at(i)));
2741 return *this;
2742 }
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761 class Reader {
2762
2763 public:
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775 Reader(std::istream & is)
2776 : file(&is), currevent(-1),
2777 curreventfile(-1), currfileevent(-1), dirpath("") {
2778 init();
2779 }
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791 Reader(std::string filename)
2792 : intstream(filename.c_str()), file(&intstream), currevent(-1),
2793 curreventfile(-1), currfileevent(-1), dirpath("") {
2794
2795 size_t slash = filename.find_last_of('/');
2796 if ( slash != std::string::npos ) dirpath = filename.substr(0, slash + 1);
2797 init();
2798 }
2799
2800 private:
2801
2802
2803
2804
2805
2806 void init() {
2807
2808
2809 initfile = file;
2810
2811 bool readingHeader = false;
2812 bool readingInit = false;
2813
2814
2815 getline();
2816 if ( !currentFind("<LesHouchesEvents") )
2817 throw std::runtime_error
2818 ("Tried to read a file which does not start with the "
2819 "LesHouchesEvents tag.");
2820 version = 1;
2821 if ( currentFind("version=\"3" ) )
2822 version = 3;
2823 else if ( currentFind("version=\"2" ) )
2824 version = 2;
2825 else if ( !currentFind("version=\"1" ) )
2826 throw std::runtime_error
2827 ("Tried to read a LesHouchesEvents file which is above version 3.");
2828
2829
2830 while ( getline() && !currentFind("</init>") ) {
2831 if ( currentFind("<header") ) {
2832
2833
2834
2835 readingHeader = true;
2836 headerBlock = currentLine + "\n";
2837 }
2838 else if ( currentFind("<init>") ) {
2839
2840 readingInit = true;
2841 initComments = currentLine + "\n";
2842 }
2843 else if ( currentFind("</header>") ) {
2844
2845
2846 readingHeader = false;
2847 headerBlock += currentLine + "\n";
2848 }
2849 else if ( readingHeader ) {
2850
2851
2852 headerBlock += currentLine + "\n";
2853 }
2854 else if ( readingInit ) {
2855
2856 initComments += currentLine + "\n";
2857 }
2858 else {
2859
2860 outsideBlock += currentLine + "\n";
2861 }
2862 }
2863 if ( !currentFind("</init>") )
2864 throw std::runtime_error("Found incomplete init tag in "
2865 "Les Houches file.");
2866 initComments += currentLine + "\n";
2867 std::vector<XMLTag*> tags = XMLTag::findXMLTags(initComments);
2868 for ( int i = 0, N = tags.size(); i < N; ++i )
2869 if ( tags[i]->name == "init" ) {
2870 heprup = HEPRUP(*tags[i], version);
2871 break;
2872 }
2873 XMLTag::deleteAll(tags);
2874
2875 if ( !heprup.eventfiles.empty() ) openeventfile(0);
2876
2877 }
2878
2879 public:
2880
2881
2882
2883
2884
2885
2886
2887 bool readEvent() {
2888
2889
2890
2891 if ( heprup.NPRUP < 0 ) return false;
2892
2893 std::string eventLines;
2894 int inEvent = 0;
2895
2896
2897 while ( getline() ) {
2898 if ( inEvent ) {
2899 eventLines += currentLine + "\n";
2900 if ( inEvent == 1 && currentFind("</event>") ) break;
2901 if ( inEvent == 2 && currentFind("</eventgroup>") ) break;
2902 }
2903 else if ( currentFind("<eventgroup") ) {
2904 eventLines += currentLine + "\n";
2905 inEvent = 2;
2906 }
2907 else if ( currentFind("<event") ) {
2908 eventLines += currentLine + "\n";
2909 inEvent = 1;
2910 }
2911 else {
2912 outsideBlock += currentLine + "\n";
2913 }
2914 }
2915 if ( ( inEvent == 1 && !currentFind("</event>") ) ||
2916 ( inEvent == 2 && !currentFind("</eventgroup>") ) ) {
2917 if ( heprup.eventfiles.empty() ||
2918 ++curreventfile >= int(heprup.eventfiles.size()) ) return false;
2919 openeventfile(curreventfile);
2920 return readEvent();
2921 }
2922
2923 std::vector<XMLTag*> tags = XMLTag::findXMLTags(eventLines);
2924
2925 for ( int i = 0, N = tags.size(); i < N ; ++i ) {
2926 if ( tags[i]->name == "event" || tags[i]->name == "eventgroup" ) {
2927 hepeup = HEPEUP(*tags[i], heprup);
2928 XMLTag::deleteAll(tags);
2929 ++currevent;
2930 if ( curreventfile >= 0 ) ++currfileevent;
2931 return true;
2932 }
2933 }
2934
2935 if ( !heprup.eventfiles.empty() &&
2936 ++curreventfile < int(heprup.eventfiles.size()) ) {
2937 openeventfile(curreventfile);
2938 XMLTag::deleteAll(tags);
2939 return readEvent();
2940 }
2941
2942 XMLTag::deleteAll(tags);
2943 return false;
2944
2945 }
2946
2947
2948
2949
2950
2951
2952 void openeventfile(int ifile) {
2953 std::cerr << "opening file " << ifile << std::endl;
2954 efile.close();
2955 std::string fname = heprup.eventfiles[ifile].filename;
2956 if ( fname[0] != '/' ) fname = dirpath + fname;
2957 efile.open(fname.c_str());
2958 if ( !efile ) throw std::runtime_error("Could not open event file " +
2959 fname);
2960 file = &efile;
2961 curreventfile = ifile;
2962 currfileevent = 0;
2963 }
2964
2965 protected:
2966
2967
2968
2969
2970 bool getline() {
2971 return ( (bool)std::getline(*file, currentLine) );
2972 }
2973
2974
2975
2976
2977 bool currentFind(std::string str) const {
2978 return currentLine.find(str) != std::string::npos;
2979 }
2980
2981 protected:
2982
2983
2984
2985
2986
2987 std::ifstream intstream;
2988
2989
2990
2991
2992
2993
2994 std::istream * file;
2995
2996
2997
2998
2999 std::istream * initfile;
3000
3001
3002
3003
3004 std::ifstream efile;
3005
3006
3007
3008
3009 std::string currentLine;
3010
3011 public:
3012
3013
3014
3015 std::ios_base::iostate initfile_rdstate() const {
3016 if (initfile) return initfile->rdstate();
3017 return std::ifstream::goodbit;
3018 }
3019
3020
3021
3022
3023 std::ios_base::iostate file_rdstate() const {
3024 if (file) return file->rdstate();
3025 return std::ifstream::goodbit;
3026 }
3027
3028
3029
3030
3031 int version;
3032
3033
3034
3035
3036
3037 std::string outsideBlock;
3038
3039
3040
3041
3042 std::string headerBlock;
3043
3044
3045
3046
3047 HEPRUP heprup;
3048
3049
3050
3051
3052 std::string initComments;
3053
3054
3055
3056
3057 HEPEUP hepeup;
3058
3059
3060
3061
3062 std::string eventComments;
3063
3064
3065
3066
3067 int currevent;
3068
3069
3070
3071
3072
3073 int curreventfile;
3074
3075
3076
3077
3078 int currfileevent;
3079
3080
3081
3082
3083 std::string dirpath;
3084
3085 private:
3086
3087
3088
3089
3090 Reader();
3091
3092
3093
3094
3095 Reader(const Reader &);
3096
3097
3098
3099
3100 Reader & operator=(const Reader &);
3101
3102 };
3103
3104
3105
3106
3107
3108
3109
3110
3111
3112
3113
3114
3115
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125 class Writer {
3126
3127 public:
3128
3129
3130
3131
3132
3133 Writer(std::ostream & os)
3134 : file(&os), initfile(&os), lastevent(-1), curreventfile(-1),
3135 currfileevent(-1), dirpath("") {}
3136
3137
3138
3139
3140
3141 Writer(std::string filename)
3142 : intstream(filename.c_str()), file(&intstream), initfile(&intstream),
3143 lastevent(-1), curreventfile(-1), currfileevent(-1), dirpath("") {
3144 size_t slash = filename.find_last_of('/');
3145 if ( slash != std::string::npos ) dirpath = filename.substr(0, slash + 1);
3146 }
3147
3148
3149
3150
3151 ~Writer() {
3152 file = initfile;
3153 if ( !heprup.eventfiles.empty() ) {
3154 if ( curreventfile >= 0 &&
3155 curreventfile < int(heprup.eventfiles.size()) &&
3156 heprup.eventfiles[curreventfile].neve < 0 )
3157 heprup.eventfiles[curreventfile].neve = currfileevent;
3158 writeinit();
3159 }
3160 *file << "</LesHouchesEvents>" << std::endl;
3161 }
3162
3163
3164
3165
3166 std::ostream & headerBlock() {
3167 return headerStream;
3168 }
3169
3170
3171
3172
3173 std::ostream & initComments() {
3174 return initStream;
3175 }
3176
3177
3178
3179
3180 std::ostream & eventComments() {
3181 return eventStream;
3182 }
3183
3184
3185
3186 void headerBlock(const std::string& a) {
3187 headerStream<<a;;
3188 }
3189
3190
3191
3192
3193 void initComments(const std::string& a) {
3194 initStream<<a;
3195 }
3196
3197
3198
3199
3200 void eventComments(const std::string& a) {
3201 eventStream<<a;
3202 }
3203
3204
3205
3206
3207 void init() {
3208 if ( heprup.eventfiles.empty() ) writeinit();
3209 lastevent = 0;
3210 curreventfile = currfileevent = -1;
3211 if ( !heprup.eventfiles.empty() ) openeventfile(0);
3212 }
3213
3214
3215
3216
3217 bool openeventfile(int ifile) {
3218 if ( heprup.eventfiles.empty() ) return false;
3219 if ( ifile < 0 || ifile >= int(heprup.eventfiles.size()) ) return false;
3220 if ( curreventfile >= 0 ) {
3221 EventFile & ef = heprup.eventfiles[curreventfile];
3222 if ( ef.neve > 0 && ef.neve != currfileevent )
3223 std::cerr << "LHEF::Writer number of events in event file "
3224 << ef.filename << " does not match the given number."
3225 << std::endl;
3226 ef.neve = currfileevent;
3227 }
3228 efile.close();
3229 std::string fname = heprup.eventfiles[ifile].filename;
3230 if ( fname[0] != '/' ) fname = dirpath + fname;
3231 efile.open(fname.c_str());
3232 if ( !efile ) throw std::runtime_error("Could not open event file " +
3233 fname);
3234 std::cerr << "Opened event file " << fname << std::endl;
3235 file = &efile;
3236 curreventfile = ifile;
3237 currfileevent = 0;
3238 return true;
3239 }
3240
3241
3242
3243
3244
3245
3246 void writeinit() {
3247
3248
3249 if ( heprup.version == 3 )
3250 *file << "<LesHouchesEvents version=\"3.0\">\n";
3251 else if ( heprup.version == 2 )
3252 *file << "<LesHouchesEvents version=\"2.0\">\n";
3253 else
3254 *file << "<LesHouchesEvents version=\"1.0\">\n";
3255
3256
3257 *file << std::setprecision(10);
3258
3259 std::string headBlock = headerStream.str();
3260 if ( headBlock.length() ) {
3261 if ( headBlock.find("<header>") == std::string::npos )
3262 *file << "<header>\n";
3263 if ( headBlock[headBlock.length() - 1] != '\n' )
3264 headBlock += '\n';
3265 *file << headBlock;
3266 if ( headBlock.find("</header>") == std::string::npos )
3267 *file << "</header>\n";
3268 }
3269
3270 heprup.print(*file);
3271
3272 }
3273
3274
3275
3276
3277 void writeEvent() {
3278
3279 if ( !heprup.eventfiles.empty() ) {
3280 if ( currfileevent == heprup.eventfiles[curreventfile].neve &&
3281 curreventfile + 1 < int(heprup.eventfiles.size()) )
3282 openeventfile(curreventfile + 1);
3283 }
3284
3285 hepeup.print(*file);
3286
3287 ++lastevent;
3288 ++currfileevent;
3289 }
3290
3291 protected:
3292
3293
3294
3295
3296
3297 std::ofstream intstream;
3298
3299
3300
3301
3302
3303 std::ostream * file;
3304
3305
3306
3307
3308 std::ostream * initfile;
3309
3310
3311
3312
3313 std::ofstream efile;
3314
3315
3316
3317
3318 int lastevent;
3319
3320
3321
3322
3323
3324 int curreventfile;
3325
3326
3327
3328
3329 int currfileevent;
3330
3331
3332
3333
3334 std::string dirpath;
3335
3336 public:
3337
3338
3339
3340 HEPRUP heprup;
3341
3342
3343
3344
3345
3346 HEPEUP hepeup;
3347
3348
3349
3350 private:
3351
3352
3353
3354
3355 std::ostringstream headerStream;
3356
3357
3358
3359
3360 std::ostringstream initStream;
3361
3362
3363
3364
3365 std::ostringstream eventStream;
3366
3367
3368
3369
3370
3371 Writer();
3372
3373
3374
3375
3376 Writer(const Writer &);
3377
3378
3379
3380
3381 Writer & operator=(const Writer &);
3382
3383 };
3384
3385 }
3386
3387
3388
3389
3390
3391
3392
3393
3394
3395
3396
3397
3398
3399
3400
3401
3402
3403
3404
3405
3406
3407
3408
3409
3410
3411
3412
3413
3414
3415
3416
3417
3418
3419
3420
3421
3422
3423
3424
3425
3426
3427
3428
3429
3430
3431
3432
3433
3434
3435
3436
3437 #endif