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