Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Detectors/TPC/qc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,19 @@

o2_add_library(TPCQC
SOURCES src/PID.cxx
src/Tracking.cxx
src/Helpers.cxx
src/TrackCuts.cxx
src/Clusters.cxx
src/Tracks.cxx
PUBLIC_LINK_LIBRARIES O2::TPCBase
O2::DataFormatsTPC)
O2::DataFormatsTPC
O2::GPUTracking)


o2_target_root_dictionary(TPCQC
HEADERS include/TPCQC/PID.h
include/TPCQC/Tracking.h
include/TPCQC/Helpers.h
include/TPCQC/TrackCuts.h
include/TPCQC/Clusters.h
Expand Down
90 changes: 90 additions & 0 deletions Detectors/TPC/qc/include/TPCQC/Tracking.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
// 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 Tracking.h
/// @author David Rohr
///

#ifndef AliceO2_TPC_QC_TRACKING_H
#define AliceO2_TPC_QC_TRACKING_H

#include <vector>
#include <memory>

class TH1F;
class TH2F;
class TH1D;

//o2 includes
#include "DataFormatsTPC/Defs.h"

namespace o2
{
class MCCompLabel;
namespace gpu
{
class GPUO2InterfaceQA;
} // namespace gpu
namespace tpc
{
class TrackTPC;
struct ClusterNativeAccess;

namespace qc
{
// Class for tracking QA (efficiency / resolution)
// Some settings can be steered via --configKeyValues: (See GPUSettingsList.h for actual definitions). Relevant QA parameters are:
// "GPU_QA.strict=[bool]" Strict QA mode: Only consider resolution of tracks where the fit ended within 5 cm of the reference, and remove outliers. (Default: true)
// "GPU_QA.qpt=[float]" Set cut for Q/Pt. (Default: 10.0)
// "GPU_QA.recThreshold=[float]" Compute the efficiency including impure tracks with fake contamination. (Default 0.9)
// "GPU_QA.maxResX=[float]" Maxmimum X (~radius) for reconstructed track position to take into accound for resolution QA in cm (Default: no limit)
// "GPU_QA.nativeFitResolutions=[bool]" Create resolution histograms in the native fit units (sin(phi), tan(lambda), Q/Pt) (Default: false)
// "GPU_QA.filterCharge=[int]" Filter for positive (+1) or negative (-1) charge (Default: no filter)
// "GPU_QA.filterPID=[int]" Filter for Particle Type (0 Electron, 1 Muon, 2 Pion, 3 Kaon, 4 Proton) (Default: no filter)

class Tracking
{
public:
/// default constructor
Tracking();
~Tracking();

enum outputModes {
outputMergeable, // output mergeaable histogrems, which can be merged and then postprocessed
outputPostprocessed, // directly postprocess the histograms before merging
outputLayout // arrange postprocessed histograms in predefined layouts
};

// Initiaalize
// postprocessOnly = false: initialize to run the full QA via processTracks function.
// postprocessOnly = true : cannot process tracks but only postprocess mergeeablee histogrems in postprocess function, output type must be outputPostprocessed or outputLayout.
void initialize(outputModes outputMode, bool postprocessOnly = false);

void processTracks(const std::vector<o2::tpc::TrackTPC>* tracks, const std::vector<o2::MCCompLabel>* tracksMC, const o2::tpc::ClusterNativeAccess* clNative, TObjArray* out = nullptr);
int postprocess(std::vector<TH1F>& in1, std::vector<TH2F>& in2, std::vector<TH1D>& in3, TObjArray& out); // Inputs are modified, thus must not be const

/// Reset all histograms
void resetHistograms();

/// get histograms
void getHists(const std::vector<TH1F>*& h1, const std::vector<TH2F>*& h2, const std::vector<TH1D>*& h3) const;

private:
std::unique_ptr<o2::gpu::GPUO2InterfaceQA> mQA; //!
outputModes mOutputMode;

ClassDefNV(Tracking, 1)
};
} // namespace qc
} // namespace tpc
} // namespace o2

#endif
1 change: 1 addition & 0 deletions Detectors/TPC/qc/src/TPCQCLinkDef.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#pragma link off all functions;

#pragma link C++ class o2::tpc::qc::PID+;
#pragma link C++ class o2::tpc::qc::Tracking + ;
#pragma link C++ class o2::tpc::qc::TrackCuts+;
#pragma link C++ class o2::tpc::qc::Clusters+;
#pragma link C++ class o2::tpc::qc::Tracks+;
Expand Down
77 changes: 77 additions & 0 deletions Detectors/TPC/qc/src/Tracking.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
// 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 Tracking.cxx
/// \author David Rohr

#define _USE_MATH_DEFINES

#include <cmath>

//root includes
#include "TStyle.h"
#include "TFile.h"
#include "TCanvas.h"
#include "TH1F.h"
#include "TH2F.h"
#include "TH1D.h"

//o2 includes
#include "DataFormatsTPC/TrackTPC.h"
#include "TPCQC/Tracking.h"
#include "GPUO2InterfaceQA.h"
#include "GPUO2InterfaceConfiguration.h"

ClassImp(o2::tpc::qc::Tracking);

using namespace o2::tpc::qc;
using namespace o2::gpu;

Tracking::Tracking() = default;
Tracking::~Tracking() = default;

static constexpr int QAMODE = 7;

//______________________________________________________________________________
void Tracking::initialize(outputModes outputMode, bool postprocessOnly)
{
mOutputMode = outputMode;
GPUO2InterfaceConfiguration config;
config.configQA.shipToQCAsCanvas = mOutputMode == outputLayout;
mQA = std::make_unique<GPUO2InterfaceQA>(&config.configQA);
if (!postprocessOnly) {
mQA->initializeForProcessing(QAMODE);
}
}

//______________________________________________________________________________
void Tracking::resetHistograms()
{
mQA->resetHists();
}

//______________________________________________________________________________
void Tracking::processTracks(const std::vector<o2::tpc::TrackTPC>* tracks, const std::vector<o2::MCCompLabel>* tracksMC, const o2::tpc::ClusterNativeAccess* clNative, TObjArray* out)
{
mQA->runQA(tracks, tracksMC, clNative);
if (mOutputMode == outputPostprocessed || mOutputMode == outputLayout) {
mQA->postprocess(*out);
}
}

int Tracking::postprocess(std::vector<TH1F>& in1, std::vector<TH2F>& in2, std::vector<TH1D>& in3, TObjArray& out)
{
return mQA->postprocessExternal(in1, in2, in3, out, QAMODE);
}

void Tracking::getHists(const std::vector<TH1F>*& h1, const std::vector<TH2F>*& h2, const std::vector<TH1D>*& h3) const
{
mQA->getHists(h1, h2, h3);
}
12 changes: 9 additions & 3 deletions Detectors/TPC/workflow/src/CATrackerSpec.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ DataProcessorSpec getCATrackerSpec(CompletionPolicyData* policyData, ca::Config
std::unique_ptr<TPCdEdxCalibrationSplines> dEdxSplines;
std::unique_ptr<TPCCFCalibration> tpcCalibration;
std::unique_ptr<GPUSettingsQA> qaConfig;
int qaTaskMask = 0;
std::unique_ptr<GPUO2InterfaceQA> qa;
std::vector<int> clusterOutputIds;
unsigned long outputBufferSize = 0;
Expand Down Expand Up @@ -162,10 +163,15 @@ DataProcessorSpec getCATrackerSpec(CompletionPolicyData* policyData, ca::Config
}
config.configProcessing.runMC = specconfig.processMC;
if (specconfig.outputQA) {
if (!specconfig.processMC) {
throw std::runtime_error("Need MC information to create QA plots");
}
config.configQA.shipToQC = true;
if (!config.configProcessing.runQA) {
config.configQA.shipToQC = true;
config.configQA.enableLocalOutput = false;
processAttributes->qaTaskMask = 15;
config.configProcessing.runQA = -processAttributes->qaTaskMask;
}
config.configProcessing.runQA = true;
}
config.configReconstruction.NWaysOuter = true;
config.configInterface.outputToExternalBuffers = true;
Expand Down Expand Up @@ -711,7 +717,7 @@ DataProcessorSpec getCATrackerSpec(CompletionPolicyData* policyData, ca::Config
std::vector<TH1F> copy1 = *outputRegions.qa.hist1; // Internally, this will also be used as output, so we need a non-const copy
std::vector<TH2F> copy2 = *outputRegions.qa.hist2;
std::vector<TH1D> copy3 = *outputRegions.qa.hist3;
processAttributes->qa->postprocess(copy1, copy2, copy3, out);
processAttributes->qa->postprocessExternal(copy1, copy2, copy3, out, processAttributes->qaTaskMask ? processAttributes->qaTaskMask : -1);
pc.outputs().snapshot({gDataOriginTPC, "TRACKINGQA", 0, Lifetime::Timeframe}, out);
processAttributes->qa->cleanup();
}
Expand Down
3 changes: 2 additions & 1 deletion GPU/GPUTracking/Base/GPUSettingsList.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,7 @@ AddOption(doublePipeline, bool, false, "", 0, "Double pipeline mode")
AddOption(prefetchTPCpageScan, int, 0, "", 0, "Prefetch Data for TPC page scan in CPU cache")
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(runQA, int, 0, "qa", 'q', "Enable tracking QA (negative number to provide bitmask for QA tasks)", message("Running QA: %d"), def(1))
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))
Expand Down Expand Up @@ -168,6 +168,7 @@ AddOption(writeRootFiles, bool, false, "", 0, "Create ROOT canvas files")
AddOption(noMC, bool, false, "", 0, "Force running QA without MC labels even if present")
AddOption(shipToQC, bool, false, "", 0, "Do not write output files but ship histograms for QC")
AddOption(shipToQCAsCanvas, bool, false, "", 0, "Send TCanvases with full layout to QC instead of individual histograms")
AddOption(enableLocalOutput, bool, true, "", 0, "Enable normal output to local PDF files / console")
AddShortcut("compare", 0, "--QAinput", "Compare QA histograms", "--qa", "--QAinputHistogramsOnly")
AddHelp("help", 'h')
EndConfig()
Expand Down
2 changes: 1 addition & 1 deletion GPU/GPUTracking/Global/GPUChainTracking.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2400,7 +2400,7 @@ int GPUChainTracking::RunChain()
}
const bool needQA = GPUQA::QAAvailable() && (GetProcessingSettings().runQA || (GetProcessingSettings().eventDisplay && mIOPtrs.nMCInfosTPC));
if (needQA && mQA->IsInitialized() == false) {
if (mQA->InitQA()) {
if (mQA->InitQA(GetProcessingSettings().runQA ? -GetProcessingSettings().runQA : -1)) {
return 1;
}
}
Expand Down
30 changes: 28 additions & 2 deletions GPU/GPUTracking/Interface/GPUO2InterfaceQA.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,23 @@ GPUO2InterfaceQA::GPUO2InterfaceQA(const GPUSettingsQA* config) : mQA(new GPUQA(

GPUO2InterfaceQA::~GPUO2InterfaceQA() = default;

int GPUO2InterfaceQA::postprocess(std::vector<TH1F>& in1, std::vector<TH2F>& in2, std::vector<TH1D>& in3, TObjArray& out)
int GPUO2InterfaceQA::initializeForProcessing(int tasks)
{
if (mQA->loadHistograms(in1, in2, in3)) {
return mQA->InitQA(tasks);
}

void GPUO2InterfaceQA::runQA(const std::vector<o2::tpc::TrackTPC>* tracksExternal, const std::vector<o2::MCCompLabel>* tracksExtMC, const o2::tpc::ClusterNativeAccess* clNative)
{
mQA->RunQA(false, tracksExternal, tracksExtMC, clNative);
}
int GPUO2InterfaceQA::postprocess(TObjArray& out)
{
return mQA->DrawQAHistograms(&out);
}

int GPUO2InterfaceQA::postprocessExternal(std::vector<TH1F>& in1, std::vector<TH2F>& in2, std::vector<TH1D>& in3, TObjArray& out, int tasks)
{
if (mQA->loadHistograms(in1, in2, in3, tasks)) {
return 1;
}
return mQA->DrawQAHistograms(&out);
Expand All @@ -35,3 +49,15 @@ void GPUO2InterfaceQA::cleanup()
{
mQA->DrawQAHistogramsCleanup();
}

void GPUO2InterfaceQA::getHists(const std::vector<TH1F>*& h1, const std::vector<TH2F>*& h2, const std::vector<TH1D>*& h3)
{
h1 = &mQA->getHistograms1D();
h2 = &mQA->getHistograms2D();
h3 = &mQA->getHistograms1Dd();
}

void GPUO2InterfaceQA::resetHists()
{
mQA->resetHists();
}
20 changes: 19 additions & 1 deletion GPU/GPUTracking/Interface/GPUO2InterfaceQA.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@ class TH1D;
class TH2F;
class TObjArray;

namespace o2
{
class MCCompLabel;
namespace tpc
{
class TrackTPC;
struct ClusterNativeAccess;
} // namespace tpc
} // namespace o2

namespace o2::gpu
{
class GPUQA;
Expand All @@ -43,8 +53,16 @@ class GPUO2InterfaceQA
GPUO2InterfaceQA(const GPUSettingsQA* config = nullptr);
~GPUO2InterfaceQA();

int initializeForProcessing(int tasks); // only needed for processing, not for postprocessing

void runQA(const std::vector<o2::tpc::TrackTPC>* tracksExternal, const std::vector<o2::MCCompLabel>* tracksExtMC, const o2::tpc::ClusterNativeAccess* clNative);
int postprocess(TObjArray& out);

// Input might be modified, so we assume non-const. If it is const, a copy should be created before.
int postprocess(std::vector<TH1F>& in1, std::vector<TH2F>& in2, std::vector<TH1D>& in3, TObjArray& out);
int postprocessExternal(std::vector<TH1F>& in1, std::vector<TH2F>& in2, std::vector<TH1D>& in3, TObjArray& out, int tasks);

void getHists(const std::vector<TH1F>*& h1, const std::vector<TH2F>*& h2, const std::vector<TH1D>*& h3);
void resetHists();
void cleanup();

private:
Expand Down
Loading