9 #include "Pandora/PandoraInputTypes.h"
11 #include "Pandora/PandoraInputTypes.h"
12 #include "Pandora/PandoraInternal.h"
13 #include "Pandora/StatusCodes.h"
15 #include "Objects/Cluster.h"
33 if ((hitType != TPC_VIEW_U) && (hitType != TPC_VIEW_V) && (hitType != TPC_VIEW_W))
34 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
36 return (hitType == TPC_VIEW_U) ? m_pClusterU : (hitType == TPC_VIEW_V) ? m_pClusterV : m_pClusterW;
44 for (
typename TheTensor::const_iterator iterU = this->
begin(), iterUEnd = this->
end(); iterU != iterUEnd; ++iterU)
47 ClusterList clusterListU, clusterListV, clusterListW;
48 this->GetConnectedElements(iterU->first, ignoreUnavailable, tempElementList, clusterListU, clusterListV, clusterListW);
50 const Cluster *pClusterU(
nullptr), *pClusterV(
nullptr), *pClusterW(
nullptr);
51 if (!this->DefaultAmbiguityFunction(clusterListU, clusterListV, clusterListW, pClusterU, pClusterV, pClusterW))
55 if (iterU->first != pClusterU)
58 if (!pClusterU || !pClusterV || !pClusterW)
62 if (iterU->second.end() == iterV)
63 throw StatusCodeException(STATUS_CODE_FAILURE);
65 typename OverlapList::const_iterator iterW = iterV->second.find(pClusterW);
66 if (iterV->second.end() == iterW)
67 throw StatusCodeException(STATUS_CODE_FAILURE);
70 elementList.push_back(element);
73 std::sort(elementList.begin(), elementList.end());
80 const ClusterList &clusterListW,
const Cluster *&pClusterU,
const Cluster *&pClusterV,
const Cluster *&pClusterW)
const
82 if ((1 != clusterListU.size()) || (1 != clusterListV.size()) || (1 != clusterListW.size()))
85 pClusterU = *(clusterListU.begin());
86 pClusterV = *(clusterListV.begin());
87 pClusterW = *(clusterListW.begin());
96 unsigned int &nU,
unsigned int &nV,
unsigned int &nW)
const
98 ClusterList clusterListU, clusterListV, clusterListW;
99 this->GetConnectedElements(pCluster, ignoreUnavailable, elementList, clusterListU, clusterListV, clusterListW);
100 nU = clusterListU.size();
101 nV = clusterListV.size();
102 nW = clusterListW.size();
107 template <
typename T>
110 for (
typename TheTensor::const_iterator iterU = this->
begin(), iterUEnd = this->
end(); iterU != iterUEnd; ++iterU)
111 sortedKeyClusters.push_back(iterU->first);
113 std::sort(sortedKeyClusters.begin(), sortedKeyClusters.end(), LArClusterHelper::SortByNHits);
118 template <
typename T>
120 const pandora::Cluster *
const pClusterW,
const OverlapResult &overlapResult)
122 OverlapList &overlapList = m_overlapTensor[pClusterU][pClusterV];
123 typename OverlapList::const_iterator iter = overlapList.find(pClusterW);
125 if (overlapList.end() != iter)
126 throw pandora::StatusCodeException(pandora::STATUS_CODE_ALREADY_PRESENT);
128 if (!overlapList.insert(
typename OverlapList::value_type(pClusterW, overlapResult)).second)
129 throw pandora::StatusCodeException(pandora::STATUS_CODE_FAILURE);
131 ClusterList &navigationUV(m_clusterNavigationMapUV[pClusterU]);
132 ClusterList &navigationVW(m_clusterNavigationMapVW[pClusterV]);
133 ClusterList &navigationWU(m_clusterNavigationMapWU[pClusterW]);
135 if (navigationUV.end() == std::find(navigationUV.begin(), navigationUV.end(), pClusterV))
136 navigationUV.push_back(pClusterV);
137 if (navigationVW.end() == std::find(navigationVW.begin(), navigationVW.end(), pClusterW))
138 navigationVW.push_back(pClusterW);
139 if (navigationWU.end() == std::find(navigationWU.begin(), navigationWU.end(), pClusterU))
140 navigationWU.push_back(pClusterU);
145 template <
typename T>
147 const pandora::Cluster *
const pClusterW,
const OverlapResult &overlapResult)
149 typename TheTensor::iterator iterU = m_overlapTensor.find(pClusterU);
151 if (m_overlapTensor.end() == iterU)
152 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
154 typename OverlapMatrix::iterator iterV = iterU->second.find(pClusterV);
156 if (iterU->second.end() == iterV)
157 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
159 typename OverlapList::iterator iterW = iterV->second.find(pClusterW);
161 if (iterV->second.end() == iterW)
162 throw pandora::StatusCodeException(pandora::STATUS_CODE_INVALID_PARAMETER);
164 iterW->second = overlapResult;
169 template <
typename T>
172 ClusterList additionalRemovals;
174 if (m_clusterNavigationMapUV.erase(pCluster) > 0)
176 typename TheTensor::iterator iter = m_overlapTensor.find(pCluster);
178 if (m_overlapTensor.end() != iter)
179 m_overlapTensor.erase(iter);
181 for (ClusterNavigationMap::iterator navIter = m_clusterNavigationMapWU.begin(); navIter != m_clusterNavigationMapWU.end();)
183 ClusterNavigationMap::iterator thisIter = navIter++;
184 ClusterList::iterator listIter = std::find(thisIter->second.begin(), thisIter->second.end(), pCluster);
186 if (thisIter->second.end() != listIter)
187 thisIter->second.erase(listIter);
189 if (thisIter->second.empty())
190 additionalRemovals.push_back(thisIter->first);
194 if (m_clusterNavigationMapVW.erase(pCluster) > 0)
196 for (
typename TheTensor::iterator iterU = m_overlapTensor.begin(), iterUEnd = m_overlapTensor.end(); iterU != iterUEnd; ++iterU)
198 typename OverlapMatrix::iterator iter = iterU->second.find(pCluster);
200 if (iterU->second.end() != iter)
201 iterU->second.erase(iter);
204 for (ClusterNavigationMap::iterator navIter = m_clusterNavigationMapUV.begin(); navIter != m_clusterNavigationMapUV.end();)
206 ClusterNavigationMap::iterator thisIter = navIter++;
207 ClusterList::iterator listIter = std::find(thisIter->second.begin(), thisIter->second.end(), pCluster);
209 if (thisIter->second.end() != listIter)
210 thisIter->second.erase(listIter);
212 if (thisIter->second.empty())
213 additionalRemovals.push_back(thisIter->first);
217 if (m_clusterNavigationMapWU.erase(pCluster) > 0)
219 for (
typename TheTensor::iterator iterU = m_overlapTensor.begin(), iterUEnd = m_overlapTensor.end(); iterU != iterUEnd; ++iterU)
221 for (
typename OverlapMatrix::iterator iterV = iterU->second.begin(), iterVEnd = iterU->second.end(); iterV != iterVEnd; ++iterV)
223 typename OverlapList::iterator iter = iterV->second.find(pCluster);
225 if (iterV->second.end() != iter)
226 iterV->second.erase(iter);
230 for (ClusterNavigationMap::iterator navIter = m_clusterNavigationMapVW.begin(); navIter != m_clusterNavigationMapVW.end();)
232 ClusterNavigationMap::iterator thisIter = navIter++;
233 ClusterList::iterator listIter = std::find(thisIter->second.begin(), thisIter->second.end(), pCluster);
235 if (thisIter->second.end() != listIter)
236 thisIter->second.erase(listIter);
238 if (thisIter->second.empty())
239 additionalRemovals.push_back(thisIter->first);
243 additionalRemovals.sort(LArClusterHelper::SortByNHits);
245 for (ClusterList::const_iterator iter = additionalRemovals.begin(), iterEnd = additionalRemovals.end(); iter != iterEnd; ++iter)
246 this->RemoveCluster(*iter);
251 template <
typename T>
253 ClusterList &clusterListU, ClusterList &clusterListV, ClusterList &clusterListW)
const
255 ClusterList localClusterListU, localClusterListV, localClusterListW;
256 this->ExploreConnections(pCluster, ignoreUnavailable, localClusterListU, localClusterListV, localClusterListW);
260 clusterListU.clear();
261 clusterListV.clear();
262 clusterListW.clear();
264 for (
typename TheTensor::const_iterator iterU = this->
begin(), iterUEnd = this->
end(); iterU != iterUEnd; ++iterU)
266 if (localClusterListU.end() == std::find(localClusterListU.begin(), localClusterListU.end(), iterU->first))
271 for (
typename OverlapList::const_iterator iterW = iterV->second.begin(), iterWEnd = iterV->second.end(); iterW != iterWEnd; ++iterW)
273 if (ignoreUnavailable && (!iterU->first->IsAvailable() || !iterV->first->IsAvailable() || !iterW->first->IsAvailable()))
276 Element
element(iterU->first, iterV->first, iterW->first, iterW->second);
277 elementList.push_back(
element);
279 if (clusterListU.end() == std::find(clusterListU.begin(), clusterListU.end(), iterU->first))
280 clusterListU.push_back(iterU->first);
281 if (clusterListV.end() == std::find(clusterListV.begin(), clusterListV.end(), iterV->first))
282 clusterListV.push_back(iterV->first);
283 if (clusterListW.end() == std::find(clusterListW.begin(), clusterListW.end(), iterW->first))
284 clusterListW.push_back(iterW->first);
289 std::sort(elementList.begin(), elementList.end());
294 template <
typename T>
296 ClusterList &clusterListV, ClusterList &clusterListW)
const
298 if (ignoreUnavailable && !pCluster->IsAvailable())
301 const HitType hitType(LArClusterHelper::GetClusterHitType(pCluster));
303 if (!((TPC_VIEW_U == hitType) || (TPC_VIEW_V == hitType) || (TPC_VIEW_W == hitType)))
304 throw StatusCodeException(STATUS_CODE_FAILURE);
306 ClusterList &clusterList((TPC_VIEW_U == hitType) ? clusterListU : (TPC_VIEW_V == hitType) ? clusterListV : clusterListW);
308 (TPC_VIEW_U == hitType) ? m_clusterNavigationMapUV : (TPC_VIEW_V == hitType) ? m_clusterNavigationMapVW : m_clusterNavigationMapWU);
310 if (clusterList.end() != std::find(clusterList.begin(), clusterList.end(), pCluster))
313 clusterList.push_back(pCluster);
314 ClusterNavigationMap::const_iterator iter = navigationMap.find(pCluster);
316 if (navigationMap.end() == iter)
317 throw StatusCodeException(STATUS_CODE_FAILURE);
319 for (ClusterList::const_iterator cIter = iter->second.begin(), cIterEnd = iter->second.end(); cIter != cIterEnd; ++cIter)
320 this->ExploreConnections(*cIter, ignoreUnavailable, clusterListU, clusterListV, clusterListW);
Header file for the lar overlap tensor class.
std::vector< Element > ElementList
Header file for the cluster helper class.
auto end(FixedBins< T, C > const &) noexcept
TheMatrix::const_iterator const_iterator
Header file for the lar shower overlap result class.
auto begin(FixedBins< T, C > const &) noexcept
required by fuzzyCluster table::sbnd_g4_services gaushitTruthMatch pandora
std::unordered_map< const pandora::Cluster *, OverlapResult > OverlapList
Header file for the lar track overlap result class.
std::unordered_map< const pandora::Cluster *, pandora::ClusterList > ClusterNavigationMap
std::vector< art::Ptr< recob::Cluster > > ClusterVector