ATLAS Offline Software
Loading...
Searching...
No Matches
VKalVrtFitSvc.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// Header include
11//-------------------------------------------------
12// Other stuff
13#include "GaudiKernel/IChronoStatSvc.h"
14//
15#include <algorithm>
16#include <cmath>
17
18 namespace Trk {
19
20//__________________________________________________________________________
21//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
22// Interface
23//
24
25 StatusCode TrkVKalVrtFitter::VKalVrtFit(const std::vector<const Perigee*>& InpPerigee,
27 TLorentzVector& Momentum,
28 long int& Charge,
30 dvect& Chi2PerTrk,
31 std::vector< std::vector<double> >& TrkAtVrt,
32 double& Chi2,
33 IVKalState& istate,
34 bool ifCovV0 /*= false*/) const
35{
36 assert(dynamic_cast<State*> (&istate)!=nullptr);
37 State& state = static_cast<State&> (istate);
38//
39//------ extract information about selected tracks
40//
41
42 int ntrk=0;
43 state.m_globalFirstHit = nullptr;
44 StatusCode sc = CvtPerigee(InpPerigee, ntrk, state);
45 if(sc.isFailure())return StatusCode::FAILURE;
46
47 int ierr = VKalVrtFit3( ntrk, Vertex, Momentum, Charge, ErrorMatrix,
48 Chi2PerTrk, TrkAtVrt,Chi2, state, ifCovV0 ) ;
49 if (ierr) return StatusCode::FAILURE;
50 return StatusCode::SUCCESS;
51}
52
53
54
55StatusCode TrkVKalVrtFitter::VKalVrtFit(const std::vector<const xAOD::TrackParticle*> & InpTrkC,
56 const std::vector<const xAOD::NeutralParticle*> & InpTrkN,
58 TLorentzVector& Momentum,
59 long int& Charge,
61 dvect& Chi2PerTrk,
62 std::vector< std::vector<double> >& TrkAtVrt,
63 double& Chi2,
64 IVKalState& istate,
65 bool ifCovV0 /*= false*/) const
66{
67 assert(dynamic_cast<State*> (&istate)!=nullptr);
68 State& state = static_cast<State&> (istate);
69
70//
71//------ extract information about selected tracks
72//
73 int ntrk=0;
74 state.m_globalFirstHit = nullptr;
75
76 // The tmpInputC will be not owning just holding plain ptr
77 // the ownership is handled via the TParamOwner
78 // and is unique_ptr so we do not leak
79 std::vector<const TrackParameters*> tmpInputC(0);
80 std::vector<std::unique_ptr<const TrackParameters>> TParamOwner(0);
81 StatusCode sc;
82 double closestHitR=1.e6; //VK needed for FirstMeasuredPointLimit if this hit itself is absent
83 if(m_firstMeasuredPoint){ //First measured point strategy
84 //------
85 if(!InpTrkC.empty()){
86 if( m_InDetExtrapolator == nullptr ){
87 if(msgLvl(MSG::WARNING))msg()<< "No InDet extrapolator given."<<
88 "Can't use FirstMeasuredPoint with xAOD::TrackParticle!!!" << endmsg;
89 return StatusCode::FAILURE;
90 }
91 std::vector<const xAOD::TrackParticle*>::const_iterator i_ntrk;
92 if(msgLvl(MSG::DEBUG))msg()<< "Start FirstMeasuredPoint handling"<<'\n';
93 unsigned int indexFMP;
94 for (i_ntrk = InpTrkC.begin(); i_ntrk < InpTrkC.end(); ++i_ntrk) {
95 if ((*i_ntrk)->indexOfParameterAtPosition(indexFMP, xAOD::FirstMeasurement)){
96 if(msgLvl(MSG::DEBUG))msg()<< "FirstMeasuredPoint on track is discovered. Use it."<<'\n';
97 // create parameters
98 TParamOwner.emplace_back(std::make_unique<CurvilinearParameters>(
99 (*i_ntrk)->curvilinearParameters(indexFMP)));
100 //For the last one we created, push also a not owning / view ptr to tmpInputC
101 tmpInputC.push_back((TParamOwner.back()).get());
102 }else{
103 if(msgLvl(MSG::DEBUG)){
104 msg()<< "FirstMeasuredPoint on track is absent."<<
105 "Try extrapolation from Perigee to FisrtMeasuredPoint radius"<<endmsg;
106 }
107
108 TParamOwner.emplace_back(m_fitPropagator->myxAODFstPntOnTrk((*i_ntrk)));
109 //For the last one we created, push also a not owning / view ptr to tmpInputC
110 tmpInputC.push_back((TParamOwner.back()).get());
111 if(tmpInputC[tmpInputC.size()-1]==nullptr){
112 //Extrapolation failure
113 if(msgLvl(MSG::WARNING)){
114 msg()<< "InDetExtrapolator can't etrapolate xAOD::TrackParticle Perigee "<<
115 "to FirstMeasuredPoint radius! Stop vertex fit!" << endmsg;
116 }
117 return StatusCode::FAILURE;
118 }
119 }
120 if( (*i_ntrk)->radiusOfFirstHit() < closestHitR ) {
121 closestHitR=(*i_ntrk)->radiusOfFirstHit();
122 }
123 }
124 sc=CvtTrackParameters(tmpInputC,ntrk,state);
125 if(sc.isFailure()){
126 return StatusCode::FAILURE;
127 }
128 }
129 }else{
130 if(!InpTrkC.empty()) {
131 sc=CvtTrackParticle(InpTrkC,ntrk,state);
132 }
133 }
134 if(sc.isFailure())return StatusCode::FAILURE;
135 if(!InpTrkN.empty()){sc=CvtNeutralParticle(InpTrkN,ntrk,state); if(sc.isFailure())return StatusCode::FAILURE;}
136 //--
137 int ierr = VKalVrtFit3( ntrk, Vertex, Momentum, Charge, ErrorMatrix, Chi2PerTrk, TrkAtVrt, Chi2, state, ifCovV0 ) ;
138 if (ierr) return StatusCode::FAILURE;
139 //
140 //-- Check vertex position with respect to first measured hit and refit with plane constraint if needed
141 state.m_planeCnstNDOF = 0;
143 Amg::Vector3D cnstRefPoint(0.,0.,0.);
144 if(closestHitR==1.e6){ // Not found previously
145 const xAOD::TrackParticle * trkFMP=nullptr;
146 for(auto &trka : InpTrkC){
147 double hitR=trka->radiusOfFirstHit();
148 if(closestHitR>hitR){
149 closestHitR=hitR;
150 trkFMP=trka;
151 }
152 }
153 if(closestHitR<1.e6){
154 auto perFMP=m_fitPropagator->myxAODFstPntOnTrk(trkFMP); //FMP is calculated by extrapolation to radiusOfFirstHit
155 if(perFMP) cnstRefPoint = perFMP->position();
156 delete perFMP;
157 }
158 }
159 Amg::Vector3D unitMom=Amg::Vector3D(Momentum.Px()/Momentum.P(),Momentum.Py()/Momentum.P(),Momentum.Pz()/Momentum.P());
160 //----------- Use as reference either hit(state.m_globalFirstHit) or its radius(closestHitR) if hit is absent
161 if(state.m_globalFirstHit)cnstRefPoint=state.m_globalFirstHit->position();
162 //------------
163 if(Vertex.perp()>closestHitR && cnstRefPoint.perp()>0.){
164 if(msgLvl(MSG::DEBUG))msg(MSG::DEBUG)<<"Vertex behind first measured point is detected. Constraint is applied!"<<endmsg;
165 state.m_planeCnstNDOF = 1; // Additional NDOF due to plane constraint
166 double D= unitMom.x()*(cnstRefPoint.x()-state.m_refFrameX)
167 +unitMom.y()*(cnstRefPoint.y()-state.m_refFrameY)
168 +unitMom.z()*(cnstRefPoint.z()-state.m_refFrameZ);
169 state.m_parPlaneCnst[0]=unitMom.x();
170 state.m_parPlaneCnst[1]=unitMom.y();
171 state.m_parPlaneCnst[2]=unitMom.z();
172 state.m_parPlaneCnst[3]=D;
173 state.m_cnstRadius=std::sqrt(std::pow(cnstRefPoint.x()-state.m_refFrameX,2.)+std::pow(cnstRefPoint.y()-state.m_refFrameY,2.));
174 state.m_cnstRadiusRef[0]=-state.m_refFrameX;
175 state.m_cnstRadiusRef[1]=-state.m_refFrameY;
176 std::vector<double> saveApproxV(3,0.); state.m_ApproximateVertex.swap(saveApproxV);
177 state.m_ApproximateVertex[0]=cnstRefPoint.x();
178 state.m_ApproximateVertex[1]=cnstRefPoint.y();
179 state.m_ApproximateVertex[2]=cnstRefPoint.z();
180 ierr = VKalVrtFit3( ntrk, Vertex, Momentum, Charge, ErrorMatrix, Chi2PerTrk, TrkAtVrt, Chi2, state, ifCovV0 );
181 state.m_vkalFitControl.setUsePlaneCnst(0.,0.,0.,0.);
182 if (ierr) { // refit without plane cnst
183 ierr = VKalVrtFit3(ntrk,Vertex,Momentum,Charge,ErrorMatrix,Chi2PerTrk,TrkAtVrt,Chi2, state, ifCovV0); // if fit with it failed
184 state.m_planeCnstNDOF = 0;
185 }
186 state.m_ApproximateVertex.swap(saveApproxV);
187 }
188 }
189 //--
190 if (ierr) return StatusCode::FAILURE;
191 return StatusCode::SUCCESS;
192}
193
194
195StatusCode TrkVKalVrtFitter::VKalVrtFit(const std::vector<const TrackParameters*> & InpTrkC,
196 const std::vector<const NeutralParameters*> & InpTrkN,
198 TLorentzVector& Momentum,
199 long int& Charge,
201 dvect& Chi2PerTrk,
202 std::vector< std::vector<double> >& TrkAtVrt,
203 double& Chi2,
204 IVKalState& istate,
205 bool ifCovV0 /*= false*/) const
206{
207 assert(dynamic_cast<State*> (&istate)!=nullptr);
208 State& state = static_cast<State&> (istate);
209
210//
211//------ extract information about selected tracks
212//
213 int ntrk=0;
214 state.m_globalFirstHit = nullptr;
215 StatusCode sc;
216 if(!InpTrkC.empty()){
217 sc=CvtTrackParameters(InpTrkC,ntrk,state);
218 if(sc.isFailure())return StatusCode::FAILURE;
219 }
220 if(!InpTrkN.empty()){
221 sc=CvtNeutralParameters(InpTrkN,ntrk,state);
222 if(sc.isFailure())return StatusCode::FAILURE;
223 }
224
225 if(state.m_ApproximateVertex.empty() && state.m_globalFirstHit){ //Initial guess if absent
226 state.m_ApproximateVertex.reserve(3);
227 state.m_ApproximateVertex.push_back(state.m_globalFirstHit->position().x());
228 state.m_ApproximateVertex.push_back(state.m_globalFirstHit->position().y());
229 state.m_ApproximateVertex.push_back(state.m_globalFirstHit->position().z());
230 }
231 int ierr = VKalVrtFit3( ntrk, Vertex, Momentum, Charge, ErrorMatrix, Chi2PerTrk, TrkAtVrt,Chi2, state, ifCovV0 ) ;
232 if (ierr) return StatusCode::FAILURE;
233//
234//-- Check vertex position with respect to first measured hit and refit with plane constraint if needed
235 state.m_planeCnstNDOF = 0;
236 if(state.m_globalFirstHit && m_firstMeasuredPointLimit && !ierr){
237 if(Vertex.perp()>state.m_globalFirstHit->position().perp()){
238 if(msgLvl(MSG::DEBUG))msg(MSG::DEBUG)<<"Vertex behind first measured point is detected. Constraint is applied!"<<endmsg;
239 state.m_planeCnstNDOF = 1; // Additional NDOF due to plane constraint
240 double pp[3]={Momentum.Px()/Momentum.Rho(),Momentum.Py()/Momentum.Rho(),Momentum.Pz()/Momentum.Rho()};
241 double D= pp[0]*(state.m_globalFirstHit->position().x()-state.m_refFrameX)
242 +pp[1]*(state.m_globalFirstHit->position().y()-state.m_refFrameY)
243 +pp[2]*(state.m_globalFirstHit->position().z()-state.m_refFrameZ);
244 state.m_vkalFitControl.setUsePlaneCnst( pp[0], pp[1], pp[2], D);
245 std::vector<double> saveApproxV(3,0.); state.m_ApproximateVertex.swap(saveApproxV);
246 state.m_ApproximateVertex[0]=state.m_globalFirstHit->position().x();
247 state.m_ApproximateVertex[1]=state.m_globalFirstHit->position().y();
248 state.m_ApproximateVertex[2]=state.m_globalFirstHit->position().z();
249 ierr = VKalVrtFit3( ntrk, Vertex, Momentum, Charge, ErrorMatrix, Chi2PerTrk, TrkAtVrt,Chi2, state, ifCovV0 ) ;
250 state.m_vkalFitControl.setUsePlaneCnst(0.,0.,0.,0.);
251 if (ierr) { // refit without plane cnst
252 ierr = VKalVrtFit3(ntrk,Vertex,Momentum,Charge,ErrorMatrix,Chi2PerTrk,TrkAtVrt,Chi2, state, ifCovV0 ) ; // if fit with it failed
253 state.m_planeCnstNDOF = 0;
254 }
255 state.m_ApproximateVertex.swap(saveApproxV);
256 }
257 }
258 if (ierr) return StatusCode::FAILURE;
259 return StatusCode::SUCCESS;
260}
261
262
263
264
265
266
267//--------------------------------------------------------------------------------------------------
268// Main code
269//
272 TLorentzVector& Momentum,
273 long int& Charge,
275 dvect& Chi2PerTrk,
276 std::vector< std::vector<double> >& TrkAtVrt,
277 double& Chi2,
278 State& state,
279 bool ifCovV0) const
280{
281//
282//------ Variables and arrays needed for fitting kernel
283//
284 int ierr,i;
285 double xyz0[3],covf[21],chi2f=-10.;
286 double ptot[4]={0.};
287 double xyzfit[3]={0.};
288//
289//--- Set field value at (0.,0.,0.) - some safety
290//
291 double Bx,By,Bz;
292 state.m_fitField.getMagFld(-state.m_refFrameX,-state.m_refFrameY,-state.m_refFrameZ,Bx,By,Bz);
293//
294//------ Fit option setting
295//
296 VKalVrtConfigureFitterCore(ntrk, state);
297//
298//------ Fit itself
299//
300 state.m_FitStatus=0;
301 state.m_vkalFitControl.renewFullCovariance(nullptr); //
304 if(state.m_ApproximateVertex.size()==3 && fabs(state.m_ApproximateVertex[2])<m_IDsizeZ &&
306 {
307 xyz0[0]=(double)state.m_ApproximateVertex[0] - state.m_refFrameX;
308 xyz0[1]=(double)state.m_ApproximateVertex[1] - state.m_refFrameY;
309 xyz0[2]=(double)state.m_ApproximateVertex[2] - state.m_refFrameZ;
310 } else {
311 xyz0[0]=xyz0[1]=xyz0[2]=0.;
312 }
313 double par0[NTrMaxVFit][3]; //used only for fit preparation
314 Trk::cfpest( ntrk, xyz0, state.m_ich, state.m_apar, par0);
315
316 Chi2PerTrk.resize (ntrk);
317 ierr=Trk::CFit( &state.m_vkalFitControl, ifCovV0, ntrk, state.m_ich, xyz0, par0, state.m_apar, state.m_awgt,
318 xyzfit, state.m_parfs, ptot, covf, chi2f,
319 Chi2PerTrk.data());
320
321 if(msgLvl(MSG::DEBUG))msg(MSG::DEBUG) << "VKalVrt fit status="<<ierr<<" Chi2="<<chi2f<<endmsg;
322
323 Chi2 = 100000000.;
324 if(ierr){
325 return ierr;
326 }
327 if(ptot[0]*ptot[0]+ptot[1]*ptot[1] == 0.) return -5; // Bad (divergent) fit
328//
329// Postfit operation. Creation of array for different error calculations and full error matrix copy
330//
331 state.m_FitStatus=ntrk;
332 if(ifCovV0 && state.m_vkalFitControl.getFullCovariance()){ //If full fit error matrix is returned by VKalVrtCORE
333 int SymCovMtxSize=(3*ntrk+3)*(3*ntrk+4)/2;
334 state.m_ErrMtx.assign (state.m_vkalFitControl.getFullCovariance(),
335 state.m_vkalFitControl.getFullCovariance()+SymCovMtxSize);
337 ErrorMatrix.clear(); ErrorMatrix.reserve(21); ErrorMatrix.assign(covf,covf+21);
338 } else {
339 ErrorMatrix.clear(); ErrorMatrix.reserve(6); ErrorMatrix.assign(covf,covf+6);
340 }
341//---------------------------------------------------------------------------
342 Momentum.SetPxPyPzE( ptot[0], ptot[1], ptot[2], ptot[3] );
343 Chi2 = (double) chi2f;
344
345 Vertex[0]= xyzfit[0] + state.m_refFrameX;
346 Vertex[1]= xyzfit[1] + state.m_refFrameY;
347 Vertex[2]= xyzfit[2] + state.m_refFrameZ;
348
349 double sizeR = state.m_allowUltraDisplaced ? m_MSsizeR : m_IDsizeR;
350 double sizeZ = state.m_allowUltraDisplaced ? m_MSsizeZ : m_IDsizeZ;
351 if (Vertex.perp() > sizeR || std::abs(Vertex.z()) > sizeZ) return -5; // Solution outside acceptable volume due to divergence
352
353 state.m_save_xyzfit[0]=xyzfit[0]; // saving of vertex position
354 state.m_save_xyzfit[1]=xyzfit[1]; // for full error matrix
355 state.m_save_xyzfit[2]=xyzfit[2];
356//
357// ------ Magnetic field in fitted vertex
358//
359 double fx,fy,fz;
360 state.m_fitField.getMagFld(xyzfit[0] ,xyzfit[1] ,xyzfit[2] ,fx,fy,fz);
361
362 Charge=0; for(i=0; i<ntrk; i++){Charge+=state.m_ich[i];};
363 Charge=-Charge; //VK 30.11.2009 Change sign acoording to ATLAS
364
365
366 TrkAtVrt.clear(); TrkAtVrt.reserve(ntrk);
367 for(i=0; i<ntrk; i++){
368 std::vector<double> TrkPar(3);
369 double effectiveBMAG=state.m_fitField.getEffField(fx, fy, fz, state.m_parfs[i][1], state.m_parfs[i][0]);
370 if(std::abs(effectiveBMAG) < 0.01) effectiveBMAG=0.01; //safety
371 VKalToTrkTrack(effectiveBMAG,(double)state.m_parfs[i][0],(double)state.m_parfs[i][1],(double)state.m_parfs[i][2],
372 TrkPar[0],TrkPar[1],TrkPar[2]);
373 TrkPar[2] = -TrkPar[2]; // Change of sign needed
374 TrkAtVrt.push_back( std::move(TrkPar) );
375 }
376 return 0;
377 }
378
379
380
381// Converts Vertex, Mom, CovVrtMom in GLOBAL SYSTEM into perigee
382// Works correctly only in ID (solenoidal field)!
383//
384
386 const TLorentzVector& Momentum,
387 const dvect& CovVrtMom,
388 const long int& Charge,
389 dvect& Perigee,
390 dvect& CovPerigee,
391 IVKalState& istate) const
392 {
393 assert(dynamic_cast<State*> (&istate)!=nullptr);
394 State& state = static_cast<State&> (istate);
395 int i,j,ij;
396 double Vrt[3],PMom[4],Cov0[21],Per[5],CovPer[15];
397
398 for(i=0; i<3; i++) Vrt[i]=Vertex[i];
399 for(i=0; i<3; i++) PMom[i]=Momentum[i];
400 for(ij=i=0; i<6; i++){
401 for(j=0; j<=i; j++){
402 Cov0[ij]=CovVrtMom[ij];
403 ij++;
404 }
405 }
406 state.m_refFrameX=state.m_refFrameY=state.m_refFrameZ=0.; //VK Work in ATLAS ref frame ONLY!!!
407 long int vkCharge=-Charge; //VK 30.11.2009 Change sign according to ATLAS
408//
409// ------ Magnetic field in vertex (solenoidal field, ID only)
410//
411 double fx,fy,BMAG_CUR;
412 state.m_fitField.getMagFld(Vrt[0], Vrt[1], Vrt[2] ,fx,fy,BMAG_CUR);
413 if(fabs(BMAG_CUR) < 0.01) BMAG_CUR=0.01; // Safety
414
415 Trk::xyztrp( vkCharge, Vrt, PMom, Cov0, BMAG_CUR, Per, CovPer );
416
417 Perigee.clear();
418 CovPerigee.clear();
419
420 for(i=0; i<5; i++) Perigee.push_back((double)Per[i]);
421 for(i=0; i<15; i++) CovPerigee.push_back((double)CovPer[i]);
422
423 return StatusCode::SUCCESS;
424 }
425
426
427 void TrkVKalVrtFitter::VKalToTrkTrack( double effectiveBMAG, double vp1, double vp2, double vp3,
428 double& tp1, double& tp2, double& tp3) const
429//tp - ATLAS parameters, vp - VKalVrt parameters//
430 { tp1= vp2; //phi angle
431 tp2= vp1; //theta angle
432 tp3= vp3 * std::sin( vp1 ) /(m_CNVMAG*effectiveBMAG);
433 constexpr double pi = M_PI;
434 // -pi < phi < pi range
435 while ( tp1 > pi) tp1 -= 2.*pi;
436 while ( tp1 <-pi) tp1 += 2.*pi;
437 // 0 < Theta < pi range
438 while ( tp2 > pi) tp2 -= 2.*pi;
439 while ( tp2 <-pi) tp2 += 2.*pi;
440 if ( tp2 < 0.) {
441 tp2 = fabs(tp2); tp1 += pi;
442 while ( tp1 > pi) tp1 -= 2.*pi;
443 }
444
445 }
446
447
448/* Returns a complete error matrix after fit
449 useMom=0 def (V,Perigee1,Perigee2....PerigeeNTrk)
450 useMom=1 (V,PxPyPz1,PxPyPz2....PxPyPzNTrk)
451*/
452
453
454 StatusCode
455 TrkVKalVrtFitter::VKalGetFullCov( long int NTrk, dvect& CovVrtTrk,
456 IVKalState& istate,
457 bool useMom) const
458 {
459 assert(dynamic_cast<State*> (&istate)!=nullptr);
460 State& state = static_cast<State&> (istate);
461 if(!state.m_FitStatus) return StatusCode::FAILURE;
462 if(NTrk<1) return StatusCode::FAILURE;
463 if(NTrk>NTrMaxVFit) return StatusCode::FAILURE;
464 if(state.m_ErrMtx.empty()) return StatusCode::FAILURE; //Now error matrix is taken from CORE in VKalVrtFit3.
465//
466// ------ Magnetic field access
467//
468 double fx,fy,fz;
469 state.m_fitField.getMagFld(state.m_save_xyzfit[0],state.m_save_xyzfit[1],state.m_save_xyzfit[2],fx,fy,fz);
470//
471// ------ Base code
472//
473 int i,j,ik,jk,ip,iTrk;
474 int DIM=3*NTrk+3; //Current size of full covariance matrix
475 std::vector<std::vector<double> > Deriv (DIM);
476 for (std::vector<double>& v : Deriv) v.resize (DIM);
477 std::vector<double> CovMtxOld(DIM*DIM);
478
479
480 CovVrtTrk.resize(DIM*(DIM+1)/2);
481
482 ip=0;
483 for( i=0; i<DIM;i++) {
484 for( j=0; j<=i; j++) {
485 CovMtxOld[i*DIM+j]=CovMtxOld[j*DIM+i]=state.m_ErrMtx[ip++];
486 }
487 }
488
489 //delete [] ErrMtx;
490
491 for(i=0;i<DIM;i++){ for(j=0;j<DIM;j++) {Deriv[i][j]=0.;}}
492 Deriv[0][0]= 1.;
493 Deriv[1][1]= 1.;
494 Deriv[2][2]= 1.;
495
496 int iSt=0;
497 double Theta,invR,Phi;
498 for( iTrk=0; iTrk<NTrk; iTrk++){
499 Theta=state.m_parfs[iTrk][0];
500 Phi =state.m_parfs[iTrk][1];
501 invR =state.m_parfs[iTrk][2];
502 double effectiveBMAG=state.m_fitField.getEffField(fx, fy, fz, Phi, Theta);
503 if(std::abs(effectiveBMAG) < 0.01) effectiveBMAG = 0.01;
504
505 /*-----------*/
506 /* dNew/dOld */
507 iSt = 3 + iTrk*3;
508 if( !useMom ){
509 Deriv[iSt ][iSt+1] = 1; // Phi <-> Theta
510 Deriv[iSt+1][iSt ] = 1; // Phi <-> Theta
511 Deriv[iSt+2][iSt ] = -(cos(Theta)/(m_CNVMAG*effectiveBMAG)) * invR ; // d1/p / dTheta
512 Deriv[iSt+2][iSt+2] = -(sin(Theta)/(m_CNVMAG*effectiveBMAG)) ; // d1/p / d1/R
513 }else{
514 double pt=std::abs(m_CNVMAG*effectiveBMAG/invR);
515 double px=pt*cos(Phi);
516 double py=pt*sin(Phi);
517 double pz=pt/tan(Theta);
518 Deriv[iSt ][iSt ]= 0; //dPx/dTheta
519 Deriv[iSt ][iSt+1]= -py; //dPx/dPhi
520 Deriv[iSt ][iSt+2]= -px/invR; //dPx/dinvR
521
522 Deriv[iSt+1][iSt ]= 0; //dPy/dTheta
523 Deriv[iSt+1][iSt+1]= px; //dPy/dPhi
524 Deriv[iSt+1][iSt+2]= -py/invR; //dPy/dinvR
525
526 Deriv[iSt+2][iSt ]= -pt/sin(Theta)/sin(Theta); //dPz/dTheta
527 Deriv[iSt+2][iSt+1]= 0; //dPz/dPhi
528 Deriv[iSt+2][iSt+2]= -pz/invR; //dPz/dinvR
529 }
530 }
531//---------- Only upper half if filled and saved
532 int ipnt=0;
533 double tmp, tmpTmp;
534 for(i=0;i<DIM;i++){
535 for(j=0;j<=i;j++){
536 tmp=0.;
537 for(ik=0;ik<DIM;ik++){
538 if(Deriv[i][ik] == 0.) continue;
539 tmpTmp=0;
540 for(jk=DIM-1;jk>=0;jk--){
541 if(Deriv[j][jk] == 0.) continue;
542 tmpTmp += CovMtxOld[ik*DIM+jk]*Deriv[j][jk];
543 }
544 tmp += Deriv[i][ik]*tmpTmp;
545 }
546 CovVrtTrk[ipnt++]=tmp;
547 }}
548
549 return StatusCode::SUCCESS;
550
551 }
552
553
554
555
556
557 StatusCode TrkVKalVrtFitter::VKalGetMassError( double& dM, double& MassError,
558 const IVKalState& istate) const
559 {
560 assert(dynamic_cast<const State*> (&istate)!=nullptr);
561 const State& state = static_cast<const State&> (istate);
562 if(!state.m_FitStatus) return StatusCode::FAILURE;
563 dM = state.m_vkalFitControl.getVertexMass();
564 MassError = state.m_vkalFitControl.getVrtMassError();
565 return StatusCode::SUCCESS;
566 }
567
568
570 const IVKalState& istate) const
571 {
572 assert(dynamic_cast<const State*> (&istate)!=nullptr);
573 const State& state = static_cast<const State&> (istate);
574 if(!state.m_FitStatus) return StatusCode::FAILURE; // no fit made
575 trkWeights.clear();
576
577 int NTRK=state.m_FitStatus;
578
579 for (int i=0; i<NTRK; i++) trkWeights.push_back(state.m_vkalFitControl.vk_forcft.robres[i]);
580
581 return StatusCode::SUCCESS;
582 }
583
584
586 {
587 if(!state.m_FitStatus) return 0;
588 int NDOF=2*state.m_FitStatus-3;
589 if(state.m_usePointingCnst) { NDOF+=2; }
590 else if(state.m_useZPointingCnst) { NDOF+=1; }
591 if( state.m_usePassNear || state.m_usePassWithTrkErr ) { NDOF+= 2; }
592
593 if( state.m_massForConstraint>0. ) { NDOF+=1; }
594 if( !state.m_partMassCnst.empty() ) { NDOF+= state.m_partMassCnst.size(); }
595 if( state.m_useAprioriVertex ) { NDOF+= 3; }
596 if( state.m_usePhiCnst ) { NDOF+=1; }
597 if( state.m_useThetaCnst ) { NDOF+=1; }
598 return NDOF;
599 }
600
601}
#define M_PI
#define endmsg
static Double_t sc
#define pi
const Amg::Vector3D & position() const
Access method for the position.
std::vector< double > m_partMassCnst
std::vector< double > m_ApproximateVertex
double m_apar[NTrMaxVFit][5]
double m_awgt[NTrMaxVFit][15]
double m_parfs[NTrMaxVFit][3]
const TrackParameters * m_globalFirstHit
std::vector< double > m_ErrMtx
StatusCode CvtTrackParameters(const std::vector< const TrackParameters * > &InpTrk, int &ntrk, State &state) const
void VKalVrtConfigureFitterCore(int NTRK, State &state) const
const IExtrapolator * m_InDetExtrapolator
Pointer to Extrapolator AlgTool.
Gaudi::Property< double > m_MSsizeZ
virtual StatusCode VKalVrtCvtTool(const Amg::Vector3D &Vertex, const TLorentzVector &Momentum, const dvect &CovVrtMom, const long int &Charge, dvect &Perigee, dvect &CovPerigee, IVKalState &istate) const override final
StatusCode CvtPerigee(const std::vector< const Perigee * > &list, int &ntrk, State &state) const
virtual StatusCode VKalGetMassError(double &Mass, double &MassError, const IVKalState &istate) const override final
Gaudi::Property< double > m_IDsizeZ
int VKalVrtFit3(int ntrk, Amg::Vector3D &Vertex, TLorentzVector &Momentum, long int &Charge, dvect &ErrorMatrix, dvect &Chi2PerTrk, std::vector< std::vector< double > > &TrkAtVrt, double &Chi2, State &state, bool ifCovV0) const
virtual StatusCode VKalGetFullCov(long int, dvect &CovMtx, IVKalState &istate, bool=false) const override final
virtual StatusCode VKalVrtFit(const std::vector< const xAOD::TrackParticle * > &, const std::vector< const xAOD::NeutralParticle * > &, Amg::Vector3D &Vertex, TLorentzVector &Momentum, long int &Charge, dvect &ErrorMatrix, dvect &Chi2PerTrk, std::vector< std::vector< double > > &TrkAtVrt, double &Chi2, IVKalState &istate, bool ifCovV0=false) const override final
Gaudi::Property< bool > m_firstMeasuredPoint
virtual StatusCode VKalGetTrkWeights(dvect &Weights, const IVKalState &istate) const override final
static int VKalGetNDOF(const State &state)
Gaudi::Property< bool > m_firstMeasuredRadiusLimit
StatusCode CvtTrackParticle(std::span< const xAOD::TrackParticle *const > list, int &ntrk, State &state) const
VKalExtPropagator * m_fitPropagator
Gaudi::Property< double > m_IDsizeR
Gaudi::Property< bool > m_firstMeasuredPointLimit
StatusCode CvtNeutralParticle(const std::vector< const xAOD::NeutralParticle * > &list, int &ntrk, State &state) const
Gaudi::Property< double > m_MSsizeR
void VKalToTrkTrack(double curBMAG, double vp1, double vp2, double vp3, double &tp1, double &tp2, double &tp3) const
StatusCode CvtNeutralParameters(const std::vector< const NeutralParameters * > &InpTrk, int &ntrk, State &state) const
virtual void getMagFld(const double, const double, const double, double &, double &, double &) override
void renewFullCovariance(double *)
double getVertexMass() const
void setVertexMass(double mass)
double getVrtMassError() const
void setUsePlaneCnst(double a, double b, double c, double d)
void setVrtMassError(double error)
const double * getFullCovariance() const
This class is a simplest representation of a vertex candidate.
double getEffField(double bx, double by, double bz, double phi, double theta)
Definition VKalVrtBMag.h:41
Eigen::Matrix< double, 3, 1 > Vector3D
Ensure that the ATLAS eigen extensions are properly loaded.
void xyztrp(const long int ich, double *vrt0, double *pv0, double *covi, double BMAG, double *paro, double *errt)
Definition XYZtrp.cxx:16
int CFit(VKalVrtControl *FitCONTROL, int ifCovV0, int NTRK, long int *ich, double xyz0[3], double(*par0)[3], double(*inp_Trk5)[5], double(*inp_CovTrk5)[15], double xyzfit[3], double(*parfs)[3], double ptot[4], double covf[21], double &chi2, double *chi2tr)
Definition CFit.cxx:445
ParametersT< TrackParametersDim, Charged, PerigeeSurface > Perigee
void cfpest(int ntrk, double *xyz, long int *ich, double(*parst)[5], double(*parf)[3])
Definition cfPEst.cxx:10
@ x
Definition ParamDefs.h:55
@ z
global position (cartesian)
Definition ParamDefs.h:57
@ pz
global momentum (cartesian)
Definition ParamDefs.h:61
@ v
Definition ParamDefs.h:78
@ y
Definition ParamDefs.h:56
@ px
Definition ParamDefs.h:59
@ py
Definition ParamDefs.h:60
std::vector< double > dvect
TrackParticle_v1 TrackParticle
Reference the current persistent version:
@ FirstMeasurement
Parameter defined at the position of the 1st measurement.
double robres[vkalNTrkM]
Definition ForCFT.h:51
MsgStream & msg
Definition testRead.cxx:32