Back to home page

Project CMSSW displayed by LXR

 
 

    


File indexing completed on 2025-04-30 22:24:39

0001 // Author: Felice Pantaleo, felice.pantaleo@cern.ch 08/2024
0002 
0003 #include "FWCore/Framework/interface/global/EDProducer.h"
0004 #include "FWCore/Framework/interface/Event.h"
0005 #include "FWCore/Framework/interface/MakerMacros.h"
0006 #include "FWCore/ParameterSet/interface/ParameterSet.h"
0007 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0008 #include "FWCore/Utilities/interface/EDGetToken.h"
0009 #include "DataFormats/HGCalReco/interface/Trackster.h"
0010 #include "SimDataFormats/Associations/interface/TICLAssociationMap.h"
0011 #include "DataFormats/Provenance/interface/ProductID.h"
0012 #include "DataFormats/HGCRecHit/interface/HGCRecHitCollections.h"
0013 #include "CommonTools/RecoAlgos/interface/MultiVectorManager.h"
0014 #include "DataFormats/CaloRecHit/interface/CaloCluster.h"
0015 #include "SimDataFormats/CaloAnalysis/interface/CaloParticle.h"
0016 #include "SimDataFormats/CaloAnalysis/interface/SimCluster.h"
0017 
0018 class AllTracksterToSimTracksterAssociatorsByHitsProducer : public edm::global::EDProducer<> {
0019 public:
0020   explicit AllTracksterToSimTracksterAssociatorsByHitsProducer(const edm::ParameterSet&);
0021   ~AllTracksterToSimTracksterAssociatorsByHitsProducer() override = default;
0022 
0023   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0024 
0025 private:
0026   void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
0027 
0028   std::vector<std::pair<std::string, edm::EDGetTokenT<std::vector<ticl::Trackster>>>> tracksterCollectionTokens_;
0029   std::vector<std::pair<std::string, edm::EDGetTokenT<std::vector<ticl::Trackster>>>> simTracksterCollectionTokens_;
0030   std::vector<std::pair<std::string, edm::EDGetTokenT<ticl::AssociationMap<ticl::mapWithFraction>>>>
0031       hitToTracksterMapTokens_;
0032   std::vector<std::pair<std::string, edm::EDGetTokenT<ticl::AssociationMap<ticl::mapWithFraction>>>>
0033       tracksterToHitMapTokens_;
0034 
0035   std::vector<std::pair<std::string, edm::EDGetTokenT<ticl::AssociationMap<ticl::mapWithFraction>>>>
0036       hitToSimTracksterMapTokens_;
0037   std::vector<std::pair<std::string, edm::EDGetTokenT<ticl::AssociationMap<ticl::mapWithFraction>>>>
0038       simTracksterToHitMapTokens_;
0039 
0040   std::vector<edm::EDGetTokenT<HGCRecHitCollection>> hitsTokens_;
0041   edm::EDGetTokenT<std::vector<CaloParticle>> caloParticleToken_;
0042   edm::EDGetTokenT<ticl::AssociationMap<ticl::mapWithFraction>> hitToSimClusterMapToken_;
0043   edm::EDGetTokenT<ticl::AssociationMap<ticl::mapWithFraction>> hitToCaloParticleMapToken_;
0044 };
0045 
0046 AllTracksterToSimTracksterAssociatorsByHitsProducer::AllTracksterToSimTracksterAssociatorsByHitsProducer(
0047     const edm::ParameterSet& pset)
0048     : caloParticleToken_(consumes<std::vector<CaloParticle>>(pset.getParameter<edm::InputTag>("caloParticles"))),
0049       hitToSimClusterMapToken_(consumes<ticl::AssociationMap<ticl::mapWithFraction>>(
0050           pset.getParameter<edm::InputTag>("hitToSimClusterMap"))),
0051       hitToCaloParticleMapToken_(consumes<ticl::AssociationMap<ticl::mapWithFraction>>(
0052           pset.getParameter<edm::InputTag>("hitToCaloParticleMap"))) {
0053   const auto& tracksterCollections = pset.getParameter<std::vector<edm::InputTag>>("tracksterCollections");
0054 
0055   std::string allHitToTSAccoc = pset.getParameter<std::string>("allHitToTSAccoc");
0056   for (const auto& tag : tracksterCollections) {
0057     std::string label = tag.label();
0058     if (!tag.instance().empty()) {
0059       label += tag.instance();
0060     }
0061     tracksterCollectionTokens_.emplace_back(label, consumes<std::vector<ticl::Trackster>>(tag));
0062     hitToTracksterMapTokens_.emplace_back(
0063         label, consumes<ticl::AssociationMap<ticl::mapWithFraction>>(edm::InputTag(allHitToTSAccoc, "hitTo" + label)));
0064     tracksterToHitMapTokens_.emplace_back(
0065         label, consumes<ticl::AssociationMap<ticl::mapWithFraction>>(edm::InputTag(allHitToTSAccoc, label + "ToHit")));
0066   }
0067 
0068   const auto& simTracksterCollections = pset.getParameter<std::vector<edm::InputTag>>("simTracksterCollections");
0069   for (const auto& tag : simTracksterCollections) {
0070     std::string label = tag.label();
0071     if (!tag.instance().empty()) {
0072       label += tag.instance();
0073     }
0074     simTracksterCollectionTokens_.emplace_back(label, consumes<std::vector<ticl::Trackster>>(tag));
0075     hitToSimTracksterMapTokens_.emplace_back(
0076         label, consumes<ticl::AssociationMap<ticl::mapWithFraction>>(edm::InputTag(allHitToTSAccoc, "hitTo" + label)));
0077     simTracksterToHitMapTokens_.emplace_back(
0078         label, consumes<ticl::AssociationMap<ticl::mapWithFraction>>(edm::InputTag(allHitToTSAccoc, label + "ToHit")));
0079   }
0080 
0081   // Hits
0082   auto hitsTags = pset.getParameter<std::vector<edm::InputTag>>("hits");
0083   for (const auto& tag : hitsTags) {
0084     hitsTokens_.push_back(consumes<HGCRecHitCollection>(tag));
0085   }
0086 
0087   // Produce separate association maps for each trackster-simTrackster combination
0088   for (const auto& tracksterToken : tracksterCollectionTokens_) {
0089     for (const auto& simTracksterToken : simTracksterCollectionTokens_) {
0090       std::string instanceLabel = tracksterToken.first + "To" + simTracksterToken.first;
0091       produces<ticl::AssociationMap<ticl::mapWithSharedEnergyAndScore,
0092                                     std::vector<ticl::Trackster>,
0093                                     std::vector<ticl::Trackster>>>(instanceLabel);
0094       std::string reverseInstanceLabel = simTracksterToken.first + "To" + tracksterToken.first;
0095       produces<ticl::AssociationMap<ticl::mapWithSharedEnergyAndScore,
0096                                     std::vector<ticl::Trackster>,
0097                                     std::vector<ticl::Trackster>>>(reverseInstanceLabel);
0098     }
0099   }
0100 }
0101 
0102 void AllTracksterToSimTracksterAssociatorsByHitsProducer::produce(edm::StreamID,
0103                                                                   edm::Event& iEvent,
0104                                                                   const edm::EventSetup&) const {
0105   using namespace edm;
0106 
0107   MultiVectorManager<HGCRecHit> rechitManager;
0108   for (const auto& token : hitsTokens_) {
0109     Handle<HGCRecHitCollection> hitsHandle;
0110     iEvent.getByToken(token, hitsHandle);
0111 
0112     if (!hitsHandle.isValid()) {
0113       edm::LogWarning("AllTracksterToSimTracksterAssociatorsByHitsProducer")
0114           << "Missing HGCRecHitCollection for one of the hitsTokens.";
0115       continue;
0116     }
0117     rechitManager.addVector(*hitsHandle);
0118   }
0119 
0120   // Check if rechitManager is empty
0121   if (rechitManager.size() == 0) {
0122     edm::LogWarning("AllTracksterToSimTracksterAssociatorsByHitsProducer")
0123         << "No valid HGCRecHitCollections found. Association maps will be empty.";
0124 
0125     for (const auto& tracksterToken : tracksterCollectionTokens_) {
0126       Handle<std::vector<ticl::Trackster>> recoTrackstersHandle;
0127       iEvent.getByToken(tracksterToken.second, recoTrackstersHandle);
0128 
0129       for (const auto& simTracksterToken : simTracksterCollectionTokens_) {
0130         Handle<std::vector<ticl::Trackster>> simTrackstersHandle;
0131         iEvent.getByToken(simTracksterToken.second, simTrackstersHandle);
0132 
0133         iEvent.put(std::make_unique<ticl::AssociationMap<ticl::mapWithSharedEnergyAndScore,
0134                                                          std::vector<ticl::Trackster>,
0135                                                          std::vector<ticl::Trackster>>>(),
0136                    tracksterToken.first + "To" + simTracksterToken.first);
0137         iEvent.put(std::make_unique<ticl::AssociationMap<ticl::mapWithSharedEnergyAndScore,
0138                                                          std::vector<ticl::Trackster>,
0139                                                          std::vector<ticl::Trackster>>>(),
0140                    simTracksterToken.first + "To" + tracksterToken.first);
0141       }
0142     }
0143     return;
0144   }
0145 
0146   Handle<ticl::AssociationMap<ticl::mapWithFraction>> hitToSimClusterMapHandle;
0147   iEvent.getByToken(hitToSimClusterMapToken_, hitToSimClusterMapHandle);
0148   const auto& hitToSimClusterMap = *hitToSimClusterMapHandle;
0149 
0150   Handle<ticl::AssociationMap<ticl::mapWithFraction>> hitToCaloParticleMapHandle;
0151   iEvent.getByToken(hitToCaloParticleMapToken_, hitToCaloParticleMapHandle);
0152   const auto& hitToCaloParticleMap = *hitToCaloParticleMapHandle;
0153 
0154   Handle<std::vector<CaloParticle>> caloParticlesHandle;
0155   iEvent.getByToken(caloParticleToken_, caloParticlesHandle);
0156 
0157   for (const auto& tracksterToken : tracksterCollectionTokens_) {
0158     Handle<std::vector<ticl::Trackster>> recoTrackstersHandle;
0159     iEvent.getByToken(tracksterToken.second, recoTrackstersHandle);
0160 
0161     if (!recoTrackstersHandle.isValid()) {
0162       edm::LogWarning("AllTracksterToSimTracksterAssociatorsByHitsProducer")
0163           << "No valid Trackster collection found. Association maps will be empty.";
0164       for (const auto& simTracksterToken : simTracksterCollectionTokens_) {
0165         Handle<std::vector<ticl::Trackster>> simTrackstersHandle;
0166         iEvent.getByToken(simTracksterToken.second, simTrackstersHandle);
0167 
0168         iEvent.put(std::make_unique<ticl::AssociationMap<ticl::mapWithSharedEnergyAndScore,
0169                                                          std::vector<ticl::Trackster>,
0170                                                          std::vector<ticl::Trackster>>>(),
0171                    tracksterToken.first + "To" + simTracksterToken.first);
0172         iEvent.put(std::make_unique<ticl::AssociationMap<ticl::mapWithSharedEnergyAndScore,
0173                                                          std::vector<ticl::Trackster>,
0174                                                          std::vector<ticl::Trackster>>>(),
0175                    simTracksterToken.first + "To" + tracksterToken.first);
0176       }
0177       return;
0178     }
0179 
0180     const auto& recoTracksters = *recoTrackstersHandle;
0181 
0182     // Retrieve the correct HitToTracksterMap for the current trackster collection
0183     Handle<ticl::AssociationMap<ticl::mapWithFraction>> hitToTracksterMapHandle;
0184     auto tracksterMapTokenIter = std::find_if(
0185         hitToTracksterMapTokens_.begin(), hitToTracksterMapTokens_.end(), [&tracksterToken](const auto& pair) {
0186           return pair.first == tracksterToken.first;
0187         });
0188     if (tracksterMapTokenIter != hitToTracksterMapTokens_.end()) {
0189       iEvent.getByToken(tracksterMapTokenIter->second, hitToTracksterMapHandle);
0190     }
0191     const auto& hitToTracksterMap = *hitToTracksterMapHandle;
0192 
0193     // Retrieve the correct TracksterToHitMap for the current trackster collection
0194     Handle<ticl::AssociationMap<ticl::mapWithFraction>> tracksterToHitMapHandle;
0195     auto tracksterToHitMapTokenIter = std::find_if(
0196         tracksterToHitMapTokens_.begin(), tracksterToHitMapTokens_.end(), [&tracksterToken](const auto& pair) {
0197           return pair.first == tracksterToken.first;
0198         });
0199     if (tracksterToHitMapTokenIter != tracksterToHitMapTokens_.end()) {
0200       iEvent.getByToken(tracksterToHitMapTokenIter->second, tracksterToHitMapHandle);
0201     }
0202     const auto& tracksterToHitMap = *tracksterToHitMapHandle;
0203 
0204     for (const auto& simTracksterToken : simTracksterCollectionTokens_) {
0205       Handle<std::vector<ticl::Trackster>> simTrackstersHandle;
0206       iEvent.getByToken(simTracksterToken.second, simTrackstersHandle);
0207       const auto& simTracksters = *simTrackstersHandle;
0208 
0209       // Retrieve the correct HitToSimTracksterMap for the current simTrackster collection
0210       Handle<ticl::AssociationMap<ticl::mapWithFraction>> hitToSimTracksterMapHandle;
0211       auto simTracksterMapTokenIter =
0212           std::find_if(hitToSimTracksterMapTokens_.begin(),
0213                        hitToSimTracksterMapTokens_.end(),
0214                        [&simTracksterToken](const auto& pair) { return pair.first == simTracksterToken.first; });
0215       if (simTracksterMapTokenIter != hitToSimTracksterMapTokens_.end()) {
0216         iEvent.getByToken(simTracksterMapTokenIter->second, hitToSimTracksterMapHandle);
0217       }
0218       const auto& hitToSimTracksterMap = *hitToSimTracksterMapHandle;
0219 
0220       // Retrieve the correct SimTracksterToHitMap for the current simTrackster collection
0221       Handle<ticl::AssociationMap<ticl::mapWithFraction>> simTracksterToHitMapHandle;
0222       auto simTracksterToHitMapTokenIter =
0223           std::find_if(simTracksterToHitMapTokens_.begin(),
0224                        simTracksterToHitMapTokens_.end(),
0225                        [&simTracksterToken](const auto& pair) { return pair.first == simTracksterToken.first; });
0226       if (simTracksterToHitMapTokenIter != simTracksterToHitMapTokens_.end()) {
0227         iEvent.getByToken(simTracksterToHitMapTokenIter->second, simTracksterToHitMapHandle);
0228       }
0229       const auto& simTracksterToHitMap = *simTracksterToHitMapHandle;
0230 
0231       // Create the association maps
0232       auto tracksterToSimTracksterMap = std::make_unique<ticl::AssociationMap<ticl::mapWithSharedEnergyAndScore,
0233                                                                               std::vector<ticl::Trackster>,
0234                                                                               std::vector<ticl::Trackster>>>(
0235           recoTrackstersHandle, simTrackstersHandle, iEvent);
0236       auto simTracksterToTracksterMap = std::make_unique<ticl::AssociationMap<ticl::mapWithSharedEnergyAndScore,
0237                                                                               std::vector<ticl::Trackster>,
0238                                                                               std::vector<ticl::Trackster>>>(
0239           simTrackstersHandle, recoTrackstersHandle, iEvent);
0240 
0241       for (unsigned int tracksterIndex = 0; tracksterIndex < recoTracksters.size(); ++tracksterIndex) {
0242         edm::Ref<std::vector<ticl::Trackster>> recoTracksterRef(recoTrackstersHandle, tracksterIndex);
0243         float recoToSimScoresDenominator = 0.f;
0244         const auto& recoTracksterHitsAndFractions = tracksterToHitMap[tracksterIndex];
0245         ticl::AssociationMap<ticl::mapWithFraction> hitToAssociatedSimTracksterMap(
0246             recoTracksterHitsAndFractions.size());
0247         std::vector<unsigned int> associatedSimTracksterIndices;
0248         for (unsigned int i = 0; i < recoTracksterHitsAndFractions.size(); ++i) {
0249           const auto& hitElement = recoTracksterHitsAndFractions[i];
0250           unsigned int hitIndex = hitElement.index();
0251           float recoFraction = hitElement.fraction();
0252           const auto& recHit = rechitManager[hitIndex];
0253           float squaredRecoFraction = recoFraction * recoFraction;
0254           float rechitEnergy = recHit.energy();
0255           float squaredRecHitEnergy = rechitEnergy * rechitEnergy;
0256           recoToSimScoresDenominator += squaredRecoFraction * squaredRecHitEnergy;
0257 
0258           const auto& hitToSimTracksterVec = hitToSimTracksterMap[hitIndex];
0259           for (const auto& simTracksterElement : hitToSimTracksterVec) {
0260             auto simTracksterIndex = simTracksterElement.index();
0261             const auto& simTrackster = simTracksters[simTracksterIndex];
0262             auto& seed = simTrackster.seedID();
0263             float simFraction = 0;
0264             if (seed == caloParticlesHandle.id()) {
0265               unsigned int caloParticleIndex = simTrackster.seedIndex();
0266               auto it =
0267                   std::find_if(hitToCaloParticleMap[hitIndex].begin(),
0268                                hitToCaloParticleMap[hitIndex].end(),
0269                                [caloParticleIndex](const auto& pair) { return pair.index() == caloParticleIndex; });
0270               if (it != hitToCaloParticleMap[hitIndex].end()) {
0271                 simFraction = it->fraction();
0272               }
0273             } else {
0274               unsigned int simClusterIndex = simTracksters[simTracksterIndex].seedIndex();
0275               auto it = std::find_if(hitToSimClusterMap[hitIndex].begin(),
0276                                      hitToSimClusterMap[hitIndex].end(),
0277                                      [simClusterIndex](const auto& pair) { return pair.index() == simClusterIndex; });
0278               if (it != hitToSimClusterMap[hitIndex].end()) {
0279                 simFraction = it->fraction();
0280               }
0281             }
0282             hitToAssociatedSimTracksterMap.insert(i, simTracksterIndex, simFraction);
0283             associatedSimTracksterIndices.push_back(simTracksterIndex);
0284           }
0285         }
0286         std::sort(associatedSimTracksterIndices.begin(), associatedSimTracksterIndices.end());
0287         associatedSimTracksterIndices.erase(
0288             std::unique(associatedSimTracksterIndices.begin(), associatedSimTracksterIndices.end()),
0289             associatedSimTracksterIndices.end());
0290 
0291         // Add missing sim tracksters with 0 shared energy to hitToAssociatedSimTracksterMap
0292         for (unsigned int i = 0; i < recoTracksterHitsAndFractions.size(); ++i) {
0293           unsigned int hitId = recoTracksterHitsAndFractions[i].index();
0294           const auto& simTracksterVec = hitToSimTracksterMap[hitId];
0295           for (unsigned int simTracksterIndex : associatedSimTracksterIndices) {
0296             if (std::find_if(simTracksterVec.begin(), simTracksterVec.end(), [simTracksterIndex](const auto& pair) {
0297                   return pair.index() == simTracksterIndex;
0298                 }) == simTracksterVec.end()) {
0299               hitToAssociatedSimTracksterMap.insert(i, simTracksterIndex, 0);
0300             }
0301           }
0302         }
0303 
0304         const float invDenominator = 1.f / recoToSimScoresDenominator;
0305 
0306         for (unsigned int i = 0; i < recoTracksterHitsAndFractions.size(); ++i) {
0307           unsigned int hitIndex = recoTracksterHitsAndFractions[i].index();
0308           const auto& recHit = rechitManager[hitIndex];
0309           float recoFraction = recoTracksterHitsAndFractions[i].fraction();
0310           float squaredRecoFraction = recoFraction * recoFraction;
0311           float rechitEnergy = recHit.energy();
0312           float squaredRecHitEnergy = rechitEnergy * rechitEnergy;
0313           float recoSharedEnergy = rechitEnergy * recoFraction;
0314           const auto& simTracksterVec = hitToAssociatedSimTracksterMap[i];
0315           for (const auto& simTracksterElement : simTracksterVec) {
0316             auto simTracksterIndex = simTracksterElement.index();
0317             auto simFraction = simTracksterElement.fraction();
0318             edm::Ref<std::vector<ticl::Trackster>> simTracksterRef(simTrackstersHandle, simTracksterIndex);
0319             float sharedEnergy = std::min(simFraction * rechitEnergy, recoSharedEnergy);
0320             float squaredFraction =
0321                 std::min(squaredRecoFraction, (recoFraction - simFraction) * (recoFraction - simFraction));
0322             float score = invDenominator * squaredFraction * squaredRecHitEnergy;
0323             tracksterToSimTracksterMap->insert(recoTracksterRef, simTracksterRef, sharedEnergy, score);
0324           }
0325         }
0326       }
0327 
0328       // Reverse mapping: SimTrackster -> RecoTrackster
0329       for (unsigned int tracksterIndex = 0; tracksterIndex < simTracksters.size(); ++tracksterIndex) {
0330         edm::Ref<std::vector<ticl::Trackster>> simTracksterRef(simTrackstersHandle, tracksterIndex);
0331         float simToRecoScoresDenominator = 0.f;
0332         const auto& simTracksterHitsAndFractions = simTracksterToHitMap[tracksterIndex];
0333         ticl::AssociationMap<ticl::mapWithFraction> hitToAssociatedRecoTracksterMap(
0334             simTracksterHitsAndFractions.size());
0335         std::vector<unsigned int> associatedRecoTracksterIndices;
0336         const auto& simTrackster = simTracksters[tracksterIndex];
0337         auto& seed = simTrackster.seedID();
0338         unsigned int simObjectIndex = simTrackster.seedIndex();
0339         bool isSimTracksterFromCP = (seed == caloParticlesHandle.id());
0340         std::vector<float> simFractions(simTracksterHitsAndFractions.size(), 0.f);
0341         for (unsigned int i = 0; i < simTracksterHitsAndFractions.size(); ++i) {
0342           auto hitIndex = simTracksterHitsAndFractions[i].index();
0343           auto it = isSimTracksterFromCP
0344                         ? (std::find_if(hitToCaloParticleMap[hitIndex].begin(),
0345                                         hitToCaloParticleMap[hitIndex].end(),
0346                                         [simObjectIndex](const auto& pair) { return pair.index() == simObjectIndex; }))
0347                         : std::find_if(hitToSimClusterMap[hitIndex].begin(),
0348                                        hitToSimClusterMap[hitIndex].end(),
0349                                        [simObjectIndex](const auto& pair) { return pair.index() == simObjectIndex; });
0350           if ((isSimTracksterFromCP and it != hitToCaloParticleMap[hitIndex].end()) or
0351               (!isSimTracksterFromCP and it != hitToSimClusterMap[hitIndex].end())) {
0352             simFractions[i] = it->fraction();
0353           }
0354           float simFraction = simFractions[i];
0355           const auto& recHit = rechitManager[hitIndex];
0356           float rechitEnergy = recHit.energy();
0357           float squaredSimFraction = simFraction * simFraction;
0358           float squaredRecHitEnergy = rechitEnergy * rechitEnergy;
0359           simToRecoScoresDenominator += squaredSimFraction * squaredRecHitEnergy;
0360           const auto& hitToRecoTracksterVec = hitToTracksterMap[hitIndex];
0361           for (const auto& recoTracksterElement : hitToRecoTracksterVec) {
0362             unsigned int recoTracksterIndex = recoTracksterElement.index();
0363             float recoFraction = recoTracksterElement.fraction();
0364             hitToAssociatedRecoTracksterMap.insert(i, recoTracksterIndex, recoFraction);
0365             associatedRecoTracksterIndices.push_back(recoTracksterIndex);
0366           }
0367         }
0368 
0369         std::sort(associatedRecoTracksterIndices.begin(), associatedRecoTracksterIndices.end());
0370         associatedRecoTracksterIndices.erase(
0371             std::unique(associatedRecoTracksterIndices.begin(), associatedRecoTracksterIndices.end()),
0372             associatedRecoTracksterIndices.end());
0373 
0374         for (unsigned int i = 0; i < simTracksterHitsAndFractions.size(); ++i) {
0375           unsigned int hitIndex = simTracksterHitsAndFractions[i].index();
0376           const auto& hitToRecoTracksterVec = hitToTracksterMap[hitIndex];
0377           for (unsigned int recoTracksterIndex : associatedRecoTracksterIndices) {
0378             if (std::find_if(
0379                     hitToRecoTracksterVec.begin(), hitToRecoTracksterVec.end(), [recoTracksterIndex](const auto& pair) {
0380                       return pair.index() == recoTracksterIndex;
0381                     }) == hitToRecoTracksterVec.end()) {
0382               hitToAssociatedRecoTracksterMap.insert(i, recoTracksterIndex, 0);
0383             }
0384           }
0385         }
0386 
0387         assert(simToRecoScoresDenominator > 0.f);
0388         const float invDenominator = 1.f / simToRecoScoresDenominator;
0389         for (unsigned int i = 0; i < simTracksterHitsAndFractions.size(); ++i) {
0390           const auto& hitIndex = simTracksterHitsAndFractions[i].index();
0391           float simFraction = simFractions[i];
0392           const auto& recHit = rechitManager[hitIndex];
0393           float rechitEnergy = recHit.energy();
0394           float squaredSimFraction = simFraction * simFraction;
0395           float squaredRecHitEnergy = rechitEnergy * rechitEnergy;
0396           float simSharedEnergy = rechitEnergy * simFraction;
0397           const auto& hitToRecoTracksterVec = hitToAssociatedRecoTracksterMap[i];
0398           for (const auto& recoTracksterElement : hitToRecoTracksterVec) {
0399             auto recoTracksterIndex = recoTracksterElement.index();
0400             float recoFraction = recoTracksterElement.fraction();
0401             edm::Ref<std::vector<ticl::Trackster>> recoTracksterRef(recoTrackstersHandle, recoTracksterIndex);
0402             float sharedEnergy = std::min(recoFraction * rechitEnergy, simSharedEnergy);
0403             float squaredFraction =
0404                 std::min(squaredSimFraction, (recoFraction - simFraction) * (recoFraction - simFraction));
0405             float score = invDenominator * squaredFraction * squaredRecHitEnergy;
0406             simTracksterToTracksterMap->insert(simTracksterRef, recoTracksterRef, sharedEnergy, score);
0407           }
0408         }
0409       }
0410 
0411       auto sortingFunc = [](const auto& a, const auto& b) {
0412         if (a.score() != b.score())
0413           return a.score() < b.score();
0414         else
0415           return a.index() < b.index();
0416       };
0417 
0418       // Sort the maps by score in ascending order
0419       tracksterToSimTracksterMap->sort(sortingFunc);
0420       simTracksterToTracksterMap->sort(sortingFunc);
0421 
0422       // After populating the maps, store them in the event
0423       iEvent.put(std::move(tracksterToSimTracksterMap), tracksterToken.first + "To" + simTracksterToken.first);
0424       iEvent.put(std::move(simTracksterToTracksterMap), simTracksterToken.first + "To" + tracksterToken.first);
0425     }
0426   }
0427 }
0428 
0429 void AllTracksterToSimTracksterAssociatorsByHitsProducer::fillDescriptions(
0430     edm::ConfigurationDescriptions& descriptions) {
0431   edm::ParameterSetDescription desc;
0432   desc.add<std::string>("allHitToTSAccoc", "allHitToTracksterAssociations");
0433   desc.add<std::vector<edm::InputTag>>(
0434       "tracksterCollections", {edm::InputTag("ticlTrackstersCLUE3DHigh"), edm::InputTag("ticlTrackstersLinks")});
0435   desc.add<std::vector<edm::InputTag>>(
0436       "simTracksterCollections", {edm::InputTag("ticlSimTracksters"), edm::InputTag("ticlSimTracksters", "fromCPs")});
0437   desc.add<std::vector<edm::InputTag>>("hits",
0438                                        {edm::InputTag("HGCalRecHit", "HGCEERecHits"),
0439                                         edm::InputTag("HGCalRecHit", "HGCHEFRecHits"),
0440                                         edm::InputTag("HGCalRecHit", "HGCHEBRecHits")});
0441   desc.add<edm::InputTag>("hitToSimClusterMap",
0442                           edm::InputTag("hitToSimClusterCaloParticleAssociator", "hitToSimClusterMap"));
0443   desc.add<edm::InputTag>("hitToCaloParticleMap",
0444                           edm::InputTag("hitToSimClusterCaloParticleAssociator", "hitToCaloParticleMap"));
0445   desc.add<edm::InputTag>("caloParticles", edm::InputTag("mix", "MergedCaloTruth"));
0446 
0447   descriptions.add("AllTracksterToSimTracksterAssociatorsByHitsProducer", desc);
0448 }
0449 
0450 // Define this as a plug-in
0451 DEFINE_FWK_MODULE(AllTracksterToSimTracksterAssociatorsByHitsProducer);