LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
NeutrinoDaughterVerticesAlgorithm.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 NeutrinoDaughterVerticesAlgorithm::NeutrinoDaughterVerticesAlgorithm() :
23  m_useParentShowerVertex(false),
24  m_halfWindowLayers(20)
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_neutrinoListName,
34  pPfoList));
35 
36  if (!pPfoList || pPfoList->empty())
37  {
38  if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
39  std::cout << "NeutrinoDaughterVerticesAlgorithm: unable to find pfo list " << m_neutrinoListName << std::endl;
40 
41  return STATUS_CODE_SUCCESS;
42  }
43 
44  PfoVector pfoVector;
45  LArPointingClusterMap pointingClusterMap;
46 
47  this->GetDaughterPfos(pPfoList, pfoVector);
48  this->BuildPointingClusterMap(pfoVector, pointingClusterMap);
49  this->BuildDaughterParticles(pointingClusterMap, pfoVector);
50 
51  return STATUS_CODE_SUCCESS;
52 }
53 
54 //------------------------------------------------------------------------------------------------------------------------------------------
55 
56 void NeutrinoDaughterVerticesAlgorithm::GetDaughterPfos(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::IsNeutrino(*pIter) && (*pIter)->GetVertexList().size() != 1)
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 NeutrinoDaughterVerticesAlgorithm::BuildPointingClusterMap(const PfoVector &pfoList, LArPointingClusterMap &pointingClusterMap) const
83 {
84  const float slidingFitPitch(LArGeometryHelper::GetWireZPitch(this->GetPandora()));
85 
86  for (PfoVector::const_iterator pIter = pfoList.begin(), pIterEnd = pfoList.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 NeutrinoDaughterVerticesAlgorithm::BuildDaughterParticles(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::IsTrack(pPfo))
125  {
126  this->BuildDaughterTrack(pointingClusterMap, pPfo);
127  }
128  else
129  {
130  this->BuildDaughterShower(pPfo);
131  }
132  }
133 }
134 
135 //------------------------------------------------------------------------------------------------------------------------------------------
136 
137 void NeutrinoDaughterVerticesAlgorithm::BuildDaughterTrack(const LArPointingClusterMap &pointingClusterMap, const ParticleFlowObject *const pDaughterPfo) const
138 {
139  if (pDaughterPfo->GetParentPfoList().size() != 1)
140  throw StatusCodeException(STATUS_CODE_FAILURE);
141 
142  const ParticleFlowObject *const pParentPfo = *(pDaughterPfo->GetParentPfoList().begin());
143 
144  ClusterList parentList, daughterList;
145  LArPfoHelper::GetClusters(pParentPfo, TPC_3D, parentList);
146  LArPfoHelper::GetClusters(pDaughterPfo, TPC_3D, daughterList);
147 
148  if (parentList.empty() && pParentPfo->GetVertexList().empty())
149  return;
150 
151  bool foundVtx(false);
152  float vtxDistance(0.f);
153  CartesianVector vtxPosition(0.f, 0.f, 0.f);
154  CartesianVector vtxDirection(0.f, 0.f, 0.f);
155 
156  for (ClusterList::const_iterator dIter = daughterList.begin(), dIterEnd = daughterList.end(); dIter != dIterEnd; ++dIter)
157  {
158  const Cluster *const pDaughterCluster = *dIter;
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  bool foundDirection(false);
163 
164  LArPointingClusterMap::const_iterator cIter = pointingClusterMap.find(pDaughterCluster);
165 
166  if (pointingClusterMap.end() != cIter)
167  {
168  const LArPointingCluster &pointingCluster(cIter->second);
169 
170  minPosition = pointingCluster.GetInnerVertex().GetPosition();
171  maxPosition = pointingCluster.GetOuterVertex().GetPosition();
172  minDirection = pointingCluster.GetInnerVertex().GetDirection();
173  maxDirection = pointingCluster.GetOuterVertex().GetDirection();
174  foundDirection = true;
175  }
176  else
177  {
178  LArClusterHelper::GetExtremalCoordinates(pDaughterCluster, minPosition, maxPosition);
179  }
180 
181  if ((maxPosition - minPosition).GetMagnitudeSquared() < std::numeric_limits<float>::epsilon())
182  continue;
183 
184  if (!foundDirection)
185  {
186  minDirection = (maxPosition - minPosition).GetUnitVector();
187  maxDirection = (minPosition - maxPosition).GetUnitVector();
188  }
189 
190  float minDistance(std::numeric_limits<float>::max());
191  float maxDistance(std::numeric_limits<float>::max());
192 
193  for (ClusterList::const_iterator pIter = parentList.begin(), pIterEnd = parentList.end(); pIter != pIterEnd; ++pIter)
194  {
195  const Cluster *const pParentCluster = *pIter;
196  minDistance = std::min(minDistance, (LArClusterHelper::GetClosestDistance(minPosition, pParentCluster)));
197  maxDistance = std::min(maxDistance, (LArClusterHelper::GetClosestDistance(maxPosition, pParentCluster)));
198  }
199 
200  if (LArPfoHelper::IsNeutrino(pParentPfo) && !pParentPfo->GetVertexList().empty())
201  {
202  const Vertex *const pVertex = *(pParentPfo->GetVertexList().begin());
203  minDistance = std::min(minDistance, (pVertex->GetPosition() - minPosition).GetMagnitude());
204  maxDistance = std::min(maxDistance, (pVertex->GetPosition() - maxPosition).GetMagnitude());
205  }
206 
207  if (!foundVtx || (minDistance < vtxDistance))
208  {
209  foundVtx = true;
210  vtxDistance = minDistance;
211  vtxPosition = minPosition;
212  vtxDirection = minDirection;
213  }
214 
215  if (!foundVtx || (maxDistance < vtxDistance))
216  {
217  foundVtx = true;
218  vtxDistance = maxDistance;
219  vtxPosition = maxPosition;
220  vtxDirection = maxDirection;
221  }
222  }
223 
224  if (!foundVtx)
225  return;
226 
227  this->SetParticleParameters(vtxPosition, vtxDirection, pDaughterPfo);
228 }
229 
230 //------------------------------------------------------------------------------------------------------------------------------------------
231 
232 void NeutrinoDaughterVerticesAlgorithm::BuildDaughterShower(const ParticleFlowObject *const pDaughterPfo) const
233 {
234  if (pDaughterPfo->GetParentPfoList().size() != 1)
235  throw StatusCodeException(STATUS_CODE_FAILURE);
236 
237  const ParticleFlowObject *const pParentPfo = *(pDaughterPfo->GetParentPfoList().begin());
238 
239  if (LArPfoHelper::IsNeutrino(pParentPfo) && pParentPfo->GetVertexList().size() != 1)
240  throw StatusCodeException(STATUS_CODE_FAILURE);
241 
242  ClusterList parentList, daughterList;
243  LArPfoHelper::GetClusters(pParentPfo, TPC_3D, parentList);
244  LArPfoHelper::GetClusters(pDaughterPfo, TPC_3D, daughterList);
245 
246  if (daughterList.empty())
247  return;
248 
249  if (LArPfoHelper::IsNeutrino(pParentPfo))
250  {
251  const Vertex *const pVertex = *(pParentPfo->GetVertexList().begin());
252  const CartesianVector vtxPosition(m_useParentShowerVertex ? pVertex->GetPosition() :
253  LArClusterHelper::GetClosestPosition(pVertex->GetPosition(), daughterList));
254 
255  return this->SetParticleParameters(vtxPosition, CartesianVector(0.f, 0.f, 0.f), pDaughterPfo);
256  }
257 
258  if (parentList.empty())
259  return;
260 
261  bool foundVtx(false);
262  float vtxDistanceSquared(0.f);
263  CartesianVector vtxPosition(0.f, 0.f, 0.f);
264 
265  for (ClusterList::const_iterator dIter = daughterList.begin(), dIterEnd = daughterList.end(); dIter != dIterEnd; ++dIter)
266  {
267  const Cluster *const pDaughterCluster = *dIter;
268 
269  for (ClusterList::const_iterator pIter = parentList.begin(), pIterEnd = parentList.end(); pIter != pIterEnd; ++pIter)
270  {
271  const Cluster *const pParentCluster = *pIter;
272 
273  CartesianVector closestDaughterPosition(0.f, 0.f, 0.f), closestParentPosition(0.f, 0.f, 0.f);
274  LArClusterHelper::GetClosestPositions(pDaughterCluster, pParentCluster, closestDaughterPosition, closestParentPosition);
275 
276  const float closestDistanceSquared((closestDaughterPosition - closestParentPosition).GetMagnitudeSquared());
277 
278  if (!foundVtx || closestDistanceSquared < vtxDistanceSquared)
279  {
280  foundVtx = true;
281  vtxDistanceSquared = closestDistanceSquared;
282  vtxPosition = (m_useParentShowerVertex ? closestParentPosition : closestDaughterPosition);
283  }
284  }
285  }
286 
287  if (!foundVtx)
288  return;
289 
290  this->SetParticleParameters(vtxPosition, CartesianVector(0.f, 0.f, 0.f), pDaughterPfo);
291 }
292 
293 //------------------------------------------------------------------------------------------------------------------------------------------
294 
295 void NeutrinoDaughterVerticesAlgorithm::SetParticleParameters(const CartesianVector &vtxPosition, const CartesianVector &vtxDirection,
296  const ParticleFlowObject *const pPfo) const
297 {
298  if (!pPfo->GetVertexList().empty())
299  throw StatusCodeException(STATUS_CODE_FAILURE);
300 
301  PandoraContentApi::ParticleFlowObject::Metadata metadata;
302  metadata.m_momentum = vtxDirection;
303  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*this, pPfo, metadata));
304 
305  const VertexList *pVertexList = NULL; std::string vertexListName;
306  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*this, pVertexList, vertexListName));
307 
308  PandoraContentApi::Vertex::Parameters parameters;
309  parameters.m_position = vtxPosition;
310  parameters.m_vertexLabel = VERTEX_INTERACTION;
311  parameters.m_vertexType = VERTEX_3D;
312 
313  const Vertex *pVertex(NULL);
314  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*this, parameters, pVertex));
315 
316  if (!pVertexList->empty())
317  {
318  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SaveList<Vertex>(*this, m_vertexListName));
319  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToPfo<Vertex>(*this, pPfo, pVertex));
320  }
321 }
322 
323 //------------------------------------------------------------------------------------------------------------------------------------------
324 
325 StatusCode NeutrinoDaughterVerticesAlgorithm::ReadSettings(const TiXmlHandle xmlHandle)
326 {
327  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
328  "NeutrinoPfoListName", m_neutrinoListName));
329 
330  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
331  "OutputVertexListName", m_vertexListName));
332 
333  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
334  "UseParentForShowerVertex", m_useParentShowerVertex));
335 
336  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
337  "SlidingFitHalfWindow", m_halfWindowLayers));
338 
339  return STATUS_CODE_SUCCESS;
340 }
341 
342 } // namespace lar_content
unsigned int m_halfWindowLayers
number of layers to use for half-window of sliding fit
std::string m_vertexListName
The name of the output cosmic-ray vertex list.
Header file for the pfo helper class.
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.
Header file for the neutrino daughter vertices algorithm class.
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.
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.
TFile f
Definition: plotHisto.C:6
Header file for the geometry helper class.
void GetDaughterPfos(const pandora::PfoList *const pfoList, pandora::PfoVector &pfoVector) const
Get the vector of daughter pfos.
Int_t max
Definition: plot.C:27
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.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
static bool IsNeutrino(const pandora::ParticleFlowObject *const pPfo)
Whether a pfo is a neutrino or (antineutrino)
std::unordered_map< const pandora::Cluster *, LArPointingCluster > LArPointingClusterMap
const pandora::CartesianVector & GetDirection() const
Get the vertex direction.
bool m_useParentShowerVertex
use the parent pfo for the shower vertices
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) ...
void SetParticleParameters(const pandora::CartesianVector &vtxPosition, const pandora::CartesianVector &vtxDirection, const pandora::ParticleFlowObject *const pPfo) const
Set the vertex and direction of the Pfos.
Int_t min
Definition: plot.C:26
void BuildDaughterShower(const pandora::ParticleFlowObject *const pDaughterPfo) const
Reconstruct the vertex and direction of a shower-like Pfos.
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 BuildDaughterParticles(const LArPointingClusterMap &pointingClusterMap, const pandora::PfoVector &pfoVector) const
Reconstruct the vertex and direction of daughter Pfos.
void BuildPointingClusterMap(const pandora::PfoVector &pfoVector, LArPointingClusterMap &pointingClusterMap) const
Build a map of 3D sliding fits from the input Pfos.
static pandora::CartesianVector GetClosestPosition(const pandora::CartesianVector &position, const pandora::ClusterList &clusterList)
Get closest position in a list of clusters to a specified input position vector.
std::string m_neutrinoListName
The input list of pfo list names.
std::list< Vertex > VertexList
Definition: DCEL.h:178
const pandora::CartesianVector & GetPosition() const
Get the vertex position.
void BuildDaughterTrack(const LArPointingClusterMap &pointingClusterMap, const pandora::ParticleFlowObject *const pDaughterPfo) const
Reconstruct the vertex and direction of a track-like Pfos.
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.