CMS 3D CMS Logo

AllTracksterToSimTracksterAssociatorsByHitsProducer.cc
Go to the documentation of this file.
1 // Author: Felice Pantaleo, felice.pantaleo@cern.ch 08/2024
2 
17 
19 public:
22 
23  static void fillDescriptions(edm::ConfigurationDescriptions& descriptions);
24 
25 private:
26  void produce(edm::StreamID, edm::Event&, const edm::EventSetup&) const override;
27 
28  std::vector<std::pair<std::string, edm::EDGetTokenT<std::vector<ticl::Trackster>>>> tracksterCollectionTokens_;
29  std::vector<std::pair<std::string, edm::EDGetTokenT<std::vector<ticl::Trackster>>>> simTracksterCollectionTokens_;
31  std::vector<std::pair<std::string, edm::EDGetTokenT<ticl::AssociationMap<ticl::mapWithFraction>>>>
33  std::vector<std::pair<std::string, edm::EDGetTokenT<ticl::AssociationMap<ticl::mapWithFraction>>>>
35 
36  std::vector<std::pair<std::string, edm::EDGetTokenT<ticl::AssociationMap<ticl::mapWithFraction>>>>
38  std::vector<std::pair<std::string, edm::EDGetTokenT<ticl::AssociationMap<ticl::mapWithFraction>>>>
40 
41  std::vector<edm::EDGetTokenT<HGCRecHitCollection>> hitsTokens_;
45 };
46 
48  const edm::ParameterSet& pset)
49  : caloParticleToken_(consumes<std::vector<CaloParticle>>(pset.getParameter<edm::InputTag>("caloParticles"))),
50  hitToSimClusterMapToken_(consumes<ticl::AssociationMap<ticl::mapWithFraction>>(
51  pset.getParameter<edm::InputTag>("hitToSimClusterMap"))),
52  hitToCaloParticleMapToken_(consumes<ticl::AssociationMap<ticl::mapWithFraction>>(
53  pset.getParameter<edm::InputTag>("hitToCaloParticleMap"))) {
54  const auto& tracksterCollections = pset.getParameter<std::vector<edm::InputTag>>("tracksterCollections");
55  for (const auto& tag : tracksterCollections) {
56  std::string label = tag.label();
57  if (tag.instance() != "") {
58  label += tag.instance();
59  }
60  tracksterCollectionTokens_.emplace_back(label, consumes<std::vector<ticl::Trackster>>(tag));
61  hitToTracksterMapTokens_.emplace_back(label,
63  edm::InputTag("allHitToTracksterAssociations", "hitTo" + label)));
64  tracksterToHitMapTokens_.emplace_back(label,
66  edm::InputTag("allHitToTracksterAssociations", label + "ToHit")));
67  }
68 
69  const auto& simTracksterCollections = pset.getParameter<std::vector<edm::InputTag>>("simTracksterCollections");
70  for (const auto& tag : simTracksterCollections) {
71  std::string label = tag.label();
72  if (tag.instance() != "") {
73  label += tag.instance();
74  }
75  simTracksterCollectionTokens_.emplace_back(label, consumes<std::vector<ticl::Trackster>>(tag));
78  edm::InputTag("allHitToTracksterAssociations", "hitTo" + label)));
81  edm::InputTag("allHitToTracksterAssociations", label + "ToHit")));
82  }
83 
84  // Hits
85  auto hitsTags = pset.getParameter<std::vector<edm::InputTag>>("hits");
86  for (const auto& tag : hitsTags) {
87  hitsTokens_.push_back(consumes<HGCRecHitCollection>(tag));
88  }
89 
90  // Produce separate association maps for each trackster-simTrackster combination
91  for (const auto& tracksterToken : tracksterCollectionTokens_) {
92  for (const auto& simTracksterToken : simTracksterCollectionTokens_) {
93  std::string instanceLabel = tracksterToken.first + "To" + simTracksterToken.first;
95  std::vector<ticl::Trackster>,
96  std::vector<ticl::Trackster>>>(instanceLabel);
97  std::string reverseInstanceLabel = simTracksterToken.first + "To" + tracksterToken.first;
99  std::vector<ticl::Trackster>,
100  std::vector<ticl::Trackster>>>(reverseInstanceLabel);
101  }
102  }
103 }
104 
107  const edm::EventSetup&) const {
108  using namespace edm;
109 
110  MultiVectorManager<HGCRecHit> rechitManager;
111  for (const auto& token : hitsTokens_) {
112  Handle<HGCRecHitCollection> hitsHandle;
113  iEvent.getByToken(token, hitsHandle);
114  rechitManager.addVector(*hitsHandle);
115  }
116 
117  Handle<ticl::AssociationMap<ticl::mapWithFraction>> hitToSimClusterMapHandle;
118  iEvent.getByToken(hitToSimClusterMapToken_, hitToSimClusterMapHandle);
119  const auto& hitToSimClusterMap = *hitToSimClusterMapHandle;
120 
121  Handle<ticl::AssociationMap<ticl::mapWithFraction>> hitToCaloParticleMapHandle;
122  iEvent.getByToken(hitToCaloParticleMapToken_, hitToCaloParticleMapHandle);
123  const auto& hitToCaloParticleMap = *hitToCaloParticleMapHandle;
124 
125  Handle<std::vector<CaloParticle>> caloParticlesHandle;
126  iEvent.getByToken(caloParticleToken_, caloParticlesHandle);
127 
128  for (const auto& tracksterToken : tracksterCollectionTokens_) {
129  Handle<std::vector<ticl::Trackster>> recoTrackstersHandle;
130  iEvent.getByToken(tracksterToken.second, recoTrackstersHandle);
131  const auto& recoTracksters = *recoTrackstersHandle;
132 
133  // Retrieve the correct HitToTracksterMap for the current trackster collection
135  auto tracksterMapTokenIter = std::find_if(
136  hitToTracksterMapTokens_.begin(), hitToTracksterMapTokens_.end(), [&tracksterToken](const auto& pair) {
137  return pair.first == tracksterToken.first;
138  });
139  if (tracksterMapTokenIter != hitToTracksterMapTokens_.end()) {
140  iEvent.getByToken(tracksterMapTokenIter->second, hitToTracksterMapHandle);
141  }
142  const auto& hitToTracksterMap = *hitToTracksterMapHandle;
143 
144  // Retrieve the correct TracksterToHitMap for the current trackster collection
146  auto tracksterToHitMapTokenIter = std::find_if(
147  tracksterToHitMapTokens_.begin(), tracksterToHitMapTokens_.end(), [&tracksterToken](const auto& pair) {
148  return pair.first == tracksterToken.first;
149  });
150  if (tracksterToHitMapTokenIter != tracksterToHitMapTokens_.end()) {
151  iEvent.getByToken(tracksterToHitMapTokenIter->second, tracksterToHitMapHandle);
152  }
153  const auto& tracksterToHitMap = *tracksterToHitMapHandle;
154 
155  for (const auto& simTracksterToken : simTracksterCollectionTokens_) {
156  Handle<std::vector<ticl::Trackster>> simTrackstersHandle;
157  iEvent.getByToken(simTracksterToken.second, simTrackstersHandle);
158  const auto& simTracksters = *simTrackstersHandle;
159 
160  // Retrieve the correct HitToSimTracksterMap for the current simTrackster collection
161  Handle<ticl::AssociationMap<ticl::mapWithFraction>> hitToSimTracksterMapHandle;
162  auto simTracksterMapTokenIter =
163  std::find_if(hitToSimTracksterMapTokens_.begin(),
165  [&simTracksterToken](const auto& pair) { return pair.first == simTracksterToken.first; });
166  if (simTracksterMapTokenIter != hitToSimTracksterMapTokens_.end()) {
167  iEvent.getByToken(simTracksterMapTokenIter->second, hitToSimTracksterMapHandle);
168  }
169  const auto& hitToSimTracksterMap = *hitToSimTracksterMapHandle;
170 
171  // Retrieve the correct SimTracksterToHitMap for the current simTrackster collection
172  Handle<ticl::AssociationMap<ticl::mapWithFraction>> simTracksterToHitMapHandle;
173  auto simTracksterToHitMapTokenIter =
174  std::find_if(simTracksterToHitMapTokens_.begin(),
176  [&simTracksterToken](const auto& pair) { return pair.first == simTracksterToken.first; });
177  if (simTracksterToHitMapTokenIter != simTracksterToHitMapTokens_.end()) {
178  iEvent.getByToken(simTracksterToHitMapTokenIter->second, simTracksterToHitMapHandle);
179  }
180  const auto& simTracksterToHitMap = *simTracksterToHitMapHandle;
181 
182  // Create the association maps
183  auto tracksterToSimTracksterMap = std::make_unique<
185  recoTrackstersHandle, simTrackstersHandle, iEvent);
186  auto simTracksterToTracksterMap = std::make_unique<
188  simTrackstersHandle, recoTrackstersHandle, iEvent);
189 
190  for (unsigned int tracksterIndex = 0; tracksterIndex < recoTracksters.size(); ++tracksterIndex) {
191  edm::Ref<std::vector<ticl::Trackster>> recoTracksterRef(recoTrackstersHandle, tracksterIndex);
192  float recoToSimScoresDenominator = 0.f;
193  const auto& recoTracksterHitsAndFractions = tracksterToHitMap[tracksterIndex];
194  ticl::AssociationMap<ticl::mapWithFraction> hitToAssociatedSimTracksterMap(
195  recoTracksterHitsAndFractions.size());
196  std::vector<unsigned int> associatedSimTracksterIndices;
197  for (unsigned int i = 0; i < recoTracksterHitsAndFractions.size(); ++i) {
198  const auto& [hitIndex, recoFraction] = recoTracksterHitsAndFractions[i];
199  const auto& recHit = rechitManager[hitIndex];
200  float squaredRecoFraction = recoFraction * recoFraction;
201  float rechitEnergy = recHit.energy();
202  float squaredRecHitEnergy = rechitEnergy * rechitEnergy;
203  recoToSimScoresDenominator += squaredRecoFraction * squaredRecHitEnergy;
204 
205  const auto& hitToSimTracksterVec = hitToSimTracksterMap[hitIndex];
206  for (const auto& [simTracksterIndex, fraction] : hitToSimTracksterVec) {
207  const auto& simTrackster = simTracksters[simTracksterIndex];
208  auto& seed = simTrackster.seedID();
209  float simFraction = 0;
210  if (seed == caloParticlesHandle.id()) {
211  unsigned int caloParticleIndex = simTrackster.seedIndex();
212  auto it = std::find_if(hitToCaloParticleMap[hitIndex].begin(),
213  hitToCaloParticleMap[hitIndex].end(),
214  [caloParticleIndex](const auto& pair) { return pair.first == caloParticleIndex; });
215  if (it != hitToCaloParticleMap[hitIndex].end()) {
216  simFraction = it->second;
217  }
218  } else {
219  unsigned int simClusterIndex = simTracksters[simTracksterIndex].seedIndex();
220  auto it = std::find_if(hitToSimClusterMap[hitIndex].begin(),
221  hitToSimClusterMap[hitIndex].end(),
222  [simClusterIndex](const auto& pair) { return pair.first == simClusterIndex; });
223  if (it != hitToSimClusterMap[hitIndex].end()) {
224  simFraction = it->second;
225  }
226  }
227  hitToAssociatedSimTracksterMap.insert(i, simTracksterIndex, simFraction);
228  associatedSimTracksterIndices.push_back(simTracksterIndex);
229  }
230  }
231  std::sort(associatedSimTracksterIndices.begin(), associatedSimTracksterIndices.end());
232  associatedSimTracksterIndices.erase(
233  std::unique(associatedSimTracksterIndices.begin(), associatedSimTracksterIndices.end()),
234  associatedSimTracksterIndices.end());
235 
236  // Add missing sim tracksters with 0 shared energy to hitToAssociatedSimTracksterMap
237  for (unsigned int i = 0; i < recoTracksterHitsAndFractions.size(); ++i) {
238  unsigned int hitId = recoTracksterHitsAndFractions[i].first;
239  const auto& simTracksterVec = hitToSimTracksterMap[hitId];
240  for (unsigned int simTracksterIndex : associatedSimTracksterIndices) {
241  if (std::find_if(simTracksterVec.begin(), simTracksterVec.end(), [simTracksterIndex](const auto& pair) {
242  return pair.first == simTracksterIndex;
243  }) == simTracksterVec.end()) {
244  hitToAssociatedSimTracksterMap.insert(i, simTracksterIndex, 0);
245  }
246  }
247  }
248 
249  const float invDenominator = 1.f / recoToSimScoresDenominator;
250 
251  for (unsigned int i = 0; i < recoTracksterHitsAndFractions.size(); ++i) {
252  unsigned int hitIndex = recoTracksterHitsAndFractions[i].first;
253  const auto& recHit = rechitManager[hitIndex];
254  float recoFraction = recoTracksterHitsAndFractions[i].second;
255  float squaredRecoFraction = recoFraction * recoFraction;
256  float squaredRecHitEnergy = recHit.energy() * recHit.energy();
257  float recoSharedEnergy = recHit.energy() * recoFraction;
258  const auto& simTracksterVec = hitToAssociatedSimTracksterMap[i];
259  for (const auto& [simTracksterIndex, simFraction] : simTracksterVec) {
260  edm::Ref<std::vector<ticl::Trackster>> simTracksterRef(simTrackstersHandle, simTracksterIndex);
261  float sharedEnergy = std::min(simFraction * recHit.energy(), recoSharedEnergy);
262  float squaredFraction =
263  std::min(squaredRecoFraction, (recoFraction - simFraction) * (recoFraction - simFraction));
264  float score = invDenominator * squaredFraction * squaredRecHitEnergy;
265  tracksterToSimTracksterMap->insert(recoTracksterRef, simTracksterRef, sharedEnergy, score);
266  }
267  }
268  }
269 
270  // Reverse mapping: SimTrackster -> RecoTrackster
271  for (unsigned int tracksterIndex = 0; tracksterIndex < simTracksters.size(); ++tracksterIndex) {
272  edm::Ref<std::vector<ticl::Trackster>> simTracksterRef(simTrackstersHandle, tracksterIndex);
273  float simToRecoScoresDenominator = 0.f;
274  const auto& simTracksterHitsAndFractions = simTracksterToHitMap[tracksterIndex];
275  ticl::AssociationMap<ticl::mapWithFraction> hitToAssociatedRecoTracksterMap(
276  simTracksterHitsAndFractions.size());
277  std::vector<unsigned int> associatedRecoTracksterIndices;
278  const auto& simTrackster = simTracksters[tracksterIndex];
279  auto& seed = simTrackster.seedID();
280  unsigned int simObjectIndex = simTrackster.seedIndex();
281  bool isSimTracksterFromCP = (seed == caloParticlesHandle.id());
282  std::vector<float> simFractions(simTracksterHitsAndFractions.size(), 0.f);
283  for (unsigned int i = 0; i < simTracksterHitsAndFractions.size(); ++i) {
284  const auto& [hitIndex, simTracksterFraction] = simTracksterHitsAndFractions[i];
285 
286  auto it = isSimTracksterFromCP
287  ? (std::find_if(hitToCaloParticleMap[hitIndex].begin(),
288  hitToCaloParticleMap[hitIndex].end(),
289  [simObjectIndex](const auto& pair) { return pair.first == simObjectIndex; }))
290  : std::find_if(hitToSimClusterMap[hitIndex].begin(),
291  hitToSimClusterMap[hitIndex].end(),
292  [simObjectIndex](const auto& pair) { return pair.first == simObjectIndex; });
293  if (it != hitToCaloParticleMap[hitIndex].end() and it != hitToSimClusterMap[hitIndex].end()) {
294  simFractions[i] = it->second;
295  }
296  float simFraction = simFractions[i];
297  const auto& recHit = rechitManager[hitIndex];
298  float squaredSimFraction = simFraction * simFraction;
299  float squaredRecHitEnergy = recHit.energy() * recHit.energy();
300  simToRecoScoresDenominator += squaredSimFraction * squaredRecHitEnergy;
301 
302  const auto& hitToRecoTracksterVec = hitToTracksterMap[hitIndex];
303  for (const auto& [recoTracksterIndex, recoFraction] : hitToRecoTracksterVec) {
304  hitToAssociatedRecoTracksterMap.insert(i, recoTracksterIndex, recoFraction);
305  associatedRecoTracksterIndices.push_back(recoTracksterIndex);
306  }
307  }
308 
309  std::sort(associatedRecoTracksterIndices.begin(), associatedRecoTracksterIndices.end());
310  associatedRecoTracksterIndices.erase(
311  std::unique(associatedRecoTracksterIndices.begin(), associatedRecoTracksterIndices.end()),
312  associatedRecoTracksterIndices.end());
313 
314  for (unsigned int i = 0; i < simTracksterHitsAndFractions.size(); ++i) {
315  unsigned int hitIndex = simTracksterHitsAndFractions[i].first;
316  const auto& hitToRecoTracksterVec = hitToTracksterMap[hitIndex];
317  for (unsigned int recoTracksterIndex : associatedRecoTracksterIndices) {
318  if (std::find_if(
319  hitToRecoTracksterVec.begin(), hitToRecoTracksterVec.end(), [recoTracksterIndex](const auto& pair) {
320  return pair.first == recoTracksterIndex;
321  }) == hitToRecoTracksterVec.end()) {
322  hitToAssociatedRecoTracksterMap.insert(i, recoTracksterIndex, 0);
323  }
324  }
325  }
326 
327  const float invDenominator = 1.f / simToRecoScoresDenominator;
328 
329  for (unsigned int i = 0; i < simTracksterHitsAndFractions.size(); ++i) {
330  const auto& [hitIndex, simTracksterFraction] = simTracksterHitsAndFractions[i];
331  float simFraction = simFractions[i];
332  const auto& recHit = rechitManager[hitIndex];
333  float squaredSimFraction = simFraction * simFraction;
334  float squaredRecHitEnergy = recHit.energy() * recHit.energy();
335  float simSharedEnergy = recHit.energy() * simFraction;
336 
337  const auto& hitToRecoTracksterVec = hitToAssociatedRecoTracksterMap[i];
338  for (const auto& [recoTracksterIndex, recoFraction] : hitToRecoTracksterVec) {
339  edm::Ref<std::vector<ticl::Trackster>> recoTracksterRef(recoTrackstersHandle, recoTracksterIndex);
340  float sharedEnergy = std::min(recoFraction * recHit.energy(), simSharedEnergy);
341  float squaredFraction =
342  std::min(squaredSimFraction, (recoFraction - simFraction) * (recoFraction - simFraction));
343  float score = invDenominator * squaredFraction * squaredRecHitEnergy;
344  simTracksterToTracksterMap->insert(simTracksterRef, recoTracksterRef, sharedEnergy, score);
345  }
346  }
347  }
348 
349  tracksterToSimTracksterMap->sort(true);
350  simTracksterToTracksterMap->sort(true);
351 
352  // After populating the maps, store them in the event
353  iEvent.put(std::move(tracksterToSimTracksterMap), tracksterToken.first + "To" + simTracksterToken.first);
354  iEvent.put(std::move(simTracksterToTracksterMap), simTracksterToken.first + "To" + tracksterToken.first);
355  }
356  }
357 }
358 
360  edm::ConfigurationDescriptions& descriptions) {
362  desc.add<std::vector<edm::InputTag>>(
363  "tracksterCollections", {edm::InputTag("ticlTrackstersCLUE3DHigh"), edm::InputTag("ticlTrackstersLinks")});
364  desc.add<std::vector<edm::InputTag>>(
365  "simTracksterCollections", {edm::InputTag("ticlSimTracksters"), edm::InputTag("ticlSimTracksters", "fromCPs")});
366  desc.add<std::vector<edm::InputTag>>("hits",
367  {edm::InputTag("HGCalRecHit", "HGCEERecHits"),
368  edm::InputTag("HGCalRecHit", "HGCHEFRecHits"),
369  edm::InputTag("HGCalRecHit", "HGCHEBRecHits")});
370  desc.add<edm::InputTag>("hitToSimClusterMap",
371  edm::InputTag("hitToSimClusterCaloParticleAssociator", "hitToSimClusterMap"));
372  desc.add<edm::InputTag>("hitToCaloParticleMap",
373  edm::InputTag("hitToSimClusterCaloParticleAssociator", "hitToCaloParticleMap"));
374  desc.add<edm::InputTag>("caloParticles", edm::InputTag("mix", "MergedCaloTruth"));
375 
376  descriptions.add("AllTracksterToSimTracksterAssociatorsByHitsProducer", desc);
377 }
378 
379 // Define this as a plug-in
static void fillDescriptions(edm::ConfigurationDescriptions &descriptions)
void produce(edm::StreamID, edm::Event &, const edm::EventSetup &) const override
ProductID id() const
Definition: HandleBase.cc:29
~AllTracksterToSimTracksterAssociatorsByHitsProducer() override=default
std::vector< std::pair< std::string, edm::EDGetTokenT< ticl::AssociationMap< ticl::mapWithFraction > > > > hitToTracksterMapTokens_
std::vector< std::pair< std::string, edm::EDGetTokenT< ticl::AssociationMap< ticl::mapWithFraction > > > > simTracksterToHitMapTokens_
EDGetTokenT< ProductType > consumes(edm::InputTag const &tag)
char const * label
std::vector< std::vector< std::pair< unsigned int, float > >> mapWithFraction
int iEvent
Definition: GenABIO.cc:224
std::vector< std::pair< std::string, edm::EDGetTokenT< ticl::AssociationMap< ticl::mapWithFraction > > > > tracksterToHitMapTokens_
def unique(seq, keepstr=True)
Definition: tier0.py:24
#define DEFINE_FWK_MODULE(type)
Definition: MakerMacros.h:16
std::vector< std::pair< std::string, edm::EDGetTokenT< ticl::AssociationMap< ticl::mapWithFraction > > > > hitToSimTracksterMapTokens_
std::vector< std::vector< std::pair< unsigned int, std::pair< float, float > >> > mapWithFractionAndScore
std::vector< std::pair< std::string, edm::EDGetTokenT< std::vector< ticl::Trackster > > > > simTracksterCollectionTokens_
void add(std::string const &label, ParameterSetDescription const &psetDescription)
void addVector(std::span< const T > vec)
float sharedEnergy(reco::CaloCluster const &clu1, reco::CaloCluster const &clu2, EcalRecHitCollection const &barrelRecHits, EcalRecHitCollection const &endcapRecHits)
edm::EDGetTokenT< ticl::AssociationMap< ticl::mapWithFraction > > hitToSimClusterMapToken_
std::vector< std::pair< std::string, edm::EDGetTokenT< std::vector< ticl::Trackster > > > > tracksterCollectionTokens_
HLT enums.
Definition: Common.h:10
edm::EDGetTokenT< ticl::AssociationMap< ticl::mapWithFraction > > hitToCaloParticleMapToken_
def move(src, dest)
Definition: eostools.py:511