CMS 3D CMS Logo

VertexFinder.cc
Go to the documentation of this file.
2 
3 using namespace std;
4 
5 namespace l1tVertexFinder {
6 
7  void VertexFinder::computeAndSetVertexParameters(RecoVertex<>& vertex,
8  const std::vector<float>& bin_centers,
9  const std::vector<unsigned int>& counts) {
10  double pt = 0.;
11  double z0 = -999.;
12  double z0width = 0.;
13  bool highPt = false;
14  double highestPt = 0.;
15  unsigned int numHighPtTracks = 0;
16 
17  float SumZ = 0.;
18  float z0square = 0.;
19  float trackPt = 0.;
20 
21  std::vector<double> bin_pt(bin_centers.size(), 0.0);
22  unsigned int ibin = 0;
23  unsigned int itrack = 0;
24 
25  for (const L1Track* track : vertex.tracks()) {
26  itrack++;
27  trackPt = track->pt();
28 
29  // Skip the bins with no tracks
30  while (ibin < counts.size() && counts[ibin] == 0)
31  ibin++;
32 
33  if (trackPt > settings_->vx_TrackMaxPt()) {
34  highPt = true;
35  numHighPtTracks++;
36  highestPt = (trackPt > highestPt) ? trackPt : highestPt;
37  if (settings_->vx_TrackMaxPtBehavior() == 0)
38  continue; // ignore this track
39  else if (settings_->vx_TrackMaxPtBehavior() == 1)
40  trackPt = settings_->vx_TrackMaxPt(); // saturate
41  }
42 
43  pt += std::pow(trackPt, settings_->vx_weightedmean());
44  if (bin_centers.empty() && counts.empty()) {
45  SumZ += track->z0() * std::pow(trackPt, settings_->vx_weightedmean());
46  z0square += track->z0() * track->z0();
47  } else {
48  bin_pt[ibin] += std::pow(trackPt, settings_->vx_weightedmean());
49  if (itrack == counts[ibin]) {
50  SumZ += bin_centers[ibin] * bin_pt[ibin];
51  z0square += bin_centers[ibin] * bin_centers[ibin];
52  itrack = 0;
53  ibin++;
54  }
55  }
56  }
57 
58  z0 = SumZ / ((settings_->vx_weightedmean() > 0) ? pt : vertex.numTracks());
59  z0square /= vertex.numTracks();
60  z0width = sqrt(std::abs(z0 * z0 - z0square));
61 
62  vertex.setParameters(pt, z0, z0width, highPt, numHighPtTracks, highestPt);
63  }
64 
65  void VertexFinder::GapClustering() {
66  sort(fitTracks_.begin(), fitTracks_.end(), SortTracksByZ0());
67  iterations_ = 0;
69  for (unsigned int i = 0; i < fitTracks_.size(); ++i) {
70  Vertex.insert(&fitTracks_[i]);
71  iterations_++;
72  if ((i + 1 < fitTracks_.size() and fitTracks_[i + 1].z0() - fitTracks_[i].z0() > settings_->vx_distance()) or
73  i == fitTracks_.size() - 1) {
74  if (Vertex.numTracks() >= settings_->vx_minTracks()) {
75  computeAndSetVertexParameters(Vertex, {}, {});
76  vertices_.push_back(Vertex);
77  }
78  Vertex.clear();
79  }
80  }
81  }
82 
84  float distance = 0;
85  for (const L1Track* track0 : cluster0.tracks()) {
86  for (const L1Track* track1 : cluster1.tracks()) {
87  if (std::abs(track0->z0() - track1->z0()) > distance) {
88  distance = std::abs(track0->z0() - track1->z0());
89  }
90  }
91  }
92 
93  return distance;
94  }
95 
96  float VertexFinder::minDistance(RecoVertex<> cluster0, RecoVertex<> cluster1) {
97  float distance = 9999;
98  for (const L1Track* track0 : cluster0.tracks()) {
99  for (const L1Track* track1 : cluster1.tracks()) {
100  if (std::abs(track0->z0() - track1->z0()) < distance) {
101  distance = std::abs(track0->z0() - track1->z0());
102  }
103  }
104  }
105 
106  return distance;
107  }
108 
109  float VertexFinder::meanDistance(RecoVertex<> cluster0, RecoVertex<> cluster1) {
110  float distanceSum = 0;
111 
112  for (const L1Track* track0 : cluster0.tracks()) {
113  for (const L1Track* track1 : cluster1.tracks()) {
114  distanceSum += std::abs(track0->z0() - track1->z0());
115  }
116  }
117 
118  float distance = distanceSum / (cluster0.numTracks() * cluster1.numTracks());
119  return distance;
120  }
121 
122  float VertexFinder::centralDistance(RecoVertex<> cluster0, RecoVertex<> cluster1) {
123  computeAndSetVertexParameters(cluster0, {}, {});
124  computeAndSetVertexParameters(cluster1, {}, {});
125  float distance = std::abs(cluster0.z0() - cluster1.z0());
126  return distance;
127  }
128 
129  void VertexFinder::agglomerativeHierarchicalClustering() {
130  iterations_ = 0;
131 
132  sort(fitTracks_.begin(), fitTracks_.end(), SortTracksByZ0());
133 
134  RecoVertexCollection vClusters;
135  vClusters.resize(fitTracks_.size());
136 
137  for (unsigned int i = 0; i < fitTracks_.size(); ++i) {
138  vClusters[i].insert(&fitTracks_[i]);
139  // iterations_++;
140  }
141 
142  while (true) {
143  float MinimumScore = 9999;
144 
145  unsigned int clusterId0 = 0;
146  unsigned int clusterId1 = 0;
147  for (unsigned int iClust = 0; iClust < vClusters.size() - 1; iClust++) {
148  iterations_++;
149 
150  float M = 0;
151  if (settings_->vx_distanceType() == 0)
152  M = maxDistance(vClusters[iClust], vClusters[iClust + 1]);
153  else if (settings_->vx_distanceType() == 1)
154  M = minDistance(vClusters[iClust], vClusters[iClust + 1]);
155  else if (settings_->vx_distanceType() == 2)
156  M = meanDistance(vClusters[iClust], vClusters[iClust + 1]);
157  else
158  M = centralDistance(vClusters[iClust], vClusters[iClust + 1]);
159 
160  if (M < MinimumScore) {
161  MinimumScore = M;
162  clusterId0 = iClust;
163  clusterId1 = iClust + 1;
164  }
165  }
166  if (MinimumScore > settings_->vx_distance() or vClusters[clusterId1].tracks().empty())
167  break;
168  for (const L1Track* track : vClusters[clusterId0].tracks()) {
169  vClusters[clusterId1].insert(track);
170  }
171  vClusters.erase(vClusters.begin() + clusterId0);
172  }
173 
174  for (RecoVertex clust : vClusters) {
175  if (clust.numTracks() >= settings_->vx_minTracks()) {
176  computeAndSetVertexParameters(clust, {}, {});
177  vertices_.push_back(clust);
178  }
179  }
180  }
181 
182  void VertexFinder::DBSCAN() {
183  // std::vector<RecoVertex> vClusters;
184  std::vector<unsigned int> visited;
185  std::vector<unsigned int> saved;
186 
187  sort(fitTracks_.begin(), fitTracks_.end(), SortTracksByPt());
188  iterations_ = 0;
189 
190  for (unsigned int i = 0; i < fitTracks_.size(); ++i) {
191  if (find(visited.begin(), visited.end(), i) != visited.end())
192  continue;
193 
194  // if(fitTracks_[i]->pt()>10.){
195  visited.push_back(i);
196  std::set<unsigned int> neighbourTrackIds;
197  unsigned int numDensityTracks = 0;
198  if (fitTracks_[i].pt() > settings_->vx_dbscan_pt())
199  numDensityTracks++;
200  else
201  continue;
202  for (unsigned int k = 0; k < fitTracks_.size(); ++k) {
203  iterations_++;
204  if (k != i and std::abs(fitTracks_[k].z0() - fitTracks_[i].z0()) < settings_->vx_distance()) {
205  neighbourTrackIds.insert(k);
206  if (fitTracks_[k].pt() > settings_->vx_dbscan_pt()) {
207  numDensityTracks++;
208  }
209  }
210  }
211 
212  if (numDensityTracks < settings_->vx_dbscan_mintracks()) {
213  // mark track as noise
214  } else {
216  vertex.insert(&fitTracks_[i]);
217  saved.push_back(i);
218  for (unsigned int id : neighbourTrackIds) {
219  if (find(visited.begin(), visited.end(), id) == visited.end()) {
220  visited.push_back(id);
221  std::vector<unsigned int> neighbourTrackIds2;
222  for (unsigned int k = 0; k < fitTracks_.size(); ++k) {
223  iterations_++;
224  if (std::abs(fitTracks_[k].z0() - fitTracks_[id].z0()) < settings_->vx_distance()) {
225  neighbourTrackIds2.push_back(k);
226  }
227  }
228 
229  // if (neighbourTrackIds2.size() >= settings_->vx_minTracks()) {
230  for (unsigned int id2 : neighbourTrackIds2) {
231  neighbourTrackIds.insert(id2);
232  }
233  // }
234  }
235  if (find(saved.begin(), saved.end(), id) == saved.end())
236  vertex.insert(&fitTracks_[id]);
237  }
238  computeAndSetVertexParameters(vertex, {}, {});
239  if (vertex.numTracks() >= settings_->vx_minTracks())
240  vertices_.push_back(vertex);
241  }
242  // }
243  }
244  }
245 
246  void VertexFinder::PVR() {
247  bool start = true;
248  FitTrackCollection discardedTracks, acceptedTracks;
249  iterations_ = 0;
250  for (const L1Track& track : fitTracks_) {
251  acceptedTracks.push_back(track);
252  }
253 
254  while (discardedTracks.size() >= settings_->vx_minTracks() or start == true) {
255  start = false;
256  bool removing = true;
257  discardedTracks.clear();
258  while (removing) {
259  float oldDistance = 0.;
260 
261  if (settings_->debug() > 2)
262  edm::LogInfo("VertexFinder") << "PVR::AcceptedTracks " << acceptedTracks.size();
263 
264  float z0start = 0;
265  for (const L1Track& track : acceptedTracks) {
266  z0start += track.z0();
267  iterations_++;
268  }
269 
270  z0start /= acceptedTracks.size();
271  if (settings_->debug() > 2)
272  edm::LogInfo("VertexFinder") << "PVR::z0 vertex " << z0start;
273  FitTrackCollection::iterator badTrackIt = acceptedTracks.end();
274  removing = false;
275 
276  for (FitTrackCollection::iterator it = acceptedTracks.begin(); it < acceptedTracks.end(); ++it) {
277  const L1Track* track = &*it;
278  iterations_++;
279  if (std::abs(track->z0() - z0start) > settings_->vx_distance() and
280  std::abs(track->z0() - z0start) > oldDistance) {
281  badTrackIt = it;
282  oldDistance = std::abs(track->z0() - z0start);
283  removing = true;
284  }
285  }
286 
287  if (removing) {
288  const L1Track badTrack = *badTrackIt;
289  if (settings_->debug() > 2)
290  edm::LogInfo("VertexFinder") << "PVR::Removing track " << badTrack.z0() << " at distance " << oldDistance;
291  discardedTracks.push_back(badTrack);
292  acceptedTracks.erase(badTrackIt);
293  }
294  }
295 
296  if (acceptedTracks.size() >= settings_->vx_minTracks()) {
298  for (const L1Track& track : acceptedTracks) {
299  vertex.insert(&track);
300  }
301  computeAndSetVertexParameters(vertex, {}, {});
302  vertices_.push_back(vertex);
303  }
304  if (settings_->debug() > 2)
305  edm::LogInfo("VertexFinder") << "PVR::DiscardedTracks size " << discardedTracks.size();
306  acceptedTracks.clear();
307  acceptedTracks = discardedTracks;
308  }
309  }
310 
311  void VertexFinder::adaptiveVertexReconstruction() {
312  bool start = true;
313  iterations_ = 0;
314  FitTrackCollection discardedTracks, acceptedTracks, discardedTracks2;
315 
316  for (const L1Track& track : fitTracks_) {
317  discardedTracks.push_back(track);
318  }
319 
320  while (discardedTracks.size() >= settings_->vx_minTracks() or start == true) {
321  start = false;
322  discardedTracks2.clear();
323  FitTrackCollection::iterator it = discardedTracks.begin();
324  const L1Track track = *it;
325  acceptedTracks.push_back(track);
326  float z0sum = track.z0();
327 
328  for (FitTrackCollection::iterator it2 = discardedTracks.begin(); it2 < discardedTracks.end(); ++it2) {
329  if (it2 != it) {
330  const L1Track secondTrack = *it2;
331  // Calculate new vertex z0 adding this track
332  z0sum += secondTrack.z0();
333  float z0vertex = z0sum / (acceptedTracks.size() + 1);
334  // Calculate chi2 of new vertex
335  float chi2 = 0.;
336  float dof = 0.;
337  for (const L1Track& accTrack : acceptedTracks) {
338  iterations_++;
339  float Residual = accTrack.z0() - z0vertex;
340  if (std::abs(accTrack.eta()) < 1.2)
341  Residual /= 0.1812; // Assumed z0 resolution
342  else if (std::abs(accTrack.eta()) >= 1.2 && std::abs(accTrack.eta()) < 1.6)
343  Residual /= 0.2912;
344  else if (std::abs(accTrack.eta()) >= 1.6 && std::abs(accTrack.eta()) < 2.)
345  Residual /= 0.4628;
346  else
347  Residual /= 0.65;
348 
349  chi2 += Residual * Residual;
350  dof = (acceptedTracks.size() + 1) * 2 - 1;
351  }
352  if (chi2 / dof < settings_->vx_chi2cut()) {
353  acceptedTracks.push_back(secondTrack);
354  } else {
355  discardedTracks2.push_back(secondTrack);
356  z0sum -= secondTrack.z0();
357  }
358  }
359  }
360 
361  if (acceptedTracks.size() >= settings_->vx_minTracks()) {
363  for (const L1Track& track : acceptedTracks) {
364  vertex.insert(&track);
365  }
366  computeAndSetVertexParameters(vertex, {}, {});
367  vertices_.push_back(vertex);
368  }
369 
370  acceptedTracks.clear();
371  discardedTracks.clear();
372  discardedTracks = discardedTracks2;
373  }
374  }
375 
376  void VertexFinder::HPV() {
377  iterations_ = 0;
378  sort(fitTracks_.begin(), fitTracks_.end(), SortTracksByPt());
379 
381  bool first = true;
382  float z = 99.;
383  for (const L1Track& track : fitTracks_) {
384  if (track.pt() < 50.) {
385  if (first) {
386  first = false;
387  z = track.z0();
388  vertex.insert(&track);
389  } else {
390  if (std::abs(track.z0() - z) < settings_->vx_distance())
391  vertex.insert(&track);
392  }
393  }
394  }
395 
396  computeAndSetVertexParameters(vertex, {}, {});
397  vertex.setZ0(z);
398  vertices_.push_back(vertex);
399  }
400 
401  void VertexFinder::Kmeans() {
402  unsigned int NumberOfClusters = settings_->vx_kmeans_nclusters();
403 
404  vertices_.resize(NumberOfClusters);
405  float ClusterSeparation = 30. / NumberOfClusters;
406 
407  for (unsigned int i = 0; i < NumberOfClusters; ++i) {
408  float ClusterCentre = -15. + ClusterSeparation * (i + 0.5);
409  vertices_[i].setZ0(ClusterCentre);
410  }
411  unsigned int iterations = 0;
412  // Initialise Clusters
413  while (iterations < settings_->vx_kmeans_iterations()) {
414  for (unsigned int i = 0; i < NumberOfClusters; ++i) {
415  vertices_[i].clear();
416  }
417 
418  for (const L1Track& track : fitTracks_) {
419  float distance = 9999;
420  if (iterations == settings_->vx_kmeans_iterations() - 3)
421  distance = settings_->vx_distance() * 2;
422  if (iterations > settings_->vx_kmeans_iterations() - 3)
423  distance = settings_->vx_distance();
424  unsigned int ClusterId;
425  bool NA = true;
426  for (unsigned int id = 0; id < NumberOfClusters; ++id) {
427  if (std::abs(track.z0() - vertices_[id].z0()) < distance) {
428  distance = std::abs(track.z0() - vertices_[id].z0());
429  ClusterId = id;
430  NA = false;
431  }
432  }
433  if (!NA) {
434  vertices_[ClusterId].insert(&track);
435  }
436  }
437  for (unsigned int i = 0; i < NumberOfClusters; ++i) {
438  if (vertices_[i].numTracks() >= settings_->vx_minTracks())
439  computeAndSetVertexParameters(vertices_[i], {}, {});
440  }
441  iterations++;
442  }
443  }
444 
445  void VertexFinder::findPrimaryVertex() {
446  if (settings_->vx_precision() == Precision::Emulation) {
447  pv_index_ = std::distance(verticesEmulation_.begin(),
448  std::max_element(verticesEmulation_.begin(),
449  verticesEmulation_.end(),
450  [](const l1t::VertexWord& vertex0, const l1t::VertexWord& vertex1) {
451  return (vertex0.pt() < vertex1.pt());
452  }));
453  } else {
454  pv_index_ = std::distance(
455  vertices_.begin(),
456  std::max_element(
457  vertices_.begin(), vertices_.end(), [](const RecoVertex<>& vertex0, const RecoVertex<>& vertex1) {
458  return (vertex0.pt() < vertex1.pt());
459  }));
460  }
461  }
462 
463  // Possible Formatting Codes: https://misc.flogisoft.com/bash/tip_colors_and_formatting
464  template <class data_type, typename stream_type>
465  void VertexFinder::printHistogram(stream_type& stream,
466  std::vector<data_type> data,
467  int width,
468  int minimum,
469  int maximum,
471  std::string color) {
472  int tableSize = data.size();
473 
474  if (maximum == -1) {
475  maximum = float(*std::max_element(std::begin(data), std::end(data))) * 1.05;
476  } else if (maximum <= minimum) {
477  maximum = float(*std::max_element(std::begin(data), std::end(data))) * 1.05;
478  minimum = float(*std::min_element(std::begin(data), std::end(data)));
479  }
480 
481  if (minimum < 0) {
482  minimum *= 1.05;
483  } else {
484  minimum = 0;
485  }
486 
487  std::vector<std::string> intervals(tableSize, "");
488  std::vector<std::string> values(tableSize, "");
489  char buffer[128];
490  int intervalswidth = 0, valueswidth = 0, tmpwidth = 0;
491  for (int i = 0; i < tableSize; i++) {
492  //Format the bin labels
493  tmpwidth = sprintf(buffer, "[%-.5g, %-.5g)", float(i), float(i + 1));
494  intervals[i] = buffer;
495  if (i == (tableSize - 1)) {
496  intervals[i][intervals[i].size() - 1] = ']';
497  }
498  if (tmpwidth > intervalswidth)
499  intervalswidth = tmpwidth;
500 
501  //Format the values
502  tmpwidth = sprintf(buffer, "%-.5g", float(data[i]));
503  values[i] = buffer;
504  if (tmpwidth > valueswidth)
505  valueswidth = tmpwidth;
506  }
507 
508  sprintf(buffer, "%-.5g", float(minimum));
509  std::string minimumtext = buffer;
510  sprintf(buffer, "%-.5g", float(maximum));
511  std::string maximumtext = buffer;
512 
513  int plotwidth =
514  std::max(int(minimumtext.size() + maximumtext.size()), width - (intervalswidth + 1 + valueswidth + 1 + 2));
516  minimumtext + std::string(plotwidth + 2 - minimumtext.size() - maximumtext.size(), ' ') + maximumtext;
517 
518  float norm = float(plotwidth) / float(maximum - minimum);
519  int zero = std::round((0.0 - minimum) * norm);
520  std::vector<char> line(plotwidth, '-');
521 
522  if ((minimum != 0) && (0 <= zero) && (zero < plotwidth)) {
523  line[zero] = '+';
524  }
525  std::string capstone =
526  std::string(intervalswidth + 1 + valueswidth + 1, ' ') + "+" + std::string(line.begin(), line.end()) + "+";
527 
528  std::vector<std::string> out;
529  if (!title.empty()) {
530  out.push_back(title);
531  out.push_back(std::string(title.size(), '='));
532  }
533  out.push_back(std::string(intervalswidth + valueswidth + 2, ' ') + scale);
534  out.push_back(capstone);
535  for (int i = 0; i < tableSize; i++) {
536  std::string interval = intervals[i];
538  data_type x = data[i];
539  std::fill_n(line.begin(), plotwidth, ' ');
540 
541  int pos = std::round((float(x) - minimum) * norm);
542  if (x < 0) {
543  std::fill_n(line.begin() + pos, zero - pos, '*');
544  } else {
545  std::fill_n(line.begin() + zero, pos - zero, '*');
546  }
547 
548  if ((minimum != 0) && (0 <= zero) && (zero < plotwidth)) {
549  line[zero] = '|';
550  }
551 
552  sprintf(buffer,
553  "%-*s %-*s |%s|",
554  intervalswidth,
555  interval.c_str(),
556  valueswidth,
557  value.c_str(),
558  std::string(line.begin(), line.end()).c_str());
559  out.push_back(buffer);
560  }
561  out.push_back(capstone);
562  if (!color.empty())
563  stream << color;
564  for (const auto& o : out) {
565  stream << o << "\n";
566  }
567  if (!color.empty())
568  stream << "\e[0m";
569  stream << "\n";
570  }
571 
572  void VertexFinder::sortVerticesInPt() {
573  if (settings_->vx_precision() == Precision::Emulation) {
574  std::sort(
575  verticesEmulation_.begin(),
576  verticesEmulation_.end(),
577  [](const l1t::VertexWord& vertex0, const l1t::VertexWord& vertex1) { return (vertex0.pt() > vertex1.pt()); });
578  } else {
579  std::sort(vertices_.begin(), vertices_.end(), [](const RecoVertex<>& vertex0, const RecoVertex<>& vertex1) {
580  return (vertex0.pt() > vertex1.pt());
581  });
582  }
583  }
584 
585  void VertexFinder::sortVerticesInZ0() {
586  if (settings_->vx_precision() == Precision::Emulation) {
587  std::sort(
588  verticesEmulation_.begin(),
589  verticesEmulation_.end(),
590  [](const l1t::VertexWord& vertex0, const l1t::VertexWord& vertex1) { return (vertex0.z0() < vertex1.z0()); });
591  } else {
592  std::sort(vertices_.begin(), vertices_.end(), [](const RecoVertex<>& vertex0, const RecoVertex<>& vertex1) {
593  return (vertex0.z0() < vertex1.z0());
594  });
595  }
596  }
597 
598  void VertexFinder::associatePrimaryVertex(double trueZ0) {
599  double distance = 999.;
600  for (unsigned int id = 0; id < vertices_.size(); ++id) {
601  if (std::abs(trueZ0 - vertices_[id].z0()) < distance) {
602  distance = std::abs(trueZ0 - vertices_[id].z0());
603  pv_index_ = id;
604  }
605  }
606  }
607 
608  void VertexFinder::fastHistoLooseAssociation() {
609  float vxPt = 0.;
610  RecoVertex leading_vertex;
611 
612  for (float z = settings_->vx_histogram_min(); z < settings_->vx_histogram_max();
613  z += settings_->vx_histogram_binwidth()) {
615  for (const L1Track& track : fitTracks_) {
616  if (std::abs(z - track.z0()) < settings_->vx_width()) {
617  vertex.insert(&track);
618  }
619  }
620  computeAndSetVertexParameters(vertex, {}, {});
621  vertex.setZ0(z);
622  if (vertex.pt() > vxPt) {
623  leading_vertex = vertex;
624  vxPt = vertex.pt();
625  }
626  }
627 
628  vertices_.emplace_back(leading_vertex);
629  pv_index_ = 0; // by default fastHistoLooseAssociation algorithm finds only hard PV
630  } // end of fastHistoLooseAssociation
631 
632  void VertexFinder::fastHisto(const TrackerTopology* tTopo) {
633  // Create the histogram
634  int nbins =
635  std::ceil((settings_->vx_histogram_max() - settings_->vx_histogram_min()) / settings_->vx_histogram_binwidth());
636  std::vector<RecoVertex<>> hist(nbins);
637  std::vector<RecoVertex<>> sums(nbins - settings_->vx_windowSize() + 1);
638  std::vector<float> bounds(nbins + 1);
639  strided_iota(std::begin(bounds),
640  std::next(std::begin(bounds), nbins + 1),
641  settings_->vx_histogram_min(),
642  settings_->vx_histogram_binwidth());
643 
644  // Loop over the tracks and fill the histogram
645  for (const L1Track& track : fitTracks_) {
646  if ((track.z0() < settings_->vx_histogram_min()) || (track.z0() > settings_->vx_histogram_max()))
647  continue;
648  if (track.getTTTrackPtr()->chi2() > settings_->vx_TrackMaxChi2())
649  continue;
650  if (track.pt() < settings_->vx_TrackMinPt())
651  continue;
652 
653  // Get the number of stubs and the number of stubs in PS layers
654  float nPS = 0., nstubs = 0;
655 
656  // Get pointers to stubs associated to the L1 track
657  const auto& theStubs = track.getTTTrackPtr()->getStubRefs();
658  if (theStubs.empty()) {
659  edm::LogWarning("VertexFinder") << "fastHisto::Could not retrieve the vector of stubs.";
660  continue;
661  }
662 
663  // Loop over the stubs
664  for (const auto& stub : theStubs) {
665  nstubs++;
666  bool isPS = false;
667  DetId detId(stub->getDetId());
668  if (detId.det() == DetId::Detector::Tracker) {
669  if (detId.subdetId() == StripSubdetector::TOB && tTopo->tobLayer(detId) <= 3)
670  isPS = true;
671  else if (detId.subdetId() == StripSubdetector::TID && tTopo->tidRing(detId) <= 9)
672  isPS = true;
673  }
674  if (isPS)
675  nPS++;
676  } // End loop over stubs
677  if (nstubs < settings_->vx_NStubMin())
678  continue;
679  if (nPS < settings_->vx_NStubPSMin())
680  continue;
681 
682  // Quality cuts, may need to be re-optimized
683  int trk_nstub = (int)track.getTTTrackPtr()->getStubRefs().size();
684  float chi2dof = track.getTTTrackPtr()->chi2() / (2 * trk_nstub - 4);
685 
686  if (settings_->vx_DoPtComp()) {
687  float trk_consistency = track.getTTTrackPtr()->stubPtConsistency();
688  if (trk_nstub == 4) {
689  if (std::abs(track.eta()) < 2.2 && trk_consistency > 10)
690  continue;
691  else if (std::abs(track.eta()) > 2.2 && chi2dof > 5.0)
692  continue;
693  }
694  }
695  if (settings_->vx_DoTightChi2()) {
696  if (track.pt() > 10.0 && chi2dof > 5.0)
697  continue;
698  }
699 
700  // Assign the track to the correct vertex
701  // The values are ordered with bounds [lower, upper)
702  // Values below bounds.begin() return 0 as the index (underflow)
703  // Values above bounds.end() will return the index of the last bin (overflow)
704  auto upper_bound = std::upper_bound(bounds.begin(), bounds.end(), track.z0());
705  int index = std::distance(bounds.begin(), upper_bound) - 1;
706  if (index == -1)
707  index = 0;
708  hist.at(index).insert(&track);
709  } // end loop over tracks
710 
711  // Compute the sums
712  // sliding windows ... sum_i_i+(w-1) where i in (0,nbins-w) and w is the window size
713  std::vector<float> bin_centers(settings_->vx_windowSize(), 0.0);
714  std::vector<unsigned int> counts(settings_->vx_windowSize(), 0);
715  for (unsigned int i = 0; i < sums.size(); i++) {
716  for (unsigned int j = 0; j < settings_->vx_windowSize(); j++) {
717  bin_centers[j] = settings_->vx_histogram_min() + ((i + j) * settings_->vx_histogram_binwidth()) +
718  (0.5 * settings_->vx_histogram_binwidth());
719  counts[j] = hist.at(i + j).numTracks();
720  sums.at(i) += hist.at(i + j);
721  }
722  computeAndSetVertexParameters(sums.at(i), bin_centers, counts);
723  }
724 
725  // Find the maxima of the sums
726  float sigma_max = -999;
727  int imax = -999;
728  std::vector<int> found;
729  found.reserve(settings_->vx_nvtx());
730  for (unsigned int ivtx = 0; ivtx < settings_->vx_nvtx(); ivtx++) {
731  sigma_max = -999;
732  imax = -999;
733  for (unsigned int i = 0; i < sums.size(); i++) {
734  // Skip this window if it will already be returned
735  if (find(found.begin(), found.end(), i) != found.end())
736  continue;
737  if (sums.at(i).pt() > sigma_max) {
738  sigma_max = sums.at(i).pt();
739  imax = i;
740  }
741  }
742  found.push_back(imax);
743  vertices_.emplace_back(sums.at(imax));
744  }
745  pv_index_ = 0;
746 
747  if (settings_->debug() >= 1) {
748  edm::LogInfo log("VertexProducer");
749  log << "fastHisto::Checking the output parameters ... \n";
750  std::vector<double> tmp;
751  std::transform(std::begin(sums), std::end(sums), std::back_inserter(tmp), [](const RecoVertex<>& v) -> double {
752  return v.pt();
753  });
754  printHistogram<double, edm::LogInfo>(log, tmp, 80, 0, -1, "fastHisto::sums", "\e[92m");
755  for (unsigned int i = 0; i < found.size(); i++) {
756  log << "RecoVertex " << i << ": bin index = " << found[i] << "\tsumPt = " << sums.at(imax).pt()
757  << "\tz0 = " << sums.at(imax).z0();
758  }
759  }
760  } // end of fastHisto
761 
762  void VertexFinder::fastHistoEmulation() {
763  // Relevant constants for the track word
764  enum TrackBitWidths {
765  kZ0Size = 12, // Width of z-position (40cm / 0.1)
766  kZ0MagSize = 5, // Width of z-position magnitude (signed)
767  kPtSize = 14, // Width of pt
768  kPtMagSize = 9, // Width of pt magnitude (unsigned)
769  kReducedPrecisionPt = 7, // Width of the reduced precision, integer only, pt
770  };
771 
772  enum HistogramBitWidths {
773  kBinSize = 8, // Width of a single bin in z
774  kBinFixedSize = 8, // Width of a single z0 bin in fixed point representation
775  kBinFixedMagSize = 5, // Width (magnitude) of a single z0 bin in fixed point representation
776  kSlidingSumSize = 11, // Width of the sum of a window of bins
777  kInverseSize = 14, // Width of the inverse sum
778  kInverseMagSize = 1, // Width of the inverse sum magnitude (unsigned)
779  kWeightedSlidingSumSize = 20, // Width of the pT weighted sliding sum
780  kWeightedSlidingSumMagSize = 10, // Width of the pT weighted sliding sum magnitude (signed)
781  kWindowSize = 3, // Number of bins in the window used to sum histogram bins
782  kSumPtLinkSize = 9, // Number of bits used to represent the sum of track pts in a single bin from a single link
783 
784  kSumPtWindowBits = BitsToRepresent(HistogramBitWidths::kWindowSize * (1 << HistogramBitWidths::kSumPtLinkSize)),
785  // Number of bits to represent the untruncated sum of track pts in a single bin from a single link
786  kSumPtUntruncatedLinkSize = TrackBitWidths::kPtSize + 2,
787  kSumPtUntruncatedLinkMagSize = TrackBitWidths::kPtMagSize + 2,
788  };
789 
790  static constexpr unsigned int kTableSize =
791  ((1 << HistogramBitWidths::kSumPtLinkSize) - 1) * HistogramBitWidths::kWindowSize;
792 
793  typedef ap_ufixed<TrackBitWidths::kPtSize, TrackBitWidths::kPtMagSize, AP_RND_CONV, AP_SAT> pt_t;
794  // Same size as TTTrack_TrackWord::z0_t, but now taking into account the sign bit (i.e. 2's complement)
795  typedef ap_int<TrackBitWidths::kZ0Size> z0_t;
796  // 7 bits chosen to represent values between [0,127]
797  // This is the next highest power of 2 value to our chosen track pt saturation value (100)
798  typedef ap_ufixed<TrackBitWidths::kReducedPrecisionPt, TrackBitWidths::kReducedPrecisionPt, AP_RND_INF, AP_SAT>
799  track_pt_fixed_t;
800  // Histogram bin index
801  typedef ap_uint<HistogramBitWidths::kBinSize> histbin_t;
802  // Histogram bin in fixed point representation, before truncation
803  typedef ap_ufixed<HistogramBitWidths::kBinFixedSize, HistogramBitWidths::kBinFixedMagSize, AP_RND_INF, AP_SAT>
804  histbin_fixed_t;
805  // This type is slightly arbitrary, but 2 bits larger than untruncated track pt to store sums in histogram bins
806  // with truncation just before vertex-finding
807  typedef ap_ufixed<HistogramBitWidths::kSumPtUntruncatedLinkSize,
808  HistogramBitWidths::kSumPtUntruncatedLinkMagSize,
809  AP_RND_INF,
810  AP_SAT>
811  histbin_pt_sum_fixed_t;
812  // This value is slightly arbitrary, but small enough that the windows sums aren't too big.
813  typedef ap_ufixed<HistogramBitWidths::kSumPtLinkSize, HistogramBitWidths::kSumPtLinkSize, AP_RND_INF, AP_SAT>
814  link_pt_sum_fixed_t;
815  // Enough bits to store HistogramBitWidths::kWindowSize * (2**HistogramBitWidths::kSumPtLinkSize)
816  typedef ap_ufixed<HistogramBitWidths::kSumPtWindowBits, HistogramBitWidths::kSumPtWindowBits, AP_RND_INF, AP_SAT>
817  window_pt_sum_fixed_t;
818  // pt weighted sum of bins in window
819  typedef ap_fixed<HistogramBitWidths::kWeightedSlidingSumSize,
820  HistogramBitWidths::kWeightedSlidingSumMagSize,
821  AP_RND_INF,
822  AP_SAT>
823  zsliding_t;
824  // Sum of histogram bins in window
825  typedef ap_uint<HistogramBitWidths::kSlidingSumSize> slidingsum_t;
826  // Inverse of sum of bins in a given window
827  typedef ap_ufixed<HistogramBitWidths::kInverseSize, HistogramBitWidths::kInverseMagSize, AP_RND_INF, AP_SAT>
828  inverse_t;
829 
830  auto track_quality_check = [&](const track_pt_fixed_t& pt) -> bool {
831  // Track quality cuts
832  if (pt.to_double() < settings_->vx_TrackMinPt())
833  return false;
834  return true;
835  };
836 
837  auto fetch_bin = [&](const z0_t& z0, int nbins) -> std::pair<histbin_t, bool> {
838  // Increase the the number of bits in the word to allow for additional dynamic range
839  ap_int<TrackBitWidths::kZ0Size + 1> z0_13 = z0;
840  // Add a number equal to half of the range in z0, meaning that the range is now [0, 2*z0_max]
841  ap_int<TrackBitWidths::kZ0Size + 1> absz0_13 = z0_13 + (1 << (TrackBitWidths::kZ0Size - 1));
842  // Shift the bits down to truncate the dynamic range to the most significant HistogramBitWidths::kBinFixedSize bits
843  ap_int<TrackBitWidths::kZ0Size + 1> absz0_13_reduced =
844  absz0_13 >> (TrackBitWidths::kZ0Size - HistogramBitWidths::kBinFixedSize);
845  // Put the relevant bits into the histbin_t container
846  histbin_t bin = absz0_13_reduced.range(HistogramBitWidths::kBinFixedSize - 1, 0);
847 
848  if (settings_->debug() > 2) {
849  edm::LogInfo("VertexProducer")
850  << "fastHistoEmulation::fetchBin() Checking the mapping from z0 to bin index ... \n"
851  << "histbin_fixed_t(1.0 / settings_->vx_histogram_binwidth()) = "
852  << histbin_fixed_t(1.0 / settings_->vx_histogram_binwidth()) << "\n"
853  << "histbin_t(std::floor(nbins / 2) = " << histbin_t(std::floor(nbins / 2.)) << "\n"
854  << "z0 = " << z0 << "\n"
855  << "bin = " << bin;
856  }
857  bool valid = true;
858  if (bin < 0) {
859  return std::make_pair(0, false);
860  } else if (bin > (nbins - 1)) {
861  return std::make_pair(0, false);
862  }
863  return std::make_pair(bin, valid);
864  };
865 
866  // Replace with https://stackoverflow.com/questions/13313980/populate-an-array-using-constexpr-at-compile-time ?
867  auto init_inversion_table = [&]() -> std::vector<inverse_t> {
868  std::vector<inverse_t> table_out(kTableSize, 0.);
869  for (unsigned int ii = 0; ii < kTableSize; ii++) {
870  // Compute lookup table function. This matches the format of the GTT HLS code.
871  // Biased generation f(x) = 1 / (x + 1) is inverted by g(y) = inversion(x - 1) = 1 / (x - 1 + 1) = 1 / y
872  table_out.at(ii) = (1.0 / (ii + 1));
873  }
874  return table_out;
875  };
876 
877  auto inversion = [&](slidingsum_t& data_den) -> inverse_t {
878  std::vector<inverse_t> inversion_table = init_inversion_table();
879 
880  // Index into the lookup table based on data
881  int index;
882  if (data_den < 0)
883  data_den = 0;
884  if (data_den > (kTableSize - 1))
885  data_den = kTableSize - 1;
886  index = data_den;
887  return inversion_table.at(index);
888  };
889 
890  auto bin_center = [&](zsliding_t iz, int nbins) -> l1t::VertexWord::vtxz0_t {
891  zsliding_t z = iz - histbin_t(std::floor(nbins / 2.));
892  std::unique_ptr<edm::LogInfo> log;
893  if (settings_->debug() >= 1) {
894  log = std::make_unique<edm::LogInfo>("VertexProducer");
895  *log << "bin_center information ...\n"
896  << "iz = " << iz << "\n"
897  << "histbin_t(std::floor(nbins / 2.)) = " << histbin_t(std::floor(nbins / 2.)) << "\n"
898  << "binwidth = " << zsliding_t(settings_->vx_histogram_binwidth()) << "\n"
899  << "z = " << z << "\n"
900  << "zsliding_t(z * zsliding_t(binwidth)) = " << std::setprecision(7)
901  << l1t::VertexWord::vtxz0_t(z * zsliding_t(settings_->vx_histogram_binwidth()));
902  }
903  return l1t::VertexWord::vtxz0_t(z * zsliding_t(settings_->vx_histogram_binwidth()));
904  };
905 
906  auto weighted_position = [&](histbin_t b_max,
907  const std::vector<link_pt_sum_fixed_t>& binpt,
908  slidingsum_t maximums,
909  int nbins) -> zsliding_t {
910  zsliding_t zvtx_sliding = 0;
911  slidingsum_t zvtx_sliding_sum = 0;
912  inverse_t inv = 0;
913 
914  std::unique_ptr<edm::LogInfo> log;
915  if (settings_->debug() >= 1) {
916  log = std::make_unique<edm::LogInfo>("VertexProducer");
917  *log << "Progression of weighted_position() ...\n"
918  << "zvtx_sliding_sum = ";
919  }
920 
921  // Find the weighted position within the window in index space (width = 1)
922  for (ap_uint<BitsToRepresent(HistogramBitWidths::kWindowSize)> w = 0; w < HistogramBitWidths::kWindowSize; ++w) {
923  zvtx_sliding_sum += (binpt.at(w) * w);
924  if (settings_->debug() >= 1) {
925  *log << "(" << w << " * " << binpt.at(w) << ")";
926  if (w < HistogramBitWidths::kWindowSize - 1) {
927  *log << " + ";
928  }
929  }
930  }
931 
932  if (settings_->debug() >= 1) {
933  *log << " = " << zvtx_sliding_sum << "\n";
934  }
935 
936  if (maximums != 0) {
937  //match F/W inversion_lut offset (inversion[x] = 1 / (x + 1); inversion[x - 1] = 1 / x;), for consistency
938  slidingsum_t offsetmaximums = maximums - 1;
939  inv = inversion(offsetmaximums);
940  zvtx_sliding = zvtx_sliding_sum * inv;
941  } else {
942  zvtx_sliding = (settings_->vx_windowSize() / 2.0) + (((int(settings_->vx_windowSize()) % 2) != 0) ? 0.5 : 0.0);
943  }
944  if (settings_->debug() >= 1) {
945  *log << "inversion(" << maximums << ") = " << inv << "\nzvtx_sliding = " << zvtx_sliding << "\n";
946  }
947 
948  // Add the starting index plus half an index to shift the z position to its weighted position (still in inxex space) within all of the bins
949  zvtx_sliding += b_max;
950  zvtx_sliding += ap_ufixed<1, 0>(0.5);
951  if (settings_->debug() >= 1) {
952  *log << "b_max = " << b_max << "\n";
953  *log << "zvtx_sliding + b_max + 0.5 = " << zvtx_sliding << "\n";
954  }
955 
956  // Shift the z position from index space into z [cm] space
957  zvtx_sliding = bin_center(zvtx_sliding, nbins);
958  if (settings_->debug() >= 1) {
959  *log << "bin_center(zvtx_sliding + b_max + 0.5, nbins) = " << std::setprecision(7) << zvtx_sliding;
960  log.reset();
961  }
962  return zvtx_sliding;
963  };
964 
965  // Create the histogram
966  unsigned int nbins = std::round((settings_->vx_histogram_max() - settings_->vx_histogram_min()) /
967  settings_->vx_histogram_binwidth());
968  unsigned int nsums = nbins - settings_->vx_windowSize() + 1;
969  std::vector<link_pt_sum_fixed_t> hist(nbins, 0);
970  std::vector<histbin_pt_sum_fixed_t> hist_untruncated(nbins, 0);
971 
972  // Loop over the tracks and fill the histogram
973  if (settings_->debug() > 2) {
974  edm::LogInfo("VertexProducer") << "fastHistoEmulation::Processing " << fitTracks_.size() << " tracks";
975  }
976  for (const L1Track& track : fitTracks_) {
977  // Get the track pt and z0
978  // Convert them to an appropriate data format
979  // Truncation and saturation taken care of by the data type specification, now delayed to end of histogramming
980  pt_t tkpt = 0;
981  tkpt.V = track.getTTTrackPtr()->getTrackWord()(TTTrack_TrackWord::TrackBitLocations::kRinvMSB - 1,
982  TTTrack_TrackWord::TrackBitLocations::kRinvLSB);
983  z0_t tkZ0 = track.getTTTrackPtr()->getZ0Word();
984 
985  if ((settings_->vx_DoQualityCuts() && track_quality_check(tkpt)) || (!settings_->vx_DoQualityCuts())) {
986  //
987  // Check bin validity of bin found for the current track
988  //
989  std::pair<histbin_t, bool> bin = fetch_bin(tkZ0, nbins);
990  assert(bin.first >= 0 && bin.first < nbins);
991 
992  //
993  // If the bin is valid then sum the tracks
994  //
995  if (settings_->debug() > 2) {
996  edm::LogInfo("VertexProducer") << "fastHistoEmulation::Checking the track word ... \n"
997  << "track word = " << track.getTTTrackPtr()->getTrackWord().to_string(2)
998  << "\n"
999  << "tkZ0 = " << tkZ0.to_double() << "(" << tkZ0.to_string(2)
1000  << ")\ttkpt = " << tkpt.to_double() << "(" << tkpt.to_string(2)
1001  << ")\tbin = " << bin.first.to_int() << "\n"
1002  << "pt sum in bin " << bin.first.to_int()
1003  << " BEFORE adding track = " << hist_untruncated.at(bin.first).to_double();
1004  }
1005  if (bin.second) {
1006  hist_untruncated.at(bin.first) = hist_untruncated.at(bin.first) + tkpt;
1007  }
1008  if (settings_->debug() > 2) {
1009  edm::LogInfo("VertexProducer") << "fastHistoEmulation::\npt sum in bin " << bin.first.to_int()
1010  << " AFTER adding track = " << hist_untruncated.at(bin.first).to_double();
1011  }
1012  } else {
1013  if (settings_->debug() > 2) {
1014  edm::LogInfo("VertexProducer") << "fastHistoEmulation::Did not add the following track ... \n"
1015  << "track word = " << track.getTTTrackPtr()->getTrackWord().to_string(2)
1016  << "\n"
1017  << "tkZ0 = " << tkZ0.to_double() << "(" << tkZ0.to_string(2)
1018  << ")\ttkpt = " << tkpt.to_double() << "(" << tkpt.to_string(2) << ")";
1019  }
1020  }
1021  } // end loop over tracks
1022 
1023  // HLS histogramming used to truncate track pt before adding, using
1024  // track_pt_fixed_t pt_tmp = tkpt;
1025  // Now, truncation should happen after histograms are filled but prior to the vertex-finding part of the algo
1026  for (unsigned int hb = 0; hb < hist.size(); ++hb) {
1027  link_pt_sum_fixed_t bin_trunc = hist_untruncated.at(hb).range(
1028  HistogramBitWidths::kSumPtUntruncatedLinkSize - 1,
1029  HistogramBitWidths::kSumPtUntruncatedLinkSize - HistogramBitWidths::kSumPtUntruncatedLinkMagSize);
1030  hist.at(hb) = bin_trunc;
1031  if (settings_->debug() > 2) {
1032  edm::LogInfo("VertexProducer") << "fastHistoEmulation::truncating histogram bin pt once filling is complete \n"
1033  << "hist_untruncated.at(" << hb << ") = " << hist_untruncated.at(hb).to_double()
1034  << "(" << hist_untruncated.at(hb).to_string(2)
1035  << ")\tbin_trunc = " << bin_trunc.to_double() << "(" << bin_trunc.to_string(2)
1036  << ")\n\thist.at(" << hb << ") = " << hist.at(hb).to_double() << "("
1037  << hist.at(hb).to_string(2) << ")";
1038  }
1039  }
1040 
1041  // Loop through all bins, taking into account the fact that the last bin is nbins-window_width+1,
1042  // and compute the sums using sliding windows ... sum_i_i+(w-1) where i in (0,nbins-w) and w is the window size
1043  std::vector<window_pt_sum_fixed_t> hist_window_sums(nsums, 0);
1044  for (unsigned int b = 0; b < nsums; ++b) {
1045  for (unsigned int w = 0; w < HistogramBitWidths::kWindowSize; ++w) {
1046  unsigned int index = b + w;
1047  hist_window_sums.at(b) += hist.at(index);
1048  }
1049  }
1050 
1051  // Find the top N vertices
1052  std::vector<int> found;
1053  found.reserve(settings_->vx_nvtx());
1054  for (unsigned int ivtx = 0; ivtx < settings_->vx_nvtx(); ivtx++) {
1055  histbin_t b_max = 0;
1056  window_pt_sum_fixed_t max_pt = 0;
1057  zsliding_t zvtx_sliding = -999;
1058  std::vector<link_pt_sum_fixed_t> binpt_max(HistogramBitWidths::kWindowSize, 0);
1059 
1060  // Find the maxima of the sums
1061  for (unsigned int i = 0; i < hist_window_sums.size(); i++) {
1062  // Skip this window if it will already be returned
1063  if (find(found.begin(), found.end(), i) != found.end())
1064  continue;
1065  if (hist_window_sums.at(i) > max_pt) {
1066  b_max = i;
1067  max_pt = hist_window_sums.at(b_max);
1068  std::copy(std::begin(hist) + b_max,
1069  std::begin(hist) + b_max + HistogramBitWidths::kWindowSize,
1070  std::begin(binpt_max));
1071 
1072  // Find the weighted position only for the highest sum pt window
1073  zvtx_sliding = weighted_position(b_max, binpt_max, max_pt, nbins);
1074  }
1075  }
1076  if (settings_->debug() >= 1) {
1077  edm::LogInfo log("VertexProducer");
1078  log << "fastHistoEmulation::Checking the output parameters ... \n";
1079  if (found.empty()) {
1080  printHistogram<link_pt_sum_fixed_t, edm::LogInfo>(log, hist, 80, 0, -1, "fastHistoEmulation::hist", "\e[92m");
1081  printHistogram<window_pt_sum_fixed_t, edm::LogInfo>(
1082  log, hist_window_sums, 80, 0, -1, "fastHistoEmulation::hist_window_sums", "\e[92m");
1083  }
1084  printHistogram<link_pt_sum_fixed_t, edm::LogInfo>(
1085  log, binpt_max, 80, 0, -1, "fastHistoEmulation::binpt_max", "\e[92m");
1086  log << "bin index (not a VertexWord parameter) = " << b_max << "\n"
1087  << "sumPt = " << max_pt.to_double() << "\n"
1088  << "z0 = " << zvtx_sliding.to_double();
1089  }
1090  found.push_back(b_max);
1091  verticesEmulation_.emplace_back(l1t::VertexWord::vtxvalid_t(1),
1092  l1t::VertexWord::vtxz0_t(zvtx_sliding),
1098  }
1099  pv_index_ = 0;
1100  } // end of fastHistoEmulation
1101 
1102 } // namespace l1tVertexFinder
Definition: start.py:1
constexpr int32_t ceil(float num)
double pt() const
Sum of fitted tracks transverse momentum [GeV].
Definition: RecoVertex.h:55
unsigned int tobLayer(const DetId &id) const
::ecal::reco::ComputationScalarType data_type
ap_uint< VertexBitWidths::kUnassignedSize > vtxunassigned_t
Definition: VertexWord.h:73
T w() const
ap_ufixed< VertexBitWidths::kNTrackInPVSize, VertexBitWidths::kNTrackInPVSize, AP_RND_CONV, AP_SAT > vtxmultiplicity_t
Definition: VertexWord.h:67
std::vector< L1Track > FitTrackCollection
Definition: VertexFinder.h:23
constexpr int pow(int x)
Definition: conifer.h:24
double z0() const
Vertex z0 position [cm].
Definition: RecoVertex.h:75
uint32_t T const *__restrict__ uint32_t const *__restrict__ int32_t int Histo::index_type cudaStream_t stream
void find(edm::Handle< EcalRecHitCollection > &hits, DetId thisDet, std::vector< EcalRecHitCollection::const_iterator > &hit, bool debug=false)
Definition: FindCaloHit.cc:19
assert(be >=bs)
const std::vector< const T * > & tracks() const
Tracks in the vertex.
Definition: RecoVertex.h:57
void insert(TP &tp)
Assign TP to this vertex.
Definition: Vertex.h:28
ap_ufixed< VertexBitWidths::kNTrackOutPVSize, VertexBitWidths::kNTrackOutPVSize, AP_RND_CONV, AP_SAT > vtxinversemult_t
Definition: VertexWord.h:72
unsigned int numTracks() const
Number of tracks originating from this vertex.
Definition: Vertex.h:26
ap_fixed< VertexBitWidths::kZ0Size, VertexBitWidths::kZ0MagSize, AP_RND_CONV, AP_SAT > vtxz0_t
Definition: VertexWord.h:65
static constexpr unsigned BitsToRepresent(unsigned x)
Definition: VertexFinder.h:21
T sqrt(T t)
Definition: SSEVec.h:19
The Signals That Services Can Subscribe To This is based on ActivityRegistry and is current per Services can connect to the signals distributed by the ActivityRegistry in order to monitor the activity of the application Each possible callback has some defined which we here list in angle e< void, edm::EventID const &, edm::Timestamp const & > We also list in braces which AR_WATCH_USING_METHOD_ is used for those or
Definition: Activities.doc:12
Simple wrapper class for TTTrack.
Definition: L1Track.h:17
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
ap_ufixed< VertexBitWidths::kSumPtSize, VertexBitWidths::kSumPtMagSize, AP_RND_CONV, AP_SAT > vtxsumpt_t
Definition: VertexWord.h:69
Definition: value.py:1
static constexpr auto TOB
ap_uint< VertexBitWidths::kQualitySize > vtxquality_t
Definition: VertexWord.h:70
double pt() const
Definition: VertexWord.h:160
ap_int< 10 > z0_t
Definition: datatypes.h:30
ii
Definition: cuy.py:589
Log< level::Info, false > LogInfo
Definition: DetId.h:17
float z0() const
Definition: L1Track.h:25
std::vector< RecoVertex<> > RecoVertexCollection
Definition: VertexFinder.h:24
double b
Definition: hdecay.h:120
const unsigned int kPtMagSize
double z0() const
Definition: VertexWord.h:158
char data[epos_bytes_allocation]
Definition: EPOS_Wrapper.h:80
float x
unsigned int tidRing(const DetId &id) const
Log< level::Warning, false > LogWarning
tmp
align.sh
Definition: createJobs.py:716
ap_ufixed< 16, 14 > pt_t
Definition: TauNNIdHW.h:27
static constexpr auto TID
const double NA
Definition: ZdcSD.cc:123
unsigned int numTracks() const
Number of tracks originating from this vertex.
Definition: RecoVertex.h:49
ap_uint< VertexBitWidths::kValidSize > vtxvalid_t
Definition: VertexWord.h:64
unsigned transform(const HcalDetId &id, unsigned transformCode)