9 #include "Pandora/AlgorithmHeaders.h" 18 LayerSplittingAlgorithm::LayerSplittingAlgorithm() :
19 m_minClusterLayers(20),
21 m_maxScatterRms(0.35
f),
22 m_maxScatterCosTheta(0.5
f),
23 m_maxSlidingCosTheta(0.866
f)
31 unsigned int splitLayer(0);
34 return this->
DivideCaloHits(pCluster, splitLayer, firstHitList, secondHitList);
36 return STATUS_CODE_NOT_FOUND;
43 const OrderedCaloHitList &orderedCaloHitList(pCluster->GetOrderedCaloHitList());
46 return STATUS_CODE_NOT_FOUND;
48 bool foundSplit(
false);
50 float bestCosTheta(1.
f);
51 CartesianVector bestPosition(0.
f,0.
f,0.
f);
53 for (
unsigned int iLayer = pCluster->GetInnerPseudoLayer() + 4; iLayer + 4 <= pCluster->GetOuterPseudoLayer(); ++iLayer)
55 if (orderedCaloHitList.find(iLayer) == orderedCaloHitList.end())
58 unsigned int innerLayer((pCluster->GetInnerPseudoLayer() +
m_layerWindow > iLayer) ? pCluster->GetInnerPseudoLayer() : iLayer -
m_layerWindow);
59 unsigned int outerLayer((iLayer +
m_layerWindow > pCluster->GetOuterPseudoLayer()) ? pCluster->GetOuterPseudoLayer() : iLayer +
m_layerWindow);
61 for ( ; innerLayer >= pCluster->GetInnerPseudoLayer(); --innerLayer)
63 if (orderedCaloHitList.find(innerLayer) != orderedCaloHitList.end())
67 for ( ; outerLayer <= pCluster->GetOuterPseudoLayer(); ++outerLayer)
69 if (orderedCaloHitList.find(outerLayer) != orderedCaloHitList.end())
73 const CartesianVector splitPosition(pCluster->GetCentroid(iLayer));
74 const CartesianVector innerPosition(pCluster->GetCentroid(innerLayer));
75 const CartesianVector outerPosition(pCluster->GetCentroid(outerLayer));
77 const CartesianVector r1(innerPosition - splitPosition);
78 const CartesianVector r2(outerPosition - splitPosition);
79 const CartesianVector p1(r1.GetUnitVector());
80 const CartesianVector p2(r2.GetUnitVector());
82 const float cosTheta(-p1.GetDotProduct(p2));
83 const float rms1(this->
CalculateRms(pCluster, innerLayer, iLayer));
84 const float rms2(this->
CalculateRms(pCluster, outerLayer, iLayer));
85 const float rms(
std::max(rms1, rms2));
100 if (rms < rmsCut && cosTheta < bestCosTheta)
102 bestCosTheta = cosTheta;
103 bestPosition = splitPosition;
111 return STATUS_CODE_NOT_FOUND;
113 return STATUS_CODE_SUCCESS;
120 const OrderedCaloHitList &orderedCaloHitList(pCluster->GetOrderedCaloHitList());
122 const unsigned int innerLayer(
std::min(firstLayer, secondLayer));
123 const unsigned int outerLayer(
std::max(firstLayer, secondLayer));
125 const CartesianVector innerPosition(pCluster->GetCentroid(innerLayer));
126 const CartesianVector outerPosition(pCluster->GetCentroid(outerLayer));
127 const CartesianVector predictedDirection((outerPosition - innerPosition).GetUnitVector());
129 float totalChi2(0.
f);
130 float totalLayers(0.
f);
132 for (
unsigned int iLayer = innerLayer + 1; iLayer + 1 < outerLayer; ++iLayer)
134 if (orderedCaloHitList.find(iLayer) == orderedCaloHitList.end())
137 const CartesianVector hitPosition(pCluster->GetCentroid(iLayer));
138 const CartesianVector predictedPosition(innerPosition + predictedDirection * predictedDirection.GetDotProduct(hitPosition - innerPosition));
140 totalChi2 += (predictedPosition - hitPosition).GetMagnitudeSquared();
144 if (totalLayers > 0.
f)
145 return std::sqrt(totalChi2/totalLayers);
154 const OrderedCaloHitList &orderedCaloHitList(pCluster->GetOrderedCaloHitList());
158 const unsigned int thisLayer(iter->first);
160 for (
CaloHitList::const_iterator hitIter = iter->second->begin(), hitIterEnd = iter->second->end(); hitIter != hitIterEnd; ++hitIter)
162 const CaloHit *
const pCaloHit = *hitIter;
164 if (thisLayer < splitLayer)
166 firstHitList.push_back(pCaloHit);
170 secondHitList.push_back(pCaloHit);
175 if (firstHitList.empty() || secondHitList.empty())
176 return STATUS_CODE_NOT_FOUND;
178 return STATUS_CODE_SUCCESS;
185 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
188 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
191 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
194 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
197 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
pandora::StatusCode FindBestSplitLayer(const pandora::Cluster *const pCluster, unsigned int &splitLayer) const
Find the best layer for splitting the cluster.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
unsigned int m_minClusterLayers
float m_maxScatterCosTheta
unsigned int m_layerWindow
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
float CalculateRms(const pandora::Cluster *const pCluster, const unsigned int &firstLayer, const unsigned int &secondLayer) const
Calculate rms deviation of cluster centroids between two extremal layers.
float m_maxSlidingCosTheta
pandora::StatusCode DivideCaloHits(const pandora::Cluster *const pCluster, pandora::CaloHitList &firstCaloHitList, pandora::CaloHitList &secondCaloHitList) const
Divide calo hits in a cluster into two lists, each associated with a separate fragment cluster...