diff --git a/GPU/GPUTracking/DataCompression/GPUTPCClusterRejection.h b/GPU/GPUTracking/DataCompression/GPUTPCClusterRejection.h index ae3ffb29926a7..8ec8c85c4c73f 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCClusterRejection.h +++ b/GPU/GPUTracking/DataCompression/GPUTPCClusterRejection.h @@ -16,12 +16,19 @@ #define GPUTPCCLUSTERREJECTION_H #include "GPUTPCGMMergerTypes.h" +#include "GPUCommonMath.h" namespace o2::gpu { struct GPUTPCClusterRejection { + template + GPUdi() static bool IsTrackRejected(const T& trk, const S& param) + { + return CAMath::Abs(trk.GetParam().GetQPt() * param.qptB5Scaler) > param.rec.tpc.rejectQPtB5 || trk.MergedLooper(); + } + template - static constexpr inline bool GetProtectionStatus(int32_t attach, bool& physics, bool& protect, T* counts = nullptr, S* mev200 = nullptr) + GPUdi() static constexpr bool GetRejectionStatus(int32_t attach, bool& physics, T* counts = nullptr, S* mev200 = nullptr) { (void)counts; // FIXME: Avoid incorrect -Wunused-but-set-parameter warning (void)mev200; @@ -39,7 +46,6 @@ struct GPUTPCClusterRejection { } retVal = true; } else if (attach & gputpcgmmergertypes::attachTube) { - protect = true; if constexpr (C) { if (*mev200) { counts->nTube200++; @@ -49,7 +55,6 @@ struct GPUTPCClusterRejection { } retVal = false; } else if ((attach & gputpcgmmergertypes::attachGood) == 0) { - protect = true; if constexpr (C) { counts->nRejected++; } @@ -60,16 +65,15 @@ struct GPUTPCClusterRejection { } if (attach & gputpcgmmergertypes::attachProtect) { - protect = true; retVal = false; } return retVal; } - static constexpr inline bool GetIsRejected(int32_t attach) + GPUdi() static constexpr bool GetIsRejected(int32_t attach) { - bool physics = false, protect = false; - return GetProtectionStatus(attach, physics, protect); + bool physics = false; + return GetRejectionStatus(attach, physics); } }; } // namespace o2::gpu diff --git a/GPU/GPUTracking/DataCompression/GPUTPCCompression.cxx b/GPU/GPUTracking/DataCompression/GPUTPCCompression.cxx index 61f8a614fbe6f..85cd9598e0bf1 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCCompression.cxx +++ b/GPU/GPUTracking/DataCompression/GPUTPCCompression.cxx @@ -111,7 +111,7 @@ void GPUTPCCompression::RegisterMemoryAllocation() if (gatherMode == 3) { mMemoryResOutputGPU = mRec->RegisterMemoryAllocation(this, &GPUTPCCompression::SetPointersOutputGPU, GPUMemoryResource::MEMORY_SCRATCH | GPUMemoryResource::MEMORY_GPU | GPUMemoryResource::MEMORY_CUSTOM | GPUMemoryResource::MEMORY_STACK, "TPCCompressionOutputGPU"); } - uint32_t stackScratch = (gatherMode != 3) ? GPUMemoryResource::MEMORY_STACK : 0; + uint32_t stackScratch = (gatherMode != 3) ? GPUMemoryResource::MEMORY_STACK : 0; // TODO: Can we use stacked memory also with gather mode 3? if (gatherMode < 2) { mRec->RegisterMemoryAllocation(this, &GPUTPCCompression::SetPointersOutput, GPUMemoryResource::MEMORY_OUTPUT | stackScratch, "TPCCompressionOutput"); } diff --git a/GPU/GPUTracking/DataCompression/GPUTPCCompression.h b/GPU/GPUTracking/DataCompression/GPUTPCCompression.h index 1dafffaeea043..95173dad7257f 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCCompression.h +++ b/GPU/GPUTracking/DataCompression/GPUTPCCompression.h @@ -60,6 +60,7 @@ class GPUTPCCompression : public GPUProcessor #ifndef GPUCA_GPUCODE void DumpCompressedClusters(std::ostream& out); #endif + GPUd() bool rejectCluster(int32_t idx, const GPUParam& param, const GPUTrackingInOutPointers& ioPtrs) const; protected: struct memory { @@ -89,7 +90,6 @@ class GPUTPCCompression : public GPUProcessor void SetPointersCompressedClusters(void*& mem, T& c, uint32_t nClA, uint32_t nTr, uint32_t nClU, bool reducedClA); template GPUd() static void truncateSignificantBits(T& val, uint32_t nBits, uint32_t max); - GPUd() bool rejectCluster(int32_t idx, GPUParam& param, const GPUTrackingInOutPointers& ioPtrs); int16_t mMemoryResOutputHost = -1; int16_t mMemoryResOutputGPU = -1; diff --git a/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.cxx b/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.cxx index 911af719dd3d4..1cd44e221f203 100644 --- a/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.cxx +++ b/GPU/GPUTracking/DataCompression/GPUTPCCompressionKernels.cxx @@ -39,7 +39,7 @@ GPUdii() void GPUTPCCompressionKernels::Thread processors.param.rec.tpc.rejectQPtB5 || trk.MergedLooper(); + bool rejectTrk = GPUTPCClusterRejection::IsTrackRejected(trk, param); uint32_t nClustersStored = 0; CompressedClustersPtrs& GPUrestrict() c = compressor.mPtrs; uint8_t lastRow = 0, lastSector = 0; @@ -185,7 +185,7 @@ GPUd() bool GPUTPCCompressionKernels::GPUTPCCompressionKernels_Compare<4>::opera return mClsPtr[a].qTot < mClsPtr[b].qTot; } -GPUd() bool GPUTPCCompression::rejectCluster(int32_t idx, GPUParam& GPUrestrict() param, const GPUTrackingInOutPointers& GPUrestrict() ioPtrs) +GPUd() bool GPUTPCCompression::rejectCluster(int32_t idx, const GPUParam& GPUrestrict() param, const GPUTrackingInOutPointers& GPUrestrict() ioPtrs) const { if (mClusterStatus[idx]) { return true; @@ -206,7 +206,7 @@ GPUd() bool GPUTPCCompression::rejectCluster(int32_t idx, GPUParam& GPUrestrict( } int32_t id = attach & gputpcgmmergertypes::attachTrackMask; auto& trk = ioPtrs.mergedTracks[id]; - if (CAMath::Abs(trk.GetParam().GetQPt() * param.qptB5Scaler) > param.rec.tpc.rejectQPtB5 || trk.MergedLooper()) { + if (GPUTPCClusterRejection::IsTrackRejected(trk, param)) { return true; } } diff --git a/GPU/GPUTracking/Definitions/GPUSettingsList.h b/GPU/GPUTracking/Definitions/GPUSettingsList.h index f8845f82ee1e2..2f1eb72cb3d00 100644 --- a/GPU/GPUTracking/Definitions/GPUSettingsList.h +++ b/GPU/GPUTracking/Definitions/GPUSettingsList.h @@ -596,6 +596,7 @@ AddOption(stripDumpedEvents, bool, false, "", 0, "Remove redundant inputs (e.g. AddOption(printSettings, int32_t, 0, "", 0, "Print all settings", def(1)) AddOption(testSyncAsync, bool, false, "syncAsync", 0, "Test first synchronous and then asynchronous processing") AddOption(testSync, bool, false, "sync", 0, "Test settings for synchronous phase") +AddOption(testSyncAsyncQcInSync, bool, false, "syncAsyncSyncQC", 0, "Run QC in sync phase of testSyncAsync") AddOption(timeFrameTime, bool, false, "tfTime", 0, "Print some debug information about time frame processing time") AddOption(controlProfiler, bool, false, "", 0, "Issues GPU profiler stop and start commands to profile only the relevant processing part") AddOption(preloadEvents, bool, false, "", 0, "Preload events into host memory before start processing") diff --git a/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx b/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx index 7a870ccb35178..bfb0457744ce5 100644 --- a/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx +++ b/GPU/GPUTracking/Global/GPUChainTrackingClusterizer.cxx @@ -587,7 +587,7 @@ int32_t GPUChainTracking::RunTPCClusterizer(bool synchronizeOutput) return ForwardTPCDigits(); } #ifdef GPUCA_TPC_GEOMETRY_O2 - [[maybe_unused]] int32_t tpcTimeBinCut = mUpdateNewCalibObjects && mNewCalibValues->newTPCTimeBinCut ? mNewCalibValues->tpcTimeBinCut : param().tpcCutTimeBin; + [[maybe_unused]] int32_t tpcTimeBinCut = (mUpdateNewCalibObjects && mNewCalibValues->newTPCTimeBinCut) ? mNewCalibValues->tpcTimeBinCut : param().tpcCutTimeBin; // TODO: Implement time bin cut fultering mRec->PushNonPersistentMemory(qStr2Tag("TPCCLUST")); const auto& threadContext = GetThreadContext(); const bool doGPU = GetRecoStepsGPU() & RecoStep::TPCClusterFinding; diff --git a/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx b/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx index 6b0637c76d857..b0ea1f5b7dbcb 100644 --- a/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx +++ b/GPU/GPUTracking/Standalone/Benchmark/standalone.cxx @@ -72,6 +72,7 @@ extern GPUSettingsStandalone configStandalone; } GPUReconstruction *rec, *recAsync, *recPipeline; +uint32_t syncAsyncDecodedClusters = 0; GPUChainTracking *chainTracking, *chainTrackingAsync, *chainTrackingPipeline; GPUChainITS *chainITS, *chainITSAsync, *chainITSPipeline; std::string eventsDir; @@ -430,7 +431,7 @@ int32_t SetupReconstruction() } } - bool runAsyncQA = procSet.runQA; + bool runAsyncQA = procSet.runQA && !configStandalone.testSyncAsyncQcInSync; if (configStandalone.testSyncAsync || configStandalone.testSync) { // Set settings for synchronous if (configStandalone.rundEdx == -1) { @@ -439,7 +440,9 @@ int32_t SetupReconstruction() recSet.useMatLUT = false; if (configStandalone.testSyncAsync) { procSet.eventDisplay = nullptr; - procSet.runQA = false; + if (!configStandalone.testSyncAsyncQcInSync) { + procSet.runQA = false; + } } } if (configStandalone.proc.rtc.optSpecialCode == -1) { @@ -664,12 +667,12 @@ int32_t RunBenchmark(GPUReconstruction* recUse, GPUChainTracking* chainTrackingU } if (tmpRetVal == 0 && configStandalone.testSyncAsync) { - if (configStandalone.testSyncAsync) { - printf("Running asynchronous phase\n"); - } vecpod compressedTmpMem(chainTracking->mIOPtrs.tpcCompressedClusters->totalDataSize); memcpy(compressedTmpMem.data(), (const void*)chainTracking->mIOPtrs.tpcCompressedClusters, chainTracking->mIOPtrs.tpcCompressedClusters->totalDataSize); + o2::tpc::CompressedClusters tmp(*chainTracking->mIOPtrs.tpcCompressedClusters); + syncAsyncDecodedClusters = tmp.nAttachedClusters + tmp.nUnattachedClusters; + printf("Running asynchronous phase from %'u compressed clusters\n", syncAsyncDecodedClusters); chainTrackingAsync->mIOPtrs = ioPtrs; chainTrackingAsync->mIOPtrs.tpcCompressedClusters = (o2::tpc::CompressedClustersFlat*)compressedTmpMem.data(); @@ -937,6 +940,11 @@ int32_t main(int argc, char** argv) printf("%s (Measured %s time - Extrapolated from %d clusters to %d)\n", stat, configStandalone.proc.debugLevel ? "kernel" : "wall", (int32_t)nClusters, (int32_t)nClsPerTF); } } + if (configStandalone.testSyncAsync && chainTracking->mIOPtrs.clustersNative && chainTrackingAsync->mIOPtrs.clustersNative) { + uint32_t rejected = chainTracking->mIOPtrs.clustersNative->nClustersTotal - syncAsyncDecodedClusters; + float rejectionPercentage = (rejected) * 100.f / chainTracking->mIOPtrs.clustersNative->nClustersTotal; + printf("Cluster Rejection: Sync: %'u, Compressed %'u, Async %'u, Rejected %'u (%7.2f%%)\n", chainTracking->mIOPtrs.clustersNative->nClustersTotal, syncAsyncDecodedClusters, chainTrackingAsync->mIOPtrs.clustersNative->nClustersTotal, rejected, rejectionPercentage); + } if (configStandalone.preloadEvents && configStandalone.proc.doublePipeline) { break; diff --git a/GPU/GPUTracking/qa/GPUQA.cxx b/GPU/GPUTracking/qa/GPUQA.cxx index 681426cdc9575..8d608e9a90173 100644 --- a/GPU/GPUTracking/qa/GPUQA.cxx +++ b/GPU/GPUTracking/qa/GPUQA.cxx @@ -55,6 +55,7 @@ #include "SimulationDataFormat/ConstMCTruthContainer.h" #include "SimulationDataFormat/MCCompLabel.h" #include "GPUSettings.h" +#include "GPUDefMacros.h" #ifdef GPUCA_O2_LIB #include "DetectorsRaw/HBFUtils.h" #include "DataFormatsTPC/TrackTPC.h" @@ -81,58 +82,55 @@ using namespace o2::gpu; -#ifdef GPUCA_MERGER_BY_MC_LABEL -#define CHECK_CLUSTER_STATE_INIT_LEG_BY_MC() \ - if (!unattached && mTrackMCLabels[id].isValid()) { \ - int32_t mcLabel = mTrackMCLabels[id].getTrackID(); \ - int32_t mcEvent = mTrackMCLabels[id].getEventID(); \ - int32_t mcSource = mTrackMCLabels[id].getSourceID(); \ - if (mTrackMCLabelsReverse[mMCEventOffset[mcSource] + mcEvent][mcLabel] != id) { \ - attach &= (~gputpcgmmergertypes::attachGoodLeg); \ - } \ - } -#else -#define CHECK_CLUSTER_STATE_INIT_LEG_BY_MC() -#endif +namespace o2::gpu +{ +struct checkClusterStateResult { + bool unattached = false; + float qpt = 0.f; + bool lowPt = false; + bool mev200 = false; + bool mergedLooperUnconnected = false; + bool mergedLooperConnected = false; + int32_t id = 0; + bool physics = false, protect = false; +}; +} // namespace o2::gpu -#define CHECK_CLUSTER_STATE_INIT() \ - bool unattached = attach == 0; \ - float qpt = 0; \ - bool lowPt = false; \ - [[maybe_unused]] bool mev200 = false; \ - bool mergedLooperUnconnected = false; \ - bool mergedLooperConnected = false; \ - int32_t id = attach & gputpcgmmergertypes::attachTrackMask; \ - if (!unattached) { \ - qpt = fabsf(mTracking->mIOPtrs.mergedTracks[id].GetParam().GetQPt()); \ - lowPt = qpt * mTracking->GetParam().qptB5Scaler > mTracking->GetParam().rec.tpc.rejectQPtB5; \ - mev200 = qpt > 5; \ - mergedLooperUnconnected = mTracking->mIOPtrs.mergedTracks[id].MergedLooperUnconnected(); \ - mergedLooperConnected = mTracking->mIOPtrs.mergedTracks[id].MergedLooperConnected(); \ - } \ - bool physics = false, protect = false; \ - CHECK_CLUSTER_STATE_INIT_LEG_BY_MC(); - -#define CHECK_CLUSTER_STATE() \ - CHECK_CLUSTER_STATE_INIT() \ - if (mev200) { \ - mClusterCounts.n200MeV++; \ - } \ - if (lowPt) { \ - mClusterCounts.nLowPt++; \ - } else if (mergedLooperUnconnected) { \ - mClusterCounts.nMergedLooperUnconnected++; \ - } else if (mergedLooperConnected) { \ - mClusterCounts.nMergedLooperConnected++; \ - } else { \ - GPUTPCClusterRejection::GetProtectionStatus(attach, physics, protect, &mClusterCounts, &mev200); \ - } - -#define CHECK_CLUSTER_STATE_NOCOUNT() \ - CHECK_CLUSTER_STATE_INIT() \ - if (!lowPt && !mergedLooperUnconnected && !mergedLooperConnected) { \ - GPUTPCClusterRejection::GetProtectionStatus(attach, physics, protect); \ +template +inline checkClusterStateResult GPUQA::checkClusterState(uint32_t attach, T* counts) const +{ + checkClusterStateResult r; + r.unattached = attach == 0; + r.id = attach & gputpcgmmergertypes::attachTrackMask; + if (!r.unattached && !(attach & gputpcgmmergertypes::attachProtect)) { + r.qpt = fabsf(mTracking->mIOPtrs.mergedTracks[r.id].GetParam().GetQPt()); + r.lowPt = r.qpt * mTracking->GetParam().qptB5Scaler > mTracking->GetParam().rec.tpc.rejectQPtB5; + r.mev200 = r.qpt > 5; + r.mergedLooperUnconnected = mTracking->mIOPtrs.mergedTracks[r.id].MergedLooperUnconnected(); + r.mergedLooperConnected = mTracking->mIOPtrs.mergedTracks[r.id].MergedLooperConnected(); + } + if (r.mev200) { + if constexpr (COUNT) { + counts->n200MeV++; + } } + if (r.lowPt) { + if constexpr (COUNT) { + counts->nLowPt++; + } + } else if (r.mergedLooperUnconnected) { + if constexpr (COUNT) { + counts->nMergedLooperUnconnected++; + } + } else if (r.mergedLooperConnected) { + if constexpr (COUNT) { + counts->nMergedLooperConnected++; + } + } else if (attach) { + r.protect = !GPUTPCClusterRejection::GetRejectionStatus(attach, r.physics, counts, &r.mev200) && ((attach & gputpcgmmergertypes::attachProtect) || !GPUTPCClusterRejection::IsTrackRejected(mTracking->mIOPtrs.mergedTracks[r.id], mTracking->GetParam())); + } + return r; +} static const GPUSettingsQA& GPUQA_GetConfig(GPUChainTracking* chain) { @@ -159,7 +157,7 @@ static constexpr bool CLUST_HIST_INT_SUM = false; static constexpr const int32_t COLORCOUNT = 12; -static const constexpr char* EFF_TYPES[5] = {"Rec", "Clone", "Fake", "All", "RecAndClone"}; +static const constexpr char* EFF_TYPES[6] = {"Rec", "Clone", "Fake", "All", "RecAndClone", "MC"}; static const constexpr char* FINDABLE_NAMES[2] = {"All", "Findable"}; static const constexpr char* PRIM_NAMES[2] = {"Prim", "Sec"}; static const constexpr char* PARAMETER_NAMES[5] = {"Y", "Z", "#Phi", "#lambda", "Relative #it{p}_{T}"}; @@ -350,11 +348,11 @@ GPUQA::~GPUQA() bool GPUQA::clusterRemovable(int32_t attach, bool prot) const { - CHECK_CLUSTER_STATE_NOCOUNT(); + const auto& r = checkClusterState(attach); if (prot) { - return protect || physics; + return r.protect || r.physics; } - return (!unattached && !physics && !protect); + return (!r.unattached && !r.physics && !r.protect); } template @@ -440,7 +438,7 @@ int32_t GPUQA::InitQACreateHistograms() char name[2048], fname[1024]; if (mQATasks & taskTrackingEff) { // Create Efficiency Histograms - for (int32_t i = 0; i < 5; i++) { + for (int32_t i = 0; i < 6; i++) { for (int32_t j = 0; j < 2; j++) { for (int32_t k = 0; k < 2; k++) { for (int32_t l = 0; l < 5; l++) { @@ -539,6 +537,12 @@ int32_t GPUQA::InitQACreateHistograms() createHist(mT0[0], "tracks_t0", "tracks_t0", (maxTime + 1) / 10, 0, maxTime); createHist(mT0[1], "tracks_t0_res", "tracks_t0_res", 1000, -100, 100); createHist(mClXY, "clXY", "clXY", 1000, -250, 250, 1000, -250, 250); // TODO: Pass name only once + const int padCount = GPUTPCGeometry::NPads(GPUCA_ROW_COUNT - 1); + for (int32_t i = 0; i < 3; i++) { + snprintf(name, 2048, "clrej_%d", i); + createHist(mClRej[i], name, name, 2 * padCount, -padCount / 2 + 0.5f, padCount / 2 - 0.5f, GPUCA_ROW_COUNT, 0, GPUCA_ROW_COUNT - 1); + } + createHist(mClRejP, "clrejp", "clrejp", GPUCA_ROW_COUNT, 0, GPUCA_ROW_COUNT - 1); } if ((mQATasks & taskClusterCounts) && mConfig.clusterRejectionHistograms) { @@ -1236,7 +1240,10 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx effdump.Fill(alpha, localX, localY, info.z, mcphi, mceta, mcpt, mRecTracks[iCol][i], mFakeTracks[iCol][i], findable, info.prim, mc2.nWeightCls); } - for (int32_t j = 0; j < 4; j++) { + for (int32_t j = 0; j < 6; j++) { + if (j == 3 || j == 4) { + continue; + } for (int32_t k = 0; k < 2; k++) { if (k == 0 && findable == 0) { continue; @@ -1462,7 +1469,7 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx } } int32_t attach = mTracking->mIOPtrs.mergedTrackHitAttachment[hitId]; - CHECK_CLUSTER_STATE_NOCOUNT(); + const auto& r = checkClusterState(attach); if (totalWeight > 0) { float weight = 1.f / (totalWeight * (mClusterParam[hitId].attached + mClusterParam[hitId].fakeAttached)); for (int32_t j = 0; j < GetMCLabelNID(hitId); j++) { @@ -1478,10 +1485,10 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx mClusters[CL_tracks]->Fill(pt, GetMCLabelWeight(hitId, j) * weight); } mClusters[CL_all]->Fill(pt, GetMCLabelWeight(hitId, j) * weight); - if (protect || physics) { + if (r.protect || r.physics) { mClusters[CL_prot]->Fill(pt, GetMCLabelWeight(hitId, j) * weight); } - if (physics) { + if (r.physics) { mClusters[CL_physics]->Fill(pt, GetMCLabelWeight(hitId, j) * weight); } } @@ -1492,10 +1499,10 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx mClusters[CL_att_adj]->Fill(0.f, weight); mClusters[CL_all]->Fill(0.f, weight); mClusterCounts.nUnaccessible += weight; - if (protect || physics) { + if (r.protect || r.physics) { mClusters[CL_prot]->Fill(0.f, weight); } - if (physics) { + if (r.physics) { mClusters[CL_physics]->Fill(0.f, weight); } } @@ -1532,11 +1539,11 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx mClusters[CL_att_adj]->Fill(pt, weight); mClusters[CL_all]->Fill(pt, weight); int32_t attach = mTracking->mIOPtrs.mergedTrackHitAttachment[hitId]; - CHECK_CLUSTER_STATE_NOCOUNT(); - if (protect || physics) { + const auto& r = checkClusterState(attach); + if (r.protect || r.physics) { mClusters[CL_prot]->Fill(pt, weight); } - if (physics) { + if (r.physics) { mClusters[CL_physics]->Fill(pt, weight); } } @@ -1549,7 +1556,7 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx continue; } int32_t attach = mTracking->mIOPtrs.mergedTrackHitAttachment[i]; - CHECK_CLUSTER_STATE_NOCOUNT(); + const auto& r = checkClusterState(attach); if (mClusterParam[i].adjacent) { int32_t label = mTracking->mIOPtrs.mergedTrackHitAttachment[i] & gputpcgmmergertypes::attachTrackMask; if (!mTrackMCLabels[label].isValid()) { @@ -1575,10 +1582,10 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx mClusters[CL_att_adj]->Fill(pt, GetMCLabelWeight(i, j) * weight); mClusters[CL_fakeAdj]->Fill(pt, GetMCLabelWeight(i, j) * weight); mClusters[CL_all]->Fill(pt, GetMCLabelWeight(i, j) * weight); - if (protect || physics) { + if (r.protect || r.physics) { mClusters[CL_prot]->Fill(pt, GetMCLabelWeight(i, j) * weight); } - if (physics) { + if (r.physics) { mClusters[CL_physics]->Fill(pt, GetMCLabelWeight(i, j) * weight); } } @@ -1588,10 +1595,10 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx mClusters[CL_fakeAdj]->Fill(0.f, 1.f); mClusters[CL_all]->Fill(0.f, 1.f); mClusterCounts.nUnaccessible++; - if (protect || physics) { + if (r.protect || r.physics) { mClusters[CL_prot]->Fill(0.f, 1.f); } - if (physics) { + if (r.physics) { mClusters[CL_physics]->Fill(0.f, 1.f); } } @@ -1603,10 +1610,10 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx mClusters[CL_att_adj]->Fill(pt, 1.f); mClusters[CL_tracks]->Fill(pt, 1.f); mClusters[CL_all]->Fill(pt, 1.f); - if (protect || physics) { + if (r.protect || r.physics) { mClusters[CL_prot]->Fill(pt, 1.f); } - if (physics) { + if (r.physics) { mClusters[CL_physics]->Fill(pt, 1.f); } } @@ -1637,10 +1644,10 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx mClusters[CL_tracks]->Fill(pt, weight); } mClusters[CL_all]->Fill(pt, weight); - if (protect || physics) { + if (r.protect || r.physics) { mClusters[CL_prot]->Fill(pt, weight); } - if (physics) { + if (r.physics) { mClusters[CL_physics]->Fill(pt, weight); } } @@ -1654,10 +1661,10 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx } mClusters[CL_all]->Fill(0.f, 1.f); mClusterCounts.nUnaccessible++; - if (protect || physics) { + if (r.protect || r.physics) { mClusters[CL_prot]->Fill(0.f, 1.f); } - if (physics) { + if (r.physics) { mClusters[CL_physics]->Fill(0.f, 1.f); } } @@ -1770,62 +1777,75 @@ void GPUQA::RunQA(bool matchOnly, const std::vector* tracksEx uint32_t nCl = clNative ? clNative->nClustersTotal : mTracking->GetProcessors()->tpcMerger.NMaxClusters(); mClusterCounts.nTotal += nCl; if (mQATasks & taskClusterCounts) { - for (uint32_t i = 0; i < nCl; i++) { - int32_t attach = mTracking->mIOPtrs.mergedTrackHitAttachment[i]; - CHECK_CLUSTER_STATE(); + for (uint32_t iSector = 0; iSector < GPUCA_NSECTORS; iSector++) { + for (uint32_t iRow = 0; iRow < GPUCA_ROW_COUNT; iRow++) { + for (uint32_t iCl = 0; iCl < mTracking->mIOPtrs.clustersNative->nClusters[iSector][iRow]; iCl++) { + uint32_t i = mTracking->mIOPtrs.clustersNative->clusterOffset[iSector][iRow] + iCl; + int32_t attach = mTracking->mIOPtrs.mergedTrackHitAttachment[i]; + const auto& r = checkClusterState(attach, &mClusterCounts); - if (mcAvail) { - float totalWeight = 0, weight400 = 0, weight40 = 0; - for (int32_t j = 0; j < GetMCLabelNID(i); j++) { - const auto& label = GetMCLabel(i, j); - if (GetMCLabelID(label) >= 0) { - totalWeight += GetMCLabelWeight(label); - if (GetMCTrackObj(mMCParam, label).pt >= 0.4) { - weight400 += GetMCLabelWeight(label); - } - if (GetMCTrackObj(mMCParam, label).pt <= 0.04) { - weight40 += GetMCLabelWeight(label); + if (mcAvail) { + float totalWeight = 0, weight400 = 0, weight40 = 0; + for (int32_t j = 0; j < GetMCLabelNID(i); j++) { + const auto& label = GetMCLabel(i, j); + if (GetMCLabelID(label) >= 0) { + totalWeight += GetMCLabelWeight(label); + if (GetMCTrackObj(mMCParam, label).pt >= 0.4) { + weight400 += GetMCLabelWeight(label); + } + if (GetMCTrackObj(mMCParam, label).pt <= 0.04) { + weight40 += GetMCLabelWeight(label); + } + } } - } - } - if (totalWeight > 0 && 10.f * weight400 >= totalWeight) { - if (!unattached && !protect && !physics) { - mClusterCounts.nFakeRemove400++; - int32_t totalFake = weight400 < 0.9f * totalWeight; - if (totalFake) { - mClusterCounts.nFullFakeRemove400++; + if (totalWeight > 0 && 10.f * weight400 >= totalWeight) { + if (!r.unattached && !r.protect && !r.physics) { + mClusterCounts.nFakeRemove400++; + int32_t totalFake = weight400 < 0.9f * totalWeight; + if (totalFake) { + mClusterCounts.nFullFakeRemove400++; + } + /*printf("Fake removal (%d): Hit %7d, attached %d lowPt %d looper %d tube200 %d highIncl %d tube %d bad %d recPt %7.2f recLabel %6d", totalFake, i, (int32_t) (mClusterParam[i].attached || mClusterParam[i].fakeAttached), + (int32_t) lowPt, (int32_t) ((attach & gputpcgmmergertypes::attachGoodLeg) == 0), (int32_t) ((attach & gputpcgmmergertypes::attachTube) && mev200), + (int32_t) ((attach & gputpcgmmergertypes::attachHighIncl) != 0), (int32_t) ((attach & gputpcgmmergertypes::attachTube) != 0), (int32_t) ((attach & gputpcgmmergertypes::attachGood) == 0), + fabsf(qpt) > 0 ? 1.f / qpt : 0.f, id); + for (int32_t j = 0;j < GetMCLabelNID(i);j++) + { + //if (GetMCLabelID(i, j) < 0) break; + printf(" - label%d %6d weight %5d", j, GetMCLabelID(i, j), (int32_t) GetMCLabelWeight(i, j)); + if (GetMCLabelID(i, j) >= 0) printf(" - pt %7.2f", mMCParam[GetMCLabelID(i, j)].pt); + else printf(" "); + } + printf("\n");*/ + } + mClusterCounts.nAbove400++; } - /*printf("Fake removal (%d): Hit %7d, attached %d lowPt %d looper %d tube200 %d highIncl %d tube %d bad %d recPt %7.2f recLabel %6d", totalFake, i, (int32_t) (mClusterParam[i].attached || mClusterParam[i].fakeAttached), - (int32_t) lowPt, (int32_t) ((attach & gputpcgmmergertypes::attachGoodLeg) == 0), (int32_t) ((attach & gputpcgmmergertypes::attachTube) && mev200), - (int32_t) ((attach & gputpcgmmergertypes::attachHighIncl) != 0), (int32_t) ((attach & gputpcgmmergertypes::attachTube) != 0), (int32_t) ((attach & gputpcgmmergertypes::attachGood) == 0), - fabsf(qpt) > 0 ? 1.f / qpt : 0.f, id); - for (int32_t j = 0;j < GetMCLabelNID(i);j++) - { - //if (GetMCLabelID(i, j) < 0) break; - printf(" - label%d %6d weight %5d", j, GetMCLabelID(i, j), (int32_t) GetMCLabelWeight(i, j)); - if (GetMCLabelID(i, j) >= 0) printf(" - pt %7.2f", mMCParam[GetMCLabelID(i, j)].pt); - else printf(" "); + if (totalWeight > 0 && weight40 >= 0.9 * totalWeight) { + mClusterCounts.nBelow40++; + if (r.protect || r.physics) { + mClusterCounts.nFakeProtect40++; + } } - printf("\n");*/ } - mClusterCounts.nAbove400++; - } - if (totalWeight > 0 && weight40 >= 0.9 * totalWeight) { - mClusterCounts.nBelow40++; - if (protect || physics) { - mClusterCounts.nFakeProtect40++; + + if (r.physics) { + mClusterCounts.nPhysics++; + } + if (r.protect) { + mClusterCounts.nProt++; + } + if (r.unattached) { + mClusterCounts.nUnattached++; + } + if (mTracking && mTracking->mIOPtrs.clustersNative) { + const auto& cl = mTracking->mIOPtrs.clustersNative->clustersLinear[i]; + mClRej[0]->Fill(cl.getPad() - GPUTPCGeometry::NPads(iRow) / 2 + 0.5, iRow, 1.f); + if (!r.unattached && !r.protect) { + mClRej[1]->Fill(cl.getPad() - GPUTPCGeometry::NPads(iRow) / 2 + 0.5, iRow, 1.f); + } } } } - if (physics) { - mClusterCounts.nPhysics++; - } - if (physics || protect) { - mClusterCounts.nProt++; - } - if (unattached) { - mClusterCounts.nUnattached++; - } } } @@ -2213,6 +2233,18 @@ int32_t GPUQA::DrawQAHistograms(TObjArray* qcout) mCClXY->cd(); mPClXY = createGarbageCollected("p0", "", 0.0, 0.0, 1.0, 1.0); mPClXY->Draw(); + + for (int32_t i = 0; i < 3; i++) { + snprintf(name, 2048, "cnclrej%d", i); + mCClRej[i] = createGarbageCollected(name, i == 0 ? "Number of clusters" : (i == 1 ? "Rejected Clusters" : "Fraction of Rejected Clusters"), 0, 0, 700, 700. * 2. / 3.); + mCClRej[i]->cd(); + mPClRej[i] = createGarbageCollected("p0", "", 0.0, 0.0, 1.0, 1.0); + mPClRej[i]->Draw(); + } + mCClRejP = createGarbageCollected("cnclrejp", "Fraction of Rejected Clusters", 0, 0, 700, 700. * 2. / 3.); + mCClRejP->cd(); + mPClRejP = createGarbageCollected("p0", "", 0.0, 0.0, 1.0, 1.0); + mPClRejP->Draw(); } } @@ -2243,7 +2275,7 @@ int32_t GPUQA::DrawQAHistograms(TObjArray* qcout) // Divide eff, compute all for fake/clone auto oldLevel = gErrorIgnoreLevel; gErrorIgnoreLevel = kError; - mEffResult[0][j / 2][j % 2][i]->Divide(mEff[l][j / 2][j % 2][i], mEff[3][j / 2][j % 2][i], "cl=0.683 b(1,1) mode"); + mEffResult[0][j / 2][j % 2][i]->Divide(mEff[l][j / 2][j % 2][i], mEff[5][j / 2][j % 2][i], "cl=0.683 b(1,1) mode"); gErrorIgnoreLevel = oldLevel; mEff[3][j / 2][j % 2][i]->Reset(); // Sum up rec + clone + fake for fake rate mEff[3][j / 2][j % 2][i]->Add(mEff[0][j / 2][j % 2][i]); @@ -2953,6 +2985,62 @@ int32_t GPUQA::DrawQAHistograms(TObjArray* qcout) if (mConfig.writeRootFiles) { mCClXY->Print("plots/clustersXY.root"); } + + if (mQATasks & taskClusterCounts) { + mClRej[2]->Divide(mClRej[1], mClRej[0]); + + for (int32_t i = 0; i < 3; i++) { + if (tout && !mConfig.inputHistogramsOnly) { + mClRej[i]->Write(); + } + mPClRej[i]->cd(); + mClRej[i]->SetOption("colz"); + mClRej[i]->Draw(); + mCClRej[i]->cd(); + snprintf(name, 2048, "plots/clustersRej%d.pdf", i); + mCClRej[i]->Print(name); + if (mConfig.writeRootFiles) { + snprintf(name, 2048, "plots/clustersRej%d.root", i); + mCClRej[i]->Print(name); + } + } + + mPClRejP->cd(); + for (int32_t k = 0; k < ConfigNumInputs; k++) { + auto* tmp = mClRej[0]; + if (GetHist(tmp, tin, k, nNewInput) == nullptr) { + continue; + } + snprintf(name, 2048, "clrejptmp1%d", k); // TODO: Clean up names, and how names are written to char arrays + TH1D* proj1 = tmp->ProjectionY(name); + proj1->SetDirectory(nullptr); + tmp = mClRej[1]; + if (GetHist(tmp, tin, k, nNewInput) == nullptr) { + continue; + } + snprintf(name, 2048, "clrejptmp2%d", k); // TODO: Clean up names, and how names are written to char arrays + TH1D* proj2 = tmp->ProjectionY(name); + proj2->SetDirectory(nullptr); + + auto* e = mClRejP; + if (GetHist(e, tin, k, nNewInput) == nullptr) { + continue; + } + e->Divide(proj2, proj1); + if (tout && !mConfig.inputHistogramsOnly && k == 0) { + e->Write(); + } + delete proj1; + delete proj2; + e->SetMinimum(-0.02); + e->SetMaximum(0.22); + e->Draw(k == 0 ? "" : "same"); + } + mPClRejP->Print("plots/clustersRejP.pdf"); // TODO: Add option to write pngs + if (mConfig.writeRootFiles) { + mPClRejP->Print("plots/clustersRejP.root"); + } + } } if (tout && !mConfig.inputHistogramsOnly && mConfig.writeMCLabels) { @@ -3010,7 +3098,7 @@ int32_t GPUQA::DoClusterCounts(uint64_t* attachClusterCounts, int32_t mode) { int32_t num = 0; if (mcPresent() && (mQATasks & taskClusterAttach) && attachClusterCounts) { - for (int32_t i = 0; i < N_CLS_HIST; i++) { + for (int32_t i = 0; i < N_CLS_HIST; i++) { // TODO: Check that these counts are still printed correctly! PrintClusterCount(mode, num, CLUSTER_NAMES[i], attachClusterCounts[i], mClusterCounts.nTotal); } PrintClusterCount(mode, num, "Unattached", attachClusterCounts[N_CLS_HIST - 1] - attachClusterCounts[CL_att_adj], mClusterCounts.nTotal); diff --git a/GPU/GPUTracking/qa/GPUQA.h b/GPU/GPUTracking/qa/GPUQA.h index fcfe1aea8b04f..dfa644a67e9e0 100644 --- a/GPU/GPUTracking/qa/GPUQA.h +++ b/GPU/GPUTracking/qa/GPUQA.h @@ -86,6 +86,7 @@ namespace o2::gpu class GPUChainTracking; struct GPUParam; struct GPUTPCMCInfo; +struct checkClusterStateResult; namespace internal { struct GPUQAGarbageCollection; @@ -230,6 +231,9 @@ class GPUQA const auto& GetClusterLabels(); bool mcPresent(); + template + checkClusterStateResult checkClusterState(uint32_t attach, T* counts = nullptr) const; + GPUChainTracking* mTracking; const GPUSettingsQA& mConfig; const GPUParam* mParam; @@ -256,7 +260,7 @@ class GPUQA std::vector mClusterParam; int32_t mNTotalFakes = 0; - TH1F* mEff[5][2][2][5]; // eff,clone,fake,all,all-fake - findable - secondaries - y,z,phi,eta,pt - work,result + TH1F* mEff[6][2][2][5]; // eff,clone,fake,all,all-fake - findable - secondaries - y,z,phi,eta,pt - work,result TGraphAsymmErrors* mEffResult[4][2][2][5]; TCanvas* mCEff[6]; TPad* mPEff[6][4]; @@ -312,6 +316,13 @@ class GPUQA TCanvas* mCClXY; TPad* mPClXY; + TH2F* mClRej[3]; + TH1D* mClRejP; + TCanvas* mCClRej[3]; + TCanvas* mCClRejP; + TPad* mPClRej[3]; + TPad* mPClRejP; + std::vector mHistClusterCount; std::vector* mHist1D = nullptr;