ATLAS Offline Software
Loading...
Searching...
No Matches
VKalVrtFitSvc.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 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 }
157 }
158 Amg::Vector3D unitMom=Amg::Vector3D(Momentum.Px()/Momentum.P(),Momentum.Py()/Momentum.P(),Momentum.Pz()/Momentum.P());
159 //----------- Use as reference either hit(state.m_globalFirstHit) or its radius(closestHitR) if hit is absent
160 if(state.m_globalFirstHit)cnstRefPoint=state.m_globalFirstHit->position();
161 //------------
162 if(Vertex.perp()>closestHitR && cnstRefPoint.perp()>0.){
163 if(msgLvl(MSG::DEBUG))msg(MSG::DEBUG)<<"Vertex behind first measured point is detected. Constraint is applied!"<<endmsg;
164 state.m_planeCnstNDOF = 1; // Additional NDOF due to plane constraint
165 double D= unitMom.x()*(cnstRefPoint.x()-state.m_refFrameX)
166 +unitMom.y()*(cnstRefPoint.y()-state.m_refFrameY)
167 +unitMom.z()*(cnstRefPoint.z()-state.m_refFrameZ);
168 state.m_parPlaneCnst[0]=unitMom.x();
169 state.m_parPlaneCnst[1]=unitMom.y();
170 state.m_parPlaneCnst[2]=unitMom.z();
171 state.m_parPlaneCnst[3]=D;
172 state.m_cnstRadius=std::sqrt(std::pow(cnstRefPoint.x()-state.m_refFrameX,2.)+std::pow(cnstRefPoint.y()-state.m_refFrameY,2.));
173 state.m_cnstRadiusRef[0]=-state.m_refFrameX;
174 state.m_cnstRadiusRef[1]=-state.m_refFrameY;
175 std::vector<double> saveApproxV(3,0.); state.m_ApproximateVertex.swap(saveApproxV);
176 state.m_ApproximateVertex[0]=cnstRefPoint.x();
177 state.m_ApproximateVertex[1]=cnstRefPoint.y();
178 state.m_ApproximateVertex[2]=cnstRefPoint.z();
179 ierr = VKalVrtFit3( ntrk, Vertex, Momentum, Charge, ErrorMatrix, Chi2PerTrk, TrkAtVrt, Chi2, state, ifCovV0 );
180 state.m_vkalFitControl.setUsePlaneCnst(0.,0.,0.,0.);
181 if (ierr) { // refit without plane cnst
182 ierr = VKalVrtFit3(ntrk,Vertex,Momentum,Charge,ErrorMatrix,Chi2PerTrk,TrkAtVrt,Chi2, state, ifCovV0); // if fit with it failed
183 state.m_planeCnstNDOF = 0;
184 }
185 state.m_ApproximateVertex.swap(saveApproxV);
186 }
187 }
188 //--
189 if (ierr) return StatusCode::FAILURE;
190 return StatusCode::SUCCESS;
191}
192
193
194StatusCode TrkVKalVrtFitter::VKalVrtFit(const std::vector<const TrackParameters*> & InpTrkC,
195 const std::vector<const NeutralParameters*> & InpTrkN,
197 TLorentzVector& Momentum,
198 long int& Charge,
200 dvect& Chi2PerTrk,
201 std::vector< std::vector<double> >& TrkAtVrt,
202 double& Chi2,
203 IVKalState& istate,
204 bool ifCovV0 /*= false*/) const
205{
206 assert(dynamic_cast<State*> (&istate)!=nullptr);
207 State& state = static_cast<State&> (istate);
208
209//
210//------ extract information about selected tracks
211//
212 int ntrk=0;
213 state.m_globalFirstHit = nullptr;
214 StatusCode sc;
215 if(!InpTrkC.empty()){
216 sc=CvtTrackParameters(InpTrkC,ntrk,state);
217 if(sc.isFailure())return StatusCode::FAILURE;
218 }
219 if(!InpTrkN.empty()){
220 sc=CvtNeutralParameters(InpTrkN,ntrk,state);
221 if(sc.isFailure())return StatusCode::FAILURE;
222 }
223
224 if(state.m_ApproximateVertex.empty() && state.m_globalFirstHit){ //Initial guess if absent
225 state.m_ApproximateVertex.reserve(3);
226 state.m_ApproximateVertex.push_back(state.m_globalFirstHit->position().x());
227 state.m_ApproximateVertex.push_back(state.m_globalFirstHit->position().y());
228 state.m_ApproximateVertex.push_back(state.m_globalFirstHit->position().z());
229 }
230 int ierr = VKalVrtFit3( ntrk, Vertex, Momentum, Charge, ErrorMatrix, Chi2PerTrk, TrkAtVrt,Chi2, state, ifCovV0 ) ;
231 if (ierr) return StatusCode::FAILURE;
232//
233//-- Check vertex position with respect to first measured hit and refit with plane constraint if needed
234 state.m_planeCnstNDOF = 0;
235 if(state.m_globalFirstHit && m_firstMeasuredPointLimit && !ierr){
236 if(Vertex.perp()>state.m_globalFirstHit->position().perp()){
237 if(msgLvl(MSG::DEBUG))msg(MSG::DEBUG)<<"Vertex behind first measured point is detected. Constraint is applied!"<<endmsg;
238 state.m_planeCnstNDOF = 1; // Additional NDOF due to plane constraint
239 double pp[3]={Momentum.Px()/Momentum.Rho(),Momentum.Py()/Momentum.Rho(),Momentum.Pz()/Momentum.Rho()};
240 double D= pp[0]*(state.m_globalFirstHit->position().x()-state.m_refFrameX)
241 +pp[1]*(state.m_globalFirstHit->position().y()-state.m_refFrameY)
242 +pp[2]*(state.m_globalFirstHit->position().z()-state.m_refFrameZ);
243 state.m_vkalFitControl.setUsePlaneCnst( pp[0], pp[1], pp[2], D);
244 std::vector<double> saveApproxV(3,0.); state.m_ApproximateVertex.swap(saveApproxV);
245 state.m_ApproximateVertex[0]=state.m_globalFirstHit->position().x();
246 state.m_ApproximateVertex[1]=state.m_globalFirstHit->position().y();
247 state.m_ApproximateVertex[2]=state.m_globalFirstHit->position().z();
248 ierr = VKalVrtFit3( ntrk, Vertex, Momentum, Charge, ErrorMatrix, Chi2PerTrk, TrkAtVrt,Chi2, state, ifCovV0 ) ;
249 state.m_vkalFitControl.setUsePlaneCnst(0.,0.,0.,0.);
250 if (ierr) { // refit without plane cnst
251 ierr = VKalVrtFit3(ntrk,Vertex,Momentum,Charge,ErrorMatrix,Chi2PerTrk,TrkAtVrt,Chi2, state, ifCovV0 ) ; // if fit with it failed
252 state.m_planeCnstNDOF = 0;
253 }
254 state.m_ApproximateVertex.swap(saveApproxV);
255 }
256 }
257 if (ierr) return StatusCode::FAILURE;
258 return StatusCode::SUCCESS;
259}
260
261
262
263
264
265
266//--------------------------------------------------------------------------------------------------
267// Main code
268//
271 TLorentzVector& Momentum,
272 long int& Charge,
274 dvect& Chi2PerTrk,
275 std::vector< std::vector<double> >& TrkAtVrt,
276 double& Chi2,
277 State& state,
278 bool ifCovV0) const
279{
280//
281//------ Variables and arrays needed for fitting kernel
282//
283 int ierr,i;
284 double xyz0[3],covf[21],chi2f=-10.;
285 double ptot[4]={0.};
286 double xyzfit[3]={0.};
287//
288//--- Set field value at (0.,0.,0.) - some safety
289//
290 double Bx,By,Bz;
291 state.m_fitField.getMagFld(-state.m_refFrameX,-state.m_refFrameY,-state.m_refFrameZ,Bx,By,Bz);
292//
293//------ Fit option setting
294//
295 VKalVrtConfigureFitterCore(ntrk, state);
296//
297//------ Fit itself
298//
299 state.m_FitStatus=0;
300 state.m_vkalFitControl.renewFullCovariance(nullptr); //
303 if(state.m_ApproximateVertex.size()==3 && fabs(state.m_ApproximateVertex[2])<m_IDsizeZ &&
305 {
306 xyz0[0]=(double)state.m_ApproximateVertex[0] - state.m_refFrameX;
307 xyz0[1]=(double)state.m_ApproximateVertex[1] - state.m_refFrameY;
308 xyz0[2]=(double)state.m_ApproximateVertex[2] - state.m_refFrameZ;
309 } else {
310 xyz0[0]=xyz0[1]=xyz0[2]=0.;
311 }
312 double par0[NTrMaxVFit][3]; //used only for fit preparation
313 Trk::cfpest( ntrk, xyz0, state.m_ich, state.m_apar, par0);
314
315 Chi2PerTrk.resize (ntrk);
316 ierr=Trk::CFit( &state.m_vkalFitControl, ifCovV0, ntrk, state.m_ich, xyz0, par0, state.m_apar, state.m_awgt,
317 xyzfit, state.m_parfs, ptot, covf, chi2f,
318 Chi2PerTrk.data());
319
320 if(msgLvl(MSG::DEBUG))msg(MSG::DEBUG) << "VKalVrt fit status="<<ierr<<" Chi2="<<chi2f<<endmsg;
321
322 Chi2 = 100000000.;
323 if(ierr){
324 return ierr;
325 }
326 if(ptot[0]*ptot[0]+ptot[1]*ptot[1] == 0.) return -5; // Bad (divergent) fit
327//
328// Postfit operation. Creation of array for different error calculations and full error matrix copy
329//
330 state.m_FitStatus=ntrk;
331 if(ifCovV0 && state.m_vkalFitControl.getFullCovariance()){ //If full fit error matrix is returned by VKalVrtCORE
332 int SymCovMtxSize=(3*ntrk+3)*(3*ntrk+4)/2;
333 state.m_ErrMtx.assign (state.m_vkalFitControl.getFullCovariance(),
334 state.m_vkalFitControl.getFullCovariance()+SymCovMtxSize);
336 ErrorMatrix.clear(); ErrorMatrix.reserve(21); ErrorMatrix.assign(covf,covf+21);
337 } else {
338 ErrorMatrix.clear(); ErrorMatrix.reserve(6); ErrorMatrix.assign(covf,covf+6);
339 }
340//---------------------------------------------------------------------------
341 Momentum.SetPxPyPzE( ptot[0], ptot[1], ptot[2], ptot[3] );
342 Chi2 = (double) chi2f;
343
344 Vertex[0]= xyzfit[0] + state.m_refFrameX;
345 Vertex[1]= xyzfit[1] + state.m_refFrameY;
346 Vertex[2]= xyzfit[2] + state.m_refFrameZ;
347
348 double sizeR = state.m_allowUltraDisplaced ? m_MSsizeR : m_IDsizeR;
349 double sizeZ = state.m_allowUltraDisplaced ? m_MSsizeZ : m_IDsizeZ;
350 if (Vertex.perp() > sizeR || std::abs(Vertex.z()) > sizeZ) return -5; // Solution outside acceptable volume due to divergence
351
352 state.m_save_xyzfit[0]=xyzfit[0]; // saving of vertex position
353 state.m_save_xyzfit[1]=xyzfit[1]; // for full error matrix
354 state.m_save_xyzfit[2]=xyzfit[2];
355//
356// ------ Magnetic field in fitted vertex
357//
358 double fx,fy,fz;
359 state.m_fitField.getMagFld(xyzfit[0] ,xyzfit[1] ,xyzfit[2] ,fx,fy,fz);
360
361 Charge=0; for(i=0; i<ntrk; i++){Charge+=state.m_ich[i];};
362 Charge=-Charge; //VK 30.11.2009 Change sign acoording to ATLAS
363
364
365 TrkAtVrt.clear(); TrkAtVrt.reserve(ntrk);
366 for(i=0; i<ntrk; i++){
367 std::vector<double> TrkPar(3);
368 double effectiveBMAG=state.m_fitField.getEffField(fx, fy, fz, state.m_parfs[i][1], state.m_parfs[i][0]);
369 if(std::abs(effectiveBMAG) < 0.01) effectiveBMAG=0.01; //safety
370 VKalToTrkTrack(effectiveBMAG,(double)state.m_parfs[i][0],(double)state.m_parfs[i][1],(double)state.m_parfs[i][2],
371 TrkPar[0],TrkPar[1],TrkPar[2]);
372 TrkPar[2] = -TrkPar[2]; // Change of sign needed
373 TrkAtVrt.push_back( TrkPar );
374 }
375 return 0;
376 }
377
378
379
380// Converts Vertex, Mom, CovVrtMom in GLOBAL SYSTEM into perigee
381// Works correctly only in ID (solenoidal field)!
382//
383
385 const TLorentzVector& Momentum,
386 const dvect& CovVrtMom,
387 const long int& Charge,
388 dvect& Perigee,
389 dvect& CovPerigee,
390 IVKalState& istate) const
391 {
392 assert(dynamic_cast<State*> (&istate)!=nullptr);
393 State& state = static_cast<State&> (istate);
394 int i,j,ij;
395 double Vrt[3],PMom[4],Cov0[21],Per[5],CovPer[15];
396
397 for(i=0; i<3; i++) Vrt[i]=Vertex[i];
398 for(i=0; i<3; i++) PMom[i]=Momentum[i];
399 for(ij=i=0; i<6; i++){
400 for(j=0; j<=i; j++){
401 Cov0[ij]=CovVrtMom[ij];
402 ij++;
403 }
404 }
405 state.m_refFrameX=state.m_refFrameY=state.m_refFrameZ=0.; //VK Work in ATLAS ref frame ONLY!!!
406 long int vkCharge=-Charge; //VK 30.11.2009 Change sign according to ATLAS
407//
408// ------ Magnetic field in vertex (solenoidal field, ID only)
409//
410 double fx,fy,BMAG_CUR;
411 state.m_fitField.getMagFld(Vrt[0], Vrt[1], Vrt[2] ,fx,fy,BMAG_CUR);
412 if(fabs(BMAG_CUR) < 0.01) BMAG_CUR=0.01; // Safety
413
414 Trk::xyztrp( vkCharge, Vrt, PMom, Cov0, BMAG_CUR, Per, CovPer );
415
416 Perigee.clear();
417 CovPerigee.clear();
418
419 for(i=0; i<5; i++) Perigee.push_back((double)Per[i]);
420 for(i=0; i<15; i++) CovPerigee.push_back((double)CovPer[i]);
421
422 return StatusCode::SUCCESS;
423 }
424
425
426 void TrkVKalVrtFitter::VKalToTrkTrack( double effectiveBMAG, double vp1, double vp2, double vp3,
427 double& tp1, double& tp2, double& tp3) const
428//tp - ATLAS parameters, vp - VKalVrt parameters//
429 { tp1= vp2; //phi angle
430 tp2= vp1; //theta angle
431 tp3= vp3 * std::sin( vp1 ) /(m_CNVMAG*effectiveBMAG);
432 constexpr double pi = M_PI;
433 // -pi < phi < pi range
434 while ( tp1 > pi) tp1 -= 2.*pi;
435 while ( tp1 <-pi) tp1 += 2.*pi;
436 // 0 < Theta < pi range
437 while ( tp2 > pi) tp2 -= 2.*pi;
438 while ( tp2 <-pi) tp2 += 2.*pi;
439 if ( tp2 < 0.) {
440 tp2 = fabs(tp2); tp1 += pi;
441 while ( tp1 > pi) tp1 -= 2.*pi;
442 }
443
444 }
445
446
447/* Returns a complete error matrix after fit
448 useMom=0 def (V,Perigee1,Perigee2....PerigeeNTrk)
449 useMom=1 (V,PxPyPz1,PxPyPz2....PxPyPzNTrk)
450*/
451
452
453 StatusCode
454 TrkVKalVrtFitter::VKalGetFullCov( long int NTrk, dvect& CovVrtTrk,
455 IVKalState& istate,
456 bool useMom) const
457 {
458 assert(dynamic_cast<State*> (&istate)!=nullptr);
459 State& state = static_cast<State&> (istate);
460 if(!state.m_FitStatus) return StatusCode::FAILURE;
461 if(NTrk<1) return StatusCode::FAILURE;
462 if(NTrk>NTrMaxVFit) return StatusCode::FAILURE;
463 if(state.m_ErrMtx.empty()) return StatusCode::FAILURE; //Now error matrix is taken from CORE in VKalVrtFit3.
464//
465// ------ Magnetic field access
466//
467 double fx,fy,fz;
468 state.m_fitField.getMagFld(state.m_save_xyzfit[0],state.m_save_xyzfit[1],state.m_save_xyzfit[2],fx,fy,fz);
469//
470// ------ Base code
471//
472 int i,j,ik,jk,ip,iTrk;
473 int DIM=3*NTrk+3; //Current size of full covariance matrix
474 std::vector<std::vector<double> > Deriv (DIM);
475 for (std::vector<double>& v : Deriv) v.resize (DIM);
476 std::vector<double> CovMtxOld(DIM*DIM);
477
478
479 CovVrtTrk.resize(DIM*(DIM+1)/2);
480
481 ip=0;
482 for( i=0; i<DIM;i++) {
483 for( j=0; j<=i; j++) {
484 CovMtxOld[i*DIM+j]=CovMtxOld[j*DIM+i]=state.m_ErrMtx[ip++];
485 }
486 }
487
488 //delete [] ErrMtx;
489
490 for(i=0;i<DIM;i++){ for(j=0;j<DIM;j++) {Deriv[i][j]=0.;}}
491 Deriv[0][0]= 1.;
492 Deriv[1][1]= 1.;
493 Deriv[2][2]= 1.;
494
495 int iSt=0;
496 double Theta,invR,Phi;
497 for( iTrk=0; iTrk<NTrk; iTrk++){
498 Theta=state.m_parfs[iTrk][0];
499 Phi =state.m_parfs[iTrk][1];
500 invR =state.m_parfs[iTrk][2];
501 double effectiveBMAG=state.m_fitField.getEffField(fx, fy, fz, Phi, Theta);
502 if(std::abs(effectiveBMAG) < 0.01) effectiveBMAG = 0.01;
503
504 /*-----------*/
505 /* dNew/dOld */
506 iSt = 3 + iTrk*3;
507 if( !useMom ){
508 Deriv[iSt ][iSt+1] = 1; // Phi <-> Theta
509 Deriv[iSt+1][iSt ] = 1; // Phi <-> Theta
510 Deriv[iSt+2][iSt ] = -(cos(Theta)/(m_CNVMAG*effectiveBMAG)) * invR ; // d1/p / dTheta
511 Deriv[iSt+2][iSt+2] = -(sin(Theta)/(m_CNVMAG*effectiveBMAG)) ; // d1/p / d1/R
512 }else{
513 double pt=std::abs(m_CNVMAG*effectiveBMAG/invR);
514 double px=pt*cos(Phi);
515 double py=pt*sin(Phi);
516 double pz=pt/tan(Theta);
517 Deriv[iSt ][iSt ]= 0; //dPx/dTheta
518 Deriv[iSt ][iSt+1]= -py; //dPx/dPhi
519 Deriv[iSt ][iSt+2]= -px/invR; //dPx/dinvR
520
521 Deriv[iSt+1][iSt ]= 0; //dPy/dTheta
522 Deriv[iSt+1][iSt+1]= px; //dPy/dPhi
523 Deriv[iSt+1][iSt+2]= -py/invR; //dPy/dinvR
524
525 Deriv[iSt+2][iSt ]= -pt/sin(Theta)/sin(Theta); //dPz/dTheta
526 Deriv[iSt+2][iSt+1]= 0; //dPz/dPhi
527 Deriv[iSt+2][iSt+2]= -pz/invR; //dPz/dinvR
528 }
529 }
530//---------- Only upper half if filled and saved
531 int ipnt=0;
532 double tmp, tmpTmp;
533 for(i=0;i<DIM;i++){
534 for(j=0;j<=i;j++){
535 tmp=0.;
536 for(ik=0;ik<DIM;ik++){
537 if(Deriv[i][ik] == 0.) continue;
538 tmpTmp=0;
539 for(jk=DIM-1;jk>=0;jk--){
540 if(Deriv[j][jk] == 0.) continue;
541 tmpTmp += CovMtxOld[ik*DIM+jk]*Deriv[j][jk];
542 }
543 tmp += Deriv[i][ik]*tmpTmp;
544 }
545 CovVrtTrk[ipnt++]=tmp;
546 }}
547
548 return StatusCode::SUCCESS;
549
550 }
551
552
553
554
555
556 StatusCode TrkVKalVrtFitter::VKalGetMassError( double& dM, double& MassError,
557 const IVKalState& istate) const
558 {
559 assert(dynamic_cast<const State*> (&istate)!=nullptr);
560 const State& state = static_cast<const State&> (istate);
561 if(!state.m_FitStatus) return StatusCode::FAILURE;
562 dM = state.m_vkalFitControl.getVertexMass();
563 MassError = state.m_vkalFitControl.getVrtMassError();
564 return StatusCode::SUCCESS;
565 }
566
567
569 const IVKalState& istate) const
570 {
571 assert(dynamic_cast<const State*> (&istate)!=nullptr);
572 const State& state = static_cast<const State&> (istate);
573 if(!state.m_FitStatus) return StatusCode::FAILURE; // no fit made
574 trkWeights.clear();
575
576 int NTRK=state.m_FitStatus;
577
578 for (int i=0; i<NTRK; i++) trkWeights.push_back(state.m_vkalFitControl.vk_forcft.robres[i]);
579
580 return StatusCode::SUCCESS;
581 }
582
583
585 {
586 if(!state.m_FitStatus) return 0;
587 int NDOF=2*state.m_FitStatus-3;
588 if(state.m_usePointingCnst) { NDOF+=2; }
589 else if(state.m_useZPointingCnst) { NDOF+=1; }
590 if( state.m_usePassNear || state.m_usePassWithTrkErr ) { NDOF+= 2; }
591
592 if( state.m_massForConstraint>0. ) { NDOF+=1; }
593 if( !state.m_partMassCnst.empty() ) { NDOF+= state.m_partMassCnst.size(); }
594 if( state.m_useAprioriVertex ) { NDOF+= 3; }
595 if( state.m_usePhiCnst ) { NDOF+=1; }
596 if( state.m_useThetaCnst ) { NDOF+=1; }
597 return NDOF;
598 }
599
600}
#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:436
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