Belle II Software  release-05-01-25
SegmentAliasResolver.cc
1 /**************************************************************************
2  * BASF2 (Belle Analysis Framework 2) *
3  * Copyright(C) 2015 - Belle II Collaboration *
4  * *
5  * Author: The Belle II Collaboration *
6  * Contributors: Oliver Frost *
7  * *
8  * This software is provided "as is" without any warranty. *
9  **************************************************************************/
10 #include <tracking/trackFindingCDC/findlets/minimal/SegmentAliasResolver.h>
11 
12 #include <tracking/trackFindingCDC/fitting/CDCObservations2D.h>
13 
14 #include <tracking/trackFindingCDC/eventdata/segments/CDCSegment2D.h>
15 #include <tracking/trackFindingCDC/eventdata/segments/CDCFacetSegment.h>
16 #include <tracking/trackFindingCDC/eventdata/segments/CDCRLWireHitSegment.h>
17 #include <tracking/trackFindingCDC/eventdata/hits/CDCWireHit.h>
18 
19 #include <tracking/trackFindingCDC/utilities/StringManipulation.h>
20 
21 #include <framework/core/ModuleParamList.templateDetails.h>
22 
23 #include <utility>
24 
25 using namespace Belle2;
26 using namespace TrackFindingCDC;
27 
28 namespace {
29  void swapBetterChi2(CDCSegment2D& segment, CDCSegment2D& aliasSegment)
30  {
31  const CDCTrajectory2D& aliasTrajectory2D = aliasSegment.getTrajectory2D();
32  if (aliasTrajectory2D.isFitted() and
33  aliasTrajectory2D.getChi2() < segment.getTrajectory2D().getChi2()) {
34  aliasSegment.setAliasScore(NAN);
35  std::swap(segment, aliasSegment);
36  }
37  }
38 }
39 
41 {
42  return "Resolves the rl aliasing of segments in various scenarios";
43 }
44 
45 void SegmentAliasResolver::exposeParameters(ModuleParamList* moduleParamList, const std::string& prefix)
46 {
47  moduleParamList->addParameter(prefixed(prefix, "investigateAlias"),
49  "Which alias resolutions should be applied. "
50  "Options are trailing_hit, last_hit, full.",
52 
53  moduleParamList->addParameter(prefixed(prefix, "reestimateDriftLength"),
55  "Switch to reestimate the drift length in the alias resolver",
57 
58  moduleParamList->addParameter(prefixed(prefix, "reestimatePositions"),
60  "Switch to reestimate the reconstructed positions in the alias resolver",
62 }
63 
65 {
67  for (const std::string& investigatedAlias : m_param_investigateAlias) {
68  if (investigatedAlias == "full") {
69  m_fullAlias = true;
70  } else if (investigatedAlias == "cross") {
71  m_crossAliases = true;
72  } else if (investigatedAlias == "borders") {
73  m_borderAliases = true;
74  } else if (investigatedAlias == "middle") {
75  m_middleAliases = true;
76  } else {
77  B2ERROR("Unknown alias to investigate " << investigatedAlias);
78  }
79  }
80 }
81 
82 void SegmentAliasResolver::apply(std::vector<CDCSegment2D>& outputSegments)
83 {
84  if (m_fullAlias) {
85  for (CDCSegment2D& segment : outputSegments) {
86  if (segment->hasAliasFlag()) continue; // A full alias has been found in the facet ca.
87  int nRLSwitches = segment.getNRLSwitches();
88  // Sufficiently right left constrained that the alias is already fixed.
89  bool aliasStable = nRLSwitches > 2;
90  if (aliasStable) continue;
91 
92  CDCSegment2D aliasSegment = segment.getAlias();
93  refit(aliasSegment, true);
94  swapBetterChi2(segment, aliasSegment);
95  } // end alias loop
96  }
97 
98  // Detect whether the segment has a waist and flip the rest of the segment to right
99  if (m_crossAliases) {
100  for (CDCSegment2D& segment : outputSegments) {
101  int nRLSwitches = segment.getNRLSwitches();
102  // Sufficiently right left constrained that the alias is already fixed.
103  bool aliasStable = nRLSwitches > 2;
104  if (aliasStable) continue;
105 
106  if (nRLSwitches == 1) {
107  // One RL switch. Try the all left and all right aliases
108  CDCSegment2D rightSegment = segment;
109  CDCSegment2D leftSegment = segment;
110  for (CDCRecoHit2D& recoHit2D : rightSegment) {
111  if (recoHit2D.getRLInfo() == ERightLeft::c_Left) {
112  recoHit2D = recoHit2D.getAlias();
113  }
114  }
115 
116  for (CDCRecoHit2D& recoHit2D : leftSegment) {
117  if (recoHit2D.getRLInfo() == ERightLeft::c_Right) {
118  recoHit2D = recoHit2D.getAlias();
119  }
120  }
121  refit(rightSegment, true);
122  refit(leftSegment, true);
123  swapBetterChi2(segment, rightSegment);
124  swapBetterChi2(segment, leftSegment);
125 
126  } else if (nRLSwitches == 0) {
127  // No RL switch. Try to introduce one at the smallest drift length
128  CDCSegment2D frontCrossSegment = segment;
129  CDCSegment2D backCrossSegment = segment;
130 
131  auto lessDriftLength = [](const CDCRecoHit2D & lhs, const CDCRecoHit2D & rhs) {
132  return lhs.getRefDriftLength() < rhs.getRefDriftLength();
133  };
134 
135  // Alias before the minimal drift length
136  {
137  auto itMinLRecoHit2D =
138  std::min_element(frontCrossSegment.begin(), frontCrossSegment.end(), lessDriftLength);
139  for (CDCRecoHit2D& recoHit2D : asRange(frontCrossSegment.begin(), itMinLRecoHit2D)) {
140  recoHit2D = recoHit2D.getAlias();
141  }
142  }
143 
144  // Alias after the minimal drift length
145  {
146  auto itMinLRecoHit2D =
147  std::min_element(backCrossSegment.begin(), backCrossSegment.end(), lessDriftLength);
148  for (CDCRecoHit2D& recoHit2D : asRange(itMinLRecoHit2D, backCrossSegment.end())) {
149  recoHit2D = recoHit2D.getAlias();
150  }
151  }
152  refit(frontCrossSegment, true);
153  refit(backCrossSegment, true);
154  swapBetterChi2(segment, frontCrossSegment);
155  swapBetterChi2(segment, backCrossSegment);
156  }
157  }
158  }
159 
160  if (m_borderAliases) {
161  for (CDCSegment2D& segment : outputSegments) {
162  // Check aliasing last hit
163  CDCSegment2D aliasSegment = segment;
164  CDCRecoHit2D& aliasHit = aliasSegment.back();
165  aliasHit.reverse();
166  aliasHit.setRecoPos2D(Vector2D(NAN, NAN));
167  if (aliasHit.getRefDriftLength() < 0.2) {
168  refit(aliasSegment, false);
169  Vector2D recoPos2D = aliasSegment.getTrajectory2D().getClosest(aliasHit.getRefPos2D());
170  ERightLeft rlInfo = aliasSegment.getTrajectory2D().isRightOrLeft(aliasHit.getRefPos2D());
171  aliasHit.setRecoPos2D(recoPos2D);
172  aliasHit.setRLInfo(rlInfo);
173  swapBetterChi2(segment, aliasSegment);
174  }
175  }
176 
177  for (CDCSegment2D& segment : outputSegments) {
178  // Check aliasing first hit
179  CDCSegment2D aliasSegment = segment;
180  CDCRecoHit2D& aliasHit = aliasSegment.front();
181  aliasHit.reverse();
182  aliasHit.setRecoPos2D(Vector2D(NAN, NAN));
183  if (aliasHit.getRefDriftLength() < 0.2) {
184  refit(aliasSegment, false);
185  Vector2D recoPos2D = aliasSegment.getTrajectory2D().getClosest(aliasHit.getRefPos2D());
186  ERightLeft rlInfo = aliasSegment.getTrajectory2D().isRightOrLeft(aliasHit.getRefPos2D());
187  aliasHit.setRecoPos2D(recoPos2D);
188  aliasHit.setRLInfo(rlInfo);
189  swapBetterChi2(segment, aliasSegment);
190  }
191  }
192  }// end if (m_borderAliases)
193 
194  if (m_middleAliases) {
195  for (CDCSegment2D& segment : outputSegments) {
196  // Check aliasing hit with lowest drift length
197  CDCSegment2D aliasSegment = segment;
198 
199  // Find hit with minimal drift length
200  double minimalDriftLength = 0.1;
201  CDCRecoHit2D* minimalHit = nullptr;
202  for (CDCRecoHit2D& aliasHit : aliasSegment) {
203  if (aliasHit.getRefDriftLength() < minimalDriftLength) {
204  minimalHit = &aliasHit;
205  minimalDriftLength = aliasHit.getRefDriftLength();
206  }
207  }
208  if (minimalHit) {
209  CDCRecoHit2D& aliasHit = *minimalHit;
210  aliasHit.reverse();
211  aliasHit.setRecoPos2D(Vector2D(NAN, NAN));
212  refit(aliasSegment, false);
213  Vector2D recoPos2D = aliasSegment.getTrajectory2D().getClosest(aliasHit.getRefPos2D());
214  ERightLeft rlInfo = aliasSegment.getTrajectory2D().isRightOrLeft(aliasHit.getRefPos2D());
215  aliasHit.setRecoPos2D(recoPos2D);
216  aliasHit.setRLInfo(rlInfo);
217  swapBetterChi2(segment, aliasSegment);
218  }
219  }
220  }
221 
222  std::sort(outputSegments.begin(), outputSegments.end());
223 }
224 
225 void SegmentAliasResolver::refit(CDCSegment2D& segment, bool reestimate)
226 {
227  if (reestimate) {
229  CDCRLWireHitSegment rlWireHitSegment = segment.getRLWireHitSegment();
230  // Reset the drift length to the default values.
231  for (CDCRLWireHit& rlWireHit : rlWireHitSegment) {
232  rlWireHit.setRefDriftLength(rlWireHit.getWireHit().getRefDriftLength());
233  }
234  CDCFacetSegment facetSegment = CDCFacetSegment::create(rlWireHitSegment);
235  for (CDCFacet& facet : facetSegment) {
236  facet.adjustFitLine();
239  }
240  }
241  CDCSegment2D replacement = CDCSegment2D::condense(facetSegment);
242  segment = replacement;
243  }
244 
247  }
248  }
249 
250  const EFitPos fitPos = EFitPos::c_RecoPos;
251  const EFitVariance fitVariance = EFitVariance::c_Proper;
252  CDCObservations2D observations2D(fitPos, fitVariance);
253  observations2D.appendRange(segment);
254  if (observations2D.size() < 4) {
255  segment.getTrajectory2D().clear();
256  } else {
257  CDCTrajectory2D trajectory2D = m_riemannFitter.fit(observations2D);
258  segment.setTrajectory2D(trajectory2D);
259  }
260 
261 }
Belle2::TrackFindingCDC::SegmentAliasResolver::m_riemannFitter
CDCRiemannFitter m_riemannFitter
Instance of the riemann fitter to be used.
Definition: SegmentAliasResolver.h:86
Belle2::TrackFindingCDC::CDCObservations2D::size
std::size_t size() const
Returns the number of observations stored.
Definition: CDCObservations2D.h:88
Belle2::TrackFindingCDC::SegmentAliasResolver::m_fullAlias
bool m_fullAlias
Switch whether the complete segment should be aliased.
Definition: SegmentAliasResolver.h:68
Belle2::TrackFindingCDC::Vector2D
A two dimensional vector which is equipped with functions for correct handeling of orientation relat...
Definition: Vector2D.h:37
Belle2::TrackFindingCDC::CDCFacetSegment::create
static CDCFacetSegment create(const CDCRLWireHitSegment &rlWireHitSegment)
Construct a train of facets from the given oriented wire hits.
Definition: CDCFacetSegment.cc:37
Belle2::TrackFindingCDC::SegmentAliasResolver::apply
void apply(std::vector< CDCSegment2D > &outputSegments) final
Main algorithm applying the fit to each segment.
Definition: SegmentAliasResolver.cc:82
Belle2::TrackFindingCDC::SegmentAliasResolver::m_param_reestimateDriftLength
bool m_param_reestimateDriftLength
Parameter : Switch to reestimate the drift length before each fit.
Definition: SegmentAliasResolver.h:80
Belle2::TrackFindingCDC::CDCRecoHit2D::getRefDriftLength
double getRefDriftLength() const
Getter for the drift length at the wire reference position.
Definition: CDCRecoHit2D.h:227
Belle2::TrackFindingCDC::SegmentAliasResolver::m_driftLengthEstimator
DriftLengthEstimator m_driftLengthEstimator
Instance of the drift length estimator to be used.
Definition: SegmentAliasResolver.h:89
Belle2::TrackFindingCDC::CDCRecoHit2D::setRecoPos2D
void setRecoPos2D(const Vector2D &recoPos2D)
Setter for the position in the reference plane.
Definition: CDCRecoHit2D.h:254
Belle2::TrackFindingCDC::SegmentAliasResolver::exposeParameters
void exposeParameters(ModuleParamList *moduleParamList, const std::string &prefix) final
Expose the parameters to a module.
Definition: SegmentAliasResolver.cc:45
Belle2::TrackFindingCDC::CDCTrajectory2D::getClosest
Vector2D getClosest(const Vector2D &point) const
Calculates the closest approach on the trajectory to the given point.
Definition: CDCTrajectory2D.cc:173
Belle2::TrackFindingCDC::CDCTrajectory2D
Particle trajectory as it is seen in xy projection represented as a circle.
Definition: CDCTrajectory2D.h:46
Belle2::TrackFindingCDC::DriftLengthEstimator::updateDriftLength
double updateDriftLength(CDCRecoHit2D &recoHit2D)
Update the drift length of the reconstructed hit in place.
Definition: DriftLengthEstimator.cc:58
Belle2::TrackFindingCDC::CompositeProcessingSignalListener::initialize
void initialize() override
Receive and dispatch signal before the start of the event processing.
Definition: CompositeProcessingSignalListener.cc:17
Belle2::TrackFindingCDC::CDCSegment2D::condense
static CDCSegment2D condense(const CDCTangentSegment &tangentSegment)
Averages the reconstructed positions from hits that overlap in adjacent tangents in the given tangent...
Definition: CDCSegment2D.cc:217
Belle2::TrackFindingCDC::CDCRecoHit2D::getRefPos2D
const Vector2D & getRefPos2D() const
Getter for the reference position of the wire.
Definition: CDCRecoHit2D.h:191
Belle2::TrackFindingCDC::CDCObservations2D::appendRange
std::size_t appendRange(const CDCSegment2D &segment2D)
Appends all reconstructed hits from the two dimensional segment.
Definition: CDCObservations2D.cc:242
Belle2::TrackFindingCDC::CDCRLWireHitSegment
A segment consisting of two dimensional reconsturcted hits.
Definition: CDCRLWireHitSegment.h:34
Belle2::TrackFindingCDC::SegmentAliasResolver::m_param_reestimatePositions
bool m_param_reestimatePositions
Parameter : Switch to restimate the reconstructed positions with a pass of facets.
Definition: SegmentAliasResolver.h:83
Belle2::TrackFindingCDC::CDCFacetSegment
A segment consisting of adjacent facets.
Definition: CDCFacetSegment.h:32
Belle2::TrackFindingCDC::CDCTrajectory2D::isRightOrLeft
ERightLeft isRightOrLeft(const Vector2D &point) const
Checks if the given point is to the right or to the left of the trajectory.
Definition: CDCTrajectory2D.h:425
Belle2::TrackFindingCDC::CDCObservations2D
Class serving as a storage of observed drift circles to present to the Riemann fitter.
Definition: CDCObservations2D.h:53
Belle2::ModuleParamList::addParameter
void addParameter(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module list.
Definition: ModuleParamList.templateDetails.h:38
Belle2::TrackFindingCDC::CDCRecoHit2D
Class representing a two dimensional reconstructed hit in the central drift chamber.
Definition: CDCRecoHit2D.h:57
Belle2::TrackFindingCDC::CDCSegment::getTrajectory2D
CDCTrajectory2D & getTrajectory2D() const
Getter for the two dimensional trajectory fitted to the segment.
Definition: CDCSegment.h:79
Belle2
Abstract base class for different kinds of events.
Definition: MillepedeAlgorithm.h:19
Belle2::TrackFindingCDC::CDCRLWireHit
Class representing an oriented hit wire including a hypotheses whether the causing track passes left ...
Definition: CDCRLWireHit.h:51
Belle2::TrackFindingCDC::SegmentAliasResolver::m_borderAliases
bool m_borderAliases
Switch whether the border hits at the beginning and the end should be aliased.
Definition: SegmentAliasResolver.h:74
Belle2::TrackFindingCDC::CDCFitter2D::fit
CDCTrajectory2D fit(const CDCObservations2D &observations2D) const
Fits a collection of observation drift circles.
Definition: CDCFitter2D.icc.h:48
Belle2::TrackFindingCDC::NRightLeft::ERightLeft
ERightLeft
Enumeration to represent the distinct possibilities of the right left passage.
Definition: ERightLeft.h:35
Belle2::TrackFindingCDC::CDCRecoHit2D::reverse
void reverse()
Turns the orientation in place.
Definition: CDCRecoHit2D.cc:97
Belle2::TrackFindingCDC::SegmentAliasResolver::m_crossAliases
bool m_crossAliases
Switch whether the segment should be aliased at the waist where an rl side switch was missed.
Definition: SegmentAliasResolver.h:71
Belle2::TrackFindingCDC::CDCFacet
Class representing a triple of neighboring oriented wire with additional trajectory information.
Definition: CDCFacet.h:42
Belle2::TrackFindingCDC::SegmentAliasResolver::m_param_investigateAlias
std::vector< std::string > m_param_investigateAlias
Parameter : Which alias resolutions should be applied.
Definition: SegmentAliasResolver.h:65
Belle2::TrackFindingCDC::SegmentAliasResolver::refit
void refit(CDCSegment2D &segment, bool reestimate)
Fit the alias segment.
Definition: SegmentAliasResolver.cc:225
Belle2::TrackFindingCDC::CDCSegment2D
A reconstructed sequence of two dimensional hits in one super layer.
Definition: CDCSegment2D.h:40
Belle2::TrackFindingCDC::CDCRecoHit2D::setRLInfo
void setRLInfo(ERightLeft &rlInfo)
Setter the right left passage information.
Definition: CDCRecoHit2D.h:221
Belle2::ModuleParamList
The Module parameter list class.
Definition: ModuleParamList.h:46
Belle2::TrackFindingCDC::SegmentAliasResolver::m_middleAliases
bool m_middleAliases
Switch whether the hits in the middle with lowest drift radius should be aliased.
Definition: SegmentAliasResolver.h:77
Belle2::TrackFindingCDC::SegmentAliasResolver::initialize
void initialize() final
Signals the beginning of the event processing.
Definition: SegmentAliasResolver.cc:64
Belle2::TrackFindingCDC::SegmentAliasResolver::getDescription
std::string getDescription() final
Short description of the findlet.
Definition: SegmentAliasResolver.cc:40