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,
const CartesianVector &vertexDirection,
67 const pandora::Cluster *
const pCluster,
const float projectionAngularAllowance)
69 const CaloHit *pClosestCaloHit(
nullptr);
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,
112 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
114 if (!useX && !useY && !useZ)
115 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
117 for (
unsigned int useInnerI = 0; useInnerI < 2; ++useInnerI)
122 for (
unsigned int useInnerJ = 0; useInnerJ < 2; ++useInnerJ)
127 const float vtxI_vtxJ_dx(useX ? (vtxI.GetPosition().GetX() - vtxJ.GetPosition().GetX()) : 0.
f);
128 const float vtxI_vtxJ_dy(useY ? (vtxI.GetPosition().GetY() - vtxJ.GetPosition().GetY()) : 0.
f);
129 const float vtxI_vtxJ_dz(useZ ? (vtxI.GetPosition().GetZ() - vtxJ.GetPosition().GetZ()) : 0.
f);
130 const float vtxI_vtxJ(vtxI_vtxJ_dx * vtxI_vtxJ_dx + vtxI_vtxJ_dy * vtxI_vtxJ_dy + vtxI_vtxJ_dz * vtxI_vtxJ_dz);
132 const float vtxI_endJ_dx(useX ? (vtxI.GetPosition().GetX() - endJ.GetPosition().GetX()) : 0.
f);
133 const float vtxI_endJ_dy(useY ? (vtxI.GetPosition().GetY() - endJ.GetPosition().GetY()) : 0.
f);
134 const float vtxI_endJ_dz(useZ ? (vtxI.GetPosition().GetZ() - endJ.GetPosition().GetZ()) : 0.
f);
135 const float vtxI_endJ(vtxI_endJ_dx * vtxI_endJ_dx + vtxI_endJ_dy * vtxI_endJ_dy + vtxI_endJ_dz * vtxI_endJ_dz);
137 const float endI_vtxJ_dx(useX ? (endI.GetPosition().GetX() - vtxJ.GetPosition().GetX()) : 0.
f);
138 const float endI_vtxJ_dy(useY ? (endI.GetPosition().GetY() - vtxJ.GetPosition().GetY()) : 0.
f);
139 const float endI_vtxJ_dz(useZ ? (endI.GetPosition().GetZ() - vtxJ.GetPosition().GetZ()) : 0.
f);
140 const float endI_vtxJ(endI_vtxJ_dx * endI_vtxJ_dx + endI_vtxJ_dy * endI_vtxJ_dy + endI_vtxJ_dz * endI_vtxJ_dz);
142 const float endI_endJ_dx(useX ? (endI.GetPosition().GetX() - endJ.GetPosition().GetX()) : 0.
f);
143 const float endI_endJ_dy(useY ? (endI.GetPosition().GetY() - endJ.GetPosition().GetY()) : 0.
f);
144 const float endI_endJ_dz(useZ ? (endI.GetPosition().GetZ() - endJ.GetPosition().GetZ()) : 0.
f);
145 const float endI_endJ(endI_endJ_dx * endI_endJ_dx + endI_endJ_dy * endI_endJ_dy + endI_endJ_dz * endI_endJ_dz);
150 closestVertexI = vtxI;
151 closestVertexJ = vtxJ;
157 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
165 return LArPointingClusterHelper::GetClosestVertices(
true,
true,
true, pointingClusterI, pointingClusterJ, closestVertexI, closestVertexJ);
173 return LArPointingClusterHelper::GetClosestVertices(
true,
false,
false, pointingClusterI, pointingClusterJ, closestVertexI, closestVertexJ);
181 return LArPointingClusterHelper::GetClosestVertices(
false,
true,
true, pointingClusterI, pointingClusterJ, closestVertexI, closestVertexJ);
189 if (std::fabs(initialVertex.
GetDirection().GetX()) > 1.
f - std::numeric_limits<float>::epsilon())
190 throw pandora::StatusCodeException(pandora::STATUS_CODE_NOT_FOUND);
192 const pandora::CartesianVector initialPosition(0.
f, initialVertex.
GetPosition().GetY(), initialVertex.
GetPosition().GetZ());
193 const pandora::CartesianVector initialDirection(0.
f, initialVertex.
GetDirection().GetY(), initialVertex.
GetDirection().GetZ());
194 const pandora::CartesianVector targetPosition(0.
f, targetVertex.
GetPosition().GetY(), targetVertex.
GetPosition().GetZ());
196 return LArPointingClusterHelper::GetImpactParameters(initialPosition, initialDirection.GetUnitVector(),
197 targetPosition, longitudinal, transverse);
205 return LArPointingClusterHelper::GetImpactParameters(pointingVertex.
GetPosition(), pointingVertex.
GetDirection(),
206 targetVertex.
GetPosition(), longitudinal, transverse);
212 const CartesianVector &targetPosition,
float &longitudinal,
float &transverse)
214 return LArPointingClusterHelper::GetImpactParameters(pointingVertex.
GetPosition(), pointingVertex.
GetDirection(),
215 targetPosition, longitudinal, transverse);
220 void LArPointingClusterHelper::GetImpactParameters(
const CartesianVector &initialPosition,
const CartesianVector &initialDirection,
221 const CartesianVector &targetPosition,
float &longitudinal,
float &transverse)
225 transverse = initialDirection.GetCrossProduct(targetPosition-initialPosition).GetMagnitude();
226 longitudinal = -initialDirection.GetDotProduct(targetPosition-initialPosition);
234 const Cluster *
const pFirstCluster(firstVertex.
GetCluster());
235 const Cluster *
const pSecondCluster(secondVertex.
GetCluster());
237 if (pFirstCluster == pSecondCluster)
238 throw pandora::StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
240 const float energy1(pFirstCluster->GetHadronicEnergy());
241 const float energy2(pSecondCluster->GetHadronicEnergy());
243 if ((energy1 < std::numeric_limits<float>::epsilon()) || (energy2 < std::numeric_limits<float>::epsilon()))
244 throw pandora::StatusCodeException(STATUS_CODE_NOT_ALLOWED);
252 CartesianVector &intersectPosition,
float &firstDisplacement,
float &secondDisplacement)
254 const Cluster *
const pFirstCluster(firstVertex.
GetCluster());
255 const Cluster *
const pSecondCluster(secondVertex.
GetCluster());
257 if (pFirstCluster == pSecondCluster)
258 throw pandora::StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
261 secondVertex.
GetDirection(), intersectPosition, firstDisplacement, secondDisplacement );
267 const CartesianVector &b2, CartesianVector &intersectPosition,
float &firstDisplacement,
float &secondDisplacement)
270 const float cosTheta = a2.GetDotProduct(b2);
273 if (1.
f - std::fabs(cosTheta) < std::numeric_limits<float>::epsilon())
274 throw pandora::StatusCodeException(STATUS_CODE_NOT_ALLOWED);
277 const float P = ((a2 - b2 * cosTheta).GetDotProduct(b1 - a1)) / (1.
f - cosTheta * cosTheta);
278 const float Q = ((a2 * cosTheta - b2).GetDotProduct(b1 - a1)) / (1.
f - cosTheta * cosTheta);
281 intersectPosition = (a1 + a2 * P + b1 + b2 * Q) * 0.5
f;
284 firstDisplacement = P;
285 secondDisplacement = Q;
291 CartesianVector &intersectPosition,
float &displacementL,
float &displacementT)
296 float rL(0.
f), rT(0.
f);
298 float foundIntersection(
false);
300 const OrderedCaloHitList &orderedCaloHitList(pTargetCluster->GetOrderedCaloHitList());
306 const CartesianVector &hitPosition = (*iter2)->GetPositionVector();
308 LArPointingClusterHelper::GetImpactParameters(vertexCluster.
GetPosition(), vertexCluster.
GetDirection(), hitPosition, rL, rT);
310 if (rT < figureOfMerit)
316 intersectPosition = hitPosition;
317 foundIntersection =
true;
322 if (!foundIntersection)
323 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
330 const LArPointingClusterList &pointingClusterList,
const float minLongitudinalDistance,
const float maxLongitudinalDistance,
331 const float maxTransverseDistance,
const float angularAllowance)
333 float bestAssociatedEnergy(0.
f);
341 LArPointingClusterHelper::CollectAssociatedClusters(vertex, pointingClusterList, minLongitudinalDistance,
342 maxLongitudinalDistance, maxTransverseDistance, angularAllowance, associatedVertices);
344 const float associatedEnergy(LArPointingClusterHelper::GetAssociatedEnergy(vertex, associatedVertices));
346 if (associatedEnergy > bestAssociatedEnergy)
348 bestVertexIter = iter;
349 bestAssociatedEnergy = associatedEnergy;
353 if (vertexList.end() == bestVertexIter)
354 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
356 return (*bestVertexIter);
362 const float minLongitudinalDistance,
const float maxLongitudinalDistance,
const float maxTransverseDistance,
const float angularAllowance,
371 const float innerDistanceSquared = (innerVertex.
GetPosition() - vertex.
GetPosition()).GetMagnitudeSquared();
372 const float outerDistanceSquared = (outerVertex.
GetPosition() - vertex.
GetPosition()).GetMagnitudeSquared();
376 if (LArPointingClusterHelper::IsNode(vertex.
GetPosition(), chosenVertex, minLongitudinalDistance, maxTransverseDistance) ||
377 LArPointingClusterHelper::IsEmission(vertex.
GetPosition(), chosenVertex, minLongitudinalDistance, maxLongitudinalDistance, maxTransverseDistance, angularAllowance))
379 outputList.push_back(chosenVertex);
388 float associatedEnergy(0.
f);
393 const Cluster *
const pCluster(clusterVertex.
GetCluster());
395 const float clusterEnergy(LArClusterHelper::GetEnergyFromLength(pCluster));
396 const float clusterLength(LArClusterHelper::GetLength(pCluster));
399 if (deltaLength < std::numeric_limits<float>::epsilon())
401 associatedEnergy += clusterEnergy;
403 else if(deltaLength < clusterLength)
405 associatedEnergy += clusterEnergy * (1.f - (deltaLength / clusterLength));
409 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.