64 for (
const auto& [key, groupHits] : hitGroups) {
65 std::array<std::array<std::vector<const Hit*>, 2>, 3> grouped{};
66 for (
const Hit& hit : groupHits) {
67 if (!isBigWheelStation(hit.station))
continue;
68 grouped[stationIndex(hit.station)][hit.isStrip ? 1U : 0U].emplace_back(&hit);
71 for (std::size_t stationPosition = 0U; stationPosition < grouped.size();
74 for (std::size_t projection = 0U; projection < 2U; ++projection) {
75 const bool isStrip = projection == 1U;
76 std::vector<const Hit*>& hits = grouped[stationPosition][projection];
77 if (hits.empty())
continue;
80 [](
const Hit* lhs,
const Hit* rhs) {
81 if (lhs->channel != rhs->channel) {
82 return lhs->channel < rhs->channel;
85 return lhs->gasGap < rhs->gasGap;
88 return lhs->stationEta < rhs->stationEta;
93 std::vector<const Hit*> cluster;
94 auto flushCluster = [&]() {
95 if (cluster.empty())
return;
97 std::uint32_t channelSum = 0U;
98 std::uint8_t layerMask = 0U;
100 float sinPhiSum = 0.F;
101 float cosPhiSum = 0.F;
104 for (
const Hit* hit : cluster) {
105 channelSum += hit->channel;
106 if (hit->gasGap > 0U && hit->gasGap <= 3U) {
107 layerMask |=
static_cast<std::uint8_t
>(1U << (hit->gasGap - 1U));
110 sinPhiSum += std::sin(hit->phi);
111 cosPhiSum += std::cos(hit->phi);
116 const std::uint8_t observedLayers =
static_cast<std::uint8_t
>(
117 std::popcount(
static_cast<unsigned int>(layerMask)));
118 if (observedLayers == 0U) {
123 const std::uint16_t representativeChannel =
124 static_cast<std::uint16_t
>(std::lround(
125 static_cast<double>(channelSum) /
126 static_cast<double>(cluster.size())));
127 const Hit* representativeHit =
nullptr;
128 for (
const Hit* hit : cluster) {
129 if (betterRepresentativeHit(hit, representativeHit,
130 representativeChannel)) {
131 representativeHit = hit;
134 if (representativeHit ==
nullptr) {
139 const float scale = 1.F /
static_cast<float>(cluster.size());
140 coincidences.emplace_back(
143 representativeChannel, layerMask, observedLayers,
145 std::atan2(sinPhiSum, cosPhiSum), rSum * scale, zSum * scale);
149 std::uint16_t previousChannel = 0U;
150 bool hasPreviousChannel =
false;
151 for (
const Hit* hit : hits) {
152 if (!hasPreviousChannel ||
153 std::abs(
static_cast<int>(hit->channel) -
154 static_cast<int>(previousChannel)) <= 1) {
155 cluster.emplace_back(hit);
158 cluster.emplace_back(hit);
160 previousChannel = hit->channel;
161 hasPreviousChannel =
true;
168 std::sort(coincidences.begin(), coincidences.end(),
171 if (lhs.key.tie() != rhs.key.tie()) {
172 return lhs.key.tie() < rhs.key.tie();
177 return lhs.observedLayers > rhs.observedLayers;
181 return StatusCode::SUCCESS;