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 while(dphi[kt] > M_PI)dphi[kt]-=2.*M_PI;
420 while(dphi[kt] < -M_PI)dphi[kt]+=2.*M_PI;
421
422
423 /* derivatives (deriv1) of perigee param. w.r.t. X,Y,Z (vertex) uu=Q, vv=R */
424 double d11 = sinf - ( uu*cosf *invR_ini);
425 double d12 = -cosf - ( uu*sinf *invR_ini);
426 double d21 = -cosf * cotth + ( (vv*cosf-uu*sinf)*cotth *invR_ini) - uu*cosf*invR_ini*corrCz;
427 double d22 = -sinf * cotth + ( (vv*sinf+uu*cosf)*cotth *invR_ini) - uu*sinf*invR_ini*corrCz;
428 //double d23 = 1.; //VK for reference
429 double d41 = -cosf * invR_ini;
430 double d42 = -sinf * invR_ini;
431 if (trk->Charge == 0) {
432 d11 = sinf;
433 d12 = -cosf;
434 d21 = -cosf * cotth;
435 d22 = -sinf * cotth;
436 d41 = 0.;
437 d42 = 0.;
438 }
439
440 /* matrix DW = (deriv1)t * weight */
441 double dw11 = d11 * trk->WgtM[0] + d21 * trk->WgtM[1] + d41 * trk->WgtM[6];
442 double dw12 = d11 * trk->WgtM[1] + d21 * trk->WgtM[2] + d41 * trk->WgtM[7];
443 double dw13 = d11 * trk->WgtM[3] + d21 * trk->WgtM[4] + d41 * trk->WgtM[8];
444 double dw14 = d11 * trk->WgtM[6] + d21 * trk->WgtM[7] + d41 * trk->WgtM[9];
445 double dw15 = d11 * trk->WgtM[10]+ d21 * trk->WgtM[11]+ d41 * trk->WgtM[13];
446
447
448 double dw21 = d12 * trk->WgtM[0] + d22 * trk->WgtM[1] + d42 * trk->WgtM[6];
449 double dw22 = d12 * trk->WgtM[1] + d22 * trk->WgtM[2] + d42 * trk->WgtM[7];
450 double dw23 = d12 * trk->WgtM[3] + d22 * trk->WgtM[4] + d42 * trk->WgtM[8];
451 double dw24 = d12 * trk->WgtM[6] + d22 * trk->WgtM[7] + d42 * trk->WgtM[9];
452 double dw25 = d12 * trk->WgtM[10]+ d22 * trk->WgtM[11]+ d42 * trk->WgtM[13];
453 double dw31 = trk->WgtM[1];
454 double dw32 = trk->WgtM[2];
455 double dw33 = trk->WgtM[4];
456 double dw34 = trk->WgtM[7];
457 double dw35 = trk->WgtM[11];
458
459 /* summation of DW * DPAR to vector TV */
460 tv[0] += dw11 * deps[kt] + dw12 * dzp[kt];
461 tv[1] += dw21 * deps[kt] + dw22 * dzp[kt];
462 tv[2] += dw31 * deps[kt] + dw32 * dzp[kt];
463 tv[0] += dw13 * dtet[kt] + dw14 * dphi[kt] + dw15 * drho[kt];
464 tv[1] += dw23 * dtet[kt] + dw24 * dphi[kt] + dw25 * drho[kt];
465 tv[2] += dw33 * dtet[kt] + dw34 * dphi[kt] + dw35 * drho[kt];
466
467 stv[0] += dw11 * deps[kt] + dw12 * dzp[kt];
468 stv[1] += dw21 * deps[kt] + dw22 * dzp[kt];
469 stv[2] += dw31 * deps[kt] + dw32 * dzp[kt];
470 stv[0] += dw13 * dtet[kt] + dw14 * dphi[kt] + dw15*drho[kt];
471 stv[1] += dw23 * dtet[kt] + dw24 * dphi[kt] + dw25*drho[kt];
472 stv[2] += dw33 * dtet[kt] + dw34 * dphi[kt] + dw35*drho[kt];
473
474 /* derivatives (deriv2) of perigee param. w.r.t. theta,phi,1/R (vertex) uu=Q, vv=R */
475 double e12 = uu - invR_ini * vv * uu;
476 double e13 = -uu*uu / 2.;
477 double e21 = uu *(1. - vv*invR_ini) * (cotth*cotth + 1.);
478 double e22 = -vv*cotth + (vv*vv-uu*uu)*invR_ini*cotth - uu*vv*invR_ini*corrCz;
479 double e23 = uu*vv*cotth -0.5*uu*uu*corrCz;
480 double e43 = -uu + 2.*uu*vv*invR_ini;
481 /* if straight line, set to zero derivatives w.r.t. the curvature */
482 /* and curvature terms in derivatives */
483 if (trk->Charge == 0) {
484 e12 = uu;
485 e13 = 0.;
486 e21 = uu * (cotth*cotth + 1.);
487 e22 = -vv * cotth;
488 e23 = 0.;
489 e43 = 0.;
490 }
491
492 /* matrix EW = (deriv2)t * weight */
493 double ew11 = e21 * trk->WgtM[1] + trk->WgtM[3];
494 double ew12 = e21 * trk->WgtM[2] + trk->WgtM[4];
495 double ew13 = e21 * trk->WgtM[4] + trk->WgtM[5];
496 double ew14 = e21 * trk->WgtM[7] + trk->WgtM[8];
497 double ew15 = e21 * trk->WgtM[11]+ trk->WgtM[12];
498 double ew21 = e12 * trk->WgtM[0] + e22 * trk->WgtM[1] + trk->WgtM[6];
499 double ew22 = e12 * trk->WgtM[1] + e22 * trk->WgtM[2] + trk->WgtM[7];
500 double ew23 = e12 * trk->WgtM[3] + e22 * trk->WgtM[4] + trk->WgtM[8];
501 double ew24 = e12 * trk->WgtM[6] + e22 * trk->WgtM[7] + trk->WgtM[9];
502 double ew25 = e12 * trk->WgtM[10]+ e22 * trk->WgtM[11]+ trk->WgtM[13];
503 double ew31 = e13 * trk->WgtM[0] + e23 * trk->WgtM[1] + e43 * trk->WgtM[6] + trk->WgtM[10];
504 double ew32 = e13 * trk->WgtM[1] + e23 * trk->WgtM[2] + e43 * trk->WgtM[7] + trk->WgtM[11];
505 double ew33 = e13 * trk->WgtM[3] + e23 * trk->WgtM[4] + e43 * trk->WgtM[8] + trk->WgtM[12];
506 double ew34 = e13 * trk->WgtM[6] + e23 * trk->WgtM[7] + e43 * trk->WgtM[9] + trk->WgtM[13];
507 double ew35 = e13 * trk->WgtM[10]+ e23 * trk->WgtM[11]+ e43 * trk->WgtM[13]+ trk->WgtM[14];
508
509 /* computation of vector TT = EW * DPAR */
510 TWRK* t_trk=vk->tmpArr[kt].get();
511 t_trk->tt[0] = ew11*deps[kt] + ew12*dzp[kt];
512 t_trk->tt[1] = ew21*deps[kt] + ew22*dzp[kt];
513 t_trk->tt[2] = ew31*deps[kt] + ew32*dzp[kt];
514 t_trk->tt[0] += ew13*dtet[kt] + ew14*dphi[kt] + ew15*drho[kt];
515 t_trk->tt[1] += ew23*dtet[kt] + ew24*dphi[kt] + ew25*drho[kt];
516 t_trk->tt[2] += ew33*dtet[kt] + ew34*dphi[kt] + ew35*drho[kt];
517 if ( vk->passNearVertex ) {
518 for (j = 1; j <= 2; ++j) { /* Derivatives dR/dQi */
519 int i3=(kt+1)*3;
520 t_trk->drdp[j-1][0] = cvder_ref(j,4) * dcv_ref(4,i3 + 1) + cvder_ref(j,5) * dcv_ref(5,i3 + 1);
521 t_trk->drdp[j-1][1] = cvder_ref(j,4) * dcv_ref(4,i3 + 2) + cvder_ref(j,5) * dcv_ref(5,i3 + 2);
522 t_trk->drdp[j-1][2] = cvder_ref(j,4) * dcv_ref(4,i3 + 3) + cvder_ref(j,5) * dcv_ref(5,i3 + 3);
523 t_trk->drdp[j-1][0] += cvder_ref(j, 6) * dcv_ref(6, i3 + 1);
524 t_trk->drdp[j-1][1] += cvder_ref(j, 6) * dcv_ref(6, i3 + 2);
525 t_trk->drdp[j-1][2] += cvder_ref(j, 6) * dcv_ref(6, i3 + 3);
526 }
527 /* Matrix dR/dQ */
528 drdpy[0][0] = t_trk->drdp[0][0] * vk->FVC.ywgt[0] + t_trk->drdp[1][0] * vk->FVC.ywgt[1];
529 drdpy[1][0] = t_trk->drdp[0][0] * vk->FVC.ywgt[1] + t_trk->drdp[1][0] * vk->FVC.ywgt[2];
530 drdpy[0][1] = t_trk->drdp[0][1] * vk->FVC.ywgt[0] + t_trk->drdp[1][1] * vk->FVC.ywgt[1];
531 drdpy[1][1] = t_trk->drdp[0][1] * vk->FVC.ywgt[1] + t_trk->drdp[1][1] * vk->FVC.ywgt[2];
532 drdpy[0][2] = t_trk->drdp[0][2] * vk->FVC.ywgt[0] + t_trk->drdp[1][2] * vk->FVC.ywgt[1];
533 drdpy[1][2] = t_trk->drdp[0][2] * vk->FVC.ywgt[1] + t_trk->drdp[1][2] * vk->FVC.ywgt[2];
534 t_trk->tt[0] -= drdpy[0][0]*vk->FVC.rv0[0] + drdpy[1][0]*vk->FVC.rv0[1];
535 t_trk->tt[1] -= drdpy[0][1]*vk->FVC.rv0[0] + drdpy[1][1]*vk->FVC.rv0[1];
536 t_trk->tt[2] -= drdpy[0][2]*vk->FVC.rv0[0] + drdpy[1][2]*vk->FVC.rv0[1];
537 for (ii = 1; ii <= 3; ++ii) { /* Matrix dR/dQi*Y*dR/dV */
538 for (jj = 1; jj <= 3; ++jj) {
539 pyv[jj-1][ii-1] = drdpy[0][ii-1] * cvder_ref(1, jj) + drdpy[1][ii-1] * cvder_ref(2, jj);
540 }
541 }
542 }
543
544 /* summation of (deriv1)t * weight * (deriv1) to matrix WA */
545 wa[0] += dw11 * d11 + dw12 * d21 + dw14 * d41;
546 wa[1] += dw11 * d12 + dw12 * d22 + dw14 * d42;
547 wa[2] += dw21 * d12 + dw22 * d22 + dw24 * d42;
548 wa[3] += dw12;
549 wa[4] += dw22;
550 wa[5] += dw32;
551 vk->wa[0] = vk->wa[0] + dw11 * d11 + dw12 * d21 + dw14 * d41;
552 vk->wa[1] = vk->wa[1] + dw11 * d12 + dw12 * d22 + dw14 * d42;
553 vk->wa[2] = vk->wa[2] + dw21 * d12 + dw22 * d22 + dw24 * d42;
554 vk->wa[3] += dw12;
555 vk->wa[4] += dw22;
556 vk->wa[5] += dw32;
557
558 /* computation of matrix WB = (deriv1)t * weight * (deriv2) */
559 twb[0] = dw12 * e21 + dw13;
560 twb[1] = dw22 * e21 + dw23;
561 twb[2] = dw32 * e21 + dw33;
562 twb[3] = dw11 * e12 + dw12 * e22 + dw14;
563 twb[4] = dw21 * e12 + dw22 * e22 + dw24;
564 twb[5] = dw31 * e12 + dw32 * e22 + dw34;
565 twb[6] = dw11 * e13 + dw12 * e23 + dw14 * e43 + dw15;
566 twb[7] = dw21 * e13 + dw22 * e23 + dw24 * e43 + dw25;
567 twb[8] = dw31 * e13 + dw32 * e23 + dw34 * e43 + dw35;
568 if ( vk->passNearVertex ) {
569 twb[0] += pyv[0][0];
570 twb[1] += pyv[1][0];
571 twb[2] += pyv[2][0];
572 twb[3] += pyv[0][1];
573 twb[4] += pyv[1][1];
574 twb[5] += pyv[2][1];
575 twb[6] += pyv[0][2];
576 twb[7] += pyv[1][2];
577 twb[8] += pyv[2][2];
578 }
579
580 /* computation of matrix WC = (deriv2)t * weight * (deriv2) */
581 vk->tmpArr[kt]->wc[0] = ew12 * e21 + ew13;
582 vk->tmpArr[kt]->wc[1] = ew22 * e21 + ew23;
583 vk->tmpArr[kt]->wc[3] = ew32 * e21 + ew33;
584 vk->tmpArr[kt]->wc[2] = ew21 * e12 + ew22 * e22 + ew24;
585 vk->tmpArr[kt]->wc[4] = ew31 * e12 + ew32 * e22 + ew34;
586 vk->tmpArr[kt]->wc[5] = ew31 * e13 + ew32 * e23 + ew34 * e43 + ew35;
587
588 /* computation of matrices WCI = (WC)**(-1) and WBCI = WB * WCI */
589 IERR=cfdinv(&(vk->tmpArr[kt]->wc[0]), twci, -3);
590 if (IERR) {IERR=cfdinv(&(vk->tmpArr[kt]->wc[0]), twci, 3);}
591 if (IERR) return IERR;
592
593
594 twbci[0] = twb[0]*twci[0] + twb[3]*twci[1] + twb[6]*twci[3];
595 twbci[1] = twb[1]*twci[0] + twb[4]*twci[1] + twb[7]*twci[3];
596 twbci[2] = twb[2]*twci[0] + twb[5]*twci[1] + twb[8]*twci[3];
597 twbci[3] = twb[0]*twci[1] + twb[3]*twci[2] + twb[6]*twci[4];
598 twbci[4] = twb[1]*twci[1] + twb[4]*twci[2] + twb[7]*twci[4];
599 twbci[5] = twb[2]*twci[1] + twb[5]*twci[2] + twb[8]*twci[4];
600 twbci[6] = twb[0]*twci[3] + twb[3]*twci[4] + twb[6]*twci[5];
601 twbci[7] = twb[1]*twci[3] + twb[4]*twci[4] + twb[7]*twci[5];
602 twbci[8] = twb[2]*twci[3] + twb[5]*twci[4] + twb[8]*twci[5];
603
604 /* subtraction of WBCI * (WB)t from matrix WA */
605 wa[0] = wa[0] - twbci[0]*twb[0] - twbci[3]*twb[3] - twbci[6]*twb[6];
606 wa[1] = wa[1] - twbci[0]*twb[1] - twbci[3]*twb[4] - twbci[6]*twb[7];
607 wa[2] = wa[2] - twbci[1]*twb[1] - twbci[4]*twb[4] - twbci[7]*twb[7];
608 wa[3] = wa[3] - twbci[0]*twb[2] - twbci[3]*twb[5] - twbci[6]*twb[8];
609 wa[4] = wa[4] - twbci[1]*twb[2] - twbci[4]*twb[5] - twbci[7]*twb[8];
610 wa[5] = wa[5] - twbci[2]*twb[2] - twbci[5]*twb[5] - twbci[8]*twb[8];
611
612 /* subtraction of WBCI * TT from vector TV */
613 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];
614 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];
615 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];
616 //Save to vertex ....
617 for( int tpn=0; tpn<9; tpn++){
618 vk->tmpArr[kt]->wb[tpn] = twb[tpn];
619 if(tpn<6)vk->tmpArr[kt]->wci[tpn] = twci[tpn];
620 vk->tmpArr[kt]->wbci[tpn] = twbci[tpn];
621 }
622 }
623 if (vk->useApriorVertex) {
624 for (ic = 0; ic < 3; ++ic) { xyzt[ic] = vk->apriorV[ic] - vk->refIterV[ic] - xyz[ic];}
625 for (ic = 0; ic < 6; ++ic) {wgtvrtd[ic] = vk->apriorVWGT[ic];}
626 wa[0] += wgtvrtd[0];
627 wa[1] += wgtvrtd[1];
628 wa[2] += wgtvrtd[2];
629 wa[3] += wgtvrtd[3];
630 wa[4] += wgtvrtd[4];
631 wa[5] += wgtvrtd[5];
632 vk->wa[0] += wgtvrtd[0];
633 vk->wa[1] += wgtvrtd[1];
634 vk->wa[2] += wgtvrtd[2];
635 vk->wa[3] += wgtvrtd[3];
636 vk->wa[4] += wgtvrtd[4];
637 vk->wa[5] += wgtvrtd[5];
638 tv[0] = tv[0] + xyzt[0] * wgtvrtd[0] + xyzt[1] * wgtvrtd[1] + xyzt[2] * wgtvrtd[3];
639 tv[1] = tv[1] + xyzt[0] * wgtvrtd[1] + xyzt[1] * wgtvrtd[2] + xyzt[2] * wgtvrtd[4];
640 tv[2] = tv[2] + xyzt[0] * wgtvrtd[3] + xyzt[1] * wgtvrtd[4] + xyzt[2] * wgtvrtd[5];
641 stv[0] = stv[0] + xyzt[0] * wgtvrtd[0] + xyzt[1] * wgtvrtd[1] + xyzt[2] * wgtvrtd[3];
642 stv[1] = stv[1] + xyzt[0] * wgtvrtd[1] + xyzt[1] * wgtvrtd[2] + xyzt[2] * wgtvrtd[4];
643 stv[2] = stv[2] + xyzt[0] * wgtvrtd[3] + xyzt[1] * wgtvrtd[4] + xyzt[2] * wgtvrtd[5];
644 }
645 //Save T vector(see Billoir...)
646 vk->T[0]=stv[0]; vk->T[1]=stv[1]; vk->T[2]=stv[2];
647
648 //std::cout<<" newwa="<<wa[0]<<", "<<wa[1]<<", "<<wa[2]<<", "<<wa[3]<<", "<<wa[4]<<", "<<wa[5]<<'\n';
649
650 /* solution of the linear system */
651 if ( !vk->passNearVertex ) { /* No correction for these constraints */
652 /* because solution is calculated with full error matrix*/
653 if( vk->ConstraintList.empty()){
654 double EigThreshold = 1.e-9;
655 vkGetEigVal(wa, eigv, 3);
656 if (eigv[0] < eigv[2] * EigThreshold) {
657 wa[0] += (eigv[2] * EigThreshold - eigv[0]);
658 wa[2] += (eigv[2] * EigThreshold - eigv[0]);
659 wa[5] += (eigv[2] * EigThreshold - eigv[0]);
660 }
661 }else{
662 vkGetEigVal(vk->wa, eigv, 3);
663 wa[0] += eigv[2] * 1.e-12; //Permanent addition works better than addition
664 wa[2] += eigv[2] * 1.e-12; // for small eigenvalues only.
665 wa[5] += eigv[2] * 1.e-12;
666 vk->wa[0] += eigv[2] * 1.e-12; //Permanent addition works better than addition
667 vk->wa[2] += eigv[2] * 1.e-12; // for small eigenvalues only.
668 vk->wa[5] += eigv[2] * 1.e-12;
669 }
670 }
671
672 /* covariance matrix on vertex coordinates */
673 for(ii=0; ii<6; ii++) {if(std::isnan(wa[ii])) return -2;} // Matrix inversion failed
674 if(wa[0]<0 || wa[2]<0 || wa[5]<0) return -2; // Matrix elements must be positive!
675 IERR=cfdinv(wa, &(vk->fitVcov[0]), -3);
676 if (IERR) {IERR=cfdinv(wa, &(vk->fitVcov[0]), 3);} // last safety
677 if ( !vk->passNearVertex ) { if (IERR) return IERR; } // If nothing helps - detect failure (not for passNearVertex!!!)
678 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;}
679
680 /* corrections to vertex coordinates */
681 dxyz[0] = vk->fitVcov[0]*tv[0] + vk->fitVcov[1]*tv[1] + vk->fitVcov[3]*tv[2];
682 dxyz[1] = vk->fitVcov[1]*tv[0] + vk->fitVcov[2]*tv[1] + vk->fitVcov[4]*tv[2];
683 dxyz[2] = vk->fitVcov[3]*tv[0] + vk->fitVcov[4]*tv[1] + vk->fitVcov[5]*tv[2];
684 for (j = 0; j < 3; ++j) {
685 vk->dxyz0[j] = dxyz[j];
686 vk->fitV[j] = xyzf[j] = vk->iniV[j] + dxyz[j];
687 }
688 //std::cout<< "NVertex Old="<<vk->iniV[0]<<", "<<vk->iniV[1]<<", "<<vk->iniV[2]<<" CloseV="<<vk->passNearVertex<<'\n';
689 //std::cout<<__func__<<":NVertex shift="<<dxyz[0]<<", "<<dxyz[1]<<", "<<dxyz[2]<<'\n';
690
691
692
693
694
695 /*-----------------------------------------------------------*/
696 /* corrections to track parameters and covariance matrices */
697
698 for (kt = 0; kt < NTRK; ++kt) { /* variation on PAR is WCI * TT - (WBCI)t * DXYZ */
699 for( int tpn=0; tpn<9; tpn++){
700 if(tpn<6)twci[tpn] = vk->tmpArr[kt]->wci[tpn];
701 twbci[tpn] = vk->tmpArr[kt]->wbci[tpn];
702 }
703 double tt1=vk->tmpArr[kt]->tt[0];
704 double tt2=vk->tmpArr[kt]->tt[1];
705 double tt3=vk->tmpArr[kt]->tt[2];
706 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];
707 if( !std::isfinite(vk->tmpArr[kt]->parf0[0]) ) return -19; // Rare FPE presumably seen in trigger
708 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];
709 if( !std::isfinite(vk->tmpArr[kt]->parf0[1]) ) return -19; // Rare FPE presumably seen in trigger
710 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];
711 if( !std::isfinite(vk->tmpArr[kt]->parf0[2]) ) return -19; // Rare FPE presumably seen in trigger
712 if( (vk->TrackList[kt]->iniP[2] + vk->tmpArr[kt]->parf0[2]) * vk->TrackList[kt]->iniP[2] < 0 ){
713 vk->tmpArr[kt]->parf0[2]= - vk->TrackList[kt]->iniP[2]/4.; } // VK 15.12.2009 - Protection against change of sign
714 vk->TrackList[kt]->fitP[0] = vk->TrackList[kt]->iniP[0] + vk->tmpArr[kt]->parf0[0];
715 vk->TrackList[kt]->fitP[1] = vk->TrackList[kt]->iniP[1] + vk->tmpArr[kt]->parf0[1];
716 vk->TrackList[kt]->fitP[2] = vk->TrackList[kt]->iniP[2] + vk->tmpArr[kt]->parf0[2];
717 //std::cout<<__func__<<":NTrack shift="<<vk->tmpArr[kt]->parf0[0]<<", "<<vk->tmpArr[kt]->parf0[1]<<", "
718 // <<vk->tmpArr[kt]->parf0[2]<<'\n';
719 }
720 /* ------------------------------------------------------------ */
721 /* The same solution but through full matrix */
722 /* ------------------------------------------------------------ */
723 if ( vk->passNearVertex ) {
724 //std::cout <<" Std="<<vk->dxyz0[0]<<", "<<vk->dxyz0[1]<<", "<<vk->dxyz0[2]<<'\n';
725 stv[0] = stv[0] - drdvy[0][0] * vk->FVC.rv0[0] - drdvy[1][0] * vk->FVC.rv0[1];
726 stv[1] = stv[1] - drdvy[0][1] * vk->FVC.rv0[0] - drdvy[1][1] * vk->FVC.rv0[1];
727 stv[2] = stv[2] - drdvy[0][2] * vk->FVC.rv0[0] - drdvy[1][2] * vk->FVC.rv0[1];
728 //Save T vector(see Billoir...)
729 vk->T[0]=stv[0];vk->T[1]=stv[1];vk->T[2]=stv[2];
730 //
731 vk->wa[0] += vyv[0][0];
732 vk->wa[1] += vyv[1][0];
733 vk->wa[2] += vyv[1][1];
734 vk->wa[3] += vyv[2][0];
735 vk->wa[4] += vyv[2][1];
736 vk->wa[5] += vyv[2][2];
737 FullMTXfill(vk, vk->ader);
738 if ( vk->passNearVertex ) {
739 for (it = 1; it <= NTRK; ++it) {
740 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];
741 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];
742 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];
743 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];
744 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];
745 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];
746 for (jt = 1; jt <= NTRK; ++jt) { /* Matrix */
747 for (k = 0; k < 3; ++k) {
748 for (l = 0; l < 3; ++l) {
749 dpipj[k][l] = 0.;
750 for (j = 0; j < 2; ++j) {
751 dpipj[k][l] += vk->tmpArr[jt-1]->drdp[j][k] * drdpy[j][l];
752 }
753 }
754 }
755 for (k = 1; k <= 3; ++k) {
756 for (l = 1; l <= 3; ++l) {
757 ader_ref(it * 3 + k, jt * 3 + l) += dpipj[l-1][k-1];
758 }
759 }
760 }
761 }
762 }
763 //VK 27-Sep-2006 Add eigenvalue limitation for 7,8,9,10,13,14 constraints
764 double ArrTmp[9]; int ktmp=0;
765 for (k=1; k<=3; ++k) {
766 for (l=1; l<=k; ++l) { ArrTmp[ktmp++] = ader_ref(k,l); }}
767 vkGetEigVal(ArrTmp, eigv, 3);
768 double EigAddon=0.;
769 if( eigv[0]<0 ){EigAddon=eigv[0];}
770 for (k = 1; k <=3; ++k) {
771 ader_ref(k,k) = ader_ref(k,k) - EigAddon + eigv[2] * 1.e-18 ;
772 }
773 //----------------------------------------------------------------------------------
774 long int NParam = NTRK*3 + 3;
775 dsinv(NParam, vk->ader, vkalNTrkM*3+3, &IERR);
776 if ( IERR) return IERR;
777 double *fortst = new double[vkalNTrkM*3+3];
778 for (j = 0; j < 3; ++j) {
779 fortst[j] = stv[j];
780 for (ii=0; ii<NTRK; ++ii) { fortst[ii*3 +3 +j] = vk->tmpArr[ii]->tt[j];}
781 }
782 for (j=0; j<3; ++j) {
783 dxyz[j] = 0.;
784 for (ii=0; ii<NParam; ++ii) {dxyz[j] += ader_ref(j+1, ii+1) * fortst[ii];}
785 vk->dxyz0[j] = dxyz [j];
786 vk->fitV[j] = vk->iniV[j] + dxyz[j];
787 }
788 double tparf0[3]={0.};
789 for (it = 1; it <= NTRK; ++it) {
790 TWRK* t_trk=vk->tmpArr[it-1].get();
791 for (j=0; j<3; ++j) {
792 tparf0[j] = 0.;
793 for (ii = 1; ii <= NParam; ++ii) { tparf0[j] += ader_ref(it*3+j+1, ii)*fortst[ii-1];}
794 }
795 for (j=0; j<3; ++j) { t_trk->parf0[j] = tparf0[j];
796 vk->TrackList[it-1]->fitP[j] = vk->TrackList[it-1]->iniP[j] + tparf0[j];}
797 }
798 vk->fitVcov[0] = ader_ref(1, 1);
799 vk->fitVcov[1] = ader_ref(2, 1);
800 vk->fitVcov[2] = ader_ref(2, 2);
801 vk->fitVcov[3] = ader_ref(3, 1);
802 vk->fitVcov[4] = ader_ref(3, 2);
803 vk->fitVcov[5] = ader_ref(3, 3);
804 delete[] fortst;
805
806 //std::cout<< "NVertex Full="<<vk->fitV[0]<<", "<<vk->fitV[1]<<", "<<vk->fitV[2]<<'\n';
807 //std::cout<< "NVertex Full shft="<<dxyz[0]<<", "<<dxyz[1]<<", "<<dxyz[2]<<'\n';
808 //double *tmpA=new double[3+3*NTRK+20];
809 //IERR = FullMCNSTfill( vk, vk->ader, tmpA);
810 //delete[] tmpA;
811 }
812 /* ------------------------------------------------------------ */
813 /* End of the solution with full matrix */
814 /* */
815 /* Now constraints */
816 /* ------------------------------------------------------------ */
817 double dCoefNorm = 0;
818 if ( !vk->ConstraintList.empty()) {
819 IERR = vtcfitc( vk );
820 if (IERR != 0) return IERR;
826 double* tmpB=new double[3+3*NTRK]; double* tmpA=new double[3+3*NTRK];
827 for (ii=0; ii<3; ++ii) {
828 tmpA[ii] = vk->fitV[ii] - vk->iniV[ii];
829 tmpB[ii] = vk->dxyz0[ii];
830 }
831 for ( it=0; it<NTRK; ++it) {
832 tmpA[0 +3*it+3] = vk->TrackList[it]->fitP[0] - vk->TrackList[it]->iniP[0];
833 tmpA[1 +3*it+3] = vk->TrackList[it]->fitP[1] - vk->TrackList[it]->iniP[1];
834 tmpA[2 +3*it+3] = vk->TrackList[it]->fitP[2] - vk->TrackList[it]->iniP[2];
835 tmpB[0 +3*it+3] = vk->tmpArr[it]->parf0[0];
836 tmpB[1 +3*it+3] = vk->tmpArr[it]->parf0[1];
837 tmpB[2 +3*it+3] = vk->tmpArr[it]->parf0[2];
838 }
839 double scalAA=0., scalAB=0.;
840 for (ii=0; ii<3+3*NTRK; ii++) scalAA += tmpA[ii]*tmpA[ii];
841 for (ii=0; ii<3+3*NTRK; ii++) scalAB += tmpA[ii]*tmpB[ii];
842 if(scalAB != 0.) dCoefNorm = -scalAA/scalAB;
843 //double scalCC;
844 //for (ii=0; ii<3+3*NTRK; ii++) scalCC += (tmpA[ii]+dCoefNorm*tmpB[ii])*(tmpA[ii]+dCoefNorm*tmpB[ii]); // Length of perp vector
845 delete[] tmpA; delete[] tmpB;
846
847 //std::cout<<"VRTOLD="<<vk->fitV[0] - vk->iniV[0]<<", "<<vk->fitV[1] - vk->iniV[1]<<", "
848 // <<vk->fitV[2] - vk->iniV[2]<<'\n';
849 //for ( it=0; it<NTRK; ++it) std::cout<<"TRKOLD="<<vk->TrackList[it]->fitP[0] - vk->TrackList[it]->iniP[0]<<", "
850 // <<vk->TrackList[it]->fitP[1] - vk->TrackList[it]->iniP[1]<<", "
851 // <<vk->TrackList[it]->fitP[2] - vk->TrackList[it]->iniP[2]<<'\n';
852 //tmpA=new double[3+3*NTRK+20];
853 //IERR = FullMCNSTfill( vk, vk->ader, tmpA);
854 //delete[] tmpA;
855 }
856
857 /* chi2 with fitted values */
858
859 for (it = 0; it < NTRK; ++it) { //Check if curvature sign is changed or change in Pt is too big
860 if(vk->TrackList[it]->Id >= 0){
861 double Ratio=vk->TrackList[it]->fitP[2]/vk->TrackList[it]->Perig[4]; if(std::abs(Ratio)<1.)Ratio=1./Ratio;
862 if(Ratio<0. || Ratio > vkalAllowedPtChange ){
863 if(std::abs(vk->TrackList[it]->fitP[2])<std::abs(vk->TrackList[it]->Perig[4]) || Ratio<0 ){
864 vk->TrackList[it]->fitP[2]=vk->TrackList[it]->Perig[4]/vkalAllowedPtChange;
865 }else{
866 vk->TrackList[it]->fitP[2]=vk->TrackList[it]->Perig[4]*vkalAllowedPtChange;
867 }
868 }
869 }
870 }
871 //--Additional iterations along shift direction
872 bool improved=makePostFit( vk , wgtvrtd, dCoefNorm);
873 if(!improved)improved=makePostFit( vk , wgtvrtd, dCoefNorm); //Step truncation doesn't help. Make second pass
874 if(!improved)vk->truncatedStep=true;
875
876 //-- If no additional iterations (for tests)
877 //makeNoPostFit( vk , wgtvrtd, dCoefNorm);
878
879
880 return 0;
881
882}
883
884} //End of namespace Trk
885
#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 *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