Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-08-12 02:29:05

0001 #include <memory>
0002 
0003 #include "FWCore/Framework/interface/Frameworkfwd.h"
0004 #include "FWCore/Framework/interface/stream/EDProducer.h"
0005 #include "FWCore/Framework/interface/ConsumesCollector.h"
0006 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0007 #include "FWCore/ParameterSet/interface/ParameterSetDescription.h"
0008 #include "FWCore/ParameterSet/interface/EmptyGroupDescription.h"
0009 #include "FWCore/ParameterSet/interface/allowedValues.h"
0010 #include "Utilities/General/interface/ClassName.h"
0011 
0012 #include "CommonTools/Utils/interface/StringCutObjectSelector.h"
0013 #include "CommonTools/Utils/interface/StringObjectFunction.h"
0014 
0015 #include "DataFormats/Common/interface/ValueMap.h"
0016 #include "DataFormats/NanoAOD/interface/FlatTable.h"
0017 #include "PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h"
0018 
0019 #include "DataFormats/L1Scouting/interface/OrbitCollection.h"
0020 #include "DataFormats/NanoAOD/interface/OrbitFlatTable.h"
0021 
0022 template <typename T>
0023 class SimpleOrbitFlatTableProducer : public edm::stream::EDProducer<> {
0024 public:
0025   using TOrbitCollection = OrbitCollection<T>;
0026 
0027   SimpleOrbitFlatTableProducer(edm::ParameterSet const &params)
0028       : name_(params.getParameter<std::string>("name")),
0029         doc_(params.getParameter<std::string>("doc")),
0030         singleton_(params.getParameter<bool>("singleton")),
0031         extension_(params.getParameter<bool>("extension")),
0032         skipNonExistingSrc_(params.getParameter<bool>("skipNonExistingSrc")),
0033         cut_(!singleton_ ? params.getParameter<std::string>("cut") : "",
0034              !singleton_ && params.existsAs<bool>("lazyEval") ? params.getUntrackedParameter<bool>("lazyEval") : false),
0035         maxLen_(params.existsAs<unsigned int>("maxLen") ? params.getParameter<unsigned int>("maxLen")
0036                                                         : std::numeric_limits<unsigned int>::max()),
0037         src_(consumes(params.getParameter<edm::InputTag>("src"))) {
0038     // variables
0039     edm::ParameterSet const &varsPSet = params.getParameter<edm::ParameterSet>("variables");
0040     for (const std::string &vname : varsPSet.getParameterNamesForType<edm::ParameterSet>()) {
0041       const auto &varPSet = varsPSet.getParameter<edm::ParameterSet>(vname);
0042       const std::string &type = varPSet.getParameter<std::string>("type");
0043       if (type == "int")
0044         vars_.push_back(std::make_unique<IntVar>(vname, varPSet));
0045       else if (type == "uint")
0046         vars_.push_back(std::make_unique<UIntVar>(vname, varPSet));
0047       else if (type == "int64")
0048         vars_.push_back(std::make_unique<Int64Var>(vname, varPSet));
0049       else if (type == "uint64")
0050         vars_.push_back(std::make_unique<UInt64Var>(vname, varPSet));
0051       else if (type == "float")
0052         vars_.push_back(std::make_unique<FloatVar>(vname, varPSet));
0053       else if (type == "double")
0054         vars_.push_back(std::make_unique<DoubleVar>(vname, varPSet));
0055       else if (type == "uint8")
0056         vars_.push_back(std::make_unique<UInt8Var>(vname, varPSet));
0057       else if (type == "int16")
0058         vars_.push_back(std::make_unique<Int16Var>(vname, varPSet));
0059       else if (type == "uint16")
0060         vars_.push_back(std::make_unique<UInt16Var>(vname, varPSet));
0061       else if (type == "bool")
0062         vars_.push_back(std::make_unique<BoolVar>(vname, varPSet));
0063       else
0064         throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
0065     }
0066 
0067     // external variables
0068     if (params.existsAs<edm::ParameterSet>("externalVariables")) {
0069       edm::ParameterSet const &extvarsPSet = params.getParameter<edm::ParameterSet>("externalVariables");
0070       for (const std::string &vname : extvarsPSet.getParameterNamesForType<edm::ParameterSet>()) {
0071         const auto &varPSet = extvarsPSet.getParameter<edm::ParameterSet>(vname);
0072         const std::string &type = varPSet.getParameter<std::string>("type");
0073         if (type == "int")
0074           extvars_.push_back(
0075               std::make_unique<IntExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0076         else if (type == "uint")
0077           extvars_.push_back(
0078               std::make_unique<UIntExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0079         else if (type == "int64")
0080           extvars_.push_back(
0081               std::make_unique<Int64ExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0082         else if (type == "uint64")
0083           extvars_.push_back(
0084               std::make_unique<UInt64ExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0085         else if (type == "float")
0086           extvars_.push_back(
0087               std::make_unique<FloatExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0088         else if (type == "double")
0089           extvars_.push_back(
0090               std::make_unique<DoubleExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0091         else if (type == "uint8")
0092           extvars_.push_back(
0093               std::make_unique<UInt8ExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0094         else if (type == "int16")
0095           extvars_.push_back(
0096               std::make_unique<Int16ExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0097         else if (type == "uint16")
0098           extvars_.push_back(
0099               std::make_unique<UInt16ExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0100         else if (type == "bool")
0101           extvars_.push_back(
0102               std::make_unique<BoolExtVar>(vname, varPSet, this->consumesCollector(), this->skipNonExistingSrc_));
0103         else
0104           throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + vname);
0105       }
0106     }
0107 
0108     produces<l1ScoutingRun3::OrbitFlatTable>();
0109   }
0110 
0111   ~SimpleOrbitFlatTableProducer() override {}
0112 
0113   static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0114     edm::ParameterSetDescription desc;
0115     std::string classname = ClassName<T>::name();
0116     desc.add<std::string>("name")->setComment("name of the branch in the flat table output for " + classname);
0117     desc.add<std::string>("doc", "")->setComment("few words of self documentation");
0118     desc.ifValue(
0119         edm::ParameterDescription<bool>(
0120             "singleton", false, true, edm::Comment("whether or not the input collection is single-element")),
0121         false >> (edm::ParameterDescription<std::string>(
0122                       "cut", "", true, edm::Comment("selection on the main input collection")) and
0123                   edm::ParameterDescription<bool>("lazyEval",
0124                                                   false,
0125                                                   false,
0126                                                   edm::Comment("if true, can use methods of inheriting classes. Can "
0127                                                                "cause problems when multi-threading."))) or
0128             true >> edm::EmptyGroupDescription());
0129 
0130     desc.addOptional<unsigned int>("maxLen")->setComment(
0131         "define the maximum length per bx of the input collection to put in the branch");
0132     desc.add<bool>("extension", false)->setComment("whether or not to extend an existing same table");
0133     desc.add<bool>("skipNonExistingSrc", false)
0134         ->setComment("whether or not to skip producing the table on absent input product");
0135     desc.add<edm::InputTag>("src")->setComment("input collection to fill the flat table");
0136 
0137     edm::ParameterSetDescription variable;
0138     variable.add<std::string>("expr")->setComment("a function to define the content of the branch in the flat table");
0139     variable.add<std::string>("doc")->setComment("few words description of the branch content");
0140     variable.addUntracked<bool>("lazyEval", false)
0141         ->setComment("if true, can use methods of inheriting classes in `expr`. Can cause problems with threading.");
0142     variable.ifValue(
0143         edm::ParameterDescription<std::string>(
0144             "type", "int", true, edm::Comment("the c++ type of the branch in the flat table")),
0145         edm::allowedValues<std::string>("int", "uint", "float", "double", "uint8", "int16", "uint16", "bool"));
0146     variable.addOptionalNode(
0147         edm::ParameterDescription<int>(
0148             "precision", true, edm::Comment("the precision with which to store the value in the flat table")) xor
0149             edm::ParameterDescription<std::string>(
0150                 "precision", true, edm::Comment("the precision with which to store the value in the flat table")),
0151         false);
0152 
0153     edm::ParameterSetDescription variables;
0154     variables.setComment("a parameters set to define all variable to fill the flat table");
0155     variables.addNode(
0156         edm::ParameterWildcard<edm::ParameterSetDescription>("*", edm::RequireZeroOrMore, true, variable));
0157     desc.add<edm::ParameterSetDescription>("variables", variables);
0158 
0159     // external variables
0160     edm::ParameterSetDescription extvariable;
0161     extvariable.add<edm::InputTag>("src")->setComment("valuemap input collection to fill the flat table");
0162     extvariable.add<std::string>("doc")->setComment("few words description of the branch content");
0163     extvariable.ifValue(edm::ParameterDescription<std::string>(
0164                             "type", "int", true, edm::Comment("the c++ type of the branch in the flat table")),
0165                         edm::allowedValues<std::string>(
0166                             "int", "uint", "int64", "uint64", "float", "double", "uint8", "int16", "uint16", "bool"));
0167     extvariable.addOptionalNode(
0168         edm::ParameterDescription<int>(
0169             "precision", true, edm::Comment("the precision with which to store the value in the flat table")) xor
0170             edm::ParameterDescription<std::string>("precision",
0171                                                    true,
0172                                                    edm::Comment("the precision with which to store the value in the "
0173                                                                 "flat table, as a function of the object evaluated")),
0174         false);
0175 
0176     edm::ParameterSetDescription extvariables;
0177     extvariables.setComment("a parameters set to define all variable taken form valuemap to fill the flat table");
0178     extvariables.addOptionalNode(
0179         edm::ParameterWildcard<edm::ParameterSetDescription>("*", edm::RequireZeroOrMore, true, extvariable), false);
0180     desc.addOptional<edm::ParameterSetDescription>("externalVariables", extvariables);
0181 
0182     descriptions.addWithDefaultLabel(desc);
0183   }
0184 
0185   void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override {
0186     edm::Handle<TOrbitCollection> src;
0187     iEvent.getByToken(src_, src);
0188 
0189     std::vector<const T *> selobjs;
0190     std::vector<edm::Ptr<T>> selptrs;  // for external variables
0191     std::vector<unsigned int> selbxOffsets;
0192 
0193     if (src.isValid() || !skipNonExistingSrc_) {
0194       if (singleton_) {
0195         // fill objects
0196         for (int i = 0; i < src->size(); i++) {
0197           selobjs.push_back(&(*src)[i]);
0198           if (!extvars_.empty())
0199             selptrs.emplace_back(src, 0);
0200         }
0201 
0202         // set bx offsets of selected objects
0203         selbxOffsets = src->bxOffsets();
0204 
0205       } else {  // not singleton
0206         // offsets before cut
0207         std::vector<unsigned int> bxOffsets = src->bxOffsets();
0208 
0209         // number of objects per bx after cut
0210         std::vector<unsigned int> selbxSizes = std::vector<unsigned int>(l1ScoutingRun3::OrbitFlatTable::NBX + 1, 0);
0211 
0212         for (const unsigned int &bx : src->getFilledBxs()) {
0213           const auto &objs = src->bxIterator(bx);
0214           for (unsigned int i = 0; i < objs.size(); i++) {
0215             const auto &obj = objs[i];
0216             edm::Ptr<T> objptr = edm::Ptr<T>(src, bxOffsets[bx] + i);
0217             if (cut_(obj)) {  // apply cut
0218               selobjs.push_back(&obj);
0219               if (!extvars_.empty())
0220                 selptrs.push_back(objptr);
0221               selbxSizes[bx]++;
0222             }
0223             if (selbxSizes[bx] >= maxLen_)  // skip to the next bx
0224               break;
0225           }
0226         }
0227 
0228         selbxOffsets = sizes2offsets(selbxSizes);
0229       }
0230     }
0231 
0232     auto out = std::make_unique<l1ScoutingRun3::OrbitFlatTable>(selbxOffsets, name_, singleton_, extension_);
0233     out->setDoc(doc_);
0234 
0235     for (const auto &var : this->vars_)
0236       var->fill(selobjs, *out);
0237     for (const auto &var : this->extvars_)
0238       var->fill(iEvent, selptrs, *out);
0239 
0240     iEvent.put(std::move(out));
0241   }
0242 
0243 private:  // private attributes
0244   const std::string name_;
0245   const std::string doc_;
0246   const bool singleton_;
0247   const bool extension_;
0248   const bool skipNonExistingSrc_;
0249   const StringCutObjectSelector<T> cut_;
0250   const unsigned int maxLen_;
0251   const edm::EDGetTokenT<TOrbitCollection> src_;
0252 
0253   // variables
0254   typedef FuncVariable<T, StringObjectFunction<T>, int32_t> IntVar;
0255   typedef FuncVariable<T, StringObjectFunction<T>, uint32_t> UIntVar;
0256   typedef FuncVariable<T, StringObjectFunction<T>, int64_t> Int64Var;
0257   typedef FuncVariable<T, StringObjectFunction<T>, uint64_t> UInt64Var;
0258   typedef FuncVariable<T, StringObjectFunction<T>, float> FloatVar;
0259   typedef FuncVariable<T, StringObjectFunction<T>, double> DoubleVar;
0260   typedef FuncVariable<T, StringObjectFunction<T>, uint8_t> UInt8Var;
0261   typedef FuncVariable<T, StringObjectFunction<T>, int16_t> Int16Var;
0262   typedef FuncVariable<T, StringObjectFunction<T>, uint16_t> UInt16Var;
0263   typedef FuncVariable<T, StringCutObjectSelector<T>, bool> BoolVar;
0264   std::vector<std::unique_ptr<Variable<T>>> vars_;
0265 
0266   // external variables
0267   typedef ValueMapVariable<T, int32_t> IntExtVar;
0268   typedef ValueMapVariable<T, uint32_t> UIntExtVar;
0269   typedef ValueMapVariable<T, int64_t> Int64ExtVar;
0270   typedef ValueMapVariable<T, uint64_t> UInt64ExtVar;
0271   typedef ValueMapVariable<T, float> FloatExtVar;
0272   typedef ValueMapVariable<T, double, float> DoubleExtVar;
0273   typedef ValueMapVariable<T, bool> BoolExtVar;
0274   typedef ValueMapVariable<T, int, uint8_t> UInt8ExtVar;
0275   typedef ValueMapVariable<T, int, int16_t> Int16ExtVar;
0276   typedef ValueMapVariable<T, int, uint16_t> UInt16ExtVar;
0277   std::vector<std::unique_ptr<ExtVariable<T>>> extvars_;
0278 
0279 private:  // private methods
0280   std::vector<unsigned int> sizes2offsets(std::vector<unsigned int> sizes) const {
0281     std::vector<unsigned int> offsets(sizes.size() + 1, 0);  // add extra one for the last offset = total size
0282     for (unsigned int i = 0; i < sizes.size(); i++) {
0283       offsets[i + 1] = offsets[i] + sizes[i];
0284     }
0285     return offsets;
0286   }
0287 };
0288 
0289 #include "DataFormats/L1Scouting/interface/L1ScoutingMuon.h"
0290 typedef SimpleOrbitFlatTableProducer<l1ScoutingRun3::Muon> SimpleL1ScoutingMuonOrbitFlatTableProducer;
0291 
0292 #include "DataFormats/L1Scouting/interface/L1ScoutingCalo.h"
0293 typedef SimpleOrbitFlatTableProducer<l1ScoutingRun3::EGamma> SimpleL1ScoutingEGammaOrbitFlatTableProducer;
0294 typedef SimpleOrbitFlatTableProducer<l1ScoutingRun3::Tau> SimpleL1ScoutingTauOrbitFlatTableProducer;
0295 typedef SimpleOrbitFlatTableProducer<l1ScoutingRun3::Jet> SimpleL1ScoutingJetOrbitFlatTableProducer;
0296 
0297 #include "DataFormats/L1Scouting/interface/L1ScoutingBMTFStub.h"
0298 typedef SimpleOrbitFlatTableProducer<l1ScoutingRun3::BMTFStub> SimpleL1ScoutingBMTFStubOrbitFlatTableProducer;
0299 
0300 #include "FWCore/Framework/interface/MakerMacros.h"
0301 DEFINE_FWK_MODULE(SimpleL1ScoutingMuonOrbitFlatTableProducer);
0302 DEFINE_FWK_MODULE(SimpleL1ScoutingEGammaOrbitFlatTableProducer);
0303 DEFINE_FWK_MODULE(SimpleL1ScoutingTauOrbitFlatTableProducer);
0304 DEFINE_FWK_MODULE(SimpleL1ScoutingJetOrbitFlatTableProducer);
0305 DEFINE_FWK_MODULE(SimpleL1ScoutingBMTFStubOrbitFlatTableProducer);