76 const std::vector<CDCFacet>& inputFacets,
78 std::vector<CDCSegment2D>& outputSegments)
80 std::vector<ConstVectorRange<CDCFacet>> facetsByICluster =
83 for (
const ConstVectorRange<CDCFacet>& facetsInCluster : facetsByICluster) {
84 if (facetsInCluster.empty())
continue;
86 B2ASSERT(
"Expect the facets to be sorted",
87 std::is_sorted(std::begin(facetsInCluster), std::end(facetsInCluster)));
90 std::vector<const CDCFacet*> facetPtrsInCluster = as_pointers<const CDCFacet>(facetsInCluster);
93 const CDCFacet& firstFacet = facetsInCluster.front();
94 auto beginFacetRelationInCluster =
95 std::lower_bound(inputFacetRelations.begin(), inputFacetRelations.end(), &firstFacet);
97 const CDCFacet& lastFacet = facetsInCluster.back();
98 auto endFacetRelationInCluster =
99 std::upper_bound(inputFacetRelations.begin(), inputFacetRelations.end(), &lastFacet);
103 std::vector<WeightedRelation<const CDCFacet>>
104 facetRelationsInCluster(beginFacetRelationInCluster,
105 endFacetRelationInCluster);
114 auto getFacetPath = [&facetsInCluster,
115 &facetRelationsInCluster,
116 &iCluster](
const CDCSegment2D & segment,
bool checkRelations =
true) {
119 std::vector<const CDCFacet*> facetPath;
125 auto itFacet = std::lower_bound(facetsInCluster.begin(), facetsInCluster.end(), rlWireHitTriple);
126 if (itFacet == facetsInCluster.end())
break;
127 if (not(*itFacet == rlWireHitTriple))
break;
131 if (not facetPath.empty() and checkRelations) {
132 const CDCFacet* fromFacet = facetPath.back();
133 auto relationsFromFacet = std::equal_range(facetRelationsInCluster.begin(),
134 facetRelationsInCluster.end(),
136 if (std::count_if(relationsFromFacet.first, relationsFromFacet.second, Second() == facet) == 0)
break;
138 facetPath.push_back(facet);
147 outputSegments.reserve(outputSegments.size() + additionalSpace);
149 for (
const std::vector<const CDCFacet*>& facetPath :
m_facetPaths) {
152 const CDCFacet& originalSingleFacet = *facetPath.front();
154 int nSingleFacets = 0;
157 std::vector<const CDCFacet*> singleFacetPath;
158 singleFacetPath.reserve(1);
160 std::array<int, 3> permIndices{0, 1, 2};
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());
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}) {
176 auto itFacet = std::lower_bound(facetsInCluster.begin(),
177 facetsInCluster.end(),
180 if (itFacet == facetsInCluster.end())
continue;
181 if (not(*itFacet == rlWireHitTriple))
continue;
183 const CDCFacet* singleFacet = &*itFacet;
184 singleFacetPath.clear();
185 singleFacetPath.push_back(singleFacet);
187 outputSegments.back()->setReverseFlag();
188 outputSegments.back()->setAliasFlag();
194 B2ASSERT(
"At least one single facet added", nSingleFacets > 0);
200 outputSegments.reserve(outputSegments.size() + 4);
207 bool checkRelations =
true;
212 auto itLayerSwitch = std::adjacent_find(segment->begin(), segment->end(), differentILayer);
213 const bool onlyOneLayer = itLayerSwitch == segment->end();
214 checkRelations = not onlyOneLayer;
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();
225 (*segment)->setReverseFlag(
true);
226 (*reverseSegment)->setReverseFlag(
true);
233 int nRLSwitches = segment->getNRLSwitches();
234 if (nRLSwitches > 2)
continue;
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();
243 (*segment)->setAliasFlag(
true);
244 (*aliasSegment)->setAliasFlag(
true);
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);
262 if (reverseSegment !=
nullptr and reverseAliasSegment !=
nullptr) {
263 (*reverseSegment)->setAliasFlag(
true);
264 (*reverseAliasSegment)->setAliasFlag(
true);