LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
ThreeDLongitudinalTracksAlgorithm.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
10 
13 
15 
16 using namespace pandora;
17 
18 namespace lar_content
19 {
20 
21 ThreeDLongitudinalTracksAlgorithm::ThreeDLongitudinalTracksAlgorithm() :
22  m_nMaxTensorToolRepeats(1000),
23  m_vertexChi2Cut(10.f),
24  m_reducedChi2Cut(5.f),
25  m_samplingPitch(1.f)
26 {
27 }
28 
29 //------------------------------------------------------------------------------------------------------------------------------------------
30 
31 void ThreeDLongitudinalTracksAlgorithm::CalculateOverlapResult(const Cluster *const pClusterU, const Cluster *const pClusterV, const Cluster *const pClusterW)
32 {
33  LongitudinalOverlapResult overlapResult;
34  this->CalculateOverlapResult(pClusterU, pClusterV, pClusterW, overlapResult);
35 
36  if (overlapResult.IsInitialized())
37  m_overlapTensor.SetOverlapResult(pClusterU, pClusterV, pClusterW, overlapResult);
38 }
39 
40 //------------------------------------------------------------------------------------------------------------------------------------------
41 
42 void ThreeDLongitudinalTracksAlgorithm::CalculateOverlapResult(const Cluster *const pClusterU, const Cluster *const pClusterV, const Cluster *const pClusterW,
43  LongitudinalOverlapResult &longitudinalOverlapResult)
44 {
45  const TwoDSlidingFitResult &slidingFitResultU(this->GetCachedSlidingFitResult(pClusterU));
46  const TwoDSlidingFitResult &slidingFitResultV(this->GetCachedSlidingFitResult(pClusterV));
47  const TwoDSlidingFitResult &slidingFitResultW(this->GetCachedSlidingFitResult(pClusterW));
48 
49  // Loop over possible permutations of cluster direction
50  TrackOverlapResult bestOverlapResult;
51 
52  for (unsigned int iPermutation = 0; iPermutation < 4; ++iPermutation)
53  {
54  const bool isForwardU((1 == iPermutation) ? false : true);
55  const bool isForwardV((2 == iPermutation) ? false : true);
56  const bool isForwardW((3 == iPermutation) ? false : true);
57 
58  // Get 2D start and end positions from each sliding fit for this permutation
59  const CartesianVector vtxU((isForwardU) ? slidingFitResultU.GetGlobalMinLayerPosition() : slidingFitResultU.GetGlobalMaxLayerPosition());
60  const CartesianVector endU((!isForwardU) ? slidingFitResultU.GetGlobalMinLayerPosition() : slidingFitResultU.GetGlobalMaxLayerPosition());
61 
62  const CartesianVector vtxV((isForwardV) ? slidingFitResultV.GetGlobalMinLayerPosition() : slidingFitResultV.GetGlobalMaxLayerPosition());
63  const CartesianVector endV((!isForwardV) ? slidingFitResultV.GetGlobalMinLayerPosition() : slidingFitResultV.GetGlobalMaxLayerPosition());
64 
65  const CartesianVector vtxW((isForwardW) ? slidingFitResultW.GetGlobalMinLayerPosition() : slidingFitResultW.GetGlobalMaxLayerPosition());
66  const CartesianVector endW((!isForwardW) ? slidingFitResultW.GetGlobalMinLayerPosition() : slidingFitResultW.GetGlobalMaxLayerPosition());
67 
68  // Merge start and end positions (three views)
69  const float halfLengthSquaredU(0.25*(vtxU - endU).GetMagnitudeSquared());
70  const float halfLengthSquaredV(0.25*(vtxV - endV).GetMagnitudeSquared());
71  const float halfLengthSquaredW(0.25*(vtxW - endW).GetMagnitudeSquared());
72 
73  CartesianVector vtxMergedU(0.f,0.f,0.f), vtxMergedV(0.f,0.f,0.f), vtxMergedW(0.f,0.f,0.f);
74  CartesianVector endMergedU(0.f,0.f,0.f), endMergedV(0.f,0.f,0.f), endMergedW(0.f,0.f,0.f);
75 
76  float vtxChi2(std::numeric_limits<float>::max());
77  float endChi2(std::numeric_limits<float>::max());
78 
79  LArGeometryHelper::MergeThreePositions(this->GetPandora(), TPC_VIEW_U, TPC_VIEW_V, TPC_VIEW_W, vtxU, vtxV, vtxW, vtxMergedU,
80  vtxMergedV, vtxMergedW, vtxChi2);
81 
82  if (vtxChi2 > m_vertexChi2Cut)
83  continue;
84 
85  if (((vtxMergedU - vtxU).GetMagnitudeSquared() > std::min(halfLengthSquaredU, (vtxMergedU - endU).GetMagnitudeSquared())) ||
86  ((vtxMergedV - vtxV).GetMagnitudeSquared() > std::min(halfLengthSquaredV, (vtxMergedV - endV).GetMagnitudeSquared())) ||
87  ((vtxMergedW - vtxW).GetMagnitudeSquared() > std::min(halfLengthSquaredW, (vtxMergedW - endW).GetMagnitudeSquared())))
88  continue;
89 
90  LArGeometryHelper::MergeThreePositions(this->GetPandora(), TPC_VIEW_U, TPC_VIEW_V, TPC_VIEW_W, endU, endV, endW, endMergedU,
91  endMergedV, endMergedW, endChi2);
92 
93  if (endChi2 > m_vertexChi2Cut)
94  continue;
95 
96  if (((endMergedU - endU).GetMagnitudeSquared() > std::min(halfLengthSquaredU, (endMergedU - vtxU).GetMagnitudeSquared())) ||
97  ((endMergedV - endV).GetMagnitudeSquared() > std::min(halfLengthSquaredV, (endMergedV - vtxV).GetMagnitudeSquared())) ||
98  ((endMergedW - endW).GetMagnitudeSquared() > std::min(halfLengthSquaredW, (endMergedW - vtxW).GetMagnitudeSquared())))
99  continue;
100 
101  // Merge start and end positions (two views)
102  float chi2(0.f);
103  CartesianVector position3D(0.f,0.f,0.f);
104  CartesianPointVector vtxList3D, endList3D;
105 
106  LArGeometryHelper::MergeTwoPositions3D(this->GetPandora(), TPC_VIEW_U, TPC_VIEW_V, vtxU, vtxV, position3D, chi2);
107  vtxList3D.push_back(position3D);
108 
109  LArGeometryHelper::MergeTwoPositions3D(this->GetPandora(), TPC_VIEW_V, TPC_VIEW_W, vtxV, vtxW, position3D, chi2);
110  vtxList3D.push_back(position3D);
111 
112  LArGeometryHelper::MergeTwoPositions3D(this->GetPandora(), TPC_VIEW_W, TPC_VIEW_U, vtxW, vtxU, position3D, chi2);
113  vtxList3D.push_back(position3D);
114 
115  LArGeometryHelper::MergeTwoPositions3D(this->GetPandora(), TPC_VIEW_U, TPC_VIEW_V, endU, endV, position3D, chi2);
116  endList3D.push_back(position3D);
117 
118  LArGeometryHelper::MergeTwoPositions3D(this->GetPandora(), TPC_VIEW_V, TPC_VIEW_W, endV, endW, position3D, chi2);
119  endList3D.push_back(position3D);
120 
121  LArGeometryHelper::MergeTwoPositions3D(this->GetPandora(), TPC_VIEW_W, TPC_VIEW_U, endW, endU, position3D, chi2);
122  endList3D.push_back(position3D);
123 
124  // Find best matched 3D trajactory
125  for (CartesianPointVector::const_iterator iterI = vtxList3D.begin(), iterEndI = vtxList3D.end(); iterI != iterEndI; ++iterI)
126  {
127  const CartesianVector &vtxMerged3D(*iterI);
128 
129  for (CartesianPointVector::const_iterator iterJ = endList3D.begin(), iterEndJ = endList3D.end(); iterJ != iterEndJ; ++iterJ)
130  {
131  const CartesianVector &endMerged3D(*iterJ);
132 
133  TrackOverlapResult overlapResult;
134  this->CalculateOverlapResult(slidingFitResultU, slidingFitResultV, slidingFitResultW,
135  vtxMerged3D, endMerged3D, overlapResult);
136 
137  if (overlapResult.IsInitialized() && (overlapResult.GetNMatchedSamplingPoints() > 0) && (overlapResult > bestOverlapResult))
138  {
139  bestOverlapResult = overlapResult;
140  longitudinalOverlapResult = LongitudinalOverlapResult(overlapResult, vtxChi2, endChi2);
141  }
142  }
143  }
144  }
145 }
146 
147 //------------------------------------------------------------------------------------------------------------------------------------------
148 
149 void ThreeDLongitudinalTracksAlgorithm::CalculateOverlapResult(const TwoDSlidingFitResult &slidingFitResultU, const TwoDSlidingFitResult &slidingFitResultV,
150  const TwoDSlidingFitResult &slidingFitResultW, const CartesianVector &vtxMerged3D, const CartesianVector &endMerged3D, TrackOverlapResult &overlapResult) const
151 {
152  // Calculate start and end positions of linear trajectory
153  const CartesianVector vtxMergedU(LArGeometryHelper::ProjectPosition(this->GetPandora(), vtxMerged3D, TPC_VIEW_U));
154  const CartesianVector vtxMergedV(LArGeometryHelper::ProjectPosition(this->GetPandora(), vtxMerged3D, TPC_VIEW_V));
155  const CartesianVector vtxMergedW(LArGeometryHelper::ProjectPosition(this->GetPandora(), vtxMerged3D, TPC_VIEW_W));
156 
157  const CartesianVector endMergedU(LArGeometryHelper::ProjectPosition(this->GetPandora(), endMerged3D, TPC_VIEW_U));
158  const CartesianVector endMergedV(LArGeometryHelper::ProjectPosition(this->GetPandora(), endMerged3D, TPC_VIEW_V));
159  const CartesianVector endMergedW(LArGeometryHelper::ProjectPosition(this->GetPandora(), endMerged3D, TPC_VIEW_W));
160 
161  const unsigned int nSamplingPoints = static_cast<unsigned int>((endMerged3D - vtxMerged3D).GetMagnitude()/ m_samplingPitch);
162 
163  if(0 == nSamplingPoints)
164  return;
165 
166  // Loop over sampling points and calculate track overlap result
167  float deltaChi2(0.f), totalChi2(0.f);
168  unsigned int nMatchedSamplingPoints(0);
169 
170  for (unsigned int n = 0; n < nSamplingPoints; ++n)
171  {
172  const float alpha((0.5f + static_cast<float>(n)) / static_cast<float>(nSamplingPoints));
173  const CartesianVector linearU(vtxMergedU + (endMergedU - vtxMergedU) * alpha);
174  const CartesianVector linearV(vtxMergedV + (endMergedV - vtxMergedV) * alpha);
175  const CartesianVector linearW(vtxMergedW + (endMergedW - vtxMergedW) * alpha);
176 
177  CartesianVector posU(0.f,0.f,0.f), posV(0.f,0.f,0.f), posW(0.f,0.f,0.f);
178  if ((STATUS_CODE_SUCCESS != slidingFitResultU.GetGlobalFitProjection(linearU, posU)) ||
179  (STATUS_CODE_SUCCESS != slidingFitResultV.GetGlobalFitProjection(linearV, posV)) ||
180  (STATUS_CODE_SUCCESS != slidingFitResultW.GetGlobalFitProjection(linearW, posW)))
181  {
182  continue;
183  }
184 
185  CartesianVector mergedU(0.f,0.f,0.f), mergedV(0.f,0.f,0.f), mergedW(0.f,0.f,0.f);
186  LArGeometryHelper::MergeThreePositions(this->GetPandora(), posU, posV, posW, mergedU, mergedV, mergedW, deltaChi2);
187 
188  if (deltaChi2 < m_reducedChi2Cut)
189  ++nMatchedSamplingPoints;
190 
191  totalChi2 += deltaChi2;
192  }
193 
194  if (nMatchedSamplingPoints > 0)
195  overlapResult = TrackOverlapResult(nMatchedSamplingPoints, nSamplingPoints, totalChi2);
196 }
197 
198 //------------------------------------------------------------------------------------------------------------------------------------------
199 
201 {
202  unsigned int repeatCounter(0);
203 
204  for (TensorToolVector::const_iterator iter = m_algorithmToolVector.begin(), iterEnd = m_algorithmToolVector.end(); iter != iterEnd; )
205  {
206  if ((*iter)->Run(this, m_overlapTensor))
207  {
208  iter = m_algorithmToolVector.begin();
209 
210  if (++repeatCounter > m_nMaxTensorToolRepeats)
211  break;
212  }
213  else
214  {
215  ++iter;
216  }
217  }
218 }
219 
220 //------------------------------------------------------------------------------------------------------------------------------------------
221 
222 StatusCode ThreeDLongitudinalTracksAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
223 {
224  AlgorithmToolVector algorithmToolVector;
225  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmToolList(*this, xmlHandle,
226  "TrackTools", algorithmToolVector));
227 
228  for (AlgorithmToolVector::const_iterator iter = algorithmToolVector.begin(), iterEnd = algorithmToolVector.end(); iter != iterEnd; ++iter)
229  {
230  LongitudinalTensorTool *const pLongitudinalTensorTool(dynamic_cast<LongitudinalTensorTool*>(*iter));
231 
232  if (NULL == pLongitudinalTensorTool)
233  return STATUS_CODE_INVALID_PARAMETER;
234 
235  m_algorithmToolVector.push_back(pLongitudinalTensorTool);
236  }
237 
238  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
239  "NMaxTensorToolRepeats", m_nMaxTensorToolRepeats));
240 
241  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
242  "VertexChi2Cut", m_vertexChi2Cut));
243 
244  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
245  "ReducedChi2Cut", m_reducedChi2Cut));
246 
247  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
248  "SamplingPitch", m_samplingPitch));
249 
250  if (m_samplingPitch < std::numeric_limits<float>::epsilon())
251  return STATUS_CODE_INVALID_PARAMETER;
252 
254 }
255 
256 } // namespace lar_content
LongitudinalOverlapResult class.
static void MergeTwoPositions3D(const pandora::Pandora &pandora, const pandora::HitType view1, const pandora::HitType view2, const pandora::CartesianVector &position1, const pandora::CartesianVector &position2, pandora::CartesianVector &position3D, float &chiSquared)
Merge 2D positions from two views to give unified 3D position.
unsigned int GetNMatchedSamplingPoints() const
Get the number of matched sampling points.
bool IsInitialized() const
Whether the track overlap result has been initialized.
void CalculateOverlapResult(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV, const pandora::Cluster *const pClusterW)
Calculate cluster overlap result and store in tensor.
static pandora::CartesianVector ProjectPosition(const pandora::Pandora &pandora, const pandora::CartesianVector &position3D, const pandora::HitType view)
Project 3D position into a given 2D view.
TensorToolVector m_algorithmToolVector
The algorithm tool vector.
const TwoDSlidingFitResult & GetCachedSlidingFitResult(const pandora::Cluster *const pCluster) const
Get a sliding fit result from the algorithm cache.
TFile f
Definition: plotHisto.C:6
Header file for the geometry helper class.
float m_samplingPitch
Pitch used to generate sampling points along tracks.
void SetOverlapResult(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV, const pandora::Cluster *const pClusterW, const OverlapResult &overlapResult)
Set overlap result.
Int_t max
Definition: plot.C:27
float m_reducedChi2Cut
The maximum allowed chi2 for associating hit positions from three views.
intermediate_table::const_iterator const_iterator
Header file for the cluster helper class.
pandora::CartesianVector GetGlobalMinLayerPosition() const
Get global position corresponding to the fit result in minimum fit layer.
static void MergeThreePositions(const pandora::Pandora &pandora, const pandora::HitType view1, const pandora::HitType view2, const pandora::HitType view3, const pandora::CartesianVector &position1, const pandora::CartesianVector &position2, const pandora::CartesianVector &position3, pandora::CartesianVector &outputU, pandora::CartesianVector &outputV, pandora::CartesianVector &outputW, float &chiSquared)
Merge 2D positions from three views to give unified 2D positions for each view.
TrackOverlapResult class.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
unsigned int m_nMaxTensorToolRepeats
The maximum number of repeat loops over tensor tools.
Int_t min
Definition: plot.C:26
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
pandora::StatusCode GetGlobalFitProjection(const pandora::CartesianVector &inputPosition, pandora::CartesianVector &projectedPosition) const
Get projected position on global fit for a given position vector.
float m_vertexChi2Cut
The maximum allowed chi2 for associating end points from three views.
Char_t n[5]
pandora::CartesianVector GetGlobalMaxLayerPosition() const
Get global position corresponding to the fit result in maximum fit layer.
void ExamineTensor()
Examine contents of tensor, collect together best-matching 2D particles and modify clusters as requir...
Header file for the three dimensional longitudinal tracks algorithm class.