337 LOG(error) <<
"Initialization not yet done. Aborting...";
346 mNTPCOccBinLength = mTPCParam->rec.tpc.occupancyMapTimeBins;
347 mNTPCOccBinLengthInv = 1.f / mNTPCOccBinLength;
350 LOG(error) <<
"No ITS dictionary available";
356 auto pattIt = patterns.begin();
357 mITSClustersArray.clear();
358 mITSClustersArray.reserve(clusITS.size());
359 LOGP(info,
"We have {} ITS clusters and the number of patterns is {}", clusITS.size(), patterns.size());
367 std::random_device
rd;
368 std::mt19937
g(
rd());
369 std::vector<uint32_t> trackIndices;
378 int nSeeds = mSeeds.size(), lastChecked = 0;
380 mParentID.resize(nSeeds, -1);
382 int maxOutputTracks = (mMaxTracksPerTF >= 0) ? mMaxTracksPerTF + mAddTracksForMapPerTF : nSeeds;
383 mTrackData.reserve(maxOutputTracks);
384 mClRes.reserve(maxOutputTracks * param::NPadRows);
385 mDetInfoRes.reserve(maxOutputTracks * param::NPadRows);
386 bool maxTracksReached =
false;
387 for (
int iSeed = 0; iSeed < nSeeds; ++iSeed) {
388 if (mMaxTracksPerTF >= 0 && mTrackDataCompact.size() >= mMaxTracksPerTF + mAddTracksForMapPerTF) {
389 LOG(info) <<
"Maximum number of tracks per TF reached. Skipping the remaining " << nSeeds - iSeed <<
" tracks.";
392 int seedIndex = trackIndices[iSeed];
397 this->mGIDs.push_back(this->mGIDtables[seedIndex][
src]);
399 this->mTrackTimes.push_back(this->mTrackTimes[seedIndex]);
400 this->mSeeds.push_back(this->mSeeds[seedIndex]);
401 this->mParentID.push_back(seedIndex);
402 this->mTrackPVID.push_back(this->mTrackPVID[seedIndex]);
406 if (!mSingleSourcesConfigured && !mSourcesConfiguredMap[mGIDs[seedIndex].getSource()]) {
413 if (mMaxTracksPerTF >= 0 && mTrackDataCompact.size() >= mMaxTracksPerTF) {
414 if (!maxTracksReached) {
415 LOGP(info,
"We already have reached mMaxTracksPerTF={}, but we continue to create seeds until mAddTracksForMapPerTF={} is also reached, iSeed: {} of {} inital seeds", mMaxTracksPerTF, mAddTracksForMapPerTF, iSeed, nSeeds);
417 maxTracksReached =
true;
422 LOGP(
debug,
"interpolateTrack {} {}, accepted: {}", iSeed,
GTrackID::getSourceName(mGIDs[seedIndex].getSource()), mTrackDataCompact.size());
433 LOGP(
debug,
"extrapolateTrack {} {}, accepted: {}", iSeed,
GTrackID::getSourceName(mGIDs[seedIndex].getSource()), mTrackDataCompact.size());
437 std::vector<int> remSeeds;
438 if (mSeeds.size() > ++lastChecked) {
439 remSeeds.resize(mSeeds.size() - lastChecked);
440 std::iota(remSeeds.begin(), remSeeds.end(), lastChecked);
441 std::shuffle(remSeeds.begin(), remSeeds.end(),
g);
442 LOGP(info,
"Up to {} tracks out of {} additional seeds will be processed in random order, of which {} are stripped versions, accepted seeds: {}",
443 mAddTracksForMapPerTF > 0 ? mAddTracksForMapPerTF : remSeeds.size(),
444 remSeeds.size(), mSeeds.size() - nSeeds, mTrackDataCompact.size());
446 int extraChecked = 0;
447 for (
int iSeed : remSeeds) {
448 if (mAddTracksForMapPerTF > 0 && mTrackDataCompact.size() >= mMaxTracksPerTF + mAddTracksForMapPerTF) {
449 LOGP(info,
"Maximum number {} of additional tracks per TF reached. Skipping the remaining {} tracks", mAddTracksForMapPerTF, remSeeds.size() - extraChecked);
455 LOGP(
debug,
"extra check {} of {}, seed {} interpolateTrack {}, used: {}", extraChecked, remSeeds.size(), iSeed,
GTrackID::getSourceName(mGIDs[iSeed].getSource()), mTrackDataCompact.size());
457 LOGP(
debug,
"extra check {} of {}, seed {} extrapolateTrack {}, used: {}", extraChecked, remSeeds.size(), iSeed,
GTrackID::getSourceName(mGIDs[iSeed].getSource()), mTrackDataCompact.size());
461 LOGP(info,
"Could process {} tracks successfully ({} rejected in refits, {} in propagation, {} as loopers), {} residuals were rejected, {} accepted",
462 mTrackData.size(), mNRejRefit, mNRejProp, mNRejLoop, mRejectedResiduals, mClRes.size());
463 mRejectedResiduals = 0;
471 LOGP(
debug,
"Starting track interpolation for GID {}", mGIDs[iSeed].
asString());
475 std::unique_ptr<TrackDataExtended> trackDataExtended;
476 std::vector<TPCClusterResiduals> clusterResiduals;
478 const auto& gidTable = mGIDtables[iSeed];
481 if (mDumpTrackPoints) {
482 trackDataExtended = std::make_unique<TrackDataExtended>();
483 (*trackDataExtended).gid = mGIDs[iSeed];
484 (*trackDataExtended).clIdx.setFirstEntry(mClRes.size());
485 (*trackDataExtended).trkITS = trkITS;
486 (*trackDataExtended).trkTPC = trkTPC;
487 auto nCl = trkITS.getNumberOfClusters();
488 auto clEntry = trkITS.getFirstClusterEntry();
489 for (
int iCl = nCl - 1; iCl >= 0; iCl--) {
490 const auto& clsITS = mITSClustersArray[mITSTrackClusIdx[clEntry + iCl]];
491 (*trackDataExtended).clsITS.push_back(clsITS);
498 trackData.
gid = mGIDs[iSeed];
499 trackData.
par = mSeeds[iSeed];
500 auto trkWork = mSeeds[iSeed];
503 for (
auto& elem : mCache) {
504 elem.clAvailable = 0;
506 trackData.
clIdx.setFirstEntry(mClRes.size());
507 float clusterTimeBinOffset = mTrackTimes[iSeed] / mTPCTimeBinMUS;
511 std::array<short, constants::MAXGLOBALPADROW> multBins{};
512 for (
int iCl = trkTPC.getNClusterReferences(); iCl--;) {
514 uint32_t clusterIndexInRow;
515 trkTPC.getClusterReference(mTPCTrackClusIdx, iCl, sector,
row, clusterIndexInRow);
516 unsigned int absoluteIndex = mTPCClusterIdxStruct->
clusterOffset[sector][
row] + clusterIndexInRow;
517 const auto& clTPC = mTPCClusterIdxStruct->
clustersLinear[absoluteIndex];
519 std::array<float, 2> clTPCYZ;
520 mFastTransform->TransformIdeal(sector,
row, clTPC.getPad(), clTPC.getTime(), clTPCX, clTPCYZ[0], clTPCYZ[1], clusterTimeBinOffset);
521 mCache[
row].clSec = sector;
522 mCache[
row].clAvailable = 1;
523 mCache[
row].clY = clTPCYZ[0];
524 mCache[
row].clZ = clTPCYZ[1];
526 mCache[
row].clFlags = clTPC.getFlags();
530 mCacheDEDX[
row].first = std::min<uint16_t>(clTPC.getQtot(), UINT16_MAX);
531 mCacheDEDX[
row].second = clTPC.getQmax();
532 int imb =
int(clTPC.getTime() * mNTPCOccBinLengthInv);
533 if (imb < mTPCParam->occupancyMapSize) {
534 multBins[
row] = 1 + std::max(0, imb);
539 for (
int iRow = 0; iRow < param::NPadRows; ++iRow) {
540 if (!mCache[iRow].clAvailable) {
543 if (!trkWork.rotate(mCache[iRow].clAngle)) {
544 LOG(
debug) <<
"Failed to rotate track during first extrapolation";
548 if (!propagator->PropagateToXBxByBz(trkWork, param::RowX[iRow], mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
549 LOG(
debug) <<
"Failed on first extrapolation";
553 mCache[iRow].y[
ExtOut] = trkWork.getY();
554 mCache[iRow].z[
ExtOut] = trkWork.getZ();
555 mCache[iRow].sy2[
ExtOut] = trkWork.getSigmaY2();
556 mCache[iRow].szy[
ExtOut] = trkWork.getSigmaZY();
557 mCache[iRow].sz2[
ExtOut] = trkWork.getSigmaZ2();
558 mCache[iRow].snp[
ExtOut] = trkWork.getSnp();
564 LOG(
debug) <<
"TOF point available";
566 if (mDumpTrackPoints) {
567 (*trackDataExtended).clsTOF = clTOF;
568 (*trackDataExtended).matchTOF = mRecoCont->
getTOFMatch(mGIDs[iSeed]);
570 const int clTOFSec = clTOF.getCount();
572 if (!trkWork.rotate(clTOFAlpha)) {
573 LOG(
debug) <<
"Failed to rotate into TOF cluster sector frame";
577 float clTOFxyz[3] = {clTOF.getX(), clTOF.getY(), clTOF.getZ()};
578 if (!clTOF.isInNominalSector()) {
581 std::array<float, 2> clTOFYZ{clTOFxyz[1], clTOFxyz[2]};
583 if (!propagator->PropagateToXBxByBz(trkWork, clTOFxyz[0], mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
584 LOG(
debug) <<
"Failed final propagation to TOF radius";
589 if (!trkWork.update(clTOFYZ, clTOFCov)) {
590 LOG(
debug) <<
"Failed to update extrapolated ITS track with TOF cluster";
599 if (mDumpTrackPoints) {
600 (*trackDataExtended).trkTRD = trkTRD;
603 std::array<float, 2> trkltTRDYZ{};
604 std::array<float, 3> trkltTRDCov{};
612 if (!trkWork.update(trkltTRDYZ, trkltTRDCov)) {
613 LOG(
debug) <<
"Failed to update track at TRD layer " << iLayer;
620 if (mDumpTrackPoints) {
621 (*trackDataExtended).trkOuter = trkWork;
623 auto trkOuter = trkWork;
626 bool outerParamStored =
false;
627 for (
int iRow = param::NPadRows; iRow--;) {
628 if (!mCache[iRow].clAvailable) {
631 if (mProcessSeeds && !outerParamStored) {
637 trackData.
par = trkWork;
638 outerParamStored =
true;
640 if (!trkWork.rotate(mCache[iRow].clAngle)) {
641 LOG(
debug) <<
"Failed to rotate track during back propagation";
645 if (!propagator->PropagateToXBxByBz(trkWork, param::RowX[iRow], mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
646 LOG(
debug) <<
"Failed on back propagation";
651 mCache[iRow].y[
ExtIn] = trkWork.getY();
652 mCache[iRow].z[
ExtIn] = trkWork.getZ();
653 mCache[iRow].sy2[
ExtIn] = trkWork.getSigmaY2();
654 mCache[iRow].szy[
ExtIn] = trkWork.getSigmaZY();
655 mCache[iRow].sz2[
ExtIn] = trkWork.getSigmaZ2();
656 mCache[iRow].snp[
ExtIn] = trkWork.getSnp();
660 unsigned short deltaRow = 0;
661 for (
int iRow = 0; iRow < param::NPadRows; ++iRow) {
662 if (!mCache[iRow].clAvailable) {
666 float wTotY = 1.f / mCache[iRow].sy2[
ExtOut] + 1.f / mCache[iRow].sy2[
ExtIn];
667 float wTotZ = 1.f / mCache[iRow].sz2[
ExtOut] + 1.f / mCache[iRow].sz2[
ExtIn];
668 mCache[iRow].y[
Int] = (mCache[iRow].y[
ExtOut] / mCache[iRow].sy2[
ExtOut] + mCache[iRow].y[
ExtIn] / mCache[iRow].sy2[
ExtIn]) / wTotY;
669 mCache[iRow].z[
Int] = (mCache[iRow].z[
ExtOut] / mCache[iRow].sz2[
ExtOut] + mCache[iRow].z[
ExtIn] / mCache[iRow].sz2[
ExtIn]) / wTotZ;
672 mCache[iRow].snp[
Int] = (mCache[iRow].snp[
ExtOut] + mCache[iRow].snp[
ExtIn]) / 2.f;
674 const auto dY = mCache[iRow].clY - mCache[iRow].y[
Int];
675 const auto dZ = mCache[iRow].clZ - mCache[iRow].z[
Int];
676 const auto y = mCache[iRow].y[
Int];
677 const auto z = mCache[iRow].z[
Int];
678 const auto snp = mCache[iRow].snp[
Int];
679 const auto sec = mCache[iRow].clSec;
680 clusterResiduals.emplace_back(dY, dZ,
y,
z, snp, sec, deltaRow, mCache[iRow].clFlags);
685 trackData.
chi2TPC = trkTPC.getChi2();
686 trackData.
chi2ITS = trkITS.getChi2();
687 trackData.
nClsTPC = trkTPC.getNClusterReferences();
688 trackData.
nClsITS = trkITS.getNumberOfClusters();
691 double t0forTOF = 0.;
692 float t0forTOFwithinBC = 0.f;
693 float t0forTOFres = 9999.f;
696 const auto& tofMatch = mRecoCont->
getTOFMatch(mGIDs[iSeed]);
700 t0forTOFres = tofMatch.getFT0BestRes();
701 trackData.
deltaTOF = tofMatch.getSignal() - t0forTOF - tofMatch.getLTIntegralOut().getTOF(trkTPC.getPID().getID());
706 trackData.
dEdxTPC = trkTPC.getdEdx().dEdxTotTPC;
708 mTrackValidation.
clear();
713 int nClValidated = 0;
715 for (
unsigned int iCl = 0; iCl < clusterResiduals.size(); ++iCl) {
716 iRow += clusterResiduals[iCl].dRow;
717 const auto rej = trackData.
filterFlag < 0 ? false : mTrackValidation.
points[iCl].flagRej;
721 const float tgPhi = clusterResiduals[iCl].snp / std::sqrt((1.f - clusterResiduals[iCl].snp) * (1.f + clusterResiduals[iCl].snp));
722 const auto dy = clusterResiduals[iCl].dy;
723 const auto dz = clusterResiduals[iCl].dz;
724 const auto y = clusterResiduals[iCl].y;
725 const auto z = clusterResiduals[iCl].z;
726 const auto sec = clusterResiduals[iCl].sec;
727 const short flags = clusterResiduals[iCl].flags;
728 if ((std::abs(dy) < param::MaxResid) && (std::abs(dz) < param::MaxResid) && (std::abs(
y) < param::MaxY) && (std::abs(
z) < param::MaxZ) && (std::abs(tgPhi) < param::MaxTgSlp)) {
729 mClRes.emplace_back(dy, dz, tgPhi,
y,
z, iRow, sec,
flags, rej);
730 mDetInfoRes.emplace_back().setTPC(mCacheDEDX[iRow].
first, mCacheDEDX[iRow].second);
733 ++mRejectedResiduals;
736 trackData.
clIdx.setEntries(nClValidated);
739 for (
int ist = 0; ist < NSTACKS; ist++) {
740 int mltBinMin = 0x7ffff, mltBinMax = -1, prevBin = -1;
741 for (
int ir = STACKROWS[ist];
ir < STACKROWS[ist + 1];
ir++) {
742 if (multBins[
ir] != prevBin && multBins[
ir] > 0) {
743 prevBin = multBins[
ir];
744 if (multBins[
ir] > mltBinMax) {
745 mltBinMax = multBins[
ir];
747 if (multBins[
ir] < mltBinMin) {
748 mltBinMin = multBins[
ir];
752 if (--mltBinMin >= 0) {
754 for (
int ib = mltBinMin; ib < mltBinMax; ib++) {
755 avMlt += mTPCParam->occupancyMap[ib];
757 avMlt /= (mltBinMax - mltBinMin);
762 bool stopPropagation = !mExtDetResid;
763 if (!stopPropagation) {
769 std::array<float, 2> trkltTRDYZ{};
770 int res =
processTRDLayer(trkTRD, iLayer, trkWork, &trkltTRDYZ,
nullptr, &trackData, &trkl64, &trklCalib);
775 stopPropagation =
true;
779 float tgPhi = trkWork.getSnp() / std::sqrt((1.f - trkWork.getSnp()) * (1.f + trkWork.getSnp()));
780 auto dy = trkltTRDYZ[0] - trkWork.getY();
781 auto dz = trkltTRDYZ[1] - trkWork.getZ();
782 if ((std::abs(dy) < param::MaxResid) && (std::abs(dz) < param::MaxResid) && (std::abs(trkWork.getY()) < param::MaxY) && (std::abs(trkWork.getZ()) < param::MaxZ) && (std::abs(tgPhi) < param::MaxTgSlp)) {
784 mDetInfoRes.emplace_back().setTRD(trkl64.getQ0(), trkl64.getQ1(), trkl64.getQ2(), trklCalib.getDy());
791 while (gidTable[
GTrackID::TOF].isIndexSet() && !stopPropagation) {
793 float clTOFxyz[3] = {clTOF.getX(), clTOF.getY(), clTOF.getZ()};
794 if (!clTOF.isInNominalSector()) {
798 if (trkWork.getAlpha() != clTOFAlpha && !trkWork.rotate(clTOFAlpha)) {
799 LOG(
debug) <<
"Failed to rotate into TOF cluster sector frame";
800 stopPropagation =
true;
803 if (!propagator->PropagateToXBxByBz(trkWork, clTOFxyz[0], mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
804 LOG(
debug) <<
"Failed final propagation to TOF radius";
808 float tgPhi = trkWork.getSnp() / std::sqrt((1.f - trkWork.getSnp()) * (1.f + trkWork.getSnp()));
809 auto dy = clTOFxyz[1] - trkWork.getY();
810 auto dz = clTOFxyz[2] - trkWork.getZ();
813 if ((std::abs(dy) < param::MaxResid) && (std::abs(dz) < param::MaxResid) && (std::abs(trkWork.getY()) < param::MaxY) && (std::abs(trkWork.getZ()) < param::MaxZ) && (std::abs(tgPhi) < param::MaxTgSlp)) {
814 mClRes.emplace_back(dy, dz, tgPhi, trkWork.getY(), trkWork.getZ(), 170, clTOF.getCount(), clTOF.getPadInSector());
817 LOGP(fatal,
"ITS-TPC seed index is not set for TOF track");
819 float tdif =
static_cast<float>(clTOF.getTime() - t0forTOF);
820 mDetInfoRes.emplace_back().setTOF(tdif * 1e-6);
827 while (!stopPropagation) {
828 auto& trkWorkITS = trkInner;
829 auto nCl = trkITS.getNumberOfClusters();
830 auto clEntry = trkITS.getFirstClusterEntry();
832 for (
int iCl = 0; iCl < nCl; iCl++) {
833 const auto& cls = mITSClustersArray[mITSTrackClusIdx[clEntry + iCl]];
834 int chip = cls.getSensorID();
835 float chipX, chipAlpha;
836 geom->getSensorXAlphaRefPlane(cls.getSensorID(), chipX, chipAlpha);
837 if (!trkWorkITS.rotate(chipAlpha) || !propagator->PropagateToXBxByBz(trkWorkITS, chipX, mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
838 LOGP(
debug,
"Failed final propagation to ITS X={} alpha={}", chipX, chipAlpha);
839 stopPropagation =
true;
842 float tgPhi = trkWorkITS.getSnp() / std::sqrt((1.f - trkWorkITS.getSnp()) * (1.f + trkWorkITS.getSnp()));
843 auto dy = cls.getY() - trkWorkITS.getY();
844 auto dz = cls.getZ() - trkWorkITS.getZ();
845 if ((std::abs(dy) < param::MaxResid) && (std::abs(dz) < param::MaxResid) && (std::abs(trkWorkITS.getY()) < param::MaxY) && (std::abs(trkWorkITS.getZ()) < param::MaxZ) && (std::abs(tgPhi) < param::MaxTgSlp)) {
846 mClRes.emplace_back(dy, dz, tgPhi, trkWorkITS.getY(), trkWorkITS.getZ(), 180 + geom->getLayer(cls.getSensorID()), -1, cls.getSensorID());
847 mDetInfoRes.emplace_back();
851 if (!stopPropagation) {
854 if (!propagator->propagateToDCA(vtx, trkWorkITS, mBz, mParams->
maxStep, mMatCorr)) {
855 LOGP(
debug,
"Failed propagation to DCA to PV ({} {} {}), {}", pv.getX(), pv.getY(), pv.getZ(), trkWorkITS.asString());
856 stopPropagation =
true;
860 float sn, cs,
alpha = trkWorkITS.getAlpha();
861 math_utils::detail::bringToPMPi(
alpha);
862 math_utils::detail::sincos<float>(
alpha, sn, cs);
863 float xv = vtx.X() * cs + vtx.Y() * sn, yv = -vtx.X() * sn + vtx.Y() * cs, zv = vtx.Z();
864 auto dy = yv - trkWorkITS.getY();
865 auto dz = zv - trkWorkITS.getZ();
866 if ((std::abs(dy) < param::MaxResid) && (std::abs(dz) < param::MaxResid) && (std::abs(trkWorkITS.getY()) < param::MaxY) && (std::abs(trkWorkITS.getZ()) < param::MaxZ) && std::abs(xv) < param::MaxVtxX) {
867 short compXV =
static_cast<short>(xv * 0x7fff / param::MaxVtxX);
868 mClRes.emplace_back(dy, dz,
alpha / TMath::Pi(), trkWorkITS.getY(), trkWorkITS.getZ(), 190, -1, compXV);
870 LOGP(fatal,
"ITS-TPC seed index is not set for TOF track");
873 mDetInfoRes.emplace_back().setPV(tdif);
881 mGIDsSuccess.push_back(mGIDs[iSeed]);
883 mTrackData.push_back(std::move(trackData));
885 if (mDumpTrackPoints) {
886 (*trackDataExtended).clIdx.setEntries(nClValidated);
887 (*trackDataExtended).nExtDetResid = trackData.
nExtDetResid;
888 (*trackDataExtended).filterFlag = trackData.
filterFlag;
889 mTrackDataExtended.push_back(std::move(*trackDataExtended));
893 (*mDBGOut) <<
"valdata" <<
"params=" << mTrackValidation <<
"trackData=" << (stored ? mTrackData.back() : trackData) <<
"\n";
953 LOGP(
debug,
"Starting track extrapolation for GID {}", mGIDs[iSeed].
asString());
954 const auto& gidTable = mGIDtables[iSeed];
958 std::unique_ptr<TrackDataExtended> trackDataExtended;
959 std::vector<TPCClusterResiduals> clusterResiduals;
960 trackData.
clIdx.setFirstEntry(mClRes.size());
963 if (mDumpTrackPoints) {
964 trackDataExtended = std::make_unique<TrackDataExtended>();
965 (*trackDataExtended).gid = mGIDs[iSeed];
966 (*trackDataExtended).clIdx.setFirstEntry(mClRes.size());
967 (*trackDataExtended).trkITS = trkITS;
968 (*trackDataExtended).trkTPC = trkTPC;
969 auto nCl = trkITS.getNumberOfClusters();
970 auto clEntry = trkITS.getFirstClusterEntry();
971 for (
int iCl = nCl - 1; iCl >= 0; iCl--) {
972 const auto& clsITS = mITSClustersArray[mITSTrackClusIdx[clEntry + iCl]];
973 (*trackDataExtended).clsITS.push_back(clsITS);
980 trackData.
gid = mGIDs[iSeed];
981 trackData.
par = mSeeds[iSeed];
983 auto trkWork = mSeeds[iSeed];
984 float clusterTimeBinOffset = mTrackTimes[iSeed] / mTPCTimeBinMUS;
986 unsigned short rowPrev = 0;
987 unsigned short nMeasurements = 0;
990 std::array<short, constants::MAXGLOBALPADROW> multBins{};
991 for (
int iCl = trkTPC.getNClusterReferences(); iCl--;) {
993 uint32_t clusterIndexInRow;
994 trkTPC.getClusterReference(mTPCTrackClusIdx, iCl, sector,
row, clusterIndexInRow);
995 unsigned int absoluteIndex = mTPCClusterIdxStruct->
clusterOffset[sector][
row] + clusterIndexInRow;
996 const auto& cl = mTPCClusterIdxStruct->
clustersLinear[absoluteIndex];
997 if (clRowPrev ==
row) {
1000 }
else if (clRowPrev < constants::MAXGLOBALPADROW && clRowPrev >
row) {
1002 LOGP(
debug,
"TPC track with pT={} GeV and {} clusters has cluster {} on row {} while the previous cluster was on row {}",
1003 mSeeds[iSeed].getPt(), trkTPC.getNClusterReferences(), iCl,
row, clRowPrev);
1010 float x = 0,
y = 0,
z = 0;
1011 mFastTransform->TransformIdeal(sector,
row, cl.getPad(), cl.getTime(),
x,
y,
z, clusterTimeBinOffset);
1016 if (!propagator->PropagateToXBxByBz(trkWork,
x, mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
1021 const auto dY =
y - trkWork.getY();
1022 const auto dZ =
z - trkWork.getZ();
1023 const auto ty = trkWork.getY();
1024 const auto tz = trkWork.getZ();
1025 const auto snp = trkWork.getSnp();
1026 const auto sec = sector;
1027 unsigned char flags = cl.getFlags();
1031 clusterResiduals.emplace_back(dY, dZ, ty, tz, snp, sec,
row - rowPrev,
flags);
1032 mCacheDEDX[
row].first = cl.getQtot();
1033 mCacheDEDX[
row].second = cl.getQmax();
1035 int imb =
int(cl.getTime() * mNTPCOccBinLengthInv);
1036 if (imb < mTPCParam->occupancyMapSize) {
1037 multBins[
row] = 1 + std::max(0, imb);
1042 mTrackValidation.
clear();
1044 LOGP(warn,
"Extrapolated ITS-TPC track and found more residuals than possible ({})", clusterResiduals.size());
1049 trackData.
chi2TPC = trkTPC.getChi2();
1050 trackData.
chi2ITS = trkITS.getChi2();
1051 trackData.
nClsTPC = trkTPC.getNClusterReferences();
1052 trackData.
nClsITS = trkITS.getNumberOfClusters();
1053 trackData.
clIdx.setEntries(nMeasurements);
1054 trackData.
dEdxTPC = trkTPC.getdEdx().dEdxTotTPC;
1055 if (mDumpTrackPoints) {
1056 (*trackDataExtended).trkOuter = trkWork;
1059 bool stored =
false;
1062 int nClValidated = 0, iRow = 0;
1063 unsigned int iCl = 0;
1064 for (iCl = 0; iCl < clusterResiduals.size(); ++iCl) {
1065 iRow += clusterResiduals[iCl].dRow;
1066 if (iRow >= param::NPadRows) {
1069 const auto rej = trackData.
filterFlag < 0 ? false : mTrackValidation.
points[iCl].flagRej;
1073 const float tgPhi = clusterResiduals[iCl].snp / std::sqrt((1.f - clusterResiduals[iCl].snp) * (1.f + clusterResiduals[iCl].snp));
1074 const auto dy = clusterResiduals[iCl].dy;
1075 const auto dz = clusterResiduals[iCl].dz;
1076 const auto y = clusterResiduals[iCl].y;
1077 const auto z = clusterResiduals[iCl].z;
1078 const short flags = clusterResiduals[iCl].flags;
1079 if ((std::abs(dy) < param::MaxResid) && (std::abs(dz) < param::MaxResid) && (std::abs(
y) < param::MaxY) && (std::abs(
z) < param::MaxZ) && (std::abs(tgPhi) < param::MaxTgSlp)) {
1080 mClRes.emplace_back(dy, dz, tgPhi,
y,
z, iRow, clusterResiduals[iCl].sec,
flags, rej);
1081 mDetInfoRes.emplace_back().setTPC(mCacheDEDX[iRow].
first, mCacheDEDX[iRow].second);
1084 ++mRejectedResiduals;
1087 trackData.
clIdx.setEntries(nClValidated);
1090 for (
int ist = 0; ist < NSTACKS; ist++) {
1091 int mltBinMin = 0x7ffff, mltBinMax = -1, prevBin = -1;
1092 for (
int ir = STACKROWS[ist];
ir < STACKROWS[ist + 1];
ir++) {
1093 if (multBins[
ir] != prevBin && multBins[
ir] > 0) {
1094 prevBin = multBins[
ir];
1095 if (multBins[
ir] > mltBinMax) {
1096 mltBinMax = multBins[
ir];
1098 if (multBins[
ir] < mltBinMin) {
1099 mltBinMin = multBins[
ir];
1103 if (--mltBinMin >= 0) {
1105 for (
int ib = mltBinMin; ib < mltBinMax; ib++) {
1106 avMlt += mTPCParam->occupancyMap[ib];
1108 avMlt /= (mltBinMax - mltBinMin);
1113 bool stopPropagation = !mExtDetResid;
1114 if (!stopPropagation) {
1116 int iSeedFull = mParentID[iSeed] == -1 ? iSeed : mParentID[iSeed];
1117 auto gidFull = mGIDs[iSeedFull];
1118 const auto& gidTableFull = mGIDtables[iSeedFull];
1121 trackData.
nTrkltsTRD = trkTRD.getNtracklets();
1122 trackData.
chi2TRD = trkTRD.getChi2();
1124 std::array<float, 2> trkltTRDYZ{};
1125 int res =
processTRDLayer(trkTRD, iLayer, trkWork, &trkltTRDYZ,
nullptr, &trackData, &trkl64, &trklCalib);
1130 stopPropagation =
true;
1134 float tgPhi = trkWork.getSnp() / std::sqrt((1.f - trkWork.getSnp()) * (1.f + trkWork.getSnp()));
1135 auto dy = trkltTRDYZ[0] - trkWork.getY();
1136 auto dz = trkltTRDYZ[1] - trkWork.getZ();
1137 const auto sec = clusterResiduals[iCl].sec;
1138 if ((std::abs(dy) < param::MaxResid) && (std::abs(dz) < param::MaxResid) && (std::abs(trkWork.getY()) < param::MaxY) && (std::abs(trkWork.getZ()) < param::MaxZ) && (std::abs(tgPhi) < param::MaxTgSlp)) {
1140 mDetInfoRes.emplace_back().setTRD(trkl64.getQ0(), trkl64.getQ1(), trkl64.getQ2(), trklCalib.getDy());
1148 while (gidTableFull[
GTrackID::TOF].isIndexSet() && !stopPropagation) {
1149 const auto& tofMatch = mRecoCont->
getTOFMatch(gidFull);
1153 float t0forTOFres = tofMatch.getFT0BestRes();
1154 trackData.
deltaTOF = tofMatch.getSignal() - t0forTOF - tofMatch.getLTIntegralOut().getTOF(trkTPC.getPID().getID());
1155 trackData.
clAvailTOF = uint16_t(t0forTOFres);
1158 float clTOFxyz[3] = {clTOF.getX(), clTOF.getY(), clTOF.getZ()};
1159 if (!clTOF.isInNominalSector()) {
1162 if (trkWork.getAlpha() != clTOFAlpha && !trkWork.rotate(clTOFAlpha)) {
1163 LOG(
debug) <<
"Failed to rotate into TOF cluster sector frame";
1164 stopPropagation =
true;
1167 if (!propagator->PropagateToXBxByBz(trkWork, clTOFxyz[0], mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
1168 LOG(
debug) <<
"Failed final propagation to TOF radius";
1172 float tgPhi = trkWork.getSnp() / std::sqrt((1.f - trkWork.getSnp()) * (1.f + trkWork.getSnp()));
1173 auto dy = clTOFxyz[1] - trkWork.getY();
1174 auto dz = clTOFxyz[2] - trkWork.getZ();
1175 if ((std::abs(dy) < param::MaxResid) && (std::abs(dz) < param::MaxResid) && (std::abs(trkWork.getY()) < param::MaxY) && (std::abs(trkWork.getZ()) < param::MaxZ) && (std::abs(tgPhi) < param::MaxTgSlp)) {
1176 mClRes.emplace_back(dy, dz, tgPhi, trkWork.getY(), trkWork.getZ(), 170, clTOF.getCount(), clTOF.getPadInSector());
1179 LOGP(fatal,
"ITS-TPC seed index is not set for TOF track");
1182 float tdif =
static_cast<float>(clTOF.getTime() - t0forTOF);
1183 mDetInfoRes.emplace_back().setTOF(tdif * 1e-6);
1190 while (!stopPropagation) {
1192 auto nCl = trkITS.getNumberOfClusters();
1193 auto clEntry = trkITS.getFirstClusterEntry();
1195 for (
int iCl = 0; iCl < nCl; iCl++) {
1196 const auto& cls = mITSClustersArray[mITSTrackClusIdx[clEntry + iCl]];
1197 int chip = cls.getSensorID();
1198 float chipX, chipAlpha;
1199 geom->getSensorXAlphaRefPlane(cls.getSensorID(), chipX, chipAlpha);
1200 if (!trkWorkITS.rotate(chipAlpha) || !propagator->propagateToX(trkWorkITS, chipX, mBz, mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
1201 LOGP(
debug,
"Failed final propagation to ITS X={} alpha={}", chipX, chipAlpha);
1202 stopPropagation =
true;
1205 float tgPhi = trkWorkITS.getSnp() / std::sqrt((1.f - trkWorkITS.getSnp()) * (1.f + trkWorkITS.getSnp()));
1206 auto dy = cls.getY() - trkWorkITS.getY();
1207 auto dz = cls.getZ() - trkWorkITS.getZ();
1208 if ((std::abs(dy) < param::MaxResid) && (std::abs(dz) < param::MaxResid) && (std::abs(trkWorkITS.getY()) < param::MaxY) && (std::abs(trkWorkITS.getZ()) < param::MaxZ) && (std::abs(tgPhi) < param::MaxTgSlp)) {
1209 mClRes.emplace_back(dy, dz, tgPhi, trkWorkITS.getY(), trkWorkITS.getZ(), 180 + geom->getLayer(cls.getSensorID()), -1, cls.getSensorID());
1210 mDetInfoRes.emplace_back();
1214 if (!stopPropagation) {
1217 if (!propagator->propagateToDCA(vtx, trkWorkITS, mBz, mParams->
maxStep, mMatCorr)) {
1218 LOGP(
debug,
"Failed propagation to DCA to PV ({} {} {}), {}", pv.getX(), pv.getY(), pv.getZ(), trkWorkITS.asString());
1219 stopPropagation =
true;
1223 float sn, cs,
alpha = trkWorkITS.getAlpha();
1224 math_utils::detail::bringToPMPi(
alpha);
1225 math_utils::detail::sincos<float>(
alpha, sn, cs);
1226 float xv = vtx.X() * cs + vtx.Y() * sn, yv = -vtx.X() * sn + vtx.Y() * cs, zv = vtx.Z();
1227 auto dy = yv - trkWorkITS.getY();
1228 auto dz = zv - trkWorkITS.getZ();
1229 if ((std::abs(dy) < param::MaxResid) && (std::abs(dz) < param::MaxResid) && (std::abs(trkWorkITS.getY()) < param::MaxY) && (std::abs(trkWorkITS.getZ()) < param::MaxZ) && std::abs(xv) < param::MaxVtxX) {
1230 short compXV =
static_cast<short>(xv * 0x7fff / param::MaxVtxX);
1231 mClRes.emplace_back(dy, dz,
alpha / TMath::Pi(), trkWorkITS.getY(), trkWorkITS.getZ(), 190, -1, compXV);
1233 LOGP(fatal,
"ITS-TPC seed index is not set for TOF track");
1236 mDetInfoRes.emplace_back().setPV(tdif);
1243 mTrackData.push_back(std::move(trackData));
1245 mGIDsSuccess.push_back(mGIDs[iSeed]);
1247 if (mDumpTrackPoints) {
1248 (*trackDataExtended).clIdx.setEntries(nClValidated);
1249 (*trackDataExtended).nExtDetResid = trackData.
nExtDetResid;
1250 (*trackDataExtended).filterFlag = trackData.
filterFlag;
1251 mTrackDataExtended.push_back(std::move(*trackDataExtended));
1255 (*mDBGOut) <<
"valdata" <<
"params=" << mTrackValidation <<
"trackData=" << (stored ? mTrackData.back() : trackData) <<
"\n";