Belle II Software prerelease-11-00-00d
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#include <cassert>
27
28using namespace Belle2;
29using namespace CDC;
30using namespace TrackFindingCDC;
31using namespace TrackingUtilities;
32
34
36
38
40 const std::string& prefix)
41{
42 moduleParamList
43 ->addParameter(prefixed(prefix, "missingPrimaryNeighborThresholds"),
45 "Map of o'clock directions to number of missing drift cells "
46 "in the primary neighborhood to trigger the inclusion of secondary neighbors "
47 "in that very o'clock direction",
49}
50
52{
54 for (short oClockDirection = 0; oClockDirection < 12; oClockDirection++) {
55 m_missingPrimaryNeighborThresholds[oClockDirection] = 3;
56 if (m_param_missingPrimaryNeighborThresholdMap.count(oClockDirection)) {
57 m_missingPrimaryNeighborThresholds[oClockDirection] =
59 }
60 }
61
63 for (short oClockDirection : {5, 6, 7, 4, 8, 3, 9, 2, 10, 1, 0, 11}) {
64 if (m_missingPrimaryNeighborThresholds[oClockDirection] < 3) {
65 m_consideredSecondaryNeighbors.push_back(oClockDirection);
66 }
67 }
68}
69
70void BridgingWireHitRelationFilter::prepare(const std::vector<CDCWireHit*>& wireHits)
71{
72 m_preparedWires.clear();
73 m_preparedWires.reserve(wireHits.size());
74 for (const CDCWireHit* wireHit : wireHits) {
75 m_preparedWires.push_back(&wireHit->getWire());
76 }
77 m_preparedWireHitsData = wireHits.data();
78 m_preparedWireHitsSize = wireHits.size();
79}
80
82 CDCWireHit* from,
83 const std::vector<CDCWireHit*>& wireHits) const
84{
85 assert(std::is_sorted(wireHits.begin(), wireHits.end(), LessOf<Deref>()) &&
86 "Expected wire hits to be sorted");
87
88 // Use the wires precomputed by prepare() when called with the prepared vector.
89 // The wire hits are sorted by the address of their wire such that a search in the
90 // contiguous wire array gives the same ranges without dereferencing the wire hits.
91 const bool prepared =
92 wireHits.data() == m_preparedWireHitsData and wireHits.size() == m_preparedWireHitsSize;
93
94 auto findWireHitRange = [&](const CDCWire * neighborWire) -> ConstVectorRange<CDCWireHit*> {
95 if (prepared)
96 {
97 const auto itRange = std::equal_range(m_preparedWires.begin(), m_preparedWires.end(), neighborWire);
98 return {
99 wireHits.begin() + (itRange.first - m_preparedWires.begin()),
100 wireHits.begin() + (itRange.second - m_preparedWires.begin())};
101 }
102 return ConstVectorRange<CDCWireHit*>{
103 std::equal_range(wireHits.begin(), wireHits.end(), neighborWire, LessOf<Deref>())
104 };
105 };
106
107 // Stack buffer for the wire neighbors - at most 6 primary
108 // respectively 12 secondary neighbors can be collected
109 std::array<std::pair<const CDCWire*, int>, 12> wireNeighbors;
110 int nWireNeighbors = 0;
111
112 std::vector<CDCWireHit*> wireHitNeighbors;
113 wireHitNeighbors.reserve(12);
114
115 std::array<short, 12> missingPrimaryNeighbor = {0};
116
117 const CDCWireTopology& wireTopology = CDCWireTopology::getInstance();
118
119 const CDCWire& wire = from->getWire();
120
121 // Analyse primary neighborhood - sorted such that the wire hits relations are most likely sorted.
122 for (short oClockDirection : {5, 7, 3, 9, 1, 11}) {
123 MayBePtr<const CDCWire> neighborWire = wireTopology.getPrimaryNeighbor(oClockDirection, wire);
124 if (neighborWire) wireNeighbors[nWireNeighbors++] = {neighborWire, oClockDirection};
125 }
126
127 std::sort(wireNeighbors.begin(), wireNeighbors.begin() + nWireNeighbors);
128
129 for (std::pair<const CDCWire*, int> wireAndOClockDirection :
130 asRange(wireNeighbors.begin(), wireNeighbors.begin() + nWireNeighbors)) {
131 const CDCWire* neighborWire = wireAndOClockDirection.first;
132 int oClockDirection = wireAndOClockDirection.second;
133
134 ConstVectorRange<CDCWireHit*> wireHitRange = findWireHitRange(neighborWire);
135 if (wireHitRange.empty()) {
136 int ccwOClockDirection = oClockDirection - 1;
137 int cwOClockDirection = oClockDirection == 11 ? 0 : oClockDirection + 1;
138 ++missingPrimaryNeighbor[ccwOClockDirection];
139 ++missingPrimaryNeighbor[oClockDirection];
140 ++missingPrimaryNeighbor[cwOClockDirection];
141 }
142 wireHitNeighbors.insert(wireHitNeighbors.end(), wireHitRange.begin(), wireHitRange.end());
143 }
144
145 size_t nPrimaryWireHitNeighbors = wireHitNeighbors.size();
146 nWireNeighbors = 0;
147
148 // Analyse secondary neighborhood
149 for (short oClockDirection : m_consideredSecondaryNeighbors) {
150 MayBePtr<const CDCWire> neighborWire = wireTopology.getSecondaryNeighbor(oClockDirection, wire);
151 if (not neighborWire) continue;
152 if (missingPrimaryNeighbor[oClockDirection] <
153 m_missingPrimaryNeighborThresholds[oClockDirection])
154 continue;
155 wireNeighbors[nWireNeighbors++] = {neighborWire, oClockDirection};
156 }
157
158 std::sort(wireNeighbors.begin(), wireNeighbors.begin() + nWireNeighbors);
159
160 for (std::pair<const CDCWire*, int> wireAndOClockDirection :
161 asRange(wireNeighbors.begin(), wireNeighbors.begin() + nWireNeighbors)) {
162 const CDCWire* neighborWire = wireAndOClockDirection.first;
163 ConstVectorRange<CDCWireHit*> wireHitRange = findWireHitRange(neighborWire);
164 wireHitNeighbors.insert(wireHitNeighbors.end(), wireHitRange.begin(), wireHitRange.end());
165 }
166
168 std::inplace_merge(wireHitNeighbors.begin(),
169 wireHitNeighbors.begin() + nPrimaryWireHitNeighbors,
170 wireHitNeighbors.end(),
171 std::less<CDCWireHit*>());
172
173 return wireHitNeighbors;
174}
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.