CMS 3D CMS Logo

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