89 void combine(
double &,
double &,
double &,
const double &,
const double &,
const double &)
const;
138 xsecPreFilter_(-1, -1),
140 filterOnlyEffStat_(0, 0, 0, 0, 0., 0., 0., 0.),
141 hepMCFilterEffStat_(0, 0, 0, 0, 0., 0., 0., 0.) {
163 return std::make_shared<gxsec::RunCache>();
168 return std::shared_ptr<gxsec::LumiCache>();
180 std::vector<GenLumiInfoProduct::ProcessInfo>
const &theProcesses =
genLumiInfo->getProcessInfos();
182 unsigned int theProcesses_size = theProcesses.size();
187 if (theProcesses_size != 1) {
188 edm::LogError(
"GenXSecAnalyzer::endLuminosityBlock") <<
"Pure parton shower has thisProcessInfos size!=1";
193 for (
unsigned int ip = 0; ip < theProcesses_size; ip++) {
194 if (theProcesses[ip].lheXSec().
value() < 0) {
196 <<
"cross section of process " << ip <<
" value = " << theProcesses[ip].lheXSec().value();
212 runC->filterOnlyEffRun_.mergeProduct(*genFilter);
222 runC->hepMCFilterEffRun_.mergeProduct(*hepMCFilter);
228 for (
unsigned int ip = 0; ip < theProcesses_size; ip++) {
229 int id = theProcesses[ip].process();
234 double passw = temp_killed.
sum();
235 double passw2 = temp_killed.
sum2();
236 double totalw = temp_selected.
sum();
237 double totalw2 = temp_selected.
sum2();
239 theProcesses[ip].nPassNeg(),
240 theProcesses[ip].nTotalPos(),
241 theProcesses[ip].nTotalNeg(),
249 double currentValue = theProcesses[ip].lheXSec().value();
250 double currentError = theProcesses[ip].lheXSec().error();
253 auto &thisRunWeightPre = runC->thisRunWeightPre_;
255 x.mergeProduct(tempInfo);
256 double previousValue = runC->previousLumiBlockLHEXSec_[
id].value();
258 if (currentValue != previousValue)
260 double xsec =
y.value();
261 double err =
y.error();
262 combine(xsec,
err, thisRunWeightPre, currentValue, currentError, totalw);
265 thisRunWeightPre += totalw;
271 y = theProcesses[ip].lheXSec();
272 thisRunWeightPre += totalw;
275 runC->previousLumiBlockLHEXSec_[
id] = theProcesses[ip].lheXSec();
288 for (
unsigned int iSize = 0; iSize < thisHeprup.
XSECUP.size(); iSize++) {
296 auto runC = runCache(iRun.
index());
302 std::vector<GenLumiInfoProduct::ProcessInfo> newInfos;
303 for (std::map<int, GenLumiInfoProduct::XSec>::const_iterator iter = runC->currentLumiBlockLHEXSec_.begin();
304 iter != runC->currentLumiBlockLHEXSec_.end();
307 temp.setLheXSec(iter->second.value(), iter->second.error());
308 newInfos.push_back(
temp);
310 runC->product_.setProcessInfo(newInfos);
316 double thisHepFilterEff = 1;
317 double thisHepFilterErr = 0;
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;
328 double thisGenFilterEff = 1;
329 double thisGenFilterErr = 0;
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;
339 double thisXsec = thisRunXSecPre.
value() > 0 ? thisHepFilterEff * thisGenFilterEff * thisRunXSecPre.
value() : 0;
341 thisRunXSecPre.
value() > 0
343 pow(thisHepFilterErr / thisHepFilterEff, 2) +
pow(thisGenFilterErr / thisGenFilterEff, 2))
352 const double ¤tValue,
353 const double ¤tError,
354 const double ¤tWeight)
const {
355 if (finalValue <= 0) {
356 finalValue = currentValue;
357 finalError = currentError;
358 finalWeight += currentWeight;
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);
366 finalWeight += currentWeight;
374 const double &thisw)
const {
377 double thisValue = thisRunXSec.
value();
378 double thisError = thisRunXSec.
error();
386 double sigSelSum = 0.0;
387 double err2SelSum = 0.0;
389 double err2Sum = 0.0;
391 std::vector<GenLumiInfoProduct::XSec> tempVector_before;
392 std::vector<GenLumiInfoProduct::XSec> tempVector_after;
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();
402 sigSelSum += hepxsec_value;
403 err2SelSum += hepxsec_error * hepxsec_error;
406 if (
proc.killed().n() < 1) {
414 double npass =
proc.nPassPos() -
proc.nPassNeg();
421 fracAcc =
proc.selected().sum() > 0 ?
proc.killed().sum() /
proc.selected().sum() : -1;
431 double sigmaFin = hepxsec_value * fracAcc;
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;
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;
448 ? (ntotal_pos * ntotal_pos * effp_err2 + ntotal_neg * ntotal_neg * effn_err2) /
ntotal /
ntotal
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);
464 double delta2Veto = efferr2 / fracAcc / fracAcc;
468 double sigma2Sum, sigma2Err;
469 sigma2Sum = hepxsec_value * hepxsec_value;
470 sigma2Err = hepxsec_error * hepxsec_error;
472 double delta2Sum = delta2Veto + sigma2Err / sigma2Sum;
473 relErr = (delta2Sum > 0.0 ?
std::sqrt(delta2Sum) : 0.0);
474 double deltaFin = sigmaFin * relErr;
480 err2Sum += deltaFin * deltaFin;
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)
495 tempVector_after.push_back(
result);
505 <<
"------------------------------------"
507 <<
"GenXsecAnalyzer:"
509 <<
"------------------------------------";
512 edm::LogPrint(
"GenXSecAnalyzer") <<
"------------------------------------"
514 <<
"Cross-section summary not available"
516 <<
"------------------------------------";
521 double final_fract_neg_w = 0;
522 double final_fract_neg_w_unc = 0;
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 [%]";
537 const unsigned last = sizeOfInfos - 1;
540 double jetmatch_eff = 0;
541 double jetmatch_err = 0;
542 double matching_eff = 1;
543 double matching_efferr = 1;
565 <<
"-------------------------------------------------------------------------------------------------------"
566 "------------------------------------------------------------------- ";
572 final_fract_neg_w_unc =
574 ? final_fract_neg_w * final_fract_neg_w / thisEventEffStat.
numEventsPassed() *
583 edm::LogPrint(
"GenXSecAnalyzer") <<
title[
i] <<
"\t\t" << std::scientific << std::setprecision(3)
593 << (jetmatch_eff * 100) <<
" +/- " << (jetmatch_err * 100) <<
"\t" <<
std::fixed
603 <<
"-----------------------------------------------------------------------------------------------------------"
604 "---------------------------------------------------------------";
606 edm::LogPrint(
"GenXSecAnalyzer") <<
"Before matching: total cross section = " << std::scientific
610 edm::LogPrint(
"GenXSecAnalyzer") <<
"After matching: total cross section = " << std::scientific
614 edm::LogPrint(
"GenXSecAnalyzer") <<
"Matching efficiency = " <<
std::fixed << std::setprecision(1) << matching_eff
615 <<
" +/- " << matching_efferr <<
" [TO BE USED IN MCM]";
618 edm::LogPrint(
"GenXSecAnalyzer") <<
"Before Filter: total cross section = " << std::scientific
623 double hepMCFilter_eff = 1.0;
624 double hepMCFilter_err = 0.0;
628 edm::LogPrint(
"GenXSecAnalyzer") <<
"HepMC filter efficiency (taking into account weights)= "
632 <<
" = " << std::scientific << std::setprecision(3) << hepMCFilter_eff <<
" +- "
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)
644 edm::LogPrint(
"GenXSecAnalyzer") <<
"HepMC filter efficiency (event-level)= "
645 <<
"(" << hepMCFilter_event_pass <<
")"
647 <<
"(" << hepMCFilter_event_total <<
")"
648 <<
" = " << std::scientific << std::setprecision(3) << hepMCFilter_event_eff
649 <<
" +- " << hepMCFilter_event_err;
657 edm::LogPrint(
"GenXSecAnalyzer") <<
"Filter efficiency (taking into account weights)= "
661 <<
" = " << std::scientific << std::setprecision(3) << filterOnly_eff <<
" +- "
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)
672 edm::LogPrint(
"GenXSecAnalyzer") <<
"Filter efficiency (event-level)= "
673 <<
"(" << filterOnly_event_pass <<
")"
675 <<
"(" << filterOnly_event_total <<
")"
676 <<
" = " << std::scientific << std::setprecision(3) << filterOnly_event_eff
677 <<
" +- " << filterOnly_event_err <<
" [TO BE USED IN MCM]";
682 final_fract_neg_w_unc =
684 ? final_fract_neg_w * final_fract_neg_w / filterOnly_event_pass *
691 edm::LogPrint(
"GenXSecAnalyzer") <<
"\nAfter filter: final cross section = " << std::scientific
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;
699 double lumi_1M_evts =
700 xsec_.
value() > 0 ? 1e6 * (1 - 2 * final_fract_neg_w) * (1 - 2 * final_fract_neg_w) /
xsec_.
value() / 1
e3 : 0;
701 double lumi_1M_evts_unc =
702 xsec_.
value() > 0 ? (1 - 2 * final_fract_neg_w) * lumi_1M_evts *
703 sqrt(1
e-6 + 16 *
pow(final_fract_neg_w_unc, 2) /
pow(1 - 2 * final_fract_neg_w, 2) +
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;