00001 #include "SimTracker/TrackAssociation/interface/QuickTrackAssociatorByHits.h"
00002
00003 #include "SimTracker/TrackerHitAssociation/interface/TrackerHitAssociator.h"
00004 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00005
00006 QuickTrackAssociatorByHits::QuickTrackAssociatorByHits( const edm::ParameterSet& config )
00007 : pHitAssociator_(NULL), pEventForWhichAssociatorIsValid_(NULL),
00008 absoluteNumberOfHits_( config.getParameter<bool>( "AbsoluteNumberOfHits" ) ),
00009 qualitySimToReco_( config.getParameter<double>( "Quality_SimToReco" ) ),
00010 puritySimToReco_( config.getParameter<double>( "Purity_SimToReco" ) ),
00011 cutRecoToSim_( config.getParameter<double>( "Cut_RecoToSim" ) ),
00012 threeHitTracksAreSpecial_( config.getParameter<bool> ( "ThreeHitTracksAreSpecial" ) )
00013 {
00014
00015
00016
00017
00018 std::string denominatorString=config.getParameter<std::string>("SimToRecoDenominator");
00019 if( denominatorString=="sim" ) simToRecoDenominator_=denomsim;
00020 else if( denominatorString=="reco" ) simToRecoDenominator_=denomreco;
00021 else throw cms::Exception( "QuickTrackAssociatorByHits" ) << "SimToRecoDenominator not specified as sim or reco";
00022
00023
00024
00025
00026 hitAssociatorParameters_.addParameter<bool>( "associatePixel", config.getParameter<bool>("associatePixel") );
00027 hitAssociatorParameters_.addParameter<bool>( "associateStrip", config.getParameter<bool>("associateStrip") );
00028
00029
00030
00031 hitAssociatorParameters_.addParameter<bool>("associateRecoTracks",true);
00032
00033
00034
00035
00036
00037 bool useGrouped, useSplitting;
00038 if( config.exists("UseGrouped") ) useGrouped=config.getParameter<bool>("UseGrouped");
00039 else useGrouped=true;
00040
00041 if( config.exists("UseSplitting") ) useSplitting=config.getParameter<bool>("UseSplitting");
00042 else useSplitting=true;
00043
00044
00045
00046 if( !(useGrouped && useSplitting) )
00047 {
00048 edm::LogWarning("QuickTrackAssociatorByHits") << "UseGrouped and/or UseSplitting has been set to false, but this associator ignores that setting.";
00049 }
00050 }
00051
00052 QuickTrackAssociatorByHits::~QuickTrackAssociatorByHits()
00053 {
00054 delete pHitAssociator_;
00055 }
00056
00057 QuickTrackAssociatorByHits::QuickTrackAssociatorByHits( const QuickTrackAssociatorByHits& otherAssociator )
00058 : pEventForWhichAssociatorIsValid_(otherAssociator.pEventForWhichAssociatorIsValid_),
00059 hitAssociatorParameters_(otherAssociator.hitAssociatorParameters_),
00060 absoluteNumberOfHits_(otherAssociator.absoluteNumberOfHits_),
00061 qualitySimToReco_(otherAssociator.qualitySimToReco_),
00062 puritySimToReco_(otherAssociator.puritySimToReco_),
00063 cutRecoToSim_(otherAssociator.cutRecoToSim_),
00064 threeHitTracksAreSpecial_(otherAssociator.threeHitTracksAreSpecial_),
00065 simToRecoDenominator_(otherAssociator.simToRecoDenominator_),
00066 pTrackCollectionHandle_(otherAssociator.pTrackCollectionHandle_),
00067 pTrackCollection_(otherAssociator.pTrackCollection_),
00068 pTrackingParticleCollectionHandle_(otherAssociator.pTrackingParticleCollectionHandle_),
00069 pTrackingParticleCollection_(otherAssociator.pTrackingParticleCollection_)
00070
00071 {
00072
00073
00074
00075
00076
00077
00078
00079 if( otherAssociator.pHitAssociator_ ) pHitAssociator_=new TrackerHitAssociator(*otherAssociator.pHitAssociator_);
00080 else pHitAssociator_=NULL;
00081 }
00082
00083 QuickTrackAssociatorByHits& QuickTrackAssociatorByHits::operator=( const QuickTrackAssociatorByHits& otherAssociator )
00084 {
00085
00086 delete pHitAssociator_;
00087
00088
00089
00090
00091
00092 if( otherAssociator.pHitAssociator_ ) pHitAssociator_=new TrackerHitAssociator(*otherAssociator.pHitAssociator_);
00093 else pHitAssociator_=NULL;
00094 pEventForWhichAssociatorIsValid_=otherAssociator.pEventForWhichAssociatorIsValid_;
00095 hitAssociatorParameters_=otherAssociator.hitAssociatorParameters_;
00096 absoluteNumberOfHits_=otherAssociator.absoluteNumberOfHits_;
00097 qualitySimToReco_=otherAssociator.qualitySimToReco_;
00098 puritySimToReco_=otherAssociator.puritySimToReco_;
00099 cutRecoToSim_=otherAssociator.cutRecoToSim_;
00100 threeHitTracksAreSpecial_=otherAssociator.threeHitTracksAreSpecial_;
00101 simToRecoDenominator_=otherAssociator.simToRecoDenominator_;
00102 pTrackCollectionHandle_=otherAssociator.pTrackCollectionHandle_;
00103 pTrackCollection_=otherAssociator.pTrackCollection_;
00104 pTrackingParticleCollectionHandle_=otherAssociator.pTrackingParticleCollectionHandle_;
00105 pTrackingParticleCollection_=otherAssociator.pTrackingParticleCollection_;
00106
00107 return *this;
00108 }
00109
00110 reco::RecoToSimCollection QuickTrackAssociatorByHits::associateRecoToSim( edm::Handle<edm::View<reco::Track> >& trackCollectionHandle,
00111 edm::Handle<TrackingParticleCollection>& trackingParticleCollectionHandle,
00112 const edm::Event* pEvent,
00113 const edm::EventSetup* pSetup ) const
00114 {
00115 initialiseHitAssociator( pEvent );
00116 pTrackCollectionHandle_=&trackCollectionHandle;
00117 pTrackingParticleCollectionHandle_=&trackingParticleCollectionHandle;
00118 pTrackCollection_=NULL;
00119 pTrackingParticleCollection_=NULL;
00120
00121
00122 return associateRecoToSimImplementation();
00123 }
00124
00125 reco::SimToRecoCollection QuickTrackAssociatorByHits::associateSimToReco( edm::Handle<edm::View<reco::Track> >& trackCollectionHandle,
00126 edm::Handle<TrackingParticleCollection>& trackingParticleCollectionHandle,
00127 const edm::Event * pEvent,
00128 const edm::EventSetup * pSetup ) const
00129 {
00130 initialiseHitAssociator( pEvent );
00131 pTrackCollectionHandle_=&trackCollectionHandle;
00132 pTrackingParticleCollectionHandle_=&trackingParticleCollectionHandle;
00133 pTrackCollection_=NULL;
00134 pTrackingParticleCollection_=NULL;
00135
00136
00137 return associateSimToRecoImplementation();
00138 }
00139
00140
00141 reco::RecoToSimCollection QuickTrackAssociatorByHits::associateRecoToSim(const edm::RefToBaseVector<reco::Track>& trackCollection,
00142 const edm::RefVector<TrackingParticleCollection>& trackingParticleCollection,
00143 const edm::Event* pEvent,
00144 const edm::EventSetup* pSetup ) const
00145 {
00146 initialiseHitAssociator( pEvent );
00147 pTrackCollectionHandle_=NULL;
00148 pTrackingParticleCollectionHandle_=NULL;
00149 pTrackCollection_=&trackCollection;
00150 pTrackingParticleCollection_=&trackingParticleCollection;
00151
00152
00153 return associateRecoToSimImplementation();
00154 }
00155
00156 reco::SimToRecoCollection QuickTrackAssociatorByHits::associateSimToReco(const edm::RefToBaseVector<reco::Track>& trackCollection,
00157 const edm::RefVector<TrackingParticleCollection>& trackingParticleCollection,
00158 const edm::Event* pEvent,
00159 const edm::EventSetup* pSetup ) const
00160 {
00161 initialiseHitAssociator( pEvent );
00162 pTrackCollectionHandle_=NULL;
00163 pTrackingParticleCollectionHandle_=NULL;
00164 pTrackCollection_=&trackCollection;
00165 pTrackingParticleCollection_=&trackingParticleCollection;
00166
00167
00168 return associateSimToRecoImplementation();
00169 }
00170
00171 reco::RecoToSimCollection QuickTrackAssociatorByHits::associateRecoToSimImplementation() const
00172 {
00173 reco::RecoToSimCollection returnValue;
00174
00175 size_t collectionSize;
00176
00177 if( pTrackCollection_ ) collectionSize=pTrackCollection_->size();
00178 else collectionSize=(*pTrackCollectionHandle_)->size();
00179
00180 for( size_t i=0; i<collectionSize; ++i )
00181 {
00182 const reco::Track* pTrack;
00183 if( pTrackCollection_ ) pTrack=&*(*pTrackCollection_)[i];
00184 else pTrack=&(*pTrackCollectionHandle_->product())[i];
00185
00186
00187 std::vector< std::pair<edm::Ref<TrackingParticleCollection>,size_t> > trackingParticleQualityPairs=associateTrack( pTrack );
00188 for( std::vector< std::pair<edm::Ref<TrackingParticleCollection>,size_t> >::const_iterator iTrackingParticleQualityPair=trackingParticleQualityPairs.begin();
00189 iTrackingParticleQualityPair!=trackingParticleQualityPairs.end(); ++iTrackingParticleQualityPair )
00190 {
00191 const edm::Ref<TrackingParticleCollection>& trackingParticleRef=iTrackingParticleQualityPair->first;
00192 size_t numberOfSharedHits=iTrackingParticleQualityPair->second;
00193 size_t numberOfValidTrackHits=pTrack->found();
00194
00195 if( numberOfSharedHits==0 ) continue;
00196
00197
00198 if( abs(trackingParticleRef->pdgId())==11 && (trackingParticleRef->g4Track_end() - trackingParticleRef->g4Track_begin()) > 1 )
00199 {
00200 numberOfSharedHits-=getDoubleCount( pTrack->recHitsBegin(), pTrack->recHitsEnd(), *trackingParticleRef );
00201 }
00202
00203 double quality;
00204 if( absoluteNumberOfHits_ ) quality=static_cast<double>( numberOfSharedHits );
00205 else if( numberOfValidTrackHits != 0 ) quality=(static_cast<double>(numberOfSharedHits) / static_cast<double>(numberOfValidTrackHits) );
00206 else quality=0;
00207
00208 if( quality > cutRecoToSim_ && !( threeHitTracksAreSpecial_ && numberOfValidTrackHits==3 && numberOfSharedHits<3 ) )
00209 {
00210 if( pTrackCollection_ ) returnValue.insert( (*pTrackCollection_)[i], std::make_pair( trackingParticleRef, quality ));
00211 else returnValue.insert( edm::RefToBase<reco::Track>(*pTrackCollectionHandle_,i), std::make_pair( trackingParticleRef, quality ));
00212 }
00213 }
00214 }
00215 return returnValue;
00216 }
00217
00218 reco::SimToRecoCollection QuickTrackAssociatorByHits::associateSimToRecoImplementation() const
00219 {
00220 reco::SimToRecoCollection returnValue;
00221
00222 size_t collectionSize;
00223
00224 if( pTrackCollection_ ) collectionSize=pTrackCollection_->size();
00225 else collectionSize=(*pTrackCollectionHandle_)->size();
00226
00227 for( size_t i=0; i<collectionSize; ++i )
00228 {
00229 const reco::Track* pTrack;
00230 if( pTrackCollection_ ) pTrack=&*(*pTrackCollection_)[i];
00231 else pTrack=&(*pTrackCollectionHandle_->product())[i];
00232
00233
00234 std::vector< std::pair<edm::Ref<TrackingParticleCollection>,size_t> > trackingParticleQualityPairs=associateTrack( pTrack );
00235 for( std::vector< std::pair<edm::Ref<TrackingParticleCollection>,size_t> >::const_iterator iTrackingParticleQualityPair=trackingParticleQualityPairs.begin();
00236 iTrackingParticleQualityPair!=trackingParticleQualityPairs.end(); ++iTrackingParticleQualityPair )
00237 {
00238 const edm::Ref<TrackingParticleCollection>& trackingParticleRef=iTrackingParticleQualityPair->first;
00239 size_t numberOfSharedHits=iTrackingParticleQualityPair->second;
00240 size_t numberOfValidTrackHits=pTrack->found();
00241 size_t numberOfSimulatedHits=0;
00242
00243 if( numberOfSharedHits==0 ) continue;
00244
00245 if( simToRecoDenominator_==denomsim || (numberOfSharedHits<3 && threeHitTracksAreSpecial_) )
00246 {
00247
00248
00249
00250
00251 numberOfSimulatedHits=trackingParticleRef->trackPSimHit(DetId::Tracker).size();
00252 }
00253
00254 double purity=static_cast<double>(numberOfSharedHits)/static_cast<double>(numberOfValidTrackHits);
00255 double quality;
00256 if( absoluteNumberOfHits_ ) quality=static_cast<double>(numberOfSharedHits);
00257 else if( simToRecoDenominator_==denomsim && numberOfSimulatedHits != 0 ) quality=static_cast<double>(numberOfSharedHits)/static_cast<double>(numberOfSimulatedHits);
00258 else if( simToRecoDenominator_==denomreco && numberOfValidTrackHits != 0 ) quality=purity;
00259 else quality=0;
00260
00261 if( quality>qualitySimToReco_ && !( threeHitTracksAreSpecial_ && numberOfSimulatedHits==3 && numberOfSharedHits<3 ) && ( absoluteNumberOfHits_ || (purity>puritySimToReco_) ) )
00262 {
00263 if( pTrackCollection_ ) returnValue.insert( trackingParticleRef, std::make_pair( (*pTrackCollection_)[i], quality ) );
00264 else returnValue.insert( trackingParticleRef, std::make_pair( edm::RefToBase<reco::Track>(*pTrackCollectionHandle_,i) , quality ) );
00265 }
00266 }
00267 }
00268 return returnValue;
00269
00270 }
00271
00272 std::vector< std::pair<edm::Ref<TrackingParticleCollection>,size_t> > QuickTrackAssociatorByHits::associateTrack( const reco::Track* pTrack ) const
00273 {
00274
00275 std::vector< std::pair<edm::Ref<TrackingParticleCollection>,size_t> > returnValue;
00276
00277
00278
00279
00280 std::vector< std::pair<SimTrackIdentifiers,size_t> > hitIdentifiers=getAllSimTrackIdentifiers(pTrack);
00281
00282
00283 size_t collectionSize;
00284 if( pTrackingParticleCollection_ ) collectionSize=pTrackingParticleCollection_->size();
00285 else collectionSize=(*pTrackingParticleCollectionHandle_)->size();
00286
00287 for( size_t i=0; i<collectionSize; ++i )
00288 {
00289 const TrackingParticle* pTrackingParticle;
00290 if( pTrackingParticleCollection_ ) pTrackingParticle=&*(*pTrackingParticleCollection_)[i];
00291 else pTrackingParticle=&(*pTrackingParticleCollectionHandle_->product())[i];
00292
00293
00294 if( pTrackingParticle->trackPSimHit().empty() ) continue;
00295
00296 size_t numberOfAssociatedHits=0;
00297
00298
00299 for( std::vector< std::pair<SimTrackIdentifiers,size_t> >::const_iterator iIdentifierCountPair=hitIdentifiers.begin(); iIdentifierCountPair!=hitIdentifiers.end(); ++iIdentifierCountPair )
00300 {
00301 if( trackingParticleContainsIdentifier( pTrackingParticle, iIdentifierCountPair->first ) ) numberOfAssociatedHits+=iIdentifierCountPair->second;
00302 }
00303
00304 if( numberOfAssociatedHits>0 )
00305 {
00306 if( pTrackingParticleCollection_ ) returnValue.push_back( std::make_pair( (*pTrackingParticleCollection_)[i], numberOfAssociatedHits ) );
00307 else returnValue.push_back( std::make_pair( edm::Ref<TrackingParticleCollection>( *pTrackingParticleCollectionHandle_, i ), numberOfAssociatedHits ) );
00308 }
00309 }
00310
00311 return returnValue;
00312 }
00313
00314 std::vector< std::pair<QuickTrackAssociatorByHits::SimTrackIdentifiers,size_t> > QuickTrackAssociatorByHits::getAllSimTrackIdentifiers( const reco::Track* pTrack ) const
00315 {
00316
00317 std::vector< std::pair<SimTrackIdentifiers,size_t> > returnValue;
00318
00319 std::vector<SimTrackIdentifiers> simTrackIdentifiers;
00320
00321 for( trackingRecHit_iterator iRecHit=pTrack->recHitsBegin(); iRecHit!=pTrack->recHitsEnd(); ++iRecHit )
00322 {
00323 if( (*iRecHit)->isValid() )
00324 {
00325 simTrackIdentifiers.clear();
00326
00327
00328
00329 pHitAssociator_->associateHitId( **iRecHit, simTrackIdentifiers );
00330
00331
00332 for( std::vector<SimTrackIdentifiers>::const_iterator iIdentifier=simTrackIdentifiers.begin(); iIdentifier!=simTrackIdentifiers.end(); ++iIdentifier )
00333 {
00334 std::vector< std::pair<SimTrackIdentifiers,size_t> >::iterator iIdentifierCountPair;
00335 for( iIdentifierCountPair=returnValue.begin(); iIdentifierCountPair!=returnValue.end(); ++iIdentifierCountPair )
00336 {
00337 if( iIdentifierCountPair->first.first==iIdentifier->first && iIdentifierCountPair->first.second==iIdentifier->second )
00338 {
00339
00340 ++iIdentifierCountPair->second;
00341 break;
00342 }
00343 }
00344 if( iIdentifierCountPair==returnValue.end() ) returnValue.push_back( std::make_pair(*iIdentifier,1) );
00345 }
00346 }
00347 }
00348
00349 return returnValue;
00350 }
00351
00352 bool QuickTrackAssociatorByHits::trackingParticleContainsIdentifier( const TrackingParticle* pTrackingParticle, const SimTrackIdentifiers& identifier ) const
00353 {
00354
00355 for( std::vector<SimTrack>::const_iterator iSimTrack=pTrackingParticle->g4Track_begin(); iSimTrack!=pTrackingParticle->g4Track_end(); ++iSimTrack )
00356 {
00357
00358 if( iSimTrack->eventId()==identifier.second && iSimTrack->trackId()==identifier.first )
00359 {
00360 return true;
00361 }
00362 }
00363
00364
00365
00366 return false;
00367 }
00368
00369 int QuickTrackAssociatorByHits::getDoubleCount( trackingRecHit_iterator startIterator, trackingRecHit_iterator endIterator, const TrackingParticle& associatedTrackingParticle ) const
00370 {
00371
00372
00373
00374 int doubleCount=0;
00375 std::vector<SimHitIdpr> SimTrackIdsDC;
00376
00377 for( trackingRecHit_iterator iHit=startIterator; iHit != endIterator; iHit++ )
00378 {
00379 int idcount=0;
00380 SimTrackIdsDC.clear();
00381 pHitAssociator_->associateHitId( **iHit, SimTrackIdsDC );
00382
00383 if( SimTrackIdsDC.size() > 1 )
00384 {
00385 for( TrackingParticle::g4t_iterator g4T=associatedTrackingParticle.g4Track_begin(); g4T != associatedTrackingParticle.g4Track_end(); ++g4T )
00386 {
00387 if( find( SimTrackIdsDC.begin(), SimTrackIdsDC.end(), SimHitIdpr( ( *g4T).trackId(), SimTrackIdsDC.begin()->second ) )
00388 != SimTrackIdsDC.end() )
00389 {
00390 idcount++;
00391 }
00392 }
00393 }
00394 if( idcount > 1 ) doubleCount+=(idcount - 1);
00395 }
00396
00397 return doubleCount;
00398 }
00399
00400
00401 void QuickTrackAssociatorByHits::initialiseHitAssociator( const edm::Event* pEvent ) const
00402 {
00403
00404
00405
00406
00407
00408
00409
00410
00411 delete pHitAssociator_;
00412
00413
00414 pHitAssociator_=new TrackerHitAssociator( *pEvent, hitAssociatorParameters_ );
00415 pEventForWhichAssociatorIsValid_=pEvent;
00416 }
00417