CMS 3D CMS Logo

PhotonMVAEstimatorRun2Spring15NonTrig.cc
Go to the documentation of this file.
2 
4 
5 #include "TMVA/MethodBDT.h"
6 
9  _MethodName("BDTG method"),
10  _useValueMaps(conf.getParameter<bool>("useValueMaps")),
11  _full5x5SigmaIEtaIEtaMapLabel(conf.getParameter<edm::InputTag>("full5x5SigmaIEtaIEtaMap")),
12  _full5x5SigmaIEtaIPhiMapLabel(conf.getParameter<edm::InputTag>("full5x5SigmaIEtaIPhiMap")),
13  _full5x5E1x3MapLabel(conf.getParameter<edm::InputTag>("full5x5E1x3Map")),
14  _full5x5E2x2MapLabel(conf.getParameter<edm::InputTag>("full5x5E2x2Map")),
15  _full5x5E2x5MaxMapLabel(conf.getParameter<edm::InputTag>("full5x5E2x5MaxMap")),
16  _full5x5E5x5MapLabel(conf.getParameter<edm::InputTag>("full5x5E5x5Map")),
17  _esEffSigmaRRMapLabel(conf.getParameter<edm::InputTag>("esEffSigmaRRMap")),
18  _phoChargedIsolationLabel(conf.getParameter<edm::InputTag>("phoChargedIsolation")),
19  _phoPhotonIsolationLabel(conf.getParameter<edm::InputTag>("phoPhotonIsolation")),
20  _phoWorstChargedIsolationLabel(conf.getParameter<edm::InputTag>("phoWorstChargedIsolation")),
21  _rhoLabel(conf.getParameter<edm::InputTag>("rho"))
22 {
23 
24  //
25  // Construct the MVA estimators
26  //
27  _tag = conf.getParameter<std::string>("mvaTag");
28 
29  const std::vector <std::string> weightFileNames
30  = conf.getParameter<std::vector<std::string> >("weightFileNames");
31 
32  if( (int)(weightFileNames.size()) != nCategories )
33  throw cms::Exception("MVA config failure: ")
34  << "wrong number of weightfiles" << std::endl;
35 
36  _gbrForests.clear();
37  // The method name is just a key to retrieve this method later, it is not
38  // a control parameter for a reader (the full definition of the MVA type and
39  // everything else comes from the xml weight files).
40 
41  // Create a TMVA reader object for each category
42  for(int i=0; i<nCategories; i++){
43 
44  // Use unique_ptr so that all readers are properly cleaned up
45  // when the vector clear() is called in the destructor
46 
47  edm::FileInPath weightFile( weightFileNames[i] );
48  _gbrForests.push_back( createSingleReader(i, weightFile ) );
49 
50  }
51 
52 }
53 
56 }
57 
59 mvaValue(const edm::Ptr<reco::Candidate>& particle, const edm::Event& iEvent) const {
60 
61  const int iCategory = findCategory( particle );
62  const std::vector<float> vars = std::move( fillMVAVariables( particle, iEvent ) );
63 
64  const float result = _gbrForests.at(iCategory)->GetClassifier(vars.data());
65 
66  // DEBUG
67  const bool debug = false;
68  if( debug ){
69  printf("Printout of the photon variable inputs for MVA:\n");
70  printf(" varPhi_ %f\n", vars[0] );
71  printf(" varR9_ %f\n", vars[1] );
72  printf(" varSieie_ %f\n", vars[2] );
73  printf(" varSieip_ %f\n", vars[3] );
74  printf(" varE1x3overE5x5_ %f\n", vars[4] );
75  printf(" varE2x2overE5x5_ %f\n", vars[5] );
76  printf(" varE2x5overE5x5_ %f\n", vars[6] );
77  printf(" varSCEta_ %f\n", vars[7] );
78  printf(" varRawE_ %f\n", vars[8] );
79  printf(" varSCEtaWidth_ %f\n", vars[9] );
80  printf(" varSCPhiWidth_ %f\n", vars[10] );
81  printf(" varRho_ %f\n", vars[11] );
82  printf(" varPhoIsoRaw_ %f\n", vars[12] );
83  printf(" varChIsoRaw_ %f\n", vars[13] );
84  printf(" varWorstChRaw_ %f\n", vars[14] );
85  if( isEndcapCategory( iCategory ) ) {
86  printf(" varESEnOverRawE_ %f\n", vars[15] ); // for endcap MVA only
87  printf(" varESEffSigmaRR_ %f\n", vars[16] ); // for endcap MVA only
88  // The spectators
89  printf(" varPt_ %f\n", vars[17] );
90  printf(" varEta_ %f\n", vars[18] );
91  } else {
92  // The spectators
93  printf(" varPt_ %f\n", vars[15] );
94  printf(" varEta_ %f\n", vars[16] );
95  }
96  }
97 
98  return result;
99 }
100 
102 
103  // Try to cast the particle into a reco particle.
104  // This should work for both reco and pat.
105  const edm::Ptr<reco::Photon> phoRecoPtr = ( edm::Ptr<reco::Photon> )particle;
106  if( phoRecoPtr.isNull() )
107  throw cms::Exception("MVA failure: ")
108  << " given particle is expected to be reco::Photon or pat::Photon," << std::endl
109  << " but appears to be neither" << std::endl;
110 
111  float eta = phoRecoPtr->superCluster()->eta();
112 
113  //
114  // Determine the category
115  //
116  int iCategory = UNDEFINED;
117  const float ebeeSplit = 1.479; // division between barrel and endcap
118 
119  if ( std::abs(eta) < ebeeSplit)
120  iCategory = CAT_EB;
121 
122  if (std::abs(eta) >= ebeeSplit)
123  iCategory = CAT_EE;
124 
125  return iCategory;
126 }
127 
130 
131  // For this specific MVA the function is trivial, but kept for possible
132  // future evolution to an MVA with more categories in eta
133  bool isEndcap = false;
134  if( category == CAT_EE )
135  isEndcap = true;
136 
137  return isEndcap;
138 }
139 
140 
141 std::unique_ptr<const GBRForest> PhotonMVAEstimatorRun2Spring15NonTrig::
142 createSingleReader(const int iCategory, const edm::FileInPath &weightFile){
143 
144  //
145  // Create the reader
146  //
147  TMVA::Reader tmpTMVAReader( "!Color:Silent:Error" );
148 
149  //
150  // Configure all variables and spectators. Note: the order and names
151  // must match what is found in the xml weights file!
152  //
153 
154  tmpTMVAReader.AddVariable("recoPhi" , &_allMVAVars.varPhi);
155  tmpTMVAReader.AddVariable("r9" , &_allMVAVars.varR9);
156  tmpTMVAReader.AddVariable("sieieFull5x5", &_allMVAVars.varSieie);
157  tmpTMVAReader.AddVariable("sieipFull5x5", &_allMVAVars.varSieip);
158  tmpTMVAReader.AddVariable("e1x3Full5x5/e5x5Full5x5", &_allMVAVars.varE1x3overE5x5);
159  tmpTMVAReader.AddVariable("e2x2Full5x5/e5x5Full5x5", &_allMVAVars.varE2x2overE5x5);
160  tmpTMVAReader.AddVariable("e2x5Full5x5/e5x5Full5x5", &_allMVAVars.varE2x5overE5x5);
161  tmpTMVAReader.AddVariable("recoSCEta" , &_allMVAVars.varSCEta);
162  tmpTMVAReader.AddVariable("rawE" , &_allMVAVars.varRawE);
163  tmpTMVAReader.AddVariable("scEtaWidth", &_allMVAVars.varSCEtaWidth);
164  tmpTMVAReader.AddVariable("scPhiWidth", &_allMVAVars.varSCPhiWidth);
165 
166  // Endcap only variables
167  if( isEndcapCategory(iCategory) ){
168  tmpTMVAReader.AddVariable("esEn/rawE" , &_allMVAVars.varESEnOverRawE);
169  tmpTMVAReader.AddVariable("esRR" , &_allMVAVars.varESEffSigmaRR);
170  }
171 
172  // Pileup
173  tmpTMVAReader.AddVariable("rho" , &_allMVAVars.varRho);
174 
175  // Isolations
176  tmpTMVAReader.AddVariable("phoIsoRaw" , &_allMVAVars.varPhoIsoRaw);
177  tmpTMVAReader.AddVariable("chIsoRaw" , &_allMVAVars.varChIsoRaw);
178  tmpTMVAReader.AddVariable("chWorstRaw", &_allMVAVars.varWorstChRaw);
179 
180  // Spectators
181  tmpTMVAReader.AddSpectator("recoPt" , &_allMVAVars.varPt);
182  tmpTMVAReader.AddSpectator("recoEta", &_allMVAVars.varEta);
183 
184  //
185  // Book the method and set up the weights file
186  //
187  tmpTMVAReader.BookMVA(_MethodName , weightFile.fullPath());
188 
189  return std::make_unique<const GBRForest>(dynamic_cast<TMVA::MethodBDT*>( tmpTMVAReader.FindMVA(_MethodName) ) );
190 
191 }
192 
193 // A function that should work on both pat and reco objects
195 
196  //
197  // Declare all value maps corresponding to the above tokens
198  //
206  //
207  edm::Handle<edm::ValueMap<float> > phoChargedIsolationMap;
208  edm::Handle<edm::ValueMap<float> > phoPhotonIsolationMap;
209  edm::Handle<edm::ValueMap<float> > phoWorstChargedIsolationMap;
210 
211  // Rho will be pulled from the event content
213 
214  // Get the full5x5 and ES maps
215  if( _useValueMaps ) {
216  iEvent.getByLabel(_full5x5SigmaIEtaIEtaMapLabel, full5x5SigmaIEtaIEtaMap);
217  iEvent.getByLabel(_full5x5SigmaIEtaIPhiMapLabel, full5x5SigmaIEtaIPhiMap);
218  iEvent.getByLabel(_full5x5E1x3MapLabel, full5x5E1x3Map);
219  iEvent.getByLabel(_full5x5E2x2MapLabel, full5x5E2x2Map);
220  iEvent.getByLabel(_full5x5E2x5MaxMapLabel, full5x5E2x5MaxMap);
221  iEvent.getByLabel(_full5x5E5x5MapLabel, full5x5E5x5Map);
222  iEvent.getByLabel(_esEffSigmaRRMapLabel, esEffSigmaRRMap);
223  }
224 
225  // Get the isolation maps
226  iEvent.getByLabel(_phoChargedIsolationLabel, phoChargedIsolationMap);
227  iEvent.getByLabel(_phoPhotonIsolationLabel, phoPhotonIsolationMap);
228  iEvent.getByLabel(_phoWorstChargedIsolationLabel, phoWorstChargedIsolationMap);
229 
230  // Get rho
231  iEvent.getByLabel(_rhoLabel,rho);
232 
233  // Make sure everything is retrieved successfully
234  if(! ( ( !_useValueMaps || ( full5x5SigmaIEtaIEtaMap.isValid()
235  && full5x5SigmaIEtaIPhiMap.isValid()
236  && full5x5E1x3Map.isValid()
237  && full5x5E2x2Map.isValid()
238  && full5x5E2x5MaxMap.isValid()
239  && full5x5E5x5Map.isValid()
240  && esEffSigmaRRMap.isValid() ) )
241  && phoChargedIsolationMap.isValid()
242  && phoPhotonIsolationMap.isValid()
243  && phoWorstChargedIsolationMap.isValid()
244  && rho.isValid() ) )
245  throw cms::Exception("MVA failure: ")
246  << "Failed to retrieve event content needed for this MVA"
247  << std::endl
248  << "Check python MVA configuration file and make sure all needed"
249  << std::endl
250  << "producers are running upstream" << std::endl;
251 
252  // Try to cast the particle into a reco particle.
253  // This should work for both reco and pat.
254  const edm::Ptr<reco::Photon> phoRecoPtr(particle);
255  if( phoRecoPtr.isNull() )
256  throw cms::Exception("MVA failure: ")
257  << " given particle is expected to be reco::Photon or pat::Photon," << std::endl
258  << " but appears to be neither" << std::endl;
259 
260  // Both pat and reco particles have exactly the same accessors.
261  auto superCluster = phoRecoPtr->superCluster();
262  // Full 5x5 cluster shapes. We could take some of this directly from
263  // the photon object, but some of these are not available.
264  float e1x3 = std::numeric_limits<float>::max();
265  float e2x2 = std::numeric_limits<float>::max();
268  float full5x5_sigmaIetaIeta = std::numeric_limits<float>::max();
269  float full5x5_sigmaIetaIphi = std::numeric_limits<float>::max();
270  float effSigmaRR = std::numeric_limits<float>::max();
271 
272  AllVariables allMVAVars;
273 
274  if( _useValueMaps ) { //(before 752)
275  // in principle, in the photon object as well
276  // not in the photon object
277  e1x3 = (*full5x5E1x3Map )[ phoRecoPtr ];
278  e2x2 = (*full5x5E2x2Map )[ phoRecoPtr ];
279  e2x5 = (*full5x5E2x5MaxMap)[ phoRecoPtr ];
280  e5x5 = (*full5x5E5x5Map )[ phoRecoPtr ];
281  full5x5_sigmaIetaIeta = (*full5x5SigmaIEtaIEtaMap)[ phoRecoPtr ];
282  full5x5_sigmaIetaIphi = (*full5x5SigmaIEtaIPhiMap)[ phoRecoPtr ];
283  effSigmaRR = (*esEffSigmaRRMap)[ phoRecoPtr ];
284  } else {
285  // from 753
286  const auto& full5x5_pss = phoRecoPtr->full5x5_showerShapeVariables();
287  e1x3 = full5x5_pss.e1x3;
288  e2x2 = full5x5_pss.e2x2;
289  e2x5 = full5x5_pss.e2x5Max;
290  e5x5 = full5x5_pss.e5x5;
291  full5x5_sigmaIetaIeta = full5x5_pss.sigmaIetaIeta;
292  full5x5_sigmaIetaIphi = full5x5_pss.sigmaIetaIphi;
293  effSigmaRR = full5x5_pss.effSigmaRR;
294  }
295 
296  allMVAVars.varPhi = phoRecoPtr->phi();
297  allMVAVars.varR9 = phoRecoPtr->r9() ;
298  allMVAVars.varSieie = full5x5_sigmaIetaIeta;
299  allMVAVars.varSieip = full5x5_sigmaIetaIphi;
300  allMVAVars.varE1x3overE5x5 = e1x3/e5x5;
301  allMVAVars.varE2x2overE5x5 = e2x2/e5x5;
302  allMVAVars.varE2x5overE5x5 = e2x5/e5x5;
303  allMVAVars.varSCEta = superCluster->eta();
304  allMVAVars.varRawE = superCluster->rawEnergy();
305  allMVAVars.varSCEtaWidth = superCluster->etaWidth();
306  allMVAVars.varSCPhiWidth = superCluster->phiWidth();
307  allMVAVars.varESEnOverRawE = superCluster->preshowerEnergy() / superCluster->rawEnergy();
308  allMVAVars.varESEffSigmaRR = effSigmaRR;
309  allMVAVars.varRho = *rho;
310  allMVAVars.varPhoIsoRaw = (*phoPhotonIsolationMap)[phoRecoPtr];
311  allMVAVars.varChIsoRaw = (*phoChargedIsolationMap)[phoRecoPtr];
312  allMVAVars.varWorstChRaw = (*phoWorstChargedIsolationMap)[phoRecoPtr];
313  // Declare spectator vars
314  allMVAVars.varPt = phoRecoPtr->pt();
315  allMVAVars.varEta = phoRecoPtr->eta();
316 
317  constrainMVAVariables(allMVAVars);
318 
319  std::vector<float> vars;
320  if( isEndcapCategory( findCategory( particle ) ) ) {
321  vars = std::move( packMVAVariables(allMVAVars.varPhi,
322  allMVAVars.varR9,
323  allMVAVars.varSieie,
324  allMVAVars.varSieip,
325  allMVAVars.varE1x3overE5x5,
326  allMVAVars.varE2x2overE5x5,
327  allMVAVars.varE2x5overE5x5,
328  allMVAVars.varSCEta,
329  allMVAVars.varRawE,
330  allMVAVars.varSCEtaWidth,
331  allMVAVars.varSCPhiWidth,
332  allMVAVars.varESEnOverRawE,
333  allMVAVars.varESEffSigmaRR,
334  allMVAVars.varRho,
335  allMVAVars.varPhoIsoRaw,
336  allMVAVars.varChIsoRaw,
337  allMVAVars.varWorstChRaw,
338  // Declare spectator vars
339  allMVAVars.varPt,
340  allMVAVars.varEta)
341  );
342  } else {
343  vars = std::move( packMVAVariables(allMVAVars.varPhi,
344  allMVAVars.varR9,
345  allMVAVars.varSieie,
346  allMVAVars.varSieip,
347  allMVAVars.varE1x3overE5x5,
348  allMVAVars.varE2x2overE5x5,
349  allMVAVars.varE2x5overE5x5,
350  allMVAVars.varSCEta,
351  allMVAVars.varRawE,
352  allMVAVars.varSCEtaWidth,
353  allMVAVars.varSCPhiWidth,
354  allMVAVars.varRho,
355  allMVAVars.varPhoIsoRaw,
356  allMVAVars.varChIsoRaw,
357  allMVAVars.varWorstChRaw,
358  // Declare spectator vars
359  allMVAVars.varPt,
360  allMVAVars.varEta)
361  );
362  }
363  return vars;
364 }
365 
367 
368  // Check that variables do not have crazy values
369 
370  // This function is currently empty as this specific MVA was not
371  // developed with restricting variables to specific physical ranges.
372  return;
373 
374 }
375 
377  if( _useValueMaps ) {
385  }
389  cc.consumes<double>(_rhoLabel);
390 }
391 
394  "PhotonMVAEstimatorRun2Spring15NonTrig");
T getParameter(std::string const &) const
double eta() const final
momentum pseudorapidity
std::unique_ptr< const GBRForest > createSingleReader(const int iCategory, const edm::FileInPath &weightFile)
double pt() const final
transverse momentum
reco::SuperClusterRef superCluster() const override
Ref to SuperCluster.
std::vector< float > packMVAVariables(const Args...args) const
int iEvent
Definition: GenABIO.cc:230
PhotonMVAEstimatorRun2Spring15NonTrig(const edm::ParameterSet &conf)
bool isNull() const
Checks for null.
Definition: Ptr.h:164
void setConsumes(edm::ConsumesCollector &&) const override
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
bool isValid() const
Definition: HandleBase.h:74
bool getByLabel(InputTag const &tag, Handle< PROD > &result) const
Definition: Event.h:464
bool isEndcap(GeomDetEnumerators::SubDetector m)
#define debug
Definition: HDRShower.cc:19
float mvaValue(const edm::Ptr< reco::Candidate > &particle, const edm::Event &) const override
HLT enums.
const ShowerShape & full5x5_showerShapeVariables() const
Definition: Photon.h:198
float r9() const
Definition: Photon.h:228
int findCategory(const edm::Ptr< reco::Candidate > &particle) const override
std::string fullPath() const
Definition: FileInPath.cc:184
#define DEFINE_EDM_PLUGIN(factory, type, name)
std::vector< std::unique_ptr< const GBRForest > > _gbrForests
std::vector< float > fillMVAVariables(const edm::Ptr< reco::Candidate > &particle, const edm::Event &iEvent) const override
double phi() const final
momentum azimuthal angle
def move(src, dest)
Definition: eostools.py:510