CMS 3D CMS Logo

PhotonMVAEstimatorRun2Spring16NonTrig.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  phoIsoCutoff_(conf.getParameter<double>("phoIsoCutoff"))
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  const std::vector<float> vars = std::move( fillMVAVariables( particle, iEvent ) );
58 
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(" varSCPhi_ %f\n", vars[0] );
68  printf(" varR9_ %f\n", vars[1] );
69  printf(" varSieie_ %f\n", vars[2] );
70  printf(" varSieip_ %f\n", vars[3] );
71  printf(" varE2x2overE5x5_ %f\n", vars[4] );
72  printf(" varSCEta_ %f\n", vars[5] );
73  printf(" varRawE_ %f\n", vars[6] );
74  printf(" varSCEtaWidth_ %f\n", vars[7] );
75  printf(" varSCPhiWidth_ %f\n", vars[8] );
76  printf(" varRho_ %f\n", vars[9] );
77  if( !isEndcapCategory( iCategory ) ) {
78  printf(" varPhoIsoRaw_ %f\n", vars[10] );
79  } else {
80  printf(" varPhoIsoRawCorr_ %f\n", vars[10] ); // for endcap MVA only in 2016
81  }
82  printf(" varChIsoRaw_ %f\n", vars[11] );
83  printf(" varWorstChRaw_ %f\n", vars[12] );
84  if( isEndcapCategory( iCategory ) ) {
85  printf(" varESEnOverRawE_ %f\n", vars[13] ); // for endcap MVA only
86  printf(" varESEffSigmaRR_ %f\n", vars[14] ); // for endcap MVA only
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 = ( edm::Ptr<reco::Photon> )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  float eta = phoRecoPtr->superCluster()->eta();
104 
105  //
106  // Determine the category
107  //
108  int iCategory = UNDEFINED;
109  const float ebeeSplit = 1.479; // division between barrel and endcap
110 
111  if ( std::abs(eta) < ebeeSplit)
112  iCategory = CAT_EB;
113  else
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 // A function that should work on both pat and reco objects
133 
134  //
135  // Declare all value maps corresponding to the above tokens
136  //
142  //
143  edm::Handle<edm::ValueMap<float> > phoChargedIsolationMap;
144  edm::Handle<edm::ValueMap<float> > phoPhotonIsolationMap;
145  edm::Handle<edm::ValueMap<float> > phoWorstChargedIsolationMap;
146 
147  // Rho will be pulled from the event content
149 
150  // Get the isolation maps
151  iEvent.getByLabel(phoChargedIsolationLabel_, phoChargedIsolationMap);
152  iEvent.getByLabel(phoPhotonIsolationLabel_, phoPhotonIsolationMap);
153  iEvent.getByLabel(phoWorstChargedIsolationLabel_, phoWorstChargedIsolationMap);
154 
155  // Get rho
156  iEvent.getByLabel(rhoLabel_,rho);
157 
158  // Make sure everything is retrieved successfully
159  if(! ( phoChargedIsolationMap.isValid()
160  && phoPhotonIsolationMap.isValid()
161  && phoWorstChargedIsolationMap.isValid()
162  && rho.isValid() ) )
163  throw cms::Exception("MVA failure: ")
164  << "Failed to retrieve event content needed for this MVA"
165  << std::endl
166  << "Check python MVA configuration file and make sure all needed"
167  << std::endl
168  << "producers are running upstream" << std::endl;
169 
170  // Try to cast the particle into a reco particle.
171  // This should work for both reco and pat.
172  const edm::Ptr<reco::Photon> phoRecoPtr(particle);
173  if( phoRecoPtr.isNull() )
174  throw cms::Exception("MVA failure: ")
175  << " given particle is expected to be reco::Photon or pat::Photon," << std::endl
176  << " but appears to be neither" << std::endl;
177 
178  // Both pat and reco particles have exactly the same accessors.
179  auto superCluster = phoRecoPtr->superCluster();
180  // Full 5x5 cluster shapes. We could take some of this directly from
181  // the photon object, but some of these are not available.
182  float e2x2 = std::numeric_limits<float>::max();
184  float full5x5_sigmaIetaIeta = std::numeric_limits<float>::max();
185  float full5x5_sigmaIetaIphi = std::numeric_limits<float>::max();
186  float effSigmaRR = std::numeric_limits<float>::max();
187 
188  AllVariables allMVAVars;
189 
190  const auto& full5x5_pss = phoRecoPtr->full5x5_showerShapeVariables();
191  e2x2 = full5x5_pss.e2x2;
192  e5x5 = full5x5_pss.e5x5;
193  full5x5_sigmaIetaIeta = full5x5_pss.sigmaIetaIeta;
194  full5x5_sigmaIetaIphi = full5x5_pss.sigmaIetaIphi;
195  effSigmaRR = full5x5_pss.effSigmaRR;
196 
197  allMVAVars.scPhi = superCluster->phi();
198  allMVAVars.varR9 = phoRecoPtr->r9() ;
199  allMVAVars.varSieie = full5x5_sigmaIetaIeta;
200  allMVAVars.varSieip = full5x5_sigmaIetaIphi;
201  allMVAVars.varE2x2overE5x5 = e2x2/e5x5;
202  allMVAVars.varSCEta = superCluster->eta();
203  allMVAVars.varRawE = superCluster->rawEnergy();
204  allMVAVars.varSCEtaWidth = superCluster->etaWidth();
205  allMVAVars.varSCPhiWidth = superCluster->phiWidth();
206  allMVAVars.varESEnOverRawE = superCluster->preshowerEnergy() / superCluster->rawEnergy();
207  allMVAVars.varESEffSigmaRR = effSigmaRR;
208  allMVAVars.varRho = *rho;
209  allMVAVars.varPhoIsoRaw = (*phoPhotonIsolationMap)[phoRecoPtr];
210  allMVAVars.varChIsoRaw = (*phoChargedIsolationMap)[phoRecoPtr];
211  allMVAVars.varWorstChRaw = (*phoWorstChargedIsolationMap)[phoRecoPtr];
212 
213  //photon iso corrected:
214 
215  double eA = effectiveAreas_.getEffectiveArea( std::abs(superCluster->eta()) );
216  double phoIsoPtScalingCoeffVal = 0;
217  if( !isEndcapCategory( findCategory ( particle ) ) )
218  phoIsoPtScalingCoeffVal = phoIsoPtScalingCoeff_.at(0); // barrel case
219  else
220  phoIsoPtScalingCoeffVal = phoIsoPtScalingCoeff_.at(1); //endcap case
221  double phoIsoCorr = (*phoPhotonIsolationMap)[phoRecoPtr] - eA*(*rho) - phoIsoPtScalingCoeffVal*phoRecoPtr->pt();
222 
223  allMVAVars.varPhoIsoCorr = TMath::Max(phoIsoCorr, phoIsoCutoff_);
224 
225  constrainMVAVariables(allMVAVars);
226  //
227  // Important: the order of variables in the "vars" vector has to be EXACTLY
228  // the same as in the .xml file defining the MVA.
229  //
230  std::vector<float> vars;
231  if( isEndcapCategory( findCategory( particle ) ) ) {
232  vars = std::move( packMVAVariables(
233  allMVAVars.scPhi,
234  allMVAVars.varR9,
235  allMVAVars.varSieie,
236  allMVAVars.varSieip,
237  allMVAVars.varE2x2overE5x5,
238  allMVAVars.varSCEta,
239  allMVAVars.varRawE,
240  allMVAVars.varSCEtaWidth,
241  allMVAVars.varSCPhiWidth,
242  allMVAVars.varRho,
243  allMVAVars.varPhoIsoCorr,
244  allMVAVars.varChIsoRaw,
245  allMVAVars.varWorstChRaw,
246  allMVAVars.varESEffSigmaRR,
247  allMVAVars.varESEnOverRawE
248  )
249  );
250  } else {
251  vars = std::move( packMVAVariables(
252  allMVAVars.scPhi,
253  allMVAVars.varR9,
254  allMVAVars.varSieie,
255  allMVAVars.varSieip,
256  allMVAVars.varE2x2overE5x5,
257  allMVAVars.varSCEta,
258  allMVAVars.varRawE,
259  allMVAVars.varSCEtaWidth,
260  allMVAVars.varSCPhiWidth,
261  allMVAVars.varRho,
262  allMVAVars.varPhoIsoRaw,
263  allMVAVars.varChIsoRaw,
264  allMVAVars.varWorstChRaw
265  )
266  );
267  }
268  return vars;
269 }
270 
272 
273  // Check that variables do not have crazy values
274 
275  // This function is currently empty as this specific MVA was not
276  // developed with restricting variables to specific physical ranges.
277  return;
278 
279 }
280 
285  cc.consumes<double>(rhoLabel_);
286 }
287 
290  "PhotonMVAEstimatorRun2Spring16NonTrig");
291 
T getParameter(std::string const &) const
float mvaValue(const edm::Ptr< reco::Candidate > &particle, const edm::Event &) const override
double pt() const final
transverse momentum
PhotonMVAEstimatorRun2Spring16NonTrig(const edm::ParameterSet &conf)
const float getEffectiveArea(float eta) const
int findCategory(const edm::Ptr< reco::Candidate > &particle) const override
reco::SuperClusterRef superCluster() const override
Ref to SuperCluster.
std::vector< float > packMVAVariables(const Args...args) 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
std::vector< std::unique_ptr< const GBRForest > > gbrForests_
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)
T Max(T a, T b)
Definition: MathUtil.h:44
#define debug
Definition: HDRShower.cc:19
def uint(string)
void setConsumes(edm::ConsumesCollector &&) const override
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)
def move(src, dest)
Definition: eostools.py:510