CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
EnergyScaleAnalyzer.cc
Go to the documentation of this file.
1 // -*- C++ -*-
2 //
3 // Package: EnergyScaleAnalyzer
4 // Class: EnergyScaleAnalyzer
5 //
13 // Original Author: Keti Kaadze
14 // Created: Thu Jun 21 08:59:42 CDT 2007
15 //
16 
17 //#include "RecoEcal/EnergyScaleAnalyzer/interface/EnergyScaleAnalyzer.h"
20 
21 //Framework
32 
33 //Geometry
40 
41 #include "TFile.h"
42 //Reconstruction classes
51 
55 
63 
64 #include <iostream>
65 #include <fstream>
66 #include <iomanip>
67 #include <ios>
68 #include <map>
69 #include "TString.h"
71 
72 //========================================================================
74 //========================================================================
75 {
76 
77  hepMCLabel_ = consumes<edm::HepMCProduct>(ps.getParameter<std::string>("hepMCLabel"));
78  hybridSuperClusters_token = consumes<reco::SuperClusterCollection>(ps.getUntrackedParameter<edm::InputTag>("hybridSuperClusters",edm::InputTag("hybridSuperClusters")));
79  dynamicHybridSuperClusters_token = consumes<reco::SuperClusterCollection>(ps.getUntrackedParameter<edm::InputTag>("dynamicHybridSuperClusters",edm::InputTag("dynamicHybridSuperClusters")));
80  correctedHybridSuperClusters_token = consumes<reco::SuperClusterCollection>(ps.getUntrackedParameter<edm::InputTag>("correctedHybridSuperClusters",edm::InputTag("correctedHybridSuperClusters")));
81  correctedDynamicHybridSuperClusters_token = consumes<reco::SuperClusterCollection>(ps.getUntrackedParameter<edm::InputTag>("correctedDynamicHybridSuperClusters",edm::InputTag("correctedDynamicHybridSuperClusters")));
82  correctedFixedMatrixSuperClustersWithPreshower_token = consumes<reco::SuperClusterCollection>(ps.getUntrackedParameter<edm::InputTag>("correctedFixedMatrixSuperClustersWithPreshower",edm::InputTag("correctedFixedMatrixSuperClustersWithPreshower")));
83  fixedMatrixSuperClustersWithPreshower_token = consumes<reco::SuperClusterCollection>(ps.getUntrackedParameter<edm::InputTag>("fixedMatrixSuperClustersWithPreshower",edm::InputTag("fixedMatrixSuperClustersWithPreshower")));
84 
85  outputFile_ = ps.getParameter<std::string>("outputFile");
86  rootFile_ = TFile::Open(outputFile_.c_str(),"RECREATE"); // open output file to store histograms
87 
88  evtN = 0;
89 }
90 
91 
92 //========================================================================
94 //========================================================================
95 {
96  delete rootFile_;
97 }
98 
99 //========================================================================
100 void
102 //========================================================================
103 
104  mytree_ = new TTree("energyScale","");
105  TString treeVariables = "mc_npar/I:parID:mc_sep/F:mc_e:mc_et:mc_phi:mc_eta:mc_theta:"; // MC information
106  treeVariables += "em_dR/F:"; // MC <-> EM matching information
107  treeVariables += "em_isInCrack/I:em_scType:em_e/F:em_et:em_phi:em_eta:em_theta:em_nCell/I:em_nBC:"; // EM SC info
108  treeVariables += "em_pet/F:em_pe:em_peta:em_ptheta:" ; // EM SC physics (eta corrected information)
109 
110  treeVariables += "emCorr_e/F:emCorr_et:emCorr_eta:emCorr_phi:emCorr_theta:";// CMSSW standard corrections
111  treeVariables += "emCorr_pet/F:emCorr_peta:emCorr_ptheta:" ;// CMSSW standard physics
112 
113  treeVariables += "em_pw/F:em_ew:em_br" ; // EM widths pw -- phiWidth, ew -- etaWidth, ratios of pw/ew
114 
115  mytree_->Branch("energyScale",&(tree_.mc_npar),treeVariables);
116 
117 }
118 
119 //========================================================================
120 void
122  using namespace edm; // needed for all fwk related classes
123  using namespace std;
124 
125  // std::cout << "Proceccing event # " << ++evtN << std::endl;
126 
127  //Get containers for MC truth, SC etc. ===================================================
128  // =======================================================================================
129  // =======================================================================================
130  Handle<HepMCProduct> hepMC;
131  evt.getByToken( hepMCLabel_, hepMC ) ;
132 
133  Labels l;
135 
136  const HepMC::GenEvent* genEvent = hepMC->GetEvent();
137  if ( !(hepMC.isValid())) {
138  LogInfo("EnergyScaleAnalyzer") << "Could not get MC Product!";
139  return;
140  }
141 
142 
143  //=======================For Vertex correction
144  std::vector< Handle< HepMCProduct > > evtHandles ;
145  evt.getManyByType( evtHandles ) ;
146 
147  for ( unsigned int i=0; i<evtHandles.size(); ++i) {
148  if ( evtHandles[i].isValid() ) {
149  const HepMC::GenEvent* evt = evtHandles[i]->GetEvent() ;
150 
151  // take only 1st vertex for now - it's been tested only of PGuns...
152  //
153  HepMC::GenEvent::vertex_const_iterator vtx = evt->vertices_begin() ;
154  if ( evtHandles[i].provenance()->moduleLabel() == std::string(l.module) ) {
155  //Corrdinates of Vertex w.r.o. the point (0,0,0)
156  xVtx_ = 0.1*(*vtx)->position().x();
157  yVtx_ = 0.1*(*vtx)->position().y();
158  zVtx_ = 0.1*(*vtx)->position().z();
159  }
160  }
161  }
162  //==============================================================================
163  //Get handle to SC collections
164 
166  try {
168  }catch (cms::Exception& ex) {
169  edm::LogError("EnergyScaleAnalyzer") << "Can't get collection with producer hybridSuperClusters.";
170  }
171 
173  try {
175  }catch (cms::Exception& ex) {
176  edm::LogError("EnergyScaleAnalyzer") << "Can't get collection with producer dynamicHybridSuperClusters.";
177  }
178 
179  Handle<reco::SuperClusterCollection> fixedMatrixSuperClustersWithPS;
180  try {
181  evt.getByToken(fixedMatrixSuperClustersWithPreshower_token,fixedMatrixSuperClustersWithPS);
182  }catch (cms::Exception& ex) {
183  edm::LogError("EnergyScaleAnalyzer") << "Can't get collection with producer fixedMatrixSuperClustersWithPreshower.";
184  }
185 
186  //Corrected collections
187  Handle<reco::SuperClusterCollection> correctedHybridSC;
188  try {
189  evt.getByToken(correctedHybridSuperClusters_token,correctedHybridSC);
190  }catch (cms::Exception& ex) {
191  edm::LogError("EnergyScaleAnalyzer") << "Can't get collection with producer correctedHybridSuperClusters.";
192  }
193 
194  Handle<reco::SuperClusterCollection> correctedDynamicHybridSC;
195  try{
196  evt.getByToken(correctedDynamicHybridSuperClusters_token,correctedDynamicHybridSC);
197  }catch (cms::Exception& ex) {
198  edm::LogError("EnergyScaleAnalyzer") << "Can't get collection with producer correctedDynamicHybridSuperClusters.";
199  }
200 
201  Handle<reco::SuperClusterCollection> correctedFixedMatrixSCWithPS;
202  try {
203  evt.getByToken(correctedFixedMatrixSuperClustersWithPreshower_token,correctedFixedMatrixSCWithPS);
204  }catch (cms::Exception& ex ) {
205  edm::LogError("EnergyScaleAnalyzer") << "Can't get collection with producer correctedFixedMatrixSuperClustersWithPreshower.";
206  }
207 
209  const reco::SuperClusterCollection* hSC = hybridSuperClusters.product();
210  const reco::SuperClusterCollection* fmSC = fixedMatrixSuperClustersWithPS.product();
211  const reco::SuperClusterCollection* chSC = correctedHybridSC.product();
212  const reco::SuperClusterCollection* cdSC = correctedDynamicHybridSC.product();
213  const reco::SuperClusterCollection* cfmSC = correctedFixedMatrixSCWithPS.product();
214 
215  // ----------------------- Print outs for debugging
216  /*
217  std::cout << "MC truth" << std::endl;
218  int counterI = 0;
219  for( HepMC::GenEvent::particle_const_iterator p = genEvent->particles_begin();
220  p != genEvent->particles_end(); ++p ) {
221  if ( fabs((*p)->momentum().eta()) < 1.5 ) {
222  std::cout << ++counterI << " " << (*p)->momentum().e() << " "
223  << (*p)->momentum().phi() << " " << (*p)->momentum().eta() << std::endl;
224  }
225  }
226 
227  std::cout << "Standard clusters" << std::endl;
228  counterI = 0;
229  for(reco::SuperClusterCollection::const_iterator em = hSC->begin();
230  em != hSC->end(); ++em )
231  std::cout << ++counterI << " " << em->energy() << " " << em->position().phi() << " " << em->position().eta() << std::endl;
232 
233  std::cout << "Dynamic clusters" << std::endl;
234  counterI = 0;
235  for(reco::SuperClusterCollection::const_iterator em = dSC->begin();
236  em != dSC->end(); ++em )
237  std::cout << ++counterI << " " << em->energy() << " " << em->position().phi() << " " << em->position().eta() << std::endl;
238 
239  std::cout << "FixedMatrix clusters with PS" << std::endl;
240  counterI = 0;
241  for(reco::SuperClusterCollection::const_iterator em = fmSC->begin();
242  em != fmSC->end(); ++em )
243  std::cout << ++counterI << " " << em->energy() << " " << em->position().phi() << " " << em->position().eta() << std::endl;
244  */
245  // -----------------------------
246  //=====================================================================
247  // All containers are loaded, perform the analysis
248  //====================================================================
249 
250  // --------------------------- Store MC particles
251  HepMC::GenEvent::particle_const_iterator p = genEvent->particles_begin();
252 
253  // Search for MC electrons or photons that satisfy the criteria
254  float min_eT = 5;
255  float max_eta = 2.5;
256 
257  std::vector<HepMC::GenParticle* > mcParticles;
258  //int counter = 0;
259  for ( HepMC::GenEvent::particle_const_iterator p = genEvent->particles_begin();
260  p != genEvent->particles_end();
261  ++p ) {
262  //LogInfo("EnergyScaleAnalyzer") << "Particle " << ++counter
263  //<< " PDG ID = " << (*p)->pdg_id() << " pT = " << (*p)->momentum().perp();
264  // require photon or electron
265  if ( (*p)->pdg_id() != 22 && abs((*p)->pdg_id()) != 11 ) continue;
266 
267  // require selection criteria
268  bool satisfySelectionCriteria =
269  (*p)->momentum().perp() > min_eT &&
270  fabs((*p)->momentum().eta()) < max_eta;
271 
272  if ( ! satisfySelectionCriteria ) continue;
273 
274  // EM MC particle is found, save it in the vector
275  mcParticles.push_back(*p);
276  }
277  // separation in dR between 2 first MC particles
278  // should not be used for MC samples with > 2 em objects generated!
279  if ( mcParticles.size() == 2 ) {
280  HepMC::GenParticle* mc1 = mcParticles[0];
281  HepMC::GenParticle* mc2 = mcParticles[1];
282  tree_.mc_sep = kinem::delta_R(mc1->momentum().eta(), mc1->momentum().phi(),
283  mc2->momentum().eta(), mc2->momentum().phi());
284  } else
285  tree_.mc_sep = -100;
286 
287 
288  // now loop over MC particles, find the match with SC and do everything we need
289  // then save info in the tree for every MC particle
290  for(std::vector<HepMC::GenParticle* >::const_iterator p = mcParticles.begin();
291  p != mcParticles.end(); ++p) {
292  HepMC::GenParticle* mc = *p;
293 
294  // Fill MC information
295  tree_.mc_npar = mcParticles.size();
296  tree_.parID = mc->pdg_id();
297  tree_.mc_e = mc->momentum().e();
298  tree_.mc_et = mc->momentum().e()*sin(mc->momentum().theta());
299  tree_.mc_phi = mc->momentum().phi();
300  tree_.mc_eta = mc->momentum().eta();
301  tree_.mc_theta = mc->momentum().theta();
302 
303 
304  //Call function to fill tree
305  // scType coprreponds:
306  // HybridSuperCluster -- 1
307  // DynamicHybridSuperCluster -- 2
308  // FixedMatrixSuperClustersWithPreshower -- 3
309 
310  fillTree( hSC, chSC, mc, tree_, xVtx_, yVtx_, zVtx_, 1);
311  // std::cout << " TYPE " << 1 << " : " << tree_.em_e << " : " << tree_.em_phi << " : " << tree_.em_eta << std::endl;
312 
313  fillTree( dSC, cdSC, mc, tree_, xVtx_, yVtx_, zVtx_, 2);
314  // std::cout << " TYPE " << 2 << " : " << tree_.em_e << " : " << tree_.em_phi << " : " << tree_.em_eta << std::endl;
315 
316  fillTree( fmSC, cfmSC, mc, tree_, xVtx_, yVtx_, zVtx_, 3);
317  // std::cout << " TYPE " << 3 << " : " << tree_.em_e << " : " << tree_.em_phi << " : " << tree_.em_eta << std::endl;
318 
319  // mytree_->Fill();
320  } // loop over particles
321 }
322 
323 
325  HepMC::GenParticle* mc, tree_structure_& tree_, float xV, float yV, float zV, int scType) {
326 
327  // ----------------------------- SuperClusters before energy correction
328  reco::SuperClusterCollection::const_iterator em = scColl->end();
329  float energyMax = -100.0; // dummy energy of the matched SC
330  for(reco::SuperClusterCollection::const_iterator aClus = scColl->begin();
331  aClus != scColl->end(); ++aClus) {
332  // check the matching
333  float dR = kinem::delta_R(mc ->momentum().eta(), mc ->momentum().phi(),
334  aClus->position().eta(), aClus->position().phi());
335  if (dR < 0.4) { // a rather loose matching cut
336  float energy = aClus->energy();
337  if ( energy < energyMax ) continue;
338  energyMax = energy;
339  em = aClus;
340  }
341  }
342 
343  if (em == scColl->end() ) {
344  // std::cout << "No matching SC with type " << scType << " was found for MC particle! " << std::endl;
345  // std::cout << "Going to next type of SC. " << std::endl;
346  return;
347  }
348  // ------------
349 
350  tree_.em_scType = scType;
351 
352  tree_.em_isInCrack = 0;
353  double emAbsEta = fabs(em->position().eta());
354  // copied from RecoEgama/EgammaElectronAlgos/src/EgammaElectronClassification.cc
355  if ( emAbsEta < 0.018 ||
356  (emAbsEta > 0.423 && emAbsEta < 0.461) ||
357  (emAbsEta > 0.770 && emAbsEta < 0.806) ||
358  (emAbsEta > 1.127 && emAbsEta < 1.163) ||
359  (emAbsEta > 1.460 && emAbsEta < 1.558) )
360  tree_.em_isInCrack = 1;
361 
362  tree_.em_dR = kinem::delta_R(mc->momentum().eta(), mc->momentum().phi(),
363  em->position().eta(), em->position().phi());
364  tree_.em_e = em->energy();
365  tree_.em_et = em->energy() * sin(em->position().theta());
366  tree_.em_phi = em->position().phi();
367  tree_.em_eta = em->position().eta();
368  tree_.em_theta = em->position().theta();
369  tree_.em_nCell = em->size();
370  tree_.em_nBC = em->clustersSize();
371 
372  //Get physics e, et etc:
373  //Coordinates of EM object with respect of the point (0,0,0)
374  xClust_zero_ = em->position().x();
375  yClust_zero_ = em->position().y();
376  zClust_zero_ = em->position().z();
377  //Coordinates of EM object w.r.o. the Vertex position
378  xClust_vtx_ = xClust_zero_ - xV;
379  yClust_vtx_ = yClust_zero_ - yV;
380  zClust_vtx_ = zClust_zero_ - zV;
381 
382  energyMax_ = em->energy();
383  thetaMax_ = em->position().theta();
384  etaMax_ = em->position().eta();
385  phiMax_ = em->position().phi();
387  if ( phiMax_ < 0) phiMax_ += 2*3.14159;
388 
390  thetaMaxVtx_ = acos(zClust_vtx_/rClust_vtx_);
391  etaMaxVtx_ = - log(tan(thetaMaxVtx_/2));
394  if ( phiMaxVtx_ < 0) phiMaxVtx_ += 2*3.14159;
395  //=============================
396  //parametres of EM object after vertex correction
397  tree_.em_pet = eTMaxVtx_;
398  tree_.em_pe = tree_.em_pet/sin(thetaMaxVtx_);
399  tree_.em_peta = etaMaxVtx_;
400  tree_.em_ptheta = thetaMaxVtx_;
401 
402 
403  //------------------------------- Get SC after energy correction
404  em = corrSCColl->end();
405  energyMax = -100.0; // dummy energy of the matched SC
406  for(reco::SuperClusterCollection::const_iterator aClus = corrSCColl->begin();
407  aClus != corrSCColl->end(); ++aClus) {
408  // check the matching
409  float dR = kinem::delta_R(mc ->momentum().eta(), mc ->momentum().phi(),
410  aClus->position().eta(), aClus->position().phi());
411  if (dR < 0.4) {
412  float energy = aClus->energy();
413  if ( energy < energyMax ) continue;
414  energyMax = energy;
415  em = aClus;
416  }
417  }
418 
419  if (em == corrSCColl->end() ) {
420  // std::cout << "No matching corrected SC with type " << scType << " was found for MC particle! " << std::endl;
421  // std::cout << "Going to next type of SC. " << std::endl;
422  return;
423  }
424  // ------------
425 
427  tree_.emCorr_e = em->energy();
428  tree_.emCorr_et = em->energy() * sin(em->position().theta());
429  tree_.emCorr_phi = em->position().phi();
430  tree_.emCorr_eta = em->position().eta();
431  tree_.emCorr_theta = em->position().theta();
432 
433  // =========== Eta and Theta wrt Vertex does not change after energy corrections are applied
434  // =========== So, no need to calculate them again
435 
436  tree_.emCorr_peta = tree_.em_peta;
437  tree_.emCorr_ptheta = tree_.em_ptheta;
438  tree_.emCorr_pet = tree_.emCorr_e/cosh(tree_.emCorr_peta);
439 
440  tree_.em_pw = em->phiWidth();
441  tree_.em_ew = em->etaWidth();
442  tree_.em_br = tree_.em_pw/tree_.em_ew;
443 
444  mytree_->Fill();
445 
446 }
447 
448 //==========================================================================
449 void
451  //========================================================================
452  //Fill ROOT tree
453  rootFile_->Write();
454 }
455 
void getManyByType(std::vector< Handle< PROD > > &results) const
Definition: Event.h:454
edm::EDGetTokenT< reco::SuperClusterCollection > dynamicHybridSuperClusters_token
T getParameter(std::string const &) const
T getUntrackedParameter(std::string const &, T const &) const
int i
Definition: DBlmapReader.cc:9
edm::EDGetTokenT< reco::SuperClusterCollection > fixedMatrixSuperClustersWithPreshower_token
virtual void analyze(const edm::Event &, const edm::EventSetup &)
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:464
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
edm::EDGetTokenT< edm::HepMCProduct > hepMCLabel_
edm::EDGetTokenT< reco::SuperClusterCollection > correctedFixedMatrixSuperClustersWithPreshower_token
edm::EDGetTokenT< reco::SuperClusterCollection > hybridSuperClusters_token
void fillTree(const reco::SuperClusterCollection *scColl, const reco::SuperClusterCollection *corrSCColl, HepMC::GenParticle *mc, tree_structure_ &tree_, float xV, float yV, float zV, int scType)
std::vector< SuperCluster > SuperClusterCollection
collection of SuperCluser objectr
T sqrt(T t)
Definition: SSEVec.h:48
Tan< T >::type tan(const T &t)
Definition: Tan.h:22
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
tuple genEvent
Definition: MCTruth.py:33
double delta_R(double eta1, double phi1, double eta2, double phi2)
Definition: AnglesUtil.h:116
edm::EDGetTokenT< reco::SuperClusterCollection > correctedDynamicHybridSuperClusters_token
edm::EDGetTokenT< reco::SuperClusterCollection > correctedHybridSuperClusters_token
EnergyScaleAnalyzer(const edm::ParameterSet &)
void labelsForToken(EDGetToken iToken, Labels &oLabels) const