14#include <fairlogger/Logger.h>
30#include <Math/SMatrix.h>
31#include <Math/SVector.h>
33#include <TGeoGlobalMagField.h>
61bool MatchTOF::mHasFillScheme =
false;
69 mFirstTForbit = firstTForbit;
79 updateTimeDependentParams();
81 mTimerMatchTPC.Reset();
82 mTimerMatchITSTPC.Reset();
85 mCalibInfoTOF.clear();
87 for (
int i = 0;
i < trkType::SIZEALL;
i++) {
88 mMatchedTracks[
i].clear();
89 mOutTOFLabels[
i].clear();
92 for (
int it = 0; it < trkType::SIZE; it++) {
94 mMatchedTracksIndex[sec][it].clear();
95 mTracksWork[sec][it].clear();
96 mTrackGid[sec][it].clear();
97 mLTinfos[sec][it].clear();
99 mTracksLblWork[sec][it].clear();
101 mTracksSectIndexCache[it][sec].clear();
102 mTracksSeed[it][sec].clear();
107 mSideTPC[sec].clear();
108 mExtraTPCFwdTime[sec].clear();
112 bool isPrepareTOFClusters = prepareTOFClusters();
114 LOGF(info,
"Timing prepareTOFCluster: Cpu: %.3e s Real: %.3e s in %d slots", mTimerTot.CpuTime(), mTimerTot.RealTime(), mTimerTot.Counter() - 1);
116 if (!isPrepareTOFClusters) {
121 if (!prepareTPCData()) {
125 LOGF(info,
"Timing prepare TPC tracks: Cpu: %.3e s Real: %.3e s in %d slots", mTimerTot.CpuTime(), mTimerTot.RealTime(), mTimerTot.Counter() - 1);
128 if (!prepareFITData()) {
132 LOGF(info,
"Timing prepare FIT data: Cpu: %.3e s Real: %.3e s in %d slots", mTimerTot.CpuTime(), mTimerTot.RealTime(), mTimerTot.Counter() - 1);
135 std::array<uint32_t, 18> nMatches = {0};
137 mTimerMatchITSTPC.Start();
140 mMatchedTracksPairsSec[sec].clear();
145 if (mIsITSTPCused || mIsTPCTRDused || mIsITSTPCTRDused) {
147#pragma omp parallel for schedule(dynamic) num_threads(mNlanes)
153 mTimerMatchITSTPC.Stop();
155 mTimerMatchTPC.Start();
158#pragma omp parallel for schedule(dynamic) num_threads(mNlanes)
161 doMatchingForTPC(sec);
164 mTimerMatchTPC.Stop();
168 if (mStoreMatchable) {
171 for (
auto& matchingPair : mMatchedTracksPairsSec[sec]) {
172 int trkType = (
int)matchingPair.getTrackType();
173 int itrk = matchingPair.getIdLocal();
174 const auto& labelsTOF = mTOFClusLabels->
getLabels(matchingPair.getTOFClIndex());
175 const auto& labelTrack = mTracksLblWork[sec][
trkType][itrk];
179 for (
auto& lbl : labelsTOF) {
180 if (labelTrack == lbl) {
185 matchingPair.setFakeMatch();
189 for (
auto& matchingPair : mMatchedTracksPairsSec[sec]) {
190 int bct0 =
int((matchingPair.getSignal() - matchingPair.getLTIntegralOut().getTOF(0) + 5000) *
Geo::BC_TIME_INPS_INV);
195 if (std::abs(tof - matchingPair.getLTIntegralOut().getTOF(2)) < 600) {
196 }
else if (std::abs(tof - matchingPair.getLTIntegralOut().getTOF(3)) < 600) {
197 }
else if (std::abs(tof - matchingPair.getLTIntegralOut().getTOF(4)) < 600) {
198 }
else if (std::abs(tof - matchingPair.getLTIntegralOut().getTOF(0)) < 600) {
199 }
else if (std::abs(tof - matchingPair.getLTIntegralOut().getTOF(1)) < 600) {
200 }
else if (std::abs(tof - matchingPair.getLTIntegralOut().getTOF(5)) < 600) {
201 }
else if (std::abs(tof - matchingPair.getLTIntegralOut().getTOF(6)) < 600) {
202 }
else if (std::abs(tof - matchingPair.getLTIntegralOut().getTOF(7)) < 600) {
203 }
else if (std::abs(tof - matchingPair.getLTIntegralOut().getTOF(8)) < 600) {
205 matchingPair.setFakeMatch();
211 LOG(
debug) <<
"...done. Now check the best matches";
212 nMatches[sec] = mMatchedTracksPairsSec[sec].size();
213 selectBestMatches(sec);
215 if (mStoreMatchable) {
216 for (
auto& matchingPair : mMatchedTracksPairsSec[sec]) {
217 trkType trkTypeSplitted = trkType::TPC;
218 auto sourceID = matchingPair.getTrackRef().getSource();
220 trkTypeSplitted = trkType::ITSTPC;
222 trkTypeSplitted = trkType::TPCTRD;
224 trkTypeSplitted = trkType::ITSTPCTRD;
226 matchingPair.setTrackType(trkTypeSplitted);
230 std::string nMatchesStr =
"Number of pairs matched per sector: ";
232 nMatchesStr += fmt::format(
"{} : {} ; ", sec, nMatches[sec]);
234 LOG(info) << nMatchesStr;
238 mIsITSTPCused =
false;
239 mIsTPCTRDused =
false;
240 mIsITSTPCTRDused =
false;
243 LOGF(info,
"Timing Do Matching: Cpu: %.3e s Real: %.3e s in %d slots", mTimerTot.CpuTime(), mTimerTot.RealTime(), mTimerTot.Counter() - 1);
244 LOGF(info,
"Timing Do Matching Constrained: Cpu: %.3e s Real: %.3e s in %d slots", mTimerMatchITSTPC.CpuTime(), mTimerMatchITSTPC.RealTime(), mTimerMatchITSTPC.Counter() - 1);
245 LOGF(info,
"Timing Do Matching TPC : Cpu: %.3e s Real: %.3e s in %d slots", mTimerMatchTPC.CpuTime(), mTimerMatchTPC.RealTime(), mTimerMatchTPC.Counter() - 1);
251 mTPCVDrift =
v.refVDrift *
v.corrFact;
252 mTPCVDriftCorrFact =
v.corrFact;
253 mTPCVDriftRef =
v.refVDrift;
254 mTPCDriftTimeOffset =
v.getTimeOffset();
269 LOG(info) <<
"****** component for the matching of tracks to TOF clusters ******";
271 LOG(info) <<
"MC truth: " << (mMCTruthON ?
"on" :
"off");
272 LOG(info) <<
"Time tolerance: " << mTimeTolerance;
273 LOG(info) <<
"Space tolerance: " << mSpaceTolerance;
274 LOG(info) <<
"SigmaTimeCut: " << mSigmaTimeCut;
276 LOG(info) <<
"**********************************************************************";
284bool MatchTOF::prepareFITData()
294int MatchTOF::prepareInteractionTimes()
300void MatchTOF::printGrouping(
const std::vector<o2::dataformats::MatchInfoTOFReco>&
origin,
const std::vector<std::vector<o2::dataformats::MatchInfoTOFReco>>& grouped)
302 printf(
"Original vector\n");
303 for (
const auto& seed :
origin) {
304 printf(
"Pair: track=%d TOFcl=%d\n", seed.getIdLocal(), seed.getTOFClIndex());
307 printf(
"\nGroups\n");
309 for (
const auto& gr : grouped) {
311 printf(
"Group %d\n", ngroups);
312 for (
const auto& seed : gr) {
313 printf(
"Pair: track=%d TOFcl=%d\n", seed.getIdLocal(), seed.getTOFClIndex());
318void MatchTOF::groupingMatch(
const std::vector<o2::dataformats::MatchInfoTOFReco>&
origin, std::vector<std::vector<o2::dataformats::MatchInfoTOFReco>>& grouped, std::vector<std::vector<int>>& firstEls, std::vector<std::vector<int>>& secondEls)
324 std::vector<o2::dataformats::MatchInfoTOFReco> dummy;
325 std::vector<int> dummyInt;
329 std::vector<int> alreadyUsed(
origin.size(), 0);
330 while (posInVector <
origin.size()) {
331 if (alreadyUsed[posInVector]) {
336 grouped.push_back(dummy);
337 auto& trkId = firstEls.emplace_back(dummyInt);
338 auto& cluId = secondEls.emplace_back(dummyInt);
341 const auto& seed =
origin[posInVector];
342 trkId.push_back(seed.getIdLocal());
343 cluId.push_back(seed.getTOFClIndex());
345 grouped[
pos].push_back(seed);
346 alreadyUsed[posInVector] =
true;
351 for (
int i = posInVector;
i <
origin.size();
i++) {
352 if (alreadyUsed[
i]) {
357 int matchSecond = -1;
358 for (
const int& ind : trkId) {
359 if (seed.getIdLocal() == ind) {
364 for (
const int& ind : cluId) {
365 if (seed.getTOFClIndex() == ind) {
371 if (matchFirst >= 0 || matchSecond >= 0) {
372 if (matchFirst < 0) {
373 trkId.push_back(seed.getIdLocal());
375 if (matchSecond < 0) {
376 cluId.push_back(seed.getTOFClIndex());
378 grouped[
pos].push_back(seed);
379 alreadyUsed[
i] =
true;
390bool MatchTOF::prepareTPCData()
392 mNotPropagatedToTOF[trkType::UNCONS] = 0;
393 mNotPropagatedToTOF[trkType::CONSTR] = 0;
395 auto creator = [
this](
auto& trk,
GTrackID gid,
float time0,
float terr) {
396 const int nclustersMin = 0;
397 if constexpr (isTPCTrack<decltype(trk)>()) {
398 if (trk.getNClusters() < nclustersMin) {
402 if (std::abs(trk.getQ2Pt()) > mMaxInvPt) {
405 this->addTPCSeed(trk, gid, time0, terr);
407 if constexpr (isTPCITSTrack<decltype(trk)>()) {
411 this->addITSTPCSeed(trk, gid, time0, terr);
413 if constexpr (isTRDTrack<decltype(trk)>()) {
414 this->addTRDSeed(trk, gid, time0, terr);
421#pragma omp parallel for schedule(dynamic) num_threads(mNlanes)
425 propagateTPCTracks(sec);
427 if (mIsITSTPCused || mIsTPCTRDused || mIsITSTPCTRDused) {
428 propagateConstrTracks(sec);
433 std::array<float, 3> globalPos;
436 for (
auto& it : mTracksSeed[
trkType::UNCONS][sec]) {
437 auto& pair = mTracksWork[sec][trkType::UNCONS][it];
438 auto& trc = pair.first;
439 trc.getXYZGlo(globalPos);
442 int itnew = mTracksWork[sector][trkType::UNCONS].size();
444 mSideTPC[sector].push_back(mSideTPC[sec][it]);
445 mExtraTPCFwdTime[sector].push_back(mExtraTPCFwdTime[sec][it]);
446 mTracksWork[sector][trkType::UNCONS].emplace_back(pair);
447 mTrackGid[sector][trkType::UNCONS].emplace_back(mTrackGid[sec][trkType::UNCONS][it]);
450 mTracksLblWork[sector][trkType::UNCONS].emplace_back(mTracksLblWork[sec][trkType::UNCONS][it]);
452 mLTinfos[sector][trkType::UNCONS].emplace_back(mLTinfos[sec][trkType::UNCONS][it]);
453 mVZtpcOnly[sector].push_back(mVZtpcOnly[sec][it]);
454 mTracksSectIndexCache[trkType::UNCONS][sector].push_back(itnew);
458 for (
auto& it : mTracksSeed[
trkType::CONSTR][sec]) {
459 auto& pair = mTracksWork[sec][trkType::CONSTR][it];
460 auto& trc = pair.first;
461 trc.getXYZGlo(globalPos);
464 int itnew = mTracksWork[sector][trkType::CONSTR].size();
466 mTracksWork[sector][trkType::CONSTR].emplace_back(pair);
467 mTrackGid[sector][trkType::CONSTR].emplace_back(mTrackGid[sec][trkType::CONSTR][it]);
470 mTracksLblWork[sector][trkType::CONSTR].emplace_back(mTracksLblWork[sec][trkType::CONSTR][it]);
472 mLTinfos[sector][trkType::CONSTR].emplace_back(mLTinfos[sec][trkType::CONSTR][it]);
473 mTracksSectIndexCache[trkType::CONSTR][sector].push_back(itnew);
477 for (
int it = 0; it < trkType::SIZE; it++) {
479 mMatchedTracksIndex[sec][it].resize(mTracksWork[sec][it].
size());
480 std::fill(mMatchedTracksIndex[sec][it].
begin(), mMatchedTracksIndex[sec][it].
end(), -1);
485 LOG(
debug) <<
"Number of UNCONSTRAINED tracks that failed to be propagated to TOF = " << mNotPropagatedToTOF[trkType::UNCONS];
489#pragma omp parallel for schedule(dynamic) num_threads(mNlanes)
492 auto& indexCache = mTracksSectIndexCache[trkType::UNCONS][sec];
493 LOG(
debug) <<
"Sorting sector" << sec <<
" | " << indexCache.size() <<
" tracks";
494 if (!indexCache.size()) {
497 std::sort(indexCache.begin(), indexCache.end(), [
this, sec](
int a,
int b) {
498 auto& trcA = mTracksWork[sec][trkType::UNCONS][a].second;
499 auto& trcB = mTracksWork[sec][trkType::UNCONS][b].second;
500 return ((trcA.getTimeStamp() - trcA.getTimeStampError()) - (trcB.getTimeStamp() - trcB.getTimeStampError()) < 0.);
504 if (mIsITSTPCused || mIsTPCTRDused || mIsITSTPCTRDused) {
505 LOG(
debug) <<
"Number of CONSTRAINED tracks that failed to be propagated to TOF = " << mNotPropagatedToTOF[trkType::CONSTR];
509#pragma omp parallel for schedule(dynamic) num_threads(mNlanes)
512 auto& indexCache = mTracksSectIndexCache[trkType::CONSTR][sec];
513 LOG(
debug) <<
"Sorting sector" << sec <<
" | " << indexCache.size() <<
" tracks";
514 if (!indexCache.size()) {
517 std::sort(indexCache.begin(), indexCache.end(), [
this, sec](
int a,
int b) {
518 auto& trcA = mTracksWork[sec][trkType::CONSTR][a].second;
519 auto& trcB = mTracksWork[sec][trkType::CONSTR][b].second;
520 return ((trcA.getTimeStamp() - mSigmaTimeCut * trcA.getTimeStampError()) - (trcB.getTimeStamp() - mSigmaTimeCut * trcB.getTimeStampError()) < 0.);
537void MatchTOF::propagateTPCTracks(
int sec)
539 auto& trkWork = mTracksWork[sec][trkType::UNCONS];
541 for (
int it = 0; it < trkWork.size(); it++) {
547 if (!trackTune.sourceLevelTPC) {
548 if (trackTune.useTPCOuterCorr) {
549 trc.updateParams(trackTune.tpcParOuter);
555 if (!propagateToRefXWithoutCov(trc, mXRef, 10, mBz)) {
556 mNotPropagatedToTOF[trkType::UNCONS]++;
562 mNotPropagatedToTOF[trkType::UNCONS]++;
570 if (!propagateToRefX(trc, mXRef, 2, intLT0)) {
571 mNotPropagatedToTOF[trkType::UNCONS]++;
578 std::array<float, 3> globalPos;
579 trc.getXYZGlo(globalPos);
583 mTracksSectIndexCache[trkType::UNCONS][sector].push_back(it);
585 mTracksSeed[trkType::UNCONS][sec].push_back(it);
590void MatchTOF::propagateConstrTracks(
int sec)
592 std::array<float, 3> globalPos;
594 auto& trkWork = mTracksWork[sec][trkType::CONSTR];
596 for (
int it = 0; it < trkWork.size(); it++) {
601 if (!propagateToRefXWithoutCov(trc, mXRef, 2, mBz)) {
602 mNotPropagatedToTOF[trkType::CONSTR]++;
607 if (!propagateToRefX(trc, mXRef, 2, intLT0) || std::abs(trc.getZ()) >
Geo::MAXHZTOF) {
608 mNotPropagatedToTOF[trkType::CONSTR]++;
612 trc.getXYZGlo(globalPos);
617 mTracksSectIndexCache[trkType::CONSTR][sector].push_back(it);
619 mTracksSeed[trkType::CONSTR][sec].push_back(it);
626 mIsITSTPCused =
true;
628 auto trc = _tr.getParamOut();
632 addConstrainedSeed(trc, srcGID, intLT0, ts);
637 std::array<float, 3> globalPos;
638 trc.getXYZGlo(globalPos);
643 mTracksWork[sector][trkType::CONSTR].emplace_back(std::make_pair(trc, timeMUS));
644 mTrackGid[sector][trkType::CONSTR].emplace_back(srcGID);
645 mLTinfos[sector][trkType::CONSTR].emplace_back(intLT0);
656 mIsTPCTRDused =
true;
658 mIsITSTPCTRDused =
true;
663 auto trc = _tr.getOuterParam();
668 timeEst ts(time0, terr + mExtraTimeToleranceTRD);
670 addConstrainedSeed(trc, srcGID, intLT0, ts);
677 std::array<float, 3> globalPos;
687 float trackTime0 = _tr.getTime0() * mTPCTBinMUS;
688 timeInfo.setTimeStampError((_tr.getDeltaTBwd() + 5) * mTPCTBinMUS + extraErr);
690 timeInfo.setTimeStamp(trackTime0);
692 auto trc = _tr.getOuterParam();
693 trc.getXYZGlo(globalPos);
697 mSideTPC[sector].push_back(_tr.hasASideClustersOnly() ? 1 : (_tr.hasCSideClustersOnly() ? -1 : 0));
698 mExtraTPCFwdTime[sector].push_back((_tr.getDeltaTFwd() + 5) * mTPCTBinMUS + extraErr);
700 mTracksWork[sector][trkType::UNCONS].emplace_back(std::make_pair(trc, timeInfo));
701 mTrackGid[sector][trkType::UNCONS].emplace_back(srcGID);
704 mTracksLblWork[sector][trkType::UNCONS].emplace_back(mRecoCont->
getTPCTrackMCLabel(srcGID));
708 mLTinfos[sector][trkType::UNCONS].emplace_back(intLT0);
709 float vz0 = _tr.getZAt(0, mBz);
710 if (std::abs(vz0) > 9000) {
711 vz0 = _tr.getZ() - _tr.getX() * _tr.getTgl();
713 mVZtpcOnly[sector].push_back(vz0);
754bool MatchTOF::prepareTOFClusters()
758 mMCTruthON = mTOFClusLabels && mTOFClusLabels->
getNElements();
763 mTOFClusWork.clear();
771 mTOFClusSectIndexCache[sec].clear();
777 int nClusterInCurrentChunk = mTOFClustersArrayInp.size();
778 LOG(
debug) <<
"nClusterInCurrentChunk = " << nClusterInCurrentChunk;
779 mNumOfClusters += nClusterInCurrentChunk;
780 mTOFClusWork.reserve(mTOFClusWork.size() + mNumOfClusters);
781 for (
int it = 0; it < nClusterInCurrentChunk; it++) {
782 const Cluster& clOrig = mTOFClustersArrayInp[it];
784 mTOFClusWork.emplace_back(clOrig);
785 auto& cl = mTOFClusWork.back();
787 mTOFClusSectIndexCache[cl.getSector()].push_back(mTOFClusWork.size() - 1);
792 auto& indexCache = mTOFClusSectIndexCache[sec];
793 LOG(
debug) <<
"Sorting sector" << sec <<
" | " << indexCache.size() <<
" TOF clusters";
794 if (!indexCache.size()) {
797 std::sort(indexCache.begin(), indexCache.end(), [
this](
int a,
int b) {
798 auto& clA = mTOFClusWork[a];
799 auto& clB = mTOFClusWork[b];
800 return (clA.getTime() - clB.getTime()) < 0.;
804 if (mMatchedClustersIndex) {
805 delete[] mMatchedClustersIndex;
807 mMatchedClustersIndex =
new int[mNumOfClusters];
808 std::fill_n(mMatchedClustersIndex, mNumOfClusters, -1);
813void MatchTOF::doMatching(
int sec)
818 auto& cacheTOF = mTOFClusSectIndexCache[sec];
819 auto& cacheTrk = mTracksSectIndexCache[
type][sec];
820 int nTracks = cacheTrk.size(), nTOFCls = cacheTOF.size();
821 LOG(
debug) <<
"Matching sector " << sec <<
": number of tracks: " << nTracks <<
", number of TOF clusters: " << nTOFCls;
822 if (!nTracks || !nTOFCls) {
827 float deltaPos[2][3];
829 int nStepsInsideSameStrip[2] = {0, 0};
830 float deltaPosTemp[3];
831 std::array<float, 3>
pos;
832 std::array<float, 3> posBeforeProp;
837 LOG(
debug) <<
"Trying to match %d tracks" << cacheTrk.size();
838 for (
int itrk = 0; itrk < cacheTrk.size(); itrk++) {
839 for (
int ii = 0; ii < 2; ii++) {
841 nStepsInsideSameStrip[ii] = 0;
843 int nStripsCrossedInPropagation = 0;
844 auto& trackWork = mTracksWork[sec][
type][cacheTrk[itrk]];
845 auto& trefTrk = trackWork.first;
846 float pt = trefTrk.getPt();
847 auto& intLT = mLTinfos[sec][
type][cacheTrk[itrk]];
848 float timeShift = intLT.getL() * 33.35641;
852 float minTrkTime = (trackWork.second.getTimeStamp() - mSigmaTimeCut * trackWork.second.getTimeStampError()) * 1.E6 + timeShift;
853 float maxTrkTime = (trackWork.second.getTimeStamp() + mSigmaTimeCut * trackWork.second.getTimeStampError()) * 1.E6 + timeShift + 100E3;
854 const float sqrt12inv = 1. / sqrt(12.);
855 float resT = (trackWork.second.getTimeStampError() + 100E-3) * sqrt12inv;
869 for (
int ii = 0; ii < 2; ii++) {
870 for (
int iii = 0; iii < 5; iii++) {
875 int detIdTemp[5] = {-1, -1, -1, -1, -1};
877 double reachedPoint = mXRef + istep *
step;
879 while (propagateToRefX(trefTrk, reachedPoint, step, intLT) && nStripsCrossedInPropagation <= 2 && reachedPoint <
Geo::RMAX) {
882 trefTrk.getXYZGlo(
pos);
883 for (
int ii = 0; ii < 3; ii++) {
884 posFloat[ii] =
pos[ii];
894 for (
int idet = 0; idet < 5; idet++) {
895 detIdTemp[idet] = -1;
900 reachedPoint +=
step;
902 if (detIdTemp[2] == -1) {
924 if (nStripsCrossedInPropagation == 0 ||
925 (nStripsCrossedInPropagation >= 1 && (detId[nStripsCrossedInPropagation - 1][0] != detIdTemp[0] || detId[nStripsCrossedInPropagation - 1][1] != detIdTemp[1] || detId[nStripsCrossedInPropagation - 1][2] != detIdTemp[2]))) {
926 if (nStripsCrossedInPropagation == 0) {
927 LOG(
debug) <<
"We cross a strip for the first time";
929 if (nStripsCrossedInPropagation == 2) {
932 nStripsCrossedInPropagation++;
935 if (nStepsInsideSameStrip[nStripsCrossedInPropagation - 1] == 0) {
937 trkLTInt[nStripsCrossedInPropagation - 1] = intLT;
939 int detIdTemp2[5] = {0, 0, 0, 0, 0};
940 float deltaPosTemp2[3] = {deltaPosTemp[0], deltaPosTemp[1], deltaPosTemp[2]};
942 const int maxnstep = 50;
943 float xStart = trefTrk.getX();
944 float xStop = xStart;
945 trefTrk.getXYZGlo(
pos);
946 for (
int ii = 0; ii < 3; ii++) {
947 posFloat[ii] =
pos[ii];
949 while (deltaPosTemp2[1] < -0.05 && detIdTemp2[2] != -1 && nstep < maxnstep) {
952 propagateToRefXWithoutCov(trefTrk, xStop, 0.1, mBz, posFloat);
955 if (detIdTemp2[2] != -1) {
956 float dx = deltaPosTemp2[0] - deltaPosTemp[0];
957 float dy = deltaPosTemp2[1] - deltaPosTemp[1];
958 float dz = deltaPosTemp2[2] - deltaPosTemp[2];
959 updateTL(trkLTInt[nStripsCrossedInPropagation - 1], sqrt(dx * dx + dy * dy + dz * dz));
960 detIdTemp[0] = detIdTemp2[0];
961 detIdTemp[1] = detIdTemp2[1];
962 detIdTemp[2] = detIdTemp2[2];
963 detIdTemp[3] = detIdTemp2[3];
964 detIdTemp[4] = detIdTemp2[4];
965 deltaPosTemp[0] = deltaPosTemp2[0];
966 deltaPosTemp[1] = deltaPosTemp2[1];
967 deltaPosTemp[2] = deltaPosTemp2[2];
972 updateTL(trkLTInt[nStripsCrossedInPropagation - 1], -deltaPosTemp[1]);
974 detId[nStripsCrossedInPropagation - 1][0] = detIdTemp[0];
975 detId[nStripsCrossedInPropagation - 1][1] = detIdTemp[1];
976 detId[nStripsCrossedInPropagation - 1][2] = detIdTemp[2];
977 detId[nStripsCrossedInPropagation - 1][3] = detIdTemp[3];
978 detId[nStripsCrossedInPropagation - 1][4] = detIdTemp[4];
979 deltaPos[nStripsCrossedInPropagation - 1][0] = deltaPosTemp[0];
980 deltaPos[nStripsCrossedInPropagation - 1][1] = deltaPosTemp[1];
981 deltaPos[nStripsCrossedInPropagation - 1][2] = deltaPosTemp[2];
983 nStepsInsideSameStrip[nStripsCrossedInPropagation - 1]++;
996 for (Int_t imatch = 0; imatch < nStripsCrossedInPropagation; imatch++) {
998 deltaPos[imatch][0] /= nStepsInsideSameStrip[imatch];
999 deltaPos[imatch][1] /= nStepsInsideSameStrip[imatch];
1000 deltaPos[imatch][2] /= nStepsInsideSameStrip[imatch];
1003 if (nStripsCrossedInPropagation == 0) {
1006 bool foundCluster =
false;
1007 for (
auto itof = itof0; itof < nTOFCls; itof++) {
1009 auto& trefTOF = mTOFClusWork[cacheTOF[itof]];
1013 if (trefTOF.getTime() < minTrkTime) {
1018 if (trefTOF.getTime() > maxTrkTime) {
1022 int mainChannel = trefTOF.getMainContributingChannel();
1029 float posCorr[3] = {0, 0, 0};
1056 float ndifInv = 1. / ndigits;
1058 posCorr[0] *= ndifInv;
1059 posCorr[1] *= ndifInv;
1060 posCorr[2] *= ndifInv;
1066 for (
auto iPropagation = 0; iPropagation < nStripsCrossedInPropagation; iPropagation++) {
1072 if (tof - trkLTInt[iPropagation].getTOF(6) > 2000) {
1076 const float errXinvMin = 1. / (mMatchParams->
maxResX * mMatchParams->
maxResX);
1077 const float errZinvMin = 1. / (mMatchParams->
maxResZ * mMatchParams->
maxResZ);
1078 float errXinv2 = 1. / (trefTrk.getSigmaY2());
1079 float errZinv2 = 1. / (trefTrk.getSigmaZ2() * cosangle);
1081 if (errXinv2 < errXinvMin) {
1082 errXinv2 = errXinvMin;
1084 if (errZinv2 < errZinvMin) {
1085 errZinv2 = errZinvMin;
1089 LOG(
debug) <<
"Propagated Track [" << itrk <<
"]: detId[" << iPropagation <<
"] = " << detId[iPropagation][0] <<
", " << detId[iPropagation][1] <<
", " << detId[iPropagation][2] <<
", " << detId[iPropagation][3] <<
", " << detId[iPropagation][4];
1090 float resX = deltaPos[iPropagation][0] - (
indices[4] - detId[iPropagation][4]) *
Geo::XPAD + posCorr[0];
1091 float resZ = deltaPos[iPropagation][2] - (
indices[3] - detId[iPropagation][3]) *
Geo::ZPAD + posCorr[2];
1092 float resY = deltaPos[iPropagation][1];
1093 float resXor = resX;
1094 float resZor = resZ;
1095 float res = TMath::Sqrt(resX * resX + resZ * resZ);
1099 }
else if (resX > 1.25) {
1102 resX = 1E-3 / (pt + 1E-3);
1107 }
else if (resZ > 1.75) {
1110 resZ = 1E-3 / (pt + 1E-3);
1113 LOG(
debug) <<
"resX = " << resX <<
", resZ = " << resZ <<
", res = " <<
res;
1114 if (
indices[0] != detId[iPropagation][0]) {
1117 if (
indices[1] != detId[iPropagation][1]) {
1120 if (
indices[2] != detId[iPropagation][2]) {
1123 float chi2 = 0.5 * (resX * resX * errXinv2 + resZ * resZ * errZinv2);
1125 if (
res < mSpaceTolerance && chi2 < mMatchParams->maxChi2) {
1126 LOG(
debug) <<
"MATCHING FOUND: We have a match! between track " << mTracksSectIndexCache[
type][sec][itrk] <<
" and TOF cluster " << mTOFClusSectIndexCache[
indices[0]][itof];
1127 foundCluster =
true;
1129 int eventIndexTOFCluster = mTOFClusSectIndexCache[
indices[0]][itof];
1130 mMatchedTracksPairsSec[sec].emplace_back(cacheTrk[itrk], eventIndexTOFCluster, mTOFClusWork[cacheTOF[itof]].
getTime(), chi2, trkLTInt[iPropagation], mTrackGid[sec][
type][cacheTrk[itrk]],
type, (trefTOF.getTime() - (minTrkTime + maxTrkTime - 100E3) * 0.5) * 1E-6, trefTOF.getZ(), resXor, resZor, resY);
1131 mMatchedTracksPairsSec[sec][mMatchedTracksPairsSec[sec].size() - 1].setPt(pt);
1132 mMatchedTracksPairsSec[sec][mMatchedTracksPairsSec[sec].size() - 1].setResX(sqrt(1. / errXinv2));
1133 mMatchedTracksPairsSec[sec][mMatchedTracksPairsSec[sec].size() - 1].setResZ(sqrt(1. / errZinv2));
1134 mMatchedTracksPairsSec[sec][mMatchedTracksPairsSec[sec].size() - 1].setResT(resT);
1135 mMatchedTracksPairsSec[sec][mMatchedTracksPairsSec[sec].size() - 1].setVz(0.0);
1136 mMatchedTracksPairsSec[sec][mMatchedTracksPairsSec[sec].size() - 1].setChannel(mainChannel);
1144void MatchTOF::doMatchingForTPC(
int sec)
1148 int bc_grouping = 40;
1149 int bc_grouping_tolerance = bc_grouping + mTimeTolerance / 25;
1150 int bc_grouping_half = (bc_grouping + 1) / 2;
1154 auto& cacheTOF = mTOFClusSectIndexCache[sec];
1155 auto& cacheTrk = mTracksSectIndexCache[trkType::UNCONS][sec];
1156 int nTracks = cacheTrk.size(), nTOFCls = cacheTOF.size();
1157 LOG(
debug) <<
"Matching sector " << sec <<
": number of tracks: " << nTracks <<
", number of TOF clusters: " << nTOFCls;
1158 if (!nTracks || !nTOFCls) {
1162 float deltaPosTemp[3];
1163 std::array<float, 3>
pos;
1164 std::array<float, 3> posBeforeProp;
1169 std::vector<unsigned long> BCcand;
1171 std::vector<int> nStripsCrossedInPropagation;
1172 std::vector<std::array<std::array<int, 5>, 2>> detId;
1173 std::vector<std::array<o2::track::TrackLTIntegral, 2>> trkLTInt;
1174 std::vector<std::array<std::array<float, 3>, 2>> deltaPos;
1175 std::vector<std::array<int, 2>> nStepsInsideSameStrip;
1176 std::vector<std::array<float, 2>> Zshift;
1178 LOG(
debug) <<
"Trying to match %d tracks" << cacheTrk.size();
1180 for (
int itrk = 0; itrk < cacheTrk.size(); itrk++) {
1181 auto& trackWork = mTracksWork[sec][trkType::UNCONS][cacheTrk[itrk]];
1182 auto& trefTrk = trackWork.first;
1183 float pt = trefTrk.getPt();
1184 auto& intLT = mLTinfos[sec][trkType::UNCONS][cacheTrk[itrk]];
1186 float timeShift = intLT.getL() * 33.35641;
1190 nStripsCrossedInPropagation.clear();
1192 int side = mSideTPC[sec][cacheTrk[itrk]];
1194 double tpctime = trackWork.second.getTimeStamp();
1195 double minTrkTime = (tpctime - trackWork.second.getTimeStampError()) * 1.E6 + timeShift;
1196 minTrkTime =
int(minTrkTime / BCgranularity) * BCgranularity;
1197 double maxTrkTime = (tpctime + mExtraTPCFwdTime[sec][cacheTrk[itrk]]) * 1.E6 + timeShift;
1198 const float sqrt12inv = 1. / sqrt(12.);
1199 float resT = (maxTrkTime - minTrkTime) * sqrt12inv;
1202 for (
double tBC = minTrkTime; tBC < maxTrkTime; tBC += BCgranularity) {
1204 BCcand.emplace_back(ibc);
1205 nStripsCrossedInPropagation.emplace_back(0);
1209 int itofMax = nTOFCls;
1211 for (
auto itof = itof0; itof < nTOFCls; itof++) {
1212 auto& trefTOF = mTOFClusWork[cacheTOF[itof]];
1214 if (trefTOF.getTime() < minTrkTime) {
1219 if (trefTOF.getTime() > maxTrkTime) {
1224 if ((trefTOF.getZ() *
side < 0) && ((
side > 0) != (trackWork.first.getTgl() > 0))) {
1230 bc = (
bc / bc_grouping_half) * bc_grouping_half;
1232 bool isalreadyin =
false;
1234 for (
int k = 0; k < BCcand.size(); k++) {
1235 if (
bc == BCcand[k]) {
1241 BCcand.emplace_back(
bc);
1242 nStripsCrossedInPropagation.emplace_back(0);
1247 detId.reserve(BCcand.size());
1249 trkLTInt.reserve(BCcand.size());
1251 Zshift.reserve(BCcand.size());
1253 deltaPos.reserve(BCcand.size());
1254 nStepsInsideSameStrip.clear();
1255 nStepsInsideSameStrip.reserve(BCcand.size());
1270 int detIdTemp[5] = {-1, -1, -1, -1, -1};
1272 double reachedPoint = mXRef + istep *
step;
1275 for (
int ibc = 0; ibc < BCcand.size(); ibc++) {
1276 for (
int ii = 0; ii < 2; ii++) {
1277 nStepsInsideSameStrip[ibc][ii] = 0;
1278 for (
int iii = 0; iii < 5; iii++) {
1279 detId[ibc][ii][iii] = -1;
1283 while (propagateToRefX(trefTrk, reachedPoint, step, intLT) && reachedPoint <
Geo::RMAX) {
1286 trefTrk.getXYZGlo(
pos);
1287 for (
int ii = 0; ii < 3; ii++) {
1288 posFloat[ii] =
pos[ii];
1298 reachedPoint +=
step;
1301 for (
int ibc = 0; ibc < BCcand.size(); ibc++) {
1302 for (
int idet = 0; idet < 5; idet++) {
1303 detIdTemp[idet] = -1;
1307 posFloat[2] =
pos[2] - mTPCVDrift * (trackWork.second.getTimeStamp() - BCcand[ibc] *
Geo::BC_TIME_INPS * 1E-6);
1308 }
else if (
side < 0) {
1309 posFloat[2] =
pos[2] + mTPCVDrift * (trackWork.second.getTimeStamp() - BCcand[ibc] *
Geo::BC_TIME_INPS * 1E-6);
1311 posFloat[2] =
pos[2];
1314 float ZshiftCurrent = posFloat[2] -
pos[2];
1318 if (detIdTemp[2] == -1) {
1322 if (nStripsCrossedInPropagation[ibc] == 0 ||
1323 (nStripsCrossedInPropagation[ibc] >= 1 && (detId[ibc][nStripsCrossedInPropagation[ibc] - 1][0] != detIdTemp[0] || detId[ibc][nStripsCrossedInPropagation[ibc] - 1][1] != detIdTemp[1] || detId[ibc][nStripsCrossedInPropagation[ibc] - 1][2] != detIdTemp[2]))) {
1324 if (nStripsCrossedInPropagation[ibc] == 0) {
1325 LOG(
debug) <<
"We cross a strip for the first time";
1327 if (nStripsCrossedInPropagation[ibc] == 2) {
1330 nStripsCrossedInPropagation[ibc]++;
1334 if (nStepsInsideSameStrip[ibc][nStripsCrossedInPropagation[ibc] - 1] == 0) {
1335 trkLTInt[ibc][nStripsCrossedInPropagation[ibc] - 1] = intLT;
1337 int detIdTemp2[5] = {0, 0, 0, 0, 0};
1338 float deltaPosTemp2[3] = {deltaPosTemp[0], deltaPosTemp[1], deltaPosTemp[2]};
1340 const int maxnstep = 50;
1341 float xStart = trefTrk.getX();
1342 float xStop = xStart;
1343 trefTrk.getXYZGlo(
pos);
1344 for (
int ii = 0; ii < 3; ii++) {
1345 posFloat[ii] =
pos[ii];
1348 while (deltaPosTemp2[1] < -0.05 && detIdTemp2[2] != -1 && nstep < maxnstep) {
1351 propagateToRefXWithoutCov(trefTrk, xStop, 0.1, mBz, posFloat);
1353 posFloat[2] += ZshiftCurrent;
1356 if (detIdTemp2[2] != -1) {
1357 float dx = deltaPosTemp2[0] - deltaPosTemp[0];
1358 float dy = deltaPosTemp2[1] - deltaPosTemp[1];
1359 float dz = deltaPosTemp2[2] - deltaPosTemp[2];
1360 updateTL(trkLTInt[ibc][nStripsCrossedInPropagation[ibc] - 1], sqrt(dx * dx + dy * dy + dz * dz));
1361 detIdTemp[0] = detIdTemp2[0];
1362 detIdTemp[1] = detIdTemp2[1];
1363 detIdTemp[2] = detIdTemp2[2];
1364 detIdTemp[3] = detIdTemp2[3];
1365 detIdTemp[4] = detIdTemp2[4];
1366 deltaPosTemp[0] = deltaPosTemp2[0];
1367 deltaPosTemp[1] = deltaPosTemp2[1];
1368 deltaPosTemp[2] = deltaPosTemp2[2];
1373 updateTL(trkLTInt[ibc][nStripsCrossedInPropagation[ibc] - 1], -deltaPosTemp[1]);
1375 detId[ibc][nStripsCrossedInPropagation[ibc] - 1][0] = detIdTemp[0];
1376 detId[ibc][nStripsCrossedInPropagation[ibc] - 1][1] = detIdTemp[1];
1377 detId[ibc][nStripsCrossedInPropagation[ibc] - 1][2] = detIdTemp[2];
1378 detId[ibc][nStripsCrossedInPropagation[ibc] - 1][3] = detIdTemp[3];
1379 detId[ibc][nStripsCrossedInPropagation[ibc] - 1][4] = detIdTemp[4];
1380 deltaPos[ibc][nStripsCrossedInPropagation[ibc] - 1][0] = deltaPosTemp[0];
1381 deltaPos[ibc][nStripsCrossedInPropagation[ibc] - 1][1] = deltaPosTemp[1];
1382 deltaPos[ibc][nStripsCrossedInPropagation[ibc] - 1][2] = deltaPosTemp[2];
1384 Zshift[ibc][nStripsCrossedInPropagation[ibc] - 1] = ZshiftCurrent;
1386 nStepsInsideSameStrip[ibc][nStripsCrossedInPropagation[ibc] - 1]++;
1399 for (
int ibc = 0; ibc < BCcand.size(); ibc++) {
1402 for (Int_t imatch = 0; imatch < nStripsCrossedInPropagation[ibc]; imatch++) {
1404 deltaPos[ibc][imatch][0] /= nStepsInsideSameStrip[ibc][imatch];
1405 deltaPos[ibc][imatch][1] /= nStepsInsideSameStrip[ibc][imatch];
1406 deltaPos[ibc][imatch][2] /= nStepsInsideSameStrip[ibc][imatch];
1409 if (nStripsCrossedInPropagation[ibc] == 0) {
1413 bool foundCluster =
false;
1414 for (
auto itof = itof0; itof < itofMax; itof++) {
1416 auto& trefTOF = mTOFClusWork[cacheTOF[itof]];
1419 if (trefTOF.getTime() < minTime) {
1422 if (trefTOF.getTime() > maxTime) {
1426 int mainChannel = trefTOF.getMainContributingChannel();
1430 bool isInStrip =
false;
1431 for (
auto iPropagation = 0; iPropagation < nStripsCrossedInPropagation[ibc]; iPropagation++) {
1432 if (detId[ibc][iPropagation][1] ==
indices[1] && detId[ibc][iPropagation][2] ==
indices[2]) {
1446 float posCorr[3] = {0, 0, 0};
1473 float ndifInv = 1. / ndigits;
1475 posCorr[0] *= ndifInv;
1476 posCorr[1] *= ndifInv;
1477 posCorr[2] *= ndifInv;
1483 for (
auto iPropagation = 0; iPropagation < nStripsCrossedInPropagation[ibc]; iPropagation++) {
1484 if (detId[ibc][iPropagation][1] !=
indices[1] || detId[ibc][iPropagation][2] !=
indices[2]) {
1493 if (tof - trkLTInt[ibc][iPropagation].getTOF(6) > 2000) {
1498 if (std::abs(tof - trkLTInt[ibc][iPropagation].getTOF(2)) < 2000) {
1499 }
else if (std::abs(tof - trkLTInt[ibc][iPropagation].getTOF(3)) < 2000) {
1500 }
else if (std::abs(tof - trkLTInt[ibc][iPropagation].getTOF(4)) < 2000) {
1507 const float errXinvMin = 1. / (mMatchParams->
maxResX * mMatchParams->
maxResX);
1508 const float errZinvMin = 1. / (mMatchParams->
maxResZ * mMatchParams->
maxResZ);
1509 float errXinv2 = 1. / (trefTrk.getSigmaY2());
1510 float errZinv2 = 1. / (trefTrk.getSigmaZ2() * cosangle);
1512 if (errXinv2 < errXinvMin) {
1513 errXinv2 = errXinvMin;
1515 if (errZinv2 < errZinvMin) {
1516 errZinv2 = errZinvMin;
1520 LOG(
debug) <<
"Propagated Track [" << itrk <<
"]: detId[" << iPropagation <<
"] = " << detId[ibc][iPropagation][0] <<
", " << detId[ibc][iPropagation][1] <<
", " << detId[ibc][iPropagation][2] <<
", " << detId[ibc][iPropagation][3] <<
", " << detId[ibc][iPropagation][4];
1521 float resX = deltaPos[ibc][iPropagation][0] - (
indices[4] - detId[ibc][iPropagation][4]) *
Geo::XPAD + posCorr[0];
1522 float resZ = deltaPos[ibc][iPropagation][2] - (
indices[3] - detId[ibc][iPropagation][3]) *
Geo::ZPAD + posCorr[2];
1523 float resY = deltaPos[ibc][iPropagation][1];
1524 if (BCcand[ibc] > bcClus) {
1525 resZ += (BCcand[ibc] - bcClus) * vdriftInBC *
side;
1527 resZ -= (bcClus - BCcand[ibc]) * vdriftInBC *
side;
1529 float resXor = resX;
1530 float resZor = resZ;
1531 float res = TMath::Sqrt(resX * resX + resZ * resZ);
1535 }
else if (resX > 1.25) {
1538 resX = 1E-3 / (pt + 1E-3);
1543 }
else if (resZ > 1.75) {
1546 resZ = 1E-3 / (pt + 1E-3);
1549 if (
indices[0] != detId[ibc][iPropagation][0]) {
1552 if (
indices[1] != detId[ibc][iPropagation][1]) {
1555 if (
indices[2] != detId[ibc][iPropagation][2]) {
1559 LOG(
debug) <<
"resX = " << resX <<
", resZ = " << resZ <<
", res = " <<
res;
1560 float chi2 = mIsCosmics ? resX : 0.5 * (resX * resX * errXinv2 + resZ * resZ * errZinv2);
1562 if (
res < mSpaceTolerance && chi2 < mMatchParams->maxChi2) {
1563 LOG(
debug) <<
"MATCHING FOUND: We have a match! between track " << mTracksSectIndexCache[trkType::UNCONS][sec][itrk] <<
" and TOF cluster " << mTOFClusSectIndexCache[
indices[0]][itof];
1564 foundCluster =
true;
1567 int eventIndexTOFCluster = mTOFClusSectIndexCache[
indices[0]][itof];
1568 mMatchedTracksPairsSec[sec].emplace_back(cacheTrk[itrk], eventIndexTOFCluster, mTOFClusWork[cacheTOF[itof]].
getTime(), chi2, trkLTInt[ibc][iPropagation], mTrackGid[sec][trkType::UNCONS][cacheTrk[itrk]], trkType::UNCONS, trefTOF.getTime() * 1E-6 - tpctime, trefTOF.getZ(), resXor, resZor, resY);
1569 mMatchedTracksPairsSec[sec][mMatchedTracksPairsSec[sec].size() - 1].setPt(pt);
1570 mMatchedTracksPairsSec[sec][mMatchedTracksPairsSec[sec].size() - 1].setResX(sqrt(1. / errXinv2));
1571 mMatchedTracksPairsSec[sec][mMatchedTracksPairsSec[sec].size() - 1].setResZ(sqrt(1. / errZinv2));
1572 mMatchedTracksPairsSec[sec][mMatchedTracksPairsSec[sec].size() - 1].setResT(resT);
1573 mMatchedTracksPairsSec[sec][mMatchedTracksPairsSec[sec].size() - 1].setVz(mVZtpcOnly[sec][itrk] + Zshift[ibc][iPropagation]);
1574 mMatchedTracksPairsSec[sec][mMatchedTracksPairsSec[sec].size() - 1].setChannel(mainChannel);
1588 mHasFillScheme =
true;
1594 if (FITRecPoints.size() == 0) {
1600 bool bestQuality =
false;
1601 const int distThr = 8;
1603 for (
unsigned int i = 0;
i < FITRecPoints.size();
i++) {
1604 const auto& ft = FITRecPoints[
i];
1605 if (!FT0Params.isSelected(ft)) {
1609 if (mHasFillScheme && !mFillScheme[
ir.
bc]) {
1612 bool quality = (std::abs(FITRecPoints[
i].getCollisionTime(0)) < 1000 && std::abs(FITRecPoints[
i].getVertex()) < 1000);
1613 if (bestQuality && !quality) {
1617 int dist =
bc - bct0;
1619 bool worseDistance = dist < 0 || dist > distThr || dist > distMax;
1620 if (worseDistance) {
1624 bestQuality = quality;
1632void MatchTOF::selectBestMatches(
int sec)
1634 if (mSetHighPurity) {
1635 BestMatchesHP(mMatchedTracksPairsSec[sec], mMatchedTracks, mMatchedTracksIndex[sec], mMatchedClustersIndex, mFITRecPoints, mTOFClusWork, mCalibInfoTOF, mTimestamp, mMCTruthON, mTOFClusLabels, mTracksLblWork[sec], mOutTOFLabels);
1638 BestMatches(mMatchedTracksPairsSec[sec], mMatchedTracks, mMatchedTracksIndex[sec], mMatchedClustersIndex, mFITRecPoints, mTOFClusWork, mTracksWork[sec], mCalibInfoTOF, mTimestamp, mMCTruthON, mTOFClusLabels, mTracksLblWork[sec], mOutTOFLabels, mMatchParams->
calibMaxChi2);
1641void MatchTOF::BestMatches(std::vector<o2::dataformats::MatchInfoTOFReco>& matchedTracksPairs, std::vector<o2::dataformats::MatchInfoTOF>* matchedTracks, std::vector<int>* matchedTracksIndex,
int* matchedClustersIndex,
const gsl::span<const o2::ft0::RecPoints>& FITRecPoints,
const std::vector<Cluster>& TOFClusWork,
const std::vector<matchTrack>* TracksWork, std::vector<o2::dataformats::CalibInfoTOF>& CalibInfoTOF,
unsigned long Timestamp,
bool MCTruthON,
const o2::dataformats::MCTruthContainer<o2::MCCompLabel>* TOFClusLabels,
const std::vector<o2::MCCompLabel>* TracksLblWork, std::vector<o2::MCCompLabel>* OutTOFLabels,
float calibMaxChi2)
1651 int trkType = (
int)matchingPair.getTrackType();
1653 int itrk = matchingPair.getIdLocal();
1655 int trkTypeSplitted =
trkType;
1656 auto sourceID = matchingPair.getTrackRef().getSource();
1658 trkTypeSplitted = (
int)trkType::TPCTRD;
1660 trkTypeSplitted = (
int)trkType::ITSTPCTRD;
1663 if (matchedClustersIndex[matchingPair.getTOFClIndex()] != -1) {
1666 if (matchedTracksIndex[
trkType][itrk] != -1) {
1669 int pairInd = matchedTracksIndex[
trkType][itrk];
1670 auto& prevMatching = matchedTracks[trkTypeSplitted][pairInd];
1672 if (pairInd >= matchedTracks[trkTypeSplitted].
size()) {
1673 LOG(error) <<
"Pair index out of range when trying to update TOF time. This should not happen";
1677 int istripOld = TOFClusWork[prevMatching.getTOFClIndex()].getMainContributingChannel() /
o2::tof::Geo::NPADS;
1678 int istripNew = TOFClusWork[matchingPair.getTOFClIndex()].getMainContributingChannel() /
o2::tof::Geo::NPADS;
1680 if (istripOld != istripNew) {
1684 const float cinv = 1.E+10 / TMath::C();
1685 float deltaT = (intLTnew.getL() - intLTold.getL()) * cinv;
1687 float timeNew = TOFClusWork[matchingPair.getTOFClIndex()].getTime() - deltaT;
1688 float timeOld = TOFClusWork[prevMatching.getTOFClIndex()].getTime();
1690 if (std::abs(timeNew - timeOld) < 200) {
1692 prevMatching.setSignal((timeNew + timeOld) * 0.5);
1693 float geanttime = (TOFClusWork[matchingPair.getTOFClIndex()].getTgeant() + TOFClusWork[prevMatching.getTOFClIndex()].getTgeant() - deltaT * 1E-3) * 0.5;
1694 double t0 = (TOFClusWork[matchingPair.getTOFClIndex()].getT0true() + TOFClusWork[prevMatching.getTOFClIndex()].getT0true()) * 0.5;
1695 prevMatching.setTgeant(geanttime);
1696 prevMatching.setT0true(
t0);
1697 prevMatching.setChi2(0);
1698 matchedClustersIndex[matchingPair.getTOFClIndex()] = matchedTracksIndex[
trkType][itrk];
1705 matchedTracksIndex[
trkType][itrk] = matchedTracks[trkTypeSplitted].size();
1706 matchedClustersIndex[matchingPair.getTOFClIndex()] = matchedTracksIndex[
trkType][itrk];
1708 matchingPair.setTgeant(TOFClusWork[matchingPair.getTOFClIndex()].getTgeant());
1709 matchingPair.setT0true(TOFClusWork[matchingPair.getTOFClIndex()].getT0true());
1712 const auto& tofcl = TOFClusWork[matchingPair.getTOFClIndex()];
1713 if (tofcl.getNumOfContributingChannels() > 1) {
1715 matchingPair.setHitPatternUpDown(tofcl.isAdditionalChannelSet(o2::tof::Cluster::kUp) ||
1716 tofcl.isAdditionalChannelSet(o2::tof::Cluster::kUpLeft) ||
1717 tofcl.isAdditionalChannelSet(o2::tof::Cluster::kUpRight) ||
1718 tofcl.isAdditionalChannelSet(o2::tof::Cluster::kDown) ||
1719 tofcl.isAdditionalChannelSet(o2::tof::Cluster::kDownLeft) ||
1720 tofcl.isAdditionalChannelSet(o2::tof::Cluster::kDownRight));
1722 matchingPair.setHitPatternLeftRight(tofcl.isAdditionalChannelSet(o2::tof::Cluster::kLeft) ||
1723 tofcl.isAdditionalChannelSet(o2::tof::Cluster::kDownLeft) ||
1724 tofcl.isAdditionalChannelSet(o2::tof::Cluster::kUpLeft) ||
1725 tofcl.isAdditionalChannelSet(o2::tof::Cluster::kRight) ||
1726 tofcl.isAdditionalChannelSet(o2::tof::Cluster::kDownRight) ||
1727 tofcl.isAdditionalChannelSet(o2::tof::Cluster::kUpRight));
1733 float t0BestRes = 200;
1734 if (FITRecPoints.size() > 0) {
1736 if (
index > -1 && FITRecPoints[
index].isValidTime(1) && FITRecPoints[
index].isValidTime(2)) {
1737 t0Best += FITRecPoints[
index].getCollisionTime(0);
1741 matchingPair.setFT0Best(t0Best, t0BestRes);
1742 matchedTracks[trkTypeSplitted].push_back(matchingPair);
1749 if (FITRecPoints.size() > 0 && mIsFIT) {
1757 }
else if (!mIsFIT) {
1778 if (t0info > 0 && mIsFIT) {
1781 }
else if (!mIsFIT) {
1786 float pt = trc.getPt();
1800 if (TOFClusWork[matchingPair.getTOFClIndex()].getNumOfContributingChannels() != 1) {
1804 if (matchingPair.getChi2() < calibMaxChi2 && t0info > 0) {
1805 CalibInfoTOF.emplace_back(TOFClusWork[matchingPair.getTOFClIndex()].getMainContributingChannel(),
1806 Timestamp / 1000 +
int(TOFClusWork[matchingPair.getTOFClIndex()].getTimeRaw() * 1E-12),
1808 TOFClusWork[matchingPair.getTOFClIndex()].getTot(),
mask,
flags);
1812 const auto& labelsTOF = TOFClusLabels->
getLabels(matchingPair.getTOFClIndex());
1813 auto& labelTrack = TracksLblWork[
trkType][itrk];
1816 for (
auto& lbl : labelsTOF) {
1817 if (labelTrack == lbl) {
1821 OutTOFLabels[trkTypeSplitted].emplace_back(labelTrack).setFakeFlag(fake);
1827void MatchTOF::BestMatchesHP(std::vector<o2::dataformats::MatchInfoTOFReco>& matchedTracksPairs, std::vector<o2::dataformats::MatchInfoTOF>* matchedTracks, std::vector<int>* matchedTracksIndex,
int* matchedClustersIndex,
const gsl::span<const o2::ft0::RecPoints>& FITRecPoints,
const std::vector<Cluster>& TOFClusWork, std::vector<o2::dataformats::CalibInfoTOF>& CalibInfoTOF,
unsigned long Timestamp,
bool MCTruthON,
const o2::dataformats::MCTruthContainer<o2::MCCompLabel>* TOFClusLabels,
const std::vector<o2::MCCompLabel>* TracksLblWork, std::vector<o2::MCCompLabel>* OutTOFLabels)
1830 float chi2SeparationCut = 2;
1833 std::vector<o2::dataformats::MatchInfoTOFReco> tmpMatch;
1840 int trkType = (
int)matchingPair.getTrackType();
1842 int itrk = matchingPair.getIdLocal();
1844 bool discard = matchingPair.getChi2() > chi2S;
1846 if (matchedTracksIndex[
trkType][itrk] != -1) {
1847 auto winnerChi = tmpMatch[matchedTracksIndex[
trkType][itrk]].getChi2();
1848 if (winnerChi < 0) {
1851 if (matchingPair.getChi2() - winnerChi < chi2SeparationCut) {
1852 tmpMatch[matchedTracksIndex[
trkType][itrk]].setChi2(-1);
1857 if (matchedClustersIndex[matchingPair.getTOFClIndex()] != -1) {
1858 auto winnerChi = tmpMatch[matchedClustersIndex[matchingPair.getTOFClIndex()]].getChi2();
1859 if (winnerChi < 0) {
1862 if (matchingPair.getChi2() - winnerChi < chi2SeparationCut) {
1863 tmpMatch[matchedClustersIndex[matchingPair.getTOFClIndex()]].setChi2(-1);
1869 matchedTracksIndex[
trkType][itrk] = tmpMatch.size();
1870 matchedClustersIndex[matchingPair.getTOFClIndex()] = matchedTracksIndex[
trkType][itrk];
1871 tmpMatch.push_back(matchingPair);
1876 for (
auto& matchingPair : tmpMatch) {
1877 if (matchingPair.getChi2() <= 0) {
1880 int trkType = (
int)matchingPair.getTrackType();
1881 int itrk = matchingPair.getIdLocal();
1883 int trkTypeSplitted =
trkType;
1884 auto sourceID = matchingPair.getTrackRef().getSource();
1886 trkTypeSplitted = (
int)trkType::TPCTRD;
1888 trkTypeSplitted = (
int)trkType::ITSTPCTRD;
1890 matchedTracks[trkTypeSplitted].push_back(matchingPair);
1897 if (FITRecPoints.size() > 0 && mIsFIT) {
1913 CalibInfoTOF.emplace_back(TOFClusWork[matchingPair.getTOFClIndex()].getMainContributingChannel(),
1914 Timestamp / 1000 +
int(TOFClusWork[matchingPair.getTOFClIndex()].getTimeRaw() * 1E-12),
1915 TOFClusWork[matchingPair.getTOFClIndex()].getTimeRaw() - t0info - intLT.getTOF(
o2::track::PID::Pion),
1916 TOFClusWork[matchingPair.getTOFClIndex()].getTot(), 0);
1920 const auto& labelsTOF = TOFClusLabels->
getLabels(matchingPair.getTOFClIndex());
1921 auto& labelTrack = TracksLblWork[
trkType][itrk];
1924 for (
auto& lbl : labelsTOF) {
1925 if (labelTrack == lbl) {
1929 OutTOFLabels[trkTypeSplitted].emplace_back(labelTrack).setFakeFlag(fake);
1939 bool refReached =
false;
1940 float xStart = trc.getX();
1947 while (hasPropagated) {
1948 if (trc.getX() > xRef) {
1952 if (std::abs(trc.getY()) > trc.getX() * tanHalfSector) {
1956 if (!trc.rotate(alphaNew) != 0) {
1969 return refReached && std::abs(trc.getSnp()) < 0.95;
1972bool MatchTOF::propagateToRefXWithoutCov(
const o2::track::TrackParCov& trc,
float xRef,
float stepInCm,
float bzField)
1978 bool refReached =
false;
1979 float xStart = trcNoCov.getX();
1985 bool hasPropagated = trcNoCov.propagateParamTo(xStart + istep * stepInCm, bzField);
1986 while (hasPropagated) {
1987 if (trcNoCov.getX() > xRef) {
1991 if (std::abs(trcNoCov.getY()) > trcNoCov.getX() * tanHalfSector) {
1995 if (!trcNoCov.rotateParam(alphaNew) != 0) {
2003 hasPropagated = trcNoCov.propagateParamTo(xStart + istep * stepInCm, bzField);
2008 return refReached && std::abs(trcNoCov.getSnp()) < 0.95 && std::abs(trcNoCov.getZ()) <
Geo::MAXHZTOF;
2013 for (
int i = 0;
i < intLT.getNTOFs();
i++) {
2014 float betainv = intLT.getTOF(
i) / intLT.getL();
2015 intLT.setTOF(intLT.getTOF(
i) + deltal * betainv,
i);
2017 intLT.setL(intLT.getL() + deltal);
2021bool MatchTOF::propagateToRefXWithoutCov(
const o2::track::TrackParCov& trc,
float xRef,
float stepInCm,
float bzField,
float pos[3])
2027 bool refReached =
false;
2028 float xStart = trcNoCov.getX();
2034 bool hasPropagated = trcNoCov.propagateParamTo(xStart + istep * stepInCm, bzField);
2035 while (hasPropagated) {
2036 if (trcNoCov.getX() > xRef) {
2040 if (fabs(trcNoCov.getY()) > trcNoCov.getX() * tanHalfSector) {
2044 if (!trcNoCov.rotateParam(alphaNew) != 0) {
2052 hasPropagated = trcNoCov.propagateParamTo(xStart + istep * stepInCm, bzField);
2058 trcNoCov.getXYZGlo(xyz);
2063 return refReached && std::abs(trcNoCov.getSnp()) < 0.95 && TMath::Abs(trcNoCov.getZ()) <
Geo::MAXHZTOF;
2077void MatchTOF::updateTimeDependentParams()
2081 mTPCTBinMUS = elParam.ZbinWidth;
2082 mTPCTBinMUSInv = 1. / mTPCTBinMUS;
2083 mTPCBin2Z = mTPCTBinMUS * mTPCVDrift;
2086 mMaxInvPt = std::abs(mBz) > 0.1 ? 1. / (std::abs(mBz) * 0.05) : 999.;
2089 float scale = mCTPLumi;
2091 LOGP(warning,
"Negative scale factor for TPC covariance correction, setting it to zero");
2094 mCovDiagInner = trackTune.getCovInnerTotal(scale);
2095 mCovDiagOuter = trackTune.getCovOuterTotal(scale);
2101 auto&
match = mMatchedTracks[trkType::TPC][matchedID];
2103 const auto& tofCl = mTOFClustersArrayInp[
match.getTOFClIndex()];
2104 const auto& intLT =
match.getLTIntegralOut();
2107 auto timeTOFMUS = (tofCl.getTime() - intLT.getTOF(tpcTrOrig.getPID())) * 1e-6;
2108 auto timeTOFTB = timeTOFMUS * mTPCTBinMUSInv;
2109 auto deltaTBins = timeTOFTB - tpcTrOrig.getTime0();
2110 float timeErr = 0.010;
2111 auto dzCorr = deltaTBins * mTPCBin2Z;
2113 if (mTPCClusterIdxStruct) {
2114 trConstr.o2::track::TrackParCov::operator=(tpcTrOrig.getOuterParam());
2117 trConstr.o2::track::TrackParCov::operator=(tpcTrOrig);
2123 auto zTrack = trConstr.getZ();
2124 auto zTrackOut = trConstrOut.getZ();
2126 if (tpcTrOrig.hasASideClustersOnly()) {
2128 zTrackOut += dzCorr;
2129 }
else if (tpcTrOrig.hasCSideClustersOnly()) {
2131 zTrackOut -= dzCorr;
2135 trConstr.setZ(zTrack);
2136 trConstrOut.setZ(zTrackOut);
2140 if (mTPCClusterIdxStruct) {
2143 if (mTPCRefitter->RefitTrackAsTrackParCov(trConstr, tpcTrOrig.getClusterRef(), timeTOFTB, &chi2,
false,
true) < 0) {
2144 LOGP(
debug,
"Inward Refit failed {}", trConstr.asString());
2148 if (!trackTune.useTPCInnerCorr) {
2149 trConstr.updateParams(trackTune.tpcParInner);
2158 if (mTPCRefitter->RefitTrackAsTrackParCov(trConstrOut, tpcTrOrig.getClusterRef(), timeTOFTB, &chi2,
true,
true) < 0) {
2159 LOGP(
debug,
"Outward Refit failed {}", trConstrOut.asString());
2170 if (mTPCClusterIdxStruct) {
2171 mTPCRefitter = std::make_unique<o2::gpu::GPUO2InterfaceRefit>(mTPCClusterIdxStruct, mTPCCorrMaps, mBz,
2172 mTPCTrackClusIdx.data(), 0, mTPCRefitterShMap.data(),
header::DataOrigin origin
General auxilliary methods.
Definition of the GeometryManager class.
Header of the General Run Parameters object.
Some ALICE geometry constants of common interest.
Definition of a container to keep Monte Carlo truth external to simulation objects.
Definition of the fast magnetic field parametrization MagFieldFast.
Definition of the MagF class.
Class to perform TOF matching to global tracks.
Definition of the parameter class for the detector electronics.
Definition of the parameter class for the detector gas.
Header to collect physics constants.
Wrapper container for different reconstructed object types.
Track Length and TOF integral.
Configurable params for tracks ad hoc tuning.
calibration data from laser track calibration
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
static const MatchTOFParams & Instance()
void setTPCVDrift(const o2::tpc::VDriftCorrFact &v)
void printCandidatesTOF() const
set time tolerance on track-TOF times comparison
void setTPCCorrMaps(const o2::gpu::TPCFastTransformPOD *maph, float lumi)
void run(const o2::globaltracking::RecoContainer &inp, unsigned long firstTForbit=0)
< perform matching for provided input
void setDebugFlag(UInt_t flag, bool on=true)
set the name of output debug file
static void groupingMatch(const std::vector< o2::dataformats::MatchInfoTOFReco > &origin, std::vector< std::vector< o2::dataformats::MatchInfoTOFReco > > &grouped, std::vector< std::vector< int > > &firstEls, std::vector< std::vector< int > > &secondEls)
static void printGrouping(const std::vector< o2::dataformats::MatchInfoTOFReco > &origin, const std::vector< std::vector< o2::dataformats::MatchInfoTOFReco > > &grouped)
static int findFITIndex(int bc, const gsl::span< const o2::ft0::RecPoints > &FITRecPoints, unsigned long firstOrbit)
bool makeConstrainedTPCTrack(int matchedID, o2::dataformats::TrackTPCTOF &trConstr)
populate externally provided container by TOF-time-constrained TPC tracks
HMPID cluster implementation.
static constexpr Float_t RMAX
static constexpr Float_t ZPAD
static constexpr Float_t XPAD
static constexpr Double_t BC_TIME_INPS
static constexpr Double_t BC_TIME_INPS_INV
static Float_t getAngles(Int_t iplate, Int_t istrip)
static constexpr Int_t NPADS
static constexpr Int_t LATENCYWINDOW_IN_BC
static constexpr Float_t MAXHZTOF
static void getVolumeIndices(Int_t index, Int_t *detId)
static void getPadDxDyDz(const Float_t *pos, Int_t *det, Float_t *DeltaPos, int sector=-1)
static double subtractInteractionBC(double time, int &mask, bool subLatency=false)
static int getNinteractionBC()
static bool hasFillScheme()
static int getInteractionBC(int ibc)
std::array< value_t, 3 > dim3_t
bool match(const std::vector< std::string > &queries, const char *pattern)
GLboolean GLboolean GLboolean b
GLint GLint GLsizei GLint GLenum GLenum type
GLsizei GLenum const void * indices
GLuint GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat GLfloat t0
GLboolean GLboolean GLboolean GLboolean a
constexpr float XTPCOuterRef
reference radius to propagate outer TPC track
constexpr float XTPCInnerRef
reference radius at which TPC provides the tracks
constexpr int LHCMaxBunches
constexpr float SectorSpanRad
float angle2Alpha(float phi)
int angle2Sector(float phi)
Enum< T >::Iterator begin(Enum< T >)
std::string getTime(uint64_t ts)
uint16_t bc
bunch crossing ID of interaction
o2::InteractionRecord startIR
const o2::tpc::TrackTPC & getTPCTrack(GTrackID id) const
auto getTPCITSTrackMCLabel(GTrackID id) const
void createTracksVariadic(T creator, GTrackID::mask_t srcSel=GTrackID::getSourcesMask("all")) const
auto getTPCTracksClusterRefs() const
auto getTPCTrackMCLabel(GTrackID id) const
auto getTOFClustersMCLabels() const
auto getTOFClusters() const
gsl::span< const unsigned char > clusterShMapTPC
externally set TPC clusters sharing map
auto getFT0RecPoints() const
std::unique_ptr< o2::tpc::internal::getWorkflowTPCInput_ret > inputsTPCclusters
auto getTPCTracks() const
gsl::span< const unsigned int > occupancyMapTPC
externally set TPC clusters occupancy map
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
o2::InteractionRecord ir(0, 0)