ATLAS Offline Software
Loading...
Searching...
No Matches
CFitCascadeScale.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2026 CERN for the benefit of the ATLAS collaboration
3*/
4
5// Idea:
6// Use "pass near" constraint in each cascade vertex with thermodynamical "cooling"
7// Potentially could be more powerful that currently implemented scheme with exact pointing
8// Currently is LESS efficient, so for the moment left for future work
9//==========================================================================================
24#include <cmath>
25#include <iostream>
26
27
28namespace Trk {
29//
30// Rescale covariance matrices for cascade vertices used as pointing targets
31//
32void rescaleVrtErrForPointing( double Div, CascadeEvent & cascadeEvent_ )
33{
34 if(Div<1.)Div=1.;
35 cascadeEvent_.setSCALE(cascadeEvent_.getSCALE()/Div);
36 for(int iv=0; iv<cascadeEvent_.cascadeNV-1; iv++){ // Last vertex must not be touched
37 VKVertex *vk = cascadeEvent_.cascadeVertexList[iv].get();
38 for(int i=0; i<6; i++) vk->FVC.covvrt[i] /=Div;
39 }
40}
41//
42//
43//
44int fitVertexCascadeScale( VKVertex * vk, double & distToVertex )
45{
46//-------------------------------------------------------------------------
47// Fits single vertex in cascade (no iterations , just a single fit!!!)
48// creates summary track after it and fills corresponding track parameters
49// in next vertex in cascade
50//
51// "Near to vertex" pointing is used here with decreasing vertex errors
52//
53// Procedure assumes that "included tracks"(from vertices) are already
54// recalculated in predecessor vertices fits.
55//
56// Fit itself. First get magnetic field at iteration reference point
57//
58 distToVertex = 0.;
59 vk->vk_fitterControl->vk_forcft.localbmag=Trk::vkalMagFld::getMagFld(vk->refIterV,(vk->vk_fitterControl).get());
60
61
62//
63//-------- Then fit
64//
65 applyConstraints(vk); //apply all constraints in vertex
66 int IERR = vtcfit( vk );
67 if(IERR) return IERR;
68//
69//
70// Fill fitted combined track in next vertex (if needed)
71//
72 double dptot[4],VrtMomCov[21];
73 IERR = afterFit( vk, vk->ader, vk->FVC.dcv, dptot, VrtMomCov, (vk->vk_fitterControl).get());
74 if (IERR) return -13; /* NONINVERTIBLE COV.MATRIX */
75 cfdcopy( dptot, vk->fitMom, 3); //save Momentum
76 cfdcopy(VrtMomCov, vk->fitCovXYZMom, 21); //save XYZMom covariance
78 if(vk->FVC.Charge!=0)vk->FVC.Charge=std::copysign(1,vk->FVC.Charge);
79//
80 if(vk->nextCascadeVrt){
81 FullMTXfill(vk, vk->ader);
82 VKTrack * target_trk = getCombinedVTrack(vk); // get address of combined track
83 if( target_trk == nullptr ) return -12;
84
85 long int Charge=getVertexCharge(vk);
86 if(Charge!=0)Charge=std::copysign(1,Charge);
87 target_trk->Charge=Charge;
88
89 double parV0[5],covParV0[15],tmpCov[15],fittedVrt[3];
90 fittedVrt[0]=vk->refIterV[0]+vk->fitV[0];
91 fittedVrt[1]=vk->refIterV[1]+vk->fitV[1];
92 fittedVrt[2]=vk->refIterV[2]+vk->fitV[2];
93//
94// Particle creation and propagation
95 double vBx,vBy,vBz;
96 Trk::vkalMagFld::getMagFld(fittedVrt[0], fittedVrt[1], fittedVrt[2],vBx,vBy,vBz,(vk->vk_fitterControl).get());
97 double lPhi = atan2(dptot[1], dptot[0]);
98 double lTheta = acos(dptot[2] / sqrt(dptot[0]*dptot[0]+dptot[1]*dptot[1]+dptot[2]*dptot[2]));
99 double effectiveField = Trk::vkalMagFld::getEffField(vBx, vBy, vBz, lPhi, lTheta);
100 combinedTrack( Charge, dptot, VrtMomCov, effectiveField, parV0, covParV0);
101 covParV0[0]=std::abs(covParV0[0]); covParV0[2]=std::abs(covParV0[2]); covParV0[5]=fabs(covParV0[5]);
102 covParV0[9]=std::abs(covParV0[9]); covParV0[14]=std::abs(covParV0[14]); //VK protection against numerical problems
103 Trk::vkalPropagator::Propagate(-999, Charge, parV0, covParV0, fittedVrt,
104 vk->nextCascadeVrt->refIterV, target_trk->Perig, tmpCov, (vk->vk_fitterControl).get());
105//std::cout<<"testR,Z="<<target_trk->Perig[0]<<", "<<target_trk->Perig[1]<<'\n';
106 distToVertex = sqrt(target_trk->Perig[0]*target_trk->Perig[0]+target_trk->Perig[1]*target_trk->Perig[1]);
107 target_trk->iniP[0]=target_trk->cnstP[0]=target_trk->Perig[2]; //initial guess
108 target_trk->iniP[1]=target_trk->cnstP[1]=target_trk->Perig[3];
109 target_trk->iniP[2]=target_trk->cnstP[2]=target_trk->Perig[4];
110 IERR=cfInv5(tmpCov, target_trk->WgtM); if (IERR) IERR=cfdinv(tmpCov, target_trk->WgtM, 5);
111 if (IERR) return -15; /* NONINVERTIBLE COV.MATRIX */
112 for(int im=0; im<15; im++)target_trk->WgtM[im] /= vk->vk_fitterControl->getCascadeEvent()->getSCALE(); // Tighten pseudotrack errors
113 }
114//
115// Save refitted vertex position as target for predecessors
116 if(!vk->includedVrt.empty()){ // Save fitted vertex as target for "pass near" constraint in previous vertex
117 for(int pseu=0; pseu<(int)vk->includedVrt.size(); pseu++){
118// vk->includedVrt[pseu]->FVC.vrt[0] = (vk->refIterV[0] + vk->fitV[0] + vk->includedVrt[pseu]->FVC.vrt[0])/2.;
119// vk->includedVrt[pseu]->FVC.vrt[1] = (vk->refIterV[1] + vk->fitV[1] + vk->includedVrt[pseu]->FVC.vrt[1])/2.;
120// vk->includedVrt[pseu]->FVC.vrt[2] = (vk->refIterV[2] + vk->fitV[2] + vk->includedVrt[pseu]->FVC.vrt[2])/2.;
121 vk->includedVrt[pseu]->FVC.vrt[0] = vk->refIterV[0] + vk->fitV[0];
122 vk->includedVrt[pseu]->FVC.vrt[1] = vk->refIterV[1] + vk->fitV[1];
123 vk->includedVrt[pseu]->FVC.vrt[2] = vk->refIterV[2] + vk->fitV[2];
124 }
125 }
126 return 0;
127}
128
129//-----------------------------------------------------------------------------------
130//
131// Iteration over complete cascade
132//
133 int processCascadeScale(CascadeEvent & cascadeEvent_ )
134{
135 VKVertex * vk=nullptr;
136 long int Iter, IERR, iv;
137 cascadeEvent_.setSCALE(1.); // Safety
138//============================================================================================
139//
140// First without pointing to get initial estimations and resolve mass constraints
141// This initial step is needed to get initial estimation for "passing near" constraints
142//
143 double iv_dstToVrt=0., sum_dstToVrt=0., old_dstToVrt;
144 for(iv=0; iv<cascadeEvent_.cascadeNV; iv++){
145 vk = cascadeEvent_.cascadeVertexList[iv].get();
146 vk->passNearVertex=false;
147 vk->passWithTrkCov=false;
148 IERR = fitVertexCascadeScale( vk, iv_dstToVrt ); if(IERR)return IERR; //fit
149 IERR = setVTrackMass(vk); if(IERR)return IERR; //mass of combined particle
150 }
151 IERR = translateToFittedPos(cascadeEvent_); if(IERR)return IERR;
152
153//
154// Now fit "close to vertex" pointing and cooling
155//
156 for(iv=0; iv<cascadeEvent_.cascadeNV-1; iv++) cascadeEvent_.cascadeVertexList[iv]->passNearVertex=true;
157 if(cascadeEvent_.nearPrmVertex){ // Primary vertex if needed
158 cascadeEvent_.cascadeVertexList[cascadeEvent_.cascadeNV-1]->passNearVertex=true;
159 cascadeEvent_.cascadeVertexList[cascadeEvent_.cascadeNV-1]->passWithTrkCov=true;
160 }
161//
162 double Chi2Old=0.,Chi2Cur=0;
163 double Scale=2.;
164 double limDstToVrt=0.001;
165 old_dstToVrt=100000.;
166 for(Iter=0; Iter<20; Iter++){
167
168 //*******************************************************************************
169 for(int Stabil=0; Stabil<2; Stabil++){ // Stabilization cycling for given SCALE
170 Chi2Cur=0.;
171 sum_dstToVrt=0.;
172 for(iv=0; iv<cascadeEvent_.cascadeNV; iv++){
173 vk = cascadeEvent_.cascadeVertexList[iv].get();
174//
175//Calculate derivatives for "passing near" cnst. Initial vertex position is used for derivatives.
176 if(vk->passNearVertex){
177 double dparst[6]={vk->refIterV[0]+vk->iniV[0], vk->refIterV[1]+vk->iniV[1], vk->refIterV[2]+vk->iniV[2],
178 vk->fitMom[0], vk->fitMom[1], vk->fitMom[2] };
179 vpderiv(vk->passWithTrkCov, vk->FVC.Charge, dparst, vk->fitCovXYZMom, vk->FVC.vrt, vk->FVC.covvrt,
180 vk->FVC.cvder, vk->FVC.ywgt, vk->FVC.rv0, (vk->vk_fitterControl).get());
181 }
182 IERR = fitVertexCascadeScale( vk, iv_dstToVrt); if(IERR)return IERR; //fit
183 IERR = setVTrackMass(vk); if(IERR)return IERR; //mass of combined particle
184 Chi2Cur += vk->Chi2;
185 sum_dstToVrt += iv_dstToVrt;
186 }
187 IERR = translateToFittedPos(cascadeEvent_,1.0); if(IERR)return IERR;
188 //if(Stabil>0 && sum_dstToVrt<old_dstToVrt) break;
189 }
190 //********************************************************************************
191 if(Iter>5 && Chi2Cur>1.e4) return -1; //Too bad iteration. Drop fit
192 if(cascadeEvent_.getSCALE() < 1.e-6)Scale=1.; //Enough tightening
193 if(sum_dstToVrt<old_dstToVrt){
194 rescaleVrtErrForPointing( Scale, cascadeEvent_ ); // Tighten pointing accuracy
195 if(old_dstToVrt/3. < sum_dstToVrt) { old_dstToVrt=sum_dstToVrt;} else {old_dstToVrt/=3.;}
196 }
197//std::cout<<"Cool iter="<<Iter<<" Scale="<<cascadeEvent_.getSCALE()<<", "<<Chi2Cur<<" NV="<<cascadeEvent_.cascadeNV<<
198// " dst="<<sum_dstToVrt<<'\n';
199 if(std::abs(Chi2Cur-Chi2Old)<0.01 && Iter>5 && sum_dstToVrt<limDstToVrt*(cascadeEvent_.cascadeNV-1) )break; //stable cascade position
200 Chi2Old=Chi2Cur;
201 }
202 double cnstRemnants=0. ;
203 for(iv=0; iv<cascadeEvent_.cascadeNV; iv++){
204 vk = cascadeEvent_.cascadeVertexList[iv].get();
205 for(int ii=0; ii<(int)vk->ConstraintList.size();ii++){
206 for(int ic=0; ic<(int)vk->ConstraintList[ii]->NCDim; ic++){
207 cnstRemnants += std::abs( vk->ConstraintList[ii]->aa[ic] );
208 } }
209 }
210 if( cnstRemnants > 1.e0) return -2; /* Constraints are not resolved. Stop fit */
211std::cout<<"================================================="<<sum_dstToVrt<<'\n';
212// if(sum_dstToVrt>limDstToVrt*(cascadeEvent_.cascadeNV-1) )return -2; //Pointing is not resolved
213
214 long int fullNPar = getCascadeNPar(cascadeEvent_);
215 cascadeEvent_.fullCovMatrix.reset( new double[fullNPar*fullNPar] );
216 for(int im=0; im<fullNPar*fullNPar; im++)cascadeEvent_.fullCovMatrix[im]=0.;
217 for(int im=0; im<fullNPar; im++)cascadeEvent_.fullCovMatrix[im*fullNPar + im]=1.;
218 int NStart=0;
219 cascadeEvent_.matrixPnt.resize(cascadeEvent_.cascadeNV);
220 auto tmpLSide = std::make_unique<double[]>(fullNPar);
221 for( iv=0; iv<cascadeEvent_.cascadeNV; iv++){
222 cascadeEvent_.matrixPnt[iv]=NStart;
223 NStart += FullMCNSTfill( vk, vk->ader, tmpLSide.get());
224 }
225
226 return 0;
227}
228
229
230} /* End of VKalVrtCore namespace */
double getSCALE() const
void setSCALE(double S)
std::vector< int > matrixPnt
std::unique_ptr< double[]> fullCovMatrix
std::vector< std::unique_ptr< VKVertex > > cascadeVertexList
std::vector< VKVertex * > includedVrt
double ader[(3 *vkalNTrkM+3) *(3 *vkalNTrkM+3)]
std::vector< std::unique_ptr< VKConstraintBase > > ConstraintList
double fitCovXYZMom[21]
VKVertex * nextCascadeVrt
std::unique_ptr< VKalVrtControl > vk_fitterControl
static void getMagFld(const double, const double, const double, double &, double &, double &, const VKalVrtControlBase *)
static double getEffField(double bx, double by, double bz, double phi, double theta)
Definition VKalVrtBMag.h:60
static void Propagate(long int TrkID, long int Charge, double *ParOld, double *CovOld, double *RefStart, double *RefEnd, double *ParNew, double *CovNew, VKalVrtControlBase *FitControl=0)
void Scale(TH1 *h, double d=1)
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
int translateToFittedPos(CascadeEvent &cascadeEvent_, double Step)
void rescaleVrtErrForPointing(double Div, CascadeEvent &cascadeEvent_)
int cfInv5(double *cov, double *wgt)
int cfdinv(double *cov, double *wgt, long int NI)
int setVTrackMass(VKVertex *vk)
int getCascadeNPar(CascadeEvent &cascadeEvent_, int Type)
void combinedTrack(long int ICH, double *pv0, double *covi, double effectiveBMAG, double *par, double *covo)
Definition XYZtrp.cxx:113
VKTrack * getCombinedVTrack(VKVertex *vk)
int processCascadeScale(CascadeEvent &cascadeEvent_)
int FullMCNSTfill(VKVertex *vk, double *ader, double *LSide)
Definition FullMtx.cxx:81
int fitVertexCascadeScale(VKVertex *vk, double &distToVertex)
int vtcfit(VKVertex *vk)
Definition VtCFit.cxx:293
long int getVertexCharge(VKVertex *vk)
void applyConstraints(VKVertex *vk)
Definition stCnst.cxx:22
int afterFit(VKVertex *vk, double *ader, double *dcv, double *ptot, double *VrtMomCov, const VKalVrtControlBase *CONTROL)
Definition cfTotCov.cxx:26
double covvrt[6]
Definition ForVrtClose.h:23
double cvder[12]
Definition ForVrtClose.h:30
double dcv[6 *(vkalNTrkM *3+3)]
Definition ForVrtClose.h:31