CMS 3D CMS Logo

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