File indexing completed on 2023-06-05 22:16:08
0001 #ifndef MuonTools_MuRecObjBaseProducer_h
0002 #define MuonTools_MuRecObjBaseProducer_h
0003
0004
0005
0006
0007
0008
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 Int8DetVar = FuncVariable<DETECTOR_T, StringObjectFunction<DETECTOR_T>, int8_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 ¶ms)
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));
0068 } else if (type == "uint") {
0069 detVarPtr = std::move(std::make_unique<UIntDetVar>(name, varCfg));
0070 } else if (type == "int8") {
0071 detVarPtr = std::move(std::make_unique<Int8DetVar>(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
0109 return varBase;
0110 };
0111
0112 auto fullDescription = [](auto const &var, std::string const label) {
0113 edm::ParameterSetDescription fullDesc;
0114
0115 edm::ParameterWildcard<edm::ParameterSetDescription> detIdVarWildCard{"*", edm::RequireZeroOrMore, true, var};
0116 fullDesc.setComment("a parameters set to define all " + label + " variables to the flat table");
0117 fullDesc.addNode(detIdVarWildCard);
0118
0119 return fullDesc;
0120 };
0121
0122 auto detIdVar{baseDescription()};
0123 auto globalGeomVar{baseDescription()};
0124
0125 edm::Comment comType{"the c++ type of the branch in the flat table"};
0126 detIdVar.ifValue(edm::ParameterDescription<std::string>{"type", "int", true, comType},
0127 edm::allowedValues<std::string>("int", "uint", "int8", "uint8"));
0128
0129 edm::Comment comPrecision{"the precision with which to store the value in the flat table"};
0130 globalGeomVar.addOptionalNode(edm::ParameterDescription<int>{"precision", true, comPrecision}, false);
0131
0132 desc.add<edm::ParameterSetDescription>("detIdVariables", fullDescription(detIdVar, "DetId"));
0133 desc.add<edm::ParameterSetDescription>("globalPosVariables", fullDescription(globalGeomVar, "Global Position"));
0134
0135 if constexpr (std::is_base_of_v<RecSegment, RECO_T>) {
0136 desc.add<edm::ParameterSetDescription>("globalDirVariables", fullDescription(globalGeomVar, "Global Direction"));
0137 }
0138
0139 descriptions.addWithDefaultLabel(desc);
0140 }
0141
0142 std::unique_ptr<nanoaod::FlatTable> fillTable(const edm::Event &iEvent,
0143 const edm::Handle<COLLECTION> &product) const override {
0144 std::vector<const RECO_T *> objs;
0145 std::vector<const DETECTOR_T *> detIds;
0146 std::vector<const GlobalPoint *> globalPositions;
0147 std::vector<const GlobalVector *> globalDirections;
0148
0149
0150 std::list<DETECTOR_T> detIdObjs;
0151 std::list<GlobalPoint> globalPointObjs;
0152 std::list<GlobalVector> globalVectorObjs;
0153
0154 if (product.isValid()) {
0155 auto detIdIt = product->id_begin();
0156 const auto detIdEnd = product->id_end();
0157
0158 for (; detIdIt != detIdEnd; ++detIdIt) {
0159 const auto &range = product->get(*detIdIt);
0160 const GeomDet *geomDet = m_geometry->idToDet(*detIdIt);
0161
0162 detIdObjs.push_back(*detIdIt);
0163 std::fill_n(std::back_inserter(detIds), range.second - range.first, &detIdObjs.back());
0164
0165 for (auto objIt{range.first}; objIt != range.second; ++objIt) {
0166 objs.push_back(&(*objIt));
0167 globalPointObjs.push_back(geomDet->toGlobal(objIt->localPosition()));
0168 globalPositions.push_back(&globalPointObjs.back());
0169 if constexpr (std::is_base_of_v<RecSegment, RECO_T>) {
0170 globalVectorObjs.push_back(geomDet->toGlobal(objIt->localDirection()));
0171 globalDirections.push_back(&globalVectorObjs.back());
0172 }
0173 }
0174 }
0175 }
0176
0177 auto table = std::make_unique<nanoaod::FlatTable>(objs.size(), this->name_, false, this->extension_);
0178
0179 for (const auto &var : this->vars_) {
0180 var->fill(objs, *table);
0181 }
0182
0183 for (const auto &var : detIdVars_) {
0184 var->fill(detIds, *table);
0185 }
0186
0187 for (const auto &var : globalPosVars_) {
0188 var->fill(globalPositions, *table);
0189 }
0190
0191 if constexpr (std::is_base_of_v<RecSegment, RECO_T>) {
0192 for (const auto &var : globalDirVars_) {
0193 var->fill(globalDirections, *table);
0194 }
0195 }
0196
0197 return table;
0198 }
0199
0200 void produce(edm::Event &event, const edm::EventSetup &environment) override {
0201 edm::Handle<COLLECTION> src;
0202 event.getByToken(this->src_, src);
0203
0204 m_geometry = environment.getHandle(m_token);
0205 std::unique_ptr<nanoaod::FlatTable> out = fillTable(event, src);
0206 out->setDoc(this->doc_);
0207
0208 event.put(std::move(out));
0209 }
0210 };
0211
0212 #endif