Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
RPhiFeatureTool.cc
Go to the documentation of this file.
1
13
15
16using namespace pandora;
17
18namespace lar_content
19{
20
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
41 const VertexSelectionBaseAlgorithm::ShowerClusterListMap &, const float beamDeweightingScore, float &bestFastScore)
42{
44 std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
45
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
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
82float RPhiFeatureTool::GetFastScore(const KernelEstimate &kernelEstimateU, const KernelEstimate &kernelEstimateV, const KernelEstimate &kernelEstimateW) const
83{
87
88 for (const KernelEstimate::ContributionList::value_type &contribution : kernelEstimateU.GetContributionList())
89 histogramU.Fill(contribution.first, contribution.second);
90
91 for (const KernelEstimate::ContributionList::value_type &contribution : kernelEstimateV.GetContributionList())
92 histogramV.Fill(contribution.first, contribution.second);
93
94 for (const KernelEstimate::ContributionList::value_type &contribution : kernelEstimateW.GetContributionList())
95 histogramW.Fill(contribution.first, contribution.second);
96
97 // Is the below correct?
98 histogramU.Scale(1.f / histogramU.GetCumulativeSum());
99 histogramV.Scale(1.f / histogramV.GetCumulativeSum());
100 histogramW.Scale(1.f / histogramW.GetCumulativeSum());
101
102 // ATTN Need to renormalise histograms if ever want to directly compare fast and full scores
103 float figureOfMerit(0.f);
104
105 for (int xBin = 0; xBin < histogramU.GetNBinsX(); ++xBin)
106 {
107 const float binContentU(histogramU.GetBinContent(xBin));
108 const float binContentV(histogramV.GetBinContent(xBin));
109 const float binContentW(histogramW.GetBinContent(xBin));
110 figureOfMerit += binContentU * binContentU + binContentV * binContentV + binContentW * binContentW;
111 }
112
113 return figureOfMerit;
114}
115
116//------------------------------------------------------------------------------------------------------------------------------------------
117
118float RPhiFeatureTool::GetMidwayScore(const KernelEstimate &kernelEstimateU, const KernelEstimate &kernelEstimateV, const KernelEstimate &kernelEstimateW) const
119{
123
124 for (const KernelEstimate::ContributionList::value_type &contribution : kernelEstimateU.GetContributionList())
125 histogramU.Fill(contribution.first, contribution.second);
126
127 for (const KernelEstimate::ContributionList::value_type &contribution : kernelEstimateV.GetContributionList())
128 histogramV.Fill(contribution.first, contribution.second);
129
130 for (const KernelEstimate::ContributionList::value_type &contribution : kernelEstimateW.GetContributionList())
131 histogramW.Fill(contribution.first, contribution.second);
132
133 float figureOfMerit(0.f);
134
135 for (int xBin = 0; xBin < histogramU.GetNBinsX(); ++xBin)
136 {
137 const float binCenter(histogramU.GetXLow() + (static_cast<float>(xBin) + 0.5f) * histogramU.GetXBinWidth());
138 figureOfMerit += histogramU.GetBinContent(xBin) * kernelEstimateU.Sample(binCenter);
139 figureOfMerit += histogramV.GetBinContent(xBin) * kernelEstimateV.Sample(binCenter);
140 figureOfMerit += histogramW.GetBinContent(xBin) * kernelEstimateW.Sample(binCenter);
141 }
142
143 return figureOfMerit;
144}
145
146//------------------------------------------------------------------------------------------------------------------------------------------
147
148float RPhiFeatureTool::GetFullScore(const KernelEstimate &kernelEstimateU, const KernelEstimate &kernelEstimateV, const KernelEstimate &kernelEstimateW) const
149{
150 float figureOfMerit(0.f);
151
152 for (const KernelEstimate::ContributionList::value_type &contribution : kernelEstimateU.GetContributionList())
153 figureOfMerit += contribution.second * kernelEstimateU.Sample(contribution.first);
154
155 for (const KernelEstimate::ContributionList::value_type &contribution : kernelEstimateV.GetContributionList())
156 figureOfMerit += contribution.second * kernelEstimateV.Sample(contribution.first);
157
158 for (const KernelEstimate::ContributionList::value_type &contribution : kernelEstimateW.GetContributionList())
159 figureOfMerit += contribution.second * kernelEstimateW.Sample(contribution.first);
160
161 return figureOfMerit;
162}
163
164//------------------------------------------------------------------------------------------------------------------------------------------
165
166void RPhiFeatureTool::FillKernelEstimate(const Vertex *const pVertex, const HitType hitType,
167 VertexSelectionBaseAlgorithm::HitKDTree2D &kdTree, KernelEstimate &kernelEstimate) const
168{
169 const CartesianVector vertexPosition2D(LArGeometryHelper::ProjectPosition(this->GetPandora(), pVertex->GetPosition(), hitType));
171
173 kdTree.search(searchRegionHits, found);
174
175 for (const auto &hit : found)
176 {
177 const CartesianVector displacement(hit.data->GetPositionVector() - vertexPosition2D);
178 const float magnitude(displacement.GetMagnitude());
179
180 if (magnitude < std::numeric_limits<float>::epsilon())
181 continue;
182
183 float phi(this->atan2Fast(displacement.GetZ(), displacement.GetX()));
184 float weight(1.f / (std::sqrt(magnitude + std::fabs(m_kappa))));
185
186 if (m_enableFolding && (phi < 0.f))
187 {
188 phi += M_PI;
189 weight *= -1.f;
190 }
191
192 kernelEstimate.AddContribution(phi, weight);
193 }
194}
195
196//------------------------------------------------------------------------------------------------------------------------------------------
197
198float RPhiFeatureTool::atan2Fast(const float y, const float x) const
199{
200 const float ONE_QTR_PI(0.25f * M_PI);
201 const float THR_QTR_PI(0.75f * M_PI);
202
203 const float abs_y(std::max(std::fabs(y), std::numeric_limits<float>::epsilon()));
204 const float abs_x(std::fabs(x));
205
206 const float r((x < 0.f) ? (x + abs_y) / (abs_y + abs_x) : (abs_x - abs_y) / (abs_x + abs_y));
207 const float angle(((x < 0.f) ? THR_QTR_PI : ONE_QTR_PI) + (0.1963f * r * r - 0.9817f) * r);
208
209 return ((y < 0.f) ? -angle : angle); // negate if in quad III or IV
210}
211
212//------------------------------------------------------------------------------------------------------------------------------------------
213//------------------------------------------------------------------------------------------------------------------------------------------
214
216{
217 const ContributionList &contributionList(this->GetContributionList());
218 ContributionList::const_iterator lowerIter(contributionList.lower_bound(x - 3.f * m_sigma));
219 ContributionList::const_iterator upperIter(contributionList.upper_bound(x + 3.f * m_sigma));
220
221 float sample(0.f);
222 const float gaussConstant(1.f / std::sqrt(2.f * M_PI * m_sigma * m_sigma));
223
224 for (ContributionList::const_iterator iter = lowerIter; iter != upperIter; ++iter)
225 {
226 const float deltaSigma((x - iter->first) / m_sigma);
227 const float gaussian(gaussConstant * std::exp(-0.5f * deltaSigma * deltaSigma));
228 sample += iter->second * gaussian;
229 }
230
231 return sample;
232}
233
234//------------------------------------------------------------------------------------------------------------------------------------------
235
236void RPhiFeatureTool::KernelEstimate::AddContribution(const float x, const float weight)
237{
238 m_contributionList.insert(ContributionList::value_type(x, weight));
239}
240
241//------------------------------------------------------------------------------------------------------------------------------------------
242
244{
245 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "FastScoreCheck", m_fastScoreCheck));
246
247 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "FastScoreOnly", m_fastScoreOnly));
248
249 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "FullScore", m_fullScore));
250
252 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "KernelEstimateSigma", m_kernelEstimateSigma));
253
254 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "Kappa", m_kappa));
255
256 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
257 XmlHelper::ReadValue(xmlHandle, "MaxHitVertexDisplacement1D", m_maxHitVertexDisplacement1D));
258
260 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinFastScoreFraction", m_minFastScoreFraction));
261
263 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "FastHistogramNPhiBins", m_fastHistogramNPhiBins));
264
266 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "FastHistogramPhiMin", m_fastHistogramPhiMin));
267
269 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "FastHistogramPhiMax", m_fastHistogramPhiMax));
270
271 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "EnableFolding", m_enableFolding));
272
273 return STATUS_CODE_SUCCESS;
274}
275
276} // namespace lar_content
Grouping of header files for many classes of use in particle flow algorithms.
Header file for the kd tree linker algo template class.
Header file for the cluster helper class.
Header file for the geometry helper class.
Header file for the r/phi feature tool class.
#define PANDORA_RETURN_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
Definition StatusCodes.h:31
static const pandora::PandoraSettings * GetSettings(const pandora::Algorithm &algorithm)
Get the pandora settings instance.
Box structure used to define 2D field. It's used in KDTree building step to divide the detector space...
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...
static pandora::CartesianVector ProjectPosition(const pandora::Pandora &pandora, const pandora::CartesianVector &position3D, const pandora::HitType view)
Project 3D position into a given 2D view.
MvaTypes::MvaFeatureVector MvaFeatureVector
const float m_sigma
The assigned width.
const ContributionList & GetContributionList() const
Get the contribution list.
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.
float Sample(const float x) const
Sample the parameterised distribution at a specified x coordinate.
bool m_fullScore
Whether to use the full kernel density estimation score, as opposed to the midway score.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
bool m_enableFolding
Whether to enable folding of -pi -> +pi phi distribution into 0 -> +pi region only.
bool m_fastScoreOnly
Whether to use the fast histogram based score only.
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_maxHitVertexDisplacement1D
Max hit-vertex displacement in any one dimension for contribution to kernel estimation.
float m_fastHistogramPhiMin
Min value for fast score histograms.
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 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.
float m_fastHistogramPhiMax
Max value for fast score histograms.
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 ...
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...
bool m_fastScoreCheck
Whether to use the fast histogram based score to selectively avoid calling full or midway scores.
float m_kappa
Hit-deweighting offset, of form: weight = 1 / sqrt(distance + kappa), units cm.
float m_kernelEstimateSigma
The Gaussian width to use for kernel estimation.
unsigned int m_fastHistogramNPhiBins
Number of bins to use for fast score histograms.
RPhiFeatureTool()
Default constructor.
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.
float m_minFastScoreFraction
Fast score must be at least this fraction of best fast score to calculate full score.
std::map< pandora::HitType, const SlidingFitDataList > SlidingFitDataListMap
Map of sliding fit data lists for passing to tools.
std::map< pandora::HitType, const pandora::ClusterList & > ClusterListMap
Map array of cluster lists for passing to tools.
std::map< pandora::HitType, const std::reference_wrapper< HitKDTree2D > > KDTreeMap
Map array of hit kd trees for passing to tools.
std::map< pandora::HitType, const ShowerClusterList > ShowerClusterListMap
Map of shower cluster lists for passing to tools.
CartesianVector class.
float GetX() const
Get the cartesian x coordinate.
float GetZ() const
Get the cartesian z coordinate.
float GetMagnitude() const
Get the magnitude.
Histogram class.
Definition Histograms.h:25
int GetNBinsX() const
Get the number of x bins.
Definition Histograms.h:611
float GetCumulativeSum() const
Get the cumulative sum of bin entries in the histogram (ignores overflow and underflow bins)
Definition Histograms.h:667
void Fill(const float valueX, const float weight=1.f)
Add an entry to the histogram.
float GetXBinWidth() const
Get the x bin width.
Definition Histograms.h:632
float GetBinContent(const int binX) const
Get the content of a specified bin.
Definition Histograms.cc:91
float GetXLow() const
Get the min binned x value.
Definition Histograms.h:618
void Scale(const float scaleFactor)
Scale contents of all histogram bins by a specified factor.
bool ShouldDisplayAlgorithmInfo() const
Whether to display algorithm information during processing.
const std::string & GetType() const
Get the type.
Definition Process.h:102
const Pandora & GetPandora() const
Get the associated pandora instance.
Definition Process.h:116
const std::string & GetInstanceName() const
Get the instance name.
Definition Process.h:109
Vertex class.
Definition Vertex.h:26
const CartesianVector & GetPosition() const
Get the vertex position.
Definition Vertex.h:103
static StatusCode ReadValue(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, T &t)
Read a value from an xml element.
Definition XmlHelper.h:136
KDTreeBox build_2d_kd_search_region(const pandora::CaloHit *const point, const float x_span, const float z_span)
build_2d_kd_search_region
HitType
Calorimeter hit type enum.
StatusCode
The StatusCode enum.