Skip to content
4 changes: 4 additions & 0 deletions Detectors/TPC/calibration/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@ o2_add_test_root_macro(macro/drawCMV.C
COMPILE_ONLY
PUBLIC_LINK_LIBRARIES O2::TPCCalibration O2::TPCBase
LABELS tpc)
o2_add_test_root_macro(macro/calculatedEdx.C
COMPILE_ONLY
PUBLIC_LINK_LIBRARIES O2::TPCCalibration O2::TPCBase
LABELS tpc)

o2_add_test(IDCFourierTransform
COMPONENT_NAME calibration
Expand Down
325 changes: 284 additions & 41 deletions Detectors/TPC/calibration/include/TPCCalibration/CalculatedEdx.h

Large diffs are not rendered by default.

373 changes: 373 additions & 0 deletions Detectors/TPC/calibration/macro/calculatedEdx.C

Large diffs are not rendered by default.

1,301 changes: 960 additions & 341 deletions Detectors/TPC/calibration/src/CalculatedEdx.cxx

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions Detectors/TPC/calibration/src/TPCCalibrationLinkDef.h
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@
#pragma link C++ class o2::tpc::TPCFastSpaceChargeCorrectionHelper + ;

#pragma link C++ class o2::tpc::CalculatedEdx + ;
#pragma link C++ struct o2::tpc::AverageOccupancy + ;
#pragma link C++ class o2::tpc::TPCScaler + ;
#pragma link C++ struct o2::tpc::TPCScalerWeights + ;
#pragma link C++ class o2::tpc::TPCMShapeCorrection + ;
Expand Down
8 changes: 4 additions & 4 deletions GPU/GPUTracking/Interface/GPUO2InterfaceRefit.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -133,10 +133,10 @@ void GPUO2InterfaceRefit::updateCalib(const TPCFastTransformPOD* trans, float bz
mRefit->SetFastTransform(trans);
}

int32_t GPUO2InterfaceRefit::RefitTrackAsGPU(o2::tpc::TrackTPC& trk, bool outward, bool resetCov) { return mRefit->RefitTrackAsGPU(trk, outward, resetCov); }
int32_t GPUO2InterfaceRefit::RefitTrackAsTrackParCov(o2::tpc::TrackTPC& trk, bool outward, bool resetCov) { return mRefit->RefitTrackAsTrackParCov(trk, outward, resetCov); }
int32_t GPUO2InterfaceRefit::RefitTrackAsGPU(o2::track::TrackParCov& trk, const o2::tpc::TrackTPCClusRef& clusRef, float time0, float* chi2, bool outward, bool resetCov) { return mRefit->RefitTrackAsGPU(trk, clusRef, time0, chi2, outward, resetCov); }
int32_t GPUO2InterfaceRefit::RefitTrackAsTrackParCov(o2::track::TrackParCov& trk, const o2::tpc::TrackTPCClusRef& clusRef, float time0, float* chi2, bool outward, bool resetCov) { return mRefit->RefitTrackAsTrackParCov(trk, clusRef, time0, chi2, outward, resetCov); }
int32_t GPUO2InterfaceRefit::RefitTrackAsGPU(o2::tpc::TrackTPC& trk, bool outward, bool resetCov, bool* reachedReferenceOut) { return mRefit->RefitTrackAsGPU(trk, outward, resetCov, reachedReferenceOut); }
int32_t GPUO2InterfaceRefit::RefitTrackAsTrackParCov(o2::tpc::TrackTPC& trk, bool outward, bool resetCov, bool* reachedReferenceOut) { return mRefit->RefitTrackAsTrackParCov(trk, outward, resetCov, reachedReferenceOut); }
int32_t GPUO2InterfaceRefit::RefitTrackAsGPU(o2::track::TrackParCov& trk, const o2::tpc::TrackTPCClusRef& clusRef, float time0, float* chi2, bool outward, bool resetCov, bool* reachedReferenceOut) { return mRefit->RefitTrackAsGPU(trk, clusRef, time0, chi2, outward, resetCov, reachedReferenceOut); }
int32_t GPUO2InterfaceRefit::RefitTrackAsTrackParCov(o2::track::TrackParCov& trk, const o2::tpc::TrackTPCClusRef& clusRef, float time0, float* chi2, bool outward, bool resetCov, bool* reachedReferenceOut) { return mRefit->RefitTrackAsTrackParCov(trk, clusRef, time0, chi2, outward, resetCov, reachedReferenceOut); }
void GPUO2InterfaceRefit::setIgnoreErrorsAtTrackEnds(bool v) { mRefit->mIgnoreErrorsOnTrackEnds = v; }
void GPUO2InterfaceRefit::setTrackReferenceX(float v) { mParam->rec.tpc.trackReferenceX = v; }

Expand Down
8 changes: 4 additions & 4 deletions GPU/GPUTracking/Interface/GPUO2InterfaceRefit.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ class GPUO2InterfaceRefit
GPUO2InterfaceRefit(const o2::tpc::ClusterNativeAccess* cl, const o2::gpu::TPCFastTransformPOD* trans, float bzNominalGPU, const o2::tpc::TPCClRefElem* trackRef, uint32_t nHbfPerTf = 0, const uint8_t* sharedmap = nullptr, const uint32_t* occupancymap = nullptr, int32_t occupancyMapSize = -1, const std::vector<o2::tpc::TrackTPC>* trks = nullptr, o2::base::Propagator* p = nullptr);
~GPUO2InterfaceRefit();

int32_t RefitTrackAsGPU(o2::tpc::TrackTPC& trk, bool outward = false, bool resetCov = false);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we really need this additional return value? Can't you just check at the end if the track x position is at the reference?

int32_t RefitTrackAsTrackParCov(o2::tpc::TrackTPC& trk, bool outward = false, bool resetCov = false);
int32_t RefitTrackAsGPU(o2::track::TrackParCov& trk, const o2::tpc::TrackTPCClusRef& clusRef, float time0, float* chi2 = nullptr, bool outward = false, bool resetCov = false);
int32_t RefitTrackAsTrackParCov(o2::track::TrackParCov& trk, const o2::tpc::TrackTPCClusRef& clusRef, float time0, float* chi2 = nullptr, bool outward = false, bool resetCov = false);
int32_t RefitTrackAsGPU(o2::tpc::TrackTPC& trk, bool outward = false, bool resetCov = false, bool* reachedReferenceOut = nullptr);
int32_t RefitTrackAsTrackParCov(o2::tpc::TrackTPC& trk, bool outward = false, bool resetCov = false, bool* reachedReferenceOut = nullptr);
int32_t RefitTrackAsGPU(o2::track::TrackParCov& trk, const o2::tpc::TrackTPCClusRef& clusRef, float time0, float* chi2 = nullptr, bool outward = false, bool resetCov = false, bool* reachedReferenceOut = nullptr);
int32_t RefitTrackAsTrackParCov(o2::track::TrackParCov& trk, const o2::tpc::TrackTPCClusRef& clusRef, float time0, float* chi2 = nullptr, bool outward = false, bool resetCov = false, bool* reachedReferenceOut = nullptr);
void setTrackReferenceX(float v);
void setIgnoreErrorsAtTrackEnds(bool v);
void updateCalib(const o2::gpu::TPCFastTransformPOD* trans, float bzNominalGPU);
Expand Down
10 changes: 8 additions & 2 deletions GPU/GPUTracking/Merger/GPUTPCGMO2Output.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -124,6 +124,12 @@ GPUdii() void GPUTPCGMO2Output::Thread<GPUTPCGMO2Output::output>(int32_t nBlocks
TrackTPC oTrack;
const int32_t i = trackSort[iTmp].x;
const auto& track = tracks[i];
GPUCA_DEBUG_STREAMER_CHECK(if (o2::utils::DebugStreamer::checkStream(o2::utils::StreamFlags::streamdEdx)) {
o2::utils::DebugStreamer::instance()->getStreamer("debug_dedx", "UPDATE") << o2::utils::DebugStreamer::instance()->getUniqueTreeName("tree_indices").data()
<< "trackID=" << iTmp
<< "iTrk=" << i
<< "\n";
})
auto snpIn = track.GetParam().GetSinPhi();
if (snpIn > SNPThresh) {
snpIn = SNPThresh;
Expand Down Expand Up @@ -185,7 +191,7 @@ GPUdii() void GPUTPCGMO2Output::Thread<GPUTPCGMO2Output::output>(int32_t nBlocks
uint32_t nOutCl2 = 0;
float t1 = 0, t2 = 0;
int32_t sector1 = 0, sector2 = 0;
const o2::tpc::ClusterNativeAccess* GPUrestrict() clusters = merger.GetConstantMem()->ioPtrs.clustersNative;
const o2::tpc::ClusterNativeAccess* GPUrestrict() clusters = merger.GetConstantMem() -> ioPtrs.clustersNative;
for (uint32_t j = 0; j < track.NClusters(); j++) {
if ((trackClusters[track.FirstClusterRef() + j].state & flagsReject)) {
continue;
Expand Down Expand Up @@ -278,7 +284,7 @@ template <>
GPUdii() void GPUTPCGMO2Output::Thread<GPUTPCGMO2Output::mc>(int32_t nBlocks, int32_t nThreads, int32_t iBlock, int32_t iThread, GPUsharedref() GPUSharedMemory& smem, processorType& GPUrestrict() merger)
{
#ifndef GPUCA_GPUCODE
const o2::tpc::ClusterNativeAccess* GPUrestrict() clusters = merger.GetConstantMem()->ioPtrs.clustersNative;
const o2::tpc::ClusterNativeAccess* GPUrestrict() clusters = merger.GetConstantMem() -> ioPtrs.clustersNative;
if (clusters == nullptr || clusters->clustersMCTruth == nullptr) {
return;
}
Expand Down
23 changes: 13 additions & 10 deletions GPU/GPUTracking/Merger/GPUTPCGMTrackParam.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int32_
static constexpr float kDeg2Rad = M_PI / 180.f;
CADEBUG(static constexpr float kSectAngle = 2 * M_PI / 18.f);

const GPUParam& GPUrestrict() param = merger->Param();
const GPUParam& GPUrestrict() param = merger -> Param();

GPUdEdx dEdx, dEdxAlt;
GPUTPCGMPropagator prop;
Expand Down Expand Up @@ -126,7 +126,7 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int32_
const float clAlpha = param.Alpha(clusters[ihit].sector);
float xx, yy, zz;
{
const ClusterNative& GPUrestrict() cl = merger->GetConstantMem()->ioPtrs.clustersNative->clustersLinear[clusters[ihit].num];
const ClusterNative& GPUrestrict() cl = merger -> GetConstantMem()->ioPtrs.clustersNative->clustersLinear[clusters[ihit].num];
merger->GetConstantMem()->calibObjects.fastTransform->Transform(clusters[ihit].sector, clusters[ihit].row, cl.getPad(), cl.getTime(), xx, yy, zz, mTOffset);
}
// clang-format off
Expand Down Expand Up @@ -304,11 +304,11 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int32_
relTime /= clusterCount;
relTime = relTime - CAMath::Round(relTime);
if (acc) {
dEdx.fillCluster(qtot, qmax, cluster.row, cluster.sector, mP[2], mP[3], merger->GetConstantMem()->calibObjects, zz, pad, relTime);
dEdx.fillCluster(qtot, qmax, cluster.row, cluster.sector, mP[2], mP[3], merger->GetConstantMem()->calibObjects, zz, pad, relTime, iTrk, clusterState);
}
if GPUCA_RTC_CONSTEXPR (GPUCA_GET_CONSTEXPR(param.rec.tpc, dEdxClusterRejectionFlagMask) != GPUCA_GET_CONSTEXPR(param.rec.tpc, dEdxClusterRejectionFlagMaskAlt)) {
if (accAlt) {
dEdxAlt.fillCluster(qtot, qmax, cluster.row, cluster.sector, mP[2], mP[3], merger->GetConstantMem()->calibObjects, zz, pad, relTime);
dEdxAlt.fillCluster(qtot, qmax, cluster.row, cluster.sector, mP[2], mP[3], merger->GetConstantMem()->calibObjects, zz, pad, relTime, iTrk, clusterState);
}
}
}
Expand Down Expand Up @@ -364,14 +364,16 @@ GPUd() bool GPUTPCGMTrackParam::Fit(GPUTPCGMMerger* GPUrestrict() merger, int32_
return true;
}

GPUdni() void GPUTPCGMTrackParam::MoveToReference(GPUTPCGMPropagator& prop, const GPUParam& param, float& Alpha)
GPUdni() bool GPUTPCGMTrackParam::MoveToReference(GPUTPCGMPropagator& prop, const GPUParam& param, float& Alpha)
{
static constexpr float kDeg2Rad = M_PI / 180.f;
static constexpr float kSectAngle = 2 * M_PI / 18.f;

bool reachedReference = true;
if (param.rec.tpc.trackReferenceX <= 500) {
GPUTPCGMTrackParam save = *this;
float saveAlpha = Alpha;
reachedReference = false;

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed? Just return false if the loop is completed w/o returning true.

for (int32_t attempt = 0; attempt < 3; attempt++) {
float dAngle = CAMath::Round(CAMath::ATan2(mP[0], mX) / kDeg2Rad / 20.f) * kSectAngle;
Alpha += dAngle;
Expand All @@ -380,7 +382,7 @@ GPUdni() void GPUTPCGMTrackParam::MoveToReference(GPUTPCGMPropagator& prop, cons
}
ConstrainSinPhi();
if (CAMath::Abs(mP[0]) <= mX * CAMath::Tan(kSectAngle / 2.f)) {
return;
return true;
}
}
*this = save;
Expand All @@ -392,6 +394,7 @@ GPUdni() void GPUTPCGMTrackParam::MoveToReference(GPUTPCGMPropagator& prop, cons
ConstrainSinPhi();
Alpha += dAngle;
}
return reachedReference;
}

GPUd() void GPUTPCGMTrackParam::MirrorTo(GPUTPCGMPropagator& GPUrestrict() prop, float toY, float toZ, bool inFlyDirection, const GPUParam& param, uint8_t row, uint8_t clusterState, bool mirrorParameters, int8_t sector)
Expand Down Expand Up @@ -440,7 +443,7 @@ GPUd() int32_t GPUTPCGMTrackParam::MergeDoubleRowClusters(int32_t& ihit, int32_t
xx = yy = zz = 0.f;
clusterState = 0;
while (true) {
const ClusterNative& GPUrestrict() cl = merger->GetConstantMem()->ioPtrs.clustersNative->clustersLinear[clusters[ihit].num];
const ClusterNative& GPUrestrict() cl = merger -> GetConstantMem()->ioPtrs.clustersNative->clustersLinear[clusters[ihit].num];

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure this r formatting is correct. Also, it is quite sporadic.Was it imposed by the clang-format?

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a bug in clang-format. You can leave it in or not, it will not break the code. But I will most probably revert such bogus formatting with my next PR.

float clamp = cl.getQtot();
float clx, cly, clz;
merger->GetConstantMem()->calibObjects.fastTransform->Transform(clusters[ihit].sector, clusters[ihit].row, cl.getPad(), cl.getTime(), clx, cly, clz, mTOffset);
Expand Down Expand Up @@ -493,7 +496,7 @@ GPUd() float GPUTPCGMTrackParam::AttachClusters(const GPUTPCGMMerger* GPUrestric
if (param.rec.tpc.disableRefitAttachment & 1) {
return -1e6f;
}
const GPUTPCTracker& GPUrestrict() tracker = *(Merger->GetConstantMem()->tpcTrackers + sector);
const GPUTPCTracker& GPUrestrict() tracker = *(Merger -> GetConstantMem()->tpcTrackers + sector);
const GPUTPCRow& GPUrestrict() row = tracker.Row(iRow);
GPUglobalref() const cahit2* hits = tracker.HitData(row);
GPUglobalref() const calink* firsthit = tracker.FirstHitInBin(row);
Expand Down Expand Up @@ -679,7 +682,7 @@ GPUdi() void GPUTPCGMTrackParam::AttachClustersLooperFollow(const GPUTPCGMMerger
bool inFlyDirection = (Merger->MergedTracks()[iTrack].Leg() & 1) ^ up;

static constexpr float kSectAngle = 2 * M_PI / 18.f;
const GPUParam& GPUrestrict() param = Merger->Param();
const GPUParam& GPUrestrict() param = Merger -> Param();
bool right = (mP[2] < 0) ^ up;
const int32_t sectorSide = sector >= (int32_t)(GPUTPCGeometry::NSECTORS / 2) ? (GPUTPCGeometry::NSECTORS / 2) : 0;
float lrFactor = right ^ !up ? 1.f : -1.f;
Expand Down Expand Up @@ -803,7 +806,7 @@ GPUd() float GPUTPCGMTrackParam::ShiftZ(const GPUTPCGMMergedTrackHit* clusters,
if (N == 0) {
N = 1;
}
const auto& GPUrestrict() cls = merger->GetConstantMem()->ioPtrs.clustersNative->clustersLinear;
const auto& GPUrestrict() cls = merger -> GetConstantMem()->ioPtrs.clustersNative->clustersLinear;
float z0 = cls[clusters[0].num].getTime(), zn = cls[clusters[N - 1].num].getTime();
const auto tmp = zn > z0 ? std::array<float, 3>{zn, z0, GPUTPCGeometry::Row2X(clusters[N - 1].row)} : std::array<float, 3>{z0, zn, GPUTPCGeometry::Row2X(clusters[0].row)};
return ShiftZ(merger, clusters[0].sector, tmp[0], tmp[1], tmp[2]);
Expand Down
14 changes: 7 additions & 7 deletions GPU/GPUTracking/Merger/GPUTPCGMTrackParam.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ class GPUTPCGMTrackParam
GPUd() bool CheckCov() const;

GPUd() bool Fit(GPUTPCGMMerger* merger, int32_t iTrk, GPUTPCGMMergedTrackHit* clusters, int32_t& N, int32_t& NTolerated, float& Alpha, int32_t attempt, float maxSinPhi, GPUTPCGMMergedTrack& track);
GPUd() void MoveToReference(GPUTPCGMPropagator& prop, const GPUParam& param, float& alpha);
GPUd() bool MoveToReference(GPUTPCGMPropagator& prop, const GPUParam& param, float& alpha); ///< returns false if the track could not be propagated to param.rec.tpc.trackReferenceX (position/momentum then rolled back to their pre-call values, but the trailing sector-normalization step may still rotate the track and update alpha); true if it reached it or the reference is disabled (trackReferenceX > 500)
GPUd() void MirrorTo(GPUTPCGMPropagator& prop, float toY, float toZ, bool inFlyDirection, const GPUParam& param, uint8_t row, uint8_t clusterState, bool mirrorParameters, int8_t sector);
GPUd() int32_t MergeDoubleRowClusters(int32_t& ihit, int32_t wayDirection, GPUTPCGMMergedTrackHit* clusters, const GPUTPCGMMerger* merger, GPUTPCGMPropagator& prop, float& xx, float& yy, float& zz, int32_t maxN, float clAlpha, uint8_t& clusterState, bool rejectChi2);

Expand Down Expand Up @@ -214,12 +214,12 @@ class GPUTPCGMTrackParam
private:
GPUd() int32_t initResetT0();

float mX; // x position
float mTOffset; // Z offset with early transform, T offset otherwise
float mP[5]; // 'active' track parameters: Y, Z, SinPhi, DzDs, q/Pt
float mC[15]; // the covariance matrix for Y,Z,SinPhi,..
float mChi2; // the chi^2 value
int32_t mNDF; // the Number of Degrees of Freedom
float mX; // x position
float mTOffset; // Z offset with early transform, T offset otherwise
float mP[5]; // 'active' track parameters: Y, Z, SinPhi, DzDs, q/Pt
float mC[15]; // the covariance matrix for Y,Z,SinPhi,..
float mChi2; // the chi^2 value
int32_t mNDF; // the Number of Degrees of Freedom
};

struct GPUTPCGMLoopData {
Expand Down
25 changes: 15 additions & 10 deletions GPU/GPUTracking/Refit/GPUTrackingRefit.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ GPUd() static const float* getPar(const GPUTPCGMTrackParam& trk) { return trk.Ge
GPUd() static const float* getPar(const TrackParCov& trk) { return trk.getParams(); }

template <class T, class S>
GPUd() int32_t GPUTrackingRefit::RefitTrack(T& trkX, bool outward, bool resetCov)
GPUd() int32_t GPUTrackingRefit::RefitTrack(T& trkX, bool outward, bool resetCov, bool* reachedReferenceOut)
{
CADEBUG(int32_t ii; printf("\nRefitting track\n"));
typename internal::refitTrackTypes<S>::propagator prop;
Expand Down Expand Up @@ -392,20 +392,22 @@ GPUd() int32_t GPUTrackingRefit::RefitTrack(T& trkX, bool outward, bool resetCov
resetCov = false;
nFitted++;
}
bool reachedReference = true;
if constexpr (std::is_same_v<S, GPUTPCGMTrackParam>) {
float alpha = prop.GetAlpha();
trk.MoveToReference(prop, *mPparam, alpha);
reachedReference = trk.MoveToReference(prop, *mPparam, alpha);
trk.NormalizeAlpha(alpha);
prop.SetAlpha(alpha);
} else if constexpr (std::is_same_v<S, TrackParCov>) {
static constexpr float kDeg2Rad = M_PI / 180.f;
static constexpr float kSectAngle = 2 * M_PI / 18.f;
if (mPparam->rec.tpc.trackReferenceX <= 500) {
if (prop->PropagateToXBxByBz(trk, mPparam->rec.tpc.trackReferenceX)) {
reachedReference = prop->PropagateToXBxByBz(trk, mPparam->rec.tpc.trackReferenceX);
if (reachedReference) {
if (CAMath::Abs(trk.getY()) > trk.getX() * CAMath::Tan(kSectAngle / 2.f)) {
float newAlpha = trk.getAlpha() + CAMath::Round(CAMath::ATan2(trk.getY(), trk.getX()) / kDeg2Rad / 20.f) * kSectAngle;
GPUTPCGMTrackParam::NormalizeAlpha(newAlpha);
trk.rotate(newAlpha) && prop->PropagateToXBxByBz(trk, mPparam->rec.tpc.trackReferenceX);
reachedReference = trk.rotate(newAlpha) && prop->PropagateToXBxByBz(trk, mPparam->rec.tpc.trackReferenceX);
}
}
}
Expand All @@ -414,16 +416,19 @@ GPUd() int32_t GPUTrackingRefit::RefitTrack(T& trkX, bool outward, bool resetCov
}

convertTrack<T, S, typename internal::refitTrackTypes<S>::propagator>(trkX, trk, prop, &TrackParCovChi2);
if (reachedReferenceOut) {
*reachedReferenceOut = reachedReference;
}
return nFitted;
}

#if !defined(GPUCA_GPUCODE) || defined(GPUCA_GPUCODE_DEVICE) // FIXME: DR: WORKAROUND to avoid CUDA bug creating host symbols for device code.
template GPUdni() int32_t GPUTrackingRefit::RefitTrack<GPUTPCGMMergedTrack, TrackParCov>(GPUTPCGMMergedTrack& trk, bool outward, bool resetCov);
template GPUdni() int32_t GPUTrackingRefit::RefitTrack<GPUTPCGMMergedTrack, GPUTPCGMTrackParam>(GPUTPCGMMergedTrack& trk, bool outward, bool resetCov);
template GPUdni() int32_t GPUTrackingRefit::RefitTrack<TrackTPC, TrackParCov>(TrackTPC& trk, bool outward, bool resetCov);
template GPUdni() int32_t GPUTrackingRefit::RefitTrack<TrackTPC, GPUTPCGMTrackParam>(TrackTPC& trk, bool outward, bool resetCov);
template GPUdni() int32_t GPUTrackingRefit::RefitTrack<GPUTrackingRefit::TrackParCovWithArgs, TrackParCov>(GPUTrackingRefit::TrackParCovWithArgs& trk, bool outward, bool resetCov);
template GPUdni() int32_t GPUTrackingRefit::RefitTrack<GPUTrackingRefit::TrackParCovWithArgs, GPUTPCGMTrackParam>(GPUTrackingRefit::TrackParCovWithArgs& trk, bool outward, bool resetCov);
template GPUdni() int32_t GPUTrackingRefit::RefitTrack<GPUTPCGMMergedTrack, TrackParCov>(GPUTPCGMMergedTrack& trk, bool outward, bool resetCov, bool* reachedReferenceOut);
template GPUdni() int32_t GPUTrackingRefit::RefitTrack<GPUTPCGMMergedTrack, GPUTPCGMTrackParam>(GPUTPCGMMergedTrack& trk, bool outward, bool resetCov, bool* reachedReferenceOut);
template GPUdni() int32_t GPUTrackingRefit::RefitTrack<TrackTPC, TrackParCov>(TrackTPC& trk, bool outward, bool resetCov, bool* reachedReferenceOut);
template GPUdni() int32_t GPUTrackingRefit::RefitTrack<TrackTPC, GPUTPCGMTrackParam>(TrackTPC& trk, bool outward, bool resetCov, bool* reachedReferenceOut);
template GPUdni() int32_t GPUTrackingRefit::RefitTrack<GPUTrackingRefit::TrackParCovWithArgs, TrackParCov>(GPUTrackingRefit::TrackParCovWithArgs& trk, bool outward, bool resetCov, bool* reachedReferenceOut);
template GPUdni() int32_t GPUTrackingRefit::RefitTrack<GPUTrackingRefit::TrackParCovWithArgs, GPUTPCGMTrackParam>(GPUTrackingRefit::TrackParCovWithArgs& trk, bool outward, bool resetCov, bool* reachedReferenceOut);
#endif

#ifndef GPUCA_GPUCODE
Expand Down
Loading
Loading