File indexing completed on 2024-04-06 12:31:01
0001 #include <iostream>
0002 #include <fstream>
0003 #include <type_traits>
0004 #include <typeinfo>
0005
0006 #include "QuickTrackAssociatorByHitsImpl.h"
0007
0008 #include "SimTracker/TrackerHitAssociation/interface/TrackerHitAssociator.h"
0009
0010 #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
0011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0012 #include "DataFormats/Math/interface/deltaR.h"
0013
0014 #include "SimTracker/TrackAssociation/interface/trackHitsToClusterRefs.h"
0015
0016
0017
0018
0019 namespace {
0020
0021
0022
0023
0024
0025
0026 template <class T_element>
0027 size_t collectionSize(const edm::RefToBaseVector<T_element>& collection) {
0028 return collection.size();
0029 }
0030
0031 template <class T_element>
0032 size_t collectionSize(const edm::Handle<T_element>& hCollection) {
0033 return hCollection->size();
0034 }
0035
0036 template <class T_element>
0037 size_t collectionSize(const edm::RefVector<T_element>& collection) {
0038 return collection.size();
0039 }
0040
0041 template <typename T_Track>
0042 const T_Track* getTrackAt(const edm::RefToBaseVector<T_Track>& trackCollection, size_t index) {
0043 return &*trackCollection[index];
0044 }
0045
0046 template <typename T_Coll>
0047 const auto* getTrackAt(const edm::Handle<T_Coll>& pTrackCollection, size_t index) {
0048 return &(*pTrackCollection)[index];
0049 }
0050
0051 template <typename T_Track>
0052 int numberOfValidHits(const T_Track& track) {
0053 return std::count_if(track.recHits().begin(), track.recHits().end(), [](auto const& h) { return h.isValid(); });
0054 }
0055 template <>
0056 int numberOfValidHits(const reco::Track& track) {
0057 return track.numberOfValidHits();
0058 }
0059
0060 const TrackingParticle* getTrackingParticleAt(const edm::Handle<TrackingParticleCollection>& pCollection,
0061 size_t index) {
0062 return &(*pCollection.product())[index];
0063 }
0064
0065 const TrackingParticle* getTrackingParticleAt(const edm::RefVector<TrackingParticleCollection>& collection,
0066 size_t index) {
0067 return &*collection[index];
0068 }
0069
0070 template <typename T_Track>
0071 edm::RefToBase<T_Track> getRefToTrackAt(const edm::RefToBaseVector<T_Track>& trackCollection, size_t index) {
0072 return trackCollection[index];
0073 }
0074 template <typename T_Track>
0075 edm::RefToBase<T_Track> getRefToTrackAt(const edm::Handle<edm::View<T_Track>>& pTrackCollection, size_t index) {
0076 return edm::RefToBase<T_Track>(pTrackCollection, index);
0077 }
0078 template <typename T_Track>
0079 edm::Ref<std::vector<T_Track>> getRefToTrackAt(const edm::Handle<std::vector<T_Track>>& pTrackCollection,
0080 size_t index) {
0081 return edm::Ref<std::vector<T_Track>>(pTrackCollection, index);
0082 }
0083
0084 edm::Ref<TrackingParticleCollection> getRefToTrackingParticleAt(
0085 const edm::Handle<TrackingParticleCollection>& pCollection, size_t index) {
0086 return edm::Ref<TrackingParticleCollection>(pCollection, index);
0087 }
0088
0089 edm::Ref<TrackingParticleCollection> getRefToTrackingParticleAt(
0090 const edm::RefVector<TrackingParticleCollection>& collection, size_t index) {
0091 return collection[index];
0092 }
0093
0094 void fillKeys(edm::IndexSet& keys, const edm::RefVector<TrackingParticleCollection>& collection) {
0095 keys.reserve(collection.size());
0096 for (const auto& ref : collection) {
0097 keys.insert(ref.key());
0098 }
0099 }
0100
0101 template <typename Coll>
0102 void checkClusterMapProductID(const ClusterTPAssociation& clusterToTPMap, const Coll& collection) {
0103 clusterToTPMap.checkMappedProductID(collection.id());
0104 }
0105
0106 template <typename Coll>
0107 void checkClusterMapProductID(const TrackerHitAssociator& hitAssociator, const Coll& collection) {}
0108
0109 }
0110
0111 QuickTrackAssociatorByHitsImpl::QuickTrackAssociatorByHitsImpl(edm::EDProductGetter const& productGetter,
0112 std::unique_ptr<const TrackerHitAssociator> hitAssoc,
0113 const ClusterTPAssociation* clusterToTPMap,
0114
0115 bool absoluteNumberOfHits,
0116 double qualitySimToReco,
0117 double puritySimToReco,
0118 double pixelHitWeight,
0119 double cutRecoToSim,
0120 bool threeHitTracksAreSpecial,
0121 SimToRecoDenomType simToRecoDenominator)
0122 : productGetter_(&productGetter),
0123 hitAssociator_(std::move(hitAssoc)),
0124 clusterToTPMap_(clusterToTPMap),
0125 qualitySimToReco_(qualitySimToReco),
0126 puritySimToReco_(puritySimToReco),
0127 pixelHitWeight_(pixelHitWeight),
0128 cutRecoToSim_(cutRecoToSim),
0129 simToRecoDenominator_(simToRecoDenominator),
0130 threeHitTracksAreSpecial_(threeHitTracksAreSpecial),
0131 absoluteNumberOfHits_(absoluteNumberOfHits) {}
0132
0133 reco::RecoToSimCollection QuickTrackAssociatorByHitsImpl::associateRecoToSim(
0134 const edm::Handle<edm::View<reco::Track>>& trackCollectionHandle,
0135 const edm::Handle<TrackingParticleCollection>& trackingParticleCollectionHandle) const {
0136
0137 if (not clusterToTPMap_)
0138 return associateRecoToSimImplementation<reco::RecoToSimCollection>(
0139 trackCollectionHandle, trackingParticleCollectionHandle, nullptr, *hitAssociator_);
0140 else
0141 return associateRecoToSimImplementation<reco::RecoToSimCollection>(
0142 trackCollectionHandle, trackingParticleCollectionHandle, nullptr, *clusterToTPMap_);
0143 }
0144
0145 reco::SimToRecoCollection QuickTrackAssociatorByHitsImpl::associateSimToReco(
0146 const edm::Handle<edm::View<reco::Track>>& trackCollectionHandle,
0147 const edm::Handle<TrackingParticleCollection>& trackingParticleCollectionHandle) const {
0148
0149 if (not clusterToTPMap_)
0150 return associateSimToRecoImplementation<reco::SimToRecoCollection>(
0151 trackCollectionHandle, trackingParticleCollectionHandle, nullptr, *hitAssociator_);
0152 else
0153 return associateSimToRecoImplementation<reco::SimToRecoCollection>(
0154 trackCollectionHandle, trackingParticleCollectionHandle, nullptr, *clusterToTPMap_);
0155 }
0156
0157 reco::RecoToSimCollection QuickTrackAssociatorByHitsImpl::associateRecoToSim(
0158 const edm::RefToBaseVector<reco::Track>& trackCollection,
0159 const edm::RefVector<TrackingParticleCollection>& trackingParticleCollection) const {
0160
0161 if (not clusterToTPMap_)
0162 return associateRecoToSimImplementation<reco::RecoToSimCollection>(
0163 trackCollection, trackingParticleCollection, nullptr, *hitAssociator_);
0164 else {
0165 TrackingParticleRefKeySet tpKeys;
0166 fillKeys(tpKeys, trackingParticleCollection);
0167 return associateRecoToSimImplementation<reco::RecoToSimCollection>(
0168 trackCollection, trackingParticleCollection, &tpKeys, *clusterToTPMap_);
0169 }
0170 }
0171
0172 reco::SimToRecoCollection QuickTrackAssociatorByHitsImpl::associateSimToReco(
0173 const edm::RefToBaseVector<reco::Track>& trackCollection,
0174 const edm::RefVector<TrackingParticleCollection>& trackingParticleCollection) const {
0175
0176 if (not clusterToTPMap_)
0177 return associateSimToRecoImplementation<reco::SimToRecoCollection>(
0178 trackCollection, trackingParticleCollection, nullptr, *hitAssociator_);
0179 else {
0180 TrackingParticleRefKeySet tpKeys;
0181 fillKeys(tpKeys, trackingParticleCollection);
0182 return associateSimToRecoImplementation<reco::SimToRecoCollection>(
0183 trackCollection, trackingParticleCollection, &tpKeys, *clusterToTPMap_);
0184 }
0185 }
0186
0187 template <class T_RecoToSimCollection,
0188 class T_TrackCollection,
0189 class T_TrackingParticleCollection,
0190 class T_hitOrClusterAssociator>
0191 T_RecoToSimCollection QuickTrackAssociatorByHitsImpl::associateRecoToSimImplementation(
0192 const T_TrackCollection& trackCollection,
0193 const T_TrackingParticleCollection& trackingParticleCollection,
0194 const TrackingParticleRefKeySet* trackingParticleKeys,
0195 T_hitOrClusterAssociator hitOrClusterAssociator) const {
0196 T_RecoToSimCollection returnValue(productGetter_);
0197 if (::collectionSize(trackingParticleCollection) == 0)
0198 return returnValue;
0199
0200 checkClusterMapProductID(hitOrClusterAssociator, trackingParticleCollection);
0201
0202 size_t collectionSize = ::collectionSize(trackCollection);
0203
0204 for (size_t i = 0; i < collectionSize; ++i) {
0205
0206 const auto* pTrack = ::getTrackAt(trackCollection, i);
0207
0208
0209 std::vector<std::pair<edm::Ref<TrackingParticleCollection>, double>> trackingParticleQualityPairs =
0210 associateTrack(hitOrClusterAssociator,
0211 trackingParticleCollection,
0212 trackingParticleKeys,
0213 pTrack->recHits().begin(),
0214 pTrack->recHits().end());
0215
0216
0217 for (auto iTrackingParticleQualityPair = trackingParticleQualityPairs.begin();
0218 iTrackingParticleQualityPair != trackingParticleQualityPairs.end();
0219 ++iTrackingParticleQualityPair) {
0220 const edm::Ref<TrackingParticleCollection>& trackingParticleRef = iTrackingParticleQualityPair->first;
0221 double numberOfSharedClusters = iTrackingParticleQualityPair->second;
0222 double numberOfValidTrackClusters = weightedNumberOfTrackClusters(*pTrack, hitOrClusterAssociator);
0223
0224 if (numberOfSharedClusters == 0.0)
0225 continue;
0226
0227
0228 if (abs(trackingParticleRef->pdgId()) == 11 &&
0229 (trackingParticleRef->g4Track_end() - trackingParticleRef->g4Track_begin()) > 1) {
0230 numberOfSharedClusters -= getDoubleCount(
0231 hitOrClusterAssociator, pTrack->recHits().begin(), pTrack->recHits().end(), trackingParticleRef);
0232 }
0233
0234 double quality;
0235 if (absoluteNumberOfHits_)
0236 quality = numberOfSharedClusters;
0237 else if (numberOfValidTrackClusters != 0.0)
0238 quality = numberOfSharedClusters / numberOfValidTrackClusters;
0239 else
0240 quality = 0;
0241 if (quality > cutRecoToSim_ &&
0242 !(threeHitTracksAreSpecial_ && ::numberOfValidHits(*pTrack) == 3 && numberOfSharedClusters < 3.0)) {
0243
0244 returnValue.insert(::getRefToTrackAt(trackCollection, i), std::make_pair(trackingParticleRef, quality));
0245 }
0246 }
0247 }
0248 returnValue.post_insert();
0249 return returnValue;
0250 }
0251
0252 template <class T_SimToRecoCollection,
0253 class T_TrackCollection,
0254 class T_TrackingParticleCollection,
0255 class T_hitOrClusterAssociator>
0256 T_SimToRecoCollection QuickTrackAssociatorByHitsImpl::associateSimToRecoImplementation(
0257 const T_TrackCollection& trackCollection,
0258 const T_TrackingParticleCollection& trackingParticleCollection,
0259 const TrackingParticleRefKeySet* trackingParticleKeys,
0260 T_hitOrClusterAssociator hitOrClusterAssociator) const {
0261 T_SimToRecoCollection returnValue(productGetter_);
0262 if (::collectionSize(trackingParticleCollection) == 0)
0263 return returnValue;
0264
0265 checkClusterMapProductID(hitOrClusterAssociator, trackingParticleCollection);
0266
0267 size_t collectionSize = ::collectionSize(trackCollection);
0268
0269 for (size_t i = 0; i < collectionSize; ++i) {
0270
0271 const auto* pTrack = ::getTrackAt(trackCollection, i);
0272
0273
0274 std::vector<std::pair<edm::Ref<TrackingParticleCollection>, double>> trackingParticleQualityPairs =
0275 associateTrack(hitOrClusterAssociator,
0276 trackingParticleCollection,
0277 trackingParticleKeys,
0278 pTrack->recHits().begin(),
0279 pTrack->recHits().end());
0280
0281
0282 for (auto iTrackingParticleQualityPair = trackingParticleQualityPairs.begin();
0283 iTrackingParticleQualityPair != trackingParticleQualityPairs.end();
0284 ++iTrackingParticleQualityPair) {
0285 const edm::Ref<TrackingParticleCollection>& trackingParticleRef = iTrackingParticleQualityPair->first;
0286 double numberOfSharedClusters = iTrackingParticleQualityPair->second;
0287 double numberOfValidTrackClusters = weightedNumberOfTrackClusters(*pTrack, hitOrClusterAssociator);
0288 size_t numberOfSimulatedHits = 0;
0289
0290 if (numberOfSharedClusters == 0.0)
0291 continue;
0292
0293 if (simToRecoDenominator_ == denomsim ||
0294 (numberOfSharedClusters < 3.0 &&
0295 threeHitTracksAreSpecial_))
0296 {
0297
0298
0299
0300
0301 numberOfSimulatedHits = trackingParticleRef->numberOfTrackerHits();
0302 }
0303
0304
0305 if (abs(trackingParticleRef->pdgId()) == 11 &&
0306 (trackingParticleRef->g4Track_end() - trackingParticleRef->g4Track_begin()) > 1) {
0307 numberOfSharedClusters -= getDoubleCount(
0308 hitOrClusterAssociator, pTrack->recHits().begin(), pTrack->recHits().end(), trackingParticleRef);
0309 }
0310
0311 double purity = numberOfSharedClusters / numberOfValidTrackClusters;
0312 double quality;
0313 if (absoluteNumberOfHits_)
0314 quality = numberOfSharedClusters;
0315 else if (simToRecoDenominator_ == denomsim && numberOfSimulatedHits != 0)
0316 quality = numberOfSharedClusters / static_cast<double>(numberOfSimulatedHits);
0317 else if (simToRecoDenominator_ == denomreco && numberOfValidTrackClusters != 0)
0318 quality = purity;
0319 else
0320 quality = 0;
0321
0322 if (quality > qualitySimToReco_ &&
0323 !(threeHitTracksAreSpecial_ && numberOfSimulatedHits == 3 && numberOfSharedClusters < 3.0) &&
0324 (absoluteNumberOfHits_ || (purity > puritySimToReco_))) {
0325
0326 returnValue.insert(trackingParticleRef, std::make_pair(::getRefToTrackAt(trackCollection, i), quality));
0327 }
0328 }
0329 }
0330 returnValue.post_insert();
0331 return returnValue;
0332 }
0333
0334 template <typename T_TPCollection, typename iter>
0335 std::vector<std::pair<edm::Ref<TrackingParticleCollection>, double>> QuickTrackAssociatorByHitsImpl::associateTrack(
0336 const TrackerHitAssociator& hitAssociator,
0337 const T_TPCollection& trackingParticles,
0338 const TrackingParticleRefKeySet* trackingParticleKeys,
0339 iter begin,
0340 iter end) const {
0341
0342 std::vector<std::pair<edm::Ref<TrackingParticleCollection>, double>> returnValue;
0343
0344
0345
0346
0347 std::vector<std::pair<SimTrackIdentifiers, double>> hitIdentifiers =
0348 getAllSimTrackIdentifiers(hitAssociator, begin, end);
0349
0350
0351 size_t collectionSize = ::collectionSize(trackingParticles);
0352
0353 for (size_t i = 0; i < collectionSize; ++i) {
0354 const TrackingParticle* pTrackingParticle = getTrackingParticleAt(trackingParticles, i);
0355
0356
0357
0358
0359
0360
0361
0362
0363 double numberOfAssociatedHits = 0;
0364
0365
0366 for (const auto& identifierCountPair : hitIdentifiers) {
0367 if (trackingParticleContainsIdentifier(pTrackingParticle, identifierCountPair.first))
0368 numberOfAssociatedHits += identifierCountPair.second;
0369 }
0370
0371 if (numberOfAssociatedHits > 0) {
0372 returnValue.push_back(std::make_pair(getRefToTrackingParticleAt(trackingParticles, i), numberOfAssociatedHits));
0373 }
0374 }
0375
0376 return returnValue;
0377 }
0378
0379 template <typename T_TPCollection, typename iter>
0380 std::vector<std::pair<edm::Ref<TrackingParticleCollection>, double>> QuickTrackAssociatorByHitsImpl::associateTrack(
0381 const ClusterTPAssociation& clusterToTPMap,
0382 const T_TPCollection& trackingParticles,
0383 const TrackingParticleRefKeySet* trackingParticleKeys,
0384 iter begin,
0385 iter end) const {
0386
0387
0388
0389
0390
0391
0392
0393
0394
0395
0396
0397
0398
0399
0400 std::vector<std::pair<edm::Ref<TrackingParticleCollection>, double>> returnValue;
0401 if (clusterToTPMap.empty())
0402 return returnValue;
0403
0404
0405
0406
0407
0408 std::vector<OmniClusterRef> oClusters = track_associator::hitsToClusterRefs(begin, end);
0409
0410 std::map<TrackingParticleRef, double> lmap;
0411 for (std::vector<OmniClusterRef>::const_iterator it = oClusters.begin(); it != oClusters.end(); ++it) {
0412 auto range = clusterToTPMap.equal_range(*it);
0413 const double weight = it->isPixel() ? pixelHitWeight_ : 1.0;
0414 if (range.first != range.second) {
0415 for (auto ip = range.first; ip != range.second; ++ip) {
0416 const TrackingParticleRef trackingParticle = (ip->second);
0417
0418 if (trackingParticleKeys && !trackingParticleKeys->has(trackingParticle.key()))
0419 continue;
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439
0440
0441 auto jpos = lmap.find(trackingParticle);
0442 if (jpos != lmap.end())
0443 jpos->second += weight;
0444 else
0445 lmap.insert(std::make_pair(trackingParticle, weight));
0446 }
0447 }
0448 }
0449
0450 for (auto ip = lmap.begin(); ip != lmap.end(); ++ip) {
0451 returnValue.push_back(std::make_pair(ip->first, ip->second));
0452 }
0453 return returnValue;
0454 }
0455
0456 template <typename iter>
0457 std::vector<std::pair<QuickTrackAssociatorByHitsImpl::SimTrackIdentifiers, double>>
0458 QuickTrackAssociatorByHitsImpl::getAllSimTrackIdentifiers(const TrackerHitAssociator& hitAssociator,
0459 iter begin,
0460 iter end) const {
0461
0462 std::vector<std::pair<SimTrackIdentifiers, double>> returnValue;
0463
0464 std::vector<SimTrackIdentifiers> simTrackIdentifiers;
0465
0466
0467 for (iter iRecHit = begin; iRecHit != end; ++iRecHit) {
0468 if (track_associator::getHitFromIter(iRecHit)->isValid()) {
0469 simTrackIdentifiers.clear();
0470
0471
0472
0473 hitAssociator.associateHitId(*(track_associator::getHitFromIter(iRecHit)),
0474 simTrackIdentifiers);
0475
0476 const auto subdetId = track_associator::getHitFromIter(iRecHit)->geographicalId().subdetId();
0477 const double weight = (subdetId == PixelSubdetector::PixelBarrel || subdetId == PixelSubdetector::PixelEndcap)
0478 ? pixelHitWeight_
0479 : 1.0;
0480
0481
0482 for (std::vector<SimTrackIdentifiers>::const_iterator iIdentifier = simTrackIdentifiers.begin();
0483 iIdentifier != simTrackIdentifiers.end();
0484 ++iIdentifier) {
0485 std::vector<std::pair<SimTrackIdentifiers, double>>::iterator iIdentifierCountPair;
0486 for (auto iIdentifierCountPair = returnValue.begin(); iIdentifierCountPair != returnValue.end();
0487 ++iIdentifierCountPair) {
0488 if (iIdentifierCountPair->first.first == iIdentifier->first &&
0489 iIdentifierCountPair->first.second == iIdentifier->second) {
0490
0491 iIdentifierCountPair->second += weight;
0492 break;
0493 }
0494 }
0495 if (iIdentifierCountPair == returnValue.end())
0496 returnValue.push_back(std::make_pair(*iIdentifier, 1.0));
0497
0498 }
0499 }
0500 }
0501 return returnValue;
0502 }
0503
0504 bool QuickTrackAssociatorByHitsImpl::trackingParticleContainsIdentifier(const TrackingParticle* pTrackingParticle,
0505 const SimTrackIdentifiers& identifier) const {
0506
0507 for (std::vector<SimTrack>::const_iterator iSimTrack = pTrackingParticle->g4Track_begin();
0508 iSimTrack != pTrackingParticle->g4Track_end();
0509 ++iSimTrack) {
0510
0511 if (iSimTrack->eventId() == identifier.second && iSimTrack->trackId() == identifier.first) {
0512 return true;
0513 }
0514 }
0515
0516
0517
0518 return false;
0519 }
0520
0521 template <typename iter>
0522 double QuickTrackAssociatorByHitsImpl::getDoubleCount(const TrackerHitAssociator& hitAssociator,
0523 iter startIterator,
0524 iter endIterator,
0525 TrackingParticleRef associatedTrackingParticle) const {
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535 double doubleCount = 0.0;
0536 std::vector<SimHitIdpr> SimTrackIdsDC;
0537
0538 for (iter iHit = startIterator; iHit != endIterator; iHit++) {
0539 int idcount = 0;
0540
0541 SimTrackIdsDC.clear();
0542 hitAssociator.associateHitId(*(track_associator::getHitFromIter(iHit)), SimTrackIdsDC);
0543 if (SimTrackIdsDC.size() > 1) {
0544 for (TrackingParticle::g4t_iterator g4T = associatedTrackingParticle->g4Track_begin();
0545 g4T != associatedTrackingParticle->g4Track_end();
0546 ++g4T) {
0547 if (find(SimTrackIdsDC.begin(),
0548 SimTrackIdsDC.end(),
0549 SimHitIdpr((*g4T).trackId(), SimTrackIdsDC.begin()->second)) != SimTrackIdsDC.end()) {
0550 idcount++;
0551 }
0552 }
0553 }
0554 if (idcount > 1) {
0555 const auto subdetId = track_associator::getHitFromIter(iHit)->geographicalId().subdetId();
0556 const double weight = (subdetId == PixelSubdetector::PixelBarrel || subdetId == PixelSubdetector::PixelEndcap)
0557 ? pixelHitWeight_
0558 : 1.0;
0559 doubleCount += weight * (idcount - 1);
0560 }
0561 }
0562
0563 return doubleCount;
0564 }
0565
0566 template <typename iter>
0567 double QuickTrackAssociatorByHitsImpl::getDoubleCount(const ClusterTPAssociation& clusterToTPList,
0568 iter startIterator,
0569 iter endIterator,
0570 TrackingParticleRef associatedTrackingParticle) const {
0571
0572
0573
0574
0575
0576
0577
0578
0579
0580
0581
0582
0583
0584
0585
0586
0587 double doubleCount = 0;
0588 std::vector<SimHitIdpr> SimTrackIdsDC;
0589
0590 for (iter iHit = startIterator; iHit != endIterator; iHit++) {
0591 std::vector<OmniClusterRef> oClusters =
0592 track_associator::hitsToClusterRefs(iHit, iHit + 1);
0593 for (std::vector<OmniClusterRef>::const_iterator it = oClusters.begin(); it != oClusters.end(); ++it) {
0594 int idcount = 0;
0595
0596 auto range = clusterToTPList.equal_range(*it);
0597 if (range.first != range.second) {
0598 for (auto ip = range.first; ip != range.second; ++ip) {
0599 const TrackingParticleRef trackingParticle = (ip->second);
0600 if (associatedTrackingParticle == trackingParticle) {
0601 idcount++;
0602 }
0603 }
0604 }
0605
0606 if (idcount > 1) {
0607 const auto subdetId = track_associator::getHitFromIter(iHit)->geographicalId().subdetId();
0608 const double weight = (subdetId == PixelSubdetector::PixelBarrel || subdetId == PixelSubdetector::PixelEndcap)
0609 ? pixelHitWeight_
0610 : 1.0;
0611 doubleCount += weight * (idcount - 1);
0612 }
0613 }
0614 }
0615
0616 return doubleCount;
0617 }
0618
0619 reco::RecoToSimCollectionSeed QuickTrackAssociatorByHitsImpl::associateRecoToSim(
0620 const edm::Handle<edm::View<TrajectorySeed>>& pSeedCollectionHandle_,
0621 const edm::Handle<TrackingParticleCollection>& trackingParticleCollectionHandle) const {
0622 edm::LogVerbatim("TrackAssociator") << "Starting TrackAssociatorByHitsImpl::associateRecoToSim - #seeds="
0623 << pSeedCollectionHandle_->size()
0624 << " #TPs=" << trackingParticleCollectionHandle->size();
0625
0626 reco::RecoToSimCollectionSeed returnValue(productGetter_);
0627
0628 size_t collectionSize = pSeedCollectionHandle_->size();
0629
0630 for (size_t i = 0; i < collectionSize; ++i) {
0631 const TrajectorySeed* pSeed = &(*pSeedCollectionHandle_)[i];
0632
0633
0634 std::vector<std::pair<edm::Ref<TrackingParticleCollection>, double>> trackingParticleQualityPairs =
0635 (clusterToTPMap_) ? associateTrack(*clusterToTPMap_,
0636 trackingParticleCollectionHandle,
0637 nullptr,
0638 pSeed->recHits().begin(),
0639 pSeed->recHits().end())
0640 : associateTrack(*hitAssociator_,
0641 trackingParticleCollectionHandle,
0642 nullptr,
0643 pSeed->recHits().begin(),
0644 pSeed->recHits().end());
0645 for (auto iTrackingParticleQualityPair = trackingParticleQualityPairs.begin();
0646 iTrackingParticleQualityPair != trackingParticleQualityPairs.end();
0647 ++iTrackingParticleQualityPair) {
0648 const edm::Ref<TrackingParticleCollection>& trackingParticleRef = iTrackingParticleQualityPair->first;
0649 double numberOfSharedClusters = iTrackingParticleQualityPair->second;
0650 double numberOfValidTrackClusters = clusterToTPMap_ ? weightedNumberOfTrackClusters(*pSeed, *clusterToTPMap_)
0651 : weightedNumberOfTrackClusters(*pSeed, *hitAssociator_);
0652
0653 if (numberOfSharedClusters == 0.0)
0654 continue;
0655
0656
0657 if (abs(trackingParticleRef->pdgId()) == 11 &&
0658 (trackingParticleRef->g4Track_end() - trackingParticleRef->g4Track_begin()) > 1) {
0659 if (clusterToTPMap_)
0660 numberOfSharedClusters -=
0661 getDoubleCount(*clusterToTPMap_, pSeed->recHits().begin(), pSeed->recHits().end(), trackingParticleRef);
0662 else
0663 numberOfSharedClusters -=
0664 getDoubleCount(*hitAssociator_, pSeed->recHits().begin(), pSeed->recHits().end(), trackingParticleRef);
0665 }
0666
0667 double quality;
0668 if (absoluteNumberOfHits_)
0669 quality = numberOfSharedClusters;
0670 else if (numberOfValidTrackClusters != 0.0)
0671 quality = numberOfSharedClusters / numberOfValidTrackClusters;
0672 else
0673 quality = 0;
0674
0675 if (quality > cutRecoToSim_ &&
0676 !(threeHitTracksAreSpecial_ && pSeed->nHits() == 3 && numberOfSharedClusters < 3.0)) {
0677 returnValue.insert(edm::RefToBase<TrajectorySeed>(pSeedCollectionHandle_, i),
0678 std::make_pair(trackingParticleRef, quality));
0679 }
0680 }
0681 }
0682
0683 LogTrace("TrackAssociator") << "% of Assoc Seeds="
0684 << ((double)returnValue.size()) / ((double)pSeedCollectionHandle_->size());
0685 returnValue.post_insert();
0686 return returnValue;
0687 }
0688
0689 reco::SimToRecoCollectionSeed QuickTrackAssociatorByHitsImpl::associateSimToReco(
0690 const edm::Handle<edm::View<TrajectorySeed>>& pSeedCollectionHandle_,
0691 const edm::Handle<TrackingParticleCollection>& trackingParticleCollectionHandle) const {
0692 edm::LogVerbatim("TrackAssociator") << "Starting TrackAssociatorByHitsImpl::associateSimToReco - #seeds="
0693 << pSeedCollectionHandle_->size()
0694 << " #TPs=" << trackingParticleCollectionHandle->size();
0695
0696 reco::SimToRecoCollectionSeed returnValue(productGetter_);
0697 if (trackingParticleCollectionHandle->empty())
0698 return returnValue;
0699
0700 if (clusterToTPMap_) {
0701 checkClusterMapProductID(*clusterToTPMap_, trackingParticleCollectionHandle);
0702 }
0703
0704 size_t collectionSize = pSeedCollectionHandle_->size();
0705
0706 for (size_t i = 0; i < collectionSize; ++i) {
0707 const TrajectorySeed* pSeed = &(*pSeedCollectionHandle_)[i];
0708
0709
0710 std::vector<std::pair<edm::Ref<TrackingParticleCollection>, double>> trackingParticleQualityPairs =
0711 (clusterToTPMap_) ? associateTrack(*clusterToTPMap_,
0712 trackingParticleCollectionHandle,
0713 nullptr,
0714 pSeed->recHits().begin(),
0715 pSeed->recHits().end())
0716 : associateTrack(*hitAssociator_,
0717 trackingParticleCollectionHandle,
0718 nullptr,
0719 pSeed->recHits().begin(),
0720 pSeed->recHits().end());
0721 for (auto iTrackingParticleQualityPair = trackingParticleQualityPairs.begin();
0722 iTrackingParticleQualityPair != trackingParticleQualityPairs.end();
0723 ++iTrackingParticleQualityPair) {
0724 const edm::Ref<TrackingParticleCollection>& trackingParticleRef = iTrackingParticleQualityPair->first;
0725 double numberOfSharedClusters = iTrackingParticleQualityPair->second;
0726 double numberOfValidTrackClusters = clusterToTPMap_ ? weightedNumberOfTrackClusters(*pSeed, *clusterToTPMap_)
0727 : weightedNumberOfTrackClusters(*pSeed, *hitAssociator_);
0728 size_t numberOfSimulatedHits = 0;
0729
0730 if (numberOfSharedClusters == 0.0)
0731 continue;
0732
0733
0734 if (abs(trackingParticleRef->pdgId()) == 11 &&
0735 (trackingParticleRef->g4Track_end() - trackingParticleRef->g4Track_begin()) > 1) {
0736 if (clusterToTPMap_)
0737 numberOfSharedClusters -=
0738 getDoubleCount(*clusterToTPMap_, pSeed->recHits().begin(), pSeed->recHits().end(), trackingParticleRef);
0739 else
0740 numberOfSharedClusters -=
0741 getDoubleCount(*hitAssociator_, pSeed->recHits().begin(), pSeed->recHits().end(), trackingParticleRef);
0742 }
0743
0744 if (simToRecoDenominator_ == denomsim ||
0745 (numberOfSharedClusters < 3.0 &&
0746 threeHitTracksAreSpecial_))
0747 {
0748
0749
0750
0751
0752 numberOfSimulatedHits = trackingParticleRef->numberOfTrackerHits();
0753 }
0754
0755 double purity = numberOfSharedClusters / numberOfValidTrackClusters;
0756 double quality;
0757 if (absoluteNumberOfHits_)
0758 quality = numberOfSharedClusters;
0759 else if (simToRecoDenominator_ == denomsim && numberOfSimulatedHits != 0)
0760 quality = numberOfSharedClusters / static_cast<double>(numberOfSimulatedHits);
0761 else if (simToRecoDenominator_ == denomreco && numberOfValidTrackClusters != 0.0)
0762 quality = purity;
0763 else
0764 quality = 0;
0765
0766 if (quality > qualitySimToReco_ &&
0767 !(threeHitTracksAreSpecial_ && numberOfSimulatedHits == 3 && numberOfSharedClusters < 3.0) &&
0768 (absoluteNumberOfHits_ || (purity > puritySimToReco_))) {
0769 returnValue.insert(trackingParticleRef,
0770 std::make_pair(edm::RefToBase<TrajectorySeed>(pSeedCollectionHandle_, i), quality));
0771 }
0772 }
0773 }
0774
0775 LogTrace("TrackAssociator") << "% of Assoc TPs="
0776 << ((double)returnValue.size()) / ((double)trackingParticleCollectionHandle->size());
0777 returnValue.post_insert();
0778 return returnValue;
0779 }
0780
0781 reco::RecoToSimCollectionTCandidate QuickTrackAssociatorByHitsImpl::associateRecoToSim(
0782 const edm::Handle<TrackCandidateCollection>& trackCollectionHandle,
0783 const edm::RefVector<TrackingParticleCollection>& trackingParticleCollectionHandle) const {
0784
0785 if (not clusterToTPMap_)
0786 return associateRecoToSimImplementation<reco::RecoToSimCollectionTCandidate>(
0787 trackCollectionHandle, trackingParticleCollectionHandle, nullptr, *hitAssociator_);
0788 else
0789 return associateRecoToSimImplementation<reco::RecoToSimCollectionTCandidate>(
0790 trackCollectionHandle, trackingParticleCollectionHandle, nullptr, *clusterToTPMap_);
0791 }
0792
0793 reco::SimToRecoCollectionTCandidate QuickTrackAssociatorByHitsImpl::associateSimToReco(
0794 const edm::Handle<TrackCandidateCollection>& trackCollectionHandle,
0795 const edm::RefVector<TrackingParticleCollection>& trackingParticleCollectionHandle) const {
0796
0797 if (not clusterToTPMap_)
0798 return associateSimToRecoImplementation<reco::SimToRecoCollectionTCandidate>(
0799 trackCollectionHandle, trackingParticleCollectionHandle, nullptr, *hitAssociator_);
0800 else
0801 return associateSimToRecoImplementation<reco::SimToRecoCollectionTCandidate>(
0802 trackCollectionHandle, trackingParticleCollectionHandle, nullptr, *clusterToTPMap_);
0803 }
0804
0805
0806 template <>
0807 double QuickTrackAssociatorByHitsImpl::weightedNumberOfTrackClusters(const reco::Track& track,
0808 const TrackerHitAssociator&) const {
0809 const reco::HitPattern& p = track.hitPattern();
0810 const auto pixelHits = p.numberOfValidPixelHits();
0811 const auto otherHits = p.numberOfValidHits() - pixelHits;
0812 return pixelHits * pixelHitWeight_ + otherHits;
0813 }
0814
0815 template <typename T_Track>
0816 double QuickTrackAssociatorByHitsImpl::weightedNumberOfTrackClusters(const T_Track& seed,
0817 const TrackerHitAssociator&) const {
0818 double sum = 0.0;
0819 for (auto iHit = seed.recHits().begin(); iHit != seed.recHits().end(); ++iHit) {
0820 const auto subdetId = track_associator::getHitFromIter(iHit)->geographicalId().subdetId();
0821 const double weight = (subdetId == PixelSubdetector::PixelBarrel || subdetId == PixelSubdetector::PixelEndcap)
0822 ? pixelHitWeight_
0823 : 1.0;
0824 sum += weight;
0825 }
0826 return sum;
0827 }
0828
0829
0830 template <>
0831 double QuickTrackAssociatorByHitsImpl::weightedNumberOfTrackClusters(const reco::Track& track,
0832 const ClusterTPAssociation&) const {
0833 return weightedNumberOfTrackClusters(track.recHitsBegin(), track.recHitsEnd());
0834 }
0835 template <typename T_Track>
0836 double QuickTrackAssociatorByHitsImpl::weightedNumberOfTrackClusters(const T_Track& seed,
0837 const ClusterTPAssociation&) const {
0838 const auto& hitRange = seed.recHits();
0839 return weightedNumberOfTrackClusters(hitRange.begin(), hitRange.end());
0840 }
0841
0842 template <typename iter>
0843 double QuickTrackAssociatorByHitsImpl::weightedNumberOfTrackClusters(iter begin, iter end) const {
0844 double weightedClusters = 0.0;
0845 for (iter iRecHit = begin; iRecHit != end; ++iRecHit) {
0846 const auto subdetId = track_associator::getHitFromIter(iRecHit)->geographicalId().subdetId();
0847 const double weight = (subdetId == PixelSubdetector::PixelBarrel || subdetId == PixelSubdetector::PixelEndcap)
0848 ? pixelHitWeight_
0849 : 1.0;
0850 LogTrace("QuickTrackAssociatorByHitsImpl")
0851 << " detId: " << track_associator::getHitFromIter(iRecHit)->geographicalId().rawId();
0852 LogTrace("QuickTrackAssociatorByHitsImpl") << " weight: " << weight;
0853 std::vector<OmniClusterRef> oClusters =
0854 track_associator::hitsToClusterRefs(iRecHit, iRecHit + 1);
0855 for (std::vector<OmniClusterRef>::const_iterator it = oClusters.begin(); it != oClusters.end(); ++it) {
0856 weightedClusters += weight;
0857 }
0858 }
0859 LogTrace("QuickTrackAssociatorByHitsImpl") << " total weighted clusters: " << weightedClusters;
0860 return weightedClusters;
0861 }