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) && (hitid.det() != DetId::HGCalEE) &&
166  (hitid.det() != DetId::HGCalHSi) && (hitid.det() != DetId::HGCalHSc)) {
167  IfLogTrace(debug_ > 0, "HGCalHitCalibration")
168  << ">>> Wrong type of detid " << std::hex << hitid.rawId() << std::dec
169  << " Det " << hitid.det()
170  << " Subdet " << hitid.subdetId() << std::endl;
171  return;
172  }
173  unsigned int layer = recHitTools_.getLayerWithOffset(hitid);
174  assert(hitlayer == layer);
175  Energy_layer_calib_fraction_[layer] += hitmap[hitid]->energy() * fraction;
176  LayerOccupancy_->Fill(layer);
177  if (seedEnergy < hitmap[hitid]->energy()) {
178  seedEnergy = hitmap[hitid]->energy();
179  seedDet = recHitTools_.getSiThickness(hitid);
180  }
181 }
182 
184  const edm::EventSetup& iSetup) {
185  using namespace edm;
186 
187  recHitTools_.getEventSetup(iSetup);
188 
189  Handle<HGCRecHitCollection> recHitHandleEE;
190  Handle<HGCRecHitCollection> recHitHandleFH;
191  Handle<HGCRecHitCollection> recHitHandleBH;
192 
193  Handle<std::vector<CaloParticle> > caloParticleHandle;
194  iEvent.getByToken(caloParticles_, caloParticleHandle);
195  const std::vector<CaloParticle>& caloParticles = *caloParticleHandle;
196 
197  Handle<std::vector<reco::PFCluster> > hgcalMultiClustersHandle;
198  iEvent.getByToken(hgcalMultiClusters_, hgcalMultiClustersHandle);
199 
200  Handle<std::vector<reco::GsfElectron> > PFElectronHandle;
201  iEvent.getByToken(electrons_, PFElectronHandle);
202 
203  Handle<std::vector<reco::Photon> > PFPhotonHandle;
204  iEvent.getByToken(photons_, PFPhotonHandle);
205 
206  // make a map detid-rechit
207  std::map<DetId, const HGCRecHit*> hitmap;
208  switch (algo_) {
209  case 1: {
210  iEvent.getByToken(recHitsEE_, recHitHandleEE);
211  iEvent.getByToken(recHitsFH_, recHitHandleFH);
212  iEvent.getByToken(recHitsBH_, recHitHandleBH);
213  const auto& rechitsEE = *recHitHandleEE;
214  const auto& rechitsFH = *recHitHandleFH;
215  const auto& rechitsBH = *recHitHandleBH;
216  for (unsigned int i = 0; i < rechitsEE.size(); ++i) {
217  hitmap[rechitsEE[i].detid()] = &rechitsEE[i];
218  }
219  for (unsigned int i = 0; i < rechitsFH.size(); ++i) {
220  hitmap[rechitsFH[i].detid()] = &rechitsFH[i];
221  }
222  for (unsigned int i = 0; i < rechitsBH.size(); ++i) {
223  hitmap[rechitsBH[i].detid()] = &rechitsBH[i];
224  }
225  break;
226  }
227  case 2: {
228  iEvent.getByToken(recHitsEE_, recHitHandleEE);
229  const HGCRecHitCollection& rechitsEE = *recHitHandleEE;
230  for (unsigned int i = 0; i < rechitsEE.size(); i++) {
231  hitmap[rechitsEE[i].detid()] = &rechitsEE[i];
232  }
233  break;
234  }
235  case 3: {
236  iEvent.getByToken(recHitsFH_, recHitHandleFH);
237  iEvent.getByToken(recHitsBH_, recHitHandleBH);
238  const auto& rechitsFH = *recHitHandleFH;
239  const auto& rechitsBH = *recHitHandleBH;
240  for (unsigned int i = 0; i < rechitsFH.size(); i++) {
241  hitmap[rechitsFH[i].detid()] = &rechitsFH[i];
242  }
243  for (unsigned int i = 0; i < rechitsBH.size(); i++) {
244  hitmap[rechitsBH[i].detid()] = &rechitsBH[i];
245  }
246  break;
247  }
248  default:
249  assert(false);
250  break;
251  }
252 
253  // loop over caloParticles
254  int seedDet = 0;
255  float seedEnergy = 0.;
256  IfLogTrace(debug_ > 0, "HGCalHitCalibration")
257  << "Number of caloParticles: " << caloParticles.size() << std::endl;
258  for (const auto& it_caloPart : caloParticles) {
259  const SimClusterRefVector& simClusterRefVector = it_caloPart.simClusters();
260  Energy_layer_calib_.fill(0.);
262 
263  seedDet = 0;
264  seedEnergy = 0.;
265  for (const auto& it_sc : simClusterRefVector) {
266  const SimCluster& simCluster = (*(it_sc));
267  IfLogTrace(debug_ > 1, "HGCalHitCalibration")
268  << ">>> SC.energy(): " << simCluster.energy()
269  << " SC.simEnergy(): " << simCluster.simEnergy()
270  << std::endl;
271  const std::vector<std::pair<uint32_t, float> >& hits_and_fractions =
272  simCluster.hits_and_fractions();
273 
274  // loop over hits
275  for (const auto& it_haf : hits_and_fractions) {
276  unsigned int hitlayer = recHitTools_.getLayerWithOffset(it_haf.first);
277  DetId hitid = (it_haf.first);
278  // dump raw RecHits and match
279  if (rawRecHits_) {
280  if ((hitid.det() == DetId::Forward &&
281  (hitid.subdetId() == HGCEE || hitid.subdetId() == HGCHEF ||
282  hitid.subdetId() == HGCHEB)) ||
283  (hitid.det() == DetId::HGCalEE) ||
284  (hitid.det() == DetId::HGCalHSi) ||
285  (hitid.det() == DetId::HGCalHSc) ||
286  (hitid.det() == DetId::Hcal && hitid.subdetId() == HcalEndcap))
287  fillWithRecHits(hitmap, hitid, hitlayer, it_haf.second, seedDet,
288  seedEnergy);
289  }
290  } // end simHit
291  } // end simCluster
292 
293  auto sumCalibRecHitCalib_fraction = std::accumulate(Energy_layer_calib_fraction_.begin(),
294  Energy_layer_calib_fraction_.end(), 0.);
295  IfLogTrace(debug_ > 0, "HGCalHitCalibration")
296  << ">>> MC Energy: " << it_caloPart.energy()
297  << " reco energy: " << sumCalibRecHitCalib_fraction
298  << std::endl;
299  if (h_EoP_CPene_calib_fraction_.count(seedDet))
300  h_EoP_CPene_calib_fraction_[seedDet]->Fill(sumCalibRecHitCalib_fraction /
301  it_caloPart.energy());
302 
303  // Loop on reconstructed SC.
304  const auto& clusters = *hgcalMultiClustersHandle;
305  float total_energy = 0.;
306  float max_dR2 = 0.0025;
307  auto closest = std::min_element(clusters.begin(),
308  clusters.end(),
309  [&](const reco::PFCluster &a,
310  const reco::PFCluster &b) {
311  auto dR2_a = reco::deltaR2(it_caloPart, a);
312  auto dR2_b = reco::deltaR2(it_caloPart, b);
313  auto ERatio_a = a.correctedEnergy()/it_caloPart.energy();
314  auto ERatio_b = b.correctedEnergy()/it_caloPart.energy();
315  // If both clusters are within 0.0025, mark as first (min) the
316  // element with the highest ratio against the SimCluster
317  if (dR2_a < max_dR2 && dR2_b < max_dR2)
318  return ERatio_a > ERatio_b;
319  return dR2_a < dR2_b;
320  });
321  if (closest != clusters.end()
322  && reco::deltaR2(*closest, it_caloPart) < 0.01) {
323  total_energy = closest->correctedEnergy();
324  seedDet = recHitTools_.getSiThickness(closest->seed());
325  if (hgcal_EoP_CPene_calib_fraction_.count(seedDet)) {
326  hgcal_EoP_CPene_calib_fraction_[seedDet]->Fill(total_energy /
327  it_caloPart.energy());
328  }
329  }
330 
331  auto closest_fcn = [&](auto const &a, auto const&b){
332  auto dR2_a = reco::deltaR2(it_caloPart, a);
333  auto dR2_b = reco::deltaR2(it_caloPart, b);
334  auto ERatio_a = a.energy()/it_caloPart.energy();
335  auto ERatio_b = b.energy()/it_caloPart.energy();
336  // If both clusters are within 0.0025, mark as first (min) the
337  // element with the highest ratio against the SimCluster
338  if (dR2_a < max_dR2 && dR2_b < max_dR2)
339  return ERatio_a > ERatio_b;
340  return dR2_a < dR2_b;
341  };
342  // ELECTRONS in HGCAL
343  if (PFElectronHandle.isValid()) {
344  auto const & ele = (*PFElectronHandle);
345  auto closest = std::min_element(ele.begin(),
346  ele.end(),
347  closest_fcn);
348  if (closest != ele.end()
349  && (closest->superCluster()->seed()->seed().det() == DetId::Forward ||
350  closest->superCluster()->seed()->seed().det() == DetId::HGCalEE)
351  && reco::deltaR2(*closest, it_caloPart) < 0.01) {
352  seedDet = recHitTools_.getSiThickness(closest->superCluster()->seed()->seed());
353  if (hgcal_ele_EoP_CPene_calib_fraction_.count(seedDet)) {
354  hgcal_ele_EoP_CPene_calib_fraction_[seedDet]->Fill(closest->energy() /
355  it_caloPart.energy());
356  }
357  }
358  }
359 
360  // PHOTONS in HGCAL
361  if (PFPhotonHandle.isValid()) {
362  auto const & photon = (*PFPhotonHandle);
363  auto closest = std::min_element(photon.begin(),
364  photon.end(),
365  closest_fcn);
366  if (closest != photon.end()
367  && (closest->superCluster()->seed()->seed().det() == DetId::Forward ||
368  closest->superCluster()->seed()->seed().det() == DetId::HGCalEE)
369  && reco::deltaR2(*closest, it_caloPart) < 0.01) {
370  seedDet = recHitTools_.getSiThickness(closest->superCluster()->seed()->seed());
371  if (hgcal_photon_EoP_CPene_calib_fraction_.count(seedDet)) {
372  hgcal_photon_EoP_CPene_calib_fraction_[seedDet]->Fill(closest->energy() /
373  it_caloPart.energy());
374  }
375  }
376  }
377  } // end caloparticle
378 }
379 
380 // ------------ method fills 'descriptions' with the allowed parameters for the
381 // module ------------
383  edm::ConfigurationDescriptions& descriptions) {
385  desc.add<int>("debug", 0);
386  desc.add<bool>("rawRecHits", true);
387  desc.add<std::string>("detector", "all");
388  desc.add<edm::InputTag>("caloParticles", edm::InputTag("mix", "MergedCaloTruth"));
389  desc.add<edm::InputTag>("recHitsEE", edm::InputTag("HGCalRecHit", "HGCEERecHits"));
390  desc.add<edm::InputTag>("recHitsFH", edm::InputTag("HGCalRecHit", "HGCHEFRecHits"));
391  desc.add<edm::InputTag>("recHitsBH", edm::InputTag("HGCalRecHit", "HGCHEBRecHits"));
392  desc.add<edm::InputTag>("hgcalMultiClusters", edm::InputTag("particleFlowClusterHGCalFromMultiCl"));
393  desc.add<edm::InputTag>("electrons", edm::InputTag("ecalDrivenGsfElectronsFromMultiCl"));
394  desc.add<edm::InputTag>("photons", edm::InputTag("photonsFromMultiCl"));
395  descriptions.add("hgcalHitCalibrationDefault", desc);
396 }
397 
398 // 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:127
edm::EDGetTokenT< HGCRecHitCollection > recHitsFH_
Particle flow cluster, see clustering algorithm in PFClusterAlgo.
Definition: PFCluster.h:47
edm::EDGetTokenT< HGCRecHitCollection > recHitsEE_
bool getByToken(EDGetToken token, Handle< PROD > &result) const
Definition: Event.h:517
std::map< int, MonitorElement * > hgcal_ele_EoP_CPene_calib_fraction_
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:50
#define IfLogTrace(cond, cat)
HGCalHitCalibration(const edm::ParameterSet &)
std::map< int, MonitorElement * > hgcal_photon_EoP_CPene_calib_fraction_
void getEventSetup(const edm::EventSetup &)
Definition: RecHitTools.cc:73
void Fill(long long x)
MonitorElement * LayerOccupancy_
int iEvent
Definition: GenABIO.cc:224
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
void setCurrentFolder(std::string const &fullpath)
Definition: DQMStore.cc:268
edm::EDGetTokenT< HGCRecHitCollection > recHitsBH_
Monte Carlo truth information used for tracking validation.
Definition: SimCluster.h:29
void Fill(HcalDetId &id, double val, std::vector< TH2F > &depth)
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:41
MonitorElement * book1D(Args &&...args)
Definition: DQMStore.h:106
float energy() const
Energy. Note this is taken from the first SimTrack only.
Definition: SimCluster.h:104
ParameterDescriptionBase * add(U const &iLabel, T const &value)
bool isValid() const
Definition: HandleBase.h:74
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:196
std::float_t getSiThickness(const DetId &) const
Definition: RecHitTools.cc:145
Definition: DetId.h:18
constexpr auto deltaR2(const T1 &t1, const T2 &t2) -> decltype(t1.eta())
Definition: deltaR.h:16
unsigned int getLayerWithOffset(const DetId &) const
Definition: RecHitTools.cc:283
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)
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_
#define constexpr
Definition: Run.h:45
std::vector< std::pair< uint32_t, float > > hits_and_fractions() const
Returns list of rechit IDs and fractions for this SimCluster.
Definition: SimCluster.h:181
constexpr Detector det() const
get the detector field from this detid
Definition: DetId.h:39