83 const std::vector<CDCWireHit*>& wireHits)
const
85 assert(std::is_sorted(wireHits.begin(), wireHits.end(), LessOf<Deref>()) &&
86 "Expected wire hits to be sorted");
94 auto findWireHitRange = [&](
const CDCWire * neighborWire) -> ConstVectorRange<CDCWireHit*> {
102 return ConstVectorRange<CDCWireHit*>{
103 std::equal_range(wireHits.begin(), wireHits.end(), neighborWire, LessOf<Deref>())
109 std::array<std::pair<const CDCWire*, int>, 12> wireNeighbors;
110 int nWireNeighbors = 0;
112 std::vector<CDCWireHit*> wireHitNeighbors;
113 wireHitNeighbors.reserve(12);
115 std::array<short, 12> missingPrimaryNeighbor = {0};
119 const CDCWire& wire = from->getWire();
122 for (
short oClockDirection : {5, 7, 3, 9, 1, 11}) {
123 MayBePtr<const CDCWire> neighborWire = wireTopology.
getPrimaryNeighbor(oClockDirection, wire);
124 if (neighborWire) wireNeighbors[nWireNeighbors++] = {neighborWire, oClockDirection};
127 std::sort(wireNeighbors.begin(), wireNeighbors.begin() + nWireNeighbors);
129 for (std::pair<const CDCWire*, int> wireAndOClockDirection :
130 asRange(wireNeighbors.begin(), wireNeighbors.begin() + nWireNeighbors)) {
131 const CDCWire* neighborWire = wireAndOClockDirection.first;
133 int oClockDirection = wireAndOClockDirection.second;
135 ConstVectorRange<CDCWireHit*> wireHitRange = findWireHitRange(neighborWire);
136 if (wireHitRange.
empty()) {
137 int ccwOClockDirection = oClockDirection - 1;
138 int cwOClockDirection = oClockDirection == 11 ? 0 : oClockDirection + 1;
139 ++missingPrimaryNeighbor[ccwOClockDirection];
140 ++missingPrimaryNeighbor[oClockDirection];
141 ++missingPrimaryNeighbor[cwOClockDirection];
143 wireHitNeighbors.insert(wireHitNeighbors.end(), wireHitRange.
begin(), wireHitRange.
end());
146 size_t nPrimaryWireHitNeighbors = wireHitNeighbors.size();
151 MayBePtr<const CDCWire> neighborWire = wireTopology.
getSecondaryNeighbor(oClockDirection, wire);
152 if (not neighborWire)
continue;
153 if (missingPrimaryNeighbor[oClockDirection] <
156 wireNeighbors[nWireNeighbors++] = {neighborWire, oClockDirection};
159 std::sort(wireNeighbors.begin(), wireNeighbors.begin() + nWireNeighbors);
161 for (std::pair<const CDCWire*, int> wireAndOClockDirection :
162 asRange(wireNeighbors.begin(), wireNeighbors.begin() + nWireNeighbors)) {
163 const CDCWire* neighborWire = wireAndOClockDirection.first;
164 ConstVectorRange<CDCWireHit*> wireHitRange = findWireHitRange(neighborWire);
165 wireHitNeighbors.insert(wireHitNeighbors.end(), wireHitRange.
begin(), wireHitRange.
end());
169 std::inplace_merge(wireHitNeighbors.begin(),
170 wireHitNeighbors.begin() + nPrimaryWireHitNeighbors,
171 wireHitNeighbors.end(),
172 std::less<CDCWireHit*>());
174 return wireHitNeighbors;