CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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_
 
edm::EDProductGetter const * productGetter_
 
std::shared_ptr
< hgcal::RecHitTools
recHitTools_
 

Detailed Description

Definition at line 65 of file LCToCPAssociatorByEnergyScoreImpl.h.

Constructor & Destructor Documentation

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.

References layers_, and recHitTools_.

17  : hardScatterOnly_(hardScatterOnly), recHitTools_(recHitTools), hitMap_(hitMap), productGetter_(&productGetter) {
18  layers_ = recHitTools_->lastLayerBH();
19 }
EDProductGetter const * productGetter(std::atomic< void const * > const &iCache)
const std::unordered_map< DetId, const HGCRecHit * > * hitMap_
std::shared_ptr< hgcal::RecHitTools > recHitTools_

Member Function Documentation

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 479 of file LCToCPAssociatorByEnergyScoreImpl.cc.

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

480  {
482  const auto& links = makeConnections(cCCH, cPCH);
483 
484  const auto& cpsInLayerCluster = std::get<0>(links);
485  for (size_t lcId = 0; lcId < cpsInLayerCluster.size(); ++lcId) {
486  for (auto& cpPair : cpsInLayerCluster[lcId]) {
487  LogDebug("LCToCPAssociatorByEnergyScoreImpl")
488  << "layerCluster Id: \t" << lcId << "\t CP id: \t" << cpPair.first << "\t score \t" << cpPair.second << "\n";
489  // Fill AssociationMap
490  returnValue.insert(edm::Ref<reco::CaloClusterCollection>(cCCH, lcId), // Ref to LC
491  std::make_pair(edm::Ref<CaloParticleCollection>(cPCH, cpPair.first),
492  cpPair.second) // Pair <Ref to CP, score>
493  );
494  }
495  }
496  return returnValue;
497 }
hgcal::association makeConnections(const edm::Handle< reco::CaloClusterCollection > &cCH, const edm::Handle< CaloParticleCollection > &cPCH) const
#define LogDebug(id)
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 499 of file LCToCPAssociatorByEnergyScoreImpl.cc.

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

500  {
502  const auto& links = makeConnections(cCCH, cPCH);
503  const auto& cPOnLayer = std::get<1>(links);
504  for (size_t cpId = 0; cpId < cPOnLayer.size(); ++cpId) {
505  for (size_t layerId = 0; layerId < cPOnLayer[cpId].size(); ++layerId) {
506  for (auto& lcPair : cPOnLayer[cpId][layerId].layerClusterIdToEnergyAndScore) {
507  returnValue.insert(
508  edm::Ref<CaloParticleCollection>(cPCH, cpId), // Ref to CP
509  std::make_pair(edm::Ref<reco::CaloClusterCollection>(cCCH, lcPair.first), // Pair <Ref to LC,
510  std::make_pair(lcPair.second.first, lcPair.second.second)) // pair <energy, score> >
511  );
512  }
513  }
514  }
515  return returnValue;
516 }
hgcal::association makeConnections(const edm::Handle< reco::CaloClusterCollection > &cCH, const edm::Handle< CaloParticleCollection > &cPCH) const
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.

References SplitLinear::begin, c, caloTruthProducer_cfi::caloParticles, HLT_FULL_cff::clusters, CommonMethods::cp(), relativeConstraints::empty, dataset::end, relval_parameters_module::energy, CaloRecHit::energy(), validate-o2o-wbm::f, spr::find(), for(), newFWLiteAna::found, h, hardScatterOnly_, hitMap_, SimCluster::hits_and_fractions(), mps_fire::i, dqmiolumiharvest::j, dqmdumpme::last, layers_, LogDebug, SiStripPI::min, funct::pow(), edm::Handle< T >::product(), recHitTools_, removeCPFromPU(), tier0::unique(), and findQualityFiles::v.

Referenced by associateRecoToSim(), and associateSimToReco().

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

Member Data Documentation

const bool LCToCPAssociatorByEnergyScoreImpl::hardScatterOnly_
private

Definition at line 79 of file LCToCPAssociatorByEnergyScoreImpl.h.

Referenced by makeConnections().

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

Definition at line 81 of file LCToCPAssociatorByEnergyScoreImpl.h.

Referenced by makeConnections().

unsigned LCToCPAssociatorByEnergyScoreImpl::layers_
private
edm::EDProductGetter const* LCToCPAssociatorByEnergyScoreImpl::productGetter_
private

Definition at line 83 of file LCToCPAssociatorByEnergyScoreImpl.h.

Referenced by associateRecoToSim(), and associateSimToReco().

std::shared_ptr<hgcal::RecHitTools> LCToCPAssociatorByEnergyScoreImpl::recHitTools_
private