Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-02-12 09:07:47

0001 #include "FWCore/Framework/interface/stream/EDProducer.h"
0002 #include "FWCore/Framework/interface/one/EDProducer.h"
0003 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0004 #include "FWCore/Framework/interface/ConsumesCollector.h"
0005 #include "DataFormats/Common/interface/View.h"
0006 #include "DataFormats/Common/interface/ValueMap.h"
0007 #include "DataFormats/NanoAOD/interface/FlatTable.h"
0008 
0009 #include "CommonTools/Utils/interface/StringCutObjectSelector.h"
0010 #include "CommonTools/Utils/interface/StringObjectFunction.h"
0011 
0012 #include <memory>
0013 #include <vector>
0014 
0015 // Base class for dumped variables
0016 class VariableBase {
0017 public:
0018   VariableBase(const std::string &aname, const edm::ParameterSet &cfg)
0019       : name_(aname),
0020         doc_(cfg.getParameter<std::string>("doc")),
0021         precision_(cfg.existsAs<int>("precision") ? cfg.getParameter<int>("precision")
0022                                                   : (cfg.existsAs<std::string>("precision") ? -2 : -1)) {}
0023   virtual ~VariableBase() {}
0024   const std::string &name() const { return name_; }
0025 
0026 protected:
0027   std::string name_, doc_;
0028   int precision_;
0029 };
0030 
0031 // Object member variables and methods
0032 template <typename ObjType>
0033 class Variable : public VariableBase {
0034 public:
0035   Variable(const std::string &aname, const edm::ParameterSet &cfg) : VariableBase(aname, cfg) {}
0036   virtual void fill(std::vector<const ObjType *> &selobjs, nanoaod::FlatTable &out) const = 0;
0037 };
0038 
0039 template <typename ObjType, typename StringFunctor, typename ValType>
0040 class FuncVariable : public Variable<ObjType> {
0041 public:
0042   FuncVariable(const std::string &aname, const edm::ParameterSet &cfg)
0043       : Variable<ObjType>(aname, cfg),
0044         func_(cfg.getParameter<std::string>("expr"), true),
0045         precisionFunc_(cfg.existsAs<std::string>("precision") ? cfg.getParameter<std::string>("precision") : "23",
0046                        true) {}
0047   ~FuncVariable() override {}
0048   void fill(std::vector<const ObjType *> &selobjs, nanoaod::FlatTable &out) const override {
0049     std::vector<ValType> vals(selobjs.size());
0050     for (unsigned int i = 0, n = vals.size(); i < n; ++i) {
0051       if constexpr (std::is_same<ValType, float>()) {
0052         if (this->precision_ == -2) {
0053           vals[i] = MiniFloatConverter::reduceMantissaToNbitsRounding(func_(*selobjs[i]), precisionFunc_(*selobjs[i]));
0054         } else {
0055           vals[i] = func_(*selobjs[i]);
0056         }
0057       } else {
0058         vals[i] = func_(*selobjs[i]);
0059       }
0060     }
0061     out.template addColumn<ValType>(this->name_, vals, this->doc_, this->precision_);
0062   }
0063 
0064 protected:
0065   StringFunctor func_;
0066   StringFunctor precisionFunc_;
0067 };
0068 
0069 // External variables: i.e. variables that are not member or methods of the object
0070 template <typename ObjType>
0071 class ExtVariable : public VariableBase {
0072 public:
0073   ExtVariable(const std::string &aname, const edm::ParameterSet &cfg) : VariableBase(aname, cfg) {}
0074   virtual void fill(const edm::Event &iEvent,
0075                     std::vector<edm::Ptr<ObjType>> selptrs,
0076                     nanoaod::FlatTable &out) const = 0;
0077 };
0078 template <typename ObjType, typename TIn, typename ValType = TIn>
0079 class ValueMapVariable : public ExtVariable<ObjType> {
0080 public:
0081   ValueMapVariable(const std::string &aname,
0082                    const edm::ParameterSet &cfg,
0083                    edm::ConsumesCollector &&cc,
0084                    bool skipNonExistingSrc = false)
0085       : ExtVariable<ObjType>(aname, cfg),
0086         skipNonExistingSrc_(skipNonExistingSrc),
0087         token_(cc.consumes<edm::ValueMap<TIn>>(cfg.getParameter<edm::InputTag>("src"))) {}
0088   void fill(const edm::Event &iEvent, std::vector<edm::Ptr<ObjType>> selptrs, nanoaod::FlatTable &out) const override {
0089     edm::Handle<edm::ValueMap<TIn>> vmap;
0090     iEvent.getByToken(token_, vmap);
0091     std::vector<ValType> vals;
0092     if (vmap.isValid() || !skipNonExistingSrc_) {
0093       vals.resize(selptrs.size());
0094       for (unsigned int i = 0, n = vals.size(); i < n; ++i) {
0095         vals[i] = (*vmap)[selptrs[i]];
0096       }
0097     }
0098     out.template addColumn<ValType>(this->name_, vals, this->doc_, this->precision_);
0099   }
0100 
0101 protected:
0102   const bool skipNonExistingSrc_;
0103   edm::EDGetTokenT<edm::ValueMap<TIn>> token_;
0104 };
0105 
0106 // Event producers
0107 // - ABC
0108 // - Singleton
0109 // - Collection
0110 template <typename T, typename TProd>
0111 class SimpleFlatTableProducerBase : public edm::stream::EDProducer<> {
0112 public:
0113   SimpleFlatTableProducerBase(edm::ParameterSet const &params)
0114       : name_(params.getParameter<std::string>("name")),
0115         doc_(params.existsAs<std::string>("doc") ? params.getParameter<std::string>("doc") : ""),
0116         extension_(params.existsAs<bool>("extension") ? params.getParameter<bool>("extension") : false),
0117         skipNonExistingSrc_(
0118             params.existsAs<bool>("skipNonExistingSrc") ? params.getParameter<bool>("skipNonExistingSrc") : false),
0119         src_(consumes<TProd>(params.getParameter<edm::InputTag>("src"))) {
0120     edm::ParameterSet const &varsPSet = params.getParameter<edm::ParameterSet>("variables");
0121     for (const std::string &vname : varsPSet.getParameterNamesForType<edm::ParameterSet>()) {
0122       const auto &varPSet = varsPSet.getParameter<edm::ParameterSet>(vname);
0123       const std::string &type = varPSet.getParameter<std::string>("type");
0124       if (type == "int")
0125         vars_.push_back(std::make_unique<IntVar>(vname, varPSet));
0126       else if (type == "uint")
0127         vars_.push_back(std::make_unique<UIntVar>(vname, varPSet));
0128       else if (type == "float")
0129         vars_.push_back(std::make_unique<FloatVar>(vname, varPSet));
0130       else if (type == "int8")
0131         vars_.push_back(std::make_unique<Int8Var>(vname, varPSet));
0132       else if (type == "uint8")
0133         vars_.push_back(std::make_unique<UInt8Var>(vname, varPSet));
0134       else if (type == "bool")
0135         vars_.push_back(std::make_unique<BoolVar>(vname, varPSet));
0136       else
0137         throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
0138     }
0139 
0140     produces<nanoaod::FlatTable>();
0141   }
0142 
0143   ~SimpleFlatTableProducerBase() override {}
0144 
0145   // this is to be overriden by the child class
0146   virtual std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Event &iEvent,
0147                                                         const edm::Handle<TProd> &prod) const = 0;
0148 
0149   void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override {
0150     edm::Handle<TProd> src;
0151     iEvent.getByToken(src_, src);
0152 
0153     std::unique_ptr<nanoaod::FlatTable> out = fillTable(iEvent, src);
0154     out->setDoc(doc_);
0155 
0156     iEvent.put(std::move(out));
0157   }
0158 
0159 protected:
0160   const std::string name_;
0161   const std::string doc_;
0162   const bool extension_;
0163   const bool skipNonExistingSrc_;
0164   const edm::EDGetTokenT<TProd> src_;
0165 
0166   typedef FuncVariable<T, StringObjectFunction<T>, int> IntVar;
0167   typedef FuncVariable<T, StringObjectFunction<T>, unsigned int> UIntVar;
0168   typedef FuncVariable<T, StringObjectFunction<T>, float> FloatVar;
0169   typedef FuncVariable<T, StringObjectFunction<T>, int8_t> Int8Var;
0170   typedef FuncVariable<T, StringObjectFunction<T>, uint8_t> UInt8Var;
0171   typedef FuncVariable<T, StringCutObjectSelector<T>, bool> BoolVar;
0172   std::vector<std::unique_ptr<Variable<T>>> vars_;
0173 };
0174 
0175 template <typename T>
0176 class SimpleFlatTableProducer : public SimpleFlatTableProducerBase<T, edm::View<T>> {
0177 public:
0178   SimpleFlatTableProducer(edm::ParameterSet const &params)
0179       : SimpleFlatTableProducerBase<T, edm::View<T>>(params),
0180         singleton_(params.getParameter<bool>("singleton")),
0181         maxLen_(params.existsAs<unsigned int>("maxLen") ? params.getParameter<unsigned int>("maxLen")
0182                                                         : std::numeric_limits<unsigned int>::max()),
0183         cut_(!singleton_ ? params.getParameter<std::string>("cut") : "", true) {
0184     if (params.existsAs<edm::ParameterSet>("externalVariables")) {
0185       edm::ParameterSet const &extvarsPSet = params.getParameter<edm::ParameterSet>("externalVariables");
0186       for (const std::string &vname : extvarsPSet.getParameterNamesForType<edm::ParameterSet>()) {
0187         const auto &varPSet = extvarsPSet.getParameter<edm::ParameterSet>(vname);
0188         const std::string &type = varPSet.getParameter<std::string>("type");
0189         if (type == "int")
0190           extvars_.push_back(
0191               std::make_unique<IntExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0192         else if (type == "float")
0193           extvars_.push_back(
0194               std::make_unique<FloatExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0195         else if (type == "double")
0196           extvars_.push_back(
0197               std::make_unique<DoubleExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0198         else if (type == "int8")
0199           extvars_.push_back(
0200               std::make_unique<Int8ExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0201         else if (type == "uint8")
0202           extvars_.push_back(
0203               std::make_unique<UInt8ExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0204         else if (type == "bool")
0205           extvars_.push_back(
0206               std::make_unique<BoolExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0207         else
0208           throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
0209       }
0210     }
0211   }
0212 
0213   ~SimpleFlatTableProducer() override {}
0214 
0215   std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Event &iEvent,
0216                                                 const edm::Handle<edm::View<T>> &prod) const override {
0217     std::vector<const T *> selobjs;
0218     std::vector<edm::Ptr<T>> selptrs;  // for external variables
0219     if (prod.isValid() || !(this->skipNonExistingSrc_)) {
0220       if (singleton_) {
0221         assert(prod->size() == 1);
0222         selobjs.push_back(&(*prod)[0]);
0223         if (!extvars_.empty())
0224           selptrs.emplace_back(prod->ptrAt(0));
0225       } else {
0226         for (unsigned int i = 0, n = prod->size(); i < n; ++i) {
0227           const auto &obj = (*prod)[i];
0228           if (cut_(obj)) {
0229             selobjs.push_back(&obj);
0230             if (!extvars_.empty())
0231               selptrs.emplace_back(prod->ptrAt(i));
0232           }
0233           if (selobjs.size() >= maxLen_)
0234             break;
0235         }
0236       }
0237     }
0238     auto out = std::make_unique<nanoaod::FlatTable>(selobjs.size(), this->name_, singleton_, this->extension_);
0239     for (const auto &var : this->vars_)
0240       var->fill(selobjs, *out);
0241     for (const auto &var : this->extvars_)
0242       var->fill(iEvent, selptrs, *out);
0243     return out;
0244   }
0245 
0246 protected:
0247   bool singleton_;
0248   const unsigned int maxLen_;
0249   const StringCutObjectSelector<T> cut_;
0250 
0251   typedef ValueMapVariable<T, int> IntExtVar;
0252   typedef ValueMapVariable<T, float> FloatExtVar;
0253   typedef ValueMapVariable<T, double, float> DoubleExtVar;
0254   typedef ValueMapVariable<T, bool> BoolExtVar;
0255   typedef ValueMapVariable<T, int, int8_t> Int8ExtVar;
0256   typedef ValueMapVariable<T, int, uint8_t> UInt8ExtVar;
0257   std::vector<std::unique_ptr<ExtVariable<T>>> extvars_;
0258 };
0259 
0260 template <typename T>
0261 class EventSingletonSimpleFlatTableProducer : public SimpleFlatTableProducerBase<T, T> {
0262 public:
0263   EventSingletonSimpleFlatTableProducer(edm::ParameterSet const &params) : SimpleFlatTableProducerBase<T, T>(params) {}
0264 
0265   ~EventSingletonSimpleFlatTableProducer() override {}
0266 
0267   std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Event &, const edm::Handle<T> &prod) const override {
0268     auto out = std::make_unique<nanoaod::FlatTable>(1, this->name_, true, this->extension_);
0269     std::vector<const T *> selobjs(1, prod.product());
0270     for (const auto &var : this->vars_)
0271       var->fill(selobjs, *out);
0272     return out;
0273   }
0274 };
0275 
0276 template <typename T>
0277 class FirstObjectSimpleFlatTableProducer : public SimpleFlatTableProducerBase<T, edm::View<T>> {
0278 public:
0279   FirstObjectSimpleFlatTableProducer(edm::ParameterSet const &params)
0280       : SimpleFlatTableProducerBase<T, edm::View<T>>(params) {}
0281 
0282   ~FirstObjectSimpleFlatTableProducer() override {}
0283 
0284   std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Event &iEvent,
0285                                                 const edm::Handle<edm::View<T>> &prod) const override {
0286     auto out = std::make_unique<nanoaod::FlatTable>(1, this->name_, true, this->extension_);
0287     std::vector<const T *> selobjs(1, &(*prod)[0]);
0288     for (const auto &var : this->vars_)
0289       var->fill(selobjs, *out);
0290     return out;
0291   }
0292 };
0293 
0294 // LuminosityBlock producers
0295 // - ABC
0296 // - Singleton
0297 // - Collection
0298 template <typename T, typename TProd>
0299 class SimpleFlatTableProducerBaseLumi
0300     : public edm::one::EDProducer<edm::EndLuminosityBlockProducer, edm::LuminosityBlockCache<int>> {
0301 public:
0302   SimpleFlatTableProducerBaseLumi(edm::ParameterSet const &params)
0303       : name_(params.getParameter<std::string>("name")),
0304         doc_(params.existsAs<std::string>("doc") ? params.getParameter<std::string>("doc") : ""),
0305         extension_(params.existsAs<bool>("extension") ? params.getParameter<bool>("extension") : false),
0306         skipNonExistingSrc_(
0307 
0308             params.existsAs<bool>("skipNonExistingSrc") ? params.getParameter<bool>("skipNonExistingSrc") : false),
0309         src_(consumes<TProd, edm::InLumi>(params.getParameter<edm::InputTag>("src"))) {
0310     edm::ParameterSet const &varsPSet = params.getParameter<edm::ParameterSet>("variables");
0311     for (const std::string &vname : varsPSet.getParameterNamesForType<edm::ParameterSet>()) {
0312       const auto &varPSet = varsPSet.getParameter<edm::ParameterSet>(vname);
0313       const std::string &type = varPSet.getParameter<std::string>("type");
0314       if (type == "int")
0315         vars_.push_back(std::make_unique<IntVar>(vname, varPSet));
0316       else if (type == "float")
0317         vars_.push_back(std::make_unique<FloatVar>(vname, varPSet));
0318       else if (type == "uint8")
0319         vars_.push_back(std::make_unique<UInt8Var>(vname, varPSet));
0320       else if (type == "bool")
0321         vars_.push_back(std::make_unique<BoolVar>(vname, varPSet));
0322       else
0323         throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
0324     }
0325 
0326     produces<nanoaod::FlatTable, edm::Transition::EndLuminosityBlock>();
0327   }
0328 
0329   ~SimpleFlatTableProducerBaseLumi() override {}
0330 
0331   std::shared_ptr<int> globalBeginLuminosityBlock(edm::LuminosityBlock const &,
0332                                                   edm::EventSetup const &) const override {
0333     return nullptr;
0334   }
0335 
0336   void globalEndLuminosityBlock(edm::LuminosityBlock const &, edm::EventSetup const &) override {}
0337 
0338   // this is to be overriden by the child class
0339   virtual std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::LuminosityBlock &iLumi,
0340                                                         const edm::Handle<TProd> &prod) const = 0;
0341 
0342   void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override {
0343     // do nothing
0344   }
0345 
0346   void endLuminosityBlockProduce(edm::LuminosityBlock &iLumi, const edm::EventSetup &iSetup) final {
0347     edm::Handle<TProd> src;
0348     iLumi.getByToken(src_, src);
0349 
0350     std::unique_ptr<nanoaod::FlatTable> out = fillTable(iLumi, src);
0351     out->setDoc(doc_);
0352 
0353     iLumi.put(std::move(out));
0354   }
0355 
0356 protected:
0357   const std::string name_;
0358   const std::string doc_;
0359   const bool extension_;
0360   const bool skipNonExistingSrc_;
0361   const edm::EDGetTokenT<TProd> src_;
0362 
0363   typedef FuncVariable<T, StringObjectFunction<T>, int> IntVar;
0364   typedef FuncVariable<T, StringObjectFunction<T>, float> FloatVar;
0365   typedef FuncVariable<T, StringObjectFunction<T>, uint8_t> UInt8Var;
0366   typedef FuncVariable<T, StringCutObjectSelector<T>, bool> BoolVar;
0367   std::vector<std::unique_ptr<Variable<T>>> vars_;
0368 };
0369 
0370 // Class for singletons like GenFilterInfo
0371 template <typename T>
0372 class LumiSingletonSimpleFlatTableProducer : public SimpleFlatTableProducerBaseLumi<T, T> {
0373 public:
0374   LumiSingletonSimpleFlatTableProducer(edm::ParameterSet const &params)
0375       : SimpleFlatTableProducerBaseLumi<T, T>(params) {}
0376 
0377   ~LumiSingletonSimpleFlatTableProducer() override {}
0378 
0379   std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::LuminosityBlock &,
0380                                                 const edm::Handle<T> &prod) const override {
0381     auto out = std::make_unique<nanoaod::FlatTable>(1, this->name_, true, this->extension_);
0382     std::vector<const T *> selobjs(1, prod.product());
0383     for (const auto &var : this->vars_)
0384       var->fill(selobjs, *out);
0385     return out;
0386   }
0387 };
0388 
0389 // Class for generic collections
0390 template <typename T, typename TProd>
0391 class LumiSimpleFlatTableProducer : public SimpleFlatTableProducerBaseLumi<T, TProd> {
0392 public:
0393   LumiSimpleFlatTableProducer(edm::ParameterSet const &params)
0394       : SimpleFlatTableProducerBaseLumi<T, TProd>(params),
0395         maxLen_(params.existsAs<unsigned int>("maxLen") ? params.getParameter<unsigned int>("maxLen")
0396                                                         : std::numeric_limits<unsigned int>::max()),
0397         cut_(params.existsAs<std::string>("cut") ? params.getParameter<std::string>("cut") : "", true) {}
0398 
0399   ~LumiSimpleFlatTableProducer() override {}
0400 
0401   std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::LuminosityBlock &iLumi,
0402                                                 const edm::Handle<TProd> &prod) const override {
0403     std::vector<const T *> selobjs;
0404     if (prod.isValid() || !(this->skipNonExistingSrc_)) {
0405       for (unsigned int i = 0, n = prod->size(); i < n; ++i) {
0406         const auto &obj = (*prod)[i];
0407         if (cut_(obj)) {
0408           selobjs.push_back(&obj);
0409         }
0410         if (selobjs.size() >= maxLen_)
0411           break;
0412       }
0413     }
0414     auto out = std::make_unique<nanoaod::FlatTable>(selobjs.size(), this->name_, false, this->extension_);
0415     for (const auto &var : this->vars_)
0416       var->fill(selobjs, *out);
0417     return out;
0418   }
0419 
0420 protected:
0421   const unsigned int maxLen_;
0422   const StringCutObjectSelector<T> cut_;
0423 };
0424 
0425 // Run producers
0426 // - ABC
0427 // - Singleton
0428 // - Collection
0429 template <typename T, typename TProd>
0430 class SimpleFlatTableProducerBaseRun : public edm::one::EDProducer<edm::EndRunProducer, edm::RunCache<int>> {
0431 public:
0432   SimpleFlatTableProducerBaseRun(edm::ParameterSet const &params)
0433       : name_(params.getParameter<std::string>("name")),
0434         doc_(params.existsAs<std::string>("doc") ? params.getParameter<std::string>("doc") : ""),
0435         extension_(params.existsAs<bool>("extension") ? params.getParameter<bool>("extension") : false),
0436         skipNonExistingSrc_(
0437 
0438             params.existsAs<bool>("skipNonExistingSrc") ? params.getParameter<bool>("skipNonExistingSrc") : false),
0439         src_(consumes<TProd, edm::InRun>(params.getParameter<edm::InputTag>("src"))) {
0440     edm::ParameterSet const &varsPSet = params.getParameter<edm::ParameterSet>("variables");
0441     for (const std::string &vname : varsPSet.getParameterNamesForType<edm::ParameterSet>()) {
0442       const auto &varPSet = varsPSet.getParameter<edm::ParameterSet>(vname);
0443       const std::string &type = varPSet.getParameter<std::string>("type");
0444       if (type == "int")
0445         vars_.push_back(std::make_unique<IntVar>(vname, varPSet));
0446       else if (type == "float")
0447         vars_.push_back(std::make_unique<FloatVar>(vname, varPSet));
0448       else if (type == "uint8")
0449         vars_.push_back(std::make_unique<UInt8Var>(vname, varPSet));
0450       else if (type == "bool")
0451         vars_.push_back(std::make_unique<BoolVar>(vname, varPSet));
0452       else
0453         throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
0454     }
0455 
0456     produces<nanoaod::FlatTable, edm::Transition::EndRun>();
0457   }
0458 
0459   ~SimpleFlatTableProducerBaseRun() override {}
0460 
0461   std::shared_ptr<int> globalBeginRun(edm::Run const &, edm::EventSetup const &) const override { return nullptr; }
0462 
0463   void globalEndRun(edm::Run const &, edm::EventSetup const &) override {}
0464 
0465   // this is to be overriden by the child class
0466   virtual std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Run &iRun, const edm::Handle<TProd> &prod) const = 0;
0467 
0468   void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override {
0469     // do nothing
0470   }
0471 
0472   void endRunProduce(edm::Run &iRun, const edm::EventSetup &iSetup) final {
0473     edm::Handle<TProd> src;
0474     iRun.getByToken(src_, src);
0475 
0476     std::unique_ptr<nanoaod::FlatTable> out = fillTable(iRun, src);
0477     out->setDoc(doc_);
0478 
0479     iRun.put(std::move(out));
0480   }
0481 
0482 protected:
0483   const std::string name_;
0484   const std::string doc_;
0485   const bool extension_;
0486   const bool skipNonExistingSrc_;
0487   const edm::EDGetTokenT<TProd> src_;
0488 
0489   typedef FuncVariable<T, StringObjectFunction<T>, int> IntVar;
0490   typedef FuncVariable<T, StringObjectFunction<T>, float> FloatVar;
0491   typedef FuncVariable<T, StringObjectFunction<T>, uint8_t> UInt8Var;
0492   typedef FuncVariable<T, StringCutObjectSelector<T>, bool> BoolVar;
0493   std::vector<std::unique_ptr<Variable<T>>> vars_;
0494 };
0495 
0496 // Class for singletons like GenFilterInfo
0497 template <typename T>
0498 class RunSingletonSimpleFlatTableProducer : public SimpleFlatTableProducerBaseRun<T, T> {
0499 public:
0500   RunSingletonSimpleFlatTableProducer(edm::ParameterSet const &params) : SimpleFlatTableProducerBaseRun<T, T>(params) {}
0501 
0502   ~RunSingletonSimpleFlatTableProducer() override {}
0503 
0504   std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Run &, const edm::Handle<T> &prod) const override {
0505     auto out = std::make_unique<nanoaod::FlatTable>(1, this->name_, true, this->extension_);
0506     std::vector<const T *> selobjs(1, prod.product());
0507     for (const auto &var : this->vars_)
0508       var->fill(selobjs, *out);
0509     return out;
0510   }
0511 };
0512 
0513 // Class for generic collections
0514 template <typename T, typename TProd>
0515 class RunSimpleFlatTableProducer : public SimpleFlatTableProducerBaseRun<T, TProd> {
0516 public:
0517   RunSimpleFlatTableProducer(edm::ParameterSet const &params)
0518       : SimpleFlatTableProducerBaseRun<T, TProd>(params),
0519         maxLen_(params.existsAs<unsigned int>("maxLen") ? params.getParameter<unsigned int>("maxLen")
0520                                                         : std::numeric_limits<unsigned int>::max()),
0521         cut_(params.existsAs<std::string>("cut") ? params.getParameter<std::string>("cut") : "", true) {}
0522 
0523   ~RunSimpleFlatTableProducer() override {}
0524 
0525   std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Run &iRun, const edm::Handle<TProd> &prod) const override {
0526     std::vector<const T *> selobjs;
0527     if (prod.isValid() || !(this->skipNonExistingSrc_)) {
0528       for (unsigned int i = 0, n = prod->size(); i < n; ++i) {
0529         const auto &obj = (*prod)[i];
0530         if (cut_(obj)) {
0531           selobjs.push_back(&obj);
0532         }
0533         if (selobjs.size() >= maxLen_)
0534           break;
0535       }
0536     }
0537     auto out = std::make_unique<nanoaod::FlatTable>(selobjs.size(), this->name_, false, this->extension_);
0538     for (const auto &var : this->vars_)
0539       var->fill(selobjs, *out);
0540     return out;
0541   }
0542 
0543 protected:
0544   const unsigned int maxLen_;
0545   const StringCutObjectSelector<T> cut_;
0546 };