Belle II Software development
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
42namespace Belle2 {
47 namespace TrackFindingCDC {
48 class CDCRLWireHit;
49 class CDCWire;
50 }
52}
53
54using namespace Belle2;
55using namespace TrackFindingCDC;
56
57namespace {
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 necessary
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
225CDCSegment2D 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
246CDCSegment2D 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
257CDCSegment2D 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
317bool 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
324std::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();
425 }
426}
427
429{
431 if (not toHits) return;
432 for (const CDCRecoHit2D& recoHit2D : *this) {
433 const CDCWireHit& wireHit = recoHit2D.getWireHit();
435 }
436}
437
438void 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
450bool 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 reconstructed hit.
Definition: CDCFacet.cc:120
CDCRecoHit2D getMiddleRecoHit2D() const
Getter for the second reconstructed hit.
Definition: CDCFacet.cc:115
CDCRecoHit2D getStartRecoHit2D() const
Getter for the first reconstructed hit.
Definition: CDCFacet.cc:110
A segment consisting of two dimensional reconstructed 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
const CDCWireHit & getWireHit() const
Getter for the wire hit associated with the reconstructed hit.
Definition: CDCRecoHit2D.h:193
const CDCRLWireHit & getRLWireHit() const
Getter for the oriented wire hit associated with the reconstructed hit.
Definition: CDCRecoHit2D.h:281
void reverse()
Turns the orientation in place.
Definition: CDCRecoHit2D.cc:93
CDCRecoHit2D getAlias() const
Getter for the alias version of the reco hit.
const CDCWire & getWire() const
Getter for the wire the reconstructed hit associated to.
Definition: CDCRecoHit2D.h:175
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
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
Comparison of segments up to the super cluster id keeping them close together on sort.
AutomatonCell & getAutomatonCell() const
Mutable getter for the automaton cell.
Definition: CDCSegment2D.h:119
void receiveISuperCluster() const
Setter for the super cluster id based on the hit content.
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 representing 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 reconstructed 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 handling of orientation relate...
Definition: Vector2D.h:32
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.