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 cd8d7e31ad227..be75df8afe301 100644 --- a/Detectors/Upgrades/ALICE3/IOTOF/macros/CheckClustersIOTOF.C +++ b/Detectors/Upgrades/ALICE3/IOTOF/macros/CheckClustersIOTOF.C @@ -47,8 +47,8 @@ using namespace o2::base; using namespace o2::iotof; -using o2::iotof::Digit; using o2::iotof::Cluster; +using o2::iotof::Digit; struct ClusterProperties { int clsIdx = -1; @@ -73,7 +73,7 @@ struct ClusterProperties { }; struct HitData { - int hitIdx = -1; // In the hitsPerEvent[iEvt] array + int hitIdx = -1; // In the hitsPerEvent[iEvt] array std::vector assocClsIdxs{}; std::vector assocDigitIdxs{}; }; @@ -82,7 +82,8 @@ struct TrackData { std::unordered_map> hitsByDetector; }; -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(); @@ -90,9 +91,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(); @@ -104,32 +104,32 @@ 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 GetDigitGlobalPos(const Digit& digit, o2::math_utils::Point3D& globalPos, o2::iotof::GeometryTGeo* geom, - o2::iotof::Segmentation* segm) { - const int chipID = digit.getChipIndex(); - const int layer = geom->getIOTOFLayer(chipID); + o2::iotof::Segmentation* segm) +{ + const int chipID = digit.getChipIndex(); + const int layer = geom->getIOTOFLayer(chipID); - float x = 0.f; - float z = 0.f; - if (layer >= 0) - segm->detectorToLocal(digit.getRow(), digit.getColumn(), x, z, layer); + float x = 0.f; + float z = 0.f; + if (layer >= 0) + segm->detectorToLocal(digit.getRow(), digit.getColumn(), x, z, layer); - globalPos = geom->getMatrixL2G(chipID)(o2::math_utils::Point3D{x, 0.f, z}); + globalPos = geom->getMatrixL2G(chipID)(o2::math_utils::Point3D{x, 0.f, z}); } - -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; } @@ -138,8 +138,8 @@ void PrintHit(bool verbose, o2::itsmft::Hit hit, o2::iotof::GeometryTGeo* iotofG std::cout << "Hit: detectorID = " << hit.GetDetectorID() << ", layer = " << layer << ", stave = " << stave << ", subStave = " << subStave << ", module = " << module << ", chip = " << chip << ", trackID = " << hit.GetTrackID() << ", X = " << hit.GetX() << ", Y = " << hit.GetY() << ", Z = " << hit.GetZ() << ", time = " << hit.GetTime() << std::endl; } - -void PrintDigit(bool verbose, const o2::iotof::Digit& digit, auto& labels, o2::iotof::GeometryTGeo* iotofGeom, o2::iotof::Segmentation* segmInfo) { +void PrintDigit(bool verbose, const o2::iotof::Digit& digit, auto& labels, o2::iotof::GeometryTGeo* iotofGeom, o2::iotof::Segmentation* segmInfo) +{ if (!verbose) { return; } @@ -165,16 +165,16 @@ void PrintDigit(bool verbose, const o2::iotof::Digit& digit, auto& labels, o2::i << digit.getChipIndex() << ", layer = " << layer << ", stave = " << stave << ", subStave = " << subStave << ", module = " << module << ", chip = " << chip << ", row = " << digit.getRow() << ", col = " << digit.getColumn() << ", charge = " << digit.getCharge() - << ", time = " << digit.getTime() << ", global position = (" << digitPos.X() << ", " << digitPos.Y() + << ", time = " << digit.getTime() << ", global position = (" << digitPos.X() << ", " << digitPos.Y() << ", " << digitPos.Z() << ")" << std::endl; } - void PrintCluster(bool verbose, const o2::iotof::Cluster& cluster, auto clsLabel, o2::iotof::GeometryTGeo* iotofGeom, - o2::iotof::Segmentation* segmInfo) { + o2::iotof::Segmentation* segmInfo) +{ if (!verbose) { return; } @@ -194,9 +194,9 @@ void PrintCluster(bool verbose, } } - template -void Print(bool verbose, Args&&... args) { +void Print(bool verbose, Args&&... args) +{ if (!verbose) { return; } @@ -204,12 +204,12 @@ void Print(bool verbose, Args&&... args) { (std::cout << ... << std::forward(args)) << 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; @@ -220,37 +220,36 @@ void GetClusterGlobalPos(const o2::iotof::Cluster& cluster, globalPos = iotofGeom->getMatrixL2G(cluster.getChipID())(o2::math_utils::Point3D{x, 0.f, z}); } - int FindBestMatchingHit(const o2::iotof::Cluster& cluster, - TopologyInfo topoInfo, + TopologyInfo topoInfo, std::vector& chipHitsIdxs, std::vector* evtChipHits, const std::vector* digitsArray, 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].hitIdx]; - - 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].hitIdx]; + + 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) } - void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", std::string hitfile = "o2sim_HitsTF3.root", std::string digiFilePath = "tf3digits.root", @@ -362,18 +361,25 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", nHits++; // Fill histograms - int hitLayer = iotofGeom->getIOTOFLayer(hit.GetDetectorID()); + int hitLayer = iotofGeom->getIOTOFLayer(hit.GetDetectorID()); auto& mcTrack = (*mcTracksPerEvent[iEvt])[trackID]; bool isPrimary = mcTrack.isPrimary(); - if (isPrimary) nHitsFromPrimaryTracks++; - else nHitsFromSecondaryTracks++; - float genEta = mcTrack.GetEta(); - float genPhi = mcTrack.GetPhi(); - - if (hitLayer == 0 && isPrimary) { hEtaPhiHitsPrmTrkLayer0->Fill(genPhi, genEta); } - else if (hitLayer == 0 && !isPrimary) { hEtaPhiHitsSecTrkLayer0->Fill(genPhi, genEta); } - else if (hitLayer == 1 && isPrimary) { hEtaPhiHitsPrmTrkLayer1->Fill(genPhi, genEta); } - else { hEtaPhiHitsSecTrkLayer1->Fill(genPhi, genEta); } + if (isPrimary) + nHitsFromPrimaryTracks++; + else + nHitsFromSecondaryTracks++; + float genEta = mcTrack.GetEta(); + float genPhi = mcTrack.GetPhi(); + + if (hitLayer == 0 && isPrimary) { + hEtaPhiHitsPrmTrkLayer0->Fill(genPhi, genEta); + } else if (hitLayer == 0 && !isPrimary) { + hEtaPhiHitsSecTrkLayer0->Fill(genPhi, genEta); + } else if (hitLayer == 1 && isPrimary) { + hEtaPhiHitsPrmTrkLayer1->Fill(genPhi, genEta); + } else { + hEtaPhiHitsSecTrkLayer1->Fill(genPhi, genEta); + } // PrintHit(verbose, hit, iotofGeom); } @@ -403,7 +409,7 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", // PrintDigit(verbose, digit, digitLabels, iotofGeom, segmInfo); auto& hitList = allEvtsTrackData[eventID][trackID].hitsByDetector[digit.getChipIndex()]; for (auto& hit : hitList) { - hit.assocDigitIdxs.push_back(iDigit); + hit.assocDigitIdxs.push_back(iDigit); } } @@ -431,7 +437,7 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", // PrintCluster(verbose, cls, clsLabels, iotofGeom, segmInfo); auto& hitList = allEvtsTrackData[eventID][trackID].hitsByDetector[cls.getChipID()]; for (auto& hit : hitList) { - hit.assocClsIdxs.push_back(iCls); + hit.assocClsIdxs.push_back(iCls); } } @@ -443,13 +449,13 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", Print(verbose, "-----------\n", "Chip ", chipID, ": ", hitsInfos.size(), " hits"); for (const auto& hitInfo : hitsInfos) { Print(verbose, "\nHit ", hitInfo.hitIdx, ": ", hitInfo.assocDigitIdxs.size(), " digits, ", hitInfo.assocClsIdxs.size(), " clusters"); - for (int iDigit=0; iDigitgetLabels(hitInfo.assocClsIdxs[iCls]); PrintCluster(verbose, cls, clsLabels, iotofGeom, segmInfo); @@ -471,7 +477,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; // Create vectors of digits with same chip index, cluster candidates TH2F* hCountHitMatchingType = new TH2F("hCountHitMatchingType", "hCountHitMatchingType;Hit matching type;#it{p}_{T}", 4, -0.5, 3.5, 50, 0, 10); @@ -523,7 +530,7 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", clsProps.topology = static_cast(cluster.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); @@ -644,24 +651,24 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", Print(true, "----> hCountFakeClusters filled"); // Topology names const std::array topologyNames = { - "kSingleDigit", "kLineOnRow", "kLineOnCol", "kDiagonal", "kSquare", - "kUpperTriangleLeft", "kUpperTriangleRight", "kLowerTriangleLeft", - "kLowerTriangleRight", "kSnake", "kSnakeRot90", "kSnakeRefl", - "kSnakeRot90Refl", "kHuge", "kOther"}; + "kSingleDigit", "kLineOnRow", "kLineOnCol", "kDiagonal", "kSquare", + "kUpperTriangleLeft", "kUpperTriangleRight", "kLowerTriangleLeft", + "kLowerTriangleRight", "kSnake", "kSnakeRot90", "kSnakeRefl", + "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()) { hTopoSummaryDictionary->Fill(topology.mTopology, topology.mFrequency); } - TH2F *hTrueClsSizeVsEta[2][2], *hTrueClsSizeVsPhi[2][2], *hFakeClsSizeVsEta[2][2], *hFakeClsSizeVsPhi[2][2], - *hClustersEtaPhi[2][2], *hTopoVsEta[2][2], *hClsSizeVsTopo[2][2], *hXRes[2][2], *hYRes[2][2], *hZRes[2][2], - *hTrackHitsXY[2][2], *hTrackDoubleHitsXY[2][2], *hTrackDoubleHitsPhiPt[2][2], *hTopoVsEtaPt[2][2][kNTopologies]; + TH2F *hTrueClsSizeVsEta[2][2], *hTrueClsSizeVsPhi[2][2], *hFakeClsSizeVsEta[2][2], *hFakeClsSizeVsPhi[2][2], + *hClustersEtaPhi[2][2], *hTopoVsEta[2][2], *hClsSizeVsTopo[2][2], *hXRes[2][2], *hYRes[2][2], *hZRes[2][2], + *hTrackHitsXY[2][2], *hTrackDoubleHitsXY[2][2], *hTrackDoubleHitsPhiPt[2][2], *hTopoVsEtaPt[2][2][kNTopologies]; TH1F *hNClustersFromHit[2][2], *hMeanTrueClsSizeVsEta[2][2], *hMeanTrueClsSizeVsPhi[2][2], *hMeanFakeClsSizeVsEta[2][2], - *hMeanFakeClsSizeVsPhi[2][2], *hRmsXRes[2][2], *hRmsYRes[2][2], *hRmsZRes[2][2], *hMeanXRes[2][2], *hMeanYRes[2][2], - *hMeanZRes[2][2]; + *hMeanFakeClsSizeVsPhi[2][2], *hRmsXRes[2][2], *hRmsYRes[2][2], *hRmsZRes[2][2], *hMeanXRes[2][2], *hMeanYRes[2][2], + *hMeanZRes[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); @@ -715,24 +722,24 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", // Loop over clusters Print(true, "----> Looping over clusters and filling histograms"); for (const auto& cls : clustersProperties) { - + const int layer = cls.layer; - const int topo = static_cast(cls.topology); - - const int chipID = cls.chipID; - const int eventID = cls.eventID; - const int trackID = cls.trackID; + const int topo = static_cast(cls.topology); + + 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); - + hClsSizeVsTopo[layer][type]->Fill(topo, size); hTopoSummaryTotal->Fill(topo); @@ -861,12 +868,11 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", return true; } // Reject adjacent chips with same stave, subStave, module but different chip index - if (layer == layerA && stave == staveA && subStave == subStaveA && module == moduleA &&std::abs(chip - chipA) <= 1) { + if (layer == layerA && stave == staveA && subStave == subStaveA && module == moduleA && std::abs(chip - chipA) <= 1) { return true; } return false; - } - ); + }); // Keep chip ONLY IF it is not an immediate neighbor to an existing one if (!isNeighborToExisting) { @@ -957,7 +963,7 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", TH2F* hEfficiency = static_cast(hClustersEtaPhi[layer][type]->Clone(Form("hClusterEfficiencyVsEtaPhi%sTrkLayer%d", trackName[type], layer))); TH2F* hHits = layer == 0 ? (type == 0 ? hEtaPhiHitsPrmTrkLayer0 : hEtaPhiHitsSecTrkLayer0) - : (type == 0 ? hEtaPhiHitsPrmTrkLayer1 : hEtaPhiHitsSecTrkLayer1); + : (type == 0 ? hEtaPhiHitsPrmTrkLayer1 : hEtaPhiHitsSecTrkLayer1); hEfficiency->Divide(hHits); hEfficiency->Write("hClsEfficiency"); delete hEfficiency; @@ -986,7 +992,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())); } } @@ -1000,8 +1007,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) { @@ -1041,7 +1047,6 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", } } - // Check digit efficiency across pixel by print the local coordinates // of hits without any cluster and digit associated to them Print(true, "----> Checking digit efficiency across pixel"); @@ -1087,7 +1092,6 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", outFile->Close(); delete outFile; - // // Print all properties of fake clusters // for (const auto& cluster : clusters) { // if (cluster.isFakeDiffHits || cluster.isFakeDiffTrks || cluster.isFakeDiffEvts) { @@ -1095,5 +1099,4 @@ void CheckClustersIOTOF(std::string kinefile = "o2sim_Kine.root", // PrintCluster(true, cluster, digitsArray, digitsLabels, hitsPerEvent, iotofGeom, segmInfo); // } // } - } 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 4d3c0162b9982..1a6cfa3c18a42 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 /// @@ -70,7 +70,8 @@ struct TopologyInfo { uint16_t mPattern; ///< Bitmask of fired pixels }; -class TopologyClassifier { +class TopologyClassifier +{ public: // Define limits for domain validation static constexpr uint8_t MaxRowSpan = 255; @@ -91,10 +92,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 7f1c93672bcac..68eb370bfc030 100644 --- a/Detectors/Upgrades/ALICE3/IOTOF/reconstruction/src/Clusterer.cxx +++ b/Detectors/Upgrades/ALICE3/IOTOF/reconstruction/src/Clusterer.cxx @@ -193,10 +193,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(); @@ -211,7 +211,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; @@ -307,10 +307,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); @@ -328,9 +328,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); } } @@ -372,5 +372,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 f20287501ea3a..31c86b17f293c 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; @@ -286,6 +294,5 @@ void TopologyClassifier::print() { } } - -} // namespace o2::iotof +} // namespace iotof } // namespace o2