Go to the documentation of this file.00001 #include <algorithm>
00002 #include <iterator>
00003 #include <iostream>
00004 #include <iomanip>
00005 #include <sstream>
00006 #include <string>
00007 #include <cmath>
00008 #include <map>
00009 #include <set>
00010
00011 #include "FWCore/Utilities/interface/Exception.h"
00012
00013 #include "SimDataFormats/GeneratorProducts/interface/LesHouches.h"
00014 #include "SimDataFormats/GeneratorProducts/interface/LHERunInfoProduct.h"
00015
00016 bool LHERunInfoProduct::const_iterator::operator ==
00017 (const const_iterator &other) const
00018 {
00019 if (mode != other.mode)
00020 return false;
00021
00022 switch(mode) {
00023 case kFooter:
00024 case kDone:
00025 return true;
00026
00027 case kHeader:
00028 return header == other.header;
00029
00030 case kBody:
00031 return header == other.header && iter == other.iter;
00032
00033 case kInit:
00034 return line == other.line;
00035 }
00036
00037 return false;
00038 }
00039
00040 void LHERunInfoProduct::const_iterator::next()
00041 {
00042 tmp.clear();
00043
00044 do {
00045 switch(mode) {
00046 case kHeader:
00047 if (header == runInfo->headers_end()) {
00048 if (line++ == 1)
00049 tmp = "</header>\n";
00050 else {
00051 mode = kInit;
00052 tmp = "<init>\n";
00053 line = 0;
00054 }
00055 break;
00056 } else if (!line) {
00057 line++;
00058 tmp = "<header>\n";
00059 break;
00060 } else {
00061 mode = kBody;
00062 const std::string &tag = header->tag();
00063 tmp = tag.empty() ? "<!--" :
00064 (tag == "<>") ? "" : ("<" + tag + ">");
00065 iter = header->begin();
00066 continue;
00067 }
00068
00069 case kBody:
00070 if (iter == header->end()) {
00071 mode = kHeader;
00072 const std::string &tag = header->tag();
00073 tmp += tag.empty() ? "-->" :
00074 (tag == "<>") ? "" : ("</" + tag + ">");
00075 tmp += "\n";
00076 header++;
00077 } else {
00078 tmp += *iter++;
00079 if (iter == header->end() &&
00080 (tmp.empty() ||
00081 (tmp[tmp.length() - 1] != '\r' &&
00082 tmp[tmp.length() - 1] != '\n')))
00083 continue;
00084 }
00085 break;
00086
00087 case kInit: {
00088 const lhef::HEPRUP &heprup = runInfo->heprup();
00089 if (!line++) {
00090 std::ostringstream ss;
00091 ss << std::setprecision(7)
00092 << std::scientific
00093 << std::uppercase
00094 << " " << heprup.IDBMUP.first
00095 << " " << heprup.IDBMUP.second
00096 << " " << heprup.EBMUP.first
00097 << " " << heprup.EBMUP.second
00098 << " " << heprup.PDFGUP.first
00099 << " " << heprup.PDFGUP.second
00100 << " " << heprup.PDFSUP.first
00101 << " " << heprup.PDFSUP.second
00102 << " " << heprup.IDWTUP
00103 << " " << heprup.NPRUP << std::endl;
00104 tmp = ss.str();
00105 break;
00106 }
00107 if (line >= (unsigned int)heprup.NPRUP +
00108 runInfo->comments_size() + 2) {
00109 tmp = "</init>\n";
00110 mode = kFooter;
00111 break;
00112 } else if (line >= (unsigned int)heprup.NPRUP + 2) {
00113 tmp = *(runInfo->comments_begin() + (line -
00114 (unsigned int)heprup.NPRUP - 2));
00115 break;
00116 }
00117
00118 std::ostringstream ss;
00119 ss << std::setprecision(7)
00120 << std::scientific
00121 << std::uppercase
00122 << "\t" << heprup.XSECUP[line - 2]
00123 << "\t" << heprup.XERRUP[line - 2]
00124 << "\t" << heprup.XMAXUP[line - 2]
00125 << "\t" << heprup.LPRUP[line - 2] << std::endl;
00126 tmp = ss.str();
00127 } break;
00128
00129 case kFooter:
00130 mode = kDone;
00131
00132 default:
00133 ;
00134 }
00135 } while(false);
00136 }
00137
00138 LHERunInfoProduct::const_iterator LHERunInfoProduct::begin() const
00139 {
00140 const_iterator result;
00141
00142 result.runInfo = this;
00143 result.header = headers_begin();
00144 result.mode = const_iterator::kHeader;
00145 result.line = 0;
00146 result.tmp = "<LesHouchesEvents version=\"1.0\">\n";
00147
00148 return result;
00149 }
00150
00151 LHERunInfoProduct::const_iterator LHERunInfoProduct::init() const
00152 {
00153 const_iterator result;
00154
00155 result.runInfo = this;
00156 result.mode = const_iterator::kInit;
00157 result.line = 0;
00158 result.tmp = "<init>\n";
00159
00160 return result;
00161 }
00162
00163 const std::string &LHERunInfoProduct::endOfFile()
00164 {
00165 static const std::string theEnd("</LesHouchesEvents>\n");
00166
00167 return theEnd;
00168 }
00169
00170 namespace {
00171 struct XSec {
00172 inline XSec() : xsec(0.0), err(0.0), max(0.0) {}
00173
00174 double xsec;
00175 double err;
00176 double max;
00177 };
00178
00179 struct HeaderLess {
00180 bool operator() (const LHERunInfoProduct::Header &a,
00181 const LHERunInfoProduct::Header &b) const;
00182 };
00183 }
00184
00185 bool HeaderLess::operator() (const LHERunInfoProduct::Header &a,
00186 const LHERunInfoProduct::Header &b) const
00187 {
00188 if (a == b)
00189 return false;
00190 if (a.tag() < b.tag())
00191 return true;
00192 if (a.tag() > b.tag())
00193 return false;
00194
00195 LHERunInfoProduct::Header::const_iterator iter1 = a.begin();
00196 LHERunInfoProduct::Header::const_iterator iter2 = b.begin();
00197
00198 for(; iter1 != a.end() && iter2 != b.end(); ++iter1, ++iter2) {
00199 if (*iter1 < *iter2)
00200 return true;
00201 else if (*iter1 != *iter2)
00202 return false;
00203 }
00204
00205 return iter2 != b.end();
00206 }
00207
00208 bool LHERunInfoProduct::isTagComparedInMerge(const std::string& tag) {
00209 return !(tag == "" || tag.find("Alpgen") == 0 || tag == "MGGridCard" || tag == "MGGenerationInfo");
00210 }
00211
00212 bool LHERunInfoProduct::mergeProduct(const LHERunInfoProduct &other)
00213 {
00214 if (heprup_.IDBMUP != other.heprup_.IDBMUP ||
00215 heprup_.EBMUP != other.heprup_.EBMUP ||
00216 heprup_.PDFGUP != other.heprup_.PDFGUP ||
00217 heprup_.PDFSUP != other.heprup_.PDFSUP ||
00218 heprup_.IDWTUP != other.heprup_.IDWTUP) {
00219 throw cms::Exception("ProductsNotMergeable")
00220 << "Error in LHERunInfoProduct: LHE headers differ. "
00221 "Cannot merge products." << std::endl;
00222 }
00223
00224 bool compatibleHeaders = headers_ == other.headers_;
00225
00226
00227 while(!compatibleHeaders) {
00228
00229
00230
00231
00232 std::set<Header, HeaderLess> headers;
00233 std::copy(headers_begin(), headers_end(),
00234 std::inserter(headers, headers.begin()));
00235
00236 bool failed = false;
00237 for(std::vector<LHERunInfoProduct::Header>::const_iterator
00238 header = other.headers_begin();
00239 header != other.headers_end(); ++header) {
00240 if (headers.count(*header)) {
00241 continue;
00242 }
00243
00244 if(isTagComparedInMerge(header->tag())) {
00245 failed = true;
00246 } else {
00247 addHeader(*header);
00248 headers.insert(*header);
00249 }
00250 }
00251 if (failed) {
00252 break;
00253 }
00254
00255 compatibleHeaders = true;
00256 }
00257
00258
00259 if (!compatibleHeaders) {
00260 throw cms::Exception("ProductsNotMergeable")
00261 << "Error in LHERunInfoProduct: LHE headers differ. "
00262 "Cannot merge products." << std::endl;
00263 }
00264
00265
00266 if (heprup_ == other.heprup_)
00267 return true;
00268
00269
00270
00271
00272
00273 std::map<int, XSec> processes;
00274
00275 for(int i = 0; i < heprup_.NPRUP; i++) {
00276 int id = heprup_.LPRUP[i];
00277 XSec &x = processes[id];
00278 x.xsec = heprup_.XSECUP[i];
00279 x.err = heprup_.XERRUP[i];
00280 x.max = heprup_.XMAXUP[i];
00281 }
00282
00283 for(int i = 0; i < other.heprup_.NPRUP; i++) {
00284 int id = other.heprup_.LPRUP[i];
00285 XSec &x = processes[id];
00286 if (x.xsec) {
00287 double wgt1 = 1.0 / (x.err * x.err);
00288 double wgt2 = 1.0 / (other.heprup_.XERRUP[i] *
00289 other.heprup_.XERRUP[i]);
00290 x.xsec = (wgt1 * x.xsec +
00291 wgt2 * other.heprup_.XSECUP[i]) /
00292 (wgt1 + wgt2);
00293 x.err = 1.0 / std::sqrt(wgt1 + wgt2);
00294 x.max = std::max(x.max, other.heprup_.XMAXUP[i]);
00295 } else {
00296 x.xsec = other.heprup_.XSECUP[i];
00297 x.err = other.heprup_.XERRUP[i];
00298 x.max = other.heprup_.XMAXUP[i];
00299 }
00300 }
00301
00302 heprup_.resize(processes.size());
00303 unsigned int i = 0;
00304 for(std::map<int, XSec>::const_iterator iter = processes.begin();
00305 iter != processes.end(); ++iter, i++) {
00306 heprup_.LPRUP[i] = iter->first;
00307 heprup_.XSECUP[i] = iter->second.xsec;
00308 heprup_.XERRUP[i] = iter->second.err;
00309 heprup_.XMAXUP[i] = iter->second.max;
00310 }
00311
00312 return true;
00313 }