CMS 3D CMS Logo

EGExtraInfoModifierFromValueMaps.h
Go to the documentation of this file.
1 #ifndef RecoEgamma_EgammaTools_EGExtraInfoModifierFromValueMaps_h
2 #define RecoEgamma_EgammaTools_EGExtraInfoModifierFromValueMaps_h
3 
5 
9 
12 
13 #include <unordered_map>
14 
15 namespace {
16  const edm::InputTag empty_tag;
17 }
18 
19 //class: EGExtraInfoModifierFromValueMaps
20 //
21 //this is a generalisation of EGExtraInfoModiferFromFloatValueMaps
22 //orginal author of EGExtraInfoModiferFromFloatValueMaps : L. Gray (FNAL)
23 //converter to templated version: S. Harper (RAL)
24 //
25 //This class allows an data of an arbitrary type in a ValueMap for pat::Electrons or pat::Photons
26 //to be put in the pat::Electron/Photon as userData, userInt or userFloat
27 //
28 //IMPORTANT INFO:
29 //by default the ValueMap is keyed to the object the pat::Electron/Photon was created from
30 //if you want to use a ValueMap which is keyed to a different collection (ie perhaps the same
31 //as the electrons you are aring, you must set "electronSrc" and "photonSrc" inside the ele/pho configs
32 //so if you are running over slimmedElectrons and want to read a ValueMap keyed to slimmedElectrons
33 //you need to set "electron_config.electronSrc = cms.InputTag("slimmedElectrons")"
34 //
35 //It assumes that the object can be added via pat::PATObject::userData, see pat::PATObject for the
36 //constraints here
37 //
38 //The class has two template arguements:
39 // MapType : c++ type of the object stored in the value mape
40 // OutputType : c++ type of how you want to store it in the pat::PATObject
41 // this exists so you can specialise int and float (and future exceptions) to use
42 // pat::PATObject::userInt and pat::PATObject::userFloat
43 // The specialisations are done by EGXtraModFromVMObjFiller::addValueToObject
44 //
45 // MapType and OutputType do not have to be same (but are by default). This is useful as it allows
46 // things like bools to and unsigned ints to be converted to ints to be stored as a userInt
47 // rather than having to go to the bother of setting up userData hooks for them
48 
49 namespace egmodifier {
50  class EGID {}; //dummy class to be used as a template arguement
51 } // namespace egmodifier
52 
53 template <typename OutputType>
55 public:
56  EGXtraModFromVMObjFiller() = delete;
57  ~EGXtraModFromVMObjFiller() = delete;
58 
59  //will do a UserData add but specialisations exist for float and ints
60  template <typename ObjType, typename MapType>
61  static void addValueToObject(ObjType& obj,
62  const edm::Ptr<reco::Candidate>& ptr,
63  const std::unordered_map<unsigned, edm::Handle<edm::ValueMap<MapType>>>& vmaps,
64  const std::pair<const std::string, edm::EDGetTokenT<edm::ValueMap<MapType>>>& val_map,
65  bool overrideExistingValues);
66 
67  template <typename ObjType, typename MapType>
68  static void addValuesToObject(
69  ObjType& obj,
70  const edm::Ptr<reco::Candidate>& ptr,
71  const std::unordered_map<std::string, edm::EDGetTokenT<edm::ValueMap<MapType>>>& vmaps_token,
72  const std::unordered_map<unsigned, edm::Handle<edm::ValueMap<MapType>>>& vmaps,
73  bool overrideExistingValues) {
74  for (auto itr = vmaps_token.begin(); itr != vmaps_token.end(); ++itr) {
75  addValueToObject(obj, ptr, vmaps, *itr, overrideExistingValues);
76  }
77  }
78 };
79 
80 template <typename MapType, typename OutputType = MapType>
82 public:
84  using ValueMaps = std::unordered_map<std::string, ValMapToken>;
85  struct electron_config {
88  };
89 
90  struct photon_config {
93  };
94 
96 
97  void setEvent(const edm::Event&) final;
98 
99  void modifyObject(pat::Electron&) const final;
100  void modifyObject(pat::Photon&) const final;
101 
102 private:
105  std::vector<edm::Ptr<reco::GsfElectron>> eles_by_oop; // indexed by original object ptr
106  std::unordered_map<unsigned, edm::Handle<edm::ValueMap<MapType>>> ele_vmaps;
107  std::vector<edm::Ptr<reco::Photon>> phos_by_oop;
108  std::unordered_map<unsigned, edm::Handle<edm::ValueMap<MapType>>> pho_vmaps;
109  mutable unsigned ele_idx,
110  pho_idx; // hack here until we figure out why some slimmedPhotons don't have original object ptrs
112 };
113 
114 template <typename MapType, typename OutputType>
117  : ModifyObjectValueBase(conf) {
118  constexpr char electronSrc[] = "electronSrc";
119  constexpr char photonSrc[] = "photonSrc";
121  conf.exists("overrideExistingValues") ? conf.getParameter<bool>("overrideExistingValues") : false;
122  if (conf.exists("electron_config")) {
123  const edm::ParameterSet& electrons = conf.getParameter<edm::ParameterSet>("electron_config");
124  if (electrons.exists(electronSrc))
127 
128  const std::vector<std::string> parameters = electrons.getParameterNames();
129  for (const std::string& name : parameters) {
130  if (std::string(electronSrc) == name)
131  continue;
132  if (electrons.existsAs<edm::InputTag>(name)) {
134  }
135  }
136  }
137  if (conf.exists("photon_config")) {
138  const edm::ParameterSet& photons = conf.getParameter<edm::ParameterSet>("photon_config");
139  if (photons.exists(photonSrc))
141  const std::vector<std::string> parameters = photons.getParameterNames();
142  for (const std::string& name : parameters) {
143  if (std::string(photonSrc) == name)
144  continue;
145  if (photons.existsAs<edm::InputTag>(name)) {
147  }
148  }
149  }
150  ele_idx = pho_idx = 0;
151 }
152 
153 template <typename MapType, typename OutputType>
155  eles_by_oop.clear();
156  phos_by_oop.clear();
157  ele_vmaps.clear();
158  pho_vmaps.clear();
159 
160  ele_idx = pho_idx = 0;
161 
162  if (!e_conf.tok_electron_src.isUninitialized()) {
163  auto eles = evt.getHandle(e_conf.tok_electron_src);
164 
165  eles_by_oop.resize(eles->size());
166  std::copy(eles->ptrs().begin(), eles->ptrs().end(), eles_by_oop.begin());
167  }
168 
169  for (auto const& itr : e_conf.tok_valuemaps) {
170  ele_vmaps[itr.second.index()] = evt.getHandle(itr.second);
171  }
172 
173  if (!ph_conf.tok_photon_src.isUninitialized()) {
174  auto phos = evt.getHandle(ph_conf.tok_photon_src);
175 
176  phos_by_oop.resize(phos->size());
177  std::copy(phos->ptrs().begin(), phos->ptrs().end(), phos_by_oop.begin());
178  }
179 
180  for (auto const& itr : ph_conf.tok_valuemaps) {
181  pho_vmaps[itr.second.index()] = evt.getHandle(itr.second);
182  }
183 }
184 
185 namespace {
186  template <typename T, typename U, typename V, typename MapType>
187  inline void assignValue(const T& ptr, const U& tok, const V& map, MapType& value) {
188  if (!tok.isUninitialized())
189  value = map.find(tok.index())->second->get(ptr.id(), ptr.key());
190  }
191 } // namespace
192 
193 template <typename MapType, typename OutputType>
195  // we encounter two cases here, either we are running AOD -> MINIAOD
196  // and the value maps are to the reducedEG object, can use original object ptr
197  // or we are running MINIAOD->MINIAOD and we need to fetch the pat objects to reference
199  if (!e_conf.tok_electron_src.isUninitialized())
200  ptr = eles_by_oop.at(ele_idx);
201  //now we go through and modify the objects using the valuemaps we read in
203  ele, ptr, e_conf.tok_valuemaps, ele_vmaps, overrideExistingValues_);
204  ++ele_idx;
205 }
206 
207 template <typename MapType, typename OutputType>
209  // we encounter two cases here, either we are running AOD -> MINIAOD
210  // and the value maps are to the reducedEG object, can use original object ptr
211  // or we are running MINIAOD->MINIAOD and we need to fetch the pat objects to reference
213  if (!ph_conf.tok_photon_src.isUninitialized())
214  ptr = phos_by_oop.at(pho_idx);
215  //now we go through and modify the objects using the valuemaps we read in
217  pho, ptr, ph_conf.tok_valuemaps, pho_vmaps, overrideExistingValues_);
218 
219  ++pho_idx;
220 }
221 
222 template <typename OutputType>
223 template <typename ObjType, typename MapType>
225  ObjType& obj,
226  const edm::Ptr<reco::Candidate>& ptr,
227  const std::unordered_map<unsigned, edm::Handle<edm::ValueMap<MapType>>>& vmaps,
228  const std::pair<const std::string, edm::EDGetTokenT<edm::ValueMap<MapType>>>& val_map,
229  bool overrideExistingValues) {
230  MapType value{};
231  assignValue(ptr, val_map.second, vmaps, value);
232  if (overrideExistingValues || !obj.hasUserData(val_map.first)) {
233  obj.addUserData(val_map.first, value, true);
234  } else {
235  throw cms::Exception("ValueNameAlreadyExists")
236  << "Trying to add new UserData = " << val_map.first
237  << " failed because it already exists and you didnt specify to override it (set in the config "
238  "overrideExistingValues=cms.bool(True) )";
239  }
240 }
241 
242 template <>
243 template <typename ObjType, typename MapType>
245  ObjType& obj,
246  const edm::Ptr<reco::Candidate>& ptr,
247  const std::unordered_map<unsigned, edm::Handle<edm::ValueMap<MapType>>>& vmaps,
248  const std::pair<const std::string, edm::EDGetTokenT<edm::ValueMap<MapType>>>& val_map,
249  bool overrideExistingValues) {
250  float value(0.0);
251  assignValue(ptr, val_map.second, vmaps, value);
252  if (overrideExistingValues || !obj.hasUserFloat(val_map.first)) {
253  obj.addUserFloat(val_map.first, value, true);
254  } else {
255  throw cms::Exception("ValueNameAlreadyExists")
256  << "Trying to add new UserFloat = " << val_map.first
257  << " failed because it already exists and you didnt specify to override it (set in the config "
258  "overrideExistingValues=cms.bool(True) )";
259  }
260 }
261 
262 template <>
263 template <typename ObjType, typename MapType>
265  ObjType& obj,
266  const edm::Ptr<reco::Candidate>& ptr,
267  const std::unordered_map<unsigned, edm::Handle<edm::ValueMap<MapType>>>& vmaps,
268  const std::pair<const std::string, edm::EDGetTokenT<edm::ValueMap<MapType>>>& val_map,
269  bool overrideExistingValues) {
270  int value(0);
271  assignValue(ptr, val_map.second, vmaps, value);
272  if (overrideExistingValues || !obj.hasUserInt(val_map.first)) {
273  obj.addUserInt(val_map.first, value, true);
274  } else {
275  throw cms::Exception("ValueNameAlreadyExists")
276  << "Trying to add new UserInt = " << val_map.first
277  << " failed because it already exists and you didnt specify to override it (set in the config "
278  "overrideExistingValues=cms.bool(True) )";
279  }
280 }
281 
282 template <>
283 template <>
286  const edm::Ptr<reco::Candidate>& ptr,
287  const std::unordered_map<std::string, edm::EDGetTokenT<edm::ValueMap<float>>>& vmaps_token,
288  const std::unordered_map<unsigned, edm::Handle<edm::ValueMap<float>>>& vmaps,
289  bool overrideExistingValues) {
290  std::vector<std::pair<std::string, float>> ids;
291  for (auto itr = vmaps_token.begin(); itr != vmaps_token.end(); ++itr) {
292  float idVal(0);
293  assignValue(ptr, itr->second, vmaps, idVal);
294  ids.push_back({itr->first, idVal});
295  }
296  std::sort(ids.begin(), ids.end(), [](auto& lhs, auto& rhs) { return lhs.first < rhs.first; });
297  obj.setElectronIDs(ids);
298 }
299 
300 template <>
301 template <>
303  pat::Photon& obj,
304  const edm::Ptr<reco::Candidate>& ptr,
305  const std::unordered_map<std::string, edm::EDGetTokenT<edm::ValueMap<float>>>& vmaps_token,
306  const std::unordered_map<unsigned, edm::Handle<edm::ValueMap<float>>>& vmaps,
307  bool overrideExistingValues) {
308  //we do a float->bool conversion here to make things easier to be consistent with electrons
309  std::vector<std::pair<std::string, bool>> ids;
310  for (auto itr = vmaps_token.begin(); itr != vmaps_token.end(); ++itr) {
311  float idVal(0);
312  assignValue(ptr, itr->second, vmaps, idVal);
313  ids.push_back({itr->first, idVal});
314  }
315  std::sort(ids.begin(), ids.end(), [](auto& lhs, auto& rhs) { return lhs.first < rhs.first; });
316  obj.setPhotonIDs(ids);
317 }
318 
319 #endif
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
Analysis-level Photon class.
Definition: Photon.h:46
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
bool exists(std::string const &parameterName) const
checks if a parameter exists
std::unordered_map< unsigned, edm::Handle< edm::ValueMap< MapType > > > ele_vmaps
EGExtraInfoModifierFromValueMaps(const edm::ParameterSet &conf, edm::ConsumesCollector &cc)
static void addValueToObject(ObjType &obj, const edm::Ptr< reco::Candidate > &ptr, const std::unordered_map< unsigned, edm::Handle< edm::ValueMap< MapType >>> &vmaps, const std::pair< const std::string, edm::EDGetTokenT< edm::ValueMap< MapType >>> &val_map, bool overrideExistingValues)
std::unordered_map< unsigned, edm::Handle< edm::ValueMap< MapType > > > pho_vmaps
U second(std::pair< T, U > const &p)
void modifyObject(pat::Electron &) const final
uint32_t T const *__restrict__ uint32_t const *__restrict__ int32_t int Histo::index_type cudaStream_t V
static void addValuesToObject(ObjType &obj, const edm::Ptr< reco::Candidate > &ptr, const std::unordered_map< std::string, edm::EDGetTokenT< edm::ValueMap< MapType >>> &vmaps_token, const std::unordered_map< unsigned, edm::Handle< edm::ValueMap< MapType >>> &vmaps, bool overrideExistingValues)
edm::EDGetTokenT< edm::View< reco::GsfElectron > > tok_electron_src
~EGXtraModFromVMObjFiller()=delete
std::vector< edm::Ptr< reco::Photon > > phos_by_oop
Definition: value.py:1
std::vector< edm::Ptr< reco::GsfElectron > > eles_by_oop
std::unordered_map< std::string, ValMapToken > ValueMaps
Analysis-level electron class.
Definition: Electron.h:51
const std::string & name() const
Handle< PROD > getHandle(EDGetTokenT< PROD > token) const
Definition: Event.h:563
const edm::Ptr< reco::Candidate > & originalObjectRef() const
reference to original object. Returns a null reference if not available
Definition: PATObject.h:537
long double T
edm::EDGetTokenT< edm::View< reco::Photon > > tok_photon_src