LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
SimplePCAThreeDClusteringTool.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
10 
14 
15 using namespace pandora;
16 
17 namespace lar_content
18 {
19 
20 SimplePCAThreeDClusteringTool::SimplePCAThreeDClusteringTool()
21 {
22 }
23 
24 //------------------------------------------------------------------------------------------------------------------------------------------
25 
26 bool SimplePCAThreeDClusteringTool::Run(const CaloHitList &inputCaloHitList, std::vector<CaloHitList> &outputCaloHitListsVector)
27 {
28  // Begin with a PCA
29  CartesianVector centroid(0.f, 0.f, 0.f);
31  LArPcaHelper::EigenValues eigenValues(0.f, 0.f, 0.f);
32  LArPcaHelper::RunPca(inputCaloHitList, centroid, eigenValues, eigenVecs);
33 
34  // By convention, the primary axis has a positive z-component - define ortho directions
35  const CartesianVector orthoDirection1(eigenVecs.at(1).GetZ() > 0.f ? eigenVecs.at(1) : eigenVecs.at(1) * -1.f);
36 
37  //Lists for hits that have a positive and negative projection on the secondary axis
38  CaloHitList posCaloHitList, negCaloHitList;
39 
40  for (const CaloHit *const pCaloHit3D : inputCaloHitList)
41  {
42  const CartesianVector pCaloHit3DPosition{pCaloHit3D->GetPositionVector()};
43 
44  if ((pCaloHit3DPosition - centroid).GetDotProduct(orthoDirection1) < 0)
45  {
46  negCaloHitList.push_back(pCaloHit3D);
47  }
48  else
49  {
50  posCaloHitList.push_back(pCaloHit3D);
51  }
52  }
53 
54  outputCaloHitListsVector.push_back(posCaloHitList);
55  outputCaloHitListsVector.push_back(negCaloHitList);
56 
57  //Now, run PCA independently on pos and neg hit lists, to refine split
58 
59  //Get pos list PCA
60  CartesianVector centroidPos(0.f, 0.f, 0.f);
61  LArPcaHelper::EigenVectors eigenVecsPos;
62  LArPcaHelper::EigenValues eigenValuesPos(0.f, 0.f, 0.f);
63  LArPcaHelper::RunPca(posCaloHitList, centroidPos, eigenValuesPos, eigenVecsPos);
64 
65  // By convention, the primary axis has a positive z-component.
66  const CartesianVector axisDirectionPos(eigenVecsPos.at(0).GetZ() > 0.f ? eigenVecsPos.at(0) : eigenVecsPos.at(0) * -1.f);
67 
68  //Get neg list PCA
69  CartesianVector centroidNeg(0.f, 0.f, 0.f);
70  LArPcaHelper::EigenVectors eigenVecsNeg;
71  LArPcaHelper::EigenValues eigenValuesNeg(0.f, 0.f, 0.f);
72  LArPcaHelper::RunPca(negCaloHitList, centroidNeg, eigenValuesNeg, eigenVecsNeg);
73 
74  // By convention, the primary axis has a positive z-component.
75  const CartesianVector axisDirectionNeg(eigenVecsNeg.at(0).GetZ() > 0.f ? eigenVecsNeg.at(0) : eigenVecsNeg.at(0) * -1.f);
76 
77  //Get intersection point of the two new principal axes
78  CartesianVector intersectionPoint(0.f, 0.f, 0.f);
79  float displacementPos(0.f), displacementNeg(0.f);
80 
81  try
82  {
84  centroidPos, axisDirectionPos, centroidNeg, axisDirectionNeg, intersectionPoint, displacementPos, displacementNeg);
85  }
86  catch (const StatusCodeException &)
87  {
88  std::cout << "Exception caught! Cannot get intersection between positive and negative hit lists primary PCA axes!" << std::endl;
89  }
90 
91  //Clear pos and neg lists
92  posCaloHitList.clear();
93  negCaloHitList.clear();
94 
95  //Loop over original hit list, check whether it is within smaller cone of pos or neg axis, attach to relevant list
96  for (const CaloHit *const pCaloHit3D : inputCaloHitList)
97  {
98  const float cosConeAxisPos = axisDirectionPos.GetCosOpeningAngle(pCaloHit3D->GetPositionVector() - intersectionPoint);
99  const float cosConeAxisNeg = axisDirectionNeg.GetCosOpeningAngle(pCaloHit3D->GetPositionVector() - intersectionPoint);
100  if (cosConeAxisPos > cosConeAxisNeg)
101  posCaloHitList.push_back(pCaloHit3D);
102  else
103  negCaloHitList.push_back(pCaloHit3D);
104  }
105 
106  return true;
107 }
108 
109 //------------------------------------------------------------------------------------------------------------------------------------------
110 
111 StatusCode SimplePCAThreeDClusteringTool::ReadSettings(const TiXmlHandle /*xmlHandle*/)
112 {
113  return STATUS_CODE_SUCCESS;
114 }
115 
116 } // namespace lar_content
pandora::CartesianVector EigenValues
Definition: LArPcaHelper.h:24
Header file for the principal curve analysis helper class.
std::pair< float, float > GetIntersection(double Ax, double Ay, double Bx, double By, double Cx, double Cy, double Dx, double Dy)
Definition: Polygon2D.cxx:36
TFile f
Definition: plotHisto.C:6
std::vector< pandora::CartesianVector > EigenVectors
Definition: LArPcaHelper.h:25
Header file for the simple PCA-based clustering tool class.