CMS 3D CMS Logo

ElectronMVAEstimatorRun2Phys14NonTrig.cc
Go to the documentation of this file.
2 
5 
7 
9 
12 
13  _tag = conf.getParameter<std::string>("mvaTag");
14 
15  const std::vector <std::string> weightFileNames
16  = conf.getParameter<std::vector<std::string> >("weightFileNames");
17 
18  if( (int)(weightFileNames.size()) != nCategories )
19  throw cms::Exception("MVA config failure: ")
20  << "wrong number of weightfiles" << std::endl;
21 
22  _gbrForests.clear();
23  _MethodName = "BDTG method";
24  // Create a TMVA reader object for each category
25  for(int i=0; i<nCategories; i++){
26 
27  // Use unique_ptr so that all readers are properly cleaned up
28  // when the vector clear() is called in the destructor
29 
30  edm::FileInPath weightFile( weightFileNames[i] );
31  _gbrForests.push_back( GBRForestTools::createGBRForest(weightFile ) );
32 
33  }
34 
35 }
36 
39 }
40 
42 mvaValue( const edm::Ptr<reco::Candidate>& particle, const edm::Event& evt) const {
43 
44  const int iCategory = findCategory( particle );
45  const std::vector<float> vars = fillMVAVariables( particle, evt );
46  const float result = _gbrForests.at(iCategory)->GetResponse(vars.data()); // The BDT score
47 
48  constexpr bool debug = false;
49  if(debug) {
50  std::cout << " *** Inside the class _MethodName " << _MethodName << std::endl;
51  std::cout << " bin " << iCategory
52  << " fbrem " << vars[11] //_allMVAVars.fbrem
53  << " kfchi2 " << vars[9] //_allMVAVars.kfchi2
54  << " mykfhits " << vars[0] //_allMVAVars.kfhits
55  << " gsfchi2 " << vars[10] //_allMVAVars.gsfchi2
56  << " deta " << vars[15] //_allMVAVars.deta
57  << " dphi " << vars[16] //_allMVAVars.dphi
58  << " detacalo " << vars[17] //_allMVAVars.detacalo
59  << " see " << vars[1] //_allMVAVars.see
60  << " spp " << vars[2] //_allMVAVars.spp
61  << " etawidth " << vars[5] //_allMVAVars.etawidth
62  << " phiwidth " << vars[6] // _allMVAVars.phiwidth
63  << " OneMinusE1x5E5x5 " << vars[3] //_allMVAVars.OneMinusE1x5E5x5
64  << " R9 " << vars[4] //_allMVAVars.R9
65  << " HoE " << vars[7] //_allMVAVars.HoE
66  << " EoP " << vars[12] //_allMVAVars.EoP
67  << " IoEmIoP " << vars[14] //_allMVAVars.IoEmIoP
68  << " eleEoPout " << vars[13] // _allMVAVars.eleEoPout
69  //<< " d0 " << _allMVAVars.d0
70  // << " ip3d " << _allMVAVars.ip3d
71  << " eta " << vars[21] //_allMVAVars.SCeta
72  << " isBarrel " << vars[19] //_allMVAVars.isBarrel
73  << " isEndcap " << vars[20] //_allMVAVars.isEndcap
74  << " pt " << vars[18] //_allMVAVars.pt
75  << std::endl;
76  std::cout << " ### MVA " << result << std::endl;
77  }
78 
79  return result;
80 }
81 
83 
84  // Try to cast the particle into a reco particle.
85  // This should work for both reco and pat.
86  const edm::Ptr<reco::GsfElectron> eleRecoPtr = ( edm::Ptr<reco::GsfElectron> )particle;
87  if( eleRecoPtr.get() == nullptr )
88  throw cms::Exception("MVA failure: ")
89  << " given particle is expected to be reco::GsfElectron or pat::Electron," << std::endl
90  << " but appears to be neither" << std::endl;
91 
92  const float pt = eleRecoPtr->pt();
93  const float eta = eleRecoPtr->superCluster()->eta();
94 
95  //
96  // Determine the category
97  //
98  int iCategory = UNDEFINED;
99  constexpr float ptSplit = 10; // we have above and below 10 GeV categories
100  constexpr float ebSplit = 0.800;// barrel is split into two regions
101  constexpr float ebeeSplit = 1.479; // division between barrel and endcap
102 
103  if (pt < ptSplit && std::abs(eta) < ebSplit)
104  iCategory = CAT_EB1_PT5to10;
105 
106  if (pt < ptSplit && std::abs(eta) >= ebSplit && std::abs(eta) < ebeeSplit)
107  iCategory = CAT_EB2_PT5to10;
108 
109  if (pt < ptSplit && std::abs(eta) >= ebeeSplit)
110  iCategory = CAT_EE_PT5to10;
111 
112  if (pt >= ptSplit && std::abs(eta) < ebSplit)
113  iCategory = CAT_EB1_PT10plus;
114 
115  if (pt >= ptSplit && std::abs(eta) >= ebSplit && std::abs(eta) < ebeeSplit)
116  iCategory = CAT_EB2_PT10plus;
117 
118  if (pt >= ptSplit && std::abs(eta) >= ebeeSplit)
119  iCategory = CAT_EE_PT10plus;
120 
121  return iCategory;
122 }
123 
126 
127  bool isEndcap = false;
128  if( category == CAT_EE_PT5to10 || category == CAT_EE_PT10plus )
129  isEndcap = true;
130 
131  return isEndcap;
132 }
133 
134 // A function that should work on both pat and reco objects
135 std::vector<float>
137  const edm::Event& ) const {
138 
139  // Try to cast the particle into a reco particle.
140  // This should work for both reco and pat.
141  const edm::Ptr<reco::GsfElectron> eleRecoPtr = ( edm::Ptr<reco::GsfElectron> )particle;
142  if( eleRecoPtr.get() == nullptr )
143  throw cms::Exception("MVA failure: ")
144  << " given particle is expected to be reco::GsfElectron or pat::Electron," << std::endl
145  << " but appears to be neither" << std::endl;
146 
147  // the instance of the variables that we will manipulate
148  AllVariables allMVAVars;
149 
150  // Both pat and reco particles have exactly the same accessors, so we use a reco ptr
151  // throughout the code, with a single exception as of this writing, handled separately below.
152  auto superCluster = eleRecoPtr->superCluster();
153 
154  // To get to CTF track information in pat::Electron, we have to have the pointer
155  // to pat::Electron, it is not accessible from the pointer to reco::GsfElectron.
156  // This behavior is reported and is expected to change in the future (post-7.4.5 some time).
157  bool validKF= false;
158  reco::TrackRef myTrackRef = eleRecoPtr->closestCtfTrackRef();
159  const edm::Ptr<pat::Electron> elePatPtr(eleRecoPtr);
160  // Check if this is really a pat::Electron, and if yes, get the track ref from this new
161  // pointer instead
162  if( elePatPtr.get() != nullptr )
163  myTrackRef = elePatPtr->closestCtfTrackRef();
164  validKF = (myTrackRef.isAvailable() && (myTrackRef.isNonnull()) );
165 
166  allMVAVars.kfhits = (validKF) ? myTrackRef->hitPattern().trackerLayersWithMeasurement() : -1. ;
167  // Pure ECAL -> shower shapes
168  allMVAVars.see = eleRecoPtr->full5x5_sigmaIetaIeta();
169  allMVAVars.spp = eleRecoPtr->full5x5_sigmaIphiIphi();
170  allMVAVars.OneMinusE1x5E5x5 = 1. - eleRecoPtr->full5x5_e1x5() / eleRecoPtr->full5x5_e5x5();
171  allMVAVars.R9 = eleRecoPtr->full5x5_r9();
172  allMVAVars.etawidth = superCluster->etaWidth();
173  allMVAVars.phiwidth = superCluster->phiWidth();
174  allMVAVars.HoE = eleRecoPtr->hadronicOverEm();
175  // Endcap only variables
176  allMVAVars.PreShowerOverRaw = superCluster->preshowerEnergy() / superCluster->rawEnergy();
177  //Pure tracking variables
178  allMVAVars.kfchi2 = (validKF) ? myTrackRef->normalizedChi2() : 0;
179  allMVAVars.gsfchi2 = eleRecoPtr->gsfTrack()->normalizedChi2();
180  // Energy matching
181  allMVAVars.fbrem = eleRecoPtr->fbrem();
182  allMVAVars.EoP = eleRecoPtr->eSuperClusterOverP();
183  allMVAVars.eleEoPout = eleRecoPtr->eEleClusterOverPout();
184  allMVAVars.IoEmIoP = (1.0/eleRecoPtr->ecalEnergy()) - (1.0 / eleRecoPtr->p());
185  // Geometrical matchings
186  allMVAVars.deta = eleRecoPtr->deltaEtaSuperClusterTrackAtVtx();
187  allMVAVars.dphi = eleRecoPtr->deltaPhiSuperClusterTrackAtVtx();
188  allMVAVars.detacalo = eleRecoPtr->deltaEtaSeedClusterTrackAtCalo();
189  // Spectator variables
190  allMVAVars.pt = eleRecoPtr->pt();
191  const float scEta = superCluster->eta();
192  constexpr float ebeeSplit = 1.479;
193  allMVAVars.isBarrel = ( std::abs(scEta) < ebeeSplit );
194  allMVAVars.isEndcap = ( std::abs(scEta) >= ebeeSplit );
195  allMVAVars.SCeta = scEta;
196 
197  constrainMVAVariables(allMVAVars);
198 
199  std::vector<float> vars;
200 
201  if( isEndcapCategory( findCategory(particle) ) ) {
202  vars = packMVAVariables( allMVAVars.kfhits,
203  allMVAVars.see,
204  allMVAVars.spp,
205  allMVAVars.OneMinusE1x5E5x5,
206  allMVAVars.R9,
207  allMVAVars.etawidth,
208  allMVAVars.phiwidth,
209  allMVAVars.HoE,
210  allMVAVars.PreShowerOverRaw,
211  allMVAVars.kfchi2,
212  allMVAVars.gsfchi2,
213  allMVAVars.fbrem,
214  allMVAVars.EoP,
215  allMVAVars.eleEoPout,
216  allMVAVars.IoEmIoP,
217  allMVAVars.deta,
218  allMVAVars.dphi,
219  allMVAVars.detacalo,
220  allMVAVars.pt,
221  allMVAVars.isBarrel,
222  allMVAVars.isEndcap,
223  allMVAVars.SCeta );
224  } else {
225  vars = packMVAVariables( allMVAVars.kfhits,
226  allMVAVars.see,
227  allMVAVars.spp,
228  allMVAVars.OneMinusE1x5E5x5,
229  allMVAVars.R9,
230  allMVAVars.etawidth,
231  allMVAVars.phiwidth,
232  allMVAVars.HoE,
233  allMVAVars.kfchi2,
234  allMVAVars.gsfchi2,
235  allMVAVars.fbrem,
236  allMVAVars.EoP,
237  allMVAVars.eleEoPout,
238  allMVAVars.IoEmIoP,
239  allMVAVars.deta,
240  allMVAVars.dphi,
241  allMVAVars.detacalo,
242  allMVAVars.pt,
243  allMVAVars.isBarrel,
244  allMVAVars.isEndcap,
245  allMVAVars.SCeta );
246  }
247 
248  return vars;
249 }
250 
252 
253  // Check that variables do not have crazy values
254 
255  if(vars.fbrem < -1.)
256  vars.fbrem = -1.;
257 
258  vars.deta = std::abs(vars.deta);
259  if(vars.deta > 0.06)
260  vars.deta = 0.06;
261 
262  vars.dphi = std::abs(vars.dphi);
263  if(vars.dphi > 0.6)
264  vars.dphi = 0.6;
265 
266  if(vars.EoP > 20.)
267  vars.EoP = 20.;
268 
269  if(vars.eleEoPout > 20.)
270  vars.eleEoPout = 20.;
271 
272  vars.detacalo = std::abs(vars.detacalo);
273  if(vars.detacalo > 0.2)
274  vars.detacalo = 0.2;
275 
276  if(vars.OneMinusE1x5E5x5 < -1.)
277  vars.OneMinusE1x5E5x5 = -1;
278 
279  if(vars.OneMinusE1x5E5x5 > 2.)
280  vars.OneMinusE1x5E5x5 = 2.;
281 
282  if(vars.R9 > 5)
283  vars.R9 = 5;
284 
285  if(vars.gsfchi2 > 200.)
286  vars.gsfchi2 = 200;
287 
288  if(vars.kfchi2 > 10.)
289  vars.kfchi2 = 10.;
290 }
291 
294  "ElectronMVAEstimatorRun2Phys14NonTrig");
bool isAvailable() const
Definition: Ref.h:577
T getParameter(std::string const &) const
GsfTrackRef gsfTrack() const override
reference to a GsfTrack
Definition: GsfElectron.h:185
virtual TrackRef closestCtfTrackRef() const
Definition: GsfElectron.h:201
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:253
float eSuperClusterOverP() const
Definition: GsfElectron.h:245
float full5x5_e5x5() const
Definition: GsfElectron.h:459
float full5x5_e1x5() const
Definition: GsfElectron.h:457
T const * get() const
Returns C++ pointer to the item.
Definition: Ptr.h:159
float full5x5_sigmaIphiIphi() const
Definition: GsfElectron.h:456
double pt() const final
transverse momentum
float fbrem() const
Definition: GsfElectron.h:750
#define nullptr
#define constexpr
float full5x5_sigmaIetaIeta() const
Definition: GsfElectron.h:455
std::vector< float > packMVAVariables(const Args...args) const
std::vector< std::unique_ptr< const GBRForest > > _gbrForests
float deltaEtaSuperClusterTrackAtVtx() const
Definition: GsfElectron.h:249
float hadronicOverEm() const
Definition: GsfElectron.h:487
std::vector< float > fillMVAVariables(const edm::Ptr< reco::Candidate > &particle, const edm::Event &) const override
static std::unique_ptr< const GBRForest > createGBRForest(const std::string &weightFile)
float deltaPhiSuperClusterTrackAtVtx() const
Definition: GsfElectron.h:252
ElectronMVAEstimatorRun2Phys14NonTrig(const edm::ParameterSet &conf)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
float eEleClusterOverPout() const
Definition: GsfElectron.h:248
bool isEndcap(GeomDetEnumerators::SubDetector m)
float mvaValue(const edm::Ptr< reco::Candidate > &particle, const edm::Event &evt) const override
double p() const final
magnitude of momentum vector
#define debug
Definition: HDRShower.cc:19
reco::TrackRef closestCtfTrackRef() const override
override the reco::GsfElectron::closestCtfTrackRef method, to access the internal storage of the trac...
float ecalEnergy() const
Definition: GsfElectron.h:837
float full5x5_r9() const
Definition: GsfElectron.h:460
float deltaEtaSeedClusterTrackAtCalo() const
Definition: GsfElectron.h:250
SuperClusterRef superCluster() const override
reference to a SuperCluster
Definition: GsfElectron.h:184
#define DEFINE_EDM_PLUGIN(factory, type, name)
int findCategory(const edm::Ptr< reco::Candidate > &particle) const override