CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Pages
TrackQuality.cc
Go to the documentation of this file.
1 /*
2  * TrackQuality.cc
3  *
4  * Created by Christophe Saout on 9/25/08.
5  * Copyright 2007 __MyCompanyName__. All rights reserved.
6  *
7  */
8 
9 #include <algorithm>
10 #include <vector>
11 
13 
16 
30 
35 
37 
39 
40 // #define DEBUG_TRACK_QUALITY
41 
42 namespace
43 {
44 static const uint32_t NonMatchedTrackId = (uint32_t)-1;
45 
46 struct MatchedHit
47 {
48  DetId detId;
49  uint32_t simTrackId;
50  EncodedEventId collision;
51  int recHitId;
53 
54  bool operator < (const MatchedHit &other) const
55  {
56  if (detId < other.detId)
57  return true;
58  else if (detId > other.detId)
59  return false;
60  else if (collision < other.collision)
61  return true;
62  else if (other.collision < collision)
63  return false;
64  else
65  return simTrackId < other.simTrackId;
66  }
67 
68  bool operator == (const MatchedHit &other) const
69  {
70  return detId == other.detId &&
71  collision == other.collision &&
72  simTrackId == other.simTrackId;
73  }
74 };
75 
76 static bool operator < (const MatchedHit &hit, DetId detId)
77 {
78  return hit.detId < detId;
79 }
80 static bool operator < (DetId detId, const MatchedHit &hit)
81 {
82  return detId < hit.detId;
83 }
84 }
85 
86 typedef std::pair<TrackQuality::Layer::SubDet, short int> DetLayer;
87 
88 // in case multiple hits were found, figure out the highest priority
89 static const int statePriorities[] =
90 {
91  /* Unknown */ 3,
92  /* Good */ 5,
93  /* Missed */ 0,
94  /* Noise */ 7,
95  /* Bad */ 2,
96  /* Dead */ 4,
97  /* Shared */ 6,
98  /* Misassoc */ 1
99 };
100 
101 static DetLayer getDetLayer(DetId detId)
102 {
104  short int layer = 0;
105 
106  switch (detId.det())
107  {
108  case DetId::Tracker:
109  switch (detId.subdetId())
110  {
113  layer = PXBDetId(detId).layer();
114  break;
115 
118  layer = PXFDetId(detId).disk();
119  break;
120 
123  layer = TIBDetId(detId).layer();
124  break;
125 
128  layer = TIDDetId(detId).wheel();
129  break;
130 
133  layer = TOBDetId(detId).layer();
134  break;
135 
138  layer = TECDetId(detId).wheel();
139  break;
140 
141  default:
142  /* should not get here */
143  ;
144  }
145  break;
146 
147  case DetId::Muon:
148  switch (detId.subdetId())
149  {
150  case MuonSubdetId::DT:
152  layer = DTLayerId(detId).layer();
153  break;
154 
155  case MuonSubdetId::CSC:
157  layer = CSCDetId(detId).layer();
158  break;
159 
160  case MuonSubdetId::RPC:
161  if (RPCDetId(detId).region())
163  else
165  layer = RPCDetId(detId).layer();
166  break;
167 
168  default:
169  /* should not get here */
170  ;
171  }
172  break;
173 
174  default:
175  /* should not get here */
176  ;
177  }
178 
179  return DetLayer(det, layer);
180 }
181 
183  associatorPSet_(config.getParameter<edm::ParameterSet>("hitAssociator"))
184 {
185 }
186 
188 {
190 }
191 
193  reco::TrackBaseRef const &tr)
194 {
195  std::vector<MatchedHit> matchedHits;
196 
197  // iterate over reconstructed hits
199  hit != tr->recHitsEnd(); ++hit)
200  {
201  // on which module the hit lies
202  DetId detId = (*hit)->geographicalId();
203 
204  // FIXME: check for double-sided modules?
205 
206  // didn't find a hit on that module
207  if (!(*hit)->isValid())
208  {
209  MatchedHit matchedHit;
210  matchedHit.detId = detId;
211  matchedHit.simTrackId = NonMatchedTrackId;
212  // check why hit wasn't valid and propagate information
213  switch ((*hit)->getType())
214  {
216  matchedHit.state = Layer::Dead;
217  break;
218 
219  case TrackingRecHit::bad:
220  matchedHit.state = Layer::Bad;
221  break;
222 
223  default:
224  matchedHit.state = Layer::Missed;
225  }
226  matchedHit.recHitId = hit - tr->recHitsBegin();
227  matchedHits.push_back(matchedHit);
228  continue;
229  }
230 
231  // find simulated tracks causing hit that was reconstructed
232  std::vector<SimHitIdpr> simIds = associator_->associateHitId(**hit);
233 
234  // must be noise or so
235  if (simIds.empty())
236  {
237  MatchedHit matchedHit;
238  matchedHit.detId = detId;
239  matchedHit.simTrackId = NonMatchedTrackId;
240  matchedHit.state = Layer::Noise;
241  matchedHit.recHitId = hit - tr->recHitsBegin();
242  matchedHits.push_back(matchedHit);
243  continue;
244  }
245 
246  // register all simulated tracks contributing
247  for (std::vector<SimHitIdpr>::const_iterator i = simIds.begin();
248  i != simIds.end(); ++i)
249  {
250  MatchedHit matchedHit;
251  matchedHit.detId = detId;
252  matchedHit.simTrackId = i->first;
253  matchedHit.collision = i->second;
254  // RecHit <-> SimHit matcher currently doesn't support muon system
255  if (detId.det() == DetId::Muon)
256  matchedHit.state = Layer::Unknown;
257  else
258  // assume hit was mismatched (until possible confirmation)
259  matchedHit.state = Layer::Misassoc;
260  matchedHit.recHitId = hit - tr->recHitsBegin();
261  matchedHits.push_back(matchedHit);
262  }
263  }
264 
265  // sort hits found so far by module id
266  std::stable_sort(matchedHits.begin(), matchedHits.end());
267 
268  std::vector<MatchedHit>::size_type size = matchedHits.size();
269 
270  // now iterate over simulated hits and compare (tracks in chain first)
271  for (SimParticleTrail::const_iterator track = spt.begin();
272  track != spt.end(); ++track)
273  {
274  // iterate over all hits in track
275  for (std::vector<PSimHit>::const_iterator hit =
276  (*track)->pSimHit_begin();
277  hit != (*track)->pSimHit_end(); ++hit)
278  {
279  MatchedHit matchedHit;
280  matchedHit.detId = DetId(hit->detUnitId());
281  matchedHit.simTrackId = hit->trackId();
282  matchedHit.collision = hit->eventId();
283 
284  // find range of reconstructed hits belonging to this module
285  std::pair<std::vector<MatchedHit>::iterator,
286  std::vector<MatchedHit>::iterator>
287  range = std::equal_range(
288  matchedHits.begin(),
289  matchedHits.begin() + size,
290  matchedHit.detId);
291 
292  // no reconstructed hit found, remember this as a missed module
293  if (range.first == range.second)
294  {
295  matchedHit.state = Layer::Missed;
296  matchedHit.recHitId = -1;
297  matchedHits.push_back(matchedHit);
298  continue;
299  }
300 
301  // now find if the hit belongs to the correct simulated track
302  std::vector<MatchedHit>::iterator pos =
303  std::lower_bound(range.first,
304  range.second,
305  matchedHit);
306 
307  // if it does, check for being a shared hit (was Misassoc before)
308  if (pos != range.second)
309  {
310  if (range.second - range.first > 1) // more than one SimHit
311  pos->state = Layer::Shared;
312  else
313  pos->state = Layer::Good; // only hit -> good hit
314  }
315  }
316  }
317 
318  // in case we added missed modules, re-sort
319  std::stable_sort(matchedHits.begin(), matchedHits.end());
320 
321  // prepare for ordering results by layer enum and layer/disk number
322  typedef std::multimap<DetLayer, const MatchedHit*> LayerHitMap;
323  LayerHitMap layerHitMap;
324 
325  // iterate over all simulated/reconstructed hits again
326  for (std::vector<MatchedHit>::const_iterator hit = matchedHits.begin();
327  hit != matchedHits.end();)
328  {
329  // we can have multiple reco-to-sim matches per module, find best one
330  const MatchedHit *best = 0;
331 
332  // this loop iterates over all subsequent hits in the same module
333  do
334  {
335  // update our best hit pointer
336  if (!best ||
337  statePriorities[hit->state] > statePriorities[best->state] ||
338  best->simTrackId == NonMatchedTrackId)
339  {
340  best = &*hit;
341  }
342  ++hit;
343  }
344  while (hit != matchedHits.end() &&
345  hit->detId == best->detId);
346 
347  // ignore hit in case track reco was looking at the wrong module
348  if (best->simTrackId != NonMatchedTrackId ||
349  best->state != Layer::Missed)
350  {
351  layerHitMap.insert(std::make_pair(
352  getDetLayer(best->detId), best));
353  }
354  }
355 
356  layers_.clear();
357 
358 #ifdef DEBUG_TRACK_QUALITY
359  std::cout << "---------------------" << std::endl;
360 #endif
361  // now prepare final collection
362  for (LayerHitMap::const_iterator hit = layerHitMap.begin();
363  hit != layerHitMap.end(); ++hit)
364  {
365 #ifdef DEBUG_TRACK_QUALITY
366  std::cout
367  << "detLayer (" << hit->first.first << ", " << hit->first.second << ")"
368  << " [" << (uint32_t)hit->second->detId << "] sim(" << (int)hit->second->simTrackId << ")"
369  << " hit(" << hit->second->recHitId << ") -> " << hit->second->state << std::endl;
370 #endif
371 
372  // find out if we need to start a new layer
373  Layer *layer = layers_.empty() ? 0 : &layers_.back();
374  if (!layer ||
375  hit->first.first != layer->subDet ||
376  hit->first.second != layer->layer)
377  {
378  Layer newLayer;
379  newLayer.subDet = hit->first.first;
380  newLayer.layer = hit->first.second;
381  layers_.push_back(newLayer);
382  layer = &layers_.back();
383  }
384 
385  // create hit and add it to layer
386  Layer::Hit newHit;
387  newHit.recHitId = hit->second->recHitId;
388  newHit.state = hit->second->state;
389 
390  layer->hits.push_back(newHit);
391  }
392 }
int i
Definition: DBlmapReader.cc:9
static DetLayer getDetLayer(DetId detId)
void evaluate(SimParticleTrail const &, reco::TrackBaseRef const &)
Compute information about the track reconstruction quality.
unsigned int layer() const
layer id
Definition: TOBDetId.h:39
std::vector< TrackingParticleRef > SimParticleTrail
Definition: TrackQuality.h:29
std::pair< TrackQuality::Layer::SubDet, short int > DetLayer
Definition: TrackQuality.cc:86
std::auto_ptr< TrackerHitAssociator > associator_
Definition: TrackQuality.h:92
bool operator==(const CaloTower &t1, const CaloTower &t2)
Definition: CaloTower.h:211
uint16_t size_type
TrackQuality(const edm::ParameterSet &)
Constructor by pset.
unsigned int layer() const
layer id
Definition: PXBDetId.h:35
static const int CSC
Definition: MuonSubdetId.h:15
bool operator<(const FedChannelConnection &, const FedChannelConnection &)
trackingRecHit_iterator recHitsBegin() const
Iterator to first hit on the track.
Definition: Track.h:63
int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:39
const Layer & layer(unsigned int index) const
Return information about the given layer by index.
Definition: TrackQuality.h:85
std::vector< Layer > layers_
Definition: TrackQuality.h:94
unsigned int disk() const
disk id
Definition: PXFDetId.h:43
Definition: DetId.h:20
unsigned int wheel() const
wheel id
Definition: TECDetId.h:52
char state
Definition: procUtils.cc:75
unsigned int layer() const
layer id
Definition: TIBDetId.h:41
static const int RPC
Definition: MuonSubdetId.h:16
std::vector< Hit > hits
Definition: TrackQuality.h:61
tuple cout
Definition: gather_cfg.py:121
static const int DT
Definition: MuonSubdetId.h:14
void newEvent(const edm::Event &, const edm::EventSetup &)
Pre-process event information (for accessing reconstruction information)
Detector det() const
get the detector field from this detid
Definition: DetId.h:37
tuple size
Write out results.
const edm::ParameterSet associatorPSet_
Definition: TrackQuality.h:91
static const int statePriorities[]
Definition: TrackQuality.cc:89
unsigned int wheel() const
wheel id
Definition: TIDDetId.h:50
trackingRecHit_iterator recHitsEnd() const
Iterator to last hit on the track.
Definition: Track.h:65