Skip to content

Commit f3be1ea

Browse files
MarcellocostiMarcello Di Costanzomaciaccoalibuild
authored
[TF3] Implement cluster finder for multiple digits in same chip (#15748)
* Implement cluster finder with spatial and timing constraints * Update QA macro * Before ITS topology implementation * compute bc and tdc time from hit and event time * save bc and tdc in digit * remove unused variable + remove unwanted comments * Please consider the following formatting changes * Restore IOTOF macro * Update cluster means computation * Please consider the following formatting changes * Clenup + sigma computation * Update IOTOF cluster finder * fix stepping for both passive and active pixel edges + revert change in central framework + add macro test in cmake list * remove empty lines * Fix cluster x COG computation + floating-point issue in stepping arithmetics * Please consider the following formatting changes * Fix copyright * Fix formatting --------- Co-authored-by: Marcello Di Costanzo <mdicosta@aliceml.cern.ch> Co-authored-by: maciacco <mario.ciacco@cern.ch> Co-authored-by: ALICE Action Bot <alibuild@cern.ch>
1 parent 86a1ec8 commit f3be1ea

27 files changed

Lines changed: 1623 additions & 371 deletions

Detectors/Upgrades/ALICE3/IOTOF/DataFormatsIOTOF/CMakeLists.txt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,9 @@ o2_add_library(DataFormatsIOTOF
1313
SOURCES src/Digit.cxx
1414
# SOURCES src/MCLabel.cxx
1515
SOURCES src/Cluster.cxx
16-
PUBLIC_LINK_LIBRARIES O2::DataFormatsITSMFT)
16+
PUBLIC_LINK_LIBRARIES O2::DataFormatsITSMFT
17+
O2::IOTOFBase
18+
O2::FrameworkLogger)
1719

1820
o2_target_root_dictionary(DataFormatsIOTOF
1921
HEADERS include/DataFormatsIOTOF/Digit.h

Detectors/Upgrades/ALICE3/IOTOF/DataFormatsIOTOF/include/DataFormatsIOTOF/Cluster.h

Lines changed: 163 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,28 +9,180 @@
99
// granted to it by virtue of its status as an Intergovernmental Organization
1010
// or submit itself to any jurisdiction.
1111

12+
/// \file Cluster.h
13+
/// \brief Definition of the IOTOF cluster
1214
#ifndef ALICEO2_DATAFORMATSIOTOF_CLUSTER_H
1315
#define ALICEO2_DATAFORMATSIOTOF_CLUSTER_H
1416

15-
#include <Rtypes.h>
1617
#include <cstdint>
1718
#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+
}
1872

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
20111
{
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+
}
21128

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+
}
28147

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;
29171
std::string asString() const;
30172

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);
32181
};
33182

34-
} // namespace o2::iotof
183+
} // namespace iotof
184+
} // namespace o2
185+
186+
std::ostream& operator<<(std::ostream& stream, const o2::iotof::Cluster& cl);
35187

36-
#endif
188+
#endif /* ALICEO2_DATAFORMATSIOTOF_CLUSTER_H */

Detectors/Upgrades/ALICE3/IOTOF/DataFormatsIOTOF/src/Cluster.cxx

Lines changed: 51 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,19 +9,64 @@
99
// granted to it by virtue of its status as an Intergovernmental Organization
1010
// or submit itself to any jurisdiction.
1111

12+
/// \file Cluster.cxx
13+
/// \brief Implementation of the IOTOF cluster
14+
1215
#include "DataFormatsIOTOF/Cluster.h"
13-
#include <sstream>
16+
#include "Framework/Logger.h"
17+
#include <cassert>
18+
#include <iostream>
19+
#include <format>
1420

21+
// Root ClassImp macros for serialization metadata
22+
ClassImp(o2::iotof::ClusterInfo);
1523
ClassImp(o2::iotof::Cluster);
1624

17-
namespace o2::iotof
25+
namespace o2
26+
{
27+
namespace iotof
1828
{
1929

2030
std::string Cluster::asString() const
2131
{
22-
std::ostringstream stream;
23-
stream << "chip=" << chipID << " row=" << row << " col=" << col << " size=" << size;
24-
return stream.str();
32+
LOG(debug) << "[Cluster::asString] Converting Cluster to string";
33+
return std::format(
34+
"chip: {:5d} | row: {:3d} col: {:3d} | span: {:2d}x{:2d} | pattern: {:5d} topology: {:4d}",
35+
getChipID(),
36+
getRow(),
37+
getCol(),
38+
getRowSpan(),
39+
getColSpan(),
40+
getPattern(),
41+
getTopology());
42+
}
43+
44+
//______________________________________________________________________________
45+
void Cluster::print() const
46+
{
47+
std::cout << *this << "\n";
48+
}
49+
50+
//______________________________________________________________________________
51+
void Cluster::sanityCheck()
52+
{
53+
LOG(debug) << "[Cluster::sanityCheck] Performing sanity check on Cluster fields";
54+
55+
// Ensure extracted values fit within allowed bit masks
56+
assert(getRow() <= ClusterInfo::MaskRow);
57+
assert(getCol() <= ClusterInfo::MaskCol);
58+
assert(getRowSpan() <= ClusterInfo::MaskRowSpan);
59+
assert(getColSpan() <= ClusterInfo::MaskColSpan);
60+
assert(getPattern() <= ClusterInfo::MaskPattern);
61+
assert(getTopology() <= ClusterInfo::MaskTopology);
2562
}
2663

27-
} // namespace o2::iotof
64+
} // namespace iotof
65+
} // namespace o2
66+
67+
// Stream operator implementation
68+
std::ostream& operator<<(std::ostream& stream, const o2::iotof::Cluster& cl)
69+
{
70+
stream << cl.asString();
71+
return stream;
72+
}

Detectors/Upgrades/ALICE3/IOTOF/DataFormatsIOTOF/src/DataFormatsIOTOFLinkDef.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#pragma link C++ class o2::iotof::Digit + ;
1919
#pragma link C++ class std::vector < o2::iotof::Digit> + ;
2020

21+
#pragma link C++ class o2::iotof::ClusterInfo + ;
2122
#pragma link C++ class o2::iotof::Cluster + ;
2223
#pragma link C++ class std::vector < o2::iotof::Cluster> + ;
2324

Detectors/Upgrades/ALICE3/IOTOF/base/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@
1111

1212
o2_add_library(IOTOFBase
1313
SOURCES src/GeometryTGeo.cxx
14+
src/Segmentation.cxx
1415
src/IOTOFBaseParam.cxx
1516
PUBLIC_LINK_LIBRARIES O2::DetectorsBase
1617
O2::MathUtils)
1718

1819
o2_target_root_dictionary(IOTOFBase
1920
HEADERS include/IOTOFBase/GeometryTGeo.h
21+
include/IOTOFBase/Segmentation.h
2022
include/IOTOFBase/IOTOFBaseParam.h)

0 commit comments

Comments
 (0)