Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2024-04-25 02:13:43

0001 #ifndef MuonTools_MuRecObjBaseProducer_h
0002 #define MuonTools_MuRecObjBaseProducer_h
0003 
0004 /** \class MuRecObjBaseProducer MuRecObjBaseProducer.h DPGAnalysis/MuonTools/src/MuRecObjBaseProducer.h
0005  *  
0006  * Helper class defining the generic interface of a muon digi Producer
0007  *
0008  * \author C. Battilana (INFN BO)
0009  *
0010  *
0011  */
0012 
0013 #include "DataFormats/Common/interface/RangeMap.h"
0014 #include "DataFormats/Common/interface/ClonePolicy.h"
0015 #include "DataFormats/Common/interface/OwnVector.h"
0016 
0017 #include "PhysicsTools/NanoAOD/interface/SimpleFlatTableProducer.h"
0018 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0019 #include "DataFormats/TrackingRecHit/interface/RecSegment.h"
0020 
0021 #include "FWCore/Framework/interface/ESHandle.h"
0022 
0023 #include "FWCore/Utilities/interface/ESGetToken.h"
0024 #include "FWCore/Framework/interface/ConsumesCollector.h"
0025 #include "Geometry/CommonDetUnit/interface/GlobalTrackingGeometry.h"
0026 #include "Geometry/Records/interface/GlobalTrackingGeometryRecord.h"
0027 
0028 #include <algorithm>
0029 #include <type_traits>
0030 #include <list>
0031 #include <string>
0032 
0033 template <class DETECTOR_T, class RECO_T, class GEOM_T>
0034 class MuRecObjBaseProducer
0035     : public SimpleFlatTableProducerBase<RECO_T, edm::RangeMap<DETECTOR_T, edm::OwnVector<RECO_T>>> {
0036   using COLLECTION = edm::RangeMap<DETECTOR_T, edm::OwnVector<RECO_T>>;
0037 
0038   edm::ESGetToken<GEOM_T, MuonGeometryRecord> m_token;
0039   edm::ESHandle<GEOM_T> m_geometry;
0040 
0041   using IntDetVar = FuncVariable<DETECTOR_T, StringObjectFunction<DETECTOR_T>, int>;
0042   using UIntDetVar = FuncVariable<DETECTOR_T, StringObjectFunction<DETECTOR_T>, unsigned int>;
0043   using Int16DetVar = FuncVariable<DETECTOR_T, StringObjectFunction<DETECTOR_T>, int16_t>;
0044   using UInt8DetVar = FuncVariable<DETECTOR_T, StringObjectFunction<DETECTOR_T>, uint8_t>;
0045 
0046   std::vector<std::unique_ptr<Variable<DETECTOR_T>>> detIdVars_;
0047 
0048   using GlobalPosVar = FuncVariable<GlobalPoint, StringObjectFunction<GlobalPoint>, float>;
0049   using GlobalDirVar = FuncVariable<GlobalVector, StringObjectFunction<GlobalVector>, float>;
0050 
0051   std::vector<std::unique_ptr<Variable<GlobalPoint>>> globalPosVars_;
0052   std::vector<std::unique_ptr<Variable<GlobalVector>>> globalDirVars_;
0053 
0054 public:
0055   MuRecObjBaseProducer(edm::ParameterSet const &params)
0056       : SimpleFlatTableProducerBase<RECO_T, COLLECTION>(params), m_token{this->template esConsumes()} {
0057     auto varCfgs = params.getParameter<edm::ParameterSet>("detIdVariables");
0058     auto varNames = varCfgs.getParameterNamesForType<edm::ParameterSet>();
0059 
0060     std::transform(varNames.begin(), varNames.end(), std::back_inserter(detIdVars_), [&](const auto &name) {
0061       const edm::ParameterSet &varCfg = varCfgs.getParameter<edm::ParameterSet>(name);
0062       const std::string &type = varCfg.getParameter<std::string>("type");
0063 
0064       std::unique_ptr<Variable<DETECTOR_T>> detVarPtr;
0065 
0066       if (type == "int") {
0067         detVarPtr = std::move(std::make_unique<IntDetVar>(name, varCfg));  // CB can improve?
0068       } else if (type == "uint") {
0069         detVarPtr = std::move(std::make_unique<UIntDetVar>(name, varCfg));
0070       } else if (type == "int16") {
0071         detVarPtr = std::move(std::make_unique<Int16DetVar>(name, varCfg));
0072       } else if (type == "uint8") {
0073         detVarPtr = std::move(std::make_unique<UInt8DetVar>(name, varCfg));
0074       } else {
0075         throw cms::Exception("Configuration", "unsupported type " + type + " for variable " + name);
0076       }
0077 
0078       return detVarPtr;
0079     });
0080 
0081     varCfgs = params.getParameter<edm::ParameterSet>("globalPosVariables");
0082     varNames = varCfgs.getParameterNamesForType<edm::ParameterSet>();
0083 
0084     std::transform(varNames.begin(), varNames.end(), std::back_inserter(globalPosVars_), [&](const auto &name) {
0085       return std::make_unique<GlobalPosVar>(name, varCfgs.getParameter<edm::ParameterSet>(name));
0086     });
0087 
0088     if constexpr (std::is_base_of_v<RecSegment, RECO_T>) {
0089       varCfgs = params.getParameter<edm::ParameterSet>("globalDirVariables");
0090       varNames = varCfgs.getParameterNamesForType<edm::ParameterSet>();
0091 
0092       std::transform(varNames.begin(), varNames.end(), std::back_inserter(globalDirVars_), [&](const auto &name) {
0093         return std::make_unique<GlobalDirVar>(name, varCfgs.getParameter<edm::ParameterSet>(name));
0094       });
0095     }
0096   }
0097 
0098   ~MuRecObjBaseProducer() override {}
0099 
0100   static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0101     edm::ParameterSetDescription desc = SimpleFlatTableProducerBase<RECO_T, COLLECTION>::baseDescriptions();
0102 
0103     auto baseDescription = []() {
0104       edm::ParameterSetDescription varBase;
0105 
0106       varBase.add<std::string>("expr")->setComment("a function to define the content of the branch in the flat table");
0107       varBase.add<std::string>("doc")->setComment("few words description of the branch content");
0108       varBase.addUntracked<bool>("lazyEval")->setComment("if True, check object type during Event processing.");
0109 
0110       return varBase;
0111     };
0112 
0113     auto fullDescription = [](auto const &var, std::string const label) {
0114       edm::ParameterSetDescription fullDesc;
0115 
0116       edm::ParameterWildcard<edm::ParameterSetDescription> detIdVarWildCard{"*", edm::RequireZeroOrMore, true, var};
0117       fullDesc.setComment("a parameters set to define all " + label + " variables to the flat table");
0118       fullDesc.addNode(detIdVarWildCard);
0119 
0120       return fullDesc;
0121     };
0122 
0123     auto detIdVar{baseDescription()};
0124     auto globalGeomVar{baseDescription()};
0125 
0126     edm::Comment comType{"the c++ type of the branch in the flat table"};
0127     detIdVar.ifValue(edm::ParameterDescription<std::string>{"type", "int", true, comType},
0128                      edm::allowedValues<std::string>("int", "uint", "int16", "uint8"));
0129 
0130     edm::Comment comPrecision{"the precision with which to store the value in the flat table"};
0131     globalGeomVar.addOptionalNode(edm::ParameterDescription<int>{"precision", true, comPrecision}, false);
0132 
0133     desc.add<edm::ParameterSetDescription>("detIdVariables", fullDescription(detIdVar, "DetId"));
0134     desc.add<edm::ParameterSetDescription>("globalPosVariables", fullDescription(globalGeomVar, "Global Position"));
0135 
0136     if constexpr (std::is_base_of_v<RecSegment, RECO_T>) {
0137       desc.add<edm::ParameterSetDescription>("globalDirVariables", fullDescription(globalGeomVar, "Global Direction"));
0138     }
0139 
0140     descriptions.addWithDefaultLabel(desc);
0141   }
0142 
0143   std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Event &iEvent,
0144                                                 const edm::Handle<COLLECTION> &product) const override {
0145     std::vector<const RECO_T *> objs;
0146     std::vector<const DETECTOR_T *> detIds;
0147     std::vector<const GlobalPoint *> globalPositions;
0148     std::vector<const GlobalVector *> globalDirections;
0149 
0150     // CB needed to store DetIds, global points and vectors (they are transient)
0151     std::list<DETECTOR_T> detIdObjs;
0152     std::list<GlobalPoint> globalPointObjs;
0153     std::list<GlobalVector> globalVectorObjs;
0154 
0155     if (product.isValid()) {
0156       auto detIdIt = product->id_begin();
0157       const auto detIdEnd = product->id_end();
0158 
0159       for (; detIdIt != detIdEnd; ++detIdIt) {
0160         const auto &range = product->get(*detIdIt);
0161         const GeomDet *geomDet = m_geometry->idToDet(*detIdIt);
0162 
0163         detIdObjs.push_back(*detIdIt);
0164         std::fill_n(std::back_inserter(detIds), range.second - range.first, &detIdObjs.back());
0165 
0166         for (auto objIt{range.first}; objIt != range.second; ++objIt) {
0167           objs.push_back(&(*objIt));
0168           globalPointObjs.push_back(geomDet->toGlobal(objIt->localPosition()));
0169           globalPositions.push_back(&globalPointObjs.back());
0170           if constexpr (std::is_base_of_v<RecSegment, RECO_T>) {
0171             globalVectorObjs.push_back(geomDet->toGlobal(objIt->localDirection()));
0172             globalDirections.push_back(&globalVectorObjs.back());
0173           }
0174         }
0175       }
0176     }
0177 
0178     auto table = std::make_unique<nanoaod::FlatTable>(objs.size(), this->name_, false, this->extension_);
0179 
0180     for (const auto &var : this->vars_) {
0181       var->fill(objs, *table);
0182     }
0183 
0184     for (const auto &var : detIdVars_) {
0185       var->fill(detIds, *table);
0186     }
0187 
0188     for (const auto &var : globalPosVars_) {
0189       var->fill(globalPositions, *table);
0190     }
0191 
0192     if constexpr (std::is_base_of_v<RecSegment, RECO_T>) {
0193       for (const auto &var : globalDirVars_) {
0194         var->fill(globalDirections, *table);
0195       }
0196     }
0197 
0198     return table;
0199   }
0200 
0201   void produce(edm::Event &event, const edm::EventSetup &environment) override {
0202     edm::Handle<COLLECTION> src;
0203     event.getByToken(this->src_, src);
0204 
0205     m_geometry = environment.getHandle(m_token);
0206     std::unique_ptr<nanoaod::FlatTable> out = fillTable(event, src);
0207     out->setDoc(this->doc_);
0208 
0209     event.put(std::move(out));
0210   }
0211 };
0212 
0213 #endif