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 "FWCore/Framework/interface/ESHandle.h"
0013 #include "DataFormats/CaloRecHit/interface/CaloCluster.h"
0014 
0015 class AllTracksterToSimTracksterAssociatorsByLCsProducer : public edm::global::EDProducer<> {
0016 public:
0017   explicit AllTracksterToSimTracksterAssociatorsByLCsProducer(const edm::ParameterSet&);
0018   ~AllTracksterToSimTracksterAssociatorsByLCsProducer() override = default;
0019 
0020   static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
0021 
0022 private:
0023   void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
0024 
0025   std::vector<std::pair<std::string, edm::EDGetTokenT<std::vector<ticl::Trackster>>>> tracksterCollectionTokens_;
0026   std::vector<std::pair<std::string, edm::EDGetTokenT<std::vector<ticl::Trackster>>>> simTracksterCollectionTokens_;
0027   edm::EDGetTokenT<std::vector<reco::CaloCluster>> layerClustersToken_;
0028   std::vector<std::pair<
0029       std::string,
0030       edm::EDGetTokenT<
0031           ticl::AssociationMap<ticl::mapWithSharedEnergy, std::vector<reco::CaloCluster>, std::vector<ticl::Trackster>>>>>
0032       layerClusterToTracksterMapTokens_;
0033   std::vector<std::pair<
0034       std::string,
0035       edm::EDGetTokenT<
0036           ticl::AssociationMap<ticl::mapWithSharedEnergy, std::vector<reco::CaloCluster>, std::vector<ticl::Trackster>>>>>
0037       layerClusterToSimTracksterMapTokens_;
0038 };
0039 
0040 AllTracksterToSimTracksterAssociatorsByLCsProducer::AllTracksterToSimTracksterAssociatorsByLCsProducer(
0041     const edm::ParameterSet& pset)
0042     : layerClustersToken_(consumes<std::vector<reco::CaloCluster>>(pset.getParameter<edm::InputTag>("layerClusters"))) {
0043   const auto& tracksterCollections = pset.getParameter<std::vector<edm::InputTag>>("tracksterCollections");
0044 
0045   std::string allLCtoTSAccoc = pset.getParameter<std::string>("allLCtoTSAccoc");
0046   for (const auto& tag : tracksterCollections) {
0047     std::string label = tag.label();
0048     if (!tag.instance().empty()) {
0049       label += tag.instance();
0050     }
0051     tracksterCollectionTokens_.emplace_back(label, consumes<std::vector<ticl::Trackster>>(tag));
0052     layerClusterToTracksterMapTokens_.emplace_back(
0053         label,
0054         consumes<ticl::AssociationMap<ticl::mapWithSharedEnergy,
0055                                       std::vector<reco::CaloCluster>,
0056                                       std::vector<ticl::Trackster>>>(edm::InputTag(allLCtoTSAccoc, label)));
0057   }
0058 
0059   const auto& simTracksterCollections = pset.getParameter<std::vector<edm::InputTag>>("simTracksterCollections");
0060   for (const auto& tag : simTracksterCollections) {
0061     std::string label = tag.label();
0062     if (!tag.instance().empty()) {
0063       label += tag.instance();
0064     }
0065     simTracksterCollectionTokens_.emplace_back(label, consumes<std::vector<ticl::Trackster>>(tag));
0066     layerClusterToSimTracksterMapTokens_.emplace_back(
0067         label,
0068         consumes<ticl::AssociationMap<ticl::mapWithSharedEnergy,
0069                                       std::vector<reco::CaloCluster>,
0070                                       std::vector<ticl::Trackster>>>(edm::InputTag(allLCtoTSAccoc, label)));
0071   }
0072 
0073   // Produce separate association maps for each trackster-simTrackster combination
0074   for (const auto& tracksterToken : tracksterCollectionTokens_) {
0075     for (const auto& simTracksterToken : simTracksterCollectionTokens_) {
0076       std::string instanceLabel = tracksterToken.first + "To" + simTracksterToken.first;
0077       produces<ticl::AssociationMap<ticl::mapWithSharedEnergyAndScore,
0078                                     std::vector<ticl::Trackster>,
0079                                     std::vector<ticl::Trackster>>>(instanceLabel);
0080       std::string reverseInstanceLabel = simTracksterToken.first + "To" + tracksterToken.first;
0081       produces<ticl::AssociationMap<ticl::mapWithSharedEnergyAndScore,
0082                                     std::vector<ticl::Trackster>,
0083                                     std::vector<ticl::Trackster>>>(reverseInstanceLabel);
0084     }
0085   }
0086 }
0087 
0088 void AllTracksterToSimTracksterAssociatorsByLCsProducer::produce(edm::StreamID,
0089                                                                  edm::Event& iEvent,
0090                                                                  const edm::EventSetup&) const {
0091   using namespace edm;
0092 
0093   // Retrieve layer clusters with protection
0094   const auto& layerClustersHandle = iEvent.getHandle(layerClustersToken_);
0095 
0096   // If layer clusters are missing, produce empty maps and return
0097   if (!layerClustersHandle.isValid()) {
0098     edm::LogWarning("MissingInput") << "Layer clusters collection not found. Producing empty maps.";
0099     for (const auto& tracksterToken : tracksterCollectionTokens_) {
0100       for (const auto& simTracksterToken : simTracksterCollectionTokens_) {
0101         iEvent.put(std::make_unique<ticl::AssociationMap<ticl::mapWithSharedEnergyAndScore,
0102                                                          std::vector<ticl::Trackster>,
0103                                                          std::vector<ticl::Trackster>>>(),
0104                    tracksterToken.first + "To" + simTracksterToken.first);
0105 
0106         iEvent.put(std::make_unique<ticl::AssociationMap<ticl::mapWithSharedEnergyAndScore,
0107                                                          std::vector<ticl::Trackster>,
0108                                                          std::vector<ticl::Trackster>>>(),
0109                    simTracksterToken.first + "To" + tracksterToken.first);
0110       }
0111     }
0112     return;
0113   }
0114 
0115   const auto& layerClusters = *layerClustersHandle;
0116 
0117   for (const auto& tracksterToken : tracksterCollectionTokens_) {
0118     Handle<std::vector<ticl::Trackster>> recoTrackstersHandle;
0119     iEvent.getByToken(tracksterToken.second, recoTrackstersHandle);
0120 
0121     if (!recoTrackstersHandle.isValid()) {
0122       edm::LogWarning("MissingInput") << "trackster  collection not found. Producing empty maps.";
0123       for (const auto& simTracksterToken : simTracksterCollectionTokens_) {
0124         iEvent.put(std::make_unique<ticl::AssociationMap<ticl::mapWithSharedEnergyAndScore,
0125                                                          std::vector<ticl::Trackster>,
0126                                                          std::vector<ticl::Trackster>>>(),
0127                    tracksterToken.first + "To" + simTracksterToken.first);
0128 
0129         iEvent.put(std::make_unique<ticl::AssociationMap<ticl::mapWithSharedEnergyAndScore,
0130                                                          std::vector<ticl::Trackster>,
0131                                                          std::vector<ticl::Trackster>>>(),
0132                    simTracksterToken.first + "To" + tracksterToken.first);
0133       }
0134       return;
0135     }
0136 
0137     const auto& recoTracksters = *recoTrackstersHandle;
0138 
0139     // Retrieve the correct LayerClusterToTracksterMap for the current trackster collection
0140     Handle<ticl::AssociationMap<ticl::mapWithSharedEnergy, std::vector<reco::CaloCluster>, std::vector<ticl::Trackster>>>
0141         layerClusterToTracksterMapHandle;
0142     auto tracksterMapTokenIter =
0143         std::find_if(layerClusterToTracksterMapTokens_.begin(),
0144                      layerClusterToTracksterMapTokens_.end(),
0145                      [&tracksterToken](const auto& pair) { return pair.first == tracksterToken.first; });
0146     if (tracksterMapTokenIter != layerClusterToTracksterMapTokens_.end()) {
0147       iEvent.getByToken(tracksterMapTokenIter->second, layerClusterToTracksterMapHandle);
0148     }
0149     const auto& layerClusterToTracksterMap = *layerClusterToTracksterMapHandle;
0150 
0151     for (const auto& simTracksterToken : simTracksterCollectionTokens_) {
0152       Handle<std::vector<ticl::Trackster>> simTrackstersHandle;
0153       iEvent.getByToken(simTracksterToken.second, simTrackstersHandle);
0154       const auto& simTracksters = *simTrackstersHandle;
0155 
0156       // Retrieve the correct LayerClusterToSimTracksterMap for the current simTrackster collection
0157       Handle<
0158           ticl::AssociationMap<ticl::mapWithSharedEnergy, std::vector<reco::CaloCluster>, std::vector<ticl::Trackster>>>
0159           layerClusterToSimTracksterMapHandle;
0160       auto simTracksterMapTokenIter =
0161           std::find_if(layerClusterToSimTracksterMapTokens_.begin(),
0162                        layerClusterToSimTracksterMapTokens_.end(),
0163                        [&simTracksterToken](const auto& pair) { return pair.first == simTracksterToken.first; });
0164       if (simTracksterMapTokenIter != layerClusterToSimTracksterMapTokens_.end()) {
0165         iEvent.getByToken(simTracksterMapTokenIter->second, layerClusterToSimTracksterMapHandle);
0166       }
0167       const auto& layerClusterToSimTracksterMap = *layerClusterToSimTracksterMapHandle;
0168 
0169       // Create the association maps
0170       auto tracksterToSimTracksterMap = std::make_unique<ticl::AssociationMap<ticl::mapWithSharedEnergyAndScore,
0171                                                                               std::vector<ticl::Trackster>,
0172                                                                               std::vector<ticl::Trackster>>>(
0173           recoTrackstersHandle, simTrackstersHandle, iEvent);
0174       auto simTracksterToTracksterMap = std::make_unique<ticl::AssociationMap<ticl::mapWithSharedEnergyAndScore,
0175                                                                               std::vector<ticl::Trackster>,
0176                                                                               std::vector<ticl::Trackster>>>(
0177           simTrackstersHandle, recoTrackstersHandle, iEvent);
0178 
0179       for (unsigned int tracksterIndex = 0; tracksterIndex < recoTracksters.size(); ++tracksterIndex) {
0180         const auto& recoTrackster = recoTracksters[tracksterIndex];
0181         edm::Ref<std::vector<ticl::Trackster>> recoTracksterRef(recoTrackstersHandle, tracksterIndex);
0182         const auto& layerClustersIds = recoTrackster.vertices();
0183         float recoToSimScoresDenominator = 0.f;
0184         ticl::AssociationMap<ticl::mapWithSharedEnergy> layerClusterToAssociatedSimTracksterMap(
0185             layerClustersIds.size());
0186         std::vector<unsigned int> associatedSimTracksterIndices;
0187         for (unsigned int i = 0; i < layerClustersIds.size(); ++i) {
0188           unsigned int layerClusterId = layerClustersIds[i];
0189           const auto& layerCluster = layerClusters[layerClusterId];
0190           float recoFraction = 1.f / recoTrackster.vertex_multiplicity(i);
0191           float squaredRecoFraction = recoFraction * recoFraction;
0192           float squaredLayerClusterEnergy = layerCluster.energy() * layerCluster.energy();
0193           recoToSimScoresDenominator += squaredLayerClusterEnergy * squaredRecoFraction;
0194           const auto& simTracksterVec = layerClusterToSimTracksterMap[layerClusterId];
0195           for (const auto& simTracksterElement : simTracksterVec) {
0196             auto simTracksterIndex = simTracksterElement.index();
0197             auto simSharedEnergy = simTracksterElement.sharedEnergy();
0198             layerClusterToAssociatedSimTracksterMap[i].emplace_back(simTracksterIndex, simSharedEnergy);
0199             associatedSimTracksterIndices.push_back(simTracksterIndex);
0200           }
0201         }
0202 
0203         // Keep only unique associatedSimTracksterIndices
0204         std::sort(associatedSimTracksterIndices.begin(), associatedSimTracksterIndices.end());
0205         associatedSimTracksterIndices.erase(
0206             std::unique(associatedSimTracksterIndices.begin(), associatedSimTracksterIndices.end()),
0207             associatedSimTracksterIndices.end());
0208 
0209         // Add missing sim tracksters with 0 shared energy to layerClusterToAssociatedSimTracksterMap
0210         for (unsigned int i = 0; i < layerClustersIds.size(); ++i) {
0211           unsigned int layerClusterId = layerClustersIds[i];
0212           const auto& simTracksterVec = layerClusterToSimTracksterMap[layerClusterId];
0213           for (unsigned int simTracksterIndex : associatedSimTracksterIndices) {
0214             if (std::find_if(simTracksterVec.begin(), simTracksterVec.end(), [simTracksterIndex](const auto& pair) {
0215                   return pair.index() == simTracksterIndex;
0216                 }) == simTracksterVec.end()) {
0217               layerClusterToAssociatedSimTracksterMap[i].push_back({simTracksterIndex, 0.f});
0218             }
0219           }
0220         }
0221 
0222         const float invDenominator = 1.f / recoToSimScoresDenominator;
0223 
0224         for (unsigned int i = 0; i < layerClustersIds.size(); ++i) {
0225           unsigned int layerClusterId = layerClustersIds[i];
0226           const auto& layerCluster = layerClusters[layerClusterId];
0227           float recoFraction = 1.f / recoTrackster.vertex_multiplicity(i);
0228           float squaredRecoFraction = recoFraction * recoFraction;
0229           float squaredLayerClusterEnergy = layerCluster.energy() * layerCluster.energy();
0230           float recoSharedEnergy = layerCluster.energy() * recoFraction;
0231           float invLayerClusterEnergy = 1.f / layerCluster.energy();
0232           const auto& simTracksterVec = layerClusterToAssociatedSimTracksterMap[i];
0233           for (const auto& simTracksterElement : simTracksterVec) {
0234             auto simTracksterIndex = simTracksterElement.index();
0235             float simSharedEnergy = simTracksterElement.sharedEnergy();
0236             edm::Ref<std::vector<ticl::Trackster>> simTracksterRef(simTrackstersHandle, simTracksterIndex);
0237             float sharedEnergy = std::min(simSharedEnergy, recoSharedEnergy);
0238             float simFraction = simSharedEnergy * invLayerClusterEnergy;
0239             float score = invDenominator *
0240                           std::min(squaredRecoFraction, (recoFraction - simFraction) * (recoFraction - simFraction)) *
0241                           squaredLayerClusterEnergy;
0242             tracksterToSimTracksterMap->insert(recoTracksterRef, simTracksterRef, sharedEnergy, score);
0243           }
0244         }
0245       }
0246 
0247       for (unsigned int tracksterIndex = 0; tracksterIndex < simTracksters.size(); ++tracksterIndex) {
0248         const auto& simTrackster = simTracksters[tracksterIndex];
0249         edm::Ref<std::vector<ticl::Trackster>> simTracksterRef(simTrackstersHandle, tracksterIndex);
0250         const auto& layerClustersIds = simTrackster.vertices();
0251         float simToRecoScoresDenominator = 0.f;
0252         ticl::AssociationMap<ticl::mapWithSharedEnergy> layerClusterToAssociatedTracksterMap(layerClustersIds.size());
0253         std::vector<unsigned int> associatedRecoTracksterIndices;
0254         for (unsigned int i = 0; i < layerClustersIds.size(); ++i) {
0255           unsigned int layerClusterId = layerClustersIds[i];
0256           const auto& layerCluster = layerClusters[layerClusterId];
0257           float simFraction = 1.f / simTrackster.vertex_multiplicity(i);
0258           float squaredSimFraction = simFraction * simFraction;
0259           float squaredLayerClusterEnergy = layerCluster.energy() * layerCluster.energy();
0260           simToRecoScoresDenominator += squaredLayerClusterEnergy * squaredSimFraction;
0261           const auto& recoTracksterVec = layerClusterToTracksterMap[layerClusterId];
0262           for (const auto& recoTracksterElement : recoTracksterVec) {
0263             auto recoTracksterIndex = recoTracksterElement.index();
0264             auto recoSharedEnergy = recoTracksterElement.sharedEnergy();
0265             layerClusterToAssociatedTracksterMap[i].emplace_back(recoTracksterIndex, recoSharedEnergy);
0266             associatedRecoTracksterIndices.push_back(recoTracksterIndex);
0267           }
0268         }
0269         // keep only unique associatedRecoTracksterIndices
0270         std::sort(associatedRecoTracksterIndices.begin(), associatedRecoTracksterIndices.end());
0271         associatedRecoTracksterIndices.erase(
0272             std::unique(associatedRecoTracksterIndices.begin(), associatedRecoTracksterIndices.end()),
0273             associatedRecoTracksterIndices.end());
0274         // for each layer cluster, loop over associatedRecoTracksterIndices and add the missing reco tracksters with 0 shared energy to layerClusterToAssociatedTracksterMap
0275         for (unsigned int i = 0; i < layerClustersIds.size(); ++i) {
0276           unsigned int layerClusterId = layerClustersIds[i];
0277           const auto& recoTracksterVec = layerClusterToTracksterMap[layerClusterId];
0278           for (unsigned int recoTracksterIndex : associatedRecoTracksterIndices) {
0279             if (std::find_if(recoTracksterVec.begin(), recoTracksterVec.end(), [recoTracksterIndex](const auto& pair) {
0280                   return pair.index() == recoTracksterIndex;
0281                 }) == recoTracksterVec.end()) {
0282               layerClusterToAssociatedTracksterMap[i].emplace_back(recoTracksterIndex, 0.f);
0283             }
0284           }
0285         }
0286         assert(simToRecoScoresDenominator > 0.f);
0287         const float invDenominator = 1.f / simToRecoScoresDenominator;
0288 
0289         for (unsigned int i = 0; i < layerClustersIds.size(); ++i) {
0290           unsigned int layerClusterId = layerClustersIds[i];
0291           const auto& layerCluster = layerClusters[layerClusterId];
0292           float simFraction = 1.f / simTrackster.vertex_multiplicity(i);
0293           float squaredSimFraction = simFraction * simFraction;
0294           float squaredLayerClusterEnergy = layerCluster.energy() * layerCluster.energy();
0295           float simSharedEnergy = layerCluster.energy() * simFraction;
0296           float invLayerClusterEnergy = 1.f / layerCluster.energy();
0297           const auto& recoTracksterVec = layerClusterToAssociatedTracksterMap[i];
0298           for (const auto& recoTracksterElement : recoTracksterVec) {
0299             auto recoTracksterIndex = recoTracksterElement.index();
0300             float recoSharedEnergy = recoTracksterElement.sharedEnergy();
0301             edm::Ref<std::vector<ticl::Trackster>> recoTracksterRef(recoTrackstersHandle, recoTracksterIndex);
0302             float sharedEnergy = std::min(recoSharedEnergy, simSharedEnergy);
0303             float recoFraction = recoSharedEnergy * invLayerClusterEnergy;
0304             float score = invDenominator *
0305                           std::min(squaredSimFraction, (simFraction - recoFraction) * (simFraction - recoFraction)) *
0306                           squaredLayerClusterEnergy;
0307             simTracksterToTracksterMap->insert(tracksterIndex, recoTracksterIndex, sharedEnergy, score);
0308           }
0309         }
0310       }
0311       auto sortingFunc = [](const auto& a, const auto& b) {
0312         if (a.score() != b.score())
0313           return a.score() < b.score();
0314         else
0315           return a.index() < b.index();
0316       };
0317 
0318       // Sort the maps by score in ascending order
0319       tracksterToSimTracksterMap->sort(sortingFunc);
0320       simTracksterToTracksterMap->sort(sortingFunc);
0321 
0322       // After populating the maps, store them in the event
0323       iEvent.put(std::move(tracksterToSimTracksterMap), tracksterToken.first + "To" + simTracksterToken.first);
0324       iEvent.put(std::move(simTracksterToTracksterMap), simTracksterToken.first + "To" + tracksterToken.first);
0325     }
0326   }
0327 }
0328 
0329 void AllTracksterToSimTracksterAssociatorsByLCsProducer::fillDescriptions(edm::ConfigurationDescriptions& descriptions) {
0330   edm::ParameterSetDescription desc;
0331   desc.add<std::string>("allLCtoTSAccoc", "allLayerClusterToTracksterAssociations");
0332   desc.add<std::vector<edm::InputTag>>(
0333       "tracksterCollections", {edm::InputTag("ticlTrackstersCLUE3DHigh"), edm::InputTag("ticlTrackstersLinks")});
0334   desc.add<std::vector<edm::InputTag>>(
0335       "simTracksterCollections", {edm::InputTag("ticlSimTracksters"), edm::InputTag("ticlSimTracksters", "fromCPs")});
0336   desc.add<edm::InputTag>("layerClusters", edm::InputTag("hgcalMergeLayerClusters"));
0337   descriptions.add("AllTracksterToSimTracksterAssociatorsByLCsProducer", desc);
0338 }
0339 
0340 // Define this as a plug-in
0341 DEFINE_FWK_MODULE(AllTracksterToSimTracksterAssociatorsByLCsProducer);