CMS 3D CMS Logo

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