CMS 3D CMS Logo

GenXSecAnalyzer.cc
Go to the documentation of this file.
2 #include "TMath.h"
3 #include <iostream>
4 #include <iomanip>
5 
6 // analyzer of a summary information product on filter efficiency for a user specified path
7 // meant for the generator filter efficiency calculation
8 
9 // system include files
10 #include <memory>
11 #include <vector>
12 #include <map>
13 
14 // user include files
17 
28 
30 
31 //
32 // class declaration
33 //
34 namespace gxsec {
35  struct LumiCache {};
36  struct RunCache {
38  : product_(-9999),
39  filterOnlyEffRun_(0, 0, 0, 0, 0., 0., 0., 0.),
40  hepMCFilterEffRun_(0, 0, 0, 0, 0., 0., 0., 0.) {}
41  // for weight before GenFilter and HepMCFilter and before matching
43 
44  // for weight after GenFilter and HepMCFilter and after matching
46 
47  // GenLumiInfo before HepMCFilter and GenFilter, this is used
48  // for computation
50 
51  // statistics from additional generator filter, for computation
52  // reset for each run
54 
55  // statistics from HepMC filter, for computation
57 
58  // the following vectors all have the same size
59  // LHE or Pythia/Herwig cross section of previous luminosity block
60  // vector size = number of processes, used for computation
61  CMS_THREAD_GUARD(GenXSecAnalyzer::mutex_) mutable std::map<int, GenLumiInfoProduct::XSec> previousLumiBlockLHEXSec_;
62 
63  // LHE or Pythia/Herwig combined cross section of current luminosity block
64  // updated for each luminosity block, initialized in every run
65  // used for computation
66  CMS_THREAD_GUARD(GenXSecAnalyzer::mutex_) mutable std::map<int, GenLumiInfoProduct::XSec> currentLumiBlockLHEXSec_;
67  };
68 } // namespace gxsec
69 
71  : public edm::global::EDAnalyzer<edm::RunCache<gxsec::RunCache>, edm::LuminosityBlockCache<gxsec::LumiCache>> {
72 public:
73  explicit GenXSecAnalyzer(const edm::ParameterSet &);
74  ~GenXSecAnalyzer() override;
75 
76 private:
77  void beginJob() final;
78  std::shared_ptr<gxsec::RunCache> globalBeginRun(edm::Run const &, edm::EventSetup const &) const final;
79  std::shared_ptr<gxsec::LumiCache> globalBeginLuminosityBlock(edm::LuminosityBlock const &,
80  edm::EventSetup const &) const final;
81  void analyze(edm::StreamID, const edm::Event &, const edm::EventSetup &) const final;
82  void globalEndLuminosityBlock(edm::LuminosityBlock const &, edm::EventSetup const &) const final;
83  void globalEndRun(edm::Run const &, edm::EventSetup const &) const final;
84  void endJob() final;
85  // computation of cross section after matching and before HepcFilter and GenFilter
87  // combination of cross section from different MCs after matching (could be either before or after HepcFilter and GenFilter)
88  void combine(GenLumiInfoProduct::XSec &, double &, const GenLumiInfoProduct::XSec &, const double &) const;
89  void combine(double &, double &, double &, const double &, const double &, const double &) const;
90 
95 
96  // ----------member data --------------------------
97 
98  mutable std::atomic<int> nMCs_;
99 
100  mutable std::atomic<int> hepidwtup_;
101 
103 
104  // for weight before GenFilter and HepMCFilter and before matching
106 
107  // for weight after GenFilter and HepMCFilter and after matching
109 
110  // combined cross sections before HepMCFilter and GenFilter
112 
113  // final combined cross sections
115 
116  // statistics from additional generator filter, for print-out only
118 
119  // statistics from HepMC filter, for print-out only
121 
122  // the vector/map size is the number of LHE processes + 1
123  // needed only for printouts, not used for computation
124  // only printed out when combining the same physics process
125  // uncertainty-averaged cross sections before matching
126  CMS_THREAD_GUARD(mutex_) mutable std::vector<GenLumiInfoProduct::XSec> xsecBeforeMatching_;
127  // uncertainty-averaged cross sections after matching
128  CMS_THREAD_GUARD(mutex_) mutable std::vector<GenLumiInfoProduct::XSec> xsecAfterMatching_;
129  // statistics from jet matching
130  CMS_THREAD_GUARD(mutex_) mutable std::map<int, GenFilterInfo> jetMatchEffStat_;
131 };
132 
134  : nMCs_(0),
135  hepidwtup_(-9999),
136  totalWeightPre_(0),
137  totalWeight_(0),
138  xsecPreFilter_(-1, -1),
139  xsec_(-1, -1),
140  filterOnlyEffStat_(0, 0, 0, 0, 0., 0., 0., 0.),
141  hepMCFilterEffStat_(0, 0, 0, 0, 0., 0., 0., 0.) {
142  genFilterInfoToken_ = consumes<GenFilterInfo, edm::InLumi>(edm::InputTag("genFilterEfficiencyProducer", ""));
143  hepMCFilterInfoToken_ = consumes<GenFilterInfo, edm::InLumi>(edm::InputTag("generator", ""));
144  genLumiInfoToken_ = consumes<GenLumiInfoProduct, edm::InLumi>(edm::InputTag("generator", ""));
145  lheRunInfoToken_ = consumes<LHERunInfoProduct, edm::InRun>(edm::InputTag("externalLHEProducer", ""));
146 }
147 
149 
151 
152 std::shared_ptr<gxsec::RunCache> GenXSecAnalyzer::globalBeginRun(edm::Run const &iRun, edm::EventSetup const &) const {
153  // initialization for every different physics MC
154 
155  nMCs_++;
156 
157  {
158  std::lock_guard l{mutex_};
159  xsecBeforeMatching_.clear();
160  xsecAfterMatching_.clear();
161  jetMatchEffStat_.clear();
162  }
163  return std::make_shared<gxsec::RunCache>();
164 }
165 
166 std::shared_ptr<gxsec::LumiCache> GenXSecAnalyzer::globalBeginLuminosityBlock(edm::LuminosityBlock const &iLumi,
167  edm::EventSetup const &) const {
168  return std::shared_ptr<gxsec::LumiCache>();
169 }
170 
172 
176  if (!genLumiInfo.isValid())
177  return;
178  hepidwtup_ = genLumiInfo->getHEPIDWTUP();
179 
180  std::vector<GenLumiInfoProduct::ProcessInfo> const &theProcesses = genLumiInfo->getProcessInfos();
181 
182  unsigned int theProcesses_size = theProcesses.size();
183 
184  // if it's a pure parton-shower generator, check there should be only one element in thisProcessInfos
185  // the error of lheXSec is -1
186  if (hepidwtup_ == -1) {
187  if (theProcesses_size != 1) {
188  edm::LogError("GenXSecAnalyzer::endLuminosityBlock") << "Pure parton shower has thisProcessInfos size!=1";
189  return;
190  }
191  }
192 
193  for (unsigned int ip = 0; ip < theProcesses_size; ip++) {
194  if (theProcesses[ip].lheXSec().value() < 0) {
195  edm::LogError("GenXSecAnalyzer::endLuminosityBlock")
196  << "cross section of process " << ip << " value = " << theProcesses[ip].lheXSec().value();
197  return;
198  }
199  }
200 
201  auto runC = runCache(iLumi.getRun().index());
202  {
203  std::lock_guard g{mutex_};
204  runC->product_.mergeProduct(*genLumiInfo);
205  }
206  edm::Handle<GenFilterInfo> genFilter;
207  iLumi.getByToken(genFilterInfoToken_, genFilter);
208 
209  if (genFilter.isValid()) {
210  std::lock_guard g{mutex_};
211  filterOnlyEffStat_.mergeProduct(*genFilter);
212  runC->filterOnlyEffRun_.mergeProduct(*genFilter);
213  runC->thisRunWeight_ += genFilter->sumPassWeights();
214  }
215 
216  edm::Handle<GenFilterInfo> hepMCFilter;
217  iLumi.getByToken(hepMCFilterInfoToken_, hepMCFilter);
218 
219  if (hepMCFilter.isValid()) {
220  std::lock_guard g{mutex_};
221  hepMCFilterEffStat_.mergeProduct(*hepMCFilter);
222  runC->hepMCFilterEffRun_.mergeProduct(*hepMCFilter);
223  }
224 
225  std::lock_guard g{mutex_};
226  // doing generic summing for jet matching statistics
227  // and computation of combined LHE information
228  for (unsigned int ip = 0; ip < theProcesses_size; ip++) {
229  int id = theProcesses[ip].process();
231  GenLumiInfoProduct::XSec &y = runC->currentLumiBlockLHEXSec_[id];
232  GenLumiInfoProduct::FinalStat temp_killed = theProcesses[ip].killed();
233  GenLumiInfoProduct::FinalStat temp_selected = theProcesses[ip].selected();
234  double passw = temp_killed.sum();
235  double passw2 = temp_killed.sum2();
236  double totalw = temp_selected.sum();
237  double totalw2 = temp_selected.sum2();
238  GenFilterInfo tempInfo(theProcesses[ip].nPassPos(),
239  theProcesses[ip].nPassNeg(),
240  theProcesses[ip].nTotalPos(),
241  theProcesses[ip].nTotalNeg(),
242  passw,
243  passw2,
244  totalw,
245  totalw2);
246 
247  // matching statistics for all processes
248  jetMatchEffStat_[10000].mergeProduct(tempInfo);
249  double currentValue = theProcesses[ip].lheXSec().value();
250  double currentError = theProcesses[ip].lheXSec().error();
251 
252  // this process ID has occurred before
253  auto &thisRunWeightPre = runC->thisRunWeightPre_;
254  if (y.value() > 0) {
255  x.mergeProduct(tempInfo);
256  double previousValue = runC->previousLumiBlockLHEXSec_[id].value();
257 
258  if (currentValue != previousValue) // transition of cross section
259  {
260  double xsec = y.value();
261  double err = y.error();
262  combine(xsec, err, thisRunWeightPre, currentValue, currentError, totalw);
263  y = GenLumiInfoProduct::XSec(xsec, err);
264  } else // LHE cross section is the same as previous lumiblock
265  thisRunWeightPre += totalw;
266 
267  }
268  // this process ID has never occurred before
269  else {
270  x = tempInfo;
271  y = theProcesses[ip].lheXSec();
272  thisRunWeightPre += totalw;
273  }
274 
275  runC->previousLumiBlockLHEXSec_[id] = theProcesses[ip].lheXSec();
276  } // end
277 
278  return;
279 }
280 
281 void GenXSecAnalyzer::globalEndRun(edm::Run const &iRun, edm::EventSetup const &) const {
282  //xsection before matching
284 
285  if (iRun.getByToken(lheRunInfoToken_, run)) {
286  const lhef::HEPRUP thisHeprup = run->heprup();
287 
288  for (unsigned int iSize = 0; iSize < thisHeprup.XSECUP.size(); iSize++) {
289  std::cout << std::setw(14) << std::fixed << thisHeprup.XSECUP[iSize] << std::setw(14) << std::fixed
290  << thisHeprup.XERRUP[iSize] << std::setw(14) << std::fixed << thisHeprup.XMAXUP[iSize] << std::setw(14)
291  << std::fixed << thisHeprup.LPRUP[iSize] << std::endl;
292  }
293  std::cout << " " << std::endl;
294  }
295 
296  auto runC = runCache(iRun.index());
297  std::lock_guard l{mutex_};
298 
299  // compute cross section for this run first
300  // set the correct combined LHE+filter cross sections
301  unsigned int i = 0;
302  std::vector<GenLumiInfoProduct::ProcessInfo> newInfos;
303  for (std::map<int, GenLumiInfoProduct::XSec>::const_iterator iter = runC->currentLumiBlockLHEXSec_.begin();
304  iter != runC->currentLumiBlockLHEXSec_.end();
305  ++iter, i++) {
306  GenLumiInfoProduct::ProcessInfo temp = runC->product_.getProcessInfos()[i];
307  temp.setLheXSec(iter->second.value(), iter->second.error());
308  newInfos.push_back(temp);
309  }
310  runC->product_.setProcessInfo(newInfos);
311 
312  const GenLumiInfoProduct::XSec thisRunXSecPre = compute(runC->product_);
313  // xsection after matching before filters
314  combine(xsecPreFilter_, totalWeightPre_, thisRunXSecPre, runC->thisRunWeightPre_);
315 
316  double thisHepFilterEff = 1;
317  double thisHepFilterErr = 0;
318 
319  if (runC->hepMCFilterEffRun_.sumWeights2() > 0) {
320  thisHepFilterEff = runC->hepMCFilterEffRun_.filterEfficiency(hepidwtup_);
321  thisHepFilterErr = runC->hepMCFilterEffRun_.filterEfficiencyError(hepidwtup_);
322  if (thisHepFilterEff < 0) {
323  thisHepFilterEff = 1;
324  thisHepFilterErr = 0;
325  }
326  }
327 
328  double thisGenFilterEff = 1;
329  double thisGenFilterErr = 0;
330 
331  if (runC->filterOnlyEffRun_.sumWeights2() > 0) {
332  thisGenFilterEff = runC->filterOnlyEffRun_.filterEfficiency(hepidwtup_);
333  thisGenFilterErr = runC->filterOnlyEffRun_.filterEfficiencyError(hepidwtup_);
334  if (thisGenFilterEff < 0) {
335  thisGenFilterEff = 1;
336  thisGenFilterErr = 0;
337  }
338  }
339  double thisXsec = thisRunXSecPre.value() > 0 ? thisHepFilterEff * thisGenFilterEff * thisRunXSecPre.value() : 0;
340  double thisErr =
341  thisRunXSecPre.value() > 0
342  ? thisXsec * sqrt(pow(TMath::Max(thisRunXSecPre.error(), (double)0) / thisRunXSecPre.value(), 2) +
343  pow(thisHepFilterErr / thisHepFilterEff, 2) + pow(thisGenFilterErr / thisGenFilterEff, 2))
344  : 0;
345  const GenLumiInfoProduct::XSec thisRunXSec = GenLumiInfoProduct::XSec(thisXsec, thisErr);
346  combine(xsec_, totalWeight_, thisRunXSec, runC->thisRunWeight_);
347 }
348 
349 void GenXSecAnalyzer::combine(double &finalValue,
350  double &finalError,
351  double &finalWeight,
352  const double &currentValue,
353  const double &currentError,
354  const double &currentWeight) const {
355  if (finalValue <= 0) {
356  finalValue = currentValue;
357  finalError = currentError;
358  finalWeight += currentWeight;
359  } else {
360  double wgt1 = (finalError <= 0 || currentError <= 0) ? finalWeight : 1 / (finalError * finalError);
361  double wgt2 = (finalError <= 0 || currentError <= 0) ? currentWeight : 1 / (currentError * currentError);
362  double xsec = (wgt1 * finalValue + wgt2 * currentValue) / (wgt1 + wgt2);
363  double err = (finalError <= 0 || currentError <= 0) ? 0 : 1.0 / std::sqrt(wgt1 + wgt2);
364  finalValue = xsec;
365  finalError = err;
366  finalWeight += currentWeight;
367  }
368  return;
369 }
370 
372  double &totalw,
373  const GenLumiInfoProduct::XSec &thisRunXSec,
374  const double &thisw) const {
375  double value = finalXSec.value();
376  double error = finalXSec.error();
377  double thisValue = thisRunXSec.value();
378  double thisError = thisRunXSec.error();
379  combine(value, error, totalw, thisValue, thisError, thisw);
380  finalXSec = GenLumiInfoProduct::XSec(value, error);
381  return;
382 }
383 
385  // sum of cross sections and errors over different processes
386  double sigSelSum = 0.0;
387  double err2SelSum = 0.0;
388  double sigSum = 0.0;
389  double err2Sum = 0.0;
390 
391  std::vector<GenLumiInfoProduct::XSec> tempVector_before;
392  std::vector<GenLumiInfoProduct::XSec> tempVector_after;
393 
394  // loop over different processes for each sample
395  unsigned int vectorSize = iLumiInfo.getProcessInfos().size();
396  for (unsigned int ip = 0; ip < vectorSize; ip++) {
398  double hepxsec_value = proc.lheXSec().value();
399  double hepxsec_error = proc.lheXSec().error() <= 0 ? 0 : proc.lheXSec().error();
400  tempVector_before.push_back(GenLumiInfoProduct::XSec(hepxsec_value, hepxsec_error));
401 
402  sigSelSum += hepxsec_value;
403  err2SelSum += hepxsec_error * hepxsec_error;
404 
405  // skips computation if jet matching efficiency=0
406  if (proc.killed().n() < 1) {
407  tempVector_after.push_back(GenLumiInfoProduct::XSec(0.0, 0.0));
408  continue;
409  }
410 
411  // computing jet matching efficiency for this process
412  double fracAcc = 0;
413  double ntotal = proc.nTotalPos() - proc.nTotalNeg();
414  double npass = proc.nPassPos() - proc.nPassNeg();
415  switch (hepidwtup_) {
416  case 3:
417  case -3:
418  fracAcc = ntotal > 0 ? npass / ntotal : -1;
419  break;
420  default:
421  fracAcc = proc.selected().sum() > 0 ? proc.killed().sum() / proc.selected().sum() : -1;
422  break;
423  }
424 
425  if (fracAcc <= 0) {
426  tempVector_after.push_back(GenLumiInfoProduct::XSec(0.0, 0.0));
427  continue;
428  }
429 
430  // cross section after matching for this particular process
431  double sigmaFin = hepxsec_value * fracAcc;
432 
433  // computing error on jet matching efficiency
434  double relErr = 1.0;
435  double efferr2 = 0;
436  switch (hepidwtup_) {
437  case 3:
438  case -3: {
439  double ntotal_pos = proc.nTotalPos();
440  double effp = ntotal_pos > 0 ? (double)proc.nPassPos() / ntotal_pos : 0;
441  double effp_err2 = ntotal_pos > 0 ? (1 - effp) * effp / ntotal_pos : 0;
442 
443  double ntotal_neg = proc.nTotalNeg();
444  double effn = ntotal_neg > 0 ? (double)proc.nPassNeg() / ntotal_neg : 0;
445  double effn_err2 = ntotal_neg > 0 ? (1 - effn) * effn / ntotal_neg : 0;
446 
447  efferr2 = ntotal > 0
448  ? (ntotal_pos * ntotal_pos * effp_err2 + ntotal_neg * ntotal_neg * effn_err2) / ntotal / ntotal
449  : 0;
450  break;
451  }
452  default: {
453  double denominator = pow(proc.selected().sum(), 4);
454  double passw = proc.killed().sum();
455  double passw2 = proc.killed().sum2();
456  double failw = proc.selected().sum() - passw;
457  double failw2 = proc.selected().sum2() - passw2;
458  double numerator = (passw2 * failw * failw + failw2 * passw * passw);
459 
460  efferr2 = denominator > 0 ? numerator / denominator : 0;
461  break;
462  }
463  }
464  double delta2Veto = efferr2 / fracAcc / fracAcc;
465 
466  // computing total error on cross section after matching efficiency
467 
468  double sigma2Sum, sigma2Err;
469  sigma2Sum = hepxsec_value * hepxsec_value;
470  sigma2Err = hepxsec_error * hepxsec_error;
471 
472  double delta2Sum = delta2Veto + sigma2Err / sigma2Sum;
473  relErr = (delta2Sum > 0.0 ? std::sqrt(delta2Sum) : 0.0);
474  double deltaFin = sigmaFin * relErr;
475 
476  tempVector_after.push_back(GenLumiInfoProduct::XSec(sigmaFin, deltaFin));
477 
478  // sum of cross sections and errors over different processes
479  sigSum += sigmaFin;
480  err2Sum += deltaFin * deltaFin;
481 
482  } // end of loop over different processes
483  tempVector_before.push_back(GenLumiInfoProduct::XSec(sigSelSum, sqrt(err2SelSum)));
484 
485  double total_matcheff = jetMatchEffStat_[10000].filterEfficiency(hepidwtup_);
486  double total_matcherr = jetMatchEffStat_[10000].filterEfficiencyError(hepidwtup_);
487 
488  double xsec_after = sigSelSum * total_matcheff;
489  double xsecerr_after = (total_matcheff > 0 && sigSelSum > 0)
490  ? xsec_after * sqrt(err2SelSum / sigSelSum / sigSelSum +
491  total_matcherr * total_matcherr / total_matcheff / total_matcheff)
492  : 0;
493 
494  GenLumiInfoProduct::XSec result(xsec_after, xsecerr_after);
495  tempVector_after.push_back(result);
496 
497  xsecBeforeMatching_ = tempVector_before;
498  xsecAfterMatching_ = tempVector_after;
499 
500  return result;
501 }
502 
504  edm::LogPrint("GenXSecAnalyzer") << "\n"
505  << "------------------------------------"
506  << "\n"
507  << "GenXsecAnalyzer:"
508  << "\n"
509  << "------------------------------------";
510 
511  if (jetMatchEffStat_.empty()) {
512  edm::LogPrint("GenXSecAnalyzer") << "------------------------------------"
513  << "\n"
514  << "Cross-section summary not available"
515  << "\n"
516  << "------------------------------------";
517  return;
518  }
519 
520  // fraction of negative weights
521  double final_fract_neg_w = 0;
522  double final_fract_neg_w_unc = 0;
523 
524  // below print out is only for combination of same physics MC samples and ME+Pythia MCs
525 
526  if (nMCs_ == 1 && hepidwtup_ != -1) {
527  edm::LogPrint("GenXSecAnalyzer")
528  << "-----------------------------------------------------------------------------------------------------------"
529  "--------------------------------------------------------------- \n"
530  << "Overall cross-section summary \n"
531  << "-----------------------------------------------------------------------------------------------------------"
532  "---------------------------------------------------------------";
533  edm::LogPrint("GenXSecAnalyzer") << "Process\t\txsec_before [pb]\t\tpassed\tnposw\tnnegw\ttried\tnposw\tnnegw "
534  "\txsec_match [pb]\t\t\taccepted [%]\t event_eff [%]";
535 
536  const unsigned sizeOfInfos = jetMatchEffStat_.size();
537  const unsigned last = sizeOfInfos - 1;
538  std::string *title = new std::string[sizeOfInfos];
539  unsigned int i = 0;
540  double jetmatch_eff = 0;
541  double jetmatch_err = 0;
542  double matching_eff = 1;
543  double matching_efferr = 1;
544 
545  for (std::map<int, GenFilterInfo>::const_iterator iter = jetMatchEffStat_.begin(); iter != jetMatchEffStat_.end();
546  ++iter, i++) {
547  GenFilterInfo thisJetMatchStat = iter->second;
548  GenFilterInfo thisEventEffStat =
549  GenFilterInfo(thisJetMatchStat.numPassPositiveEvents() + thisJetMatchStat.numPassNegativeEvents(),
550  0,
551  thisJetMatchStat.numTotalPositiveEvents() + thisJetMatchStat.numTotalNegativeEvents(),
552  0,
553  thisJetMatchStat.numPassPositiveEvents() + thisJetMatchStat.numPassNegativeEvents(),
554  thisJetMatchStat.numPassPositiveEvents() + thisJetMatchStat.numPassNegativeEvents(),
555  thisJetMatchStat.numTotalPositiveEvents() + thisJetMatchStat.numTotalNegativeEvents(),
556  thisJetMatchStat.numTotalPositiveEvents() + thisJetMatchStat.numTotalNegativeEvents());
557 
558  jetmatch_eff = thisJetMatchStat.filterEfficiency(hepidwtup_);
559  jetmatch_err = thisJetMatchStat.filterEfficiencyError(hepidwtup_);
560 
561  if (i == last) {
562  title[i] = "Total";
563 
564  edm::LogPrint("GenXSecAnalyzer")
565  << "-------------------------------------------------------------------------------------------------------"
566  "------------------------------------------------------------------- ";
567 
568  // fill negative fraction of negative weights and uncertainty after matching
569  final_fract_neg_w = thisEventEffStat.numEventsPassed() > 0
570  ? thisJetMatchStat.numPassNegativeEvents() / thisEventEffStat.numEventsPassed()
571  : 0;
572  final_fract_neg_w_unc =
573  thisJetMatchStat.numPassNegativeEvents() > 0
574  ? final_fract_neg_w * final_fract_neg_w / thisEventEffStat.numEventsPassed() *
575  sqrt(thisJetMatchStat.numPassPositiveEvents() * thisJetMatchStat.numPassPositiveEvents() /
576  thisJetMatchStat.numPassNegativeEvents() +
577  thisJetMatchStat.numPassPositiveEvents())
578  : 0;
579  } else {
580  title[i] = Form("%d", i);
581  }
582 
583  edm::LogPrint("GenXSecAnalyzer") << title[i] << "\t\t" << std::scientific << std::setprecision(3)
584  << xsecBeforeMatching_[i].value() << " +/- " << xsecBeforeMatching_[i].error()
585  << "\t\t" << thisEventEffStat.numEventsPassed() << "\t"
586  << thisJetMatchStat.numPassPositiveEvents() << "\t"
587  << thisJetMatchStat.numPassNegativeEvents() << "\t"
588  << thisEventEffStat.numEventsTotal() << "\t"
589  << thisJetMatchStat.numTotalPositiveEvents() << "\t"
590  << thisJetMatchStat.numTotalNegativeEvents() << "\t" << std::scientific
591  << std::setprecision(3) << xsecAfterMatching_[i].value() << " +/- "
592  << xsecAfterMatching_[i].error() << "\t\t" << std::fixed << std::setprecision(1)
593  << (jetmatch_eff * 100) << " +/- " << (jetmatch_err * 100) << "\t" << std::fixed
594  << std::setprecision(1) << (thisEventEffStat.filterEfficiency(+3) * 100)
595  << " +/- " << (thisEventEffStat.filterEfficiencyError(+3) * 100);
596 
597  matching_eff = thisEventEffStat.filterEfficiency(+3);
598  matching_efferr = thisEventEffStat.filterEfficiencyError(+3);
599  }
600  delete[] title;
601 
602  edm::LogPrint("GenXSecAnalyzer")
603  << "-----------------------------------------------------------------------------------------------------------"
604  "---------------------------------------------------------------";
605 
606  edm::LogPrint("GenXSecAnalyzer") << "Before matching: total cross section = " << std::scientific
607  << std::setprecision(3) << xsecBeforeMatching_[last].value() << " +- "
608  << xsecBeforeMatching_[last].error() << " pb";
609 
610  edm::LogPrint("GenXSecAnalyzer") << "After matching: total cross section = " << std::scientific
611  << std::setprecision(3) << xsecAfterMatching_[last].value() << " +- "
612  << xsecAfterMatching_[last].error() << " pb";
613 
614  edm::LogPrint("GenXSecAnalyzer") << "Matching efficiency = " << std::fixed << std::setprecision(1) << matching_eff
615  << " +/- " << matching_efferr << " [TO BE USED IN MCM]";
616 
617  } else if (hepidwtup_ == -1)
618  edm::LogPrint("GenXSecAnalyzer") << "Before Filter: total cross section = " << std::scientific
619  << std::setprecision(3) << xsecPreFilter_.value() << " +- "
620  << xsecPreFilter_.error() << " pb";
621 
622  // hepMC filter efficiency
623  double hepMCFilter_eff = 1.0;
624  double hepMCFilter_err = 0.0;
625  if (hepMCFilterEffStat_.sumWeights2() > 0) {
626  hepMCFilter_eff = hepMCFilterEffStat_.filterEfficiency(-1);
627  hepMCFilter_err = hepMCFilterEffStat_.filterEfficiencyError(-1);
628  edm::LogPrint("GenXSecAnalyzer") << "HepMC filter efficiency (taking into account weights)= "
629  << "(" << hepMCFilterEffStat_.sumPassWeights() << ")"
630  << " / "
631  << "(" << hepMCFilterEffStat_.sumWeights() << ")"
632  << " = " << std::scientific << std::setprecision(3) << hepMCFilter_eff << " +- "
633  << hepMCFilter_err;
634 
635  double hepMCFilter_event_total =
637  double hepMCFilter_event_pass =
639  double hepMCFilter_event_eff = hepMCFilter_event_total > 0 ? hepMCFilter_event_pass / hepMCFilter_event_total : 0;
640  double hepMCFilter_event_err =
641  hepMCFilter_event_total > 0
642  ? sqrt((1 - hepMCFilter_event_eff) * hepMCFilter_event_eff / hepMCFilter_event_total)
643  : -1;
644  edm::LogPrint("GenXSecAnalyzer") << "HepMC filter efficiency (event-level)= "
645  << "(" << hepMCFilter_event_pass << ")"
646  << " / "
647  << "(" << hepMCFilter_event_total << ")"
648  << " = " << std::scientific << std::setprecision(3) << hepMCFilter_event_eff
649  << " +- " << hepMCFilter_event_err;
650  }
651 
652  // gen-particle filter efficiency
653  if (filterOnlyEffStat_.sumWeights2() > 0) {
654  double filterOnly_eff = filterOnlyEffStat_.filterEfficiency(-1);
655  double filterOnly_err = filterOnlyEffStat_.filterEfficiencyError(-1);
656 
657  edm::LogPrint("GenXSecAnalyzer") << "Filter efficiency (taking into account weights)= "
658  << "(" << filterOnlyEffStat_.sumPassWeights() << ")"
659  << " / "
660  << "(" << filterOnlyEffStat_.sumWeights() << ")"
661  << " = " << std::scientific << std::setprecision(3) << filterOnly_eff << " +- "
662  << filterOnly_err;
663 
664  double filterOnly_event_total =
666  double filterOnly_event_pass =
668  double filterOnly_event_eff = filterOnly_event_total > 0 ? filterOnly_event_pass / filterOnly_event_total : 0;
669  double filterOnly_event_err = filterOnly_event_total > 0
670  ? sqrt((1 - filterOnly_event_eff) * filterOnly_event_eff / filterOnly_event_total)
671  : -1;
672  edm::LogPrint("GenXSecAnalyzer") << "Filter efficiency (event-level)= "
673  << "(" << filterOnly_event_pass << ")"
674  << " / "
675  << "(" << filterOnly_event_total << ")"
676  << " = " << std::scientific << std::setprecision(3) << filterOnly_event_eff
677  << " +- " << filterOnly_event_err << " [TO BE USED IN MCM]";
678 
679  // fill negative fraction of negative weights and uncertainty after filter
680  final_fract_neg_w =
681  filterOnly_event_pass > 0 ? filterOnlyEffStat_.numPassNegativeEvents() / (filterOnly_event_pass) : 0;
682  final_fract_neg_w_unc =
684  ? final_fract_neg_w * final_fract_neg_w / filterOnly_event_pass *
688  : 0;
689  }
690 
691  edm::LogPrint("GenXSecAnalyzer") << "\nAfter filter: final cross section = " << std::scientific
692  << std::setprecision(3) << xsec_.value() << " +- " << xsec_.error() << " pb";
693 
694  edm::LogPrint("GenXSecAnalyzer") << "After filter: final fraction of events with negative weights = "
695  << std::scientific << std::setprecision(3) << final_fract_neg_w << " +- "
696  << final_fract_neg_w_unc;
697 
698  // L=[N*(1-2f)^2]/s
699  double lumi_1M_evts =
700  xsec_.value() > 0 ? 1e6 * (1 - 2 * final_fract_neg_w) * (1 - 2 * final_fract_neg_w) / xsec_.value() / 1e3 : 0;
701  double lumi_1M_evts_unc =
702  xsec_.value() > 0 ? (1 - 2 * final_fract_neg_w) * lumi_1M_evts *
703  sqrt(1e-6 + 16 * pow(final_fract_neg_w_unc, 2) / pow(1 - 2 * final_fract_neg_w, 2) +
704  pow(xsec_.error() / xsec_.value(), 2))
705  : 0;
706  edm::LogPrint("GenXSecAnalyzer") << "After filter: final equivalent lumi for 1M events (1/fb) = " << std::scientific
707  << std::setprecision(3) << lumi_1M_evts << " +- " << lumi_1M_evts_unc;
708 }
709 
std::vector< GenLumiInfoProduct::XSec > xsecBeforeMatching_
std::shared_ptr< gxsec::LumiCache > globalBeginLuminosityBlock(edm::LuminosityBlock const &, edm::EventSetup const &) const final
std::map< int, GenFilterInfo > jetMatchEffStat_
edm::EDGetTokenT< GenFilterInfo > hepMCFilterInfoToken_
GenLumiInfoProduct product_
Run const & getRun() const
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
static std::mutex mutex
Definition: Proxy.cc:8
GenFilterInfo filterOnlyEffStat_
edm::EDGetTokenT< GenLumiInfoProduct > genLumiInfoToken_
void combine(GenLumiInfoProduct::XSec &, double &, const GenLumiInfoProduct::XSec &, const double &) const
GenLumiInfoProduct::XSec compute(const GenLumiInfoProduct &) const
GenFilterInfo filterOnlyEffRun_
unsigned int numTotalNegativeEvents() const
Definition: GenFilterInfo.h:29
Log< level::Error, false > LogError
void globalEndRun(edm::Run const &, edm::EventSetup const &) const final
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e g
Definition: Activities.doc:4
std::atomic< int > hepidwtup_
double sumWeights2() const
Definition: GenFilterInfo.h:38
unsigned int numPassNegativeEvents() const
Definition: GenFilterInfo.h:28
GenLumiInfoProduct::XSec xsec_
unsigned int numTotalPositiveEvents() const
Definition: GenFilterInfo.h:26
void globalEndLuminosityBlock(edm::LuminosityBlock const &, edm::EventSetup const &) const final
GenFilterInfo hepMCFilterEffStat_
bool mergeProduct(GenFilterInfo const &other)
void analyze(edm::StreamID, const edm::Event &, const edm::EventSetup &) const final
const std::vector< ProcessInfo > & getProcessInfos() const
T sqrt(T t)
Definition: SSEVec.h:19
void beginJob() final
#define CMS_THREAD_GUARD(_var_)
double sumPassWeights() const
Definition: GenFilterInfo.h:31
Definition: value.py:1
Log< level::Warning, true > LogPrint
std::vector< double > XERRUP
Definition: LesHouches.h:118
std::vector< double > XMAXUP
Definition: LesHouches.h:123
double filterEfficiency(int idwtup=+3) const
bool getByToken(EDGetToken token, Handle< PROD > &result) const
double sumWeights() const
Definition: GenFilterInfo.h:37
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Run.h:318
double filterEfficiencyError(int idwtup=+3) const
unsigned int numEventsPassed() const
Definition: GenFilterInfo.h:22
unsigned int numPassPositiveEvents() const
Definition: GenFilterInfo.h:25
bool isValid() const
Definition: HandleBase.h:70
edm::EDGetTokenT< GenFilterInfo > genFilterInfoToken_
RunIndex index() const
Definition: Run.cc:26
GenXSecAnalyzer(const edm::ParameterSet &)
std::vector< GenLumiInfoProduct::XSec > xsecAfterMatching_
~GenXSecAnalyzer() override
edm::EDGetTokenT< LHERunInfoProduct > lheRunInfoToken_
std::vector< double > XSECUP
Definition: LesHouches.h:112
unsigned int numEventsTotal() const
Definition: GenFilterInfo.h:23
std::map< int, GenLumiInfoProduct::XSec > currentLumiBlockLHEXSec_
std::shared_ptr< gxsec::RunCache > globalBeginRun(edm::Run const &, edm::EventSetup const &) const final
GenFilterInfo hepMCFilterEffRun_
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
GenLumiInfoProduct::XSec xsecPreFilter_
std::atomic< int > nMCs_
void endJob() final
Definition: Run.h:45
std::vector< int > LPRUP
Definition: LesHouches.h:128
std::map< int, GenLumiInfoProduct::XSec > previousLumiBlockLHEXSec_