4 #include "StiTrackNodeHelper.h"
5 #include "StiElossCalculator.h"
6 #include "StDetectorDbMaker/StiHitErrorCalculator.h"
14 #define NICE(a) ( ((a) <= -M_PI)? ((a)+2*M_PI) :\
15 ((a) > M_PI)? ((a)-2*M_PI) : (a))
17 #define sinX(a) StiTrackNode::sinX(a)
18 static const double kMaxEta = 1.5;
19 static const double kMaxCur = 0.2;
20 static const double kMaxSin = 0.99;
21 static const double kMinCos = sqrt(1.-kMaxSin*kMaxSin);
23 static const double DY=0.9,DZ=0.9,DEta=0.1,DPti=3,DTan=0.1;
24 static const double MAXSTEP[]={0,DY,DZ,DEta,DPti,DTan};
25 static const double ERROR_FACTOR = 2.;
26 int StiTrackNodeHelper::_debug = 0;
27 int StiTrackNodeHelper::mgCutStep=0;
35 void StiTrackNodeHelper::set(
double chi2Max,
double chi2Vtx,
double errConfidence,
int iter)
42 if (errConfidence>0.1) {
43 mNodeErrFactor = (1./(errConfidence));
44 mHitsErrFactor = (1./(1. - errConfidence));
47 if (!mIter) mFlipFlopNode = 0;
50 void StiTrackNodeHelper::reset()
52 memset(mBeg,
'A',mEnd-mBeg+1);
63 static const double EC = 2.99792458e-4;
67 mTargetHz = mTargetNode->
getHz();
68 mParentHz = mTargetHz;
70 mParentHz = mParentNode->
getHz();
71 assert(fabs(mParentHz-mParentNode->mFP.hz()) < EC*0.1);
73 mParentNode->mFP.check(
"2StiTrackNodeHelper::set");
76 if (mTargetNode->isValid()) {
78 mTargetNode->mFP.check(
"1StiTrackNodeHelper::set");
80 assert(fabs(mTargetHz-mTargetNode->mFP.hz()) < EC*0.1);
83 mDetector = mTargetNode->getDetector();
84 if (!mDetector) mVertexNode = mTargetNode;
85 mHit = mTargetNode->getHit();
88 if (mHit->vy() || mHit->vz()) time = mTargetNode->getTime();
89 mHitPars[0]=mHit->
x();
90 mHitPars[1]=mHit->y(time);
91 mHitPars[2]=mHit->z(time);
94 if (!mIter) mTargetNode->mFlipFlop=0;
97 int StiTrackNodeHelper::propagatePars(
const StiNodePars &parPars
102 alpha = mTargetNode->_alpha - mParentNode->_alpha;
105 if (fabs(alpha) > 1.e-6) {
107 double xt1=parPars.x();
108 double yt1=parPars.y();
109 double cosCA0 = parPars.
_cosCA;
110 double sinCA0 = parPars._sinCA;
115 rotPars.x() = xt1*ca + yt1*sa;
116 rotPars.y() = -xt1*sa + yt1*ca;
117 rotPars.
_cosCA = cosCA0*ca+sinCA0*sa;
118 rotPars._sinCA = -cosCA0*sa+sinCA0*ca;
119 double nor = 0.5*(rotPars._sinCA*rotPars._sinCA+rotPars.
_cosCA*rotPars.
_cosCA +1);
121 rotPars._sinCA /= nor;
122 rotPars.eta()= NICE(parPars.eta()-alpha);
124 ierr = rotPars.check();
129 int kase = (mDetector) ? mDetector->getShape()->getShapeCode():0;
131 case 0: x2 = mHitPars[0];
break;
132 case 1: x2 = mDetector->getPlacement()->getNormalRadius();
break;
136 double rxy = mDetector->getPlacement()->getNormalRadius();
137 if (rotPars.P[0]*rotPars.
_cosCA+rotPars.P[1]*rotPars._sinCA<0)
139 double rxy2P = rotPars.rxy2();
140 int outside = (rxy2P>rxy*rxy);
141 int nSol = StiTrackNode::cylCross(rotPars.P,&rotPars.
_cosCA,rotPars.curv(),rxy,mDir,out);
144 int kaze = outside + 2*mDir;
147 case 1: ou = out[1];
break;
148 case 2: ou = out[1];
break;
156 default: assert(0 &&
"wrong shape code");
160 if (fabs(dx)<1e-5) { proPars = rotPars;
return 0;}
161 rho = 0.5*(mTargetHz*rotPars.ptin()+rotPars.curv());
163 sinCA2=rotPars._sinCA + dsin;
164 if (fabs(sinCA2) > kMaxSin) {
165 sinCA2 = (sinCA2<0) ? -kMaxSin:kMaxSin;
166 dsin = sinCA2-rotPars._sinCA;
167 dx = (fabs(rho)>1e-5)? dsin/rho:0;
170 cosCA2 = ::sqrt((1.-sinCA2)*(1.+sinCA2));
171 sumSin = rotPars._sinCA+sinCA2;
172 sumCos = rotPars.
_cosCA+cosCA2;
173 dy = (fabs(sumCos)>1e-5) ? dx*(sumSin/sumCos):0;
175 dl0 = rotPars.
_cosCA*dx+rotPars._sinCA*dy;
177 if (fabs(dsin) < 0.02 && rotPars.
_cosCA >0) {
178 dl = dl0*(1.+sind*sind/6);
180 double cosd = cosCA2*rotPars.
_cosCA+sinCA2*rotPars._sinCA;
181 dl = atan2(sind,cosd)/rho;
185 proPars.z() = rotPars.z() + dl*rotPars.tanl();
186 proPars.eta() = (rotPars.eta()+rho*dl);
187 proPars.eta() = NICE(proPars.eta());
188 proPars.ptin() = rotPars.ptin();
189 proPars.hz() = mTargetHz;
190 proPars.curv() = proPars.ptin()*mTargetHz;
191 proPars.tanl() = rotPars.tanl();
192 proPars._sinCA = sinCA2;
194 ierr = proPars.check();
199 int StiTrackNodeHelper::propagateFitd()
205 mBestPars.ptin() *= (1+mMcs._ptinCorr);
206 mBestPars.curv() *= (1+mMcs._ptinCorr);
207 mMtx.A[4][4] = (mMtx.A[4][4]+1)*(1+mMcs._ptinCorr) -1;
210 ierr = propagatePars(mFitdParentPars,rotPars,mPredPars);
213 mPredPars.hz() = mTargetHz;
214 mPredPars.ptin() *= (1+mMcs._ptinCorr);
215 mPredPars.curv() *= (1+mMcs._ptinCorr);
217 ierr = mPredPars.check();
225 int StiTrackNodeHelper::propagateMtx()
228 double fYE= dx*(1.+mBestParentRotPars.
_cosCA*cosCA2+mBestParentRotPars._sinCA*sinCA2)/(sumCos*cosCA2);
230 double dLdEta = dy/cosCA2;
231 double fZE = mBestPars.tanl()*dLdEta;
237 double fEC = dx/cosCA2;
239 double fYC=(dl0)/sumCos*fEC;
241 double dang = dl*rho;
242 double C2LDX = dl*dl*(
243 0.5*sinCA2*pow((1+pow(dang/2,2)*sinX(dang/2)),2) +
244 cosCA2*dang*sinX(dang));
246 double fZC = mBestPars.tanl()*C2LDX/cosCA2;
248 fEC*=mTargetHz; fYC*=mTargetHz;fZC*=mTargetHz;
254 mMtx.A[1][0] = -sinCA2/cosCA2;
255 mMtx.A[2][0] = -mBestPars.tanl()/cosCA2 ;
256 mMtx.A[3][0] = -mBestPars.curv()/cosCA2 ; ;
258 mMtx.A[1][3]=fYE; mMtx.A[1][4]=fYC; mMtx.A[2][3]=fZE;
259 mMtx.A[2][4]=fZC; mMtx.A[2][5]=fZT; mMtx.A[3][4]=fEC;
260 double fYX = mMtx.A[1][0];
261 mMtx.A[1][0] = fYX*ca-sa;
262 mMtx.A[1][1] = fYX*sa+ca-1;
266 int StiTrackNodeHelper::propagateError()
268 mPredErrs = mFitdParentErrs;
270 int force = fabs(dl)> StiNodeErrs::kBigLen;
271 mPredErrs.recov(force);
272 mPredErrs._cEE+=mMcs._cEE;
273 mPredErrs._cPP+=mMcs._cPP;
274 mPredErrs._cTP+=mMcs._cTP;
275 mPredErrs._cTT+=mMcs._cTT;
276 int ierr = mPredErrs.check();
282 int StiTrackNodeHelper::makeFit(
int smooth)
292 mBestParentPars = mJoinPars;
293 mBestParentErrs = mJoinErrs;
294 mBestDelta = mJoinErrs.getDelta();
296 double delta = mFitdErrs.getDelta();
297 double er1 = delta*delta;
298 double er2 = mSavdDelta*mSavdDelta;
299 double wt = er1/(er1+er2);
300 mBestParentPars = mFitdPars;
301 mBestParentPars.merge(wt,mSavdParentPars);
302 mBestDelta = sqrt(er1*er2/(er1+er2));
306 mBestParentPars.check(
"1makeFit");
308 mFitdParentPars = mFitdPars;
309 mFitdParentErrs = mFitdErrs;
311 mFitdParentPars.check(
"2makeFit");
312 mFitdParentErrs.check(
"3makeFit");
315 ierr = propagatePars(mBestParentPars,mBestParentRotPars,mBestPars);
318 ierr = propagateMtx();
if(ierr)
return 2;
319 ierr = propagateMCS();
if(ierr)
return 3;
320 ierr = propagateFitd();
if(ierr)
return 4;
321 ierr = propagateError();
if(ierr)
return 5;
324 mState = StiTrackNode::kTNReady;
328 mSavdParentPars = mTargetNode->mFP;
329 mSavdDelta = (mTargetNode->isValid())? mTargetNode->
mFE.getDelta():3e33;
332 if (!smooth) mgCutStep = 0;
333 mPredErrs = mTargetNode->
mFE;
334 ierr = mPredErrs.check();
if (ierr)
return 11;
335 mPredPars = mTargetNode->mFP;
336 ierr = mPredPars.check();
if (ierr)
return 12;
337 mBestPars = mPredPars;
338 mBestDelta = mPredErrs.getDelta();
339 mJoinPars = mPredPars;
340 resetError(mNodeErrFactor);
343 mFitdPars = mPredPars;
344 mFitdErrs = mPredErrs;
351 if (nudge())
return 13;
353 double chi2 = evalChi2();
354 if (mTargetNode == mVertexNode) {
355 if (chi2>mChi2Vtx)
return 14;
357 if (chi2>mChi2Max)
break;
359 mChi2 = chi2;
if (mChi2>999) mChi2=999;
361 if (debug() & 8) { LOG_DEBUG << Form(
"%5d ",ians); StiKalmanTrackNode::PrintStep();}
363 if (mTargetNode == mVertexNode)
return 15;
364 mState = StiTrackNode::kTNReady;
365 mFitdPars = mPredPars;
366 mFitdErrs = mPredErrs;
370 ierr = (!smooth)? save():join();
377 if (mDetector && (!mFlipFlopNode || mTargetNode->mFlipFlop > mFlipFlopNode->mFlipFlop))
378 {mFlipFlopNode=mTargetNode;}
379 if(mState!=StiTrackNode::kTNFitEnd)
break;
381 if (mDetector && (!mWorstNode || mChi2>mWorstNode->getChi2()))
382 {mWorstNode=mTargetNode;}
383 if (!mParentNode)
break;
385 accu = mJoinPars.ptin() - mBestParentPars.ptin()*(1+mMcs._ptinCorr);
386 errr = sqrt(0.5*(fabs(mJoinErrs._cPP)+fabs(mBestParentErrs._cPP)));
387 if (errr > 0) mCurvQa.add(accu/errr);
388 accu = mJoinPars.tanl() - mBestParentPars.tanl();
389 errr = sqrt(0.5*(fabs(mJoinErrs._cTT)+fabs(mBestParentErrs._cTT)));
390 if (errr > 0) mTanlQa.add(accu/errr);
397 int StiTrackNodeHelper::join()
400 enum {kOLdValid=1,kNewFitd=2,kJoiUnFit=4};
407 int kase = mTargetNode->isValid();
408 if (mState==StiTrackNode::kTNFitEnd) kase |=kNewFitd;
412 mChi2 = (mHit)? 3e33:0;
413 mState = StiTrackNode::kTNReady;
416 mJoinPars = mFitdPars;
417 mJoinErrs = mFitdErrs;
428 case kOLdValid|kNewFitd:;
430 mTargetNode->mPE().recov();
432 chi2 = joinTwo(kNPars,mTargetNode->mPP().P,mTargetNode->mPE().G()
433 ,kNPars,mFitdPars.P ,mFitdErrs.G()
434 ,mJoinPars.P ,mJoinErrs.G());
435 mJoinPars.hz() = mTargetHz;
439 if (kase == (kOLdValid|kNewFitd)) {
440 if (mHrr.hYY <= mJoinErrs._cYY) {
441 LOG_DEBUG << Form(
"StiTrackNodeHelper::updateNode() WRONG hYY(%g) < nYY(%g)"
442 ,mHrr.hYY,mFitdErrs._cYY)<< endm;
445 if (mHrr.hZZ <= mJoinErrs._cZZ) {
446 LOG_DEBUG << Form(
"StiTrackNodeHelper::updateNode() WRONG hZZ(%g) < nZZ(%g)"
447 ,mHrr.hZZ,mFitdErrs._cZZ) << endm;
452 ierr = mJoinPars.check();
if (ierr)
return 2;
453 if (kase!=(kOLdValid|kNewFitd)) {kase = -1;
break;}
459 if (chi2>mChi2Max && mTargetNode!=mVertexNode)
460 { kase |=kJoiUnFit;
return 99;}
461 mChi2 = (chi2>999)? 999:chi2;
462 mState = StiTrackNode::kTNFitEnd;
469 if (std::fabs(mJoinPars.hz() - mTargetHz) > 1e-10)
471 LOG_WARN <<
"Expected |mJoinPars.hz() - mTargetHz| <= 1e-10 "
472 <<
"instead |" << mJoinPars.hz() <<
" - " << mTargetHz <<
"| = "
473 << std::fabs(mJoinPars.hz() - mTargetHz) <<
". "
474 <<
"Will set mJoinPars.hz to " << mTargetHz << endm;
475 mJoinPars.hz() = mTargetHz;
478 assert(fabs(mTargetNode->
getHz()-mTargetHz)<=1e-10);
481 mTargetNode->
mFE = mJoinErrs;
482 mTargetNode->mPE() = mJoinErrs;
483 mTargetNode->mFP = mJoinPars;
484 mTargetNode->mPP() = mJoinPars;
485 mTargetNode->mHrr = mHrr;
486 if (mTargetNode!=mVertexNode) mTargetNode->mUnTouch = mUnTouch;
487 mTargetNode->_state = mState;
488 if (mHit && ((mChi2<1000) != (mTargetNode->getChi2()<1000))) mTargetNode->mFlipFlop++;
489 if (mTargetNode!=mVertexNode) mTargetNode->setChi2(mChi2);
492 double myMaxChi2 = (mTargetNode==mVertexNode)? 1000:mChi2Max;
493 if (mState == StiTrackNode::kTNFitEnd) {
494 assert(mChi2 <myMaxChi2);
496 assert(mChi2 <=0 || mChi2 >=myMaxChi2);
502 double StiTrackNodeHelper::joinTwo(
int nP1,
const double *P1,
const double *E1
503 ,
int nP2,
const double *P2,
const double *E2
504 ,
double *PJ,
double *EJ)
508 int nE1 = nP1*(nP1+1)/2;
509 int nE2 = nP2*(nP2+1)/2;
511 double *a = ard.GetArray();
513 double *sumEI = (a+=nE2);
514 double *e1sumEIe1 = (a+=nE2);
515 double *subP = (a+=nE2);
516 double *sumEIsubP = (a+=nE2);
517 double chi2=3e33,p,q;
520 const double *p1 = P1, *p2 = P2, *e1 = E1, *e2 = E2, *t;
521 double choice = (nP1==nP2)? 0:1;
523 for (
int i=0,n=1;i<nE2;i+=(++n)) {
524 p=fabs(e1[i]);q=fabs(e2[i]);choice += (p-q)/(p+q+1e-10);
526 if ( choice >0) {t = p2; p2 = p1; p1 = t; t = e2; e2 = e1; e1 = t;}
530 TCL::vadd(e1,e2,sumE,nE1);
531 int negati = sumE[2]<0;
532 if (negati) TCL::vcopyn(sumE,sumE,nE1);
533 int ign0re = sumE[0]<=0;
534 if (ign0re) sumE[0] = 1;
536 if (ign0re) {sumE[0] = 0; sumEI[0] = 0;}
537 if (negati) {TCL::vcopyn(sumE,sumE,nE1);TCL::vcopyn(sumEI,sumEI,nE1);}
538 TCL::vsub(p2 ,p1 ,subP ,nP1);
542 TCL::vsub(e1,e1sumEIe1,EJ,nE2);
548 TCL::vadd(PJ ,p1 ,PJ ,nP2);
554 double StiTrackNodeHelper::joinVtx(
const double *P1,
const double *E1
555 ,
const double *P2,
const double *E2
556 ,
double *PJ,
double *EJ)
558 enum {nP1=3,nE1=6,nP2=kNPars,nE2=kNErrs};
559 double E1m[nE1],E2m[nE2];
561 TCL::vzero(E1m ,nE1);
562 TCL::ucopy(E2,E2m ,nE2);
563 TCL::vadd (E1,E2m,E2m,nE1);
564 return joinTwo(nP1,P1,E1m,nP2,P2,E2m,PJ,EJ);
570 double StiTrackNodeHelper::joinVtx(
const double *P1,
const double *E1
571 ,
const double *P2,
const double *E2
572 ,
double *PJ,
double *EJ)
574 enum {nP1=3,nE1=6,nP2=kNPars,nE2=kNErrs};
577 double *p = ard.GetArray();
579 double *sumEI = (p+=nE2);
580 double *sumEI_E1_sumEI = (p+=nE2);
581 double *E2_sumEI_E2 = (p+=nE2);
582 double *E2_sumEI_E1_sumEI_E2 = (p+=nE2);
583 double *sumEIsubP = (p+=nE2);
584 double *subP = (p+=nE2);
591 TCL::ucopy(E2,sumE,nE1);
592 int ign0re = sumE[0]<=0;
593 if (ign0re) sumE[0] = 1;
595 if (ign0re) {sumE[0] = 0; sumEI[0] = 0;}
596 TCL::vsub(P1 ,P2 ,subP ,nP1);
600 TCL::vsub(E2,E2_sumEI_E2,EJ,nE2);
603 TCL::trqsq (E2,sumEI_E1_sumEI,E2_sumEI_E1_sumEI_E2,nP2);
604 TCL::vadd(EJ,E2_sumEI_E1_sumEI_E2,EJ,nE2);
611 TCL::vadd(PJ ,P2 ,PJ ,nP2);
617 double StiTrackNodeHelper::joinVtx(
const double *Y,
const StiHitErrs &B
626 enum {nP1=3,nE1=6,nP2=6,nE2=21};
635 double Ai11i[6],Ai10[3][3],T10[3][3],dif[6],m[6];
641 TCL::vsub (X.P,Y,dif,3);
642 TCL::mxmpy(T10[0],dif,m+3,3,3,1);
643 TCL::vadd(X.P+3,m+3,m+3,3);
644 if (M) {TCL::ucopy(m,M->P,nP2); M->ready();}
646 TCL::vsub(X.P,m,dif,nP2);
653 double TX[nP1][nP2];memset(TX[0],0,
sizeof(TX));
654 for (
int i=0;i<3;i++) {TCL::ucopy(T10[i],TX[i],3); TX[i][i+3]=1;}
659 double TY[nP2][nP1];memset(TY[0],0,
sizeof(TX));
660 for (
int i=0;i<3;i++) {TCL::vcopyn(T10[i],TY[i+3],3); TY[i][i]=1;}
664 TCL::vadd(CYY,C->G(),C->G(),nE2);
668 int StiTrackNodeHelper::save()
670 assert(fabs(mPredPars.hz()-mTargetHz)<=1e-10);
671 assert(fabs(mFitdPars.hz()-mTargetHz)<=1e-10);
672 assert(fabs(mTargetNode->
getHz()-mTargetHz)<=1e-10);
674 mTargetNode->mPP() = mPredPars;
675 mTargetNode->mFP = mFitdPars;
676 mTargetNode->mPE() = mPredErrs;
677 mTargetNode->
mFE = mFitdErrs;
678 mTargetNode->_state = mState;
679 if (mHit && ((mChi2<1000) != (mTargetNode->getChi2()<1000))) mTargetNode->mFlipFlop++;
680 if (mTargetNode!=mVertexNode) mTargetNode->setChi2(mChi2);
693 int StiTrackNodeHelper::propagateMCS()
696 if (!mDetector)
return 0;
698 if (fabs(mBestPars.ptin())<=1e-3)
return 0;
699 double pt = 1./(fabs(mBestPars.ptin())+1e-6);
701 double relRadThickness;
703 double pL1=0,pL2=0,pL3=0,d1=0,d2=0,d3=0,dxEloss=0,dx=0;
704 pL1=0.5*pathIn(mParentNode->getDetector(),&mBestParentPars);
706 pL3=0.5*pathIn(mDetector,&mBestPars);
708 double t = mBestPars.tanl();
709 pL2= fabs(dl*sqrt(1+t*t));
710 double x0p = 1e11,x0Gas=1e11,x0=1e11;
711 dx = mBestPars.x() - mBestParentRotPars.x();
712 double tanl = mBestPars.tanl();
713 double pti = mBestPars.ptin();
714 double p2 = (1.+tanl*tanl)*pt*pt;
715 double m = StiKalmanTrackFinderParameters::instance()->getMassHypothesis();
718 double beta2 = p2/e2;
720 const StiMaterial *curMat = mDetector->getMaterial();
722 d3 =(curLos) ? curLos->
calculate(1.,m, beta2):0;
723 x0 = curMat->
getX0();
727 const StiDetector *preDet = mParentNode->getDetector();
731 preMat = preDet->getMaterial();
732 preGas = preDet->getGas();
735 x0p = preMat->
getX0();
740 const StiMaterial *gasMat = (dx>0)?curGas : preGas;
742 x0Gas = gasMat->
getX0();
749 pL2=pL2-pL1-pL3;
if (pL2<0) pL2=0;
750 relRadThickness = pL1/x0p+pL2/x0Gas+pL3/x0;
752 dxEloss = d1*pL1+ d2*pL2 + d3*pL3;
754 double theta2 = StiKalmanTrackNode::mcs2(relRadThickness,beta2,p2);
755 double cos2Li = (1.+ tanl*tanl);
756 double f = mHitsErrFactor;
757 mMcs._cEE = cos2Li *theta2*f;
758 mMcs._cPP = tanl*tanl*pti*pti *theta2*f;
759 mMcs._cTP = pti*tanl*cos2Li *theta2*f;
760 mMcs._cTT = cos2Li*cos2Li *theta2*f;
761 assert(mMcs._cPP>=0);
762 assert(mMcs._cTT>=0);
763 assert(mMcs._cEE>=0);
766 int sign = ( dx>=0)? 1:-1;
767 double dE = sign*dxEloss;
769 StiELoss *el = mTargetNode->getELoss();
770 el[0].mELoss = 2*d3*pL3;
774 el[1].mELoss = 2*d2*pL2;
779 mMcs._ptinCorr = ::sqrt(e2)*dE/p2;
780 if (fabs(mMcs._ptinCorr)>0.1) mMcs._ptinCorr = (dE<0)? -0.1:0.1;
801 double StiTrackNodeHelper::evalChi2()
803 double r00, r01,r11,chi2;
806 if (fabs(mPredPars._sinCA)>0.99 )
return 1e41;
807 if (fabs(mPredPars.eta()) >kMaxEta)
return 1e41;
808 if (fabs(mPredPars.curv()) >kMaxCur)
return 1e41;
810 mHitPars[0] = mPredPars.x();
811 chi2 = joinVtx(mHitPars,mHrr,mPredPars,mPredErrs);
814 r00=mPredErrs._cYY+mHrr.hYY;
815 r01=mPredErrs._cZY+mHrr.hZY;
816 r11=mPredErrs._cZZ+mHrr.hZZ;
817 mDetm = r00*r11 - r01*r01;
818 if (mDetm<r00*r11*1.e-5) {
819 LOG_DEBUG << Form(
"StiTrackNodeHelper::evalChi2 *** zero determinant %g",mDetm)<< endm;
822 double tmp=r00; r00=r11; r11=tmp; r01=-r01;
824 double dyt=(mPredPars.y()-mHitPars[1]);
825 double dzt=(mPredPars.z()-mHitPars[2]);
826 chi2 = (dyt*r00*dyt + 2*r01*dyt*dzt + dzt*r11*dzt)/mDetm;
854 double StiTrackNodeHelper::recvChi2()
856 if (fabs(mJoinPars._sinCA)>0.99 )
return 1e41;
857 if (fabs(mJoinPars.eta()) >kMaxEta)
return 1e41;
858 if (fabs(mJoinPars.curv()) >kMaxCur)
return 1e41;
860 double chi2 =joinVtx(mHitPars,mHrr ,mPredPars ,mPredErrs );
867 double f = -(1./mHitsErrFactor);
870 if ((r11=myHrr.hYY+mJoinErrs._cYY) >=0)
return 1e41;
871 if ((r22=myHrr.hZZ+mJoinErrs._cZZ) >=0)
return 1e41;
872 r12 =myHrr.hZY+mJoinErrs._cZY;
873 if (r11*r22-r12*r12<0)
return 1e41;
876 double chi2 = joinTwo(3,mHitPars , myHrr.G()
877 ,3,mJoinPars.P,mJoinErrs.G()
878 ,recovPars.P,recovErrs.G());
880 mUnTouch.set(recovPars,recovErrs);
884 int StiTrackNodeHelper::setHitErrs()
886 getHitErrors(mHit,&mFitdPars,&mHrr);
887 mHrr*=mHitsErrFactor;
911 int StiTrackNodeHelper::updateNode()
913 mState = StiTrackNode::kTNFitBeg;
916 mHitPars[0] = mPredPars.x();
917 double chi2 = joinVtx(mHitPars,mHrr,mPredPars,mPredErrs,&mFitdPars,&mFitdErrs);
918 mFitdPars.curv() = mTargetHz*mFitdPars.ptin();
919 assert(chi2>900 || fabs(mChi2-chi2)<1e-10);
921 StiKalmanTrackNode::ResetComment(Form(
"Vertex "));
924 r00=mHrr.hYY+mPredErrs._cYY;
925 r01=mHrr.hZY+mPredErrs._cZY;
926 r11=mHrr.hZZ+mPredErrs._cZZ;
927 mDetm=r00*r11 - r01*r01;
928 if (!(mDetm>(r00*r11)*1.e-5))
return 99;
929 assert(mDetm>(r00*r11)*1.e-5);
932 double tmp=r00; r00=r11/mDetm; r11=tmp/mDetm; r01=-r01/mDetm;
934 double k00=mPredErrs._cYY*r00+mPredErrs._cZY*r01, k01=mPredErrs._cYY*r01+mPredErrs._cZY*r11;
935 double k10=mPredErrs._cZY*r00+mPredErrs._cZZ*r01, k11=mPredErrs._cZY*r01+mPredErrs._cZZ*r11;
936 double k20=mPredErrs._cEY*r00+mPredErrs._cEZ*r01, k21=mPredErrs._cEY*r01+mPredErrs._cEZ*r11;
937 double k30=mPredErrs._cPY*r00+mPredErrs._cPZ*r01, k31=mPredErrs._cPY*r01+mPredErrs._cPZ*r11;
938 double k40=mPredErrs._cTY*r00+mPredErrs._cTZ*r01, k41=mPredErrs._cTY*r01+mPredErrs._cTZ*r11;
940 double myY = mPredPars.y();
941 double myZ = mPredPars.z();
942 double dyt = mHitPars[1] - myY;
943 double dzt = mHitPars[2] - myZ;
944 double dPt = k30*dyt + k31*dzt;
945 double dEt = k20*dyt + k21*dzt;
946 double dTa = k40*dyt + k41*dzt;
947 double eta = NICE(mPredPars.eta() + dEt);
948 double pti = mPredPars.ptin() + dPt;
949 double tanl = mPredPars.tanl() + dTa;
955 double p0 = myY + k00*dyt + k01*dzt;
956 double p1 = myZ + k10*dyt + k11*dzt;
958 double sinCA = sin(eta);
962 mFitdPars.hz() = mTargetHz;
963 mFitdPars.x() = mPredPars.x();
966 mFitdPars.eta() = eta;
967 mFitdPars.ptin() = pti;
968 mFitdPars.curv() = mTargetHz*pti;
969 mFitdPars.tanl() = tanl;
970 mFitdPars._sinCA = sinCA;
971 mFitdPars.
_cosCA = ::sqrt((1.-mFitdPars._sinCA)*(1.+mFitdPars._sinCA));
973 assert(fabs(mFitdPars.y()-mHitPars[1])>1e-10 || fabs(mHitPars[0])<4);
974 assert(mFitdPars.x()>0);
975 if (mFitdPars.check())
return -11;
977 double c00=mPredErrs._cYY;
978 double c10=mPredErrs._cZY, c11=mPredErrs._cZZ;
979 double c20=mPredErrs._cEY, c21=mPredErrs._cEZ;
980 double c30=mPredErrs._cPY, c31=mPredErrs._cPZ;
981 double c40=mPredErrs._cTY, c41=mPredErrs._cTZ;
982 mFitdErrs._cYY-=k00*c00+k01*c10;
983 mFitdErrs._cZY-=k10*c00+k11*c10;mFitdErrs._cZZ-=k10*c10+k11*c11;
984 mFitdErrs._cEY-=k20*c00+k21*c10;mFitdErrs._cEZ-=k20*c10+k21*c11;mFitdErrs._cEE-=k20*c20+k21*c21;
985 mFitdErrs._cPY-=k30*c00+k31*c10;mFitdErrs._cPZ-=k30*c10+k31*c11;mFitdErrs._cPE-=k30*c20+k31*c21;mFitdErrs._cPP-=k30*c30+k31*c31;
986 mFitdErrs._cTY-=k40*c00+k41*c10;mFitdErrs._cTZ-=k40*c10+k41*c11;mFitdErrs._cTE-=k40*c20+k41*c21;mFitdErrs._cTP-=k40*c30+k41*c31;mFitdErrs._cTT-=k40*c40+k41*c41;
991 if (mFitdErrs.check())
return -12;
995 static int ERRTEST=0;
996 if(ERRTEST) errTest(mPredPars,mPredErrs,mHit,mHrr,mFitdPars,mFitdErrs,mChi2);
1001 if (mHrr.hYY <= mFitdErrs._cYY) {
1002 LOG_DEBUG << Form(
"StiTrackNodeHelper::updateNode() WRONG hYY(%g) < nYY(%g)"
1003 ,mHrr.hYY,mFitdErrs._cYY)<< endm;
1006 if (mHrr.hZZ <= mFitdErrs._cZZ) {
1007 LOG_DEBUG << Form(
"StiTrackNodeHelper::updateNode() WRONG hZZ(%g) < nZZ(%g)"
1008 ,mHrr.hZZ,mFitdErrs._cZZ)<< endm;
1012 if (debug()) StiKalmanTrackNode::comment += Form(
" chi2 = %6.2f",mChi2);
1013 if (mTargetNode && debug()) {
1014 mTargetNode->PrintpT(
"U");
1016 mState = StiTrackNode::kTNFitEnd;
1021 void StiTrackNodeHelper::resetError(
double fk)
1024 if(mPredErrs._cYY>DY*DY)
break;
1025 if(mPredErrs._cZZ>DZ*DZ)
break;
1026 if(mPredErrs._cEE>DEta*DEta)
break;
1027 if(mPredErrs._cPP>DPti*DPti)
break;
1028 if(mPredErrs._cTT>DTan*DTan)
break;
1034 mPredErrs._cYY=DY*DY;
1035 mPredErrs._cZZ=DZ*DZ;
1036 mPredErrs._cEE=DEta*DEta;
1037 mPredErrs._cPP=DPti*DPti;
1038 mPredErrs._cTT=DTan*DTan;
1043 double fact=1,dif,fak;
1044 double cuts[kNPars];
1045 memcpy(cuts,MAXSTEP,
sizeof(cuts));
1046 if (mBestDelta<DY) {cuts[1]=mBestDelta;cuts[2]=mBestDelta;}
1048 for (
int jx=0;jx<kNPars;jx++) {
1049 dif =(fabs((*pars)[jx]-(*base)[jx]));
1050 fak = (dif >cuts[jx]) ? cuts[jx]/dif:1;
1051 if (fak < fact) fact = fak;
1053 if (fact>=1)
return 0;
1055 for (
int jx=0;jx<kNPars;jx++) {
1056 dif =(*pars)[jx]-(*base)[jx];
1057 (*pars)[jx] = (*base)[jx] +dif*fact;
1063 int StiTrackNodeHelper::nudge()
1067 for (
int i=0;i<2;i++,pars =&mPredPars) {
1068 double deltaX = mHitPars[0]-pars->x();
1069 if (fabs(deltaX) <1e-6)
continue;
1070 double deltaL = deltaX/pars->_cosCA;
1071 double deltaE = pars->curv()*deltaL;
1072 pars->x() = mHitPars[0];
1073 pars->y() += pars->_sinCA *deltaL;
1074 pars->z() += pars->tanl() *deltaL;
1075 pars->eta() += deltaE;
1076 double cosCA = pars->_cosCA;
1077 pars->_cosCA -= pars->_sinCA *deltaE;
1078 pars->_sinCA += cosCA *deltaE;
1079 if (fabs(pars->_cosCA)>=0.99
1080 ||fabs(pars->_sinCA)>=0.99) pars->ready();
1081 if (pars->check())
return 1;
1088 if (!det)
return 0.;
1089 double thickness = det->getShape()->getThickness();
1090 double t = pars->tanl();
1091 double c = fabs(pars->
_cosCA);
1092 if (det->getShape()->getShapeCode()!=kPlanar) {
1093 double CA = pars->eta()-atan2(pars->y(),pars->x());
1096 if (fabs(c)<kMinCos)
return 0.;
1098 return (thickness*::sqrt(1.+t*t)) / fabs(c);
1109 const float *ermx = hit->errMtx();
1110 for (
int i=0;i<6;i++){hrr->G()[i]=ermx[i];}
1122 hittP.x() = hit->
x();
1123 hittP.y() = hit->y();
1124 hittP.z() = hit->z();
1127 double myChi2 = StiTrackNodeHelper::joinTwo(
1128 3,hittP.P,hittE.G(),
1129 6,predP.P,predE.G(),
1134 for (
int i=0;i<kNPars;i++) {
1135 double diff = fabs(mineP.P[i]-fitdP.P[i]);
1136 if (diff < 1e-10)
continue;
1137 diff/=0.5*(fabs(mineP.P[i])+fabs(fitdP.P[i]));
1138 if (diff < 1e-5 )
continue;
1140 LOG_DEBUG << Form(
"errTest(P): %g(%d) - %g(%d) = %g",mineE.G()[i],i,fitdE.G()[i],i,diff)<< endm;
1142 if (ndif){ mineP.print();fitdP.print();}
1144 for (
int i=0;i<kNErrs;i++) {
1145 double diff = fabs(mineE.G()[i]-fitdE.G()[i]);
1146 if (diff < 1e-10)
continue;
1147 diff/=0.5*(fabs(mineE.G()[i])+fabs(fitdE.G()[i]));
1148 if (diff < 1e-5 )
continue;
1150 LOG_DEBUG << Form(
"errTest(E): %g(%d) - %g(%d) = %g",mineE.G()[i],i,fitdE.G()[i],i,diff)<< endm;
1152 if (ndif>=100){ mineE.print();fitdE.print();}
1154 double diff = fabs((chi2-myChi2)/(chi2+myChi2));
1157 LOG_DEBUG << Form(
"errTest(C): %g() - %g() = %g",myChi2,chi2,diff)<< endm;
1164 void QaFit::add(
double val)
1166 double v = val;
double p = mPrev; mPrev = v;
1167 int n = (mTally)? 2:1;
1169 for (
int i=0;i<n;i++) {
1172 if (mMaxi[i]<fabs(v)) mMaxi[i]=fabs(v);
1173 if (v<0) mNega[i]++;
1178 void QaFit::finish()
1184 for (
int i=0;i<2;i++) {
1187 if (mErrr[i]<1e-10) mErrr[i]=1e-10;
1188 mErrr[i] = sqrt(mErrr[i]);
1193 double QaFit::getAccu(
int k)
1196 if (mTally-k<=1)
return 0;
1200 double QaFit::getNStd(
int k)
1204 if (n <= 0)
return 0;
1205 return mAver[k]*sqrt(
double(n));
1208 double QaFit::getNSgn(
int k)
1212 if (n <= 0)
return 0;
1213 return (n-2*mNega[k])/sqrt(
double(n));
1216 void QaFit::getInfo(
double *info)
1218 for (
int i=0;i<2;i++) {
1220 info[l+0]=getAccu(i);
1221 info[l+1]=getNStd(i);
1222 info[l+2]=getNSgn(i);
1223 info[l+3]=getMaxi(i);
const Float_t & x() const
Return the local x, y, z values.
const StiDetector * detector() const
static void errPropag6(double G[21], const double F[6][6], int nF)
virtual void calculateError(Double_t _z, Double_t _eta, Double_t _tanl, Double_t &ecross, Double_t &edip, Double_t fudgeFactor=1) const
coeff[6] = 0:intrinsicY 1: driftY 2: crossY 3:intrinsicZ 4: driftZ 5: crossZ
StiElossCalculator * getElossCalculator() const
Get Eloss calculator.
static float * trsa(const float *s, const float *a, float *b, int m, int n)
static float * trqsq(const float *q, const float *s, float *r, int m)
double calculate(double charge2, double m, double beta2) const
static float * trsinv(const float *g, float *gi, int n)
static float * trasat(const float *a, const float *s, float *r, int m, int n)
double _cosCA
sine and cosine of cross angle
static float * tras(const float *a, const float *s, float *b, int m, int n)
double getX0() const
Get the radiation length in centimeter.
StiNodeErrs mFE
covariance matrix of the track parameters
double getDensity() const
Get the material density in grams/cubic centimeter.