CMS 3D CMS Logo

PurgeDuplicate.cc
Go to the documentation of this file.
8 
9 #ifdef USEHYBRID
14 #endif
15 
18 
19 #include <unordered_set>
20 #include <algorithm>
21 
22 using namespace std;
23 using namespace trklet;
24 
25 PurgeDuplicate::PurgeDuplicate(std::string name, Settings const& settings, Globals* global)
26  : ProcessBase(name, settings, global) {}
27 
29  if (settings_.writetrace()) {
30  edm::LogVerbatim("Tracklet") << "In " << name_ << " adding output to " << memory->getName() << " to output "
31  << output;
32  }
33  unordered_set<string> outputs = {"trackout",
34  "trackout1",
35  "trackout2",
36  "trackout3",
37  "trackout4",
38  "trackout5",
39  "trackout6",
40  "trackout7",
41  "trackout8",
42  "trackout9",
43  "trackout10",
44  "trackout11"};
45  if (outputs.find(output) != outputs.end()) {
46  auto* tmp = dynamic_cast<CleanTrackMemory*>(memory);
47  assert(tmp != nullptr);
48  outputtracklets_.push_back(tmp);
49  return;
50  }
51  throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " could not find output: " << output;
52 }
53 
55  if (settings_.writetrace()) {
56  edm::LogVerbatim("Tracklet") << "In " << name_ << " adding input from " << memory->getName() << " to input "
57  << input;
58  }
59  unordered_set<string> inputs = {"trackin",
60  "trackin1",
61  "trackin2",
62  "trackin3",
63  "trackin4",
64  "trackin5",
65  "trackin6",
66  "trackin7",
67  "trackin8",
68  "trackin9",
69  "trackin10",
70  "trackin11",
71  "trackin12"};
72  if (inputs.find(input) != inputs.end()) {
73  auto* tmp = dynamic_cast<TrackFitMemory*>(memory);
74  assert(tmp != nullptr);
75  inputtrackfits_.push_back(tmp);
76  return;
77  }
78  throw cms::Exception("BadConfig") << __FILE__ << " " << __LINE__ << " could not find input: " << input;
79 }
80 
81 void PurgeDuplicate::execute(std::vector<Track>& outputtracks, unsigned int iSector) {
82  inputtracklets_.clear();
83  inputtracks_.clear();
84 
85  inputstubidslists_.clear();
86  inputstublists_.clear();
87  mergedstubidslists_.clear();
88 
89  if (settings_.removalType() != "merge") {
90  for (auto& inputtrackfit : inputtrackfits_) {
91  if (inputtrackfit->nTracks() == 0)
92  continue;
93  for (unsigned int j = 0; j < inputtrackfit->nTracks(); j++) {
94  Track* aTrack = inputtrackfit->getTrack(j)->getTrack();
95  aTrack->setSector(iSector);
96  inputtracks_.push_back(aTrack);
97  }
98  }
99  if (inputtracks_.empty())
100  return;
101  }
102 
103  unsigned int numTrk = inputtracks_.size();
104 
106  // Hybrid Removal //
108 #ifdef USEHYBRID
109 
110  if (settings_.removalType() == "merge") {
111  // Track seed & duplicate flag
112  std::vector<std::pair<int, bool>> trackInfo;
113  // Flag for tracks in multiple bins that get merged but are not in the correct bin
114  std::vector<bool> trackBinInfo;
115  // Vector to store the relative rank of the track candidate for merging, based on seed type
116  std::vector<int> seedRank;
117 
118  // Stubs on every track
119  std::vector<std::vector<const Stub*>> inputstublistsall;
120  // (layer, unique stub index within layer) of each stub on every track
121  std::vector<std::vector<std::pair<int, int>>> mergedstubidslistsall;
122  std::vector<std::vector<std::pair<int, int>>> inputstubidslistsall;
123  std::vector<Tracklet*> inputtrackletsall;
124 
125  std::vector<unsigned int> prefTracks; // Stores all the tracks that are sent to the KF from each bin
126  std::vector<int> prefTrackFit; // Stores the track seed that corresponds to the associated track in prefTracks
127 
128  for (unsigned int bin = 0; bin < settings_.rinvBins().size() - 1; bin++) {
129  for (unsigned int phiBin = 0; phiBin < settings_.phiBins().size() - 1; phiBin++) {
130  // Get vectors from TrackFit and save them
131  // inputtracklets: Tracklet objects from the FitTrack (not actually fit yet)
132  // inputstublists: L1Stubs for that track
133  // inputstubidslists: Stub stubIDs for that 3rack
134  // mergedstubidslists: the same as inputstubidslists, but will be used during duplicate removal
135  for (unsigned int i = 0; i < inputtrackfits_.size(); i++) {
136  if (inputtrackfits_[i]->nStublists() == 0)
137  continue;
138  if (inputtrackfits_[i]->nStublists() != inputtrackfits_[i]->nTracks())
139  throw cms::Exception("LogicError")
140  << __FILE__ << " " << __LINE__ << " Number of stublists and tracks don't match up! ";
141  for (unsigned int j = 0; j < inputtrackfits_[i]->nStublists(); j++) {
144  continue;
145  if (inputtracklets_.size() >= settings_.maxStep("DR"))
146  continue;
147  Tracklet* aTrack = inputtrackfits_[i]->getTrack(j);
149  std::vector<const Stub*> stublist = inputtrackfits_[i]->getStublist(j);
150  inputstublists_.push_back(stublist);
151  std::vector<std::pair<int, int>> stubidslist = inputtrackfits_[i]->getStubidslist(j);
152  inputstubidslists_.push_back(stubidslist);
153  mergedstubidslists_.push_back(stubidslist);
154 
155  // Encoding: L1L2=0, L2L3=1, L3L4=2, L5L6=3, D1D2=4, D3D4=5, L1D1=6, L2D1=7
156  // Best Guess: L1L2 > L1D1 > L2L3 > L2D1 > D1D2 > L3L4 > L5L6 > D3D4
157  // Best Rank: L1L2 > L3L4 > D3D4 > D1D2 > L2L3 > L2D1 > L5L6 > L1D1
158  // Rank-Informed Guess: L1L2 > L3L4 > L1D1 > L2L3 > L2D1 > D1D2 > L5L6 > D3D4
159  unsigned int curSeed = aTrack->seedIndex();
160  std::vector<int> ranks{1, 5, 2, 7, 4, 3, 8, 6};
161  if (settings_.extended())
162  seedRank.push_back(9);
163  else
164  seedRank.push_back(ranks[curSeed]);
165 
166  if (stublist.size() != stubidslist.size())
167  throw cms::Exception("LogicError")
168  << __FILE__ << " " << __LINE__ << " Number of stubs and stubids don't match up! ";
169 
170  trackInfo.emplace_back(i, false);
171  trackBinInfo.emplace_back(false);
172  } else
173  continue;
174  }
175  }
176 
177  if (inputtracklets_.empty())
178  continue;
179  const unsigned int numStublists = inputstublists_.size();
180 
181  if (settings_.inventStubs()) {
182  for (unsigned int itrk = 0; itrk < numStublists; itrk++) {
184  }
185  }
186 
187  // Initialize all-false 2D vector of tracks being duplicates to other tracks
188  vector<vector<bool>> dupMap(numStublists, vector<bool>(numStublists, false));
189 
190  // Used to check if a track is in two bins, is not a duplicate in either bin, so is sent out twice
191  vector<bool> noMerge(numStublists, false);
192 
193  // Find duplicates; Fill dupMap by looping over all pairs of "tracks"
194  // numStublists-1 since last track has no other to compare to
195  for (unsigned int itrk = 0; itrk < numStublists - 1; itrk++) {
196  for (unsigned int jtrk = itrk + 1; jtrk < numStublists; jtrk++) {
197  if (itrk >= settings_.numTracksComparedPerBin())
198  continue;
199  // Get primary track stubids = (layer, unique stub index within layer)
200  const std::vector<std::pair<int, int>>& stubsTrk1 = inputstubidslists_[itrk];
201 
202  // Get and count secondary track stubids
203  const std::vector<std::pair<int, int>>& stubsTrk2 = inputstubidslists_[jtrk];
204 
205  // Count number of layers that share stubs, and the number of UR that each track hits
206  unsigned int nShareLay = 0;
207  if (settings_.mergeComparison() == "CompareAll") {
208  bool layerArr[16];
209  for (auto& i : layerArr) {
210  i = false;
211  };
212  for (const auto& st1 : stubsTrk1) {
213  for (const auto& st2 : stubsTrk2) {
214  if (st1.first == st2.first && st1.second == st2.second) { // tracks share stub
215  // Converts layer/disk encoded in st1->first to an index in the layer array
216  int i = st1.first; // layer/disk
217  bool barrel = (i > 0 && i < 10);
218  bool endcapA = (i > 10);
219  bool endcapB = (i < 0);
220  int lay = barrel * (i - 1) + endcapA * (i - 5) - endcapB * i; // encode in range 0-15
221  if (!layerArr[lay]) {
222  nShareLay++;
223  layerArr[lay] = true;
224  }
225  }
226  }
227  }
228  } else if (settings_.mergeComparison() == "CompareBest") {
229  std::vector<const Stub*> fullStubslistsTrk1 = inputstublists_[itrk];
230  std::vector<const Stub*> fullStubslistsTrk2 = inputstublists_[jtrk];
231 
232  // Arrays to store the index of the best stub in each layer
233  int layStubidsTrk1[16];
234  int layStubidsTrk2[16];
235  for (int i = 0; i < 16; i++) {
236  layStubidsTrk1[i] = -1;
237  layStubidsTrk2[i] = -1;
238  }
239  // For each stub on the first track, find the stub with the best residual and store its index in the layStubidsTrk1 array
240  for (unsigned int stcount = 0; stcount < stubsTrk1.size(); stcount++) {
241  int i = stubsTrk1[stcount].first; // layer/disk
242  bool barrel = (i > 0 && i < 10);
243  bool endcapA = (i > 10);
244  bool endcapB = (i < 0);
245  int lay = barrel * (i - 1) + endcapA * (i - 5) - endcapB * i; // encode in range 0-15
246  double nres = getPhiRes(inputtracklets_[itrk], fullStubslistsTrk1[stcount]);
247  double ores = 0;
248  if (layStubidsTrk1[lay] != -1)
249  ores = getPhiRes(inputtracklets_[itrk], fullStubslistsTrk1[layStubidsTrk1[lay]]);
250  if (layStubidsTrk1[lay] == -1 || nres < ores) {
251  layStubidsTrk1[lay] = stcount;
252  }
253  }
254  // For each stub on the second track, find the stub with the best residual and store its index in the layStubidsTrk1 array
255  for (unsigned int stcount = 0; stcount < stubsTrk2.size(); stcount++) {
256  int i = stubsTrk2[stcount].first; // layer/disk
257  bool barrel = (i > 0 && i < 10);
258  bool endcapA = (i > 10);
259  bool endcapB = (i < 0);
260  int lay = barrel * (i - 1) + endcapA * (i - 5) - endcapB * i; // encode in range 0-15
261  double nres = getPhiRes(inputtracklets_[jtrk], fullStubslistsTrk2[stcount]);
262  double ores = 0;
263  if (layStubidsTrk2[lay] != -1)
264  ores = getPhiRes(inputtracklets_[jtrk], fullStubslistsTrk2[layStubidsTrk2[lay]]);
265  if (layStubidsTrk2[lay] == -1 || nres < ores) {
266  layStubidsTrk2[lay] = stcount;
267  }
268  }
269  // For all 16 layers (6 layers and 10 disks), count the number of layers who's best stub on both tracks are the same
270  for (int i = 0; i < 16; i++) {
271  int t1i = layStubidsTrk1[i];
272  int t2i = layStubidsTrk2[i];
273  if (t1i != -1 && t2i != -1 && stubsTrk1[t1i].first == stubsTrk2[t2i].first &&
274  stubsTrk1[t1i].second == stubsTrk2[t2i].second)
275  nShareLay++;
276  }
277  }
278 
279  // Fill duplicate map
280  if (nShareLay >= settings_.minIndStubs()) { // For number of shared stub merge condition
281  dupMap.at(itrk).at(jtrk) = true;
282  dupMap.at(jtrk).at(itrk) = true;
283  }
284  }
285  }
286 
287  // Check to see if the track is a duplicate
288  for (unsigned int itrk = 0; itrk < numStublists; itrk++) {
289  for (unsigned int jtrk = 0; jtrk < numStublists; jtrk++) {
290  if (dupMap.at(itrk).at(jtrk)) {
291  noMerge.at(itrk) = true;
292  }
293  }
294  }
295 
296  // If the track isn't a duplicate, and if it's in more than one bin, and it is not in the proper rinv or phi bin, then mark it so it won't be sent to output
297  for (unsigned int itrk = 0; itrk < numStublists; itrk++) {
298  if (!noMerge.at(itrk)) {
299  if (((findOverlapRinvBins(inputtracklets_[itrk]).size() > 1) &&
300  (findRinvBin(inputtracklets_[itrk]) != bin)) ||
301  ((findOverlapPhiBins(inputtracklets_[itrk]).size() > 1) &&
302  findPhiBin(inputtracklets_[itrk]) != phiBin)) {
303  trackInfo[itrk].second = true;
304  }
305  }
306  }
307  // Merge duplicate tracks
308  for (unsigned int itrk = 0; itrk < numStublists - 1; itrk++) {
309  for (unsigned int jtrk = itrk + 1; jtrk < numStublists; jtrk++) {
310  // Merge a track with its first duplicate found.
311  if (dupMap.at(itrk).at(jtrk)) {
312  // Set preferred track based on seed rank
313  int preftrk;
314  int rejetrk;
315  if (seedRank[itrk] < seedRank[jtrk]) {
316  preftrk = itrk;
317  rejetrk = jtrk;
318  } else {
319  preftrk = jtrk;
320  rejetrk = itrk;
321  }
322 
323  // If the preffered track is in more than one bin, but not in the proper rinv or phi bin, then mark as true
324  if (((findOverlapRinvBins(inputtracklets_[preftrk]).size() > 1) &&
325  (findRinvBin(inputtracklets_[preftrk]) != bin)) ||
326  ((findOverlapPhiBins(inputtracklets_[preftrk]).size() > 1) &&
327  (findPhiBin(inputtracklets_[preftrk]) != phiBin))) {
328  trackBinInfo[preftrk] = true;
329  trackBinInfo[rejetrk] = true;
330  } else {
331  // Get a merged stub list
332  std::vector<const Stub*> newStubList;
333  std::vector<const Stub*> stubsTrk1 = inputstublists_[preftrk];
334  std::vector<const Stub*> stubsTrk2 = inputstublists_[rejetrk];
335  std::vector<unsigned int> stubsTrk1indices;
336  std::vector<unsigned int> stubsTrk2indices;
337  for (unsigned int stub1it = 0; stub1it < stubsTrk1.size(); stub1it++) {
338  stubsTrk1indices.push_back(stubsTrk1[stub1it]->l1tstub()->uniqueIndex());
339  }
340  for (unsigned int stub2it = 0; stub2it < stubsTrk2.size(); stub2it++) {
341  stubsTrk2indices.push_back(stubsTrk2[stub2it]->l1tstub()->uniqueIndex());
342  }
343  newStubList = stubsTrk1;
344  for (unsigned int stub2it = 0; stub2it < stubsTrk2.size(); stub2it++) {
345  if (find(stubsTrk1indices.begin(), stubsTrk1indices.end(), stubsTrk2indices[stub2it]) ==
346  stubsTrk1indices.end()) {
347  newStubList.push_back(stubsTrk2[stub2it]);
348  }
349  }
350  // Overwrite stublist of preferred track with merged list
351  inputstublists_[preftrk] = newStubList;
352 
353  std::vector<std::pair<int, int>> newStubidsList;
354  std::vector<std::pair<int, int>> stubidsTrk1 = mergedstubidslists_[preftrk];
355  std::vector<std::pair<int, int>> stubidsTrk2 = mergedstubidslists_[rejetrk];
356  newStubidsList = stubidsTrk1;
357 
358  for (unsigned int stub2it = 0; stub2it < stubsTrk2.size(); stub2it++) {
359  if (find(stubsTrk1indices.begin(), stubsTrk1indices.end(), stubsTrk2indices[stub2it]) ==
360  stubsTrk1indices.end()) {
361  newStubidsList.push_back(stubidsTrk2[stub2it]);
362  }
363  }
364  // Overwrite stubidslist of preferred track with merged list
365  mergedstubidslists_[preftrk] = newStubidsList;
366 
367  // Mark that rejected track has been merged into another track
368  trackInfo[rejetrk].second = true;
369  }
370  }
371  }
372  }
373 
374  for (unsigned int ktrk = 0; ktrk < numStublists; ktrk++) {
375  if ((trackInfo[ktrk].second != true) && (trackBinInfo[ktrk] != true)) {
376  prefTracks.push_back(ktrk);
377  prefTrackFit.push_back(trackInfo[ktrk].first);
378  inputtrackletsall.push_back(inputtracklets_[ktrk]);
379  inputstublistsall.push_back(inputstublists_[ktrk]);
380  inputstubidslistsall.push_back(inputstubidslists_[ktrk]);
381  mergedstubidslistsall.push_back(mergedstubidslists_[ktrk]);
382  }
383  }
384 
385  // Need to clear all the vectors which will be used in the next bin
386  seedRank.clear();
387  trackInfo.clear();
388  trackBinInfo.clear();
389  inputtracklets_.clear();
390  inputstublists_.clear();
391  inputstubidslists_.clear();
392  mergedstubidslists_.clear();
393  }
394  }
395 
396  // Make the final track objects, fit with KF, and send to output
397  for (unsigned int itrk = 0; itrk < prefTracks.size(); itrk++) {
398  Tracklet* tracklet = inputtrackletsall[itrk];
399  std::vector<const Stub*> trackstublist = inputstublistsall[itrk];
400 
401  // Run KF track fit
402  HybridFit hybridFitter(iSector, settings_, globals_);
403  hybridFitter.Fit(tracklet, trackstublist);
404 
405  // If the track was accepted (and thus fit), add to output
406  if (tracklet->fit()) {
407  // Add fitted Track to output (later converted to TTTrack)
408  Track* outtrack = tracklet->getTrack();
409  outtrack->setSector(iSector);
410  // Also store fitted track as more detailed Tracklet object.
411  outputtracklets_[prefTrackFit[itrk]]->addTrack(tracklet);
412 
413  // Add all tracks to standalone root file output
414  outtrack->setStubIDpremerge(inputstubidslistsall[itrk]);
415  outtrack->setStubIDprefit(mergedstubidslistsall[itrk]);
416  outputtracks.push_back(*outtrack);
417  }
418  }
419  }
420 
421 #endif
422 
424  // Grid removal //
426  if (settings_.removalType() == "grid") {
427  // Sort tracks by ichisq/DoF so that removal will keep the lower ichisq/DoF track
428  std::sort(inputtracks_.begin(), inputtracks_.end(), [](const Track* lhs, const Track* rhs) {
429  return lhs->ichisq() / lhs->stubID().size() < rhs->ichisq() / rhs->stubID().size();
430  });
431  bool grid[35][40] = {{false}};
432 
433  for (unsigned int itrk = 0; itrk < numTrk; itrk++) {
434  if (inputtracks_[itrk]->duplicate())
435  edm::LogPrint("Tracklet") << "WARNING: Track already tagged as duplicate!!";
436 
437  double phiBin = (inputtracks_[itrk]->phi0(settings_) - 2 * M_PI / 27 * iSector) / (2 * M_PI / 9 / 50) + 9;
438  phiBin = std::max(phiBin, 0.);
439  phiBin = std::min(phiBin, 34.);
440 
441  double ptBin = 1 / inputtracks_[itrk]->pt(settings_) * 40 + 20;
442  ptBin = std::max(ptBin, 0.);
443  ptBin = std::min(ptBin, 39.);
444 
445  if (grid[(int)phiBin][(int)ptBin])
446  inputtracks_[itrk]->setDuplicate(true);
447  grid[(int)phiBin][(int)ptBin] = true;
448 
449  double phiTest = inputtracks_[itrk]->phi0(settings_) - 2 * M_PI / 27 * iSector;
450  if (phiTest < -2 * M_PI / 27)
451  edm::LogVerbatim("Tracklet") << "track phi too small!";
452  if (phiTest > 2 * 2 * M_PI / 27)
453  edm::LogVerbatim("Tracklet") << "track phi too big!";
454  }
455  } // end grid removal
456 
458  // ichi + nstub removal //
460  if (settings_.removalType() == "ichi" || settings_.removalType() == "nstub") {
461  for (unsigned int itrk = 0; itrk < numTrk - 1; itrk++) { // numTrk-1 since last track has no other to compare to
462 
463  // If primary track is a duplicate, it cannot veto any...move on
464  if (inputtracks_[itrk]->duplicate() == 1)
465  continue;
466 
467  unsigned int nStubP = 0;
468  vector<unsigned int> nStubS(numTrk);
469  vector<unsigned int> nShare(numTrk);
470  // Get and count primary stubs
471  std::map<int, int> stubsTrk1 = inputtracks_[itrk]->stubID();
472  nStubP = stubsTrk1.size();
473 
474  for (unsigned int jtrk = itrk + 1; jtrk < numTrk; jtrk++) {
475  // Skip duplicate tracks
476  if (inputtracks_[jtrk]->duplicate() == 1)
477  continue;
478 
479  // Get and count secondary stubs
480  std::map<int, int> stubsTrk2 = inputtracks_[jtrk]->stubID();
481  nStubS[jtrk] = stubsTrk2.size();
482 
483  // Count shared stubs
484  for (auto& st : stubsTrk1) {
485  if (stubsTrk2.find(st.first) != stubsTrk2.end()) {
486  if (st.second == stubsTrk2[st.first])
487  nShare[jtrk]++;
488  }
489  }
490  }
491 
492  // Tag duplicates
493  for (unsigned int jtrk = itrk + 1; jtrk < numTrk; jtrk++) {
494  // Skip duplicate tracks
495  if (inputtracks_[jtrk]->duplicate() == 1)
496  continue;
497 
498  // Chi2 duplicate removal
499  if (settings_.removalType() == "ichi") {
500  if ((nStubP - nShare[jtrk] < settings_.minIndStubs()) ||
501  (nStubS[jtrk] - nShare[jtrk] < settings_.minIndStubs())) {
502  if ((int)inputtracks_[itrk]->ichisq() / (2 * inputtracks_[itrk]->stubID().size() - 4) >
503  (int)inputtracks_[jtrk]->ichisq() / (2 * inputtracks_[itrk]->stubID().size() - 4)) {
504  inputtracks_[itrk]->setDuplicate(true);
505  } else if ((int)inputtracks_[itrk]->ichisq() / (2 * inputtracks_[itrk]->stubID().size() - 4) <=
506  (int)inputtracks_[jtrk]->ichisq() / (2 * inputtracks_[itrk]->stubID().size() - 4)) {
507  inputtracks_[jtrk]->setDuplicate(true);
508  } else {
509  edm::LogVerbatim("Tracklet") << "Error: Didn't tag either track in duplicate pair.";
510  }
511  }
512  } // end ichi removal
513 
514  // nStub duplicate removal
515  if (settings_.removalType() == "nstub") {
516  if ((nStubP - nShare[jtrk] < settings_.minIndStubs()) && (nStubP < nStubS[jtrk])) {
517  inputtracks_[itrk]->setDuplicate(true);
518  } else if ((nStubS[jtrk] - nShare[jtrk] < settings_.minIndStubs()) && (nStubS[jtrk] <= nStubP)) {
519  inputtracks_[jtrk]->setDuplicate(true);
520  } else {
521  edm::LogVerbatim("Tracklet") << "Error: Didn't tag either track in duplicate pair.";
522  }
523  } // end nstub removal
524 
525  } // end tag duplicates
526 
527  } // end loop over primary track
528 
529  } // end ichi + nstub removal
530 
531  //Add tracks to output
532  if (settings_.removalType() != "merge") {
533  for (unsigned int i = 0; i < inputtrackfits_.size(); i++) {
534  for (unsigned int j = 0; j < inputtrackfits_[i]->nTracks(); j++) {
535  if (inputtrackfits_[i]->getTrack(j)->getTrack()->duplicate() == 0) {
536  if (settings_.writeMonitorData("Seeds")) {
537  ofstream fout("seeds.txt", ofstream::app);
538  fout << __FILE__ << ":" << __LINE__ << " " << name_ << "_" << iSector << " "
539  << inputtrackfits_[i]->getTrack(j)->getISeed() << endl;
540  fout.close();
541  }
542  outputtracklets_[i]->addTrack(inputtrackfits_[i]->getTrack(j));
543  }
544  //For root file:
545  outputtracks.push_back(*inputtrackfits_[i]->getTrack(j)->getTrack());
546  }
547  }
548  }
549 }
550 
551 double PurgeDuplicate::getPhiRes(Tracklet* curTracklet, const Stub* curStub) const {
552  double phiproj;
553  double stubphi;
554  double phires;
555  // Get phi position of stub
556  stubphi = curStub->l1tstub()->phi();
557  // Get layer that the stub is in (Layer 1->6, Disk 1->5)
558  int Layer = curStub->layerdisk() + 1;
559  if (Layer > N_LAYER) {
560  Layer = 0;
561  }
562  int Disk = curStub->layerdisk() - (N_LAYER - 1);
563  if (Disk < 0) {
564  Disk = 0;
565  }
566  // Get phi projection of tracklet
567  int seedindex = curTracklet->seedIndex();
568  // If this stub is a seed stub, set projection=phi, so that res=0
569  if (isSeedingStub(seedindex, Layer, Disk)) {
570  phiproj = stubphi;
571  // Otherwise, get projection of tracklet
572  } else {
573  phiproj = curTracklet->proj(curStub->layerdisk()).phiproj();
574  }
575  // Calculate residual
576  phires = std::abs(stubphi - phiproj);
577  return phires;
578 }
579 
580 bool PurgeDuplicate::isSeedingStub(int seedindex, int Layer, int Disk) const {
581  if ((seedindex == 0 && (Layer == 1 || Layer == 2)) || (seedindex == 1 && (Layer == 2 || Layer == 3)) ||
582  (seedindex == 2 && (Layer == 3 || Layer == 4)) || (seedindex == 3 && (Layer == 5 || Layer == 6)) ||
583  (seedindex == 4 && (abs(Disk) == 1 || abs(Disk) == 2)) ||
584  (seedindex == 5 && (abs(Disk) == 3 || abs(Disk) == 4)) || (seedindex == 6 && (Layer == 1 || abs(Disk) == 1)) ||
585  (seedindex == 7 && (Layer == 2 || abs(Disk) == 1)) ||
586  (seedindex == 8 && (Layer == 2 || Layer == 3 || Layer == 4)) ||
587  (seedindex == 9 && (Layer == 4 || Layer == 5 || Layer == 6)) ||
588  (seedindex == 10 && (Layer == 2 || Layer == 3 || abs(Disk) == 1)) ||
589  (seedindex == 11 && (Layer == 2 || abs(Disk) == 1 || abs(Disk) == 2)))
590  return true;
591 
592  return false;
593 }
594 
595 std::pair<int, int> PurgeDuplicate::findLayerDisk(const Stub* st) const {
596  std::pair<int, int> layer_disk;
597  layer_disk.first = st->layerdisk() + 1;
598  if (layer_disk.first > N_LAYER) {
599  layer_disk.first = 0;
600  }
601  layer_disk.second = st->layerdisk() - (N_LAYER - 1);
602  if (layer_disk.second < 0) {
603  layer_disk.second = 0;
604  }
605  return layer_disk;
606 }
607 
609  std::string thestr = Form("\t %s stub info: r/z/phi:\t%f\t%f\t%f\t%d\t%f\t%d",
610  str.c_str(),
611  l1stub->r(),
612  l1stub->z(),
613  l1stub->phi(),
614  l1stub->iphi(),
615  l1stub->bend(),
616  l1stub->layerdisk());
617  return thestr;
618 }
619 
620 std::vector<double> PurgeDuplicate::getInventedCoords(unsigned int iSector,
621  const Stub* st,
622  const Tracklet* tracklet) const {
623  int stubLayer = (findLayerDisk(st)).first;
624  int stubDisk = (findLayerDisk(st)).second;
625 
626  double stub_phi = -99;
627  double stub_z = -99;
628  double stub_r = -99;
629 
630  double tracklet_rinv = tracklet->rinv();
631 
632  if (st->isBarrel()) {
633  stub_r = settings_.rmean(stubLayer - 1);
634  stub_phi = tracklet->phi0() - std::asin(stub_r * tracklet_rinv / 2);
635  stub_phi = stub_phi + iSector * settings_.dphisector() - 0.5 * settings_.dphisectorHG();
636  stub_phi = reco::reduceRange(stub_phi);
637  stub_z = tracklet->z0() + 2 * tracklet->t() * 1 / tracklet_rinv * std::asin(stub_r * tracklet_rinv / 2);
638  } else {
639  stub_z = settings_.zmean(stubDisk - 1) * tracklet->disk() / abs(tracklet->disk());
640  stub_phi = tracklet->phi0() - (stub_z - tracklet->z0()) * tracklet_rinv / 2 / tracklet->t();
641  stub_phi = stub_phi + iSector * settings_.dphisector() - 0.5 * settings_.dphisectorHG();
642  stub_phi = reco::reduceRange(stub_phi);
643  stub_r = 2 / tracklet_rinv * std::sin((stub_z - tracklet->z0()) * tracklet_rinv / 2 / tracklet->t());
644  }
645 
646  std::vector<double> invented_coords{stub_r, stub_z, stub_phi};
647  return invented_coords;
648 }
649 
650 std::vector<double> PurgeDuplicate::getInventedCoordsExtended(unsigned int iSector,
651  const Stub* st,
652  const Tracklet* tracklet) const {
653  int stubLayer = (findLayerDisk(st)).first;
654  int stubDisk = (findLayerDisk(st)).second;
655 
656  double stub_phi = -99;
657  double stub_z = -99;
658  double stub_r = -99;
659 
660  double rho = 1 / tracklet->rinv();
661  double rho_minus_d0 = rho + tracklet->d0(); // should be -, but otherwise does not work
662 
663  // exact helix
664  if (st->isBarrel()) {
665  stub_r = settings_.rmean(stubLayer - 1);
666 
667  double sin_val = (stub_r * stub_r + rho_minus_d0 * rho_minus_d0 - rho * rho) / (2 * stub_r * rho_minus_d0);
668  stub_phi = tracklet->phi0() - std::asin(sin_val);
669  stub_phi = stub_phi + iSector * settings_.dphisector() - 0.5 * settings_.dphisectorHG();
670  stub_phi = reco::reduceRange(stub_phi);
671 
672  double beta = std::acos((rho * rho + rho_minus_d0 * rho_minus_d0 - stub_r * stub_r) / (2 * rho * rho_minus_d0));
673  stub_z = tracklet->z0() + tracklet->t() * std::abs(rho * beta);
674  } else {
675  stub_z = settings_.zmean(stubDisk - 1) * tracklet->disk() / abs(tracklet->disk());
676 
677  double beta = (stub_z - tracklet->z0()) / (tracklet->t() * std::abs(rho)); // maybe rho should be abs value
678  double r_square = -2 * rho * rho_minus_d0 * std::cos(beta) + rho * rho + rho_minus_d0 * rho_minus_d0;
679  stub_r = sqrt(r_square);
680 
681  double sin_val = (stub_r * stub_r + rho_minus_d0 * rho_minus_d0 - rho * rho) / (2 * stub_r * rho_minus_d0);
682  stub_phi = tracklet->phi0() - std::asin(sin_val);
683  stub_phi = stub_phi + iSector * settings_.dphisector() - 0.5 * settings_.dphisectorHG();
684  stub_phi = reco::reduceRange(stub_phi);
685  }
686 
687  // TMP: for displaced tracking, exclude one of the 3 seeding stubs
688  // to be discussed
689  int seed = tracklet->seedIndex();
690  if ((seed == 8 && stubLayer == 4) || (seed == 9 && stubLayer == 5) || (seed == 10 && stubLayer == 3) ||
691  (seed == 11 && abs(stubDisk) == 1)) {
692  stub_phi = st->l1tstub()->phi();
693  stub_z = st->l1tstub()->z();
694  stub_r = st->l1tstub()->r();
695  }
696 
697  std::vector<double> invented_coords{stub_r, stub_z, stub_phi};
698  return invented_coords;
699 }
700 
701 std::vector<const Stub*> PurgeDuplicate::getInventedSeedingStub(
702  unsigned int iSector, const Tracklet* tracklet, const std::vector<const Stub*>& originalStubsList) const {
703  std::vector<const Stub*> newStubList;
704 
705  for (unsigned int stubit = 0; stubit < originalStubsList.size(); stubit++) {
706  const Stub* thisStub = originalStubsList[stubit];
707 
708  if (isSeedingStub(tracklet->seedIndex(), (findLayerDisk(thisStub)).first, (findLayerDisk(thisStub)).second)) {
709  // get a vector containing r, z, phi
710  std::vector<double> inv_r_z_phi;
711  if (!settings_.extended())
712  inv_r_z_phi = getInventedCoords(iSector, thisStub, tracklet);
713  else {
714  inv_r_z_phi = getInventedCoordsExtended(iSector, thisStub, tracklet);
715  }
716  double stub_x_invent = inv_r_z_phi[0] * std::cos(inv_r_z_phi[2]);
717  double stub_y_invent = inv_r_z_phi[0] * std::sin(inv_r_z_phi[2]);
718  double stub_z_invent = inv_r_z_phi[1];
719 
720  Stub* invent_stub_ptr = new Stub(*thisStub);
721  const L1TStub* l1stub = thisStub->l1tstub();
722  L1TStub invent_l1stub = *l1stub;
723  invent_l1stub.setCoords(stub_x_invent, stub_y_invent, stub_z_invent);
724 
725  invent_stub_ptr->setl1tstub(new L1TStub(invent_l1stub));
726  invent_stub_ptr->l1tstub()->setAllStubIndex(l1stub->allStubIndex());
727  invent_stub_ptr->l1tstub()->setUniqueIndex(l1stub->uniqueIndex());
728 
729  newStubList.push_back(invent_stub_ptr);
730 
731  } else {
732  newStubList.push_back(thisStub);
733  }
734  }
735  return newStubList;
736 }
737 
738 // Tells us the variable bin to which a track would belong
739 unsigned int PurgeDuplicate::findRinvBin(const Tracklet* trk) const {
740  std::vector<double> rinvBins = settings_.rinvBins();
741 
742  //Get rinverse of track
743  double rinv = trk->rinv();
744 
745  //Check between what 2 values in rinvbins rinv is between
746  auto bins = std::upper_bound(rinvBins.begin(), rinvBins.end(), rinv);
747 
748  //return integer for bin index
749  unsigned int rIndx = std::distance(rinvBins.begin(), bins);
750  if (rIndx == std::distance(rinvBins.end(), bins))
751  return rinvBins.size() - 2;
752  else if (bins == rinvBins.begin())
753  return std::distance(rinvBins.begin(), bins);
754  else
755  return rIndx - 1;
756 }
757 
758 // Tells us the phi bin to which a track would belong
759 unsigned int PurgeDuplicate::findPhiBin(const Tracklet* trk) const {
760  std::vector<double> phiBins = settings_.phiBins();
761 
762  //Get phi of track at rcrit
763  double phi0 = trk->phi0();
764  double rcrit = settings_.rcrit();
765  double rinv = trk->rinv();
766  double phi = phi0 - asin(0.5 * rinv * rcrit);
767 
768  //Check between what 2 values in phibins phi is between
769  auto bins = std::upper_bound(phiBins.begin(), phiBins.end(), phi);
770 
771  //return integer for bin index
772  unsigned int phiIndx = std::distance(phiBins.begin(), bins);
773  if (phiIndx == std::distance(phiBins.end(), bins))
774  return phiBins.size() - 2;
775  else if (bins == phiBins.begin())
776  return std::distance(phiBins.begin(), bins);
777  else
778  return phiIndx - 1;
779 }
780 
781 // Tells us the overlap rinv bin(s) to which a track belongs
782 std::vector<unsigned int> PurgeDuplicate::findOverlapRinvBins(const Tracklet* trk) const {
783  double rinv = trk->rinv();
784 
785  const double rinvOverlapSize = settings_.rinvOverlapSize();
786  const std::vector<double>& rinvBins = settings_.rinvBins();
787 
788  std::vector<unsigned int> chosenBins;
789  for (long unsigned int i = 0; i < rinvBins.size() - 1; i++) {
790  if ((rinv < rinvBins[i + 1] + rinvOverlapSize) && (rinv > rinvBins[i] - rinvOverlapSize)) {
791  chosenBins.push_back(i);
792  }
793  }
794  return chosenBins;
795 }
796 
797 // Tells us the overlap phi bin(s) to which a track belongs
798 std::vector<unsigned int> PurgeDuplicate::findOverlapPhiBins(const Tracklet* trk) const {
799  double phi0 = trk->phi0();
800  double rcrit = settings_.rcrit();
801  double rinv = trk->rinv();
802  double phi = phi0 - asin(0.5 * rinv * rcrit);
803 
804  const double phiOverlapSize = settings_.phiOverlapSize();
805  const std::vector<double>& phiBins = settings_.phiBins();
806 
807  std::vector<unsigned int> chosenBins;
808  for (long unsigned int i = 0; i < phiBins.size() - 1; i++) {
809  if ((phi < phiBins[i + 1] + phiOverlapSize) && (phi > phiBins[i] - phiOverlapSize)) {
810  chosenBins.push_back(i);
811  }
812  }
813  return chosenBins;
814 }
815 
816 // Tells us if a track is in the current bin
817 bool PurgeDuplicate::isTrackInBin(const std::vector<unsigned int>& vec, unsigned int num) const {
818  auto result = std::find(vec.begin(), vec.end(), num);
819  bool found = (result != vec.end());
820  return found;
821 }
Log< level::Info, true > LogVerbatim
unsigned int seedIndex() const
Definition: Tracklet.h:224
double phi() const
Definition: L1TStub.h:65
double t() const
Definition: Tracklet.h:123
unsigned int maxStep(std::string module) const
Definition: Settings.h:125
std::string name_
Definition: ProcessBase.h:38
int disk() const
Definition: Tracklet.cc:792
constexpr T reduceRange(T x)
Definition: deltaPhi.h:18
double rinvOverlapSize() const
Definition: Settings.h:296
double bend() const
Definition: L1TStub.h:63
std::vector< std::vector< std::pair< int, int > > > inputstubidslists_
double dphisectorHG() const
Definition: Settings.h:320
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
bool isBarrel() const
Definition: Stub.h:87
void Fit(Tracklet *tracklet, std::vector< const Stub *> &trackstublist)
Projection & proj(int layerdisk)
Definition: Tracklet.h:87
Settings const & settings_
Definition: ProcessBase.h:40
double phi0() const
Definition: Tracklet.h:121
double z() const
Definition: L1TStub.h:59
Globals * globals_
Definition: ProcessBase.h:41
double getPhiRes(Tracklet *curTracklet, const Stub *curStub) const
bool writetrace() const
Definition: Settings.h:195
std::vector< CleanTrackMemory * > outputtracklets_
unsigned int minIndStubs() const
Definition: Settings.h:250
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
assert(be >=bs)
std::vector< Track * > inputtracks_
static std::string const input
Definition: EdmProvDump.cc:50
Track * getTrack()
Definition: Tracklet.h:192
bool fit() const
Definition: Tracklet.h:197
SeedingLayerSetsHits::SeedingLayer Layer
Definition: LayerTriplets.h:14
Definition: BoundDisk.h:19
U second(std::pair< T, U > const &p)
std::vector< double > getInventedCoords(unsigned int, const Stub *, const Tracklet *) const
const std::vector< double > & phiBins() const
Definition: Settings.h:304
std::vector< double > getInventedCoordsExtended(unsigned int, const Stub *, const Tracklet *) const
std::vector< unsigned int > findOverlapPhiBins(const Tracklet *trk) const
double dphisector() const
Definition: Settings.h:329
double rmean(unsigned int iLayer) const
Definition: Settings.h:173
double rinv() const
Definition: Tracklet.h:120
T sqrt(T t)
Definition: SSEVec.h:19
unsigned int findPhiBin(const Tracklet *trk) const
double phiOverlapSize() const
Definition: Settings.h:298
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
void execute(std::vector< Track > &outputtracks, unsigned int iSector)
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int layerdisk() const
Definition: L1TStub.h:119
unsigned int numTracksComparedPerBin() const
Definition: Settings.h:300
std::string removalType() const
Definition: Settings.h:251
std::vector< TrackFitMemory * > inputtrackfits_
L1TStub * l1tstub()
Definition: Stub.h:83
bool writeMonitorData(std::string module) const
Definition: Settings.h:118
unsigned int layerdisk() const
Definition: Stub.cc:193
bool inventStubs() const
Definition: Settings.h:274
void setUniqueIndex(unsigned int index)
Definition: L1TStub.h:84
double zmean(unsigned int iDisk) const
Definition: Settings.h:176
unsigned int allStubIndex() const
Definition: L1TStub.h:91
#define M_PI
bool isTrackInBin(const std::vector< unsigned int > &vec, unsigned int num) const
std::pair< int, int > findLayerDisk(const Stub *) const
double d0() const
Definition: Tracklet.h:122
static const TrackGhostTrackState * getTrack(const BasicGhostTrackState *basic)
void setSector(int nsec)
Definition: Track.h:34
std::vector< unsigned int > findOverlapRinvBins(const Tracklet *trk) const
double rinv(double phi1, double phi2, double r1, double r2)
Definition: Util.h:66
void addInput(MemoryBase *memory, std::string input) override
void setCoords(double x, double y, double z)
Definition: L1TStub.h:85
unsigned int findRinvBin(const Tracklet *trk) const
std::vector< Tracklet * > inputtracklets_
std::vector< std::vector< std::pair< int, int > > > mergedstubidslists_
std::string mergeComparison() const
Definition: Settings.h:252
void addOutput(MemoryBase *memory, std::string output) override
bool extended() const
Definition: Settings.h:268
double z0() const
Definition: Tracklet.h:124
std::vector< const Stub * > getInventedSeedingStub(unsigned int, const Tracklet *, const std::vector< const Stub *> &) const
int ichisq() const
Definition: Track.h:40
double r() const
Definition: L1TStub.h:60
void setl1tstub(L1TStub *l1tstub)
Definition: Stub.h:85
Definition: output.py:1
void setAllStubIndex(unsigned int index)
Definition: L1TStub.h:83
std::vector< std::vector< const Stub * > > inputstublists_
unsigned int iphi() const
Definition: L1TStub.h:67
#define str(s)
tmp
align.sh
Definition: createJobs.py:716
int uniqueIndex(int eta, int phi)
const std::vector< double > & rinvBins() const
Definition: Settings.h:302
std::string l1tinfo(const L1TStub *, std::string) const
bool isSeedingStub(int, int, int) const
void setStubIDprefit(std::vector< std::pair< int, int >> stubIDprefit)
Definition: Track.h:36
const std::map< int, int > & stubID() const
Definition: Track.h:42
void setStubIDpremerge(std::vector< std::pair< int, int >> stubIDpremerge)
Definition: Track.h:35
unsigned int uniqueIndex() const
Definition: L1TStub.h:92
constexpr int N_LAYER
Definition: Settings.h:25
double rcrit() const
Definition: Settings.h:327