8#include <tracking/trackFindingCDC/findlets/minimal/SegmentCreatorFacetAutomaton.h>
10#include <tracking/trackFindingCDC/eventdata/segments/CDCSegment2D.h>
11#include <tracking/trackFindingCDC/eventdata/segments/CDCFacetSegment.h>
12#include <tracking/trackFindingCDC/eventdata/segments/CDCRLWireHitSegment.h>
14#include <tracking/trackFindingCDC/eventdata/hits/CDCFacet.h>
16#include <tracking/trackFindingCDC/topology/CDCWire.h>
18#include <tracking/trackFindingCDC/utilities/WeightedRelation.h>
19#include <tracking/trackFindingCDC/utilities/Functional.h>
20#include <tracking/trackFindingCDC/utilities/VectorRange.h>
21#include <tracking/trackFindingCDC/utilities/StringManipulation.h>
22#include <tracking/trackFindingCDC/utilities/Algorithms.h>
24#include <framework/core/ModuleParamList.templateDetails.h>
30using namespace TrackFindingCDC;
35 if (iRLWireHit == 0) {
37 }
else if (iRLWireHit == 1) {
39 }
else if (iRLWireHit == 2) {
49 return "Constructs segments by extraction of facet paths in a cellular automaton.";
54 moduleParamList->
addParameter(prefixed(prefix,
"searchReversed"),
56 "Switch to construct the reversed segment if it is available in the facet graph as well.",
59 moduleParamList->
addParameter(prefixed(prefix,
"searchAlias"),
61 "Switch to construct the alias segment if it is available in the facet graph as well.",
64 moduleParamList->
addParameter(prefixed(prefix,
"relaxSingleLayerSearch"),
66 "Switch to relax the alias and reverse search for segments contained in a single layer.",
69 moduleParamList->
addParameter(prefixed(prefix,
"allSingleAliases"),
71 "Switch to activate the write out of all available orientations of single facet segments.",
76 const std::vector<CDCFacet>& inputFacets,
78 std::vector<CDCSegment2D>& outputSegments)
80 std::vector<ConstVectorRange<CDCFacet>> 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();
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();
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) {
257 (*reverseAliasSegment)->setReverseFlag(
true);
262 if (reverseSegment !=
nullptr and reverseAliasSegment !=
nullptr) {
263 (*reverseSegment)->setAliasFlag(
true);
264 (*reverseAliasSegment)->setAliasFlag(
true);
The Module parameter list class.
void setAliasFlag(bool setTo=true)
Sets the alias flag to the given value. Default value true.
void setReverseFlag(bool setTo=true)
Sets the reverse flag to the given value. Default value true.
A segment consisting of adjacent facets.
static CDCFacetSegment create(const CDCRLWireHitSegment &rlWireHitSegment)
Construct a train of facets from the given oriented wire hits.
Class representing a triple of neighboring oriented wire with additional trajectory information.
A segment consisting of two dimensional reconstructed hits.
Class representing a triple of neighboring wire hits.
void setICluster(int iCluster)
Setter for the cluster id.
void setEndRLInfo(const ERightLeft endRLInfo)
Setter for the right left passage information of the third oriented wire hit.
void setEndRLWireHit(const CDCRLWireHit &endRLWireHit)
Setter for 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.
void setMiddleRLWireHit(const CDCRLWireHit &middleRLWireHit)
Setter for 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.
void setStartRLWireHit(const CDCRLWireHit &startRLWireHit)
Setter for the first oriented wire hit.
Class representing an oriented hit wire including a hypotheses whether the causing track passes left ...
Class representing a two dimensional reconstructed hit in the central drift chamber.
const CDCWire & getWire() const
Getter for the wire the reconstructed hit associated to.
A reconstructed sequence of two dimensional hits in one super layer.
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 ...
A pair of iterators usable with the range base for loop.
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.
std::string getDescription() final
Short description of the findlet.
bool m_param_searchAlias
Parameter : Switch to construct the alias segment if it is available in the facet graph as well.
void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix) final
Expose the parameters to a module.
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.
void apply(const std::vector< CDCFacet > &inputFacets, const std::vector< WeightedRelation< const CDCFacet > > &inputFacetRelations, std::vector< CDCSegment2D > &outputSegments) final
Main function of the segment finding by the cellular automaton.
Type for two related objects with a weight.
void addParameter(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module list.
ERightLeft
Enumeration to represent the distinct possibilities of the right left passage.
Abstract base class for different kinds of events.
Functor to get the I part (as of std::get<I>) from an arbitrary objects.