CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
RegressionHelper.cc
Go to the documentation of this file.
3 
6 
8 #include "TVector2.h"
9 #include "TFile.h"
10 
12  cfg_(config),ecalRegressionInitialized_(false),combinationRegressionInitialized_(false),
13  caloTopologyCacheId_(0), caloGeometryCacheId_(0),regressionCacheId_(0)
14 {;}
15 
17 
20  const edm::Handle<EcalRecHitCollection>& rechitsEB,
21  const edm::Handle<EcalRecHitCollection>& rechitsEE) const {
22  double cor, err;
23  getEcalRegression(*ele.superCluster(), vertices, rechitsEB, rechitsEE, cor, err);
24  ele.setCorrectedEcalEnergy(cor * ele.superCluster()->correctedEnergy());
25  ele.setCorrectedEcalEnergyError( err * ele.superCluster()->correctedEnergy());
26 
27 }
28 
30 
31  // Topology
32  unsigned long long newCaloTopologyCacheId
33  = es.get<CaloTopologyRecord>().cacheIdentifier() ;
34  if (!caloTopologyCacheId_ || ( caloTopologyCacheId_ != newCaloTopologyCacheId ) )
35  {
36  caloTopologyCacheId_ = newCaloTopologyCacheId;
38  es.get<CaloTopologyRecord>().get(caloTopo);
39  caloTopology_ = &(*caloTopo);
40  }
41 
42  // Geometry
43  unsigned long long newCaloGeometryCacheId
44  = es.get<CaloGeometryRecord>().cacheIdentifier() ;
45  if (!caloGeometryCacheId_ || ( caloGeometryCacheId_ != newCaloGeometryCacheId ) )
46  {
47  caloGeometryCacheId_ = newCaloGeometryCacheId;
49  es.get<CaloGeometryRecord>().get(caloGeom);
50  caloGeometry_ = &(*caloGeom);
51  }
52 
53  // Ecal regression
54 
55  // if at least one of the set of weights come from the DB
57  {
58  unsigned long long newRegressionCacheId
59  = es.get<GBRWrapperRcd>().cacheIdentifier() ;
60  if ( !regressionCacheId_ || (newRegressionCacheId != regressionCacheId_ ) ) {
61 
62  const GBRWrapperRcd& gbrRcd = es.get<GBRWrapperRcd>();
63 
64  // ECAL barrel
65  edm::ESHandle<GBRForest> ecalRegBarrelH;
66  gbrRcd.get(cfg_.ecalRegressionWeightLabels[0].c_str(),ecalRegBarrelH);
67  ecalRegBarrel_ = &(*ecalRegBarrelH);
68 
69  // ECAL endcaps
70  edm::ESHandle<GBRForest> ecalRegEndcapH;
71  gbrRcd.get(cfg_.ecalRegressionWeightLabels[1].c_str(),ecalRegEndcapH);
72  ecalRegEndcap_= &(*ecalRegEndcapH);
73 
74  // ECAL barrel error
75  edm::ESHandle<GBRForest> ecalRegErrorBarrelH;
76  gbrRcd.get(cfg_.ecalRegressionWeightLabels[2].c_str(),ecalRegErrorBarrelH);
77  ecalRegErrorBarrel_ = &(*ecalRegErrorBarrelH);
78 
79  // ECAL endcap error
80  edm::ESHandle<GBRForest> ecalRegErrorEndcapH;
81  gbrRcd.get(cfg_.ecalRegressionWeightLabels[3].c_str(),ecalRegErrorEndcapH);
82  ecalRegErrorEndcap_ = &(*ecalRegErrorEndcapH);
83 
85  }
86  }
88  {
89 
90  // Combination
92  {
93  unsigned long long newRegressionCacheId
94  = es.get<GBRWrapperRcd>().cacheIdentifier() ;
95  if ( !regressionCacheId_ || (newRegressionCacheId != regressionCacheId_ ) ) {
96 
97  const GBRWrapperRcd& gbrRcd = es.get<GBRWrapperRcd>();
98 
99  edm::ESHandle<GBRForest> combinationRegH;
100  gbrRcd.get(cfg_.combinationRegressionWeightLabels[0].c_str(),combinationRegH);
101  combinationReg_ = &(*combinationRegH);
102 
104  }
105  }
106  }
107 
108  // read weights from file - for debugging. Even if it is one single files, 4 files should b set in the vector
111  TFile file0 (edm::FileInPath(cfg_.ecalRegressionWeightFiles[0].c_str()).fullPath().c_str());
112  ecalRegBarrel_ = (const GBRForest*)file0.Get(cfg_.ecalRegressionWeightLabels[0].c_str());
113  file0.Close();
114  TFile file1 (edm::FileInPath(cfg_.ecalRegressionWeightFiles[1].c_str()).fullPath().c_str());
116  file1.Close();
117  TFile file2 (edm::FileInPath(cfg_.ecalRegressionWeightFiles[2].c_str()).fullPath().c_str());
118  ecalRegErrorBarrel_ = (const GBRForest*)file2.Get(cfg_.ecalRegressionWeightLabels[2].c_str());
119  file2.Close();
120  TFile file3 (edm::FileInPath(cfg_.ecalRegressionWeightFiles[3].c_str()).fullPath().c_str());
121  ecalRegErrorEndcap_ = (const GBRForest*)file3.Get(cfg_.ecalRegressionWeightLabels[3].c_str());
123  file3.Close();
124  }
125 
128  {
129  TFile file0 (edm::FileInPath(cfg_.combinationRegressionWeightFiles[0].c_str()).fullPath().c_str());
130  combinationReg_ = (const GBRForest*)file0.Get(cfg_.combinationRegressionWeightLabels[0].c_str());
132  file0.Close();
133  }
134 
135 }
136 
138 
140  const edm::Handle<reco::VertexCollection>& vertices,
141  const edm::Handle<EcalRecHitCollection>& rechitsEB,
142  const edm::Handle<EcalRecHitCollection>& rechitsEE,
143  double & energyFactor, double & errorFactor) const {
144 
145  energyFactor = -999.;
146  errorFactor = -999.;
147  std::vector<float> rInputs;
148  rInputs.resize(33);
149 
150  const double rawEnergy = sc.rawEnergy();
151  const double calibEnergy = sc.correctedEnergy();
152  const edm::Ptr<reco::CaloCluster> seed(sc.seed());
153  const size_t nVtx = vertices->size();
154  float maxDR=999., maxDRDPhi=999., maxDRDEta=999., maxDRRawEnergy=0.;
155  float subClusRawE[3], subClusDPhi[3], subClusDEta[3];
156  memset(subClusRawE,0,3*sizeof(float));
157  memset(subClusDPhi,0,3*sizeof(float));
158  memset(subClusDEta,0,3*sizeof(float));
159  size_t iclus=0;
160  for( auto clus = sc.clustersBegin()+1; clus != sc.clustersEnd(); ++clus ) {
161  const float this_deta = (*clus)->eta() - seed->eta();
162  const float this_dphi = TVector2::Phi_mpi_pi((*clus)->phi() - seed->phi());
163  const float this_dr = std::hypot(this_deta,this_dphi);
164  if(this_dr > maxDR || maxDR == 999.0f) {
165  maxDR = this_dr;
166  maxDRDEta = this_deta;
167  maxDRDPhi = this_dphi;
168  maxDRRawEnergy = (*clus)->energy();
169  }
170  if( iclus++ < 3 ) {
171  subClusRawE[iclus] = (*clus)->energy();
172  subClusDEta[iclus] = this_deta;
173  subClusDPhi[iclus] = this_dphi;
174  }
175  }
176  float scPreshowerSum = sc.preshowerEnergy();
177  if ( seed->hitsAndFractions()[0].first.subdetId()==EcalBarrel ) {
178  const float eMax = EcalClusterTools::eMax( *seed, &*rechitsEB );
179  const float e2nd = EcalClusterTools::e2nd( *seed, &*rechitsEB );
180  const float e3x3 = EcalClusterTools::e3x3( *seed,
181  &*rechitsEB,
182  &*caloTopology_ );
183  const float eTop = EcalClusterTools::eTop( *seed,
184  &*rechitsEB,
185  &*caloTopology_ );
186  const float eBottom = EcalClusterTools::eBottom( *seed,
187  &*rechitsEB,
188  &*caloTopology_ );
189  const float eLeft = EcalClusterTools::eLeft( *seed,
190  &*rechitsEB,
191  &*caloTopology_ );
192  const float eRight = EcalClusterTools::eRight( *seed,
193  &*rechitsEB,
194  &*caloTopology_ );
195  const float eLpeR = eLeft + eRight;
196  const float eTpeB = eTop + eBottom;
197  const float eLmeR = eLeft - eRight;
198  const float eTmeB = eTop - eBottom;
199  std::vector<float> vCov =
200  EcalClusterTools::localCovariances( *seed, &*rechitsEB, &*caloTopology_ );
201  const float see = (isnan(vCov[0]) ? 0. : sqrt(vCov[0]));
202  const float spp = (isnan(vCov[2]) ? 0. : sqrt(vCov[2]));
203  float sep = 0.;
204  if (see*spp > 0)
205  sep = vCov[1] / (see * spp);
206  else if (vCov[1] > 0)
207  sep = 1.0;
208  else
209  sep = -1.0;
210  float cryPhi, cryEta, thetatilt, phitilt;
211  int ieta, iphi;
212  ecl_.localCoordsEB(*seed, *caloGeometry_, cryEta, cryPhi,
213  ieta, iphi, thetatilt, phitilt);
214  rInputs[0] = nVtx; //nVtx
215  rInputs[1] = sc.eta(); //scEta
216  rInputs[2] = sc.phi(); //scPhi
217  rInputs[3] = sc.etaWidth(); //scEtaWidth
218  rInputs[4] = sc.phiWidth(); //scPhiWidth
219  rInputs[5] = e3x3/rawEnergy; //scSeedR9
220  rInputs[6] = sc.seed()->energy()/rawEnergy; //scSeedRawEnergy/scRawEnergy
221  rInputs[7] = eMax/rawEnergy; //scSeedEmax/scRawEnergy
222  rInputs[8] = e2nd/rawEnergy; //scSeedE2nd/scRawEnergy
223  rInputs[9] = (eLpeR!=0. ? eLmeR/eLpeR : 0.);//scSeedLeftRightAsym
224  rInputs[10] = (eTpeB!=0.? eTmeB/eTpeB : 0.);//scSeedTopBottomAsym
225  rInputs[11] = see; //scSeedSigmaIetaIeta
226  rInputs[12] = sep; //scSeedSigmaIetaIphi
227  rInputs[13] = spp; //scSeedSigmaIphiIphi
228  rInputs[14] = sc.clustersSize()-1; //N_ECALClusters
229  rInputs[15] = maxDR; //clusterMaxDR
230  rInputs[16] = maxDRDPhi; //clusterMaxDRDPhi
231  rInputs[17] = maxDRDEta; //clusterMaxDRDEta
232  rInputs[18] = maxDRRawEnergy/rawEnergy; //clusMaxDRRawEnergy/scRawEnergy
233  rInputs[19] = subClusRawE[0]/rawEnergy; //clusterRawEnergy[0]/scRawEnergy
234  rInputs[20] = subClusRawE[1]/rawEnergy; //clusterRawEnergy[1]/scRawEnergy
235  rInputs[21] = subClusRawE[2]/rawEnergy; //clusterRawEnergy[2]/scRawEnergy
236  rInputs[22] = subClusDPhi[0]; //clusterDPhiToSeed[0]
237  rInputs[23] = subClusDPhi[1]; //clusterDPhiToSeed[1]
238  rInputs[24] = subClusDPhi[2]; //clusterDPhiToSeed[2]
239  rInputs[25] = subClusDEta[0]; //clusterDEtaToSeed[0]
240  rInputs[26] = subClusDEta[1]; //clusterDEtaToSeed[1]
241  rInputs[27] = subClusDEta[2]; //clusterDEtaToSeed[2]
242  rInputs[28] = cryEta; //scSeedCryEta
243  rInputs[29] = cryPhi; //scSeedCryPhi
244  rInputs[30] = ieta; //scSeedCryIeta
245  rInputs[31] = iphi; //scSeedCryIphi
246  rInputs[32] = calibEnergy; //scCalibratedEnergy
247  energyFactor = ecalRegBarrel_->GetResponse(&rInputs[0]);
248  errorFactor = ecalRegErrorBarrel_->GetResponse(&rInputs[0]);
249  }
250  else if(seed->hitsAndFractions()[0].first.subdetId()==EcalEndcap)
251  {
252  const float eMax = EcalClusterTools::eMax( *seed, &*rechitsEE );
253  const float e2nd = EcalClusterTools::e2nd( *seed, &*rechitsEE );
254  const float e3x3 = EcalClusterTools::e3x3( *seed,
255  &*rechitsEE,
256  &*caloTopology_ );
257  const float eTop = EcalClusterTools::eTop( *seed,
258  &*rechitsEE,
259  &*caloTopology_ );
260  const float eBottom = EcalClusterTools::eBottom( *seed,
261  &*rechitsEE,
262  &*caloTopology_ );
263  const float eLeft = EcalClusterTools::eLeft( *seed,
264  &*rechitsEE,
265  &*caloTopology_ );
266  const float eRight = EcalClusterTools::eRight( *seed,
267  &*rechitsEE,
268  &*caloTopology_ );
269  const float eLpeR = eLeft + eRight;
270  const float eTpeB = eTop + eBottom;
271  const float eLmeR = eLeft - eRight;
272  const float eTmeB = eTop - eBottom;
273  std::vector<float> vCov =
274  EcalClusterTools::localCovariances( *seed, &*rechitsEE, &*caloTopology_ );
275  const float see = (isnan(vCov[0]) ? 0. : sqrt(vCov[0]));
276  const float spp = (isnan(vCov[2]) ? 0. : sqrt(vCov[2]));
277  float sep = 0.;
278  if (see*spp > 0)
279  sep = vCov[1] / (see * spp);
280  else if (vCov[1] > 0)
281  sep = 1.0;
282  else
283  sep = -1.0;
284  rInputs[0] = nVtx; //nVtx
285  rInputs[1] = sc.eta(); //scEta
286  rInputs[2] = sc.phi(); //scPhi
287  rInputs[3] = sc.etaWidth(); //scEtaWidth
288  rInputs[4] = sc.phiWidth(); //scPhiWidth
289  rInputs[5] = e3x3/rawEnergy; //scSeedR9
290  rInputs[6] = sc.seed()->energy()/rawEnergy; //scSeedRawEnergy/scRawEnergy
291  rInputs[7] = eMax/rawEnergy; //scSeedEmax/scRawEnergy
292  rInputs[8] = e2nd/rawEnergy; //scSeedE2nd/scRawEnergy
293  rInputs[9] = (eLpeR!=0. ? eLmeR/eLpeR : 0.);//scSeedLeftRightAsym
294  rInputs[10] = (eTpeB!=0.? eTmeB/eTpeB : 0.);//scSeedTopBottomAsym
295  rInputs[11] = see; //scSeedSigmaIetaIeta
296  rInputs[12] = sep; //scSeedSigmaIetaIphi
297  rInputs[13] = spp; //scSeedSigmaIphiIphi
298  rInputs[14] = sc.clustersSize()-1; //N_ECALClusters
299  rInputs[15] = maxDR; //clusterMaxDR
300  rInputs[16] = maxDRDPhi; //clusterMaxDRDPhi
301  rInputs[17] = maxDRDEta; //clusterMaxDRDEta
302  rInputs[18] = maxDRRawEnergy/rawEnergy; //clusMaxDRRawEnergy/scRawEnergy
303  rInputs[19] = subClusRawE[0]/rawEnergy; //clusterRawEnergy[0]/scRawEnergy
304  rInputs[20] = subClusRawE[1]/rawEnergy; //clusterRawEnergy[1]/scRawEnergy
305  rInputs[21] = subClusRawE[2]/rawEnergy; //clusterRawEnergy[2]/scRawEnergy
306  rInputs[22] = subClusDPhi[0]; //clusterDPhiToSeed[0]
307  rInputs[23] = subClusDPhi[1]; //clusterDPhiToSeed[1]
308  rInputs[24] = subClusDPhi[2]; //clusterDPhiToSeed[2]
309  rInputs[25] = subClusDEta[0]; //clusterDEtaToSeed[0]
310  rInputs[26] = subClusDEta[1]; //clusterDEtaToSeed[1]
311  rInputs[27] = subClusDEta[2]; //clusterDEtaToSeed[2]
312  rInputs[28] = scPreshowerSum/rawEnergy; //scPreshowerEnergy/scRawEnergy
313  rInputs[29] = calibEnergy; //scCalibratedEnergy
314  energyFactor = ecalRegEndcap_->GetResponse(&rInputs[0]);
315  errorFactor = ecalRegErrorEndcap_->GetResponse(&rInputs[0]);
316  }
317  else
318  {
319  // std::cout << " SubdetID " << " " << seed->seed().rawId() << " " << seed->seed().subdetId() << std::endl;
320  throw cms::Exception("RegressionHelper::calculateRegressedEnergy")
321  << "Supercluster seed is either EB nor EE!" << std::endl;
322  }
323 }
324 
326 {
327  float energy = ele.correctedEcalEnergy();
329  float momentum = ele.trackMomentumAtVtx().R();
330  float momentumError = ele.trackMomentumError();
331  int elClass = -.1;
332 
333  switch (ele.classification()) {
335  elClass = 0;
336  break;
338  elClass = 1;
339  break;
341  elClass = 2;
342  break;
344  elClass = 3;
345  break;
347  elClass = 4;
348  break;
349  default:
350  elClass = -1;
351 
352 
353  bool isEcalDriven = ele.ecalDriven();
354  bool isTrackerDriven = ele.trackerDrivenSeed();
355  bool isEB = ele.isEB();
356 
357  // compute relative errors and ratio of errors
358  float energyRelError = energyError / energy;
359  float momentumRelError = momentumError / momentum;
360  float errorRatio = energyRelError / momentumRelError;
361 
362  // calculate E/p and corresponding error
363  float eOverP = energy / momentum;
364  float eOverPerror = eOverP*std::hypot(energyRelError,momentumRelError);
365 
366  // fill input variables
367  std::vector<float> regressionInputs ;
368  regressionInputs.resize(11,0.);
369 
370  regressionInputs[0] = energy;
371  regressionInputs[1] = energyRelError;
372  regressionInputs[2] = momentum;
373  regressionInputs[3] = momentumRelError;
374  regressionInputs[4] = errorRatio;
375  regressionInputs[5] = eOverP;
376  regressionInputs[6] = eOverPerror;
377  regressionInputs[7] = static_cast<float>(isEcalDriven);
378  regressionInputs[8] = static_cast<float>(isTrackerDriven);
379  regressionInputs[9] = static_cast<float>(elClass);
380  regressionInputs[10] = static_cast<float>(isEB);
381 
382  // retrieve combination weight
383  float weight = 0.;
384  if(eOverP>0.025
385  &&fabs(momentum-energy)<15.*sqrt(momentumError*momentumError + energyError*energyError)
386  ) // protection against crazy track measurement
387  {
388  weight = combinationReg_->GetResponse(regressionInputs.data());
389  if(weight>1.) weight = 1.;
390  else if(weight<0.) weight = 0.;
391  }
392 
393  float combinedMomentum = weight*momentum + (1.-weight)*energy;
394  float combinedMomentumError = sqrt(weight*weight*momentumError*momentumError + (1.-weight)*(1.-weight)*energyError*energyError);
395 
396  // FIXME : pure tracker electrons have track momentum error of 999.
397  // If the combination try to combine such electrons then the original combined momentum is kept
398  if(momentumError!=999. || weight==0.)
399  {
400  math::XYZTLorentzVector oldMomentum = ele.p4() ;
401  math::XYZTLorentzVector newMomentum(oldMomentum.x()*combinedMomentum/oldMomentum.t(),
402  oldMomentum.y()*combinedMomentum/oldMomentum.t(),
403  oldMomentum.z()*combinedMomentum/oldMomentum.t(),
404  combinedMomentum);
405 
406  ele.setP4(reco::GsfElectron::P4_COMBINATION,newMomentum,combinedMomentumError,true);
407  }
408  }
409 }
double GetResponse(const float *vector) const
Definition: GBRForest.h:51
std::vector< std::string > ecalRegressionWeightFiles
unsigned long long caloGeometryCacheId_
void applyCombinationRegression(reco::GsfElectron &ele) const
void setP4(P4Kind kind, const LorentzVector &p4, float p4Error, bool setCandidate)
Definition: GsfElectron.cc:178
std::vector< std::string > combinationRegressionWeightLabels
unsigned long long regressionCacheId_
float trackMomentumError() const
Definition: GsfElectron.h:729
const GBRForest * ecalRegEndcap_
double correctedEnergy() const
Definition: CaloCluster.h:121
const LorentzVector & p4(P4Kind kind) const
Definition: GsfElectron.cc:204
std::vector< std::string > ecalRegressionWeightLabels
double phiWidth() const
obtain phi and eta width of the Super Cluster
Definition: SuperCluster.h:55
unsigned long long caloTopologyCacheId_
math::XYZVectorF trackMomentumAtVtx() const
Definition: GsfElectron.h:273
double Phi_mpi_pi(double x)
Definition: JetUtil.h:24
const Configuration cfg_
bool isEB() const
Definition: GsfElectron.h:334
double eta() const
pseudorapidity of cluster centroid
Definition: CaloCluster.h:161
const CaloTopology * caloTopology_
XYZTLorentzVectorD XYZTLorentzVector
Lorentz vector with cylindrical internal representation using pseudorapidity.
Definition: LorentzVector.h:29
const GBRForest * ecalRegBarrel_
const GBRForest * ecalRegErrorBarrel_
void setCorrectedEcalEnergyError(float newEnergyError)
Definition: GsfElectron.cc:158
double etaWidth() const
Definition: SuperCluster.h:56
bool isnan(float x)
Definition: math.h:13
T sqrt(T t)
Definition: SSEVec.h:48
virtual SuperClusterRef superCluster() const
reference to a SuperCluster
Definition: GsfElectron.h:169
void get(HolderT &iHolder) const
double f[11][100]
std::vector< std::string > combinationRegressionWeightFiles
float correctedEcalEnergy() const
Definition: GsfElectron.h:727
double rawEnergy() const
raw uncorrected energy (sum of energies of component BasicClusters)
Definition: SuperCluster.h:47
void getEcalRegression(const reco::SuperCluster &sc, const edm::Handle< reco::VertexCollection > &vertices, const edm::Handle< EcalRecHitCollection > &rechitsEB, const edm::Handle< EcalRecHitCollection > &rechitsEE, double &energyFactor, double &errorFactor) const
size_t clustersSize() const
number of BasicCluster constituents
Definition: SuperCluster.h:87
Classification classification() const
Definition: GsfElectron.h:649
const T & get() const
Definition: EventSetup.h:55
void readEvent(const edm::Event &)
void localCoordsEB(const reco::CaloCluster &bclus, const edm::EventSetup &es, float &etacry, float &phicry, int &ieta, int &iphi, float &thetatilt, float &phitilt) const
const GBRForest * ecalRegErrorEndcap_
float correctedEcalEnergyError() const
Definition: GsfElectron.h:728
void setCorrectedEcalEnergy(float newEnergy)
Definition: GsfElectron.cc:161
void applyEcalRegression(reco::GsfElectron &electron, const edm::Handle< reco::VertexCollection > &vertices, const edm::Handle< EcalRecHitCollection > &rechitsEB, const edm::Handle< EcalRecHitCollection > &rechitsEE) const
CaloCluster_iterator clustersBegin() const
fist iterator over BasicCluster constituents
Definition: SuperCluster.h:75
bool trackerDrivenSeed() const
Definition: GsfElectron.h:174
const CaloClusterPtr & seed() const
seed BasicCluster
Definition: SuperCluster.h:66
double preshowerEnergy() const
energy deposited in preshower
Definition: SuperCluster.h:50
volatile std::atomic< bool > shutdown_flag false
RegressionHelper(const Configuration &)
int weight
Definition: histoStyle.py:50
double phi() const
azimuthal angle of cluster centroid
Definition: CaloCluster.h:164
bool ecalDriven() const
Definition: GsfElectron.cc:147
bool combinationRegressionInitialized_
EcalClusterLocal ecl_
void checkSetup(const edm::EventSetup &)
float energyError(float E, float *par)
const CaloGeometry * caloGeometry_
const GBRForest * combinationReg_
CaloCluster_iterator clustersEnd() const
last iterator over BasicCluster constituents
Definition: SuperCluster.h:78