Main algorithm applying the cluster refinement.
53{
55
57 auto wireHitsByLayer =
58 adjacent_groupby(inputWireHits.begin(), inputWireHits.end(), [](const CDCWireHit & wireHit) {
59 return wireHit.getWireID().getILayer();
60 });
61
62 for (const auto& wireHitsInLayer : wireHitsByLayer) {
63 const CDCWireLayer& wireLayer = wireHitsInLayer.front().getWire().getWireLayer();
64 const int nWires = wireLayer.
size();
65
66 auto sameWireHitChain = [](const CDCWireHit & lhs, const CDCWireHit & rhs) {
68 };
69
70 auto wireHitChains =
71 unique_ranges(wireHitsInLayer.begin(), wireHitsInLayer.end(), sameWireHitChain);
72
73 size_t nWireHits = 0;
74 for (const VectorRange<CDCWireHit>& wireHitChain : wireHitChains) {
75 nWireHits += wireHitChain.size();
76 }
77 assert(nWireHits == wireHitsInLayer.size());
78
79
80 VectorRange<CDCWireHit> frontWrapChain(wireHitsInLayer.begin(), wireHitsInLayer.begin());
81 VectorRange<CDCWireHit> backWrapChain(wireHitsInLayer.end(), wireHitsInLayer.end());
82 if (wireHitChains.
size() > 1) {
83 if (wireHitChains.
front().front().getWire().isPrimaryNeighborWith(
84 wireHitChains.
back().back().getWire())) {
85
86
87 int wrapAroundChainSize = wireHitChains.
front().size() + wireHitChains.
back().size();
88 if (wrapAroundChainSize >= 5) {
89
90
91 frontWrapChain = wireHitChains.
front();
92 frontWrapChain.first = frontWrapChain.end() - wrapAroundChainSize;
93
94 backWrapChain = wireHitChains.
back();
95 backWrapChain.second = backWrapChain.begin() + wrapAroundChainSize;
96
97 wireHitChains.erase(wireHitChains.
begin());
98 wireHitChains.pop_back();
99 }
100 }
101 }
102
103 auto itLastChain = std::remove_if(wireHitChains.
begin(), wireHitChains.
end(), Size() < 5u);
104 wireHitChains.erase(itLastChain, wireHitChains.
end());
105 if (wireHitChains.
empty())
continue;
106
107 auto connectWireHitChains = [this, nWires](const VectorRange<CDCWireHit>& lhs,
108 const VectorRange<CDCWireHit>& rhs) {
109 int iWireDelta = rhs.front().getWireID().getIWire() - lhs.
back().getWireID().getIWire();
110 if (iWireDelta < 0) iWireDelta += nWires;
111 if (iWireDelta <
static_cast<int>(lhs.
size() + rhs.size())) {
114 }
115 return false;
116 };
117
118 std::ignore = std::adjacent_find(wireHitChains.
begin(), wireHitChains.
end(), connectWireHitChains);
119
120 if (not frontWrapChain.empty()) {
121 connectWireHitChains(frontWrapChain, wireHitChains.
front());
122 }
123 if (not backWrapChain.empty()) {
124 connectWireHitChains(wireHitChains.
back(), backWrapChain);
125 }
126 if (backWrapChain.empty() and frontWrapChain.empty()) {
127 connectWireHitChains(wireHitChains.
back(), wireHitChains.
front());
128 }
129 }
130 }
131
133 const std::vector<CDCWireHit*> wireHitPtrs = as_pointers<CDCWireHit>(inputWireHits);
134
137
138 B2ASSERT("Expect wire hit neighborhood to be symmetric ",
140
142
143 int iSuperCluster = -1;
144 for (CDCWireHitCluster& superCluster : outputSuperClusters) {
145 ++iSuperCluster;
146 superCluster.setISuperCluster(iSuperCluster);
147 for (CDCWireHit* wireHit : superCluster) {
148 wireHit->setISuperCluster(iSuperCluster);
149 }
150 std::sort(superCluster.begin(), superCluster.end());
151 }
152}
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.
bool m_param_expandOverApogeeGap
Parameter : Expand the super clusters over the typical gap at the apogee of the trajectory.
std::vector< WeightedRelation< CDCWireHit > > m_wireHitRelations
Memory for the wire hit neighborhood in a cluster.
Clusterizer< CDCWireHit, CDCWireHitCluster > m_wirehitClusterizer
Instance of the hit cluster generator.
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...