Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2022-07-25 00:55:53

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 }  // namespace
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             //note this assumes that another parent coll isnt in the value map
0062             //it if its, it'll return null when the other one might work
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     };  // class NamedUserDataLoader
0104   }     // namespace helper
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     // configurables
0148     edm::EDGetTokenT<edm::View<T>> src_;
0149     //so valuemaps are keyed to a given collection so if we remake the objects,
0150     //are valuemaps are pointing to the wrong collection
0151     //this allows us to pass in past collections to try them to see if they are the ones
0152     //a valuemap is keyed to
0153     //note ParentType must inherit from T
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 }  // namespace pat
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   for (const auto &src : parentSrcs_) {
0171     parentSrcs.push_back(iEvent.getHandle(src));
0172   }
0173 
0174   std::unique_ptr<std::vector<T>> out(new std::vector<T>());
0175   out->reserve(src->size());
0176 
0177   std::vector<edm::Ptr<T>> ptrs;
0178   ptrs.reserve(src->size());
0179   for (unsigned int i = 0, n = src->size(); i < n; ++i) {
0180     // copy by value, save the ptr
0181     out->push_back((*src)[i]);
0182     ptrs.push_back(src->ptrAt(i));
0183   }
0184 
0185   userFloats_.addData(iEvent, ptrs, parentSrcs, *out);
0186   userInts_.addData(iEvent, ptrs, parentSrcs, *out);
0187   userIntFromBools_.addData(iEvent, ptrs, parentSrcs, *out);
0188   userCands_.addData(iEvent, ptrs, parentSrcs, *out);
0189 
0190   iEvent.put(std::move(out));
0191 }
0192 
0193 typedef pat::PATObjectUserDataEmbedder<pat::Electron, reco::GsfElectron> PATElectronUserDataEmbedder;
0194 typedef pat::PATObjectUserDataEmbedder<pat::Muon> PATMuonUserDataEmbedder;
0195 typedef pat::PATObjectUserDataEmbedder<pat::Photon, reco::Photon> PATPhotonUserDataEmbedder;
0196 typedef pat::PATObjectUserDataEmbedder<pat::Tau> PATTauUserDataEmbedder;
0197 typedef pat::PATObjectUserDataEmbedder<pat::Jet> PATJetUserDataEmbedder;
0198 
0199 #include "FWCore/Framework/interface/MakerMacros.h"
0200 DEFINE_FWK_MODULE(PATElectronUserDataEmbedder);
0201 DEFINE_FWK_MODULE(PATMuonUserDataEmbedder);
0202 DEFINE_FWK_MODULE(PATPhotonUserDataEmbedder);
0203 DEFINE_FWK_MODULE(PATTauUserDataEmbedder);
0204 DEFINE_FWK_MODULE(PATJetUserDataEmbedder);