82 const std::vector<CDCWireHit*>& wireHits)
const
92 auto findWireHitRange = [&](
const CDCWire * neighborWire) -> ConstVectorRange<CDCWireHit*> {
100 return ConstVectorRange<CDCWireHit*>{
101 std::equal_range(wireHits.begin(), wireHits.end(), neighborWire, LessOf<Deref>())
107 std::array<std::pair<const CDCWire*, int>, 12> wireNeighbors;
108 int nWireNeighbors = 0;
110 std::vector<CDCWireHit*> wireHitNeighbors;
111 wireHitNeighbors.reserve(12);
113 std::array<short, 12> missingPrimaryNeighbor = {0};
117 const CDCWire& wire = from->getWire();
120 for (
short oClockDirection : {5, 7, 3, 9, 1, 11}) {
121 MayBePtr<const CDCWire> neighborWire = wireTopology.
getPrimaryNeighbor(oClockDirection, wire);
122 if (neighborWire) wireNeighbors[nWireNeighbors++] = {neighborWire, oClockDirection};
125 std::sort(wireNeighbors.begin(), wireNeighbors.begin() + nWireNeighbors);
127 for (std::pair<const CDCWire*, int> wireAndOClockDirection :
128 asRange(wireNeighbors.begin(), wireNeighbors.begin() + nWireNeighbors)) {
129 const CDCWire* neighborWire = wireAndOClockDirection.first;
130 int oClockDirection = wireAndOClockDirection.second;
132 ConstVectorRange<CDCWireHit*> wireHitRange = findWireHitRange(neighborWire);
133 if (wireHitRange.
empty()) {
134 int ccwOClockDirection = oClockDirection - 1;
135 int cwOClockDirection = oClockDirection == 11 ? 0 : oClockDirection + 1;
136 ++missingPrimaryNeighbor[ccwOClockDirection];
137 ++missingPrimaryNeighbor[oClockDirection];
138 ++missingPrimaryNeighbor[cwOClockDirection];
140 wireHitNeighbors.insert(wireHitNeighbors.end(), wireHitRange.
begin(), wireHitRange.
end());
143 size_t nPrimaryWireHitNeighbors = wireHitNeighbors.size();
148 MayBePtr<const CDCWire> neighborWire = wireTopology.
getSecondaryNeighbor(oClockDirection, wire);
149 if (not neighborWire)
continue;
150 if (missingPrimaryNeighbor[oClockDirection] <
153 wireNeighbors[nWireNeighbors++] = {neighborWire, oClockDirection};
156 std::sort(wireNeighbors.begin(), wireNeighbors.begin() + nWireNeighbors);
158 for (std::pair<const CDCWire*, int> wireAndOClockDirection :
159 asRange(wireNeighbors.begin(), wireNeighbors.begin() + nWireNeighbors)) {
160 const CDCWire* neighborWire = wireAndOClockDirection.first;
161 ConstVectorRange<CDCWireHit*> wireHitRange = findWireHitRange(neighborWire);
162 wireHitNeighbors.insert(wireHitNeighbors.end(), wireHitRange.
begin(), wireHitRange.
end());
166 std::inplace_merge(wireHitNeighbors.begin(),
167 wireHitNeighbors.begin() + nPrimaryWireHitNeighbors,
168 wireHitNeighbors.end(),
169 std::less<CDCWireHit*>());
171 return wireHitNeighbors;