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