ATLAS Offline Software
VtCFit.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3  */
4 
10 #include "TrkVKalVrtCore/VtCFitC.h"
11 #include "TrkVKalVrtCore/Matrix.h"
12 #include "TrkVKalVrtCore/FullMtx.h"
13 #include "TrkVKalVrtCore/ForCFT.h"
15 #include <algorithm>
16 #include <cmath>
17 
18 namespace {
19 //internal methods
20 
21 using namespace Trk;
22 double 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 //--------------------------------------------------------------------------
57 double 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]]
77 void 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  }
92  applyConstraints(vk);
93  }
94 }
95 
96 bool 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
137  applyConstraints(vk);
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
221  applyConstraints(vk);
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  }
246  applyConstraints(vk);
247  }
248 
249  if (alf == alfLowLim)
250  return false; // Truncated step
251  return true;
252 }
253 
254 } // namespace
255 
256 namespace 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 
293 int 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  for ( kt = 0; kt < NTRK; ++kt) {
390  VKTrack* trk = vk->TrackList[kt].get();
391  double theta_ini =trk->iniP[0];
392  double phi_ini =trk->iniP[1];
393  double invR_ini =trk->iniP[2];
394  /* "perigee" parameters EPS and ZP if the trajectory goes through XYZ */
395  /* and its theta,phi,1/R at perigee are equal to the values at input*/
396  double cotth = 1. / tan( theta_ini ); /* theta at vertex */
397  double cosf = cos(phi_ini);
398  double sinf = sin(phi_ini);
399  double uu = xyz[0]*cosf + xyz[1]*sinf;
400  double vv = xyz[1]*cosf - xyz[0]*sinf;
401  double phip,zp,eps;
402  if ( trk->Charge ) {
403  eps = -vv - uu*uu * invR_ini / 2.;
404  zp = -uu * (1. - vv * invR_ini) * cotth; //xyz[2] is added later to gain precision
405  phip = -uu * invR_ini; //phi_ini is added later to gain precision
406  } else {
407  eps = -vv;
408  zp = -uu * cotth;
409  phip = 0.;
410  }
411 
412  /* contribution of this track to chi2 with initial values */
413 
414  deps[kt] = trk->a0() - eps;
415  dzp[kt] = trk->z() - xyz[2]; // Precision
416  dzp[kt]-= zp;
417  dtet[kt] = trk->theta() - theta_ini;
418  dphi[kt] = trk->phi() - phi_ini; // Precision
419  dphi[kt]-= phip;
420  drho[kt] = trk->invR() - invR_ini;
421  while(dphi[kt] > M_PI)dphi[kt]-=2.*M_PI;
422  while(dphi[kt] < -M_PI)dphi[kt]+=2.*M_PI;
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);
429  double d22 = -sinf * cotth + ( (vv*sinf+uu*cosf)*cotth *invR_ini);
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;
481  double e23 = uu*vv*cotth;
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 
Trk::finter
double finter(double y0, double y1, double y2, double x0, double x1, double x2)
Definition: Tracking/TrkVertexFitter/TrkVKalVrtCore/src/Utilities.cxx:128
Trk::VKTrack::cnstP
double cnstP[3]
Definition: TrkVKalVrtCoreBase.h:80
CommonPars.h
Trk::VKTrack::WgtM
double WgtM[15]
Definition: TrkVKalVrtCoreBase.h:87
Trk::TWRK::parf0
double parf0[3]
Definition: TrkVKalVrtCoreBase.h:56
Trk::TWRK::tt
double tt[3]
Definition: TrkVKalVrtCoreBase.h:50
stCnst.h
Trk::cfVrtDstSig
double cfVrtDstSig(VKVertex *vk, bool UseTrkErr)
Definition: cfVrtDst.cxx:33
max
#define max(a, b)
Definition: cfImp.cxx:41
Trk::FullMTXfill
void FullMTXfill(VKVertex *vk, double *ader)
Definition: FullMtx.cxx:19
ader_ref
#define ader_ref(a_1, a_2)
Trk::VKVertex::tmpArr
std::vector< std::unique_ptr< TWRK > > tmpArr
Definition: TrkVKalVrtCoreBase.h:168
cfVrtDst.h
VtCFitC.h
Trk::TWRK
Definition: TrkVKalVrtCoreBase.h:44
Trk::VKVertex::T
double T[3]
Definition: TrkVKalVrtCoreBase.h:163
Trk::TWRK::part
double part[3]
Definition: TrkVKalVrtCoreBase.h:57
Trk::VKTrack::Chi2
double Chi2
Definition: TrkVKalVrtCoreBase.h:77
skel.it
it
Definition: skel.GENtoEVGEN.py:396
Trk::VKVertex::useApriorVertex
int useApriorVertex
Definition: TrkVKalVrtCoreBase.h:151
Trk::vtcfit
int vtcfit(VKVertex *vk)
Definition: VtCFit.cxx:293
M_PI
#define M_PI
Definition: ActiveFraction.h:11
Trk::VKVertex::FVC
ForVrtClose FVC
Definition: TrkVKalVrtCoreBase.h:160
xyz
#define xyz
dq_defect_virtual_defect_validation.d1
d1
Definition: dq_defect_virtual_defect_validation.py:79
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:158
Trk::VKVertex::refIterV
double refIterV[3]
Definition: TrkVKalVrtCoreBase.h:146
Trk::applyConstraints
void applyConstraints(VKVertex *vk)
Definition: stCnst.cxx:22
ParticleJetParams::kt
@ kt
Definition: ParticleJetParamDefs.h:43
Trk::VKTrack
Definition: TrkVKalVrtCoreBase.h:64
Trk::VKTrack::Charge
int Charge
Definition: TrkVKalVrtCoreBase.h:73
Trk::VKVertex::ader
double ader[(3 *vkalNTrkM+3) *(3 *vkalNTrkM+3)]
Definition: TrkVKalVrtCoreBase.h:188
drawFromPickle.cos
cos
Definition: drawFromPickle.py:36
Trk::vtcfitc
int vtcfitc(VKVertex *vk)
Definition: VtCFitC.cxx:16
Trk::VKVertex::apriorV
double apriorV[3]
Definition: TrkVKalVrtCoreBase.h:152
Trk::VKTrack::z
double z() const
Definition: TrkVKalVrtCoreBase.h:103
Trk::cfdinv
int cfdinv(double *cov, double *wgt, long int NI)
Definition: Tracking/TrkVertexFitter/TrkVKalVrtCore/src/Matrix.cxx:497
Trk::VKVertex::ConstraintList
std::vector< std::unique_ptr< VKConstraintBase > > ConstraintList
Definition: TrkVKalVrtCoreBase.h:169
Trk::ForVrtClose::rv0
double rv0[2]
Definition: ForVrtClose.h:29
Trk::VKVertex::apriorVWGT
double apriorVWGT[6]
Definition: TrkVKalVrtCoreBase.h:153
Trk::VKTrack::fitP
double fitP[3]
Definition: TrkVKalVrtCoreBase.h:76
TrkVKalVrtCoreBase.h
Trk::VKVertex::TrackList
std::vector< std::unique_ptr< VKTrack > > TrackList
Definition: TrkVKalVrtCoreBase.h:167
Trk::VKTrack::a0
double a0() const
Definition: TrkVKalVrtCoreBase.h:102
Trk::VKVertex::fitV
double fitV[3]
Definition: TrkVKalVrtCoreBase.h:140
lumiFormat.i
int i
Definition: lumiFormat.py:85
Trk::dsinv
void dsinv(long int n, double *a, long int DIM, long int *ifail) noexcept
Definition: Tracking/TrkVertexFitter/TrkVKalVrtCore/src/Matrix.cxx:517
Trk::VKTrack::invR
double invR() const
Definition: TrkVKalVrtCoreBase.h:106
Matrix.h
Trk::vkGetEigVal
void vkGetEigVal(const double ci[], double d[], int n)
Definition: Tracking/TrkVertexFitter/TrkVKalVrtCore/src/Matrix.cxx:828
Trk::VKVertex::passNearVertex
bool passNearVertex
Definition: TrkVKalVrtCoreBase.h:156
cvder_ref
#define cvder_ref(a_1, a_2)
drawFromPickle.tan
tan
Definition: drawFromPickle.py:36
Trk::VKVertex::fitVcov
double fitVcov[6]
Definition: TrkVKalVrtCoreBase.h:141
grepfile.ic
int ic
Definition: grepfile.py:33
Trk
Ensure that the ATLAS eigen extensions are properly loaded.
Definition: FakeTrackBuilder.h:9
Trk::TWRK::drdp
double drdp[2][3]
Definition: TrkVKalVrtCoreBase.h:55
vkalNTrkM
#define vkalNTrkM
Definition: CommonPars.h:22
Trk::VKTrack::phi
double phi() const
Definition: TrkVKalVrtCoreBase.h:105
Trk::getCnstValues2
double getCnstValues2(VKVertex *vk) noexcept
Definition: VtCFitC.cxx:244
Trk::VKVertex::setCnstV
void setCnstV(double v[3]) noexcept
Definition: TrkVKalVrtCoreBase.cxx:151
xyzt
#define xyzt
dq_defect_virtual_defect_validation.d2
d2
Definition: dq_defect_virtual_defect_validation.py:81
Trk::VKVertex::Chi2
double Chi2
Definition: TrkVKalVrtCoreBase.h:139
Trk::ForVrtClose::ywgt
double ywgt[3]
Definition: ForVrtClose.h:29
Trk::cfchi2
double cfchi2(double *xyzt, const long int ich, double *part, const double *par0, double *wgt, double *rmnd)
Definition: Tracking/TrkVertexFitter/TrkVKalVrtCore/src/Utilities.cxx:27
Trk::VKVertex::wa
double wa[6]
Definition: TrkVKalVrtCoreBase.h:164
Trk::VKVertex::dxyz0
double dxyz0[3]
Definition: TrkVKalVrtCoreBase.h:165
Trk::VKVertex
Definition: TrkVKalVrtCoreBase.h:128
Trk::VKVertex::iniV
double iniV[3]
Definition: TrkVKalVrtCoreBase.h:142
Trk::VKTrack::iniP
double iniP[3]
Definition: TrkVKalVrtCoreBase.h:83
VtCFit.h
drawFromPickle.sin
sin
Definition: drawFromPickle.py:36
Trk::VKTrack::theta
double theta() const
Definition: TrkVKalVrtCoreBase.h:104
FullMtx.h
Utilities.h
PlotCalibFromCool.vv
vv
Definition: PlotCalibFromCool.py:716
Trk::VKVertex::passWithTrkCov
bool passWithTrkCov
Definition: TrkVKalVrtCoreBase.h:157
ForCFT.h
dcv_ref
#define dcv_ref(a_1, a_2)
Trk::VKVertex::truncatedStep
bool truncatedStep
Definition: TrkVKalVrtCoreBase.h:185
vkalAllowedPtChange
#define vkalAllowedPtChange
Definition: CommonPars.h:25
fitman.k
k
Definition: fitman.py:528