313 LOG(error) <<
"Initialization not yet done. Aborting...";
321 LOG(error) <<
"No ITS dictionary available";
327 auto pattIt = patterns.begin();
328 mITSClustersArray.clear();
329 mITSClustersArray.reserve(clusITS.size());
330 LOGP(info,
"We have {} ITS clusters and the number of patterns is {}", clusITS.size(), patterns.size());
338 std::random_device
rd;
339 std::mt19937
g(
rd());
340 std::vector<uint32_t> trackIndices;
350 int nSeeds = mSeeds.size(), lastChecked = 0;
352 mParentID.resize(nSeeds, -1);
354 int maxOutputTracks = (mMaxTracksPerTF >= 0) ? mMaxTracksPerTF + mAddTracksForMapPerTF : nSeeds;
355 mTrackData.reserve(maxOutputTracks);
356 mClRes.reserve(maxOutputTracks * param::NPadRows);
357 bool maxTracksReached =
false;
358 for (
int iSeed = 0; iSeed < nSeeds; ++iSeed) {
359 if (mMaxTracksPerTF >= 0 && mTrackDataCompact.size() >= mMaxTracksPerTF + mAddTracksForMapPerTF) {
360 LOG(info) <<
"Maximum number of tracks per TF reached. Skipping the remaining " << nSeeds - iSeed <<
" tracks.";
363 int seedIndex = trackIndices[iSeed];
368 this->mGIDs.push_back(this->mGIDtables[seedIndex][
src]);
370 this->mTrackTimes.push_back(this->mTrackTimes[seedIndex]);
371 this->mSeeds.push_back(this->mSeeds[seedIndex]);
372 this->mParentID.push_back(seedIndex);
373 this->mTrackPVID.push_back(this->mTrackPVID[seedIndex]);
377 if (!mSingleSourcesConfigured && !mSourcesConfiguredMap[mGIDs[seedIndex].getSource()]) {
384 if (mMaxTracksPerTF >= 0 && mTrackDataCompact.size() >= mMaxTracksPerTF) {
385 if (!maxTracksReached) {
386 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);
388 maxTracksReached =
true;
393 LOGP(
debug,
"interpolateTrack {} {}, accepted: {}", iSeed,
GTrackID::getSourceName(mGIDs[seedIndex].getSource()), mTrackDataCompact.size());
404 LOGP(
debug,
"extrapolateTrack {} {}, accepted: {}", iSeed,
GTrackID::getSourceName(mGIDs[seedIndex].getSource()), mTrackDataCompact.size());
408 std::vector<int> remSeeds;
409 if (mSeeds.size() > ++lastChecked) {
410 remSeeds.resize(mSeeds.size() - lastChecked);
411 std::iota(remSeeds.begin(), remSeeds.end(), lastChecked);
412 std::shuffle(remSeeds.begin(), remSeeds.end(),
g);
413 LOGP(info,
"Up to {} tracks out of {} additional seeds will be processed in random order, of which {} are stripped versions, accepted seeds: {}", mAddTracksForMapPerTF, remSeeds.size(), mSeeds.size() - nSeeds, mTrackDataCompact.size());
415 int extraChecked = 0;
416 for (
int iSeed : remSeeds) {
417 if (mAddTracksForMapPerTF > 0 && mTrackDataCompact.size() >= mMaxTracksPerTF + mAddTracksForMapPerTF) {
418 LOGP(info,
"Maximum number {} of additional tracks per TF reached. Skipping the remaining {} tracks", mAddTracksForMapPerTF, remSeeds.size() - extraChecked);
424 LOGP(
debug,
"extra check {} of {}, seed {} interpolateTrack {}, used: {}", extraChecked, remSeeds.size(), iSeed,
GTrackID::getSourceName(mGIDs[iSeed].getSource()), mTrackDataCompact.size());
426 LOGP(
debug,
"extra check {} of {}, seed {} extrapolateTrack {}, used: {}", extraChecked, remSeeds.size(), iSeed,
GTrackID::getSourceName(mGIDs[iSeed].getSource()), mTrackDataCompact.size());
430 LOG(info) <<
"Could process " << mTrackData.size() <<
" tracks successfully. " << mRejectedResiduals <<
" residuals were rejected. " << mClRes.size() <<
" residuals were accepted.";
431 mRejectedResiduals = 0;
436 LOGP(
debug,
"Starting track interpolation for GID {}", mGIDs[iSeed].
asString());
438 std::unique_ptr<TrackDataExtended> trackDataExtended;
439 std::vector<TPCClusterResiduals> clusterResiduals;
441 const auto& gidTable = mGIDtables[iSeed];
444 if (mDumpTrackPoints) {
445 trackDataExtended = std::make_unique<TrackDataExtended>();
446 (*trackDataExtended).gid = mGIDs[iSeed];
447 (*trackDataExtended).clIdx.setFirstEntry(mClRes.size());
448 (*trackDataExtended).trkITS = trkITS;
449 (*trackDataExtended).trkTPC = trkTPC;
450 auto nCl = trkITS.getNumberOfClusters();
451 auto clEntry = trkITS.getFirstClusterEntry();
452 for (
int iCl = nCl - 1; iCl >= 0; iCl--) {
453 const auto& clsITS = mITSClustersArray[mITSTrackClusIdx[clEntry + iCl]];
454 (*trackDataExtended).clsITS.push_back(clsITS);
460 trackData.
gid = mGIDs[iSeed];
461 trackData.
par = mSeeds[iSeed];
462 auto trkWork = mSeeds[iSeed];
465 for (
auto& elem : mCache) {
466 elem.clAvailable = 0;
468 trackData.
clIdx.setFirstEntry(mClRes.size());
469 float clusterTimeBinOffset = mTrackTimes[iSeed] / mTPCTimeBinMUS;
472 for (
int iCl = trkTPC.getNClusterReferences(); iCl--;) {
474 uint32_t clusterIndexInRow;
475 const auto& clTPC = trkTPC.getCluster(mTPCTracksClusIdx, iCl, *mTPCClusterIdxStruct, sector,
row);
477 std::array<float, 2> clTPCYZ;
478 mFastTransform->TransformIdeal(sector,
row, clTPC.getPad(), clTPC.getTime(), clTPCX, clTPCYZ[0], clTPCYZ[1], clusterTimeBinOffset);
479 mCache[
row].clSec = sector;
480 mCache[
row].clAvailable = 1;
481 mCache[
row].clY = clTPCYZ[0];
482 mCache[
row].clZ = clTPCYZ[1];
487 for (
int iRow = 0; iRow < param::NPadRows; ++iRow) {
488 if (!mCache[iRow].clAvailable) {
491 if (!trkWork.rotate(mCache[iRow].clAngle)) {
492 LOG(
debug) <<
"Failed to rotate track during first extrapolation";
495 if (!propagator->PropagateToXBxByBz(trkWork, param::RowX[iRow], mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
496 LOG(
debug) <<
"Failed on first extrapolation";
499 mCache[iRow].y[
ExtOut] = trkWork.getY();
500 mCache[iRow].z[
ExtOut] = trkWork.getZ();
501 mCache[iRow].sy2[
ExtOut] = trkWork.getSigmaY2();
502 mCache[iRow].szy[
ExtOut] = trkWork.getSigmaZY();
503 mCache[iRow].sz2[
ExtOut] = trkWork.getSigmaZ2();
504 mCache[iRow].snp[
ExtOut] = trkWork.getSnp();
510 LOG(
debug) <<
"TOF point available";
512 if (mDumpTrackPoints) {
513 (*trackDataExtended).clsTOF = clTOF;
514 (*trackDataExtended).matchTOF = mRecoCont->
getTOFMatch(mGIDs[iSeed]);
516 const int clTOFSec = clTOF.getCount();
518 if (!trkWork.rotate(clTOFAlpha)) {
519 LOG(
debug) <<
"Failed to rotate into TOF cluster sector frame";
522 float clTOFxyz[3] = {clTOF.getX(), clTOF.getY(), clTOF.getZ()};
523 if (!clTOF.isInNominalSector()) {
526 std::array<float, 2> clTOFYZ{clTOFxyz[1], clTOFxyz[2]};
528 if (!propagator->PropagateToXBxByBz(trkWork, clTOFxyz[0], mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
529 LOG(
debug) <<
"Failed final propagation to TOF radius";
533 if (!trkWork.update(clTOFYZ, clTOFCov)) {
534 LOG(
debug) <<
"Failed to update extrapolated ITS track with TOF cluster";
542 if (mDumpTrackPoints) {
543 (*trackDataExtended).trkTRD = trkTRD;
546 std::array<float, 2> trkltTRDYZ{};
547 std::array<float, 3> trkltTRDCov{};
555 if (!trkWork.update(trkltTRDYZ, trkltTRDCov)) {
556 LOG(
debug) <<
"Failed to update track at TRD layer " << iLayer;
562 if (mDumpTrackPoints) {
563 (*trackDataExtended).trkOuter = trkWork;
565 auto trkOuter = trkWork;
568 bool outerParamStored =
false;
569 for (
int iRow = param::NPadRows; iRow--;) {
570 if (!mCache[iRow].clAvailable) {
573 if (mProcessSeeds && !outerParamStored) {
579 trackData.
par = trkWork;
580 outerParamStored =
true;
582 if (!trkWork.rotate(mCache[iRow].clAngle)) {
583 LOG(
debug) <<
"Failed to rotate track during back propagation";
586 if (!propagator->PropagateToXBxByBz(trkWork, param::RowX[iRow], mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
587 LOG(
debug) <<
"Failed on back propagation";
591 mCache[iRow].y[
ExtIn] = trkWork.getY();
592 mCache[iRow].z[
ExtIn] = trkWork.getZ();
593 mCache[iRow].sy2[
ExtIn] = trkWork.getSigmaY2();
594 mCache[iRow].szy[
ExtIn] = trkWork.getSigmaZY();
595 mCache[iRow].sz2[
ExtIn] = trkWork.getSigmaZ2();
596 mCache[iRow].snp[
ExtIn] = trkWork.getSnp();
600 unsigned short deltaRow = 0;
601 for (
int iRow = 0; iRow < param::NPadRows; ++iRow) {
602 if (!mCache[iRow].clAvailable) {
606 float wTotY = 1.f / mCache[iRow].sy2[
ExtOut] + 1.f / mCache[iRow].sy2[
ExtIn];
607 float wTotZ = 1.f / mCache[iRow].sz2[
ExtOut] + 1.f / mCache[iRow].sz2[
ExtIn];
608 mCache[iRow].y[
Int] = (mCache[iRow].y[
ExtOut] / mCache[iRow].sy2[
ExtOut] + mCache[iRow].y[
ExtIn] / mCache[iRow].sy2[
ExtIn]) / wTotY;
609 mCache[iRow].z[
Int] = (mCache[iRow].z[
ExtOut] / mCache[iRow].sz2[
ExtOut] + mCache[iRow].z[
ExtIn] / mCache[iRow].sz2[
ExtIn]) / wTotZ;
612 mCache[iRow].snp[
Int] = (mCache[iRow].snp[
ExtOut] + mCache[iRow].snp[
ExtIn]) / 2.f;
614 const auto dY = mCache[iRow].clY - mCache[iRow].y[
Int];
615 const auto dZ = mCache[iRow].clZ - mCache[iRow].z[
Int];
616 const auto y = mCache[iRow].y[
Int];
617 const auto z = mCache[iRow].z[
Int];
618 const auto snp = mCache[iRow].snp[
Int];
619 const auto sec = mCache[iRow].clSec;
620 clusterResiduals.emplace_back(dY, dZ,
y,
z, snp, sec, deltaRow);
625 trackData.
chi2TPC = trkTPC.getChi2();
626 trackData.
chi2ITS = trkITS.getChi2();
627 trackData.
nClsTPC = trkTPC.getNClusterReferences();
628 trackData.
nClsITS = trkITS.getNumberOfClusters();
631 const auto& tofMatch = mRecoCont->
getTOFMatch(mGIDs[iSeed]);
632 trackData.
deltaTOF = tofMatch.getSignal() - tofMatch.getFT0Best() - tofMatch.getLTIntegralOut().getTOF(trkTPC.getPID().getID());
633 trackData.
clAvailTOF = uint16_t(tofMatch.getFT0BestRes());
637 trackData.
dEdxTPC = trkTPC.getdEdx().dEdxTotTPC;
642 int nClValidated = 0;
644 for (
unsigned int iCl = 0; iCl < clusterResiduals.size(); ++iCl) {
645 iRow += clusterResiduals[iCl].dRow;
646 if (
params.flagRej[iCl]) {
650 const float tgPhi = clusterResiduals[iCl].snp / std::sqrt((1.f - clusterResiduals[iCl].snp) * (1.f + clusterResiduals[iCl].snp));
651 const auto dy = clusterResiduals[iCl].dy;
652 const auto dz = clusterResiduals[iCl].dz;
653 const auto y = clusterResiduals[iCl].y;
654 const auto z = clusterResiduals[iCl].z;
655 const auto sec = clusterResiduals[iCl].sec;
656 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)) {
657 mClRes.emplace_back(dy, dz, tgPhi,
y,
z, iRow, sec);
660 ++mRejectedResiduals;
663 trackData.
clIdx.setEntries(nClValidated);
665 bool stopPropagation = !mExtDetResid;
666 if (!stopPropagation) {
672 std::array<float, 2> trkltTRDYZ{};
678 stopPropagation =
true;
682 float tgPhi = trkWork.getSnp() / std::sqrt((1.f - trkWork.getSnp()) * (1.f + trkWork.getSnp()));
683 auto dy = trkltTRDYZ[0] - trkWork.getY();
684 auto dz = trkltTRDYZ[1] - trkWork.getZ();
685 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)) {
693 while (gidTable[
GTrackID::TOF].isIndexSet() && !stopPropagation) {
695 float clTOFxyz[3] = {clTOF.getX(), clTOF.getY(), clTOF.getZ()};
696 if (!clTOF.isInNominalSector()) {
700 if (trkWork.getAlpha() != clTOFAlpha && !trkWork.rotate(clTOFAlpha)) {
701 LOG(
debug) <<
"Failed to rotate into TOF cluster sector frame";
702 stopPropagation =
true;
705 if (!propagator->PropagateToXBxByBz(trkWork, clTOFxyz[0], mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
706 LOG(
debug) <<
"Failed final propagation to TOF radius";
710 float tgPhi = trkWork.getSnp() / std::sqrt((1.f - trkWork.getSnp()) * (1.f + trkWork.getSnp()));
711 auto dy = clTOFxyz[1] - trkWork.getY();
712 auto dz = clTOFxyz[2] - trkWork.getZ();
713 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)) {
714 mClRes.emplace_back(dy, dz, tgPhi, trkWork.getY(), trkWork.getZ(), 170, clTOF.getCount(), clTOF.getPadInSector());
721 while (!stopPropagation) {
722 auto& trkWorkITS = trkInner;
723 auto nCl = trkITS.getNumberOfClusters();
724 auto clEntry = trkITS.getFirstClusterEntry();
726 for (
int iCl = 0; iCl < nCl; iCl++) {
727 const auto& cls = mITSClustersArray[mITSTrackClusIdx[clEntry + iCl]];
728 int chip = cls.getSensorID();
729 float chipX, chipAlpha;
730 geom->getSensorXAlphaRefPlane(cls.getSensorID(), chipX, chipAlpha);
731 if (!trkWorkITS.rotate(chipAlpha) || !propagator->PropagateToXBxByBz(trkWorkITS, chipX, mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
732 LOGP(
debug,
"Failed final propagation to ITS X={} alpha={}", chipX, chipAlpha);
733 stopPropagation =
true;
736 float tgPhi = trkWorkITS.getSnp() / std::sqrt((1.f - trkWorkITS.getSnp()) * (1.f + trkWorkITS.getSnp()));
737 auto dy = cls.getY() - trkWorkITS.getY();
738 auto dz = cls.getZ() - trkWorkITS.getZ();
739 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)) {
740 mClRes.emplace_back(dy, dz, tgPhi, trkWorkITS.getY(), trkWorkITS.getZ(), 180 + geom->getLayer(cls.getSensorID()), -1, cls.getSensorID());
744 if (!stopPropagation) {
747 if (!propagator->propagateToDCA(vtx, trkWorkITS, mBz, mParams->
maxStep, mMatCorr)) {
748 LOGP(
debug,
"Failed propagation to DCA to PV ({} {} {}), {}", pv.getX(), pv.getY(), pv.getZ(), trkWorkITS.asString());
749 stopPropagation =
true;
753 float sn, cs,
alpha = trkWorkITS.getAlpha();
754 math_utils::detail::bringToPMPi(
alpha);
755 math_utils::detail::sincos<float>(
alpha, sn, cs);
756 float xv = vtx.X() * cs + vtx.Y() * sn, yv = -vtx.X() * sn + vtx.Y() * cs, zv = vtx.Z();
757 auto dy = yv - trkWorkITS.getY();
758 auto dz = zv - trkWorkITS.getZ();
759 if ((std::abs(dy) < param::MaxResid) && (std::abs(dz) < param::MaxResid) && (std::abs(trkWorkITS.getY()) < param::MaxY) && (std::abs(trkWorkITS.getZ()) < param::MaxZ) && abs(xv) < param::MaxVtxX) {
760 short compXV =
static_cast<short>(xv * 0x7fff / param::MaxVtxX);
761 mClRes.emplace_back(dy, dz,
alpha / TMath::Pi(), trkWorkITS.getY(), trkWorkITS.getZ(), 190, -1, compXV);
769 mGIDsSuccess.push_back(mGIDs[iSeed]);
770 mTrackDataCompact.emplace_back(trackData.
clIdx.getFirstEntry(), nClValidated, mGIDs[iSeed].getSource(), trackData.
nExtDetResid);
771 mTrackData.push_back(std::move(trackData));
772 if (mDumpTrackPoints) {
773 (*trackDataExtended).clIdx.setEntries(nClValidated);
774 (*trackDataExtended).nExtDetResid = trackData.
nExtDetResid;
775 mTrackDataExtended.push_back(std::move(*trackDataExtended));
780 trkDataTmp.
clIdx.setFirstEntry(mClResUnfiltered.size());
781 trkDataTmp.
clIdx.setEntries(clusterResiduals.size());
782 mTrackDataUnfiltered.push_back(std::move(trkDataTmp));
783 mClResUnfiltered.insert(mClResUnfiltered.end(), clusterResiduals.begin(), clusterResiduals.end());
836 LOGP(
debug,
"Starting track extrapolation for GID {}", mGIDs[iSeed].
asString());
837 const auto& gidTable = mGIDtables[iSeed];
839 std::unique_ptr<TrackDataExtended> trackDataExtended;
840 std::vector<TPCClusterResiduals> clusterResiduals;
841 trackData.
clIdx.setFirstEntry(mClRes.size());
844 if (mDumpTrackPoints) {
845 trackDataExtended = std::make_unique<TrackDataExtended>();
846 (*trackDataExtended).gid = mGIDs[iSeed];
847 (*trackDataExtended).clIdx.setFirstEntry(mClRes.size());
848 (*trackDataExtended).trkITS = trkITS;
849 (*trackDataExtended).trkTPC = trkTPC;
850 auto nCl = trkITS.getNumberOfClusters();
851 auto clEntry = trkITS.getFirstClusterEntry();
852 for (
int iCl = nCl - 1; iCl >= 0; iCl--) {
853 const auto& clsITS = mITSClustersArray[mITSTrackClusIdx[clEntry + iCl]];
854 (*trackDataExtended).clsITS.push_back(clsITS);
860 trackData.
gid = mGIDs[iSeed];
861 trackData.
par = mSeeds[iSeed];
863 auto trkWork = mSeeds[iSeed];
864 float clusterTimeBinOffset = mTrackTimes[iSeed] / mTPCTimeBinMUS;
866 unsigned short rowPrev = 0;
867 unsigned short nMeasurements = 0;
869 for (
int iCl = trkTPC.getNClusterReferences(); iCl--;) {
871 uint32_t clusterIndexInRow;
872 const auto& cl = trkTPC.getCluster(mTPCTracksClusIdx, iCl, *mTPCClusterIdxStruct, sector,
row);
873 if (clRowPrev ==
row) {
876 }
else if (clRowPrev < constants::MAXGLOBALPADROW && clRowPrev >
row) {
878 LOGP(
debug,
"TPC track with pT={} GeV and {} clusters has cluster {} on row {} while the previous cluster was on row {}",
879 mSeeds[iSeed].getPt(), trkTPC.getNClusterReferences(), iCl,
row, clRowPrev);
885 float x = 0,
y = 0,
z = 0;
886 mFastTransform->TransformIdeal(sector,
row, cl.getPad(), cl.getTime(),
x,
y,
z, clusterTimeBinOffset);
890 if (!propagator->PropagateToXBxByBz(trkWork,
x, mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
894 const auto dY =
y - trkWork.getY();
895 const auto dZ =
z - trkWork.getZ();
896 const auto ty = trkWork.getY();
897 const auto tz = trkWork.getZ();
898 const auto snp = trkWork.getSnp();
899 const auto sec = sector;
901 clusterResiduals.emplace_back(dY, dZ, ty, tz, snp, sec,
row - rowPrev);
909 LOGP(warn,
"Extrapolated ITS-TPC track and found more residuals than possible ({})", clusterResiduals.size());
913 trackData.
chi2TPC = trkTPC.getChi2();
914 trackData.
chi2ITS = trkITS.getChi2();
915 trackData.
nClsTPC = trkTPC.getNClusterReferences();
916 trackData.
nClsITS = trkITS.getNumberOfClusters();
917 trackData.
clIdx.setEntries(nMeasurements);
918 trackData.
dEdxTPC = trkTPC.getdEdx().dEdxTotTPC;
919 if (mDumpTrackPoints) {
920 (*trackDataExtended).trkOuter = trkWork;
926 int nClValidated = 0, iRow = 0;
927 unsigned int iCl = 0;
928 for (iCl = 0; iCl < clusterResiduals.size(); ++iCl) {
929 iRow += clusterResiduals[iCl].dRow;
930 if (iRow < param::NPadRows &&
params.flagRej[iCl]) {
933 const float tgPhi = clusterResiduals[iCl].snp / std::sqrt((1.f - clusterResiduals[iCl].snp) * (1.f + clusterResiduals[iCl].snp));
934 const auto dy = clusterResiduals[iCl].dy;
935 const auto dz = clusterResiduals[iCl].dz;
936 const auto y = clusterResiduals[iCl].y;
937 const auto z = clusterResiduals[iCl].z;
938 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)) {
939 mClRes.emplace_back(dy, dz, tgPhi,
y,
z, iRow, clusterResiduals[iCl].sec);
942 ++mRejectedResiduals;
945 trackData.
clIdx.setEntries(nClValidated);
947 bool stopPropagation = !mExtDetResid;
948 if (!stopPropagation) {
950 int iSeedFull = mParentID[iSeed] == -1 ? iSeed : mParentID[iSeed];
951 auto gidFull = mGIDs[iSeedFull];
952 const auto& gidTableFull = mGIDtables[iSeedFull];
955 trackData.
nTrkltsTRD = trkTRD.getNtracklets();
957 std::array<float, 2> trkltTRDYZ{};
963 stopPropagation =
true;
967 float tgPhi = trkWork.getSnp() / std::sqrt((1.f - trkWork.getSnp()) * (1.f + trkWork.getSnp()));
968 auto dy = trkltTRDYZ[0] - trkWork.getY();
969 auto dz = trkltTRDYZ[1] - trkWork.getZ();
970 const auto sec = clusterResiduals[iCl].sec;
971 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)) {
980 while (gidTableFull[
GTrackID::TOF].isIndexSet() && !stopPropagation) {
981 const auto& tofMatch = mRecoCont->
getTOFMatch(gidFull);
982 trackData.
deltaTOF = tofMatch.getSignal() - tofMatch.getFT0Best() - tofMatch.getLTIntegralOut().getTOF(trkTPC.getPID().getID());
983 trackData.
clAvailTOF = uint16_t(tofMatch.getFT0BestRes());
986 float clTOFxyz[3] = {clTOF.getX(), clTOF.getY(), clTOF.getZ()};
987 if (!clTOF.isInNominalSector()) {
990 if (trkWork.getAlpha() != clTOFAlpha && !trkWork.rotate(clTOFAlpha)) {
991 LOG(
debug) <<
"Failed to rotate into TOF cluster sector frame";
992 stopPropagation =
true;
995 if (!propagator->PropagateToXBxByBz(trkWork, clTOFxyz[0], mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
996 LOG(
debug) <<
"Failed final propagation to TOF radius";
1000 float tgPhi = trkWork.getSnp() / std::sqrt((1.f - trkWork.getSnp()) * (1.f + trkWork.getSnp()));
1001 auto dy = clTOFxyz[1] - trkWork.getY();
1002 auto dz = clTOFxyz[2] - trkWork.getZ();
1003 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)) {
1004 mClRes.emplace_back(dy, dz, tgPhi, trkWork.getY(), trkWork.getZ(), 170, clTOF.getCount(), clTOF.getPadInSector());
1011 while (!stopPropagation) {
1013 auto nCl = trkITS.getNumberOfClusters();
1014 auto clEntry = trkITS.getFirstClusterEntry();
1016 for (
int iCl = 0; iCl < nCl; iCl++) {
1017 const auto& cls = mITSClustersArray[mITSTrackClusIdx[clEntry + iCl]];
1018 int chip = cls.getSensorID();
1019 float chipX, chipAlpha;
1020 geom->getSensorXAlphaRefPlane(cls.getSensorID(), chipX, chipAlpha);
1021 if (!trkWorkITS.rotate(chipAlpha) || !propagator->propagateToX(trkWorkITS, chipX, mBz, mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
1022 LOGP(
debug,
"Failed final propagation to ITS X={} alpha={}", chipX, chipAlpha);
1023 stopPropagation =
true;
1026 float tgPhi = trkWorkITS.getSnp() / std::sqrt((1.f - trkWorkITS.getSnp()) * (1.f + trkWorkITS.getSnp()));
1027 auto dy = cls.getY() - trkWorkITS.getY();
1028 auto dz = cls.getZ() - trkWorkITS.getZ();
1029 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)) {
1030 mClRes.emplace_back(dy, dz, tgPhi, trkWorkITS.getY(), trkWorkITS.getZ(), 180 + geom->getLayer(cls.getSensorID()), -1, cls.getSensorID());
1034 if (!stopPropagation) {
1037 if (!propagator->propagateToDCA(vtx, trkWorkITS, mBz, mParams->
maxStep, mMatCorr)) {
1038 LOGP(
debug,
"Failed propagation to DCA to PV ({} {} {}), {}", pv.getX(), pv.getY(), pv.getZ(), trkWorkITS.asString());
1039 stopPropagation =
true;
1043 float sn, cs,
alpha = trkWorkITS.getAlpha();
1044 math_utils::detail::bringToPMPi(
alpha);
1045 math_utils::detail::sincos<float>(
alpha, sn, cs);
1046 float xv = vtx.X() * cs + vtx.Y() * sn, yv = -vtx.X() * sn + vtx.Y() * cs, zv = vtx.Z();
1047 auto dy = yv - trkWorkITS.getY();
1048 auto dz = zv - trkWorkITS.getZ();
1049 if ((std::abs(dy) < param::MaxResid) && (std::abs(dz) < param::MaxResid) && (std::abs(trkWorkITS.getY()) < param::MaxY) && (std::abs(trkWorkITS.getZ()) < param::MaxZ) && abs(xv) < param::MaxVtxX) {
1050 short compXV =
static_cast<short>(xv * 0x7fff / param::MaxVtxX);
1051 mClRes.emplace_back(dy, dz,
alpha / TMath::Pi(), trkWorkITS.getY(), trkWorkITS.getZ(), 190, -1, compXV);
1058 mTrackData.push_back(std::move(trackData));
1059 mGIDsSuccess.push_back(mGIDs[iSeed]);
1060 mTrackDataCompact.emplace_back(trackData.
clIdx.getFirstEntry(), nClValidated, mGIDs[iSeed].getSource(), trackData.
nExtDetResid);
1061 if (mDumpTrackPoints) {
1062 (*trackDataExtended).clIdx.setEntries(nClValidated);
1063 (*trackDataExtended).nExtDetResid = trackData.
nExtDetResid;
1064 mTrackDataExtended.push_back(std::move(*trackDataExtended));
1069 trkDataTmp.
clIdx.setFirstEntry(mClResUnfiltered.size());
1070 trkDataTmp.
clIdx.setEntries(clusterResiduals.size());
1071 mTrackDataUnfiltered.push_back(std::move(trkDataTmp));
1072 mClResUnfiltered.insert(mClResUnfiltered.end(), clusterResiduals.begin(), clusterResiduals.end());
1101 std::array<float, param::NPadRows> residHelixY;
1102 std::array<float, param::NPadRows> residHelixZ;
1104 std::array<float, param::NPadRows> xLab;
1105 std::array<float, param::NPadRows> yLab;
1106 std::array<float, param::NPadRows> sPath;
1109 int secFirst = clsRes[0].sec;
1111 float snPhi = sin(phiSect);
1112 float csPhi = cos(phiSect);
1116 int nCl = clsRes.size();
1117 for (
unsigned int iP = 0; iP < nCl; ++iP) {
1118 iRow += clsRes[iP].dRow;
1119 float yTrk = clsRes[iP].y;
1121 xLab[iP] = param::RowX[iRow];
1122 if (clsRes[iP].sec != secFirst) {
1124 float cs = cos(phiSectCurrent - phiSect);
1125 float sn = sin(phiSectCurrent - phiSect);
1126 xLab[iP] = param::RowX[iRow] * cs - yTrk * sn;
1127 yLab[iP] = yTrk * cs + param::RowX[iRow] * sn;
1129 xLab[iP] = param::RowX[iRow];
1133 params.zTrk[iP] = clsRes[iP].z;
1134 params.xTrk[iP] = param::RowX[iRow];
1135 params.dy[iP] = clsRes[iP].dy;
1136 params.dz[iP] = clsRes[iP].dz;
1139 float dx = xLab[iP] - xLab[iP - 1];
1140 float dy = yLab[iP] - yLab[iP - 1];
1141 float ds2 = dx * dx + dy * dy;
1142 float ds = sqrt(ds2);
1146 if (
ds * curvature > 0.05) {
1147 ds *= (1.f + ds2 * curvature * curvature / 24.f);
1149 sPath[iP] = sPath[iP - 1] +
ds;
1152 if (fabsf(mBz) < 0.01) {
1167 float phiI = TMath::ATan2(yLab[0], xLab[0]);
1168 float phiF = TMath::ATan2(yLab[nCl - 1], xLab[nCl - 1]);
1175 float dPhi = phiF - phiI;
1176 float curvSign = -1.f;
1187 float xc = xcSec * csPhi - ycSec * snPhi;
1188 float yc = xcSec * snPhi + ycSec * csPhi;
1190 std::array<float, 2> pol1Z;
1197 float hMaxY = -1e9f;
1199 float hMaxZ = -1e9f;
1201 int secCurr = secFirst;
1203 for (
unsigned int iCl = 0; iCl < nCl; ++iCl) {
1204 iRow += clsRes[iCl].dRow;
1205 float resZ =
params.zTrk[iCl] - (pol1Z[1] + sPath[iCl] * pol1Z[0]);
1206 residHelixZ[iCl] = resZ;
1213 if (residHelixY[iCl] < hMinY) {
1214 hMinY = residHelixY[iCl];
1216 if (residHelixY[iCl] > hMaxY) {
1217 hMaxY = residHelixY[iCl];
1219 int sec = clsRes[iCl].sec;
1220 if (sec != secCurr) {
1223 snPhi = sin(phiSect);
1224 csPhi = cos(phiSect);
1225 xcSec = xc * csPhi + yc * snPhi;
1227 float cstalp = (param::RowX[iRow] - xcSec) /
r;
1228 if (fabsf(cstalp) > 1.f - sFloatEps) {
1230 cstalp = std::copysign(1.f - sFloatEps, cstalp);
1232 params.tglArr[iCl] = cstalp / sqrt((1 - cstalp) * (1 + cstalp));
1235 if (
params.qpt * mBz > 0) {
1236 params.tglArr[iCl] *= -1.f;
1264 float rmsLong = 0.f;
1266 int nCl = clsRes.size();
1268 int iClLast = nCl - 1;
1269 int secStart = clsRes[0].sec;
1272 std::array<float, param::NPadRows> yDiffLL{};
1273 std::array<float, param::NPadRows> zDiffLL{};
1274 std::array<float, param::NPadRows> absDevY{};
1275 std::array<float, param::NPadRows> absDevZ{};
1277 for (
unsigned int iCl = 0; iCl < nCl; ++iCl) {
1278 if (iCl < iClLast && clsRes[iCl].sec == secStart) {
1283 int nClSec = iCl - iClFirst;
1284 if (iCl == iClLast) {
1290 secStart = clsRes[iCl].sec;
1295 for (
int iCl = nCl; iCl--;) {
1296 if (fabsf(yDiffLL[iCl]) > param::sEps) {
1297 absDevY[nAccY++] = fabsf(yDiffLL[iCl]);
1299 if (fabsf(zDiffLL[iCl]) > param::sEps) {
1300 absDevZ[nAccZ++] = fabsf(zDiffLL[iCl]);
1303 if (nAccY < mParams->minNumberOfAcceptedResiduals || nAccZ < mParams->minNumberOfAcceptedResiduals) {
1310 int nKeepY =
static_cast<int>(.9 * nAccY);
1311 int nKeepZ =
static_cast<int>(.9 * nAccZ);
1312 std::nth_element(absDevY.begin(), absDevY.begin() + nKeepY, absDevY.begin() + nAccY);
1313 std::nth_element(absDevZ.begin(), absDevZ.begin() + nKeepZ, absDevZ.begin() + nAccZ);
1314 float rmsYkeep = 0.f;
1315 float rmsZkeep = 0.f;
1316 for (
int i = nKeepY;
i--;) {
1317 rmsYkeep += absDevY[
i] * absDevY[
i];
1319 for (
int i = nKeepZ;
i--;) {
1320 rmsZkeep += absDevZ[
i] * absDevZ[
i];
1322 rmsYkeep = std::sqrt(rmsYkeep / nKeepY);
1323 rmsZkeep = std::sqrt(rmsZkeep / nKeepZ);
1324 if (rmsYkeep < param::sEps || rmsZkeep < param::sEps) {
1325 LOG(warning) <<
"Too small RMS: " << rmsYkeep <<
"(y), " << rmsZkeep <<
"(z).";
1329 float rmsYkeepI = 1.f / rmsYkeep;
1330 float rmsZkeepI = 1.f / rmsZkeep;
1332 std::array<float, param::NPadRows> yAcc;
1333 std::array<float, param::NPadRows> yDiffLong;
1334 for (
int iCl = 0; iCl < nCl; ++iCl) {
1335 yDiffLL[iCl] *= rmsYkeepI;
1336 zDiffLL[iCl] *= rmsZkeepI;
1337 if (yDiffLL[iCl] * yDiffLL[iCl] + zDiffLL[iCl] * zDiffLL[iCl] > mParams->
maxStdDevMA) {
1340 yAcc[nAcc++] =
params.dy[iCl];
1343 if (nAcc > mParams->
nMALong) {
1345 float average = 0.f;
1347 for (
int i = 0;
i < nAcc; ++
i) {
1348 average += yDiffLong[
i];
1349 rms += yDiffLong[
i] * yDiffLong[
i];
1352 rmsLong = rms / nAcc - average * average;
1353 rmsLong = (rmsLong > 0) ? std::sqrt(rmsLong) : 0.f;