21 return (innerVertex.GetPosition() - outerVertex.GetPosition()).GetMagnitudeSquared();
28 return std::sqrt(LArPointingClusterHelper::GetLengthSquared(pointingCluster));
34 const float minLongitudinalDistance,
const float maxTransverseDistance)
36 float rL(0.
f), rT(0.
f);
37 LArPointingClusterHelper::GetImpactParameters(daughterVertex.
GetPosition(), daughterVertex.
GetDirection(), parentVertex, rL, rT);
39 if (std::fabs(rL) > std::fabs(minLongitudinalDistance) || rT > maxTransverseDistance)
48 const float minLongitudinalDistance,
const float maxLongitudinalDistance,
const float maxTransverseDistance,
const float angularAllowance)
50 float rL(0.
f), rT(0.
f);
51 LArPointingClusterHelper::GetImpactParameters(daughterVertex.
GetPosition(), daughterVertex.
GetDirection(), parentVertex, rL, rT);
53 if (std::fabs(rL) > std::fabs(minLongitudinalDistance) && (rL < 0 || rL > maxLongitudinalDistance))
56 const float tanSqTheta(std::pow(std::tan(M_PI * angularAllowance / 180.
f), 2.0));
58 if (rT * rT > maxTransverseDistance * maxTransverseDistance + rL * rL * tanSqTheta)
66 CartesianVector LArPointingClusterHelper::GetProjectedPosition(
const CartesianVector &vertexPosition,
67 const CartesianVector &vertexDirection,
const pandora::Cluster *
const pCluster,
const float projectionAngularAllowance)
69 const CaloHit *pClosestCaloHit(
nullptr);
70 float closestDistanceSquared(std::numeric_limits<float>::max());
71 const float minCosTheta(std::cos(M_PI * projectionAngularAllowance / 180.
f));
73 for (
const OrderedCaloHitList::value_type &layerEntry : pCluster->GetOrderedCaloHitList())
75 for (
const CaloHit *
const pCaloHit : *layerEntry.second)
77 const CartesianVector hitProjection(pCaloHit->GetPositionVector() - vertexPosition);
78 const float distanceSquared(hitProjection.GetMagnitudeSquared());
80 if (distanceSquared > std::numeric_limits<float>::epsilon())
83 if (distanceSquared < closestDistanceSquared)
85 if (-hitProjection.GetUnitVector().GetDotProduct(vertexDirection) > minCosTheta)
87 pClosestCaloHit = pCaloHit;
88 closestDistanceSquared = distanceSquared;
94 return pCaloHit->GetPositionVector();
100 return pClosestCaloHit->GetPositionVector();
102 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
107 void LArPointingClusterHelper::GetClosestVertices(
const bool useX,
const bool useY,
const bool useZ,
const LArPointingCluster &pointingClusterI,
111 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
113 if (!useX && !useY && !useZ)
114 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
116 for (
unsigned int useInnerI = 0; useInnerI < 2; ++useInnerI)
121 for (
unsigned int useInnerJ = 0; useInnerJ < 2; ++useInnerJ)
126 const float vtxI_vtxJ_dx(useX ? (vtxI.GetPosition().GetX() - vtxJ.GetPosition().GetX()) : 0.
f);
127 const float vtxI_vtxJ_dy(useY ? (vtxI.GetPosition().GetY() - vtxJ.GetPosition().GetY()) : 0.
f);
128 const float vtxI_vtxJ_dz(useZ ? (vtxI.GetPosition().GetZ() - vtxJ.GetPosition().GetZ()) : 0.
f);
129 const float vtxI_vtxJ(vtxI_vtxJ_dx * vtxI_vtxJ_dx + vtxI_vtxJ_dy * vtxI_vtxJ_dy + vtxI_vtxJ_dz * vtxI_vtxJ_dz);
131 const float vtxI_endJ_dx(useX ? (vtxI.GetPosition().GetX() - endJ.GetPosition().GetX()) : 0.
f);
132 const float vtxI_endJ_dy(useY ? (vtxI.GetPosition().GetY() - endJ.GetPosition().GetY()) : 0.
f);
133 const float vtxI_endJ_dz(useZ ? (vtxI.GetPosition().GetZ() - endJ.GetPosition().GetZ()) : 0.
f);
134 const float vtxI_endJ(vtxI_endJ_dx * vtxI_endJ_dx + vtxI_endJ_dy * vtxI_endJ_dy + vtxI_endJ_dz * vtxI_endJ_dz);
136 const float endI_vtxJ_dx(useX ? (endI.GetPosition().GetX() - vtxJ.GetPosition().GetX()) : 0.
f);
137 const float endI_vtxJ_dy(useY ? (endI.GetPosition().GetY() - vtxJ.GetPosition().GetY()) : 0.
f);
138 const float endI_vtxJ_dz(useZ ? (endI.GetPosition().GetZ() - vtxJ.GetPosition().GetZ()) : 0.
f);
139 const float endI_vtxJ(endI_vtxJ_dx * endI_vtxJ_dx + endI_vtxJ_dy * endI_vtxJ_dy + endI_vtxJ_dz * endI_vtxJ_dz);
141 const float endI_endJ_dx(useX ? (endI.GetPosition().GetX() - endJ.GetPosition().GetX()) : 0.
f);
142 const float endI_endJ_dy(useY ? (endI.GetPosition().GetY() - endJ.GetPosition().GetY()) : 0.
f);
143 const float endI_endJ_dz(useZ ? (endI.GetPosition().GetZ() - endJ.GetPosition().GetZ()) : 0.
f);
144 const float endI_endJ(endI_endJ_dx * endI_endJ_dx + endI_endJ_dy * endI_endJ_dy + endI_endJ_dz * endI_endJ_dz);
146 if ((vtxI_vtxJ < std::min(vtxI_endJ, std::min(endI_vtxJ, endI_endJ))) && (endI_endJ > std::max(vtxI_endJ, std::max(endI_vtxJ, vtxI_vtxJ))))
148 closestVertexI = vtxI;
149 closestVertexJ = vtxJ;
155 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
163 return LArPointingClusterHelper::GetClosestVertices(
true,
true,
true, pointingClusterI, pointingClusterJ, closestVertexI, closestVertexJ);
171 return LArPointingClusterHelper::GetClosestVertices(
true,
false,
false, pointingClusterI, pointingClusterJ, closestVertexI, closestVertexJ);
179 return LArPointingClusterHelper::GetClosestVertices(
false,
true,
true, pointingClusterI, pointingClusterJ, closestVertexI, closestVertexJ);
184 void LArPointingClusterHelper::GetImpactParametersInYZ(
187 if (std::fabs(initialVertex.
GetDirection().GetX()) > 1.
f - std::numeric_limits<float>::epsilon())
188 throw pandora::StatusCodeException(pandora::STATUS_CODE_NOT_FOUND);
190 const pandora::CartesianVector initialPosition(0.
f, initialVertex.
GetPosition().GetY(), initialVertex.
GetPosition().GetZ());
191 const pandora::CartesianVector initialDirection(0.
f, initialVertex.
GetDirection().GetY(), initialVertex.
GetDirection().GetZ());
192 const pandora::CartesianVector targetPosition(0.
f, targetVertex.
GetPosition().GetY(), targetVertex.
GetPosition().GetZ());
194 return LArPointingClusterHelper::GetImpactParameters(initialPosition, initialDirection.GetUnitVector(), targetPosition, longitudinal, transverse);
199 void LArPointingClusterHelper::GetImpactParameters(
202 return LArPointingClusterHelper::GetImpactParameters(
208 void LArPointingClusterHelper::GetImpactParameters(
209 const LArPointingCluster::Vertex &pointingVertex,
const CartesianVector &targetPosition,
float &longitudinal,
float &transverse)
211 return LArPointingClusterHelper::GetImpactParameters(
217 void LArPointingClusterHelper::GetImpactParameters(
const CartesianVector &initialPosition,
const CartesianVector &initialDirection,
218 const CartesianVector &targetPosition,
float &longitudinal,
float &transverse)
222 transverse = initialDirection.GetCrossProduct(targetPosition - initialPosition).GetMagnitude();
223 longitudinal = -initialDirection.GetDotProduct(targetPosition - initialPosition);
228 void LArPointingClusterHelper::GetAverageDirection(
231 const Cluster *
const pFirstCluster(firstVertex.
GetCluster());
232 const Cluster *
const pSecondCluster(secondVertex.
GetCluster());
234 if (pFirstCluster == pSecondCluster)
235 throw pandora::StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
237 const float energy1(pFirstCluster->GetHadronicEnergy());
238 const float energy2(pSecondCluster->GetHadronicEnergy());
240 if ((energy1 < std::numeric_limits<float>::epsilon()) || (energy2 < std::numeric_limits<float>::epsilon()))
241 throw pandora::StatusCodeException(STATUS_CODE_NOT_ALLOWED);
249 const LArPointingCluster::Vertex &secondVertex, CartesianVector &intersectPosition,
float &firstDisplacement,
float &secondDisplacement)
251 const Cluster *
const pFirstCluster(firstVertex.
GetCluster());
252 const Cluster *
const pSecondCluster(secondVertex.
GetCluster());
254 if (pFirstCluster == pSecondCluster)
255 throw pandora::StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
258 secondVertex.
GetDirection(), intersectPosition, firstDisplacement, secondDisplacement);
264 const CartesianVector &b2, CartesianVector &intersectPosition,
float &firstDisplacement,
float &secondDisplacement)
267 const float cosTheta = a2.GetDotProduct(b2);
270 if (1.
f - std::fabs(cosTheta) < std::numeric_limits<float>::epsilon())
271 throw pandora::StatusCodeException(STATUS_CODE_NOT_ALLOWED);
274 const float P = ((a2 - b2 * cosTheta).GetDotProduct(b1 - a1)) / (1.
f - cosTheta * cosTheta);
275 const float Q = ((a2 * cosTheta - b2).GetDotProduct(b1 - a1)) / (1.
f - cosTheta * cosTheta);
278 intersectPosition = (a1 + a2 * P + b1 + b2 * Q) * 0.5
f;
281 firstDisplacement = P;
282 secondDisplacement = Q;
288 CartesianVector &intersectPosition,
float &displacementL,
float &displacementT)
290 displacementT = +std::numeric_limits<float>::max();
291 displacementL = -std::numeric_limits<float>::max();
293 float rL(0.
f), rT(0.
f);
294 float figureOfMerit(std::numeric_limits<float>::max());
295 float foundIntersection(
false);
297 const OrderedCaloHitList &orderedCaloHitList(pTargetCluster->GetOrderedCaloHitList());
303 const CartesianVector &hitPosition = (*iter2)->GetPositionVector();
305 LArPointingClusterHelper::GetImpactParameters(vertexCluster.
GetPosition(), vertexCluster.
GetDirection(), hitPosition, rL, rT);
307 if (rT < figureOfMerit)
313 intersectPosition = hitPosition;
314 foundIntersection =
true;
319 if (!foundIntersection)
320 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
326 const LArPointingClusterList &pointingClusterList,
const float minLongitudinalDistance,
const float maxLongitudinalDistance,
327 const float maxTransverseDistance,
const float angularAllowance)
329 float bestAssociatedEnergy(0.
f);
337 LArPointingClusterHelper::CollectAssociatedClusters(vertex, pointingClusterList, minLongitudinalDistance, maxLongitudinalDistance,
338 maxTransverseDistance, angularAllowance, associatedVertices);
340 const float associatedEnergy(LArPointingClusterHelper::GetAssociatedEnergy(vertex, associatedVertices));
342 if (associatedEnergy > bestAssociatedEnergy)
344 bestVertexIter = iter;
345 bestAssociatedEnergy = associatedEnergy;
349 if (vertexList.end() == bestVertexIter)
350 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
352 return (*bestVertexIter);
358 const float minLongitudinalDistance,
const float maxLongitudinalDistance,
const float maxTransverseDistance,
367 const float innerDistanceSquared = (innerVertex.
GetPosition() - vertex.
GetPosition()).GetMagnitudeSquared();
368 const float outerDistanceSquared = (outerVertex.
GetPosition() - vertex.
GetPosition()).GetMagnitudeSquared();
372 if (LArPointingClusterHelper::IsNode(vertex.
GetPosition(), chosenVertex, minLongitudinalDistance, maxTransverseDistance) ||
373 LArPointingClusterHelper::IsEmission(vertex.
GetPosition(), chosenVertex, minLongitudinalDistance, maxLongitudinalDistance,
374 maxTransverseDistance, angularAllowance))
376 outputList.push_back(chosenVertex);
385 float associatedEnergy(0.
f);
390 const Cluster *
const pCluster(clusterVertex.
GetCluster());
392 const float clusterEnergy(LArClusterHelper::GetEnergyFromLength(pCluster));
393 const float clusterLength(LArClusterHelper::GetLength(pCluster));
396 if (deltaLength < std::numeric_limits<float>::epsilon())
398 associatedEnergy += clusterEnergy;
400 else if (deltaLength < clusterLength)
402 associatedEnergy += clusterEnergy * (1.f - (deltaLength / clusterLength));
406 return associatedEnergy;
std::vector< LArPointingCluster > LArPointingClusterList
LArPointingCluster class.
const pandora::Cluster * GetCluster() const
Get the address of the cluster.
std::pair< float, float > GetIntersection(double Ax, double Ay, double Bx, double By, double Cx, double Cy, double Dx, double Dy)
std::vector< LArPointingCluster::Vertex > LArPointingClusterVertexList
const pandora::Cluster * GetCluster() const
Get the address of the cluster.
Header file for the cluster helper class.
const Vertex & GetOuterVertex() const
Get the outer vertex.
const Vertex & GetInnerVertex() const
Get the inner vertex.
const pandora::CartesianVector & GetDirection() const
Get the vertex direction.
const pandora::CartesianVector & GetPosition() const
Get the vertex position.