Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2021-02-14 13:32:45

0001 #include "FWCore/Framework/interface/stream/EDProducer.h"
0002 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0003 #include "DataFormats/NanoAOD/interface/FlatTable.h"
0004 #include "FWCore/Framework/interface/ConsumesCollector.h"
0005 #include "DataFormats/Candidate/interface/Candidate.h"
0006 
0007 #include <memory>
0008 #include <utility>
0009 #include <vector>
0010 
0011 class GlobalVariablesTableProducer : public edm::stream::EDProducer<> {
0012 public:
0013   GlobalVariablesTableProducer(edm::ParameterSet const& params)
0014       : name_(params.existsAs<std::string>("name") ? params.getParameter<std::string>("name") : ""),
0015         extension_(params.existsAs<bool>("extension") ? params.getParameter<bool>("extension") : false) {
0016     edm::ParameterSet const& varsPSet = params.getParameter<edm::ParameterSet>("variables");
0017     for (const std::string& vname : varsPSet.getParameterNamesForType<edm::ParameterSet>()) {
0018       const auto& varPSet = varsPSet.getParameter<edm::ParameterSet>(vname);
0019       const std::string& type = varPSet.getParameter<std::string>("type");
0020       if (type == "int")
0021         vars_.push_back(std::make_unique<IntVar>(vname, varPSet, consumesCollector()));
0022       else if (type == "float")
0023         vars_.push_back(std::make_unique<FloatVar>(vname, varPSet, consumesCollector()));
0024       else if (type == "double")
0025         vars_.push_back(std::make_unique<DoubleVar>(vname, varPSet, consumesCollector()));
0026       else if (type == "bool")
0027         vars_.push_back(std::make_unique<BoolVar>(vname, varPSet, consumesCollector()));
0028       else if (type == "candidatescalarsum")
0029         vars_.push_back(std::make_unique<CandidateScalarSumVar>(vname, varPSet, consumesCollector()));
0030       else if (type == "candidatesize")
0031         vars_.push_back(std::make_unique<CandidateSizeVar>(vname, varPSet, consumesCollector()));
0032       else if (type == "candidatesummass")
0033         vars_.push_back(std::make_unique<CandidateSumMassVar>(vname, varPSet, consumesCollector()));
0034       else
0035         throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
0036     }
0037 
0038     produces<nanoaod::FlatTable>();
0039   }
0040 
0041   ~GlobalVariablesTableProducer() override {}
0042 
0043   void produce(edm::Event& iEvent, const edm::EventSetup& iSetup) override {
0044     auto out = std::make_unique<nanoaod::FlatTable>(1, this->name_, true, this->extension_);
0045 
0046     for (const auto& var : vars_)
0047       var->fill(iEvent, *out);
0048 
0049     iEvent.put(std::move(out));
0050   }
0051 
0052 protected:
0053   class Variable {
0054   public:
0055     Variable(const std::string& aname, const edm::ParameterSet& cfg)
0056         : name_(aname), doc_(cfg.getParameter<std::string>("doc")) {}
0057     virtual void fill(const edm::Event& iEvent, nanoaod::FlatTable& out) const = 0;
0058     virtual ~Variable() {}
0059     const std::string& name() const { return name_; }
0060 
0061   protected:
0062     std::string name_, doc_;
0063   };
0064   template <typename ValType>
0065   class Identity {
0066   public:
0067     static ValType convert(ValType x) { return x; }
0068   };
0069   template <typename ValType>
0070   class Size {
0071   public:
0072     static int convert(ValType x) { return x.size(); }
0073   };
0074 
0075   template <typename ColType, typename ValType>
0076   class Max {
0077   public:
0078     static ColType convert(ValType x) {
0079       ColType v = std::numeric_limits<ColType>::min();
0080       for (const auto& i : x)
0081         if (i > v)
0082           v = i;
0083       return v;
0084     }
0085   };
0086   template <typename ColType, typename ValType>
0087   class Min {
0088   public:
0089     static ColType convert(ValType x) {
0090       ColType v = std::numeric_limits<ColType>::max();
0091       for (const auto& i : x)
0092         if (i < v)
0093           v = i;
0094       return v;
0095     }
0096   };
0097   template <typename ColType, typename ValType>
0098   class ScalarPtSum {
0099   public:
0100     static ColType convert(ValType x) {
0101       ColType v = 0;
0102       for (const auto& i : x)
0103         v += i.pt();
0104       return v;
0105     }
0106   };
0107   template <typename ColType, typename ValType>
0108   class MassSum {
0109   public:
0110     static ColType convert(ValType x) {
0111       if (x.empty())
0112         return 0;
0113       auto v = x[0].p4();
0114       for (const auto& i : x)
0115         v += i.p4();
0116       return v.mass();
0117     }
0118   };
0119   template <typename ColType, typename ValType>
0120   class PtVectorSum {
0121   public:
0122     static ColType convert(ValType x) {
0123       if (x.empty())
0124         return 0;
0125       auto v = x[0].p4();
0126       v -= x[0].p4();
0127       for (const auto& i : x)
0128         v += i.p4();
0129       return v.pt();
0130     }
0131   };
0132 
0133   template <typename ValType, typename ColType = ValType, typename Converter = Identity<ValType>>
0134   class VariableT : public Variable {
0135   public:
0136     VariableT(const std::string& aname, const edm::ParameterSet& cfg, edm::ConsumesCollector&& cc)
0137         : Variable(aname, cfg), src_(cc.consumes<ValType>(cfg.getParameter<edm::InputTag>("src"))) {}
0138     ~VariableT() override {}
0139     void fill(const edm::Event& iEvent, nanoaod::FlatTable& out) const override {
0140       out.template addColumnValue<ColType>(this->name_, Converter::convert(iEvent.get(src_)), this->doc_);
0141     }
0142 
0143   protected:
0144     edm::EDGetTokenT<ValType> src_;
0145   };
0146   typedef VariableT<int> IntVar;
0147   typedef VariableT<float> FloatVar;
0148   typedef VariableT<double, float> DoubleVar;
0149   typedef VariableT<bool> BoolVar;
0150   typedef VariableT<edm::View<reco::Candidate>, float, ScalarPtSum<float, edm::View<reco::Candidate>>>
0151       CandidateScalarSumVar;
0152   typedef VariableT<edm::View<reco::Candidate>, float, MassSum<float, edm::View<reco::Candidate>>> CandidateSumMassVar;
0153   typedef VariableT<edm::View<reco::Candidate>, int, Size<edm::View<reco::Candidate>>> CandidateSizeVar;
0154   std::vector<std::unique_ptr<Variable>> vars_;
0155   const std::string name_;
0156   const bool extension_;
0157 };
0158 
0159 #include "FWCore/Framework/interface/MakerMacros.h"
0160 DEFINE_FWK_MODULE(GlobalVariablesTableProducer);