10 #include <tracking/trackFindingCDC/findlets/minimal/SegmentCreatorFacetAutomaton.h>
12 #include <tracking/trackFindingCDC/eventdata/segments/CDCSegment2D.h>
13 #include <tracking/trackFindingCDC/eventdata/segments/CDCFacetSegment.h>
14 #include <tracking/trackFindingCDC/eventdata/segments/CDCRLWireHitSegment.h>
16 #include <tracking/trackFindingCDC/eventdata/hits/CDCFacet.h>
18 #include <tracking/trackFindingCDC/topology/CDCWire.h>
20 #include <tracking/trackFindingCDC/utilities/WeightedRelation.h>
21 #include <tracking/trackFindingCDC/utilities/Functional.h>
22 #include <tracking/trackFindingCDC/utilities/VectorRange.h>
23 #include <tracking/trackFindingCDC/utilities/StringManipulation.h>
24 #include <tracking/trackFindingCDC/utilities/Algorithms.h>
26 #include <framework/core/ModuleParamList.templateDetails.h>
32 using namespace TrackFindingCDC;
35 void setRLWireHit(CDCRLWireHitTriple& rlWireHitTriple,
int iRLWireHit,
const CDCRLWireHit& rlWireHit)
37 if (iRLWireHit == 0) {
38 rlWireHitTriple.setStartRLWireHit(rlWireHit);
39 }
else if (iRLWireHit == 1) {
40 rlWireHitTriple.setMiddleRLWireHit(rlWireHit);
41 }
else if (iRLWireHit == 2) {
42 rlWireHitTriple.setEndRLWireHit(rlWireHit);
51 return "Constructs segments by extraction of facet paths in a cellular automaton.";
56 moduleParamList->
addParameter(prefixed(prefix,
"searchReversed"),
58 "Switch to construct the reversed segment if it is available in the facet graph as well.",
61 moduleParamList->
addParameter(prefixed(prefix,
"searchAlias"),
63 "Switch to construct the alias segment if it is available in the facet graph as well.",
66 moduleParamList->
addParameter(prefixed(prefix,
"relaxSingleLayerSearch"),
68 "Switch to relax the alias and reverse search for segments contained in a single layer.",
71 moduleParamList->
addParameter(prefixed(prefix,
"allSingleAliases"),
73 "Switch to activate the write out of all available orientations of single facet segments.",
78 const std::vector<CDCFacet>& inputFacets,
80 std::vector<CDCSegment2D>& outputSegments)
82 std::vector<ConstVectorRange<CDCFacet>> facetsByICluster =
86 if (facetsInCluster.empty())
continue;
88 B2ASSERT(
"Expect the facets to be sorted",
89 std::is_sorted(std::begin(facetsInCluster), std::end(facetsInCluster)));
92 std::vector<const CDCFacet*> facetPtrsInCluster = as_pointers<const CDCFacet>(facetsInCluster);
95 const CDCFacet& firstFacet = facetsInCluster.front();
96 auto beginFacetRelationInCluster =
97 std::lower_bound(inputFacetRelations.begin(), inputFacetRelations.end(), &firstFacet);
99 const CDCFacet& lastFacet = facetsInCluster.back();
100 auto endFacetRelationInCluster =
101 std::upper_bound(inputFacetRelations.begin(), inputFacetRelations.end(), &lastFacet);
105 std::vector<WeightedRelation<const CDCFacet>>
106 facetRelationsInCluster(beginFacetRelationInCluster,
107 endFacetRelationInCluster);
116 auto getFacetPath = [&facetsInCluster,
117 &facetRelationsInCluster,
118 &iCluster](
const CDCSegment2D & segment,
bool checkRelations =
true) {
121 std::vector<const CDCFacet*> facetPath;
124 rlWireHitTriple.setICluster(iCluster);
127 auto itFacet = std::lower_bound(facetsInCluster.begin(), facetsInCluster.end(), rlWireHitTriple);
128 if (itFacet == facetsInCluster.end())
break;
129 if (not(*itFacet == rlWireHitTriple))
break;
133 if (not facetPath.empty() and checkRelations) {
134 const CDCFacet* fromFacet = facetPath.back();
135 auto relationsFromFacet = std::equal_range(facetRelationsInCluster.begin(),
136 facetRelationsInCluster.end(),
138 if (std::count_if(relationsFromFacet.first, relationsFromFacet.second,
Second() == facet) == 0)
break;
140 facetPath.push_back(facet);
149 outputSegments.reserve(outputSegments.size() + additionalSpace);
151 for (
const std::vector<const CDCFacet*>& facetPath :
m_facetPaths) {
154 const CDCFacet& originalSingleFacet = *facetPath.front();
156 int nSingleFacets = 0;
159 std::vector<const CDCFacet*> singleFacetPath;
160 singleFacetPath.reserve(1);
162 std::array<int, 3> permIndices{0, 1, 2};
165 for (
int iPerm = 0; iPerm < 6; ++iPerm) {
166 setRLWireHit(rlWireHitTriple, permIndices[0], originalSingleFacet.
getStartRLWireHit());
167 setRLWireHit(rlWireHitTriple, permIndices[1], originalSingleFacet.
getMiddleRLWireHit());
168 setRLWireHit(rlWireHitTriple, permIndices[2], originalSingleFacet.
getEndRLWireHit());
169 std::next_permutation(permIndices.begin(), permIndices.end());
171 for (
ERightLeft startRLInfo : {ERightLeft::c_Left, ERightLeft::c_Right}) {
173 for (
ERightLeft middleRLInfo : {ERightLeft::c_Left, ERightLeft::c_Right}) {
175 for (
ERightLeft endRLInfo : {ERightLeft::c_Left, ERightLeft::c_Right}) {
178 auto itFacet = std::lower_bound(facetsInCluster.begin(),
179 facetsInCluster.end(),
182 if (itFacet == facetsInCluster.end())
continue;
183 if (not(*itFacet == rlWireHitTriple))
continue;
185 const CDCFacet* singleFacet = &*itFacet;
186 singleFacetPath.clear();
187 singleFacetPath.push_back(singleFacet);
189 outputSegments.back()->setReverseFlag();
190 outputSegments.back()->setAliasFlag();
196 B2ASSERT(
"At least one single facet added", nSingleFacets > 0);
202 outputSegments.reserve(outputSegments.size() + 4);
209 bool checkRelations =
true;
214 auto itLayerSwitch = std::adjacent_find(segment->begin(), segment->end(), differentILayer);
215 const bool onlyOneLayer = itLayerSwitch == segment->end();
216 checkRelations = not onlyOneLayer;
221 std::vector<const CDCFacet*> reverseFacetPath = getFacetPath(segment->reversed(), checkRelations);
222 if (reverseFacetPath.size() == facetPath.size()) {
223 B2DEBUG(100,
"Successful constructed REVERSE");
225 reverseSegment = &outputSegments.back();
227 (*segment)->setReverseFlag(
true);
228 (*reverseSegment)->setReverseFlag(
true);
235 int nRLSwitches = segment->getNRLSwitches();
236 if (nRLSwitches > 2)
continue;
239 std::vector<const CDCFacet*> aliasFacetPath = getFacetPath(segment->getAlias(), checkRelations);
240 if (aliasFacetPath.size() == facetPath.size()) {
241 B2DEBUG(100,
"Successful constructed alias");
243 aliasSegment = &outputSegments.back();
245 (*segment)->setAliasFlag(
true);
246 (*aliasSegment)->setAliasFlag(
true);
251 std::vector<const CDCFacet*> reverseAliasFacetPath =
252 getFacetPath(segment->reversed().getAlias(), checkRelations);
253 if (reverseAliasFacetPath.size() == facetPath.size()) {
254 B2DEBUG(100,
"Successful constructed REVERSE alias");
256 reverseAliasSegment = &outputSegments.back();
257 if (aliasSegment !=
nullptr) {
258 (*aliasSegment)->setReverseFlag(
true);
259 (*reverseAliasSegment)->setReverseFlag(
true);
264 if (reverseSegment !=
nullptr and reverseAliasSegment !=
nullptr) {
265 (*reverseSegment)->setAliasFlag(
true);
266 (*reverseAliasSegment)->setAliasFlag(
true);