CMS 3D CMS Logo

LHERunInfo.cc
Go to the documentation of this file.
1 #include <algorithm>
2 #include <iostream>
3 #include <iomanip>
4 #include <string>
5 #include <cctype>
6 #include <vector>
7 #include <memory>
8 #include <cmath>
9 #include <cstring>
10 
11 #include <xercesc/dom/DOM.hpp>
12 #include <xercesc/parsers/XercesDOMParser.hpp>
13 #include <xercesc/sax/HandlerBase.hpp>
14 
17 
19 
21 
22 #include "XMLUtils.h"
23 
25 
26 static int skipWhitespace(std::istream &in) {
27  int ch;
28  do {
29  ch = in.get();
30  } while (std::isspace(ch));
31  if (ch != std::istream::traits_type::eof())
32  in.putback(ch);
33  return ch;
34 }
35 
36 namespace lhef {
37 
38  LHERunInfo::LHERunInfo(std::istream &in) {
39  in >> heprup.IDBMUP.first >> heprup.IDBMUP.second >> heprup.EBMUP.first >> heprup.EBMUP.second >>
40  heprup.PDFGUP.first >> heprup.PDFGUP.second >> heprup.PDFSUP.first >> heprup.PDFSUP.second >> heprup.IDWTUP >>
41  heprup.NPRUP;
42  if (!in.good())
43  throw cms::Exception("InvalidFormat") << "Les Houches file contained invalid"
44  " header in init section."
45  << std::endl;
46 
47  heprup.resize();
48 
49  for (int i = 0; i < heprup.NPRUP; i++) {
51  if (!in.good())
52  throw cms::Exception("InvalidFormat") << "Les Houches file contained invalid data"
53  " in header payload line "
54  << (i + 1) << "." << std::endl;
55  }
56 
57  while (skipWhitespace(in) == '#') {
59  std::getline(in, line);
60  comments.push_back(line + "\n");
61  }
62 
63  if (!in.eof())
64  edm::LogInfo("Generator|LHEInterface")
65  << "Les Houches file contained spurious"
66  " content after the regular data (this is normal for LHEv3 files for now)."
67  << std::endl;
68 
69  init();
70  }
71 
72  LHERunInfo::LHERunInfo(const HEPRUP &heprup) : heprup(heprup) { init(); }
73 
75  const std::vector<LHERunInfoProduct::Header> &headers,
76  const std::vector<std::string> &comments)
77  : heprup(heprup) {
78  std::copy(headers.begin(), headers.end(), std::back_inserter(this->headers));
79  std::copy(comments.begin(), comments.end(), std::back_inserter(this->comments));
80 
81  init();
82  }
83 
84  LHERunInfo::LHERunInfo(const LHERunInfoProduct &product) : heprup(product.heprup()) {
85  std::copy(product.headers_begin(), product.headers_end(), std::back_inserter(headers));
86  std::copy(product.comments_begin(), product.comments_end(), std::back_inserter(comments));
87 
88  init();
89  }
90 
92 
94  for (int i = 0; i < heprup.NPRUP; i++) {
95  Process proc;
96  proc.setProcess(heprup.LPRUP[i]);
97  proc.setHepRupIndex((unsigned int)i);
98  processes.push_back(proc);
99  }
100 
101  std::sort(processes.begin(), processes.end());
102  }
103 
105  processesLumi.clear();
106  for (int i = 0; i < heprup.NPRUP; i++) {
107  Process proc;
108  proc.setProcess(heprup.LPRUP[i]);
109  proc.setHepRupIndex((unsigned int)i);
110  proc.setLHEXSec(heprup.XSECUP[i], heprup.XERRUP[i]);
111  processesLumi.push_back(proc);
112  }
113 
114  std::sort(processesLumi.begin(), processesLumi.end());
115  }
116 
117  bool LHERunInfo::operator==(const LHERunInfo &other) const { return heprup == other.heprup; }
118 
119  void LHERunInfo::count(int process, CountMode mode, double eventWeight, double brWeight, double matchWeight) {
120  std::vector<Process>::iterator proc = std::lower_bound(processes.begin(), processes.end(), process);
121  if (proc == processes.end() || proc->process() != process)
122  return;
123 
124  std::vector<Process>::iterator procLumi = std::lower_bound(processesLumi.begin(), processesLumi.end(), process);
125  if (procLumi == processesLumi.end() || procLumi->process() != process)
126  return;
127 
128  switch (mode) {
129  case kAccepted:
130  proc->addAcceptedBr(eventWeight * brWeight * matchWeight);
131  proc->addAccepted(eventWeight * matchWeight);
132  procLumi->addAcceptedBr(eventWeight * brWeight * matchWeight);
133  procLumi->addAccepted(eventWeight * matchWeight);
134  [[fallthrough]];
135  case kKilled:
136  proc->addKilled(eventWeight * matchWeight);
137  procLumi->addKilled(eventWeight * matchWeight);
138  if (eventWeight > 0) {
139  proc->addNPassPos();
140  procLumi->addNPassPos();
141  } else {
142  proc->addNPassNeg();
143  procLumi->addNPassNeg();
144  }
145  [[fallthrough]];
146  case kSelected:
147  proc->addSelected(eventWeight);
148  procLumi->addSelected(eventWeight);
149  if (eventWeight > 0) {
150  proc->addNTotalPos();
151  procLumi->addNTotalPos();
152  } else {
153  proc->addNTotalNeg();
154  procLumi->addNTotalNeg();
155  }
156  [[fallthrough]];
157  case kTried:
158  proc->addTried(eventWeight);
159  procLumi->addTried(eventWeight);
160  }
161  }
162 
164  double sigBrSum = 0.0;
165  double errBr2Sum = 0.0;
166  int idwtup = heprup.IDWTUP;
167  for (std::vector<Process>::const_iterator proc = processes.begin(); proc != processes.end(); ++proc) {
168  unsigned int idx = proc->heprupIndex();
169 
170  if (!proc->killed().n())
171  continue;
172 
173  double sigma2Sum, sigma2Err;
174  sigma2Sum = heprup.XSECUP[idx] * heprup.XSECUP[idx];
175  sigma2Err = heprup.XERRUP[idx] * heprup.XERRUP[idx];
176 
177  double sigmaAvg = heprup.XSECUP[idx];
178 
179  double fracAcc = 0;
180  double ntotal = proc->nTotalPos() - proc->nTotalNeg();
181  double npass = proc->nPassPos() - proc->nPassNeg();
182  switch (idwtup) {
183  case 3:
184  case -3:
185  fracAcc = ntotal > 0 ? npass / ntotal : -1;
186  break;
187  default:
188  fracAcc = proc->selected().sum() > 0 ? proc->killed().sum() / proc->selected().sum() : -1;
189  break;
190  }
191 
192  if (fracAcc <= 0)
193  continue;
194 
195  double fracBr = proc->accepted().sum() > 0.0 ? proc->acceptedBr().sum() / proc->accepted().sum() : 1;
196  double sigmaFin = sigmaAvg * fracAcc;
197  double sigmaFinBr = sigmaFin * fracBr;
198 
199  double relErr = 1.0;
200 
201  double efferr2 = 0;
202  switch (idwtup) {
203  case 3:
204  case -3: {
205  double ntotal_pos = proc->nTotalPos();
206  double effp = ntotal_pos > 0 ? (double)proc->nPassPos() / ntotal_pos : 0;
207  double effp_err2 = ntotal_pos > 0 ? (1 - effp) * effp / ntotal_pos : 0;
208 
209  double ntotal_neg = proc->nTotalNeg();
210  double effn = ntotal_neg > 0 ? (double)proc->nPassNeg() / ntotal_neg : 0;
211  double effn_err2 = ntotal_neg > 0 ? (1 - effn) * effn / ntotal_neg : 0;
212 
213  efferr2 = ntotal > 0
214  ? (ntotal_pos * ntotal_pos * effp_err2 + ntotal_neg * ntotal_neg * effn_err2) / ntotal / ntotal
215  : 0;
216  break;
217  }
218  default: {
219  double denominator = pow(proc->selected().sum(), 4);
220  double passw = proc->killed().sum();
221  double passw2 = proc->killed().sum2();
222  double failw = proc->selected().sum() - passw;
223  double failw2 = proc->selected().sum2() - passw2;
224  double numerator = (passw2 * failw * failw + failw2 * passw * passw);
225 
226  efferr2 = denominator > 0 ? numerator / denominator : 0;
227  break;
228  }
229  }
230  double delta2Veto = efferr2 / fracAcc / fracAcc;
231  double delta2Sum = delta2Veto + sigma2Err / sigma2Sum;
232  relErr = (delta2Sum > 0.0 ? std::sqrt(delta2Sum) : 0.0);
233 
234  double deltaFinBr = sigmaFinBr * relErr;
235 
236  sigBrSum += sigmaFinBr;
237  errBr2Sum += deltaFinBr * deltaFinBr;
238  }
239 
240  XSec result(sigBrSum, std::sqrt(errBr2Sum));
241 
242  return result;
243  }
244 
245  void LHERunInfo::statistics() const {
246  double sigSelSum = 0.0;
247  double sigSum = 0.0;
248  double sigBrSum = 0.0;
249  double errSel2Sum = 0.0;
250  double errBr2Sum = 0.0;
251  double errMatch2Sum = 0.0;
252  unsigned long nAccepted = 0;
253  unsigned long nTried = 0;
254  unsigned long nAccepted_pos = 0;
255  unsigned long nTried_pos = 0;
256  unsigned long nAccepted_neg = 0;
257  unsigned long nTried_neg = 0;
258  int idwtup = heprup.IDWTUP;
259 
260  LogDebug("LHERunInfo") << " statistics";
261  LogDebug("LHERunInfo") << "Process and cross-section statistics";
262  LogDebug("LHERunInfo") << "------------------------------------";
263  LogDebug("LHERunInfo") << "Process\t\txsec_before [pb]\t\tpassed\tnposw\tnnegw\ttried\tnposw\tnnegw \txsec_match "
264  "[pb]\t\t\taccepted [%]\t event_eff [%]";
265 
266  for (std::vector<Process>::const_iterator proc = processes.begin(); proc != processes.end(); ++proc) {
267  unsigned int idx = proc->heprupIndex();
268 
269  if (!proc->selected().n()) {
270  LogDebug("LHERunInfo") << proc->process() << "\t0\t0\tn/a\t\t\tn/a";
271  continue;
272  }
273 
274  double sigma2Sum, sigma2Err;
275  sigma2Sum = heprup.XSECUP[idx] * heprup.XSECUP[idx];
276  sigma2Err = heprup.XERRUP[idx] * heprup.XERRUP[idx];
277 
278  double sigmaAvg = heprup.XSECUP[idx];
279 
280  double fracAcc = 0;
281  double ntotal = proc->nTotalPos() - proc->nTotalNeg();
282  double npass = proc->nPassPos() - proc->nPassNeg();
283  switch (idwtup) {
284  case 3:
285  case -3:
286  fracAcc = ntotal > 0 ? npass / ntotal : -1;
287  break;
288  default:
289  fracAcc = proc->selected().sum() > 0 ? proc->killed().sum() / proc->selected().sum() : -1;
290  break;
291  }
292 
293  double fracBr = proc->accepted().sum() > 0.0 ? proc->acceptedBr().sum() / proc->accepted().sum() : 1;
294  double sigmaFin = fracAcc > 0 ? sigmaAvg * fracAcc : 0;
295  double sigmaFinBr = sigmaFin * fracBr;
296 
297  double relErr = 1.0;
298  double relAccErr = 1.0;
299  double efferr2 = 0;
300 
301  if (proc->killed().n() > 0 && fracAcc > 0) {
302  switch (idwtup) {
303  case 3:
304  case -3: {
305  double ntotal_pos = proc->nTotalPos();
306  double effp = ntotal_pos > 0 ? (double)proc->nPassPos() / ntotal_pos : 0;
307  double effp_err2 = ntotal_pos > 0 ? (1 - effp) * effp / ntotal_pos : 0;
308 
309  double ntotal_neg = proc->nTotalNeg();
310  double effn = ntotal_neg > 0 ? (double)proc->nPassNeg() / ntotal_neg : 0;
311  double effn_err2 = ntotal_neg > 0 ? (1 - effn) * effn / ntotal_neg : 0;
312 
313  efferr2 = ntotal > 0 ? (ntotal_pos * ntotal_pos * effp_err2 + ntotal_neg * ntotal_neg * effn_err2) /
314  ntotal / ntotal
315  : 0;
316  break;
317  }
318  default: {
319  double denominator = pow(proc->selected().sum(), 4);
320  double passw = proc->killed().sum();
321  double passw2 = proc->killed().sum2();
322  double failw = proc->selected().sum() - passw;
323  double failw2 = proc->selected().sum2() - passw2;
324  double numerator = (passw2 * failw * failw + failw2 * passw * passw);
325 
326  efferr2 = denominator > 0 ? numerator / denominator : 0;
327  break;
328  }
329  }
330  double delta2Veto = efferr2 / fracAcc / fracAcc;
331  double delta2Sum = delta2Veto + sigma2Err / sigma2Sum;
332  relErr = (delta2Sum > 0.0 ? std::sqrt(delta2Sum) : 0.0);
333  relAccErr = (delta2Veto > 0.0 ? std::sqrt(delta2Veto) : 0.0);
334  }
335  double deltaFinBr = sigmaFinBr * relErr;
336 
337  double ntotal_proc = proc->nTotalPos() + proc->nTotalNeg();
338  double event_eff_proc = ntotal_proc > 0 ? (double)(proc->nPassPos() + proc->nPassNeg()) / ntotal_proc : -1;
339  double event_eff_err_proc = ntotal_proc > 0 ? std::sqrt((1 - event_eff_proc) * event_eff_proc / ntotal_proc) : -1;
340 
341  LogDebug("LHERunInfo") << proc->process() << "\t\t" << std::scientific << std::setprecision(3)
342  << heprup.XSECUP[proc->heprupIndex()] << " +/- " << heprup.XERRUP[proc->heprupIndex()]
343  << "\t\t" << proc->accepted().n() << "\t" << proc->nPassPos() << "\t" << proc->nPassNeg()
344  << "\t" << proc->tried().n() << "\t" << proc->nTotalPos() << "\t" << proc->nTotalNeg()
345  << "\t" << std::scientific << std::setprecision(3) << sigmaFinBr << " +/- " << deltaFinBr
346  << "\t\t" << std::fixed << std::setprecision(1) << (fracAcc * 100) << " +/- "
347  << (std::sqrt(efferr2) * 100) << "\t" << std::fixed << std::setprecision(1)
348  << (event_eff_proc * 100) << " +/- " << (event_eff_err_proc * 100);
349 
350  nAccepted += proc->accepted().n();
351  nTried += proc->tried().n();
352  nAccepted_pos += proc->nPassPos();
353  nTried_pos += proc->nTotalPos();
354  nAccepted_neg += proc->nPassNeg();
355  nTried_neg += proc->nTotalNeg();
356  sigSelSum += sigmaAvg;
357  sigSum += sigmaFin;
358  sigBrSum += sigmaFinBr;
359  errSel2Sum += sigma2Err;
360  errBr2Sum += deltaFinBr * deltaFinBr;
361  errMatch2Sum += sigmaFin * relAccErr * sigmaFin * relAccErr;
362  }
363 
364  double ntotal_all = (nTried_pos + nTried_neg);
365  double event_eff_all = ntotal_all > 0 ? (double)(nAccepted_pos + nAccepted_neg) / ntotal_all : -1;
366  double event_eff_err_all = ntotal_all > 0 ? std::sqrt((1 - event_eff_all) * event_eff_all / ntotal_all) : -1;
367 
368  LogDebug("LHERunInfo") << "Total\t\t" << std::scientific << std::setprecision(3) << sigSelSum << " +/- "
369  << std::sqrt(errSel2Sum) << "\t\t" << nAccepted << "\t" << nAccepted_pos << "\t"
370  << nAccepted_neg << "\t" << nTried << "\t" << nTried_pos << "\t" << nTried_neg << "\t"
371  << std::scientific << std::setprecision(3) << sigBrSum << " +/- " << std::sqrt(errBr2Sum)
372  << "\t\t" << std::fixed << std::setprecision(1) << (sigSum / sigSelSum * 100) << " +/- "
373  << (std::sqrt(errMatch2Sum) / sigSelSum * 100) << "\t" << std::fixed << std::setprecision(1)
374  << (event_eff_all * 100) << " +/- " << (event_eff_err_all * 100);
375  }
376 
377  LHERunInfo::Header::Header() : xmlDoc(nullptr) {}
378 
380 
381  LHERunInfo::Header::Header(const Header &orig) : LHERunInfoProduct::Header(orig), xmlDoc(nullptr) {}
382 
384  : LHERunInfoProduct::Header(orig), xmlDoc(nullptr) {}
385 
387  if (xmlDoc)
388  xmlDoc->release();
389  }
390 
391  static void fillLines(std::vector<std::string> &lines, const char *data, int len = -1) {
392  const char *end = len >= 0 ? (data + len) : nullptr;
393  while (*data && (!end || data < end)) {
394  std::size_t len = std::strcspn(data, "\r\n");
395  if (end && data + len > end)
396  len = end - data;
397  if (data[len] == '\r' && data[len + 1] == '\n')
398  len += 2;
399  else if (data[len])
400  len++;
401  lines.push_back(std::string(data, len));
402  data += len;
403  }
404  }
405 
406  static std::vector<std::string> domToLines(const DOMNode *node) {
407  std::vector<std::string> result;
408  DOMImplementation *impl = DOMImplementationRegistry::getDOMImplementation(XMLUniStr("Core"));
409  std::unique_ptr<DOMLSSerializer> writer(((DOMImplementationLS *)(impl))->createLSSerializer());
410 
411  std::unique_ptr<DOMLSOutput> outputDesc(((DOMImplementationLS *)impl)->createLSOutput());
412  assert(outputDesc.get());
413  outputDesc->setEncoding(XMLUniStr("UTF-8"));
414 
415  XMLSimpleStr buffer(writer->writeToString(node));
416 
417  const char *p = std::strchr((const char *)buffer, '>') + 1;
418  const char *q = std::strrchr(p, '<');
419  fillLines(result, p, q - p);
420 
421  return result;
422  }
423 
424  std::vector<std::string> LHERunInfo::findHeader(const std::string &tag) const {
425  const LHERunInfo::Header *header = nullptr;
426  for (std::vector<Header>::const_iterator iter = headers.begin(); iter != headers.end(); ++iter) {
427  if (iter->tag() == tag)
428  return std::vector<std::string>(iter->begin(), iter->end());
429  if (iter->tag() == "header")
430  header = &*iter;
431  }
432 
433  if (!header)
434  return std::vector<std::string>();
435 
436  const DOMNode *root = header->getXMLNode();
437  if (!root)
438  return std::vector<std::string>();
439 
440  for (const DOMNode *iter = root->getFirstChild(); iter; iter = iter->getNextSibling()) {
441  if (iter->getNodeType() != DOMNode::ELEMENT_NODE)
442  continue;
443  if (tag == (const char *)XMLSimpleStr(iter->getNodeName()))
444  return domToLines(iter);
445  }
446 
447  return std::vector<std::string>();
448  }
449 
450  namespace {
451  class HeaderReader : public CBInputStream::Reader {
452  public:
453  HeaderReader(const LHERunInfo::Header *header) : header(header), mode(kHeader), iter(header->begin()) {}
454 
455  const std::string &data() override {
456  switch (mode) {
457  case kHeader:
458  tmp = "<" + header->tag() + ">";
459  mode = kBody;
460  break;
461  case kBody:
462  if (iter != header->end())
463  return *iter++;
464  tmp = "</" + header->tag() + ">";
465  mode = kFooter;
466  break;
467  case kFooter:
468  tmp.clear();
469  }
470 
471  return tmp;
472  }
473 
474  private:
475  enum Mode { kHeader, kBody, kFooter };
476 
477  const LHERunInfo::Header *header;
478  Mode mode;
481  };
482  } // anonymous namespace
483 
484  const DOMNode *LHERunInfo::Header::getXMLNode() const {
485  if (tag().empty())
486  return nullptr;
487 
488  if (!xmlDoc) {
489  XercesDOMParser parser;
490  parser.setValidationScheme(XercesDOMParser::Val_Auto);
491  parser.setDoNamespaces(false);
492  parser.setDoSchema(false);
493  parser.setValidationSchemaFullChecking(false);
494 
495  HandlerBase errHandler;
496  parser.setErrorHandler(&errHandler);
497  parser.setCreateEntityReferenceNodes(false);
498 
499  try {
500  std::unique_ptr<CBInputStream::Reader> reader(new HeaderReader(this));
502  parser.parse(source);
503  xmlDoc = parser.adoptDocument();
504  } catch (const XMLException &e) {
505  throw cms::Exception("Generator|LHEInterface")
506  << "XML parser reported DOM error no. " << (unsigned long)e.getCode() << ": "
507  << XMLSimpleStr(e.getMessage()) << "." << std::endl;
508  } catch (const SAXException &e) {
509  throw cms::Exception("Generator|LHEInterface")
510  << "XML parser reported: " << XMLSimpleStr(e.getMessage()) << "." << std::endl;
511  }
512  }
513 
514  return xmlDoc->getDocumentElement();
515  }
516 
517  std::pair<int, int> LHERunInfo::pdfSetTranslation() const {
518  int pdfA = -1, pdfB = -1;
519 
520  if (heprup.PDFGUP.first >= 0) {
521  pdfA = heprup.PDFSUP.first;
522  }
523 
524  if (heprup.PDFGUP.second >= 0) {
525  pdfB = heprup.PDFSUP.second;
526  }
527 
528  return std::make_pair(pdfA, pdfB);
529  }
530 
531  const bool operator==(const LHERunInfo::Process &lhs, const LHERunInfo::Process &rhs) {
532  return (lhs.process() == rhs.process());
533  }
534 
535  const bool operator<(const LHERunInfo::Process &lhs, const LHERunInfo::Process &rhs) {
536  return (lhs.process() < rhs.process());
537  }
538 
539 } // namespace lhef
static XERCES_CPP_NAMESPACE_USE int skipWhitespace(std::istream &in)
Definition: LHERunInfo.cc:26
void resize(int nrup)
Definition: LesHouches.h:44
const bool operator<(const LHERunInfo::Process &lhs, const LHERunInfo::Process &rhs)
Definition: LHERunInfo.cc:535
XMLInputSourceWrapper< CBInputStream > CBInputSource
Definition: XMLUtils.h:188
std::pair< double, double > EBMUP
Definition: LesHouches.h:82
headers_const_iterator headers_begin() const
static std::vector< std::string > domToLines(const DOMNode *node)
Definition: LHERunInfo.cc:406
std::pair< int, int > IDBMUP
Definition: LesHouches.h:77
reader
Definition: DQM.py:105
std::vector< std::string >::const_iterator const_iterator
std::vector< Process > processes
Definition: LHERunInfo.h:158
assert(be >=bs)
std::pair< int, int > pdfSetTranslation() const
Definition: LHERunInfo.cc:517
comments_const_iterator comments_end() const
std::pair< int, int > PDFGUP
Definition: LesHouches.h:88
headers_const_iterator headers_end() const
T sqrt(T t)
Definition: SSEVec.h:19
std::vector< std::string > findHeader(const std::string &tag) const
Definition: LHERunInfo.cc:424
LHERunInfo(std::istream &in)
Definition: LHERunInfo.cc:38
void statistics() const
Definition: LHERunInfo.cc:245
std::vector< double > XERRUP
Definition: LesHouches.h:118
bool operator==(const LHERunInfo &other) const
Definition: LHERunInfo.cc:117
std::vector< double > XMAXUP
Definition: LesHouches.h:123
std::vector< Process > processesLumi
Definition: LHERunInfo.h:168
std::pair< int, int > PDFSUP
Definition: LesHouches.h:94
std::vector< std::string > comments
Definition: LHERunInfo.h:160
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:79
std::vector< Header > headers
Definition: LHERunInfo.h:159
comments_const_iterator comments_begin() const
void count(int process, CountMode count, double eventWeight=1.0, double brWeight=1.0, double matchWeight=1.0)
Definition: LHERunInfo.cc:119
std::vector< double > XSECUP
Definition: LesHouches.h:112
XSec xsec() const
Definition: LHERunInfo.cc:163
tmp
align.sh
Definition: createJobs.py:716
static void fillLines(std::vector< std::string > &lines, const char *data, int len=-1)
Definition: LHERunInfo.cc:391
static std::string const source
Definition: EdmProvDump.cc:49
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
std::vector< int > LPRUP
Definition: LesHouches.h:128
#define LogDebug(id)