ATLAS Offline Software
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 //==========================================================================================
13 #include "TrkVKalVrtCore/XYZtrp.h"
14 #include "TrkVKalVrtCore/VtCFit.h"
15 #include "TrkVKalVrtCore/stCnst.h"
16 #include "TrkVKalVrtCore/FullMtx.h"
17 #include "TrkVKalVrtCore/VtDeriv.h"
18 #include "TrkVKalVrtCore/Derivt.h"
20 #include "TrkVKalVrtCore/Matrix.h"
24 #include <cmath>
25 #include <iostream>
26 
27 
28 namespace Trk {
29 //
30 // Rescale covariance matrices for cascade vertices used as pointing targets
31 //
32 void 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 //
44 int 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
77  vk->FVC.Charge=getVertexCharge(vk);
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 */
207 std::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 */
Propagator.h
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::CascadeEvent::setSCALE
void setSCALE(double S)
Definition: TrkVKalVrtCoreBase.h:26
Trk::cfdcopy
void cfdcopy(double *source, double *target, int n)
Definition: TrkVKalUtils.h:23
Trk::FullMTXfill
void FullMTXfill(VKVertex *vk, double *ader)
Definition: FullMtx.cxx:19
Trk::vkalMagFld::getMagFld
static void getMagFld(const double, const double, const double, double &, double &, double &, VKalVrtControlBase *)
Definition: VKalVrtBMag.cxx:24
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
Trk::getVertexCharge
long int getVertexCharge(VKVertex *vk)
Definition: CFitCascade.cxx:71
Trk::vtcfit
int vtcfit(VKVertex *vk)
Definition: VtCFit.cxx:293
Trk::VKVertex::FVC
ForVrtClose FVC
Definition: TrkVKalVrtCoreBase.h:160
python.atlas_oh.im
im
Definition: atlas_oh.py:167
Trk::VKVertex::refIterV
double refIterV[3]
Definition: TrkVKalVrtCoreBase.h:146
Trk::applyConstraints
void applyConstraints(VKVertex *vk)
Definition: stCnst.cxx:22
Trk::VKTrack
Definition: TrkVKalVrtCoreBase.h:64
Trk::CascadeEvent::getSCALE
double getSCALE() const
Definition: TrkVKalVrtCoreBase.h:25
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::ForVrtClose::Charge
long int Charge
Definition: ForVrtClose.h:22
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
cfTotCov.h
Trk::CascadeEvent::fullCovMatrix
std::unique_ptr< double[]> fullCovMatrix
Definition: TrkVKalVrtCoreBase.h:28
Trk::CascadeEvent::matrixPnt
std::vector< int > matrixPnt
Definition: TrkVKalVrtCoreBase.h:31
TrkVKalVrtCoreBase.h
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::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::fitMom
double fitMom[3]
Definition: TrkVKalVrtCoreBase.h:158
Matrix.h
Trk::VKVertex::passNearVertex
bool passNearVertex
Definition: TrkVKalVrtCoreBase.h:156
Trk::getCombinedVTrack
VKTrack * getCombinedVTrack(VKVertex *vk)
Definition: CascadeUtils.cxx:110
Scale
void Scale(TH1 *h, double d=1)
Definition: comparitor.cxx:76
Trk::ForVrtClose::cvder
double cvder[12]
Definition: ForVrtClose.h:30
CFitCascade.h
grepfile.ic
int ic
Definition: grepfile.py:33
Trk::fitVertexCascadeScale
int fitVertexCascadeScale(VKVertex *vk, double &distToVertex)
Definition: CFitCascadeScale.cxx:44
Derivt.h
Trk::processCascadeScale
int processCascadeScale(CascadeEvent &cascadeEvent_)
Definition: CFitCascadeScale.cxx:129
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::CascadeEvent::nearPrmVertex
int nearPrmVertex
Definition: TrkVKalVrtCoreBase.h:24
Trk::FullMCNSTfill
int FullMCNSTfill(VKVertex *vk, double *ader, double *LSide)
Definition: FullMtx.cxx:81
CascadeUtils.h
Trk::CascadeEvent
Definition: TrkVKalVrtCoreBase.h:21
Trk::setVTrackMass
int setVTrackMass(VKVertex *vk)
Definition: CFitCascade.cxx:34
Trk::CascadeEvent::cascadeNV
int cascadeNV
Definition: TrkVKalVrtCoreBase.h:23
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
XYZtrp.h
Trk::VKVertex::nextCascadeVrt
VKVertex * nextCascadeVrt
Definition: TrkVKalVrtCoreBase.h:179
Trk::VKVertex
Definition: TrkVKalVrtCoreBase.h:128
CFitCascadeScale.h
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
VtCFit.h
egammaEnergyPositionAllSamples::e0
double e0(const xAOD::CaloCluster &cluster)
return the uncorrected cluster energy in pre-sampler
FullMtx.h
Trk::rescaleVrtErrForPointing
void rescaleVrtErrForPointing(double Div, CascadeEvent &cascadeEvent_)
Definition: CFitCascadeScale.cxx:32
Trk::CascadeEvent::cascadeVertexList
std::vector< std::unique_ptr< VKVertex > > cascadeVertexList
Definition: TrkVKalVrtCoreBase.h:30
Trk::ForVrtClose::covvrt
double covvrt[6]
Definition: ForVrtClose.h:23
Trk::VKVertex::passWithTrkCov
bool passWithTrkCov
Definition: TrkVKalVrtCoreBase.h:157
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