TrackShowerIdFeatureTool.cc
Go to the documentation of this file.
1 /**
2  * @file larpandoracontent/LArTrackShowerId/TrackShowerIdFeatureTool.cc
3  *
4  * @brief Implementation of the track shower id feature fool class
5  *
6  * $Log: $
7  */
8 
9 #include "Pandora/AlgorithmHeaders.h"
10 
15 
17 
20 
21 using namespace pandora;
22 
23 namespace lar_content
24 {
25 
26 TwoDShowerFitFeatureTool::TwoDShowerFitFeatureTool() : m_slidingShowerFitWindow(3), m_slidingLinearFitWindow(10000)
27 {
28 }
29 
30 //------------------------------------------------------------------------------------------------------------------------------------------
31 
32 void TwoDShowerFitFeatureTool::Run(LArMvaHelper::MvaFeatureVector &featureVector, const Algorithm *const pAlgorithm, const pandora::Cluster *const pCluster)
33 {
34  if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
35  std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
36 
37  float ratio(-1.f);
38  try
39  {
40  const TwoDSlidingFitResult slidingFitResultLarge(pCluster, m_slidingLinearFitWindow, LArGeometryHelper::GetWireZPitch(this->GetPandora()));
41  const float straightLineLength =
42  (slidingFitResultLarge.GetGlobalMaxLayerPosition() - slidingFitResultLarge.GetGlobalMinLayerPosition()).GetMagnitude();
43  if (straightLineLength > std::numeric_limits<float>::epsilon())
44  ratio = (CutClusterCharacterisationAlgorithm::GetShowerFitWidth(pAlgorithm, pCluster, m_slidingShowerFitWindow)) / straightLineLength;
45  }
46  catch (const StatusCodeException &)
47  {
48  ratio = -1.f;
49  }
50  featureVector.push_back(ratio);
51 }
52 
53 //------------------------------------------------------------------------------------------------------------------------------------------
54 
55 StatusCode TwoDShowerFitFeatureTool::ReadSettings(const TiXmlHandle xmlHandle)
56 {
57  PANDORA_RETURN_RESULT_IF_AND_IF(
58  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "SlidingShowerFitWindow", m_slidingShowerFitWindow));
59 
60  PANDORA_RETURN_RESULT_IF_AND_IF(
61  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "SlidingLinearFitWindow", m_slidingLinearFitWindow));
62 
63  return STATUS_CODE_SUCCESS;
64 }
65 
66 //------------------------------------------------------------------------------------------------------------------------------------------
67 //------------------------------------------------------------------------------------------------------------------------------------------
68 
70 {
71 }
72 
73 //------------------------------------------------------------------------------------------------------------------------------------------
74 
75 void TwoDLinearFitFeatureTool::Run(LArMvaHelper::MvaFeatureVector &featureVector, const Algorithm *const pAlgorithm, const pandora::Cluster *const pCluster)
76 {
77  if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
78  std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
79 
80  float dTdLWidth(-1.f), straightLineLengthLarge(-1.f), diffWithStraightLineMean(-1.f), diffWithStraightLineSigma(-1.f),
81  maxFitGapLength(-1.f), rmsSlidingLinearFit(-1.f);
82  this->CalculateVariablesSlidingLinearFit(pCluster, straightLineLengthLarge, diffWithStraightLineMean, diffWithStraightLineSigma,
83  dTdLWidth, maxFitGapLength, rmsSlidingLinearFit);
84 
85  if (straightLineLengthLarge > std::numeric_limits<float>::epsilon())
86  {
87  diffWithStraightLineMean /= straightLineLengthLarge;
88  diffWithStraightLineSigma /= straightLineLengthLarge;
89  dTdLWidth /= straightLineLengthLarge;
90  maxFitGapLength /= straightLineLengthLarge;
91  rmsSlidingLinearFit /= straightLineLengthLarge;
92  }
93 
94  featureVector.push_back(straightLineLengthLarge);
95  featureVector.push_back(diffWithStraightLineMean);
96  featureVector.push_back(diffWithStraightLineSigma);
97  featureVector.push_back(dTdLWidth);
98  featureVector.push_back(maxFitGapLength);
99  featureVector.push_back(rmsSlidingLinearFit);
100 }
101 
102 //------------------------------------------------------------------------------------------------------------------------------------------
103 
104 void TwoDLinearFitFeatureTool::CalculateVariablesSlidingLinearFit(const pandora::Cluster *const pCluster, float &straightLineLengthLarge,
105  float &diffWithStraightLineMean, float &diffWithStraightLineSigma, float &dTdLWidth, float &maxFitGapLength, float &rmsSlidingLinearFit) const
106 {
107  try
108  {
109  const TwoDSlidingFitResult slidingFitResult(pCluster, m_slidingLinearFitWindow, LArGeometryHelper::GetWireZPitch(this->GetPandora()));
110  const TwoDSlidingFitResult slidingFitResultLarge(
111  pCluster, m_slidingLinearFitWindowLarge, LArGeometryHelper::GetWireZPitch(this->GetPandora()));
112 
113  if (slidingFitResult.GetLayerFitResultMap().empty())
114  throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
115 
116  straightLineLengthLarge =
117  (slidingFitResultLarge.GetGlobalMaxLayerPosition() - slidingFitResultLarge.GetGlobalMinLayerPosition()).GetMagnitude();
118  rmsSlidingLinearFit = 0.f;
119 
120  FloatVector diffWithStraightLineVector;
121  const HitType hitType(LArClusterHelper::GetClusterHitType(pCluster));
122  CartesianVector previousFitPosition(slidingFitResult.GetGlobalMinLayerPosition());
124 
125  for (const auto &mapEntry : slidingFitResult.GetLayerFitResultMap())
126  {
127  const LayerFitResult &layerFitResult(mapEntry.second);
128  rmsSlidingLinearFit += layerFitResult.GetRms();
129 
130  CartesianVector thisFitPosition(0.f, 0.f, 0.f);
131  slidingFitResult.GetGlobalPosition(layerFitResult.GetL(), layerFitResult.GetFitT(), thisFitPosition);
132 
134  slidingFitResultLarge.GetLayerFitResultMap().find(slidingFitResultLarge.GetLayer(layerFitResult.GetL()));
135 
136  if (slidingFitResultLarge.GetLayerFitResultMap().end() == iterLarge)
137  throw StatusCodeException(STATUS_CODE_FAILURE);
138 
139  diffWithStraightLineVector.push_back(static_cast<float>(std::fabs(layerFitResult.GetFitT() - iterLarge->second.GetFitT())));
140 
141  const float thisGapLength((thisFitPosition - previousFitPosition).GetMagnitude());
142  const float minZ(std::min(thisFitPosition.GetZ(), previousFitPosition.GetZ()));
143  const float maxZ(std::max(thisFitPosition.GetZ(), previousFitPosition.GetZ()));
144 
145  if ((maxZ - minZ) > std::numeric_limits<float>::epsilon())
146  {
147  const float gapZ(LArGeometryHelper::CalculateGapDeltaZ(this->GetPandora(), minZ, maxZ, hitType));
148  const float correctedGapLength(thisGapLength * (1.f - gapZ / (maxZ - minZ)));
149 
150  if (correctedGapLength > maxFitGapLength)
151  maxFitGapLength = correctedGapLength;
152  }
153 
154  dTdLMin = std::min(dTdLMin, static_cast<float>(layerFitResult.GetGradient()));
155  dTdLMax = std::max(dTdLMax, static_cast<float>(layerFitResult.GetGradient()));
156  previousFitPosition = thisFitPosition;
157  }
158 
159  if (diffWithStraightLineVector.empty())
160  throw StatusCodeException(STATUS_CODE_FAILURE);
161 
162  diffWithStraightLineMean = 0.f;
163  diffWithStraightLineSigma = 0.f;
164 
165  for (const float diffWithStraightLine : diffWithStraightLineVector)
166  diffWithStraightLineMean += diffWithStraightLine;
167 
168  diffWithStraightLineMean /= static_cast<float>(diffWithStraightLineVector.size());
169 
170  for (const float diffWithStraightLine : diffWithStraightLineVector)
171  diffWithStraightLineSigma += (diffWithStraightLine - diffWithStraightLineMean) * (diffWithStraightLine - diffWithStraightLineMean);
172 
173  if (diffWithStraightLineSigma < 0.f)
174  throw StatusCodeException(STATUS_CODE_FAILURE);
175 
176  diffWithStraightLineSigma = std::sqrt(diffWithStraightLineSigma / static_cast<float>(diffWithStraightLineVector.size()));
177  dTdLWidth = dTdLMax - dTdLMin;
178  }
179  catch (const StatusCodeException &)
180  {
181  straightLineLengthLarge = -1.f;
182  diffWithStraightLineMean = -1.f;
183  diffWithStraightLineSigma = -1.f;
184  dTdLWidth = -1.f;
185  maxFitGapLength = -1.f;
186  rmsSlidingLinearFit = -1.f;
187  }
188 }
189 
190 //------------------------------------------------------------------------------------------------------------------------------------------
191 
192 StatusCode TwoDLinearFitFeatureTool::ReadSettings(const TiXmlHandle xmlHandle)
193 {
194  PANDORA_RETURN_RESULT_IF_AND_IF(
195  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "SlidingLinearFitWindow", m_slidingLinearFitWindow));
196 
197  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
198  XmlHelper::ReadValue(xmlHandle, "SlidingLinearFitWindowLarge", m_slidingLinearFitWindowLarge));
199 
200  return STATUS_CODE_SUCCESS;
201 }
202 
203 //------------------------------------------------------------------------------------------------------------------------------------------
204 //------------------------------------------------------------------------------------------------------------------------------------------
205 
207 {
208 }
209 
210 //------------------------------------------------------------------------------------------------------------------------------------------
211 
213  LArMvaHelper::MvaFeatureVector &featureVector, const Algorithm *const pAlgorithm, const pandora::Cluster *const pCluster)
214 {
215  if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
216  std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
217 
218  float straightLineLength(-1.f), ratio(-1.f);
219  try
220  {
221  const TwoDSlidingFitResult slidingFitResultLarge(pCluster, m_slidingLinearFitWindow, LArGeometryHelper::GetWireZPitch(this->GetPandora()));
222  straightLineLength = (slidingFitResultLarge.GetGlobalMaxLayerPosition() - slidingFitResultLarge.GetGlobalMinLayerPosition()).GetMagnitude();
223  if (straightLineLength > std::numeric_limits<float>::epsilon())
224  ratio = (CutClusterCharacterisationAlgorithm::GetVertexDistance(pAlgorithm, pCluster)) / straightLineLength;
225  }
226  catch (const StatusCodeException &)
227  {
228  ratio = -1.f;
229  }
230  featureVector.push_back(ratio);
231 }
232 
233 //------------------------------------------------------------------------------------------------------------------------------------------
234 
235 StatusCode TwoDVertexDistanceFeatureTool::ReadSettings(const TiXmlHandle xmlHandle)
236 {
237  PANDORA_RETURN_RESULT_IF_AND_IF(
238  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "SlidingLinearFitWindow", m_slidingLinearFitWindow));
239 
240  return STATUS_CODE_SUCCESS;
241 }
242 
243 //------------------------------------------------------------------------------------------------------------------------------------------
244 //------------------------------------------------------------------------------------------------------------------------------------------
245 
247 {
248 }
249 
250 //------------------------------------------------------------------------------------------------------------------------------------------
251 
253  LArMvaHelper::MvaFeatureVector &featureVector, const Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pInputPfo)
254 {
255  if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
256  std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
257 
258  CaloHitList parent3DHitList;
259  LArPfoHelper::GetCaloHits(pInputPfo, TPC_3D, parent3DHitList);
260  const unsigned int nParentHits3D(parent3DHitList.size());
261 
262  PfoList allDaughtersPfoList;
263  LArPfoHelper::GetAllDownstreamPfos(pInputPfo, allDaughtersPfoList);
264  const unsigned int nDaughterPfos(allDaughtersPfoList.empty() ? 0 : allDaughtersPfoList.size() - 1);
265 
266  unsigned int nDaughterHits3DTotal(0);
267 
268  if (nDaughterPfos > 0)
269  {
270  // ATTN This relies on knowing that the first pfo in allDaughtersPfoList is the input pfo
271  allDaughtersPfoList.pop_front();
272 
273  for (const ParticleFlowObject *const pDaughterPfo : allDaughtersPfoList)
274  {
275  CaloHitList daughter3DHitList;
276  LArPfoHelper::GetCaloHits(pDaughterPfo, TPC_3D, daughter3DHitList);
277  nDaughterHits3DTotal += daughter3DHitList.size();
278  }
279  }
280 
281  const LArMvaHelper::MvaFeature nDaughters(static_cast<double>(nDaughterPfos));
282  const LArMvaHelper::MvaFeature nDaughterHits3D(static_cast<double>(nDaughterHits3DTotal));
283  const LArMvaHelper::MvaFeature daughterParentNHitsRatio(
284  (nParentHits3D > 0) ? static_cast<double>(nDaughterHits3DTotal) / static_cast<double>(nParentHits3D) : 0.);
285 
286  featureVector.push_back(nDaughters);
287  featureVector.push_back(nDaughterHits3D);
288  featureVector.push_back(daughterParentNHitsRatio);
289 }
290 
291 //------------------------------------------------------------------------------------------------------------------------------------------
292 
293 StatusCode PfoHierarchyFeatureTool::ReadSettings(const TiXmlHandle /*xmlHandle*/)
294 {
295  return STATUS_CODE_SUCCESS;
296 }
297 
298 //------------------------------------------------------------------------------------------------------------------------------------------
299 //------------------------------------------------------------------------------------------------------------------------------------------
300 
302 {
303 }
304 
305 //------------------------------------------------------------------------------------------------------------------------------------------
306 
308  LArMvaHelper::MvaFeatureVector &featureVector, const Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pInputPfo)
309 {
310  if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
311  std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
312 
313  ClusterList clusterList;
314  LArPfoHelper::GetTwoDClusterList(pInputPfo, clusterList);
315  float diffWithStraightLineMean(0.f), maxFitGapLength(0.f), rmsSlidingLinearFit(0.f);
316  LArMvaHelper::MvaFeature length, diff, gap, rms;
317  unsigned int nClustersUsed(0);
318 
319  for (const Cluster *const pCluster : clusterList)
320  {
321  float straightLineLengthLargeCluster(-1.f), diffWithStraightLineMeanCluster(-1.f), maxFitGapLengthCluster(-1.f),
322  rmsSlidingLinearFitCluster(-1.f);
323 
325  pCluster, straightLineLengthLargeCluster, diffWithStraightLineMeanCluster, maxFitGapLengthCluster, rmsSlidingLinearFitCluster);
326 
327  if (straightLineLengthLargeCluster > std::numeric_limits<float>::epsilon())
328  {
329  diffWithStraightLineMeanCluster /= straightLineLengthLargeCluster;
330  maxFitGapLengthCluster /= straightLineLengthLargeCluster;
331  rmsSlidingLinearFitCluster /= straightLineLengthLargeCluster;
332 
333  diffWithStraightLineMean += diffWithStraightLineMeanCluster;
334  maxFitGapLength += maxFitGapLengthCluster;
335  rmsSlidingLinearFit += rmsSlidingLinearFitCluster;
336 
337  ++nClustersUsed;
338  }
339  }
340 
341  if (nClustersUsed > 0)
342  {
343  const float nClusters(static_cast<float>(nClustersUsed));
344  length = std::sqrt(LArPfoHelper::GetThreeDLengthSquared(pInputPfo));
345  diff = diffWithStraightLineMean / nClusters;
346  gap = maxFitGapLength / nClusters;
347  rms = rmsSlidingLinearFit / nClusters;
348  }
349 
350  featureVector.push_back(length);
351  featureVector.push_back(diff);
352  featureVector.push_back(gap);
353  featureVector.push_back(rms);
354 }
355 
356 //------------------------------------------------------------------------------------------------------------------------------------------
357 
358 void ThreeDLinearFitFeatureTool::CalculateVariablesSlidingLinearFit(const pandora::Cluster *const pCluster, float &straightLineLengthLarge,
359  float &diffWithStraightLineMean, float &maxFitGapLength, float &rmsSlidingLinearFit) const
360 {
361  try
362  {
363  const TwoDSlidingFitResult slidingFitResult(pCluster, m_slidingLinearFitWindow, LArGeometryHelper::GetWireZPitch(this->GetPandora()));
364  const TwoDSlidingFitResult slidingFitResultLarge(
365  pCluster, m_slidingLinearFitWindowLarge, LArGeometryHelper::GetWireZPitch(this->GetPandora()));
366 
367  if (slidingFitResult.GetLayerFitResultMap().empty())
368  throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
369 
370  straightLineLengthLarge =
371  (slidingFitResultLarge.GetGlobalMaxLayerPosition() - slidingFitResultLarge.GetGlobalMinLayerPosition()).GetMagnitude();
372  rmsSlidingLinearFit = 0.f;
373 
374  FloatVector diffWithStraightLineVector;
375  const HitType hitType(LArClusterHelper::GetClusterHitType(pCluster));
376  CartesianVector previousFitPosition(slidingFitResult.GetGlobalMinLayerPosition());
378 
379  for (const auto &mapEntry : slidingFitResult.GetLayerFitResultMap())
380  {
381  const LayerFitResult &layerFitResult(mapEntry.second);
382  rmsSlidingLinearFit += layerFitResult.GetRms();
383 
384  CartesianVector thisFitPosition(0.f, 0.f, 0.f);
385  slidingFitResult.GetGlobalPosition(layerFitResult.GetL(), layerFitResult.GetFitT(), thisFitPosition);
386 
388  slidingFitResultLarge.GetLayerFitResultMap().find(slidingFitResultLarge.GetLayer(layerFitResult.GetL()));
389 
390  if (slidingFitResultLarge.GetLayerFitResultMap().end() == iterLarge)
391  throw StatusCodeException(STATUS_CODE_FAILURE);
392 
393  diffWithStraightLineVector.push_back(static_cast<float>(std::fabs(layerFitResult.GetFitT() - iterLarge->second.GetFitT())));
394 
395  const float thisGapLength((thisFitPosition - previousFitPosition).GetMagnitude());
396  const float minZ(std::min(thisFitPosition.GetZ(), previousFitPosition.GetZ()));
397  const float maxZ(std::max(thisFitPosition.GetZ(), previousFitPosition.GetZ()));
398 
399  if ((maxZ - minZ) > std::numeric_limits<float>::epsilon())
400  {
401  const float gapZ(LArGeometryHelper::CalculateGapDeltaZ(this->GetPandora(), minZ, maxZ, hitType));
402  const float correctedGapLength(thisGapLength * (1.f - gapZ / (maxZ - minZ)));
403 
404  if (correctedGapLength > maxFitGapLength)
405  maxFitGapLength = correctedGapLength;
406  }
407  else
408  {
409  maxFitGapLength = 0.f;
410  }
411 
412  dTdLMin = std::min(dTdLMin, static_cast<float>(layerFitResult.GetGradient()));
413  dTdLMax = std::max(dTdLMax, static_cast<float>(layerFitResult.GetGradient()));
414  previousFitPosition = thisFitPosition;
415  }
416 
417  if (diffWithStraightLineVector.empty())
418  throw StatusCodeException(STATUS_CODE_FAILURE);
419 
420  diffWithStraightLineMean = 0.f;
421 
422  for (const float diffWithStraightLine : diffWithStraightLineVector)
423  diffWithStraightLineMean += diffWithStraightLine;
424 
425  diffWithStraightLineMean /= static_cast<float>(diffWithStraightLineVector.size());
426  }
427  catch (const StatusCodeException &)
428  {
429  straightLineLengthLarge = -1.f;
430  diffWithStraightLineMean = -1.f;
431  maxFitGapLength = -1.f;
432  rmsSlidingLinearFit = -1.f;
433  }
434 }
435 
436 //------------------------------------------------------------------------------------------------------------------------------------------
437 
438 StatusCode ThreeDLinearFitFeatureTool::ReadSettings(const TiXmlHandle xmlHandle)
439 {
440  PANDORA_RETURN_RESULT_IF_AND_IF(
441  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "SlidingLinearFitWindow", m_slidingLinearFitWindow));
442 
443  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
444  XmlHelper::ReadValue(xmlHandle, "SlidingLinearFitWindowLarge", m_slidingLinearFitWindowLarge));
445 
446  return STATUS_CODE_SUCCESS;
447 }
448 
449 //------------------------------------------------------------------------------------------------------------------------------------------
450 //------------------------------------------------------------------------------------------------------------------------------------------
451 
453 {
454 }
455 
456 //------------------------------------------------------------------------------------------------------------------------------------------
457 
459  LArMvaHelper::MvaFeatureVector &featureVector, const Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pInputPfo)
460 {
461  if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
462  std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
463 
464  LArMvaHelper::MvaFeature vertexDistance;
465 
466  const VertexList *pVertexList(nullptr);
467  (void)PandoraContentApi::GetCurrentList(*pAlgorithm, pVertexList);
468 
469  if (!pVertexList || pVertexList->empty())
470  {
471  featureVector.push_back(vertexDistance);
472  return;
473  }
474 
475  unsigned int nInteractionVertices(0);
476  const Vertex *pInteractionVertex(nullptr);
477 
478  for (const Vertex *pVertex : *pVertexList)
479  {
480  if ((pVertex->GetVertexLabel() == VERTEX_INTERACTION) && (pVertex->GetVertexType() == VERTEX_3D))
481  {
482  ++nInteractionVertices;
483  pInteractionVertex = pVertex;
484  }
485  }
486 
487  if (pInteractionVertex && (1 == nInteractionVertices))
488  {
489  try
490  {
491  vertexDistance = (pInteractionVertex->GetPosition() - LArPfoHelper::GetVertex(pInputPfo)->GetPosition()).GetMagnitude();
492  }
493  catch (const StatusCodeException &)
494  {
495  CaloHitList threeDCaloHitList;
496  LArPfoHelper::GetCaloHits(pInputPfo, TPC_3D, threeDCaloHitList);
497 
498  if (!threeDCaloHitList.empty())
499  vertexDistance = (pInteractionVertex->GetPosition() - (threeDCaloHitList.front())->GetPositionVector()).GetMagnitude();
500  }
501  }
502 
503  featureVector.push_back(vertexDistance);
504 }
505 
506 //------------------------------------------------------------------------------------------------------------------------------------------
507 
508 StatusCode ThreeDVertexDistanceFeatureTool::ReadSettings(const TiXmlHandle /*xmlHandle*/)
509 {
510  return STATUS_CODE_SUCCESS;
511 }
512 
513 //------------------------------------------------------------------------------------------------------------------------------------------
514 //------------------------------------------------------------------------------------------------------------------------------------------
515 
516 ThreeDOpeningAngleFeatureTool::ThreeDOpeningAngleFeatureTool() : m_hitFraction(0.5f), m_defaultValue(0.1f)
517 {
518 }
519 
520 //------------------------------------------------------------------------------------------------------------------------------------------
521 
523  LArMvaHelper::MvaFeatureVector &featureVector, const Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pInputPfo)
524 {
525  if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
526  std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
527 
528  // Need the 3D hits to calculate PCA components
529  CaloHitList threeDCaloHitList;
530  LArPfoHelper::GetCaloHits(pInputPfo, TPC_3D, threeDCaloHitList);
531 
532  LArMvaHelper::MvaFeature diffAngle;
533  if (!threeDCaloHitList.empty())
534  {
535  CartesianPointVector pointVectorStart, pointVectorEnd;
536  this->Divide3DCaloHitList(pAlgorithm, threeDCaloHitList, pointVectorStart, pointVectorEnd);
537 
538  // Able to calculate angles only if > 1 point provided
539  if ((pointVectorStart.size() > 1) && (pointVectorEnd.size() > 1))
540  {
541  try
542  {
543  // Run the PCA analysis twice
544  CartesianVector centroidStart(0.f, 0.f, 0.f), centroidEnd(0.f, 0.f, 0.f);
545  LArPcaHelper::EigenVectors eigenVecsStart, eigenVecsEnd;
546  LArPcaHelper::EigenValues eigenValuesStart(0.f, 0.f, 0.f), eigenValuesEnd(0.f, 0.f, 0.f);
547 
548  LArPcaHelper::RunPca(pointVectorStart, centroidStart, eigenValuesStart, eigenVecsStart);
549  LArPcaHelper::RunPca(pointVectorEnd, centroidEnd, eigenValuesEnd, eigenVecsEnd);
550 
551  const float openingAngle(this->OpeningAngle(eigenVecsStart.at(0), eigenVecsStart.at(1), eigenValuesStart));
552  const float closingAngle(this->OpeningAngle(eigenVecsEnd.at(0), eigenVecsEnd.at(1), eigenValuesEnd));
553  diffAngle = std::fabs(openingAngle - closingAngle);
554  }
555  catch (const StatusCodeException &)
556  {
557  }
558  }
559  else
560  {
561  diffAngle = m_defaultValue;
562  }
563  }
564 
565  featureVector.push_back(diffAngle);
566 }
567 
568 //------------------------------------------------------------------------------------------------------------------------------------------
569 
570 void ThreeDOpeningAngleFeatureTool::Divide3DCaloHitList(const Algorithm *const pAlgorithm, const CaloHitList &threeDCaloHitList,
571  CartesianPointVector &pointVectorStart, CartesianPointVector &pointVectorEnd)
572 {
573  const VertexList *pVertexList(nullptr);
574  (void)PandoraContentApi::GetCurrentList(*pAlgorithm, pVertexList);
575 
576  if (threeDCaloHitList.empty() || !pVertexList || pVertexList->empty())
577  return;
578 
579  unsigned int nInteractionVertices(0);
580  const Vertex *pInteractionVertex(nullptr);
581 
582  for (const Vertex *pVertex : *pVertexList)
583  {
584  if ((pVertex->GetVertexLabel() == VERTEX_INTERACTION) && (pVertex->GetVertexType() == VERTEX_3D))
585  {
586  ++nInteractionVertices;
587  pInteractionVertex = pVertex;
588  }
589  }
590 
591  if (pInteractionVertex && (1 == nInteractionVertices))
592  {
593  // Order by distance to vertex, so first ones are closer to nuvertex
594  CaloHitVector threeDCaloHitVector(threeDCaloHitList.begin(), threeDCaloHitList.end());
595  std::sort(threeDCaloHitVector.begin(), threeDCaloHitVector.end(),
596  ThreeDChargeFeatureTool::VertexComparator(pInteractionVertex->GetPosition()));
597 
598  unsigned int iHit(1);
599  const unsigned int nHits(threeDCaloHitVector.size());
600 
601  for (const CaloHit *const pCaloHit : threeDCaloHitVector)
602  {
603  if (static_cast<float>(iHit) / static_cast<float>(nHits) <= m_hitFraction)
604  pointVectorStart.push_back(pCaloHit->GetPositionVector());
605 
606  if (static_cast<float>(iHit) / static_cast<float>(nHits) >= 1.f - m_hitFraction)
607  pointVectorEnd.push_back(pCaloHit->GetPositionVector());
608 
609  ++iHit;
610  }
611  }
612 }
613 
614 //------------------------------------------------------------------------------------------------------------------------------------------
615 
616 float ThreeDOpeningAngleFeatureTool::OpeningAngle(const CartesianVector &principal, const CartesianVector &secondary, const CartesianVector &eigenValues) const
617 {
618  const float principalMagnitude(principal.GetMagnitude());
619  const float secondaryMagnitude(secondary.GetMagnitude());
620 
621  if (std::fabs(principalMagnitude) < std::numeric_limits<float>::epsilon())
622  {
623  std::cout << "ThreeDOpeningAngleFeatureTool::OpeningAngle - The principal eigenvector is 0." << std::endl;
624  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
625  }
626  else if (std::fabs(secondaryMagnitude) < std::numeric_limits<float>::epsilon())
627  {
628  return 0.f;
629  }
630 
631  const float cosTheta(principal.GetDotProduct(secondary) / (principalMagnitude * secondaryMagnitude));
632 
633  if (cosTheta > 1.f)
634  {
635  std::cout << "PcaShowerParticleBuildingAlgorithm::OpeningAngle - cos(theta) reportedly greater than 1." << std::endl;
636  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
637  }
638 
639  const float sinTheta(std::sqrt(1.f - cosTheta * cosTheta));
640 
641  if (eigenValues.GetX() < std::numeric_limits<float>::epsilon())
642  {
643  std::cout << "PcaShowerParticleBuildingAlgorithm::OpeningAngle - principal eigenvalue less than or equal to 0." << std::endl;
644  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
645  }
646  else if (eigenValues.GetY() < std::numeric_limits<float>::epsilon())
647  {
648  return 0.f;
649  }
650 
651  return std::atan(std::sqrt(eigenValues.GetY()) * sinTheta / std::sqrt(eigenValues.GetX()));
652 }
653 
654 //------------------------------------------------------------------------------------------------------------------------------------------
655 
656 StatusCode ThreeDOpeningAngleFeatureTool::ReadSettings(const TiXmlHandle xmlHandle)
657 {
658  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "HitFraction", m_hitFraction));
659 
660  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "DefaultValue", m_defaultValue));
661 
662  return STATUS_CODE_SUCCESS;
663 }
664 
665 //------------------------------------------------------------------------------------------------------------------------------------------
666 //------------------------------------------------------------------------------------------------------------------------------------------
667 
669 {
670 }
671 
672 //------------------------------------------------------------------------------------------------------------------------------------------
673 
675  LArMvaHelper::MvaFeatureVector &featureVector, const Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pInputPfo)
676 {
677  if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
678  std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
679 
680  LArMvaHelper::MvaFeature pca1, pca2;
681 
682  // Need the 3D hits to calculate PCA components
683  CaloHitList threeDCaloHitList;
684  LArPfoHelper::GetCaloHits(pInputPfo, TPC_3D, threeDCaloHitList);
685 
686  if (!threeDCaloHitList.empty())
687  {
688  try
689  {
690  CartesianVector centroid(0.f, 0.f, 0.f);
691  LArPcaHelper::EigenVectors eigenVecs;
692  LArPcaHelper::EigenValues eigenValues(0.f, 0.f, 0.f);
693 
694  LArPcaHelper::RunPca(threeDCaloHitList, centroid, eigenValues, eigenVecs);
695  const float principalEigenvalue(eigenValues.GetX()), secondaryEigenvalue(eigenValues.GetY()), tertiaryEigenvalue(eigenValues.GetZ());
696 
697  if (principalEigenvalue > std::numeric_limits<float>::epsilon())
698  {
699  pca1 = secondaryEigenvalue / principalEigenvalue;
700  pca2 = tertiaryEigenvalue / principalEigenvalue;
701  }
702  else
703  {
704  // ATTN if n3dHits == 1 then principal, secondary, and tertiary eigenvalues are zero hence default to zero
705  pca1 = 0.;
706  pca2 = 0.;
707  }
708  }
709  catch (const StatusCodeException &)
710  {
711  }
712  }
713 
714  featureVector.push_back(pca1);
715  featureVector.push_back(pca2);
716 }
717 
718 //------------------------------------------------------------------------------------------------------------------------------------------
719 
720 StatusCode ThreeDPCAFeatureTool::ReadSettings(const TiXmlHandle /*xmlHandle*/)
721 {
722  return STATUS_CODE_SUCCESS;
723 }
724 
725 //------------------------------------------------------------------------------------------------------------------------------------------
726 //------------------------------------------------------------------------------------------------------------------------------------------
727 
729 {
730 }
731 
732 //------------------------------------------------------------------------------------------------------------------------------------------
733 
735  LArMvaHelper::MvaFeatureVector &featureVector, const Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pInputPfo)
736 {
737  if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
738  std::cout << "----> Running Algorithm Tool: " << this->GetInstanceName() << ", " << this->GetType() << std::endl;
739 
740  float totalCharge(-1.f), chargeSigma(-1.f), chargeMean(-1.f), endCharge(-1.f);
741  LArMvaHelper::MvaFeature charge1, charge2;
742 
743  ClusterList clusterListW;
744  LArPfoHelper::GetClusters(pInputPfo, TPC_VIEW_W, clusterListW);
745 
746  if (!clusterListW.empty())
747  this->CalculateChargeVariables(pAlgorithm, clusterListW.front(), totalCharge, chargeSigma, chargeMean, endCharge);
748 
749  if (chargeMean > std::numeric_limits<float>::epsilon())
750  charge1 = chargeSigma / chargeMean;
751 
752  if (totalCharge > std::numeric_limits<float>::epsilon())
753  charge2 = endCharge / totalCharge;
754 
755  featureVector.push_back(charge1);
756  featureVector.push_back(charge2);
757 }
758 
759 //------------------------------------------------------------------------------------------------------------------------------------------
760 
761 void ThreeDChargeFeatureTool::CalculateChargeVariables(const Algorithm *const pAlgorithm, const pandora::Cluster *const pCluster,
762  float &totalCharge, float &chargeSigma, float &chargeMean, float &endCharge)
763 {
764  totalCharge = 0.f;
765  chargeSigma = 0.f;
766  chargeMean = 0.f;
767  endCharge = 0.f;
768 
769  CaloHitList orderedCaloHitList;
770  this->OrderCaloHitsByDistanceToVertex(pAlgorithm, pCluster, orderedCaloHitList);
771 
772  FloatVector chargeVector;
773  unsigned int hitCounter(0);
774  const unsigned int nTotalHits(orderedCaloHitList.size());
775 
776  for (const CaloHit *const pCaloHit : orderedCaloHitList)
777  {
778  ++hitCounter;
779  const float pCaloHitCharge(pCaloHit->GetInputEnergy());
780 
781  if (pCaloHitCharge >= 0.f)
782  {
783  totalCharge += pCaloHitCharge;
784  chargeVector.push_back(pCaloHitCharge);
785 
786  if (hitCounter >= std::floor(static_cast<float>(nTotalHits) * (1.f - m_endChargeFraction)))
787  endCharge += pCaloHitCharge;
788  }
789  }
790 
791  if (!chargeVector.empty())
792  {
793  chargeMean = totalCharge / static_cast<float>(chargeVector.size());
794 
795  for (const float charge : chargeVector)
796  chargeSigma += (charge - chargeMean) * (charge - chargeMean);
797 
798  chargeSigma = std::sqrt(chargeSigma / static_cast<float>(chargeVector.size()));
799  }
800 }
801 
802 //------------------------------------------------------------------------------------------------------------------------------------------
803 
805  const Algorithm *const pAlgorithm, const pandora::Cluster *const pCluster, CaloHitList &caloHitList)
806 {
807  const VertexList *pVertexList(nullptr);
808  (void)PandoraContentApi::GetCurrentList(*pAlgorithm, pVertexList);
809 
810  if (!pVertexList || pVertexList->empty())
811  return;
812 
813  unsigned int nInteractionVertices(0);
814  const Vertex *pInteractionVertex(nullptr);
815 
816  for (const Vertex *pVertex : *pVertexList)
817  {
818  if ((pVertex->GetVertexLabel() == VERTEX_INTERACTION) && (pVertex->GetVertexType() == VERTEX_3D))
819  {
820  ++nInteractionVertices;
821  pInteractionVertex = pVertex;
822  }
823  }
824 
825  if (pInteractionVertex && (1 == nInteractionVertices))
826  {
827  const HitType hitType(LArClusterHelper::GetClusterHitType(pCluster));
828  const CartesianVector vertexPosition2D(LArGeometryHelper::ProjectPosition(pAlgorithm->GetPandora(), pInteractionVertex->GetPosition(), hitType));
829 
830  CaloHitList clusterCaloHitList;
831  pCluster->GetOrderedCaloHitList().FillCaloHitList(clusterCaloHitList);
832 
833  clusterCaloHitList.sort(ThreeDChargeFeatureTool::VertexComparator(vertexPosition2D));
834  caloHitList.insert(caloHitList.end(), clusterCaloHitList.begin(), clusterCaloHitList.end());
835  }
836 }
837 
838 //------------------------------------------------------------------------------------------------------------------------------------------
839 
840 StatusCode ThreeDChargeFeatureTool::ReadSettings(const TiXmlHandle xmlHandle)
841 {
842  PANDORA_RETURN_RESULT_IF_AND_IF(
843  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "EndChargeFraction", m_endChargeFraction));
844 
845  return STATUS_CODE_SUCCESS;
846 }
847 
848 //------------------------------------------------------------------------------------------------------------------------------------------
849 //------------------------------------------------------------------------------------------------------------------------------------------
850 
851 ThreeDChargeFeatureTool::VertexComparator::VertexComparator(const CartesianVector vertexPosition2D) : m_neutrinoVertex(vertexPosition2D)
852 {
853 }
854 
855 //------------------------------------------------------------------------------------------------------------------------------------------
856 
857 bool ThreeDChargeFeatureTool::VertexComparator::operator()(const CaloHit *const left, const CaloHit *const right) const
858 {
859  const float distanceL((left->GetPositionVector() - m_neutrinoVertex).GetMagnitudeSquared());
860  const float distanceR((right->GetPositionVector() - m_neutrinoVertex).GetMagnitudeSquared());
861  return distanceL < distanceR;
862 }
863 
864 } // namespace lar_content
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
void OrderCaloHitsByDistanceToVertex(const pandora::Algorithm *const pAlgorithm, const pandora::Cluster *const pCluster, pandora::CaloHitList &caloHitList)
Function to order the calo hit list by distance to neutrino vertex.
Header file for the pfo helper class.
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pInputPfo)
Header file for the cut based cluster characterisation algorithm class.
MvaTypes::MvaFeatureVector MvaFeatureVector
Definition: LArMvaHelper.h:58
float m_hitFraction
Fraction of hits in start and end of pfo.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
double rms(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:40
static void GetClusters(const pandora::PfoList &pfoList, const pandora::HitType &hitType, pandora::ClusterList &clusterList)
Get a list of clusters of a particular hit type from a list of pfos.
enum cvn::HType HitType
static void GetTwoDClusterList(const pandora::ParticleFlowObject *const pPfo, pandora::ClusterList &clusterList)
Get the list of 2D clusters from an input pfo.
pandora::CartesianVector EigenValues
Definition: LArPcaHelper.h:24
static float GetThreeDLengthSquared(const pandora::ParticleFlowObject *const pPfo)
Calculate length of Pfo using 3D clusters.
static float CalculateGapDeltaZ(const pandora::Pandora &pandora, const float minZ, const float maxZ, const pandora::HitType hitType)
Calculate the total distance within a given 2D region that is composed of detector gaps...
static const pandora::Vertex * GetVertex(const pandora::ParticleFlowObject *const pPfo)
Get the pfo vertex.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
static float GetVertexDistance(const pandora::Algorithm *const pAlgorithm, const pandora::Cluster *const pCluster)
Get the distance between the interaction vertex (if present in the current vertex list) and a provide...
static pandora::CartesianVector ProjectPosition(const pandora::Pandora &pandora, const pandora::CartesianVector &position3D, const pandora::HitType view)
Project 3D position into a given 2D view.
unsigned int m_slidingShowerFitWindow
The sliding shower fit window.
Header file for the principal curve analysis helper class.
intermediate_table::const_iterator const_iterator
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
void CalculateVariablesSlidingLinearFit(const pandora::Cluster *const pCluster, float &straightLineLengthLarge, float &diffWithStraigthLineMean, float &maxFitGapLength, float &rmsSlidingLinearFit) const
Calculation of several variables related to sliding linear fit.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::Cluster *const pCluster)
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pInputPfo)
unsigned int m_slidingLinearFitWindow
The sliding linear fit window.
Header file for the geometry helper class.
Header file for the track shower id feature tools.
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pInputPfo)
unsigned int m_slidingLinearFitWindow
The sliding linear fit window.
bool operator()(const pandora::CaloHit *const left, const pandora::CaloHit *const right) const
operator <
double GetFitT() const
Get the fitted t coordinate.
InitializedDouble class used to define mva features.
unsigned int m_slidingLinearFitWindowLarge
The sliding linear fit window - should be large, providing a simple linear fit.
Header file for the cluster helper class.
float OpeningAngle(const pandora::CartesianVector &principal, const pandora::CartesianVector &secondary, const pandora::CartesianVector &eigenValues) const
Use the results of principal component analysis to calculate an opening angle.
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pInputPfo)
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pInputPfo)
Header file for the lar two dimensional sliding fit result class.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
unsigned int m_slidingLinearFitWindow
The sliding linear fit window.
pandora::CartesianVector GetGlobalMinLayerPosition() const
Get global position corresponding to the fit result in minimum fit layer.
static int max(int a, int b)
double GetGradient() const
Get the fitted gradient dt/dz.
const LayerFitResultMap & GetLayerFitResultMap() const
Get the layer fit result map.
VertexComparator class for comparison of two points wrt neutrino vertex position. ...
double GetRms() const
Get the rms of the fit residuals.
static void RunPca(const T &t, pandora::CartesianVector &centroid, EigenValues &outputEigenValues, EigenVectors &outputEigenVectors)
Run principal component analysis using input calo hits (TPC_VIEW_U,V,W or TPC_3D; all treated as 3D p...
VertexComparator(const pandora::CartesianVector vertexPosition2D)
Constructor.
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
std::vector< pandora::CartesianVector > EigenVectors
Definition: LArPcaHelper.h:25
static void GetAllDownstreamPfos(const pandora::PfoList &inputPfoList, pandora::PfoList &outputPfoList)
Get a flat list of all pfos, recursively, of all daughters associated with those pfos in an input lis...
void GetGlobalPosition(const float rL, const float rT, pandora::CartesianVector &position) const
Get global coordinates for given sliding linear fit coordinates.
unsigned int m_slidingLinearFitWindowLarge
The sliding linear fit window - should be large, providing a simple linear fit.
float m_defaultValue
Default value to return, in case calculation not feasible.
void CalculateChargeVariables(const pandora::Algorithm *const pAlgorithm, const pandora::Cluster *const pCluster, float &totalCharge, float &chargeSigma, float &chargeMean, float &endCharge)
Calculation of the charge variables.
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::ParticleFlowObject *const pInputPfo)
void Divide3DCaloHitList(const pandora::Algorithm *const pAlgorithm, const pandora::CaloHitList &threeDCaloHitList, pandora::CartesianPointVector &pointVectorStart, pandora::CartesianPointVector &pointVectorEnd)
Obtain positions at the vertex and non-vertex end of a list of three dimensional calo hits...
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
Definition: ModuleGraph.h:25
Dft::FloatVector FloatVector
float m_endChargeFraction
Fraction of hits that will be considered to calculate end charge (default 10%)
double GetL() const
Get the l coordinate.
static float GetShowerFitWidth(const pandora::Algorithm *const pAlgorithm, const pandora::Cluster *const pCluster, const unsigned int showerFitWindow)
Get a measure of the width of a cluster, using a sliding shower fit result.
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::Cluster *const pCluster)
unsigned int m_slidingLinearFitWindow
The sliding linear fit window.
void CalculateVariablesSlidingLinearFit(const pandora::Cluster *const pCluster, float &straightLineLengthLarge, float &diffWithStraigthLineMean, float &diffWithStraightLineSigma, float &dTdLWidth, float &maxFitGapLength, float &rmsSlidingLinearFit) const
Calculation of several variables related to sliding linear fit.
static void GetCaloHits(const pandora::PfoList &pfoList, const pandora::HitType &hitType, pandora::CaloHitList &caloHitList)
Get a list of calo hits of a particular hit type from a list of pfos.
std::list< Vertex > VertexList
Definition: DCEL.h:182
pandora::CartesianVector GetGlobalMaxLayerPosition() const
Get global position corresponding to the fit result in maximum fit layer.
int GetLayer(const float rL) const
Get layer number for given sliding linear fit longitudinal coordinate.
QTextStream & endl(QTextStream &s)
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const pandora::Algorithm *const pAlgorithm, const pandora::Cluster *const pCluster)
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)