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 //It assumes that the object can be added via pat::PATObject::userData, see pat::PATObject for the
29 //constraints here
30 //
31 //The class has two template arguements:
32 // MapType : c++ type of the object stored in the value mape
33 // OutputType : c++ type of how you want to store it in the pat::PATObject
34 // this exists so you can specialise int and float (and future exceptions) to use
35 // pat::PATObject::userInt and pat::PATObject::userFloat
36 // The specialisations are done by EGXtraModFromVMObjFiller::addValueToObject
37 //
38 // MapType and OutputType do not have to be same (but are by default). This is useful as it allows
39 // things like bools to and unsigned ints to be converted to ints to be stored as a userInt
40 // rather than having to go to the bother of setting up userData hooks for them
41 
42 
43 
44 template<typename OutputType>
46 public:
47  EGXtraModFromVMObjFiller()=delete;
49 
50  //will do a UserData add but specialisations exist for float and ints
51  template<typename ObjType,typename MapType>
52  static void
53  addValueToObject(ObjType& obj,
54  const edm::Ptr<reco::Candidate>& ptr,
55  const std::unordered_map<unsigned,edm::Handle<edm::ValueMap<MapType> > >& vmaps,
56  const std::pair<const std::string,edm::EDGetTokenT<edm::ValueMap<MapType> > > & val_map);
57 };
58 
59 
60 template<typename MapType,typename OutputType=MapType>
62 public:
64  using ValueMaps = std::unordered_map<std::string,ValMapToken>;
65  using ValueMapsTags = std::unordered_map<std::string,edm::InputTag>;
66  struct electron_config {
71  };
72 
73  struct photon_config {
78  };
79 
81 
82  void setEvent(const edm::Event&) override final;
83  void setEventContent(const edm::EventSetup&) override final;
84  void setConsumes(edm::ConsumesCollector&) override final;
85 
86  void modifyObject(pat::Electron&) const override final;
87  void modifyObject(pat::Photon&) const override final;
88 
89 
90 private:
92  photon_config ph_conf;
93  std::unordered_map<unsigned,edm::Ptr<reco::GsfElectron> > eles_by_oop; // indexed by original object ptr
94  std::unordered_map<unsigned,edm::Handle<edm::ValueMap<MapType> > > ele_vmaps;
95  std::unordered_map<unsigned,edm::Ptr<reco::Photon> > phos_by_oop;
96  std::unordered_map<unsigned,edm::Handle<edm::ValueMap<MapType> > > pho_vmaps;
97  mutable unsigned ele_idx,pho_idx; // hack here until we figure out why some slimmedPhotons don't have original object ptrs
98 };
99 
100 
101 template<typename MapType,typename OutputType>
102 EGExtraInfoModifierFromValueMaps<MapType,OutputType>::
104  ModifyObjectValueBase(conf) {
105  constexpr char electronSrc[] = "electronSrc";
106  constexpr char photonSrc[] = "photonSrc";
107 
108  if( conf.exists("electron_config") ) {
109  const edm::ParameterSet& electrons = conf.getParameter<edm::ParameterSet>("electron_config");
110  if( electrons.exists(electronSrc) ) e_conf.electron_src = electrons.getParameter<edm::InputTag>(electronSrc);
111  const std::vector<std::string> parameters = electrons.getParameterNames();
112  for( const std::string& name : parameters ) {
113  if( std::string(electronSrc) == name ) continue;
114  if( electrons.existsAs<edm::InputTag>(name) ) {
115  e_conf.valuemaps[name] = electrons.getParameter<edm::InputTag>(name);
116  }
117  }
118  }
119  if( conf.exists("photon_config") ) {
120  const edm::ParameterSet& photons = conf.getParameter<edm::ParameterSet>("photon_config");
121  if( photons.exists(photonSrc) ) ph_conf.photon_src = photons.getParameter<edm::InputTag>(photonSrc);
122  const std::vector<std::string> parameters = photons.getParameterNames();
123  for( const std::string& name : parameters ) {
124  if( std::string(photonSrc) == name ) continue;
125  if( photons.existsAs<edm::InputTag>(name) ) {
126  ph_conf.valuemaps[name] = photons.getParameter<edm::InputTag>(name);
127  }
128  }
129  }
130  ele_idx = pho_idx = 0;
131 }
132 
133 namespace {
134  template<typename T>
135  inline void get_product(const edm::Event& evt,
136  const edm::EDGetTokenT<edm::ValueMap<T> >& tok,
137  std::unordered_map<unsigned, edm::Handle<edm::ValueMap<T> > >& map) {
138  evt.getByToken(tok,map[tok.index()]);
139  }
140 }
141 
142 template<typename MapType,typename OutputType>
144 setEvent(const edm::Event& evt) {
145  eles_by_oop.clear();
146  phos_by_oop.clear();
147  ele_vmaps.clear();
148  pho_vmaps.clear();
149 
150  ele_idx = pho_idx = 0;
151 
152  if( !e_conf.tok_electron_src.isUninitialized() ) {
154  evt.getByToken(e_conf.tok_electron_src,eles);
155 
156  for( unsigned i = 0; i < eles->size(); ++i ) {
157  edm::Ptr<pat::Electron> ptr = eles->ptrAt(i);
158  eles_by_oop[i] = ptr;
159  }
160  }
161 
162  for( auto itr = e_conf.tok_valuemaps.begin(); itr != e_conf.tok_valuemaps.end(); ++itr ) {
163  get_product(evt,itr->second,ele_vmaps);
164  }
165 
166  if( !ph_conf.tok_photon_src.isUninitialized() ) {
168  evt.getByToken(ph_conf.tok_photon_src,phos);
169 
170  for( unsigned i = 0; i < phos->size(); ++i ) {
171  edm::Ptr<pat::Photon> ptr = phos->ptrAt(i);
172  phos_by_oop[i] = ptr;
173  }
174  }
175 
176  for( auto itr = ph_conf.tok_valuemaps.begin(); itr != ph_conf.tok_valuemaps.end(); ++itr ) {
177  get_product(evt,itr->second,pho_vmaps);
178  }
179 }
180 
181 
182 template<typename MapType,typename OutputType>
185 }
186 
187 namespace {
188  template<typename T>
189  inline void make_consumes(const edm::InputTag& tag,edm::EDGetTokenT<T>& token,
191  { if( !(empty_tag == tag) ) token = cc.consumes<T>(tag); }
192 }
193 
194 template<typename MapType,typename OutputType>
197  //setup electrons
198  if( !(empty_tag == e_conf.electron_src) ) e_conf.tok_electron_src = sumes.consumes<edm::View<pat::Electron> >(e_conf.electron_src);
199 
200  for( auto itr = e_conf.valuemaps.begin(); itr != e_conf.valuemaps.end(); ++itr ) {
201  make_consumes(itr->second,e_conf.tok_valuemaps[itr->first],sumes);
202  }
203 
204  // setup photons
205  if( !(empty_tag == ph_conf.photon_src) ) ph_conf.tok_photon_src = sumes.consumes<edm::View<pat::Photon> >(ph_conf.photon_src);
206 
207  for( auto itr = ph_conf.valuemaps.begin(); itr != ph_conf.valuemaps.end(); ++itr ) {
208  make_consumes(itr->second,ph_conf.tok_valuemaps[itr->first],sumes);
209  }
210 }
211 
212 namespace {
213  template<typename T, typename U, typename V, typename MapType >
214  inline void assignValue(const T& ptr, const U& tok, const V& map, MapType& value) {
215  if( !tok.isUninitialized() ) value = map.find(tok.index())->second->get(ptr.id(),ptr.key());
216  }
217 }
218 
219 template<typename MapType,typename OutputType>
222  // we encounter two cases here, either we are running AOD -> MINIAOD
223  // and the value maps are to the reducedEG object, can use original object ptr
224  // or we are running MINIAOD->MINIAOD and we need to fetch the pat objects to reference
226  if( !e_conf.tok_electron_src.isUninitialized() ) {
227  auto key = eles_by_oop.find(ele_idx);
228  if( key != eles_by_oop.end() ) {
229  ptr = key->second;
230  } else {
231  throw cms::Exception("BadElectronKey")
232  << "Original object pointer with key = " << ele.originalObjectRef().key()
233  << " not found in cache!";
234  }
235  }
236  //now we go through and modify the objects using the valuemaps we read in
237  for( auto itr = e_conf.tok_valuemaps.begin(); itr != e_conf.tok_valuemaps.end(); ++itr ) {
239  }
240  ++ele_idx;
241 }
242 
243 template<typename MapType,typename OutputType>
246  // we encounter two cases here, either we are running AOD -> MINIAOD
247  // and the value maps are to the reducedEG object, can use original object ptr
248  // or we are running MINIAOD->MINIAOD and we need to fetch the pat objects to reference
250  if( !ph_conf.tok_photon_src.isUninitialized() ) {
251  auto key = phos_by_oop.find(pho_idx);
252  if( key != phos_by_oop.end() ) {
253  ptr = key->second;
254  } else {
255  throw cms::Exception("BadPhotonKey")
256  << "Original object pointer with key = " << pho.originalObjectRef().key() << " not found in cache!";
257  }
258  }
259  //now we go through and modify the objects using the valuemaps we read in
260  for( auto itr = ph_conf.tok_valuemaps.begin(); itr != ph_conf.tok_valuemaps.end(); ++itr ) {
262  }
263  ++pho_idx;
264 }
265 
266 
267 template<typename OutputType>
268 template<typename ObjType,typename MapType>
271  const edm::Ptr<reco::Candidate>& ptr,
272  const std::unordered_map<unsigned,edm::Handle<edm::ValueMap<MapType> > >& vmaps,
273  const std::pair<const std::string,edm::EDGetTokenT<edm::ValueMap<MapType> > > & val_map)
274 {
275  MapType value{};
276  assignValue(ptr,val_map.second,vmaps,value);
277  if( !obj.hasUserData(val_map.first) ) {
278  obj.addUserData(val_map.first,value);
279  } else {
280  throw cms::Exception("ValueNameAlreadyExists")
281  << "Trying to add new UserData = " << val_map.first
282  << " failed because it already exists!";
283  }
284 }
285 
286 template<>
287 template<typename ObjType,typename MapType>
290  const edm::Ptr<reco::Candidate>& ptr,
291  const std::unordered_map<unsigned,edm::Handle<edm::ValueMap<MapType> > >& vmaps,
292  const std::pair<const std::string,edm::EDGetTokenT<edm::ValueMap<MapType> > >& val_map)
293 {
294  float value(0.0);
295  assignValue(ptr,val_map.second,vmaps,value);
296  if( !obj.hasUserFloat(val_map.first) ) {
297  obj.addUserFloat(val_map.first,value);
298  } else {
299  throw cms::Exception("ValueNameAlreadyExists")
300  << "Trying to add new UserFloat = " << val_map.first
301  << " failed because it already exists!";
302  }
303 }
304 
305 template<>
306 template<typename ObjType,typename MapType>
309  const edm::Ptr<reco::Candidate>& ptr,
310  const std::unordered_map<unsigned,edm::Handle<edm::ValueMap<MapType> > >& vmaps,
311  const std::pair<const std::string,edm::EDGetTokenT<edm::ValueMap<MapType> > >& val_map)
312 {
313  int value(0);
314  assignValue(ptr,val_map.second,vmaps,value);
315  if( !obj.hasUserInt(val_map.first) ) {
316  obj.addUserInt(val_map.first,value);
317  } else {
318  throw cms::Exception("ValueNameAlreadyExists")
319  << "Trying to add new UserInt = " << val_map.first
320  << " failed because it already exists!";
321  }
322 }
323 
324 
325 
326 #endif
std::unordered_map< std::string, ValMapToken > ValueMaps
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
T getParameter(std::string const &) const
Analysis-level Photon class.
Definition: Photon.h:47
std::unordered_map< std::string, edm::InputTag > ValueMapsTags
Definition: Photon.py:1
bool existsAs(std::string const &parameterName, bool trackiness=true) const
checks if a parameter exists as a given type
Definition: ParameterSet.h:186
key_type key() const
Definition: Ptr.h:185
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:460
bool exists(std::string const &parameterName) const
checks if a parameter exists
void modifyObject(pat::Electron &) const override final
#define constexpr
Definition: HeavyIon.h:7
U second(std::pair< T, U > const &p)
~EGXtraModFromVMObjFiller()=delete
void setEventContent(const edm::EventSetup &) override final
def template(fileName, svg, replaceme="REPLACEME")
Definition: svgfig.py:520
Definition: value.py:1
std::vector< std::string > getParameterNames() const
const edm::Ptr< reco::Candidate > & originalObjectRef() const
reference to original object. Returns a null reference if not available
Definition: PATObject.h:500
Analysis-level electron class.
Definition: Electron.h:52
void setEvent(const edm::Event &) override final
edm::EDGetTokenT< edm::View< pat::Electron > > tok_electron_src
fixed size matrix
HLT enums.
edm::EDGetTokenT< edm::View< pat::Photon > > tok_photon_src
long double T
void setConsumes(edm::ConsumesCollector &) override final
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)