4 #include "vdt/vdtMath.h" 10 const double mintrkweight,
11 const bool multivertexfit)
12 : chi_cutoff_(chicutoff), z_cutoff_(zcutoff), min_trackweight_(mintrkweight), multivertexfit_(multivertexfit) {
15 <<
"instantiating AdaptiveChisquarePrimaryVertexFitter with " 25 double F1 = ti.
b1 + xvtx * ti.
H1[0] + yvtx * ti.
H1[1];
26 double F2 = ti.
b2 + xvtx * ti.
H2[0] + yvtx * ti.
H2[1] - zvtx;
27 double chsq = F1 * F1 * ti.
S11 + F2 * F2 * ti.
S22 + 2. * F1 * F2 * ti.
S12;
29 assert((chsq >= 0) &&
" negative chi**2");
44 const auto tspca = trk.stateAtBeamLine().trackStateAtPCA();
46 const auto momentum = tspca.momentum();
47 auto const cos_phi = momentum.x() / momentum.perp();
48 auto const sin_phi = momentum.y() / momentum.perp();
49 auto const tan_lambda = momentum.z() / momentum.perp();
52 double cov11 = tspca_pe.covarianceMatrix()(3, 3);
53 double cov22 = tspca_pe.covarianceMatrix()(4, 4);
54 double cov12 = tspca_pe.covarianceMatrix()(3, 4);
57 double DetV = cov11 * cov22 - cov12 * cov12;
58 if (fabs(DetV) < 1.e-16) {
60 <<
"Warning, det(V) almost vanishes : " << DetV <<
" !! This should not happen!" << std::endl;
65 ti.
S11 = cov22 / DetV;
66 ti.
S22 = cov11 / DetV;
67 ti.
S12 = -cov12 / DetV;
69 ti.
b1 = tspca.position().x() * sin_phi - tspca.position().y() * cos_phi;
73 ti.
b2 = tspca.position().z() - (tspca.position().x() * cos_phi + tspca.position().y() * sin_phi) * tan_lambda;
74 ti.
H2[0] = cos_phi * tan_lambda;
75 ti.
H2[1] = sin_phi * tan_lambda;
78 for (
int k = 0;
k < 3;
k++) {
81 ti.
g[
k] = ti.
b1 * SH1k + ti.
b2 * SH2k;
82 for (
int l = 0;
l < 3;
l++) {
83 ti.
C(
l,
k) = ti.
H1[
l] * SH1k + ti.
H2[
l] * SH2k;
87 ti.
zpca = tspca.position().z();
88 ti.
dzError = trk.track().dzError();
94 unsigned const int nv =
xv_.size();
99 edm::LogWarning(
"AdaptiveChisquarePrimaryVertexFit") <<
" empty vertex list with " <<
nt <<
" tracks" << std::endl;
115 for (
unsigned int i = 0;
i <
nt;
i++) {
124 for (
unsigned int k = 0;
k < nv;
k++) {
126 for (
unsigned int i = 0;
i <
nt;
i++) {
128 const double zrange = zrange_scale * ti.dzError;
130 const double dztrk = ti.b2 +
xv_[
k] * ti.H2[0] +
yv_[
k] * ti.H2[1] -
zv_[
k];
144 unsigned const int nv =
xv_.size();
145 const double beta_over_2 = 0.5 *
beta;
149 std::vector<double> Z_track(
nt, Z_cutoff);
152 for (
unsigned int k = 0;
k < nv;
k++) {
157 const double e = vdt::fast_exp(-
arg);
167 for (
unsigned int j = 0;
j <
tkmap_.size();
j++) {
170 assert((
i <
nt) &&
"tkmap out of range");
185 const double trkweight_threshold = 0.7;
186 unsigned int nv =
xv_.size();
191 std::vector<double> wsumhi(nv, 0);
192 for (
unsigned int k = 0;
k < nv;
k++) {
200 unsigned int k_dzmin = 0;
201 for (
unsigned int k = 0;
k < nv - 1;
k++) {
203 if ((
k == 0) || (
dz < dzmin)) {
209 if ((
std::abs(dzmin) < 0.0200) && (
std::min(wsumhi[k_dzmin], wsumhi[k_dzmin + 1]) < 0.5)) {
210 if (wsumhi[k_dzmin] < wsumhi[k_dzmin + 1]) {
223 unsigned int nv =
xv_.size();
239 for (
unsigned int k1 =
k + 1; k1 < nv + 1; k1++) {
247 const float beam_weight,
248 const bool fill_covariances) {
254 unsigned const int nv =
xv_.size();
255 if (fill_covariances) {
261 double c_beam[3] = {0, 0, 0};
262 if (beam_weight > 0) {
264 for (
unsigned int j = 0;
j < 3;
j++) {
269 for (
unsigned int k = 0;
k < nv;
k++) {
273 double c[3] = {c_beam[0], c_beam[1], c_beam[2]};
279 for (
unsigned int l = 0;
l < 3;
l++) {
285 if ((fabs(
S(1, 2) -
S(2, 1)) > 1
e-3) || (fabs(
S(0, 2) -
S(2, 0)) > 1
e-3) || (fabs(
S(0, 1) -
S(1, 0)) > 1
e-3) ||
286 (
S(0, 0) <= 0) || (
S(0, 0) <= 0) || (
S(0, 0) <= 0)) {
287 edm::LogWarning(
"AdaptiveChisquarePrimaryVertexFitter") <<
"update() bad S-matrix S=" << std::endl
290 <<
"n-vertex = " << nv <<
" n-track = " <<
nt << std::endl;
294 const auto xold =
xv_[
k];
295 const auto yold =
yv_[
k];
296 const auto zold =
zv_[
k];
299 xv_[
k] = -(
S(0, 0) *
c[0] +
S(0, 1) *
c[1] +
S(0, 2) *
c[2]);
300 yv_[
k] = -(
S(1, 0) *
c[0] +
S(1, 1) *
c[1] +
S(1, 2) *
c[2]);
301 zv_[
k] = -(
S(2, 0) *
c[0] +
S(2, 1) *
c[1] +
S(2, 2) *
c[2]);
302 if (fill_covariances) {
306 edm::LogWarning(
"AdaptiveChisquarePrimaryVertexFitter") <<
"update() Matrix inversion failed" <<
S << std::endl;
307 if (fill_covariances) {
309 covv_dummy(0, 0) = 100.;
310 covv_dummy(1, 1) = 100.;
311 covv_dummy(2, 2) = 100.;
312 covv_.emplace_back(covv_dummy);
316 if ((
nt > 1) && (rho_vtx > 1.0)) {
329 auto SBeam =
beamspot.rotatedCovariance3D();
330 if (SBeam.Invert()) {
334 <<
"Warning, beam-spot covariance matrix inversion failed " << std::endl;
344 const unsigned int k,
345 const std::vector<std::pair<unsigned int, float>> &vertex_track_weights,
346 const std::vector<reco::TransientTrack> &
tracks,
347 const float beam_weight,
351 covv_[
k](0, 0),
covv_[
k](1, 0),
covv_[
k](1, 1),
covv_[
k](2, 0),
covv_[
k](2, 1),
covv_[
k](2, 2));
353 float vtx_ndof = -3.;
354 if (beam_weight > 0) {
356 vtx_ndof = 3 * beam_weight;
362 2 *
S(0, 2) *
dx *
dz + 2 *
S(1, 2) *
dy *
dz);
365 std::vector<reco::TransientTrack> vertex_tracks;
367 for (
const auto &tk : vertex_track_weights) {
368 const unsigned int i = tk.first;
369 const float track_weight = tk.second;
371 vertex_tracks.emplace_back(
tracks[
i]);
372 trkWeightMap[
tracks[
i]] = track_weight;
373 vtx_ndof += 2 * track_weight;
379 vtx.weightMap(trkWeightMap);
385 const std::vector<reco::TransientTrack> &
tracks,
386 const std::vector<TransientVertex> &
clusters,
391 const int max_iterations = 50;
394 const unsigned int nv =
clusters.size();
408 const double zclu = clu.position().z();
411 zv_.emplace_back(zclu);
421 unsigned int nit = 0;
422 while ((nit == 0) || ((
delta > 0.0001) && (nit < max_iterations))) {
427 if ((nit >= max_iterations) && (
delta > 0.01)) {
429 <<
"iteration limit reached " << nit <<
" last delta = " <<
delta << std::endl
430 <<
" nv = " << nv <<
" nt = " <<
tracks.size() << std::endl;
435 while ((
xv_.size() > 1) && (nit < max_iterations) && (
clean())) {
445 std::vector<unsigned int> track_to_vertex(
trackinfo_.size(), nv);
447 std::vector<double> maxweight(
trackinfo_.size(), -1.);
448 for (
unsigned int k = 0;
k < nv;
k++) {
453 track_to_vertex[
i] =
k;
459 std::vector<TransientVertex>
pvs;
460 for (
unsigned int k = 0;
k <
xv_.size();
k++) {
461 std::vector<std::pair<unsigned int, float>> vertex_tracks_weights;
464 if (track_to_vertex[
i] ==
k) {
479 const int max_iterations = 50;
482 const double zclu = cluster.
position().
z();
493 for (
unsigned int i = 0;
i <
nt;
i++) {
500 unsigned int nit = 0;
501 while ((nit == 0) || ((
delta > 0.0001) && (nit < max_iterations))) {
507 if ((nit >= max_iterations) && (
delta > 0.1)) {
509 <<
"single vertex fit, iteration limit reached " << nit <<
" last delta = " <<
delta << std::endl
517 std::vector<std::pair<unsigned int, float>> vertex_track_weights;
518 for (
unsigned int i = 0;
i <
nt;
i++) {
519 vertex_track_weights.emplace_back(
i,
tkweight_[
i]);
527 const std::vector<TransientVertex> &
clusters,
535 std::vector<TransientVertex>
pvs;
541 pvs.emplace_back(
pv);
void fill_weights(const reco::BeamSpot &, const double beta=1.)
GlobalPoint position() const
std::vector< TransientVertex > vertices(const std::vector< reco::TransientTrack > &, const std::vector< TransientVertex > &, const reco::BeamSpot &, const bool)
std::map< reco::TransientTrack, float > TransientTrackToFloatMap
void remove_vertex(unsigned int)
std::vector< double > tkweight_
std::vector< TransientVertex > fit(const std::vector< reco::TransientTrack > &, const std::vector< TransientVertex > &, const reco::BeamSpot &, const bool) override
std::vector< unsigned int > tkfirstv_
Error3 get_inverse_beam_covariance(const reco::BeamSpot &)
void fill_trackinfo(const std::vector< reco::TransientTrack > &, const reco::BeamSpot &)
Abs< T >::type abs(const T &t)
ROOT::Math::SMatrix< double, 3 > Error3
std::vector< reco::TransientTrack > const & originalTracks() const
void make_vtx_trk_map(const double)
double update(const reco::BeamSpot &, float beam_weight, const bool fill_covariances=false)
Log< level::Info, false > LogInfo
std::vector< Error3 > covv_
std::vector< TrackInfo > trackinfo_
std::vector< double > yv_
TransientVertex get_TransientVertex(const unsigned int, const std::vector< std::pair< unsigned int, float >> &, const std::vector< reco::TransientTrack > &, const float, const reco::BeamSpot &)
std::vector< unsigned int > tkmap_
std::vector< double > xv_
PerigeeTrajectoryError ftsToPerigeeError(const FTS &originalFTS)
std::vector< double > zv_
TransientVertex refit(const TransientVertex &, const reco::BeamSpot &, const bool)
Log< level::Warning, false > LogWarning
double track_in_vertex_chsq(const TrackInfo &, const double, const double, const double)
Power< A, B >::type pow(const A &a, const B &b)
AdaptiveChisquarePrimaryVertexFitter(double chicutoff=2.5, double zcutoff=1.0, double mintrkweight=0.4, bool multivertexfit=false)