Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
NeutrinoDaughterVerticesAlgorithm.cc
Go to the documentation of this file.
1
10
14
16
17using namespace pandora;
18
19namespace lar_content
20{
21
22NeutrinoDaughterVerticesAlgorithm::NeutrinoDaughterVerticesAlgorithm() : m_useParentShowerVertex(false), m_halfWindowLayers(20)
23{
24}
25
26//------------------------------------------------------------------------------------------------------------------------------------------
27
29{
30 const PfoList *pPfoList = NULL;
31 PANDORA_THROW_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*this, m_neutrinoListName, pPfoList));
32
33 if (!pPfoList || pPfoList->empty())
34 {
36 std::cout << "NeutrinoDaughterVerticesAlgorithm: unable to find pfo list " << m_neutrinoListName << std::endl;
37
38 return STATUS_CODE_SUCCESS;
39 }
40
41 PfoVector pfoVector;
42 LArPointingClusterMap pointingClusterMap;
43
44 this->GetDaughterPfos(pPfoList, pfoVector);
45 this->BuildPointingClusterMap(pfoVector, pointingClusterMap);
46 this->BuildDaughterParticles(pointingClusterMap, pfoVector);
47
48 return STATUS_CODE_SUCCESS;
49}
50
51//------------------------------------------------------------------------------------------------------------------------------------------
52
53void NeutrinoDaughterVerticesAlgorithm::GetDaughterPfos(const PfoList *const pPfoList, PfoVector &pfoVector) const
54{
55 PfoList outputList;
56
57 for (PfoList::const_iterator pIter = pPfoList->begin(), pIterEnd = pPfoList->end(); pIter != pIterEnd; ++pIter)
58 {
59 if (!LArPfoHelper::IsNeutrino(*pIter) && (*pIter)->GetVertexList().size() != 1)
60 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
61
62 LArPfoHelper::GetAllDownstreamPfos(*pIter, outputList);
63 }
64
65 for (PfoList::const_iterator pIter = outputList.begin(), pIterEnd = outputList.end(); pIter != pIterEnd; ++pIter)
66 {
67 ClusterList clusterList;
68 LArPfoHelper::GetClusters(*pIter, TPC_3D, clusterList);
69
70 if (clusterList.empty())
71 continue;
72
73 pfoVector.push_back(*pIter);
74 }
75}
76
77//------------------------------------------------------------------------------------------------------------------------------------------
78
80{
81 const float slidingFitPitch(LArGeometryHelper::GetWireZPitch(this->GetPandora()));
82
83 for (PfoVector::const_iterator pIter = pfoList.begin(), pIterEnd = pfoList.end(); pIter != pIterEnd; ++pIter)
84 {
85 const ParticleFlowObject *const pPfo = *pIter;
86
87 if (!LArPfoHelper::IsTrack(pPfo))
88 continue;
89
90 ClusterList clusterList;
91 LArPfoHelper::GetClusters(pPfo, TPC_3D, clusterList);
92
93 for (ClusterList::const_iterator cIter = clusterList.begin(), cIterEnd = clusterList.end(); cIter != cIterEnd; ++cIter)
94 {
95 const Cluster *const pCluster = *cIter;
96
97 try
98 {
99 const LArPointingCluster pointingCluster(pCluster, m_halfWindowLayers, slidingFitPitch);
100
101 if (!pointingClusterMap.insert(LArPointingClusterMap::value_type(pCluster, pointingCluster)).second)
102 throw StatusCodeException(STATUS_CODE_FAILURE);
103 }
104 catch (StatusCodeException &statusCodeException)
105 {
106 if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
107 throw statusCodeException;
108 }
109 }
110 }
111}
112
113//------------------------------------------------------------------------------------------------------------------------------------------
114
116{
117 for (PfoVector::const_iterator iter = pfoVector.begin(), iterEnd = pfoVector.end(); iter != iterEnd; ++iter)
118 {
119 const ParticleFlowObject *const pPfo = *iter;
120
121 if (LArPfoHelper::IsTrack(pPfo))
122 {
123 this->BuildDaughterTrack(pointingClusterMap, pPfo);
124 }
125 else
126 {
127 this->BuildDaughterShower(pPfo);
128 }
129 }
130}
131
132//------------------------------------------------------------------------------------------------------------------------------------------
133
134void NeutrinoDaughterVerticesAlgorithm::BuildDaughterTrack(const LArPointingClusterMap &pointingClusterMap, const ParticleFlowObject *const pDaughterPfo) const
135{
136 if (pDaughterPfo->GetParentPfoList().size() != 1)
137 throw StatusCodeException(STATUS_CODE_FAILURE);
138
139 const ParticleFlowObject *const pParentPfo = *(pDaughterPfo->GetParentPfoList().begin());
140
141 ClusterList parentList, daughterList;
142 LArPfoHelper::GetClusters(pParentPfo, TPC_3D, parentList);
143 LArPfoHelper::GetClusters(pDaughterPfo, TPC_3D, daughterList);
144
145 if (parentList.empty() && pParentPfo->GetVertexList().empty())
146 return;
147
148 bool foundVtx(false);
149 float vtxDistance(0.f);
150 CartesianVector vtxPosition(0.f, 0.f, 0.f);
151 CartesianVector vtxDirection(0.f, 0.f, 0.f);
152
153 for (ClusterList::const_iterator dIter = daughterList.begin(), dIterEnd = daughterList.end(); dIter != dIterEnd; ++dIter)
154 {
155 const Cluster *const pDaughterCluster = *dIter;
156
157 CartesianVector minPosition(0.f, 0.f, 0.f), maxPosition(0.f, 0.f, 0.f);
158 CartesianVector minDirection(0.f, 0.f, 0.f), maxDirection(0.f, 0.f, 0.f);
159 bool foundDirection(false);
160
161 LArPointingClusterMap::const_iterator cIter = pointingClusterMap.find(pDaughterCluster);
162
163 if (pointingClusterMap.end() != cIter)
164 {
165 const LArPointingCluster &pointingCluster(cIter->second);
166
167 minPosition = pointingCluster.GetInnerVertex().GetPosition();
168 maxPosition = pointingCluster.GetOuterVertex().GetPosition();
169 minDirection = pointingCluster.GetInnerVertex().GetDirection();
170 maxDirection = pointingCluster.GetOuterVertex().GetDirection();
171 foundDirection = true;
172 }
173 else
174 {
175 LArClusterHelper::GetExtremalCoordinates(pDaughterCluster, minPosition, maxPosition);
176 }
177
178 if ((maxPosition - minPosition).GetMagnitudeSquared() < std::numeric_limits<float>::epsilon())
179 continue;
180
181 if (!foundDirection)
182 {
183 minDirection = (maxPosition - minPosition).GetUnitVector();
184 maxDirection = (minPosition - maxPosition).GetUnitVector();
185 }
186
187 float minDistance(std::numeric_limits<float>::max());
188 float maxDistance(std::numeric_limits<float>::max());
189
190 for (ClusterList::const_iterator pIter = parentList.begin(), pIterEnd = parentList.end(); pIter != pIterEnd; ++pIter)
191 {
192 const Cluster *const pParentCluster = *pIter;
193 minDistance = std::min(minDistance, (LArClusterHelper::GetClosestDistance(minPosition, pParentCluster)));
194 maxDistance = std::min(maxDistance, (LArClusterHelper::GetClosestDistance(maxPosition, pParentCluster)));
195 }
196
197 if (LArPfoHelper::IsNeutrino(pParentPfo) && !pParentPfo->GetVertexList().empty())
198 {
199 const Vertex *const pVertex = *(pParentPfo->GetVertexList().begin());
200 minDistance = std::min(minDistance, (pVertex->GetPosition() - minPosition).GetMagnitude());
201 maxDistance = std::min(maxDistance, (pVertex->GetPosition() - maxPosition).GetMagnitude());
202 }
203
204 if (!foundVtx || (minDistance < vtxDistance))
205 {
206 foundVtx = true;
207 vtxDistance = minDistance;
208 vtxPosition = minPosition;
209 vtxDirection = minDirection;
210 }
211
212 if (!foundVtx || (maxDistance < vtxDistance))
213 {
214 foundVtx = true;
215 vtxDistance = maxDistance;
216 vtxPosition = maxPosition;
217 vtxDirection = maxDirection;
218 }
219 }
220
221 if (!foundVtx)
222 return;
223
224 this->SetParticleParameters(vtxPosition, vtxDirection, pDaughterPfo);
225}
226
227//------------------------------------------------------------------------------------------------------------------------------------------
228
230{
231 if (pDaughterPfo->GetParentPfoList().size() != 1)
232 throw StatusCodeException(STATUS_CODE_FAILURE);
233
234 const ParticleFlowObject *const pParentPfo = *(pDaughterPfo->GetParentPfoList().begin());
235
236 if (LArPfoHelper::IsNeutrino(pParentPfo) && pParentPfo->GetVertexList().size() != 1)
237 throw StatusCodeException(STATUS_CODE_FAILURE);
238
239 ClusterList parentList, daughterList;
240 LArPfoHelper::GetClusters(pParentPfo, TPC_3D, parentList);
241 LArPfoHelper::GetClusters(pDaughterPfo, TPC_3D, daughterList);
242
243 if (daughterList.empty())
244 return;
245
246 if (LArPfoHelper::IsNeutrino(pParentPfo))
247 {
248 const Vertex *const pVertex = *(pParentPfo->GetVertexList().begin());
249 const CartesianVector vtxPosition(
251
252 return this->SetParticleParameters(vtxPosition, CartesianVector(0.f, 0.f, 0.f), pDaughterPfo);
253 }
254
255 if (parentList.empty())
256 return;
257
258 bool foundVtx(false);
259 float vtxDistanceSquared(0.f);
260 CartesianVector vtxPosition(0.f, 0.f, 0.f);
261
262 for (ClusterList::const_iterator dIter = daughterList.begin(), dIterEnd = daughterList.end(); dIter != dIterEnd; ++dIter)
263 {
264 const Cluster *const pDaughterCluster = *dIter;
265
266 for (ClusterList::const_iterator pIter = parentList.begin(), pIterEnd = parentList.end(); pIter != pIterEnd; ++pIter)
267 {
268 const Cluster *const pParentCluster = *pIter;
269
270 CartesianVector closestDaughterPosition(0.f, 0.f, 0.f), closestParentPosition(0.f, 0.f, 0.f);
271 LArClusterHelper::GetClosestPositions(pDaughterCluster, pParentCluster, closestDaughterPosition, closestParentPosition);
272
273 const float closestDistanceSquared((closestDaughterPosition - closestParentPosition).GetMagnitudeSquared());
274
275 if (!foundVtx || closestDistanceSquared < vtxDistanceSquared)
276 {
277 foundVtx = true;
278 vtxDistanceSquared = closestDistanceSquared;
279 vtxPosition = (m_useParentShowerVertex ? closestParentPosition : closestDaughterPosition);
280 }
281 }
282 }
283
284 if (!foundVtx)
285 return;
286
287 this->SetParticleParameters(vtxPosition, CartesianVector(0.f, 0.f, 0.f), pDaughterPfo);
288}
289
290//------------------------------------------------------------------------------------------------------------------------------------------
291
293 const CartesianVector &vtxPosition, const CartesianVector &vtxDirection, const ParticleFlowObject *const pPfo) const
294{
295 if (!pPfo->GetVertexList().empty())
296 throw StatusCodeException(STATUS_CODE_FAILURE);
297
298 PandoraContentApi::ParticleFlowObject::Metadata metadata;
299 metadata.m_momentum = vtxDirection;
300 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*this, pPfo, metadata));
301
302 const VertexList *pVertexList = NULL;
303 std::string vertexListName;
304 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*this, pVertexList, vertexListName));
305
306 PandoraContentApi::Vertex::Parameters parameters;
307 parameters.m_position = vtxPosition;
308 parameters.m_vertexLabel = VERTEX_INTERACTION;
309 parameters.m_vertexType = VERTEX_3D;
310
311 const Vertex *pVertex(NULL);
312 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*this, parameters, pVertex));
313
314 if (!pVertexList->empty())
315 {
317 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToPfo<Vertex>(*this, pPfo, pVertex));
318 }
319}
320
321//------------------------------------------------------------------------------------------------------------------------------------------
322
324{
325 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "NeutrinoPfoListName", m_neutrinoListName));
326
327 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "OutputVertexListName", m_vertexListName));
328
329 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
330 XmlHelper::ReadValue(xmlHandle, "UseParentForShowerVertex", m_useParentShowerVertex));
331
333 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "SlidingFitHalfWindow", m_halfWindowLayers));
334
335 return STATUS_CODE_SUCCESS;
336}
337
338} // namespace lar_content
Grouping of header files for many classes of use in particle flow algorithms.
Header file for the cluster helper class.
Header file for the geometry helper class.
Header file for the pfo helper class.
Header file for the neutrino daughter vertices algorithm class.
#define PANDORA_THROW_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
Definition StatusCodes.h:55
#define PANDORA_THROW_RESULT_IF(StatusCode1, Operator, Command)
Definition StatusCodes.h:43
#define PANDORA_RETURN_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
Definition StatusCodes.h:31
#define PANDORA_RETURN_RESULT_IF(StatusCode1, Operator, Command)
Definition StatusCodes.h:19
static pandora::StatusCode ReplaceCurrentList(const pandora::Algorithm &algorithm, const std::string &newListName)
Replace the current list with a pre-saved list; use this new list as a permanent replacement for the ...
static pandora::StatusCode CreateTemporaryListAndSetCurrent(const pandora::Algorithm &algorithm, const T *&pT, std::string &temporaryListName)
Create a temporary list and set it to be the current list, enabling object creation.
static pandora::StatusCode GetList(const pandora::Algorithm &algorithm, const std::string &listName, const T *&pT)
Get a named list.
static const pandora::PandoraSettings * GetSettings(const pandora::Algorithm &algorithm)
Get the pandora settings instance.
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.
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 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)
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
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...
static bool IsTrack(const pandora::ParticleFlowObject *const pPfo)
Return track flag based on Pfo Particle ID.
static bool IsNeutrino(const pandora::ParticleFlowObject *const pPfo)
Whether a pfo is a neutrino or (antineutrino)
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.
const pandora::CartesianVector & GetDirection() const
Get the vertex direction.
const pandora::CartesianVector & GetPosition() const
Get the vertex position.
LArPointingCluster class.
const Vertex & GetInnerVertex() const
Get the inner vertex.
const Vertex & GetOuterVertex() const
Get the outer vertex.
void BuildDaughterShower(const pandora::ParticleFlowObject *const pDaughterPfo) const
Reconstruct the vertex and direction of a shower-like Pfos.
void GetDaughterPfos(const pandora::PfoList *const pfoList, pandora::PfoVector &pfoVector) const
Get the vector of daughter pfos.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
void BuildDaughterParticles(const LArPointingClusterMap &pointingClusterMap, const pandora::PfoVector &pfoVector) const
Reconstruct the vertex and direction of daughter Pfos.
void BuildDaughterTrack(const LArPointingClusterMap &pointingClusterMap, const pandora::ParticleFlowObject *const pDaughterPfo) const
Reconstruct the vertex and direction of a track-like Pfos.
void BuildPointingClusterMap(const pandora::PfoVector &pfoVector, LArPointingClusterMap &pointingClusterMap) const
Build a map of 3D sliding fits from the input Pfos.
unsigned int m_halfWindowLayers
number of layers to use for half-window of sliding fit
void SetParticleParameters(const pandora::CartesianVector &vtxPosition, const pandora::CartesianVector &vtxDirection, const pandora::ParticleFlowObject *const pPfo) const
Set the vertex and direction of the Pfos.
std::string m_vertexListName
The name of the output cosmic-ray vertex list.
bool m_useParentShowerVertex
use the parent pfo for the shower vertices
std::string m_neutrinoListName
The input list of pfo list names.
CartesianVector class.
Cluster class.
Definition Cluster.h:31
bool ShouldDisplayAlgorithmInfo() const
Whether to display algorithm information during processing.
ParticleFlowObject class.
const PfoList & GetParentPfoList() const
Get the parent pfo list.
const VertexList & GetVertexList() const
Get the vertex list.
StatusCode AlterMetadata(const object_creation::ParticleFlowObject::Metadata &metadata)
Alter particle flow object metadata parameters.
const Pandora & GetPandora() const
Get the associated pandora instance.
Definition Process.h:116
StatusCodeException class.
StatusCode GetStatusCode() const
Get status code.
Vertex class.
Definition Vertex.h:26
const CartesianVector & GetPosition() const
Get the vertex position.
Definition Vertex.h:103
static StatusCode ReadValue(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, T &t)
Read a value from an xml element.
Definition XmlHelper.h:136
std::unordered_map< const pandora::Cluster *, LArPointingCluster > LArPointingClusterMap
MANAGED_CONTAINER< const Cluster * > ClusterList
std::vector< const ParticleFlowObject * > PfoVector
MANAGED_CONTAINER< const Vertex * > VertexList
StatusCode
The StatusCode enum.
MANAGED_CONTAINER< const ParticleFlowObject * > PfoList