CMS 3D CMS Logo

List of all members | Public Member Functions | Private Member Functions | Private Attributes
LCToCPAssociatorByEnergyScoreImpl Class Reference

#include <LCToCPAssociatorByEnergyScoreImpl.h>

Inheritance diagram for LCToCPAssociatorByEnergyScoreImpl:
hgcal::LayerClusterToCaloParticleAssociatorBaseImpl

Public Member Functions

hgcal::RecoToSimCollection associateRecoToSim (const edm::Handle< reco::CaloClusterCollection > &cCH, const edm::Handle< CaloParticleCollection > &cPCH) const override
 Associate a LayerCluster to CaloParticles. More...
 
hgcal::SimToRecoCollection associateSimToReco (const edm::Handle< reco::CaloClusterCollection > &cCH, const edm::Handle< CaloParticleCollection > &cPCH) const override
 Associate a CaloParticle to LayerClusters. More...
 
 LCToCPAssociatorByEnergyScoreImpl (edm::EDProductGetter const &, bool, std::shared_ptr< hgcal::RecHitTools >, const std::unordered_map< DetId, const HGCRecHit * > *)
 
- Public Member Functions inherited from hgcal::LayerClusterToCaloParticleAssociatorBaseImpl
 LayerClusterToCaloParticleAssociatorBaseImpl ()
 Constructor. More...
 
virtual ~LayerClusterToCaloParticleAssociatorBaseImpl ()
 Destructor. More...
 

Private Member Functions

hgcal::association makeConnections (const edm::Handle< reco::CaloClusterCollection > &cCH, const edm::Handle< CaloParticleCollection > &cPCH) const
 

Private Attributes

const bool hardScatterOnly_
 
const std::unordered_map< DetId, const HGCRecHit * > * hitMap_
 
unsigned layers_
 
const edm::EDProductGetterproductGetter_
 
std::shared_ptr< hgcal::RecHitToolsrecHitTools_
 

Detailed Description

Definition at line 47 of file LCToCPAssociatorByEnergyScoreImpl.h.

Constructor & Destructor Documentation

◆ LCToCPAssociatorByEnergyScoreImpl()

LCToCPAssociatorByEnergyScoreImpl::LCToCPAssociatorByEnergyScoreImpl ( edm::EDProductGetter const &  productGetter,
bool  hardScatterOnly,
std::shared_ptr< hgcal::RecHitTools recHitTools,
const std::unordered_map< DetId, const HGCRecHit * > *  hitMap 
)
explicit

Definition at line 12 of file LCToCPAssociatorByEnergyScoreImpl.cc.

17  : hardScatterOnly_(hardScatterOnly), recHitTools_(recHitTools), hitMap_(hitMap), productGetter_(&productGetter) {
18  layers_ = recHitTools_->lastLayerBH();
19 }

References layers_, and recHitTools_.

Member Function Documentation

◆ associateRecoToSim()

hgcal::RecoToSimCollection LCToCPAssociatorByEnergyScoreImpl::associateRecoToSim ( const edm::Handle< reco::CaloClusterCollection > &  cCH,
const edm::Handle< CaloParticleCollection > &  cPCH 
) const
overridevirtual

Associate a LayerCluster to CaloParticles.

Reimplemented from hgcal::LayerClusterToCaloParticleAssociatorBaseImpl.

Definition at line 472 of file LCToCPAssociatorByEnergyScoreImpl.cc.

473  {
475  const auto& links = makeConnections(cCCH, cPCH);
476 
477  const auto& cpsInLayerCluster = std::get<0>(links);
478  for (size_t lcId = 0; lcId < cpsInLayerCluster.size(); ++lcId) {
479  for (auto& cpPair : cpsInLayerCluster[lcId]) {
480  LogDebug("LCToCPAssociatorByEnergyScoreImpl")
481  << "layerCluster Id: \t" << lcId << "\t CP id: \t" << cpPair.first << "\t score \t" << cpPair.second << "\n";
482  // Fill AssociationMap
483  returnValue.insert(edm::Ref<reco::CaloClusterCollection>(cCCH, lcId), // Ref to LC
484  std::make_pair(edm::Ref<CaloParticleCollection>(cPCH, cpPair.first),
485  cpPair.second) // Pair <Ref to CP, score>
486  );
487  }
488  }
489  return returnValue;
490 }

References edm::AssociationMap< Tag >::insert(), electronStore::links, LogDebug, makeConnections(), and productGetter_.

◆ associateSimToReco()

hgcal::SimToRecoCollection LCToCPAssociatorByEnergyScoreImpl::associateSimToReco ( const edm::Handle< reco::CaloClusterCollection > &  cCH,
const edm::Handle< CaloParticleCollection > &  cPCH 
) const
overridevirtual

Associate a CaloParticle to LayerClusters.

Reimplemented from hgcal::LayerClusterToCaloParticleAssociatorBaseImpl.

Definition at line 492 of file LCToCPAssociatorByEnergyScoreImpl.cc.

493  {
495  const auto& links = makeConnections(cCCH, cPCH);
496  const auto& cPOnLayer = std::get<1>(links);
497  for (size_t cpId = 0; cpId < cPOnLayer.size(); ++cpId) {
498  for (size_t layerId = 0; layerId < cPOnLayer[cpId].size(); ++layerId) {
499  for (auto& lcPair : cPOnLayer[cpId][layerId].layerClusterIdToEnergyAndScore) {
500  returnValue.insert(
501  edm::Ref<CaloParticleCollection>(cPCH, cpId), // Ref to CP
502  std::make_pair(edm::Ref<reco::CaloClusterCollection>(cCCH, lcPair.first), // Pair <Ref to LC,
503  std::make_pair(lcPair.second.first, lcPair.second.second)) // pair <energy, score> >
504  );
505  }
506  }
507  }
508  return returnValue;
509 }

References edm::AssociationMap< Tag >::insert(), electronStore::links, makeConnections(), and productGetter_.

◆ makeConnections()

hgcal::association LCToCPAssociatorByEnergyScoreImpl::makeConnections ( const edm::Handle< reco::CaloClusterCollection > &  cCH,
const edm::Handle< CaloParticleCollection > &  cPCH 
) const
private

Definition at line 21 of file LCToCPAssociatorByEnergyScoreImpl.cc.

22  {
23  // 1. Extract collections and filter CaloParticles, if required
24  const auto& clusters = *cCCH.product();
25  const auto& caloParticles = *cPCH.product();
26  auto nLayerClusters = clusters.size();
27  //Consider CaloParticles coming from the hard scatterer, excluding the PU contribution.
28  std::vector<size_t> cPIndices;
29  //Consider CaloParticles coming from the hard scatterer
30  //excluding the PU contribution and save the indices.
32  auto nCaloParticles = cPIndices.size();
33 
34  // Initialize cPOnLayer. To be returned outside, since it contains the
35  // information to compute the CaloParticle-To-LayerCluster score.
37  cPOnLayer.resize(nCaloParticles);
38  for (unsigned int i = 0; i < nCaloParticles; ++i) {
39  cPOnLayer[i].resize(layers_ * 2);
40  for (unsigned int j = 0; j < layers_ * 2; ++j) {
41  cPOnLayer[i][j].caloParticleId = i;
42  cPOnLayer[i][j].energy = 0.f;
43  cPOnLayer[i][j].hits_and_fractions.clear();
44  //cPOnLayer[i][j].layerClusterIdToEnergyAndScore.reserve(nLayerClusters); // Not necessary but may improve performance
45  }
46  }
47 
48  // Fill detIdToCaloParticleId_Map and update cPOnLayer
49  std::unordered_map<DetId, std::vector<hgcal::detIdInfoInCluster>> detIdToCaloParticleId_Map;
50  for (const auto& cpId : cPIndices) {
51  const SimClusterRefVector& simClusterRefVector = caloParticles[cpId].simClusters();
52  for (const auto& it_sc : simClusterRefVector) {
53  const SimCluster& simCluster = (*(it_sc));
54  const auto& hits_and_fractions = simCluster.hits_and_fractions();
55  for (const auto& it_haf : hits_and_fractions) {
56  const auto hitid = (it_haf.first);
57  const auto cpLayerId =
58  recHitTools_->getLayerWithOffset(hitid) + layers_ * ((recHitTools_->zside(hitid) + 1) >> 1) - 1;
59  const auto itcheck = hitMap_->find(hitid);
60  if (itcheck != hitMap_->end()) {
61  auto hit_find_it = detIdToCaloParticleId_Map.find(hitid);
62  if (hit_find_it == detIdToCaloParticleId_Map.end()) {
63  detIdToCaloParticleId_Map[hitid] = std::vector<hgcal::detIdInfoInCluster>();
64  detIdToCaloParticleId_Map[hitid].emplace_back(cpId, it_haf.second);
65  } else {
66  auto findHitIt = std::find(detIdToCaloParticleId_Map[hitid].begin(),
67  detIdToCaloParticleId_Map[hitid].end(),
68  hgcal::detIdInfoInCluster{cpId, it_haf.second});
69  if (findHitIt != detIdToCaloParticleId_Map[hitid].end()) {
70  findHitIt->fraction += it_haf.second;
71  } else {
72  detIdToCaloParticleId_Map[hitid].emplace_back(cpId, it_haf.second);
73  }
74  }
75  const HGCRecHit* hit = itcheck->second;
76  cPOnLayer[cpId][cpLayerId].energy += it_haf.second * hit->energy();
77  // We need to compress the hits and fractions in order to have a
78  // reasonable score between CP and LC. Imagine, for example, that a
79  // CP has detID X used by 2 SimClusters with different fractions. If
80  // a single LC uses X with fraction 1 and is compared to the 2
81  // contributions separately, it will be assigned a score != 0, which
82  // is wrong.
83  auto& haf = cPOnLayer[cpId][cpLayerId].hits_and_fractions;
84  auto found = std::find_if(
85  std::begin(haf), std::end(haf), [&hitid](const std::pair<DetId, float>& v) { return v.first == hitid; });
86  if (found != haf.end()) {
87  found->second += it_haf.second;
88  } else {
89  cPOnLayer[cpId][cpLayerId].hits_and_fractions.emplace_back(hitid, it_haf.second);
90  }
91  }
92  }
93  }
94  }
95 
96 #ifdef EDM_ML_DEBUG
97  LogDebug("LCToCPAssociatorByEnergyScoreImpl") << "cPOnLayer INFO" << std::endl;
98  for (size_t cp = 0; cp < cPOnLayer.size(); ++cp) {
99  LogDebug("LCToCPAssociatorByEnergyScoreImpl") << "For CaloParticle Idx: " << cp << " we have: " << std::endl;
100  for (size_t cpp = 0; cpp < cPOnLayer[cp].size(); ++cpp) {
101  LogDebug("LCToCPAssociatorByEnergyScoreImpl") << " On Layer: " << cpp << " we have:" << std::endl;
102  LogDebug("LCToCPAssociatorByEnergyScoreImpl")
103  << " CaloParticleIdx: " << cPOnLayer[cp][cpp].caloParticleId << std::endl;
104  LogDebug("LCToCPAssociatorByEnergyScoreImpl")
105  << " Energy: " << cPOnLayer[cp][cpp].energy << std::endl;
106  double tot_energy = 0.;
107  for (auto const& haf : cPOnLayer[cp][cpp].hits_and_fractions) {
108  LogDebug("LCToCPAssociatorByEnergyScoreImpl")
109  << " Hits/fraction/energy: " << (uint32_t)haf.first << "/" << haf.second << "/"
110  << haf.second * hitMap_->at(haf.first)->energy() << std::endl;
111  tot_energy += haf.second * hitMap_->at(haf.first)->energy();
112  }
113  LogDebug("LCToCPAssociatorByEnergyScoreImpl") << " Tot Sum haf: " << tot_energy << std::endl;
114  for (auto const& lc : cPOnLayer[cp][cpp].layerClusterIdToEnergyAndScore) {
115  LogDebug("LCToCPAssociatorByEnergyScoreImpl") << " lcIdx/energy/score: " << lc.first << "/"
116  << lc.second.first << "/" << lc.second.second << std::endl;
117  }
118  }
119  }
120 
121  LogDebug("LCToCPAssociatorByEnergyScoreImpl") << "detIdToCaloParticleId_Map INFO" << std::endl;
122  for (auto const& cp : detIdToCaloParticleId_Map) {
123  LogDebug("LCToCPAssociatorByEnergyScoreImpl")
124  << "For detId: " << (uint32_t)cp.first
125  << " we have found the following connections with CaloParticles:" << std::endl;
126  for (auto const& cpp : cp.second) {
127  LogDebug("LCToCPAssociatorByEnergyScoreImpl")
128  << " CaloParticle Id: " << cpp.clusterId << " with fraction: " << cpp.fraction
129  << " and energy: " << cpp.fraction * hitMap_->at(cp.first)->energy() << std::endl;
130  }
131  }
132 #endif
133 
134  // Fill detIdToLayerClusterId_Map and cpsInLayerCluster; update cPOnLayer
135  std::unordered_map<DetId, std::vector<hgcal::detIdInfoInCluster>> detIdToLayerClusterId_Map;
136  // this contains the ids of the caloparticles contributing with at least one
137  // hit to the layer cluster and the reconstruction error. To be returned
138  // since this contains the information to compute the
139  // LayerCluster-To-CaloParticle score.
140  hgcal::layerClusterToCaloParticle cpsInLayerCluster;
141  cpsInLayerCluster.resize(nLayerClusters);
142 
143  for (unsigned int lcId = 0; lcId < nLayerClusters; ++lcId) {
144  const std::vector<std::pair<DetId, float>>& hits_and_fractions = clusters[lcId].hitsAndFractions();
145  unsigned int numberOfHitsInLC = hits_and_fractions.size();
146  const auto firstHitDetId = hits_and_fractions[0].first;
147  int lcLayerId =
148  recHitTools_->getLayerWithOffset(firstHitDetId) + layers_ * ((recHitTools_->zside(firstHitDetId) + 1) >> 1) - 1;
149 
150  for (unsigned int hitId = 0; hitId < numberOfHitsInLC; hitId++) {
151  const auto rh_detid = hits_and_fractions[hitId].first;
152  const auto rhFraction = hits_and_fractions[hitId].second;
153 
154  auto hit_find_in_LC = detIdToLayerClusterId_Map.find(rh_detid);
155  if (hit_find_in_LC == detIdToLayerClusterId_Map.end()) {
156  detIdToLayerClusterId_Map[rh_detid] = std::vector<hgcal::detIdInfoInCluster>();
157  }
158  detIdToLayerClusterId_Map[rh_detid].emplace_back(lcId, rhFraction);
159 
160  auto hit_find_in_CP = detIdToCaloParticleId_Map.find(rh_detid);
161 
162  if (hit_find_in_CP != detIdToCaloParticleId_Map.end()) {
163  const auto itcheck = hitMap_->find(rh_detid);
164  const HGCRecHit* hit = itcheck->second;
165  for (auto& h : hit_find_in_CP->second) {
166  cPOnLayer[h.clusterId][lcLayerId].layerClusterIdToEnergyAndScore[lcId].first += h.fraction * hit->energy();
167  cpsInLayerCluster[lcId].emplace_back(h.clusterId, 0.f);
168  }
169  }
170  } // End loop over hits on a LayerCluster
171  } // End of loop over LayerClusters
172 
173 #ifdef EDM_ML_DEBUG
174  for (unsigned int lcId = 0; lcId < nLayerClusters; ++lcId) {
175  const auto& hits_and_fractions = clusters[lcId].hitsAndFractions();
176  unsigned int numberOfHitsInLC = hits_and_fractions.size();
177  const auto firstHitDetId = hits_and_fractions[0].first;
178  int lcLayerId =
179  recHitTools_->getLayerWithOffset(firstHitDetId) + layers_ * ((recHitTools_->zside(firstHitDetId) + 1) >> 1) - 1;
180 
181  // This vector will store, for each hit in the Layercluster, the index of
182  // the CaloParticle that contributed the most, in terms of energy, to it.
183  // Special values are:
184  //
185  // -2 --> the reconstruction fraction of the RecHit is 0 (used in the past to monitor Halo Hits)
186  // -3 --> same as before with the added condition that no CaloParticle has been linked to this RecHit
187  // -1 --> the reco fraction is >0, but no CaloParticle has been linked to it
188  // >=0 --> index of the linked CaloParticle
189  std::vector<int> hitsToCaloParticleId(numberOfHitsInLC);
190  // This will store the index of the CaloParticle linked to the LayerCluster that has the most number of hits in common.
191  int maxCPId_byNumberOfHits = -1;
192  // This will store the maximum number of shared hits between a Layercluster andd a CaloParticle
193  unsigned int maxCPNumberOfHitsInLC = 0;
194  // This will store the index of the CaloParticle linked to the LayerCluster that has the most energy in common.
195  int maxCPId_byEnergy = -1;
196  // This will store the maximum number of shared energy between a Layercluster and a CaloParticle
197  float maxEnergySharedLCandCP = 0.f;
198  // This will store the fraction of the LayerCluster energy shared with the best(energy) CaloParticle: e_shared/lc_energy
199  float energyFractionOfLCinCP = 0.f;
200  // This will store the fraction of the CaloParticle energy shared with the LayerCluster: e_shared/cp_energy
201  float energyFractionOfCPinLC = 0.f;
202  std::unordered_map<unsigned, unsigned> occurrencesCPinLC;
203  unsigned int numberOfNoiseHitsInLC = 0;
204  std::unordered_map<unsigned, float> CPEnergyInLC;
205 
206  for (unsigned int hitId = 0; hitId < numberOfHitsInLC; hitId++) {
207  const auto rh_detid = hits_and_fractions[hitId].first;
208  const auto rhFraction = hits_and_fractions[hitId].second;
209 
210  auto hit_find_in_CP = detIdToCaloParticleId_Map.find(rh_detid);
211 
212  // if the fraction is zero or the hit does not belong to any calo
213  // particle, set the caloparticleId for the hit to -1 this will
214  // contribute to the number of noise hits
215 
216  // MR Remove the case in which the fraction is 0, since this could be a
217  // real hit that has been marked as halo.
218  if (rhFraction == 0.) {
219  hitsToCaloParticleId[hitId] = -2;
220  }
221  if (hit_find_in_CP == detIdToCaloParticleId_Map.end()) {
222  hitsToCaloParticleId[hitId] -= 1;
223  } else {
224  const auto itcheck = hitMap_->find(rh_detid);
225  const HGCRecHit* hit = itcheck->second;
226  auto maxCPEnergyInLC = 0.f;
227  auto maxCPId = -1;
228  for (auto& h : hit_find_in_CP->second) {
229  CPEnergyInLC[h.clusterId] += h.fraction * hit->energy();
230  // Keep track of which CaloParticle ccontributed the most, in terms
231  // of energy, to this specific LayerCluster.
232  if (CPEnergyInLC[h.clusterId] > maxCPEnergyInLC) {
233  maxCPEnergyInLC = CPEnergyInLC[h.clusterId];
234  maxCPId = h.clusterId;
235  }
236  }
237  hitsToCaloParticleId[hitId] = maxCPId;
238  }
239  } // End loop over hits on a LayerCluster
240 
241  for (const auto& c : hitsToCaloParticleId) {
242  if (c < 0) {
243  numberOfNoiseHitsInLC++;
244  } else {
245  occurrencesCPinLC[c]++;
246  }
247  }
248 
249  for (const auto& c : occurrencesCPinLC) {
250  if (c.second > maxCPNumberOfHitsInLC) {
251  maxCPId_byNumberOfHits = c.first;
252  maxCPNumberOfHitsInLC = c.second;
253  }
254  }
255 
256  for (const auto& c : CPEnergyInLC) {
257  if (c.second > maxEnergySharedLCandCP) {
258  maxCPId_byEnergy = c.first;
259  maxEnergySharedLCandCP = c.second;
260  }
261  }
262 
263  float totalCPEnergyOnLayer = 0.f;
264  if (maxCPId_byEnergy >= 0) {
265  totalCPEnergyOnLayer = cPOnLayer[maxCPId_byEnergy][lcLayerId].energy;
266  energyFractionOfCPinLC = maxEnergySharedLCandCP / totalCPEnergyOnLayer;
267  if (clusters[lcId].energy() > 0.f) {
268  energyFractionOfLCinCP = maxEnergySharedLCandCP / clusters[lcId].energy();
269  }
270  }
271 
272  LogDebug("LCToCPAssociatorByEnergyScoreImpl")
273  << std::setw(10) << "LayerId:\t" << std::setw(12) << "layerCluster\t" << std::setw(10) << "lc energy\t"
274  << std::setw(5) << "nhits\t" << std::setw(12) << "noise hits\t" << std::setw(22) << "maxCPId_byNumberOfHits\t"
275  << std::setw(8) << "nhitsCP\t" << std::setw(13) << "maxCPId_byEnergy\t" << std::setw(20)
276  << "maxEnergySharedLCandCP\t" << std::setw(22) << "totalCPEnergyOnLayer\t" << std::setw(22)
277  << "energyFractionOfLCinCP\t" << std::setw(25) << "energyFractionOfCPinLC\t"
278  << "\n";
279  LogDebug("LCToCPAssociatorByEnergyScoreImpl")
280  << std::setw(10) << lcLayerId << "\t" << std::setw(12) << lcId << "\t" << std::setw(10)
281  << clusters[lcId].energy() << "\t" << std::setw(5) << numberOfHitsInLC << "\t" << std::setw(12)
282  << numberOfNoiseHitsInLC << "\t" << std::setw(22) << maxCPId_byNumberOfHits << "\t" << std::setw(8)
283  << maxCPNumberOfHitsInLC << "\t" << std::setw(13) << maxCPId_byEnergy << "\t" << std::setw(20)
284  << maxEnergySharedLCandCP << "\t" << std::setw(22) << totalCPEnergyOnLayer << "\t" << std::setw(22)
285  << energyFractionOfLCinCP << "\t" << std::setw(25) << energyFractionOfCPinLC << "\n";
286  } // End of loop over LayerClusters
287 
288  LogDebug("LCToCPAssociatorByEnergyScoreImpl") << "Improved cPOnLayer INFO" << std::endl;
289  for (size_t cp = 0; cp < cPOnLayer.size(); ++cp) {
290  LogDebug("LCToCPAssociatorByEnergyScoreImpl") << "For CaloParticle Idx: " << cp << " we have: " << std::endl;
291  for (size_t cpp = 0; cpp < cPOnLayer[cp].size(); ++cpp) {
292  LogDebug("LCToCPAssociatorByEnergyScoreImpl") << " On Layer: " << cpp << " we have:" << std::endl;
293  LogDebug("LCToCPAssociatorByEnergyScoreImpl")
294  << " CaloParticleIdx: " << cPOnLayer[cp][cpp].caloParticleId << std::endl;
295  LogDebug("LCToCPAssociatorByEnergyScoreImpl")
296  << " Energy: " << cPOnLayer[cp][cpp].energy << std::endl;
297  double tot_energy = 0.;
298  for (auto const& haf : cPOnLayer[cp][cpp].hits_and_fractions) {
299  LogDebug("LCToCPAssociatorByEnergyScoreImpl")
300  << " Hits/fraction/energy: " << (uint32_t)haf.first << "/" << haf.second << "/"
301  << haf.second * hitMap_->at(haf.first)->energy() << std::endl;
302  tot_energy += haf.second * hitMap_->at(haf.first)->energy();
303  }
304  LogDebug("LCToCPAssociatorByEnergyScoreImpl") << " Tot Sum haf: " << tot_energy << std::endl;
305  for (auto const& lc : cPOnLayer[cp][cpp].layerClusterIdToEnergyAndScore) {
306  LogDebug("LCToCPAssociatorByEnergyScoreImpl") << " lcIdx/energy/score: " << lc.first << "/"
307  << lc.second.first << "/" << lc.second.second << std::endl;
308  }
309  }
310  }
311 
312  LogDebug("LCToCPAssociatorByEnergyScoreImpl") << "Improved detIdToCaloParticleId_Map INFO" << std::endl;
313  for (auto const& cp : detIdToCaloParticleId_Map) {
314  LogDebug("LCToCPAssociatorByEnergyScoreImpl")
315  << "For detId: " << (uint32_t)cp.first
316  << " we have found the following connections with CaloParticles:" << std::endl;
317  for (auto const& cpp : cp.second) {
318  LogDebug("LCToCPAssociatorByEnergyScoreImpl")
319  << " CaloParticle Id: " << cpp.clusterId << " with fraction: " << cpp.fraction
320  << " and energy: " << cpp.fraction * hitMap_->at(cp.first)->energy() << std::endl;
321  }
322  }
323 #endif
324 
325  // Update cpsInLayerCluster; compute the score LayerCluster-to-CaloParticle,
326  // together with the returned AssociationMap
327  for (unsigned int lcId = 0; lcId < nLayerClusters; ++lcId) {
328  // find the unique caloparticles id contributing to the layer clusters
329  std::sort(cpsInLayerCluster[lcId].begin(), cpsInLayerCluster[lcId].end());
330  auto last = std::unique(cpsInLayerCluster[lcId].begin(), cpsInLayerCluster[lcId].end());
331  cpsInLayerCluster[lcId].erase(last, cpsInLayerCluster[lcId].end());
332  const auto& hits_and_fractions = clusters[lcId].hitsAndFractions();
333  unsigned int numberOfHitsInLC = hits_and_fractions.size();
334  // If a reconstructed LayerCluster has energy 0 but is linked to a
335  // CaloParticle, assigned score 1
336  if (clusters[lcId].energy() == 0. && !cpsInLayerCluster[lcId].empty()) {
337  for (auto& cpPair : cpsInLayerCluster[lcId]) {
338  cpPair.second = 1.;
339  LogDebug("LCToCPAssociatorByEnergyScoreImpl") << "layerClusterId : \t " << lcId << "\t CP id : \t"
340  << cpPair.first << "\t score \t " << cpPair.second << "\n";
341  }
342  continue;
343  }
344 
345  // Compute the correct normalization
346  float invLayerClusterEnergyWeight = 0.f;
347  for (auto const& haf : clusters[lcId].hitsAndFractions()) {
348  invLayerClusterEnergyWeight +=
349  (haf.second * hitMap_->at(haf.first)->energy()) * (haf.second * hitMap_->at(haf.first)->energy());
350  }
351  invLayerClusterEnergyWeight = 1.f / invLayerClusterEnergyWeight;
352  for (unsigned int i = 0; i < numberOfHitsInLC; ++i) {
353  DetId rh_detid = hits_and_fractions[i].first;
354  float rhFraction = hits_and_fractions[i].second;
355 
356  bool hitWithNoCP = (detIdToCaloParticleId_Map.find(rh_detid) == detIdToCaloParticleId_Map.end());
357 
358  auto itcheck = hitMap_->find(rh_detid);
359  const HGCRecHit* hit = itcheck->second;
360  float hitEnergyWeight = hit->energy() * hit->energy();
361 
362  for (auto& cpPair : cpsInLayerCluster[lcId]) {
363  float cpFraction = 0.f;
364  if (!hitWithNoCP) {
365  auto findHitIt = std::find(detIdToCaloParticleId_Map[rh_detid].begin(),
366  detIdToCaloParticleId_Map[rh_detid].end(),
367  hgcal::detIdInfoInCluster{cpPair.first, 0.f});
368  if (findHitIt != detIdToCaloParticleId_Map[rh_detid].end())
369  cpFraction = findHitIt->fraction;
370  }
371  cpPair.second +=
372  (rhFraction - cpFraction) * (rhFraction - cpFraction) * hitEnergyWeight * invLayerClusterEnergyWeight;
373  }
374  } // End of loop over Hits within a LayerCluster
375 #ifdef EDM_ML_DEBUG
376  if (cpsInLayerCluster[lcId].empty())
377  LogDebug("LCToCPAssociatorByEnergyScoreImpl") << "layerCluster Id: \t" << lcId << "\tCP id:\t-1 "
378  << "\t score \t-1\n";
379 #endif
380  } // End of loop over LayerClusters
381 
382  // Compute the CaloParticle-To-LayerCluster score
383  for (const auto& cpId : cPIndices) {
384  for (unsigned int layerId = 0; layerId < layers_ * 2; ++layerId) {
385  unsigned int CPNumberOfHits = cPOnLayer[cpId][layerId].hits_and_fractions.size();
386  if (CPNumberOfHits == 0)
387  continue;
388 #ifdef EDM_ML_DEBUG
389  int lcWithMaxEnergyInCP = -1;
390  float maxEnergyLCinCP = 0.f;
391  float CPenergy = cPOnLayer[cpId][layerId].energy;
392  float CPEnergyFractionInLC = 0.f;
393  for (auto& lc : cPOnLayer[cpId][layerId].layerClusterIdToEnergyAndScore) {
394  if (lc.second.first > maxEnergyLCinCP) {
395  maxEnergyLCinCP = lc.second.first;
396  lcWithMaxEnergyInCP = lc.first;
397  }
398  }
399  if (CPenergy > 0.f)
400  CPEnergyFractionInLC = maxEnergyLCinCP / CPenergy;
401 
402  LogDebug("LCToCPAssociatorByEnergyScoreImpl")
403  << std::setw(8) << "LayerId:\t" << std::setw(12) << "caloparticle\t" << std::setw(15) << "cp total energy\t"
404  << std::setw(15) << "cpEnergyOnLayer\t" << std::setw(14) << "CPNhitsOnLayer\t" << std::setw(18)
405  << "lcWithMaxEnergyInCP\t" << std::setw(15) << "maxEnergyLCinCP\t" << std::setw(20) << "CPEnergyFractionInLC"
406  << "\n";
407  LogDebug("LCToCPAssociatorByEnergyScoreImpl")
408  << std::setw(8) << layerId << "\t" << std::setw(12) << cpId << "\t" << std::setw(15)
409  << caloParticles[cpId].energy() << "\t" << std::setw(15) << CPenergy << "\t" << std::setw(14)
410  << CPNumberOfHits << "\t" << std::setw(18) << lcWithMaxEnergyInCP << "\t" << std::setw(15) << maxEnergyLCinCP
411  << "\t" << std::setw(20) << CPEnergyFractionInLC << "\n";
412 #endif
413  // Compute the correct normalization
414  float invCPEnergyWeight = 0.f;
415  for (auto const& haf : cPOnLayer[cpId][layerId].hits_and_fractions) {
416  invCPEnergyWeight += std::pow(haf.second * hitMap_->at(haf.first)->energy(), 2);
417  }
418  invCPEnergyWeight = 1.f / invCPEnergyWeight;
419  for (unsigned int i = 0; i < CPNumberOfHits; ++i) {
420  auto& cp_hitDetId = cPOnLayer[cpId][layerId].hits_and_fractions[i].first;
421  auto& cpFraction = cPOnLayer[cpId][layerId].hits_and_fractions[i].second;
422 
423  bool hitWithNoLC = false;
424  if (cpFraction == 0.f)
425  continue; //hopefully this should never happen
426  auto hit_find_in_LC = detIdToLayerClusterId_Map.find(cp_hitDetId);
427  if (hit_find_in_LC == detIdToLayerClusterId_Map.end())
428  hitWithNoLC = true;
429  auto itcheck = hitMap_->find(cp_hitDetId);
430  const HGCRecHit* hit = itcheck->second;
431  float hitEnergyWeight = hit->energy() * hit->energy();
432  for (auto& lcPair : cPOnLayer[cpId][layerId].layerClusterIdToEnergyAndScore) {
433  unsigned int layerClusterId = lcPair.first;
434  float lcFraction = 0.f;
435 
436  if (!hitWithNoLC) {
437  auto findHitIt = std::find(detIdToLayerClusterId_Map[cp_hitDetId].begin(),
438  detIdToLayerClusterId_Map[cp_hitDetId].end(),
439  hgcal::detIdInfoInCluster{layerClusterId, 0.f});
440  if (findHitIt != detIdToLayerClusterId_Map[cp_hitDetId].end())
441  lcFraction = findHitIt->fraction;
442  }
443  lcPair.second.second +=
444  (lcFraction - cpFraction) * (lcFraction - cpFraction) * hitEnergyWeight * invCPEnergyWeight;
445 #ifdef EDM_ML_DEBUG
446  LogDebug("LCToCPAssociatorByEnergyScoreImpl")
447  << "cpDetId:\t" << (uint32_t)cp_hitDetId << "\tlayerClusterId:\t" << layerClusterId << "\t"
448  << "lcfraction,cpfraction:\t" << lcFraction << ", " << cpFraction << "\t"
449  << "hitEnergyWeight:\t" << hitEnergyWeight << "\t"
450  << "current score:\t" << lcPair.second.second << "\t"
451  << "invCPEnergyWeight:\t" << invCPEnergyWeight << "\n";
452 #endif
453  } // End of loop over LayerClusters linked to hits of this CaloParticle
454  } // End of loop over hits of CaloParticle on a Layer
455 #ifdef EDM_ML_DEBUG
456  if (cPOnLayer[cpId][layerId].layerClusterIdToEnergyAndScore.empty())
457  LogDebug("LCToCPAssociatorByEnergyScoreImpl") << "CP Id: \t" << cpId << "\tLC id:\t-1 "
458  << "\t score \t-1\n";
459 
460  for (const auto& lcPair : cPOnLayer[cpId][layerId].layerClusterIdToEnergyAndScore) {
461  LogDebug("LCToCPAssociatorByEnergyScoreImpl")
462  << "CP Id: \t" << cpId << "\t LC id: \t" << lcPair.first << "\t score \t" << lcPair.second.second
463  << "\t shared energy:\t" << lcPair.second.first << "\t shared energy fraction:\t"
464  << (lcPair.second.first / CPenergy) << "\n";
465  }
466 #endif
467  }
468  }
469  return {cpsInLayerCluster, cPOnLayer};
470 }

References c, caloTruthCellsProducer_cfi::caloParticles, bsc_activity_cfg::clusters, CommonMethods::cp(), relativeConstraints::empty, mps_fire::end, HCALHighEnergyHPDFilter_cfi::energy, f, spr::find(), cms::cuda::for(), newFWLiteAna::found, hardScatterOnly_, hitMap_, SimCluster::hits_and_fractions(), mps_fire::i, dqmiolumiharvest::j, dqmdumpme::last, layers_, LogDebug, funct::pow(), edm::Handle< T >::product(), recHitTools_, removeCPFromPU(), jetUpdater_cfi::sort, tier0::unique(), and findQualityFiles::v.

Referenced by associateRecoToSim(), and associateSimToReco().

Member Data Documentation

◆ hardScatterOnly_

const bool LCToCPAssociatorByEnergyScoreImpl::hardScatterOnly_
private

Definition at line 61 of file LCToCPAssociatorByEnergyScoreImpl.h.

Referenced by makeConnections().

◆ hitMap_

const std::unordered_map<DetId, const HGCRecHit *>* LCToCPAssociatorByEnergyScoreImpl::hitMap_
private

Definition at line 63 of file LCToCPAssociatorByEnergyScoreImpl.h.

Referenced by makeConnections().

◆ layers_

unsigned LCToCPAssociatorByEnergyScoreImpl::layers_
private

◆ productGetter_

const edm::EDProductGetter* LCToCPAssociatorByEnergyScoreImpl::productGetter_
private

Definition at line 65 of file LCToCPAssociatorByEnergyScoreImpl.h.

Referenced by associateRecoToSim(), and associateSimToReco().

◆ recHitTools_

std::shared_ptr<hgcal::RecHitTools> LCToCPAssociatorByEnergyScoreImpl::recHitTools_
private
mps_fire.i
i
Definition: mps_fire.py:428
edm::Handle::product
T const * product() const
Definition: Handle.h:70
f
double f[11][100]
Definition: MuScleFitUtils.cc:78
hgcal_conditions::parameters
Definition: HGCConditions.h:86
edm::RefVector< SimClusterCollection >
SimCluster
Monte Carlo truth information used for tracking validation.
Definition: SimCluster.h:29
findQualityFiles.v
v
Definition: findQualityFiles.py:179
LCToCPAssociatorByEnergyScoreImpl::makeConnections
hgcal::association makeConnections(const edm::Handle< reco::CaloClusterCollection > &cCH, const edm::Handle< CaloParticleCollection > &cPCH) const
Definition: LCToCPAssociatorByEnergyScoreImpl.cc:21
spr::find
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
newFWLiteAna.found
found
Definition: newFWLiteAna.py:118
edm::Ref
Definition: AssociativeIterator.h:58
DetId
Definition: DetId.h:17
dqmdumpme.last
last
Definition: dqmdumpme.py:56
LCToCPAssociatorByEnergyScoreImpl::recHitTools_
std::shared_ptr< hgcal::RecHitTools > recHitTools_
Definition: LCToCPAssociatorByEnergyScoreImpl.h:62
caloTruthCellsProducer_cfi.caloParticles
caloParticles
Definition: caloTruthCellsProducer_cfi.py:6
mps_fire.end
end
Definition: mps_fire.py:242
removeCPFromPU
static void removeCPFromPU(const std::vector< CaloParticle > &caloParticles, std::vector< size_t > &cPIndices, bool hardScatterOnly=true)
Definition: AssociatorTools.h:7
HCALHighEnergyHPDFilter_cfi.energy
energy
Definition: HCALHighEnergyHPDFilter_cfi.py:5
h
HGCRecHit
Definition: HGCRecHit.h:14
bsc_activity_cfg.clusters
clusters
Definition: bsc_activity_cfg.py:36
LogDebug
#define LogDebug(id)
Definition: MessageLogger.h:233
hgcal::detIdInfoInCluster
Definition: LCToCPAssociatorByEnergyScoreImpl.h:18
edm::AssociationMap
Definition: AssociationMap.h:48
jetUpdater_cfi.sort
sort
Definition: jetUpdater_cfi.py:29
edm::refcoreimpl::productGetter
EDProductGetter const * productGetter(std::atomic< void const * > const &iCache)
Definition: refcore_implementation.h:72
LCToCPAssociatorByEnergyScoreImpl::productGetter_
const edm::EDProductGetter * productGetter_
Definition: LCToCPAssociatorByEnergyScoreImpl.h:65
cms::cuda::for
for(int i=first, nt=offsets[nh];i< nt;i+=gridDim.x *blockDim.x)
Definition: HistoContainer.h:15
LCToCPAssociatorByEnergyScoreImpl::hardScatterOnly_
const bool hardScatterOnly_
Definition: LCToCPAssociatorByEnergyScoreImpl.h:61
tier0.unique
def unique(seq, keepstr=True)
Definition: tier0.py:24
relativeConstraints.empty
bool empty
Definition: relativeConstraints.py:46
electronStore.links
links
Definition: electronStore.py:149
hgcal::caloParticleToLayerCluster
std::vector< std::vector< hgcal::caloParticleOnLayer > > caloParticleToLayerCluster
Definition: LCToCPAssociatorByEnergyScoreImpl.h:43
SimCluster::hits_and_fractions
std::vector< std::pair< uint32_t, float > > hits_and_fractions() const
Returns list of rechit IDs and fractions for this SimCluster.
Definition: SimCluster.h:184
funct::pow
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
LCToCPAssociatorByEnergyScoreImpl::hitMap_
const std::unordered_map< DetId, const HGCRecHit * > * hitMap_
Definition: LCToCPAssociatorByEnergyScoreImpl.h:63
c
auto & c
Definition: CAHitNtupletGeneratorKernelsImpl.h:56
dqmiolumiharvest.j
j
Definition: dqmiolumiharvest.py:66
CommonMethods.cp
def cp(fromDir, toDir, listOfFiles, overwrite=False, smallList=False)
Definition: CommonMethods.py:191
hit
Definition: SiStripHitEffFromCalibTree.cc:88
hgcal::layerClusterToCaloParticle
std::vector< std::vector< std::pair< unsigned int, float > > > layerClusterToCaloParticle
Definition: LCToCPAssociatorByEnergyScoreImpl.h:42
LCToCPAssociatorByEnergyScoreImpl::layers_
unsigned layers_
Definition: LCToCPAssociatorByEnergyScoreImpl.h:64