File indexing completed on 2024-09-07 04:37:21
0001 #include "FWCore/Framework/interface/stream/EDProducer.h"
0002 #include "FWCore/Framework/interface/Event.h"
0003 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0004 #include "FWCore/Utilities/interface/InputTag.h"
0005 #include "DataFormats/Common/interface/View.h"
0006
0007 #include "DataFormats/PatCandidates/interface/UserData.h"
0008 #include "PhysicsTools/PatAlgos/interface/PATUserDataMerger.h"
0009
0010 #include "DataFormats/PatCandidates/interface/Muon.h"
0011 #include "DataFormats/PatCandidates/interface/Electron.h"
0012 #include "DataFormats/PatCandidates/interface/Photon.h"
0013 #include "DataFormats/PatCandidates/interface/Tau.h"
0014 #include "DataFormats/PatCandidates/interface/Jet.h"
0015
0016 namespace {
0017 template <typename T>
0018 bool equal(const T &lhs, const T &rhs) {
0019 throw cms::Exception("NotImplimented")
0020 << " equal in PATObjectUserDataEmbedder is not implimented for objects of type " << typeid(lhs).name()
0021 << " and thus their src coll must be the same collection the valuemaps are keyed off";
0022 }
0023 template <>
0024 bool equal(const reco::GsfElectron &lhs, const reco::GsfElectron &rhs) {
0025 return lhs.superCluster()->seed()->seed().rawId() == rhs.superCluster()->seed()->seed().rawId();
0026 }
0027 template <>
0028 bool equal(const reco::Photon &lhs, const reco::Photon &rhs) {
0029 return lhs.superCluster()->seed()->seed().rawId() == rhs.superCluster()->seed()->seed().rawId();
0030 }
0031
0032 }
0033
0034 namespace pat {
0035
0036 namespace helper {
0037
0038 struct AddUserIntFromBool {
0039 typedef bool value_type;
0040 typedef edm::ValueMap<value_type> product_type;
0041 template <typename ObjectType>
0042 void addData(ObjectType &obj, const std::string &key, const value_type &val) {
0043 obj.addUserInt(key, val);
0044 }
0045 };
0046
0047 template <typename T, typename TParent, typename TProd>
0048 edm::Ptr<TParent> getPtrForProd(edm::Ptr<T> ptr,
0049 const std::vector<edm::Handle<edm::View<TParent>>> &parentColls,
0050 const TProd &prod) {
0051 if (prod.contains(ptr.id())) {
0052 return edm::Ptr<TParent>(ptr);
0053 } else {
0054 for (const auto &parentColl : parentColls) {
0055 if (parentColl.isValid() && prod.contains(parentColl.id())) {
0056 for (size_t indx = 0; indx < parentColl->size(); indx++) {
0057 if (equal<TParent>(*ptr, (*parentColl)[indx])) {
0058 return edm::Ptr<TParent>(parentColl, indx);
0059 }
0060 }
0061
0062
0063 return edm::Ptr<TParent>(parentColl.id());
0064 }
0065 }
0066 }
0067 throw cms::Exception("ConfigurationError")
0068 << "When accessing value maps in PATObjectUserDataEmbedder, the collection the valuemap was keyed off is not "
0069 "either the input src or listed in one of the parentSrcs";
0070 }
0071
0072 template <typename A>
0073 class NamedUserDataLoader {
0074 public:
0075 NamedUserDataLoader(const edm::ParameterSet &iConfig, const std::string &main, edm::ConsumesCollector &&cc) {
0076 if (iConfig.existsAs<edm::ParameterSet>(main)) {
0077 edm::ParameterSet const &srcPSet = iConfig.getParameter<edm::ParameterSet>(main);
0078 for (const std::string &label : srcPSet.getParameterNamesForType<edm::InputTag>()) {
0079 labelsAndTokens_.emplace_back(
0080 label, cc.consumes<typename A::product_type>(srcPSet.getParameter<edm::InputTag>(label)));
0081 }
0082 }
0083 }
0084 template <typename T, typename TParent = T>
0085 void addData(const edm::Event &iEvent,
0086 const std::vector<edm::Ptr<T>> &ptrs,
0087 std::vector<edm::Handle<edm::View<TParent>>> parents,
0088 std::vector<T> &out) const {
0089 A adder;
0090 unsigned int n = ptrs.size();
0091 edm::Handle<typename A::product_type> handle;
0092 for (const auto &pair : labelsAndTokens_) {
0093 iEvent.getByToken(pair.second, handle);
0094 for (unsigned int i = 0; i < n; ++i) {
0095 auto ptr = getPtrForProd(ptrs[i], parents, *handle);
0096 adder.addData(out[i], pair.first, (*handle)[ptr]);
0097 }
0098 }
0099 }
0100
0101 private:
0102 std::vector<std::pair<std::string, edm::EDGetTokenT<typename A::product_type>>> labelsAndTokens_;
0103 };
0104 }
0105
0106 template <typename T, typename ParentType = T>
0107 class PATObjectUserDataEmbedder : public edm::stream::EDProducer<> {
0108 public:
0109 explicit PATObjectUserDataEmbedder(const edm::ParameterSet &iConfig)
0110 : src_(consumes<edm::View<T>>(iConfig.getParameter<edm::InputTag>("src"))),
0111 userFloats_(iConfig, "userFloats", consumesCollector()),
0112 userInts_(iConfig, "userInts", consumesCollector()),
0113 userIntFromBools_(iConfig, "userIntFromBools", consumesCollector()),
0114 userCands_(iConfig, "userCands", consumesCollector()) {
0115 for (const auto &parentSrc : iConfig.getParameter<std::vector<edm::InputTag>>("parentSrcs")) {
0116 parentSrcs_.push_back(consumes<edm::View<ParentType>>(parentSrc));
0117 }
0118 produces<std::vector<T>>();
0119 }
0120
0121 ~PATObjectUserDataEmbedder() override {}
0122
0123 void produce(edm::Event &iEvent, const edm::EventSetup &iSetup) override;
0124
0125 static void fillDescriptions(edm::ConfigurationDescriptions &descriptions) {
0126 edm::ParameterSetDescription desc;
0127 desc.add<edm::InputTag>("src");
0128 desc.add<std::vector<edm::InputTag>>("parentSrcs", std::vector<edm::InputTag>());
0129 for (auto &&what : {"userFloats", "userInts", "userIntFromBools", "userCands"}) {
0130 edm::ParameterSetDescription descNested;
0131 descNested.addWildcard<edm::InputTag>("*");
0132 desc.add<edm::ParameterSetDescription>(what, descNested);
0133 }
0134 if (typeid(T) == typeid(pat::Muon))
0135 descriptions.add("muonsWithUserData", desc);
0136 else if (typeid(T) == typeid(pat::Electron))
0137 descriptions.add("electronsWithUserData", desc);
0138 else if (typeid(T) == typeid(pat::Photon))
0139 descriptions.add("photonsWithUserData", desc);
0140 else if (typeid(T) == typeid(pat::Tau))
0141 descriptions.add("tausWithUserData", desc);
0142 else if (typeid(T) == typeid(pat::Jet))
0143 descriptions.add("jetsWithUserData", desc);
0144 }
0145
0146 private:
0147
0148 edm::EDGetTokenT<edm::View<T>> src_;
0149
0150
0151
0152
0153
0154 std::vector<edm::EDGetTokenT<edm::View<ParentType>>> parentSrcs_;
0155
0156 helper::NamedUserDataLoader<pat::helper::AddUserFloat> userFloats_;
0157 helper::NamedUserDataLoader<pat::helper::AddUserInt> userInts_;
0158 helper::NamedUserDataLoader<pat::helper::AddUserIntFromBool> userIntFromBools_;
0159 helper::NamedUserDataLoader<pat::helper::AddUserCand> userCands_;
0160 };
0161
0162 }
0163
0164 template <typename T, typename ParentType>
0165 void pat::PATObjectUserDataEmbedder<T, ParentType>::produce(edm::Event &iEvent, const edm::EventSetup &iSetup) {
0166 edm::Handle<edm::View<T>> src;
0167 iEvent.getByToken(src_, src);
0168
0169 std::vector<edm::Handle<edm::View<ParentType>>> parentSrcs;
0170 parentSrcs.reserve(parentSrcs_.size());
0171 for (const auto &src : parentSrcs_) {
0172 parentSrcs.push_back(iEvent.getHandle(src));
0173 }
0174
0175 std::unique_ptr<std::vector<T>> out(new std::vector<T>());
0176 out->reserve(src->size());
0177
0178 std::vector<edm::Ptr<T>> ptrs;
0179 ptrs.reserve(src->size());
0180 for (unsigned int i = 0, n = src->size(); i < n; ++i) {
0181
0182 out->push_back((*src)[i]);
0183 ptrs.push_back(src->ptrAt(i));
0184 }
0185
0186 userFloats_.addData(iEvent, ptrs, parentSrcs, *out);
0187 userInts_.addData(iEvent, ptrs, parentSrcs, *out);
0188 userIntFromBools_.addData(iEvent, ptrs, parentSrcs, *out);
0189 userCands_.addData(iEvent, ptrs, parentSrcs, *out);
0190
0191 iEvent.put(std::move(out));
0192 }
0193
0194 typedef pat::PATObjectUserDataEmbedder<pat::Electron, reco::GsfElectron> PATElectronUserDataEmbedder;
0195 typedef pat::PATObjectUserDataEmbedder<pat::Muon> PATMuonUserDataEmbedder;
0196 typedef pat::PATObjectUserDataEmbedder<pat::Photon, reco::Photon> PATPhotonUserDataEmbedder;
0197 typedef pat::PATObjectUserDataEmbedder<pat::Tau> PATTauUserDataEmbedder;
0198 typedef pat::PATObjectUserDataEmbedder<pat::Jet> PATJetUserDataEmbedder;
0199
0200 #include "FWCore/Framework/interface/MakerMacros.h"
0201 DEFINE_FWK_MODULE(PATElectronUserDataEmbedder);
0202 DEFINE_FWK_MODULE(PATMuonUserDataEmbedder);
0203 DEFINE_FWK_MODULE(PATPhotonUserDataEmbedder);
0204 DEFINE_FWK_MODULE(PATTauUserDataEmbedder);
0205 DEFINE_FWK_MODULE(PATJetUserDataEmbedder);