ATLAS Offline Software
CFit.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 #include "TrkVKalVrtCore/CFit.h"
10 #include "TrkVKalVrtCore/VtDeriv.h"
11 #include "TrkVKalVrtCore/Matrix.h"
12 #include "TrkVKalVrtCore/VtCFit.h"
13 #include "TrkVKalVrtCore/stCnst.h"
15 #include "TrkVKalVrtCore/RobTest.h"
21 #include <array>
22 #include <cmath>
23 #include <iostream>
24 
25 /*----------------------------------------------------------------------------*/
26 /* CONSTRAINT VERTEX FIT: */
27 /* INPUT : */
28 /* IFLAG : what to do */
29 /* 0 - simple vertex fit */
30 /* 1 - fit with mass constraint */
31 /* 2 - fit with constraint on passing through vertex VRT*/
32 /* 3 - fit with Z-constraint */
33 /* 4 - 1+2 */
34 /* 5 - 1+3 */
35 /* 6 - fit with primary vertex constraint */
36 /* 7 - fit with summary vector close to given vertex */
37 /* 8 - 1+7 */
38 /* 9 - like 7 but summary track error is not used */
39 /* 10 - like 8 but summary track error is not used */
40 /* 11 - Phi angle between track is 0 */
41 /* 12 - Phi and Theta angles between track are 0 */
42 /* 13 - 11+7 */
43 /* 14 - 12+7 */
44 /* IFCOVV0 : =0 only vertex error matrix(6) is returned */
45 /* >0 full V0 x,p error matrix(21) is returned */
46 /* (calculations are CPU consuming in case of */
47 /* constraints 1:5 with big track number) */
48 /* NTRK : number of tracks */
49 /* ICH(JTK) : charge of tracks */
50 /* XYZ0(3) : starting point */
51 /* PAR0(3,JTK) : tracks parameters in XYZ */
52 /* APAR(5,JTK) : measured tracks parameters */
53 /* AWGT(15,JTK): tracks parameter errors */
54 /* OUTPUT: XYZFIT(3) : fitted sec. vertex */
55 /* PARFS(3,JTK): th,phi,1/r of tracks at vertex */
56 /* PTOT(3) : total momentum in vertex */
57 /* COVF(21) : covariance matrix (x,y,z,ptot(3)) */
58 /* CHI2 : total chi-squared */
59 /* CHI2TR(JTK) : chi-squared per track */
60 /* IERR : error flag */
61 /* -1 bad fit chi2>1000000 ( no fitted output) */
62 /* -2 fit is ready but without covariance matrix */
63 /* -3 no fit at all */
64 /* -4 noninvertible vert.error matrix for IFLAG=6 */
65 /* -5 Divergence of iterations */
66 /* Author: V.Kostyukhin ( 1996 ) */
67 /*----------------------------------------------------------------------------*/
68 
69 
70 namespace{
71 using namespace Trk;
72 // Functions only used internally in this module for the implementation
73 // of the external modules go to the anonymous namespace.
74 // They have internal linkage.
75 
76 // New data model for cascade fit
77 void fillVertex(VKVertex *vk, int NTRK, const long int *ich,
78  double xyz0[3], double (*par0)[3], double (*inp_Trk5)[5],
79  double (*inp_CovTrk5)[15]) {
80 
81 
82  ForCFT &vrtForCFT = vk->vk_fitterControl->vk_forcft;
83  double xyz[3] = {0., 0., 0.}; // Perigee point
84  //
85  // VK 13.01.2009 New strategy with ref.point left at initial position
86  vk->setRefV(xyz); // ref point
87  vk->setRefIterV(xyz0); // iteration ref. point
88  vk->tmpArr.resize(NTRK);
89  vk->TrackList.resize(NTRK);
90  for (int tk = 0; tk < NTRK; tk++) {
91  long int TrkID = tk;
92  vk->TrackList[tk] = std::make_unique<VKTrack>(
93  TrkID, &inp_Trk5[tk][0], &inp_CovTrk5[tk][0], vk, vrtForCFT.wm[tk]);
94  //printT(&inp_Trk5[tk][0], &inp_CovTrk5[tk][0] , "Input track:");
95  //std::cout<<(*vk->TrackList[tk]);
96  vk->tmpArr[tk]= std::make_unique< TWRK > ();
97  vk->TrackList[tk]->Charge = ich[tk]; // Charge coinsides with sign of curvature
98  }
99 
100  vk->FVC.Charge = 0; for (int tk=0; tk<NTRK; ++tk)vk->FVC.Charge += ich[tk]; // summary charge
101  cfdcopy(vrtForCFT.vrt, vk->FVC.vrt , 3);
102  cfdcopy(vrtForCFT.covvrt, vk->FVC.covvrt , 6);
103 
104  /* --------------------------------------------------------*/
105  /* Initial value */
106  /* --------------------------------------------------------*/
107  for(int tk=0; tk<NTRK; tk++){
108  VKTrack *trk = vk->TrackList[tk].get();
109  trk->iniP[0]=trk->cnstP[0]=trk->fitP[0]=par0[tk][0]; //initial guess
110  trk->iniP[1]=trk->cnstP[1]=trk->fitP[1]=par0[tk][1];
111  trk->iniP[2]=trk->cnstP[2]=trk->fitP[2]=par0[tk][2];
112  }
113  vk->setIniV(xyz); vk->setCnstV(xyz);
114 }
115 
116 bool checkPosition(VKVertex *vk, double vertex[3]) {
117  bool insideGoodVolume = true;
118  if (vk->vk_fitterControl && vk->vk_fitterControl->vk_objProp) {
119  insideGoodVolume = vk->vk_fitterControl->vk_objProp->checkTarget(
120  vertex, *vk->vk_fitterControl->vk_istate);
121  } else {
122  insideGoodVolume = Trk::vkalPropagator::checkTarget(vertex);
123  }
124  return insideGoodVolume;
125 }
126 
127 void protectCurvatureSign(
128  double ini, double cur,
129  double *Wgt) { // VK 15.12.2009 Protection against sign change
130  double x = cur / ini;
131  if (x >= 0.7)
132  return;
133  if (x <= 0.)
134  return;
135  Wgt[14] *= (0.7 * 0.7) / (x * x);
136 }
137 
138 int fitVertex(VKVertex * vk)
139 {
140  int i, jerr, tk, it=0;
141 
142  double dparst[6];
143  double chi2min, chi21s=11., chi22s=10., vShift;
144  double aermd[6],tmpd[6]={0.}; // temporary arrays
145  double tmpPer[5],tmpCov[15], tmpWgt[15];
146  double VrtMomCov[21],PartMom[4];
147  double cnstRemnants=0., iniCnstRem=1.e-12;
148  double newVrtXYZ[3];
149 
150  const double ConstraintAccuracy=1.e-6;
151 
152  //
153  // New datastructure
154 
155  long int IERR = 0;
156  /* Type of the constraint for the fit */
157  int NTRK = vk->TrackList.size();
158  ForCFT& vrtForCFT=vk->vk_fitterControl->vk_forcft;
159  vk->passNearVertex=false; //explicit setting - not to use
160  vk->passWithTrkCov=false; //explicit setting - not to use
161  if ( vrtForCFT.usePassNear ) vk->passNearVertex=true;
162  if ( vrtForCFT.usePassNear==2 ) vk->passWithTrkCov=true;
163  double zeroV[3]={0.,0.,0.};
164  VKTrack * trk=nullptr;
165 
166  chi2min = 1e15;
167 
168  if( vrtForCFT.nmcnst && vrtForCFT.useMassCnst ) { //mass constraints are present
169  std::vector<int> index;
170  for( int ic=0; ic<vkalMaxNMassCnst; ic++){
171  if(vrtForCFT.wmfit[ic]>0){ // new mass constraint
172  index.clear();
173  for(tk=0; tk<NTRK; tk++){ if( vrtForCFT.indtrkmc[ic][tk] )index.push_back(tk); }
174  vk->ConstraintList.emplace_back(std::make_unique<VKMassConstraint>( NTRK, vrtForCFT.wmfit[ic], std::move(index), vk));
175  }
176  }
177  }
178  if( vrtForCFT.usePointingCnst==1 ){ //3Dpointing
179  vk->ConstraintList.emplace_back(std::make_unique<VKPointConstraint>( NTRK, vrtForCFT.vrt, vk, false));
180  }
181  if( vrtForCFT.usePointingCnst==2 ){ //Z pointing
182  vk->ConstraintList.emplace_back(std::make_unique<VKPointConstraint>( NTRK, vrtForCFT.vrt, vk, true));
183  }
184  if ( vrtForCFT.useAprioriVrt ) {
185  cfdcopy(vrtForCFT.covvrt, tmpd, 6);
186  IERR=cfdinv(tmpd, aermd, -3); if (IERR) { IERR = -4; return IERR; }
187  vk->useApriorVertex = 1;
188  cfdcopy(vrtForCFT.vrt, vk->apriorV, 3);
189  cfdcopy( aermd, vk->apriorVWGT,6);
190  }
191  if ( vrtForCFT.usePhiCnst ) vk->ConstraintList.emplace_back(std::make_unique<VKPhiConstraint>( NTRK, vk));
192  if ( vrtForCFT.useThetaCnst )vk->ConstraintList.emplace_back(std::make_unique<VKThetaConstraint>( NTRK, vk));
193  if ( vrtForCFT.usePlaneCnst ){
194  if( vrtForCFT.Ap+vrtForCFT.Bp+vrtForCFT.Cp != 0.){
195  vk->ConstraintList.emplace_back(std::make_unique<VKPlaneConstraint>( NTRK, vrtForCFT.Ap, vrtForCFT.Bp, vrtForCFT.Cp, vrtForCFT.Dp, vk));
196  }
197  }
198  //-----Debug printout
199  // for(auto & cnst : vk->ConstraintList) {
200  // VKMassConstraint *ctmp=dynamic_cast<VKMassConstraint*>( cnst.get() ); if(ctmp) std::cout<<(*ctmp)<<'\n';
201  // VKPointConstraint *ptmp=dynamic_cast<VKPointConstraint*>( cnst.get() ); if(ptmp) std::cout<<(*ptmp)<<'\n';
202  // }
203  //
204  // Needed for track close to vertex constraint
205  for(i=0; i<2*6; i++)vk->FVC.cvder[i]=0.;
206  for(i=0; i<21; i++)vk->FVC.dcovf[i]=0.;
207  vk->FVC.dcovf[0]=10.;vk->FVC.dcovf[2] =10.;vk->FVC.dcovf[5] =10.;
208  vk->FVC.dcovf[9]=10.;vk->FVC.dcovf[14]=10.;vk->FVC.dcovf[20]=10.;
209 
210  /* --------------------------------------------------------*/
211  /* Initial value */
212  /* --------------------------------------------------------*/
213  cfdcopy(vk->refIterV,newVrtXYZ,3); // copy initial data to start values
214  vk->setIniV(zeroV);vk->setCnstV(zeroV); // initial guess. 0 of course.
215  /* ------------------------------------------------------------*/
216  /* MAIN FITTING CYCLE */
217  /* ------------------------------------------------------------*/
218  bool extrapolationDone=false;
219  bool forcedExtrapolation=false; //To force explicit extrapolation
220  std::vector< Vect3DF > savedExtrapVertices(vrtForCFT.IterationNumber);
221  double cnstRemnantsPrev=1.e20, Chi2Prev=0.; int countBadStep=0; // For consecutive bad steps
222 
223  for (it = 1; it <= vrtForCFT.IterationNumber; ++it) {
224  vShift = cfddist3D( newVrtXYZ, vk->refIterV ); // Extrapolation distance
225  savedExtrapVertices[it-1].Set(newVrtXYZ); // Save new position. Index [it] starts from 1 !!!
226  /* ---------------------------------------------------------------- */
227  /* Propagate parameters and errors to the point newVrtXYZ */
228  /* Also set up localBMAG at newVrtXYZ if nonuniform field is used */
229  /* ---------------------------------------------------------------- */
230  extrapolationDone=false;
231  bool insideGoodVolume=checkPosition(vk,newVrtXYZ);
232  if( vShift>vkalShiftToTrigExtrapolation || it==1 || forcedExtrapolation || !insideGoodVolume ){ //Propagation is needed
233  //--- Check whether propagation step must be truncated
234  if( forcedExtrapolation || vk->truncatedStep || !insideGoodVolume){
235  insideGoodVolume=false;
236  while( !insideGoodVolume ){ //check extrapolation and limit step if needed
237  newVrtXYZ[0]=(2.*savedExtrapVertices[it-1].X + savedExtrapVertices[it-2].X)/3.; //Use 2/3 of the initial distance
238  newVrtXYZ[1]=(2.*savedExtrapVertices[it-1].Y + savedExtrapVertices[it-2].Y)/3.; //for extrapolation
239  newVrtXYZ[2]=(2.*savedExtrapVertices[it-1].Z + savedExtrapVertices[it-2].Z)/3.;
240  savedExtrapVertices[it-1].Set(newVrtXYZ);
241  insideGoodVolume=checkPosition(vk,newVrtXYZ);
242  if(!insideGoodVolume && savedExtrapVertices[it-1].Dist3D(savedExtrapVertices[it-2])<5.) { return -11; }
243  } }
244  //------------------------------
245  extrapolationDone=true;
246  forcedExtrapolation=false;
247  double targV[3]={newVrtXYZ[0],newVrtXYZ[1],newVrtXYZ[2]}; //Temporary to avoid overwriting
248  for (tk = 0; tk < NTRK; ++tk) {
249  //std::cout<<__func__<<" propagate trk="<<tk<<" X,Y,Z="<<targV[0]<<","<<targV[1]<<","<<targV[2]<<'\n';
250  Trk::vkalPropagator::Propagate(vk->TrackList[tk].get(), vk->refV, targV, tmpPer, tmpCov, (vk->vk_fitterControl).get());
251  if(std::abs(tmpCov[14])<1.e-20 || std::isnan(tmpCov[14])) {return -7;} // Zero Q/p covariance. Stop fit and return failure
252  cfTrkCovarCorr(tmpCov);
253  double eig5=cfSmallEigenvalue(tmpCov,5 );
254  if(eig5>0 && eig5<1.e-15 ){
255  tmpCov[0]+=1.e-15; tmpCov[2]+=1.e-15; tmpCov[5]+=1.e-15; tmpCov[9]+=1.e-15; tmpCov[14]+=1.e-15;
256  }else if(tmpCov[0]>1.e9 || eig5<0.) { //Bad propagation with material. Try without it.
257  Trk::vkalPropagator::Propagate(-999, vk->TrackList[tk]->Charge, vk->TrackList[tk]->refPerig,vk->TrackList[tk]->refCovar,
258  vk->refV, targV, tmpPer, tmpCov, (vk->vk_fitterControl).get());
259 
260  if(cfSmallEigenvalue(tmpCov,5 )<1.e-15){ // Final protection. Zero non-diagonal terms
261  tmpCov[1]=0.;tmpCov[3]=0.;tmpCov[6]=0.;tmpCov[10]=0.; // and make positive diagonal ones
262  tmpCov[4]=0.;tmpCov[7]=0.;tmpCov[11]=0.;
263  tmpCov[8]=0.;tmpCov[12]=0.;
264  tmpCov[13]=0.;
265  tmpCov[0]=std::abs(tmpCov[0]); tmpCov[2]=std::abs(tmpCov[2]);tmpCov[5]=std::abs(tmpCov[5]);
266  tmpCov[9]=std::abs(tmpCov[9]); tmpCov[14]=std::abs(tmpCov[14]);
267  }
268  }
269  if(tmpCov[0]>1.e9){ IERR=-7; return IERR; } //extremely big A0 error !!!
270  jerr=cfInv5(tmpCov, tmpWgt);
271  if(jerr)jerr=cfdinv(tmpCov, tmpWgt,5);
272  if(jerr){ IERR=-7; return IERR; } //Nothing helps. Break fit.
273  vk->TrackList[tk]->setCurrent(tmpPer,tmpWgt);
274  }
275 //
276 /* Magnetic field in fitting point setting */
277  vk->setRefIterV(targV);
278  vrtForCFT.localbmag = Trk::vkalMagFld::getMagFld(vk->refIterV,(vk->vk_fitterControl).get());
279  vk->setIniV(zeroV);vk->setCnstV(zeroV); // initial guess with respect to refIterV[]. 0 after extrap.
280  }else{
281  vk->setIniV( vk->fitV ); vk->setCnstV( vk->fitV ); // use previous fitV[] as start position
282  for( tk=0; tk<NTRK; tk++) vk->TrackList[tk]->restoreCurrentWgt(); // restore matrix changed by ROBTEST!!!
283  }
284 /*-----------------------------------------------------------------------*/
285 /* All parameters are set in new vertex position. We are ready for fit */
286 /* Track WGT matrix is completely clean now */
287 /* - apply protection against charge sign change */
288 /*-----------------------------------------------------------------------*/
289  for (tk = 0; tk < NTRK; ++tk){
290  trk = vk->TrackList[tk].get(); protectCurvatureSign( trk->refPerig[4], trk->fitP[2] , trk->WgtM);
291  }
292 /*-------------------------------- Now the fit itself -----------------*/
293  if (vrtForCFT.irob != 0) {robtest(vk, 0, it);} // ROBUSTIFICATION new data structure
294  if (vrtForCFT.irob != 0) {robtest(vk, 1, it);} // ROBUSTIFICATION new data structure
295  for( tk=0; tk<NTRK; tk++){
296  trk = vk->TrackList[tk].get();
297  trk->iniP[0]=trk->cnstP[0]=trk->fitP[0]; //use fitted track parameters as initial guess
298  trk->iniP[1]=trk->cnstP[1]=trk->fitP[1];
299  trk->iniP[2]=trk->cnstP[2]=trk->fitP[2];
300  if(extrapolationDone)trk->iniP[2]=trk->cnstP[2]=trk->Perig[4]; //Use exact value here to take into account change of mag.field
301  }
302  applyConstraints( vk );
303  if(it==1) { bool bsave = vk->passNearVertex; vk->passNearVertex=false; IERR = vtcfit( vk ); vk->passNearVertex=bsave;}
304  else IERR = vtcfit( vk ); // In first iteration data for PassNearVertex constraint don't exist!!!
305  if (IERR) return IERR;
306  vShift = cfddist3D( vk->fitV, vk->iniV );
307 //----
308  if(extrapolationDone && chi21s*10.<vk->Chi2 && it>2 && vk->Chi2>NTRK*5.){ //Extrapolation produced huge degradation
309  double ddstep=savedExtrapVertices[it-1].Dist3D(savedExtrapVertices[it-2]);
310 //std::cout<<" Huge degradation due to extrapolation. Limit step! it="<<it<<" step="<<ddstep<<'\n';
311  if( ddstep > 5.*vkalShiftToTrigExtrapolation) {
312  forcedExtrapolation=true;
313  continue;
314  }
315  }
316  chi21s = vk->Chi2;
317  chi22s = chi21s * 1.01 + 10.; //for safety
318  if ( vShift < 10.*vkalShiftToTrigExtrapolation) { // REASONABLE DISPLACEMENT - RECALCULATE
319 /* ROBUSTIFICATION */
320  if (vrtForCFT.irob != 0) {robtest(vk, 1, it+1);} // ROBUSTIFICATION new data structure
321 //Reset mag.field
322  for( i=0; i<3; i++) dparst[i]=vk->refIterV[i]+vk->fitV[i]; // fitted vertex at global frame
323  vrtForCFT.localbmag=Trk::vkalMagFld::getMagFld(dparst,(vk->vk_fitterControl).get());
324  if ( vk->passNearVertex && it>1 ) { //No necessary information at first iteration
325  jerr = afterFit(vk, vk->ader, vk->FVC.dcv, PartMom, VrtMomCov, (vk->vk_fitterControl).get());
326  if(jerr!=0) return -17; // Non-invertable matrix for combined track
327  cfdcopy( PartMom, &dparst[3], 3); //vertex part of it is filled above
328  cfdcopy(VrtMomCov,vk->FVC.dcovf,21); //Used in chi2 caclulation later...
329  cfdcopy( PartMom, vk->fitMom, 3); //save Momentum
330  cfdcopy(VrtMomCov, vk->fitCovXYZMom, 21); //save XYZMom covariance
331  vpderiv(vk->passWithTrkCov, vk->FVC.Charge, dparst, VrtMomCov, vk->FVC.vrt, vk->FVC.covvrt,
332  vk->FVC.cvder, vk->FVC.ywgt, vk->FVC.rv0, (vk->vk_fitterControl).get());
333  }
334 
335  for( tk=0; tk<NTRK; tk++){
336  trk = vk->TrackList[tk].get();
337  trk->iniP[0]=trk->cnstP[0]=trk->fitP[0]; //use fitted track parameters as initial guess
338  trk->iniP[1]=trk->cnstP[1]=trk->fitP[1];
339  trk->iniP[2]=trk->cnstP[2]=trk->fitP[2];
340  }
341  vk->setIniV( vk->fitV ); vk->setCnstV( vk->fitV ); // use previous fitV[] as start position
342  applyConstraints( vk);
343  if(it==1) { bool bsave = vk->passNearVertex; vk->passNearVertex=false; IERR = vtcfit( vk ); vk->passNearVertex=bsave;}
344  else IERR = vtcfit( vk ); // In first iteration data for PassNearVertex constraint don't exist!!!
345  if ( IERR ) return IERR;
346  vShift = cfddist3D( vk->fitV, vk->iniV );
347  chi22s = vk->Chi2;
348  }
349 //
350 //
351  if (chi22s > 1e8) { return -1; } // TOO HIGH CHI2 - BAD FIT
352  if (chi22s != chi22s) { return -14; } // Chi2 == nan - BAD FIT
353  for( i=0; i<3; i++) newVrtXYZ[i] = vk->refIterV[i]+vk->fitV[i]; // fitted vertex in global frame
354  //std::cout.precision(11);
355  //std::cout<<"NNFIT Iter="<<it<<" Chi2ss="<< chi21s <<", "<<chi22s<<", "<<vShift<<'\n';
356  //std::cout<<"NNVertex="<<newVrtXYZ[0]<<", "<<newVrtXYZ[1]<<", "<<newVrtXYZ[2]<<'\n';
357  //std::cout<<"-----------------------------------------------"<<'\n';
358 /* Test of convergence */
359  double chi2df = std::abs(chi21s - chi22s);
360  /*---------------------Normal convergence--------------------*/
361  double PrecLimit = std::min(chi22s*1.e-4, vrtForCFT.IterationPrecision);
362 //std::cout<<"Convergence="<< chi2df <<"<"<<PrecLimit<<" cnst="<<cnstRemnants<<"<"<<ConstraintAccuracy<<'\n';
363  if( ( vk->vk_fitterControl->m_frozenVersionForBTagging && it>1 )
364  || (!vk->vk_fitterControl->m_frozenVersionForBTagging && (it>3||vrtForCFT.irob==0) ) ){
365  if((chi2df < PrecLimit) && (vShift < 0.001) && (cnstRemnants<ConstraintAccuracy)){
366  double dstFromExtrapPnt=sqrt(vk->fitV[0]*vk->fitV[0] + vk->fitV[1]*vk->fitV[1]+ vk->fitV[2]*vk->fitV[2]);
367  if( dstFromExtrapPnt>vkalShiftToTrigExtrapolation/2. && it < vrtForCFT.IterationNumber-15){
368  forcedExtrapolation=true;
369  continue; // Make another extrapolation exactly to found vertex position
370  }
371  break;
372  }
373  }
374  chi2min = std::min(chi2min,chi22s);
375  if ((chi2min*100. < chi22s) && (chi22s>std::max( (2*NTRK-3)*10., 100.)) && (it>5)){
376  //std::cout<<" DIVERGENCE="<<chi22s<<" Ratio="<<chi22s/chi2min<<'\n';
377  IERR = -5; return IERR; /* Divergence. Stop fit */
378  }
379 
380 // Track near vertex constraint recalculation for next fit
381  if ( vk->passNearVertex ) {
382  if(it==1) jerr = afterFit(vk, nullptr, vk->FVC.dcv, PartMom, VrtMomCov, (vk->vk_fitterControl).get());
383  else jerr = afterFit(vk, vk->ader, vk->FVC.dcv, PartMom, VrtMomCov, (vk->vk_fitterControl).get());
384  for( i=0; i<3; i++) dparst[i] = vk->refIterV[i]+vk->fitV[i]; // fitted vertex at global frame
385  cfdcopy( PartMom, &dparst[3], 3);
386  cfdcopy(VrtMomCov,vk->FVC.dcovf,21); //Used in chi2 caclulation later...
387  cfdcopy( PartMom, vk->fitMom, 3); //save Momentum
388  cfdcopy(VrtMomCov, vk->fitCovXYZMom, 21); //save XYZMom covariance
389  vpderiv(vk->passWithTrkCov, vk->FVC.Charge, dparst, VrtMomCov,
390  vk->FVC.vrt, vk->FVC.covvrt,
391  vk->FVC.cvder, vk->FVC.ywgt, vk->FVC.rv0, (vk->vk_fitterControl).get());
392  }
393 //
394 // Check constraints status
395 //
396  cnstRemnants=0. ;
397  for(int ii=0; ii<(int)vk->ConstraintList.size();ii++){
398  for(int ic=0; ic<(int)vk->ConstraintList[ii]->NCDim; ic++){
399  cnstRemnants += std::abs( vk->ConstraintList[ii]->aa[ic] ); } }
400  if(it==1){ if(cnstRemnants>0.){iniCnstRem=cnstRemnants;}else{iniCnstRem=1.e-12;} }
401  if(it==10){
402  if(cnstRemnants > 0.1 && cnstRemnants/iniCnstRem > 0.1 ){
403  IERR = -6; return IERR; /* Constraints are not resolved. Stop fit */
404  }
405  }
406 //
407 // Check consecutive bad steps in fitting
408 //
409  if(it>5 && ((cnstRemnants>cnstRemnantsPrev)||cnstRemnants==0.) && chi22s>(Chi2Prev*1.0001)){
410  if(++countBadStep>5) break; // Apparently further improvement is impossible
411  }else{countBadStep=0;}
412  Chi2Prev=chi22s; cnstRemnantsPrev=cnstRemnants;
413  }
414 /*--------------------------------------*/
415 /* End of cycling */
416 /* Now we have a secondary vertex xyzs */
417 /*--------------------------------------*/
418  if( cnstRemnants > ConstraintAccuracy ){
419  IERR = -6; return IERR; /* Constraints are not resolved. Bad fit */
420  }
421  return 0;
422 
423 }
424 //
425 } //end of anonymous
426 
427 
428 namespace Trk {
429 int CFit(VKalVrtControl *FitCONTROL, int ifCovV0, int NTRK,
430  long int *ich, double xyz0[3], double (*par0)[3],
431  double (*inp_Trk5)[5], double (*inp_CovTrk5)[15],
432  double xyzfit[3], double (*parfs)[3], double ptot[4],
433  double covf[21], double &chi2, double *chi2tr)
434 {
435 
436  std::fill_n(ptot,4,0.);
437  std::fill_n(covf,21,0.);
438  cfdcopy(xyz0,xyzfit,3);
439  FitCONTROL->renewFullCovariance(nullptr);
440 
441 //
442 // Create vertex
443 //
444  std::unique_ptr<VKVertex> MainVRT(new VKVertex(*FitCONTROL));
445  fillVertex(MainVRT.get(), NTRK, ich, xyz0, par0, inp_Trk5, inp_CovTrk5);
446 //
447 // Fit vertex
448 //
449  int IERR = fitVertex( MainVRT.get());
450  if(IERR) return IERR;
451 //
452 // if successful - save results
453 //
454  for(int i=0; i<3; i++) xyzfit[i] = MainVRT->refIterV[i]+MainVRT->fitV[i]; // fitted vertex in global frame
455  MainVRT->vk_fitterControl->vk_forcft.localbmag = Trk::vkalMagFld::getMagFld(xyzfit,(MainVRT->vk_fitterControl).get());
456  chi2 = 0.;
457  for (int tk = 0; tk < NTRK; tk++) {
458  VKTrack * trk = MainVRT->TrackList[tk].get();
459  chi2 += trk->Chi2;
460  chi2tr[tk] = trk->Chi2;
461  cfdcopy( trk->fitP, &parfs[tk][0], 3);
462  std::array<double, 4> pp = getFitParticleMom( trk, MainVRT->vk_fitterControl->vk_forcft.localbmag );
463  ptot[0]+=pp[0]; ptot[1]+=pp[1]; ptot[2]+=pp[2]; ptot[3]+=pp[3];
464  }
465  cfdcopy(MainVRT->fitVcov, covf , 6); //fitted vertex covariance
466  double vM2=(ptot[3]-ptot[2])*(ptot[3]+ptot[2]) - ptot[1]*ptot[1] - ptot[0]*ptot[0];
467  FitCONTROL->setVertexMass(std::sqrt(vM2>0. ? vM2 : 0. ) );
468  FitCONTROL->setVrtMassError(0.);
469 //
470 // If required - get full covariance matrix
471 //
472  if(ifCovV0){
473  double dptot[5], VrtMomCov[21];
474  IERR = afterFit(MainVRT.get(), MainVRT->ader, MainVRT->FVC.dcv, dptot, VrtMomCov, (MainVRT->vk_fitterControl).get());
475  if (IERR) return -2; /* NONINVERTIBLE COV.MATRIX */
476  if(MainVRT->existFullCov){
477  FitCONTROL->renewFullCovariance(new double[ (3*NTRK+3)*(3*NTRK+3+1)/2 ]);
478  int out=0;
479  for(int ti=0; ti<3+3*NTRK; ti++){
480  for(int tj=0; tj<=ti; tj++){
481  FitCONTROL->getFullCovariance()[out] = ARR2D_FS(MainVRT->ader, 3*vkalNTrkM+3, ti, tj);
482  out++;
483  } }
484  int activeTrk[vkalNTrkM]={0}; std::fill_n(activeTrk,NTRK,1);
485  double vrtMass=0., vrtMassError=0.;
486  cfmasserr(MainVRT.get(), activeTrk,MainVRT->vk_fitterControl->vk_forcft.localbmag, &vrtMass, &vrtMassError);
487  FitCONTROL->setVertexMass(vrtMass);
488  FitCONTROL->setVrtMassError(vrtMassError);
489  }
490  cfdcopy( VrtMomCov, covf, 21); //XvYvZvPxPyPz covariance
491  cfdcopy( MainVRT->vk_fitterControl->vk_forcft.robres, FitCONTROL->vk_forcft.robres, NTRK); //Track weights from robust fit
492 
493  }
494 
495  return 0;
496 }
497 
498 } //End of Trk
Trk::ForVrtClose::dcovf
double dcovf[21]
Definition: ForVrtClose.h:24
Propagator.h
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
Trk::VKTrack::cnstP
double cnstP[3]
Definition: TrkVKalVrtCoreBase.h:80
CommonPars.h
Trk::VKTrack::WgtM
double WgtM[15]
Definition: TrkVKalVrtCoreBase.h:87
Trk::cfInv5
int cfInv5(double *cov, double *wgt)
Definition: Tracking/TrkVertexFitter/TrkVKalVrtCore/src/Matrix.cxx:459
stCnst.h
Trk::cfdcopy
void cfdcopy(double *source, double *target, int n)
Definition: TrkVKalUtils.h:23
Trk::vkalPropagator::checkTarget
static bool checkTarget(double *RefEnd)
Definition: Propagator.cxx:108
max
#define max(a, b)
Definition: cfImp.cxx:41
Trk::ForCFT::useThetaCnst
int useThetaCnst
Definition: ForCFT.h:17
Trk::VKVertex::tmpArr
std::vector< std::unique_ptr< TWRK > > tmpArr
Definition: TrkVKalVrtCoreBase.h:168
Trk::vkalMagFld::getMagFld
static void getMagFld(const double, const double, const double, double &, double &, double &, VKalVrtControlBase *)
Definition: VKalVrtBMag.cxx:24
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
beamspotman.cur
def cur
Definition: beamspotman.py:671
Trk::VKTrack::Chi2
double Chi2
Definition: TrkVKalVrtCoreBase.h:77
index
Definition: index.py:1
Trk::cfddist3D
double cfddist3D(double *V1, double *V2)
Definition: TrkVKalUtils.h:26
skel.it
it
Definition: skel.GENtoEVGEN.py:396
Trk::VKVertex::useApriorVertex
int useApriorVertex
Definition: TrkVKalVrtCoreBase.h:151
python.AthDsoLogger.out
out
Definition: AthDsoLogger.py:71
Trk::vtcfit
int vtcfit(VKVertex *vk)
Definition: VtCFit.cxx:293
Trk::VKalVrtControl::setVrtMassError
void setVrtMassError(double error)
Definition: TrkVKalVrtCore.h:76
Trk::VKVertex::FVC
ForVrtClose FVC
Definition: TrkVKalVrtCoreBase.h:160
Trk::cfSmallEigenvalue
double cfSmallEigenvalue(double *cov, long int n)
Definition: Tracking/TrkVertexFitter/TrkVKalVrtCore/src/Matrix.cxx:450
CFit.h
vkalShiftToTrigExtrapolation
#define vkalShiftToTrigExtrapolation
Definition: CommonPars.h:26
xyz
#define xyz
Trk::VKVertex::refIterV
double refIterV[3]
Definition: TrkVKalVrtCoreBase.h:146
Trk::applyConstraints
void applyConstraints(VKVertex *vk)
Definition: stCnst.cxx:22
Trk::VKTrack
Definition: TrkVKalVrtCoreBase.h:64
Trk::ForCFT::Cp
double Cp
Definition: ForCFT.h:30
Trk::VKVertex::ader
double ader[(3 *vkalNTrkM+3) *(3 *vkalNTrkM+3)]
Definition: TrkVKalVrtCoreBase.h:188
Trk::VKTrack::refPerig
double refPerig[5]
Definition: TrkVKalVrtCoreBase.h:96
Trk::ForVrtClose::Charge
long int Charge
Definition: ForVrtClose.h:22
Trk::VKVertex::apriorV
double apriorV[3]
Definition: TrkVKalVrtCoreBase.h:152
Trk::VKTrack::Perig
double Perig[5]
Definition: TrkVKalVrtCoreBase.h:86
VKalVrtBMag.h
VtDeriv.h
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
cfTotCov.h
Trk::ForCFT
Definition: ForCFT.h:13
Trk::VKTrack::fitP
double fitP[3]
Definition: TrkVKalVrtCoreBase.h:76
TrkVKalVrtCoreBase.h
Trk::ForCFT::vrt
double vrt[3]
Definition: ForCFT.h:39
Trk::VKVertex::TrackList
std::vector< std::unique_ptr< VKTrack > > TrackList
Definition: TrkVKalVrtCoreBase.h:167
Trk::ForCFT::usePassNear
int usePassNear
Definition: ForCFT.h:20
Trk::VKalVrtControl::setVertexMass
void setVertexMass(double mass)
Definition: TrkVKalVrtCore.h:75
Trk::vkalPropagator::Propagate
static void Propagate(long int TrkID, long int Charge, double *ParOld, double *CovOld, double *RefStart, double *RefEnd, double *ParNew, double *CovNew, VKalVrtControlBase *FitControl=0)
Definition: Propagator.cxx:127
Trk::afterFit
int afterFit(VKVertex *vk, double *ader, double *dcv, double *ptot, double *VrtMomCov, const VKalVrtControlBase *CONTROL)
Definition: cfTotCov.cxx:26
Trk::VKVertex::fitV
double fitV[3]
Definition: TrkVKalVrtCoreBase.h:140
Trk::ForCFT::indtrkmc
int indtrkmc[vkalMaxNMassCnst][vkalNTrkM]
Definition: ForCFT.h:46
Trk::ForVrtClose::vrt
double vrt[3]
Definition: ForVrtClose.h:23
lumiFormat.i
int i
Definition: lumiFormat.py:85
Trk::cfmasserr
void cfmasserr(VKVertex *vk, const int *list, double BMAG, double *MASS, double *sigM)
Definition: cfMassErr.cxx:16
Trk::VKVertex::setRefIterV
void setRefIterV(double v[]) noexcept
Definition: TrkVKalVrtCoreBase.cxx:148
Trk::VKVertex::setIniV
void setIniV(double v[3]) noexcept
Definition: TrkVKalVrtCoreBase.cxx:149
Trk::VKVertex::fitMom
double fitMom[3]
Definition: TrkVKalVrtCoreBase.h:158
TrkVKalVrtCore.h
chi2
double chi2(TH1 *h0, TH1 *h1)
Definition: comparitor.cxx:522
Matrix.h
Trk::VKVertex::refV
double refV[3]
Definition: TrkVKalVrtCoreBase.h:148
Trk::VKVertex::passNearVertex
bool passNearVertex
Definition: TrkVKalVrtCoreBase.h:156
Trk::ForCFT::useAprioriVrt
int useAprioriVrt
Definition: ForCFT.h:19
Trk::ForCFT::IterationPrecision
double IterationPrecision
Definition: ForCFT.h:48
Trk::VKVertex::fitVcov
double fitVcov[6]
Definition: TrkVKalVrtCoreBase.h:141
Trk::ForCFT::usePhiCnst
int usePhiCnst
Definition: ForCFT.h:16
Trk::VKalVrtControl::renewFullCovariance
void renewFullCovariance(double *)
Definition: TrkVKalVrtCoreBase.cxx:311
Trk::ForCFT::usePlaneCnst
int usePlaneCnst
Definition: ForCFT.h:21
Trk::ForVrtClose::cvder
double cvder[12]
Definition: ForVrtClose.h:30
min
#define min(a, b)
Definition: cfImp.cxx:40
Trk::ForCFT::covvrt
double covvrt[6]
Definition: ForCFT.h:39
Trk::VKVertex::existFullCov
int existFullCov
Definition: TrkVKalVrtCoreBase.h:186
ARR2D_FS
#define ARR2D_FS(name, N, i, j)
Definition: CommonPars.h:29
grepfile.ic
int ic
Definition: grepfile.py:33
Derivt.h
Trk
Ensure that the ATLAS eigen extensions are properly loaded.
Definition: FakeTrackBuilder.h:9
Trk::VKVertex::vk_fitterControl
std::unique_ptr< VKalVrtControl > vk_fitterControl
Definition: TrkVKalVrtCoreBase.h:194
Trk::VKVertex::setRefV
void setRefV(double v[3]) noexcept
Definition: TrkVKalVrtCoreBase.cxx:147
Trk::VKalVrtControl::getFullCovariance
const double * getFullCovariance() const
Definition: TrkVKalVrtCore.h:73
Trk::getFitParticleMom
std::array< double, 4 > getFitParticleMom(const VKTrack *trk, const VKVertex *vk)
Definition: cfMomentum.cxx:25
Trk::ForCFT::wm
double wm[vkalNTrkM]
Definition: ForCFT.h:26
Trk::ForCFT::Dp
double Dp
Definition: ForCFT.h:30
Trk::ForCFT::Ap
double Ap
Definition: ForCFT.h:30
vkalNTrkM
#define vkalNTrkM
Definition: CommonPars.h:22
Trk::ForCFT::wmfit
double wmfit[vkalMaxNMassCnst]
Definition: ForCFT.h:27
Trk::VKVertex::setCnstV
void setCnstV(double v[3]) noexcept
Definition: TrkVKalVrtCoreBase.cxx:151
Trk::vertex
@ vertex
Definition: MeasurementType.h:21
DeMoScan.index
string index
Definition: DeMoScan.py:364
Trk::ForCFT::localbmag
double localbmag
Definition: ForCFT.h:28
Trk::VKalVrtControl
Definition: TrkVKalVrtCore.h:44
Trk::VKVertex::Chi2
double Chi2
Definition: TrkVKalVrtCoreBase.h:139
Trk::VKVertex::fitCovXYZMom
double fitCovXYZMom[21]
Definition: TrkVKalVrtCoreBase.h:159
cfMassErr.h
Trk::ForCFT::irob
int irob
Definition: ForCFT.h:43
vkalMaxNMassCnst
#define vkalMaxNMassCnst
Definition: CommonPars.h:27
Trk::ForVrtClose::ywgt
double ywgt[3]
Definition: ForVrtClose.h:29
Trk::ForCFT::IterationNumber
int IterationNumber
Definition: ForCFT.h:47
Trk::VKVertex
Definition: TrkVKalVrtCoreBase.h:128
Trk::robtest
void robtest(VKVertex *vk, int ifl, int nIteration)
Definition: RobTest.cxx:14
Trk::CFit
int CFit(VKalVrtControl *FitCONTROL, int ifCovV0, int NTRK, long int *ich, double xyz0[3], double(*par0)[3], double(*inp_Trk5)[5], double(*inp_CovTrk5)[15], double xyzfit[3], double(*parfs)[3], double ptot[4], double covf[21], double &chi2, double *chi2tr)
Definition: CFit.cxx:429
Trk::VKVertex::iniV
double iniV[3]
Definition: TrkVKalVrtCoreBase.h:142
Trk::ForVrtClose::dcv
double dcv[6 *(vkalNTrkM *3+3)]
Definition: ForVrtClose.h:31
Trk::VKTrack::iniP
double iniP[3]
Definition: TrkVKalVrtCoreBase.h:83
VtCFit.h
Trk::x
@ x
Definition: ParamDefs.h:55
Trk::ForCFT::nmcnst
int nmcnst
Definition: ForCFT.h:25
Utilities.h
Trk::ForVrtClose::covvrt
double covvrt[6]
Definition: ForVrtClose.h:23
Trk::VKVertex::passWithTrkCov
bool passWithTrkCov
Definition: TrkVKalVrtCoreBase.h:157
Trk::ForCFT::Bp
double Bp
Definition: ForCFT.h:30
Trk::VKalVrtControl::vk_forcft
ForCFT vk_forcft
Definition: TrkVKalVrtCore.h:91
Trk::ForCFT::robres
double robres[vkalNTrkM]
Definition: ForCFT.h:45
Trk::VKVertex::truncatedStep
bool truncatedStep
Definition: TrkVKalVrtCoreBase.h:185
Trk::cfTrkCovarCorr
void cfTrkCovarCorr(double *cov)
Definition: Tracking/TrkVertexFitter/TrkVKalVrtCore/src/Utilities.cxx:290
Trk::ForCFT::useMassCnst
int useMassCnst
Definition: ForCFT.h:15
cfMomentum.h
Trk::vpderiv
void vpderiv(bool UseTrackErr, long int Charge, const double *pari0, double *covi, double *vrtref, double *covvrtref, double *drdpar, double *dwgt, double *rv0, VKalVrtControl *FitCONTROL)
Definition: VtDeriv.cxx:16
RobTest.h
Trk::ForCFT::usePointingCnst
int usePointingCnst
Definition: ForCFT.h:18