LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
lar_content::LArStitchingHelper Class Reference

LArStitchingHelper class. More...

#include "LArStitchingHelper.h"

Static Public Member Functions

static const pandora::LArTPC & FindClosestTPC (const pandora::Pandora &pandora, const pandora::LArTPC &inputTPC, const bool checkPositive)
 Find closest tpc to a specified input tpc. More...
 
static bool CanTPCsBeStitched (const pandora::LArTPC &firstTPC, const pandora::LArTPC &secondTPC)
 Whether particles from a given pair of tpcs can be stitched together. More...
 
static bool AreTPCsAdjacent (const pandora::LArTPC &firstTPC, const pandora::LArTPC &secondTPC)
 Whether a pair of drift volumes are adjacent to each other. More...
 
static bool AreTPCsAdjacent (const pandora::Pandora &pandora, const pandora::LArTPC &firstTPC, const pandora::LArTPC &secondTPC)
 Whether a pair of drift volumes are adjacent to each other. More...
 
static float GetTPCBoundaryCenterX (const pandora::LArTPC &firstTPC, const pandora::LArTPC &secondTPC)
 Determine centre in X at the boundary between a pair of tpcs. More...
 
static float GetTPCBoundaryWidthX (const pandora::LArTPC &firstTPC, const pandora::LArTPC &secondTPC)
 Determine width in X at the boundary between a pair of tpcs. More...
 
static float GetTPCDisplacement (const pandora::LArTPC &firstTPC, const pandora::LArTPC &secondTPC)
 Calculate distance between central positions of a pair of tpcs. More...
 
static void GetClosestVertices (const pandora::LArTPC &larTPC1, const pandora::LArTPC &larTPC2, const LArPointingCluster &pointingCluster1, const LArPointingCluster &pointingCluster2, LArPointingCluster::Vertex &closestVertex1, LArPointingCluster::Vertex &closestVertex2)
 Given a pair of pointing clusters, find the pair of vertices with smallest yz-separation. More...
 
static float CalculateX0 (const pandora::LArTPC &firstTPC, const pandora::LArTPC &secondTPC, const LArPointingCluster::Vertex &firstVertex, const LArPointingCluster::Vertex &secondVertex)
 Calculate X0 for a pair of vertices. More...
 
static pandora::CartesianVector GetCorrectedPosition (const pandora::LArTPC &larTPC, const float x0, const pandora::CartesianVector &inputPosition)
 Apply the X0 correction to an input position vector. More...
 
static bool SortTPCs (const pandora::LArTPC *const pLhs, const pandora::LArTPC *const pRhs)
 Sort tpcs by central positions. More...
 

Detailed Description

LArStitchingHelper class.

Definition at line 23 of file LArStitchingHelper.h.

Member Function Documentation

static bool lar_content::LArStitchingHelper::AreTPCsAdjacent ( const pandora::LArTPC &  firstTPC,
const pandora::LArTPC &  secondTPC 
)
static

Whether a pair of drift volumes are adjacent to each other.

Parameters
firstTPCthe first tpc
secondTPCthe second tpc
Returns
boolean
static bool lar_content::LArStitchingHelper::AreTPCsAdjacent ( const pandora::Pandora &  pandora,
const pandora::LArTPC &  firstTPC,
const pandora::LArTPC &  secondTPC 
)
static

Whether a pair of drift volumes are adjacent to each other.

Parameters
pandorathe pandora stitching instance
firstTPCthe first tpc
secondTPCthe second tpc
Returns
boolean
float lar_content::LArStitchingHelper::CalculateX0 ( const pandora::LArTPC &  firstTPC,
const pandora::LArTPC &  secondTPC,
const LArPointingCluster::Vertex firstVertex,
const LArPointingCluster::Vertex secondVertex 
)
static

Calculate X0 for a pair of vertices.

Parameters
firstTPCthe first tpc
secondTPCthe second tpc
firstVertexthe relevant vertex from the first pointing cluster
secondVertexthe relevant vertex from the second pointing cluster
Returns
X0 value for this pair of vertices

Definition at line 232 of file LArStitchingHelper.cc.

References f, lar_content::LArPointingCluster::Vertex::GetDirection(), lar_content::LArPointingCluster::Vertex::GetPosition(), X1, and X2.

Referenced by lar_content::StitchingCosmicRayMergingTool::CalculateX0().

234 {
235  if (&firstTPC == &secondTPC)
236  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
237 
238  // ATTN: Assume that Pfos are crossing either an anode-anode boundary or a cathode-cathode boundary
239  if (firstTPC.IsDriftInPositiveX() == secondTPC.IsDriftInPositiveX())
240  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
241 
242  // Assume that Pfos have opposite direction components in x, and have some direction component in the y-z plane
243  const CartesianVector firstDirectionX(firstVertex.GetDirection().GetX(), 0.f, 0.f);
244  const CartesianVector secondDirectionX(secondVertex.GetDirection().GetX(), 0.f, 0.f);
245 
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);
249 
250  if (-firstDirectionX.GetDotProduct(secondDirectionX) < std::numeric_limits<float>::epsilon())
251  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
252 
253  // Calculate displacement in x from relative displacement in y-z plane
254  const CartesianVector firstPositionYZ(0.f, firstVertex.GetPosition().GetY(), firstVertex.GetPosition().GetZ());
255  const CartesianVector firstDirectionYZ(0.f, firstVertex.GetDirection().GetY(), firstVertex.GetDirection().GetZ());
256 
257  const CartesianVector secondPositionYZ(0.f, secondVertex.GetPosition().GetY(), secondVertex.GetPosition().GetZ());
258  const CartesianVector secondDirectionYZ(0.f, secondVertex.GetDirection().GetY(), secondVertex.GetDirection().GetZ());
259 
260  const float firstDirectionYZmag(firstDirectionYZ.GetMagnitude());
261  const float secondDirectionYZmag(secondDirectionYZ.GetMagnitude());
262 
263  if (firstDirectionYZmag < std::numeric_limits<float>::epsilon() || secondDirectionYZmag < std::numeric_limits<float>::epsilon())
264  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
265 
266  const float R1(firstDirectionYZ.GetUnitVector().GetDotProduct(firstPositionYZ - secondPositionYZ) / firstDirectionYZmag);
267  const float X1(-1.f * firstDirectionX.GetUnitVector().GetDotProduct(secondVertex.GetPosition() - (firstVertex.GetPosition() - firstVertex.GetDirection() * R1)));
268 
269  const float R2(secondDirectionYZ.GetUnitVector().GetDotProduct(secondPositionYZ - firstPositionYZ) / secondDirectionYZmag);
270  const float X2(-1.f * secondDirectionX.GetUnitVector().GetDotProduct(firstVertex.GetPosition() - (secondVertex.GetPosition() - secondVertex.GetDirection() * R2)));
271 
272  // ATTN: By convention, X0 is half the displacement in x (because both Pfos will be corrected)
273  return (X1 + X2) * 0.25f;
274 }
Double_t X2
Definition: plot.C:266
TFile f
Definition: plotHisto.C:6
Double_t X1
Definition: plot.C:266
bool lar_content::LArStitchingHelper::CanTPCsBeStitched ( const pandora::LArTPC &  firstTPC,
const pandora::LArTPC &  secondTPC 
)
static

Whether particles from a given pair of tpcs can be stitched together.

Parameters
firstTPCthe first tpc
secondTPCthe second tpc
Returns
boolean

Definition at line 69 of file LArStitchingHelper.cc.

References f.

Referenced by lar_content::StitchingCosmicRayMergingTool::CalculateX0(), and lar_content::StitchingCosmicRayMergingTool::CreatePfoMatches().

70 {
71  if (&firstTPC == &secondTPC)
72  return false;
73 
74  // ATTN: We assume that Pfos are crossing either an anode-anode boundary or a cathode-cathode boundary
75  if (firstTPC.IsDriftInPositiveX() == secondTPC.IsDriftInPositiveX())
76  return false;
77 
78  return LArStitchingHelper::AreTPCsAdjacent(firstTPC, secondTPC);
79 }
static bool AreTPCsAdjacent(const pandora::LArTPC &firstTPC, const pandora::LArTPC &secondTPC)
Whether a pair of drift volumes are adjacent to each other.
const LArTPC & lar_content::LArStitchingHelper::FindClosestTPC ( const pandora::Pandora &  pandora,
const pandora::LArTPC &  inputTPC,
const bool  checkPositive 
)
static

Find closest tpc to a specified input tpc.

Parameters
pandorathe pandora stitching instance
inputTPCthe specified drift volume
checkPositivelook in higher (lower) x positions if this is set to true (false)
Returns
the closest tpc

Definition at line 23 of file LArStitchingHelper.cc.

References f, MultiPandoraApi::GetPandoraInstanceMap(), and max.

24 {
26  {
27  std::cout << "LArStitchingHelper::FindClosestTPC - functionality only available to primary/master Pandora instance " << std::endl;
28  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
29  }
30 
31  const LArTPCMap &larTPCMap(pandora.GetGeometry()->GetLArTPCMap());
32 
33  const LArTPC *pClosestTPC(nullptr);
34  float closestSeparation(std::numeric_limits<float>::max());
35  const float maxDisplacement(30.f); // TODO: 30cm should be fine, but can we do better than a hard-coded number here?
36 
37  for (const LArTPCMap::value_type &mapEntry : larTPCMap)
38  {
39  const LArTPC &checkTPC(*(mapEntry.second));
40 
41  if (&inputTPC == &checkTPC)
42  continue;
43 
44  if (checkPositive != (checkTPC.GetCenterX() > inputTPC.GetCenterX()))
45  continue;
46 
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()));
50 
51  if (deltaY > maxDisplacement || deltaZ > maxDisplacement)
52  continue;
53 
54  if (deltaX < closestSeparation)
55  {
56  closestSeparation = deltaX;
57  pClosestTPC = &checkTPC;
58  }
59  }
60 
61  if (!pClosestTPC)
62  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
63 
64  return (*pClosestTPC);
65 }
TFile f
Definition: plotHisto.C:6
Int_t max
Definition: plot.C:27
static const PandoraInstanceMap & GetPandoraInstanceMap()
Get the pandora instance map.
void lar_content::LArStitchingHelper::GetClosestVertices ( const pandora::LArTPC &  larTPC1,
const pandora::LArTPC &  larTPC2,
const LArPointingCluster pointingCluster1,
const LArPointingCluster pointingCluster2,
LArPointingCluster::Vertex closestVertex1,
LArPointingCluster::Vertex closestVertex2 
)
static

Given a pair of pointing clusters, find the pair of vertices with smallest yz-separation.

Parameters
larTPC1the first tpc
larTPC2the second tpc
pointingCluster1the pointing cluster in the first tpc
pointingCluster2the pointing cluster in the second tpc
closestVertex1to receive the relevant vertex from the first pointing cluster
closestVertex2to receive the relevant vertex from the second pointing cluster

Definition at line 178 of file LArStitchingHelper.cc.

References f, lar_content::LArPointingCluster::GetInnerVertex(), lar_content::LArPointingCluster::GetOuterVertex(), lar_content::LArPointingCluster::Vertex::GetPosition(), and min.

Referenced by lar_content::StitchingCosmicRayMergingTool::CalculateX0(), lar_content::StitchingCosmicRayMergingTool::CreatePfoMatches(), and lar_content::StitchingCosmicRayMergingTool::OrderPfoMerges().

181 {
182  if (&larTPC1 == &larTPC2)
183  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
184 
185  // Find the closest vertices based on relative X positions in tpc
186  const float dxVolume(larTPC2.GetCenterX() - larTPC1.GetCenterX());
187  const float dx1(pointingCluster1.GetOuterVertex().GetPosition().GetX() - pointingCluster1.GetInnerVertex().GetPosition().GetX());
188  const float dx2(pointingCluster2.GetOuterVertex().GetPosition().GetX() - pointingCluster2.GetInnerVertex().GetPosition().GetX());
189 
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);
192 
193  const bool useInner1((dxVolume > 0.f) == (dx1 < 0.f)); // xVol1 - OUTER - INNER - | - xVol2 [xVol2-xVol1>0; xOuter1-xInner1<0]
194  const bool useInner2((dxVolume > 0.f) == (dx2 > 0.f)); // xVol1 - | - INNER - OUTER - xVol2 [xVol2-xVol1>0; xOuter2-xInner2>0]
195 
196  // Confirm that these really are the closest pair of vertices by checking the other possible pairs
197  const LArPointingCluster::Vertex &nearVertex1(useInner1 ? pointingCluster1.GetInnerVertex() : pointingCluster1.GetOuterVertex());
198  const LArPointingCluster::Vertex &nearVertex2(useInner2 ? pointingCluster2.GetInnerVertex() : pointingCluster2.GetOuterVertex());
199 
200  const LArPointingCluster::Vertex &farVertex1(useInner1 ? pointingCluster1.GetOuterVertex() : pointingCluster1.GetInnerVertex());
201  const LArPointingCluster::Vertex &farVertex2(useInner2 ? pointingCluster2.GetOuterVertex() : pointingCluster2.GetInnerVertex());
202 
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);
207 
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);
212 
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);
217 
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);
222 
223  if (drNearNearSquared > std::min(drFarFarSquared, std::min(drNearFarSquared, drFarNearSquared)))
224  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
225 
226  closestVertex1 = nearVertex1;
227  closestVertex2 = nearVertex2;
228 }
TFile f
Definition: plotHisto.C:6
Int_t min
Definition: plot.C:26
CartesianVector lar_content::LArStitchingHelper::GetCorrectedPosition ( const pandora::LArTPC &  larTPC,
const float  x0,
const pandora::CartesianVector &  inputPosition 
)
static

Apply the X0 correction to an input position vector.

Parameters
larTPCthe tpc
x0the x0 value
inputPositionthe input uncorrected position vector
Returns
the output corrected position vector

Definition at line 278 of file LArStitchingHelper.cc.

279 {
280  return (inputPosition + CartesianVector(larTPC.IsDriftInPositiveX() ? -x0 : x0, 0.f, 0.f));
281 }
float lar_content::LArStitchingHelper::GetTPCBoundaryCenterX ( const pandora::LArTPC &  firstTPC,
const pandora::LArTPC &  secondTPC 
)
static

Determine centre in X at the boundary between a pair of tpcs.

Parameters
firstTPCthe first tpc
secondTPCthe second tpc
Returns
boundary X centre

Definition at line 133 of file LArStitchingHelper.cc.

Referenced by lar_content::StitchingCosmicRayMergingTool::CreatePfoMatches().

134 {
135  if (!LArStitchingHelper::AreTPCsAdjacent(firstTPC, secondTPC))
136  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
137 
138  if (firstTPC.GetCenterX() < secondTPC.GetCenterX())
139  {
140  return 0.5 * ((firstTPC.GetCenterX() + 0.5 * firstTPC.GetWidthX()) + (secondTPC.GetCenterX() - 0.5 * secondTPC.GetWidthX()));
141  }
142  else
143  {
144  return 0.5 * ((firstTPC.GetCenterX() - 0.5 * firstTPC.GetWidthX()) + (secondTPC.GetCenterX() + 0.5 * secondTPC.GetWidthX()));
145  }
146 }
static bool AreTPCsAdjacent(const pandora::LArTPC &firstTPC, const pandora::LArTPC &secondTPC)
Whether a pair of drift volumes are adjacent to each other.
float lar_content::LArStitchingHelper::GetTPCBoundaryWidthX ( const pandora::LArTPC &  firstTPC,
const pandora::LArTPC &  secondTPC 
)
static

Determine width in X at the boundary between a pair of tpcs.

Parameters
firstTPCthe first tpc
secondTPCthe second tpc
Returns
boundary X width

Definition at line 150 of file LArStitchingHelper.cc.

Referenced by lar_content::StitchingCosmicRayMergingTool::CreatePfoMatches().

151 {
152  if (!LArStitchingHelper::AreTPCsAdjacent(firstTPC, secondTPC))
153  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
154 
155  if (firstTPC.GetCenterX() < secondTPC.GetCenterX())
156  {
157  return ((secondTPC.GetCenterX() - 0.5 * secondTPC.GetWidthX()) - (firstTPC.GetCenterX() + 0.5 * firstTPC.GetWidthX()));
158  }
159  else
160  {
161  return ((firstTPC.GetCenterX() - 0.5 * firstTPC.GetWidthX()) - (secondTPC.GetCenterX() + 0.5 * secondTPC.GetWidthX()));
162  }
163 }
static bool AreTPCsAdjacent(const pandora::LArTPC &firstTPC, const pandora::LArTPC &secondTPC)
Whether a pair of drift volumes are adjacent to each other.
float lar_content::LArStitchingHelper::GetTPCDisplacement ( const pandora::LArTPC &  firstTPC,
const pandora::LArTPC &  secondTPC 
)
static

Calculate distance between central positions of a pair of tpcs.

Parameters
firstTPCthe first tpc
secondTPCthe second tpc
Returns
the distance

Definition at line 167 of file LArStitchingHelper.cc.

Referenced by lar_content::StitchingCosmicRayMergingTool::OrderPfoMerges().

168 {
169  const float deltaX(firstTPC.GetCenterX() - secondTPC.GetCenterX());
170  const float deltaY(firstTPC.GetCenterY() - secondTPC.GetCenterY());
171  const float deltaZ(firstTPC.GetCenterZ() - secondTPC.GetCenterZ());
172 
173  return std::sqrt(deltaX * deltaX + deltaY * deltaY + deltaZ * deltaZ);
174 }
bool lar_content::LArStitchingHelper::SortTPCs ( const pandora::LArTPC *const  pLhs,
const pandora::LArTPC *const  pRhs 
)
static

Sort tpcs by central positions.

Parameters
pLhsaddress of first tpc
pRhsaddress of second tpc

Definition at line 285 of file LArStitchingHelper.cc.

Referenced by lar_content::StitchingCosmicRayMergingTool::CreatePfoMatches().

286 {
287  if (std::fabs(pLhs->GetCenterX() - pRhs->GetCenterX()) > std::numeric_limits<float>::epsilon())
288  return (pLhs->GetCenterX() < pRhs->GetCenterX());
289 
290  if (std::fabs(pLhs->GetCenterY() - pRhs->GetCenterY()) > std::numeric_limits<float>::epsilon())
291  return (pLhs->GetCenterY() < pRhs->GetCenterY());
292 
293  return (pLhs->GetCenterZ() < pRhs->GetCenterZ());
294 }

The documentation for this class was generated from the following files: