Belle II Software  release-08-01-10
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 <tracking/trackFindingCDC/topology/CDCWire.h>
11 #include <tracking/trackFindingCDC/geometry/Vector3D.h>
12 #include <tracking/trackFindingCDC/geometry/Vector2D.h>
13 #include <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectory3D.h>
14 #include <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectory2D.h>
15 #include <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectorySZ.h>
16 #include <tracking/trackFitting/fitter/base/TrackFitter.h>
17 #include <tracking/dataobjects/RecoHitInformation.h>
18 
19 using namespace Belle2;
20 using namespace TrackFindingCDC;
21 
22 REG_MODULE(ReattachCDCWireHitsToRecoTracks);
23 
25  Module()
26 {
27  setDescription(R"DOC(
28 Module to loop over low-ADC/TOT CDCWireHits and RecoTracks
29 and reattach the hits to the tracks if they are closer
30 than a given distance.)DOC");
31  setPropertyFlags(c_ParallelProcessingCertified); // parallel processing
32 
33  addParam("CDCWireHitsStoreArrayName", m_CDCWireHitsStoreArrayName,
34  "Name of the input CDCWireHit StoreArray", m_CDCWireHitsStoreArrayName);
35  addParam("inputRecoTracksStoreArrayName", m_inputRecoTracksStoreArrayName,
36  "Name of the input RecoTrack StoreArray", m_inputRecoTracksStoreArrayName);
37  addParam("outputRecoTracksStoreArrayName", m_outputRecoTracksStoreArrayName,
38  "Name of the output RecoTrack StoreArray", m_outputRecoTracksStoreArrayName);
39  addParam("MaximumDistance", m_maximumDistance,
40  "Distance (cm) below which (exclusive) a CDC hit can be reattached to a track", m_maximumDistance);
41  addParam("MinimumADC", m_minimumADC,
42  "ADC above which (inclusive) a CDC hit can be reattached to a track", m_minimumADC);
43  addParam("MinimumTOT", m_minimumTOT,
44  "TOT above which (inclusive) a CDC hit can be reattached to a track", m_minimumTOT);
45  addParam("MaximumAbsD0", m_maximumAbsD0,
46  "Only tracks with an absolute value of d0 below (exclusive) this parameter (cm) are considered", m_maximumAbsD0);
47  addParam("MaximumAbsZ0", m_maximumAbsZ0,
48  "Only tracks with an absolute value of z0 below (exclusive) this parameter (cm) are considered", m_maximumAbsZ0);
49 }
50 
51 
53 {
58 }
59 
60 
62 {
63  m_mapToHitsOnTrack.clear();
64  m_mapToHitsToAdd.clear();
65  findHits();
66  addHits();
67 }
68 
70 {
71 
72  TrackFitter trackFitter;
73 
74  for (RecoTrack& recoTrack : m_inputRecoTracks) {
75  // only fit tracks coming from the IP (d0 and z0 from Helix)
76  const Vector3D trackPosition(recoTrack.getPositionSeed());
77  const Vector3D trackMomentum(recoTrack.getMomentumSeed());
78  const CDCTrajectory3D trajectory(trackPosition, recoTrack.getTimeSeed(), trackMomentum, recoTrack.getChargeSeed());
79  const CDCTrajectory2D& trajectory2D(trajectory.getTrajectory2D());
80  const CDCTrajectorySZ& trajectorySZ(trajectory.getTrajectorySZ());
81  const double d0Estimate((trajectory2D.getClosest(Vector2D(0, 0))).norm());
82  const double z0Estimate(trajectorySZ.getZ0());
83  if (abs(d0Estimate) < m_maximumAbsD0 and abs(z0Estimate) < m_maximumAbsZ0) {
84  if (trackFitter.fit(recoTrack)) {
85  m_mapToHitsOnTrack[&recoTrack] = recoTrack.getSortedCDCHitList();
86  }
87  }
88  }
89 
90  // Loop over the CDC hits and find the closest track (if any) whose distance to the hit is smaller than the threshold.
91  // Only the hits with the BadADCOrTOTFlag are considered (these are hits rejected by the TFCDC_WireHitPreparer module).
92  for (CDCWireHit& wireHit : *m_CDCWireHits) {
93  if ((wireHit.getAutomatonCell().hasBadADCOrTOTFlag()) and
94  (wireHit.getHit()->getADCCount() >= m_minimumADC) and
95  (wireHit.getHit()->getTOT() >= m_minimumTOT)) {
96 
97  double currentMinimalDistance(m_maximumDistance);
98  RecoTrack* currentClosestTrack(nullptr);
99  ERightLeft currentRlInfo(ERightLeft::c_Unknown);
100 
101  for (RecoTrack& recoTrack : m_inputRecoTracks) {
102  if (m_mapToHitsOnTrack.find(&recoTrack) == m_mapToHitsOnTrack.end()) { // Track not considered
103  continue;
104  }
105 
106  bool neighborFound(false);
107  for (CDCHit* hitOnTrack : m_mapToHitsOnTrack[&recoTrack]) {
108 
109  if (neighborFound) {
110  continue;
111  }
112  // To be added, the hit off track needs to be a neighbor of at least one hit on track
113  if (wireHit.getWire().isPrimaryNeighborWith(*CDCWire::getInstance(*hitOnTrack))) {
114  neighborFound = true;
115  } else {
116  continue;
117  }
118 
119  const ReconstructionResults results(reconstruct(wireHit,
120  recoTrack,
121  recoTrack.getRecoHitInformation(hitOnTrack)));
122 
123  if (not results.isValid) {
124  continue;
125  }
126 
127  if (std::abs(results.distanceToTrack) < currentMinimalDistance) {
128 
129  currentMinimalDistance = std::abs(results.distanceToTrack);
130  currentClosestTrack = &recoTrack;
131  currentRlInfo = results.rlInfo;
132 
133  B2DEBUG(29, "Background hit close to the track found..." << std::endl
134  << "Layer of the hit on track: " << hitOnTrack->getICLayer() << std::endl
135  << "Layer of the background hit: " << wireHit.getHit()->getICLayer() << std::endl
136  << "ID of the background hit: " << wireHit.getHit()->getID() << std::endl
137  << "ADC of the background hit: " << wireHit.getHit()->getADCCount() << std::endl
138  << "TOT of the background hit: " << wireHit.getHit()->getTOT() << std::endl
139  << "Distance from track to hit: " << results.distanceToTrack << std::endl);
140  }
141  }
142  }
143 
144  if (currentMinimalDistance < m_maximumDistance) { // This hit needs to be added to a RecoTrack
145  HitToAddInfo hitToAddInfo;
146  hitToAddInfo.hit = &wireHit;
147  hitToAddInfo.rlInfo = currentRlInfo;
148  m_mapToHitsToAdd[currentClosestTrack].emplace_back(hitToAddInfo);
149  }
150  }
151  }
152 }
153 
154 
156 {
157 
158  for (RecoTrack& recoTrack : m_inputRecoTracks) {
159 
160  RecoTrack* newRecoTrack = recoTrack.copyToStoreArray(m_outputRecoTracks);
161 
162  if (m_mapToHitsToAdd.find(&recoTrack) == m_mapToHitsToAdd.end()) { // No hit to add
163 
164  newRecoTrack->addHitsFromRecoTrack(&recoTrack);
165 
166  } else { // At least one hit to add
167 
168  std::unordered_map<CDCWireHit*, double> previousArcLength;
169  std::unordered_map<CDCWireHit*, double> currentArcLength;
170  // Initialise the arc-length maps to zero and unset the taken and background flags.
171  for (HitToAddInfo& hitToAddInfo : m_mapToHitsToAdd[&recoTrack]) {
172  previousArcLength[hitToAddInfo.hit] = 0.0;
173  currentArcLength[hitToAddInfo.hit] = 0.0;
174  (hitToAddInfo.hit)->getAutomatonCell().setTakenFlag(false);
175  (hitToAddInfo.hit)->getAutomatonCell().setBackgroundFlag(false);
176  }
177 
178  unsigned int sortingParameter(0);
179  for (CDCHit* hitOnTrack : m_mapToHitsOnTrack[&recoTrack]) {
180  for (HitToAddInfo& hitToAddInfo : m_mapToHitsToAdd[&recoTrack]) {
181  CDCWireHit& hitToAdd = *(hitToAddInfo.hit);
182  if (not hitToAdd.getAutomatonCell().hasTakenFlag()) {
183 
184  const ReconstructionResults results(reconstruct(hitToAdd,
185  recoTrack,
186  recoTrack.getRecoHitInformation(hitOnTrack)));
187 
188  previousArcLength[&hitToAdd] = currentArcLength[&hitToAdd];
189  currentArcLength[&hitToAdd] = results.arcLength;
190 
191  B2DEBUG(29, "Hit to be added..." << std::endl
192  << "Layer of the hit on track: " << hitOnTrack->getICLayer() << std::endl
193  << "Layer of the background hit: " << hitToAdd.getHit()->getICLayer() << std::endl
194  << "ID of the background hit: " << hitToAdd.getHit()->getID() << std::endl
195  << "ADC of the background hit: " << hitToAdd.getHit()->getADCCount() << std::endl
196  << "TOT of the background hit: " << hitToAdd.getHit()->getTOT() << std::endl
197  << "Distance from track to hit: " << results.distanceToTrack << std::endl
198  << "Previous arc lenght of the hit: " << previousArcLength[&hitToAdd] << std::endl
199  << "Current arc lenght of the hit: " << currentArcLength[&hitToAdd] << std::endl);
200 
201  if ((previousArcLength[&hitToAdd] > 0) and (currentArcLength[&hitToAdd] < 0)) { // Hit needs to be added here.
202 
204  newRecoTrack->addCDCHit(hitToAdd.getHit(), sortingParameter, rl, RecoHitInformation::c_ReattachCDCWireHitsToRecoTracks);
205  hitToAdd.getAutomatonCell().setTakenFlag(true);
206  ++sortingParameter;
207 
208  }
209  }
210  }
211  const RecoHitInformation::RightLeftInformation rl = recoTrack.getRecoHitInformation(hitOnTrack)->getRightLeftInformation();
212  const RecoHitInformation::OriginTrackFinder foundBy = recoTrack.getRecoHitInformation(hitOnTrack)->getFoundByTrackFinder();
213  newRecoTrack->addCDCHit(hitOnTrack, sortingParameter, rl, foundBy);
214  //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.
215  ++sortingParameter;
216  }
217  }
218  }
219 }
220 
221 
223  const CDCWireHit& wireHit,
224  const RecoTrack& recoTrack, const RecoHitInformation* const recoHitInformation) const
225 {
226  ReconstructionResults results;
227 
228  try {
229 
230  const genfit::MeasuredStateOnPlane& mSoP(recoTrack.getMeasuredStateOnPlaneFromRecoHit(recoHitInformation));
231  const Vector3D trackPosition(mSoP.getPos());
232  const Vector3D trackMomentum(mSoP.getMom());
233  const CDCTrajectory3D trajectory(trackPosition, mSoP.getTime(), trackMomentum, mSoP.getCharge());
234 
235  const CDCTrajectory2D& trajectory2D(trajectory.getTrajectory2D());
236  const CDCTrajectorySZ& trajectorySZ(trajectory.getTrajectorySZ());
237 
238  Vector2D recoPos2D;
239  if (wireHit.isAxial()) {
240  recoPos2D = wireHit.reconstruct2D(trajectory2D);
241  } else {
242  const CDCWire& wire(wireHit.getWire());
243  const Vector2D& posOnXYPlane(wireHit.reconstruct2D(trajectory2D));
244 
245  const double arcLength(trajectory2D.calcArcLength2D(posOnXYPlane));
246  const double z(trajectorySZ.mapSToZ(arcLength));
247 
248  const Vector2D& wirePos2DAtZ(wire.getWirePos2DAtZ(z));
249 
250  const Vector2D& recoPosOnTrajectory(trajectory2D.getClosest(wirePos2DAtZ));
251  const double driftLength(wireHit.getRefDriftLength());
252  Vector2D disp2D(recoPosOnTrajectory - wirePos2DAtZ);
253  disp2D.normalizeTo(driftLength);
254  recoPos2D = wirePos2DAtZ + disp2D;
255  }
256 
257 
258  results.arcLength = trajectory2D.calcArcLength2D(recoPos2D);
259  results.z = trajectorySZ.mapSToZ(results.arcLength);
260  results.distanceToTrack = trajectory2D.getDist2D(recoPos2D);
261 
262  const Vector3D hitPosition(wireHit.getWire().getWirePos3DAtZ(trackPosition.z()));
263 
264  Vector3D trackPosToWire{hitPosition - trackPosition};
265  results.rlInfo = trackPosToWire.xy().isRightOrLeftOf(trackMomentum.xy());
266 
267  results.isValid = true;
268 
269  } catch (...) {
270  B2WARNING("Distance measurement does not work.");
271  results.isValid = false;
272  }
273 
274  return results;
275 }
276 
277 
279  ERightLeft rlInfo) const
280 {
281  using RightLeftInformation = RecoHitInformation::RightLeftInformation;
282  if (rlInfo == ERightLeft::c_Left) {
283  return RightLeftInformation::c_left;
284  } else if (rlInfo == ERightLeft::c_Right) {
285  return RightLeftInformation::c_right;
286  } else if (rlInfo == ERightLeft::c_Invalid) {
287  return RightLeftInformation::c_invalidRightLeftInformation;
288  } else {
289  return RightLeftInformation::c_undefinedRightLeftInformation;
290  }
291 }
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
Base class for Modules.
Definition: Module.h:72
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
@ 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
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
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
bool registerInDataStore(DataStore::EStoreFlags storeFlags=DataStore::c_WriteOut)
Register the object/array in the DataStore.
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.
double calcArcLength2D(const Vector2D &point) const
Calculate the travel distance from the start position of the trajectory.
Vector2D getClosest(const Vector2D &point) const
Calculates the closest approach on the trajectory to the given point.
double getDist2D(const Vector2D &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.
Linear trajectory in sz space.
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:55
const CDCHit * getHit() const
Getter for the CDCHit pointer into the StoreArray.
Definition: CDCWireHit.h:159
double getRefDriftLength() const
Getter for the drift length at the reference position of the wire.
Definition: CDCWireHit.h:224
bool isAxial() const
Indicator if the underlying wire is axial.
Definition: CDCWireHit.h:197
AutomatonCell & getAutomatonCell() const
Mutable getter for the automaton cell.
Definition: CDCWireHit.h:286
Vector2D reconstruct2D(const CDCTrajectory2D &trajectory2D) const
Reconstructs a position of primary ionisation on the drift circle.
Definition: CDCWireHit.cc:166
const CDCWire & getWire() const
Getter for the CDCWire the hit is located on.
Definition: CDCWireHit.h:168
Class representing a sense wire in the central drift chamber.
Definition: CDCWire.h:58
Vector3D getWirePos3DAtZ(const double z) const
Gives position of the wire at the given z coordinate.
Definition: CDCWire.h:196
Vector2D getWirePos2DAtZ(const double z) const
Gives the xy projected position of the wire at the given z coordinate.
Definition: CDCWire.h:192
static const CDCWire * getInstance(const WireID &wireID)
Getter from the wireID convinience object. Does not construct a new object.
Definition: CDCWire.cc:24
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.
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.
RecoHitInformation::RightLeftInformation rightLeftInformationTranslator(ERightLeft rlInfo) const
Translate a TrackFindingCDC::ERightLeft into a RecoHitInformation::RightLeftInformation.
ReconstructionResults reconstruct(const CDCWireHit &wireHit, const RecoTrack &recoTrack, const RecoHitInformation *recoHitInformation) const
Compute distance from a CDCWireHit to a RecoTrack using the mSoP found with a RecoHitInformation.
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.
StoreWrappedObjPtr< std::vector< CDCWireHit > > m_CDCWireHits
Input CDCWireHits.
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.
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.
A two dimensional vector which is equipped with functions for correct handeling of orientation relat...
Definition: Vector2D.h:35
double normalizeTo(const double toLength)
Normalizes the vector to the given length.
Definition: Vector2D.h:325
A three dimensional vector.
Definition: Vector3D.h:33
const Vector2D & xy() const
Getter for the xy projected vector ( reference ! )
Definition: Vector3D.h:508
double z() const
Getter for the z coordinate.
Definition: Vector3D.h:496
Algorithm class to handle the fitting of RecoTrack objects.
Definition: TrackFitter.h:116
bool fit(RecoTrack &recoTrack, genfit::AbsTrackRep *trackRepresentation) const
Fit a reco track with a given non-default track representation.
Definition: TrackFitter.cc:107
#StateOnPlane with additional covariance matrix.
REG_MODULE(arichBtest)
Register the Module.
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:560
ERightLeft
Enumeration to represent the distinct possibilities of the right left passage.
Definition: ERightLeft.h:25
Abstract base class for different kinds of events.
Internal structure to store the information about a hit to be added.