CMS 3D CMS Logo

HGCalHitCalibration.cc
Go to the documentation of this file.
1 // user include files
2 
6 
10 
12 
14 
17 
24 
29 
35 
37 
38 #include <map>
39 #include <array>
40 #include <string>
41 #include <numeric>
42 
44  public:
45  explicit HGCalHitCalibration(const edm::ParameterSet&);
46  ~HGCalHitCalibration() override;
47 
48  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
49 
50  private:
52  edm::EventSetup const&) override;
53  void analyze(const edm::Event&, const edm::EventSetup&) override;
54 
55  void fillWithRecHits(std::map<DetId, const HGCRecHit*>&, DetId, unsigned int,
56  float, int&, float&);
57 
65 
66  int algo_;
68  int debug_;
70 
71  std::map<int, MonitorElement*> h_EoP_CPene_calib_fraction_;
72  std::map<int, MonitorElement*> hgcal_EoP_CPene_calib_fraction_;
73  std::map<int, MonitorElement*> hgcal_ele_EoP_CPene_calib_fraction_;
74  std::map<int, MonitorElement*> hgcal_photon_EoP_CPene_calib_fraction_;
76 
77  static constexpr int layers_ = 60;
78  std::array<float, layers_> Energy_layer_calib_;
79  std::array<float, layers_> Energy_layer_calib_fraction_;
80 };
81 
83  : rawRecHits_(iConfig.getParameter<bool>("rawRecHits")),
84  debug_(iConfig.getParameter<int>("debug")) {
85  auto detector = iConfig.getParameter<std::string>("detector");
86  auto recHitsEE = iConfig.getParameter<edm::InputTag>("recHitsEE");
87  auto recHitsFH = iConfig.getParameter<edm::InputTag>("recHitsFH");
88  auto recHitsBH = iConfig.getParameter<edm::InputTag>("recHitsBH");
89  auto caloParticles = iConfig.getParameter<edm::InputTag>("caloParticles");
90  auto hgcalMultiClusters = iConfig.getParameter<edm::InputTag>("hgcalMultiClusters");
91  auto electrons = iConfig.getParameter<edm::InputTag>("electrons");
92  auto photons = iConfig.getParameter<edm::InputTag>("photons");
93  if (detector == "all") {
94  recHitsEE_ = consumes<HGCRecHitCollection>(recHitsEE);
95  recHitsFH_ = consumes<HGCRecHitCollection>(recHitsFH);
96  recHitsBH_ = consumes<HGCRecHitCollection>(recHitsBH);
97  algo_ = 1;
98  } else if (detector == "EM") {
99  recHitsEE_ = consumes<HGCRecHitCollection>(recHitsEE);
100  algo_ = 2;
101  } else if (detector == "HAD") {
102  recHitsFH_ = consumes<HGCRecHitCollection>(recHitsFH);
103  recHitsBH_ = consumes<HGCRecHitCollection>(recHitsBH);
104  algo_ = 3;
105  }
106  caloParticles_ = consumes<std::vector<CaloParticle> >(caloParticles);
107  hgcalMultiClusters_ = consumes<std::vector<reco::PFCluster> >(hgcalMultiClusters);
108  electrons_ = consumes<std::vector<reco::GsfElectron> >(electrons);
109  photons_ = consumes<std::vector<reco::Photon> >(photons);
110 
111  // size should be HGC layers 52 is enough
112  Energy_layer_calib_.fill(0.);
114 }
115 
117  // do anything here that needs to be done at desctruction time
118  // (e.g. close files, deallocate resources etc.)
119 }
120 
122  edm::Run const& iRun,
123  edm::EventSetup const& /* iSetup */) {
124  ibooker.cd();
125  ibooker.setCurrentFolder("HGCalHitCalibration");
127  ibooker.book1D("h_EoP_CPene_100_calib_fraction", "", 1000, -0.5, 2.5);
129  ibooker.book1D("h_EoP_CPene_200_calib_fraction", "", 1000, -0.5, 2.5);
131  ibooker.book1D("h_EoP_CPene_300_calib_fraction", "", 1000, -0.5, 2.5);
133  ibooker.book1D("hgcal_EoP_CPene_100_calib_fraction", "", 1000, -0.5, 2.5);
135  ibooker.book1D("hgcal_EoP_CPene_200_calib_fraction", "", 1000, -0.5, 2.5);
137  ibooker.book1D("hgcal_EoP_CPene_300_calib_fraction", "", 1000, -0.5, 2.5);
139  ibooker.book1D("hgcal_ele_EoP_CPene_100_calib_fraction", "", 1000, -0.5, 2.5);
141  ibooker.book1D("hgcal_ele_EoP_CPene_200_calib_fraction", "", 1000, -0.5, 2.5);
143  ibooker.book1D("hgcal_ele_EoP_CPene_300_calib_fraction", "", 1000, -0.5, 2.5);
145  ibooker.book1D("hgcal_photon_EoP_CPene_100_calib_fraction", "", 1000, -0.5, 2.5);
147  ibooker.book1D("hgcal_photon_EoP_CPene_200_calib_fraction", "", 1000, -0.5, 2.5);
149  ibooker.book1D("hgcal_photon_EoP_CPene_300_calib_fraction", "", 1000, -0.5, 2.5);
150  LayerOccupancy_ = ibooker.book1D("LayerOccupancy", "", layers_, 0., (float)layers_);
151 }
152 
154  std::map<DetId, const HGCRecHit*>& hitmap, const DetId hitid,
155  const unsigned int hitlayer, const float fraction, int& seedDet,
156  float& seedEnergy) {
157  if (hitmap.find(hitid) == hitmap.end()) {
158  // Hit was not reconstructed
159  IfLogTrace(debug_ > 0, "HGCalHitCalibration")
160  << ">>> Failed to find detid " << std::hex << hitid.rawId() << std::dec
161  << " Det " << hitid.det()
162  << " Subdet " << hitid.subdetId() << std::endl;
163  return;
164  }
165  if (hitid.det() != DetId::Forward) {
166  IfLogTrace(debug_ > 0, "HGCalHitCalibration")
167  << ">>> Wrong type of detid " << std::hex << hitid.rawId() << std::dec
168  << " Det " << hitid.det()
169  << " Subdet " << hitid.subdetId() << std::endl;
170  return;
171  }
172  unsigned int layer = recHitTools_.getLayerWithOffset(hitid);
173  assert(hitlayer == layer);
174  Energy_layer_calib_fraction_[layer] += hitmap[hitid]->energy() * fraction;
175  LayerOccupancy_->Fill(layer);
176  if (seedEnergy < hitmap[hitid]->energy()) {
177  seedEnergy = hitmap[hitid]->energy();
178  seedDet = recHitTools_.getSiThickness(hitid);
179  }
180 }
181 
183  const edm::EventSetup& iSetup) {
184  using namespace edm;
185 
186  recHitTools_.getEventSetup(iSetup);
187 
188  Handle<HGCRecHitCollection> recHitHandleEE;
189  Handle<HGCRecHitCollection> recHitHandleFH;
190  Handle<HGCRecHitCollection> recHitHandleBH;
191 
192  Handle<std::vector<CaloParticle> > caloParticleHandle;
193  iEvent.getByToken(caloParticles_, caloParticleHandle);
194  const std::vector<CaloParticle>& caloParticles = *caloParticleHandle;
195 
196  Handle<std::vector<reco::PFCluster> > hgcalMultiClustersHandle;
197  iEvent.getByToken(hgcalMultiClusters_, hgcalMultiClustersHandle);
198 
199  Handle<std::vector<reco::GsfElectron> > PFElectronHandle;
200  iEvent.getByToken(electrons_, PFElectronHandle);
201 
202  Handle<std::vector<reco::Photon> > PFPhotonHandle;
203  iEvent.getByToken(photons_, PFPhotonHandle);
204 
205  // make a map detid-rechit
206  std::map<DetId, const HGCRecHit*> hitmap;
207  switch (algo_) {
208  case 1: {
209  iEvent.getByToken(recHitsEE_, recHitHandleEE);
210  iEvent.getByToken(recHitsFH_, recHitHandleFH);
211  iEvent.getByToken(recHitsBH_, recHitHandleBH);
212  const auto& rechitsEE = *recHitHandleEE;
213  const auto& rechitsFH = *recHitHandleFH;
214  const auto& rechitsBH = *recHitHandleBH;
215  for (unsigned int i = 0; i < rechitsEE.size(); ++i) {
216  hitmap[rechitsEE[i].detid()] = &rechitsEE[i];
217  }
218  for (unsigned int i = 0; i < rechitsFH.size(); ++i) {
219  hitmap[rechitsFH[i].detid()] = &rechitsFH[i];
220  }
221  for (unsigned int i = 0; i < rechitsBH.size(); ++i) {
222  hitmap[rechitsBH[i].detid()] = &rechitsBH[i];
223  }
224  break;
225  }
226  case 2: {
227  iEvent.getByToken(recHitsEE_, recHitHandleEE);
228  const HGCRecHitCollection& rechitsEE = *recHitHandleEE;
229  for (unsigned int i = 0; i < rechitsEE.size(); i++) {
230  hitmap[rechitsEE[i].detid()] = &rechitsEE[i];
231  }
232  break;
233  }
234  case 3: {
235  iEvent.getByToken(recHitsFH_, recHitHandleFH);
236  iEvent.getByToken(recHitsBH_, recHitHandleBH);
237  const auto& rechitsFH = *recHitHandleFH;
238  const auto& rechitsBH = *recHitHandleBH;
239  for (unsigned int i = 0; i < rechitsFH.size(); i++) {
240  hitmap[rechitsFH[i].detid()] = &rechitsFH[i];
241  }
242  for (unsigned int i = 0; i < rechitsBH.size(); i++) {
243  hitmap[rechitsBH[i].detid()] = &rechitsBH[i];
244  }
245  break;
246  }
247  default:
248  assert(false);
249  break;
250  }
251 
252  // loop over caloParticles
253  int seedDet = 0;
254  float seedEnergy = 0.;
255  IfLogTrace(debug_ > 0, "HGCalHitCalibration")
256  << "Number of caloParticles: " << caloParticles.size() << std::endl;
257  for (const auto& it_caloPart : caloParticles) {
258  const SimClusterRefVector& simClusterRefVector = it_caloPart.simClusters();
259  Energy_layer_calib_.fill(0.);
261 
262  seedDet = 0;
263  seedEnergy = 0.;
264  for (const auto& it_sc : simClusterRefVector) {
265  const SimCluster& simCluster = (*(it_sc));
266  IfLogTrace(debug_ > 1, "HGCalHitCalibration")
267  << ">>> SC.energy(): " << simCluster.energy()
268  << " SC.simEnergy(): " << simCluster.simEnergy()
269  << std::endl;
270  const std::vector<std::pair<uint32_t, float> >& hits_and_fractions =
271  simCluster.hits_and_fractions();
272 
273  // loop over hits
274  for (const auto& it_haf : hits_and_fractions) {
275  unsigned int hitlayer = recHitTools_.getLayerWithOffset(it_haf.first);
276  DetId hitid = (it_haf.first);
277  // dump raw RecHits and match
278  if (rawRecHits_) {
279  if ((hitid.det() == DetId::Forward &&
280  (hitid.subdetId() == HGCEE || hitid.subdetId() == HGCHEF ||
281  hitid.subdetId() == HGCHEB)) ||
282  (hitid.det() == DetId::Hcal && hitid.subdetId() == HcalEndcap))
283  fillWithRecHits(hitmap, hitid, hitlayer, it_haf.second, seedDet,
284  seedEnergy);
285  }
286  } // end simHit
287  } // end simCluster
288 
289  auto sumCalibRecHitCalib_fraction = std::accumulate(Energy_layer_calib_fraction_.begin(),
290  Energy_layer_calib_fraction_.end(), 0.);
291  IfLogTrace(debug_ > 0, "HGCalHitCalibration")
292  << ">>> MC Energy: " << it_caloPart.energy()
293  << " reco energy: " << sumCalibRecHitCalib_fraction
294  << std::endl;
295  if (h_EoP_CPene_calib_fraction_.count(seedDet))
296  h_EoP_CPene_calib_fraction_[seedDet]->Fill(sumCalibRecHitCalib_fraction /
297  it_caloPart.energy());
298 
299  // Loop on reconstructed SC.
300  const auto& clusters = *hgcalMultiClustersHandle;
301  float total_energy = 0.;
302  float max_dR2 = 0.0025;
303  auto closest = std::min_element(clusters.begin(),
304  clusters.end(),
305  [&](const reco::PFCluster &a,
306  const reco::PFCluster &b) {
307  auto dR2_a = reco::deltaR2(it_caloPart, a);
308  auto dR2_b = reco::deltaR2(it_caloPart, b);
309  auto ERatio_a = a.correctedEnergy()/it_caloPart.energy();
310  auto ERatio_b = b.correctedEnergy()/it_caloPart.energy();
311  // If both clusters are within 0.0025, mark as first (min) the
312  // element with the highest ratio against the SimCluster
313  if (dR2_a < max_dR2 && dR2_b < max_dR2)
314  return ERatio_a > ERatio_b;
315  return dR2_a < dR2_b;
316  });
317  if (closest != clusters.end()
318  && reco::deltaR2(*closest, it_caloPart) < 0.01) {
319  total_energy = closest->correctedEnergy();
320  seedDet = recHitTools_.getSiThickness(closest->seed());
321  if (hgcal_EoP_CPene_calib_fraction_.count(seedDet)) {
322  hgcal_EoP_CPene_calib_fraction_[seedDet]->Fill(total_energy /
323  it_caloPart.energy());
324  }
325  }
326 
327  auto closest_fcn = [&](auto const &a, auto const&b){
328  auto dR2_a = reco::deltaR2(it_caloPart, a);
329  auto dR2_b = reco::deltaR2(it_caloPart, b);
330  auto ERatio_a = a.energy()/it_caloPart.energy();
331  auto ERatio_b = b.energy()/it_caloPart.energy();
332  // If both clusters are within 0.0025, mark as first (min) the
333  // element with the highest ratio against the SimCluster
334  if (dR2_a < max_dR2 && dR2_b < max_dR2)
335  return ERatio_a > ERatio_b;
336  return dR2_a < dR2_b;
337  };
338  // ELECTRONS in HGCAL
339  if (PFElectronHandle.isValid()) {
340  auto const & ele = (*PFElectronHandle);
341  auto closest = std::min_element(ele.begin(),
342  ele.end(),
343  closest_fcn);
344  if (closest != ele.end()
345  && closest->superCluster()->seed()->seed().det() == DetId::Forward
346  && reco::deltaR2(*closest, it_caloPart) < 0.01) {
347  seedDet = recHitTools_.getSiThickness(closest->superCluster()->seed()->seed());
348  if (hgcal_ele_EoP_CPene_calib_fraction_.count(seedDet)) {
349  hgcal_ele_EoP_CPene_calib_fraction_[seedDet]->Fill(closest->energy() /
350  it_caloPart.energy());
351  }
352  }
353  }
354 
355  // PHOTONS in HGCAL
356  if (PFPhotonHandle.isValid()) {
357  auto const & photon = (*PFPhotonHandle);
358  auto closest = std::min_element(photon.begin(),
359  photon.end(),
360  closest_fcn);
361  if (closest != photon.end()
362  && closest->superCluster()->seed()->seed().det() == DetId::Forward
363  && reco::deltaR2(*closest, it_caloPart) < 0.01) {
364  seedDet = recHitTools_.getSiThickness(closest->superCluster()->seed()->seed());
365  if (hgcal_photon_EoP_CPene_calib_fraction_.count(seedDet)) {
366  hgcal_photon_EoP_CPene_calib_fraction_[seedDet]->Fill(closest->energy() /
367  it_caloPart.energy());
368  }
369  }
370  }
371  } // end caloparticle
372 }
373 
374 // ------------ method fills 'descriptions' with the allowed parameters for the
375 // module ------------
377  edm::ConfigurationDescriptions& descriptions) {
379  desc.add<int>("debug", 0);
380  desc.add<bool>("rawRecHits", true);
381  desc.add<std::string>("detector", "all");
382  desc.add<edm::InputTag>("caloParticles", edm::InputTag("mix", "MergedCaloTruth"));
383  desc.add<edm::InputTag>("recHitsEE", edm::InputTag("HGCalRecHit", "HGCEERecHits"));
384  desc.add<edm::InputTag>("recHitsFH", edm::InputTag("HGCalRecHit", "HGCHEFRecHits"));
385  desc.add<edm::InputTag>("recHitsBH", edm::InputTag("HGCalRecHit", "HGCHEBRecHits"));
386  desc.add<edm::InputTag>("hgcalMultiClusters", edm::InputTag("particleFlowClusterHGCalFromMultiCl"));
387  desc.add<edm::InputTag>("electrons", edm::InputTag("ecalDrivenGsfElectronsFromMultiCl"));
388  desc.add<edm::InputTag>("photons", edm::InputTag("photonsFromMultiCl"));
389  descriptions.add("hgcalHitCalibration", desc);
390 }
391 
392 // define this as a plug-in
T getParameter(std::string const &) const
edm::EDGetTokenT< std::vector< CaloParticle > > caloParticles_
edm::EDGetTokenT< std::vector< reco::Photon > > photons_
std::array< float, layers_ > Energy_layer_calib_fraction_
edm::EDGetTokenT< std::vector< reco::PFCluster > > hgcalMultiClusters_
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
std::map< int, MonitorElement * > hgcal_EoP_CPene_calib_fraction_
double correctedEnergy() const
Definition: CaloCluster.h:125
edm::EDGetTokenT< HGCRecHitCollection > recHitsFH_
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
Definition: PFCluster.h:47
edm::EDGetTokenT< HGCRecHitCollection > recHitsEE_
std::vector< std::pair< uint32_t, float > > hits_and_fractions() const
Returns list of rechit IDs and fractions for this SimCluster.
Definition: SimCluster.h:210
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:519
std::map< int, MonitorElement * > hgcal_ele_EoP_CPene_calib_fraction_
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:17
#define IfLogTrace(cond, cat)
HGCalHitCalibration(const edm::ParameterSet &)
std::map< int, MonitorElement * > hgcal_photon_EoP_CPene_calib_fraction_
#define constexpr
void getEventSetup(const edm::EventSetup &)
Definition: RecHitTools.cc:61
void Fill(long long x)
uint32_t rawId() const
get the raw id
Definition: DetId.h:44
MonitorElement * LayerOccupancy_
int iEvent
Definition: GenABIO.cc:230
edm::EDGetTokenT< HGCRecHitCollection > recHitsBH_
Monte Carlo truth information used for tracking validation.
Definition: SimCluster.h:28
void Fill(HcalDetId &id, double val, std::vector< TH2F > &depth)
MonitorElement * book1D(Args &&...args)
Definition: DQMStore.h:118
float energy() const
Energy. Note this is taken from the first SimTrack only.
Definition: SimCluster.h:111
ParameterDescriptionBase * add(U const &iLabel, T const &value)
bool isValid() const
Definition: HandleBase.h:74
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:38
double energy() const
cluster energy
Definition: PFCluster.h:82
hgcal::RecHitTools recHitTools_
void bookHistograms(DQMStore::IBooker &, edm::Run const &, edm::EventSetup const &) override
float simEnergy() const
returns the accumulated sim energy in the cluster
Definition: SimCluster.h:225
std::float_t getSiThickness(const DetId &) const
Definition: RecHitTools.cc:103
Definition: DetId.h:18
void setCurrentFolder(const std::string &fullpath)
Definition: DQMStore.cc:279
unsigned int getLayerWithOffset(const DetId &) const
Definition: RecHitTools.cc:179
edm::EDGetTokenT< std::vector< reco::GsfElectron > > electrons_
std::map< int, MonitorElement * > h_EoP_CPene_calib_fraction_
double b
Definition: hdecay.h:120
void add(std::string const &label, ParameterSetDescription const &psetDescription)
T1 deltaR2(T1 eta1, T2 phi1, T3 eta2, T4 phi2)
Definition: deltaR.h:36
void analyze(const edm::Event &, const edm::EventSetup &) override
HLT enums.
void fillWithRecHits(std::map< DetId, const HGCRecHit * > &, DetId, unsigned int, float, int &, float &)
size_type size() const
double a
Definition: hdecay.h:121
std::array< float, layers_ > Energy_layer_calib_
Detector det() const
get the detector field from this detid
Definition: DetId.h:36
Definition: Run.h:43