ATLAS Offline Software
CFitCascade.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3 */
4 
10 #include "TrkVKalVrtCore/VtCFit.h"
11 #include "TrkVKalVrtCore/VtDeriv.h"
12 #include "TrkVKalVrtCore/Matrix.h"
15 #include "TrkVKalVrtCore/RobTest.h"
18 #include "TrkVKalVrtCore/XYZtrp.h"
19 #include "TrkVKalVrtCore/ForCFT.h"
23 #include <array>
24 #include <cmath>
25 #include <iostream>
26 
27 
28 namespace Trk {
29 
30 //--------------------------------------------------------------------
31 //
32 // Set up masses of combined particles
33 //
35 {
36  double vBx,vBy,vBz;
37  int it, NTRK;
38  VectMOM totP{};
39 
40  if(!vk->nextCascadeVrt)return 0; // nonpointing vertex
41 
42  Trk::vkalMagFld::getMagFld(vk->refIterV[0]+vk->fitV[0], vk->refIterV[1]+vk->fitV[1], vk->refIterV[2]+vk->fitV[2],
43  vBx,vBy,vBz,(vk->vk_fitterControl).get());
44 
45  NTRK = vk->TrackList.size(); // Number of tracks at vertex
46  totP.Px=0.;totP.Py=0.;totP.Pz=0.;totP.E=0.;
47  for(it=0; it<NTRK; it++){
48  std::array<double, 4> pp = getFitParticleMom( vk->TrackList[it].get(), vBz );
49  totP.Px += pp[0];
50  totP.Py += pp[1];
51  totP.Pz += pp[2];
52  totP.E += pp[3];
53  }
54  VKTrack * target_trk = getCombinedVTrack(vk);
55  if( target_trk == nullptr ) {
56  std::cout<<" ERROR in CASCADE STRUCTURE"<<'\n';
57  return -1;
58  }
59  double Pt=sqrt(totP.Px*totP.Px + totP.Py*totP.Py);
60  double Mass;
61  if(Pt > std::abs(totP.Pz)){
62  Mass = sqrt( (totP.E-Pt)*(totP.E+Pt) - totP.Pz*totP.Pz);
63  }else{
64  Mass = sqrt( (totP.E-totP.Pz)*(totP.E+totP.Pz) - Pt*Pt);
65  }
66  target_trk->setMass(Mass);
67 
68  return 0;
69 }
70 
71 long int getVertexCharge( VKVertex * vk){
72  long int tCharge=0;
73  for(int it=0; it<(int)vk->TrackList.size(); it++) tCharge += vk->TrackList[it]->Charge;
74  return tCharge;
75 }
76 
77 double cascadeCnstRemnants(CascadeEvent & cascadeEvent_){
78  double cnstRemnants=0.;
79  for(int iv=0; iv<cascadeEvent_.cascadeNV; iv++){
80  VKVertex * vk = cascadeEvent_.cascadeVertexList[iv].get();
81  for(int ii=0; ii<(int)vk->ConstraintList.size();ii++){
82  for(int ic=0; ic<(int)vk->ConstraintList[ii]->NCDim; ic++){
83  cnstRemnants += std::abs( vk->ConstraintList[ii]->aa[ic] );
84  } }
85  }
86  return cnstRemnants;
87 }
88 
89 int fitVertexCascade( VKVertex * vk, int Pointing)
90 {
91 //-------------------------------------------------------------------------
92 // Fits single vertex in cascade (no iterations , just a single fit!!!)
93 // creates summary track after it and fills corresponding track parameters
94 // in next vertex in cascade
95 //
96 // Procedure assumes that "included tracks"(from vertices) are already
97 // recalculated in predecessor vertices fits.
98 //
99 // Pointing=0 (false) - for combined track FITTED at vertex parameters are used
100 // ^^^^^^ better convergence
101 // Pointing=1 (true) - for combined track GUESSED(ini) at GUESSED(ini) vertex
102 // parameters are used together with afterfit error matrix.
103 // It's needed for correct treatment of pointing
104 //-------------------------------------------------------------------------
105 //
106 // Fit itself. First get magnetic field at iteration reference point
107 //
108  vk->vk_fitterControl->vk_forcft.localbmag=Trk::vkalMagFld::getMagFld(vk->refIterV,(vk->vk_fitterControl).get());
109 
110 
111 //
112 //-------- Check if pointing constraint exists
113 //
114  bool existPointingCnst=false;
115  for(int ic=0; ic<(int)vk->ConstraintList.size(); ic++){
116  if(vk->ConstraintList[ic]->getType() == VKContraintType::Point) { existPointingCnst=true; break; }
117  }
118 //
119 //-------- Then fit
120 //
121  applyConstraints(vk); //apply all constraints in vertex
122  int IERR = vtcfit( vk );
123  if(IERR) return IERR;
124 //
125 //fit vertex once more with resolved constraints to prevent oscillations
126 // if(Pointing){
127 // double targVrt[3]={vk->refIterV[0] + vk->fitV[0],vk->refIterV[1] + vk->fitV[1],vk->refIterV[2] + vk->fitV[2]};
128 // vk->vk_fitterControl->vk_forcft.localbmag=myMagFld.getMagFld(vk->targVrt,(vk->vk_fitterControl).get());
129 // vk->setRefIterV(targVrt);
130 // vk->iniV[0]=vk->fitV[0]=vk->cnstV[0]=vk->iniV[1]=vk->fitV[1]=vk->cnstV[1]=vk->iniV[2]=vk->fitV[2]=vk->cnstV[2]=0.;
131 // for(int it=0; it<(int)vk->TrackList.size(); it++){
132 // VKTrack * trk = vk->TrackList[it];
133 // trk->cnstP[0] = trk->iniP[0] = trk->fitP[0]; // for constraint calculation on next step
134 // trk->cnstP[1] = trk->iniP[1] = trk->fitP[1];
135 // trk->cnstP[2] = trk->iniP[2] = trk->fitP[2];
136 // }
137 // applyConstraints(vk); //apply all constraints in vertex
138 // int IERR = vtcfit( vk );
139 // if(IERR) return IERR;
140 // }
141 //
142 // Fill fitted combined track in next vertex (if needed)
143 //
144  if(vk->nextCascadeVrt){
145  FullMTXfill(vk, vk->ader);
146  VKTrack * target_trk = getCombinedVTrack(vk); // get address of combined track
147  if( target_trk == nullptr ) return -12;
148 
149  long int Charge=getVertexCharge(vk);
150  if(Charge!=0) Charge=std::copysign(1,Charge);
151  target_trk->Charge=Charge;
152 
153  double dptot[4],VrtMomCov[21];
154  double parV0[5],covParV0[15],tmpCov[15],fittedVrt[3];
155  if(Pointing){
156  IERR = afterFitWithIniPar( vk, vk->ader, vk->FVC.dcv, dptot, VrtMomCov, (vk->vk_fitterControl).get());
157  fittedVrt[0]=vk->refIterV[0]+vk->iniV[0];
158  fittedVrt[1]=vk->refIterV[1]+vk->iniV[1];
159  fittedVrt[2]=vk->refIterV[2]+vk->iniV[2];
160  }
161  else{
162  IERR = afterFit( vk, vk->ader, vk->FVC.dcv, dptot, VrtMomCov, (vk->vk_fitterControl).get());
163  fittedVrt[0]=vk->refIterV[0]+vk->fitV[0];
164  fittedVrt[1]=vk->refIterV[1]+vk->fitV[1];
165  fittedVrt[2]=vk->refIterV[2]+vk->fitV[2];
166  }
167  if (IERR) return -13; /* NONINVERTIBLE COV.MATRIX */
168  cfdcopy( dptot, vk->fitMom, 3); //save Momentum
169  cfdcopy(VrtMomCov, vk->fitCovXYZMom, 21); //save XYZMom covariance
170 //
171 //-- Solution (not ideal!) of cascade covariance problem.
172 //-- Covariance of pseudo-particle must be calculated WITHOUT pointing constraint ALWAYS!.
173 //
174 // if(existPointingCnst){ // use saved matrix without pointing constraint
175 // cfdcopy( vk->savedVrtMomCov, VrtMomCov, 21);
176 // }else{ // save computed matrix for further use
177 // cfdcopy( VrtMomCov, vk->savedVrtMomCov, 21);
178 // }
179  if(existPointingCnst){ // add pointed vertex covariance to track
180  for(int km=0; km<6; km++) VrtMomCov[km] += vk->nextCascadeVrt->fitCovXYZMom[km];
181  if(vk->nextCascadeVrt->TrackList[0]->Id>0){ //There is at least one real track in this vertex
182  VrtMomCov[0] *= 1000.;
183  VrtMomCov[2] *= 1000.;
184  VrtMomCov[5] *= 1000.;
185  VrtMomCov[9] *= 1000.;
186  VrtMomCov[14] *= 1000.;
187  VrtMomCov[20] *= 1000.;
188  }
189  }
190 //
191 // Particle creation and propagation
192  double localField=Trk::vkalMagFld::getMagFld(fittedVrt,(vk->vk_fitterControl).get());
193  combinedTrack( Charge, dptot, VrtMomCov, localField, parV0, covParV0);
194  covParV0[0]=std::abs(covParV0[0]); covParV0[2]=std::abs(covParV0[2]); covParV0[5]=std::abs(covParV0[5]);
195  covParV0[9]=std::abs(covParV0[9]); covParV0[14]=std::abs(covParV0[14]); //VK protection against numerical problems
196  Trk::vkalPropagator::Propagate(-999, Charge, parV0, covParV0, fittedVrt,
197  vk->nextCascadeVrt->refIterV, target_trk->Perig, tmpCov, (vk->vk_fitterControl).get());
198 // IERR=cfInv5(tmpCov, target_trk->WgtM); if (IERR) IERR=cfdinv(tmpCov, target_trk->WgtM, 5);
199 // target_trk->iniP[0]=target_trk->cnstP[0]=target_trk->fitP[0]=target_trk->Perig[2]; //initial guess
200 // target_trk->iniP[1]=target_trk->cnstP[1]=target_trk->fitP[1]=target_trk->Perig[3];
201 // target_trk->iniP[2]=target_trk->cnstP[2]=target_trk->fitP[2]=target_trk->Perig[4];
202  if( target_trk->fitP[2] == 0.){
203  target_trk->iniP[0]=target_trk->cnstP[0]=target_trk->Perig[2]; //initial guess
204  target_trk->iniP[1]=target_trk->cnstP[1]=target_trk->Perig[3];
205  target_trk->iniP[2]=target_trk->cnstP[2]=target_trk->Perig[4];
206  }else if(Pointing){
207  target_trk->iniP[0]=target_trk->cnstP[0]=target_trk->fitP[0]; //initial guess
208  target_trk->iniP[1]=target_trk->cnstP[1]=target_trk->fitP[1];
209  target_trk->iniP[2]=target_trk->cnstP[2]=target_trk->fitP[2];
210  }else{
211  target_trk->iniP[0]=target_trk->cnstP[0]=(target_trk->fitP[0]+target_trk->Perig[2])/2.; //initial guess
212  target_trk->iniP[1]=target_trk->cnstP[1]=(target_trk->fitP[1]+target_trk->Perig[3])/2.;
213  target_trk->iniP[2]=target_trk->cnstP[2]=(target_trk->fitP[2]+target_trk->Perig[4])/2.;
214  }
215  if(tmpCov[0]>1.e12 || tmpCov[2]>1.e12) return -18; //Something is wrong in combined track creation
216  if(Pointing){tmpCov[0] += target_trk->Perig[0]*target_trk->Perig[0]; tmpCov[2] += target_trk->Perig[1]*target_trk->Perig[1];}
217  tmpCov[0] += 0.0001*0.0001; tmpCov[2] += 0.0002*0.0002; //numerical accuracy protection
218 
219  IERR=cfInv5(tmpCov, target_trk->WgtM); if (IERR) IERR=cfdinv(tmpCov, target_trk->WgtM, 5);
220  if (IERR) return -15; /* NONINVERTIBLE COV.MATRIX */
221  }
222 //
223 // For passing near vertex constraint. Normally first(mother) vertex of cascade
224 // Now used also for "close to vertex" mode for cascade
225 // For last in structure (mother in cascade...) always calculate it - needed for pointing
226 //
227  CascadeEvent & cascadeEvent_ = *(vk->vk_fitterControl->getCascadeEvent());
228  if( vk->passNearVertex || vk==cascadeEvent_.cascadeVertexList[cascadeEvent_.cascadeNV-1].get()){
229  double dptot[4],VrtMomCov[21];
230  IERR = afterFit( vk, vk->ader, vk->FVC.dcv, dptot, VrtMomCov, (vk->vk_fitterControl).get());
231  if (IERR) return -13; /* NONINVERTIBLE COV.MATRIX */
232  cfdcopy( dptot, vk->fitMom, 3); //save Momentum
233  cfdcopy(VrtMomCov, vk->fitCovXYZMom, 21); //save XYZMom covariance
234  }
235  return 0;
236 }
237 //==============================
238 // int processCascadeScale( );
239 // int processCascade( ) { int IERR=processCascadeScale(); std::cout<<IERR<<'\n'; return IERR;}
240 //-----------------------------------------------------------------------------------
241 //
242 // Iteration over complete cascade
243 //
244 int processCascade(CascadeEvent & cascadeEvent_ )
245 {
246  int translateToFittedPos(CascadeEvent &, double Step=1.);
247  int restorePreviousPos(CascadeEvent &, std::vector<VKVertex> & );
248 
249  VKVertex * vk;
250  long int Iter, IERR, iv, i;
251 //============================================================================================
252 //
253 // First without pointing to get initial estimations and resolve mass constraints
254 // This initial step is needed to get initial estimation for "passing near constraint
255 //
256  for(iv=0; iv<cascadeEvent_.cascadeNV; iv++){
257  vk = cascadeEvent_.cascadeVertexList[iv].get();
258  IERR = fitVertexCascade( vk, 0); if(IERR)return IERR; //fit
259  IERR = setVTrackMass(vk); if(IERR)return IERR; //mass of combined particle
260  }
261  IERR = translateToFittedPos(cascadeEvent_); if(IERR)return IERR;
262 //
263 // Now standard fit without pointing in cascade but WITH pointing to PV if present
264 //
265 
266  double Chi2Old=0.,Chi2Cur=0.;
267  for(Iter=0; Iter<100; Iter++){
268  Chi2Cur=0.;
269  for(iv=0; iv<cascadeEvent_.cascadeNV; iv++){
270  vk = cascadeEvent_.cascadeVertexList[iv].get();
271 //
272 //Calculate derivatives for "passing near" cnst. Initial vertex position is used for derivatives.
273 //Results are saved in ForVRTClose structure
274  if(cascadeEvent_.nearPrmVertex && iv==(cascadeEvent_.cascadeNV-1)){ //only last vertex in cascade may have it
275  double dparst[6]={vk->refIterV[0]+vk->iniV[0], vk->refIterV[1]+vk->iniV[1], vk->refIterV[2]+vk->iniV[2],
276  vk->fitMom[0], vk->fitMom[1], vk->fitMom[2] };
277  vk->FVC.Charge=getVertexCharge(vk);
278  if(vk->FVC.Charge!=0)vk->FVC.Charge=std::copysign(1,vk->FVC.Charge);
279  vpderiv(true, vk->FVC.Charge, dparst, vk->fitCovXYZMom, vk->FVC.vrt, vk->FVC.covvrt,
280  vk->FVC.cvder, vk->FVC.ywgt, vk->FVC.rv0, (vk->vk_fitterControl).get());
281  }
282  IERR = fitVertexCascade( vk, 0); if(IERR)return IERR; //fit
283  IERR = setVTrackMass(vk); if(IERR)return IERR; //mass of combined particle
284  Chi2Cur += vk->Chi2;
285 //std::cout<<iv<<"---Chi2="<<vk->Chi2<<", "<<vk->refIterV[0]+vk->fitV[0]<<", "<<vk->refIterV[1]+vk->fitV[1]<<", "<<vk->refIterV[2]+vk->fitV[2]<<'\n';
286  }
287  if( Chi2Cur-Chi2Old > 1. && Iter){ IERR = translateToFittedPos(cascadeEvent_,0.8);} //step limitation is case of divergence
288  else { IERR = translateToFittedPos(cascadeEvent_,1.0);} if(IERR)return IERR;
289 
290 //std::cout<<" free iter="<<Iter<<", "<<Chi2Cur<<", "<<Chi2Old-Chi2Cur<<"; "<<cascadeEvent_.cascadeNV<<'\n';
291  if(std::abs(Chi2Cur-Chi2Old)<0.01)break; //stable cascade position
292  if(Iter>10 && (Chi2Cur-Chi2Old)>0.)break; //oscillations. Stop preliminary fit
293  Chi2Old=Chi2Cur;
294  if(Chi2Cur>1.e6 && Iter>0) return -1; //Too bad iteration. Drop fit
295  }
296 // if(Chi2Cur>3000.) return -1; // Initial solution is too bad!!!
297 //-------------------------------- Check constraints status
298  double cnstRemnants=cascadeCnstRemnants(cascadeEvent_);
299  if( cnstRemnants > 10000.e0) return -2; /* Constraints are not resolved. Stop fit */
300  if(cnstRemnants==0. && Chi2Cur>3000. ) return -1; // Initial solution is too bad!!!
301  if( Chi2Cur>50000.) return -1; // Initial solution is too bad!!!
302 //-------------------------------------------------------------------------
303 // Attach pointing constraint to affected vertices and create working arrays
304 // of correct size
305 //
306  for(iv=0; iv<cascadeEvent_.cascadeNV; iv++){
307  vk = cascadeEvent_.cascadeVertexList[iv].get();
308  if(vk->nextCascadeVrt){
309  long int NTRK = vk->TrackList.size();
310  vk->ConstraintList.emplace_back(new VKPointConstraint( NTRK, vk->nextCascadeVrt->refIterV , vk, false));
311  }
312  }
313  long int fullNPar = getCascadeNPar(cascadeEvent_);
314  double * fullMatrix = new double[fullNPar*fullNPar];
315  double * iniCovMatrix = new double[fullNPar*fullNPar];for(int ss=0; ss<fullNPar*fullNPar; ss++) iniCovMatrix[ss]=0.;
316  double * fullLSide = new double[fullNPar];
317  double * tmpLSide = new double[fullNPar];
318  //std::unique_ptr<double[]> tmpLSide = std::unique_ptr<double[]>(new double[fullNPar])
319  std::vector<VKVertex> listVCopy(cascadeEvent_.cascadeNV);
320 //-------------------------------------------------------
321 // Now fit with pointing constraint
322 //
323  cascadeEvent_.matrixPnt.resize(cascadeEvent_.cascadeNV);
324  long int NParCur, NStart;
325  int getBack=0; // counter of oscillations
326  int fullSTOP=0; // immediate stop iteration flag
327  double Chi2Diff=0.;
328 
329  int NFitIterationMax=100; // Maximal amount of iterations
330  int badStepCountMax=5; // Maximal amount of bad steps
331 
332  cnstRemnants=100000.; double cnstProgr=1.; double minCnstRemnants=100000.;
333  int badStepCount=0;
334 
335  for(Iter=0; Iter<=NFitIterationMax; Iter++){
336  Chi2Cur=0.;
337  NStart=0;
338  for( iv=0; iv<fullNPar*fullNPar; iv++)fullMatrix[iv]=0.; // zero full matrix
339  for( iv=0; iv<cascadeEvent_.cascadeNV; iv++){
340  vk = cascadeEvent_.cascadeVertexList[iv].get();
341 //
342 //Calculate derivatives for "passing near" cnst. Initial vertex position is used for derivatives.
343 //Results are saved in ForVRTClose structure
344  if(cascadeEvent_.nearPrmVertex && iv==(cascadeEvent_.cascadeNV-1)){ //only last vertex in cascade may have it
345  double dparst[6]={vk->refIterV[0]+vk->iniV[0], vk->refIterV[1]+vk->iniV[1], vk->refIterV[2]+vk->iniV[2],
346  vk->fitMom[0], vk->fitMom[1], vk->fitMom[2] };
347  vk->FVC.Charge=getVertexCharge(vk);
348  if(vk->FVC.Charge!=0)vk->FVC.Charge=std::copysign(1,vk->FVC.Charge);
349  vpderiv(vk->passWithTrkCov, vk->FVC.Charge, dparst, vk->fitCovXYZMom,
350  vk->FVC.vrt, vk->FVC.covvrt, vk->FVC.cvder, vk->FVC.ywgt, vk->FVC.rv0, (vk->vk_fitterControl).get());
351  }
352  if (vk->vk_fitterControl->vk_forcft.irob != 0) {robtest(vk, 0, Iter);} // ROBUSTIFICATION new data structure
353  if (vk->vk_fitterControl->vk_forcft.irob != 0) {robtest(vk, 1, Iter);} // ROBUSTIFICATION new data structure
354  IERR = fitVertexCascade( vk, 1 ); if(IERR) break; //with passNear for last vertex in cascade if needed
355  IERR = setVTrackMass(vk); if(IERR) break; //mass of combined particle
356 //
357 //Get full constraint matrix and left side for vertex
358  cascadeEvent_.matrixPnt[iv]=NStart;
359  NParCur = FullMCNSTfill( vk, vk->ader, tmpLSide);
360 //
361 //Move them to cascade full matrix and left side
362  copyFullMtx( vk->ader, NParCur, NParCur, fullMatrix, NStart, fullNPar);
363 //
364 //Copy error matrix for left side vector (measured part T,U1,..,Un - see Billoir)
365 // to correct place in iniCovMatrix matrix. Only at last step and without constraint part!!! CHECK IT!!!
366  if(Iter==NFitIterationMax || fullSTOP || badStepCount>=badStepCountMax)
367  copyFullMtx( vk->ader, 3+3*vk->TrackList.size(), NParCur, iniCovMatrix, NStart, fullNPar);
368 //
369 // Fill left part of the system
370  for(i=0; i<NParCur; i++) fullLSide[i+NStart] = tmpLSide[i];
371  NStart += NParCur;
372  Chi2Cur += vk->Chi2;
373 //std::cout<<iv<<"--------Chi2="<<vk->Chi2<<", "<<cascadeEvent_.nearPrmVertex<<" nstart="<<NStart<<'\n';
374  }
375  if( (Chi2Cur>1.e8 && Iter>0) || IERR){
376  delete[] fullMatrix; delete[] fullLSide; delete[] tmpLSide; delete[] iniCovMatrix;
377  if(Chi2Cur>1.e8) return -1;
378  return IERR;
379  }
380 //
381 //--- Attempt to dump oscillations by returning to good position
382  cnstProgr=cascadeCnstRemnants(cascadeEvent_)/cnstRemnants;
383  if( Iter>3 && cnstProgr>4. && getBack<5 && fullSTOP==0 ) { //------ Bad previous step discovered.
384  //std::cout<<" oscillation discovered="<<Iter<<" progr="<<cnstProgr<<'\n';
385  IERR=restorePreviousPos(cascadeEvent_, listVCopy );
386  if(IERR){ delete[] fullMatrix; delete[] fullLSide; delete[] tmpLSide; delete[] iniCovMatrix; return IERR;}
387  cnstRemnants=100000.; Chi2Old+=10000; // to skip restoring on next iteration
388  if(Iter==NFitIterationMax )Iter-=2; // to give time to converge after this operation
389  if(Iter==NFitIterationMax-1)Iter-=1; // to give time to converge after this operation
390  getBack++; badStepCount=0;
391  continue;
392  } //--------- Make some copy of vertices for safety
393  cnstRemnants*=cnstProgr; cnstRemnants += 1.e-6*cascadeEvent_.getAccuracyConstraint(); //VK Protection against 0
394  if(cnstRemnants<minCnstRemnants)minCnstRemnants=cnstRemnants;
395  if(minCnstRemnants==cnstRemnants){ //--------- Make copy of vertices for safety at best point
396  for( iv=0; iv<cascadeEvent_.cascadeNV; iv++){
397  listVCopy.at(iv)=*(cascadeEvent_.cascadeVertexList[iv]); // vertex list copy
398  }
399  }
400 //--------------------------------------------------------------------------
401 //for( iv=0; iv<fullNPar; iv++)std::cout<<fullLSide[iv]<<", ";std::cout<<'\n';
402 // std::cout<<fullLSide[3+3*2]<<", "<<fullLSide[3+3*2+1]<<", "<<
403 // fullLSide[20]<<", "<<fullLSide[21]<<", "<<fullLSide[22]<<'\n';
404 //---------------------------------------------------------------------------
405 //
406 // Add cross vertices derivatives
407  addCrossVertexDeriv(cascadeEvent_, fullMatrix, fullNPar, cascadeEvent_.matrixPnt);
408 //
409 // Add pseudotrack momentum fix
410 //
411  int tstRet=fixPseudoTrackPt(fullNPar, fullMatrix, fullLSide, cascadeEvent_ );
412  if( tstRet ){ delete[] fullMatrix; delete[] fullLSide; delete[] tmpLSide; delete[] iniCovMatrix; return -1; }
413 //
414 // Resolve full cascade with constraints system
415 //
416  if( Iter<NFitIterationMax && fullSTOP==0 && badStepCount<badStepCountMax){ //Normal step. Solution of system only
417  IERR = vkMSolve(fullMatrix, fullLSide, fullNPar);
418  if(IERR){ delete[] fullMatrix; delete[] fullLSide; delete[] tmpLSide; delete[] iniCovMatrix;return IERR;}
419  }else{ //Last step. Solution+full error matrix
420  cascadeEvent_.fullCovMatrix.reset( new double[fullNPar*fullNPar] ); //Create fresh matrix
421  IERR = vkMSolve(fullMatrix, fullLSide, fullNPar, cascadeEvent_.fullCovMatrix.get());
422  if(IERR){ delete[] fullMatrix; delete[] fullLSide; delete[] tmpLSide; delete[] iniCovMatrix;
423  cascadeEvent_.fullCovMatrix.reset(); return IERR;}
424 //std::cout<<"fulcov="; for(int tt=0; tt<fullNPar; tt++)std::cout<<cascadeEvent_.fullCovMatrix[tt*fullNPar+tt]<<", "; std::cout<<'\n';
425  std::unique_ptr<double[]> newCov(new double[fullNPar*fullNPar]); //Check via error transfer from left side (measured values). Gives exactly the same errors - correct!!!
426  getNewCov(iniCovMatrix, cascadeEvent_.fullCovMatrix.get(), newCov.get(), fullNPar);
427  cascadeEvent_.fullCovMatrix=std::move(newCov); //Unique_ptr will handle deletion automatically
428  }
429 //
430 // Set fitted parameters
431 //
432  setFittedParameters( fullLSide, cascadeEvent_.matrixPnt, cascadeEvent_ );
433 //
434 // Update pointing constraints and calculate real cascade Chi2
435 //
436  double Chi2Full=0.;
437  for(iv=0; iv<cascadeEvent_.cascadeNV; iv++){
438  vk = cascadeEvent_.cascadeVertexList[iv].get();
439  for(int it=0; it<(int)vk->TrackList.size(); it++){
440  VKTrack * trk=vk->TrackList[it].get(); if(trk->Id >= 0)Chi2Full+=trk->Chi2; // real track in cascade
441  }
442  if(cascadeEvent_.nearPrmVertex && iv==(cascadeEvent_.cascadeNV-1)){ //only last vertex in cascade may have it
443  double signift = cfVrtDstSig( vk, vk->passWithTrkCov);
444  Chi2Full += signift*signift;
445  }
446  }
447  Chi2Diff=Chi2Old-Chi2Full;
448  if(Chi2Diff<0. && cnstProgr>0.99) badStepCount++;
449  if(cnstRemnants==minCnstRemnants || cnstProgr<0.9) badStepCount=0;
450 //std::cout.precision(5); std::cout<<" iter="<<Iter<<" separ="<<Chi2Cur<<" full="<<Chi2Full<<" iter diff="<<Chi2Full/Chi2Cur<<
451 //" cnstrem="<<cnstRemnants<<" progr="<<cnstProgr<<" lim="<<cnstRemnants/minCnstRemnants<<" bstep="<<badStepCount<<'\n';
452  bool badFullStep=false;
453  if( Iter>5 && Chi2Full/Chi2Cur>1.2) badFullStep=true; //VK 16.04.2013 New strategy
454  if( Iter==NFitIterationMax || fullSTOP ) badFullStep=false; //VK 16.04.2013 No step limitation on last iteration
455 //
456 // Prepare next iteration
457 //
458  if(badFullStep) IERR = translateToFittedPos(cascadeEvent_,0.3);
459  else IERR = translateToFittedPos(cascadeEvent_);
460  if(IERR){ delete[] fullMatrix; delete[] fullLSide; delete[] tmpLSide; delete[] iniCovMatrix; return IERR;}
461 
462  for(iv=0; iv<cascadeEvent_.cascadeNV; iv++){
463  vk = cascadeEvent_.cascadeVertexList[iv].get();
464  if(vk->nextCascadeVrt){
465  int pntCnst = vk->ConstraintList.size() - 1; // pointing constraint is always last in the list
466  VKPointConstraint * pcnst = dynamic_cast<VKPointConstraint*>(vk->ConstraintList[pntCnst].get());
468  }
469  }
470 //
471 
472  if(fullSTOP) break;
473  if(cnstRemnants>1.e4&&Iter>10) //no way to fulfil constraints
474  { delete[] fullMatrix; delete[] fullLSide; delete[] tmpLSide; delete[] iniCovMatrix; return -2;}
475 //
476  if( Iter<NFitIterationMax && Iter>2){
477  if(std::abs(Chi2Diff)<0.001 && cnstRemnants/minCnstRemnants<10.){ //stable cascade position before end of cycling
478  NFitIterationMax=Iter+1; //then makes additional iteration to get the full error matrix
479  }
480  if(cnstRemnants<cascadeEvent_.getAccuracyConstraint()) fullSTOP++; //Good constraint accuracy is reached
481  }
482  if ( Iter>NFitIterationMax+50 ) break; //Protection - too many iterations due to whatever reason.
483  if(badStepCount>badStepCountMax)break; //Divergence discovered (in both cases the full error matrix is ready!!!)
484 
485  Chi2Old=Chi2Full;
486  }
487 
488  //if(tmpc0)std::cout<<(*tmpc0)<<'\n';
489  //if(tmpc1)std::cout<<(*tmpc1)<<'\n';
490 
491  delete[] fullMatrix; delete[] fullLSide; delete[] tmpLSide; delete[] iniCovMatrix;
492 //-------------------------------- Check constraints status
493  cnstRemnants=cascadeCnstRemnants(cascadeEvent_);
494 //std::cout<<"fullcnst="<<cnstRemnants<<" lim="<<cnstRemnants/minCnstRemnants<<'\n';
495  if( cnstRemnants > 1.e0) return -2; /* Constraints are not resolved. Stop fit */
496  return 0;
497 }
498 
499 //-----------------------------------------------------------------------------------
500 //
501 // Iteration over complete cascade with first cascade vertex in Primary Vertex
502 //
503  int processCascadePV(CascadeEvent & cascadeEvent_, const double *primVrt, const double *primVrtCov )
504 {
505  double aermd[6],tmpd[6]; // temporary arrays
506  VKVertex * vk = cascadeEvent_.cascadeVertexList[cascadeEvent_.cascadeNV-1].get(); //Main vertex
507 
508  vk->vk_fitterControl->vk_forcft.vrt[0] = primVrt[0];
509  vk->vk_fitterControl->vk_forcft.vrt[1] = primVrt[1];
510  vk->vk_fitterControl->vk_forcft.vrt[2] = primVrt[2];
511  vk->vk_fitterControl->vk_forcft.covvrt[0] = primVrtCov[0];
512  vk->vk_fitterControl->vk_forcft.covvrt[1] = primVrtCov[1];
513  vk->vk_fitterControl->vk_forcft.covvrt[2] = primVrtCov[2];
514  vk->vk_fitterControl->vk_forcft.covvrt[3] = primVrtCov[3];
515  vk->vk_fitterControl->vk_forcft.covvrt[4] = primVrtCov[4];
516  vk->vk_fitterControl->vk_forcft.covvrt[5] = primVrtCov[5];
517 
518  vk->useApriorVertex = 1;
519  cfdcopy(vk->vk_fitterControl->vk_forcft.covvrt, tmpd, 6);
520  int IERR=cfdinv(tmpd, aermd, -3); if (IERR) { IERR = -4; return IERR; }
521  cfdcopy(vk->vk_fitterControl->vk_forcft.vrt, vk->apriorV, 3);
522  cfdcopy( aermd, vk->apriorVWGT,6);
523 
524  return processCascade(cascadeEvent_);
525 }
526 
527 //-----------------------------------------------------------------------------------
528 //
529 // Iteration over complete cascade with "close to primary vertex" Chi2 term
530 //
531  int processCascade(CascadeEvent & cascadeEvent_, const double *primVrt, const double *primVrtCov )
532 {
533  cascadeEvent_.nearPrmVertex=1; //setting up additional Chi2 term
534  VKVertex * vk = cascadeEvent_.cascadeVertexList[cascadeEvent_.cascadeNV-1].get(); //Main vertex
535  vk->passNearVertex =true; // For fitting machinery
536  vk->passWithTrkCov =true; // For fitting machinery
537  std::copy(primVrt, primVrt+3, vk->FVC.vrt);
538  std::copy(primVrtCov, primVrtCov+6, vk->FVC.covvrt);
539  return processCascade(cascadeEvent_);
540 }
541 //-----------------------------------------------------------------------------------
542 //
543 // Iteration over complete cascade with exact pointing to primary vertex
544 //
545  int processCascade(CascadeEvent & cascadeEvent_, double *primVrt )
546 {
547  VKVertex * vk = cascadeEvent_.cascadeVertexList[cascadeEvent_.cascadeNV-1].get(); //Main vertex
548  long int NTRK = vk->TrackList.size();
549  vk->ConstraintList.emplace_back(new VKPointConstraint( NTRK, primVrt, vk, false));
550  cascadeEvent_.nearPrmVertex=0; //explicitly turn off additional Chi2 term
551  return processCascade(cascadeEvent_);
552 }
553 
554 
555 //----------------------------------------------------------------------
556 // Translate all external (physics) tracks to fitted vertices positions
557 // Step limitation is needed to break positive feedback
558 //
559  int translateToFittedPos(CascadeEvent & cascadeEvent_, double Step )
560 {
561  int iv,it;
562  long int IERR,NTRK;
563  double vShift, tmpPer[5], tmpWgt[15], tmpCov[15], targetVertex[3];
564  VKTrack * trk; VKVertex * vk;
565  if(Step>1.)Step=1.;
566 
567  for( iv=0; iv<cascadeEvent_.cascadeNV; iv++){
568  vk=cascadeEvent_.cascadeVertexList[iv].get();
569  NTRK = vk->TrackList.size(); // Number of tracks at vertex
570  targetVertex[0]=vk->refIterV[0] + vk->fitV[0]*Step; // target vertex for extrapolation
571  targetVertex[1]=vk->refIterV[1] + vk->fitV[1]*Step;
572  targetVertex[2]=vk->refIterV[2] + vk->fitV[2]*Step;
573  vShift = sqrt( (vk->refV[0]-targetVertex[0])*(vk->refV[0]-targetVertex[0])
574  +(vk->refV[1]-targetVertex[1])*(vk->refV[1]-targetVertex[1])
575  +(vk->refV[2]-targetVertex[2])*(vk->refV[2]-targetVertex[2]) );
576  for(auto *pvx : vk->includedVrt){ //Check space position of internal vertex
577  double dirMom=(pvx->refIterV[0]-targetVertex[0])*pvx->fitMom[0]+
578  (pvx->refIterV[1]-targetVertex[1])*pvx->fitMom[1]+
579  (pvx->refIterV[2]-targetVertex[2])*pvx->fitMom[2];
580  if(dirMom<0.)cfdcopy(pvx->refIterV,targetVertex,3);
581  }
582  bool insideGoodVolume=false;
583  if(vk->vk_fitterControl && vk->vk_fitterControl->vk_objProp)
584  { insideGoodVolume = vk->vk_fitterControl->vk_objProp->checkTarget(targetVertex, *vk->vk_fitterControl->vk_istate);}
585  else { insideGoodVolume = Trk::vkalPropagator::checkTarget(targetVertex); }
586  if(!insideGoodVolume) { return -16; } //Vertex is definitely outside working volume
587  for(it=0; it<NTRK; it++){
588  trk=vk->TrackList[it].get();
589  if(trk->Id < 0){ // pseudo-track from cascade vertex
590  trk->fitP[0] =trk->iniP[0]+ Step*(trk->fitP[0]-trk->iniP[0]);
591  trk->fitP[1] =trk->iniP[1]+ Step*(trk->fitP[1]-trk->iniP[1]);
592  trk->fitP[2] =trk->iniP[2]+ Step*(trk->fitP[2]-trk->iniP[2]);
593  continue;
594  }
595  Trk::vkalPropagator::Propagate(trk, vk->refV, targetVertex, tmpPer, tmpCov, (vk->vk_fitterControl).get());
596  //Check!!!And protection if needed.
597  double eig5=cfSmallEigenvalue(tmpCov,5 );
598  if(eig5<1.e-15 || tmpCov[0]>1.e7) { //Bad propagation with material. Try without it.
599  Trk::vkalPropagator::Propagate(-999, trk->Charge,trk->refPerig,trk->refCovar, vk->refV, targetVertex, tmpPer, tmpCov, (vk->vk_fitterControl).get());
600  if(cfSmallEigenvalue(tmpCov,5 )<1.e-15){ //Final protection
601  tmpCov[1]=0.;tmpCov[3]=0.;tmpCov[6]=0.;tmpCov[10]=0.;
602  tmpCov[4]=0.;tmpCov[7]=0.;tmpCov[11]=0.;
603  tmpCov[8]=0.;tmpCov[12]=0.;
604  tmpCov[13]=0.;
605  tmpCov[0]=std::abs(tmpCov[0]); tmpCov[2]=std::abs(tmpCov[2]);tmpCov[5]=std::abs(tmpCov[5]);
606  tmpCov[9]=std::abs(tmpCov[9]); tmpCov[14]=std::abs(tmpCov[14]);
607  }
608  }
609  if(tmpCov[0]>1.e7){ IERR=-7; return IERR; } //extremely big A0 error !!!
610  IERR=cfInv5(tmpCov, tmpWgt); if (IERR) IERR=cfdinv(tmpCov, tmpWgt, 5); if(IERR)return -8;
611  trk->setCurrent(tmpPer,tmpWgt);
612  if ( vShift > 100. ) trk->setReference( tmpPer, tmpCov ); //Change reference for big shift
613  }
614  vk->setRefIterV(targetVertex);
615  if ( vShift > 100. )vk->setRefV(targetVertex); // Change reference vertex for big shift
616  vk->iniV[0] = vk->fitV[0] = vk->cnstV[0]=0.;
617  vk->iniV[1] = vk->fitV[1] = vk->cnstV[1]=0.;
618  vk->iniV[2] = vk->fitV[2] = vk->cnstV[2]=0.;
619  for(it=0; it<NTRK; it++){
620  trk=vk->TrackList[it].get();
621  if(Step<1.){ // Step limitation for constraint calculation on next step
622  trk->cnstP[0] = trk->iniP[0] =trk->iniP[0]+ Step*(trk->fitP[0]-trk->iniP[0]);
623  trk->cnstP[1] = trk->iniP[1] =trk->iniP[1]+ Step*(trk->fitP[1]-trk->iniP[1]);
624  trk->cnstP[2] = trk->iniP[2] =trk->iniP[2]+ Step*(trk->fitP[2]-trk->iniP[2]);
625  }else{
626  trk->cnstP[0] = trk->iniP[0] = trk->fitP[0]; // for constraint calculation on next step
627  trk->cnstP[1] = trk->iniP[1] = trk->fitP[1];
628  trk->cnstP[2] = trk->iniP[2] = trk->fitP[2];
629  }
630  }
631  }
632  return 0;
633 }
634 
635 //----------------------------------------------------------------------
636 // Translate all external (physics) tracks to fitted vertices positions
637 // Step limitation is needed to break positive feedback
638 //
639 int restorePreviousPos(CascadeEvent & cascadeEvent_, std::vector<VKVertex> & SV )
640 {
641  int iv,it;
642  long int NTRK;
643  VKTrack * trk; VKTrack * trks; VKVertex * vk; VKVertex * vks;
644 
645  for( iv=0; iv<cascadeEvent_.cascadeNV; iv++){
646  vk=cascadeEvent_.cascadeVertexList[iv].get();
647  vks=&SV[iv];
648  NTRK = vk->TrackList.size(); // Number of tracks at vertex
649  vk->refIterV[0]=vks->refIterV[0];
650  vk->refIterV[1]=vks->refIterV[1];
651  vk->refIterV[2]=vks->refIterV[2];
652  vk->iniV[0] = vk->fitV[0] = vk->cnstV[0]=0.;
653  vk->iniV[1] = vk->fitV[1] = vk->cnstV[1]=0.;
654  vk->iniV[2] = vk->fitV[2] = vk->cnstV[2]=0.;
655  cfdcopy(vks->fitMom, vk->fitMom, 3); //saved Momentum
656  cfdcopy(vks->fitCovXYZMom, vk->fitCovXYZMom, 21); //saved XYZMom covariance
657  for(it=0; it<NTRK; it++){
658  trk =vk ->TrackList[it].get(); // working track
659  trks=vks->TrackList[it].get(); // track from saved copy
660  if(trk->Id < 0) { // pseudo-track from cascade vertex
661  //trk->fitP[2]=0.; // reset the pseudo-track parameters
662  trk->fitP[0] =(trks->iniP[0]+trks->fitP[0])/2.;
663  trk->fitP[1] = trks->iniP[1];
664  trk->fitP[2] =(trks->iniP[2]+trks->fitP[2])/2.;
665  continue;
666  }
667  cfdcopy(trks->Perig, trk->Perig, 5);
668  cfdcopy(trks->WgtM, trk->WgtM, 15);
669  cfdcopy(trks->fitP, trk->fitP, 3);
670  cfdcopy(trks->iniP, trk->iniP, 3);
671  cfdcopy(trks->cnstP, trk->cnstP, 3);
672  }
673  }
674  for(iv=0; iv<cascadeEvent_.cascadeNV; iv++){
675  vk = cascadeEvent_.cascadeVertexList[iv].get();
676  if(vk->nextCascadeVrt){
677  int pntCnst = vk->ConstraintList.size() - 1; // pointing constraint is always last in the list
678  if(vk->ConstraintList[pntCnst]->getType() != VKContraintType::Point) return -1;
679  static_cast< VKPointConstraint* >(vk->ConstraintList[pntCnst].get())->setTargetVertex(vk->nextCascadeVrt->refIterV);
680  }
681  }
682  return 0;
683 }
684 
685 void getFittedCascade( CascadeEvent & cascadeEvent_,
686  std::vector< Vect3DF > & cVertices,
687  std::vector< std::vector<double> > & covVertices,
688  std::vector< std::vector< VectMOM> > & fittedParticles,
689  std::vector< std::vector<double> > & cascadeCovar,
690  std::vector<double> & particleChi2,
691  std::vector<double> & fullCovar)
692 {
693  cVertices.clear();
694  covVertices.clear();
695  fittedParticles.clear();
696  particleChi2.clear();
697 //
698 // Split common covariance matrix into pieces
699 //
700  std::vector< std::vector<double> > cascadeCovarFit;
701  setFittedMatrices(cascadeEvent_.fullCovMatrix.get(), getCascadeNPar(cascadeEvent_), cascadeEvent_.matrixPnt, cascadeCovarFit, cascadeEvent_);
702 //
703  double vBx,vBy,vBz,pp2,pt,invR;
704  int iv,it,jt, NTRK, pnt;
705 //
706  int PDIM=getCascadeNPar(cascadeEvent_, 1); // number of physics parametrs
707  int ADIM=getCascadeNPar(cascadeEvent_, 0); // number of ALL parametrs
708  double **DPhys = new double*[PDIM]; for(it=0; it<PDIM; it++) DPhys[it] = new double[ADIM];
709  for(it=0;it<PDIM;it++) for(jt=0;jt<ADIM;jt++)DPhys[it][jt]=0.;
710 //
711 //
712  Vect3DF vrtPos;
713  VectMOM prtMom{};
714  VKVertex * vk;
715  std::vector<VectMOM> momCollector;
716  std::vector<double> tmpCov(6);
717 //
718  int pntPhys=0; // Counter for physics cascade parameters
719  for( iv=0; iv<cascadeEvent_.cascadeNV; iv++){
720  vk=cascadeEvent_.cascadeVertexList[iv].get();
721  vrtPos.X=vk->refIterV[0] + vk->fitV[0]; // target vertex for extrapolation
722  vrtPos.Y=vk->refIterV[1] + vk->fitV[1];
723  vrtPos.Z=vk->refIterV[2] + vk->fitV[2];
724  cVertices.push_back(vrtPos);
725  NTRK = vk->TrackList.size(); // Number of tracks at vertex
726  momCollector.clear();
727  int DIM=3*(NTRK+1);
728  double **Deriv = new double*[DIM]; for(it=0; it<DIM; it++) Deriv[it] = new double[DIM];
729  for(it=0;it<DIM;it++) for(jt=0;jt<DIM;jt++)Deriv[it][jt]=0.;
730  Deriv[0][0]=1.;Deriv[1][1]=1.;Deriv[2][2]=1.;
731  DPhys[pntPhys+0][cascadeEvent_.matrixPnt[iv]+0]=1.;
732  DPhys[pntPhys+1][cascadeEvent_.matrixPnt[iv]+1]=1.;
733  DPhys[pntPhys+2][cascadeEvent_.matrixPnt[iv]+2]=1.;
734  Trk::vkalMagFld::getMagFld(vk->refIterV[0]+vk->fitV[0], vk->refIterV[1]+vk->fitV[1], vk->refIterV[2]+vk->fitV[2],
735  vBx,vBy,vBz,(vk->vk_fitterControl).get());
736  for(it=0; it<NTRK; it++){
737  std::array<double, 4> pp = getFitParticleMom( vk->TrackList[it].get(), vBz );
738  prtMom.Px=pp[0]; prtMom.Py=pp[1]; prtMom.Pz=pp[2]; prtMom.E=pp[3];
739  momCollector.push_back( prtMom );
740  if(vk->TrackList[it]->Id >= 0) particleChi2.push_back( vk->TrackList[it]->Chi2 ); //Only real tracks
741  pp2 = pp[0]*pp[0] + pp[1]*pp[1] +pp[2]*pp[2];
742  pt = sqrt(pp[0]*pp[0] + pp[1]*pp[1]);
743  invR = vk->TrackList[it]->fitP[2];
744 
745  pnt = it*3+3;
746  DPhys[pntPhys+pnt+0][cascadeEvent_.matrixPnt[iv]+pnt+0]= Deriv[pnt+0][pnt+0]= 0 ; //dPx/dTheta
747  DPhys[pntPhys+pnt+0][cascadeEvent_.matrixPnt[iv]+pnt+1]= Deriv[pnt+0][pnt+1]= -pp[1]; //dPx/dPhi
748  DPhys[pntPhys+pnt+0][cascadeEvent_.matrixPnt[iv]+pnt+2]= Deriv[pnt+0][pnt+2]= -pp[0]/invR; //dPx/dinvR
749 
750  DPhys[pntPhys+pnt+1][cascadeEvent_.matrixPnt[iv]+pnt+0]= Deriv[pnt+1][pnt+0]= 0 ; //dPy/dTheta
751  DPhys[pntPhys+pnt+1][cascadeEvent_.matrixPnt[iv]+pnt+1]= Deriv[pnt+1][pnt+1]= pp[0]; //dPy/dPhi
752  DPhys[pntPhys+pnt+1][cascadeEvent_.matrixPnt[iv]+pnt+2]= Deriv[pnt+1][pnt+2]= -pp[1]/invR; //dPy/dinvR
753 
754  DPhys[pntPhys+pnt+2][cascadeEvent_.matrixPnt[iv]+pnt+0]= Deriv[pnt+2][pnt+0]= -pp2/pt; //dPz/dTheta
755  DPhys[pntPhys+pnt+2][cascadeEvent_.matrixPnt[iv]+pnt+1]= Deriv[pnt+2][pnt+1]= 0 ; //dPz/dPhi
756  DPhys[pntPhys+pnt+2][cascadeEvent_.matrixPnt[iv]+pnt+2]= Deriv[pnt+2][pnt+2]= -pp[2]/invR; //dPz/dinvR
757  }
758  pntPhys += DIM;
759  fittedParticles.push_back(momCollector);
760  cascadeCovar.push_back( transformCovar(DIM, Deriv, cascadeCovarFit[iv] ) ); //Transform covariance and save it
761  for(int kk=0; kk<6; kk++) tmpCov[kk]=cascadeCovar[iv][kk];
762  covVertices.push_back(tmpCov);
763  for(it=0; it<DIM; it++) delete[]Deriv[it];
764  delete[]Deriv;
765  }
766 //
767 // Get full physics covariance
768  int itn,jtn;
769  fullCovar.resize(PDIM*(PDIM+1)/2);
770  for(it=0; it<PDIM; it++){
771  for(jt=0; jt<=it; jt++){
772  double tmp=0.;
773  for(itn=0; itn<ADIM; itn++) for(jtn=0; jtn<ADIM; jtn++) tmp += DPhys[it][itn]*DPhys[jt][jtn]*cascadeEvent_.fullCovMatrix[itn*ADIM+jtn];
774  fullCovar[it*(it+1)/2+jt]=tmp; // symmetrical index formula works ONLY if it>=jt!!!
775  }
776  }
777  for(it=0; it<PDIM; it++) delete[]DPhys[it];
778  delete[]DPhys;
779 }
780 
781 
782 
783 } /* End of VKalVrtCore namespace */
Propagator.h
AllowedVariables::e
e
Definition: AsgElectronSelectorTool.cxx:37
Trk::VKTrack::cnstP
double cnstP[3]
Definition: TrkVKalVrtCoreBase.h:80
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::cfVrtDstSig
double cfVrtDstSig(VKVertex *vk, bool UseTrkErr)
Definition: cfVrtDst.cxx:33
Trk::cfdcopy
void cfdcopy(double *source, double *target, int n)
Definition: TrkVKalUtils.h:23
Trk::copyFullMtx
void copyFullMtx(const double *Input, long int IPar, long int IDIM, double *Target, long int TStart, long int TDIM)
Definition: CascadeUtils.cxx:246
Trk::vkalPropagator::checkTarget
static bool checkTarget(double *RefEnd)
Definition: Propagator.cxx:108
PowhegControl_ttHplus_NLO.ss
ss
Definition: PowhegControl_ttHplus_NLO.py:83
Trk::FullMTXfill
void FullMTXfill(VKVertex *vk, double *ader)
Definition: FullMtx.cxx:19
cfVrtDst.h
Trk::processCascadePV
int processCascadePV(CascadeEvent &cascadeEvent_, const double *primVrt, const double *primVrtCov)
Definition: CFitCascade.cxx:503
Trk::vkalMagFld::getMagFld
static void getMagFld(const double, const double, const double, double &, double &, double &, VKalVrtControlBase *)
Definition: VKalVrtBMag.cxx:24
Trk::transformCovar
std::vector< double > transformCovar(int NPar, double **Deriv, const std::vector< double > &covarI)
Definition: CascadeUtils.cxx:191
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
Trk::vkMSolve
int vkMSolve(double *a, double *b, long int n, double *ainv)
Definition: Tracking/TrkVertexFitter/TrkVKalVrtCore/src/Matrix.cxx:618
Trk::VKTrack::Chi2
double Chi2
Definition: TrkVKalVrtCoreBase.h:77
Trk::getVertexCharge
long int getVertexCharge(VKVertex *vk)
Definition: CFitCascade.cxx:71
Trk::VKContraintType::Point
@ Point
skel.it
it
Definition: skel.GENtoEVGEN.py:396
Trk::Vect3DF::Y
double Y
Definition: TrkVKalUtils.h:15
Trk::VKVertex::useApriorVertex
int useApriorVertex
Definition: TrkVKalVrtCoreBase.h:151
test_pyathena.pt
pt
Definition: test_pyathena.py:11
Trk::vtcfit
int vtcfit(VKVertex *vk)
Definition: VtCFit.cxx:293
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
Trk::getFittedCascade
void getFittedCascade(CascadeEvent &cascadeEvent_, std::vector< Vect3DF > &cVertices, std::vector< std::vector< double > > &covVertices, std::vector< std::vector< VectMOM > > &fittedParticles, std::vector< std::vector< double > > &cascadeCovar, std::vector< double > &particleChi2, std::vector< double > &fullCovar)
Definition: CFitCascade.cxx:685
Trk::VKVertex::refIterV
double refIterV[3]
Definition: TrkVKalVrtCoreBase.h:146
Trk::Vect3DF::Z
double Z
Definition: TrkVKalUtils.h:15
Trk::applyConstraints
void applyConstraints(VKVertex *vk)
Definition: stCnst.cxx:22
Trk::addCrossVertexDeriv
void addCrossVertexDeriv(CascadeEvent &cascadeEvent_, double *ader, long int MATRIXSIZE, const std::vector< int > &matrixPnt)
Definition: CascadeUtils.cxx:207
Trk::VKTrack::Id
long int Id
Definition: TrkVKalVrtCoreBase.h:72
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
Trk::VKTrack::refPerig
double refPerig[5]
Definition: TrkVKalVrtCoreBase.h:96
Trk::VKTrack::setReference
void setReference(const double[], const double[])
Definition: TrkVKalVrtCoreBase.cxx:76
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
Trk::combinedTrack
void combinedTrack(long int ICH, double *pv0, double *covi, double BMAG, double *par, double *covo)
Definition: XYZtrp.cxx:113
VtDeriv.h
Trk::getCascadeNPar
int getCascadeNPar(CascadeEvent &cascadeEvent_, int Type)
Definition: CascadeUtils.cxx:133
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::cascadeCnstRemnants
double cascadeCnstRemnants(CascadeEvent &cascadeEvent_)
Definition: CFitCascade.cxx:77
Trk::VKVertex::apriorVWGT
double apriorVWGT[6]
Definition: TrkVKalVrtCoreBase.h:153
Trk::fitVertexCascade
int fitVertexCascade(VKVertex *vk, int Pointing)
Definition: CFitCascade.cxx:89
cfTotCov.h
Trk::CascadeEvent::fullCovMatrix
std::unique_ptr< double[]> fullCovMatrix
Definition: TrkVKalVrtCoreBase.h:28
Trk::VKTrack::fitP
double fitP[3]
Definition: TrkVKalVrtCoreBase.h:76
Trk::CascadeEvent::matrixPnt
std::vector< int > matrixPnt
Definition: TrkVKalVrtCoreBase.h:31
TrkVKalVrtCoreBase.h
Trk::processCascade
int processCascade(CascadeEvent &cascadeEvent_)
Definition: CFitCascade.cxx:244
Trk::VKVertex::TrackList
std::vector< std::unique_ptr< VKTrack > > TrackList
Definition: TrkVKalVrtCoreBase.h:167
python.changerun.kk
list kk
Definition: changerun.py:41
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::VKPointConstraint
Definition: Derivt.h:87
Trk::VKVertex::includedVrt
std::vector< VKVertex * > includedVrt
Definition: TrkVKalVrtCoreBase.h:180
Trk::ForVrtClose::vrt
double vrt[3]
Definition: ForVrtClose.h:23
lumiFormat.i
int i
Definition: lumiFormat.py:85
PixelAthClusterMonAlgCfg.e4
e4
Definition: PixelAthClusterMonAlgCfg.py:332
Trk::VKVertex::setRefIterV
void setRefIterV(double v[]) noexcept
Definition: TrkVKalVrtCoreBase.cxx:148
Trk::VKVertex::fitMom
double fitMom[3]
Definition: TrkVKalVrtCoreBase.h:158
Trk::VKTrack::setCurrent
void setCurrent(const double[], const double[])
Definition: TrkVKalVrtCoreBase.cxx:70
Matrix.h
Trk::VKVertex::refV
double refV[3]
Definition: TrkVKalVrtCoreBase.h:148
Trk::VKVertex::passNearVertex
bool passNearVertex
Definition: TrkVKalVrtCoreBase.h:156
Trk::getCombinedVTrack
VKTrack * getCombinedVTrack(VKVertex *vk)
Definition: CascadeUtils.cxx:110
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
Trk::ForVrtClose::cvder
double cvder[12]
Definition: ForVrtClose.h:30
CFitCascade.h
grepfile.ic
int ic
Definition: grepfile.py:33
Trk::setFittedParameters
void setFittedParameters(const double *result, std::vector< int > &matrixPnt, CascadeEvent &cascadeEvent_)
Definition: CascadeUtils.cxx:151
Derivt.h
Trk::CascadeEvent::getAccuracyConstraint
double getAccuracyConstraint() const
Definition: TrkVKalVrtCoreBase.h:27
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::getFitParticleMom
std::array< double, 4 > getFitParticleMom(const VKTrack *trk, const VKVertex *vk)
Definition: cfMomentum.cxx:25
Trk::Vect3DF
Definition: TrkVKalUtils.h:14
Trk::CascadeEvent::nearPrmVertex
int nearPrmVertex
Definition: TrkVKalVrtCoreBase.h:24
Trk::Vect3DF::X
double X
Definition: TrkVKalUtils.h:15
Trk::VKVertex::cnstV
double cnstV[3]
Definition: TrkVKalVrtCoreBase.h:143
Trk::getNewCov
void getNewCov(const double *OldCov, const double *Der, double *Cov, long int DIM) noexcept
Definition: CascadeUtils.cxx:261
Trk::FullMCNSTfill
int FullMCNSTfill(VKVertex *vk, double *ader, double *LSide)
Definition: FullMtx.cxx:81
CascadeUtils.h
Trk::CascadeEvent
Definition: TrkVKalVrtCoreBase.h:21
Trk::VKTrack::setMass
void setMass(double M)
Definition: TrkVKalVrtCoreBase.h:101
Prompt::Def::Pt
@ Pt
Definition: VarHolder.h:76
Trk::setVTrackMass
int setVTrackMass(VKVertex *vk)
Definition: CFitCascade.cxx:34
Trk::CascadeEvent::cascadeNV
int cascadeNV
Definition: TrkVKalVrtCoreBase.h:23
Trk::restorePreviousPos
int restorePreviousPos(CascadeEvent &cascadeEvent_, std::vector< VKVertex > &SV)
Definition: CFitCascade.cxx:639
Trk::VKTrack::refCovar
double refCovar[15]
Definition: TrkVKalVrtCoreBase.h:97
Trk::VKVertex::Chi2
double Chi2
Definition: TrkVKalVrtCoreBase.h:139
Trk::VKVertex::fitCovXYZMom
double fitCovXYZMom[21]
Definition: TrkVKalVrtCoreBase.h:159
Trk::ForVrtClose::ywgt
double ywgt[3]
Definition: ForVrtClose.h:29
Trk::VKPointConstraint::setTargetVertex
void setTargetVertex(double VRT[3])
Definition: Derivt.h:93
XYZtrp.h
Trk::VKVertex::nextCascadeVrt
VKVertex * nextCascadeVrt
Definition: TrkVKalVrtCoreBase.h:179
Trk::VKVertex
Definition: TrkVKalVrtCoreBase.h:128
Trk::robtest
void robtest(VKVertex *vk, int ifl, int nIteration)
Definition: RobTest.cxx:14
Trk::VectMOM
Definition: TrkVKalUtils.h:21
Trk::translateToFittedPos
int translateToFittedPos(CascadeEvent &cascadeEvent_, double Step)
Definition: CFitCascade.cxx:559
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
calibdata.copy
bool copy
Definition: calibdata.py:27
Trk::fixPseudoTrackPt
int fixPseudoTrackPt(long int NPar, double *fullMtx, double *LSide, CascadeEvent &cascadeEvent_)
Definition: CascadeUtils.cxx:18
VtCFit.h
egammaEnergyPositionAllSamples::e0
double e0(const xAOD::CaloCluster &cluster)
return the uncorrected cluster energy in pre-sampler
FullMtx.h
Utilities.h
Trk::CascadeEvent::cascadeVertexList
std::vector< std::unique_ptr< VKVertex > > cascadeVertexList
Definition: TrkVKalVrtCoreBase.h:30
Trk::setFittedMatrices
void setFittedMatrices(const double *COVFIT, long int MATRIXSIZE, std::vector< int > &matrixPnt, std::vector< std::vector< double > > &covarCascade, CascadeEvent &cascadeEvent_)
Definition: CascadeUtils.cxx:168
Trk::ForVrtClose::covvrt
double covvrt[6]
Definition: ForVrtClose.h:23
Trk::VKVertex::passWithTrkCov
bool passWithTrkCov
Definition: TrkVKalVrtCoreBase.h:157
Trk::afterFitWithIniPar
int afterFitWithIniPar(VKVertex *vk, double *ader, double *dcv, double *ptot, double *VrtMomCov, const VKalVrtControlBase *CONTROL)
Definition: cfTotCov.cxx:80
ForCFT.h
python.SystemOfUnits.km
int km
Definition: SystemOfUnits.py:95
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