9 #include "Pandora/AlgorithmHeaders.h" 21 LocalAsymmetryFeatureTool::LocalAsymmetryFeatureTool() :
22 m_maxAsymmetryDistance(5.
f),
23 m_minAsymmetryCosAngle(0.9962),
24 m_maxAsymmetryNClusters(2)
34 if (PandoraContentApi::GetSettings(*pAlgorithm)->ShouldDisplayAlgorithmInfo())
35 std::cout <<
"----> Running Algorithm Tool: " << this->GetInstanceName() <<
", " << this->GetType() << std::endl;
37 float localAsymmetry(0.
f);
40 slidingFitDataListMap.at(TPC_VIEW_U));
43 slidingFitDataListMap.at(TPC_VIEW_V));
46 slidingFitDataListMap.at(TPC_VIEW_W));
48 featureVector.push_back(localAsymmetry);
56 bool useEnergy(
true), useAsymmetry(
true);
57 CartesianVector energyWeightedDirectionSum(0.
f, 0.
f, 0.
f), hitWeightedDirectionSum(0.
f, 0.
f, 0.
f);
62 const Cluster *
const pCluster(slidingFitData.GetCluster());
64 if (pCluster->GetElectromagneticEnergy() < std::numeric_limits<float>::epsilon())
67 const CartesianVector vertexToMinLayer(slidingFitData.GetMinLayerPosition() - vertexPosition2D);
68 const CartesianVector vertexToMaxLayer(slidingFitData.GetMaxLayerPosition() - vertexPosition2D);
70 const bool minLayerClosest(vertexToMinLayer.GetMagnitudeSquared() < vertexToMaxLayer.GetMagnitudeSquared());
71 const CartesianVector &clusterDirection((minLayerClosest) ? slidingFitData.GetMinLayerDirection() : slidingFitData.GetMaxLayerDirection());
76 useAsymmetry &= this->
IncrementAsymmetryParameters(static_cast<float>(pCluster->GetNCaloHits()), clusterDirection, hitWeightedDirectionSum);
77 asymmetryClusters.push_back(pCluster);
85 if ((useEnergy && energyWeightedDirectionSum == CartesianVector(0.
f, 0.
f, 0.
f)) || (!useEnergy && hitWeightedDirectionSum == CartesianVector(0.
f, 0.
f, 0.
f)))
88 const CartesianVector &localWeightedDirectionSum(useEnergy ? energyWeightedDirectionSum : hitWeightedDirectionSum);
89 return this->
CalculateLocalAsymmetry(useEnergy, vertexPosition2D, asymmetryClusters, localWeightedDirectionSum);
95 CartesianVector &localWeightedDirectionSum)
const 98 CartesianVector newDirection(clusterDirection);
100 if (localWeightedDirectionSum.GetMagnitudeSquared() > std::numeric_limits<float>::epsilon())
102 const float cosOpeningAngle(localWeightedDirectionSum.GetCosOpeningAngle(clusterDirection));
106 if (cosOpeningAngle < 0.
f)
107 newDirection *= -1.f;
114 localWeightedDirectionSum += newDirection *
weight;
121 const ClusterVector &asymmetryClusters,
const CartesianVector &localWeightedDirectionSum)
const 127 float beforeVtxHitEnergy(0.
f), afterVtxHitEnergy(0.
f);
128 unsigned int beforeVtxHitCount(0), afterVtxHitCount(0);
130 const CartesianVector localWeightedDirection(localWeightedDirectionSum.GetUnitVector());
131 const float evtProjectedVtxPos(vertexPosition2D.GetDotProduct(localWeightedDirection));
133 for (
const Cluster *
const pCluster : asymmetryClusters)
135 CaloHitList caloHitList;
136 pCluster->GetOrderedCaloHitList().FillCaloHitList(caloHitList);
138 CaloHitVector caloHitVector(caloHitList.begin(), caloHitList.end());
141 for (
const CaloHit *
const pCaloHit : caloHitVector)
143 if (pCaloHit->GetPositionVector().GetDotProduct(localWeightedDirection) < evtProjectedVtxPos)
145 beforeVtxHitEnergy += pCaloHit->GetElectromagneticEnergy();
151 afterVtxHitEnergy += pCaloHit->GetElectromagneticEnergy();
158 const float totHitEnergy(afterVtxHitEnergy + beforeVtxHitEnergy);
159 const unsigned int totHitCount(beforeVtxHitCount + afterVtxHitCount);
161 if (useEnergyMetrics && (totHitEnergy > std::numeric_limits<float>::epsilon()))
162 return std::fabs((afterVtxHitEnergy - beforeVtxHitEnergy)) / totHitEnergy;
164 if (0 == totHitCount)
165 throw StatusCodeException(STATUS_CODE_FAILURE);
167 return std::fabs((static_cast<float>(afterVtxHitCount) - static_cast<float>(beforeVtxHitCount))) /
static_cast<float>(totHitCount);
174 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
177 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
180 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
183 return STATUS_CODE_SUCCESS;
float m_maxAsymmetryDistance
The max distance between cluster (any hit) and vertex to calculate asymmetry score.
MvaTypes::MvaFeatureVector MvaFeatureVector
float CalculateLocalAsymmetry(const bool useEnergyMetrics, const pandora::CartesianVector &vertexPosition2D, const pandora::ClusterVector &asymmetryClusters, const pandora::CartesianVector &localWeightedDirectionSum) const
Calculate the local asymmetry feature.
void Run(LArMvaHelper::MvaFeatureVector &featureVector, const VertexSelectionBaseAlgorithm *const pAlgorithm, const pandora::Vertex *const pVertex, const VertexSelectionBaseAlgorithm::SlidingFitDataListMap &slidingFitDataListMap, const VertexSelectionBaseAlgorithm::ClusterListMap &, const VertexSelectionBaseAlgorithm::KDTreeMap &, const VertexSelectionBaseAlgorithm::ShowerClusterListMap &, const float, float &)
Run the tool.
static pandora::CartesianVector ProjectPosition(const pandora::Pandora &pandora, const pandora::CartesianVector &position3D, const pandora::HitType view)
Project 3D position into a given 2D view.
float GetLocalAsymmetryForView(const pandora::CartesianVector &vertexPosition2D, const VertexSelectionBaseAlgorithm::SlidingFitDataList &slidingFitDataList) const
Get the local asymmetry feature in a given view.
std::vector< SlidingFitData > SlidingFitDataList
Header file for the geometry helper class.
std::map< pandora::HitType, const ShowerClusterList > ShowerClusterListMap
Map of shower cluster lists for passing to tools.
static bool SortHitsByPosition(const pandora::CaloHit *const pLhs, const pandora::CaloHit *const pRhs)
Sort calo hits by their position (use Z, followed by X, followed by Y)
Header file for the cluster helper class.
std::map< pandora::HitType, const pandora::ClusterList & > ClusterListMap
Map array of cluster lists for passing to tools.
bool IncrementAsymmetryParameters(const float weight, const pandora::CartesianVector &clusterDirection, pandora::CartesianVector &localWeightedDirectionSum) const
Increment the asymmetry parameters.
VertexSelectionBaseAlgorithm class.
std::vector< art::Ptr< recob::Cluster > > ClusterVector
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
std::map< pandora::HitType, const SlidingFitDataList > SlidingFitDataListMap
Map of sliding fit data lists for passing to tools.
float m_minAsymmetryCosAngle
The min opening angle cosine used to determine viability of asymmetry score.
std::map< pandora::HitType, const std::reference_wrapper< HitKDTree2D > > KDTreeMap
Map array of hit kd trees for passing to tools.
unsigned int m_maxAsymmetryNClusters
The max number of associated clusters to calculate the asymmetry.
static float GetClosestDistance(const pandora::ClusterList &clusterList1, const pandora::ClusterList &clusterList2)
Get closest distance between clusters in a pair of cluster lists.