15 #include "boost/algorithm/string.hpp" 21 #include <unordered_map> 28 Counter() :
num(0), sumw(0), sumw2(0), sumPDF(), sumScale(), sumRwgt(), sumNamed(), sumPS() {}
34 std::vector<long double> sumPDF, sumScale, sumRwgt, sumNamed, sumPS;
43 sumNamed.clear(), sumPS.clear();
47 void incGenOnly(
double w) {
53 void incPSOnly(
double w0,
const std::vector<double>& wPS) {
56 sumPS.resize(wPS.size(), 0);
57 for (
unsigned int i = 0,
n = wPS.size();
i <
n; ++
i)
58 sumPS[
i] += (w0 * wPS[
i]);
62 void incLHE(
double w0,
63 const std::vector<double>& wScale,
64 const std::vector<double>& wPDF,
65 const std::vector<double>& wRwgt,
66 const std::vector<double>& wNamed,
67 const std::vector<double>& wPS) {
71 if (!wScale.empty()) {
73 sumScale.resize(wScale.size(), 0);
74 for (
unsigned int i = 0,
n = wScale.size();
i <
n; ++
i)
75 sumScale[
i] += (w0 * wScale[
i]);
79 sumPDF.resize(wPDF.size(), 0);
80 for (
unsigned int i = 0,
n = wPDF.size();
i <
n; ++
i)
81 sumPDF[
i] += (w0 * wPDF[
i]);
85 sumRwgt.resize(wRwgt.size(), 0);
86 for (
unsigned int i = 0,
n = wRwgt.size();
i <
n; ++
i)
87 sumRwgt[
i] += (w0 * wRwgt[
i]);
89 if (!wNamed.empty()) {
91 sumNamed.resize(wNamed.size(), 0);
92 for (
unsigned int i = 0,
n = wNamed.size();
i <
n; ++
i)
93 sumNamed[
i] += (w0 * wNamed[
i]);
101 sumw2 +=
other.sumw2;
102 if (sumScale.empty() && !
other.sumScale.empty())
103 sumScale.resize(
other.sumScale.size(), 0);
104 if (sumPDF.empty() && !
other.sumPDF.empty())
105 sumPDF.resize(
other.sumPDF.size(), 0);
106 if (sumRwgt.empty() && !
other.sumRwgt.empty())
107 sumRwgt.resize(
other.sumRwgt.size(), 0);
108 if (sumNamed.empty() && !
other.sumNamed.empty())
109 sumNamed.resize(
other.sumNamed.size(), 0);
110 if (sumPS.empty() && !
other.sumPS.empty())
111 sumPS.resize(
other.sumPS.size(), 0);
112 if (!
other.sumScale.empty())
113 for (
unsigned int i = 0,
n = sumScale.size();
i <
n; ++
i)
114 sumScale[
i] +=
other.sumScale[
i];
116 for (
unsigned int i = 0,
n = sumPDF.size();
i <
n; ++
i)
119 for (
unsigned int i = 0,
n = sumRwgt.size();
i <
n; ++
i)
120 sumRwgt[
i] +=
other.sumRwgt[
i];
122 for (
unsigned int i = 0,
n = sumNamed.size();
i <
n; ++
i)
123 sumNamed[
i] +=
other.sumNamed[
i];
125 for (
unsigned int i = 0,
n = sumPS.size();
i <
n; ++
i)
131 std::map<std::string, Counter> countermap;
135 for (
const auto&
y :
other.countermap)
136 countermap[
y.first].merge(
y.second);
140 for (
auto x : countermap)
146 active_el = &(countermap[
label]);
147 active_label =
label;
149 void checkLabelSet() {
151 throw cms::Exception(
"LogicError",
"Called CounterMap::get() before setting the active label\n");
164 struct DynamicWeightChoice {
167 std::vector<std::string> scaleWeightIDs;
170 std::vector<std::string> pdfWeightIDs;
173 std::vector<std::string> rwgtIDs;
177 constexpr std::array<unsigned int, 4> defPSWeightIDs = {{6, 7, 8, 9}};
178 constexpr std::array<unsigned int, 4> defPSWeightIDs_alt = {{27, 5, 26, 4}};
180 struct DynamicWeightChoiceGenInfo {
183 std::vector<unsigned int> scaleWeightIDs;
186 std::vector<unsigned int> pdfWeightIDs;
189 bool matchPS_alt =
false;
190 std::vector<unsigned int> psWeightIDs;
191 unsigned int psBaselineID = 1;
194 void setMissingWeight(
int idx) { psWeightIDs[
idx] = (matchPS_alt) ? defPSWeightIDs_alt[
idx] : defPSWeightIDs[
idx]; }
196 bool empty()
const {
return scaleWeightIDs.empty() && pdfWeightIDs.empty() && psWeightIDs.empty(); }
199 struct LumiCacheInfoHolder {
200 CounterMap countermap;
201 void clear() { countermap.clear(); }
206 if (
match != std::string::npos) {
211 return std::stof(
str);
215 struct ScaleVarWeight {
217 std::pair<float, float>
scales;
224 struct PDFSetWeights {
225 std::vector<std::string> wids;
226 std::pair<unsigned int, unsigned int> lhaIDs;
227 PDFSetWeights(
const std::string& wid,
unsigned int lhaID) : wids(1, wid), lhaIDs(lhaID, lhaID) {}
231 lhaIDs.second = lhaID;
233 bool maybe_add(
const std::string& wid,
unsigned int lhaID) {
234 if (lhaID == lhaIDs.second + 1) {
246 edm::RunCache<DynamicWeightChoice>,
247 edm::LuminosityBlockCache<DynamicWeightChoiceGenInfo>,
248 edm::RunSummaryCache<CounterMap>,
249 edm::EndRunProducer> {
259 mayConsume<GenLumiInfoHeader, edm::InLumi>(
params.getParameter<
edm::InputTag>(
"genLumiInfoHeader"))),
265 debug_(
params.getUntrackedParameter<
bool>(
"debug",
false)),
269 produces<nanoaod::FlatTable>();
270 produces<std::string>(
"genModel");
271 produces<nanoaod::FlatTable>(
"LHEScale");
272 produces<nanoaod::FlatTable>(
"LHEPdf");
273 produces<nanoaod::FlatTable>(
"LHEReweighting");
274 produces<nanoaod::FlatTable>(
"LHENamed");
275 produces<nanoaod::FlatTable>(
"PS");
276 produces<nanoaod::MergeableCounterTable, edm::Transition::EndRun>();
278 throw cms::Exception(
"Configuration",
"Size mismatch between namedWeightIDs & namedWeightLabels");
282 uint32_t
lhaid = pdfps.getParameter<uint32_t>(
"lhaid");
301 auto out = std::make_unique<nanoaod::FlatTable>(1,
"genWeight",
true);
302 out->setDoc(
"generator weight");
303 out->addColumnValue<
float>(
"",
weight,
"generator weight");
306 std::string model_label = streamCache(
id)->countermap.getLabel();
307 auto outM = std::make_unique<std::string>((!model_label.empty()) ?
std::string(
"GenModel_") + model_label :
"");
309 bool getLHEweightsFromGenInfo = !model_label.empty();
312 std::unique_ptr<nanoaod::FlatTable> lheScaleTab, lhePdfTab, lheRwgtTab, lheNamedTab;
313 std::unique_ptr<nanoaod::FlatTable> genPSTab;
316 for (
const auto& lheTag :
lheTag_) {
323 const auto genWeightChoice = luminosityBlockCache(
iEvent.getLuminosityBlock().index());
327 <<
"Found both a LHEEventProduct and a GenLumiInfoHeader: will only save weights from LHEEventProduct.\n";
329 const DynamicWeightChoice* weightChoice = runCache(
iEvent.getRun().index());
342 }
else if (getLHEweightsFromGenInfo) {
344 counter, genWeightChoice,
weight, *genInfo, lheScaleTab, lhePdfTab, lheNamedTab, genPSTab);
345 lheRwgtTab = std::make_unique<nanoaod::FlatTable>(1,
"LHEReweightingWeights",
true);
352 lheScaleTab = std::make_unique<nanoaod::FlatTable>(1,
"LHEScaleWeights",
true);
353 lhePdfTab = std::make_unique<nanoaod::FlatTable>(1,
"LHEPdfWeights",
true);
354 lheRwgtTab = std::make_unique<nanoaod::FlatTable>(1,
"LHEReweightingWeights",
true);
355 lheNamedTab = std::make_unique<nanoaod::FlatTable>(1,
"LHENamedWeights",
true);
357 edm::LogWarning(
"LHETablesProducer") <<
"No LHEEventProduct, so there will be no LHE Tables\n";
369 const DynamicWeightChoice* weightChoice,
370 const DynamicWeightChoiceGenInfo* genWeightChoice,
374 std::unique_ptr<nanoaod::FlatTable>& outScale,
375 std::unique_ptr<nanoaod::FlatTable>& outPdf,
376 std::unique_ptr<nanoaod::FlatTable>& outRwgt,
377 std::unique_ptr<nanoaod::FlatTable>& outNamed,
378 std::unique_ptr<nanoaod::FlatTable>& outPS)
const {
379 bool lheDebug =
debug_.exchange(
382 const std::vector<std::string>& scaleWeightIDs = weightChoice->scaleWeightIDs;
383 const std::vector<std::string>& pdfWeightIDs = weightChoice->pdfWeightIDs;
384 const std::vector<std::string>& rwgtWeightIDs = weightChoice->rwgtIDs;
388 std::vector<double> wScale(scaleWeightIDs.size(), 1), wPDF(pdfWeightIDs.size(), 1), wRwgt(rwgtWeightIDs.size(), 1),
392 printf(
"Weight %+9.5f rel %+9.5f for id %s\n",
weight.wgt,
weight.wgt / w0,
weight.id.c_str());
394 auto mScale =
std::find(scaleWeightIDs.begin(), scaleWeightIDs.end(),
weight.id);
395 if (mScale != scaleWeightIDs.end())
396 wScale[mScale - scaleWeightIDs.begin()] =
weight.wgt / w0;
398 auto mPDF =
std::find(pdfWeightIDs.begin(), pdfWeightIDs.end(),
weight.id);
399 if (mPDF != pdfWeightIDs.end())
400 wPDF[mPDF - pdfWeightIDs.begin()] =
weight.wgt / w0;
402 auto mRwgt =
std::find(rwgtWeightIDs.begin(), rwgtWeightIDs.end(),
weight.id);
403 if (mRwgt != rwgtWeightIDs.end())
404 wRwgt[mRwgt - rwgtWeightIDs.begin()] =
weight.wgt / w0;
411 std::vector<double> wPS;
415 outPS = std::make_unique<nanoaod::FlatTable>(wPS.size(),
"PSWeight",
false);
418 outScale = std::make_unique<nanoaod::FlatTable>(wScale.size(),
"LHEScaleWeight",
false);
419 outScale->addColumn<
float>(
"", wScale, weightChoice->scaleWeightsDoc,
lheWeightPrecision_);
421 outPdf = std::make_unique<nanoaod::FlatTable>(wPDF.size(),
"LHEPdfWeight",
false);
424 outRwgt = std::make_unique<nanoaod::FlatTable>(wRwgt.size(),
"LHEReweightingWeight",
false);
427 outNamed = std::make_unique<nanoaod::FlatTable>(1,
"LHEWeight",
true);
428 outNamed->addColumnValue<
float>(
"originalXWGTUP", lheProd.
originalXWGTUP(),
"Nominal event weight in the LHE file");
429 for (
unsigned int i = 0,
n = wNamed.size();
i <
n; ++
i) {
436 counter->incLHE(genWeight, wScale, wPDF, wRwgt, wNamed, wPS);
440 const DynamicWeightChoiceGenInfo* weightChoice,
443 std::unique_ptr<nanoaod::FlatTable>& outScale,
444 std::unique_ptr<nanoaod::FlatTable>& outPdf,
445 std::unique_ptr<nanoaod::FlatTable>& outNamed,
446 std::unique_ptr<nanoaod::FlatTable>& outPS)
const {
447 const std::vector<unsigned int>& scaleWeightIDs = weightChoice->scaleWeightIDs;
448 const std::vector<unsigned int>& pdfWeightIDs = weightChoice->pdfWeightIDs;
452 double originalXWGTUP = (
weights.size() > 1) ?
weights.at(1) : 1.;
454 std::vector<double> wScale, wPDF, wPS;
455 for (
auto id : scaleWeightIDs)
456 wScale.push_back(
weights.at(
id) / w0);
457 for (
auto id : pdfWeightIDs) {
458 wPDF.push_back(
weights.at(
id) / w0);
464 outScale = std::make_unique<nanoaod::FlatTable>(wScale.size(),
"LHEScaleWeight",
false);
465 outScale->addColumn<
float>(
"", wScale, weightChoice->scaleWeightsDoc,
lheWeightPrecision_);
467 outPdf = std::make_unique<nanoaod::FlatTable>(wPDF.size(),
"LHEPdfWeight",
false);
470 outPS = std::make_unique<nanoaod::FlatTable>(wPS.size(),
"PSWeight",
false);
473 outNamed = std::make_unique<nanoaod::FlatTable>(1,
"LHEWeight",
true);
474 outNamed->addColumnValue<
float>(
"originalXWGTUP", originalXWGTUP,
"Nominal event weight in the LHE file");
479 counter->incLHE(genWeight, wScale, wPDF, std::vector<double>(), std::vector<double>(), wPS);
483 const DynamicWeightChoiceGenInfo* genWeightChoice,
486 std::unique_ptr<nanoaod::FlatTable>& outPS)
const {
487 std::vector<double> wPS;
490 outPS = std::make_unique<nanoaod::FlatTable>(wPS.size(),
"PSWeight",
false);
493 counter->incGenOnly(genWeight);
494 counter->incPSOnly(genWeight, wPS);
498 const DynamicWeightChoiceGenInfo* genWeightChoice,
499 std::vector<double>& wPS,
504 bool isRegularPSSet =
keepAllPSWeights_ && (genWeights.size() == 14 || genWeights.size() == 46);
505 if (!genWeightChoice->psWeightIDs.empty() && !isRegularPSSet) {
506 psWeightDocStr = genWeightChoice->psWeightsDoc;
507 double psNom = genWeights.at(genWeightChoice->psBaselineID);
508 for (
auto wgtidx : genWeightChoice->psWeightIDs) {
509 wPS.push_back(genWeights.at(wgtidx) / psNom);
513 keepAllPSWeights_ ? (genWeights.size() - 2) : ((genWeights.size() == 14 || genWeights.size() == 46) ? 4 : 1);
515 if (vectorSize > 1) {
516 double nominal = genWeights.at(1);
518 for (
int i = 0;
i < vectorSize;
i++) {
519 wPS.push_back(genWeights.at(
i + 2) / nominal);
521 psWeightDocStr =
"All PS weights (w_var / w_nominal)";
525 <<
"GenLumiInfoHeader not found: Central PartonShower weights will fill with the 6-10th entries \n" 526 <<
" This may incorrect for some mcs (madgraph 2.6.1 with its `isr:murfact=0.5` have a differnt " 528 for (std::size_t
i = 6;
i < 10;
i++) {
529 wPS.push_back(genWeights.at(
i) / nominal);
532 "PS weights (w_var / w_nominal); [0] is ISR=2 FSR=1; [1] is ISR=1 FSR=2" 533 "[2] is ISR=0.5 FSR=1; [3] is ISR=1 FSR=0.5;";
537 psWeightDocStr =
"dummy PS weight (1.0) ";
548 auto weightChoice = std::make_shared<DynamicWeightChoice>();
559 std::vector<ScaleVarWeight> scaleVariationIDs;
560 std::vector<PDFSetWeights> pdfSetWeightIDs;
561 std::vector<std::string> lheReweighingIDs;
562 bool isFirstGroup =
true;
564 std::regex weightgroupmg26x(
"<weightgroup\\s+(?:name|type)=\"(.*)\"\\s+combine=\"(.*)\"\\s*>");
565 std::regex weightgroup(
"<weightgroup\\s+combine=\"(.*)\"\\s+(?:name|type)=\"(.*)\"\\s*>");
566 std::regex weightgroupRwgt(
"<weightgroup\\s+(?:name|type)=\"(.*)\"\\s*>");
567 std::regex endweightgroup(
"</weightgroup>");
568 std::regex scalewmg26x(
569 "<weight\\s+(?:.*\\s+)?id=\"(\\d+)\"\\s*(?:lhapdf=\\d+|dyn=\\s*-?\\d+)?\\s*((?:[mM][uU][rR]|renscfact)=\"(" 570 "\\S+)\"\\s+(?:[mM][uU][Ff]|facscfact)=\"(\\S+)\")(\\s+.*)?</weight>");
571 std::regex scalewmg26xNew(
572 "<weight\\s*((?:[mM][uU][fF]|facscfact)=\"(\\S+)\"\\s+(?:[mM][uU][Rr]|renscfact)=\"(\\S+)\").+id=\"(\\d+)\"(." 577 "<weight\\s+(?:.*\\s+)?id=\"(\\d+|\\d+-NNLOPS)\">\\s*(?:lhapdf=\\d+|dyn=\\s*-?\\d+)?\\s*((?:mu[rR]|renscfact)" 578 "=(\\S+)\\s+(?:mu[Ff]|facscfact)=(\\S+)(\\s+.*)?)</weight>");
580 "<weight\\s+id=\"(\\d+)\">\\s*(?:PDF set|lhapdf|PDF|pdfset)\\s*=\\s*(\\d+)\\s*(?:\\s.*)?</weight>");
581 std::regex pdfwOld(
"<weight\\s+(?:.*\\s+)?id=\"(\\d+)\">\\s*Member \\s*(\\d+)\\s*(?:.*)</weight>");
582 std::regex pdfwmg26x(
583 "<weight\\s+id=\"(\\d+)\"\\s*MUR=\"(?:\\S+)\"\\s*MUF=\"(?:\\S+)\"\\s*(?:PDF " 584 "set|lhapdf|PDF|pdfset)\\s*=\\s*\"(\\d+)\"\\s*>\\s*(?:PDF=(\\d+)\\s*MemberID=(\\d+))?\\s*(?:\\s.*)?</" 589 std::regex pdfwmg26xNew(
590 "<weight\\s+MUF=\"(?:\\S+)\"\\s*MUR=\"(?:\\S+)\"\\s*PDF=\"(?:\\S+)\"\\s*id=\"(\\S+)\"\\s*>" 591 "\\s*(?:PDF=(\\d+)\\s*MemberID=(\\d+))?\\s*(?:\\s.*)?</" 594 std::regex rwgt(
"<weight\\s+id=\"(.+)\">(.+)?(</weight>)?");
597 if (iter->tag() !=
"initrwgt") {
599 std::cout <<
"Skipping LHE header with tag" << iter->tag() << std::endl;
603 std::cout <<
"Found LHE header with tag" << iter->tag() << std::endl;
604 std::vector<std::string>
lines = iter->lines();
605 bool missed_weightgroup =
607 bool ismg26x =
false;
608 bool ismg26xNew =
false;
611 boost::replace_all(
lines[iLine],
"<",
"<");
612 boost::replace_all(
lines[iLine],
">",
">");
613 if (std::regex_search(
lines[iLine], groups, weightgroupmg26x)) {
615 }
else if (std::regex_search(
lines[iLine], groups, scalewmg26xNew) ||
616 std::regex_search(
lines[iLine], groups, pdfwmg26xNew)) {
623 if (std::regex_search(
lines[iLine], groups, ismg26x ? weightgroupmg26x : weightgroup)) {
626 groupname = groups.str(1);
628 std::cout <<
">>> Looks like the beginning of a weight group for '" << groupname <<
"'" << std::endl;
629 if (groupname.find(
"scale_variation") == 0 || groupname ==
"Central scale variation" || isFirstGroup) {
630 if (lheDebug && groupname.find(
"scale_variation") != 0 && groupname !=
"Central scale variation")
631 std::cout <<
">>> First weight is not scale variation, but assuming is the Central Weight" << std::endl;
633 std::cout <<
">>> Looks like scale variation for theory uncertainties" << std::endl;
634 isFirstGroup =
false;
635 for (++iLine; iLine <
nLines; ++iLine) {
639 if (std::regex_search(
640 lines[iLine], groups, ismg26x ? scalewmg26x : (ismg26xNew ? scalewmg26xNew : scalew))) {
642 std::cout <<
" >>> Scale weight " << groups[1].str() <<
" for " << groups[3].str() <<
" , " 643 << groups[4].str() <<
" , " << groups[5].str() << std::endl;
645 scaleVariationIDs.emplace_back(groups.str(4), groups.str(1), groups.str(3), groups.str(2));
647 scaleVariationIDs.emplace_back(groups.str(1), groups.str(2), groups.str(3), groups.str(4));
649 }
else if (std::regex_search(
lines[iLine], endweightgroup)) {
651 std::cout <<
">>> Looks like the end of a weight group" << std::endl;
652 if (!missed_weightgroup) {
655 missed_weightgroup =
false;
656 }
else if (std::regex_search(
lines[iLine], ismg26x ? weightgroupmg26x : weightgroup)) {
658 std::cout <<
">>> Looks like the beginning of a new weight group, I will assume I missed the end " 661 if (ismg26x || ismg26xNew)
662 missed_weightgroup =
true;
667 }
else if (groupname ==
"PDF_variation" || groupname.find(
"PDF_variation ") == 0) {
669 std::cout <<
">>> Looks like a new-style block of PDF weights for one or more pdfs" << std::endl;
670 for (++iLine; iLine <
nLines; ++iLine) {
673 if (std::regex_search(
lines[iLine], groups, pdfw)) {
674 unsigned int lhaID = std::stoi(groups.str(2));
676 std::cout <<
" >>> PDF weight " << groups.str(1) <<
" for " << groups.str(2) <<
" = " << lhaID
678 if (pdfSetWeightIDs.empty() || !pdfSetWeightIDs.back().maybe_add(groups.str(1), lhaID)) {
679 pdfSetWeightIDs.emplace_back(groups.str(1), lhaID);
681 }
else if (std::regex_search(
lines[iLine], endweightgroup)) {
683 std::cout <<
">>> Looks like the end of a weight group" << std::endl;
684 if (!missed_weightgroup) {
687 missed_weightgroup =
false;
688 }
else if (std::regex_search(
lines[iLine], ismg26x ? weightgroupmg26x : weightgroup)) {
690 std::cout <<
">>> Looks like the beginning of a new weight group, I will assume I missed the end " 693 if (ismg26x || ismg26xNew)
694 missed_weightgroup =
true;
699 }
else if (groupname ==
"PDF_variation1" || groupname ==
"PDF_variation2") {
701 std::cout <<
">>> Looks like a new-style block of PDF weights for multiple pdfs" << std::endl;
702 unsigned int lastid = 0;
703 for (++iLine; iLine <
nLines; ++iLine) {
706 if (std::regex_search(
lines[iLine], groups, pdfw)) {
707 unsigned int id = std::stoi(groups.str(1));
708 unsigned int lhaID = std::stoi(groups.str(2));
710 std::cout <<
" >>> PDF weight " << groups.str(1) <<
" for " << groups.str(2) <<
" = " << lhaID
712 if (
id != (lastid + 1) || pdfSetWeightIDs.empty()) {
713 pdfSetWeightIDs.emplace_back(groups.str(1), lhaID);
715 pdfSetWeightIDs.back().add(groups.str(1), lhaID);
718 }
else if (std::regex_search(
lines[iLine], endweightgroup)) {
720 std::cout <<
">>> Looks like the end of a weight group" << std::endl;
721 if (!missed_weightgroup) {
724 missed_weightgroup =
false;
725 }
else if (std::regex_search(
lines[iLine], ismg26x ? weightgroupmg26x : weightgroup)) {
727 std::cout <<
">>> Looks like the beginning of a new weight group, I will assume I missed the end " 730 if (ismg26x || ismg26xNew)
731 missed_weightgroup =
true;
738 std::cout <<
">>> Looks like an old-style PDF weight for an individual pdf" << std::endl;
739 unsigned int firstLhaID =
lhaNameToID_.find(groupname)->second;
741 for (++iLine; iLine <
nLines; ++iLine) {
744 if (std::regex_search(
745 lines[iLine], groups, ismg26x ? pdfwmg26x : (ismg26xNew ? pdfwmg26xNew : pdfwOld))) {
746 unsigned int member = 0;
747 if (!ismg26x && !ismg26xNew) {
748 member = std::stoi(groups.str(2));
749 }
else if (ismg26xNew) {
750 if (!groups.str(3).empty()) {
751 member = std::stoi(groups.str(3));
754 if (!groups.str(4).empty()) {
755 member = std::stoi(groups.str(4));
758 unsigned int lhaID = member + firstLhaID;
760 std::cout <<
" >>> PDF weight " << groups.str(1) <<
" for " << member <<
" = " << lhaID
764 pdfSetWeightIDs.emplace_back(groups.str(1), lhaID);
767 pdfSetWeightIDs.back().add(groups.str(1), lhaID);
769 }
else if (std::regex_search(
lines[iLine], endweightgroup)) {
771 std::cout <<
">>> Looks like the end of a weight group" << std::endl;
772 if (!missed_weightgroup) {
775 missed_weightgroup =
false;
776 }
else if (std::regex_search(
lines[iLine], ismg26x ? weightgroupmg26x : weightgroup)) {
778 std::cout <<
">>> Looks like the beginning of a new weight group, I will assume I missed the end " 781 if (ismg26x || ismg26xNew)
782 missed_weightgroup =
true;
787 }
else if (groupname ==
"mass_variation" || groupname ==
"sthw2_variation" ||
788 groupname ==
"width_variation") {
790 std::cout <<
">>> Looks like an EW parameter weight" << std::endl;
791 for (++iLine; iLine <
nLines; ++iLine) {
794 if (std::regex_search(
lines[iLine], groups, rwgt)) {
797 std::cout <<
" >>> LHE reweighting weight: " << rwgtID << std::endl;
798 if (
std::find(lheReweighingIDs.begin(), lheReweighingIDs.end(), rwgtID) == lheReweighingIDs.end()) {
800 lheReweighingIDs.emplace_back(rwgtID);
802 }
else if (std::regex_search(
lines[iLine], endweightgroup)) {
804 std::cout <<
">>> Looks like the end of a weight group" << std::endl;
808 for (++iLine; iLine <
nLines; ++iLine) {
811 if (std::regex_search(
lines[iLine], groups, endweightgroup)) {
813 std::cout <<
">>> Looks like the end of a weight group" << std::endl;
814 if (!missed_weightgroup) {
817 missed_weightgroup =
false;
818 }
else if (std::regex_search(
lines[iLine], ismg26x ? weightgroupmg26x : weightgroup)) {
820 std::cout <<
">>> Looks like the beginning of a new weight group, I will assume I missed the end " 823 if (ismg26x || ismg26xNew)
824 missed_weightgroup =
true;
830 }
else if (std::regex_search(
lines[iLine], groups, weightgroupRwgt)) {
832 if (groupname.find(
"mg_reweighting") != std::string::npos) {
834 std::cout <<
">>> Looks like a LHE weights for reweighting" << std::endl;
835 for (++iLine; iLine <
nLines; ++iLine) {
838 if (std::regex_search(
lines[iLine], groups, rwgt)) {
841 std::cout <<
" >>> LHE reweighting weight: " << rwgtID << std::endl;
842 if (
std::find(lheReweighingIDs.begin(), lheReweighingIDs.end(), rwgtID) == lheReweighingIDs.end()) {
844 lheReweighingIDs.emplace_back(rwgtID);
846 }
else if (std::regex_search(
lines[iLine], endweightgroup)) {
848 std::cout <<
">>> Looks like the end of a weight group" << std::endl;
849 if (!missed_weightgroup) {
852 missed_weightgroup =
false;
853 }
else if (std::regex_search(
lines[iLine], ismg26x ? weightgroupmg26x : weightgroup)) {
855 std::cout <<
">>> Looks like the beginning of a new weight group, I will assume I missed the end " 859 missed_weightgroup =
true;
870 std::sort(scaleVariationIDs.begin(), scaleVariationIDs.end());
872 std::cout <<
"Found " << scaleVariationIDs.size() <<
" scale variations: " << std::endl;
873 std::stringstream scaleDoc;
874 scaleDoc <<
"LHE scale variation weights (w_var / w_nominal); ";
875 for (
unsigned int isw = 0, nsw = scaleVariationIDs.size(); isw < nsw; ++isw) {
876 const auto& sw = scaleVariationIDs[isw];
879 scaleDoc <<
"[" << isw <<
"] is " << sw.label;
880 weightChoice->scaleWeightIDs.push_back(sw.wid);
882 printf(
" id %s: scales ren = % .2f fact = % .2f text = %s\n",
888 if (!scaleVariationIDs.empty())
889 weightChoice->scaleWeightsDoc = scaleDoc.str();
893 std::cout <<
"Found " << pdfSetWeightIDs.size() <<
" PDF set errors: " << std::endl;
894 for (
const auto& pw : pdfSetWeightIDs)
895 printf(
"lhaIDs %6d - %6d (%3lu weights: %s, ... )\n",
899 pw.wids.front().c_str());
904 std::cout <<
"Found " << lheReweighingIDs.size() <<
" reweighting weights" << std::endl;
906 std::copy(lheReweighingIDs.begin(), lheReweighingIDs.end(), std::back_inserter(weightChoice->rwgtIDs));
908 std::stringstream pdfDoc;
909 pdfDoc <<
"LHE pdf variation weights (w_var / w_nominal) for LHA IDs ";
911 for (
const auto& pw : pdfSetWeightIDs) {
913 if (pw.lhaIDs.first !=
lhaid && pw.lhaIDs.first != (
lhaid + 1))
915 if (pw.wids.size() == 1)
917 pdfDoc << pw.lhaIDs.first <<
" - " << pw.lhaIDs.second;
918 weightChoice->pdfWeightIDs = pw.wids;
921 pdfDoc <<
", truncated to the first " <<
maxPdfWeights_ <<
" replicas";
923 weightChoice->pdfWeightsDoc = pdfDoc.str();
937 return std::make_unique<LumiCacheInfoHolder>();
941 streamCache(
id)->clear();
946 auto dynamicWeightChoiceGenInfo = std::make_shared<DynamicWeightChoiceGenInfo>();
950 if (!genLumiInfoHead.isValid())
952 <<
"No GenLumiInfoHeader product found, will not fill generator model string.\n";
954 if (genLumiInfoHead.isValid()) {
955 auto weightChoice = dynamicWeightChoiceGenInfo.get();
957 std::vector<ScaleVarWeight> scaleVariationIDs;
958 std::vector<PDFSetWeights> pdfSetWeightIDs;
959 weightChoice->psWeightIDs.clear();
961 std::regex scalew(
"LHE,\\s+id\\s+=\\s+(\\d+),\\s+(.+)\\,\\s+mur=(\\S+)\\smuf=(\\S+)");
962 std::regex pdfw(
"LHE,\\s+id\\s+=\\s+(\\d+),\\s+(.+),\\s+Member\\s+(\\d+)\\s+of\\ssets\\s+(\\w+\\b)");
963 std::regex mainPSw(
"sr(Def|:murfac=)(Hi|Lo|_dn|_up|0.5|2.0)");
965 auto weightNames = genLumiInfoHead->weightNames();
966 std::unordered_map<std::string, uint32_t> knownPDFSetsFromGenInfo_;
967 unsigned int weightIter = 0;
968 for (
const auto&
line : weightNames) {
969 if (std::regex_search(
line, groups, scalew)) {
970 auto id = groups.str(1);
971 auto group = groups.str(2);
972 auto mur = groups.str(3);
973 auto muf = groups.str(4);
974 if (
group.find(
"Central scale variation") != std::string::npos)
975 scaleVariationIDs.emplace_back(groups.str(1), groups.str(2), groups.str(3), groups.str(4));
976 }
else if (std::regex_search(
line, groups, pdfw)) {
977 auto id = groups.str(1);
978 auto group = groups.str(2);
979 auto memberid = groups.str(3);
980 auto pdfset = groups.str(4);
981 if (
group.find(pdfset) != std::string::npos) {
982 if (knownPDFSetsFromGenInfo_.find(pdfset) == knownPDFSetsFromGenInfo_.end()) {
983 knownPDFSetsFromGenInfo_[pdfset] = std::atoi(
id.c_str());
984 pdfSetWeightIDs.emplace_back(
id, std::atoi(
id.c_str()));
986 pdfSetWeightIDs.back().add(
id, std::atoi(
id.c_str()));
988 }
else if (
line ==
"Baseline") {
989 weightChoice->psBaselineID = weightIter;
990 }
else if (
line.find(
"isr") != std::string::npos ||
line.find(
"fsr") != std::string::npos) {
991 weightChoice->matchPS_alt =
line.find(
"sr:") != std::string::npos;
993 weightChoice->psWeightIDs.push_back(weightIter);
994 }
else if (std::regex_search(
line, groups, mainPSw)) {
995 if (weightChoice->psWeightIDs.empty())
996 weightChoice->psWeightIDs = std::vector<unsigned int>(4, -1);
997 int psIdx = (
line.find(
"fsr") != std::string::npos) ? 1 : 0;
998 psIdx += (groups.str(2) ==
"Hi" || groups.str(2) ==
"_up" || groups.str(2) ==
"2.0") ? 0 : 2;
999 weightChoice->psWeightIDs[psIdx] = weightIter;
1005 weightChoice->psWeightsDoc =
"All PS weights (w_var / w_nominal)";
1006 }
else if (weightChoice->psWeightIDs.size() == 4) {
1007 weightChoice->psWeightsDoc =
1008 "PS weights (w_var / w_nominal); [0] is ISR=2 FSR=1; [1] is ISR=1 FSR=2" 1009 "[2] is ISR=0.5 FSR=1; [3] is ISR=1 FSR=0.5;";
1010 for (
int i = 0;
i < 4;
i++) {
1011 if (static_cast<int>(weightChoice->psWeightIDs[
i]) == -1)
1012 weightChoice->setMissingWeight(
i);
1015 weightChoice->psWeightsDoc =
"dummy PS weight (1.0) ";
1018 weightChoice->scaleWeightIDs.clear();
1019 weightChoice->pdfWeightIDs.clear();
1021 std::sort(scaleVariationIDs.begin(), scaleVariationIDs.end());
1022 std::stringstream scaleDoc;
1023 scaleDoc <<
"LHE scale variation weights (w_var / w_nominal); ";
1024 for (
unsigned int isw = 0, nsw = scaleVariationIDs.size(); isw < nsw; ++isw) {
1025 const auto& sw = scaleVariationIDs[isw];
1028 scaleDoc <<
"[" << isw <<
"] is " << sw.label;
1029 weightChoice->scaleWeightIDs.push_back(std::atoi(sw.wid.c_str()));
1031 if (!scaleVariationIDs.empty())
1032 weightChoice->scaleWeightsDoc = scaleDoc.str();
1033 std::stringstream pdfDoc;
1034 pdfDoc <<
"LHE pdf variation weights (w_var / w_nominal) for LHA names ";
1036 for (
const auto& pw : pdfSetWeightIDs) {
1037 if (pw.wids.size() == 1)
1040 auto pdfname = wantedpdf.first;
1041 if (knownPDFSetsFromGenInfo_.find(pdfname) == knownPDFSetsFromGenInfo_.end())
1043 uint32_t
lhaid = knownPDFSetsFromGenInfo_.at(pdfname);
1044 if (pw.lhaIDs.first !=
lhaid)
1047 for (
const auto&
x : pw.wids)
1048 weightChoice->pdfWeightIDs.push_back(std::atoi(
x.c_str()));
1051 pdfDoc <<
", truncated to the first " <<
maxPdfWeights_ <<
" replicas";
1053 weightChoice->pdfWeightsDoc = pdfDoc.str();
1061 return dynamicWeightChoiceGenInfo;
1069 auto counterMap = &(streamCache(
id)->countermap);
1074 if (genLumiInfoHead.
isValid()) {
1076 boost::replace_all(
label,
"-",
"_");
1077 boost::replace_all(
label,
"/",
"_");
1079 counterMap->setLabel(
label);
1083 return std::make_shared<CounterMap>();
1089 CounterMap* runCounterMap)
const override {
1090 runCounterMap->merge(streamCache(
id)->countermap);
1096 auto out = std::make_unique<nanoaod::MergeableCounterTable>();
1098 for (
const auto&
x : runCounterMap->countermap) {
1099 auto runCounter = &(
x.second);
1103 out->addInt(
"genEventCount" +
label,
"event count" + doclabel, runCounter->num);
1104 out->addFloat(
"genEventSumw" +
label,
"sum of gen weights" + doclabel, runCounter->sumw);
1105 out->addFloat(
"genEventSumw2" +
label,
"sum of gen (weight^2)" + doclabel, runCounter->sumw2);
1107 double norm = runCounter->sumw ? 1.0 / runCounter->sumw : 1;
1108 auto sumScales = runCounter->sumScale;
1109 for (
auto&
val : sumScales)
1111 out->addVFloatWithNorm(
"LHEScaleSumw" +
label,
1112 "Sum of genEventWeight * LHEScaleWeight[i], divided by genEventSumw" + doclabel,
1115 auto sumPDFs = runCounter->sumPDF;
1116 for (
auto&
val : sumPDFs)
1118 out->addVFloatWithNorm(
"LHEPdfSumw" +
label,
1119 "Sum of genEventWeight * LHEPdfWeight[i], divided by genEventSumw" + doclabel,
1122 auto sumPS = runCounter->sumPS;
1123 for (
auto&
val : sumPS)
1125 out->addVFloatWithNorm(
"PSSumw" +
label,
1126 "Sum of genEventWeight * PSWeight[i], divided by genEventSumw" + doclabel,
1129 if (!runCounter->sumRwgt.empty()) {
1130 auto sumRwgts = runCounter->sumRwgt;
1131 for (
auto&
val : sumRwgts)
1133 out->addVFloatWithNorm(
"LHEReweightingSumw" +
label,
1134 "Sum of genEventWeight * LHEReweightingWeight[i], divided by genEventSumw" + doclabel,
1138 if (!runCounter->sumNamed.empty()) {
1140 out->addFloatWithNorm(
1142 "Sum of genEventWeight * LHEWeight_" +
namedWeightLabels_[
i] +
", divided by genEventSumw" + doclabel,
1143 runCounter->sumNamed[
i] * norm,
1156 ->setComment(
"tag for the GenEventInfoProduct, to get the main weight");
1158 ->setComment(
"tag for the GenLumiInfoProduct, to get the model string");
1159 desc.add<std::vector<edm::InputTag>>(
"lheInfo", std::vector<edm::InputTag>{{
"externalLHEProducer"}, {
"source"}})
1160 ->setComment(
"tag(s) for the LHE information (LHEEventProduct and LHERunInfoProduct)");
1164 prefpdf.
add<uint32_t>(
"lhaid");
1165 desc.addVPSet(
"preferredPDFs", prefpdf, std::vector<edm::ParameterSet>())
1167 "LHA PDF Ids of the preferred PDF sets, in order of preference (the first matching one will be used)");
1168 desc.add<std::vector<std::string>>(
"namedWeightIDs")->setComment(
"set of LHA weight IDs for named LHE weights");
1169 desc.add<std::vector<std::string>>(
"namedWeightLabels")
1170 ->setComment(
"output names for the namedWeightIDs (in the same order)");
1171 desc.add<int32_t>(
"lheWeightPrecision")->setComment(
"Number of bits in the mantissa for LHE weights");
1172 desc.add<uint32_t>(
"maxPdfWeights")->setComment(
"Maximum number of PDF weights to save (to crop NN replicas)");
1173 desc.add<
bool>(
"keepAllPSWeights")->setComment(
"Store all PS weights found");
1174 desc.addOptionalUntracked<
bool>(
"debug")->setComment(
"dump out all LHE information for one event");
1175 descriptions.
add(
"genWeightsTable",
desc);
1181 const std::vector<edm::EDGetTokenT<LHEEventProduct>>
lheTag_;
1182 const std::vector<edm::EDGetTokenT<LHERunInfoProduct>>
lheRunTag_;
const std::vector< edm::EDGetTokenT< LHERunInfoProduct > > lheRunTag_
std::shared_ptr< CounterMap > globalBeginRunSummary(edm::Run const &, edm::EventSetup const &) const override
double originalXWGTUP() const
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
bool operator<(IOVSyncValue const &iLHS, IOVSyncValue const &iRHS)
int merge(int argc, char *argv[])
const edm::EDGetTokenT< GenEventInfoProduct > genTag_
void setPSWeightInfo(const std::vector< double > &genWeights, const DynamicWeightChoiceGenInfo *genWeightChoice, std::vector< double > &wPS, std::string &psWeightDocStr) const
void fillOnlyPSWeightTable(Counter *counter, const DynamicWeightChoiceGenInfo *genWeightChoice, double genWeight, const GenEventInfoProduct &genProd, std::unique_ptr< nanoaod::FlatTable > &outPS) const
std::atomic< bool > hasIssuedWarning_
auto vector_transform(std::vector< InputType > const &input, Function predicate) -> std::vector< typename std::remove_cv< typename std::remove_reference< decltype(predicate(input.front()))>::type >::type >
std::unordered_map< std::string, uint32_t > lhaNameToID_
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
const std::vector< edm::InputTag > lheLabel_
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
void fillLHEWeightTables(Counter *counter, const DynamicWeightChoice *weightChoice, const DynamicWeightChoiceGenInfo *genWeightChoice, double genWeight, const LHEEventProduct &lheProd, const GenEventInfoProduct &genProd, std::unique_ptr< nanoaod::FlatTable > &outScale, std::unique_ptr< nanoaod::FlatTable > &outPdf, std::unique_ptr< nanoaod::FlatTable > &outRwgt, std::unique_ptr< nanoaod::FlatTable > &outNamed, std::unique_ptr< nanoaod::FlatTable > &outPS) const
std::function< unsigned int(align::ID)> Counter
std::atomic< bool > debug_
std::unique_ptr< LumiCacheInfoHolder > beginStream(edm::StreamID) const override
void globalEndRunProduce(edm::Run &iRun, edm::EventSetup const &, CounterMap const *runCounterMap) const override
void produce(edm::StreamID id, edm::Event &iEvent, const edm::EventSetup &iSetup) const override
std::atomic< bool > debugRun_
bool getByLabel(std::string const &label, Handle< PROD > &result) const
#define DEFINE_FWK_MODULE(type)
std::atomic< bool > psWeightWarning_
ParameterDescriptionBase * add(U const &iLabel, T const &value)
void fillLHEPdfWeightTablesFromGenInfo(Counter *counter, const DynamicWeightChoiceGenInfo *weightChoice, double genWeight, const GenEventInfoProduct &genProd, std::unique_ptr< nanoaod::FlatTable > &outScale, std::unique_ptr< nanoaod::FlatTable > &outPdf, std::unique_ptr< nanoaod::FlatTable > &outNamed, std::unique_ptr< nanoaod::FlatTable > &outPS) const
void streamBeginLuminosityBlock(edm::StreamID id, edm::LuminosityBlock const &lumiBlock, edm::EventSetup const &) const override
void globalEndRun(edm::Run const &, edm::EventSetup const &) const override
void streamEndRunSummary(edm::StreamID id, edm::Run const &, edm::EventSetup const &, CounterMap *runCounterMap) const override
bool getByToken(EDGetToken token, Handle< PROD > &result) const
std::vector< std::string > namedWeightLabels_
~GenWeightsTableProducer() override
GenWeightsTableProducer(edm::ParameterSet const ¶ms)
std::shared_ptr< DynamicWeightChoice > globalBeginRun(edm::Run const &iRun, edm::EventSetup const &) const override
void put(std::unique_ptr< PROD > product)
Put a new product.
void add(std::string const &label, ParameterSetDescription const &psetDescription)
unsigned int maxPdfWeights_
void globalEndRunSummary(edm::Run const &, edm::EventSetup const &, CounterMap *runCounterMap) const override
const std::vector< edm::EDGetTokenT< LHEEventProduct > > lheTag_
std::vector< uint32_t > preferredPDFLHAIDs_
void add(std::map< std::string, TH1 *> &h, TH1 *hist)
void globalEndLuminosityBlock(edm::LuminosityBlock const &, edm::EventSetup const &) const override
std::vector< double > & weights()
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
std::vector< std::string > namedWeightIDs_
Log< level::Warning, false > LogWarning
void streamBeginRun(edm::StreamID id, edm::Run const &, edm::EventSetup const &) const override
if(threadIdxLocalY==0 &&threadIdxLocalX==0)
const edm::EDGetTokenT< GenLumiInfoHeader > genLumiInfoHeadTag_
std::shared_ptr< DynamicWeightChoiceGenInfo > globalBeginLuminosityBlock(edm::LuminosityBlock const &lumiBlock, edm::EventSetup const &) const override
Power< A, B >::type pow(const A &a, const B &b)
const std::vector< WGT > & weights() const