Calculate the energy deposition asymmetry feature.
30 float beforeVtxEnergy(0.
f), afterVtxEnergy(0.
f);
31 unsigned int beforeVtxHits(0), afterVtxHits(0);
33 const CartesianVector localWeightedDirection(localWeightedDirectionSum.GetUnitVector());
34 const float evtProjectedVtxPos(vertexPosition2D.GetDotProduct(localWeightedDirection));
36 float minBeforeProjectedPos(std::numeric_limits<float>::max());
37 float maxBeforeProjectedPos(-std::numeric_limits<float>::max());
39 float minAfterProjectedPos(std::numeric_limits<float>::max());
40 float maxAfterProjectedPos(-std::numeric_limits<float>::max());
42 for (
const Cluster *
const pCluster : clusterVector)
44 CaloHitList caloHitList;
45 pCluster->GetOrderedCaloHitList().FillCaloHitList(caloHitList);
47 CaloHitVector caloHitVector(caloHitList.begin(), caloHitList.end());
50 for (
const CaloHit *
const pCaloHit : caloHitVector)
52 if (pCaloHit->GetPositionVector().GetDotProduct(localWeightedDirection) < evtProjectedVtxPos)
54 minBeforeProjectedPos = std::min(minBeforeProjectedPos, pCaloHit->GetPositionVector().GetDotProduct(localWeightedDirection));
55 maxBeforeProjectedPos = std::max(maxBeforeProjectedPos, pCaloHit->GetPositionVector().GetDotProduct(localWeightedDirection));
57 beforeVtxEnergy += pCaloHit->GetElectromagneticEnergy();
63 minAfterProjectedPos = std::min(minAfterProjectedPos, pCaloHit->GetPositionVector().GetDotProduct(localWeightedDirection));
64 maxAfterProjectedPos = std::max(maxAfterProjectedPos, pCaloHit->GetPositionVector().GetDotProduct(localWeightedDirection));
66 afterVtxEnergy += pCaloHit->GetElectromagneticEnergy();
73 const unsigned int totalHits(beforeVtxHits + afterVtxHits);
75 const float beforeLength(std::fabs(maxBeforeProjectedPos - minBeforeProjectedPos));
76 const float afterLength(std::fabs(maxAfterProjectedPos - minAfterProjectedPos));
78 const float beforeVtxEnergyDeposition(beforeLength < std::numeric_limits<float>::epsilon() ? 0 : beforeVtxEnergy / beforeLength);
80 const float afterVtxEnergyDeposition(afterLength < std::numeric_limits<float>::epsilon() ? 0 : afterVtxEnergy / afterLength);
82 const float totalEnergyDeposition(beforeVtxEnergyDeposition + afterVtxEnergyDeposition);
84 if (useEnergyMetrics && totalEnergyDeposition > std::numeric_limits<float>::epsilon())
85 return std::fabs((afterVtxEnergyDeposition - beforeVtxEnergyDeposition)) / totalEnergyDeposition;
88 throw StatusCodeException(STATUS_CODE_FAILURE);
90 const float beforeVtxHitDeposition(beforeLength < std::numeric_limits<float>::epsilon() ? 0 : beforeVtxHits / beforeLength);
92 const float afterVtxHitDeposition(afterLength < std::numeric_limits<float>::epsilon() ? 0 : afterVtxHits / afterLength);
94 const float totalHitDeposition(beforeVtxHitDeposition + afterVtxHitDeposition);
96 if (totalHitDeposition > std::numeric_limits<float>::epsilon())
97 return std::fabs((afterVtxHitDeposition - beforeVtxHitDeposition)) / totalHitDeposition;
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)