77 const std::vector<CDCFacet>& inputFacets,
79 std::vector<CDCSegment2D>& outputSegments)
81 std::vector<ConstVectorRange<CDCFacet>> facetsByICluster =
82 adjacent_groupby(inputFacets.begin(), inputFacets.end(), std::mem_fn(&CDCFacet::getICluster));
84 for (
const ConstVectorRange<CDCFacet>& facetsInCluster : facetsByICluster) {
85 if (facetsInCluster.empty())
continue;
87 B2ASSERT(
"Expect the facets to be sorted",
88 std::is_sorted(std::begin(facetsInCluster), std::end(facetsInCluster)));
91 std::vector<const CDCFacet*> facetPtrsInCluster = as_pointers<const CDCFacet>(facetsInCluster);
94 const CDCFacet& firstFacet = facetsInCluster.front();
95 auto beginFacetRelationInCluster =
96 std::lower_bound(inputFacetRelations.begin(), inputFacetRelations.end(), &firstFacet);
98 const CDCFacet& lastFacet = facetsInCluster.back();
99 auto endFacetRelationInCluster =
100 std::upper_bound(inputFacetRelations.begin(), inputFacetRelations.end(), &lastFacet);
104 std::vector<WeightedRelation<const CDCFacet>>
105 facetRelationsInCluster(beginFacetRelationInCluster,
106 endFacetRelationInCluster);
115 auto getFacetPath = [&facetsInCluster,
116 &facetRelationsInCluster,
117 &iCluster](
const CDCSegment2D & segment,
bool checkRelations =
true) {
120 std::vector<const CDCFacet*> facetPath;
126 auto itFacet = std::lower_bound(facetsInCluster.begin(), facetsInCluster.end(), rlWireHitTriple);
127 if (itFacet == facetsInCluster.end())
break;
128 if (not(*itFacet == rlWireHitTriple))
break;
132 if (not facetPath.empty() and checkRelations) {
133 const CDCFacet* fromFacet = facetPath.back();
134 auto relationsFromFacet = std::equal_range(facetRelationsInCluster.begin(),
135 facetRelationsInCluster.end(),
137 if (std::count_if(relationsFromFacet.first, relationsFromFacet.second, Second() == facet) == 0)
break;
139 facetPath.push_back(facet);
148 outputSegments.reserve(outputSegments.size() + additionalSpace);
150 for (
const std::vector<const CDCFacet*>& facetPath :
m_facetPaths) {
153 const CDCFacet& originalSingleFacet = *facetPath.front();
155 int nSingleFacets = 0;
158 std::vector<const CDCFacet*> singleFacetPath;
159 singleFacetPath.reserve(1);
161 std::array<int, 3> permIndices{0, 1, 2};
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());
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}) {
177 auto itFacet = std::lower_bound(facetsInCluster.begin(),
178 facetsInCluster.end(),
181 if (itFacet == facetsInCluster.end())
continue;
182 if (not(*itFacet == rlWireHitTriple))
continue;
184 const CDCFacet* singleFacet = &*itFacet;
185 singleFacetPath.clear();
186 singleFacetPath.push_back(singleFacet);
188 outputSegments.back()->setReverseFlag();
189 outputSegments.back()->setAliasFlag();
195 B2ASSERT(
"At least one single facet added", nSingleFacets > 0);
201 outputSegments.reserve(outputSegments.size() + 4);
208 bool checkRelations =
true;
213 auto itLayerSwitch = std::adjacent_find(segment->begin(), segment->end(), differentILayer);
214 const bool onlyOneLayer = itLayerSwitch == segment->end();
215 checkRelations = not onlyOneLayer;
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();
226 (*segment)->setReverseFlag(
true);
227 (*reverseSegment)->setReverseFlag(
true);
234 int nRLSwitches = segment->getNRLSwitches();
235 if (nRLSwitches > 2)
continue;
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();
244 (*segment)->setAliasFlag(
true);
245 (*aliasSegment)->setAliasFlag(
true);
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);
263 if (reverseSegment !=
nullptr and reverseAliasSegment !=
nullptr) {
264 (*reverseSegment)->setAliasFlag(
true);
265 (*reverseAliasSegment)->setAliasFlag(
true);