Belle II Software prerelease-11-00-00e
BridgingWireHitRelationFilter.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8#include <tracking/trackFindingCDC/filters/wireHitRelation/BridgingWireHitRelationFilter.h>
9
10#include <tracking/trackingUtilities/filters/base/RelationFilter.icc.h>
11
12#include <tracking/trackingUtilities/eventdata/hits/CDCWireHit.h>
13
14#include <cdc/topology/CDCWireTopology.h>
15#include <cdc/topology/CDCWire.h>
16
17#include <tracking/trackingUtilities/utilities/Relation.h>
18#include <tracking/trackingUtilities/utilities/VectorRange.h>
19#include <tracking/trackingUtilities/utilities/Functional.h>
20#include <tracking/trackingUtilities/utilities/StringManipulation.h>
21
22#include <framework/core/ModuleParamList.templateDetails.h>
23
24#include <vector>
25#include <string>
26
27using namespace Belle2;
28using namespace CDC;
29using namespace TrackFindingCDC;
30using namespace TrackingUtilities;
31
33
35
37
39 const std::string& prefix)
40{
41 moduleParamList
42 ->addParameter(prefixed(prefix, "missingPrimaryNeighborThresholds"),
44 "Map of o'clock directions to number of missing drift cells "
45 "in the primary neighborhood to trigger the inclusion of secondary neighbors "
46 "in that very o'clock direction",
48}
49
51{
53 for (short oClockDirection = 0; oClockDirection < 12; oClockDirection++) {
54 m_missingPrimaryNeighborThresholds[oClockDirection] = 3;
55 if (m_param_missingPrimaryNeighborThresholdMap.count(oClockDirection)) {
56 m_missingPrimaryNeighborThresholds[oClockDirection] =
58 }
59 }
60
62 for (short oClockDirection : {5, 6, 7, 4, 8, 3, 9, 2, 10, 1, 0, 11}) {
63 if (m_missingPrimaryNeighborThresholds[oClockDirection] < 3) {
64 m_consideredSecondaryNeighbors.push_back(oClockDirection);
65 }
66 }
67}
68
69void BridgingWireHitRelationFilter::prepare(const std::vector<CDCWireHit*>& wireHits)
70{
71 m_preparedWires.clear();
72 m_preparedWires.reserve(wireHits.size());
73 for (const CDCWireHit* wireHit : wireHits) {
74 m_preparedWires.push_back(&wireHit->getWire());
75 }
76 m_preparedWireHitsData = wireHits.data();
77 m_preparedWireHitsSize = wireHits.size();
78}
79
81 CDCWireHit* from,
82 const std::vector<CDCWireHit*>& wireHits) const
83{
84 // Use the wires precomputed by prepare() when called with the prepared vector.
85 // The comparison LessOf<Deref>() used below resolves to operator<(CDCWireHit, CDCWire),
86 // which compares the *address* of the wire of the hit with the address of the wire.
87 // Searching the precomputed wire addresses therefore evaluates exactly the same
88 // predicate on exactly the same values, only without dereferencing the wire hits.
89 const bool prepared =
90 wireHits.data() == m_preparedWireHitsData and wireHits.size() == m_preparedWireHitsSize;
91
92 auto findWireHitRange = [&](const CDCWire * neighborWire) -> ConstVectorRange<CDCWireHit*> {
93 if (prepared)
94 {
95 const auto itRange = std::equal_range(m_preparedWires.begin(), m_preparedWires.end(), neighborWire);
96 return {
97 wireHits.begin() + (itRange.first - m_preparedWires.begin()),
98 wireHits.begin() + (itRange.second - m_preparedWires.begin())};
99 }
100 return ConstVectorRange<CDCWireHit*>{
101 std::equal_range(wireHits.begin(), wireHits.end(), neighborWire, LessOf<Deref>())
102 };
103 };
104
105 // Stack buffer for the wire neighbors - at most 6 primary
106 // respectively 12 secondary neighbors can be collected
107 std::array<std::pair<const CDCWire*, int>, 12> wireNeighbors;
108 int nWireNeighbors = 0;
109
110 std::vector<CDCWireHit*> wireHitNeighbors;
111 wireHitNeighbors.reserve(12);
112
113 std::array<short, 12> missingPrimaryNeighbor = {0};
114
115 const CDCWireTopology& wireTopology = CDCWireTopology::getInstance();
116
117 const CDCWire& wire = from->getWire();
118
119 // Analyse primary neighborhood - sorted such that the wire hits relations are most likely sorted.
120 for (short oClockDirection : {5, 7, 3, 9, 1, 11}) {
121 MayBePtr<const CDCWire> neighborWire = wireTopology.getPrimaryNeighbor(oClockDirection, wire);
122 if (neighborWire) wireNeighbors[nWireNeighbors++] = {neighborWire, oClockDirection};
123 }
124
125 std::sort(wireNeighbors.begin(), wireNeighbors.begin() + nWireNeighbors);
126
127 for (std::pair<const CDCWire*, int> wireAndOClockDirection :
128 asRange(wireNeighbors.begin(), wireNeighbors.begin() + nWireNeighbors)) {
129 const CDCWire* neighborWire = wireAndOClockDirection.first;
130 int oClockDirection = wireAndOClockDirection.second;
131
132 ConstVectorRange<CDCWireHit*> wireHitRange = findWireHitRange(neighborWire);
133 if (wireHitRange.empty()) {
134 int ccwOClockDirection = oClockDirection - 1;
135 int cwOClockDirection = oClockDirection == 11 ? 0 : oClockDirection + 1;
136 ++missingPrimaryNeighbor[ccwOClockDirection];
137 ++missingPrimaryNeighbor[oClockDirection];
138 ++missingPrimaryNeighbor[cwOClockDirection];
139 }
140 wireHitNeighbors.insert(wireHitNeighbors.end(), wireHitRange.begin(), wireHitRange.end());
141 }
142
143 size_t nPrimaryWireHitNeighbors = wireHitNeighbors.size();
144 nWireNeighbors = 0;
145
146 // Analyse secondary neighborhood
147 for (short oClockDirection : m_consideredSecondaryNeighbors) {
148 MayBePtr<const CDCWire> neighborWire = wireTopology.getSecondaryNeighbor(oClockDirection, wire);
149 if (not neighborWire) continue;
150 if (missingPrimaryNeighbor[oClockDirection] <
151 m_missingPrimaryNeighborThresholds[oClockDirection])
152 continue;
153 wireNeighbors[nWireNeighbors++] = {neighborWire, oClockDirection};
154 }
155
156 std::sort(wireNeighbors.begin(), wireNeighbors.begin() + nWireNeighbors);
157
158 for (std::pair<const CDCWire*, int> wireAndOClockDirection :
159 asRange(wireNeighbors.begin(), wireNeighbors.begin() + nWireNeighbors)) {
160 const CDCWire* neighborWire = wireAndOClockDirection.first;
161 ConstVectorRange<CDCWireHit*> wireHitRange = findWireHitRange(neighborWire);
162 wireHitNeighbors.insert(wireHitNeighbors.end(), wireHitRange.begin(), wireHitRange.end());
163 }
164
166 std::inplace_merge(wireHitNeighbors.begin(),
167 wireHitNeighbors.begin() + nPrimaryWireHitNeighbors,
168 wireHitNeighbors.end(),
169 std::less<CDCWireHit*>());
170
171 return wireHitNeighbors;
172}
Class representing the sense wire arrangement in the whole of the central drift chamber.
TrackingUtilities::MayBePtr< const CDCWire > getSecondaryNeighbor(short oClockDirection, const WireID &wireID) const
Getter for the secondary neighbor of the given wire id.
TrackingUtilities::MayBePtr< const CDCWire > getPrimaryNeighbor(short oClockDirection, const WireID &wireID) const
Getter for the primary neighbor of the given wire id.
static CDCWireTopology & getInstance()
Getter for the singleton instance of the wire topology.
Class representing a sense wire in the central drift chamber.
Definition CDCWire.h:50
The Module parameter list class.
std::map< int, int > m_param_missingPrimaryNeighborThresholdMap
Parameter: A map from o'clock direction to the number of missing primary drift cells.
void prepare(const std::vector< TrackingUtilities::CDCWireHit * > &wireHits)
Precompute the wires of the given wire hits to speed up the searches in the following getPossibleTos ...
TrackingUtilities::CDCWireHit *const * m_preparedWireHitsData
Data pointer of the prepared wire hit vector used to recognize it in getPossibleTos.
void initialize() override
Receive signal at the begin of the event processing and prepare some parameters.
std::vector< TrackingUtilities::CDCWireHit * > getPossibleTos(TrackingUtilities::CDCWireHit *from, const std::vector< TrackingUtilities::CDCWireHit * > &wireHits) const final
Returns a vector containing the neighboring wire hits of the given wire hit out of the sorted range g...
std::array< short, 12 > m_missingPrimaryNeighborThresholds
Array for the number of primary drift cells to be included for the o'clock position at each index.
std::vector< const CDC::CDCWire * > m_preparedWires
Memory for the wires of the prepared wire hit vector.
void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix) override
Expose the set of parameters of the filter to the module parameter list.
std::size_t m_preparedWireHitsSize
Size of the prepared wire hit vector used to recognize it in getPossibleTos.
std::vector< short > m_consideredSecondaryNeighbors
Indices of the considered o'clock positions of the secondary neighborhood.
Class representing a hit wire in the central drift chamber.
Definition CDCWireHit.h:58
Iterator begin() const
Begin of the range for range based for.
Definition Range.h:64
Iterator end() const
End of the range for range based for.
Definition Range.h:68
bool empty() const
Checks if the begin equals the end iterator, hence if the range is empty.
Definition Range.h:72
Base class for filtering the neighborhood of objects.
void addParameter(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module list.
Abstract base class for different kinds of events.