Main function of the segment finding by the cellular automaton.
79{
80 std::vector<ConstVectorRange<CDCFacet>> facetsByICluster =
82
83 for (const ConstVectorRange<CDCFacet>& facetsInCluster : facetsByICluster) {
84 if (facetsInCluster.empty()) continue;
85
86 B2ASSERT("Expect the facets to be sorted",
87 std::is_sorted(std::begin(facetsInCluster), std::end(facetsInCluster)));
88
89
90 std::vector<const CDCFacet*> facetPtrsInCluster = as_pointers<const CDCFacet>(facetsInCluster);
91
92
93 const CDCFacet& firstFacet = facetsInCluster.front();
94 auto beginFacetRelationInCluster =
95 std::lower_bound(inputFacetRelations.begin(), inputFacetRelations.end(), &firstFacet);
96
97 const CDCFacet& lastFacet = facetsInCluster.back();
98 auto endFacetRelationInCluster =
99 std::upper_bound(inputFacetRelations.begin(), inputFacetRelations.end(), &lastFacet);
100
102
103 std::vector<WeightedRelation<const CDCFacet>>
104 facetRelationsInCluster(beginFacetRelationInCluster,
105 endFacetRelationInCluster);
106
107
110
111
112
113
114 auto getFacetPath = [&facetsInCluster,
115 &facetRelationsInCluster,
116 &iCluster](const CDCSegment2D & segment, bool checkRelations = true) {
117 CDCRLWireHitSegment rlWireHitSegment = segment.getRLWireHitSegment();
119 std::vector<const CDCFacet*> facetPath;
120 for (CDCRLWireHitTriple& rlWireHitTriple : aliasFacetSegment) {
121
122 rlWireHitTriple.setICluster(iCluster);
123
124
125 auto itFacet = std::lower_bound(facetsInCluster.begin(), facetsInCluster.end(), rlWireHitTriple);
126 if (itFacet == facetsInCluster.end()) break;
127 if (not(*itFacet == rlWireHitTriple)) break;
128 const CDCFacet* facet = &*itFacet;
129
130
131 if (not facetPath.empty() and checkRelations) {
132 const CDCFacet* fromFacet = facetPath.back();
133 auto relationsFromFacet = std::equal_range(facetRelationsInCluster.begin(),
134 facetRelationsInCluster.end(),
135 fromFacet);
136 if (std::count_if(relationsFromFacet.first, relationsFromFacet.second, Second() == facet) == 0) break;
137 }
138 facetPath.push_back(facet);
139 }
140 return facetPath;
141 };
142
143
147 outputSegments.reserve(outputSegments.size() + additionalSpace);
148
149 for (
const std::vector<const CDCFacet*>& facetPath :
m_facetPaths) {
150
152 const CDCFacet& originalSingleFacet = *facetPath.front();
153
154 int nSingleFacets = 0;
155
156
157 std::vector<const CDCFacet*> singleFacetPath;
158 singleFacetPath.reserve(1);
159
160 std::array<int, 3> permIndices{0, 1, 2};
161 CDCRLWireHitTriple rlWireHitTriple = originalSingleFacet;
162
163 for (int iPerm = 0; iPerm < 6; ++iPerm) {
164 setRLWireHit(rlWireHitTriple, permIndices[0], originalSingleFacet.
getStartRLWireHit());
165 setRLWireHit(rlWireHitTriple, permIndices[1], originalSingleFacet.
getMiddleRLWireHit());
166 setRLWireHit(rlWireHitTriple, permIndices[2], originalSingleFacet.
getEndRLWireHit());
167 std::next_permutation(permIndices.begin(), permIndices.end());
168
169 for (ERightLeft startRLInfo : {ERightLeft::c_Left, ERightLeft::c_Right}) {
171 for (ERightLeft middleRLInfo : {ERightLeft::c_Left, ERightLeft::c_Right}) {
173 for (ERightLeft endRLInfo : {ERightLeft::c_Left, ERightLeft::c_Right}) {
175
176 auto itFacet = std::lower_bound(facetsInCluster.begin(),
177 facetsInCluster.end(),
178 rlWireHitTriple);
179
180 if (itFacet == facetsInCluster.end())continue;
181 if (not(*itFacet == rlWireHitTriple)) continue;
182
183 const CDCFacet* singleFacet = &*itFacet;
184 singleFacetPath.clear();
185 singleFacetPath.push_back(singleFacet);
187 outputSegments.back()->setReverseFlag();
188 outputSegments.back()->setAliasFlag();
189 ++nSingleFacets;
190 }
191 }
192 }
193 }
194 B2ASSERT("At least one single facet added", nSingleFacets > 0);
195
196
197 continue;
198 }
199
200 outputSegments.reserve(outputSegments.size() + 4);
202 const CDCSegment2D* segment = &outputSegments.back();
203
204
205
206
207 bool checkRelations = true;
209 auto differentILayer = [](const CDCRecoHit2D & lhs, const CDCRecoHit2D & rhs) {
211 };
212 auto itLayerSwitch = std::adjacent_find(segment->begin(), segment->end(), differentILayer);
213 const bool onlyOneLayer = itLayerSwitch == segment->end();
214 checkRelations = not onlyOneLayer;
215 }
216
217 const CDCSegment2D* reverseSegment = nullptr;
219 std::vector<const CDCFacet*> reverseFacetPath = getFacetPath(segment->reversed(), checkRelations);
220 if (reverseFacetPath.size() == facetPath.size()) {
221 B2DEBUG(25, "Successful constructed REVERSE");
223 reverseSegment = &outputSegments.back();
224
225 (*segment)->setReverseFlag(true);
226 (*reverseSegment)->setReverseFlag(true);
227 }
228 }
229
231
232
233 int nRLSwitches = segment->getNRLSwitches();
234 if (nRLSwitches > 2) continue;
235
236 const CDCSegment2D* aliasSegment = nullptr;
237 std::vector<const CDCFacet*> aliasFacetPath = getFacetPath(segment->getAlias(), checkRelations);
238 if (aliasFacetPath.size() == facetPath.size()) {
239 B2DEBUG(25, "Successful constructed alias");
241 aliasSegment = &outputSegments.back();
242
243 (*segment)->setAliasFlag(true);
244 (*aliasSegment)->setAliasFlag(true);
245 }
246
247 const CDCSegment2D* reverseAliasSegment = nullptr;
249 std::vector<const CDCFacet*> reverseAliasFacetPath =
250 getFacetPath(segment->reversed().getAlias(), checkRelations);
251 if (reverseAliasFacetPath.size() == facetPath.size()) {
252 B2DEBUG(25, "Successful constructed REVERSE alias");
254 reverseAliasSegment = &outputSegments.back();
255 if (aliasSegment != nullptr) {
256 (*aliasSegment)->setReverseFlag(true);
257 (*reverseAliasSegment)->setReverseFlag(true);
258 }
259 }
260 }
261
262 if (reverseSegment != nullptr and reverseAliasSegment != nullptr) {
263 (*reverseSegment)->setAliasFlag(true);
264 (*reverseAliasSegment)->setAliasFlag(true);
265 }
266 }
267 }
268}
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 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...
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.
bool m_param_searchAlias
Parameter : Switch to construct the alias segment if it is available in the facet graph as well.
MultipassCellularPathFinder< const CDCFacet > m_cellularPathFinder
Instance of the cellular automaton path finder.
std::vector< Path< const CDCFacet > > m_facetPaths
Memory for the facet paths generated from the graph.