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