LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
CosmicRayVertexBuildingAlgorithm.cc
Go to the documentation of this file.
1 
9 #include "Pandora/AlgorithmHeaders.h"
10 
14 
16 
17 using namespace pandora;
18 
19 namespace lar_content
20 {
21 
22 CosmicRayVertexBuildingAlgorithm::CosmicRayVertexBuildingAlgorithm() :
23  m_useParentShowerVertex(false),
24  m_halfWindowLayers(30)
25 {
26 }
27 
28 //------------------------------------------------------------------------------------------------------------------------------------------
29 
31 {
32  const PfoList *pPfoList = NULL;
33  PANDORA_THROW_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*this, m_parentPfoListName,
34  pPfoList));
35 
36  if (NULL == pPfoList)
37  {
38  if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
39  std::cout << "CosmicRayVertexBuildingAlgorithm: pfo list unavailable." << std::endl;
40 
41  return STATUS_CODE_SUCCESS;
42  }
43 
44  PfoVector pfoVector;
45  LArPointingClusterMap pointingClusterMap;
46 
47  this->GetCosmicPfos(pPfoList, pfoVector);
48  this->BuildPointingClusterMap(pfoVector, pointingClusterMap);
49  this->BuildCosmicRayParticles(pointingClusterMap, pfoVector);
50 
51  return STATUS_CODE_SUCCESS;
52 }
53 
54 //------------------------------------------------------------------------------------------------------------------------------------------
55 
56 void CosmicRayVertexBuildingAlgorithm::GetCosmicPfos(const PfoList *const pPfoList, PfoVector &pfoVector) const
57 {
58  PfoList outputList;
59 
60  for (PfoList::const_iterator pIter = pPfoList->begin(), pIterEnd = pPfoList->end(); pIter != pIterEnd; ++pIter)
61  {
62  if (!LArPfoHelper::IsFinalState(*pIter))
63  throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
64 
65  LArPfoHelper::GetAllDownstreamPfos(*pIter, outputList);
66  }
67 
68  for (PfoList::const_iterator pIter = outputList.begin(), pIterEnd = outputList.end(); pIter != pIterEnd; ++pIter)
69  {
70  ClusterList clusterList;
71  LArPfoHelper::GetClusters(*pIter, TPC_3D, clusterList);
72 
73  if (clusterList.empty())
74  continue;
75 
76  pfoVector.push_back(*pIter);
77  }
78 }
79 
80 //------------------------------------------------------------------------------------------------------------------------------------------
81 
82 void CosmicRayVertexBuildingAlgorithm::BuildPointingClusterMap(const PfoVector &pfoVector, LArPointingClusterMap &pointingClusterMap) const
83 {
84  const float slidingFitPitch(LArGeometryHelper::GetWireZPitch(this->GetPandora()));
85 
86  for (PfoVector::const_iterator pIter = pfoVector.begin(), pIterEnd = pfoVector.end(); pIter != pIterEnd; ++pIter)
87  {
88  const ParticleFlowObject *const pPfo = *pIter;
89 
90  if (!LArPfoHelper::IsTrack(pPfo))
91  continue;
92 
93  ClusterList clusterList;
94  LArPfoHelper::GetClusters(pPfo, TPC_3D, clusterList);
95 
96  for (ClusterList::const_iterator cIter = clusterList.begin(), cIterEnd = clusterList.end(); cIter != cIterEnd; ++cIter)
97  {
98  const Cluster *const pCluster = *cIter;
99 
100  try
101  {
102  const LArPointingCluster pointingCluster(pCluster, m_halfWindowLayers, slidingFitPitch);
103 
104  if (!pointingClusterMap.insert(LArPointingClusterMap::value_type(pCluster, pointingCluster)).second)
105  throw StatusCodeException(STATUS_CODE_FAILURE);
106  }
107  catch (StatusCodeException &statusCodeException)
108  {
109  if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
110  throw statusCodeException;
111  }
112  }
113  }
114 }
115 
116 //------------------------------------------------------------------------------------------------------------------------------------------
117 
118 void CosmicRayVertexBuildingAlgorithm::BuildCosmicRayParticles(const LArPointingClusterMap &pointingClusterMap, const PfoVector &pfoVector) const
119 {
120  for (PfoVector::const_iterator iter = pfoVector.begin(), iterEnd = pfoVector.end(); iter != iterEnd; ++iter)
121  {
122  const ParticleFlowObject *const pPfo = *iter;
123 
124  if (LArPfoHelper::IsFinalState(pPfo))
125  {
126  this->BuildCosmicRayParent(pointingClusterMap, pPfo);
127  }
128  else
129  {
130  this->BuildCosmicRayDaughter(pPfo);
131  }
132  }
133 }
134 
135 //------------------------------------------------------------------------------------------------------------------------------------------
136 
137 void CosmicRayVertexBuildingAlgorithm::BuildCosmicRayParent(const LArPointingClusterMap &pointingClusterMap, const ParticleFlowObject *const pPfo) const
138 {
139  ClusterList clusterList;
140  LArPfoHelper::GetClusters(pPfo, TPC_3D, clusterList);
141 
142  if (clusterList.empty())
143  return;
144 
145  // Take highest point as vertex of parent Pfos (TODO: do something more sophisticated for horizontal events)
146  bool foundVtx(false);
147  CartesianVector vtxPosition(0.f, 0.f, 0.f);
148  CartesianVector vtxDirection(0.f, 0.f, 0.f);
149 
150  bool foundEnd(false);
151  CartesianVector endPosition(0.f, 0.f, 0.f);
152  CartesianVector endDirection(0.f, 0.f, 0.f);
153 
154  for (ClusterList::const_iterator cIter1 = clusterList.begin(), cIterEnd1 = clusterList.end(); cIter1 != cIterEnd1; ++cIter1)
155  {
156  const Cluster *const pCluster = *cIter1;
157 
158  try
159  {
160  CartesianVector minPosition(0.f, 0.f, 0.f), maxPosition(0.f,0.f,0.f);
161  CartesianVector minDirection(0.f, 0.f, 0.f), maxDirection(0.f,0.f,0.f);
162 
163  LArPointingClusterMap::const_iterator cIter2 = pointingClusterMap.find(pCluster);
164 
165  if (pointingClusterMap.end() != cIter2)
166  {
167  const LArPointingCluster &pointingCluster(cIter2->second);
168 
169  minPosition = pointingCluster.GetInnerVertex().GetPosition();
170  maxPosition = pointingCluster.GetOuterVertex().GetPosition();
171  minDirection = pointingCluster.GetInnerVertex().GetDirection();
172  maxDirection = pointingCluster.GetOuterVertex().GetDirection();
173  }
174  else
175  {
176  LArClusterHelper::GetExtremalCoordinates(pCluster, minPosition, maxPosition);
177  minDirection = (maxPosition - minPosition).GetUnitVector();
178  maxDirection = (minPosition - maxPosition).GetUnitVector();
179  }
180 
181  if ((maxPosition - minPosition).GetMagnitudeSquared() < std::numeric_limits<float>::epsilon())
182  throw StatusCodeException(STATUS_CODE_NOT_FOUND);
183 
184  if (!foundVtx || (minPosition.GetY() > std::max(maxPosition.GetY(), vtxPosition.GetY())))
185  {
186  foundVtx = true;
187  vtxPosition = minPosition;
188  vtxDirection = minDirection;
189  }
190 
191  if (!foundVtx || (maxPosition.GetY() > std::max(minPosition.GetY(), vtxPosition.GetY())))
192  {
193  foundVtx = true;
194  vtxPosition = maxPosition;
195  vtxDirection = maxDirection;
196  }
197 
198  if (!foundEnd || (minPosition.GetY() < std::min(maxPosition.GetY(), endPosition.GetY())))
199  {
200  foundEnd = true;
201  endPosition = minPosition;
202  endDirection = minDirection;
203  }
204 
205  if (!foundEnd || (maxPosition.GetY() < std::min(minPosition.GetY(), endPosition.GetY())))
206  {
207  foundEnd = true;
208  endPosition = maxPosition;
209  endDirection = maxDirection;
210  }
211  }
212  catch(StatusCodeException &statusCodeException)
213  {
214  if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
215  throw statusCodeException;
216 
217  continue;
218  }
219  }
220 
221  if (!(foundVtx && foundEnd))
222  return;
223 
224  this->SetParticleParameters(vtxPosition, vtxDirection, pPfo);
225 }
226 
227 //------------------------------------------------------------------------------------------------------------------------------------------
228 
229 void CosmicRayVertexBuildingAlgorithm::BuildCosmicRayDaughter(const ParticleFlowObject *const pDaughterPfo) const
230 {
231  if (pDaughterPfo->GetParentPfoList().size() != 1)
232  throw StatusCodeException(STATUS_CODE_FAILURE);
233 
234  const ParticleFlowObject *const pParentPfo = *(pDaughterPfo->GetParentPfoList().begin());
235 
236  ClusterList parentList, daughterList;
237  LArPfoHelper::GetClusters(pParentPfo, TPC_3D, parentList);
238  LArPfoHelper::GetClusters(pDaughterPfo, TPC_3D, daughterList);
239 
240  if (daughterList.empty() || parentList.empty())
241  return;
242 
243  bool foundVtx(false);
244  float vtxDistanceSquared(0.f);
245  CartesianVector vtxPosition(0.f, 0.f, 0.f);
246 
247  for (ClusterList::const_iterator dIter = daughterList.begin(), dIterEnd = daughterList.end(); dIter != dIterEnd; ++dIter)
248  {
249  const Cluster *const pDaughterCluster = *dIter;
250 
251  for (ClusterList::const_iterator pIter = parentList.begin(), pIterEnd = parentList.end(); pIter != pIterEnd; ++pIter)
252  {
253  const Cluster *const pParentCluster = *pIter;
254 
255  CartesianVector closestDaughterPosition(0.f, 0.f, 0.f), closestParentPosition(0.f, 0.f, 0.f);
256  LArClusterHelper::GetClosestPositions(pDaughterCluster, pParentCluster, closestDaughterPosition, closestParentPosition);
257 
258  const float closestDistanceSquared((closestDaughterPosition - closestParentPosition).GetMagnitudeSquared());
259 
260  if (!foundVtx || closestDistanceSquared < vtxDistanceSquared)
261  {
262  foundVtx = true;
263  vtxDistanceSquared = closestDistanceSquared;
264  vtxPosition = (m_useParentShowerVertex ? closestParentPosition : closestDaughterPosition);
265  }
266  }
267  }
268 
269  if (!foundVtx)
270  return;
271 
272  this->SetParticleParameters(vtxPosition, CartesianVector(0.f, 0.f, 0.f), pDaughterPfo);
273 }
274 
275 //------------------------------------------------------------------------------------------------------------------------------------------
276 
277 void CosmicRayVertexBuildingAlgorithm::SetParticleParameters(const CartesianVector &vtxPosition, const CartesianVector &vtxDirection,
278  const ParticleFlowObject *const pPfo) const
279 {
280  if (!pPfo->GetVertexList().empty())
281  throw StatusCodeException(STATUS_CODE_FAILURE);
282 
283  PandoraContentApi::ParticleFlowObject::Metadata metadata;
284  metadata.m_momentum = vtxDirection;
285  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*this, pPfo, metadata));
286 
287  const VertexList *pVertexList = NULL; std::string vertexListName;
288  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*this, pVertexList, vertexListName));
289 
290  PandoraContentApi::Vertex::Parameters parameters;
291  parameters.m_position = vtxPosition;
292  parameters.m_vertexLabel = VERTEX_START;
293  parameters.m_vertexType = VERTEX_3D;
294 
295  const Vertex *pVertex(NULL);
296  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*this, parameters, pVertex));
297 
298  if (!pVertexList->empty())
299  {
300  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Vertex>(*this, m_vertexListName));
301  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToPfo<Vertex>(*this, pPfo, pVertex));
302  }
303 }
304 
305 //------------------------------------------------------------------------------------------------------------------------------------------
306 
307 StatusCode CosmicRayVertexBuildingAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
308 {
309  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "InputPfoListName", m_parentPfoListName));
310 
311  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "OutputVertexListName", m_vertexListName));
312 
313  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
314  "UseParentForShowerVertex", m_useParentShowerVertex));
315 
316  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
317  "SlidingFitHalfWindow", m_halfWindowLayers));
318 
319  return STATUS_CODE_SUCCESS;
320 }
321 
322 } // namespace lar_content
Header file for the pfo helper class.
bool m_useParentShowerVertex
use the parent pfo for the shower vertices
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.
void SetParticleParameters(const pandora::CartesianVector &vtxPosition, const pandora::CartesianVector &vtxDirection, const pandora::ParticleFlowObject *const pPfo) const
Set the vertex and direction of the Pfos.
LArPointingCluster class.
static void GetClosestPositions(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, pandora::CartesianVector &position1, pandora::CartesianVector &position2)
Get pair of closest positions for a pair of clusters.
std::string m_vertexListName
The name of the output vertex list.
Header file for the cosmic-ray vertex building algorithm class.
static bool IsTrack(const pandora::ParticleFlowObject *const pPfo)
Return track flag based on Pfo Particle ID.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
void BuildCosmicRayParent(const LArPointingClusterMap &pointingClusterMap, const pandora::ParticleFlowObject *const pPfo) const
Reconstruct the vertex and direction of a parent cosmic-ray Pfo.
TFile f
Definition: plotHisto.C:6
Header file for the geometry helper class.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Int_t max
Definition: plot.C:27
void BuildCosmicRayParticles(const LArPointingClusterMap &pointingClusterMap, const pandora::PfoVector &pfoVector) const
Reconstruct the vertex and direction of a list of cosmic-ray Pfos.
intermediate_table::const_iterator const_iterator
Header file for the cluster helper class.
const Vertex & GetOuterVertex() const
Get the outer vertex.
const Vertex & GetInnerVertex() const
Get the inner vertex.
std::string m_parentPfoListName
The name of the input pfo list.
std::unordered_map< const pandora::Cluster *, LArPointingCluster > LArPointingClusterMap
const pandora::CartesianVector & GetDirection() const
Get the vertex direction.
unsigned int m_halfWindowLayers
number of layers to use for half-window of sliding fit
static void GetExtremalCoordinates(const pandora::ClusterList &clusterList, pandora::CartesianVector &innerCoordinate, pandora::CartesianVector &outerCoordinate)
Get positions of the two most distant calo hits in a list of cluster (ordered by Z) ...
Int_t min
Definition: plot.C:26
static bool IsFinalState(const pandora::ParticleFlowObject *const pPfo)
Whether a pfo is a primary parent particle.
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 GetCosmicPfos(const pandora::PfoList *const pPfoList, pandora::PfoVector &pfoVector) const
Get the list of input pfos to this algorithm.
void BuildCosmicRayDaughter(const pandora::ParticleFlowObject *const pPfo) const
Reconstruct the vertex and direction of a daughter cosmic-ray Pfo.
void BuildPointingClusterMap(const pandora::PfoVector &pfoVector, LArPointingClusterMap &pointingClusterMap) const
Build a map of 3D sliding fits from the input Pfos.
std::list< Vertex > VertexList
Definition: DCEL.h:178
const pandora::CartesianVector & GetPosition() const
Get the vertex position.