9 #include "Pandora/AlgorithmHeaders.h" 21 DeltaRayIdentificationAlgorithm::DeltaRayIdentificationAlgorithm() :
22 m_distanceForMatching(3.
f),
23 m_minParentLengthSquared(10.
f * 10.
f),
24 m_maxDaughterLengthSquared(175.
f * 175.
f)
32 PfoVector parentPfos, daughterPfos;
36 if (parentPfos.empty())
38 if (PandoraContentApi::GetSettings(*this)->ShouldDisplayAlgorithmInfo())
39 std::cout <<
"DeltaRayIdentificationAlgorithm: pfo list " <<
m_parentPfoListName <<
" unavailable." << std::endl;
40 return STATUS_CODE_SUCCESS;
48 PfoList newDaughterPfoList;
51 if (!newDaughterPfoList.empty())
57 return STATUS_CODE_SUCCESS;
64 const PfoList *pPfoList = NULL;
65 PANDORA_THROW_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_INITIALIZED, !=, PandoraContentApi::GetList(*
this,
66 inputPfoListName, pPfoList));
71 outputPfoVector.insert(outputPfoVector.end(), pPfoList->begin(), pPfoList->end());
80 PfoSet parentPfoList, daughterPfoList;
81 parentPfoList.insert(parentPfos.begin(), parentPfos.end());
82 daughterPfoList.insert(daughterPfos.begin(), daughterPfos.end());
84 PfoVector allPfos(parentPfos.begin(), parentPfos.end());
85 allPfos.insert(allPfos.end(), daughterPfos.begin(), daughterPfos.end());
90 const ParticleFlowObject *
const pDaughterPfo = *iter1;
93 const ParticleFlowObject *pBestParentPfo = NULL;
98 const ParticleFlowObject *
const pThisParentPfo = *iter2;
101 if (pDaughterPfo == pThisParentPfo)
104 if (!this->
IsAssociated(pDaughterPfo, pThisParentPfo, thisDisplacement))
107 if (thisDisplacement < bestDisplacement)
109 bestDisplacement = thisDisplacement;
110 pBestParentPfo = pThisParentPfo;
118 if (pBestParentPfo->GetParentPfoList().empty())
121 if (daughterPfoList.count(pBestParentPfo))
122 throw StatusCodeException(STATUS_CODE_FAILURE);
124 pfoAssociationMap.insert(PfoAssociationMap::value_type(pDaughterPfo, pBestParentPfo));
131 if (parentPfoList.count(pBestParentPfo))
132 throw StatusCodeException(STATUS_CODE_FAILURE);
135 if (pBestParentPfo->GetParentPfoList().size() != 1)
136 throw StatusCodeException(STATUS_CODE_FAILURE);
140 const ParticleFlowObject *
const pReplacementParentPfo = *pIter;
141 if (pReplacementParentPfo->GetParentPfoList().size() != 0)
142 throw StatusCodeException(STATUS_CODE_FAILURE);
144 pfoAssociationMap.insert(PfoAssociationMap::value_type(pDaughterPfo, pReplacementParentPfo));
152 float &displacement)
const 156 if (pDaughterPfo == pParentPfo)
163 daughterLengthSquared > 0.5 * parentLengthSquared)
166 const float transitionLengthSquared(125.
f);
167 const float displacementCut((daughterLengthSquared > transitionLengthSquared) ?
m_distanceForMatching :
174 catch(StatusCodeException &statusCodeException)
176 if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
177 throw statusCodeException;
180 if (displacement > displacementCut)
190 CartesianPointVector vertexVectorU, vertexVectorV, vertexVectorW;
195 ClusterList clusterListU, clusterListV, clusterListW;
201 float sumDisplacementSquared(0.
f);
203 if (!vertexVectorU.empty())
206 sumDisplacementSquared += thisDisplacement * thisDisplacement;
210 if (!vertexVectorV.empty())
213 sumDisplacementSquared += thisDisplacement * thisDisplacement;
217 if (!vertexVectorW.empty())
220 sumDisplacementSquared += thisDisplacement * thisDisplacement;
224 if (sumViews < std::numeric_limits<float>::epsilon())
225 throw StatusCodeException(STATUS_CODE_FAILURE);
227 return std::sqrt(sumDisplacementSquared / sumViews);
234 ClusterList clusterList;
239 const Cluster *
const pCluster = *iter;
241 CartesianVector firstCoordinate(0.
f,0.
f,0.
f), secondCoordinate(0.
f,0.
f,0.
f);
244 vertexVector.push_back(firstCoordinate);
245 vertexVector.push_back(secondCoordinate);
253 if (vertexVector.empty() || clusterList.empty())
254 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
260 const CartesianVector &thisVertex = *iter1;
264 const Cluster *
const pCluster = *iter2;
267 if (thisDisplacement < bestDisplacement)
268 bestDisplacement = thisDisplacement;
272 return bestDisplacement;
280 for (
const auto &mapEntry : pfoAssociationMap) pfoList.push_back(mapEntry.first);
283 for (
const ParticleFlowObject *
const pDaughterPfo : pfoList)
285 const ParticleFlowObject *
const pParentPfo(this->
GetParent(pfoAssociationMap, pDaughterPfo));
288 throw StatusCodeException(STATUS_CODE_FAILURE);
293 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::SetPfoParentDaughterRelationship(*
this, pParentPfo, pDaughterPfo));
295 PandoraContentApi::ParticleFlowObject::Metadata metadata;
296 metadata.m_particleId = E_MINUS;
297 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ParticleFlowObject::AlterMetadata(*
this, pDaughterPfo, metadata));
299 daughterPfoList.push_back(pDaughterPfo);
306 const ParticleFlowObject *
const pPfo)
const 308 const ParticleFlowObject *pParentPfo =
nullptr;
309 const ParticleFlowObject *pDaughterPfo = pPfo;
314 if (pfoAssociationMap.end() == iter)
317 pParentPfo = iter->second;
318 pDaughterPfo = pParentPfo;
328 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"ParentPfoListName",
m_parentPfoListName));
329 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ReadValue(xmlHandle,
"DaughterPfoListName",
m_daughterPfoListName));
331 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
335 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
336 "MinParentLength", minParentLength));
340 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
341 "MaxDaughterLength", maxDaughterLength));
344 return STATUS_CODE_SUCCESS;
static bool SortByNHits(const pandora::ParticleFlowObject *const pLhs, const pandora::ParticleFlowObject *const pRhs)
Sort pfos by number of constituent hits.
Header file for the pfo helper class.
pandora::StatusCode Run()
float m_distanceForMatching
Maximum allowed distance of delta ray from parent cosmic ray.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
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 GetPfos(const std::string &inputPfoListName, pandora::PfoVector &outputPfoVector) const
Get the vector of Pfos, given the input list name.
const pandora::ParticleFlowObject * GetParent(const PfoAssociationMap &pfoAssociationMap, const pandora::ParticleFlowObject *const pPfo) const
For a given daughter, follow the parent/daughter links to find the overall parent.
float GetTwoDSeparation(const pandora::ParticleFlowObject *const pDaughterPfo, const pandora::ParticleFlowObject *const pParentPfo) const
Calculate 2D separation between two Pfos.
static bool IsTrack(const pandora::ParticleFlowObject *const pPfo)
Return track flag based on Pfo Particle ID.
std::string m_parentPfoListName
The parent pfo list name.
static float GetTwoDLengthSquared(const pandora::ParticleFlowObject *const pPfo)
Calculate length of Pfo using 2D clusters.
float m_maxDaughterLengthSquared
Maximum allowed length of daughter delta ray.
std::string m_daughterPfoListName
The daughter pfo list name.
Header file for the cluster helper class.
void GetTwoDVertices(const pandora::ParticleFlowObject *const pPfo, const pandora::HitType &hitType, pandora::CartesianPointVector &vertexVector) const
Calculate 2D separation between two Pfos.
bool IsAssociated(const pandora::ParticleFlowObject *const pDaughterPfo, const pandora::ParticleFlowObject *const pParentPfo, float &displacement) const
Determine if a given pair of Pfos have a parent/daughter association.
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 BuildParentDaughterLinks(const PfoAssociationMap &pfoAssociationMap, pandora::PfoList &outputPfoList) const
Build the parent/daughter links from the map of parent/daughter associations.
void BuildAssociationMap(const pandora::PfoVector &inputPfos, const pandora::PfoVector &outputPfos, PfoAssociationMap &pfoAssociationMap) const
Build parent/daughter associations between PFOs.
float m_minParentLengthSquared
Minimum allowed length of parent cosmic ray.
float GetClosestDistance(const pandora::CartesianPointVector &vertexVector, const pandora::ClusterList &clusterList) const
Calculate closest 2D separation between a set of vertices and a set of clusters.
std::unordered_map< const pandora::ParticleFlowObject *, const pandora::ParticleFlowObject * > PfoAssociationMap
Header file for the delta ray identification algorithm class.
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.