LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
RPhiFeatureTool.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
13 
15 
16 using namespace pandora;
17 
18 namespace lar_content
19 {
20 
21 RPhiFeatureTool::RPhiFeatureTool() :
22  m_fastScoreCheck(true),
23  m_fastScoreOnly(false),
24  m_fullScore(false),
25  m_kernelEstimateSigma(0.048f),
26  m_kappa(0.42f),
27  m_maxHitVertexDisplacement1D(100.f),
28  m_minFastScoreFraction(0.8f),
29  m_fastHistogramNPhiBins(200),
30  m_fastHistogramPhiMin(-1.1f * M_PI),
31  m_fastHistogramPhiMax(+1.1f * M_PI),
32  m_enableFolding(true)
33 {
34 }
35 
36 //------------------------------------------------------------------------------------------------------------------------------------------
37 
38 void RPhiFeatureTool::Run(LArMvaHelper::MvaFeatureVector &featureVector, const VertexSelectionBaseAlgorithm *const pAlgorithm, const Vertex * const pVertex,
41  const float beamDeweightingScore, float &bestFastScore)
42 {
43  if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
44  std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
45 
46  KernelEstimate kernelEstimateU(m_kernelEstimateSigma);
47  KernelEstimate kernelEstimateV(m_kernelEstimateSigma);
48  KernelEstimate kernelEstimateW(m_kernelEstimateSigma);
49 
50  this->FillKernelEstimate(pVertex, TPC_VIEW_U, kdTreeMap.at(TPC_VIEW_U), kernelEstimateU);
51  this->FillKernelEstimate(pVertex, TPC_VIEW_V, kdTreeMap.at(TPC_VIEW_V), kernelEstimateV);
52  this->FillKernelEstimate(pVertex, TPC_VIEW_W, kdTreeMap.at(TPC_VIEW_W), kernelEstimateW);
53 
54  const float expBeamDeweightingScore = std::exp(beamDeweightingScore);
55 
57  {
58  const float fastScore(this->GetFastScore(kernelEstimateU, kernelEstimateV, kernelEstimateW));
59 
60  if (m_fastScoreOnly)
61  {
62  featureVector.push_back(fastScore);
63  return;
64  }
65 
66  if (expBeamDeweightingScore * fastScore < m_minFastScoreFraction * bestFastScore)
67  {
68  featureVector.push_back(0.);
69  return;
70  }
71 
72  if (expBeamDeweightingScore * fastScore > bestFastScore)
73  bestFastScore = expBeamDeweightingScore * fastScore;
74  }
75 
76  featureVector.push_back(m_fullScore ? this->GetFullScore(kernelEstimateU, kernelEstimateV, kernelEstimateW) :
77  this->GetMidwayScore(kernelEstimateU, kernelEstimateV, kernelEstimateW));
78 }
79 
80 //------------------------------------------------------------------------------------------------------------------------------------------
81 
82 float RPhiFeatureTool::GetFastScore(const KernelEstimate &kernelEstimateU, const KernelEstimate &kernelEstimateV,
83  const KernelEstimate &kernelEstimateW) const
84 {
88 
89  for (const KernelEstimate::ContributionList::value_type &contribution : kernelEstimateU.GetContributionList())
90  histogramU.Fill(contribution.first, contribution.second);
91 
92  for (const KernelEstimate::ContributionList::value_type &contribution : kernelEstimateV.GetContributionList())
93  histogramV.Fill(contribution.first, contribution.second);
94 
95  for (const KernelEstimate::ContributionList::value_type &contribution : kernelEstimateW.GetContributionList())
96  histogramW.Fill(contribution.first, contribution.second);
97 
98  // Is the below correct?
99  histogramU.Scale(1.f/histogramU.GetCumulativeSum());
100  histogramV.Scale(1.f/histogramV.GetCumulativeSum());
101  histogramW.Scale(1.f/histogramW.GetCumulativeSum());
102 
103  // ATTN Need to renormalise histograms if ever want to directly compare fast and full scores
104  float figureOfMerit(0.f);
105 
106  for (int xBin = 0; xBin < histogramU.GetNBinsX(); ++xBin)
107  {
108  const float binContentU(histogramU.GetBinContent(xBin));
109  const float binContentV(histogramV.GetBinContent(xBin));
110  const float binContentW(histogramW.GetBinContent(xBin));
111  figureOfMerit += binContentU * binContentU + binContentV * binContentV + binContentW * binContentW;
112  }
113 
114  return figureOfMerit;
115 }
116 
117 //------------------------------------------------------------------------------------------------------------------------------------------
118 
119 float RPhiFeatureTool::GetMidwayScore(const KernelEstimate &kernelEstimateU, const KernelEstimate &kernelEstimateV,
120  const KernelEstimate &kernelEstimateW) const
121 {
125 
126  for (const KernelEstimate::ContributionList::value_type &contribution : kernelEstimateU.GetContributionList())
127  histogramU.Fill(contribution.first, contribution.second);
128 
129  for (const KernelEstimate::ContributionList::value_type &contribution : kernelEstimateV.GetContributionList())
130  histogramV.Fill(contribution.first, contribution.second);
131 
132  for (const KernelEstimate::ContributionList::value_type &contribution : kernelEstimateW.GetContributionList())
133  histogramW.Fill(contribution.first, contribution.second);
134 
135  float figureOfMerit(0.f);
136 
137  for (int xBin = 0; xBin < histogramU.GetNBinsX(); ++xBin)
138  {
139  const float binCenter(histogramU.GetXLow() + (static_cast<float>(xBin) + 0.5f) * histogramU.GetXBinWidth());
140  figureOfMerit += histogramU.GetBinContent(xBin) * kernelEstimateU.Sample(binCenter);
141  figureOfMerit += histogramV.GetBinContent(xBin) * kernelEstimateV.Sample(binCenter);
142  figureOfMerit += histogramW.GetBinContent(xBin) * kernelEstimateW.Sample(binCenter);
143  }
144 
145  return figureOfMerit;
146 }
147 
148 //------------------------------------------------------------------------------------------------------------------------------------------
149 
150 float RPhiFeatureTool::GetFullScore(const KernelEstimate &kernelEstimateU, const KernelEstimate &kernelEstimateV,
151  const KernelEstimate &kernelEstimateW) const
152 {
153  float figureOfMerit(0.f);
154 
155  for (const KernelEstimate::ContributionList::value_type &contribution : kernelEstimateU.GetContributionList())
156  figureOfMerit += contribution.second * kernelEstimateU.Sample(contribution.first);
157 
158  for (const KernelEstimate::ContributionList::value_type &contribution : kernelEstimateV.GetContributionList())
159  figureOfMerit += contribution.second * kernelEstimateV.Sample(contribution.first);
160 
161  for (const KernelEstimate::ContributionList::value_type &contribution : kernelEstimateW.GetContributionList())
162  figureOfMerit += contribution.second * kernelEstimateW.Sample(contribution.first);
163 
164  return figureOfMerit;
165 }
166 
167 //------------------------------------------------------------------------------------------------------------------------------------------
168 
169 void RPhiFeatureTool::FillKernelEstimate(const Vertex *const pVertex, const HitType hitType, VertexSelectionBaseAlgorithm::HitKDTree2D &kdTree,
170  KernelEstimate &kernelEstimate) const
171 {
172  const CartesianVector vertexPosition2D(LArGeometryHelper::ProjectPosition(this->GetPandora(), pVertex->GetPosition(), hitType));
174 
176  kdTree.search(searchRegionHits, found);
177 
178  for (const auto &hit : found)
179  {
180  const CartesianVector displacement(hit.data->GetPositionVector() - vertexPosition2D);
181  const float magnitude(displacement.GetMagnitude());
182 
183  if (magnitude < std::numeric_limits<float>::epsilon())
184  continue;
185 
186  float phi(this->atan2Fast(displacement.GetZ(), displacement.GetX()));
187  float weight(1.f / (std::sqrt(magnitude + std::fabs(m_kappa))));
188 
189  if (m_enableFolding && (phi < 0.f))
190  {
191  phi += M_PI;
192  weight *= -1.f;
193  }
194 
195  kernelEstimate.AddContribution(phi, weight);
196  }
197 }
198 
199 //------------------------------------------------------------------------------------------------------------------------------------------
200 
201 float RPhiFeatureTool::atan2Fast(const float y, const float x) const
202 {
203  const float ONE_QTR_PI(0.25f * M_PI);
204  const float THR_QTR_PI(0.75f * M_PI);
205 
206  const float abs_y(std::max(std::fabs(y), std::numeric_limits<float>::epsilon()));
207  const float abs_x(std::fabs(x));
208 
209  const float r((x < 0.f) ? (x + abs_y) / (abs_y + abs_x) : (abs_x - abs_y) / (abs_x + abs_y));
210  const float angle(((x < 0.f) ? THR_QTR_PI : ONE_QTR_PI) + (0.1963f * r * r - 0.9817f) * r);
211 
212  return ((y < 0.f) ? -angle : angle); // negate if in quad III or IV
213 }
214 
215 //------------------------------------------------------------------------------------------------------------------------------------------
216 //------------------------------------------------------------------------------------------------------------------------------------------
217 
219 {
220  const ContributionList &contributionList(this->GetContributionList());
221  ContributionList::const_iterator lowerIter(contributionList.lower_bound(x - 3.f * m_sigma));
222  ContributionList::const_iterator upperIter(contributionList.upper_bound(x + 3.f * m_sigma));
223 
224  float sample(0.f);
225  const float gaussConstant(1.f / std::sqrt(2.f * M_PI * m_sigma * m_sigma));
226 
227  for (ContributionList::const_iterator iter = lowerIter; iter != upperIter; ++iter)
228  {
229  const float deltaSigma((x - iter->first) / m_sigma);
230  const float gaussian(gaussConstant * std::exp(-0.5f * deltaSigma * deltaSigma));
231  sample += iter->second * gaussian;
232  }
233 
234  return sample;
235 }
236 
237 //------------------------------------------------------------------------------------------------------------------------------------------
238 
240 {
241  m_contributionList.insert(ContributionList::value_type(x, weight));
242 }
243 
244 //------------------------------------------------------------------------------------------------------------------------------------------
245 
246 StatusCode RPhiFeatureTool::ReadSettings(const TiXmlHandle xmlHandle)
247 {
248  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
249  "FastScoreCheck", m_fastScoreCheck));
250 
251  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
252  "FastScoreOnly", m_fastScoreOnly));
253 
254  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
255  "FullScore", m_fullScore));
256 
257  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
258  "KernelEstimateSigma", m_kernelEstimateSigma));
259 
260  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
261  "Kappa", m_kappa));
262 
263  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
264  "MaxHitVertexDisplacement1D", m_maxHitVertexDisplacement1D));
265 
266  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
267  "MinFastScoreFraction", m_minFastScoreFraction));
268 
269  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
270  "FastHistogramNPhiBins", m_fastHistogramNPhiBins));
271 
272  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
273  "FastHistogramPhiMin", m_fastHistogramPhiMin));
274 
275  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
276  "FastHistogramPhiMax", m_fastHistogramPhiMax));
277 
278  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
279  "EnableFolding", m_enableFolding));
280 
281  return STATUS_CODE_SUCCESS;
282 }
283 
284 } // namespace lar_content
Float_t x
Definition: compare.C:6
bool m_fastScoreCheck
Whether to use the fast histogram based score to selectively avoid calling full or midway scores...
Header file for the kd tree linker algo template class.
MvaTypes::MvaFeatureVector MvaFeatureVector
Definition: LArMvaHelper.h:58
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const VertexSelectionBaseAlgorithm *const pAlgorithm, const pandora::Vertex *const pVertex, const VertexSelectionBaseAlgorithm::SlidingFitDataListMap &, const VertexSelectionBaseAlgorithm::ClusterListMap &, const VertexSelectionBaseAlgorithm::KDTreeMap &kdTreeMap, const VertexSelectionBaseAlgorithm::ShowerClusterListMap &, const float beamDeweightingScore, float &bestFastScore)
Run the tool.
unsigned int m_fastHistogramNPhiBins
Number of bins to use for fast score histograms.
Float_t y
Definition: compare.C:6
Class that implements the KDTree partition of 2D space and a closest point search algorithm...
Box structure used to define 2D field. It&#39;s used in KDTree building step to divide the detector space...
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
float m_fastHistogramPhiMin
Min value for fast score histograms.
static pandora::CartesianVector ProjectPosition(const pandora::Pandora &pandora, const pandora::CartesianVector &position3D, const pandora::HitType view)
Project 3D position into a given 2D view.
float m_kappa
Hit-deweighting offset, of form: weight = 1 / sqrt(distance + kappa), units cm.
bool m_fastScoreOnly
Whether to use the fast histogram based score only.
const ContributionList & GetContributionList() const
Get the contribution list.
float m_minFastScoreFraction
Fast score must be at least this fraction of best fast score to calculate full score.
TFile f
Definition: plotHisto.C:6
float atan2Fast(const float y, const float x) const
Fast estimate of std::atan2 function. Rather coarse (max |error| > 0.01) but should suffice for this ...
Header file for the geometry helper class.
Int_t max
Definition: plot.C:27
void search(const KDTreeBoxT< DIM > &searchBox, std::vector< KDTreeNodeInfoT< DATA, DIM > > &resRecHitList)
Search in the KDTree for all points that would be contained in the given searchbox The founded points...
std::map< pandora::HitType, const ShowerClusterList > ShowerClusterListMap
Map of shower cluster lists for passing to tools.
intermediate_table::const_iterator const_iterator
float GetFastScore(const KernelEstimate &kernelEstimateU, const KernelEstimate &kernelEstimateV, const KernelEstimate &kernelEstimateW) const
Get the score for a trio of kernel estimations, using fast histogram approach.
Header file for the cluster helper class.
float Sample(const float x) const
Sample the parameterised distribution at a specified x coordinate.
float m_maxHitVertexDisplacement1D
Max hit-vertex displacement in any one dimension for contribution to kernel estimation.
float GetFullScore(const KernelEstimate &kernelEstimateU, const KernelEstimate &kernelEstimateV, const KernelEstimate &kernelEstimateW) const
Get the score for a trio of kernel estimations, using kernel density estimation and full hit-by-hit s...
float m_fastHistogramPhiMax
Max value for fast score histograms.
bool m_fullScore
Whether to use the full kernel density estimation score, as opposed to the midway score...
std::map< pandora::HitType, const pandora::ClusterList & > ClusterListMap
Map array of cluster lists for passing to tools.
float m_kernelEstimateSigma
The Gaussian width to use for kernel estimation.
bool m_enableFolding
Whether to enable folding of -pi -> +pi phi distribution into 0 -> +pi region only.
Detector simulation of raw signals on wires.
double weight
Definition: plottest35.C:25
std::map< pandora::HitType, const SlidingFitDataList > SlidingFitDataListMap
Map of sliding fit data lists for passing to tools.
float GetMidwayScore(const KernelEstimate &kernelEstimateU, const KernelEstimate &kernelEstimateV, const KernelEstimate &kernelEstimateW) const
Get the score for a trio of kernel estimations, using kernel density estimation but with reduced (bin...
void FillKernelEstimate(const pandora::Vertex *const pVertex, const pandora::HitType hitType, VertexSelectionBaseAlgorithm::HitKDTree2D &kdTree, KernelEstimate &kernelEstimate) const
Use hits in clusters (in the provided kd tree) to fill a provided kernel estimate with hit-vertex rel...
void AddContribution(const float x, const float weight)
Add a contribution to the distribution.
std::multimap< float, float > ContributionList
Map from x coord to weight, ATTN avoid map.find, etc. with float key.
std::map< pandora::HitType, const std::reference_wrapper< HitKDTree2D > > KDTreeMap
Map array of hit kd trees for passing to tools.
KDTreeBox build_2d_kd_search_region(const pandora::CaloHit *const point, const float x_span, const float z_span)
build_2d_kd_search_region
Header file for the r/phi feature tool class.