Belle II Software development
StereoHitTrackQuadTreeMatcher.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/collectors/matchers/StereoHitTrackQuadTreeMatcher.h>
9
10#include <tracking/trackFindingCDC/hough/z0_tanLambda/HitZ0TanLambdaLegendre.h>
11#include <tracking/trackFindingCDC/hough/quadratic/HitQuadraticLegendre.h>
12#include <tracking/trackFindingCDC/hough/hyperbolic/HitHyperHough.h>
13
14#include <tracking/trackingUtilities/eventdata/tracks/CDCTrack.h>
15
16#include <tracking/trackingUtilities/eventdata/hits/CDCRLWireHit.h>
17#include <tracking/trackingUtilities/eventdata/hits/CDCWireHit.h>
18#include <tracking/trackingUtilities/eventdata/trajectories/CDCTrajectory2D.h>
19
20#include <tracking/trackingUtilities/ca/AutomatonCell.h>
21
22#include <framework/core/ModuleParamList.templateDetails.h>
23
24#include <tracking/trackingUtilities/utilities/StringManipulation.h>
25
26#include <Math/Vector3D.h>
27
28#include <utility>
29
30using namespace Belle2;
31using namespace CDC;
32using namespace TrackFindingCDC;
33using namespace TrackingUtilities;
34
35template <class AQuadTree>
37 const std::string& prefix)
39 Super::exposeParameters(moduleParamList, prefix);
40
41 moduleParamList->addParameter(prefixed(prefix, "level"), m_param_quadTreeLevel,
42 "The number of levels for the quad tree search.",
44
45 moduleParamList->addParameter(prefixed(prefix, "minimumNumberOfHits"), m_param_minimumNumberOfHits,
46 "The minimum number of hits in a quad tree bin to be called as result.",
48
49 moduleParamList->addParameter(prefixed(prefix, "writeDebugInformation"), m_param_writeDebugInformation,
50 "Set to true to output debug information.",
52
53 moduleParamList->addParameter(prefixed(prefix, "checkForB2BTracks"),
55 "Set to false to skip the check for back-2-back tracks "
56 "(good for cosmics).",
58
59 moduleParamList->addParameter(prefixed(prefix, "checkForInWireBoundsFactor"),
61 "Used to scale the CDC before checking "
62 "whether hits are in the CDC z bounds.",
64}
65
66
67template <class AQuadTree>
75
76
77template <class AQuadTree>
84
85template <class AQuadTree>
86void StereoHitTrackQuadTreeMatcher<AQuadTree>::match(CDCTrack& track, const std::vector<CDCRLWireHit>& rlWireHits,
87 std::vector<Super::WeightedRelationItem>& relationsForCollector)
88{
89 // TODO: Extract this into smaller steps
90 // TODO: Split the filtering from the rest.
91 // This means this method would output WeightedRelations based on the quad tree decision and a second filter step
92 // can be applied on these weighted relations
93
94 // Reconstruct the hits to the track
95 const CDCTrajectory2D& trajectory2D = track.getStartTrajectory3D().getTrajectory2D();
96 const bool isCurler = trajectory2D.isCurler();
97
98 using CDCRecoHitWithRLPointer = std::pair<CDCRecoHit3D, const CDCRLWireHit*>;
99 std::vector<CDCRecoHitWithRLPointer> recoHits;
100 recoHits.reserve(rlWireHits.size() + track.size());
101
102 /*
103 * Use the given trajectory to reconstruct the 2d hits in the vector in z direction
104 * to match the trajectory perfectly. Then add the newly created reconstructed 3D hit to the given list.
105 */
106 for (const CDCRLWireHit& rlWireHit : rlWireHits) {
107 if (rlWireHit.getWireHit().getAutomatonCell().hasTakenFlag()) continue;
108
109 const CDCWire& wire = rlWireHit.getWire();
110 const WireLine& wireLine = wire.getWireLine();
111 double signedDriftLength = rlWireHit.getSignedRefDriftLength();
112 for (const ROOT::Math::XYZVector& recoPos3D : trajectory2D.reconstructBoth3D(wireLine, signedDriftLength)) {
113 // Skip hits out of CDC
114 if (not wire.isInCellZBounds(recoPos3D, m_param_checkForInWireBoundsFactor)) {
115 continue;
116 }
117
118 // If the track is a curler, shift all perpS values to positive ones.
119 // Else do not use this hit if m_param_checkForB2BTracks is enabled.
120 double perpS = trajectory2D.calcArcLength2D(VectorUtil::getXYVector(recoPos3D));
121 if (perpS < 0) {
122 if (isCurler) {
123 perpS += trajectory2D.getArcLength2DPeriod();
124 } else if (m_param_checkForB2BTracks) {
125 continue;
126 }
127 }
128 recoHits.emplace_back(CDCRecoHit3D(rlWireHit, recoPos3D, perpS), &rlWireHit);
129 }
130 }
131
132 // Also add already found stereo hits of the track
133 for (const CDCRecoHit3D& recoHit : track) {
134 if (not recoHit.isAxial()) {
135 recoHit.getWireHit().getAutomatonCell().setAssignedFlag();
136 const CDCRLWireHit& rlWireHit = recoHit.getRLWireHit();
137 recoHits.emplace_back(recoHit, &rlWireHit);
138 }
139 }
140
141 // Do the tree finding
142 m_quadTreeInstance.seed(recoHits);
143
146 }
147
148 const auto& foundStereoHitsWithNode = m_quadTreeInstance.findSingleBest(m_param_minimumNumberOfHits);
149 m_quadTreeInstance.fell();
150
151 if (foundStereoHitsWithNode.size() != 1) {
152 return;
153 }
154
155 // There is the possibility that we have added one cdc hits twice (as left and right one). We search for those cases here:
156 auto foundStereoHits = foundStereoHitsWithNode[0].second;
157 const auto& node = foundStereoHitsWithNode[0].first;
158
160 std::vector<CDCRecoHit3D> allHits;
161 std::vector<CDCRecoHit3D> foundHits;
162 // Turn vector of pairs into vector of first items
163 for (const CDCRecoHitWithRLPointer& recoHitWithRL : recoHits) {
164 const CDCRecoHit3D& recoHit3D = recoHitWithRL.first;
165 allHits.push_back(recoHit3D);
166 }
167 for (const CDCRecoHitWithRLPointer& recoHitWithRL : foundStereoHits) {
168 const CDCRecoHit3D& recoHit3D = recoHitWithRL.first;
169 foundHits.push_back(recoHit3D);
170 }
171 m_quadTreeInstance.drawDebugPlot(allHits, foundHits, node);
172 }
173
174 // Remove all assigned hits, which where already found before (and do not need to be added again)
175 const auto& isAssignedHit = [](const CDCRecoHitWithRLPointer & recoHitWithRLPointer) {
176 const CDCRecoHit3D& recoHit3D = recoHitWithRLPointer.first;
177 const auto& automatonCell = recoHit3D.getWireHit().getAutomatonCell();
178 return automatonCell.hasAssignedFlag();
179 };
180
181 foundStereoHits.erase(std::remove_if(foundStereoHits.begin(),
182 foundStereoHits.end(),
183 isAssignedHit),
184 foundStereoHits.end());
185
186 // Sort the found stereo hits by same CDCHit and smaller distance to the node
187 auto sortByHitAndNodeCenterDistance = [node](const CDCRecoHitWithRLPointer & lhs,
188 const CDCRecoHitWithRLPointer & rhs) {
189
190
191 const CDCRecoHit3D& rhsRecoHit = rhs.first;
192 const CDCRecoHit3D& lhsRecoHit = lhs.first;
193
194 const CDCWireHit& rhsWireHit = rhsRecoHit.getWireHit();
195 const CDCWireHit& lhsWireHit = lhsRecoHit.getWireHit();
196
197 if (lhsWireHit < rhsWireHit) {
198 return true;
199 } else if (rhsWireHit < lhsWireHit) {
200 return false;
201 } else {
202 return AQuadTree::DecisionAlgorithm::BoxAlgorithm::compareDistances(node, lhsRecoHit, rhsRecoHit); //returns true if lhs < rhs
203 }
204 };
205
206 const auto& sameHitComparer = [](const CDCRecoHitWithRLPointer & lhs,
207 const CDCRecoHitWithRLPointer & rhs) {
208 const CDCRecoHit3D& rhsRecoHit = rhs.first;
209 const CDCRecoHit3D& lhsRecoHit = lhs.first;
210
211 return lhsRecoHit.getWireHit() == rhsRecoHit.getWireHit();
212 };
213
214 std::sort(foundStereoHits.begin(),
215 foundStereoHits.end(),
216 sortByHitAndNodeCenterDistance);
217
218 // If the same hit is added as right and left hypothesis, do only use the one with the smaller distance to the node.
219 foundStereoHits.erase(std::unique(foundStereoHits.begin(),
220 foundStereoHits.end(),
221 sameHitComparer),
222 foundStereoHits.end());
223
224 // Add the found stereo hits to the relation vector. In the moment, all hits get the same weight (may change later).
225 for (const CDCRecoHitWithRLPointer& recoHitWithRLPointer : foundStereoHits) {
226 const CDCRLWireHit* rlWireHit = recoHitWithRLPointer.second;
227 relationsForCollector.emplace_back(&track, foundStereoHits.size(), rlWireHit);
228 }
229}
230
231template <class AQuadTree>
233{
234 std::string outputFileName = "quadTreeContent_call_" + std::to_string(m_numberOfPassedDebugCalls) + ".root";
235 m_quadTreeInstance.writeDebugInfoToFile(outputFileName);
236
238}
239
Class representing a sense wire in the central drift chamber.
Definition CDCWire.h:50
bool isInCellZBounds(const ROOT::Math::XYZVector &pos3D, const double factor=1) const
Checks whether the position is in the z bounds of the drift cell (scaled by the factor) surrounding t...
Definition CDCWire.h:287
const WireLine & getWireLine() const
Getter for the wire line representation of the wire.
Definition CDCWire.h:180
A three dimensional limited line represented by its closest approach to the z-axes (reference positio...
Definition WireLine.h:33
The Module parameter list class.
A matcher algorithm for using a stereo quad tree for matching rl tagged wire hits to tracks.
void initialize() override
Initialize the filter and the quad tree.
void terminate() override
Terminate the filter and the quad tree.
unsigned int m_numberOfPassedDebugCalls
Store the number of passed calls to the debug function.
void match(TrackingUtilities::CDCTrack &track, const std::vector< TrackingUtilities::CDCRLWireHit > &rlWireHits, std::vector< Super::WeightedRelationItem > &relationsForCollector) override
Create a QuadTree and fill with each unused stereo hit (to be exact: twice for each stereo hit - righ...
void writeDebugInformation()
Use the writeDebugInformation function of the quad tree to write the tree into a root file with a asc...
void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix) override
Expose the parameters to the module.
bool hasAssignedFlag() const
Gets the current state of the already assigned marker flag.
Class representing an oriented hit wire including a hypotheses whether the causing track passes left ...
Class representing a three dimensional reconstructed hit.
const CDCWireHit & getWireHit() const
Getter for the wire hit.
Class representing a sequence of three dimensional reconstructed hits.
Definition CDCTrack.h:37
Particle trajectory as it is seen in xy projection represented as a circle.
std::array< ROOT::Math::XYZVector, 2 > reconstructBoth3D(const CDC::WireLine &wireLine, double distance=0.0, double z=0) const
Gives the two three dimensional points where the drift circle touches the wire line.
double calcArcLength2D(const ROOT::Math::XYVector &point) const
Calculate the travel distance from the start position of the trajectory.
bool isCurler(double factor=1) const
Checks if the trajectory leaves the outer radius of the CDC times the given tolerance factor.
double getArcLength2DPeriod() const
Getter for the arc length for one round trip around the trajectory.
Class representing a hit wire in the central drift chamber.
Definition CDCWireHit.h:56
AutomatonCell & getAutomatonCell() const
Mutable getter for the automaton cell.
Definition CDCWireHit.h:287
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.