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);
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.5
f * (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,
182 if (&larTPC1 == &larTPC2)
183 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
186 const float dxVolume(larTPC2.GetCenterX() - larTPC1.GetCenterX());
190 if (std::fabs(dx1) < std::numeric_limits<float>::epsilon() || std::fabs(dx2) < std::numeric_limits<float>::epsilon())
191 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
193 const bool useInner1((dxVolume > 0.
f) == (dx1 < 0.
f));
194 const bool useInner2((dxVolume > 0.
f) == (dx2 > 0.
f));
203 const float dxNearNear(0.
f);
204 const float dyNearNear(nearVertex1.GetPosition().GetY() - nearVertex2.GetPosition().GetY());
205 const float dzNearNear(nearVertex1.GetPosition().GetZ() - nearVertex2.GetPosition().GetZ());
206 const float drNearNearSquared(dxNearNear * dxNearNear + dyNearNear * dyNearNear + dzNearNear * dzNearNear);
208 const float dxNearFar(std::fabs(dx2));
209 const float dyNearFar(nearVertex1.GetPosition().GetY() - farVertex2.GetPosition().GetY());
210 const float dzNearFar(nearVertex1.GetPosition().GetZ() - farVertex2.GetPosition().GetZ());
211 const float drNearFarSquared(dxNearFar * dxNearFar + dyNearFar * dyNearFar + dzNearFar * dzNearFar);
213 const float dxFarNear(std::fabs(dx1));
214 const float dyFarNear(farVertex1.GetPosition().GetY() - nearVertex2.GetPosition().GetY());
215 const float dzFarNear(farVertex1.GetPosition().GetZ() - nearVertex2.GetPosition().GetZ());
216 const float drFarNearSquared(dxFarNear * dxFarNear + dyFarNear * dyFarNear + dzFarNear * dzFarNear);
218 const float dxFarFar(std::fabs(dx1) + std::fabs(dx2));
219 const float dyFarFar(farVertex1.GetPosition().GetY() - farVertex2.GetPosition().GetY());
220 const float dzFarFar(farVertex1.GetPosition().GetZ() - farVertex2.GetPosition().GetZ());
221 const float drFarFarSquared(dxFarFar * dxFarFar + dyFarFar * dyFarFar + dzFarFar * dzFarFar);
223 if (drNearNearSquared >
std::min(drFarFarSquared,
std::min(drNearFarSquared, drFarNearSquared)))
224 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
226 closestVertex1 = nearVertex1;
227 closestVertex2 = nearVertex2;
232 float LArStitchingHelper::CalculateX0(
const LArTPC &firstTPC,
const LArTPC &secondTPC,
235 if (&firstTPC == &secondTPC)
236 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
239 if (firstTPC.IsDriftInPositiveX() == secondTPC.IsDriftInPositiveX())
240 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
243 const CartesianVector firstDirectionX(firstVertex.
GetDirection().GetX(), 0.f, 0.f);
244 const CartesianVector secondDirectionX(secondVertex.
GetDirection().GetX(), 0.f, 0.f);
246 if (std::fabs(firstDirectionX.GetX()) > 1.
f - std::numeric_limits<float>::epsilon() ||
247 std::fabs(secondDirectionX.GetX()) > 1.
f - std::numeric_limits<float>::epsilon())
248 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
250 if (-firstDirectionX.GetDotProduct(secondDirectionX) < std::numeric_limits<float>::epsilon())
251 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
254 const CartesianVector firstPositionYZ(0.
f, firstVertex.
GetPosition().GetY(), firstVertex.
GetPosition().GetZ());
257 const CartesianVector secondPositionYZ(0.
f, secondVertex.
GetPosition().GetY(), secondVertex.
GetPosition().GetZ());
260 const float firstDirectionYZmag(firstDirectionYZ.GetMagnitude());
261 const float secondDirectionYZmag(secondDirectionYZ.GetMagnitude());
263 if (firstDirectionYZmag < std::numeric_limits<float>::epsilon() || secondDirectionYZmag < std::numeric_limits<float>::epsilon())
264 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
266 const float R1(firstDirectionYZ.GetUnitVector().GetDotProduct(firstPositionYZ - secondPositionYZ) / firstDirectionYZmag);
269 const float R2(secondDirectionYZ.GetUnitVector().GetDotProduct(secondPositionYZ - firstPositionYZ) / secondDirectionYZmag);
273 return (
X1 +
X2) * 0.25f;
278 CartesianVector LArStitchingHelper::GetCorrectedPosition(
const LArTPC &larTPC,
const float x0,
const CartesianVector &inputPosition)
280 return (inputPosition + CartesianVector(larTPC.IsDriftInPositiveX() ? -x0 : x0, 0.f, 0.f));
285 bool LArStitchingHelper::SortTPCs(
const pandora::LArTPC *
const pLhs,
const pandora::LArTPC *
const pRhs)
287 if (std::fabs(pLhs->GetCenterX() - pRhs->GetCenterX()) > std::numeric_limits<float>::epsilon())
288 return (pLhs->GetCenterX() < pRhs->GetCenterX());
290 if (std::fabs(pLhs->GetCenterY() - pRhs->GetCenterY()) > std::numeric_limits<float>::epsilon())
291 return (pLhs->GetCenterY() < pRhs->GetCenterY());
293 return (pLhs->GetCenterZ() < pRhs->GetCenterZ());
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.
static const PandoraInstanceMap & GetPandoraInstanceMap()
Get the pandora instance map.
const pandora::CartesianVector & GetPosition() const
Get the vertex position.