diff --git a/Detectors/Upgrades/ALICE3/IOTOF/DataFormatsIOTOF/include/DataFormatsIOTOF/Cluster.h b/Detectors/Upgrades/ALICE3/IOTOF/DataFormatsIOTOF/include/DataFormatsIOTOF/Cluster.h index 21028d21c9cde..b949aa485e3ae 100644 --- a/Detectors/Upgrades/ALICE3/IOTOF/DataFormatsIOTOF/include/DataFormatsIOTOF/Cluster.h +++ b/Detectors/Upgrades/ALICE3/IOTOF/DataFormatsIOTOF/include/DataFormatsIOTOF/Cluster.h @@ -29,27 +29,27 @@ namespace iotof /// Compact encoding for ALICE3 IOTOF cluster parameters inside a single 64-bit word. struct ClusterInfo { // Bit widths (Total: 52 bits out of 64) - static constexpr int NBitsRow = 9; - static constexpr int NBitsCol = 8; - static constexpr int NBitsRowSpan = 4; - static constexpr int NBitsColSpan = 4; - static constexpr int NBitsPattern = 16; + static constexpr int NBitsRow = 9; + static constexpr int NBitsCol = 8; + static constexpr int NBitsRowSpan = 4; + static constexpr int NBitsColSpan = 4; + static constexpr int NBitsPattern = 16; static constexpr int NBitsTopology = 11; // Bit offsets (ordered logically from LSB to MSB) - static constexpr int ShiftRow = 0; - static constexpr int ShiftCol = ShiftRow + NBitsRow; // 9 - static constexpr int ShiftRowSpan = ShiftCol + NBitsCol; // 17 - static constexpr int ShiftColSpan = ShiftRowSpan + NBitsRowSpan; // 21 - static constexpr int ShiftPattern = ShiftColSpan + NBitsColSpan; // 25 - static constexpr int ShiftTopology = ShiftPattern + NBitsPattern; // 41 + static constexpr int ShiftRow = 0; + static constexpr int ShiftCol = ShiftRow + NBitsRow; // 9 + static constexpr int ShiftRowSpan = ShiftCol + NBitsCol; // 17 + static constexpr int ShiftColSpan = ShiftRowSpan + NBitsRowSpan; // 21 + static constexpr int ShiftPattern = ShiftColSpan + NBitsColSpan; // 25 + static constexpr int ShiftTopology = ShiftPattern + NBitsPattern; // 41 // Bit masks - static constexpr uint64_t MaskRow = (1ULL << NBitsRow) - 1; - static constexpr uint64_t MaskCol = (1ULL << NBitsCol) - 1; - static constexpr uint64_t MaskRowSpan = (1ULL << NBitsRowSpan) - 1; - static constexpr uint64_t MaskColSpan = (1ULL << NBitsColSpan) - 1; - static constexpr uint64_t MaskPattern = (1ULL << NBitsPattern) - 1; + static constexpr uint64_t MaskRow = (1ULL << NBitsRow) - 1; + static constexpr uint64_t MaskCol = (1ULL << NBitsCol) - 1; + static constexpr uint64_t MaskRowSpan = (1ULL << NBitsRowSpan) - 1; + static constexpr uint64_t MaskColSpan = (1ULL << NBitsColSpan) - 1; + static constexpr uint64_t MaskPattern = (1ULL << NBitsPattern) - 1; static constexpr uint64_t MaskTopology = (1ULL << NBitsTopology) - 1; uint64_t data{0}; @@ -59,41 +59,48 @@ struct ClusterInfo { constexpr ClusterInfo(uint64_t d) : data(d) {} // Static packer - static constexpr uint64_t pack(uint32_t row, uint32_t col, uint32_t rowSpan, - uint32_t colSpan, uint32_t pattern, uint32_t topology) { - return ((static_cast(row) & MaskRow) << ShiftRow) | - ((static_cast(col) & MaskCol) << ShiftCol) | - ((static_cast(rowSpan) & MaskRowSpan) << ShiftRowSpan) | - ((static_cast(colSpan) & MaskColSpan) << ShiftColSpan) | - ((static_cast(pattern) & MaskPattern) << ShiftPattern) | + static constexpr uint64_t pack(uint32_t row, uint32_t col, uint32_t rowSpan, + uint32_t colSpan, uint32_t pattern, uint32_t topology) + { + return ((static_cast(row) & MaskRow) << ShiftRow) | + ((static_cast(col) & MaskCol) << ShiftCol) | + ((static_cast(rowSpan) & MaskRowSpan) << ShiftRowSpan) | + ((static_cast(colSpan) & MaskColSpan) << ShiftColSpan) | + ((static_cast(pattern) & MaskPattern) << ShiftPattern) | ((static_cast(topology) & MaskTopology) << ShiftTopology); } // Getters - constexpr uint32_t getRow() const { return (data >> ShiftRow) & MaskRow; } - constexpr uint32_t getCol() const { return (data >> ShiftCol) & MaskCol; } - constexpr uint32_t getRowSpan() const { return (data >> ShiftRowSpan) & MaskRowSpan; } - constexpr uint32_t getColSpan() const { return (data >> ShiftColSpan) & MaskColSpan; } - constexpr uint32_t getPattern() const { return (data >> ShiftPattern) & MaskPattern; } + constexpr uint32_t getRow() const { return (data >> ShiftRow) & MaskRow; } + constexpr uint32_t getCol() const { return (data >> ShiftCol) & MaskCol; } + constexpr uint32_t getRowSpan() const { return (data >> ShiftRowSpan) & MaskRowSpan; } + constexpr uint32_t getColSpan() const { return (data >> ShiftColSpan) & MaskColSpan; } + constexpr uint32_t getPattern() const { return (data >> ShiftPattern) & MaskPattern; } constexpr uint32_t getTopology() const { return (data >> ShiftTopology) & MaskTopology; } // Setters - constexpr void setRow(uint32_t r) { + constexpr void setRow(uint32_t r) + { data = (data & ~(MaskRow << ShiftRow)) | ((static_cast(r) & MaskRow) << ShiftRow); } - constexpr void setCol(uint32_t c) { + constexpr void setCol(uint32_t c) + { data = (data & ~(MaskCol << ShiftCol)) | ((static_cast(c) & MaskCol) << ShiftCol); } - constexpr void setRowSpan(uint32_t rs) { + constexpr void setRowSpan(uint32_t rs) + { data = (data & ~(MaskRowSpan << ShiftRowSpan)) | ((static_cast(rs) & MaskRowSpan) << ShiftRowSpan); } - constexpr void setColSpan(uint32_t cs) { + constexpr void setColSpan(uint32_t cs) + { data = (data & ~(MaskColSpan << ShiftColSpan)) | ((static_cast(cs) & MaskColSpan) << ShiftColSpan); } - constexpr void setPattern(uint32_t p) { + constexpr void setPattern(uint32_t p) + { data = (data & ~(MaskPattern << ShiftPattern)) | ((static_cast(p) & MaskPattern) << ShiftPattern); } - constexpr void setTopology(uint32_t t) { + constexpr void setTopology(uint32_t t) + { data = (data & ~(MaskTopology << ShiftTopology)) | ((static_cast(t) & MaskTopology) << ShiftTopology); } @@ -120,13 +127,14 @@ class Cluster } // Unpack Getters - uint32_t getRow() const { return mClusterInfo.getRow(); } - uint32_t getCol() const { return mClusterInfo.getCol(); } - uint32_t getRowSpan() const { return mClusterInfo.getRowSpan(); } - uint32_t getColSpan() const { return mClusterInfo.getColSpan(); } - uint32_t getPattern() const { return mClusterInfo.getPattern(); } + uint32_t getRow() const { return mClusterInfo.getRow(); } + uint32_t getCol() const { return mClusterInfo.getCol(); } + uint32_t getRowSpan() const { return mClusterInfo.getRowSpan(); } + uint32_t getColSpan() const { return mClusterInfo.getColSpan(); } + uint32_t getPattern() const { return mClusterInfo.getPattern(); } uint32_t getTopology() const { return mClusterInfo.getTopology(); } - int getSize() const { + int getSize() const + { // Count the number of set bits in the pattern to determine the size of the cluster uint32_t pattern = getPattern(); int size = 0; @@ -138,20 +146,20 @@ class Cluster } // BaseCluster / Interface Compatibility Getters - uint32_t getChipID() const { return mChipID; } + uint32_t getChipID() const { return mChipID; } uint32_t getSensorID() const { return mChipID; } - time_t getTime() const { return mTime; } + time_t getTime() const { return mTime; } uint64_t getPackedData() const { return mClusterInfo.data; } // Setters - void setRow(UShort_t r) { mClusterInfo.setRow(r); } - void setCol(UShort_t c) { mClusterInfo.setCol(c); } - void setRowSpan(UShort_t rs) { mClusterInfo.setRowSpan(rs); } - void setColSpan(UShort_t cs) { mClusterInfo.setColSpan(cs); } - void setPatternID(UShort_t p) { mClusterInfo.setPattern(p); } - void setTopology(UShort_t t) { mClusterInfo.setTopology(t); } - void setChipID(UShort_t c) { mChipID = c; } - void setTime(time_t t) { mTime = t; } + void setRow(UShort_t r) { mClusterInfo.setRow(r); } + void setCol(UShort_t c) { mClusterInfo.setCol(c); } + void setRowSpan(UShort_t rs) { mClusterInfo.setRowSpan(rs); } + void setColSpan(UShort_t cs) { mClusterInfo.setColSpan(cs); } + void setPatternID(UShort_t p) { mClusterInfo.setPattern(p); } + void setTopology(UShort_t t) { mClusterInfo.setTopology(t); } + void setChipID(UShort_t c) { mChipID = c; } + void setTime(time_t t) { mTime = t; } // Operators & Debugging bool operator==(const Cluster& cl) const diff --git a/Detectors/Upgrades/ALICE3/IOTOF/DataFormatsIOTOF/src/Cluster.cxx b/Detectors/Upgrades/ALICE3/IOTOF/DataFormatsIOTOF/src/Cluster.cxx index 22735a9225c19..b0ea13477909f 100644 --- a/Detectors/Upgrades/ALICE3/IOTOF/DataFormatsIOTOF/src/Cluster.cxx +++ b/Detectors/Upgrades/ALICE3/IOTOF/DataFormatsIOTOF/src/Cluster.cxx @@ -38,8 +38,7 @@ std::string Cluster::asString() const getRowSpan(), getColSpan(), getPattern(), - getTopology() - ); + getTopology()); } //______________________________________________________________________________ @@ -54,11 +53,11 @@ void Cluster::sanityCheck() LOG(debug) << "[Cluster::sanityCheck] Performing sanity check on Cluster fields"; // Ensure extracted values fit within allowed bit masks - assert(getRow() <= ClusterInfo::MaskRow); - assert(getCol() <= ClusterInfo::MaskCol); - assert(getRowSpan() <= ClusterInfo::MaskRowSpan); - assert(getColSpan() <= ClusterInfo::MaskColSpan); - assert(getPattern() <= ClusterInfo::MaskPattern); + assert(getRow() <= ClusterInfo::MaskRow); + assert(getCol() <= ClusterInfo::MaskCol); + assert(getRowSpan() <= ClusterInfo::MaskRowSpan); + assert(getColSpan() <= ClusterInfo::MaskColSpan); + assert(getPattern() <= ClusterInfo::MaskPattern); assert(getTopology() <= ClusterInfo::MaskTopology); } diff --git a/Detectors/Upgrades/ALICE3/IOTOF/macros/CheckClustersIOTOF.C b/Detectors/Upgrades/ALICE3/IOTOF/macros/CheckClustersIOTOF.C index 5825c499f39cf..15840f21d3978 100644 --- a/Detectors/Upgrades/ALICE3/IOTOF/macros/CheckClustersIOTOF.C +++ b/Detectors/Upgrades/ALICE3/IOTOF/macros/CheckClustersIOTOF.C @@ -49,11 +49,11 @@ using namespace o2::base; using namespace o2::iotof; -using o2::iotof::Digit; using o2::iotof::Cluster; +using o2::iotof::Digit; - -void GetHitAvgPositionGlobal(const o2::itsmft::Hit& hit, o2::math_utils::Point3D& avgPos) { +void GetHitAvgPositionGlobal(const o2::itsmft::Hit& hit, o2::math_utils::Point3D& avgPos) +{ o2::math_utils::Point3D startPos = hit.GetPosStart(); o2::math_utils::Point3D endPos = hit.GetPos(); @@ -61,8 +61,8 @@ void GetHitAvgPositionGlobal(const o2::itsmft::Hit& hit, o2::math_utils::Point3D avgPos = o2::math_utils::Point3D((startPos.X() + endPos.X()) / 2, (startPos.Y() + endPos.Y()) / 2, (startPos.Z() + endPos.Z()) / 2); } - -void GetHitAvgPositionLocal(const o2::itsmft::Hit& hit, o2::iotof::GeometryTGeo* geom, o2::math_utils::Point3D& avgPos) { +void GetHitAvgPositionLocal(const o2::itsmft::Hit& hit, o2::iotof::GeometryTGeo* geom, o2::math_utils::Point3D& avgPos) +{ const int chipID = hit.GetDetectorID(); @@ -74,16 +74,16 @@ void GetHitAvgPositionLocal(const o2::itsmft::Hit& hit, o2::iotof::GeometryTGeo* avgPos = o2::math_utils::Point3D((startPosLocal.X() + endPosLocal.X()) / 2, (startPosLocal.Y() + endPosLocal.Y()) / 2, (startPosLocal.Z() + endPosLocal.Z()) / 2); } - -void PrintMcTrack(bool verbose, const o2::MCTrack& mcTrack) { +void PrintMcTrack(bool verbose, const o2::MCTrack& mcTrack) +{ if (!verbose) { return; } std::cout << "MCTrack: pdgCode = " << mcTrack.GetPdgCode() << ", isPrimary = " << mcTrack.isPrimary() << ", process: " << mcTrack.getProcess() << ", pt = " << mcTrack.GetPt() << ", eta = " << mcTrack.GetEta() << ", phi = " << mcTrack.GetPhi() << std::endl; } - -void PrintHit(bool verbose, o2::itsmft::Hit hit, o2::iotof::GeometryTGeo* iotofGeom, o2::iotof::Segmentation* segmInfo) { +void PrintHit(bool verbose, o2::itsmft::Hit hit, o2::iotof::GeometryTGeo* iotofGeom, o2::iotof::Segmentation* segmInfo) +{ if (!verbose) { return; } @@ -102,12 +102,12 @@ void PrintHit(bool verbose, o2::itsmft::Hit hit, o2::iotof::GeometryTGeo* iotofG << std::endl; } - void GetClusterGlobalPos(const o2::iotof::Cluster& cluster, TopologyInfo topoInfo, o2::math_utils::Point3D& globalPos, o2::iotof::GeometryTGeo* iotofGeom, - o2::iotof::Segmentation* segmInfo){ + o2::iotof::Segmentation* segmInfo) +{ float x = 0.f; float y = 0.f; @@ -119,13 +119,13 @@ void GetClusterGlobalPos(const o2::iotof::Cluster& cluster, globalPos = iotofGeom->getMatrixL2G(cluster.getChipID())(o2::math_utils::Point3D{x, 0.f, z}); } - void PrintCluster(bool verbose, const o2::iotof::Cluster& cluster, auto clsLabel, TopologyInfo topoInfo, o2::iotof::GeometryTGeo* iotofGeom, - o2::iotof::Segmentation* segmInfo) { + o2::iotof::Segmentation* segmInfo) +{ if (!verbose) { return; } @@ -157,9 +157,9 @@ void PrintCluster(bool verbose, // } } - template -void Print(bool verbose, Args&&... args) { +void Print(bool verbose, Args&&... args) +{ if (!verbose) { return; } @@ -167,12 +167,12 @@ void Print(bool verbose, Args&&... args) { (std::cout << ... << std::forward(args)) << std::endl; } - void GetClusterLocalPos(const o2::iotof::Cluster& cluster, const TopologyInfo& topoInfo, o2::math_utils::Point3D& localPos, o2::iotof::GeometryTGeo* iotofGeom, - o2::iotof::Segmentation* segmInfo){ + o2::iotof::Segmentation* segmInfo) +{ float x = 0.f; float y = 0.f; @@ -189,52 +189,49 @@ void GetClusterLocalPos(const o2::iotof::Cluster& cluster, localPos = o2::math_utils::Point3D{x, 0.f, z}; } - int FindBestMatchingHit(const o2::iotof::Cluster& cluster, TopologyInfo topoInfo, const std::vector& chipHitsIdxs, const std::vector* evtChipHits, o2::iotof::GeometryTGeo* iotofGeom, - o2::iotof::Segmentation* segmInfo){ - int bestHitIdx = -1; - float minDistanceSq = std::numeric_limits::max(); - o2::math_utils::Point3D clsPos; - GetClusterGlobalPos(cluster, topoInfo, clsPos, iotofGeom, segmInfo); + o2::iotof::Segmentation* segmInfo) +{ + int bestHitIdx = -1; + float minDistanceSq = std::numeric_limits::max(); + o2::math_utils::Point3D clsPos; + GetClusterGlobalPos(cluster, topoInfo, clsPos, iotofGeom, segmInfo); - int layerCls{-1}, staveCls{-1}, subStaveCls{-1}, moduleCls{-1}, chipCls{-1}; - iotofGeom->getIOTOFChipId(cluster.getChipID(), layerCls, staveCls, subStaveCls, moduleCls, chipCls); - - for (int i = 0; i < chipHitsIdxs.size(); ++i) { - - const auto& hit = (*evtChipHits)[chipHitsIdxs[i]]; - int layerHit{-1}, staveHit{-1}, subStaveHit{-1}, moduleHit{-1}, chipHit{-1}; - iotofGeom->getIOTOFChipId(hit.GetDetectorID(), layerHit, staveHit, subStaveHit, moduleHit, chipHit); - - // Check same stave, substave because multiple hits - // for a single MC track can only occur in stave/substave - // overlaps - if (layerCls == layerHit - && staveCls == staveHit - && subStaveCls == subStaveHit - // && moduleCls == moduleHit - // && chipCls == chipHit - ) { - - float dx = clsPos.X() - hit.GetX(); - float dy = clsPos.Y() - hit.GetY(); - float dz = clsPos.Z() - hit.GetZ(); - float distSq = dx*dx + dy*dy + dz*dz; - if (distSq < minDistanceSq) { - minDistanceSq = distSq; - bestHitIdx = i; // chipHitsIdxs[i]; - } + int layerCls{-1}, staveCls{-1}, subStaveCls{-1}, moduleCls{-1}, chipCls{-1}; + iotofGeom->getIOTOFChipId(cluster.getChipID(), layerCls, staveCls, subStaveCls, moduleCls, chipCls); + + for (int i = 0; i < chipHitsIdxs.size(); ++i) { + + const auto& hit = (*evtChipHits)[chipHitsIdxs[i]]; + int layerHit{-1}, staveHit{-1}, subStaveHit{-1}, moduleHit{-1}, chipHit{-1}; + iotofGeom->getIOTOFChipId(hit.GetDetectorID(), layerHit, staveHit, subStaveHit, moduleHit, chipHit); + + // Check same stave, substave because multiple hits + // for a single MC track can only occur in stave/substave + // overlaps + if (layerCls == layerHit && staveCls == staveHit && subStaveCls == subStaveHit + // && moduleCls == moduleHit + // && chipCls == chipHit + ) { + + float dx = clsPos.X() - hit.GetX(); + float dy = clsPos.Y() - hit.GetY(); + float dz = clsPos.Z() - hit.GetZ(); + float distSq = dx * dx + dy * dy + dz * dz; + if (distSq < minDistanceSq) { + minDistanceSq = distSq; + bestHitIdx = i; // chipHitsIdxs[i]; } } + } - return bestHitIdx; // Returns -1 if no hit is found + return bestHitIdx; // Returns -1 if no hit is found } - struct ClusterProperties { int clsIdx = -1; int eventID = -1; @@ -248,9 +245,9 @@ struct ClusterProperties { uint8_t colSpan = 0; int size = 0; bool isPrimary = false; - std::vector assocPrimaries = {}; // More than one primary MC particle from the same event is associated to the cluster - bool isShared = false; // More than one primary MC particle from the same event is associated to the cluster - bool isFake = false; // More than one primary MC particle from different events is associated to the cluster + std::vector assocPrimaries = {}; // More than one primary MC particle from the same event is associated to the cluster + bool isShared = false; // More than one primary MC particle from the same event is associated to the cluster + bool isFake = false; // More than one primary MC particle from different events is associated to the cluster int hitIdx = -1; Topologies topology = kOther; uint32_t topoKey = 0; @@ -263,7 +260,6 @@ struct DetectorData { std::vector clsIndicesL1; }; - void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", std::string hitfile = "o2sim_HitsTF3.root", std::string clsFilePath = "tf3clusters.root", @@ -316,11 +312,16 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", int nPixelsB = b.second.mNPixels; int frequencyA = a.second.mFrequency; int frequencyB = b.second.mFrequency; - if (topoA != topoB) return topoA < topoB; - if (frequencyA != frequencyB) return frequencyA > frequencyB; - if (spanRowA != spanRowB) return spanRowA < spanRowB; - if (spanColA != spanColB) return spanColA < spanColB; - if (nPixelsA != nPixelsB) return nPixelsA < nPixelsB; + if (topoA != topoB) + return topoA < topoB; + if (frequencyA != frequencyB) + return frequencyA > frequencyB; + if (spanRowA != spanRowB) + return spanRowA < spanRowB; + if (spanColA != spanColB) + return spanColA < spanColB; + if (nPixelsA != nPixelsB) + return nPixelsA < nPixelsB; return a.first < b.first; // Finally sort by bitmask if spans are equal }); @@ -425,29 +426,28 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", tracksHitCls[trackKey].hitIndicesL1.push_back(iHit); } - auto &mcTrack = (*mcTracksPerEvent[iEvt])[trackID]; + auto& mcTrack = (*mcTracksPerEvent[iEvt])[trackID]; bool isPrimary = mcTrack.isPrimary(); - if (isPrimary) nHitsFromPrimaryTracks++; - else nHitsFromSecondaryTracks++; - - float genEta = mcTrack.GetEta(); - float genPhi = mcTrack.GetPhi(); - float genPt = mcTrack.GetPt(); + if (isPrimary) + nHitsFromPrimaryTracks++; + else + nHitsFromSecondaryTracks++; + + float genEta = mcTrack.GetEta(); + float genPhi = mcTrack.GetPhi(); + float genPt = mcTrack.GetPt(); int hitLayer = iotofGeom->getIOTOFLayer(hit.GetDetectorID()); - if (hitLayer == 0 && isPrimary) { + if (hitLayer == 0 && isPrimary) { hEtaPhiHitsPrmTrkLayer0->Fill(genPhi, genEta); hEtaPtHitsPrmTrkLayer0->Fill(genEta, genPt); - } - else if (hitLayer == 0 && !isPrimary) { + } else if (hitLayer == 0 && !isPrimary) { hEtaPhiHitsSecTrkLayer0->Fill(genPhi, genEta); hEtaPtHitsSecTrkLayer0->Fill(genEta, genPt); - } - else if (hitLayer == 1 && isPrimary) { + } else if (hitLayer == 1 && isPrimary) { hEtaPhiHitsPrmTrkLayer1->Fill(genPhi, genEta); hEtaPtHitsPrmTrkLayer1->Fill(genEta, genPt); - } - else { + } else { hEtaPhiHitsSecTrkLayer1->Fill(genPhi, genEta); hEtaPtHitsSecTrkLayer1->Fill(genEta, genPt); } @@ -464,11 +464,11 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", if (clsLabels.empty()) continue; - // Link the cluster to the primary track + // Link the cluster to the primary track int clsEventID{-1}, clsTrackID{-1}; bool hasValidLabels{false}; int nAssoc{0}; - for (int iLabel=0; iLabel(clsEventID) << 32) | static_cast(clsTrackID); @@ -517,11 +517,15 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", tracksHitCls[trackKey].clsIndicesL1.push_back(iCls); } - if (clsLayer == 0 && isPrimary) { hEtaPhiClsPrmTrkLayer0->Fill(genPhi, genEta); } - else if (clsLayer == 0 && !isPrimary) { hEtaPhiClsSecTrkLayer0->Fill(genPhi, genEta); } - else if (clsLayer == 1 && isPrimary) { hEtaPhiClsPrmTrkLayer1->Fill(genPhi, genEta); } - else { hEtaPhiClsSecTrkLayer1->Fill(genPhi, genEta); } - + if (clsLayer == 0 && isPrimary) { + hEtaPhiClsPrmTrkLayer0->Fill(genPhi, genEta); + } else if (clsLayer == 0 && !isPrimary) { + hEtaPhiClsSecTrkLayer0->Fill(genPhi, genEta); + } else if (clsLayer == 1 && isPrimary) { + hEtaPhiClsPrmTrkLayer1->Fill(genPhi, genEta); + } else { + hEtaPhiClsSecTrkLayer1->Fill(genPhi, genEta); + } } // Create vectors of digits with same chip index, cluster candidates @@ -551,7 +555,7 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", bool hasValidLabels{false}; std::set uniqueEventIDs; - for (int iLabel=0; iLabelgetIOTOFLayer(cls.getChipID()); + clsProps.chipID = cls.getChipID(); + clsProps.layer = iotofGeom->getIOTOFLayer(cls.getChipID()); clsProps.rowStart = cls.getRow(); - clsProps.rowSpan = cls.getRowSpan(); + clsProps.rowSpan = cls.getRowSpan(); clsProps.colStart = cls.getCol(); - clsProps.colSpan = cls.getColSpan(); - clsProps.pattern = cls.getPattern(); - clsProps.size = cls.getSize(); + clsProps.colSpan = cls.getColSpan(); + clsProps.pattern = cls.getPattern(); + clsProps.size = cls.getSize(); clsProps.topology = static_cast(cls.getTopology()); uint32_t clsTopoKey = (static_cast(clsProps.rowSpan) << 24) | (static_cast(clsProps.colSpan) << 16) | - static_cast(clsProps.pattern); + static_cast(clsProps.pattern); clsProps.topoKey = clsTopoKey; TopologyInfo clsTopoInfo = topoClassifier.getTopologyFeatures(clsProps.topoKey); @@ -615,7 +619,7 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", clsProps.isFake = (uniqueEventIDs.size() > 1); clsProps.hitIdx = -1; clsProps.isPrimary = mcTrack.isPrimary(); - float genPt = mcTrack.GetPt(); + float genPt = mcTrack.GetPt(); uint64_t trackKey = (static_cast(clsEventID) << 32) | static_cast(clsTrackID); @@ -629,7 +633,8 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", if (chipHitsIdxs.size() == 0) { std::cout << "No hits by this track and event in this chip: " << clsProps.chipID << std::endl; continue; - } if (chipHitsIdxs.size() == 1) { + } + if (chipHitsIdxs.size() == 1) { clsProps.hitIdx = 0; hCountHitMatchingType->Fill(clsProps.isPrimary ? 0 : 2, genPt); } else { @@ -646,7 +651,6 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", // // Print cluster information // PrintCluster(verbose, cluster, digitsArray, digitsLabels, hitsPerEvent, iotofGeom, segmInfo); clustersProperties.push_back(clsProps); - } Print(true, "----> Total number of clusters: ", clustersProperties.size()); @@ -656,7 +660,7 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", const auto eventID = static_cast(trackKey >> 32); const auto trackID = static_cast(trackKey & 0xFFFFFFFF); Print(verbose, "\n\n"); - PrintMcTrack(verbose, (*mcTracksPerEvent[eventID])[trackID]); + PrintMcTrack(verbose, (*mcTracksPerEvent[eventID])[trackID]); Print(verbose, "Layer 0"); for (const auto& hitIdx : trackProperties.second.hitIndicesL0) { @@ -668,7 +672,7 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", const auto& clsLabels = clustersLabelsArr->getLabels(clsIdx); uint32_t clsTopoKey = (static_cast(cls.getRowSpan()) << 24) | (static_cast(cls.getColSpan()) << 16) | - static_cast(cls.getPattern()); + static_cast(cls.getPattern()); TopologyInfo clsTopoInfo = topoClassifier.getTopologyFeatures(clsTopoKey); PrintCluster(verbose, cls, clsLabels, clsTopoInfo, iotofGeom, segmInfo); } @@ -682,7 +686,7 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", const auto& clsLabels = clustersLabelsArr->getLabels(clsIdx); uint32_t clsTopoKey = (static_cast(cls.getRowSpan()) << 24) | (static_cast(cls.getColSpan()) << 16) | - static_cast(cls.getPattern()); + static_cast(cls.getPattern()); TopologyInfo clsTopoInfo = topoClassifier.getTopologyFeatures(clsTopoKey); PrintCluster(verbose, cls, clsLabels, clsTopoInfo, iotofGeom, segmInfo); } @@ -697,7 +701,8 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", Print(true, "Number of clusters: ", clustersArray->size()); Print(true, "Number of clusters labels: ", clustersLabelsArr->getNElements()); Print(true, "Number of entries in cluster tree: ", clustersTree->GetEntries()); - std::cout << "***********************************\n" << std::endl; + std::cout << "***********************************\n" + << std::endl; // QA printouts and histograms Print(true, "\n\n----> Starting QA logging ... "); @@ -722,7 +727,6 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", hEtaPhiClsPrmTrkLayer1->Write(); hEtaPhiClsSecTrkLayer1->Write(); - // Count fake clusters TH1F* hCountClsTypes[2][2]; for (int layer = 0; layer < 2; ++layer) { @@ -753,11 +757,11 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", // Topology names const std::array topologyNames = { - "kSingleDigit", "kLineOnRow", "kLineOnCol", "kSquare", "kRectangle", "kDiagonal", - "kLowerTriangleLeft", "kLowerTriangleRight", "kUpperTriangleLeft", "kUpperTriangleRight", - "kSnake", "kSnakeRefl", "kSnakeRot90", "kSnakeRot90Refl", "kHuge", "kOther"}; + "kSingleDigit", "kLineOnRow", "kLineOnCol", "kSquare", "kRectangle", "kDiagonal", + "kLowerTriangleLeft", "kLowerTriangleRight", "kUpperTriangleLeft", "kUpperTriangleRight", + "kSnake", "kSnakeRefl", "kSnakeRot90", "kSnakeRot90Refl", "kHuge", "kOther"}; - // Count topologies from frequency values in + // Count topologies from frequency values in // topologies dictionary and fill the summary histograms TH1F* hTopoSummaryDictionary = new TH1F("hTopoSummaryDictionary", "Cluster Topology Count Summary;;Counts", kNTopologies, 0, kNTopologies); for (const auto& [topoKey, topology] : topoClassifier.getTopologyMap()) { @@ -765,13 +769,13 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", } TH2F *hTrueClsSizeVsEta[2][2], *hSplitClsEtaPt[2][2], *hTrueClsSizeVsPhi[2][2], *hFakeClsSizeVsEta[2][2], *hFakeClsSizeVsPhi[2][2], - *hClustersEtaPhi[2][2], *hTopoVsEta[2][2], *hClsSizeVsTopo[2][2], - *hXResVsEta[2][2], *hZResVsEta[2][2], *hXZRes[2][2], *hXResVsTopo[2][2], *hZResVsTopo[2][2], - *hTrackHitsXY[2][2], *hTrackDoubleHitsXY[2][2], *hTrackDoubleHitsPhiPt[2][2], *hTopoVsEtaPt[2][2][kNTopologies], - *hRecoClsEtaPt[2][2]; + *hClustersEtaPhi[2][2], *hTopoVsEta[2][2], *hClsSizeVsTopo[2][2], + *hXResVsEta[2][2], *hZResVsEta[2][2], *hXZRes[2][2], *hXResVsTopo[2][2], *hZResVsTopo[2][2], + *hTrackHitsXY[2][2], *hTrackDoubleHitsXY[2][2], *hTrackDoubleHitsPhiPt[2][2], *hTopoVsEtaPt[2][2][kNTopologies], + *hRecoClsEtaPt[2][2]; TH1F *hMeanTrueClsSizeVsEta[2][2], *hMeanTrueClsSizeVsPhi[2][2], *hMeanFakeClsSizeVsEta[2][2], *hMeanFakeClsSizeVsPhi[2][2], - *hRmsXResVsEta[2][2], *hRmsZResVsEta[2][2], *hMeanXResVsEta[2][2], *hMeanZResVsEta[2][2], - *hRmsXResVsTopo[2][2], *hRmsZResVsTopo[2][2], *hMeanXResVsTopo[2][2], *hMeanZResVsTopo[2][2]; + *hRmsXResVsEta[2][2], *hRmsZResVsEta[2][2], *hMeanXResVsEta[2][2], *hMeanZResVsEta[2][2], + *hRmsXResVsTopo[2][2], *hRmsZResVsTopo[2][2], *hMeanXResVsTopo[2][2], *hMeanZResVsTopo[2][2]; TH1F* hTopoSummaryTotal = new TH1F("hTopoSummaryTotal", "Cluster Topology Summary;;Counts", kNTopologies, 0, kNTopologies); TH1F* hTopoSummaryReal = new TH1F("hTopoSummaryReal", "Cluster Topology Summary;;Counts", kNTopologies, 0, kNTopologies); TH1F* hTopoSummaryFake = new TH1F("hTopoSummaryFake", "Cluster Topology Summary;;Counts", kNTopologies, 0, kNTopologies); @@ -835,8 +839,7 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", Form("hNotRecoHits_layer%d_type%d", l, t), Form("Local Position Unreconstructed Hits L%d Type%d;x (cm);y (cm)", l, t), 1000, -2., 2., // Adjust binning/ranges to your sensor dimensions - 1000, -2., 2. - ); + 1000, -2., 2.); } } @@ -845,7 +848,9 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", int trackID = static_cast(trackProperties.first & 0xFFFFFFFF); const auto& mcTrack = (*mcTracksPerEvent[eventID])[trackID]; - if (!mcTrack.isPrimary()) { continue; } + if (!mcTrack.isPrimary()) { + continue; + } const int type = 0; if (trackProperties.second.hitIndicesL0.empty() && trackProperties.second.hitIndicesL1.empty()) { @@ -883,7 +888,8 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", // Helper lambda to check a layer's cluster list auto hasNonAdjacentDoubleClusters = [&](const std::vector& hitIndices) -> bool { - if (hitIndices.size() < 2) return false; + if (hitIndices.size() < 2) + return false; // Collect unique chip IDs for this layer std::vector chips; @@ -893,7 +899,8 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", std::sort(chips.begin(), chips.end()); chips.erase(std::unique(chips.begin(), chips.end()), chips.end()); - if (chips.size() < 2) return false; // All clusters are on the exact same chip + if (chips.size() < 2) + return false; // All clusters are on the exact same chip // Check if ANY pair of chips is non-adjacent for (size_t i = 0; i < chips.size(); ++i) { @@ -949,22 +956,23 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", // Loop over clusters Print(true, "----> Looping over clusters and filling histograms"); - std::cout << "\n\n\n\n\n\n\n" << std::endl; + std::cout << "\n\n\n\n\n\n\n" + << std::endl; for (const auto& cls : clustersProperties) { const int layer = cls.layer; - const int topo = static_cast(cls.topology); + const int topo = static_cast(cls.topology); - const int chipID = cls.chipID; - const int eventID = cls.eventID; - const int trackID = cls.trackID; + const int chipID = cls.chipID; + const int eventID = cls.eventID; + const int trackID = cls.trackID; const auto& mcTrack = (*mcTracksPerEvent[eventID])[trackID]; - const float eta = mcTrack.GetEta(); - const float phi = mcTrack.GetPhi(); - const float pt = mcTrack.GetPt(); - const int type = cls.isPrimary ? 0 : 1; - const int size = cls.size; + const float eta = mcTrack.GetEta(); + const float phi = mcTrack.GetPhi(); + const float pt = mcTrack.GetPt(); + const int type = cls.isPrimary ? 0 : 1; + const int size = cls.size; hTopoVsEtaPt[layer][type][topo]->Fill(eta, pt); hTopoVsEta[layer][type]->Fill(topo, eta); @@ -1124,14 +1132,14 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", // Compute Efficiency vs Eta TH1D* hClustersEta = hClustersEtaPhi[layer][type]->ProjectionY(Form("hClsEta_%sTrkLayer%d", trackName[type], layer)); - TH1D* hHitsEta = hEtaPhiHits->ProjectionY(Form("hHitsEta_%sTrkLayer%d", trackName[type], layer)); + TH1D* hHitsEta = hEtaPhiHits->ProjectionY(Form("hHitsEta_%sTrkLayer%d", trackName[type], layer)); TH1F* hEffVsEta = static_cast(hClustersEta->Clone(Form("hClsEffVsEta%sTrkLayer%d", trackName[type], layer))); hEffVsEta->Divide(hHitsEta); // Compute proper binomial uncertainties for (int bin = 1; bin <= hEffVsEta->GetNbinsX(); ++bin) { - double eff = hEffVsEta->GetBinContent(bin); + double eff = hEffVsEta->GetBinContent(bin); double nHits = hHitsEta->GetBinContent(bin); if (nHits > 0) { @@ -1146,13 +1154,13 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", hEffVsEta->Write("hClsEffVsEta"); TH1D* hClustersPt = hRecoClsEtaPt[layer][type]->ProjectionY(Form("hClsPt_%sTrkLayer%d", trackName[type], layer)); - TH1D* hHitsPt = hEtaPtHits->ProjectionY(Form("hHitsPt_%sTrkLayer%d", trackName[type], layer)); + TH1D* hHitsPt = hEtaPtHits->ProjectionY(Form("hHitsPt_%sTrkLayer%d", trackName[type], layer)); TH1F* hEffVsPt = static_cast(hClustersPt->Clone(Form("hClsEffVsPt%sTrkLayer%d", trackName[type], layer))); hEffVsPt->Divide(hHitsPt); // Compute proper binomial uncertainties for (int bin = 1; bin <= hEffVsPt->GetNbinsX(); ++bin) { - double eff = hEffVsPt->GetBinContent(bin); + double eff = hEffVsPt->GetBinContent(bin); double nHits = hHitsPt->GetBinContent(bin); if (nHits > 0) { @@ -1168,14 +1176,14 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", // Compute Efficiency vs Phi TH1D* hClustersPhi = hClustersEtaPhi[layer][type]->ProjectionX(Form("hClsPhi_%sTrkLayer%d", trackName[type], layer)); - TH1D* hHitsPhi = hEtaPhiHits->ProjectionX(Form("hHitsPhi_%sTrkLayer%d", trackName[type], layer)); + TH1D* hHitsPhi = hEtaPhiHits->ProjectionX(Form("hHitsPhi_%sTrkLayer%d", trackName[type], layer)); TH1F* hEffVsPhi = static_cast(hClustersPhi->Clone(Form("hClsEffVsPhi%sTrkLayer%d", trackName[type], layer))); hEffVsPhi->Divide(hHitsPhi); // Compute proper binomial uncertainties for (int bin = 1; bin <= hEffVsPhi->GetNbinsX(); ++bin) { - double eff = hEffVsPhi->GetBinContent(bin); + double eff = hEffVsPhi->GetBinContent(bin); double nHits = hHitsPhi->GetBinContent(bin); if (nHits > 0) { @@ -1215,7 +1223,8 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", } outFile->cd(Form("%sTrkLayer%d/Topologies", trackName[type], layer)); - for (int topo = 0; topo < kNTopologies; ++topo) hTopoVsEtaPt[layer][type][topo]->Write(Form("%sVsEtaPt", topologyNames[topo].c_str())); + for (int topo = 0; topo < kNTopologies; ++topo) + hTopoVsEtaPt[layer][type][topo]->Write(Form("%sVsEtaPt", topologyNames[topo].c_str())); } } @@ -1229,8 +1238,7 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", cTrackHitsXY[layer][type] = new TCanvas( Form("cTrackHitsXY%sTrkLayer%d", trackName[type], layer), Form("Track Hits XY %s Track Layer %d", trackName[type], layer), - 800, 600 - ); + 800, 600); // Constrain in a box (xMin, xMax, yMin, yMax) to visualize the double hits if (layer == 0) { @@ -1296,20 +1304,18 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", float maxRowCoord = chipInfo.PitchRow * (spanRow + 0.5); float minColCoord = -1.5 * chipInfo.PitchCol; float maxColCoord = chipInfo.PitchCol * (spanCol + 0.5); - TH2F* hTopoDisplayAll = new TH2F(Form("spanRow_%i_spanCol_%i_key_%i_all", spanRow, spanCol, topoKey), Form("Cluster Topology %s;Row;Column", topoName.c_str()), + TH2F* hTopoDisplayAll = new TH2F(Form("spanRow_%i_spanCol_%i_key_%i_all", spanRow, spanCol, topoKey), Form("Cluster Topology %s;Row;Column", topoName.c_str()), spanRow + 2, minRowCoord, maxRowCoord, spanCol + 2, minColCoord, maxColCoord); - TH2F* hTopoDisplayReal = new TH2F(Form("spanRow_%i_spanCol_%i_key_%i_real", spanRow, spanCol, topoKey), Form("Cluster Topology %s;Row;Column", topoName.c_str()), + TH2F* hTopoDisplayReal = new TH2F(Form("spanRow_%i_spanCol_%i_key_%i_real", spanRow, spanCol, topoKey), Form("Cluster Topology %s;Row;Column", topoName.c_str()), spanRow + 2, minRowCoord, maxRowCoord, spanCol + 2, minColCoord, maxColCoord); - TH2F* hTopoDisplayFake = new TH2F(Form("spanRow_%i_spanCol_%i_key_%i_fake", spanRow, spanCol, topoKey), Form("Cluster Topology %s;Row;Column", topoName.c_str()), + TH2F* hTopoDisplayFake = new TH2F(Form("spanRow_%i_spanCol_%i_key_%i_fake", spanRow, spanCol, topoKey), Form("Cluster Topology %s;Row;Column", topoName.c_str()), spanRow + 2, minRowCoord, maxRowCoord, spanCol + 2, minColCoord, maxColCoord); int frequency = topology.mFrequency; int countFakeThisTopo = std::count_if(clustersProperties.begin(), clustersProperties.end(), - [topoKey](const ClusterProperties& cls) - { return cls.topoKey == topoKey && cls.isFake; }); + [topoKey](const ClusterProperties& cls) { return cls.topoKey == topoKey && cls.isFake; }); int countRealThisTopo = std::count_if(clustersProperties.begin(), clustersProperties.end(), - [topoKey](const ClusterProperties& cls) - { return cls.topoKey == topoKey && !cls.isFake; }); + [topoKey](const ClusterProperties& cls) { return cls.topoKey == topoKey && !cls.isFake; }); // One-point TGraph for COG TGraph* gTopoCOG = new TGraph(1); @@ -1319,17 +1325,17 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", gTopoCOG->SetMarkerStyle(20); gTopoCOG->SetMarkerColor(kBlue); - // Loop over the bits of bitmask and fill the histogram + // Loop over the bits of bitmask and fill the histogram for (int row = 0; row < spanRow; ++row) { for (int col = 0; col < spanCol; ++col) { int bitIndex = row * spanCol + col; if (bitmask & (1 << bitIndex)) { - hTopoDisplayAll->SetBinContent(row+2, col+2, frequency); + hTopoDisplayAll->SetBinContent(row + 2, col + 2, frequency); if (countRealThisTopo > 0) { - hTopoDisplayReal->SetBinContent(row+2, col+2, countFakeThisTopo); + hTopoDisplayReal->SetBinContent(row + 2, col + 2, countFakeThisTopo); } if (countFakeThisTopo > 0) { - hTopoDisplayFake->SetBinContent(row+2, col+2, countRealThisTopo); + hTopoDisplayFake->SetBinContent(row + 2, col + 2, countRealThisTopo); } } } @@ -1360,7 +1366,9 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", int eventID = static_cast(trackProperties.first >> 32); int trackID = static_cast(trackProperties.first & 0xFFFFFFFF); const auto& mcTrack = (*mcTracksPerEvent[eventID])[trackID]; - if (!mcTrack.isPrimary()) { continue; } + if (!mcTrack.isPrimary()) { + continue; + } if (!(trackProperties.second.hitIndicesL0.size() > 0 && trackProperties.second.clsIndicesL0.empty()) || !(trackProperties.second.hitIndicesL1.size() > 0 && trackProperties.second.clsIndicesL1.empty())) { diff --git a/Detectors/Upgrades/ALICE3/IOTOF/reconstruction/include/IOTOFReconstruction/ClustererParam.h b/Detectors/Upgrades/ALICE3/IOTOF/reconstruction/include/IOTOFReconstruction/ClustererParam.h index 038cf639ba674..388fec83143b9 100644 --- a/Detectors/Upgrades/ALICE3/IOTOF/reconstruction/include/IOTOFReconstruction/ClustererParam.h +++ b/Detectors/Upgrades/ALICE3/IOTOF/reconstruction/include/IOTOFReconstruction/ClustererParam.h @@ -30,8 +30,8 @@ namespace iotof { struct ClustererParam : public o2::conf::ConfigurableParamHelper { - int maxTimeDiffNSigma = 3; ///< maximum time difference in nsigma for clustering - int maxFiredDigitsForCls = 16; ///< maximum time difference in nsigma for clustering + int maxTimeDiffNSigma = 3; ///< maximum time difference in nsigma for clustering + int maxFiredDigitsForCls = 16; ///< maximum time difference in nsigma for clustering // boilerplate stuff + make principal key O2ParamDef(ClustererParam, "TF3ClustererParam"); diff --git a/Detectors/Upgrades/ALICE3/IOTOF/reconstruction/include/IOTOFReconstruction/TopologyClassifier.h b/Detectors/Upgrades/ALICE3/IOTOF/reconstruction/include/IOTOFReconstruction/TopologyClassifier.h index dd7de45b1a65e..b87517051b6f1 100644 --- a/Detectors/Upgrades/ALICE3/IOTOF/reconstruction/include/IOTOFReconstruction/TopologyClassifier.h +++ b/Detectors/Upgrades/ALICE3/IOTOF/reconstruction/include/IOTOFReconstruction/TopologyClassifier.h @@ -14,7 +14,7 @@ /// /// Short TopologyClassifier descritpion /// -/// This class is for the association of the cluster +/// This class is for the association of the cluster /// topology with the corresponding entry in the dictionary /// @@ -71,7 +71,8 @@ struct TopologyInfo { Topologies mTopology = Topologies::kNTopologies; uint16_t mPattern; ///< Bitmask of fired pixels - void print() const { + void print() const + { LOG(info) << "---> TopologyInfo: Topology = " << static_cast(mTopology) << ", SizeX = " << mSizeX << ", SizeZ = " << mSizeZ << ", OffsetXToCOG = " << mOffsetXToCOG << ", OffsetZToCOG = " << mOffsetZToCOG @@ -83,7 +84,8 @@ struct TopologyInfo { } }; -class TopologyClassifier { +class TopologyClassifier +{ public: // Define limits for domain validation static constexpr uint8_t MaxRowSpan = 255; @@ -104,10 +106,11 @@ class TopologyClassifier { private: /// Packs: [ spanRow (8b) ][ spanCol (8b) ][ bitmask (16b) ] -> 32 bits total - [[nodiscard]] static constexpr uint32_t packKey(uint8_t spanRow, uint8_t spanCol, uint16_t bitmask) noexcept { + [[nodiscard]] static constexpr uint32_t packKey(uint8_t spanRow, uint8_t spanCol, uint16_t bitmask) noexcept + { return (static_cast(spanRow) << 24) | (static_cast(spanCol) << 16) | - static_cast(bitmask); + static_cast(bitmask); } std::unordered_map mTopologyCache; diff --git a/Detectors/Upgrades/ALICE3/IOTOF/reconstruction/src/Clusterer.cxx b/Detectors/Upgrades/ALICE3/IOTOF/reconstruction/src/Clusterer.cxx index 35050c0d37272..208e1f1250a2f 100644 --- a/Detectors/Upgrades/ALICE3/IOTOF/reconstruction/src/Clusterer.cxx +++ b/Detectors/Upgrades/ALICE3/IOTOF/reconstruction/src/Clusterer.cxx @@ -136,10 +136,10 @@ void Clusterer::ClustererThread::processChip(gsl::span digits, } findClustersMultipleHits( - digits, - gsl::span(digitIdxs), - labelsDigPtr, - labelsClusPtr); + digits, + gsl::span(digitIdxs), + labelsDigPtr, + labelsClusPtr); } // else { // LOG(info) << "[Clusterer] Processing multi-hit chip with " << nDigits << " hits"; @@ -211,10 +211,10 @@ void Clusterer::ClustererThread::findClustersMultipleHits(gsl::span const auto& digitizerParams = o2::iotof::DPLDigitizerParam::Instance(); float timeResolution = digitizerParams.timeResolution; // in ns const auto& clustererParams = o2::iotof::ClustererParam::Instance(); - int maxTimeDiffNSigma = clustererParams.maxTimeDiffNSigma; // in nsigma + int maxTimeDiffNSigma = clustererParams.maxTimeDiffNSigma; // in nsigma int maxFiredDigitsForCls = clustererParams.maxFiredDigitsForCls; // max fired digits in a cluster - // Digits are ordered by (chipID, row, col, time) within the same chip, + // Digits are ordered by (chipID, row, col, time) within the same chip, // so we can group them into preclusters based on adjacency in row and column. std::vector> preclusters; int chipID = digits[digitIdxs[0]].getChipIndex(); @@ -229,7 +229,7 @@ void Clusterer::ClustererThread::findClustersMultipleHits(gsl::span const auto& lastDigit = digits[lastDigitIdx]; if (std::abs(static_cast(lastDigit.getRow()) - static_cast(row)) <= 1 && std::abs(static_cast(lastDigit.getColumn()) - static_cast(col)) <= 1 && - std::abs(lastDigit.getTime() - digit.getTime()) <= maxTimeDiffNSigma*timeResolution) { + std::abs(lastDigit.getTime() - digit.getTime()) <= maxTimeDiffNSigma * timeResolution) { precluster.push_back(idx); addedToPrecluster = true; break; @@ -325,10 +325,10 @@ void Clusterer::ClustererThread::findClustersMultipleHits(gsl::span const auto& digit = digits[idx]; const uint16_t rowOffset = digit.getRow() - minRow; const uint16_t colOffset = digit.getColumn() - minCol; - + // Single bit position calculation const uint16_t bitIndex = rowOffset * colSpan + colOffset; - + // Set bit in LSB-to-MSB order if (bitIndex < ClusterInfo::NBitsPattern) { firedDigitsMask |= (1U << bitIndex); @@ -346,9 +346,9 @@ void Clusterer::ClustererThread::findClustersMultipleHits(gsl::span } Cluster cluster(minRow, minCol, rowSpan, colSpan, firedDigitsMask, clsTopology, chipID, clsTime); LOG(info) << "Pushing back cluster with row: " << minRow << ", col: " << minCol << ", rowSpan: " << rowSpan - << ", colSpan: " << colSpan << ", pattern: " << firedDigitsMask - << ", topology: " << Topologies::kSingleDigit << ", chipID: " << chipID - << ", time: " << clsTime; + << ", colSpan: " << colSpan << ", pattern: " << firedDigitsMask + << ", topology: " << Topologies::kSingleDigit << ", chipID: " << chipID + << ", time: " << clsTime; mClusters.emplace_back(cluster); } } @@ -390,5 +390,4 @@ void Clusterer::ClustererThread::writeTopologiesToFile(const char* filename) mClsTopoClassifier.saveCacheToFile("TF3ClusterTopologies.root"); } - } // namespace o2::iotof diff --git a/Detectors/Upgrades/ALICE3/IOTOF/reconstruction/src/IOTOFReconstructionLinkDef.h b/Detectors/Upgrades/ALICE3/IOTOF/reconstruction/src/IOTOFReconstructionLinkDef.h index 46b6d93506d59..c38b8b7f02d9a 100644 --- a/Detectors/Upgrades/ALICE3/IOTOF/reconstruction/src/IOTOFReconstructionLinkDef.h +++ b/Detectors/Upgrades/ALICE3/IOTOF/reconstruction/src/IOTOFReconstructionLinkDef.h @@ -21,7 +21,7 @@ #pragma link C++ class o2::iotof::TopologyClassifier + ; -#pragma link C++ class o2::iotof::TopologyInfo+; -#pragma link C++ class std::unordered_map+; +#pragma link C++ class o2::iotof::TopologyInfo + ; +#pragma link C++ class std::unordered_map < uint32_t, o2::iotof::TopologyInfo> + ; #endif diff --git a/Detectors/Upgrades/ALICE3/IOTOF/reconstruction/src/TopologyClassifier.cxx b/Detectors/Upgrades/ALICE3/IOTOF/reconstruction/src/TopologyClassifier.cxx index 5513702b0fee3..73f696acca723 100644 --- a/Detectors/Upgrades/ALICE3/IOTOF/reconstruction/src/TopologyClassifier.cxx +++ b/Detectors/Upgrades/ALICE3/IOTOF/reconstruction/src/TopologyClassifier.cxx @@ -30,7 +30,7 @@ namespace iotof void TopologyClassifier::getTopology(uint16_t bitmask, uint16_t minRow, uint8_t spanRow, uint16_t minCol, uint8_t spanCol, uint8_t& topology) { - // 1. Guard against spans exceeding 8-bit representation for + // 1. Guard against spans exceeding 8-bit representation for // row, col span and 16-bit bitmasks if (spanRow > MaxRowSpan || spanCol > MaxColSpan || bitmask > MaxBitmask) { topology = Topologies::kHuge; @@ -56,7 +56,6 @@ void TopologyClassifier::getTopology(uint16_t bitmask, uint16_t minRow, uint8_t accountTopology(bitmask, minRow, spanRow, minCol, spanCol, topology); } - TopologyInfo TopologyClassifier::getTopologyFeatures(uint32_t key) { auto it = mTopologyCache.find(key); @@ -111,7 +110,8 @@ void TopologyClassifier::accountTopology(uint16_t bitmask, uint16_t minRow, uint int firedDigits = 0; for (int r = minRow; r <= maxRow; ++r) { for (int c = minCol; c <= maxCol; ++c) { - if (hasDigit(r, c)) firedDigits++; + if (hasDigit(r, c)) + firedDigits++; } } @@ -139,13 +139,23 @@ void TopologyClassifier::accountTopology(uint16_t bitmask, uint16_t minRow, uint // Triangles const int nCorners = hasTopLeft + hasTopRight + hasBottomLeft + hasBottomRight; if (nCorners == 3) { - const int missing = !hasTopLeft ? 0 : !hasTopRight ? 1 : !hasBottomLeft ? 2 : 3; + const int missing = !hasTopLeft ? 0 : !hasTopRight ? 1 + : !hasBottomLeft ? 2 + : 3; switch (missing) { - case 0: newTopo.mTopology = Topologies::kLowerTriangleLeft; break; - case 1: newTopo.mTopology = Topologies::kLowerTriangleRight; break; - case 2: newTopo.mTopology = Topologies::kUpperTriangleLeft; break; - case 3: newTopo.mTopology = Topologies::kUpperTriangleRight; break; + case 0: + newTopo.mTopology = Topologies::kLowerTriangleLeft; + break; + case 1: + newTopo.mTopology = Topologies::kLowerTriangleRight; + break; + case 2: + newTopo.mTopology = Topologies::kUpperTriangleLeft; + break; + case 3: + newTopo.mTopology = Topologies::kUpperTriangleRight; + break; } mTopologyCache[packKey(spanRow, spanCol, bitmask)] = newTopo; return; @@ -206,7 +216,6 @@ void TopologyClassifier::accountTopology(uint16_t bitmask, uint16_t minRow, uint } } - void TopologyClassifier::computeCOG(uint16_t bitmask, uint16_t minRow, uint8_t spanRow, uint16_t minCol, uint8_t spanCol, TopologyInfo& topoInfo) { LOG(info) << "\n\nComputing COG"; @@ -255,19 +264,18 @@ void TopologyClassifier::computeCOG(uint16_t bitmask, uint16_t minRow, uint8_t s // topoInfo.mXsigma2 = chipSpecs.PitchRow * chipSpecs.PitchRow / 12. / std::min(10, topoInfo.mSizeX); // topoInfo.mZsigma2 = chipSpecs.PitchCol * chipSpecs.PitchCol / 12. / std::min(10, topoInfo.mSizeZ); // } - } - -void TopologyClassifier::saveCacheToFile(const char* filename) { +void TopologyClassifier::saveCacheToFile(const char* filename) +{ TFile file(filename, "RECREATE"); // Write directly using TObject::Write syntax with explicit class name handling file.WriteObject(&mTopologyCache, "TF3ClusterTopologies"); file.Close(); } - -void TopologyClassifier::print() { +void TopologyClassifier::print() +{ LOG(info) << "Topology Cache Contents:"; for (const auto& entry : mTopologyCache) { const uint32_t key = entry.first; @@ -285,6 +293,5 @@ void TopologyClassifier::print() { } } - -} // namespace o2::iotof +} // namespace iotof } // namespace o2