From 99d6505f4295c6d35a1da3eb5b52ce6c656f841b Mon Sep 17 00:00:00 2001 From: "s.zharko@gsi.de" <s.zharko@gsi.de> Date: Thu, 2 Nov 2023 14:11:53 +0100 Subject: [PATCH] CA QA: Track fit QA in track vertex --- reco/L1/catools/CaToolsMCTrack.cxx | 38 ++++++++++++++++- reco/L1/catools/CaToolsMCTrack.h | 3 ++ reco/L1/qa/CbmCaTrackFitQa.cxx | 29 +++++++------ reco/L1/qa/CbmCaTrackFitQa.h | 9 ++-- reco/L1/qa/CbmCaTrackTypeQa.cxx | 68 ++++++++++++++++++++++++------ reco/L1/qa/CbmCaTrackTypeQa.h | 6 +++ 6 files changed, 123 insertions(+), 30 deletions(-) diff --git a/reco/L1/catools/CaToolsMCTrack.cxx b/reco/L1/catools/CaToolsMCTrack.cxx index 36afa39172..abbf2aaf62 100644 --- a/reco/L1/catools/CaToolsMCTrack.cxx +++ b/reco/L1/catools/CaToolsMCTrack.cxx @@ -16,9 +16,9 @@ #include "CaToolsMCPoint.h" +using cbm::ca::tools::MCPoint; using cbm::ca::tools::MCTrack; - // --------------------------------------------------------------------------------------------------------------------- // void MCTrack::Clear() @@ -30,6 +30,42 @@ void MCTrack::Clear() ClearTouchTrackIndexes(); } +// --------------------------------------------------------------------------------------------------------------------- +// +MCPoint MCTrack::GetVertexPoint() const +{ + MCPoint point; + point.SetCharge(this->GetCharge()); + point.SetEventId(this->GetEventId()); + point.SetFileId(this->GetFileId()); + point.SetExternalId(-1); // not in the array + point.SetId(-1); // not in the array + point.SetStationId(-1); + point.SetMass(this->GetMass()); + point.SetMotherId(this->GetMotherId()); + point.SetPdgCode(this->GetPdgCode()); + point.SetPx(this->GetPx()); + point.SetPy(this->GetPy()); + point.SetPz(this->GetPz()); + point.SetPxIn(this->GetPx()); + point.SetPyIn(this->GetPy()); + point.SetPzIn(this->GetPz()); + point.SetPxOut(this->GetPx()); + point.SetPyOut(this->GetPy()); + point.SetPzOut(this->GetPz()); + point.SetX(this->GetStartX()); + point.SetY(this->GetStartY()); + point.SetZ(this->GetStartZ()); + point.SetXIn(this->GetStartX()); + point.SetYIn(this->GetStartY()); + point.SetZIn(this->GetStartZ()); + point.SetXOut(this->GetStartX()); + point.SetYOut(this->GetStartY()); + point.SetZOut(this->GetStartZ()); + point.SetTime(this->GetStartT()); + return point; +} + // --------------------------------------------------------------------------------------------------------------------- // void MCTrack::InitHitsInfo(const ca::Vector<CbmL1HitDebugInfo>& vHits) diff --git a/reco/L1/catools/CaToolsMCTrack.h b/reco/L1/catools/CaToolsMCTrack.h index 3ec771e864..aeda05ea67 100644 --- a/reco/L1/catools/CaToolsMCTrack.h +++ b/reco/L1/catools/CaToolsMCTrack.h @@ -211,6 +211,9 @@ namespace cbm::ca::tools /// Gets track slope along y-axis double GetTy() const { return fMom[1] / fMom[2]; } + /// \brief Creates an MC point from the track vertex + MCPoint GetVertexPoint() const; + /// Gets a reference to vector of reconstructed track indexes, not associated with this MC track but containing some /// hits, produced by this MC track const auto& GetTouchTrackIndexes() const { return fvTouchTrackIndexes; } diff --git a/reco/L1/qa/CbmCaTrackFitQa.cxx b/reco/L1/qa/CbmCaTrackFitQa.cxx index 97875b5c4b..fd8cbbe0ea 100644 --- a/reco/L1/qa/CbmCaTrackFitQa.cxx +++ b/reco/L1/qa/CbmCaTrackFitQa.cxx @@ -149,17 +149,24 @@ void TrackFitQa::Fill(const TrackParamV& trPar, const tools::MCPoint& mcPoint, b const TrackParamV& trParExtr = fitter.Tr(); // Track parameters extrapolated to given MC point // ** Time-independent measurements ** - FillResAndPull(ETrackParType::kX, trParExtr.GetX()[0], trParExtr.GetXError()[0], mcPoint.GetXOut(), weight); - FillResAndPull(ETrackParType::kY, trParExtr.GetY()[0], trParExtr.GetYError()[0], mcPoint.GetYOut(), weight); - FillResAndPull(ETrackParType::kTX, trParExtr.GetTx()[0], trParExtr.GetTxError()[0], mcPoint.GetTxOut(), weight); - FillResAndPull(ETrackParType::kTY, trParExtr.GetTy()[0], trParExtr.GetTyError()[0], mcPoint.GetTyOut(), weight); - FillResAndPull(ETrackParType::kQP, trParExtr.GetQp()[0], trParExtr.GetQpError()[0], mcPoint.GetQpOut(), weight); + FillResAndPull(ETrackParType::kX, trPar.GetX()[0], trParExtr.GetXError()[0], mcPoint.GetXOut()); + FillResAndPull(ETrackParType::kY, trPar.GetY()[0], trParExtr.GetYError()[0], mcPoint.GetYOut()); + FillResAndPull(ETrackParType::kTX, trPar.GetTx()[0], trParExtr.GetTxError()[0], mcPoint.GetTxOut()); + FillResAndPull(ETrackParType::kTY, trPar.GetTy()[0], trParExtr.GetTyError()[0], mcPoint.GetTyOut()); + FillResAndPull(ETrackParType::kQP, trPar.GetQp()[0], trParExtr.GetQpError()[0], mcPoint.GetQpOut()); - // TODO: in which point do we calculate MC parameters (central, entrance, exit)?? + // Momentum resolution double recoP = std::fabs(mcPoint.GetCharge() / trParExtr.GetQp()[0]); // reco mom. (with MC charge) double resP = recoP - mcPoint.GetPOut(); // residual of total momentum - double resPhi = trParExtr.GetPhi()[0] - mcPoint.GetPhiOut(); // residual of azimuthal angle - double resTheta = trParExtr.GetTheta()[0] - mcPoint.GetThetaOut(); // residual of polar angle + + // Phi resolution + double mcPhi = mcPoint.GetPhiOut(); + double recoTx = trPar.Tx()[0]; + double recoTy = trPar.Ty()[0]; + double resPhi = atan2(recoTx * cos(mcPhi) + recoTy * sin(mcPhi), -recoTx * cos(mcPhi) + recoTy * sin(mcPhi)); + + // Theta resolution + double resTheta = trPar.GetTheta()[0] - mcPoint.GetThetaOut(); // residual of polar angle resPhi = std::atan2(std::sin(resPhi), std::cos(resPhi)); // overflow over (-pi, pi] protection @@ -169,10 +176,8 @@ void TrackFitQa::Fill(const TrackParamV& trPar, const tools::MCPoint& mcPoint, b // ** Time-dependent measurements ** if (bTimeMeasured) { - FillResAndPull(ETrackParType::kTIME, trParExtr.GetTime()[0], trParExtr.GetTimeError()[0], mcPoint.GetTime(), - weight); - FillResAndPull(ETrackParType::kVI, trParExtr.GetVi()[0], trParExtr.GetViError()[0], mcPoint.GetInvSpeedOut(), - weight); + FillResAndPull(ETrackParType::kTIME, trPar.GetTime()[0], trPar.GetTimeError()[0], mcPoint.GetTime()); + FillResAndPull(ETrackParType::kVI, trPar.GetVi()[0], trPar.GetViError()[0], mcPoint.GetInvSpeedOut()); } } diff --git a/reco/L1/qa/CbmCaTrackFitQa.h b/reco/L1/qa/CbmCaTrackFitQa.h index 1491ee5537..270bbf8171 100644 --- a/reco/L1/qa/CbmCaTrackFitQa.h +++ b/reco/L1/qa/CbmCaTrackFitQa.h @@ -181,8 +181,7 @@ namespace cbm::ca /// @param recoVal Reconstructed error of quantity /// @param recoErr Error of quantity /// @param trueVal True value of quantity - /// @param weight Weight - void FillResAndPull(ETrackParType type, double recoVal, double recoErr, double trueVal, double w); + void FillResAndPull(ETrackParType type, double recoVal, double recoErr, double trueVal); TrackParArray_t<TH1F*> fvphResiduals = {{0}}; ///< Residuals for different track parameters TrackParArray_t<TH1F*> fvphPulls = {{0}}; ///< Pulls for different track parameters @@ -209,13 +208,13 @@ namespace cbm::ca // --------------------------------------------------------------------------------------------------------------------- // TODO: Test this function for performance penalties - inline void TrackFitQa::FillResAndPull(ETrackParType type, double recoVal, double recoErr, double trueVal, double w) + inline void TrackFitQa::FillResAndPull(ETrackParType type, double recoVal, double recoErr, double trueVal) { if (fvbParIgnored[type]) { return; } double res = recoVal - trueVal; double pull = res / recoErr; - fvphResiduals[type]->Fill(res, w); - fvphPulls[type]->Fill(pull, w); + fvphResiduals[type]->Fill(res); + fvphPulls[type]->Fill(pull); } } // namespace cbm::ca diff --git a/reco/L1/qa/CbmCaTrackTypeQa.cxx b/reco/L1/qa/CbmCaTrackTypeQa.cxx index de706d1e42..f5c9c09be1 100644 --- a/reco/L1/qa/CbmCaTrackTypeQa.cxx +++ b/reco/L1/qa/CbmCaTrackTypeQa.cxx @@ -14,6 +14,8 @@ #include "CaToolsMCData.h" +using cbm::algo::ca::FieldRegion; +using cbm::algo::ca::TrackFit; using cbm::ca::TrackTypeQa; using cbm::ca::tools::MCPoint; using cbm::ca::tools::MCTrack; @@ -172,6 +174,11 @@ void TrackTypeQa::Init() fpFitQaVertex->SetTitle("Vertex"); fpFitQaVertex->Init(); } + + // Track fitter + fTrackFit.SetDoFitVelocity(true); // TODO: set flag to the configuration + fTrackFit.SetMask(fmask::One()); + fFieldRegion.SetUseOriginalField(); } // --------------------------------------------------------------------------------------------------------------------- @@ -211,21 +218,58 @@ void TrackTypeQa::FillRecoTrack(int iTrkReco, double weight) bool isTimeFitted = (nTimeMeasurements > 1); // ** First hit ** - int iHfst = recoTrack.GetFirstHitIndex(); - int iPfst = (*fpvHits)[iHfst].GetBestMcPointId(); - if (iPfst > -1) { - const auto& mcPoint = fpMCData->GetPoint(iPfst); - TrackParamV trPar(recoTrack); - fpFitQaFirstHit->Fill(trPar, mcPoint, isTimeFitted, weight); + fTrackFit.SetParticleMass(mcTrack.GetMass()); + { + int iHfst = recoTrack.GetFirstHitIndex(); + int iPfst = (*fpvHits)[iHfst].GetBestMcPointId(); + if (iPfst > -1) { + const auto& mcPoint = fpMCData->GetPoint(iPfst); + TrackParamV trPar(recoTrack); + fTrackFit.SetTrack(trPar); + fTrackFit.Extrapolate(mcPoint.GetZOut(), fFieldRegion); + fpFitQaFirstHit->Fill(fTrackFit.Tr(), mcPoint, isTimeFitted); + } } // ** Last hit ** - int iHlst = recoTrack.GetLastHitIndex(); - int iPlst = (*fpvHits)[iHlst].GetBestMcPointId(); - if (iPlst > -1) { - const auto& mcPoint = fpMCData->GetPoint(iPlst); - TrackParamV trPar(recoTrack.TLast); - fpFitQaLastHit->Fill(trPar, mcPoint, isTimeFitted, weight); + { + int iHlst = recoTrack.GetLastHitIndex(); + int iPlst = (*fpvHits)[iHlst].GetBestMcPointId(); + if (iPlst > -1) { + const auto& mcPoint = fpMCData->GetPoint(iPlst); + TrackParamV trPar(recoTrack.TLast); + fTrackFit.SetTrack(trPar); + fTrackFit.Extrapolate(mcPoint.GetZOut(), fFieldRegion); + fpFitQaLastHit->Fill(trPar, mcPoint, isTimeFitted); + } + } + + // ** Vertex ** + { + // Create an MC point for track vertex + MCPoint mcTrkVertex = mcTrack.GetVertexPoint(); + TrackParamV trPar(recoTrack); + fTrackFit.SetTrack(trPar); + fTrackFit.Extrapolate(mcTrkVertex.GetZ(), fFieldRegion); + // Add material + int iStFst = (*fpvHits)[recoTrack.GetFirstHitIndex()].GetStationId(); + double dZ = mcTrkVertex.GetZ() - fpParameters->GetStation(iStFst).fZ[0]; + int direction = static_cast<int>(dZ / std::fabs(dZ)); + for (int iSt = iStFst; (iSt >= 0) && (iSt < fpParameters->GetNstationsActive()) + && (direction * (mcTrkVertex.GetZ() - fpParameters->GetStation(iSt).fZ[0]) > 0); + iSt += direction) { + fTrackFit.Extrapolate(fpParameters->GetStation(iSt).fZ, fFieldRegion); + auto radLength = fpParameters->GetMaterialThickness(iSt, fTrackFit.Tr().GetX(), fTrackFit.Tr().GetY()); + fTrackFit.MultipleScattering(radLength); + fTrackFit.EnergyLossCorrection(radLength, fvec::One()); + } + fTrackFit.Extrapolate(mcTrkVertex.GetZ(), fFieldRegion); + const TrackParamV& trParExtr = fTrackFit.Tr(); + if (mcTrkVertex.GetZ() == trParExtr.GetZ()[0]) { fpFitQaVertex->Fill(trParExtr, mcTrkVertex, isTimeFitted); } + else { + LOG(warn) << "iTrkReco = " << iTrkReco << ", mcTrkVertex = " << mcTrkVertex.GetZ() + << ", par = " << trParExtr.GetZ()[0]; + } } } } diff --git a/reco/L1/qa/CbmCaTrackTypeQa.h b/reco/L1/qa/CbmCaTrackTypeQa.h index 470cbb5a01..2e1a8de3bf 100644 --- a/reco/L1/qa/CbmCaTrackTypeQa.h +++ b/reco/L1/qa/CbmCaTrackTypeQa.h @@ -18,7 +18,9 @@ #include <map> #include <string> +#include "CaField.h" #include "CaParameters.h" +#include "CaTrackFit.h" // Forward declarations namespace cbm::ca::tools @@ -275,6 +277,9 @@ namespace cbm::ca TProfile* fph_stations_point = nullptr; ///< Average number of stations with MC point TProfile* fph_stations_hit = nullptr; ///< Average number of stations with hit + ca::TrackFit fTrackFit; ///< Track fitter + ca::FieldRegion fFieldRegion; ///< Magnetic field + int fCounterMC = 0; ///< Counter of MC tracks int fCounterClones = 0; ///< Counter of clone tracks int fCounterRecoTotal = 0; ///< Counter of reco tracks (total = reco + ghost + clones) @@ -291,6 +296,7 @@ namespace cbm::ca tools::MCData* fpMCData = nullptr; ///< Pointer to MC data object std::shared_ptr<ca::Parameters> fpParameters = nullptr; ///< Pointer to parameters object + // ** Cuts on tracks for a given track class ** /// Cut function on MC tracks -- GitLab