Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
LArConnectionPathwayHelper.cc
Go to the documentation of this file.
1
9#include "Pandora/Algorithm.h"
10#include "Pandora/Pandora.h"
12
14
19
20#include <limits>
21
22using namespace pandora;
23
24namespace lar_content
25{
26
27//------------------------------------------------------------------------------------------------------------------------------------------
28
33
34//------------------------------------------------------------------------------------------------------------------------------------------
35
37{
38 return (m_referencePoint.GetDistanceSquared(lhs->GetPositionVector()) < m_referencePoint.GetDistanceSquared(rhs->GetPositionVector()));
39}
40
41//------------------------------------------------------------------------------------------------------------------------------------------
42// Finding 3D Shower Start Position
43//------------------------------------------------------------------------------------------------------------------------------------------
44
45bool LArConnectionPathwayHelper::FindShowerStarts3D(const Algorithm *const pAlgorithm, const ParticleFlowObject *const pShowerPfo,
46 const ProtoShowerMatch &protoShowerMatch, const CartesianVector &nuVertexPosition, const float maxSeparationFromHit,
47 const float maxProjectionSeparation, const float maxXSeparation, CartesianPointVector &showerStarts3D)
48{
49 const ProtoShower &protoShowerU(protoShowerMatch.GetProtoShowerU());
50 const ProtoShower &protoShowerV(protoShowerMatch.GetProtoShowerV());
51 const ProtoShower &protoShowerW(protoShowerMatch.GetProtoShowerW());
52 const Consistency consistency(protoShowerMatch.GetConsistencyType());
53
54 bool uFound(false), vFound(false), wFound(false);
55 CartesianVector uShowerStart3D(0.f, 0.f, 0.f), vShowerStart3D(0.f, 0.f, 0.f), wShowerStart3D(0.f, 0.f, 0.f);
56
57 CaloHitList caloHitList3D;
58 LArPfoHelper::GetCaloHits(pShowerPfo, TPC_3D, caloHitList3D);
59
60 if (consistency == Consistency::POSITION)
61 {
62 LArConnectionPathwayHelper::FindShowerStartFromPosition(pAlgorithm, protoShowerU, protoShowerV, protoShowerW, uShowerStart3D);
63 vShowerStart3D = uShowerStart3D;
64 wShowerStart3D = uShowerStart3D;
65
66 if (LArClusterHelper::GetClosestDistance(uShowerStart3D, caloHitList3D) < maxSeparationFromHit)
67 {
68 uFound = true;
69 vFound = true;
70 wFound = true;
71 }
72 }
73 else if (consistency == Consistency::DIRECTION)
74 {
76 pAlgorithm, protoShowerU, protoShowerV, protoShowerW, uShowerStart3D, vShowerStart3D, wShowerStart3D))
77 {
78 if (LArClusterHelper::GetClosestDistance(uShowerStart3D, caloHitList3D) < maxSeparationFromHit)
79 uFound = true;
80
81 if (LArClusterHelper::GetClosestDistance(vShowerStart3D, caloHitList3D) < maxSeparationFromHit)
82 vFound = true;
83
84 if (LArClusterHelper::GetClosestDistance(wShowerStart3D, caloHitList3D) < maxSeparationFromHit)
85 wFound = true;
86 }
87 }
88
89 if (!uFound || (consistency == Consistency::X_PROJECTION))
90 {
92 pAlgorithm, protoShowerU, protoShowerV, protoShowerW, maxProjectionSeparation, maxXSeparation, uShowerStart3D) ||
94 pAlgorithm, protoShowerU, protoShowerV, protoShowerW, maxProjectionSeparation, maxXSeparation, uShowerStart3D) ||
96 pAlgorithm, protoShowerU, protoShowerW, protoShowerV, maxProjectionSeparation, maxXSeparation, uShowerStart3D))
97 {
98 uFound = true;
99 }
100
102 pAlgorithm, protoShowerV, protoShowerW, protoShowerU, maxProjectionSeparation, maxXSeparation, vShowerStart3D) ||
104 pAlgorithm, protoShowerV, protoShowerW, protoShowerU, maxProjectionSeparation, maxXSeparation, vShowerStart3D) ||
106 pAlgorithm, protoShowerV, protoShowerU, protoShowerW, maxProjectionSeparation, maxXSeparation, vShowerStart3D))
107 {
108 vFound = true;
109 }
110
112 pAlgorithm, protoShowerW, protoShowerU, protoShowerV, maxProjectionSeparation, maxXSeparation, wShowerStart3D) ||
114 pAlgorithm, protoShowerW, protoShowerU, protoShowerV, maxProjectionSeparation, maxXSeparation, wShowerStart3D) ||
116 pAlgorithm, protoShowerW, protoShowerV, protoShowerU, maxProjectionSeparation, maxXSeparation, wShowerStart3D))
117 {
118 wFound = true;
119 }
120 }
121
122 CartesianPointVector foundShowerStarts3D;
123
124 if (uFound)
125 foundShowerStarts3D.push_back(uShowerStart3D);
126
127 if (vFound)
128 foundShowerStarts3D.push_back(vShowerStart3D);
129
130 if (wFound)
131 foundShowerStarts3D.push_back(wShowerStart3D);
132
133 if (foundShowerStarts3D.empty())
134 return false;
135
136 std::sort(foundShowerStarts3D.begin(), foundShowerStarts3D.end(), LArConnectionPathwayHelper::SortByDistanceToPoint(nuVertexPosition));
137
138 // ATTN: We need there to be three
139 showerStarts3D.push_back(foundShowerStarts3D.front());
140 showerStarts3D.push_back((foundShowerStarts3D.size() == 3) ? foundShowerStarts3D[1] : foundShowerStarts3D[0]);
141 showerStarts3D.push_back(foundShowerStarts3D.back());
142
143 return true;
144}
145
146//------------------------------------------------------------------------------------------------------------------------------------------
147
148void LArConnectionPathwayHelper::FindShowerStartFromPosition(const Algorithm *const pAlgorithm, const ProtoShower &protoShowerU,
149 const ProtoShower &protoShowerV, const ProtoShower &protoShowerW, CartesianVector &showerStart3D)
150{
151 const CartesianVector showerStartU(protoShowerU.GetShowerCore().GetStartPosition());
152 const CartesianVector showerStartV(protoShowerV.GetShowerCore().GetStartPosition());
153 const CartesianVector showerStartW(protoShowerW.GetShowerCore().GetStartPosition());
154
155 float chi2(0.0);
157 pAlgorithm->GetPandora(), TPC_VIEW_U, TPC_VIEW_V, TPC_VIEW_W, showerStartU, showerStartV, showerStartW, showerStart3D, chi2);
158}
159
160//------------------------------------------------------------------------------------------------------------------------------------------
161
163 const ProtoShower &protoShowerV, const ProtoShower &protoShowerW, CartesianVector &uShowerStart3D, CartesianVector &vShowerStart3D,
164 CartesianVector &wShowerStart3D)
165{
166
167 if (!LArConnectionPathwayHelper::FindShowerStartFromDirection(pAlgorithm, protoShowerU, protoShowerV, protoShowerW, uShowerStart3D))
168 return false;
169
170 if (!LArConnectionPathwayHelper::FindShowerStartFromDirection(pAlgorithm, protoShowerV, protoShowerW, protoShowerU, vShowerStart3D))
171 return false;
172
173 if (!LArConnectionPathwayHelper::FindShowerStartFromDirection(pAlgorithm, protoShowerW, protoShowerU, protoShowerV, wShowerStart3D))
174 return false;
175
176 return true;
177}
178
179//------------------------------------------------------------------------------------------------------------------------------------------
180
182 const ProtoShower &protoShowerA, const ProtoShower &protoShowerB, CartesianVector &showerStart3D)
183{
184 const CartesianVector &showerStart(protoShower.GetShowerCore().GetStartPosition());
185 const float x(showerStart.GetX());
186 CartesianVector showerStartA(0.f, 0.f, 0.f), showerStartB(0.f, 0.f, 0.f);
187
188 if (!LArConnectionPathwayHelper::ProjectShowerStartByDirection(protoShowerA, x, showerStartA))
189 return false;
190
191 if (!LArConnectionPathwayHelper::ProjectShowerStartByDirection(protoShowerB, x, showerStartB))
192 return false;
193
194 float chi2(0.0);
195 const HitType hitType(protoShower.GetSpineHitList().front()->GetHitType());
196 const HitType hitTypeA(protoShowerA.GetSpineHitList().front()->GetHitType());
197 const HitType hitTypeB(protoShowerB.GetSpineHitList().front()->GetHitType());
198
200 pAlgorithm->GetPandora(), hitType, hitTypeA, hitTypeB, showerStart, showerStartA, showerStartB, showerStart3D, chi2);
201
202 return false;
203}
204
205//------------------------------------------------------------------------------------------------------------------------------------------
206
207bool LArConnectionPathwayHelper::ProjectShowerStartByDirection(const ProtoShower &protoShower, const float x, CartesianVector &showerStart2D)
208{
209 const CartesianVector &viewShowerStart(protoShower.GetShowerCore().GetStartPosition());
210 const CartesianVector &viewNuVertex(protoShower.GetConnectionPathway().GetStartPosition());
211 const CartesianVector &viewPeakDirection(protoShower.GetConnectionPathway().GetStartDirection());
212 const CartesianVector &displacement(viewShowerStart - viewNuVertex);
213 const float transverse(viewPeakDirection.GetCrossProduct(displacement).GetMagnitude());
214
215 if (transverse > 1.f)
216 return false;
217
218 const CartesianVector xAxis(1.f, 0.f, 0.f);
219 const float cosTheta(std::fabs(viewPeakDirection.GetCosOpeningAngle(xAxis)));
220
221 showerStart2D = viewNuVertex + (viewPeakDirection * (std::fabs(x - viewNuVertex.GetX()) * cosTheta));
222
223 return true;
224}
225
226//------------------------------------------------------------------------------------------------------------------------------------------
227
229 const ProtoShower &protoShower1, const ProtoShower &protoShower2, const float maxSeparation, const float maxXSeparation, CartesianVector &showerStart3D)
230{
231 const CartesianVector showerStart(protoShower.GetShowerCore().GetStartPosition());
232 CartesianVector showerStart1(0.f, 0.f, 0.f), showerStart2(0.f, 0.f, 0.f);
233
234 const HitType hitType(protoShower.GetSpineHitList().front()->GetHitType());
235 const HitType hitType1(protoShower1.GetSpineHitList().front()->GetHitType());
236 const HitType hitType2(protoShower2.GetSpineHitList().front()->GetHitType());
237
238 if (!LArConnectionPathwayHelper::FindClosestSpinePosition(protoShower1, showerStart, maxXSeparation, showerStart1))
239 return false;
240
241 if (!LArConnectionPathwayHelper::FindClosestSpinePosition(protoShower2, showerStart, maxXSeparation, showerStart2))
242 return false;
243
244 float chi2(0.f);
245 CartesianVector projection(0.f, 0.f, 0.f), projection1(0.f, 0.f, 0.f), projection2(0.f, 0.f, 0.f);
246
247 LArGeometryHelper::MergeTwoPositions(pAlgorithm->GetPandora(), hitType1, hitType2, showerStart1, showerStart2, projection, chi2);
248 const float separationSquared((projection - showerStart).GetMagnitudeSquared());
249
250 LArGeometryHelper::MergeTwoPositions(pAlgorithm->GetPandora(), hitType, hitType2, showerStart, showerStart2, projection1, chi2);
251 const float separationSquared1((projection1 - showerStart1).GetMagnitudeSquared());
252
253 LArGeometryHelper::MergeTwoPositions(pAlgorithm->GetPandora(), hitType, hitType1, showerStart, showerStart1, projection2, chi2);
254 const float separationSquared2((projection2 - showerStart2).GetMagnitudeSquared());
255
256 if ((separationSquared > maxSeparation * maxSeparation) || (separationSquared1 > maxSeparation * maxSeparation) ||
257 (separationSquared2 > maxSeparation * maxSeparation))
258 {
259 return false;
260 }
261
263 pAlgorithm->GetPandora(), hitType, hitType1, hitType2, showerStart, showerStart1, showerStart2, showerStart3D, chi2);
264
265 return true;
266}
267
268//------------------------------------------------------------------------------------------------------------------------------------------
269
271 const ProtoShower &protoShower, const CartesianVector &showerStart3D, const float maxXSeparation, CartesianVector &foundShowerStart)
272{
273 bool found(false);
274 float lowestL(std::numeric_limits<float>::max());
275
276 for (const CaloHit *const pCaloHit : protoShower.GetSpineHitList())
277 {
278 if (std::fabs(pCaloHit->GetPositionVector().GetX() - showerStart3D.GetX()) > maxXSeparation)
279 continue;
280
281 const float lVertex(protoShower.GetConnectionPathway().GetStartDirection().GetDotProduct(
282 pCaloHit->GetPositionVector() - protoShower.GetConnectionPathway().GetStartPosition()));
283
284 if ((lVertex > 0.f) && (lVertex < lowestL))
285 {
286 lowestL = lVertex;
287 foundShowerStart = pCaloHit->GetPositionVector();
288 found = true;
289 }
290 }
291
292 return found;
293}
294
295//------------------------------------------------------------------------------------------------------------------------------------------
296
298 const ProtoShower &protoShower1, const ProtoShower &protoShower2, const float maxSeparation, const float maxXSeparation, CartesianVector &showerStart3D)
299{
300 const CartesianVector showerStart(protoShower.GetShowerCore().GetStartPosition());
301 CartesianVector showerStart1(0.f, 0.f, 0.f);
302
303 const HitType hitType(protoShower.GetSpineHitList().front()->GetHitType());
304 const HitType hitType1(protoShower1.GetSpineHitList().front()->GetHitType());
305
306 if (!LArConnectionPathwayHelper::FindClosestSpinePosition(protoShower1, showerStart, maxXSeparation, showerStart1))
307 return false;
308
309 float chi2(0.f);
310 CartesianVector projection2(0.f, 0.f, 0.f);
311
312 LArGeometryHelper::MergeTwoPositions(pAlgorithm->GetPandora(), hitType, hitType1, showerStart, showerStart1, projection2, chi2);
313
314 // Now make sure that they agree...
315 const CaloHitList &caloHitList2(protoShower2.GetSpineHitList());
316 const float separation(LArClusterHelper::GetClosestDistance(projection2, caloHitList2));
317
318 if (separation > maxSeparation)
319 return false;
320
321 LArGeometryHelper::MergeTwoPositions3D(pAlgorithm->GetPandora(), hitType, hitType1, showerStart, showerStart1, showerStart3D, chi2);
322
323 return true;
324}
325
326//------------------------------------------------------------------------------------------------------------------------------------------
327// Ordeing Functions
328//------------------------------------------------------------------------------------------------------------------------------------------
329
331 const float value1, const float value2, const float value3, float &minValue, float &middleValue, float &maxValue)
332{
333 FloatVector values({value1, value2, value3});
334
335 std::sort(values.begin(), values.end());
336
337 minValue = values.at(0);
338 middleValue = values.at(1);
339 maxValue = values.at(2);
340}
341
342//------------------------------------------------------------------------------------------------------------------------------------------
343
344} // namespace lar_content
Header file for the algorithm class.
Header file for the cluster helper class.
Header file for the connection pathway helper class.
Header file for the geometry helper class.
Header file for the pfo helper class.
Header file for the ProtoShower class.
Header file for the pandora class.
Header file defining relevant internal typedefs, sort and string conversion functions.
const pandora::CartesianVector & GetStartDirection() const
Get the start direction of the connection pathway.
const pandora::CartesianVector & GetStartPosition() const
Get the start position of the connection pathway.
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.
const pandora::CartesianVector m_referencePoint
The point relative to which constituent hits are ordered.
bool operator()(const pandora::CartesianVector &lhs, const pandora::CartesianVector &rhs)
Sort constituent hits by their position relative to a referencePoint.
static bool FindShowerStartFromXProjection(const pandora::Algorithm *const pAlgorithm, const ProtoShower &protoShower, const ProtoShower &protoShower1, const ProtoShower &protoShower2, const float maxSeparation, const float maxXSeparation, pandora::CartesianVector &showerStart3D)
Create a 3D shower start position from an input 2D position, assuming consistency of the drift coordi...
static bool FindShowerStartFromDirection(const pandora::Algorithm *const pAlgorithm, const ProtoShower &protoShowerU, const ProtoShower &protoShowerV, const ProtoShower &protoShowerW, pandora::CartesianVector &uShowerStart3D, pandora::CartesianVector &vShowerStart3D, pandora::CartesianVector &wShowerStart3D)
Create a 3D shower start position from each input 2D position, assuming consistency of initial direct...
static void GetMinMiddleMax(const float value1, const float value2, const float value3, float &minValue, float &middleValue, float &maxValue)
Determine the lowest, median and highest value from an input of three numbers.
static bool ProjectShowerStartByDirection(const ProtoShower &protoShower, const float x, pandora::CartesianVector &showerStart2D)
Find a 2D shower start, from a drift coordinate by assuming consistency of initial direction.
static void FindShowerStartFromPosition(const pandora::Algorithm *const pAlgorithm, const ProtoShower &protoShowerU, const ProtoShower &protoShowerV, const ProtoShower &protoShowerW, pandora::CartesianVector &showerStart3D)
Create 3D shower start position from three input 2D positions, assuming consistency of position.
static bool FindShowerStartFromXProjectionRelaxed(const pandora::Algorithm *const pAlgorithm, const ProtoShower &protoShower, const ProtoShower &protoShower1, const ProtoShower &protoShower2, const float maxSeparation, const float maxXSeparation, pandora::CartesianVector &showerStart3D)
A relaxed approach to create a 3D shower start position from an input 2D position,...
static bool FindClosestSpinePosition(const ProtoShower &protoShower, const pandora::CartesianVector &showerStart3D, const float maxXSeparation, pandora::CartesianVector &foundShowerStart)
Find the 2D spine hit that is closest to the neutrino vertex and shares a drift coordinate with an in...
static bool FindShowerStarts3D(const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pShowerPfo, const ProtoShowerMatch &protoShowerMatch, const pandora::CartesianVector &nuVertexPosition, const float maxSeparationFromHit, const float maxProjectionSeparation, const float maxXSeparation, pandora::CartesianPointVector &showerStarts3D)
Create 3D shower start position(s) from three input 2D positions.
static float MergeTwoPositions(const pandora::Pandora &pandora, const pandora::HitType view1, const pandora::HitType view2, const float position1, const float position2)
Merge two views (U,V) to give a third view (Z).
static void MergeTwoPositions3D(const pandora::Pandora &pandora, const pandora::HitType view1, const pandora::HitType view2, const pandora::CartesianVector &position1, const pandora::CartesianVector &position2, pandora::CartesianVector &position3D, float &chiSquared)
Merge 2D positions from two views to give unified 3D position.
static void MergeThreePositions3D(const pandora::Pandora &pandora, const pandora::HitType view1, const pandora::HitType view2, const pandora::HitType view3, const pandora::CartesianVector &position1, const pandora::CartesianVector &position2, const pandora::CartesianVector &position3, pandora::CartesianVector &position3D, float &chiSquared)
Merge 2D positions from three views to give unified 3D position.
static void GetCaloHits(const pandora::PfoList &pfoList, const pandora::HitType &hitType, pandora::CaloHitList &caloHitList)
Get a list of calo hits of a particular hit type from a list of pfos.
const ShowerCore & GetShowerCore() const
Get the shower core.
const ConnectionPathway & GetConnectionPathway() const
Get the connection pathway.
const pandora::CaloHitList & GetSpineHitList() const
Get the spine hit list.
ProtoShowerMatch class.
const ProtoShower & GetProtoShowerV() const
Get the V view ProtoShower.
const ProtoShower & GetProtoShowerW() const
Get the W view ProtoShower.
const Consistency & GetConsistencyType() const
Get the consistency type.
const ProtoShower & GetProtoShowerU() const
Get the U view ProtoShower.
const pandora::CartesianVector & GetStartPosition() const
Get the start position of the shower core.
Algorithm class. Algorithm addresses are held only by the algorithm manager. They have a fully define...
Definition Algorithm.h:21
CaloHit class.
Definition CaloHit.h:26
const CartesianVector & GetPositionVector() const
Get the position vector of center of calorimeter cell, units mm.
Definition CaloHit.h:350
CartesianVector class.
float GetCosOpeningAngle(const CartesianVector &rhs) const
Get the cosine of the opening angle of the cartesian vector with respect to a second cartesian vector...
float GetX() const
Get the cartesian x coordinate.
float GetDistanceSquared(const CartesianVector &rhs) const
Get the distance squared of a cartesian vector with respect to a second cartesian vector.
float GetDotProduct(const CartesianVector &rhs) const
Get the dot product of the cartesian vector with a second cartesian vector.
float GetMagnitude() const
Get the magnitude.
CartesianVector GetCrossProduct(const CartesianVector &rhs) const
Get the cross product of the cartesian vector with a second cartesian vector.
ParticleFlowObject class.
const Pandora & GetPandora() const
Get the associated pandora instance.
Definition Process.h:116
Consistency
Consistency enumeration.
HitType
Calorimeter hit type enum.
std::vector< CartesianVector > CartesianPointVector
MANAGED_CONTAINER< const CaloHit * > CaloHitList
std::vector< float > FloatVector