File indexing completed on 2024-04-06 12:23:41
0001 #include "FWCore/Framework/interface/stream/EDProducer.h"
0002 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0003 #include "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0004 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0005 #include "FWCore/ParameterSet/interface/allowedValues.h"
0006 #include "DataFormats/NanoAOD/interface/FlatTable.h"
0007 #include "FWCore/Framework/interface/ConsumesCollector.h"
0008 #include "DataFormats/Candidate/interface/Candidate.h"
0009
0010 #include <memory>
0011 #include <utility>
0012 #include <vector>
0013
0014 class GlobalVariablesTableProducer : public edm::stream::EDProducer<> {
0015 public:
0016 GlobalVariablesTableProducer(edm::ParameterSet const& params)
0017 : name_(params.getParameter<std::string>("name")), extension_(params.getParameter<bool>("extension")) {
0018 edm::ParameterSet const& varsPSet = params.getParameter<edm::ParameterSet>("variables");
0019 for (const std::string& vname : varsPSet.getParameterNamesForType<edm::ParameterSet>()) {
0020 const auto& varPSet = varsPSet.getParameter<edm::ParameterSet>(vname);
0021 const std::string& type = varPSet.getParameter<std::string>("type");
0022 if (type == "int")
0023 vars_.push_back(std::make_unique<IntVar>(vname, varPSet, consumesCollector()));
0024 else if (type == "float")
0025 vars_.push_back(std::make_unique<FloatVar>(vname, varPSet, consumesCollector()));
0026 else if (type == "double")
0027 vars_.push_back(std::make_unique<DoubleVar>(vname, varPSet, consumesCollector()));
0028 else if (type == "bool")
0029 vars_.push_back(std::make_unique<BoolVar>(vname, varPSet, consumesCollector()));
0030 else if (type == "candidatescalarsum")
0031 vars_.push_back(std::make_unique<CandidateScalarSumVar>(vname, varPSet, consumesCollector()));
0032 else if (type == "candidatesize")
0033 vars_.push_back(std::make_unique<CandidateSizeVar>(vname, varPSet, consumesCollector()));
0034 else if (type == "candidatesummass")
0035 vars_.push_back(std::make_unique<CandidateSumMassVar>(vname, varPSet, consumesCollector()));
0036 else
0037 throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
0038 }
0039
0040 produces<nanoaod::FlatTable>();
0041 }
0042
0043 ~GlobalVariablesTableProducer() override {}
0044
0045 static void fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0046 edm::ParameterSetDescription desc;
0047 desc.add<std::string>("name", "")->setComment("name of the branch in the flat table output");
0048 desc.add<bool>("extension", false)->setComment("whether or not to extend an existing same table");
0049 edm::ParameterSetDescription variable;
0050 variable.ifValue(edm::ParameterDescription<std::string>(
0051 "type", "int", true, edm::Comment("the c++ type of the branch in the flat table")),
0052 edm::allowedValues<std::string>(
0053 "int", "float", "double", "bool", "candidatescalarsum", "candidatesize", "candidatesummass"));
0054 variable.add<edm::InputTag>("src")->setComment("input collection for the branch");
0055 variable.add<std::string>("doc")->setComment("few words description of the branch content");
0056 variable.add<int>("precision", -1)->setComment("precision to store the information");
0057 edm::ParameterSetDescription variables;
0058 variables.setComment("a parameters set to define variable to fill the flat table");
0059 variables.addNode(
0060 edm::ParameterWildcard<edm::ParameterSetDescription>("*", edm::RequireZeroOrMore, true, variable));
0061 desc.add<edm::ParameterSetDescription>("variables", variables);
0062
0063 descriptions.addWithDefaultLabel(desc);
0064 }
0065 void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override {
0066 auto out = std::make_unique<nanoaod::FlatTable>(1, this->name_, true, this->extension_);
0067
0068 for (const auto& var : vars_)
0069 var->fill(iEvent, *out);
0070
0071 iEvent.put(std::move(out));
0072 }
0073
0074 protected:
0075 class Variable {
0076 public:
0077 Variable(const std::string& aname, const edm::ParameterSet& cfg)
0078 : name_(aname), doc_(cfg.getParameter<std::string>("doc")), precision_(cfg.getParameter<int>("precision")) {}
0079 virtual void fill(const edm::Event& iEvent, nanoaod::FlatTable& out) const = 0;
0080 virtual ~Variable() {}
0081 const std::string& name() const { return name_; }
0082
0083 protected:
0084 std::string name_, doc_;
0085 int precision_;
0086 };
0087 template <typename ValType>
0088 class Identity {
0089 public:
0090 static ValType convert(ValType x) { return x; }
0091 };
0092 template <typename ValType>
0093 class Size {
0094 public:
0095 static int convert(ValType x) { return x.size(); }
0096 };
0097
0098 template <typename ColType, typename ValType>
0099 class Max {
0100 public:
0101 static ColType convert(ValType x) {
0102 ColType v = std::numeric_limits<ColType>::min();
0103 for (const auto& i : x)
0104 if (i > v)
0105 v = i;
0106 return v;
0107 }
0108 };
0109 template <typename ColType, typename ValType>
0110 class Min {
0111 public:
0112 static ColType convert(ValType x) {
0113 ColType v = std::numeric_limits<ColType>::max();
0114 for (const auto& i : x)
0115 if (i < v)
0116 v = i;
0117 return v;
0118 }
0119 };
0120 template <typename ColType, typename ValType>
0121 class ScalarPtSum {
0122 public:
0123 static ColType convert(ValType x) {
0124 ColType v = 0;
0125 for (const auto& i : x)
0126 v += i.pt();
0127 return v;
0128 }
0129 };
0130 template <typename ColType, typename ValType>
0131 class MassSum {
0132 public:
0133 static ColType convert(ValType x) {
0134 if (x.empty())
0135 return 0;
0136 auto v = x[0].p4();
0137 for (const auto& i : x)
0138 v += i.p4();
0139 return v.mass();
0140 }
0141 };
0142 template <typename ColType, typename ValType>
0143 class PtVectorSum {
0144 public:
0145 static ColType convert(ValType x) {
0146 if (x.empty())
0147 return 0;
0148 auto v = x[0].p4();
0149 v -= x[0].p4();
0150 for (const auto& i : x)
0151 v += i.p4();
0152 return v.pt();
0153 }
0154 };
0155
0156 template <typename ValType, typename ColType = ValType, typename Converter = Identity<ValType>>
0157 class VariableT : public Variable {
0158 public:
0159 VariableT(const std::string& aname, const edm::ParameterSet& cfg, edm::ConsumesCollector&& cc)
0160 : Variable(aname, cfg), src_(cc.consumes<ValType>(cfg.getParameter<edm::InputTag>("src"))) {}
0161 ~VariableT() override {}
0162 void fill(const edm::Event& iEvent, nanoaod::FlatTable& out) const override {
0163 out.template addColumnValue<ColType>(
0164 this->name_, Converter::convert(iEvent.get(src_)), this->doc_, this->precision_);
0165 }
0166
0167 protected:
0168 edm::EDGetTokenT<ValType> src_;
0169 };
0170 typedef VariableT<int> IntVar;
0171 typedef VariableT<float> FloatVar;
0172 typedef VariableT<double, float> DoubleVar;
0173 typedef VariableT<bool> BoolVar;
0174 typedef VariableT<edm::View<reco::Candidate>, float, ScalarPtSum<float, edm::View<reco::Candidate>>>
0175 CandidateScalarSumVar;
0176 typedef VariableT<edm::View<reco::Candidate>, float, MassSum<float, edm::View<reco::Candidate>>> CandidateSumMassVar;
0177 typedef VariableT<edm::View<reco::Candidate>, int, Size<edm::View<reco::Candidate>>> CandidateSizeVar;
0178 std::vector<std::unique_ptr<Variable>> vars_;
0179 const std::string name_;
0180 const bool extension_;
0181 };
0182
0183 #include "FWCore/Framework/interface/MakerMacros.h"
0184 DEFINE_FWK_MODULE(GlobalVariablesTableProducer);