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