9 #include "Pandora/AlgorithmHeaders.h" 21 ThreeDShowersAlgorithm::ThreeDShowersAlgorithm() :
22 m_nMaxTensorToolRepeats(1000),
23 m_slidingFitWindow(20),
24 m_ignoreUnavailableClusters(true),
25 m_minClusterCaloHits(5),
26 m_minClusterLengthSquared(3.
f * 3.
f),
27 m_minShowerMatchedFraction(0.2
f),
28 m_minShowerMatchedPoints(20)
39 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
52 catch (StatusCodeException &statusCodeException)
54 if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
55 throw statusCodeException;
77 const Cluster *
const pCluster = *iter;
88 selectedClusterList.push_back(pCluster);
97 pfoParameters.m_particleId = E_MINUS;
98 pfoParameters.m_charge = PdgTable::GetParticleCharge(pfoParameters.m_particleId.Get());
99 pfoParameters.m_mass = PdgTable::GetParticleMass(pfoParameters.m_particleId.Get());
100 pfoParameters.m_energy = 0.f;
101 pfoParameters.m_momentum = CartesianVector(0.
f, 0.
f, 0.
f);
102 pfoParameters.m_clusterList.insert(pfoParameters.m_clusterList.end(), protoParticle.
m_clusterListU.begin(), protoParticle.
m_clusterListU.end());
103 pfoParameters.m_clusterList.insert(pfoParameters.m_clusterList.end(), protoParticle.
m_clusterListV.begin(), protoParticle.
m_clusterListV.end());
104 pfoParameters.m_clusterList.insert(pfoParameters.m_clusterList.end(), protoParticle.
m_clusterListW.begin(), protoParticle.
m_clusterListW.end());
120 for (
ClusterList::iterator iter = clusterList.begin(), iterEnd = clusterList.end(); iter != iterEnd; )
122 const Cluster *
const pCluster(*iter);
129 catch (StatusCodeException &statusCodeException)
131 clusterList.erase(iter++);
133 if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
134 throw statusCodeException;
154 if (!
m_slidingFitResultMap.insert(TwoDSlidingShowerFitResultMap::value_type(pCluster, slidingShowerFitResult)).second)
155 throw StatusCodeException(STATUS_CODE_FAILURE);
173 PANDORA_THROW_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, this->
CalculateOverlapResult(pClusterU, pClusterV, pClusterW, overlapResult));
189 if (xSampling.m_xOverlapSpan < std::numeric_limits<float>::epsilon())
190 return STATUS_CODE_NOT_FOUND;
193 this->
GetShowerPositionMaps(fitResultU, fitResultV, fitResultW, xSampling, positionMapsU, positionMapsV, positionMapsW);
195 unsigned int nSampledHitsU(0), nMatchedHitsU(0);
198 unsigned int nSampledHitsV(0), nMatchedHitsV(0);
201 unsigned int nSampledHitsW(0), nMatchedHitsW(0);
204 const unsigned int nMatchedHits(nMatchedHitsU + nMatchedHitsV + nMatchedHitsW);
205 const unsigned int nSampledHits(nSampledHitsU + nSampledHitsV + nSampledHitsW);
207 if (0 == nSampledHits)
208 return STATUS_CODE_NOT_FOUND;
210 const XOverlap xOverlapObject(xSampling.m_uMinX, xSampling.m_uMaxX, xSampling.m_vMinX, xSampling.m_vMaxX, xSampling.m_wMinX, xSampling.m_wMaxX, xSampling.m_xOverlapSpan);
214 return STATUS_CODE_NOT_FOUND;
216 overlapResult = showerOverlapResult;
217 return STATUS_CODE_SUCCESS;
226 const unsigned int nPoints(static_cast<unsigned int>(xSampling.
m_nPoints));
228 for (
unsigned n = 0;
n <= nPoints; ++
n)
230 const float x(xSampling.
m_minX + (xSampling.
m_maxX - xSampling.
m_minX) * static_cast<float>(
n) / static_cast<float>(nPoints));
233 if (STATUS_CODE_SUCCESS != xSampling.
GetBin(x, xBin))
236 FloatVector uValues, vValues, wValues;
241 std::sort(uValues.begin(), uValues.end());
242 std::sort(vValues.begin(), vValues.end());
243 std::sort(wValues.begin(), wValues.end());
245 if ((uValues.size() > 1) && (vValues.size() > 1))
247 const float uMin(uValues.front()), uMax(uValues.back());
248 const float vMin(vValues.front()), vMax(vValues.back());
253 positionMapsW.first.insert(ShowerPositionMap::value_type(xBin,
ShowerExtent(x, uv2wMinMin, uv2wMaxMax)));
254 positionMapsW.second.insert(ShowerPositionMap::value_type(xBin,
ShowerExtent(x, uv2wMinMax, uv2wMaxMin)));
257 if ((uValues.size() > 1) && (wValues.size() > 1))
259 const float uMin(uValues.front()), uMax(uValues.back());
260 const float wMin(wValues.front()), wMax(wValues.back());
265 positionMapsV.first.insert(ShowerPositionMap::value_type(xBin,
ShowerExtent(x, uw2vMinMin, uw2vMaxMax)));
266 positionMapsV.second.insert(ShowerPositionMap::value_type(xBin,
ShowerExtent(x, uw2vMinMax, uw2vMaxMin)));
269 if ((vValues.size() > 1) && (wValues.size() > 1))
271 const float vMin(vValues.front()), vMax(vValues.back());
272 const float wMin(wValues.front()), wMax(wValues.back());
277 positionMapsU.first.insert(ShowerPositionMap::value_type(xBin,
ShowerExtent(x, vw2uMinMin, vw2uMaxMax)));
278 positionMapsU.second.insert(ShowerPositionMap::value_type(xBin,
ShowerExtent(x, vw2uMinMax, vw2uMaxMin)));
286 unsigned int &nSampledHits,
unsigned int &nMatchedHits)
const 288 if ((xSampling.
m_maxX - xSampling.
m_minX) < std::numeric_limits<float>::epsilon())
289 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
291 nSampledHits = 0; nMatchedHits = 0;
292 unsigned int nMatchedHits1(0), nMatchedHits2(0);
293 const OrderedCaloHitList &orderedCaloHitList(pCluster->GetOrderedCaloHitList());
299 const CaloHit *
const pCaloHit = *hIter;
300 const float x(pCaloHit->GetPositionVector().GetX());
301 const float z(pCaloHit->GetPositionVector().GetZ());
304 if (STATUS_CODE_SUCCESS != xSampling.
GetBin(
x, xBin))
312 if ((positionMaps.first.end() != positionIter1) && (
z > positionIter1->second.GetLowEdgeZ()) && (z < positionIter1->second.GetHighEdgeZ()))
315 if ((positionMaps.second.end() != positionIter2) && (
z > positionIter2->second.GetLowEdgeZ()) && (z < positionIter2->second.GetHighEdgeZ()))
320 nMatchedHits =
std::max(nMatchedHits1, nMatchedHits2);
327 unsigned int repeatCounter(0);
356 m_xOverlapSpan = (m_maxX - m_minX);
359 if (m_xOverlapSpan > std::numeric_limits<float>::epsilon())
361 const float nPointsU(std::fabs((m_xOverlapSpan / (m_uMaxX - m_uMinX)) * static_cast<float>(fitResultU.
GetMaxLayer() - fitResultU.
GetMinLayer())));
362 const float nPointsV(std::fabs((m_xOverlapSpan / (m_vMaxX - m_vMinX)) * static_cast<float>(fitResultV.
GetMaxLayer() - fitResultV.
GetMinLayer())));
363 const float nPointsW(std::fabs((m_xOverlapSpan / (m_wMaxX - m_wMinX)) * static_cast<float>(fitResultW.
GetMaxLayer() - fitResultW.
GetMinLayer())));
364 m_nPoints = 1.f + ((nPointsU + nPointsV + nPointsW) / 3.
f);
372 if (((x - m_minX) < -std::numeric_limits<float>::epsilon()) || ((x - m_maxX) > +std::numeric_limits<float>::epsilon()))
373 return STATUS_CODE_NOT_FOUND;
375 xBin =
static_cast<int>(0.5f + m_nPoints * (x - m_minX) / (m_maxX - m_minX));
376 return STATUS_CODE_SUCCESS;
384 AlgorithmToolVector algorithmToolVector;
385 PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmToolList(*
this, xmlHandle,
386 "ShowerTools", algorithmToolVector));
390 ShowerTensorTool *
const pShowerTensorTool(dynamic_cast<ShowerTensorTool*>(*iter));
392 if (NULL == pShowerTensorTool)
393 return STATUS_CODE_INVALID_PARAMETER;
398 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
401 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
404 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
407 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
411 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
412 "MinClusterLength", minClusterLength));
415 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
418 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
bool IsInitialized() const
Whether the track overlap result has been initialized.
pandora::ClusterList m_clusterListW
The selected modified cluster list W.
void GetMinAndMaxX(float &minX, float &maxX) const
Get the minimum and maximum x coordinates associated with the sliding fit.
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
void PreparationStep()
Perform any preparatory steps required, e.g. caching expensive fit results for clusters.
const TwoDSlidingFitResult & GetShowerFitResult() const
Get the sliding fit result for the full shower cluster.
void UpdateUponDeletion(const pandora::Cluster *const pDeletedCluster)
Update to reflect cluster deletion.
void UpdateForNewCluster(const pandora::Cluster *const pNewCluster)
Update to reflect addition of a new cluster to the problem space.
bool m_ignoreUnavailableClusters
Whether to ignore (skip-over) unavailable clusters.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
TwoDSlidingShowerFitResult class.
pandora::ClusterList m_clusterListV
The selected modified cluster list V.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Header file for the geometry helper class.
pandora::ClusterList m_clusterListW
List of 2D W clusters in a 3D proto particle.
float m_minClusterLengthSquared
The min length (squared) in base cluster selection method.
const TwoDSlidingShowerFitResult & GetCachedSlidingFitResult(const pandora::Cluster *const pCluster) const
Get a sliding shower fit result from the algorithm cache.
void SetOverlapResult(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV, const pandora::Cluster *const pClusterW, const OverlapResult &overlapResult)
Set overlap result.
ShowerOverlapResult class.
int GetMaxLayer() const
Get the maximum occupied layer in the sliding fit.
int GetMinLayer() const
Get the minimum occupied layer in the sliding fit.
Header file for the cluster helper class.
TensorType m_overlapTensor
The overlap tensor.
float m_nPoints
The number of sampling points to be used.
unsigned int m_minShowerMatchedPoints
The minimum number of matched shower sampling points to allow shower grouping.
TensorToolVector m_algorithmToolVector
The algorithm tool vector.
pandora::ClusterList m_clusterListV
List of 2D V clusters in a 3D proto particle.
void SetPfoParameters(const ProtoParticle &protoParticle, PandoraContentApi::ParticleFlowObject::Parameters &pfoParameters) const
Calculate Pfo properties from proto particle.
static float MergeTwoPositions(const pandora::Pandora &pandora, const pandora::HitType view1, const pandora::HitType view2, const float position1, const float position2)
Merge two views (U,V) to give a third view (Z).
unsigned int GetNMatchedSamplingPoints() const
Get the number of matched sampling points.
pandora::ClusterList m_clusterListU
List of 2D U clusters in a 3D proto particle.
virtual void TidyUp()
Tidy member variables in derived class.
float m_maxX
The max x value of the common x-overlap range.
void ExamineTensor()
Examine contents of tensor, collect together best-matching 2D particles and modify clusters as requir...
unsigned int m_slidingFitWindow
The layer window for the sliding linear fits.
void TidyUp()
Tidy member variables in derived class.
std::pair< ShowerPositionMap, ShowerPositionMap > ShowerPositionMapPair
virtual void UpdateUponDeletion(const pandora::Cluster *const pDeletedCluster)
Update to reflect cluster deletion.
virtual void UpdateForNewCluster(const pandora::Cluster *const pNewCluster)
Update to reflect addition of a new cluster to the problem space.
pandora::ClusterList m_clusterListU
The selected modified cluster list U.
static float GetLengthSquared(const pandora::Cluster *const pCluster)
Get length squared of cluster.
void RemoveFromSlidingFitCache(const pandora::Cluster *const pCluster)
Remova an existing sliding fit result, for the specified cluster, from the algorithm cache...
void SelectInputClusters(const pandora::ClusterList *const pInputClusterList, pandora::ClusterList &selectedClusterList) const
Select a subset of input clusters for processing in this algorithm.
Header file for the three dimensional showers algorithm class.
TwoDSlidingShowerFitResultMap m_slidingFitResultMap
The sliding shower fit result map.
float GetMatchedFraction() const
Get the fraction of sampling points resulting in a match.
unsigned int m_nMaxTensorToolRepeats
The maximum number of repeat loops over tensor tools.
pandora::StatusCode GetBin(const float x, int &xBin) const
Convert an x position into a sampling bin.
void CalculateOverlapResult(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV, const pandora::Cluster *const pClusterW)
Calculate cluster overlap result and store in tensor.
void AddToSlidingFitCache(const pandora::Cluster *const pCluster)
Add a new sliding fit result, for the specified cluster, to the algorithm cache.
void GetBestHitOverlapFraction(const pandora::Cluster *const pCluster, const XSampling &xSampling, const ShowerPositionMapPair &positionMaps, unsigned int &nSampledHits, unsigned int &nMatchedHits) const
Get the best fraction of hits, in the common x-overlap range, contained within the provided pair of s...
void GetShowerPositionMaps(const TwoDSlidingShowerFitResult &fitResultU, const TwoDSlidingShowerFitResult &fitResultV, const TwoDSlidingShowerFitResult &fitResultW, const XSampling &xSampling, ShowerPositionMapPair &positionMapsU, ShowerPositionMapPair &positionMapsV, ShowerPositionMapPair &positionMapsW) const
Get the shower position maps.
unsigned int m_minClusterCaloHits
The min number of hits in base cluster selection method.
XSampling(const TwoDSlidingFitResult &fitResultU, const TwoDSlidingFitResult &fitResultV, const TwoDSlidingFitResult &fitResultW)
Constructor.
TwoDSlidingFitResult class.
float m_minShowerMatchedFraction
The minimum shower matched sampling fraction to allow shower grouping.
void GetShowerEdges(const float x, const bool widenIfAmbiguity, pandora::FloatVector &edgePositions) const
Get the most appropriate shower edges at a given x coordinate.
float m_minX
The min x value of the common x-overlap range.