diff --git a/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h b/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h index 4644c3ccf78de..2e5c20452f8e0 100644 --- a/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h +++ b/PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h @@ -51,18 +51,18 @@ class FuncVariable : public Variable { precisionFunc_(cfg.existsAs("precision") ? cfg.getParameter("precision") : "23", true) {} ~FuncVariable() override {} + void fill(std::vector &selobjs, nanoaod::FlatTable &out) const override { std::vector vals(selobjs.size()); for (unsigned int i = 0, n = vals.size(); i < n; ++i) { - ValType val = func_(*selobjs[i]); + vals[i] = func_(*selobjs[i]); if constexpr (std::is_same()) { if (this->precision_ == -2) { auto prec = precisionFunc_(*selobjs[i]); - vals[i] = prec > 0 ? MiniFloatConverter::reduceMantissaToNbitsRounding(val, prec) : val; - } else - vals[i] = val; - } else { - vals[i] = val; + if (prec > 0) { + vals[i] = MiniFloatConverter::reduceMantissaToNbitsRounding(vals[i], prec); + } + } } } out.template addColumn(this->name_, vals, this->doc_, this->precision_); @@ -82,16 +82,18 @@ class ExtVariable : public VariableBase { std::vector> selptrs, nanoaod::FlatTable &out) const = 0; }; + template -class ValueMapVariable : public ExtVariable { +class ValueMapVariableBase : public ExtVariable { public: - ValueMapVariable(const std::string &aname, - const edm::ParameterSet &cfg, - edm::ConsumesCollector &&cc, - bool skipNonExistingSrc = false) + ValueMapVariableBase(const std::string &aname, + const edm::ParameterSet &cfg, + edm::ConsumesCollector &&cc, + bool skipNonExistingSrc = false) : ExtVariable(aname, cfg), skipNonExistingSrc_(skipNonExistingSrc), token_(cc.consumes>(cfg.getParameter("src"))) {} + virtual ValType eval(const edm::Handle> &vmap, const edm::Ptr &op) const = 0; void fill(const edm::Event &iEvent, std::vector> selptrs, nanoaod::FlatTable &out) const override { edm::Handle> vmap; iEvent.getByToken(token_, vmap); @@ -99,7 +101,8 @@ class ValueMapVariable : public ExtVariable { if (vmap.isValid() || !skipNonExistingSrc_) { vals.resize(selptrs.size()); for (unsigned int i = 0, n = vals.size(); i < n; ++i) { - vals[i] = (*vmap)[selptrs[i]]; + // calls the overloade method to either get the valuemap value directly, or a function of the object value. + vals[i] = this->eval(vmap, selptrs[i]); } } out.template addColumn(this->name_, vals, this->doc_, this->precision_); @@ -110,6 +113,50 @@ class ValueMapVariable : public ExtVariable { edm::EDGetTokenT> token_; }; +template +class ValueMapVariable : public ValueMapVariableBase { +public: + ValueMapVariable(const std::string &aname, + const edm::ParameterSet &cfg, + edm::ConsumesCollector &&cc, + bool skipNonExistingSrc = false) + : ValueMapVariableBase(aname, cfg, std::move(cc), skipNonExistingSrc) {} + ValType eval(const edm::Handle> &vmap, const edm::Ptr &op) const { + ValType val = (*vmap)[op]; + return val; + } +}; + +template +class TypedValueMapVariable : public ValueMapVariableBase { +public: + TypedValueMapVariable(const std::string &aname, + const edm::ParameterSet &cfg, + edm::ConsumesCollector &&cc, + bool skipNonExistingSrc = false) + : ValueMapVariableBase(aname, cfg, std::move(cc), skipNonExistingSrc), + func_(cfg.getParameter("expr"), true), + precisionFunc_(cfg.existsAs("precision") ? cfg.getParameter("precision") : "23", + true) {} + + ValType eval(const edm::Handle> &vmap, const edm::Ptr &op) const { + ValType val = func_((*vmap)[op]); + if constexpr (std::is_same()) { + if (this->precision_ == -2) { + auto prec = precisionFunc_(*op); + if (prec > 0) { + val = MiniFloatConverter::reduceMantissaToNbitsRounding(val, prec); + } + } + } + return val; + } + +protected: + StringFunctor func_; + StringObjectFunction precisionFunc_; +}; + // Event producers // - ABC // - Singleton @@ -262,7 +309,7 @@ class SimpleFlatTableProducer : public SimpleFlatTableProducerBase>::baseDescriptions(); desc.ifValue(edm::ParameterDescription( @@ -283,8 +330,10 @@ class SimpleFlatTableProducer : public SimpleFlatTableProducerBase( "precision", true, edm::Comment("the precision with which to store the value in the flat table")) xor - edm::ParameterDescription( - "precision", true, edm::Comment("the precision with which to store the value in the flat table")), + edm::ParameterDescription("precision", + true, + edm::Comment("the precision with which to store the value in the " + "flat table, as a fucntion of the object evaluated")), false); edm::ParameterSetDescription extvariables; @@ -293,9 +342,12 @@ class SimpleFlatTableProducer : public SimpleFlatTableProducerBase("*", edm::RequireZeroOrMore, true, extvariable), false); desc.addOptional("externalVariables", extvariables); + return desc; + } + static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) { + edm::ParameterSetDescription desc = SimpleFlatTableProducer::baseDescriptions(); descriptions.addWithDefaultLabel(desc); } - std::unique_ptr fillTable(const edm::Event &iEvent, const edm::Handle> &prod) const override { std::vector selobjs; @@ -304,14 +356,14 @@ class SimpleFlatTableProducer : public SimpleFlatTableProducerBasesize() == 1); selobjs.push_back(&(*prod)[0]); - if (!extvars_.empty()) + if (!extvars_.empty() || !typedextvars_.empty()) selptrs.emplace_back(prod->ptrAt(0)); } else { for (unsigned int i = 0, n = prod->size(); i < n; ++i) { const auto &obj = (*prod)[i]; if (cut_(obj)) { selobjs.push_back(&obj); - if (!extvars_.empty()) + if (!extvars_.empty() || !typedextvars_.empty()) selptrs.emplace_back(prod->ptrAt(i)); } if (selobjs.size() >= maxLen_) @@ -324,6 +376,8 @@ class SimpleFlatTableProducer : public SimpleFlatTableProducerBasefill(selobjs, *out); for (const auto &var : this->extvars_) var->fill(iEvent, selptrs, *out); + for (const auto &var : this->typedextvars_) + var->fill(iEvent, selptrs, *out); return out; } @@ -341,6 +395,84 @@ class SimpleFlatTableProducer : public SimpleFlatTableProducerBase Int16ExtVar; typedef ValueMapVariable UInt16ExtVar; std::vector>> extvars_; + std::vector>> typedextvars_; +}; + +template +class SimpleTypedExternalFlatTableProducer : public SimpleFlatTableProducer { +public: + SimpleTypedExternalFlatTableProducer(edm::ParameterSet const ¶ms) : SimpleFlatTableProducer(params) { + edm::ParameterSet const &extvarsPSet = params.getParameter("externalTypedVariables"); + for (const std::string &vname : extvarsPSet.getParameterNamesForType()) { + const auto &varPSet = extvarsPSet.getParameter(vname); + const std::string &type = varPSet.getParameter("type"); + if (type == "int") + this->typedextvars_.push_back( + std::make_unique(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_)); + else if (type == "uint") + this->typedextvars_.push_back( + std::make_unique(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_)); + else if (type == "float") + this->typedextvars_.push_back( + std::make_unique(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_)); + else if (type == "double") + this->typedextvars_.push_back( + std::make_unique(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_)); + else if (type == "uint8") + this->typedextvars_.push_back( + std::make_unique(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_)); + else if (type == "int16") + this->typedextvars_.push_back( + std::make_unique(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_)); + else if (type == "uint16") + this->typedextvars_.push_back( + std::make_unique(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_)); + else if (type == "bool") + this->typedextvars_.push_back( + std::make_unique(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_)); + else + throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname); + } + } + ~SimpleTypedExternalFlatTableProducer() override {} + static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) { + edm::ParameterSetDescription desc = SimpleFlatTableProducer::baseDescriptions(); + edm::ParameterSetDescription extvariable; + extvariable.add("src")->setComment("valuemap input collection to fill the flat table"); + extvariable.add("expr")->setComment( + "a function to define the content of the branch in the flat table"); + extvariable.add("doc")->setComment("few words description of the branch content"); + extvariable.ifValue( + edm::ParameterDescription( + "type", "int", true, edm::Comment("the c++ type of the branch in the flat table")), + edm::allowedValues("int", "uint", "float", "double", "uint8", "int16", "uint16", "bool")); + extvariable.addOptionalNode( + edm::ParameterDescription( + "precision", true, edm::Comment("the precision with which to store the value in the flat table")) xor + edm::ParameterDescription("precision", + true, + edm::Comment("the precision with which to store the value in the " + "flat table, as a fucntion of the object evaluated")), + false); + + edm::ParameterSetDescription extvariables; + extvariables.setComment("a parameters set to define all variable taken form valuemap to fill the flat table"); + extvariables.addOptionalNode( + edm::ParameterWildcard("*", edm::RequireZeroOrMore, true, extvariable), false); + desc.addOptional("externalTypedVariables", extvariables); + + descriptions.addWithDefaultLabel(desc); + } + +protected: + typedef TypedValueMapVariable, int32_t> IntTypedExtVar; + typedef TypedValueMapVariable, uint32_t> UIntTypedExtVar; + typedef TypedValueMapVariable, float> FloatTypedExtVar; + typedef TypedValueMapVariable, double> DoubleTypedExtVar; + typedef TypedValueMapVariable, bool> BoolTypedExtVar; + typedef TypedValueMapVariable, uint8_t> UInt8TypedExtVar; + typedef TypedValueMapVariable, int16_t> Int16TypedExtVar; + typedef TypedValueMapVariable, uint16_t> UInt16TypedExtVar; }; template diff --git a/PhysicsTools/NanoAOD/plugins/SimpleFlatTableProducerPlugins.cc b/PhysicsTools/NanoAOD/plugins/SimpleFlatTableProducerPlugins.cc index f9a2fa3efe213..27dbb6487a9b8 100644 --- a/PhysicsTools/NanoAOD/plugins/SimpleFlatTableProducerPlugins.cc +++ b/PhysicsTools/NanoAOD/plugins/SimpleFlatTableProducerPlugins.cc @@ -3,6 +3,9 @@ #include "DataFormats/Candidate/interface/Candidate.h" typedef SimpleFlatTableProducer SimpleCandidateFlatTableProducer; +typedef SimpleTypedExternalFlatTableProducer + SimpleCandidate2CandidateFlatTableProducer; + #include "SimDataFormats/GeneratorProducts/interface/GenEventInfoProduct.h" typedef EventSingletonSimpleFlatTableProducer SimpleGenEventFlatTableProducer; @@ -59,6 +62,7 @@ typedef SimpleFlatTableProducer SimpleRun3ScoutingTrackFlatTa #include "FWCore/Framework/interface/MakerMacros.h" DEFINE_FWK_MODULE(SimpleCandidateFlatTableProducer); +DEFINE_FWK_MODULE(SimpleCandidate2CandidateFlatTableProducer); DEFINE_FWK_MODULE(SimpleGenEventFlatTableProducer); DEFINE_FWK_MODULE(SimpleGenFilterFlatTableProducerLumi); DEFINE_FWK_MODULE(SimpleHTXSFlatTableProducer);