LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
ThreeDTracksBaseAlgorithm.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
10 
13 
16 
18 
19 using namespace pandora;
20 
21 namespace lar_content
22 {
23 
24 template<typename T>
26  m_slidingFitWindow(20),
27  m_minClusterCaloHits(5),
28  m_minClusterLengthSquared(3.f * 3.f)
29 {
30 }
31 
32 //------------------------------------------------------------------------------------------------------------------------------------------
33 
34 template <typename T>
36 {
37 }
38 
39 //------------------------------------------------------------------------------------------------------------------------------------------
40 
41 template<typename T>
43 {
45 
46  if (m_slidingFitResultMap.end() == iter)
47  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
48 
49  return iter->second;
50 }
51 
52 //------------------------------------------------------------------------------------------------------------------------------------------
53 
54 template <typename T>
56 {
57  bool changesMade(false);
58 
59  ClusterList splitClusters;
60  for (const auto &mapEntry : splitPositionMap) splitClusters.push_back(mapEntry.first);
61  splitClusters.sort(LArClusterHelper::SortByNHits);
62 
63  for (const Cluster *pCurrentCluster : splitClusters)
64  {
65  CartesianPointVector splitPositions(splitPositionMap.at(pCurrentCluster));
66  std::sort(splitPositions.begin(), splitPositions.end(), ThreeDTracksBaseAlgorithm::SortSplitPositions);
67 
68  const HitType hitType(LArClusterHelper::GetClusterHitType(pCurrentCluster));
69  const std::string clusterListName((TPC_VIEW_U == hitType) ? this->GetClusterListNameU() : (TPC_VIEW_V == hitType) ? this->GetClusterListNameV() : this->GetClusterListNameW());
70 
71  if (!((TPC_VIEW_U == hitType) || (TPC_VIEW_V == hitType) || (TPC_VIEW_W == hitType)))
72  throw StatusCodeException(STATUS_CODE_FAILURE);
73 
74  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Cluster>(*this, clusterListName));
75 
76  for (CartesianPointVector::const_iterator sIter = splitPositions.begin(), sIterEnd = splitPositions.end(); sIter != sIterEnd; ++sIter)
77  {
78  const Cluster *pLowXCluster(NULL), *pHighXCluster(NULL);
79  this->UpdateUponDeletion(pCurrentCluster);
80 
81  if (this->MakeClusterSplit(*sIter, pCurrentCluster, pLowXCluster, pHighXCluster))
82  {
83  changesMade = true;
84  this->UpdateForNewCluster(pLowXCluster);
85  this->UpdateForNewCluster(pHighXCluster);
86  pCurrentCluster = pHighXCluster;
87  }
88  else
89  {
90  this->UpdateForNewCluster(pCurrentCluster);
91  }
92  }
93  }
94 
95  return changesMade;
96 }
97 
98 //------------------------------------------------------------------------------------------------------------------------------------------
99 
100 template <typename T>
101 bool ThreeDTracksBaseAlgorithm<T>::MakeClusterSplit(const CartesianVector &splitPosition, const Cluster *&pCurrentCluster, const Cluster *&pLowXCluster,
102  const Cluster *&pHighXCluster) const
103 {
104  CartesianVector lowXEnd(0.f, 0.f, 0.f), highXEnd(0.f, 0.f, 0.f);
105 
106  try
107  {
108  LArPointingCluster pointingCluster(pCurrentCluster);
109  const bool innerIsLowX(pointingCluster.GetInnerVertex().GetPosition().GetX() < pointingCluster.GetOuterVertex().GetPosition().GetX());
110  lowXEnd = (innerIsLowX ? pointingCluster.GetInnerVertex().GetPosition() : pointingCluster.GetOuterVertex().GetPosition());
111  highXEnd = (innerIsLowX ? pointingCluster.GetOuterVertex().GetPosition() : pointingCluster.GetInnerVertex().GetPosition());
112  }
113  catch (const StatusCodeException &) {return false;}
114 
115  const CartesianVector lowXUnitVector((lowXEnd - splitPosition).GetUnitVector());
116  const CartesianVector highXUnitVector((highXEnd - splitPosition).GetUnitVector());
117 
118  CaloHitList caloHitList;
119  pCurrentCluster->GetOrderedCaloHitList().FillCaloHitList(caloHitList);
120 
121  std::string originalListName, fragmentListName;
122  const ClusterList clusterList(1, pCurrentCluster);
123  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::InitializeFragmentation(*this, clusterList, originalListName, fragmentListName));
124 
125  pLowXCluster = NULL;
126  pHighXCluster = NULL;
127 
128  for (CaloHitList::const_iterator hIter = caloHitList.begin(), hIterEnd = caloHitList.end(); hIter != hIterEnd; ++hIter)
129  {
130  const CaloHit *const pCaloHit = *hIter;
131  const CartesianVector unitVector((pCaloHit->GetPositionVector() - splitPosition).GetUnitVector());
132 
133  const float dotProductLowX(unitVector.GetDotProduct(lowXUnitVector));
134  const float dotProductHighX(unitVector.GetDotProduct(highXUnitVector));
135  const Cluster *&pClusterToModify((dotProductLowX > dotProductHighX) ? pLowXCluster : pHighXCluster);
136 
137  if (NULL == pClusterToModify)
138  {
139  PandoraContentApi::Cluster::Parameters parameters;
140  parameters.m_caloHitList.push_back(pCaloHit);
141  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Cluster::Create(*this, parameters, pClusterToModify));
142  }
143  else
144  {
145  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToCluster(*this, pClusterToModify, pCaloHit));
146  }
147  }
148 
149  if ((NULL == pLowXCluster) || (NULL == pHighXCluster))
150  {
151  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::EndFragmentation(*this, originalListName, fragmentListName));
152  return false;
153  }
154 
155  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::EndFragmentation(*this, fragmentListName, originalListName));
156  return true;
157 }
158 
159 //------------------------------------------------------------------------------------------------------------------------------------------
160 
161 template <typename T>
162 bool ThreeDTracksBaseAlgorithm<T>::SortSplitPositions(const pandora::CartesianVector &lhs, const pandora::CartesianVector &rhs)
163 {
164  return (lhs.GetX() < rhs.GetX());
165 }
166 
167 //------------------------------------------------------------------------------------------------------------------------------------------
168 
169 template<typename T>
170 void ThreeDTracksBaseAlgorithm<T>::UpdateForNewCluster(const Cluster *const pNewCluster)
171 {
172  try
173  {
174  this->AddToSlidingFitCache(pNewCluster);
175  }
176  catch (StatusCodeException &statusCodeException)
177  {
178  if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
179  throw statusCodeException;
180 
181  return;
182  }
183 
185 }
186 
187 //------------------------------------------------------------------------------------------------------------------------------------------
188 
189 template<typename T>
190 void ThreeDTracksBaseAlgorithm<T>::UpdateUponDeletion(const Cluster *const pDeletedCluster)
191 {
192  this->RemoveFromSlidingFitCache(pDeletedCluster);
194 }
195 
196 //------------------------------------------------------------------------------------------------------------------------------------------
197 
198 template <typename T>
199 void ThreeDTracksBaseAlgorithm<T>::SelectInputClusters(const ClusterList *const pInputClusterList, ClusterList &selectedClusterList) const
200 {
201  for (ClusterList::const_iterator iter = pInputClusterList->begin(), iterEnd = pInputClusterList->end(); iter != iterEnd; ++iter)
202  {
203  const Cluster *const pCluster = *iter;
204 
205  if (!pCluster->IsAvailable())
206  continue;
207 
208  if (pCluster->GetNCaloHits() < m_minClusterCaloHits)
209  continue;
210 
212  continue;
213 
214  selectedClusterList.push_back(pCluster);
215  }
216 }
217 
218 //------------------------------------------------------------------------------------------------------------------------------------------
219 
220 template<typename T>
221 void ThreeDTracksBaseAlgorithm<T>::SetPfoParameters(const ProtoParticle &protoParticle, PandoraContentApi::ParticleFlowObject::Parameters &pfoParameters) const
222 {
223  // TODO Correct these placeholder parameters
224  pfoParameters.m_particleId = MU_MINUS; // Track
225  pfoParameters.m_charge = PdgTable::GetParticleCharge(pfoParameters.m_particleId.Get());
226  pfoParameters.m_mass = PdgTable::GetParticleMass(pfoParameters.m_particleId.Get());
227  pfoParameters.m_energy = 0.f;
228  pfoParameters.m_momentum = CartesianVector(0.f, 0.f, 0.f);
229  pfoParameters.m_clusterList.insert(pfoParameters.m_clusterList.end(), protoParticle.m_clusterListU.begin(), protoParticle.m_clusterListU.end());
230  pfoParameters.m_clusterList.insert(pfoParameters.m_clusterList.end(), protoParticle.m_clusterListV.begin(), protoParticle.m_clusterListV.end());
231  pfoParameters.m_clusterList.insert(pfoParameters.m_clusterList.end(), protoParticle.m_clusterListW.begin(), protoParticle.m_clusterListW.end());
232 }
233 
234 //------------------------------------------------------------------------------------------------------------------------------------------
235 
236 template<typename T>
238 {
239  this->PreparationStep(this->m_clusterListU);
240  this->PreparationStep(this->m_clusterListV);
241  this->PreparationStep(this->m_clusterListW);
242 }
243 
244 //------------------------------------------------------------------------------------------------------------------------------------------
245 
246 template<typename T>
247 void ThreeDTracksBaseAlgorithm<T>::PreparationStep(ClusterList &clusterList)
248 {
249  for (ClusterList::iterator iter = clusterList.begin(), iterEnd = clusterList.end(); iter != iterEnd; )
250  {
251  const Cluster *const pCluster(*iter);
252 
253  try
254  {
255  this->AddToSlidingFitCache(pCluster);
256  ++iter;
257  }
258  catch (StatusCodeException &statusCodeException)
259  {
260  clusterList.erase(iter++);
261 
262  if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
263  throw statusCodeException;
264  }
265  }
266 }
267 
268 //------------------------------------------------------------------------------------------------------------------------------------------
269 
270 template<typename T>
272 {
273  m_slidingFitResultMap.clear();
275 }
276 
277 //------------------------------------------------------------------------------------------------------------------------------------------
278 
279 template<typename T>
280 void ThreeDTracksBaseAlgorithm<T>::AddToSlidingFitCache(const Cluster *const pCluster)
281 {
282  const float slidingFitPitch(LArGeometryHelper::GetWireZPitch(this->GetPandora()));
283  const TwoDSlidingFitResult slidingFitResult(pCluster, m_slidingFitWindow, slidingFitPitch);
284 
285  if (!m_slidingFitResultMap.insert(TwoDSlidingFitResultMap::value_type(pCluster, slidingFitResult)).second)
286  throw StatusCodeException(STATUS_CODE_FAILURE);
287 }
288 
289 //------------------------------------------------------------------------------------------------------------------------------------------
290 
291 template<typename T>
293 {
295 
296  if (m_slidingFitResultMap.end() != iter)
297  m_slidingFitResultMap.erase(iter);
298 }
299 
300 //------------------------------------------------------------------------------------------------------------------------------------------
301 
302 template<typename T>
303 StatusCode ThreeDTracksBaseAlgorithm<T>::ReadSettings(const TiXmlHandle xmlHandle)
304 {
305  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
306  "SlidingFitWindow", m_slidingFitWindow));
307 
308  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
309  "MinClusterCaloHits", m_minClusterCaloHits));
310 
311  float minClusterLength = std::sqrt(m_minClusterLengthSquared);
312  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
313  "MinClusterLength", minClusterLength));
314  m_minClusterLengthSquared = minClusterLength * minClusterLength;
315 
316  return ThreeDBaseAlgorithm<T>::ReadSettings(xmlHandle);
317 }
318 
322 
323 } // namespace lar_content
static bool SortByNHits(const pandora::Cluster *const pLhs, const pandora::Cluster *const pRhs)
Sort clusters by number of hits, then layer span, then inner layer, then position, then pulse-height.
virtual void UpdateUponDeletion(const pandora::Cluster *const pDeletedCluster)
Update to reflect cluster deletion.
const std::string & GetClusterListNameU() const
Get the name of the u cluster list.
pandora::ClusterList m_clusterListW
The selected modified cluster list W.
std::unordered_map< const pandora::Cluster *, pandora::CartesianPointVector > SplitPositionMap
Header file for the lar pointing cluster class.
virtual bool MakeClusterSplits(const SplitPositionMap &splitPositionMap)
Make cluster splits.
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
intermediate_table::iterator iterator
const std::string & GetClusterListNameV() const
Get the name of the v cluster list.
LArPointingCluster class.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
const TwoDSlidingFitResult & GetCachedSlidingFitResult(const pandora::Cluster *const pCluster) const
Get a sliding fit result from the algorithm cache.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
virtual void TidyUp()
Tidy member variables in derived class.
TwoDSlidingFitResultMap m_slidingFitResultMap
The sliding fit result map.
ThreeDTransverseTracksAlgorithm class.
void AddToSlidingFitCache(const pandora::Cluster *const pCluster)
Add a new sliding fit result, for the specified cluster, to the algorithm cache.
TFile f
Definition: plotHisto.C:6
static bool SortSplitPositions(const pandora::CartesianVector &lhs, const pandora::CartesianVector &rhs)
Sort split position cartesian vectors by increasing x coordinate.
pandora::ClusterList m_clusterListV
The selected modified cluster list V.
Header file for the geometry helper class.
pandora::ClusterList m_clusterListW
List of 2D W clusters in a 3D proto particle.
const std::string & GetClusterListNameW() const
Get the name of the w cluster list.
intermediate_table::const_iterator const_iterator
virtual void SelectInputClusters(const pandora::ClusterList *const pInputClusterList, pandora::ClusterList &selectedClusterList) const
Select a subset of input clusters for processing in this algorithm.
Header file for the cluster helper class.
unsigned int m_minClusterCaloHits
The min number of hits in base cluster selection method.
const Vertex & GetOuterVertex() const
Get the outer vertex.
const Vertex & GetInnerVertex() const
Get the inner vertex.
pandora::ClusterList m_clusterListV
List of 2D V clusters in a 3D proto particle.
pandora::ClusterList m_clusterListU
List of 2D U clusters in a 3D proto particle.
virtual void TidyUp()
Tidy member variables in derived class.
virtual void PreparationStep()
Perform any preparatory steps required, e.g. caching expensive fit results for clusters.
unsigned int m_slidingFitWindow
The layer window for the sliding linear fits.
Header file for the lar track overlap result class.
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
virtual bool MakeClusterSplit(const pandora::CartesianVector &splitPosition, const pandora::Cluster *&pCurrentCluster, const pandora::Cluster *&pLowXCluster, const pandora::Cluster *&pHighXCluster) const
Make a cluster split.
virtual void UpdateUponDeletion(const pandora::Cluster *const pDeletedCluster)
Update to reflect cluster deletion.
virtual void UpdateForNewCluster(const pandora::Cluster *const pNewCluster)
Update to reflect addition of a new cluster to the problem space.
pandora::ClusterList m_clusterListU
The selected modified cluster list U.
static float GetLengthSquared(const pandora::Cluster *const pCluster)
Get length squared of cluster.
Header file for the three dimensional tracks algorithm base class.
float m_minClusterLengthSquared
The min length (squared) in base cluster selection method.
virtual void UpdateForNewCluster(const pandora::Cluster *const pNewCluster)
Update to reflect addition of a new cluster to the problem space.
const pandora::CartesianVector & GetPosition() const
Get the vertex position.
virtual void SetPfoParameters(const ProtoParticle &protoParticle, PandoraContentApi::ParticleFlowObject::Parameters &pfoParameters) const
Calculate Pfo properties from proto particle.
void RemoveFromSlidingFitCache(const pandora::Cluster *const pCluster)
Remova an existing sliding fit result, for the specified cluster, from the algorithm cache...