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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Comment on lines +29 to +34

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

convert to fwd declarations

#include "DataFormatsCTP/LumiInfo.h"
#include <gsl/span>
#include <array>
#include <memory>
#include <stdexcept>
#include <vector>

// 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)
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -323,6 +332,12 @@ struct RecoContainer {
using GlobalIDSet = std::array<GTrackID, GTrackID::NSources>;

static constexpr float PS2MUS = 1e-6;
static constexpr int NITSLayers = o2::itsmft::DPLAlpideParam<o2::detectors::DetID::ITS>::getNLayers();

struct ITSClusterReference {
int layer = -1;
int index = -1;
};
Comment on lines +337 to +340

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed? In the staggered mode the cluster index is already ((0x1<<28) + index_in_layer), the same can be extended to refs of the ITS-TPC AB.


o2::InteractionRecord startIR; // TF start IR

Expand All @@ -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<gsl::span<const o2::itsmft::ROFRecord>, NITSLayers> itsClustersROFRecordsPerLayer;
std::array<gsl::span<const o2::itsmft::CompClusterExt>, NITSLayers> itsClustersPerLayer;
std::array<gsl::span<const unsigned char>, NITSLayers> itsClustersPatternsPerLayer;
Comment on lines +349 to +351

@shahor02 shahor02 Sep 27, 2026 •

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To avoid dependencies on headers, I would use here (implementing the same also for the MFT)

o2::dataformats::AbstractRefAccessor<3, MaxITSlayers> itsClusters; // [ROF/Clus/Patt][7 slots also for non-staggered]
o2::dataformats::AbstractRefAccessor<3, MaxMFTlayers> itsClusters; // [ROF/Clus/Patt][10 slots also for non-staggered]

and for the non-staggered case would just use the 1st slot (nominally layer 0)
Can also provide getters for span of spans (span per layer)

std::array<std::unique_ptr<const o2::dataformats::MCTruthContainer<o2::MCCompLabel>>, NITSLayers> mcITSClustersPerLayer;
bool itsClustersPerLayerLoaded = false;

std::unique_ptr<const o2::dataformats::MCTruthContainer<o2::MCCompLabel>> mcITSClusters;
std::unique_ptr<const o2::dataformats::MCTruthContainer<o2::MCCompLabel>> mcTOFClusters;
Expand Down Expand Up @@ -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);
Expand Down Expand Up @@ -498,10 +518,116 @@ struct RecoContainer {
auto getITSABMCLabels() const { return getSpan<o2::MCCompLabel>(GTrackID::ITSAB, MCLABELS); }

// ITS clusters
auto getITSClustersROFRecords() const { return getSpan<o2::itsmft::ROFRecord>(GTrackID::ITS, CLUSREFS); }
auto getITSClusters() const { return getSpan<o2::itsmft::CompClusterExt>(GTrackID::ITS, CLUSTERS); }
auto getITSClustersPatterns() const { return getSpan<unsigned char>(GTrackID::ITS, PATTERNS); }
auto getITSClustersMCLabels() const { return mcITSClusters.get(); }
auto getITSClustersROFRecords() const
{
checkFlatITSClusterAccess();
return getSpan<o2::itsmft::ROFRecord>(GTrackID::ITS, CLUSREFS);
}
auto getITSClusters() const
{
checkFlatITSClusterAccess();
return getSpan<o2::itsmft::CompClusterExt>(GTrackID::ITS, CLUSTERS);
}
Comment on lines +526 to +530

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

would remove these methods w/o layer arg., which would simply default to 0.

auto getITSClustersPatterns() const
{
checkFlatITSClusterAccess();
return getSpan<unsigned char>(GTrackID::ITS, PATTERNS);
}
bool hasITSClustersPerLayer() const { return itsClustersPerLayerLoaded; }
auto getITSClustersROFRecords(int layer) const { return itsClustersROFRecordsPerLayer[layer]; }

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i.e. simply

auto getITSClustersROFRecords(int layer=0) 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<const int> 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<const int> 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 <typename TrackSpan>
std::vector<int> makeFlatITSTrackClusterRefs(TrackSpan tracks, gsl::span<const int> clusterRefs, const std::array<int, NITSLayers>& layerOffsets) const
{
if (!hasITSClustersPerLayer()) {
return {};
}
std::vector<int> 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 <typename TrackletRefSpan>
std::vector<int> makeFlatITSABClusterRefs(TrackletRefSpan trackletRefs, gsl::span<const int> clusterRefs, const std::array<int, NITSLayers>& layerOffsets) const
{
if (!hasITSClustersPerLayer()) {
return {};
}
std::vector<int> flatRefs(clusterRefs.size());
Comment on lines +558 to +597

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See above. the cluster ref already provides the layer and index within the layer, no need in additional flat structure.

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<o2::mft::TrackMFT>(gid); }
Expand Down
80 changes: 61 additions & 19 deletions DataFormats/Detectors/GlobalTracking/src/RecoContainer.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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<o2::detectors::DetID::ITS>::getNLayers() : 1;
for (int iLayer = 0; iLayer < nLayers; ++iLayer) {
const auto suffix = perLayer ? std::to_string(iLayer) : std::string{};
const auto subspec = static_cast<o2::header::DataHeader::SubSpecificationType>(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<o2::header::DataHeader::SubSpecificationType>(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<o2::detectors::DetID::ITS>::getNLayers();
for (int iLayer = 0; iLayer < nLayers; ++iLayer) {
const auto suffix = std::to_string(iLayer);
const auto subspec = static_cast<o2::header::DataHeader::SubSpecificationType>(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<o2::header::DataHeader::SubSpecificationType>(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

Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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<o2::framework::TimingInfo>().globalRunNumberChanged) { // this params need to be queried only once
pc.inputs().get<o2::itsmft::TopologyDictionary*>("cldictITS"); // just to trigger the finaliseCCDB
pc.inputs().get<o2::itsmft::DPLAlpideParam<o2::detectors::DetID::ITS>*>("alpparITS"); // note: configurable param does not need finaliseCCDB
}
commonPool[GTrackID::ITS].registerContainer(pc.inputs().get<gsl::span<o2::itsmft::ROFRecord>>("clusITSROF"), CLUSREFS);
commonPool[GTrackID::ITS].registerContainer(pc.inputs().get<gsl::span<o2::itsmft::CompClusterExt>>("clusITS"), CLUSTERS);
commonPool[GTrackID::ITS].registerContainer(pc.inputs().get<gsl::span<unsigned char>>("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<gsl::span<o2::itsmft::ROFRecord>>("clusITSROF" + suffix);
itsClustersPerLayer[iLayer] = pc.inputs().get<gsl::span<o2::itsmft::CompClusterExt>>("clusITS" + suffix);
itsClustersPatternsPerLayer[iLayer] = pc.inputs().get<gsl::span<unsigned char>>("clusITSPatt" + suffix);
}
} else {
commonPool[GTrackID::ITS].registerContainer(pc.inputs().get<gsl::span<o2::itsmft::ROFRecord>>("clusITSROF"), CLUSREFS);
commonPool[GTrackID::ITS].registerContainer(pc.inputs().get<gsl::span<o2::itsmft::CompClusterExt>>("clusITS"), CLUSTERS);
commonPool[GTrackID::ITS].registerContainer(pc.inputs().get<gsl::span<unsigned char>>("clusITSPatt"), PATTERNS);
}
if (mc && perLayer) {
for (int iLayer = 0; iLayer < NITSLayers; ++iLayer) {
mcITSClustersPerLayer[iLayer] = pc.inputs().get<const dataformats::MCTruthContainer<MCCompLabel>*>("clusITSMC" + std::to_string(iLayer));
}
} else if (mc) {
mcITSClusters = pc.inputs().get<const dataformats::MCTruthContainer<MCCompLabel>*>("clusITSMC");
}
}
Expand All @@ -1089,11 +1125,17 @@ void RecoContainer::addIT3Clusters(ProcessingContext& pc, bool mc)
pc.inputs().get<o2::itsmft::DPLAlpideParam<o2::detectors::DetID::ITS>*>("alpparITS"); // note: configurable param does not need finaliseCCDB
pc.inputs().get<o2::its3::TopologyDictionary*>("cldictIT3"); // just to trigger the finaliseCCDB
}
commonPool[GTrackID::ITS].registerContainer(pc.inputs().get<gsl::span<o2::itsmft::ROFRecord>>("clusITSROF"), CLUSREFS);
commonPool[GTrackID::ITS].registerContainer(pc.inputs().get<gsl::span<o2::itsmft::CompClusterExt>>("clusITS"), CLUSTERS);
commonPool[GTrackID::ITS].registerContainer(pc.inputs().get<gsl::span<unsigned char>>("clusITSPatt"), PATTERNS);
itsClustersPerLayerLoaded = true;
for (int iLayer = 0; iLayer < NITSLayers; ++iLayer) {
const auto suffix = std::to_string(iLayer);
itsClustersROFRecordsPerLayer[iLayer] = pc.inputs().get<gsl::span<o2::itsmft::ROFRecord>>("clusITSROF" + suffix);
itsClustersPerLayer[iLayer] = pc.inputs().get<gsl::span<o2::itsmft::CompClusterExt>>("clusITS" + suffix);
itsClustersPatternsPerLayer[iLayer] = pc.inputs().get<gsl::span<unsigned char>>("clusITSPatt" + suffix);
}
if (mc) {
mcITSClusters = pc.inputs().get<const dataformats::MCTruthContainer<MCCompLabel>*>("clusITSMC");
for (int iLayer = 0; iLayer < NITSLayers; ++iLayer) {
mcITSClustersPerLayer[iLayer] = pc.inputs().get<const dataformats::MCTruthContainer<MCCompLabel>*>("clusITSMC" + std::to_string(iLayer));
}
}
}
#endif
Expand Down
2 changes: 2 additions & 0 deletions Detectors/Align/include/Align/AlignableDetectorITS.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ class AlignableDetectorITS : public AlignableDetector
protected:
//
std::vector<ClusterD> mITSClustersArray;

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code in the Align can be discarded. I am developing new MP code, at the moment in a separate git repo to minimise switches. Will take care of extending to staggered version later.

std::vector<int> mITSTrackClusIdxFlat;
std::vector<int> mITSABTrackClusIdxFlat;
std::vector<int> mOverlapCandidateID; // pool of indices for potentially overlapping clusters
std::vector<int> mOverlapClusRef; // 1st entry in mOverlapCandidateID for the overlapping cluster indices of each cluster
std::vector<o2::itsmft::ChipMappingITS::Overlaps> mOverlaps;
Expand Down
Loading
Loading