Back to home page

Project CMSSW displayed by LXR

 
 

    


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);