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 5a6a4b51134b5..403042c8b1485 100644 --- a/Detectors/Upgrades/ALICE3/IOTOF/macros/CheckClustersIOTOF.C +++ b/Detectors/Upgrades/ALICE3/IOTOF/macros/CheckClustersIOTOF.C @@ -48,11 +48,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(); @@ -60,8 +60,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(); @@ -73,16 +73,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) { +void PrintHit(bool verbose, o2::itsmft::Hit hit, o2::iotof::GeometryTGeo* iotofGeom) +{ if (!verbose) { return; } @@ -98,13 +98,13 @@ void PrintHit(bool verbose, o2::itsmft::Hit hit, o2::iotof::GeometryTGeo* iotofG << std::endl; } - // Fare residuo in-chip 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) +{ std::cout << "Computing cluster global position for cluster with bottom left corner at (row = " << cluster.getRow() << ", col = " << cluster.getCol() << "), chipID = " << cluster.getChipID() << std::endl; float x = 0.f; @@ -118,13 +118,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; } @@ -156,9 +156,9 @@ void PrintCluster(bool verbose, // } } - template -void Print(bool verbose, Args&&... args) { +void Print(bool verbose, Args&&... args) +{ if (!verbose) { return; } @@ -166,12 +166,12 @@ void Print(bool verbose, Args&&... args) { (std::cout << ... << std::forward(args)) << std::endl; } - void GetClusterLocalPos(const o2::iotof::Cluster& cluster, TopologyInfo topoInfo, o2::math_utils::Point3D& localPos, o2::iotof::GeometryTGeo* iotofGeom, - o2::iotof::Segmentation* segmInfo){ + o2::iotof::Segmentation* segmInfo) +{ std::cout << "Computing cluster global position for cluster with bottom left corner at (row = " << cluster.getRow() << ", col = " << cluster.getCol() << "), chipID = " << cluster.getChipID() << std::endl; float x = 0.f; @@ -185,36 +185,35 @@ 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); - - for (int i = 0; i < chipHitsIdxs.size(); ++i) { - const auto& hit = (*evtChipHits)[chipHitsIdxs[i]]; - - 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; - } + o2::iotof::Segmentation* segmInfo) +{ + int bestHitIdx = -1; + float minDistanceSq = std::numeric_limits::max(); + o2::math_utils::Point3D clsPos; + GetClusterGlobalPos(cluster, topoInfo, clsPos, iotofGeom, segmInfo); + + for (int i = 0; i < chipHitsIdxs.size(); ++i) { + const auto& hit = (*evtChipHits)[chipHitsIdxs[i]]; + + 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; } + } - return bestHitIdx; // Returns -1 if no hit is within maxToleranceCm (true fake cluster) + return bestHitIdx; // Returns -1 if no hit is within maxToleranceCm (true fake cluster) } - struct ClusterProperties { int clsIdx = -1; int eventID = -1; @@ -228,9 +227,9 @@ struct ClusterProperties { uint8_t colSpan = 0; int size = 0; bool isPrimary = false; - int nAssocPrimaries = 0; // 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 nAssocPrimaries = 0; // 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; @@ -243,7 +242,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", @@ -295,11 +293,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 }); @@ -404,29 +407,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); } @@ -443,11 +445,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); @@ -496,11 +498,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 @@ -528,7 +534,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); @@ -592,7 +598,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); @@ -606,7 +612,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 { @@ -618,7 +625,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()); @@ -628,7 +634,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) { @@ -640,7 +646,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); } @@ -654,7 +660,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); } @@ -669,7 +675,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 ... "); @@ -694,7 +701,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) { @@ -725,11 +731,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()) { @@ -737,13 +743,13 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", } TH2F *hTrueClsSizeVsEta[2][2], *hTrueClsSizeVsPhi[2][2], *hFakeClsSizeVsEta[2][2], *hFakeClsSizeVsPhi[2][2], - *hClustersEtaPhi[2][2], *hTopoVsEta[2][2], *hClsSizeVsTopo[2][2], - *hXResVsEta[2][2], *hYResVsEta[2][2], *hZResVsEta[2][2], *hXResVsTopo[2][2], *hYResVsTopo[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], *hYResVsEta[2][2], *hZResVsEta[2][2], *hXResVsTopo[2][2], *hYResVsTopo[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], *hRmsYResVsEta[2][2], *hRmsZResVsEta[2][2], *hMeanXResVsEta[2][2], *hMeanYResVsEta[2][2], *hMeanZResVsEta[2][2], - *hRmsXResVsTopo[2][2], *hRmsYResVsTopo[2][2], *hRmsZResVsTopo[2][2], *hMeanXResVsTopo[2][2], *hMeanYResVsTopo[2][2], *hMeanZResVsTopo[2][2]; + *hRmsXResVsEta[2][2], *hRmsYResVsEta[2][2], *hRmsZResVsEta[2][2], *hMeanXResVsEta[2][2], *hMeanYResVsEta[2][2], *hMeanZResVsEta[2][2], + *hRmsXResVsTopo[2][2], *hRmsYResVsTopo[2][2], *hRmsZResVsTopo[2][2], *hMeanXResVsTopo[2][2], *hMeanYResVsTopo[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); @@ -811,8 +817,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.); } } @@ -821,7 +826,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()) { @@ -859,7 +866,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; @@ -869,7 +877,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) { @@ -925,22 +934,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); @@ -1092,14 +1102,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) { @@ -1114,13 +1124,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) { @@ -1136,14 +1146,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) { @@ -1188,7 +1198,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())); } } @@ -1202,8 +1213,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) { @@ -1265,32 +1275,30 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", int spanCol = topology.mSizeZ; uint16_t bitmask = topology.mPattern; - 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, -1.5, spanRow + 0.5, spanCol + 2, -1.5, spanCol + 0.5); - 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, -1.5, spanRow + 0.5, spanCol + 2, -1.5, spanCol + 0.5); - 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, -1.5, spanRow + 0.5, spanCol + 2, -1.5, spanCol + 0.5); - TH2F* hTopoCOGAll = new TH2F(Form("spanRow_%i_spanCol_%i_key_%i_all_COG", spanRow, spanCol, topoKey), Form("Cluster Topology %s;Row;Column", topoName.c_str()), - spanRow + 2, -1.5, spanRow + 0.5, spanCol + 2, -1.5, spanCol + 0.5); - TH2F* hTopoCOGReal = new TH2F(Form("spanRow_%i_spanCol_%i_key_%i_real_COG", spanRow, spanCol, topoKey), Form("Cluster Topology %s;Row;Column", topoName.c_str()), - spanRow + 2, -1.5, spanRow + 0.5, spanCol + 2, -1.5, spanCol + 0.5); - TH2F* hTopoCOGFake = new TH2F(Form("spanRow_%i_spanCol_%i_key_%i_fake_COG", spanRow, spanCol, topoKey), Form("Cluster Topology %s;Row;Column", topoName.c_str()), - spanRow + 2, -1.5, spanRow + 0.5, spanCol + 2, -1.5, spanCol + 0.5); + TH2F* hTopoCOGAll = new TH2F(Form("spanRow_%i_spanCol_%i_key_%i_all_COG", spanRow, spanCol, topoKey), Form("Cluster Topology %s;Row;Column", topoName.c_str()), + spanRow + 2, -1.5, spanRow + 0.5, spanCol + 2, -1.5, spanCol + 0.5); + TH2F* hTopoCOGReal = new TH2F(Form("spanRow_%i_spanCol_%i_key_%i_real_COG", spanRow, spanCol, topoKey), Form("Cluster Topology %s;Row;Column", topoName.c_str()), + spanRow + 2, -1.5, spanRow + 0.5, spanCol + 2, -1.5, spanCol + 0.5); + TH2F* hTopoCOGFake = new TH2F(Form("spanRow_%i_spanCol_%i_key_%i_fake_COG", spanRow, spanCol, topoKey), Form("Cluster Topology %s;Row;Column", topoName.c_str()), + spanRow + 2, -1.5, spanRow + 0.5, spanCol + 2, -1.5, spanCol + 0.5); int frequency = topology.mFrequency; hTopoCOGAll->Fill(topology.mOffsetXToCOG, topology.mOffsetZToCOG, frequency); 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; }); hTopoCOGAll->Fill(topology.mOffsetXToCOG, topology.mOffsetZToCOG, countFakeThisTopo); 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; }); hTopoCOGAll->Fill(topology.mOffsetXToCOG, topology.mOffsetZToCOG, countRealThisTopo); - // 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; @@ -1335,7 +1343,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/macros/CheckDigitsIOTOF.C b/Detectors/Upgrades/ALICE3/IOTOF/macros/CheckDigitsIOTOF.C index 65a921a814d8f..85dc63d997cf8 100644 --- a/Detectors/Upgrades/ALICE3/IOTOF/macros/CheckDigitsIOTOF.C +++ b/Detectors/Upgrades/ALICE3/IOTOF/macros/CheckDigitsIOTOF.C @@ -142,12 +142,13 @@ void CheckDigitsIOTOF(std::string digifile = "tf3digits.root", kineTree->SetBranchAddress("TrackRefs", &mcTracksRefsPerEvent[0]); TH1F* hGenHitsEta[2][2] = {{ - new TH1F("hGenHitsEtaPrmL0", "hGenHitsEtaPrmL0", 40, -2, 2), - new TH1F("hGenHitsEtaSecL0", "hGenHitsEtaSecL0", 40, -2, 2), - }, { - new TH1F("hGenHitsEtaPrmL1", "hGenHitsEtaPrmL1", 40, -2, 2), - new TH1F("hGenHitsEtaSecL1", "hGenHitsEtaSecL1", 40, -2, 2), - }}; + new TH1F("hGenHitsEtaPrmL0", "hGenHitsEtaPrmL0", 40, -2, 2), + new TH1F("hGenHitsEtaSecL0", "hGenHitsEtaSecL0", 40, -2, 2), + }, + { + new TH1F("hGenHitsEtaPrmL1", "hGenHitsEtaPrmL1", 40, -2, 2), + new TH1F("hGenHitsEtaSecL1", "hGenHitsEtaSecL1", 40, -2, 2), + }}; // Load all MC hit events upfront and build the hit lookup map. for (int im = 0; im < nevH; ++im) { @@ -162,7 +163,7 @@ void CheckDigitsIOTOF(std::string digifile = "tf3digits.root", uint64_t key = (uint64_t(hit.GetTrackID()) << 32) + hit.GetDetectorID(); mc2hit.emplace(key, ih); - auto &mcTrack = mcTracksPerEvent[im]->at(hit.GetTrackID()); + auto& mcTrack = mcTracksPerEvent[im]->at(hit.GetTrackID()); bool isPrimary = mcTrack.isPrimary(); int layer = gman->getIOTOFLayer(hit.GetDetectorID()); @@ -186,12 +187,13 @@ void CheckDigitsIOTOF(std::string digifile = "tf3digits.root", // LOOP on : ROFRecord array TH1F* hRecoDigitEta[2][2] = {{ - new TH1F("hRecoDigitEtaPrmL0", "hRecoDigitEtaPrmL0", 40, -2, 2), - new TH1F("hRecoDigitEtaSecL0", "hRecoDigitEtaSecL0", 40, -2, 2), - }, { - new TH1F("hRecoDigitEtaPrmL1", "hRecoDigitEtaPrmL1", 40, -2, 2), - new TH1F("hRecoDigitEtaSecL1", "hRecoDigitEtaSecL1", 40, -2, 2), - }}; + new TH1F("hRecoDigitEtaPrmL0", "hRecoDigitEtaPrmL0", 40, -2, 2), + new TH1F("hRecoDigitEtaSecL0", "hRecoDigitEtaSecL0", 40, -2, 2), + }, + { + new TH1F("hRecoDigitEtaPrmL1", "hRecoDigitEtaPrmL1", 40, -2, 2), + new TH1F("hRecoDigitEtaSecL1", "hRecoDigitEtaSecL1", 40, -2, 2), + }}; std::unordered_map> hitDigitMap; for (unsigned int iROF = 0; iROF < rofArr.size(); ++iROF) { @@ -397,14 +399,16 @@ void CheckDigitsIOTOF(std::string digifile = "tf3digits.root", const auto& hit = (*hitArray[evtID])[hitIndex]; int hitLayer = gman->getIOTOFLayer(hit.GetDetectorID()); - if (hitLayer != layer) continue; + if (hitLayer != layer) + continue; float energyLoss = hit.GetEnergyLoss(); // in GeV int charge = static_cast(energyLoss * 2.77778e+08); auto& mcTrack = mcTracksPerEvent[evtID]->at(hit.GetTrackID()); bool isPrimary = mcTrack.isPrimary(); - if ((isPrimary ? 0 : 1) != type) continue; + if ((isPrimary ? 0 : 1) != type) + continue; const auto& digitIndices = hitDigitPair.second; float totalDigitCharge = 0.0f; 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 5995515ea06a8..f5ab2b06bc38d 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 /// @@ -69,7 +69,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 @@ -81,7 +82,8 @@ struct TopologyInfo { } }; -class TopologyClassifier { +class TopologyClassifier +{ public: // Define limits for domain validation static constexpr uint8_t MaxRowSpan = 255; @@ -102,10 +104,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 973a8911f68f7..f226442478326 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 2daf6357b63b9..46375b1682e34 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"; @@ -252,19 +261,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; @@ -282,6 +290,5 @@ void TopologyClassifier::print() { } } - -} // namespace o2::iotof +} // namespace iotof } // namespace o2