25 const auto& mClusters = *mCCH.
product();
27 auto nMultiClusters = mClusters.size();
29 std::vector<size_t> cPIndices;
33 auto nCaloParticles = cPIndices.size();
35 std::vector<size_t> cPSelectedIndices;
46 cPOnLayer.resize(nCaloParticles);
47 for (
unsigned int i = 0;
i < nCaloParticles; ++
i) {
48 auto cpIndex = cPIndices[
i];
49 cPOnLayer[cpIndex].resize(
layers_ * 2);
50 for (
unsigned int j = 0;
j <
layers_ * 2; ++
j) {
51 cPOnLayer[cpIndex][
j].caloParticleId = cpIndex;
52 cPOnLayer[cpIndex][
j].energy = 0.f;
53 cPOnLayer[cpIndex][
j].hits_and_fractions.clear();
57 std::unordered_map<DetId, std::vector<hgcal::detIdInfoInCluster>> detIdToCaloParticleId_Map;
59 for (
const auto& cpId : cPIndices) {
63 for (
const auto& it_sc : simClusterRefVector) {
66 for (
const auto& it_haf : hits_and_fractions) {
67 const auto hitid = (it_haf.first);
68 const auto cpLayerId =
70 const auto itcheck =
hitMap_->find(hitid);
71 if (itcheck !=
hitMap_->end()) {
79 auto hit_find_it = detIdToCaloParticleId_Map.find(hitid);
80 if (hit_find_it == detIdToCaloParticleId_Map.end()) {
81 detIdToCaloParticleId_Map[hitid] = std::vector<hgcal::detIdInfoInCluster>();
82 detIdToCaloParticleId_Map[hitid].emplace_back(cpId, it_haf.second);
84 auto findHitIt =
std::find(detIdToCaloParticleId_Map[hitid].
begin(),
85 detIdToCaloParticleId_Map[hitid].
end(),
87 if (findHitIt != detIdToCaloParticleId_Map[hitid].
end()) {
88 findHitIt->fraction += it_haf.second;
90 detIdToCaloParticleId_Map[hitid].emplace_back(cpId, it_haf.second);
97 cPOnLayer[cpId][cpLayerId].energy += it_haf.second * hit->
energy();
104 auto& haf = cPOnLayer[cpId][cpLayerId].hits_and_fractions;
105 auto found = std::find_if(
106 std::begin(haf),
std::end(haf), [&hitid](
const std::pair<DetId, float>&
v) {
return v.first == hitid; });
107 if (
found != haf.end()) {
108 found->second += it_haf.second;
110 cPOnLayer[cpId][cpLayerId].hits_and_fractions.emplace_back(hitid, it_haf.second);
118 LogDebug(
"MultiClusterAssociatorByEnergyScoreImpl") <<
"cPOnLayer INFO" << std::endl;
119 for (
size_t cp = 0;
cp < cPOnLayer.size(); ++
cp) {
120 LogDebug(
"MultiClusterAssociatorByEnergyScoreImpl") <<
"For CaloParticle Idx: " <<
cp <<
" we have: " << std::endl;
121 for (
size_t cpp = 0; cpp < cPOnLayer[
cp].size(); ++cpp) {
122 LogDebug(
"MultiClusterAssociatorByEnergyScoreImpl") <<
" On Layer: " << cpp <<
" we have:" << std::endl;
123 LogDebug(
"MultiClusterAssociatorByEnergyScoreImpl")
124 <<
" CaloParticleIdx: " << cPOnLayer[
cp][cpp].caloParticleId << std::endl;
125 LogDebug(
"MultiClusterAssociatorByEnergyScoreImpl")
126 <<
" Energy: " << cPOnLayer[
cp][cpp].energy << std::endl;
127 double tot_energy = 0.;
128 for (
auto const& haf : cPOnLayer[
cp][cpp].hits_and_fractions) {
129 LogDebug(
"MultiClusterAssociatorByEnergyScoreImpl")
130 <<
" Hits/fraction/energy: " << (uint32_t)haf.first <<
"/" << haf.second <<
"/"
131 << haf.second *
hitMap_->at(haf.first)->energy() << std::endl;
132 tot_energy += haf.second *
hitMap_->at(haf.first)->energy();
134 LogDebug(
"MultiClusterAssociatorByEnergyScoreImpl") <<
" Tot Sum haf: " << tot_energy << std::endl;
135 for (
auto const& mc : cPOnLayer[
cp][cpp].multiClusterIdToEnergyAndScore) {
136 LogDebug(
"MultiClusterAssociatorByEnergyScoreImpl") <<
" mcIdx/energy/score: " << mc.first <<
"/"
137 << mc.second.first <<
"/" << mc.second.second << std::endl;
142 LogDebug(
"MultiClusterAssociatorByEnergyScoreImpl") <<
"detIdToCaloParticleId_Map INFO" << std::endl;
143 for (
auto const&
cp : detIdToCaloParticleId_Map) {
144 LogDebug(
"MultiClusterAssociatorByEnergyScoreImpl")
145 <<
"For detId: " << (uint32_t)
cp.first
146 <<
" we have found the following connections with CaloParticles:" << std::endl;
147 for (
auto const& cpp :
cp.second) {
148 LogDebug(
"MultiClusterAssociatorByEnergyScoreImpl")
149 <<
" CaloParticle Id: " << cpp.clusterId <<
" with fraction: " << cpp.fraction
150 <<
" and energy: " << cpp.fraction *
hitMap_->at(
cp.first)->energy() << std::endl;
156 std::unordered_map<DetId, std::vector<hgcal::detIdInfoInMultiCluster>> detIdToMultiClusterId_Map;
162 cpsInMultiCluster.resize(nMultiClusters);
165 for (
unsigned int mcId = 0; mcId < nMultiClusters; ++mcId) {
166 const auto& hits_and_fractions = mClusters[mcId].hitsAndFractions();
167 if (!hits_and_fractions.empty()) {
168 std::unordered_map<unsigned, float> CPEnergyInMCL;
169 int maxCPId_byNumberOfHits = -1;
170 unsigned int maxCPNumberOfHitsInMCL = 0;
171 int maxCPId_byEnergy = -1;
172 float maxEnergySharedMCLandCP = 0.f;
173 float energyFractionOfMCLinCP = 0.f;
174 float energyFractionOfCPinMCL = 0.f;
181 std::unordered_map<unsigned, unsigned> occurrencesCPinMCL;
182 unsigned int numberOfNoiseHitsInMCL = 0;
183 unsigned int numberOfHaloHitsInMCL = 0;
184 unsigned int numberOfHitsInMCL = 0;
187 unsigned int numberOfHitsInLC = hits_and_fractions.size();
188 numberOfHitsInMCL += numberOfHitsInLC;
189 std::unordered_map<unsigned, float> CPEnergyInLC;
208 std::vector<int> hitsToCaloParticleId(numberOfHitsInLC);
211 const auto firstHitDetId = hits_and_fractions[0].first;
212 int lcLayerId =
recHitTools_->getLayerWithOffset(firstHitDetId) +
213 layers_ * ((
recHitTools_->zside(firstHitDetId) + 1) >> 1) - 1;
216 for (
unsigned int hitId = 0; hitId < numberOfHitsInLC; hitId++) {
217 const auto rh_detid = hits_and_fractions[hitId].first;
218 const auto rhFraction = hits_and_fractions[hitId].second;
221 const auto itcheck =
hitMap_->find(rh_detid);
222 const auto hit = itcheck->second;
231 auto hit_find_in_LC = detIdToMultiClusterId_Map.find(rh_detid);
232 if (hit_find_in_LC == detIdToMultiClusterId_Map.end()) {
233 detIdToMultiClusterId_Map[rh_detid] = std::vector<hgcal::detIdInfoInMultiCluster>();
238 auto hit_find_in_CP = detIdToCaloParticleId_Map.find(rh_detid);
243 if (rhFraction == 0.) {
244 hitsToCaloParticleId[hitId] = -2;
245 numberOfHaloHitsInMCL++;
247 if (hit_find_in_CP == detIdToCaloParticleId_Map.end()) {
248 hitsToCaloParticleId[hitId] -= 1;
250 auto maxCPEnergyInLC = 0.f;
252 for (
auto&
h : hit_find_in_CP->second) {
253 auto shared_fraction =
std::min(rhFraction,
h.fraction);
258 CPEnergyInMCL[
h.clusterId] += shared_fraction * hit->
energy();
260 CPEnergyInLC[
h.clusterId] += shared_fraction * hit->
energy();
263 cPOnLayer[
h.clusterId][lcLayerId].multiClusterIdToEnergyAndScore[mcId].first +=
264 shared_fraction * hit->
energy();
265 cPOnLayer[
h.clusterId][lcLayerId].multiClusterIdToEnergyAndScore[mcId].second = FLT_MAX;
268 cpsInMultiCluster[mcId].emplace_back(
h.clusterId, FLT_MAX);
271 if (shared_fraction > maxCPEnergyInLC) {
273 maxCPEnergyInLC = CPEnergyInLC[
h.clusterId];
274 maxCPId =
h.clusterId;
278 hitsToCaloParticleId[hitId] = maxCPId;
285 for (
auto c : hitsToCaloParticleId) {
287 numberOfNoiseHitsInMCL++;
289 occurrencesCPinMCL[
c]++;
295 for (
auto&
c : occurrencesCPinMCL) {
296 if (
c.second > maxCPNumberOfHitsInMCL) {
297 maxCPId_byNumberOfHits =
c.first;
298 maxCPNumberOfHitsInMCL =
c.second;
303 for (
auto&
c : CPEnergyInMCL) {
304 if (
c.second > maxEnergySharedMCLandCP) {
305 maxCPId_byEnergy =
c.first;
306 maxEnergySharedMCLandCP =
c.second;
310 float totalCPEnergyFromLayerCP = 0.f;
311 if (maxCPId_byEnergy >= 0) {
313 for (
unsigned int j = 0;
j < layers_ * 2; ++
j) {
314 totalCPEnergyFromLayerCP = totalCPEnergyFromLayerCP + cPOnLayer[maxCPId_byEnergy][
j].energy;
316 energyFractionOfCPinMCL = maxEnergySharedMCLandCP / totalCPEnergyFromLayerCP;
317 if (mClusters[mcId].
energy() > 0.
f) {
318 energyFractionOfMCLinCP = maxEnergySharedMCLandCP / mClusters[mcId].energy();
322 LogDebug(
"MultiClusterAssociatorByEnergyScoreImpl") << std::setw(12) <<
"multiCluster"
323 <<
"\t" << std::setw(10) <<
"mulcl energy"
324 <<
"\t" << std::setw(5) <<
"nhits"
325 <<
"\t" << std::setw(12) <<
"noise hits"
326 <<
"\t" << std::setw(22) <<
"maxCPId_byNumberOfHits"
327 <<
"\t" << std::setw(8) <<
"nhitsCP"
328 <<
"\t" << std::setw(16) <<
"maxCPId_byEnergy"
329 <<
"\t" << std::setw(23) <<
"maxEnergySharedMCLandCP"
330 <<
"\t" << std::setw(22) <<
"totalCPEnergyFromAllLayerCP"
331 <<
"\t" << std::setw(22) <<
"energyFractionOfMCLinCP"
332 <<
"\t" << std::setw(25) <<
"energyFractionOfCPinMCL"
333 <<
"\t" << std::endl;
334 LogDebug(
"MultiClusterAssociatorByEnergyScoreImpl")
335 << std::setw(12) << mcId <<
"\t" << std::setw(10) << mClusters[mcId].energy() <<
"\t" << std::setw(5)
336 << numberOfHitsInMCL <<
"\t" << std::setw(12) << numberOfNoiseHitsInMCL <<
"\t" << std::setw(22)
337 << maxCPId_byNumberOfHits <<
"\t" << std::setw(8) << maxCPNumberOfHitsInMCL <<
"\t" << std::setw(16)
338 << maxCPId_byEnergy <<
"\t" << std::setw(23) << maxEnergySharedMCLandCP <<
"\t" << std::setw(22)
339 << totalCPEnergyFromLayerCP <<
"\t" << std::setw(22) << energyFractionOfMCLinCP <<
"\t" << std::setw(25)
340 << energyFractionOfCPinMCL << std::endl;
346 for (
unsigned int mcId = 0; mcId < nMultiClusters; ++mcId) {
348 std::sort(cpsInMultiCluster[mcId].
begin(), cpsInMultiCluster[mcId].
end());
350 cpsInMultiCluster[mcId].erase(
last, cpsInMultiCluster[mcId].
end());
352 const auto& hits_and_fractions = mClusters[mcId].hitsAndFractions();
353 unsigned int numberOfHitsInLC = hits_and_fractions.size();
354 if (numberOfHitsInLC > 0) {
355 if (mClusters[mcId].
energy() == 0. && !cpsInMultiCluster[mcId].
empty()) {
357 for (
auto& cpPair : cpsInMultiCluster[mcId]) {
360 LogDebug(
"MultiClusterAssociatorByEnergyScoreImpl")
361 <<
"multiClusterId : \t " << mcId <<
"\t CP id : \t" << cpPair.first <<
"\t score \t " << cpPair.second
368 float invMultiClusterEnergyWeight = 0.f;
369 for (
auto const& haf : mClusters[mcId].hitsAndFractions()) {
370 invMultiClusterEnergyWeight +=
371 (haf.second *
hitMap_->at(haf.first)->energy()) * (haf.second *
hitMap_->at(haf.first)->energy());
373 invMultiClusterEnergyWeight = 1.f / invMultiClusterEnergyWeight;
375 for (
unsigned int i = 0;
i < numberOfHitsInLC; ++
i) {
376 DetId rh_detid = hits_and_fractions[
i].first;
377 float rhFraction = hits_and_fractions[
i].second;
379 bool hitWithNoCP = (detIdToCaloParticleId_Map.find(rh_detid) == detIdToCaloParticleId_Map.end());
381 auto itcheck =
hitMap_->find(rh_detid);
385 for (
auto& cpPair : cpsInMultiCluster[mcId]) {
386 unsigned int multiClusterId = cpPair.first;
387 float cpFraction = 0.f;
389 auto findHitIt =
std::find(detIdToCaloParticleId_Map[rh_detid].
begin(),
390 detIdToCaloParticleId_Map[rh_detid].
end(),
392 if (findHitIt != detIdToCaloParticleId_Map[rh_detid].
end())
393 cpFraction = findHitIt->fraction;
395 if (cpPair.second == FLT_MAX) {
399 (rhFraction - cpFraction) * (rhFraction - cpFraction) * hitEnergyWeight * invMultiClusterEnergyWeight;
404 if (cpsInMultiCluster[mcId].
empty())
405 LogDebug(
"MultiClusterAssociatorByEnergyScoreImpl") <<
"multiCluster Id: \t" << mcId <<
"\tCP id:\t-1 "
413 for (
const auto& cpId : cPSelectedIndices) {
414 for (
unsigned int layerId = 0; layerId < layers_ * 2; ++layerId) {
415 unsigned int CPNumberOfHits = cPOnLayer[cpId][layerId].hits_and_fractions.size();
416 if (CPNumberOfHits == 0)
419 int mcWithMaxEnergyInCP = -1;
420 float maxEnergyMCLperlayerinCP = 0.f;
421 float CPenergy = cPOnLayer[cpId][layerId].energy;
422 float CPEnergyFractionInMCLperlayer = 0.f;
423 for (
auto& mc : cPOnLayer[cpId][layerId].multiClusterIdToEnergyAndScore) {
424 if (mc.second.first > maxEnergyMCLperlayerinCP) {
425 maxEnergyMCLperlayerinCP = mc.second.first;
426 mcWithMaxEnergyInCP = mc.first;
430 CPEnergyFractionInMCLperlayer = maxEnergyMCLperlayerinCP / CPenergy;
432 LogDebug(
"MultiClusterAssociatorByEnergyScoreImpl")
433 << std::setw(8) <<
"LayerId:\t" << std::setw(12) <<
"caloparticle\t" << std::setw(15) <<
"cp total energy\t"
434 << std::setw(15) <<
"cpEnergyOnLayer\t" << std::setw(14) <<
"CPNhitsOnLayer\t" << std::setw(18)
435 <<
"mcWithMaxEnergyInCP\t" << std::setw(15) <<
"maxEnergyMCLinCP\t" << std::setw(20)
436 <<
"CPEnergyFractionInMCL"
438 LogDebug(
"MultiClusterAssociatorByEnergyScoreImpl")
439 << std::setw(8) << layerId <<
"\t" << std::setw(12) << cpId <<
"\t" << std::setw(15)
440 <<
caloParticles[cpId].energy() <<
"\t" << std::setw(15) << CPenergy <<
"\t" << std::setw(14)
441 << CPNumberOfHits <<
"\t" << std::setw(18) << mcWithMaxEnergyInCP <<
"\t" << std::setw(15)
442 << maxEnergyMCLperlayerinCP <<
"\t" << std::setw(20) << CPEnergyFractionInMCLperlayer <<
"\n";
445 for (
unsigned int i = 0;
i < CPNumberOfHits; ++
i) {
446 auto& cp_hitDetId = cPOnLayer[cpId][layerId].hits_and_fractions[
i].first;
447 auto& cpFraction = cPOnLayer[cpId][layerId].hits_and_fractions[
i].second;
449 bool hitWithNoMCL =
false;
450 if (cpFraction == 0.
f)
452 auto hit_find_in_MCL = detIdToMultiClusterId_Map.find(cp_hitDetId);
453 if (hit_find_in_MCL == detIdToMultiClusterId_Map.end())
455 auto itcheck =
hitMap_->find(cp_hitDetId);
458 for (
auto& mcPair : cPOnLayer[cpId][layerId].multiClusterIdToEnergyAndScore) {
459 unsigned int multiClusterId = mcPair.first;
460 float mcFraction = 0.f;
463 auto findHitIt =
std::find(detIdToMultiClusterId_Map[cp_hitDetId].
begin(),
464 detIdToMultiClusterId_Map[cp_hitDetId].
end(),
466 if (findHitIt != detIdToMultiClusterId_Map[cp_hitDetId].
end())
467 mcFraction = findHitIt->fraction;
471 if (mcPair.second.second == FLT_MAX) {
472 mcPair.second.second = 0.f;
474 mcPair.second.second += (mcFraction - cpFraction) * (mcFraction - cpFraction) * hitEnergyWeight;
476 LogDebug(
"HGCalValidator") <<
"multiClusterId:\t" << multiClusterId <<
"\tmcfraction,cpfraction:\t"
477 << mcFraction <<
", " << cpFraction <<
"\thitEnergyWeight:\t" << hitEnergyWeight
478 <<
"\tcurrent score numerator:\t" << mcPair.second.second <<
"\n";
483 if (cPOnLayer[cpId][layerId].multiClusterIdToEnergyAndScore.empty())
484 LogDebug(
"HGCalValidator") <<
"CP Id: \t" << cpId <<
"\t MCL id:\t-1 "
485 <<
"\t layer \t " << layerId <<
" Sub score in \t -1"
491 return {cpsInMultiCluster, cPOnLayer};
constexpr float energy() const
const edm::EventSetup & c
std::shared_ptr< hgcal::RecHitTools > recHitTools_
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
std::vector< std::vector< hgcal::caloParticleOnLayer > > caloParticleToMultiCluster
Monte Carlo truth information used for tracking validation.
for(Iditer=Id.begin();Iditer!=Id.end();Iditer++)
T const * product() const
const std::unordered_map< DetId, const HGCRecHit * > * hitMap_
std::vector< std::vector< std::pair< unsigned int, float > > > multiClusterToCaloParticle
The Signals That Services Can Subscribe To This is based on ActivityRegistry h
Helper function to determine trigger accepts.
std::vector< std::pair< uint32_t, float > > hits_and_fractions() const
Returns list of rechit IDs and fractions for this SimCluster.