Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 14:28:51

0001 #include <algorithm>
0002 #include <iterator>
0003 #include <iostream>
0004 #include <iomanip>
0005 #include <sstream>
0006 #include <string>
0007 #include <cmath>
0008 #include <map>
0009 #include <set>
0010 
0011 #include "FWCore/Utilities/interface/Exception.h"
0012 
0013 #include "SimDataFormats/GeneratorProducts/interface/LesHouches.h"
0014 #include "SimDataFormats/GeneratorProducts/interface/LHERunInfoProduct.h"
0015 
0016 bool LHERunInfoProduct::const_iterator::operator==(const const_iterator &other) const {
0017   if (mode != other.mode)
0018     return false;
0019 
0020   switch (mode) {
0021     case kFooter:
0022     case kDone:
0023       return true;
0024 
0025     case kHeader:
0026       return header == other.header;
0027 
0028     case kBody:
0029       return header == other.header && iter == other.iter;
0030 
0031     case kInit:
0032       return line == other.line;
0033   }
0034 
0035   return false;
0036 }
0037 
0038 void LHERunInfoProduct::const_iterator::next() {
0039   tmp.clear();
0040 
0041   do {
0042     switch (mode) {
0043       case kHeader:
0044         if (header == runInfo->headers_end()) {
0045           if (line++ == 1)
0046             tmp = "</header>\n";
0047           else {
0048             mode = kInit;
0049             tmp = "<init>\n";
0050             line = 0;
0051           }
0052           break;
0053         } else if (!line) {
0054           line++;
0055           tmp = "<header>\n";
0056           break;
0057         } else {
0058           mode = kBody;
0059           const std::string &tag = header->tag();
0060           tmp = tag.empty() ? "<!--" : (tag == "<>") ? "" : ("<" + tag + ">");
0061           iter = header->begin();
0062           continue;
0063         }
0064 
0065       case kBody:
0066         if (iter == header->end()) {
0067           mode = kHeader;
0068           const std::string &tag = header->tag();
0069           tmp += tag.empty() ? "-->" : (tag == "<>") ? "" : ("</" + tag + ">");
0070           tmp += "\n";
0071           header++;
0072         } else {
0073           tmp += *iter++;
0074           if (iter == header->end() &&
0075               (tmp.empty() || (tmp[tmp.length() - 1] != '\r' && tmp[tmp.length() - 1] != '\n')))
0076             continue;
0077         }
0078         break;
0079 
0080       case kInit: {
0081         const lhef::HEPRUP &heprup = runInfo->heprup();
0082         if (!line++) {
0083           std::ostringstream ss;
0084           ss << std::setprecision(7) << std::scientific << std::uppercase << "    " << heprup.IDBMUP.first << "  "
0085              << heprup.IDBMUP.second << "  " << heprup.EBMUP.first << "  " << heprup.EBMUP.second << "  "
0086              << heprup.PDFGUP.first << "  " << heprup.PDFGUP.second << "  " << heprup.PDFSUP.first << "  "
0087              << heprup.PDFSUP.second << "  " << heprup.IDWTUP << "  " << heprup.NPRUP << std::endl;
0088           tmp = ss.str();
0089           break;
0090         }
0091         if (line >= (unsigned int)heprup.NPRUP + runInfo->comments_size() + 2) {
0092           tmp = "</init>\n";
0093           mode = kFooter;
0094           break;
0095         } else if (line >= (unsigned int)heprup.NPRUP + 2) {
0096           tmp = *(runInfo->comments_begin() + (line - (unsigned int)heprup.NPRUP - 2));
0097           break;
0098         }
0099 
0100         std::ostringstream ss;
0101         ss << std::setprecision(7) << std::scientific << std::uppercase << "\t" << heprup.XSECUP[line - 2] << "\t"
0102            << heprup.XERRUP[line - 2] << "\t" << heprup.XMAXUP[line - 2] << "\t" << heprup.LPRUP[line - 2] << std::endl;
0103         tmp = ss.str();
0104       } break;
0105 
0106       case kFooter:
0107         mode = kDone;
0108 
0109       default:
0110           /* ... */;
0111     }
0112   } while (false);
0113 }
0114 
0115 LHERunInfoProduct::const_iterator LHERunInfoProduct::begin() const {
0116   const_iterator result;
0117 
0118   result.runInfo = this;
0119   result.header = headers_begin();
0120   result.mode = const_iterator::kHeader;
0121   result.line = 0;
0122   result.tmp = "<LesHouchesEvents version=\"1.0\">\n";
0123 
0124   return result;
0125 }
0126 
0127 LHERunInfoProduct::const_iterator LHERunInfoProduct::init() const {
0128   const_iterator result;
0129 
0130   result.runInfo = this;
0131   result.mode = const_iterator::kInit;
0132   result.line = 0;
0133   result.tmp = "<init>\n";
0134 
0135   return result;
0136 }
0137 
0138 const std::string &LHERunInfoProduct::endOfFile() {
0139   static const std::string theEnd("</LesHouchesEvents>\n");
0140 
0141   return theEnd;
0142 }
0143 
0144 namespace {
0145   struct XSec {
0146     inline XSec() : xsec(0.0), err(0.0), max(0.0) {}
0147 
0148     double xsec;
0149     double err;
0150     double max;
0151   };
0152 
0153   struct HeaderLess {
0154     bool operator()(const LHERunInfoProduct::Header &a, const LHERunInfoProduct::Header &b) const;
0155   };
0156 }  // namespace
0157 
0158 bool HeaderLess::operator()(const LHERunInfoProduct::Header &a, const LHERunInfoProduct::Header &b) const {
0159   if (a == b)
0160     return false;
0161   if (a.tag() < b.tag())
0162     return true;
0163   if (a.tag() > b.tag())
0164     return false;
0165 
0166   LHERunInfoProduct::Header::const_iterator iter1 = a.begin();
0167   LHERunInfoProduct::Header::const_iterator iter2 = b.begin();
0168 
0169   for (; iter1 != a.end() && iter2 != b.end(); ++iter1, ++iter2) {
0170     if (*iter1 < *iter2)
0171       return true;
0172     else if (*iter1 != *iter2)
0173       return false;
0174   }
0175 
0176   return iter2 != b.end();
0177 }
0178 
0179 static std::vector<std::string> checklist{"iseed", "Random", ".log", ".dat", ".lhe"};
0180 static std::vector<std::string> tag_comparison_checklist{"", "MGRunCard", "mgruncard"};
0181 
0182 bool LHERunInfoProduct::find_if_checklist(const std::string x, std::vector<std::string> checklist) {
0183   return checklist.end() != std::find_if(checklist.begin(), checklist.end(), [&](const std::string &y) {
0184            return x.find(y) != std::string::npos;
0185          });
0186 }
0187 
0188 bool LHERunInfoProduct::isTagComparedInMerge(const std::string &tag) {
0189   return !(tag.empty() || tag.find("Alpgen") == 0 || tag == "MGGridCard" || tag == "MGRunCard" || tag == "mgruncard" ||
0190            tag == "MadSpin" || tag == "madspin");
0191 }
0192 
0193 bool LHERunInfoProduct::mergeProduct(const LHERunInfoProduct &other) {
0194   if (heprup_.IDBMUP != other.heprup_.IDBMUP || heprup_.EBMUP != other.heprup_.EBMUP ||
0195       heprup_.PDFGUP != other.heprup_.PDFGUP || heprup_.PDFSUP != other.heprup_.PDFSUP ||
0196       heprup_.IDWTUP != other.heprup_.IDWTUP) {
0197     return false;
0198   }
0199 
0200   bool compatibleHeaders = (headers_ == other.headers_);
0201 
0202   // try to merge not equal but compatible headers (i.e. different iseed)
0203   while (!compatibleHeaders) {
0204     // okay, something is not the same.
0205     // Let's try to merge, but don't duplicate identical headers
0206     // and test the rest against a whitelist
0207 
0208     std::set<Header, HeaderLess> headers;
0209     std::copy(headers_begin(), headers_end(), std::inserter(headers, headers.begin()));
0210 
0211     // make a list of headers contained in the second file
0212     std::vector<std::vector<std::string> > runcard_v2;
0213     std::vector<std::string> runcard_v2_header;
0214     for (const auto &header2 : headers_) {
0215       // fill a vector with the relevant header tags that can be not equal but sill compatible
0216       if (find_if_checklist(header2.tag(), tag_comparison_checklist)) {
0217         runcard_v2.push_back(header2.lines());
0218         runcard_v2_header.push_back(header2.tag());
0219       }
0220     }
0221 
0222     // loop over the headers of the original file
0223     bool failed = false;
0224     for (std::vector<LHERunInfoProduct::Header>::const_iterator header = other.headers_begin();
0225          header != other.headers_end();
0226          ++header) {
0227       if (headers.count(*header)) {
0228         continue;
0229       }
0230 
0231       if (find_if_checklist(header->tag(), tag_comparison_checklist)) {
0232         bool header_compatible = false;
0233         for (unsigned int iter_runcard = 0; iter_runcard < runcard_v2.size(); iter_runcard++) {
0234           std::vector<std::string> runcard_v1 = header->lines();
0235           runcard_v1.erase(std::remove_if(runcard_v1.begin(),
0236                                           runcard_v1.end(),
0237                                           [&](const std::string &x) { return find_if_checklist(x, checklist); }),
0238                            runcard_v1.end());
0239           runcard_v2[iter_runcard].erase(
0240               std::remove_if(runcard_v2[iter_runcard].begin(),
0241                              runcard_v2[iter_runcard].end(),
0242                              [&](const std::string &x) { return find_if_checklist(x, checklist); }),
0243               runcard_v2[iter_runcard].end());
0244 
0245           if (std::equal(runcard_v1.begin(), runcard_v1.end(), runcard_v2[iter_runcard].begin())) {
0246             header_compatible = true;
0247             break;
0248           }
0249         }
0250         if (header_compatible)
0251           continue;
0252       }
0253 
0254       if (isTagComparedInMerge(header->tag())) {
0255         failed = true;
0256       } else {
0257         addHeader(*header);
0258         headers.insert(*header);
0259       }
0260     }
0261 
0262     if (failed) {
0263       break;
0264     }
0265 
0266     compatibleHeaders = true;
0267   }
0268 
0269   // still not compatible after fixups
0270   if (!compatibleHeaders) {
0271     return false;
0272   }
0273 
0274   // it is exactly the same, so merge
0275   return true;
0276 }
0277 
0278 void LHERunInfoProduct::swap(LHERunInfoProduct &other) {
0279   heprup_.swap(other.heprup_);
0280   headers_.swap(other.headers_);
0281   comments_.swap(other.comments_);
0282 }