ATLAS Offline Software
Loading...
Searching...
No Matches
CFitCascade.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
23#include <array>
24#include <cmath>
25#include <iostream>
26
27
28namespace 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
71long 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
77double 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
89int 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() == VKConstraintType::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//
244int 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 if (fullNPar<0) return -1;
315 double * fullMatrix = new double[fullNPar*fullNPar];
316 double * iniCovMatrix = new double[fullNPar*fullNPar];for(int ss=0; ss<fullNPar*fullNPar; ss++) iniCovMatrix[ss]=0.;
317 double * fullLSide = new double[fullNPar];
318 double * tmpLSide = new double[fullNPar];
319 //std::unique_ptr<double[]> tmpLSide = std::unique_ptr<double[]>(new double[fullNPar])
320 std::vector<VKVertex> listVCopy(cascadeEvent_.cascadeNV);
321//-------------------------------------------------------
322// Now fit with pointing constraint
323//
324 cascadeEvent_.matrixPnt.resize(cascadeEvent_.cascadeNV);
325 long int NParCur, NStart;
326 int getBack=0; // counter of oscillations
327 int fullSTOP=0; // immediate stop iteration flag
328 double Chi2Diff=0.;
329
330 int NFitIterationMax=100; // Maximal amount of iterations
331 int badStepCountMax=5; // Maximal amount of bad steps
332
333 cnstRemnants=100000.; double cnstProgr=1.; double minCnstRemnants=100000.;
334 int badStepCount=0;
335
336 for(Iter=0; Iter<=NFitIterationMax; Iter++){
337 Chi2Cur=0.;
338 NStart=0;
339 for( iv=0; iv<fullNPar*fullNPar; iv++)fullMatrix[iv]=0.; // zero full matrix
340 for( iv=0; iv<cascadeEvent_.cascadeNV; iv++){
341 vk = cascadeEvent_.cascadeVertexList[iv].get();
342//
343//Calculate derivatives for "passing near" cnst. Initial vertex position is used for derivatives.
344//Results are saved in ForVRTClose structure
345 if(cascadeEvent_.nearPrmVertex && iv==(cascadeEvent_.cascadeNV-1)){ //only last vertex in cascade may have it
346 double dparst[6]={vk->refIterV[0]+vk->iniV[0], vk->refIterV[1]+vk->iniV[1], vk->refIterV[2]+vk->iniV[2],
347 vk->fitMom[0], vk->fitMom[1], vk->fitMom[2] };
348 vk->FVC.Charge=getVertexCharge(vk);
349 if(vk->FVC.Charge!=0)vk->FVC.Charge=std::copysign(1,vk->FVC.Charge);
350 vpderiv(vk->passWithTrkCov, vk->FVC.Charge, dparst, vk->fitCovXYZMom,
351 vk->FVC.vrt, vk->FVC.covvrt, vk->FVC.cvder, vk->FVC.ywgt, vk->FVC.rv0, (vk->vk_fitterControl).get());
352 }
353 if (vk->vk_fitterControl->vk_forcft.irob != 0) {robtest(vk, 0, Iter);} // ROBUSTIFICATION new data structure
354 if (vk->vk_fitterControl->vk_forcft.irob != 0) {robtest(vk, 1, Iter);} // ROBUSTIFICATION new data structure
355 IERR = fitVertexCascade( vk, 1 ); if(IERR) break; //with passNear for last vertex in cascade if needed
356 IERR = setVTrackMass(vk); if(IERR) break; //mass of combined particle
357//
358//Get full constraint matrix and left side for vertex
359 cascadeEvent_.matrixPnt[iv]=NStart;
360 NParCur = FullMCNSTfill( vk, vk->ader, tmpLSide);
361//
362//Move them to cascade full matrix and left side
363 copyFullMtx( vk->ader, NParCur, NParCur, fullMatrix, NStart, fullNPar);
364//
365//Copy error matrix for left side vector (measured part T,U1,..,Un - see Billoir)
366// to correct place in iniCovMatrix matrix. Only at last step and without constraint part!!! CHECK IT!!!
367 if(Iter==NFitIterationMax || fullSTOP || badStepCount>=badStepCountMax)
368 copyFullMtx( vk->ader, 3+3*vk->TrackList.size(), NParCur, iniCovMatrix, NStart, fullNPar);
369//
370// Fill left part of the system
371 for(i=0; i<NParCur; i++) fullLSide[i+NStart] = tmpLSide[i];
372 NStart += NParCur;
373 Chi2Cur += vk->Chi2;
374//std::cout<<iv<<"--------Chi2="<<vk->Chi2<<", "<<cascadeEvent_.nearPrmVertex<<" nstart="<<NStart<<'\n';
375 }
376 if( (Chi2Cur>1.e8 && Iter>0) || IERR){
377 delete[] fullMatrix; delete[] fullLSide; delete[] tmpLSide; delete[] iniCovMatrix;
378 if(Chi2Cur>1.e8) return -1;
379 return IERR;
380 }
381//
382//--- Attempt to dump oscillations by returning to good position
383 cnstProgr=cascadeCnstRemnants(cascadeEvent_)/cnstRemnants;
384 if( Iter>3 && cnstProgr>4. && getBack<5 && fullSTOP==0 ) { //------ Bad previous step discovered.
385 //std::cout<<" oscillation discovered="<<Iter<<" progr="<<cnstProgr<<'\n';
386 IERR=restorePreviousPos(cascadeEvent_, listVCopy );
387 if(IERR){ delete[] fullMatrix; delete[] fullLSide; delete[] tmpLSide; delete[] iniCovMatrix; return IERR;}
388 cnstRemnants=100000.; Chi2Old+=10000; // to skip restoring on next iteration
389 if(Iter==NFitIterationMax )Iter-=2; // to give time to converge after this operation
390 if(Iter==NFitIterationMax-1)Iter-=1; // to give time to converge after this operation
391 getBack++; badStepCount=0;
392 continue;
393 } //--------- Make some copy of vertices for safety
394 cnstRemnants*=cnstProgr; cnstRemnants += 1.e-6*cascadeEvent_.getAccuracyConstraint(); //VK Protection against 0
395 if(cnstRemnants<minCnstRemnants)minCnstRemnants=cnstRemnants;
396 if(minCnstRemnants==cnstRemnants){ //--------- Make copy of vertices for safety at best point
397 for( iv=0; iv<cascadeEvent_.cascadeNV; iv++){
398 listVCopy.at(iv)=*(cascadeEvent_.cascadeVertexList[iv]); // vertex list copy
399 }
400 }
401//--------------------------------------------------------------------------
402//for( iv=0; iv<fullNPar; iv++)std::cout<<fullLSide[iv]<<", ";std::cout<<'\n';
403// std::cout<<fullLSide[3+3*2]<<", "<<fullLSide[3+3*2+1]<<", "<<
404// fullLSide[20]<<", "<<fullLSide[21]<<", "<<fullLSide[22]<<'\n';
405//---------------------------------------------------------------------------
406//
407// Add cross vertices derivatives
408 addCrossVertexDeriv(cascadeEvent_, fullMatrix, fullNPar, cascadeEvent_.matrixPnt);
409//
410// Add pseudotrack momentum fix
411//
412 int tstRet=fixPseudoTrackPt(fullNPar, fullMatrix, fullLSide, cascadeEvent_ );
413 if( tstRet ){ delete[] fullMatrix; delete[] fullLSide; delete[] tmpLSide; delete[] iniCovMatrix; return -1; }
414//
415// Resolve full cascade with constraints system
416//
417 if( Iter<NFitIterationMax && fullSTOP==0 && badStepCount<badStepCountMax){ //Normal step. Solution of system only
418 IERR = vkMSolve(fullMatrix, fullLSide, fullNPar);
419 if(IERR){ delete[] fullMatrix; delete[] fullLSide; delete[] tmpLSide; delete[] iniCovMatrix;return IERR;}
420 }else{ //Last step. Solution+full error matrix
421 cascadeEvent_.fullCovMatrix.reset( new double[fullNPar*fullNPar] ); //Create fresh matrix
422 IERR = vkMSolve(fullMatrix, fullLSide, fullNPar, cascadeEvent_.fullCovMatrix.get());
423 if(IERR){ delete[] fullMatrix; delete[] fullLSide; delete[] tmpLSide; delete[] iniCovMatrix;
424 cascadeEvent_.fullCovMatrix.reset(); return IERR;}
425//std::cout<<"fulcov="; for(int tt=0; tt<fullNPar; tt++)std::cout<<cascadeEvent_.fullCovMatrix[tt*fullNPar+tt]<<", "; std::cout<<'\n';
426 std::unique_ptr<double[]> newCov(new double[fullNPar*fullNPar]); //Check via error transfer from left side (measured values). Gives exactly the same errors - correct!!!
427 getNewCov(iniCovMatrix, cascadeEvent_.fullCovMatrix.get(), newCov.get(), fullNPar);
428 cascadeEvent_.fullCovMatrix=std::move(newCov); //Unique_ptr will handle deletion automatically
429 }
430//
431// Set fitted parameters
432//
433 setFittedParameters( fullLSide, cascadeEvent_.matrixPnt, cascadeEvent_ );
434//
435// Update pointing constraints and calculate real cascade Chi2
436//
437 double Chi2Full=0.;
438 for(iv=0; iv<cascadeEvent_.cascadeNV; iv++){
439 vk = cascadeEvent_.cascadeVertexList[iv].get();
440 for(int it=0; it<(int)vk->TrackList.size(); it++){
441 VKTrack * trk=vk->TrackList[it].get(); if(trk->Id >= 0)Chi2Full+=trk->Chi2; // real track in cascade
442 }
443 if(cascadeEvent_.nearPrmVertex && iv==(cascadeEvent_.cascadeNV-1)){ //only last vertex in cascade may have it
444 double signift = cfVrtDstSig( vk, vk->passWithTrkCov);
445 Chi2Full += signift*signift;
446 }
447 }
448 Chi2Diff=Chi2Old-Chi2Full;
449 if(Chi2Diff<0. && cnstProgr>0.99) badStepCount++;
450 if(cnstRemnants==minCnstRemnants || cnstProgr<0.9) badStepCount=0;
451//std::cout.precision(5); std::cout<<" iter="<<Iter<<" separ="<<Chi2Cur<<" full="<<Chi2Full<<" iter diff="<<Chi2Full/Chi2Cur<<
452//" cnstrem="<<cnstRemnants<<" progr="<<cnstProgr<<" lim="<<cnstRemnants/minCnstRemnants<<" bstep="<<badStepCount<<'\n';
453 bool badFullStep=false;
454 if( Iter>5 && Chi2Full/Chi2Cur>1.2) badFullStep=true; //VK 16.04.2013 New strategy
455 if( Iter==NFitIterationMax || fullSTOP ) badFullStep=false; //VK 16.04.2013 No step limitation on last iteration
456//
457// Prepare next iteration
458//
459 if(badFullStep) IERR = translateToFittedPos(cascadeEvent_,0.3);
460 else IERR = translateToFittedPos(cascadeEvent_);
461 if(IERR){ delete[] fullMatrix; delete[] fullLSide; delete[] tmpLSide; delete[] iniCovMatrix; return IERR;}
462
463 for(iv=0; iv<cascadeEvent_.cascadeNV; iv++){
464 vk = cascadeEvent_.cascadeVertexList[iv].get();
465 if(vk->nextCascadeVrt){
466 int pntCnst = vk->ConstraintList.size() - 1; // pointing constraint is always last in the list
467 VKPointConstraint * pcnst = dynamic_cast<VKPointConstraint*>(vk->ConstraintList[pntCnst].get());
469 }
470 }
471//
472
473 if(fullSTOP) break;
474 if(cnstRemnants>1.e4&&Iter>10) //no way to fulfil constraints
475 { delete[] fullMatrix; delete[] fullLSide; delete[] tmpLSide; delete[] iniCovMatrix; return -2;}
476//
477 if( Iter<NFitIterationMax && Iter>2){
478 if(std::abs(Chi2Diff)<0.001 && cnstRemnants/minCnstRemnants<10.){ //stable cascade position before end of cycling
479 NFitIterationMax=Iter+1; //then makes additional iteration to get the full error matrix
480 }
481 if(cnstRemnants<cascadeEvent_.getAccuracyConstraint()) fullSTOP++; //Good constraint accuracy is reached
482 }
483 if ( Iter>NFitIterationMax+50 ) break; //Protection - too many iterations due to whatever reason.
484 if(badStepCount>badStepCountMax)break; //Divergence discovered (in both cases the full error matrix is ready!!!)
485
486 Chi2Old=Chi2Full;
487 }
488
489 //if(tmpc0)std::cout<<(*tmpc0)<<'\n';
490 //if(tmpc1)std::cout<<(*tmpc1)<<'\n';
491
492 delete[] fullMatrix; delete[] fullLSide; delete[] tmpLSide; delete[] iniCovMatrix;
493//-------------------------------- Check constraints status
494 cnstRemnants=cascadeCnstRemnants(cascadeEvent_);
495//std::cout<<"fullcnst="<<cnstRemnants<<" lim="<<cnstRemnants/minCnstRemnants<<'\n';
496 if( cnstRemnants > 1.e0) return -2; /* Constraints are not resolved. Stop fit */
497 return 0;
498}
499
500//-----------------------------------------------------------------------------------
501//
502// Iteration over complete cascade with first cascade vertex in Primary Vertex
503//
504 int processCascadePV(CascadeEvent & cascadeEvent_, const double *primVrt, const double *primVrtCov )
505{
506 double aermd[6],tmpd[6]; // temporary arrays
507 VKVertex * vk = cascadeEvent_.cascadeVertexList[cascadeEvent_.cascadeNV-1].get(); //Main vertex
508
509 vk->vk_fitterControl->vk_forcft.vrt[0] = primVrt[0];
510 vk->vk_fitterControl->vk_forcft.vrt[1] = primVrt[1];
511 vk->vk_fitterControl->vk_forcft.vrt[2] = primVrt[2];
512 vk->vk_fitterControl->vk_forcft.covvrt[0] = primVrtCov[0];
513 vk->vk_fitterControl->vk_forcft.covvrt[1] = primVrtCov[1];
514 vk->vk_fitterControl->vk_forcft.covvrt[2] = primVrtCov[2];
515 vk->vk_fitterControl->vk_forcft.covvrt[3] = primVrtCov[3];
516 vk->vk_fitterControl->vk_forcft.covvrt[4] = primVrtCov[4];
517 vk->vk_fitterControl->vk_forcft.covvrt[5] = primVrtCov[5];
518
519 vk->useApriorVertex = 1;
520 cfdcopy(vk->vk_fitterControl->vk_forcft.covvrt, tmpd, 6);
521 int IERR=cfdinv(tmpd, aermd, -3); if (IERR) { IERR = -4; return IERR; }
522 cfdcopy(vk->vk_fitterControl->vk_forcft.vrt, vk->apriorV, 3);
523 cfdcopy( aermd, vk->apriorVWGT,6);
524
525 return processCascade(cascadeEvent_);
526}
527
528//-----------------------------------------------------------------------------------
529//
530// Iteration over complete cascade with "close to primary vertex" Chi2 term
531//
532 int processCascade(CascadeEvent & cascadeEvent_, const double *primVrt, const double *primVrtCov )
533{
534 cascadeEvent_.nearPrmVertex=1; //setting up additional Chi2 term
535 VKVertex * vk = cascadeEvent_.cascadeVertexList[cascadeEvent_.cascadeNV-1].get(); //Main vertex
536 vk->passNearVertex =true; // For fitting machinery
537 vk->passWithTrkCov =true; // For fitting machinery
538 std::copy(primVrt, primVrt+3, vk->FVC.vrt);
539 std::copy(primVrtCov, primVrtCov+6, vk->FVC.covvrt);
540 return processCascade(cascadeEvent_);
541}
542//-----------------------------------------------------------------------------------
543//
544// Iteration over complete cascade with exact pointing to primary vertex
545//
546 int processCascade(CascadeEvent & cascadeEvent_, double *primVrt )
547{
548 VKVertex * vk = cascadeEvent_.cascadeVertexList[cascadeEvent_.cascadeNV-1].get(); //Main vertex
549 long int NTRK = vk->TrackList.size();
550 vk->ConstraintList.emplace_back(new VKPointConstraint( NTRK, primVrt, vk, false));
551 cascadeEvent_.nearPrmVertex=0; //explicitly turn off additional Chi2 term
552 return processCascade(cascadeEvent_);
553}
554
555
556//----------------------------------------------------------------------
557// Translate all external (physics) tracks to fitted vertices positions
558// Step limitation is needed to break positive feedback
559//
560 int translateToFittedPos(CascadeEvent & cascadeEvent_, double Step )
561{
562 int iv,it;
563 long int IERR,NTRK;
564 double vShift, tmpPer[5], tmpWgt[15], tmpCov[15], targetVertex[3];
565 VKTrack * trk; VKVertex * vk;
566 if(Step>1.)Step=1.;
567
568 for( iv=0; iv<cascadeEvent_.cascadeNV; iv++){
569 vk=cascadeEvent_.cascadeVertexList[iv].get();
570 NTRK = vk->TrackList.size(); // Number of tracks at vertex
571 targetVertex[0]=vk->refIterV[0] + vk->fitV[0]*Step; // target vertex for extrapolation
572 targetVertex[1]=vk->refIterV[1] + vk->fitV[1]*Step;
573 targetVertex[2]=vk->refIterV[2] + vk->fitV[2]*Step;
574 vShift = sqrt( (vk->refV[0]-targetVertex[0])*(vk->refV[0]-targetVertex[0])
575 +(vk->refV[1]-targetVertex[1])*(vk->refV[1]-targetVertex[1])
576 +(vk->refV[2]-targetVertex[2])*(vk->refV[2]-targetVertex[2]) );
577 for(auto *pvx : vk->includedVrt){ //Check space position of internal vertex
578 double dirMom=(pvx->refIterV[0]-targetVertex[0])*pvx->fitMom[0]+
579 (pvx->refIterV[1]-targetVertex[1])*pvx->fitMom[1]+
580 (pvx->refIterV[2]-targetVertex[2])*pvx->fitMom[2];
581 if(dirMom<0.)cfdcopy(pvx->refIterV,targetVertex,3);
582 }
583 bool insideGoodVolume=false;
584 if(vk->vk_fitterControl && vk->vk_fitterControl->vk_objProp)
585 { insideGoodVolume = vk->vk_fitterControl->vk_objProp->checkTarget(targetVertex, *vk->vk_fitterControl->vk_istate);}
586 else { insideGoodVolume = Trk::vkalPropagator::checkTarget(targetVertex); }
587 if(!insideGoodVolume) { return -16; } //Vertex is definitely outside working volume
588 for(it=0; it<NTRK; it++){
589 trk=vk->TrackList[it].get();
590 if(trk->Id < 0){ // pseudo-track from cascade vertex
591 trk->fitP[0] =trk->iniP[0]+ Step*(trk->fitP[0]-trk->iniP[0]);
592 trk->fitP[1] =trk->iniP[1]+ Step*(trk->fitP[1]-trk->iniP[1]);
593 trk->fitP[2] =trk->iniP[2]+ Step*(trk->fitP[2]-trk->iniP[2]);
594 continue;
595 }
596 Trk::vkalPropagator::Propagate(trk, vk->refV, targetVertex, tmpPer, tmpCov, (vk->vk_fitterControl).get());
597 //Check!!!And protection if needed.
598 double eig5=cfSmallEigenvalue(tmpCov,5 );
599 if(eig5<1.e-15 || tmpCov[0]>1.e7) { //Bad propagation with material. Try without it.
600 Trk::vkalPropagator::Propagate(-999, trk->Charge,trk->refPerig,trk->refCovar, vk->refV, targetVertex, tmpPer, tmpCov, (vk->vk_fitterControl).get());
601 if(cfSmallEigenvalue(tmpCov,5 )<1.e-15){ //Final protection
602 tmpCov[1]=0.;tmpCov[3]=0.;tmpCov[6]=0.;tmpCov[10]=0.;
603 tmpCov[4]=0.;tmpCov[7]=0.;tmpCov[11]=0.;
604 tmpCov[8]=0.;tmpCov[12]=0.;
605 tmpCov[13]=0.;
606 tmpCov[0]=std::abs(tmpCov[0]); tmpCov[2]=std::abs(tmpCov[2]);tmpCov[5]=std::abs(tmpCov[5]);
607 tmpCov[9]=std::abs(tmpCov[9]); tmpCov[14]=std::abs(tmpCov[14]);
608 }
609 }
610 if(tmpCov[0]>1.e7){ IERR=-7; return IERR; } //extremely big A0 error !!!
611 IERR=cfInv5(tmpCov, tmpWgt); if (IERR) IERR=cfdinv(tmpCov, tmpWgt, 5); if(IERR)return -8;
612 trk->setCurrent(tmpPer,tmpWgt);
613 if ( vShift > 100. ) trk->setReference( tmpPer, tmpCov ); //Change reference for big shift
614 }
615 vk->setRefIterV(targetVertex);
616 if ( vShift > 100. )vk->setRefV(targetVertex); // Change reference vertex for big shift
617 vk->iniV[0] = vk->fitV[0] = vk->cnstV[0]=0.;
618 vk->iniV[1] = vk->fitV[1] = vk->cnstV[1]=0.;
619 vk->iniV[2] = vk->fitV[2] = vk->cnstV[2]=0.;
620 for(it=0; it<NTRK; it++){
621 trk=vk->TrackList[it].get();
622 if(Step<1.){ // Step limitation for constraint calculation on next step
623 trk->cnstP[0] = trk->iniP[0] =trk->iniP[0]+ Step*(trk->fitP[0]-trk->iniP[0]);
624 trk->cnstP[1] = trk->iniP[1] =trk->iniP[1]+ Step*(trk->fitP[1]-trk->iniP[1]);
625 trk->cnstP[2] = trk->iniP[2] =trk->iniP[2]+ Step*(trk->fitP[2]-trk->iniP[2]);
626 }else{
627 trk->cnstP[0] = trk->iniP[0] = trk->fitP[0]; // for constraint calculation on next step
628 trk->cnstP[1] = trk->iniP[1] = trk->fitP[1];
629 trk->cnstP[2] = trk->iniP[2] = trk->fitP[2];
630 }
631 }
632 }
633 return 0;
634}
635
636//----------------------------------------------------------------------
637// Translate all external (physics) tracks to fitted vertices positions
638// Step limitation is needed to break positive feedback
639//
640int restorePreviousPos(CascadeEvent & cascadeEvent_, std::vector<VKVertex> & SV )
641{
642 int iv,it;
643 long int NTRK;
644 VKTrack * trk; VKTrack * trks; VKVertex * vk; VKVertex * vks;
645
646 for( iv=0; iv<cascadeEvent_.cascadeNV; iv++){
647 vk=cascadeEvent_.cascadeVertexList[iv].get();
648 vks=&SV[iv];
649 NTRK = vk->TrackList.size(); // Number of tracks at vertex
650 vk->refIterV[0]=vks->refIterV[0];
651 vk->refIterV[1]=vks->refIterV[1];
652 vk->refIterV[2]=vks->refIterV[2];
653 vk->iniV[0] = vk->fitV[0] = vk->cnstV[0]=0.;
654 vk->iniV[1] = vk->fitV[1] = vk->cnstV[1]=0.;
655 vk->iniV[2] = vk->fitV[2] = vk->cnstV[2]=0.;
656 cfdcopy(vks->fitMom, vk->fitMom, 3); //saved Momentum
657 cfdcopy(vks->fitCovXYZMom, vk->fitCovXYZMom, 21); //saved XYZMom covariance
658 for(it=0; it<NTRK; it++){
659 trk =vk ->TrackList[it].get(); // working track
660 trks=vks->TrackList[it].get(); // track from saved copy
661 if(trk->Id < 0) { // pseudo-track from cascade vertex
662 //trk->fitP[2]=0.; // reset the pseudo-track parameters
663 trk->fitP[0] =(trks->iniP[0]+trks->fitP[0])/2.;
664 trk->fitP[1] = trks->iniP[1];
665 trk->fitP[2] =(trks->iniP[2]+trks->fitP[2])/2.;
666 continue;
667 }
668 cfdcopy(trks->Perig, trk->Perig, 5);
669 cfdcopy(trks->WgtM, trk->WgtM, 15);
670 cfdcopy(trks->fitP, trk->fitP, 3);
671 cfdcopy(trks->iniP, trk->iniP, 3);
672 cfdcopy(trks->cnstP, trk->cnstP, 3);
673 }
674 }
675 for(iv=0; iv<cascadeEvent_.cascadeNV; iv++){
676 vk = cascadeEvent_.cascadeVertexList[iv].get();
677 if(vk->nextCascadeVrt){
678 int pntCnst = vk->ConstraintList.size() - 1; // pointing constraint is always last in the list
679 if(vk->ConstraintList[pntCnst]->getType() != VKConstraintType::Point) return -1;
680 static_cast< VKPointConstraint* >(vk->ConstraintList[pntCnst].get())->setTargetVertex(vk->nextCascadeVrt->refIterV);
681 }
682 }
683 return 0;
684}
685
686void getFittedCascade( CascadeEvent & cascadeEvent_,
687 std::vector< Vect3DF > & cVertices,
688 std::vector< std::vector<double> > & covVertices,
689 std::vector< std::vector< VectMOM> > & fittedParticles,
690 std::vector< std::vector<double> > & cascadeCovar,
691 std::vector<double> & particleChi2,
692 std::vector<double> & fullCovar)
693{
694 cVertices.clear();
695 covVertices.clear();
696 fittedParticles.clear();
697 particleChi2.clear();
698//
699// Split common covariance matrix into pieces
700//
701 std::vector< std::vector<double> > cascadeCovarFit;
702 setFittedMatrices(cascadeEvent_.fullCovMatrix.get(), getCascadeNPar(cascadeEvent_), cascadeEvent_.matrixPnt, cascadeCovarFit, cascadeEvent_);
703//
704 double vBx,vBy,vBz,pp2,pt,invR;
705 int iv,it,jt, NTRK, pnt;
706//
707 int PDIM=getCascadeNPar(cascadeEvent_, 1); // number of physics parametrs
708 int ADIM=getCascadeNPar(cascadeEvent_, 0); // number of ALL parametrs
709 double **DPhys = new double*[PDIM]; for(it=0; it<PDIM; it++) DPhys[it] = new double[ADIM];
710 for(it=0;it<PDIM;it++) for(jt=0;jt<ADIM;jt++)DPhys[it][jt]=0.;
711//
712//
713 Vect3DF vrtPos;
714 VectMOM prtMom{};
715 VKVertex * vk;
716 std::vector<VectMOM> momCollector;
717 std::vector<double> tmpCov(6);
718//
719 int pntPhys=0; // Counter for physics cascade parameters
720 for( iv=0; iv<cascadeEvent_.cascadeNV; iv++){
721 vk=cascadeEvent_.cascadeVertexList[iv].get();
722 vrtPos.X=vk->refIterV[0] + vk->fitV[0]; // target vertex for extrapolation
723 vrtPos.Y=vk->refIterV[1] + vk->fitV[1];
724 vrtPos.Z=vk->refIterV[2] + vk->fitV[2];
725 cVertices.push_back(vrtPos);
726 NTRK = vk->TrackList.size(); // Number of tracks at vertex
727 momCollector.clear();
728 int DIM=3*(NTRK+1);
729 double **Deriv = new double*[DIM]; for(it=0; it<DIM; it++) Deriv[it] = new double[DIM];
730 for(it=0;it<DIM;it++) for(jt=0;jt<DIM;jt++)Deriv[it][jt]=0.;
731 Deriv[0][0]=1.;Deriv[1][1]=1.;Deriv[2][2]=1.;
732 DPhys[pntPhys+0][cascadeEvent_.matrixPnt[iv]+0]=1.;
733 DPhys[pntPhys+1][cascadeEvent_.matrixPnt[iv]+1]=1.;
734 DPhys[pntPhys+2][cascadeEvent_.matrixPnt[iv]+2]=1.;
735 Trk::vkalMagFld::getMagFld(vk->refIterV[0]+vk->fitV[0], vk->refIterV[1]+vk->fitV[1], vk->refIterV[2]+vk->fitV[2],
736 vBx,vBy,vBz,(vk->vk_fitterControl).get());
737 for(it=0; it<NTRK; it++){
738 std::array<double, 4> pp = getFitParticleMom( vk->TrackList[it].get(), vBz );
739 prtMom.Px=pp[0]; prtMom.Py=pp[1]; prtMom.Pz=pp[2]; prtMom.E=pp[3];
740 momCollector.push_back( prtMom );
741 if(vk->TrackList[it]->Id >= 0) particleChi2.push_back( vk->TrackList[it]->Chi2 ); //Only real tracks
742 pp2 = pp[0]*pp[0] + pp[1]*pp[1] +pp[2]*pp[2];
743 pt = sqrt(pp[0]*pp[0] + pp[1]*pp[1]);
744 invR = vk->TrackList[it]->fitP[2];
745
746 pnt = it*3+3;
747 DPhys[pntPhys+pnt+0][cascadeEvent_.matrixPnt[iv]+pnt+0]= Deriv[pnt+0][pnt+0]= 0 ; //dPx/dTheta
748 DPhys[pntPhys+pnt+0][cascadeEvent_.matrixPnt[iv]+pnt+1]= Deriv[pnt+0][pnt+1]= -pp[1]; //dPx/dPhi
749 DPhys[pntPhys+pnt+0][cascadeEvent_.matrixPnt[iv]+pnt+2]= Deriv[pnt+0][pnt+2]= -pp[0]/invR; //dPx/dinvR
750
751 DPhys[pntPhys+pnt+1][cascadeEvent_.matrixPnt[iv]+pnt+0]= Deriv[pnt+1][pnt+0]= 0 ; //dPy/dTheta
752 DPhys[pntPhys+pnt+1][cascadeEvent_.matrixPnt[iv]+pnt+1]= Deriv[pnt+1][pnt+1]= pp[0]; //dPy/dPhi
753 DPhys[pntPhys+pnt+1][cascadeEvent_.matrixPnt[iv]+pnt+2]= Deriv[pnt+1][pnt+2]= -pp[1]/invR; //dPy/dinvR
754
755 DPhys[pntPhys+pnt+2][cascadeEvent_.matrixPnt[iv]+pnt+0]= Deriv[pnt+2][pnt+0]= -pp2/pt; //dPz/dTheta
756 DPhys[pntPhys+pnt+2][cascadeEvent_.matrixPnt[iv]+pnt+1]= Deriv[pnt+2][pnt+1]= 0 ; //dPz/dPhi
757 DPhys[pntPhys+pnt+2][cascadeEvent_.matrixPnt[iv]+pnt+2]= Deriv[pnt+2][pnt+2]= -pp[2]/invR; //dPz/dinvR
758 }
759 pntPhys += DIM;
760 fittedParticles.push_back(momCollector);
761 cascadeCovar.push_back( transformCovar(DIM, Deriv, cascadeCovarFit[iv] ) ); //Transform covariance and save it
762 for(int kk=0; kk<6; kk++) tmpCov[kk]=cascadeCovar[iv][kk];
763 covVertices.push_back(tmpCov);
764 for(it=0; it<DIM; it++) delete[]Deriv[it];
765 delete[]Deriv;
766 }
767//
768// Get full physics covariance
769 int itn,jtn;
770 fullCovar.resize(PDIM*(PDIM+1)/2);
771 for(it=0; it<PDIM; it++){
772 for(jt=0; jt<=it; jt++){
773 double tmp=0.;
774 for(itn=0; itn<ADIM; itn++) for(jtn=0; jtn<ADIM; jtn++) tmp += DPhys[it][itn]*DPhys[jt][jtn]*cascadeEvent_.fullCovMatrix[itn*ADIM+jtn];
775 fullCovar[it*(it+1)/2+jt]=tmp; // symmetrical index formula works ONLY if it>=jt!!!
776 }
777 }
778 for(it=0; it<PDIM; it++) delete[]DPhys[it];
779 delete[]DPhys;
780}
781
782
783
784} /* End of VKalVrtCore namespace */
static Double_t ss
double getAccuracyConstraint() const
std::vector< int > matrixPnt
std::unique_ptr< double[]> fullCovMatrix
std::vector< std::unique_ptr< VKVertex > > cascadeVertexList
void setTargetVertex(double VRT[3])
Definition Derivt.h:95
double refCovar[15]
void setReference(const double[], const double[])
void setCurrent(const double[], const double[])
void setMass(double M)
void setRefIterV(double v[]) noexcept
std::vector< VKVertex * > includedVrt
std::vector< std::unique_ptr< VKTrack > > TrackList
double ader[(3 *vkalNTrkM+3) *(3 *vkalNTrkM+3)]
std::vector< std::unique_ptr< VKConstraintBase > > ConstraintList
double fitCovXYZMom[21]
void setRefV(double v[3]) noexcept
VKVertex * nextCascadeVrt
std::unique_ptr< VKalVrtControl > vk_fitterControl
static void getMagFld(const double, const double, const double, double &, double &, double &, const VKalVrtControlBase *)
static bool checkTarget(double *RefEnd)
static void Propagate(long int TrkID, long int Charge, double *ParOld, double *CovOld, double *RefStart, double *RefEnd, double *ParNew, double *CovNew, VKalVrtControlBase *FitControl=0)
Ensure that the ATLAS eigen extensions are properly loaded.
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
void cfdcopy(double *source, double *target, int n)
void FullMTXfill(VKVertex *vk, double *ader)
Definition FullMtx.cxx:19
void getNewCov(const double *OldCov, const double *Der, double *Cov, long int DIM) noexcept
int translateToFittedPos(CascadeEvent &cascadeEvent_, double Step)
void setFittedParameters(const double *result, std::vector< int > &matrixPnt, CascadeEvent &cascadeEvent_)
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)
int fixPseudoTrackPt(long int NPar, double *fullMtx, double *LSide, CascadeEvent &cascadeEvent_)
int cfInv5(double *cov, double *wgt)
int processCascade(CascadeEvent &cascadeEvent_)
double cascadeCnstRemnants(CascadeEvent &cascadeEvent_)
int cfdinv(double *cov, double *wgt, long int NI)
void copyFullMtx(const double *Input, long int IPar, long int IDIM, double *Target, long int TStart, long int TDIM)
int setVTrackMass(VKVertex *vk)
void setFittedMatrices(const double *COVFIT, long int MATRIXSIZE, std::vector< int > &matrixPnt, std::vector< std::vector< double > > &covarCascade, CascadeEvent &cascadeEvent_)
int getCascadeNPar(CascadeEvent &cascadeEvent_, int Type)
int afterFitWithIniPar(VKVertex *vk, double *ader, double *dcv, double *ptot, double *VrtMomCov, const VKalVrtControlBase *CONTROL)
Definition cfTotCov.cxx:83
VKTrack * getCombinedVTrack(VKVertex *vk)
int FullMCNSTfill(VKVertex *vk, double *ader, double *LSide)
Definition FullMtx.cxx:81
void addCrossVertexDeriv(CascadeEvent &cascadeEvent_, double *ader, long int MATRIXSIZE, const std::vector< int > &matrixPnt)
int fitVertexCascade(VKVertex *vk, int Pointing)
std::vector< double > transformCovar(int NPar, double **Deriv, const std::vector< double > &covarI)
int vtcfit(VKVertex *vk)
Definition VtCFit.cxx:293
long int getVertexCharge(VKVertex *vk)
int restorePreviousPos(CascadeEvent &cascadeEvent_, std::vector< VKVertex > &SV)
double cfVrtDstSig(VKVertex *vk, bool UseTrkErr)
Definition cfVrtDst.cxx:33
std::array< double, 4 > getFitParticleMom(const VKTrack *trk, const VKVertex *vk)
void applyConstraints(VKVertex *vk)
Definition stCnst.cxx:22
void robtest(VKVertex *vk, int ifl, int nIteration)
Definition RobTest.cxx:14
int processCascadePV(CascadeEvent &cascadeEvent_, const double *primVrt, const double *primVrtCov)
int vkMSolve(double *a, double *b, long int n, double *ainv)
int afterFit(VKVertex *vk, double *ader, double *dcv, double *ptot, double *VrtMomCov, const VKalVrtControlBase *CONTROL)
Definition cfTotCov.cxx:26
double cfSmallEigenvalue(double *cov, long int n)
void combinedTrack(long int ICH, double *pv0, double *covi, double BMAG, double *par, double *covo)
Definition XYZtrp.cxx:113
double covvrt[6]
Definition ForVrtClose.h:23
double cvder[12]
Definition ForVrtClose.h:30
double dcv[6 *(vkalNTrkM *3+3)]
Definition ForVrtClose.h:31