9 #include "Managers/PluginManager.h" 10 #include "Managers/GeometryManager.h" 12 #include "Geometry/DetectorGap.h" 13 #include "Geometry/LArTPC.h" 15 #include "Objects/CartesianVector.h" 17 #include "Pandora/Pandora.h" 24 #include "Plugins/LArTransformationPlugin.h" 31 float LArGeometryHelper::MergeTwoPositions(
const Pandora &
pandora,
const HitType view1,
const HitType view2,
const float position1,
const float position2)
34 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
36 if ((view1 == TPC_VIEW_U) && (view2 == TPC_VIEW_V))
38 return pandora.GetPlugins()->GetLArTransformationPlugin()->UVtoW(position1, position2);
41 if ((view1 == TPC_VIEW_V) && (view2 == TPC_VIEW_U))
43 return pandora.GetPlugins()->GetLArTransformationPlugin()->UVtoW(position2, position1);
46 if ((view1 == TPC_VIEW_W) && (view2 == TPC_VIEW_U))
48 return pandora.GetPlugins()->GetLArTransformationPlugin()->WUtoV(position1, position2);
51 if ((view1 == TPC_VIEW_U) && (view2 == TPC_VIEW_W))
53 return pandora.GetPlugins()->GetLArTransformationPlugin()->WUtoV(position2, position1);
56 if ((view1 == TPC_VIEW_V) && (view2 == TPC_VIEW_W))
58 return pandora.GetPlugins()->GetLArTransformationPlugin()->VWtoU(position1, position2);
61 if ((view1 == TPC_VIEW_W) && (view2 == TPC_VIEW_V))
63 return pandora.GetPlugins()->GetLArTransformationPlugin()->VWtoU(position2, position1);
66 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
71 CartesianVector LArGeometryHelper::MergeTwoDirections(
const Pandora &pandora,
const HitType view1,
const HitType view2,
72 const CartesianVector &direction1,
const CartesianVector &direction2)
75 if (direction1.GetX() * direction2.GetX() < 0.f)
76 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
79 const float s1((std::fabs(direction1.GetX()) > std::numeric_limits<float>::epsilon()) ? 100.
f * std::fabs(direction2.GetX()) : 1.
f);
80 const float s2((std::fabs(direction2.GetX()) > std::numeric_limits<float>::epsilon()) ? 100.
f * std::fabs(direction1.GetX()) : 1.
f);
82 float pX(s1 * direction1.GetX()), pU(0.
f), pV(0.
f), pW(0.
f);
83 HitType newView(HIT_CUSTOM);
85 if ((view1 == TPC_VIEW_U) && (view2 == TPC_VIEW_V))
87 pU = s1 * direction1.GetZ(); pV = s2 * direction2.GetZ(); newView = TPC_VIEW_W;
90 if ((view1 == TPC_VIEW_V) && (view2 == TPC_VIEW_U))
92 pV = s1 * direction1.GetZ(); pU = s2 * direction2.GetZ(); newView = TPC_VIEW_W;
95 if ((view1 == TPC_VIEW_W) && (view2 == TPC_VIEW_U))
97 pW = s1 * direction1.GetZ(); pU = s2 * direction2.GetZ(); newView = TPC_VIEW_V;
100 if ((view1 == TPC_VIEW_U) && (view2 == TPC_VIEW_W))
102 pU = s1 * direction1.GetZ(); pW = s2 * direction2.GetZ(); newView = TPC_VIEW_V;
105 if ((view1 == TPC_VIEW_V) && (view2 == TPC_VIEW_W))
107 pV = s1 * direction1.GetZ(); pW = s2 * direction2.GetZ(); newView = TPC_VIEW_U;
110 if ((view1 == TPC_VIEW_W) && (view2 == TPC_VIEW_V))
112 pW = s1 * direction1.GetZ(); pV = s2 * direction2.GetZ(); newView = TPC_VIEW_U;
115 if (newView == TPC_VIEW_W)
116 return CartesianVector(pX, 0.
f, pandora.GetPlugins()->GetLArTransformationPlugin()->UVtoW(pU, pV)).GetUnitVector();
118 if (newView == TPC_VIEW_U)
119 return CartesianVector(pX, 0.
f, pandora.GetPlugins()->GetLArTransformationPlugin()->VWtoU(pV, pW)).GetUnitVector();
121 if (newView == TPC_VIEW_V)
122 return CartesianVector(pX, 0.
f, pandora.GetPlugins()->GetLArTransformationPlugin()->WUtoV(pW, pU)).GetUnitVector();
124 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
129 void LArGeometryHelper::MergeTwoPositions(
const Pandora &pandora,
const HitType view1,
const HitType view2,
const CartesianVector &position1,
130 const CartesianVector &position2, CartesianVector &position3,
float& chiSquared)
133 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
135 const float X3((position1.GetX() + position2.GetX() ) / 2.
f);
136 const float Z1(position1.GetZ());
137 const float Z2(position2.GetZ());
138 const float Z3(LArGeometryHelper::MergeTwoPositions(pandora, view1, view2,
Z1,
Z2));
140 position3.SetValues(X3, 0.
f, Z3);
141 const float sigmaUVW(LArGeometryHelper::GetSigmaUVW(pandora));
142 chiSquared = ((X3 - position1.GetX()) * (X3 - position1.GetX()) + (X3 - position2.GetX()) * (X3 - position2.GetX())) / (sigmaUVW * sigmaUVW);
147 void LArGeometryHelper::MergeTwoPositions(
const Pandora &pandora,
const HitType view1,
const HitType view2,
const CartesianVector &position1,
148 const CartesianVector &position2, CartesianVector &outputU, CartesianVector &outputV, CartesianVector &outputW,
float& chiSquared)
151 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
153 CartesianVector position3(0.
f, 0.
f, 0.
f);
154 LArGeometryHelper::MergeTwoPositions(pandora, view1, view2, position1, position2, position3, chiSquared);
156 float aveU(0.
f), aveV(0.
f), aveW(0.
f);
157 const float Z1(position1.GetZ()),
Z2(position2.GetZ()), Z3(position3.GetZ()), aveX(position3.GetX());
159 if ((view1 == TPC_VIEW_U) && (view2 == TPC_VIEW_V))
161 aveU =
Z1; aveV =
Z2; aveW = Z3;
164 if ((view1 == TPC_VIEW_V) && (view2 == TPC_VIEW_W))
166 aveV =
Z1; aveW =
Z2; aveU = Z3;
169 if ((view1 == TPC_VIEW_W) && (view2 == TPC_VIEW_U))
171 aveW =
Z1; aveU =
Z2; aveV = Z3;
174 if ((view1 == TPC_VIEW_V) && (view2 == TPC_VIEW_U))
176 aveV =
Z1; aveU =
Z2; aveW = Z3;
179 if ((view1 == TPC_VIEW_W) && (view2 == TPC_VIEW_V))
181 aveW =
Z1; aveV =
Z2; aveU = Z3;
184 if ((view1 == TPC_VIEW_U) && (view2 == TPC_VIEW_W))
186 aveU =
Z1; aveW =
Z2; aveV = Z3;
189 outputU.SetValues( aveX, 0.
f, aveU );
190 outputV.SetValues( aveX, 0.
f, aveV );
191 outputW.SetValues( aveX, 0.
f, aveW );
196 void LArGeometryHelper::MergeThreePositions(
const Pandora &pandora,
const HitType view1,
const HitType view2,
const HitType view3,
197 const CartesianVector &position1,
const CartesianVector &position2,
const CartesianVector &position3, CartesianVector &outputU,
198 CartesianVector &outputV, CartesianVector &outputW,
float &chiSquared)
200 if ((view1 == view2) || (view2 == view3) || (view3 == view1))
201 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
203 if ((view1 == TPC_VIEW_U) && (view2 == TPC_VIEW_V))
205 return LArGeometryHelper::MergeThreePositions(pandora, position1, position2, position3, outputU, outputV, outputW, chiSquared);
208 if ((view1 == TPC_VIEW_V) && (view2 == TPC_VIEW_W))
210 return LArGeometryHelper::MergeThreePositions(pandora, position3, position1, position2, outputU, outputV, outputW, chiSquared );
213 if ((view1 == TPC_VIEW_W) && (view2 == TPC_VIEW_U))
215 return LArGeometryHelper::MergeThreePositions(pandora, position2, position3, position1, outputU, outputV, outputW, chiSquared);
218 if ((view1 == TPC_VIEW_V) && (view2 == TPC_VIEW_U))
220 return LArGeometryHelper::MergeThreePositions(pandora, position2, position1, position3, outputU, outputV, outputW, chiSquared);
223 if ((view1 == TPC_VIEW_W) && (view2 == TPC_VIEW_V))
225 return LArGeometryHelper::MergeThreePositions(pandora, position3, position2, position1, outputU, outputV, outputW, chiSquared);
228 if ((view1 == TPC_VIEW_U) && (view2 == TPC_VIEW_W))
230 return LArGeometryHelper::MergeThreePositions(pandora, position1, position3, position2, outputU, outputV, outputW, chiSquared);
233 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
238 void LArGeometryHelper::MergeThreePositions(
const Pandora &pandora,
const CartesianVector &positionU,
const CartesianVector &positionV,
239 const CartesianVector &positionW, CartesianVector &outputU, CartesianVector &outputV, CartesianVector &outputW,
float &chiSquared)
241 const float YfromUV(pandora.GetPlugins()->GetLArTransformationPlugin()->UVtoY(positionU.GetZ(), positionV.GetZ()));
242 const float YfromUW(pandora.GetPlugins()->GetLArTransformationPlugin()->UWtoY(positionU.GetZ(), positionW.GetZ()));
243 const float YfromVW(pandora.GetPlugins()->GetLArTransformationPlugin()->VWtoY(positionV.GetZ(), positionW.GetZ()));
245 const float ZfromUV(pandora.GetPlugins()->GetLArTransformationPlugin()->UVtoZ(positionU.GetZ(), positionV.GetZ()));
246 const float ZfromUW(pandora.GetPlugins()->GetLArTransformationPlugin()->UWtoZ(positionU.GetZ(), positionW.GetZ()));
247 const float ZfromVW(pandora.GetPlugins()->GetLArTransformationPlugin()->VWtoZ(positionV.GetZ(), positionW.GetZ()));
250 const bool useOldWZEquivalentTreatment(std::fabs(ZfromUW - ZfromVW) < std::numeric_limits<float>::epsilon());
251 const float aveX((positionU.GetX() + positionV.GetX() + positionW.GetX()) / 3.
f);
252 const float aveY(useOldWZEquivalentTreatment ? YfromUV : (YfromUV + YfromUW + YfromVW) / 3.
f);
253 const float aveZ(useOldWZEquivalentTreatment ? (positionW.GetZ() + 2.f * ZfromUV) / 3.
f : (ZfromUV + ZfromUW + ZfromVW) / 3.f);
255 const float aveU(pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoU(aveY, aveZ));
256 const float aveV(pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoV(aveY, aveZ));
257 const float aveW(pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoW(aveY, aveZ));
259 outputU.SetValues(aveX, 0.
f, aveU);
260 outputV.SetValues(aveX, 0.
f, aveV);
261 outputW.SetValues(aveX, 0.
f, aveW);
263 const float sigmaUVW(LArGeometryHelper::GetSigmaUVW(pandora));
264 chiSquared = ((outputU.GetX() - positionU.GetX()) * (outputU.GetX() - positionU.GetX()) +
265 (outputV.GetX() - positionV.GetX()) * (outputV.GetX() - positionV.GetX()) +
266 (outputW.GetX() - positionW.GetX()) * (outputW.GetX() - positionW.GetX()) +
267 (outputU.GetZ() - positionU.GetZ()) * (outputU.GetZ() - positionU.GetZ()) +
268 (outputV.GetZ() - positionV.GetZ()) * (outputV.GetZ() - positionV.GetZ()) +
269 (outputW.GetZ() - positionW.GetZ()) * (outputW.GetZ() - positionW.GetZ())) / (sigmaUVW * sigmaUVW);
274 void LArGeometryHelper::MergeTwoPositions3D(
const Pandora &pandora,
const HitType view1,
const HitType view2,
const CartesianVector &position1,
275 const CartesianVector &position2, CartesianVector &position3D,
float &chiSquared)
277 CartesianVector positionU(0.
f, 0.
f, 0.
f), positionV(0.
f, 0.
f, 0.
f), positionW(0.
f, 0.
f, 0.
f);
278 LArGeometryHelper::MergeTwoPositions(pandora, view1, view2, position1, position2, positionU, positionV, positionW, chiSquared);
280 position3D.SetValues(positionW.GetX(), pandora.GetPlugins()->GetLArTransformationPlugin()->UVtoY(positionU.GetZ(),positionV.GetZ()),
281 pandora.GetPlugins()->GetLArTransformationPlugin()->UVtoZ(positionU.GetZ(),positionV.GetZ()) );
286 void LArGeometryHelper::MergeThreePositions3D(
const Pandora &pandora,
const HitType view1,
const HitType view2,
const HitType view3,
287 const CartesianVector &position1,
const CartesianVector &position2,
const CartesianVector &position3, CartesianVector &position3D,
float &chiSquared)
289 CartesianVector positionU(0.
f, 0.
f, 0.
f), positionV(0.
f, 0.
f, 0.
f), positionW(0.
f, 0.
f, 0.
f);
290 LArGeometryHelper::MergeThreePositions(pandora, view1, view2, view3, position1, position2, position3, positionU, positionV, positionW, chiSquared);
292 position3D.SetValues(positionW.GetX(), pandora.GetPlugins()->GetLArTransformationPlugin()->UVtoY(positionU.GetZ(),positionV.GetZ()),
293 pandora.GetPlugins()->GetLArTransformationPlugin()->UVtoZ(positionU.GetZ(),positionV.GetZ()));
298 CartesianVector LArGeometryHelper::ProjectPosition(
const Pandora &pandora,
const CartesianVector &position3D,
const HitType view)
300 if (view == TPC_VIEW_U)
302 return CartesianVector(position3D.GetX(), 0.f, pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoU(position3D.GetY(), position3D.GetZ()));
305 else if (view == TPC_VIEW_V)
307 return CartesianVector(position3D.GetX(), 0.f, pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoV(position3D.GetY(), position3D.GetZ()));
310 else if (view == TPC_VIEW_W)
312 return CartesianVector(position3D.GetX(), 0.f, pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoW(position3D.GetY(), position3D.GetZ()));
315 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
320 CartesianVector LArGeometryHelper::ProjectDirection(
const Pandora &pandora,
const CartesianVector &direction3D,
const HitType view)
322 if (view == TPC_VIEW_U)
324 return CartesianVector(direction3D.GetX(), 0.f, pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoU(direction3D.GetY(), direction3D.GetZ())).GetUnitVector();
327 else if (view == TPC_VIEW_V)
329 return CartesianVector(direction3D.GetX(), 0.f, pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoV(direction3D.GetY(), direction3D.GetZ())).GetUnitVector();
332 else if (view == TPC_VIEW_W)
334 return CartesianVector(direction3D.GetX(), 0.f, pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoW(direction3D.GetY(), direction3D.GetZ())).GetUnitVector();
337 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
342 float LArGeometryHelper::GetWirePitch(
const Pandora &pandora,
const HitType view,
const float maxWirePitchDiscrepancy)
344 if (view != TPC_VIEW_U && view != TPC_VIEW_V && view != TPC_VIEW_W)
345 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
347 const LArTPCMap &larTPCMap(pandora.GetGeometry()->GetLArTPCMap());
349 if (larTPCMap.empty())
351 std::cout <<
"LArGeometryHelper::GetWirePitch - LArTPC description not registered with Pandora as required " << std::endl;
352 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
355 const LArTPC *
const pFirstLArTPC(larTPCMap.begin()->second);
356 const float wirePitch(view == TPC_VIEW_U ? pFirstLArTPC->GetWirePitchU() : (view == TPC_VIEW_V ? pFirstLArTPC->GetWirePitchV() : pFirstLArTPC->GetWirePitchW()));
358 for (
const LArTPCMap::value_type &mapEntry : larTPCMap)
360 const LArTPC *
const pLArTPC(mapEntry.second);
361 const float alternateWirePitch(view == TPC_VIEW_U ? pLArTPC->GetWirePitchU() : (view == TPC_VIEW_V ? pLArTPC->GetWirePitchV() : pLArTPC->GetWirePitchW()));
363 if (std::fabs(wirePitch - alternateWirePitch) > maxWirePitchDiscrepancy)
365 std::cout <<
"LArGeometryHelper::GetWirePitch - LArTPC configuration not supported" << std::endl;
366 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
375 CartesianVector LArGeometryHelper::GetWireAxis(
const Pandora &pandora,
const HitType view)
377 if (view == TPC_VIEW_U)
379 return CartesianVector(0.
f,
380 pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoU(1.
f, 0.
f),
381 pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoU(0.
f, 1.
f));
384 else if (view == TPC_VIEW_V)
386 return CartesianVector(0.
f,
387 pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoV(1.
f, 0.
f),
388 pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoV(0.
f, 1.
f));
391 else if (view == TPC_VIEW_W)
393 return CartesianVector(0.
f,
394 pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoW(1.
f, 0.
f),
395 pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoW(0.
f, 1.
f));
398 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
403 bool LArGeometryHelper::IsInGap(
const Pandora &pandora,
const CartesianVector &testPoint2D,
const HitType hitType,
const float gapTolerance)
406 for (
const DetectorGap *
const pDetectorGap : pandora.GetGeometry()->GetDetectorGapList())
408 if (pDetectorGap->IsInGap(testPoint2D, hitType, gapTolerance))
417 bool LArGeometryHelper::IsInGap3D(
const Pandora &pandora,
const CartesianVector &testPoint3D,
const HitType hitType,
const float gapTolerance)
419 const CartesianVector testPoint2D(LArGeometryHelper::ProjectPosition(pandora, testPoint3D, hitType));
420 return LArGeometryHelper::IsInGap(pandora, testPoint2D, hitType, gapTolerance);
425 bool LArGeometryHelper::IsXSamplingPointInGap(
const Pandora &pandora,
const float xSample,
const TwoDSlidingFitResult &slidingFitResult,
426 const float gapTolerance)
428 const HitType hitType(LArClusterHelper::GetClusterHitType(slidingFitResult.
GetCluster()));
432 const bool minLayerIsAtLowX(minLayerPosition.GetX() < maxLayerPosition.GetX());
433 const CartesianVector &lowXCoordinate(minLayerIsAtLowX ? minLayerPosition : maxLayerPosition);
434 const CartesianVector &highXCoordinate(minLayerIsAtLowX ? maxLayerPosition : minLayerPosition);
436 if ((xSample > lowXCoordinate.GetX()) && (xSample < highXCoordinate.GetX()))
438 CartesianVector slidingFitPosition(0.
f, 0.
f, 0.
f);
441 return (LArGeometryHelper::IsInGap(pandora, slidingFitPosition, hitType, gapTolerance));
447 const bool sampleIsNearerToLowX(std::fabs(xSample - lowXCoordinate.GetX()) < std::fabs(xSample - highXCoordinate.GetX()));
448 const CartesianVector &startPosition(sampleIsNearerToLowX ? lowXCoordinate : highXCoordinate);
449 const CartesianVector &startDirection(sampleIsNearerToLowX ? lowXDirection : highXDirection);
451 if (std::fabs(startDirection.GetX()) < std::numeric_limits<float>::epsilon())
452 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
454 const float pathLength((xSample - startPosition.GetX()) / startDirection.GetX());
455 const CartesianVector samplingPoint(startPosition + startDirection * pathLength);
457 return (LArGeometryHelper::IsInGap(pandora, samplingPoint, hitType, gapTolerance));
462 float LArGeometryHelper::CalculateGapDeltaZ(
const Pandora &pandora,
const float minZ,
const float maxZ,
const HitType hitType)
464 if (maxZ - minZ < std::numeric_limits<float>::epsilon())
465 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
467 float gapDeltaZ(0.
f);
469 for (
const DetectorGap *
const pDetectorGap : pandora.GetGeometry()->GetDetectorGapList())
471 const LineGap *
const pLineGap =
dynamic_cast<const LineGap*
>(pDetectorGap);
474 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
476 const LineGapType lineGapType(pLineGap->GetLineGapType());
478 if (!(((TPC_VIEW_U == hitType) && (TPC_WIRE_GAP_VIEW_U == lineGapType)) ||
479 ((TPC_VIEW_V == hitType) && (TPC_WIRE_GAP_VIEW_V == lineGapType)) ||
480 ((TPC_VIEW_W == hitType) && (TPC_WIRE_GAP_VIEW_W == lineGapType))))
485 if ((pLineGap->GetLineStartZ() > maxZ) || (pLineGap->GetLineEndZ() < minZ))
488 const float gapMinZ(
std::max(minZ, pLineGap->GetLineStartZ()));
489 const float gapMaxZ(
std::min(maxZ, pLineGap->GetLineEndZ()));
491 if ((gapMaxZ - gapMinZ) > std::numeric_limits<float>::epsilon())
492 gapDeltaZ += (gapMaxZ - gapMinZ);
500 float LArGeometryHelper::GetSigmaUVW(
const Pandora &pandora,
const float maxSigmaDiscrepancy)
502 const LArTPCMap &larTPCMap(pandora.GetGeometry()->GetLArTPCMap());
504 if (larTPCMap.empty())
506 std::cout <<
"LArGeometryHelper::GetSigmaUVW - LArTPC description not registered with Pandora as required " << std::endl;
507 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
510 const LArTPC *
const pFirstLArTPC(larTPCMap.begin()->second);
511 const float sigmaUVW(pFirstLArTPC->GetSigmaUVW());
513 for (
const LArTPCMap::value_type &mapEntry : larTPCMap)
515 const LArTPC *
const pLArTPC(mapEntry.second);
517 if (std::fabs(sigmaUVW - pLArTPC->GetSigmaUVW()) > maxSigmaDiscrepancy)
519 std::cout <<
"LArGeometryHelper::GetSigmaUVW - Plugin does not support provided LArTPC configurations " << std::endl;
520 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
pandora::CartesianVector GetGlobalMinLayerDirection() const
Get global direction corresponding to the fit result in minimum fit layer.
Header file for the geometry helper class.
Header file for the cluster helper class.
Header file for the lar two dimensional sliding fit result class.
pandora::CartesianVector GetGlobalMinLayerPosition() const
Get global position corresponding to the fit result in minimum fit layer.
const pandora::Cluster * GetCluster() const
Get the address of the cluster, if originally provided.
pandora::StatusCode GetGlobalFitPositionAtX(const float x, pandora::CartesianVector &position) const
Get global fit position for a given input x coordinate.
pandora::CartesianVector GetGlobalMaxLayerDirection() const
Get global direction corresponding to the fit result in maximum fit layer.
pandora::CartesianVector GetGlobalMaxLayerPosition() const
Get global position corresponding to the fit result in maximum fit layer.
TwoDSlidingFitResult class.