CMS 3D CMS Logo

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