15 #include "boost/algorithm/string.hpp" 20 #include <unordered_map> 27 Counter() :
num(0), sumw(0), sumw2(0), sumPDF(), sumScale(), sumRwgt(), sumNamed(), sumPS() {}
33 std::vector<long double> sumPDF, sumScale, sumRwgt, sumNamed, sumPS;
42 sumNamed.clear(), sumPS.clear();
46 void incGenOnly(
double w) {
52 void incPSOnly(
double w0,
const std::vector<double>& wPS) {
55 sumPS.resize(wPS.size(), 0);
56 for (
unsigned int i = 0,
n = wPS.size();
i <
n; ++
i)
57 sumPS[
i] += (w0 * wPS[
i]);
61 void incLHE(
double w0,
62 const std::vector<double>& wScale,
63 const std::vector<double>& wPDF,
64 const std::vector<double>& wRwgt,
65 const std::vector<double>& wNamed,
66 const std::vector<double>& wPS) {
70 if (!wScale.empty()) {
72 sumScale.resize(wScale.size(), 0);
73 for (
unsigned int i = 0,
n = wScale.size();
i <
n; ++
i)
74 sumScale[
i] += (w0 * wScale[
i]);
78 sumPDF.resize(wPDF.size(), 0);
79 for (
unsigned int i = 0, n = wPDF.size();
i <
n; ++
i)
80 sumPDF[
i] += (w0 * wPDF[
i]);
84 sumRwgt.resize(wRwgt.size(), 0);
85 for (
unsigned int i = 0, n = wRwgt.size();
i <
n; ++
i)
86 sumRwgt[
i] += (w0 * wRwgt[
i]);
88 if (!wNamed.empty()) {
90 sumNamed.resize(wNamed.size(), 0);
91 for (
unsigned int i = 0, n = wNamed.size();
i <
n; ++
i)
92 sumNamed[
i] += (w0 * wNamed[
i]);
100 sumw2 += other.sumw2;
101 if (sumScale.empty() && !other.sumScale.empty())
102 sumScale.resize(other.sumScale.size(), 0);
103 if (sumPDF.empty() && !other.sumPDF.empty())
104 sumPDF.resize(other.sumPDF.size(), 0);
105 if (sumRwgt.empty() && !other.sumRwgt.empty())
106 sumRwgt.resize(other.sumRwgt.size(), 0);
107 if (sumNamed.empty() && !other.sumNamed.empty())
108 sumNamed.resize(other.sumNamed.size(), 0);
109 if (sumPS.empty() && !other.sumPS.empty())
110 sumPS.resize(other.sumPS.size(), 0);
111 if (!other.sumScale.empty())
112 for (
unsigned int i = 0, n = sumScale.size();
i <
n; ++
i)
113 sumScale[
i] += other.sumScale[
i];
114 if (!other.sumPDF.empty())
115 for (
unsigned int i = 0, n = sumPDF.size();
i <
n; ++
i)
116 sumPDF[
i] += other.sumPDF[
i];
117 if (!other.sumRwgt.empty())
118 for (
unsigned int i = 0, n = sumRwgt.size();
i <
n; ++
i)
119 sumRwgt[
i] += other.sumRwgt[
i];
120 if (!other.sumNamed.empty())
121 for (
unsigned int i = 0, n = sumNamed.size();
i <
n; ++
i)
122 sumNamed[
i] += other.sumNamed[
i];
123 if (!other.sumPS.empty())
124 for (
unsigned int i = 0, n = sumPS.size();
i <
n; ++
i)
125 sumPS[
i] += other.sumPS[
i];
130 std::map<std::string, Counter> countermap;
133 void merge(
const CounterMap& other) {
134 for (
const auto&
y : other.countermap)
135 countermap[
y.first].merge(
y.second);
139 for (
auto x : countermap)
145 active_el = &(countermap[
label]);
146 active_label =
label;
148 void checkLabelSet() {
150 throw cms::Exception(
"LogicError",
"Called CounterMap::get() before setting the active label\n");
163 struct DynamicWeightChoice {
166 std::vector<std::string> scaleWeightIDs;
169 std::vector<std::string> pdfWeightIDs;
172 std::vector<std::string> rwgtIDs;
176 struct DynamicWeightChoiceGenInfo {
179 std::vector<unsigned int> scaleWeightIDs;
182 std::vector<unsigned int> pdfWeightIDs;
185 std::vector<unsigned int> defPSWeightIDs = {6, 7, 8, 9};
186 std::vector<unsigned int> defPSWeightIDs_alt = {27, 5, 26, 4};
187 bool matchPS_alt =
false;
188 std::vector<unsigned int> psWeightIDs;
189 unsigned int psBaselineID = 1;
192 void setMissingWeight(
int idx) { psWeightIDs[
idx] = (matchPS_alt) ? defPSWeightIDs_alt[idx] : defPSWeightIDs[idx]; }
194 bool empty()
const {
return scaleWeightIDs.empty() && pdfWeightIDs.empty() && psWeightIDs.empty(); }
197 struct LumiCacheInfoHolder {
198 CounterMap countermap;
199 DynamicWeightChoiceGenInfo weightChoice;
202 weightChoice = DynamicWeightChoiceGenInfo();
208 if (match != std::string::npos) {
211 return std::stof(pre) *
std::pow(10.0
f, std::stof(post));
213 return std::stof(str);
217 struct ScaleVarWeight {
219 std::pair<float, float> scales;
221 : wid(id), label(text), scales(stof_fortrancomp(muR), stof_fortrancomp(muF)) {}
222 bool operator<(
const ScaleVarWeight& other) {
223 return (scales == other.scales ? wid < other.wid : scales < other.scales);
226 struct PDFSetWeights {
227 std::vector<std::string> wids;
228 std::pair<unsigned int, unsigned int> lhaIDs;
229 PDFSetWeights(
const std::string& wid,
unsigned int lhaID) : wids(1, wid), lhaIDs(lhaID, lhaID) {}
230 bool operator<(
const PDFSetWeights& other)
const {
return lhaIDs < other.lhaIDs; }
233 lhaIDs.second = lhaID;
235 bool maybe_add(
const std::string& wid,
unsigned int lhaID) {
236 if (lhaID == lhaIDs.second + 1) {
248 edm::RunCache<DynamicWeightChoice>,
249 edm::RunSummaryCache<CounterMap>,
250 edm::EndRunProducer> {
254 lheLabel_(params.getParameter<
std::vector<
edm::InputTag>>(
"lheInfo")),
256 [this](const
edm::InputTag&
tag) {
return mayConsume<LHEEventProduct>(
tag); })),
258 lheLabel_, [
this](
const edm::InputTag&
tag) {
return mayConsume<LHERunInfoProduct, edm::InRun>(
tag); })),
260 mayConsume<GenLumiInfoHeader, edm::InLumi>(params.getParameter<
edm::InputTag>(
"genLumiInfoHeader"))),
261 namedWeightIDs_(params.getParameter<std::vector<std::string>>(
"namedWeightIDs")),
262 namedWeightLabels_(params.getParameter<std::vector<std::string>>(
"namedWeightLabels")),
263 lheWeightPrecision_(params.getParameter<int32_t>(
"lheWeightPrecision")),
264 maxPdfWeights_(params.getParameter<uint32_t>(
"maxPdfWeights")),
265 keepAllPSWeights_(params.getParameter<
bool>(
"keepAllPSWeights")),
266 debug_(params.getUntrackedParameter<
bool>(
"debug",
false)),
267 debugRun_(debug_.load()),
268 hasIssuedWarning_(
false),
269 psWeightWarning_(
false) {
270 produces<nanoaod::FlatTable>();
271 produces<std::string>(
"genModel");
272 produces<nanoaod::FlatTable>(
"LHEScale");
273 produces<nanoaod::FlatTable>(
"LHEPdf");
274 produces<nanoaod::FlatTable>(
"LHEReweighting");
275 produces<nanoaod::FlatTable>(
"LHENamed");
276 produces<nanoaod::FlatTable>(
"PS");
277 produces<nanoaod::MergeableCounterTable, edm::Transition::EndRun>();
278 if (namedWeightIDs_.size() != namedWeightLabels_.size()) {
279 throw cms::Exception(
"Configuration",
"Size mismatch between namedWeightIDs & namedWeightLabels");
283 uint32_t
lhaid = pdfps.getParameter<uint32_t>(
"lhaid");
284 preferredPDFLHAIDs_.push_back(lhaid);
286 lhaNameToID_[name +
".LHgrid"] =
lhaid;
302 auto out = std::make_unique<nanoaod::FlatTable>(1,
"genWeight",
true);
303 out->setDoc(
"generator weight");
307 std::string model_label = streamCache(
id)->countermap.getLabel();
308 auto outM = std::make_unique<std::string>((!model_label.empty()) ?
std::string(
"GenModel_") + model_label :
"");
310 bool getLHEweightsFromGenInfo = !model_label.empty();
313 std::unique_ptr<nanoaod::FlatTable> lheScaleTab, lhePdfTab, lheRwgtTab, lheNamedTab;
314 std::unique_ptr<nanoaod::FlatTable> genPSTab;
317 for (
const auto& lheTag : lheTag_) {
324 const auto genWeightChoice = &(streamCache(
id)->weightChoice);
326 if (getLHEweightsFromGenInfo && !hasIssuedWarning_.exchange(
true))
328 <<
"Found both a LHEEventProduct and a GenLumiInfoHeader: will only save weights from LHEEventProduct.\n";
330 const DynamicWeightChoice* weightChoice = runCache(iEvent.
getRun().
index());
332 fillLHEWeightTables(counter,
343 }
else if (getLHEweightsFromGenInfo) {
344 fillLHEPdfWeightTablesFromGenInfo(
345 counter, genWeightChoice, weight, *genInfo, lheScaleTab, lhePdfTab, lheNamedTab, genPSTab);
346 lheRwgtTab = std::make_unique<nanoaod::FlatTable>(1,
"LHEReweightingWeights",
true);
351 fillOnlyPSWeightTable(counter, genWeightChoice, weight, *genInfo, genPSTab);
353 lheScaleTab = std::make_unique<nanoaod::FlatTable>(1,
"LHEScaleWeights",
true);
354 lhePdfTab = std::make_unique<nanoaod::FlatTable>(1,
"LHEPdfWeights",
true);
355 lheRwgtTab = std::make_unique<nanoaod::FlatTable>(1,
"LHEReweightingWeights",
true);
356 lheNamedTab = std::make_unique<nanoaod::FlatTable>(1,
"LHENamedWeights",
true);
357 if (!hasIssuedWarning_.exchange(
true)) {
358 edm::LogWarning(
"LHETablesProducer") <<
"No LHEEventProduct, so there will be no LHE Tables\n";
370 const DynamicWeightChoice* weightChoice,
371 const DynamicWeightChoiceGenInfo* genWeightChoice,
375 std::unique_ptr<nanoaod::FlatTable>& outScale,
376 std::unique_ptr<nanoaod::FlatTable>& outPdf,
377 std::unique_ptr<nanoaod::FlatTable>& outRwgt,
378 std::unique_ptr<nanoaod::FlatTable>& outNamed,
379 std::unique_ptr<nanoaod::FlatTable>& outPS)
const {
380 bool lheDebug = debug_.exchange(
383 const std::vector<std::string>& scaleWeightIDs = weightChoice->scaleWeightIDs;
384 const std::vector<std::string>& pdfWeightIDs = weightChoice->pdfWeightIDs;
385 const std::vector<std::string>& rwgtWeightIDs = weightChoice->rwgtIDs;
389 std::vector<double> wScale(scaleWeightIDs.size(), 1), wPDF(pdfWeightIDs.size(), 1), wRwgt(rwgtWeightIDs.size(), 1),
390 wNamed(namedWeightIDs_.size(), 1);
393 printf(
"Weight %+9.5f rel %+9.5f for id %s\n",
weight.wgt,
weight.wgt / w0,
weight.id.c_str());
395 auto mScale =
std::find(scaleWeightIDs.begin(), scaleWeightIDs.end(),
weight.id);
396 if (mScale != scaleWeightIDs.end())
397 wScale[mScale - scaleWeightIDs.begin()] =
weight.wgt / w0;
399 auto mPDF =
std::find(pdfWeightIDs.begin(), pdfWeightIDs.end(),
weight.id);
400 if (mPDF != pdfWeightIDs.end())
401 wPDF[mPDF - pdfWeightIDs.begin()] =
weight.wgt / w0;
403 auto mRwgt =
std::find(rwgtWeightIDs.begin(), rwgtWeightIDs.end(),
weight.id);
404 if (mRwgt != rwgtWeightIDs.end())
405 wRwgt[mRwgt - rwgtWeightIDs.begin()] =
weight.wgt / w0;
407 auto mNamed =
std::find(namedWeightIDs_.begin(), namedWeightIDs_.end(),
weight.id);
408 if (mNamed != namedWeightIDs_.end())
409 wNamed[mNamed - namedWeightIDs_.begin()] =
weight.wgt / w0;
412 std::vector<double> wPS;
414 setPSWeightInfo(genProd.
weights(), genWeightChoice, wPS, psWeightDocStr);
416 outPS = std::make_unique<nanoaod::FlatTable>(wPS.size(),
"PSWeight",
false);
419 outScale = std::make_unique<nanoaod::FlatTable>(wScale.size(),
"LHEScaleWeight",
false);
420 outScale->addColumn<
float>(
423 outPdf = std::make_unique<nanoaod::FlatTable>(wPDF.size(),
"LHEPdfWeight",
false);
424 outPdf->addColumn<
float>(
427 outRwgt = std::make_unique<nanoaod::FlatTable>(wRwgt.size(),
"LHEReweightingWeight",
false);
428 outRwgt->addColumn<
float>(
431 outNamed = std::make_unique<nanoaod::FlatTable>(1,
"LHEWeight",
true);
432 outNamed->addColumnValue<
float>(
"originalXWGTUP",
434 "Nominal event weight in the LHE file",
436 for (
unsigned int i = 0, n = wNamed.size();
i <
n; ++
i) {
437 outNamed->addColumnValue<
float>(namedWeightLabels_[
i],
439 "LHE weight for id " + namedWeightIDs_[
i] +
", relative to nominal",
441 lheWeightPrecision_);
444 counter->incLHE(genWeight, wScale, wPDF, wRwgt, wNamed, wPS);
448 const DynamicWeightChoiceGenInfo* weightChoice,
451 std::unique_ptr<nanoaod::FlatTable>& outScale,
452 std::unique_ptr<nanoaod::FlatTable>& outPdf,
453 std::unique_ptr<nanoaod::FlatTable>& outNamed,
454 std::unique_ptr<nanoaod::FlatTable>& outPS)
const {
455 const std::vector<unsigned int>& scaleWeightIDs = weightChoice->scaleWeightIDs;
456 const std::vector<unsigned int>& pdfWeightIDs = weightChoice->pdfWeightIDs;
460 double originalXWGTUP = (
weights.size() > 1) ?
weights.at(1) : 1.;
462 std::vector<double> wScale, wPDF, wPS;
463 for (
auto id : scaleWeightIDs)
464 wScale.push_back(
weights.at(
id) / w0);
465 for (
auto id : pdfWeightIDs) {
466 wPDF.push_back(
weights.at(
id) / w0);
470 setPSWeightInfo(genProd.
weights(), weightChoice, wPS, psWeightsDocStr);
472 outScale = std::make_unique<nanoaod::FlatTable>(wScale.size(),
"LHEScaleWeight",
false);
473 outScale->addColumn<
float>(
476 outPdf = std::make_unique<nanoaod::FlatTable>(wPDF.size(),
"LHEPdfWeight",
false);
477 outPdf->addColumn<
float>(
480 outPS = std::make_unique<nanoaod::FlatTable>(wPS.size(),
"PSWeight",
false);
482 lheWeightPrecision_);
484 outNamed = std::make_unique<nanoaod::FlatTable>(1,
"LHEWeight",
true);
485 outNamed->addColumnValue<
float>(
491 counter->incLHE(genWeight, wScale, wPDF, std::vector<double>(), std::vector<double>(), wPS);
495 const DynamicWeightChoiceGenInfo* genWeightChoice,
498 std::unique_ptr<nanoaod::FlatTable>& outPS)
const {
499 std::vector<double> wPS;
501 setPSWeightInfo(genProd.
weights(), genWeightChoice, wPS, psWeightDocStr);
502 outPS = std::make_unique<nanoaod::FlatTable>(wPS.size(),
"PSWeight",
false);
505 counter->incGenOnly(genWeight);
506 counter->incPSOnly(genWeight, wPS);
510 const DynamicWeightChoiceGenInfo* genWeightChoice,
511 std::vector<double>& wPS,
516 bool isRegularPSSet = keepAllPSWeights_ && (genWeights.size() == 14 || genWeights.size() == 46);
517 if (!genWeightChoice->psWeightIDs.empty() && !isRegularPSSet) {
518 psWeightDocStr = genWeightChoice->psWeightsDoc;
519 double psNom = genWeights.at(genWeightChoice->psBaselineID);
520 for (
auto wgtidx : genWeightChoice->psWeightIDs) {
521 wPS.push_back(genWeights.at(wgtidx) / psNom);
525 keepAllPSWeights_ ? (genWeights.size() - 2) : ((genWeights.size() == 14 || genWeights.size() == 46) ? 4 : 1);
527 if (vectorSize > 1) {
528 double nominal = genWeights.at(1);
529 if (keepAllPSWeights_) {
530 for (
int i = 0;
i < vectorSize;
i++) {
531 wPS.push_back(genWeights.at(
i + 2) / nominal);
533 psWeightDocStr =
"All PS weights (w_var / w_nominal)";
535 if (!psWeightWarning_.exchange(
true))
537 <<
"GenLumiInfoHeader not found: Central PartonShower weights will fill with the 6-10th entries \n" 538 <<
" This may incorrect for some mcs (madgraph 2.6.1 with its `isr:murfact=0.5` have a differnt " 540 for (std::size_t
i = 6;
i < 10;
i++) {
541 wPS.push_back(genWeights.at(
i) / nominal);
544 "PS weights (w_var / w_nominal); [0] is ISR=2 FSR=1; [1] is ISR=1 FSR=2" 545 "[2] is ISR=0.5 FSR=1; [3] is ISR=1 FSR=0.5;";
549 psWeightDocStr =
"dummy PS weight (1.0) ";
558 bool lheDebug = debugRun_.exchange(
560 auto weightChoice = std::make_shared<DynamicWeightChoice>();
564 for (
const auto& lheLabel : lheLabel_) {
571 std::vector<ScaleVarWeight> scaleVariationIDs;
572 std::vector<PDFSetWeights> pdfSetWeightIDs;
573 std::vector<std::string> lheReweighingIDs;
574 bool isFirstGroup =
true;
576 std::regex weightgroupmg26x(
"<weightgroup\\s+(?:name|type)=\"(.*)\"\\s+combine=\"(.*)\"\\s*>");
577 std::regex weightgroup(
"<weightgroup\\s+combine=\"(.*)\"\\s+(?:name|type)=\"(.*)\"\\s*>");
578 std::regex weightgroupRwgt(
"<weightgroup\\s+(?:name|type)=\"(.*)\"\\s*>");
579 std::regex endweightgroup(
"</weightgroup>");
580 std::regex scalewmg26x(
581 "<weight\\s+(?:.*\\s+)?id=\"(\\d+)\"\\s*(?:lhapdf=\\d+|dyn=\\s*-?\\d+)?\\s*((?:[mM][uU][rR]|renscfact)=\"(" 582 "\\S+)\"\\s+(?:[mM][uU][Ff]|facscfact)=\"(\\S+)\")(\\s+.*)?</weight>");
583 std::regex scalewmg26xNew(
584 "<weight\\s*((?:[mM][uU][fF]|facscfact)=\"(\\S+)\"\\s+(?:[mM][uU][Rr]|renscfact)=\"(\\S+)\").+id=\"(\\d+)\"(." 589 "<weight\\s+(?:.*\\s+)?id=\"(\\d+|\\d+-NNLOPS)\">\\s*(?:lhapdf=\\d+|dyn=\\s*-?\\d+)?\\s*((?:mu[rR]|renscfact)" 590 "=(\\S+)\\s+(?:mu[Ff]|facscfact)=(\\S+)(\\s+.*)?)</weight>");
592 "<weight\\s+id=\"(\\d+)\">\\s*(?:PDF set|lhapdf|PDF|pdfset)\\s*=\\s*(\\d+)\\s*(?:\\s.*)?</weight>");
593 std::regex pdfwOld(
"<weight\\s+(?:.*\\s+)?id=\"(\\d+)\">\\s*Member \\s*(\\d+)\\s*(?:.*)</weight>");
594 std::regex pdfwmg26x(
595 "<weight\\s+id=\"(\\d+)\"\\s*MUR=\"(?:\\S+)\"\\s*MUF=\"(?:\\S+)\"\\s*(?:PDF " 596 "set|lhapdf|PDF|pdfset)\\s*=\\s*\"(\\d+)\"\\s*>\\s*(?:PDF=(\\d+)\\s*MemberID=(\\d+))?\\s*(?:\\s.*)?</" 601 std::regex pdfwmg26xNew(
602 "<weight\\s+MUF=\"(?:\\S+)\"\\s*MUR=\"(?:\\S+)\"\\s*PDF=\"(?:\\S+)\"\\s*id=\"(\\S+)\"\\s*>" 603 "\\s*(?:PDF=(\\d+)\\s*MemberID=(\\d+))?\\s*(?:\\s.*)?</" 606 std::regex rwgt(
"<weight\\s+id=\"(.+)\">(.+)?(</weight>)?");
609 if (iter->tag() !=
"initrwgt") {
611 std::cout <<
"Skipping LHE header with tag" << iter->tag() << std::endl;
615 std::cout <<
"Found LHE header with tag" << iter->tag() << std::endl;
616 std::vector<std::string>
lines = iter->lines();
617 bool missed_weightgroup =
619 bool ismg26x =
false;
620 bool ismg26xNew =
false;
621 for (
unsigned int iLine = 0, nLines = lines.size(); iLine < nLines;
623 boost::replace_all(lines[iLine],
"<",
"<");
624 boost::replace_all(lines[iLine],
">",
">");
625 if (std::regex_search(lines[iLine], groups, weightgroupmg26x)) {
627 }
else if (std::regex_search(lines[iLine], groups, scalewmg26xNew) ||
628 std::regex_search(lines[iLine], groups, pdfwmg26xNew)) {
632 for (
unsigned int iLine = 0, nLines = lines.size(); iLine < nLines; ++iLine) {
635 if (std::regex_search(lines[iLine], groups, ismg26x ? weightgroupmg26x : weightgroup)) {
638 groupname = groups.str(1);
640 std::cout <<
">>> Looks like the beginning of a weight group for '" << groupname <<
"'" << std::endl;
641 if (groupname.find(
"scale_variation") == 0 || groupname ==
"Central scale variation" || isFirstGroup) {
642 if (lheDebug && groupname.find(
"scale_variation") != 0 && groupname !=
"Central scale variation")
643 std::cout <<
">>> First weight is not scale variation, but assuming is the Central Weight" << std::endl;
645 std::cout <<
">>> Looks like scale variation for theory uncertainties" << std::endl;
646 isFirstGroup =
false;
647 for (++iLine; iLine < nLines; ++iLine) {
651 if (std::regex_search(
652 lines[iLine], groups, ismg26x ? scalewmg26x : (ismg26xNew ? scalewmg26xNew : scalew))) {
654 std::cout <<
" >>> Scale weight " << groups[1].str() <<
" for " << groups[3].str() <<
" , " 655 << groups[4].str() <<
" , " << groups[5].str() << std::endl;
657 scaleVariationIDs.emplace_back(groups.str(4), groups.str(1), groups.str(3), groups.str(2));
659 scaleVariationIDs.emplace_back(groups.str(1), groups.str(2), groups.str(3), groups.str(4));
661 }
else if (std::regex_search(lines[iLine], endweightgroup)) {
663 std::cout <<
">>> Looks like the end of a weight group" << std::endl;
664 if (!missed_weightgroup) {
667 missed_weightgroup =
false;
668 }
else if (std::regex_search(lines[iLine], ismg26x ? weightgroupmg26x : weightgroup)) {
670 std::cout <<
">>> Looks like the beginning of a new weight group, I will assume I missed the end " 673 if (ismg26x || ismg26xNew)
674 missed_weightgroup =
true;
679 }
else if (groupname ==
"PDF_variation" || groupname.find(
"PDF_variation ") == 0) {
681 std::cout <<
">>> Looks like a new-style block of PDF weights for one or more pdfs" << std::endl;
682 for (++iLine; iLine < nLines; ++iLine) {
685 if (std::regex_search(lines[iLine], groups, pdfw)) {
686 unsigned int lhaID = std::stoi(groups.str(2));
688 std::cout <<
" >>> PDF weight " << groups.str(1) <<
" for " << groups.str(2) <<
" = " << lhaID
690 if (pdfSetWeightIDs.empty() || !pdfSetWeightIDs.back().maybe_add(groups.str(1), lhaID)) {
691 pdfSetWeightIDs.emplace_back(groups.str(1), lhaID);
693 }
else if (std::regex_search(lines[iLine], endweightgroup)) {
695 std::cout <<
">>> Looks like the end of a weight group" << std::endl;
696 if (!missed_weightgroup) {
699 missed_weightgroup =
false;
700 }
else if (std::regex_search(lines[iLine], ismg26x ? weightgroupmg26x : weightgroup)) {
702 std::cout <<
">>> Looks like the beginning of a new weight group, I will assume I missed the end " 705 if (ismg26x || ismg26xNew)
706 missed_weightgroup =
true;
711 }
else if (groupname ==
"PDF_variation1" || groupname ==
"PDF_variation2") {
713 std::cout <<
">>> Looks like a new-style block of PDF weights for multiple pdfs" << std::endl;
714 unsigned int lastid = 0;
715 for (++iLine; iLine < nLines; ++iLine) {
718 if (std::regex_search(lines[iLine], groups, pdfw)) {
719 unsigned int id = std::stoi(groups.str(1));
720 unsigned int lhaID = std::stoi(groups.str(2));
722 std::cout <<
" >>> PDF weight " << groups.str(1) <<
" for " << groups.str(2) <<
" = " << lhaID
724 if (
id != (lastid + 1) || pdfSetWeightIDs.empty()) {
725 pdfSetWeightIDs.emplace_back(groups.str(1), lhaID);
727 pdfSetWeightIDs.back().add(groups.str(1), lhaID);
730 }
else if (std::regex_search(lines[iLine], endweightgroup)) {
732 std::cout <<
">>> Looks like the end of a weight group" << std::endl;
733 if (!missed_weightgroup) {
736 missed_weightgroup =
false;
737 }
else if (std::regex_search(lines[iLine], ismg26x ? weightgroupmg26x : weightgroup)) {
739 std::cout <<
">>> Looks like the beginning of a new weight group, I will assume I missed the end " 742 if (ismg26x || ismg26xNew)
743 missed_weightgroup =
true;
748 }
else if (lhaNameToID_.find(groupname) != lhaNameToID_.end()) {
750 std::cout <<
">>> Looks like an old-style PDF weight for an individual pdf" << std::endl;
751 unsigned int firstLhaID = lhaNameToID_.find(groupname)->second;
753 for (++iLine; iLine < nLines; ++iLine) {
756 if (std::regex_search(
757 lines[iLine], groups, ismg26x ? pdfwmg26x : (ismg26xNew ? pdfwmg26xNew : pdfwOld))) {
758 unsigned int member = 0;
759 if (!ismg26x && !ismg26xNew) {
760 member = std::stoi(groups.str(2));
761 }
else if (ismg26xNew) {
762 if (!groups.str(3).empty()) {
763 member = std::stoi(groups.str(3));
766 if (!groups.str(4).empty()) {
767 member = std::stoi(groups.str(4));
770 unsigned int lhaID = member + firstLhaID;
772 std::cout <<
" >>> PDF weight " << groups.str(1) <<
" for " << member <<
" = " << lhaID
776 pdfSetWeightIDs.emplace_back(groups.str(1), lhaID);
779 pdfSetWeightIDs.back().add(groups.str(1), lhaID);
781 }
else if (std::regex_search(lines[iLine], endweightgroup)) {
783 std::cout <<
">>> Looks like the end of a weight group" << std::endl;
784 if (!missed_weightgroup) {
787 missed_weightgroup =
false;
788 }
else if (std::regex_search(lines[iLine], ismg26x ? weightgroupmg26x : weightgroup)) {
790 std::cout <<
">>> Looks like the beginning of a new weight group, I will assume I missed the end " 793 if (ismg26x || ismg26xNew)
794 missed_weightgroup =
true;
799 }
else if (groupname ==
"mass_variation" || groupname ==
"sthw2_variation" ||
800 groupname ==
"width_variation") {
802 std::cout <<
">>> Looks like an EW parameter weight" << std::endl;
803 for (++iLine; iLine < nLines; ++iLine) {
806 if (std::regex_search(lines[iLine], groups, rwgt)) {
809 std::cout <<
" >>> LHE reweighting weight: " << rwgtID << std::endl;
810 if (
std::find(lheReweighingIDs.begin(), lheReweighingIDs.end(), rwgtID) == lheReweighingIDs.end()) {
812 lheReweighingIDs.emplace_back(rwgtID);
814 }
else if (std::regex_search(lines[iLine], endweightgroup)) {
816 std::cout <<
">>> Looks like the end of a weight group" << std::endl;
820 for (++iLine; iLine < nLines; ++iLine) {
823 if (std::regex_search(lines[iLine], groups, endweightgroup)) {
825 std::cout <<
">>> Looks like the end of a weight group" << std::endl;
826 if (!missed_weightgroup) {
829 missed_weightgroup =
false;
830 }
else if (std::regex_search(lines[iLine], ismg26x ? weightgroupmg26x : weightgroup)) {
832 std::cout <<
">>> Looks like the beginning of a new weight group, I will assume I missed the end " 835 if (ismg26x || ismg26xNew)
836 missed_weightgroup =
true;
842 }
else if (std::regex_search(lines[iLine], groups, weightgroupRwgt)) {
844 if (groupname ==
"mg_reweighting") {
846 std::cout <<
">>> Looks like a LHE weights for reweighting" << std::endl;
847 for (++iLine; iLine < nLines; ++iLine) {
850 if (std::regex_search(lines[iLine], groups, rwgt)) {
853 std::cout <<
" >>> LHE reweighting weight: " << rwgtID << std::endl;
854 if (
std::find(lheReweighingIDs.begin(), lheReweighingIDs.end(), rwgtID) == lheReweighingIDs.end()) {
856 lheReweighingIDs.emplace_back(rwgtID);
858 }
else if (std::regex_search(lines[iLine], endweightgroup)) {
860 std::cout <<
">>> Looks like the end of a weight group" << std::endl;
861 if (!missed_weightgroup) {
864 missed_weightgroup =
false;
865 }
else if (std::regex_search(lines[iLine], ismg26x ? weightgroupmg26x : weightgroup)) {
867 std::cout <<
">>> Looks like the beginning of a new weight group, I will assume I missed the end " 871 missed_weightgroup =
true;
882 std::sort(scaleVariationIDs.begin(), scaleVariationIDs.end());
884 std::cout <<
"Found " << scaleVariationIDs.size() <<
" scale variations: " << std::endl;
885 std::stringstream scaleDoc;
886 scaleDoc <<
"LHE scale variation weights (w_var / w_nominal); ";
887 for (
unsigned int isw = 0, nsw = scaleVariationIDs.size(); isw < nsw; ++isw) {
888 const auto& sw = scaleVariationIDs[isw];
891 scaleDoc <<
"[" << isw <<
"] is " << sw.label;
892 weightChoice->scaleWeightIDs.push_back(sw.wid);
894 printf(
" id %s: scales ren = % .2f fact = % .2f text = %s\n",
900 if (!scaleVariationIDs.empty())
901 weightChoice->scaleWeightsDoc = scaleDoc.str();
905 std::cout <<
"Found " << pdfSetWeightIDs.size() <<
" PDF set errors: " << std::endl;
906 for (
const auto& pw : pdfSetWeightIDs)
907 printf(
"lhaIDs %6d - %6d (%3lu weights: %s, ... )\n",
911 pw.wids.front().c_str());
916 std::cout <<
"Found " << lheReweighingIDs.size() <<
" reweighting weights" << std::endl;
918 std::copy(lheReweighingIDs.begin(), lheReweighingIDs.end(), std::back_inserter(weightChoice->rwgtIDs));
920 std::stringstream pdfDoc;
921 pdfDoc <<
"LHE pdf variation weights (w_var / w_nominal) for LHA IDs ";
923 for (
const auto& pw : pdfSetWeightIDs) {
924 for (uint32_t
lhaid : preferredPDFLHAIDs_) {
925 if (pw.lhaIDs.first !=
lhaid && pw.lhaIDs.first != (
lhaid + 1))
927 if (pw.wids.size() == 1)
929 pdfDoc << pw.lhaIDs.first <<
" - " << pw.lhaIDs.second;
930 weightChoice->pdfWeightIDs = pw.wids;
931 if (maxPdfWeights_ < pw.wids.size()) {
932 weightChoice->pdfWeightIDs.resize(maxPdfWeights_);
933 pdfDoc <<
", truncated to the first " << maxPdfWeights_ <<
" replicas";
935 weightChoice->pdfWeightsDoc = pdfDoc.str();
949 return std::make_unique<LumiCacheInfoHolder>();
953 streamCache(
id)->clear();
958 auto counterMap = &(streamCache(
id)->countermap);
960 lumiBlock.
getByToken(genLumiInfoHeadTag_, genLumiInfoHead);
961 if (!genLumiInfoHead.
isValid())
963 <<
"No GenLumiInfoHeader product found, will not fill generator model string.\n";
966 if (genLumiInfoHead.
isValid()) {
968 boost::replace_all(label,
"-",
"_");
969 boost::replace_all(label,
"/",
"_");
971 counterMap->setLabel(label);
973 if (genLumiInfoHead.
isValid()) {
974 auto weightChoice = &(streamCache(
id)->weightChoice);
976 std::vector<ScaleVarWeight> scaleVariationIDs;
977 std::vector<PDFSetWeights> pdfSetWeightIDs;
978 weightChoice->psWeightIDs.clear();
980 std::regex scalew(
"LHE,\\s+id\\s+=\\s+(\\d+),\\s+(.+)\\,\\s+mur=(\\S+)\\smuf=(\\S+)");
981 std::regex pdfw(
"LHE,\\s+id\\s+=\\s+(\\d+),\\s+(.+),\\s+Member\\s+(\\d+)\\s+of\\ssets\\s+(\\w+\\b)");
982 std::regex mainPSw(
"sr(Def|:murfac=)(Hi|Lo|_dn|_up|0.5|2.0)");
985 std::unordered_map<std::string, uint32_t> knownPDFSetsFromGenInfo_;
986 unsigned int weightIter = 0;
987 for (
const auto&
line : weightNames) {
988 if (std::regex_search(
line, groups, scalew)) {
989 auto id = groups.str(1);
990 auto group = groups.str(2);
991 auto mur = groups.str(3);
992 auto muf = groups.str(4);
993 if (
group.find(
"Central scale variation") != std::string::npos)
994 scaleVariationIDs.emplace_back(groups.str(1), groups.str(2), groups.str(3), groups.str(4));
995 }
else if (std::regex_search(
line, groups, pdfw)) {
996 auto id = groups.str(1);
997 auto group = groups.str(2);
998 auto memberid = groups.str(3);
999 auto pdfset = groups.str(4);
1000 if (
group.find(pdfset) != std::string::npos) {
1001 if (knownPDFSetsFromGenInfo_.find(pdfset) == knownPDFSetsFromGenInfo_.end()) {
1002 knownPDFSetsFromGenInfo_[pdfset] = std::atoi(
id.c_str());
1003 pdfSetWeightIDs.emplace_back(
id, std::atoi(
id.c_str()));
1005 pdfSetWeightIDs.back().add(
id, std::atoi(
id.c_str()));
1007 }
else if (
line ==
"Baseline") {
1008 weightChoice->psBaselineID = weightIter;
1009 }
else if (
line.find(
"isr") != std::string::npos ||
line.find(
"fsr") != std::string::npos) {
1010 weightChoice->matchPS_alt =
line.find(
"sr:") != std::string::npos;
1011 if (keepAllPSWeights_) {
1012 weightChoice->psWeightIDs.push_back(weightIter);
1013 }
else if (std::regex_search(
line, groups, mainPSw)) {
1014 if (weightChoice->psWeightIDs.empty())
1015 weightChoice->psWeightIDs = std::vector<unsigned int>(4, -1);
1016 int psIdx = (
line.find(
"fsr") != std::string::npos) ? 1 : 0;
1017 psIdx += (groups.str(2) ==
"Hi" || groups.str(2) ==
"_up" || groups.str(2) ==
"2.0") ? 0 : 2;
1018 weightChoice->psWeightIDs[psIdx] = weightIter;
1023 if (keepAllPSWeights_) {
1024 weightChoice->psWeightsDoc =
"All PS weights (w_var / w_nominal)";
1025 }
else if (weightChoice->psWeightIDs.size() == 4) {
1026 weightChoice->psWeightsDoc =
1027 "PS weights (w_var / w_nominal); [0] is ISR=2 FSR=1; [1] is ISR=1 FSR=2" 1028 "[2] is ISR=0.5 FSR=1; [3] is ISR=1 FSR=0.5;";
1029 for (
int i = 0;
i < 4;
i++) {
1030 if (static_cast<int>(weightChoice->psWeightIDs[
i]) == -1)
1031 weightChoice->setMissingWeight(
i);
1034 weightChoice->psWeightsDoc =
"dummy PS weight (1.0) ";
1037 weightChoice->scaleWeightIDs.clear();
1038 weightChoice->pdfWeightIDs.clear();
1040 std::sort(scaleVariationIDs.begin(), scaleVariationIDs.end());
1041 std::stringstream scaleDoc;
1042 scaleDoc <<
"LHE scale variation weights (w_var / w_nominal); ";
1043 for (
unsigned int isw = 0, nsw = scaleVariationIDs.size(); isw < nsw; ++isw) {
1044 const auto& sw = scaleVariationIDs[isw];
1047 scaleDoc <<
"[" << isw <<
"] is " << sw.label;
1048 weightChoice->scaleWeightIDs.push_back(std::atoi(sw.wid.c_str()));
1050 if (!scaleVariationIDs.empty())
1051 weightChoice->scaleWeightsDoc = scaleDoc.str();
1052 std::stringstream pdfDoc;
1053 pdfDoc <<
"LHE pdf variation weights (w_var / w_nominal) for LHA names ";
1055 for (
const auto& pw : pdfSetWeightIDs) {
1056 if (pw.wids.size() == 1)
1058 for (
const auto& wantedpdf : lhaNameToID_) {
1059 auto pdfname = wantedpdf.first;
1060 if (knownPDFSetsFromGenInfo_.find(pdfname) == knownPDFSetsFromGenInfo_.end())
1062 uint32_t
lhaid = knownPDFSetsFromGenInfo_.at(pdfname);
1063 if (pw.lhaIDs.first != lhaid)
1066 for (
const auto&
x : pw.wids)
1067 weightChoice->pdfWeightIDs.push_back(std::atoi(
x.c_str()));
1068 if (maxPdfWeights_ < pw.wids.size()) {
1069 weightChoice->pdfWeightIDs.resize(maxPdfWeights_);
1070 pdfDoc <<
", truncated to the first " << maxPdfWeights_ <<
" replicas";
1072 weightChoice->pdfWeightsDoc = pdfDoc.str();
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 if (!runCounter->sumRwgt.empty()) {
1123 auto sumRwgts = runCounter->sumRwgt;
1124 for (
auto&
val : sumRwgts)
1126 out->addVFloatWithNorm(
"LHEReweightingSumw" + label,
1127 "Sum of genEventWeight * LHEReweightingWeight[i], divided by genEventSumw" + doclabel,
1131 if (!runCounter->sumNamed.empty()) {
1132 for (
unsigned int i = 0, n = namedWeightLabels_.size();
i <
n; ++
i) {
1133 out->addFloatWithNorm(
1134 "LHESumw_" + namedWeightLabels_[
i] + label,
1135 "Sum of genEventWeight * LHEWeight_" + namedWeightLabels_[
i] +
", divided by genEventSumw" + doclabel,
1136 runCounter->sumNamed[
i] * norm,
1149 ->setComment(
"tag for the GenEventInfoProduct, to get the main weight");
1151 ->setComment(
"tag for the GenLumiInfoProduct, to get the model string");
1152 desc.
add<std::vector<edm::InputTag>>(
"lheInfo", std::vector<edm::InputTag>{{
"externalLHEProducer"}, {
"source"}})
1153 ->setComment(
"tag(s) for the LHE information (LHEEventProduct and LHERunInfoProduct)");
1157 prefpdf.
add<uint32_t>(
"lhaid");
1158 desc.
addVPSet(
"preferredPDFs", prefpdf, std::vector<edm::ParameterSet>())
1160 "LHA PDF Ids of the preferred PDF sets, in order of preference (the first matching one will be used)");
1161 desc.
add<std::vector<std::string>>(
"namedWeightIDs")->setComment(
"set of LHA weight IDs for named LHE weights");
1162 desc.
add<std::vector<std::string>>(
"namedWeightLabels")
1163 ->setComment(
"output names for the namedWeightIDs (in the same order)");
1164 desc.
add<int32_t>(
"lheWeightPrecision")->setComment(
"Number of bits in the mantissa for LHE weights");
1165 desc.
add<uint32_t>(
"maxPdfWeights")->setComment(
"Maximum number of PDF weights to save (to crop NN replicas)");
1166 desc.
add<
bool>(
"keepAllPSWeights")->setComment(
"Store all PS weights found");
1167 desc.
addOptionalUntracked<
bool>(
"debug")->setComment(
"dump out all LHE information for one event");
1168 descriptions.
add(
"genWeightsTable", desc);
1174 const std::vector<edm::EDGetTokenT<LHEEventProduct>>
lheTag_;
1175 const std::vector<edm::EDGetTokenT<LHERunInfoProduct>>
lheRunTag_;
const std::vector< edm::EDGetTokenT< LHERunInfoProduct > > lheRunTag_
double originalXWGTUP() const
T getParameter(std::string const &) const
bool getByLabel(std::string const &label, Handle< PROD > &result) const
void setComment(std::string const &value)
void setPSWeightInfo(const std::vector< double > &genWeights, const DynamicWeightChoiceGenInfo *genWeightChoice, std::vector< double > &wPS, std::string &psWeightDocStr) const
std::unique_ptr< LumiCacheInfoHolder > beginStream(edm::StreamID) const override
void streamBeginRun(edm::StreamID id, edm::Run const &, edm::EventSetup const &) const override
OrphanHandle< PROD > put(std::unique_ptr< PROD > product)
Put a new product.
ParameterDescriptionBase * addVPSet(U const &iLabel, ParameterSetDescription const &validator, std::vector< ParameterSet > const &defaults)
void streamBeginLuminosityBlock(edm::StreamID id, edm::LuminosityBlock const &lumiBlock, edm::EventSetup const &eventSetup) const override
void globalEndRun(edm::Run const &, edm::EventSetup const &) const override
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
bool getByToken(EDGetToken token, Handle< PROD > &result) const
bool getByToken(EDGetToken token, Handle< PROD > &result) const
const edm::EDGetTokenT< GenEventInfoProduct > genTag_
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
std::shared_ptr< DynamicWeightChoice > globalBeginRun(edm::Run const &iRun, edm::EventSetup const &) const override
headers_const_iterator headers_end() const
Run const & getRun() const
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)
void globalEndRunSummary(edm::Run const &, edm::EventSetup const &, CounterMap *runCounterMap) const override
const std::vector< edm::InputTag > lheLabel_
const std::vector< WGT > & weights() const
std::function< unsigned int(align::ID)> Counter
std::shared_ptr< CounterMap > globalBeginRunSummary(edm::Run const &, edm::EventSetup const &) const override
#define DEFINE_FWK_MODULE(type)
headers_const_iterator headers_begin() const
void clear(CLHEP::HepGenMatrix &m)
Helper function: Reset all elements of a matrix to 0.
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::atomic< bool > psWeightWarning_
ParameterDescriptionBase * add(U const &iLabel, T const &value)
void fillOnlyPSWeightTable(Counter *counter, const DynamicWeightChoiceGenInfo *genWeightChoice, double genWeight, const GenEventInfoProduct &genProd, std::unique_ptr< nanoaod::FlatTable > &outPS) const
void add(std::map< std::string, TH1 * > &h, TH1 *hist)
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::vector< std::string > namedWeightLabels_
~GenWeightsTableProducer() override
GenWeightsTableProducer(edm::ParameterSet const ¶ms)
void put(std::unique_ptr< PROD > product)
Put a new product.
void add(std::string const &label, ParameterSetDescription const &psetDescription)
unsigned int maxPdfWeights_
const std::vector< edm::EDGetTokenT< LHEEventProduct > > lheTag_
bool operator<(DTCELinkId const &lhs, DTCELinkId const &rhs)
void streamEndRunSummary(edm::StreamID id, edm::Run const &, edm::EventSetup const &, CounterMap *runCounterMap) const override
void globalEndRunProduce(edm::Run &iRun, edm::EventSetup const &, CounterMap const *runCounterMap) const override
std::vector< uint32_t > preferredPDFLHAIDs_
std::vector< double > & weights()
void produce(edm::StreamID id, edm::Event &iEvent, const edm::EventSetup &iSetup) const override
ParameterDescriptionBase * addOptionalUntracked(U const &iLabel, T const &value)
std::pair< typename Association::data_type::first_type, double > match(Reference key, Association association, bool bestMatchByMaxValue)
Generic matching function.
std::vector< std::string > namedWeightIDs_
const edm::EDGetTokenT< GenLumiInfoHeader > genLumiInfoHeadTag_
Power< A, B >::type pow(const A &a, const B &b)
def merge(dictlist, TELL=False)