9 #include "Pandora/AlgorithmHeaders.h"
29 m_slidingFitWindow(20),
30 m_minClusterCaloHits(5),
31 m_minClusterLengthSquared(3.f * 3.f)
47 TwoDSlidingFitResultMap::const_iterator iter = m_slidingFitResultMap.find(pCluster);
49 if (m_slidingFitResultMap.end() == iter)
50 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
60 bool changesMade(
false);
62 ClusterList splitClusters;
63 for (
const auto &mapEntry : splitPositionMap)
64 splitClusters.push_back(mapEntry.first);
67 for (
const Cluster *pCurrentCluster : splitClusters)
69 CartesianPointVector splitPositions(splitPositionMap.at(pCurrentCluster));
73 const std::string &clusterListName(this->GetClusterListName(hitType));
75 if (!((TPC_VIEW_U == hitType) || (TPC_VIEW_V == hitType) || (TPC_VIEW_W == hitType)))
76 throw StatusCodeException(STATUS_CODE_FAILURE);
78 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::ReplaceCurrentList<Cluster>(*
this, clusterListName));
80 for (
const CartesianVector &splitPosition : splitPositions)
82 const Cluster *pLowXCluster(
nullptr), *pHighXCluster(
nullptr);
83 this->UpdateUponDeletion(pCurrentCluster);
85 if (this->MakeClusterSplit(splitPosition, pCurrentCluster, pLowXCluster, pHighXCluster))
88 this->UpdateForNewCluster(pLowXCluster);
89 this->UpdateForNewCluster(pHighXCluster);
90 pCurrentCluster = pHighXCluster;
94 this->UpdateForNewCluster(pCurrentCluster);
104 template <
typename T>
106 const CartesianVector &splitPosition,
const Cluster *&pCurrentCluster,
const Cluster *&pLowXCluster,
const Cluster *&pHighXCluster)
const
108 CartesianVector lowXEnd(0.f, 0.f, 0.f), highXEnd(0.f, 0.f, 0.f);
117 catch (
const StatusCodeException &)
122 const CartesianVector lowXUnitVector((lowXEnd - splitPosition).GetUnitVector());
123 const CartesianVector highXUnitVector((highXEnd - splitPosition).GetUnitVector());
125 CaloHitList caloHitList;
126 pCurrentCluster->GetOrderedCaloHitList().FillCaloHitList(caloHitList);
128 std::string originalListName, fragmentListName;
129 const ClusterList clusterList(1, pCurrentCluster);
130 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::InitializeFragmentation(*
this, clusterList, originalListName, fragmentListName));
132 pLowXCluster =
nullptr;
133 pHighXCluster =
nullptr;
135 for (
const CaloHit *
const pCaloHit : caloHitList)
137 const CartesianVector unitVector((pCaloHit->GetPositionVector() - splitPosition).GetUnitVector());
138 const float dotProductLowX(unitVector.GetDotProduct(lowXUnitVector));
139 const float dotProductHighX(unitVector.GetDotProduct(highXUnitVector));
141 const Cluster *&pClusterToModify((dotProductLowX > dotProductHighX) ? pLowXCluster : pHighXCluster);
143 if (!pClusterToModify)
146 parameters.m_caloHitList.push_back(pCaloHit);
147 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::Cluster::Create(*
this, parameters, pClusterToModify));
151 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::AddToCluster(*
this, pClusterToModify, pCaloHit));
155 if (!pLowXCluster || !pHighXCluster)
157 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::EndFragmentation(*
this, originalListName, fragmentListName));
161 PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::EndFragmentation(*
this, fragmentListName, originalListName));
167 template <
typename T>
170 return (lhs.GetX() < rhs.GetX());
175 template <
typename T>
180 this->AddToSlidingFitCache(pNewCluster);
182 catch (
const StatusCodeException &statusCodeException)
184 if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
185 throw statusCodeException;
195 template <
typename T>
198 this->RemoveFromSlidingFitCache(pDeletedCluster);
204 template <
typename T>
207 for (
const Cluster *
const pCluster : *pInputClusterList)
209 if (!pCluster->IsAvailable())
212 if (pCluster->GetNCaloHits() < m_minClusterCaloHits)
218 selectedClusterList.push_back(pCluster);
224 template <
typename T>
227 for (ClusterList::iterator iter = preparedClusterList.begin(), iterEnd = preparedClusterList.end(); iter != iterEnd;)
231 this->AddToSlidingFitCache(*iter);
234 catch (
const StatusCodeException &statusCodeException)
236 preparedClusterList.erase(iter++);
238 if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
239 throw statusCodeException;
246 template <
typename T>
249 pfoParameters.m_particleId = MU_MINUS;
254 template <
typename T>
260 if (!m_slidingFitResultMap.insert(TwoDSlidingFitResultMap::value_type(pCluster, slidingFitResult)).second)
261 throw StatusCodeException(STATUS_CODE_FAILURE);
266 template <
typename T>
269 TwoDSlidingFitResultMap::iterator iter = m_slidingFitResultMap.find(pCluster);
271 if (m_slidingFitResultMap.end() != iter)
272 m_slidingFitResultMap.erase(iter);
277 template <
typename T>
280 m_slidingFitResultMap.clear();
286 template <
typename T>
289 PANDORA_RETURN_RESULT_IF_AND_IF(
290 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"SlidingFitWindow", m_slidingFitWindow));
292 PANDORA_RETURN_RESULT_IF_AND_IF(
293 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinClusterCaloHits", m_minClusterCaloHits));
295 float minClusterLength = std::sqrt(m_minClusterLengthSquared);
296 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle,
"MinClusterLength", minClusterLength));
297 m_minClusterLengthSquared = minClusterLength * minClusterLength;
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
static bool SortSplitPositions(const pandora::CartesianVector &lhs, const pandora::CartesianVector &rhs)
Sort split position cartesian vectors by increasing x coordinate.
static bool SortByNHits(const pandora::Cluster *const pLhs, const pandora::Cluster *const pRhs)
Sort clusters by number of hits, then layer span, then inner layer, then position, then pulse-height.
void AddToSlidingFitCache(const pandora::Cluster *const pCluster)
Add a new sliding fit result, for the specified cluster, to the algorithm cache.
NViewTrackMatchingAlgorithm class.
Header file for the n view track matching algorithm class.
virtual bool MakeClusterSplits(const SplitPositionMap &splitPositionMap)
Make cluster splits.
Header file for the lar pointing cluster class.
virtual void PrepareInputClusters(pandora::ClusterList &preparedClusterList)
Perform any preparatory steps required on the input clusters, e.g. caching expensive fit results...
virtual void UpdateUponDeletion(const pandora::Cluster *const pDeletedCluster)
Update to reflect cluster deletion.
const TwoDSlidingFitResult & GetCachedSlidingFitResult(const pandora::Cluster *const pCluster) const
Get a sliding fit result from the algorithm cache.
virtual void TidyUp()
Tidy member variables in derived class.
LArPointingCluster class.
virtual ~NViewTrackMatchingAlgorithm()
Destructor.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
virtual void TidyUp()
Tidy member variables in derived class.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
void UpdateUponDeletion(const pandora::Cluster *const pDeletedCluster)
Update to reflect cluster deletion.
Header file for the geometry helper class.
void UpdateForNewCluster(const pandora::Cluster *const pNewCluster)
Update to reflect addition of a new cluster to the problem space.
Header file for the cluster helper class.
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
const Vertex & GetOuterVertex() const
Get the outer vertex.
std::unordered_map< const pandora::Cluster *, pandora::CartesianPointVector > SplitPositionMap
const Vertex & GetInnerVertex() const
Get the inner vertex.
fhicl::Table< sbnd::crt::CRTDetSimParams > Parameters
void RemoveFromSlidingFitCache(const pandora::Cluster *const pCluster)
Remova an existing sliding fit result, for the specified cluster, from the algorithm cache...
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
Header file for the lar track overlap result class.
virtual void SetPfoParticleId(PandoraContentApi::ParticleFlowObject::Parameters &pfoParameters) const
Set pfo particle id.
virtual bool MakeClusterSplit(const pandora::CartesianVector &splitPosition, const pandora::Cluster *&pCurrentCluster, const pandora::Cluster *&pLowXCluster, const pandora::Cluster *&pHighXCluster) const
Make a cluster split.
Header file for the three view matching control class.
virtual void SelectInputClusters(const pandora::ClusterList *const pInputClusterList, pandora::ClusterList &selectedClusterList) const
Select a subset of input clusters for processing in this algorithm.
static float GetLengthSquared(const pandora::Cluster *const pCluster)
Get length squared of cluster.
Header file for the two view matching control class.
virtual void UpdateForNewCluster(const pandora::Cluster *const pNewCluster)
Update to reflect addition of a new cluster to the problem space.
Header file for the lar track two view overlap result class.
const pandora::CartesianVector & GetPosition() const
Get the vertex position.
TwoDSlidingFitResult class.