Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
CosmicRayVertexBuildingAlgorithm.cc
Go to the documentation of this file.
1
10
14
16
17using namespace pandora;
18
19namespace lar_content
20{
21
23 m_useParentShowerVertex(false),
24 m_isDualPhase(false),
25 m_halfWindowLayers(30),
26 m_maxVertexDisplacementFromTrack(1.f)
27{
28}
29
30//------------------------------------------------------------------------------------------------------------------------------------------
31
33{
34 const PfoList *pPfoList = NULL;
36 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*this, m_parentPfoListName, pPfoList));
37
38 if (NULL == pPfoList)
39 {
41 std::cout << "CosmicRayVertexBuildingAlgorithm: pfo list unavailable." << std::endl;
42
43 return STATUS_CODE_SUCCESS;
44 }
45
46 PfoVector pfoVector;
47 LArPointingClusterMap pointingClusterMap;
48
49 this->GetCosmicPfos(pPfoList, pfoVector);
50 this->BuildPointingClusterMap(pfoVector, pointingClusterMap);
51 this->BuildCosmicRayParticles(pointingClusterMap, pfoVector);
52
53 return STATUS_CODE_SUCCESS;
54}
55
56//------------------------------------------------------------------------------------------------------------------------------------------
57
58void CosmicRayVertexBuildingAlgorithm::GetCosmicPfos(const PfoList *const pPfoList, PfoVector &pfoVector) const
59{
60 PfoList outputList;
61
62 for (PfoList::const_iterator pIter = pPfoList->begin(), pIterEnd = pPfoList->end(); pIter != pIterEnd; ++pIter)
63 {
64 if (!LArPfoHelper::IsFinalState(*pIter))
65 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
66
67 LArPfoHelper::GetAllDownstreamPfos(*pIter, outputList);
68 }
69
70 for (PfoList::const_iterator pIter = outputList.begin(), pIterEnd = outputList.end(); pIter != pIterEnd; ++pIter)
71 {
72 ClusterList clusterList;
73 LArPfoHelper::GetClusters(*pIter, TPC_3D, clusterList);
74
75 if (clusterList.empty())
76 continue;
77
78 pfoVector.push_back(*pIter);
79 }
80}
81
82//------------------------------------------------------------------------------------------------------------------------------------------
83
85{
86 const float slidingFitPitch(LArGeometryHelper::GetWireZPitch(this->GetPandora()));
87
88 for (PfoVector::const_iterator pIter = pfoVector.begin(), pIterEnd = pfoVector.end(); pIter != pIterEnd; ++pIter)
89 {
90 const ParticleFlowObject *const pPfo = *pIter;
91
92 if (!LArPfoHelper::IsTrack(pPfo))
93 continue;
94
95 ClusterList clusterList;
96 LArPfoHelper::GetClusters(pPfo, TPC_3D, clusterList);
97
98 for (ClusterList::const_iterator cIter = clusterList.begin(), cIterEnd = clusterList.end(); cIter != cIterEnd; ++cIter)
99 {
100 const Cluster *const pCluster = *cIter;
101
102 try
103 {
104 const LArPointingCluster pointingCluster(pCluster, m_halfWindowLayers, slidingFitPitch);
105
106 if (!pointingClusterMap.insert(LArPointingClusterMap::value_type(pCluster, pointingCluster)).second)
107 throw StatusCodeException(STATUS_CODE_FAILURE);
108 }
109 catch (StatusCodeException &statusCodeException)
110 {
111 if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
112 throw statusCodeException;
113 }
114 }
115 }
116}
117
118//------------------------------------------------------------------------------------------------------------------------------------------
119
121{
122 for (PfoVector::const_iterator iter = pfoVector.begin(), iterEnd = pfoVector.end(); iter != iterEnd; ++iter)
123 {
124 const ParticleFlowObject *const pPfo = *iter;
125
127 {
128 this->BuildCosmicRayParent(pointingClusterMap, pPfo);
129 }
130 else
131 {
132 this->BuildCosmicRayDaughter(pPfo);
133 }
134 }
135}
136
137//------------------------------------------------------------------------------------------------------------------------------------------
138
140{
141 ClusterList clusterList;
142 LArPfoHelper::GetClusters(pPfo, TPC_3D, clusterList);
143
144 if (clusterList.empty())
145 return;
146
147 // Take highest point as vertex of parent Pfos (TODO: do something more sophisticated for horizontal events)
148 bool foundVtx(false);
149 CartesianVector vtxPosition(0.f, 0.f, 0.f);
150 CartesianVector vtxDirection(0.f, 0.f, 0.f);
151
152 bool foundEnd(false);
153 CartesianVector endPosition(0.f, 0.f, 0.f);
154 CartesianVector endDirection(0.f, 0.f, 0.f);
155
156 for (ClusterList::const_iterator cIter1 = clusterList.begin(), cIterEnd1 = clusterList.end(); cIter1 != cIterEnd1; ++cIter1)
157 {
158 const Cluster *const pCluster = *cIter1;
159
160 try
161 {
162 CartesianVector minPosition(0.f, 0.f, 0.f), maxPosition(0.f, 0.f, 0.f);
163 CartesianVector minDirection(0.f, 0.f, 0.f), maxDirection(0.f, 0.f, 0.f);
164
165 LArPointingClusterMap::const_iterator cIter2 = pointingClusterMap.find(pCluster);
166
167 if (pointingClusterMap.end() != cIter2)
168 {
169 const LArPointingCluster &pointingCluster(cIter2->second);
170
171 minPosition = pointingCluster.GetInnerVertex().GetPosition();
172 maxPosition = pointingCluster.GetOuterVertex().GetPosition();
173 minDirection = pointingCluster.GetInnerVertex().GetDirection();
174 maxDirection = pointingCluster.GetOuterVertex().GetDirection();
175 }
176 else
177 {
178 LArClusterHelper::GetExtremalCoordinates(pCluster, minPosition, maxPosition);
179 minDirection = (maxPosition - minPosition).GetUnitVector();
180 maxDirection = (minPosition - maxPosition).GetUnitVector();
181 }
182
183 if ((maxPosition - minPosition).GetMagnitudeSquared() < std::numeric_limits<float>::epsilon())
184 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
185
186 // ATTN X is the vertical coordinate in Dual-Phase geometry
187 const float minVerticalCoordinate(m_isDualPhase ? minPosition.GetX() : minPosition.GetY());
188 const float maxVerticalCoordinate(m_isDualPhase ? maxPosition.GetX() : maxPosition.GetY());
189
190 if (!foundVtx || (minVerticalCoordinate > std::max(maxVerticalCoordinate, m_isDualPhase ? vtxPosition.GetX() : vtxPosition.GetY())))
191 {
192 foundVtx = true;
193 vtxPosition = minPosition;
194 vtxDirection = minDirection;
195 }
196
197 if (!foundVtx || (maxVerticalCoordinate > std::max(minVerticalCoordinate, m_isDualPhase ? vtxPosition.GetX() : vtxPosition.GetY())))
198 {
199 foundVtx = true;
200 vtxPosition = maxPosition;
201 vtxDirection = maxDirection;
202 }
203
204 if (!foundEnd || (minVerticalCoordinate < std::min(maxVerticalCoordinate, m_isDualPhase ? endPosition.GetX() : endPosition.GetY())))
205 {
206 foundEnd = true;
207 endPosition = minPosition;
208 endDirection = minDirection;
209 }
210
211 if (!foundEnd || (maxVerticalCoordinate < std::min(minVerticalCoordinate, m_isDualPhase ? endPosition.GetX() : endPosition.GetY())))
212 {
213 foundEnd = true;
214 endPosition = maxPosition;
215 endDirection = maxDirection;
216 }
217 }
218 catch (StatusCodeException &statusCodeException)
219 {
220 if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
221 throw statusCodeException;
222
223 continue;
224 }
225 }
226
227 if (!(foundVtx && foundEnd))
228 return;
229
230 this->SetParticleParameters(vtxPosition, vtxDirection, pPfo);
231}
232
233//------------------------------------------------------------------------------------------------------------------------------------------
234
236{
237 if (pDaughterPfo->GetParentPfoList().size() != 1)
238 throw StatusCodeException(STATUS_CODE_FAILURE);
239
240 const ParticleFlowObject *const pParentPfo = *(pDaughterPfo->GetParentPfoList().begin());
241
242 ClusterList parentList, daughterList;
243 LArPfoHelper::GetClusters(pParentPfo, TPC_3D, parentList);
244 LArPfoHelper::GetClusters(pDaughterPfo, TPC_3D, daughterList);
245
246 if (daughterList.empty() || parentList.empty())
247 return;
248
249 bool found(false);
250 float closestMaxVerticalCoordinate(-std::numeric_limits<float>::max()), maxVerticalCoordinate(-std::numeric_limits<float>::max());
251 CartesianVector closestMaxVerticalVertex(0.f, 0.f, 0.f), maxVerticalVertex(0.f, 0.f, 0.f);
252
253 for (const Cluster *const pDaughterCluster : daughterList)
254 {
255 CaloHitList daughterCaloHitList;
256 pDaughterCluster->GetOrderedCaloHitList().FillCaloHitList(daughterCaloHitList);
257
258 for (const Cluster *const pParentCluster : parentList)
259 {
260 CaloHitList parentCaloHitList;
261 pParentCluster->GetOrderedCaloHitList().FillCaloHitList(parentCaloHitList);
262
263 for (const CaloHit *const pDaughterCaloHit : daughterCaloHitList)
264 {
265 const CartesianVector &daughterPosition(pDaughterCaloHit->GetPositionVector());
266
267 for (const CaloHit *const pParentCaloHit : parentCaloHitList)
268 {
269 const CartesianVector &parentPosition(pParentCaloHit->GetPositionVector());
270 const float separationSquared((daughterPosition - parentPosition).GetMagnitudeSquared());
271 const float verticalCoordinate(m_isDualPhase ? daughterPosition.GetX() : daughterPosition.GetY());
272
273 if (verticalCoordinate > maxVerticalCoordinate)
274 {
275 maxVerticalCoordinate = verticalCoordinate;
276 maxVerticalVertex = daughterPosition;
277 }
278
280 {
281 if (verticalCoordinate > closestMaxVerticalCoordinate)
282 {
283 found = true;
284 closestMaxVerticalCoordinate = verticalCoordinate;
285 closestMaxVerticalVertex = daughterPosition;
286 }
287 }
288 }
289 }
290 }
291 }
292
293 const CartesianVector &daughterVertex(found ? closestMaxVerticalVertex : maxVerticalVertex);
294 const CartesianVector &vertexPosition(m_useParentShowerVertex ? LArClusterHelper::GetClosestPosition(daughterVertex, parentList) : daughterVertex);
295
296 this->SetParticleParameters(vertexPosition, CartesianVector(0.f, 0.f, 0.f), pDaughterPfo);
297}
298
299//------------------------------------------------------------------------------------------------------------------------------------------
300
302 const CartesianVector &vtxPosition, const CartesianVector &vtxDirection, const ParticleFlowObject *const pPfo) const
303{
304 if (!pPfo->GetVertexList().empty())
305 throw StatusCodeException(STATUS_CODE_FAILURE);
306
307 PandoraContentApi::ParticleFlowObject::Metadata metadata;
308 metadata.m_momentum = vtxDirection;
309 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*this, pPfo, metadata));
310
311 const VertexList *pVertexList = NULL;
312 std::string vertexListName;
313 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::CreateTemporaryListAndSetCurrent(*this, pVertexList, vertexListName));
314
315 PandoraContentApi::Vertex::Parameters parameters;
316 parameters.m_position = vtxPosition;
317 parameters.m_vertexLabel = VERTEX_START;
318 parameters.m_vertexType = VERTEX_3D;
319
320 const Vertex *pVertex(NULL);
321 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Vertex::Create(*this, parameters, pVertex));
322
323 if (!pVertexList->empty())
324 {
326 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToPfo<Vertex>(*this, pPfo, pVertex));
327 }
328}
329
330//------------------------------------------------------------------------------------------------------------------------------------------
331
333{
334 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "InputPfoListName", m_parentPfoListName));
335
336 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle, "OutputVertexListName", m_vertexListName));
337
338 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
339 XmlHelper::ReadValue(xmlHandle, "UseParentForShowerVertex", m_useParentShowerVertex));
340
342 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "SlidingFitHalfWindow", m_halfWindowLayers));
343
344 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "IsDualPhase", m_isDualPhase));
345
346 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
347 XmlHelper::ReadValue(xmlHandle, "MaxVertexDisplacementFromTrack", m_maxVertexDisplacementFromTrack));
348
349 return STATUS_CODE_SUCCESS;
350}
351
352} // namespace lar_content
Grouping of header files for many classes of use in particle flow algorithms.
Header file for the cosmic-ray vertex building algorithm class.
Header file for the cluster helper class.
Header file for the geometry helper class.
Header file for the pfo helper 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.
bool m_useParentShowerVertex
use the parent pfo for the shower vertices
std::string m_vertexListName
The name of the output vertex list.
void BuildCosmicRayParticles(const LArPointingClusterMap &pointingClusterMap, const pandora::PfoVector &pfoVector) const
Reconstruct the vertex and direction of a list of cosmic-ray Pfos.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
float m_maxVertexDisplacementFromTrack
The maximum separation of a close vertex from the cosmic ray track.
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.
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.
std::string m_parentPfoListName
The name of the input pfo list.
void BuildCosmicRayParent(const LArPointingClusterMap &pointingClusterMap, const pandora::ParticleFlowObject *const pPfo) const
Reconstruct the vertex and direction of a parent cosmic-ray Pfo.
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.
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 GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
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...
static bool IsTrack(const pandora::ParticleFlowObject *const pPfo)
Return track flag based on Pfo Particle ID.
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.
CaloHit class.
Definition CaloHit.h:26
CartesianVector class.
float GetX() const
Get the cartesian x coordinate.
float GetY() const
Get the cartesian y coordinate.
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
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 CaloHit * > CaloHitList
MANAGED_CONTAINER< const Vertex * > VertexList
StatusCode
The StatusCode enum.
MANAGED_CONTAINER< const ParticleFlowObject * > PfoList