Static Public Member Functions | List of all members
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 bool SortTPCs (const pandora::LArTPC *const pLhs, const pandora::LArTPC *const pRhs)
 Sort tpcs by central positions. More...
 
static bool HasPfoBeenStitched (const pandora::ParticleFlowObject *const pPfo)
 Whether a pfo has been stitched. More...
 
static float GetPfoX0 (const pandora::ParticleFlowObject *const pPfo)
 Return the x0 for a pfo. 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 231 of file LArStitchingHelper.cc.

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

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.

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 }
static int max(int a, int b)
static const PandoraInstanceMap & GetPandoraInstanceMap()
Get the pandora instance map.
QTextStream & endl(QTextStream &s)
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.

180 {
181  if (&larTPC1 == &larTPC2)
182  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
183 
184  // Find the closest vertices based on relative X positions in tpc
185  const float dxVolume(larTPC2.GetCenterX() - larTPC1.GetCenterX());
186  const float dx1(pointingCluster1.GetOuterVertex().GetPosition().GetX() - pointingCluster1.GetInnerVertex().GetPosition().GetX());
187  const float dx2(pointingCluster2.GetOuterVertex().GetPosition().GetX() - pointingCluster2.GetInnerVertex().GetPosition().GetX());
188 
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);
191 
192  const bool useInner1((dxVolume > 0.f) == (dx1 < 0.f)); // xVol1 - OUTER - INNER - | - xVol2 [xVol2-xVol1>0; xOuter1-xInner1<0]
193  const bool useInner2((dxVolume > 0.f) == (dx2 > 0.f)); // xVol1 - | - INNER - OUTER - xVol2 [xVol2-xVol1>0; xOuter2-xInner2>0]
194 
195  // Confirm that these really are the closest pair of vertices by checking the other possible pairs
196  const LArPointingCluster::Vertex &nearVertex1(useInner1 ? pointingCluster1.GetInnerVertex() : pointingCluster1.GetOuterVertex());
197  const LArPointingCluster::Vertex &nearVertex2(useInner2 ? pointingCluster2.GetInnerVertex() : pointingCluster2.GetOuterVertex());
198 
199  const LArPointingCluster::Vertex &farVertex1(useInner1 ? pointingCluster1.GetOuterVertex() : pointingCluster1.GetInnerVertex());
200  const LArPointingCluster::Vertex &farVertex2(useInner2 ? pointingCluster2.GetOuterVertex() : pointingCluster2.GetInnerVertex());
201 
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);
206 
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);
211 
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);
216 
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);
221 
222  if (drNearNearSquared > std::min(drFarFarSquared, std::min(drNearFarSquared, drFarNearSquared)))
223  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
224 
225  closestVertex1 = nearVertex1;
226  closestVertex2 = nearVertex2;
227 }
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
Definition: ModuleGraph.h:25
float lar_content::LArStitchingHelper::GetPfoX0 ( const pandora::ParticleFlowObject *const  pPfo)
static

Return the x0 for a pfo.

Parameters
pPfothe address of the Pfo

Definition at line 305 of file LArStitchingHelper.cc.

306 {
307  // ATTN: If no stitch is present return a shift of 0.f
309  return 0.f;
310 
311  // ATTN: HasPfoBeenStitched ensures X0 is present in the properties map
312  return pPfo->GetPropertiesMap().at("X0");
313 }
static bool HasPfoBeenStitched(const pandora::ParticleFlowObject *const pPfo)
Whether a pfo has been stitched.
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.

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.

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.

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::HasPfoBeenStitched ( const pandora::ParticleFlowObject *const  pPfo)
static

Whether a pfo has been stitched.

Parameters
pPfothe address of the Pfo
Returns
boolean

Definition at line 292 of file LArStitchingHelper.cc.

293 {
294  const PropertiesMap &properties(pPfo->GetPropertiesMap());
295  const PropertiesMap::const_iterator iter(properties.find("X0"));
296 
297  if (iter != properties.end())
298  return true;
299 
300  return false;
301 }
intermediate_table::const_iterator const_iterator
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 279 of file LArStitchingHelper.cc.

280 {
281  if (std::fabs(pLhs->GetCenterX() - pRhs->GetCenterX()) > std::numeric_limits<float>::epsilon())
282  return (pLhs->GetCenterX() < pRhs->GetCenterX());
283 
284  if (std::fabs(pLhs->GetCenterY() - pRhs->GetCenterY()) > std::numeric_limits<float>::epsilon())
285  return (pLhs->GetCenterY() < pRhs->GetCenterY());
286 
287  return (pLhs->GetCenterZ() < pRhs->GetCenterZ());
288 }

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