Belle II Software  release-08-01-10
CDCSegment2D.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/eventdata/segments/CDCSegment2D.h>
9 
10 #include <tracking/trackFindingCDC/eventdata/segments/CDCFacetSegment.h>
11 #include <tracking/trackFindingCDC/eventdata/segments/CDCTangentSegment.h>
12 
13 #include <tracking/trackFindingCDC/eventdata/segments/CDCRLWireHitSegment.h>
14 #include <tracking/trackFindingCDC/eventdata/segments/CDCWireHitSegment.h>
15 #include <tracking/trackFindingCDC/eventdata/hits/CDCFacet.h>
16 #include <tracking/trackFindingCDC/eventdata/hits/CDCTangent.h>
17 #include <tracking/trackFindingCDC/eventdata/hits/CDCRecoHit2D.h>
18 #include <tracking/trackFindingCDC/eventdata/hits/CDCWireHit.h>
19 #include <tracking/trackFindingCDC/eventdata/trajectories/CDCTrajectory2D.h>
20 
21 #include <tracking/trackFindingCDC/geometry/Vector2D.h>
22 
23 #include <tracking/trackFindingCDC/ca/AutomatonCell.h>
24 
25 #include <tracking/trackFindingCDC/numerics/ERightLeft.h>
26 
27 #include <tracking/trackFindingCDC/utilities/WeightedRelation.h>
28 #include <tracking/trackFindingCDC/utilities/Relation.h>
29 #include <tracking/trackFindingCDC/utilities/Algorithms.h>
30 #include <tracking/trackFindingCDC/utilities/ReversedRange.h>
31 #include <tracking/trackFindingCDC/utilities/GetIterator.h>
32 
33 #include <framework/logging/Logger.h>
34 
35 #include <functional>
36 #include <algorithm>
37 #include <iterator>
38 
39 #include <cassert>
40 #include <cstddef>
41 
42 namespace Belle2 {
47  namespace TrackFindingCDC {
48  class CDCRLWireHit;
49  class CDCWire;
50  }
52 }
53 
54 using namespace Belle2;
55 using namespace TrackFindingCDC;
56 
57 namespace {
58  void createTangentSegment(const CDCRLWireHitSegment& rlWireHitSegment,
59  CDCTangentSegment& tangentSegment)
60  {
61  size_t nRLWireHits = rlWireHitSegment.size();
62  if (nRLWireHits < 2) return;
63 
64  tangentSegment.reserve(nRLWireHits - 1);
65 
66  // Make tangents from pairs of hits along the segment.
67  transform_adjacent_pairs(rlWireHitSegment.begin(), rlWireHitSegment.end(),
68  back_inserter(tangentSegment),
69  [](const CDCRLWireHit & firstRLWireHit,
70  const CDCRLWireHit & secondRLWireHit) {
71  return CDCTangent(firstRLWireHit, secondRLWireHit);
72  });
73 
74  if (tangentSegment.size() + 1 != rlWireHitSegment.size()) {
75  B2ERROR("Wrong number of tangents created.");
76  }
77 
78  }
79 
80  template<class ATangentRange>
81  CDCSegment2D condenseTangentSegment(const ATangentRange& tangentSegment)
82  {
83  using TangentIt = GetIterator<const ATangentRange&>;
84  TangentIt tangentIt{tangentSegment.begin()};
85  TangentIt endTangentIt{tangentSegment.end()};
86  int nTangents = std::distance(tangentIt, endTangentIt);
87 
88  CDCSegment2D result;
89  result.reserve(nTangents + 1);
90 
91  if (nTangents == 0) {
92  //pass
93  } else if (nTangents == 1) {
94  // Only one tangent no averaging necesssary
95  const CDCTangent& tangent = *tangentIt;
96  result.push_back(tangent.getFromRecoHit2D());
97  result.push_back(tangent.getToRecoHit2D());
98 
99  } else { // nTangents > 2
100  TangentIt firstTangentIt = tangentIt++;
101  TangentIt secondTangentIt = tangentIt++;
102 
103  {
104  const CDCTangent& firstTangent = *firstTangentIt;
105  result.push_back(firstTangent.getFromRecoHit2D());
106  }
107 
108  while (tangentIt != endTangentIt) {
109 
110  firstTangentIt = secondTangentIt; // tangentSegment[iTangent];
111  secondTangentIt = tangentIt++; // tangentSegment[iTangent+1];
112 
113  const CDCTangent& firstTangent = *firstTangentIt;
114  const CDCTangent& secondTangent = *secondTangentIt;
115 
116  result.push_back(CDCRecoHit2D::average(firstTangent.getToRecoHit2D(),
117  secondTangent.getFromRecoHit2D()));
118  }
119  {
120  const CDCTangent& secondTangent = *secondTangentIt;
121  result.push_back(secondTangent.getToRecoHit2D());
122  }
123  }
124 
125  result.receiveISuperCluster();
126  return result;
127  }
128 
129  template<class AFacetRange>
130  CDCSegment2D condenseFacetSegment(const AFacetRange& facetSegment)
131  {
132  using FacetIt = GetIterator<const AFacetRange&>;
133  FacetIt facetIt = facetSegment.begin();
134  FacetIt endFacetIt = facetSegment.end();
135  int nFacets = std::distance(facetIt, endFacetIt);
136 
137  CDCSegment2D result;
138  result.reserve(nFacets + 2);
139 
140  if (nFacets == 0) {
141  //pass
142  } else if (nFacets == 1) {
143  FacetIt onlyFacetIt = facetIt;
144  const CDCFacet& onlyFacet = *onlyFacetIt;
145  result.push_back(onlyFacet.getStartRecoHit2D());
146  result.push_back(onlyFacet.getMiddleRecoHit2D());
147  result.push_back(onlyFacet.getEndRecoHit2D());
148 
149  } else if (nFacets == 2) {
150  FacetIt firstFacetIt = facetIt++;
151  FacetIt secondFacetIt = facetIt;
152 
153  const CDCFacet& firstFacet = *firstFacetIt;
154  const CDCFacet& secondFacet = *secondFacetIt;
155 
156  result.push_back(firstFacet.getStartRecoHit2D());
157  result.push_back(CDCRecoHit2D::average(secondFacet.getStartRecoHit2D() ,
158  firstFacet.getMiddleRecoHit2D()));
159 
160  result.push_back(CDCRecoHit2D::average(secondFacet.getMiddleRecoHit2D(),
161  firstFacet.getEndRecoHit2D()));
162 
163  result.push_back(secondFacet.getEndRecoHit2D());
164 
165  } else { // nFacets > 2
166  FacetIt firstFacetIt = facetIt++; // facetSegment[0];
167  FacetIt secondFacetIt = facetIt++; // facetSegment[1];
168  FacetIt thirdFacetIt = facetIt++; // facetSegment[2];
169 
170  {
171  const CDCFacet& firstFacet = *firstFacetIt;
172  const CDCFacet& secondFacet = *secondFacetIt;
173  const CDCFacet& thirdFacet = *thirdFacetIt;
174 
175  result.push_back(firstFacet.getStartRecoHit2D());
176 
177  result.push_back(CDCRecoHit2D::average(firstFacet.getMiddleRecoHit2D(),
178  secondFacet.getStartRecoHit2D()));
179 
180  result.push_back(CDCRecoHit2D::average(firstFacet.getEndRecoHit2D(),
181  secondFacet.getMiddleRecoHit2D(),
182  thirdFacet.getStartRecoHit2D()));
183  }
184 
185  while (facetIt != endFacetIt) {
186  firstFacetIt = secondFacetIt; // facetSegment[iFacet];
187  secondFacetIt = thirdFacetIt; // facetSegment[iFacet+1];
188  thirdFacetIt = facetIt++; // facetSegment[iFacet+2];
189 
190  const CDCFacet& firstFacet = *firstFacetIt;
191  const CDCFacet& secondFacet = *secondFacetIt;
192  const CDCFacet& thirdFacet = *thirdFacetIt;
193 
194  result.push_back(CDCRecoHit2D::average(firstFacet.getEndRecoHit2D(),
195  secondFacet.getMiddleRecoHit2D(),
196  thirdFacet.getStartRecoHit2D()));
197  }
198  {
199  const CDCFacet& secondFacet = *secondFacetIt;
200  const CDCFacet& thirdFacet = *thirdFacetIt;
201 
202  result.push_back(CDCRecoHit2D::average(secondFacet.getEndRecoHit2D(),
203  thirdFacet.getMiddleRecoHit2D()));
204 
205  result.push_back(thirdFacet.getEndRecoHit2D());
206  }
207  }
208 
209  result.receiveISuperCluster();
210  return result;
211  }
212 
213 }
214 
216 {
217  const std::vector<CDCTangent>& tangents = tangentSegment;
218  CDCSegment2D segment2D = ::condenseTangentSegment(tangents);
219  segment2D.setTrajectory2D(tangentSegment.getTrajectory2D());
220  segment2D.receiveISuperCluster();
221  segment2D.setAliasScore(tangentSegment.getAliasScore());
222  return segment2D;
223 }
224 
225 CDCSegment2D CDCSegment2D::condense(const std::vector<const CDCTangent* >& tangentPath)
226 {
227  std::vector<std::reference_wrapper<const CDCTangent> > tangents;
228  tangents.reserve(tangentPath.size());
229  for (const CDCTangent* tangent : tangentPath) {
230  tangents.push_back(std::ref(*tangent));
231  }
232 
233  return ::condenseTangentSegment(tangents);
234 }
235 
237 {
238  const std::vector<CDCFacet>& facets = facetSegment;
239  CDCSegment2D segment2D = ::condenseFacetSegment(facets);
240  segment2D.setTrajectory2D(facetSegment.getTrajectory2D());
241  segment2D.receiveISuperCluster();
242  segment2D.setAliasScore(facetSegment.getAliasScore());
243  return segment2D;
244 }
245 
246 CDCSegment2D CDCSegment2D::condense(const std::vector<const CDCFacet* >& facetPath)
247 {
248  std::vector<std::reference_wrapper<const CDCFacet> > facets;
249  facets.reserve(facetPath.size());
250  for (const CDCFacet* facet : facetPath) {
251  facets.push_back(std::ref(*facet));
252  }
253 
254  return ::condenseFacetSegment(facets);
255 }
256 
257 CDCSegment2D CDCSegment2D::condense(const std::vector<const CDCSegment2D*>& segmentPath)
258 {
259  CDCSegment2D result;
260  double aliasScore = 0;
261  for (const CDCSegment2D* ptrSegment2D : segmentPath) {
262  assert(ptrSegment2D);
263  const CDCSegment2D& segment2D = *ptrSegment2D;
264  if (result.empty()) {
265  result = segment2D;
266  } else {
267  for (const CDCRecoHit2D& recoHit2D : segment2D) {
268  result.push_back(recoHit2D);
269  }
270  }
271  aliasScore = aliasScore + segment2D.getAliasScore();
272  }
273  result.receiveISuperCluster();
274  result.setAliasScore(aliasScore);
275  return result;
276 }
277 
279 {
280  if (rlWireHitSegment.size() == 1) {
281  CDCSegment2D segment2D;
282  Vector2D zeroDisp2D(0.0, 0.0);
283  segment2D.emplace_back(rlWireHitSegment.front(), zeroDisp2D);
284  segment2D.setTrajectory2D(rlWireHitSegment.getTrajectory2D());
285  segment2D.receiveISuperCluster();
286  segment2D.setAliasScore(rlWireHitSegment.getAliasScore());
287  return segment2D;
288  } else {
289  CDCTangentSegment tangentSegment;
290  createTangentSegment(rlWireHitSegment, tangentSegment);
291  tangentSegment.setTrajectory2D(rlWireHitSegment.getTrajectory2D());
292  tangentSegment.setAliasScore(rlWireHitSegment.getAliasScore());
293  return condense(tangentSegment);
294  }
295 }
296 
298 {
299  if (rlWireHitSegment.size() < 3) {
300  return reconstructUsingTangents(rlWireHitSegment);
301  } else {
302  CDCFacetSegment facetSegment = CDCFacetSegment::create(rlWireHitSegment);
303  return condense(facetSegment);
304  }
305 }
306 
308 {
309  return {this, segment};
310 }
311 
313 {
314  return {this, weight, segment};
315 }
316 
317 bool CDCSegment2D::operator<(const CDCSegment2D& segment2D) const
318 {
319  return (this->getISuperLayer() < segment2D.getISuperLayer()) or
320  (not(segment2D.getISuperLayer() < this->getISuperLayer()) and
321  this->getISuperCluster() < segment2D.getISuperCluster());
322 }
323 
324 std::vector<const CDCWire*> CDCSegment2D::getWireSegment() const
325 {
326  std::vector<const CDCWire*> wireSegment;
327  for (const CDCRecoHit2D& recoHit2D : *this) {
328  wireSegment.push_back(&(recoHit2D.getWire()));
329  }
330  return wireSegment;
331 }
332 
334 {
335  CDCWireHitSegment wireHitSegment;
336  for (const CDCRecoHit2D& recoHit2D : *this) {
337  wireHitSegment.push_back(&(recoHit2D.getWireHit()));
338  }
339  wireHitSegment.setTrajectory2D(getTrajectory2D());
340  wireHitSegment.setAliasScore(getAliasScore());
341  return wireHitSegment;
342 }
343 
345 {
346  CDCSegment2D segment;
347  for (const CDCRecoHit2D& recoHit2D : *this) {
348  segment.push_back(recoHit2D.getAlias());
349  }
350  segment.setISuperCluster(getISuperCluster());
351  segment.setAliasScore(getAliasScore());
352  return segment;
353 }
354 
356 {
357  ERightLeft rlInfo = ERightLeft::c_Invalid;
358  int nRLSwitches = -1;
359  for (const CDCRecoHit2D& recoHit2D : *this) {
360  if (rlInfo != recoHit2D.getRLInfo()) {
361  rlInfo = recoHit2D.getRLInfo();
362  ++nRLSwitches;
363  }
364  }
365  return nRLSwitches;
366 }
367 
369 {
370  int rlSum = 0;
371  for (const CDCRecoHit2D& recoHit2D : *this) {
372  if (isValid(recoHit2D.getRLInfo())) {
373  rlSum += recoHit2D.getRLInfo();
374  }
375  }
376  return static_cast<double>(rlSum) / size();
377 }
378 
380 {
381  CDCRLWireHitSegment rlWireHitSegment;
382  for (const CDCRecoHit2D& recoHit2D : *this) {
383  rlWireHitSegment.push_back(recoHit2D.getRLWireHit());
384  }
385  rlWireHitSegment.setTrajectory2D(getTrajectory2D());
386  rlWireHitSegment.setAliasScore(getAliasScore());
387  return rlWireHitSegment;
388 }
389 
391 {
392  CDCSegment2D reverseSegment;
393  reverseSegment.reserve(size());
394  for (const CDCRecoHit2D& recohit : reversedRange(*this)) {
395  reverseSegment.push_back(recohit.reversed());
396  }
397 
398  reverseSegment.setTrajectory2D(getTrajectory2D().reversed());
399  reverseSegment.m_automatonCell = m_automatonCell;
400  reverseSegment.setISuperCluster(getISuperCluster());
401  reverseSegment.setAliasScore(getAliasScore());
402  return reverseSegment;
403 }
404 
406 {
407  // Reverse the trajectory
409 
410  // Reverse the left right passage hypotheses
411  for (CDCRecoHit2D& recoHit2D : *this) {
412  recoHit2D.reverse();
413  }
414  // Reverse the arrangement of hits.
415  std::reverse(begin(), end());
416 }
417 
419 {
421  if (not toHits) return;
422  for (const CDCRecoHit2D& recoHit2D : *this) {
423  const CDCWireHit& wireHit = recoHit2D.getWireHit();
424  wireHit.getAutomatonCell().unsetMaskedFlag();
425  }
426 }
427 
429 {
431  if (not toHits) return;
432  for (const CDCRecoHit2D& recoHit2D : *this) {
433  const CDCWireHit& wireHit = recoHit2D.getWireHit();
434  wireHit.getAutomatonCell().setMaskedFlag();
435  }
436 }
437 
438 void CDCSegment2D::receiveMaskedFlag(bool fromHits) const
439 {
440  if (not fromHits) return;
441  for (const CDCRecoHit2D& recoHit2D : *this) {
442  const CDCWireHit& wireHit = recoHit2D.getWireHit();
443  if (wireHit.getAutomatonCell().hasMaskedFlag()) {
445  return;
446  }
447  }
448 }
449 
450 bool CDCSegment2D::isFullyTaken(unsigned int maxNotTaken) const
451 {
452  unsigned int notTakenCounter = 0;
453  for (const CDCRecoHit2D& recoHit : *this) {
454  if (not recoHit.getWireHit().getAutomatonCell().hasTakenFlag()) {
455  notTakenCounter++;
456  if (notTakenCounter > maxNotTaken) {
457  return false;
458  }
459  }
460  }
461 
462  return true;
463 }
464 
466 {
467  auto getISuperClusterOfHit = [](const CDCRecoHit2D & recoHit2d) -> int {
468  return recoHit2d.getWireHit().getISuperCluster();
469  };
470  int iSuperCluster = common(*this, getISuperClusterOfHit, -1);
471  setISuperCluster(iSuperCluster);
472 }
void setMaskedFlag(bool setTo=true)
Sets the masked flag to the given value. Default value true.
void unsetMaskedFlag()
Resets the masked flag to false.
bool hasMaskedFlag() const
Gets the current state of the masked marker flag.
bool hasTakenFlag() const
Gets the current state of the taken marker flag.
A segment consisting of adjacent facets.
static CDCFacetSegment create(const CDCRLWireHitSegment &rlWireHitSegment)
Construct a train of facets from the given oriented wire hits.
Class representing a triple of neighboring oriented wire with additional trajectory information.
Definition: CDCFacet.h:32
CDCRecoHit2D getEndRecoHit2D() const
Getter for the third reconstucted hit.
Definition: CDCFacet.cc:120
CDCRecoHit2D getMiddleRecoHit2D() const
Getter for the second reconstucted hit.
Definition: CDCFacet.cc:115
CDCRecoHit2D getStartRecoHit2D() const
Getter for the first reconstucted hit.
Definition: CDCFacet.cc:110
A segment consisting of two dimensional reconsturcted hits.
Class representing an oriented hit wire including a hypotheses whether the causing track passes left ...
Definition: CDCRLWireHit.h:41
Class representing a two dimensional reconstructed hit in the central drift chamber.
Definition: CDCRecoHit2D.h:47
void reverse()
Turns the orientation in place.
Definition: CDCRecoHit2D.cc:93
CDCRecoHit2D getAlias() const
Getter for the alias version of the reco hit.
static CDCRecoHit2D average(const CDCRecoHit2D &recoHit1, const CDCRecoHit2D &recoHit2)
Constructs the average of two reconstructed hit positions and snaps it to the drift circle.
Definition: CDCRecoHit2D.cc:47
const CDCRLWireHit & getRLWireHit() const
Getter for the oriented wire hit assoziated with the reconstructed hit.
Definition: CDCRecoHit2D.h:281
const CDCWireHit & getWireHit() const
Getter for the wire hit assoziated with the reconstructed hit.
Definition: CDCRecoHit2D.h:193
const CDCWire & getWire() const
Getter for the wire the reconstructed hit assoziated to.
Definition: CDCRecoHit2D.h:175
ERightLeft getRLInfo() const
Getter for the right left passage information.
Definition: CDCRecoHit2D.h:205
A reconstructed sequence of two dimensional hits in one super layer.
Definition: CDCSegment2D.h:39
std::vector< const CDCWire * > getWireSegment() const
Getter for the vector of wires the hits of this segment are based on in the same order.
Relation< const CDCSegment2D, const CDCSegment2D > makeRelation(const CDCSegment2D *segment) const
Helper constructor to create a relation in python.
bool isFullyTaken(unsigned int maxNotTaken=0) const
Returns false, if there are more than N hits in the range which does not have a taken flag.
void unsetAndForwardMaskedFlag(bool toHits=false) const
Unset the masked flag of the automaton cell of this segment and of all contained wire hits.
void reverse()
Reverses the order of hits and their right left passage hypotheses inplace.
double getRLAsymmetry() const
Getter for the sum of right left information relative to the size.
void receiveMaskedFlag(bool fromHits=false) const
Check all contained wire hits if one has the masked flag.
CDCSegment2D getAlias() const
Getter for the alias version of the segment - fit not copied.
bool operator<(const CDCSegment2D &segment2D) const
Comparision of segments up to the super cluster id keeping them close together on sort.
void receiveISuperCluster() const
Setter for the super cluster id based on the hit content.
AutomatonCell & getAutomatonCell() const
Mutable getter for the automaton cell.
Definition: CDCSegment2D.h:119
static CDCSegment2D reconstructUsingTangents(const CDCRLWireHitSegment &rlWireHitSegment)
Reconstruct from wire hits with attached right left passage hypotheses by constructing tangents betwe...
void setAndForwardMaskedFlag(bool toHits=false) const
Set the masked flag of the automaton cell of this segment and forward the masked flag to all containe...
static CDCSegment2D reconstructUsingFacets(const CDCRLWireHitSegment &rlWireHitSegment)
Reconstruct from wire hits with attached right left passage hypotheses by constructing facets between...
WeightedRelation< const CDCSegment2D, const CDCSegment2D > makeWeightedRelation(double weight, const CDCSegment2D *segment) const
Helper constructor to create a relation in python.
AutomatonCell m_automatonCell
Memory for the automaton cell.
Definition: CDCSegment2D.h:173
CDCSegment2D reversed() const
Makes a copy of the segment with the reversed hits in the opposite order.
static CDCSegment2D condense(const CDCTangentSegment &tangentSegment)
Averages the reconstructed positions from hits that overlap in adjacent tangents in the given tangent...
CDCWireHitSegment getWireHitSegment() const
Getter for the vector of the wire hits of this segment are based on in the same order.
int getISuperCluster() const
Getter for the global super cluster id.
Definition: CDCSegment2D.h:150
void setISuperCluster(int iSuperCluster) const
Setter for the globale super cluster id.
Definition: CDCSegment2D.h:156
int getNRLSwitches() const
Getter for the number of changes in the right left passage in the segment.
CDCRLWireHitSegment getRLWireHitSegment() const
Getter for the vector of right left oriented the hits of this segment.
void setTrajectory2D(const CDCTrajectory2D &trajectory2D) const
Setter for the two dimensional trajectory fitted to the segment.
Definition: CDCSegment.h:75
ISuperLayer getISuperLayer() const
Returns the common super layer id of all stored tracking hits.
Definition: CDCSegment.h:57
CDCTrajectory2D & getTrajectory2D() const
Getter for the two dimensional trajectory fitted to the segment.
Definition: CDCSegment.h:69
void setAliasScore(double aliasScore)
Setter for the flag that this segment may have an aliased version.
Definition: CDCSegment.h:96
double getAliasScore() const
Getter for the flag that this segment may have an aliased version.
Definition: CDCSegment.h:90
A segment consisting of adjacent tangents.
Class representating a linear track piece between two oriented wire hits.
Definition: CDCTangent.h:40
CDCRecoHit2D getToRecoHit2D() const
Getter for the reconstructed hit on the second oriented wire hit using reconstructed touch point as p...
Definition: CDCTangent.cc:99
CDCRecoHit2D getFromRecoHit2D() const
Getter for the reconstructed hit on the first oriented wire hit using reconstructed touch point as po...
Definition: CDCTangent.cc:94
void reverse()
Reverses the trajectory in place.
A segment consisting of two dimensional reconsturcted hits.
Class representing a hit wire in the central drift chamber.
Definition: CDCWireHit.h:55
AutomatonCell & getAutomatonCell() const
Mutable getter for the automaton cell.
Definition: CDCWireHit.h:286
Class representing a sense wire in the central drift chamber.
Definition: CDCWire.h:58
Type for two related objects.
Definition: Relation.h:21
A two dimensional vector which is equipped with functions for correct handeling of orientation relat...
Definition: Vector2D.h:35
Type for two related objects with a weight.
ERightLeft
Enumeration to represent the distinct possibilities of the right left passage.
Definition: ERightLeft.h:25
Abstract base class for different kinds of events.