636 #include "StThreeVector.hh"
637 #include "StThreeVectorF.hh"
638 #include "StThreeVectorD.hh"
639 #include "StPhysicalHelixD.hh"
640 #include "THelixTrack.h"
646 #include "StiKalmanTrackFinder.h"
648 #include "StiDetectorContainer.h"
650 #include "StiKalmanTrackNode.h"
652 #include "StiDetector.h"
653 #include "StiDetectorGroups.h"
654 #include "StiDetectorBuilder.h"
655 #include "StiPlacement.h"
656 #include "StiMaterial.h"
657 #include "StDetectorDbMaker/StiHitErrorCalculator.h"
658 #include "StPhysicalHelixD.hh"
659 #include "StHelix.hh"
660 #include "StDetectorDbMaker/StiKalmanTrackFitterParameters.h"
661 #include "StDetectorDbMaker/StiKalmanTrackFinderParameters.h"
662 #include "StiHitContainer.h"
664 #include "TCernLib.h"
665 #include "StMessMgr.h"
666 ostream& operator<<(ostream&,
const StiHit&);
670 int StiKalmanTrack::_debug = 0;
689 static int mIdCount = 0;
690 if ((++mIdCount) >= 1<<16) mIdCount = 1;
701 StiDebug::Break(mIdDb);
711 trackNodeFactory = val;
753 UInt_t nhits = hits.size();
754 setSeedHitCount(nhits);
756 for (UInt_t ihit=0;ihit<nhits;ihit++)
766 int ierr = approx(kAppRR|kAppUPD);
776 UInt_t nhits = hits.size();
777 setSeedHitCount(nhits);
779 for (UInt_t ihit = 0; ihit < nhits; ihit++) {
787 if (!firstPars) {approx();
return 0;}
788 else {firstNode->fitPars() = *firstPars;}
790 if (firstErrs) {firstNode->fitErrs() = *firstErrs;}
791 if (lastPars) {lastNode ->fitPars() = *lastPars ;}
792 if (lastErrs) {lastNode->fitErrs() = *lastErrs ;}
823 double trackChi2 = 0;
824 double maxChi2 = StiKalmanTrackFitterParameters::instance()->getMaxChi2();
825 if (!firstNode)
return 1.e+60;
829 if (!node->isValid())
continue;
830 if (!node->getHit() )
continue;
831 if (!node->getDetector())
continue;
832 double nodeChi2 = node->getChi2();
833 if (nodeChi2>maxChi2)
continue;
834 trackChi2 += nodeChi2;
837 return (fitHits>3)?trackChi2/(2.*fitHits-5.):1e30;
843 double trackChi2 = 0;
844 double maxChi2 = StiKalmanTrackFitterParameters::instance()->getMaxChi2();
845 if (!firstNode)
return 1e11;
846 for (
auto it=
begin();it!=
end();++it) {
848 if (!node->isValid())
continue;
849 if (!node->getHit() )
continue;
850 if (!node->getDetector())
continue;
851 double nodeChi2 = node->getChi2();
852 if (nodeChi2>maxChi2)
continue;
853 if (trackChi2<nodeChi2) trackChi2=nodeChi2;
875 if (!node->isValid())
continue;
876 if (!node->getHit())
continue;
877 detector = node->getDetector();
878 if (!detector)
continue;
879 if (node->getChi2()>=1000)
continue;
880 if (detectorId && detector->getGroupId() != detectorId)
continue;
905 if (!node->isValid())
continue;
907 if (!detector)
continue;
908 StiHit* h = node->getHit();
909 if (!h && !detector->isActive(node->getY(),node->getZ()))
continue;
910 if (detectorId && detector->getGroupId() != detectorId)
continue;
936 const StiDetector * detector = (*it).getDetector();
937 if (detector && detector->isActive())
972 int fitPointCount = 0;
976 if(!node->isValid())
continue;
977 StiHit* hit = node->getHit();
979 if (!node->isFitted())
continue;
982 if (detectorId && detectorId!=det->getGroupId())
continue;
985 return fitPointCount;
996 enum {kPP=0,kMP=1,kFP=2};
1001 memset(count[0],0,(maxDetId+1)*3*
sizeof(
int));
1006 if (!node->isValid())
continue;
1007 const StiDetector *detector = node->getDetector();
1008 if (!detector)
continue;
1009 int detId = detector->getGroupId();
1010 StiHit* h = node->getHit();
1011 if (detectorOld && detId == kTpcId) {
1012 Double_t R = detector->getPlacement()->getNormalRadius();
1013 Double_t angle = detector->getPlacement()->getNormalRefAngle();
1014 Double_t R_OLD = detectorOld->getPlacement()->getNormalRadius();
1017 if ( detectorContainer->
moveIn(TMath::DegToRad()*5,100,R)) {
1018 StiDetector* d = detectorContainer->getCurrentDetector();
1019 if (d == detector)
break;
1021 R_OLD = detectorOld->getPlacement()->getNormalRadius();
1022 Double_t angle_OLD = detectorOld->getPlacement()->getNormalRefAngle();
1023 if (detectorOld->isActive() && R < R_OLD && TMath::Abs(angle - angle_OLD) < TMath::DegToRad()*5) {
1024 count[0][kPP]++; count[detId][kPP]++;
1031 if (h || detector->isActive(node->getY(),node->getZ())) {
1032 count[0][kPP]++; count[detId][kPP]++;
1034 detectorOld = detector;
1038 count[0][kMP]++; count[detId][kMP]++;
1039 if (!node->isFitted())
continue;
1040 count[0][kFP]++; count[detId][kFP]++;
1057 for (
int i = 0; i < 4; i++){ x[0][i] = 0; }
1062 for (;(node=it());it++){
1063 if (!node->isValid())
continue;
1064 if (!node->getHit())
continue;
1065 if ( node->getChi2()>10000.)
continue;
1066 x[1][0]=node->x_g();
1067 x[1][1]=node->y_g();
1068 x[1][2]=node->z_g();
1071 double dlen = sqrt(pow(x[1][0]-x[0][0],2) + pow(x[1][1]-x[0][1],2));
1072 double curv = fabs(0.5*(x[0][3]+x[1][3]));
1073 double dsin = (0.5*dlen*curv);
1076 Form(
"StiKalmanTrack::getTrackLength ***ERROR*** dsin %g >.9",dsin)
1080 dlen = (dsin<0.1)? dlen*(1.+dsin*dsin/6) : 2*asin(dsin)/curv;
1081 len +=sqrt(dlen*dlen + pow(x[1][2]-x[0][2],2));
1083 memcpy(x[0],x[1],4*
sizeof(
double)); iready=2005;
1105 x1=thisNode->pathlength()/2.;
1110 while ((tNode++)!=
end() && (*tNode).getDetector())
1117 x3=nextNode->pathlength()/2.;
1119 if(x3==-1.)
continue;
1124 if (x2> (x1+x3)) x2 = x2 - x1 - x3;
1128 <<
"getTrackRadLength:"
1129 <<
"\n\tIn Detector: "<<thisNode->getDetector()->
getName()
1130 <<
"\n\t\tMaterial: "<<thisNode->getDetector()->getMaterial()
1131 <<
"\n\t\tLength: "<<x1
1132 <<
"\t\tGap Length: "<<x2
1133 <<
"\n\tNext Detector: "<<nextNode->getDetector()->
getName()
1134 <<
"\n\t\tMaterial: "<<nextNode->getDetector()->getMaterial()
1135 <<
"\n\t\tLength: "<<x3
1138 if (thisNode->
getX0()>0) totalR += x1/thisNode->
getX0();
1140 if (nextNode->
getX0()>0) totalR += x3/nextNode->
getX0();
1143 thisNode = nextNode;
1147 cout <<
"StiKalmanTrack::getTrackRadLength() -W- Total Rad Length Error: "<<totalR;
1157 inNode->getDipAngle(),
1160 inNode->getHelicity());
1161 double per = hlx.
period();
1165 if (fabs(len) > fabs(len+per)) len+=per;
1166 if (fabs(len) > fabs(len-per)) len-=per;
1169 if (pnt) (*pnt) = hlx.at(0);
1172 double phase = hlx.
phase();
1173 double dip = hlx.dipAngle();
1176 (*dir)[0]= -sin(phase)*cos(dip)*h;
1177 (*dir)[1]= cos(phase)*cos(dip)*h;
1178 (*dir)[2]= sin(dip)*h;}
1197 assert(firstNode && lastNode);
1201 for (;(node=it());it++){
1202 if (!node->isValid())
continue;
1203 StiHit *hit = node->getHit();
1204 if (qua&kKeepHit) {
if (!hit)
continue;}
1205 if (qua&kGoodHit) {
if (!hit || node->getChi2()>10000.)
continue;}
1208 cout <<
"StiKalmanTrack::getInnOutMostNode() -E- No requested nodes " << endl;
1236 assert(firstNode && lastNode);
1238 for (
auto it=
begin();(node=it());++it)
1240 if (!node->isValid())
continue;
1241 if (node->getChi2()>10000.)
continue;
1242 StiHit* hit = node->getHit();
1246 if (detId!=det->getGroupId())
continue;
1252 int StiKalmanTrack::getNNodes(
int qua)
const
1257 for (;(node=it());it++){
1258 if (!node->isValid())
continue;
1259 StiHit *hit = node->getHit();
1260 if (qua&kKeepHit) {
if (!hit)
continue;}
1261 if (qua&kGoodHit) {
if (!hit || node->getChi2()>10000.)
continue;}
1272 vector<StiKalmanTrackNode*> nodeVec;
1275 const StiHit* hit = node->getHit();
1279 if (node->getDedx()<=0.)
continue;
1280 if (detectorId!=det->getGroupId())
continue;
1281 nodeVec.push_back(node);
1291 vector<const StMeasuredPoint*> hits;
1294 if (!node->isValid())
continue;
1295 if (node->getChi2()>10000.)
continue;
1296 const StiHit* hit = node->getHit();
1300 if (!stHit)
continue;
1301 hits.push_back(stHit);
1354 static int nCall=0; nCall++;
1356 int dcaHit = vertex->
isDca();
1359 bool trackExtended =
false;
1362 if (!innerMostHitNode)
return 0;
1364 StiHit localVertex = *vertex;
1366 if (sNode->isDca()) {
1372 localVertex.
rotate(sNode->getAlpha());
1379 if (tNode->
propagate(sNode, &localVertex,kOutsideIn))
1382 double dy=0,dz=0,d=0;
1386 tNode->setDetector(0);
1389 tNode->setChi2(3e33);
1391 dy=tNode->getY()- localVertex.y();
1392 dz=tNode->getZ()- localVertex.z();
1393 d = ::sqrt(dy*dy+dz*dz);
1394 _vChi2= chi2; _dca = d;
1400 if (chi2<StiKalmanTrackFinderParameters::instance()->maxChi2Vertex())
1402 myHit = StiToolkit::instance()->getHitFactory()->
getInstance();
1403 *myHit = localVertex;
1404 tNode->setHit(myHit);
1405 tNode->setChi2(chi2);
1406 tNode->setDetector(0);
1409 if (trackExtended)
return tNode;
1410 trackNodeFactory->
free(tNode);
1414 Form(
"Primary(%d) not accepted BUT d = %g chi2 = %g",nCall,d,chi2)
1427 vector<StiHit*> hits;
1434 if (!node.isValid())
continue;
1435 if (node.getChi2()>10000.)
continue;
1436 StiHit* hit = node.getHit();
1438 hits.push_back(hit);
1453 physicalHelix.setParameters(fabs(node->
getCurvature()),
1454 node->getDipAngle(),
1457 node->getHelicity());
1458 double dca = physicalHelix.distance(vxDD);
1467 os <<
"List of nodes" << endl;
1472 while (tNode != eNode) {
1474 if (thisNode) os << *thisNode;
1478 catch (runtime_error & rte)
1480 os <<
" Run-time Error while accessing track parameters: " << rte.what() << endl;
1482 catch (logic_error & le)
1484 os <<
" Logic Error while accessing track parameters: " << le.what() << endl;
1498 if (!innerMostNode)
return 0;
1501 trackNodeFactory->
free(n);
1510 if (!outerMostNode)
return 0;
1513 trackNodeFactory->
free(n);
1523 lastNode = firstNode = Node;
return;
1526 if (!near) near = lastNode;
1527 near->add(Node,direction);
1530 if (!near) near = firstNode;
1531 near->add(Node,direction);
1542 void StiKalmanTrack::removeLastNode()
1557 int errType = kNoErrors;
1559 enum {kMaxIter=30,kPctLoss=10,kHitLoss=3};
1560 static double defConfidence = StiDebug::dFlag(
"StiConfidence",0.01);
1561 int nNBeg = getNNodes(3), nNEnd = nNBeg;
1562 if (nNBeg<=3)
return 1;
1565 int fail=0,status=0;
1571 double errConfidence = defConfidence;
1573 for (iter=0;iter<kMaxIter;iter++) {
1575 errType = kNoErrors;
1576 sTNH.set(StiKalmanTrackFitterParameters::instance()->getMaxChi2()*10,StiKalmanTrackFitterParameters::instance()->getMaxChi2Vtx()*100,errConfidence,iter);
1577 pPrev = inn->fitPars();
1578 ePrev = inn->fitErrs();
1581 if (status) {fail= 1; errType = kRefitFail;
break;}
1582 nNEnd = sTNH.getUsed();
1583 if ((nNEnd <=3)) {fail= 2; errType = kNotEnoughUsed;
break;}
1584 if (!inn->isValid() || inn->getChi2()>1000) {
1586 qA = StiKalmanTrack::diff(pPrev,ePrev,inn->fitPars(),inn->fitErrs(),igor);
1587 static int oldRefit = StiDebug::iFlag(
"StiOldRefit");
1589 if (qA>0.5) {fail=-2; errType = kBadQA;
continue;}
1591 if (qA <1 && errConfidence>0.1) errConfidence = 0.1;
1592 if (qA>0.01) {fail=-2; errType = kBadQA;
continue;}
1593 if (sTNH.isCutStep()) {fail=-2; errType = kBadQA;
continue;}
1596 sTNH.mCurvQa.getInfo(info[0]);
1597 sTNH.mTanlQa.getInfo(info[1]);
1603 if (worstNode && worstNode->getChi2()>StiKalmanTrackFitterParameters::instance()->getMaxChi2())
1605 worstNode->setHit(0); worstNode->setChi2(3e33);
continue;}
1606 if (rejectByHitSet()) { releaseHits() ;
continue;}
1611 if (flipFlopNode && flipFlopNode->getFlipFlop()>kMaxIter/3)
1613 flipFlopNode->setHit(0); flipFlopNode->setChi2(3e33);
continue;}
1622 while (!fail && vertexNode) {
1624 errType = kVertexNodeInvalid;
1625 if (!vertexNode->isValid())
break;
1627 errType = kNodeNotValid;
1628 if ( vertexNode->getChi2()>StiKalmanTrackFitterParameters::instance()->getMaxChi2Vtx())
break;
1630 errType = kTooManyDroppedNodes;
1631 if (nNBeg*kPctLoss/100 < nNBeg-nNEnd
1632 && nNEnd+kHitLoss < nNBeg)
break;
1634 errType = kNoErrors;
1640 for (;(node=it());it++){
1641 if (node == vertexNode)
continue;
1642 StiHit *hit = node->getHit();
1644 if (node->isValid() && node->getChi2()<10000. )
continue;
1649 if (fail) setFlag(-1);
1653 int StiKalmanTrack::refitL()
1655 static int nCall=0;nCall++;
1656 StiDebug::Break(nCall);
1660 int iNode=0, status = 0;
1661 bool isStarted=
false;
1663 for (source=rbegin();source!=rend();source++) {
1665 targetNode = &(*source);
1668 if (!targetNode->getHit()) targetNode->setInvalid();
1669 if ( targetNode->getChi2()>1000) targetNode->setInvalid();
1670 if (!targetNode->isValid())
continue;
1672 sTNH.set(pNode,targetNode);
1673 status = sTNH.makeFit(0);
1674 if (status) {targetNode->setInvalid();
continue;}
1675 if (!targetNode->isValid())
continue;
1680 pNode = 0; iNode=0;isStarted=
false;
1682 for (source=
begin();source!=
end();source++) {
1684 targetNode = &(*source);
1686 if (!targetNode->getHit()) targetNode->setInvalid();
1687 if ( targetNode->getChi2()>1000) targetNode->setInvalid();
1688 if (!targetNode->isValid())
continue;
1690 sTNH.set(pNode,targetNode);
1691 status = sTNH.makeFit(1);
1692 if (status) {targetNode->setInvalid();
continue;}
1693 if (!targetNode->isValid())
continue;
1700 void StiKalmanTrack::reduce()
1703 for (source=
begin();source!=
end();source++) {(*source).reduce();}
1706 void StiKalmanTrack::unset()
1708 if (!lastNode)
return;
1711 lastNode=0; firstNode=0;
1714 void StiKalmanTrack::print(
const char *opt)
const
1716 printf(
"Track %p\n",(
void*)
this);
1722 StiHit *hit = node->getHit();
1723 if (!hit && strchr(opt,
'h'))
continue;
1724 if (!hit && strchr(opt,
'H'))
continue;
1732 int StiKalmanTrack::approx(
int mode)
1735 const double BAD_XI2[2] = {99,22}, XI2_FACT = 9;
1746 for (source = rbegin(); (targetNode = source()); ++source) {
1747 if (!targetNode->isValid())
continue;
1748 const StiHit * hit = targetNode->getHit();
1750 if (targetNode->getChi2()>1000)
continue;
1752 double hz = targetNode->
getHz();
1753 zeroH = fabs(hz)<=kZEROHZ;
1755 circ.Add(hit->
x_g(),hit->y_g(),hit->z_g());
1756 if (mode & kAppRR) {
1757 hr = targetNode->getGlobalHitErrs(hit);
1758 circ.AddErr(hr.G(),hr.hZZ);
1762 if (!nNode)
return 1;
1765 if (mXi2 > BAD_XI2[mode & kAppGud])
return 2;
1766 if (zeroH) circ.Set(kZEROCURV);
1767 if (mode & kAppRR) circ.MakeErrs();
1770 double curv = circ.GetRho();
1771 for (source = rbegin(); (targetNode = source()); ++source) {
1772 if (!targetNode->isValid())
continue;
1773 const StiHit *hit = targetNode->getHit();
1775 xyz[0] = hit->
x_g();
1776 xyz[1] = hit->y_g();
1777 xyz[2] = hit->z_g();
1779 xyz[0] = targetNode->x_g();
1780 xyz[1] = targetNode->y_g();
1781 xyz[2] = targetNode->z_g();
1783 double ds = circ.Path(xyz[0],xyz[1]);
1786 int upd = (mode & kAppUPD);
1787 upd |= ((mode & kAppUpd) && (targetNode == firstNode));
1790 double alfa = targetNode->getAlpha();
1793 P.x() = cirl.Pos()[0];
1794 P.y() = cirl.Pos()[1];
1795 P.z() = cirl.Pos()[2];
1796 P.eta() = atan2(cirl.Dir()[1],cirl.Dir()[0]);
1799 hh = (fabs(hh)<1e-10)? 0:1./hh;
1800 P.ptin() = (hh)? curv*hh:1e-3;
1802 P.tanl() = cirl.GetSin()/cirl.GetCos();
1803 P.
_cosCA = cirl.Dir()[0]/cirl.GetCos();
1804 P._sinCA = cirl.Dir()[1]/cirl.GetCos();
1805 if (fabs(P.
_cosCA)>0.99 || fabs(P._sinCA)>0.99) P.ready();
1807 targetNode->fitPars() = P;
1808 int ians = targetNode->nudge();
1809 if(ians) {nNode--; targetNode->setInvalid();
continue;}
1810 if (mode & kAppRR) {
1811 P = targetNode->fitPars();
1814 TCL::vscale(&(E._cPX),hh,&(E._cPX),5);
1815 E._cPP*=hh; E._cTP*=hh;
1816 if ((mode & kAppGud) == 0 && mXi2 > XI2_FACT) E*=mXi2/XI2_FACT;
1817 E.check(
"In aprox");
1827 for (
int i=0;i<kNPars;i++) {
1828 double err = 0.5*(e1(i,i)+e2(i,i));
1829 if (err<1e-10)
continue;
1830 double dif = pow(p1[i]-p2[i],2)/err;
1831 if (est<dif) {est = dif; igor = i;}
1838 StiTrack::operator=(tk);
1842 mSeedHitCount=tk.mSeedHitCount;
1847 mVertex =tk.mVertex;
1849 for (it=tk.
begin();it!=tk.
end();it++){
1851 if (!node->isValid())
continue;
1854 add(myNode,kOutsideIn);
1860 void StiKalmanTrack::setMaxRefiter(
int maxRefiter)
1865 int StiKalmanTrack::rejectByHitSet()
const
1870 if (node->x()>50)
break;
1871 if (!node->isValid())
continue;
1872 StiHit *hit = node->getHit();
1875 if (node->getChi2()>1000)
continue;
1876 sum+= StiKalmanTrackFinderParameters::instance()->hitWeight(
int(hit->
x()));
1879 return sum < StiKalmanTrackFinderParameters::instance()->sumWeight();
1882 int StiKalmanTrack::releaseHits(
double rMin,
double rMax)
1887 StiHit *hit = node->getHit();
1890 if (hit->
x()<rMin)
continue;
1891 if (hit->
x()>rMax)
break;
1898 void StiKalmanTrack::test(
const char *txt)
const
1901 for (
auto it=
begin();it!=
end();it++) {
1903 if (!node->isValid())
continue;
1906 const auto &P = node->fitPars();
1907 double tst = P[0]*P.
_cosCA+P[1]*P._sinCA;
1908 if (tst>=0)
continue;
1909 tst /= sqrt(P[0]*P[0]+P[1]*P[1]);
1911 StiDebug::Count(
"OverKill",tst);
1916 #include "StarRoot/TIdTruUtil.h"
1918 int StiKalmanTrack::idTruth(
int *qa)
const
1921 for (
auto it=
begin();it!=
end();it++) {
1923 if (!node->isValid())
continue;
1924 const StiHit *hit = node->getHit();
1926 if (!node->getDetector())
continue;
1927 if ( node->getChi2()>100)
continue;
1928 ut.Add(hit->idTruth(),hit->qaTruth());
1930 if (qa) *qa = 100*ut.GetQua();
1931 return ut.GetIdTru();
StiKalmanTrackNode * getInnOutMostNode(int inot, int qua) const
Same for getNNodes(qua)
int propagate(StiKalmanTrackNode *p, const StiDetector *tDet, int dir)
Propagates a track encapsulated by the given node "p" to the given detector "tDet".
StiKalmanTrackNode * getInnerMostHitNode(int qua=0) const
Accessor method returns the inner most hit node associated with the track.
Definition of Kalman Track.
double getNearBeam(StThreeVectorD *pnt=0, StThreeVectorD *dir=0) const
double getTrackRadLength() const
int h() const
y-center of circle in xy-plane
StiKalmanTrackNode * getOuterMostHitNode(int qua=0) const
Accessor method returns the outer most hit node associated with the track.
int propagateToRadius(StiKalmanTrackNode *pNode, double radius, int dir)
int getMaxPointCount(int detectorId=0) const
Abstract definition of a Track.
bool moveIn(double phiCut=-1.0, double zCut=-1.0, double rMin=-1.0)
Step in radially in STAR TPC global coordinates.
StiTrackNode * extendToVertex(StiHit *vertex)
int getGapCount() const
Return the number of gaps on this track.
StiKalmanTrackNode * getLastNode() const
Accessor method returns the last node associated with the track.
bool propagateToBeam(const StiKalmanTrackNode *p, int dir)
void getAllPointCount(int count[1][3], int maxDetId) const
Returns all the PointCount far all detectors and types of nodes.
void setToDetector(const StiDetector *layer)
Set iterators to the detector nearest to the passed StiDetector pointer.
const Float_t & x() const
Return the local x, y, z values.
virtual void free(Abstract *obj)=0
Free an object for reuse.
StiKalmanTrackNode * getOuterMostNode(int qua=0) const
Accessor method returns the outer most node associated with the track.
virtual vector< StiHit * > getHits()
void reserveHits(int yes=1)
void rotate(double angle)
const StiDetector * detector() const
double pathLToNode(const StiKalmanTrackNode *const oNode)
Float_t x_g() const
Return the global x, y, z values.
virtual vector< StiKalmanTrackNode * > getNodes(int detectorGroupId) const
return vector of nodes with hits
int print(const char *opt) const
rotation angle of local coordinates wrt global coordinates
pair< double, double > pathLength(double r) const
path length at given r (cylindrical r)
int getFitPointCount(int detectorId=0) const
Returns the number of hits associated and used in the fit of this track.
virtual Abstract * getInstance()=0
Get a pointer to instance of objects served by this factory.
StiKalmanTrackNode * getInnerMostNode(int qua=0) const
Accessor method returns the inner most node associated with the track.
double getChi2Max() const
Return the maximal node chi2.
int getPointCount(int detectorId=0) const
Return the number of hits associated with this track.
Definition of Kalman Track.
virtual int initialize(const vector< StiHit * > &)
Convenience method to initialize a track based on seed information.
StiKalmanTrackNode * extrapolateToBeam()
static void Free(void *obj)
Free an object for reuse.
Int_t isDca() const
Test for DCA. Fake hit for dca calculation.
double _cosCA
sine and cosine of cross angle
const StiKTNBidirectionalIterator & end() const
double evaluateChi2(const StiHit *hit)
virtual vector< const StMeasuredPoint * > stHits() const
return hits;
double getTrackLength() const
double getCurvature() const
Calculates and returns the tangent of the track pitch angle at this node.
const StMeasuredPoint * stHit() const
virtual void moveOrigin(double s)
move the origin along the helix to s which becomes then s=0
virtual void add(StiTrackNode *node, int direction, StiTrackNode *near=0)
double period() const
returns period length of helix
double Move(double step)
Move along helix.
int getCharge() const
Get the charge (sign) of the track at this node.
StiKTNBidirectionalIterator begin() const
double phase() const
1/R in xy-plane
static void setKalmanTrackNodeFactory(Factory< StiKalmanTrackNode > *)
Set the factory used for the creation of kalman track nodes.
void initialize(StiHit *h)
Initialize this node with the given hit information.
const string & getName() const
Get the name of the object.