25#include "FairRootManager.h"
26#include "KFParticleDatabase.h"
30#include "TClonesArray.h"
31#include "TDatabasePDG.h"
54 FairRootManager* ioman = FairRootManager::Instance();
57 LOG(fatal) <<
"CbmKfTrackFitter: no FairRootManager";
63 LOG(fatal) <<
"CbmTrackingDetectorInterface instance was not found. Please, add it as a task to your "
64 "reco macro right before the KF and L1 tasks:\n"
65 <<
"\033[1;30mrun->AddTask(new CbmTrackingDetectorInterfaceInit());\033[0m";
70 fInputMvdHits =
dynamic_cast<TClonesArray*
>(ioman->GetObject(
"MvdHit"));
71 fInputStsHits =
dynamic_cast<TClonesArray*
>(ioman->GetObject(
"StsHit"));
72 fInputTrdHits =
dynamic_cast<TClonesArray*
>(ioman->GetObject(
"TrdHit"));
73 fInputMuchHits =
dynamic_cast<TClonesArray*
>(ioman->GetObject(
"MuchHit"));
74 fInputTofHits =
dynamic_cast<TClonesArray*
>(ioman->GetObject(
"TofHit"));
80 fInputStsTracks =
dynamic_cast<TClonesArray*
>(ioman->GetObject(
"StsTrack"));
81 fInputMuchTracks =
dynamic_cast<TClonesArray*
>(ioman->GetObject(
"MuchTrack"));
82 fInputTrdTracks =
dynamic_cast<TClonesArray*
>(ioman->GetObject(
"TrdTrack"));
83 fInputTofTracks =
dynamic_cast<TClonesArray*
>(ioman->GetObject(
"TofTrack"));
92 TParticlePDG* particlePDG = TDatabasePDG::Instance()->GetParticle(pdg);
94 LOG(fatal) <<
"CbmKfTrackFitter: particle PDG " << pdg <<
" is not in the data base, please set the mass manually";
97 fMass = particlePDG->Mass();
119 LOG(error) <<
"CbmKfTrackFitter: Sts track array not found!";
123 LOG(error) <<
"CbmKfTrackFitter: Sts track index " << stsTrackIndex <<
" is out of range!";
128 LOG(error) <<
"CbmKfTrackFitter: Sts track is null!";
134 globalTrack.
SetParamFirst(*
dynamic_cast<const FairTrackParam*
>(stsTrack->GetParamFirst()));
148 LOG(error) <<
"CbmKfTrackFitter: Global track array not found!";
153 LOG(error) <<
"CbmKfTrackFitter: Global track index " << globalTrackIndex <<
" is out of range!";
159 LOG(error) <<
"CbmKfTrackFitter: Global track is null!";
179 for (
int i = 0; i <
fKfSetup->GetNofLayers(); i++) {
196 auto setNode = [&](
const CbmPixelHit&
h,
int stIdx,
int hitIdx,
198 int iLayer =
fKfSetup->GetIndexMap().LocalToGlobal(detId, stIdx);
202 assert(iLayer >= 0 && iLayer < fKfSetup->GetNofLayers());
216 n.
fIsTimeSet = (detId != ca::EDetectorID::kMvd);
232 LOG(error) <<
"CbmKfTrackFitter: Sts track array not found!";
236 LOG(error) <<
"CbmKfTrackFitter: Sts track index " << stsTrackIndex <<
" is out of range!";
241 LOG(error) <<
"CbmKfTrackFitter: Sts track is null!";
250 LOG(error) <<
"CbmKfTrackFitter: Mvd hit array not found!";
254 LOG(error) <<
"CbmKfTrackFitter: Mvd tracking interface not found!";
257 for (
int ih = 0; ih < nMvdHits; ih++) {
258 int hitIndex = stsTrack->GetMvdHitIndex(ih);
260 LOG(error) <<
"CbmKfTrackFitter: Mvd hit index " << hitIndex <<
" is out of range!";
265 ca::EDetectorID::kMvd);
271 int nStsHits = stsTrack->GetNofStsHits();
274 LOG(error) <<
"CbmKfTrackFitter: Sts hit array not found!";
278 LOG(error) <<
"CbmKfTrackFitter: Sts tracking interface not found!";
281 for (
int ih = 0; ih <
nStsHits; ih++) {
282 int hitIndex = stsTrack->GetStsHitIndex(ih);
284 LOG(error) <<
"CbmKfTrackFitter: Sts hit index " << hitIndex <<
" is out of range!";
289 ca::EDetectorID::kSts);
300 LOG(error) <<
"CbmKfTrackFitter: Much track array not found!";
304 LOG(error) <<
"CbmKfTrackFitter: Much track index " << muchTrackIndex <<
" is out of range!";
309 LOG(error) <<
"CbmKfTrackFitter: Much track is null!";
315 LOG(error) <<
"CbmKfTrackFitter: Much hit array not found!";
319 LOG(error) <<
"CbmKfTrackFitter: Much tracking interface not found!";
322 for (
int ih = 0; ih < nHits; ih++) {
323 int hitIndex = track->GetHitIndex(ih);
325 LOG(error) <<
"CbmKfTrackFitter: Much hit index " << hitIndex <<
" is out of range!";
330 ca::EDetectorID::kMuch);
340 LOG(error) <<
"CbmKfTrackFitter: Trd track array not found!";
344 LOG(error) <<
"CbmKfTrackFitter: Trd track index " << trdTrackIndex <<
" is out of range!";
349 LOG(error) <<
"CbmKfTrackFitter: Trd track is null!";
355 LOG(error) <<
"CbmKfTrackFitter: Trd hit array not found!";
359 LOG(error) <<
"CbmKfTrackFitter: Trd tracking interface not found!";
362 for (
int ih = 0; ih < nHits; ih++) {
363 int hitIndex = track->GetHitIndex(ih);
365 LOG(error) <<
"CbmKfTrackFitter: Trd hit index " << hitIndex <<
" is out of range!";
371 ca::EDetectorID::kTrd);
372 if (node !=
nullptr && hit.GetClassType() == 1) {
385 LOG(error) <<
"CbmKfTrackFitter: Trd track array not found!";
389 LOG(error) <<
"CbmKfTrackFitter: Trd track index " << tofTrackIndex <<
" is out of range!";
394 LOG(error) <<
"CbmKfTrackFitter: Tof track is null!";
401 LOG(error) <<
"CbmKfTrackFitter: Tof hit array not found!";
405 LOG(error) <<
"CbmKfTrackFitter: Tof tracking interface not found!";
408 for (
int ih = 0; ih < nHits; ih++) {
409 int hitIndex = track->GetHitIndex(ih);
411 LOG(error) <<
"CbmKfTrackFitter: Tof hit index " << hitIndex <<
" is out of range!";
416 ca::EDetectorID::kTof);
437 const auto& mxy = n.
fMxy;
438 const auto& mt = n.
fMt;
442 if (fabs(tr.GetZ() - n.
fZ) > 1.e-10) {
443 LOG(fatal) <<
"CbmKfTrackFitter: Z mismatch: fitted track " << tr.GetZ() <<
" != node " << n.
fZ;
446 tr.
ResetErrors(mxy.Dx2(), mxy.Dy2(), 100., 100., 10., 1.e4, 1.e2);
447 tr.SetC10(mxy.Dxy());
453 if (mxy.NdfX() == 0) {
457 if (mxy.NdfY() == 0) {
466 tr.SetNdf(-5. + mxy.NdfX() + mxy.NdfY());
470 tr.SetNdfTime(-2 + 1);
476 tr.InitVelocityRange(0.5);
505 if (direction == kf::FitDirection::kDownstream) {
520 std::cout <<
"FitTrajectory ... " << std::endl;
527 int nNodes = t.
fNodes.size();
530 LOG(warning) <<
"CbmKfTrackFitter: no nodes found!";
534 int firstHitNode = -1;
535 int lastHitNode = -1;
536 bool isOrdered =
true;
539 double zOld = -1.e10;
540 for (
int i = 0; i < nNodes; i++) {
541 const auto& n = t.
fNodes[i];
543 if (firstHitNode < 0) {
555 if (firstHitNode < 0 || lastHitNode < 0) {
556 LOG(warning) <<
"CbmKfTrackFitter: no hit nodes found!";
561 LOG(warning) <<
"CbmKfTrackFitter: track nodes are not ordered in Z!";
570 std::vector<LinearizationAtNode> linearization(nNodes);
573 for (
int i = firstHitNode; i <= lastHitNode; i++) {
574 if (!t.
fNodes[i].fIsFitted) {
575 LOG(fatal) <<
"CbmKfTrackFitter: node " << i <<
" in the measured region is not fitted";
577 linearization[i].fParamDn = t.
fNodes[i].fParamDn;
578 linearization[i].fParamUp = t.
fNodes[i].fParamUp;
582 for (
int i1 = firstHitNode, i2 = firstHitNode + 1; i2 <= lastHitNode; i2++) {
588 double dz = n2.fZ - n1.fZ;
589 double dzi = (fabs(dz) > 1.e-4) ? 1. / dz : 0.;
590 double tx = (n2.fMxy.X() - n1.fMxy.X()) * dzi;
591 double ty = (n2.fMxy.Y() - n1.fMxy.Y()) * dzi;
592 for (
int i = i1; i <= i2; i++) {
594 auto& l = linearization[i];
595 double x = n1.fMxy.X() + tx * (n.fZ - n1.fZ);
596 double y = n1.fMxy.Y() + ty * (n.fZ - n1.fZ);
598 || i == lastHitNode) {
601 l.fParamDn.SetZ(n.fZ);
602 l.fParamDn.SetTx(tx);
603 l.fParamDn.SetTy(ty);
604 l.fParamDn.SetQp(0.);
605 l.fParamDn.SetTime(0.);
608 if (i > i1 || i == firstHitNode) {
611 l.fParamUp.SetZ(n.fZ);
612 l.fParamUp.SetTx(tx);
613 l.fParamUp.SetTy(ty);
614 l.fParamUp.SetQp(0.);
615 l.fParamUp.SetTime(0.);
624 for (
auto& n : t.
fNodes) {
628 auto printNode = [&](std::string str,
int node) {
644 printNode(
"fit downstream", firstHitNode);
647 for (
int iNode = firstHitNode + 1; iNode <= lastHitNode; iNode++) {
652 fFit.
SetQp0(linearization[iNode - 1].fParamDn.GetQp());
662 printNode(
"fit downstream", iNode);
686 printNode(
"fit upstream", lastHitNode);
689 for (
int iNode = lastHitNode - 1; ok && (iNode > firstHitNode); iNode--) {
694 fFit.
SetQp0(linearization[iNode + 1].fParamUp.GetQp());
714 printNode(
"fit upstream", iNode);
722 int iNode = firstHitNode;
727 fFit.
SetQp0(linearization[iNode + 1].fParamUp.GetQp());
737 printNode(
"fit upstream", iNode);
750 for (
int i = lastHitNode + 1; i < nNodes; i++) {
765 for (
int i = firstHitNode - 1; i >= 0; i--) {
782 if (fabs(upChi2 - dnChi2) > 1.e-1) {
784 LOG(debug) <<
"CbmKfTrackFitter: " <<
fDebugInfo <<
": chi2 mismatch: dn " << dnChi2 <<
" != up " << upChi2
785 <<
" first node " << firstHitNode <<
" last node " << lastHitNode <<
" of " << nNodes;
793 const auto& tt =
fFit.
Tr();
794 for (
int iNode = 0; iNode < nNodes; iNode++) {
813 constexpr int nPar = kf::TrackParamV::kNtrackParam;
814 constexpr int nCov = kf::TrackParamV::kNcovParam;
816 double r[nPar] = {t1.
X(), t1.
Y(), t1.
Tx(), t1.
Ty(), t1.
Qp(), t1.
Time(), t1.
Vi()};
817 double m[nPar] = {t2.
X(), t2.
Y(), t2.
Tx(), t2.
Ty(), t2.
Qp(), t2.
Time(), t2.
Vi()};
819 double S[nCov], S1[nCov], Tmp[nCov];
820 for (
int i = 0; i < nCov; i++) {
828 if ((0 != ifault) || (0 != nullty)) {
834 for (
int i = 0; i < nPar; i++) {
835 dzeta[i] = m[i] - r[i];
838 double C[nPar][nPar];
839 double Si[nPar][nPar];
840 for (
int i = 0, k = 0; i < nPar; i++) {
841 for (
int j = 0; j <= i; j++, k++) {
850 double K[nPar][nPar];
851 for (
int i = 0; i < nPar; i++) {
852 for (
int j = 0; j < nPar; j++) {
854 for (
int k = 0; k < nPar; k++) {
855 K[i][j] += C[i][k] * Si[k][j];
860 for (
int i = 0, k = 0; i < nPar; i++) {
861 for (
int j = 0; j <= i; j++, k++) {
863 for (
int l = 0; l < nPar; l++) {
864 kc += K[i][l] * C[l][j];
870 for (
int i = 0; i < nPar; i++) {
872 for (
int j = 0; j < nPar; j++) {
873 kd += K[i][j] * dzeta[j];
886 double chi2Time = 0.;
887 for (
int i = 0; i < nPar; i++) {
889 for (
int j = 0; j < nPar; j++) {
890 SiDzeta += Si[i][j] * dzeta[j];
893 chi2 += dzeta[i] * SiDzeta;
896 chi2Time += dzeta[i] * SiDzeta;
@ kTrd2d
TRD-FASP Detector (FIXME)
Class for pixel hits in MUCH detector.
Data class for a reconstructed hit in the STS.
Data class for STS tracks.
Class for hits in TRD detector.
Common constant definitions for the Kalman Filter library.
Track fit utilities for the CA tracking based on the Kalman filter.
Generates beam ions for transport simulation.
int32_t GetStsTrackIndex() const
int32_t GetTofTrackIndex() const
int32_t GetMuchTrackIndex() const
void SetParamFirst(const FairTrackParam *parFirst)
int32_t GetTrdTrackIndex() const
void SetStsTrackIndex(int32_t iSts)
TClonesArray * fInputTofTracks
TClonesArray * fInputMuchTracks
cbm::algo::kf::TrackKalmanFilter< double > fFit
void SetElectronFlag(bool isElectron)
set electron flag (bremmstrallung will be applied)
TClonesArray * fInputMvdHits
bool CreateMvdStsTrack(Trajectory &kfTrack, int stsTrackIndex)
set the input data arrays
bool CreateGlobalTrack(Trajectory &kfTrack, int globalTrackIndex)
void SetMassHypothesis(double mass)
set particle mass
void FilterFirstMeasurement(const TrajectoryNode &n)
TClonesArray * fInputStsHits
bool FitTrajectory(CbmKfTrackFitter::Trajectory &t)
fit the track
bool Smooth(cbm::algo::kf::TrackParamD &t1, const cbm::algo::kf::TrackParamD &t2)
TClonesArray * fInputTrdHits
TClonesArray * fInputStsTracks
bool fSkipUnmeasuredCoordinates
TClonesArray * fInputMuchHits
void AddMaterialEffects(TrajectoryNode &n, const LinearizationAtNode &l, cbm::algo::kf::FitDirection direction)
TClonesArray * fInputGlobalTracks
TClonesArray * fInputTofHits
std::shared_ptr< const cbm::algo::kf::Setup< double > > fKfSetup
TClonesArray * fInputTrdTracks
void SetParticleHypothesis(int pid)
set particle hypothesis (mass and electron flag) via particle PDG
static CbmMuchTrackingInterface * Instance()
Gets pointer to the instance of the CbmMuchTrackingInterface.
static CbmMvdTrackingInterface * Instance()
Gets pointer to the instance of the CbmMvdTrackingInterface.
data class for a reconstructed 3-d hit in the STS
int32_t GetNofMvdHits() const
static CbmStsTrackingInterface * Instance()
Gets pointer to the instance of the CbmStsTrackingInterface class.
static CbmTofTrackingInterface * Instance()
Gets pointer to the instance of the CbmTofTrackingInterface.
virtual int32_t GetNofHits() const
data class for a reconstructed Energy-4D measurement in the TRD
static CbmTrdTrackingInterface * Instance()
Gets pointer to the instance of the CbmTrdTrackingInterface.
Magnetic field region, corresponding to a hit triplet.
static EFieldType fgOriginalFieldType
Global field type.
static FieldFn_t fgOriginalField
Global variable to store the fielf funciton (x,y,z)->(Bx,By,Bz)
A map of station thickness in units of radiation length (X0) to the specific point in XY plane.
void Extrapolate(DataT z, const kf::FieldRegion< DataT > &F)
void FilterXY(const kf::MeasurementXy< DataT > &m, bool skipUnmeasuredCoordinates=false)
filter the track with the XY measurement
kf::TrackParam< DataT > & Tr()
void MultipleScattering(DataT radThick, DataT tx0, DataT ty0, DataT qp0)
apply multiple scattering correction to the track with the given Qp0
void EnergyLossCorrection(DataT radThick, FitDirection direction)
void FilterTime(DataT t, DataT dt2, const DataTmask &m)
filter the track with the time measurement
void SetParticleMass(DataT mass)
set particle mass for the fit
void SetTrack(const kf::TrackParam< T > &t)
void SetChiSqTime(T v)
Sets Chi-square of time measurements.
T Vi() const
Gets inverse velocity [ns/cm].
const CovMatrix_t & GetCovMatrix() const
Gets covariance matrix.
T GetTy() const
Gets slope along y-axis.
T GetZ() const
Gets z position [cm].
void ResetErrors(T c00, T c11, T c22, T c33, T c44, T c55, T c66)
Resets variances of track parameters and chi2, ndf values.
T Tx() const
Gets slope along x-axis.
void SetChiSq(T v)
Sets Chi-square of track fit model.
T X() const
Gets x position [cm].
T GetTx() const
Gets slope along x-axis.
void SetNdf(T v)
Sets NDF of track fit model.
T GetNdfTime() const
Gets NDF of time measurements.
T GetQp() const
Gets charge over momentum [ec/GeV].
T Y() const
Gets y position [cm].
T GetChiSqTime() const
Gets Chi-square of time measurements.
T Qp() const
Gets charge over momentum [ec/GeV].
T GetNdf() const
Gets NDF of track fit model.
T Time() const
Gets time [ns].
T GetY() const
Gets y position [cm].
void SetNdfTime(T v)
Sets NDF of time measurements.
CovMatrix_t & CovMatrix()
Reference to covariance matrix.
T GetChiSq() const
Gets Chi-square of track fit model.
T Ty() const
Gets slope along y-axis.
T GetX() const
Gets x position [cm].
std::shared_ptr< const cbm::algo::kf::Setup< double > > GetSharedGeoSetup()
Gets a shared pointer to the geometry setup.
static TrackingSetupBuilder * Instance()
Instance access.
EDetectorID
Enumeration for the tracking detector subsystems in CBM-CA.
ECbmModuleId ToCbmModuleId(EDetectorID detID)
Conversion map from EDetectorID to ECbmModuleId.
constexpr auto SpeedOfLightInv
Inverse speed of light [ns/cm].
void SymInv(const double a[], const int n, double c[], double w[], int *nullty, int *ifault)
cbm::algo::kf::TrackParamD fParamUp
fitted track parameters upstream the node
cbm::algo::kf::TrackParamD fParamDn
fitted track parameters downstream the node
cbm::algo::kf::TrackParamD fParamUp
fitted track parameters upstream the node
double fZ
Z coordinate of the node.
bool fIsFitted
true if the track parameters at the node are fitted
cbm::algo::kf::MeasurementXy< double > fMxy
== Hit information ( if present )
int fHitIndex
hit index in the detector hit array
int fHitAddress
detector ID of the hit
ECbmModuleId fHitSystemId
== External references
cbm::algo::kf::TrackParamD fParamDn
fitted track parameters downstream the node
bool fIsXySet
== Flags etc
bool fIsRadThickFixed
true if the radiation thickness is fixed to the fRadThick value
cbm::algo::kf::MeasurementTime< double > fMt
time measurement at fZ
int fMaterialLayer
== Material information (if present)
bool fIsTimeSet
true if the time measurement is set
A trajectory to be fitted.
std::vector< TrajectoryNode > fNodes
nodes on the trajectory
bool fIsFitted
true if the trajectory is fitted