CMS 3D CMS Logo

DAClusterizerInZT_vect.cc
Go to the documentation of this file.
5 
6 #include <cmath>
7 #include <cassert>
8 #include <limits>
9 #include <iomanip>
11 #include "vdt/vdtMath.h"
12 
13 using namespace std;
14 
15 //#define DEBUG
16 #ifdef DEBUG
17 #define DEBUGLEVEL 0
18 #endif
19 
20 //#define USEVTXDT2
21 
23  // hardcoded parameters
24  maxIterations_ = 1000;
25  mintrkweight_ = 0.5;
26 
27  // configurable debug output
28  verbose_ = conf.getUntrackedParameter<bool>("verbose", false);
29  zdumpcenter_ = conf.getUntrackedParameter<double>("zdumpcenter", 0.);
30  zdumpwidth_ = conf.getUntrackedParameter<double>("zdumpwidth", 20.);
31 
32  // configurable parameters
33  double minT = conf.getParameter<double>("Tmin");
34  double purgeT = conf.getParameter<double>("Tpurge");
35  double stopT = conf.getParameter<double>("Tstop");
36  vertexSize_ = conf.getParameter<double>("vertexSize");
37  vertexSizeTime_ = conf.getParameter<double>("vertexSizeTime");
38  coolingFactor_ = conf.getParameter<double>("coolingFactor");
39  d0CutOff_ = conf.getParameter<double>("d0CutOff");
40  dzCutOff_ = conf.getParameter<double>("dzCutOff");
41  dtCutOff_ = conf.getParameter<double>("dtCutOff");
42  t0Max_ = conf.getParameter<double>("t0Max");
43  uniquetrkweight_ = conf.getParameter<double>("uniquetrkweight");
44  zmerge_ = conf.getParameter<double>("zmerge");
45  tmerge_ = conf.getParameter<double>("tmerge");
46 
47  sel_zrange_ = conf.getParameter<double>("zrange");
48  convergence_mode_ = conf.getParameter<int>("convergence_mode");
49  delta_lowT_ = conf.getParameter<double>("delta_lowT");
50  delta_highT_ = conf.getParameter<double>("delta_highT");
51 
52  if (verbose_) {
53  std::cout << "DAClusterizerInZT_vect: mintrkweight = " << mintrkweight_ << std::endl;
54  std::cout << "DAClusterizerInZT_vect: uniquetrkweight = " << uniquetrkweight_ << std::endl;
55  std::cout << "DAClusterizerInZT_vect: zmerge = " << zmerge_ << std::endl;
56  std::cout << "DAClusterizerInZT_vect: tmerge = " << tmerge_ << std::endl;
57  std::cout << "DAClusterizerInZT_vect: Tmin = " << minT << std::endl;
58  std::cout << "DAClusterizerInZT_vect: Tpurge = " << purgeT << std::endl;
59  std::cout << "DAClusterizerInZT_vect: Tstop = " << stopT << std::endl;
60  std::cout << "DAClusterizerInZT_vect: vertexSize = " << vertexSize_ << std::endl;
61  std::cout << "DAClusterizerInZT_vect: vertexSizeTime = " << vertexSizeTime_ << std::endl;
62  std::cout << "DAClusterizerInZT_vect: coolingFactor = " << coolingFactor_ << std::endl;
63  std::cout << "DAClusterizerInZT_vect: d0CutOff = " << d0CutOff_ << std::endl;
64  std::cout << "DAClusterizerInZT_vect: dzCutOff = " << dzCutOff_ << std::endl;
65  std::cout << "DAClusterizerInZT_vect: dtCutoff = " << dtCutOff_ << std::endl;
66  std::cout << "DAClusterizerInZT_vect: zrange = " << sel_zrange_ << std::endl;
67  std::cout << "DAClusterizerinZT_vect: convergence mode = " << convergence_mode_ << std::endl;
68  std::cout << "DAClusterizerinZT_vect: delta_highT = " << delta_highT_ << std::endl;
69  std::cout << "DAClusterizerinZT_vect: delta_lowT = " << delta_lowT_ << std::endl;
70  }
71 #ifdef DEBUG
72  std::cout << "DAClusterizerinZT_vect: DEBUGLEVEL " << DEBUGLEVEL << std::endl;
73 #endif
74 
75  if (convergence_mode_ > 1) {
76  edm::LogWarning("DAClusterizerinZT_vect")
77  << "DAClusterizerInZT_vect: invalid convergence_mode" << convergence_mode_ << " reset to default " << 0;
78  convergence_mode_ = 0;
79  }
80 
81  if (minT == 0) {
82  edm::LogWarning("DAClusterizerinZT_vect")
83  << "DAClusterizerInZT_vect: invalid Tmin" << minT << " reset to default " << 1. / betamax_;
84  } else {
85  betamax_ = 1. / minT;
86  }
87 
88  if ((purgeT > minT) || (purgeT == 0)) {
89  edm::LogWarning("DAClusterizerinZT_vect")
90  << "DAClusterizerInZT_vect: invalid Tpurge" << purgeT << " set to " << minT;
91  purgeT = minT;
92  }
93  betapurge_ = 1. / purgeT;
94 
95  if ((stopT > purgeT) || (stopT == 0)) {
96  edm::LogWarning("DAClusterizerinZT_vect")
97  << "DAClusterizerInZT_vect: invalid Tstop" << stopT << " set to " << max(1., purgeT);
98  stopT = max(1., purgeT);
99  }
100  betastop_ = 1. / stopT;
101 }
102 
103 namespace {
104  inline double local_exp(double const& inp) { return vdt::fast_exp(inp); }
105 
106  inline void local_exp_list(double const* __restrict__ arg_inp, double* __restrict__ arg_out, const int arg_arr_size) {
107  for (auto i = 0; i != arg_arr_size; ++i)
108  arg_out[i] = vdt::fast_exp(arg_inp[i]);
109  }
110 
111  inline void local_exp_list_range(double const* __restrict__ arg_inp,
112  double* __restrict__ arg_out,
113  const int kmin,
114  const int kmax) {
115  for (auto i = kmin; i != kmax; ++i)
116  arg_out[i] = vdt::fast_exp(arg_inp[i]);
117  }
118 
119 } // namespace
120 
121 void DAClusterizerInZT_vect::verify(const vertex_t& v, const track_t& tks, unsigned int nv, unsigned int nt) const {
122  if (nv == 999999) {
123  nv = v.getSize();
124  } else {
125  assert(nv == v.getSize());
126  }
127 
128  if (nt == 999999) {
129  nt = tks.getSize();
130  } else {
131  assert(nt == tks.getSize());
132  }
133 
134  // clusters
135  assert(v.z.size() == nv);
136  assert(v.t.size() == nv);
137 #ifdef USEVTXDT2
138  assert(v.dt2.size() == nv);
139 #endif
140  assert(v.sumw.size() == nv);
141  assert(v.pk.size() == nv);
142  assert(v.swz.size() == nv);
143  assert(v.swt.size() == nv);
144  assert(v.ei_cache.size() == nv);
145  assert(v.ei.size() == nv);
146  assert(v.se.size() == nv);
147  assert(v.nuz.size() == nv);
148  assert(v.nut.size() == nv);
149  assert(v.szz.size() == nv);
150  assert(v.stt.size() == nv);
151  assert(v.szt.size() == nv);
152 
153  assert(v.z_ptr == &v.z.front());
154  assert(v.t_ptr == &v.t.front());
155  assert(v.pk_ptr == &v.pk.front());
156  assert(v.ei_cache_ptr == &v.ei_cache.front());
157  assert(v.swz_ptr == &v.swz.front());
158  assert(v.swt_ptr == &v.swt.front());
159  assert(v.se_ptr == &v.se.front());
160  assert(v.nuz_ptr == &v.nuz.front());
161  assert(v.nut_ptr == &v.nut.front());
162  assert(v.szz_ptr == &v.szz.front());
163  assert(v.stt_ptr == &v.stt.front());
164  assert(v.szt_ptr == &v.szt.front());
165  assert(v.sumw_ptr == &v.sumw.front());
166 
167 #ifdef USEVTXDT2
168  assert(v.dt2_ptr == &v.dt2.front());
169 #endif
170 
171  for (unsigned int k = 0; k < nv - 1; k++) {
172  if (v.z[k] <= v.z[k + 1])
173  continue;
174  cout << " ZT, cluster z-ordering assertion failure z[" << k << "] =" << v.z[k] << " z[" << k + 1
175  << "] =" << v.z[k + 1] << endl;
176  }
177  //for(unsigned int k=0; k< nv-1; k++){
178  //assert( v.z[k] <= v.z[k+1]);
179  //}
180 
181  // tracks
182  assert(nt == tks.z.size());
183  assert(nt == tks.t.size());
184  assert(nt == tks.dz2.size());
185 #ifdef USEVTXDT2
186  assert(nt == tks.dt2.size());
187 #endif
188  assert(nt == tks.tt.size());
189  assert(nt == tks.pi.size());
190  assert(nt == tks.Z_sum.size());
191  assert(nt == tks.kmin.size());
192  assert(nt == tks.kmax.size());
193 
194  assert(tks.z_ptr == &tks.z.front());
195  assert(tks.t_ptr == &tks.t.front());
196  assert(tks.dz2_ptr == &tks.dz2.front());
197  assert(tks.dt2_ptr == &tks.dt2.front());
198  assert(tks.pi_ptr == &tks.pi.front());
199  assert(tks.Z_sum_ptr == &tks.Z_sum.front());
200 
201  for (unsigned int i = 0; i < nt; i++) {
202  if ((tks.kmin[i] < tks.kmax[i]) && (tks.kmax[i] <= nv))
203  continue;
204  cout << "track vertex range assertion failure" << i << "/" << nt << " kmin,kmax=" << tks.kmin[i] << ", "
205  << tks.kmax[i] << " nv=" << nv << endl;
206  }
207 
208  for (unsigned int i = 0; i < nt; i++) {
209  assert((tks.kmin[i] < tks.kmax[i]) && (tks.kmax[i] <= nv));
210  }
211 }
212 
213 //todo: use r-value possibility of c++11 here
214 DAClusterizerInZT_vect::track_t DAClusterizerInZT_vect::fill(const vector<reco::TransientTrack>& tracks) const {
215  // prepare track data for clustering
216  track_t tks;
217  for (const auto& tk : tracks) {
218  if (!tk.isValid())
219  continue;
220  double t_pi = 1.;
221  double t_z = tk.stateAtBeamLine().trackStateAtPCA().position().z();
222  double t_t = tk.timeExt();
223 
224  if (std::fabs(t_z) > 1000.)
225  continue;
226  /* for comparison with 1d clustering, keep such tracks without timing info, see below
227  if (std::abs(t_t) > t0Max_)
228  continue;
229  */
230 
231  auto const& t_mom = tk.stateAtBeamLine().trackStateAtPCA().momentum();
232  // get the beam-spot
233  reco::BeamSpot beamspot = tk.stateAtBeamLine().beamSpot();
234  double t_dz2 = std::pow(tk.track().dzError(), 2) // track errror
235  + (std::pow(beamspot.BeamWidthX() * t_mom.x(), 2) + std::pow(beamspot.BeamWidthY() * t_mom.y(), 2)) *
236  std::pow(t_mom.z(), 2) / std::pow(t_mom.perp2(), 2) // beam spot width
237  + std::pow(vertexSize_, 2); // intrinsic vertex size, safer for outliers and short lived decays
238  t_dz2 = 1. / t_dz2;
239  if (edm::isNotFinite(t_dz2) || t_dz2 < std::numeric_limits<double>::min()) {
240  std::cout << "DAClusterizerInZT_vect.fill rejected track t_dz2 " << t_dz2 << std::endl;
241  continue;
242  }
243 
244  double t_dt2 =
245  std::pow(tk.dtErrorExt(), 2.) +
246  std::pow(vertexSizeTime_, 2.); // the ~injected~ timing error, need to add a small minimum vertex size in time
247  if ((tk.dtErrorExt() > 0.3) || (std::abs(t_t) > t0Max_)) {
248  t_dt2 = 0; // tracks with no time measurement
249  } else {
250  t_dt2 = 1. / t_dt2;
252  std::cout << "DAClusterizerInZT_vect.fill rejected track t_dt2 " << t_dt2 << std::endl;
253  continue;
254  }
255  }
256 
257  if (d0CutOff_ > 0) {
258  Measurement1D atIP = tk.stateAtBeamLine().transverseImpactParameter(); // error contains beamspot
259  t_pi = 1. / (1. + local_exp(std::pow(atIP.value() / atIP.error(), 2) -
260  std::pow(d0CutOff_, 2))); // reduce weight for high ip tracks
262  std::cout << "DAClusterizerInZT_vect.fill rejected track t_pu " << t_pi << std::endl;
263  continue; // usually is > 0.99
264  }
265  }
266 
267  tks.addItem(t_z, t_t, t_dz2, t_dt2, &tk, t_pi);
268  }
269  tks.extractRaw();
270 #ifdef DEBUG
271  if (DEBUGLEVEL > 0) {
272  std::cout << "Track count (ZT) filled " << tks.getSize() << " initial " << tracks.size() << std::endl;
273  }
274 #endif
275 
276  return tks;
277 }
278 
279 namespace {
280  inline double Eik(double t_z, double k_z, double t_dz2, double t_t, double k_t, double t_dt2) {
281  return std::pow(t_z - k_z, 2) * t_dz2 + std::pow(t_t - k_t, 2) * t_dt2;
282  }
283 } // namespace
284 
285 void DAClusterizerInZT_vect::set_vtx_range(double beta, track_t& gtracks, vertex_t& gvertices) const {
286  const unsigned int nv = gvertices.getSize();
287  const unsigned int nt = gtracks.getSize();
288 
289  if (nv == 0) {
290  edm::LogWarning("DAClusterizerinZT_vect") << "empty cluster list in set_vtx_range";
291  return;
292  }
293 
294  for (auto itrack = 0U; itrack < nt; ++itrack) {
295  double zrange = max(sel_zrange_ / sqrt(beta * gtracks.dz2[itrack]), zrange_min_);
296 
297  double zmin = gtracks.z_ptr[itrack] - zrange;
298  unsigned int kmin = min(nv - 1, gtracks.kmin[itrack]);
299  // find the smallest vertex_z that is larger than zmin
300  if (gvertices.z_ptr[kmin] > zmin) {
301  while ((kmin > 0) && (gvertices.z_ptr[kmin - 1] > zmin)) {
302  kmin--;
303  }
304  } else {
305  while ((kmin < (nv - 1)) && (gvertices.z_ptr[kmin] < zmin)) {
306  kmin++;
307  }
308  }
309 
310  double zmax = gtracks.z_ptr[itrack] + zrange;
311  unsigned int kmax = min(nv - 1, gtracks.kmax[itrack] - 1);
312  // note: kmax points to the last vertex in the range, while gtracks.kmax points to the entry BEHIND the last vertex
313  // find the largest vertex_z that is smaller than zmax
314  if (gvertices.z_ptr[kmax] < zmax) {
315  while ((kmax < (nv - 1)) && (gvertices.z_ptr[kmax + 1] < zmax)) {
316  kmax++;
317  }
318  } else {
319  while ((kmax > 0) && (gvertices.z_ptr[kmax] > zmax)) {
320  kmax--;
321  }
322  }
323 
324  if (kmin <= kmax) {
325  gtracks.kmin[itrack] = kmin;
326  gtracks.kmax[itrack] = kmax + 1;
327  } else {
328  gtracks.kmin[itrack] = max(0U, min(kmin, kmax));
329  gtracks.kmax[itrack] = min(nv, max(kmin, kmax) + 1);
330  }
331 
332 #ifdef DEBUG
333  if (gtracks.kmin[itrack] >= gtracks.kmax[itrack]) {
334  cout << "set_vtx_range trk = " << itrack << " kmin,kmax=" << kmin << "," << kmax
335  << " gtrack.kmin,kmax = " << gtracks.kmin[itrack] << "," << gtracks.kmax[itrack] << " zrange = " << zrange
336  << endl;
337  }
338 #endif
339  }
340 }
341 
342 void DAClusterizerInZT_vect::clear_vtx_range(track_t& gtracks, vertex_t& gvertices) const {
343  const unsigned int nt = gtracks.getSize();
344  const unsigned int nv = gvertices.getSize();
345  for (auto itrack = 0U; itrack < nt; ++itrack) {
346  gtracks.kmin[itrack] = 0;
347  gtracks.kmax[itrack] = nv;
348  }
349 }
350 
351 double DAClusterizerInZT_vect::update(double beta, track_t& gtracks, vertex_t& gvertices, const double rho0) const {
352  //update weights and vertex positions
353  // mass constrained annealing without noise
354  // returns the maximum of changes of vertex positions
355 
356  const unsigned int nt = gtracks.getSize();
357  const unsigned int nv = gvertices.getSize();
358 
359  //initialize sums
360  double sumpi = 0.;
361 
362  // to return how much the prototype moved
363  double delta = 0.;
364 
365  // intial value of a sum
366  double Z_init = 0;
367  // independpent of loop
368  if (rho0 > 0) {
369  Z_init = rho0 * local_exp(-beta * dzCutOff_ * dzCutOff_); // cut-off
370  }
371 
372  // define kernels
373 
374  auto kernel_calc_exp_arg_range = [beta](const unsigned int itrack,
375  track_t const& tracks,
376  vertex_t const& vertices,
377  const unsigned int kmin,
378  const unsigned int kmax) {
379  const auto track_z = tracks.z_ptr[itrack];
380  const auto track_t = tracks.t_ptr[itrack];
381  const auto botrack_dz2 = -beta * tracks.dz2_ptr[itrack];
382 #ifndef USEVTXDT2
383  const auto botrack_dt2 = -beta * tracks.dt2_ptr[itrack];
384 #endif
385  // auto-vectorized
386  for (unsigned int ivertex = kmin; ivertex < kmax; ++ivertex) {
387  const auto mult_resz = track_z - vertices.z_ptr[ivertex];
388  const auto mult_rest = track_t - vertices.t_ptr[ivertex];
389 #ifdef USEVTXDT2
390  const auto botrack_dt2 = -beta * tracks.dt2_ptr[itrack] * vertices.dt2_ptr[ivertex] /
391  (tracks.dt2_ptr[itrack] + vertices.dt2_ptr[ivertex] + 1.e-10);
392 #endif
393  vertices.ei_cache_ptr[ivertex] = botrack_dz2 * (mult_resz * mult_resz) + botrack_dt2 * (mult_rest * mult_rest);
394  }
395  };
396 
397  auto kernel_add_Z_range = [Z_init](
398  vertex_t const& vertices, const unsigned int kmin, const unsigned int kmax) -> double {
399  double ZTemp = Z_init;
400  for (unsigned int ivertex = kmin; ivertex < kmax; ++ivertex) {
401  ZTemp += vertices.pk_ptr[ivertex] * vertices.ei_ptr[ivertex];
402  }
403  return ZTemp;
404  };
405 
406  auto kernel_calc_normalization_range = [](const unsigned int track_num,
407  track_t& tks_vec,
408  vertex_t& y_vec,
409  const unsigned int kmin,
410  const unsigned int kmax) {
411  auto tmp_trk_pi = tks_vec.pi_ptr[track_num];
412  auto o_trk_Z_sum = 1. / tks_vec.Z_sum_ptr[track_num];
413  auto o_trk_err_z = tks_vec.dz2_ptr[track_num];
414  auto o_trk_err_t = tks_vec.dt2_ptr[track_num];
415  auto tmp_trk_z = tks_vec.z_ptr[track_num];
416  auto tmp_trk_t = tks_vec.t_ptr[track_num];
417  // auto-vectorized
418 #pragma GCC ivdep
419  for (unsigned int k = kmin; k < kmax; ++k) {
420  // parens are important for numerical stability
421  y_vec.se_ptr[k] += tmp_trk_pi * (y_vec.ei_ptr[k] * o_trk_Z_sum);
422  const auto w = tmp_trk_pi * (y_vec.pk_ptr[k] * y_vec.ei_ptr[k] * o_trk_Z_sum); // p_{ik}
423  const auto wz = w * o_trk_err_z;
424  const auto wt = w * o_trk_err_t;
425 #ifdef USEVTXDT2
426  y_vec.sumw_ptr[k] += w; // for vtxdt2
427 #endif
428  y_vec.nuz_ptr[k] += wz;
429  y_vec.nut_ptr[k] += wt;
430  y_vec.swz_ptr[k] += wz * tmp_trk_z;
431  y_vec.swt_ptr[k] += wt * tmp_trk_t;
432  /* this is really only needed when we want to get Tc too, maybe better to do it elsewhere? */
433  const auto dsz = (tmp_trk_z - y_vec.z_ptr[k]) * o_trk_err_z;
434  const auto dst = (tmp_trk_t - y_vec.t_ptr[k]) * o_trk_err_t;
435  y_vec.szz_ptr[k] += w * dsz * dsz;
436  y_vec.stt_ptr[k] += w * dst * dst;
437  y_vec.szt_ptr[k] += w * dsz * dst;
438  }
439  };
440 
441  for (auto ivertex = 0U; ivertex < nv; ++ivertex) {
442  gvertices.se_ptr[ivertex] = 0.0;
443  gvertices.nuz_ptr[ivertex] = 0.0;
444  gvertices.nut_ptr[ivertex] = 0.0;
445  gvertices.swz_ptr[ivertex] = 0.0;
446  gvertices.swt_ptr[ivertex] = 0.0;
447  gvertices.szz_ptr[ivertex] = 0.0;
448  gvertices.stt_ptr[ivertex] = 0.0;
449  gvertices.szt_ptr[ivertex] = 0.0;
450 #ifdef USEVTXDT2
451  gvertices.sumw_ptr[k] = 0.0;
452 #endif
453  }
454 
455  // loop over tracks
456  for (auto itrack = 0U; itrack < nt; ++itrack) {
457  unsigned int kmin = gtracks.kmin[itrack];
458  unsigned int kmax = gtracks.kmax[itrack];
459 
460 #ifdef DEBUG
461  assert((kmin < kmax) && (kmax <= nv));
462  assert(itrack < gtracks.Z_sum.size());
463 #endif
464 
465  kernel_calc_exp_arg_range(itrack, gtracks, gvertices, kmin, kmax);
466  local_exp_list_range(gvertices.ei_cache_ptr, gvertices.ei_ptr, kmin, kmax);
467 
468  gtracks.Z_sum_ptr[itrack] = kernel_add_Z_range(gvertices, kmin, kmax);
469  if (edm::isNotFinite(gtracks.Z_sum_ptr[itrack]))
470  gtracks.Z_sum_ptr[itrack] = 0.0;
471  // used in the next major loop to follow
472  sumpi += gtracks.pi_ptr[itrack];
473 
474  if (gtracks.Z_sum_ptr[itrack] > 1.e-100) {
475  kernel_calc_normalization_range(itrack, gtracks, gvertices, kmin, kmax);
476  }
477  }
478 
479  // now update z, t, and pk
480  auto kernel_calc_zt = [sumpi, nv](vertex_t& vertices) -> double {
481  double delta = 0;
482 
483  // does not vectorizes
484  for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
485  if (vertices.nuz_ptr[ivertex] > 0.) {
486  auto znew = vertices.swz_ptr[ivertex] / vertices.nuz_ptr[ivertex];
487  delta = max(std::abs(vertices.z_ptr[ivertex] - znew), delta);
488  vertices.z_ptr[ivertex] = znew;
489  }
490 
491  if (vertices.nut_ptr[ivertex] > 0.) {
492  auto tnew = vertices.swt_ptr[ivertex] / vertices.nut_ptr[ivertex];
493  //delta = max(std::abs(vertices.t_ptr[ ivertex ] - tnew), delta); // FIXME
494  vertices.t_ptr[ivertex] = tnew;
495 #ifdef USEVTXDT2
496  vertices.dt2_ptr[ivertex] = vertices.nut_ptr[ivertex] / vertices.sumw_ptr[ivertex];
497 #endif
498  } else {
499  // FIXME
500  // apparently this cluster has not timing info attached
501  // this should be taken into account somehow, otherwise we might fail to attach
502  // new tracks that do have timing information
503  vertices.t_ptr[ivertex] = 0;
504 #ifdef USEVTXDT2
505  vertices.dt2_ptr[ivertex] = 0;
506 #endif
507  }
508 
509 #ifdef DEBUG
510  if ((vertices.nut_ptr[ivertex] <= 0.) && (vertices.nuz_ptr[ivertex] <= 0.)) {
511  edm::LogInfo("sumw") << "invalid sum of weights in fit: " << endl;
512  std::cout << " a cluster melted away ? "
513  << " zk=" << vertices.z_ptr[ivertex] << " pk=" << vertices.pk_ptr[ivertex]
514  << " sumw(z,t) =" << vertices.nuz_ptr[ivertex] << "," << vertices.nut_ptr[ivertex] << endl;
515  // FIXME: discard this cluster
516  }
517 #endif
518  }
519 
520  auto osumpi = 1. / sumpi;
521  for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
522  vertices.pk_ptr[ivertex] = vertices.pk_ptr[ivertex] * vertices.se_ptr[ivertex] * osumpi;
523  }
524 
525  return delta;
526  };
527 
528  delta += kernel_calc_zt(gvertices);
529 
530  if (zorder(gvertices)) {
531  set_vtx_range(beta, gtracks, gvertices);
532  };
533 
534  // return how much the prototypes moved
535  return delta;
536 }
537 
539  const unsigned int nv = y.getSize();
540 
541 #ifdef DEBUG
542  assert(y.z.size() == nv);
543  assert(y.t.size() == nv);
544  // assert(y.dt2.size() == nv);
545  assert(y.pk.size() == nv);
546 #endif
547 
548  if (nv < 2)
549  return false;
550 
551  bool reordering = true;
552  bool modified = false;
553 
554  while (reordering) {
555  reordering = false;
556  for (unsigned int k = 0; (k + 1) < nv; k++) {
557  if (y.z[k + 1] < y.z[k]) {
558  auto ztemp = y.z[k];
559  y.z[k] = y.z[k + 1];
560  y.z[k + 1] = ztemp;
561  auto ttemp = y.t[k];
562  y.t[k] = y.t[k + 1];
563  y.t[k + 1] = ttemp;
564 #ifdef USEVTXDT2
565  auto dt2temp = y.dt2[k];
566  y.dt2[k] = y.dt2[k + 1];
567  y.dt2[k + 1] = dt2temp;
568 #endif
569  auto ptemp = y.pk[k];
570  y.pk[k] = y.pk[k + 1];
571  y.pk[k + 1] = ptemp;
572  reordering = true;
573  }
574  }
575  modified |= reordering;
576  }
577 
578  if (modified) {
579  y.extractRaw();
580  return true;
581  }
582 
583  return false;
584 }
585 
587  double z, double t, vertex_t& y, unsigned int& k_min, double dz, double dt) const {
588  // find the cluster nearest to (z,t)
589  // distance measure is delta = (delta_z / dz )**2 + (delta_t/ d_t)**2
590  // assumes that clusters are ordered n z
591  // return value is false if no neighbour with distance < 1 is found
592 
593  unsigned int nv = y.getSize();
594  if (nv < 2) {
595  k_min = 0;
596  return false;
597  }
598 
599  // find nearest in z, binary search later
600  unsigned int k = 0;
601  for (unsigned int k0 = 1; k0 < nv; k0++) {
602  if (std::abs(y.z_ptr[k0] - z) < std::abs(y.z_ptr[k] - z)) {
603  k = k0;
604  }
605  }
606 
607  double delta_min = 1.;
608 
609  //search left
610  unsigned int k1 = k;
611  while ((k1 > 0) && ((y.z[k] - y.z[--k1]) < dz)) {
612  auto delta = std::pow((y.z_ptr[k] - y.z_ptr[k1]) / dz, 2) + std::pow((y.t_ptr[k] - y.t_ptr[k1]) / dt, 2);
613  if (delta < delta_min) {
614  k_min = k1;
615  delta_min = delta;
616  }
617  }
618 
619  //search right
620  k1 = k;
621  while (((++k1) < nv) && ((y.z[k1] - y.z[k]) < dz)) {
622  auto delta = std::pow((y.z_ptr[k1] - y.z_ptr[k]) / dz, 2) + std::pow((y.t_ptr[k1] - y.t_ptr[k]) / dt, 2);
623  if (delta < delta_min) {
624  k_min = k1;
625  delta_min = delta;
626  }
627  }
628 
629  return (delta_min < 1.);
630 }
631 
633  double beta, track_t& tks, vertex_t& v, const double delta_max0, const double rho0) const {
634  unsigned int niter = 0;
635  double delta = 0;
636  double delta_max = delta_lowT_;
637 
638  if (convergence_mode_ == 0) {
639  delta_max = delta_max0;
640  } else if (convergence_mode_ == 1) {
641  delta_max = delta_lowT_ / sqrt(std::max(beta, 1.0));
642  }
643 
644  zorder(v);
645  set_vtx_range(beta, tks, v);
646 
647  double delta_sum_range = 0; // accumulate max(|delta-z|) as a lower bound
648  std::vector<double> z0 = v.z;
649 
650  while (niter++ < maxIterations_) {
651  delta = update(beta, tks, v, rho0);
652  delta_sum_range += delta;
653 
654  if (delta_sum_range > zrange_min_) {
655  for (unsigned int k = 0; k < v.getSize(); k++) {
656  if (std::abs(v.z[k] - z0[k]) > zrange_min_) {
657  zorder(v);
658  set_vtx_range(beta, tks, v);
659  delta_sum_range = 0;
660  z0 = v.z;
661  break;
662  }
663  }
664  }
665 
666  if (delta < delta_max) {
667  break;
668  }
669  }
670 
671 #ifdef DEBUG
672  if (DEBUGLEVEL > 0) {
673  std::cout << "DAClusterizerInZT_vect.thermalize niter = " << niter << " at T = " << 1 / beta
674  << " nv = " << v.getSize() << std::endl;
675  if (DEBUGLEVEL > 2)
676  dump(beta, v, tks, 0);
677  }
678 #endif
679 
680  return niter;
681 }
682 
683 bool DAClusterizerInZT_vect::merge(vertex_t& y, track_t& tks, double& beta) const {
684  // merge clusters that collapsed or never separated,
685  // return true if vertices were merged, false otherwise
686  const unsigned int nv = y.getSize();
687 
688  if (nv < 2)
689  return false;
690 
691  // merge the smallest distance clusters first
692  unsigned int k1_min = 0, k2_min = 0;
693  double delta_min = 0;
694 
695  for (unsigned int k1 = 0; (k1 + 1) < nv; k1++) {
696  unsigned int k2 = k1;
697  while ((++k2 < nv) && (std::fabs(y.z[k2] - y.z_ptr[k1]) < zmerge_)) {
698  auto delta =
699  std::pow((y.z_ptr[k2] - y.z_ptr[k1]) / zmerge_, 2) + std::pow((y.t_ptr[k2] - y.t_ptr[k1]) / tmerge_, 2);
700  if ((delta < delta_min) || (k1_min == k2_min)) {
701  k1_min = k1;
702  k2_min = k2;
703  delta_min = delta;
704  }
705  }
706  }
707 
708  if ((k1_min == k2_min) || (delta_min > 1)) {
709  return false;
710  }
711 
712  double rho = y.pk_ptr[k1_min] + y.pk_ptr[k2_min];
713 
714 #ifdef DEBUG
715  assert((k1_min < nv) && (k2_min < nv));
716  if (DEBUGLEVEL > 1) {
717  std::cout << "merging (" << setw(8) << fixed << setprecision(4) << y.z_ptr[k1_min] << ',' << y.t_ptr[k1_min]
718  << ") and (" << y.z_ptr[k2_min] << ',' << y.t_ptr[k2_min] << ")"
719  << " idx=" << k1_min << "," << k2_min << std::endl;
720  }
721 #endif
722 
723  if (rho > 0) {
724  y.z_ptr[k1_min] = (y.pk_ptr[k1_min] * y.z_ptr[k1_min] + y.pk_ptr[k2_min] * y.z_ptr[k2_min]) / rho;
725  y.t_ptr[k1_min] = (y.pk_ptr[k1_min] * y.t_ptr[k1_min] + y.pk_ptr[k2_min] * y.t_ptr[k2_min]) / rho;
726 #ifdef USEVTXDT2
727  y.dt2_ptr[k1_min] = (y.pk_ptr[k1_min] * y.dt2_ptr[k1_min] + y.pk_ptr[k2_min] * y.dt2_ptr[k2_min]) / rho;
728 #endif
729  } else {
730  y.z_ptr[k1_min] = 0.5 * (y.z_ptr[k1_min] + y.z_ptr[k2_min]);
731  y.t_ptr[k1_min] = 0.5 * (y.t_ptr[k1_min] + y.t_ptr[k2_min]);
732  }
733  y.pk_ptr[k1_min] = rho;
734  y.removeItem(k2_min, tks);
735 
736  zorder(y);
737  set_vtx_range(beta, tks, y);
738  y.extractRaw();
739  return true;
740 }
741 
742 bool DAClusterizerInZT_vect::purge(vertex_t& y, track_t& tks, double& rho0, const double beta) const {
743  constexpr double eps = 1.e-100;
744  // eliminate clusters with only one significant/unique track
745  const unsigned int nv = y.getSize();
746  const unsigned int nt = tks.getSize();
747 
748  if (nv < 2)
749  return false;
750 
751  double sumpmin = nt;
752  unsigned int k0 = nv;
753 
754  int nUnique = 0;
755  double sump = 0;
756 
757  std::vector<double> inverse_zsums(nt), arg_cache(nt), eik_cache(nt), pcut_cache(nt);
758  double* __restrict__ pinverse_zsums;
759  double* __restrict__ parg_cache;
760  double* __restrict__ peik_cache;
761  double* __restrict__ ppcut_cache;
762  pinverse_zsums = inverse_zsums.data();
763  parg_cache = arg_cache.data();
764  peik_cache = eik_cache.data();
765  ppcut_cache = pcut_cache.data();
766  for (unsigned i = 0; i < nt; ++i) {
767  inverse_zsums[i] = tks.Z_sum_ptr[i] > eps ? 1. / tks.Z_sum_ptr[i] : 0.0;
768  }
769  const auto rhoconst = rho0 * local_exp(-beta * dzCutOff_ * dzCutOff_);
770  for (unsigned int k = 0; k < nv; ++k) {
771  const double pmax = y.pk_ptr[k] / (y.pk_ptr[k] + rhoconst);
772  ppcut_cache[k] = uniquetrkweight_ * pmax;
773  }
774 
775  for (unsigned int k = 0; k < nv; ++k) {
776  for (unsigned i = 0; i < nt; ++i) {
777  const auto track_z = tks.z_ptr[i];
778  const auto track_t = tks.t_ptr[i];
779  const auto botrack_dz2 = -beta * tks.dz2_ptr[i];
780  const auto botrack_dt2 = -beta * tks.dt2_ptr[i]; // FIXME usevtxdt2?
781 
782  const auto mult_resz = track_z - y.z_ptr[k];
783  const auto mult_rest = track_t - y.t_ptr[k];
784  parg_cache[i] = botrack_dz2 * (mult_resz * mult_resz) + botrack_dt2 * (mult_rest * mult_rest);
785  }
786  local_exp_list(parg_cache, peik_cache, nt);
787 
788  nUnique = 0;
789  sump = 0;
790  for (unsigned int i = 0; i < nt; ++i) {
791  const auto p = y.pk_ptr[k] * peik_cache[i] * pinverse_zsums[i];
792  sump += p;
793  nUnique += ((p > ppcut_cache[k]) & (tks.pi_ptr[i] > 0)) ? 1 : 0;
794  }
795 
796  if ((nUnique < 2) && (sump < sumpmin)) {
797  sumpmin = sump;
798  k0 = k;
799  }
800  }
801 
802  if (k0 != nv) {
803 #ifdef DEBUG
804  assert(k0 < y.getSize());
805  if (DEBUGLEVEL > 1) {
806  std::cout << "eliminating prototype at " << std::setw(10) << std::setprecision(4) << y.z_ptr[k0] << ","
807  << y.t_ptr[k0] << " with sump=" << sumpmin << " rho*nt =" << y.pk_ptr[k0] * nt << endl;
808  }
809 #endif
810  y.removeItem(k0, tks);
811  set_vtx_range(beta, tks, y);
812  return true;
813  } else {
814  return false;
815  }
816 }
817 
818 double DAClusterizerInZT_vect::beta0(double betamax, track_t const& tks, vertex_t const& y) const {
819  double T0 = 0; // max Tc for beta=0
820  // estimate critical temperature from beta=0 (T=inf)
821  const unsigned int nt = tks.getSize();
822  const unsigned int nv = y.getSize();
823 
824  for (unsigned int k = 0; k < nv; k++) {
825  // vertex fit at T=inf
826  double sumwz = 0;
827  double sumwt = 0;
828  double sumw_z = 0;
829  double sumw_t = 0;
830  for (unsigned int i = 0; i < nt; i++) {
831  double w_z = tks.pi_ptr[i] * tks.dz2_ptr[i];
832  double w_t = tks.pi_ptr[i] * tks.dt2_ptr[i];
833  sumwz += w_z * tks.z_ptr[i];
834  sumwt += w_t * tks.t_ptr[i];
835  sumw_z += w_z;
836  sumw_t += w_t;
837  }
838  y.z_ptr[k] = sumwz / sumw_z;
839  y.t_ptr[k] = sumwt / sumw_t;
840 
841  // estimate Tc, eventually do this in the same loop
842  double szz = 0, stt = 0, szt = 0;
843  double nuz = 0, nut = 0;
844  for (unsigned int i = 0; i < nt; i++) {
845  double dz = (tks.z_ptr[i] - y.z_ptr[k]) * tks.dz2_ptr[i];
846  double dt = (tks.t_ptr[i] - y.t_ptr[k]) * tks.dt2_ptr[i];
847  double w = tks.pi_ptr[i];
848  szz += w * dz * dz;
849  stt += w * dt * dt;
850  szt += w * dz * dt;
851  nuz += w * tks.dz2_ptr[i];
852  nut += w * tks.dt2_ptr[i];
853  }
854  double Tz = szz / nuz;
855  double Tt = 0;
856  double Tc = 0;
857  if (nut > 0) {
858  Tt = stt / nut;
859  Tc = Tz + Tt + sqrt(pow(Tz - Tt, 2) + 4 * szt * szt / nuz / nut);
860  } else {
861  Tc = 2. * Tz;
862  }
863 
864  if (Tc > T0)
865  T0 = Tc;
866  } // vertex loop (normally there should be only one vertex at beta=0)
867 
868 #ifdef DEBUG
869  if (DEBUGLEVEL > 0) {
870  std::cout << "DAClusterizerInZT_vect.beta0: Tc = " << T0 << std::endl;
871  int coolingsteps = 1 - int(std::log(T0 * betamax) / std::log(coolingFactor_));
872  std::cout << "DAClusterizerInZT_vect.beta0: nstep = " << coolingsteps << std::endl;
873  }
874 #endif
875 
876  if (T0 > 1. / betamax) {
877  int coolingsteps = 1 - int(std::log(T0 * betamax) / std::log(coolingFactor_));
878  return betamax * std::pow(coolingFactor_, coolingsteps);
879  } else {
880  // ensure at least one annealing step
881  return betamax * coolingFactor_;
882  }
883 }
884 
885 double DAClusterizerInZT_vect::get_Tc(const vertex_t& y, int k) const {
886  double Tz = y.szz_ptr[k] / y.nuz_ptr[k]; // actually 0.5*Tc(z)
887  double Tt = 0.;
888  if (y.nut_ptr[k] > 0) {
889  Tt = y.stt_ptr[k] / y.nut_ptr[k];
890  double mx = y.szt_ptr[k] / y.nuz_ptr[k] * y.szt_ptr[k] / y.nut_ptr[k];
891  return Tz + Tt + sqrt(pow(Tz - Tt, 2) + 4 * mx);
892  }
893  return 2 * Tz;
894 }
895 
896 bool DAClusterizerInZT_vect::split(const double beta, track_t& tks, vertex_t& y, double threshold) const {
897  // split only critical vertices (Tc >~ T=1/beta <==> beta*Tc>~1)
898  // an update must have been made just before doing this (same beta, no merging)
899  // returns true if at least one cluster was split
900 
901  constexpr double epsilonz = 1e-3; // minimum split size z
902  constexpr double epsilont = 1e-2; // minimum split size t
903  unsigned int nv = y.getSize();
904  const double twoBeta = 2.0 * beta;
905 
906  // avoid left-right biases by splitting highest Tc first
907 
908  std::vector<std::pair<double, unsigned int> > critical;
909  for (unsigned int k = 0; k < nv; k++) {
910  double Tc = get_Tc(y, k);
911  if (beta * Tc > threshold) {
912  critical.push_back(make_pair(Tc, k));
913  }
914  }
915  if (critical.empty())
916  return false;
917 
918  std::stable_sort(critical.begin(), critical.end(), std::greater<std::pair<double, unsigned int> >());
919 
920  bool split = false;
921  const unsigned int nt = tks.getSize();
922 
923  for (unsigned int ic = 0; ic < critical.size(); ic++) {
924  unsigned int k = critical[ic].second;
925 
926  // split direction in the (z,t)-plane
927 
928  double Mzz = y.nuz_ptr[k] - twoBeta * y.szz_ptr[k];
929  double Mtt = y.nut_ptr[k] - twoBeta * y.stt_ptr[k];
930  double Mzt = -twoBeta * y.szt_ptr[k];
931  const double twoMzt = 2.0 * Mzt;
932  double D = sqrt(pow(Mtt - Mzz, 2) + twoMzt * twoMzt);
933  double q1 = atan2(-Mtt + Mzz + D, -twoMzt);
934  double l1 = 0.5 * (-Mzz - Mtt + D);
935  double l2 = 0.5 * (-Mzz - Mtt - D);
936  if ((std::abs(l1) < 1e-4) && (std::abs(l2) < 1e-4)) {
937  edm::LogWarning("DAClusterizerInZT_vect") << "warning, bad eigenvalues! idx=" << k << " z= " << y.z_ptr[k]
938  << " Mzz=" << Mzz << " Mtt=" << Mtt << " Mzt=" << Mzt << endl;
939  }
940 
941  double qsplit = q1;
942  double cq = cos(qsplit);
943  double sq = sin(qsplit);
944  if (cq < 0) {
945  cq = -cq;
946  sq = -sq;
947  } // prefer cq>0 to keep z-ordering
948 
949  // estimate subcluster positions and weight
950  double p1 = 0, z1 = 0, t1 = 0, wz1 = 0, wt1 = 0;
951  double p2 = 0, z2 = 0, t2 = 0, wz2 = 0, wt2 = 0;
952  for (unsigned int i = 0; i < nt; ++i) {
953  if (tks.Z_sum_ptr[i] > 1.e-100) {
954  double lr = (tks.z_ptr[i] - y.z_ptr[k]) * cq + (tks.t[i] - y.t_ptr[k]) * sq;
955  // winner-takes-all, usually overestimates splitting
956  double tl = lr < 0 ? 1. : 0.;
957  double tr = 1. - tl;
958 
959  // soften it, especially at low T
960  double arg = lr * std::sqrt(beta * (cq * cq * tks.dz2_ptr[i] + sq * sq * tks.dt2_ptr[i]));
961  if (std::abs(arg) < 20) {
962  double t = local_exp(-arg);
963  tl = t / (t + 1.);
964  tr = 1 / (t + 1.);
965  }
966 
967  double p =
968  y.pk_ptr[k] * tks.pi_ptr[i] *
969  local_exp(-beta * Eik(tks.z_ptr[i], y.z_ptr[k], tks.dz2_ptr[i], tks.t_ptr[i], y.t_ptr[k], tks.dt2_ptr[i])) /
970  tks.Z_sum_ptr[i];
971  double wz = p * tks.dz2_ptr[i];
972  double wt = p * tks.dt2_ptr[i];
973  p1 += p * tl;
974  z1 += wz * tl * tks.z_ptr[i];
975  t1 += wt * tl * tks.t_ptr[i];
976  wz1 += wz * tl;
977  wt1 += wt * tl;
978  p2 += p * tr;
979  z2 += wz * tr * tks.z_ptr[i];
980  t2 += wt * tr * tks.t_ptr[i];
981  wz2 += wz * tr;
982  wt2 += wt * tr;
983  }
984  }
985 
986  if (wz1 > 0) {
987  z1 /= wz1;
988  } else {
989  z1 = y.z_ptr[k] - epsilonz * cq;
990  edm::LogWarning("DAClusterizerInZT_vect") << "warning, wz1 = " << scientific << wz1 << endl;
991  }
992  if (wt1 > 0) {
993  t1 /= wt1;
994  } else {
995  t1 = y.t_ptr[k] - epsilont * sq;
996  edm::LogWarning("DAClusterizerInZT_vect") << "warning, wt1 = " << scientific << wt1 << endl;
997  }
998  if (wz2 > 0) {
999  z2 /= wz2;
1000  } else {
1001  z2 = y.z_ptr[k] + epsilonz * cq;
1002  edm::LogWarning("DAClusterizerInZT_vect") << "warning, wz2 = " << scientific << wz2 << endl;
1003  }
1004  if (wt2 > 0) {
1005  t2 /= wt2;
1006  } else {
1007  t2 = y.t_ptr[k] + epsilont * sq;
1008  edm::LogWarning("DAClusterizerInZT_vect") << "warning, wt2 = " << scientific << wt2 << endl;
1009  }
1010 
1011  unsigned int k_min1 = k, k_min2 = k;
1012  constexpr double spliteps = 1e-8;
1013  while (((find_nearest(z1, t1, y, k_min1, epsilonz, epsilont) && (k_min1 != k)) ||
1014  (find_nearest(z2, t2, y, k_min2, epsilonz, epsilont) && (k_min2 != k))) &&
1015  (std::abs(z2 - z1) > spliteps || std::abs(t2 - t1) > spliteps)) {
1016  z1 = 0.5 * (z1 + y.z_ptr[k]);
1017  t1 = 0.5 * (t1 + y.t_ptr[k]);
1018  z2 = 0.5 * (z2 + y.z_ptr[k]);
1019  t2 = 0.5 * (t2 + y.t_ptr[k]);
1020  }
1021 
1022 #ifdef DEBUG
1023  assert(k < nv);
1024  if (DEBUGLEVEL > 1) {
1025  if (std::fabs(y.z_ptr[k] - zdumpcenter_) < zdumpwidth_) {
1026  std::cout << " T= " << std::setw(10) << std::setprecision(1) << 1. / beta << " Tc= " << critical[ic].first
1027  << " direction =" << std::setprecision(4) << qsplit << " splitting (" << std::setw(8) << std::fixed
1028  << std::setprecision(4) << y.z_ptr[k] << "," << y.t_ptr[k] << ")"
1029  << " --> (" << z1 << ',' << t1 << "),(" << z2 << ',' << t2 << ") [" << p1 << "," << p2 << "]";
1030  if (std::fabs(z2 - z1) > epsilonz || std::fabs(t2 - t1) > epsilont) {
1031  std::cout << std::endl;
1032  } else {
1033  std::cout << " rejected " << std::endl;
1034  }
1035  }
1036  }
1037 #endif
1038 
1039  if (z1 > z2) {
1040  edm::LogInfo("DAClusterizerInZT") << "warning swapping z in split qsplit=" << qsplit << " cq=" << cq
1041  << " sq=" << sq << endl;
1042  auto ztemp = z1;
1043  auto ttemp = t1;
1044  auto ptemp = p1;
1045  z1 = z2;
1046  t1 = t2;
1047  p1 = p2;
1048  z2 = ztemp;
1049  t2 = ttemp;
1050  p2 = ptemp;
1051  }
1052 
1053  // split if the new subclusters are significantly separated
1054  if (std::fabs(z2 - z1) > epsilonz || std::fabs(t2 - t1) > epsilont) {
1055  split = true;
1056  double pk1 = p1 * y.pk_ptr[k] / (p1 + p2);
1057  double pk2 = p2 * y.pk_ptr[k] / (p1 + p2);
1058 
1059  // replace the original by (z2,t2)
1060  y.removeItem(k, tks);
1061  unsigned int k2 = y.insertOrdered(z2, t2, pk2, tks);
1062 
1063 #ifdef DEBUG
1064  if (k2 < k) {
1065  std::cout << "unexpected z-ordering in split" << std::endl;
1066  }
1067 #endif
1068 
1069  // adjust pointers if necessary
1070  if (!(k == k2)) {
1071  for (unsigned int jc = ic; jc < critical.size(); jc++) {
1072  if (critical[jc].second > k) {
1073  critical[jc].second--;
1074  }
1075  if (critical[jc].second >= k2) {
1076  critical[jc].second++;
1077  }
1078  }
1079  }
1080 
1081  // insert (z1,t1) where it belongs
1082  unsigned int k1 = y.insertOrdered(z1, t1, pk1, tks);
1083  nv++;
1084 
1085  // adjust remaining pointers
1086  for (unsigned int jc = ic; jc < critical.size(); jc++) {
1087  if (critical[jc].second >= k1) {
1088  critical[jc].second++;
1089  } // need to backport the ">-"?
1090  }
1091 
1092  } else {
1093 #ifdef DEBUG
1094  std::cout << "warning ! split rejected, too small." << endl;
1095 #endif
1096  }
1097  }
1098  return split;
1099 }
1100 
1101 vector<TransientVertex> DAClusterizerInZT_vect::vertices(const vector<reco::TransientTrack>& tracks,
1102  const int verbosity) const {
1103  track_t&& tks = fill(tracks);
1104  tks.extractRaw();
1105 
1106  unsigned int nt = tks.getSize();
1107  double rho0 = 0.0; // start with no outlier rejection
1108 
1109  vector<TransientVertex> clusters;
1110  if (tks.getSize() == 0)
1111  return clusters;
1112 
1113  vertex_t y; // the vertex prototypes
1114 
1115  // initialize:single vertex at infinite temperature
1116  y.addItem(0, 0, 1.0);
1117  clear_vtx_range(tks, y);
1118 
1119  // estimate first critical temperature
1120  double beta = beta0(betamax_, tks, y);
1121 #ifdef DEBUG
1122  if (DEBUGLEVEL > 0)
1123  std::cout << "Beta0 is " << beta << std::endl;
1124 #endif
1125 
1126  thermalize(beta, tks, y, delta_highT_, 0.);
1127 
1128  // annealing loop, stop when T<minT (i.e. beta>1/minT)
1129 
1130  double betafreeze = betamax_ * sqrt(coolingFactor_);
1131 
1132  while (beta < betafreeze) {
1133  update(beta, tks, y, rho0);
1134  while (merge(y, tks, beta)) {
1135  if (zorder(y))
1136  set_vtx_range(beta, tks, y);
1137  update(beta, tks, y, rho0);
1138  }
1139  split(beta, tks, y);
1140 
1141  beta = beta / coolingFactor_;
1142  thermalize(beta, tks, y, delta_highT_, 0.);
1143  }
1144 
1145 #ifdef DEBUG
1146  verify(y, tks);
1147 
1148  if (DEBUGLEVEL > 0) {
1149  std::cout << "DAClusterizerInZT_vect::vertices :"
1150  << "merging at T=" << 1 / beta << std::endl;
1151  }
1152 #endif
1153 
1154  zorder(y);
1155  set_vtx_range(beta, tks, y);
1156  update(beta, tks, y, rho0); // make sure Tc is up-to-date
1157 
1158  while (merge(y, tks, beta)) {
1159  zorder(y);
1160  set_vtx_range(beta, tks, y);
1161  update(beta, tks, y, rho0);
1162  }
1163 
1164 #ifdef DEBUG
1165  verify(y, tks);
1166  if (DEBUGLEVEL > 0) {
1167  std::cout << "DAClusterizerInZT_vect::vertices :"
1168  << "splitting/merging at T=" << 1 / beta << std::endl;
1169  }
1170 #endif
1171 
1172  unsigned int ntry = 0;
1173  double threshold = 1.0;
1174  while (split(beta, tks, y, threshold) && (ntry++ < 10)) {
1175  thermalize(beta, tks, y, delta_highT_, 0.);
1176 
1177  while (merge(y, tks, beta)) {
1178  if (zorder(y))
1179  set_vtx_range(beta, tks, y);
1180  update(beta, tks, y, rho0);
1181  }
1182 
1183 #ifdef DEBUG
1184  verify(y, tks);
1185 #endif
1186 
1187  // relax splitting a bit to reduce multiple split-merge cycles of the same cluster
1188  threshold *= 1.1;
1189  }
1190 
1191 #ifdef DEBUG
1192  verify(y, tks);
1193  if (DEBUGLEVEL > 0) {
1194  std::cout << "DAClusterizerInZT_vect::vertices :"
1195  << "turning on outlier rejection at T=" << 1 / beta << std::endl;
1196  }
1197 #endif
1198 
1199  // switch on outlier rejection at T=minT
1200  if (dzCutOff_ > 0) {
1201  rho0 = 1. / nt;
1202  for (unsigned int a = 0; a < 5; a++) {
1203  update(beta, tks, y, a * rho0 / 5); // adiabatic turn-on
1204  }
1205  }
1206 
1207  thermalize(beta, tks, y, delta_lowT_, rho0);
1208 
1209 #ifdef DEBUG
1210  verify(y, tks);
1211  if (DEBUGLEVEL > 0) {
1212  std::cout << "DAClusterizerInZT_vect::vertices :"
1213  << "merging with outlier rejection at T=" << 1 / beta << std::endl;
1214  }
1215  if (DEBUGLEVEL > 2)
1216  dump(beta, y, tks, 2);
1217 #endif
1218 
1219  // merge again (some cluster split by outliers collapse here)
1220  zorder(y);
1221  while (merge(y, tks, beta)) {
1222  set_vtx_range(beta, tks, y);
1223  update(beta, tks, y, rho0);
1224  }
1225 
1226 #ifdef DEBUG
1227  if (DEBUGLEVEL > 0) {
1228  std::cout << "DAClusterizerInZT_vect::vertices :"
1229  << "after merging with outlier rejection at T=" << 1 / beta << std::endl;
1230  }
1231  if (DEBUGLEVEL > 1)
1232  dump(beta, y, tks, 2);
1233 #endif
1234 
1235  // go down to the purging temperature (if it is lower than tmin)
1236  while (beta < betapurge_) {
1237  beta = min(beta / coolingFactor_, betapurge_);
1238  thermalize(beta, tks, y, delta_lowT_, rho0);
1239  }
1240 
1241 #ifdef DEBUG
1242  verify(y, tks);
1243  if (DEBUGLEVEL > 0) {
1244  std::cout << "DAClusterizerInZT_vect::vertices :"
1245  << "purging at T=" << 1 / beta << std::endl;
1246  }
1247 #endif
1248 
1249  // eliminate insigificant vertices, this is more restrictive at higher T
1250  while (purge(y, tks, rho0, beta)) {
1251  thermalize(beta, tks, y, delta_lowT_, rho0);
1252  if (zorder(y)) {
1253  set_vtx_range(beta, tks, y);
1254  };
1255  }
1256 
1257 #ifdef DEBUG
1258  verify(y, tks);
1259  if (DEBUGLEVEL > 0) {
1260  std::cout << "DAClusterizerInZT_vect::vertices :"
1261  << "last cooling T=" << 1 / beta << std::endl;
1262  }
1263 #endif
1264 
1265  // optionally cool some more without doing anything, to make the assignment harder
1266  while (beta < betastop_) {
1267  beta = min(beta / coolingFactor_, betastop_);
1268  thermalize(beta, tks, y, delta_lowT_, rho0);
1269  if (zorder(y)) {
1270  set_vtx_range(beta, tks, y);
1271  };
1272  }
1273 
1274 #ifdef DEBUG
1275  verify(y, tks);
1276  if (DEBUGLEVEL > 0) {
1277  std::cout << "DAClusterizerInZT_vect::vertices :"
1278  << "stop cooling at T=" << 1 / beta << std::endl;
1279  }
1280  if (DEBUGLEVEL > 2)
1281  dump(beta, y, tks, 2);
1282 #endif
1283 
1284  // new, merge here and not in "clusterize"
1285  // final merging step
1286  double betadummy = 1;
1287  while (merge(y, tks, betadummy))
1288  ;
1289 
1290  // select significant tracks and use a TransientVertex as a container
1291  GlobalError dummyError(0.01, 0, 0.01, 0., 0., 0.01);
1292 
1293  // ensure correct normalization of probabilities, should makes double assignment reasonably impossible
1294  const unsigned int nv = y.getSize();
1295  for (unsigned int k = 0; k < nv; k++)
1296  if (edm::isNotFinite(y.pk_ptr[k]) || edm::isNotFinite(y.z_ptr[k])) {
1297  y.pk_ptr[k] = 0;
1298  y.z_ptr[k] = 0;
1299  }
1300 
1301  const auto z_sum_init = rho0 * local_exp(-beta * dzCutOff_ * dzCutOff_);
1302  for (unsigned int i = 0; i < nt; i++) // initialize
1303  tks.Z_sum_ptr[i] = z_sum_init;
1304 
1305  // improve vectorization (does not require reduction ....)
1306  for (unsigned int k = 0; k < nv; k++) {
1307  for (unsigned int i = 0; i < nt; i++)
1308  tks.Z_sum_ptr[i] +=
1309  y.pk_ptr[k] *
1310  local_exp(-beta * Eik(tks.z_ptr[i], y.z_ptr[k], tks.dz2_ptr[i], tks.t_ptr[i], y.t_ptr[k], tks.dt2_ptr[i]));
1311  }
1312 
1313  for (unsigned int k = 0; k < nv; k++) {
1314  GlobalPoint pos(0, 0, y.z_ptr[k]);
1315 
1316  vector<reco::TransientTrack> vertexTracks;
1317  for (unsigned int i = 0; i < nt; i++) {
1318  if (tks.Z_sum_ptr[i] > 1e-100) {
1319  double p =
1320  y.pk_ptr[k] *
1321  local_exp(-beta * Eik(tks.z_ptr[i], y.z_ptr[k], tks.dz2_ptr[i], tks.t_ptr[i], y.t_ptr[k], tks.dt2_ptr[i])) /
1322  tks.Z_sum_ptr[i];
1323  if ((tks.pi_ptr[i] > 0) && (p > mintrkweight_)) {
1324  vertexTracks.push_back(*(tks.tt[i]));
1325  tks.Z_sum_ptr[i] = 0; // setting Z=0 excludes double assignment
1326  }
1327  }
1328  }
1329  TransientVertex v(pos, y.t_ptr[k], dummyError, vertexTracks, 0);
1330  clusters.push_back(v);
1331  }
1332 
1333  return clusters;
1334 }
1335 
1336 vector<vector<reco::TransientTrack> > DAClusterizerInZT_vect::clusterize(
1337  const vector<reco::TransientTrack>& tracks) const {
1338  vector<vector<reco::TransientTrack> > clusters;
1339  vector<TransientVertex>&& pv = vertices(tracks);
1340 
1341 #ifdef DEBUG
1342  if (DEBUGLEVEL > 0) {
1343  std::cout << "###################################################" << endl;
1344  std::cout << "# vectorized DAClusterizerInZT_vect::clusterize nt=" << tracks.size() << endl;
1345  std::cout << "# DAClusterizerInZT_vect::clusterize pv.size=" << pv.size() << endl;
1346  std::cout << "###################################################" << endl;
1347  }
1348 #endif
1349 
1350  if (pv.empty()) {
1351  return clusters;
1352  }
1353 
1354  // fill into clusters, don't merge
1355  for (auto k = pv.begin(); k != pv.end(); k++) {
1356  vector<reco::TransientTrack> aCluster = k->originalTracks();
1357  if (aCluster.size() > 1) {
1358  clusters.push_back(aCluster);
1359  }
1360  }
1361 
1362  return clusters;
1363 }
1364 
1365 void DAClusterizerInZT_vect::dump(const double beta, const vertex_t& y, const track_t& tks, int verbosity) const {
1366 #ifdef DEBUG
1367  const unsigned int nv = y.getSize();
1368  const unsigned int nt = tks.getSize();
1369 
1370  std::vector<unsigned int> iz;
1371  for (unsigned int j = 0; j < nt; j++) {
1372  iz.push_back(j);
1373  }
1374  std::sort(iz.begin(), iz.end(), [tks](unsigned int a, unsigned int b) { return tks.z_ptr[a] < tks.z_ptr[b]; });
1375  std::cout << std::endl;
1376  std::cout << "-----DAClusterizerInZT::dump ----" << nv << " clusters " << std::endl;
1377  string h = " ";
1378  std::cout << h << " k= ";
1379  for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1380  if (std::fabs(y.z_ptr[ivertex] - zdumpcenter_) < zdumpwidth_) {
1381  std::cout << setw(8) << fixed << ivertex;
1382  }
1383  }
1384  std::cout << endl;
1385 
1386  std::cout << h << " z= ";
1387  std::cout << setprecision(4);
1388  for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1389  if (std::fabs(y.z_ptr[ivertex] - zdumpcenter_) < zdumpwidth_) {
1390  std::cout << setw(8) << fixed << y.z_ptr[ivertex];
1391  }
1392  }
1393  std::cout << endl;
1394 
1395  std::cout << h << " t= ";
1396  std::cout << setprecision(4);
1397  for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1398  if (std::fabs(y.z_ptr[ivertex] - zdumpcenter_) < zdumpwidth_) {
1399  std::cout << setw(8) << fixed << y.t_ptr[ivertex];
1400  }
1401  }
1402  std::cout << endl;
1403 
1404  std::cout << "T=" << setw(15) << 1. / beta << " Tmin =" << setw(10) << 1. / betamax_
1405  << " Tc= ";
1406  for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1407  if (std::fabs(y.z_ptr[ivertex] - zdumpcenter_) < zdumpwidth_) {
1408  double Tc = get_Tc(y, ivertex);
1409  std::cout << setw(8) << fixed << setprecision(1) << Tc;
1410  }
1411  }
1412  std::cout << endl;
1413 
1414  std::cout << h << "pk= ";
1415  double sumpk = 0;
1416  for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1417  sumpk += y.pk_ptr[ivertex];
1418  if (std::fabs(y.z_ptr[ivertex] - zdumpcenter_) > zdumpwidth_)
1419  continue;
1420  std::cout << setw(8) << setprecision(4) << fixed << y.pk_ptr[ivertex];
1421  }
1422  std::cout << endl;
1423 
1424  std::cout << h << "nt= ";
1425  for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1426  sumpk += y.pk_ptr[ivertex];
1427  if (std::fabs(y.z_ptr[ivertex] - zdumpcenter_) > zdumpwidth_)
1428  continue;
1429  std::cout << setw(8) << setprecision(1) << fixed << y.pk_ptr[ivertex] * nt;
1430  }
1431  std::cout << endl;
1432 
1433  if (verbosity > 0) {
1434  double E = 0, F = 0;
1435  std::cout << endl;
1436  std::cout << "---- z +/- dz t +/- dt ip +/-dip pt phi eta weights ----"
1437  << endl;
1438  std::cout << setprecision(4);
1439  for (unsigned int i0 = 0; i0 < nt; i0++) {
1440  unsigned int i = iz[i0];
1441  if (tks.Z_sum_ptr[i] > 0) {
1442  F -= std::log(tks.Z_sum_ptr[i]) / beta;
1443  }
1444  double tz = tks.z_ptr[i];
1445 
1446  if (std::fabs(tz - zdumpcenter_) > zdumpwidth_)
1447  continue;
1448  std::cout << setw(4) << i << ")" << setw(8) << fixed << setprecision(4) << tz << " +/-" << setw(6)
1449  << sqrt(1. / tks.dz2_ptr[i]);
1450 
1451  if (tks.dt2_ptr[i] > 0) {
1452  std::cout << setw(8) << fixed << setprecision(4) << tks.t_ptr[i] << " +/-" << setw(6)
1453  << sqrt(1. / tks.dt2_ptr[i]);
1454  } else {
1455  std::cout << " ";
1456  }
1457 
1458  if (tks.tt[i]->track().quality(reco::TrackBase::highPurity)) {
1459  std::cout << " *";
1460  } else {
1461  std::cout << " ";
1462  }
1463  if (tks.tt[i]->track().hitPattern().hasValidHitInPixelLayer(PixelSubdetector::SubDetector::PixelBarrel, 1)) {
1464  std::cout << "+";
1465  } else {
1466  std::cout << "-";
1467  }
1468  std::cout << setw(1)
1469  << tks.tt[i]
1470  ->track()
1471  .hitPattern()
1472  .pixelBarrelLayersWithMeasurement(); // see DataFormats/TrackReco/interface/HitPattern.h
1473  std::cout << setw(1) << tks.tt[i]->track().hitPattern().pixelEndcapLayersWithMeasurement();
1474  std::cout << setw(1) << hex
1475  << tks.tt[i]->track().hitPattern().trackerLayersWithMeasurement() -
1476  tks.tt[i]->track().hitPattern().pixelLayersWithMeasurement()
1477  << dec;
1478  std::cout << "=" << setw(1) << hex
1479  << tks.tt[i]->track().hitPattern().numberOfLostHits(reco::HitPattern::MISSING_OUTER_HITS) << dec;
1480 
1481  Measurement1D IP = tks.tt[i]->stateAtBeamLine().transverseImpactParameter();
1482  std::cout << setw(8) << IP.value() << "+/-" << setw(6) << IP.error();
1483  std::cout << " " << setw(6) << setprecision(2) << tks.tt[i]->track().pt() * tks.tt[i]->track().charge();
1484  std::cout << " " << setw(5) << setprecision(2) << tks.tt[i]->track().phi() << " " << setw(5) << setprecision(2)
1485  << tks.tt[i]->track().eta();
1486 
1487  double sump = 0.;
1488  for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1489  if (std::fabs(y.z_ptr[ivertex] - zdumpcenter_) > zdumpwidth_)
1490  continue;
1491 
1492  if ((tks.pi_ptr[i] > 0) && (tks.Z_sum_ptr[i] > 0)) {
1493  double p =
1494  y.pk_ptr[ivertex] *
1495  local_exp(
1496  -beta *
1497  Eik(tks.z_ptr[i], y.z_ptr[ivertex], tks.dz2_ptr[i], tks.t_ptr[i], y.t_ptr[ivertex], tks.dt2_ptr[i])) /
1498  tks.Z_sum_ptr[i];
1499 
1500  if ((ivertex >= tks.kmin[i]) && (ivertex < tks.kmax[i])) {
1501  if (p > 0.0001) {
1502  std::cout << setw(8) << setprecision(3) << p;
1503  } else {
1504  std::cout << " _ "; // tiny but in the cluster list
1505  }
1506  E +=
1507  p * Eik(tks.z_ptr[i], y.z_ptr[ivertex], tks.dz2_ptr[i], tks.t_ptr[i], y.t_ptr[ivertex], tks.dt2_ptr[i]);
1508  sump += p;
1509  } else {
1510  if (p > 0.1) {
1511  std::cout << "XXXXXXXX"; // we have an inconsistency here
1512  } else if (p > 0.0001) {
1513  std::cout << "X" << setw(6) << setprecision(3) << p << "X";
1514  } else {
1515  std::cout << " . "; // not in the cluster list
1516  }
1517  }
1518  } else {
1519  std::cout << " ";
1520  }
1521  }
1522  std::cout << " ( " << std::setw(3) << tks.kmin[i] << "," << std::setw(3) << tks.kmax[i] - 1 << " ) ";
1523  std::cout << endl;
1524  }
1525  std::cout << " ";
1526  for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1527  if (std::fabs(y.z_ptr[ivertex] - zdumpcenter_) < zdumpwidth_) {
1528  std::cout << " " << setw(3) << ivertex << " ";
1529  }
1530  }
1531  std::cout << endl;
1532  std::cout << " z= ";
1533  std::cout << setprecision(4);
1534  for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1535  if (std::fabs(y.z_ptr[ivertex] - zdumpcenter_) < zdumpwidth_) {
1536  std::cout << setw(8) << fixed << y.z_ptr[ivertex];
1537  }
1538  }
1539  std::cout << endl;
1540  std::cout << endl
1541  << "T=" << 1 / beta << " E=" << E << " n=" << y.getSize() << " F= " << F << endl
1542  << "----------" << endl;
1543  }
1544 #endif
1545 }
DAClusterizerInZT_vect::track_t::kmin
std::vector< unsigned int > kmin
Definition: DAClusterizerInZT_vect.h:66
DAClusterizerInZT_vect::vertex_t::szt_ptr
double * szt_ptr
Definition: DAClusterizerInZT_vect.h:219
DAClusterizerInZT_vect::vertex_t::stt_ptr
double * stt_ptr
Definition: DAClusterizerInZT_vect.h:218
DAClusterizerInZT_vect::vertex_t::swz_ptr
double * swz_ptr
Definition: DAClusterizerInZT_vect.h:214
DAClusterizerInZT_vect::track_t::Z_sum_ptr
double * Z_sum_ptr
Definition: DAClusterizerInZT_vect.h:58
HIPAlignmentAlgorithm_cfi.verbosity
verbosity
Definition: HIPAlignmentAlgorithm_cfi.py:7
RandomServiceHelper.t2
t2
Definition: RandomServiceHelper.py:257
reco::HitPattern::MISSING_OUTER_HITS
Definition: HitPattern.h:155
alignBH_cfg.fixed
fixed
Definition: alignBH_cfg.py:54
DAClusterizerInZT_vect::vertex_t::nut_ptr
double * nut_ptr
Definition: DAClusterizerInZT_vect.h:221
PDWG_EXOHSCP_cff.tracks
tracks
Definition: PDWG_EXOHSCP_cff.py:28
Measurement1D
Definition: Measurement1D.h:11
mps_fire.i
i
Definition: mps_fire.py:428
HLT_FULL_cff.atIP
atIP
Definition: HLT_FULL_cff.py:46139
DAClusterizerInZT_vect::track_t::pi
std::vector< double > pi
Definition: DAClusterizerInZT_vect.h:65
MessageLogger.h
TkClusParameters_cff.zrange
zrange
Definition: TkClusParameters_cff.py:7
reco::ParticleMasses::k0
const double k0
Definition: ParticleMasses.h:7
edm::isNotFinite
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
nt
int nt
Definition: AMPTWrapper.h:42
min
T min(T a, T b)
Definition: MathUtil.h:58
DAClusterizerInZT_vect::vertex_t::ei_cache_ptr
double * ei_cache_ptr
Definition: DAClusterizerInZT_vect.h:212
DAClusterizerInZT_vect::track_t::z_ptr
double * z_ptr
Definition: DAClusterizerInZT_vect.h:52
DAClusterizerInZT_vect::track_t::dz2
std::vector< double > dz2
Definition: DAClusterizerInZT_vect.h:62
DAClusterizerInZT_vect::vertices
std::vector< TransientVertex > vertices(const std::vector< reco::TransientTrack > &tracks, const int verbosity=0) const
Definition: DAClusterizerInZT_vect.cc:1101
zMuMuMuonUserData.beta
beta
Definition: zMuMuMuonUserData.py:10
DAClusterizerInZT_vect::track_t::t
std::vector< double > t
Definition: DAClusterizerInZT_vect.h:61
AlCaHLTBitMon_ParallelJobs.p
p
Definition: AlCaHLTBitMon_ParallelJobs.py:153
DAClusterizerInZT_vect::track_t::getSize
unsigned int getSize() const
Definition: DAClusterizerInZT_vect.h:40
gather_cfg.cout
cout
Definition: gather_cfg.py:144
pos
Definition: PixelAliasList.h:18
AlignmentPI::t_z
Definition: AlignmentPayloadInspectorHelper.h:36
Measurement1D.h
cms::cuda::assert
assert(be >=bs)
edm::second
U second(std::pair< T, U > const &p)
Definition: ParameterSet.cc:222
edm::ParameterSet::getUntrackedParameter
T getUntrackedParameter(std::string const &, T const &) const
DAClusterizerInZT_vect::purge
bool purge(vertex_t &, track_t &, double &, const double) const
Definition: DAClusterizerInZT_vect.cc:742
edm::LogInfo
Log< level::Info, false > LogInfo
Definition: MessageLogger.h:125
findQualityFiles.v
v
Definition: findQualityFiles.py:179
SiStripMonitorCluster_cfi.zmin
zmin
Definition: SiStripMonitorCluster_cfi.py:200
DAClusterizerInZT_vect::vertex_t::ei_ptr
double * ei_ptr
Definition: DAClusterizerInZT_vect.h:213
edm::LogWarning
Log< level::Warning, false > LogWarning
Definition: MessageLogger.h:122
DAClusterizerInZT_vect::get_Tc
double get_Tc(const vertex_t &y, int k) const
Definition: DAClusterizerInZT_vect.cc:885
DAClusterizerInZT_vect::DAClusterizerInZT_vect
DAClusterizerInZT_vect(const edm::ParameterSet &conf)
Definition: DAClusterizerInZT_vect.cc:22
DAClusterizerInZT_vect::track_t::t_ptr
double * t_ptr
Definition: DAClusterizerInZT_vect.h:53
geometryDiff.epsilon
int epsilon
Definition: geometryDiff.py:26
DAClusterizerInZT_vect::track_t::Z_sum
std::vector< double > Z_sum
Definition: DAClusterizerInZT_vect.h:64
F
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:163
funct::sin
Sin< T >::type sin(const T &t)
Definition: Sin.h:22
testProducerWithPsetDescEmpty_cfi.z2
z2
Definition: testProducerWithPsetDescEmpty_cfi.py:41
dt
float dt
Definition: AMPTWrapper.h:136
GeomDetEnumerators::PixelBarrel
Definition: GeomDetEnumerators.h:11
RandomServiceHelper.t1
t1
Definition: RandomServiceHelper.py:256
DAClusterizerInZT_vect::vertex_t::se_ptr
double * se_ptr
Definition: DAClusterizerInZT_vect.h:216
DAClusterizerInZT_vect::split
bool split(const double beta, track_t &t, vertex_t &y, double threshold=1.) const
Definition: DAClusterizerInZT_vect.cc:896
funct::cos
Cos< T >::type cos(const T &t)
Definition: Cos.h:22
h
DAClusterizerInZT_vect::track_t::dt2
std::vector< double > dt2
Definition: DAClusterizerInZT_vect.h:63
SiStripMonitorCluster_cfi.zmax
zmax
Definition: SiStripMonitorCluster_cfi.py:201
submitPVValidationJobs.split
def split(sequence, size)
Definition: submitPVValidationJobs.py:352
w
const double w
Definition: UKUtility.cc:23
DAClusterizerInZT_vect::track_t::dz2_ptr
double * dz2_ptr
Definition: DAClusterizerInZT_vect.h:56
DAClusterizerInZT_vect::vertex_t::szz_ptr
double * szz_ptr
Definition: DAClusterizerInZT_vect.h:217
mathSSE::sqrt
T sqrt(T t)
Definition: SSEVec.h:19
reco::BeamSpot
Definition: BeamSpot.h:21
p2
double p2[4]
Definition: TauolaWrapper.h:90
DAClusterizerInZT_vect::vertex_t::z_ptr
double * z_ptr
Definition: DAClusterizerInZT_vect.h:206
beamspot
Definition: BeamSpotWrite2Txt.h:8
DAClusterizerInZT_vect::vertex_t::swt_ptr
double * swt_ptr
Definition: DAClusterizerInZT_vect.h:215
DAClusterizerInZT_vect::track_t::dt2_ptr
double * dt2_ptr
Definition: DAClusterizerInZT_vect.h:57
HLTMuonOfflineAnalyzer_cfi.z0
z0
Definition: HLTMuonOfflineAnalyzer_cfi.py:98
dqmdumpme.k
k
Definition: dqmdumpme.py:60
DAClusterizerInZT_vect::beta0
double beta0(const double betamax, track_t const &tks, vertex_t const &y) const
Definition: DAClusterizerInZT_vect.cc:818
Point3DBase< float, GlobalTag >
b
double b
Definition: hdecay.h:118
DAClusterizerInZT_vect::zorder
bool zorder(vertex_t &y) const
Definition: DAClusterizerInZT_vect.cc:538
mitigatedMETSequence_cff.U
U
Definition: mitigatedMETSequence_cff.py:36
DAClusterizerInZT_vect::track_t
Definition: DAClusterizerInZT_vect.h:25
bsc_activity_cfg.clusters
clusters
Definition: bsc_activity_cfg.py:36
listHistos.IP
IP
Definition: listHistos.py:76
ntuplemaker.fill
fill
Definition: ntuplemaker.py:304
DAClusterizerInZT_vect::set_vtx_range
void set_vtx_range(double beta, track_t &gtracks, vertex_t &gvertices) const
Definition: DAClusterizerInZT_vect.cc:285
DAClusterizerInZT_vect::fill
track_t fill(const std::vector< reco::TransientTrack > &tracks) const
Definition: DAClusterizerInZT_vect.cc:214
edm::ParameterSet
Definition: ParameterSet.h:47
q1
double q1[4]
Definition: TauolaWrapper.h:87
a
double a
Definition: hdecay.h:119
DAClusterizerInZT_vect::verify
void verify(const vertex_t &v, const track_t &tks, unsigned int nv=999999, unsigned int nt=999999) const
Definition: DAClusterizerInZT_vect.cc:121
DAClusterizerInZT_vect::vertex_t
Definition: DAClusterizerInZT_vect.h:71
SiStripPI::max
Definition: SiStripPayloadInspectorHelper.h:169
dumpMFGeometry_cfg.delta
delta
Definition: dumpMFGeometry_cfg.py:25
DAClusterizerInZT_vect::merge
bool merge(vertex_t &, track_t &, double &beta) const
Definition: DAClusterizerInZT_vect.cc:683
DAClusterizerInZT_vect::track_t::addItem
void addItem(double new_z, double new_t, double new_dz2, double new_dt2, const reco::TransientTrack *new_tt, double new_pi)
Definition: DAClusterizerInZT_vect.h:26
FrontierConditions_GlobalTag_cff.dump
dump
Definition: FrontierConditions_GlobalTag_cff.py:12
createfilelist.int
int
Definition: createfilelist.py:10
MetAnalyzer.pv
def pv(vc)
Definition: MetAnalyzer.py:7
DAClusterizerInZT_vect.h
hlt_jetmet_dqm_QT_fromfile_cfg.critical
critical
Definition: hlt_jetmet_dqm_QT_fromfile_cfg.py:109
p1
double p1[4]
Definition: TauolaWrapper.h:89
GlobalErrorBase< double, ErrorMatrixTag >
TransientVertex
Definition: TransientVertex.h:18
DAClusterizerInZT_vect::vertex_t::getSize
unsigned int getSize() const
Definition: DAClusterizerInZT_vect.h:94
DAClusterizerInZT_vect::vertex_t::sumw_ptr
double * sumw_ptr
Definition: DAClusterizerInZT_vect.h:210
cms::cuda::for
for(int i=first, nt=offsets[nh];i< nt;i+=gridDim.x *blockDim.x)
Definition: HistoContainer.h:27
DAClusterizerInZT_vect::dump
void dump(const double beta, const vertex_t &y, const track_t &tks, const int verbosity=0) const
Definition: DAClusterizerInZT_vect.cc:1365
funct::D
DecomposeProduct< arg, typename Div::arg > D
Definition: Factorize.h:141
DAClusterizerInZT_vect::track_t::pi_ptr
double * pi_ptr
Definition: DAClusterizerInZT_vect.h:54
DAClusterizerInZT_vect::update
double update(double beta, track_t &gtracks, vertex_t &gvertices, const double rho0=0) const
Definition: DAClusterizerInZT_vect.cc:351
DAClusterizerInZT_vect::clusterize
std::vector< std::vector< reco::TransientTrack > > clusterize(const std::vector< reco::TransientTrack > &tracks) const override
Definition: DAClusterizerInZT_vect.cc:1336
DAClusterizerInZT_vect::vertex_t::nuz_ptr
double * nuz_ptr
Definition: DAClusterizerInZT_vect.h:220
std
Definition: JetResolutionObject.h:76
isFinite.h
PVValHelper::dz
Definition: PVValidationHelpers.h:50
DAClusterizerInZT_vect::track_t::extractRaw
void extractRaw()
Definition: DAClusterizerInZT_vect.h:43
DAClusterizerInZT_vect::track_t::z
std::vector< double > z
Definition: DAClusterizerInZT_vect.h:60
edm::ParameterSet::getParameter
T getParameter(std::string const &) const
Definition: ParameterSet.h:303
VertexException.h
dqm-mbProfile.log
log
Definition: dqm-mbProfile.py:17
funct::arg
A arg
Definition: Factorize.h:31
funct::pow
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
DAClusterizerInZT_vect::clear_vtx_range
void clear_vtx_range(track_t &gtracks, vertex_t &gvertices) const
Definition: DAClusterizerInZT_vect.cc:342
math::cholesky::dst
M2 & dst
Definition: choleskyInversion.h:158
funct::abs
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
dqmiolumiharvest.j
j
Definition: dqmiolumiharvest.py:66
DAClusterizerInZT_vect::track_t::tt
std::vector< const reco::TransientTrack * > tt
Definition: DAClusterizerInZT_vect.h:68
remoteMonitoring_LED_IterMethod_cfg.threshold
threshold
Definition: remoteMonitoring_LED_IterMethod_cfg.py:426
MatrixUtil.merge
def merge(dictlist, TELL=False)
Definition: MatrixUtil.py:201
DAClusterizerInZT_vect::thermalize
unsigned int thermalize(double beta, track_t &gtracks, vertex_t &gvertices, const double delta_max, const double rho0=0.) const
Definition: DAClusterizerInZT_vect.cc:632
DAClusterizerInZT_vect::track_t::kmax
std::vector< unsigned int > kmax
Definition: DAClusterizerInZT_vect.h:67
submitPVValidationJobs.t
string t
Definition: submitPVValidationJobs.py:644
TauDecayModes.dec
dec
Definition: TauDecayModes.py:143
DAClusterizerInZT_vect::find_nearest
bool find_nearest(double z, double t, vertex_t &y, unsigned int &k_min, double dz, double dt) const
Definition: DAClusterizerInZT_vect.cc:586
update
#define update(a, b)
Definition: TrackClassifier.cc:10
pwdgSkimBPark_cfi.vertices
vertices
Definition: pwdgSkimBPark_cfi.py:7
MillePedeFileConverter_cfg.e
e
Definition: MillePedeFileConverter_cfg.py:37
reco::TrackBase::highPurity
Definition: TrackBase.h:154