ATTPCROOT  0.3.0-alpha
A ROOT-based framework for analyzing data from active target detectors
AtSampleConsensus.cxx
Go to the documentation of this file.
1 #include "AtSampleConsensus.h"
2 
3 #include "AtBaseEvent.h" // for AtBaseEvent
4 #include "AtContainerManip.h"
5 #include "AtEvent.h" // for AtEvent
6 #include "AtHit.h" // for AtHit
7 #include "AtPattern.h"
8 #include "AtPatternEvent.h"
9 #include "AtPatternTypes.h"
10 #include "AtSample.h" // for AtSample
11 #include "AtSampleEstimator.h"
12 #include "AtSampleMethods.h"
13 
14 #include <FairLogger.h> // for Logger, LOG
15 
16 #include <fstream> // for std
17 #include <memory> // for allocator_traits<>::value_type
18 #include <set> // for set, operator!=, _Rb_tree_const_iterator
19 
20 using namespace SampleConsensus;
21 
24 {
25 }
26 
28  : fPatternType(patternType), fEstimator(estimator), fRandSampler(RandomSample::CreateSampler(sampleMethod))
29 
30 {
31 }
32 
33 std::unique_ptr<AtPatterns::AtPattern>
34 AtSampleConsensus::GeneratePatternFromHits(const std::vector<const AtHit *> &hitArray)
35 {
36 
37  if (hitArray.size() < fMinPatternPoints) {
38  return nullptr;
39  }
40  LOG(debug) << "Creating pattern";
41  auto pattern = AtPatterns::CreatePattern(fPatternType);
42  LOG(debug) << "Sampling points";
43  auto points = fRandSampler->SamplePoints(pattern->GetNumPoints());
44  LOG(debug) << "Defining pattern";
45  pattern->DefinePattern(points);
46 
47  LOG(debug) << "Testing pattern";
48  auto nInliers = SampleConsensus::AtEstimator::EvaluateModel(pattern.get(), hitArray, fDistanceThreshold, fEstimator);
49  LOG(debug) << "Found " << nInliers << " inliers" << std::endl;
50 
51  // If the pattern is consistent with enough points, save it
52  if (nInliers > fMinPatternPoints) {
53  LOG(debug) << "Adding pattern with nInliers: " << nInliers << std::endl;
54  return pattern;
55  }
56 
57  return nullptr;
58 }
59 
61 {
62  auto hitVec = ContainerManip::GetConstPointerVector(event->GetHits());
63  return Solve(hitVec, event);
64 }
65 
66 AtPatternEvent AtSampleConsensus::Solve(const std::vector<AtHit> &hitArray, AtBaseEvent *event)
67 {
68  auto hitVec = ContainerManip::GetConstPointerVector(hitArray);
69  return Solve(hitVec, event);
70 };
71 
72 AtPatternEvent AtSampleConsensus::Solve(const std::vector<const AtHit *> &hitArray, AtBaseEvent *event)
73 {
74  // Return early if we were passed an event and it is marked bad
75  if (event != nullptr && !event->IsGood())
76  return {*event};
77 
78  if (hitArray.size() < fMinPatternPoints) {
79  LOG(error) << "Not enough points to solve. Has " << hitArray.size() << " requires " << fMinPatternPoints;
80  return {};
81  }
82  LOG(info) << "Solving with " << hitArray.size() << " points";
83 
84  auto comp = [](const PatternPtr &a, const PatternPtr &b) { return a->GetChi2() < b->GetChi2(); };
85  auto sortedPatterns = std::set<PatternPtr, decltype(comp)>(comp);
86 
87  LOG(debug2) << "Generating " << fIterations << " patterns";
88  fRandSampler->SetHitsToSample(hitArray);
89  for (int i = 0; i < fIterations; i++) {
90  if (i % 1000 == 0)
91  LOG(debug) << "Iteration: " << i << "/" << fIterations;
92 
93  auto pattern = GeneratePatternFromHits(hitArray);
94  if (pattern != nullptr)
95  sortedPatterns.insert(std::move(pattern));
96  }
97  LOG(debug2) << "Created " << sortedPatterns.size() << " valid patterns.";
98 
99  // Loop through each pattern, and extract the points that fit each pattern
100  auto remainHits = hitArray;
101  AtPatternEvent retEvent;
102  if (event)
103  retEvent = AtPatternEvent(*event);
104 
105  for (const auto &pattern : sortedPatterns) {
106  if (remainHits.size() < fMinPatternPoints)
107  break;
108 
109  auto inlierHits = movePointsInPattern(pattern.get(), remainHits);
110  if (inlierHits.size() > fMinPatternPoints) {
111  auto track = CreateTrack(pattern.get(), inlierHits);
112  track.SetTrackID(retEvent.GetTrackCand().size());
113  retEvent.AddTrack(track);
114  }
115  }
116 
117  // Add the remaining hits as noise
118  for (auto &hit : remainHits)
119  retEvent.AddNoise(std::move(*hit));
120 
121  return retEvent;
122 }
123 
124 AtTrack AtSampleConsensus::CreateTrack(AtPattern *pattern, std::vector<const AtHit *> &inliers)
125 {
126  AtTrack track;
127 
128  // Add inliers to our ouput track
129  for (auto hit : inliers)
130  track.AddHit(std::move(*hit));
131 
132  if (fFitPattern)
133  pattern->FitPattern(inliers, fChargeThres);
134 
135  track.SetPattern(pattern->Clone());
136  return track;
137 }
146 std::vector<const AtHit *> AtSampleConsensus::movePointsInPattern(AtPattern *pattern, std::vector<const AtHit *> &hits)
147 {
148 
149  auto isInPattern = [pattern, this](const AtHit *hit) {
150  double error = pattern->DistanceToPattern(hit->GetPosition());
151  return (error * error) < (fDistanceThreshold * fDistanceThreshold);
152  };
153 
154  return ContainerManip::MoveFromVector(hits, isInPattern);
155 }
AtTrack::SetPattern
void SetPattern(std::unique_ptr< AtPatterns::AtPattern > pat)
Definition: AtTrack.h:99
SampleConsensus::Estimators::kRANSAC
@ kRANSAC
AtBaseEvent.h
AtPatternEvent
Definition: AtPatternEvent.h:19
SampleConsensus::AtSampleConsensus::Solve
AtPatternEvent Solve(AtEvent *event)
See Solve(const std::vector<const AtHit *> &hitArray)
Definition: AtSampleConsensus.cxx:60
AtEvent.h
RandomSample::SampleMethod
SampleMethod
. Methods of random sampling.
Definition: AtSampleMethods.h:22
SampleConsensus::AtSampleConsensus
Perform a sample consensus on a cloud of AtHits.
Definition: AtSampleConsensus.h:46
SampleConsensus::Estimators
Estimators
Estimators for AtSampleConsensus.
Definition: AtEstimatorMethods.h:17
AtPatternEvent::AddTrack
void AddTrack(const AtTrack &track)
Definition: AtPatternEvent.h:46
RandomSample
Definition: AtSampleConsensus.h:26
RandomSample::CreateSampler
std::unique_ptr< AtSample > CreateSampler(SampleMethod method, Ts &&...params)
. Create a hit sampler
Definition: AtSampleMethods.h:41
AtPattern.h
AtPatterns::CreatePattern
std::unique_ptr< AtPattern > CreatePattern(PatternType type)
Factory for AtPattern.
Definition: AtPatternTypes.cxx:11
SampleConsensus::AtEstimator::EvaluateModel
static int EvaluateModel(AtPatterns::AtPattern *model, const std::vector< AtHit > &hits, double distThresh, Estimators estimator)
Definition: AtSampleEstimator.cxx:36
ContainerManip::GetConstPointerVector
std::vector< const T * > GetConstPointerVector(const std::vector< T > &vec)
Definition: AtContainerManip.h:85
AtEvent
Definition: AtEvent.h:22
ContainerManip::MoveFromVector
std::vector< T > MoveFromVector(std::vector< T > &vec, Operator op)
Definition: AtContainerManip.h:151
AtHit.h
AtPatternEvent::GetTrackCand
std::vector< AtTrack > & GetTrackCand()
Definition: AtPatternEvent.h:56
AtBaseEvent::IsGood
Bool_t IsGood() const
Definition: AtBaseEvent.h:70
AtEvent::GetHits
const HitVector & GetHits() const
Definition: AtEvent.h:116
AtSampleConsensus.h
AtTrack
Definition: AtTrack.h:25
AtBaseEvent
Base class for all event types in ATTPCROOT.
Definition: AtBaseEvent.h:20
SampleConsensus::AtSampleConsensus::AtSampleConsensus
AtSampleConsensus()
Definition: AtSampleConsensus.cxx:22
AtSampleMethods.h
AtPatternEvent.h
AtPatternEvent::AddNoise
void AddNoise(Ts &&...params)
Definition: AtPatternEvent.h:50
AtContainerManip.h
AtPatterns::PatternType
PatternType
Supported patterns.
Definition: AtPatternTypes.h:14
AtPatternTypes.h
AtSample.h
AtSampleEstimator.h
SampleConsensus
Definition: AtEstimatorMethods.h:9
AtHit
Point in space with charge.
Definition: AtHit.h:27
AtTrack::AddHit
void AddHit(const AtHit &hit)
Definition: AtTrack.h:97