Main algorithm applying the cluster refinement.
55{
57
59 auto wireHitsByLayer =
60 adjacent_groupby(inputWireHits.begin(), inputWireHits.end(), [](const CDCWireHit & wireHit) {
61 return wireHit.getWireID().getILayer();
62 });
63
64 for (const auto& wireHitsInLayer : wireHitsByLayer) {
65 const CDCWireLayer& wireLayer = wireHitsInLayer.front().getWire().getWireLayer();
66 const int nWires = wireLayer.
size();
67
68 auto sameWireHitChain = [](const CDCWireHit & lhs, const CDCWireHit & rhs) {
70 };
71
72 auto wireHitChains =
73 unique_ranges(wireHitsInLayer.begin(), wireHitsInLayer.end(), sameWireHitChain);
74
75 size_t nWireHits = 0;
76 for (const VectorRange<CDCWireHit>& wireHitChain : wireHitChains) {
77 nWireHits += wireHitChain.size();
78 }
79 assert(nWireHits == wireHitsInLayer.size());
80
81
82 VectorRange<CDCWireHit> frontWrapChain(wireHitsInLayer.begin(), wireHitsInLayer.begin());
83 VectorRange<CDCWireHit> backWrapChain(wireHitsInLayer.end(), wireHitsInLayer.end());
84 if (wireHitChains.
size() > 1) {
85 if (wireHitChains.
front().front().getWire().isPrimaryNeighborWith(
86 wireHitChains.
back().back().getWire())) {
87
88
89 int wrapAroundChainSize = wireHitChains.
front().size() + wireHitChains.
back().size();
90 if (wrapAroundChainSize >= 5) {
91
92
93 frontWrapChain = wireHitChains.
front();
94 frontWrapChain.first = frontWrapChain.end() - wrapAroundChainSize;
95
96 backWrapChain = wireHitChains.
back();
97 backWrapChain.second = backWrapChain.begin() + wrapAroundChainSize;
98
99 wireHitChains.erase(wireHitChains.
begin());
100 wireHitChains.pop_back();
101 }
102 }
103 }
104
105 auto itLastChain = std::remove_if(wireHitChains.
begin(), wireHitChains.
end(), Size() < 5u);
106 wireHitChains.erase(itLastChain, wireHitChains.
end());
107 if (wireHitChains.
empty())
continue;
108
109 auto connectWireHitChains = [this, nWires](const VectorRange<CDCWireHit>& lhs,
110 const VectorRange<CDCWireHit>& rhs) {
111 int iWireDelta = rhs.front().getWireID().getIWire() - lhs.
back().getWireID().getIWire();
112 if (iWireDelta < 0) iWireDelta += nWires;
113 if (iWireDelta <
static_cast<int>(lhs.
size() + rhs.size())) {
116 }
117 return false;
118 };
119
120 std::ignore = std::adjacent_find(wireHitChains.
begin(), wireHitChains.
end(), connectWireHitChains);
121
122 if (not frontWrapChain.empty()) {
123 connectWireHitChains(frontWrapChain, wireHitChains.
front());
124 }
125 if (not backWrapChain.empty()) {
126 connectWireHitChains(wireHitChains.
back(), backWrapChain);
127 }
128 if (backWrapChain.empty() and frontWrapChain.empty()) {
129 connectWireHitChains(wireHitChains.
back(), wireHitChains.
front());
130 }
131 }
132 }
133
135 const std::vector<CDCWireHit*> wireHitPtrs = as_pointers<CDCWireHit>(inputWireHits);
136
139
140 B2ASSERT("Expect wire hit neighborhood to be symmetric ",
142
144
145 int iSuperCluster = -1;
146 for (CDCWireHitCluster& superCluster : outputSuperClusters) {
147 ++iSuperCluster;
148 superCluster.setISuperCluster(iSuperCluster);
149 for (CDCWireHit* wireHit : superCluster) {
150 wireHit->setISuperCluster(iSuperCluster);
151 }
152 std::sort(superCluster.begin(), superCluster.end());
153 }
154}
TrackingUtilities::Clusterizer< TrackingUtilities::CDCWireHit, TrackingUtilities::CDCWireHitCluster > m_wirehitClusterizer
Instance of the hit cluster generator.
bool m_param_expandOverApogeeGap
Parameter : Expand the super clusters over the typical gap at the apogee of the trajectory.
std::vector< TrackingUtilities::WeightedRelation< TrackingUtilities::CDCWireHit > > m_wireHitRelations
Memory for the wire hit neighborhood in a cluster.
const WireID & getWireID() const
Getter for the WireID of the wire the hit is located on.
Iterator begin() const
Begin of the range for range based for.
Iterator end() const
End of the range for range based for.
bool empty() const
Checks if the begin equals the end iterator, hence if the range is empty.
Reference back() const
Returns the dereferenced iterator before end()
Reference front() const
Returns the dereferenced iterator at begin()
std::size_t size() const
Returns the total number of objects in this range.
unsigned short getIWire() const
Getter for wire within the layer.
static void appendUsing(ARelationFilter &relationFilter, const std::vector< AObject * > &froms, const std::vector< AObject * > &tos, std::vector< WeightedRelation< AObject > > &weightedRelations, unsigned int maximumNumberOfRelations=std::numeric_limits< unsigned int >::max())
Appends relations between elements in the given AItems using the ARelationFilter.
static bool areSymmetric(const AWeightedRelations &weightedRelations)
Checks for the symmetry of a range of weighted relations Explicitly checks for each weighted relation...