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 array of tracks being duplicates to other tracks
188  bool dupMap[numStublists][numStublists]; // Ends up symmetric
189  for (unsigned int itrk = 0; itrk < numStublists; itrk++) {
190  for (unsigned int jtrk = 0; jtrk < numStublists; jtrk++) {
191  dupMap[itrk][jtrk] = false;
192  }
193  }
194 
195  // Used to check if a track is in two bins, is not a duplicate in either bin, so is sent out twice
196  bool noMerge[numStublists];
197  for (unsigned int itrk = 0; itrk < numStublists; itrk++) {
198  noMerge[itrk] = false;
199  }
200 
201  // Find duplicates; Fill dupMap by looping over all pairs of "tracks"
202  // numStublists-1 since last track has no other to compare to
203  for (unsigned int itrk = 0; itrk < numStublists - 1; itrk++) {
204  for (unsigned int jtrk = itrk + 1; jtrk < numStublists; jtrk++) {
205  if (itrk >= settings_.numTracksComparedPerBin())
206  continue;
207  // Get primary track stubids = (layer, unique stub index within layer)
208  const std::vector<std::pair<int, int>>& stubsTrk1 = inputstubidslists_[itrk];
209 
210  // Get and count secondary track stubids
211  const std::vector<std::pair<int, int>>& stubsTrk2 = inputstubidslists_[jtrk];
212 
213  // Count number of layers that share stubs, and the number of UR that each track hits
214  unsigned int nShareLay = 0;
215  if (settings_.mergeComparison() == "CompareAll") {
216  bool layerArr[16];
217  for (auto& i : layerArr) {
218  i = false;
219  };
220  for (const auto& st1 : stubsTrk1) {
221  for (const auto& st2 : stubsTrk2) {
222  if (st1.first == st2.first && st1.second == st2.second) { // tracks share stub
223  // Converts layer/disk encoded in st1->first to an index in the layer array
224  int i = st1.first; // layer/disk
225  bool barrel = (i > 0 && i < 10);
226  bool endcapA = (i > 10);
227  bool endcapB = (i < 0);
228  int lay = barrel * (i - 1) + endcapA * (i - 5) - endcapB * i; // encode in range 0-15
229  if (!layerArr[lay]) {
230  nShareLay++;
231  layerArr[lay] = true;
232  }
233  }
234  }
235  }
236  } else if (settings_.mergeComparison() == "CompareBest") {
237  std::vector<const Stub*> fullStubslistsTrk1 = inputstublists_[itrk];
238  std::vector<const Stub*> fullStubslistsTrk2 = inputstublists_[jtrk];
239 
240  // Arrays to store the index of the best stub in each layer
241  int layStubidsTrk1[16];
242  int layStubidsTrk2[16];
243  for (int i = 0; i < 16; i++) {
244  layStubidsTrk1[i] = -1;
245  layStubidsTrk2[i] = -1;
246  }
247  // For each stub on the first track, find the stub with the best residual and store its index in the layStubidsTrk1 array
248  for (unsigned int stcount = 0; stcount < stubsTrk1.size(); stcount++) {
249  int i = stubsTrk1[stcount].first; // layer/disk
250  bool barrel = (i > 0 && i < 10);
251  bool endcapA = (i > 10);
252  bool endcapB = (i < 0);
253  int lay = barrel * (i - 1) + endcapA * (i - 5) - endcapB * i; // encode in range 0-15
254  double nres = getPhiRes(inputtracklets_[itrk], fullStubslistsTrk1[stcount]);
255  double ores = 0;
256  if (layStubidsTrk1[lay] != -1)
257  ores = getPhiRes(inputtracklets_[itrk], fullStubslistsTrk1[layStubidsTrk1[lay]]);
258  if (layStubidsTrk1[lay] == -1 || nres < ores) {
259  layStubidsTrk1[lay] = stcount;
260  }
261  }
262  // For each stub on the second track, find the stub with the best residual and store its index in the layStubidsTrk1 array
263  for (unsigned int stcount = 0; stcount < stubsTrk2.size(); stcount++) {
264  int i = stubsTrk2[stcount].first; // layer/disk
265  bool barrel = (i > 0 && i < 10);
266  bool endcapA = (i > 10);
267  bool endcapB = (i < 0);
268  int lay = barrel * (i - 1) + endcapA * (i - 5) - endcapB * i; // encode in range 0-15
269  double nres = getPhiRes(inputtracklets_[jtrk], fullStubslistsTrk2[stcount]);
270  double ores = 0;
271  if (layStubidsTrk2[lay] != -1)
272  ores = getPhiRes(inputtracklets_[jtrk], fullStubslistsTrk2[layStubidsTrk2[lay]]);
273  if (layStubidsTrk2[lay] == -1 || nres < ores) {
274  layStubidsTrk2[lay] = stcount;
275  }
276  }
277  // For all 16 layers (6 layers and 10 disks), count the number of layers who's best stub on both tracks are the same
278  for (int i = 0; i < 16; i++) {
279  int t1i = layStubidsTrk1[i];
280  int t2i = layStubidsTrk2[i];
281  if (t1i != -1 && t2i != -1 && stubsTrk1[t1i].first == stubsTrk2[t2i].first &&
282  stubsTrk1[t1i].second == stubsTrk2[t2i].second)
283  nShareLay++;
284  }
285  }
286 
287  // Fill duplicate map
288  if (nShareLay >= settings_.minIndStubs()) { // For number of shared stub merge condition
289  dupMap[itrk][jtrk] = true;
290  dupMap[jtrk][itrk] = true;
291  }
292  }
293  }
294 
295  // Check to see if the track is a duplicate
296  for (unsigned int itrk = 0; itrk < numStublists; itrk++) {
297  for (unsigned int jtrk = 0; jtrk < numStublists; jtrk++) {
298  if (dupMap[itrk][jtrk]) {
299  noMerge[itrk] = true;
300  }
301  }
302  }
303 
304  // 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
305  for (unsigned int itrk = 0; itrk < numStublists; itrk++) {
306  if (noMerge[itrk] == false) {
307  if (((findOverlapRinvBins(inputtracklets_[itrk]).size() > 1) &&
308  (findRinvBin(inputtracklets_[itrk]) != bin)) ||
309  ((findOverlapPhiBins(inputtracklets_[itrk]).size() > 1) &&
310  findPhiBin(inputtracklets_[itrk]) != phiBin)) {
311  trackInfo[itrk].second = true;
312  }
313  }
314  }
315  // Merge duplicate tracks
316  for (unsigned int itrk = 0; itrk < numStublists - 1; itrk++) {
317  for (unsigned int jtrk = itrk + 1; jtrk < numStublists; jtrk++) {
318  // Merge a track with its first duplicate found.
319  if (dupMap[itrk][jtrk]) {
320  // Set preferred track based on seed rank
321  int preftrk;
322  int rejetrk;
323  if (seedRank[itrk] < seedRank[jtrk]) {
324  preftrk = itrk;
325  rejetrk = jtrk;
326  } else {
327  preftrk = jtrk;
328  rejetrk = itrk;
329  }
330 
331  // If the preffered track is in more than one bin, but not in the proper rinv or phi bin, then mark as true
332  if (((findOverlapRinvBins(inputtracklets_[preftrk]).size() > 1) &&
333  (findRinvBin(inputtracklets_[preftrk]) != bin)) ||
334  ((findOverlapPhiBins(inputtracklets_[preftrk]).size() > 1) &&
335  (findPhiBin(inputtracklets_[preftrk]) != phiBin))) {
336  trackBinInfo[preftrk] = true;
337  trackBinInfo[rejetrk] = true;
338  } else {
339  // Get a merged stub list
340  std::vector<const Stub*> newStubList;
341  std::vector<const Stub*> stubsTrk1 = inputstublists_[preftrk];
342  std::vector<const Stub*> stubsTrk2 = inputstublists_[rejetrk];
343  std::vector<unsigned int> stubsTrk1indices;
344  std::vector<unsigned int> stubsTrk2indices;
345  for (unsigned int stub1it = 0; stub1it < stubsTrk1.size(); stub1it++) {
346  stubsTrk1indices.push_back(stubsTrk1[stub1it]->l1tstub()->uniqueIndex());
347  }
348  for (unsigned int stub2it = 0; stub2it < stubsTrk2.size(); stub2it++) {
349  stubsTrk2indices.push_back(stubsTrk2[stub2it]->l1tstub()->uniqueIndex());
350  }
351  newStubList = stubsTrk1;
352  for (unsigned int stub2it = 0; stub2it < stubsTrk2.size(); stub2it++) {
353  if (find(stubsTrk1indices.begin(), stubsTrk1indices.end(), stubsTrk2indices[stub2it]) ==
354  stubsTrk1indices.end()) {
355  newStubList.push_back(stubsTrk2[stub2it]);
356  }
357  }
358  // Overwrite stublist of preferred track with merged list
359  inputstublists_[preftrk] = newStubList;
360 
361  std::vector<std::pair<int, int>> newStubidsList;
362  std::vector<std::pair<int, int>> stubidsTrk1 = mergedstubidslists_[preftrk];
363  std::vector<std::pair<int, int>> stubidsTrk2 = mergedstubidslists_[rejetrk];
364  newStubidsList = stubidsTrk1;
365 
366  for (unsigned int stub2it = 0; stub2it < stubsTrk2.size(); stub2it++) {
367  if (find(stubsTrk1indices.begin(), stubsTrk1indices.end(), stubsTrk2indices[stub2it]) ==
368  stubsTrk1indices.end()) {
369  newStubidsList.push_back(stubidsTrk2[stub2it]);
370  }
371  }
372  // Overwrite stubidslist of preferred track with merged list
373  mergedstubidslists_[preftrk] = newStubidsList;
374 
375  // Mark that rejected track has been merged into another track
376  trackInfo[rejetrk].second = true;
377  }
378  }
379  }
380  }
381 
382  for (unsigned int ktrk = 0; ktrk < numStublists; ktrk++) {
383  if ((trackInfo[ktrk].second != true) && (trackBinInfo[ktrk] != true)) {
384  prefTracks.push_back(ktrk);
385  prefTrackFit.push_back(trackInfo[ktrk].first);
386  inputtrackletsall.push_back(inputtracklets_[ktrk]);
387  inputstublistsall.push_back(inputstublists_[ktrk]);
388  inputstubidslistsall.push_back(inputstubidslists_[ktrk]);
389  mergedstubidslistsall.push_back(mergedstubidslists_[ktrk]);
390  }
391  }
392 
393  // Need to clear all the vectors which will be used in the next bin
394  seedRank.clear();
395  trackInfo.clear();
396  trackBinInfo.clear();
397  inputtracklets_.clear();
398  inputstublists_.clear();
399  inputstubidslists_.clear();
400  mergedstubidslists_.clear();
401  }
402  }
403 
404  // Make the final track objects, fit with KF, and send to output
405  for (unsigned int itrk = 0; itrk < prefTracks.size(); itrk++) {
406  Tracklet* tracklet = inputtrackletsall[itrk];
407  std::vector<const Stub*> trackstublist = inputstublistsall[itrk];
408 
409  // Run KF track fit
410  HybridFit hybridFitter(iSector, settings_, globals_);
411  hybridFitter.Fit(tracklet, trackstublist);
412 
413  // If the track was accepted (and thus fit), add to output
414  if (tracklet->fit()) {
415  // Add fitted Track to output (later converted to TTTrack)
416  Track* outtrack = tracklet->getTrack();
417  outtrack->setSector(iSector);
418  // Also store fitted track as more detailed Tracklet object.
419  outputtracklets_[prefTrackFit[itrk]]->addTrack(tracklet);
420 
421  // Add all tracks to standalone root file output
422  outtrack->setStubIDpremerge(inputstubidslistsall[itrk]);
423  outtrack->setStubIDprefit(mergedstubidslistsall[itrk]);
424  outputtracks.push_back(*outtrack);
425  }
426  }
427  }
428 
429 #endif
430 
432  // Grid removal //
434  if (settings_.removalType() == "grid") {
435  // Sort tracks by ichisq/DoF so that removal will keep the lower ichisq/DoF track
436  std::sort(inputtracks_.begin(), inputtracks_.end(), [](const Track* lhs, const Track* rhs) {
437  return lhs->ichisq() / lhs->stubID().size() < rhs->ichisq() / rhs->stubID().size();
438  });
439  bool grid[35][40] = {{false}};
440 
441  for (unsigned int itrk = 0; itrk < numTrk; itrk++) {
442  if (inputtracks_[itrk]->duplicate())
443  edm::LogPrint("Tracklet") << "WARNING: Track already tagged as duplicate!!";
444 
445  double phiBin = (inputtracks_[itrk]->phi0(settings_) - 2 * M_PI / 27 * iSector) / (2 * M_PI / 9 / 50) + 9;
446  phiBin = std::max(phiBin, 0.);
447  phiBin = std::min(phiBin, 34.);
448 
449  double ptBin = 1 / inputtracks_[itrk]->pt(settings_) * 40 + 20;
450  ptBin = std::max(ptBin, 0.);
451  ptBin = std::min(ptBin, 39.);
452 
453  if (grid[(int)phiBin][(int)ptBin])
454  inputtracks_[itrk]->setDuplicate(true);
455  grid[(int)phiBin][(int)ptBin] = true;
456 
457  double phiTest = inputtracks_[itrk]->phi0(settings_) - 2 * M_PI / 27 * iSector;
458  if (phiTest < -2 * M_PI / 27)
459  edm::LogVerbatim("Tracklet") << "track phi too small!";
460  if (phiTest > 2 * 2 * M_PI / 27)
461  edm::LogVerbatim("Tracklet") << "track phi too big!";
462  }
463  } // end grid removal
464 
466  // ichi + nstub removal //
468  if (settings_.removalType() == "ichi" || settings_.removalType() == "nstub") {
469  for (unsigned int itrk = 0; itrk < numTrk - 1; itrk++) { // numTrk-1 since last track has no other to compare to
470 
471  // If primary track is a duplicate, it cannot veto any...move on
472  if (inputtracks_[itrk]->duplicate() == 1)
473  continue;
474 
475  unsigned int nStubP = 0;
476  vector<unsigned int> nStubS(numTrk);
477  vector<unsigned int> nShare(numTrk);
478  // Get and count primary stubs
479  std::map<int, int> stubsTrk1 = inputtracks_[itrk]->stubID();
480  nStubP = stubsTrk1.size();
481 
482  for (unsigned int jtrk = itrk + 1; jtrk < numTrk; jtrk++) {
483  // Skip duplicate tracks
484  if (inputtracks_[jtrk]->duplicate() == 1)
485  continue;
486 
487  // Get and count secondary stubs
488  std::map<int, int> stubsTrk2 = inputtracks_[jtrk]->stubID();
489  nStubS[jtrk] = stubsTrk2.size();
490 
491  // Count shared stubs
492  for (auto& st : stubsTrk1) {
493  if (stubsTrk2.find(st.first) != stubsTrk2.end()) {
494  if (st.second == stubsTrk2[st.first])
495  nShare[jtrk]++;
496  }
497  }
498  }
499 
500  // Tag duplicates
501  for (unsigned int jtrk = itrk + 1; jtrk < numTrk; jtrk++) {
502  // Skip duplicate tracks
503  if (inputtracks_[jtrk]->duplicate() == 1)
504  continue;
505 
506  // Chi2 duplicate removal
507  if (settings_.removalType() == "ichi") {
508  if ((nStubP - nShare[jtrk] < settings_.minIndStubs()) ||
509  (nStubS[jtrk] - nShare[jtrk] < settings_.minIndStubs())) {
510  if ((int)inputtracks_[itrk]->ichisq() / (2 * inputtracks_[itrk]->stubID().size() - 4) >
511  (int)inputtracks_[jtrk]->ichisq() / (2 * inputtracks_[itrk]->stubID().size() - 4)) {
512  inputtracks_[itrk]->setDuplicate(true);
513  } else if ((int)inputtracks_[itrk]->ichisq() / (2 * inputtracks_[itrk]->stubID().size() - 4) <=
514  (int)inputtracks_[jtrk]->ichisq() / (2 * inputtracks_[itrk]->stubID().size() - 4)) {
515  inputtracks_[jtrk]->setDuplicate(true);
516  } else {
517  edm::LogVerbatim("Tracklet") << "Error: Didn't tag either track in duplicate pair.";
518  }
519  }
520  } // end ichi removal
521 
522  // nStub duplicate removal
523  if (settings_.removalType() == "nstub") {
524  if ((nStubP - nShare[jtrk] < settings_.minIndStubs()) && (nStubP < nStubS[jtrk])) {
525  inputtracks_[itrk]->setDuplicate(true);
526  } else if ((nStubS[jtrk] - nShare[jtrk] < settings_.minIndStubs()) && (nStubS[jtrk] <= nStubP)) {
527  inputtracks_[jtrk]->setDuplicate(true);
528  } else {
529  edm::LogVerbatim("Tracklet") << "Error: Didn't tag either track in duplicate pair.";
530  }
531  } // end nstub removal
532 
533  } // end tag duplicates
534 
535  } // end loop over primary track
536 
537  } // end ichi + nstub removal
538 
539  //Add tracks to output
540  if (settings_.removalType() != "merge") {
541  for (unsigned int i = 0; i < inputtrackfits_.size(); i++) {
542  for (unsigned int j = 0; j < inputtrackfits_[i]->nTracks(); j++) {
543  if (inputtrackfits_[i]->getTrack(j)->getTrack()->duplicate() == 0) {
544  if (settings_.writeMonitorData("Seeds")) {
545  ofstream fout("seeds.txt", ofstream::app);
546  fout << __FILE__ << ":" << __LINE__ << " " << name_ << "_" << iSector << " "
547  << inputtrackfits_[i]->getTrack(j)->getISeed() << endl;
548  fout.close();
549  }
550  outputtracklets_[i]->addTrack(inputtrackfits_[i]->getTrack(j));
551  }
552  //For root file:
553  outputtracks.push_back(*inputtrackfits_[i]->getTrack(j)->getTrack());
554  }
555  }
556  }
557 }
558 
559 double PurgeDuplicate::getPhiRes(Tracklet* curTracklet, const Stub* curStub) const {
560  double phiproj;
561  double stubphi;
562  double phires;
563  // Get phi position of stub
564  stubphi = curStub->l1tstub()->phi();
565  // Get layer that the stub is in (Layer 1->6, Disk 1->5)
566  int Layer = curStub->layerdisk() + 1;
567  if (Layer > N_LAYER) {
568  Layer = 0;
569  }
570  int Disk = curStub->layerdisk() - (N_LAYER - 1);
571  if (Disk < 0) {
572  Disk = 0;
573  }
574  // Get phi projection of tracklet
575  int seedindex = curTracklet->seedIndex();
576  // If this stub is a seed stub, set projection=phi, so that res=0
577  if (isSeedingStub(seedindex, Layer, Disk)) {
578  phiproj = stubphi;
579  // Otherwise, get projection of tracklet
580  } else {
581  phiproj = curTracklet->proj(curStub->layerdisk()).phiproj();
582  }
583  // Calculate residual
584  phires = std::abs(stubphi - phiproj);
585  return phires;
586 }
587 
588 bool PurgeDuplicate::isSeedingStub(int seedindex, int Layer, int Disk) const {
589  if ((seedindex == 0 && (Layer == 1 || Layer == 2)) || (seedindex == 1 && (Layer == 2 || Layer == 3)) ||
590  (seedindex == 2 && (Layer == 3 || Layer == 4)) || (seedindex == 3 && (Layer == 5 || Layer == 6)) ||
591  (seedindex == 4 && (abs(Disk) == 1 || abs(Disk) == 2)) ||
592  (seedindex == 5 && (abs(Disk) == 3 || abs(Disk) == 4)) || (seedindex == 6 && (Layer == 1 || abs(Disk) == 1)) ||
593  (seedindex == 7 && (Layer == 2 || abs(Disk) == 1)) ||
594  (seedindex == 8 && (Layer == 2 || Layer == 3 || Layer == 4)) ||
595  (seedindex == 9 && (Layer == 4 || Layer == 5 || Layer == 6)) ||
596  (seedindex == 10 && (Layer == 2 || Layer == 3 || abs(Disk) == 1)) ||
597  (seedindex == 11 && (Layer == 2 || abs(Disk) == 1 || abs(Disk) == 2)))
598  return true;
599 
600  return false;
601 }
602 
603 std::pair<int, int> PurgeDuplicate::findLayerDisk(const Stub* st) const {
604  std::pair<int, int> layer_disk;
605  layer_disk.first = st->layerdisk() + 1;
606  if (layer_disk.first > N_LAYER) {
607  layer_disk.first = 0;
608  }
609  layer_disk.second = st->layerdisk() - (N_LAYER - 1);
610  if (layer_disk.second < 0) {
611  layer_disk.second = 0;
612  }
613  return layer_disk;
614 }
615 
617  std::string thestr = Form("\t %s stub info: r/z/phi:\t%f\t%f\t%f\t%d\t%f\t%d",
618  str.c_str(),
619  l1stub->r(),
620  l1stub->z(),
621  l1stub->phi(),
622  l1stub->iphi(),
623  l1stub->bend(),
624  l1stub->layerdisk());
625  return thestr;
626 }
627 
628 std::vector<double> PurgeDuplicate::getInventedCoords(unsigned int iSector,
629  const Stub* st,
630  const Tracklet* tracklet) const {
631  int stubLayer = (findLayerDisk(st)).first;
632  int stubDisk = (findLayerDisk(st)).second;
633 
634  double stub_phi = -99;
635  double stub_z = -99;
636  double stub_r = -99;
637 
638  double tracklet_rinv = tracklet->rinv();
639 
640  if (st->isBarrel()) {
641  stub_r = settings_.rmean(stubLayer - 1);
642  stub_phi = tracklet->phi0() - std::asin(stub_r * tracklet_rinv / 2);
643  stub_phi = stub_phi + iSector * settings_.dphisector() - 0.5 * settings_.dphisectorHG();
644  stub_phi = reco::reduceRange(stub_phi);
645  stub_z = tracklet->z0() + 2 * tracklet->t() * 1 / tracklet_rinv * std::asin(stub_r * tracklet_rinv / 2);
646  } else {
647  stub_z = settings_.zmean(stubDisk - 1) * tracklet->disk() / abs(tracklet->disk());
648  stub_phi = tracklet->phi0() - (stub_z - tracklet->z0()) * tracklet_rinv / 2 / tracklet->t();
649  stub_phi = stub_phi + iSector * settings_.dphisector() - 0.5 * settings_.dphisectorHG();
650  stub_phi = reco::reduceRange(stub_phi);
651  stub_r = 2 / tracklet_rinv * std::sin((stub_z - tracklet->z0()) * tracklet_rinv / 2 / tracklet->t());
652  }
653 
654  std::vector<double> invented_coords{stub_r, stub_z, stub_phi};
655  return invented_coords;
656 }
657 
658 std::vector<double> PurgeDuplicate::getInventedCoordsExtended(unsigned int iSector,
659  const Stub* st,
660  const Tracklet* tracklet) const {
661  int stubLayer = (findLayerDisk(st)).first;
662  int stubDisk = (findLayerDisk(st)).second;
663 
664  double stub_phi = -99;
665  double stub_z = -99;
666  double stub_r = -99;
667 
668  double rho = 1 / tracklet->rinv();
669  double rho_minus_d0 = rho + tracklet->d0(); // should be -, but otherwise does not work
670 
671  // exact helix
672  if (st->isBarrel()) {
673  stub_r = settings_.rmean(stubLayer - 1);
674 
675  double sin_val = (stub_r * stub_r + rho_minus_d0 * rho_minus_d0 - rho * rho) / (2 * stub_r * rho_minus_d0);
676  stub_phi = tracklet->phi0() - std::asin(sin_val);
677  stub_phi = stub_phi + iSector * settings_.dphisector() - 0.5 * settings_.dphisectorHG();
678  stub_phi = reco::reduceRange(stub_phi);
679 
680  double beta = std::acos((rho * rho + rho_minus_d0 * rho_minus_d0 - stub_r * stub_r) / (2 * rho * rho_minus_d0));
681  stub_z = tracklet->z0() + tracklet->t() * std::abs(rho * beta);
682  } else {
683  stub_z = settings_.zmean(stubDisk - 1) * tracklet->disk() / abs(tracklet->disk());
684 
685  double beta = (stub_z - tracklet->z0()) / (tracklet->t() * std::abs(rho)); // maybe rho should be abs value
686  double r_square = -2 * rho * rho_minus_d0 * std::cos(beta) + rho * rho + rho_minus_d0 * rho_minus_d0;
687  stub_r = sqrt(r_square);
688 
689  double sin_val = (stub_r * stub_r + rho_minus_d0 * rho_minus_d0 - rho * rho) / (2 * stub_r * rho_minus_d0);
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 
695  // TMP: for displaced tracking, exclude one of the 3 seeding stubs
696  // to be discussed
697  int seed = tracklet->seedIndex();
698  if ((seed == 8 && stubLayer == 4) || (seed == 9 && stubLayer == 5) || (seed == 10 && stubLayer == 3) ||
699  (seed == 11 && abs(stubDisk) == 1)) {
700  stub_phi = st->l1tstub()->phi();
701  stub_z = st->l1tstub()->z();
702  stub_r = st->l1tstub()->r();
703  }
704 
705  std::vector<double> invented_coords{stub_r, stub_z, stub_phi};
706  return invented_coords;
707 }
708 
709 std::vector<const Stub*> PurgeDuplicate::getInventedSeedingStub(
710  unsigned int iSector, const Tracklet* tracklet, const std::vector<const Stub*>& originalStubsList) const {
711  std::vector<const Stub*> newStubList;
712 
713  for (unsigned int stubit = 0; stubit < originalStubsList.size(); stubit++) {
714  const Stub* thisStub = originalStubsList[stubit];
715 
716  if (isSeedingStub(tracklet->seedIndex(), (findLayerDisk(thisStub)).first, (findLayerDisk(thisStub)).second)) {
717  // get a vector containing r, z, phi
718  std::vector<double> inv_r_z_phi;
719  if (!settings_.extended())
720  inv_r_z_phi = getInventedCoords(iSector, thisStub, tracklet);
721  else {
722  inv_r_z_phi = getInventedCoordsExtended(iSector, thisStub, tracklet);
723  }
724  double stub_x_invent = inv_r_z_phi[0] * std::cos(inv_r_z_phi[2]);
725  double stub_y_invent = inv_r_z_phi[0] * std::sin(inv_r_z_phi[2]);
726  double stub_z_invent = inv_r_z_phi[1];
727 
728  Stub* invent_stub_ptr = new Stub(*thisStub);
729  const L1TStub* l1stub = thisStub->l1tstub();
730  L1TStub invent_l1stub = *l1stub;
731  invent_l1stub.setCoords(stub_x_invent, stub_y_invent, stub_z_invent);
732 
733  invent_stub_ptr->setl1tstub(new L1TStub(invent_l1stub));
734  invent_stub_ptr->l1tstub()->setAllStubIndex(l1stub->allStubIndex());
735  invent_stub_ptr->l1tstub()->setUniqueIndex(l1stub->uniqueIndex());
736 
737  newStubList.push_back(invent_stub_ptr);
738 
739  } else {
740  newStubList.push_back(thisStub);
741  }
742  }
743  return newStubList;
744 }
745 
746 // Tells us the variable bin to which a track would belong
747 unsigned int PurgeDuplicate::findRinvBin(const Tracklet* trk) const {
748  std::vector<double> rinvBins = settings_.rinvBins();
749 
750  //Get rinverse of track
751  double rinv = trk->rinv();
752 
753  //Check between what 2 values in rinvbins rinv is between
754  auto bins = std::upper_bound(rinvBins.begin(), rinvBins.end(), rinv);
755 
756  //return integer for bin index
757  unsigned int rIndx = std::distance(rinvBins.begin(), bins);
758  if (rIndx == std::distance(rinvBins.end(), bins))
759  return rinvBins.size() - 2;
760  else if (bins == rinvBins.begin())
761  return std::distance(rinvBins.begin(), bins);
762  else
763  return rIndx - 1;
764 }
765 
766 // Tells us the phi bin to which a track would belong
767 unsigned int PurgeDuplicate::findPhiBin(const Tracklet* trk) const {
768  std::vector<double> phiBins = settings_.phiBins();
769 
770  //Get phi of track at rcrit
771  double phi0 = trk->phi0();
772  double rcrit = settings_.rcrit();
773  double rinv = trk->rinv();
774  double phi = phi0 - asin(0.5 * rinv * rcrit);
775 
776  //Check between what 2 values in phibins phi is between
777  auto bins = std::upper_bound(phiBins.begin(), phiBins.end(), phi);
778 
779  //return integer for bin index
780  unsigned int phiIndx = std::distance(phiBins.begin(), bins);
781  if (phiIndx == std::distance(phiBins.end(), bins))
782  return phiBins.size() - 2;
783  else if (bins == phiBins.begin())
784  return std::distance(phiBins.begin(), bins);
785  else
786  return phiIndx - 1;
787 }
788 
789 // Tells us the overlap rinv bin(s) to which a track belongs
790 std::vector<unsigned int> PurgeDuplicate::findOverlapRinvBins(const Tracklet* trk) const {
791  double rinv = trk->rinv();
792 
793  const double rinvOverlapSize = settings_.rinvOverlapSize();
794  const std::vector<double>& rinvBins = settings_.rinvBins();
795 
796  std::vector<unsigned int> chosenBins;
797  for (long unsigned int i = 0; i < rinvBins.size() - 1; i++) {
798  if ((rinv < rinvBins[i + 1] + rinvOverlapSize) && (rinv > rinvBins[i] - rinvOverlapSize)) {
799  chosenBins.push_back(i);
800  }
801  }
802  return chosenBins;
803 }
804 
805 // Tells us the overlap phi bin(s) to which a track belongs
806 std::vector<unsigned int> PurgeDuplicate::findOverlapPhiBins(const Tracklet* trk) const {
807  double phi0 = trk->phi0();
808  double rcrit = settings_.rcrit();
809  double rinv = trk->rinv();
810  double phi = phi0 - asin(0.5 * rinv * rcrit);
811 
812  const double phiOverlapSize = settings_.phiOverlapSize();
813  const std::vector<double>& phiBins = settings_.phiBins();
814 
815  std::vector<unsigned int> chosenBins;
816  for (long unsigned int i = 0; i < phiBins.size() - 1; i++) {
817  if ((phi < phiBins[i + 1] + phiOverlapSize) && (phi > phiBins[i] - phiOverlapSize)) {
818  chosenBins.push_back(i);
819  }
820  }
821  return chosenBins;
822 }
823 
824 // Tells us if a track is in the current bin
825 bool PurgeDuplicate::isTrackInBin(const std::vector<unsigned int>& vec, unsigned int num) const {
826  auto result = std::find(vec.begin(), vec.end(), num);
827  bool found = (result != vec.end());
828  return found;
829 }
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: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: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