Main function of the segment finding by the cellular automaton.
80{
81 std::vector<ConstVectorRange<CDCFacet>> facetsByICluster =
82 adjacent_groupby(inputFacets.begin(), inputFacets.end(), std::mem_fn(&CDCFacet::getICluster));
83
84 for (const ConstVectorRange<CDCFacet>& facetsInCluster : facetsByICluster) {
85 if (facetsInCluster.empty()) continue;
86
87 B2ASSERT("Expect the facets to be sorted",
88 std::is_sorted(std::begin(facetsInCluster), std::end(facetsInCluster)));
89
90
91 std::vector<const CDCFacet*> facetPtrsInCluster = as_pointers<const CDCFacet>(facetsInCluster);
92
93
94 const CDCFacet& firstFacet = facetsInCluster.front();
95 auto beginFacetRelationInCluster =
96 std::lower_bound(inputFacetRelations.begin(), inputFacetRelations.end(), &firstFacet);
97
98 const CDCFacet& lastFacet = facetsInCluster.back();
99 auto endFacetRelationInCluster =
100 std::upper_bound(inputFacetRelations.begin(), inputFacetRelations.end(), &lastFacet);
101
103
104 std::vector<WeightedRelation<const CDCFacet>>
105 facetRelationsInCluster(beginFacetRelationInCluster,
106 endFacetRelationInCluster);
107
108
111
112
113
114
115 auto getFacetPath = [&facetsInCluster,
116 &facetRelationsInCluster,
117 &iCluster](const CDCSegment2D & segment, bool checkRelations = true) {
118 CDCRLWireHitSegment rlWireHitSegment = segment.getRLWireHitSegment();
120 std::vector<const CDCFacet*> facetPath;
121 for (CDCRLWireHitTriple& rlWireHitTriple : aliasFacetSegment) {
122
123 rlWireHitTriple.setICluster(iCluster);
124
125
126 auto itFacet = std::lower_bound(facetsInCluster.begin(), facetsInCluster.end(), rlWireHitTriple);
127 if (itFacet == facetsInCluster.end()) break;
128 if (not(*itFacet == rlWireHitTriple)) break;
129 const CDCFacet* facet = &*itFacet;
130
131
132 if (not facetPath.empty() and checkRelations) {
133 const CDCFacet* fromFacet = facetPath.back();
134 auto relationsFromFacet = std::equal_range(facetRelationsInCluster.begin(),
135 facetRelationsInCluster.end(),
136 fromFacet);
137 if (std::count_if(relationsFromFacet.first, relationsFromFacet.second, Second() == facet) == 0) break;
138 }
139 facetPath.push_back(facet);
140 }
141 return facetPath;
142 };
143
144
148 outputSegments.reserve(outputSegments.size() + additionalSpace);
149
150 for (
const std::vector<const CDCFacet*>& facetPath :
m_facetPaths) {
151
153 const CDCFacet& originalSingleFacet = *facetPath.front();
154
155 int nSingleFacets = 0;
156
157
158 std::vector<const CDCFacet*> singleFacetPath;
159 singleFacetPath.reserve(1);
160
161 std::array<int, 3> permIndices{0, 1, 2};
162 CDCRLWireHitTriple rlWireHitTriple = originalSingleFacet;
163
164 for (int iPerm = 0; iPerm < 6; ++iPerm) {
165 setRLWireHit(rlWireHitTriple, permIndices[0], originalSingleFacet.
getStartRLWireHit());
166 setRLWireHit(rlWireHitTriple, permIndices[1], originalSingleFacet.
getMiddleRLWireHit());
167 setRLWireHit(rlWireHitTriple, permIndices[2], originalSingleFacet.
getEndRLWireHit());
168 std::next_permutation(permIndices.begin(), permIndices.end());
169
170 for (ERightLeft startRLInfo : {ERightLeft::c_Left, ERightLeft::c_Right}) {
172 for (ERightLeft middleRLInfo : {ERightLeft::c_Left, ERightLeft::c_Right}) {
174 for (ERightLeft endRLInfo : {ERightLeft::c_Left, ERightLeft::c_Right}) {
176
177 auto itFacet = std::lower_bound(facetsInCluster.begin(),
178 facetsInCluster.end(),
179 rlWireHitTriple);
180
181 if (itFacet == facetsInCluster.end())continue;
182 if (not(*itFacet == rlWireHitTriple)) continue;
183
184 const CDCFacet* singleFacet = &*itFacet;
185 singleFacetPath.clear();
186 singleFacetPath.push_back(singleFacet);
188 outputSegments.back()->setReverseFlag();
189 outputSegments.back()->setAliasFlag();
190 ++nSingleFacets;
191 }
192 }
193 }
194 }
195 B2ASSERT("At least one single facet added", nSingleFacets > 0);
196
197
198 continue;
199 }
200
201 outputSegments.reserve(outputSegments.size() + 4);
203 const CDCSegment2D* segment = &outputSegments.back();
204
205
206
207
208 bool checkRelations = true;
210 auto differentILayer = [](const CDCRecoHit2D & lhs, const CDCRecoHit2D & rhs) {
212 };
213 auto itLayerSwitch = std::adjacent_find(segment->begin(), segment->end(), differentILayer);
214 const bool onlyOneLayer = itLayerSwitch == segment->end();
215 checkRelations = not onlyOneLayer;
216 }
217
218 const CDCSegment2D* reverseSegment = nullptr;
220 std::vector<const CDCFacet*> reverseFacetPath = getFacetPath(segment->reversed(), checkRelations);
221 if (reverseFacetPath.size() == facetPath.size()) {
222 B2DEBUG(25, "Successful constructed REVERSE");
224 reverseSegment = &outputSegments.back();
225
226 (*segment)->setReverseFlag(true);
227 (*reverseSegment)->setReverseFlag(true);
228 }
229 }
230
232
233
234 int nRLSwitches = segment->getNRLSwitches();
235 if (nRLSwitches > 2) continue;
236
237 const CDCSegment2D* aliasSegment = nullptr;
238 std::vector<const CDCFacet*> aliasFacetPath = getFacetPath(segment->getAlias(), checkRelations);
239 if (aliasFacetPath.size() == facetPath.size()) {
240 B2DEBUG(25, "Successful constructed alias");
242 aliasSegment = &outputSegments.back();
243
244 (*segment)->setAliasFlag(true);
245 (*aliasSegment)->setAliasFlag(true);
246 }
247
248 const CDCSegment2D* reverseAliasSegment = nullptr;
250 std::vector<const CDCFacet*> reverseAliasFacetPath =
251 getFacetPath(segment->reversed().getAlias(), checkRelations);
252 if (reverseAliasFacetPath.size() == facetPath.size()) {
253 B2DEBUG(25, "Successful constructed REVERSE alias");
255 reverseAliasSegment = &outputSegments.back();
256 if (aliasSegment != nullptr) {
257 (*aliasSegment)->setReverseFlag(true);
258 (*reverseAliasSegment)->setReverseFlag(true);
259 }
260 }
261 }
262
263 if (reverseSegment != nullptr and reverseAliasSegment != nullptr) {
264 (*reverseSegment)->setAliasFlag(true);
265 (*reverseAliasSegment)->setAliasFlag(true);
266 }
267 }
268 }
269}
ILayer getILayer() const
Getter for the layer id within its superlayer Gives the layer id within its superlayer ranging from ...
bool m_param_relaxSingleLayerSearch
Parameter : Switch to relax the alias and reverse search for segments contained in a single layer.
bool m_param_allSingleAliases
Paraneter : Switch to activate the write out of all available orientations of single facet segments.
bool m_param_searchReversed
Parameter : Switch to construct the reversed segment if it is available in the facet graph as well.
TrackingUtilities::MultipassCellularPathFinder< const TrackingUtilities::CDCFacet > m_cellularPathFinder
Instance of the cellular automaton path finder.
bool m_param_searchAlias
Parameter : Switch to construct the alias segment if it is available in the facet graph as well.
std::vector< TrackingUtilities::Path< const TrackingUtilities::CDCFacet > > m_facetPaths
Memory for the facet paths generated from the graph.
static CDCFacetSegment create(const CDCRLWireHitSegment &rlWireHitSegment)
Construct a train of facets from the given oriented wire hits.
void setEndRLInfo(const ERightLeft endRLInfo)
Setter for the right left passage information of the third oriented wire hit.
CDCRLWireHit & getStartRLWireHit()
Getter for the first oriented wire hit.
void setMiddleRLInfo(const ERightLeft middleRLInfo)
Setter for the right left passage information of the second oriented wire hit.
int getICluster() const
Getter for the cluster id.
CDCRLWireHit & getEndRLWireHit()
Getter for the third oriented wire hit.
CDCRLWireHit & getMiddleRLWireHit()
Getter for the second oriented wire hit.
void setStartRLInfo(const ERightLeft startRLInfo)
Setter for the right left passage information of the first oriented wire hit.
const CDC::CDCWire & getWire() const
Getter for the wire the reconstructed hit associated to.
static CDCSegment2D condense(const CDCTangentSegment &tangentSegment)
Averages the reconstructed positions from hits that overlap in adjacent tangents in the given tangent...