File indexing completed on 2025-07-09 05:00:31
0001
0002
0003
0004 #include "LCToCPAssociatorByEnergyScoreImpl.h"
0005
0006 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0007 #include "SimDataFormats/CaloAnalysis/interface/CaloParticle.h"
0008 #include "SimDataFormats/CaloAnalysis/interface/SimCluster.h"
0009
0010 #include "SimCalorimetry/HGCalAssociatorProducers/interface/AssociatorTools.h"
0011 #include "DataFormats/EcalDetId/interface/EBDetId.h"
0012
0013 template <typename HIT>
0014 LCToCPAssociatorByEnergyScoreImpl<HIT>::LCToCPAssociatorByEnergyScoreImpl(
0015 edm::EDProductGetter const& productGetter,
0016 bool hardScatterOnly,
0017 std::shared_ptr<hgcal::RecHitTools> recHitTools,
0018 const std::unordered_map<DetId, const unsigned int>* hitMap,
0019 const std::vector<const HIT*>& hits)
0020 : hardScatterOnly_(hardScatterOnly),
0021 recHitTools_(recHitTools),
0022 hitMap_(hitMap),
0023 productGetter_(&productGetter),
0024 hits_(hits) {
0025 if constexpr (std::is_same_v<HIT, HGCRecHit>)
0026 layers_ = recHitTools_->lastLayerBH();
0027 else
0028 layers_ = recHitTools_->lastLayerBarrel() + 1;
0029 }
0030
0031 template <typename HIT>
0032 ticl::association LCToCPAssociatorByEnergyScoreImpl<HIT>::makeConnections(
0033 const edm::Handle<reco::CaloClusterCollection>& cCCH, const edm::Handle<CaloParticleCollection>& cPCH) const {
0034
0035 const auto& clusters = *cCCH.product();
0036 const auto& caloParticles = *cPCH.product();
0037 auto nLayerClusters = clusters.size();
0038
0039
0040 std::vector<size_t> cPIndices;
0041 removeCPFromPU(caloParticles, cPIndices, hardScatterOnly_);
0042 auto nCaloParticles = cPIndices.size();
0043
0044
0045
0046
0047
0048 ticl::caloParticleToLayerCluster cPOnLayer;
0049 cPOnLayer.resize(nCaloParticles);
0050 for (unsigned int i = 0; i < nCaloParticles; ++i) {
0051 unsigned int nLayers = layers_ * 2;
0052 if constexpr (std::is_same_v<HIT, reco::PFRecHit>)
0053 nLayers = layers_;
0054 cPOnLayer[i].resize(nLayers);
0055 for (unsigned int j = 0; j < nLayers; ++j) {
0056 cPOnLayer[i][j].caloParticleId = i;
0057 cPOnLayer[i][j].energy = 0.f;
0058 cPOnLayer[i][j].hits_and_fractions.clear();
0059
0060 }
0061 }
0062
0063
0064
0065
0066
0067
0068 std::unordered_map<DetId, std::vector<ticl::detIdInfoInCluster>> detIdToCaloParticleId_Map;
0069 for (const auto& cpId : cPIndices) {
0070 const SimClusterRefVector& simClusterRefVector = caloParticles[cpId].simClusters();
0071 for (const auto& it_sc : simClusterRefVector) {
0072 const SimCluster& simCluster = (*(it_sc));
0073 std::vector<std::pair<uint32_t, float>> hits_and_fractions;
0074 if constexpr (std::is_same_v<HIT, HGCRecHit>)
0075 hits_and_fractions = simCluster.endcap_hits_and_fractions();
0076 else
0077 hits_and_fractions = simCluster.barrel_hits_and_fractions();
0078 for (const auto& it_haf : hits_and_fractions) {
0079 const auto hitid = (it_haf.first);
0080 unsigned int cpLayerId = recHitTools_->getLayerWithOffset(hitid);
0081 if constexpr (std::is_same_v<HIT, HGCRecHit>)
0082 cpLayerId += layers_ * ((recHitTools_->zside(hitid) + 1) >> 1) - 1;
0083
0084 const auto itcheck = hitMap_->find(hitid);
0085
0086 if (itcheck != hitMap_->end()) {
0087 auto hit_find_it = detIdToCaloParticleId_Map.find(hitid);
0088 if (hit_find_it == detIdToCaloParticleId_Map.end()) {
0089 detIdToCaloParticleId_Map[hitid] = std::vector<ticl::detIdInfoInCluster>();
0090 detIdToCaloParticleId_Map[hitid].emplace_back(cpId, it_haf.second);
0091 } else {
0092 auto findHitIt = std::find(detIdToCaloParticleId_Map[hitid].begin(),
0093 detIdToCaloParticleId_Map[hitid].end(),
0094 ticl::detIdInfoInCluster{cpId, it_haf.second});
0095 if (findHitIt != detIdToCaloParticleId_Map[hitid].end()) {
0096 findHitIt->fraction += it_haf.second;
0097 } else {
0098 detIdToCaloParticleId_Map[hitid].emplace_back(cpId, it_haf.second);
0099 }
0100 }
0101 const HIT* hit = hits_[itcheck->second];
0102 cPOnLayer[cpId][cpLayerId].energy += it_haf.second * hit->energy();
0103
0104
0105
0106
0107
0108
0109 auto& haf = cPOnLayer[cpId][cpLayerId].hits_and_fractions;
0110 auto found = std::find_if(
0111 std::begin(haf), std::end(haf), [&hitid](const std::pair<DetId, float>& v) { return v.first == hitid; });
0112 if (found != haf.end()) {
0113 found->second += it_haf.second;
0114 } else {
0115 cPOnLayer[cpId][cpLayerId].hits_and_fractions.emplace_back(hitid, it_haf.second);
0116 }
0117 }
0118 }
0119 }
0120 }
0121
0122 #ifdef EDM_ML_DEBUG
0123 LogDebug("LCToCPAssociatorByEnergyScoreImpl") << "cPOnLayer INFO" << std::endl;
0124 for (size_t cp = 0; cp < cPOnLayer.size(); ++cp) {
0125 LogDebug("LCToCPAssociatorByEnergyScoreImpl") << "For CaloParticle Idx: " << cp << " we have: " << std::endl;
0126 for (size_t cpp = 0; cpp < cPOnLayer[cp].size(); ++cpp) {
0127 LogDebug("LCToCPAssociatorByEnergyScoreImpl") << " On Layer: " << cpp << " we have:" << std::endl;
0128 LogDebug("LCToCPAssociatorByEnergyScoreImpl")
0129 << " CaloParticleIdx: " << cPOnLayer[cp][cpp].caloParticleId << std::endl;
0130 LogDebug("LCToCPAssociatorByEnergyScoreImpl")
0131 << " Energy: " << cPOnLayer[cp][cpp].energy << std::endl;
0132 double tot_energy = 0.;
0133 for (auto const& haf : cPOnLayer[cp][cpp].hits_and_fractions) {
0134
0135 const HIT* hit = hits_[hitMap_->at(haf.first)];
0136 LogDebug("LCToCPAssociatorByEnergyScoreImpl") << " Hits/fraction/energy: " << (uint32_t)haf.first << "/"
0137 << haf.second << "/" << haf.second * hit->energy() << std::endl;
0138 tot_energy += haf.second * hit->energy();
0139 }
0140 LogDebug("LCToCPAssociatorByEnergyScoreImpl") << " Tot Sum haf: " << tot_energy << std::endl;
0141 for (auto const& lc : cPOnLayer[cp][cpp].layerClusterIdToEnergyAndScore) {
0142 LogDebug("LCToCPAssociatorByEnergyScoreImpl") << " lcIdx/energy/score: " << lc.first << "/"
0143 << lc.second.first << "/" << lc.second.second << std::endl;
0144 }
0145 }
0146 }
0147
0148 LogDebug("LCToCPAssociatorByEnergyScoreImpl") << "detIdToCaloParticleId_Map INFO" << std::endl;
0149 for (auto const& cp : detIdToCaloParticleId_Map) {
0150 LogDebug("LCToCPAssociatorByEnergyScoreImpl")
0151 << "For detId: " << (uint32_t)cp.first
0152 << " we have found the following connections with CaloParticles:" << std::endl;
0153 const HIT* hit = hits_[hitMap_->at(cp.first)];
0154 for (auto const& cpp : cp.second) {
0155 LogDebug("LCToCPAssociatorByEnergyScoreImpl")
0156 << " CaloParticle Id: " << cpp.clusterId << " with fraction: " << cpp.fraction
0157 << " and energy: " << cpp.fraction * hit->energy() << std::endl;
0158 }
0159 }
0160 #endif
0161
0162
0163 std::unordered_map<DetId, std::vector<ticl::detIdInfoInCluster>> detIdToLayerClusterId_Map;
0164
0165
0166
0167
0168 ticl::layerClusterToCaloParticle cpsInLayerCluster;
0169 cpsInLayerCluster.resize(nLayerClusters);
0170
0171 for (unsigned int lcId = 0; lcId < nLayerClusters; ++lcId) {
0172 const std::vector<std::pair<DetId, float>>& hits_and_fractions = clusters[lcId].hitsAndFractions();
0173 unsigned int numberOfHitsInLC = hits_and_fractions.size();
0174 const auto firstHitDetId = hits_and_fractions[0].first;
0175 unsigned int lcLayerId = recHitTools_->getLayerWithOffset(firstHitDetId);
0176 if constexpr (std::is_same_v<HIT, HGCRecHit>)
0177 lcLayerId += layers_ * ((recHitTools_->zside(firstHitDetId) + 1) >> 1) - 1;
0178 for (unsigned int hitId = 0; hitId < numberOfHitsInLC; hitId++) {
0179 const auto rh_detid = hits_and_fractions[hitId].first;
0180 const auto rhFraction = hits_and_fractions[hitId].second;
0181
0182 auto hit_find_in_LC = detIdToLayerClusterId_Map.find(rh_detid);
0183 if (hit_find_in_LC == detIdToLayerClusterId_Map.end()) {
0184 detIdToLayerClusterId_Map[rh_detid] = std::vector<ticl::detIdInfoInCluster>();
0185 }
0186 detIdToLayerClusterId_Map[rh_detid].emplace_back(lcId, rhFraction);
0187
0188 auto hit_find_in_CP = detIdToCaloParticleId_Map.find(rh_detid);
0189
0190 if (hit_find_in_CP != detIdToCaloParticleId_Map.end()) {
0191 const auto itcheck = hitMap_->find(rh_detid);
0192 const HIT* hit = hits_[itcheck->second];
0193 for (auto& h : hit_find_in_CP->second) {
0194 cPOnLayer[h.clusterId][lcLayerId].layerClusterIdToEnergyAndScore[lcId].first += h.fraction * hit->energy();
0195 cpsInLayerCluster[lcId].emplace_back(h.clusterId, 0.f);
0196 }
0197 }
0198 }
0199 }
0200
0201 #ifdef EDM_ML_DEBUG
0202 for (unsigned int lcId = 0; lcId < nLayerClusters; ++lcId) {
0203 const auto& hits_and_fractions = clusters[lcId].hitsAndFractions();
0204 unsigned int numberOfHitsInLC = hits_and_fractions.size();
0205 const auto firstHitDetId = hits_and_fractions[0].first;
0206 int lcLayerId = recHitTools_->getLayerWithOffset(firstHitDetId);
0207 if constexpr (std::is_same_v<HIT, HGCRecHit>)
0208 lcLayerId += layers_ * ((recHitTools_->zside(firstHitDetId) + 1) >> 1) - 1;
0209
0210
0211
0212
0213
0214
0215
0216
0217 std::vector<int> hitsToCaloParticleId(numberOfHitsInLC);
0218
0219 int maxCPId_byNumberOfHits = -1;
0220
0221 unsigned int maxCPNumberOfHitsInLC = 0;
0222
0223 int maxCPId_byEnergy = -1;
0224
0225 float maxEnergySharedLCandCP = 0.f;
0226
0227 float energyFractionOfLCinCP = 0.f;
0228
0229 float energyFractionOfCPinLC = 0.f;
0230 std::unordered_map<unsigned, unsigned> occurrencesCPinLC;
0231 unsigned int numberOfNoiseHitsInLC = 0;
0232 std::unordered_map<unsigned, float> CPEnergyInLC;
0233 for (unsigned int hitId = 0; hitId < numberOfHitsInLC; hitId++) {
0234 const auto rh_detid = hits_and_fractions[hitId].first;
0235 const auto rhFraction = hits_and_fractions[hitId].second;
0236
0237 auto hit_find_in_CP = detIdToCaloParticleId_Map.find(rh_detid);
0238
0239
0240
0241
0242
0243
0244
0245 if (rhFraction == 0.) {
0246 hitsToCaloParticleId[hitId] = -2;
0247 }
0248 if (hit_find_in_CP == detIdToCaloParticleId_Map.end()) {
0249 hitsToCaloParticleId[hitId] -= 1;
0250 } else {
0251 const HIT* hit = hits_[hitMap_->at(rh_detid)];
0252 auto maxCPEnergyInLC = 0.f;
0253 auto maxCPId = -1;
0254 for (auto& h : hit_find_in_CP->second) {
0255 CPEnergyInLC[h.clusterId] += h.fraction * hit->energy();
0256
0257
0258 if (CPEnergyInLC[h.clusterId] > maxCPEnergyInLC) {
0259 maxCPEnergyInLC = CPEnergyInLC[h.clusterId];
0260 maxCPId = h.clusterId;
0261 }
0262 }
0263 hitsToCaloParticleId[hitId] = maxCPId;
0264 }
0265 }
0266 for (const auto& c : hitsToCaloParticleId) {
0267 if (c < 0) {
0268 numberOfNoiseHitsInLC++;
0269 } else {
0270 occurrencesCPinLC[c]++;
0271 }
0272 }
0273
0274 for (const auto& c : occurrencesCPinLC) {
0275 if (c.second > maxCPNumberOfHitsInLC) {
0276 maxCPId_byNumberOfHits = c.first;
0277 maxCPNumberOfHitsInLC = c.second;
0278 }
0279 }
0280
0281 for (const auto& c : CPEnergyInLC) {
0282 if (c.second > maxEnergySharedLCandCP) {
0283 maxCPId_byEnergy = c.first;
0284 maxEnergySharedLCandCP = c.second;
0285 }
0286 }
0287
0288 float totalCPEnergyOnLayer = 0.f;
0289 if (maxCPId_byEnergy >= 0) {
0290 totalCPEnergyOnLayer = cPOnLayer[maxCPId_byEnergy][lcLayerId].energy;
0291 energyFractionOfCPinLC = maxEnergySharedLCandCP / totalCPEnergyOnLayer;
0292 if (clusters[lcId].energy() > 0.f) {
0293 energyFractionOfLCinCP = maxEnergySharedLCandCP / clusters[lcId].energy();
0294 }
0295 }
0296
0297 LogDebug("LCToCPAssociatorByEnergyScoreImpl")
0298 << std::setw(10) << "LayerId:\t" << std::setw(12) << "layerCluster\t" << std::setw(10) << "lc energy\t"
0299 << std::setw(5) << "nhits\t" << std::setw(12) << "noise hits\t" << std::setw(22) << "maxCPId_byNumberOfHits\t"
0300 << std::setw(8) << "nhitsCP\t" << std::setw(13) << "maxCPId_byEnergy\t" << std::setw(20)
0301 << "maxEnergySharedLCandCP\t" << std::setw(22) << "totalCPEnergyOnLayer\t" << std::setw(22)
0302 << "energyFractionOfLCinCP\t" << std::setw(25) << "energyFractionOfCPinLC\t"
0303 << "\n";
0304 LogDebug("LCToCPAssociatorByEnergyScoreImpl")
0305 << std::setw(10) << lcLayerId << "\t" << std::setw(12) << lcId << "\t" << std::setw(10)
0306 << clusters[lcId].energy() << "\t" << std::setw(5) << numberOfHitsInLC << "\t" << std::setw(12)
0307 << numberOfNoiseHitsInLC << "\t" << std::setw(22) << maxCPId_byNumberOfHits << "\t" << std::setw(8)
0308 << maxCPNumberOfHitsInLC << "\t" << std::setw(13) << maxCPId_byEnergy << "\t" << std::setw(20)
0309 << maxEnergySharedLCandCP << "\t" << std::setw(22) << totalCPEnergyOnLayer << "\t" << std::setw(22)
0310 << energyFractionOfLCinCP << "\t" << std::setw(25) << energyFractionOfCPinLC << "\n";
0311 }
0312
0313 LogDebug("LCToCPAssociatorByEnergyScoreImpl") << "Improved cPOnLayer INFO" << std::endl;
0314 for (size_t cp = 0; cp < cPOnLayer.size(); ++cp) {
0315 LogDebug("LCToCPAssociatorByEnergyScoreImpl") << "For CaloParticle Idx: " << cp << " we have: " << std::endl;
0316 for (size_t cpp = 0; cpp < cPOnLayer[cp].size(); ++cpp) {
0317 LogDebug("LCToCPAssociatorByEnergyScoreImpl") << " On Layer: " << cpp << " we have:" << std::endl;
0318 LogDebug("LCToCPAssociatorByEnergyScoreImpl")
0319 << " CaloParticleIdx: " << cPOnLayer[cp][cpp].caloParticleId << std::endl;
0320 LogDebug("LCToCPAssociatorByEnergyScoreImpl")
0321 << " Energy: " << cPOnLayer[cp][cpp].energy << std::endl;
0322 double tot_energy = 0.;
0323 for (auto const& haf : cPOnLayer[cp][cpp].hits_and_fractions) {
0324 const HIT* hit = hits_[hitMap_->at(haf.first)];
0325 LogDebug("LCToCPAssociatorByEnergyScoreImpl") << " Hits/fraction/energy: " << (uint32_t)haf.first << "/"
0326 << haf.second << "/" << haf.second * hit->energy() << std::endl;
0327 tot_energy += haf.second * hit->energy();
0328 }
0329 LogDebug("LCToCPAssociatorByEnergyScoreImpl") << " Tot Sum haf: " << tot_energy << std::endl;
0330 for (auto const& lc : cPOnLayer[cp][cpp].layerClusterIdToEnergyAndScore) {
0331 LogDebug("LCToCPAssociatorByEnergyScoreImpl") << " lcIdx/energy/score: " << lc.first << "/"
0332 << lc.second.first << "/" << lc.second.second << std::endl;
0333 }
0334 }
0335 }
0336
0337 LogDebug("LCToCPAssociatorByEnergyScoreImpl") << "Improved detIdToCaloParticleId_Map INFO" << std::endl;
0338 for (auto const& cp : detIdToCaloParticleId_Map) {
0339 LogDebug("LCToCPAssociatorByEnergyScoreImpl")
0340 << "For detId: " << (uint32_t)cp.first
0341 << " we have found the following connections with CaloParticles:" << std::endl;
0342 const HIT* hit = hits_[hitMap_->at(cp.first)];
0343 for (auto const& cpp : cp.second) {
0344 LogDebug("LCToCPAssociatorByEnergyScoreImpl")
0345 << " CaloParticle Id: " << cpp.clusterId << " with fraction: " << cpp.fraction
0346 << " and energy: " << cpp.fraction * hit->energy() << std::endl;
0347 }
0348 }
0349 #endif
0350
0351
0352
0353 for (unsigned int lcId = 0; lcId < nLayerClusters; ++lcId) {
0354
0355 if constexpr (std::is_same_v<HIT, HGCRecHit>) {
0356 if (recHitTools_->isBarrel(clusters[lcId].seed()))
0357 continue;
0358 } else {
0359 if (!recHitTools_->isBarrel(clusters[lcId].seed()))
0360 continue;
0361 }
0362 std::sort(cpsInLayerCluster[lcId].begin(), cpsInLayerCluster[lcId].end());
0363 auto last = std::unique(cpsInLayerCluster[lcId].begin(), cpsInLayerCluster[lcId].end());
0364 cpsInLayerCluster[lcId].erase(last, cpsInLayerCluster[lcId].end());
0365 const auto& hits_and_fractions = clusters[lcId].hitsAndFractions();
0366 unsigned int numberOfHitsInLC = hits_and_fractions.size();
0367
0368
0369 if (clusters[lcId].energy() == 0. && !cpsInLayerCluster[lcId].empty()) {
0370 for (auto& cpPair : cpsInLayerCluster[lcId]) {
0371 cpPair.second = 1.;
0372 LogDebug("LCToCPAssociatorByEnergyScoreImpl") << "layerClusterId : \t " << lcId << "\t CP id : \t"
0373 << cpPair.first << "\t score \t " << cpPair.second << "\n";
0374 }
0375 continue;
0376 }
0377
0378
0379
0380 float invLayerClusterEnergyWeight = 0.f;
0381 for (auto const& haf : hits_and_fractions) {
0382 const HIT* hit = hits_[hitMap_->at(haf.first)];
0383 invLayerClusterEnergyWeight += (haf.second * hit->energy()) * (haf.second * hit->energy());
0384 }
0385 invLayerClusterEnergyWeight = 1.f / invLayerClusterEnergyWeight;
0386 for (unsigned int i = 0; i < numberOfHitsInLC; ++i) {
0387 DetId rh_detid = hits_and_fractions[i].first;
0388 float rhFraction = hits_and_fractions[i].second;
0389
0390 bool hitWithNoCP = (detIdToCaloParticleId_Map.find(rh_detid) == detIdToCaloParticleId_Map.end());
0391
0392 auto itcheck = hitMap_->find(rh_detid);
0393 if (itcheck == hitMap_->end())
0394 continue;
0395 const HIT* hit = hits_[itcheck->second];
0396 float hitEnergyWeight = hit->energy() * hit->energy();
0397
0398 for (auto& cpPair : cpsInLayerCluster[lcId]) {
0399 float cpFraction = 0.f;
0400 if (!hitWithNoCP) {
0401 auto findHitIt = std::find(detIdToCaloParticleId_Map[rh_detid].begin(),
0402 detIdToCaloParticleId_Map[rh_detid].end(),
0403 ticl::detIdInfoInCluster{cpPair.first, 0.f});
0404 if (findHitIt != detIdToCaloParticleId_Map[rh_detid].end())
0405 cpFraction = findHitIt->fraction;
0406 }
0407 cpPair.second += std::min(std::pow(rhFraction - cpFraction, 2), std::pow(rhFraction, 2)) * hitEnergyWeight *
0408 invLayerClusterEnergyWeight;
0409 }
0410 }
0411 #ifdef EDM_ML_DEBUG
0412 if (cpsInLayerCluster[lcId].empty())
0413 LogDebug("LCToCPAssociatorByEnergyScoreImpl") << "layerCluster Id: \t" << lcId << "\tCP id:\t-1 "
0414 << "\t score \t-1\n";
0415 #endif
0416 }
0417
0418
0419 for (const auto& cpId : cPIndices) {
0420 unsigned int nLayers = layers_ * 2;
0421 if constexpr (std::is_same_v<HIT, reco::PFRecHit>)
0422 nLayers = layers_;
0423 for (unsigned int layerId = 0; layerId < nLayers; ++layerId) {
0424 unsigned int CPNumberOfHits = cPOnLayer[cpId][layerId].hits_and_fractions.size();
0425 if (CPNumberOfHits == 0)
0426 continue;
0427 #ifdef EDM_ML_DEBUG
0428 int lcWithMaxEnergyInCP = -1;
0429 float maxEnergyLCinCP = 0.f;
0430 float CPenergy = cPOnLayer[cpId][layerId].energy;
0431 float CPEnergyFractionInLC = 0.f;
0432 for (auto& lc : cPOnLayer[cpId][layerId].layerClusterIdToEnergyAndScore) {
0433 if (lc.second.first > maxEnergyLCinCP) {
0434 maxEnergyLCinCP = lc.second.first;
0435 lcWithMaxEnergyInCP = lc.first;
0436 }
0437 }
0438 if (CPenergy > 0.f)
0439 CPEnergyFractionInLC = maxEnergyLCinCP / CPenergy;
0440
0441 LogDebug("LCToCPAssociatorByEnergyScoreImpl")
0442 << std::setw(8) << "LayerId:\t" << std::setw(12) << "caloparticle\t" << std::setw(15) << "cp total energy\t"
0443 << std::setw(15) << "cpEnergyOnLayer\t" << std::setw(14) << "CPNhitsOnLayer\t" << std::setw(18)
0444 << "lcWithMaxEnergyInCP\t" << std::setw(15) << "maxEnergyLCinCP\t" << std::setw(20) << "CPEnergyFractionInLC"
0445 << "\n";
0446 LogDebug("LCToCPAssociatorByEnergyScoreImpl")
0447 << std::setw(8) << layerId << "\t" << std::setw(12) << cpId << "\t" << std::setw(15)
0448 << caloParticles[cpId].energy() << "\t" << std::setw(15) << CPenergy << "\t" << std::setw(14)
0449 << CPNumberOfHits << "\t" << std::setw(18) << lcWithMaxEnergyInCP << "\t" << std::setw(15) << maxEnergyLCinCP
0450 << "\t" << std::setw(20) << CPEnergyFractionInLC << "\n";
0451 #endif
0452
0453 float invCPEnergyWeight = 0.f;
0454 for (auto const& haf : cPOnLayer[cpId][layerId].hits_and_fractions) {
0455 const HIT* hit = hits_[hitMap_->at(haf.first)];
0456 invCPEnergyWeight += std::pow(haf.second * hit->energy(), 2);
0457 }
0458 invCPEnergyWeight = 1.f / invCPEnergyWeight;
0459 for (unsigned int i = 0; i < CPNumberOfHits; ++i) {
0460 auto& cp_hitDetId = cPOnLayer[cpId][layerId].hits_and_fractions[i].first;
0461 auto& cpFraction = cPOnLayer[cpId][layerId].hits_and_fractions[i].second;
0462
0463 bool hitWithNoLC = false;
0464 if (cpFraction == 0.f)
0465 continue;
0466 auto hit_find_in_LC = detIdToLayerClusterId_Map.find(cp_hitDetId);
0467 if (hit_find_in_LC == detIdToLayerClusterId_Map.end())
0468 hitWithNoLC = true;
0469 auto itcheck = hitMap_->find(cp_hitDetId);
0470 const HIT* hit = hits_[itcheck->second];
0471 float hitEnergyWeight = hit->energy() * hit->energy();
0472 for (auto& lcPair : cPOnLayer[cpId][layerId].layerClusterIdToEnergyAndScore) {
0473 unsigned int layerClusterId = lcPair.first;
0474 float lcFraction = 0.f;
0475
0476 if (!hitWithNoLC) {
0477 auto findHitIt = std::find(detIdToLayerClusterId_Map[cp_hitDetId].begin(),
0478 detIdToLayerClusterId_Map[cp_hitDetId].end(),
0479 ticl::detIdInfoInCluster{layerClusterId, 0.f});
0480 if (findHitIt != detIdToLayerClusterId_Map[cp_hitDetId].end())
0481 lcFraction = findHitIt->fraction;
0482 }
0483 lcPair.second.second += std::min(std::pow(lcFraction - cpFraction, 2), std::pow(cpFraction, 2)) *
0484 hitEnergyWeight * invCPEnergyWeight;
0485 #ifdef EDM_ML_DEBUG
0486 LogDebug("LCToCPAssociatorByEnergyScoreImpl")
0487 << "cpDetId:\t" << (uint32_t)cp_hitDetId << "\tlayerClusterId:\t" << layerClusterId << "\t"
0488 << "lcfraction,cpfraction:\t" << lcFraction << ", " << cpFraction << "\t"
0489 << "hitEnergyWeight:\t" << hitEnergyWeight << "\t"
0490 << "current score:\t" << lcPair.second.second << "\t"
0491 << "invCPEnergyWeight:\t" << invCPEnergyWeight << "\n";
0492 #endif
0493 }
0494 }
0495 #ifdef EDM_ML_DEBUG
0496 if (cPOnLayer[cpId][layerId].layerClusterIdToEnergyAndScore.empty())
0497 LogDebug("LCToCPAssociatorByEnergyScoreImpl") << "CP Id: \t" << cpId << "\tLC id:\t-1 "
0498 << "\t score \t-1\n";
0499
0500 for (const auto& lcPair : cPOnLayer[cpId][layerId].layerClusterIdToEnergyAndScore) {
0501 LogDebug("LCToCPAssociatorByEnergyScoreImpl")
0502 << "CP Id: \t" << cpId << "\t LC id: \t" << lcPair.first << "\t score \t" << lcPair.second.second
0503 << "\t shared energy:\t" << lcPair.second.first << "\t shared energy fraction:\t"
0504 << (lcPair.second.first / CPenergy) << "\n";
0505 }
0506 #endif
0507 }
0508 }
0509
0510 return {cpsInLayerCluster, cPOnLayer};
0511 }
0512
0513 template <typename HIT>
0514 ticl::RecoToSimCollection LCToCPAssociatorByEnergyScoreImpl<HIT>::associateRecoToSim(
0515 const edm::Handle<reco::CaloClusterCollection>& cCCH, const edm::Handle<CaloParticleCollection>& cPCH) const {
0516 ticl::RecoToSimCollection returnValue(productGetter_);
0517 const auto& links = makeConnections(cCCH, cPCH);
0518
0519 const auto& cpsInLayerCluster = std::get<0>(links);
0520 for (size_t lcId = 0; lcId < cpsInLayerCluster.size(); ++lcId) {
0521 for (auto& cpPair : cpsInLayerCluster[lcId]) {
0522 LogDebug("LCToCPAssociatorByEnergyScoreImpl")
0523 << "layerCluster Id: \t" << lcId << "\t CP id: \t" << cpPair.first << "\t score \t" << cpPair.second << "\n";
0524
0525 returnValue.insert(edm::Ref<reco::CaloClusterCollection>(cCCH, lcId),
0526 std::make_pair(edm::Ref<CaloParticleCollection>(cPCH, cpPair.first),
0527 cpPair.second)
0528 );
0529 }
0530 }
0531 return returnValue;
0532 }
0533
0534 template <typename HIT>
0535 ticl::SimToRecoCollection LCToCPAssociatorByEnergyScoreImpl<HIT>::associateSimToReco(
0536 const edm::Handle<reco::CaloClusterCollection>& cCCH, const edm::Handle<CaloParticleCollection>& cPCH) const {
0537 ticl::SimToRecoCollection returnValue(productGetter_);
0538 const auto& links = makeConnections(cCCH, cPCH);
0539 const auto& cPOnLayer = std::get<1>(links);
0540 for (size_t cpId = 0; cpId < cPOnLayer.size(); ++cpId) {
0541 for (size_t layerId = 0; layerId < cPOnLayer[cpId].size(); ++layerId) {
0542 for (auto& lcPair : cPOnLayer[cpId][layerId].layerClusterIdToEnergyAndScore) {
0543 returnValue.insert(
0544 edm::Ref<CaloParticleCollection>(cPCH, cpId),
0545 std::make_pair(edm::Ref<reco::CaloClusterCollection>(cCCH, lcPair.first),
0546 std::make_pair(lcPair.second.first, lcPair.second.second))
0547 );
0548 }
0549 }
0550 }
0551 return returnValue;
0552 }
0553
0554 template class LCToCPAssociatorByEnergyScoreImpl<HGCRecHit>;
0555 template class LCToCPAssociatorByEnergyScoreImpl<reco::PFRecHit>;