CMS 3D CMS Logo

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