35 for(
int i = 0; i < _trk.
getNHits(); i++)
65 for(
auto iter = tracklet.
hits.begin(); iter != tracklet.
hits.end(); ++iter)
67 if(iter->hit.index < 0)
continue;
70 _nodes.push_back(node_add);
71 _hit_index.push_back(iter->sign*iter->hit.index);
93 _nodes.back().getPredicted() = _trkpar_curr;
99 if(_chisq < 0 || _chisq/_hit_index.size() > 100)
return false;
100 if(_nodes.empty())
return false;
109 double z_bend_k = 1064.26;
110 double z_bend_f = 251.4;
111 double kick_f = -2.911;
112 double kick_k = -0.4;
113 double deltaE_kf = 8.12;
114 double c4 = deltaE_kf;
115 double c5 = deltaE_kf/2.;
117 double z_ref = _nodes.front().getZ();
118 double x_ref = _nodes.front().getFiltered()._state_kf[3][0];
119 double axz = _nodes.front().getFiltered()._state_kf[1][0];
122 if(_nodes.front().getFiltered()._state_kf[0][0] > 0)
131 double c1 = (z_0 - z_bend_f)*kick_f*charge;
132 double c2 = (z_0 - z_bend_k)*kick_k*charge;
133 double c3 = axz*(z_ref - z_0) - x_ref;
134 double b = c1/c3 + c2/c3 - c4 - c5;
135 double c = c4*c5 - c1*c5/c3 - c2*c4/c3;
137 double disc = b*b - 4.*c;
143 double p = (-b + sqrt(disc))/2.;
146 if(p < 0. || p > 100.)
153 for(std::list<Node>::iterator iter = _nodes.begin(); iter != _nodes.end(); ++iter)
155 iter->getPredicted()._state_kf[0][0] = charge/p;
156 iter->getFiltered()._state_kf[0][0] = charge/p;
172 TrkPar _trkpar = _nodes.back().getSmoothed();
182 _nodes.back().getPredicted() = _trkpar;
190 _node_next =
Node(hit_dummy);
207 _node_vertex.
setZ(z);
209 TMatrixD m(2, 1), cov(2, 2), proj(2, 5);
233 _chisq_vertex = _node_vertex.
getChisq();
249 return (proj*state)[0][0];
266 return sqrt(wire_spacing*wire_spacing + track_err_sq);
271 Node *_node_prev = &(_nodes.front());
272 double deltaZ_curr, deltaZ_prev;
274 for(std::list<Node>::iterator iter = _nodes.begin(); iter != _nodes.end(); ++iter)
276 deltaZ_curr = fabs(z - iter->getZ());
277 if(deltaZ_curr > deltaZ_prev)
282 deltaZ_prev = deltaZ_curr;
283 _node_prev = &(*iter);
310 double z_ref = _trkpar->
get_z();
311 double x_ref = _trkpar->
get_x();
312 double y_ref = _trkpar->
get_y();
316 x = x_ref + axz*(z - z_ref);
317 y = y_ref + ayz*(z - z_ref);
341 double z_ref = _trkpar->
get_z();
342 double dx_ref = sqrt(fabs(_trkpar->
_covar_kf[3][3]));
343 double dy_ref = sqrt(fabs(_trkpar->
_covar_kf[4][4]));
344 double daxz = sqrt(fabs(_trkpar->
_covar_kf[1][1]));
345 double dayz = sqrt(fabs(_trkpar->
_covar_kf[2][2]));
347 dx = 2.*(dx_ref + fabs(daxz*(z - z_ref)));
348 dy = 2.*(dy_ref + fabs(dayz*(z - z_ref)));
357 return proj[0][3]*state[1][0] + proj[0][4]*state[2][0];
365 double err_x = sqrt(covar[1][1]);
366 double err_y = sqrt(covar[2][2]);
368 return fabs(proj[0][3]*err_x) + fabs(proj[0][4]*err_y);
373 Node* _node =
nullptr;
374 for(std::list<Node>::iterator iter = _nodes.begin(); iter != _nodes.end(); ++iter)
392 Node* _node =
nullptr;
393 for(std::list<Node>::reverse_iterator iter = _nodes.rbegin(); iter != _nodes.rend(); ++iter)
411 int detectorID_begin = stationID*6 - 5;
412 int detectorID_end = stationID*6;
415 for(std::list<Node>::iterator iter = _nodes.begin(); iter != _nodes.end(); ++iter)
417 double detectorID = iter->getHit().detectorID;
418 if(detectorID >= detectorID_begin && detectorID <= detectorID_end)
420 p = iter->getFiltered().get_mom();
430 int detectorID_begin = stationID*6 - 5;
431 int detectorID_end = stationID*6;
434 for(std::list<Node>::iterator iter = _nodes.begin(); iter != _nodes.end(); ++iter)
436 double detectorID = iter->getHit().detectorID;
437 if(detectorID >= detectorID_begin && detectorID <= detectorID_end)
439 axz = iter->getFiltered().get_dxdz();
449 int detectorID_begin = stationID*6 - 5;
450 int detectorID_end = stationID*6;
454 for(std::list<Node>::iterator iter = _nodes.begin(); iter != _nodes.end(); ++iter)
456 double detectorID = iter->getHit().detectorID;
457 if(detectorID >= detectorID_begin && detectorID <= detectorID_end)
460 if(iter->isSmoothDone())
462 x = iter->getSmoothed().get_x();
463 y = iter->getSmoothed().get_y();
465 else if(iter->isFilterDone())
467 x = iter->getFiltered().get_x();
468 y = iter->getFiltered().get_y();
474 return sqrt(x*x + y*y);
483 return axz_st1 < axz_st2 ? -1 : 1;
488 if(_nodes.front().isSmoothDone())
490 return _nodes.front().getSmoothed().get_mom(px, py, pz);
492 else if(_nodes.front().isFilterDone())
494 return _nodes.front().getFiltered().get_mom(px, py, pz);
498 return _nodes.front().getPredicted().get_mom(px, py, pz);
504 int detectorID_begin = stationID*6 - 5;
505 int detectorID_end = stationID*6;
508 for(std::list<Node>::iterator iter = _nodes.begin(); iter != _nodes.end(); ++iter)
510 int detectorID = iter->getHit().detectorID;
511 if(detectorID >= detectorID_begin && detectorID <= detectorID_end)
522 double nHits = _hit_index.size();
525 for(std::list<Node>::iterator node = _nodes.begin(); node != _nodes.end(); ++node)
527 _chisq += node->getChisq();
530 _quality = nHits - 0.4*_chisq;
535 return _quality > elem._quality;
540 if(_hit_index.size() != elem._hit_index.size())
return false;
541 if(fabs(_quality - elem._quality) > 1E-6)
return false;
548 std::list<int> _hit_index1, _hit_index2;
551 for(std::list<int>::const_iterator iter = _hit_index.begin(); iter != _hit_index.end(); ++iter)
553 _hit_index1.push_back(abs(*iter));
558 for(std::list<int>::const_iterator iter = elem._hit_index.begin(); iter != elem._hit_index.end(); ++iter)
560 _hit_index2.push_back(abs(*iter));
564 std::list<int> commonHits;
566 set_intersection(_hit_index1.begin(), _hit_index1.end(), _hit_index2.begin(), _hit_index2.end(), back_inserter(commonHits));
568 double nHits_original = double(_hit_index1.size());
569 double nHits_common = double(commonHits.size());
571 if(nHits_common/nHits_original > 0.2)
return true;
578 _hit_index.push_front(_hit.
index);
587 _nodes.push_front(_node);
602 if(level != 1 && level != 2 && level != 3)
604 std::cerr <<
"Wrong output level selection! " << std::endl;
612 for(std::list<Node>::iterator iter = _nodes.begin(); iter != _nodes.end(); ++iter)
616 x = iter->getSmoothed().get_x();
617 y = iter->getSmoothed().get_y();
618 res[nHits] = iter->getSmoothedResidual()[0][0];
622 x = iter->getFiltered().get_x();
623 y = iter->getFiltered().get_y();
624 res[nHits] = iter->getFilteredResidual()[0][0];
628 x = iter->getPredicted().get_x();
629 y = iter->getPredicted().get_y();
630 res[nHits] = iter->getPredictedResidual()[0][0];
633 detectorID[nHits] = iter->getHit().detectorID;
634 R[nHits] = x*p_geomSvc->
getCostheta(detectorID[nHits]) + y*p_geomSvc->
getSintheta(detectorID[nHits]) - iter->getHit().pos;
635 T[nHits] = iter->getHit().tdcTime;
645 if(level != 1 && level != 2 && level != 3)
647 std::cerr <<
"Wrong output level selection! " << std::endl;
652 for(std::list<Node>::iterator iter = _nodes.begin(); iter != _nodes.end(); ++iter)
654 z[nHits] = iter->getZ();
657 x[nHits] = iter->getSmoothed().get_x();
658 y[nHits] = iter->getSmoothed().get_y();
662 x[nHits] = iter->getFiltered().get_x();
663 y[nHits] = iter->getFiltered().get_y();
667 x[nHits] = iter->getPredicted().get_x();
668 y[nHits] = iter->getPredicted().get_y();
679 if(level != 1 && level != 2 && level != 3)
681 std::cerr <<
"Wrong output level selection! " << std::endl;
686 for(std::list<Node>::iterator iter = _nodes.begin(); iter != _nodes.end(); ++iter)
688 double m_px, m_py, m_pz;
691 iter->getSmoothed().get_mom(m_px, m_py, m_pz);
695 iter->getFiltered().get_mom(m_px, m_py, m_pz);
699 iter->getPredicted().get_mom(m_px, m_py, m_pz);
715 for(std::list<int>::iterator iter = _hit_index.begin(); iter != _hit_index.end(); ++iter)
717 index[nHits] = *iter;
726 std::vector<int> detectorIDs_all;
727 for(
int i = 1; i <= 12; ++i) detectorIDs_all.push_back(i);
728 if(_nodes.back().getHit().detectorID < 19)
730 for(
int i = 13; i <= 18; ++i) detectorIDs_all.push_back(i);
734 for(
int i = 19; i <= 24; ++i) detectorIDs_all.push_back(i);
737 std::vector<int> detectorIDs_now;
738 detectorIDs_now.clear();
739 for(std::list<Node>::iterator iter = _nodes.begin(); iter != _nodes.end(); ++iter)
741 detectorIDs_now.push_back(iter->getHit().detectorID);
743 std::sort(detectorIDs_now.begin(), detectorIDs_now.end());
745 std::vector<int> detectorIDs_miss(18);
746 std::vector<int>::iterator iter = std::set_difference(detectorIDs_all.begin(), detectorIDs_all.end(), detectorIDs_now.begin(), detectorIDs_now.end(), detectorIDs_miss.begin());
747 detectorIDs_miss.resize(iter - detectorIDs_miss.begin());
749 return detectorIDs_miss;
754 if(detectorID > 3 || detectorID < 1)
return;
758 int detectorID_st2[3] = {12, 10, 8};
759 double ratio[3] = {1.9, 1.80, 1.7};
760 double sigma[3] = {0.2, 0.2, 0.2};
762 double x_st3, y_st3, z_st3;
763 z_st3 = _nodes.back().getZ();
764 if(_nodes.back().isSmoothDone())
766 x_st3 = _nodes.back().getSmoothed().get_x();
767 y_st3 = _nodes.back().getSmoothed().get_y();
769 else if(_nodes.back().isFilterDone())
771 x_st3 = _nodes.back().getFiltered().get_x();
772 y_st3 = _nodes.back().getFiltered().get_y();
776 x_st3 = _nodes.back().getPredicted().get_x();
777 y_st3 = _nodes.back().getPredicted().get_y();
779 double pos_st3 = x_st3*p_geomSvc->
getCostheta(_nodes.back().getHit().detectorID) + y_st3*p_geomSvc->
getSintheta(_nodes.back().getHit().detectorID);
781 double x_st2, y_st2, z_st2;
784 double pos_st2 = x_st2*p_geomSvc->
getCostheta(detectorID_st2[detectorID-1]) + y_st2*p_geomSvc->
getSintheta(detectorID_st2[detectorID-1]);
785 double sagitta_st2 = pos_st2 - pos_st3/z_st3*z_st2;
788 pos_exp = sagitta_st2*ratio[detectorID-1] + pos_st3/z_st3*z_st1;
789 window = fabs(6.*sagitta_st2*sigma[detectorID-1]);
794 double x[20], y[20], z[20];
806 for(std::list<Node>::iterator iter = _nodes.begin(); iter != _nodes.end(); ++iter)
822 std::cout <<
"=============== Kalman finder candidate track ==================" << std::endl;
823 std::cout <<
"This candidate has " << _hit_index.size() <<
" hits!" << std::endl;
825 for(std::list<int>::iterator iter = _hit_index.begin(); iter != _hit_index.end(); ++iter)
827 std::cout << *iter <<
" : ";
829 std::cout << std::endl;
831 for(std::list<Node>::iterator iter = _nodes.begin(); iter != _nodes.end(); ++iter)
833 std::cout << iter->getHit().detectorID <<
" : ";
835 std::cout << std::endl;
837 std::cout <<
"Most upstream momentum is: " << 1./fabs(_trkpar_curr.
_state_kf[0][0]) << std::endl;
838 std::cout <<
"Most upstream position is: " << _trkpar_curr.
get_z() << std::endl;
839 std::cout <<
"Current slope: X-Z = " << _trkpar_curr.
_state_kf[1][0] <<
", Y-Z = " << _trkpar_curr.
_state_kf[2][0] << std::endl;
840 std::cout <<
"Current position: X = " << _trkpar_curr.
_state_kf[3][0] <<
", Y = " << _trkpar_curr.
_state_kf[4][0] << std::endl;
841 std::cout <<
"Quality is: " << _quality << std::endl;
842 std::cout <<
"Chisq/d.o.f = " << _chisq/_hit_index.size() << std::endl;
843 if(!_hit_index.empty()) std::cout <<
"Charge = " <<
getCharge() << std::endl;
844 if(!_hit_index.empty()) std::cout <<
"Assigned Charge = " <<
getAssignedCharge() << std::endl;
845 if(!_hit_index.empty()) std::cout <<
"Kick Charge = " <<
getKickCharge() << std::endl;
853 std::cout <<
"The content of all Nodes of this track ... " << std::endl;
854 for(std::list<Node>::reverse_iterator node = _nodes.rbegin(); node != _nodes.rend(); ++node)
bool predict(Node &_node)
Kalman filter steps.
void insertHitIndex(Int_t index)
TrkPar & getPredicted()
Gets.
void insertChisq(Double_t chisq)
double getPositionInStation(int stationID, double &x, double &y, double &z)
Double_t getChisq() const
SRecTrack getSRecTrack()
Output to SRecTrack.
double getSintheta(int detectorID) const
Node * getNodeDownstream()
Get Nodes in both upstream and downstream which are closest to KMag.
void print()
Debugging print.
void updateMomentum()
Update the momentum.
TMatrixD & getMeasurement()
void insertStateVector(TMatrixD state)
void setChisq(double chisq)
double getMomentumUpstream()
void setKalmanStatus(Int_t status)
Int_t getHitIndex(Int_t i)
bool operator==(const KalmanTrack &elem) const
bool operator<(const KalmanTrack &elem) const
Overriden operators.
void setPredictionDone(bool flag=true)
double getExpPositionY(double z) const
TMatrixD & getProjector()
void insertCovariance(TMatrixD covar)
void getExpPosErrorFast(double z, double &dx, double &dy, Node *_node=nullptr)
void getSagittaInSuperDetector(int detectorID, double &pos_exp, double &window)
bool propagateTo(int detectorID)
Propagate the track to a designated position.
void setCurrTrkpar(Node &_node)
set the current track parameter using the current node
Definition of hit structure.
std::list< SignedHit > hits
double get_mom(double &px, double &py, double &pz)
int getAlignment(int level, int *detectorID, double *res, double *R, double *T)
double getExpLocalSlop()
Get the expected slope.
int getNHitsInStation(int stationID)
bool fit_node(Node &_node)
Fit one node.
TMatrixD & getMeasurementCov()
void setTracklet(Tracklet &tracklet, bool wildseedcov=true)
std::vector< int > getMissedDetectorIDs()
static KalmanFilter * instance()
singlton instance
double getXZSlopeInStation(int stationID)
double getPlaneSpacing(int detectorID) const
int getPositions(int level, double *x, double *y, double *z)
TMatrixD _state_kf
State vectors and its covariance.
static TMatrixD getABCt(const TMatrixD &A, const TMatrixD &B, const TMatrixD &C)
void update()
Update the track status.
double getMomentumInStation(int stationID)
void flipCharge()
Flip the sign of this track.
Node * getNearestNodePtr(double z)
double getCostheta(int detectorID) const
TMatrixD getCovariance(Int_t i)
static GeomSvc * instance()
singlton instance
void setFilterDone(bool flag=true)
bool similarity(const KalmanTrack &elem) const
Double_t getChisqAtNode(Int_t i)
void getExpPositionFast(double z, double &x, double &y, Node *_node=nullptr)
TMatrixD getStateVector(Int_t i)
Int_t getLocalID(Int_t hitID)
int getHitsIndex(int *index)
void getMeasurement(int detectorID, int elementID, double &measurement, double &dmeasurement)
Convert the detectorID and elementID to the actual hit position.
double getMomentumVertex(double z, double &px, double &py, double &pz)
Get the rough vertex momentum.
bool isValid()
Self check to see if it is null.
double getExpPositionX(double z) const
double getDriftDistance(int detectorID, double tdcTime)
double getExpPosition()
Get the expected position.
void setChisq(Double_t chisq)
Sets.
KalmanTrack()
Constructor, default one is for list::resize()
int getMomentums(int level, double *px, double *py, double *pz)
void setSmoothDone(bool flag=true)
double getPlanePosition(int detectorID) const
void swimToVertex(TVector3 *pos=nullptr, TVector3 *mom=nullptr, bool hyptest=true)
Simple swim to vertex.