File indexing completed on 2025-03-23 16:00:20
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 "FWCore/ParameterSet/interface/ConfigurationDescriptions.h"
0006 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0007 #include "FWCore/ParameterSet/interface/EmptyGroupDescription.h"
0008 #include "FWCore/ParameterSet/interface/allowedValues.h"
0009 #include "DataFormats/Common/interface/View.h"
0010 #include "DataFormats/Common/interface/ValueMap.h"
0011 #include "DataFormats/NanoAOD/interface/FlatTable.h"
0012 #include "Utilities/General/interface/ClassName.h"
0013 #include "DataFormats/L1Trigger/interface/BXVector.h"
0014
0015 #include "CommonTools/Utils/interface/StringCutObjectSelector.h"
0016 #include "CommonTools/Utils/interface/StringObjectFunction.h"
0017 #include "CommonTools/Utils/interface/TypedStringObjectMethodCaller.h"
0018
0019 #include <memory>
0020 #include <vector>
0021
0022
0023 class VariableBase {
0024 public:
0025 VariableBase(const std::string &aname, const edm::ParameterSet &cfg)
0026 : name_(aname),
0027 doc_(cfg.getParameter<std::string>("doc")),
0028 precision_(cfg.existsAs<int>("precision") ? cfg.getParameter<int>("precision")
0029 : (cfg.existsAs<std::string>("precision") ? -2 : -1)) {}
0030 virtual ~VariableBase() {}
0031 const std::string &name() const { return name_; }
0032
0033 protected:
0034 std::string name_, doc_;
0035 int precision_;
0036 };
0037
0038
0039 template <typename ObjType>
0040 class Variable : public VariableBase {
0041 public:
0042 Variable(const std::string &aname, const edm::ParameterSet &cfg) : VariableBase(aname, cfg) {}
0043 virtual void fill(std::vector<const ObjType *> &selobjs, nanoaod::FlatTable &out) const = 0;
0044 };
0045
0046 template <typename ObjType, typename StringFunctor, typename ValType>
0047 class FuncVariable : public Variable<ObjType> {
0048 public:
0049 FuncVariable(const std::string &aname, const edm::ParameterSet &cfg)
0050 : Variable<ObjType>(aname, cfg),
0051 func_(cfg.getParameter<std::string>("expr"), cfg.getUntrackedParameter<bool>("lazyEval")),
0052 precisionFunc_(cfg.existsAs<std::string>("precision") ? cfg.getParameter<std::string>("precision") : "23",
0053 cfg.getUntrackedParameter<bool>("lazyEval")) {}
0054 ~FuncVariable() override {}
0055
0056 void fill(std::vector<const ObjType *> &selobjs, nanoaod::FlatTable &out) const override {
0057 std::vector<ValType> vals(selobjs.size());
0058 for (unsigned int i = 0, n = vals.size(); i < n; ++i) {
0059 vals[i] = func_(*selobjs[i]);
0060 if constexpr (std::is_same<ValType, float>()) {
0061 if (this->precision_ == -2) {
0062 auto prec = precisionFunc_(*selobjs[i]);
0063 if (prec > 0) {
0064 vals[i] = MiniFloatConverter::reduceMantissaToNbitsRounding(vals[i], prec);
0065 }
0066 }
0067 }
0068 }
0069 out.template addColumn<ValType>(this->name_, vals, this->doc_, this->precision_);
0070 }
0071
0072 protected:
0073 StringFunctor func_;
0074 StringFunctor precisionFunc_;
0075 };
0076
0077
0078 template <typename ObjType>
0079 class CollectionVariable : public VariableBase {
0080 public:
0081 CollectionVariable(const std::string &aname, const edm::ParameterSet &cfg) : VariableBase(aname, cfg) {}
0082 virtual std::unique_ptr<std::vector<unsigned int>> getCounts(std::vector<const ObjType *> &selobjs) const = 0;
0083 virtual void fill(std::vector<const ObjType *> &selobjs, nanoaod::FlatTable &out) const = 0;
0084 };
0085
0086 template <typename ObjType, typename CollectionStringFunctor, typename PrecisionStringFunctor, typename ValType>
0087 class FuncCollectionVariable : public CollectionVariable<ObjType> {
0088 public:
0089 FuncCollectionVariable(const std::string &aname, const edm::ParameterSet &cfg)
0090 : CollectionVariable<ObjType>(aname, cfg),
0091 func_(cfg.getParameter<std::string>("expr"), cfg.getUntrackedParameter<bool>("lazyEval")),
0092 precisionFunc_(cfg.existsAs<std::string>("precision") ? cfg.getParameter<std::string>("precision") : "23",
0093 cfg.getUntrackedParameter<bool>("lazyEval")) {}
0094 ~FuncCollectionVariable() override {}
0095
0096 std::unique_ptr<std::vector<unsigned int>> getCounts(std::vector<const ObjType *> &selobjs) const override {
0097 auto counts = std::make_unique<std::vector<unsigned int>>();
0098 for (auto const &obj : selobjs)
0099 counts->push_back(func_(*obj).size());
0100 return counts;
0101 }
0102
0103 void fill(std::vector<const ObjType *> &selobjs, nanoaod::FlatTable &out) const override {
0104 std::vector<ValType> vals;
0105 for (unsigned int i = 0; i < selobjs.size(); ++i) {
0106 for (ValType val : func_(*selobjs[i])) {
0107 if constexpr (std::is_same<ValType, float>()) {
0108 if (this->precision_ == -2) {
0109 auto prec = precisionFunc_(*selobjs[i]);
0110 if (prec > 0) {
0111 val = MiniFloatConverter::reduceMantissaToNbitsRounding(val, prec);
0112 }
0113 }
0114 }
0115 vals.push_back(val);
0116 }
0117 }
0118 out.template addColumn<ValType>(this->name_, vals, this->doc_, this->precision_);
0119 }
0120
0121 protected:
0122 CollectionStringFunctor func_;
0123 PrecisionStringFunctor precisionFunc_;
0124 };
0125
0126
0127 template <typename ObjType>
0128 class ExtVariable : public VariableBase {
0129 public:
0130 ExtVariable(const std::string &aname, const edm::ParameterSet &cfg) : VariableBase(aname, cfg) {}
0131 virtual void fill(const edm::Event &iEvent,
0132 std::vector<edm::Ptr<ObjType>> selptrs,
0133 nanoaod::FlatTable &out) const = 0;
0134 };
0135
0136 template <typename ObjType, typename TIn, typename ValType = TIn>
0137 class ValueMapVariableBase : public ExtVariable<ObjType> {
0138 public:
0139 ValueMapVariableBase(const std::string &aname,
0140 const edm::ParameterSet &cfg,
0141 edm::ConsumesCollector &&cc,
0142 bool skipNonExistingSrc = false)
0143 : ExtVariable<ObjType>(aname, cfg),
0144 skipNonExistingSrc_(skipNonExistingSrc),
0145 token_(cc.consumes<edm::ValueMap<TIn>>(cfg.getParameter<edm::InputTag>("src"))) {}
0146 virtual ValType eval(const edm::Handle<edm::ValueMap<TIn>> &vmap, const edm::Ptr<ObjType> &op) const = 0;
0147 void fill(const edm::Event &iEvent, std::vector<edm::Ptr<ObjType>> selptrs, nanoaod::FlatTable &out) const override {
0148 edm::Handle<edm::ValueMap<TIn>> vmap;
0149 iEvent.getByToken(token_, vmap);
0150 std::vector<ValType> vals;
0151 if (vmap.isValid() || !skipNonExistingSrc_) {
0152 vals.resize(selptrs.size());
0153 for (unsigned int i = 0, n = vals.size(); i < n; ++i) {
0154
0155 vals[i] = this->eval(vmap, selptrs[i]);
0156 }
0157 }
0158 out.template addColumn<ValType>(this->name_, vals, this->doc_, this->precision_);
0159 }
0160
0161 protected:
0162 const bool skipNonExistingSrc_;
0163 edm::EDGetTokenT<edm::ValueMap<TIn>> token_;
0164 };
0165
0166 template <typename ObjType, typename TIn, typename ValType = TIn>
0167 class ValueMapVariable : public ValueMapVariableBase<ObjType, TIn, ValType> {
0168 public:
0169 ValueMapVariable(const std::string &aname,
0170 const edm::ParameterSet &cfg,
0171 edm::ConsumesCollector &&cc,
0172 bool skipNonExistingSrc = false)
0173 : ValueMapVariableBase<ObjType, TIn, ValType>(aname, cfg, std::move(cc), skipNonExistingSrc) {}
0174 ValType eval(const edm::Handle<edm::ValueMap<TIn>> &vmap, const edm::Ptr<ObjType> &op) const override {
0175 ValType val = (*vmap)[op];
0176 return val;
0177 }
0178 };
0179
0180 template <typename ObjType, typename TIn, typename StringFunctor, typename ValType>
0181 class TypedValueMapVariable : public ValueMapVariableBase<ObjType, TIn, ValType> {
0182 public:
0183 TypedValueMapVariable(const std::string &aname,
0184 const edm::ParameterSet &cfg,
0185 edm::ConsumesCollector &&cc,
0186 bool skipNonExistingSrc = false)
0187 : ValueMapVariableBase<ObjType, TIn, ValType>(aname, cfg, std::move(cc), skipNonExistingSrc),
0188 func_(cfg.getParameter<std::string>("expr"), true),
0189 precisionFunc_(cfg.existsAs<std::string>("precision") ? cfg.getParameter<std::string>("precision") : "23",
0190 true) {}
0191
0192 ValType eval(const edm::Handle<edm::ValueMap<TIn>> &vmap, const edm::Ptr<ObjType> &op) const override {
0193 ValType val = func_((*vmap)[op]);
0194 if constexpr (std::is_same<ValType, float>()) {
0195 if (this->precision_ == -2) {
0196 auto prec = precisionFunc_(*op);
0197 if (prec > 0) {
0198 val = MiniFloatConverter::reduceMantissaToNbitsRounding(val, prec);
0199 }
0200 }
0201 }
0202 return val;
0203 }
0204
0205 protected:
0206 StringFunctor func_;
0207 StringObjectFunction<ObjType> precisionFunc_;
0208 };
0209
0210
0211
0212
0213
0214 template <typename T, typename TProd>
0215 class SimpleFlatTableProducerBase : public edm::stream::EDProducer<> {
0216 public:
0217 SimpleFlatTableProducerBase(edm::ParameterSet const ¶ms)
0218 : name_(params.getParameter<std::string>("name")),
0219 doc_(params.getParameter<std::string>("doc")),
0220 extension_(params.getParameter<bool>("extension")),
0221 skipNonExistingSrc_(params.getParameter<bool>("skipNonExistingSrc")),
0222 src_(consumes<TProd>(params.getParameter<edm::InputTag>("src"))) {
0223 edm::ParameterSet const &varsPSet = params.getParameter<edm::ParameterSet>("variables");
0224 for (const std::string &vname : varsPSet.getParameterNamesForType<edm::ParameterSet>()) {
0225 const auto &varPSet = varsPSet.getParameter<edm::ParameterSet>(vname);
0226 const std::string &type = varPSet.getParameter<std::string>("type");
0227 if (type == "int")
0228 vars_.push_back(std::make_unique<IntVar>(vname, varPSet));
0229 else if (type == "uint")
0230 vars_.push_back(std::make_unique<UIntVar>(vname, varPSet));
0231 else if (type == "int64")
0232 vars_.push_back(std::make_unique<Int64Var>(vname, varPSet));
0233 else if (type == "uint64")
0234 vars_.push_back(std::make_unique<UInt64Var>(vname, varPSet));
0235 else if (type == "float")
0236 vars_.push_back(std::make_unique<FloatVar>(vname, varPSet));
0237 else if (type == "double")
0238 vars_.push_back(std::make_unique<DoubleVar>(vname, varPSet));
0239 else if (type == "uint8")
0240 vars_.push_back(std::make_unique<UInt8Var>(vname, varPSet));
0241 else if (type == "int16")
0242 vars_.push_back(std::make_unique<Int16Var>(vname, varPSet));
0243 else if (type == "uint16")
0244 vars_.push_back(std::make_unique<UInt16Var>(vname, varPSet));
0245 else if (type == "bool")
0246 vars_.push_back(std::make_unique<BoolVar>(vname, varPSet));
0247 else
0248 throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
0249 }
0250
0251 produces<nanoaod::FlatTable>();
0252 }
0253
0254 ~SimpleFlatTableProducerBase() override {}
0255
0256 static edm::ParameterSetDescription baseDescriptions() {
0257 edm::ParameterSetDescription desc;
0258 std::string classname = ClassName<T>::name();
0259 desc.add<std::string>("name")->setComment("name of the branch in the flat table output for " + classname);
0260 desc.add<std::string>("doc", "")->setComment("few words of self documentation");
0261 desc.add<bool>("extension", false)->setComment("whether or not to extend an existing same table");
0262 desc.add<bool>("skipNonExistingSrc", false)
0263 ->setComment("whether or not to skip producing the table on absent input product");
0264 desc.add<edm::InputTag>("src")->setComment("input collection to fill the flat table");
0265
0266 edm::ParameterSetDescription variable;
0267 variable.add<std::string>("expr")->setComment("a function to define the content of the branch in the flat table");
0268 variable.add<std::string>("doc")->setComment("few words description of the branch content");
0269 variable.addUntracked<bool>("lazyEval", false)
0270 ->setComment("if true, can use methods of inheriting classes in `expr`. Can cause problems with threading.");
0271 variable.ifValue(edm::ParameterDescription<std::string>(
0272 "type", "int", true, edm::Comment("the c++ type of the branch in the flat table")),
0273 edm::allowedValues<std::string>(
0274 "int", "uint", "int64", "uint64", "float", "double", "uint8", "int16", "uint16", "bool"));
0275 variable.addOptionalNode(
0276 edm::ParameterDescription<int>(
0277 "precision", true, edm::Comment("the precision with which to store the value in the flat table")) xor
0278 edm::ParameterDescription<std::string>(
0279 "precision", true, edm::Comment("the precision with which to store the value in the flat table")),
0280 false);
0281
0282 edm::ParameterSetDescription variables;
0283 variables.setComment("a parameters set to define all variable to fill the flat table");
0284 variables.addNode(
0285 edm::ParameterWildcard<edm::ParameterSetDescription>("*", edm::RequireZeroOrMore, true, variable));
0286 desc.add<edm::ParameterSetDescription>("variables", variables);
0287
0288 return desc;
0289 }
0290
0291 virtual std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Event &iEvent,
0292 const edm::Handle<TProd> &prod) const = 0;
0293
0294 void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override {
0295 edm::Handle<TProd> src;
0296 iEvent.getByToken(src_, src);
0297
0298 std::unique_ptr<nanoaod::FlatTable> out = fillTable(iEvent, src);
0299 out->setDoc(doc_);
0300
0301 iEvent.put(std::move(out));
0302 }
0303
0304 protected:
0305 const std::string name_;
0306 const std::string doc_;
0307 const bool extension_;
0308 const bool skipNonExistingSrc_;
0309 const edm::EDGetTokenT<TProd> src_;
0310
0311 typedef FuncVariable<T, StringObjectFunction<T>, int32_t> IntVar;
0312 typedef FuncVariable<T, StringObjectFunction<T>, uint32_t> UIntVar;
0313 typedef FuncVariable<T, StringObjectFunction<T>, int64_t> Int64Var;
0314 typedef FuncVariable<T, StringObjectFunction<T>, uint64_t> UInt64Var;
0315 typedef FuncVariable<T, StringObjectFunction<T>, float> FloatVar;
0316 typedef FuncVariable<T, StringObjectFunction<T>, double> DoubleVar;
0317 typedef FuncVariable<T, StringObjectFunction<T>, uint8_t> UInt8Var;
0318 typedef FuncVariable<T, StringObjectFunction<T>, int16_t> Int16Var;
0319 typedef FuncVariable<T, StringObjectFunction<T>, uint16_t> UInt16Var;
0320 typedef FuncVariable<T, StringCutObjectSelector<T>, bool> BoolVar;
0321 std::vector<std::unique_ptr<Variable<T>>> vars_;
0322 };
0323
0324 template <typename T>
0325 class SimpleFlatTableProducer : public SimpleFlatTableProducerBase<T, edm::View<T>> {
0326 public:
0327 SimpleFlatTableProducer(edm::ParameterSet const ¶ms)
0328 : SimpleFlatTableProducerBase<T, edm::View<T>>(params),
0329 singleton_(params.getParameter<bool>("singleton")),
0330 maxLen_(params.existsAs<unsigned int>("maxLen") ? params.getParameter<unsigned int>("maxLen")
0331 : std::numeric_limits<unsigned int>::max()),
0332 cut_(!singleton_ ? params.getParameter<std::string>("cut") : "",
0333 !singleton_ ? params.getUntrackedParameter<bool>("lazyEval") : false) {
0334 if (params.existsAs<edm::ParameterSet>("externalVariables")) {
0335 edm::ParameterSet const &extvarsPSet = params.getParameter<edm::ParameterSet>("externalVariables");
0336 for (const std::string &vname : extvarsPSet.getParameterNamesForType<edm::ParameterSet>()) {
0337 const auto &varPSet = extvarsPSet.getParameter<edm::ParameterSet>(vname);
0338 const std::string &type = varPSet.getParameter<std::string>("type");
0339 if (type == "int")
0340 extvars_.push_back(
0341 std::make_unique<IntExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0342 else if (type == "uint")
0343 extvars_.push_back(
0344 std::make_unique<UIntExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0345 else if (type == "int64")
0346 extvars_.push_back(
0347 std::make_unique<Int64ExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0348 else if (type == "uint64")
0349 extvars_.push_back(
0350 std::make_unique<UInt64ExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0351 else if (type == "float")
0352 extvars_.push_back(
0353 std::make_unique<FloatExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0354 else if (type == "double")
0355 extvars_.push_back(
0356 std::make_unique<DoubleExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0357 else if (type == "uint8")
0358 extvars_.push_back(
0359 std::make_unique<UInt8ExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0360 else if (type == "int16")
0361 extvars_.push_back(
0362 std::make_unique<Int16ExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0363 else if (type == "uint16")
0364 extvars_.push_back(
0365 std::make_unique<UInt16ExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0366 else if (type == "bool")
0367 extvars_.push_back(
0368 std::make_unique<BoolExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0369 else
0370 throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
0371 }
0372 }
0373 }
0374
0375 ~SimpleFlatTableProducer() override {}
0376
0377 static edm::ParameterSetDescription baseDescriptions() {
0378 edm::ParameterSetDescription desc = SimpleFlatTableProducerBase<T, edm::View<T>>::baseDescriptions();
0379
0380 desc.ifValue(
0381 edm::ParameterDescription<bool>(
0382 "singleton", false, true, edm::Comment("whether or not the input collection is single-element")),
0383 false >> (edm::ParameterDescription<std::string>(
0384 "cut", "", true, edm::Comment("selection on the main input collection")) and
0385 edm::ParameterDescription<bool>("lazyEval",
0386 false,
0387 false,
0388 edm::Comment("if true, can use methods of inheriting classes. Can "
0389 "cause problems when multi-threading."))) or
0390 true >> edm::EmptyGroupDescription());
0391 desc.addOptional<unsigned int>("maxLen")->setComment(
0392 "define the maximum length of the input collection to put in the branch");
0393
0394 edm::ParameterSetDescription extvariable;
0395 extvariable.add<edm::InputTag>("src")->setComment("valuemap input collection to fill the flat table");
0396 extvariable.add<std::string>("doc")->setComment("few words description of the branch content");
0397 extvariable.ifValue(edm::ParameterDescription<std::string>(
0398 "type", "int", true, edm::Comment("the c++ type of the branch in the flat table")),
0399 edm::allowedValues<std::string>(
0400 "int", "uint", "int64", "uint64", "float", "double", "uint8", "int16", "uint16", "bool"));
0401 extvariable.addOptionalNode(
0402 edm::ParameterDescription<int>(
0403 "precision", true, edm::Comment("the precision with which to store the value in the flat table")) xor
0404 edm::ParameterDescription<std::string>("precision",
0405 true,
0406 edm::Comment("the precision with which to store the value in the "
0407 "flat table, as a function of the object evaluated")),
0408 false);
0409
0410 edm::ParameterSetDescription extvariables;
0411 extvariables.setComment("a parameters set to define all variable taken form valuemap to fill the flat table");
0412 extvariables.addOptionalNode(
0413 edm::ParameterWildcard<edm::ParameterSetDescription>("*", edm::RequireZeroOrMore, true, extvariable), false);
0414 desc.addOptional<edm::ParameterSetDescription>("externalVariables", extvariables);
0415
0416 return desc;
0417 }
0418 static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0419 edm::ParameterSetDescription desc = SimpleFlatTableProducer<T>::baseDescriptions();
0420 descriptions.addWithDefaultLabel(desc);
0421 }
0422 std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Event &iEvent,
0423 const edm::Handle<edm::View<T>> &prod) const override {
0424 std::vector<const T *> selobjs;
0425 std::vector<edm::Ptr<T>> selptrs;
0426 if (prod.isValid() || !(this->skipNonExistingSrc_)) {
0427 if (singleton_) {
0428 assert(prod->size() == 1);
0429 selobjs.push_back(&(*prod)[0]);
0430 if (!extvars_.empty() || !typedextvars_.empty())
0431 selptrs.emplace_back(prod->ptrAt(0));
0432 } else {
0433 for (unsigned int i = 0, n = prod->size(); i < n; ++i) {
0434 const auto &obj = (*prod)[i];
0435 if (cut_(obj)) {
0436 selobjs.push_back(&obj);
0437 if (!extvars_.empty() || !typedextvars_.empty())
0438 selptrs.emplace_back(prod->ptrAt(i));
0439 }
0440 if (selobjs.size() >= maxLen_)
0441 break;
0442 }
0443 }
0444 }
0445 auto out = std::make_unique<nanoaod::FlatTable>(selobjs.size(), this->name_, singleton_, this->extension_);
0446 for (const auto &var : this->vars_)
0447 var->fill(selobjs, *out);
0448 for (const auto &var : this->extvars_)
0449 var->fill(iEvent, selptrs, *out);
0450 for (const auto &var : this->typedextvars_)
0451 var->fill(iEvent, selptrs, *out);
0452 return out;
0453 }
0454
0455 protected:
0456 bool singleton_;
0457 const unsigned int maxLen_;
0458 const StringCutObjectSelector<T> cut_;
0459
0460 typedef ValueMapVariable<T, int32_t> IntExtVar;
0461 typedef ValueMapVariable<T, uint32_t> UIntExtVar;
0462 typedef ValueMapVariable<T, int64_t> Int64ExtVar;
0463 typedef ValueMapVariable<T, uint64_t> UInt64ExtVar;
0464 typedef ValueMapVariable<T, float> FloatExtVar;
0465 typedef ValueMapVariable<T, double, float> DoubleExtVar;
0466 typedef ValueMapVariable<T, bool> BoolExtVar;
0467 typedef ValueMapVariable<T, int, uint8_t> UInt8ExtVar;
0468 typedef ValueMapVariable<T, int, int16_t> Int16ExtVar;
0469 typedef ValueMapVariable<T, int, uint16_t> UInt16ExtVar;
0470 std::vector<std::unique_ptr<ExtVariable<T>>> extvars_;
0471 std::vector<std::unique_ptr<ExtVariable<T>>> typedextvars_;
0472 };
0473
0474 template <typename T, typename V>
0475 class SimpleTypedExternalFlatTableProducer : public SimpleFlatTableProducer<T> {
0476 public:
0477 SimpleTypedExternalFlatTableProducer(edm::ParameterSet const ¶ms) : SimpleFlatTableProducer<T>(params) {
0478 edm::ParameterSet const &extvarsPSet = params.getParameter<edm::ParameterSet>("externalTypedVariables");
0479 for (const std::string &vname : extvarsPSet.getParameterNamesForType<edm::ParameterSet>()) {
0480 const auto &varPSet = extvarsPSet.getParameter<edm::ParameterSet>(vname);
0481 const std::string &type = varPSet.getParameter<std::string>("type");
0482 if (type == "int")
0483 this->typedextvars_.push_back(
0484 std::make_unique<IntTypedExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0485 else if (type == "uint")
0486 this->typedextvars_.push_back(
0487 std::make_unique<UIntTypedExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0488 else if (type == "int64")
0489 this->typedextvars_.push_back(
0490 std::make_unique<Int64TypedExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0491 else if (type == "uint64")
0492 this->typedextvars_.push_back(
0493 std::make_unique<UInt64TypedExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0494 else if (type == "float")
0495 this->typedextvars_.push_back(
0496 std::make_unique<FloatTypedExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0497 else if (type == "double")
0498 this->typedextvars_.push_back(
0499 std::make_unique<DoubleTypedExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0500 else if (type == "uint8")
0501 this->typedextvars_.push_back(
0502 std::make_unique<UInt8TypedExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0503 else if (type == "int16")
0504 this->typedextvars_.push_back(
0505 std::make_unique<Int16TypedExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0506 else if (type == "uint16")
0507 this->typedextvars_.push_back(
0508 std::make_unique<UInt16TypedExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0509 else if (type == "bool")
0510 this->typedextvars_.push_back(
0511 std::make_unique<BoolTypedExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0512 else
0513 throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
0514 }
0515 }
0516 ~SimpleTypedExternalFlatTableProducer() override {}
0517 static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0518 edm::ParameterSetDescription desc = SimpleFlatTableProducer<T>::baseDescriptions();
0519 edm::ParameterSetDescription extvariable;
0520 extvariable.add<edm::InputTag>("src")->setComment("valuemap input collection to fill the flat table");
0521 extvariable.add<std::string>("expr")->setComment(
0522 "a function to define the content of the branch in the flat table");
0523 extvariable.add<std::string>("doc")->setComment("few words description of the branch content");
0524 extvariable.addUntracked<bool>("lazyEval", false)
0525 ->setComment("if true, can use methods of inheriting classes in `expr`. Can cause problems with threading.");
0526 extvariable.ifValue(
0527 edm::ParameterDescription<std::string>(
0528 "type", "int", true, edm::Comment("the c++ type of the branch in the flat table")),
0529 edm::allowedValues<std::string>("int", "uint", "float", "double", "uint8", "int16", "uint16", "bool"));
0530 extvariable.addOptionalNode(
0531 edm::ParameterDescription<int>(
0532 "precision", true, edm::Comment("the precision with which to store the value in the flat table")) xor
0533 edm::ParameterDescription<std::string>("precision",
0534 true,
0535 edm::Comment("the precision with which to store the value in the "
0536 "flat table, as a function of the object evaluated")),
0537 false);
0538
0539 edm::ParameterSetDescription extvariables;
0540 extvariables.setComment("a parameters set to define all variable taken form valuemap to fill the flat table");
0541 extvariables.addOptionalNode(
0542 edm::ParameterWildcard<edm::ParameterSetDescription>("*", edm::RequireZeroOrMore, true, extvariable), false);
0543 desc.addOptional<edm::ParameterSetDescription>("externalTypedVariables", extvariables);
0544
0545 descriptions.addWithDefaultLabel(desc);
0546 }
0547
0548 protected:
0549 typedef TypedValueMapVariable<T, V, StringObjectFunction<V>, int32_t> IntTypedExtVar;
0550 typedef TypedValueMapVariable<T, V, StringObjectFunction<V>, uint32_t> UIntTypedExtVar;
0551 typedef TypedValueMapVariable<T, V, StringObjectFunction<V>, int64_t> Int64TypedExtVar;
0552 typedef TypedValueMapVariable<T, V, StringObjectFunction<V>, uint64_t> UInt64TypedExtVar;
0553 typedef TypedValueMapVariable<T, V, StringObjectFunction<V>, float> FloatTypedExtVar;
0554 typedef TypedValueMapVariable<T, V, StringObjectFunction<V>, double> DoubleTypedExtVar;
0555 typedef TypedValueMapVariable<T, V, StringCutObjectSelector<V>, bool> BoolTypedExtVar;
0556 typedef TypedValueMapVariable<T, V, StringObjectFunction<V>, uint8_t> UInt8TypedExtVar;
0557 typedef TypedValueMapVariable<T, V, StringObjectFunction<V>, int16_t> Int16TypedExtVar;
0558 typedef TypedValueMapVariable<T, V, StringObjectFunction<V>, uint16_t> UInt16TypedExtVar;
0559 };
0560
0561 template <typename T>
0562 class SimpleCollectionFlatTableProducer : public SimpleFlatTableProducer<T> {
0563 public:
0564 SimpleCollectionFlatTableProducer(edm::ParameterSet const ¶ms) : SimpleFlatTableProducer<T>(params) {
0565 if (params.existsAs<edm::ParameterSet>("collectionVariables")) {
0566 edm::ParameterSet const &collectionVarsPSet = params.getParameter<edm::ParameterSet>("collectionVariables");
0567 for (const std::string &coltablename :
0568 collectionVarsPSet.getParameterNamesForType<edm::ParameterSet>()) {
0569 const auto &coltablePSet = collectionVarsPSet.getParameter<edm::ParameterSet>(coltablename);
0570 CollectionVariableTableInfo coltable;
0571 coltable.name =
0572 coltablePSet.existsAs<std::string>("name") ? coltablePSet.getParameter<std::string>("name") : coltablename;
0573 coltable.doc = coltablePSet.getParameter<std::string>("doc");
0574 coltable.useCount = coltablePSet.getParameter<bool>("useCount");
0575 coltable.useOffset = coltablePSet.getParameter<bool>("useOffset");
0576 const auto &colvarsPSet = coltablePSet.getParameter<edm::ParameterSet>("variables");
0577 for (const std::string &colvarname : colvarsPSet.getParameterNamesForType<edm::ParameterSet>()) {
0578 const auto &colvarPSet = colvarsPSet.getParameter<edm::ParameterSet>(colvarname);
0579 const std::string &type = colvarPSet.getParameter<std::string>("type");
0580 if (type == "int")
0581 coltable.colvars.push_back(std::make_unique<IntVectorVar>(colvarname, colvarPSet));
0582 else if (type == "uint")
0583 coltable.colvars.push_back(std::make_unique<UIntVectorVar>(colvarname, colvarPSet));
0584 else if (type == "int64")
0585 coltable.colvars.push_back(std::make_unique<Int64VectorVar>(colvarname, colvarPSet));
0586 else if (type == "uint64")
0587 coltable.colvars.push_back(std::make_unique<UInt64VectorVar>(colvarname, colvarPSet));
0588 else if (type == "float")
0589 coltable.colvars.push_back(std::make_unique<FloatVectorVar>(colvarname, colvarPSet));
0590 else if (type == "double")
0591 coltable.colvars.push_back(std::make_unique<DoubleVectorVar>(colvarname, colvarPSet));
0592 else if (type == "uint8")
0593 coltable.colvars.push_back(std::make_unique<UInt8VectorVar>(colvarname, colvarPSet));
0594 else if (type == "int16")
0595 coltable.colvars.push_back(std::make_unique<Int16VectorVar>(colvarname, colvarPSet));
0596 else if (type == "uint16")
0597 coltable.colvars.push_back(std::make_unique<UInt16VectorVar>(colvarname, colvarPSet));
0598 else
0599 throw cms::Exception("Configuration",
0600 "unsupported type " + type + " for variable " + colvarname + " in " + coltablename);
0601 }
0602 this->coltables.push_back(std::move(coltable));
0603 edm::stream::EDProducer<>::produces<nanoaod::FlatTable>(coltables.back().name + "Table");
0604 }
0605 }
0606 }
0607
0608 ~SimpleCollectionFlatTableProducer() override {}
0609
0610 static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0611 edm::ParameterSetDescription desc = SimpleFlatTableProducer<T>::baseDescriptions();
0612 edm::ParameterSetDescription colvariable;
0613 colvariable.add<std::string>("expr")->setComment(
0614 "a function to define the content of the branch in the flat table");
0615 colvariable.add<std::string>("doc")->setComment("few words of self documentation");
0616 colvariable.addUntracked<bool>("lazyEval", false)
0617 ->setComment("if true, can use methods of inheriting classes in `expr`. Can cause problems with threading.");
0618 colvariable.ifValue(edm::ParameterDescription<std::string>(
0619 "type", "int", true, edm::Comment("the c++ type of the branch in the flat table")),
0620 edm::allowedValues<std::string>("int", "uint", "float", "double", "uint8", "int16", "uint16"));
0621 colvariable.addOptionalNode(
0622 edm::ParameterDescription<int>(
0623 "precision", true, edm::Comment("the precision with which to store the value in the flat table")) xor
0624 edm::ParameterDescription<std::string>(
0625 "precision", true, edm::Comment("the precision with which to store the value in the flat table")),
0626 false);
0627 edm::ParameterSetDescription colvariables;
0628 colvariables.setComment("a parameters set to define all variable to fill the flat table");
0629 colvariables.addNode(
0630 edm::ParameterWildcard<edm::ParameterSetDescription>("*", edm::RequireAtLeastOne, true, colvariable));
0631
0632 edm::ParameterSetDescription coltable;
0633 coltable.addOptional<std::string>("name")->setComment(
0634 "name of the branch in the flat table containing flatten collections of variables");
0635 coltable.add<std::string>("doc")->setComment(
0636 "few words description of the table containing flatten collections of variables");
0637 coltable.add<bool>("useCount", true)
0638 ->setComment("whether to use count for the main table to index table with flatten collections of variables");
0639 coltable.add<bool>("useOffset", false)
0640 ->setComment("whether to use offset for the main table to index table with flatten collections of variables");
0641 coltable.add<edm::ParameterSetDescription>("variables", colvariables);
0642
0643 edm::ParameterSetDescription coltables;
0644 coltables.setComment("a parameters set to define variables to be flatten to fill the table");
0645 coltables.addOptionalNode(
0646 edm::ParameterWildcard<edm::ParameterSetDescription>("*", edm::RequireZeroOrMore, true, coltable), false);
0647 desc.addOptional<edm::ParameterSetDescription>("collectionVariables", coltables);
0648
0649 descriptions.addWithDefaultLabel(desc);
0650 }
0651
0652 void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override {
0653
0654 edm::Handle<edm::View<T>> prod;
0655 iEvent.getByToken(this->src_, prod);
0656
0657 std::vector<const T *> selobjs;
0658 std::vector<edm::Ptr<T>> selptrs;
0659 if (prod.isValid() || !(this->skipNonExistingSrc_)) {
0660 if (this->singleton_) {
0661 assert(prod->size() == 1);
0662 selobjs.push_back(&(*prod)[0]);
0663 if (!this->extvars_.empty() || !this->typedextvars_.empty())
0664 selptrs.emplace_back(prod->ptrAt(0));
0665 } else {
0666 for (unsigned int i = 0, n = prod->size(); i < n; ++i) {
0667 const auto &obj = (*prod)[i];
0668 if (this->cut_(obj)) {
0669 selobjs.push_back(&obj);
0670 if (!this->extvars_.empty() || !this->typedextvars_.empty())
0671 selptrs.emplace_back(prod->ptrAt(i));
0672 }
0673 if (selobjs.size() >= this->maxLen_)
0674 break;
0675 }
0676 }
0677 }
0678
0679 auto out = std::make_unique<nanoaod::FlatTable>(selobjs.size(), this->name_, this->singleton_, this->extension_);
0680 for (const auto &var : this->vars_)
0681 var->fill(selobjs, *out);
0682 for (const auto &var : this->extvars_)
0683 var->fill(iEvent, selptrs, *out);
0684 for (const auto &var : this->typedextvars_)
0685 var->fill(iEvent, selptrs, *out);
0686
0687
0688 for (const auto &coltable : this->coltables) {
0689 std::unique_ptr<std::vector<unsigned int>> counts = coltable.colvars[0]->getCounts(selobjs);
0690
0691 unsigned int coltablesize = 0;
0692 for (auto const &count : *counts)
0693 coltablesize += count;
0694
0695 if (coltable.useCount)
0696 out->template addColumn<uint16_t>("n" + coltable.name, *counts, "counts for " + coltable.name);
0697
0698 if (coltable.useOffset) {
0699 unsigned int offset = 0;
0700 std::vector<unsigned int> offsets;
0701 for (auto const &count : *counts) {
0702 offsets.push_back(offset);
0703 offset += count;
0704 }
0705 out->template addColumn<uint16_t>("o" + coltable.name, offsets, "offsets for " + coltable.name);
0706 }
0707
0708 std::unique_ptr<nanoaod::FlatTable> outcoltable =
0709 std::make_unique<nanoaod::FlatTable>(coltablesize, coltable.name, false, false);
0710 for (const auto &colvar : coltable.colvars) {
0711 colvar->fill(selobjs, *outcoltable);
0712 }
0713 outcoltable->setDoc(coltable.doc);
0714 iEvent.put(std::move(outcoltable), coltable.name + "Table");
0715 }
0716
0717
0718 out->setDoc(this->doc_);
0719 iEvent.put(std::move(out));
0720 }
0721
0722 protected:
0723 template <typename R>
0724 using VectorVar =
0725 FuncCollectionVariable<T, TypedStringObjectMethodCaller<T, std::vector<R>>, StringObjectFunction<T>, R>;
0726
0727 using IntVectorVar = VectorVar<int32_t>;
0728 using UIntVectorVar = VectorVar<uint32_t>;
0729 using Int64VectorVar = VectorVar<int64_t>;
0730 using UInt64VectorVar = VectorVar<uint64_t>;
0731 using FloatVectorVar = VectorVar<float>;
0732 using DoubleVectorVar = VectorVar<double>;
0733 using UInt8VectorVar = VectorVar<uint8_t>;
0734 using Int16VectorVar = VectorVar<int16_t>;
0735 using UInt16VectorVar = VectorVar<uint16_t>;
0736
0737 struct CollectionVariableTableInfo {
0738 std::string name;
0739 std::string doc;
0740 bool useCount;
0741 bool useOffset;
0742 std::vector<std::unique_ptr<CollectionVariable<T>>> colvars;
0743 };
0744 std::vector<CollectionVariableTableInfo> coltables;
0745 };
0746
0747 template <typename T>
0748 class BXVectorSimpleFlatTableProducer : public SimpleFlatTableProducerBase<T, BXVector<T>> {
0749 public:
0750 BXVectorSimpleFlatTableProducer(edm::ParameterSet const ¶ms)
0751 : SimpleFlatTableProducerBase<T, BXVector<T>>(params),
0752 maxLen_(params.existsAs<unsigned int>("maxLen") ? params.getParameter<unsigned int>("maxLen")
0753 : std::numeric_limits<unsigned int>::max()),
0754 cut_(params.getParameter<std::string>("cut"), false),
0755 minBX_(params.getParameter<int>("minBX")),
0756 maxBX_(params.getParameter<int>("maxBX")),
0757 alwaysWriteBXValue_(params.getParameter<bool>("alwaysWriteBXValue")),
0758 bxVarName_("bx") {
0759 edm::ParameterSet const &varsPSet = params.getParameter<edm::ParameterSet>("variables");
0760 auto varNames = varsPSet.getParameterNamesForType<edm::ParameterSet>();
0761 if (std::find(varNames.begin(), varNames.end(), bxVarName_) != varNames.end()) {
0762 throw cms::Exception("Configuration",
0763 "BXVectorSimpleFlatTableProducer already defines the " + bxVarName_ +
0764 "internally and thus you should not specify it yourself");
0765 }
0766 }
0767
0768 static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0769 edm::ParameterSetDescription desc = SimpleFlatTableProducerBase<T, BXVector<T>>::baseDescriptions();
0770 desc.add<std::string>("cut", "")->setComment(
0771 "selection on the main input collection (but selection can not be bx based)");
0772 desc.addOptional<unsigned int>("maxLen")->setComment(
0773 "define the maximum length of the input collection to put in the branch");
0774 desc.add<int>("minBX", -2)->setComment("min bx (inclusive) to include");
0775 desc.add<int>("maxBX", 2)->setComment("max bx (inclusive) to include");
0776 desc.add<bool>("alwaysWriteBXValue", true)
0777 ->setComment("always write the bx number (event when only one bx can be present, ie minBX==maxBX)");
0778 descriptions.addWithDefaultLabel(desc);
0779 }
0780
0781 std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Event &iEvent,
0782 const edm::Handle<BXVector<T>> &prod) const override {
0783 std::vector<const T *> selObjs;
0784 std::vector<int> selObjBXs;
0785
0786 if (prod.isValid() || !(this->skipNonExistingSrc_)) {
0787 const int minBX = std::max(minBX_, prod->getFirstBX());
0788 const int maxBX = std::min(maxBX_, prod->getLastBX());
0789 for (int bx = minBX; bx <= maxBX; bx++) {
0790 for (size_t objNr = 0, nrObjs = prod->size(bx); objNr < nrObjs; ++objNr) {
0791 const auto &obj = prod->at(bx, objNr);
0792 if (cut_(obj)) {
0793 selObjs.push_back(&obj);
0794 selObjBXs.push_back(bx);
0795 }
0796 if (selObjs.size() >= maxLen_)
0797 break;
0798 }
0799 }
0800 }
0801 auto out = std::make_unique<nanoaod::FlatTable>(selObjs.size(), this->name_, false, this->extension_);
0802 for (const auto &var : this->vars_)
0803 var->fill(selObjs, *out);
0804 if (alwaysWriteBXValue_ || minBX_ != maxBX_) {
0805 out->template addColumn<int16_t>(bxVarName_, selObjBXs, "BX of the L1 candidate");
0806 }
0807 return out;
0808 }
0809
0810 protected:
0811 const unsigned int maxLen_;
0812 const StringCutObjectSelector<T> cut_;
0813 const int minBX_;
0814 const int maxBX_;
0815 const bool alwaysWriteBXValue_;
0816 const std::string bxVarName_;
0817 };
0818
0819 template <typename T>
0820 class EventSingletonSimpleFlatTableProducer : public SimpleFlatTableProducerBase<T, T> {
0821 public:
0822 EventSingletonSimpleFlatTableProducer(edm::ParameterSet const ¶ms) : SimpleFlatTableProducerBase<T, T>(params) {}
0823
0824 ~EventSingletonSimpleFlatTableProducer() override {}
0825
0826 static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0827 edm::ParameterSetDescription desc = SimpleFlatTableProducerBase<T, T>::baseDescriptions();
0828 descriptions.addWithDefaultLabel(desc);
0829 }
0830
0831 std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Event &, const edm::Handle<T> &prod) const override {
0832 auto out = std::make_unique<nanoaod::FlatTable>(1, this->name_, true, this->extension_);
0833 std::vector<const T *> selobjs(1, prod.product());
0834 for (const auto &var : this->vars_)
0835 var->fill(selobjs, *out);
0836 return out;
0837 }
0838 };
0839
0840 template <typename T>
0841 class FirstObjectSimpleFlatTableProducer : public SimpleFlatTableProducerBase<T, edm::View<T>> {
0842 public:
0843 FirstObjectSimpleFlatTableProducer(edm::ParameterSet const ¶ms)
0844 : SimpleFlatTableProducerBase<T, edm::View<T>>(params) {}
0845
0846 ~FirstObjectSimpleFlatTableProducer() override {}
0847
0848 static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0849 edm::ParameterSetDescription desc = SimpleFlatTableProducerBase<T, edm::View<T>>::baseDescriptions();
0850 descriptions.addWithDefaultLabel(desc);
0851 }
0852
0853 std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Event &iEvent,
0854 const edm::Handle<edm::View<T>> &prod) const override {
0855 auto out = std::make_unique<nanoaod::FlatTable>(1, this->name_, true, this->extension_);
0856 std::vector<const T *> selobjs(1, &(*prod)[0]);
0857 for (const auto &var : this->vars_)
0858 var->fill(selobjs, *out);
0859 return out;
0860 }
0861 };
0862
0863
0864
0865
0866
0867 template <typename T, typename TProd>
0868 class SimpleFlatTableProducerBaseLumi
0869 : public edm::one::EDProducer<edm::EndLuminosityBlockProducer, edm::LuminosityBlockCache<int>> {
0870 public:
0871 SimpleFlatTableProducerBaseLumi(edm::ParameterSet const ¶ms)
0872 : name_(params.getParameter<std::string>("name")),
0873 doc_(params.existsAs<std::string>("doc") ? params.getParameter<std::string>("doc") : ""),
0874 extension_(params.existsAs<bool>("extension") ? params.getParameter<bool>("extension") : false),
0875 skipNonExistingSrc_(
0876
0877 params.existsAs<bool>("skipNonExistingSrc") ? params.getParameter<bool>("skipNonExistingSrc") : false),
0878 src_(consumes<TProd, edm::InLumi>(params.getParameter<edm::InputTag>("src"))) {
0879 edm::ParameterSet const &varsPSet = params.getParameter<edm::ParameterSet>("variables");
0880 for (const std::string &vname : varsPSet.getParameterNamesForType<edm::ParameterSet>()) {
0881 const auto &varPSet = varsPSet.getParameter<edm::ParameterSet>(vname);
0882 const std::string &type = varPSet.getParameter<std::string>("type");
0883 if (type == "int")
0884 vars_.push_back(std::make_unique<IntVar>(vname, varPSet));
0885 else if (type == "float")
0886 vars_.push_back(std::make_unique<FloatVar>(vname, varPSet));
0887 else if (type == "uint8")
0888 vars_.push_back(std::make_unique<UInt8Var>(vname, varPSet));
0889 else if (type == "bool")
0890 vars_.push_back(std::make_unique<BoolVar>(vname, varPSet));
0891 else
0892 throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
0893 }
0894
0895 produces<nanoaod::FlatTable, edm::Transition::EndLuminosityBlock>();
0896 }
0897
0898 ~SimpleFlatTableProducerBaseLumi() override {}
0899
0900 std::shared_ptr<int> globalBeginLuminosityBlock(edm::LuminosityBlock const &,
0901 edm::EventSetup const &) const override {
0902 return nullptr;
0903 }
0904
0905 void globalEndLuminosityBlock(edm::LuminosityBlock const &, edm::EventSetup const &) override {}
0906
0907
0908 virtual std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::LuminosityBlock &iLumi,
0909 const edm::Handle<TProd> &prod) const = 0;
0910
0911 void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override {
0912
0913 }
0914
0915 void endLuminosityBlockProduce(edm::LuminosityBlock &iLumi, const edm::EventSetup &iSetup) final {
0916 edm::Handle<TProd> src;
0917 iLumi.getByToken(src_, src);
0918
0919 std::unique_ptr<nanoaod::FlatTable> out = fillTable(iLumi, src);
0920 out->setDoc(doc_);
0921
0922 iLumi.put(std::move(out));
0923 }
0924
0925 protected:
0926 const std::string name_;
0927 const std::string doc_;
0928 const bool extension_;
0929 const bool skipNonExistingSrc_;
0930 const edm::EDGetTokenT<TProd> src_;
0931
0932 typedef FuncVariable<T, StringObjectFunction<T>, int> IntVar;
0933 typedef FuncVariable<T, StringObjectFunction<T>, float> FloatVar;
0934 typedef FuncVariable<T, StringObjectFunction<T>, uint8_t> UInt8Var;
0935 typedef FuncVariable<T, StringCutObjectSelector<T>, bool> BoolVar;
0936 std::vector<std::unique_ptr<Variable<T>>> vars_;
0937 };
0938
0939
0940 template <typename T>
0941 class LumiSingletonSimpleFlatTableProducer : public SimpleFlatTableProducerBaseLumi<T, T> {
0942 public:
0943 LumiSingletonSimpleFlatTableProducer(edm::ParameterSet const ¶ms)
0944 : SimpleFlatTableProducerBaseLumi<T, T>(params) {}
0945
0946 ~LumiSingletonSimpleFlatTableProducer() override {}
0947
0948 static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0949 edm::ParameterSetDescription desc = SimpleFlatTableProducerBase<T, T>::baseDescriptions();
0950 descriptions.addWithDefaultLabel(desc);
0951 }
0952
0953 std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::LuminosityBlock &,
0954 const edm::Handle<T> &prod) const override {
0955 auto out = std::make_unique<nanoaod::FlatTable>(1, this->name_, true, this->extension_);
0956 std::vector<const T *> selobjs(1, prod.product());
0957 for (const auto &var : this->vars_)
0958 var->fill(selobjs, *out);
0959 return out;
0960 }
0961 };
0962
0963
0964 template <typename T, typename TProd>
0965 class LumiSimpleFlatTableProducer : public SimpleFlatTableProducerBaseLumi<T, TProd> {
0966 public:
0967 LumiSimpleFlatTableProducer(edm::ParameterSet const ¶ms)
0968 : SimpleFlatTableProducerBaseLumi<T, TProd>(params),
0969 maxLen_(params.existsAs<unsigned int>("maxLen") ? params.getParameter<unsigned int>("maxLen")
0970 : std::numeric_limits<unsigned int>::max()),
0971 cut_(params.existsAs<std::string>("cut") ? params.getParameter<std::string>("cut") : "", true) {}
0972
0973 ~LumiSimpleFlatTableProducer() override {}
0974
0975 static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0976 edm::ParameterSetDescription desc = SimpleFlatTableProducerBase<T, TProd>::baseDescriptions();
0977 desc.addOptional<unsigned int>("maxLen")->setComment(
0978 "define the maximum length of the input collection to put in the branch");
0979 descriptions.addWithDefaultLabel(desc);
0980 }
0981
0982 std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::LuminosityBlock &iLumi,
0983 const edm::Handle<TProd> &prod) const override {
0984 std::vector<const T *> selobjs;
0985 if (prod.isValid() || !(this->skipNonExistingSrc_)) {
0986 for (unsigned int i = 0, n = prod->size(); i < n; ++i) {
0987 const auto &obj = (*prod)[i];
0988 if (cut_(obj)) {
0989 selobjs.push_back(&obj);
0990 }
0991 if (selobjs.size() >= maxLen_)
0992 break;
0993 }
0994 }
0995 auto out = std::make_unique<nanoaod::FlatTable>(selobjs.size(), this->name_, false, this->extension_);
0996 for (const auto &var : this->vars_)
0997 var->fill(selobjs, *out);
0998 return out;
0999 }
1000
1001 protected:
1002 const unsigned int maxLen_;
1003 const StringCutObjectSelector<T> cut_;
1004 };
1005
1006
1007
1008
1009
1010 template <typename T, typename TProd>
1011 class SimpleFlatTableProducerBaseRun : public edm::one::EDProducer<edm::EndRunProducer, edm::RunCache<int>> {
1012 public:
1013 SimpleFlatTableProducerBaseRun(edm::ParameterSet const ¶ms)
1014 : name_(params.getParameter<std::string>("name")),
1015 doc_(params.existsAs<std::string>("doc") ? params.getParameter<std::string>("doc") : ""),
1016 extension_(params.existsAs<bool>("extension") ? params.getParameter<bool>("extension") : false),
1017 skipNonExistingSrc_(
1018
1019 params.existsAs<bool>("skipNonExistingSrc") ? params.getParameter<bool>("skipNonExistingSrc") : false),
1020 src_(consumes<TProd, edm::InRun>(params.getParameter<edm::InputTag>("src"))) {
1021 edm::ParameterSet const &varsPSet = params.getParameter<edm::ParameterSet>("variables");
1022 for (const std::string &vname : varsPSet.getParameterNamesForType<edm::ParameterSet>()) {
1023 const auto &varPSet = varsPSet.getParameter<edm::ParameterSet>(vname);
1024 const std::string &type = varPSet.getParameter<std::string>("type");
1025 if (type == "int")
1026 vars_.push_back(std::make_unique<IntVar>(vname, varPSet));
1027 else if (type == "float")
1028 vars_.push_back(std::make_unique<FloatVar>(vname, varPSet));
1029 else if (type == "uint8")
1030 vars_.push_back(std::make_unique<UInt8Var>(vname, varPSet));
1031 else if (type == "bool")
1032 vars_.push_back(std::make_unique<BoolVar>(vname, varPSet));
1033 else
1034 throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
1035 }
1036
1037 produces<nanoaod::FlatTable, edm::Transition::EndRun>();
1038 }
1039
1040 ~SimpleFlatTableProducerBaseRun() override {}
1041
1042 std::shared_ptr<int> globalBeginRun(edm::Run const &, edm::EventSetup const &) const override { return nullptr; }
1043
1044 void globalEndRun(edm::Run const &, edm::EventSetup const &) override {}
1045
1046
1047 virtual std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Run &iRun, const edm::Handle<TProd> &prod) const = 0;
1048
1049 void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override {
1050
1051 }
1052
1053 void endRunProduce(edm::Run &iRun, const edm::EventSetup &iSetup) final {
1054 edm::Handle<TProd> src;
1055 iRun.getByToken(src_, src);
1056
1057 std::unique_ptr<nanoaod::FlatTable> out = fillTable(iRun, src);
1058 out->setDoc(doc_);
1059
1060 iRun.put(std::move(out));
1061 }
1062
1063 protected:
1064 const std::string name_;
1065 const std::string doc_;
1066 const bool extension_;
1067 const bool skipNonExistingSrc_;
1068 const edm::EDGetTokenT<TProd> src_;
1069
1070 typedef FuncVariable<T, StringObjectFunction<T>, int> IntVar;
1071 typedef FuncVariable<T, StringObjectFunction<T>, float> FloatVar;
1072 typedef FuncVariable<T, StringObjectFunction<T>, uint8_t> UInt8Var;
1073 typedef FuncVariable<T, StringCutObjectSelector<T>, bool> BoolVar;
1074 std::vector<std::unique_ptr<Variable<T>>> vars_;
1075 };
1076
1077
1078 template <typename T>
1079 class RunSingletonSimpleFlatTableProducer : public SimpleFlatTableProducerBaseRun<T, T> {
1080 public:
1081 RunSingletonSimpleFlatTableProducer(edm::ParameterSet const ¶ms) : SimpleFlatTableProducerBaseRun<T, T>(params) {}
1082
1083 ~RunSingletonSimpleFlatTableProducer() override {}
1084
1085 std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Run &, const edm::Handle<T> &prod) const override {
1086 auto out = std::make_unique<nanoaod::FlatTable>(1, this->name_, true, this->extension_);
1087 std::vector<const T *> selobjs(1, prod.product());
1088 for (const auto &var : this->vars_)
1089 var->fill(selobjs, *out);
1090 return out;
1091 }
1092 };
1093
1094
1095 template <typename T, typename TProd>
1096 class RunSimpleFlatTableProducer : public SimpleFlatTableProducerBaseRun<T, TProd> {
1097 public:
1098 RunSimpleFlatTableProducer(edm::ParameterSet const ¶ms)
1099 : SimpleFlatTableProducerBaseRun<T, TProd>(params),
1100 maxLen_(params.existsAs<unsigned int>("maxLen") ? params.getParameter<unsigned int>("maxLen")
1101 : std::numeric_limits<unsigned int>::max()),
1102 cut_(params.existsAs<std::string>("cut") ? params.getParameter<std::string>("cut") : "", true) {}
1103
1104 ~RunSimpleFlatTableProducer() override {}
1105
1106 std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Run &iRun, const edm::Handle<TProd> &prod) const override {
1107 std::vector<const T *> selobjs;
1108 if (prod.isValid() || !(this->skipNonExistingSrc_)) {
1109 for (unsigned int i = 0, n = prod->size(); i < n; ++i) {
1110 const auto &obj = (*prod)[i];
1111 if (cut_(obj)) {
1112 selobjs.push_back(&obj);
1113 }
1114 if (selobjs.size() >= maxLen_)
1115 break;
1116 }
1117 }
1118 auto out = std::make_unique<nanoaod::FlatTable>(selobjs.size(), this->name_, false, this->extension_);
1119 for (const auto &var : this->vars_)
1120 var->fill(selobjs, *out);
1121 return out;
1122 }
1123
1124 protected:
1125 const unsigned int maxLen_;
1126 const StringCutObjectSelector<T> cut_;
1127 };