CMS 3D CMS Logo

List of all members | Public Member Functions | Private Member Functions | Private Attributes
LCToCPAssociatorByEnergyScoreImpl< HIT > Class Template Reference

#include <LCToCPAssociatorByEnergyScoreImpl.h>

Inheritance diagram for LCToCPAssociatorByEnergyScoreImpl< HIT >:
ticl::LayerClusterToCaloParticleAssociatorBaseImpl

Public Member Functions

ticl::RecoToSimCollection associateRecoToSim (const edm::Handle< reco::CaloClusterCollection > &cCH, const edm::Handle< CaloParticleCollection > &cPCH) const override
 Associate a LayerCluster to CaloParticles. More...
 
ticl::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 unsigned int > *, const std::vector< const HIT *> &hits)
 
- Public Member Functions inherited from ticl::LayerClusterToCaloParticleAssociatorBaseImpl
 LayerClusterToCaloParticleAssociatorBaseImpl ()
 Constructor. More...
 
virtual ~LayerClusterToCaloParticleAssociatorBaseImpl ()
 Destructor. More...
 

Private Member Functions

ticl::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 unsigned int > * hitMap_
 
std::vector< const HIT * > hits_
 
unsigned layers_
 
edm::EDProductGetter const * productGetter_
 
std::shared_ptr< hgcal::RecHitToolsrecHitTools_
 

Detailed Description

template<typename HIT>
class LCToCPAssociatorByEnergyScoreImpl< HIT >

Definition at line 68 of file LCToCPAssociatorByEnergyScoreImpl.h.

Constructor & Destructor Documentation

◆ LCToCPAssociatorByEnergyScoreImpl()

template<typename HIT >
LCToCPAssociatorByEnergyScoreImpl< HIT >::LCToCPAssociatorByEnergyScoreImpl ( edm::EDProductGetter const &  productGetter,
bool  hardScatterOnly,
std::shared_ptr< hgcal::RecHitTools recHitTools,
const std::unordered_map< DetId, const unsigned int > *  hitMap,
const std::vector< const HIT *> &  hits 
)
explicit

Definition at line 14 of file LCToCPAssociatorByEnergyScoreImpl.cc.

References ALPAKA_ACCELERATOR_NAMESPACE::brokenline::constexpr(), LCToCPAssociatorByEnergyScoreImpl< HIT >::layers_, and LCToCPAssociatorByEnergyScoreImpl< HIT >::recHitTools_.

20  : hardScatterOnly_(hardScatterOnly),
21  recHitTools_(recHitTools),
22  hitMap_(hitMap),
24  hits_(hits) {
25  if constexpr (std::is_same_v<HIT, HGCRecHit>)
26  layers_ = recHitTools_->lastLayerBH();
27  else
28  layers_ = 6;
29 }
const std::unordered_map< DetId, const unsigned int > * hitMap_
EDProductGetter const * productGetter(std::atomic< void const *> const &iCache)
std::shared_ptr< hgcal::RecHitTools > recHitTools_

Member Function Documentation

◆ associateRecoToSim()

template<typename HIT >
ticl::RecoToSimCollection LCToCPAssociatorByEnergyScoreImpl< HIT >::associateRecoToSim ( const edm::Handle< reco::CaloClusterCollection > &  cCH,
const edm::Handle< CaloParticleCollection > &  cPCH 
) const
overridevirtual

Associate a LayerCluster to CaloParticles.

Reimplemented from ticl::LayerClusterToCaloParticleAssociatorBaseImpl.

Definition at line 499 of file LCToCPAssociatorByEnergyScoreImpl.cc.

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

500  {
502  const auto& links = makeConnections(cCCH, cPCH);
503 
504  const auto& cpsInLayerCluster = std::get<0>(links);
505  for (size_t lcId = 0; lcId < cpsInLayerCluster.size(); ++lcId) {
506  for (auto& cpPair : cpsInLayerCluster[lcId]) {
507  LogDebug("LCToCPAssociatorByEnergyScoreImpl")
508  << "layerCluster Id: \t" << lcId << "\t CP id: \t" << cpPair.first << "\t score \t" << cpPair.second << "\n";
509  // Fill AssociationMap
510  returnValue.insert(edm::Ref<reco::CaloClusterCollection>(cCCH, lcId), // Ref to LC
511  std::make_pair(edm::Ref<CaloParticleCollection>(cPCH, cpPair.first),
512  cpPair.second) // Pair <Ref to CP, score>
513  );
514  }
515  }
516  return returnValue;
517 }
ticl::association makeConnections(const edm::Handle< reco::CaloClusterCollection > &cCH, const edm::Handle< CaloParticleCollection > &cPCH) const
#define LogDebug(id)

◆ associateSimToReco()

template<typename HIT >
ticl::SimToRecoCollection LCToCPAssociatorByEnergyScoreImpl< HIT >::associateSimToReco ( const edm::Handle< reco::CaloClusterCollection > &  cCH,
const edm::Handle< CaloParticleCollection > &  cPCH 
) const
overridevirtual

Associate a CaloParticle to LayerClusters.

Reimplemented from ticl::LayerClusterToCaloParticleAssociatorBaseImpl.

Definition at line 520 of file LCToCPAssociatorByEnergyScoreImpl.cc.

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

521  {
523  const auto& links = makeConnections(cCCH, cPCH);
524  const auto& cPOnLayer = std::get<1>(links);
525  for (size_t cpId = 0; cpId < cPOnLayer.size(); ++cpId) {
526  for (size_t layerId = 0; layerId < cPOnLayer[cpId].size(); ++layerId) {
527  for (auto& lcPair : cPOnLayer[cpId][layerId].layerClusterIdToEnergyAndScore) {
528  returnValue.insert(
529  edm::Ref<CaloParticleCollection>(cPCH, cpId), // Ref to CP
530  std::make_pair(edm::Ref<reco::CaloClusterCollection>(cCCH, lcPair.first), // Pair <Ref to LC,
531  std::make_pair(lcPair.second.first, lcPair.second.second)) // pair <energy, score> >
532  );
533  }
534  }
535  }
536  return returnValue;
537 }
ticl::association makeConnections(const edm::Handle< reco::CaloClusterCollection > &cCH, const edm::Handle< CaloParticleCollection > &cPCH) const

◆ makeConnections()

template<typename HIT >
ticl::association LCToCPAssociatorByEnergyScoreImpl< HIT >::makeConnections ( const edm::Handle< reco::CaloClusterCollection > &  cCH,
const edm::Handle< CaloParticleCollection > &  cPCH 
) const
private

Definition at line 32 of file LCToCPAssociatorByEnergyScoreImpl.cc.

References SimCluster::barrel_hits_and_fractions(), DummyCfis::c, caloTruthCellsProducer_cfi::caloParticles, bsc_activity_cfg::clusters, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::constexpr(), CommonMethods::cp(), relativeConstraints::empty, mps_fire::end, SimCluster::endcap_hits_and_fractions(), hcalRecHitTable_cff::energy, f, spr::find(), newFWLiteAna::found, h, mps_fire::i, dqmiolumiharvest::j, dqmdumpme::last, LogDebug, SiStripPI::min, funct::pow(), edm::Handle< T >::product(), removeCPFromPU(), jetUpdater_cfi::sort, tier0::unique(), and findQualityFiles::v.

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

Member Data Documentation

◆ hardScatterOnly_

template<typename HIT >
const bool LCToCPAssociatorByEnergyScoreImpl< HIT >::hardScatterOnly_
private

Definition at line 83 of file LCToCPAssociatorByEnergyScoreImpl.h.

◆ hitMap_

template<typename HIT >
const std::unordered_map<DetId, const unsigned int>* LCToCPAssociatorByEnergyScoreImpl< HIT >::hitMap_
private

Definition at line 85 of file LCToCPAssociatorByEnergyScoreImpl.h.

◆ hits_

template<typename HIT >
std::vector<const HIT *> LCToCPAssociatorByEnergyScoreImpl< HIT >::hits_
private

Definition at line 90 of file LCToCPAssociatorByEnergyScoreImpl.h.

◆ layers_

template<typename HIT >
unsigned LCToCPAssociatorByEnergyScoreImpl< HIT >::layers_
private

◆ productGetter_

template<typename HIT >
edm::EDProductGetter const* LCToCPAssociatorByEnergyScoreImpl< HIT >::productGetter_
private

Definition at line 87 of file LCToCPAssociatorByEnergyScoreImpl.h.

◆ recHitTools_

template<typename HIT >
std::shared_ptr<hgcal::RecHitTools> LCToCPAssociatorByEnergyScoreImpl< HIT >::recHitTools_
private