LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
LArConnectionPathwayHelper.cc
Go to the documentation of this file.
1 
9 #include "Pandora/Algorithm.h"
10 #include "Pandora/Pandora.h"
11 #include "Pandora/PandoraInternal.h"
12 
14 
19 
20 #include <limits>
21 
22 using namespace pandora;
23 
24 namespace lar_content
25 {
26 
27 //------------------------------------------------------------------------------------------------------------------------------------------
28 
29 bool LArConnectionPathwayHelper::SortByDistanceToPoint::operator()(const CartesianVector &lhs, const CartesianVector &rhs)
30 {
31  return (m_referencePoint.GetDistanceSquared(lhs) < m_referencePoint.GetDistanceSquared(rhs));
32 }
33 
34 //------------------------------------------------------------------------------------------------------------------------------------------
35 
36 bool LArConnectionPathwayHelper::SortByDistanceToPoint::operator()(const CaloHit *const lhs, const CaloHit *const rhs)
37 {
38  return (m_referencePoint.GetDistanceSquared(lhs->GetPositionVector()) < m_referencePoint.GetDistanceSquared(rhs->GetPositionVector()));
39 }
40 
41 //------------------------------------------------------------------------------------------------------------------------------------------
42 // Finding 3D Shower Start Position
43 //------------------------------------------------------------------------------------------------------------------------------------------
44 
45 bool 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  {
75  if (LArConnectionPathwayHelper::FindShowerStartFromDirection(
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  {
91  if (LArConnectionPathwayHelper::FindShowerStartFromXProjection(
92  pAlgorithm, protoShowerU, protoShowerV, protoShowerW, maxProjectionSeparation, maxXSeparation, uShowerStart3D) ||
93  LArConnectionPathwayHelper::FindShowerStartFromXProjectionRelaxed(
94  pAlgorithm, protoShowerU, protoShowerV, protoShowerW, maxProjectionSeparation, maxXSeparation, uShowerStart3D) ||
95  LArConnectionPathwayHelper::FindShowerStartFromXProjectionRelaxed(
96  pAlgorithm, protoShowerU, protoShowerW, protoShowerV, maxProjectionSeparation, maxXSeparation, uShowerStart3D))
97  {
98  uFound = true;
99  }
100 
101  if (LArConnectionPathwayHelper::FindShowerStartFromXProjection(
102  pAlgorithm, protoShowerV, protoShowerW, protoShowerU, maxProjectionSeparation, maxXSeparation, vShowerStart3D) ||
103  LArConnectionPathwayHelper::FindShowerStartFromXProjectionRelaxed(
104  pAlgorithm, protoShowerV, protoShowerW, protoShowerU, maxProjectionSeparation, maxXSeparation, vShowerStart3D) ||
105  LArConnectionPathwayHelper::FindShowerStartFromXProjectionRelaxed(
106  pAlgorithm, protoShowerV, protoShowerU, protoShowerW, maxProjectionSeparation, maxXSeparation, vShowerStart3D))
107  {
108  vFound = true;
109  }
110 
111  if (LArConnectionPathwayHelper::FindShowerStartFromXProjection(
112  pAlgorithm, protoShowerW, protoShowerU, protoShowerV, maxProjectionSeparation, maxXSeparation, wShowerStart3D) ||
113  LArConnectionPathwayHelper::FindShowerStartFromXProjectionRelaxed(
114  pAlgorithm, protoShowerW, protoShowerU, protoShowerV, maxProjectionSeparation, maxXSeparation, wShowerStart3D) ||
115  LArConnectionPathwayHelper::FindShowerStartFromXProjectionRelaxed(
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 
148 void 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);
156  LArGeometryHelper::MergeThreePositions3D(
157  pAlgorithm->GetPandora(), TPC_VIEW_U, TPC_VIEW_V, TPC_VIEW_W, showerStartU, showerStartV, showerStartW, showerStart3D, chi2);
158 }
159 
160 //------------------------------------------------------------------------------------------------------------------------------------------
161 
162 bool LArConnectionPathwayHelper::FindShowerStartFromDirection(const Algorithm *const pAlgorithm, const ProtoShower &protoShowerU,
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 
181 bool LArConnectionPathwayHelper::FindShowerStartFromDirection(const Algorithm *const pAlgorithm, const ProtoShower &protoShower,
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 
199  LArGeometryHelper::MergeThreePositions3D(
200  pAlgorithm->GetPandora(), hitType, hitTypeA, hitTypeB, showerStart, showerStartA, showerStartB, showerStart3D, chi2);
201 
202  return false;
203 }
204 
205 //------------------------------------------------------------------------------------------------------------------------------------------
206 
207 bool 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 
228 bool LArConnectionPathwayHelper::FindShowerStartFromXProjection(const Algorithm *const pAlgorithm, const ProtoShower &protoShower,
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 
262  LArGeometryHelper::MergeThreePositions3D(
263  pAlgorithm->GetPandora(), hitType, hitType1, hitType2, showerStart, showerStart1, showerStart2, showerStart3D, chi2);
264 
265  return true;
266 }
267 
268 //------------------------------------------------------------------------------------------------------------------------------------------
269 
270 bool LArConnectionPathwayHelper::FindClosestSpinePosition(
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 
297 bool LArConnectionPathwayHelper::FindShowerStartFromXProjectionRelaxed(const Algorithm *const pAlgorithm, const ProtoShower &protoShower,
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 
330 void LArConnectionPathwayHelper::GetMinMiddleMax(
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
Float_t x
Definition: compare.C:6
const ProtoShower & GetProtoShowerU() const
Get the U view ProtoShower.
const ProtoShower & GetProtoShowerV() const
Get the V view ProtoShower.
Header file for the pfo helper class.
Header file for the ProtoShower class.
Header file for the connection pathway helper class.
Consistency
Consistency enumeration.
const ConnectionPathway & GetConnectionPathway() const
Get the connection pathway.
const pandora::CaloHitList & GetSpineHitList() const
Get the spine hit list.
ProtoShowerMatch class.
TFile f
Definition: plotHisto.C:6
const pandora::CartesianVector & GetStartPosition() const
Get the start position of the connection pathway.
Header file for the geometry helper class.
const pandora::CartesianVector & GetStartPosition() const
Get the start position of the shower core.
Header file for the cluster helper class.
const Consistency & GetConsistencyType() const
Get the consistency type.
decltype(auto) values(Coll &&coll)
Range-for loop helper iterating across the values of the specified collection.
ProtoShower class.
HitType
Definition: HitType.h:12
const ShowerCore & GetShowerCore() const
Get the shower core.
const ProtoShower & GetProtoShowerW() const
Get the W view ProtoShower.
const pandora::CartesianVector & GetStartDirection() const
Get the start direction of the connection pathway.