CMS 3D CMS Logo

TrackQuality.cc
Go to the documentation of this file.
1 /*
2  * TrackQuality.cc
3  *
4  * Created by Christophe Saout on 9/25/08.
5  * 2007 __MyCompanyName__.
6  *
7  */
8 
9 #include <algorithm>
10 #include <vector>
11 
13 
16 
26 
31 
33 
35 
36 // #define DEBUG_TRACK_QUALITY
37 
38 namespace
39 {
40 const uint32_t NonMatchedTrackId = (uint32_t)-1;
41 
42 struct MatchedHit
43 {
44  DetId detId;
45  uint32_t simTrackId;
46  EncodedEventId collision;
47  int recHitId;
49 
50  bool operator < (const MatchedHit &other) const
51  {
52  if (detId < other.detId)
53  return true;
54  else if (detId > other.detId)
55  return false;
56  else if (collision < other.collision)
57  return true;
58  else if (other.collision < collision)
59  return false;
60  else
61  return simTrackId < other.simTrackId;
62  }
63 
64  bool operator == (const MatchedHit &other) const
65  {
66  return detId == other.detId &&
67  collision == other.collision &&
68  simTrackId == other.simTrackId;
69  }
70 };
71  /*
72 static bool operator < (const MatchedHit &hit, DetId detId)
73 {
74  return hit.detId < detId;
75 }
76 static bool operator < (DetId detId, const MatchedHit &hit)
77 {
78  return detId < hit.detId;
79 }
80  */
81 }
82 
83 typedef std::pair<TrackQuality::Layer::SubDet, short int> DetLayer;
84 
85 // in case multiple hits were found, figure out the highest priority
86 static const int statePriorities[] =
87 {
88  /* Unknown */ 3,
89  /* Good */ 5,
90  /* Missed */ 0,
91  /* Noise */ 7,
92  /* Bad */ 2,
93  /* Dead */ 4,
94  /* Shared */ 6,
95  /* Misassoc */ 1
96 };
97 
98 DetLayer getDetLayer(DetId detId, const TrackerTopology *tTopo)
99 {
101  short int layer = 0;
102 
103  switch (detId.det())
104  {
105  case DetId::Tracker:
106  layer=tTopo->layer(detId);
107  break;
108 
109  case DetId::Muon:
110  switch (detId.subdetId())
111  {
112  case MuonSubdetId::DT:
114  layer = DTLayerId(detId).layer();
115  break;
116 
117  case MuonSubdetId::CSC:
119  layer = CSCDetId(detId).layer();
120  break;
121 
122  case MuonSubdetId::RPC:
123  if (RPCDetId(detId).region())
125  else
127  layer = RPCDetId(detId).layer();
128  break;
129 
130  default:
131  /* should not get here */
132  ;
133  }
134  break;
135 
136  default:
137  /* should not get here */
138  ;
139  }
140 
141  return DetLayer(det, layer);
142 }
143 
145  trackerHitAssociatorConfig_(config.getParameter<edm::ParameterSet>("hitAssociator"), std::move(iC))
146 {
147 }
148 
150 {
152 }
153 
155  reco::TrackBaseRef const &tr,
156  const TrackerTopology *tTopo)
157 {
158  std::vector<MatchedHit> matchedHits;
159 
160  // iterate over reconstructed hits
162  hit != tr->recHitsEnd(); ++hit)
163  {
164  // on which module the hit lies
165  DetId detId = (*hit)->geographicalId();
166 
167  // FIXME: check for double-sided modules?
168 
169  // didn't find a hit on that module
170  if (!(*hit)->isValid())
171  {
172  MatchedHit matchedHit;
173  matchedHit.detId = detId;
174  matchedHit.simTrackId = NonMatchedTrackId;
175  // check why hit wasn't valid and propagate information
176  switch ((*hit)->getType())
177  {
179  matchedHit.state = Layer::Dead;
180  break;
181 
182  case TrackingRecHit::bad:
183  matchedHit.state = Layer::Bad;
184  break;
185 
186  default:
187  matchedHit.state = Layer::Missed;
188  }
189  matchedHit.recHitId = hit - tr->recHitsBegin();
190  matchedHits.push_back(matchedHit);
191  continue;
192  }
193 
194  // find simulated tracks causing hit that was reconstructed
195  std::vector<SimHitIdpr> simIds = associator_->associateHitId(**hit);
196 
197  // must be noise or so
198  if (simIds.empty())
199  {
200  MatchedHit matchedHit;
201  matchedHit.detId = detId;
202  matchedHit.simTrackId = NonMatchedTrackId;
203  matchedHit.state = Layer::Noise;
204  matchedHit.recHitId = hit - tr->recHitsBegin();
205  matchedHits.push_back(matchedHit);
206  continue;
207  }
208 
209  // register all simulated tracks contributing
210  for (std::vector<SimHitIdpr>::const_iterator i = simIds.begin();
211  i != simIds.end(); ++i)
212  {
213  MatchedHit matchedHit;
214  matchedHit.detId = detId;
215  matchedHit.simTrackId = i->first;
216  matchedHit.collision = i->second;
217  // RecHit <-> SimHit matcher currently doesn't support muon system
218  if (detId.det() == DetId::Muon)
219  matchedHit.state = Layer::Unknown;
220  else
221  // assume hit was mismatched (until possible confirmation)
222  matchedHit.state = Layer::Misassoc;
223  matchedHit.recHitId = hit - tr->recHitsBegin();
224  matchedHits.push_back(matchedHit);
225  }
226  }
227 
228  // sort hits found so far by module id
229  std::stable_sort(matchedHits.begin(), matchedHits.end());
230 
231  // in case we added missed modules, re-sort
232  std::stable_sort(matchedHits.begin(), matchedHits.end());
233 
234  // prepare for ordering results by layer enum and layer/disk number
235  typedef std::multimap<DetLayer, const MatchedHit*> LayerHitMap;
236  LayerHitMap layerHitMap;
237 
238  // iterate over all simulated/reconstructed hits again
239  for (std::vector<MatchedHit>::const_iterator hit = matchedHits.begin();
240  hit != matchedHits.end();)
241  {
242  // we can have multiple reco-to-sim matches per module, find best one
243  const MatchedHit *best = nullptr;
244 
245  // this loop iterates over all subsequent hits in the same module
246  do
247  {
248  // update our best hit pointer
249  if (!best ||
250  statePriorities[hit->state] > statePriorities[best->state] ||
251  best->simTrackId == NonMatchedTrackId)
252  {
253  best = &*hit;
254  }
255  ++hit;
256  }
257  while (hit != matchedHits.end() &&
258  hit->detId == best->detId);
259 
260  // ignore hit in case track reco was looking at the wrong module
261  if (best->simTrackId != NonMatchedTrackId ||
262  best->state != Layer::Missed)
263  {
264  layerHitMap.insert(std::make_pair(
265  getDetLayer(best->detId,tTopo), best));
266  }
267  }
268 
269  layers_.clear();
270 
271 #ifdef DEBUG_TRACK_QUALITY
272  std::cout << "---------------------" << std::endl;
273 #endif
274  // now prepare final collection
275  for (LayerHitMap::const_iterator hit = layerHitMap.begin();
276  hit != layerHitMap.end(); ++hit)
277  {
278 #ifdef DEBUG_TRACK_QUALITY
279  std::cout
280  << "detLayer (" << hit->first.first << ", " << hit->first.second << ")"
281  << " [" << (uint32_t)hit->second->detId << "] sim(" << (int)hit->second->simTrackId << ")"
282  << " hit(" << hit->second->recHitId << ") -> " << hit->second->state << std::endl;
283 #endif
284 
285  // find out if we need to start a new layer
286  Layer *layer = layers_.empty() ? nullptr : &layers_.back();
287  if (!layer ||
288  hit->first.first != layer->subDet ||
289  hit->first.second != layer->layer)
290  {
291  Layer newLayer;
292  newLayer.subDet = hit->first.first;
293  newLayer.layer = hit->first.second;
294  layers_.push_back(newLayer);
295  layer = &layers_.back();
296  }
297 
298  // create hit and add it to layer
299  Layer::Hit newHit;
300  newHit.recHitId = hit->second->recHitId;
301  newHit.state = hit->second->state;
302 
303  layer->hits.push_back(newHit);
304  }
305 }
std::vector< TrackingParticleRef > SimParticleTrail
Definition: TrackQuality.h:31
std::unique_ptr< TrackerHitAssociator > associator_
Definition: TrackQuality.h:94
std::pair< TrackQuality::Layer::SubDet, short int > DetLayer
Definition: TrackQuality.cc:83
TrackerHitAssociator::Config trackerHitAssociatorConfig_
Definition: TrackQuality.h:93
bool ev
Definition: config.py:1
int layer() const
Return the layer number.
Definition: DTLayerId.h:53
int layer() const
Definition: CSCDetId.h:61
static const int CSC
Definition: MuonSubdetId.h:13
bool operator<(const FedChannelConnection &, const FedChannelConnection &)
void evaluate(SimParticleTrail const &, reco::TrackBaseRef const &, const TrackerTopology *tTopo)
Compute information about the track reconstruction quality.
bool operator==(const QGLikelihoodParameters &lhs, const QGLikelihoodCategory &rhs)
Test if parameters are compatible with category.
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:41
DetLayer getDetLayer(DetId detId, const TrackerTopology *tTopo)
Definition: TrackQuality.cc:98
trackingRecHit_iterator recHitsBegin() const
Iterator to first hit on the track.
Definition: Track.h:106
const Layer & layer(unsigned int index) const
Return information about the given layer by index.
Definition: TrackQuality.h:87
std::vector< Layer > layers_
Definition: TrackQuality.h:96
int layer() const
Definition: RPCDetId.h:108
Definition: DetId.h:18
unsigned int layer(const DetId &id) const
HLT enums.
static const int RPC
Definition: MuonSubdetId.h:14
std::vector< Hit > hits
Definition: TrackQuality.h:63
static const int DT
Definition: MuonSubdetId.h:12
void newEvent(const edm::Event &, const edm::EventSetup &)
Pre-process event information (for accessing reconstruction information)
TrackQuality(const edm::ParameterSet &, edm::ConsumesCollector &iC)
Constructor by pset.
def move(src, dest)
Definition: eostools.py:511
static const int statePriorities[]
Definition: TrackQuality.cc:86
constexpr Detector det() const
get the detector field from this detid
Definition: DetId.h:39
trackingRecHit_iterator recHitsEnd() const
Iterator to last hit on the track.
Definition: Track.h:111