CMS 3D CMS Logo

LHERunInfo.cc

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

Generated on Tue Jun 9 17:37:07 2009 for CMSSW by  doxygen 1.5.4