337 LOG(error) <<
"Initialization not yet done. Aborting...";
345 mNTPCOccBinLength = mTPCParam->rec.tpc.occupancyMapTimeBins;
346 mNTPCOccBinLengthInv = 1.f / mNTPCOccBinLength;
349 LOG(error) <<
"No ITS dictionary available";
355 auto pattIt = patterns.begin();
356 mITSClustersArray.clear();
357 mITSClustersArray.reserve(clusITS.size());
358 LOGP(info,
"We have {} ITS clusters and the number of patterns is {}", clusITS.size(), patterns.size());
366 std::random_device
rd;
367 std::mt19937
g(
rd());
368 std::vector<uint32_t> trackIndices;
377 int nSeeds = mSeeds.size(), lastChecked = 0;
379 mParentID.resize(nSeeds, -1);
381 int maxOutputTracks = (mMaxTracksPerTF >= 0) ? mMaxTracksPerTF + mAddTracksForMapPerTF : nSeeds;
382 mTrackData.reserve(maxOutputTracks);
383 mClRes.reserve(maxOutputTracks * param::NPadRows);
384 mDetInfoRes.reserve(maxOutputTracks * param::NPadRows);
385 bool maxTracksReached =
false;
386 for (
int iSeed = 0; iSeed < nSeeds; ++iSeed) {
387 if (mMaxTracksPerTF >= 0 && mTrackDataCompact.size() >= mMaxTracksPerTF + mAddTracksForMapPerTF) {
388 LOG(info) <<
"Maximum number of tracks per TF reached. Skipping the remaining " << nSeeds - iSeed <<
" tracks.";
391 int seedIndex = trackIndices[iSeed];
396 this->mGIDs.push_back(this->mGIDtables[seedIndex][
src]);
398 this->mTrackTimes.push_back(this->mTrackTimes[seedIndex]);
399 this->mSeeds.push_back(this->mSeeds[seedIndex]);
400 this->mParentID.push_back(seedIndex);
401 this->mTrackPVID.push_back(this->mTrackPVID[seedIndex]);
405 if (!mSingleSourcesConfigured && !mSourcesConfiguredMap[mGIDs[seedIndex].getSource()]) {
412 if (mMaxTracksPerTF >= 0 && mTrackDataCompact.size() >= mMaxTracksPerTF) {
413 if (!maxTracksReached) {
414 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);
416 maxTracksReached =
true;
421 LOGP(
debug,
"interpolateTrack {} {}, accepted: {}", iSeed,
GTrackID::getSourceName(mGIDs[seedIndex].getSource()), mTrackDataCompact.size());
432 LOGP(
debug,
"extrapolateTrack {} {}, accepted: {}", iSeed,
GTrackID::getSourceName(mGIDs[seedIndex].getSource()), mTrackDataCompact.size());
436 std::vector<int> remSeeds;
437 if (mSeeds.size() > ++lastChecked) {
438 remSeeds.resize(mSeeds.size() - lastChecked);
439 std::iota(remSeeds.begin(), remSeeds.end(), lastChecked);
440 std::shuffle(remSeeds.begin(), remSeeds.end(),
g);
441 LOGP(info,
"Up to {} tracks out of {} additional seeds will be processed in random order, of which {} are stripped versions, accepted seeds: {}",
442 mAddTracksForMapPerTF > 0 ? mAddTracksForMapPerTF : remSeeds.size(),
443 remSeeds.size(), mSeeds.size() - nSeeds, mTrackDataCompact.size());
445 int extraChecked = 0;
446 for (
int iSeed : remSeeds) {
447 if (mAddTracksForMapPerTF > 0 && mTrackDataCompact.size() >= mMaxTracksPerTF + mAddTracksForMapPerTF) {
448 LOGP(info,
"Maximum number {} of additional tracks per TF reached. Skipping the remaining {} tracks", mAddTracksForMapPerTF, remSeeds.size() - extraChecked);
454 LOGP(
debug,
"extra check {} of {}, seed {} interpolateTrack {}, used: {}", extraChecked, remSeeds.size(), iSeed,
GTrackID::getSourceName(mGIDs[iSeed].getSource()), mTrackDataCompact.size());
456 LOGP(
debug,
"extra check {} of {}, seed {} extrapolateTrack {}, used: {}", extraChecked, remSeeds.size(), iSeed,
GTrackID::getSourceName(mGIDs[iSeed].getSource()), mTrackDataCompact.size());
460 LOGP(info,
"Could process {} tracks successfully ({} rejected in refits, {} in propagation, {} as loopers), {} residuals were rejected, {} accepted",
461 mTrackData.size(), mNRejRefit, mNRejProp, mNRejLoop, mRejectedResiduals, mClRes.size());
462 mRejectedResiduals = 0;
470 LOGP(
debug,
"Starting track interpolation for GID {}", mGIDs[iSeed].
asString());
474 std::unique_ptr<TrackDataExtended> trackDataExtended;
475 std::vector<TPCClusterResiduals> clusterResiduals;
477 const auto& gidTable = mGIDtables[iSeed];
480 if (mDumpTrackPoints) {
481 trackDataExtended = std::make_unique<TrackDataExtended>();
482 (*trackDataExtended).gid = mGIDs[iSeed];
483 (*trackDataExtended).clIdx.setFirstEntry(mClRes.size());
484 (*trackDataExtended).trkITS = trkITS;
485 (*trackDataExtended).trkTPC = trkTPC;
486 auto nCl = trkITS.getNumberOfClusters();
487 auto clEntry = trkITS.getFirstClusterEntry();
488 for (
int iCl = nCl - 1; iCl >= 0; iCl--) {
489 const auto& clsITS = mITSClustersArray[mITSTrackClusIdx[clEntry + iCl]];
490 (*trackDataExtended).clsITS.push_back(clsITS);
497 trackData.
gid = mGIDs[iSeed];
498 trackData.
par = mSeeds[iSeed];
499 auto trkWork = mSeeds[iSeed];
502 for (
auto& elem : mCache) {
503 elem.clAvailable = 0;
505 trackData.
clIdx.setFirstEntry(mClRes.size());
506 float clusterTimeBinOffset = mTrackTimes[iSeed] / mTPCTimeBinMUS;
510 std::array<short, constants::MAXGLOBALPADROW> multBins{};
511 for (
int iCl = trkTPC.getNClusterReferences(); iCl--;) {
513 uint32_t clusterIndexInRow;
514 const auto& clTPC = trkTPC.getCluster(mTPCTracksClusIdx, iCl, *mTPCClusterIdxStruct, sector,
row);
516 std::array<float, 2> clTPCYZ;
517 mFastTransform->TransformIdeal(sector,
row, clTPC.getPad(), clTPC.getTime(), clTPCX, clTPCYZ[0], clTPCYZ[1], clusterTimeBinOffset);
518 mCache[
row].clSec = sector;
519 mCache[
row].clAvailable = 1;
520 mCache[
row].clY = clTPCYZ[0];
521 mCache[
row].clZ = clTPCYZ[1];
523 mCacheDEDX[
row].first = clTPC.getQtot();
524 mCacheDEDX[
row].second = clTPC.getQmax();
525 int imb =
int(clTPC.getTime() * mNTPCOccBinLengthInv);
526 if (imb < mTPCParam->occupancyMapSize) {
527 multBins[
row] = 1 + std::max(0, imb);
532 for (
int iRow = 0; iRow < param::NPadRows; ++iRow) {
533 if (!mCache[iRow].clAvailable) {
536 if (!trkWork.rotate(mCache[iRow].clAngle)) {
537 LOG(
debug) <<
"Failed to rotate track during first extrapolation";
541 if (!propagator->PropagateToXBxByBz(trkWork, param::RowX[iRow], mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
542 LOG(
debug) <<
"Failed on first extrapolation";
546 mCache[iRow].y[
ExtOut] = trkWork.getY();
547 mCache[iRow].z[
ExtOut] = trkWork.getZ();
548 mCache[iRow].sy2[
ExtOut] = trkWork.getSigmaY2();
549 mCache[iRow].szy[
ExtOut] = trkWork.getSigmaZY();
550 mCache[iRow].sz2[
ExtOut] = trkWork.getSigmaZ2();
551 mCache[iRow].snp[
ExtOut] = trkWork.getSnp();
557 LOG(
debug) <<
"TOF point available";
559 if (mDumpTrackPoints) {
560 (*trackDataExtended).clsTOF = clTOF;
561 (*trackDataExtended).matchTOF = mRecoCont->
getTOFMatch(mGIDs[iSeed]);
563 const int clTOFSec = clTOF.getCount();
565 if (!trkWork.rotate(clTOFAlpha)) {
566 LOG(
debug) <<
"Failed to rotate into TOF cluster sector frame";
570 float clTOFxyz[3] = {clTOF.getX(), clTOF.getY(), clTOF.getZ()};
571 if (!clTOF.isInNominalSector()) {
574 std::array<float, 2> clTOFYZ{clTOFxyz[1], clTOFxyz[2]};
576 if (!propagator->PropagateToXBxByBz(trkWork, clTOFxyz[0], mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
577 LOG(
debug) <<
"Failed final propagation to TOF radius";
582 if (!trkWork.update(clTOFYZ, clTOFCov)) {
583 LOG(
debug) <<
"Failed to update extrapolated ITS track with TOF cluster";
592 if (mDumpTrackPoints) {
593 (*trackDataExtended).trkTRD = trkTRD;
596 std::array<float, 2> trkltTRDYZ{};
597 std::array<float, 3> trkltTRDCov{};
605 if (!trkWork.update(trkltTRDYZ, trkltTRDCov)) {
606 LOG(
debug) <<
"Failed to update track at TRD layer " << iLayer;
613 if (mDumpTrackPoints) {
614 (*trackDataExtended).trkOuter = trkWork;
616 auto trkOuter = trkWork;
619 bool outerParamStored =
false;
620 for (
int iRow = param::NPadRows; iRow--;) {
621 if (!mCache[iRow].clAvailable) {
624 if (mProcessSeeds && !outerParamStored) {
630 trackData.
par = trkWork;
631 outerParamStored =
true;
633 if (!trkWork.rotate(mCache[iRow].clAngle)) {
634 LOG(
debug) <<
"Failed to rotate track during back propagation";
638 if (!propagator->PropagateToXBxByBz(trkWork, param::RowX[iRow], mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
639 LOG(
debug) <<
"Failed on back propagation";
644 mCache[iRow].y[
ExtIn] = trkWork.getY();
645 mCache[iRow].z[
ExtIn] = trkWork.getZ();
646 mCache[iRow].sy2[
ExtIn] = trkWork.getSigmaY2();
647 mCache[iRow].szy[
ExtIn] = trkWork.getSigmaZY();
648 mCache[iRow].sz2[
ExtIn] = trkWork.getSigmaZ2();
649 mCache[iRow].snp[
ExtIn] = trkWork.getSnp();
653 unsigned short deltaRow = 0;
654 for (
int iRow = 0; iRow < param::NPadRows; ++iRow) {
655 if (!mCache[iRow].clAvailable) {
659 float wTotY = 1.f / mCache[iRow].sy2[
ExtOut] + 1.f / mCache[iRow].sy2[
ExtIn];
660 float wTotZ = 1.f / mCache[iRow].sz2[
ExtOut] + 1.f / mCache[iRow].sz2[
ExtIn];
661 mCache[iRow].y[
Int] = (mCache[iRow].y[
ExtOut] / mCache[iRow].sy2[
ExtOut] + mCache[iRow].y[
ExtIn] / mCache[iRow].sy2[
ExtIn]) / wTotY;
662 mCache[iRow].z[
Int] = (mCache[iRow].z[
ExtOut] / mCache[iRow].sz2[
ExtOut] + mCache[iRow].z[
ExtIn] / mCache[iRow].sz2[
ExtIn]) / wTotZ;
665 mCache[iRow].snp[
Int] = (mCache[iRow].snp[
ExtOut] + mCache[iRow].snp[
ExtIn]) / 2.f;
667 const auto dY = mCache[iRow].clY - mCache[iRow].y[
Int];
668 const auto dZ = mCache[iRow].clZ - mCache[iRow].z[
Int];
669 const auto y = mCache[iRow].y[
Int];
670 const auto z = mCache[iRow].z[
Int];
671 const auto snp = mCache[iRow].snp[
Int];
672 const auto sec = mCache[iRow].clSec;
673 clusterResiduals.emplace_back(dY, dZ,
y,
z, snp, sec, deltaRow);
678 trackData.
chi2TPC = trkTPC.getChi2();
679 trackData.
chi2ITS = trkITS.getChi2();
680 trackData.
nClsTPC = trkTPC.getNClusterReferences();
681 trackData.
nClsITS = trkITS.getNumberOfClusters();
684 double t0forTOF = 0.;
685 float t0forTOFwithinBC = 0.f;
686 float t0forTOFres = 9999.f;
689 const auto& tofMatch = mRecoCont->
getTOFMatch(mGIDs[iSeed]);
693 t0forTOFres = tofMatch.getFT0BestRes();
694 trackData.
deltaTOF = tofMatch.getSignal() - t0forTOF - tofMatch.getLTIntegralOut().getTOF(trkTPC.getPID().getID());
699 trackData.
dEdxTPC = trkTPC.getdEdx().dEdxTotTPC;
701 mTrackValidation.
clear();
706 int nClValidated = 0;
708 for (
unsigned int iCl = 0; iCl < clusterResiduals.size(); ++iCl) {
709 iRow += clusterResiduals[iCl].dRow;
710 const auto rej = trackData.
filterFlag < 0 ? false : mTrackValidation.
points[iCl].flagRej;
714 const float tgPhi = clusterResiduals[iCl].snp / std::sqrt((1.f - clusterResiduals[iCl].snp) * (1.f + clusterResiduals[iCl].snp));
715 const auto dy = clusterResiduals[iCl].dy;
716 const auto dz = clusterResiduals[iCl].dz;
717 const auto y = clusterResiduals[iCl].y;
718 const auto z = clusterResiduals[iCl].z;
719 const auto sec = clusterResiduals[iCl].sec;
720 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)) {
721 mClRes.emplace_back(dy, dz, tgPhi,
y,
z, iRow, sec, -1, rej);
722 mDetInfoRes.emplace_back().setTPC(mCacheDEDX[iRow].
first, mCacheDEDX[iRow].second);
725 ++mRejectedResiduals;
728 trackData.
clIdx.setEntries(nClValidated);
731 for (
int ist = 0; ist < NSTACKS; ist++) {
732 int mltBinMin = 0x7ffff, mltBinMax = -1, prevBin = -1;
733 for (
int ir = STACKROWS[ist];
ir < STACKROWS[ist + 1];
ir++) {
734 if (multBins[
ir] != prevBin && multBins[
ir] > 0) {
735 prevBin = multBins[
ir];
736 if (multBins[
ir] > mltBinMax) {
737 mltBinMax = multBins[
ir];
739 if (multBins[
ir] < mltBinMin) {
740 mltBinMin = multBins[
ir];
744 if (--mltBinMin >= 0) {
746 for (
int ib = mltBinMin; ib < mltBinMax; ib++) {
747 avMlt += mTPCParam->occupancyMap[ib];
749 avMlt /= (mltBinMax - mltBinMin);
754 bool stopPropagation = !mExtDetResid;
755 if (!stopPropagation) {
761 std::array<float, 2> trkltTRDYZ{};
762 int res =
processTRDLayer(trkTRD, iLayer, trkWork, &trkltTRDYZ,
nullptr, &trackData, &trkl64, &trklCalib);
767 stopPropagation =
true;
771 float tgPhi = trkWork.getSnp() / std::sqrt((1.f - trkWork.getSnp()) * (1.f + trkWork.getSnp()));
772 auto dy = trkltTRDYZ[0] - trkWork.getY();
773 auto dz = trkltTRDYZ[1] - trkWork.getZ();
774 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)) {
776 mDetInfoRes.emplace_back().setTRD(trkl64.getQ0(), trkl64.getQ1(), trkl64.getQ2(), trklCalib.getDy());
783 while (gidTable[
GTrackID::TOF].isIndexSet() && !stopPropagation) {
785 float clTOFxyz[3] = {clTOF.getX(), clTOF.getY(), clTOF.getZ()};
786 if (!clTOF.isInNominalSector()) {
790 if (trkWork.getAlpha() != clTOFAlpha && !trkWork.rotate(clTOFAlpha)) {
791 LOG(
debug) <<
"Failed to rotate into TOF cluster sector frame";
792 stopPropagation =
true;
795 if (!propagator->PropagateToXBxByBz(trkWork, clTOFxyz[0], mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
796 LOG(
debug) <<
"Failed final propagation to TOF radius";
800 float tgPhi = trkWork.getSnp() / std::sqrt((1.f - trkWork.getSnp()) * (1.f + trkWork.getSnp()));
801 auto dy = clTOFxyz[1] - trkWork.getY();
802 auto dz = clTOFxyz[2] - trkWork.getZ();
805 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)) {
806 mClRes.emplace_back(dy, dz, tgPhi, trkWork.getY(), trkWork.getZ(), 170, clTOF.getCount(), clTOF.getPadInSector());
809 LOGP(fatal,
"ITS-TPC seed index is not set for TOF track");
811 float tdif =
static_cast<float>(clTOF.getTime() - t0forTOF);
812 mDetInfoRes.emplace_back().setTOF(tdif * 1e-6);
819 while (!stopPropagation) {
820 auto& trkWorkITS = trkInner;
821 auto nCl = trkITS.getNumberOfClusters();
822 auto clEntry = trkITS.getFirstClusterEntry();
824 for (
int iCl = 0; iCl < nCl; iCl++) {
825 const auto& cls = mITSClustersArray[mITSTrackClusIdx[clEntry + iCl]];
826 int chip = cls.getSensorID();
827 float chipX, chipAlpha;
828 geom->getSensorXAlphaRefPlane(cls.getSensorID(), chipX, chipAlpha);
829 if (!trkWorkITS.rotate(chipAlpha) || !propagator->PropagateToXBxByBz(trkWorkITS, chipX, mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
830 LOGP(
debug,
"Failed final propagation to ITS X={} alpha={}", chipX, chipAlpha);
831 stopPropagation =
true;
834 float tgPhi = trkWorkITS.getSnp() / std::sqrt((1.f - trkWorkITS.getSnp()) * (1.f + trkWorkITS.getSnp()));
835 auto dy = cls.getY() - trkWorkITS.getY();
836 auto dz = cls.getZ() - trkWorkITS.getZ();
837 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)) {
838 mClRes.emplace_back(dy, dz, tgPhi, trkWorkITS.getY(), trkWorkITS.getZ(), 180 + geom->getLayer(cls.getSensorID()), -1, cls.getSensorID());
839 mDetInfoRes.emplace_back();
843 if (!stopPropagation) {
846 if (!propagator->propagateToDCA(vtx, trkWorkITS, mBz, mParams->
maxStep, mMatCorr)) {
847 LOGP(
debug,
"Failed propagation to DCA to PV ({} {} {}), {}", pv.getX(), pv.getY(), pv.getZ(), trkWorkITS.asString());
848 stopPropagation =
true;
852 float sn, cs,
alpha = trkWorkITS.getAlpha();
853 math_utils::detail::bringToPMPi(
alpha);
854 math_utils::detail::sincos<float>(
alpha, sn, cs);
855 float xv = vtx.X() * cs + vtx.Y() * sn, yv = -vtx.X() * sn + vtx.Y() * cs, zv = vtx.Z();
856 auto dy = yv - trkWorkITS.getY();
857 auto dz = zv - trkWorkITS.getZ();
858 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) {
859 short compXV =
static_cast<short>(xv * 0x7fff / param::MaxVtxX);
860 mClRes.emplace_back(dy, dz,
alpha / TMath::Pi(), trkWorkITS.getY(), trkWorkITS.getZ(), 190, -1, compXV);
862 LOGP(fatal,
"ITS-TPC seed index is not set for TOF track");
865 mDetInfoRes.emplace_back().setPV(tdif);
873 mGIDsSuccess.push_back(mGIDs[iSeed]);
875 mTrackData.push_back(std::move(trackData));
877 if (mDumpTrackPoints) {
878 (*trackDataExtended).clIdx.setEntries(nClValidated);
879 (*trackDataExtended).nExtDetResid = trackData.
nExtDetResid;
880 (*trackDataExtended).filterFlag = trackData.
filterFlag;
881 mTrackDataExtended.push_back(std::move(*trackDataExtended));
885 (*mDBGOut) <<
"valdata" <<
"params=" << mTrackValidation <<
"trackData=" << (stored ? mTrackData.back() : trackData) <<
"\n";
945 LOGP(
debug,
"Starting track extrapolation for GID {}", mGIDs[iSeed].
asString());
946 const auto& gidTable = mGIDtables[iSeed];
950 std::unique_ptr<TrackDataExtended> trackDataExtended;
951 std::vector<TPCClusterResiduals> clusterResiduals;
952 trackData.
clIdx.setFirstEntry(mClRes.size());
955 if (mDumpTrackPoints) {
956 trackDataExtended = std::make_unique<TrackDataExtended>();
957 (*trackDataExtended).gid = mGIDs[iSeed];
958 (*trackDataExtended).clIdx.setFirstEntry(mClRes.size());
959 (*trackDataExtended).trkITS = trkITS;
960 (*trackDataExtended).trkTPC = trkTPC;
961 auto nCl = trkITS.getNumberOfClusters();
962 auto clEntry = trkITS.getFirstClusterEntry();
963 for (
int iCl = nCl - 1; iCl >= 0; iCl--) {
964 const auto& clsITS = mITSClustersArray[mITSTrackClusIdx[clEntry + iCl]];
965 (*trackDataExtended).clsITS.push_back(clsITS);
972 trackData.
gid = mGIDs[iSeed];
973 trackData.
par = mSeeds[iSeed];
975 auto trkWork = mSeeds[iSeed];
976 float clusterTimeBinOffset = mTrackTimes[iSeed] / mTPCTimeBinMUS;
978 unsigned short rowPrev = 0;
979 unsigned short nMeasurements = 0;
982 std::array<short, constants::MAXGLOBALPADROW> multBins{};
983 for (
int iCl = trkTPC.getNClusterReferences(); iCl--;) {
985 uint32_t clusterIndexInRow;
986 const auto& cl = trkTPC.getCluster(mTPCTracksClusIdx, iCl, *mTPCClusterIdxStruct, sector,
row);
987 if (clRowPrev ==
row) {
990 }
else if (clRowPrev < constants::MAXGLOBALPADROW && clRowPrev >
row) {
992 LOGP(
debug,
"TPC track with pT={} GeV and {} clusters has cluster {} on row {} while the previous cluster was on row {}",
993 mSeeds[iSeed].getPt(), trkTPC.getNClusterReferences(), iCl,
row, clRowPrev);
1000 float x = 0,
y = 0,
z = 0;
1001 mFastTransform->TransformIdeal(sector,
row, cl.getPad(), cl.getTime(),
x,
y,
z, clusterTimeBinOffset);
1006 if (!propagator->PropagateToXBxByBz(trkWork,
x, mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
1011 const auto dY =
y - trkWork.getY();
1012 const auto dZ =
z - trkWork.getZ();
1013 const auto ty = trkWork.getY();
1014 const auto tz = trkWork.getZ();
1015 const auto snp = trkWork.getSnp();
1016 const auto sec = sector;
1017 clusterResiduals.emplace_back(dY, dZ, ty, tz, snp, sec,
row - rowPrev);
1018 mCacheDEDX[
row].first = cl.getQtot();
1019 mCacheDEDX[
row].second = cl.getQmax();
1021 int imb =
int(cl.getTime() * mNTPCOccBinLengthInv);
1022 if (imb < mTPCParam->occupancyMapSize) {
1023 multBins[
row] = 1 + std::max(0, imb);
1028 mTrackValidation.
clear();
1030 LOGP(warn,
"Extrapolated ITS-TPC track and found more residuals than possible ({})", clusterResiduals.size());
1035 trackData.
chi2TPC = trkTPC.getChi2();
1036 trackData.
chi2ITS = trkITS.getChi2();
1037 trackData.
nClsTPC = trkTPC.getNClusterReferences();
1038 trackData.
nClsITS = trkITS.getNumberOfClusters();
1039 trackData.
clIdx.setEntries(nMeasurements);
1040 trackData.
dEdxTPC = trkTPC.getdEdx().dEdxTotTPC;
1041 if (mDumpTrackPoints) {
1042 (*trackDataExtended).trkOuter = trkWork;
1045 bool stored =
false;
1048 int nClValidated = 0, iRow = 0;
1049 unsigned int iCl = 0;
1050 for (iCl = 0; iCl < clusterResiduals.size(); ++iCl) {
1051 iRow += clusterResiduals[iCl].dRow;
1052 if (iRow >= param::NPadRows) {
1055 const auto rej = trackData.
filterFlag < 0 ? false : mTrackValidation.
points[iCl].flagRej;
1059 const float tgPhi = clusterResiduals[iCl].snp / std::sqrt((1.f - clusterResiduals[iCl].snp) * (1.f + clusterResiduals[iCl].snp));
1060 const auto dy = clusterResiduals[iCl].dy;
1061 const auto dz = clusterResiduals[iCl].dz;
1062 const auto y = clusterResiduals[iCl].y;
1063 const auto z = clusterResiduals[iCl].z;
1064 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)) {
1065 mClRes.emplace_back(dy, dz, tgPhi,
y,
z, iRow, clusterResiduals[iCl].sec, -1, rej);
1066 mDetInfoRes.emplace_back().setTPC(mCacheDEDX[iRow].
first, mCacheDEDX[iRow].second);
1069 ++mRejectedResiduals;
1072 trackData.
clIdx.setEntries(nClValidated);
1075 for (
int ist = 0; ist < NSTACKS; ist++) {
1076 int mltBinMin = 0x7ffff, mltBinMax = -1, prevBin = -1;
1077 for (
int ir = STACKROWS[ist];
ir < STACKROWS[ist + 1];
ir++) {
1078 if (multBins[
ir] != prevBin && multBins[
ir] > 0) {
1079 prevBin = multBins[
ir];
1080 if (multBins[
ir] > mltBinMax) {
1081 mltBinMax = multBins[
ir];
1083 if (multBins[
ir] < mltBinMin) {
1084 mltBinMin = multBins[
ir];
1088 if (--mltBinMin >= 0) {
1090 for (
int ib = mltBinMin; ib < mltBinMax; ib++) {
1091 avMlt += mTPCParam->occupancyMap[ib];
1093 avMlt /= (mltBinMax - mltBinMin);
1098 bool stopPropagation = !mExtDetResid;
1099 if (!stopPropagation) {
1101 int iSeedFull = mParentID[iSeed] == -1 ? iSeed : mParentID[iSeed];
1102 auto gidFull = mGIDs[iSeedFull];
1103 const auto& gidTableFull = mGIDtables[iSeedFull];
1106 trackData.
nTrkltsTRD = trkTRD.getNtracklets();
1108 std::array<float, 2> trkltTRDYZ{};
1109 int res =
processTRDLayer(trkTRD, iLayer, trkWork, &trkltTRDYZ,
nullptr, &trackData, &trkl64, &trklCalib);
1114 stopPropagation =
true;
1118 float tgPhi = trkWork.getSnp() / std::sqrt((1.f - trkWork.getSnp()) * (1.f + trkWork.getSnp()));
1119 auto dy = trkltTRDYZ[0] - trkWork.getY();
1120 auto dz = trkltTRDYZ[1] - trkWork.getZ();
1121 const auto sec = clusterResiduals[iCl].sec;
1122 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)) {
1124 mDetInfoRes.emplace_back().setTRD(trkl64.getQ0(), trkl64.getQ1(), trkl64.getQ2(), trklCalib.getDy());
1132 while (gidTableFull[
GTrackID::TOF].isIndexSet() && !stopPropagation) {
1133 const auto& tofMatch = mRecoCont->
getTOFMatch(gidFull);
1137 float t0forTOFres = tofMatch.getFT0BestRes();
1138 trackData.
deltaTOF = tofMatch.getSignal() - t0forTOF - tofMatch.getLTIntegralOut().getTOF(trkTPC.getPID().getID());
1139 trackData.
clAvailTOF = uint16_t(t0forTOFres);
1142 float clTOFxyz[3] = {clTOF.getX(), clTOF.getY(), clTOF.getZ()};
1143 if (!clTOF.isInNominalSector()) {
1146 if (trkWork.getAlpha() != clTOFAlpha && !trkWork.rotate(clTOFAlpha)) {
1147 LOG(
debug) <<
"Failed to rotate into TOF cluster sector frame";
1148 stopPropagation =
true;
1151 if (!propagator->PropagateToXBxByBz(trkWork, clTOFxyz[0], mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
1152 LOG(
debug) <<
"Failed final propagation to TOF radius";
1156 float tgPhi = trkWork.getSnp() / std::sqrt((1.f - trkWork.getSnp()) * (1.f + trkWork.getSnp()));
1157 auto dy = clTOFxyz[1] - trkWork.getY();
1158 auto dz = clTOFxyz[2] - trkWork.getZ();
1159 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)) {
1160 mClRes.emplace_back(dy, dz, tgPhi, trkWork.getY(), trkWork.getZ(), 170, clTOF.getCount(), clTOF.getPadInSector());
1163 LOGP(fatal,
"ITS-TPC seed index is not set for TOF track");
1166 float tdif =
static_cast<float>(clTOF.getTime() - t0forTOF);
1167 mDetInfoRes.emplace_back().setTOF(tdif * 1e-6);
1174 while (!stopPropagation) {
1176 auto nCl = trkITS.getNumberOfClusters();
1177 auto clEntry = trkITS.getFirstClusterEntry();
1179 for (
int iCl = 0; iCl < nCl; iCl++) {
1180 const auto& cls = mITSClustersArray[mITSTrackClusIdx[clEntry + iCl]];
1181 int chip = cls.getSensorID();
1182 float chipX, chipAlpha;
1183 geom->getSensorXAlphaRefPlane(cls.getSensorID(), chipX, chipAlpha);
1184 if (!trkWorkITS.rotate(chipAlpha) || !propagator->propagateToX(trkWorkITS, chipX, mBz, mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
1185 LOGP(
debug,
"Failed final propagation to ITS X={} alpha={}", chipX, chipAlpha);
1186 stopPropagation =
true;
1189 float tgPhi = trkWorkITS.getSnp() / std::sqrt((1.f - trkWorkITS.getSnp()) * (1.f + trkWorkITS.getSnp()));
1190 auto dy = cls.getY() - trkWorkITS.getY();
1191 auto dz = cls.getZ() - trkWorkITS.getZ();
1192 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)) {
1193 mClRes.emplace_back(dy, dz, tgPhi, trkWorkITS.getY(), trkWorkITS.getZ(), 180 + geom->getLayer(cls.getSensorID()), -1, cls.getSensorID());
1194 mDetInfoRes.emplace_back();
1198 if (!stopPropagation) {
1201 if (!propagator->propagateToDCA(vtx, trkWorkITS, mBz, mParams->
maxStep, mMatCorr)) {
1202 LOGP(
debug,
"Failed propagation to DCA to PV ({} {} {}), {}", pv.getX(), pv.getY(), pv.getZ(), trkWorkITS.asString());
1203 stopPropagation =
true;
1207 float sn, cs,
alpha = trkWorkITS.getAlpha();
1208 math_utils::detail::bringToPMPi(
alpha);
1209 math_utils::detail::sincos<float>(
alpha, sn, cs);
1210 float xv = vtx.X() * cs + vtx.Y() * sn, yv = -vtx.X() * sn + vtx.Y() * cs, zv = vtx.Z();
1211 auto dy = yv - trkWorkITS.getY();
1212 auto dz = zv - trkWorkITS.getZ();
1213 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) {
1214 short compXV =
static_cast<short>(xv * 0x7fff / param::MaxVtxX);
1215 mClRes.emplace_back(dy, dz,
alpha / TMath::Pi(), trkWorkITS.getY(), trkWorkITS.getZ(), 190, -1, compXV);
1217 LOGP(fatal,
"ITS-TPC seed index is not set for TOF track");
1220 mDetInfoRes.emplace_back().setPV(tdif);
1227 mTrackData.push_back(std::move(trackData));
1229 mGIDsSuccess.push_back(mGIDs[iSeed]);
1231 if (mDumpTrackPoints) {
1232 (*trackDataExtended).clIdx.setEntries(nClValidated);
1233 (*trackDataExtended).nExtDetResid = trackData.
nExtDetResid;
1234 (*trackDataExtended).filterFlag = trackData.
filterFlag;
1235 mTrackDataExtended.push_back(std::move(*trackDataExtended));
1239 (*mDBGOut) <<
"valdata" <<
"params=" << mTrackValidation <<
"trackData=" << (stored ? mTrackData.back() : trackData) <<
"\n";