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::mergeProduct(const LHERunInfoProduct &other)
00209 {
00210 if (heprup_.IDBMUP != other.heprup_.IDBMUP ||
00211 heprup_.EBMUP != other.heprup_.EBMUP ||
00212 heprup_.PDFGUP != other.heprup_.PDFGUP ||
00213 heprup_.PDFSUP != other.heprup_.PDFSUP ||
00214 heprup_.IDWTUP != other.heprup_.IDWTUP) {
00215 throw cms::Exception("ProductsNotMergeable")
00216 << "Error in LHERunInfoProduct: LHE headers differ. "
00217 "Cannot merge products." << std::endl;
00218 }
00219
00220 bool compatibleHeaders = headers_ == other.headers_;
00221
00222
00223 while(!compatibleHeaders) {
00224
00225
00226
00227
00228 std::set<Header, HeaderLess> headers;
00229 std::copy(headers_begin(), headers_end(),
00230 std::inserter(headers, headers.begin()));
00231
00232 bool failed = false;
00233 for(std::vector<LHERunInfoProduct::Header>::const_iterator
00234 header = other.headers_begin();
00235 header != other.headers_end(); ++header) {
00236 if (headers.count(*header))
00237 continue;
00238
00239 if (header->tag() == "" ||
00240 header->tag().find("Alpgen") == 0 ||
00241 header->tag() == "MGGridCard" ||
00242 header->tag() == "MGGenerationInfo") {
00243 addHeader(*header);
00244 headers.insert(*header);
00245 } else
00246 failed = true;
00247 }
00248 if (failed)
00249 break;
00250
00251 compatibleHeaders = true;
00252 }
00253
00254
00255 if (!compatibleHeaders) {
00256 throw cms::Exception("ProductsNotMergeable")
00257 << "Error in LHERunInfoProduct: LHE headers differ. "
00258 "Cannot merge products." << std::endl;
00259 }
00260
00261
00262 if (heprup_ == other.heprup_)
00263 return true;
00264
00265
00266
00267
00268
00269 std::map<int, XSec> processes;
00270
00271 for(int i = 0; i < heprup_.NPRUP; i++) {
00272 int id = heprup_.LPRUP[i];
00273 XSec &x = processes[id];
00274 x.xsec = heprup_.XSECUP[i];
00275 x.err = heprup_.XERRUP[i];
00276 x.max = heprup_.XMAXUP[i];
00277 }
00278
00279 for(int i = 0; i < other.heprup_.NPRUP; i++) {
00280 int id = other.heprup_.LPRUP[i];
00281 XSec &x = processes[id];
00282 if (x.xsec) {
00283 double wgt1 = 1.0 / (x.err * x.err);
00284 double wgt2 = 1.0 / (other.heprup_.XERRUP[i] *
00285 other.heprup_.XERRUP[i]);
00286 x.xsec = (wgt1 * x.xsec +
00287 wgt2 * other.heprup_.XSECUP[i]) /
00288 (wgt1 + wgt2);
00289 x.err = 1.0 / std::sqrt(wgt1 + wgt2);
00290 x.max = std::max(x.max, other.heprup_.XMAXUP[i]);
00291 } else {
00292 x.xsec = other.heprup_.XSECUP[i];
00293 x.err = other.heprup_.XERRUP[i];
00294 x.max = other.heprup_.XMAXUP[i];
00295 }
00296 }
00297
00298 heprup_.resize(processes.size());
00299 unsigned int i = 0;
00300 for(std::map<int, XSec>::const_iterator iter = processes.begin();
00301 iter != processes.end(); ++iter, i++) {
00302 heprup_.LPRUP[i] = iter->first;
00303 heprup_.XSECUP[i] = iter->second.xsec;
00304 heprup_.XERRUP[i] = iter->second.err;
00305 heprup_.XMAXUP[i] = iter->second.max;
00306 }
00307
00308 return true;
00309 }