CMS 3D CMS Logo

PhotonMVAEstimatorRunIIFall17.cc
Go to the documentation of this file.
3 #include "TMVA/MethodBDT.h"
4 #include <vector>
5 
8  methodName_("BDTG method"),
9  phoChargedIsolationLabel_(conf.getParameter<edm::InputTag>("phoChargedIsolation")),
10  phoPhotonIsolationLabel_(conf.getParameter<edm::InputTag>("phoPhotonIsolation")),
11  phoWorstChargedIsolationLabel_(conf.getParameter<edm::InputTag>("phoWorstChargedIsolation")),
12  rhoLabel_(conf.getParameter<edm::InputTag>("rho")),
13  effectiveAreas_( (conf.getParameter<edm::FileInPath>("effAreasConfigFile")).fullPath()),
14  phoIsoPtScalingCoeff_(conf.getParameter<std::vector<double >>("phoIsoPtScalingCoeff"))
15 
16 {
17 
18  //
19  // Construct the MVA estimators
20  //
21  tag_ = conf.getParameter<std::string>("mvaTag");
22 
23  const std::vector <std::string> weightFileNames
24  = conf.getParameter<std::vector<std::string> >("weightFileNames");
25 
26  if( weightFileNames.size() != nCategories )
27  throw cms::Exception("MVA config failure: ")
28  << "wrong number of weightfiles" << std::endl;
29 
30  gbrForests_.clear();
31  // The method name is just a key to retrieve this method later, it is not
32  // a control parameter for a reader (the full definition of the MVA type and
33  // everything else comes from the xml weight files).
34 
35  // Create a TMVA reader object for each category
36  for(uint i=0; i<nCategories; i++){
37 
38  // Use unique_ptr so that all readers are properly cleaned up
39  // when the vector clear() is called in the destructor
40 
41  edm::FileInPath weightFile( weightFileNames[i] );
42  gbrForests_.push_back( createSingleReader(i, weightFile ) );
43 
44  }
45 
46 }
47 
50 }
51 
53 mvaValue(const edm::Ptr<reco::Candidate>& particle, const edm::Event& iEvent) const {
54 
55  const int iCategory = findCategory( particle );
56 
57  const std::vector<float> vars = fillMVAVariables( particle, iEvent ) ;
58  const float result = gbrForests_.at(iCategory)->GetClassifier(vars.data());
59 
60  // DEBUG
61  const bool debug = false;
62  // The list of variables here must match EXACTLY the list and order in the
63  // packMVAVariables() call for barrel and endcap in this file.
64  if( debug ){
65  printf("Printout of the photon variable inputs for MVA:\n");
66  printf(" varRawE_ %f\n", vars[0] );
67  printf(" varR9_ %f\n", vars[1] );
68  printf(" varSieie_ %f\n", vars[2] );
69  printf(" varSCEtaWidth_ %f\n", vars[3] );
70  printf(" varSCPhiWidth_ %f\n", vars[4] );
71  printf(" varSieip_ %f\n", vars[5] );
72  printf(" varE2x2overE5x5_ %f\n", vars[6] );
73  printf(" varPhoIsoRaw_ %f\n", vars[7] );
74  printf(" varChIsoRaw_ %f\n", vars[8] );
75  printf(" varWorstChRaw_ %f\n", vars[9] );
76  printf(" varSCEta_ %f\n", vars[10] );
77  printf(" varRho_ %f\n", vars[11] );
78  if( isEndcapCategory( iCategory ) ) {
79  printf(" varESEffSigmaRR_ %f\n", vars[12] ); // for endcap MVA only
80  printf(" varESEnOverRawE_ %f\n", vars[13] ); // for endcap MVA only
81  }
82  }
83 
84  return result;
85 }
86 
88 
89  // Try to cast the particle into a reco particle.
90  // This should work for both reco and pat.
91  const edm::Ptr<reco::Photon> phoRecoPtr = ( edm::Ptr<reco::Photon> )particle;
92  if( phoRecoPtr.isNull() )
93  throw cms::Exception("MVA failure: ")
94  << " given particle is expected to be reco::Photon or pat::Photon," << std::endl
95  << " but appears to be neither" << std::endl;
96 
97  float eta = phoRecoPtr->superCluster()->eta();
98 
99  //
100  // Determine the category
101  //
102  int iCategory = UNDEFINED;
103  const float ebeeSplit = 1.479; // division between barrel and endcap
104 
105  if ( std::abs(eta) < ebeeSplit)
106  iCategory = CAT_EB;
107  else
108  iCategory = CAT_EE;
109 
110  return iCategory;
111 }
112 
115 
116  // For this specific MVA the function is trivial, but kept for possible
117  // future evolution to an MVA with more categories in eta
118  bool isEndcap = false;
119  if( category == CAT_EE )
120  isEndcap = true;
121 
122  return isEndcap;
123 }
124 
125 
126 std::unique_ptr<const GBRForest> PhotonMVAEstimatorRunIIFall17::
127 createSingleReader(const int iCategory, const edm::FileInPath &weightFile){
128 
129  //
130  // Create the reader
131  //
132  TMVA::Reader tmpTMVAReader( "!Color:Silent:Error" );
133 
134  //
135  // Configure all variables and spectators. Note: the order and names
136  // must match what is found in the xml weights file!
137  //
138 
139  tmpTMVAReader.AddVariable("SCRawE", &allMVAVars_.varRawE);
140  tmpTMVAReader.AddVariable("r9", &allMVAVars_.varR9);
141  tmpTMVAReader.AddVariable("sigmaIetaIeta", &allMVAVars_.varSieie);
142  tmpTMVAReader.AddVariable("etaWidth", &allMVAVars_.varSCEtaWidth);
143  tmpTMVAReader.AddVariable("phiWidth", &allMVAVars_.varSCPhiWidth);
144  tmpTMVAReader.AddVariable("covIEtaIPhi", &allMVAVars_.varSieip);
145  tmpTMVAReader.AddVariable("s4", &allMVAVars_.varE2x2overE5x5);
146  tmpTMVAReader.AddVariable("phoIso03", &allMVAVars_.varPhoIsoRaw);
147  tmpTMVAReader.AddVariable("chgIsoWrtChosenVtx", &allMVAVars_.varChIsoRaw);
148  tmpTMVAReader.AddVariable("chgIsoWrtWorstVtx", &allMVAVars_.varWorstChRaw);
149  tmpTMVAReader.AddVariable("scEta", &allMVAVars_.varSCEta);
150  tmpTMVAReader.AddVariable("rho", &allMVAVars_.varRho);
151 
152  // Endcap only variables
153  if( isEndcapCategory(iCategory) ){
154  tmpTMVAReader.AddVariable("esEffSigmaRR", &allMVAVars_.varESEffSigmaRR);
155  tmpTMVAReader.AddVariable("esEnergy/SCRawE", &allMVAVars_.varESEnOverRawE);
156  }
157 
158  //
159  // Book the method and set up the weights file
160  //
161  tmpTMVAReader.BookMVA(methodName_ , weightFile.fullPath() );
162 
163  return std::unique_ptr<const GBRForest>( new GBRForest( dynamic_cast<TMVA::MethodBDT*>( tmpTMVAReader.FindMVA(methodName_) ) ) );
164 
165 }
166 
167 // A function that should work on both pat and reco objects
169 
170  //
171  // Declare all value maps corresponding to the above tokens
172  //
178  //
179  edm::Handle<edm::ValueMap<float> > phoChargedIsolationMap;
180  edm::Handle<edm::ValueMap<float> > phoPhotonIsolationMap;
181  edm::Handle<edm::ValueMap<float> > phoWorstChargedIsolationMap;
182 
183  // Rho will be pulled from the event content
185 
186  // Get the isolation maps
187  iEvent.getByLabel(phoChargedIsolationLabel_, phoChargedIsolationMap);
188  iEvent.getByLabel(phoPhotonIsolationLabel_, phoPhotonIsolationMap);
189  iEvent.getByLabel(phoWorstChargedIsolationLabel_, phoWorstChargedIsolationMap);
190 
191  // Get rho
192  iEvent.getByLabel(rhoLabel_,rho);
193 
194  // Make sure everything is retrieved successfully
195  if(! ( phoChargedIsolationMap.isValid()
196  && phoPhotonIsolationMap.isValid()
197  && phoWorstChargedIsolationMap.isValid()
198  && rho.isValid() ) )
199  throw cms::Exception("MVA failure: ")
200  << "Failed to retrieve event content needed for this MVA"
201  << std::endl
202  << "Check python MVA configuration file and make sure all needed"
203  << std::endl
204  << "producers are running upstream" << std::endl;
205 
206  // Try to cast the particle into a reco particle.
207  // This should work for both reco and pat.
208  const edm::Ptr<reco::Photon> phoRecoPtr(particle);
209  if( phoRecoPtr.isNull() )
210  throw cms::Exception("MVA failure: ")
211  << " given particle is expected to be reco::Photon or pat::Photon," << std::endl
212  << " but appears to be neither" << std::endl;
213 
214  // Both pat and reco particles have exactly the same accessors.
215  auto superCluster = phoRecoPtr->superCluster();
216  // Full 5x5 cluster shapes. We could take some of this directly from
217  // the photon object, but some of these are not available.
218  float e2x2 = std::numeric_limits<float>::max();
220  float full5x5_sigmaIetaIeta = std::numeric_limits<float>::max();
221  float full5x5_sigmaIetaIphi = std::numeric_limits<float>::max();
222  float effSigmaRR = std::numeric_limits<float>::max();
223 
224  AllVariables allMVAVars;
225 
226  const auto& full5x5_pss = phoRecoPtr->full5x5_showerShapeVariables();
227  e2x2 = full5x5_pss.e2x2;
228  e5x5 = full5x5_pss.e5x5;
229  full5x5_sigmaIetaIeta = full5x5_pss.sigmaIetaIeta;
230  full5x5_sigmaIetaIphi = full5x5_pss.sigmaIetaIphi;
231  effSigmaRR = full5x5_pss.effSigmaRR;
232 
233  allMVAVars.varRawE = superCluster->rawEnergy();
234  allMVAVars.varR9 = phoRecoPtr->r9() ;
235  allMVAVars.varSieie = full5x5_sigmaIetaIeta;
236  allMVAVars.varSCEtaWidth = superCluster->etaWidth();
237  allMVAVars.varSCPhiWidth = superCluster->phiWidth();
238  allMVAVars.varSieip = full5x5_sigmaIetaIphi;
239  allMVAVars.varE2x2overE5x5 = e2x2/e5x5;
240  allMVAVars.varPhoIsoRaw = (*phoPhotonIsolationMap)[phoRecoPtr];
241  allMVAVars.varChIsoRaw = (*phoChargedIsolationMap)[phoRecoPtr];
242  allMVAVars.varWorstChRaw = (*phoWorstChargedIsolationMap)[phoRecoPtr];
243  allMVAVars.varSCEta = superCluster->eta();
244  allMVAVars.varRho = *rho;
245  allMVAVars.varESEffSigmaRR = effSigmaRR;
246  allMVAVars.varESEnOverRawE = superCluster->preshowerEnergy() / superCluster->rawEnergy();
247 
248  constrainMVAVariables(allMVAVars);
249  //
250  // Important: the order of variables in the "vars" vector has to be EXACTLY
251  // the same as in the .xml file defining the MVA.
252  //
253  std::vector<float> vars;
254  if( isEndcapCategory( findCategory( particle ) ) ) {
255  vars = packMVAVariables(
256  allMVAVars.varRawE,
257  allMVAVars.varR9,
258  allMVAVars.varSieie,
259  allMVAVars.varSCEtaWidth,
260  allMVAVars.varSCPhiWidth,
261  allMVAVars.varSieip,
262  allMVAVars.varE2x2overE5x5,
263  allMVAVars.varPhoIsoRaw,
264  allMVAVars.varChIsoRaw,
265  allMVAVars.varWorstChRaw,
266  allMVAVars.varSCEta,
267  allMVAVars.varRho,
268  allMVAVars.varESEffSigmaRR,
269  allMVAVars.varESEnOverRawE
270  )
271  ;
272  } else {
273  vars = packMVAVariables(
274  allMVAVars.varRawE,
275  allMVAVars.varR9,
276  allMVAVars.varSieie,
277  allMVAVars.varSCEtaWidth,
278  allMVAVars.varSCPhiWidth,
279  allMVAVars.varSieip,
280  allMVAVars.varE2x2overE5x5,
281  allMVAVars.varPhoIsoRaw,
282  allMVAVars.varChIsoRaw,
283  allMVAVars.varWorstChRaw,
284  allMVAVars.varSCEta,
285  allMVAVars.varRho
286  )
287  ;
288  }
289  return vars;
290 }
291 
293 
294  // Check that variables do not have crazy values
295 
296  // This function is currently empty as this specific MVA was not
297  // developed with restricting variables to specific physical ranges.
298 
299 }
300 
305  cc.consumes<double>(rhoLabel_);
306 }
307 
310  "PhotonMVAEstimatorRunIIFall17");
311 
T getParameter(std::string const &) const
std::vector< std::unique_ptr< const GBRForest > > gbrForests_
reco::SuperClusterRef superCluster() const override
Ref to SuperCluster.
std::vector< float > packMVAVariables(const Args...args) const
void constrainMVAVariables(AllVariables &) const
std::vector< float > fillMVAVariables(const edm::Ptr< reco::Candidate > &particle, const edm::Event &iEvent) const override
int iEvent
Definition: GenABIO.cc:230
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:475
bool isEndcap(GeomDetEnumerators::SubDetector m)
float mvaValue(const edm::Ptr< reco::Candidate > &particle, const edm::Event &) const
#define debug
Definition: HDRShower.cc:19
def uint(string)
PhotonMVAEstimatorRunIIFall17(const edm::ParameterSet &conf)
HLT enums.
const ShowerShape & full5x5_showerShapeVariables() const
Definition: Photon.h:198
float r9() const
Definition: Photon.h:228
std::unique_ptr< const GBRForest > createSingleReader(const int iCategory, const edm::FileInPath &weightFile)
std::string fullPath() const
Definition: FileInPath.cc:197
#define DEFINE_EDM_PLUGIN(factory, type, name)
void setConsumes(edm::ConsumesCollector &&) const override
int findCategory(const edm::Ptr< reco::Candidate > &particle) const override