ATLAS Offline Software
Loading...
Searching...
No Matches
VtCFit.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
15#include <algorithm>
16#include <cmath>
17
18namespace {
19//internal methods
20
21using namespace Trk;
22double setLimitedFitVrt(VKVertex* vk, double alf, double bet, double dCoefNorm,
23 double newVrt[3]) {
24 int NTRK = vk->TrackList.size();
25 double chi2t = 0.;
26 for (int ii = 0; ii < 3; ++ii) { // Intermediate vertex.
27 newVrt[ii] = vk->iniV[ii] + (alf + bet) * (vk->fitV[ii] - vk->iniV[ii]) +
28 bet * dCoefNorm * vk->dxyz0[ii];
29 }
30
31 for (int ii = 0; ii < NTRK;
32 ++ii) { // track parameters at intermediate vertex. Also save to cnstP
33 // for constraint
34 VKTrack* trk = vk->TrackList[ii].get();
35 TWRK* t_trk = vk->tmpArr[ii].get();
36 t_trk->part[0] = trk->cnstP[0] =
37 trk->iniP[0] + (alf + bet) * (trk->fitP[0] - trk->iniP[0]) +
38 bet * dCoefNorm * t_trk->parf0[0];
39 t_trk->part[1] = trk->cnstP[1] =
40 trk->iniP[1] + (alf + bet) * (trk->fitP[1] - trk->iniP[1]) +
41 bet * dCoefNorm * t_trk->parf0[1];
42 t_trk->part[2] = trk->cnstP[2] =
43 trk->iniP[2] + (alf + bet) * (trk->fitP[2] - trk->iniP[2]) +
44 bet * dCoefNorm * t_trk->parf0[2];
45 // Limit momentum change if too big
46 if (bet != 0. && std::abs(t_trk->part[2]) < 1.e-7)
47 t_trk->part[2] = trk->cnstP[2] =
48 trk->iniP[2] + (alf + bet) * (trk->fitP[2] - trk->iniP[2]);
49 trk->Chi2 = cfchi2(newVrt, t_trk->part, trk);
50 chi2t += trk->Chi2;
51 }
52 return chi2t;
53}
54
55// Calculates Chi2 due "apriory vertex" and/or "pass near" constraints
56//--------------------------------------------------------------------------
57double calcChi2Addition(VKVertex* vk, const double wgtvrtd[6],
58 const double xyzf[3]) {
59
60 double Chi2t = 0., signif;
61 if (vk->useApriorVertex) {
62 double d1 = vk->apriorV[0] - vk->refIterV[0] - xyzf[0];
63 double d2 = vk->apriorV[1] - vk->refIterV[1] - xyzf[1];
64 double d3 = vk->apriorV[2] - vk->refIterV[2] - xyzf[2];
65 Chi2t +=
66 wgtvrtd[0] * d1 * d1 + wgtvrtd[2] * d2 * d2 + wgtvrtd[5] * d3 * d3 +
67 2. * (d2 * d1 * wgtvrtd[1] + d3 * (d1 * wgtvrtd[3] + d2 * wgtvrtd[4]));
68 }
69 if (vk->passNearVertex) {
70 signif = cfVrtDstSig(vk, vk->passWithTrkCov);
71 Chi2t += signif * signif;
72 }
73 return Chi2t;
74}
75
76[[maybe_unused]]
77void makeNoPostFit(VKVertex* vk, double wgtvrtd[], double& dCoefNorm) {
78 double xyzt[3] = {0.};
79 vk->Chi2 = setLimitedFitVrt(
80 vk, 1., 0., dCoefNorm, xyzt); // track parameters at intermediate vertex.
81 vk->setCnstV(xyzt); // Also save to cnstP for constraint
82 vk->Chi2 += calcChi2Addition(vk, wgtvrtd, xyzt); // Constraints of Chi2 type
83 if (!vk->ConstraintList.empty()) { // Restore initial derivatives
84 int NTRK = vk->TrackList.size();
85 vk->setCnstV(vk->iniV);
86 for (int i = 0; i < NTRK; ++i) {
87 VKTrack* trk = vk->TrackList[i].get();
88 for (int j = 0; j < 3; j++) {
89 trk->cnstP[j] = trk->iniP[j];
90 }
91 }
93 }
94}
95
96bool makePostFit(VKVertex* vk, double wgtvrtd[], double& dCoefNorm) {
97
98 int NTRK = vk->TrackList.size();
99 double dScale = 1.e8, dScaleMax = 1.e10;
100 double alfLowLim = 0.1;
101 double alfUppLim = 1.1; // Should be compatible with vkalAllowedPtChange -
102 // not causing 1/p shift up to zero.
103 double xyzt[3], chi2t[10] = {0.};
104 double alf = 1., bet = 0.;
105 int ii, j;
106 double ContribC[10] = {0.};
107 //
108 int NCNST = vk->ConstraintList.size();
109 int PostFitIteration = 4;
110 if (NCNST)
111 PostFitIteration = 4;
112 double ValForChk; // Now PostFit=4 works better than default PostFit=7.
113 // Reason is unclear
114
115 for (j = 1; j <= PostFitIteration; ++j) {
116 int jm1 = j - 1;
117 chi2t[jm1] = 0.;
118 ContribC[jm1] = 0.;
119 //--
120 if (j < 4) {
121 alf = jm1 * .5;
122 bet = 0.;
123 }
124 // else{ if(j==4)bet=0.; if(j==5)bet=-0.02; if(j==6)bet= 0.02;}
125 //
126 //--vk->fitV and trk->fitP stay untouched during these iterations
127 //
128 chi2t[jm1] =
129 setLimitedFitVrt(vk, alf, bet, dCoefNorm,
130 xyzt); // track parameters at intermediate vertex.
131 vk->setCnstV(xyzt); // Also save to cnstP for constraint
132 chi2t[jm1] +=
133 calcChi2Addition(vk, wgtvrtd, xyzt); // Constraints of Chi2 type
134 //
135 // Addition of constraints
136 if (NCNST) { // VK 25.10.2006 new mechanism for constraint treatment
138 double dCnstContrib = getCnstValues2(vk);
139 if (j == 1) {
140 dScale = std::max(chi2t[0], 5. * NTRK) / (dCnstContrib + 1 / dScaleMax);
141 if (dScale > dScaleMax)
142 dScale = dScaleMax;
143 if (dScale < 0.01)
144 dScale = 0.01;
145 }
146 ContribC[jm1] = dCnstContrib * dScale;
147 if (j != PostFitIteration) {
148 chi2t[jm1] += 5. * ContribC[jm1];
149 } // Last cycle is ALWAYS without constraints
150 }
151 // Having 3 points (0,0.5,1.) find a pabolic minimum
152 if (j == 3) {
153 alf = finter(chi2t[0], chi2t[1], chi2t[2], 0., 0.5, 1.);
154 if (chi2t[0] == chi2t[1] && chi2t[1] == chi2t[2])
155 alf = 1.;
156 if (alf > alfUppLim)
157 alf = alfUppLim;
158 if (alf < alfLowLim) {
159 alf = alfLowLim;
160 PostFitIteration =
161 4; // Something is wrong. Don't make second optimisation
162 }
163 }
164
165 // The commented piece of code below worked well before Rel.22 but now
166 // (22.0+) results in performance degradation. The reason is not clear and
167 // is being investigated. This part will be either retuned of rewritten
168 // (WIP).
169 // ------
170 // Having 3 points (0,-0.02,0.02) find a pabolic minimum
171 /* if (j == 6) { bet = finter(chi2t[4], chi2t[3], chi2t[5], -0.02, 0.,
172 0.02); if (chi2t[3] == chi2t[4] && chi2t[4] == chi2t[5]) bet = 0.; if (bet
173 > 0.2)bet = 0.2; if (bet <-0.2)bet = -0.2;
174 }
175 //Check if minimum is really a minimum. Otherwise use bet=0. point
176 if (j == 7 && ContribC[6]>ContribC[3]) {
177 //std::cout<<__func__<<": step7 no improvement. Revert back bet=0"<<'\n';
178 bet = 0.;
179 chi2t[jm1]= setLimitedFitVrt(vk,alf,bet,dCoefNorm,xyzt);// track parameters
180 at intermediate vertex. vk->setCnstV(xyzt); // Also save to cnstP for
181 constraint chi2t[jm1] += calcChi2Addition( vk, wgtvrtd, xyzt); //
182 Constraints of Chi2 type if (NCNST) { //VK 25.10.2006 new mechanism
183 for constraint treatment applyConstraints(vk); ContribC[jm1]
184 = 2.*dScale*getCnstValues2(vk);
185 }
186 }
187 */
188 // Trick to cut step in case of divergence and wrong ALFA. Step==4!!!
189 // Check if minimum is really a minimum. Otherwise use alf=0.02 or alf=0.5
190 // or alf=1. points
191 if (j == 4 && alf != alfLowLim) {
192 ValForChk = chi2t[3];
193 if ((PostFitIteration == 4) && NCNST)
194 ValForChk += ContribC[3];
195 int notImproved = false;
196 if (ValForChk > chi2t[0] * 1.0001) {
197 alf = alfLowLim;
198 ValForChk = chi2t[0];
199 notImproved = true;
200 }
201 if (ValForChk > chi2t[1] * 1.0001) {
202 alf = 0.5;
203 ValForChk = chi2t[1];
204 notImproved = true;
205 }
206 if (ValForChk > chi2t[2] * 1.0001) {
207 alf = 1.0;
208 ValForChk = chi2t[2];
209 notImproved = true;
210 }
211 if (notImproved) { // Recalculate all with reverted alf
212 // std::cout<<__func__<<": step4 no improvement. Revert back
213 // alf="<<alf<<'\n';
214 chi2t[jm1] =
215 setLimitedFitVrt(vk, alf, bet, dCoefNorm,
216 xyzt); // track parameters at intermediate vertex.
217 vk->setCnstV(xyzt); // Also save to cnstP for constraint
218 chi2t[jm1] +=
219 calcChi2Addition(vk, wgtvrtd, xyzt); // Constraints of Chi2 type
220 if (NCNST) { // VK 25.10.2006 new mechanism for constraint treatment
222 ContribC[jm1] = 5. * dScale * getCnstValues2(vk);
223 if (j != PostFitIteration) {
224 chi2t[jm1] += ContribC[jm1];
225 } // Last cycle is ALWAYS without constraints
226 }
227 }
228 }
229 }
230 /* -- Saving of final j=PostFitIteration step as output */
231 /*------------------------------------------------------*/
232 std::copy_n(xyzt, 3, vk->fitV);
233 for (ii = 0; ii < NTRK; ++ii) {
234 std::copy_n(vk->tmpArr[ii]->part, 3, vk->TrackList[ii]->fitP);
235 }
236 vk->Chi2 = chi2t[PostFitIteration - 1]; // Chi2 from last try.
237 //-----------------------------------------------------------
238 if (NCNST) { /* Restore initial derivatives */
239 vk->setCnstV(vk->iniV);
240 for (ii = 0; ii < NTRK; ++ii) {
241 VKTrack* trk = vk->TrackList[ii].get();
242 for (j = 0; j < 3; j++) {
243 trk->cnstP[j] = trk->iniP[j];
244 }
245 }
247 }
248
249 if (alf == alfLowLim)
250 return false; // Truncated step
251 return true;
252}
253
254} // namespace
255
256namespace Trk {
257
258
259/* ************************************************************************/
260/* */
261/* ************************************************************************/
262/* Created : 1-AUG-1994 Author : V.KOSTYUKHIN (IHEP) */
263/* Original version of vertex fit : PXFVTX by P. Billoir (CDF) */
264/* ********* */
265/* Arguments : Input : NTRK : number of tracks */
266/* ICH(1:NTRK) : charge */
267/* PAR(1:5,1:NTRK) : "perigee" parameters */
268/* 1 : epsilon (impact par. in xy projection, with sign)*/
269/* 2 : z coordinate */
270/* 3 : theta angle */
271/* 4 : phi angle */
272/* 5 : 1/R (R = radius of curvature, with sign) */
273/* 0.0029979246d0/Pt if charge=0 */
274/* WGT(1:15,1:NTRK) : weight matrix on PAR */
275/* :in case of zero charge WGT(15) must be */
276/* :error of 0.0029979246d0/Pt with correlation*/
277/* XYZ(1:3) : approximate coordinates of the vertex*/
278/* PAR0(1:3) : approximate parameters of tracks at*/
279/* the vertex(result of pxfvtx fit) */
280/* Output : XYZF(1:3) : fitted coordinates of the vertex */
281/* PARF(1:3,1:NTRK) : fitted parameters at THE vertex*/
282/* 1 : theta */
283/* 2 : phi */
284/* 3 : 1/R */
285/* CHI2 : chi2 of the fit */
286/* CHI2TR(I)=CONTRIBUTION OF TRACK I TO THE */
287/* TOTAL CHI2 */
288
289/* Errors : IERR = 1 : too many tracks (NTRK > NTRMAX) */
290/* IERR = 2 : covariance or weight matrix not positive */
291/**************************************************************************/
292
293int vtcfit( VKVertex * vk) {
294
295 double dxyz[3], xyzt[3], eigv[8];
296 double dpipj[3][3] /* was [3][3] */;
297 double drdpy[2][3] /* was [2][3] */;
298 double drdvy[2][3] /* was [2][3] */;
299 double pyv[3][3] /*was [3][3]*/;
300 double vyv[3][3] /*was [3][3]*/;
301 double wa[6], stv[3], wgtvrtd[6], tv[3];
302
303 int ic, jj, it, jt, ii, kt;
304 int j, k, l;
305
306#define ader_ref(a_1,a_2) vk->ader[(a_2)*(vkalNTrkM*3+3) + (a_1) - (vkalNTrkM*3+4)]
307#define cvder_ref(a_1,a_2) vk->FVC.cvder[(a_2)*2 + (a_1) - 3]
308#define dcv_ref(a_1,a_2) vk->FVC.dcv[(a_2)*6 + (a_1) - 7]
309
310 /* ************************************************************************/
311 /* Created : 14-MAY-2008 Author : V.KOSTYUKHIN (INFN) */
312 /* ********* */
313 /* Arguments : Input : NTRK : number of tracks */
314 /* ICH(1:NTRK) : charge */
315 /* PAR(1:5,1:NTRK) : "perigee" parameters */
316 /* 1 : epsilon (impact par. in xy projection, with sign)*/
317 /* 2 : z coordinate */
318 /* 3 : theta angle */
319 /* 4 : phi angle */
320 /* 5 : 1/R (R = radius of curvature, with sign) */
321 /* 0.0029979246d0/Pt if charge=0 */
322 /* WGT(1:15,1:NTRK) : weight matrix on PAR */
323 /* :in case of zero charge WGT(15) must be */
324 /* :error of 0.0029979246d0/Pt with correlation*/
325 /* XYZ(1:3) : approximate coordinates of the vertex*/
326 /* PAR0(1:3) : approximate parameters of tracks at*/
327 /* the vertex(result of pxfvtx fit) */
328 /* Output : XYZF(1:3) : fitted coordinates of the vertex */
329 /* PARF(1:3,1:NTRK) : fitted parameters at THE vertex*/
330 /* 1 : theta */
331 /* 2 : phi */
332 /* 3 : 1/R */
333 /* CHI2 : chi2 of the fit */
334 /* CHI2TR(I)=CONTRIBUTION OF TRACK I TO THE */
335 /* TOTAL CHI2 */
336
337 /* Errors : IERR = 1 : too many tracks (NTRK > NTRMAX) */
338 /* IERR = 2 : covariance or weight matrix not positive */
339 /**************************************************************************/
340
341 /* -------------------------------------------- */
342 /* Fit results needed in other calculations */
343 /* -------------------------------------------- */
344 /* For close to vertex constraint */
345 /* For step constraint */
346 /* -- Derivatives and others for constraint */
347 /* ---------------------------------------------------------------------- */
348
349 long int IERR = 0;
350 int NTRK = vk->TrackList.size();
351 double xyz[3]={vk->iniV[0],vk->iniV[1],vk->iniV[2]};
352 double twb[9];
353 double twci[6];
354 double twbci[9];
355 double xyzf[3];
356
357 vk->truncatedStep=false;
358 if ( NTRK > vkalNTrkM ) return 1;
359
360 std::unique_ptr<double[]> dphi = std::unique_ptr<double[]>(new double[NTRK]);
361 std::unique_ptr<double[]> deps = std::unique_ptr<double[]>(new double[NTRK]);
362 std::unique_ptr<double[]> drho = std::unique_ptr<double[]>(new double[NTRK]);
363 std::unique_ptr<double[]> dtet = std::unique_ptr<double[]>(new double[NTRK]);
364 std::unique_ptr<double[]> dzp = std::unique_ptr<double[]>(new double[NTRK]);
365
366 for (int i=0; i<3; ++i) { tv[i] = 0.; stv[i] = 0.;}
367 for (int i=0; i<6; ++i) { vk->wa[i] = 0.; wa[i] = 0.;}
368 for (k=0; k<2; k++) { for(j=0; j<3; j++) drdvy[k][j] = drdpy[k][j] = 0.;};
369 for (k=0; k<3; k++) { for(j=0; j<3; j++) pyv[k][j] = vyv[k][j] = 0.;};
370
371 /* =================================================================== */
372 /* loop over the tracks */
373
374 if (vk->passNearVertex) {
375 /* dR/dV*Y and dR/dV*Y*dR/dV f */
376 drdvy[0][0]= cvder_ref(1, 1)*vk->FVC.ywgt[0] + cvder_ref(2, 1)*vk->FVC.ywgt[1];
377 drdvy[1][0]= cvder_ref(1, 1)*vk->FVC.ywgt[1] + cvder_ref(2, 1)*vk->FVC.ywgt[2];
378 drdvy[0][1]= cvder_ref(1, 2)*vk->FVC.ywgt[0] + cvder_ref(2, 2)*vk->FVC.ywgt[1];
379 drdvy[1][1]= cvder_ref(1, 2)*vk->FVC.ywgt[1] + cvder_ref(2, 2)*vk->FVC.ywgt[2];
380 drdvy[0][2]= cvder_ref(1, 3)*vk->FVC.ywgt[0] + cvder_ref(2, 3)*vk->FVC.ywgt[1];
381 drdvy[1][2]= cvder_ref(1, 3)*vk->FVC.ywgt[1] + cvder_ref(2, 3)*vk->FVC.ywgt[2];
382 for (ii = 1; ii <= 3; ++ii) { /* Matrix dR/dV*Y*dR/dV */
383 for (jj = 1; jj <= 3; ++jj) {
384 vyv[ii-1][jj-1] = drdvy[0][ii-1]*cvder_ref(1, jj) + drdvy[1][ii-1]*cvder_ref(2, jj);
385 }
386 }
387 }
388
389 double vBx,vBy,vBz;
390 Trk::vkalMagFld::getMagFld(xyz[0], xyz[1], xyz[2],vBx,vBy,vBz,(vk->vk_fitterControl).get());
391
392 for ( kt = 0; kt < NTRK; ++kt) {
393 VKTrack* trk = vk->TrackList[kt].get();
394 double theta_ini =trk->iniP[0];
395 double phi_ini =trk->iniP[1];
396 double invR_ini =trk->iniP[2];
397 /* "perigee" parameters EPS and ZP if the trajectory goes through XYZ */
398 /* and its theta,phi,1/R at perigee are equal to the values at input*/
399 double cotth = 1. / tan( theta_ini ); /* theta at vertex */
400 double cosf = cos(phi_ini);
401 double sinf = sin(phi_ini);
402 double uu = xyz[0]*cosf + xyz[1]*sinf;
403 double vv = xyz[1]*cosf - xyz[0]*sinf;
404 double phip,zp,eps;
405 double corrCz = (vBy*cosf-vBx*sinf)/Trk::vkalMagFld::getEffField(vBx, vBy, vBz, phi_ini, theta_ini);
406 if ( trk->Charge ) {
407 eps = -vv - uu*uu * invR_ini / 2.;
408 zp = -uu * (1. - vv * invR_ini) * cotth - 0.5*uu*uu*invR_ini*corrCz; //xyz[2] is added later to gain precision
409 phip = -uu * invR_ini; //phi_ini is added later to gain precision
410 } else {
411 eps = -vv;
412 zp = -uu * cotth;
413 phip = 0.;
414 }
415
416 /* contribution of this track to chi2 with initial values */
417
418 deps[kt] = trk->a0() - eps;
419 dzp[kt] = trk->z() - xyz[2]; // Precision
420 dzp[kt]-= zp;
421 dtet[kt] = trk->theta() - theta_ini;
422 dphi[kt] = trk->phi() - phi_ini; // Precision
423 dphi[kt]-= phip;
424 drho[kt] = trk->invR() - invR_ini;
425 while(dphi[kt] > M_PI)dphi[kt]-=2.*M_PI;
426 while(dphi[kt] < -M_PI)dphi[kt]+=2.*M_PI;
427
428
429 /* derivatives (deriv1) of perigee param. w.r.t. X,Y,Z (vertex) uu=Q, vv=R */
430 double d11 = sinf - ( uu*cosf *invR_ini);
431 double d12 = -cosf - ( uu*sinf *invR_ini);
432 double d21 = -cosf * cotth + ( (vv*cosf-uu*sinf)*cotth *invR_ini) - uu*cosf*invR_ini*corrCz;
433 double d22 = -sinf * cotth + ( (vv*sinf+uu*cosf)*cotth *invR_ini) - uu*sinf*invR_ini*corrCz;
434 //double d23 = 1.; //VK for reference
435 double d41 = -cosf * invR_ini;
436 double d42 = -sinf * invR_ini;
437 if (trk->Charge == 0) {
438 d11 = sinf;
439 d12 = -cosf;
440 d21 = -cosf * cotth;
441 d22 = -sinf * cotth;
442 d41 = 0.;
443 d42 = 0.;
444 }
445
446 /* matrix DW = (deriv1)t * weight */
447 double dw11 = d11 * trk->WgtM[0] + d21 * trk->WgtM[1] + d41 * trk->WgtM[6];
448 double dw12 = d11 * trk->WgtM[1] + d21 * trk->WgtM[2] + d41 * trk->WgtM[7];
449 double dw13 = d11 * trk->WgtM[3] + d21 * trk->WgtM[4] + d41 * trk->WgtM[8];
450 double dw14 = d11 * trk->WgtM[6] + d21 * trk->WgtM[7] + d41 * trk->WgtM[9];
451 double dw15 = d11 * trk->WgtM[10]+ d21 * trk->WgtM[11]+ d41 * trk->WgtM[13];
452
453
454 double dw21 = d12 * trk->WgtM[0] + d22 * trk->WgtM[1] + d42 * trk->WgtM[6];
455 double dw22 = d12 * trk->WgtM[1] + d22 * trk->WgtM[2] + d42 * trk->WgtM[7];
456 double dw23 = d12 * trk->WgtM[3] + d22 * trk->WgtM[4] + d42 * trk->WgtM[8];
457 double dw24 = d12 * trk->WgtM[6] + d22 * trk->WgtM[7] + d42 * trk->WgtM[9];
458 double dw25 = d12 * trk->WgtM[10]+ d22 * trk->WgtM[11]+ d42 * trk->WgtM[13];
459 double dw31 = trk->WgtM[1];
460 double dw32 = trk->WgtM[2];
461 double dw33 = trk->WgtM[4];
462 double dw34 = trk->WgtM[7];
463 double dw35 = trk->WgtM[11];
464
465 /* summation of DW * DPAR to vector TV */
466 tv[0] += dw11 * deps[kt] + dw12 * dzp[kt];
467 tv[1] += dw21 * deps[kt] + dw22 * dzp[kt];
468 tv[2] += dw31 * deps[kt] + dw32 * dzp[kt];
469 tv[0] += dw13 * dtet[kt] + dw14 * dphi[kt] + dw15 * drho[kt];
470 tv[1] += dw23 * dtet[kt] + dw24 * dphi[kt] + dw25 * drho[kt];
471 tv[2] += dw33 * dtet[kt] + dw34 * dphi[kt] + dw35 * drho[kt];
472
473 stv[0] += dw11 * deps[kt] + dw12 * dzp[kt];
474 stv[1] += dw21 * deps[kt] + dw22 * dzp[kt];
475 stv[2] += dw31 * deps[kt] + dw32 * dzp[kt];
476 stv[0] += dw13 * dtet[kt] + dw14 * dphi[kt] + dw15*drho[kt];
477 stv[1] += dw23 * dtet[kt] + dw24 * dphi[kt] + dw25*drho[kt];
478 stv[2] += dw33 * dtet[kt] + dw34 * dphi[kt] + dw35*drho[kt];
479
480 /* derivatives (deriv2) of perigee param. w.r.t. theta,phi,1/R (vertex) uu=Q, vv=R */
481 double e12 = uu - invR_ini * vv * uu;
482 double e13 = -uu*uu / 2.;
483 double e21 = uu *(1. - vv*invR_ini) * (cotth*cotth + 1.);
484 double e22 = -vv*cotth + (vv*vv-uu*uu)*invR_ini*cotth - uu*vv*invR_ini*corrCz;
485 double e23 = uu*vv*cotth -0.5*uu*uu*corrCz;
486 double e43 = -uu + 2.*uu*vv*invR_ini;
487 /* if straight line, set to zero derivatives w.r.t. the curvature */
488 /* and curvature terms in derivatives */
489 if (trk->Charge == 0) {
490 e12 = uu;
491 e13 = 0.;
492 e21 = uu * (cotth*cotth + 1.);
493 e22 = -vv * cotth;
494 e23 = 0.;
495 e43 = 0.;
496 }
497
498 /* matrix EW = (deriv2)t * weight */
499 double ew11 = e21 * trk->WgtM[1] + trk->WgtM[3];
500 double ew12 = e21 * trk->WgtM[2] + trk->WgtM[4];
501 double ew13 = e21 * trk->WgtM[4] + trk->WgtM[5];
502 double ew14 = e21 * trk->WgtM[7] + trk->WgtM[8];
503 double ew15 = e21 * trk->WgtM[11]+ trk->WgtM[12];
504 double ew21 = e12 * trk->WgtM[0] + e22 * trk->WgtM[1] + trk->WgtM[6];
505 double ew22 = e12 * trk->WgtM[1] + e22 * trk->WgtM[2] + trk->WgtM[7];
506 double ew23 = e12 * trk->WgtM[3] + e22 * trk->WgtM[4] + trk->WgtM[8];
507 double ew24 = e12 * trk->WgtM[6] + e22 * trk->WgtM[7] + trk->WgtM[9];
508 double ew25 = e12 * trk->WgtM[10]+ e22 * trk->WgtM[11]+ trk->WgtM[13];
509 double ew31 = e13 * trk->WgtM[0] + e23 * trk->WgtM[1] + e43 * trk->WgtM[6] + trk->WgtM[10];
510 double ew32 = e13 * trk->WgtM[1] + e23 * trk->WgtM[2] + e43 * trk->WgtM[7] + trk->WgtM[11];
511 double ew33 = e13 * trk->WgtM[3] + e23 * trk->WgtM[4] + e43 * trk->WgtM[8] + trk->WgtM[12];
512 double ew34 = e13 * trk->WgtM[6] + e23 * trk->WgtM[7] + e43 * trk->WgtM[9] + trk->WgtM[13];
513 double ew35 = e13 * trk->WgtM[10]+ e23 * trk->WgtM[11]+ e43 * trk->WgtM[13]+ trk->WgtM[14];
514
515 /* computation of vector TT = EW * DPAR */
516 TWRK* t_trk=vk->tmpArr[kt].get();
517 t_trk->tt[0] = ew11*deps[kt] + ew12*dzp[kt];
518 t_trk->tt[1] = ew21*deps[kt] + ew22*dzp[kt];
519 t_trk->tt[2] = ew31*deps[kt] + ew32*dzp[kt];
520 t_trk->tt[0] += ew13*dtet[kt] + ew14*dphi[kt] + ew15*drho[kt];
521 t_trk->tt[1] += ew23*dtet[kt] + ew24*dphi[kt] + ew25*drho[kt];
522 t_trk->tt[2] += ew33*dtet[kt] + ew34*dphi[kt] + ew35*drho[kt];
523 if ( vk->passNearVertex ) {
524 for (j = 1; j <= 2; ++j) { /* Derivatives dR/dQi */
525 int i3=(kt+1)*3;
526 t_trk->drdp[j-1][0] = cvder_ref(j,4) * dcv_ref(4,i3 + 1) + cvder_ref(j,5) * dcv_ref(5,i3 + 1);
527 t_trk->drdp[j-1][1] = cvder_ref(j,4) * dcv_ref(4,i3 + 2) + cvder_ref(j,5) * dcv_ref(5,i3 + 2);
528 t_trk->drdp[j-1][2] = cvder_ref(j,4) * dcv_ref(4,i3 + 3) + cvder_ref(j,5) * dcv_ref(5,i3 + 3);
529 t_trk->drdp[j-1][0] += cvder_ref(j, 6) * dcv_ref(6, i3 + 1);
530 t_trk->drdp[j-1][1] += cvder_ref(j, 6) * dcv_ref(6, i3 + 2);
531 t_trk->drdp[j-1][2] += cvder_ref(j, 6) * dcv_ref(6, i3 + 3);
532 }
533 /* Matrix dR/dQ */
534 drdpy[0][0] = t_trk->drdp[0][0] * vk->FVC.ywgt[0] + t_trk->drdp[1][0] * vk->FVC.ywgt[1];
535 drdpy[1][0] = t_trk->drdp[0][0] * vk->FVC.ywgt[1] + t_trk->drdp[1][0] * vk->FVC.ywgt[2];
536 drdpy[0][1] = t_trk->drdp[0][1] * vk->FVC.ywgt[0] + t_trk->drdp[1][1] * vk->FVC.ywgt[1];
537 drdpy[1][1] = t_trk->drdp[0][1] * vk->FVC.ywgt[1] + t_trk->drdp[1][1] * vk->FVC.ywgt[2];
538 drdpy[0][2] = t_trk->drdp[0][2] * vk->FVC.ywgt[0] + t_trk->drdp[1][2] * vk->FVC.ywgt[1];
539 drdpy[1][2] = t_trk->drdp[0][2] * vk->FVC.ywgt[1] + t_trk->drdp[1][2] * vk->FVC.ywgt[2];
540 t_trk->tt[0] -= drdpy[0][0]*vk->FVC.rv0[0] + drdpy[1][0]*vk->FVC.rv0[1];
541 t_trk->tt[1] -= drdpy[0][1]*vk->FVC.rv0[0] + drdpy[1][1]*vk->FVC.rv0[1];
542 t_trk->tt[2] -= drdpy[0][2]*vk->FVC.rv0[0] + drdpy[1][2]*vk->FVC.rv0[1];
543 for (ii = 1; ii <= 3; ++ii) { /* Matrix dR/dQi*Y*dR/dV */
544 for (jj = 1; jj <= 3; ++jj) {
545 pyv[jj-1][ii-1] = drdpy[0][ii-1] * cvder_ref(1, jj) + drdpy[1][ii-1] * cvder_ref(2, jj);
546 }
547 }
548 }
549
550 /* summation of (deriv1)t * weight * (deriv1) to matrix WA */
551 wa[0] += dw11 * d11 + dw12 * d21 + dw14 * d41;
552 wa[1] += dw11 * d12 + dw12 * d22 + dw14 * d42;
553 wa[2] += dw21 * d12 + dw22 * d22 + dw24 * d42;
554 wa[3] += dw12;
555 wa[4] += dw22;
556 wa[5] += dw32;
557 vk->wa[0] = vk->wa[0] + dw11 * d11 + dw12 * d21 + dw14 * d41;
558 vk->wa[1] = vk->wa[1] + dw11 * d12 + dw12 * d22 + dw14 * d42;
559 vk->wa[2] = vk->wa[2] + dw21 * d12 + dw22 * d22 + dw24 * d42;
560 vk->wa[3] += dw12;
561 vk->wa[4] += dw22;
562 vk->wa[5] += dw32;
563
564 /* computation of matrix WB = (deriv1)t * weight * (deriv2) */
565 twb[0] = dw12 * e21 + dw13;
566 twb[1] = dw22 * e21 + dw23;
567 twb[2] = dw32 * e21 + dw33;
568 twb[3] = dw11 * e12 + dw12 * e22 + dw14;
569 twb[4] = dw21 * e12 + dw22 * e22 + dw24;
570 twb[5] = dw31 * e12 + dw32 * e22 + dw34;
571 twb[6] = dw11 * e13 + dw12 * e23 + dw14 * e43 + dw15;
572 twb[7] = dw21 * e13 + dw22 * e23 + dw24 * e43 + dw25;
573 twb[8] = dw31 * e13 + dw32 * e23 + dw34 * e43 + dw35;
574 if ( vk->passNearVertex ) {
575 twb[0] += pyv[0][0];
576 twb[1] += pyv[1][0];
577 twb[2] += pyv[2][0];
578 twb[3] += pyv[0][1];
579 twb[4] += pyv[1][1];
580 twb[5] += pyv[2][1];
581 twb[6] += pyv[0][2];
582 twb[7] += pyv[1][2];
583 twb[8] += pyv[2][2];
584 }
585
586 /* computation of matrix WC = (deriv2)t * weight * (deriv2) */
587 vk->tmpArr[kt]->wc[0] = ew12 * e21 + ew13;
588 vk->tmpArr[kt]->wc[1] = ew22 * e21 + ew23;
589 vk->tmpArr[kt]->wc[3] = ew32 * e21 + ew33;
590 vk->tmpArr[kt]->wc[2] = ew21 * e12 + ew22 * e22 + ew24;
591 vk->tmpArr[kt]->wc[4] = ew31 * e12 + ew32 * e22 + ew34;
592 vk->tmpArr[kt]->wc[5] = ew31 * e13 + ew32 * e23 + ew34 * e43 + ew35;
593
594 /* computation of matrices WCI = (WC)**(-1) and WBCI = WB * WCI */
595 IERR=cfdinv(&(vk->tmpArr[kt]->wc[0]), twci, -3);
596 if (IERR) {IERR=cfdinv(&(vk->tmpArr[kt]->wc[0]), twci, 3);}
597 if (IERR) return IERR;
598
599
600 twbci[0] = twb[0]*twci[0] + twb[3]*twci[1] + twb[6]*twci[3];
601 twbci[1] = twb[1]*twci[0] + twb[4]*twci[1] + twb[7]*twci[3];
602 twbci[2] = twb[2]*twci[0] + twb[5]*twci[1] + twb[8]*twci[3];
603 twbci[3] = twb[0]*twci[1] + twb[3]*twci[2] + twb[6]*twci[4];
604 twbci[4] = twb[1]*twci[1] + twb[4]*twci[2] + twb[7]*twci[4];
605 twbci[5] = twb[2]*twci[1] + twb[5]*twci[2] + twb[8]*twci[4];
606 twbci[6] = twb[0]*twci[3] + twb[3]*twci[4] + twb[6]*twci[5];
607 twbci[7] = twb[1]*twci[3] + twb[4]*twci[4] + twb[7]*twci[5];
608 twbci[8] = twb[2]*twci[3] + twb[5]*twci[4] + twb[8]*twci[5];
609
610 /* subtraction of WBCI * (WB)t from matrix WA */
611 wa[0] = wa[0] - twbci[0]*twb[0] - twbci[3]*twb[3] - twbci[6]*twb[6];
612 wa[1] = wa[1] - twbci[0]*twb[1] - twbci[3]*twb[4] - twbci[6]*twb[7];
613 wa[2] = wa[2] - twbci[1]*twb[1] - twbci[4]*twb[4] - twbci[7]*twb[7];
614 wa[3] = wa[3] - twbci[0]*twb[2] - twbci[3]*twb[5] - twbci[6]*twb[8];
615 wa[4] = wa[4] - twbci[1]*twb[2] - twbci[4]*twb[5] - twbci[7]*twb[8];
616 wa[5] = wa[5] - twbci[2]*twb[2] - twbci[5]*twb[5] - twbci[8]*twb[8];
617
618 /* subtraction of WBCI * TT from vector TV */
619 tv[0] = tv[0] - twbci[0] * vk->tmpArr[kt]->tt[0] - twbci[3] * vk->tmpArr[kt]->tt[1] - twbci[6] * vk->tmpArr[kt]->tt[2];
620 tv[1] = tv[1] - twbci[1] * vk->tmpArr[kt]->tt[0] - twbci[4] * vk->tmpArr[kt]->tt[1] - twbci[7] * vk->tmpArr[kt]->tt[2];
621 tv[2] = tv[2] - twbci[2] * vk->tmpArr[kt]->tt[0] - twbci[5] * vk->tmpArr[kt]->tt[1] - twbci[8] * vk->tmpArr[kt]->tt[2];
622 //Save to vertex ....
623 for( int tpn=0; tpn<9; tpn++){
624 vk->tmpArr[kt]->wb[tpn] = twb[tpn];
625 if(tpn<6)vk->tmpArr[kt]->wci[tpn] = twci[tpn];
626 vk->tmpArr[kt]->wbci[tpn] = twbci[tpn];
627 }
628 }
629 if (vk->useApriorVertex) {
630 for (ic = 0; ic < 3; ++ic) { xyzt[ic] = vk->apriorV[ic] - vk->refIterV[ic] - xyz[ic];}
631 for (ic = 0; ic < 6; ++ic) {wgtvrtd[ic] = vk->apriorVWGT[ic];}
632 wa[0] += wgtvrtd[0];
633 wa[1] += wgtvrtd[1];
634 wa[2] += wgtvrtd[2];
635 wa[3] += wgtvrtd[3];
636 wa[4] += wgtvrtd[4];
637 wa[5] += wgtvrtd[5];
638 vk->wa[0] += wgtvrtd[0];
639 vk->wa[1] += wgtvrtd[1];
640 vk->wa[2] += wgtvrtd[2];
641 vk->wa[3] += wgtvrtd[3];
642 vk->wa[4] += wgtvrtd[4];
643 vk->wa[5] += wgtvrtd[5];
644 tv[0] = tv[0] + xyzt[0] * wgtvrtd[0] + xyzt[1] * wgtvrtd[1] + xyzt[2] * wgtvrtd[3];
645 tv[1] = tv[1] + xyzt[0] * wgtvrtd[1] + xyzt[1] * wgtvrtd[2] + xyzt[2] * wgtvrtd[4];
646 tv[2] = tv[2] + xyzt[0] * wgtvrtd[3] + xyzt[1] * wgtvrtd[4] + xyzt[2] * wgtvrtd[5];
647 stv[0] = stv[0] + xyzt[0] * wgtvrtd[0] + xyzt[1] * wgtvrtd[1] + xyzt[2] * wgtvrtd[3];
648 stv[1] = stv[1] + xyzt[0] * wgtvrtd[1] + xyzt[1] * wgtvrtd[2] + xyzt[2] * wgtvrtd[4];
649 stv[2] = stv[2] + xyzt[0] * wgtvrtd[3] + xyzt[1] * wgtvrtd[4] + xyzt[2] * wgtvrtd[5];
650 }
651 //Save T vector(see Billoir...)
652 vk->T[0]=stv[0]; vk->T[1]=stv[1]; vk->T[2]=stv[2];
653
654 //std::cout<<" newwa="<<wa[0]<<", "<<wa[1]<<", "<<wa[2]<<", "<<wa[3]<<", "<<wa[4]<<", "<<wa[5]<<'\n';
655
656 /* solution of the linear system */
657 if ( !vk->passNearVertex ) { /* No correction for these constraints */
658 /* because solution is calculated with full error matrix*/
659 if( vk->ConstraintList.empty()){
660 double EigThreshold = 1.e-9;
661 vkGetEigVal(wa, eigv, 3);
662 if (eigv[0] < eigv[2] * EigThreshold) {
663 wa[0] += (eigv[2] * EigThreshold - eigv[0]);
664 wa[2] += (eigv[2] * EigThreshold - eigv[0]);
665 wa[5] += (eigv[2] * EigThreshold - eigv[0]);
666 }
667 }else{
668 vkGetEigVal(vk->wa, eigv, 3);
669 wa[0] += eigv[2] * 1.e-12; //Permanent addition works better than addition
670 wa[2] += eigv[2] * 1.e-12; // for small eigenvalues only.
671 wa[5] += eigv[2] * 1.e-12;
672 vk->wa[0] += eigv[2] * 1.e-12; //Permanent addition works better than addition
673 vk->wa[2] += eigv[2] * 1.e-12; // for small eigenvalues only.
674 vk->wa[5] += eigv[2] * 1.e-12;
675 }
676 }
677
678 /* covariance matrix on vertex coordinates */
679 for(ii=0; ii<6; ii++) {if(std::isnan(wa[ii])) return -2;} // Matrix inversion failed
680 if(wa[0]<0 || wa[2]<0 || wa[5]<0) return -2; // Matrix elements must be positive!
681 IERR=cfdinv(wa, &(vk->fitVcov[0]), -3);
682 if (IERR) {IERR=cfdinv(wa, &(vk->fitVcov[0]), 3);} // last safety
683 if ( !vk->passNearVertex ) { if (IERR) return IERR; } // If nothing helps - detect failure (not for passNearVertex!!!)
684 else {vk->fitVcov[0]=1.;vk->fitVcov[1]=0;vk->fitVcov[2]=1.;vk->fitVcov[3]=0;vk->fitVcov[4]=0;vk->fitVcov[5]=1;}
685
686 /* corrections to vertex coordinates */
687 dxyz[0] = vk->fitVcov[0]*tv[0] + vk->fitVcov[1]*tv[1] + vk->fitVcov[3]*tv[2];
688 dxyz[1] = vk->fitVcov[1]*tv[0] + vk->fitVcov[2]*tv[1] + vk->fitVcov[4]*tv[2];
689 dxyz[2] = vk->fitVcov[3]*tv[0] + vk->fitVcov[4]*tv[1] + vk->fitVcov[5]*tv[2];
690 for (j = 0; j < 3; ++j) {
691 vk->dxyz0[j] = dxyz[j];
692 vk->fitV[j] = xyzf[j] = vk->iniV[j] + dxyz[j];
693 }
694 //std::cout<< "NVertex Old="<<vk->iniV[0]<<", "<<vk->iniV[1]<<", "<<vk->iniV[2]<<" CloseV="<<vk->passNearVertex<<'\n';
695 //std::cout<<__func__<<":NVertex shift="<<dxyz[0]<<", "<<dxyz[1]<<", "<<dxyz[2]<<'\n';
696
697
698
699
700
701 /*-----------------------------------------------------------*/
702 /* corrections to track parameters and covariance matrices */
703
704 for (kt = 0; kt < NTRK; ++kt) { /* variation on PAR is WCI * TT - (WBCI)t * DXYZ */
705 for( int tpn=0; tpn<9; tpn++){
706 if(tpn<6)twci[tpn] = vk->tmpArr[kt]->wci[tpn];
707 twbci[tpn] = vk->tmpArr[kt]->wbci[tpn];
708 }
709 double tt1=vk->tmpArr[kt]->tt[0];
710 double tt2=vk->tmpArr[kt]->tt[1];
711 double tt3=vk->tmpArr[kt]->tt[2];
712 vk->tmpArr[kt]->parf0[0] = twci[0]*tt1 + twci[1]*tt2 + twci[3]*tt3 - twbci[0]*dxyz[0] - twbci[1]*dxyz[1] - twbci[2]*dxyz[2];
713 if( !std::isfinite(vk->tmpArr[kt]->parf0[0]) ) return -19; // Rare FPE presumably seen in trigger
714 vk->tmpArr[kt]->parf0[1] = twci[1]*tt1 + twci[2]*tt2 + twci[4]*tt3 - twbci[3]*dxyz[0] - twbci[4]*dxyz[1] - twbci[5]*dxyz[2];
715 if( !std::isfinite(vk->tmpArr[kt]->parf0[1]) ) return -19; // Rare FPE presumably seen in trigger
716 vk->tmpArr[kt]->parf0[2] = twci[3]*tt1 + twci[4]*tt2 + twci[5]*tt3 - twbci[6]*dxyz[0] - twbci[7]*dxyz[1] - twbci[8]*dxyz[2];
717 if( !std::isfinite(vk->tmpArr[kt]->parf0[2]) ) return -19; // Rare FPE presumably seen in trigger
718 if( (vk->TrackList[kt]->iniP[2] + vk->tmpArr[kt]->parf0[2]) * vk->TrackList[kt]->iniP[2] < 0 ){
719 vk->tmpArr[kt]->parf0[2]= - vk->TrackList[kt]->iniP[2]/4.; } // VK 15.12.2009 - Protection against change of sign
720 vk->TrackList[kt]->fitP[0] = vk->TrackList[kt]->iniP[0] + vk->tmpArr[kt]->parf0[0];
721 vk->TrackList[kt]->fitP[1] = vk->TrackList[kt]->iniP[1] + vk->tmpArr[kt]->parf0[1];
722 vk->TrackList[kt]->fitP[2] = vk->TrackList[kt]->iniP[2] + vk->tmpArr[kt]->parf0[2];
723 //std::cout<<__func__<<":NTrack shift="<<vk->tmpArr[kt]->parf0[0]<<", "<<vk->tmpArr[kt]->parf0[1]<<", "
724 // <<vk->tmpArr[kt]->parf0[2]<<'\n';
725 }
726 /* ------------------------------------------------------------ */
727 /* The same solution but through full matrix */
728 /* ------------------------------------------------------------ */
729 if ( vk->passNearVertex ) {
730 //std::cout <<" Std="<<vk->dxyz0[0]<<", "<<vk->dxyz0[1]<<", "<<vk->dxyz0[2]<<'\n';
731 stv[0] = stv[0] - drdvy[0][0] * vk->FVC.rv0[0] - drdvy[1][0] * vk->FVC.rv0[1];
732 stv[1] = stv[1] - drdvy[0][1] * vk->FVC.rv0[0] - drdvy[1][1] * vk->FVC.rv0[1];
733 stv[2] = stv[2] - drdvy[0][2] * vk->FVC.rv0[0] - drdvy[1][2] * vk->FVC.rv0[1];
734 //Save T vector(see Billoir...)
735 vk->T[0]=stv[0];vk->T[1]=stv[1];vk->T[2]=stv[2];
736 //
737 vk->wa[0] += vyv[0][0];
738 vk->wa[1] += vyv[1][0];
739 vk->wa[2] += vyv[1][1];
740 vk->wa[3] += vyv[2][0];
741 vk->wa[4] += vyv[2][1];
742 vk->wa[5] += vyv[2][2];
743 FullMTXfill(vk, vk->ader);
744 if ( vk->passNearVertex ) {
745 for (it = 1; it <= NTRK; ++it) {
746 drdpy[0][0] = vk->tmpArr[it-1]->drdp[0][0] * vk->FVC.ywgt[0] + vk->tmpArr[it-1]->drdp[1][0] * vk->FVC.ywgt[1];
747 drdpy[1][0] = vk->tmpArr[it-1]->drdp[0][0] * vk->FVC.ywgt[1] + vk->tmpArr[it-1]->drdp[1][0] * vk->FVC.ywgt[2];
748 drdpy[0][1] = vk->tmpArr[it-1]->drdp[0][1] * vk->FVC.ywgt[0] + vk->tmpArr[it-1]->drdp[1][1] * vk->FVC.ywgt[1];
749 drdpy[1][1] = vk->tmpArr[it-1]->drdp[0][1] * vk->FVC.ywgt[1] + vk->tmpArr[it-1]->drdp[1][1] * vk->FVC.ywgt[2];
750 drdpy[0][2] = vk->tmpArr[it-1]->drdp[0][2] * vk->FVC.ywgt[0] + vk->tmpArr[it-1]->drdp[1][2] * vk->FVC.ywgt[1];
751 drdpy[1][2] = vk->tmpArr[it-1]->drdp[0][2] * vk->FVC.ywgt[1] + vk->tmpArr[it-1]->drdp[1][2] * vk->FVC.ywgt[2];
752 for (jt = 1; jt <= NTRK; ++jt) { /* Matrix */
753 for (k = 0; k < 3; ++k) {
754 for (l = 0; l < 3; ++l) {
755 dpipj[k][l] = 0.;
756 for (j = 0; j < 2; ++j) {
757 dpipj[k][l] += vk->tmpArr[jt-1]->drdp[j][k] * drdpy[j][l];
758 }
759 }
760 }
761 for (k = 1; k <= 3; ++k) {
762 for (l = 1; l <= 3; ++l) {
763 ader_ref(it * 3 + k, jt * 3 + l) += dpipj[l-1][k-1];
764 }
765 }
766 }
767 }
768 }
769 //VK 27-Sep-2006 Add eigenvalue limitation for 7,8,9,10,13,14 constraints
770 double ArrTmp[9]; int ktmp=0;
771 for (k=1; k<=3; ++k) {
772 for (l=1; l<=k; ++l) { ArrTmp[ktmp++] = ader_ref(k,l); }}
773 vkGetEigVal(ArrTmp, eigv, 3);
774 double EigAddon=0.;
775 if( eigv[0]<0 ){EigAddon=eigv[0];}
776 for (k = 1; k <=3; ++k) {
777 ader_ref(k,k) = ader_ref(k,k) - EigAddon + eigv[2] * 1.e-18 ;
778 }
779 //----------------------------------------------------------------------------------
780 long int NParam = NTRK*3 + 3;
781 dsinv(NParam, vk->ader, vkalNTrkM*3+3, &IERR);
782 if ( IERR) return IERR;
783 double *fortst = new double[vkalNTrkM*3+3];
784 for (j = 0; j < 3; ++j) {
785 fortst[j] = stv[j];
786 for (ii=0; ii<NTRK; ++ii) { fortst[ii*3 +3 +j] = vk->tmpArr[ii]->tt[j];}
787 }
788 for (j=0; j<3; ++j) {
789 dxyz[j] = 0.;
790 for (ii=0; ii<NParam; ++ii) {dxyz[j] += ader_ref(j+1, ii+1) * fortst[ii];}
791 vk->dxyz0[j] = dxyz [j];
792 vk->fitV[j] = vk->iniV[j] + dxyz[j];
793 }
794 double tparf0[3]={0.};
795 for (it = 1; it <= NTRK; ++it) {
796 TWRK* t_trk=vk->tmpArr[it-1].get();
797 for (j=0; j<3; ++j) {
798 tparf0[j] = 0.;
799 for (ii = 1; ii <= NParam; ++ii) { tparf0[j] += ader_ref(it*3+j+1, ii)*fortst[ii-1];}
800 }
801 for (j=0; j<3; ++j) { t_trk->parf0[j] = tparf0[j];
802 vk->TrackList[it-1]->fitP[j] = vk->TrackList[it-1]->iniP[j] + tparf0[j];}
803 }
804 vk->fitVcov[0] = ader_ref(1, 1);
805 vk->fitVcov[1] = ader_ref(2, 1);
806 vk->fitVcov[2] = ader_ref(2, 2);
807 vk->fitVcov[3] = ader_ref(3, 1);
808 vk->fitVcov[4] = ader_ref(3, 2);
809 vk->fitVcov[5] = ader_ref(3, 3);
810 delete[] fortst;
811
812 //std::cout<< "NVertex Full="<<vk->fitV[0]<<", "<<vk->fitV[1]<<", "<<vk->fitV[2]<<'\n';
813 //std::cout<< "NVertex Full shft="<<dxyz[0]<<", "<<dxyz[1]<<", "<<dxyz[2]<<'\n';
814 //double *tmpA=new double[3+3*NTRK+20];
815 //IERR = FullMCNSTfill( vk, vk->ader, tmpA);
816 //delete[] tmpA;
817 }
818 /* ------------------------------------------------------------ */
819 /* End of the solution with full matrix */
820 /* */
821 /* Now constraints */
822 /* ------------------------------------------------------------ */
823 double dCoefNorm = 0;
824 if ( !vk->ConstraintList.empty()) {
825 IERR = vtcfitc( vk );
826 if (IERR != 0) return IERR;
832 double* tmpB=new double[3+3*NTRK]; double* tmpA=new double[3+3*NTRK];
833 for (ii=0; ii<3; ++ii) {
834 tmpA[ii] = vk->fitV[ii] - vk->iniV[ii];
835 tmpB[ii] = vk->dxyz0[ii];
836 }
837 for ( it=0; it<NTRK; ++it) {
838 tmpA[0 +3*it+3] = vk->TrackList[it]->fitP[0] - vk->TrackList[it]->iniP[0];
839 tmpA[1 +3*it+3] = vk->TrackList[it]->fitP[1] - vk->TrackList[it]->iniP[1];
840 tmpA[2 +3*it+3] = vk->TrackList[it]->fitP[2] - vk->TrackList[it]->iniP[2];
841 tmpB[0 +3*it+3] = vk->tmpArr[it]->parf0[0];
842 tmpB[1 +3*it+3] = vk->tmpArr[it]->parf0[1];
843 tmpB[2 +3*it+3] = vk->tmpArr[it]->parf0[2];
844 }
845 double scalAA=0., scalAB=0.;
846 for (ii=0; ii<3+3*NTRK; ii++) scalAA += tmpA[ii]*tmpA[ii];
847 for (ii=0; ii<3+3*NTRK; ii++) scalAB += tmpA[ii]*tmpB[ii];
848 if(scalAB != 0.) dCoefNorm = -scalAA/scalAB;
849 //double scalCC;
850 //for (ii=0; ii<3+3*NTRK; ii++) scalCC += (tmpA[ii]+dCoefNorm*tmpB[ii])*(tmpA[ii]+dCoefNorm*tmpB[ii]); // Length of perp vector
851 delete[] tmpA; delete[] tmpB;
852
853 //std::cout<<"VRTOLD="<<vk->fitV[0] - vk->iniV[0]<<", "<<vk->fitV[1] - vk->iniV[1]<<", "
854 // <<vk->fitV[2] - vk->iniV[2]<<'\n';
855 //for ( it=0; it<NTRK; ++it) std::cout<<"TRKOLD="<<vk->TrackList[it]->fitP[0] - vk->TrackList[it]->iniP[0]<<", "
856 // <<vk->TrackList[it]->fitP[1] - vk->TrackList[it]->iniP[1]<<", "
857 // <<vk->TrackList[it]->fitP[2] - vk->TrackList[it]->iniP[2]<<'\n';
858 //tmpA=new double[3+3*NTRK+20];
859 //IERR = FullMCNSTfill( vk, vk->ader, tmpA);
860 //delete[] tmpA;
861 }
862
863 /* chi2 with fitted values */
864
865 for (it = 0; it < NTRK; ++it) { //Check if curvature sign is changed or change in Pt is too big
866 if(vk->TrackList[it]->Id >= 0){
867 double Ratio=vk->TrackList[it]->fitP[2]/vk->TrackList[it]->Perig[4]; if(std::abs(Ratio)<1.)Ratio=1./Ratio;
868 if(Ratio<0. || Ratio > vkalAllowedPtChange ){
869 if(std::abs(vk->TrackList[it]->fitP[2])<std::abs(vk->TrackList[it]->Perig[4]) || Ratio<0 ){
870 vk->TrackList[it]->fitP[2]=vk->TrackList[it]->Perig[4]/vkalAllowedPtChange;
871 }else{
872 vk->TrackList[it]->fitP[2]=vk->TrackList[it]->Perig[4]*vkalAllowedPtChange;
873 }
874 }
875 }
876 }
877 //--Additional iterations along shift direction
878 bool improved=makePostFit( vk , wgtvrtd, dCoefNorm);
879 if(!improved)improved=makePostFit( vk , wgtvrtd, dCoefNorm); //Step truncation doesn't help. Make second pass
880 if(!improved)vk->truncatedStep=true;
881
882 //-- If no additional iterations (for tests)
883 //makeNoPostFit( vk , wgtvrtd, dCoefNorm);
884
885
886 return 0;
887
888}
889
890} //End of namespace Trk
891
#define M_PI
#define vkalAllowedPtChange
Definition CommonPars.h:25
#define vkalNTrkM
Definition CommonPars.h:22
#define ader_ref(a_1, a_2)
Definition FullMtx.cxx:17
#define xyz
#define xyzt
#define cvder_ref(a_1, a_2)
#define dcv_ref(a_1, a_2)
double parf0[3]
double drdp[2][3]
double a0() const
double z() const
double invR() const
double phi() const
double theta() const
void setCnstV(double v[3]) noexcept
std::vector< std::unique_ptr< VKTrack > > TrackList
double ader[(3 *vkalNTrkM+3) *(3 *vkalNTrkM+3)]
std::vector< std::unique_ptr< VKConstraintBase > > ConstraintList
std::vector< std::unique_ptr< TWRK > > tmpArr
std::unique_ptr< VKalVrtControl > vk_fitterControl
static void getMagFld(const double, const double, const double, double &, double &, double &, const VKalVrtControlBase *)
static double getEffField(double bx, double by, double bz, double phi, double theta)
Definition VKalVrtBMag.h:60
Ensure that the ATLAS eigen extensions are properly loaded.
double cfchi2(double *xyzt, const long int ich, double *part, const double *par0, double *wgt, double *rmnd)
void FullMTXfill(VKVertex *vk, double *ader)
Definition FullMtx.cxx:19
void dsinv(long int n, double *a, long int DIM, long int *ifail) noexcept
int vtcfitc(VKVertex *vk)
Definition VtCFitC.cxx:16
int cfdinv(double *cov, double *wgt, long int NI)
void vkGetEigVal(const double ci[], double d[], int n)
double finter(double y0, double y1, double y2, double x0, double x1, double x2)
int vtcfit(VKVertex *vk)
Definition VtCFit.cxx:293
double cfVrtDstSig(VKVertex *vk, bool UseTrkErr)
Definition cfVrtDst.cxx:33
void applyConstraints(VKVertex *vk)
Definition stCnst.cxx:22
double getCnstValues2(VKVertex *vk) noexcept
Definition VtCFitC.cxx:244