ATTPCROOT  0.3.0-alpha
A ROOT-based framework for analyzing data from active target detectors
AtSample.cxx
Go to the documentation of this file.
1 #include "AtSample.h"
2 
3 #include "AtContainerManip.h"
4 #include "AtHit.h"
5 
6 #include <Math/Point3D.h> // for PositionVector3D
7 #include <TRandom.h> // for TRandom
8 #include <TRandom3.h>
9 
10 #include <functional> // for multiplies
11 #include <numeric>
12 
13 using namespace RandomSample;
14 
20 std::vector<AtHit> AtSample::SampleHits(int N)
21 {
22  // Using the sampled indices, return a vector of positions
23  std::vector<AtHit> ret;
24  for (auto ind : sampleIndicesFromCDF(N))
25  ret.push_back(*fHits->at(ind));
26  return ret;
27 }
28 
34 std::vector<ROOT::Math::XYZPoint> AtSample::SamplePoints(int N)
35 {
36  std::vector<ROOT::Math::XYZPoint> ret;
37  for (const auto &hit : SampleHits(N))
38  ret.push_back(hit.GetPosition());
39  return ret;
40 }
41 
54 int AtSample::getIndexFromCDF(double r, double rmCFD, std::vector<int> vetoed)
55 {
56  double probRemoved = 0; // Probability removed up to this point in the CFD
57  for (int i = 0; i < fCDF.size(); ++i) {
58 
59  if (isInVector(i, vetoed)) {
60  probRemoved += getPDFfromCDF(i);
61  continue;
62  }
63 
64  if ((fCDF[i] - probRemoved) / (1.0 - rmCFD) >= r)
65  return i;
66  }
67  return fCDF.size() - 1;
68 }
69 
77 std::vector<int> AtSample::sampleIndicesFromCDF(int N, std::vector<int> vetoed)
78 {
79  // Get the total probablility from the CDF that accounts for the vetoed pads
80  auto probSum = [this](double accum, int ind) { return accum + getPDFfromCDF(ind); };
81  double rmProb = std::accumulate(vetoed.begin(), vetoed.end(), 0.0, probSum);
82 
83  std::vector<int> sampledInd;
84  while (sampledInd.size() < N) {
85  auto r = gRandom->Uniform();
86 
87  // Get the index i where CDF[i] >= r and CDF[i-1] < r
88  int hitInd = getIndexFromCDF(r, rmProb, vetoed);
89 
90  if (!fWithReplacement) {
91  rmProb += getPDFfromCDF(hitInd);
92  vetoed.push_back(hitInd);
93  }
94 
95  // Save the index if it has not already been sampled
96  if (fWithReplacement || !isInVector(hitInd, sampledInd)) {
97  sampledInd.push_back(hitInd);
98  }
99  }
100 
101  return sampledInd;
102 }
103 
104 double AtSample::getPDFfromCDF(int index)
105 {
106  return index == 0 ? fCDF[0] : fCDF[index] - fCDF[index - 1];
107 }
116 {
117  std::vector<double> normalization;
118  fCDF.clear();
119  for (const auto &hit : *fHits) {
120 
121  // Get the unnormalized marginal and joint PDFs
122  auto pdfMarginal = PDF(*hit);
123  auto pdfJoint = std::accumulate(pdfMarginal.begin(), pdfMarginal.end(), 1.0,
124  std::multiplies<>()); // Has to be 1.0 not 1 or return type is deduced as int
125 
126  // If this is the first hit, setup the normalization vector
127  if (normalization.size() == 0)
128  normalization.assign(pdfMarginal.size(), 0);
129 
130  for (int i = 0; i < pdfMarginal.size(); ++i)
131  normalization[i] += pdfMarginal[i];
132 
133  if (fCDF.size() == 0)
134  fCDF.push_back(pdfJoint);
135  else
136  fCDF.push_back(pdfJoint + fCDF.back());
137  }
138 
139  // Get the total normalization from the marginal PDFs, and normalize the CDF
140  auto norm = std::accumulate(normalization.begin(), normalization.end(), 1.0, std::multiplies<>());
141  for (auto &elem : fCDF) {
142  elem /= norm;
143  }
144 }
145 
146 void AtSample::SetHitsToSample(const std::vector<HitPtr> &hits)
147 {
149 }
150 
151 void AtSample::SetHitsToSample(const std::vector<AtHit> &hits)
152 {
153  // Cast away const, for container manip but it is restored when SetHitsToSample is called
155 }
RandomSample::AtSample::SampleHits
virtual std::vector< AtHit > SampleHits(int N)
Sample hits (AtHit) from fHits.
Definition: AtSample.cxx:20
RandomSample::AtSample::SetHitsToSample
virtual void SetHitsToSample(const std::vector< const AtHit * > &hits)=0
RandomSample
Definition: AtSampleConsensus.h:26
RandomSample::AtSample::fWithReplacement
bool fWithReplacement
Definition: AtSample.h:40
RandomSample::AtSample::sampleIndicesFromCDF
std::vector< int > sampleIndicesFromCDF(int N, std::vector< int > vetoed={})
Definition: AtSample.cxx:77
ContainerManip::GetConstPointerVector
std::vector< const T * > GetConstPointerVector(const std::vector< T > &vec)
Definition: AtContainerManip.h:85
RandomSample::AtSample::getPDFfromCDF
double getPDFfromCDF(int index)
Definition: AtSample.cxx:104
RandomSample::AtSample::getIndexFromCDF
int getIndexFromCDF(double r, double rmCFD, std::vector< int > vetoed)
Get the index i where CDF[i] >= r and CDF[i-1] < r.
Definition: AtSample.cxx:54
RandomSample::AtSample::fCDF
std::vector< double > fCDF
Definition: AtSample.h:39
RandomSample::AtSample::fHits
const std::vector< const AtHit * > * fHits
Definition: AtSample.h:38
AtHit.h
RandomSample::AtSample::SamplePoints
std::vector< ROOT::Math::XYZPoint > SamplePoints(int N)
Sample spacial locations (XYZPoints) from fHits.
Definition: AtSample.cxx:34
RandomSample::AtSample::FillCDF
void FillCDF()
Definition: AtSample.cxx:115
RandomSample::AtSample::PDF
virtual std::vector< double > PDF(const AtHit &hit)=0
AtContainerManip.h
RandomSample::AtSample::isInVector
static bool isInVector(T val, std::vector< T > vec)
Definition: AtSample.h:72
AtSample.h