ATLAS Offline Software
Loading...
Searching...
No Matches
CFitCascadeScale.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2023 CERN for the benefit of the ATLAS collaboration
3*/
4
5// 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 localField=Trk::vkalMagFld::getMagFld(fittedVrt,(vk->vk_fitterControl).get());
96 combinedTrack( Charge, dptot, VrtMomCov, localField, parV0, covParV0);
97 covParV0[0]=std::abs(covParV0[0]); covParV0[2]=std::abs(covParV0[2]); covParV0[5]=fabs(covParV0[5]);
98 covParV0[9]=std::abs(covParV0[9]); covParV0[14]=std::abs(covParV0[14]); //VK protection against numerical problems
99 Trk::vkalPropagator::Propagate(-999, Charge, parV0, covParV0, fittedVrt,
100 vk->nextCascadeVrt->refIterV, target_trk->Perig, tmpCov, (vk->vk_fitterControl).get());
101//std::cout<<"testR,Z="<<target_trk->Perig[0]<<", "<<target_trk->Perig[1]<<'\n';
102 distToVertex = sqrt(target_trk->Perig[0]*target_trk->Perig[0]+target_trk->Perig[1]*target_trk->Perig[1]);
103 target_trk->iniP[0]=target_trk->cnstP[0]=target_trk->Perig[2]; //initial guess
104 target_trk->iniP[1]=target_trk->cnstP[1]=target_trk->Perig[3];
105 target_trk->iniP[2]=target_trk->cnstP[2]=target_trk->Perig[4];
106 IERR=cfInv5(tmpCov, target_trk->WgtM); if (IERR) IERR=cfdinv(tmpCov, target_trk->WgtM, 5);
107 if (IERR) return -15; /* NONINVERTIBLE COV.MATRIX */
108 for(int im=0; im<15; im++)target_trk->WgtM[im] /= vk->vk_fitterControl->getCascadeEvent()->getSCALE(); // Tighten pseudotrack errors
109 }
110//
111// Save refitted vertex position as target for predecessors
112 if(!vk->includedVrt.empty()){ // Save fitted vertex as target for "pass near" constraint in previous vertex
113 for(int pseu=0; pseu<(int)vk->includedVrt.size(); pseu++){
114// vk->includedVrt[pseu]->FVC.vrt[0] = (vk->refIterV[0] + vk->fitV[0] + vk->includedVrt[pseu]->FVC.vrt[0])/2.;
115// vk->includedVrt[pseu]->FVC.vrt[1] = (vk->refIterV[1] + vk->fitV[1] + vk->includedVrt[pseu]->FVC.vrt[1])/2.;
116// vk->includedVrt[pseu]->FVC.vrt[2] = (vk->refIterV[2] + vk->fitV[2] + vk->includedVrt[pseu]->FVC.vrt[2])/2.;
117 vk->includedVrt[pseu]->FVC.vrt[0] = vk->refIterV[0] + vk->fitV[0];
118 vk->includedVrt[pseu]->FVC.vrt[1] = vk->refIterV[1] + vk->fitV[1];
119 vk->includedVrt[pseu]->FVC.vrt[2] = vk->refIterV[2] + vk->fitV[2];
120 }
121 }
122 return 0;
123}
124
125//-----------------------------------------------------------------------------------
126//
127// Iteration over complete cascade
128//
129 int processCascadeScale(CascadeEvent & cascadeEvent_ )
130{
131 VKVertex * vk=nullptr;
132 long int Iter, IERR, iv;
133 cascadeEvent_.setSCALE(1.); // Safety
134//============================================================================================
135//
136// First without pointing to get initial estimations and resolve mass constraints
137// This initial step is needed to get initial estimation for "passing near" constraints
138//
139 double iv_dstToVrt=0., sum_dstToVrt=0., old_dstToVrt;
140 for(iv=0; iv<cascadeEvent_.cascadeNV; iv++){
141 vk = cascadeEvent_.cascadeVertexList[iv].get();
142 vk->passNearVertex=false;
143 vk->passWithTrkCov=false;
144 IERR = fitVertexCascadeScale( vk, iv_dstToVrt ); if(IERR)return IERR; //fit
145 IERR = setVTrackMass(vk); if(IERR)return IERR; //mass of combined particle
146 }
147 IERR = translateToFittedPos(cascadeEvent_); if(IERR)return IERR;
148
149//
150// Now fit "close to vertex" pointing and cooling
151//
152 for(iv=0; iv<cascadeEvent_.cascadeNV-1; iv++) cascadeEvent_.cascadeVertexList[iv]->passNearVertex=true;
153 if(cascadeEvent_.nearPrmVertex){ // Primary vertex if needed
154 cascadeEvent_.cascadeVertexList[cascadeEvent_.cascadeNV-1]->passNearVertex=true;
155 cascadeEvent_.cascadeVertexList[cascadeEvent_.cascadeNV-1]->passWithTrkCov=true;
156 }
157//
158 double Chi2Old=0.,Chi2Cur=0;
159 double Scale=2.;
160 double limDstToVrt=0.001;
161 old_dstToVrt=100000.;
162 for(Iter=0; Iter<20; Iter++){
163
164 //*******************************************************************************
165 for(int Stabil=0; Stabil<2; Stabil++){ // Stabilization cycling for given SCALE
166 Chi2Cur=0.;
167 sum_dstToVrt=0.;
168 for(iv=0; iv<cascadeEvent_.cascadeNV; iv++){
169 vk = cascadeEvent_.cascadeVertexList[iv].get();
170//
171//Calculate derivatives for "passing near" cnst. Initial vertex position is used for derivatives.
172 if(vk->passNearVertex){
173 double dparst[6]={vk->refIterV[0]+vk->iniV[0], vk->refIterV[1]+vk->iniV[1], vk->refIterV[2]+vk->iniV[2],
174 vk->fitMom[0], vk->fitMom[1], vk->fitMom[2] };
175 vpderiv(vk->passWithTrkCov, vk->FVC.Charge, dparst, vk->fitCovXYZMom, vk->FVC.vrt, vk->FVC.covvrt,
176 vk->FVC.cvder, vk->FVC.ywgt, vk->FVC.rv0, (vk->vk_fitterControl).get());
177 }
178 IERR = fitVertexCascadeScale( vk, iv_dstToVrt); if(IERR)return IERR; //fit
179 IERR = setVTrackMass(vk); if(IERR)return IERR; //mass of combined particle
180 Chi2Cur += vk->Chi2;
181 sum_dstToVrt += iv_dstToVrt;
182 }
183 IERR = translateToFittedPos(cascadeEvent_,1.0); if(IERR)return IERR;
184 //if(Stabil>0 && sum_dstToVrt<old_dstToVrt) break;
185 }
186 //********************************************************************************
187 if(Iter>5 && Chi2Cur>1.e4) return -1; //Too bad iteration. Drop fit
188 if(cascadeEvent_.getSCALE() < 1.e-6)Scale=1.; //Enough tightening
189 if(sum_dstToVrt<old_dstToVrt){
190 rescaleVrtErrForPointing( Scale, cascadeEvent_ ); // Tighten pointing accuracy
191 if(old_dstToVrt/3. < sum_dstToVrt) { old_dstToVrt=sum_dstToVrt;} else {old_dstToVrt/=3.;}
192 }
193//std::cout<<"Cool iter="<<Iter<<" Scale="<<cascadeEvent_.getSCALE()<<", "<<Chi2Cur<<" NV="<<cascadeEvent_.cascadeNV<<
194// " dst="<<sum_dstToVrt<<'\n';
195 if(std::abs(Chi2Cur-Chi2Old)<0.01 && Iter>5 && sum_dstToVrt<limDstToVrt*(cascadeEvent_.cascadeNV-1) )break; //stable cascade position
196 Chi2Old=Chi2Cur;
197 }
198 double cnstRemnants=0. ;
199 for(iv=0; iv<cascadeEvent_.cascadeNV; iv++){
200 vk = cascadeEvent_.cascadeVertexList[iv].get();
201 for(int ii=0; ii<(int)vk->ConstraintList.size();ii++){
202 for(int ic=0; ic<(int)vk->ConstraintList[ii]->NCDim; ic++){
203 cnstRemnants += std::abs( vk->ConstraintList[ii]->aa[ic] );
204 } }
205 }
206 if( cnstRemnants > 1.e0) return -2; /* Constraints are not resolved. Stop fit */
207std::cout<<"================================================="<<sum_dstToVrt<<'\n';
208// if(sum_dstToVrt>limDstToVrt*(cascadeEvent_.cascadeNV-1) )return -2; //Pointing is not resolved
209
210 long int fullNPar = getCascadeNPar(cascadeEvent_);
211 cascadeEvent_.fullCovMatrix.reset( new double[fullNPar*fullNPar] );
212 for(int im=0; im<fullNPar*fullNPar; im++)cascadeEvent_.fullCovMatrix[im]=0.;
213 for(int im=0; im<fullNPar; im++)cascadeEvent_.fullCovMatrix[im*fullNPar + im]=1.;
214 int NStart=0;
215 cascadeEvent_.matrixPnt.resize(cascadeEvent_.cascadeNV);
216 auto tmpLSide = std::make_unique<double[]>(fullNPar);
217 for( iv=0; iv<cascadeEvent_.cascadeNV; iv++){
218 cascadeEvent_.matrixPnt[iv]=NStart;
219 NStart += FullMCNSTfill( vk, vk->ader, tmpLSide.get());
220 }
221
222 return 0;
223}
224
225
226} /* 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 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)
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
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