59 return param::RowX[
row];
67 ROOT::Math::Impl::Transform3D<double>::Point local{geo->cdrHght() - 0.5 - 0.279, 0., 0.};
68 return (geo->getMatrixT2L(
channel) ^ local).X();
73 float pos[3] = {0.f, 0.f, 0.f};
79 LOGP(fatal,
"Did not recognize detector type: row:{}, sec:{}, channel:{}",
row,
sec,
channel);
86 LOGP(warn,
"geometry initialization was not done, doing this for the current timestamp");
89 LOGP(fatal,
"geometry initialization failed");
97 LOGP(warn,
"Initialization was already done");
104 geoTRD->createPadPlaneArray();
105 geoTRD->createClusterMatrixArray();
112 LOG(info) <<
"Start initializing TrackInterpolation";
114 LOG(error) <<
"Initialization already performed.";
119 mTPCTimeBinMUS = elParam.ZbinWidth;
128 mSourcesConfigured =
src;
129 mSourcesConfiguredMap = srcMap;
130 mSingleSourcesConfigured = (mSourcesConfigured == mSourcesConfiguredMap);
140 LOGP(info,
"Done initializing TrackInterpolation. Configured track input: {}. Track input specifically for map: {}",
146 LOGP(
debug,
"Check if input track {} is accepted", gid.
asString());
148 if (!hasOuterPoint && !mProcessITSTPConly) {
162 if (itsTrk.getChi2() / itsTrk.getNumberOfClusters() > mParams->
maxITSChi2 || tpcTrk.getChi2() / tpcTrk.getNClusterReferences() > mParams->
maxTPCChi2) {
165 if (!hasOuterPoint) {
174 if (itsTrk.getNumberOfClusters() < mParams->
minITSNCls || tpcTrk.getNClusterReferences() < mParams->
minTPCNCls) {
182 if (!prop->propagateToDCA(pv, trc, prop->getNominalBz(), 2., o2::base::PropagatorF::MatCorrType::USEMatCorrLUT, &dca)) {
216 uint32_t nTrackSeeds = 0;
217 uint32_t countSeedCandidates[4] = {0};
221 int nv = vtxRefs.size() - 1;
225 for (
int iv = 0; iv < nv; iv++) {
226 LOGP(
debug,
"processing PV {} of {}", iv, nv);
228 const auto& vtref = vtxRefs[iv];
233 for (uint32_t is = 0; is < SrcFast.size() && !usePV; is++) {
234 int src = SrcFast[is], idMin = vtref.getFirstEntryOfSource(
src), idMax = idMin + vtref.getEntriesOfSource(
src);
235 for (
int i = idMin;
i < idMax;
i++) {
248 if (!allowedSources[is]) {
251 LOGP(
debug,
"Checking source {}", is);
252 int idMin = vtref.getFirstEntryOfSource(is), idMax = idMin + vtref.getEntriesOfSource(is);
253 for (
int i = idMin;
i < idMax;
i++) {
254 auto vid = trackIndex[
i];
259 if (vid.isAmbiguous()) {
263 if (!mSourcesConfigured[is]) {
273 ++countSeedCandidates[mTrackTypes[vid.getSource()]];
274 LOGP(
debug,
"Checking vid {}", vid.asString());
279 mSeeds.back().setPID(mRecoCont->
getTrackParam(vidOrig).getPID(),
true);
280 mGIDs.push_back(vid);
281 mGIDtables.push_back(gidTable);
282 mTrackTimes.push_back(pv.getTimeStamp().getTimeStamp());
283 mTrackIndices[mTrackTypes[vid.getSource()]].push_back(nTrackSeeds++);
288 LOGP(info,
"Created {} seeds. {} out of {} ITS-TPC-TRD-TOF, {} out of {} ITS-TPC-TRD, {} out of {} ITS-TPC-TOF, {} out of {} ITS-TPC",
298 std::random_device
rd;
299 std::mt19937
g(
rd());
300 std::uniform_real_distribution<>
distr(0., 1.);
309 LOG(error) <<
"Initialization not yet done. Aborting...";
317 LOG(error) <<
"No ITS dictionary available";
323 auto pattIt = patterns.begin();
324 mITSClustersArray.clear();
325 mITSClustersArray.reserve(clusITS.size());
326 LOGP(info,
"We have {} ITS clusters and the number of patterns is {}", clusITS.size(), patterns.size());
334 std::random_device
rd;
335 std::mt19937
g(
rd());
336 std::vector<uint32_t> trackIndices;
346 int nSeeds = mSeeds.size(), lastChecked = 0;
348 mParentID.resize(nSeeds, -1);
350 int maxOutputTracks = (mMaxTracksPerTF >= 0) ? mMaxTracksPerTF + mAddTracksForMapPerTF : nSeeds;
351 mTrackData.reserve(maxOutputTracks);
352 mClRes.reserve(maxOutputTracks * param::NPadRows);
353 bool maxTracksReached =
false;
354 for (
int iSeed = 0; iSeed < nSeeds; ++iSeed) {
355 if (mMaxTracksPerTF >= 0 && mTrackDataCompact.size() >= mMaxTracksPerTF + mAddTracksForMapPerTF) {
356 LOG(info) <<
"Maximum number of tracks per TF reached. Skipping the remaining " << nSeeds - iSeed <<
" tracks.";
359 int seedIndex = trackIndices[iSeed];
365 this->mGIDs.push_back(this->mGIDtables[seedIndex][
src]);
367 this->mTrackTimes.push_back(this->mTrackTimes[seedIndex]);
368 this->mSeeds.push_back(this->mSeeds[seedIndex]);
369 this->mParentID.push_back(seedIndex);
373 if (!mSingleSourcesConfigured && !mSourcesConfiguredMap[mGIDs[seedIndex].getSource()]) {
380 if (mMaxTracksPerTF >= 0 && mTrackDataCompact.size() >= mMaxTracksPerTF) {
381 if (!maxTracksReached) {
382 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);
384 maxTracksReached =
true;
389 LOGP(
debug,
"interpolateTrack {} {}, accepted: {}", iSeed,
GTrackID::getSourceName(mGIDs[seedIndex].getSource()), mTrackDataCompact.size());
400 LOGP(
debug,
"extrapolateTrack {} {}, accepted: {}", iSeed,
GTrackID::getSourceName(mGIDs[seedIndex].getSource()), mTrackDataCompact.size());
404 std::vector<int> remSeeds;
405 if (mSeeds.size() > ++lastChecked) {
406 remSeeds.resize(mSeeds.size() - lastChecked);
407 std::iota(remSeeds.begin(), remSeeds.end(), lastChecked);
408 std::shuffle(remSeeds.begin(), remSeeds.end(),
g);
409 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());
411 int extraChecked = 0;
412 for (
int iSeed : remSeeds) {
413 if (mAddTracksForMapPerTF > 0 && mTrackDataCompact.size() >= mMaxTracksPerTF + mAddTracksForMapPerTF) {
414 LOGP(info,
"Maximum number {} of additional tracks per TF reached. Skipping the remaining {} tracks", mAddTracksForMapPerTF, remSeeds.size() - extraChecked);
420 LOGP(
debug,
"extra check {} of {}, seed {} interpolateTrack {}, used: {}", extraChecked, remSeeds.size(), iSeed,
GTrackID::getSourceName(mGIDs[iSeed].getSource()), mTrackDataCompact.size());
422 LOGP(
debug,
"extra check {} of {}, seed {} extrapolateTrack {}, used: {}", extraChecked, remSeeds.size(), iSeed,
GTrackID::getSourceName(mGIDs[iSeed].getSource()), mTrackDataCompact.size());
426 LOG(info) <<
"Could process " << mTrackData.size() <<
" tracks successfully. " << mRejectedResiduals <<
" residuals were rejected. " << mClRes.size() <<
" residuals were accepted.";
427 mRejectedResiduals = 0;
432 LOGP(
debug,
"Starting track interpolation for GID {}", mGIDs[iSeed].
asString());
434 std::unique_ptr<TrackDataExtended> trackDataExtended;
435 std::vector<TPCClusterResiduals> clusterResiduals;
437 const auto& gidTable = mGIDtables[iSeed];
440 if (mDumpTrackPoints) {
441 trackDataExtended = std::make_unique<TrackDataExtended>();
442 (*trackDataExtended).gid = mGIDs[iSeed];
443 (*trackDataExtended).clIdx.setFirstEntry(mClRes.size());
444 (*trackDataExtended).trkITS = trkITS;
445 (*trackDataExtended).trkTPC = trkTPC;
446 auto nCl = trkITS.getNumberOfClusters();
447 auto clEntry = trkITS.getFirstClusterEntry();
448 for (
int iCl = nCl - 1; iCl >= 0; iCl--) {
449 const auto& clsITS = mITSClustersArray[mITSTrackClusIdx[clEntry + iCl]];
450 (*trackDataExtended).clsITS.push_back(clsITS);
453 trackData.
gid = mGIDs[iSeed];
454 trackData.
par = mSeeds[iSeed];
455 auto& trkWork = mSeeds[iSeed];
458 for (
auto& elem : mCache) {
459 elem.clAvailable = 0;
461 trackData.
clIdx.setFirstEntry(mClRes.size());
462 float clusterTimeBinOffset = mTrackTimes[iSeed] / mTPCTimeBinMUS;
465 for (
int iCl = trkTPC.getNClusterReferences(); iCl--;) {
467 uint32_t clusterIndexInRow;
468 const auto& clTPC = trkTPC.getCluster(mTPCTracksClusIdx, iCl, *mTPCClusterIdxStruct, sector,
row);
470 std::array<float, 2> clTPCYZ;
471 mFastTransform->TransformIdeal(sector,
row, clTPC.getPad(), clTPC.getTime(), clTPCX, clTPCYZ[0], clTPCYZ[1], clusterTimeBinOffset);
472 mCache[
row].clSec = sector;
473 mCache[
row].clAvailable = 1;
474 mCache[
row].clY = clTPCYZ[0];
475 mCache[
row].clZ = clTPCYZ[1];
480 for (
int iRow = 0; iRow < param::NPadRows; ++iRow) {
481 if (!mCache[iRow].clAvailable) {
484 if (!trkWork.rotate(mCache[iRow].clAngle)) {
485 LOG(
debug) <<
"Failed to rotate track during first extrapolation";
488 if (!propagator->PropagateToXBxByBz(trkWork, param::RowX[iRow], mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
489 LOG(
debug) <<
"Failed on first extrapolation";
492 mCache[iRow].y[
ExtOut] = trkWork.getY();
493 mCache[iRow].z[
ExtOut] = trkWork.getZ();
494 mCache[iRow].sy2[
ExtOut] = trkWork.getSigmaY2();
495 mCache[iRow].szy[
ExtOut] = trkWork.getSigmaZY();
496 mCache[iRow].sz2[
ExtOut] = trkWork.getSigmaZ2();
497 mCache[iRow].snp[
ExtOut] = trkWork.getSnp();
503 LOG(
debug) <<
"TOF point available";
505 if (mDumpTrackPoints) {
506 (*trackDataExtended).clsTOF = clTOF;
507 (*trackDataExtended).matchTOF = mRecoCont->
getTOFMatch(mGIDs[iSeed]);
509 const int clTOFSec = clTOF.getCount();
511 if (!trkWork.rotate(clTOFAlpha)) {
512 LOG(
debug) <<
"Failed to rotate into TOF cluster sector frame";
515 float clTOFxyz[3] = {clTOF.getX(), clTOF.getY(), clTOF.getZ()};
516 if (!clTOF.isInNominalSector()) {
519 std::array<float, 2> clTOFYZ{clTOFxyz[1], clTOFxyz[2]};
521 if (!propagator->PropagateToXBxByBz(trkWork, clTOFxyz[0], mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
522 LOG(
debug) <<
"Failed final propagation to TOF radius";
526 if (!trkWork.update(clTOFYZ, clTOFCov)) {
527 LOG(
debug) <<
"Failed to update extrapolated ITS track with TOF cluster";
535 if (mDumpTrackPoints) {
536 (*trackDataExtended).trkTRD = trkTRD;
539 std::array<float, 2> trkltTRDYZ{};
540 std::array<float, 3> trkltTRDCov{};
548 if (!trkWork.update(trkltTRDYZ, trkltTRDCov)) {
549 LOG(
debug) <<
"Failed to update track at TRD layer " << iLayer;
555 if (mDumpTrackPoints) {
556 (*trackDataExtended).trkOuter = trkWork;
558 auto trkOuter = trkWork;
561 bool outerParamStored =
false;
562 for (
int iRow = param::NPadRows; iRow--;) {
563 if (!mCache[iRow].clAvailable) {
566 if (mProcessSeeds && !outerParamStored) {
572 trackData.
par = trkWork;
573 outerParamStored =
true;
575 if (!trkWork.rotate(mCache[iRow].clAngle)) {
576 LOG(
debug) <<
"Failed to rotate track during back propagation";
579 if (!propagator->PropagateToXBxByBz(trkWork, param::RowX[iRow], mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
580 LOG(
debug) <<
"Failed on back propagation";
584 mCache[iRow].y[
ExtIn] = trkWork.getY();
585 mCache[iRow].z[
ExtIn] = trkWork.getZ();
586 mCache[iRow].sy2[
ExtIn] = trkWork.getSigmaY2();
587 mCache[iRow].szy[
ExtIn] = trkWork.getSigmaZY();
588 mCache[iRow].sz2[
ExtIn] = trkWork.getSigmaZ2();
589 mCache[iRow].snp[
ExtIn] = trkWork.getSnp();
593 unsigned short deltaRow = 0;
594 for (
int iRow = 0; iRow < param::NPadRows; ++iRow) {
595 if (!mCache[iRow].clAvailable) {
599 float wTotY = 1.f / mCache[iRow].sy2[
ExtOut] + 1.f / mCache[iRow].sy2[
ExtIn];
600 float wTotZ = 1.f / mCache[iRow].sz2[
ExtOut] + 1.f / mCache[iRow].sz2[
ExtIn];
601 mCache[iRow].y[
Int] = (mCache[iRow].y[
ExtOut] / mCache[iRow].sy2[
ExtOut] + mCache[iRow].y[
ExtIn] / mCache[iRow].sy2[
ExtIn]) / wTotY;
602 mCache[iRow].z[
Int] = (mCache[iRow].z[
ExtOut] / mCache[iRow].sz2[
ExtOut] + mCache[iRow].z[
ExtIn] / mCache[iRow].sz2[
ExtIn]) / wTotZ;
605 mCache[iRow].snp[
Int] = (mCache[iRow].snp[
ExtOut] + mCache[iRow].snp[
ExtIn]) / 2.f;
607 const auto dY = mCache[iRow].clY - mCache[iRow].y[
Int];
608 const auto dZ = mCache[iRow].clZ - mCache[iRow].z[
Int];
609 const auto y = mCache[iRow].y[
Int];
610 const auto z = mCache[iRow].z[
Int];
611 const auto snp = mCache[iRow].snp[
Int];
612 const auto sec = mCache[iRow].clSec;
613 clusterResiduals.emplace_back(dY, dZ,
y,
z, snp, sec, deltaRow);
618 trackData.
chi2TPC = trkTPC.getChi2();
619 trackData.
chi2ITS = trkITS.getChi2();
620 trackData.
nClsTPC = trkTPC.getNClusterReferences();
621 trackData.
nClsITS = trkITS.getNumberOfClusters();
624 const auto& tofMatch = mRecoCont->
getTOFMatch(mGIDs[iSeed]);
625 trackData.
deltaTOF = tofMatch.getSignal() - tofMatch.getFT0Best() - tofMatch.getLTIntegralOut().getTOF(trkTPC.getPID().getID());
626 trackData.
clAvailTOF = uint16_t(tofMatch.getFT0BestRes());
630 trackData.
dEdxTPC = trkTPC.getdEdx().dEdxTotTPC;
635 int nClValidated = 0;
637 for (
unsigned int iCl = 0; iCl < clusterResiduals.size(); ++iCl) {
638 iRow += clusterResiduals[iCl].dRow;
639 if (
params.flagRej[iCl]) {
644 const float tgPhi = clusterResiduals[iCl].snp / std::sqrt((1.f - clusterResiduals[iCl].snp) * (1.f + clusterResiduals[iCl].snp));
645 const auto dy = clusterResiduals[iCl].dy;
646 const auto dz = clusterResiduals[iCl].dz;
647 const auto y = clusterResiduals[iCl].y;
648 const auto z = clusterResiduals[iCl].z;
649 const auto sec = clusterResiduals[iCl].sec;
650 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)) {
651 mClRes.emplace_back(dy, dz, tgPhi,
y,
z, iRow, sec);
653 ++mRejectedResiduals;
656 trackData.
clIdx.setEntries(nClValidated);
658 bool stopPropagation = !mExtDetResid;
659 if (!stopPropagation) {
665 std::array<float, 2> trkltTRDYZ{};
671 stopPropagation =
true;
675 float tgPhi = trkWork.getSnp() / std::sqrt((1.f - trkWork.getSnp()) * (1.f + trkWork.getSnp()));
676 auto dy = trkltTRDYZ[0] - trkWork.getY();
677 auto dz = trkltTRDYZ[1] - trkWork.getZ();
678 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)) {
686 while (gidTable[
GTrackID::TOF].isIndexSet() && !stopPropagation) {
688 float clTOFxyz[3] = {clTOF.getX(), clTOF.getY(), clTOF.getZ()};
689 if (!clTOF.isInNominalSector()) {
693 if (trkWork.getAlpha() != clTOFAlpha && !trkWork.rotate(clTOFAlpha)) {
694 LOG(
debug) <<
"Failed to rotate into TOF cluster sector frame";
695 stopPropagation =
true;
698 if (!propagator->PropagateToXBxByBz(trkWork, clTOFxyz[0], mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
699 LOG(
debug) <<
"Failed final propagation to TOF radius";
703 float tgPhi = trkWork.getSnp() / std::sqrt((1.f - trkWork.getSnp()) * (1.f + trkWork.getSnp()));
704 auto dy = clTOFxyz[1] - trkWork.getY();
705 auto dz = clTOFxyz[2] - trkWork.getZ();
706 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)) {
707 mClRes.emplace_back(dy, dz, tgPhi, trkWork.getY(), trkWork.getZ(), 170, clTOF.getCount(), clTOF.getPadInSector());
714 while (!stopPropagation) {
715 auto& trkWorkITS = trkInner;
716 auto nCl = trkITS.getNumberOfClusters();
717 auto clEntry = trkITS.getFirstClusterEntry();
719 for (
int iCl = 0; iCl < nCl; iCl++) {
720 const auto& cls = mITSClustersArray[mITSTrackClusIdx[clEntry + iCl]];
721 int chip = cls.getSensorID();
722 float chipX, chipAlpha;
723 geom->getSensorXAlphaRefPlane(cls.getSensorID(), chipX, chipAlpha);
724 if (!trkWorkITS.rotate(chipAlpha) || !propagator->PropagateToXBxByBz(trkWorkITS, chipX, mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
725 LOGP(
debug,
"Failed final propagation to ITS X={} alpha={}", chipX, chipAlpha);
726 stopPropagation =
true;
729 float tgPhi = trkWorkITS.getSnp() / std::sqrt((1.f - trkWorkITS.getSnp()) * (1.f + trkWorkITS.getSnp()));
730 auto dy = cls.getY() - trkWorkITS.getY();
731 auto dz = cls.getZ() - trkWorkITS.getZ();
732 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)) {
733 mClRes.emplace_back(dy, dz, tgPhi, trkWorkITS.getY(), trkWorkITS.getZ(), 180 + geom->getLayer(cls.getSensorID()), -1, cls.getSensorID());
741 mGIDsSuccess.push_back(mGIDs[iSeed]);
742 mTrackDataCompact.emplace_back(trackData.
clIdx.getFirstEntry(), nClValidated, mGIDs[iSeed].getSource(), trackData.
nExtDetResid);
743 mTrackData.push_back(std::move(trackData));
744 if (mDumpTrackPoints) {
745 (*trackDataExtended).clIdx.setEntries(nClValidated);
746 (*trackDataExtended).nExtDetResid = trackData.
nExtDetResid;
747 mTrackDataExtended.push_back(std::move(*trackDataExtended));
752 trkDataTmp.
clIdx.setFirstEntry(mClResUnfiltered.size());
753 trkDataTmp.
clIdx.setEntries(clusterResiduals.size());
754 mTrackDataUnfiltered.push_back(std::move(trkDataTmp));
755 mClResUnfiltered.insert(mClResUnfiltered.end(), clusterResiduals.begin(), clusterResiduals.end());
760 std::array<float, 2>* trkltTRDYZ, std::array<float, 3>* trkltTRDCov,
TrackData* trkData)
763 int trkltIdx = trkTRD.getTrackletIndex(iLayer);
769 auto trkltDet = trdTrklt.getDetector();
773 LOG(
debug) <<
"Track could not be rotated in TRD tracklet coordinate system in layer " << iLayer;
778 LOG(
debug) <<
"Failed propagation to TRD layer " << iLayer;
782 const auto* pad = mGeoTRD->getPadPlane(trkltDet);
783 float tilt = tan(TMath::DegToRad() * pad->getTiltingAngle());
784 float tiltCorrUp = tilt * (trdSP.getZ() - trkWork.getZ());
785 float zPosCorrUp = trdSP.getZ() + mRecoParam.
getZCorrCoeffNRC() * trkWork.getTgl();
786 float padLength = pad->getRowSize(trdTrklt.getPadRow());
787 if (!((trkWork.getSigmaZ2() < (padLength * padLength / 12.f)) && (std::fabs(trdSP.getZ() - trkWork.getZ()) < padLength))) {
790 (*trkltTRDYZ)[0] = trdSP.getY() - tiltCorrUp;
791 (*trkltTRDYZ)[1] = zPosCorrUp;
793 mRecoParam.
recalcTrkltCov(tilt, trkWork.getSnp(), pad->getRowSize(trdTrklt.getPadRow()), *trkltTRDCov);
797 auto slope = trdSP.getDy();
798 if (std::abs(
slope) < param::MaxTRDSlope) {
808 LOGP(
debug,
"Starting track extrapolation for GID {}", mGIDs[iSeed].
asString());
809 const auto& gidTable = mGIDtables[iSeed];
811 std::unique_ptr<TrackDataExtended> trackDataExtended;
812 std::vector<TPCClusterResiduals> clusterResiduals;
813 trackData.
clIdx.setFirstEntry(mClRes.size());
816 if (mDumpTrackPoints) {
817 trackDataExtended = std::make_unique<TrackDataExtended>();
818 (*trackDataExtended).gid = mGIDs[iSeed];
819 (*trackDataExtended).clIdx.setFirstEntry(mClRes.size());
820 (*trackDataExtended).trkITS = trkITS;
821 (*trackDataExtended).trkTPC = trkTPC;
822 auto nCl = trkITS.getNumberOfClusters();
823 auto clEntry = trkITS.getFirstClusterEntry();
824 for (
int iCl = nCl - 1; iCl >= 0; iCl--) {
825 const auto& clsITS = mITSClustersArray[mITSTrackClusIdx[clEntry + iCl]];
826 (*trackDataExtended).clsITS.push_back(clsITS);
829 trackData.
gid = mGIDs[iSeed];
830 trackData.
par = mSeeds[iSeed];
832 auto trkWork = mSeeds[iSeed];
833 float clusterTimeBinOffset = mTrackTimes[iSeed] / mTPCTimeBinMUS;
835 unsigned short rowPrev = 0;
836 unsigned short nMeasurements = 0;
838 for (
int iCl = trkTPC.getNClusterReferences(); iCl--;) {
840 uint32_t clusterIndexInRow;
841 const auto& cl = trkTPC.getCluster(mTPCTracksClusIdx, iCl, *mTPCClusterIdxStruct, sector,
row);
842 if (clRowPrev ==
row) {
845 }
else if (clRowPrev < constants::MAXGLOBALPADROW && clRowPrev >
row) {
847 LOGP(
debug,
"TPC track with pT={} GeV and {} clusters has cluster {} on row {} while the previous cluster was on row {}",
848 mSeeds[iSeed].getPt(), trkTPC.getNClusterReferences(), iCl,
row, clRowPrev);
854 float x = 0,
y = 0,
z = 0;
855 mFastTransform->TransformIdeal(sector,
row, cl.getPad(), cl.getTime(),
x,
y,
z, clusterTimeBinOffset);
859 if (!propagator->PropagateToXBxByBz(trkWork,
x, mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
863 const auto dY =
y - trkWork.getY();
864 const auto dZ =
z - trkWork.getZ();
865 const auto ty = trkWork.getY();
866 const auto tz = trkWork.getZ();
867 const auto snp = trkWork.getSnp();
868 const auto sec = sector;
870 clusterResiduals.emplace_back(dY, dZ, ty, tz, snp, sec,
row - rowPrev);
878 LOGP(warn,
"Extrapolated ITS-TPC track and found more reesiduals than possible ({})", clusterResiduals.size());
882 trackData.
chi2TPC = trkTPC.getChi2();
883 trackData.
chi2ITS = trkITS.getChi2();
884 trackData.
nClsTPC = trkTPC.getNClusterReferences();
885 trackData.
nClsITS = trkITS.getNumberOfClusters();
886 trackData.
clIdx.setEntries(nMeasurements);
887 trackData.
dEdxTPC = trkTPC.getdEdx().dEdxTotTPC;
888 if (mDumpTrackPoints) {
889 (*trackDataExtended).trkOuter = trkWork;
895 int nClValidated = 0, iRow = 0;
896 unsigned int iCl = 0;
897 for (iCl = 0; iCl < clusterResiduals.size(); ++iCl) {
898 iRow += clusterResiduals[iCl].dRow;
899 if (iRow < param::NPadRows &&
params.flagRej[iCl]) {
903 const float tgPhi = clusterResiduals[iCl].snp / std::sqrt((1.f - clusterResiduals[iCl].snp) * (1.f + clusterResiduals[iCl].snp));
904 const auto dy = clusterResiduals[iCl].dy;
905 const auto dz = clusterResiduals[iCl].dz;
906 const auto y = clusterResiduals[iCl].y;
907 const auto z = clusterResiduals[iCl].z;
908 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)) {
909 mClRes.emplace_back(dy, dz, tgPhi,
y,
z, iRow, clusterResiduals[iCl].sec);
911 ++mRejectedResiduals;
914 trackData.
clIdx.setEntries(nClValidated);
916 bool stopPropagation = !mExtDetResid;
917 if (!stopPropagation) {
919 int iSeedFull = mParentID[iSeed] == -1 ? iSeed : mParentID[iSeed];
920 auto gidFull = mGIDs[iSeedFull];
921 const auto& gidTableFull = mGIDtables[iSeedFull];
924 trackData.
nTrkltsTRD = trkTRD.getNtracklets();
926 std::array<float, 2> trkltTRDYZ{};
932 stopPropagation =
true;
936 float tgPhi = trkWork.getSnp() / std::sqrt((1.f - trkWork.getSnp()) * (1.f + trkWork.getSnp()));
937 auto dy = trkltTRDYZ[0] - trkWork.getY();
938 auto dz = trkltTRDYZ[1] - trkWork.getZ();
939 const auto sec = clusterResiduals[iCl].sec;
940 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)) {
949 while (gidTableFull[
GTrackID::TOF].isIndexSet() && !stopPropagation) {
950 const auto& tofMatch = mRecoCont->
getTOFMatch(gidFull);
951 trackData.
deltaTOF = tofMatch.getSignal() - tofMatch.getFT0Best() - tofMatch.getLTIntegralOut().getTOF(trkTPC.getPID().getID());
952 trackData.
clAvailTOF = uint16_t(tofMatch.getFT0BestRes());
955 float clTOFxyz[3] = {clTOF.getX(), clTOF.getY(), clTOF.getZ()};
956 if (!clTOF.isInNominalSector()) {
959 if (trkWork.getAlpha() != clTOFAlpha && !trkWork.rotate(clTOFAlpha)) {
960 LOG(
debug) <<
"Failed to rotate into TOF cluster sector frame";
961 stopPropagation =
true;
964 if (!propagator->PropagateToXBxByBz(trkWork, clTOFxyz[0], mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
965 LOG(
debug) <<
"Failed final propagation to TOF radius";
969 float tgPhi = trkWork.getSnp() / std::sqrt((1.f - trkWork.getSnp()) * (1.f + trkWork.getSnp()));
970 auto dy = clTOFxyz[1] - trkWork.getY();
971 auto dz = clTOFxyz[2] - trkWork.getZ();
972 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)) {
973 mClRes.emplace_back(dy, dz, tgPhi, trkWork.getY(), trkWork.getZ(), 170, clTOF.getCount(), clTOF.getPadInSector());
980 while (!stopPropagation) {
982 auto nCl = trkITS.getNumberOfClusters();
983 auto clEntry = trkITS.getFirstClusterEntry();
985 for (
int iCl = 0; iCl < nCl; iCl++) {
986 const auto& cls = mITSClustersArray[mITSTrackClusIdx[clEntry + iCl]];
987 int chip = cls.getSensorID();
988 float chipX, chipAlpha;
989 geom->getSensorXAlphaRefPlane(cls.getSensorID(), chipX, chipAlpha);
990 if (!trkWorkITS.rotate(chipAlpha) || !propagator->PropagateToXBxByBz(trkWorkITS, chipX, mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
991 LOGP(
debug,
"Failed final propagation to ITS X={} alpha={}", chipX, chipAlpha);
992 stopPropagation =
true;
995 float tgPhi = trkWorkITS.getSnp() / std::sqrt((1.f - trkWorkITS.getSnp()) * (1.f + trkWorkITS.getSnp()));
996 auto dy = cls.getY() - trkWorkITS.getY();
997 auto dz = cls.getZ() - trkWorkITS.getZ();
998 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)) {
999 mClRes.emplace_back(dy, dz, tgPhi, trkWorkITS.getY(), trkWorkITS.getZ(), 180 + geom->getLayer(cls.getSensorID()), -1, cls.getSensorID());
1006 mTrackData.push_back(std::move(trackData));
1007 mGIDsSuccess.push_back(mGIDs[iSeed]);
1008 mTrackDataCompact.emplace_back(trackData.
clIdx.getFirstEntry(), nClValidated, mGIDs[iSeed].getSource(), trackData.
nExtDetResid);
1009 if (mDumpTrackPoints) {
1010 (*trackDataExtended).clIdx.setEntries(nClValidated);
1011 (*trackDataExtended).nExtDetResid = trackData.
nExtDetResid;
1012 mTrackDataExtended.push_back(std::move(*trackDataExtended));
1017 trkDataTmp.
clIdx.setFirstEntry(mClResUnfiltered.size());
1018 trkDataTmp.
clIdx.setEntries(clusterResiduals.size());
1019 mTrackDataUnfiltered.push_back(std::move(trkDataTmp));
1020 mClResUnfiltered.insert(mClResUnfiltered.end(), clusterResiduals.begin(), clusterResiduals.end());
1026 if (clsRes.size() < mParams->
minNCl) {
1028 LOG(
debug) <<
"Skipping track with too few clusters: " << clsRes.size();
1034 LOG(
debug) <<
"Skipping track too far from helix approximation";
1037 if (fabsf(mBz) > 0.01 && fabsf(
params.qpt) > mParams->
maxQ2Pt) {
1038 LOG(
debug) <<
"Skipping track with too high q/pT: " <<
params.qpt;
1049 std::array<float, param::NPadRows> residHelixY;
1050 std::array<float, param::NPadRows> residHelixZ;
1052 std::array<float, param::NPadRows> xLab;
1053 std::array<float, param::NPadRows> yLab;
1054 std::array<float, param::NPadRows> sPath;
1057 int secFirst = clsRes[0].sec;
1059 float snPhi = sin(phiSect);
1060 float csPhi = cos(phiSect);
1064 int nCl = clsRes.size();
1065 for (
unsigned int iP = 0; iP < nCl; ++iP) {
1066 iRow += clsRes[iP].dRow;
1067 float yTrk = clsRes[iP].y;
1069 xLab[iP] = param::RowX[iRow];
1070 if (clsRes[iP].sec != secFirst) {
1072 float cs = cos(phiSectCurrent - phiSect);
1073 float sn = sin(phiSectCurrent - phiSect);
1074 xLab[iP] = param::RowX[iRow] * cs - yTrk * sn;
1075 yLab[iP] = yTrk * cs + param::RowX[iRow] * sn;
1077 xLab[iP] = param::RowX[iRow];
1081 params.zTrk[iP] = clsRes[iP].z;
1082 params.xTrk[iP] = param::RowX[iRow];
1083 params.dy[iP] = clsRes[iP].dy;
1084 params.dz[iP] = clsRes[iP].dz;
1087 float dx = xLab[iP] - xLab[iP - 1];
1088 float dy = yLab[iP] - yLab[iP - 1];
1089 float ds2 = dx * dx + dy * dy;
1090 float ds = sqrt(ds2);
1094 if (
ds * curvature > 0.05) {
1095 ds *= (1.f + ds2 * curvature * curvature / 24.f);
1097 sPath[iP] = sPath[iP - 1] +
ds;
1100 if (fabsf(mBz) < 0.01) {
1115 float phiI = TMath::ATan2(yLab[0], xLab[0]);
1116 float phiF = TMath::ATan2(yLab[nCl - 1], xLab[nCl - 1]);
1123 float dPhi = phiF - phiI;
1124 float curvSign = -1.f;
1135 float xc = xcSec * csPhi - ycSec * snPhi;
1136 float yc = xcSec * snPhi + ycSec * csPhi;
1138 std::array<float, 2> pol1Z;
1145 float hMaxY = -1e9f;
1147 float hMaxZ = -1e9f;
1149 int secCurr = secFirst;
1151 for (
unsigned int iCl = 0; iCl < nCl; ++iCl) {
1152 iRow += clsRes[iCl].dRow;
1153 float resZ =
params.zTrk[iCl] - (pol1Z[1] + sPath[iCl] * pol1Z[0]);
1154 residHelixZ[iCl] = resZ;
1161 if (residHelixY[iCl] < hMinY) {
1162 hMinY = residHelixY[iCl];
1164 if (residHelixY[iCl] > hMaxY) {
1165 hMaxY = residHelixY[iCl];
1167 int sec = clsRes[iCl].sec;
1168 if (sec != secCurr) {
1171 snPhi = sin(phiSect);
1172 csPhi = cos(phiSect);
1173 xcSec = xc * csPhi + yc * snPhi;
1175 float cstalp = (param::RowX[iRow] - xcSec) /
r;
1176 if (fabsf(cstalp) > 1.f - sFloatEps) {
1178 cstalp = std::copysign(1.f - sFloatEps, cstalp);
1180 params.tglArr[iCl] = cstalp / sqrt((1 - cstalp) * (1 + cstalp));
1183 if (
params.qpt * mBz > 0) {
1184 params.tglArr[iCl] *= -1.f;
1194 if (clsRes.size() < mParams->
nMALong) {
1195 LOG(
debug) <<
"Skipping track with too few clusters for long moving average: " << clsRes.size();
1199 if (
static_cast<float>(
params.flagRej.count()) / clsRes.size() > mParams->
maxRejFrac) {
1200 LOGP(
debug,
"Skipping track with too many clusters rejected: {} out of {}",
params.flagRej.count(), clsRes.size());
1204 LOG(
debug) <<
"Skipping track with too large RMS: " << rmsLong;
1212 float rmsLong = 0.f;
1214 int nCl = clsRes.size();
1216 int iClLast = nCl - 1;
1217 int secStart = clsRes[0].sec;
1220 std::array<float, param::NPadRows> yDiffLL{};
1221 std::array<float, param::NPadRows> zDiffLL{};
1222 std::array<float, param::NPadRows> absDevY{};
1223 std::array<float, param::NPadRows> absDevZ{};
1225 for (
unsigned int iCl = 0; iCl < nCl; ++iCl) {
1226 if (iCl < iClLast && clsRes[iCl].sec == secStart) {
1231 int nClSec = iCl - iClFirst;
1232 if (iCl == iClLast) {
1238 secStart = clsRes[iCl].sec;
1243 for (
int iCl = nCl; iCl--;) {
1244 if (fabsf(yDiffLL[iCl]) > param::sEps) {
1245 absDevY[nAccY++] = fabsf(yDiffLL[iCl]);
1247 if (fabsf(zDiffLL[iCl]) > param::sEps) {
1248 absDevZ[nAccZ++] = fabsf(zDiffLL[iCl]);
1251 if (nAccY < mParams->minNumberOfAcceptedResiduals || nAccZ < mParams->minNumberOfAcceptedResiduals) {
1258 int nKeepY =
static_cast<int>(.9 * nAccY);
1259 int nKeepZ =
static_cast<int>(.9 * nAccZ);
1260 std::nth_element(absDevY.begin(), absDevY.begin() + nKeepY, absDevY.begin() + nAccY);
1261 std::nth_element(absDevZ.begin(), absDevZ.begin() + nKeepZ, absDevZ.begin() + nAccZ);
1262 float rmsYkeep = 0.f;
1263 float rmsZkeep = 0.f;
1264 for (
int i = nKeepY;
i--;) {
1265 rmsYkeep += absDevY[
i] * absDevY[
i];
1267 for (
int i = nKeepZ;
i--;) {
1268 rmsZkeep += absDevZ[
i] * absDevZ[
i];
1270 rmsYkeep = std::sqrt(rmsYkeep / nKeepY);
1271 rmsZkeep = std::sqrt(rmsZkeep / nKeepZ);
1272 if (rmsYkeep < param::sEps || rmsZkeep < param::sEps) {
1273 LOG(warning) <<
"Too small RMS: " << rmsYkeep <<
"(y), " << rmsZkeep <<
"(z).";
1277 float rmsYkeepI = 1.f / rmsYkeep;
1278 float rmsZkeepI = 1.f / rmsZkeep;
1280 std::array<float, param::NPadRows> yAcc;
1281 std::array<float, param::NPadRows> yDiffLong;
1282 for (
int iCl = 0; iCl < nCl; ++iCl) {
1283 yDiffLL[iCl] *= rmsYkeepI;
1284 zDiffLL[iCl] *= rmsZkeepI;
1285 if (yDiffLL[iCl] * yDiffLL[iCl] + zDiffLL[iCl] * zDiffLL[iCl] > mParams->
maxStdDevMA) {
1288 yAcc[nAcc++] =
params.dy[iCl];
1291 if (nAcc > mParams->
nMALong) {
1293 float average = 0.f;
1295 for (
int i = 0;
i < nAcc; ++
i) {
1296 average += yDiffLong[
i];
1297 rms += yDiffLong[
i] * yDiffLong[
i];
1300 rmsLong = rms / nAcc - average * average;
1301 rmsLong = (rmsLong > 0) ? std::sqrt(rmsLong) : 0.f;
1306void TrackInterpolation::diffToLocLine(
const int np,
int idxOffset,
const std::array<float, param::NPadRows>&
x,
const std::array<float, param::NPadRows>&
y, std::array<float, param::NPadRows>& diffY)
const
1313 std::vector<float> sumX1vec(np + 1);
1314 std::vector<float> sumX2vec(np + 1);
1315 std::vector<float> sumY1vec(np + 1);
1316 std::vector<float> sumXYvec(np + 1);
1317 auto sumX1 = &(sumX1vec[1]);
1318 auto sumX2 = &(sumX2vec[1]);
1319 auto sumY1 = &(sumY1vec[1]);
1320 auto sumXY = &(sumXYvec[1]);
1323 for (
int iCl = 0; iCl < np; ++iCl) {
1324 int idx = iCl + idxOffset;
1325 sumX1[iCl] = sumX1[iCl - 1] +
x[idx];
1326 sumX2[iCl] = sumX2[iCl - 1] +
x[idx] *
x[idx];
1327 sumY1[iCl] = sumY1[iCl - 1] +
y[idx];
1328 sumXY[iCl] = sumXY[iCl - 1] +
x[idx] *
y[idx];
1331 for (
int iCl = 0; iCl < np; ++iCl) {
1332 int iClLeft = iCl - mParams->
nMAShort;
1333 int iClRight = iCl + mParams->
nMAShort;
1337 if (iClRight >= np) {
1340 int nPoints = iClRight - iClLeft;
1341 if (nPoints < mParams->nMAShort) {
1344 float nPointsInv = 1.f / nPoints;
1345 int iClLeftP = iClLeft - 1;
1346 int iClCurrP = iCl - 1;
1348 float sX1 = sumX1[iClRight] - sumX1[iClLeftP] - (sumX1[iCl] - sumX1[iClCurrP]);
1349 float sX2 = sumX2[iClRight] - sumX2[iClLeftP] - (sumX2[iCl] - sumX2[iClCurrP]);
1350 float sY1 = sumY1[iClRight] - sumY1[iClLeftP] - (sumY1[iCl] - sumY1[iClCurrP]);
1351 float sXY = sumXY[iClRight] - sumXY[iClLeftP] - (sumXY[iCl] - sumXY[iClCurrP]);
1352 float det = sX2 - nPointsInv * sX1 * sX1;
1353 if (fabsf(det) < 1e-12f) {
1356 float slope = (sXY - nPointsInv * sX1 * sY1) / det;
1357 float offset = nPointsInv * sY1 - nPointsInv *
slope * sX1;
1358 diffY[iCl + idxOffset] =
y[iCl + idxOffset] -
slope *
x[iCl + idxOffset] -
offset;
1365 std::vector<float> sumVec(np + 1);
1366 auto sum = &(sumVec[1]);
1367 for (
int i = 0;
i < np; ++
i) {
1370 for (
int i = 0;
i < np; ++
i) {
1380 int nPoints = iRight - iLeft;
1381 if (nPoints < mParams->nMALong) {
1385 float movingAverage = (
sum[iRight] -
sum[iLeft - 1] - (
sum[
i] -
sum[
i - 1])) / nPoints;
1386 diffMA[
i] =
y[
i] - movingAverage;
1393 mTrackDataCompact.clear();
1394 mTrackDataExtended.clear();
1396 mTrackDataUnfiltered.clear();
1397 mClResUnfiltered.clear();
1398 mGIDsSuccess.clear();
1399 for (
auto&
vec : mTrackIndices) {
1404 mTrackTimes.clear();
1412 if (
v.refVDrift != mTPCVDriftRef) {
1413 mTPCVDriftRef =
v.refVDrift;
1414 mTPCDriftTimeOffsetRef =
v.refTimeOffset;
1415 LOGP(info,
"Imposing reference VDrift={}/TDrift={} for TPC residuals extraction", mTPCVDriftRef, mTPCDriftTimeOffsetRef);
std::string asString(TDataMember const &dm, char *pointer)
Definition of the GeometryTGeo class.
Definition of the parameter class for the detector electronics.
Definition of the TrackInterpolation class.
Definition of the TrackResiduals class.
calibration data from laser track calibration
Referenc on track indices contributing to the vertex, with possibility chose tracks from specific sou...
GPUd() value_type estimateLTFast(o2 static GPUd() float estimateLTIncrement(const o2 PropagatorImpl * Instance(bool uninitialized=false)
static BasicCCDBManager & instance()
T * getSpecific(std::string const &path, long timestamp=-1, MD metaData=MD(), std::map< std::string, std::string > *headers=nullptr)
retrieve an object of type T from CCDB as stored under path, timestamp and metaData
static const ParameterElectronics & Instance()
Static class with identifiers, bitmasks and names for ALICE detectors.
float getSensorRefAlpha(int isn) const
static GeometryTGeo * Instance()
float getSensorRefX(int isn) const
static void rotateToSector(Float_t *xyz, Int_t isector)
static void getPos(Int_t *det, Float_t *pos)
static constexpr Int_t NPADSXSECTOR
static void getVolumeIndices(Int_t index, Int_t *detId)
static void alignedToNominalSector(Float_t *xyz, Int_t isector)
void prepareInputTrackSample(const o2::globaltracking::RecoContainer &inp)
Prepare input track sample (not relying on CreateTracksVariadic functionality)
bool isInputTrackAccepted(const o2::dataformats::GlobalTrackID &gid, const o2::globaltracking::RecoContainer::GlobalIDSet &gidTable, const o2::dataformats::PrimaryVertex &pv) const
Check if input track passes configured cuts.
void diffToMA(const int np, const std::array< float, param::NPadRows > &y, std::array< float, param::NPadRows > &diffMA) const
For a given set of points, calculate their deviation from the moving average (build from the neighbou...
void diffToLocLine(const int np, int idxOffset, const std::array< float, param::NPadRows > &x, const std::array< float, param::NPadRows > &y, std::array< float, param::NPadRows > &diffY) const
For a given set of points, calculate the differences from each point to the fitted lines from all oth...
void extrapolateTrack(int iSeed)
@ ExtIn
extrapolation inwards of TRD/TOF track
@ Int
interpolation (mean positions of both extrapolations)
@ ExtOut
extrapolation outwards of ITS track
o2::dataformats::GlobalTrackID::Source findValidSource(const o2::dataformats::GlobalTrackID::mask_t mask, const o2::dataformats::GlobalTrackID::Source src) const
For given vertex track source which is not in mSourcesConfigured find the seeding source which is ena...
float checkResiduals(const TrackData &trk, TrackParams ¶ms, const std::vector< TPCClusterResiduals > &clsRes) const
void interpolateTrack(int iSeed)
bool compareToHelix(const TrackData &trk, TrackParams ¶ms, const std::vector< TPCClusterResiduals > &clsRes) const
void process()
Main processing function.
void setTPCVDrift(const o2::tpc::VDriftCorrFact &v)
int processTRDLayer(const o2::trd::TrackTRD &trkTRD, int iLayer, o2::track::TrackParCov &trkWork, std::array< float, 2 > *trkltTRDYZ=nullptr, std::array< float, 3 > *trkltTRDCov=nullptr, TrackData *trkData=nullptr)
bool isTrackSelected(const o2::track::TrackParCov &trk) const
Given the defined downsampling factor tsalisThreshold check if track is selected.
void reset()
Reset cache and output vectors.
bool outlierFiltering(const TrackData &trk, TrackParams ¶ms, const std::vector< TPCClusterResiduals > &clsRes) const
void init(o2::dataformats::GlobalTrackID::mask_t src, o2::dataformats::GlobalTrackID::mask_t srcMap)
Initialize everything, set the requested track sources.
bool validateTrack(const TrackData &trk, TrackParams ¶ms, const std::vector< TPCClusterResiduals > &clsRes) const
static bool fitPoly1(int nCl, std::array< float, param::NPadRows > &x, std::array< float, param::NPadRows > &y, std::array< float, 2 > &res)
static void fitCircle(int nCl, std::array< float, param::NPadRows > &x, std::array< float, param::NPadRows > &y, float &xc, float &yc, float &r, std::array< float, param::NPadRows > &residHelixY)
static Geometry * instance()
void recalcTrkltCov(const float tilt, const float snp, const float rowSize, std::array< float, 3 > &cov) const
Recalculate tracklet covariance based on phi angle of related track.
float getZCorrCoeffNRC() const
Get tracklet z correction coefficient for track-eta based corraction.
void setBfield(float bz)
Load parameterization for given magnetic field.
GLuint GLuint GLfloat weight
GLenum const GLfloat * params
GLdouble GLdouble GLdouble z
constexpr float SectorSpanRad
constexpr float LightSpeedCm2S
constexpr double MassPionCharged
void convertCompactClusters(gsl::span< const itsmft::CompClusterExt > clusters, gsl::span< const unsigned char >::iterator &pattIt, std::vector< o2::BaseCluster< float > > &output, const itsmft::TopologyDictionary *dict)
convert compact clusters to 3D spacepoints
int angle2Sector(float phi)
float sector2Angle(int sect)
constexpr int MAXGLOBALPADROW
Global TPC definitions and constants.
Enum< T >::Iterator begin(Enum< T >)
DataT sum(const Vector< DataT, N > &a)
constexpr int NLAYER
the number of layers
constexpr int NSTACK
the number of stacks per sector
GlobalIDSet getSingleDetectorRefs(GTrackID gidx) const
const o2::tpc::TrackTPC & getTPCTrack(GTrackID id) const
gsl::span< const o2::trd::CalibratedTracklet > getTRDCalibratedTracklets() const
auto getITSTracksClusterRefs() const
auto getPrimaryVertices() const
auto getPrimaryVertexMatchedTracks() const
const o2::tpc::ClusterNativeAccess & getTPCClusters() const
auto getTPCTracksClusterRefs() const
auto getPrimaryVertexMatchedTrackRefs() const
auto getITSClustersPatterns() const
const o2::track::TrackParCov & getTrackParam(GTrackID gidx) const
auto getTOFClusters() const
const o2::its::TrackITS & getITSTrack(GTrackID gid) const
auto getITSTPCTRDTrack(GTrackID id) const
std::array< GTrackID, GTrackID::NSources > GlobalIDSet
auto getITSClusters() const
gsl::span< const o2::trd::Tracklet64 > getTRDTracklets() const
const o2::dataformats::MatchInfoTOF & getTOFMatch(GTrackID id) const
static bool downsampleTsallisCharged(float pt, float factorPt, float sqrts, float &weight, float rnd, float mass=0.13957)
float maxRejFrac
if the fraction of rejected clusters of a track is higher, the full track is invalidated
float maxDCA
DCA cut value in cm.
float maxDevHelixZ
max deviation in Z for clusters wrt helix fit
int nMALong
number of points to be used for moving average (long range)
float maxTPCChi2
cut on TPC reduced chi2
float minPtNoOuterPoint
minimum pt for ITS-TPC tracks to be considered for extrapolation
int minTRDNTrklts
min number of TRD space points
int nMAShort
number of points to be used for estimation of distance from local line (short range)
float maxDevHelixY
max deviation in Y for clusters wrt helix fit
float maxStdDevMA
max cluster std. deviation (Y^2 + Z^2) wrt moving average to accept
bool skipOutlierFiltering
if set, the outlier filtering will not be applied at all
bool ignoreNonPVContrib
flag if tracks which did not contribute to the PV should be ignored or not
int minITSNClsNoOuterPoint
min number of ITS clusters if no hit in TRD or TOF exists
int minTPCNCls
min number of TPC clusters
float tsalisThreshold
in case the sampling functions returns a value smaller than this the track is discarded (1....
float maxStep
maximum step for propagation
int minTOFTRDPVContributors
min contributors from TRD or TOF (fast detectors) to consider tracks of this PV
bool enableTrackDownsampling
flag if track sampling shall be enabled or not
float maxQ2Pt
max fitted q/pt for a track to be used for calibration
float sigYZ2TOF
for now assume cluster error for TOF equal for all clusters in both Y and Z
int minNumberOfAcceptedResiduals
min number of accepted residuals for
float maxRMSLong
maximum variance of the cluster residuals wrt moving avarage for a track to be considered
int minITSNCls
min number of ITS clusters
float maxSnp
max snp when propagating tracks
float maxITSChi2
cut on ITS reduced chi2
bool writeUnfiltered
if set, all residuals and track parameters will be aggregated and dumped additionally without outlier...
int minNCl
min number of clusters in a track to be used for calibration
int minTPCNClsNoOuterPoint
min number of TPC clusters if no hit in TRD or TOF exists
Structure filled for each track with track quality information and a vector with TPCClusterResiduals.
float chi2TRD
chi2 of TRD track
float dEdxTPC
TPC dEdx information.
unsigned short nTrkltsTRD
number of attached TRD tracklets
unsigned short clAvailTOF
whether or not track seed has a matched TOF cluster, if so, gives the resolution of the T0 in ps
short TRDTrkltSlope[6]
TRD tracklet slope 0x7fff / param::MaxTRDSlope.
unsigned short nClsITS
number of attached ITS clusters
o2::dataformats::RangeReference clIdx
index of first cluster residual and total number of TPC cluster residuals of this track
float chi2TPC
chi2 of TPC track
unsigned short nClsTPC
number of attached TPC clusters
o2::dataformats::GlobalTrackID gid
global track ID for seeding track
float deltaTOF
TOFsignal - T0 - texp(PID), if T0 is available.
uint8_t nExtDetResid
number of external detectors (to TPC) residuals stored, on top of clIdx.getEntries
o2::track::TrackPar par
ITS track at inner TPC radius.
float chi2ITS
chi2 of ITS track
Structure for on-the-fly re-calculated track parameters at the validation stage.
unsigned char sec
TPC sector (0..35)
unsigned char row
TPC pad row.
static void init(long timestamp=-1)
static void checkInitDone()
short channel
extra channel info (ITS chip ID, TRD chamber, TOF main pad within the sector)
std::vector< o2::ctf::BufferType > vec
LOG(info)<< "Compressed in "<< sw.CpuTime()<< " s"
std::uniform_int_distribution< unsigned long long > distr