Skip to content

Commit

Permalink
Merge pull request cms-sw#9 from kdlong/WmassNanoProd_106X_genweights
Browse files Browse the repository at this point in the history
Big commit to restructure nano weights
  • Loading branch information
kdlong authored Nov 16, 2021
2 parents 64a27aa + 02019a8 commit b9b7820
Show file tree
Hide file tree
Showing 44 changed files with 3,167 additions and 1,560 deletions.
4 changes: 4 additions & 0 deletions DataFormats/NanoAOD/src/classes_def.xml
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<lcgdict>
<class name="nanoaod::FlatTable::Column" ClassVersion="3">
<version ClassVersion="3" checksum="3066258528"/>
Expand All @@ -9,6 +10,9 @@
<class name="nanoaod::FlatTable::RowView" transient="true" />
<class name="edm::Wrapper<nanoaod::FlatTable>" />

<class name="std::vector<nanoaod::FlatTable>" />
<class name="edm::Wrapper<std::vector<nanoaod::FlatTable>>" />

<class name="nanoaod::MergeableCounterTable::FloatColumn" ClassVersion="3">
<version ClassVersion="3" checksum="828208870"/>
</class>
Expand Down
1 change: 1 addition & 0 deletions GeneratorInterface/Core/BuildFile.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
<use name="lhapdf"/>
<use name="f77compiler"/>
<use name="root"/>
<use name="tinyxml2"/>
<export>
<lib name="1"/>
</export>
26 changes: 26 additions & 0 deletions GeneratorInterface/Core/interface/GenWeightHelper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
#ifndef GeneratorInterface_Core_GenWeightHelper_h
#define GeneratorInterface_Core_GenWeightHelper_h

#include <string>
#include <vector>
#include <map>
#include <regex>
#include <fstream>

#include "SimDataFormats/GeneratorProducts/interface/PdfWeightGroupInfo.h"
#include "SimDataFormats/GeneratorProducts/interface/ScaleWeightGroupInfo.h"
#include "SimDataFormats/GeneratorProducts/interface/PartonShowerWeightGroupInfo.h"
#include "SimDataFormats/GeneratorProducts/interface/GenLumiInfoProduct.h"
#include "GeneratorInterface/Core/interface/WeightHelper.h"

#include <tinyxml2.h>

namespace gen {
class GenWeightHelper : public WeightHelper {
public:
GenWeightHelper();
void parseWeightGroupsFromNames(std::vector<std::string> weightNames);
};
} // namespace gen

#endif
45 changes: 45 additions & 0 deletions GeneratorInterface/Core/interface/LHEWeightHelper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
#ifndef GeneratorInterface_Core_LHEWeightHelper_h
#define GeneratorInterface_Core_LHEWeightHelper_h

#include <string>
#include <vector>
#include <map>
#include <regex>
#include <fstream>

#include "SimDataFormats/GeneratorProducts/interface/UnknownWeightGroupInfo.h"
#include "SimDataFormats/GeneratorProducts/interface/MEParamWeightGroupInfo.h"
#include "SimDataFormats/GeneratorProducts/interface/PdfWeightGroupInfo.h"
#include "SimDataFormats/GeneratorProducts/interface/ScaleWeightGroupInfo.h"
#include "SimDataFormats/GeneratorProducts/interface/LHERunInfoProduct.h"
#include "GeneratorInterface/Core/interface/WeightHelper.h"

#include <tinyxml2.h>

namespace gen {
class LHEWeightHelper : public WeightHelper {
public:
LHEWeightHelper() : WeightHelper(){};

enum ErrorType { SWAPHEADER, HTMLSTYLE, TRAILINGSTR, UNKNOWN };

void setHeaderLines(std::vector<std::string> headerLines);
void parseWeights();
bool isConsistent();
void swapHeaders();
void setFailIfInvalidXML(bool value) { failIfInvalidXML_ = value; }

private:
std::vector<std::string> headerLines_;
std::string weightgroupKet_ = "</weightgroup>";
bool failIfInvalidXML_ = false;
std::string parseGroupName(tinyxml2::XMLElement* el);
void addGroup(tinyxml2::XMLElement* inner, std::string groupName, int groupIndex, int& weightIndex);
bool parseLHE(tinyxml2::XMLDocument& xmlDoc);
tinyxml2::XMLError tryReplaceHtmlStyle(tinyxml2::XMLDocument& xmlDoc, std::string& fullHeader);
tinyxml2::XMLError tryRemoveTrailings(tinyxml2::XMLDocument& xmlDoc, std::string& fullHeader);
ErrorType findErrorType(std::string& fullHeader);
};
} // namespace gen

#endif
118 changes: 118 additions & 0 deletions GeneratorInterface/Core/interface/WeightHelper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
#ifndef GeneratorInterface_LHEInterface_WeightHelper_h
#define GeneratorInterface_LHEInterface_WeightHelper_h

#include "DataFormats/Common/interface/OwnVector.h"
#include "SimDataFormats/GeneratorProducts/interface/GenWeightProduct.h"
#include "SimDataFormats/GeneratorProducts/interface/WeightGroupInfo.h"
#include "SimDataFormats/GeneratorProducts/interface/PdfWeightGroupInfo.h"
#include "SimDataFormats/GeneratorProducts/interface/WeightsInfo.h"
#include "SimDataFormats/GeneratorProducts/interface/UnknownWeightGroupInfo.h"
#include "SimDataFormats/GeneratorProducts/interface/PdfWeightGroupInfo.h"
#include "SimDataFormats/GeneratorProducts/interface/PartonShowerWeightGroupInfo.h"
#include "SimDataFormats/GeneratorProducts/interface/ScaleWeightGroupInfo.h"
#include "SimDataFormats/GeneratorProducts/interface/MEParamWeightGroupInfo.h"
#include "LHAPDF/LHAPDF.h"
#include <boost/algorithm/string.hpp>
#include <bits/stdc++.h>
#include <fstream>

namespace gen {
struct ParsedWeight {
std::string id;
int index;
std::string groupname;
std::string content;
std::unordered_map<std::string, std::string> attributes;
int wgtGroup_idx;
};

class WeightHelper {
public:
WeightHelper();
edm::OwnVector<gen::WeightGroupInfo> weightGroups() { return weightGroups_; }

template <typename T>
std::unique_ptr<GenWeightProduct> weightProduct(std::vector<T> weights, float w0);

void setModel(std::string model) { model_ = model; }
void setGuessPSWeightIdx(bool guessPSWeightIdx) {
PartonShowerWeightGroupInfo::setGuessPSWeightIdx(guessPSWeightIdx);
}
void addUnassociatedGroup() {
weightGroups_.push_back(std::make_unique<UnknownWeightGroupInfo>("unassociated"));
weightGroups_.back().setDescription("Weights with missing or invalid header meta data");
}
int addWeightToProduct(
std::unique_ptr<GenWeightProduct>& product, double weight, std::string name, int weightNum, int groupIndex);
int findContainingWeightGroup(std::string wgtId, int weightIndex, int previousGroupIndex);
void setDebug(bool value) { debug_ = value; }

protected:
// TODO: Make this only print from one thread a la
// https://github.com/kdlong/cmssw/blob/master/PhysicsTools/NanoAOD/plugins/GenWeightsTableProducer.cc#L1069
bool debug_ = false;
const unsigned int FIRST_PSWEIGHT_ENTRY = 2;
const unsigned int DEFAULT_PSWEIGHT_LENGTH = 46;
std::string model_;
std::vector<ParsedWeight> parsedWeights_;
std::map<std::string, std::string> currWeightAttributeMap_;
std::map<std::string, std::string> currGroupAttributeMap_;
edm::OwnVector<gen::WeightGroupInfo> weightGroups_;
bool isScaleWeightGroup(const ParsedWeight& weight);
bool isMEParamWeightGroup(const ParsedWeight& weight);
bool isPdfWeightGroup(const ParsedWeight& weight);
bool isPartonShowerWeightGroup(const ParsedWeight& weight);
bool isOrphanPdfWeightGroup(ParsedWeight& weight);
void updateScaleInfo(gen::ScaleWeightGroupInfo& scaleGroup, const ParsedWeight& weight);
void updateMEParamInfo(const ParsedWeight& weight, int index);
void updatePdfInfo(gen::PdfWeightGroupInfo& pdfGroup, const ParsedWeight& weight);
void updatePartonShowerInfo(gen::PartonShowerWeightGroupInfo& psGroup, const ParsedWeight& weight);
void cleanupOrphanCentralWeight();
bool splitPdfWeight(ParsedWeight& weight);

int lhapdfId(const ParsedWeight& weight, gen::PdfWeightGroupInfo& pdfGroup);
std::string searchAttributes(const std::string& label, const ParsedWeight& weight) const;
std::string searchAttributesByTag(const std::string& label, const ParsedWeight& weight) const;
std::string searchAttributesByRegex(const std::string& label, const ParsedWeight& weight) const;

// Possible names for the same thing
const std::unordered_map<std::string, std::vector<std::string>> attributeNames_ = {
{"muf", {"muF", "MUF", "muf", "facscfact"}},
{"mur", {"muR", "MUR", "mur", "renscfact"}},
{"pdf", {"PDF", "PDF set", "lhapdf", "pdf", "pdf set", "pdfset"}},
{"dyn", {"DYN_SCALE"}},
{"dyn_name", {"dyn_scale_choice"}},
{"up", {"_up", "Hi"}},
{"down", {"_dn", "Lo"}},
{"me_variation", {"mass", "sthw2", "width"}},
};
void printWeights();
std::unique_ptr<WeightGroupInfo> buildGroup(ParsedWeight& weight);
void buildGroups();
std::string searchString(const std::string& label, const std::string& name);
};

// Templated function (needed here because of plugins)
template <typename T>
std::unique_ptr<GenWeightProduct> WeightHelper::weightProduct(std::vector<T> weights, float w0) {
auto weightProduct = std::make_unique<GenWeightProduct>(w0);
weightProduct->setNumWeightSets(weightGroups_.size());
int weightGroupIndex = 0;
int i = 0;
// This happens if there are no PS weights, so the weights vector contains only the central GEN weight.
// Just add an empty product (need for all cases or...?)
if (weights.size() > 1) {
for (const auto& weight : weights) {
if constexpr (std::is_same<T, gen::WeightsInfo>::value) {
weightGroupIndex = addWeightToProduct(weightProduct, weight.wgt, weight.id, i, weightGroupIndex);
}
else if (std::is_same<T, double>::value)
weightGroupIndex = addWeightToProduct(weightProduct, weight, std::to_string(i), i, weightGroupIndex);
i++;
}
}
return weightProduct;
}
} // namespace gen

#endif
95 changes: 95 additions & 0 deletions GeneratorInterface/Core/plugins/GenWeightProductProducer.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#include <cstdio>
#include <memory>
#include <vector>
#include <string>

// user include files
#include "FWCore/Framework/interface/Frameworkfwd.h"
#include "FWCore/Framework/interface/one/EDProducer.h"
#include "FWCore/Framework/interface/LuminosityBlock.h"

#include "FWCore/Framework/interface/Run.h"
#include "FWCore/Framework/interface/Event.h"
#include "FWCore/Framework/interface/MakerMacros.h"

#include "FWCore/ParameterSet/interface/FileInPath.h"
#include "FWCore/ParameterSet/interface/ParameterSet.h"

#include "SimDataFormats/GeneratorProducts/interface/LHERunInfoProduct.h"
#include "SimDataFormats/GeneratorProducts/interface/GenWeightInfoProduct.h"
#include "SimDataFormats/GeneratorProducts/interface/GenEventInfoProduct.h"
#include "SimDataFormats/GeneratorProducts/interface/GenLumiInfoHeader.h"

#include "GeneratorInterface/Core/interface/GenWeightHelper.h"

#include "FWCore/ServiceRegistry/interface/Service.h"
#include <boost/algorithm/string.hpp>

class GenWeightProductProducer : public edm::one::EDProducer<edm::BeginLuminosityBlockProducer> {
public:
explicit GenWeightProductProducer(const edm::ParameterSet& iConfig);
~GenWeightProductProducer() override;

private:
std::vector<std::string> weightNames_;
gen::GenWeightHelper weightHelper_;
edm::EDGetTokenT<GenLumiInfoHeader> genLumiInfoToken_;
edm::EDGetTokenT<GenEventInfoProduct> genEventToken_;
const edm::EDGetTokenT<GenLumiInfoHeader> genLumiInfoHeadTag_;

void produce(edm::Event&, const edm::EventSetup&) override;
void beginLuminosityBlockProduce(edm::LuminosityBlock& lb, edm::EventSetup const& c) override;
};

//
// constructors and destructor
//
GenWeightProductProducer::GenWeightProductProducer(const edm::ParameterSet& iConfig)
: genLumiInfoToken_(consumes<GenLumiInfoHeader, edm::InLumi>(iConfig.getParameter<edm::InputTag>("genInfo"))),
genEventToken_(consumes<GenEventInfoProduct>(iConfig.getParameter<edm::InputTag>("genInfo"))),
genLumiInfoHeadTag_(
mayConsume<GenLumiInfoHeader, edm::InLumi>(iConfig.getParameter<edm::InputTag>("genLumiInfoHeader"))) {
weightHelper_.setDebug(iConfig.getUntrackedParameter<bool>("debug", false));
produces<GenWeightProduct>();
produces<GenWeightInfoProduct, edm::Transition::BeginLuminosityBlock>();
weightHelper_.setGuessPSWeightIdx(iConfig.getUntrackedParameter<bool>("guessPSWeightIdx", false));
}

GenWeightProductProducer::~GenWeightProductProducer() {}

// ------------ method called to produce the data ------------
void GenWeightProductProducer::produce(edm::Event& iEvent, const edm::EventSetup& iSetup) {
edm::Handle<GenEventInfoProduct> genEventInfo;
iEvent.getByToken(genEventToken_, genEventInfo);

float centralWeight = !genEventInfo->weights().empty() ? genEventInfo->weights().at(0) : 1.;
auto weightProduct = weightHelper_.weightProduct(genEventInfo->weights(), centralWeight);
iEvent.put(std::move(weightProduct));
}

void GenWeightProductProducer::beginLuminosityBlockProduce(edm::LuminosityBlock& iLumi, edm::EventSetup const& iSetup) {
edm::Handle<GenLumiInfoHeader> genLumiInfoHead;
iLumi.getByToken(genLumiInfoHeadTag_, genLumiInfoHead);
if (genLumiInfoHead.isValid()) {
std::string label = genLumiInfoHead->configDescription();
boost::replace_all(label, "-", "_");
weightHelper_.setModel(label);
}

edm::Handle<GenLumiInfoHeader> genLumiInfoHandle;
iLumi.getByToken(genLumiInfoToken_, genLumiInfoHandle);

weightNames_ = genLumiInfoHandle->weightNames();
weightHelper_.parseWeightGroupsFromNames(weightNames_);

auto weightInfoProduct = std::make_unique<GenWeightInfoProduct>();
if (weightHelper_.weightGroups().empty())
weightHelper_.addUnassociatedGroup();

for (auto& weightGroup : weightHelper_.weightGroups()) {
weightInfoProduct->addWeightGroupInfo(weightGroup);
}
iLumi.put(std::move(weightInfoProduct));
}

DEFINE_FWK_MODULE(GenWeightProductProducer);
Loading

0 comments on commit b9b7820

Please sign in to comment.