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> psWeightIDs;
188 struct LumiCacheInfoHolder {
189 CounterMap countermap;
190 DynamicWeightChoiceGenInfo weightChoice;
193 weightChoice = DynamicWeightChoiceGenInfo();
199 if (match != std::string::npos) {
202 return std::stof(pre) *
std::pow(10.0
f, std::stof(post));
204 return std::stof(str);
208 struct ScaleVarWeight {
210 std::pair<float, float> scales;
212 : wid(id), label(text), scales(stof_fortrancomp(muR), stof_fortrancomp(muF)) {}
213 bool operator<(
const ScaleVarWeight& other) {
214 return (scales == other.scales ? wid < other.wid : scales < other.scales);
217 struct PDFSetWeights {
218 std::vector<std::string> wids;
219 std::pair<unsigned int, unsigned int> lhaIDs;
220 PDFSetWeights(
const std::string& wid,
unsigned int lhaID) : wids(1, wid), lhaIDs(lhaID, lhaID) {}
221 bool operator<(
const PDFSetWeights& other)
const {
return lhaIDs < other.lhaIDs; }
224 lhaIDs.second = lhaID;
226 bool maybe_add(
const std::string& wid,
unsigned int lhaID) {
227 if (lhaID == lhaIDs.second + 1) {
239 edm::RunCache<DynamicWeightChoice>,
240 edm::RunSummaryCache<CounterMap>,
241 edm::EndRunProducer> {
245 lheLabel_(params.getParameter<
std::vector<
edm::InputTag>>(
"lheInfo")),
247 [this](const
edm::InputTag&
tag) {
return mayConsume<LHEEventProduct>(
tag); })),
249 lheLabel_, [
this](
const edm::InputTag&
tag) {
return mayConsume<LHERunInfoProduct, edm::InRun>(
tag); })),
251 mayConsume<GenLumiInfoHeader, edm::InLumi>(params.getParameter<
edm::InputTag>(
"genLumiInfoHeader"))),
252 namedWeightIDs_(params.getParameter<std::vector<std::string>>(
"namedWeightIDs")),
253 namedWeightLabels_(params.getParameter<std::vector<std::string>>(
"namedWeightLabels")),
254 lheWeightPrecision_(params.getParameter<int32_t>(
"lheWeightPrecision")),
255 maxPdfWeights_(params.getParameter<uint32_t>(
"maxPdfWeights")),
256 keepAllPSWeights_(params.getParameter<
bool>(
"keepAllPSWeights")),
257 debug_(params.getUntrackedParameter<
bool>(
"debug",
false)),
258 debugRun_(debug_.load()),
259 hasIssuedWarning_(
false) {
260 produces<nanoaod::FlatTable>();
261 produces<std::string>(
"genModel");
262 produces<nanoaod::FlatTable>(
"LHEScale");
263 produces<nanoaod::FlatTable>(
"LHEPdf");
264 produces<nanoaod::FlatTable>(
"LHEReweighting");
265 produces<nanoaod::FlatTable>(
"LHENamed");
266 produces<nanoaod::FlatTable>(
"PS");
267 produces<nanoaod::MergeableCounterTable, edm::Transition::EndRun>();
268 if (namedWeightIDs_.size() != namedWeightLabels_.size()) {
269 throw cms::Exception(
"Configuration",
"Size mismatch between namedWeightIDs & namedWeightLabels");
273 uint32_t
lhaid = pdfps.getParameter<uint32_t>(
"lhaid");
274 preferredPDFLHAIDs_.push_back(lhaid);
276 lhaNameToID_[name +
".LHgrid"] =
lhaid;
292 auto out = std::make_unique<nanoaod::FlatTable>(1,
"genWeight",
true);
293 out->setDoc(
"generator weight");
297 std::string model_label = streamCache(
id)->countermap.getLabel();
298 auto outM = std::make_unique<std::string>((!model_label.empty()) ?
std::string(
"GenModel_") + model_label :
"");
300 bool getLHEweightsFromGenInfo = !model_label.empty();
303 std::unique_ptr<nanoaod::FlatTable> lheScaleTab, lhePdfTab, lheRwgtTab, lheNamedTab;
304 std::unique_ptr<nanoaod::FlatTable> genPSTab;
307 for (
const auto& lheTag : lheTag_) {
314 if (getLHEweightsFromGenInfo)
316 <<
"Found both a LHEEventProduct and a GenLumiInfoHeader: will only save weights from LHEEventProduct.\n";
318 const DynamicWeightChoice* weightChoice = runCache(iEvent.
getRun().
index());
321 counter, weightChoice, weight, *lheInfo, *genInfo, lheScaleTab, lhePdfTab, lheRwgtTab, lheNamedTab, genPSTab);
322 }
else if (getLHEweightsFromGenInfo) {
323 const DynamicWeightChoiceGenInfo* weightChoice = &(streamCache(
id)->weightChoice);
324 fillLHEPdfWeightTablesFromGenInfo(
325 counter, weightChoice, weight, *genInfo, lheScaleTab, lhePdfTab, lheNamedTab, genPSTab);
326 lheRwgtTab = std::make_unique<nanoaod::FlatTable>(1,
"LHEReweightingWeights",
true);
331 fillOnlyPSWeightTable(counter, weight, *genInfo, genPSTab);
333 lheScaleTab = std::make_unique<nanoaod::FlatTable>(1,
"LHEScaleWeights",
true);
334 lhePdfTab = std::make_unique<nanoaod::FlatTable>(1,
"LHEPdfWeights",
true);
335 lheRwgtTab = std::make_unique<nanoaod::FlatTable>(1,
"LHEReweightingWeights",
true);
336 lheNamedTab = std::make_unique<nanoaod::FlatTable>(1,
"LHENamedWeights",
true);
337 if (!hasIssuedWarning_.exchange(
true)) {
338 edm::LogWarning(
"LHETablesProducer") <<
"No LHEEventProduct, so there will be no LHE Tables\n";
350 const DynamicWeightChoice* weightChoice,
354 std::unique_ptr<nanoaod::FlatTable>& outScale,
355 std::unique_ptr<nanoaod::FlatTable>& outPdf,
356 std::unique_ptr<nanoaod::FlatTable>& outRwgt,
357 std::unique_ptr<nanoaod::FlatTable>& outNamed,
358 std::unique_ptr<nanoaod::FlatTable>& outPS)
const {
359 bool lheDebug = debug_.exchange(
362 const std::vector<std::string>& scaleWeightIDs = weightChoice->scaleWeightIDs;
363 const std::vector<std::string>& pdfWeightIDs = weightChoice->pdfWeightIDs;
364 const std::vector<std::string>& rwgtWeightIDs = weightChoice->rwgtIDs;
368 std::vector<double> wScale(scaleWeightIDs.size(), 1), wPDF(pdfWeightIDs.size(), 1), wRwgt(rwgtWeightIDs.size(), 1),
369 wNamed(namedWeightIDs_.size(), 1);
372 printf(
"Weight %+9.5f rel %+9.5f for id %s\n",
weight.wgt,
weight.wgt / w0,
weight.id.c_str());
374 auto mScale =
std::find(scaleWeightIDs.begin(), scaleWeightIDs.end(),
weight.id);
375 if (mScale != scaleWeightIDs.end())
376 wScale[mScale - scaleWeightIDs.begin()] =
weight.wgt / w0;
378 auto mPDF =
std::find(pdfWeightIDs.begin(), pdfWeightIDs.end(),
weight.id);
379 if (mPDF != pdfWeightIDs.end())
380 wPDF[mPDF - pdfWeightIDs.begin()] =
weight.wgt / w0;
382 auto mRwgt =
std::find(rwgtWeightIDs.begin(), rwgtWeightIDs.end(),
weight.id);
383 if (mRwgt != rwgtWeightIDs.end())
384 wRwgt[mRwgt - rwgtWeightIDs.begin()] =
weight.wgt / w0;
386 auto mNamed =
std::find(namedWeightIDs_.begin(), namedWeightIDs_.end(),
weight.id);
387 if (mNamed != namedWeightIDs_.end())
388 wNamed[mNamed - namedWeightIDs_.begin()] =
weight.wgt / w0;
391 std::size_t vectorSize =
393 ? (keepAllPSWeights_ ? (genProd.
weights().size() - 2)
394 : ((genProd.
weights().size() == 14 || genProd.
weights().size() == 46) ? 4 : 1))
396 std::vector<double> wPS(vectorSize, 1);
398 if (vectorSize > 1) {
399 double nominal = genProd.
weights()[1];
400 if (keepAllPSWeights_) {
401 for (std::size_t
i = 0;
i < vectorSize;
i++) {
402 wPS[
i] = (genProd.
weights()[
i + 2]) / nominal;
404 psWeightDocStr =
"All PS weights (w_var / w_nominal)";
406 for (std::size_t
i = 6;
i < 10;
i++) {
407 wPS[
i - 6] = (genProd.
weights()[
i]) / nominal;
410 "PS weights (w_var / w_nominal); [0] is ISR=0.5 FSR=1; [1] is ISR=1 " 411 "FSR=0.5; [2] is ISR=2 FSR=1; [3] is ISR=1 FSR=2 ";
414 psWeightDocStr =
"dummy PS weight (1.0) ";
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;
457 const std::vector<unsigned int>& psWeightIDs = weightChoice->psWeightIDs;
461 double originalXWGTUP = (
weights.size() > 1) ?
weights.at(1) : 1.;
463 std::vector<double> wScale, wPDF, wPS;
464 for (
auto id : scaleWeightIDs)
465 wScale.push_back(
weights.at(
id) / w0);
466 for (
auto id : pdfWeightIDs) {
467 wPDF.push_back(
weights.at(
id) / w0);
469 if (!psWeightIDs.empty()) {
472 for (std::size_t
i = 1;
i < psWeightIDs.size();
i++)
473 wPS.push_back(
weights.at(psWeightIDs.at(
i)) / psNom);
477 if (keepAllPSWeights_) {
478 psWeightDocStr =
"All PS weights (w_var / w_nominal)";
481 "PS weights (w_var / w_nominal); [0] is ISR=0.5 FSR=1; [1] is ISR=1 " 482 "FSR=0.5; [2] is ISR=2 FSR=1; [3] is ISR=1 FSR=2 ";
485 outScale = std::make_unique<nanoaod::FlatTable>(wScale.size(),
"LHEScaleWeight",
false);
486 outScale->addColumn<
float>(
489 outPdf = std::make_unique<nanoaod::FlatTable>(wPDF.size(),
"LHEPdfWeight",
false);
490 outPdf->addColumn<
float>(
493 outPS = std::make_unique<nanoaod::FlatTable>(wPS.size(),
"PSWeight",
false);
494 outPS->addColumn<
float>(
"",
496 wPS.size() > 1 ? psWeightDocStr :
"dummy PS weight (1.0) ",
498 lheWeightPrecision_);
500 outNamed = std::make_unique<nanoaod::FlatTable>(1,
"LHEWeight",
true);
501 outNamed->addColumnValue<
float>(
507 counter->incLHE(genWeight, wScale, wPDF, std::vector<double>(), std::vector<double>(), wPS);
513 std::unique_ptr<nanoaod::FlatTable>& outPS)
const {
514 std::size_t vectorSize =
516 ? (keepAllPSWeights_ ? (genProd.
weights().size() - 2)
517 : ((genProd.
weights().size() == 14 || genProd.
weights().size() == 46) ? 4 : 1))
519 std::vector<double> wPS(vectorSize, 1);
521 if (vectorSize > 1) {
522 double nominal = genProd.
weights()[1];
523 if (keepAllPSWeights_) {
524 for (std::size_t
i = 0;
i < vectorSize;
i++) {
525 wPS[
i] = (genProd.
weights()[
i + 2]) / nominal;
527 psWeightDocStr =
"All PS weights (w_var / w_nominal)";
529 for (std::size_t
i = 6;
i < 10;
i++) {
530 wPS[
i - 6] = (genProd.
weights()[
i]) / nominal;
533 "PS weights (w_var / w_nominal); [0] is ISR=0.5 FSR=1; [1] is ISR=1 " 534 "FSR=0.5; [2] is ISR=2 FSR=1; [3] is ISR=1 FSR=2 ";
537 psWeightDocStr =
"dummy PS weight (1.0) ";
539 outPS = std::make_unique<nanoaod::FlatTable>(wPS.size(),
"PSWeight",
false);
542 counter->incGenOnly(genWeight);
543 counter->incPSOnly(genWeight, wPS);
550 bool lheDebug = debugRun_.exchange(
552 auto weightChoice = std::make_shared<DynamicWeightChoice>();
556 for (
const auto& lheLabel : lheLabel_) {
563 std::vector<ScaleVarWeight> scaleVariationIDs;
564 std::vector<PDFSetWeights> pdfSetWeightIDs;
565 std::vector<std::string> lheReweighingIDs;
567 std::regex weightgroupmg26x(
"<weightgroup\\s+(?:name|type)=\"(.*)\"\\s+combine=\"(.*)\"\\s*>");
568 std::regex weightgroup(
"<weightgroup\\s+combine=\"(.*)\"\\s+(?:name|type)=\"(.*)\"\\s*>");
569 std::regex weightgroupRwgt(
"<weightgroup\\s+(?:name|type)=\"(.*)\"\\s*>");
570 std::regex endweightgroup(
"</weightgroup>");
571 std::regex scalewmg26x(
572 "<weight\\s+(?:.*\\s+)?id=\"(\\d+)\"\\s*(?:lhapdf=\\d+|dyn=\\s*-?\\d+)?\\s*((?:[mM][uU][rR]|renscfact)=\"(" 573 "\\S+)\"\\s+(?:[mM][uU][Ff]|facscfact)=\"(\\S+)\")(\\s+.*)?</weight>");
575 "<weight\\s+(?:.*\\s+)?id=\"(\\d+)\">\\s*(?:lhapdf=\\d+|dyn=\\s*-?\\d+)?\\s*((?:mu[rR]|renscfact)=(\\S+)\\s+(" 576 "?:mu[Ff]|facscfact)=(\\S+)(\\s+.*)?)</weight>");
578 "<weight\\s+id=\"(\\d+)\">\\s*(?:PDF set|lhapdf|PDF|pdfset)\\s*=\\s*(\\d+)\\s*(?:\\s.*)?</weight>");
579 std::regex pdfwOld(
"<weight\\s+(?:.*\\s+)?id=\"(\\d+)\">\\s*Member \\s*(\\d+)\\s*(?:.*)</weight>");
580 std::regex pdfwmg26x(
581 "<weight\\s+id=\"(\\d+)\"\\s*MUR=\"(?:\\S+)\"\\s*MUF=\"(?:\\S+)\"\\s*(?:PDF " 582 "set|lhapdf|PDF|pdfset)\\s*=\\s*\"(\\d+)\"\\s*>\\s*(?:PDF=(\\d+)\\s*MemberID=(\\d+))?\\s*(?:\\s.*)?</" 584 std::regex rwgt(
"<weight\\s+id=\"(.+)\">(.+)?(</weight>)?");
587 if (iter->tag() !=
"initrwgt") {
589 std::cout <<
"Skipping LHE header with tag" << iter->tag() << std::endl;
593 std::cout <<
"Found LHE header with tag" << iter->tag() << std::endl;
594 std::vector<std::string>
lines = iter->lines();
595 bool missed_weightgroup =
597 bool ismg26x =
false;
598 for (
unsigned int iLine = 0, nLines = lines.size(); iLine < nLines;
600 boost::replace_all(lines[iLine],
"<",
"<");
601 boost::replace_all(lines[iLine],
">",
">");
602 if (std::regex_search(lines[iLine], groups, weightgroupmg26x)) {
606 for (
unsigned int iLine = 0, nLines = lines.size(); iLine < nLines; ++iLine) {
609 if (std::regex_search(lines[iLine], groups, ismg26x ? weightgroupmg26x : weightgroup)) {
612 groupname = groups.str(1);
614 std::cout <<
">>> Looks like the beginning of a weight group for '" << groupname <<
"'" << std::endl;
615 if (groupname.find(
"scale_variation") == 0 || groupname ==
"Central scale variation") {
617 std::cout <<
">>> Looks like scale variation for theory uncertainties" << std::endl;
618 for (++iLine; iLine < nLines; ++iLine) {
621 if (std::regex_search(lines[iLine], groups, ismg26x ? scalewmg26x : scalew)) {
623 std::cout <<
" >>> Scale weight " << groups[1].str() <<
" for " << groups[3].str() <<
" , " 624 << groups[4].str() <<
" , " << groups[5].str() << std::endl;
625 scaleVariationIDs.emplace_back(groups.str(1), groups.str(2), groups.str(3), groups.str(4));
626 }
else if (std::regex_search(lines[iLine], endweightgroup)) {
628 std::cout <<
">>> Looks like the end of a weight group" << std::endl;
629 if (!missed_weightgroup) {
632 missed_weightgroup =
false;
633 }
else if (std::regex_search(lines[iLine], ismg26x ? weightgroupmg26x : weightgroup)) {
635 std::cout <<
">>> Looks like the beginning of a new weight group, I will assume I missed the end " 639 missed_weightgroup =
true;
644 }
else if (groupname ==
"PDF_variation" || groupname.find(
"PDF_variation ") == 0) {
646 std::cout <<
">>> Looks like a new-style block of PDF weights for one or more pdfs" << std::endl;
647 for (++iLine; iLine < nLines; ++iLine) {
650 if (std::regex_search(lines[iLine], groups, pdfw)) {
651 unsigned int lhaID = std::stoi(groups.str(2));
653 std::cout <<
" >>> PDF weight " << groups.str(1) <<
" for " << groups.str(2) <<
" = " << lhaID
655 if (pdfSetWeightIDs.empty() || !pdfSetWeightIDs.back().maybe_add(groups.str(1), lhaID)) {
656 pdfSetWeightIDs.emplace_back(groups.str(1), lhaID);
658 }
else if (std::regex_search(lines[iLine], endweightgroup)) {
660 std::cout <<
">>> Looks like the end of a weight group" << std::endl;
661 if (!missed_weightgroup) {
664 missed_weightgroup =
false;
665 }
else if (std::regex_search(lines[iLine], ismg26x ? weightgroupmg26x : weightgroup)) {
667 std::cout <<
">>> Looks like the beginning of a new weight group, I will assume I missed the end " 671 missed_weightgroup =
true;
676 }
else if (groupname ==
"PDF_variation1" || groupname ==
"PDF_variation2") {
678 std::cout <<
">>> Looks like a new-style block of PDF weights for multiple pdfs" << std::endl;
679 unsigned int lastid = 0;
680 for (++iLine; iLine < nLines; ++iLine) {
683 if (std::regex_search(lines[iLine], groups, pdfw)) {
684 unsigned int id = std::stoi(groups.str(1));
685 unsigned int lhaID = std::stoi(groups.str(2));
687 std::cout <<
" >>> PDF weight " << groups.str(1) <<
" for " << groups.str(2) <<
" = " << lhaID
689 if (
id != (lastid + 1) || pdfSetWeightIDs.empty()) {
690 pdfSetWeightIDs.emplace_back(groups.str(1), lhaID);
692 pdfSetWeightIDs.back().add(groups.str(1), lhaID);
695 }
else if (std::regex_search(lines[iLine], endweightgroup)) {
697 std::cout <<
">>> Looks like the end of a weight group" << std::endl;
698 if (!missed_weightgroup) {
701 missed_weightgroup =
false;
702 }
else if (std::regex_search(lines[iLine], ismg26x ? weightgroupmg26x : weightgroup)) {
704 std::cout <<
">>> Looks like the beginning of a new weight group, I will assume I missed the end " 708 missed_weightgroup =
true;
713 }
else if (lhaNameToID_.find(groupname) != lhaNameToID_.end()) {
715 std::cout <<
">>> Looks like an old-style PDF weight for an individual pdf" << std::endl;
716 unsigned int firstLhaID = lhaNameToID_.find(groupname)->second;
718 for (++iLine; iLine < nLines; ++iLine) {
721 if (std::regex_search(lines[iLine], groups, ismg26x ? pdfwmg26x : pdfwOld)) {
722 unsigned int member = 0;
724 member = std::stoi(groups.str(2));
726 if (!groups.str(4).empty()) {
727 member = std::stoi(groups.str(4));
730 unsigned int lhaID = member + firstLhaID;
732 std::cout <<
" >>> PDF weight " << groups.str(1) <<
" for " << member <<
" = " << lhaID
736 pdfSetWeightIDs.emplace_back(groups.str(1), lhaID);
739 pdfSetWeightIDs.back().add(groups.str(1), lhaID);
741 }
else if (std::regex_search(lines[iLine], endweightgroup)) {
743 std::cout <<
">>> Looks like the end of a weight group" << std::endl;
744 if (!missed_weightgroup) {
747 missed_weightgroup =
false;
748 }
else if (std::regex_search(lines[iLine], ismg26x ? weightgroupmg26x : weightgroup)) {
750 std::cout <<
">>> Looks like the beginning of a new weight group, I will assume I missed the end " 754 missed_weightgroup =
true;
760 for (++iLine; iLine < nLines; ++iLine) {
763 if (std::regex_search(lines[iLine], groups, endweightgroup)) {
765 std::cout <<
">>> Looks like the end of a weight group" << std::endl;
766 if (!missed_weightgroup) {
769 missed_weightgroup =
false;
770 }
else if (std::regex_search(lines[iLine], ismg26x ? weightgroupmg26x : weightgroup)) {
772 std::cout <<
">>> Looks like the beginning of a new weight group, I will assume I missed the end " 776 missed_weightgroup =
true;
782 }
else if (std::regex_search(lines[iLine], groups, weightgroupRwgt)) {
784 if (groupname ==
"mg_reweighting") {
786 std::cout <<
">>> Looks like a LHE weights for reweighting" << std::endl;
787 for (++iLine; iLine < nLines; ++iLine) {
790 if (std::regex_search(lines[iLine], groups, rwgt)) {
793 std::cout <<
" >>> LHE reweighting weight: " << rwgtID << std::endl;
794 if (
std::find(lheReweighingIDs.begin(), lheReweighingIDs.end(), rwgtID) == lheReweighingIDs.end()) {
796 lheReweighingIDs.emplace_back(rwgtID);
798 }
else if (std::regex_search(lines[iLine], endweightgroup)) {
800 std::cout <<
">>> Looks like the end of a weight group" << std::endl;
801 if (!missed_weightgroup) {
804 missed_weightgroup =
false;
805 }
else if (std::regex_search(lines[iLine], ismg26x ? weightgroupmg26x : weightgroup)) {
807 std::cout <<
">>> Looks like the beginning of a new weight group, I will assume I missed the end " 811 missed_weightgroup =
true;
822 std::sort(scaleVariationIDs.begin(), scaleVariationIDs.end());
824 std::cout <<
"Found " << scaleVariationIDs.size() <<
" scale variations: " << std::endl;
825 std::stringstream scaleDoc;
826 scaleDoc <<
"LHE scale variation weights (w_var / w_nominal); ";
827 for (
unsigned int isw = 0, nsw = scaleVariationIDs.size(); isw < nsw; ++isw) {
828 const auto& sw = scaleVariationIDs[isw];
831 scaleDoc <<
"[" << isw <<
"] is " << sw.label;
832 weightChoice->scaleWeightIDs.push_back(sw.wid);
834 printf(
" id %s: scales ren = % .2f fact = % .2f text = %s\n",
840 if (!scaleVariationIDs.empty())
841 weightChoice->scaleWeightsDoc = scaleDoc.str();
845 std::cout <<
"Found " << pdfSetWeightIDs.size() <<
" PDF set errors: " << std::endl;
846 for (
const auto& pw : pdfSetWeightIDs)
847 printf(
"lhaIDs %6d - %6d (%3lu weights: %s, ... )\n",
851 pw.wids.front().c_str());
856 std::cout <<
"Found " << lheReweighingIDs.size() <<
" reweighting weights" << std::endl;
858 std::copy(lheReweighingIDs.begin(), lheReweighingIDs.end(), std::back_inserter(weightChoice->rwgtIDs));
860 std::stringstream pdfDoc;
861 pdfDoc <<
"LHE pdf variation weights (w_var / w_nominal) for LHA IDs ";
863 for (uint32_t
lhaid : preferredPDFLHAIDs_) {
864 for (
const auto& pw : pdfSetWeightIDs) {
865 if (pw.lhaIDs.first !=
lhaid && pw.lhaIDs.first != (
lhaid + 1))
867 if (pw.wids.size() == 1)
869 pdfDoc << pw.lhaIDs.first <<
" - " << pw.lhaIDs.second;
870 weightChoice->pdfWeightIDs = pw.wids;
871 if (maxPdfWeights_ < pw.wids.size()) {
872 weightChoice->pdfWeightIDs.resize(maxPdfWeights_);
873 pdfDoc <<
", truncated to the first " << maxPdfWeights_ <<
" replicas";
875 weightChoice->pdfWeightsDoc = pdfDoc.str();
889 return std::make_unique<LumiCacheInfoHolder>();
893 streamCache(
id)->clear();
898 auto counterMap = &(streamCache(
id)->countermap);
900 lumiBlock.
getByToken(genLumiInfoHeadTag_, genLumiInfoHead);
901 if (!genLumiInfoHead.
isValid())
903 <<
"No GenLumiInfoHeader product found, will not fill generator model string.\n";
905 if (genLumiInfoHead.
isValid()) {
907 boost::replace_all(label,
"-",
"_");
908 boost::replace_all(label,
"/",
"_");
910 counterMap->setLabel(label);
912 if (genLumiInfoHead.
isValid()) {
913 auto weightChoice = &(streamCache(
id)->weightChoice);
915 std::vector<ScaleVarWeight> scaleVariationIDs;
916 std::vector<PDFSetWeights> pdfSetWeightIDs;
917 weightChoice->psWeightIDs.clear();
919 std::regex scalew(
"LHE,\\s+id\\s+=\\s+(\\d+),\\s+(.+)\\,\\s+mur=(\\S+)\\smuf=(\\S+)");
920 std::regex pdfw(
"LHE,\\s+id\\s+=\\s+(\\d+),\\s+(.+),\\s+Member\\s+(\\d+)\\s+of\\ssets\\s+(\\w+\\b)");
923 std::unordered_map<std::string, uint32_t> knownPDFSetsFromGenInfo_;
924 unsigned int weightIter = 0;
925 for (
const auto&
line : weightNames) {
926 if (std::regex_search(
line, groups, scalew)) {
927 auto id = groups.str(1);
928 auto group = groups.str(2);
929 auto mur = groups.str(3);
930 auto muf = groups.str(4);
931 if (
group.find(
"Central scale variation") != std::string::npos)
932 scaleVariationIDs.emplace_back(groups.str(1), groups.str(2), groups.str(3), groups.str(4));
933 }
else if (std::regex_search(
line, groups, pdfw)) {
934 auto id = groups.str(1);
935 auto group = groups.str(2);
936 auto memberid = groups.str(3);
937 auto pdfset = groups.str(4);
938 if (
group.find(pdfset) != std::string::npos) {
939 if (knownPDFSetsFromGenInfo_.find(pdfset) == knownPDFSetsFromGenInfo_.end()) {
940 knownPDFSetsFromGenInfo_[pdfset] = std::atoi(
id.c_str());
941 pdfSetWeightIDs.emplace_back(
id, std::atoi(
id.c_str()));
943 pdfSetWeightIDs.back().add(
id, std::atoi(
id.c_str()));
945 }
else if (
line.find(
"Baseline") != std::string::npos ||
line.find(
"isr") != std::string::npos ||
946 line.find(
"fsr") != std::string::npos) {
947 if (keepAllPSWeights_ ||
line.find(
"Baseline") != std::string::npos ||
948 line.find(
"Def") != std::string::npos) {
949 weightChoice->psWeightIDs.push_back(weightIter);
955 weightChoice->scaleWeightIDs.clear();
956 weightChoice->pdfWeightIDs.clear();
958 std::sort(scaleVariationIDs.begin(), scaleVariationIDs.end());
959 std::stringstream scaleDoc;
960 scaleDoc <<
"LHE scale variation weights (w_var / w_nominal); ";
961 for (
unsigned int isw = 0, nsw = scaleVariationIDs.size(); isw < nsw; ++isw) {
962 const auto& sw = scaleVariationIDs[isw];
965 scaleDoc <<
"[" << isw <<
"] is " << sw.label;
966 weightChoice->scaleWeightIDs.push_back(std::atoi(sw.wid.c_str()));
968 if (!scaleVariationIDs.empty())
969 weightChoice->scaleWeightsDoc = scaleDoc.str();
970 std::stringstream pdfDoc;
971 pdfDoc <<
"LHE pdf variation weights (w_var / w_nominal) for LHA names ";
973 for (
const auto& pw : pdfSetWeightIDs) {
974 if (pw.wids.size() == 1)
976 for (
const auto& wantedpdf : lhaNameToID_) {
977 auto pdfname = wantedpdf.first;
978 if (knownPDFSetsFromGenInfo_.find(pdfname) == knownPDFSetsFromGenInfo_.end())
980 uint32_t
lhaid = knownPDFSetsFromGenInfo_.at(pdfname);
981 if (pw.lhaIDs.first != lhaid)
984 for (
const auto&
x : pw.wids)
985 weightChoice->pdfWeightIDs.push_back(std::atoi(
x.c_str()));
986 if (maxPdfWeights_ < pw.wids.size()) {
987 weightChoice->pdfWeightIDs.resize(maxPdfWeights_);
988 pdfDoc <<
", truncated to the first " << maxPdfWeights_ <<
" replicas";
990 weightChoice->pdfWeightsDoc = pdfDoc.str();
1001 return std::make_shared<CounterMap>();
1007 CounterMap* runCounterMap)
const override {
1008 runCounterMap->merge(streamCache(
id)->countermap);
1014 auto out = std::make_unique<nanoaod::MergeableCounterTable>();
1016 for (
const auto&
x : runCounterMap->countermap) {
1017 auto runCounter = &(
x.second);
1021 out->addInt(
"genEventCount" + label,
"event count" + doclabel, runCounter->num);
1022 out->addFloat(
"genEventSumw" + label,
"sum of gen weights" + doclabel, runCounter->sumw);
1023 out->addFloat(
"genEventSumw2" + label,
"sum of gen (weight^2)" + doclabel, runCounter->sumw2);
1025 double norm = runCounter->sumw ? 1.0 / runCounter->sumw : 1;
1026 auto sumScales = runCounter->sumScale;
1027 for (
auto&
val : sumScales)
1029 out->addVFloatWithNorm(
"LHEScaleSumw" + label,
1030 "Sum of genEventWeight * LHEScaleWeight[i], divided by genEventSumw" + doclabel,
1033 auto sumPDFs = runCounter->sumPDF;
1034 for (
auto&
val : sumPDFs)
1036 out->addVFloatWithNorm(
"LHEPdfSumw" + label,
1037 "Sum of genEventWeight * LHEPdfWeight[i], divided by genEventSumw" + doclabel,
1040 if (!runCounter->sumRwgt.empty()) {
1041 auto sumRwgts = runCounter->sumRwgt;
1042 for (
auto&
val : sumRwgts)
1044 out->addVFloatWithNorm(
"LHEReweightingSumw" + label,
1045 "Sum of genEventWeight * LHEReweightingWeight[i], divided by genEventSumw" + doclabel,
1049 if (!runCounter->sumNamed.empty()) {
1050 for (
unsigned int i = 0, n = namedWeightLabels_.size();
i <
n; ++
i) {
1051 out->addFloatWithNorm(
1052 "LHESumw_" + namedWeightLabels_[
i] + label,
1053 "Sum of genEventWeight * LHEWeight_" + namedWeightLabels_[
i] +
", divided by genEventSumw" + doclabel,
1054 runCounter->sumNamed[
i] * norm,
1067 ->setComment(
"tag for the GenEventInfoProduct, to get the main weight");
1069 ->setComment(
"tag for the GenLumiInfoProduct, to get the model string");
1070 desc.
add<std::vector<edm::InputTag>>(
"lheInfo", std::vector<edm::InputTag>{{
"externalLHEProducer"}, {
"source"}})
1071 ->setComment(
"tag(s) for the LHE information (LHEEventProduct and LHERunInfoProduct)");
1075 prefpdf.
add<uint32_t>(
"lhaid");
1076 desc.
addVPSet(
"preferredPDFs", prefpdf, std::vector<edm::ParameterSet>())
1078 "LHA PDF Ids of the preferred PDF sets, in order of preference (the first matching one will be used)");
1079 desc.
add<std::vector<std::string>>(
"namedWeightIDs")->setComment(
"set of LHA weight IDs for named LHE weights");
1080 desc.
add<std::vector<std::string>>(
"namedWeightLabels")
1081 ->setComment(
"output names for the namedWeightIDs (in the same order)");
1082 desc.
add<int32_t>(
"lheWeightPrecision")->setComment(
"Number of bits in the mantissa for LHE weights");
1083 desc.
add<uint32_t>(
"maxPdfWeights")->setComment(
"Maximum number of PDF weights to save (to crop NN replicas)");
1084 desc.
add<
bool>(
"keepAllPSWeights")->setComment(
"Store all PS weights found");
1085 desc.
addOptionalUntracked<
bool>(
"debug")->setComment(
"dump out all LHE information for one event");
1086 descriptions.
add(
"genWeightsTable", desc);
1092 const std::vector<edm::EDGetTokenT<LHEEventProduct>>
lheTag_;
1093 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)
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
#define DEFINE_FWK_MODULE(type)
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::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)
void fillLHEWeightTables(Counter *counter, const DynamicWeightChoice *weightChoice, 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
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
bool operator<(const FedChannelConnection &, const FedChannelConnection &)
headers_const_iterator headers_begin() const
void clear(CLHEP::HepGenMatrix &m)
Helper function: Reset all elements of a matrix to 0.
void fillOnlyPSWeightTable(Counter *counter, double genWeight, const GenEventInfoProduct &genProd, std::unique_ptr< nanoaod::FlatTable > &outPS) const
ParameterDescriptionBase * add(U const &iLabel, T const &value)
void add(std::map< std::string, TH1 * > &h, TH1 *hist)
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_
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)