diff --git a/DataFormats/Detectors/ITSMFT/ITS/include/DataFormatsITS/TrackITS.h b/DataFormats/Detectors/ITSMFT/ITS/include/DataFormatsITS/TrackITS.h index 3cef7f45a9fb1..709e8aa3ee329 100644 --- a/DataFormats/Detectors/ITSMFT/ITS/include/DataFormatsITS/TrackITS.h +++ b/DataFormats/Detectors/ITSMFT/ITS/include/DataFormatsITS/TrackITS.h @@ -122,13 +122,39 @@ class TrackITS : public o2::track::TrackParCov void setNextROFbit(bool toggle = true) { setUserField((getUserField() & ~kNextROF) | (-toggle & kNextROF)); } bool hasHitInNextROF() const { return getUserField() & kNextROF; } + void setClusterSize(int l, int size) + { + if (l >= 8) { + return; + } + if (size > 15) { + size = 15; + } + mClusterSizes &= ~(0xf << (l * 4)); + mClusterSizes |= (size << (l * 4)); + } + + int getClusterSize(int l) + { + if (l >= 8) { + return 0; + } + return (mClusterSizes >> (l * 4)) & 0xf; + } + + int getClusterSizes() const + { + return mClusterSizes; + } + private: o2::track::TrackParCov mParamOut; ///< parameter at largest radius ClusRefs mClusRef; ///< references on clusters float mChi2 = 0.; ///< Chi2 for this track uint32_t mPattern = 0; ///< layers pattern + unsigned int mClusterSizes = 0u; - ClassDefNV(TrackITS, 5); + ClassDefNV(TrackITS, 6); }; class TrackITSExt : public TrackITS diff --git a/DataFormats/Detectors/ITSMFT/common/include/DataFormatsITSMFT/TrkClusRef.h b/DataFormats/Detectors/ITSMFT/common/include/DataFormatsITSMFT/TrkClusRef.h index 164fd850fd539..7a027c2a2156c 100644 --- a/DataFormats/Detectors/ITSMFT/common/include/DataFormatsITSMFT/TrkClusRef.h +++ b/DataFormats/Detectors/ITSMFT/common/include/DataFormatsITSMFT/TrkClusRef.h @@ -25,12 +25,35 @@ namespace itsmft // can refer to max 15 indices in the vector of total length <268435456, i.e. 17895697 tracks in worst case struct TrkClusRef : public o2::dataformats::RangeRefComp<4> { using o2::dataformats::RangeRefComp<4>::RangeRefComp; + uint32_t clsizes = 0; ///< cluster sizes for each layer uint16_t pattern = 0; ///< layers pattern GPUd() int getNClusters() const { return getEntries(); } bool hasHitOnLayer(int i) { return pattern & (0x1 << i); } - ClassDefNV(TrkClusRef, 1); + void setClusterSize(int l, int size) + { + if (l >= 8) + return; + if (size > 15) + size = 15; + clsizes &= ~(0xf << (l * 4)); + clsizes |= (size << (l * 4)); + } + + int getClusterSize(int l) + { + if (l >= 8) + return 0; + return (clsizes >> (l * 4)) & 0xf; + } + + int getClusterSizes() const + { + return clsizes; + } + + ClassDefNV(TrkClusRef, 2); }; } // namespace itsmft diff --git a/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h b/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h index 10c70ad2e77eb..854b487cbe78e 100644 --- a/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h +++ b/Detectors/AOD/include/AODProducerWorkflow/AODProducerWorkflowSpec.h @@ -356,6 +356,7 @@ class AODProducerWorkflowDPL : public Task struct TrackExtraInfo { float tpcInnerParam = 0.f; uint32_t flags = 0; + uint32_t itsClusterSizes = 0u; uint8_t itsClusterMap = 0; uint8_t tpcNClsFindable = 0; int8_t tpcNClsFindableMinusFound = 0; diff --git a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx index 6984ed3841e63..9c2f1d13eefaf 100644 --- a/Detectors/AOD/src/AODProducerWorkflowSpec.cxx +++ b/Detectors/AOD/src/AODProducerWorkflowSpec.cxx @@ -2729,6 +2729,9 @@ DataProcessorSpec getAODProducerWorkflowSpec(GID::mask_t src, bool enableSV, boo dataRequest->requestStrangeTracks(useMC); LOGF(info, "requestStrangeTracks Finish"); } + if (src[GID::ITS]) { + dataRequest->requestClusters(GIndex::getSourcesMask("ITS"), false); + } if (src[GID::TPC]) { dataRequest->requestClusters(GIndex::getSourcesMask("TPC"), false); // no need to ask for TOF clusters as they are requested with TOF tracks } diff --git a/Detectors/GlobalTracking/include/GlobalTracking/MatchTPCITS.h b/Detectors/GlobalTracking/include/GlobalTracking/MatchTPCITS.h index 506ca2222aca2..87cb8f6b8a44e 100644 --- a/Detectors/GlobalTracking/include/GlobalTracking/MatchTPCITS.h +++ b/Detectors/GlobalTracking/include/GlobalTracking/MatchTPCITS.h @@ -89,7 +89,7 @@ namespace tpc { class TrackTPC; class VDriftCorrFact; -} +} // namespace tpc namespace gpu { @@ -127,7 +127,7 @@ struct TrackLocTPC : public o2::track::TrackParCov { float timeErr = 0.f; ///< time sigma (makes sense for constrained tracks only) int sourceID = 0; ///< TPC track origin in o2::dataformats::GlobalTrackID gid{}; // global track source ID (TPC track may be part of it) - int matchID = MinusOne; ///< entry (non if MinusOne) of its matchTPC struct in the mMatchesTPC + int matchID = MinusOne; ///< entry (non if MinusOne) of its matchTPC struct in the mMatchesTPC Constraint_t constraint{Constrained}; float getCorrectedTime(float dt) const // return time0 corrected for extra drift (to match certain Z) @@ -148,9 +148,9 @@ struct TrackLocITS : public o2::track::TrackParCov { enum : uint16_t { CloneBefore = 0x1, CloneAfter = 0x2 }; o2::math_utils::Bracketf_t tBracket; ///< bracketing time in \mus - int sourceID = 0; ///< track origin id - int roFrame = MinusOne; ///< ITS readout frame assigned to this track - int matchID = MinusOne; ///< entry (non if MinusOne) of its matchCand struct in the mMatchesITS + int sourceID = 0; ///< track origin id + int roFrame = MinusOne; ///< ITS readout frame assigned to this track + int matchID = MinusOne; ///< entry (non if MinusOne) of its matchCand struct in the mMatchesITS bool hasCloneBefore() const { return getUserField() & CloneBefore; } bool hasCloneAfter() const { return getUserField() & CloneAfter; } int getCloneShift() const { return hasCloneBefore() ? -1 : (hasCloneAfter() ? 1 : 0); } @@ -536,13 +536,13 @@ class MatchTPCITS float correctTPCTrack(o2::track::TrackParCov& trc, const TrackLocTPC& tTPC, const InteractionCandidate& cand) const; // RS FIXME will be needed for refit //================================================================ - bool mInitDone = false; ///< flag init already done - bool mFieldON = true; ///< flag for field ON/OFF - bool mCosmics = false; ///< flag cosmics mode - bool mMCTruthON = false; ///< flag availability of MC truth - float mBz = 0; ///< nominal Bz - int mTFCount = 0; ///< internal TF counter for debugger - int mNThreads = 1; ///< number of OMP threads + bool mInitDone = false; ///< flag init already done + bool mFieldON = true; ///< flag for field ON/OFF + bool mCosmics = false; ///< flag cosmics mode + bool mMCTruthON = false; ///< flag availability of MC truth + float mBz = 0; ///< nominal Bz + int mTFCount = 0; ///< internal TF counter for debugger + int mNThreads = 1; ///< number of OMP threads o2::InteractionRecord mStartIR{0, 0}; ///< IR corresponding to the start of the TF ///========== Parameters to be set externally, e.g. from CCDB ==================== @@ -566,27 +566,27 @@ class MatchTPCITS ///< assigned time0 and its track Z position (converted from mTPCTimeEdgeZSafeMargin) float mTPCTimeEdgeTSafeMargin = 0.f; float mTPCExtConstrainedNSigmaInv = 0.f; // inverse for NSigmas for TPC time-interval from external constraint time sigma - int mITSROFrameLengthInBC = 0; ///< ITS RO frame in BC (for ITS cont. mode only) - float mITSROFrameLengthMUS = -1.; ///< ITS RO frame in \mus - float mITSTimeResMUS = -1.; ///< nominal ITS time resolution derived from ROF - float mITSROFrameLengthMUSInv = -1.; ///< ITS RO frame in \mus inverse - int mITSTimeBiasInBC = 0; ///< ITS RO frame shift in BCs, i.e. t_i = (I_ROF*mITSROFrameLengthInBC + mITSTimeBiasInBC)*BCLength_MUS - float mITSTimeBiasMUS = 0.; ///< ITS RO frame shift in \mus, i.e. t_i = (I_ROF*mITSROFrameLengthInBC)*BCLength_MUS + mITSTimeBiasMUS - float mTPCVDrift = -1.; ///< TPC drift speed in cm/microseconds - float mTPCVDriftInv = -1.; ///< inverse TPC nominal drift speed in cm/microseconds - float mTPCDriftTimeOffset = 0; ///< drift time offset in mus - float mTPCTBinMUS = 0.; ///< TPC time bin duration in microseconds - float mTPCTBinNS = 0.; ///< TPC time bin duration in ns - float mTPCTBinMUSInv = 0.; ///< inverse TPC time bin duration in microseconds - float mZ2TPCBin = 0.; ///< conversion coeff from Z to TPC time-bin - float mTPCBin2Z = 0.; ///< conversion coeff from TPC time-bin to Z - float mNTPCBinsFullDrift = 0.; ///< max time bin for full drift - float mTPCZMax = 0.; ///< max drift length - float mTPCmeanX0Inv = 1. / 31850.; ///< TPC gas 1/X0 + int mITSROFrameLengthInBC = 0; ///< ITS RO frame in BC (for ITS cont. mode only) + float mITSROFrameLengthMUS = -1.; ///< ITS RO frame in \mus + float mITSTimeResMUS = -1.; ///< nominal ITS time resolution derived from ROF + float mITSROFrameLengthMUSInv = -1.; ///< ITS RO frame in \mus inverse + int mITSTimeBiasInBC = 0; ///< ITS RO frame shift in BCs, i.e. t_i = (I_ROF*mITSROFrameLengthInBC + mITSTimeBiasInBC)*BCLength_MUS + float mITSTimeBiasMUS = 0.; ///< ITS RO frame shift in \mus, i.e. t_i = (I_ROF*mITSROFrameLengthInBC)*BCLength_MUS + mITSTimeBiasMUS + float mTPCVDrift = -1.; ///< TPC drift speed in cm/microseconds + float mTPCVDriftInv = -1.; ///< inverse TPC nominal drift speed in cm/microseconds + float mTPCDriftTimeOffset = 0; ///< drift time offset in mus + float mTPCTBinMUS = 0.; ///< TPC time bin duration in microseconds + float mTPCTBinNS = 0.; ///< TPC time bin duration in ns + float mTPCTBinMUSInv = 0.; ///< inverse TPC time bin duration in microseconds + float mZ2TPCBin = 0.; ///< conversion coeff from Z to TPC time-bin + float mTPCBin2Z = 0.; ///< conversion coeff from TPC time-bin to Z + float mNTPCBinsFullDrift = 0.; ///< max time bin for full drift + float mTPCZMax = 0.; ///< max drift length + float mTPCmeanX0Inv = 1. / 31850.; ///< TPC gas 1/X0 float mMinTPCTrackPtInv = 999.; ///< cutoff on TPC track inverse pT float mMinITSTrackPtInv = 999.; ///< cutoff on ITS track inverse pT - bool mVDriftCalibOn = false; ///< flag to produce VDrift calibration data + bool mVDriftCalibOn = false; ///< flag to produce VDrift calibration data o2::tpc::VDriftCorrFact mTPCDrift{}; o2::gpu::CorrectionMapsHelper* mTPCCorrMapsHelper = nullptr; @@ -601,12 +601,14 @@ class MatchTPCITS const o2::globaltracking::RecoContainer* mRecoCont = nullptr; ///>>>------ these are input arrays which should not be modified by the matching code // since this info is provided by external device - gsl::span mTPCTracksArray; ///< input TPC tracks span - gsl::span mTPCTrackClusIdx; ///< input TPC track cluster indices span - gsl::span mITSTrackROFRec; ///< input ITS tracks ROFRecord span - gsl::span mITSTracksArray; ///< input ITS tracks span - gsl::span mITSTrackClusIdx; ///< input ITS track cluster indices span - std::vector mITSClustersArray; ///< ITS clusters created in loadInput + gsl::span mTPCTracksArray; ///< input TPC tracks span + gsl::span mTPCTrackClusIdx; ///< input TPC track cluster indices span + gsl::span mITSTrackROFRec; ///< input ITS tracks ROFRecord span + gsl::span mITSTracksArray; ///< input ITS tracks span + gsl::span mITSTrackClusIdx; ///< input ITS track cluster indices span + std::vector mITSClustersArray; ///< ITS clusters created in loadInput + std::vector mITSClusterSizes; ///< ITS cluster sizes created in loadInput + gsl::span mITSClusterROFRec; ///< input ITS clusters ROFRecord span gsl::span mFITInfo; ///< optional input FIT info span @@ -624,6 +626,7 @@ class MatchTPCITS size_t mNMatches = 0; size_t mNCalibPrelim = 0; size_t mNMatchesControl = 0; + size_t mNABRefsClus = 0; float mAB2MatchGuess = 0.2; // heuristic guess about fraction of AB matches in total matches std::vector mInteractions; ///< possible interaction times @@ -693,7 +696,6 @@ class MatchTPCITS static constexpr std::string_view TimerName[] = {"Total", "PrepareITS", "PrepareTPC", "DoMatching", "SelectBest", "Refit", "ABSeeds", "ABMatching", "ABWinners", "ABRefit", "IO", "Debug"}; TStopwatch mTimer[NStopWatches]; - }; //______________________________________________ @@ -714,7 +716,6 @@ inline bool MatchTPCITS::isDisabledITS(const TrackLocITS& t) const { return t.ma //______________________________________________ inline bool MatchTPCITS::isDisabledTPC(const TrackLocTPC& t) const { return t.matchID < 0; } - } // namespace globaltracking } // namespace o2 diff --git a/Detectors/GlobalTracking/src/MatchTPCITS.cxx b/Detectors/GlobalTracking/src/MatchTPCITS.cxx index cff36caf2a249..3f22b9da176f6 100644 --- a/Detectors/GlobalTracking/src/MatchTPCITS.cxx +++ b/Detectors/GlobalTracking/src/MatchTPCITS.cxx @@ -155,6 +155,7 @@ void MatchTPCITS::clear() mITSROFTimes.clear(); mITSTrackROFContMapping.clear(); mITSClustersArray.clear(); + mITSClusterSizes.clear(); mTPCABSeeds.clear(); mTPCABIndexCache.clear(); mABWinnersIDs.clear(); @@ -309,7 +310,7 @@ bool MatchTPCITS::validateTPCMatch(int iTPC) if (rcITS.nextRecID == Validated) { return false; } - if (rcITS.partnerID == iTPC) { // is best matching TPC track for this ITS track actually iTPC? + if (rcITS.partnerID == iTPC) { // is best matching TPC track for this ITS track actually iTPC? int cloneID = tITS.getCloneShift(); // check if there is a clone of tITS while (cloneID) { cloneID += rcTPC.partnerID; @@ -580,6 +581,27 @@ bool MatchTPCITS::prepareITSData() auto pattIt = patterns.begin(); mITSClustersArray.reserve(clusITS.size()); o2::its::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mITSDict); + + // ITS clusters sizes + mITSClusterSizes.reserve(clusITS.size()); + auto pattIt2 = patterns.begin(); + for (auto& clus : clusITS) { + auto pattID = clus.getPatternID(); + unsigned int npix; + if (pattID == o2::itsmft::CompCluster::InvalidPatternID || mITSDict->isGroup(pattID)) { + o2::itsmft::ClusterPattern patt; + patt.acquirePattern(pattIt2); + npix = patt.getNPixels(); + } else { + npix = mITSDict->getNpixels(pattID); + } + if (npix < 255) { + mITSClusterSizes.push_back(npix); + } else { + mITSClusterSizes.push_back(255); + } + } + if (mMCTruthON) { mITSClsLabels = inp.mcITSClusters.get(); } @@ -1295,21 +1317,21 @@ bool MatchTPCITS::refitTrackTPCITS(int iTPC, int& iITS, pmr::vector mITSTimeResMUS && tTPC.constraint != TrackLocTPC::Constrained) { timeErr = mITSTimeResMUS; // chose smallest error deltaT = tTPC.constraint == TrackLocTPC::ASide ? tITS.tBracket.mean() - tTPC.time0 : tTPC.time0 - tITS.tBracket.mean(); } timeErr += mParams->globalTimeExtraErrorMUS; - float timeC = tTPC.getCorrectedTime(deltaT) + mParams->globalTimeBiasMUS; /// precise time estimate, optionally corrected for bias - if (timeC < 0) { // RS TODO similar check is needed for other edge of TF + float timeC = tTPC.getCorrectedTime(deltaT) + mParams->globalTimeBiasMUS; /// precise time estimate, optionally corrected for bias + if (timeC < 0) { // RS TODO similar check is needed for other edge of TF if (timeC + std::min(timeErr, mParams->tfEdgeTimeToleranceMUS * mTPCTBinMUSInv) < 0) { matchedTracks.pop_back(); // destroy failed track return false; @@ -1845,6 +1867,7 @@ void MatchTPCITS::refitABWinners(pmr::vector& matc ABTrackletClusterIDs.push_back(winL.clID); ncl++; clref.pattern |= 0x1 << winL.layerID; + clref.setClusterSize(winL.layerID, mITSClusterSizes[winL.clID]); if (mMCTruthON) { accountClusterLabel(winL.clID); } diff --git a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h index da35b1714978a..3b10e1d76f18c 100644 --- a/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h +++ b/Detectors/ITSMFT/ITS/tracking/include/ITStracking/TimeFrame.h @@ -129,6 +129,7 @@ class TimeFrame const gsl::span getClusterLabels(int layerId, const Cluster& cl) const; const gsl::span getClusterLabels(int layerId, const int clId) const; int getClusterExternalIndex(int layerId, const int clId) const; + int getClusterSize(int clusterId); std::vector& getTrackletsLabel(int layer) { return mTrackletLabels[layer]; } std::vector& getCellsLabel(int layer) { return mCellLabels[layer]; } @@ -244,6 +245,7 @@ class TimeFrame std::vector mMSangles; std::vector mPhiCuts; std::vector mPositionResolution; + std::vector mClusterSize; std::vector mMultiplicityCutMask; std::vector> mPValphaX; /// PV x and alpha for track propagation std::vector> mUnsortedClusters; @@ -424,6 +426,11 @@ inline const gsl::span TimeFrame::getClusterLabels(int layerI return mClusterLabels->getLabels(mClusterExternalIndices[layerId][clId]); } +inline int TimeFrame::getClusterSize(int clusterId) +{ + return mClusterSize[clusterId]; +} + inline int TimeFrame::getClusterExternalIndex(int layerId, const int clId) const { return mClusterExternalIndices[layerId][clId]; diff --git a/Detectors/ITSMFT/ITS/tracking/src/TimeFrame.cxx b/Detectors/ITSMFT/ITS/tracking/src/TimeFrame.cxx index 24349e30b8017..11da548c377b0 100644 --- a/Detectors/ITSMFT/ITS/tracking/src/TimeFrame.cxx +++ b/Detectors/ITSMFT/ITS/tracking/src/TimeFrame.cxx @@ -175,6 +175,8 @@ int TimeFrame::loadROFrameData(gsl::span rofs, geom->fillMatrixCache(o2::math_utils::bit2Mask(o2::math_utils::TransformType::T2L, o2::math_utils::TransformType::L2G)); mNrof = 0; + mClusterSize.clear(); + mClusterSize.reserve(clusters.size()); for (auto& rof : rofs) { for (int clusterId{rof.getFirstEntry()}; clusterId < rof.getFirstEntry() + rof.getNEntries(); ++clusterId) { auto& c = clusters[clusterId]; @@ -184,18 +186,27 @@ int TimeFrame::loadROFrameData(gsl::span rofs, auto pattID = c.getPatternID(); o2::math_utils::Point3D locXYZ; float sigmaY2 = DefClusError2Row, sigmaZ2 = DefClusError2Col, sigmaYZ = 0; // Dummy COG errors (about half pixel size) + unsigned int clusterSize{0}; if (pattID != itsmft::CompCluster::InvalidPatternID) { sigmaY2 = dict->getErr2X(pattID); sigmaZ2 = dict->getErr2Z(pattID); if (!dict->isGroup(pattID)) { locXYZ = dict->getClusterCoordinates(c); + clusterSize = dict->getNpixels(pattID); } else { o2::itsmft::ClusterPattern patt(pattIt); locXYZ = dict->getClusterCoordinates(c, patt); + clusterSize = patt.getNPixels(); } } else { o2::itsmft::ClusterPattern patt(pattIt); locXYZ = dict->getClusterCoordinates(c, patt, false); + clusterSize = patt.getNPixels(); + } + if (clusterSize < 255) { + mClusterSize.push_back(clusterSize); + } else { + mClusterSize.push_back(255); } auto sensorID = c.getSensorID(); // Inverse transformation to the local --> tracking diff --git a/Detectors/ITSMFT/ITS/workflow/src/TrackerSpec.cxx b/Detectors/ITSMFT/ITS/workflow/src/TrackerSpec.cxx index b9831462b0a13..91542a37ae2eb 100644 --- a/Detectors/ITSMFT/ITS/workflow/src/TrackerSpec.cxx +++ b/Detectors/ITSMFT/ITS/workflow/src/TrackerSpec.cxx @@ -296,6 +296,7 @@ void TrackerDPL::run(ProcessingContext& pc) for (int ic = TrackITSExt::MaxClusters; ic--;) { // track internally keeps in->out cluster indices, but we want to store the references as out->in!!! auto clid = trc.getClusterIndex(ic); if (clid >= 0) { + trc.setClusterSize(ic, mTimeFrame->getClusterSize(clid)); allClusIdx.push_back(clid); nclf++; } diff --git a/Framework/Core/include/Framework/AnalysisDataModel.h b/Framework/Core/include/Framework/AnalysisDataModel.h index e409dba7db9da..5f8f7fef5f506 100644 --- a/Framework/Core/include/Framework/AnalysisDataModel.h +++ b/Framework/Core/include/Framework/AnalysisDataModel.h @@ -221,7 +221,8 @@ DECLARE_SOA_EXPRESSION_COLUMN(C1Pt21Pt2, c1Pt21Pt2, float, //! // TRACKEXTRA TABLE definition DECLARE_SOA_COLUMN(TPCInnerParam, tpcInnerParam, float); //! Momentum at inner wall of the TPC DECLARE_SOA_COLUMN(Flags, flags, uint32_t); //! Track flags. Run 2: see TrackFlagsRun2Enum | Run 3: see TrackFlags -DECLARE_SOA_COLUMN(ITSClusterMap, itsClusterMap, uint8_t); //! ITS cluster map, one bit per a layer, starting from the innermost +DECLARE_SOA_COLUMN(ITSClusterSizes, itsClusterSizes, uint32_t); //! Clusters sizes, four bits per a layer, starting from the innermost +DECLARE_SOA_COLUMN(ITSClusterMap, itsClusterMap, uint8_t); //! Old cluster ITS cluster map, kept for version 0 compatibility DECLARE_SOA_COLUMN(TPCNClsFindable, tpcNClsFindable, uint8_t); //! Findable TPC clusters for this track geometry DECLARE_SOA_COLUMN(TPCNClsFindableMinusFound, tpcNClsFindableMinusFound, int8_t); //! TPC Clusters: Findable - Found DECLARE_SOA_COLUMN(TPCNClsFindableMinusCrossedRows, tpcNClsFindableMinusCrossedRows, int8_t); //! TPC Clusters: Findable - crossed rows @@ -239,11 +240,53 @@ DECLARE_SOA_COLUMN(TrackEtaEMCAL, trackEtaEmcal, float); DECLARE_SOA_COLUMN(TrackPhiEMCAL, trackPhiEmcal, float); //! DECLARE_SOA_COLUMN(TrackTime, trackTime, float); //! Estimated time of the track in ns wrt collision().bc() or ambiguoustrack.bcSlice()[0] DECLARE_SOA_COLUMN(TrackTimeRes, trackTimeRes, float); //! Resolution of the track time in ns (see TrackFlags::TrackTimeResIsRange) -DECLARE_SOA_EXPRESSION_COLUMN(DetectorMap, detectorMap, uint8_t, //! Detector map: see enum DetectorMapEnum + +// expression columns changing between versions have to be declared in different namespaces + +DECLARE_SOA_EXPRESSION_COLUMN(DetectorMap, detectorMap, uint8_t, //! Detector map: see enum DetectorMapEnum ifnode(aod::track::itsClusterMap > (uint8_t)0, static_cast(o2::aod::track::ITS), (uint8_t)0x0) | ifnode(aod::track::tpcNClsFindable > (uint8_t)0, static_cast(o2::aod::track::TPC), (uint8_t)0x0) | ifnode(aod::track::trdPattern > (uint8_t)0, static_cast(o2::aod::track::TRD), (uint8_t)0x0) | ifnode((aod::track::tofChi2 >= 0.f) && (aod::track::tofExpMom > 0.f), static_cast(o2::aod::track::TOF), (uint8_t)0x0)); + +namespace v001 +{ +DECLARE_SOA_EXPRESSION_COLUMN(DetectorMap, detectorMap, uint8_t, //! Detector map version 1, see enum DetectorMapEnum + ifnode(aod::track::itsClusterSizes > (uint32_t)0, static_cast(o2::aod::track::ITS), (uint8_t)0x0) | + ifnode(aod::track::tpcNClsFindable > (uint8_t)0, static_cast(o2::aod::track::TPC), (uint8_t)0x0) | + ifnode(aod::track::trdPattern > (uint8_t)0, static_cast(o2::aod::track::TRD), (uint8_t)0x0) | + ifnode((aod::track::tofChi2 >= 0.f) && (aod::track::tofExpMom > 0.f), static_cast(o2::aod::track::TOF), (uint8_t)0x0)); +DECLARE_SOA_DYNAMIC_COLUMN(ITSClusterMap, itsClusterMap, //! ITS cluster map, one bit per a layer, starting from the innermost + [](uint32_t itsClusterSizes) -> uint8_t { + uint8_t clmap = 0; + for (unsigned int layer = 0; layer < 7; layer++) { + if ((itsClusterSizes >> (layer * 4)) & 0xf) { + clmap |= (1 << layer); + } + } + return clmap; + }); +DECLARE_SOA_DYNAMIC_COLUMN(ITSNCls, itsNCls, //! Number of ITS clusters + [](uint8_t itsClusterSizes) -> uint8_t { + uint8_t itsNcls = 0; + for (int layer = 0; layer < 7; layer++) { + if ((itsClusterSizes >> (layer * 4)) & 0xf) + itsNcls++; + } + return itsNcls; + }); +DECLARE_SOA_DYNAMIC_COLUMN(ITSNClsInnerBarrel, itsNClsInnerBarrel, //! Number of ITS clusters in the Inner Barrel + [](uint8_t itsClusterSizes) -> uint8_t { + uint8_t itsNclsInnerBarrel = 0; + for (int layer = 0; layer < 3; layer++) { + if ((itsClusterSizes >> (layer * 4)) & 0xf) + itsNclsInnerBarrel++; + } + return itsNclsInnerBarrel; + }); + +} // namespace v001 + DECLARE_SOA_DYNAMIC_COLUMN(HasITS, hasITS, //! Flag to check if track has a ITS match [](uint8_t detectorMap) -> bool { return detectorMap & o2::aod::track::ITS; }); DECLARE_SOA_DYNAMIC_COLUMN(HasTPC, hasTPC, //! Flag to check if track has a TPC match @@ -280,7 +323,6 @@ DECLARE_SOA_DYNAMIC_COLUMN(ITSNClsInnerBarrel, itsNClsInnerBarrel, //! Number of } return itsNclsInnerBarrel; }); - DECLARE_SOA_DYNAMIC_COLUMN(TPCFoundOverFindableCls, tpcFoundOverFindableCls, //! Ratio of found over findable clusters [](uint8_t tpcNClsFindable, int8_t tpcNClsFindableMinusFound) -> float { int16_t tpcNClsFound = (int16_t)tpcNClsFindable - tpcNClsFindableMinusFound; @@ -390,7 +432,7 @@ DECLARE_SOA_EXTENDED_TABLE(TracksCovIU, StoredTracksCovIU, "TRACKCOV_IU", //! Tr aod::track::C1PtTgl, aod::track::C1Pt21Pt2); -DECLARE_SOA_TABLE_FULL(StoredTracksExtra, "TracksExtra", "AOD", "TRACKEXTRA", //! On disk version of TracksExtra +DECLARE_SOA_TABLE_FULL(StoredTracksExtra_000, "TracksExtra", "AOD", "TRACKEXTRA", //! On disk version of TracksExtra, version 0 track::TPCInnerParam, track::Flags, track::ITSClusterMap, track::TPCNClsFindable, track::TPCNClsFindableMinusFound, track::TPCNClsFindableMinusCrossedRows, track::TPCNClsShared, track::TRDPattern, track::ITSChi2NCl, @@ -408,8 +450,31 @@ DECLARE_SOA_TABLE_FULL(StoredTracksExtra, "TracksExtra", "AOD", "TRACKEXTRA", // track::TPCFractionSharedCls, track::TrackEtaEMCAL, track::TrackPhiEMCAL, track::TrackTime, track::TrackTimeRes); -DECLARE_SOA_EXTENDED_TABLE(TracksExtra, StoredTracksExtra, "TRACKEXTRA", //! Additional track information (clusters, PID, etc.) +DECLARE_SOA_TABLE_FULL_VERSIONED(StoredTracksExtra_001, "TracksExtra", "AOD", "TRACKEXTRA", 1, // On disk version of TracksExtra, version 1 + track::TPCInnerParam, track::Flags, track::ITSClusterSizes, + track::TPCNClsFindable, track::TPCNClsFindableMinusFound, track::TPCNClsFindableMinusCrossedRows, + track::TPCNClsShared, track::TRDPattern, track::ITSChi2NCl, + track::TPCChi2NCl, track::TRDChi2, track::TOFChi2, + track::TPCSignal, track::TRDSignal, track::Length, track::TOFExpMom, + track::PIDForTracking, + track::IsPVContributor, + track::HasITS, track::HasTPC, + track::HasTRD, track::HasTOF, + track::TPCNClsFound, + track::TPCNClsCrossedRows, + track::v001::ITSClusterMap, track::v001::ITSNCls, track::v001::ITSNClsInnerBarrel, + track::TPCCrossedRowsOverFindableCls, + track::TPCFoundOverFindableCls, + track::TPCFractionSharedCls, + track::TrackEtaEMCAL, track::TrackPhiEMCAL, track::TrackTime, track::TrackTimeRes); + +DECLARE_SOA_EXTENDED_TABLE(TracksExtra_000, StoredTracksExtra_000, "TRACKEXTRA", //! Additional track information (clusters, PID, etc.) track::DetectorMap); +DECLARE_SOA_EXTENDED_TABLE(TracksExtra_001, StoredTracksExtra_001, "TRACKEXTRA", //! Additional track information (clusters, PID, etc.) + track::v001::DetectorMap); + +using StoredTracksExtra = StoredTracksExtra_000; +using TracksExtra = TracksExtra_000; using Track = Tracks::iterator; using TrackIU = TracksIU::iterator; @@ -1298,7 +1363,7 @@ using Run2BCInfo = Run2BCInfos::iterator; // ---- MC tables ---- namespace mccollision { -DECLARE_SOA_INDEX_COLUMN(BC, bc); //! BC index +DECLARE_SOA_INDEX_COLUMN(BC, bc); //! BC index DECLARE_SOA_COLUMN(GeneratorsID, generatorsID, short); //! disentangled generator IDs should be accessed from dynamic columns using getGenId, getCocktailId and getSourceId DECLARE_SOA_COLUMN(PosX, posX, float); //! X vertex position in cm DECLARE_SOA_COLUMN(PosY, posY, float); //! Y vertex position in cm @@ -1437,8 +1502,11 @@ namespace soa DECLARE_EQUIVALENT_FOR_INDEX(aod::Collisions_000, aod::Collisions_001); DECLARE_EQUIVALENT_FOR_INDEX(aod::StoredMcParticles_000, aod::StoredMcParticles_001); DECLARE_EQUIVALENT_FOR_INDEX(aod::StoredTracks, aod::StoredTracksIU); -DECLARE_EQUIVALENT_FOR_INDEX(aod::StoredTracks, aod::StoredTracksExtra); -DECLARE_EQUIVALENT_FOR_INDEX(aod::StoredTracksIU, aod::StoredTracksExtra); +DECLARE_EQUIVALENT_FOR_INDEX(aod::StoredTracks, aod::StoredTracksExtra_000); +DECLARE_EQUIVALENT_FOR_INDEX(aod::StoredTracksIU, aod::StoredTracksExtra_000); +DECLARE_EQUIVALENT_FOR_INDEX(aod::StoredTracks, aod::StoredTracksExtra_001); +DECLARE_EQUIVALENT_FOR_INDEX(aod::StoredTracksIU, aod::StoredTracksExtra_001); +DECLARE_EQUIVALENT_FOR_INDEX(aod::StoredTracksExtra_000, aod::StoredTracksExtra_001); DECLARE_EQUIVALENT_FOR_INDEX(aod::HMPID_000, aod::HMPID_001); } // namespace soa diff --git a/Framework/Core/src/AODReaderHelpers.cxx b/Framework/Core/src/AODReaderHelpers.cxx index 28b1c65f7def2..5f65f42e13427 100644 --- a/Framework/Core/src/AODReaderHelpers.cxx +++ b/Framework/Core/src/AODReaderHelpers.cxx @@ -176,7 +176,11 @@ AlgorithmSpec AODReaderHelpers::aodSpawnerCallback(std::vector& reque } else if (description == header::DataDescription{"TRACKCOV_IU"}) { outputs.adopt(Output{origin, description, version}, maker(o2::aod::TracksCovIUExtensionMetadata{})); } else if (description == header::DataDescription{"TRACKEXTRA"}) { - outputs.adopt(Output{origin, description, version}, maker(o2::aod::TracksExtraExtensionMetadata{})); + if (version == 0U) { + outputs.adopt(Output{origin, description, version}, maker(o2::aod::TracksExtra_000ExtensionMetadata{})); + } else if (version == 1U) { + outputs.adopt(Output{origin, description, version}, maker(o2::aod::TracksExtra_001ExtensionMetadata{})); + } } else if (description == header::DataDescription{"MFTTRACK"}) { outputs.adopt(Output{origin, description, version}, maker(o2::aod::MFTTracksExtensionMetadata{})); } else if (description == header::DataDescription{"FWDTRACK"}) { diff --git a/Framework/Core/test/test_AnalysisTask.cxx b/Framework/Core/test/test_AnalysisTask.cxx index b07c6a9afa0d4..30e58735257ed 100644 --- a/Framework/Core/test/test_AnalysisTask.cxx +++ b/Framework/Core/test/test_AnalysisTask.cxx @@ -164,7 +164,7 @@ TEST_CASE("AdaptorCompilation") REQUIRE(task2.inputs.size() == 10); REQUIRE(task2.inputs[1].binding == "TracksExtension"); REQUIRE(task2.inputs[2].binding == "Tracks"); - REQUIRE(task2.inputs[3].binding == "TracksExtraExtension"); + REQUIRE(task2.inputs[3].binding == "TracksExtra_000Extension"); REQUIRE(task2.inputs[4].binding == "TracksExtra"); REQUIRE(task2.inputs[5].binding == "TracksCovExtension"); REQUIRE(task2.inputs[6].binding == "TracksCov");