From fdb237b7b28998d85f17968c2dfc7da122cc56fe Mon Sep 17 00:00:00 2001 From: Marian Ivanov Date: Tue, 12 Dec 2023 08:52:41 +0100 Subject: [PATCH] TPC QA and PID information in the AO2D (#12387) * ATO-647 - adding trackqa table to the AO2D * ATO-647 - adding trackqa table to the AO2D as in original pull request of David https://github.com/AliceO2Group/AliceO2/pull/12118 * ATO-647 - adding structure for TrackQA +all dEdx information * ATO-647 - adding cursor for the tracksQA table * ATO-647 - formally declaring trackQA table (not filled yet) * ATO-647 - filling content of the dEdx and ClusterByteMask * dEdx and Cluster byte mask compression very effective * trackIndex - not compressed as data are not sorted * ATO-647 - adding description string for columns, add DCAr and DCAz * ATO-647 - adding configuration parameter form TrmTrackQAFraction https://github.com/AliceO2Group/AliceO2/pull/12387#issuecomment-1837504505 removing reference to non relevant pull request * ATO-647 - applying clang-format * ATO-647 - adding Tsaliss downsamling using configured parameter * ATO-647 - clang format * ATO-647 - get sqrts from CCDB, clang format * ATO-647 - making clang hapy * ATO-647 - disabling initialization part - causing failure * CCDB can not be used in init * problem to read fraction * ATO-647 - fixing setting and reading of the fraction * ATO-647 - initializing SqrtS only once as suggested by Ruben comment * ATO-647 -cleanup the code / remoing copypaste leftover * ATO-647 -adding brackets to resolve pull request * ATO-647 -use simple track without error for propagation * ATO-647 - speed up dEdx ratio calculation * ATO-647 - uing only TPC gid (commented by Ruben) * ATO-647 - adding mTrackQCNTrCut cut to reduce amount of the "short tracks" triggered by sampling * ATO-647 - make consistent type for the NTrCut+warning removal + changing index * ATO-647 -use mTableTrID as index trackQAInfoHolder.trackID = mTableTrID; * ATO-647 -fixing minor comments of Jan-Fiete - for documentation string * ATO-647 -adding tpcTime0 for the QA of the V0 and Cascade finder * ATO-647 -adding tpcTime0 in respect to collision time from AO2D following https://github.com/AliceO2Group/AliceO2/pull/12387#discussion_r1422465801 * ATO-647 bug fix in diffBCRef --------- Co-authored-by: miranov25 --- .../AODProducerWorkflowSpec.h | 31 ++++- Detectors/AOD/src/AODProducerWorkflowSpec.cxx | 119 +++++++++++++++++- .../include/Framework/AnalysisDataModel.h | 26 ++++ 3 files changed, 168 insertions(+), 8 deletions(-) diff --git a/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h b/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h index dc28f111450d6..ae774ab7e168d 100644 --- a/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h +++ b/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h @@ -33,7 +33,7 @@ #include #include #include - +#include using namespace o2::framework; using GID = o2::dataformats::GlobalTrackID; using GIndex = o2::dataformats::VtxTrackIndex; @@ -229,6 +229,10 @@ class AODProducerWorkflowDPL : public Task bool mPropTracks{false}; bool mPropMuons{false}; + float mTrackQCFraction{0.00}; + int64_t mTrackQCNTrCut{4}; + float mSqrtS{13860.}; + std::mt19937 mGenerator; ///< random generator for trackQA sampling o2::base::Propagator::MatCorrType mMatCorr{o2::base::Propagator::MatCorrType::USEMatCorrLUT}; o2::dataformats::MeanVertexObject mVtx; float mMinPropR{o2::constants::geom::XTPCInnerRef + 0.1f}; @@ -381,9 +385,26 @@ class AODProducerWorkflowDPL : public Task float trackPhiEMCAL = -999.f; float trackTime = -999.f; float trackTimeRes = -999.f; + int diffBCRef = 0; // offset of time reference BC from the start of the orbit int bcSlice[2] = {-1, -1}; }; + struct TrackQA { + GID trackID; + float tpcTime0; + int16_t tpcdcaR; + int16_t tpcdcaZ; + uint8_t tpcClusterByteMask; + uint8_t tpcdEdxMax0R; + uint8_t tpcdEdxMax1R; + uint8_t tpcdEdxMax2R; + uint8_t tpcdEdxMax3R; + uint8_t tpcdEdxTot0R; + uint8_t tpcdEdxTot1R; + uint8_t tpcdEdxTot2R; + uint8_t tpcdEdxTot3R; + }; + // helper struct for addToFwdTracksTable() struct FwdTrackInfo { uint8_t trackTypeId = 0; @@ -462,6 +483,9 @@ class AODProducerWorkflowDPL : public Task template void addToTracksExtraTable(TracksExtraCursorType& tracksExtraCursor, TrackExtraInfo& extraInfoHolder); + template + void addToTracksQATable(TracksQACursorType& tracksQACursor, TrackQA& trackQAInfoHolder); + template void addToMFTTracksTable(mftTracksCursorType& mftTracksCursor, AmbigMFTTracksCursorType& ambigMFTTracksCursor, GIndex trackID, const o2::globaltracking::RecoContainer& data, int collisionID, @@ -472,6 +496,8 @@ class AODProducerWorkflowDPL : public Task GIndex trackID, const o2::globaltracking::RecoContainer& data, int collisionID, std::uint64_t collisionBC, const std::map& bcsMap); TrackExtraInfo processBarrelTrack(int collisionID, std::uint64_t collisionBC, GIndex trackIndex, const o2::globaltracking::RecoContainer& data, const std::map& bcsMap); + TrackQA processBarrelTrackQA(int collisionID, std::uint64_t collisionBC, GIndex trackIndex, const o2::globaltracking::RecoContainer& data, const std::map& bcsMap); + bool propagateTrackToPV(o2::track::TrackParametrizationWithError& trackPar, const o2::globaltracking::RecoContainer& data, int colID); void extrapolateToCalorimeters(TrackExtraInfo& extraInfoHolder, const o2::track::TrackPar& track); void cacheTriggers(const o2::globaltracking::RecoContainer& recoData); @@ -479,7 +505,7 @@ class AODProducerWorkflowDPL : public Task // helper for track tables // * fills tables collision by collision // * interaction time is for TOF information - template void fillTrackTablesPerCollision(int collisionID, @@ -490,6 +516,7 @@ class AODProducerWorkflowDPL : public Task TracksCursorType& tracksCursor, TracksCovCursorType& tracksCovCursor, TracksExtraCursorType& tracksExtraCursor, + TracksQACursorType& tracksQACursor, AmbigTracksCursorType& ambigTracksCursor, MFTTracksCursorType& mftTracksCursor, AmbigMFTTracksCursorType& ambigMFTTracksCursor, diff --git a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx index 9d21b87bee762..bdf641981f2fe 100644 --- a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx +++ b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx @@ -92,6 +92,8 @@ #include #include "TLorentzVector.h" #include "TVector3.h" +#include "MathUtils/Tsallis.h" +#include #ifdef WITH_OPENMP #include #endif @@ -340,6 +342,30 @@ void AODProducerWorkflowDPL::addToTracksExtraTable(TracksExtraCursorType& tracks truncateFloatFraction(extraInfoHolder.trackTimeRes, mTrackTimeError)); } +template +void AODProducerWorkflowDPL::addToTracksQATable(TracksQACursorType& tracksQACursor, TrackQA& trackQAInfoHolder) +{ + + // trackQA + tracksQACursor( + + // truncateFloatFraction(trackQAInfoHolder.tpcdcaR, mTrackChi2), + // truncateFloatFraction(trackQAInfoHolder.tpcdcaZ, mTrackChi2), + trackQAInfoHolder.trackID, + trackQAInfoHolder.tpcTime0, + trackQAInfoHolder.tpcdcaR, + trackQAInfoHolder.tpcdcaZ, + trackQAInfoHolder.tpcClusterByteMask, + trackQAInfoHolder.tpcdEdxMax0R, + trackQAInfoHolder.tpcdEdxMax1R, + trackQAInfoHolder.tpcdEdxMax2R, + trackQAInfoHolder.tpcdEdxMax3R, + trackQAInfoHolder.tpcdEdxTot0R, + trackQAInfoHolder.tpcdEdxTot1R, + trackQAInfoHolder.tpcdEdxTot2R, + trackQAInfoHolder.tpcdEdxTot3R); +} + template void AODProducerWorkflowDPL::addToMFTTracksTable(mftTracksCursorType& mftTracksCursor, AmbigMFTTracksCursorType& ambigMFTTracksCursor, GIndex trackID, const o2::globaltracking::RecoContainer& data, int collisionID, @@ -381,7 +407,7 @@ void AODProducerWorkflowDPL::addToMFTTracksTable(mftTracksCursorType& mftTracksC } } -template void AODProducerWorkflowDPL::fillTrackTablesPerCollision(int collisionID, @@ -392,6 +418,7 @@ void AODProducerWorkflowDPL::fillTrackTablesPerCollision(int collisionID, TracksCursorType& tracksCursor, TracksCovCursorType& tracksCovCursor, TracksExtraCursorType& tracksExtraCursor, + TracksQACursorType& tracksQACursor, AmbigTracksCursorType& ambigTracksCursor, MFTTracksCursorType& mftTracksCursor, AmbigMFTTracksCursorType& ambigMFTTracksCursor, @@ -440,6 +467,21 @@ void AODProducerWorkflowDPL::fillTrackTablesPerCollision(int collisionID, continue; } auto extraInfoHolder = processBarrelTrack(collisionID, collisionBC, trackIndex, data, bcsMap); + + float weight = 0; + std::uniform_real_distribution<> distr(0., 1.); + bool writeQAData = o2::math_utils::Tsallis::downsampleTsallisCharged(data.getTrackParam(trackIndex).getPt(), mTrackQCFraction, mSqrtS, weight, distr(mGenerator)); + if (writeQAData) { + auto trackQAInfoHolder = processBarrelTrackQA(collisionID, collisionBC, trackIndex, data, bcsMap); + if (std::bitset<8>(trackQAInfoHolder.tpcClusterByteMask).count() >= mTrackQCNTrCut) { + trackQAInfoHolder.trackID = mTableTrID; + // LOGP(info, "orig time0 in bc: {} diffBCRef: {}, ttime: {} -> {}", trackQAInfoHolder.tpcTime0*8, extraInfoHolder.diffBCRef, extraInfoHolder.trackTime, (trackQAInfoHolder.tpcTime0 * 8 - extraInfoHolder.diffBCRef) * o2::constants::lhc::LHCBunchSpacingNS - extraInfoHolder.trackTime); + trackQAInfoHolder.tpcTime0 = (trackQAInfoHolder.tpcTime0 * 8 - extraInfoHolder.diffBCRef) * o2::constants::lhc::LHCBunchSpacingNS - extraInfoHolder.trackTime; + // difference between TPC track time0 and stored track nominal time in ns instead of TF start + addToTracksQATable(tracksQACursor, trackQAInfoHolder); + } + } + if (extraInfoHolder.trackTimeRes < 0.f) { // failed or rejected? LOG(warning) << "Barrel track " << trackIndex << " has no time set, rejection is not expected : time=" << extraInfoHolder.trackTime << " timeErr=" << extraInfoHolder.trackTimeRes << " BCSlice: " << extraInfoHolder.bcSlice[0] << ":" << extraInfoHolder.bcSlice[1]; @@ -458,7 +500,8 @@ void AODProducerWorkflowDPL::fillTrackTablesPerCollision(int collisionID, addToTracksTable(tracksCursor, tracksCovCursor, trOrig, collisionID, aod::track::TrackIU); } addToTracksExtraTable(tracksExtraCursor, extraInfoHolder); - // collecting table indices of barrel tracks for V0s table + // addToTracksQATable(tracksQACursor, trackQAInfoHolder); + // collecting table indices of barrel tracks for V0s table if (extraInfoHolder.bcSlice[0] >= 0 && collisionID < 0) { ambigTracksCursor(mTableTrID, extraInfoHolder.bcSlice); } @@ -1628,6 +1671,9 @@ void AODProducerWorkflowDPL::init(InitContext& ic) mEMCselectLeading = ic.options().get("emc-select-leading"); mPropTracks = ic.options().get("propagate-tracks"); mPropMuons = ic.options().get("propagate-muons"); + mTrackQCFraction = ic.options().get("trackqc-fraction"); + mTrackQCNTrCut = ic.options().get("trackqc-NTrCut"); + mGenerator = std::mt19937(std::random_device{}()); #ifdef WITH_OPENMP LOGP(info, "Multi-threaded parts will run with {} OpenMP threads", mNThreads); #else @@ -1761,6 +1807,7 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc) auto tracksCursor = createTableCursor(pc); auto tracksCovCursor = createTableCursor(pc); auto tracksExtraCursor = createTableCursor(pc); + auto tracksQACursor = createTableCursor(pc); auto ambigTracksCursor = createTableCursor(pc); auto ambigMFTTracksCursor = createTableCursor(pc); auto ambigFwdTracksCursor = createTableCursor(pc); @@ -2065,7 +2112,7 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc) // so that all unassigned tracks are stored in the beginning of the table together auto& trackRef = primVer2TRefs.back(); // references to unassigned tracks are at the end // fixme: interaction time is undefined for unassigned tracks (?) - fillTrackTablesPerCollision(-1, std::uint64_t(-1), trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, + fillTrackTablesPerCollision(-1, std::uint64_t(-1), trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor, ambigTracksCursor, mftTracksCursor, ambigMFTTracksCursor, fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, bcsMap); @@ -2107,7 +2154,7 @@ void AODProducerWorkflowDPL::run(ProcessingContext& pc) auto& trackRef = primVer2TRefs[collisionID]; // passing interaction time in [ps] - fillTrackTablesPerCollision(collisionID, globalBC, trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, ambigTracksCursor, + fillTrackTablesPerCollision(collisionID, globalBC, trackRef, primVerGIs, recoData, tracksCursor, tracksCovCursor, tracksExtraCursor, tracksQACursor, ambigTracksCursor, mftTracksCursor, ambigMFTTracksCursor, fwdTracksCursor, fwdTracksCovCursor, ambigFwdTracksCursor, bcsMap); collisionID++; @@ -2341,6 +2388,7 @@ AODProducerWorkflowDPL::TrackExtraInfo AODProducerWorkflowDPL::processBarrelTrac bcOfTimeRef = fillBCSlice(extraInfoHolder.bcSlice, t - error, t + error, bcsMap); } extraInfoHolder.trackTime = float(t - bcOfTimeRef * o2::constants::lhc::LHCBunchSpacingNS); + extraInfoHolder.diffBCRef = int(bcOfTimeRef); LOGP(debug, "time : {}/{} -> {}/{} -> trunc: {}/{} CollID: {} Amb: {}", t, terr, t - bcOfTimeRef * o2::constants::lhc::LHCBunchSpacingNS, terr, truncateFloatFraction(extraInfoHolder.trackTime, mTrackTime), truncateFloatFraction(extraInfoHolder.trackTimeRes, mTrackTimeError), collisionID, trackIndex.isAmbiguous()); @@ -2426,6 +2474,61 @@ AODProducerWorkflowDPL::TrackExtraInfo AODProducerWorkflowDPL::processBarrelTrac return extraInfoHolder; } +AODProducerWorkflowDPL::TrackQA AODProducerWorkflowDPL::processBarrelTrackQA(int collisionID, std::uint64_t collisionBC, GIndex trackIndex, + const o2::globaltracking::RecoContainer& data, const std::map& bcsMap) +{ + TrackQA trackQAHolder; + auto contributorsGID = data.getTPCContributorGID(trackIndex); + const auto& trackPar = data.getTrackParam(trackIndex); + // auto src = trackIndex.getSource(); + if (contributorsGID.isIndexSet()) { + const auto& tpcOrig = data.getTPCTrack(contributorsGID); + /// getDCA - should be done with the copy of TPC only track + // LOGP(info, "GloIdx: {} TPCIdx: {}, NTPCTracks: {}", trackIndex.asString(), contributorsGID.asString(), data.getTPCTracks().size()); + o2::track::TrackParametrization tpcTMP = tpcOrig; /// get backup of the track + o2::base::Propagator::MatCorrType mMatType = o2::base::Propagator::MatCorrType::USEMatCorrLUT; /// should be parameterized + o2::dataformats::VertexBase v = mVtx.getMeanVertex(collisionID < 0 ? 0.f : data.getPrimaryVertex(collisionID).getZ()); + o2::gpu::gpustd::array dcaInfo{-999., -999.}; + if (o2::base::Propagator::Instance()->propagateToDCABxByBz({v.getX(), v.getY(), v.getZ()}, tpcTMP, 2.f, mMatType, &dcaInfo)) { + trackQAHolder.tpcdcaR = 100. * dcaInfo[0] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt()); + trackQAHolder.tpcdcaZ = 100. * dcaInfo[1] / sqrt(1. + trackPar.getQ2Pt() * trackPar.getQ2Pt()); + } + /// get tracklet byteMask + uint8_t clusterCounters[8] = {0}; + { + uint8_t sectorIndex, rowIndex; + uint32_t clusterIndex; + const auto& tpcClusRefs = data.getTPCTracksClusterRefs(); + for (int i = 0; i < tpcOrig.getNClusterReferences(); i++) { + o2::tpc::TrackTPC::getClusterReference(tpcClusRefs, i, sectorIndex, rowIndex, clusterIndex, tpcOrig.getClusterRef()); + char indexTracklet = (rowIndex % 152) / 19; + clusterCounters[indexTracklet]++; + } + } + uint8_t byteMask = 0; + for (int i = 0; i < 8; i++) { + if (clusterCounters[i] > 5) { + byteMask |= (1 << i); + } + } + trackQAHolder.tpcTime0 = tpcOrig.getTime0(); + trackQAHolder.tpcClusterByteMask = byteMask; + float dEdxNorm = (tpcOrig.getdEdx().dEdxTotTPC > 0) ? 100. / tpcOrig.getdEdx().dEdxTotTPC : 0; + trackQAHolder.tpcdEdxMax0R = uint8_t(tpcOrig.getdEdx().dEdxMaxIROC * dEdxNorm); + trackQAHolder.tpcdEdxMax1R = uint8_t(tpcOrig.getdEdx().dEdxMaxOROC1 * dEdxNorm); + trackQAHolder.tpcdEdxMax2R = uint8_t(tpcOrig.getdEdx().dEdxMaxOROC2 * dEdxNorm); + trackQAHolder.tpcdEdxMax3R = uint8_t(tpcOrig.getdEdx().dEdxMaxOROC3 * dEdxNorm); + // + trackQAHolder.tpcdEdxTot0R = uint8_t(tpcOrig.getdEdx().dEdxTotIROC * dEdxNorm); + trackQAHolder.tpcdEdxTot1R = uint8_t(tpcOrig.getdEdx().dEdxTotOROC1 * dEdxNorm); + trackQAHolder.tpcdEdxTot2R = uint8_t(tpcOrig.getdEdx().dEdxTotOROC2 * dEdxNorm); + trackQAHolder.tpcdEdxTot3R = uint8_t(tpcOrig.getdEdx().dEdxTotOROC3 * dEdxNorm); + /// + } + + return trackQAHolder; +} + bool AODProducerWorkflowDPL::propagateTrackToPV(o2::track::TrackParametrizationWithError& trackPar, const o2::globaltracking::RecoContainer& data, int colID) @@ -2551,7 +2654,7 @@ void AODProducerWorkflowDPL::updateTimeDependentParams(ProcessingContext& pc) if (!initOnceDone) { // this params need to be queried only once initOnceDone = true; // Note: DPLAlpideParam for ITS and MFT will be loaded by the RecoContainer - + mSqrtS = o2::base::GRPGeomHelper::instance().getGRPLHCIF()->getSqrtS(); // apply settings auto grpECS = o2::base::GRPGeomHelper::instance().getGRPECS(); o2::BunchFilling bcf = o2::base::GRPGeomHelper::instance().getGRPLHCIF()->getBunchFilling(); @@ -2829,6 +2932,7 @@ DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, boo OutputForTable::spec(), OutputForTable::spec(), OutputForTable::spec(), + OutputForTable::spec(), OutputForTable::spec(), OutputForTable::spec(), OutputForTable::spec(), @@ -2872,7 +2976,10 @@ DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, boo ConfigParamSpec{"ctpreadout-create", VariantType::Int, 0, {"Create CTP digits from detector readout and CTP inputs. !=1 -- off, 1 -- on"}}, ConfigParamSpec{"emc-select-leading", VariantType::Bool, false, {"Flag to select if only the leading contributing particle for an EMCal cell should be stored"}}, ConfigParamSpec{"propagate-tracks", VariantType::Bool, false, {"Propagate tracks (not used for secondary vertices) to IP"}}, - ConfigParamSpec{"propagate-muons", VariantType::Bool, false, {"Propagate muons to IP"}}}}; + ConfigParamSpec{"propagate-muons", VariantType::Bool, false, {"Propagate muons to IP"}}, + ConfigParamSpec{"trackqc-fraction", VariantType::Float, float(0.1), {"Fraction of tracks to QC"}}, + ConfigParamSpec{"trackqc-NTrCut", VariantType::Int64, 4L, {"Minimal length of the track - in amount of tracklets"}}, + }}; } } // namespace o2::aodproducer diff --git a/Framework/Core/include/Framework/AnalysisDataModel.h b/Framework/Core/include/Framework/AnalysisDataModel.h index 6ea65bd7b27ec..bc1a70fb18c15 100644 --- a/Framework/Core/include/Framework/AnalysisDataModel.h +++ b/Framework/Core/include/Framework/AnalysisDataModel.h @@ -494,6 +494,32 @@ namespace aod using FullTracks = soa::Join; using FullTrack = FullTracks::iterator; +namespace trackqa +{ +// TRACKQA TABLE COLUMNS +DECLARE_SOA_INDEX_COLUMN(Track, track); //! track to which this QA information belongs +DECLARE_SOA_COLUMN(TPCTime0, tpcTime0, float); //! tpc only time0 (mTime0 in TPC track) +DECLARE_SOA_COLUMN(TPCDCAR, tpcdcaR, int16_t); //! tpc only DCAr +DECLARE_SOA_COLUMN(TPCDCAZ, tpcdcaZ, int16_t); //! tpc only DCAz +DECLARE_SOA_COLUMN(TPCClusterByteMask, tpcClusterByteMask, uint8_t); //! tracklet bitmask - track defining 8 tracklets (152=8*19 rows) bit set if nCluster>thr (default 5) +DECLARE_SOA_COLUMN(TPCdEdxMax0R, tpcdEdxMax0R, uint8_t); //! TPC dEdxQMax -ROC0/dEdx +DECLARE_SOA_COLUMN(TPCdEdxMax1R, tpcdEdxMax1R, uint8_t); //! TPC dEdxQMax -ROC1/dEdx +DECLARE_SOA_COLUMN(TPCdEdxMax2R, tpcdEdxMax2R, uint8_t); //! TPC dEdxQMax -ROC2/dEdx +DECLARE_SOA_COLUMN(TPCdEdxMax3R, tpcdEdxMax3R, uint8_t); //! TPC dEdxQMax -ROC3/dEdx +DECLARE_SOA_COLUMN(TPCdEdxTot0R, tpcdEdxTot0R, uint8_t); //! TPC dEdxQtot -ROC0/dEdx +DECLARE_SOA_COLUMN(TPCdEdxTot1R, tpcdEdxTot1R, uint8_t); //! TPC dEdxQtot -ROC1/dEdx +DECLARE_SOA_COLUMN(TPCdEdxTot2R, tpcdEdxTot2R, uint8_t); //! TPC dEdxQtot -ROC2/dEdx +DECLARE_SOA_COLUMN(TPCdEdxTot3R, tpcdEdxTot3R, uint8_t); //! TPC dEdxQtot -ROC3/dEdx +} // namespace trackqa + +DECLARE_SOA_TABLE(TracksQA, "AOD", "TRACKQA", //! trackQA information - sampled QA information currently for the TPC + o2::soa::Index<>, trackqa::TrackId, trackqa::TPCTime0, trackqa::TPCDCAR, trackqa::TPCDCAZ, trackqa::TPCClusterByteMask, + // o2::soa::Index<>, trackqa::TrackId, trackqa::TPCDCAR, trackqa::TPCDCAZ, trackqa::TPCClusterByteMask, + trackqa::TPCdEdxMax0R, trackqa::TPCdEdxMax1R, trackqa::TPCdEdxMax2R, trackqa::TPCdEdxMax3R, + trackqa::TPCdEdxTot0R, trackqa::TPCdEdxTot1R, trackqa::TPCdEdxTot2R, trackqa::TPCdEdxTot3R); + +using TrackQA = TracksQA::iterator; + namespace fwdtrack { // FwdTracks and MFTTracks Columns definitions