From d86f1944d2bdc8600c43e935a7ce750b05b1452e Mon Sep 17 00:00:00 2001 From: Maximiliano Puccio Date: Wed, 3 Jun 2026 12:08:06 +0200 Subject: [PATCH] Adapt global reco code to ITS per layer stream of clusters --- .../DataFormatsGlobalTracking/RecoContainer.h | 138 ++++++++++++- .../GlobalTracking/src/RecoContainer.cxx | 80 ++++++-- .../include/Align/AlignableDetectorITS.h | 2 + Detectors/Align/src/AlignableDetectorITS.cxx | 190 +++++++++--------- .../include/GlobalTracking/MatchCosmics.h | 6 +- .../include/GlobalTracking/MatchTPCITS.h | 3 + Detectors/GlobalTracking/src/MatchCosmics.cxx | 35 +++- Detectors/GlobalTracking/src/MatchTPCITS.cxx | 126 ++++++++---- .../StrangenessTrackingSpec.h | 2 +- .../TPCITSMatchingSpec.h | 2 +- .../src/StrangenessTrackingSpec.cxx | 4 +- .../src/TPCITSMatchingSpec.cxx | 6 +- .../src/strangeness-tracking-workflow.cxx | 3 +- .../src/tpcits-match-workflow.cxx | 4 +- .../include/SpacePoints/TrackInterpolation.h | 1 + .../SpacePoints/src/TrackInterpolation.cxx | 27 ++- .../TRDWorkflow/TRDGlobalTrackingSpec.h | 4 +- .../workflow/src/TRDGlobalTrackingSpec.cxx | 59 ++++-- .../workflow/src/trd-tracking-workflow.cxx | 3 +- .../StrangenessTracking/StrangenessTracker.h | 2 + .../src/StrangenessTracker.cxx | 58 ++++-- .../include/EveWorkflow/EveWorkflowHelper.h | 2 + .../Workflow/src/EveWorkflowHelper.cxx | 30 ++- GPU/Workflow/helper/src/GPUWorkflowHelper.cxx | 48 ++++- 24 files changed, 609 insertions(+), 226 deletions(-) diff --git a/DataFormats/Detectors/GlobalTracking/include/DataFormatsGlobalTracking/RecoContainer.h b/DataFormats/Detectors/GlobalTracking/include/DataFormatsGlobalTracking/RecoContainer.h index 31d531ef19265..93c902d52f24a 100644 --- a/DataFormats/Detectors/GlobalTracking/include/DataFormatsGlobalTracking/RecoContainer.h +++ b/DataFormats/Detectors/GlobalTracking/include/DataFormatsGlobalTracking/RecoContainer.h @@ -26,9 +26,18 @@ #include "SimulationDataFormat/MCCompLabel.h" #include "SimulationDataFormat/MCTruthContainer.h" #include "SimulationDataFormat/ConstMCTruthContainer.h" +#include "DataFormatsITS/TrackITS.h" +#include "DataFormatsITSMFT/DPLAlpideParam.h" +#include "DataFormatsITSMFT/CompCluster.h" +#include "DataFormatsITSMFT/ROFRecord.h" +#include "DataFormatsITSMFT/TrkClusRef.h" +#include "DetectorsCommonDataFormats/DetID.h" #include "DataFormatsCTP/LumiInfo.h" #include +#include #include +#include +#include // We forward declare the internal structures, to reduce header dependencies. // Please include headers for TPC Hits or TRD tracklets directly (DataFormatsTPC/WorkflowHelper.h / DataFormatsTRD/RecoInputContainer.h) @@ -222,7 +231,7 @@ struct DataRequest { void requestFV0RecPoints(bool mc); void requestFDDRecPoints(bool mc); void requestZDCRecEvents(bool mc); - void requestITSClusters(bool mc); + void requestITSClusters(bool mc, bool perLayer = false); void requestMFTClusters(bool mc); void requestTPCClusters(bool mc); void requestTPCOccMap(); @@ -323,6 +332,12 @@ struct RecoContainer { using GlobalIDSet = std::array; static constexpr float PS2MUS = 1e-6; + static constexpr int NITSLayers = o2::itsmft::DPLAlpideParam::getNLayers(); + + struct ITSClusterReference { + int layer = -1; + int index = -1; + }; o2::InteractionRecord startIR; // TF start IR @@ -331,6 +346,11 @@ struct RecoContainer { SVertexAccessor svtxPool; // containers for secondary vertex related objects STrackAccessor strkPool; // containers for strangeness tracking related objects CosmicsAccessor cosmPool; // containers for cosmics track data + std::array, NITSLayers> itsClustersROFRecordsPerLayer; + std::array, NITSLayers> itsClustersPerLayer; + std::array, NITSLayers> itsClustersPatternsPerLayer; + std::array>, NITSLayers> mcITSClustersPerLayer; + bool itsClustersPerLayerLoaded = false; std::unique_ptr> mcITSClusters; std::unique_ptr> mcTOFClusters; @@ -375,7 +395,7 @@ struct RecoContainer { void addMFTMCHMatches(o2::framework::ProcessingContext& pc, bool mc); void addMCHMIDMatches(o2::framework::ProcessingContext& pc, bool mc); - void addITSClusters(o2::framework::ProcessingContext& pc, bool mc); + void addITSClusters(o2::framework::ProcessingContext& pc, bool mc, bool perLayer = false); void addMFTClusters(o2::framework::ProcessingContext& pc, bool mc); void addTPCClusters(o2::framework::ProcessingContext& pc, bool mc, bool shmap, bool occmap); void addTPCOccMap(o2::framework::ProcessingContext& pc); @@ -498,10 +518,116 @@ struct RecoContainer { auto getITSABMCLabels() const { return getSpan(GTrackID::ITSAB, MCLABELS); } // ITS clusters - auto getITSClustersROFRecords() const { return getSpan(GTrackID::ITS, CLUSREFS); } - auto getITSClusters() const { return getSpan(GTrackID::ITS, CLUSTERS); } - auto getITSClustersPatterns() const { return getSpan(GTrackID::ITS, PATTERNS); } - auto getITSClustersMCLabels() const { return mcITSClusters.get(); } + auto getITSClustersROFRecords() const + { + checkFlatITSClusterAccess(); + return getSpan(GTrackID::ITS, CLUSREFS); + } + auto getITSClusters() const + { + checkFlatITSClusterAccess(); + return getSpan(GTrackID::ITS, CLUSTERS); + } + auto getITSClustersPatterns() const + { + checkFlatITSClusterAccess(); + return getSpan(GTrackID::ITS, PATTERNS); + } + bool hasITSClustersPerLayer() const { return itsClustersPerLayerLoaded; } + auto getITSClustersROFRecords(int layer) const { return itsClustersROFRecordsPerLayer[layer]; } + auto getITSClusters(int layer) const { return itsClustersPerLayer[layer]; } + auto getITSClustersPatterns(int layer) const { return itsClustersPatternsPerLayer[layer]; } + auto getITSClustersMCLabels() const + { + checkFlatITSClusterAccess(); + return mcITSClusters.get(); + } + auto getITSClustersMCLabels(int layer) const { return mcITSClustersPerLayer[layer].get(); } + int getNITSClusterLayers() const { return hasITSClustersPerLayer() ? NITSLayers : 1; } + size_t getNITSClusters() const + { + if (!hasITSClustersPerLayer()) { + return getITSClusters().size(); + } + size_t nClusters = 0; + for (int iLayer = 0; iLayer < NITSLayers; ++iLayer) { + nClusters += getITSClusters(iLayer).size(); + } + return nClusters; + } + ITSClusterReference getITSClusterReference(const o2::its::TrackITS& track, gsl::span clusterRefs, int clusterOrdinal) const + { + const auto clusterEntry = track.getClusterEntry(clusterOrdinal); + const auto clusterIndex = clusterRefs[clusterEntry]; + if (!hasITSClustersPerLayer()) { + return {-1, clusterIndex}; + } + return {getClusterLayer(track.getPattern(), clusterOrdinal, true), clusterIndex}; + } + ITSClusterReference getITSClusterReference(const o2::itsmft::TrkClusRef& trackletRef, gsl::span clusterRefs, int clusterOrdinal) const + { + const auto clusterEntry = trackletRef.getFirstEntry() + clusterOrdinal; + const auto clusterIndex = clusterRefs[clusterEntry]; + if (!hasITSClustersPerLayer()) { + return {-1, clusterIndex}; + } + return {getClusterLayer(trackletRef.pattern, clusterOrdinal, false), clusterIndex}; + } + template + std::vector makeFlatITSTrackClusterRefs(TrackSpan tracks, gsl::span clusterRefs, const std::array& layerOffsets) const + { + if (!hasITSClustersPerLayer()) { + return {}; + } + std::vector flatRefs(clusterRefs.size()); + for (const auto& track : tracks) { + for (int iCluster = 0; iCluster < track.getNumberOfClusters(); ++iCluster) { + const auto ref = getITSClusterReference(track, clusterRefs, iCluster); + flatRefs[track.getClusterEntry(iCluster)] = layerOffsets[ref.layer] + ref.index; + } + } + return flatRefs; + } + template + std::vector makeFlatITSABClusterRefs(TrackletRefSpan trackletRefs, gsl::span clusterRefs, const std::array& layerOffsets) const + { + if (!hasITSClustersPerLayer()) { + return {}; + } + std::vector flatRefs(clusterRefs.size()); + for (const auto& trackletRef : trackletRefs) { + for (int iCluster = 0; iCluster < trackletRef.getNClusters(); ++iCluster) { + const auto ref = getITSClusterReference(trackletRef, clusterRefs, iCluster); + flatRefs[trackletRef.getFirstEntry() + iCluster] = layerOffsets[ref.layer] + ref.index; + } + } + return flatRefs; + } + + void checkFlatITSClusterAccess() const + { + if (hasITSClustersPerLayer()) { + throw std::runtime_error("flat ITS cluster access requested while ITS clusters are loaded per layer"); + } + } + + static int getClusterLayer(uint32_t pattern, int clusterOrdinal, bool outerToInner) + { + if (outerToInner) { + for (int iLayer = NITSLayers; iLayer--;) { + if ((pattern & (0x1u << iLayer)) && clusterOrdinal-- == 0) { + return iLayer; + } + } + } else { + for (int iLayer = 0; iLayer < NITSLayers; ++iLayer) { + if ((pattern & (0x1u << iLayer)) && clusterOrdinal-- == 0) { + return iLayer; + } + } + } + return -1; + } // MFT const o2::mft::TrackMFT& getMFTTrack(GTrackID gid) const { return getTrack(gid); } diff --git a/DataFormats/Detectors/GlobalTracking/src/RecoContainer.cxx b/DataFormats/Detectors/GlobalTracking/src/RecoContainer.cxx index 141d4520229fe..b8b0d5045be41 100644 --- a/DataFormats/Detectors/GlobalTracking/src/RecoContainer.cxx +++ b/DataFormats/Detectors/GlobalTracking/src/RecoContainer.cxx @@ -41,6 +41,7 @@ #include "Framework/ProcessingContext.h" #include "Framework/DataRefUtils.h" #include "Framework/CCDBParamSpec.h" +#include "Headers/DataHeader.h" #ifdef ENABLE_UPGRADES #include "ITS3Reconstruction/TopologyDictionary.h" @@ -226,31 +227,51 @@ void DataRequest::requestTOFMatches(o2::dataformats::GlobalTrackID::mask_t src, } } -void DataRequest::requestITSClusters(bool mc) +void DataRequest::requestITSClusters(bool mc, bool perLayer) { - addInput({"clusITS", "ITS", "COMPCLUSTERS", 0, Lifetime::Timeframe}); - addInput({"clusITSPatt", "ITS", "PATTERNS", 0, Lifetime::Timeframe}); - addInput({"clusITSROF", "ITS", "CLUSTERSROF", 0, Lifetime::Timeframe}); + const int nLayers = perLayer ? o2::itsmft::DPLAlpideParam::getNLayers() : 1; + for (int iLayer = 0; iLayer < nLayers; ++iLayer) { + const auto suffix = perLayer ? std::to_string(iLayer) : std::string{}; + const auto subspec = static_cast(iLayer); + addInput({"clusITS" + suffix, "ITS", "COMPCLUSTERS", subspec, Lifetime::Timeframe}); + addInput({"clusITSPatt" + suffix, "ITS", "PATTERNS", subspec, Lifetime::Timeframe}); + addInput({"clusITSROF" + suffix, "ITS", "CLUSTERSROF", subspec, Lifetime::Timeframe}); + } addInput({"alpparITS", "ITS", "ALPIDEPARAM", 0, Lifetime::Condition, ccdbParamSpec("ITS/Config/AlpideParam")}); if (mc) { - addInput({"clusITSMC", "ITS", "CLUSTERSMCTR", 0, Lifetime::Timeframe}); + for (int iLayer = 0; iLayer < nLayers; ++iLayer) { + const auto suffix = perLayer ? std::to_string(iLayer) : std::string{}; + const auto subspec = static_cast(iLayer); + addInput({"clusITSMC" + suffix, "ITS", "CLUSTERSMCTR", subspec, Lifetime::Timeframe}); + } } addInput({"cldictITS", "ITS", "CLUSDICT", 0, Lifetime::Condition, ccdbParamSpec("ITS/Calib/ClusterDictionary")}); requestMap["clusITS"] = mc; + requestMap["clusITSPerLayer"] = perLayer; } #ifdef ENABLE_UPGRADES void DataRequest::requestIT3Clusters(bool mc) { - addInput({"clusITS", "ITS", "COMPCLUSTERS", 0, Lifetime::Timeframe}); - addInput({"clusITSPatt", "ITS", "PATTERNS", 0, Lifetime::Timeframe}); - addInput({"clusITSROF", "ITS", "CLUSTERSROF", 0, Lifetime::Timeframe}); + constexpr int nLayers = o2::itsmft::DPLAlpideParam::getNLayers(); + for (int iLayer = 0; iLayer < nLayers; ++iLayer) { + const auto suffix = std::to_string(iLayer); + const auto subspec = static_cast(iLayer); + addInput({"clusITS" + suffix, "ITS", "COMPCLUSTERS", subspec, Lifetime::Timeframe}); + addInput({"clusITSPatt" + suffix, "ITS", "PATTERNS", subspec, Lifetime::Timeframe}); + addInput({"clusITSROF" + suffix, "ITS", "CLUSTERSROF", subspec, Lifetime::Timeframe}); + } addInput({"alpparITS", "ITS", "ALPIDEPARAM", 0, Lifetime::Condition, ccdbParamSpec("ITS/Config/AlpideParam")}); if (mc) { - addInput({"clusITSMC", "ITS", "CLUSTERSMCTR", 0, Lifetime::Timeframe}); + for (int iLayer = 0; iLayer < nLayers; ++iLayer) { + const auto suffix = std::to_string(iLayer); + const auto subspec = static_cast(iLayer); + addInput({"clusITSMC" + suffix, "ITS", "CLUSTERSMCTR", subspec, Lifetime::Timeframe}); + } } addInput({"cldictIT3", "IT3", "CLUSDICT", 0, Lifetime::Condition, ccdbParamSpec("IT3/Calib/ClusterDictionary")}); requestMap["clusIT3"] = mc; + requestMap["clusITSPerLayer"] = true; } #endif @@ -695,7 +716,8 @@ void RecoContainer::collectData(ProcessingContext& pc, const DataRequest& reques req = reqMap.find("clusITS"); if (req != reqMap.end()) { - addITSClusters(pc, req->second); + const auto perLayer = reqMap.find("clusITSPerLayer"); + addITSClusters(pc, req->second, perLayer != reqMap.end() && perLayer->second); } #ifdef ENABLE_UPGRADES @@ -1068,16 +1090,30 @@ void RecoContainer::addHMPMatches(ProcessingContext& pc, bool mc) } //__________________________________________________________ -void RecoContainer::addITSClusters(ProcessingContext& pc, bool mc) +void RecoContainer::addITSClusters(ProcessingContext& pc, bool mc, bool perLayer) { if (pc.services().get().globalRunNumberChanged) { // this params need to be queried only once pc.inputs().get("cldictITS"); // just to trigger the finaliseCCDB pc.inputs().get*>("alpparITS"); // note: configurable param does not need finaliseCCDB } - commonPool[GTrackID::ITS].registerContainer(pc.inputs().get>("clusITSROF"), CLUSREFS); - commonPool[GTrackID::ITS].registerContainer(pc.inputs().get>("clusITS"), CLUSTERS); - commonPool[GTrackID::ITS].registerContainer(pc.inputs().get>("clusITSPatt"), PATTERNS); - if (mc) { + itsClustersPerLayerLoaded = perLayer; + if (perLayer) { + for (int iLayer = 0; iLayer < NITSLayers; ++iLayer) { + const auto suffix = std::to_string(iLayer); + itsClustersROFRecordsPerLayer[iLayer] = pc.inputs().get>("clusITSROF" + suffix); + itsClustersPerLayer[iLayer] = pc.inputs().get>("clusITS" + suffix); + itsClustersPatternsPerLayer[iLayer] = pc.inputs().get>("clusITSPatt" + suffix); + } + } else { + commonPool[GTrackID::ITS].registerContainer(pc.inputs().get>("clusITSROF"), CLUSREFS); + commonPool[GTrackID::ITS].registerContainer(pc.inputs().get>("clusITS"), CLUSTERS); + commonPool[GTrackID::ITS].registerContainer(pc.inputs().get>("clusITSPatt"), PATTERNS); + } + if (mc && perLayer) { + for (int iLayer = 0; iLayer < NITSLayers; ++iLayer) { + mcITSClustersPerLayer[iLayer] = pc.inputs().get*>("clusITSMC" + std::to_string(iLayer)); + } + } else if (mc) { mcITSClusters = pc.inputs().get*>("clusITSMC"); } } @@ -1089,11 +1125,17 @@ void RecoContainer::addIT3Clusters(ProcessingContext& pc, bool mc) pc.inputs().get*>("alpparITS"); // note: configurable param does not need finaliseCCDB pc.inputs().get("cldictIT3"); // just to trigger the finaliseCCDB } - commonPool[GTrackID::ITS].registerContainer(pc.inputs().get>("clusITSROF"), CLUSREFS); - commonPool[GTrackID::ITS].registerContainer(pc.inputs().get>("clusITS"), CLUSTERS); - commonPool[GTrackID::ITS].registerContainer(pc.inputs().get>("clusITSPatt"), PATTERNS); + itsClustersPerLayerLoaded = true; + for (int iLayer = 0; iLayer < NITSLayers; ++iLayer) { + const auto suffix = std::to_string(iLayer); + itsClustersROFRecordsPerLayer[iLayer] = pc.inputs().get>("clusITSROF" + suffix); + itsClustersPerLayer[iLayer] = pc.inputs().get>("clusITS" + suffix); + itsClustersPatternsPerLayer[iLayer] = pc.inputs().get>("clusITSPatt" + suffix); + } if (mc) { - mcITSClusters = pc.inputs().get*>("clusITSMC"); + for (int iLayer = 0; iLayer < NITSLayers; ++iLayer) { + mcITSClustersPerLayer[iLayer] = pc.inputs().get*>("clusITSMC" + std::to_string(iLayer)); + } } } #endif diff --git a/Detectors/Align/include/Align/AlignableDetectorITS.h b/Detectors/Align/include/Align/AlignableDetectorITS.h index 5f1816d8368b8..e09a5bb95317e 100644 --- a/Detectors/Align/include/Align/AlignableDetectorITS.h +++ b/Detectors/Align/include/Align/AlignableDetectorITS.h @@ -77,6 +77,8 @@ class AlignableDetectorITS : public AlignableDetector protected: // std::vector mITSClustersArray; + std::vector mITSTrackClusIdxFlat; + std::vector mITSABTrackClusIdxFlat; std::vector mOverlapCandidateID; // pool of indices for potentially overlapping clusters std::vector mOverlapClusRef; // 1st entry in mOverlapCandidateID for the overlapping cluster indices of each cluster std::vector mOverlaps; diff --git a/Detectors/Align/src/AlignableDetectorITS.cxx b/Detectors/Align/src/AlignableDetectorITS.cxx index 7387ae4620bf3..0bfc2c86d609c 100644 --- a/Detectors/Align/src/AlignableDetectorITS.cxx +++ b/Detectors/Align/src/AlignableDetectorITS.cxx @@ -89,10 +89,10 @@ void AlignableDetectorITS::defineVolumes() sym2vol[volMod->getSymName()] = volMod; volMod->setParent(volHSt); } // module - } //halfstave - } // stave - } // layer halfBarrel - } // layer + } // halfstave + } // stave + } // layer halfBarrel + } // layer for (int ich = 0; ich < geom->getNumberOfChips(); ich++) { int chID = o2::base::GeometryManager::getSensID(mDetID, ich); @@ -153,7 +153,8 @@ int AlignableDetectorITS::processPoints(GIndex gid, int npntCut, bool inv) if (track.getNClusters() < npntCut) { return -1; } - const auto& clusIdx = recoData->getITSTracksClusterRefs(); + const auto clusIdxOrig = recoData->getITSTracksClusterRefs(); + const auto clusIdx = recoData->hasITSClustersPerLayer() ? gsl::span{mITSTrackClusIdxFlat} : clusIdxOrig; // do we want to apply some cuts? int clEntry = track.getFirstClusterEntry(); int preevSensID = -1; @@ -181,7 +182,8 @@ int AlignableDetectorITS::processPoints(GIndex gid, int npntCut, bool inv) } } else { // ITSAB const auto& trkITSABref = recoData->getITSABRefs()[gid.getIndex()]; - const auto& ABTrackClusIdx = recoData->getITSABClusterRefs(); + const auto ABTrackClusIdxOrig = recoData->getITSABClusterRefs(); + const auto ABTrackClusIdx = recoData->hasITSClustersPerLayer() ? gsl::span{mITSABTrackClusIdxFlat} : ABTrackClusIdxOrig; int nCl = trkITSABref.getNClusters(); int clEntry = trkITSABref.getFirstEntry(); for (int icl = 0; icl < nCl; icl++) { // clusters are stored from inner to outer layers @@ -256,19 +258,16 @@ bool AlignableDetectorITS::prepareDetectorData() // prepare TF data for processing: convert clusters const auto& algConf = AlignConfig::Instance(); auto recoData = mController->getRecoContainer(); - const auto clusITS = recoData->getITSClusters(); - const auto clusITSROF = recoData->getITSClustersROFRecords(); - const auto patterns = recoData->getITSClustersPatterns(); - auto pattIt = patterns.begin(); mITSClustersArray.clear(); - mITSClustersArray.reserve(clusITS.size()); + mITSClustersArray.reserve(recoData->getNITSClusters()); if (algConf.ITSOverlapMargin > 0) { mOverlapClusRef.clear(); - mOverlapClusRef.resize(clusITS.size(), -1); + mOverlapClusRef.resize(recoData->getNITSClusters(), -1); mOverlapCandidateID.clear(); - mOverlapCandidateID.reserve(clusITS.size()); + mOverlapCandidateID.reserve(recoData->getNITSClusters()); } + std::array layerOffsets{}; static std::vector edgeClusters; int ROFCount = 0; int16_t curSensID = -1; @@ -278,103 +277,108 @@ bool AlignableDetectorITS::prepareDetectorData() }; std::array chipROFStart{}; // fill only for clusters with overlaps - for (const auto& rof : clusITSROF) { - int maxic = rof.getFirstEntry() + rof.getNEntries(); - edgeClusters.clear(); - for (int ic = rof.getFirstEntry(); ic < maxic; ic++) { - const auto& c = clusITS[ic]; - int16_t sensID = c.getSensorID(); - auto* sensor = getSensor(sensID); - double sigmaY2, sigmaZ2, sigmaYZ = 0, locXYZC[3], traXYZ[3]; - auto pattItCopy = pattIt; - auto locXYZ = o2::its::ioutils::extractClusterDataA(c, pattIt, mITSDict, sigmaY2, sigmaZ2); // local ideal coordinates - const auto& matAlg = sensor->getMatrixClAlg(); // local alignment matrix !!! RS FIXME - matAlg.LocalToMaster(locXYZ.data(), locXYZC); // aligned point in the local frame - const auto& mat = sensor->getMatrixT2L(); // RS FIXME check if correct - mat.MasterToLocal(locXYZC, traXYZ); - auto& cl3d = mITSClustersArray.emplace_back(sensID, traXYZ[0], traXYZ[1], traXYZ[2], sigmaY2, sigmaZ2, sigmaYZ); // local --> tracking + auto processClusterInput = [&](const gsl::span clusITSROF, const gsl::span clusITS, const gsl::span patterns) { + auto pattIt = patterns.begin(); + for (const auto& rof : clusITSROF) { + int maxic = rof.getFirstEntry() + rof.getNEntries(); + edgeClusters.clear(); + for (int ic = rof.getFirstEntry(); ic < maxic; ic++) { + const auto& c = clusITS[ic]; + int16_t sensID = c.getSensorID(); + auto* sensor = getSensor(sensID); + double sigmaY2, sigmaZ2, sigmaYZ = 0, locXYZC[3], traXYZ[3]; + auto pattItCopy = pattIt; + auto locXYZ = o2::its::ioutils::extractClusterDataA(c, pattIt, mITSDict, sigmaY2, sigmaZ2); // local ideal coordinates + const auto& matAlg = sensor->getMatrixClAlg(); // local alignment matrix !!! RS FIXME + matAlg.LocalToMaster(locXYZ.data(), locXYZC); // aligned point in the local frame + const auto& mat = sensor->getMatrixT2L(); // RS FIXME check if correct + mat.MasterToLocal(locXYZC, traXYZ); + auto& cl3d = mITSClustersArray.emplace_back(sensID, traXYZ[0], traXYZ[1], traXYZ[2], sigmaY2, sigmaZ2, sigmaYZ); // local --> tracking + const int workClusterID = mITSClustersArray.size() - 1; - if (algConf.ITSOverlapMargin > 0) { - // fill chips overlaps info for clusters whose center is within of the algConf.ITSOverlapMargin distance from the chip min or max row edge - // but the pixel closest to this edge has distance of at least algConf.ITSOverlapEdgeRows from the edge - int row = 0, col = 0; - o2::itsmft::SegmentationAlpide::localToDetectorUnchecked(locXYZ[0], locXYZ[2], row, col); - int drow = row < o2::itsmft::SegmentationAlpide::NRows / 2 ? row : o2::itsmft::SegmentationAlpide::NRows - row - 1; // distance to the edge - if (drow * o2::itsmft::SegmentationAlpide::PitchRow < algConf.ITSOverlapMargin) { // rough check is passed, check if the edge cluster is indeed good - cl3d.setBit(row < o2::itsmft::SegmentationAlpide::NRows / 2 ? EdgeFlags::LowRow : EdgeFlags::HighRow); // flag that this is an edge cluster and indicate the low/high row side - // check if it is not too close to the edge (to be biased) - if (algConf.ITSOverlapEdgeRows > 0) { // is there a restriction? - auto pattID = c.getPatternID(); - drow = c.getRow(); - if (pattID != itsmft::CompCluster::InvalidPatternID) { - if (!mITSDict->isGroup(pattID)) { - const auto& patt = mITSDict->getPattern(pattID); // reference pixel is min row/col corner + if (algConf.ITSOverlapMargin > 0) { + int row = 0, col = 0; + o2::itsmft::SegmentationAlpide::localToDetectorUnchecked(locXYZ[0], locXYZ[2], row, col); + int drow = row < o2::itsmft::SegmentationAlpide::NRows / 2 ? row : o2::itsmft::SegmentationAlpide::NRows - row - 1; + if (drow * o2::itsmft::SegmentationAlpide::PitchRow < algConf.ITSOverlapMargin) { + cl3d.setBit(row < o2::itsmft::SegmentationAlpide::NRows / 2 ? EdgeFlags::LowRow : EdgeFlags::HighRow); + if (algConf.ITSOverlapEdgeRows > 0) { + auto pattID = c.getPatternID(); + drow = c.getRow(); + if (pattID != itsmft::CompCluster::InvalidPatternID) { + if (!mITSDict->isGroup(pattID)) { + const auto& patt = mITSDict->getPattern(pattID); + if (row > o2::itsmft::SegmentationAlpide::NRows / 2) { + drow = o2::itsmft::SegmentationAlpide::NRows - 1 - (drow + patt.getRowSpan() - 1); + } + } else { + o2::itsmft::ClusterPattern patt(pattItCopy); + drow = row < o2::itsmft::SegmentationAlpide::NRows / 2 ? drow - patt.getRowSpan() / 2 : o2::itsmft::SegmentationAlpide::NRows - 1 - (drow + patt.getRowSpan() / 2 - 1); + } + } else { + o2::itsmft::ClusterPattern patt(pattItCopy); if (row > o2::itsmft::SegmentationAlpide::NRows / 2) { drow = o2::itsmft::SegmentationAlpide::NRows - 1 - (drow + patt.getRowSpan() - 1); } - } else { // group: reference pixel is the one containing the COG - o2::itsmft::ClusterPattern patt(pattItCopy); - drow = row < o2::itsmft::SegmentationAlpide::NRows / 2 ? drow - patt.getRowSpan() / 2 : o2::itsmft::SegmentationAlpide::NRows - 1 - (drow + patt.getRowSpan() / 2 - 1); } - } else { - o2::itsmft::ClusterPattern patt(pattItCopy); // reference pixel is min row/col corner - if (row > o2::itsmft::SegmentationAlpide::NRows / 2) { - drow = o2::itsmft::SegmentationAlpide::NRows - 1 - (drow + patt.getRowSpan() - 1); + if (drow < algConf.ITSOverlapEdgeRows) { + cl3d.setBit(EdgeFlags::Biased); } } - if (drow < algConf.ITSOverlapEdgeRows) { // too close to the edge, flag this - cl3d.setBit(EdgeFlags::Biased); - } - } - if (!cl3d.isBitSet(EdgeFlags::Biased)) { - if (chipROFStart[sensID].rofCount != ROFCount) { // remember 1st entry - chipROFStart[sensID].rofCount = ROFCount; - chipROFStart[sensID].chipFirstEntry = edgeClusters.size(); // remember 1st entry of edge cluster for this chip + if (!cl3d.isBitSet(EdgeFlags::Biased)) { + if (chipROFStart[sensID].rofCount != ROFCount) { + chipROFStart[sensID].rofCount = ROFCount; + chipROFStart[sensID].chipFirstEntry = edgeClusters.size(); + } + edgeClusters.push_back(workClusterID); } - edgeClusters.push_back(ic); } } } - } // clusters of ROF - // relate edge clusters of ROF to each other - int prevSensID = -1; - for (auto ic : edgeClusters) { - auto& cl = mITSClustersArray[ic]; - int sensID = cl.getSensorID(); - auto ovl = mOverlaps[sensID]; - int ovlCount = 0; - for (int ir = 0; ir < OVL::NSides; ir++) { - if (ovl.rowSide[ir] == OVL::NONE) { // no overlap from this row side - continue; - } - int chipOvl = ovl.rowSide[ir]; // look for overlaps with this chip - // are there clusters with overlaps on chipOvl? - if (chipROFStart[chipOvl].rofCount == ROFCount) { - auto oClusID = edgeClusters[chipROFStart[chipOvl].chipFirstEntry]; - while (oClusID < int(mITSClustersArray.size())) { - auto oClus = mITSClustersArray[oClusID]; - if (oClus.getSensorID() != sensID) { - break; // no more clusters on the overlapping chip - } - if (oClus.isBitSet(ovl.rowSideOverlap[ir]) && // make sure that the edge cluster is on the right side of the row - !oClus.isBitSet(EdgeFlags::Biased) && // not too close to the edge - std::abs(oClus.getZ() - cl.getZ()) < algConf.ITSOverlapMaxDZ) { // apply fiducial cut on Z distance of 2 clusters - // register overlaping cluster - if (!ovlCount) { // 1st overlap - mOverlapClusRef[ic] = mOverlapCandidateID.size(); + for (auto ic : edgeClusters) { + auto& cl = mITSClustersArray[ic]; + int sensID = cl.getSensorID(); + auto ovl = mOverlaps[sensID]; + int ovlCount = 0; + for (int ir = 0; ir < OVL::NSides; ir++) { + if (ovl.rowSide[ir] == OVL::NONE) { + continue; + } + int chipOvl = ovl.rowSide[ir]; + if (chipROFStart[chipOvl].rofCount == ROFCount) { + auto oClusID = edgeClusters[chipROFStart[chipOvl].chipFirstEntry]; + while (oClusID < int(mITSClustersArray.size())) { + auto oClus = mITSClustersArray[oClusID]; + if (oClus.getSensorID() != sensID) { + break; + } + if (oClus.isBitSet(ovl.rowSideOverlap[ir]) && !oClus.isBitSet(EdgeFlags::Biased) && std::abs(oClus.getZ() - cl.getZ()) < algConf.ITSOverlapMaxDZ) { + if (!ovlCount) { + mOverlapClusRef[ic] = mOverlapCandidateID.size(); + } + mOverlapCandidateID.push_back(oClusID); + ovlCount++; } - mOverlapCandidateID.push_back(oClusID); - ovlCount++; + oClusID++; } - oClusID++; } } + cl.setCount(std::min(127, ovlCount)); } - cl.setCount(std::min(127, ovlCount)); + ROFCount++; } + }; - ROFCount++; - } // loop over ROFs + if (recoData->hasITSClustersPerLayer()) { + for (int iLayer = 0; iLayer < o2::globaltracking::RecoContainer::NITSLayers; ++iLayer) { + layerOffsets[iLayer] = mITSClustersArray.size(); + processClusterInput(recoData->getITSClustersROFRecords(iLayer), recoData->getITSClusters(iLayer), recoData->getITSClustersPatterns(iLayer)); + } + mITSTrackClusIdxFlat = recoData->makeFlatITSTrackClusterRefs(recoData->getITSTracks(), recoData->getITSTracksClusterRefs(), layerOffsets); + mITSABTrackClusIdxFlat = recoData->makeFlatITSABClusterRefs(recoData->getITSABRefs(), recoData->getITSABClusterRefs(), layerOffsets); + } else { + processClusterInput(recoData->getITSClustersROFRecords(), recoData->getITSClusters(), recoData->getITSClustersPatterns()); + } return true; } @@ -418,7 +422,7 @@ void AlignableDetectorITS::updatePointByTrackInfo(AlignmentPoint* pnt, const tra { // update point using specific error parameterization // the track must be in the detector tracking frame - //TODO RS + // TODO RS /* const AlignableSensor* sens = pnt->getSensor(); int vid = sens->getVolID(); diff --git a/Detectors/GlobalTracking/include/GlobalTracking/MatchCosmics.h b/Detectors/GlobalTracking/include/GlobalTracking/MatchCosmics.h index 896351f7baa06..55c99b07b16d6 100644 --- a/Detectors/GlobalTracking/include/GlobalTracking/MatchCosmics.h +++ b/Detectors/GlobalTracking/include/GlobalTracking/MatchCosmics.h @@ -86,6 +86,10 @@ class MatchCosmics short vtIDMin = -1; ///< id of the 1st compatible vertex short vtIDMax = -1; ///< id of the last compatible vertex }; + struct ITSClusterData { + std::vector> clusters; + std::vector trackClusterRefs; + }; void setTPCCorrMaps(const o2::gpu::TPCFastTransformPOD* maph); void setTPCVDrift(const o2::tpc::VDriftCorrFact& v); void setITSROFrameLengthMUS(float fums) { mITSROFrameLengthMUS = fums; } @@ -134,7 +138,7 @@ class MatchCosmics bool validateMatch(int partner0); void selectWinners(); void refitWinners(const o2::globaltracking::RecoContainer& data); - std::vector> prepareITSClusters(const o2::globaltracking::RecoContainer& data) const; + ITSClusterData prepareITSClusters(const o2::globaltracking::RecoContainer& data) const; std::vector mSeeds; std::vector mRecords; diff --git a/Detectors/GlobalTracking/include/GlobalTracking/MatchTPCITS.h b/Detectors/GlobalTracking/include/GlobalTracking/MatchTPCITS.h index e736f0c9c8a42..e8c900b795552 100644 --- a/Detectors/GlobalTracking/include/GlobalTracking/MatchTPCITS.h +++ b/Detectors/GlobalTracking/include/GlobalTracking/MatchTPCITS.h @@ -662,10 +662,12 @@ class MatchTPCITS 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 mITSTrackClusIdxFlat; ///< remapped ITS track cluster indices for local cluster working array 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 + std::vector mITSClusterROFRecFlat; ///< remapped ITS cluster ROF records for local cluster working array gsl::span mFITInfo; ///< optional input FIT info span gsl::span mTPCRefitterShMap; ///< externally set TPC clusters sharing map @@ -679,6 +681,7 @@ class MatchTPCITS const o2::tpc::ClusterNativeAccess* mTPCClusterIdxStruct = nullptr; ///< struct holding the TPC cluster indices const o2::dataformats::MCTruthContainer* mITSClsLabels = nullptr; ///< input ITS Cluster MC labels + o2::dataformats::MCTruthContainer mITSClsLabelsFlat; ///< remapped ITS cluster MC labels for local cluster working array gsl::span mITSTrkLabels; ///< input ITS Track MC labels gsl::span mTPCTrkLabels; ///< input TPC Track MC labels /// <<<----- diff --git a/Detectors/GlobalTracking/src/MatchCosmics.cxx b/Detectors/GlobalTracking/src/MatchCosmics.cxx index 53c87d39974c7..7cca723e10171 100644 --- a/Detectors/GlobalTracking/src/MatchCosmics.cxx +++ b/Detectors/GlobalTracking/src/MatchCosmics.cxx @@ -36,6 +36,7 @@ #include "DataFormatsTPC/WorkflowHelper.h" #include "DataFormatsTPC/VDriftCorrFact.h" #include "TPCFastTransformPOD.h" +#include #include #include #include @@ -134,7 +135,8 @@ void MatchCosmics::refitWinners(const o2::globaltracking::RecoContainer& data) tpcClusOccMap.data(), tpcClusOccMap.size(), nullptr, o2::base::Propagator::Instance()); } - const auto& itsClusters = prepareITSClusters(data); + const auto itsClusterData = prepareITSClusters(data); + const auto& itsClusters = itsClusterData.clusters; // RS FIXME: this is probably a temporary solution, since ITS tracking over boundaries will likely change the TrackITS format std::vector itsTracksROF; @@ -147,10 +149,11 @@ void MatchCosmics::refitWinners(const o2::globaltracking::RecoContainer& data) } } - auto refitITSTrack = [this, &data, &itsTracksROF, &itsClusters](o2::track::TrackParCov& trFit, GTrackID gidx, float& chi2, bool inward = false) { + auto refitITSTrack = [this, &data, &itsTracksROF, &itsClusters, &itsClusterData](o2::track::TrackParCov& trFit, GTrackID gidx, float& chi2, bool inward = false) { const auto& itsTrOrig = data.getITSTrack(gidx); int nclRefit = 0, ncl = itsTrOrig.getNumberOfClusters(), rof = itsTracksROF[gidx.getIndex()]; - const auto& itsTrackClusRefs = data.getITSTracksClusterRefs(); + const auto itsTrackClusRefsOrig = data.getITSTracksClusterRefs(); + const auto& itsTrackClusRefs = data.hasITSClustersPerLayer() ? gsl::span{itsClusterData.trackClusterRefs} : itsTrackClusRefsOrig; int clEntry = itsTrOrig.getFirstClusterEntry(); const auto propagator = o2::base::Propagator::Instance(); const auto geomITS = o2::its::GeometryTGeo::Instance(); @@ -208,7 +211,7 @@ void MatchCosmics::refitWinners(const o2::globaltracking::RecoContainer& data) trCosm.setQ2Pt(-o2::track::kMostProbablePt); } int retVal = tpcRefitter->RefitTrackAsTrackParCov(trCosm, tpcTrOrig.getClusterRef(), t0 * tpcTBinMUSInv, &chi2, false, false); // inward refit, reset - if (retVal < 0) { // refit failed + if (retVal < 0) { // refit failed LOG(debug) << "Inward refit of btm TPC track failed."; continue; } @@ -622,17 +625,27 @@ void MatchCosmics::init() } //________________________________________________________ -std::vector> MatchCosmics::prepareITSClusters(const o2::globaltracking::RecoContainer& data) const +MatchCosmics::ITSClusterData MatchCosmics::prepareITSClusters(const o2::globaltracking::RecoContainer& data) const { - std::vector> itscl; - const auto& clusITS = data.getITSClusters(); - if (clusITS.size()) { + ITSClusterData out; + out.clusters.reserve(data.getNITSClusters()); + if (data.hasITSClustersPerLayer()) { + std::array layerOffsets{}; + for (int iLayer = 0; iLayer < o2::globaltracking::RecoContainer::NITSLayers; ++iLayer) { + const auto& clusITS = data.getITSClusters(iLayer); + const auto& patterns = data.getITSClustersPatterns(iLayer); + layerOffsets[iLayer] = out.clusters.size(); + auto pattIt = patterns.begin(); + o2::its::ioutils::convertCompactClusters(clusITS, pattIt, out.clusters, mITSDict); + } + out.trackClusterRefs = data.makeFlatITSTrackClusterRefs(data.getITSTracks(), data.getITSTracksClusterRefs(), layerOffsets); + } else { + const auto& clusITS = data.getITSClusters(); const auto& patterns = data.getITSClustersPatterns(); - itscl.reserve(clusITS.size()); auto pattIt = patterns.begin(); - o2::its::ioutils::convertCompactClusters(clusITS, pattIt, itscl, mITSDict); + o2::its::ioutils::convertCompactClusters(clusITS, pattIt, out.clusters, mITSDict); } - return std::move(itscl); + return out; } //______________________________________________ diff --git a/Detectors/GlobalTracking/src/MatchTPCITS.cxx b/Detectors/GlobalTracking/src/MatchTPCITS.cxx index 1457790c7c531..6d147b58aca6b 100644 --- a/Detectors/GlobalTracking/src/MatchTPCITS.cxx +++ b/Detectors/GlobalTracking/src/MatchTPCITS.cxx @@ -19,6 +19,7 @@ #include #include #include +#include #include #include "Field/MagneticField.h" @@ -174,6 +175,9 @@ void MatchTPCITS::clear() mITSTrackROFContMapping.clear(); mITSClustersArray.clear(); mITSClusterSizes.clear(); + mITSTrackClusIdxFlat.clear(); + mITSClusterROFRecFlat.clear(); + mITSClsLabelsFlat.clear(); mTPCABSeeds.clear(); mTPCABIndexCache.clear(); mABWinnersIDs.clear(); @@ -644,63 +648,105 @@ bool MatchTPCITS::prepareITSData() mTimer[SWPrepITS].Start(false); const auto& inp = *mRecoCont; - // ITS clusters - mITSClusterROFRec = inp.getITSClustersROFRecords(); - const auto clusITS = inp.getITSClusters(); - if (mITSClusterROFRec.empty() || clusITS.empty()) { - LOG(info) << "No ITS clusters"; - return false; - } - const auto patterns = inp.getITSClustersPatterns(); - auto pattIt = patterns.begin(); - mITSClustersArray.reserve(clusITS.size()); + auto appendClusterSizes = [this](const auto& clusITS, auto& pattIt2) { + for (auto& clus : clusITS) { + auto pattID = clus.getPatternID(); + unsigned int npix; #ifdef ENABLE_UPGRADES - bool withITS3 = o2::GlobalParams::Instance().withITS3; - if (withITS3) { - o2::its3::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mIT3Dict); - } else { - o2::its::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mITSDict); - } + bool withITS3 = o2::GlobalParams::Instance().withITS3; + auto ib = o2::its3::constants::detID::isDetITS3(clus.getChipID()); + if ((pattID == o2::itsmft::CompCluster::InvalidPatternID) || ((withITS3) ? mIT3Dict->isGroup(pattID, ib) : mITSDict->isGroup(pattID))) { #else - o2::its::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mITSDict); + if (pattID == o2::itsmft::CompCluster::InvalidPatternID || mITSDict->isGroup(pattID)) { #endif - - // ITS clusters sizes - mITSClusterSizes.reserve(clusITS.size()); - auto pattIt2 = patterns.begin(); - for (auto& clus : clusITS) { - auto pattID = clus.getPatternID(); - unsigned int npix; + o2::itsmft::ClusterPattern patt; + patt.acquirePattern(pattIt2); + npix = patt.getNPixels(); + } else { #ifdef ENABLE_UPGRADES - auto ib = o2::its3::constants::detID::isDetITS3(clus.getChipID()); - if ((pattID == o2::itsmft::CompCluster::InvalidPatternID) || ((withITS3) ? mIT3Dict->isGroup(pattID, ib) : mITSDict->isGroup(pattID))) { // braces guarantee evaluation order + if (withITS3) { + npix = mIT3Dict->getNpixels(pattID, ib); + } else { + npix = mITSDict->getNpixels(pattID); + } #else - if (pattID == o2::itsmft::CompCluster::InvalidPatternID || mITSDict->isGroup(pattID)) { + npix = mITSDict->getNpixels(pattID); #endif - o2::itsmft::ClusterPattern patt; - patt.acquirePattern(pattIt2); - npix = patt.getNPixels(); - } else { + } + mITSClusterSizes.push_back(std::clamp(npix, 0u, 255u)); + } + }; + + // ITS clusters + mITSClustersArray.reserve(inp.getNITSClusters()); + mITSClusterSizes.reserve(inp.getNITSClusters()); + if (inp.hasITSClustersPerLayer()) { + std::array layerOffsets{}; + for (int iLayer = 0; iLayer < o2::globaltracking::RecoContainer::NITSLayers; ++iLayer) { + const auto rofs = inp.getITSClustersROFRecords(iLayer); + const auto clusITS = inp.getITSClusters(iLayer); + const auto patterns = inp.getITSClustersPatterns(iLayer); + layerOffsets[iLayer] = mITSClustersArray.size(); + for (const auto& rof : rofs) { + auto& rofFlat = mITSClusterROFRecFlat.emplace_back(rof); + rofFlat.setFirstEntry(rof.getFirstEntry() + layerOffsets[iLayer]); + } + auto pattIt = patterns.begin(); #ifdef ENABLE_UPGRADES - if (withITS3) { - npix = mIT3Dict->getNpixels(pattID, ib); + if (o2::GlobalParams::Instance().withITS3) { + o2::its3::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mIT3Dict); } else { - npix = mITSDict->getNpixels(pattID); + o2::its::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mITSDict); } #else - npix = mITSDict->getNpixels(pattID); + o2::its::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mITSDict); #endif + auto pattIt2 = patterns.begin(); + appendClusterSizes(clusITS, pattIt2); + if (mMCTruthON) { + if (const auto* labels = inp.getITSClustersMCLabels(iLayer)) { + for (int iCluster = 0; iCluster < clusITS.size(); ++iCluster) { + for (const auto& label : labels->getLabels(iCluster)) { + mITSClsLabelsFlat.addElement(layerOffsets[iLayer] + iCluster, label); + } + } + } + } + } + mITSClusterROFRec = mITSClusterROFRecFlat; + mITSTrackClusIdxFlat = inp.makeFlatITSTrackClusterRefs(inp.getITSTracks(), inp.getITSTracksClusterRefs(), layerOffsets); + mITSTrackClusIdx = mITSTrackClusIdxFlat; + if (mMCTruthON) { + mITSClsLabels = &mITSClsLabelsFlat; + } + } else { + mITSClusterROFRec = inp.getITSClustersROFRecords(); + const auto clusITS = inp.getITSClusters(); + const auto patterns = inp.getITSClustersPatterns(); + auto pattIt = patterns.begin(); +#ifdef ENABLE_UPGRADES + if (o2::GlobalParams::Instance().withITS3) { + o2::its3::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mIT3Dict); + } else { + o2::its::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mITSDict); + } +#else + o2::its::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mITSDict); +#endif + auto pattIt2 = patterns.begin(); + appendClusterSizes(clusITS, pattIt2); + mITSTrackClusIdx = inp.getITSTracksClusterRefs(); + if (mMCTruthON) { + mITSClsLabels = inp.mcITSClusters.get(); } - mITSClusterSizes.push_back(std::clamp(npix, 0u, 255u)); } - - if (mMCTruthON) { - mITSClsLabels = inp.mcITSClusters.get(); + if (mITSClusterROFRec.empty() || mITSClustersArray.empty()) { + LOG(info) << "No ITS clusters"; + return false; } // ITS tracks mITSTracksArray = inp.getITSTracks(); - mITSTrackClusIdx = inp.getITSTracksClusterRefs(); mITSTrackROFRec = inp.getITSTracksROFRecords(); if (mMCTruthON) { mITSTrkLabels = inp.getITSTracksMCLabels(); diff --git a/Detectors/GlobalTrackingWorkflow/include/GlobalTrackingWorkflow/StrangenessTrackingSpec.h b/Detectors/GlobalTrackingWorkflow/include/GlobalTrackingWorkflow/StrangenessTrackingSpec.h index bbc2cdc80995e..38af469758325 100644 --- a/Detectors/GlobalTrackingWorkflow/include/GlobalTrackingWorkflow/StrangenessTrackingSpec.h +++ b/Detectors/GlobalTrackingWorkflow/include/GlobalTrackingWorkflow/StrangenessTrackingSpec.h @@ -60,7 +60,7 @@ class StrangenessTrackerSpec : public framework::Task std::unique_ptr mGRP = nullptr; }; -o2::framework::DataProcessorSpec getStrangenessTrackerSpec(o2::dataformats::GlobalTrackID::mask_t src, bool useMC, bool useGeom); +o2::framework::DataProcessorSpec getStrangenessTrackerSpec(o2::dataformats::GlobalTrackID::mask_t src, bool useMC, bool useGeom, bool itsClustersPerLayer); o2::framework::WorkflowSpec getWorkflow(bool upstreamClusters = false, bool upstreamV0s = false); } // namespace strangeness_tracking diff --git a/Detectors/GlobalTrackingWorkflow/include/GlobalTrackingWorkflow/TPCITSMatchingSpec.h b/Detectors/GlobalTrackingWorkflow/include/GlobalTrackingWorkflow/TPCITSMatchingSpec.h index 56240fd2c8f98..fbccff3b0cdbe 100644 --- a/Detectors/GlobalTrackingWorkflow/include/GlobalTrackingWorkflow/TPCITSMatchingSpec.h +++ b/Detectors/GlobalTrackingWorkflow/include/GlobalTrackingWorkflow/TPCITSMatchingSpec.h @@ -23,7 +23,7 @@ namespace o2 namespace globaltracking { /// create a processor spec -framework::DataProcessorSpec getTPCITSMatchingSpec(o2::dataformats::GlobalTrackID::mask_t src, bool useFT0, bool calib, bool skipTPCOnly, bool useGeom, bool useMC, bool requestCTPLumi); +framework::DataProcessorSpec getTPCITSMatchingSpec(o2::dataformats::GlobalTrackID::mask_t src, bool useFT0, bool calib, bool skipTPCOnly, bool useGeom, bool useMC, bool requestCTPLumi, bool itsClustersPerLayer); } // namespace globaltracking } // namespace o2 diff --git a/Detectors/GlobalTrackingWorkflow/src/StrangenessTrackingSpec.cxx b/Detectors/GlobalTrackingWorkflow/src/StrangenessTrackingSpec.cxx index c438f869773a5..f695e8587118b 100644 --- a/Detectors/GlobalTrackingWorkflow/src/StrangenessTrackingSpec.cxx +++ b/Detectors/GlobalTrackingWorkflow/src/StrangenessTrackingSpec.cxx @@ -154,11 +154,11 @@ void StrangenessTrackerSpec::endOfStream(framework::EndOfStreamContext& ec) mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1); } -DataProcessorSpec getStrangenessTrackerSpec(o2::dataformats::GlobalTrackID::mask_t src, bool useMC, bool useGeom) +DataProcessorSpec getStrangenessTrackerSpec(o2::dataformats::GlobalTrackID::mask_t src, bool useMC, bool useGeom, bool itsClustersPerLayer) { // ITS auto dataRequest = std::make_shared(); - dataRequest->requestITSClusters(useMC); + dataRequest->requestITSClusters(useMC, itsClustersPerLayer); dataRequest->requestTracks(src, useMC); dataRequest->requestPrimaryVertices(useMC); dataRequest->requestSecondaryVertices(useMC); diff --git a/Detectors/GlobalTrackingWorkflow/src/TPCITSMatchingSpec.cxx b/Detectors/GlobalTrackingWorkflow/src/TPCITSMatchingSpec.cxx index 7f63b61e02be0..d652ba5148e07 100644 --- a/Detectors/GlobalTrackingWorkflow/src/TPCITSMatchingSpec.cxx +++ b/Detectors/GlobalTrackingWorkflow/src/TPCITSMatchingSpec.cxx @@ -250,7 +250,7 @@ void TPCITSMatchingDPL::updateTimeDependentParams(ProcessingContext& pc) } } -DataProcessorSpec getTPCITSMatchingSpec(GTrackID::mask_t src, bool useFT0, bool calib, bool skipTPCOnly, bool useGeom, bool useMC, bool requestCTPLumi) +DataProcessorSpec getTPCITSMatchingSpec(GTrackID::mask_t src, bool useFT0, bool calib, bool skipTPCOnly, bool useGeom, bool useMC, bool requestCTPLumi, bool itsClustersPerLayer) { std::vector outputs; auto dataRequest = std::make_shared(); @@ -266,10 +266,10 @@ DataProcessorSpec getTPCITSMatchingSpec(GTrackID::mask_t src, bool useFT0, bool if (o2::GlobalParams::Instance().withITS3) { dataRequest->requestIT3Clusters(useMC); } else { - dataRequest->requestITSClusters(useMC); + dataRequest->requestITSClusters(useMC, itsClustersPerLayer); } #else - dataRequest->requestITSClusters(useMC); + dataRequest->requestITSClusters(useMC, itsClustersPerLayer); #endif if (useFT0) { dataRequest->requestFT0RecPoints(false); diff --git a/Detectors/GlobalTrackingWorkflow/src/strangeness-tracking-workflow.cxx b/Detectors/GlobalTrackingWorkflow/src/strangeness-tracking-workflow.cxx index 8c42871ac05bf..4d47cc15e1306 100644 --- a/Detectors/GlobalTrackingWorkflow/src/strangeness-tracking-workflow.cxx +++ b/Detectors/GlobalTrackingWorkflow/src/strangeness-tracking-workflow.cxx @@ -64,13 +64,14 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) auto useRootInput = !configcontext.options().get("disable-root-input"); auto disableRootOut = configcontext.options().get("disable-root-output"); auto useGeom = configcontext.options().get("use-full-geometry"); + auto doStag = o2::itsmft::DPLAlpideParamInitializer::isITSStaggeringEnabled(configcontext); o2::conf::ConfigurableParam::updateFromString(configcontext.options().get("configKeyValues")); o2::conf::ConfigurableParam::writeINI("o2strangeness_tracking_workflow_configuration.ini"); GID::mask_t itsSource = GID::getSourceMask(GID::ITS); // ITS tracks and clusters WorkflowSpec specs; - specs.emplace_back(o2::strangeness_tracking::getStrangenessTrackerSpec(itsSource, useMC, useGeom)); + specs.emplace_back(o2::strangeness_tracking::getStrangenessTrackerSpec(itsSource, useMC, useGeom, doStag)); o2::globaltracking::InputHelper::addInputSpecs(configcontext, specs, itsSource, itsSource, itsSource, useMC, itsSource); o2::globaltracking::InputHelper::addInputSpecsPVertex(configcontext, specs, useMC); // P-vertex is always needed o2::globaltracking::InputHelper::addInputSpecsSVertex(configcontext, specs); // S-vertex is always needed diff --git a/Detectors/GlobalTrackingWorkflow/src/tpcits-match-workflow.cxx b/Detectors/GlobalTrackingWorkflow/src/tpcits-match-workflow.cxx index 79ca13430ccd9..2526321daa5d6 100644 --- a/Detectors/GlobalTrackingWorkflow/src/tpcits-match-workflow.cxx +++ b/Detectors/GlobalTrackingWorkflow/src/tpcits-match-workflow.cxx @@ -78,7 +78,7 @@ WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& configcont GID::mask_t alowedSources = GID::getSourcesMask("ITS,TPC,TPC-TOF"); GID::mask_t src = alowedSources & GID::getSourcesMask(configcontext.options().get("track-sources")); bool needStrictTRDTOF = (src & GID::getSourcesMask("TPC-TRD,TPC-TOF,TPC-TRD-TOF")).any(); - auto doStag = o2::itsmft::DPLAlpideParamInitializer::isITSStaggeringEnabled(configcontext); // RS at the moment is not passed to the matching w-flow + auto doStag = o2::itsmft::DPLAlpideParamInitializer::isITSStaggeringEnabled(configcontext); auto sclOpt = o2::tpc::CorrectionMapsOptions::parseGlobalOptions(configcontext.options()); auto useGeom = configcontext.options().get("use-full-geometry"); auto useFT0 = configcontext.options().get("use-ft0"); @@ -96,7 +96,7 @@ WorkflowSpec defineDataProcessing(o2::framework::ConfigContext const& configcont if (!configcontext.options().get("disable-root-input")) { specs.emplace_back(o2::tpc::getTPCScalerSpec(sclOpt)); } - specs.emplace_back(o2::globaltracking::getTPCITSMatchingSpec(srcL, useFT0, calib, !GID::includesSource(GID::TPC, src), useGeom, useMC, sclOpt.requestCTPLumi)); + specs.emplace_back(o2::globaltracking::getTPCITSMatchingSpec(srcL, useFT0, calib, !GID::includesSource(GID::TPC, src), useGeom, useMC, sclOpt.requestCTPLumi, doStag)); if (!configcontext.options().get("disable-root-output")) { specs.emplace_back(o2::globaltracking::getTrackWriterTPCITSSpec(useMC)); diff --git a/Detectors/TPC/calibration/SpacePoints/include/SpacePoints/TrackInterpolation.h b/Detectors/TPC/calibration/SpacePoints/include/SpacePoints/TrackInterpolation.h index 99e85cf19101a..af2b314b27b75 100644 --- a/Detectors/TPC/calibration/SpacePoints/include/SpacePoints/TrackInterpolation.h +++ b/Detectors/TPC/calibration/SpacePoints/include/SpacePoints/TrackInterpolation.h @@ -468,6 +468,7 @@ class TrackInterpolation // ITS specific input only needed for debugging gsl::span mITSTrackClusIdx; ///< input ITS track cluster indices span + std::vector mITSTrackClusIdxFlat; ///< remapped ITS track cluster indices for local cluster working array std::vector> mITSClustersArray; ///< ITS clusters created in run() method from compact clusters std::vector mITSRefitSeedID; ///< seed ID first using refitted ITS track const o2::itsmft::TopologyDictionary* mITSDict = nullptr; ///< cluster patterns dictionary diff --git a/Detectors/TPC/calibration/SpacePoints/src/TrackInterpolation.cxx b/Detectors/TPC/calibration/SpacePoints/src/TrackInterpolation.cxx index 571bc00a48763..6de2af9ec8cae 100644 --- a/Detectors/TPC/calibration/SpacePoints/src/TrackInterpolation.cxx +++ b/Detectors/TPC/calibration/SpacePoints/src/TrackInterpolation.cxx @@ -33,6 +33,7 @@ #include "DataFormatsTPC/VDriftCorrFact.h" #include "Framework/Logger.h" #include "CCDB/BasicCCDBManager.h" +#include #include "GPUO2InterfaceUtils.h" #include "GPUO2InterfaceConfiguration.h" #include "GPUO2InterfaceRefit.h" @@ -351,13 +352,27 @@ void TrackInterpolation::process() return; } mITSTrackClusIdx = mRecoCont->getITSTracksClusterRefs(); - const auto clusITS = mRecoCont->getITSClusters(); - const auto patterns = mRecoCont->getITSClustersPatterns(); - auto pattIt = patterns.begin(); mITSClustersArray.clear(); - mITSClustersArray.reserve(clusITS.size()); - LOGP(info, "We have {} ITS clusters and the number of patterns is {}", clusITS.size(), patterns.size()); - o2::its::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mITSDict); + mITSClustersArray.reserve(mRecoCont->getNITSClusters()); + if (mRecoCont->hasITSClustersPerLayer()) { + std::array layerOffsets{}; + for (int iLayer = 0; iLayer < o2::globaltracking::RecoContainer::NITSLayers; ++iLayer) { + const auto clusITS = mRecoCont->getITSClusters(iLayer); + const auto patterns = mRecoCont->getITSClustersPatterns(iLayer); + auto pattIt = patterns.begin(); + layerOffsets[iLayer] = mITSClustersArray.size(); + LOGP(info, "We have {} ITS clusters and {} pattern bytes on layer {}", clusITS.size(), patterns.size(), iLayer); + o2::its::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mITSDict); + } + mITSTrackClusIdxFlat = mRecoCont->makeFlatITSTrackClusterRefs(mRecoCont->getITSTracks(), mITSTrackClusIdx, layerOffsets); + mITSTrackClusIdx = mITSTrackClusIdxFlat; + } else { + const auto clusITS = mRecoCont->getITSClusters(); + const auto patterns = mRecoCont->getITSClustersPatterns(); + auto pattIt = patterns.begin(); + LOGP(info, "We have {} ITS clusters and the number of patterns is {}", clusITS.size(), patterns.size()); + o2::its::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mITSDict); + } } // In case we have more input tracks available than are required per TF diff --git a/Detectors/TRD/workflow/include/TRDWorkflow/TRDGlobalTrackingSpec.h b/Detectors/TRD/workflow/include/TRDWorkflow/TRDGlobalTrackingSpec.h index c3a5be6a45649..41d082067c0c2 100644 --- a/Detectors/TRD/workflow/include/TRDWorkflow/TRDGlobalTrackingSpec.h +++ b/Detectors/TRD/workflow/include/TRDWorkflow/TRDGlobalTrackingSpec.h @@ -97,6 +97,8 @@ class TRDGlobalTracking : public o2::framework::Task gsl::span mITSABRefsArray; ///< input ITS-TPC Afterburner ITS tracklets references gsl::span mITSTrackClusIdx; ///< input ITS track cluster indices span gsl::span mITSABTrackClusIdx; ///< input ITSAB track cluster indices span + std::vector mITSTrackClusIdxFlat; ///< remapped ITS track cluster indices for local cluster working array + std::vector mITSABTrackClusIdxFlat; ///< remapped ITSAB track cluster indices for local cluster working array std::vector> mITSClustersArray; ///< ITS clusters created in run() method from compact clusters const o2::itsmft::TopologyDictionary* mITSDict = nullptr; ///< ITS cluster patterns dictionary #ifdef ENABLE_UPGRADES @@ -112,7 +114,7 @@ class TRDGlobalTracking : public o2::framework::Task }; /// create a processor spec -framework::DataProcessorSpec getTRDGlobalTrackingSpec(bool useMC, o2::dataformats::GlobalTrackID::mask_t src, bool trigRecFilterActive, bool strict /* = false*/, bool withPID /* = false*/, PIDPolicy policy /* = PIDPolicy::DEFAULT*/, bool requestCTPLumi); +framework::DataProcessorSpec getTRDGlobalTrackingSpec(bool useMC, o2::dataformats::GlobalTrackID::mask_t src, bool trigRecFilterActive, bool strict /* = false*/, bool withPID /* = false*/, PIDPolicy policy /* = PIDPolicy::DEFAULT*/, bool requestCTPLumi, bool itsClustersPerLayer); } // namespace trd } // namespace o2 diff --git a/Detectors/TRD/workflow/src/TRDGlobalTrackingSpec.cxx b/Detectors/TRD/workflow/src/TRDGlobalTrackingSpec.cxx index e541482dbde2a..e395082736da3 100644 --- a/Detectors/TRD/workflow/src/TRDGlobalTrackingSpec.cxx +++ b/Detectors/TRD/workflow/src/TRDGlobalTrackingSpec.cxx @@ -300,20 +300,55 @@ void TRDGlobalTracking::run(ProcessingContext& pc) mITSTrackClusIdx = inputTracks.getITSTracksClusterRefs(); mITSABRefsArray = inputTracks.getITSABRefs(); mITSABTrackClusIdx = inputTracks.getITSABClusterRefs(); - const auto clusITS = inputTracks.getITSClusters(); - const auto patterns = inputTracks.getITSClustersPatterns(); - auto pattIt = patterns.begin(); mITSClustersArray.clear(); - mITSClustersArray.reserve(clusITS.size()); + mITSClustersArray.reserve(inputTracks.getNITSClusters()); + if (inputTracks.hasITSClustersPerLayer()) { + std::array layerOffsets{}; + for (int iLayer = 0; iLayer < o2::globaltracking::RecoContainer::NITSLayers; ++iLayer) { + const auto clusITS = inputTracks.getITSClusters(iLayer); + const auto patterns = inputTracks.getITSClustersPatterns(iLayer); + auto pattIt = patterns.begin(); + layerOffsets[iLayer] = mITSClustersArray.size(); #ifdef ENABLE_UPGRADES - if (o2::GlobalParams::Instance().withITS3) { - o2::its3::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mIT3Dict); + if (o2::GlobalParams::Instance().withITS3) { + o2::its3::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mIT3Dict); + } else { + o2::its::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mITSDict); + } +#else + o2::its::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mITSDict); +#endif + } + mITSTrackClusIdxFlat.resize(mITSTrackClusIdx.size()); + for (const auto& track : mITSTracksArray) { + for (int iCluster = 0; iCluster < track.getNumberOfClusters(); ++iCluster) { + const auto ref = inputTracks.getITSClusterReference(track, mITSTrackClusIdx, iCluster); + mITSTrackClusIdxFlat[track.getClusterEntry(iCluster)] = layerOffsets[ref.layer] + ref.index; + } + } + mITSTrackClusIdx = mITSTrackClusIdxFlat; + mITSABTrackClusIdxFlat.resize(mITSABTrackClusIdx.size()); + for (const auto& trackletRef : mITSABRefsArray) { + for (int iCluster = 0; iCluster < trackletRef.getNClusters(); ++iCluster) { + const auto ref = inputTracks.getITSClusterReference(trackletRef, mITSABTrackClusIdx, iCluster); + mITSABTrackClusIdxFlat[trackletRef.getFirstEntry() + iCluster] = layerOffsets[ref.layer] + ref.index; + } + } + mITSABTrackClusIdx = mITSABTrackClusIdxFlat; } else { - o2::its::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mITSDict); - } + const auto clusITS = inputTracks.getITSClusters(); + const auto patterns = inputTracks.getITSClustersPatterns(); + auto pattIt = patterns.begin(); +#ifdef ENABLE_UPGRADES + if (o2::GlobalParams::Instance().withITS3) { + o2::its3::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mIT3Dict); + } else { + o2::its::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mITSDict); + } #else - o2::its::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mITSDict); + o2::its::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, mITSDict); #endif + } } LOGF(info, "There are %i tracklets in total from %i trigger records", mChainTracking->mIOPtrs.nTRDTracklets, mChainTracking->mIOPtrs.nTRDTriggerRecords); @@ -933,7 +968,7 @@ void TRDGlobalTracking::endOfStream(EndOfStreamContext& ec) mTimer.CpuTime(), mTimer.RealTime(), mTimer.Counter() - 1); } -DataProcessorSpec getTRDGlobalTrackingSpec(bool useMC, GTrackID::mask_t src, bool trigRecFilterActive, bool strict, bool withPID, PIDPolicy policy, bool requestCTPLumi) +DataProcessorSpec getTRDGlobalTrackingSpec(bool useMC, GTrackID::mask_t src, bool trigRecFilterActive, bool strict, bool withPID, PIDPolicy policy, bool requestCTPLumi, bool itsClustersPerLayer) { std::vector outputs; uint32_t ss = o2::globaltracking::getSubSpec(strict ? o2::globaltracking::MatchingType::Strict : o2::globaltracking::MatchingType::Standard); @@ -951,10 +986,10 @@ DataProcessorSpec getTRDGlobalTrackingSpec(bool useMC, GTrackID::mask_t src, boo if (o2::GlobalParams::Instance().withITS3) { dataRequest->requestIT3Clusters(false); // only needed for refit, don't care about labels } else { - dataRequest->requestITSClusters(false); // only needed for refit, don't care about labels + dataRequest->requestITSClusters(false, itsClustersPerLayer); // only needed for refit, don't care about labels } #else - dataRequest->requestITSClusters(false); // only needed for refit, don't care about labels + dataRequest->requestITSClusters(false, itsClustersPerLayer); // only needed for refit, don't care about labels #endif trkSrc |= GTrackID::getSourcesMask("ITS"); } diff --git a/Detectors/TRD/workflow/src/trd-tracking-workflow.cxx b/Detectors/TRD/workflow/src/trd-tracking-workflow.cxx index bc0da73c09dd5..e5db74716cbd3 100644 --- a/Detectors/TRD/workflow/src/trd-tracking-workflow.cxx +++ b/Detectors/TRD/workflow/src/trd-tracking-workflow.cxx @@ -89,6 +89,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) auto pulseHeight = configcontext.options().get("enable-ph"); auto digitsSpec = configcontext.options().get("trd-digits-spec"); auto sclOpt = o2::tpc::CorrectionMapsOptions::parseGlobalOptions(configcontext.options()); + auto doStag = o2::itsmft::DPLAlpideParamInitializer::isITSStaggeringEnabled(configcontext); bool rootInput = !configcontext.options().get("disable-root-input"); GTrackID::mask_t srcTRD = allowedSources & GTrackID::getSourcesMask(configcontext.options().get("track-sources")); if (strict && (srcTRD & ~GTrackID::getSourcesMask("TPC")).any()) { @@ -118,7 +119,7 @@ WorkflowSpec defineDataProcessing(ConfigContext const& configcontext) if (!configcontext.options().get("disable-root-input")) { specs.emplace_back(o2::tpc::getTPCScalerSpec(sclOpt)); } - specs.emplace_back(o2::trd::getTRDGlobalTrackingSpec(useMC, srcTRD, trigRecFilterActive, strict, pid, policy, sclOpt.requestCTPLumi)); + specs.emplace_back(o2::trd::getTRDGlobalTrackingSpec(useMC, srcTRD, trigRecFilterActive, strict, pid, policy, sclOpt.requestCTPLumi, doStag)); if (vdexb || gain) { specs.emplace_back(o2::trd::getTRDTrackBasedCalibSpec(srcTRD, vdexb, gain)); } diff --git a/Detectors/Vertexing/StrangenessTracking/include/StrangenessTracking/StrangenessTracker.h b/Detectors/Vertexing/StrangenessTracking/include/StrangenessTracking/StrangenessTracker.h index b30be4dd081e3..61732652dc0df 100644 --- a/Detectors/Vertexing/StrangenessTracking/include/StrangenessTracking/StrangenessTracker.h +++ b/Detectors/Vertexing/StrangenessTracking/include/StrangenessTracking/StrangenessTracker.h @@ -128,6 +128,7 @@ class StrangenessTracker mITSvtxBrackets.clear(); mInputITSclusters.clear(); mInputClusterSizes.clear(); + mInputITSidxsFlat.clear(); } void setupThreads(int nThreads = 1) @@ -328,6 +329,7 @@ class StrangenessTracker std::vector mInputClusterSizes; // input cluster sizes std::vector mInputITSclusters; // input ITS clusters gsl::span mInputITSidxs; // input ITS track-cluster indexes + std::vector mInputITSidxsFlat; // remapped indexes for local cluster working array gsl::span mInputV0tracks; // input V0 of decay daughters gsl::span mInputV0Indices; // input V0 indices of decay daughters gsl::span mInputCascadeTracks; // input cascade of decay daughters diff --git a/Detectors/Vertexing/StrangenessTracking/src/StrangenessTracker.cxx b/Detectors/Vertexing/StrangenessTracking/src/StrangenessTracker.cxx index acbaa9d6a08fd..21e8780d8313c 100644 --- a/Detectors/Vertexing/StrangenessTracking/src/StrangenessTracker.cxx +++ b/Detectors/Vertexing/StrangenessTracking/src/StrangenessTracker.cxx @@ -11,6 +11,7 @@ /// \file StrangenessTracker.cxx /// \brief +#include #include #include "StrangenessTracking/StrangenessTracker.h" #include "ITStracking/IOUtils.h" @@ -42,24 +43,55 @@ bool StrangenessTracker::loadData(const o2::globaltracking::RecoContainer& recoD mInputITStracks = recoData.getITSTracks(); mInputITSidxs = recoData.getITSTracksClusterRefs(); - auto compClus = recoData.getITSClusters(); - auto clusPatt = recoData.getITSClustersPatterns(); - auto pattIt = clusPatt.begin(); - auto pattIt2 = clusPatt.begin(); - mInputITSclusters.reserve(compClus.size()); - mInputClusterSizes.resize(compClus.size()); + mInputITSclusters.reserve(recoData.getNITSClusters()); + mInputClusterSizes.reserve(recoData.getNITSClusters()); + if (recoData.hasITSClustersPerLayer()) { + std::array layerOffsets{}; + for (int iLayer = 0; iLayer < o2::globaltracking::RecoContainer::NITSLayers; ++iLayer) { + const auto compClus = recoData.getITSClusters(iLayer); + const auto clusPatt = recoData.getITSClustersPatterns(iLayer); + auto pattIt = clusPatt.begin(); + auto pattIt2 = clusPatt.begin(); + layerOffsets[iLayer] = mInputITSclusters.size(); #ifdef ENABLE_UPGRADES - if (o2::GlobalParams::Instance().withITS3) { - o2::its3::ioutils::convertCompactClusters(compClus, pattIt, mInputITSclusters, mIT3Dict); - getClusterSizesIT3(mInputClusterSizes, compClus, pattIt2, mIT3Dict); + if (o2::GlobalParams::Instance().withITS3) { + o2::its3::ioutils::convertCompactClusters(compClus, pattIt, mInputITSclusters, mIT3Dict); + getClusterSizesIT3(mInputClusterSizes, compClus, pattIt2, mIT3Dict); + } else { + o2::its::ioutils::convertCompactClusters(compClus, pattIt, mInputITSclusters, mITSDict); + getClusterSizesITS(mInputClusterSizes, compClus, pattIt2, mITSDict); + } +#else + o2::its::ioutils::convertCompactClusters(compClus, pattIt, mInputITSclusters, mITSDict); + getClusterSizesITS(mInputClusterSizes, compClus, pattIt2, mITSDict); +#endif + } + mInputITSidxsFlat.resize(mInputITSidxs.size()); + for (const auto& track : mInputITStracks) { + for (int iCluster = 0; iCluster < track.getNumberOfClusters(); ++iCluster) { + const auto ref = recoData.getITSClusterReference(track, mInputITSidxs, iCluster); + mInputITSidxsFlat[track.getClusterEntry(iCluster)] = layerOffsets[ref.layer] + ref.index; + } + } + mInputITSidxs = mInputITSidxsFlat; } else { + auto compClus = recoData.getITSClusters(); + auto clusPatt = recoData.getITSClustersPatterns(); + auto pattIt = clusPatt.begin(); + auto pattIt2 = clusPatt.begin(); +#ifdef ENABLE_UPGRADES + if (o2::GlobalParams::Instance().withITS3) { + o2::its3::ioutils::convertCompactClusters(compClus, pattIt, mInputITSclusters, mIT3Dict); + getClusterSizesIT3(mInputClusterSizes, compClus, pattIt2, mIT3Dict); + } else { + o2::its::ioutils::convertCompactClusters(compClus, pattIt, mInputITSclusters, mITSDict); + getClusterSizesITS(mInputClusterSizes, compClus, pattIt2, mITSDict); + } +#else o2::its::ioutils::convertCompactClusters(compClus, pattIt, mInputITSclusters, mITSDict); getClusterSizesITS(mInputClusterSizes, compClus, pattIt2, mITSDict); - } -#else - o2::its::ioutils::convertCompactClusters(compClus, pattIt, mInputITSclusters, mITSDict); - getClusterSizesITS(mInputClusterSizes, compClus, pattIt2, mITSDict); #endif + } mITSvtxBrackets.resize(mInputITStracks.size()); for (int i = 0; i < mInputITStracks.size(); i++) { diff --git a/EventVisualisation/Workflow/include/EveWorkflow/EveWorkflowHelper.h b/EventVisualisation/Workflow/include/EveWorkflow/EveWorkflowHelper.h index 6b3ec653c5350..331fba485faad 100644 --- a/EventVisualisation/Workflow/include/EveWorkflow/EveWorkflowHelper.h +++ b/EventVisualisation/Workflow/include/EveWorkflow/EveWorkflowHelper.h @@ -202,6 +202,8 @@ class EveWorkflowHelper std::unordered_map mGIDTrackTime; std::vector mItsROFBrackets; std::vector> mITSClustersArray; + std::vector mITSTrackClusIdxFlat; + std::vector mITSABTrackClusIdxFlat; std::vector> mMFTClustersArray; o2::mft::GeometryTGeo* mMFTGeom; o2::its::GeometryTGeo* mITSGeom; diff --git a/EventVisualisation/Workflow/src/EveWorkflowHelper.cxx b/EventVisualisation/Workflow/src/EveWorkflowHelper.cxx index b4f7655648001..b9e130e92aaac 100644 --- a/EventVisualisation/Workflow/src/EveWorkflowHelper.cxx +++ b/EventVisualisation/Workflow/src/EveWorkflowHelper.cxx @@ -33,6 +33,7 @@ #include "MCHTracking/TrackExtrap.h" #include "DataFormatsITSMFT/TrkClusRef.h" #include "DataFormatsITSMFT/DPLAlpideParam.h" +#include #include "CommonDataFormat/IRFrame.h" #include "MFTBase/GeometryTGeo.h" #include "ITSBase/GeometryTGeo.h" @@ -618,12 +619,27 @@ void EveWorkflowHelper::addTrackToEvent(const o2::track::TrackPar& tr, GID gid, void EveWorkflowHelper::prepareITSClusters(const o2::itsmft::TopologyDictionary* dict) { - const auto& ITSClusterROFRec = mRecoCont->getITSClustersROFRecords(); - const auto& clusITS = mRecoCont->getITSClusters(); - if (clusITS.size() && ITSClusterROFRec.size()) { + mITSClustersArray.clear(); + mITSClustersArray.reserve(mRecoCont->getNITSClusters()); + if (mRecoCont->hasITSClustersPerLayer()) { + std::array layerOffsets{}; + for (int iLayer = 0; iLayer < o2::globaltracking::RecoContainer::NITSLayers; ++iLayer) { + const auto& clusITS = mRecoCont->getITSClusters(iLayer); + const auto& patterns = mRecoCont->getITSClustersPatterns(iLayer); + layerOffsets[iLayer] = mITSClustersArray.size(); + auto pattIt = patterns.begin(); + o2::its::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, dict); + } + mITSTrackClusIdxFlat = mRecoCont->makeFlatITSTrackClusterRefs(mRecoCont->getITSTracks(), mRecoCont->getITSTracksClusterRefs(), layerOffsets); + mITSABTrackClusIdxFlat = mRecoCont->makeFlatITSABClusterRefs(mRecoCont->getITSABRefs(), mRecoCont->getITSABClusterRefs(), layerOffsets); + } else { + const auto& ITSClusterROFRec = mRecoCont->getITSClustersROFRecords(); + const auto& clusITS = mRecoCont->getITSClusters(); + if (!clusITS.size() || !ITSClusterROFRec.size()) { + return; + } const auto& patterns = mRecoCont->getITSClustersPatterns(); auto pattIt = patterns.begin(); - mITSClustersArray.reserve(clusITS.size()); o2::its::ioutils::convertCompactClusters(clusITS, pattIt, mITSClustersArray, dict); } } @@ -987,7 +1003,8 @@ void EveWorkflowHelper::drawITSClusters(GID gid) // float trackTime if (gid.getSource() == GID::ITS) { // this is for for full standalone tracks const auto& trc = mRecoCont->getITSTrack(gid); - auto refs = mRecoCont->getITSTracksClusterRefs(); + auto refsOrig = mRecoCont->getITSTracksClusterRefs(); + auto refs = mRecoCont->hasITSClustersPerLayer() ? gsl::span{mITSTrackClusIdxFlat} : refsOrig; int ncl = trc.getNumberOfClusters(); int offset = trc.getFirstClusterEntry(); for (int icl = 0; icl < ncl; icl++) { @@ -999,7 +1016,8 @@ void EveWorkflowHelper::drawITSClusters(GID gid) // float trackTime } else if (gid.getSource() == GID::ITSAB) { // this is for ITS tracklets from ITS-TPC afterburner const auto& trc = mRecoCont->getITSABRef(gid); - const auto& refs = mRecoCont->getITSABClusterRefs(); + auto refsOrig = mRecoCont->getITSABClusterRefs(); + auto refs = mRecoCont->hasITSClustersPerLayer() ? gsl::span{mITSABTrackClusIdxFlat} : refsOrig; int ncl = trc.getNClusters(); int offset = trc.getFirstEntry(); for (int icl = 0; icl < ncl; icl++) { diff --git a/GPU/Workflow/helper/src/GPUWorkflowHelper.cxx b/GPU/Workflow/helper/src/GPUWorkflowHelper.cxx index a9c9b78e9847e..816d841c64274 100644 --- a/GPU/Workflow/helper/src/GPUWorkflowHelper.cxx +++ b/GPU/Workflow/helper/src/GPUWorkflowHelper.cxx @@ -15,6 +15,7 @@ #include "ITStracking/IOUtils.h" #include "DataFormatsTPC/WorkflowHelper.h" #include "DataFormatsGlobalTracking/RecoContainerCreateTracksVariadic.h" +#include #include using namespace o2::globaltracking; @@ -22,6 +23,10 @@ using namespace o2::gpu; struct GPUWorkflowHelper::tmpDataContainer { std::vector> ITSClustersArray; + std::vector ITSCompClustersArray; + std::vector ITSClusterROFRec; + std::vector ITSTrackClusIdx; + std::array ITSLayerOffsets{}; std::vector tpcLinkITS, tpcLinkTRD, tpcLinkTOF; std::vector globalTracks; std::vector globalTrackTimes; @@ -32,21 +37,46 @@ std::shared_ptr GPUWorkflowHelper::fi auto retVal = std::make_shared(); if (maskCl[GID::ITS] && ioPtr.nItsClusters == 0) { - const auto& ITSClusterROFRec = recoCont.getITSClustersROFRecords(); - const auto& clusITS = recoCont.getITSClusters(); + gsl::span ITSClusterROFRec; + gsl::span clusITS; + if (recoCont.hasITSClustersPerLayer()) { + retVal->ITSCompClustersArray.reserve(recoCont.getNITSClusters()); + for (int iLayer = 0; iLayer < o2::globaltracking::RecoContainer::NITSLayers; ++iLayer) { + const auto layerClusters = recoCont.getITSClusters(iLayer); + retVal->ITSLayerOffsets[iLayer] = retVal->ITSCompClustersArray.size(); + retVal->ITSCompClustersArray.insert(retVal->ITSCompClustersArray.end(), layerClusters.begin(), layerClusters.end()); + for (const auto& rof : recoCont.getITSClustersROFRecords(iLayer)) { + auto& rofFlat = retVal->ITSClusterROFRec.emplace_back(rof); + rofFlat.setFirstEntry(rof.getFirstEntry() + retVal->ITSLayerOffsets[iLayer]); + } + } + ITSClusterROFRec = retVal->ITSClusterROFRec; + clusITS = retVal->ITSCompClustersArray; + } else { + ITSClusterROFRec = recoCont.getITSClustersROFRecords(); + clusITS = recoCont.getITSClusters(); + } if (clusITS.size() && ITSClusterROFRec.size()) { if (calib && calib->itsPatternDict) { - const auto& patterns = recoCont.getITSClustersPatterns(); - auto pattIt = patterns.begin(); retVal->ITSClustersArray.reserve(clusITS.size()); - o2::its::ioutils::convertCompactClusters(clusITS, pattIt, retVal->ITSClustersArray, calib->itsPatternDict); + if (recoCont.hasITSClustersPerLayer()) { + for (int iLayer = 0; iLayer < o2::globaltracking::RecoContainer::NITSLayers; ++iLayer) { + const auto patterns = recoCont.getITSClustersPatterns(iLayer); + auto pattIt = patterns.begin(); + o2::its::ioutils::convertCompactClusters(recoCont.getITSClusters(iLayer), pattIt, retVal->ITSClustersArray, calib->itsPatternDict); + } + } else { + const auto& patterns = recoCont.getITSClustersPatterns(); + auto pattIt = patterns.begin(); + o2::its::ioutils::convertCompactClusters(clusITS, pattIt, retVal->ITSClustersArray, calib->itsPatternDict); + } ioPtr.itsClusters = retVal->ITSClustersArray.data(); } ioPtr.nItsClusters = clusITS.size(); ioPtr.itsCompClusters = clusITS.data(); ioPtr.nItsClusterROF = ITSClusterROFRec.size(); ioPtr.itsClusterROF = ITSClusterROFRec.data(); - if (useMC) { + if (useMC && !recoCont.hasITSClustersPerLayer()) { const auto& ITSClsLabels = recoCont.mcITSClusters.get(); ioPtr.itsClusterMC = ITSClsLabels; } @@ -57,7 +87,11 @@ std::shared_ptr GPUWorkflowHelper::fi const auto& ITSTracksArray = recoCont.getITSTracks(); const auto& ITSTrackROFRec = recoCont.getITSTracksROFRecords(); if (ITSTracksArray.size() && ITSTrackROFRec.size()) { - const auto& ITSTrackClusIdx = recoCont.getITSTracksClusterRefs(); + auto ITSTrackClusIdx = recoCont.getITSTracksClusterRefs(); + if (recoCont.hasITSClustersPerLayer()) { + retVal->ITSTrackClusIdx = recoCont.makeFlatITSTrackClusterRefs(ITSTracksArray, ITSTrackClusIdx, retVal->ITSLayerOffsets); + ITSTrackClusIdx = retVal->ITSTrackClusIdx; + } ioPtr.nItsTracks = ITSTracksArray.size(); ioPtr.itsTracks = ITSTracksArray.data(); ioPtr.itsTrackClusIdx = ITSTrackClusIdx.data();