Belle II Software development
ReattachCDCWireHitsToRecoTracksModule.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/modules/reattachCDCWireHitsToRecoTracks/ReattachCDCWireHitsToRecoTracksModule.h>
9
10#include <cdc/topology/CDCWire.h>
11#include <tracking/trackingUtilities/eventdata/trajectories/CDCTrajectory3D.h>
12#include <tracking/trackingUtilities/eventdata/trajectories/CDCTrajectory2D.h>
13#include <tracking/trackingUtilities/eventdata/trajectories/CDCTrajectorySZ.h>
14#include <tracking/trackFitting/fitter/base/TrackFitter.h>
15#include <tracking/dataobjects/RecoHitInformation.h>
16#include <tracking/dbobjects/DAFConfiguration.h>
17
18#include <Math/Vector3D.h>
19#include <Math/Vector2D.h>
20
21using namespace Belle2;
22using namespace CDC;
23using namespace TrackingUtilities;
24
25REG_MODULE(ReattachCDCWireHitsToRecoTracks);
26
28 Module()
29{
30 setDescription(R"DOC(
31Module to loop over low-ADC/TOT CDCWireHits and RecoTracks
32and reattach the hits to the tracks if they are closer
33than a given distance.)DOC");
34 setPropertyFlags(c_ParallelProcessingCertified); // parallel processing
35
36 addParam("CDCWireHitsStoreArrayName", m_CDCWireHitsStoreArrayName,
37 "Name of the input CDCWireHit StoreArray", m_CDCWireHitsStoreArrayName);
38 addParam("inputRecoTracksStoreArrayName", m_inputRecoTracksStoreArrayName,
39 "Name of the input RecoTrack StoreArray", m_inputRecoTracksStoreArrayName);
40 addParam("outputRecoTracksStoreArrayName", m_outputRecoTracksStoreArrayName,
41 "Name of the output RecoTrack StoreArray", m_outputRecoTracksStoreArrayName);
42 addParam("MaximumDistance", m_maximumDistance,
43 "Distance (cm) below which (exclusive) a CDC hit can be reattached to a track", m_maximumDistance);
44 addParam("MinimumADC", m_minimumADC,
45 "ADC above which (inclusive) a CDC hit can be reattached to a track", m_minimumADC);
46 addParam("MinimumTOT", m_minimumTOT,
47 "TOT above which (inclusive) a CDC hit can be reattached to a track", m_minimumTOT);
48 addParam("MaximumAbsD0", m_maximumAbsD0,
49 "Only tracks with an absolute value of d0 below (exclusive) this parameter (cm) are considered", m_maximumAbsD0);
50 addParam("MaximumAbsZ0", m_maximumAbsZ0,
51 "Only tracks with an absolute value of z0 below (exclusive) this parameter (cm) are considered", m_maximumAbsZ0);
52 addParam("trackFitType", m_trackFitType,
53 "Type of track fit algorithm to use the corresponding DAFParameter, the list is defined in DAFConfiguration class.",
55
56}
57
58
66
67
75
77{
78
80
81 for (RecoTrack& recoTrack : m_inputRecoTracks) {
82 // only fit tracks coming from the IP (d0 and z0 from Helix)
83 const ROOT::Math::XYZVector trackPosition(recoTrack.getPositionSeed());
84 const ROOT::Math::XYZVector trackMomentum(recoTrack.getMomentumSeed());
85 const CDCTrajectory3D trajectory(trackPosition, recoTrack.getTimeSeed(), trackMomentum, recoTrack.getChargeSeed());
86 const CDCTrajectory2D& trajectory2D(trajectory.getTrajectory2D());
87 const CDCTrajectorySZ& trajectorySZ(trajectory.getTrajectorySZ());
88 const double d0Estimate(trajectory2D.getClosest(ROOT::Math::XYVector(0, 0)).R());
89 const double z0Estimate(trajectorySZ.getZ0());
90 if (abs(d0Estimate) < m_maximumAbsD0 and abs(z0Estimate) < m_maximumAbsZ0) {
91 if (trackFitter.fit(recoTrack)) {
92 m_mapToHitsOnTrack[&recoTrack] = recoTrack.getSortedCDCHitList();
93 }
94 }
95 }
96
97 // Loop over the CDC hits and find the closest track (if any) whose distance to the hit is smaller than the threshold.
98 // Only the hits with the BadADCOrTOTFlag are considered (these are hits rejected by the TFCDC_WireHitPreparer module).
99 for (CDCWireHit& wireHit : *m_CDCWireHits) {
100 if ((wireHit.getAutomatonCell().hasBadADCOrTOTFlag()) and
101 (wireHit.getHit()->getADCCount() >= m_minimumADC) and
102 (wireHit.getHit()->getTOT() >= m_minimumTOT)) {
103
104 double currentMinimalDistance(m_maximumDistance);
105 RecoTrack* currentClosestTrack(nullptr);
106 ERightLeft currentRlInfo(ERightLeft::c_Unknown);
107
108 for (RecoTrack& recoTrack : m_inputRecoTracks) {
109 if (m_mapToHitsOnTrack.find(&recoTrack) == m_mapToHitsOnTrack.end()) { // Track not considered
110 continue;
111 }
112
113 bool neighborFound(false);
114 for (CDCHit* hitOnTrack : m_mapToHitsOnTrack[&recoTrack]) {
115
116 if (neighborFound) {
117 continue;
118 }
119 // To be added, the hit off track needs to be a neighbor of at least one hit on track
120 if (wireHit.getWire().isPrimaryNeighborWith(*CDCWire::getInstance(*hitOnTrack))) {
121 neighborFound = true;
122 } else {
123 continue;
124 }
125
126 const ReconstructionResults results(reconstruct(wireHit,
127 recoTrack,
128 recoTrack.getRecoHitInformation(hitOnTrack)));
129
130 if (not results.isValid) {
131 continue;
132 }
133
134 if (std::abs(results.distanceToTrack) < currentMinimalDistance) {
135
136 currentMinimalDistance = std::abs(results.distanceToTrack);
137 currentClosestTrack = &recoTrack;
138 currentRlInfo = results.rlInfo;
139
140 B2DEBUG(29, "Background hit close to the track found..." << std::endl
141 << "Layer of the hit on track: " << hitOnTrack->getICLayer() << std::endl
142 << "Layer of the background hit: " << wireHit.getHit()->getICLayer() << std::endl
143 << "ID of the background hit: " << wireHit.getHit()->getID() << std::endl
144 << "ADC of the background hit: " << wireHit.getHit()->getADCCount() << std::endl
145 << "TOT of the background hit: " << wireHit.getHit()->getTOT() << std::endl
146 << "Distance from track to hit: " << results.distanceToTrack << std::endl);
147 }
148 }
149 }
150
151 if (currentMinimalDistance < m_maximumDistance) { // This hit needs to be added to a RecoTrack
152 HitToAddInfo hitToAddInfo;
153 hitToAddInfo.hit = &wireHit;
154 hitToAddInfo.rlInfo = currentRlInfo;
155 m_mapToHitsToAdd[currentClosestTrack].emplace_back(hitToAddInfo);
156 }
157 }
158 }
159}
160
161
163{
164
165 for (RecoTrack& recoTrack : m_inputRecoTracks) {
166
167 RecoTrack* newRecoTrack = recoTrack.copyToStoreArray(m_outputRecoTracks);
168
169 if (m_mapToHitsToAdd.find(&recoTrack) == m_mapToHitsToAdd.end()) { // No hit to add
170
171 newRecoTrack->addHitsFromRecoTrack(&recoTrack);
172
173 } else { // At least one hit to add
174
175 std::unordered_map<CDCWireHit*, double> previousArcLength;
176 std::unordered_map<CDCWireHit*, double> currentArcLength;
177 // Initialise the arc-length maps to zero and unset the taken and background flags.
178 for (HitToAddInfo& hitToAddInfo : m_mapToHitsToAdd[&recoTrack]) {
179 previousArcLength[hitToAddInfo.hit] = 0.0;
180 currentArcLength[hitToAddInfo.hit] = 0.0;
181 (hitToAddInfo.hit)->getAutomatonCell().setTakenFlag(false);
182 (hitToAddInfo.hit)->getAutomatonCell().setBackgroundFlag(false);
183 }
184
185 unsigned int sortingParameter(0);
186 for (CDCHit* hitOnTrack : m_mapToHitsOnTrack[&recoTrack]) {
187 for (HitToAddInfo& hitToAddInfo : m_mapToHitsToAdd[&recoTrack]) {
188 CDCWireHit& hitToAdd = *(hitToAddInfo.hit);
189 if (not hitToAdd.getAutomatonCell().hasTakenFlag()) {
190
191 const ReconstructionResults results(reconstruct(hitToAdd,
192 recoTrack,
193 recoTrack.getRecoHitInformation(hitOnTrack)));
194
195 previousArcLength[&hitToAdd] = currentArcLength[&hitToAdd];
196 currentArcLength[&hitToAdd] = results.arcLength;
197
198 B2DEBUG(29, "Hit to be added..." << std::endl
199 << "Layer of the hit on track: " << hitOnTrack->getICLayer() << std::endl
200 << "Layer of the background hit: " << hitToAdd.getHit()->getICLayer() << std::endl
201 << "ID of the background hit: " << hitToAdd.getHit()->getID() << std::endl
202 << "ADC of the background hit: " << hitToAdd.getHit()->getADCCount() << std::endl
203 << "TOT of the background hit: " << hitToAdd.getHit()->getTOT() << std::endl
204 << "Distance from track to hit: " << results.distanceToTrack << std::endl
205 << "Previous arc length of the hit: " << previousArcLength[&hitToAdd] << std::endl
206 << "Current arc length of the hit: " << currentArcLength[&hitToAdd] << std::endl);
207
208 if ((previousArcLength[&hitToAdd] > 0) and (currentArcLength[&hitToAdd] < 0)) { // Hit needs to be added here.
209
211 newRecoTrack->addCDCHit(hitToAdd.getHit(), sortingParameter, rl, RecoHitInformation::c_ReattachCDCWireHitsToRecoTracks);
212 hitToAdd.getAutomatonCell().setTakenFlag(true);
213 ++sortingParameter;
214
215 }
216 }
217 }
218 const RecoHitInformation::RightLeftInformation rl = recoTrack.getRecoHitInformation(hitOnTrack)->getRightLeftInformation();
219 const RecoHitInformation::OriginTrackFinder foundBy = recoTrack.getRecoHitInformation(hitOnTrack)->getFoundByTrackFinder();
220 newRecoTrack->addCDCHit(hitOnTrack, sortingParameter, rl, foundBy);
221 //TODO: In the (rare) case where more than one hit are added between the same 2 hits on track, one should order them w.r.t. the arcLength.
222 ++sortingParameter;
223 }
224 }
225 }
226}
227
228
230 const CDCWireHit& wireHit,
231 const RecoTrack& recoTrack, const RecoHitInformation* const recoHitInformation) const
232{
233 ReconstructionResults results;
234
235 try {
236
237 const genfit::MeasuredStateOnPlane& mSoP(recoTrack.getMeasuredStateOnPlaneFromRecoHit(recoHitInformation));
238 const ROOT::Math::XYZVector trackPosition(mSoP.getPos());
239 const ROOT::Math::XYZVector trackMomentum(mSoP.getMom());
240 const CDCTrajectory3D trajectory(trackPosition, mSoP.getTime(), trackMomentum, mSoP.getCharge());
241
242 const CDCTrajectory2D& trajectory2D(trajectory.getTrajectory2D());
243 const CDCTrajectorySZ& trajectorySZ(trajectory.getTrajectorySZ());
244
245 ROOT::Math::XYVector recoPos2D;
246 if (wireHit.isAxial()) {
247 recoPos2D = wireHit.reconstruct2D(trajectory2D);
248 } else {
249 const CDCWire& wire(wireHit.getWire());
250 const ROOT::Math::XYVector& posOnXYPlane(wireHit.reconstruct2D(trajectory2D));
251
252 const double arcLength(trajectory2D.calcArcLength2D(posOnXYPlane));
253 const double z(trajectorySZ.mapSToZ(arcLength));
254
255 const ROOT::Math::XYVector& wirePos2DAtZ(wire.getWirePos2DAtZ(z));
256
257 const ROOT::Math::XYVector& recoPosOnTrajectory(trajectory2D.getClosest(wirePos2DAtZ));
258 const double driftLength(wireHit.getRefDriftLength());
259 ROOT::Math::XYVector disp2D(recoPosOnTrajectory - wirePos2DAtZ);
260 if (disp2D.R() > 0.0) {
261 disp2D *= (driftLength / disp2D.R());
262 }
263 recoPos2D = wirePos2DAtZ + disp2D;
264 }
265
266
267 results.arcLength = trajectory2D.calcArcLength2D(recoPos2D);
268 results.z = trajectorySZ.mapSToZ(results.arcLength);
269 results.distanceToTrack = trajectory2D.getDist2D(recoPos2D);
270
271 const ROOT::Math::XYZVector hitPosition(wireHit.getWire().getWirePos3DAtZ(trackPosition.z()));
272
273 ROOT::Math::XYZVector trackPosToWire{hitPosition - trackPosition};
274 results.rlInfo = VectorUtil::isRightOrLeftOf(VectorUtil::getXYVector(trackPosToWire), VectorUtil::getXYVector(trackMomentum));
275
276 results.isValid = true;
277
278 } catch (...) {
279 B2WARNING("Distance measurement does not work.");
280 results.isValid = false;
281 }
282
283 return results;
284}
285
286
288 ERightLeft rlInfo) const
289{
290 using RightLeftInformation = RecoHitInformation::RightLeftInformation;
291 if (rlInfo == ERightLeft::c_Left) {
292 return RightLeftInformation::c_left;
293 } else if (rlInfo == ERightLeft::c_Right) {
294 return RightLeftInformation::c_right;
295 } else if (rlInfo == ERightLeft::c_Invalid) {
296 return RightLeftInformation::c_invalidRightLeftInformation;
297 } else {
298 return RightLeftInformation::c_undefinedRightLeftInformation;
299 }
300}
Class containing the result of the unpacker in raw data and the result of the digitizer in simulation...
Definition CDCHit.h:40
unsigned short getICLayer() const
Getter for iCLayer (0-55).
Definition CDCHit.h:178
unsigned short getID() const
Getter for encoded wire number.
Definition CDCHit.h:193
unsigned short getADCCount() const
Getter for integrated charge.
Definition CDCHit.h:230
unsigned short getTOT() const
Getter for TOT.
Definition CDCHit.h:248
Class representing a sense wire in the central drift chamber.
Definition CDCWire.h:50
ROOT::Math::XYVector getWirePos2DAtZ(const double z) const
Gives the xy projected position of the wire at the given z coordinate.
Definition CDCWire.h:184
ROOT::Math::XYZVector getWirePos3DAtZ(const double z) const
Gives position of the wire at the given z coordinate.
Definition CDCWire.h:188
static const CDCWire * getInstance(const WireID &wireID)
Getter from the wireID convenience object. Does not construct a new object.
Definition CDCWire.cc:24
ETrackFitType
Enum for identifying the type of track fit algorythm ( or cosmic)
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition Module.cc:208
Module()
Constructor.
Definition Module.cc:30
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition Module.h:80
std::string m_outputRecoTracksStoreArrayName
Name of the output RecoTrack StoreArray.
std::string m_CDCWireHitsStoreArrayName
Name of the input CDCWireHit StoreWrappedObjPtr.
ReattachCDCWireHitsToRecoTracksModule()
Constructor of the module. Setting up parameters and description.
ReconstructionResults reconstruct(const TrackingUtilities::CDCWireHit &wireHit, const RecoTrack &recoTrack, const RecoHitInformation *recoHitInformation) const
Compute distance from a CDCWireHit to a RecoTrack using the mSoP found with a RecoHitInformation.
TrackingUtilities::StoreWrappedObjPtr< std::vector< TrackingUtilities::CDCWireHit > > m_CDCWireHits
Input CDCWireHits.
void event() override
Event processing, combine store array.
int m_minimumADC
ADC above which (inclusive) a CDC hit can be reattached to a track.
std::string m_inputRecoTracksStoreArrayName
Name of the input RecoTrack StoreArray.
std::unordered_map< RecoTrack *, std::vector< CDCHit * > > m_mapToHitsOnTrack
Map from a RecoTrack ptr to the vector of the hits that belong to this track.
double m_maximumDistance
Distance (cm) below which (exclusive) a CDC hit can be reattached to a track.
int m_minimumTOT
TOT above which (inclusive) a CDC hit can be reattached to a track.
void addHits()
Add the selected CDC hits to the RecoTracks.
double m_maximumAbsD0
Only tracks with an absolute value of d0 below (exclusive) this parameter (cm) are considered.
void findHits()
Find the hits that can be added to the RecoTracks.
RecoHitInformation::RightLeftInformation rightLeftInformationTranslator(TrackingUtilities::ERightLeft rlInfo) const
Translate a TrackingUtilities::ERightLeft into a RecoHitInformation::RightLeftInformation.
short m_trackFitType
Track Fit type to select the proper DAFParameter from DAFConfiguration; by default c_CDConly.
std::unordered_map< RecoTrack *, std::vector< HitToAddInfo > > m_mapToHitsToAdd
Map from a RecoTrack ptr to the vector of the hits that need to be added to this track.
double m_maximumAbsZ0
Only tracks with an absolute value of z0 below (exclusive) this parameter (cm) are considered.
This class stores additional information to every CDC/SVD/PXD hit stored in a RecoTrack.
OriginTrackFinder
The TrackFinder which has added the hit to the track.
RightLeftInformation
The RightLeft information of the hit which is only valid for CDC hits.
This is the Reconstruction Event-Data Model Track.
Definition RecoTrack.h:79
size_t addHitsFromRecoTrack(const RecoTrack *recoTrack, unsigned int sortingParameterOffset=0, bool reversed=false, std::optional< double > optionalMinimalWeight=std::nullopt)
Add all hits from another RecoTrack to this RecoTrack.
Definition RecoTrack.cc:240
bool addCDCHit(const UsedCDCHit *cdcHit, const unsigned int sortingParameter, RightLeftInformation rightLeftInformation=RightLeftInformation::c_undefinedRightLeftInformation, OriginTrackFinder foundByTrackFinder=OriginTrackFinder::c_undefinedTrackFinder)
Adds a cdc hit with the given information to the reco track.
Definition RecoTrack.h:243
RecoTrack * copyToStoreArray(StoreArray< RecoTrack > &storeArray) const
Append a new RecoTrack to the given store array and copy its general properties, but not the hits the...
Definition RecoTrack.cc:529
static void registerRequiredRelations(StoreArray< RecoTrack > &recoTracks, std::string const &pxdHitsStoreArrayName="", std::string const &svdHitsStoreArrayName="", std::string const &cdcHitsStoreArrayName="", std::string const &bklmHitsStoreArrayName="", std::string const &eklmHitsStoreArrayName="", std::string const &recoHitInformationStoreArrayName="")
Convenience method which registers all relations required to fully use a RecoTrack.
Definition RecoTrack.cc:53
const genfit::MeasuredStateOnPlane & getMeasuredStateOnPlaneFromRecoHit(const RecoHitInformation *recoHitInfo, const genfit::AbsTrackRep *representation=nullptr) const
Return genfit's MeasuredStateOnPlane on plane for associated with one RecoHitInformation.
Definition RecoTrack.cc:579
Algorithm class to handle the fitting of RecoTrack objects.
bool fit(RecoTrack &recoTrack, genfit::AbsTrackRep *trackRepresentation, bool resortHits=false) const
Fit a reco track with a given non-default track representation.
void setTakenFlag(bool setTo=true)
Sets the taken flag to the given value. Default value true.
bool hasTakenFlag() const
Gets the current state of the taken marker flag.
Particle trajectory as it is seen in xy projection represented as a circle.
ROOT::Math::XYVector getClosest(const ROOT::Math::XYVector &point) const
Calculates the closest approach on the trajectory to the given point.
double calcArcLength2D(const ROOT::Math::XYVector &point) const
Calculate the travel distance from the start position of the trajectory.
double getDist2D(const ROOT::Math::XYVector &point) const
Calculates the distance from the point to the trajectory as seen from the xy projection.
Particle full three dimensional trajectory.
CDCTrajectory2D getTrajectory2D() const
Getter for the two dimensional trajectory.
CDCTrajectorySZ getTrajectorySZ() const
Getter for the sz trajectory.
double mapSToZ(const double s=0) const
Translates the travel distance to the z coordinate.
double getZ0() const
Getter for the z coordinate at zero travel distance.
Class representing a hit wire in the central drift chamber.
Definition CDCWireHit.h:56
const CDCHit * getHit() const
Getter for the CDCHit pointer into the StoreArray.
Definition CDCWireHit.h:160
double getRefDriftLength() const
Getter for the drift length at the reference position of the wire.
Definition CDCWireHit.h:225
bool isAxial() const
Indicator if the underlying wire is axial.
Definition CDCWireHit.h:198
const CDC::CDCWire & getWire() const
Getter for the CDCWire the hit is located on.
Definition CDCWireHit.h:169
AutomatonCell & getAutomatonCell() const
Mutable getter for the automaton cell.
Definition CDCWireHit.h:287
ROOT::Math::XYVector reconstruct2D(const CDCTrajectory2D &trajectory2D) const
Reconstructs a position of primary ionisation on the drift circle.
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition Module.h:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
Abstract base class for different kinds of events.
Internal structure to store the information about a hit to be added.
TrackingUtilities::ERightLeft rlInfo
Right-left information of the hit.
TrackingUtilities::CDCWireHit * hit
Pointer the hit to be added.