Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
LArTwoDSlidingShowerFitResult.cc
Go to the documentation of this file.
1
9#include "Objects/Cluster.h"
10
12
14
15#include <algorithm>
16#include <cmath>
17#include <limits>
18
19using namespace pandora;
20
21namespace lar_content
22{
23
24template <typename T>
26 const T *const pT, const unsigned int slidingFitWindow, const float slidingFitLayerPitch, const float showerEdgeMultiplier) :
27 m_showerFitResult(TwoDSlidingFitResult(pT, slidingFitWindow, slidingFitLayerPitch)),
28 m_negativeEdgeFitResult(TwoDSlidingShowerFitResult::LArTwoDShowerEdgeFit(pT, m_showerFitResult, NEGATIVE_SHOWER_EDGE, showerEdgeMultiplier)),
29 m_positiveEdgeFitResult(TwoDSlidingShowerFitResult::LArTwoDShowerEdgeFit(pT, m_showerFitResult, POSITIVE_SHOWER_EDGE, showerEdgeMultiplier))
30{
31}
32
33//------------------------------------------------------------------------------------------------------------------------------------------
34
35void TwoDSlidingShowerFitResult::GetShowerEdges(const float x, const bool widenIfAmbiguity, FloatVector &edgePositions) const
36{
37 edgePositions.clear();
38 CartesianPointVector fitPositionVector;
40 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, this->GetNegativeEdgeFitResult().GetGlobalFitPositionListAtX(x, fitPositionVector));
42 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, this->GetPositiveEdgeFitResult().GetGlobalFitPositionListAtX(x, fitPositionVector));
43
44 if (fitPositionVector.size() < 2)
45 {
46 float minXn(0.f), maxXn(0.f), minXp(0.f), maxXp(0.f);
47 this->GetNegativeEdgeFitResult().GetMinAndMaxX(minXn, maxXn);
48 this->GetPositiveEdgeFitResult().GetMinAndMaxX(minXp, maxXp);
49 const float minX(std::min(minXn, minXp)), maxX(std::max(maxXn, maxXp));
50
51 if ((x < minX) || (x > maxX))
52 return;
53
54 float minZn(0.f), maxZn(0.f), minZp(0.f), maxZp(0.f);
55 this->GetNegativeEdgeFitResult().GetMinAndMaxZ(minZn, maxZn);
56 this->GetPositiveEdgeFitResult().GetMinAndMaxZ(minZp, maxZp);
57 const float minZ(std::min(minZn, minZp)), maxZ(std::max(maxZn, maxZp));
58
59 if (!widenIfAmbiguity)
60 {
61 return;
62 }
63 else if (fitPositionVector.empty())
64 {
65 fitPositionVector.push_back(CartesianVector(x, 0.f, minZ));
66 fitPositionVector.push_back(CartesianVector(x, 0.f, maxZ));
67 }
68 else if (1 == fitPositionVector.size())
69 {
70 // ATTN Could improve sophistication of choice of second bounding edge
71 const float existingEdge(fitPositionVector.front().GetZ());
72 const float secondEdge((std::fabs(existingEdge - minZ) < std::fabs(existingEdge - maxZ)) ? minZ : maxZ);
73 fitPositionVector.push_back(CartesianVector(x, 0.f, secondEdge));
74 }
75 }
76
77 FloatVector localEdgePositions;
78 for (const CartesianVector &fitPosition : fitPositionVector)
79 localEdgePositions.push_back(fitPosition.GetZ());
80
81 if (localEdgePositions.size() < 2)
82 throw StatusCodeException(STATUS_CODE_FAILURE);
83
84 std::sort(localEdgePositions.begin(), localEdgePositions.end());
85 edgePositions.push_back(localEdgePositions.front());
86 edgePositions.push_back(localEdgePositions.back());
87}
88
89//------------------------------------------------------------------------------------------------------------------------------------------
90
92 const Cluster *const pCluster, const TwoDSlidingFitResult &fullShowerFit, const ShowerEdge showerEdge, const float showerEdgeMultiplier)
93{
94 CartesianPointVector pointVector;
95 LArClusterHelper::GetCoordinateVector(pCluster, pointVector);
96 return TwoDSlidingShowerFitResult::LArTwoDShowerEdgeFit(&pointVector, fullShowerFit, showerEdge, showerEdgeMultiplier);
97}
98
99//------------------------------------------------------------------------------------------------------------------------------------------
100
102 const TwoDSlidingFitResult &fullShowerFit, const ShowerEdge showerEdge, const float showerEdgeMultiplier)
103{
104 // Examine all possible fit contributions
105 FitCoordinateMap fitCoordinateMap;
106
107 for (const CartesianVector &hitPosition : *pPointVector)
108 {
109 float rL(0.f), rT(0.f);
110 fullShowerFit.GetLocalPosition(hitPosition, rL, rT);
111 rT *= showerEdgeMultiplier;
112
113 CartesianVector fullShowerFitPosition(0.f, 0.f, 0.f);
114 if (STATUS_CODE_SUCCESS != fullShowerFit.GetGlobalFitPosition(rL, fullShowerFitPosition))
115 continue;
116
117 float rLFit(0.f), rTFit(0.f);
118 fullShowerFit.GetLocalPosition(fullShowerFitPosition, rLFit, rTFit);
119
120 const float rTDiff(rT - rTFit);
121 if (((POSITIVE_SHOWER_EDGE == showerEdge) && (rTDiff < 0.f)) || ((NEGATIVE_SHOWER_EDGE == showerEdge) && (rTDiff > 0.f)))
122 rT = rTFit;
123
124 const int layer(fullShowerFit.GetLayer(rL));
125 fitCoordinateMap[layer].push_back(FitCoordinate(rL, rT));
126 }
127
128 // Select fit contributions representing relevant shower edge
129 LayerFitContributionMap layerFitContributionMap;
130
131 for (const FitCoordinateMap::value_type &mapEntry : fitCoordinateMap)
132 {
133 // ATTN Could modify this hit selection, e.g. add inertia to edge positions
134 bool bestFitCoordinateFound(false);
135 FitCoordinate bestFitCoordinate = (POSITIVE_SHOWER_EDGE == showerEdge) ? FitCoordinate(0.f, -std::numeric_limits<float>::max())
136 : FitCoordinate(0.f, +std::numeric_limits<float>::max());
137
138 for (const FitCoordinate &fitCoordinate : mapEntry.second)
139 {
140 if (((POSITIVE_SHOWER_EDGE == showerEdge) && (fitCoordinate.second > bestFitCoordinate.second)) ||
141 ((NEGATIVE_SHOWER_EDGE == showerEdge) && (fitCoordinate.second < bestFitCoordinate.second)))
142 {
143 bestFitCoordinate = fitCoordinate;
144 bestFitCoordinateFound = true;
145 }
146 }
147
148 if (bestFitCoordinateFound)
149 layerFitContributionMap[mapEntry.first].AddPoint(bestFitCoordinate.first, bestFitCoordinate.second);
150 }
151
152 return TwoDSlidingFitResult(fullShowerFit.GetLayerFitHalfWindow(), fullShowerFit.GetLayerPitch(), fullShowerFit.GetAxisIntercept(),
153 fullShowerFit.GetAxisDirection(), fullShowerFit.GetOrthoDirection(), layerFitContributionMap);
154}
155
156//------------------------------------------------------------------------------------------------------------------------------------------
157//------------------------------------------------------------------------------------------------------------------------------------------
158
159template TwoDSlidingShowerFitResult::TwoDSlidingShowerFitResult(const pandora::Cluster *const, const unsigned int, const float, const float);
160template TwoDSlidingShowerFitResult::TwoDSlidingShowerFitResult(const pandora::CartesianPointVector *const, const unsigned int, const float, const float);
161
162} // namespace lar_content
Header file for the cluster class.
Header file for the cluster helper class.
Header file for the lar two dimensional sliding shower fit result class.
#define PANDORA_THROW_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
Definition StatusCodes.h:55
static void GetCoordinateVector(const pandora::Cluster *const pCluster, pandora::CartesianPointVector &coordinateVector)
Get vector of hit coordinates from an input cluster.
void GetLocalPosition(const pandora::CartesianVector &position, float &rL, float &rT) const
Get local sliding fit coordinates for a given global position.
pandora::StatusCode GetGlobalFitPosition(const float rL, pandora::CartesianVector &position) const
Get global fit position for a given longitudinal coordinate.
const pandora::CartesianVector & GetAxisIntercept() const
Get the axis intercept position.
float GetLayerPitch() const
Get the layer pitch, units cm.
unsigned int GetLayerFitHalfWindow() const
Get the layer fit half window.
const pandora::CartesianVector & GetOrthoDirection() const
Get the orthogonal direction vector.
int GetLayer(const float rL) const
Get layer number for given sliding linear fit longitudinal coordinate.
const pandora::CartesianVector & GetAxisDirection() const
Get the axis direction vector.
void GetMinAndMaxX(float &minX, float &maxX) const
Get the minimum and maximum x coordinates associated with the sliding fit.
void GetMinAndMaxZ(float &minZ, float &maxZ) const
Get the minimum and maximum z coordinates associated with the sliding fit.
void GetShowerEdges(const float x, const bool widenIfAmbiguity, pandora::FloatVector &edgePositions) const
Get the most appropriate shower edges at a given x coordinate.
const TwoDSlidingFitResult & GetNegativeEdgeFitResult() const
Get the sliding fit result for the negative shower edge.
TwoDSlidingShowerFitResult(const T *const pT, const unsigned int slidingFitWindow, const float slidingFitLayerPitch, const float showerEdgeMultiplier=1.f)
Constructor.
static TwoDSlidingFitResult LArTwoDShowerEdgeFit(const pandora::Cluster *const pCluster, const TwoDSlidingFitResult &fullShowerFit, const ShowerEdge showerEdge, const float showerEdgeMultiplier)
Perform two dimensional sliding fit to shower edge, using specified primary axis.
const TwoDSlidingFitResult & GetPositiveEdgeFitResult() const
Get the sliding fit result for the positive shower edge.
std::map< int, FitCoordinateList > FitCoordinateMap
CartesianVector class.
Cluster class.
Definition Cluster.h:31
StatusCodeException class.
std::map< int, LayerFitContribution > LayerFitContributionMap
std::vector< CartesianVector > CartesianPointVector
std::vector< float > FloatVector