From 74e1dbe96cb7bb6570f3c09ae70fa12e6c43ff1e Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 10 Nov 2020 11:40:46 +0100 Subject: [PATCH 1/6] GPU: Some cleanup in TPC QA --- .../Standalone/display/GPUDisplayKeys.cxx | 23 +++-- GPU/GPUTracking/Standalone/qa/GPUQA.cxx | 91 ++++++++++++++++--- GPU/GPUTracking/Standalone/qa/GPUQA.h | 62 +------------ 3 files changed, 90 insertions(+), 86 deletions(-) diff --git a/GPU/GPUTracking/Standalone/display/GPUDisplayKeys.cxx b/GPU/GPUTracking/Standalone/display/GPUDisplayKeys.cxx index e7c85ef06826e..6d453b0af8e69 100644 --- a/GPU/GPUTracking/Standalone/display/GPUDisplayKeys.cxx +++ b/GPU/GPUTracking/Standalone/display/GPUDisplayKeys.cxx @@ -35,7 +35,6 @@ const char* HelpText[] = { "[L] / [K] Draw single collisions (next / previous)", "[C] Colorcode clusters of different collisions", "[v] Hide rejected clusters from tracks", - "[b] Hide all clusters not belonging or related to matched tracks in QA", "[j] Show global tracks as additional segments of final tracks", "[u] Cycle through track filter", "[E] / [G] Extrapolate tracks / loopers", @@ -59,7 +58,8 @@ const char* HelpText[] = { "[ALT] / [CTRL] / [m] Focus camera on origin / orient y-axis upwards (combine with [SHIFT] to lock) / Cycle through modes", "[1] ... [8] / [N] Enable display of clusters, preseeds, seeds, starthits, tracklets, tracks, global tracks, merged tracks / Show assigned clusters in colors" "[F1] / [F2] Enable / disable drawing of TPC / TRD" - // FREE: u + // FREE: b + // Test setting: # --> mHideUnmatchedClusters }; void GPUDisplay::PrintHelp() @@ -218,10 +218,6 @@ void GPUDisplay::HandleKeyRelease(unsigned char key) mHideRejectedClusters ^= 1; SetInfo("Rejected clusters are %s", mHideRejectedClusters ? "hidden" : "shown"); mUpdateDLList = true; - } else if (key == 'b') { - mHideUnmatchedClusters ^= 1; - SetInfo("Unmatched clusters are %s", mHideUnmatchedClusters ? "hidden" : "shown"); - mUpdateDLList = true; } else if (key == 'i') { mProjectXY ^= 1; SetInfo("Projection onto xy plane %s", mProjectXY ? "enabled" : "disabled"); @@ -429,12 +425,15 @@ void GPUDisplay::HandleKeyRelease(unsigned char key) PrintHelp(); SetInfo("Showing help text", 1); } - /*else if (key == '#') - { - mTestSetting++; - SetInfo("Debug test variable set to %d", mTestSetting); - mUpdateDLList = true; - }*/ + /* + else if (key == '#') + { + mTestSetting++; + SetInfo("Debug test variable set to %d", mTestSetting); + // mHideUnmatchedClusters ^= 1; + mUpdateDLList = true; + } + */ } void GPUDisplay::HandleSendKey(int key) diff --git a/GPU/GPUTracking/Standalone/qa/GPUQA.cxx b/GPU/GPUTracking/Standalone/qa/GPUQA.cxx index 0aa569f33cb3c..887998f196f28 100644 --- a/GPU/GPUTracking/Standalone/qa/GPUQA.cxx +++ b/GPU/GPUTracking/Standalone/qa/GPUQA.cxx @@ -134,6 +134,63 @@ static const GPUSettingsQA& GPUQA_GetConfig(GPUChainTracking* rec) #endif } +static const constexpr bool PLOT_ROOT = 0; +static const constexpr bool FIX_SCALES = 0; +static const constexpr bool PERF_FIGURE = 0; +static const constexpr float FIXED_SCALES_MIN[5] = {-0.05, -0.05, -0.2, -0.2, -0.5}; +static const constexpr float FIXED_SCALES_MAX[5] = {0.4, 0.7, 5, 3, 6.5}; +static const constexpr float LOG_PT_MIN = -1.; + +static constexpr float Y_MAX = 40; +static constexpr float Z_MAX = 100; +static constexpr float PT_MIN = GPUCA_MIN_TRACK_PT_DEFAULT; +static constexpr float PT_MIN2 = 0.1; +static constexpr float PT_MIN_PRIM = 0.1; +static constexpr float PT_MIN_CLUST = GPUCA_MIN_TRACK_PT_DEFAULT; +static constexpr float PT_MAX = 20; +static constexpr float ETA_MAX = 1.5; +static constexpr float ETA_MAX2 = 0.9; + +static constexpr float MIN_WEIGHT_CLS = 40; +static constexpr float FINDABLE_WEIGHT_CLS = 70; + +static constexpr int MC_LABEL_INVALID = -1e9; + +static constexpr bool CLUST_HIST_INT_SUM = false; + +static constexpr const int COLORCOUNT = 12; + +static const constexpr char* EFF_TYPES[4] = {"Rec", "Clone", "Fake", "All"}; +static const constexpr char* FINDABLE_NAMES[2] = {"", "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}"}; +static const constexpr char* PARAMETER_NAMES_NATIVE[5] = {"Y", "Z", "sin(#Phi)", "tan(#lambda)", "q/#it{p}_{T} (curvature)"}; +static const constexpr char* VSPARAMETER_NAMES[6] = {"Y", "Z", "Phi", "Eta", "Pt", "Pt_log"}; +static const constexpr char* EFF_NAMES[3] = {"Efficiency", "Clone Rate", "Fake Rate"}; +static const constexpr char* EFFICIENCY_TITLES[4] = {"Efficiency (Primary Tracks, Findable)", "Efficiency (Secondary Tracks, Findable)", "Efficiency (Primary Tracks)", "Efficiency (Secondary Tracks)"}; +static const constexpr double SCALE[5] = {10., 10., 1000., 1000., 100.}; +static const constexpr double SCALE_NATIVE[5] = {10., 10., 1000., 1000., 1.}; +static const constexpr char* XAXIS_TITLES[5] = {"#it{y}_{mc} (cm)", "#it{z}_{mc} (cm)", "#Phi_{mc} (rad)", "#eta_{mc}", "#it{p}_{Tmc} (GeV/#it{c})"}; +static const constexpr char* AXIS_TITLES[5] = {"#it{y}-#it{y}_{mc} (mm) (Resolution)", "#it{z}-#it{z}_{mc} (mm) (Resolution)", "#phi-#phi_{mc} (mrad) (Resolution)", "#lambda-#lambda_{mc} (mrad) (Resolution)", "(#it{p}_{T} - #it{p}_{Tmc}) / #it{p}_{Tmc} (%) (Resolution)"}; +static const constexpr char* AXIS_TITLES_NATIVE[5] = {"#it{y}-#it{y}_{mc} (mm) (Resolution)", "#it{z}-#it{z}_{mc} (mm) (Resolution)", "sin(#phi)-sin(#phi_{mc}) (Resolution)", "tan(#lambda)-tan(#lambda_{mc}) (Resolution)", "q*(q/#it{p}_{T} - q/#it{p}_{Tmc}) (Resolution)"}; +static const constexpr char* AXIS_TITLES_PULL[5] = {"#it{y}-#it{y}_{mc}/#sigma_{y} (Pull)", "#it{z}-#it{z}_{mc}/#sigma_{z} (Pull)", "sin(#phi)-sin(#phi_{mc})/#sigma_{sin(#phi)} (Pull)", "tan(#lambda)-tan(#lambda_{mc})/#sigma_{tan(#lambda)} (Pull)", + "q*(q/#it{p}_{T} - q/#it{p}_{Tmc})/#sigma_{q/#it{p}_{T}} (Pull)"}; +static const constexpr char* CLUSTER_NAMES[GPUQA::N_CLS_HIST] = {"Correctly attached clusters", "Fake attached clusters", "Attached + adjacent clusters", "Fake adjacent clusters", "Clusters of reconstructed tracks", "Used in Physics", "Protected", "All clusters"}; +static const constexpr char* CLUSTER_TITLES[GPUQA::N_CLS_TYPE] = {"Clusters Pt Distribution / Attachment", "Clusters Pt Distribution / Attachment (relative to all clusters)", "Clusters Pt Distribution / Attachment (integrated)"}; +static const constexpr char* CLUSTER_NAMES_SHORT[GPUQA::N_CLS_HIST] = {"Attached", "Fake", "AttachAdjacent", "FakeAdjacent", "FoundTracks", "Physics", "Protected", "All"}; +static const constexpr char* CLUSTER_TYPES[GPUQA::N_CLS_TYPE] = {"", "Ratio", "Integral"}; +static const constexpr int COLORS_HEX[COLORCOUNT] = {0xB03030, 0x00A000, 0x0000C0, 0x9400D3, 0x19BBBF, 0xF25900, 0x7F7F7F, 0xFFD700, 0x07F707, 0x07F7F7, 0xF08080, 0x000000}; + +static const constexpr int CONFIG_DASHED_MARKERS = 0; + +static const constexpr float AXES_MIN[5] = {-Y_MAX, -Z_MAX, 0.f, -ETA_MAX, PT_MIN}; +static const constexpr float AXES_MAX[5] = {Y_MAX, Z_MAX, 2.f * M_PI, ETA_MAX, PT_MAX}; +static const constexpr int AXIS_BINS[5] = {51, 51, 144, 31, 50}; +static const constexpr int RES_AXIS_BINS[] = {1017, 113}; // Consecutive bin sizes, histograms are binned down until the maximum entry is 50, each bin size should evenly divide its predecessor. +static const constexpr float RES_AXES[5] = {1., 1., 0.03, 0.03, 1.0}; +static const constexpr float RES_AXES_NATIVE[5] = {1., 1., 0.1, 0.1, 5.0}; +static const constexpr float PULL_AXIS = 10.f; + #ifdef GPUCA_TPC_GEOMETRY_O2 #include "SimulationDataFormat/MCCompLabel.h" #include "SimulationDataFormat/ConstMCTruthContainer.h" @@ -654,6 +711,11 @@ void GPUQA::RunQA(bool matchOnly) if (ompError) { return; } + if (QA_TIMING) { + GPUInfo("QA Time: Assign Track Labels:\t\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6); + } + + // fill cluster attachment status for (unsigned int i = 0; i < mTracking->mIOPtrs.nMergedTracks; i++) { const GPUTPCGMMergedTrack& track = mTracking->mIOPtrs.mergedTracks[i]; if (!track.OK()) { @@ -701,6 +763,7 @@ void GPUQA::RunQA(bool matchOnly) } } } + // fill cluster adjacent status for (unsigned int i = 0; i < GetNMCLabels(); i++) { if (mClusterParam[i].attached == 0 && mClusterParam[i].fakeAttached == 0) { int attach = mTracking->mIOPtrs.mergedTrackHitAttachment[i]; @@ -763,16 +826,14 @@ void GPUQA::RunQA(bool matchOnly) } } } + if (QA_TIMING) { + GPUInfo("QA Time: Cluster attach status:\t\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6); + } if (matchOnly) { return; } - if (QA_TIMING) { - GPUInfo("QA Time: Assign Track Labels:\t\t%6.0f us", timer.GetCurrentElapsedTime() * 1e6); - } - timer.ResetStart(); - // Recompute fNWeightCls (might have changed after merging events into timeframes) for (unsigned int iCol = 0; iCol < GetNMCCollissions(); iCol++) { for (unsigned int i = 0; i < GetNMCTracks(iCol); i++) { @@ -793,10 +854,10 @@ void GPUQA::RunQA(bool matchOnly) } } if (QA_TIMING) { - GPUInfo("QA Time: Compute cluster label weights:\t%6.0f us", timer.GetCurrentElapsedTime() * 1e6); + GPUInfo("QA Time: Compute cluster label weights:\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6); } - timer.ResetStart(); + // Compute MC Track Parameters for MC Tracks GPUCA_OPENMP(parallel for) for (unsigned int iCol = 0; iCol < GetNMCCollissions(); iCol++) { for (unsigned int i = 0; i < GetNMCTracks(iCol); i++) { @@ -817,7 +878,10 @@ void GPUQA::RunQA(bool matchOnly) } } } - // Compute MC Track Parameters for MC Tracks + if (QA_TIMING) { + GPUInfo("QA Time: Compute track mc parameters:\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6); + } + // Fill Efficiency Histograms for (unsigned int iCol = 0; iCol < GetNMCCollissions(); iCol++) { for (unsigned int i = 0; i < GetNMCTracks(iCol); i++) { @@ -895,9 +959,8 @@ void GPUQA::RunQA(bool matchOnly) } } if (QA_TIMING) { - GPUInfo("QA Time: Fill efficiency histograms:\t%6.0f us", timer.GetCurrentElapsedTime() * 1e6); + GPUInfo("QA Time: Fill efficiency histograms:\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6); } - timer.ResetStart(); // Fill Resolution Histograms GPUTPCGMPropagator prop; @@ -1030,9 +1093,8 @@ void GPUQA::RunQA(bool matchOnly) } } if (QA_TIMING) { - GPUInfo("QA Time: Fill resolution histograms:\t%6.0f us", timer.GetCurrentElapsedTime() * 1e6); + GPUInfo("QA Time: Fill resolution histograms:\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6); } - timer.ResetStart(); // Fill cluster histograms for (unsigned int iTrk = 0; iTrk < mTracking->mIOPtrs.nMergedTracks; iTrk++) { @@ -1256,9 +1318,8 @@ void GPUQA::RunQA(bool matchOnly) } if (QA_TIMING) { - GPUInfo("QA Time: Fill cluster histograms:\t%6.0f us", timer.GetCurrentElapsedTime() * 1e6); + GPUInfo("QA Time: Fill cluster histograms:\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6); } - timer.ResetStart(); } else if (!mConfig.inputHistogramsOnly) { GPUWarning("No MC information available, only running partial TPC QA!"); } @@ -1335,7 +1396,7 @@ void GPUQA::RunQA(bool matchOnly) } if (QA_TIMING) { - GPUInfo("QA Time: Others:\t%6.0f us", timer.GetCurrentElapsedTime() * 1e6); + GPUInfo("QA Time: Others:\t%6.0f us", timer.GetCurrentElapsedTime(true) * 1e6); } // Create CSV DumpTrackHits diff --git a/GPU/GPUTracking/Standalone/qa/GPUQA.h b/GPU/GPUTracking/Standalone/qa/GPUQA.h index df2e8b0e4a6eb..99cf7f074e260 100644 --- a/GPU/GPUTracking/Standalone/qa/GPUQA.h +++ b/GPU/GPUTracking/Standalone/qa/GPUQA.h @@ -95,6 +95,9 @@ class GPUQA static bool QAAvailable() { return true; } bool IsInitialized() { return mQAInitialized; } + static constexpr int N_CLS_HIST = 8; + static constexpr int N_CLS_TYPE = 3; + private: struct additionalMCParameters { float pt, phi, theta, eta, nWeightCls; @@ -170,14 +173,6 @@ class GPUQA GPUChainTracking* mTracking; const GPUSettingsQA& mConfig; - //-------------------------: Some compile time settings.... - static const constexpr bool PLOT_ROOT = 0; - static const constexpr bool FIX_SCALES = 0; - static const constexpr bool PERF_FIGURE = 0; - static const constexpr float FIXED_SCALES_MIN[5] = {-0.05, -0.05, -0.2, -0.2, -0.5}; - static const constexpr float FIXED_SCALES_MAX[5] = {0.4, 0.7, 5, 3, 6.5}; - static const constexpr float LOG_PT_MIN = -1.; - const char* str_perf_figure_1 = "ALICE Performance 2018/03/20"; // const char* str_perf_figure_2 = "2015, MC pp, #sqrt{s} = 5.02 TeV"; const char* str_perf_figure_2 = "2015, MC Pb-Pb, #sqrt{s_{NN}} = 5.02 TeV"; @@ -217,8 +212,6 @@ class GPUQA TPad* mPPull[7][5]; TLegend* mLPull[6]; - static constexpr int N_CLS_HIST = 8; - static constexpr int N_CLS_TYPE = 3; enum CL_types { CL_attached = 0, CL_fake = 1, CL_att_adj = 2, @@ -254,57 +247,8 @@ class GPUQA std::vector> mGoodTracks; std::vector> mGoodHits; - static constexpr float Y_MAX = 40; - static constexpr float Z_MAX = 100; - static constexpr float PT_MIN = GPUCA_MIN_TRACK_PT_DEFAULT; - static constexpr float PT_MIN2 = 0.1; - static constexpr float PT_MIN_PRIM = 0.1; - static constexpr float PT_MIN_CLUST = GPUCA_MIN_TRACK_PT_DEFAULT; - static constexpr float PT_MAX = 20; - static constexpr float ETA_MAX = 1.5; - static constexpr float ETA_MAX2 = 0.9; - - static constexpr float MIN_WEIGHT_CLS = 40; - static constexpr float FINDABLE_WEIGHT_CLS = 70; - - static constexpr int MC_LABEL_INVALID = -1e9; - - static constexpr bool CLUST_HIST_INT_SUM = false; - - static constexpr const int COLORCOUNT = 12; Color_t* mColorNums; - static const constexpr char* EFF_TYPES[4] = {"Rec", "Clone", "Fake", "All"}; - static const constexpr char* FINDABLE_NAMES[2] = {"", "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}"}; - static const constexpr char* PARAMETER_NAMES_NATIVE[5] = {"Y", "Z", "sin(#Phi)", "tan(#lambda)", "q/#it{p}_{T} (curvature)"}; - static const constexpr char* VSPARAMETER_NAMES[6] = {"Y", "Z", "Phi", "Eta", "Pt", "Pt_log"}; - static const constexpr char* EFF_NAMES[3] = {"Efficiency", "Clone Rate", "Fake Rate"}; - static const constexpr char* EFFICIENCY_TITLES[4] = {"Efficiency (Primary Tracks, Findable)", "Efficiency (Secondary Tracks, Findable)", "Efficiency (Primary Tracks)", "Efficiency (Secondary Tracks)"}; - static const constexpr double SCALE[5] = {10., 10., 1000., 1000., 100.}; - static const constexpr double SCALE_NATIVE[5] = {10., 10., 1000., 1000., 1.}; - static const constexpr char* XAXIS_TITLES[5] = {"#it{y}_{mc} (cm)", "#it{z}_{mc} (cm)", "#Phi_{mc} (rad)", "#eta_{mc}", "#it{p}_{Tmc} (GeV/#it{c})"}; - static const constexpr char* AXIS_TITLES[5] = {"#it{y}-#it{y}_{mc} (mm) (Resolution)", "#it{z}-#it{z}_{mc} (mm) (Resolution)", "#phi-#phi_{mc} (mrad) (Resolution)", "#lambda-#lambda_{mc} (mrad) (Resolution)", "(#it{p}_{T} - #it{p}_{Tmc}) / #it{p}_{Tmc} (%) (Resolution)"}; - static const constexpr char* AXIS_TITLES_NATIVE[5] = {"#it{y}-#it{y}_{mc} (mm) (Resolution)", "#it{z}-#it{z}_{mc} (mm) (Resolution)", "sin(#phi)-sin(#phi_{mc}) (Resolution)", "tan(#lambda)-tan(#lambda_{mc}) (Resolution)", "q*(q/#it{p}_{T} - q/#it{p}_{Tmc}) (Resolution)"}; - static const constexpr char* AXIS_TITLES_PULL[5] = {"#it{y}-#it{y}_{mc}/#sigma_{y} (Pull)", "#it{z}-#it{z}_{mc}/#sigma_{z} (Pull)", "sin(#phi)-sin(#phi_{mc})/#sigma_{sin(#phi)} (Pull)", "tan(#lambda)-tan(#lambda_{mc})/#sigma_{tan(#lambda)} (Pull)", - "q*(q/#it{p}_{T} - q/#it{p}_{Tmc})/#sigma_{q/#it{p}_{T}} (Pull)"}; - static const constexpr char* CLUSTER_NAMES[N_CLS_HIST] = {"Correctly attached clusters", "Fake attached clusters", "Attached + adjacent clusters", "Fake adjacent clusters", "Clusters of reconstructed tracks", "Used in Physics", "Protected", "All clusters"}; - static const constexpr char* CLUSTER_TITLES[N_CLS_TYPE] = {"Clusters Pt Distribution / Attachment", "Clusters Pt Distribution / Attachment (relative to all clusters)", "Clusters Pt Distribution / Attachment (integrated)"}; - static const constexpr char* CLUSTER_NAMES_SHORT[N_CLS_HIST] = {"Attached", "Fake", "AttachAdjacent", "FakeAdjacent", "FoundTracks", "Physics", "Protected", "All"}; - static const constexpr char* CLUSTER_TYPES[N_CLS_TYPE] = {"", "Ratio", "Integral"}; - static const constexpr int COLORS_HEX[COLORCOUNT] = {0xB03030, 0x00A000, 0x0000C0, 0x9400D3, 0x19BBBF, 0xF25900, 0x7F7F7F, 0xFFD700, 0x07F707, 0x07F7F7, 0xF08080, 0x000000}; - - static const constexpr int CONFIG_DASHED_MARKERS = 0; - - static const constexpr float AXES_MIN[5] = {-Y_MAX, -Z_MAX, 0.f, -ETA_MAX, PT_MIN}; - static const constexpr float AXES_MAX[5] = {Y_MAX, Z_MAX, 2.f * M_PI, ETA_MAX, PT_MAX}; - static const constexpr int AXIS_BINS[5] = {51, 51, 144, 31, 50}; - static const constexpr int RES_AXIS_BINS[] = {1017, 113}; // Consecutive bin sizes, histograms are binned down until the maximum entry is 50, each bin size should evenly divide its predecessor. - static const constexpr float RES_AXES[5] = {1., 1., 0.03, 0.03, 1.0}; - static const constexpr float RES_AXES_NATIVE[5] = {1., 1., 0.1, 0.1, 5.0}; - static const constexpr float PULL_AXIS = 10.f; - int mMCTrackMin = -1, mMCTrackMax = -1; }; From 112823b1f345c59464241b4f45f6d525fa22d62f Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 10 Nov 2020 15:16:35 +0100 Subject: [PATCH 2/6] GPU: Move TPC Standalone QA histograms into an std::vector to enable simple shipping of histograms --- GPU/GPUTracking/Standalone/qa/GPUQA.cxx | 134 +++++++++++++++--------- GPU/GPUTracking/Standalone/qa/GPUQA.h | 23 +++- 2 files changed, 109 insertions(+), 48 deletions(-) diff --git a/GPU/GPUTracking/Standalone/qa/GPUQA.cxx b/GPU/GPUTracking/Standalone/qa/GPUQA.cxx index 887998f196f28..f24b97bd6db90 100644 --- a/GPU/GPUTracking/Standalone/qa/GPUQA.cxx +++ b/GPU/GPUTracking/Standalone/qa/GPUQA.cxx @@ -154,8 +154,6 @@ static constexpr float ETA_MAX2 = 0.9; static constexpr float MIN_WEIGHT_CLS = 40; static constexpr float FINDABLE_WEIGHT_CLS = 70; -static constexpr int MC_LABEL_INVALID = -1e9; - static constexpr bool CLUST_HIST_INT_SUM = false; static constexpr const int COLORCOUNT = 12; @@ -249,7 +247,36 @@ inline auto& GPUQA::GetMCTrackObj(T& obj, const GPUQA::mcLabelI_t& l) return obj[l.getEventID()][l.getTrackID()]; } -GPUQA::GPUQA(GPUChainTracking* rec) : mTracking(rec), mConfig(GPUQA_GetConfig(rec)) {} +template <> +auto GPUQA::getHist() +{ + return std::make_pair(&mHist1D, &mHist1D_pos); +} +template <> +auto GPUQA::getHist() +{ + return std::make_pair(&mHist2D, &mHist2D_pos); +} +template <> +auto GPUQA::getHist() +{ + return std::make_pair(&mHist1Dd, &mHist1Dd_pos); +} +template +void GPUQA::createHist(T*& h, Args... args) +{ + const auto& p = getHist(); + p.first->get()->emplace_back(args...); + p.second->emplace_back(&h); + h = &p.first->get()->back(); +} + +GPUQA::GPUQA(GPUChainTracking* rec) : mTracking(rec), mConfig(GPUQA_GetConfig(rec)) +{ + mHist1D.reset(new std::vector); + mHist2D.reset(new std::vector); + mHist1Dd.reset(new std::vector); +} GPUQA::~GPUQA() = default; @@ -338,22 +365,9 @@ void GPUQA::SetMCTrackRange(int min, int max) int GPUQA::GetMCTrackLabel(unsigned int trackId) const { return (trackId >= mTrackMCLabels.size() ? MC_LABEL_INVALID : mTrackMCLabels[trackId].getTrackID()); } -int GPUQA::InitQA() +int GPUQA::InitQACreateHistograms() { - if (mQAInitialized) { - return 1; - } char name[2048], fname[1024]; - - mColorNums = new Color_t[COLORCOUNT]; - for (int i = 0; i < COLORCOUNT; i++) { - float f1 = (float)((COLORS_HEX[i] >> 16) & 0xFF) / (float)0xFF; - float f2 = (float)((COLORS_HEX[i] >> 8) & 0xFF) / (float)0xFF; - float f3 = (float)((COLORS_HEX[i] >> 0) & 0xFF) / (float)0xFF; - TColor* c = new TColor(10000 + i, f1, f2, f3); - mColorNums[i] = c->GetNumber(); - } - // Create Efficiency Histograms for (int i = 0; i < 4; i++) { for (int j = 0; j < 2; j++) { @@ -362,11 +376,10 @@ int GPUQA::InitQA() for (int m = 0; m < 2; m++) { sprintf(name, "%s%s%s%sVs%s", m ? "eff" : "tracks", EFF_TYPES[i], FINDABLE_NAMES[j], PRIM_NAMES[k], VSPARAMETER_NAMES[l]); if (l == 4) { - double* binsPt = CreateLogAxis(AXIS_BINS[4], k == 0 ? PT_MIN_PRIM : AXES_MIN[4], AXES_MAX[4]); - mEff[i][j][k][l][m] = new TH1F(name, name, AXIS_BINS[l], binsPt); - delete[] binsPt; + std::unique_ptr binsPt{CreateLogAxis(AXIS_BINS[4], k == 0 ? PT_MIN_PRIM : AXES_MIN[4], AXES_MAX[4])}; + createHist(mEff[i][j][k][l][m], name, name, AXIS_BINS[l], binsPt.get()); } else { - mEff[i][j][k][l][m] = new TH1F(name, name, AXIS_BINS[l], AXES_MIN[l], AXES_MAX[l]); + createHist(mEff[i][j][k][l][m], name, name, AXIS_BINS[l], AXES_MIN[l], AXES_MAX[l]); } mEff[i][j][k][l][m]->Sumw2(); } @@ -381,23 +394,21 @@ int GPUQA::InitQA() sprintf(name, "rms_%s_vs_%s", VSPARAMETER_NAMES[i], VSPARAMETER_NAMES[j]); sprintf(fname, "mean_%s_vs_%s", VSPARAMETER_NAMES[i], VSPARAMETER_NAMES[j]); if (j == 4) { - double* binsPt = CreateLogAxis(AXIS_BINS[4], mConfig.resPrimaries == 1 ? PT_MIN_PRIM : AXES_MIN[4], AXES_MAX[4]); - mRes[i][j][0] = new TH1F(name, name, AXIS_BINS[j], binsPt); - mRes[i][j][1] = new TH1F(fname, fname, AXIS_BINS[j], binsPt); - delete[] binsPt; + std::unique_ptr binsPt{CreateLogAxis(AXIS_BINS[4], mConfig.resPrimaries == 1 ? PT_MIN_PRIM : AXES_MIN[4], AXES_MAX[4])}; + createHist(mRes[i][j][0], name, name, AXIS_BINS[j], binsPt.get()); + createHist(mRes[i][j][1], fname, fname, AXIS_BINS[j], binsPt.get()); } else { - mRes[i][j][0] = new TH1F(name, name, AXIS_BINS[j], AXES_MIN[j], AXES_MAX[j]); - mRes[i][j][1] = new TH1F(fname, fname, AXIS_BINS[j], AXES_MIN[j], AXES_MAX[j]); + createHist(mRes[i][j][0], name, name, AXIS_BINS[j], AXES_MIN[j], AXES_MAX[j]); + createHist(mRes[i][j][1], fname, fname, AXIS_BINS[j], AXES_MIN[j], AXES_MAX[j]); } sprintf(name, "res_%s_vs_%s", VSPARAMETER_NAMES[i], VSPARAMETER_NAMES[j]); const float* axis = mConfig.nativeFitResolutions ? RES_AXES_NATIVE : RES_AXES; const int nbins = i == 4 && mConfig.nativeFitResolutions ? (10 * RES_AXIS_BINS[0]) : RES_AXIS_BINS[0]; if (j == 4) { - double* binsPt = CreateLogAxis(AXIS_BINS[4], mConfig.resPrimaries == 1 ? PT_MIN_PRIM : AXES_MIN[4], AXES_MAX[4]); - mRes2[i][j] = new TH2F(name, name, nbins, -axis[i], axis[i], AXIS_BINS[j], binsPt); - delete[] binsPt; + std::unique_ptr binsPt{CreateLogAxis(AXIS_BINS[4], mConfig.resPrimaries == 1 ? PT_MIN_PRIM : AXES_MIN[4], AXES_MAX[4])}; + createHist(mRes2[i][j], name, name, nbins, -axis[i], axis[i], AXIS_BINS[j], binsPt.get()); } else { - mRes2[i][j] = new TH2F(name, name, nbins, -axis[i], axis[i], AXIS_BINS[j], AXES_MIN[j], AXES_MAX[j]); + createHist(mRes2[i][j], name, name, nbins, -axis[i], axis[i], AXIS_BINS[j], AXES_MIN[j], AXES_MAX[j]); } } } @@ -408,21 +419,19 @@ int GPUQA::InitQA() sprintf(name, "pull_rms_%s_vs_%s", VSPARAMETER_NAMES[i], VSPARAMETER_NAMES[j]); sprintf(fname, "pull_mean_%s_vs_%s", VSPARAMETER_NAMES[i], VSPARAMETER_NAMES[j]); if (j == 4) { - double* binsPt = CreateLogAxis(AXIS_BINS[4], AXES_MIN[4], AXES_MAX[4]); - mPull[i][j][0] = new TH1F(name, name, AXIS_BINS[j], binsPt); - mPull[i][j][1] = new TH1F(fname, fname, AXIS_BINS[j], binsPt); - delete[] binsPt; + std::unique_ptr binsPt{CreateLogAxis(AXIS_BINS[4], AXES_MIN[4], AXES_MAX[4])}; + createHist(mPull[i][j][0], name, name, AXIS_BINS[j], binsPt.get()); + createHist(mPull[i][j][1], fname, fname, AXIS_BINS[j], binsPt.get()); } else { - mPull[i][j][0] = new TH1F(name, name, AXIS_BINS[j], AXES_MIN[j], AXES_MAX[j]); - mPull[i][j][1] = new TH1F(fname, fname, AXIS_BINS[j], AXES_MIN[j], AXES_MAX[j]); + createHist(mPull[i][j][0], name, name, AXIS_BINS[j], AXES_MIN[j], AXES_MAX[j]); + createHist(mPull[i][j][1], fname, fname, AXIS_BINS[j], AXES_MIN[j], AXES_MAX[j]); } sprintf(name, "pull_%s_vs_%s", VSPARAMETER_NAMES[i], VSPARAMETER_NAMES[j]); if (j == 4) { - double* binsPt = CreateLogAxis(AXIS_BINS[4], AXES_MIN[4], AXES_MAX[4]); - mPull2[i][j] = new TH2F(name, name, RES_AXIS_BINS[0], -PULL_AXIS, PULL_AXIS, AXIS_BINS[j], binsPt); - delete[] binsPt; + std::unique_ptr binsPt{CreateLogAxis(AXIS_BINS[4], AXES_MIN[4], AXES_MAX[4])}; + createHist(mPull2[i][j], name, name, RES_AXIS_BINS[0], -PULL_AXIS, PULL_AXIS, AXIS_BINS[j], binsPt.get()); } else { - mPull2[i][j] = new TH2F(name, name, RES_AXIS_BINS[0], -PULL_AXIS, PULL_AXIS, AXIS_BINS[j], AXES_MIN[j], AXES_MAX[j]); + createHist(mPull2[i][j], name, name, RES_AXIS_BINS[0], -PULL_AXIS, PULL_AXIS, AXIS_BINS[j], AXES_MIN[j], AXES_MAX[j]); } } } @@ -432,20 +441,51 @@ int GPUQA::InitQA() int ioffset = i >= (2 * N_CLS_HIST - 1) ? (2 * N_CLS_HIST - 1) : i >= N_CLS_HIST ? N_CLS_HIST : 0; int itype = i >= (2 * N_CLS_HIST - 1) ? 2 : i >= N_CLS_HIST ? 1 : 0; sprintf(name, "clusters%s%s", CLUSTER_NAMES_SHORT[i - ioffset], CLUSTER_TYPES[itype]); - double* binsPt = CreateLogAxis(AXIS_BINS[4], PT_MIN_CLUST, PT_MAX); - mClusters[i] = new TH1D(name, name, AXIS_BINS[4], binsPt); - delete[] binsPt; + std::unique_ptr binsPt{CreateLogAxis(AXIS_BINS[4], PT_MIN_CLUST, PT_MAX)}; + createHist(mClusters[i], name, name, AXIS_BINS[4], binsPt.get()); } { sprintf(name, "nclusters"); - mNCl = new TH1F(name, name, 160, 0, 159); + createHist(mNCl, name, name, 160, 0, 159); } // Create Tracks Histograms { sprintf(name, "tracks"); - double* binsPt = CreateLogAxis(AXIS_BINS[4], PT_MIN_CLUST, PT_MAX); - mTracks = new TH1F(name, name, AXIS_BINS[4], binsPt); + std::unique_ptr binsPt{CreateLogAxis(AXIS_BINS[4], PT_MIN_CLUST, PT_MAX)}; + createHist(mTracks, name, name, AXIS_BINS[4], binsPt.get()); + } + + for (unsigned int i = 0; i < mHist1D->size(); i++) { + *mHist1D_pos[i] = &(*mHist1D)[i]; + } + for (unsigned int i = 0; i < mHist2D->size(); i++) { + *mHist2D_pos[i] = &(*mHist2D)[i]; + } + for (unsigned int i = 0; i < mHist1Dd->size(); i++) { + *mHist1Dd_pos[i] = &(*mHist1Dd)[i]; + } + + return 0; +} + +int GPUQA::InitQA() +{ + if (mQAInitialized) { + return 1; + } + + mColorNums = new Color_t[COLORCOUNT]; + for (int i = 0; i < COLORCOUNT; i++) { + float f1 = (float)((COLORS_HEX[i] >> 16) & 0xFF) / (float)0xFF; + float f2 = (float)((COLORS_HEX[i] >> 8) & 0xFF) / (float)0xFF; + float f3 = (float)((COLORS_HEX[i] >> 0) & 0xFF) / (float)0xFF; + TColor* c = new TColor(10000 + i, f1, f2, f3); + mColorNums[i] = c->GetNumber(); + } + + if (InitQACreateHistograms()) { + return 1; } mkdir("plots", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); diff --git a/GPU/GPUTracking/Standalone/qa/GPUQA.h b/GPU/GPUTracking/Standalone/qa/GPUQA.h index 99cf7f074e260..c9a5aa18badf2 100644 --- a/GPU/GPUTracking/Standalone/qa/GPUQA.h +++ b/GPU/GPUTracking/Standalone/qa/GPUQA.h @@ -60,7 +60,8 @@ class GPUQA #include "GPUTPCDef.h" #include - +#include +#include #ifdef GPUCA_TPC_GEOMETRY_O2 #include #endif @@ -80,6 +81,7 @@ class GPUTPCMCInfo; class GPUQA { public: + GPUQA(); GPUQA(GPUChainTracking* rec); ~GPUQA(); @@ -95,9 +97,15 @@ class GPUQA static bool QAAvailable() { return true; } bool IsInitialized() { return mQAInitialized; } + const std::vector& getHistograms1D() const { return mHist1D; } + const std::vector& getHistograms2D() const { return mHist2D; } + const std::vector& getHistograms1Dd() const { return mHist1Dd; } + static constexpr int N_CLS_HIST = 8; static constexpr int N_CLS_TYPE = 3; + static constexpr int MC_LABEL_INVALID = -1e9; + private: struct additionalMCParameters { float pt, phi, theta, eta, nWeightCls; @@ -108,6 +116,8 @@ class GPUQA float pt; }; + int InitQACreateHistograms(); + void SetAxisSize(TH1F* e); void SetLegend(TLegend* l); double* CreateLogAxis(int nbins, float xmin, float xmax); @@ -240,6 +250,17 @@ class GPUQA TPad* mPNCl; TLegend* mLNCl; + std::unique_ptr> mHist1D{}; + std::unique_ptr> mHist2D{}; + std::unique_ptr> mHist1Dd{}; + std::vector mHist1D_pos{}; + std::vector mHist2D_pos{}; + std::vector mHist1Dd_pos{}; + template + auto getHist(); + template + void createHist(T*& h, Args... args); + int mNEvents = 0; bool mQAInitialized = false; std::vector> mcEffBuffer; From e3992d52358e8cddd4552e41bc03c2cc004da235 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 10 Nov 2020 18:00:28 +0100 Subject: [PATCH 3/6] GPU: Add TPC Standalone QA mode for producing histograms for QC without writing them to file --- .../Standalone/display/GPUDisplay.cxx | 8 +- .../Standalone/display/GPUDisplay.h | 4 +- GPU/GPUTracking/Standalone/qa/GPUQA.cxx | 348 ++++++++++-------- GPU/GPUTracking/Standalone/qa/GPUQA.h | 13 +- 4 files changed, 212 insertions(+), 161 deletions(-) diff --git a/GPU/GPUTracking/Standalone/display/GPUDisplay.cxx b/GPU/GPUTracking/Standalone/display/GPUDisplay.cxx index 1a5c77b0a5ecb..7aa72568bac25 100644 --- a/GPU/GPUTracking/Standalone/display/GPUDisplay.cxx +++ b/GPU/GPUTracking/Standalone/display/GPUDisplay.cxx @@ -84,12 +84,12 @@ namespace GPUCA_NAMESPACE::gpu extern GPUSettingsStandalone configStandalone; } #endif -static const GPUSettingsDisplay& GPUDisplay_GetConfig(GPUChainTracking* rec) +static const GPUSettingsDisplay& GPUDisplay_GetConfig(GPUChainTracking* chain) { #if !defined(GPUCA_STANDALONE) static GPUSettingsDisplay defaultConfig; - if (rec->mConfigDisplay) { - return *((const GPUSettingsDisplay*)rec->mConfigDisplay); + if (chain->mConfigDisplay) { + return *((const GPUSettingsDisplay*)chain->mConfigDisplay); } else { return defaultConfig; } @@ -99,7 +99,7 @@ static const GPUSettingsDisplay& GPUDisplay_GetConfig(GPUChainTracking* rec) #endif } -GPUDisplay::GPUDisplay(GPUDisplayBackend* backend, GPUChainTracking* rec, GPUQA* qa) : mBackend(backend), mChain(rec), mConfig(GPUDisplay_GetConfig(rec)), mQA(qa), mMerger(rec->GetTPCMerger()) { backend->mDisplay = this; } +GPUDisplay::GPUDisplay(GPUDisplayBackend* backend, GPUChainTracking* chain, GPUQA* qa) : mBackend(backend), mChain(chain), mConfig(GPUDisplay_GetConfig(chain)), mQA(qa), mMerger(chain->GetTPCMerger()) { backend->mDisplay = this; } const GPUParam& GPUDisplay::param() { return mChain->GetParam(); } const GPUTPCTracker& GPUDisplay::sliceTracker(int iSlice) { return mChain->GetTPCSliceTrackers()[iSlice]; } diff --git a/GPU/GPUTracking/Standalone/display/GPUDisplay.h b/GPU/GPUTracking/Standalone/display/GPUDisplay.h index 8f0efea771780..565b3af52c2e8 100644 --- a/GPU/GPUTracking/Standalone/display/GPUDisplay.h +++ b/GPU/GPUTracking/Standalone/display/GPUDisplay.h @@ -53,7 +53,7 @@ namespace gpu class GPUDisplay { public: - GPUDisplay(GPUDisplayBackend* backend, GPUChainTracking* rec, GPUQA* qa) {} + GPUDisplay(GPUDisplayBackend* backend, GPUChainTracking* chain, GPUQA* qa) {} ~GPUDisplay() = default; GPUDisplay(const GPUDisplay&) = delete; @@ -94,7 +94,7 @@ struct GPUParam; class GPUDisplay { public: - GPUDisplay(GPUDisplayBackend* backend, GPUChainTracking* rec, GPUQA* qa); + GPUDisplay(GPUDisplayBackend* backend, GPUChainTracking* chain, GPUQA* qa); ~GPUDisplay() = default; GPUDisplay(const GPUDisplay&) = delete; diff --git a/GPU/GPUTracking/Standalone/qa/GPUQA.cxx b/GPU/GPUTracking/Standalone/qa/GPUQA.cxx index f24b97bd6db90..91cf458ba05ac 100644 --- a/GPU/GPUTracking/Standalone/qa/GPUQA.cxx +++ b/GPU/GPUTracking/Standalone/qa/GPUQA.cxx @@ -119,12 +119,12 @@ namespace GPUCA_NAMESPACE::gpu extern GPUSettingsStandalone configStandalone; } #endif -static const GPUSettingsQA& GPUQA_GetConfig(GPUChainTracking* rec) +static const GPUSettingsQA& GPUQA_GetConfig(GPUChainTracking* chain) { #if !defined(GPUCA_STANDALONE) static GPUSettingsQA defaultConfig; - if (rec->mConfigQA) { - return *((const GPUSettingsQA*)rec->mConfigQA); + if (chain && chain->mConfigQA) { + return *((const GPUSettingsQA*)chain->mConfigQA); } else { return defaultConfig; } @@ -189,6 +189,8 @@ static const constexpr float RES_AXES[5] = {1., 1., 0.03, 0.03, 1.0}; static const constexpr float RES_AXES_NATIVE[5] = {1., 1., 0.1, 0.1, 5.0}; static const constexpr float PULL_AXIS = 10.f; +static TCanvas cfit; + #ifdef GPUCA_TPC_GEOMETRY_O2 #include "SimulationDataFormat/MCCompLabel.h" #include "SimulationDataFormat/ConstMCTruthContainer.h" @@ -271,11 +273,12 @@ void GPUQA::createHist(T*& h, Args... args) h = &p.first->get()->back(); } -GPUQA::GPUQA(GPUChainTracking* rec) : mTracking(rec), mConfig(GPUQA_GetConfig(rec)) +GPUQA::GPUQA(GPUChainTracking* chain) : mTracking(chain), mConfig(GPUQA_GetConfig(chain)) { mHist1D.reset(new std::vector); mHist2D.reset(new std::vector); mHist1Dd.reset(new std::vector); + mRunForQC = chain == nullptr; } GPUQA::~GPUQA() = default; @@ -475,7 +478,7 @@ int GPUQA::InitQA() return 1; } - mColorNums = new Color_t[COLORCOUNT]; + mColorNums.resize(COLORCOUNT); for (int i = 0; i < COLORCOUNT; i++) { float f1 = (float)((COLORS_HEX[i] >> 16) & 0xFF) / (float)0xFF; float f2 = (float)((COLORS_HEX[i] >> 8) & 0xFF) / (float)0xFF; @@ -488,11 +491,13 @@ int GPUQA::InitQA() return 1; } - mkdir("plots", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + if (!mRunForQC) { + mkdir("plots", S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH); + } #ifdef GPUCA_O2_LIB - TFile* fileSim = new TFile(o2::base::NameConf::getMCKinematicsFileName("o2sim").c_str()); - TTree* treeSim = (TTree*)fileSim->Get("o2sim"); + TFile fileSim(o2::base::NameConf::getMCKinematicsFileName("o2sim").c_str()); + TTree* treeSim = (TTree*)fileSim.Get("o2sim"); std::vector* tracksX; std::vector* trackRefsX; if (treeSim == nullptr) { @@ -567,8 +572,7 @@ int GPUQA::InitQA() } } - fileSim->Close(); - delete fileSim; + fileSim.Close(); #endif if (mConfig.matchMCLabels.size()) { @@ -1605,148 +1609,150 @@ int GPUQA::DrawQAHistograms() tout = new TFile(mConfig.output.c_str(), "RECREATE"); } - float legendSpacingString = 0.025; - for (int i = 0; i < ConfigNumInputs; i++) { - GetName(fname, i); - if (strlen(fname) * 0.006 > legendSpacingString) { - legendSpacingString = strlen(fname) * 0.006; + if (!mRunForQC) { + float legendSpacingString = 0.025; + for (int i = 0; i < ConfigNumInputs; i++) { + GetName(fname, i); + if (strlen(fname) * 0.006 > legendSpacingString) { + legendSpacingString = strlen(fname) * 0.006; + } } - } - // Create Canvas / Pads for Efficiency Histograms - for (int ii = 0; ii < 6; ii++) { - int i = ii == 5 ? 4 : ii; - sprintf(fname, "ceff_%d", ii); - sprintf(name, "Efficiency versus %s", VSPARAMETER_NAMES[i]); - mCEff[ii] = new TCanvas(fname, name, 0, 0, 700, 700. * 2. / 3.); - mCEff[ii]->cd(); - float dy = 1. / 2.; - mPEff[ii][0] = new TPad("p0", "", 0.0, dy * 0, 0.5, dy * 1); - mPEff[ii][0]->Draw(); - mPEff[ii][0]->SetRightMargin(0.04); - mPEff[ii][1] = new TPad("p1", "", 0.5, dy * 0, 1.0, dy * 1); - mPEff[ii][1]->Draw(); - mPEff[ii][1]->SetRightMargin(0.04); - mPEff[ii][2] = new TPad("p2", "", 0.0, dy * 1, 0.5, dy * 2 - .001); - mPEff[ii][2]->Draw(); - mPEff[ii][2]->SetRightMargin(0.04); - mPEff[ii][3] = new TPad("p3", "", 0.5, dy * 1, 1.0, dy * 2 - .001); - mPEff[ii][3]->Draw(); - mPEff[ii][3]->SetRightMargin(0.04); - mLEff[ii] = new TLegend(0.92 - legendSpacingString * 1.45, 0.83 - (0.93 - 0.82) / 2. * (float)ConfigNumInputs, 0.98, 0.849); - SetLegend(mLEff[ii]); - } - - // Create Canvas / Pads for Resolution Histograms - for (int ii = 0; ii < 7; ii++) { - int i = ii == 5 ? 4 : ii; - sprintf(fname, "cres_%d", ii); - if (ii == 6) { - sprintf(name, "Integral Resolution"); - } else { - sprintf(name, "Resolution versus %s", VSPARAMETER_NAMES[i]); - } - mCRes[ii] = new TCanvas(fname, name, 0, 0, 700, 700. * 2. / 3.); - mCRes[ii]->cd(); - gStyle->SetOptFit(1); - - float dy = 1. / 2.; - mPRes[ii][3] = new TPad("p0", "", 0.0, dy * 0, 0.5, dy * 1); - mPRes[ii][3]->Draw(); - mPRes[ii][3]->SetRightMargin(0.04); - mPRes[ii][4] = new TPad("p1", "", 0.5, dy * 0, 1.0, dy * 1); - mPRes[ii][4]->Draw(); - mPRes[ii][4]->SetRightMargin(0.04); - mPRes[ii][0] = new TPad("p2", "", 0.0, dy * 1, 1. / 3., dy * 2 - .001); - mPRes[ii][0]->Draw(); - mPRes[ii][0]->SetRightMargin(0.04); - mPRes[ii][0]->SetLeftMargin(0.15); - mPRes[ii][1] = new TPad("p3", "", 1. / 3., dy * 1, 2. / 3., dy * 2 - .001); - mPRes[ii][1]->Draw(); - mPRes[ii][1]->SetRightMargin(0.04); - mPRes[ii][1]->SetLeftMargin(0.135); - mPRes[ii][2] = new TPad("p4", "", 2. / 3., dy * 1, 1.0, dy * 2 - .001); - mPRes[ii][2]->Draw(); - mPRes[ii][2]->SetRightMargin(0.06); - mPRes[ii][2]->SetLeftMargin(0.135); - if (ii < 6) { - mLRes[ii] = new TLegend(0.9 - legendSpacingString * 1.45, 0.93 - (0.93 - 0.86) / 2. * (float)ConfigNumInputs, 0.98, 0.949); - SetLegend(mLRes[ii]); + // Create Canvas / Pads for Efficiency Histograms + for (int ii = 0; ii < 6; ii++) { + int i = ii == 5 ? 4 : ii; + sprintf(fname, "ceff_%d", ii); + sprintf(name, "Efficiency versus %s", VSPARAMETER_NAMES[i]); + mCEff[ii] = new TCanvas(fname, name, 0, 0, 700, 700. * 2. / 3.); + mCEff[ii]->cd(); + float dy = 1. / 2.; + mPEff[ii][0] = new TPad("p0", "", 0.0, dy * 0, 0.5, dy * 1); + mPEff[ii][0]->Draw(); + mPEff[ii][0]->SetRightMargin(0.04); + mPEff[ii][1] = new TPad("p1", "", 0.5, dy * 0, 1.0, dy * 1); + mPEff[ii][1]->Draw(); + mPEff[ii][1]->SetRightMargin(0.04); + mPEff[ii][2] = new TPad("p2", "", 0.0, dy * 1, 0.5, dy * 2 - .001); + mPEff[ii][2]->Draw(); + mPEff[ii][2]->SetRightMargin(0.04); + mPEff[ii][3] = new TPad("p3", "", 0.5, dy * 1, 1.0, dy * 2 - .001); + mPEff[ii][3]->Draw(); + mPEff[ii][3]->SetRightMargin(0.04); + mLEff[ii] = new TLegend(0.92 - legendSpacingString * 1.45, 0.83 - (0.93 - 0.82) / 2. * (float)ConfigNumInputs, 0.98, 0.849); + SetLegend(mLEff[ii]); } - } - // Create Canvas / Pads for Pull Histograms - for (int ii = 0; ii < 7; ii++) { - int i = ii == 5 ? 4 : ii; - sprintf(fname, "cpull_%d", ii); - if (ii == 6) { - sprintf(name, "Integral Pull"); - } else { - sprintf(name, "Pull versus %s", VSPARAMETER_NAMES[i]); - } - mCPull[ii] = new TCanvas(fname, name, 0, 0, 700, 700. * 2. / 3.); - mCPull[ii]->cd(); - gStyle->SetOptFit(1); - - float dy = 1. / 2.; - mPPull[ii][3] = new TPad("p0", "", 0.0, dy * 0, 0.5, dy * 1); - mPPull[ii][3]->Draw(); - mPPull[ii][3]->SetRightMargin(0.04); - mPPull[ii][4] = new TPad("p1", "", 0.5, dy * 0, 1.0, dy * 1); - mPPull[ii][4]->Draw(); - mPPull[ii][4]->SetRightMargin(0.04); - mPPull[ii][0] = new TPad("p2", "", 0.0, dy * 1, 1. / 3., dy * 2 - .001); - mPPull[ii][0]->Draw(); - mPPull[ii][0]->SetRightMargin(0.04); - mPPull[ii][0]->SetLeftMargin(0.15); - mPPull[ii][1] = new TPad("p3", "", 1. / 3., dy * 1, 2. / 3., dy * 2 - .001); - mPPull[ii][1]->Draw(); - mPPull[ii][1]->SetRightMargin(0.04); - mPPull[ii][1]->SetLeftMargin(0.135); - mPPull[ii][2] = new TPad("p4", "", 2. / 3., dy * 1, 1.0, dy * 2 - .001); - mPPull[ii][2]->Draw(); - mPPull[ii][2]->SetRightMargin(0.06); - mPPull[ii][2]->SetLeftMargin(0.135); - if (ii < 6) { - mLPull[ii] = new TLegend(0.9 - legendSpacingString * 1.45, 0.93 - (0.93 - 0.86) / 2. * (float)ConfigNumInputs, 0.98, 0.949); - SetLegend(mLPull[ii]); + // Create Canvas / Pads for Resolution Histograms + for (int ii = 0; ii < 7; ii++) { + int i = ii == 5 ? 4 : ii; + sprintf(fname, "cres_%d", ii); + if (ii == 6) { + sprintf(name, "Integral Resolution"); + } else { + sprintf(name, "Resolution versus %s", VSPARAMETER_NAMES[i]); + } + mCRes[ii] = new TCanvas(fname, name, 0, 0, 700, 700. * 2. / 3.); + mCRes[ii]->cd(); + gStyle->SetOptFit(1); + + float dy = 1. / 2.; + mPRes[ii][3] = new TPad("p0", "", 0.0, dy * 0, 0.5, dy * 1); + mPRes[ii][3]->Draw(); + mPRes[ii][3]->SetRightMargin(0.04); + mPRes[ii][4] = new TPad("p1", "", 0.5, dy * 0, 1.0, dy * 1); + mPRes[ii][4]->Draw(); + mPRes[ii][4]->SetRightMargin(0.04); + mPRes[ii][0] = new TPad("p2", "", 0.0, dy * 1, 1. / 3., dy * 2 - .001); + mPRes[ii][0]->Draw(); + mPRes[ii][0]->SetRightMargin(0.04); + mPRes[ii][0]->SetLeftMargin(0.15); + mPRes[ii][1] = new TPad("p3", "", 1. / 3., dy * 1, 2. / 3., dy * 2 - .001); + mPRes[ii][1]->Draw(); + mPRes[ii][1]->SetRightMargin(0.04); + mPRes[ii][1]->SetLeftMargin(0.135); + mPRes[ii][2] = new TPad("p4", "", 2. / 3., dy * 1, 1.0, dy * 2 - .001); + mPRes[ii][2]->Draw(); + mPRes[ii][2]->SetRightMargin(0.06); + mPRes[ii][2]->SetLeftMargin(0.135); + if (ii < 6) { + mLRes[ii] = new TLegend(0.9 - legendSpacingString * 1.45, 0.93 - (0.93 - 0.86) / 2. * (float)ConfigNumInputs, 0.98, 0.949); + SetLegend(mLRes[ii]); + } } - } - // Create Canvas for Cluster Histos - for (int i = 0; i < 3; i++) { - sprintf(fname, "cclust_%d", i); - mCClust[i] = new TCanvas(fname, CLUSTER_TITLES[i], 0, 0, 700, 700. * 2. / 3.); - mCClust[i]->cd(); - mPClust[i] = new TPad("p0", "", 0.0, 0.0, 1.0, 1.0); - mPClust[i]->Draw(); - float y1 = i != 1 ? 0.77 : 0.27, y2 = i != 1 ? 0.9 : 0.42; - mLClust[i] = new TLegend(i == 2 ? 0.1 : (0.65 - legendSpacingString * 1.45), y2 - (y2 - y1) * (ConfigNumInputs + (i != 1) / 2.) + 0.005, i == 2 ? (0.3 + legendSpacingString * 1.45) : 0.9, y2); - SetLegend(mLClust[i]); - } + // Create Canvas / Pads for Pull Histograms + for (int ii = 0; ii < 7; ii++) { + int i = ii == 5 ? 4 : ii; + sprintf(fname, "cpull_%d", ii); + if (ii == 6) { + sprintf(name, "Integral Pull"); + } else { + sprintf(name, "Pull versus %s", VSPARAMETER_NAMES[i]); + } + mCPull[ii] = new TCanvas(fname, name, 0, 0, 700, 700. * 2. / 3.); + mCPull[ii]->cd(); + gStyle->SetOptFit(1); + + float dy = 1. / 2.; + mPPull[ii][3] = new TPad("p0", "", 0.0, dy * 0, 0.5, dy * 1); + mPPull[ii][3]->Draw(); + mPPull[ii][3]->SetRightMargin(0.04); + mPPull[ii][4] = new TPad("p1", "", 0.5, dy * 0, 1.0, dy * 1); + mPPull[ii][4]->Draw(); + mPPull[ii][4]->SetRightMargin(0.04); + mPPull[ii][0] = new TPad("p2", "", 0.0, dy * 1, 1. / 3., dy * 2 - .001); + mPPull[ii][0]->Draw(); + mPPull[ii][0]->SetRightMargin(0.04); + mPPull[ii][0]->SetLeftMargin(0.15); + mPPull[ii][1] = new TPad("p3", "", 1. / 3., dy * 1, 2. / 3., dy * 2 - .001); + mPPull[ii][1]->Draw(); + mPPull[ii][1]->SetRightMargin(0.04); + mPPull[ii][1]->SetLeftMargin(0.135); + mPPull[ii][2] = new TPad("p4", "", 2. / 3., dy * 1, 1.0, dy * 2 - .001); + mPPull[ii][2]->Draw(); + mPPull[ii][2]->SetRightMargin(0.06); + mPPull[ii][2]->SetLeftMargin(0.135); + if (ii < 6) { + mLPull[ii] = new TLegend(0.9 - legendSpacingString * 1.45, 0.93 - (0.93 - 0.86) / 2. * (float)ConfigNumInputs, 0.98, 0.949); + SetLegend(mLPull[ii]); + } + } - // Create Canvas for other histos - { - mCTracks = new TCanvas("ctracks", "Track Pt", 0, 0, 700, 700. * 2. / 3.); - mCTracks->cd(); - mPTracks = new TPad("p0", "", 0.0, 0.0, 1.0, 1.0); - mPTracks->Draw(); - mLTracks = new TLegend(0.9 - legendSpacingString * 1.45, 0.93 - (0.93 - 0.86) / 2. * (float)ConfigNumInputs, 0.98, 0.949); - SetLegend(mLTracks); + // Create Canvas for Cluster Histos + for (int i = 0; i < 3; i++) { + sprintf(fname, "cclust_%d", i); + mCClust[i] = new TCanvas(fname, CLUSTER_TITLES[i], 0, 0, 700, 700. * 2. / 3.); + mCClust[i]->cd(); + mPClust[i] = new TPad("p0", "", 0.0, 0.0, 1.0, 1.0); + mPClust[i]->Draw(); + float y1 = i != 1 ? 0.77 : 0.27, y2 = i != 1 ? 0.9 : 0.42; + mLClust[i] = new TLegend(i == 2 ? 0.1 : (0.65 - legendSpacingString * 1.45), y2 - (y2 - y1) * (ConfigNumInputs + (i != 1) / 2.) + 0.005, i == 2 ? (0.3 + legendSpacingString * 1.45) : 0.9, y2); + SetLegend(mLClust[i]); + } - mCNCl = new TCanvas("cncl", "Number of clusters per track", 0, 0, 700, 700. * 2. / 3.); - mCNCl->cd(); - mPNCl = new TPad("p0", "", 0.0, 0.0, 1.0, 1.0); - mPNCl->Draw(); - mLNCl = new TLegend(0.9 - legendSpacingString * 1.45, 0.93 - (0.93 - 0.86) / 2. * (float)ConfigNumInputs, 0.98, 0.949); - SetLegend(mLNCl); - } + // Create Canvas for other histos + { + mCTracks = new TCanvas("ctracks", "Track Pt", 0, 0, 700, 700. * 2. / 3.); + mCTracks->cd(); + mPTracks = new TPad("p0", "", 0.0, 0.0, 1.0, 1.0); + mPTracks->Draw(); + mLTracks = new TLegend(0.9 - legendSpacingString * 1.45, 0.93 - (0.93 - 0.86) / 2. * (float)ConfigNumInputs, 0.98, 0.949); + SetLegend(mLTracks); + + mCNCl = new TCanvas("cncl", "Number of clusters per track", 0, 0, 700, 700. * 2. / 3.); + mCNCl->cd(); + mPNCl = new TPad("p0", "", 0.0, 0.0, 1.0, 1.0); + mPNCl->Draw(); + mLNCl = new TLegend(0.9 - legendSpacingString * 1.45, 0.93 - (0.93 - 0.86) / 2. * (float)ConfigNumInputs, 0.98, 0.949); + SetLegend(mLNCl); + } - if (!mConfig.inputHistogramsOnly) { - GPUInfo("QA Stats: Eff: Tracks Prim %d (Eta %d, Pt %d) %f%% (%f%%) Sec %d (Eta %d, Pt %d) %f%% (%f%%) - Res: Tracks %d (Eta %d, Pt %d)", (int)mEff[3][1][0][0][0]->GetEntries(), (int)mEff[3][1][0][3][0]->GetEntries(), (int)mEff[3][1][0][4][0]->GetEntries(), - mEff[0][0][0][0][0]->GetSumOfWeights() / std::max(1., mEff[3][0][0][0][0]->GetSumOfWeights()), mEff[0][1][0][0][0]->GetSumOfWeights() / std::max(1., mEff[3][1][0][0][0]->GetSumOfWeights()), (int)mEff[3][1][1][0][0]->GetEntries(), (int)mEff[3][1][1][3][0]->GetEntries(), - (int)mEff[3][1][1][4][0]->GetEntries(), mEff[0][0][1][0][0]->GetSumOfWeights() / std::max(1., mEff[3][0][1][0][0]->GetSumOfWeights()), mEff[0][1][1][0][0]->GetSumOfWeights() / std::max(1., mEff[3][1][1][0][0]->GetSumOfWeights()), (int)mRes2[0][0]->GetEntries(), - (int)mRes2[0][3]->GetEntries(), (int)mRes2[0][4]->GetEntries()); + if (!mConfig.inputHistogramsOnly) { + GPUInfo("QA Stats: Eff: Tracks Prim %d (Eta %d, Pt %d) %f%% (%f%%) Sec %d (Eta %d, Pt %d) %f%% (%f%%) - Res: Tracks %d (Eta %d, Pt %d)", (int)mEff[3][1][0][0][0]->GetEntries(), (int)mEff[3][1][0][3][0]->GetEntries(), (int)mEff[3][1][0][4][0]->GetEntries(), + mEff[0][0][0][0][0]->GetSumOfWeights() / std::max(1., mEff[3][0][0][0][0]->GetSumOfWeights()), mEff[0][1][0][0][0]->GetSumOfWeights() / std::max(1., mEff[3][1][0][0][0]->GetSumOfWeights()), (int)mEff[3][1][1][0][0]->GetEntries(), (int)mEff[3][1][1][3][0]->GetEntries(), + (int)mEff[3][1][1][4][0]->GetEntries(), mEff[0][0][1][0][0]->GetSumOfWeights() / std::max(1., mEff[3][0][1][0][0]->GetSumOfWeights()), mEff[0][1][1][0][0]->GetSumOfWeights() / std::max(1., mEff[3][1][1][0][0]->GetSumOfWeights()), (int)mRes2[0][0]->GetEntries(), + (int)mRes2[0][3]->GetEntries(), (int)mRes2[0][4]->GetEntries()); + } } // Process / Draw Efficiency Histograms @@ -1795,6 +1801,9 @@ int GPUQA::DrawQAHistograms() e->SetLineColor(mColorNums[(l == 2 ? (ConfigNumInputs * 2 + k) : (k * 2 + l)) % COLORCOUNT]); e->SetLineStyle(CONFIG_DASHED_MARKERS ? k + 1 : 1); SetAxisSize(e); + if (mRunForQC) { + continue; + } e->Draw(k || l ? "same" : ""); if (j == 0) { GetName(fname, k); @@ -1805,10 +1814,17 @@ int GPUQA::DrawQAHistograms() mPEff[ii][j]->SetLogx(); } } + if (mRunForQC) { + continue; + } mCEff[ii]->cd(); ChangePadTitleSize(mPEff[ii][j], 0.056); } } + if (mRunForQC) { + continue; + } + mLEff[ii]->Draw(); doPerfFigure(0.2, 0.295, 0.025); @@ -1834,8 +1850,9 @@ int GPUQA::DrawQAHistograms() TPad* pad = p ? mPPull[ii][j] : mPRes[ii][j]; if (!mConfig.inputHistogramsOnly && ii != 5) { - TCanvas cfit; - cfit.cd(); + if (!mRunForQC) { + cfit.cd(); + } TAxis* axis = src->GetYaxis(); int nBins = axis->GetNbins(); @@ -1920,8 +1937,9 @@ int GPUQA::DrawQAHistograms() dstIntegral->SetName(fname); dstIntegral->SetTitle(name); } - pad->cd(); - + if (!mRunForQC) { + pad->cd(); + } int numColor = 0; float tmpMax = -1000.; float tmpMin = 1000.; @@ -1999,6 +2017,10 @@ int GPUQA::DrawQAHistograms() } else if (j < 3) { e->GetYaxis()->SetTitleOffset(1.4); } + if (mRunForQC) { + continue; + } + e->Draw(k || l ? "same" : ""); if (j == 0) { GetName(fname, k); @@ -2011,6 +2033,10 @@ int GPUQA::DrawQAHistograms() } } } + if (mRunForQC) { + continue; + } + if (ii == 5) { pad->SetLogx(); } @@ -2019,6 +2045,10 @@ int GPUQA::DrawQAHistograms() ChangePadTitleSize(pad, 0.056); } } + if (mRunForQC) { + continue; + } + leg->Draw(); doPerfFigure(0.2, 0.295, 0.025); @@ -2068,10 +2098,18 @@ int GPUQA::DrawQAHistograms() if (tout && !mConfig.inputHistogramsOnly && k == 0) { e->Write(); } + if (mRunForQC) { + continue; + } + e->Draw(k == 0 ? "" : "same"); } can->cd(); } + if (mRunForQC) { + continue; + } + can->Print(p ? "plots/pull_integral.pdf" : "plots/res_integral.pdf"); if (mConfig.writeRootFiles) { can->Print(p ? "plots/pull_integral.root" : "plots/res_integral.root"); @@ -2111,7 +2149,7 @@ int GPUQA::DrawQAHistograms() if (!mcAvail) { counts[N_CLS_HIST - 1] = mClusterCounts.nTotal; } - if (counts[N_CLS_HIST - 1]) { + if (counts[N_CLS_HIST - 1] && !mRunForQC) { if (mcAvail) { for (int i = 0; i < N_CLS_HIST; i++) { printf("\t%35s: %'12llu (%6.2f%%)\n", CLUSTER_NAMES[i], counts[i], 100.f * counts[i] / counts[N_CLS_HIST - 1]); @@ -2220,6 +2258,10 @@ int GPUQA::DrawQAHistograms() if (i == 0) { e->GetXaxis()->SetRange(2, AXIS_BINS[4]); } + if (mRunForQC) { + continue; + } + e->Draw(j == end - 1 && k == 0 ? "" : "same"); GetName(fname, k); sprintf(name, "%s%s", fname, CLUSTER_NAMES[j - begin]); @@ -2230,9 +2272,17 @@ int GPUQA::DrawQAHistograms() TH1* e = reinterpret_cast(mClusters[begin + CL_att_adj]->Clone()); e->Add(mClusters[begin + CL_prot], -1); e->SetLineColor(mColorNums[numColor++ % COLORCOUNT]); + if (mRunForQC) { + continue; + } + e->Draw("same"); mLClust[i]->AddEntry(e, "Removed", "l"); } + if (mRunForQC) { + continue; + } + mLClust[i]->Draw(); doPerfFigure(i != 2 ? 0.37 : 0.6, 0.295, 0.030); @@ -2246,7 +2296,7 @@ int GPUQA::DrawQAHistograms() } // Process track histograms - { + if (!mRunForQC) { float tmpMax = 0.; for (int k = 0; k < ConfigNumInputs; k++) { TH1F* e = mTracks; diff --git a/GPU/GPUTracking/Standalone/qa/GPUQA.h b/GPU/GPUTracking/Standalone/qa/GPUQA.h index c9a5aa18badf2..e37310af68fc1 100644 --- a/GPU/GPUTracking/Standalone/qa/GPUQA.h +++ b/GPU/GPUTracking/Standalone/qa/GPUQA.h @@ -38,7 +38,7 @@ class GPUChainTracking; class GPUQA { public: - GPUQA(GPUChainTracking* rec) {} + GPUQA(GPUChainTracking* chain) {} ~GPUQA() = default; int InitQA() { return 1; } @@ -82,7 +82,7 @@ class GPUQA { public: GPUQA(); - GPUQA(GPUChainTracking* rec); + GPUQA(GPUChainTracking* chain); ~GPUQA(); int InitQA(); @@ -97,9 +97,9 @@ class GPUQA static bool QAAvailable() { return true; } bool IsInitialized() { return mQAInitialized; } - const std::vector& getHistograms1D() const { return mHist1D; } - const std::vector& getHistograms2D() const { return mHist2D; } - const std::vector& getHistograms1Dd() const { return mHist1Dd; } + const std::vector& getHistograms1D() const { return *mHist1D; } + const std::vector& getHistograms2D() const { return *mHist2D; } + const std::vector& getHistograms1Dd() const { return *mHist1Dd; } static constexpr int N_CLS_HIST = 8; static constexpr int N_CLS_TYPE = 3; @@ -182,6 +182,7 @@ class GPUQA GPUChainTracking* mTracking; const GPUSettingsQA& mConfig; + bool mRunForQC; const char* str_perf_figure_1 = "ALICE Performance 2018/03/20"; // const char* str_perf_figure_2 = "2015, MC pp, #sqrt{s} = 5.02 TeV"; @@ -268,7 +269,7 @@ class GPUQA std::vector> mGoodTracks; std::vector> mGoodHits; - Color_t* mColorNums; + std::vector mColorNums; int mMCTrackMin = -1, mMCTrackMax = -1; }; From baf204b693b4daf9f1c74f615fcf92bec04781b6 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 10 Nov 2020 19:21:10 +0100 Subject: [PATCH 4/6] TPC Workflow: Add option to send QA data as external input to QC --- .../include/TPCWorkflow/CATrackerSpec.h | 5 ++++ .../include/TPCWorkflow/RecoWorkflow.h | 1 + Detectors/TPC/workflow/src/CATrackerSpec.cxx | 26 +++++++++++++++++++ Detectors/TPC/workflow/src/RecoWorkflow.cxx | 3 ++- .../TPC/workflow/src/tpc-reco-workflow.cxx | 2 +- GPU/GPUTracking/Base/GPUSettingsList.h | 3 ++- GPU/GPUTracking/Interface/GPUO2Interface.cxx | 6 +++++ .../Interface/GPUO2InterfaceConfiguration.h | 11 ++++++++ GPU/GPUTracking/Standalone/qa/GPUQA.cxx | 6 ++--- 9 files changed, 57 insertions(+), 6 deletions(-) diff --git a/Detectors/TPC/workflow/include/TPCWorkflow/CATrackerSpec.h b/Detectors/TPC/workflow/include/TPCWorkflow/CATrackerSpec.h index 0be54aaf59818..8f2195dc9eecc 100644 --- a/Detectors/TPC/workflow/include/TPCWorkflow/CATrackerSpec.h +++ b/Detectors/TPC/workflow/include/TPCWorkflow/CATrackerSpec.h @@ -41,6 +41,7 @@ enum struct Operation { OutputCAClusters, // publish the clusters produced by CA clusterer OutputCompClusters, // publish CompClusters container OutputCompClustersFlat, // publish CompClusters container + OutputQA, // Ship QA histograms to QC ProcessMC, // process MC labels SendClustersPerSector, // Send clusters and clusters mc labels per sector Noop, // skip argument on the constructor @@ -88,6 +89,9 @@ struct Config { case Operation::OutputCAClusters: outputCAClusters = true; break; + case Operation::OutputQA: + outputQA = true; + break; case Operation::ProcessMC: processMC = true; break; @@ -116,6 +120,7 @@ struct Config { bool outputCompClusters = false; bool outputCompClustersFlat = false; bool outputCAClusters = false; + bool outputQA = false; bool processMC = false; bool sendClustersPerSector = false; }; diff --git a/Detectors/TPC/workflow/include/TPCWorkflow/RecoWorkflow.h b/Detectors/TPC/workflow/include/TPCWorkflow/RecoWorkflow.h index 100a35e82c0bc..d4140736b0985 100644 --- a/Detectors/TPC/workflow/include/TPCWorkflow/RecoWorkflow.h +++ b/Detectors/TPC/workflow/include/TPCWorkflow/RecoWorkflow.h @@ -60,6 +60,7 @@ enum struct OutputType { Digits, DisableWriter, SendClustersPerSector, ZSRaw, + QA, }; using CompletionPolicyData = std::vector; diff --git a/Detectors/TPC/workflow/src/CATrackerSpec.cxx b/Detectors/TPC/workflow/src/CATrackerSpec.cxx index bd7597b7a1a1b..97a196aadbc60 100644 --- a/Detectors/TPC/workflow/src/CATrackerSpec.cxx +++ b/Detectors/TPC/workflow/src/CATrackerSpec.cxx @@ -65,6 +65,10 @@ #include "GPUReconstructionConvert.h" #include "DetectorsRaw/RDHUtils.h" #include +#include +#include +#include +#include using namespace o2::framework; using namespace o2::header; @@ -154,6 +158,12 @@ DataProcessorSpec getCATrackerSpec(CompletionPolicyData* policyData, ca::Config LOG(INFO) << "GPU device number selected from pipeline id: " << myId << " / " << idMax; } config.configProcessing.runMC = specconfig.processMC; + if (specconfig.outputQA) { + if (!config.configProcessing.runQA) { + config.configQA.forQC = true; + } + config.configProcessing.runQA = true; + } config.configReconstruction.NWaysOuter = true; config.configInterface.outputToExternalBuffers = true; @@ -689,6 +699,19 @@ DataProcessorSpec getCATrackerSpec(CompletionPolicyData* policyData, ca::Config } } } + if (specconfig.outputQA) { + TObjArray out; + for (unsigned int i = 0; i < outputRegions.qa.hist1->size(); i++) { + out.Add((TObject*)&(*outputRegions.qa.hist1)[i]); // FIXME: Fundamentally broken, we cannot add the const object, but QC doesn't accept the std::vector + } + for (unsigned int i = 0; i < outputRegions.qa.hist2->size(); i++) { + out.Add((TObject*)&(*outputRegions.qa.hist2)[i]); + } + for (unsigned int i = 0; i < outputRegions.qa.hist3->size(); i++) { + out.Add((TObject*)&(*outputRegions.qa.hist3)[i]); + } + pc.outputs().snapshot({gDataOriginTPC, "TRACKINGQA", 0, Lifetime::Timeframe}, out); + } timer.Stop(); LOG(INFO) << "TPC CATracker time for this TF " << timer.CpuTime() - cput << " s"; }; @@ -789,6 +812,9 @@ DataProcessorSpec getCATrackerSpec(CompletionPolicyData* policyData, ca::Config } } } + if (specconfig.outputQA) { + outputSpecs.emplace_back(gDataOriginTPC, "TRACKINGQA", 0, Lifetime::Timeframe); + } return std::move(outputSpecs); }; diff --git a/Detectors/TPC/workflow/src/RecoWorkflow.cxx b/Detectors/TPC/workflow/src/RecoWorkflow.cxx index 8c850f3b8c03e..43116540ffed7 100644 --- a/Detectors/TPC/workflow/src/RecoWorkflow.cxx +++ b/Detectors/TPC/workflow/src/RecoWorkflow.cxx @@ -85,7 +85,7 @@ const std::unordered_map OutputMap{ {"disable-writer", OutputType::DisableWriter}, {"send-clusters-per-sector", OutputType::SendClustersPerSector}, {"zsraw", OutputType::ZSRaw}, -}; + {"qa", OutputType::QA}}; framework::WorkflowSpec getWorkflow(CompletionPolicyData* policyData, std::vector const& tpcSectors, std::vector const& laneConfiguration, bool propagateMC, unsigned nLanes, std::string const& cfgInput, std::string const& cfgOutput, @@ -442,6 +442,7 @@ framework::WorkflowSpec getWorkflow(CompletionPolicyData* policyData, std::vecto produceCompClusters ? ca::Operation::OutputCompClusters : ca::Operation::Noop, runClusterEncoder ? ca::Operation::OutputCompClustersFlat : ca::Operation::Noop, isEnabled(OutputType::SendClustersPerSector) ? ca::Operation::SendClustersPerSector : ca::Operation::Noop, + isEnabled(OutputType::QA) ? ca::Operation::OutputQA : ca::Operation::Noop, isEnabled(OutputType::Clusters) && (caClusterer || decompressTPC) ? ca::Operation::OutputCAClusters : ca::Operation::Noop, }, tpcSectors)); diff --git a/Detectors/TPC/workflow/src/tpc-reco-workflow.cxx b/Detectors/TPC/workflow/src/tpc-reco-workflow.cxx index 4f084afa6f527..b10b2c08f5293 100644 --- a/Detectors/TPC/workflow/src/tpc-reco-workflow.cxx +++ b/Detectors/TPC/workflow/src/tpc-reco-workflow.cxx @@ -46,7 +46,7 @@ void customize(std::vector& workflowOptions) std::vector options{ {"input-type", VariantType::String, "digits", {"digitizer, digits, zsraw, clustershw, clustersnative, compressed-clusters, compressed-clusters-ctf"}}, - {"output-type", VariantType::String, "tracks", {"digits, zsraw, clustershw, clustersnative, tracks, compressed-clusters, encoded-clusters, disable-writer, send-clusters-per-sector"}}, + {"output-type", VariantType::String, "tracks", {"digits, zsraw, clustershw, clustersnative, tracks, compressed-clusters, encoded-clusters, disable-writer, send-clusters-per-sector, qa"}}, {"no-ca-clusterer", VariantType::Bool, false, {"Use HardwareClusterer instead of clusterer of GPUCATracking"}}, {"disable-mc", VariantType::Bool, false, {"disable sending of MC information"}}, //{"tpc-sectors", VariantType::String, "0-35", {"TPC sector range, e.g. 5-7,8,9"}}, diff --git a/GPU/GPUTracking/Base/GPUSettingsList.h b/GPU/GPUTracking/Base/GPUSettingsList.h index 572cfc27636b8..c116d67c5ceb1 100644 --- a/GPU/GPUTracking/Base/GPUSettingsList.h +++ b/GPU/GPUTracking/Base/GPUSettingsList.h @@ -117,7 +117,6 @@ AddOption(prefetchTPCpageScan, int, 0, "", 0, "Prefetch Data for TPC page scan i AddOption(debugLevel, int, -1, "debug", 'd', "Set debug level (-1 = silend)") AddOption(allocDebugLevel, int, 0, "allocDebug", 0, "Some debug output for memory allocations (without messing with normal debug level)") AddOption(runQA, bool, false, "qa", 'q', "Enable tracking QA", message("Running QA: %s")) -AddOption(QAnoMC, bool, false, "", 0, "Force running QA without MC labels even if present") AddOption(runCompressionStatistics, bool, false, "compressionStat", 0, "Run statistics and verification for cluster compression") AddOption(forceMemoryPoolSize, unsigned long, 1, "memSize", 0, "Force size of allocated GPU / page locked host memory", min(0ul)) AddOption(forceHostMemoryPoolSize, unsigned long, 0, "hostMemSize", 0, "Force size of allocated host page locked host memory (overriding memSize)", min(0ul)) @@ -160,6 +159,8 @@ AddOption(writeMCLabels, bool, false, "", 0, "Store mc labels to file for later AddOptionVec(matchMCLabels, const char*, "", 0, "Read labels from files and match them, only process tracks where labels differ") AddOption(matchDisplayMinPt, float, 0, "", 0, "Minimum Pt of a matched track to be displayed") AddOption(writeRootFiles, bool, false, "", 0, "Create ROOT canvas files") +AddOption(noMC, bool, false, "", 0, "Force running QA without MC labels even if present") +AddOption(forQC, bool, false, "", 0, "Do not write output files but ship histograms for QC") AddShortcut("compare", 0, "--QAinput", "Compare QA histograms", "--qa", "--QAinputHistogramsOnly") AddHelp("help", 'h') EndConfig() diff --git a/GPU/GPUTracking/Interface/GPUO2Interface.cxx b/GPU/GPUTracking/Interface/GPUO2Interface.cxx index 4c65f08a9aaa7..b356e5ba0f32c 100644 --- a/GPU/GPUTracking/Interface/GPUO2Interface.cxx +++ b/GPU/GPUTracking/Interface/GPUO2Interface.cxx @@ -18,6 +18,7 @@ #include "GPUOutputControl.h" #include "GPUO2InterfaceConfiguration.h" #include "GPUParam.inc" +#include "GPUQA.h" #include #include #ifdef WITH_OPENMP @@ -159,6 +160,11 @@ int GPUTPCO2Interface::RunTracking(GPUTrackingInOutPointers* data, GPUInterfaceO outputs->clustersNative.size = mOutputClustersNative->EndOfSpace ? 0 : (mChain->mIOPtrs.clustersNative->nClustersTotal * sizeof(*mChain->mIOPtrs.clustersNative->clustersLinear)); outputs->tpcTracks.size = mOutputCompressedClusters->EndOfSpace ? 0 : (size_t)((char*)mOutputCompressedClusters->OutputPtr - (char*)mOutputCompressedClusters->OutputBase); } + if (mConfig->configQA.forQC) { + outputs->qa.hist1 = &mChain->GetQA()->getHistograms1D(); + outputs->qa.hist2 = &mChain->GetQA()->getHistograms2D(); + outputs->qa.hist3 = &mChain->GetQA()->getHistograms1Dd(); + } *data = mChain->mIOPtrs; nEvent++; diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceConfiguration.h b/GPU/GPUTracking/Interface/GPUO2InterfaceConfiguration.h index eac5c9d7363ec..b3ca1cabe5ab0 100644 --- a/GPU/GPUTracking/Interface/GPUO2InterfaceConfiguration.h +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceConfiguration.h @@ -34,6 +34,10 @@ #include "GPUHostDataTypes.h" #include "DataFormatsTPC/Constants.h" +class TH1F; +class TH1D; +class TH2F; + namespace o2 { namespace tpc @@ -57,11 +61,18 @@ struct GPUInterfaceOutputRegion { std::function allocator = nullptr; }; +struct GPUInterfaceQAOutputs { + const std::vector* hist1; + const std::vector* hist2; + const std::vector* hist3; +}; + struct GPUInterfaceOutputs { GPUInterfaceOutputRegion compressedClusters; GPUInterfaceOutputRegion clustersNative; GPUInterfaceOutputRegion tpcTracks; GPUInterfaceOutputRegion clusterLabels; + GPUInterfaceQAOutputs qa; }; // Full configuration structure with all available settings of GPU... diff --git a/GPU/GPUTracking/Standalone/qa/GPUQA.cxx b/GPU/GPUTracking/Standalone/qa/GPUQA.cxx index 91cf458ba05ac..8d11f67b264ce 100644 --- a/GPU/GPUTracking/Standalone/qa/GPUQA.cxx +++ b/GPU/GPUTracking/Standalone/qa/GPUQA.cxx @@ -214,7 +214,7 @@ inline int GPUQA::GetMCLabelCol(unsigned int i, unsigned int j) { return mTracki inline float GPUQA::GetMCLabelWeight(unsigned int i, unsigned int j) { return 1; } inline float GPUQA::GetMCLabelWeight(const mcLabels_t& label, unsigned int j) { return 1; } inline float GPUQA::GetMCLabelWeight(const mcLabel_t& label) { return 1; } -inline bool GPUQA::mcPresent() { return !mTracking->GetProcessingSettings().QAnoMC && mTracking->mIOPtrs.clustersNative->clustersMCTruth && mNColTracks.size(); } +inline bool GPUQA::mcPresent() { return !mConfig.noMC && mTracking->mIOPtrs.clustersNative->clustersMCTruth && mNColTracks.size(); } #define TRACK_EXPECTED_REFERENCE_X 78 #else inline GPUQA::mcLabelI_t::mcLabelI_t(const GPUQA::mcLabel_t& l) : track(l.fMCID) @@ -240,7 +240,7 @@ inline float GPUQA::GetMCLabelWeight(const mcLabels_t& label, unsigned int j) { inline float GPUQA::GetMCLabelWeight(const mcLabel_t& label) { return label.fWeight; } inline int GPUQA::FakeLabelID(int id) { return id < 0 ? id : (-2 - id); } inline int GPUQA::AbsLabelID(int id) { return id >= 0 ? id : (-id - 2); } -inline bool GPUQA::mcPresent() { return !mTracking->GetProcessingSettings().QAnoMC && GetNMCLabels() && GetNMCTracks(0); } +inline bool GPUQA::mcPresent() { return !mConfig.noMC && GetNMCLabels() && GetNMCTracks(0); } #define TRACK_EXPECTED_REFERENCE_X 81 #endif template @@ -278,7 +278,7 @@ GPUQA::GPUQA(GPUChainTracking* chain) : mTracking(chain), mConfig(GPUQA_GetConfi mHist1D.reset(new std::vector); mHist2D.reset(new std::vector); mHist1Dd.reset(new std::vector); - mRunForQC = chain == nullptr; + mRunForQC = chain == nullptr || mConfig.forQC; } GPUQA::~GPUQA() = default; From cd68a297f24c12a1814bfac1f54072efaa12e0e4 Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 10 Nov 2020 20:46:19 +0100 Subject: [PATCH 5/6] GPU: Add TrackingQAInterface to perform postprocessing independently from tracking --- GPU/GPUTracking/CMakeLists.txt | 4 +- GPU/GPUTracking/GPUTrackingLinkDef_O2.h | 1 + .../Interface/GPUO2InterfaceQA.cxx | 32 ++++ GPU/GPUTracking/Interface/GPUO2InterfaceQA.h | 54 +++++++ GPU/GPUTracking/Standalone/qa/GPUQA.cxx | 150 +++++++++++++----- GPU/GPUTracking/Standalone/qa/GPUQA.h | 19 ++- 6 files changed, 212 insertions(+), 48 deletions(-) create mode 100644 GPU/GPUTracking/Interface/GPUO2InterfaceQA.cxx create mode 100644 GPU/GPUTracking/Interface/GPUO2InterfaceQA.h diff --git a/GPU/GPUTracking/CMakeLists.txt b/GPU/GPUTracking/CMakeLists.txt index 7daaa1eceef1b..dec5d3d5686b0 100644 --- a/GPU/GPUTracking/CMakeLists.txt +++ b/GPU/GPUTracking/CMakeLists.txt @@ -135,8 +135,8 @@ set(HDRS_INSTALL # Sources only for O2 if(ALIGPU_BUILD_TYPE STREQUAL "O2") - set(SRCS ${SRCS} Interface/GPUO2Interface.cxx Interface/GPUO2InterfaceRefit.cxx Interface/GPUO2InterfaceConfigurableParam.cxx) - set(HDRS_CINT_O2 ${HDRS_CINT_O2} Interface/GPUO2Interface.h Interface/GPUO2InterfaceRefit.h Interface/GPUO2InterfaceConfigurableParam.h dEdx/TPCdEdxCalibrationSplines.h) + set(SRCS ${SRCS} Interface/GPUO2Interface.cxx Interface/GPUO2InterfaceRefit.cxx Interface/GPUO2InterfaceQA.cxx Interface/GPUO2InterfaceConfigurableParam.cxx) + set(HDRS_CINT_O2 ${HDRS_CINT_O2} Interface/GPUO2Interface.h Interface/GPUO2InterfaceRefit.h Interface/GPUO2InterfaceQA.h Interface/GPUO2InterfaceConfigurableParam.h dEdx/TPCdEdxCalibrationSplines.h) set(HDRS_CINT_O2_ADDITIONAL Base/GPUSettings.h Base/GPUSettingsList.h) # Manual depencies for ROOT dictionary generation endif() diff --git a/GPU/GPUTracking/GPUTrackingLinkDef_O2.h b/GPU/GPUTracking/GPUTrackingLinkDef_O2.h index 93c1c854de59e..fe035e5a71a45 100644 --- a/GPU/GPUTracking/GPUTrackingLinkDef_O2.h +++ b/GPU/GPUTracking/GPUTrackingLinkDef_O2.h @@ -19,6 +19,7 @@ #pragma link C++ class o2::gpu::GPUTPCO2Interface + ; #pragma link C++ class o2::gpu::GPUTPCO2InterfaceRefit + ; +#pragma link C++ class o2::gpu::GPUO2InterfaceQA + ; #pragma link C++ class o2::gpu::TPCdEdxCalibrationSplines + ; #pragma link C++ class o2::gpu::GPUConfigurableParamGPUSettingsO2 + ; #pragma link C++ class o2::gpu::GPUConfigurableParamGPUSettingsRec + ; diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceQA.cxx b/GPU/GPUTracking/Interface/GPUO2InterfaceQA.cxx new file mode 100644 index 0000000000000..a30db8bef77a8 --- /dev/null +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceQA.cxx @@ -0,0 +1,32 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file GPUO2InterfaceQA.cxx +/// \author David Rohr + +#include "GPUQA.h" +#include "GPUO2InterfaceQA.h" + +using namespace o2::gpu; +using namespace o2::tpc; + +GPUO2InterfaceQA::GPUO2InterfaceQA(const GPUSettingsQA* config) : mQA(new GPUQA(nullptr, config)) +{ +} + +GPUO2InterfaceQA::~GPUO2InterfaceQA() = default; + +int GPUO2InterfaceQA::postprocess(std::vector& in1, std::vector& in2, std::vector& in3, TObjArray& out) +{ + if (mQA->loadHistograms(in1, in2, in3)) { + return 1; + } + return mQA->DrawQAHistograms(&out); +} diff --git a/GPU/GPUTracking/Interface/GPUO2InterfaceQA.h b/GPU/GPUTracking/Interface/GPUO2InterfaceQA.h new file mode 100644 index 0000000000000..83f0d00e3f018 --- /dev/null +++ b/GPU/GPUTracking/Interface/GPUO2InterfaceQA.h @@ -0,0 +1,54 @@ +// Copyright CERN and copyright holders of ALICE O2. This software is +// distributed under the terms of the GNU General Public License v3 (GPL +// Version 3), copied verbatim in the file "COPYING". +// +// See http://alice-o2.web.cern.ch/license for full licensing information. +// +// In applying this license CERN does not waive the privileges and immunities +// granted to it by virtue of its status as an Intergovernmental Organization +// or submit itself to any jurisdiction. + +/// \file GPUO2InterfaceQA.h +/// \author David Rohr + +#ifndef GPUO2INTERFACEQA_H +#define GPUO2INTERFACEQA_H + +// Some defines denoting that we are compiling for O2 +#ifndef HAVE_O2HEADERS +#define HAVE_O2HEADERS +#endif +#ifndef GPUCA_TPC_GEOMETRY_O2 +#define GPUCA_TPC_GEOMETRY_O2 +#endif +#ifndef GPUCA_O2_INTERFACE +#define GPUCA_O2_INTERFACE +#endif + +#include +#include + +class TH1F; +class TH1D; +class TH2F; +class TObjArray; + +namespace o2::gpu +{ +class GPUQA; +class GPUSettingsQA; +class GPUO2InterfaceQA +{ + public: + GPUO2InterfaceQA(const GPUSettingsQA* config = nullptr); + ~GPUO2InterfaceQA(); + + // Input might be modified, so we assume non-const. If it is const, a copy should be created before. + int postprocess(std::vector& in1, std::vector& in2, std::vector& in3, TObjArray& out); + + private: + std::unique_ptr mQA; +}; +} // namespace o2::gpu + +#endif diff --git a/GPU/GPUTracking/Standalone/qa/GPUQA.cxx b/GPU/GPUTracking/Standalone/qa/GPUQA.cxx index 8d11f67b264ce..3ee8e480e2f7f 100644 --- a/GPU/GPUTracking/Standalone/qa/GPUQA.cxx +++ b/GPU/GPUTracking/Standalone/qa/GPUQA.cxx @@ -26,6 +26,7 @@ #include "TTree.h" #include "TStyle.h" #include "TLatex.h" +#include "TObjArray.h" #include #include "GPUQA.h" @@ -214,7 +215,7 @@ inline int GPUQA::GetMCLabelCol(unsigned int i, unsigned int j) { return mTracki inline float GPUQA::GetMCLabelWeight(unsigned int i, unsigned int j) { return 1; } inline float GPUQA::GetMCLabelWeight(const mcLabels_t& label, unsigned int j) { return 1; } inline float GPUQA::GetMCLabelWeight(const mcLabel_t& label) { return 1; } -inline bool GPUQA::mcPresent() { return !mConfig.noMC && mTracking->mIOPtrs.clustersNative->clustersMCTruth && mNColTracks.size(); } +inline bool GPUQA::mcPresent() { return !mConfig.noMC && mTracking && mTracking->mIOPtrs.clustersNative->clustersMCTruth && mNColTracks.size(); } #define TRACK_EXPECTED_REFERENCE_X 78 #else inline GPUQA::mcLabelI_t::mcLabelI_t(const GPUQA::mcLabel_t& l) : track(l.fMCID) @@ -240,7 +241,7 @@ inline float GPUQA::GetMCLabelWeight(const mcLabels_t& label, unsigned int j) { inline float GPUQA::GetMCLabelWeight(const mcLabel_t& label) { return label.fWeight; } inline int GPUQA::FakeLabelID(int id) { return id < 0 ? id : (-2 - id); } inline int GPUQA::AbsLabelID(int id) { return id >= 0 ? id : (-id - 2); } -inline bool GPUQA::mcPresent() { return !mConfig.noMC && GetNMCLabels() && GetNMCTracks(0); } +inline bool GPUQA::mcPresent() { return !mConfig.noMC && mTracking && GetNMCLabels() && GetNMCTracks(0); } #define TRACK_EXPECTED_REFERENCE_X 81 #endif template @@ -250,38 +251,51 @@ inline auto& GPUQA::GetMCTrackObj(T& obj, const GPUQA::mcLabelI_t& l) } template <> -auto GPUQA::getHist() +auto GPUQA::getHistArray() { - return std::make_pair(&mHist1D, &mHist1D_pos); + return std::make_pair(mHist1D, &mHist1D_pos); } template <> -auto GPUQA::getHist() +auto GPUQA::getHistArray() { - return std::make_pair(&mHist2D, &mHist2D_pos); + return std::make_pair(mHist2D, &mHist2D_pos); } template <> -auto GPUQA::getHist() +auto GPUQA::getHistArray() { - return std::make_pair(&mHist1Dd, &mHist1Dd_pos); + return std::make_pair(mHist1Dd, &mHist1Dd_pos); } template -void GPUQA::createHist(T*& h, Args... args) +void GPUQA::createHist(T*& h, const char* name, Args... args) { - const auto& p = getHist(); - p.first->get()->emplace_back(args...); + const auto& p = getHistArray(); + if (mHaveExternalHists) { + if (p.first->size() <= p.second->size()) { + throw std::runtime_error("Incoming histogram array incomplete"); + } + if (strcmp((*p.first)[p.second->size()].GetName(), name)) { + throw std::runtime_error("Incoming histogram has incorrect name"); + } + } else { + p.first->emplace_back(name, args...); + } p.second->emplace_back(&h); - h = &p.first->get()->back(); + h = &p.first->back(); } -GPUQA::GPUQA(GPUChainTracking* chain) : mTracking(chain), mConfig(GPUQA_GetConfig(chain)) +GPUQA::GPUQA(GPUChainTracking* chain, const GPUSettingsQA* config) : mTracking(chain), mConfig(config ? *config : GPUQA_GetConfig(chain)) { - mHist1D.reset(new std::vector); - mHist2D.reset(new std::vector); - mHist1Dd.reset(new std::vector); mRunForQC = chain == nullptr || mConfig.forQC; } -GPUQA::~GPUQA() = default; +GPUQA::~GPUQA() +{ + if (mQAInitialized && !mHaveExternalHists) { + delete mHist1D; + delete mHist2D; + delete mHist1Dd; + } +} inline bool GPUQA::MCComp(const mcLabel_t& a, const mcLabel_t& b) { return (GPUQA::GetMCLabelID(a) > GPUQA::GetMCLabelID(b)); } @@ -384,7 +398,9 @@ int GPUQA::InitQACreateHistograms() } else { createHist(mEff[i][j][k][l][m], name, name, AXIS_BINS[l], AXES_MIN[l], AXES_MAX[l]); } - mEff[i][j][k][l][m]->Sumw2(); + if (!mHaveExternalHists) { + mEff[i][j][k][l][m]->Sumw2(); + } } } } @@ -472,19 +488,43 @@ int GPUQA::InitQACreateHistograms() return 0; } +int GPUQA::loadHistograms(std::vector& i1, std::vector& i2, std::vector& i3) +{ + if (mQAInitialized) { + return 1; + } + mHist1D = &i1; + mHist2D = &i2; + mHist1Dd = &i3; + mHist1D_pos.clear(); + mHist2D_pos.clear(); + mHist1Dd_pos.clear(); + mHaveExternalHists = true; + if (InitQACreateHistograms()) { + return 1; + } + mQAInitialized = true; + return 0; +} + int GPUQA::InitQA() { if (mQAInitialized) { return 1; } + mHist1D = new std::vector; + mHist2D = new std::vector; + mHist1Dd = new std::vector; + mColorNums.resize(COLORCOUNT); + mColors.reserve(COLORCOUNT); for (int i = 0; i < COLORCOUNT; i++) { float f1 = (float)((COLORS_HEX[i] >> 16) & 0xFF) / (float)0xFF; float f2 = (float)((COLORS_HEX[i] >> 8) & 0xFF) / (float)0xFF; float f3 = (float)((COLORS_HEX[i] >> 0) & 0xFF) / (float)0xFF; - TColor* c = new TColor(10000 + i, f1, f2, f3); - mColorNums[i] = c->GetNumber(); + mColors.emplace_back(10000 + i, f1, f2, f3); + mColorNums[i] = mColors.back().GetNumber(); } if (InitQACreateHistograms()) { @@ -1589,7 +1629,7 @@ T* GPUQA::GetHist(T*& ee, std::vector& tin, int k, int nNewInput) return (e); } -int GPUQA::DrawQAHistograms() +int GPUQA::DrawQAHistograms(TObjArray* qcout) { if (!mQAInitialized) { return 1; @@ -1755,12 +1795,16 @@ int GPUQA::DrawQAHistograms() } } + int flagShowVsPtLog = mRunForQC ? 0 : 1; + // Process / Draw Efficiency Histograms - for (int ii = 0; ii < 6; ii++) { + for (int ii = 0; ii < 5 + flagShowVsPtLog; ii++) { int i = ii == 5 ? 4 : ii; for (int k = 0; k < ConfigNumInputs; k++) { for (int j = 0; j < 4; j++) { - mPEff[ii][j]->cd(); + if (!mRunForQC) { + mPEff[ii][j]->cd(); + } for (int l = 0; l < 3; l++) { if (k == 0 && mConfig.inputHistogramsOnly == 0 && ii != 5) { if (l == 0) { @@ -1796,14 +1840,17 @@ int GPUQA::DrawQAHistograms() e->GetYaxis()->SetTitle("(Efficiency)"); e->GetXaxis()->SetTitle(XAXIS_TITLES[i]); - e->SetMarkerColor(kBlack); e->SetLineWidth(1); - e->SetLineColor(mColorNums[(l == 2 ? (ConfigNumInputs * 2 + k) : (k * 2 + l)) % COLORCOUNT]); e->SetLineStyle(CONFIG_DASHED_MARKERS ? k + 1 : 1); SetAxisSize(e); + if (qcout) { + qcout->Add(e); + } if (mRunForQC) { continue; } + e->SetMarkerColor(kBlack); + e->SetLineColor(mColorNums[(l == 2 ? (ConfigNumInputs * 2 + k) : (k * 2 + l)) % COLORCOUNT]); e->Draw(k || l ? "same" : ""); if (j == 0) { GetName(fname, k); @@ -1839,7 +1886,7 @@ int GPUQA::DrawQAHistograms() TH1D *resIntegral[5] = {}, *pullIntegral[5] = {}; TF1* customGaus = new TF1("G", "[0]*exp(-(x-[1])*(x-[1])/(2.*[2]*[2]))"); for (int p = 0; p < 2; p++) { - for (int ii = 0; ii < 6; ii++) { + for (int ii = 0; ii < 5 + flagShowVsPtLog; ii++) { TCanvas* can = p ? mCPull[ii] : mCRes[ii]; TLegend* leg = p ? mLPull[ii] : mLRes[ii]; int i = ii == 5 ? 4 : ii; @@ -2001,9 +2048,7 @@ int GPUQA::DrawQAHistograms() } e->SetMaximum(tmpMax); e->SetMinimum(tmpMin); - e->SetMarkerColor(kBlack); e->SetLineWidth(1); - e->SetLineColor(mColorNums[numColor++ % COLORCOUNT]); e->SetLineStyle(CONFIG_DASHED_MARKERS ? k + 1 : 1); SetAxisSize(e); e->GetYaxis()->SetTitle(p ? AXIS_TITLES_PULL[j] : mConfig.nativeFitResolutions ? AXIS_TITLES_NATIVE[j] : AXIS_TITLES[j]); @@ -2017,10 +2062,15 @@ int GPUQA::DrawQAHistograms() } else if (j < 3) { e->GetYaxis()->SetTitleOffset(1.4); } + if (qcout) { + qcout->Add(e); + } if (mRunForQC) { continue; } + e->SetMarkerColor(kBlack); + e->SetLineColor(mColorNums[numColor++ % COLORCOUNT]); e->Draw(k || l ? "same" : ""); if (j == 0) { GetName(fname, k); @@ -2068,7 +2118,9 @@ int GPUQA::DrawQAHistograms() TPad* pad = p ? mPPull[6][i] : mPRes[6][i]; TH1D* hist = p ? pullIntegral[i] : resIntegral[i]; int numColor = 0; - pad->cd(); + if (!mRunForQC) { + pad->cd(); + } if (!mConfig.inputHistogramsOnly && mcAvail) { TH1D* e = hist; e->GetEntries(); @@ -2094,16 +2146,22 @@ int GPUQA::DrawQAHistograms() } e->SetMaximum(tmpMax * 1.02); e->SetMinimum(tmpMax * -0.02); - e->SetLineColor(mColorNums[numColor++ % COLORCOUNT]); if (tout && !mConfig.inputHistogramsOnly && k == 0) { e->Write(); } + if (qcout) { + qcout->Add(e); + } if (mRunForQC) { continue; } + e->SetLineColor(mColorNums[numColor++ % COLORCOUNT]); e->Draw(k == 0 ? "" : "same"); } + if (mRunForQC) { + continue; + } can->cd(); } if (mRunForQC) { @@ -2230,8 +2288,10 @@ int GPUQA::DrawQAHistograms() } for (int i = 0; i < N_CLS_TYPE; i++) { - mPClust[i]->cd(); - mPClust[i]->SetLogx(); + if (!mRunForQC) { + mPClust[i]->cd(); + mPClust[i]->SetLogx(); + } int begin = i == 2 ? (2 * N_CLS_HIST - 1) : i == 1 ? N_CLS_HIST : 0; int end = i == 2 ? (3 * N_CLS_HIST - 1) : i == 1 ? (2 * N_CLS_HIST - 1) : N_CLS_HIST; int numColor = 0; @@ -2251,17 +2311,20 @@ int GPUQA::DrawQAHistograms() e->Write(); } e->SetStats(kFALSE); - e->SetMarkerColor(kBlack); e->SetLineWidth(1); - e->SetLineColor(mColorNums[numColor++ % COLORCOUNT]); e->SetLineStyle(CONFIG_DASHED_MARKERS ? j + 1 : 1); if (i == 0) { e->GetXaxis()->SetRange(2, AXIS_BINS[4]); } + if (qcout) { + qcout->Add(e); + } if (mRunForQC) { continue; } + e->SetMarkerColor(kBlack); + e->SetLineColor(mColorNums[numColor++ % COLORCOUNT]); e->Draw(j == end - 1 && k == 0 ? "" : "same"); GetName(fname, k); sprintf(name, "%s%s", fname, CLUSTER_NAMES[j - begin]); @@ -2271,11 +2334,14 @@ int GPUQA::DrawQAHistograms() if (ConfigNumInputs == 1) { TH1* e = reinterpret_cast(mClusters[begin + CL_att_adj]->Clone()); e->Add(mClusters[begin + CL_prot], -1); - e->SetLineColor(mColorNums[numColor++ % COLORCOUNT]); + if (qcout) { + qcout->Add(e); + } if (mRunForQC) { continue; } + e->SetLineColor(mColorNums[numColor++ % COLORCOUNT]); e->Draw("same"); mLClust[i]->AddEntry(e, "Removed", "l"); } @@ -2321,11 +2387,14 @@ int GPUQA::DrawQAHistograms() e->SetMaximum(tmpMax * 1.02); e->SetMinimum(tmpMax * -0.02); e->SetStats(kFALSE); - e->SetMarkerColor(kBlack); e->SetLineWidth(1); - e->SetLineColor(mColorNums[k % COLORCOUNT]); e->GetYaxis()->SetTitle("a.u."); e->GetXaxis()->SetTitle("#it{p}_{Tmc} (GeV/#it{c})"); + if (qcout) { + qcout->Add(e); + } + e->SetMarkerColor(kBlack); + e->SetLineColor(mColorNums[k % COLORCOUNT]); e->Draw(k == 0 ? "" : "same"); GetName(fname, k); sprintf(name, "%sTrack Pt", fname); @@ -2360,11 +2429,14 @@ int GPUQA::DrawQAHistograms() e->SetMaximum(tmpMax * 1.02); e->SetMinimum(tmpMax * -0.02); e->SetStats(kFALSE); - e->SetMarkerColor(kBlack); e->SetLineWidth(1); - e->SetLineColor(mColorNums[k % COLORCOUNT]); e->GetYaxis()->SetTitle("a.u."); e->GetXaxis()->SetTitle("NClusters"); + if (qcout) { + qcout->Add(e); + } + e->SetMarkerColor(kBlack); + e->SetLineColor(mColorNums[k % COLORCOUNT]); e->Draw(k == 0 ? "" : "same"); GetName(fname, k); sprintf(name, "%sNClusters", fname); diff --git a/GPU/GPUTracking/Standalone/qa/GPUQA.h b/GPU/GPUTracking/Standalone/qa/GPUQA.h index e37310af68fc1..89dd94c6c9f1e 100644 --- a/GPU/GPUTracking/Standalone/qa/GPUQA.h +++ b/GPU/GPUTracking/Standalone/qa/GPUQA.h @@ -25,6 +25,8 @@ class TPad; class TH1; class TFile; class TH1D; +class TObjArray; +class TColor; typedef short int Color_t; #if !defined(GPUCA_BUILD_QA) || defined(GPUCA_GPUCODE) @@ -82,12 +84,12 @@ class GPUQA { public: GPUQA(); - GPUQA(GPUChainTracking* chain); + GPUQA(GPUChainTracking* chain, const GPUSettingsQA* config = nullptr); ~GPUQA(); int InitQA(); void RunQA(bool matchOnly = false); - int DrawQAHistograms(); + int DrawQAHistograms(TObjArray* qcout = nullptr); void SetMCTrackRange(int min, int max); bool SuppressTrack(int iTrack) const; bool SuppressHit(int iHit) const; @@ -100,6 +102,7 @@ class GPUQA const std::vector& getHistograms1D() const { return *mHist1D; } const std::vector& getHistograms2D() const { return *mHist2D; } const std::vector& getHistograms1Dd() const { return *mHist1Dd; } + int loadHistograms(std::vector& i1, std::vector& i2, std::vector& i3); static constexpr int N_CLS_HIST = 8; static constexpr int N_CLS_TYPE = 3; @@ -251,16 +254,17 @@ class GPUQA TPad* mPNCl; TLegend* mLNCl; - std::unique_ptr> mHist1D{}; - std::unique_ptr> mHist2D{}; - std::unique_ptr> mHist1Dd{}; + std::vector* mHist1D = nullptr; + std::vector* mHist2D = nullptr; + std::vector* mHist1Dd = nullptr; + bool mHaveExternalHists = false; std::vector mHist1D_pos{}; std::vector mHist2D_pos{}; std::vector mHist1Dd_pos{}; template - auto getHist(); + auto getHistArray(); template - void createHist(T*& h, Args... args); + void createHist(T*& h, const char* name, Args... args); int mNEvents = 0; bool mQAInitialized = false; @@ -270,6 +274,7 @@ class GPUQA std::vector> mGoodHits; std::vector mColorNums; + std::vector mColors; int mMCTrackMin = -1, mMCTrackMax = -1; }; From f2f234b323693c56d620f15ff9adb7289f64230b Mon Sep 17 00:00:00 2001 From: David Rohr Date: Tue, 10 Nov 2020 22:07:02 +0100 Subject: [PATCH 6/6] TPC Workflow: apply postprocessing to TPC QA histograms before shipping as external to QC --- Detectors/TPC/workflow/src/CATrackerSpec.cxx | 20 +++++++++++--------- GPU/GPUTracking/Standalone/qa/GPUQA.cxx | 2 +- 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/Detectors/TPC/workflow/src/CATrackerSpec.cxx b/Detectors/TPC/workflow/src/CATrackerSpec.cxx index 97a196aadbc60..bd5be552fabff 100644 --- a/Detectors/TPC/workflow/src/CATrackerSpec.cxx +++ b/Detectors/TPC/workflow/src/CATrackerSpec.cxx @@ -42,6 +42,7 @@ #include "DetectorsRaw/HBFUtils.h" #include "TPCBase/RDHUtils.h" #include "GPUO2InterfaceConfiguration.h" +#include "GPUO2InterfaceQA.h" #include "TPCCFCalibration.h" #include "GPUDisplayBackend.h" #ifdef GPUCA_BUILD_EVENT_DISPLAY @@ -100,6 +101,8 @@ DataProcessorSpec getCATrackerSpec(CompletionPolicyData* policyData, ca::Config std::unique_ptr fastTransform; std::unique_ptr dEdxSplines; std::unique_ptr tpcCalibration; + std::unique_ptr qaConfig; + std::unique_ptr qa; std::vector clusterOutputIds; unsigned long outputBufferSize = 0; unsigned long tpcSectorMask = 0; @@ -242,6 +245,10 @@ DataProcessorSpec getCATrackerSpec(CompletionPolicyData* policyData, ca::Config if (tracker->initialize(config) != 0) { throw std::invalid_argument("GPUCATracking initialization failed"); } + if (specconfig.outputQA) { + processAttributes->qaConfig.reset(new GPUSettingsQA(config.configQA)); + processAttributes->qa = std::make_unique(processAttributes->qaConfig.get()); + } timer.Stop(); timer.Reset(); } @@ -701,15 +708,10 @@ DataProcessorSpec getCATrackerSpec(CompletionPolicyData* policyData, ca::Config } if (specconfig.outputQA) { TObjArray out; - for (unsigned int i = 0; i < outputRegions.qa.hist1->size(); i++) { - out.Add((TObject*)&(*outputRegions.qa.hist1)[i]); // FIXME: Fundamentally broken, we cannot add the const object, but QC doesn't accept the std::vector - } - for (unsigned int i = 0; i < outputRegions.qa.hist2->size(); i++) { - out.Add((TObject*)&(*outputRegions.qa.hist2)[i]); - } - for (unsigned int i = 0; i < outputRegions.qa.hist3->size(); i++) { - out.Add((TObject*)&(*outputRegions.qa.hist3)[i]); - } + std::vector copy1 = *outputRegions.qa.hist1; // Internally, this will also be used as output, so we need a non-const copy + std::vector copy2 = *outputRegions.qa.hist2; + std::vector copy3 = *outputRegions.qa.hist3; + processAttributes->qa->postprocess(copy1, copy2, copy3, out); pc.outputs().snapshot({gDataOriginTPC, "TRACKINGQA", 0, Lifetime::Timeframe}, out); } timer.Stop(); diff --git a/GPU/GPUTracking/Standalone/qa/GPUQA.cxx b/GPU/GPUTracking/Standalone/qa/GPUQA.cxx index 3ee8e480e2f7f..50d3db0f8569c 100644 --- a/GPU/GPUTracking/Standalone/qa/GPUQA.cxx +++ b/GPU/GPUTracking/Standalone/qa/GPUQA.cxx @@ -516,7 +516,7 @@ int GPUQA::InitQA() mHist1D = new std::vector; mHist2D = new std::vector; mHist1Dd = new std::vector; - + mColorNums.resize(COLORCOUNT); mColors.reserve(COLORCOUNT); for (int i = 0; i < COLORCOUNT; i++) {