test
CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
QuickTrackAssociatorByHitsImpl.cc
Go to the documentation of this file.
1 #include <iostream>
2 #include <fstream>
3 
5 
7 
16 
17 //
18 // Use the unnamed namespace for utility functions only used in this file
19 //
20 namespace
21 {
22  //
23  // All of these functions are pretty straightforward but the implementation is type dependent.
24  // The templated methods call these for the type specific parts and the compiler will resolve
25  // the type and call the correct overload.
26  //
27 
28  template<class T_element>
29  size_t collectionSize( const edm::RefToBaseVector<T_element>& collection )
30  {
31  return collection.size();
32  }
33 
34  template<class T_element>
35  size_t collectionSize( const edm::Handle<T_element>& hCollection )
36  {
37  return hCollection->size();
38  }
39 
40  template<class T_element>
41  size_t collectionSize( const edm::RefVector<T_element>& collection )
42  {
43  return collection.size();
44  }
45 
46  const reco::Track* getTrackAt( const edm::RefToBaseVector<reco::Track>& trackCollection, size_t index )
47  {
48  return &*trackCollection[index]; // pretty obscure dereference
49  }
50 
51  const reco::Track* getTrackAt( const edm::Handle<edm::View<reco::Track> >& pTrackCollection, size_t index )
52  {
53  return &(*pTrackCollection.product())[index];
54  }
55 
56  const TrackingParticle* getTrackingParticleAt( const edm::Handle<TrackingParticleCollection>& pCollection, size_t index )
57  {
58  return &(*pCollection.product())[index];
59  }
60 
61  const TrackingParticle* getTrackingParticleAt( const edm::RefVector<TrackingParticleCollection>& collection, size_t index )
62  {
63  return &*collection[index];
64  }
65 
67  {
68  return trackCollection[index];
69  }
70 
71  edm::RefToBase<reco::Track> getRefToTrackAt( const edm::Handle<edm::View<reco::Track> >& pTrackCollection, size_t index )
72  {
73  return edm::RefToBase<reco::Track>( pTrackCollection, index );
74  }
75 
76  edm::Ref<TrackingParticleCollection> getRefToTrackingParticleAt( const edm::Handle<TrackingParticleCollection>& pCollection, size_t index )
77  {
78  return edm::Ref<TrackingParticleCollection>( pCollection, index );
79  }
80 
81  edm::Ref<TrackingParticleCollection> getRefToTrackingParticleAt( const edm::RefVector<TrackingParticleCollection>& collection, size_t index )
82  {
83  return collection[index];
84  }
85 
86 } // end of the unnamed namespace
87 
89  std::unique_ptr<const TrackerHitAssociator> hitAssoc,
90  const ClusterTPAssociationList *clusterToTPMap,
91 
92  bool absoluteNumberOfHits,
93  double qualitySimToReco,
94  double puritySimToReco,
95  double cutRecoToSim,
96  bool threeHitTracksAreSpecial,
97  SimToRecoDenomType simToRecoDenominator):
98  productGetter_(&productGetter),
99  hitAssociator_(std::move(hitAssoc)),
100  clusterToTPMap_(clusterToTPMap),
101  qualitySimToReco_(qualitySimToReco),
102  puritySimToReco_(puritySimToReco),
103  cutRecoToSim_(cutRecoToSim),
104  simToRecoDenominator_(simToRecoDenominator) ,
105  threeHitTracksAreSpecial_(threeHitTracksAreSpecial),
106  absoluteNumberOfHits_(absoluteNumberOfHits)
107  {}
108 
109 
111  const edm::Handle<TrackingParticleCollection>& trackingParticleCollectionHandle) const
112 {
113  // Only pass the one that was successfully created to the templated method.
114  if( not clusterToTPMap_ ) return associateRecoToSimImplementation( trackCollectionHandle, trackingParticleCollectionHandle, *hitAssociator_ );
115  else return associateRecoToSimImplementation( trackCollectionHandle, trackingParticleCollectionHandle, *clusterToTPMap_ );
116 }
117 
119  const edm::Handle<TrackingParticleCollection>& trackingParticleCollectionHandle) const
120 {
121  // Only pass the one that was successfully created to the templated method.
122  if( not clusterToTPMap_ ) return associateSimToRecoImplementation( trackCollectionHandle, trackingParticleCollectionHandle, *hitAssociator_ );
123  else return associateSimToRecoImplementation( trackCollectionHandle, trackingParticleCollectionHandle, *clusterToTPMap_ );
124 }
125 
127  const edm::RefVector<TrackingParticleCollection>& trackingParticleCollection ) const
128 {
129  // Only pass the one that was successfully created to the templated method.
130  if( not clusterToTPMap_ ) return associateRecoToSimImplementation( trackCollection, trackingParticleCollection, *hitAssociator_ );
131  else return associateRecoToSimImplementation( trackCollection, trackingParticleCollection, *clusterToTPMap_ );
132 }
133 
135  const edm::RefVector<TrackingParticleCollection>& trackingParticleCollection) const
136 {
137  // Only pass the one that was successfully created to the templated method.
138  if( not clusterToTPMap_ ) return associateSimToRecoImplementation( trackCollection, trackingParticleCollection, *hitAssociator_ );
139  else return associateSimToRecoImplementation( trackCollection, trackingParticleCollection, *clusterToTPMap_ );
140 }
141 
142 
143 template<class T_TrackCollection, class T_TrackingParticleCollection, class T_hitOrClusterAssociator>
144 reco::RecoToSimCollection QuickTrackAssociatorByHitsImpl::associateRecoToSimImplementation( T_TrackCollection trackCollection, T_TrackingParticleCollection trackingParticleCollection, T_hitOrClusterAssociator hitOrClusterAssociator ) const
145 {
147 
148  size_t collectionSize=::collectionSize(trackCollection); // Delegate away type specific part
149 
150  for( size_t i=0; i < collectionSize; ++i )
151  {
152  const reco::Track* pTrack=::getTrackAt(trackCollection,i); // Get a normal pointer for ease of use. This part is type specific so delegate.
153 
154  // The return of this function has first as the index and second as the number of associated hits
155  std::vector < std::pair<edm::Ref<TrackingParticleCollection>,size_t> > trackingParticleQualityPairs=associateTrack( hitOrClusterAssociator, trackingParticleCollection, pTrack->recHitsBegin(), pTrack->recHitsEnd() );
156 
157  // int nt = 0;
158  for( std::vector<std::pair<edm::Ref<TrackingParticleCollection>,size_t> >::const_iterator iTrackingParticleQualityPair=
159  trackingParticleQualityPairs.begin(); iTrackingParticleQualityPair != trackingParticleQualityPairs.end();
160  ++iTrackingParticleQualityPair )
161  {
162  const edm::Ref<TrackingParticleCollection>& trackingParticleRef=iTrackingParticleQualityPair->first;
163  size_t numberOfSharedHits=iTrackingParticleQualityPair->second;
164  size_t numberOfValidTrackHits=pTrack->found();
165 
166  if( numberOfSharedHits == 0 ) continue; // No point in continuing if there was no association
167 
168  //if electron subtract double counting
169  if( abs( trackingParticleRef->pdgId() ) == 11 && (trackingParticleRef->g4Track_end() - trackingParticleRef->g4Track_begin()) > 1 )
170  {
171  numberOfSharedHits-=getDoubleCount( hitOrClusterAssociator, pTrack->recHitsBegin(), pTrack->recHitsEnd(), trackingParticleRef );
172  }
173 
174  double quality;
175  if( absoluteNumberOfHits_ ) quality=static_cast<double>( numberOfSharedHits );
176  else if( numberOfValidTrackHits != 0 ) quality=
177  (static_cast<double>( numberOfSharedHits ) / static_cast<double>( numberOfValidTrackHits ));
178  else quality=0;
179  if( quality > cutRecoToSim_ && !(threeHitTracksAreSpecial_ && numberOfValidTrackHits == 3 && numberOfSharedHits < 3) )
180  {
181  // Getting the RefToBase is dependent on the type of trackCollection, so delegate that to an overload.
182  returnValue.insert( ::getRefToTrackAt(trackCollection,i), std::make_pair( trackingParticleRef, quality ) );
183  }
184  }
185  }
186  returnValue.post_insert();
187  return returnValue;
188 }
189 
190 template<class T_TrackCollection, class T_TrackingParticleCollection, class T_hitOrClusterAssociator>
191 reco::SimToRecoCollection QuickTrackAssociatorByHitsImpl::associateSimToRecoImplementation( T_TrackCollection trackCollection, T_TrackingParticleCollection trackingParticleCollection, T_hitOrClusterAssociator hitOrClusterAssociator ) const
192 {
194 
195  size_t collectionSize=::collectionSize(trackCollection); // Delegate away type specific part
196 
197  for( size_t i=0; i<collectionSize; ++i )
198  {
199  const reco::Track* pTrack=::getTrackAt(trackCollection,i); // Get a normal pointer for ease of use. This part is type specific so delegate.
200 
201  // The return of this function has first as an edm:Ref to the associated TrackingParticle, and second as the number of associated hits
202  std::vector < std::pair<edm::Ref<TrackingParticleCollection>,size_t> > trackingParticleQualityPairs=associateTrack( hitOrClusterAssociator, trackingParticleCollection, pTrack->recHitsBegin(), pTrack->recHitsEnd() );
203 
204  // int nt = 0;
205  for( std::vector< std::pair<edm::Ref<TrackingParticleCollection>,size_t> >::const_iterator iTrackingParticleQualityPair=trackingParticleQualityPairs.begin();
206  iTrackingParticleQualityPair!=trackingParticleQualityPairs.end(); ++iTrackingParticleQualityPair )
207  {
208  const edm::Ref<TrackingParticleCollection>& trackingParticleRef=iTrackingParticleQualityPair->first;
209  size_t numberOfSharedHits=iTrackingParticleQualityPair->second;
210  size_t numberOfValidTrackHits=pTrack->found();
211  size_t numberOfSimulatedHits=0; // Set a few lines below, but only if required.
212 
213  if( numberOfSharedHits==0 ) continue; // No point in continuing if there was no association
214 
215  if( simToRecoDenominator_==denomsim || (numberOfSharedHits<3 && threeHitTracksAreSpecial_) ) // the numberOfSimulatedHits is not always required, so can skip counting in some circumstances
216  {
217  // Note that in the standard TrackAssociatorByHits, all of the hits in associatedTrackingParticleHits are checked for
218  // various things. I'm not sure what these checks are for but they depend on the UseGrouping and UseSplitting settings.
219  // This associator works as though both UseGrouping and UseSplitting were set to true, i.e. just counts the number of
220  // hits in the tracker.
221  numberOfSimulatedHits=trackingParticleRef->numberOfTrackerHits();
222  }
223 
224  //if electron subtract double counting
225  if (abs(trackingParticleRef->pdgId())==11 && (trackingParticleRef->g4Track_end() - trackingParticleRef->g4Track_begin()) > 1 )
226  {
227  numberOfSharedHits -= getDoubleCount( hitOrClusterAssociator, pTrack->recHitsBegin(), pTrack->recHitsEnd(), trackingParticleRef );
228  }
229 
230  double purity=static_cast<double>(numberOfSharedHits)/static_cast<double>(numberOfValidTrackHits);
231  double quality;
232  if( absoluteNumberOfHits_ ) quality=static_cast<double>(numberOfSharedHits);
233  else if( simToRecoDenominator_==denomsim && numberOfSimulatedHits != 0 ) quality=static_cast<double>(numberOfSharedHits)/static_cast<double>(numberOfSimulatedHits);
234  else if( simToRecoDenominator_==denomreco && numberOfValidTrackHits != 0 ) quality=purity;
235  else quality=0;
236 
237  if( quality>qualitySimToReco_ && !( threeHitTracksAreSpecial_ && numberOfSimulatedHits==3 && numberOfSharedHits<3 ) && ( absoluteNumberOfHits_ || (purity>puritySimToReco_) ) )
238  {
239  // Getting the RefToBase is dependent on the type of trackCollection, so delegate that to an overload.
240  returnValue.insert( trackingParticleRef, std::make_pair( ::getRefToTrackAt(trackCollection,i), quality ) );
241  }
242  }
243  }
244  returnValue.post_insert();
245  return returnValue;
246 
247 }
248 
249 template<typename T_TPCollection,typename iter> std::vector<std::pair<edm::Ref<TrackingParticleCollection>,size_t> > QuickTrackAssociatorByHitsImpl::associateTrack( const TrackerHitAssociator& hitAssociator, T_TPCollection trackingParticles, iter begin, iter end ) const
250 {
251  // The pairs in this vector have a Ref to the associated TrackingParticle as "first" and the number of associated hits as "second"
252  std::vector< std::pair<edm::Ref<TrackingParticleCollection>,size_t> > returnValue;
253 
254  // The pairs in this vector have first as the sim track identifiers, and second the number of reco hits associated to that sim track.
255  // Most reco hits will probably have come from the same sim track, so the number of entries in this vector should be fewer than the
256  // number of reco hits. The pair::second entries should add up to the total number of reco hits though.
257  std::vector< std::pair<SimTrackIdentifiers,size_t> > hitIdentifiers=getAllSimTrackIdentifiers( hitAssociator, begin, end );
258 
259  // Loop over the TrackingParticles
260  size_t collectionSize=::collectionSize(trackingParticles);
261 
262  for( size_t i=0; i<collectionSize; ++i )
263  {
264  const TrackingParticle* pTrackingParticle=getTrackingParticleAt( trackingParticles, i );
265 
266  // Ignore TrackingParticles with no hits
267  if( pTrackingParticle->numberOfHits()==0 ) continue;
268 
269  size_t numberOfAssociatedHits=0;
270  // Loop over all of the sim track identifiers and see if any of them are part of this TrackingParticle. If they are, add
271  // the number of reco hits associated to that sim track to the total number of associated hits.
272  for( std::vector< std::pair<SimTrackIdentifiers,size_t> >::const_iterator iIdentifierCountPair=hitIdentifiers.begin(); iIdentifierCountPair!=hitIdentifiers.end(); ++iIdentifierCountPair )
273  {
274  if( trackingParticleContainsIdentifier( pTrackingParticle, iIdentifierCountPair->first ) ) numberOfAssociatedHits+=iIdentifierCountPair->second;
275  }
276 
277  if( numberOfAssociatedHits>0 )
278  {
279  returnValue.push_back( std::make_pair( getRefToTrackingParticleAt(trackingParticles,i), numberOfAssociatedHits ) );
280  }
281  }
282 
283  return returnValue;
284 }
285 
286 template<typename T_TPCollection,typename iter> std::vector< std::pair<edm::Ref<TrackingParticleCollection>,size_t> > QuickTrackAssociatorByHitsImpl::associateTrack( const ClusterTPAssociationList& clusterToTPMap, T_TPCollection trackingParticles, iter begin, iter end ) const
287 {
288  // Note that the trackingParticles parameter is not actually required since all the information is in clusterToTPMap,
289  // but the method signature has to match the other overload because it is called from a templated method.
290 
291  // The pairs in this vector have a Ref to the associated TrackingParticle as "first" and the number of associated clusters as "second"
292  // Note: typedef edm::Ref<TrackingParticleCollection> TrackingParticleRef;
293  std::vector < std::pair<edm::Ref<TrackingParticleCollection>,size_t> > returnValue;
294  if( clusterToTPMap.empty() ) return returnValue;
295 
296  // The pairs in this vector have first as the TP, and second the number of reco clusters associated to that TP.
297  // Most reco clusters will probably have come from the same sim track (i.e TP), so the number of entries in this
298  // vector should be fewer than the number of clusters. The pair::second entries should add up to the total
299  // number of reco clusters though.
300  std::vector<OmniClusterRef> oClusters=getMatchedClusters( begin, end );
301 
302  std::map < TrackingParticleRef, size_t > lmap;
303  for( std::vector<OmniClusterRef>::const_iterator it=oClusters.begin(); it != oClusters.end(); ++it )
304  {
305 
306  std::pair < OmniClusterRef, TrackingParticleRef > clusterTPpairWithDummyTP( *it, TrackingParticleRef() ); //TP is dummy: for clusterTPAssociationListGreater sorting only the cluster is needed
307  auto range=std::equal_range( clusterToTPMap.begin(), clusterToTPMap.end(), clusterTPpairWithDummyTP, clusterTPAssociationListGreater );
308  if( range.first != range.second )
309  {
310  for( auto ip=range.first; ip != range.second; ++ip )
311  {
312 
313  const TrackingParticleRef trackingParticle=(ip->second);
314 
315  // Ignore TrackingParticles with no hits
316  if( trackingParticle->numberOfHits() == 0 ) continue;
317 
318  /* Alternative implementation to avoid the use of lmap... memory slightly improved but slightly slower...
319  std::pair<edm::Ref<TrackingParticleCollection>,size_t> tpIntPair(trackingParticle, 1);
320  auto tp_range = std::equal_range(returnValue.begin(), returnValue.end(), tpIntPair, tpIntPairGreater);
321  if ((tp_range.second-tp_range.first)>1) {
322  edm::LogError("TrackAssociator") << ">>> Error in counting TPs!" << " file: " << __FILE__ << " line: " << __LINE__;
323  }
324  if(tp_range.first != tp_range.second) {
325  tp_range.first->second++;
326  } else {
327  returnValue.push_back(tpIntPair);
328  std::sort(returnValue.begin(), returnValue.end(), tpIntPairGreater);
329  }
330  */
331  auto jpos=lmap.find( trackingParticle );
332  if( jpos != lmap.end() ) ++jpos->second;
333  else lmap.insert( std::make_pair( trackingParticle, 1 ) );
334  }
335  }
336  }
337  // now copy the map to returnValue
338  for( auto ip=lmap.begin(); ip != lmap.end(); ++ip )
339  {
340  returnValue.push_back( std::make_pair( ip->first, ip->second ) );
341  }
342  return returnValue;
343 }
344 
345 template<typename iter> std::vector<OmniClusterRef> QuickTrackAssociatorByHitsImpl::getMatchedClusters(iter begin, iter end) const
346 {
347  std::vector<OmniClusterRef> returnValue;
348  for (iter iRecHit = begin; iRecHit != end; ++iRecHit) {
349  const TrackingRecHit* rhit = getHitFromIter(iRecHit);
350  if (rhit->isValid()) {
351  int subdetid = rhit->geographicalId().subdetId();
353  const SiPixelRecHit* pRHit = dynamic_cast<const SiPixelRecHit*>(rhit);
354  if (!pRHit->cluster().isNonnull())
355  edm::LogError("TrackAssociator") << ">>> RecHit does not have an associated cluster!" << " file: " << __FILE__ << " line: " << __LINE__;
356  returnValue.push_back(pRHit->omniClusterRef());
357  }
358  else if (subdetid==SiStripDetId::TIB||subdetid==SiStripDetId::TOB||subdetid==SiStripDetId::TID||subdetid==SiStripDetId::TEC) {
359  const std::type_info &tid = typeid(*rhit);
360  if (tid == typeid(SiStripMatchedRecHit2D)) {
361  const SiStripMatchedRecHit2D* sMatchedRHit = dynamic_cast<const SiStripMatchedRecHit2D*>(rhit);
362  if (!sMatchedRHit->monoHit().cluster().isNonnull() || !sMatchedRHit->stereoHit().cluster().isNonnull())
363  edm::LogError("TrackAssociator") << ">>> RecHit does not have an associated cluster!" << " file: " << __FILE__ << " line: " << __LINE__;
364  returnValue.push_back(sMatchedRHit->monoClusterRef());
365  returnValue.push_back(sMatchedRHit->stereoClusterRef());
366  }
367  else if (tid == typeid(SiStripRecHit2D)) {
368  const SiStripRecHit2D* sRHit = dynamic_cast<const SiStripRecHit2D*>(rhit);
369  if (!sRHit->cluster().isNonnull())
370  edm::LogError("TrackAssociator") << ">>> RecHit does not have an associated cluster!" << " file: " << __FILE__ << " line: " << __LINE__;
371  returnValue.push_back(sRHit->omniClusterRef());
372  }
373  else if (tid == typeid(SiStripRecHit1D)) {
374  const SiStripRecHit1D* sRHit = dynamic_cast<const SiStripRecHit1D*>(rhit);
375  if (!sRHit->cluster().isNonnull())
376  edm::LogError("TrackAssociator") << ">>> RecHit does not have an associated cluster!" << " file: " << __FILE__ << " line: " << __LINE__;
377  returnValue.push_back(sRHit->omniClusterRef());
378  }
379  else {
380  auto const & thit = static_cast<BaseTrackerRecHit const&>(*rhit);
381  if ( thit.isProjected() ) {
382  } else {
383  edm::LogError("TrackAssociator") << ">>> getMatchedClusters: TrackingRecHit not associated to any SiStripCluster! subdetid = " << subdetid;
384  }
385  }
386  }
387  else {
388  edm::LogError("TrackAssociator") << ">>> getMatchedClusters: TrackingRecHit not associated to any cluster! subdetid = " << subdetid;
389  }
390  }
391  }
392  return returnValue;
393 }
394 
395 template<typename iter> std::vector< std::pair<QuickTrackAssociatorByHitsImpl::SimTrackIdentifiers,size_t> > QuickTrackAssociatorByHitsImpl::getAllSimTrackIdentifiers( const TrackerHitAssociator& hitAssociator, iter begin, iter end ) const
396 {
397  // The pairs in this vector have first as the sim track identifiers, and second the number of reco hits associated to that sim track.
398  std::vector < std::pair<SimTrackIdentifiers,size_t> > returnValue;
399 
400  std::vector<SimTrackIdentifiers> simTrackIdentifiers;
401  // Loop over all of the rec hits in the track
402  //iter tRHIterBeginEnd = getTRHIterBeginEnd( pTrack );
403  for( iter iRecHit=begin; iRecHit != end; ++iRecHit )
404  {
405  if( getHitFromIter( iRecHit )->isValid() )
406  {
407  simTrackIdentifiers.clear();
408 
409  // Get the identifiers for the sim track that this hit came from. There should only be one entry unless clusters
410  // have merged (as far as I know).
411  hitAssociator.associateHitId( *(getHitFromIter( iRecHit )), simTrackIdentifiers ); // This call fills simTrackIdentifiers
412  // Loop over each identifier, and add it to the return value only if it's not already in there
413  for( std::vector<SimTrackIdentifiers>::const_iterator iIdentifier=simTrackIdentifiers.begin(); iIdentifier != simTrackIdentifiers.end();
414  ++iIdentifier )
415  {
416  std::vector<std::pair<SimTrackIdentifiers,size_t> >::iterator iIdentifierCountPair;
417  for( iIdentifierCountPair=returnValue.begin(); iIdentifierCountPair != returnValue.end(); ++iIdentifierCountPair )
418  {
419  if( iIdentifierCountPair->first.first == iIdentifier->first && iIdentifierCountPair->first.second == iIdentifier->second )
420  {
421  // This sim track identifier is already in the list, so increment the count of how many hits it relates to.
422  ++iIdentifierCountPair->second;
423  break;
424  }
425  }
426  if( iIdentifierCountPair == returnValue.end() ) returnValue.push_back( std::make_pair( *iIdentifier, 1 ) );
427  // This identifier wasn't found, so add it
428  }
429  }
430  }
431  return returnValue;
432 }
433 
435 {
436  // Loop over all of the g4 tracks in the tracking particle
437  for( std::vector<SimTrack>::const_iterator iSimTrack=pTrackingParticle->g4Track_begin(); iSimTrack != pTrackingParticle->g4Track_end();
438  ++iSimTrack )
439  {
440  // And see if the sim track identifiers match
441  if( iSimTrack->eventId() == identifier.second && iSimTrack->trackId() == identifier.first )
442  {
443  return true;
444  }
445  }
446 
447  // If control has made it this far then none of the identifiers were found in
448  // any of the g4 tracks, so return false.
449  return false;
450 }
451 
452 template<typename iter> int QuickTrackAssociatorByHitsImpl::getDoubleCount( const TrackerHitAssociator& hitAssociator, iter startIterator, iter endIterator, TrackingParticleRef associatedTrackingParticle ) const
453 {
454  // This method is largely copied from the standard TrackAssociatorByHits. Once I've tested how much difference
455  // it makes I'll go through and comment it properly.
456 
457  int doubleCount=0;
458  std::vector < SimHitIdpr > SimTrackIdsDC;
459 
460  for( iter iHit=startIterator; iHit != endIterator; iHit++ )
461  {
462  int idcount=0;
463 
464  SimTrackIdsDC.clear();
465  hitAssociator.associateHitId( *(getHitFromIter( iHit )), SimTrackIdsDC );
466  if( SimTrackIdsDC.size() > 1 )
467  {
468  for( TrackingParticle::g4t_iterator g4T=associatedTrackingParticle->g4Track_begin(); g4T != associatedTrackingParticle->g4Track_end();
469  ++g4T )
470  {
471  if( find( SimTrackIdsDC.begin(), SimTrackIdsDC.end(), SimHitIdpr( ( *g4T).trackId(), SimTrackIdsDC.begin()->second ) )
472  != SimTrackIdsDC.end() )
473  {
474  idcount++;
475  }
476  }
477  }
478  if( idcount > 1 ) doubleCount+=(idcount - 1);
479  }
480 
481  return doubleCount;
482 }
483 
484 template<typename iter> int QuickTrackAssociatorByHitsImpl::getDoubleCount( const ClusterTPAssociationList& clusterToTPList, iter startIterator, iter endIterator, TrackingParticleRef associatedTrackingParticle ) const
485 {
486  // This code here was written by Subir Sarkar. I'm just splitting it off into a
487  // separate method. - Grimes 01/May/2014
488 
489  int doubleCount=0;
490  std::vector < SimHitIdpr > SimTrackIdsDC;
491 
492  for( iter iHit=startIterator; iHit != endIterator; iHit++ )
493  {
494  int idcount=0;
495 
496  std::vector < OmniClusterRef > oClusters=getMatchedClusters( iHit, iHit + 1 ); //only for the cluster being checked
497  for( std::vector<OmniClusterRef>::const_iterator it=oClusters.begin(); it != oClusters.end(); ++it )
498  {
499  std::pair<OmniClusterRef,TrackingParticleRef> clusterTPpairWithDummyTP( *it, TrackingParticleRef() ); //TP is dummy: for clusterTPAssociationListGreater sorting only the cluster is needed
500  auto range=std::equal_range( clusterToTPList.begin(), clusterToTPList.end(), clusterTPpairWithDummyTP, clusterTPAssociationListGreater );
501  if( range.first != range.second )
502  {
503  for( auto ip=range.first; ip != range.second; ++ip )
504  {
505  const TrackingParticleRef trackingParticle=(ip->second);
506  if( associatedTrackingParticle == trackingParticle )
507  {
508  idcount++;
509  }
510  }
511  }
512  }
513 
514  if( idcount > 1 ) doubleCount+=(idcount - 1);
515  }
516 
517  return doubleCount;
518 }
519 
521  const edm::Handle<TrackingParticleCollection>& trackingParticleCollectionHandle) const
522 {
523 
524  edm::LogVerbatim( "TrackAssociator" ) << "Starting TrackAssociatorByHitsImpl::associateRecoToSim - #seeds=" << pSeedCollectionHandle_->size()
525  << " #TPs=" << trackingParticleCollectionHandle->size();
526 
528 
529  size_t collectionSize=pSeedCollectionHandle_->size();
530 
531  for( size_t i=0; i < collectionSize; ++i )
532  {
533  const TrajectorySeed* pSeed= &( *pSeedCollectionHandle_)[i];
534 
535  // The return of this function has first as the index and second as the number of associated hits
536  std::vector < std::pair<edm::Ref<TrackingParticleCollection>,size_t> > trackingParticleQualityPairs=
537  (clusterToTPMap_) ? associateTrack( *clusterToTPMap_, trackingParticleCollectionHandle, pSeed->recHits().first, pSeed->recHits().second ) : associateTrack( *hitAssociator_, trackingParticleCollectionHandle, pSeed->recHits().first, pSeed->recHits().second );
538  for( std::vector<std::pair<edm::Ref<TrackingParticleCollection>,size_t> >::const_iterator iTrackingParticleQualityPair=
539  trackingParticleQualityPairs.begin(); iTrackingParticleQualityPair != trackingParticleQualityPairs.end();
540  ++iTrackingParticleQualityPair )
541  {
542  const edm::Ref<TrackingParticleCollection>& trackingParticleRef=iTrackingParticleQualityPair->first;
543  size_t numberOfSharedHits=iTrackingParticleQualityPair->second;
544  size_t numberOfValidTrackHits=pSeed->recHits().second - pSeed->recHits().first;
545 
546  if( numberOfSharedHits == 0 ) continue; // No point in continuing if there was no association
547 
548  //if electron subtract double counting
549  if( abs( trackingParticleRef->pdgId() ) == 11 && (trackingParticleRef->g4Track_end() - trackingParticleRef->g4Track_begin()) > 1 )
550  {
551  if( clusterToTPMap_ ) numberOfSharedHits-=getDoubleCount( *clusterToTPMap_, pSeed->recHits().first, pSeed->recHits().second, trackingParticleRef );
552  else numberOfSharedHits-=getDoubleCount( *hitAssociator_, pSeed->recHits().first, pSeed->recHits().second, trackingParticleRef );
553  }
554 
555  double quality;
556  if( absoluteNumberOfHits_ ) quality=static_cast<double>( numberOfSharedHits );
557  else if( numberOfValidTrackHits != 0 ) quality=
558  (static_cast<double>( numberOfSharedHits ) / static_cast<double>( numberOfValidTrackHits ));
559  else quality=0;
560 
561  if( quality > cutRecoToSim_ && !(threeHitTracksAreSpecial_ && numberOfValidTrackHits == 3 && numberOfSharedHits < 3) )
562  {
563  returnValue.insert( edm::RefToBase < TrajectorySeed > (pSeedCollectionHandle_, i), std::make_pair( trackingParticleRef, quality ) );
564  }
565  }
566  }
567 
568  LogTrace( "TrackAssociator" ) << "% of Assoc Seeds=" << ((double)returnValue.size()) / ((double)pSeedCollectionHandle_->size());
569  returnValue.post_insert();
570  return returnValue;
571 
572 }
573 
575  const edm::Handle<TrackingParticleCollection>& trackingParticleCollectionHandle) const
576 {
577 
578  edm::LogVerbatim( "TrackAssociator" ) << "Starting TrackAssociatorByHitsImpl::associateSimToReco - #seeds=" << pSeedCollectionHandle_->size()
579  << " #TPs=" << trackingParticleCollectionHandle->size();
580 
582 
583  size_t collectionSize=pSeedCollectionHandle_->size();
584 
585  for( size_t i=0; i < collectionSize; ++i )
586  {
587  const TrajectorySeed* pSeed= &( *pSeedCollectionHandle_)[i];
588 
589  // The return of this function has first as an edm:Ref to the associated TrackingParticle, and second as the number of associated hits
590  std::vector < std::pair<edm::Ref<TrackingParticleCollection>,size_t> > trackingParticleQualityPairs=
591  (clusterToTPMap_) ? associateTrack( *clusterToTPMap_, trackingParticleCollectionHandle, pSeed->recHits().first, pSeed->recHits().second ) : associateTrack( *hitAssociator_, trackingParticleCollectionHandle, pSeed->recHits().first, pSeed->recHits().second );
592  for( std::vector<std::pair<edm::Ref<TrackingParticleCollection>,size_t> >::const_iterator iTrackingParticleQualityPair=
593  trackingParticleQualityPairs.begin(); iTrackingParticleQualityPair != trackingParticleQualityPairs.end();
594  ++iTrackingParticleQualityPair )
595  {
596  const edm::Ref<TrackingParticleCollection>& trackingParticleRef=iTrackingParticleQualityPair->first;
597  size_t numberOfSharedHits=iTrackingParticleQualityPair->second;
598  size_t numberOfValidTrackHits=pSeed->recHits().second - pSeed->recHits().first;
599  size_t numberOfSimulatedHits=0; // Set a few lines below, but only if required.
600 
601  if( numberOfSharedHits == 0 ) continue; // No point in continuing if there was no association
602 
603  //if electron subtract double counting
604  if( abs( trackingParticleRef->pdgId() ) == 11 && (trackingParticleRef->g4Track_end() - trackingParticleRef->g4Track_begin()) > 1 )
605  {
606  if( clusterToTPMap_ ) numberOfSharedHits-=getDoubleCount( *clusterToTPMap_, pSeed->recHits().first, pSeed->recHits().second, trackingParticleRef );
607  else numberOfSharedHits-=getDoubleCount( *hitAssociator_, pSeed->recHits().first, pSeed->recHits().second, trackingParticleRef );
608  }
609 
610  if( simToRecoDenominator_ == denomsim || (numberOfSharedHits < 3 && threeHitTracksAreSpecial_) ) // the numberOfSimulatedHits is not always required, so can skip counting in some circumstances
611  {
612  // Note that in the standard TrackAssociatorByHits, all of the hits in associatedTrackingParticleHits are checked for
613  // various things. I'm not sure what these checks are for but they depend on the UseGrouping and UseSplitting settings.
614  // This associator works as though both UseGrouping and UseSplitting were set to true, i.e. just counts the number of
615  // hits in the tracker.
616  numberOfSimulatedHits=trackingParticleRef->numberOfTrackerHits();
617  }
618 
619  double purity=static_cast<double>( numberOfSharedHits ) / static_cast<double>( numberOfValidTrackHits );
620  double quality;
621  if( absoluteNumberOfHits_ ) quality=static_cast<double>( numberOfSharedHits );
622  else if( simToRecoDenominator_ == denomsim && numberOfSimulatedHits != 0 ) quality=static_cast<double>( numberOfSharedHits )
623  / static_cast<double>( numberOfSimulatedHits );
624  else if( simToRecoDenominator_ == denomreco && numberOfValidTrackHits != 0 ) quality=purity;
625  else quality=0;
626 
627  if( quality > qualitySimToReco_ && !(threeHitTracksAreSpecial_ && numberOfSimulatedHits == 3 && numberOfSharedHits < 3)
628  && (absoluteNumberOfHits_ || (purity > puritySimToReco_)) )
629  {
630  returnValue.insert( trackingParticleRef, std::make_pair( edm::RefToBase < TrajectorySeed > (pSeedCollectionHandle_, i), quality ) );
631  }
632  }
633  }
634 
635  LogTrace("TrackAssociator") << "% of Assoc TPs=" << ((double)returnValue.size())/((double)trackingParticleCollectionHandle->size());
636  returnValue.post_insert();
637  return returnValue;
638 }
ClusterRef cluster() const
int i
Definition: DBlmapReader.cc:9
bool isNonnull() const
Checks for non-null.
Definition: Ref.h:252
virtual reco::RecoToSimCollection associateRecoToSim(const edm::Handle< edm::View< reco::Track > > &trackCollectionHandle, const edm::Handle< TrackingParticleCollection > &trackingParticleCollectionHandle) const override
compare reco to sim the handle of reco::Track and TrackingParticle collections
bool clusterTPAssociationListGreater(std::pair< OmniClusterRef, TrackingParticleRef > i, std::pair< OmniClusterRef, TrackingParticleRef > j)
g4t_iterator g4Track_begin() const
OmniClusterRef const & stereoClusterRef() const
edm::EDProductGetter const * productGetter_
creates either a ClusterTPAssociationList OR a TrackerHitAssociator and stores it in the provided uni...
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:7
EDProductGetter const * productGetter(std::atomic< void const * > const &iCache)
QuickTrackAssociatorByHitsImpl(edm::EDProductGetter const &productGetter, std::unique_ptr< const TrackerHitAssociator > hitAssoc, const ClusterTPAssociationList *clusterToTPMap, bool absoluteNumberOfHits, double qualitySimToReco, double puritySimToReco, double cutRecoToSim, bool threeHitTracksAreSpecial, SimToRecoDenomType simToRecoDenominator)
virtual reco::SimToRecoCollection associateSimToReco(const edm::Handle< edm::View< reco::Track > > &trackCollectionHandle, const edm::Handle< TrackingParticleCollection > &trackingParticleCollectionHandle) const override
compare reco to sim the handle of reco::Track and TrackingParticle collections
reco::RecoToSimCollection associateRecoToSimImplementation(T_TrackCollection trackCollection, T_TrackingParticleCollection trackingParticleCollection, T_hitOrClusterAssociator hitOrClusterAssociator) const
The method that does the work for both overloads of associateRecoToSim.
const TrackingRecHit * getHitFromIter(trackingRecHit_iterator iter) const
std::vector< std::pair< SimTrackIdentifiers, size_t > > getAllSimTrackIdentifiers(const TrackerHitAssociator &hitAssociator, iter begin, iter end) const
Returns a vector of pairs where first is a SimTrackIdentifiers (see typedef above) and second is the ...
void post_insert()
post insert action
def move
Definition: eostools.py:510
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
ClusterRef cluster() const
#define end
Definition: vmac.h:37
size_type size() const
trackingRecHit_iterator recHitsBegin() const
Iterator to first hit on the track.
Definition: Track.h:104
OmniClusterRef const & monoClusterRef() const
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:37
#define LogTrace(id)
std::vector< SimTrack >::const_iterator g4t_iterator
OmniClusterRef const & omniClusterRef() const
std::vector< std::pair< OmniClusterRef, TrackingParticleRef > > ClusterTPAssociationList
std::pair< uint32_t, EncodedEventId > SimTrackIdentifiers
This is enough information to uniquely identify a sim track.
std::pair< uint32_t, EncodedEventId > SimHitIdpr
SiStripRecHit2D stereoHit() const
std::vector< std::pair< edm::Ref< TrackingParticleCollection >, size_t > > associateTrack(const TrackerHitAssociator &hitAssociator, T_TPCollection trackingParticles, iter begin, iter end) const
Returns the TrackingParticle that has the most associated hits to the given track.
int getDoubleCount(const TrackerHitAssociator &hitAssociator, iter begin, iter end, TrackingParticleRef associatedTrackingParticle) const
This method was copied almost verbatim from the standard TrackAssociatorByHits.
size_type size() const
map size
T const * product() const
Definition: Handle.h:81
void insert(const key_type &k, const data_type &v)
insert an association
ClusterRef cluster() const
Definition: SiPixelRecHit.h:49
range recHits() const
bool isValid() const
string const
Definition: compareJSON.py:14
int numberOfHits() const
Gives the total number of hits, including muon hits. Hits on overlaps in the same layer count separat...
const ClusterTPAssociationList * clusterToTPMap_
SiStripRecHit2D monoHit() const
std::vector< SimHitIdpr > associateHitId(const TrackingRecHit &thit) const
#define begin
Definition: vmac.h:30
reco::SimToRecoCollection associateSimToRecoImplementation(T_TrackCollection trackCollection, T_TrackingParticleCollection trackingParticleCollection, T_hitOrClusterAssociator hitOrClusterAssociator) const
The method that does the work for both overloads of associateSimToReco.
unsigned short found() const
Number of valid hits on track.
Definition: Track.h:194
size_type size() const
Size of the RefVector.
Definition: RefVector.h:99
Monte Carlo truth information used for tracking validation.
DetId geographicalId() const
g4t_iterator g4Track_end() const
edm::Ref< TrackingParticleCollection > TrackingParticleRef
bool trackingParticleContainsIdentifier(const TrackingParticle *pTrackingParticle, const SimTrackIdentifiers &identifier) const
Returns true if the supplied TrackingParticle has the supplied g4 track identifiers.
std::vector< OmniClusterRef > getMatchedClusters(iter begin, iter end) const
Our base class.
Definition: SiPixelRecHit.h:23
std::unique_ptr< const TrackerHitAssociator > hitAssociator_
trackingRecHit_iterator recHitsEnd() const
Iterator to last hit on the track.
Definition: Track.h:109