diff --git a/reco/L1/CbmL1.cxx b/reco/L1/CbmL1.cxx index 68e7d8df887c325c0582dd96387230b1af70397e..10863478a5c0bff9725438569bdeb70b7c2f0331 100644 --- a/reco/L1/CbmL1.cxx +++ b/reco/L1/CbmL1.cxx @@ -335,13 +335,11 @@ InitStatus CbmL1::Init() if (nullptr == fpStsPoints) LOG(fatal) << GetName() << ": No StsPoint data!"; } - if (!fUseTRD) { - fpTrdPoints = 0; - fpTrdHitMatches = 0; - } + fpTrdPoints = mcManager->InitBranch("TrdPoint"); + + if (!fUseTRD) { fpTrdHitMatches = 0; } else { fpTrdHitMatches = (TClonesArray*) fairManager->GetObject("TrdHitMatch"); - fpTrdPoints = mcManager->InitBranch("TrdPoint"); } if (!fUseMUCH) { @@ -349,7 +347,6 @@ InitStatus CbmL1::Init() fpMuchHitMatches = 0; } else { - fpMuchDigis = (TClonesArray*) fairManager->GetObject("MuchDigi"); fpMuchDigiMatches = (TClonesArray*) fairManager->GetObject("MuchDigiMatch"); fpMuchClusters = (TClonesArray*) fairManager->GetObject("MuchCluster"); @@ -357,12 +354,10 @@ InitStatus CbmL1::Init() fpMuchHitMatches = L1_DYNAMIC_CAST<TClonesArray*>(fairManager->GetObject("MuchPixelHitMatch")); } - if (!fUseTOF) { - fpTofPoints = 0; - fpTofHitMatches = 0; - } + fpTofPoints = mcManager->InitBranch("TofPoint"); + + if (!fUseTOF) { fpTofHitMatches = 0; } else { - fpTofPoints = mcManager->InitBranch("TofPoint"); fpTofHitMatches = static_cast<TClonesArray*>(fairManager->GetObject("TofHitMatch")); } } @@ -1040,18 +1035,19 @@ void CbmL1::Reconstruct(CbmEvent* event) for (L1Vector<L1Track>::iterator it = fpAlgo->fTracks.begin(); it != fpAlgo->fTracks.end(); it++) { CbmL1Track t; - for (int i = 0; i < 7; i++) - t.T[i] = it->TFirst[i]; - for (int i = 0; i < 21; i++) - t.C[i] = it->CFirst[i]; - for (int i = 0; i < 7; i++) + + for (int i = 0; i < L1TrackPar::kNparTr; i++) { + t.T[i] = it->TFirst[i]; t.TLast[i] = it->TLast[i]; - for (int i = 0; i < 21; i++) + t.Tpv[i] = it->Tpv[i]; + } + + for (int i = 0; i < L1TrackPar::kNparCov; i++) { + t.C[i] = it->CFirst[i]; t.CLast[i] = it->CLast[i]; - for (int k = 0; k < 7; k++) - t.Tpv[k] = it->Tpv[k]; - for (int k = 0; k < 21; k++) - t.Cpv[k] = it->Cpv[k]; + t.Cpv[i] = it->Cpv[i]; + } + t.chi2 = it->chi2; t.NDF = it->NDF; //t.T[4] = it->Momentum; diff --git a/reco/L1/CbmL1.h b/reco/L1/CbmL1.h index 7cf53c95b7ff63be02f29e42659677bc101da8b9..20995c11b8714546506c5ad27b26cfd5f6687ffe 100644 --- a/reco/L1/CbmL1.h +++ b/reco/L1/CbmL1.h @@ -420,6 +420,8 @@ private: /// \note Should be called only after CbmL1::Performance() void TrackFitPerformance(); + void FillFitHistos(L1TrackPar& tr, const CbmL1MCPoint& mc, bool isTimeFitted, TH1F* h[]); + /// Fills performance histograms void HistoPerformance(); @@ -485,7 +487,7 @@ public: L1InitManager fInitManager; ///< Tracking parameters data manager L1IODataManager fIODataManager; ///< Input-output data manager - bool fMissingHits = false; ///< Turns on several ad-hock settings for "mcbm_beam_2021_07_surveyed.100ev" setup + bool fMissingHits = false; ///< Turns on several ad-hock settings for "mcbm_beam_2021_07_surveyed.100ev" setup L1Algo::TrackingMode fTrackingMode = L1Algo::TrackingMode::kSts; ///< Tracking mode: kSts, kMcbm or kGlobal diff --git a/reco/L1/CbmL1Performance.cxx b/reco/L1/CbmL1Performance.cxx index 4b9f07235f4d614daa978fc493d2a41161692b19..5a2479c3227d94e65a9e6478dd5d6021ceb5ccfc 100644 --- a/reco/L1/CbmL1Performance.cxx +++ b/reco/L1/CbmL1Performance.cxx @@ -1077,8 +1077,8 @@ void CbmL1::HistoPerformance() // TODO: check if works correctly. Change vHitFa void CbmL1::TrackFitPerformance() { - const int Nh_fit = 14; - static TH1F *h_fit[Nh_fit], *h_fitL[Nh_fit], *h_fitSV[Nh_fit], *h_fitPV[Nh_fit], + const int Nh_fit = 17; + static TH1F *h_fit[Nh_fit], *h_fitL[Nh_fit], *h_fitSV[Nh_fit], *h_fitPV[Nh_fit], *h_fitTrd[Nh_fit], *h_fitTof[Nh_fit], *h_fit_chi2; //, *h_smoothed[12][Nh_fit]; static TH2F *PRes2D, *PRes2DPrim, *PRes2DSec; @@ -1104,6 +1104,8 @@ void CbmL1::TrackFitPerformance() L1Fit fit; fit.SetParticleMass(fpAlgo->GetDefaultParticleMass()); fit.SetMask(fmask::One()); + //fit.SetMaxExtrapolationStep(10.); + fit.SetDoFitVelocity(true); if (first_call) { first_call = 0; @@ -1139,12 +1141,8 @@ void CbmL1::TrackFitPerformance() Double_t l, r; } Table[Nh_fit] = {{"x", "Residual X [#mum]", 140, -40., 40.}, {"y", "Residual Y [#mum]", 100, -450., 450.}, - //{"y", "Residual Y [#mum]", 100, -45., 45.}, {"tx", "Residual Tx [mrad]", 100, -4., 4.}, - //{"tx", "Residual Tx [mrad]", 100, -7., 7.}, - //{"tx", "Residual Tx [mrad]", 100, -2.5, 2.5}, {"ty", "Residual Ty [mrad]", 100, -3.5, 3.5}, - //{"ty", "Residual Ty [mrad]", 100, -2.5, 2.5}, {"P", "Resolution P/Q [%]", 100, -15., 15.}, {"px", "Pull X [residual/estimated_error]", 100, -6., 6.}, {"py", "Pull Y [residual/estimated_error]", 100, -6., 6.}, @@ -1154,7 +1152,10 @@ void CbmL1::TrackFitPerformance() {"QPreco", "Reco Q/P ", 100, -10., 10.}, {"QPmc", "MC Q/P ", 100, -10., 10.}, {"time", "Residual Time [ns]", 100, -10., 10.}, - {"ptime", "Pull Time [residual/estimated_error]", 100, -10., 10.}}; + {"ptime", "Pull Time [residual/estimated_error]", 100, -10., 10.}, + {"vi", "Residual Vi [1/c]", 100, -4., 4.}, + {"pvi", "Pull Vi [residual/estimated_error]", 100, -10., 10.}, + {"distrVi", "Vi distribution [1/c]", 100, 0., 4.}}; if (L1Algo::kGlobal == fpAlgo->fTrackingMode) { Table[4].l = -1.; @@ -1176,15 +1177,18 @@ void CbmL1::TrackFitPerformance() //{"ty", "Residual Ty [mrad]", 100, -3., 3.}, {"ty", "Residual Ty [mrad]", 100, -2., 2.}, {"P", "Resolution P/Q [%]", 100, -15., 15.}, - {"px", "Pull X [residual/estimated_error]", 100, -6., 6.}, - {"py", "Pull Y [residual/estimated_error]", 100, -6., 6.}, - {"ptx", "Pull Tx [residual/estimated_error]", 100, -6., 6.}, - {"pty", "Pull Ty [residual/estimated_error]", 100, -6., 6.}, - {"pQP", "Pull Q/P [residual/estimated_error]", 100, -6., 6.}, + {"px", "Pull X [residual/estimated_error]", 100, -10., 10.}, + {"py", "Pull Y [residual/estimated_error]", 100, -10., 10.}, + {"ptx", "Pull Tx [residual/estimated_error]", 100, -10., 10.}, + {"pty", "Pull Ty [residual/estimated_error]", 100, -10., 10.}, + {"pQP", "Pull Q/P [residual/estimated_error]", 100, -10., 10.}, {"QPreco", "Reco Q/P ", 100, -10., 10.}, {"QPmc", "MC Q/P ", 100, -10., 10.}, - {"t", "Residual T [ns]", 100, -10., 10.}, - {"pt", "Pull T [residual/estimated_error]", 100, -6., 6.}}; + {"time", "Residual Time [ns]", 100, -10., 10.}, + {"ptime", "Pull Time [residual/estimated_error]", 100, -10., 10.}, + {"vi", "Residual Vi [1/c]", 100, -10., 10.}, + {"pvi", "Pull Vi [residual/estimated_error]", 100, -10., 10.}, + {"distrVi", "Vi distribution [1/c]", 100, -10., 10.}}; if (L1Algo::kGlobal == fpAlgo->fTrackingMode) { TableVertex[4].l = -1.; @@ -1206,6 +1210,26 @@ void CbmL1::TrackFitPerformance() sprintf(t, "Primary vertex point %s", TableVertex[i].title); h_fitPV[i] = new TH1F(n, t, TableVertex[i].n, TableVertex[i].l, TableVertex[i].r); + sprintf(n, "trd_%s", TableVertex[i].name); + sprintf(t, "Last Trd point %s", TableVertex[i].title); + if (i == 12) { h_fitTrd[i] = new TH1F(n, t, Table[i].n, -30., 30.); } + else if (i == 13) { + h_fitTrd[i] = new TH1F(n, t, Table[i].n, -5., 5.); + } + else { + h_fitTrd[i] = new TH1F(n, t, Table[i].n, Table[i].l, Table[i].r); + } + + sprintf(n, "tof_%s", TableVertex[i].name); + sprintf(t, "Last Tof point %s", TableVertex[i].title); + if (i == 12) { h_fitTof[i] = new TH1F(n, t, Table[i].n, -30., 30.); } + else if (i == 13) { + h_fitTof[i] = new TH1F(n, t, Table[i].n, -5., 5.); + } + else { + h_fitTof[i] = new TH1F(n, t, Table[i].n, Table[i].l, Table[i].r); + } + for (int j = 0; j < 12; j++) { sprintf(n, "smth_%s_sta_%i", Table[i].name, j); sprintf(t, "Station %i %s", j, Table[i].title); @@ -1221,7 +1245,16 @@ void CbmL1::TrackFitPerformance() if (it->IsGhost()) continue; - const int isTimeFitted = (fvHitStore[it->Hits.back()].iStation > fNMvdStations); + bool isTimeFitted = 0; + + { + int nTimeMeasurenments = 0; + for (unsigned int ih = 0; ih < it->Hits.size(); ih++) { + int ista = fvHitStore[it->Hits[ih]].iStation; + if (fpAlgo->GetParameters()->GetStation(ista).timeInfo) { nTimeMeasurenments++; } + } + isTimeFitted = (nTimeMeasurenments > 1); + } do { // first hit @@ -1239,12 +1272,9 @@ void CbmL1::TrackFitPerformance() const CbmL1MCPoint& mcP = fvMCPoints[imcPoint]; - fit.SetTrack(it->T, it->C); - const L1TrackPar& tr = fit.Tr(); - - L1FieldRegion fld _fvecalignment; - fld.SetUseOriginalField(); - fit.Extrapolate(mcP.zIn, fld); + L1TrackPar tr; + tr.copyFromArrays(it->T, it->C); + FillFitHistos(tr, mcP, isTimeFitted, h_fit); double dx = tr.x[0] - mcP.xIn; double dy = tr.y[0] - mcP.yIn; @@ -1252,11 +1282,6 @@ void CbmL1::TrackFitPerformance() // make dca distance negative for the half of the tracks to ease the gaussian fit and the rms calculation if (mcTrack.ID % 2) dca = -dca; double pt = sqrt(mcP.px * mcP.px + mcP.py * mcP.py); - h_fit[0]->Fill(dx * 1.e4); - h_fit[1]->Fill(dy * 1.e4); - h_fit[2]->Fill((tr.tx[0] - mcP.pxIn / mcP.pzIn) * 1.e3); - h_fit[3]->Fill((tr.ty[0] - mcP.pyIn / mcP.pzIn) * 1.e3); - double dP = (fabs(1. / tr.qp[0]) - mcP.p) / mcP.p; PRes2D->Fill(mcP.p, 100. * dP); @@ -1283,88 +1308,23 @@ void CbmL1::TrackFitPerformance() else { PRes2DSec->Fill(mcP.p, 100. * dP); } - - if (std::isfinite(tr.C00[0]) && tr.C00[0] > 0) h_fit[5]->Fill((tr.x[0] - mcP.xIn) / sqrt(tr.C00[0])); - if (std::isfinite(tr.C11[0]) && tr.C11[0] > 0) h_fit[6]->Fill((tr.y[0] - mcP.yIn) / sqrt(tr.C11[0])); - if (std::isfinite(tr.C22[0]) && tr.C22[0] > 0) h_fit[7]->Fill((tr.tx[0] - mcP.pxIn / mcP.pzIn) / sqrt(tr.C22[0])); - if (std::isfinite(tr.C33[0]) && tr.C33[0] > 0) h_fit[8]->Fill((tr.ty[0] - mcP.pyIn / mcP.pzIn) / sqrt(tr.C33[0])); - if (std::isfinite(tr.C44[0]) && tr.C44[0] > 0) h_fit[9]->Fill((tr.qp[0] - mcP.q / mcP.p) / sqrt(tr.C44[0])); - h_fit[10]->Fill(tr.qp[0]); - h_fit[11]->Fill(mcP.q / mcP.p); - if (isTimeFitted) { - h_fit[12]->Fill(tr.t[0] - mcP.time); - if (std::isfinite(tr.C55[0]) && tr.C55[0] > 0.) { h_fit[13]->Fill((tr.t[0] - mcP.time) / sqrt(tr.C55[0])); } - } } while (0); - { // last hit + { // last hit + int iMC = fvHitPointIndexes[it->Hits.back()]; // TODO2: adapt to linking if (iMC < 0) continue; - -#define L1FSTPARAMEXTRAPOLATE -#ifdef L1FSTPARAMEXTRAPOLATE - - const int last_station = fvHitStore[it->Hits.back()].iStation; - - CbmL1MCTrack mc = *(it->GetMCTracks()[0]); - - L1FieldRegion fld _fvecalignment; - fld.SetUseOriginalField(); - - fit.SetTrack(it->TLast, it->CLast); - const L1TrackPar& tr = fit.Tr(); - CbmL1MCPoint& mcP = fvMCPoints[iMC]; - fit.Extrapolate(mcP.zOut, fld); - - h_fitL[0]->Fill((tr.x[0] - mcP.xOut) * 1.e4); - h_fitL[1]->Fill((tr.y[0] - mcP.yOut) * 1.e4); - h_fitL[2]->Fill((tr.tx[0] - mcP.pxOut / mcP.pzOut) * 1.e3); - h_fitL[3]->Fill((tr.ty[0] - mcP.pyOut / mcP.pzOut) * 1.e3); - h_fitL[4]->Fill(100. * (fabs(1. / tr.qp[0]) / mcP.p - 1.)); - if (last_station > fNMvdStations) h_fitL[12]->Fill(tr.t[0] - mcP.time); - - - if (std::isfinite(tr.C00[0]) && tr.C00[0] > 0) h_fitL[5]->Fill((tr.x[0] - mcP.xOut) / sqrt(tr.C00[0])); - if (std::isfinite(tr.C11[0]) && tr.C11[0] > 0) h_fitL[6]->Fill((tr.y[0] - mcP.yOut) / sqrt(tr.C11[0])); - if (std::isfinite(tr.C22[0]) && tr.C22[0] > 0) - h_fitL[7]->Fill((tr.tx[0] - mcP.pxOut / mcP.pzOut) / sqrt(tr.C22[0])); - if (std::isfinite(tr.C33[0]) && tr.C33[0] > 0) - h_fitL[8]->Fill((tr.ty[0] - mcP.pyOut / mcP.pzOut) / sqrt(tr.C33[0])); - if (std::isfinite(tr.C44[0]) && tr.C44[0] > 0) h_fitL[9]->Fill((tr.qp[0] - mcP.q / mcP.p) / sqrt(tr.C44[0])); - h_fitL[10]->Fill(tr.qp[0]); - h_fitL[11]->Fill(mcP.q / mcP.p); - if (last_station > fNMvdStations) - if (std::isfinite(tr.C55[0]) && tr.C55[0] > 0) h_fitL[13]->Fill((tr.t[0] - mcP.time) / sqrt(tr.C55[0])); -#else - CbmL1MCPoint& mc = fvMCPoints[iMC]; - - h_fitL[0]->Fill((it->TLast[0] - mc.x) * 1.e4); - h_fitL[1]->Fill((it->TLast[1] - mc.y) * 1.e4); - h_fitL[2]->Fill((it->TLast[2] - mc.px / mc.pz) * 1.e3); - h_fitL[3]->Fill((it->TLast[3] - mc.py / mc.pz) * 1.e3); - h_fitL[4]->Fill(100. * (fabs(1. / it->TLast[4]) / mc.p - 1.)); - if (std::isfinite(it->CLast[0]) && it->CLast[0] > 0) h_fitL[5]->Fill((it->TLast[0] - mc.x) / sqrt(it->CLast[0])); - if (std::isfinite(it->CLast[2]) && it->CLast[2] > 0) h_fitL[6]->Fill((it->TLast[1] - mc.y) / sqrt(it->CLast[2])); - if (std::isfinite(it->CLast[5]) && it->CLast[5] > 0) - h_fitL[7]->Fill((it->TLast[2] - mc.px / mc.pz) / sqrt(it->CLast[5])); - if (std::isfinite(it->CLast[9]) && it->CLast[9] > 0) - h_fitL[8]->Fill((it->TLast[3] - mc.py / mc.pz) / sqrt(it->CLast[9])); - if (std::isfinite(it->CLast[14]) && it->CLast[14] > 0) - h_fitL[9]->Fill((it->TLast[4] - mc.q / mc.p) / sqrt(it->CLast[14])); - h_fitL[10]->Fill(it->TLast[4]); - h_fitL[11]->Fill(mc.q / mc.p); - h_fitL[12]->Fill(it->TLast[6] - mc.time); - if (std::isfinite(it->CLast[20]) && it->CLast[20] > 0) - h_fitL[13]->Fill((it->TLast[6] - mc.time) / sqrt(it->CLast[20])); - -#endif + L1TrackPar tr; + tr.copyFromArrays(it->TLast, it->CLast); + FillFitHistos(tr, mcP, isTimeFitted, h_fitL); } { // vertex CbmL1MCTrack mc = *(it->GetMCTracks()[0]); fit.SetTrack(it->T, it->C); + const L1TrackPar& tr = fit.Tr(); // if (mc.mother_ID != -1) { // secondary @@ -1414,13 +1374,17 @@ void CbmL1::TrackFitPerformance() if (std::isfinite(tr.C44[0]) && tr.C44[0] > 0) h_fitSV[9]->Fill((tr.qp[0] - mc.q / mc.p) / sqrt(tr.C44[0])); h_fitSV[10]->Fill(tr.qp[0]); h_fitSV[11]->Fill(mc.q / mc.p); - h_fitSV[12]->Fill(tr.t[0] - mc.time); - if (std::isfinite(tr.C55[0]) && tr.C55[0] > 0) h_fitSV[13]->Fill((tr.t[0] - mc.time) / sqrt(tr.C55[0])); + if (isTimeFitted) { + h_fitSV[12]->Fill(tr.t[0] - mc.time); + if (std::isfinite(tr.C55[0]) && tr.C55[0] > 0.) { h_fitSV[13]->Fill((tr.t[0] - mc.time) / sqrt(tr.C55[0])); } + double dvi = tr.vi[0] - sqrt(1. + mc.mass * mc.mass / mc.p / mc.p) * L1TrackPar::kClightNsInv; + h_fitSV[14]->Fill(dvi * L1TrackPar::kClightNs); + if (std::isfinite(tr.C66[0]) && tr.C66[0] > 0.) { h_fitSV[15]->Fill(dvi / sqrt(tr.C66[0])); } + h_fitSV[16]->Fill(tr.vi[0] * L1TrackPar::kClightNs); + } } else { // primary -#define L1EXTRAPOLATE -#ifdef L1EXTRAPOLATE { // extrapolate to vertex L1FieldRegion fld _fvecalignment; fld.SetUseOriginalField(); @@ -1479,51 +1443,110 @@ void CbmL1::TrackFitPerformance() if (std::isfinite(tr.C44[0]) && tr.C44[0] > 0) h_fitPV[9]->Fill((mc.q / mc.p - tr.qp[0]) / sqrt(tr.C44[0])); h_fitPV[10]->Fill(tr.qp[0]); h_fitPV[11]->Fill(mc.q / mc.p); - h_fitPV[12]->Fill(mc.time - tr.t[0]); - if (std::isfinite(tr.C55[0]) && tr.C55[0] > 0) h_fitPV[13]->Fill((mc.time - tr.t[0]) / sqrt(tr.C55[0])); -#else - FairTrackParam fTP; - - CbmKFMath::CopyTC2TrackParam(&fTP, it->T, it->C); + if (isTimeFitted) { + h_fitPV[12]->Fill(tr.t[0] - mc.time); + if (std::isfinite(tr.C55[0]) && tr.C55[0] > 0.) { h_fitPV[13]->Fill((tr.t[0] - mc.time) / sqrt(tr.C55[0])); } + double dvi = tr.vi[0] - sqrt(1. + mc.mass * mc.mass / mc.p / mc.p) * L1TrackPar::kClightNsInv; + h_fitPV[14]->Fill(dvi * L1TrackPar::kClightNs); + if (std::isfinite(tr.C66[0]) && tr.C66[0] > 0.) { h_fitPV[15]->Fill(dvi / sqrt(tr.C66[0])); } + h_fitPV[16]->Fill(tr.vi[0] * L1TrackPar::kClightNs); + } + } + } - CbmKFTrack kfTr; - kfTr.SetTrackParam(fTP); + h_fit_chi2->Fill(it->chi2 / it->NDF); - kfTr.Extrapolate(mc.z); - CbmL1Track it2; - for (int ipar = 0; ipar < 6; ipar++) - it2.T[ipar] = kfTr.GetTrack()[ipar]; - for (int ipar = 0; ipar < 15; ipar++) - it2.C[ipar] = kfTr.GetCovMatrix()[ipar]; + // last TRD point + do { + if (!fpTrdPoints) break; + const CbmL1MCTrack& mcTrack = *(it->GetMCTracks()[0]); + int nTrdPoints = fpTrdPoints->Size(mcTrack.iFile, mcTrack.iEvent); + int lastP = -1; + double lastZ = -1.e8; + for (int iPoint = 0; iPoint < nTrdPoints; iPoint++) { + const CbmTrdPoint* pt = dynamic_cast<CbmTrdPoint*>(fpTrdPoints->Get(mcTrack.iFile, mcTrack.iEvent, iPoint)); + if (!pt) { continue; } + if (pt->GetTrackID() != mcTrack.ID) { continue; } + if (lastP < 0 || lastZ < pt->GetZ()) { + lastP = iPoint; + lastZ = pt->GetZ(); + } + } + CbmL1MCPoint mcP; + if (CbmL1::ReadMCPoint(&mcP, lastP, mcTrack.iFile, mcTrack.iEvent, 3)) { break; } + L1TrackPar tr; + tr.copyFromArrays(it->TLast, it->CLast); + FillFitHistos(tr, mcP, isTimeFitted, h_fitTrd); + } while (0); // Trd point - // calculate pulls - // h_fitPV[0]->Fill( (mc.x-it2.T[0]) *1.e4); - // h_fitPV[1]->Fill( (mc.y-it2.T[1]) *1.e4); - h_fitPV[0]->Fill((mc.x - it2.T[0])); - h_fitPV[1]->Fill((mc.y - it2.T[1])); - h_fitPV[2]->Fill((mc.px / mc.pz - it2.T[2]) * 1.e3); - h_fitPV[3]->Fill((mc.py / mc.pz - it2.T[3]) * 1.e3); - h_fitPV[4]->Fill(100. * (it2.T[4] / mc.q * mc.p - 1.)); - if (std::isfinite(it2.C[0]) && it2.C[0] > 0) h_fitPV[5]->Fill((mc.x - it2.T[0]) / sqrt(it2.C[0])); - if (std::isfinite(it2.C[2]) && it2.C[2] > 0) h_fitPV[6]->Fill((mc.y - it2.T[1]) / sqrt(it2.C[2])); - if (std::isfinite(it2.C[5]) && it2.C[5] > 0) h_fitPV[7]->Fill((mc.px / mc.pz - it2.T[2]) / sqrt(it2.C[5])); - if (std::isfinite(it2.C[9]) && it2.C[9] > 0) h_fitPV[8]->Fill((mc.py / mc.pz - it2.T[3]) / sqrt(it2.C[9])); - if (std::isfinite(it2.C[14]) && it2.C[14] > 0) h_fitPV[9]->Fill((mc.q / mc.p - it2.T[4]) / sqrt(it2.C[14])); - h_fitPV[10]->Fill(it2.T[4]); - h_fitPV[11]->Fill(mc.q / mc.p); - h_fitPV[12]->Fill(mc.time - it2.T[6]); - if (std::isfinite(it2.C[20]) && it2.C[20] > 0) h_fitPV[13]->Fill((mc.time - it2.T[6]) / sqrt(it2.C[20])); -#endif // L1EXTRAPOLATE + // last TOF point + do { + if (!fpTofPoints) break; + const CbmL1MCTrack& mcTrack = *(it->GetMCTracks()[0]); + int nTofPoints = fpTofPoints->Size(mcTrack.iFile, mcTrack.iEvent); + int lastP = -1; + double lastZ = -1.e8; + for (int iPoint = 0; iPoint < nTofPoints; iPoint++) { + const CbmTofPoint* pt = dynamic_cast<CbmTofPoint*>(fpTofPoints->Get(mcTrack.iFile, mcTrack.iEvent, iPoint)); + if (!pt) { continue; } + if (pt->GetTrackID() != mcTrack.ID) { continue; } + if (lastP < 0 || lastZ < pt->GetZ()) { + lastP = iPoint; + lastZ = pt->GetZ(); + } } - } + CbmL1MCPoint mcP; + if (CbmL1::ReadMCPoint(&mcP, lastP, mcTrack.iFile, mcTrack.iEvent, 4)) { break; } + L1TrackPar tr; + tr.copyFromArrays(it->TLast, it->CLast); + FillFitHistos(tr, mcP, isTimeFitted, h_fitTof); + } while (0); // tof point - h_fit_chi2->Fill(it->chi2 / it->NDF); - } + } // reco track } // void CbmL1::TrackFitPerformance() +void CbmL1::FillFitHistos(L1TrackPar& track, const CbmL1MCPoint& mcP, bool isTimeFitted, TH1F* h[]) +{ + L1Fit fit; + fit.SetParticleMass(fpAlgo->GetDefaultParticleMass()); + fit.SetMask(fmask::One()); + //fit.SetMaxExtrapolationStep(10.); + fit.SetDoFitVelocity(true); + fit.SetTrack(track); + L1FieldRegion fld _fvecalignment; + fld.SetUseOriginalField(); + fit.Extrapolate(mcP.zOut, fld); + track = fit.Tr(); + + const L1TrackPar& tr = track; + + h[0]->Fill((tr.x[0] - mcP.xOut) * 1.e4); + h[1]->Fill((tr.y[0] - mcP.yOut) * 1.e4); + h[2]->Fill((tr.tx[0] - mcP.pxOut / mcP.pzOut) * 1.e3); + h[3]->Fill((tr.ty[0] - mcP.pyOut / mcP.pzOut) * 1.e3); + h[4]->Fill(100. * (fabs(1. / tr.qp[0]) / mcP.p - 1.)); + + if (std::isfinite(tr.C00[0]) && tr.C00[0] > 0) h[5]->Fill((tr.x[0] - mcP.xOut) / sqrt(tr.C00[0])); + if (std::isfinite(tr.C11[0]) && tr.C11[0] > 0) h[6]->Fill((tr.y[0] - mcP.yOut) / sqrt(tr.C11[0])); + if (std::isfinite(tr.C22[0]) && tr.C22[0] > 0) h[7]->Fill((tr.tx[0] - mcP.pxOut / mcP.pzOut) / sqrt(tr.C22[0])); + if (std::isfinite(tr.C33[0]) && tr.C33[0] > 0) h[8]->Fill((tr.ty[0] - mcP.pyOut / mcP.pzOut) / sqrt(tr.C33[0])); + if (std::isfinite(tr.C44[0]) && tr.C44[0] > 0) h[9]->Fill((tr.qp[0] - mcP.q / mcP.p) / sqrt(tr.C44[0])); + h[10]->Fill(tr.qp[0]); + h[11]->Fill(mcP.q / mcP.p); + if (isTimeFitted) { + h[12]->Fill(tr.t[0] - mcP.time); + if (std::isfinite(tr.C55[0]) && tr.C55[0] > 0.) { h[13]->Fill((tr.t[0] - mcP.time) / sqrt(tr.C55[0])); } + double dvi = tr.vi[0] - sqrt(1. + mcP.mass * mcP.mass / mcP.p / mcP.p) * L1TrackPar::kClightNsInv; + h[14]->Fill(dvi * L1TrackPar::kClightNs); + if (std::isfinite(tr.C66[0]) && tr.C66[0] > 0.) { h[15]->Fill(dvi / sqrt(tr.C66[0])); } + h[16]->Fill(tr.vi[0] * L1TrackPar::kClightNs); + } +} + + void CbmL1::FieldApproxCheck() { TDirectory* curr = gDirectory; diff --git a/reco/L1/CbmL1ReadEvent.cxx b/reco/L1/CbmL1ReadEvent.cxx index 2dbc50b3089d2cd614eb939061890a38562ccc13..22a86e698267d1e03ae30a22cd016a2628bde890 100644 --- a/reco/L1/CbmL1ReadEvent.cxx +++ b/reco/L1/CbmL1ReadEvent.cxx @@ -88,7 +88,7 @@ struct TmpHit { double ty; ///< MC slopes of the mc point int iMC; ///< index of MCPoint in the fvMCPoints array double time = 0.; ///< time of the hit [ns] - double dt = 1.e10; ///< time error of the hit [ns] + double dt = 1.e4; ///< time error of the hit [ns] int Det; int id; ///< index of hit before hits sorting int track; @@ -1358,6 +1358,8 @@ void CbmL1::Fill_vMCTracks() auto header = dynamic_cast<FairMCEventHeader*>(fpMcEventHeader->Get(iFile, iEvent)); assert(header); + double eventTime = fpEventList->GetEventTime(iEvent, iFile); + Int_t nMCTrack = fpMCTracks->Size(iFile, iEvent); /* Loop over MC tracks */ for (Int_t iMCTrack = 0; iMCTrack < nMCTrack; iMCTrack++) { @@ -1385,7 +1387,7 @@ void CbmL1::Fill_vMCTracks() Int_t iTrack = fvMCTracks.size(); //or iMCTrack? CbmL1MCTrack T(mass, q, vr, vp, iTrack, mother_ID, pdg, processID); // CbmL1MCTrack T(mass, q, vr, vp, iMCTrack, mother_ID, pdg); - T.time = MCTrack->GetStartT(); + T.time = eventTime + MCTrack->GetStartT(); T.iFile = iFile; T.iEvent = iEvent; // signal: primary tracks, displaced from the primary vertex @@ -1474,9 +1476,9 @@ bool CbmL1::ReadMCPoint(CbmL1MCPoint* MC, int iPoint, int file, int event, int M if (!pt) return 1; if (!fLegacyEventMode) { - Double_t StartTime = fTimeSlice->GetStartTime(); // not used - Double_t EndTime = fTimeSlice->GetEndTime(); // not used - Double_t Time_MC_point = eventTime + pt->GetTime(); // not used + Double_t StartTime = fTimeSlice->GetStartTime(); // not used + Double_t EndTime = fTimeSlice->GetEndTime(); // not used + Double_t Time_MC_point = eventTime + pt->GetTime(); // not used if (StartTime > 0) if (Time_MC_point < StartTime) return 1; diff --git a/reco/L1/CbmL1Track.h b/reco/L1/CbmL1Track.h index 4286a905adb66e20960ef68cbc438764cf8a63d2..e5275831aa65903f7d64253ff4ca9231959db4ea 100644 --- a/reco/L1/CbmL1Track.h +++ b/reco/L1/CbmL1Track.h @@ -51,10 +51,10 @@ public: static bool comparePChi2(const CbmL1Track* a, const CbmL1Track* b) { return (a->chi2 < b->chi2); } - double Tpv[7], Cpv[21]; + double Tpv[L1TrackPar::kNparTr], Cpv[L1TrackPar::kNparCov]; - double TLast[7], CLast[21]; + double TLast[L1TrackPar::kNparTr], CLast[L1TrackPar::kNparCov]; vector<int> Hits; int nStations; int index; diff --git a/reco/L1/CbmL1TrackPar.h b/reco/L1/CbmL1TrackPar.h index d1d69306bc87d3fd9f9574c9cd59344718f34449..57fe79607bc74bd4bb512937114484cd34cbeecf 100644 --- a/reco/L1/CbmL1TrackPar.h +++ b/reco/L1/CbmL1TrackPar.h @@ -1,12 +1,14 @@ /* Copyright (C) 2006-2017 GSI Helmholtzzentrum fuer Schwerionenforschung, Darmstadt SPDX-License-Identifier: GPL-3.0-only - Authors: Denis Bertini [committer] */ + Authors: Sergey Gorbunov [committer] */ #ifndef CbmL1TrackPar_H #define CbmL1TrackPar_H #include "CbmKFTrackInterface.h" +#include "L1TrackPar.h" + struct CbmL1TrackPar : public CbmKFTrackInterface { public: CbmL1TrackPar() : chi2(0), NDF(0), mass(0), is_electron(0) {} @@ -17,7 +19,7 @@ public: double GetMass() { return mass; } bool IsElectron() { return is_electron; } - double T[7], C[21], chi2; + double T[L1TrackPar::kNparTr], C[L1TrackPar::kNparCov], chi2; int NDF; double mass; // mass hypothesis bool is_electron; diff --git a/reco/L1/L1Algo/L1BranchExtender.cxx b/reco/L1/L1Algo/L1BranchExtender.cxx index 00d60be0de2bf0ec1f6a6dd3cd1e6de48d1348fd..9aad594f2904d6aecad6c552b8db88cf604550aa 100644 --- a/reco/L1/L1Algo/L1BranchExtender.cxx +++ b/reco/L1/L1Algo/L1BranchExtender.cxx @@ -70,8 +70,8 @@ void L1Algo::BranchFitterFast(const L1Branch& t, L1TrackPar& Tout, const bool di fvec dzi = fvec(1.) / (z1 - z0); - T.x = x0; - T.y = y0; + T.x = x0; + T.y = y0; if (initParams) { T.tx = (x1 - x0) * dzi; T.ty = (y1 - y0) * dzi; @@ -242,7 +242,7 @@ void L1Algo::FindMoreHits(L1Branch& t, L1TrackPar& Tout, const bool dir, const L1Hit& hit = (*vHitsUnused)[globalInd]; - if (sta.timeInfo) { + if (sta.timeInfo && tr.nTimeMeasurements[0] > 0) { fscal dt = hit.t - tr.t[0]; if (dt * dt > (tr.C55[0] + hit.dt2) * 25) continue; } diff --git a/reco/L1/L1Algo/L1CloneMerger.cxx b/reco/L1/L1Algo/L1CloneMerger.cxx index 16a469c6d2615c02c57f08c9bfe70a096d718689..cc5fd275e9745dd0465ffccb2809cc0d76230688 100644 --- a/reco/L1/L1Algo/L1CloneMerger.cxx +++ b/reco/L1/L1Algo/L1CloneMerger.cxx @@ -114,7 +114,10 @@ void L1CloneMerger::Exec(L1Vector<L1Track>& extTracks, L1Vector<L1HitIndex_t>& e Tf.copyFromArrays(extTracks[jTr].TLast, extTracks[jTr].CLast); fitF.SetQp0(fitF.Tr().qp); - if (fabs(Tf.t[0] - Tb.t[0]) > 3 * sqrt(Tf.C55[0] + Tb.C55[0])) continue; + if (Tf.nTimeMeasurements[0] > 0 && Tb.nTimeMeasurements[0] > 0) { + if (fabs(Tf.t[0] - Tb.t[0]) > 3 * sqrt(Tf.C55[0] + Tb.C55[0])) continue; + } + unsigned short stam; frAlgo.GetParameters()->GetStation(staf).fieldSlice.GetFieldValue(Tf.x, Tf.y, fBf); diff --git a/reco/L1/L1Algo/L1Fit.cxx b/reco/L1/L1Algo/L1Fit.cxx index 3a99d903dbe6b6dd83d5cf418b5f1a23a9eaa174..8fe46a0534673e32b0b472161869f44ca4546da6 100644 --- a/reco/L1/L1Algo/L1Fit.cxx +++ b/reco/L1/L1Algo/L1Fit.cxx @@ -55,26 +55,32 @@ void L1Fit::Filter(const L1UMeasurementInfo& info, cnst& u, cnst& sigma2) fTr.vi -= F6 * zetawi; fTr.C00 -= F0 * F0 * wi; + fTr.C10 -= K1 * F0; fTr.C11 -= K1 * F1; + fTr.C20 -= K2 * F0; fTr.C21 -= K2 * F1; fTr.C22 -= K2 * F2; + fTr.C30 -= K3 * F0; fTr.C31 -= K3 * F1; fTr.C32 -= K3 * F2; fTr.C33 -= K3 * F3; + fTr.C40 -= K4 * F0; fTr.C41 -= K4 * F1; fTr.C42 -= K4 * F2; fTr.C43 -= K4 * F3; fTr.C44 -= K4 * F4; + fTr.C50 -= K5 * F0; fTr.C51 -= K5 * F1; fTr.C52 -= K5 * F2; fTr.C53 -= K5 * F3; fTr.C54 -= K5 * F4; fTr.C55 -= K5 * F5; + fTr.C60 -= K6 * F0; fTr.C61 -= K6 * F1; fTr.C62 -= K6 * F2; @@ -133,27 +139,35 @@ void L1Fit::FilterTime(cnst& t, cnst& dt2, cnst& timeInfo) fTr.t -= F5 * zetawi; fTr.vi -= F6 * zetawi; + fTr.nTimeMeasurements += w; + fTr.C00 -= F0 * F0 * wi; + fTr.C10 -= K1 * F0; fTr.C11 -= K1 * F1; + fTr.C20 -= K2 * F0; fTr.C21 -= K2 * F1; fTr.C22 -= K2 * F2; + fTr.C30 -= K3 * F0; fTr.C31 -= K3 * F1; fTr.C32 -= K3 * F2; fTr.C33 -= K3 * F3; + fTr.C40 -= K4 * F0; fTr.C41 -= K4 * F1; fTr.C42 -= K4 * F2; fTr.C43 -= K4 * F3; fTr.C44 -= K4 * F4; + fTr.C50 -= K5 * F0; fTr.C51 -= K5 * F1; fTr.C52 -= K5 * F2; fTr.C53 -= K5 * F3; fTr.C54 -= K5 * F4; fTr.C55 -= K5 * F5; + fTr.C60 -= K6 * F0; fTr.C61 -= K6 * F1; fTr.C62 -= K6 * F2; @@ -209,16 +223,22 @@ void L1Fit::FilterXY(const L1XYMeasurementInfo& info, cnst& x, cnst& y) K00 = F00 * S00 + F01 * S10; K01 = F00 * S10 + F01 * S11; + K10 = F10 * S00 + F11 * S10; K11 = F10 * S10 + F11 * S11; + K20 = F20 * S00 + F21 * S10; K21 = F20 * S10 + F21 * S11; + K30 = F30 * S00 + F31 * S10; K31 = F30 * S10 + F31 * S11; + K40 = F40 * S00 + F41 * S10; K41 = F40 * S10 + F41 * S11; + K50 = F50 * S00 + F51 * S10; K51 = F50 * S10 + F51 * S11; + K60 = F60 * S00 + F61 * S10; K61 = F60 * S10 + F61 * S11; @@ -347,6 +367,188 @@ void L1Fit::FilterExtrapolatedXY(cnst& x, cnst& y, const L1XYMeasurementInfo& in } +void L1Fit::MeasureVelocityWithQp() +{ + // measure velocity using measured qp + // assuming particle mass == fMass; + + cnst kClightNsInv = fvec(L1TrackPar::kClightNsInv); + + fvec zeta, HCH; + fvec F0, F1, F2, F3, F4, F5, F6; + fvec K1, K2, K3, K4, K5, K6; + + //FilterVi(sqrt(fvec(1.) + fMass2 * fQp0 * fQp0) * kClightNsInv); + //return; + + fvec vi0 = sqrt(fvec(1.) + fMass2 * fQp0 * fQp0) * kClightNsInv; + + fvec h = fMass2 * fQp0 / sqrt(fvec(1.) + fMass2 * fQp0 * fQp0) * kClightNsInv; + + zeta = vi0 + h * (fTr.qp - fQp0) - fTr.vi; + + fTr.vi = vi0; + + // H = (0,0,0,0, h,0, -1) + + // F = CH' + + F0 = h * fTr.C40 - fTr.C60; + F1 = h * fTr.C41 - fTr.C61; + F2 = h * fTr.C42 - fTr.C62; + F3 = h * fTr.C43 - fTr.C63; + F4 = h * fTr.C44 - fTr.C64; + F5 = h * fTr.C54 - fTr.C65; + F6 = h * fTr.C64 - fTr.C66; + + HCH = F4 * h - F6; + + fvec wi = fMaskF / HCH; + fvec zetawi = fMaskF * zeta / HCH; + fTr.chi2 += zeta * zeta * wi; + fTr.NDF += fMaskF; + + K1 = F1 * wi; + K2 = F2 * wi; + K3 = F3 * wi; + K4 = F4 * wi; + K5 = F5 * wi; + K6 = F6 * wi; + + fTr.x -= F0 * zetawi; + fTr.y -= F1 * zetawi; + fTr.tx -= F2 * zetawi; + fTr.ty -= F3 * zetawi; + fTr.qp -= F4 * zetawi; + fTr.t -= F5 * zetawi; + fTr.vi -= F6 * zetawi; + + fTr.C00 -= F0 * F0 * wi; + + fTr.C10 -= K1 * F0; + fTr.C11 -= K1 * F1; + + fTr.C20 -= K2 * F0; + fTr.C21 -= K2 * F1; + fTr.C22 -= K2 * F2; + + fTr.C30 -= K3 * F0; + fTr.C31 -= K3 * F1; + fTr.C32 -= K3 * F2; + fTr.C33 -= K3 * F3; + + fTr.C40 -= K4 * F0; + fTr.C41 -= K4 * F1; + fTr.C42 -= K4 * F2; + fTr.C43 -= K4 * F3; + fTr.C44 -= K4 * F4; + + fTr.C50 -= K5 * F0; + fTr.C51 -= K5 * F1; + fTr.C52 -= K5 * F2; + fTr.C53 -= K5 * F3; + fTr.C54 -= K5 * F4; + fTr.C55 -= K5 * F5; + + fTr.C60 -= K6 * F0; + fTr.C61 -= K6 * F1; + fTr.C62 -= K6 * F2; + fTr.C63 -= K6 * F3; + fTr.C64 -= K6 * F4; + fTr.C65 -= K6 * F5; + fTr.C66 -= K6 * F6; + + // fTr.vi( fTr.vi < fvec(L1TrackPar::kClightNsInv) ) = fvec(L1TrackPar::kClightNsInv); +} + +void L1Fit::FilterVi(fvec vi) +{ + // set inverse velocity to vi + + fvec zeta, HCH; + fvec F0, F1, F2, F3, F4, F5, F6; + fvec K1, K2, K3, K4, K5, K6; + + zeta = fTr.vi - vi; + + // H = (0,0,0,0, 0, 0, 1) + + // F = CH' + + F0 = fTr.C60; + F1 = fTr.C61; + F2 = fTr.C62; + F3 = fTr.C63; + F4 = fTr.C64; + F5 = fTr.C65; + F6 = fTr.C66; + + HCH = F6; + + fvec wi = fMaskF / HCH; + fvec zetawi = fMaskF * zeta / HCH; + fTr.chi2 += zeta * zeta * wi; + fTr.NDF += fMaskF; + + K1 = F1 * wi; + K2 = F2 * wi; + K3 = F3 * wi; + K4 = F4 * wi; + K5 = F5 * wi; + K6 = F6 * wi; + + fTr.x -= F0 * zetawi; + fTr.y -= F1 * zetawi; + fTr.tx -= F2 * zetawi; + fTr.ty -= F3 * zetawi; + fTr.qp -= F4 * zetawi; + fTr.t -= F5 * zetawi; + // fTr.vi -= F6 * zetawi; + fTr.vi = vi; + + fTr.C00 -= F0 * F0 * wi; + + fTr.C10 -= K1 * F0; + fTr.C11 -= K1 * F1; + + fTr.C20 -= K2 * F0; + fTr.C21 -= K2 * F1; + fTr.C22 -= K2 * F2; + + fTr.C30 -= K3 * F0; + fTr.C31 -= K3 * F1; + fTr.C32 -= K3 * F2; + fTr.C33 -= K3 * F3; + + fTr.C40 -= K4 * F0; + fTr.C41 -= K4 * F1; + fTr.C42 -= K4 * F2; + fTr.C43 -= K4 * F3; + fTr.C44 -= K4 * F4; + + fTr.C50 -= K5 * F0; + fTr.C51 -= K5 * F1; + fTr.C52 -= K5 * F2; + fTr.C53 -= K5 * F3; + fTr.C54 -= K5 * F4; + fTr.C55 -= K5 * F5; + + //fTr.C60 -= K6 * F0; + //fTr.C61 -= K6 * F1; + //fTr.C62 -= K6 * F2; + //fTr.C63 -= K6 * F3; + //fTr.C64 -= K6 * F4; + //fTr.C65 -= K6 * F5; + //fTr.C66 -= K6 * F6; + fTr.C60 = fvec(0.); + fTr.C61 = fvec(0.); + fTr.C62 = fvec(0.); + fTr.C63 = fvec(0.); + fTr.C64 = fvec(0.); + fTr.C65 = fvec(0.); + fTr.C66 = fvec(1.e-8); // just for a case.. +} + void L1Fit::Extrapolate // extrapolates track parameters and returns jacobian for extrapolation of CovMatrix (cnst& z_out, // extrapolate to this z position const L1FieldRegion& F) @@ -355,7 +557,7 @@ void L1Fit::Extrapolate // extrapolates track parameters and returns jacobian f fvec sgn = iif(fTr.z < z_out, fvec(1.), fvec(-1.)); while (!(fMaskF * abs(z_out - fTr.z) <= fvec(1.e-6)).isFull()) { - fvec zNew = fTr.z + sgn * fvec(50.); // max. 50 cm step + fvec zNew = fTr.z + sgn * fMaxExtraplationStep; // max. 50 cm step zNew(sgn * (z_out - zNew) <= fvec(0.)) = z_out; ExtrapolateStepFull(zNew, F); } @@ -363,7 +565,7 @@ void L1Fit::Extrapolate // extrapolates track parameters and returns jacobian f void L1Fit::ExtrapolateStepFull // extrapolates track parameters and returns jacobian for extrapolation of CovMatrix (cnst& zOut, // extrapolate to this z position - const L1FieldRegion& F) + const L1FieldRegion& Field) { // use Q/p linearisation at fQp0 // implementation of the Runge-Kutta method without optimization @@ -406,235 +608,130 @@ void L1Fit::ExtrapolateStepFull // extrapolates track parameters and returns ja cnst zMasked = iif(fMask, zOut, fTr.z); - fvec qp_in = fTr.qp; - cnst h = (zMasked - fTr.z); - - cnst a[4] = {0., h * fvec(0.5), h * fvec(0.5), h}; - cnst c[4] = {h / fvec(6.), h / fvec(3.), h / fvec(3.), h / fvec(6.)}; + cnst h = (zMasked - fTr.z); - fvec f0[4] = {{0.}}; // ( dx/dz )[step] - fvec f1[4] = {{0.}}; // ( dy/dz )[step] - fvec f2[4] = {{0.}}; // ( dtx/dz )[step] - fvec f3[4] = {{0.}}; // ( dty/dz )[step] - fvec f4[4] = {{0.}}; // ( dqp/dz )[step] - fvec f5[4] = {{0.}}; // ( dt/dz )[step] - fvec f6[4] = {{0.}}; // ( dvi/dz )[step] + cnst stepDz[5] = {0., 0., h * fvec(0.5), h * fvec(0.5), h}; - //fvec df0[4][7] = {{0.}}; // df0[step] / d {x,y,tx,ty,qp,t,vi} - //fvec df1[4][7] = {{0.}}; // df1[step] / d {x,y,tx,ty,qp,t,vi} - fvec df2[4][7] = {{0.}}; // df2[step] / d {x,y,tx,ty,qp,t,vi} - fvec df3[4][7] = {{0.}}; // df3[step] / d {x,y,tx,ty,qp,t,vi} - //fvec df4[4][7] = {{0.}}; // df4[step] / d {x,y,tx,ty,qp,t,vi} - fvec df5[4][7] = {{0.}}; // df5[step] / d {x,y,tx,ty,qp,t,vi} - //fvec df6[4][7] = {{0.}}; // df6[step] / d {x,y,tx,ty,qp,t,vi} + fvec f[5][7] = {{0.}}; // ( d*/dz ) [step] + fvec F[5][7][7] = {{0.}}; // ( d *new [step] / d *old ) - fvec k[5][7] = {{0.}}; // [ step-1 ] [ {x,y,tx,ty,qp,t,vi} ] - - // Runge-Kutta steps for track parameters + // Runge-Kutta steps // - { - fvec r0[7] = {fTr.x, fTr.y, fTr.tx, fTr.ty, fTr.qp, fTr.t, fTr.vi}; - - for (int step = 0; step < 4; ++step) { - fvec z = fTr.z + a[step]; - fvec r[7]; - for (int i = 0; i < 7; ++i) { - r[i] = r0[i] + a[step] * k[step][i]; - } - - fvec B[3]; - cnst& Bx = B[0]; - cnst& By = B[1]; - cnst& Bz = B[2]; - - F.Get(r[0], r[1], z, B); - fvec tx = r[2]; - fvec ty = r[3]; - fvec tx2 = tx * tx; - fvec ty2 = ty * ty; - fvec txty = tx * ty; - fvec L2 = fvec(1.) + tx2 + ty2; - fvec L2i = fvec(1.) / L2; - fvec L = sqrt(L2); - fvec cL = c_light * L; - fvec cLqp0 = cL * fQp0; - - f0[step] = tx; - f1[step] = ty; - - fvec f2tmp = (txty * Bx + ty * Bz) - (fvec(1.) + tx2) * By; - f2[step] = cLqp0 * f2tmp; - df2[step][2] = cLqp0 * (tx * f2tmp * L2i + ty * Bx - fvec(2.) * tx * By); - df2[step][3] = cLqp0 * (ty * f2tmp * L2i + tx * Bx + Bz); - df2[step][4] = cL * f2tmp; - - fvec f3tmp = -txty * By - tx * Bz + (fvec(1.) + ty2) * Bx; - f3[step] = cLqp0 * f3tmp; - df3[step][2] = cLqp0 * (tx * f3tmp * L2i - ty * By - Bz); - df3[step][3] = cLqp0 * (ty * f3tmp * L2i + fvec(2.) * ty * Bx - tx * By); - df3[step][4] = cL * f3tmp; - - fvec vi = r[6]; - fvec m2 = fMass2; - if (!fDoFitVelocity) { vi = sqrt(fvec(1.) + m2 * fQp0 * fQp0) / fvec(29.9792458f); } - - f5[step] = vi * L; - df5[step][2] = vi * tx / L; - df5[step][3] = vi * ty / L; - df5[step][4] = 0.; - df5[step][5] = 0.; - df5[step][6] = L; - - if (!fDoFitVelocity) { - df5[step][4] = (m2 * fQp0) * (L / sqrt(fvec(1.) + m2 * fQp0 * fQp0) / fvec(29.9792458f)); - df5[step][6] = 0.; - } - - k[step + 1][0] = f0[step]; - k[step + 1][1] = f1[step]; - k[step + 1][2] = f2[step]; - k[step + 1][3] = f3[step]; - k[step + 1][4] = f4[step]; // == 0 - k[step + 1][5] = f5[step]; - k[step + 1][6] = f6[step]; // == 0 - - } // end of Runge-Kutta step - - fTr.x = r0[0] + (c[0] * k[1][0] + c[1] * k[2][0] + c[2] * k[3][0] + c[3] * k[4][0]); - fTr.y = r0[1] + (c[0] * k[1][1] + c[1] * k[2][1] + c[2] * k[3][1] + c[3] * k[4][1]); - fTr.tx = r0[2] + (c[0] * k[1][2] + c[1] * k[2][2] + c[2] * k[3][2] + c[3] * k[4][2]); - fTr.ty = r0[3] + (c[0] * k[1][3] + c[1] * k[2][3] + c[2] * k[3][3] + c[3] * k[4][3]); - //fTr.qp = r0[4] + (c[0] * k[1][4] + c[1] * k[2][4] + c[2] * k[3][4] + c[3] * k[4][4]); - fTr.t = r0[5] + (c[0] * k[1][5] + c[1] * k[2][5] + c[2] * k[3][5] + c[3] * k[4][5]); - //fTr.vi = r0[6] + (c[0] * k[1][6] + c[1] * k[2][6] + c[2] * k[3][6] + c[3] * k[4][6]); - - fTr.z = zMasked; + fvec r0[7] = {fTr.x, fTr.y, fTr.tx, fTr.ty, fQp0, fTr.t, fTr.vi}; + fvec R0[7][7] = {{0.}}; + for (int i = 0; i < 7; ++i) { + R0[i][i] = 1.; } + for (int step = 1; step <= 4; ++step) { - // Jacobian of extrapolation - - // - // derivatives d/dx and d/dy - // - fvec Jx[7] = {1., 0., 0., 0., 0., 0., 0.}; // D new { x,y,tx,ty,qp,t,vi } / D old x - fvec Jy[7] = {0., 1., 0., 0., 0., 0., 0.}; // D new { x,y,tx,ty,qp,t,vi } / D old y - - // - // Runge-Kutta steps for derivatives d/dtx - // - fvec Jtx[7] = {0., 0., 1., 0., 0., 0., 0.}; // D new { x,y,tx,ty,qp,t,vi } / D old tx - { - for (int step = 0; step < 4; ++step) { - fvec r2 = Jtx[2] + a[step] * k[step][2]; // dtx[step]/dtx0 - fvec r3 = Jtx[3] + a[step] * k[step][3]; // dty[step]/dtx0 - k[step + 1][0] = r2; - k[step + 1][1] = r3; - k[step + 1][2] = df2[step][2] * r2 + df2[step][3] * r3; - k[step + 1][3] = df3[step][2] * r2 + df3[step][3] * r3; - k[step + 1][4] = 0.; - k[step + 1][5] = df5[step][2] * r2 + df5[step][3] * r3; - k[step + 1][6] = 0.; - } + fvec rstep[7] = {{0.}}; for (int i = 0; i < 7; ++i) { - Jtx[i] += c[0] * k[1][i] + c[1] * k[2][i] + c[2] * k[3][i] + c[3] * k[4][i]; + rstep[i] = r0[i] + stepDz[step] * f[step - 1][i]; } - } - - // - // Runge-Kutta steps for derivatives d/dty - // - fvec Jty[7] = {0., 0., 0., 1., 0., 0., 0.}; // D new { x,y,tx,ty,qp,t,vi } / D old ty - { - for (int step = 0; step < 4; ++step) { - fvec r2 = Jty[2] + a[step] * k[step][2]; // dtx[step]/dty0 - fvec r3 = Jty[3] + a[step] * k[step][3]; // dty[step]/dty0 - k[step + 1][0] = r2; - k[step + 1][1] = r3; - k[step + 1][2] = df2[step][2] * r2 + df2[step][3] * r3; - k[step + 1][3] = df3[step][2] * r2 + df3[step][3] * r3; - k[step + 1][4] = 0.; - k[step + 1][5] = df5[step][2] * r2 + df5[step][3] * r3; - k[step + 1][6] = 0.; + fvec z = fTr.z + stepDz[step]; + + fvec B[3]; + cnst& Bx = B[0]; + cnst& By = B[1]; + cnst& Bz = B[2]; + Field.Get(rstep[0], rstep[1], z, B); + + fvec tx = rstep[2]; + fvec ty = rstep[3]; + fvec tx2 = tx * tx; + fvec ty2 = ty * ty; + fvec txty = tx * ty; + fvec L2 = fvec(1.) + tx2 + ty2; + fvec L2i = fvec(1.) / L2; + fvec L = sqrt(L2); + fvec cL = c_light * L; + fvec cLqp0 = cL * fQp0; + + f[step][0] = tx; + F[step][0][2] = 1.; + + f[step][1] = ty; + F[step][1][3] = 1.; + + fvec f2tmp = txty * Bx - (fvec(1.) + tx2) * By + ty * Bz; + f[step][2] = cLqp0 * f2tmp; + + F[step][2][2] = cLqp0 * (tx * f2tmp * L2i + ty * Bx - fvec(2.) * tx * By); + F[step][2][3] = cLqp0 * (ty * f2tmp * L2i + tx * Bx + Bz); + F[step][2][4] = cL * f2tmp; + + fvec f3tmp = -txty * By - tx * Bz + (fvec(1.) + ty2) * Bx; + f[step][3] = cLqp0 * f3tmp; + F[step][3][2] = cLqp0 * (tx * f3tmp * L2i - ty * By - Bz); + F[step][3][3] = cLqp0 * (ty * f3tmp * L2i + fvec(2.) * ty * Bx - tx * By); + F[step][3][4] = cL * f3tmp; + + f[step][4] = 0.; + + if (fDoFitVelocity) { + fvec vi = rstep[6]; + f[step][5] = vi * L; + F[step][5][2] = vi * tx / L; + F[step][5][3] = vi * ty / L; + F[step][5][4] = 0.; + F[step][5][5] = 0.; + F[step][5][6] = L; } - for (int i = 0; i < 7; ++i) { - Jty[i] += c[0] * k[1][i] + c[1] * k[2][i] + c[2] * k[3][i] + c[3] * k[4][i]; + else { + fvec vi = sqrt(fvec(1.) + fMass2 * fQp0 * fQp0) * fvec(L1TrackPar::kClightNsInv); + f[step][5] = vi * L; + F[step][5][2] = vi * tx / L; + F[step][5][3] = vi * ty / L; + F[step][5][4] = fMass2 * fQp0 * L / sqrt(fvec(1.) + fMass2 * fQp0 * fQp0) * fvec(L1TrackPar::kClightNsInv); + F[step][5][5] = 0.; + F[step][5][6] = 0.; } - } - // - // Runge-Kutta steps for derivatives d/dqp - // - fvec Jqp[7] = {0., 0., 0., 0., 1., 0., 0.}; // D new { x,y,tx,ty,qp,t,vi } / D old qp - { - for (int step = 0; step < 4; ++step) { - fvec r2 = Jqp[2] + a[step] * k[step][2]; // dtx/dqp - fvec r3 = Jqp[3] + a[step] * k[step][3]; // dty/dqp; - fvec r4 = Jqp[4] + a[step] * k[step][4]; // dqp/dqp == 1 - k[step + 1][0] = r2; - k[step + 1][1] = r3; - k[step + 1][2] = df2[step][2] * r2 + df2[step][3] * r3 + df2[step][4] * r4; - k[step + 1][3] = df3[step][2] * r2 + df3[step][3] * r3 + df3[step][4] * r4; - k[step + 1][4] = 0.; - k[step + 1][5] = df5[step][2] * r2 + df5[step][3] * r3 + df5[step][4] * r4; - k[step + 1][6] = 0.; - } - for (int i = 0; i < 7; ++i) { - Jqp[i] += c[0] * k[1][i] + c[1] * k[2][i] + c[2] * k[3][i] + c[3] * k[4][i]; - } - } + f[step][6] = 0.; + } // end of Runge-Kutta step - // - // derivatives d/dt - // - fvec Jt[7] = {0., 0., 0., 0., 0., 1., 0.}; // D new { x,y,tx,ty,qp,t,vi } / D old t + fvec r[7] = {{0.}}; // extrapolated parameters + fvec R[7][7] = {{0.}}; // Jacobian of the extrapolation - // - // derivatives d/dvi - // - fvec Jvi[7] = {0., 0., 0., 0., 0., 0., 1.}; // D new { x,y,tx,ty,qp,t,vi } / D old vi - { - for (int step = 0; step < 4; ++step) { - fvec r2 = Jvi[2] + a[step] * k[step][2]; // dtx/dvi - fvec r3 = Jvi[3] + a[step] * k[step][3]; // dty/dvi; - fvec r6 = Jvi[6] + a[step] * k[step][6]; //(dvi/dvi == 1) - k[step + 1][0] = r2; - k[step + 1][1] = r3; - k[step + 1][2] = df2[step][2] * r2 + df2[step][3] * r3; - k[step + 1][3] = df3[step][2] * r2 + df3[step][3] * r3; - k[step + 1][4] = 0.; - k[step + 1][5] = df5[step][2] * r2 + df5[step][3] * r3 + df5[step][6] * r6; - k[step + 1][6] = 0.; - } - for (int i = 0; i < 7; ++i) { - Jvi[i] += c[0] * k[1][i] + c[1] * k[2][i] + c[2] * k[3][i] + c[3] * k[4][i]; + cnst stepW[5] = {0., h / fvec(6.), h / fvec(3.), h / fvec(3.), h / fvec(6.)}; + + for (int i = 0; i < 7; i++) { + for (int j = 0; j < 7; j++) { + R[i][j] = R0[i][j]; + for (int step = 1; step <= 4; step++) { + R[i][j] += stepW[step] * F[step][i][j]; + } } } + fvec dqp = fTr.qp - fQp0; - { // update parameters - fvec dqp = qp_in - fQp0; - fTr.x += Jqp[0] * dqp; - fTr.y += Jqp[1] * dqp; - fTr.tx += Jqp[2] * dqp; - fTr.ty += Jqp[3] * dqp; - fTr.t += Jqp[5] * dqp; + for (int i = 0; i < 7; i++) { + r[i] = r0[i]; + for (int step = 1; step <= 4; step++) { + r[i] += stepW[step] * f[step][i]; + } + // take into account linearisation at fQp0 + r[i] += R[i][4] * dqp; } - // covariance matrix transport + // update parameters - fvec J[7][7]; - for (int i = 0; i < 7; i++) { - J[i][0] = Jx[i]; // d {x,y,tx,ty,qp,t,vi} / dx - J[i][1] = Jy[i]; // d * / dy - J[i][2] = Jtx[i]; // d * / dtx - J[i][3] = Jty[i]; // d * / dty - J[i][4] = Jqp[i]; // d * / dqp - J[i][5] = Jt[i]; // d * / dt - J[i][6] = Jvi[i]; // d * / dvi - } + fTr.x = r[0]; + fTr.y = r[1]; + fTr.tx = r[2]; + fTr.ty = r[3]; + fTr.qp = r[4]; + fTr.t = r[5]; + fTr.vi = r[6]; + + //fTr.vi( fTr.vi < fvec(L1TrackPar::kClightNsInv) ) = fvec(L1TrackPar::kClightNsInv); + fTr.z = zMasked; + + // covariance matrix transport fvec C[7][7]; for (int i = 0; i < 7; i++) { @@ -643,12 +740,12 @@ void L1Fit::ExtrapolateStepFull // extrapolates track parameters and returns ja } } - fvec JC[7][7]; + fvec RC[7][7]; for (int i = 0; i < 7; i++) { for (int j = 0; j < 7; j++) { - JC[i][j] = 0.; + RC[i][j] = 0.; for (int m = 0; m < 7; m++) { - JC[i][j] += J[i][m] * C[m][j]; + RC[i][j] += R[i][m] * C[m][j]; } } } @@ -656,7 +753,7 @@ void L1Fit::ExtrapolateStepFull // extrapolates track parameters and returns ja for (int j = 0; j < 7; j++) { fvec Cij = 0.; for (int m = 0; m < 7; m++) { - Cij += JC[i][m] * J[j][m]; + Cij += RC[i][m] * R[j][m]; } fTr.C(i, j) = Cij; } @@ -1849,7 +1946,7 @@ void L1Fit::GuessTrack(const fvec& trackZ, const fvec hitX[], const fvec hitY[], fTr.qp = -L * c_light_i / sqrt(txtx1 + fTr.ty * fTr.ty); fTr.t = time; fTr.z = trackZ; - fTr.vi = 0.; + fTr.vi = L1TrackPar::kClightNsInv; fQp0 = fTr.qp; } diff --git a/reco/L1/L1Algo/L1Fit.h b/reco/L1/L1Algo/L1Fit.h index 6ca7a9b1f93f87f1ee1773e0072107db01b3297f..458d9d576ac1989efc9c06b5987f69bc4a0cd182 100644 --- a/reco/L1/L1Algo/L1Fit.h +++ b/reco/L1/L1Algo/L1Fit.h @@ -83,11 +83,21 @@ public: /// get the particle mass squared fvec GetParticleMass2() const { return fMass2; } + /// set max extrapolation step [cm] + void SetMaxExtrapolationStep(fscal step) { fMaxExtraplationStep = fvec(step); } + + /// get the particle mass + fvec GetMaxExtrapolationStep() const { return fMaxExtraplationStep; } + + void Filter(const L1UMeasurementInfo& info, cnst& u, cnst& sigma2); void FilterXY(const L1XYMeasurementInfo& info, cnst& x, cnst& y); void FilterTime(cnst& t, cnst& dt2, cnst& timeInfo); void FilterExtrapolatedXY(cnst& x, cnst& y, const L1XYMeasurementInfo& info, cnst& extrX, cnst& extrY, cnst Jx[6], cnst Jy[6]); + void FilterVi(fvec vi); + + void MeasureVelocityWithQp(); void Extrapolate(cnst& z_out, const L1FieldRegion& F); @@ -143,6 +153,8 @@ private: fvec fMass {0.10565800}; // muon mass fvec fMass2 {fMass * fMass}; // mass squared + fvec fMaxExtraplationStep {50.}; // max extrapolation step [cm] + fvec fPipeRadThick {7.87e-3f}; // 0.7 mm Aluminium // TODO: fvec fTargetRadThick {3.73e-2f * 2}; // 250 mum Gold // TODO: diff --git a/reco/L1/L1Algo/L1TrackFitter.cxx b/reco/L1/L1Algo/L1TrackFitter.cxx index 4676463254b70d2e098154f8162a68efa39bf1db..6f8330d0ea5b79901056e0a373bfd8d6dee703a2 100644 --- a/reco/L1/L1Algo/L1TrackFitter.cxx +++ b/reco/L1/L1Algo/L1TrackFitter.cxx @@ -38,11 +38,10 @@ void L1Algo::L1KFTrackFitter() const int nStations = fParameters.GetNstationsActive(); int nTracks_SIMD = fvec::size(); - L1Fit fit; // fitting parametr coresponding to current track + L1Fit fit; // fit parameters coresponding to the current track L1TrackPar& tr = fit.Tr(); - fit.SetParticleMass(GetDefaultParticleMass()); - fit.SetDoFitVelocity(false); + fit.SetDoFitVelocity(true); L1Track* t[fvec::size()] {nullptr}; @@ -73,6 +72,7 @@ void L1Algo::L1KFTrackFitter() fvec d_xy_fst; fvec time_first; + fvec wtime_first; fvec dt2_first; fvec x_last; @@ -82,6 +82,7 @@ void L1Algo::L1KFTrackFitter() fvec d_xy_lst; fvec time_last; + fvec wtime_last; fvec dt2_last; // fvec dt2_lst; /// TODO: Why are there two different variables for the time error on the last station? @@ -154,7 +155,8 @@ void L1Algo::L1KFTrackFitter() y[ista][iVec] = y_temp[iVec]; time[ista][iVec] = hit.t; dt2[ista][iVec] = hit.dt2; - z[ista][iVec] = hit.z; + if (!sta[ista].timeInfo) { dt2[ista][iVec] = 1.e4; } + z[ista][iVec] = hit.z; sta[ista].fieldSlice.GetFieldValue(x[ista], y[ista], fB_temp); std::tie(d_xx[ista], d_xy[ista], d_yy[ista]) = sta[ista].FormXYCovarianceMatrix(du2[ista], dv2[ista]); @@ -162,25 +164,27 @@ void L1Algo::L1KFTrackFitter() fB[ista].y[iVec] = fB_temp.y[iVec]; fB[ista].z[iVec] = fB_temp.z[iVec]; if (ih == 0) { - z_start[iVec] = z[ista][iVec]; - x_first[iVec] = x[ista][iVec]; - y_first[iVec] = y[ista][iVec]; - time_first[iVec] = time[ista][iVec]; - dt2_first[iVec] = dt2[ista][iVec]; - d_xx_fst[iVec] = d_xx[ista][iVec]; - d_yy_fst[iVec] = d_yy[ista][iVec]; - d_xy_fst[iVec] = d_xy[ista][iVec]; + z_start[iVec] = z[ista][iVec]; + x_first[iVec] = x[ista][iVec]; + y_first[iVec] = y[ista][iVec]; + time_first[iVec] = time[ista][iVec]; + wtime_first[iVec] = sta[ista].timeInfo ? 1. : 0.; + dt2_first[iVec] = dt2[ista][iVec]; + d_xx_fst[iVec] = d_xx[ista][iVec]; + d_yy_fst[iVec] = d_yy[ista][iVec]; + d_xy_fst[iVec] = d_xy[ista][iVec]; } else if (ih == nHitsTrack - 1) { - z_end[iVec] = z[ista][iVec]; - x_last[iVec] = x[ista][iVec]; - y_last[iVec] = y[ista][iVec]; - d_xx_lst[iVec] = d_xx[ista][iVec]; - d_yy_lst[iVec] = d_yy[ista][iVec]; - d_xy_lst[iVec] = d_xy[ista][iVec]; - time_last[iVec] = time[ista][iVec]; - dt2_last[iVec] = dt2[ista][iVec]; + z_end[iVec] = z[ista][iVec]; + x_last[iVec] = x[ista][iVec]; + y_last[iVec] = y[ista][iVec]; + d_xx_lst[iVec] = d_xx[ista][iVec]; + d_yy_lst[iVec] = d_yy[ista][iVec]; + d_xy_lst[iVec] = d_xy[ista][iVec]; + time_last[iVec] = time[ista][iVec]; + dt2_last[iVec] = dt2[ista][iVec]; + wtime_last[iVec] = sta[ista].timeInfo ? 1. : 0.; } } @@ -208,13 +212,17 @@ void L1Algo::L1KFTrackFitter() time_last = iif(w_time[ista], time_last, fvec::Zero()); dt2_last = iif(w_time[ista], dt2_last, fvec(1.e6)); - tr.ResetErrors(d_xx_lst, d_yy_lst, 0.1, 0.1, 1.0, dt2_last, 1.e2); + tr.ResetErrors(d_xx_lst, d_yy_lst, 0.1, 0.1, 1.0, dt2_last, 1.e-2); tr.C10 = d_xy_lst; tr.x = x_last; tr.y = y_last; tr.t = time_last; + tr.vi = L1TrackPar::kClightNsInv; + tr.InitVelocityRange(0.5); tr.NDF = -3.0; + tr.nTimeMeasurements = wtime_last; + fldZ1 = z[ista]; sta[ista].fieldSlice.GetFieldValue(tr.x, tr.y, fldB1); @@ -286,6 +294,11 @@ void L1Algo::L1KFTrackFitter() } } + //fit.SetQp0(tr.qp); + //fit.SetMask(fmask::One()); + //fit.MeasureVelocityWithQp(); + //fit.FilterVi(L1TrackPar::kClightNsInv); + L1TrackPar Tf = fit.Tr(); if (kGlobal == fTrackingMode) { Tf.qp = fitpv.Tr().qp; } @@ -299,20 +312,25 @@ void L1Algo::L1KFTrackFitter() fitpv.Tr().copyToArrays(iVec, t[iVec]->Tpv, t[iVec]->Cpv); } - if (iter == 1) continue; // only 1.5 iterations + if (iter == 1) { break; } // only 1.5 iterations // fit forward ista = 0; - tr.ResetErrors(d_xx_fst, d_yy_fst, 0.1, 0.1, 1., dt2_first, 1.e2); + tr.ResetErrors(d_xx_fst, d_yy_fst, 0.1, 0.1, 1., dt2_first, 1.e-2); tr.C10 = d_xy_fst; - tr.x = x_first; - tr.y = y_first; - tr.t = time_first; + tr.x = x_first; + tr.y = y_first; + tr.t = time_first; + tr.vi = L1TrackPar::kClightNsInv; + tr.InitVelocityRange(0.5); + tr.NDF = -3.0; + tr.nTimeMeasurements = wtime_first; + fit.SetQp0(tr.qp); fldZ1 = z[ista]; @@ -349,6 +367,11 @@ void L1Algo::L1KFTrackFitter() fldZ1 = fldZ0; } + //fit.SetQp0(tr.qp); + //fit.SetMask(fmask::One()); + //fit.MeasureVelocityWithQp(); + //fit.FilterVi(L1TrackPar::kClightNsInv); + L1TrackPar Tl = fit.Tr(); if (kGlobal == fTrackingMode) { Tl.qp = fitpv.Tr().qp; } diff --git a/reco/L1/L1Algo/L1TrackPar.h b/reco/L1/L1Algo/L1TrackPar.h index 25e4fb43a7d60be9a88519c5683282afde5b3986..10eb77615bebea405ac417f1adfe8b7b47f2515b 100644 --- a/reco/L1/L1Algo/L1TrackPar.h +++ b/reco/L1/L1Algo/L1TrackPar.h @@ -13,6 +13,9 @@ using namespace cbm::algo::ca; class L1TrackPar { public: + static constexpr int kNparTr {8}; + static constexpr int kNparCov {28}; + fvec x {0.}, y {0.}, tx {0.}, ty {0.}, qp {0.}, z {0.}, t {0.}, vi {0.}; fvec C00 {0.}, @@ -31,6 +34,8 @@ public: fvec chi2 {0.}, NDF {0.}; + fvec nTimeMeasurements {0.}; + L1TrackPar() = default; template<typename T> @@ -58,7 +63,6 @@ public: return c[ind]; } - void ResetErrors(fvec c00, fvec c11, fvec c22, fvec c33, fvec c44, fvec c55, fvec c66); void Print(int i = -1) const; @@ -70,20 +74,29 @@ public: bool IsConsistent(bool printWhenWrong, int nFilled) const; template<typename T> - void copyToArrays(const int iVec, T p[7], T c[28]) const; + void copyToArrays(const int iVec, T p[kNparTr], T c[kNparCov]) const; template<typename T> - void copyFromArrays(const int iVec, const T p[7], const T c[28]); + void copyFromArrays(const int iVec, const T p[kNparTr], const T c[kNparCov]); template<typename T> - void copyFromArrays(const T p[7], const T c[28]); + void copyFromArrays(const T p[kNparTr], const T c[kNparCov]); + + void InitVelocityRange(fscal minP); + + static constexpr float kClightNs {29.9792458}; // the speed of light cm/ns + static constexpr float kClightNsInv {1. / 29.9792458}; // inverse speed of light + static constexpr float kProtonMass = 0.93827208816; + static constexpr float kPionMass = 0.1395703918; + static constexpr float kMuonMass = 0.105658375523; + static constexpr float kElectronMass = 0.0005109989500015; } _fvecalignment; // ============================================================================================= template<typename T> -inline void L1TrackPar::copyToArrays(const int iVec, T p[7], T c[28]) const +inline void L1TrackPar::copyToArrays(const int iVec, T p[kNparTr], T c[kNparCov]) const { p[0] = x[iVec]; p[1] = y[iVec]; @@ -95,13 +108,13 @@ inline void L1TrackPar::copyToArrays(const int iVec, T p[7], T c[28]) const p[7] = vi[iVec]; const fvec* tC = &(C00); - for (int i = 0; i < 28; i++) { + for (int i = 0; i < kNparCov; i++) { c[i] = tC[i][iVec]; } } template<typename T> -inline void L1TrackPar::copyFromArrays(const int iVec, const T p[7], const T c[28]) +inline void L1TrackPar::copyFromArrays(const int iVec, const T p[kNparTr], const T c[kNparCov]) { x[iVec] = p[0]; y[iVec] = p[1]; @@ -113,7 +126,7 @@ inline void L1TrackPar::copyFromArrays(const int iVec, const T p[7], const T c[2 vi[iVec] = p[7]; fvec* tC = &(C00); - for (int i = 0; i < 28; i++) { + for (int i = 0; i < kNparCov; i++) { tC[i][iVec] = c[i]; } @@ -122,7 +135,7 @@ inline void L1TrackPar::copyFromArrays(const int iVec, const T p[7], const T c[2 } template<typename T> -inline void L1TrackPar::copyFromArrays(const T p[7], const T c[28]) +inline void L1TrackPar::copyFromArrays(const T p[kNparTr], const T c[kNparCov]) { x = p[0]; y = p[1]; @@ -134,7 +147,7 @@ inline void L1TrackPar::copyFromArrays(const T p[7], const T c[28]) vi = p[7]; fvec* tC = &(C00); - for (int i = 0; i < 28; i++) { + for (int i = 0; i < kNparCov; i++) { tC[i] = c[i]; } @@ -196,15 +209,29 @@ inline void L1TrackPar::ResetErrors(fvec c00, fvec c11, fvec c22, fvec c33, fvec C50 = C51 = C52 = C53 = C54 = 0.; C60 = C61 = C62 = C63 = C64 = C65 = 0.; - C00 = c00; - C11 = c11; - C22 = c22; - C33 = c33; - C44 = c44; - C55 = c55; - C66 = c66; + C00 = c00; + C11 = c11; + C22 = c22; + C33 = c33; + C44 = c44; + C55 = c55; + C66 = c66; + chi2 = 0.; NDF = -6.; + nTimeMeasurements = 0.; +} + +inline void L1TrackPar::InitVelocityRange(fscal minP) +{ + // initialise the velocity range with respect to the minimal momentum minP {GeV/c} + + fscal maxVi = sqrt(1. + (kProtonMass / minP) * (kProtonMass / minP)) * kClightNsInv; + fscal minVi = kClightNsInv; + fscal vmean = minVi + 0.4 * (maxVi - minVi); + fscal dvi = (maxVi - vmean) / 3.; + vi = vmean; + C66 = dvi * dvi; } #endif