LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
LongitudinalTrackHitsBaseTool.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
10 
12 
15 
16 using namespace pandora;
17 
18 namespace lar_content
19 {
20 
21 LongitudinalTrackHitsBaseTool::LongitudinalTrackHitsBaseTool() :
22  m_vtxDisplacementCutSquared(5.f * 5.f),
23  m_minTrackLengthSquared(7.5f * 7.5f)
24 {
25 }
26 
27 //------------------------------------------------------------------------------------------------------------------------------------------
28 
29 void LongitudinalTrackHitsBaseTool::GetTrackHits3D(const CaloHitVector &inputTwoDHits, const MatchedSlidingFitMap &inputSlidingFitMap,
30  ProtoHitVector &protoHitVector) const
31 {
32  MatchedSlidingFitMap matchedSlidingFitMap;
33  CartesianVector vtx3D(0.f, 0.f, 0.f), end3D(0.f, 0.f, 0.f);
34  this->GetVertexAndEndPositions(inputSlidingFitMap, matchedSlidingFitMap, vtx3D, end3D);
35 
36  for (const CaloHit *const pCaloHit2D : inputTwoDHits)
37  {
38  try
39  {
40  ProtoHit protoHit(pCaloHit2D);
41  this->GetLongitudinalTrackHit3D(matchedSlidingFitMap, vtx3D, end3D, protoHit);
42 
43  if (protoHit.IsPositionSet() && (protoHit.GetChi2() < m_chiSquaredCut))
44  protoHitVector.push_back(protoHit);
45  }
46  catch (StatusCodeException &)
47  {
48  }
49  }
50 }
51 
52 //------------------------------------------------------------------------------------------------------------------------------------------
53 
55  MatchedSlidingFitMap &outputSlidingFitMap, CartesianVector &bestVtx3D, CartesianVector &bestEnd3D) const
56 {
57  // TODO Tidy up: The code below is quite repetitive...
58  MatchedSlidingFitMap::const_iterator iterU = inputSlidingFitMap.find(TPC_VIEW_U);
59  const bool foundU(inputSlidingFitMap.end() != iterU);
60 
61  MatchedSlidingFitMap::const_iterator iterV = inputSlidingFitMap.find(TPC_VIEW_V);
62  const bool foundV(inputSlidingFitMap.end() != iterV);
63 
64  MatchedSlidingFitMap::const_iterator iterW = inputSlidingFitMap.find(TPC_VIEW_W);
65  const bool foundW(inputSlidingFitMap.end() != iterW);
66 
67  bool useU(false), useV(false), useW(false);
68  float bestChi2(std::numeric_limits<float>::max());
69 
70  for (unsigned int iPermutation = 0; iPermutation < 4; ++iPermutation)
71  {
72  const bool isForwardU((1 == iPermutation) ? false : true);
73  const bool isForwardV((2 == iPermutation) ? false : true);
74  const bool isForwardW((3 == iPermutation) ? false : true);
75 
76  CartesianVector vtxU(0.f, 0.f, 0.f), endU(0.f, 0.f, 0.f);
77  CartesianVector vtxV(0.f, 0.f, 0.f), endV(0.f, 0.f, 0.f);
78  CartesianVector vtxW(0.f, 0.f, 0.f), endW(0.f, 0.f, 0.f);
79 
80  if (foundU)
81  {
82  const TwoDSlidingFitResult &slidingFitResultU = iterU->second;
83  vtxU = (isForwardU ? slidingFitResultU.GetGlobalMinLayerPosition() : slidingFitResultU.GetGlobalMaxLayerPosition());
84  endU = (isForwardU ? slidingFitResultU.GetGlobalMaxLayerPosition() : slidingFitResultU.GetGlobalMinLayerPosition());
85  }
86 
87  if (foundV)
88  {
89  const TwoDSlidingFitResult &slidingFitResultV = iterV->second;
90  vtxV = (isForwardV ? slidingFitResultV.GetGlobalMinLayerPosition() : slidingFitResultV.GetGlobalMaxLayerPosition());
91  endV = (isForwardV ? slidingFitResultV.GetGlobalMaxLayerPosition() : slidingFitResultV.GetGlobalMinLayerPosition());
92  }
93 
94  if (foundW)
95  {
96  const TwoDSlidingFitResult &slidingFitResultW = iterW->second;
97  vtxW = (isForwardW ? slidingFitResultW.GetGlobalMinLayerPosition() : slidingFitResultW.GetGlobalMaxLayerPosition());
98  endW = (isForwardW ? slidingFitResultW.GetGlobalMaxLayerPosition() : slidingFitResultW.GetGlobalMinLayerPosition());
99  }
100 
101  CartesianVector vtx3D(0.f, 0.f, 0.f), end3D(0.f, 0.f, 0.f);
103 
104  if (foundU && foundV)
105  {
106  this->UpdateBestPosition(TPC_VIEW_U, TPC_VIEW_V, vtxU, vtxV, vtx3D, vtxChi2);
107  this->UpdateBestPosition(TPC_VIEW_U, TPC_VIEW_V, endU, endV, end3D, endChi2);
108  }
109 
110  if (foundV && foundW)
111  {
112  this->UpdateBestPosition(TPC_VIEW_V, TPC_VIEW_W, vtxV, vtxW, vtx3D, vtxChi2);
113  this->UpdateBestPosition(TPC_VIEW_V, TPC_VIEW_W, endV, endW, end3D, endChi2);
114  }
115 
116  if (foundW && foundU)
117  {
118  this->UpdateBestPosition(TPC_VIEW_W, TPC_VIEW_U, vtxW, vtxU, vtx3D, vtxChi2);
119  this->UpdateBestPosition(TPC_VIEW_W, TPC_VIEW_U, endW, endU, end3D, endChi2);
120  }
121 
122  bool matchedU(false), matchedV(false), matchedW(false);
123  unsigned int matchedViews(0);
124 
125  if (foundU)
126  {
127  const CartesianVector projVtxU(LArGeometryHelper::ProjectPosition(this->GetPandora(), vtx3D, TPC_VIEW_U));
128  const CartesianVector projEndU(LArGeometryHelper::ProjectPosition(this->GetPandora(), end3D, TPC_VIEW_U));
129 
130  if((endU - vtxU).GetMagnitudeSquared() > m_minTrackLengthSquared &&
131  (projVtxU - vtxU).GetMagnitudeSquared() < std::min(m_vtxDisplacementCutSquared, (projVtxU - endU).GetMagnitudeSquared()) &&
132  (projEndU - endU).GetMagnitudeSquared() < std::min(m_vtxDisplacementCutSquared, (projEndU - vtxU).GetMagnitudeSquared()))
133  {
134  matchedU = true; ++matchedViews;
135  }
136  }
137 
138  if (foundV)
139  {
140  const CartesianVector projVtxV(LArGeometryHelper::ProjectPosition(this->GetPandora(), vtx3D, TPC_VIEW_V));
141  const CartesianVector projEndV(LArGeometryHelper::ProjectPosition(this->GetPandora(), end3D, TPC_VIEW_V));
142 
143  if((endV - vtxV).GetMagnitudeSquared() > m_minTrackLengthSquared &&
144  (projVtxV - vtxV).GetMagnitudeSquared() < std::min(m_vtxDisplacementCutSquared, (projVtxV - endV).GetMagnitudeSquared()) &&
145  (projEndV - endV).GetMagnitudeSquared() < std::min(m_vtxDisplacementCutSquared, (projEndV - vtxV).GetMagnitudeSquared()))
146  {
147  matchedV = true; ++matchedViews;
148  }
149  }
150 
151  if (foundW)
152  {
153  const CartesianVector projVtxW(LArGeometryHelper::ProjectPosition(this->GetPandora(), vtx3D, TPC_VIEW_W));
154  const CartesianVector projEndW(LArGeometryHelper::ProjectPosition(this->GetPandora(), end3D, TPC_VIEW_W));
155 
156  if((endW - vtxW).GetMagnitudeSquared() > m_minTrackLengthSquared &&
157  (projVtxW - vtxW).GetMagnitudeSquared() < std::min(m_vtxDisplacementCutSquared, (projVtxW - endW).GetMagnitudeSquared()) &&
158  (projEndW - endW).GetMagnitudeSquared() < std::min(m_vtxDisplacementCutSquared, (projEndW - vtxW).GetMagnitudeSquared()))
159  {
160  matchedW = true; ++matchedViews;
161  }
162  }
163 
164  if (matchedViews < 2)
165  continue;
166 
167  if (vtxChi2 + endChi2 < bestChi2)
168  {
169  useU = matchedU;
170  useV = matchedV;
171  useW = matchedW;
172 
173  bestVtx3D = vtx3D;
174  bestEnd3D = end3D;
175  bestChi2 = vtxChi2 + endChi2;
176  }
177  }
178 
179  if (useU)
180  outputSlidingFitMap.insert(MatchedSlidingFitMap::value_type(iterU->first, iterU->second));
181 
182  if (useV)
183  outputSlidingFitMap.insert(MatchedSlidingFitMap::value_type(iterV->first, iterV->second));
184 
185  if (useW)
186  outputSlidingFitMap.insert(MatchedSlidingFitMap::value_type(iterW->first, iterW->second));
187 
188  if (outputSlidingFitMap.empty())
189  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
190 }
191 
192 //------------------------------------------------------------------------------------------------------------------------------------------
193 
194 void LongitudinalTrackHitsBaseTool::UpdateBestPosition(const HitType hitType1, const HitType hitType2, const CartesianVector &vtx1,
195  const CartesianVector &vtx2, CartesianVector &bestVtx, float &bestChi2) const
196 {
197  CartesianVector mergedVtx(0.f, 0.f, 0.f);
198  float mergedChi2(std::numeric_limits<float>::max());
199 
200  LArGeometryHelper::MergeTwoPositions3D(this->GetPandora(), hitType1, hitType2, vtx1, vtx2, mergedVtx, mergedChi2);
201 
202  if (mergedChi2 < bestChi2)
203  {
204  bestVtx = mergedVtx;
205  bestChi2 = mergedChi2;
206  }
207 }
208 
209 //------------------------------------------------------------------------------------------------------------------------------------------
210 
211 StatusCode LongitudinalTrackHitsBaseTool::ReadSettings(const TiXmlHandle xmlHandle)
212 {
213  float vtxDisplacementCut = std::sqrt(m_vtxDisplacementCutSquared);
214  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
215  "VertexDisplacementCut", vtxDisplacementCut));
216  m_vtxDisplacementCutSquared = vtxDisplacementCut * vtxDisplacementCut;
217 
218  float minTrackLength = std::sqrt(m_minTrackLengthSquared);
219  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
220  "MinTrackLength", minTrackLength));
221  m_minTrackLengthSquared = minTrackLength * minTrackLength;
222 
223  return TrackHitsBaseTool::ReadSettings(xmlHandle);
224 }
225 
226 } // namespace lar_content
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Proto hits are temporary constructs to be used during iterative 3D hit procedure. ...
std::map< pandora::HitType, TwoDSlidingFitResult > MatchedSlidingFitMap
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.
virtual void GetLongitudinalTrackHit3D(const MatchedSlidingFitMap &matchedSlidingFitMap, const pandora::CartesianVector &vtx3D, const pandora::CartesianVector &end3D, ProtoHit &protoHit) const =0
Get the three dimensional position using a provided two dimensional calo hit and sliding linear fits ...
virtual void GetTrackHits3D(const pandora::CaloHitVector &inputTwoDHits, const MatchedSlidingFitMap &matchedSlidingFitMap, ProtoHitVector &protoHitVector) const
Calculate 3D hits from an input list of 2D hits.
ThreeDHitCreationAlgorithm::ProtoHitVector ProtoHitVector
static pandora::CartesianVector ProjectPosition(const pandora::Pandora &pandora, const pandora::CartesianVector &position3D, const pandora::HitType view)
Project 3D position into a given 2D view.
bool IsPositionSet() const
Whether the proto hit position is set.
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
double m_chiSquaredCut
The chi squared cut (accept only values below the cut value)
void UpdateBestPosition(const pandora::HitType hitType1, const pandora::HitType hitType2, const pandora::CartesianVector &vtx1, const pandora::CartesianVector &vtx2, pandora::CartesianVector &bestVtx, float &bestChi2) const
Combine two 2D coordinates to give a 3D coordinate.
TFile f
Definition: plotHisto.C:6
Header file for the three dimensional hit creation algorithm class.
Header file for the geometry helper class.
Int_t max
Definition: plot.C:27
intermediate_table::const_iterator const_iterator
double GetChi2() const
Get the chi squared value.
pandora::CartesianVector GetGlobalMinLayerPosition() const
Get global position corresponding to the fit result in minimum fit layer.
Header file for the longitudinal track hits base tool.
void GetVertexAndEndPositions(const MatchedSlidingFitMap &inputSlidingFitMap, MatchedSlidingFitMap &outputSlidingFitMap, pandora::CartesianVector &outputVtx3D, pandora::CartesianVector &outputEnd3D) const
Get reconstructed vertex and end positions for this 3D track.
Int_t min
Definition: plot.C:26
pandora::CartesianVector GetGlobalMaxLayerPosition() const
Get global position corresponding to the fit result in maximum fit layer.