File indexing completed on 2024-04-25 02:14:03
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
0018 #include <memory>
0019 #include <vector>
0020
0021
0022 class VariableBase {
0023 public:
0024 VariableBase(const std::string &aname, const edm::ParameterSet &cfg)
0025 : name_(aname),
0026 doc_(cfg.getParameter<std::string>("doc")),
0027 precision_(cfg.existsAs<int>("precision") ? cfg.getParameter<int>("precision")
0028 : (cfg.existsAs<std::string>("precision") ? -2 : -1)) {}
0029 virtual ~VariableBase() {}
0030 const std::string &name() const { return name_; }
0031
0032 protected:
0033 std::string name_, doc_;
0034 int precision_;
0035 };
0036
0037
0038 template <typename ObjType>
0039 class Variable : public VariableBase {
0040 public:
0041 Variable(const std::string &aname, const edm::ParameterSet &cfg) : VariableBase(aname, cfg) {}
0042 virtual void fill(std::vector<const ObjType *> &selobjs, nanoaod::FlatTable &out) const = 0;
0043 };
0044
0045 template <typename ObjType, typename StringFunctor, typename ValType>
0046 class FuncVariable : public Variable<ObjType> {
0047 public:
0048 FuncVariable(const std::string &aname, const edm::ParameterSet &cfg)
0049 : Variable<ObjType>(aname, cfg),
0050 func_(cfg.getParameter<std::string>("expr"), cfg.getUntrackedParameter<bool>("lazyEval")),
0051 precisionFunc_(cfg.existsAs<std::string>("precision") ? cfg.getParameter<std::string>("precision") : "23",
0052 cfg.getUntrackedParameter<bool>("lazyEval")) {}
0053 ~FuncVariable() override {}
0054
0055 void fill(std::vector<const ObjType *> &selobjs, nanoaod::FlatTable &out) const override {
0056 std::vector<ValType> vals(selobjs.size());
0057 for (unsigned int i = 0, n = vals.size(); i < n; ++i) {
0058 vals[i] = func_(*selobjs[i]);
0059 if constexpr (std::is_same<ValType, float>()) {
0060 if (this->precision_ == -2) {
0061 auto prec = precisionFunc_(*selobjs[i]);
0062 if (prec > 0) {
0063 vals[i] = MiniFloatConverter::reduceMantissaToNbitsRounding(vals[i], prec);
0064 }
0065 }
0066 }
0067 }
0068 out.template addColumn<ValType>(this->name_, vals, this->doc_, this->precision_);
0069 }
0070
0071 protected:
0072 StringFunctor func_;
0073 StringFunctor precisionFunc_;
0074 };
0075
0076
0077 template <typename ObjType>
0078 class ExtVariable : public VariableBase {
0079 public:
0080 ExtVariable(const std::string &aname, const edm::ParameterSet &cfg) : VariableBase(aname, cfg) {}
0081 virtual void fill(const edm::Event &iEvent,
0082 std::vector<edm::Ptr<ObjType>> selptrs,
0083 nanoaod::FlatTable &out) const = 0;
0084 };
0085
0086 template <typename ObjType, typename TIn, typename ValType = TIn>
0087 class ValueMapVariableBase : public ExtVariable<ObjType> {
0088 public:
0089 ValueMapVariableBase(const std::string &aname,
0090 const edm::ParameterSet &cfg,
0091 edm::ConsumesCollector &&cc,
0092 bool skipNonExistingSrc = false)
0093 : ExtVariable<ObjType>(aname, cfg),
0094 skipNonExistingSrc_(skipNonExistingSrc),
0095 token_(cc.consumes<edm::ValueMap<TIn>>(cfg.getParameter<edm::InputTag>("src"))) {}
0096 virtual ValType eval(const edm::Handle<edm::ValueMap<TIn>> &vmap, const edm::Ptr<ObjType> &op) const = 0;
0097 void fill(const edm::Event &iEvent, std::vector<edm::Ptr<ObjType>> selptrs, nanoaod::FlatTable &out) const override {
0098 edm::Handle<edm::ValueMap<TIn>> vmap;
0099 iEvent.getByToken(token_, vmap);
0100 std::vector<ValType> vals;
0101 if (vmap.isValid() || !skipNonExistingSrc_) {
0102 vals.resize(selptrs.size());
0103 for (unsigned int i = 0, n = vals.size(); i < n; ++i) {
0104
0105 vals[i] = this->eval(vmap, selptrs[i]);
0106 }
0107 }
0108 out.template addColumn<ValType>(this->name_, vals, this->doc_, this->precision_);
0109 }
0110
0111 protected:
0112 const bool skipNonExistingSrc_;
0113 edm::EDGetTokenT<edm::ValueMap<TIn>> token_;
0114 };
0115
0116 template <typename ObjType, typename TIn, typename ValType = TIn>
0117 class ValueMapVariable : public ValueMapVariableBase<ObjType, TIn, ValType> {
0118 public:
0119 ValueMapVariable(const std::string &aname,
0120 const edm::ParameterSet &cfg,
0121 edm::ConsumesCollector &&cc,
0122 bool skipNonExistingSrc = false)
0123 : ValueMapVariableBase<ObjType, TIn, ValType>(aname, cfg, std::move(cc), skipNonExistingSrc) {}
0124 ValType eval(const edm::Handle<edm::ValueMap<TIn>> &vmap, const edm::Ptr<ObjType> &op) const override {
0125 ValType val = (*vmap)[op];
0126 return val;
0127 }
0128 };
0129
0130 template <typename ObjType, typename TIn, typename StringFunctor, typename ValType>
0131 class TypedValueMapVariable : public ValueMapVariableBase<ObjType, TIn, ValType> {
0132 public:
0133 TypedValueMapVariable(const std::string &aname,
0134 const edm::ParameterSet &cfg,
0135 edm::ConsumesCollector &&cc,
0136 bool skipNonExistingSrc = false)
0137 : ValueMapVariableBase<ObjType, TIn, ValType>(aname, cfg, std::move(cc), skipNonExistingSrc),
0138 func_(cfg.getParameter<std::string>("expr"), true),
0139 precisionFunc_(cfg.existsAs<std::string>("precision") ? cfg.getParameter<std::string>("precision") : "23",
0140 true) {}
0141
0142 ValType eval(const edm::Handle<edm::ValueMap<TIn>> &vmap, const edm::Ptr<ObjType> &op) const override {
0143 ValType val = func_((*vmap)[op]);
0144 if constexpr (std::is_same<ValType, float>()) {
0145 if (this->precision_ == -2) {
0146 auto prec = precisionFunc_(*op);
0147 if (prec > 0) {
0148 val = MiniFloatConverter::reduceMantissaToNbitsRounding(val, prec);
0149 }
0150 }
0151 }
0152 return val;
0153 }
0154
0155 protected:
0156 StringFunctor func_;
0157 StringObjectFunction<ObjType> precisionFunc_;
0158 };
0159
0160
0161
0162
0163
0164 template <typename T, typename TProd>
0165 class SimpleFlatTableProducerBase : public edm::stream::EDProducer<> {
0166 public:
0167 SimpleFlatTableProducerBase(edm::ParameterSet const ¶ms)
0168 : name_(params.getParameter<std::string>("name")),
0169 doc_(params.getParameter<std::string>("doc")),
0170 extension_(params.getParameter<bool>("extension")),
0171 skipNonExistingSrc_(params.getParameter<bool>("skipNonExistingSrc")),
0172 src_(consumes<TProd>(params.getParameter<edm::InputTag>("src"))) {
0173 edm::ParameterSet const &varsPSet = params.getParameter<edm::ParameterSet>("variables");
0174 for (const std::string &vname : varsPSet.getParameterNamesForType<edm::ParameterSet>()) {
0175 const auto &varPSet = varsPSet.getParameter<edm::ParameterSet>(vname);
0176 const std::string &type = varPSet.getParameter<std::string>("type");
0177 if (type == "int")
0178 vars_.push_back(std::make_unique<IntVar>(vname, varPSet));
0179 else if (type == "uint")
0180 vars_.push_back(std::make_unique<UIntVar>(vname, varPSet));
0181 else if (type == "float")
0182 vars_.push_back(std::make_unique<FloatVar>(vname, varPSet));
0183 else if (type == "double")
0184 vars_.push_back(std::make_unique<DoubleVar>(vname, varPSet));
0185 else if (type == "uint8")
0186 vars_.push_back(std::make_unique<UInt8Var>(vname, varPSet));
0187 else if (type == "int16")
0188 vars_.push_back(std::make_unique<Int16Var>(vname, varPSet));
0189 else if (type == "uint16")
0190 vars_.push_back(std::make_unique<UInt16Var>(vname, varPSet));
0191 else if (type == "bool")
0192 vars_.push_back(std::make_unique<BoolVar>(vname, varPSet));
0193 else
0194 throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
0195 }
0196
0197 produces<nanoaod::FlatTable>();
0198 }
0199
0200 ~SimpleFlatTableProducerBase() override {}
0201
0202 static edm::ParameterSetDescription baseDescriptions() {
0203 edm::ParameterSetDescription desc;
0204 std::string classname = ClassName<T>::name();
0205 desc.add<std::string>("name")->setComment("name of the branch in the flat table output for " + classname);
0206 desc.add<std::string>("doc", "")->setComment("few words of self documentation");
0207 desc.add<bool>("extension", false)->setComment("whether or not to extend an existing same table");
0208 desc.add<bool>("skipNonExistingSrc", false)
0209 ->setComment("whether or not to skip producing the table on absent input product");
0210 desc.add<edm::InputTag>("src")->setComment("input collection to fill the flat table");
0211
0212 edm::ParameterSetDescription variable;
0213 variable.add<std::string>("expr")->setComment("a function to define the content of the branch in the flat table");
0214 variable.add<std::string>("doc")->setComment("few words description of the branch content");
0215 variable.addUntracked<bool>("lazyEval", false)
0216 ->setComment("if true, can use methods of inheriting classes in `expr`. Can cause problems with threading.");
0217 variable.ifValue(
0218 edm::ParameterDescription<std::string>(
0219 "type", "int", true, edm::Comment("the c++ type of the branch in the flat table")),
0220 edm::allowedValues<std::string>("int", "uint", "float", "double", "uint8", "int16", "uint16", "bool"));
0221 variable.addOptionalNode(
0222 edm::ParameterDescription<int>(
0223 "precision", true, edm::Comment("the precision with which to store the value in the flat table")) xor
0224 edm::ParameterDescription<std::string>(
0225 "precision", true, edm::Comment("the precision with which to store the value in the flat table")),
0226 false);
0227
0228 edm::ParameterSetDescription variables;
0229 variables.setComment("a parameters set to define all variable to fill the flat table");
0230 variables.addNode(
0231 edm::ParameterWildcard<edm::ParameterSetDescription>("*", edm::RequireZeroOrMore, true, variable));
0232 desc.add<edm::ParameterSetDescription>("variables", variables);
0233
0234 return desc;
0235 }
0236
0237 virtual std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Event &iEvent,
0238 const edm::Handle<TProd> &prod) const = 0;
0239
0240 void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override {
0241 edm::Handle<TProd> src;
0242 iEvent.getByToken(src_, src);
0243
0244 std::unique_ptr<nanoaod::FlatTable> out = fillTable(iEvent, src);
0245 out->setDoc(doc_);
0246
0247 iEvent.put(std::move(out));
0248 }
0249
0250 protected:
0251 const std::string name_;
0252 const std::string doc_;
0253 const bool extension_;
0254 const bool skipNonExistingSrc_;
0255 const edm::EDGetTokenT<TProd> src_;
0256
0257 typedef FuncVariable<T, StringObjectFunction<T>, int32_t> IntVar;
0258 typedef FuncVariable<T, StringObjectFunction<T>, uint32_t> UIntVar;
0259 typedef FuncVariable<T, StringObjectFunction<T>, float> FloatVar;
0260 typedef FuncVariable<T, StringObjectFunction<T>, double> DoubleVar;
0261 typedef FuncVariable<T, StringObjectFunction<T>, uint8_t> UInt8Var;
0262 typedef FuncVariable<T, StringObjectFunction<T>, int16_t> Int16Var;
0263 typedef FuncVariable<T, StringObjectFunction<T>, uint16_t> UInt16Var;
0264 typedef FuncVariable<T, StringCutObjectSelector<T>, bool> BoolVar;
0265 std::vector<std::unique_ptr<Variable<T>>> vars_;
0266 };
0267
0268 template <typename T>
0269 class SimpleFlatTableProducer : public SimpleFlatTableProducerBase<T, edm::View<T>> {
0270 public:
0271 SimpleFlatTableProducer(edm::ParameterSet const ¶ms)
0272 : SimpleFlatTableProducerBase<T, edm::View<T>>(params),
0273 singleton_(params.getParameter<bool>("singleton")),
0274 maxLen_(params.existsAs<unsigned int>("maxLen") ? params.getParameter<unsigned int>("maxLen")
0275 : std::numeric_limits<unsigned int>::max()),
0276 cut_(!singleton_ ? params.getParameter<std::string>("cut") : "",
0277 !singleton_ ? params.getUntrackedParameter<bool>("lazyEval") : false) {
0278 if (params.existsAs<edm::ParameterSet>("externalVariables")) {
0279 edm::ParameterSet const &extvarsPSet = params.getParameter<edm::ParameterSet>("externalVariables");
0280 for (const std::string &vname : extvarsPSet.getParameterNamesForType<edm::ParameterSet>()) {
0281 const auto &varPSet = extvarsPSet.getParameter<edm::ParameterSet>(vname);
0282 const std::string &type = varPSet.getParameter<std::string>("type");
0283 if (type == "int")
0284 extvars_.push_back(
0285 std::make_unique<IntExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0286 else if (type == "uint")
0287 extvars_.push_back(
0288 std::make_unique<UIntExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0289 else if (type == "float")
0290 extvars_.push_back(
0291 std::make_unique<FloatExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0292 else if (type == "double")
0293 extvars_.push_back(
0294 std::make_unique<DoubleExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0295 else if (type == "uint8")
0296 extvars_.push_back(
0297 std::make_unique<UInt8ExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0298 else if (type == "int16")
0299 extvars_.push_back(
0300 std::make_unique<Int16ExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0301 else if (type == "uint16")
0302 extvars_.push_back(
0303 std::make_unique<UInt16ExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0304 else if (type == "bool")
0305 extvars_.push_back(
0306 std::make_unique<BoolExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0307 else
0308 throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
0309 }
0310 }
0311 }
0312
0313 ~SimpleFlatTableProducer() override {}
0314
0315 static edm::ParameterSetDescription baseDescriptions() {
0316 edm::ParameterSetDescription desc = SimpleFlatTableProducerBase<T, edm::View<T>>::baseDescriptions();
0317
0318 desc.ifValue(
0319 edm::ParameterDescription<bool>(
0320 "singleton", false, true, edm::Comment("whether or not the input collection is single-element")),
0321 false >> (edm::ParameterDescription<std::string>(
0322 "cut", "", true, edm::Comment("selection on the main input collection")) and
0323 edm::ParameterDescription<bool>("lazyEval",
0324 false,
0325 false,
0326 edm::Comment("if true, can use methods of inheriting classes. Can "
0327 "cause problems when multi-threading."))) or
0328 true >> edm::EmptyGroupDescription());
0329 desc.addOptional<unsigned int>("maxLen")->setComment(
0330 "define the maximum length of the input collection to put in the branch");
0331
0332 edm::ParameterSetDescription extvariable;
0333 extvariable.add<edm::InputTag>("src")->setComment("valuemap input collection to fill the flat table");
0334 extvariable.add<std::string>("doc")->setComment("few words description of the branch content");
0335 extvariable.ifValue(
0336 edm::ParameterDescription<std::string>(
0337 "type", "int", true, edm::Comment("the c++ type of the branch in the flat table")),
0338 edm::allowedValues<std::string>("int", "uint", "float", "double", "uint8", "int16", "uint16", "bool"));
0339 extvariable.addOptionalNode(
0340 edm::ParameterDescription<int>(
0341 "precision", true, edm::Comment("the precision with which to store the value in the flat table")) xor
0342 edm::ParameterDescription<std::string>("precision",
0343 true,
0344 edm::Comment("the precision with which to store the value in the "
0345 "flat table, as a function of the object evaluated")),
0346 false);
0347
0348 edm::ParameterSetDescription extvariables;
0349 extvariables.setComment("a parameters set to define all variable taken form valuemap to fill the flat table");
0350 extvariables.addOptionalNode(
0351 edm::ParameterWildcard<edm::ParameterSetDescription>("*", edm::RequireZeroOrMore, true, extvariable), false);
0352 desc.addOptional<edm::ParameterSetDescription>("externalVariables", extvariables);
0353
0354 return desc;
0355 }
0356 static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0357 edm::ParameterSetDescription desc = SimpleFlatTableProducer<T>::baseDescriptions();
0358 descriptions.addWithDefaultLabel(desc);
0359 }
0360 std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Event &iEvent,
0361 const edm::Handle<edm::View<T>> &prod) const override {
0362 std::vector<const T *> selobjs;
0363 std::vector<edm::Ptr<T>> selptrs;
0364 if (prod.isValid() || !(this->skipNonExistingSrc_)) {
0365 if (singleton_) {
0366 assert(prod->size() == 1);
0367 selobjs.push_back(&(*prod)[0]);
0368 if (!extvars_.empty() || !typedextvars_.empty())
0369 selptrs.emplace_back(prod->ptrAt(0));
0370 } else {
0371 for (unsigned int i = 0, n = prod->size(); i < n; ++i) {
0372 const auto &obj = (*prod)[i];
0373 if (cut_(obj)) {
0374 selobjs.push_back(&obj);
0375 if (!extvars_.empty() || !typedextvars_.empty())
0376 selptrs.emplace_back(prod->ptrAt(i));
0377 }
0378 if (selobjs.size() >= maxLen_)
0379 break;
0380 }
0381 }
0382 }
0383 auto out = std::make_unique<nanoaod::FlatTable>(selobjs.size(), this->name_, singleton_, this->extension_);
0384 for (const auto &var : this->vars_)
0385 var->fill(selobjs, *out);
0386 for (const auto &var : this->extvars_)
0387 var->fill(iEvent, selptrs, *out);
0388 for (const auto &var : this->typedextvars_)
0389 var->fill(iEvent, selptrs, *out);
0390 return out;
0391 }
0392
0393 protected:
0394 bool singleton_;
0395 const unsigned int maxLen_;
0396 const StringCutObjectSelector<T> cut_;
0397
0398 typedef ValueMapVariable<T, int32_t> IntExtVar;
0399 typedef ValueMapVariable<T, uint32_t> UIntExtVar;
0400 typedef ValueMapVariable<T, float> FloatExtVar;
0401 typedef ValueMapVariable<T, double, float> DoubleExtVar;
0402 typedef ValueMapVariable<T, bool> BoolExtVar;
0403 typedef ValueMapVariable<T, int, uint8_t> UInt8ExtVar;
0404 typedef ValueMapVariable<T, int, int16_t> Int16ExtVar;
0405 typedef ValueMapVariable<T, int, uint16_t> UInt16ExtVar;
0406 std::vector<std::unique_ptr<ExtVariable<T>>> extvars_;
0407 std::vector<std::unique_ptr<ExtVariable<T>>> typedextvars_;
0408 };
0409
0410 template <typename T, typename V>
0411 class SimpleTypedExternalFlatTableProducer : public SimpleFlatTableProducer<T> {
0412 public:
0413 SimpleTypedExternalFlatTableProducer(edm::ParameterSet const ¶ms) : SimpleFlatTableProducer<T>(params) {
0414 edm::ParameterSet const &extvarsPSet = params.getParameter<edm::ParameterSet>("externalTypedVariables");
0415 for (const std::string &vname : extvarsPSet.getParameterNamesForType<edm::ParameterSet>()) {
0416 const auto &varPSet = extvarsPSet.getParameter<edm::ParameterSet>(vname);
0417 const std::string &type = varPSet.getParameter<std::string>("type");
0418 if (type == "int")
0419 this->typedextvars_.push_back(
0420 std::make_unique<IntTypedExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0421 else if (type == "uint")
0422 this->typedextvars_.push_back(
0423 std::make_unique<UIntTypedExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0424 else if (type == "float")
0425 this->typedextvars_.push_back(
0426 std::make_unique<FloatTypedExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0427 else if (type == "double")
0428 this->typedextvars_.push_back(
0429 std::make_unique<DoubleTypedExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0430 else if (type == "uint8")
0431 this->typedextvars_.push_back(
0432 std::make_unique<UInt8TypedExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0433 else if (type == "int16")
0434 this->typedextvars_.push_back(
0435 std::make_unique<Int16TypedExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0436 else if (type == "uint16")
0437 this->typedextvars_.push_back(
0438 std::make_unique<UInt16TypedExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0439 else if (type == "bool")
0440 this->typedextvars_.push_back(
0441 std::make_unique<BoolTypedExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0442 else
0443 throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
0444 }
0445 }
0446 ~SimpleTypedExternalFlatTableProducer() override {}
0447 static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0448 edm::ParameterSetDescription desc = SimpleFlatTableProducer<T>::baseDescriptions();
0449 edm::ParameterSetDescription extvariable;
0450 extvariable.add<edm::InputTag>("src")->setComment("valuemap input collection to fill the flat table");
0451 extvariable.add<std::string>("expr")->setComment(
0452 "a function to define the content of the branch in the flat table");
0453 extvariable.add<std::string>("doc")->setComment("few words description of the branch content");
0454 extvariable.addUntracked<bool>("lazyEval", false)
0455 ->setComment("if true, can use methods of inheriting classes in `expr`. Can cause problems with threading.");
0456 extvariable.ifValue(
0457 edm::ParameterDescription<std::string>(
0458 "type", "int", true, edm::Comment("the c++ type of the branch in the flat table")),
0459 edm::allowedValues<std::string>("int", "uint", "float", "double", "uint8", "int16", "uint16", "bool"));
0460 extvariable.addOptionalNode(
0461 edm::ParameterDescription<int>(
0462 "precision", true, edm::Comment("the precision with which to store the value in the flat table")) xor
0463 edm::ParameterDescription<std::string>("precision",
0464 true,
0465 edm::Comment("the precision with which to store the value in the "
0466 "flat table, as a function of the object evaluated")),
0467 false);
0468
0469 edm::ParameterSetDescription extvariables;
0470 extvariables.setComment("a parameters set to define all variable taken form valuemap to fill the flat table");
0471 extvariables.addOptionalNode(
0472 edm::ParameterWildcard<edm::ParameterSetDescription>("*", edm::RequireZeroOrMore, true, extvariable), false);
0473 desc.addOptional<edm::ParameterSetDescription>("externalTypedVariables", extvariables);
0474
0475 descriptions.addWithDefaultLabel(desc);
0476 }
0477
0478 protected:
0479 typedef TypedValueMapVariable<T, V, StringObjectFunction<V>, int32_t> IntTypedExtVar;
0480 typedef TypedValueMapVariable<T, V, StringObjectFunction<V>, uint32_t> UIntTypedExtVar;
0481 typedef TypedValueMapVariable<T, V, StringObjectFunction<V>, float> FloatTypedExtVar;
0482 typedef TypedValueMapVariable<T, V, StringObjectFunction<V>, double> DoubleTypedExtVar;
0483 typedef TypedValueMapVariable<T, V, StringCutObjectSelector<V>, bool> BoolTypedExtVar;
0484 typedef TypedValueMapVariable<T, V, StringObjectFunction<V>, uint8_t> UInt8TypedExtVar;
0485 typedef TypedValueMapVariable<T, V, StringObjectFunction<V>, int16_t> Int16TypedExtVar;
0486 typedef TypedValueMapVariable<T, V, StringObjectFunction<V>, uint16_t> UInt16TypedExtVar;
0487 };
0488
0489 template <typename T>
0490 class BXVectorSimpleFlatTableProducer : public SimpleFlatTableProducerBase<T, BXVector<T>> {
0491 public:
0492 BXVectorSimpleFlatTableProducer(edm::ParameterSet const ¶ms)
0493 : SimpleFlatTableProducerBase<T, BXVector<T>>(params),
0494 maxLen_(params.existsAs<unsigned int>("maxLen") ? params.getParameter<unsigned int>("maxLen")
0495 : std::numeric_limits<unsigned int>::max()),
0496 cut_(params.getParameter<std::string>("cut"), false),
0497 minBX_(params.getParameter<int>("minBX")),
0498 maxBX_(params.getParameter<int>("maxBX")),
0499 alwaysWriteBXValue_(params.getParameter<bool>("alwaysWriteBXValue")),
0500 bxVarName_("bx") {
0501 edm::ParameterSet const &varsPSet = params.getParameter<edm::ParameterSet>("variables");
0502 auto varNames = varsPSet.getParameterNamesForType<edm::ParameterSet>();
0503 if (std::find(varNames.begin(), varNames.end(), bxVarName_) != varNames.end()) {
0504 throw cms::Exception("Configuration",
0505 "BXVectorSimpleFlatTableProducer already defines the " + bxVarName_ +
0506 "internally and thus you should not specify it yourself");
0507 }
0508 }
0509
0510 static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0511 edm::ParameterSetDescription desc = SimpleFlatTableProducerBase<T, BXVector<T>>::baseDescriptions();
0512 desc.add<std::string>("cut", "")->setComment(
0513 "selection on the main input collection (but selection can not be bx based)");
0514 desc.addOptional<unsigned int>("maxLen")->setComment(
0515 "define the maximum length of the input collection to put in the branch");
0516 desc.add<int>("minBX", -2)->setComment("min bx (inclusive) to include");
0517 desc.add<int>("maxBX", 2)->setComment("max bx (inclusive) to include");
0518 desc.add<bool>("alwaysWriteBXValue", true)
0519 ->setComment("always write the bx number (event when only one bx can be present, ie minBX==maxBX)");
0520 descriptions.addWithDefaultLabel(desc);
0521 }
0522
0523 std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Event &iEvent,
0524 const edm::Handle<BXVector<T>> &prod) const override {
0525 std::vector<const T *> selObjs;
0526 std::vector<int> selObjBXs;
0527
0528 if (prod.isValid() || !(this->skipNonExistingSrc_)) {
0529 const int minBX = std::max(minBX_, prod->getFirstBX());
0530 const int maxBX = std::min(maxBX_, prod->getLastBX());
0531 for (int bx = minBX; bx <= maxBX; bx++) {
0532 for (size_t objNr = 0, nrObjs = prod->size(bx); objNr < nrObjs; ++objNr) {
0533 const auto &obj = prod->at(bx, objNr);
0534 if (cut_(obj)) {
0535 selObjs.push_back(&obj);
0536 selObjBXs.push_back(bx);
0537 }
0538 if (selObjs.size() >= maxLen_)
0539 break;
0540 }
0541 }
0542 }
0543 auto out = std::make_unique<nanoaod::FlatTable>(selObjs.size(), this->name_, false, this->extension_);
0544 for (const auto &var : this->vars_)
0545 var->fill(selObjs, *out);
0546 if (alwaysWriteBXValue_ || minBX_ != maxBX_) {
0547 out->template addColumn<int16_t>(bxVarName_, selObjBXs, "BX of the L1 candidate");
0548 }
0549 return out;
0550 }
0551
0552 protected:
0553 const unsigned int maxLen_;
0554 const StringCutObjectSelector<T> cut_;
0555 const int minBX_;
0556 const int maxBX_;
0557 const bool alwaysWriteBXValue_;
0558 const std::string bxVarName_;
0559 };
0560
0561 template <typename T>
0562 class EventSingletonSimpleFlatTableProducer : public SimpleFlatTableProducerBase<T, T> {
0563 public:
0564 EventSingletonSimpleFlatTableProducer(edm::ParameterSet const ¶ms) : SimpleFlatTableProducerBase<T, T>(params) {}
0565
0566 ~EventSingletonSimpleFlatTableProducer() override {}
0567
0568 static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0569 edm::ParameterSetDescription desc = SimpleFlatTableProducerBase<T, T>::baseDescriptions();
0570 descriptions.addWithDefaultLabel(desc);
0571 }
0572
0573 std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Event &, const edm::Handle<T> &prod) const override {
0574 auto out = std::make_unique<nanoaod::FlatTable>(1, this->name_, true, this->extension_);
0575 std::vector<const T *> selobjs(1, prod.product());
0576 for (const auto &var : this->vars_)
0577 var->fill(selobjs, *out);
0578 return out;
0579 }
0580 };
0581
0582 template <typename T>
0583 class FirstObjectSimpleFlatTableProducer : public SimpleFlatTableProducerBase<T, edm::View<T>> {
0584 public:
0585 FirstObjectSimpleFlatTableProducer(edm::ParameterSet const ¶ms)
0586 : SimpleFlatTableProducerBase<T, edm::View<T>>(params) {}
0587
0588 ~FirstObjectSimpleFlatTableProducer() override {}
0589
0590 static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0591 edm::ParameterSetDescription desc = SimpleFlatTableProducerBase<T, edm::View<T>>::baseDescriptions();
0592 descriptions.addWithDefaultLabel(desc);
0593 }
0594
0595 std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Event &iEvent,
0596 const edm::Handle<edm::View<T>> &prod) const override {
0597 auto out = std::make_unique<nanoaod::FlatTable>(1, this->name_, true, this->extension_);
0598 std::vector<const T *> selobjs(1, &(*prod)[0]);
0599 for (const auto &var : this->vars_)
0600 var->fill(selobjs, *out);
0601 return out;
0602 }
0603 };
0604
0605
0606
0607
0608
0609 template <typename T, typename TProd>
0610 class SimpleFlatTableProducerBaseLumi
0611 : public edm::one::EDProducer<edm::EndLuminosityBlockProducer, edm::LuminosityBlockCache<int>> {
0612 public:
0613 SimpleFlatTableProducerBaseLumi(edm::ParameterSet const ¶ms)
0614 : name_(params.getParameter<std::string>("name")),
0615 doc_(params.existsAs<std::string>("doc") ? params.getParameter<std::string>("doc") : ""),
0616 extension_(params.existsAs<bool>("extension") ? params.getParameter<bool>("extension") : false),
0617 skipNonExistingSrc_(
0618
0619 params.existsAs<bool>("skipNonExistingSrc") ? params.getParameter<bool>("skipNonExistingSrc") : false),
0620 src_(consumes<TProd, edm::InLumi>(params.getParameter<edm::InputTag>("src"))) {
0621 edm::ParameterSet const &varsPSet = params.getParameter<edm::ParameterSet>("variables");
0622 for (const std::string &vname : varsPSet.getParameterNamesForType<edm::ParameterSet>()) {
0623 const auto &varPSet = varsPSet.getParameter<edm::ParameterSet>(vname);
0624 const std::string &type = varPSet.getParameter<std::string>("type");
0625 if (type == "int")
0626 vars_.push_back(std::make_unique<IntVar>(vname, varPSet));
0627 else if (type == "float")
0628 vars_.push_back(std::make_unique<FloatVar>(vname, varPSet));
0629 else if (type == "uint8")
0630 vars_.push_back(std::make_unique<UInt8Var>(vname, varPSet));
0631 else if (type == "bool")
0632 vars_.push_back(std::make_unique<BoolVar>(vname, varPSet));
0633 else
0634 throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
0635 }
0636
0637 produces<nanoaod::FlatTable, edm::Transition::EndLuminosityBlock>();
0638 }
0639
0640 ~SimpleFlatTableProducerBaseLumi() override {}
0641
0642 std::shared_ptr<int> globalBeginLuminosityBlock(edm::LuminosityBlock const &,
0643 edm::EventSetup const &) const override {
0644 return nullptr;
0645 }
0646
0647 void globalEndLuminosityBlock(edm::LuminosityBlock const &, edm::EventSetup const &) override {}
0648
0649
0650 virtual std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::LuminosityBlock &iLumi,
0651 const edm::Handle<TProd> &prod) const = 0;
0652
0653 void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override {
0654
0655 }
0656
0657 void endLuminosityBlockProduce(edm::LuminosityBlock &iLumi, const edm::EventSetup &iSetup) final {
0658 edm::Handle<TProd> src;
0659 iLumi.getByToken(src_, src);
0660
0661 std::unique_ptr<nanoaod::FlatTable> out = fillTable(iLumi, src);
0662 out->setDoc(doc_);
0663
0664 iLumi.put(std::move(out));
0665 }
0666
0667 protected:
0668 const std::string name_;
0669 const std::string doc_;
0670 const bool extension_;
0671 const bool skipNonExistingSrc_;
0672 const edm::EDGetTokenT<TProd> src_;
0673
0674 typedef FuncVariable<T, StringObjectFunction<T>, int> IntVar;
0675 typedef FuncVariable<T, StringObjectFunction<T>, float> FloatVar;
0676 typedef FuncVariable<T, StringObjectFunction<T>, uint8_t> UInt8Var;
0677 typedef FuncVariable<T, StringCutObjectSelector<T>, bool> BoolVar;
0678 std::vector<std::unique_ptr<Variable<T>>> vars_;
0679 };
0680
0681
0682 template <typename T>
0683 class LumiSingletonSimpleFlatTableProducer : public SimpleFlatTableProducerBaseLumi<T, T> {
0684 public:
0685 LumiSingletonSimpleFlatTableProducer(edm::ParameterSet const ¶ms)
0686 : SimpleFlatTableProducerBaseLumi<T, T>(params) {}
0687
0688 ~LumiSingletonSimpleFlatTableProducer() override {}
0689
0690 static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0691 edm::ParameterSetDescription desc = SimpleFlatTableProducerBase<T, T>::baseDescriptions();
0692 descriptions.addWithDefaultLabel(desc);
0693 }
0694
0695 std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::LuminosityBlock &,
0696 const edm::Handle<T> &prod) const override {
0697 auto out = std::make_unique<nanoaod::FlatTable>(1, this->name_, true, this->extension_);
0698 std::vector<const T *> selobjs(1, prod.product());
0699 for (const auto &var : this->vars_)
0700 var->fill(selobjs, *out);
0701 return out;
0702 }
0703 };
0704
0705
0706 template <typename T, typename TProd>
0707 class LumiSimpleFlatTableProducer : public SimpleFlatTableProducerBaseLumi<T, TProd> {
0708 public:
0709 LumiSimpleFlatTableProducer(edm::ParameterSet const ¶ms)
0710 : SimpleFlatTableProducerBaseLumi<T, TProd>(params),
0711 maxLen_(params.existsAs<unsigned int>("maxLen") ? params.getParameter<unsigned int>("maxLen")
0712 : std::numeric_limits<unsigned int>::max()),
0713 cut_(params.existsAs<std::string>("cut") ? params.getParameter<std::string>("cut") : "", true) {}
0714
0715 ~LumiSimpleFlatTableProducer() override {}
0716
0717 static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0718 edm::ParameterSetDescription desc = SimpleFlatTableProducerBase<T, TProd>::baseDescriptions();
0719 desc.addOptional<unsigned int>("maxLen")->setComment(
0720 "define the maximum length of the input collection to put in the branch");
0721 descriptions.addWithDefaultLabel(desc);
0722 }
0723
0724 std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::LuminosityBlock &iLumi,
0725 const edm::Handle<TProd> &prod) const override {
0726 std::vector<const T *> selobjs;
0727 if (prod.isValid() || !(this->skipNonExistingSrc_)) {
0728 for (unsigned int i = 0, n = prod->size(); i < n; ++i) {
0729 const auto &obj = (*prod)[i];
0730 if (cut_(obj)) {
0731 selobjs.push_back(&obj);
0732 }
0733 if (selobjs.size() >= maxLen_)
0734 break;
0735 }
0736 }
0737 auto out = std::make_unique<nanoaod::FlatTable>(selobjs.size(), this->name_, false, this->extension_);
0738 for (const auto &var : this->vars_)
0739 var->fill(selobjs, *out);
0740 return out;
0741 }
0742
0743 protected:
0744 const unsigned int maxLen_;
0745 const StringCutObjectSelector<T> cut_;
0746 };
0747
0748
0749
0750
0751
0752 template <typename T, typename TProd>
0753 class SimpleFlatTableProducerBaseRun : public edm::one::EDProducer<edm::EndRunProducer, edm::RunCache<int>> {
0754 public:
0755 SimpleFlatTableProducerBaseRun(edm::ParameterSet const ¶ms)
0756 : name_(params.getParameter<std::string>("name")),
0757 doc_(params.existsAs<std::string>("doc") ? params.getParameter<std::string>("doc") : ""),
0758 extension_(params.existsAs<bool>("extension") ? params.getParameter<bool>("extension") : false),
0759 skipNonExistingSrc_(
0760
0761 params.existsAs<bool>("skipNonExistingSrc") ? params.getParameter<bool>("skipNonExistingSrc") : false),
0762 src_(consumes<TProd, edm::InRun>(params.getParameter<edm::InputTag>("src"))) {
0763 edm::ParameterSet const &varsPSet = params.getParameter<edm::ParameterSet>("variables");
0764 for (const std::string &vname : varsPSet.getParameterNamesForType<edm::ParameterSet>()) {
0765 const auto &varPSet = varsPSet.getParameter<edm::ParameterSet>(vname);
0766 const std::string &type = varPSet.getParameter<std::string>("type");
0767 if (type == "int")
0768 vars_.push_back(std::make_unique<IntVar>(vname, varPSet));
0769 else if (type == "float")
0770 vars_.push_back(std::make_unique<FloatVar>(vname, varPSet));
0771 else if (type == "uint8")
0772 vars_.push_back(std::make_unique<UInt8Var>(vname, varPSet));
0773 else if (type == "bool")
0774 vars_.push_back(std::make_unique<BoolVar>(vname, varPSet));
0775 else
0776 throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
0777 }
0778
0779 produces<nanoaod::FlatTable, edm::Transition::EndRun>();
0780 }
0781
0782 ~SimpleFlatTableProducerBaseRun() override {}
0783
0784 std::shared_ptr<int> globalBeginRun(edm::Run const &, edm::EventSetup const &) const override { return nullptr; }
0785
0786 void globalEndRun(edm::Run const &, edm::EventSetup const &) override {}
0787
0788
0789 virtual std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Run &iRun, const edm::Handle<TProd> &prod) const = 0;
0790
0791 void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override {
0792
0793 }
0794
0795 void endRunProduce(edm::Run &iRun, const edm::EventSetup &iSetup) final {
0796 edm::Handle<TProd> src;
0797 iRun.getByToken(src_, src);
0798
0799 std::unique_ptr<nanoaod::FlatTable> out = fillTable(iRun, src);
0800 out->setDoc(doc_);
0801
0802 iRun.put(std::move(out));
0803 }
0804
0805 protected:
0806 const std::string name_;
0807 const std::string doc_;
0808 const bool extension_;
0809 const bool skipNonExistingSrc_;
0810 const edm::EDGetTokenT<TProd> src_;
0811
0812 typedef FuncVariable<T, StringObjectFunction<T>, int> IntVar;
0813 typedef FuncVariable<T, StringObjectFunction<T>, float> FloatVar;
0814 typedef FuncVariable<T, StringObjectFunction<T>, uint8_t> UInt8Var;
0815 typedef FuncVariable<T, StringCutObjectSelector<T>, bool> BoolVar;
0816 std::vector<std::unique_ptr<Variable<T>>> vars_;
0817 };
0818
0819
0820 template <typename T>
0821 class RunSingletonSimpleFlatTableProducer : public SimpleFlatTableProducerBaseRun<T, T> {
0822 public:
0823 RunSingletonSimpleFlatTableProducer(edm::ParameterSet const ¶ms) : SimpleFlatTableProducerBaseRun<T, T>(params) {}
0824
0825 ~RunSingletonSimpleFlatTableProducer() override {}
0826
0827 std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Run &, const edm::Handle<T> &prod) const override {
0828 auto out = std::make_unique<nanoaod::FlatTable>(1, this->name_, true, this->extension_);
0829 std::vector<const T *> selobjs(1, prod.product());
0830 for (const auto &var : this->vars_)
0831 var->fill(selobjs, *out);
0832 return out;
0833 }
0834 };
0835
0836
0837 template <typename T, typename TProd>
0838 class RunSimpleFlatTableProducer : public SimpleFlatTableProducerBaseRun<T, TProd> {
0839 public:
0840 RunSimpleFlatTableProducer(edm::ParameterSet const ¶ms)
0841 : SimpleFlatTableProducerBaseRun<T, TProd>(params),
0842 maxLen_(params.existsAs<unsigned int>("maxLen") ? params.getParameter<unsigned int>("maxLen")
0843 : std::numeric_limits<unsigned int>::max()),
0844 cut_(params.existsAs<std::string>("cut") ? params.getParameter<std::string>("cut") : "", true) {}
0845
0846 ~RunSimpleFlatTableProducer() override {}
0847
0848 std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Run &iRun, const edm::Handle<TProd> &prod) const override {
0849 std::vector<const T *> selobjs;
0850 if (prod.isValid() || !(this->skipNonExistingSrc_)) {
0851 for (unsigned int i = 0, n = prod->size(); i < n; ++i) {
0852 const auto &obj = (*prod)[i];
0853 if (cut_(obj)) {
0854 selobjs.push_back(&obj);
0855 }
0856 if (selobjs.size() >= maxLen_)
0857 break;
0858 }
0859 }
0860 auto out = std::make_unique<nanoaod::FlatTable>(selobjs.size(), this->name_, false, this->extension_);
0861 for (const auto &var : this->vars_)
0862 var->fill(selobjs, *out);
0863 return out;
0864 }
0865
0866 protected:
0867 const unsigned int maxLen_;
0868 const StringCutObjectSelector<T> cut_;
0869 };