|
9 | 9 | // granted to it by virtue of its status as an Intergovernmental Organization |
10 | 10 | // or submit itself to any jurisdiction. |
11 | 11 |
|
| 12 | +/// \file Cluster.h |
| 13 | +/// \brief Definition of the IOTOF cluster |
12 | 14 | #ifndef ALICEO2_DATAFORMATSIOTOF_CLUSTER_H |
13 | 15 | #define ALICEO2_DATAFORMATSIOTOF_CLUSTER_H |
14 | 16 |
|
15 | | -#include <Rtypes.h> |
16 | 17 | #include <cstdint> |
17 | 18 | #include <string> |
| 19 | +#include <iosfwd> |
| 20 | +#include <Rtypes.h> |
| 21 | + |
| 22 | +#include "Framework/Logger.h" |
| 23 | + |
| 24 | +namespace o2 |
| 25 | +{ |
| 26 | +namespace iotof |
| 27 | +{ |
| 28 | + |
| 29 | +/// Compact encoding for ALICE3 IOTOF cluster parameters inside a single 64-bit word. |
| 30 | +struct ClusterInfo { |
| 31 | + // Bit widths (Total: 52 bits out of 64) |
| 32 | + static constexpr int NBitsRow = 9; |
| 33 | + static constexpr int NBitsCol = 8; |
| 34 | + static constexpr int NBitsRowSpan = 4; |
| 35 | + static constexpr int NBitsColSpan = 4; |
| 36 | + static constexpr int NBitsPattern = 16; |
| 37 | + static constexpr int NBitsTopology = 11; |
| 38 | + |
| 39 | + // Bit offsets (ordered logically from LSB to MSB) |
| 40 | + static constexpr int ShiftRow = 0; |
| 41 | + static constexpr int ShiftCol = ShiftRow + NBitsRow; // 9 |
| 42 | + static constexpr int ShiftRowSpan = ShiftCol + NBitsCol; // 17 |
| 43 | + static constexpr int ShiftColSpan = ShiftRowSpan + NBitsRowSpan; // 21 |
| 44 | + static constexpr int ShiftPattern = ShiftColSpan + NBitsColSpan; // 25 |
| 45 | + static constexpr int ShiftTopology = ShiftPattern + NBitsPattern; // 41 |
| 46 | + |
| 47 | + // Bit masks |
| 48 | + static constexpr uint64_t MaskRow = (1ULL << NBitsRow) - 1; |
| 49 | + static constexpr uint64_t MaskCol = (1ULL << NBitsCol) - 1; |
| 50 | + static constexpr uint64_t MaskRowSpan = (1ULL << NBitsRowSpan) - 1; |
| 51 | + static constexpr uint64_t MaskColSpan = (1ULL << NBitsColSpan) - 1; |
| 52 | + static constexpr uint64_t MaskPattern = (1ULL << NBitsPattern) - 1; |
| 53 | + static constexpr uint64_t MaskTopology = (1ULL << NBitsTopology) - 1; |
| 54 | + |
| 55 | + uint64_t data{0}; |
| 56 | + |
| 57 | + // Constructors |
| 58 | + constexpr ClusterInfo() = default; |
| 59 | + constexpr ClusterInfo(uint64_t d) : data(d) {} |
| 60 | + |
| 61 | + // Static packer |
| 62 | + static constexpr uint64_t pack(uint32_t row, uint32_t col, uint8_t rowSpan, |
| 63 | + uint8_t colSpan, uint32_t pattern, uint32_t topology) |
| 64 | + { |
| 65 | + return ((static_cast<uint64_t>(row) & MaskRow) << ShiftRow) | |
| 66 | + ((static_cast<uint64_t>(col) & MaskCol) << ShiftCol) | |
| 67 | + ((static_cast<uint64_t>(rowSpan) & MaskRowSpan) << ShiftRowSpan) | |
| 68 | + ((static_cast<uint64_t>(colSpan) & MaskColSpan) << ShiftColSpan) | |
| 69 | + ((static_cast<uint64_t>(pattern) & MaskPattern) << ShiftPattern) | |
| 70 | + ((static_cast<uint64_t>(topology) & MaskTopology) << ShiftTopology); |
| 71 | + } |
18 | 72 |
|
19 | | -namespace o2::iotof |
| 73 | + // Getters |
| 74 | + constexpr uint32_t getRow() const { return (data >> ShiftRow) & MaskRow; } |
| 75 | + constexpr uint32_t getCol() const { return (data >> ShiftCol) & MaskCol; } |
| 76 | + constexpr uint8_t getRowSpan() const { return (data >> ShiftRowSpan) & MaskRowSpan; } |
| 77 | + constexpr uint8_t getColSpan() const { return (data >> ShiftColSpan) & MaskColSpan; } |
| 78 | + constexpr uint32_t getPattern() const { return (data >> ShiftPattern) & MaskPattern; } |
| 79 | + constexpr uint32_t getTopology() const { return (data >> ShiftTopology) & MaskTopology; } |
| 80 | + |
| 81 | + // Setters |
| 82 | + constexpr void setRow(uint32_t r) |
| 83 | + { |
| 84 | + data = (data & ~(MaskRow << ShiftRow)) | ((static_cast<uint64_t>(r) & MaskRow) << ShiftRow); |
| 85 | + } |
| 86 | + constexpr void setCol(uint32_t c) |
| 87 | + { |
| 88 | + data = (data & ~(MaskCol << ShiftCol)) | ((static_cast<uint64_t>(c) & MaskCol) << ShiftCol); |
| 89 | + } |
| 90 | + constexpr void setRowSpan(uint8_t rs) |
| 91 | + { |
| 92 | + data = (data & ~(MaskRowSpan << ShiftRowSpan)) | ((static_cast<uint64_t>(rs) & MaskRowSpan) << ShiftRowSpan); |
| 93 | + } |
| 94 | + constexpr void setColSpan(uint8_t cs) |
| 95 | + { |
| 96 | + data = (data & ~(MaskColSpan << ShiftColSpan)) | ((static_cast<uint64_t>(cs) & MaskColSpan) << ShiftColSpan); |
| 97 | + } |
| 98 | + constexpr void setPattern(uint32_t p) |
| 99 | + { |
| 100 | + data = (data & ~(MaskPattern << ShiftPattern)) | ((static_cast<uint64_t>(p) & MaskPattern) << ShiftPattern); |
| 101 | + } |
| 102 | + constexpr void setTopology(uint32_t t) |
| 103 | + { |
| 104 | + data = (data & ~(MaskTopology << ShiftTopology)) | ((static_cast<uint64_t>(t) & MaskTopology) << ShiftTopology); |
| 105 | + } |
| 106 | + |
| 107 | + ClassDefNV(ClusterInfo, 1); |
| 108 | +}; |
| 109 | + |
| 110 | +class Cluster |
20 | 111 | { |
| 112 | + public: |
| 113 | + static constexpr uint16_t InvalidPatternID = static_cast<uint16_t>(ClusterInfo::MaskPattern); |
| 114 | + |
| 115 | + Cluster() = default; |
| 116 | + Cluster(UShort_t row, UShort_t col, UShort_t rowSpan, UShort_t colSpan, UShort_t patt, UShort_t topo, UShort_t chipID = 0, time_t time = 0.0f) |
| 117 | + : mChipID(chipID), mTime(time) |
| 118 | + { |
| 119 | + mClusterInfo.data = ClusterInfo::pack(row, col, rowSpan, colSpan, patt, topo); |
| 120 | + } |
| 121 | + |
| 122 | + void set(UShort_t row, UShort_t col, UShort_t rowSpan, UShort_t colSpan, UShort_t patt, UShort_t topo, UShort_t chipID, time_t time) |
| 123 | + { |
| 124 | + mClusterInfo.data = ClusterInfo::pack(row, col, rowSpan, colSpan, patt, topo); |
| 125 | + mChipID = chipID; |
| 126 | + mTime = time; |
| 127 | + } |
21 | 128 |
|
22 | | -struct Cluster { |
23 | | - uint16_t chipID = 0; |
24 | | - uint16_t row = 0; |
25 | | - uint16_t col = 0; |
26 | | - uint16_t size = 1; |
27 | | - double time = 0.0; |
| 129 | + // Unpack Getters |
| 130 | + uint32_t getRow() const { return mClusterInfo.getRow(); } |
| 131 | + uint32_t getCol() const { return mClusterInfo.getCol(); } |
| 132 | + uint8_t getRowSpan() const { return mClusterInfo.getRowSpan(); } |
| 133 | + uint8_t getColSpan() const { return mClusterInfo.getColSpan(); } |
| 134 | + uint32_t getPattern() const { return mClusterInfo.getPattern(); } |
| 135 | + uint32_t getTopology() const { return mClusterInfo.getTopology(); } |
| 136 | + int getSize() const |
| 137 | + { |
| 138 | + // Count the number of set bits in the pattern to determine the size of the cluster |
| 139 | + uint32_t pattern = getPattern(); |
| 140 | + int size = 0; |
| 141 | + while (pattern) { |
| 142 | + size += pattern & 1; |
| 143 | + pattern >>= 1; |
| 144 | + } |
| 145 | + return size; |
| 146 | + } |
28 | 147 |
|
| 148 | + // BaseCluster / Interface Compatibility Getters |
| 149 | + uint32_t getChipID() const { return mChipID; } |
| 150 | + uint32_t getSensorID() const { return mChipID; } |
| 151 | + time_t getTime() const { return mTime; } |
| 152 | + uint64_t getPackedData() const { return mClusterInfo.data; } |
| 153 | + |
| 154 | + // Setters |
| 155 | + void setRow(UShort_t r) { mClusterInfo.setRow(r); } |
| 156 | + void setCol(UShort_t c) { mClusterInfo.setCol(c); } |
| 157 | + void setRowSpan(UShort_t rs) { mClusterInfo.setRowSpan(rs); } |
| 158 | + void setColSpan(UShort_t cs) { mClusterInfo.setColSpan(cs); } |
| 159 | + void setPatternID(UShort_t p) { mClusterInfo.setPattern(p); } |
| 160 | + void setTopology(UShort_t t) { mClusterInfo.setTopology(t); } |
| 161 | + void setChipID(UShort_t c) { mChipID = c; } |
| 162 | + void setTime(time_t t) { mTime = t; } |
| 163 | + |
| 164 | + // Operators & Debugging |
| 165 | + bool operator==(const Cluster& cl) const |
| 166 | + { |
| 167 | + return mClusterInfo.data == cl.mClusterInfo.data && mChipID == cl.mChipID && mTime == cl.mTime; |
| 168 | + } |
| 169 | + |
| 170 | + void print() const; |
29 | 171 | std::string asString() const; |
30 | 172 |
|
31 | | - ClassDefNV(Cluster, 1); |
| 173 | + private: |
| 174 | + ClusterInfo mClusterInfo{}; ///< 64-bit packed structure containing geometry/topology |
| 175 | + UShort_t mChipID{0}; ///< Chip / Sensor ID |
| 176 | + float mTime{0.0f}; ///< Hit timing information |
| 177 | + |
| 178 | + void sanityCheck(); |
| 179 | + |
| 180 | + ClassDefNV(Cluster, 2); |
32 | 181 | }; |
33 | 182 |
|
34 | | -} // namespace o2::iotof |
| 183 | +} // namespace iotof |
| 184 | +} // namespace o2 |
| 185 | + |
| 186 | +std::ostream& operator<<(std::ostream& stream, const o2::iotof::Cluster& cl); |
35 | 187 |
|
36 | | -#endif |
| 188 | +#endif /* ALICEO2_DATAFORMATSIOTOF_CLUSTER_H */ |
0 commit comments