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)
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);
802 LOGP(
debug,
"Starting track extrapolation for GID {}", mGIDs[iSeed].
asString());
803 const auto& gidTable = mGIDtables[iSeed];
805 std::unique_ptr<TrackDataExtended> trackDataExtended;
806 std::vector<TPCClusterResiduals> clusterResiduals;
807 trackData.
clIdx.setFirstEntry(mClRes.size());
810 if (mDumpTrackPoints) {
811 trackDataExtended = std::make_unique<TrackDataExtended>();
812 (*trackDataExtended).gid = mGIDs[iSeed];
813 (*trackDataExtended).clIdx.setFirstEntry(mClRes.size());
814 (*trackDataExtended).trkITS = trkITS;
815 (*trackDataExtended).trkTPC = trkTPC;
816 auto nCl = trkITS.getNumberOfClusters();
817 auto clEntry = trkITS.getFirstClusterEntry();
818 for (
int iCl = nCl - 1; iCl >= 0; iCl--) {
819 const auto& clsITS = mITSClustersArray[mITSTrackClusIdx[clEntry + iCl]];
820 (*trackDataExtended).clsITS.push_back(clsITS);
823 trackData.
gid = mGIDs[iSeed];
824 trackData.
par = mSeeds[iSeed];
826 auto trkWork = mSeeds[iSeed];
827 float clusterTimeBinOffset = mTrackTimes[iSeed] / mTPCTimeBinMUS;
829 unsigned short rowPrev = 0;
830 unsigned short nMeasurements = 0;
832 for (
int iCl = trkTPC.getNClusterReferences(); iCl--;) {
834 uint32_t clusterIndexInRow;
835 const auto& cl = trkTPC.getCluster(mTPCTracksClusIdx, iCl, *mTPCClusterIdxStruct, sector,
row);
836 if (clRowPrev ==
row) {
839 }
else if (clRowPrev < constants::MAXGLOBALPADROW && clRowPrev >
row) {
841 LOGP(
debug,
"TPC track with pT={} GeV and {} clusters has cluster {} on row {} while the previous cluster was on row {}",
842 mSeeds[iSeed].getPt(), trkTPC.getNClusterReferences(), iCl,
row, clRowPrev);
848 float x = 0,
y = 0,
z = 0;
849 mFastTransform->TransformIdeal(sector,
row, cl.getPad(), cl.getTime(),
x,
y,
z, clusterTimeBinOffset);
853 if (!propagator->PropagateToXBxByBz(trkWork,
x, mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
857 const auto dY =
y - trkWork.getY();
858 const auto dZ =
z - trkWork.getZ();
859 const auto ty = trkWork.getY();
860 const auto tz = trkWork.getZ();
861 const auto snp = trkWork.getSnp();
862 const auto sec = sector;
864 clusterResiduals.emplace_back(dY, dZ, ty, tz, snp, sec,
row - rowPrev);
872 LOGP(warn,
"Extrapolated ITS-TPC track and found more reesiduals than possible ({})", clusterResiduals.size());
876 trackData.
chi2TPC = trkTPC.getChi2();
877 trackData.
chi2ITS = trkITS.getChi2();
878 trackData.
nClsTPC = trkTPC.getNClusterReferences();
879 trackData.
nClsITS = trkITS.getNumberOfClusters();
880 trackData.
clIdx.setEntries(nMeasurements);
881 trackData.
dEdxTPC = trkTPC.getdEdx().dEdxTotTPC;
882 if (mDumpTrackPoints) {
883 (*trackDataExtended).trkOuter = trkWork;
889 int nClValidated = 0, iRow = 0;
890 unsigned int iCl = 0;
891 for (iCl = 0; iCl < clusterResiduals.size(); ++iCl) {
892 iRow += clusterResiduals[iCl].dRow;
893 if (iRow < param::NPadRows &&
params.flagRej[iCl]) {
897 const float tgPhi = clusterResiduals[iCl].snp / std::sqrt((1.f - clusterResiduals[iCl].snp) * (1.f + clusterResiduals[iCl].snp));
898 const auto dy = clusterResiduals[iCl].dy;
899 const auto dz = clusterResiduals[iCl].dz;
900 const auto y = clusterResiduals[iCl].y;
901 const auto z = clusterResiduals[iCl].z;
902 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)) {
903 mClRes.emplace_back(dy, dz, tgPhi,
y,
z, iRow, clusterResiduals[iCl].sec);
905 ++mRejectedResiduals;
908 trackData.
clIdx.setEntries(nClValidated);
910 bool stopPropagation = !mExtDetResid;
911 if (!stopPropagation) {
913 int iSeedFull = mParentID[iSeed] == -1 ? iSeed : mParentID[iSeed];
914 auto gidFull = mGIDs[iSeedFull];
915 const auto& gidTableFull = mGIDtables[iSeedFull];
919 std::array<float, 2> trkltTRDYZ{};
925 stopPropagation =
true;
929 float tgPhi = trkWork.getSnp() / std::sqrt((1.f - trkWork.getSnp()) * (1.f + trkWork.getSnp()));
930 auto dy = trkltTRDYZ[0] - trkWork.getY();
931 auto dz = trkltTRDYZ[1] - trkWork.getZ();
932 const auto sec = clusterResiduals[iCl].sec;
933 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)) {
943 while (gidTableFull[
GTrackID::TOF].isIndexSet() && !stopPropagation) {
944 const auto& tofMatch = mRecoCont->
getTOFMatch(gidFull);
945 trackData.
deltaTOF = tofMatch.getSignal() - tofMatch.getFT0Best() - tofMatch.getLTIntegralOut().getTOF(trkTPC.getPID().getID());
946 trackData.
clAvailTOF = uint16_t(tofMatch.getFT0BestRes());
949 float clTOFxyz[3] = {clTOF.getX(), clTOF.getY(), clTOF.getZ()};
950 if (!clTOF.isInNominalSector()) {
953 if (trkWork.getAlpha() != clTOFAlpha && !trkWork.rotate(clTOFAlpha)) {
954 LOG(
debug) <<
"Failed to rotate into TOF cluster sector frame";
955 stopPropagation =
true;
958 if (!propagator->PropagateToXBxByBz(trkWork, clTOFxyz[0], mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
959 LOG(
debug) <<
"Failed final propagation to TOF radius";
963 float tgPhi = trkWork.getSnp() / std::sqrt((1.f - trkWork.getSnp()) * (1.f + trkWork.getSnp()));
964 auto dy = clTOFxyz[1] - trkWork.getY();
965 auto dz = clTOFxyz[2] - trkWork.getZ();
966 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)) {
967 mClRes.emplace_back(dy, dz, tgPhi, trkWork.getY(), trkWork.getZ(), 170, clTOF.getCount(), clTOF.getPadInSector());
974 while (!stopPropagation) {
976 auto nCl = trkITS.getNumberOfClusters();
977 auto clEntry = trkITS.getFirstClusterEntry();
979 for (
int iCl = 0; iCl < nCl; iCl++) {
980 const auto& cls = mITSClustersArray[mITSTrackClusIdx[clEntry + iCl]];
981 int chip = cls.getSensorID();
982 float chipX, chipAlpha;
983 geom->getSensorXAlphaRefPlane(cls.getSensorID(), chipX, chipAlpha);
984 if (!trkWorkITS.rotate(chipAlpha) || !propagator->PropagateToXBxByBz(trkWorkITS, chipX, mParams->
maxSnp, mParams->
maxStep, mMatCorr)) {
985 LOGP(
debug,
"Failed final propagation to ITS X={} alpha={}", chipX, chipAlpha);
986 stopPropagation =
true;
989 float tgPhi = trkWorkITS.getSnp() / std::sqrt((1.f - trkWorkITS.getSnp()) * (1.f + trkWorkITS.getSnp()));
990 auto dy = cls.getY() - trkWorkITS.getY();
991 auto dz = cls.getZ() - trkWorkITS.getZ();
992 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)) {
993 mClRes.emplace_back(dy, dz, tgPhi, trkWorkITS.getY(), trkWorkITS.getZ(), 180 + geom->getLayer(cls.getSensorID()), -1, cls.getSensorID());
1000 mTrackData.push_back(std::move(trackData));
1001 mGIDsSuccess.push_back(mGIDs[iSeed]);
1002 mTrackDataCompact.emplace_back(trackData.
clIdx.getFirstEntry(), nClValidated, mGIDs[iSeed].getSource(), trackData.
nExtDetResid);
1003 if (mDumpTrackPoints) {
1004 (*trackDataExtended).clIdx.setEntries(nClValidated);
1005 (*trackDataExtended).nExtDetResid = trackData.
nExtDetResid;
1006 mTrackDataExtended.push_back(std::move(*trackDataExtended));
1011 trkDataTmp.
clIdx.setFirstEntry(mClResUnfiltered.size());
1012 trkDataTmp.
clIdx.setEntries(clusterResiduals.size());
1013 mTrackDataUnfiltered.push_back(std::move(trkDataTmp));
1014 mClResUnfiltered.insert(mClResUnfiltered.end(), clusterResiduals.begin(), clusterResiduals.end());
1020 if (clsRes.size() < mParams->
minNCl) {
1022 LOG(
debug) <<
"Skipping track with too few clusters: " << clsRes.size();
1028 LOG(
debug) <<
"Skipping track too far from helix approximation";
1031 if (fabsf(mBz) > 0.01 && fabsf(
params.qpt) > mParams->
maxQ2Pt) {
1032 LOG(
debug) <<
"Skipping track with too high q/pT: " <<
params.qpt;
1043 std::array<float, param::NPadRows> residHelixY;
1044 std::array<float, param::NPadRows> residHelixZ;
1046 std::array<float, param::NPadRows> xLab;
1047 std::array<float, param::NPadRows> yLab;
1048 std::array<float, param::NPadRows> sPath;
1051 int secFirst = clsRes[0].sec;
1053 float snPhi = sin(phiSect);
1054 float csPhi = cos(phiSect);
1058 int nCl = clsRes.size();
1059 for (
unsigned int iP = 0; iP < nCl; ++iP) {
1060 iRow += clsRes[iP].dRow;
1061 float yTrk = clsRes[iP].y;
1063 xLab[iP] = param::RowX[iRow];
1064 if (clsRes[iP].sec != secFirst) {
1066 float cs = cos(phiSectCurrent - phiSect);
1067 float sn = sin(phiSectCurrent - phiSect);
1068 xLab[iP] = param::RowX[iRow] * cs - yTrk * sn;
1069 yLab[iP] = yTrk * cs + param::RowX[iRow] * sn;
1071 xLab[iP] = param::RowX[iRow];
1075 params.zTrk[iP] = clsRes[iP].z;
1076 params.xTrk[iP] = param::RowX[iRow];
1077 params.dy[iP] = clsRes[iP].dy;
1078 params.dz[iP] = clsRes[iP].dz;
1081 float dx = xLab[iP] - xLab[iP - 1];
1082 float dy = yLab[iP] - yLab[iP - 1];
1083 float ds2 = dx * dx + dy * dy;
1084 float ds = sqrt(ds2);
1088 if (
ds * curvature > 0.05) {
1089 ds *= (1.f + ds2 * curvature * curvature / 24.f);
1091 sPath[iP] = sPath[iP - 1] +
ds;
1094 if (fabsf(mBz) < 0.01) {
1109 float phiI = TMath::ATan2(yLab[0], xLab[0]);
1110 float phiF = TMath::ATan2(yLab[nCl - 1], xLab[nCl - 1]);
1117 float dPhi = phiF - phiI;
1118 float curvSign = -1.f;
1129 float xc = xcSec * csPhi - ycSec * snPhi;
1130 float yc = xcSec * snPhi + ycSec * csPhi;
1132 std::array<float, 2> pol1Z;
1139 float hMaxY = -1e9f;
1141 float hMaxZ = -1e9f;
1143 int secCurr = secFirst;
1145 for (
unsigned int iCl = 0; iCl < nCl; ++iCl) {
1146 iRow += clsRes[iCl].dRow;
1147 float resZ =
params.zTrk[iCl] - (pol1Z[1] + sPath[iCl] * pol1Z[0]);
1148 residHelixZ[iCl] = resZ;
1155 if (residHelixY[iCl] < hMinY) {
1156 hMinY = residHelixY[iCl];
1158 if (residHelixY[iCl] > hMaxY) {
1159 hMaxY = residHelixY[iCl];
1161 int sec = clsRes[iCl].sec;
1162 if (sec != secCurr) {
1165 snPhi = sin(phiSect);
1166 csPhi = cos(phiSect);
1167 xcSec = xc * csPhi + yc * snPhi;
1169 float cstalp = (param::RowX[iRow] - xcSec) /
r;
1170 if (fabsf(cstalp) > 1.f - sFloatEps) {
1172 cstalp = std::copysign(1.f - sFloatEps, cstalp);
1174 params.tglArr[iCl] = cstalp / sqrt((1 - cstalp) * (1 + cstalp));
1177 if (
params.qpt * mBz > 0) {
1178 params.tglArr[iCl] *= -1.f;
1188 if (clsRes.size() < mParams->
nMALong) {
1189 LOG(
debug) <<
"Skipping track with too few clusters for long moving average: " << clsRes.size();
1193 if (
static_cast<float>(
params.flagRej.count()) / clsRes.size() > mParams->
maxRejFrac) {
1194 LOGP(
debug,
"Skipping track with too many clusters rejected: {} out of {}",
params.flagRej.count(), clsRes.size());
1198 LOG(
debug) <<
"Skipping track with too large RMS: " << rmsLong;
1206 float rmsLong = 0.f;
1208 int nCl = clsRes.size();
1210 int iClLast = nCl - 1;
1211 int secStart = clsRes[0].sec;
1214 std::array<float, param::NPadRows> yDiffLL{};
1215 std::array<float, param::NPadRows> zDiffLL{};
1216 std::array<float, param::NPadRows> absDevY{};
1217 std::array<float, param::NPadRows> absDevZ{};
1219 for (
unsigned int iCl = 0; iCl < nCl; ++iCl) {
1220 if (iCl < iClLast && clsRes[iCl].sec == secStart) {
1225 int nClSec = iCl - iClFirst;
1226 if (iCl == iClLast) {
1232 secStart = clsRes[iCl].sec;
1237 for (
int iCl = nCl; iCl--;) {
1238 if (fabsf(yDiffLL[iCl]) > param::sEps) {
1239 absDevY[nAccY++] = fabsf(yDiffLL[iCl]);
1241 if (fabsf(zDiffLL[iCl]) > param::sEps) {
1242 absDevZ[nAccZ++] = fabsf(zDiffLL[iCl]);
1245 if (nAccY < mParams->minNumberOfAcceptedResiduals || nAccZ < mParams->minNumberOfAcceptedResiduals) {
1252 int nKeepY =
static_cast<int>(.9 * nAccY);
1253 int nKeepZ =
static_cast<int>(.9 * nAccZ);
1254 std::nth_element(absDevY.begin(), absDevY.begin() + nKeepY, absDevY.begin() + nAccY);
1255 std::nth_element(absDevZ.begin(), absDevZ.begin() + nKeepZ, absDevZ.begin() + nAccZ);
1256 float rmsYkeep = 0.f;
1257 float rmsZkeep = 0.f;
1258 for (
int i = nKeepY;
i--;) {
1259 rmsYkeep += absDevY[
i] * absDevY[
i];
1261 for (
int i = nKeepZ;
i--;) {
1262 rmsZkeep += absDevZ[
i] * absDevZ[
i];
1264 rmsYkeep = std::sqrt(rmsYkeep / nKeepY);
1265 rmsZkeep = std::sqrt(rmsZkeep / nKeepZ);
1266 if (rmsYkeep < param::sEps || rmsZkeep < param::sEps) {
1267 LOG(warning) <<
"Too small RMS: " << rmsYkeep <<
"(y), " << rmsZkeep <<
"(z).";
1271 float rmsYkeepI = 1.f / rmsYkeep;
1272 float rmsZkeepI = 1.f / rmsZkeep;
1274 std::array<float, param::NPadRows> yAcc;
1275 std::array<float, param::NPadRows> yDiffLong;
1276 for (
int iCl = 0; iCl < nCl; ++iCl) {
1277 yDiffLL[iCl] *= rmsYkeepI;
1278 zDiffLL[iCl] *= rmsZkeepI;
1279 if (yDiffLL[iCl] * yDiffLL[iCl] + zDiffLL[iCl] * zDiffLL[iCl] > mParams->
maxStdDevMA) {
1282 yAcc[nAcc++] =
params.dy[iCl];
1285 if (nAcc > mParams->
nMALong) {
1287 float average = 0.f;
1289 for (
int i = 0;
i < nAcc; ++
i) {
1290 average += yDiffLong[
i];
1291 rms += yDiffLong[
i] * yDiffLong[
i];
1294 rmsLong = rms / nAcc - average * average;
1295 rmsLong = (rmsLong > 0) ? std::sqrt(rmsLong) : 0.f;
1300void 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
1307 std::vector<float> sumX1vec(np + 1);
1308 std::vector<float> sumX2vec(np + 1);
1309 std::vector<float> sumY1vec(np + 1);
1310 std::vector<float> sumXYvec(np + 1);
1311 auto sumX1 = &(sumX1vec[1]);
1312 auto sumX2 = &(sumX2vec[1]);
1313 auto sumY1 = &(sumY1vec[1]);
1314 auto sumXY = &(sumXYvec[1]);
1317 for (
int iCl = 0; iCl < np; ++iCl) {
1318 int idx = iCl + idxOffset;
1319 sumX1[iCl] = sumX1[iCl - 1] +
x[idx];
1320 sumX2[iCl] = sumX2[iCl - 1] +
x[idx] *
x[idx];
1321 sumY1[iCl] = sumY1[iCl - 1] +
y[idx];
1322 sumXY[iCl] = sumXY[iCl - 1] +
x[idx] *
y[idx];
1325 for (
int iCl = 0; iCl < np; ++iCl) {
1326 int iClLeft = iCl - mParams->
nMAShort;
1327 int iClRight = iCl + mParams->
nMAShort;
1331 if (iClRight >= np) {
1334 int nPoints = iClRight - iClLeft;
1335 if (nPoints < mParams->nMAShort) {
1338 float nPointsInv = 1.f / nPoints;
1339 int iClLeftP = iClLeft - 1;
1340 int iClCurrP = iCl - 1;
1342 float sX1 = sumX1[iClRight] - sumX1[iClLeftP] - (sumX1[iCl] - sumX1[iClCurrP]);
1343 float sX2 = sumX2[iClRight] - sumX2[iClLeftP] - (sumX2[iCl] - sumX2[iClCurrP]);
1344 float sY1 = sumY1[iClRight] - sumY1[iClLeftP] - (sumY1[iCl] - sumY1[iClCurrP]);
1345 float sXY = sumXY[iClRight] - sumXY[iClLeftP] - (sumXY[iCl] - sumXY[iClCurrP]);
1346 float det = sX2 - nPointsInv * sX1 * sX1;
1347 if (fabsf(det) < 1e-12f) {
1350 float slope = (sXY - nPointsInv * sX1 * sY1) / det;
1351 float offset = nPointsInv * sY1 - nPointsInv *
slope * sX1;
1352 diffY[iCl + idxOffset] =
y[iCl + idxOffset] -
slope *
x[iCl + idxOffset] -
offset;
1359 std::vector<float> sumVec(np + 1);
1360 auto sum = &(sumVec[1]);
1361 for (
int i = 0;
i < np; ++
i) {
1364 for (
int i = 0;
i < np; ++
i) {
1374 int nPoints = iRight - iLeft;
1375 if (nPoints < mParams->nMALong) {
1379 float movingAverage = (
sum[iRight] -
sum[iLeft - 1] - (
sum[
i] -
sum[
i - 1])) / nPoints;
1380 diffMA[
i] =
y[
i] - movingAverage;
1387 mTrackDataCompact.clear();
1388 mTrackDataExtended.clear();
1390 mTrackDataUnfiltered.clear();
1391 mClResUnfiltered.clear();
1392 mGIDsSuccess.clear();
1393 for (
auto&
vec : mTrackIndices) {
1398 mTrackTimes.clear();
1406 if (
v.refVDrift != mTPCVDriftRef) {
1407 mTPCVDriftRef =
v.refVDrift;
1408 mTPCDriftTimeOffsetRef =
v.refTimeOffset;
1409 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.
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)
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)
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
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