Go to the documentation of this file.00001 #include <algorithm>
00002 #include <iostream>
00003 #include <iomanip>
00004 #include <string>
00005 #include <cctype>
00006 #include <vector>
00007 #include <memory>
00008 #include <cmath>
00009 #include <cstring>
00010
00011 #include <boost/bind.hpp>
00012
00013 #include <xercesc/dom/DOM.hpp>
00014 #include <xercesc/parsers/XercesDOMParser.hpp>
00015 #include <xercesc/sax/HandlerBase.hpp>
00016
00017 #include "FWCore/Utilities/interface/Exception.h"
00018 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00019
00020 #include "SimDataFormats/GeneratorProducts/interface/LesHouches.h"
00021
00022 #include "GeneratorInterface/LHEInterface/interface/LHERunInfo.h"
00023
00024 #include "XMLUtils.h"
00025
00026 XERCES_CPP_NAMESPACE_USE
00027
00028 static int skipWhitespace(std::istream &in)
00029 {
00030 int ch;
00031 do {
00032 ch = in.get();
00033 } while(std::isspace(ch));
00034 if (ch != std::istream::traits_type::eof())
00035 in.putback(ch);
00036 return ch;
00037 }
00038
00039 namespace lhef {
00040
00041 LHERunInfo::LHERunInfo(std::istream &in)
00042 {
00043 in >> heprup.IDBMUP.first >> heprup.IDBMUP.second
00044 >> heprup.EBMUP.first >> heprup.EBMUP.second
00045 >> heprup.PDFGUP.first >> heprup.PDFGUP.second
00046 >> heprup.PDFSUP.first >> heprup.PDFSUP.second
00047 >> heprup.IDWTUP >> heprup.NPRUP;
00048 if (!in.good())
00049 throw cms::Exception("InvalidFormat")
00050 << "Les Houches file contained invalid"
00051 " header in init section." << std::endl;
00052
00053 heprup.resize();
00054
00055 for(int i = 0; i < heprup.NPRUP; i++) {
00056 in >> heprup.XSECUP[i] >> heprup.XERRUP[i]
00057 >> heprup.XMAXUP[i] >> heprup.LPRUP[i];
00058 if (!in.good())
00059 throw cms::Exception("InvalidFormat")
00060 << "Les Houches file contained invalid data"
00061 " in header payload line " << (i + 1)
00062 << "." << std::endl;
00063 }
00064
00065 while(skipWhitespace(in) == '#') {
00066 std::string line;
00067 std::getline(in, line);
00068 comments.push_back(line + "\n");
00069 }
00070
00071 if (!in.eof())
00072 edm::LogWarning("Generator|LHEInterface")
00073 << "Les Houches file contained spurious"
00074 " content after the regular data." << std::endl;
00075
00076 init();
00077 }
00078
00079 LHERunInfo::LHERunInfo(const HEPRUP &heprup) :
00080 heprup(heprup)
00081 {
00082 init();
00083 }
00084
00085 LHERunInfo::LHERunInfo(const HEPRUP &heprup,
00086 const std::vector<LHERunInfoProduct::Header> &headers,
00087 const std::vector<std::string> &comments) :
00088 heprup(heprup)
00089 {
00090 std::copy(headers.begin(), headers.end(),
00091 std::back_inserter(this->headers));
00092 std::copy(comments.begin(), comments.end(),
00093 std::back_inserter(this->comments));
00094
00095 init();
00096 }
00097
00098 LHERunInfo::LHERunInfo(const LHERunInfoProduct &product) :
00099 heprup(product.heprup())
00100 {
00101 std::copy(product.headers_begin(), product.headers_end(),
00102 std::back_inserter(headers));
00103 std::copy(product.comments_begin(), product.comments_end(),
00104 std::back_inserter(comments));
00105
00106 init();
00107 }
00108
00109 LHERunInfo::~LHERunInfo()
00110 {
00111 }
00112
00113 void LHERunInfo::init()
00114 {
00115 for(int i = 0; i < heprup.NPRUP; i++) {
00116 Process proc;
00117
00118 proc.process = heprup.LPRUP[i];
00119 proc.heprupIndex = (unsigned int)i;
00120
00121 processes.push_back(proc);
00122 }
00123
00124 std::sort(processes.begin(), processes.end());
00125 }
00126
00127 bool LHERunInfo::operator == (const LHERunInfo &other) const
00128 {
00129 return heprup == other.heprup;
00130 }
00131
00132 void LHERunInfo::count(int process, CountMode mode, double eventWeight,
00133 double brWeight, double matchWeight)
00134 {
00135 std::vector<Process>::iterator proc =
00136 std::lower_bound(processes.begin(), processes.end(), process);
00137 if (proc == processes.end() || proc->process != process)
00138 return;
00139
00140 switch(mode) {
00141 case kAccepted:
00142 proc->acceptedBr.add(eventWeight * brWeight * matchWeight);
00143 proc->accepted.add(eventWeight * matchWeight);
00144 case kKilled:
00145 proc->killed.add(eventWeight * matchWeight);
00146 case kSelected:
00147 proc->selected.add(eventWeight);
00148 case kTried:
00149 proc->tried.add(eventWeight);
00150 }
00151 }
00152
00153 LHERunInfo::XSec LHERunInfo::xsec() const
00154 {
00155 double sigSelSum = 0.0;
00156 double sigSum = 0.0;
00157 double sigBrSum = 0.0;
00158 double err2Sum = 0.0;
00159 double errBr2Sum = 0.0;
00160
00161 for(std::vector<Process>::const_iterator proc = processes.begin();
00162 proc != processes.end(); ++proc) {
00163 unsigned int idx = proc->heprupIndex;
00164
00165 double sigmaSum, sigma2Sum, sigma2Err, xsec;
00166 switch(std::abs(heprup.IDWTUP)) {
00167 case 2:
00168 sigmaSum = proc->tried.sum * heprup.XSECUP[idx];
00169 sigma2Sum = proc->tried.sum2 * heprup.XSECUP[idx]
00170 * heprup.XSECUP[idx];
00171 sigma2Err = proc->tried.sum2 * heprup.XERRUP[idx]
00172 * heprup.XERRUP[idx];
00173 break;
00174 case 3:
00175 sigmaSum = proc->tried.n * heprup.XSECUP[idx];
00176 sigma2Sum = sigmaSum * heprup.XSECUP[idx];
00177 sigma2Err = proc->tried.n * heprup.XERRUP[idx]
00178 * heprup.XERRUP[idx];
00179 break;
00180 default:
00181 xsec = proc->tried.sum / proc->tried.n;
00182 sigmaSum = proc->tried.sum * xsec;
00183 sigma2Sum = proc->tried.sum2 * xsec * xsec;
00184 sigma2Err = 0.0;
00185 }
00186
00187 if (!proc->killed.n)
00188 continue;
00189
00190 double sigmaAvg = sigmaSum / proc->tried.sum;
00191 double fracAcc = proc->killed.sum / proc->selected.sum;
00192 double fracBr = proc->accepted.sum > 0.0 ?
00193 proc->acceptedBr.sum / proc->accepted.sum : 1;
00194 double sigmaFin = sigmaAvg * fracAcc * fracBr;
00195 double sigmaFinBr = sigmaFin * fracBr;
00196
00197 double relErr = 1.0;
00198 if (proc->killed.n > 1) {
00199 double sigmaAvg2 = sigmaAvg * sigmaAvg;
00200 double delta2Sig =
00201 (sigma2Sum / proc->tried.n - sigmaAvg2) /
00202 (proc->tried.n * sigmaAvg2);
00203 double delta2Veto =
00204 ((double)proc->selected.n - proc->killed.n) /
00205 ((double)proc->selected.n * proc->killed.n);
00206 double delta2Sum = delta2Sig + delta2Veto
00207 + sigma2Err / sigma2Sum;
00208 relErr = (delta2Sum > 0.0 ?
00209 std::sqrt(delta2Sum) : 0.0);
00210 }
00211 double deltaFin = sigmaFin * relErr;
00212 double deltaFinBr = sigmaFinBr * relErr;
00213
00214 sigSelSum += sigmaAvg;
00215 sigSum += sigmaFin;
00216 sigBrSum += sigmaFinBr;
00217 err2Sum += deltaFin * deltaFin;
00218 errBr2Sum += deltaFinBr * deltaFinBr;
00219 }
00220
00221 XSec result;
00222 result.value = sigBrSum;
00223 result.error = std::sqrt(errBr2Sum);
00224
00225 return result;
00226 }
00227
00228 void LHERunInfo::statistics() const
00229 {
00230 double sigSelSum = 0.0;
00231 double sigSum = 0.0;
00232 double sigBrSum = 0.0;
00233 double err2Sum = 0.0;
00234 double errBr2Sum = 0.0;
00235 unsigned long nAccepted = 0;
00236 unsigned long nTried = 0;
00237
00238 std::cout << std::endl;
00239 std::cout << "Process and cross-section statistics" << std::endl;
00240 std::cout << "------------------------------------" << std::endl;
00241 std::cout << "Process\tevents\ttried\txsec [pb]\t\taccepted [%]"
00242 << std::endl;
00243
00244 for(std::vector<Process>::const_iterator proc = processes.begin();
00245 proc != processes.end(); ++proc) {
00246 unsigned int idx = proc->heprupIndex;
00247
00248 double sigmaSum, sigma2Sum, sigma2Err, xsec;
00249 switch(std::abs(heprup.IDWTUP)) {
00250 case 2:
00251 sigmaSum = proc->tried.sum * heprup.XSECUP[idx];
00252 sigma2Sum = proc->tried.sum2 * heprup.XSECUP[idx]
00253 * heprup.XSECUP[idx];
00254 sigma2Err = proc->tried.sum2 * heprup.XERRUP[idx]
00255 * heprup.XERRUP[idx];
00256 break;
00257 case 3:
00258 sigmaSum = proc->tried.n * heprup.XSECUP[idx];
00259 sigma2Sum = sigmaSum * heprup.XSECUP[idx];
00260 sigma2Err = proc->tried.n * heprup.XERRUP[idx]
00261 * heprup.XERRUP[idx];
00262 break;
00263 default:
00264 xsec = proc->tried.sum / proc->tried.n;
00265 sigmaSum = proc->tried.sum * xsec;
00266 sigma2Sum = proc->tried.sum2 * xsec * xsec;
00267 sigma2Err = 0.0;
00268 }
00269
00270 if (!proc->selected.n) {
00271 std::cout << proc->process << "\t0\t0\tn/a\t\t\tn/a"
00272 << std::endl;
00273 continue;
00274 }
00275
00276 double sigmaAvg = sigmaSum / proc->tried.sum;
00277 double fracAcc = proc->killed.sum / proc->selected.sum;
00278 double fracBr = proc->accepted.sum > 0.0 ?
00279 proc->acceptedBr.sum / proc->accepted.sum : 1;
00280 double sigmaFin = sigmaAvg * fracAcc;
00281 double sigmaFinBr = sigmaFin * fracBr;
00282
00283 double relErr = 1.0;
00284 if (proc->killed.n > 1) {
00285 double sigmaAvg2 = sigmaAvg * sigmaAvg;
00286 double delta2Sig =
00287 (sigma2Sum / proc->tried.n - sigmaAvg2) /
00288 (proc->tried.n * sigmaAvg2);
00289 double delta2Veto =
00290 ((double)proc->selected.n - proc->killed.n) /
00291 ((double)proc->selected.n * proc->killed.n);
00292 double delta2Sum = delta2Sig + delta2Veto
00293 + sigma2Err / sigma2Sum;
00294 relErr = (delta2Sum > 0.0 ?
00295 std::sqrt(delta2Sum) : 0.0);
00296 }
00297 double deltaFin = sigmaFin * relErr;
00298 double deltaFinBr = sigmaFinBr * relErr;
00299
00300 std::cout << proc->process << "\t"
00301 << proc->accepted.n << "\t"
00302 << proc->tried.n << "\t"
00303 << std::scientific << std::setprecision(3)
00304 << sigmaFinBr << " +/- "
00305 << deltaFinBr << "\t"
00306 << std::fixed << std::setprecision(1)
00307 << (fracAcc * 100) << std::endl;
00308
00309 nAccepted += proc->accepted.n;
00310 nTried += proc->tried.n;
00311 sigSelSum += sigmaAvg;
00312 sigSum += sigmaFin;
00313 sigBrSum += sigmaFinBr;
00314 err2Sum += deltaFin * deltaFin;
00315 errBr2Sum += deltaFinBr * deltaFinBr;
00316 }
00317
00318 std::cout << "Total\t"
00319 << nAccepted << "\t"
00320 << nTried << "\t"
00321 << std::scientific << std::setprecision(3)
00322 << sigBrSum << " +/- "
00323 << std::sqrt(errBr2Sum) << "\t"
00324 << std::fixed << std::setprecision(1)
00325 << (sigSum / sigSelSum * 100) << std::endl;
00326 }
00327
00328 LHERunInfo::Header::Header() :
00329 xmlDoc(0)
00330 {
00331 }
00332
00333 LHERunInfo::Header::Header(const std::string &tag) :
00334 LHERunInfoProduct::Header(tag), xmlDoc(0)
00335 {
00336 }
00337
00338 LHERunInfo::Header::Header(const Header &orig) :
00339 LHERunInfoProduct::Header(orig), xmlDoc(0)
00340 {
00341 }
00342
00343 LHERunInfo::Header::Header(const LHERunInfoProduct::Header &orig) :
00344 LHERunInfoProduct::Header(orig), xmlDoc(0)
00345 {
00346 }
00347
00348 LHERunInfo::Header::~Header()
00349 {
00350 if (xmlDoc)
00351 xmlDoc->release();
00352 }
00353
00354 static void fillLines(std::vector<std::string> &lines, const char *data,
00355 int len = -1)
00356 {
00357 const char *end = len >= 0 ? (data + len) : 0;
00358 while(*data && (!end || data < end)) {
00359 std::size_t len = std::strcspn(data, "\r\n");
00360 if (end && data + len > end)
00361 len = end - data;
00362 if (data[len] == '\r' && data[len + 1] == '\n')
00363 len += 2;
00364 else if (data[len])
00365 len++;
00366 lines.push_back(std::string(data, len));
00367 data += len;
00368 }
00369 }
00370
00371 static std::vector<std::string> domToLines(const DOMNode *node)
00372 {
00373 std::vector<std::string> result;
00374 DOMImplementation *impl =
00375 DOMImplementationRegistry::getDOMImplementation(
00376 XMLUniStr("Core"));
00377 std::auto_ptr<DOMWriter> writer(
00378 static_cast<DOMImplementationLS*>(impl)->createDOMWriter());
00379
00380 writer->setEncoding(XMLUniStr("UTF-8"));
00381 XMLSimpleStr buffer(writer->writeToString(*node));
00382
00383 const char *p = std::strchr((const char*)buffer, '>') + 1;
00384 const char *q = std::strrchr(p, '<');
00385 fillLines(result, p, q - p);
00386
00387 return result;
00388 }
00389
00390 std::vector<std::string> LHERunInfo::findHeader(const std::string &tag) const
00391 {
00392 const LHERunInfo::Header *header = 0;
00393 for(std::vector<Header>::const_iterator iter = headers.begin();
00394 iter != headers.end(); ++iter) {
00395 if (iter->tag() == tag)
00396 return std::vector<std::string>(iter->begin(),
00397 iter->end());
00398 if (iter->tag() == "header")
00399 header = &*iter;
00400 }
00401
00402 if (!header)
00403 return std::vector<std::string>();
00404
00405 const DOMNode *root = header->getXMLNode();
00406 if (!root)
00407 return std::vector<std::string>();
00408
00409 for(const DOMNode *iter = root->getFirstChild();
00410 iter; iter = iter->getNextSibling()) {
00411 if (iter->getNodeType() != DOMNode::ELEMENT_NODE)
00412 continue;
00413 if (tag == (const char*)XMLSimpleStr(iter->getNodeName()))
00414 return domToLines(iter);
00415 }
00416
00417 return std::vector<std::string>();
00418 }
00419
00420 namespace {
00421 class HeaderReader : public CBInputStream::Reader {
00422 public:
00423 HeaderReader(const LHERunInfo::Header *header) :
00424 header(header), mode(kHeader),
00425 iter(header->begin())
00426 {
00427 }
00428
00429 const std::string &data()
00430 {
00431 switch(mode) {
00432 case kHeader:
00433 tmp = "<" + header->tag() + ">";
00434 mode = kBody;
00435 break;
00436 case kBody:
00437 if (iter != header->end())
00438 return *iter++;
00439 tmp = "</" + header->tag() + ">";
00440 mode = kFooter;
00441 break;
00442 case kFooter:
00443 tmp.clear();
00444 }
00445
00446 return tmp;
00447 }
00448
00449 private:
00450 enum Mode {
00451 kHeader,
00452 kBody,
00453 kFooter
00454 };
00455
00456 const LHERunInfo::Header *header;
00457 Mode mode;
00458 LHERunInfo::Header::const_iterator iter;
00459 std::string tmp;
00460 };
00461 }
00462
00463 const DOMNode *LHERunInfo::Header::getXMLNode() const
00464 {
00465 if (tag().empty())
00466 return 0;
00467
00468 if (!xmlDoc) {
00469 XercesDOMParser parser;
00470 parser.setValidationScheme(XercesDOMParser::Val_Auto);
00471 parser.setDoNamespaces(false);
00472 parser.setDoSchema(false);
00473 parser.setValidationSchemaFullChecking(false);
00474
00475 HandlerBase errHandler;
00476 parser.setErrorHandler(&errHandler);
00477 parser.setCreateEntityReferenceNodes(false);
00478
00479 try {
00480 std::auto_ptr<CBInputStream::Reader> reader(
00481 new HeaderReader(this));
00482 CBInputSource source(reader);
00483 parser.parse(source);
00484 xmlDoc = parser.adoptDocument();
00485 } catch(const XMLException &e) {
00486 throw cms::Exception("Generator|LHEInterface")
00487 << "XML parser reported DOM error no. "
00488 << (unsigned long)e.getCode()
00489 << ": " << XMLSimpleStr(e.getMessage()) << "."
00490 << std::endl;
00491 } catch(const SAXException &e) {
00492 throw cms::Exception("Generator|LHEInterface")
00493 << "XML parser reported: "
00494 << XMLSimpleStr(e.getMessage()) << "."
00495 << std::endl;
00496 }
00497 }
00498
00499 return xmlDoc->getDocumentElement();
00500 }
00501
00502 std::pair<int, int> LHERunInfo::pdfSetTranslation() const
00503 {
00504 int pdfA = -1, pdfB = -1;
00505
00506 if (heprup.PDFGUP.first >= 0) {
00507 pdfA = heprup.PDFSUP.first;
00508 }
00509
00510 if (heprup.PDFGUP.second >= 0) {
00511 pdfB = heprup.PDFSUP.second;
00512 }
00513
00514 return std::make_pair(pdfA, pdfB);
00515 }
00516
00517 }