File indexing completed on 2024-06-25 22:35:19
0001 #include "RecoVertex/PrimaryVertexProducer/interface/DAClusterizerInZT_vect.h"
0002 #include "RecoVertex/PrimaryVertexProducer/interface/DAClusterizerInZ_vect.h"
0003 #include "FWCore/MessageLogger/interface/MessageLogger.h"
0004 #include "DataFormats/GeometryCommonDetAlgo/interface/Measurement1D.h"
0005 #include "RecoVertex/VertexPrimitives/interface/VertexException.h"
0006
0007 #include <cmath>
0008 #include <cassert>
0009 #include <limits>
0010 #include <iomanip>
0011 #include "FWCore/Utilities/interface/isFinite.h"
0012 #include "vdt/vdtMath.h"
0013
0014 using namespace std;
0015
0016
0017 #ifdef DEBUG
0018 #define DEBUGLEVEL 0
0019 #endif
0020
0021 DAClusterizerInZT_vect::DAClusterizerInZT_vect(const edm::ParameterSet& conf) {
0022
0023 maxIterations_ = 1000;
0024 mintrkweight_ = 0.5;
0025
0026
0027 #ifdef DEBUG
0028 zdumpcenter_ = conf.getUntrackedParameter<double>("zdumpcenter", 0.);
0029 zdumpwidth_ = conf.getUntrackedParameter<double>("zdumpwidth", 20.);
0030 #endif
0031
0032
0033 double minT = conf.getParameter<double>("Tmin");
0034 double purgeT = conf.getParameter<double>("Tpurge");
0035 double stopT = conf.getParameter<double>("Tstop");
0036 vertexSize_ = conf.getParameter<double>("vertexSize");
0037 vertexSizeTime_ = conf.getParameter<double>("vertexSizeTime");
0038 coolingFactor_ = conf.getParameter<double>("coolingFactor");
0039 d0CutOff_ = conf.getParameter<double>("d0CutOff");
0040 dzCutOff_ = conf.getParameter<double>("dzCutOff");
0041 dtCutOff_ = conf.getParameter<double>("dtCutOff");
0042 t0Max_ = conf.getParameter<double>("t0Max");
0043 uniquetrkweight_ = conf.getParameter<double>("uniquetrkweight");
0044 uniquetrkminp_ = conf.getParameter<double>("uniquetrkminp");
0045 zmerge_ = conf.getParameter<double>("zmerge");
0046 tmerge_ = conf.getParameter<double>("tmerge");
0047 sel_zrange_ = conf.getParameter<double>("zrange");
0048 convergence_mode_ = conf.getParameter<int>("convergence_mode");
0049 delta_lowT_ = conf.getParameter<double>("delta_lowT");
0050 delta_highT_ = conf.getParameter<double>("delta_highT");
0051
0052 #ifdef DEBUG
0053 std::cout << "DAClusterizerInZT_vect: mintrkweight = " << mintrkweight_ << std::endl;
0054 std::cout << "DAClusterizerInZT_vect: uniquetrkweight = " << uniquetrkweight_ << std::endl;
0055 std::cout << "DAClusterizerInZT_vect: uniquetrkminp = " << uniquetrkminp_ << std::endl;
0056 std::cout << "DAClusterizerInZT_vect: zmerge = " << zmerge_ << std::endl;
0057 std::cout << "DAClusterizerInZT_vect: tmerge = " << tmerge_ << std::endl;
0058 std::cout << "DAClusterizerInZT_vect: Tmin = " << minT << std::endl;
0059 std::cout << "DAClusterizerInZT_vect: Tpurge = " << purgeT << std::endl;
0060 std::cout << "DAClusterizerInZT_vect: Tstop = " << stopT << std::endl;
0061 std::cout << "DAClusterizerInZT_vect: vertexSize = " << vertexSize_ << std::endl;
0062 std::cout << "DAClusterizerInZT_vect: vertexSizeTime = " << vertexSizeTime_ << std::endl;
0063 std::cout << "DAClusterizerInZT_vect: coolingFactor = " << coolingFactor_ << std::endl;
0064 std::cout << "DAClusterizerInZT_vect: d0CutOff = " << d0CutOff_ << std::endl;
0065 std::cout << "DAClusterizerInZT_vect: dzCutOff = " << dzCutOff_ << std::endl;
0066 std::cout << "DAClusterizerInZT_vect: dtCutoff = " << dtCutOff_ << std::endl;
0067 std::cout << "DAClusterizerInZT_vect: zrange = " << sel_zrange_ << std::endl;
0068 std::cout << "DAClusterizerinZT_vect: convergence mode = " << convergence_mode_ << std::endl;
0069 std::cout << "DAClusterizerinZT_vect: delta_highT = " << delta_highT_ << std::endl;
0070 std::cout << "DAClusterizerinZT_vect: delta_lowT = " << delta_lowT_ << std::endl;
0071 std::cout << "DAClusterizerinZT_vect: DEBUGLEVEL " << DEBUGLEVEL << std::endl;
0072 #endif
0073
0074 if (convergence_mode_ > 1) {
0075 edm::LogWarning("DAClusterizerinZT_vect")
0076 << "DAClusterizerInZT_vect: invalid convergence_mode " << convergence_mode_ << " reset to default " << 0;
0077 convergence_mode_ = 0;
0078 }
0079
0080 if (minT == 0) {
0081 betamax_ = 1.0;
0082 edm::LogWarning("DAClusterizerinZT_vect")
0083 << "DAClusterizerInZT_vect: invalid Tmin " << minT << " reset to default " << 1. / betamax_;
0084 } else {
0085 betamax_ = 1. / minT;
0086 }
0087
0088 if ((purgeT > minT) || (purgeT == 0)) {
0089 edm::LogWarning("DAClusterizerinZT_vect")
0090 << "DAClusterizerInZT_vect: invalid Tpurge " << purgeT << " set to " << minT;
0091 purgeT = minT;
0092 }
0093 betapurge_ = 1. / purgeT;
0094
0095 if ((stopT > purgeT) || (stopT == 0)) {
0096 edm::LogWarning("DAClusterizerinZT_vect")
0097 << "DAClusterizerInZT_vect: invalid Tstop " << stopT << " set to " << max(1., purgeT);
0098 stopT = max(1., purgeT);
0099 }
0100 betastop_ = 1. / stopT;
0101 }
0102
0103 namespace {
0104 inline double local_exp(double const& inp) { return vdt::fast_exp(inp); }
0105
0106 inline void local_exp_list_range(double const* __restrict__ arg_inp,
0107 double* __restrict__ arg_out,
0108 const int kmin,
0109 const int kmax) {
0110 for (auto i = kmin; i != kmax; ++i)
0111 arg_out[i] = vdt::fast_exp(arg_inp[i]);
0112 }
0113
0114 }
0115
0116 void DAClusterizerInZT_vect::verify(const vertex_t& v, const track_t& tks, unsigned int nv, unsigned int nt) const {
0117 if (nv == 999999) {
0118 nv = v.getSize();
0119 } else {
0120 assert(nv == v.getSize());
0121 }
0122
0123 if (nt == 999999) {
0124 nt = tks.getSize();
0125 } else {
0126 assert(nt == tks.getSize());
0127 }
0128
0129
0130 assert(v.zvtx_vec.size() == nv);
0131 assert(v.tvtx_vec.size() == nv);
0132 #ifdef USEVTXDT2
0133 assert(v.dt2_vec.size() == nv);
0134 assert(v.sumw_vec.size() == nv);
0135 #endif
0136 assert(v.rho_vec.size() == nv);
0137 assert(v.swz_vec.size() == nv);
0138 assert(v.swt_vec.size() == nv);
0139 assert(v.exp_arg_vec.size() == nv);
0140 assert(v.exp_vec.size() == nv);
0141 assert(v.se_vec.size() == nv);
0142 assert(v.nuz_vec.size() == nv);
0143 assert(v.nut_vec.size() == nv);
0144 assert(v.szz_vec.size() == nv);
0145 assert(v.stt_vec.size() == nv);
0146 assert(v.szt_vec.size() == nv);
0147
0148 assert(v.zvtx == &v.zvtx_vec.front());
0149 assert(v.tvtx == &v.tvtx_vec.front());
0150 assert(v.rho == &v.rho_vec.front());
0151 assert(v.exp_arg == &v.exp_arg_vec.front());
0152 assert(v.swz == &v.swz_vec.front());
0153 assert(v.swt == &v.swt_vec.front());
0154 assert(v.se == &v.se_vec.front());
0155 assert(v.nuz == &v.nuz_vec.front());
0156 assert(v.nut == &v.nut_vec.front());
0157 assert(v.szz == &v.szz_vec.front());
0158 assert(v.stt == &v.stt_vec.front());
0159 assert(v.szt == &v.szt_vec.front());
0160 #ifdef USEVTXDT2
0161 assert(v.sumw == &v.sumw_vec.front());
0162 assert(v.dt2 == &v.dt2_vec.front());
0163 #endif
0164
0165 for (unsigned int k = 0; k < nv - 1; k++) {
0166 if (v.zvtx[k] <= v.zvtx[k + 1])
0167 continue;
0168 cout << " ZT, cluster z-ordering assertion failure z[" << k << "] =" << v.zvtx[k] << " z[" << k + 1
0169 << "] =" << v.zvtx[k + 1] << endl;
0170 }
0171
0172
0173
0174
0175
0176 assert(nt == tks.zpca_vec.size());
0177 assert(nt == tks.tpca_vec.size());
0178 assert(nt == tks.dz2_vec.size());
0179 assert(nt == tks.dt2_vec.size());
0180 assert(nt == tks.tt.size());
0181 assert(nt == tks.tkwt_vec.size());
0182 assert(nt == tks.sum_Z_vec.size());
0183 assert(nt == tks.kmin.size());
0184 assert(nt == tks.kmax.size());
0185
0186 assert(tks.zpca == &tks.zpca_vec.front());
0187 assert(tks.tpca == &tks.tpca_vec.front());
0188 assert(tks.dz2 == &tks.dz2_vec.front());
0189 assert(tks.dt2 == &tks.dt2_vec.front());
0190 assert(tks.tkwt == &tks.tkwt_vec.front());
0191 assert(tks.sum_Z == &tks.sum_Z_vec.front());
0192
0193 for (unsigned int i = 0; i < nt; i++) {
0194 if ((tks.kmin[i] < tks.kmax[i]) && (tks.kmax[i] <= nv))
0195 continue;
0196 cout << "track vertex range assertion failure" << i << "/" << nt << " kmin,kmax=" << tks.kmin[i] << ", "
0197 << tks.kmax[i] << " nv=" << nv << endl;
0198 }
0199
0200 for (unsigned int i = 0; i < nt; i++) {
0201 assert((tks.kmin[i] < tks.kmax[i]) && (tks.kmax[i] <= nv));
0202 }
0203 }
0204
0205
0206 DAClusterizerInZT_vect::track_t DAClusterizerInZT_vect::fill(const vector<reco::TransientTrack>& tracks) const {
0207
0208 track_t tks;
0209 double sumtkwt = 0.;
0210
0211 for (const auto& tk : tracks) {
0212 if (!tk.isValid())
0213 continue;
0214 double t_tkwt = 1.;
0215 double t_z = tk.stateAtBeamLine().trackStateAtPCA().position().z();
0216 double t_t = tk.timeExt();
0217
0218 if (std::fabs(t_z) > 1000.)
0219 continue;
0220
0221
0222
0223
0224
0225 auto const& t_mom = tk.stateAtBeamLine().trackStateAtPCA().momentum();
0226
0227 reco::BeamSpot beamspot = tk.stateAtBeamLine().beamSpot();
0228 double t_dz2 = std::pow(tk.track().dzError(), 2)
0229 + (std::pow(beamspot.BeamWidthX() * t_mom.x(), 2) + std::pow(beamspot.BeamWidthY() * t_mom.y(), 2)) *
0230 std::pow(t_mom.z(), 2) / std::pow(t_mom.perp2(), 2)
0231 + std::pow(vertexSize_, 2);
0232 t_dz2 = 1. / t_dz2;
0233 if (edm::isNotFinite(t_dz2) || t_dz2 < std::numeric_limits<double>::min()) {
0234 edm::LogWarning("DAClusterizerinZT_vect") << "rejected track t_dz2 " << t_dz2;
0235 continue;
0236 }
0237
0238 double t_dt2 =
0239 std::pow(tk.dtErrorExt(), 2.) +
0240 std::pow(vertexSizeTime_, 2.);
0241 if ((tk.dtErrorExt() >= TransientTrackBuilder::defaultInvalidTrackTimeReso) || (std::abs(t_t) > t0Max_)) {
0242 t_dt2 = 0;
0243 } else {
0244 t_dt2 = 1. / t_dt2;
0245 if (edm::isNotFinite(t_dt2) || t_dt2 < std::numeric_limits<double>::min()) {
0246 edm::LogWarning("DAClusterizerinZT_vect") << "rejected track t_dt2 " << t_dt2;
0247 continue;
0248 }
0249 }
0250
0251 if (d0CutOff_ > 0) {
0252 Measurement1D atIP = tk.stateAtBeamLine().transverseImpactParameter();
0253 t_tkwt = 1. / (1. + local_exp(std::pow(atIP.value() / atIP.error(), 2) -
0254 std::pow(d0CutOff_, 2)));
0255 if (edm::isNotFinite(t_tkwt) || t_tkwt < std::numeric_limits<double>::epsilon()) {
0256 edm::LogWarning("DAClusterizerinZT_vect") << "rejected track t_tkwt " << t_tkwt;
0257 continue;
0258 }
0259 }
0260
0261 tks.addItem(t_z, t_t, t_dz2, t_dt2, &tk, t_tkwt);
0262 sumtkwt += t_tkwt;
0263 }
0264
0265 if (sumtkwt > 0) {
0266 tks.extractRaw();
0267 tks.osumtkwt = 1. / sumtkwt;
0268 } else {
0269 tks.osumtkwt = 0.;
0270 }
0271
0272 #ifdef DEBUG
0273 if (DEBUGLEVEL > 0) {
0274 std::cout << "Track count (ZT) filled " << tks.getSize() << " initial " << tracks.size() << std::endl;
0275 }
0276 #endif
0277
0278 return tks;
0279 }
0280
0281 namespace {
0282 inline double Eik(double t_z, double k_z, double t_dz2, double t_t, double k_t, double t_dt2) {
0283 return std::pow(t_z - k_z, 2) * t_dz2 + std::pow(t_t - k_t, 2) * t_dt2;
0284 }
0285 }
0286
0287 void DAClusterizerInZT_vect::set_vtx_range(double beta, track_t& gtracks, vertex_t& gvertices) const {
0288 const unsigned int nv = gvertices.getSize();
0289 const unsigned int nt = gtracks.getSize();
0290
0291 if (nv == 0) {
0292 edm::LogWarning("DAClusterizerinZT_vect") << "empty cluster list in set_vtx_range";
0293 return;
0294 }
0295
0296 for (auto itrack = 0U; itrack < nt; ++itrack) {
0297 double zrange = max(sel_zrange_ / sqrt(beta * gtracks.dz2[itrack]), zrange_min_);
0298
0299 double zmin = gtracks.zpca[itrack] - zrange;
0300 unsigned int kmin = min(nv - 1, gtracks.kmin[itrack]);
0301
0302 if (gvertices.zvtx[kmin] > zmin) {
0303 while ((kmin > 0) && (gvertices.zvtx[kmin - 1] > zmin)) {
0304 kmin--;
0305 }
0306 } else {
0307 while ((kmin < (nv - 1)) && (gvertices.zvtx[kmin] < zmin)) {
0308 kmin++;
0309 }
0310 }
0311
0312 double zmax = gtracks.zpca[itrack] + zrange;
0313 unsigned int kmax = min(nv - 1, gtracks.kmax[itrack] - 1);
0314
0315
0316 if (gvertices.zvtx[kmax] < zmax) {
0317 while ((kmax < (nv - 1)) && (gvertices.zvtx[kmax + 1] < zmax)) {
0318 kmax++;
0319 }
0320 } else {
0321 while ((kmax > 0) && (gvertices.zvtx[kmax] > zmax)) {
0322 kmax--;
0323 }
0324 }
0325
0326 if (kmin <= kmax) {
0327 gtracks.kmin[itrack] = kmin;
0328 gtracks.kmax[itrack] = kmax + 1;
0329 } else {
0330 gtracks.kmin[itrack] = max(0U, min(kmin, kmax));
0331 gtracks.kmax[itrack] = min(nv, max(kmin, kmax) + 1);
0332 }
0333
0334 #ifdef DEBUG
0335 if (gtracks.kmin[itrack] >= gtracks.kmax[itrack]) {
0336 cout << "set_vtx_range trk = " << itrack << " kmin,kmax=" << kmin << "," << kmax
0337 << " gtrack.kmin,kmax = " << gtracks.kmin[itrack] << "," << gtracks.kmax[itrack] << " zrange = " << zrange
0338 << endl;
0339 }
0340 #endif
0341 }
0342 }
0343
0344 void DAClusterizerInZT_vect::clear_vtx_range(track_t& gtracks, vertex_t& gvertices) const {
0345 const unsigned int nt = gtracks.getSize();
0346 const unsigned int nv = gvertices.getSize();
0347 for (auto itrack = 0U; itrack < nt; ++itrack) {
0348 gtracks.kmin[itrack] = 0;
0349 gtracks.kmax[itrack] = nv;
0350 }
0351 }
0352
0353 double DAClusterizerInZT_vect::update(
0354 double beta, track_t& gtracks, vertex_t& gvertices, const double rho0, const bool updateTc) const {
0355
0356
0357
0358
0359 const unsigned int nt = gtracks.getSize();
0360 const unsigned int nv = gvertices.getSize();
0361 auto osumtkwt = gtracks.osumtkwt;
0362
0363 double Z_init = 0;
0364 if (rho0 > 0) {
0365 Z_init = rho0 * local_exp(-beta * dzCutOff_ * dzCutOff_);
0366 }
0367
0368
0369
0370 auto kernel_calc_exp_arg_range = [beta](const unsigned int itrack,
0371 track_t const& tracks,
0372 vertex_t const& vertices,
0373 const unsigned int kmin,
0374 const unsigned int kmax) {
0375 const auto track_z = tracks.zpca[itrack];
0376 const auto track_t = tracks.tpca[itrack];
0377 const auto botrack_dz2 = -beta * tracks.dz2[itrack];
0378 #ifndef USEVTXDT2
0379 const auto botrack_dt2 = -beta * tracks.dt2[itrack];
0380 #endif
0381
0382 for (unsigned int ivertex = kmin; ivertex < kmax; ++ivertex) {
0383 const auto mult_resz = track_z - vertices.zvtx[ivertex];
0384 const auto mult_rest = track_t - vertices.tvtx[ivertex];
0385 #ifdef USEVTXDT2
0386 const auto botrack_dt2 =
0387 -beta * tracks.dt2[itrack] * vertices.dt2[ivertex] / (tracks.dt2[itrack] + vertices.dt2[ivertex] + 1.e-10);
0388 #endif
0389 vertices.exp_arg[ivertex] = botrack_dz2 * (mult_resz * mult_resz) + botrack_dt2 * (mult_rest * mult_rest);
0390 }
0391 };
0392
0393 auto kernel_add_Z_range = [Z_init](
0394 vertex_t const& vertices, const unsigned int kmin, const unsigned int kmax) -> double {
0395 double ZTemp = Z_init;
0396 for (unsigned int ivertex = kmin; ivertex < kmax; ++ivertex) {
0397 ZTemp += vertices.rho[ivertex] * vertices.exp[ivertex];
0398 }
0399 return ZTemp;
0400 };
0401
0402 auto kernel_calc_normalization_range = [updateTc](const unsigned int track_num,
0403 track_t& tracks,
0404 vertex_t& vertices,
0405 const unsigned int kmin,
0406 const unsigned int kmax) {
0407 auto tmp_trk_tkwt = tracks.tkwt[track_num];
0408 auto o_trk_sum_Z = 1. / tracks.sum_Z[track_num];
0409 auto o_trk_err_z = tracks.dz2[track_num];
0410 auto o_trk_err_t = tracks.dt2[track_num];
0411 auto tmp_trk_z = tracks.zpca[track_num];
0412 auto tmp_trk_t = tracks.tpca[track_num];
0413
0414 if (updateTc) {
0415 #pragma GCC ivdep
0416 for (unsigned int k = kmin; k < kmax; ++k) {
0417
0418 vertices.se[k] += tmp_trk_tkwt * (vertices.exp[k] * o_trk_sum_Z);
0419 const auto w = tmp_trk_tkwt * (vertices.rho[k] * vertices.exp[k] * o_trk_sum_Z);
0420 const auto wz = w * o_trk_err_z;
0421 const auto wt = w * o_trk_err_t;
0422 #ifdef USEVTXDT2
0423 vertices.sumw[k] += w;
0424 #endif
0425 vertices.nuz[k] += wz;
0426 vertices.nut[k] += wt;
0427 vertices.swz[k] += wz * tmp_trk_z;
0428 vertices.swt[k] += wt * tmp_trk_t;
0429
0430 const auto dsz = (tmp_trk_z - vertices.zvtx[k]) * o_trk_err_z;
0431 const auto dst = (tmp_trk_t - vertices.tvtx[k]) * o_trk_err_t;
0432 vertices.szz[k] += w * dsz * dsz;
0433 vertices.stt[k] += w * dst * dst;
0434 vertices.szt[k] += w * dsz * dst;
0435 }
0436 } else {
0437 #pragma GCC ivdep
0438 for (unsigned int k = kmin; k < kmax; ++k) {
0439 vertices.se[k] += tmp_trk_tkwt * (vertices.exp[k] * o_trk_sum_Z);
0440 const auto w = tmp_trk_tkwt * (vertices.rho[k] * vertices.exp[k] * o_trk_sum_Z);
0441 const auto wz = w * o_trk_err_z;
0442 const auto wt = w * o_trk_err_t;
0443 #ifdef USEVTXDT2
0444 vertices.sumw[k] += w;
0445 #endif
0446 vertices.nuz[k] += wz;
0447 vertices.nut[k] += wt;
0448 vertices.swz[k] += wz * tmp_trk_z;
0449 vertices.swt[k] += wt * tmp_trk_t;
0450 }
0451 }
0452 };
0453
0454 for (auto ivertex = 0U; ivertex < nv; ++ivertex) {
0455 gvertices.se[ivertex] = 0.0;
0456 gvertices.nuz[ivertex] = 0.0;
0457 gvertices.nut[ivertex] = 0.0;
0458 gvertices.swz[ivertex] = 0.0;
0459 gvertices.swt[ivertex] = 0.0;
0460 gvertices.szz[ivertex] = 0.0;
0461 gvertices.stt[ivertex] = 0.0;
0462 gvertices.szt[ivertex] = 0.0;
0463 #ifdef USEVTXDT2
0464 gvertices.sumw[ivertex] = 0.0;
0465 #endif
0466 }
0467
0468
0469 for (auto itrack = 0U; itrack < nt; ++itrack) {
0470 const unsigned int kmin = gtracks.kmin[itrack];
0471 const unsigned int kmax = gtracks.kmax[itrack];
0472
0473 #ifdef DEBUG
0474 assert((kmin < kmax) && (kmax <= nv));
0475 assert(itrack < gtracks.sum_Z_vec.size());
0476 #endif
0477
0478 kernel_calc_exp_arg_range(itrack, gtracks, gvertices, kmin, kmax);
0479 local_exp_list_range(gvertices.exp_arg, gvertices.exp, kmin, kmax);
0480 gtracks.sum_Z[itrack] = kernel_add_Z_range(gvertices, kmin, kmax);
0481
0482 if (edm::isNotFinite(gtracks.sum_Z[itrack]))
0483 gtracks.sum_Z[itrack] = 0.0;
0484
0485 if (gtracks.sum_Z[itrack] > 1.e-100) {
0486 kernel_calc_normalization_range(itrack, gtracks, gvertices, kmin, kmax);
0487 }
0488 }
0489
0490
0491 auto kernel_calc_zt = [osumtkwt, nv](vertex_t& vertices) -> double {
0492 double delta = 0;
0493
0494
0495 for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
0496 if (vertices.nuz[ivertex] > 0.) {
0497 auto znew = vertices.swz[ivertex] / vertices.nuz[ivertex];
0498 delta = max(std::abs(vertices.zvtx[ivertex] - znew), delta);
0499 vertices.zvtx[ivertex] = znew;
0500 }
0501
0502 if (vertices.nut[ivertex] > 0.) {
0503 auto tnew = vertices.swt[ivertex] / vertices.nut[ivertex];
0504
0505 vertices.tvtx[ivertex] = tnew;
0506 #ifdef USEVTXDT2
0507 vertices.dt2[ivertex] = vertices.nut[ivertex] / vertices.sumw[ivertex];
0508 #endif
0509 } else {
0510
0511
0512
0513
0514 vertices.tvtx[ivertex] = 0;
0515 #ifdef USEVTXDT2
0516 vertices.dt2[ivertex] = 0;
0517 #endif
0518 }
0519
0520 #ifdef DEBUG
0521 if ((vertices.nut[ivertex] <= 0.) && (vertices.nuz[ivertex] <= 0.)) {
0522 edm::LogInfo("sumw") << "invalid sum of weights in fit: " << endl;
0523 std::cout << " a cluster melted away ? "
0524 << " zk=" << vertices.zvtx[ivertex] << " rho=" << vertices.rho[ivertex]
0525 << " sumw(z,t) =" << vertices.nuz[ivertex] << "," << vertices.nut[ivertex] << endl;
0526
0527 }
0528 #endif
0529 }
0530
0531 for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
0532 vertices.rho[ivertex] = vertices.rho[ivertex] * vertices.se[ivertex] * osumtkwt;
0533 }
0534
0535 return delta;
0536 };
0537
0538 double delta = kernel_calc_zt(gvertices);
0539
0540 if (zorder(gvertices)) {
0541 set_vtx_range(beta, gtracks, gvertices);
0542 };
0543
0544
0545 return delta;
0546 }
0547
0548 bool DAClusterizerInZT_vect::zorder(vertex_t& y) const {
0549 const unsigned int nv = y.getSize();
0550
0551 #ifdef DEBUG
0552 assert(y.zvtx_vec.size() == nv);
0553 assert(y.tvtx_vec.size() == nv);
0554 assert(y.rho_vec.size() == nv);
0555 #endif
0556
0557 if (nv < 2)
0558 return false;
0559
0560 bool reordering = true;
0561 bool modified = false;
0562
0563 while (reordering) {
0564 reordering = false;
0565 for (unsigned int k = 0; (k + 1) < nv; k++) {
0566 if (y.zvtx[k + 1] < y.zvtx[k]) {
0567 auto ztemp = y.zvtx[k];
0568 y.zvtx[k] = y.zvtx[k + 1];
0569 y.zvtx[k + 1] = ztemp;
0570 auto ttemp = y.tvtx[k];
0571 y.tvtx[k] = y.tvtx[k + 1];
0572 y.tvtx[k + 1] = ttemp;
0573 #ifdef USEVTXDT2
0574 auto dt2temp = y.dt2[k];
0575 y.dt2[k] = y.dt2[k + 1];
0576 y.dt2[k + 1] = dt2temp;
0577 #endif
0578 auto ptemp = y.rho[k];
0579 y.rho[k] = y.rho[k + 1];
0580 y.rho[k + 1] = ptemp;
0581 reordering = true;
0582 }
0583 }
0584 modified |= reordering;
0585 }
0586
0587 if (modified) {
0588 y.extractRaw();
0589 return true;
0590 }
0591
0592 return false;
0593 }
0594
0595 bool DAClusterizerInZT_vect::find_nearest(
0596 double z, double t, vertex_t& y, unsigned int& k_min, double dz, double dt) const {
0597
0598
0599
0600
0601
0602 unsigned int nv = y.getSize();
0603 if (nv < 2) {
0604 k_min = 0;
0605 return false;
0606 }
0607
0608
0609 unsigned int k = 0;
0610 for (unsigned int k0 = 1; k0 < nv; k0++) {
0611 if (std::abs(y.zvtx[k0] - z) < std::abs(y.zvtx[k] - z)) {
0612 k = k0;
0613 }
0614 }
0615
0616 double delta_min = 1.;
0617
0618
0619 unsigned int k1 = k;
0620 while ((k1 > 0) && ((y.zvtx[k] - y.zvtx[--k1]) < dz)) {
0621 auto delta = std::pow((y.zvtx[k] - y.zvtx[k1]) / dz, 2) + std::pow((y.tvtx[k] - y.tvtx[k1]) / dt, 2);
0622 if (delta < delta_min) {
0623 k_min = k1;
0624 delta_min = delta;
0625 }
0626 }
0627
0628
0629 k1 = k;
0630 while (((++k1) < nv) && ((y.zvtx[k1] - y.zvtx[k]) < dz)) {
0631 auto delta = std::pow((y.zvtx[k1] - y.zvtx[k]) / dz, 2) + std::pow((y.tvtx[k1] - y.tvtx[k]) / dt, 2);
0632 if (delta < delta_min) {
0633 k_min = k1;
0634 delta_min = delta;
0635 }
0636 }
0637
0638 return (delta_min < 1.);
0639 }
0640
0641 unsigned int DAClusterizerInZT_vect::thermalize(
0642 double beta, track_t& tks, vertex_t& v, const double delta_max0, const double rho0) const {
0643 unsigned int niter = 0;
0644 double delta = 0;
0645 double delta_max = delta_lowT_;
0646
0647 if (convergence_mode_ == 0) {
0648 delta_max = delta_max0;
0649 } else if (convergence_mode_ == 1) {
0650 delta_max = delta_lowT_ / sqrt(std::max(beta, 1.0));
0651 }
0652
0653 zorder(v);
0654 set_vtx_range(beta, tks, v);
0655
0656 double delta_sum_range = 0;
0657 std::vector<double> z0 = v.zvtx_vec;
0658
0659 while (niter++ < maxIterations_) {
0660 delta = update(beta, tks, v, rho0);
0661 delta_sum_range += delta;
0662
0663 if (delta_sum_range > zrange_min_) {
0664 for (unsigned int k = 0; k < v.getSize(); k++) {
0665 if (std::abs(v.zvtx_vec[k] - z0[k]) > zrange_min_) {
0666 zorder(v);
0667 set_vtx_range(beta, tks, v);
0668 delta_sum_range = 0;
0669 z0 = v.zvtx_vec;
0670 break;
0671 }
0672 }
0673 }
0674
0675 if (delta < delta_max) {
0676 break;
0677 }
0678 }
0679
0680 #ifdef DEBUG
0681 if (DEBUGLEVEL > 0) {
0682 std::cout << "DAClusterizerInZT_vect.thermalize niter = " << niter << " at T = " << 1 / beta
0683 << " nv = " << v.getSize() << std::endl;
0684 if (DEBUGLEVEL > 2)
0685 dump(beta, v, tks, 0);
0686 }
0687 #endif
0688
0689 return niter;
0690 }
0691
0692 bool DAClusterizerInZT_vect::merge(vertex_t& y, track_t& tks, double& beta) const {
0693
0694
0695 const unsigned int nv = y.getSize();
0696
0697 if (nv < 2)
0698 return false;
0699
0700
0701 unsigned int k1_min = 0, k2_min = 0;
0702 double delta_min = 0;
0703
0704 for (unsigned int k1 = 0; (k1 + 1) < nv; k1++) {
0705 unsigned int k2 = k1;
0706 while ((++k2 < nv) && (std::fabs(y.zvtx[k2] - y.zvtx[k1]) < zmerge_)) {
0707 auto delta = std::pow((y.zvtx[k2] - y.zvtx[k1]) / zmerge_, 2) + std::pow((y.tvtx[k2] - y.tvtx[k1]) / tmerge_, 2);
0708 if ((delta < delta_min) || (k1_min == k2_min)) {
0709 k1_min = k1;
0710 k2_min = k2;
0711 delta_min = delta;
0712 }
0713 }
0714 }
0715
0716 if ((k1_min == k2_min) || (delta_min > 1)) {
0717 return false;
0718 }
0719
0720 double rho = y.rho[k1_min] + y.rho[k2_min];
0721
0722 #ifdef DEBUG
0723 assert((k1_min < nv) && (k2_min < nv));
0724 if (DEBUGLEVEL > 1) {
0725 std::cout << "merging (" << setw(8) << fixed << setprecision(4) << y.zvtx[k1_min] << ',' << y.tvtx[k1_min]
0726 << ") and (" << y.zvtx[k2_min] << ',' << y.tvtx[k2_min] << ")"
0727 << " idx=" << k1_min << "," << k2_min << std::endl;
0728 }
0729 #endif
0730
0731 if (rho > 0) {
0732 y.zvtx[k1_min] = (y.rho[k1_min] * y.zvtx[k1_min] + y.rho[k2_min] * y.zvtx[k2_min]) / rho;
0733 y.tvtx[k1_min] = (y.rho[k1_min] * y.tvtx[k1_min] + y.rho[k2_min] * y.tvtx[k2_min]) / rho;
0734 #ifdef USEVTXDT2
0735 y.dt2[k1_min] = (y.rho[k1_min] * y.dt2[k1_min] + y.rho[k2_min] * y.dt2[k2_min]) / rho;
0736 #endif
0737 } else {
0738 y.zvtx[k1_min] = 0.5 * (y.zvtx[k1_min] + y.zvtx[k2_min]);
0739 y.tvtx[k1_min] = 0.5 * (y.tvtx[k1_min] + y.tvtx[k2_min]);
0740 }
0741 y.rho[k1_min] = rho;
0742 y.removeItem(k2_min, tks);
0743
0744 zorder(y);
0745 set_vtx_range(beta, tks, y);
0746 y.extractRaw();
0747 return true;
0748 }
0749
0750 bool DAClusterizerInZT_vect::purge(vertex_t& y, track_t& tks, double& rho0, const double beta) const {
0751 constexpr double eps = 1.e-100;
0752
0753 const unsigned int nv = y.getSize();
0754 const unsigned int nt = tks.getSize();
0755
0756 if (nv < 2)
0757 return false;
0758
0759 std::vector<double> sump_v(nv), arg_cache_v(nv), exp_cache_v(nv), pcut_cache_v(nv);
0760 std::vector<int> nUnique_v(nv);
0761 double* __restrict__ parg_cache;
0762 double* __restrict__ pexp_cache;
0763 double* __restrict__ ppcut_cache;
0764 double* __restrict__ psump;
0765 int* __restrict__ pnUnique;
0766 int constexpr nunique_min_ = 2;
0767
0768 zorder(y);
0769 set_vtx_range(beta, tks, y);
0770
0771 parg_cache = arg_cache_v.data();
0772 pexp_cache = exp_cache_v.data();
0773 ppcut_cache = pcut_cache_v.data();
0774 psump = sump_v.data();
0775 pnUnique = nUnique_v.data();
0776
0777 const auto rhoconst = rho0 * local_exp(-beta * dzCutOff_ * dzCutOff_);
0778 for (unsigned int k = 0; k < nv; ++k) {
0779 const double pmax = y.rho[k] / (y.rho[k] + rhoconst);
0780 ppcut_cache[k] = uniquetrkweight_ * pmax;
0781 }
0782
0783 for (unsigned int i = 0; i < nt; i++) {
0784 const auto invZ = ((tks.sum_Z[i] > eps) && (tks.tkwt[i] > uniquetrkminp_)) ? 1. / tks.sum_Z[i] : 0.;
0785 const auto track_z = tks.zpca[i];
0786 const auto track_t = tks.tpca[i];
0787 const auto botrack_dz2 = -beta * tks.dz2[i];
0788 const auto botrack_dt2 = -beta * tks.dt2[i];
0789 const auto kmin = tks.kmin[i];
0790 const auto kmax = tks.kmax[i];
0791
0792 for (unsigned int k = kmin; k < kmax; k++) {
0793 const auto mult_resz = track_z - y.zvtx[k];
0794 const auto mult_rest = track_t - y.tvtx[k];
0795 parg_cache[k] = botrack_dz2 * (mult_resz * mult_resz) + botrack_dt2 * (mult_rest * mult_rest);
0796 }
0797
0798 local_exp_list_range(parg_cache, pexp_cache, kmin, kmax);
0799
0800 for (unsigned int k = kmin; k < kmax; k++) {
0801 const double p = y.rho[k] * pexp_cache[k] * invZ;
0802 psump[k] += p;
0803 pnUnique[k] += (p > ppcut_cache[k]) ? 1 : 0;
0804 }
0805 }
0806
0807 double sumpmin = nt;
0808 unsigned int k0 = nv;
0809 for (unsigned k = 0; k < nv; k++) {
0810 if ((pnUnique[k] < nunique_min_) && (psump[k] < sumpmin)) {
0811 sumpmin = psump[k];
0812 k0 = k;
0813 }
0814 }
0815
0816 if (k0 != nv) {
0817 #ifdef DEBUG
0818 assert(k0 < y.getSize());
0819 if (DEBUGLEVEL > 1) {
0820 std::cout << "eliminating prototype at " << std::setw(10) << std::setprecision(4) << y.zvtx[k0] << ","
0821 << y.tvtx[k0] << " with sump=" << sumpmin << " rho*nt =" << y.rho[k0] * nt << endl;
0822 }
0823 #endif
0824 y.removeItem(k0, tks);
0825 set_vtx_range(beta, tks, y);
0826 return true;
0827 } else {
0828 return false;
0829 }
0830 }
0831
0832 double DAClusterizerInZT_vect::beta0(double betamax, track_t const& tks, vertex_t const& y) const {
0833 double T0 = 0;
0834
0835 const unsigned int nt = tks.getSize();
0836 const unsigned int nv = y.getSize();
0837
0838 for (unsigned int k = 0; k < nv; k++) {
0839
0840 double sumwz = 0;
0841 double sumwt = 0;
0842 double sumw_z = 0;
0843 double sumw_t = 0;
0844 for (unsigned int i = 0; i < nt; i++) {
0845 double w_z = tks.tkwt[i] * tks.dz2[i];
0846 double w_t = tks.tkwt[i] * tks.dt2[i];
0847 sumwz += w_z * tks.zpca[i];
0848 sumwt += w_t * tks.tpca[i];
0849 sumw_z += w_z;
0850 sumw_t += w_t;
0851 }
0852 y.zvtx[k] = sumwz / sumw_z;
0853 y.tvtx[k] = sumwt / sumw_t;
0854
0855
0856 double szz = 0, stt = 0, szt = 0;
0857 double nuz = 0, nut = 0;
0858 for (unsigned int i = 0; i < nt; i++) {
0859 double dz = (tks.zpca[i] - y.zvtx[k]) * tks.dz2[i];
0860 double dt = (tks.tpca[i] - y.tvtx[k]) * tks.dt2[i];
0861 double w = tks.tkwt[i];
0862 szz += w * dz * dz;
0863 stt += w * dt * dt;
0864 szt += w * dz * dt;
0865 nuz += w * tks.dz2[i];
0866 nut += w * tks.dt2[i];
0867 }
0868 double Tz = szz / nuz;
0869 double Tt = 0;
0870 double Tc = 0;
0871 if (nut > 0) {
0872 Tt = stt / nut;
0873 Tc = Tz + Tt + sqrt(pow(Tz - Tt, 2) + 4 * szt * szt / nuz / nut);
0874 } else {
0875 Tc = 2. * Tz;
0876 }
0877
0878 if (Tc > T0)
0879 T0 = Tc;
0880 }
0881
0882 #ifdef DEBUG
0883 if (DEBUGLEVEL > 0) {
0884 std::cout << "DAClusterizerInZT_vect.beta0: Tc = " << T0 << std::endl;
0885 int coolingsteps = 1 - int(std::log(T0 * betamax) / std::log(coolingFactor_));
0886 std::cout << "DAClusterizerInZT_vect.beta0: nstep = " << coolingsteps << std::endl;
0887 }
0888 #endif
0889
0890 if (T0 > 1. / betamax) {
0891 int coolingsteps = 1 - int(std::log(T0 * betamax) / std::log(coolingFactor_));
0892 return betamax * std::pow(coolingFactor_, coolingsteps);
0893 } else {
0894
0895 return betamax * coolingFactor_;
0896 }
0897 }
0898
0899 double DAClusterizerInZT_vect::get_Tc(const vertex_t& y, int k) const {
0900 double Tz = y.szz[k] / y.nuz[k];
0901 double Tt = 0.;
0902 if (y.nut[k] > 0) {
0903 Tt = y.stt[k] / y.nut[k];
0904 double mx = y.szt[k] / y.nuz[k] * y.szt[k] / y.nut[k];
0905 return Tz + Tt + sqrt(pow(Tz - Tt, 2) + 4 * mx);
0906 }
0907 return 2 * Tz;
0908 }
0909
0910 bool DAClusterizerInZT_vect::split(const double beta, track_t& tks, vertex_t& y, double threshold) const {
0911
0912
0913
0914
0915 constexpr double epsilonz = 1e-3;
0916 constexpr double epsilont = 1e-2;
0917 unsigned int nv = y.getSize();
0918 const double twoBeta = 2.0 * beta;
0919
0920
0921
0922 std::vector<std::pair<double, unsigned int> > critical;
0923 for (unsigned int k = 0; k < nv; k++) {
0924 double Tc = get_Tc(y, k);
0925 if (beta * Tc > threshold) {
0926 critical.push_back(make_pair(Tc, k));
0927 }
0928 }
0929 if (critical.empty())
0930 return false;
0931
0932 std::stable_sort(critical.begin(), critical.end(), std::greater<std::pair<double, unsigned int> >());
0933
0934 bool split = false;
0935 const unsigned int nt = tks.getSize();
0936
0937 for (unsigned int ic = 0; ic < critical.size(); ic++) {
0938 unsigned int k = critical[ic].second;
0939
0940
0941
0942 double Mzz = y.nuz[k] - twoBeta * y.szz[k];
0943 double Mtt = y.nut[k] - twoBeta * y.stt[k];
0944 double Mzt = -twoBeta * y.szt[k];
0945 const double twoMzt = 2.0 * Mzt;
0946 double D = sqrt(pow(Mtt - Mzz, 2) + twoMzt * twoMzt);
0947 double q1 = atan2(-Mtt + Mzz + D, -twoMzt);
0948 double l1 = 0.5 * (-Mzz - Mtt + D);
0949 double l2 = 0.5 * (-Mzz - Mtt - D);
0950 if ((std::abs(l1) < 1e-4) && (std::abs(l2) < 1e-4)) {
0951 edm::LogWarning("DAClusterizerInZT_vect") << "warning, bad eigenvalues! idx=" << k << " z= " << y.zvtx[k]
0952 << " Mzz=" << Mzz << " Mtt=" << Mtt << " Mzt=" << Mzt << endl;
0953 }
0954
0955 double qsplit = q1;
0956 double cq = cos(qsplit);
0957 double sq = sin(qsplit);
0958 if (cq < 0) {
0959 cq = -cq;
0960 sq = -sq;
0961 }
0962
0963
0964 double p1 = 0, z1 = 0, t1 = 0, wz1 = 0, wt1 = 0;
0965 double p2 = 0, z2 = 0, t2 = 0, wz2 = 0, wt2 = 0;
0966 for (unsigned int i = 0; i < nt; ++i) {
0967 if (tks.sum_Z[i] > 1.e-100) {
0968 double lr = (tks.zpca[i] - y.zvtx[k]) * cq + (tks.tpca[i] - y.tvtx[k]) * sq;
0969
0970 double tl = lr < 0 ? 1. : 0.;
0971 double tr = 1. - tl;
0972
0973
0974 double arg = lr * std::sqrt(beta * (cq * cq * tks.dz2[i] + sq * sq * tks.dt2[i]));
0975 if (std::abs(arg) < 20) {
0976 double t = local_exp(-arg);
0977 tl = t / (t + 1.);
0978 tr = 1 / (t + 1.);
0979 }
0980
0981 double p = y.rho[k] * tks.tkwt[i] *
0982 local_exp(-beta * Eik(tks.zpca[i], y.zvtx[k], tks.dz2[i], tks.tpca[i], y.tvtx[k], tks.dt2[i])) /
0983 tks.sum_Z[i];
0984 double wz = p * tks.dz2[i];
0985 double wt = p * tks.dt2[i];
0986 p1 += p * tl;
0987 z1 += wz * tl * tks.zpca[i];
0988 t1 += wt * tl * tks.tpca[i];
0989 wz1 += wz * tl;
0990 wt1 += wt * tl;
0991 p2 += p * tr;
0992 z2 += wz * tr * tks.zpca[i];
0993 t2 += wt * tr * tks.tpca[i];
0994 wz2 += wz * tr;
0995 wt2 += wt * tr;
0996 }
0997 }
0998
0999 if (wz1 > 0) {
1000 z1 /= wz1;
1001 } else {
1002 z1 = y.zvtx[k] - epsilonz * cq;
1003 edm::LogWarning("DAClusterizerInZT_vect") << "warning, wz1 = " << scientific << wz1 << endl;
1004 }
1005 if (wt1 > 0) {
1006 t1 /= wt1;
1007 } else {
1008 t1 = y.tvtx[k] - epsilont * sq;
1009 edm::LogWarning("DAClusterizerInZT_vect") << "warning, wt1 = " << scientific << wt1 << endl;
1010 }
1011 if (wz2 > 0) {
1012 z2 /= wz2;
1013 } else {
1014 z2 = y.zvtx[k] + epsilonz * cq;
1015 edm::LogWarning("DAClusterizerInZT_vect") << "warning, wz2 = " << scientific << wz2 << endl;
1016 }
1017 if (wt2 > 0) {
1018 t2 /= wt2;
1019 } else {
1020 t2 = y.tvtx[k] + epsilont * sq;
1021 edm::LogWarning("DAClusterizerInZT_vect") << "warning, wt2 = " << scientific << wt2 << endl;
1022 }
1023
1024 unsigned int k_min1 = k, k_min2 = k;
1025 constexpr double spliteps = 1e-8;
1026 while (((find_nearest(z1, t1, y, k_min1, epsilonz, epsilont) && (k_min1 != k)) ||
1027 (find_nearest(z2, t2, y, k_min2, epsilonz, epsilont) && (k_min2 != k))) &&
1028 (std::abs(z2 - z1) > spliteps || std::abs(t2 - t1) > spliteps)) {
1029 z1 = 0.5 * (z1 + y.zvtx[k]);
1030 t1 = 0.5 * (t1 + y.tvtx[k]);
1031 z2 = 0.5 * (z2 + y.zvtx[k]);
1032 t2 = 0.5 * (t2 + y.tvtx[k]);
1033 }
1034
1035 #ifdef DEBUG
1036 assert(k < nv);
1037 if (DEBUGLEVEL > 1) {
1038 if (std::fabs(y.zvtx[k] - zdumpcenter_) < zdumpwidth_) {
1039 std::cout << " T= " << std::setw(10) << std::setprecision(1) << 1. / beta << " Tc= " << critical[ic].first
1040 << " direction =" << std::setprecision(4) << qsplit << " splitting (" << std::setw(8) << std::fixed
1041 << std::setprecision(4) << y.zvtx[k] << "," << y.tvtx[k] << ")"
1042 << " --> (" << z1 << ',' << t1 << "),(" << z2 << ',' << t2 << ") [" << p1 << "," << p2 << "]";
1043 if (std::fabs(z2 - z1) > epsilonz || std::fabs(t2 - t1) > epsilont) {
1044 std::cout << std::endl;
1045 } else {
1046 std::cout << " rejected " << std::endl;
1047 }
1048 }
1049 }
1050 #endif
1051
1052 if (z1 > z2) {
1053 edm::LogInfo("DAClusterizerInZT") << "warning swapping z in split qsplit=" << qsplit << " cq=" << cq
1054 << " sq=" << sq << endl;
1055 auto ztemp = z1;
1056 auto ttemp = t1;
1057 auto ptemp = p1;
1058 z1 = z2;
1059 t1 = t2;
1060 p1 = p2;
1061 z2 = ztemp;
1062 t2 = ttemp;
1063 p2 = ptemp;
1064 }
1065
1066
1067 if (std::fabs(z2 - z1) > epsilonz || std::fabs(t2 - t1) > epsilont) {
1068 split = true;
1069 double rho1 = p1 * y.rho[k] / (p1 + p2);
1070 double rho2 = p2 * y.rho[k] / (p1 + p2);
1071
1072
1073 y.removeItem(k, tks);
1074 unsigned int k2 = y.insertOrdered(z2, t2, rho2, tks);
1075
1076 #ifdef DEBUG
1077 if (k2 < k) {
1078 std::cout << "unexpected z-ordering in split" << std::endl;
1079 }
1080 #endif
1081
1082
1083 if (!(k == k2)) {
1084 for (unsigned int jc = ic; jc < critical.size(); jc++) {
1085 if (critical[jc].second > k) {
1086 critical[jc].second--;
1087 }
1088 if (critical[jc].second >= k2) {
1089 critical[jc].second++;
1090 }
1091 }
1092 }
1093
1094
1095 unsigned int k1 = y.insertOrdered(z1, t1, rho1, tks);
1096 nv++;
1097
1098
1099 for (unsigned int jc = ic; jc < critical.size(); jc++) {
1100 if (critical[jc].second >= k1) {
1101 critical[jc].second++;
1102 }
1103 }
1104 } else {
1105 #ifdef DEBUG
1106 std::cout << "warning ! split rejected, too small." << endl;
1107 #endif
1108 }
1109 }
1110
1111 return split;
1112 }
1113
1114 vector<TransientVertex> DAClusterizerInZT_vect::vertices(const vector<reco::TransientTrack>& tracks) const {
1115 track_t&& tks = fill(tracks);
1116 vector<TransientVertex> clusters;
1117 if (tks.getSize() == 0)
1118 return clusters;
1119 tks.extractRaw();
1120
1121 unsigned int nt = tks.getSize();
1122 double rho0 = 0.0;
1123
1124 vertex_t y;
1125
1126
1127 y.addItem(0, 0, 1.0);
1128 clear_vtx_range(tks, y);
1129
1130
1131 double beta = beta0(betamax_, tks, y);
1132 #ifdef DEBUG
1133 if (DEBUGLEVEL > 0)
1134 std::cout << "Beta0 is " << beta << std::endl;
1135 #endif
1136
1137 thermalize(beta, tks, y, delta_highT_, 0.);
1138
1139
1140
1141 double betafreeze = betamax_ * sqrt(coolingFactor_);
1142
1143 while (beta < betafreeze) {
1144 update(beta, tks, y, rho0, true);
1145 while (merge(y, tks, beta)) {
1146 if (zorder(y))
1147 set_vtx_range(beta, tks, y);
1148 update(beta, tks, y, rho0, true);
1149 }
1150 split(beta, tks, y);
1151
1152 beta = beta / coolingFactor_;
1153 thermalize(beta, tks, y, delta_highT_, 0.);
1154 }
1155
1156 #ifdef DEBUG
1157 verify(y, tks);
1158
1159 if (DEBUGLEVEL > 0) {
1160 std::cout << "DAClusterizerInZT_vect::vertices :"
1161 << "merging at T=" << 1 / beta << std::endl;
1162 }
1163 #endif
1164
1165 zorder(y);
1166 set_vtx_range(beta, tks, y);
1167
1168 update(beta, tks, y, rho0, true);
1169
1170 while (merge(y, tks, beta)) {
1171 zorder(y);
1172 set_vtx_range(beta, tks, y);
1173 update(beta, tks, y, rho0, true);
1174 }
1175
1176 #ifdef DEBUG
1177 verify(y, tks);
1178 if (DEBUGLEVEL > 0) {
1179 std::cout << "DAClusterizerInZT_vect::vertices :"
1180 << "splitting/merging at T=" << 1 / beta << std::endl;
1181 }
1182 #endif
1183
1184 unsigned int ntry = 0;
1185 double threshold = 1.0;
1186 while (split(beta, tks, y, threshold) && (ntry++ < 10)) {
1187 thermalize(beta, tks, y, delta_highT_, 0.);
1188
1189 while (merge(y, tks, beta)) {
1190 if (zorder(y))
1191 set_vtx_range(beta, tks, y);
1192 update(beta, tks, y, rho0, true);
1193 }
1194
1195 #ifdef DEBUG
1196 verify(y, tks);
1197 #endif
1198
1199
1200 threshold *= 1.1;
1201 }
1202
1203 #ifdef DEBUG
1204 verify(y, tks);
1205 if (DEBUGLEVEL > 0) {
1206 std::cout << "DAClusterizerInZT_vect::vertices :"
1207 << "turning on outlier rejection at T=" << 1 / beta << std::endl;
1208 }
1209 #endif
1210
1211
1212 if (dzCutOff_ > 0) {
1213 rho0 = 1. / nt;
1214 for (unsigned int a = 0; a < 5; a++) {
1215 update(beta, tks, y, a * rho0 / 5);
1216 }
1217 }
1218
1219 thermalize(beta, tks, y, delta_lowT_, rho0);
1220
1221 #ifdef DEBUG
1222 verify(y, tks);
1223 if (DEBUGLEVEL > 0) {
1224 std::cout << "DAClusterizerInZT_vect::vertices :"
1225 << "merging with outlier rejection at T=" << 1 / beta << std::endl;
1226 }
1227 if (DEBUGLEVEL > 2)
1228 dump(beta, y, tks, 2);
1229 #endif
1230
1231
1232 zorder(y);
1233 while (merge(y, tks, beta)) {
1234 set_vtx_range(beta, tks, y);
1235 update(beta, tks, y, rho0);
1236 }
1237
1238 #ifdef DEBUG
1239 if (DEBUGLEVEL > 0) {
1240 std::cout << "DAClusterizerInZT_vect::vertices :"
1241 << "after merging with outlier rejection at T=" << 1 / beta << std::endl;
1242 }
1243 if (DEBUGLEVEL > 1)
1244 dump(beta, y, tks, 2);
1245 #endif
1246
1247
1248 while (beta < betapurge_) {
1249 beta = min(beta / coolingFactor_, betapurge_);
1250 thermalize(beta, tks, y, delta_lowT_, rho0);
1251 }
1252
1253 #ifdef DEBUG
1254 verify(y, tks);
1255 if (DEBUGLEVEL > 0) {
1256 std::cout << "DAClusterizerInZT_vect::vertices :"
1257 << "purging at T=" << 1 / beta << std::endl;
1258 }
1259 #endif
1260
1261
1262 while (purge(y, tks, rho0, beta)) {
1263 thermalize(beta, tks, y, delta_lowT_, rho0);
1264 if (zorder(y)) {
1265 set_vtx_range(beta, tks, y);
1266 };
1267 }
1268
1269 #ifdef DEBUG
1270 verify(y, tks);
1271 if (DEBUGLEVEL > 0) {
1272 std::cout << "DAClusterizerInZT_vect::vertices :"
1273 << "last cooling T=" << 1 / beta << std::endl;
1274 }
1275 #endif
1276
1277
1278 while (beta < betastop_) {
1279 beta = min(beta / coolingFactor_, betastop_);
1280 thermalize(beta, tks, y, delta_lowT_, rho0);
1281 if (zorder(y)) {
1282 set_vtx_range(beta, tks, y);
1283 };
1284 }
1285
1286 #ifdef DEBUG
1287 verify(y, tks);
1288 if (DEBUGLEVEL > 0) {
1289 std::cout << "DAClusterizerInZT_vect::vertices :"
1290 << "stop cooling at T=" << 1 / beta << std::endl;
1291 }
1292 if (DEBUGLEVEL > 2)
1293 dump(beta, y, tks, 2);
1294 #endif
1295
1296
1297
1298 double betadummy = 1;
1299 while (merge(y, tks, betadummy))
1300 ;
1301
1302
1303 zorder(y);
1304 set_vtx_range(beta, tks, y);
1305 const unsigned int nv = y.getSize();
1306 for (unsigned int k = 0; k < nv; k++)
1307 if (edm::isNotFinite(y.rho[k]) || edm::isNotFinite(y.zvtx[k])) {
1308 y.rho[k] = 0;
1309 y.zvtx[k] = 0;
1310 }
1311
1312 const auto z_sum_init = rho0 * local_exp(-beta * dzCutOff_ * dzCutOff_);
1313 std::vector<std::vector<unsigned int> > vtx_track_indices(nv);
1314 for (unsigned int i = 0; i < nt; i++) {
1315 const auto kmin = tks.kmin[i];
1316 const auto kmax = tks.kmax[i];
1317 for (auto k = kmin; k < kmax; k++) {
1318 y.exp_arg[k] = -beta * Eik(tks.zpca[i], y.zvtx[k], tks.dz2[i], tks.tpca[i], y.tvtx[k], tks.dt2[i]);
1319 }
1320
1321 local_exp_list_range(y.exp_arg, y.exp, kmin, kmax);
1322
1323 tks.sum_Z[i] = z_sum_init;
1324 for (auto k = kmin; k < kmax; k++) {
1325 tks.sum_Z[i] += y.rho[k] * y.exp[k];
1326 }
1327 const double invZ = tks.sum_Z[i] > 1e-100 ? 1. / tks.sum_Z[i] : 0.0;
1328
1329 for (auto k = kmin; k < kmax; k++) {
1330 double p = y.rho[k] * y.exp[k] * invZ;
1331 if (p > mintrkweight_) {
1332
1333 vtx_track_indices[k].push_back(i);
1334 break;
1335 }
1336 }
1337
1338 }
1339
1340 GlobalError dummyError(0.01, 0, 0.01, 0., 0., 0.01);
1341 for (unsigned int k = 0; k < nv; k++) {
1342 if (!vtx_track_indices[k].empty()) {
1343 GlobalPoint pos(0, 0, y.zvtx[k]);
1344 vector<reco::TransientTrack> vertexTracks;
1345 for (auto i : vtx_track_indices[k]) {
1346 vertexTracks.push_back(*(tks.tt[i]));
1347 }
1348 TransientVertex v(pos, dummyError, vertexTracks, 0);
1349 clusters.push_back(v);
1350 }
1351 }
1352
1353 return clusters;
1354 }
1355
1356 vector<vector<reco::TransientTrack> > DAClusterizerInZT_vect::clusterize(
1357 const vector<reco::TransientTrack>& tracks) const {
1358 vector<vector<reco::TransientTrack> > clusters;
1359 vector<TransientVertex>&& pv = vertices(tracks);
1360
1361 #ifdef DEBUG
1362 if (DEBUGLEVEL > 0) {
1363 std::cout << "###################################################" << endl;
1364 std::cout << "# vectorized DAClusterizerInZT_vect::clusterize nt=" << tracks.size() << endl;
1365 std::cout << "# DAClusterizerInZT_vect::clusterize pv.size=" << pv.size() << endl;
1366 std::cout << "###################################################" << endl;
1367 }
1368 #endif
1369
1370 if (pv.empty()) {
1371 return clusters;
1372 }
1373
1374
1375 for (auto k = pv.begin(); k != pv.end(); k++) {
1376 vector<reco::TransientTrack> aCluster = k->originalTracks();
1377 if (aCluster.size() > 1) {
1378 clusters.push_back(aCluster);
1379 }
1380 }
1381
1382 return clusters;
1383 }
1384
1385 void DAClusterizerInZT_vect::dump(const double beta, const vertex_t& y, const track_t& tks, int verbosity) const {
1386 #ifdef DEBUG
1387 const unsigned int nv = y.getSize();
1388 const unsigned int nt = tks.getSize();
1389
1390 std::vector<unsigned int> iz;
1391 for (unsigned int j = 0; j < nt; j++) {
1392 iz.push_back(j);
1393 }
1394 std::sort(iz.begin(), iz.end(), [tks](unsigned int a, unsigned int b) { return tks.zpca[a] < tks.zpca[b]; });
1395 std::cout << std::endl;
1396 std::cout << "-----DAClusterizerInZT::dump ----" << nv << " clusters " << std::endl;
1397 string h = " ";
1398 std::cout << h << " k= ";
1399 for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1400 if (std::fabs(y.zvtx[ivertex] - zdumpcenter_) < zdumpwidth_) {
1401 std::cout << setw(8) << fixed << ivertex;
1402 }
1403 }
1404 std::cout << endl;
1405
1406 std::cout << h << " z= ";
1407 std::cout << setprecision(4);
1408 for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1409 if (std::fabs(y.zvtx[ivertex] - zdumpcenter_) < zdumpwidth_) {
1410 std::cout << setw(8) << fixed << y.zvtx[ivertex];
1411 }
1412 }
1413 std::cout << endl;
1414
1415 std::cout << h << " t= ";
1416 std::cout << setprecision(4);
1417 for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1418 if (std::fabs(y.zvtx[ivertex] - zdumpcenter_) < zdumpwidth_) {
1419 std::cout << setw(8) << fixed << y.tvtx[ivertex];
1420 }
1421 }
1422 std::cout << endl;
1423
1424 std::cout << "T=" << setw(15) << 1. / beta << " Tmin =" << setw(10) << 1. / betamax_
1425 << " Tc= ";
1426 for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1427 if (std::fabs(y.zvtx[ivertex] - zdumpcenter_) < zdumpwidth_) {
1428 double Tc = get_Tc(y, ivertex);
1429 std::cout << setw(8) << fixed << setprecision(1) << Tc;
1430 }
1431 }
1432 std::cout << endl;
1433
1434 std::cout << h << "rho= ";
1435 double sumrho = 0;
1436 for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1437 sumrho += y.rho[ivertex];
1438 if (std::fabs(y.zvtx[ivertex] - zdumpcenter_) > zdumpwidth_)
1439 continue;
1440 std::cout << setw(8) << setprecision(4) << fixed << y.rho[ivertex];
1441 }
1442 std::cout << endl;
1443
1444 std::cout << h << "nt= ";
1445 for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1446 sumrho += y.rho[ivertex];
1447 if (std::fabs(y.zvtx[ivertex] - zdumpcenter_) > zdumpwidth_)
1448 continue;
1449 std::cout << setw(8) << setprecision(1) << fixed << y.rho[ivertex] * nt;
1450 }
1451 std::cout << endl;
1452
1453 if (verbosity > 0) {
1454 double E = 0, F = 0;
1455 std::cout << endl;
1456 std::cout << "---- z +/- dz t +/- dt ip +/-dip pt phi eta weights ----"
1457 << endl;
1458 std::cout << setprecision(4);
1459 for (unsigned int i0 = 0; i0 < nt; i0++) {
1460 unsigned int i = iz[i0];
1461 if (tks.sum_Z[i] > 0) {
1462 F -= std::log(tks.sum_Z[i]) / beta;
1463 }
1464 double tz = tks.zpca[i];
1465
1466 if (std::fabs(tz - zdumpcenter_) > zdumpwidth_)
1467 continue;
1468 std::cout << setw(4) << i << ")" << setw(8) << fixed << setprecision(4) << tz << " +/-" << setw(6)
1469 << sqrt(1. / tks.dz2[i]);
1470
1471 if (tks.dt2[i] > 0) {
1472 std::cout << setw(8) << fixed << setprecision(4) << tks.tpca[i] << " +/-" << setw(6) << sqrt(1. / tks.dt2[i]);
1473 } else {
1474 std::cout << " ";
1475 }
1476
1477 if (tks.tt[i]->track().quality(reco::TrackBase::highPurity)) {
1478 std::cout << " *";
1479 } else {
1480 std::cout << " ";
1481 }
1482 if (tks.tt[i]->track().hitPattern().hasValidHitInPixelLayer(PixelSubdetector::SubDetector::PixelBarrel, 1)) {
1483 std::cout << "+";
1484 } else {
1485 std::cout << "-";
1486 }
1487 std::cout << setw(1)
1488 << tks.tt[i]
1489 ->track()
1490 .hitPattern()
1491 .pixelBarrelLayersWithMeasurement();
1492 std::cout << setw(1) << tks.tt[i]->track().hitPattern().pixelEndcapLayersWithMeasurement();
1493 std::cout << setw(1) << hex
1494 << tks.tt[i]->track().hitPattern().trackerLayersWithMeasurement() -
1495 tks.tt[i]->track().hitPattern().pixelLayersWithMeasurement()
1496 << dec;
1497 std::cout << "=" << setw(1) << hex
1498 << tks.tt[i]->track().hitPattern().numberOfLostHits(reco::HitPattern::MISSING_OUTER_HITS) << dec;
1499
1500 Measurement1D IP = tks.tt[i]->stateAtBeamLine().transverseImpactParameter();
1501 std::cout << setw(8) << IP.value() << "+/-" << setw(6) << IP.error();
1502 std::cout << " " << setw(6) << setprecision(2) << tks.tt[i]->track().pt() * tks.tt[i]->track().charge();
1503 std::cout << " " << setw(5) << setprecision(2) << tks.tt[i]->track().phi() << " " << setw(5) << setprecision(2)
1504 << tks.tt[i]->track().eta();
1505
1506 double sump = 0.;
1507 for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1508 if (std::fabs(y.zvtx[ivertex] - zdumpcenter_) > zdumpwidth_)
1509 continue;
1510
1511 if ((tks.tkwt[i] > 0) && (tks.sum_Z[i] > 0)) {
1512 double p =
1513 y.rho[ivertex] *
1514 local_exp(-beta *
1515 Eik(tks.zpca[i], y.zvtx[ivertex], tks.dz2[i], tks.tpca[i], y.tvtx[ivertex], tks.dt2[i])) /
1516 tks.sum_Z[i];
1517
1518 if ((ivertex >= tks.kmin[i]) && (ivertex < tks.kmax[i])) {
1519 if (p > 0.0001) {
1520 std::cout << setw(8) << setprecision(3) << p;
1521 } else {
1522 std::cout << " _ ";
1523 }
1524 E += p * Eik(tks.zpca[i], y.zvtx[ivertex], tks.dz2[i], tks.tpca[i], y.tvtx[ivertex], tks.dt2[i]);
1525 sump += p;
1526 } else {
1527 if (p > 0.1) {
1528 std::cout << "XXXXXXXX";
1529 } else if (p > 0.0001) {
1530 std::cout << "X" << setw(6) << setprecision(3) << p << "X";
1531 } else {
1532 std::cout << " . ";
1533 }
1534 }
1535 } else {
1536 std::cout << " ";
1537 }
1538 }
1539 std::cout << " ( " << std::setw(3) << tks.kmin[i] << "," << std::setw(3) << tks.kmax[i] - 1 << " ) ";
1540 std::cout << endl;
1541 }
1542 std::cout << " ";
1543 for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1544 if (std::fabs(y.zvtx[ivertex] - zdumpcenter_) < zdumpwidth_) {
1545 std::cout << " " << setw(3) << ivertex << " ";
1546 }
1547 }
1548 std::cout << endl;
1549 std::cout << " z= ";
1550 std::cout << setprecision(4);
1551 for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1552 if (std::fabs(y.zvtx[ivertex] - zdumpcenter_) < zdumpwidth_) {
1553 std::cout << setw(8) << fixed << y.zvtx[ivertex];
1554 }
1555 }
1556 std::cout << endl;
1557 std::cout << endl
1558 << "T=" << 1 / beta << " E=" << E << " n=" << y.getSize() << " F= " << F << endl
1559 << "----------" << endl;
1560 }
1561 #endif
1562 }
1563
1564 void DAClusterizerInZT_vect::fillPSetDescription(edm::ParameterSetDescription& desc) {
1565 DAClusterizerInZ_vect::fillPSetDescription(desc);
1566 desc.add<double>("tmerge", 0.1);
1567 desc.add<double>("dtCutOff", 4.);
1568 desc.add<double>("t0Max", 1.0);
1569 desc.add<double>("vertexSizeTime", 0.008);
1570 }