File indexing completed on 2024-04-06 12:25:01
0001 #ifndef RecoEgamma_EgammaTools_EGExtraInfoModifierFromValueMaps_h
0002 #define RecoEgamma_EgammaTools_EGExtraInfoModifierFromValueMaps_h
0003
0004 #include "CommonTools/CandAlgos/interface/ModifyObjectValueBase.h"
0005
0006 #include "FWCore/Utilities/interface/InputTag.h"
0007 #include "FWCore/Utilities/interface/EDGetToken.h"
0008 #include "DataFormats/Common/interface/ValueMap.h"
0009
0010 #include "DataFormats/PatCandidates/interface/Electron.h"
0011 #include "DataFormats/PatCandidates/interface/Photon.h"
0012
0013 #include <unordered_map>
0014
0015 namespace {
0016 const edm::InputTag empty_tag;
0017 }
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049 namespace egmodifier {
0050 class EGID {};
0051 }
0052
0053 template <typename OutputType>
0054 class EGXtraModFromVMObjFiller {
0055 public:
0056 EGXtraModFromVMObjFiller() = delete;
0057 ~EGXtraModFromVMObjFiller() = delete;
0058
0059
0060 template <typename ObjType, typename MapType>
0061 static void addValueToObject(ObjType& obj,
0062 const edm::Ptr<reco::Candidate>& ptr,
0063 const std::unordered_map<unsigned, edm::Handle<edm::ValueMap<MapType>>>& vmaps,
0064 const std::pair<const std::string, edm::EDGetTokenT<edm::ValueMap<MapType>>>& val_map,
0065 bool overrideExistingValues);
0066
0067 template <typename ObjType, typename MapType>
0068 static void addValuesToObject(
0069 ObjType& obj,
0070 const edm::Ptr<reco::Candidate>& ptr,
0071 const std::unordered_map<std::string, edm::EDGetTokenT<edm::ValueMap<MapType>>>& vmaps_token,
0072 const std::unordered_map<unsigned, edm::Handle<edm::ValueMap<MapType>>>& vmaps,
0073 bool overrideExistingValues) {
0074 for (auto itr = vmaps_token.begin(); itr != vmaps_token.end(); ++itr) {
0075 addValueToObject(obj, ptr, vmaps, *itr, overrideExistingValues);
0076 }
0077 }
0078 };
0079
0080 template <typename MapType, typename OutputType = MapType>
0081 class EGExtraInfoModifierFromValueMaps : public ModifyObjectValueBase {
0082 public:
0083 using ValMapToken = edm::EDGetTokenT<edm::ValueMap<MapType>>;
0084 using ValueMaps = std::unordered_map<std::string, ValMapToken>;
0085 struct electron_config {
0086 edm::EDGetTokenT<edm::View<reco::GsfElectron>> tok_electron_src;
0087 ValueMaps tok_valuemaps;
0088 };
0089
0090 struct photon_config {
0091 edm::EDGetTokenT<edm::View<reco::Photon>> tok_photon_src;
0092 ValueMaps tok_valuemaps;
0093 };
0094
0095 EGExtraInfoModifierFromValueMaps(const edm::ParameterSet& conf, edm::ConsumesCollector& cc);
0096
0097 void setEvent(const edm::Event&) final;
0098
0099 void modifyObject(pat::Electron&) const final;
0100 void modifyObject(pat::Photon&) const final;
0101
0102 private:
0103 electron_config e_conf;
0104 photon_config ph_conf;
0105 std::vector<edm::Ptr<reco::GsfElectron>> eles_by_oop;
0106 std::unordered_map<unsigned, edm::Handle<edm::ValueMap<MapType>>> ele_vmaps;
0107 std::vector<edm::Ptr<reco::Photon>> phos_by_oop;
0108 std::unordered_map<unsigned, edm::Handle<edm::ValueMap<MapType>>> pho_vmaps;
0109 mutable unsigned ele_idx,
0110 pho_idx;
0111 bool overrideExistingValues_;
0112 };
0113
0114 template <typename MapType, typename OutputType>
0115 EGExtraInfoModifierFromValueMaps<MapType, OutputType>::EGExtraInfoModifierFromValueMaps(const edm::ParameterSet& conf,
0116 edm::ConsumesCollector& cc)
0117 : ModifyObjectValueBase(conf) {
0118 constexpr char electronSrc[] = "electronSrc";
0119 constexpr char photonSrc[] = "photonSrc";
0120 overrideExistingValues_ =
0121 conf.exists("overrideExistingValues") ? conf.getParameter<bool>("overrideExistingValues") : false;
0122 if (conf.exists("electron_config")) {
0123 const edm::ParameterSet& electrons = conf.getParameter<edm::ParameterSet>("electron_config");
0124 if (electrons.exists(electronSrc))
0125 e_conf.tok_electron_src =
0126 cc.consumes<edm::View<reco::GsfElectron>>(electrons.getParameter<edm::InputTag>(electronSrc));
0127
0128 const std::vector<std::string> parameters = electrons.getParameterNames();
0129 for (const std::string& name : parameters) {
0130 if (std::string(electronSrc) == name)
0131 continue;
0132 if (electrons.existsAs<edm::InputTag>(name)) {
0133 e_conf.tok_valuemaps[name] = cc.consumes<edm::ValueMap<MapType>>(electrons.getParameter<edm::InputTag>(name));
0134 }
0135 }
0136 }
0137 if (conf.exists("photon_config")) {
0138 const edm::ParameterSet& photons = conf.getParameter<edm::ParameterSet>("photon_config");
0139 if (photons.exists(photonSrc))
0140 ph_conf.tok_photon_src = cc.consumes<edm::View<reco::Photon>>(photons.getParameter<edm::InputTag>(photonSrc));
0141 const std::vector<std::string> parameters = photons.getParameterNames();
0142 for (const std::string& name : parameters) {
0143 if (std::string(photonSrc) == name)
0144 continue;
0145 if (photons.existsAs<edm::InputTag>(name)) {
0146 ph_conf.tok_valuemaps[name] = cc.consumes<edm::ValueMap<MapType>>(photons.getParameter<edm::InputTag>(name));
0147 }
0148 }
0149 }
0150 ele_idx = pho_idx = 0;
0151 }
0152
0153 template <typename MapType, typename OutputType>
0154 void EGExtraInfoModifierFromValueMaps<MapType, OutputType>::setEvent(const edm::Event& evt) {
0155 eles_by_oop.clear();
0156 phos_by_oop.clear();
0157 ele_vmaps.clear();
0158 pho_vmaps.clear();
0159
0160 ele_idx = pho_idx = 0;
0161
0162 if (!e_conf.tok_electron_src.isUninitialized()) {
0163 auto eles = evt.getHandle(e_conf.tok_electron_src);
0164
0165 eles_by_oop.resize(eles->size());
0166 std::copy(eles->ptrs().begin(), eles->ptrs().end(), eles_by_oop.begin());
0167 }
0168
0169 for (auto const& itr : e_conf.tok_valuemaps) {
0170 ele_vmaps[itr.second.index()] = evt.getHandle(itr.second);
0171 }
0172
0173 if (!ph_conf.tok_photon_src.isUninitialized()) {
0174 auto phos = evt.getHandle(ph_conf.tok_photon_src);
0175
0176 phos_by_oop.resize(phos->size());
0177 std::copy(phos->ptrs().begin(), phos->ptrs().end(), phos_by_oop.begin());
0178 }
0179
0180 for (auto const& itr : ph_conf.tok_valuemaps) {
0181 pho_vmaps[itr.second.index()] = evt.getHandle(itr.second);
0182 }
0183 }
0184
0185 namespace {
0186 template <typename T, typename U, typename V, typename MapType>
0187 inline void assignValue(const T& ptr, const U& tok, const V& map, MapType& value) {
0188 if (!tok.isUninitialized())
0189 value = map.find(tok.index())->second->get(ptr.id(), ptr.key());
0190 }
0191 }
0192
0193 template <typename MapType, typename OutputType>
0194 void EGExtraInfoModifierFromValueMaps<MapType, OutputType>::modifyObject(pat::Electron& ele) const {
0195
0196
0197
0198 edm::Ptr<reco::Candidate> ptr(ele.originalObjectRef());
0199 if (!e_conf.tok_electron_src.isUninitialized())
0200 ptr = eles_by_oop.at(ele_idx);
0201
0202 EGXtraModFromVMObjFiller<OutputType>::addValuesToObject(
0203 ele, ptr, e_conf.tok_valuemaps, ele_vmaps, overrideExistingValues_);
0204 ++ele_idx;
0205 }
0206
0207 template <typename MapType, typename OutputType>
0208 void EGExtraInfoModifierFromValueMaps<MapType, OutputType>::modifyObject(pat::Photon& pho) const {
0209
0210
0211
0212 edm::Ptr<reco::Candidate> ptr(pho.originalObjectRef());
0213 if (!ph_conf.tok_photon_src.isUninitialized())
0214 ptr = phos_by_oop.at(pho_idx);
0215
0216 EGXtraModFromVMObjFiller<OutputType>::addValuesToObject(
0217 pho, ptr, ph_conf.tok_valuemaps, pho_vmaps, overrideExistingValues_);
0218
0219 ++pho_idx;
0220 }
0221
0222 template <typename OutputType>
0223 template <typename ObjType, typename MapType>
0224 void EGXtraModFromVMObjFiller<OutputType>::addValueToObject(
0225 ObjType& obj,
0226 const edm::Ptr<reco::Candidate>& ptr,
0227 const std::unordered_map<unsigned, edm::Handle<edm::ValueMap<MapType>>>& vmaps,
0228 const std::pair<const std::string, edm::EDGetTokenT<edm::ValueMap<MapType>>>& val_map,
0229 bool overrideExistingValues) {
0230 MapType value{};
0231 assignValue(ptr, val_map.second, vmaps, value);
0232 if (overrideExistingValues || !obj.hasUserData(val_map.first)) {
0233 obj.addUserData(val_map.first, value, true);
0234 } else {
0235 throw cms::Exception("ValueNameAlreadyExists")
0236 << "Trying to add new UserData = " << val_map.first
0237 << " failed because it already exists and you didnt specify to override it (set in the config "
0238 "overrideExistingValues=cms.bool(True) )";
0239 }
0240 }
0241
0242 template <>
0243 template <typename ObjType, typename MapType>
0244 void EGXtraModFromVMObjFiller<float>::addValueToObject(
0245 ObjType& obj,
0246 const edm::Ptr<reco::Candidate>& ptr,
0247 const std::unordered_map<unsigned, edm::Handle<edm::ValueMap<MapType>>>& vmaps,
0248 const std::pair<const std::string, edm::EDGetTokenT<edm::ValueMap<MapType>>>& val_map,
0249 bool overrideExistingValues) {
0250 float value(0.0);
0251 assignValue(ptr, val_map.second, vmaps, value);
0252 if (overrideExistingValues || !obj.hasUserFloat(val_map.first)) {
0253 obj.addUserFloat(val_map.first, value, true);
0254 } else {
0255 throw cms::Exception("ValueNameAlreadyExists")
0256 << "Trying to add new UserFloat = " << val_map.first
0257 << " failed because it already exists and you didnt specify to override it (set in the config "
0258 "overrideExistingValues=cms.bool(True) )";
0259 }
0260 }
0261
0262 template <>
0263 template <typename ObjType, typename MapType>
0264 void EGXtraModFromVMObjFiller<int>::addValueToObject(
0265 ObjType& obj,
0266 const edm::Ptr<reco::Candidate>& ptr,
0267 const std::unordered_map<unsigned, edm::Handle<edm::ValueMap<MapType>>>& vmaps,
0268 const std::pair<const std::string, edm::EDGetTokenT<edm::ValueMap<MapType>>>& val_map,
0269 bool overrideExistingValues) {
0270 int value(0);
0271 assignValue(ptr, val_map.second, vmaps, value);
0272 if (overrideExistingValues || !obj.hasUserInt(val_map.first)) {
0273 obj.addUserInt(val_map.first, value, true);
0274 } else {
0275 throw cms::Exception("ValueNameAlreadyExists")
0276 << "Trying to add new UserInt = " << val_map.first
0277 << " failed because it already exists and you didnt specify to override it (set in the config "
0278 "overrideExistingValues=cms.bool(True) )";
0279 }
0280 }
0281
0282 template <>
0283 template <>
0284 inline void EGXtraModFromVMObjFiller<egmodifier::EGID>::addValuesToObject(
0285 pat::Electron& obj,
0286 const edm::Ptr<reco::Candidate>& ptr,
0287 const std::unordered_map<std::string, edm::EDGetTokenT<edm::ValueMap<float>>>& vmaps_token,
0288 const std::unordered_map<unsigned, edm::Handle<edm::ValueMap<float>>>& vmaps,
0289 bool overrideExistingValues) {
0290 std::vector<std::pair<std::string, float>> ids;
0291 for (auto itr = vmaps_token.begin(); itr != vmaps_token.end(); ++itr) {
0292 float idVal(0);
0293 assignValue(ptr, itr->second, vmaps, idVal);
0294 ids.push_back({itr->first, idVal});
0295 }
0296 std::sort(ids.begin(), ids.end(), [](auto& lhs, auto& rhs) { return lhs.first < rhs.first; });
0297 obj.setElectronIDs(ids);
0298 }
0299
0300 template <>
0301 template <>
0302 inline void EGXtraModFromVMObjFiller<egmodifier::EGID>::addValuesToObject(
0303 pat::Photon& obj,
0304 const edm::Ptr<reco::Candidate>& ptr,
0305 const std::unordered_map<std::string, edm::EDGetTokenT<edm::ValueMap<float>>>& vmaps_token,
0306 const std::unordered_map<unsigned, edm::Handle<edm::ValueMap<float>>>& vmaps,
0307 bool overrideExistingValues) {
0308
0309 std::vector<std::pair<std::string, bool>> ids;
0310 for (auto itr = vmaps_token.begin(); itr != vmaps_token.end(); ++itr) {
0311 float idVal(0);
0312 assignValue(ptr, itr->second, vmaps, idVal);
0313 ids.push_back({itr->first, idVal});
0314 }
0315 std::sort(ids.begin(), ids.end(), [](auto& lhs, auto& rhs) { return lhs.first < rhs.first; });
0316 obj.setPhotonIDs(ids);
0317 }
0318
0319 #endif