9 #include "Managers/GeometryManager.h"
23 const LArTPC &LArStitchingHelper::FindClosestTPC(
const Pandora &
pandora,
const LArTPC &inputTPC,
const bool checkPositive)
27 std::cout <<
"LArStitchingHelper::FindClosestTPC - functionality only available to primary/master Pandora instance " << std::endl;
28 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
31 const LArTPCMap &larTPCMap(pandora.GetGeometry()->GetLArTPCMap());
33 const LArTPC *pClosestTPC(
nullptr);
34 float closestSeparation(std::numeric_limits<float>::max());
35 const float maxDisplacement(30.f);
37 for (
const LArTPCMap::value_type &mapEntry : larTPCMap)
39 const LArTPC &checkTPC(*(mapEntry.second));
41 if (&inputTPC == &checkTPC)
44 if (checkPositive != (checkTPC.GetCenterX() > inputTPC.GetCenterX()))
47 const float deltaX(std::fabs(checkTPC.GetCenterX() - inputTPC.GetCenterX()));
48 const float deltaY(std::fabs(checkTPC.GetCenterY() - inputTPC.GetCenterY()));
49 const float deltaZ(std::fabs(checkTPC.GetCenterZ() - inputTPC.GetCenterZ()));
51 if (deltaY > maxDisplacement || deltaZ > maxDisplacement)
54 if (deltaX < closestSeparation)
56 closestSeparation = deltaX;
57 pClosestTPC = &checkTPC;
62 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
64 return (*pClosestTPC);
69 bool LArStitchingHelper::CanTPCsBeStitched(
const LArTPC &firstTPC,
const LArTPC &secondTPC)
71 if (&firstTPC == &secondTPC)
75 if (firstTPC.IsDriftInPositiveX() == secondTPC.IsDriftInPositiveX())
78 return LArStitchingHelper::AreTPCsAdjacent(firstTPC, secondTPC);
83 bool LArStitchingHelper::AreTPCsAdjacent(
const LArTPC &firstTPC,
const LArTPC &secondTPC)
86 const float maxDisplacement(30.f);
87 const float widthX(0.5f * (firstTPC.GetWidthX() + secondTPC.GetWidthX()));
88 const float deltaX(std::fabs(firstTPC.GetCenterX() - secondTPC.GetCenterX()));
89 const float deltaY(std::fabs(firstTPC.GetCenterY() - secondTPC.GetCenterY()));
90 const float deltaZ(std::fabs(firstTPC.GetCenterZ() - secondTPC.GetCenterZ()));
92 if (std::fabs(deltaX - widthX) > maxDisplacement || deltaY > maxDisplacement || deltaZ > maxDisplacement)
100 bool LArStitchingHelper::AreTPCsAdjacent(
const Pandora &
pandora,
const LArTPC &firstTPC,
const LArTPC &secondTPC)
105 const LArTPC &firstTPCCheck(LArStitchingHelper::FindClosestTPC(pandora, secondTPC,
true));
106 const LArTPC &secondTPCCheck(LArStitchingHelper::FindClosestTPC(pandora, firstTPC,
false));
108 if ((&firstTPCCheck == &firstTPC) && (&secondTPCCheck == &secondTPC))
111 catch (pandora::StatusCodeException &)
118 const LArTPC &firstTPCCheck(LArStitchingHelper::FindClosestTPC(pandora, secondTPC,
false));
119 const LArTPC &secondTPCCheck(LArStitchingHelper::FindClosestTPC(pandora, firstTPC,
true));
121 if ((&firstTPCCheck == &firstTPC) && (&secondTPCCheck == &secondTPC))
124 catch (pandora::StatusCodeException &)
133 float LArStitchingHelper::GetTPCBoundaryCenterX(
const LArTPC &firstTPC,
const LArTPC &secondTPC)
135 if (!LArStitchingHelper::AreTPCsAdjacent(firstTPC, secondTPC))
136 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
138 if (firstTPC.GetCenterX() < secondTPC.GetCenterX())
140 return 0.5 * ((firstTPC.GetCenterX() + 0.5 * firstTPC.GetWidthX()) + (secondTPC.GetCenterX() - 0.5 * secondTPC.GetWidthX()));
144 return 0.5 * ((firstTPC.GetCenterX() - 0.5 * firstTPC.GetWidthX()) + (secondTPC.GetCenterX() + 0.5 * secondTPC.GetWidthX()));
150 float LArStitchingHelper::GetTPCBoundaryWidthX(
const LArTPC &firstTPC,
const LArTPC &secondTPC)
152 if (!LArStitchingHelper::AreTPCsAdjacent(firstTPC, secondTPC))
153 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
155 if (firstTPC.GetCenterX() < secondTPC.GetCenterX())
157 return ((secondTPC.GetCenterX() - 0.5 * secondTPC.GetWidthX()) - (firstTPC.GetCenterX() + 0.5 * firstTPC.GetWidthX()));
161 return ((firstTPC.GetCenterX() - 0.5 * firstTPC.GetWidthX()) - (secondTPC.GetCenterX() + 0.5 * secondTPC.GetWidthX()));
167 float LArStitchingHelper::GetTPCDisplacement(
const LArTPC &firstTPC,
const LArTPC &secondTPC)
169 const float deltaX(firstTPC.GetCenterX() - secondTPC.GetCenterX());
170 const float deltaY(firstTPC.GetCenterY() - secondTPC.GetCenterY());
171 const float deltaZ(firstTPC.GetCenterZ() - secondTPC.GetCenterZ());
173 return std::sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);
178 void LArStitchingHelper::GetClosestVertices(
const LArTPC &larTPC1,
const LArTPC &larTPC2,
const LArPointingCluster &pointingCluster1,
181 if (&larTPC1 == &larTPC2)
182 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
185 const float dxVolume(larTPC2.GetCenterX() - larTPC1.GetCenterX());
189 if (std::fabs(dx1) < std::numeric_limits<float>::epsilon() || std::fabs(dx2) < std::numeric_limits<float>::epsilon())
190 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
192 const bool useInner1((dxVolume > 0.f) == (dx1 < 0.f));
193 const bool useInner2((dxVolume > 0.f) == (dx2 > 0.f));
202 const float dxNearNear(0.f);
203 const float dyNearNear(nearVertex1.GetPosition().GetY() - nearVertex2.GetPosition().GetY());
204 const float dzNearNear(nearVertex1.GetPosition().GetZ() - nearVertex2.GetPosition().GetZ());
205 const float drNearNearSquared(dxNearNear * dxNearNear + dyNearNear * dyNearNear + dzNearNear * dzNearNear);
207 const float dxNearFar(std::fabs(dx2));
208 const float dyNearFar(nearVertex1.GetPosition().GetY() - farVertex2.GetPosition().GetY());
209 const float dzNearFar(nearVertex1.GetPosition().GetZ() - farVertex2.GetPosition().GetZ());
210 const float drNearFarSquared(dxNearFar * dxNearFar + dyNearFar * dyNearFar + dzNearFar * dzNearFar);
212 const float dxFarNear(std::fabs(dx1));
213 const float dyFarNear(farVertex1.GetPosition().GetY() - nearVertex2.GetPosition().GetY());
214 const float dzFarNear(farVertex1.GetPosition().GetZ() - nearVertex2.GetPosition().GetZ());
215 const float drFarNearSquared(dxFarNear * dxFarNear + dyFarNear * dyFarNear + dzFarNear * dzFarNear);
217 const float dxFarFar(std::fabs(dx1) + std::fabs(dx2));
218 const float dyFarFar(farVertex1.GetPosition().GetY() - farVertex2.GetPosition().GetY());
219 const float dzFarFar(farVertex1.GetPosition().GetZ() - farVertex2.GetPosition().GetZ());
220 const float drFarFarSquared(dxFarFar * dxFarFar + dyFarFar * dyFarFar + dzFarFar * dzFarFar);
222 if (drNearNearSquared > std::min(drFarFarSquared, std::min(drNearFarSquared, drFarNearSquared)))
223 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
225 closestVertex1 = nearVertex1;
226 closestVertex2 = nearVertex2;
234 if (&firstTPC == &secondTPC)
235 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
238 if (firstTPC.IsDriftInPositiveX() == secondTPC.IsDriftInPositiveX())
239 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
242 const CartesianVector firstDirectionX(firstVertex.
GetDirection().GetX(), 0.f, 0.f);
243 const CartesianVector secondDirectionX(secondVertex.
GetDirection().GetX(), 0.f, 0.f);
245 if (std::fabs(firstDirectionX.GetX()) > 1.f - std::numeric_limits<float>::epsilon() ||
246 std::fabs(secondDirectionX.GetX()) > 1.f - std::numeric_limits<float>::epsilon())
247 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
249 if (-firstDirectionX.GetDotProduct(secondDirectionX) < std::numeric_limits<float>::epsilon())
250 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
253 const CartesianVector firstPositionYZ(0.f, firstVertex.
GetPosition().GetY(), firstVertex.
GetPosition().GetZ());
256 const CartesianVector secondPositionYZ(0.f, secondVertex.
GetPosition().GetY(), secondVertex.
GetPosition().GetZ());
257 const CartesianVector secondDirectionYZ(0.f, secondVertex.
GetDirection().GetY(), secondVertex.
GetDirection().GetZ());
259 const float firstDirectionYZmag(firstDirectionYZ.GetMagnitude());
260 const float secondDirectionYZmag(secondDirectionYZ.GetMagnitude());
262 if (firstDirectionYZmag < std::numeric_limits<float>::epsilon() || secondDirectionYZmag < std::numeric_limits<float>::epsilon())
263 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
265 const float R1(firstDirectionYZ.GetUnitVector().GetDotProduct(firstPositionYZ - secondPositionYZ) / firstDirectionYZmag);
266 const float X1(-1.f * firstDirectionX.GetUnitVector().GetDotProduct(
269 const float R2(secondDirectionYZ.GetUnitVector().GetDotProduct(secondPositionYZ - firstPositionYZ) / secondDirectionYZmag);
270 const float X2(-1.f * secondDirectionX.GetUnitVector().GetDotProduct(
274 return (X1 + X2) * 0.25f;
279 bool LArStitchingHelper::SortTPCs(
const pandora::LArTPC *
const pLhs,
const pandora::LArTPC *
const pRhs)
281 if (std::fabs(pLhs->GetCenterX() - pRhs->GetCenterX()) > std::numeric_limits<float>::epsilon())
282 return (pLhs->GetCenterX() < pRhs->GetCenterX());
284 if (std::fabs(pLhs->GetCenterY() - pRhs->GetCenterY()) > std::numeric_limits<float>::epsilon())
285 return (pLhs->GetCenterY() < pRhs->GetCenterY());
287 return (pLhs->GetCenterZ() < pRhs->GetCenterZ());
292 bool LArStitchingHelper::HasPfoBeenStitched(
const ParticleFlowObject *
const pPfo)
294 const PropertiesMap &properties(pPfo->GetPropertiesMap());
295 const PropertiesMap::const_iterator iter(properties.find(
"X0"));
297 if (iter != properties.end())
305 float LArStitchingHelper::GetPfoX0(
const ParticleFlowObject *
const pPfo)
308 if (!LArStitchingHelper::HasPfoBeenStitched(pPfo))
312 return pPfo->GetPropertiesMap().at(
"X0");
LArPointingCluster class.
const Vertex & GetOuterVertex() const
Get the outer vertex.
const Vertex & GetInnerVertex() const
Get the inner vertex.
Header file for the MultiPandoraApi class.
const pandora::CartesianVector & GetDirection() const
Get the vertex direction.
Header file for the helper class for multiple drift volumes.
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
static const PandoraInstanceMap & GetPandoraInstanceMap()
Get the pandora instance map.
std::size_t count(Cont const &cont)
const pandora::CartesianVector & GetPosition() const
Get the vertex position.
BEGIN_PROLOG could also be cout