CMS 3D CMS Logo

List of all members | Classes | Public Member Functions | Static Public Member Functions | Private Attributes
DAClusterizerInZ_vect Class Referencefinal

#include <DAClusterizerInZ_vect.h>

Inheritance diagram for DAClusterizerInZ_vect:
TrackClusterizerInZ

Classes

struct  track_t
 
struct  vertex_t
 

Public Member Functions

double beta0 (const double betamax, track_t const &tks, vertex_t const &y) const
 
void clear_vtx_range (track_t &gtracks, vertex_t &gvertices) const
 
std::vector< std::vector< reco::TransientTrack > > clusterize (const std::vector< reco::TransientTrack > &tracks) const override
 
 DAClusterizerInZ_vect (const edm::ParameterSet &conf)
 
void dump (const double beta, const vertex_t &y, const track_t &tks, const int verbosity=0, const double rho0=0.) const
 
track_t fill (const std::vector< reco::TransientTrack > &tracks) const
 
std::vector< TransientVertexfill_vertices (double beta, double rho0, track_t &tracks, vertex_t &vertices) const
 
bool merge (vertex_t &y, track_t &tks, double &beta) const
 
bool purge (vertex_t &, track_t &, double &, const double) const
 
void set_vtx_range (double beta, track_t &gtracks, vertex_t &gvertices) const
 
bool split (const double beta, track_t &t, vertex_t &y, double threshold=1.) const
 
unsigned int thermalize (double beta, track_t &gtracks, vertex_t &gvertices, const double delta_max, const double rho0=0.) const
 
double update (double beta, track_t &gtracks, vertex_t &gvertices, const double rho0=0, const bool updateTc=false) const
 
void verify (const vertex_t &v, const track_t &tks, unsigned int nv=999999, unsigned int nt=999999) const
 
std::vector< TransientVertexvertices (const std::vector< reco::TransientTrack > &tracks) const override
 
std::vector< TransientVertexvertices_in_blocks (const std::vector< reco::TransientTrack > &tracks) const
 
std::vector< TransientVertexvertices_no_blocks (const std::vector< reco::TransientTrack > &tracks) const
 
- Public Member Functions inherited from TrackClusterizerInZ
 TrackClusterizerInZ ()=default
 
 TrackClusterizerInZ (const edm::ParameterSet &conf)
 
virtual ~TrackClusterizerInZ ()=default
 

Static Public Member Functions

static void fillPSetDescription (edm::ParameterSetDescription &desc)
 

Private Attributes

double betamax_
 
double betapurge_
 
double betastop_
 
unsigned int block_size_
 
unsigned int convergence_mode_
 
double coolingFactor_
 
double d0CutOff_
 
double delta_highT_
 
double delta_lowT_
 
double dzCutOff_
 
unsigned int maxIterations_
 
double mintrkweight_
 
double overlap_frac_
 
bool runInBlocks_
 
double sel_zrange_
 
double uniquetrkminp_
 
double uniquetrkweight_
 
double vertexSize_
 
double zdumpcenter_
 
double zdumpwidth_
 
double zmerge_
 
const double zrange_min_ = 0.1
 

Detailed Description

Description: separates event tracks into clusters along the beam line

Version which auto-vectorizes with gcc 4.6 or newer

Definition at line 21 of file DAClusterizerInZ_vect.h.

Constructor & Destructor Documentation

◆ DAClusterizerInZ_vect()

DAClusterizerInZ_vect::DAClusterizerInZ_vect ( const edm::ParameterSet conf)

Definition at line 20 of file DAClusterizerInZ_vect.cc.

References gather_cfg::cout, edm::ParameterSet::getParameter(), edm::ParameterSet::getUntrackedParameter(), SiStripPI::max, HLT_2024v13_cff::Tmin, HLT_2024v13_cff::Tpurge, and HLT_2024v13_cff::Tstop.

20  {
21  // hardcoded parameters
22  maxIterations_ = 1000;
23  mintrkweight_ = 0.5;
24 
25  // configurable debug output
26 #ifdef DEBUG
27  zdumpcenter_ = conf.getUntrackedParameter<double>("zdumpcenter", 0.);
28  zdumpwidth_ = conf.getUntrackedParameter<double>("zdumpwidth", 20.);
29 #endif
30 
31  // configurable parameters
32  double Tmin = conf.getParameter<double>("Tmin");
33  double Tpurge = conf.getParameter<double>("Tpurge");
34  double Tstop = conf.getParameter<double>("Tstop");
35  vertexSize_ = conf.getParameter<double>("vertexSize");
36  coolingFactor_ = conf.getParameter<double>("coolingFactor");
37  d0CutOff_ = conf.getParameter<double>("d0CutOff");
38  dzCutOff_ = conf.getParameter<double>("dzCutOff");
39  uniquetrkweight_ = conf.getParameter<double>("uniquetrkweight");
40  uniquetrkminp_ = conf.getParameter<double>("uniquetrkminp");
41  zmerge_ = conf.getParameter<double>("zmerge");
42  sel_zrange_ = conf.getParameter<double>("zrange");
43  convergence_mode_ = conf.getParameter<int>("convergence_mode");
44  delta_lowT_ = conf.getParameter<double>("delta_lowT");
45  delta_highT_ = conf.getParameter<double>("delta_highT");
46  runInBlocks_ = conf.getParameter<bool>("runInBlocks");
47  block_size_ = conf.getParameter<unsigned int>("block_size");
48  overlap_frac_ = conf.getParameter<double>("overlap_frac");
49 
50 #ifdef DEBUG
51  std::cout << "DAClusterizerinZ_vect: mintrkweight = " << mintrkweight_ << std::endl;
52  std::cout << "DAClusterizerinZ_vect: uniquetrkweight = " << uniquetrkweight_ << std::endl;
53  std::cout << "DAClusterizerInZ_vect: uniquetrkminp = " << uniquetrkminp_ << std::endl;
54  std::cout << "DAClusterizerinZ_vect: zmerge = " << zmerge_ << std::endl;
55  std::cout << "DAClusterizerinZ_vect: Tmin = " << Tmin << std::endl;
56  std::cout << "DAClusterizerinZ_vect: Tpurge = " << Tpurge << std::endl;
57  std::cout << "DAClusterizerinZ_vect: Tstop = " << Tstop << std::endl;
58  std::cout << "DAClusterizerinZ_vect: vertexSize = " << vertexSize_ << std::endl;
59  std::cout << "DAClusterizerinZ_vect: coolingFactor = " << coolingFactor_ << std::endl;
60  std::cout << "DAClusterizerinZ_vect: d0CutOff = " << d0CutOff_ << std::endl;
61  std::cout << "DAClusterizerinZ_vect: dzCutOff = " << dzCutOff_ << std::endl;
62  std::cout << "DAClusterizerInZ_vect: zrange = " << sel_zrange_ << std::endl;
63  std::cout << "DAClusterizerinZ_vect: convergence mode = " << convergence_mode_ << std::endl;
64  std::cout << "DAClusterizerinZ_vect: delta_highT = " << delta_highT_ << std::endl;
65  std::cout << "DAClusterizerinZ_vect: delta_lowT = " << delta_lowT_ << std::endl;
66 
67  std::cout << "DAClusterizerinZ_vect: run in blocks = " << runInBlocks_ << std::endl;
68  std::cout << "DAClusterizerinZ_vect: block_size = " << block_size_ << std::endl;
69  std::cout << "DAClusterizerinZ_vect: overlap_fraction = " << overlap_frac_ << std::endl;
70  std::cout << "DAClusterizerinZ_vect: DEBUGLEVEL " << DEBUGLEVEL << std::endl;
71 #endif
72 
73  if (convergence_mode_ > 1) {
74  edm::LogWarning("DAClusterizerinZ_vect")
75  << "DAClusterizerInZ_vect: invalid convergence_mode " << convergence_mode_ << " reset to default " << 0;
77  }
78 
79  if (Tmin == 0) {
80  betamax_ = 1.0;
81  edm::LogWarning("DAClusterizerinZ_vect")
82  << "DAClusterizerInZ_vect: invalid Tmin " << Tmin << " reset to default " << 1. / betamax_;
83  } else {
84  betamax_ = 1. / Tmin;
85  }
86 
87  if ((Tpurge > Tmin) || (Tpurge == 0)) {
88  edm::LogWarning("DAClusterizerinZ_vect")
89  << "DAClusterizerInZ_vect: invalid Tpurge " << Tpurge << " set to " << Tmin;
90  Tpurge = Tmin;
91  }
92  betapurge_ = 1. / Tpurge;
93 
94  if ((Tstop > Tpurge) || (Tstop == 0)) {
95  edm::LogWarning("DAClusterizerinZ_vect")
96  << "DAClusterizerInZ_vect: invalid Tstop " << Tstop << " set to " << max(1., Tpurge);
97  Tstop = max(1., Tpurge);
98  }
99  betastop_ = 1. / Tstop;
100 }
T getParameter(std::string const &) const
Definition: ParameterSet.h:307
T getUntrackedParameter(std::string const &, T const &) const
Log< level::Warning, false > LogWarning

Member Function Documentation

◆ beta0()

double DAClusterizerInZ_vect::beta0 ( const double  betamax,
track_t const &  tks,
vertex_t const &  y 
) const

Definition at line 600 of file DAClusterizerInZ_vect.cc.

References a, b, gather_cfg::cout, PVValHelper::dx, DAClusterizerInZ_vect::track_t::dz2, DAClusterizerInZ_vect::track_t::getSize(), mps_fire::i, createfilelist::int, dqmdumpme::k, dqm-mbProfile::log, nt, funct::pow(), DAClusterizerInZ_vect::track_t::tkwt, w(), and DAClusterizerInZ_vect::track_t::zpca.

600  {
601  double T0 = 0; // max Tc for beta=0
602  // estimate critical temperature from beta=0 (T=inf)
603  const unsigned int nt = tks.getSize();
604  const unsigned int nv = y.getSize();
605 
606  for (unsigned int k = 0; k < nv; k++) {
607  // vertex fit at T=inf
608  double sumwz = 0;
609  double sumw = 0;
610  for (unsigned int i = 0; i < nt; i++) {
611  double w = tks.tkwt[i] * tks.dz2[i];
612  sumwz += w * tks.zpca[i];
613  sumw += w;
614  }
615 
616  y.zvtx[k] = sumwz / sumw;
617 
618  // estimate Tcrit
619  double a = 0, b = 0;
620  for (unsigned int i = 0; i < nt; i++) {
621  double dx = tks.zpca[i] - y.zvtx[k];
622  double w = tks.tkwt[i] * tks.dz2[i];
623  a += w * std::pow(dx, 2) * tks.dz2[i];
624  b += w;
625  }
626  double Tc = 2. * a / b; // the critical temperature of this vertex
627 
628  if (Tc > T0)
629  T0 = Tc;
630 
631  } // vertex loop (normally there should be only one vertex at beta=0)
632 
633 #ifdef DEBUG
634  if (DEBUGLEVEL > 0) {
635  std::cout << "DAClusterizerInZ_vect.beta0: Tc = " << T0 << std::endl;
636  int coolingsteps = 1 - int(std::log(T0 * betamax) / std::log(coolingFactor_));
637  std::cout << "DAClusterizerInZ_vect.beta0: nstep = " << coolingsteps << std::endl;
638  }
639 #endif
640 
641  if (T0 > 1. / betamax) {
642  int coolingsteps = 1 - int(std::log(T0 * betamax) / std::log(coolingFactor_));
643 
644  return betamax * std::pow(coolingFactor_, coolingsteps);
645  } else {
646  // ensure at least one annealing step
647  return betamax * coolingFactor_;
648  }
649 }
T w() const
int nt
Definition: AMPTWrapper.h:42
double b
Definition: hdecay.h:120
double a
Definition: hdecay.h:121
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29

◆ clear_vtx_range()

void DAClusterizerInZ_vect::clear_vtx_range ( track_t gtracks,
vertex_t gvertices 
) const

Definition at line 279 of file DAClusterizerInZ_vect.cc.

References DAClusterizerInZ_vect::track_t::getSize(), DAClusterizerInZ_vect::vertex_t::getSize(), DAClusterizerInZ_vect::track_t::kmax, DAClusterizerInZ_vect::track_t::kmin, nt, and mitigatedMETSequence_cff::U.

279  {
280  const unsigned int nt = gtracks.getSize();
281  const unsigned int nv = gvertices.getSize();
282  for (auto itrack = 0U; itrack < nt; ++itrack) {
283  gtracks.kmin[itrack] = 0;
284  gtracks.kmax[itrack] = nv;
285  }
286 }
int nt
Definition: AMPTWrapper.h:42

◆ clusterize()

vector< vector< reco::TransientTrack > > DAClusterizerInZ_vect::clusterize ( const std::vector< reco::TransientTrack > &  tracks) const
overridevirtual

Implements TrackClusterizerInZ.

Definition at line 1341 of file DAClusterizerInZ_vect.cc.

References funct::abs(), bsc_activity_cfg::clusters, gather_cfg::cout, mps_fire::i, dqmdumpme::k, eostools::move(), position, DiMuonV_cfg::tracks, and AlignmentTracksFromVertexSelector_cfi::vertices.

1342  {
1343  vector<vector<reco::TransientTrack>> clusters;
1344  vector<TransientVertex>&& pv = vertices(tracks);
1345 
1346 #ifdef DEBUG
1347  if (DEBUGLEVEL > 0) {
1348  std::cout << "###################################################" << endl;
1349  std::cout << "# vectorized DAClusterizerInZ_vect::clusterize nt=" << tracks.size() << endl;
1350  std::cout << "# DAClusterizerInZ_vect::clusterize pv.size=" << pv.size() << endl;
1351  std::cout << "###################################################" << endl;
1352  }
1353 #endif
1354 
1355  if (pv.empty()) {
1356  return clusters;
1357  }
1358 
1359  // fill into clusters and merge
1360  vector<reco::TransientTrack> aCluster = pv.begin()->originalTracks();
1361 
1362  for (auto k = pv.begin() + 1; k != pv.end(); k++) {
1363  if (std::abs(k->position().z() - (k - 1)->position().z()) > (2 * vertexSize_)) {
1364  // close a cluster
1365  if (aCluster.size() > 1) {
1366  clusters.push_back(aCluster);
1367  }
1368 #ifdef DEBUG
1369  else {
1370  std::cout << " one track cluster at " << k->position().z() << " suppressed" << std::endl;
1371  }
1372 #endif
1373  aCluster.clear();
1374  }
1375  for (unsigned int i = 0; i < k->originalTracks().size(); i++) {
1376  aCluster.push_back(k->originalTracks()[i]);
1377  }
1378  }
1379  clusters.emplace_back(std::move(aCluster));
1380 
1381  return clusters;
1382 }
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
static int position[264][3]
Definition: ReadPGInfo.cc:289
std::vector< TransientVertex > vertices(const std::vector< reco::TransientTrack > &tracks) const override
def move(src, dest)
Definition: eostools.py:511

◆ dump()

void DAClusterizerInZ_vect::dump ( const double  beta,
const vertex_t y,
const track_t tks,
const int  verbosity = 0,
const double  rho0 = 0. 
) const

Definition at line 1384 of file DAClusterizerInZ_vect.cc.

References a, b, HLT_2024v13_cff::beta, gather_cfg::cout, TauDecayModes::dec, DAClusterizerInZ_vect::track_t::dz2, F(), alignBH_cfg::fixed, DAClusterizerInZ_vect::track_t::getSize(), reco::TrackBase::highPurity, mps_fire::i, listHistos::IP, dqmiolumiharvest::j, DAClusterizerInZ_vect::track_t::kmax, DAClusterizerInZ_vect::track_t::kmin, dqm-mbProfile::log, reco::HitPattern::MISSING_OUTER_HITS, nt, AlCaHLTBitMon_ParallelJobs::p, GeomDetEnumerators::PixelBarrel, jetUpdater_cfi::sort, mathSSE::sqrt(), DAClusterizerInZ_vect::track_t::sum_Z, DAClusterizerInZ_vect::vertex_t::sw, DAClusterizerInZ_vect::vertex_t::swE, DAClusterizerInZ_vect::track_t::tkwt, DAClusterizerInZ_vect::track_t::tt, update, verbosity, and DAClusterizerInZ_vect::track_t::zpca.

1385  {
1386 #ifdef DEBUG
1387  const unsigned int nv = y.getSize();
1388  const unsigned int nt = tks.getSize();
1389  // make a local copies of clusters and tracks to update Tc [ = y_local.swE / y_local.sw ]
1390  vertex_t y_local = y;
1391  track_t tks_local = tks;
1392  update(beta, tks_local, y_local, rho0, true);
1393 
1394  std::vector<unsigned int> iz;
1395  for (unsigned int j = 0; j < nt; j++) {
1396  iz.push_back(j);
1397  }
1398  std::sort(iz.begin(), iz.end(), [tks](unsigned int a, unsigned int b) { return tks.zpca[a] < tks.zpca[b]; });
1399  std::cout << std::endl;
1400  std::cout << "-----DAClusterizerInZ::dump ----" << nv << " clusters " << std::endl;
1401  std::cout << " ";
1402  for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1403  if (std::fabs(y.zvtx[ivertex] - zdumpcenter_) < zdumpwidth_) {
1404  std::cout << " " << setw(3) << ivertex << " ";
1405  }
1406  }
1407  std::cout << endl;
1408  std::cout << " z= ";
1409  std::cout << setprecision(4);
1410  for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1411  if (std::fabs(y.zvtx[ivertex] - zdumpcenter_) < zdumpwidth_) {
1412  std::cout << setw(8) << fixed << y.zvtx[ivertex];
1413  }
1414  }
1415  std::cout << endl
1416  << "T=" << setw(15) << 1. / beta << " Tmin =" << setw(10) << 1. / betamax_
1417  << " Tc= ";
1418  for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1419  if (std::fabs(y.zvtx[ivertex] - zdumpcenter_) < zdumpwidth_) {
1420  double Tc = 2 * y_local.swE[ivertex] / y_local.sw[ivertex];
1421  std::cout << setw(8) << fixed << setprecision(1) << Tc;
1422  }
1423  }
1424  std::cout << endl;
1425 
1426  std::cout << " pk= ";
1427  double sumpk = 0;
1428  for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1429  sumpk += y.rho[ivertex];
1430  if (std::fabs(y.zvtx[ivertex] - zdumpcenter_) > zdumpwidth_)
1431  continue;
1432  std::cout << setw(8) << setprecision(4) << fixed << y.rho[ivertex];
1433  }
1434  std::cout << endl;
1435 
1436  std::cout << " nt= ";
1437  for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1438  if (std::fabs(y.zvtx[ivertex] - zdumpcenter_) > zdumpwidth_)
1439  continue;
1440  std::cout << setw(8) << setprecision(1) << fixed << y.rho[ivertex] * nt;
1441  }
1442  std::cout << endl;
1443 
1444  if (verbosity > 0) {
1445  double E = 0, F = 0;
1446  std::cout << endl;
1447  std::cout << "---- z +/- dz ip +/-dip pt phi eta weights ----" << endl;
1448  std::cout << setprecision(4);
1449  for (unsigned int i0 = 0; i0 < nt; i0++) {
1450  unsigned int i = iz[i0];
1451  if (tks.sum_Z[i] > 0) {
1452  F -= std::log(tks.sum_Z[i]) / beta;
1453  }
1454  double tz = tks.zpca[i];
1455 
1456  if (std::fabs(tz - zdumpcenter_) > zdumpwidth_)
1457  continue;
1458  std::cout << setw(4) << i << ")" << setw(8) << fixed << setprecision(4) << tz << " +/-" << setw(6)
1459  << sqrt(1. / tks.dz2[i]);
1460  if ((tks.tt[i] == nullptr)) {
1461  std::cout << " effective track ";
1462  } else {
1463  if (tks.tt[i]->track().quality(reco::TrackBase::highPurity)) {
1464  std::cout << " *";
1465  } else {
1466  std::cout << " ";
1467  }
1468  if (tks.tt[i]->track().hitPattern().hasValidHitInPixelLayer(PixelSubdetector::SubDetector::PixelBarrel, 1)) {
1469  std::cout << "+";
1470  } else {
1471  std::cout << "-";
1472  }
1473  std::cout << setw(1)
1474  << tks.tt[i]
1475  ->track()
1476  .hitPattern()
1477  .pixelBarrelLayersWithMeasurement(); // see DataFormats/TrackReco/interface/HitPattern.h
1478  std::cout << setw(1) << tks.tt[i]->track().hitPattern().pixelEndcapLayersWithMeasurement();
1479  std::cout << setw(1) << hex
1480  << tks.tt[i]->track().hitPattern().trackerLayersWithMeasurement() -
1481  tks.tt[i]->track().hitPattern().pixelLayersWithMeasurement()
1482  << dec;
1483  std::cout << "=" << setw(1) << hex
1484  << tks.tt[i]->track().hitPattern().numberOfLostHits(reco::HitPattern::MISSING_OUTER_HITS) << dec;
1485 
1486  Measurement1D IP = tks.tt[i]->stateAtBeamLine().transverseImpactParameter();
1487  std::cout << setw(8) << IP.value() << "+/-" << setw(6) << IP.error();
1488  std::cout << " " << setw(6) << setprecision(2) << tks.tt[i]->track().pt() * tks.tt[i]->track().charge();
1489  std::cout << " " << setw(5) << setprecision(2) << tks.tt[i]->track().phi() << " " << setw(5) << setprecision(2)
1490  << tks.tt[i]->track().eta();
1491  } // not a dummy track
1492 
1493  double sump = 0.;
1494  for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1495  if (std::fabs(y.zvtx[ivertex] - zdumpcenter_) > zdumpwidth_)
1496  continue;
1497 
1498  if ((tks.tkwt[i] > 0) && (tks.sum_Z[i] > 0)) {
1499  //double p=pik(beta,tks[i],*k);
1500  double p = y.rho[ivertex] * local_exp(-beta * Eik(tks.zpca[i], y.zvtx[ivertex], tks.dz2[i])) / tks.sum_Z[i];
1501  if (p > 0.0001) {
1502  std::cout << setw(8) << setprecision(3) << p;
1503  } else {
1504  std::cout << " . ";
1505  }
1506  E += p * Eik(tks.zpca[i], y.zvtx[ivertex], tks.dz2[i]);
1507  sump += p;
1508  } else {
1509  std::cout << " ";
1510  }
1511  }
1512  std::cout << " ( " << std::setw(3) << tks.kmin[i] << "," << std::setw(3) << tks.kmax[i] - 1 << " ) ";
1513  std::cout << endl;
1514  }
1515  std::cout << " ";
1516  for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1517  if (std::fabs(y.zvtx[ivertex] - zdumpcenter_) < zdumpwidth_) {
1518  std::cout << " " << setw(3) << ivertex << " ";
1519  }
1520  }
1521  std::cout << endl;
1522  std::cout << " z= ";
1523  std::cout << setprecision(4);
1524  for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
1525  if (std::fabs(y.zvtx[ivertex] - zdumpcenter_) < zdumpwidth_) {
1526  std::cout << setw(8) << fixed << y.zvtx[ivertex];
1527  }
1528  }
1529  std::cout << endl;
1530  std::cout << endl
1531  << "T=" << 1 / beta << " E=" << E << " n=" << y.getSize() << " F= " << F << endl
1532  << "----------" << endl;
1533  }
1534 #endif
1535 }
double update(double beta, track_t &gtracks, vertex_t &gvertices, const double rho0=0, const bool updateTc=false) const
T sqrt(T t)
Definition: SSEVec.h:23
int nt
Definition: AMPTWrapper.h:42
const int verbosity
double b
Definition: hdecay.h:120
double a
Definition: hdecay.h:121
static uInt32 F(BLOWFISH_CTX *ctx, uInt32 x)
Definition: blowfish.cc:163

◆ fill()

DAClusterizerInZ_vect::track_t DAClusterizerInZ_vect::fill ( const std::vector< reco::TransientTrack > &  tracks) const

Definition at line 177 of file DAClusterizerInZ_vect.cc.

References DAClusterizerInZ_vect::track_t::addItemSorted(), HLT_2024v13_cff::atIP, pwdgSkimBPark_cfi::beamSpot, gather_cfg::cout, geometryDiff::epsilon, DAClusterizerInZ_vect::track_t::extractRaw(), DAClusterizerInZ_vect::track_t::getSize(), edm::isNotFinite(), ALPAKA_ACCELERATOR_NAMESPACE::vertexFinder::it, SiStripPI::min, DAClusterizerInZ_vect::track_t::osumtkwt, position, funct::pow(), AlignmentPI::t_z, and DiMuonV_cfg::tracks.

177  {
178  // prepare track data for clustering
179  track_t tks;
180  double sumtkwt = 0.;
181  for (auto it = tracks.begin(); it != tracks.end(); it++) {
182  if (!(*it).isValid())
183  continue;
184  double t_tkwt = 1.;
185  double t_z = ((*it).stateAtBeamLine().trackStateAtPCA()).position().z();
186  if (std::fabs(t_z) > 1000.)
187  continue;
188  auto const& t_mom = (*it).stateAtBeamLine().trackStateAtPCA().momentum();
189  // get the beam-spot
190  reco::BeamSpot beamspot = (it->stateAtBeamLine()).beamSpot();
191  double t_dz2 = std::pow((*it).track().dzError(), 2) // track errror
192  + (std::pow(beamspot.BeamWidthX() * t_mom.x(), 2) + std::pow(beamspot.BeamWidthY() * t_mom.y(), 2)) *
193  std::pow(t_mom.z(), 2) / std::pow(t_mom.perp2(), 2) // beam spot width
194  + std::pow(vertexSize_, 2); // intrinsic vertex size, safer for outliers and short lived decays
195  t_dz2 = 1. / t_dz2;
196  if (edm::isNotFinite(t_dz2) || t_dz2 < std::numeric_limits<double>::min())
197  continue;
198  if (d0CutOff_ > 0) {
199  Measurement1D atIP = (*it).stateAtBeamLine().transverseImpactParameter(); // error contains beamspot
200  t_tkwt = 1. / (1. + local_exp(std::pow(atIP.value() / atIP.error(), 2) -
201  std::pow(d0CutOff_, 2))); // reduce weight for high ip tracks
203  edm::LogWarning("DAClusterizerinZ_vect") << "rejected track t_tkwt " << t_tkwt;
204  continue; // usually is > 0.99
205  }
206  }
207  tks.addItemSorted(t_z, t_dz2, &(*it), t_tkwt);
208  sumtkwt += t_tkwt;
209  }
210 
211  if (sumtkwt > 0) {
212  tks.extractRaw();
213  tks.osumtkwt = 1. / sumtkwt;
214  } else {
215  tks.osumtkwt = 0.;
216  }
217 
218 #ifdef DEBUG
219  if (DEBUGLEVEL > 0) {
220  std::cout << "Track count (Z) " << tks.getSize() << std::endl;
221  }
222 #endif
223  return tks;
224 }
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
static int position[264][3]
Definition: ReadPGInfo.cc:289
Log< level::Warning, false > LogWarning
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29

◆ fill_vertices()

vector< TransientVertex > DAClusterizerInZ_vect::fill_vertices ( double  beta,
double  rho0,
track_t tracks,
vertex_t vertices 
) const

Definition at line 1243 of file DAClusterizerInZ_vect.cc.

References HLT_2024v13_cff::beta, cms::cuda::bs, bsc_activity_cfg::clusters, DAClusterizerInZ_vect::track_t::dz2, MillePedeFileConverter_cfg::e, relativeConstraints::empty, submitPVResolutionJobs::err, DAClusterizerInZ_vect::track_t::getSize(), mps_fire::i, edm::isNotFinite(), dqmiolumiharvest::j, dqmdumpme::k, DAClusterizerInZ_vect::track_t::kmax, DAClusterizerInZ_vect::track_t::kmin, nt, AlCaHLTBitMon_ParallelJobs::p, funct::pow(), DAClusterizerInZ_vect::track_t::sum_Z, DAClusterizerInZ_vect::track_t::tt, findQualityFiles::v, w(), and DAClusterizerInZ_vect::track_t::zpca.

1243  {
1244  // select significant tracks and use a TransientVertex as a container
1245 
1246  set_vtx_range(beta, tks, y);
1247  const unsigned int nv = y.getSize();
1248  for (unsigned int k = 0; k < nv; k++) {
1249  if (edm::isNotFinite(y.rho[k]) || edm::isNotFinite(y.zvtx[k])) {
1250  y.rho[k] = 0;
1251  y.zvtx[k] = 0;
1252  }
1253  }
1254 
1255  // ensure consistent assignment probabillities and make a hard assignment
1256  const unsigned int nt = tks.getSize();
1257  const auto z_sum_init = rho0 * local_exp(-beta * dzCutOff_ * dzCutOff_);
1258  std::vector<std::vector<unsigned int>> vtx_track_indices(nv);
1259  std::vector<std::vector<float>> vtx_track_weights(nv);
1260  for (unsigned int i = 0; i < nt; i++) {
1261  const auto kmin = tks.kmin[i];
1262  const auto kmax = tks.kmax[i];
1263  for (auto k = kmin; k < kmax; k++) {
1264  y.exp_arg[k] = -beta * Eik(tks.zpca[i], y.zvtx[k], tks.dz2[i]);
1265  }
1266 
1267  local_exp_list_range(y.exp_arg, y.exp, kmin, kmax);
1268 
1269  tks.sum_Z[i] = z_sum_init;
1270  for (auto k = kmin; k < kmax; k++) {
1271  tks.sum_Z[i] += y.rho[k] * y.exp[k];
1272  }
1273  const double invZ = tks.sum_Z[i] > 1e-100 ? 1. / tks.sum_Z[i] : 0.0;
1274 
1275  double pmax = -1;
1276  unsigned int k_pmax = 0;
1277  for (auto k = kmin; k < kmax; k++) {
1278  double p = y.rho[k] * y.exp[k] * invZ;
1279  if (p > pmax) {
1280  pmax = p;
1281  k_pmax = k;
1282  }
1283  }
1284 
1285  if (pmax > mintrkweight_) {
1286  // assign to the cluster with the highest assignment weight, if it is at least mintrkweight_
1287  vtx_track_indices[k_pmax].push_back(i);
1288  vtx_track_weights[k_pmax].push_back(pmax);
1289  }
1290  }
1291 
1292  // fill transient vertices
1293  // the position is normally not used, probably not optimal when Tstop <> 2, anyway
1294  vector<TransientVertex> clusters;
1295  for (unsigned int k = 0; k < nv; k++) {
1296  double sump = 0;
1297  double sumw = 0;
1298  double sumwp = 0, sumwz = 0;
1299  if (!vtx_track_indices[k].empty()) {
1300  vector<reco::TransientTrack> vertexTracks;
1302  unsigned int j = 0;
1303  for (auto i : vtx_track_indices[k]) {
1304  auto p = vtx_track_weights[k][j];
1305  vertexTracks.push_back(*(tks.tt[i]));
1306  trkWeightMap[vertexTracks[j]] = p;
1307  auto w = p * tks.dz2[i];
1308  sump += p;
1309  sumw += w;
1310  sumwp += w * p;
1311  sumwz += w * tks.zpca[i];
1312  j++;
1313  }
1314  float zerror_squared = 1.; //
1315  if ((sumw > 0) && (sumwp > 0)) {
1316  zerror_squared = sumwp / (sumw * sumw);
1317  y.zvtx[k] = sumwz / sumw;
1318  }
1319 
1320  reco::BeamSpot bs = vertexTracks[0].stateAtBeamLine().beamSpot();
1321  GlobalPoint pos(bs.x(y.zvtx[k]), bs.y(y.zvtx[k]), y.zvtx[k]);
1322  const float xerror_squared = pow(bs.BeamWidthX(), 2);
1323  const float yerror_squared = pow(bs.BeamWidthY(), 2);
1324  GlobalError err(xerror_squared, 0, yerror_squared, 0., 0., zerror_squared);
1325  TransientVertex v(pos, err, vertexTracks, 0, 2 * sump - 3.);
1326  v.weightMap(trkWeightMap);
1327  clusters.push_back(v);
1328  }
1329  }
1330 
1331  return clusters;
1332 }
T w() const
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
std::map< reco::TransientTrack, float > TransientTrackToFloatMap
int nt
Definition: AMPTWrapper.h:42
void set_vtx_range(double beta, track_t &gtracks, vertex_t &gvertices) const
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29

◆ fillPSetDescription()

void DAClusterizerInZ_vect::fillPSetDescription ( edm::ParameterSetDescription desc)
static

Definition at line 1537 of file DAClusterizerInZ_vect.cc.

References submitPVResolutionJobs::desc.

Referenced by PrimaryVertexProducer::fillDescriptions(), PrimaryVertexValidation::fillDescriptions(), and DAClusterizerInZT_vect::fillPSetDescription().

1537  {
1538  desc.addUntracked<double>("zdumpcenter", 0.);
1539  desc.addUntracked<double>("zdumpwidth", 20.);
1540  desc.add<double>("d0CutOff", 3.0);
1541  desc.add<double>("Tmin", 2.0);
1542  desc.add<double>("delta_lowT", 0.001);
1543  desc.add<double>("zmerge", 0.01);
1544  desc.add<double>("dzCutOff", 3.0);
1545  desc.add<double>("Tpurge", 2.0);
1546  desc.add<int>("convergence_mode", 0);
1547  desc.add<double>("delta_highT", 0.01);
1548  desc.add<double>("Tstop", 0.5);
1549  desc.add<double>("coolingFactor", 0.6);
1550  desc.add<double>("vertexSize", 0.006);
1551  desc.add<double>("uniquetrkweight", 0.8);
1552  desc.add<double>("uniquetrkminp", 0.0);
1553  desc.add<double>("zrange", 4.0);
1554  desc.add<bool>("runInBlocks", false);
1555  desc.add<unsigned int>("block_size", 10000);
1556  desc.add<double>("overlap_frac", 0.0);
1557 }

◆ merge()

bool DAClusterizerInZ_vect::merge ( vertex_t y,
track_t tks,
double &  beta 
) const

Definition at line 472 of file DAClusterizerInZ_vect.cc.

References cms::cuda::assert(), HLT_2024v13_cff::beta, gather_cfg::cout, hlt_jetmet_dqm_QT_fromfile_cfg::critical, alignBH_cfg::fixed, and dqmdumpme::k.

472  {
473  // merge clusters that collapsed or never separated,
474  // only merge if the estimated critical temperature of the merged vertex is below the current temperature
475  // return true if vertices were merged, false otherwise
476  const unsigned int nv = y.getSize();
477 
478  if (nv < 2)
479  return false;
480 
481  // merge the smallest distance clusters first
482  std::vector<std::pair<double, unsigned int>> critical;
483  for (unsigned int k = 0; (k + 1) < nv; k++) {
484  if (std::fabs(y.zvtx[k + 1] - y.zvtx[k]) < zmerge_) {
485  critical.push_back(make_pair(std::fabs(y.zvtx[k + 1] - y.zvtx[k]), k));
486  }
487  }
488  if (critical.empty())
489  return false;
490 
491  std::stable_sort(critical.begin(), critical.end(), std::less<std::pair<double, unsigned int>>());
492 
493  for (unsigned int ik = 0; ik < critical.size(); ik++) {
494  unsigned int k = critical[ik].second;
495  double rho = y.rho[k] + y.rho[k + 1];
496 
497 #ifdef DEBUG
498  assert((k + 1) < nv);
499  if (DEBUGLEVEL > 1) {
500  std::cout << "merging " << fixed << setprecision(4) << y.zvtx[k + 1] << " and " << y.zvtx[k]
501  << " sw = " << y.sw[k] + y.sw[k + 1] << std::endl;
502  }
503 #endif
504 
505  if (rho > 0) {
506  y.zvtx[k] = (y.rho[k] * y.zvtx[k] + y.rho[k + 1] * y.zvtx[k + 1]) / rho;
507  } else {
508  y.zvtx[k] = 0.5 * (y.zvtx[k] + y.zvtx[k + 1]);
509  }
510  y.rho[k] = rho;
511  y.sw[k] += y.sw[k + 1];
512  y.removeItem(k + 1, tks);
513  set_vtx_range(beta, tks, y);
514  y.extractRaw();
515  return true;
516  }
517 
518  return false;
519 }
assert(be >=bs)
void set_vtx_range(double beta, track_t &gtracks, vertex_t &gvertices) const

◆ purge()

bool DAClusterizerInZ_vect::purge ( vertex_t y,
track_t tks,
double &  rho0,
const double  beta 
) const

Definition at line 521 of file DAClusterizerInZ_vect.cc.

References cms::cuda::assert(), HLT_2024v13_cff::beta, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::constexpr(), gather_cfg::cout, DAClusterizerInZ_vect::track_t::dz2, HLT_2024v13_cff::eps, cms::cuda::for(), DAClusterizerInZ_vect::track_t::getSize(), mps_fire::i, dqmdumpme::k, reco::ParticleMasses::k0, DAClusterizerInZ_vect::track_t::kmax, DAClusterizerInZ_vect::track_t::kmin, nt, AlCaHLTBitMon_ParallelJobs::p, DAClusterizerInZ_vect::track_t::sum_Z, DAClusterizerInZ_vect::track_t::tkwt, and DAClusterizerInZ_vect::track_t::zpca.

521  {
522  constexpr double eps = 1.e-100;
523  // eliminate clusters with only one significant/unique track
524  const unsigned int nv = y.getSize();
525  const unsigned int nt = tks.getSize();
526 
527  if (nv < 2)
528  return false;
529 
530  std::vector<double> sump_v(nv), arg_cache_v(nv), exp_cache_v(nv), pcut_cache_v(nv);
531  std::vector<int> nUnique_v(nv);
532  double* __restrict__ parg_cache;
533  double* __restrict__ pexp_cache;
534  double* __restrict__ ppcut_cache;
535  double* __restrict__ psump;
536  int* __restrict__ pnUnique;
537  int constexpr nunique_min_ = 2;
538 
539  set_vtx_range(beta, tks, y);
540 
541  parg_cache = arg_cache_v.data();
542  pexp_cache = exp_cache_v.data();
543  ppcut_cache = pcut_cache_v.data();
544  psump = sump_v.data();
545  pnUnique = nUnique_v.data();
546 
547  const auto rhoconst = rho0 * local_exp(-beta * dzCutOff_ * dzCutOff_);
548  for (unsigned int k = 0; k < nv; k++) {
549  const double pmax = y.rho[k] / (y.rho[k] + rhoconst);
550  ppcut_cache[k] = uniquetrkweight_ * pmax;
551  }
552 
553  for (unsigned int i = 0; i < nt; i++) {
554  const auto invZ = ((tks.sum_Z[i] > eps) && (tks.tkwt[i] > uniquetrkminp_)) ? 1. / tks.sum_Z[i] : 0.;
555  const auto track_z = tks.zpca[i];
556  const auto botrack_dz2 = -beta * tks.dz2[i];
557  const auto kmin = tks.kmin[i];
558  const auto kmax = tks.kmax[i];
559 
560  for (unsigned int k = kmin; k < kmax; k++) {
561  const auto mult_resz = track_z - y.zvtx[k];
562  parg_cache[k] = botrack_dz2 * (mult_resz * mult_resz);
563  }
564 
565  local_exp_list_range(parg_cache, pexp_cache, kmin, kmax);
566 
567  for (unsigned int k = kmin; k < kmax; k++) {
568  const double p = y.rho[k] * pexp_cache[k] * invZ;
569  psump[k] += p;
570  pnUnique[k] += (p > ppcut_cache[k]) ? 1 : 0;
571  }
572  }
573 
574  double sumpmin = nt;
575  unsigned int k0 = nv;
576  for (unsigned k = 0; k < nv; k++) {
577  if ((pnUnique[k] < nunique_min_) && (psump[k] < sumpmin)) {
578  sumpmin = psump[k];
579  k0 = k;
580  }
581  }
582 
583  if (k0 != nv) {
584 #ifdef DEBUG
585  assert(k0 < y.getSize());
586  if (DEBUGLEVEL > 1) {
587  std::cout << "eliminating prototype at " << std::setw(10) << std::setprecision(4) << y.zvtx[k0]
588  << " with sump=" << sumpmin << " rho*nt =" << y.rho[k0] * nt << " pnUnique=" << pnUnique[k0] << endl;
589  }
590 #endif
591 
592  y.removeItem(k0, tks);
593  set_vtx_range(beta, tks, y);
594  return true;
595  } else {
596  return false;
597  }
598 }
for(int i=first, nt=offsets[nh];i< nt;i+=gridDim.x *blockDim.x)
assert(be >=bs)
int nt
Definition: AMPTWrapper.h:42
void set_vtx_range(double beta, track_t &gtracks, vertex_t &gvertices) const

◆ set_vtx_range()

void DAClusterizerInZ_vect::set_vtx_range ( double  beta,
track_t gtracks,
vertex_t gvertices 
) const

Definition at line 230 of file DAClusterizerInZ_vect.cc.

References HLT_2024v13_cff::beta, DAClusterizerInZ_vect::track_t::dz2, DAClusterizerInZ_vect::track_t::getSize(), DAClusterizerInZ_vect::vertex_t::getSize(), DAClusterizerInZ_vect::track_t::kmax, DAClusterizerInZ_vect::track_t::kmin, SiStripPI::max, SiStripPI::min, nt, mathSSE::sqrt(), mitigatedMETSequence_cff::U, SiStripMonitorCluster_cfi::zmax, SiStripMonitorCluster_cfi::zmin, DAClusterizerInZ_vect::track_t::zpca, OfflinePixel3DPrimaryVertices_cfi::zrange, and DAClusterizerInZ_vect::vertex_t::zvtx.

230  {
231  const unsigned int nv = gvertices.getSize();
232  const unsigned int nt = gtracks.getSize();
233 
234  if (nv == 0) {
235  edm::LogWarning("DAClusterizerinZ_vect") << "empty cluster list in set_vtx_range";
236  return;
237  }
238 
239  for (auto itrack = 0U; itrack < nt; ++itrack) {
240  double zrange = max(sel_zrange_ / sqrt(beta * gtracks.dz2[itrack]), zrange_min_);
241 
242  double zmin = gtracks.zpca[itrack] - zrange;
243  unsigned int kmin = min(nv - 1, gtracks.kmin[itrack]);
244  // find the smallest vertex_z that is larger than zmin
245  if (gvertices.zvtx[kmin] > zmin) {
246  while ((kmin > 0) && (gvertices.zvtx[kmin - 1] > zmin)) {
247  kmin--;
248  }
249  } else {
250  while ((kmin < (nv - 1)) && (gvertices.zvtx[kmin] < zmin)) {
251  kmin++;
252  }
253  }
254 
255  double zmax = gtracks.zpca[itrack] + zrange;
256  unsigned int kmax = min(nv - 1, gtracks.kmax[itrack] - 1);
257  // note: kmax points to the last vertex in the range, while gtracks.kmax points to the entry BEHIND the last vertex
258  // find the largest vertex_z that is smaller than zmax
259  if (gvertices.zvtx[kmax] < zmax) {
260  while ((kmax < (nv - 1)) && (gvertices.zvtx[kmax + 1] < zmax)) {
261  kmax++;
262  }
263  } else {
264  while ((kmax > 0) && (gvertices.zvtx[kmax] > zmax)) {
265  kmax--;
266  }
267  }
268 
269  if (kmin <= kmax) {
270  gtracks.kmin[itrack] = kmin;
271  gtracks.kmax[itrack] = kmax + 1;
272  } else {
273  gtracks.kmin[itrack] = max(0U, min(kmin, kmax));
274  gtracks.kmax[itrack] = min(nv, max(kmin, kmax) + 1);
275  }
276  }
277 }
T sqrt(T t)
Definition: SSEVec.h:23
int nt
Definition: AMPTWrapper.h:42
Log< level::Warning, false > LogWarning

◆ split()

bool DAClusterizerInZ_vect::split ( const double  beta,
track_t t,
vertex_t y,
double  threshold = 1. 
) const

Definition at line 651 of file DAClusterizerInZ_vect.cc.

References cms::cuda::assert(), HLT_2024v13_cff::beta, ALPAKA_ACCELERATOR_NAMESPACE::brokenline::constexpr(), gather_cfg::cout, hlt_jetmet_dqm_QT_fromfile_cfg::critical, DAClusterizerInZ_vect::track_t::dz2, MillePedeFileConverter_cfg::e, geometryDiff::epsilon, alignBH_cfg::fixed, DAClusterizerInZ_vect::track_t::getSize(), mps_fire::i, dqmdumpme::k, nt, AlCaHLTBitMon_ParallelJobs::p, LaserDQM_cfg::p1, SiStripOfflineCRack_cfg::p2, edm::second(), submitPVValidationJobs::split(), mathSSE::sqrt(), DAClusterizerInZ_vect::track_t::sum_Z, submitPVValidationJobs::t, DiMuonV_cfg::threshold, DAClusterizerInZ_vect::track_t::tkwt, update, w(), w2, testProducerWithPsetDescEmpty_cfi::z2, and DAClusterizerInZ_vect::track_t::zpca.

651  {
652  // split only critical vertices (Tc >~ T=1/beta <==> beta*Tc>~1)
653  // returns true if at least one cluster was split
654 
655  // update the sums needed for Tc, rho0 is never non-zero while splitting is still active
656  update(beta, tks, y, 0., true); // the "true" flag enables Tc evaluation
657 
658  constexpr double epsilon = 1e-3; // minimum split size
659  unsigned int nv = y.getSize();
660 
661  // avoid left-right biases by splitting highest Tc first
662 
663  std::vector<std::pair<double, unsigned int>> critical;
664  for (unsigned int k = 0; k < nv; k++) {
665  double Tc = 2 * y.swE[k] / y.sw[k];
666  if (beta * Tc > threshold) {
667  critical.push_back(make_pair(Tc, k));
668  }
669  }
670  if (critical.empty())
671  return false;
672 
673  std::stable_sort(critical.begin(), critical.end(), std::greater<std::pair<double, unsigned int>>());
674 
675  bool split = false;
676  const unsigned int nt = tks.getSize();
677 
678  for (unsigned int ic = 0; ic < critical.size(); ic++) {
679  unsigned int k = critical[ic].second;
680 
681  // estimate subcluster positions and weight
682  double p1 = 0, z1 = 0, w1 = 0;
683  double p2 = 0, z2 = 0, w2 = 0;
684  for (unsigned int i = 0; i < nt; i++) {
685  if (tks.sum_Z[i] > 1.e-100) {
686  // winner-takes-all, usually overestimates splitting
687  double tl = tks.zpca[i] < y.zvtx[k] ? 1. : 0.;
688  double tr = 1. - tl;
689 
690  // soften it, especially at low T
691  double arg = (tks.zpca[i] - y.zvtx[k]) * sqrt(beta * tks.dz2[i]);
692  if (std::fabs(arg) < 20) {
693  double t = local_exp(-arg);
694  tl = t / (t + 1.);
695  tr = 1 / (t + 1.);
696  }
697 
698  double p = y.rho[k] * tks.tkwt[i] * local_exp(-beta * Eik(tks.zpca[i], y.zvtx[k], tks.dz2[i])) / tks.sum_Z[i];
699  double w = p * tks.dz2[i];
700  p1 += p * tl;
701  z1 += w * tl * tks.zpca[i];
702  w1 += w * tl;
703  p2 += p * tr;
704  z2 += w * tr * tks.zpca[i];
705  w2 += w * tr;
706  }
707  }
708 
709  if (w1 > 0) {
710  z1 = z1 / w1;
711  } else {
712  z1 = y.zvtx[k] - epsilon;
713  }
714  if (w2 > 0) {
715  z2 = z2 / w2;
716  } else {
717  z2 = y.zvtx[k] + epsilon;
718  }
719 
720  // reduce split size if there is not enough room
721  if ((k > 0) && (z1 < (0.6 * y.zvtx[k] + 0.4 * y.zvtx[k - 1]))) {
722  z1 = 0.6 * y.zvtx[k] + 0.4 * y.zvtx[k - 1];
723  }
724  if ((k + 1 < nv) && (z2 > (0.6 * y.zvtx[k] + 0.4 * y.zvtx[k + 1]))) {
725  z2 = 0.6 * y.zvtx[k] + 0.4 * y.zvtx[k + 1];
726  }
727 
728 #ifdef DEBUG
729  assert(k < nv);
730  if (DEBUGLEVEL > 1) {
731  if (std::fabs(y.zvtx[k] - zdumpcenter_) < zdumpwidth_) {
732  std::cout << " T= " << std::setw(8) << 1. / beta << " Tc= " << critical[ic].first << " splitting "
733  << std::fixed << std::setprecision(4) << y.zvtx[k] << " --> " << z1 << "," << z2 << " [" << p1
734  << "," << p2 << "]";
735  if (std::fabs(z2 - z1) > epsilon) {
736  std::cout << std::endl;
737  } else {
738  std::cout << " rejected " << std::endl;
739  }
740  }
741  }
742 #endif
743 
744  // split if the new subclusters are significantly separated
745  if ((z2 - z1) > epsilon) {
746  split = true;
747  double pk1 = p1 * y.rho[k] / (p1 + p2);
748  double pk2 = p2 * y.rho[k] / (p1 + p2);
749  y.zvtx[k] = z2;
750  y.rho[k] = pk2;
751  y.insertItem(k, z1, pk1, tks);
752  if (k == 0)
753  y.extractRaw();
754 
755  nv++;
756 
757  // adjust remaining pointers
758  for (unsigned int jc = ic; jc < critical.size(); jc++) {
759  if (critical[jc].second >= k) {
760  critical[jc].second++;
761  }
762  }
763  } else {
764 #ifdef DEBUG
765  std::cout << "warning ! split rejected, too small." << endl;
766 #endif
767  }
768  }
769 
770  return split;
771 }
common ppss p3p6s2 common epss epspn46 common const1 w2
Definition: inclppp.h:1
T w() const
assert(be >=bs)
A arg
Definition: Factorize.h:31
U second(std::pair< T, U > const &p)
double update(double beta, track_t &gtracks, vertex_t &gvertices, const double rho0=0, const bool updateTc=false) const
T sqrt(T t)
Definition: SSEVec.h:23
int nt
Definition: AMPTWrapper.h:42
bool split(const double beta, track_t &t, vertex_t &y, double threshold=1.) const

◆ thermalize()

unsigned int DAClusterizerInZ_vect::thermalize ( double  beta,
track_t gtracks,
vertex_t gvertices,
const double  delta_max,
const double  rho0 = 0. 
) const

Definition at line 424 of file DAClusterizerInZ_vect.cc.

References funct::abs(), HLT_2024v13_cff::beta, gather_cfg::cout, dumpMFGeometry_cfg::delta, GCP_Ntuples_cfg::dump, dqmdumpme::k, SiStripPI::max, mathSSE::sqrt(), update, and findQualityFiles::v.

425  {
426  unsigned int niter = 0;
427  double delta = 0;
428  double delta_max = delta_lowT_;
429 
430  if (convergence_mode_ == 0) {
431  delta_max = delta_max0;
432  } else if (convergence_mode_ == 1) {
433  delta_max = delta_lowT_ / sqrt(std::max(beta, 1.0));
434  }
435 
436  set_vtx_range(beta, tks, v);
437  double delta_sum_range = 0; // accumulate max(|delta-z|) as a lower bound
438  std::vector<double> z0 = v.zvtx_vec;
439 
440  while (niter++ < maxIterations_) {
441  delta = update(beta, tks, v, rho0);
442  delta_sum_range += delta;
443 
444  if (delta_sum_range > zrange_min_) {
445  for (unsigned int k = 0; k < v.getSize(); k++) {
446  if (std::abs(v.zvtx_vec[k] - z0[k]) > zrange_min_) {
447  set_vtx_range(beta, tks, v);
448  delta_sum_range = 0;
449  z0 = v.zvtx_vec;
450  break;
451  }
452  }
453  }
454 
455  if (delta < delta_max) {
456  break;
457  }
458  }
459 
460 #ifdef DEBUG
461  if (DEBUGLEVEL > 0) {
462  std::cout << "DAClusterizerInZ_vect.thermalize niter = " << niter << " at T = " << 1 / beta
463  << " nv = " << v.getSize() << std::endl;
464  if (DEBUGLEVEL > 2)
465  dump(beta, v, tks, 0, rho0);
466  }
467 #endif
468 
469  return niter;
470 }
double update(double beta, track_t &gtracks, vertex_t &gvertices, const double rho0=0, const bool updateTc=false) const
T sqrt(T t)
Definition: SSEVec.h:23
void dump(const double beta, const vertex_t &y, const track_t &tks, const int verbosity=0, const double rho0=0.) const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
void set_vtx_range(double beta, track_t &gtracks, vertex_t &gvertices) const

◆ update()

double DAClusterizerInZ_vect::update ( double  beta,
track_t gtracks,
vertex_t gvertices,
const double  rho0 = 0,
const bool  updateTc = false 
) const

Definition at line 288 of file DAClusterizerInZ_vect.cc.

References funct::abs(), HLT_2024v13_cff::beta, dumpMFGeometry_cfg::delta, DAClusterizerInZ_vect::vertex_t::exp, DAClusterizerInZ_vect::vertex_t::exp_arg, DAClusterizerInZ_vect::track_t::getSize(), DAClusterizerInZ_vect::vertex_t::getSize(), edm::isNotFinite(), dqmdumpme::k, DAClusterizerInZ_vect::track_t::kmax, DAClusterizerInZ_vect::track_t::kmin, SiStripPI::max, nt, DAClusterizerInZ_vect::track_t::osumtkwt, DAClusterizerInZ_vect::vertex_t::se, DAClusterizerInZ_vect::track_t::sum_Z, DAClusterizerInZ_vect::vertex_t::sw, DAClusterizerInZ_vect::vertex_t::swE, DAClusterizerInZ_vect::vertex_t::swz, DiMuonV_cfg::tracks, mitigatedMETSequence_cff::U, AlignmentTracksFromVertexSelector_cfi::vertices, and w().

Referenced by progressbar.ProgressBar::__next__(), MatrixUtil.Matrix::__setitem__(), MatrixUtil.Steps::__setitem__(), progressbar.ProgressBar::finish(), and MatrixUtil.Steps::overwrite().

289  {
290  // update weights and vertex positions
291  // returns the maximum of changes of vertex positions
292  // sums needed for Tc are only updated if updateTC == true
293 
294  const unsigned int nt = gtracks.getSize();
295  const unsigned int nv = gvertices.getSize();
296  auto osumtkwt = gtracks.osumtkwt;
297 
298  double Z_init = 0;
299  if (rho0 > 0) {
300  Z_init = rho0 * local_exp(-beta * dzCutOff_ * dzCutOff_); // cut-off
301  }
302 
303  // define kernels
304  auto kernel_calc_exp_arg_range = [beta](const unsigned int itrack,
305  track_t const& tracks,
306  vertex_t const& vertices,
307  const unsigned int kmin,
308  const unsigned int kmax) {
309  const double track_z = tracks.zpca[itrack];
310  const double botrack_dz2 = -beta * tracks.dz2[itrack];
311 
312  // auto-vectorized
313  for (unsigned int ivertex = kmin; ivertex < kmax; ++ivertex) {
314  auto mult_res = track_z - vertices.zvtx[ivertex];
315  vertices.exp_arg[ivertex] = botrack_dz2 * (mult_res * mult_res);
316  }
317  };
318 
319  auto kernel_add_Z_range = [Z_init](
320  vertex_t const& vertices, const unsigned int kmin, const unsigned int kmax) -> double {
321  double ZTemp = Z_init;
322  for (unsigned int ivertex = kmin; ivertex < kmax; ++ivertex) {
323  ZTemp += vertices.rho[ivertex] * vertices.exp[ivertex];
324  }
325  return ZTemp;
326  };
327 
328  auto kernel_calc_normalization_range = [updateTc](const unsigned int track_num,
329  track_t& tracks,
330  vertex_t& vertices,
331  const unsigned int kmin,
332  const unsigned int kmax) {
333  auto o_trk_sum_Z = tracks.tkwt[track_num] / tracks.sum_Z[track_num];
334  auto o_trk_dz2 = tracks.dz2[track_num];
335  auto tmp_trk_z = tracks.zpca[track_num];
336 
337  // auto-vectorized
338  if (updateTc) {
339 #pragma GCC ivdep
340  for (unsigned int k = kmin; k < kmax; ++k) {
341  vertices.se[k] += vertices.exp[k] * o_trk_sum_Z;
342  auto w = vertices.rho[k] * vertices.exp[k] * (o_trk_sum_Z * o_trk_dz2);
343  vertices.sw[k] += w;
344  vertices.swz[k] += w * tmp_trk_z;
345  vertices.swE[k] += w * vertices.exp_arg[k];
346  }
347  } else {
348  // same loop but without updating sWE
349 #pragma GCC ivdep
350  for (unsigned int k = kmin; k < kmax; ++k) {
351  vertices.se[k] += vertices.exp[k] * o_trk_sum_Z;
352  auto w = vertices.rho[k] * vertices.exp[k] * (o_trk_sum_Z * o_trk_dz2);
353  vertices.sw[k] += w;
354  vertices.swz[k] += w * tmp_trk_z;
355  }
356  }
357  };
358 
359  if (updateTc) {
360  for (auto ivertex = 0U; ivertex < nv; ++ivertex) {
361  gvertices.se[ivertex] = 0.0;
362  gvertices.sw[ivertex] = 0.0;
363  gvertices.swz[ivertex] = 0.0;
364  gvertices.swE[ivertex] = 0.0;
365  }
366  } else {
367  for (auto ivertex = 0U; ivertex < nv; ++ivertex) {
368  gvertices.se[ivertex] = 0.0;
369  gvertices.sw[ivertex] = 0.0;
370  gvertices.swz[ivertex] = 0.0;
371  }
372  }
373 
374  // loop over tracks
375  for (auto itrack = 0U; itrack < nt; ++itrack) {
376  const unsigned int kmin = gtracks.kmin[itrack];
377  const unsigned int kmax = gtracks.kmax[itrack];
378 
379  kernel_calc_exp_arg_range(itrack, gtracks, gvertices, kmin, kmax);
380  local_exp_list_range(gvertices.exp_arg, gvertices.exp, kmin, kmax);
381  gtracks.sum_Z[itrack] = kernel_add_Z_range(gvertices, kmin, kmax);
382 
383  if (edm::isNotFinite(gtracks.sum_Z[itrack]))
384  gtracks.sum_Z[itrack] = 0.0;
385 
386  if (gtracks.sum_Z[itrack] > 1.e-100) {
387  kernel_calc_normalization_range(itrack, gtracks, gvertices, kmin, kmax);
388  }
389  }
390 
391  // (un-)apply the factor -beta which is needed in exp_arg, but not in swE
392  if (updateTc) {
393  auto obeta = -1. / beta;
394  for (auto ivertex = 0U; ivertex < nv; ++ivertex) {
395  gvertices.swE[ivertex] *= obeta;
396  }
397  }
398 
399  // now update z and rho
400  auto kernel_calc_z = [osumtkwt, nv](vertex_t& vertices) -> double {
401  double delta = 0;
402  // does not vectorize
403  for (unsigned int ivertex = 0; ivertex < nv; ++ivertex) {
404  if (vertices.sw[ivertex] > 0) {
405  auto znew = vertices.swz[ivertex] / vertices.sw[ivertex];
406  // prevents from vectorizing if
407  delta = max(std::abs(vertices.zvtx[ivertex] - znew), delta);
408  vertices.zvtx[ivertex] = znew;
409  }
410  }
411 
412  for (unsigned int ivertex = 0; ivertex < nv; ++ivertex)
413  vertices.rho[ivertex] = vertices.rho[ivertex] * vertices.se[ivertex] * osumtkwt;
414 
415  return delta;
416  };
417 
418  double delta = kernel_calc_z(gvertices);
419 
420  // return how much the prototypes moved
421  return delta;
422 }
T w() const
constexpr bool isNotFinite(T x)
Definition: isFinite.h:9
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int nt
Definition: AMPTWrapper.h:42
std::vector< TransientVertex > vertices(const std::vector< reco::TransientTrack > &tracks) const override

◆ verify()

void DAClusterizerInZ_vect::verify ( const vertex_t v,
const track_t tks,
unsigned int  nv = 999999,
unsigned int  nt = 999999 
) const

Definition at line 115 of file DAClusterizerInZ_vect.cc.

References cms::cuda::assert(), gather_cfg::cout, DAClusterizerInZ_vect::track_t::dz2, DAClusterizerInZ_vect::track_t::dz2_vec, DAClusterizerInZ_vect::track_t::getSize(), mps_fire::i, dqmdumpme::k, DAClusterizerInZ_vect::track_t::kmax, DAClusterizerInZ_vect::track_t::kmin, nt, DAClusterizerInZ_vect::track_t::sum_Z, DAClusterizerInZ_vect::track_t::sum_Z_vec, DAClusterizerInZ_vect::track_t::tkwt, DAClusterizerInZ_vect::track_t::tkwt_vec, DAClusterizerInZ_vect::track_t::tt, findQualityFiles::v, DAClusterizerInZ_vect::track_t::zpca, and DAClusterizerInZ_vect::track_t::zpca_vec.

115  {
116  if (!(nv == 999999)) {
117  assert(nv == v.getSize());
118  } else {
119  nv = v.getSize();
120  }
121 
122  if (!(nt == 999999)) {
123  assert(nt == tks.getSize());
124  } else {
125  nt = tks.getSize();
126  }
127 
128  assert(v.zvtx_vec.size() == nv);
129  assert(v.rho_vec.size() == nv);
130  assert(v.swz_vec.size() == nv);
131  assert(v.exp_arg_vec.size() == nv);
132  assert(v.exp_vec.size() == nv);
133  assert(v.se_vec.size() == nv);
134  assert(v.swz_vec.size() == nv);
135  assert(v.swE_vec.size() == nv);
136 
137  assert(v.zvtx == &v.zvtx_vec.front());
138  assert(v.rho == &v.rho_vec.front());
139  assert(v.exp_arg == &v.exp_arg_vec.front());
140  assert(v.sw == &v.sw_vec.front());
141  assert(v.swz == &v.swz_vec.front());
142  assert(v.se == &v.se_vec.front());
143  assert(v.swE == &v.swE_vec.front());
144 
145  for (unsigned int k = 0; k < nv - 1; k++) {
146  if (v.zvtx_vec[k] <= v.zvtx_vec[k + 1])
147  continue;
148  cout << " Z, cluster z-ordering assertion failure z[" << k << "] =" << v.zvtx_vec[k] << " z[" << k + 1
149  << "] =" << v.zvtx_vec[k + 1] << endl;
150  }
151 
152  assert(nt == tks.zpca_vec.size());
153  assert(nt == tks.dz2_vec.size());
154  assert(nt == tks.tt.size());
155  assert(nt == tks.tkwt_vec.size());
156  assert(nt == tks.sum_Z_vec.size());
157  assert(nt == tks.kmin.size());
158  assert(nt == tks.kmax.size());
159 
160  assert(tks.zpca == &tks.zpca_vec.front());
161  assert(tks.dz2 == &tks.dz2_vec.front());
162  assert(tks.tkwt == &tks.tkwt_vec.front());
163  assert(tks.sum_Z == &tks.sum_Z_vec.front());
164 
165  for (unsigned int i = 0; i < nt; i++) {
166  if ((tks.kmin[i] < tks.kmax[i]) && (tks.kmax[i] <= nv))
167  continue;
168  cout << "track vertex range assertion failure" << i << "/" << nt << " kmin,kmax=" << tks.kmin[i] << ", "
169  << tks.kmax[i] << " nv=" << nv << endl;
170  }
171 
172  for (unsigned int i = 0; i < nt; i++) {
173  assert((tks.kmin[i] < tks.kmax[i]) && (tks.kmax[i] <= nv));
174  }
175 }
assert(be >=bs)
int nt
Definition: AMPTWrapper.h:42

◆ vertices()

vector< TransientVertex > DAClusterizerInZ_vect::vertices ( const std::vector< reco::TransientTrack > &  tracks) const
overridevirtual

Implements TrackClusterizerInZ.

Definition at line 1334 of file DAClusterizerInZ_vect.cc.

References DiMuonV_cfg::tracks.

1334  {
1335  if (runInBlocks_ and (block_size_ < tracks.size())) //doesn't bother if low number of tracks
1336  return vertices_in_blocks(tracks);
1337  else
1338  return vertices_no_blocks(tracks);
1339 }
std::vector< TransientVertex > vertices_no_blocks(const std::vector< reco::TransientTrack > &tracks) const
std::vector< TransientVertex > vertices_in_blocks(const std::vector< reco::TransientTrack > &tracks) const

◆ vertices_in_blocks()

vector< TransientVertex > DAClusterizerInZ_vect::vertices_in_blocks ( const std::vector< reco::TransientTrack > &  tracks) const

Definition at line 931 of file DAClusterizerInZ_vect.cc.

References a, funct::abs(), b, HLT_2024v13_cff::beta, groupFilesInBlocks::block, bsc_activity_cfg::clusters, gather_cfg::cout, GCP_Ntuples_cfg::dump, MillePedeFileConverter_cfg::e, relativeConstraints::empty, DAClusterizerInZ_vect::track_t::extractRaw(), ntuplemaker::fill, dqmdumpme::first, mps_fire::i, createfilelist::int, dqmdumpme::k, SiStripPI::max, merge(), SiStripPI::min, nt, AlCaHLTBitMon_ParallelJobs::p, position, jetUpdater_cfi::sort, submitPVValidationJobs::split(), mathSSE::sqrt(), DiMuonV_cfg::threshold, DiMuonV_cfg::tracks, mitigatedMETSequence_cff::U, update, findQualityFiles::v, SiStripMonitorCluster_cfi::zmax, SiStripMonitorCluster_cfi::zmin, and OfflinePixel3DPrimaryVertices_cfi::zrange.

931  {
932  vector<reco::TransientTrack> sorted_tracks;
933  vector<pair<float, float>> vertices_tot; // z, rho for each vertex
934  for (unsigned int i = 0; i < tracks.size(); i++) {
935  sorted_tracks.push_back(tracks[i]);
936  }
937  double rho0, beta;
938  std::sort(sorted_tracks.begin(),
939  sorted_tracks.end(),
940  [](const reco::TransientTrack& a, const reco::TransientTrack& b) -> bool {
941  return (a.stateAtBeamLine().trackStateAtPCA()).position().z() <
942  (b.stateAtBeamLine().trackStateAtPCA()).position().z();
943  });
944 
945  unsigned int nBlocks = (unsigned int)std::floor(sorted_tracks.size() / (block_size_ * (1 - overlap_frac_)));
946  if (nBlocks < 1) {
947  nBlocks = 1;
948  edm::LogWarning("DAClusterizerinZ_vect")
949  << "Warning nBlocks was 0 with ntracks = " << sorted_tracks.size() << " block_size = " << block_size_
950  << " and overlap fraction = " << overlap_frac_ << ". Setting nBlocks = 1";
951  }
952  for (unsigned int block = 0; block < nBlocks; block++) {
953  vector<reco::TransientTrack> block_tracks;
954  unsigned int begin = (unsigned int)(block * block_size_ * (1 - overlap_frac_));
955  unsigned int end = (unsigned int)std::min(begin + block_size_, (unsigned int)sorted_tracks.size());
956  for (unsigned int i = begin; i < end; i++) {
957  block_tracks.push_back(sorted_tracks[i]);
958  }
959  if (block_tracks.empty()) {
960  continue;
961  }
962 
963 #ifdef DEBUG
964  std::cout << "Running vertices_in_blocks on" << std::endl;
965  std::cout << "- block no." << block << " on " << nBlocks << " blocks " << std::endl;
966  std::cout << "- block track size: " << sorted_tracks.size() << " - block size: " << block_size_ << std::endl;
967 #endif
968  track_t&& tks = fill(block_tracks);
969  tks.extractRaw();
970 
971  rho0 = 0.0; // start with no outlier rejection
972 
973  vertex_t y; // the vertex prototypes
974 
975  // initialize:single vertex at infinite temperature
976  y.addItem(0, 1.0);
977  clear_vtx_range(tks, y);
978 
979  // estimate first critical temperature
980  beta = beta0(betamax_, tks, y);
981 #ifdef DEBUG
982  if (DEBUGLEVEL > 0)
983  std::cout << "Beta0 is " << beta << std::endl;
984 #endif
985 
986  thermalize(beta, tks, y, delta_highT_);
987 
988  // annealing loop, stop when T<Tmin (i.e. beta>1/Tmin)
989 
990  double betafreeze = betamax_ * sqrt(coolingFactor_);
991  while (beta < betafreeze) {
992  while (merge(y, tks, beta)) {
993  update(beta, tks, y, rho0, false);
994  }
995  split(beta, tks, y);
996 
998  thermalize(beta, tks, y, delta_highT_);
999  }
1000 
1001 #ifdef DEBUG
1002  verify(y, tks);
1003 
1004  if (DEBUGLEVEL > 0) {
1005  std::cout << "DAClusterizerInZSubCluster_vect::vertices :"
1006  << "last round of splitting" << std::endl;
1007  }
1008 #endif
1009 
1010  set_vtx_range(beta, tks, y);
1011  update(beta, tks, y, rho0, false);
1012 
1013  while (merge(y, tks, beta)) {
1014  set_vtx_range(beta, tks, y);
1015  update(beta, tks, y, rho0, false);
1016  }
1017 
1018  unsigned int ntry = 0;
1019  double threshold = 1.0;
1020  while (split(beta, tks, y, threshold) && (ntry++ < 10)) {
1021  thermalize(beta, tks, y, delta_highT_, rho0); // rho0 = 0. here
1022  while (merge(y, tks, beta)) {
1023  update(beta, tks, y, rho0, false);
1024  }
1025 
1026  // relax splitting a bit to reduce multiple split-merge cycles of the same cluster
1027  threshold *= 1.1;
1028  }
1029 
1030 #ifdef DEBUG
1031  verify(y, tks);
1032  if (DEBUGLEVEL > 0) {
1033  std::cout << "DAClusterizerInZSubCluster_vect::vertices :"
1034  << "turning on outlier rejection at T=" << 1 / beta << std::endl;
1035  }
1036 #endif
1037 
1038  // switch on outlier rejection at T=Tmin
1039  if (dzCutOff_ > 0) {
1040  rho0 = y.getSize() > 1 ? 1. / y.getSize() : 1.;
1041  for (unsigned int a = 0; a < 5; a++) {
1042  update(beta, tks, y, a * rho0 / 5.); // adiabatic turn-on
1043  }
1044  }
1045 
1046  thermalize(beta, tks, y, delta_lowT_, rho0);
1047 
1048 #ifdef DEBUG
1049  verify(y, tks);
1050  if (DEBUGLEVEL > 0) {
1051  std::cout << "DAClusterizerInZSubCluster_vect::vertices :"
1052  << "merging with outlier rejection at T=" << 1 / beta << std::endl;
1053  }
1054  if (DEBUGLEVEL > 2)
1055  dump(beta, y, tks, 2, rho0);
1056 #endif
1057 
1058  // merge again (some cluster split by outliers collapse here)
1059  while (merge(y, tks, beta)) {
1060  set_vtx_range(beta, tks, y);
1061  update(beta, tks, y, rho0, false);
1062  }
1063 
1064 #ifdef DEBUG
1065  verify(y, tks);
1066  if (DEBUGLEVEL > 0) {
1067  std::cout << "DAClusterizerInZSubCluster_vect::vertices :"
1068  << "after merging with outlier rejection at T=" << 1 / beta << std::endl;
1069  }
1070  if (DEBUGLEVEL > 2)
1071  dump(beta, y, tks, 2, rho0);
1072 #endif
1073 
1074  // go down to the purging temperature (if it is lower than tmin)
1075  while (beta < betapurge_) {
1077  thermalize(beta, tks, y, delta_lowT_, rho0);
1078  }
1079 
1080 #ifdef DEBUG
1081  verify(y, tks);
1082  if (DEBUGLEVEL > 0) {
1083  std::cout << "DAClusterizerInZSubCluster_vect::vertices :"
1084  << "purging at T=" << 1 / beta << std::endl;
1085  }
1086 #endif
1087 
1088  // eliminate insignificant vertices, this is more restrictive at higher T
1089  while (purge(y, tks, rho0, beta)) {
1090  thermalize(beta, tks, y, delta_lowT_, rho0);
1091  }
1092 
1093 #ifdef DEBUG
1094  verify(y, tks);
1095  if (DEBUGLEVEL > 0) {
1096  std::cout << "DAClusterizerInZSubCluster_vect::vertices :"
1097  << "last cooling T=" << 1 / beta << std::endl;
1098  }
1099 #endif
1100 
1101  // optionally cool some more without doing anything, to make the assignment harder
1102  while (beta < betastop_) {
1104  thermalize(beta, tks, y, delta_lowT_, rho0);
1105  }
1106 
1107 #ifdef DEBUG
1108  verify(y, tks);
1109  if (DEBUGLEVEL > 0) {
1110  std::cout << "DAClusterizerInZSubCluster_vect::vertices :"
1111  << "stop cooling at T=" << 1 / beta << std::endl;
1112  }
1113  if (DEBUGLEVEL > 2)
1114  dump(beta, y, tks, 2, rho0);
1115 #endif
1116 
1117  for (unsigned int ivertex = 0; ivertex < y.getSize(); ivertex++) {
1118  if (y.zvtx_vec[ivertex] != 0 && y.rho_vec[ivertex] != 0) {
1119  vertices_tot.push_back(pair(y.zvtx_vec[ivertex], y.rho_vec[ivertex]));
1120 #ifdef DEBUG
1121  std::cout << "Found new vertex " << y.zvtx_vec[ivertex] << " , " << y.rho_vec[ivertex] << std::endl;
1122 #endif
1123  }
1124  }
1125  }
1126 
1127  std::sort(vertices_tot.begin(),
1128  vertices_tot.end(),
1129  [](const pair<float, float>& a, const pair<float, float>& b) -> bool { return a.first < b.first; });
1130 
1131  // reassign tracks to vertices
1132  track_t&& tracks_tot = fill(tracks);
1133  const unsigned int nv = vertices_tot.size();
1134  const unsigned int nt = tracks_tot.getSize();
1135 
1136  for (auto itrack = 0U; itrack < nt; ++itrack) {
1137  double zrange = max(sel_zrange_ / sqrt(beta * tracks_tot.dz2[itrack]), zrange_min_);
1138 
1139  double zmin = tracks_tot.zpca[itrack] - zrange;
1140  unsigned int kmin = min(nv - 1, tracks_tot.kmin[itrack]);
1141  // find the smallest vertex_z that is larger than zmin
1142  if (vertices_tot[kmin].first > zmin) {
1143  while ((kmin > 0) && (vertices_tot[kmin - 1].first > zmin)) {
1144  kmin--;
1145  }
1146  } else {
1147  while ((kmin < (nv - 1)) && (vertices_tot[kmin].first < zmin)) {
1148  kmin++;
1149  }
1150  }
1151 
1152  double zmax = tracks_tot.zpca[itrack] + zrange;
1153  unsigned int kmax = min(nv - 1, tracks_tot.kmax[itrack] - 1);
1154  // note: kmax points to the last vertex in the range, while gtracks.kmax points to the entry BEHIND the last vertex
1155  // find the largest vertex_z that is smaller than zmax
1156  if (vertices_tot[kmax].first < zmax) {
1157  while ((kmax < (nv - 1)) && (vertices_tot[kmax + 1].first < zmax)) {
1158  kmax++;
1159  }
1160  } else {
1161  while ((kmax > 0) && (vertices_tot[kmax].first > zmax)) {
1162  kmax--;
1163  }
1164  }
1165 
1166  if (kmin <= kmax) {
1167  tracks_tot.kmin[itrack] = kmin;
1168  tracks_tot.kmax[itrack] = kmax + 1;
1169  } else {
1170  tracks_tot.kmin[itrack] = max(0U, min(kmin, kmax));
1171  tracks_tot.kmax[itrack] = min(nv, max(kmin, kmax) + 1);
1172  }
1173  }
1174 
1175  rho0 = nv > 1 ? 1. / nv : 1.;
1176  const auto z_sum_init = rho0 * local_exp(-beta * dzCutOff_ * dzCutOff_);
1177 
1178  std::vector<std::vector<unsigned int>> vtx_track_indices(nv);
1179  for (unsigned int i = 0; i < nt; i++) {
1180  const auto kmin = tracks_tot.kmin[i];
1181  const auto kmax = tracks_tot.kmax[i];
1182  double p_max = -1;
1183  unsigned int iMax = 10000; //just a "big" number w.r.t. number of vertices
1184  float sum_Z = z_sum_init;
1185  for (auto k = kmin; k < kmax; k++) {
1186  float v_exp = local_exp(-beta * Eik(tracks_tot.zpca[i], vertices_tot[k].first, tracks_tot.dz2[i]));
1187  sum_Z += vertices_tot[k].second * v_exp;
1188  }
1189  double invZ = sum_Z > 1e-100 ? 1. / sum_Z : 0.0;
1190  for (auto k = kmin; k < kmax && invZ != 0.0; k++) {
1191  float v_exp = local_exp(-beta * Eik(tracks_tot.zpca[i], vertices_tot[k].first, tracks_tot.dz2[i]));
1192  double p = vertices_tot[k].second * v_exp * invZ;
1193  if (p > p_max && p > mintrkweight_) {
1194  p_max = p;
1195  iMax = k;
1196  }
1197  }
1198  if (iMax < vtx_track_indices.size()) {
1199  vtx_track_indices[iMax].push_back(i);
1200  }
1201  }
1202 #ifdef DEBUG
1203  for (auto itrack = 0U; itrack < nt; ++itrack) {
1204  std::cout << "itrack " << itrack << " , " << tracks_tot.kmin[itrack] << " , " << tracks_tot.kmax[itrack]
1205  << std::endl;
1206  }
1207 #endif
1208 
1209  vector<TransientVertex> clusters;
1210  if (nv == 0) {
1211  return clusters;
1212  }
1213 
1214  GlobalError dummyError(0.01, 0, 0.01, 0., 0., 0.01);
1215  vector<reco::TransientTrack> vertexTracks;
1216 
1217  for (unsigned int k = 0; k < nv; k++) {
1218  if (!vtx_track_indices[k].empty()) {
1219  for (auto i : vtx_track_indices[k]) {
1220  vertexTracks.push_back(*(tracks_tot.tt[i]));
1221 #ifdef DEBUG
1222  std::cout << vertices_tot[k].first << ","
1223  << (*(tracks_tot.tt[i])).stateAtBeamLine().trackStateAtPCA().position().z() << std::endl;
1224 #endif
1225  }
1226  }
1227 
1228  // implement what clusterize() did before : merge left-to-right if distance < 2 * vertexSize_
1229  if ((k + 1 == nv) || (abs(vertices_tot[k + 1].first - vertices_tot[k].first) > (2 * vertexSize_))) {
1230  // close a cluster
1231  if (vertexTracks.size() > 1) {
1232  GlobalPoint pos(0, 0, vertices_tot[k].first); // only usable with subsequent fit
1233  TransientVertex v(pos, dummyError, vertexTracks, 0);
1234  clusters.push_back(v);
1235  }
1236  vertexTracks.clear();
1237  }
1238  }
1239 
1240  return clusters;
1241 } // end of vertices_in_blocks
double beta0(const double betamax, track_t const &tks, vertex_t const &y) const
bool merge(vertex_t &y, track_t &tks, double &beta) const
void clear_vtx_range(track_t &gtracks, vertex_t &gvertices) const
bool purge(vertex_t &, track_t &, double &, const double) const
double update(double beta, track_t &gtracks, vertex_t &gvertices, const double rho0=0, const bool updateTc=false) const
T sqrt(T t)
Definition: SSEVec.h:23
void dump(const double beta, const vertex_t &y, const track_t &tks, const int verbosity=0, const double rho0=0.) const
track_t fill(const std::vector< reco::TransientTrack > &tracks) const
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int nt
Definition: AMPTWrapper.h:42
unsigned int thermalize(double beta, track_t &gtracks, vertex_t &gvertices, const double delta_max, const double rho0=0.) const
void set_vtx_range(double beta, track_t &gtracks, vertex_t &gvertices) const
double b
Definition: hdecay.h:120
double a
Definition: hdecay.h:121
static int position[264][3]
Definition: ReadPGInfo.cc:289
Log< level::Warning, false > LogWarning
void verify(const vertex_t &v, const track_t &tks, unsigned int nv=999999, unsigned int nt=999999) const
bool split(const double beta, track_t &t, vertex_t &y, double threshold=1.) const

◆ vertices_no_blocks()

vector< TransientVertex > DAClusterizerInZ_vect::vertices_no_blocks ( const std::vector< reco::TransientTrack > &  tracks) const

Definition at line 773 of file DAClusterizerInZ_vect.cc.

References a, HLT_2024v13_cff::beta, bsc_activity_cfg::clusters, gather_cfg::cout, GCP_Ntuples_cfg::dump, DAClusterizerInZ_vect::track_t::extractRaw(), ntuplemaker::fill, DAClusterizerInZ_vect::track_t::getSize(), merge(), SiStripPI::min, submitPVValidationJobs::split(), mathSSE::sqrt(), DiMuonV_cfg::threshold, DiMuonV_cfg::tracks, and update.

773  {
774  track_t&& tks = fill(tracks);
775  vector<TransientVertex> clusters;
776  if (tks.getSize() == 0)
777  return clusters;
778  tks.extractRaw();
779 
780  double rho0 = 0.0; // start with no outlier rejection
781 
782  vertex_t y; // the vertex prototypes
783 
784  // initialize:single vertex at infinite temperature
785  y.addItem(0, 1.0);
786  clear_vtx_range(tks, y);
787 
788  // estimate first critical temperature
789  double beta = beta0(betamax_, tks, y);
790 #ifdef DEBUG
791  if (DEBUGLEVEL > 0)
792  std::cout << "Beta0 is " << beta << std::endl;
793 #endif
794 
795  thermalize(beta, tks, y, delta_highT_);
796 
797  // annealing loop, stop when T<Tmin (i.e. beta>1/Tmin)
798 
799  double betafreeze = betamax_ * sqrt(coolingFactor_);
800 
801  while (beta < betafreeze) {
802  while (merge(y, tks, beta)) {
803  update(beta, tks, y, rho0, false);
804  }
805  split(beta, tks, y);
806 
808  thermalize(beta, tks, y, delta_highT_);
809  }
810 
811 #ifdef DEBUG
812  verify(y, tks);
813 
814  if (DEBUGLEVEL > 0) {
815  std::cout << "DAClusterizerInZ_vect::vertices_no_blocks :"
816  << "last round of splitting" << std::endl;
817  }
818 #endif
819 
820  set_vtx_range(beta, tks, y);
821  update(beta, tks, y, rho0, false);
822 
823  while (merge(y, tks, beta)) {
824  set_vtx_range(beta, tks, y);
825  update(beta, tks, y, rho0, false);
826  }
827 
828  unsigned int ntry = 0;
829  double threshold = 1.0;
830  while (split(beta, tks, y, threshold) && (ntry++ < 10)) {
831  thermalize(beta, tks, y, delta_highT_, rho0); // rho0 = 0. here
832  while (merge(y, tks, beta)) {
833  update(beta, tks, y, rho0, false);
834  }
835 
836  // relax splitting a bit to reduce multiple split-merge cycles of the same cluster
837  threshold *= 1.1;
838  }
839 
840 #ifdef DEBUG
841  verify(y, tks);
842  if (DEBUGLEVEL > 0) {
843  std::cout << "DAClusterizerInZ_vect::vertices_no_blocks :"
844  << "turning on outlier rejection at T=" << 1 / beta << std::endl;
845  }
846 #endif
847 
848  // switch on outlier rejection at T=Tmin
849  if (dzCutOff_ > 0) {
850  rho0 = y.getSize() > 1 ? 1. / y.getSize() : 1.;
851  for (unsigned int a = 0; a < 5; a++) {
852  update(beta, tks, y, a * rho0 / 5.); // adiabatic turn-on
853  }
854  }
855 
856  thermalize(beta, tks, y, delta_lowT_, rho0);
857 
858 #ifdef DEBUG
859  verify(y, tks);
860  if (DEBUGLEVEL > 0) {
861  std::cout << "DAClusterizerInZ_vect::vertices_no_blocks :"
862  << "merging with outlier rejection at T=" << 1 / beta << std::endl;
863  }
864  if (DEBUGLEVEL > 2)
865  dump(beta, y, tks, 2, rho0);
866 #endif
867 
868  // merge again (some cluster split by outliers collapse here)
869  while (merge(y, tks, beta)) {
870  set_vtx_range(beta, tks, y);
871  update(beta, tks, y, rho0, false);
872  }
873 
874 #ifdef DEBUG
875  verify(y, tks);
876  if (DEBUGLEVEL > 0) {
877  std::cout << "DAClusterizerInZ_vect::vertices_no_blocks :"
878  << "after merging with outlier rejection at T=" << 1 / beta << std::endl;
879  }
880  if (DEBUGLEVEL > 2)
881  dump(beta, y, tks, 2, rho0);
882 #endif
883 
884  // go down to the purging temperature (if it is lower than tmin)
885  while (beta < betapurge_) {
887  thermalize(beta, tks, y, delta_lowT_, rho0);
888  }
889 
890 #ifdef DEBUG
891  verify(y, tks);
892  if (DEBUGLEVEL > 0) {
893  std::cout << "DAClusterizerInZ_vect::vertices :"
894  << "purging at T=" << 1 / beta << std::endl;
895  }
896 #endif
897 
898  // eliminate insignificant vertices, this is more restrictive at higher T
899  while (purge(y, tks, rho0, beta)) {
900  thermalize(beta, tks, y, delta_lowT_, rho0);
901  }
902 
903 #ifdef DEBUG
904  verify(y, tks);
905  if (DEBUGLEVEL > 0) {
906  std::cout << "DAClusterizerInZ_vect::vertices_no_blocks :"
907  << "last cooling T=" << 1 / beta << std::endl;
908  }
909 #endif
910 
911  // optionally cool some more without doing anything, to make the assignment harder
912  while (beta < betastop_) {
914  thermalize(beta, tks, y, delta_lowT_, rho0);
915  }
916 
917 #ifdef DEBUG
918  verify(y, tks);
919  if (DEBUGLEVEL > 0) {
920  std::cout << "DAClusterizerInZ_vect::vertices_no_blocks :"
921  << "stop cooling at T=" << 1 / beta << std::endl;
922  }
923  if (DEBUGLEVEL > 2)
924  dump(beta, y, tks, 2, rho0);
925 #endif
926 
927  // assign tracks and fill into transient vertices
928  return fill_vertices(beta, rho0, tks, y);
929 }
double beta0(const double betamax, track_t const &tks, vertex_t const &y) const
bool merge(vertex_t &y, track_t &tks, double &beta) const
void clear_vtx_range(track_t &gtracks, vertex_t &gvertices) const
bool purge(vertex_t &, track_t &, double &, const double) const
std::vector< TransientVertex > fill_vertices(double beta, double rho0, track_t &tracks, vertex_t &vertices) const
double update(double beta, track_t &gtracks, vertex_t &gvertices, const double rho0=0, const bool updateTc=false) const
T sqrt(T t)
Definition: SSEVec.h:23
void dump(const double beta, const vertex_t &y, const track_t &tks, const int verbosity=0, const double rho0=0.) const
track_t fill(const std::vector< reco::TransientTrack > &tracks) const
unsigned int thermalize(double beta, track_t &gtracks, vertex_t &gvertices, const double delta_max, const double rho0=0.) const
void set_vtx_range(double beta, track_t &gtracks, vertex_t &gvertices) const
double a
Definition: hdecay.h:121
void verify(const vertex_t &v, const track_t &tks, unsigned int nv=999999, unsigned int nt=999999) const
bool split(const double beta, track_t &t, vertex_t &y, double threshold=1.) const

Member Data Documentation

◆ betamax_

double DAClusterizerInZ_vect::betamax_
private

Definition at line 211 of file DAClusterizerInZ_vect.h.

◆ betapurge_

double DAClusterizerInZ_vect::betapurge_
private

Definition at line 220 of file DAClusterizerInZ_vect.h.

◆ betastop_

double DAClusterizerInZ_vect::betastop_
private

Definition at line 212 of file DAClusterizerInZ_vect.h.

◆ block_size_

unsigned int DAClusterizerInZ_vect::block_size_
private

Definition at line 230 of file DAClusterizerInZ_vect.h.

◆ convergence_mode_

unsigned int DAClusterizerInZ_vect::convergence_mode_
private

Definition at line 222 of file DAClusterizerInZ_vect.h.

◆ coolingFactor_

double DAClusterizerInZ_vect::coolingFactor_
private

Definition at line 210 of file DAClusterizerInZ_vect.h.

◆ d0CutOff_

double DAClusterizerInZ_vect::d0CutOff_
private

Definition at line 214 of file DAClusterizerInZ_vect.h.

◆ delta_highT_

double DAClusterizerInZ_vect::delta_highT_
private

Definition at line 223 of file DAClusterizerInZ_vect.h.

◆ delta_lowT_

double DAClusterizerInZ_vect::delta_lowT_
private

Definition at line 224 of file DAClusterizerInZ_vect.h.

◆ dzCutOff_

double DAClusterizerInZ_vect::dzCutOff_
private

Definition at line 213 of file DAClusterizerInZ_vect.h.

◆ maxIterations_

unsigned int DAClusterizerInZ_vect::maxIterations_
private

Definition at line 209 of file DAClusterizerInZ_vect.h.

◆ mintrkweight_

double DAClusterizerInZ_vect::mintrkweight_
private

Definition at line 216 of file DAClusterizerInZ_vect.h.

◆ overlap_frac_

double DAClusterizerInZ_vect::overlap_frac_
private

Definition at line 231 of file DAClusterizerInZ_vect.h.

◆ runInBlocks_

bool DAClusterizerInZ_vect::runInBlocks_
private

Definition at line 229 of file DAClusterizerInZ_vect.h.

◆ sel_zrange_

double DAClusterizerInZ_vect::sel_zrange_
private

Definition at line 226 of file DAClusterizerInZ_vect.h.

◆ uniquetrkminp_

double DAClusterizerInZ_vect::uniquetrkminp_
private

Definition at line 218 of file DAClusterizerInZ_vect.h.

◆ uniquetrkweight_

double DAClusterizerInZ_vect::uniquetrkweight_
private

Definition at line 217 of file DAClusterizerInZ_vect.h.

◆ vertexSize_

double DAClusterizerInZ_vect::vertexSize_
private

Definition at line 208 of file DAClusterizerInZ_vect.h.

◆ zdumpcenter_

double DAClusterizerInZ_vect::zdumpcenter_
private

Definition at line 205 of file DAClusterizerInZ_vect.h.

◆ zdumpwidth_

double DAClusterizerInZ_vect::zdumpwidth_
private

Definition at line 206 of file DAClusterizerInZ_vect.h.

◆ zmerge_

double DAClusterizerInZ_vect::zmerge_
private

Definition at line 219 of file DAClusterizerInZ_vect.h.

◆ zrange_min_

const double DAClusterizerInZ_vect::zrange_min_ = 0.1
private

Definition at line 227 of file DAClusterizerInZ_vect.h.