CMS 3D CMS Logo

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