00001
00002
00003 #include "FWCore/Framework/interface/Frameworkfwd.h"
00004 #include "FWCore/Framework/interface/Event.h"
00005 #include "FWCore/Framework/interface/EventSetup.h"
00006 #include "FWCore/Framework/interface/ESHandle.h"
00007 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00008 #include "DataFormats/Common/interface/Ref.h"
00009 #include "SimTracker/TrackAssociation/interface/TrackAssociatorByHits.h"
00010 #include "SimTracker/TrackerHitAssociation/interface/TrackerHitAssociator.h"
00011 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00012 #include "FWCore/Utilities/interface/Exception.h"
00013
00014
00015 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00016 #include "DataFormats/TrackReco/interface/Track.h"
00017 #include "DataFormats/TrackingRecHit/interface/TrackingRecHit.h"
00018
00019 #include "SimDataFormats/TrackingAnalysis/interface/TrackingParticle.h"
00020 #include "SimDataFormats/TrackingAnalysis/interface/TrackingParticleFwd.h"
00021 #include "SimGeneral/TrackingAnalysis/interface/SimHitTPAssociationProducer.h"
00022 #include "SimDataFormats/EncodedEventId/interface/EncodedEventId.h"
00023
00024 #include "Geometry/CommonDetUnit/interface/GeomDetUnit.h"
00025 #include "DataFormats/DetId/interface/DetId.h"
00026 #include "Geometry/TrackerGeometryBuilder/interface/TrackerGeometry.h"
00027 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
00028 #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
00029 #include "DataFormats/TrackerCommon/interface/TrackerTopology.h"
00030 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00031 using namespace reco;
00032 using namespace std;
00033
00034
00035 TrackAssociatorByHits::TrackAssociatorByHits (const edm::ParameterSet& conf) :
00036 conf_(conf),
00037 AbsoluteNumberOfHits(conf_.getParameter<bool>("AbsoluteNumberOfHits")),
00038 SimToRecoDenominator(denomnone),
00039 quality_SimToReco(conf_.getParameter<double>("Quality_SimToReco")),
00040 purity_SimToReco(conf_.getParameter<double>("Purity_SimToReco")),
00041 cut_RecoToSim(conf_.getParameter<double>("Cut_RecoToSim")),
00042 UsePixels(conf_.getParameter<bool>("UsePixels")),
00043 UseGrouped(conf_.getParameter<bool>("UseGrouped")),
00044 UseSplitting(conf_.getParameter<bool>("UseSplitting")),
00045 ThreeHitTracksAreSpecial(conf_.getParameter<bool>("ThreeHitTracksAreSpecial")),
00046 _simHitTpMapTag(conf_.getParameter<edm::InputTag>("simHitTpMapTag"))
00047 {
00048 std::string tmp = conf_.getParameter<string>("SimToRecoDenominator");
00049 if (tmp=="sim") {
00050 SimToRecoDenominator = denomsim;
00051 } else if (tmp == "reco") {
00052 SimToRecoDenominator = denomreco;
00053 }
00054
00055 if (SimToRecoDenominator == denomnone) {
00056 throw cms::Exception("TrackAssociatorByHits") << "SimToRecoDenominator not specified as sim or reco";
00057 }
00058
00059 }
00060
00061
00062
00063 TrackAssociatorByHits::~TrackAssociatorByHits()
00064 {
00065
00066 }
00067
00068
00069
00070
00071
00072 RecoToSimCollection
00073 TrackAssociatorByHits::associateRecoToSim(const edm::RefToBaseVector<reco::Track>& tC,
00074 const edm::RefVector<TrackingParticleCollection>& TPCollectionH,
00075 const edm::Event * e,
00076 const edm::EventSetup *setup ) const{
00077
00078
00079 int nshared = 0;
00080 float quality=0;
00081 std::vector< SimHitIdpr> SimTrackIds;
00082 std::vector< SimHitIdpr> matchedIds;
00083 RecoToSimCollection outputCollection;
00084
00085 TrackerHitAssociator * associate = new TrackerHitAssociator(*e, conf_);
00086
00087 TrackingParticleCollection tPC;
00088 if (TPCollectionH.size()!=0) tPC = *const_cast<TrackingParticleCollection*>(TPCollectionH.product());
00089
00090
00091 int tindex=0;
00092 for (edm::RefToBaseVector<reco::Track>::const_iterator track=tC.begin(); track!=tC.end(); track++, tindex++){
00093 matchedIds.clear();
00094 int ri=0;
00095
00096 getMatchedIds<trackingRecHit_iterator>(matchedIds, SimTrackIds, ri, (*track)->recHitsBegin(), (*track)->recHitsEnd(), associate);
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106 std::vector<SimHitIdpr> idcachev;
00107 if(!matchedIds.empty()){
00108
00109 int tpindex =0;
00110 for (TrackingParticleCollection::iterator t = tPC.begin(); t != tPC.end(); ++t, ++tpindex) {
00111
00112
00113 idcachev.clear();
00114 nshared = getShared(matchedIds, idcachev, t);
00115
00116
00117 if (abs(t->pdgId())==11&&(t->g4Track_end()-t->g4Track_begin())>1){
00118 nshared-=getDoubleCount<trackingRecHit_iterator>((*track)->recHitsBegin(), (*track)->recHitsEnd(), associate, t);
00119 }
00120
00121 if (AbsoluteNumberOfHits) quality = static_cast<double>(nshared);
00122 else if(ri!=0) quality = (static_cast<double>(nshared)/static_cast<double>(ri));
00123 else quality = 0;
00124
00125
00126 if(quality > cut_RecoToSim && !(ThreeHitTracksAreSpecial && ri==3 && nshared<3)){
00127
00128 outputCollection.insert(tC[tindex],
00129 std::make_pair(edm::Ref<TrackingParticleCollection>(TPCollectionH, tpindex),
00130 quality));
00131
00132
00133
00134
00135
00136 } else {
00137
00138
00139 }
00140 }
00141 }
00142 }
00143
00144 delete associate;
00145 outputCollection.post_insert();
00146 return outputCollection;
00147 }
00148
00149
00150 SimToRecoCollection
00151 TrackAssociatorByHits::associateSimToReco(const edm::RefToBaseVector<reco::Track>& tC,
00152 const edm::RefVector<TrackingParticleCollection>& TPCollectionH,
00153 const edm::Event * e,
00154 const edm::EventSetup *setup ) const{
00155
00156 edm::ESHandle<TrackerTopology> tTopoHand;
00157 setup->get<IdealGeometryRecord>().get(tTopoHand);
00158
00159
00160 float quality=0;
00161 int nshared = 0;
00162 std::vector< SimHitIdpr> SimTrackIds;
00163 std::vector< SimHitIdpr> matchedIds;
00164 SimToRecoCollection outputCollection;
00165
00166 TrackerHitAssociator * associate = new TrackerHitAssociator(*e, conf_);
00167
00168 TrackingParticleCollection tPC;
00169 if (TPCollectionH.size()!=0) tPC = *const_cast<TrackingParticleCollection*>(TPCollectionH.product());
00170
00171
00172
00173
00174
00175
00176
00177
00178 edm::Handle<SimHitTPAssociationProducer::SimHitTPAssociationList> simHitsTPAssoc;
00179
00180 e->getByLabel(_simHitTpMapTag,simHitsTPAssoc);
00181
00182
00183 int tindex=0;
00184 for (edm::RefToBaseVector<reco::Track>::const_iterator track=tC.begin(); track!=tC.end(); track++, tindex++){
00185
00186 int ri=0;
00187 getMatchedIds<trackingRecHit_iterator>(matchedIds, SimTrackIds, ri, (*track)->recHitsBegin(), (*track)->recHitsEnd(), associate);
00188
00189
00190 std::vector<SimHitIdpr> idcachev;
00191 if(!matchedIds.empty()){
00192
00193 int tpindex =0;
00194 for (TrackingParticleCollection::iterator t = tPC.begin(); t != tPC.end(); ++t, ++tpindex) {
00195 idcachev.clear();
00196 float totsimhit = 0;
00197 const TrackerTopology *tTopo=tTopoHand.product();
00198
00199
00200 std::vector<PSimHit> tphits;
00201
00202
00203 nshared = getShared(matchedIds, idcachev, t);
00204
00205
00206
00207
00208
00209
00210
00211
00212 if (nshared!=0) {
00213
00214
00215
00216
00217 std::pair<TrackingParticleRef, TrackPSimHitRef>
00218 clusterTPpairWithDummyTP(TrackingParticleRef(TPCollectionH,t-tPC.begin()),TrackPSimHitRef());
00219
00220 auto range = std::equal_range(simHitsTPAssoc->begin(), simHitsTPAssoc->end(),
00221 clusterTPpairWithDummyTP, SimHitTPAssociationProducer::simHitTPAssociationListGreater);
00222 for(auto ip = range.first; ip != range.second; ++ip) {
00223 TrackPSimHitRef TPhit = ip->second;
00224 DetId dId = DetId(TPhit->detUnitId());
00225
00226 unsigned int subdetId = static_cast<unsigned int>(dId.subdetId());
00227 if (!UsePixels && (subdetId==PixelSubdetector::PixelBarrel || subdetId==PixelSubdetector::PixelEndcap) )
00228 continue;
00229
00230
00231 SiStripDetId* stripDetId = 0;
00232 if (subdetId==SiStripDetId::TIB||subdetId==SiStripDetId::TOB||
00233 subdetId==SiStripDetId::TID||subdetId==SiStripDetId::TEC)
00234 stripDetId= new SiStripDetId(dId);
00235
00236
00237
00238 bool newhit = true;
00239 for(std::vector<PSimHit>::const_iterator TPhitOK = tphits.begin(); TPhitOK != tphits.end(); TPhitOK++){
00240 DetId dIdOK = DetId(TPhitOK->detUnitId());
00241
00242
00243
00244
00245
00246 if (!UseGrouped && !UseSplitting)
00247 if (tTopo->layer(dId)==tTopo->layer(dIdOK) &&
00248 dId.subdetId()==dIdOK.subdetId()) newhit = false;
00249
00250 if (!UseGrouped && UseSplitting)
00251 if (tTopo->layer(dId)==tTopo->layer(dIdOK) &&
00252 dId.subdetId()==dIdOK.subdetId() &&
00253 (stripDetId==0 || stripDetId->partnerDetId()!=dIdOK.rawId()))
00254 newhit = false;
00255
00256 if (UseGrouped && !UseSplitting)
00257 if (tTopo->layer(dId)==tTopo->layer(dIdOK) &&
00258 dId.subdetId()==dIdOK.subdetId() &&
00259 stripDetId!=0 && stripDetId->partnerDetId()==dIdOK.rawId())
00260 newhit = false;
00261
00262 if (UseGrouped && UseSplitting)
00263 newhit = true;
00264 }
00265 if (newhit) {
00266
00267 tphits.push_back(*TPhit);
00268 }
00269
00270 delete stripDetId;
00271 }
00272 totsimhit = tphits.size();
00273 }
00274
00275 if (AbsoluteNumberOfHits) quality = static_cast<double>(nshared);
00276 else if(SimToRecoDenominator == denomsim && totsimhit!=0) quality = ((double) nshared)/((double)totsimhit);
00277 else if(SimToRecoDenominator == denomreco && ri!=0) quality = ((double) nshared)/((double)ri);
00278 else quality = 0;
00279
00280
00281
00282 float purity = 1.0*nshared/ri;
00283 if (quality>quality_SimToReco && !(ThreeHitTracksAreSpecial && totsimhit==3 && nshared<3) && (AbsoluteNumberOfHits||(purity>purity_SimToReco))) {
00284
00285 outputCollection.insert(edm::Ref<TrackingParticleCollection>(TPCollectionH, tpindex),
00286 std::make_pair(tC[tindex],quality));
00287
00288
00289
00290
00291 } else {
00292
00293
00294
00295 }
00296 }
00297 }
00298 }
00299
00300 delete associate;
00301 outputCollection.post_insert();
00302 return outputCollection;
00303 }
00304
00305
00306 RecoToSimCollectionSeed
00307 TrackAssociatorByHits::associateRecoToSim(edm::Handle<edm::View<TrajectorySeed> >& seedCollectionH,
00308 edm::Handle<TrackingParticleCollection>& TPCollectionH,
00309 const edm::Event * e,
00310 const edm::EventSetup *setup ) const{
00311
00312 edm::LogVerbatim("TrackAssociator") << "Starting TrackAssociatorByHits::associateRecoToSim - #seeds="
00313 <<seedCollectionH->size()<<" #TPs="<<TPCollectionH->size();
00314 int nshared = 0;
00315 float quality=0;
00316 std::vector< SimHitIdpr> SimTrackIds;
00317 std::vector< SimHitIdpr> matchedIds;
00318 RecoToSimCollectionSeed outputCollection;
00319
00320 TrackerHitAssociator * associate = new TrackerHitAssociator(*e, conf_);
00321
00322 const TrackingParticleCollection tPC = *(TPCollectionH.product());
00323
00324 const edm::View<TrajectorySeed> sC = *(seedCollectionH.product());
00325
00326
00327 int tindex=0;
00328 for (edm::View<TrajectorySeed>::const_iterator seed=sC.begin(); seed!=sC.end(); seed++, tindex++) {
00329 matchedIds.clear();
00330 int ri=0;
00331 int nsimhit = seed->recHits().second-seed->recHits().first;
00332 LogTrace("TrackAssociator") << "\nNEW SEED - seed number " << tindex << " # valid=" << nsimhit;
00333 getMatchedIds<edm::OwnVector<TrackingRecHit>::const_iterator>(matchedIds, SimTrackIds, ri, seed->recHits().first, seed->recHits().second, associate );
00334
00335
00336 std::vector<SimHitIdpr> idcachev;
00337 if(!matchedIds.empty()){
00338
00339 int tpindex =0;
00340 for (TrackingParticleCollection::const_iterator t = tPC.begin(); t != tPC.end(); ++t, ++tpindex) {
00341 LogTrace("TrackAssociator") << "TP number " << tpindex << " pdgId=" << t->pdgId() << " with number of PSimHits: " << nsimhit;
00342 idcachev.clear();
00343 nshared = getShared(matchedIds, idcachev, t);
00344
00345
00346 if (abs(t->pdgId())==11&&(t->g4Track_end()-t->g4Track_begin())>1){
00347 nshared-=getDoubleCount<edm::OwnVector<TrackingRecHit>::const_iterator>(seed->recHits().first, seed->recHits().second, associate, t);
00348 }
00349
00350 if (AbsoluteNumberOfHits) quality = static_cast<double>(nshared);
00351 else if(ri!=0) quality = (static_cast<double>(nshared)/static_cast<double>(ri));
00352 else quality = 0;
00353
00354 if(quality > cut_RecoToSim && !(ThreeHitTracksAreSpecial && ri==3 && nshared<3) ){
00355
00356 outputCollection.insert(edm::RefToBase<TrajectorySeed>(seedCollectionH,tindex),
00357 std::make_pair(edm::Ref<TrackingParticleCollection>(TPCollectionH, tpindex),quality));
00358 LogTrace("TrackAssociator") << "Seed number " << tindex << " with #hits=" << ri
00359 << "associated to TP (pdgId, nb segments, p) = "
00360 << (*t).pdgId() << " " << (*t).g4Tracks().size()
00361 << " " << (*t).momentum() <<" number " << tpindex << " with quality =" << quality;
00362 } else {
00363 LogTrace("TrackAssociator") <<"Seed number " << tindex << " with #hits=" << ri << " NOT associated with quality =" << quality;
00364 }
00365 }
00366 }
00367 }
00368 LogTrace("TrackAssociator") << "% of Assoc Seeds=" << ((double)outputCollection.size())/((double)seedCollectionH->size());
00369 delete associate;
00370 outputCollection.post_insert();
00371 return outputCollection;
00372 }
00373
00374
00375 SimToRecoCollectionSeed
00376 TrackAssociatorByHits::associateSimToReco(edm::Handle<edm::View<TrajectorySeed> >& seedCollectionH,
00377 edm::Handle<TrackingParticleCollection>& TPCollectionH,
00378 const edm::Event * e,
00379 const edm::EventSetup *setup ) const{
00380
00381 edm::LogVerbatim("TrackAssociator") << "Starting TrackAssociatorByHits::associateSimToReco - #seeds="
00382 <<seedCollectionH->size()<<" #TPs="<<TPCollectionH->size();
00383 float quality=0;
00384 int nshared = 0;
00385 std::vector< SimHitIdpr> SimTrackIds;
00386 std::vector< SimHitIdpr> matchedIds;
00387 SimToRecoCollectionSeed outputCollection;
00388
00389 TrackerHitAssociator * associate = new TrackerHitAssociator(*e, conf_);
00390
00391 TrackingParticleCollection tPC =*const_cast<TrackingParticleCollection*>(TPCollectionH.product());
00392
00393 const edm::View<TrajectorySeed> sC = *(seedCollectionH.product());
00394
00395
00396 int tindex=0;
00397 for (edm::View<TrajectorySeed>::const_iterator seed=sC.begin(); seed!=sC.end(); seed++, tindex++) {
00398 int ri=0;
00399 LogTrace("TrackAssociator") << "\nNEW SEED - seed number " << tindex << " # valid=" << seed->recHits().second-seed->recHits().first;
00400 getMatchedIds<edm::OwnVector<TrackingRecHit>::const_iterator>(matchedIds, SimTrackIds, ri, seed->recHits().first, seed->recHits().second, associate );
00401
00402
00403 std::vector<SimHitIdpr> idcachev;
00404 if(!matchedIds.empty()){
00405 int tpindex =0;
00406 for (TrackingParticleCollection::iterator t = tPC.begin(); t != tPC.end(); ++t, ++tpindex) {
00407 idcachev.clear();
00408 int nsimhit = t->numberOfTrackerHits();
00409 LogTrace("TrackAssociator") << "TP number " << tpindex << " pdgId=" << t->pdgId() << " with number of PSimHits: " << nsimhit;
00410 nshared = getShared(matchedIds, idcachev, t);
00411
00412 if (AbsoluteNumberOfHits) quality = static_cast<double>(nshared);
00413 else if(ri!=0) quality = ((double) nshared)/((double)ri);
00414 else quality = 0;
00415
00416
00417
00418 if(quality > quality_SimToReco && !(ThreeHitTracksAreSpecial && ri==3 && nshared<3) ){
00419 outputCollection.insert(edm::Ref<TrackingParticleCollection>(TPCollectionH, tpindex),
00420 std::make_pair(edm::RefToBase<TrajectorySeed>(seedCollectionH,tindex), quality));
00421 LogTrace("TrackAssociator") << "TrackingParticle number " << tpindex << " with #hits=" << nsimhit
00422 << " associated to seed number " << tindex << " with #hits=" << ri
00423 << " with hit quality =" << quality ;
00424 }
00425 else {
00426 LogTrace("TrackAssociator") << "TrackingParticle number " << tpindex << " with #hits=" << nsimhit << " NOT associated with quality =" << quality;
00427 }
00428 }
00429 }
00430 }
00431 LogTrace("TrackAssociator") << "% of Assoc TPs=" << ((double)outputCollection.size())/((double)TPCollectionH->size());
00432 delete associate;
00433 outputCollection.post_insert();
00434 return outputCollection;
00435 }
00436
00437 template<typename iter>
00438 void TrackAssociatorByHits::getMatchedIds(std::vector<SimHitIdpr>& matchedIds,
00439 std::vector<SimHitIdpr>& SimTrackIds,
00440 int& ri,
00441 iter begin,
00442 iter end,
00443 TrackerHitAssociator* associate ) const {
00444 matchedIds.clear();
00445 ri=0;
00446 for (iter it = begin; it != end; it++){
00447 const TrackingRecHit *hit=getHitPtr(it);
00448 if (hit->isValid()){
00449 ri++;
00450 uint32_t t_detID= hit->geographicalId().rawId();
00451 SimTrackIds.clear();
00452 associate->associateHitId(*hit, SimTrackIds);
00453
00454 if(!SimTrackIds.empty()){
00455 for(size_t j=0; j<SimTrackIds.size(); j++){
00456 LogTrace("TrackAssociator") << " hit # " << ri << " valid=" << hit->isValid()
00457 << " det id = " << t_detID << " SimId " << SimTrackIds[j].first
00458 << " evt=" << SimTrackIds[j].second.event()
00459 << " bc=" << SimTrackIds[j].second.bunchCrossing();
00460 matchedIds.push_back(SimTrackIds[j]);
00461 }
00462 }
00464
00465
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00479 }else{
00480 LogTrace("TrackAssociator") <<"\t\t Invalid Hit On "<<hit->geographicalId().rawId();
00481 }
00482 }
00483 }
00484
00485
00486 int TrackAssociatorByHits::getShared(std::vector<SimHitIdpr>& matchedIds,
00487 std::vector<SimHitIdpr>& idcachev,
00488 TrackingParticleCollection::const_iterator t) const {
00489 int nshared = 0;
00490 if (t->numberOfHits()==0) return nshared;
00491
00492 for(size_t j=0; j<matchedIds.size(); j++){
00493
00494 if(find(idcachev.begin(), idcachev.end(),matchedIds[j]) == idcachev.end() ){
00495
00496 idcachev.push_back(matchedIds[j]);
00497
00498 for (TrackingParticle::g4t_iterator g4T = t -> g4Track_begin(); g4T != t -> g4Track_end(); ++g4T) {
00499
00500
00501
00502
00503
00504
00505
00506 if((*g4T).trackId() == matchedIds[j].first && t->eventId() == matchedIds[j].second){
00507 int countedhits = std::count(matchedIds.begin(), matchedIds.end(), matchedIds[j]);
00508 nshared += countedhits;
00509
00510
00511
00512 }
00513 }
00514 }
00515 }
00516 return nshared;
00517 }
00518
00519
00520 template<typename iter>
00521 int TrackAssociatorByHits::getDoubleCount(iter begin,
00522 iter end,
00523 TrackerHitAssociator* associate,
00524 TrackingParticleCollection::const_iterator t) const {
00525 int doublecount = 0 ;
00526 std::vector<SimHitIdpr> SimTrackIdsDC;
00527
00528 for (iter it = begin; it != end; it++){
00529 int idcount = 0;
00530 SimTrackIdsDC.clear();
00531 associate->associateHitId(*getHitPtr(it), SimTrackIdsDC);
00532
00533 if(SimTrackIdsDC.size()>1){
00534
00535 for (TrackingParticle::g4t_iterator g4T = t -> g4Track_begin(); g4T != t -> g4Track_end(); ++g4T) {
00536 if(find(SimTrackIdsDC.begin(), SimTrackIdsDC.end(),SimHitIdpr((*g4T).trackId(), SimTrackIdsDC.begin()->second)) != SimTrackIdsDC.end() ){
00537 idcount++;
00538 }
00539 }
00540 }
00541 if (idcount>1) doublecount+=(idcount-1);
00542 }
00543 return doublecount;
00544 }