CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_0/src/SimTracker/TrackHistory/src/TrackQuality.cc

Go to the documentation of this file.
00001 /*
00002  *  TrackQuality.cc
00003  *
00004  *  Created by Christophe Saout on 9/25/08.
00005  *  Copyright 2007 __MyCompanyName__. All rights reserved.
00006  *
00007  */
00008 
00009 #include <algorithm>
00010 #include <vector>
00011 
00012 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00013 
00014 #include "SimDataFormats/TrackingAnalysis/interface/TrackingParticleFwd.h"
00015 #include "SimDataFormats/TrackingHit/interface/PSimHitContainer.h"
00016 
00017 #include "DataFormats/DetId/interface/DetId.h"
00018 #include "DataFormats/SiPixelDetId/interface/PixelSubdetector.h"
00019 #include "DataFormats/SiPixelDetId/interface/PXBDetId.h"
00020 #include "DataFormats/SiPixelDetId/interface/PXFDetId.h"
00021 #include "DataFormats/SiStripDetId/interface/StripSubdetector.h"
00022 #include "DataFormats/SiStripDetId/interface/TIBDetId.h"
00023 #include "DataFormats/SiStripDetId/interface/TIDDetId.h"
00024 #include "DataFormats/SiStripDetId/interface/TOBDetId.h"
00025 #include "DataFormats/SiStripDetId/interface/TECDetId.h"
00026 #include "DataFormats/MuonDetId/interface/MuonSubdetId.h"
00027 #include "DataFormats/MuonDetId/interface/DTLayerId.h"
00028 #include "DataFormats/MuonDetId/interface/CSCDetId.h"
00029 #include "DataFormats/MuonDetId/interface/RPCDetId.h"
00030 
00031 #include "DataFormats/TrackingRecHit/interface/TrackingRecHit.h"
00032 #include "DataFormats/TrackingRecHit/interface/TrackingRecHitFwd.h"
00033 #include "DataFormats/TrackReco/interface/Track.h"
00034 #include "DataFormats/TrackReco/interface/TrackFwd.h"
00035 
00036 #include "SimTracker/TrackerHitAssociation/interface/TrackerHitAssociator.h"
00037 
00038 #include "SimTracker/TrackHistory/interface/TrackQuality.h"
00039 
00040 // #define DEBUG_TRACK_QUALITY
00041 
00042 namespace
00043 {
00044 static const uint32_t NonMatchedTrackId = (uint32_t)-1;
00045 
00046 struct MatchedHit
00047 {
00048     DetId detId;
00049     uint32_t simTrackId;
00050     EncodedEventId collision;
00051     int recHitId;
00052     TrackQuality::Layer::State state;
00053 
00054     bool operator < (const MatchedHit &other) const
00055     {
00056         if (detId < other.detId)
00057             return true;
00058         else if (detId > other.detId)
00059             return false;
00060         else if (collision < other.collision)
00061             return true;
00062         else if (other.collision < collision)
00063             return false;
00064         else
00065             return simTrackId < other.simTrackId;
00066     }
00067 
00068     bool operator == (const MatchedHit &other) const
00069     {
00070         return detId == other.detId &&
00071                collision == other.collision &&
00072                simTrackId == other.simTrackId;
00073     }
00074 };
00075 
00076 static bool operator < (const MatchedHit &hit, DetId detId)
00077 {
00078     return hit.detId < detId;
00079 }
00080 static bool operator < (DetId detId, const MatchedHit &hit)
00081 {
00082     return detId < hit.detId;
00083 }
00084 }
00085 
00086 typedef std::pair<TrackQuality::Layer::SubDet, short int> DetLayer;
00087 
00088 // in case multiple hits were found, figure out the highest priority
00089 static const int statePriorities[] =
00090 {
00091     /* Unknown */  3,
00092     /* Good */     5,
00093     /* Missed */   0,
00094     /* Noise */    7,
00095     /* Bad */      2,
00096     /* Dead */     4,
00097     /* Shared */   6,
00098     /* Misassoc */ 1
00099 };
00100 
00101 static DetLayer getDetLayer(DetId detId)
00102 {
00103     TrackQuality::Layer::SubDet det = TrackQuality::Layer::Invalid;
00104     short int layer = 0;
00105 
00106     switch (detId.det())
00107     {
00108     case DetId::Tracker:
00109         switch (detId.subdetId())
00110         {
00111         case PixelSubdetector::PixelBarrel:
00112             det = TrackQuality::Layer::PixelBarrel;
00113             layer = PXBDetId(detId).layer();
00114             break;
00115 
00116         case PixelSubdetector::PixelEndcap:
00117             det = TrackQuality::Layer::PixelForward;
00118             layer = PXFDetId(detId).disk();
00119             break;
00120 
00121         case StripSubdetector::TIB:
00122             det = TrackQuality::Layer::StripTIB;
00123             layer = TIBDetId(detId).layer();
00124             break;
00125 
00126         case StripSubdetector::TID:
00127             det = TrackQuality::Layer::StripTID;
00128             layer = TIDDetId(detId).wheel();
00129             break;
00130 
00131         case StripSubdetector::TOB:
00132             det = TrackQuality::Layer::StripTOB;
00133             layer = TOBDetId(detId).layer();
00134             break;
00135 
00136         case StripSubdetector::TEC:
00137             det = TrackQuality::Layer::StripTEC;
00138             layer = TECDetId(detId).wheel();
00139             break;
00140 
00141         default:
00142             /* should not get here */
00143             ;
00144         }
00145         break;
00146 
00147     case DetId::Muon:
00148         switch (detId.subdetId())
00149         {
00150         case MuonSubdetId::DT:
00151             det = TrackQuality::Layer::MuonDT;
00152             layer = DTLayerId(detId).layer();
00153             break;
00154 
00155         case MuonSubdetId::CSC:
00156             det = TrackQuality::Layer::MuonCSC;
00157             layer = CSCDetId(detId).layer();
00158             break;
00159 
00160         case MuonSubdetId::RPC:
00161             if (RPCDetId(detId).region())
00162                 det = TrackQuality::Layer::MuonRPCEndcap;
00163             else
00164                 det = TrackQuality::Layer::MuonRPCBarrel;
00165             layer = RPCDetId(detId).layer();
00166             break;
00167 
00168         default:
00169             /* should not get here */
00170             ;
00171         }
00172         break;
00173 
00174     default:
00175         /* should not get here */
00176         ;
00177     }
00178 
00179     return DetLayer(det, layer);
00180 }
00181 
00182 TrackQuality::TrackQuality(const edm::ParameterSet &config) :
00183         associatorPSet_(config.getParameter<edm::ParameterSet>("hitAssociator"))
00184 {
00185 }
00186 
00187 void TrackQuality::newEvent(const edm::Event &ev, const edm::EventSetup &es)
00188 {
00189     associator_.reset(new TrackerHitAssociator(ev, associatorPSet_));
00190 }
00191 
00192 void TrackQuality::evaluate(SimParticleTrail const &spt,
00193                             reco::TrackBaseRef const &tr)
00194 {
00195     std::vector<MatchedHit> matchedHits;
00196 
00197     // iterate over reconstructed hits
00198     for (trackingRecHit_iterator hit = tr->recHitsBegin();
00199             hit != tr->recHitsEnd(); ++hit)
00200     {
00201         // on which module the hit lies
00202         DetId detId = (*hit)->geographicalId();
00203 
00204         // FIXME: check for double-sided modules?
00205 
00206         // didn't find a hit on that module
00207         if (!(*hit)->isValid())
00208         {
00209             MatchedHit matchedHit;
00210             matchedHit.detId = detId;
00211             matchedHit.simTrackId = NonMatchedTrackId;
00212             // check why hit wasn't valid and propagate information
00213             switch ((*hit)->getType())
00214             {
00215             case TrackingRecHit::inactive:
00216                 matchedHit.state = Layer::Dead;
00217                 break;
00218 
00219             case TrackingRecHit::bad:
00220                 matchedHit.state = Layer::Bad;
00221                 break;
00222 
00223             default:
00224                 matchedHit.state = Layer::Missed;
00225             }
00226             matchedHit.recHitId = hit - tr->recHitsBegin();
00227             matchedHits.push_back(matchedHit);
00228             continue;
00229         }
00230 
00231         // find simulated tracks causing hit that was reconstructed
00232         std::vector<SimHitIdpr> simIds = associator_->associateHitId(**hit);
00233 
00234         // must be noise or so
00235         if (simIds.empty())
00236         {
00237             MatchedHit matchedHit;
00238             matchedHit.detId = detId;
00239             matchedHit.simTrackId = NonMatchedTrackId;
00240             matchedHit.state = Layer::Noise;
00241             matchedHit.recHitId = hit - tr->recHitsBegin();
00242             matchedHits.push_back(matchedHit);
00243             continue;
00244         }
00245 
00246         // register all simulated tracks contributing
00247         for (std::vector<SimHitIdpr>::const_iterator i = simIds.begin();
00248                 i != simIds.end(); ++i)
00249         {
00250             MatchedHit matchedHit;
00251             matchedHit.detId = detId;
00252             matchedHit.simTrackId = i->first;
00253             matchedHit.collision = i->second;
00254             // RecHit <-> SimHit matcher currently doesn't support muon system
00255             if (detId.det() == DetId::Muon)
00256                 matchedHit.state = Layer::Unknown;
00257             else
00258                 // assume hit was mismatched (until possible confirmation)
00259                 matchedHit.state = Layer::Misassoc;
00260             matchedHit.recHitId = hit - tr->recHitsBegin();
00261             matchedHits.push_back(matchedHit);
00262         }
00263     }
00264 
00265     // sort hits found so far by module id
00266     std::stable_sort(matchedHits.begin(), matchedHits.end());
00267 
00268     std::vector<MatchedHit>::size_type size = matchedHits.size();
00269 
00270     // now iterate over simulated hits and compare (tracks in chain first)
00271     for (SimParticleTrail::const_iterator track = spt.begin();
00272             track != spt.end(); ++track)
00273     {
00274         // iterate over all hits in track
00275         for (std::vector<PSimHit>::const_iterator hit =
00276                     (*track)->pSimHit_begin();
00277                 hit != (*track)->pSimHit_end(); ++hit)
00278         {
00279             MatchedHit matchedHit;
00280             matchedHit.detId = DetId(hit->detUnitId());
00281             matchedHit.simTrackId = hit->trackId();
00282             matchedHit.collision = hit->eventId();
00283 
00284             // find range of reconstructed hits belonging to this module
00285             std::pair<std::vector<MatchedHit>::iterator,
00286             std::vector<MatchedHit>::iterator>
00287             range = std::equal_range(
00288                         matchedHits.begin(),
00289                         matchedHits.begin() + size,
00290                         matchedHit.detId);
00291 
00292             // no reconstructed hit found, remember this as a missed module
00293             if (range.first == range.second)
00294             {
00295                 matchedHit.state = Layer::Missed;
00296                 matchedHit.recHitId = -1;
00297                 matchedHits.push_back(matchedHit);
00298                 continue;
00299             }
00300 
00301             // now find if the hit belongs to the correct simulated track
00302             std::vector<MatchedHit>::iterator pos =
00303                 std::lower_bound(range.first,
00304                                  range.second,
00305                                  matchedHit);
00306 
00307             // if it does, check for being a shared hit (was Misassoc before)
00308             if (pos != range.second)
00309             {
00310                 if (range.second - range.first > 1) // more than one SimHit
00311                     pos->state = Layer::Shared;
00312                 else
00313                     pos->state = Layer::Good; // only hit -> good hit
00314             }
00315         }
00316     }
00317 
00318     // in case we added missed modules, re-sort
00319     std::stable_sort(matchedHits.begin(), matchedHits.end());
00320 
00321     // prepare for ordering results by layer enum and layer/disk number
00322     typedef std::multimap<DetLayer, const MatchedHit*> LayerHitMap;
00323     LayerHitMap layerHitMap;
00324 
00325     // iterate over all simulated/reconstructed hits again
00326     for (std::vector<MatchedHit>::const_iterator hit = matchedHits.begin();
00327             hit != matchedHits.end();)
00328     {
00329         // we can have multiple reco-to-sim matches per module, find best one
00330         const MatchedHit *best = 0;
00331 
00332         // this loop iterates over all subsequent hits in the same module
00333         do
00334         {
00335             // update our best hit pointer
00336             if (!best ||
00337                     statePriorities[hit->state] > statePriorities[best->state] ||
00338                     best->simTrackId == NonMatchedTrackId)
00339             {
00340                 best = &*hit;
00341             }
00342             ++hit;
00343         }
00344         while (hit != matchedHits.end() &&
00345                 hit->detId == best->detId);
00346 
00347         // ignore hit in case track reco was looking at the wrong module
00348         if (best->simTrackId != NonMatchedTrackId ||
00349                 best->state != Layer::Missed)
00350         {
00351             layerHitMap.insert(std::make_pair(
00352                                    getDetLayer(best->detId), best));
00353         }
00354     }
00355 
00356     layers_.clear();
00357 
00358 #ifdef DEBUG_TRACK_QUALITY
00359     std::cout << "---------------------" << std::endl;
00360 #endif
00361     // now prepare final collection
00362     for (LayerHitMap::const_iterator hit = layerHitMap.begin();
00363             hit != layerHitMap.end(); ++hit)
00364     {
00365 #ifdef DEBUG_TRACK_QUALITY
00366         std::cout
00367             << "detLayer (" << hit->first.first << ", " << hit->first.second << ")"
00368             << " [" << (uint32_t)hit->second->detId << "] sim(" << (int)hit->second->simTrackId << ")"
00369             << " hit(" << hit->second->recHitId << ") -> " << hit->second->state << std::endl;
00370 #endif
00371 
00372         // find out if we need to start a new layer
00373         Layer *layer = layers_.empty() ? 0 : &layers_.back();
00374         if (!layer ||
00375                 hit->first.first != layer->subDet ||
00376                 hit->first.second != layer->layer)
00377         {
00378             Layer newLayer;
00379             newLayer.subDet = hit->first.first;
00380             newLayer.layer = hit->first.second;
00381             layers_.push_back(newLayer);
00382             layer = &layers_.back();
00383         }
00384 
00385         // create hit and add it to layer
00386         Layer::Hit newHit;
00387         newHit.recHitId = hit->second->recHitId;
00388         newHit.state = hit->second->state;
00389 
00390         layer->hits.push_back(newHit);
00391     }
00392 }