CMS 3D CMS Logo

MkStandaloneSeqs.cc
Go to the documentation of this file.
3 
6 
8 
9 #include "oneapi/tbb/parallel_for.h"
10 
11 namespace mkfit {
12 
13  namespace StdSeq {
14 
15  //=========================================================================
16  // Hit processing
17  //=========================================================================
18 
20  eoh.reset();
21 
22  // fill vector of hits in each layer
23  // XXXXMT: Does it really makes sense to multi-thread this?
24  tbb::parallel_for(tbb::blocked_range<int>(0, ev.layerHits_.size()), [&](const tbb::blocked_range<int> &layers) {
25  for (int ilay = layers.begin(); ilay < layers.end(); ++ilay) {
26  eoh.suckInHits(ilay, ev.layerHits_[ilay]);
27  }
28  });
29  eoh.setBeamSpot(ev.beamSpot_);
30  }
31 
33  // Mark tracks as duplicates; if within CMSSW, remove duplicate tracks from fit or candidate track collection
34  if (Config::removeDuplicates) {
36  find_duplicates(event->candidateTracks_);
38  find_duplicates(event->fitTracks_);
39  }
40  // For the MEIF benchmarks and the stress tests, no validation flags are set so we will enter this block
41  else {
42  // Only care about the candidate tracks here; no need to run the duplicate removal on both candidate and fit tracks
43  find_duplicates(event->candidateTracks_);
44  }
45  }
46  }
47 
48  //=========================================================================
49  // Random stuff
50  //=========================================================================
51 
53  // Ripped out of MkBuilder::begin_event, ifdefed under DEBUG
54 
55  std::vector<Track> &simtracks = event->simTracks_;
56 
57  for (int itrack = 0; itrack < (int)simtracks.size(); ++itrack) {
58  // bool debug = true;
59  Track track = simtracks[itrack];
60  // simtracks are initially written with label = index; uncomment in case tracks were edited
61  // if (track.label() != itrack) {
62  // dprintf("Bad label for simtrack %d -- %d\n", itrack, track.label());
63  // }
64 
65  dprint("MX - simtrack with nHits=" << track.nFoundHits() << " chi2=" << track.chi2() << " pT=" << track.pT()
66  << " phi=" << track.momPhi() << " eta=" << track.momEta());
67  }
68 
69  for (int itrack = 0; itrack < (int)simtracks.size(); ++itrack) {
70  for (int ihit = 0; ihit < simtracks[itrack].nFoundHits(); ++ihit) {
71  dprint("track #" << itrack << " hit #" << ihit
72  << " hit pos=" << simtracks[itrack].hitsVector(event->layerHits_)[ihit].position()
73  << " phi=" << simtracks[itrack].hitsVector(event->layerHits_)[ihit].phi());
74  }
75  }
76  }
77 
78  void track_print(Event *event, const Track &t, const char *pref) {
79  printf("%s with q=%+i pT=%7.3f eta=% 7.3f nHits=%2d label=%4d\nState:\n",
80  pref,
81  t.charge(),
82  t.pT(),
83  t.momEta(),
84  t.nFoundHits(),
85  t.label());
86 
87  print(t.state());
88 
89  printf("Hits:\n");
90  for (int ih = 0; ih < t.nTotalHits(); ++ih) {
91  int lyr = t.getHitLyr(ih);
92  int idx = t.getHitIdx(ih);
93  if (idx >= 0) {
94  const Hit &hit = event->layerHits_[lyr][idx];
95  printf(" hit %2d lyr=%2d idx=%4d pos r=%7.3f z=% 8.3f mc_hit=%4d mc_trk=%4d\n",
96  ih,
97  lyr,
98  idx,
99  hit.r(),
100  hit.z(),
101  hit.mcHitID(),
102  hit.mcTrackID(event->simHitsInfo_));
103  } else
104  printf(" hit %2d idx=%i\n", ih, t.getHitIdx(ih));
105  }
106  }
107 
108  //------------------------------------------------------------------------------
109  // Non-ROOT validation
110  //------------------------------------------------------------------------------
111 
113  quality_reset();
114 
115  std::map<int, int> cmsswLabelToPos;
117  for (size_t itrack = 0; itrack < event->cmsswTracks_.size(); itrack++) {
118  cmsswLabelToPos[event->cmsswTracks_[itrack].label()] = itrack;
119  }
120  }
121 
122  for (size_t itrack = 0; itrack < event->candidateTracks_.size(); itrack++) {
123  quality_process(event, event->candidateTracks_[itrack], itrack, cmsswLabelToPos);
124  }
125 
126  quality_print();
127  }
128 
130 
131  void Quality::quality_process(Event *event, Track &tkcand, const int itrack, std::map<int, int> &cmsswLabelToPos) {
132  // KPM: Do not use this method for validating CMSSW tracks if we ever build a DumbCMSSW function for them to print out...
133  // as we would need to access seeds through map of seed ids...
134 
135  // initialize track extra (input original seed label)
136  const auto label = tkcand.label();
137  TrackExtra extra(label);
138 
139  // track_print(tkcand, "XXX");
140 
141  // access temp seed trk and set matching seed hits
142  const auto &seed = event->seedTracks_[itrack];
143  extra.findMatchingSeedHits(tkcand, seed, event->layerHits_);
144 
145  // set mcTrackID through 50% hit matching after seed
146  extra.setMCTrackIDInfo(
147  tkcand, event->layerHits_, event->simHitsInfo_, event->simTracks_, false, (Config::seedInput == simSeeds));
148  const int mctrk = extra.mcTrackID();
149 
150  // int mctrk = tkcand.label(); // assumes 100% "efficiency"
151 
152  const float pT = tkcand.pT();
153  float pTmc = 0.f, etamc = 0.f, phimc = 0.f;
154  float pTr = 0.f;
155  int nfoundmc = -1;
156 
157  if (mctrk < 0 || static_cast<size_t>(mctrk) >= event->simTracks_.size()) {
158  ++m_cnt_nomc;
159  dprint("XX bad track idx " << mctrk << ", orig label was " << label);
160  } else {
161  auto &simtrack = event->simTracks_[mctrk];
162  pTmc = simtrack.pT();
163  etamc = simtrack.momEta();
164  phimc = simtrack.momPhi();
165  pTr = pT / pTmc;
166 
167  nfoundmc = simtrack.nUniqueLayers();
168 
169  ++m_cnt;
170  if (pTr > 0.9 && pTr < 1.1)
171  ++m_cnt1;
172  if (pTr > 0.8 && pTr < 1.2)
173  ++m_cnt2;
174 
175  if (tkcand.nFoundHits() >= 0.8f * nfoundmc) {
176  ++m_cnt_8;
177  if (pTr > 0.9 && pTr < 1.1)
178  ++m_cnt1_8;
179  if (pTr > 0.8 && pTr < 1.2)
180  ++m_cnt2_8;
181  }
182 
183  // perl -ne 'print if m/FOUND_LABEL\s+[-\d]+/o;' | sort -k2 -n
184  // grep "FOUND_LABEL" | sort -n -k 8,8 -k 2,2
185  // printf("FOUND_LABEL %6d pT_mc= %8.2f eta_mc= %8.2f event= %d\n", label, pTmc, etamc, event->evtID());
186  }
187 
188 #ifdef SELECT_SEED_LABEL
189  if (label == SELECT_SEED_LABEL)
190  track_print(tkcand, "MkBuilder::quality_process SELECT_SEED_LABEL:");
191 #endif
192 
193  float pTcmssw = 0.f, etacmssw = 0.f, phicmssw = 0.f;
194  int nfoundcmssw = -1;
196  if (cmsswLabelToPos.count(label)) {
197  auto &cmsswtrack = event->cmsswTracks_[cmsswLabelToPos[label]];
198  pTcmssw = cmsswtrack.pT();
199  etacmssw = cmsswtrack.momEta();
200  phicmssw = cmsswtrack.swimPhiToR(tkcand.x(), tkcand.y()); // to get rough estimate of diff in phi
201  nfoundcmssw = cmsswtrack.nUniqueLayers();
202  }
203  }
204 
206  std::lock_guard<std::mutex> printlock(Event::printmutex);
207  printf(
208  "MX - found track with chi2= %6.3f nFoundHits= %2d pT= %7.4f eta= %7.4f phi= %7.4f nfoundmc= %2d pTmc= "
209  "%7.4f etamc= %7.4f phimc= %7.4f nfoundcmssw= %2d pTcmssw= %7.4f etacmssw= %7.4f phicmssw= %7.4f lab= %d\n",
210  tkcand.chi2(),
211  tkcand.nFoundHits(),
212  pT,
213  tkcand.momEta(),
214  tkcand.momPhi(),
215  nfoundmc,
216  pTmc,
217  etamc,
218  phimc,
219  nfoundcmssw,
220  pTcmssw,
221  etacmssw,
222  phicmssw,
223  label);
224  }
225  }
226 
228  if (!Config::silent) {
229  std::lock_guard<std::mutex> printlock(Event::printmutex);
230  std::cout << "found tracks=" << m_cnt << " in pT 10%=" << m_cnt1 << " in pT 20%=" << m_cnt2
231  << " no_mc_assoc=" << m_cnt_nomc << std::endl;
232  std::cout << " nH >= 80% =" << m_cnt_8 << " in pT 10%=" << m_cnt1_8 << " in pT 20%=" << m_cnt2_8
233  << std::endl;
234  }
235  }
236 
237  //------------------------------------------------------------------------------
238  // Root validation
239  //------------------------------------------------------------------------------
240 
242  // get labels correct first
243  event->relabel_bad_seedtracks();
244  event->relabel_cmsswtracks_from_seeds();
245 
246  //collection cleaning
247  if (Config::nItersCMSSW > 0)
248  event->select_tracks_iter(Config::nItersCMSSW);
249 
250  // set the track collections to each other
251  event->candidateTracks_ = event->cmsswTracks_;
252  event->fitTracks_ = event->candidateTracks_;
253 
254  // prep the tracks + extras
257 
258  // validate
259  event->validate();
260  }
261 
263  // score the tracks
264  score_tracks(event->seedTracks_);
265  score_tracks(event->candidateTracks_);
266 
267  // deal with fit tracks
268  if (Config::backwardFit) {
269  score_tracks(event->fitTracks_);
270  } else
271  event->fitTracks_ = event->candidateTracks_;
272 
273  // sort hits + make extras, align if needed
275  if (Config::cmssw_val)
277 
278  // validate
279  event->validate();
280  }
281 
283  // seed tracks extras always needed
285  prep_tracks(event, event->seedTracks_, event->seedTracksExtra_, true);
286  } else if (Config::cmssw_val) // seed tracks are not validated, labels used for maps --> do NOT align index and labels!
287  {
288  prep_tracks(event, event->seedTracks_, event->seedTracksExtra_, false);
289  }
290 
291  // make extras + align index == label() for candidate tracks
292  prep_tracks(event, event->candidateTracks_, event->candidateTracksExtra_, true);
293  prep_tracks(event, event->fitTracks_, event->fitTracksExtra_, true);
294  }
295 
297  // First prep sim tracks to have hits sorted, then mark unfindable if too short
298  prep_reftracks(event, event->simTracks_, event->simTracksExtra_, false);
299 
300  // Now, make sure sim track shares at least four hits with a single cmssw seed.
301  // This ensures we factor out any weakness from CMSSW
302 
303  // First, make a make a map of [lyr][hit idx].vector(seed trk labels)
304  LayIdxIDVecMapMap seedHitIDMap;
305  std::map<int, int> labelNHitsMap;
306  std::map<int, int> labelAlgoMap;
307  std::map<int, std::vector<int>> labelSeedHitsMap;
308  for (const auto &seedtrack : event->seedTracks_) {
309  for (int ihit = 0; ihit < seedtrack.nTotalHits(); ihit++) {
310  const auto lyr = seedtrack.getHitLyr(ihit);
311  const auto idx = seedtrack.getHitIdx(ihit);
312 
313  if (lyr < 0 || idx < 0)
314  continue; // standard check
315  seedHitIDMap[lyr][idx].push_back(seedtrack.label());
316  labelSeedHitsMap[seedtrack.label()].push_back(lyr);
317  }
318  labelNHitsMap[seedtrack.label()] = seedtrack.nTotalHits();
319  labelAlgoMap[seedtrack.label()] = seedtrack.algoint();
320  }
321 
322  // Then, loop over sim tracks, and add up how many lyrs they possess of a single seed track
323  unsigned int count = 0;
324  for (auto &simtrack : event->simTracks_) {
325  if (simtrack.isNotFindable())
326  continue; // skip ones we already know are bad
327  TrkIDLaySetMap seedIDMap;
328  for (int ihit = 0; ihit < simtrack.nTotalHits(); ihit++) {
329  const auto lyr = simtrack.getHitLyr(ihit);
330  const auto idx = simtrack.getHitIdx(ihit);
331 
332  if (lyr < 0 || idx < 0)
333  continue; // standard check
334 
335  if (!seedHitIDMap.count(lyr))
336  continue; // ensure seed hit map has at least one entry for this layer
337  if (!seedHitIDMap.at(lyr).count(idx))
338  continue; // ensure seed hit map has at least one entry for this idx
339 
340  for (const auto label : seedHitIDMap.at(lyr).at(idx)) {
341  const auto &seedLayers = labelSeedHitsMap[label];
342  if (std::find(seedLayers.begin(), seedLayers.end(), lyr) != seedLayers.end()) //seed check moved here
343  seedIDMap[label].emplace(lyr);
344  }
345  }
346 
347  // now see if one of the seedIDs matched has at least 4 hits!
348  bool isSimSeed = false;
349  for (const auto &seedIDpair : seedIDMap) {
350  if ((int)seedIDpair.second.size() == labelNHitsMap[seedIDpair.first]) {
351  isSimSeed = true;
353  simtrack.setAlgoint(labelAlgoMap[seedIDpair.first]);
355  event->simTracksExtra_[count].addAlgo(labelAlgoMap[seedIDpair.first]);
356  //break;
357  }
358  }
360  // Apply MTV selection criteria and then return
361  if (simtrack.prodType() != Track::ProdType::Signal || simtrack.charge() == 0 || simtrack.posR() > 2.5 ||
362  std::abs(simtrack.z()) > 30 || std::abs(simtrack.momEta()) > 3.0)
363  simtrack.setNotFindable();
364  else if (Config::mtvRequireSeeds && !isSimSeed)
365  simtrack.setNotFindable();
366  } else {
367  // set findability based on bool isSimSeed
368  if (!isSimSeed)
369  simtrack.setNotFindable();
370  }
371  count++;
372  }
373  }
374 
375  void prep_cmsswtracks(Event *event) { prep_reftracks(event, event->cmsswTracks_, event->cmsswTracksExtra_, true); }
376 
377  void prep_reftracks(Event *event, TrackVec &tracks, TrackExtraVec &extras, const bool realigntracks) {
378  prep_tracks(event, tracks, extras, realigntracks);
379 
380  // mark cmsswtracks as unfindable if too short
381  for (auto &track : tracks) {
382  const int nlyr = track.nUniqueLayers();
383  if (nlyr < Config::cmsSelMinLayers)
384  track.setNotFindable();
385  }
386  }
387 
388  void prep_tracks(Event *event, TrackVec &tracks, TrackExtraVec &extras, const bool realigntracks) {
389  for (size_t i = 0; i < tracks.size(); i++) {
390  extras.emplace_back(tracks[i].label());
391  }
392  if (realigntracks)
393  event->validation_.alignTracks(tracks, extras, false);
394  }
395 
397  for (auto &track : tracks) {
398  track.setScore(getScoreCand(track));
399  }
400  }
401 
402  } // namespace StdSeq
403 
404 } // namespace mkfit
void prep_reftracks(Event *event, TrackVec &tracks, TrackExtraVec &extras, const bool realigntracks)
std::vector< TrackExtra > TrackExtraVec
void find_duplicates(TrackVec &tracks)
Definition: MkStdSeqs.cc:335
float pT() const
Definition: Track.h:169
void findMatchingSeedHits(const Track &reco_trk, const Track &seed_trk, const std::vector< HitVec > &layerHits)
Definition: TrackExtra.cc:13
float chi2() const
Definition: Track.h:184
std::map< int, std::unordered_set< int > > TrkIDLaySetMap
Definition: TrackExtra.h:38
void root_val(Event *event)
int label() const
Definition: Track.h:186
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
int mcTrackID() const
Definition: TrackExtra.h:79
void quality_process(Event *event, Track &tkcand, const int itrack, std::map< int, int > &cmsswLabelToPos)
void setMCTrackIDInfo(const Track &trk, const std::vector< HitVec > &layerHits, const MCHitInfoVec &globalHitInfo, const TrackVec &simtracks, const bool isSeed, const bool isPure)
Definition: TrackExtra.cc:106
void prep_simtracks(Event *event)
int nFoundHits() const
Definition: Track.h:516
float momEta() const
Definition: Track.h:173
float y() const
Definition: Track.h:159
char const * label
void prep_tracks(Event *event, TrackVec &tracks, TrackExtraVec &extras, const bool realigntracks)
void loadHitsAndBeamSpot(Event &ev, EventOfHits &eoh)
void track_print(Event *event, const Track &t, const char *pref)
float getScoreCand(const Track &cand1, bool penalizeTailMissHits=false, bool inFindCandidates=false)
Definition: Track.h:630
void score_tracks(TrackVec &tracks)
void prep_recotracks(Event *event)
void setBeamSpot(const BeamSpot &bs)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
static std::mutex printmutex
Definition: Event.h:68
std::vector< Track > TrackVec
auto const & tracks
cannot be loose
void print(std::string_view label, const MeasurementState &s)
Definition: Hit.cc:8
void suckInHits(int layer, const HitVec &hitv)
#define dprint(x)
Definition: Debug.h:90
void dump_simtracks(Event *event)
void handle_duplicates(Event *event)
float x() const
Definition: Track.h:158
void root_val_dumb_cmssw(Event *event)
void quality_val(Event *event)
float momPhi() const
Definition: Track.h:172
std::map< int, std::map< int, std::vector< int > > > LayIdxIDVecMapMap
Definition: TrackExtra.h:37
Definition: event.py:1
void prep_cmsswtracks(Event *event)