All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Public Types | Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | List of all members
lar_content::ThreeViewTrackFragmentsAlgorithm Class Reference

ThreeViewTrackFragmentsAlgorithm class. More...

#include <ThreeViewTrackFragmentsAlgorithm.h>

Inheritance diagram for lar_content::ThreeViewTrackFragmentsAlgorithm:
lar_content::NViewTrackMatchingAlgorithm< ThreeViewMatchingControl< FragmentOverlapResult > > lar_content::NViewMatchingAlgorithm< ThreeViewMatchingControl< FragmentOverlapResult > > lar_content::MatchingBaseAlgorithm

Public Types

typedef
NViewTrackMatchingAlgorithm
< ThreeViewMatchingControl
< FragmentOverlapResult > > 
BaseAlgorithm
 
- Public Types inherited from lar_content::NViewMatchingAlgorithm< ThreeViewMatchingControl< FragmentOverlapResult > >
typedef
ThreeViewMatchingControl
< FragmentOverlapResult
MatchingType
 

Public Member Functions

 ThreeViewTrackFragmentsAlgorithm ()
 Default constructor. More...
 
void UpdateForNewCluster (const pandora::Cluster *const pNewCluster)
 Update to reflect addition of a new cluster to the problem space. More...
 
void RebuildClusters (const pandora::ClusterList &rebuildList, pandora::ClusterList &newClusters) const
 Rebuild clusters after fragmentation. More...
 
- Public Member Functions inherited from lar_content::NViewTrackMatchingAlgorithm< ThreeViewMatchingControl< FragmentOverlapResult > >
 NViewTrackMatchingAlgorithm ()
 Default constructor. More...
 
virtual ~NViewTrackMatchingAlgorithm ()
 Destructor. More...
 
const TwoDSlidingFitResultGetCachedSlidingFitResult (const pandora::Cluster *const pCluster) const
 Get a sliding fit result from the algorithm cache. More...
 
unsigned int GetSlidingFitWindow () const
 Get the layer window for the sliding linear fits. More...
 
virtual bool MakeClusterSplits (const SplitPositionMap &splitPositionMap)
 Make cluster splits. More...
 
virtual bool MakeClusterSplit (const pandora::CartesianVector &splitPosition, const pandora::Cluster *&pCurrentCluster, const pandora::Cluster *&pLowXCluster, const pandora::Cluster *&pHighXCluster) const
 Make a cluster split. More...
 
virtual void UpdateUponDeletion (const pandora::Cluster *const pDeletedCluster)
 Update to reflect cluster deletion. More...
 
virtual void SelectInputClusters (const pandora::ClusterList *const pInputClusterList, pandora::ClusterList &selectedClusterList) const
 Select a subset of input clusters for processing in this algorithm. More...
 
virtual void PrepareInputClusters (pandora::ClusterList &preparedClusterList)
 Perform any preparatory steps required on the input clusters, e.g. caching expensive fit results. More...
 
virtual void SetPfoParticleId (PandoraContentApi::ParticleFlowObject::Parameters &pfoParameters) const
 Set pfo particle id. More...
 
- Public Member Functions inherited from lar_content::NViewMatchingAlgorithm< ThreeViewMatchingControl< FragmentOverlapResult > >
 NViewMatchingAlgorithm ()
 Default constructor. More...
 
virtual ~NViewMatchingAlgorithm ()
 Destructor. More...
 
const std::string & GetClusterListName (const pandora::HitType hitType) const
 Get the cluster list name corresponding to a specified hit type. More...
 
const pandora::ClusterList & GetInputClusterList (const pandora::HitType hitType) const
 Get the input cluster list corresponding to a specified hit type. More...
 
const pandora::ClusterList & GetSelectedClusterList (const pandora::HitType hitType) const
 Get the selected cluster list corresponding to a specified hit type. More...
 
- Public Member Functions inherited from lar_content::MatchingBaseAlgorithm
 MatchingBaseAlgorithm ()
 Default constructor. More...
 
virtual ~MatchingBaseAlgorithm ()
 Destructor. More...
 
virtual bool MakeClusterMerges (const ClusterMergeMap &clusterMergeMap)
 Merge clusters together. More...
 
virtual bool CreateThreeDParticles (const ProtoParticleVector &protoParticleVector)
 Create particles using findings from recent algorithm processing. More...
 
virtual void SetPfoParameters (const ProtoParticle &protoParticle, PandoraContentApi::ParticleFlowObject::Parameters &pfoParameters) const
 Set Pfo properties. More...
 

Protected Types

typedef std::unordered_map
< const pandora::CaloHit
*, const pandora::Cluster * > 
HitToClusterMap
 
typedef std::unordered_map
< const pandora::Cluster
*, unsigned int > 
ClusterToMatchedHitsMap
 
typedef std::vector
< FragmentTensorTool * > 
TensorToolVector
 

Protected Member Functions

void PerformMainLoop ()
 Main loop over cluster combinations in order to populate the overlap container. Responsible for calling CalculateOverlapResult. More...
 
void CalculateOverlapResult (const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV, const pandora::Cluster *const pClusterW)
 Calculate cluster overlap result and store in container. More...
 
pandora::StatusCode CalculateOverlapResult (const TwoDSlidingFitResult &fitResult1, const TwoDSlidingFitResult &fitResult2, const pandora::ClusterList &inputClusterList, const pandora::Cluster *&pBestMatchedCluster, FragmentOverlapResult &fragmentOverlapResult) const
 Calculate overlap result for track fragment candidate consisting of two sliding fit results and a list of available clusters. More...
 
pandora::StatusCode GetProjectedPositions (const TwoDSlidingFitResult &fitResult1, const TwoDSlidingFitResult &fitResult2, pandora::CartesianPointVector &projectedPositions) const
 Get the list of projected positions, in the third view, corresponding to a pair of sliding fit results. More...
 
pandora::StatusCode GetMatchedHits (const pandora::ClusterList &inputClusterList, const pandora::CartesianPointVector &projectedPositions, HitToClusterMap &hitToClusterMap, pandora::CaloHitList &matchedCaloHits) const
 Get the list of hits associated with the projected positions and a useful hit to cluster map. More...
 
pandora::StatusCode GetMatchedClusters (const pandora::CaloHitList &matchedHits, const HitToClusterMap &hitToClusterMap, pandora::ClusterList &matchedClusters, const pandora::Cluster *&pBestMatchedCluster) const
 Get the list of the relevant clusters and the address of the single best matched cluster. More...
 
void GetFragmentOverlapResult (const pandora::CartesianPointVector &projectedPositions, const pandora::CaloHitList &matchedHits, const pandora::ClusterList &matchedClusters, FragmentOverlapResult &fragmentOverlapResult) const
 Get the populated fragment overlap result. More...
 
bool CheckMatchedClusters (const pandora::CartesianPointVector &projectedPositions, const pandora::ClusterList &matchedClusters) const
 Whether the matched clusters are consistent with the projected positions. More...
 
bool CheckOverlapResult (const FragmentOverlapResult &overlapResult) const
 Whether the matched clusters and hits pass the algorithm quality cuts. More...
 
void ExamineOverlapContainer ()
 Examine contents of overlap container, collect together best-matching 2D particles and modify clusters as required. More...
 
pandora::StatusCode ReadSettings (const pandora::TiXmlHandle xmlHandle)
 
- Protected Member Functions inherited from lar_content::NViewTrackMatchingAlgorithm< ThreeViewMatchingControl< FragmentOverlapResult > >
void AddToSlidingFitCache (const pandora::Cluster *const pCluster)
 Add a new sliding fit result, for the specified cluster, to the algorithm cache. More...
 
void RemoveFromSlidingFitCache (const pandora::Cluster *const pCluster)
 Remova an existing sliding fit result, for the specified cluster, from the algorithm cache. More...
 
virtual void TidyUp ()
 Tidy member variables in derived class. More...
 
- Protected Member Functions inherited from lar_content::NViewMatchingAlgorithm< ThreeViewMatchingControl< FragmentOverlapResult > >
MatchingTypeGetMatchingControl ()
 Get the matching control. More...
 
virtual void SelectAllInputClusters ()
 Select a subset of input clusters for processing in this algorithm. More...
 
virtual void PrepareAllInputClusters ()
 Perform any preparatory steps required, e.g. caching expensive fit results for clusters. More...
 

Protected Attributes

std::string m_reclusteringAlgorithmName
 Name of daughter algorithm to use for cluster re-building. More...
 
TensorToolVector m_algorithmToolVector
 The algorithm tool list. More...
 
unsigned int m_nMaxTensorToolRepeats
 The maximum number of repeat loops over tensor tools. More...
 
float m_minXOverlap
 requirement on minimum X overlap for associated clusters More...
 
float m_minXOverlapFraction
 requirement on minimum X overlap fraction for associated clusters More...
 
float m_maxPointDisplacementSquared
 maximum allowed distance (squared) between projected points and associated hits More...
 
float m_minMatchedSamplingPointFraction
 minimum fraction of matched sampling points More...
 
unsigned int m_minMatchedHits
 minimum number of matched calo hits More...
 
- Protected Attributes inherited from lar_content::NViewMatchingAlgorithm< ThreeViewMatchingControl< FragmentOverlapResult > >
MatchingType m_matchingControl
 The matching control. More...
 

Additional Inherited Members

- Static Public Member Functions inherited from lar_content::NViewTrackMatchingAlgorithm< ThreeViewMatchingControl< FragmentOverlapResult > >
static bool SortSplitPositions (const pandora::CartesianVector &lhs, const pandora::CartesianVector &rhs)
 Sort split position cartesian vectors by increasing x coordinate. More...
 

Detailed Description

ThreeViewTrackFragmentsAlgorithm class.

Definition at line 31 of file ThreeViewTrackFragmentsAlgorithm.h.

Member Typedef Documentation

Definition at line 34 of file ThreeViewTrackFragmentsAlgorithm.h.

typedef std::unordered_map<const pandora::Cluster *, unsigned int> lar_content::ThreeViewTrackFragmentsAlgorithm::ClusterToMatchedHitsMap
protected

Definition at line 142 of file ThreeViewTrackFragmentsAlgorithm.h.

typedef std::unordered_map<const pandora::CaloHit *, const pandora::Cluster *> lar_content::ThreeViewTrackFragmentsAlgorithm::HitToClusterMap
protected

Definition at line 69 of file ThreeViewTrackFragmentsAlgorithm.h.

Definition at line 146 of file ThreeViewTrackFragmentsAlgorithm.h.

Constructor & Destructor Documentation

lar_content::ThreeViewTrackFragmentsAlgorithm::ThreeViewTrackFragmentsAlgorithm ( )

Default constructor.

Definition at line 21 of file ThreeViewTrackFragmentsAlgorithm.cc.

21  :
23  m_minXOverlap(3.f),
25  m_maxPointDisplacementSquared(1.5f * 1.5f),
28 {
29 }
unsigned int m_minMatchedHits
minimum number of matched calo hits
unsigned int m_nMaxTensorToolRepeats
The maximum number of repeat loops over tensor tools.
float m_minXOverlapFraction
requirement on minimum X overlap fraction for associated clusters
float m_maxPointDisplacementSquared
maximum allowed distance (squared) between projected points and associated hits
float m_minXOverlap
requirement on minimum X overlap for associated clusters
float m_minMatchedSamplingPointFraction
minimum fraction of matched sampling points

Member Function Documentation

void lar_content::ThreeViewTrackFragmentsAlgorithm::CalculateOverlapResult ( const pandora::Cluster *const  pCluster1,
const pandora::Cluster *const  pCluster2,
const pandora::Cluster *const  pCluster3 
)
protectedvirtual

Calculate cluster overlap result and store in container.

Parameters
pCluster1address of cluster1
pCluster2address of cluster2
pCluster3address of cluster3

Implements lar_content::MatchingBaseAlgorithm.

pandora::StatusCode lar_content::ThreeViewTrackFragmentsAlgorithm::CalculateOverlapResult ( const TwoDSlidingFitResult fitResult1,
const TwoDSlidingFitResult fitResult2,
const pandora::ClusterList &  inputClusterList,
const pandora::Cluster *&  pBestMatchedCluster,
FragmentOverlapResult fragmentOverlapResult 
) const
protected

Calculate overlap result for track fragment candidate consisting of two sliding fit results and a list of available clusters.

Parameters
fitResult1the first sliding fit result
fitResult2the second sliding fit result
inputClusterListthe input cluster list
pBestMatchedClusterto receive the address of the best matched cluster
fragmentOverlapResultto receive the populated fragment overlap result
Returns
statusCode, faster than throwing in regular use-cases
bool lar_content::ThreeViewTrackFragmentsAlgorithm::CheckMatchedClusters ( const pandora::CartesianPointVector &  projectedPositions,
const pandora::ClusterList &  matchedClusters 
) const
protected

Whether the matched clusters are consistent with the projected positions.

Parameters
projectedPositionsthe list of projected positions
matchedClustersthe list of matched clusters
Returns
boolean

Definition at line 554 of file ThreeViewTrackFragmentsAlgorithm.cc.

555 {
556  if (projectedPositions.empty() || matchedClusters.empty())
557  return false;
558 
559  // Calculate X and Z span of projected positions
560  float minXproj(+std::numeric_limits<float>::max());
561  float maxXproj(-std::numeric_limits<float>::max());
562  float minZproj(+std::numeric_limits<float>::max());
563  float maxZproj(-std::numeric_limits<float>::max());
564 
565  for (const CartesianVector &projectedPosition : projectedPositions)
566  {
567  minXproj = std::min(minXproj, projectedPosition.GetX());
568  maxXproj = std::max(maxXproj, projectedPosition.GetX());
569  minZproj = std::min(minZproj, projectedPosition.GetZ());
570  maxZproj = std::max(maxZproj, projectedPosition.GetZ());
571  }
572 
573  const float dXproj(maxXproj - minXproj);
574  const float dZproj(maxZproj - minZproj);
575  const float projectedLengthSquared(dXproj * dXproj + dZproj * dZproj);
576 
577  // Calculate X and Z span of matched clusters
578  float minXcluster(+std::numeric_limits<float>::max());
579  float maxXcluster(-std::numeric_limits<float>::max());
580  float minZcluster(+std::numeric_limits<float>::max());
581  float maxZcluster(-std::numeric_limits<float>::max());
582 
583  for (const Cluster *const pCluster : matchedClusters)
584  {
585  CartesianVector minPosition(0.f, 0.f, 0.f);
586  CartesianVector maxPosition(0.f, 0.f, 0.f);
587 
588  LArClusterHelper::GetClusterBoundingBox(pCluster, minPosition, maxPosition);
589 
590  minXcluster = std::min(minXcluster, minPosition.GetX());
591  maxXcluster = std::max(maxXcluster, maxPosition.GetX());
592  minZcluster = std::min(minZcluster, minPosition.GetZ());
593  maxZcluster = std::max(maxZcluster, maxPosition.GetZ());
594  }
595 
596  const float dXcluster(maxXcluster - minXcluster);
597  const float dZcluster(maxZcluster - minZcluster);
598  const float clusterLengthSquared(dXcluster * dXcluster + dZcluster * dZcluster);
599 
600  // Require that the span of the matched clusters is no larger than twice the span of the projected positions
601  if (clusterLengthSquared > 4.f * projectedLengthSquared)
602  return false;
603 
604  return true;
605 }
static void GetClusterBoundingBox(const pandora::Cluster *const pCluster, pandora::CartesianVector &minimumCoordinate, pandora::CartesianVector &maximumCoordinate)
Get minimum and maximum X, Y and Z positions of the calo hits in a cluster.
bool lar_content::ThreeViewTrackFragmentsAlgorithm::CheckOverlapResult ( const FragmentOverlapResult overlapResult) const
protected

Whether the matched clusters and hits pass the algorithm quality cuts.

Parameters
fragmentOverlapResultthe fragment overlap result
Returns
boolean

Definition at line 609 of file ThreeViewTrackFragmentsAlgorithm.cc.

610 {
611  // ATTN This method is currently mirrored in ClearTrackFragments tool
612  if (overlapResult.GetMatchedFraction() < m_minMatchedSamplingPointFraction)
613  return false;
614 
615  if (overlapResult.GetFragmentCaloHitList().size() < m_minMatchedHits)
616  return false;
617 
618  return true;
619 }
unsigned int m_minMatchedHits
minimum number of matched calo hits
float m_minMatchedSamplingPointFraction
minimum fraction of matched sampling points
void lar_content::ThreeViewTrackFragmentsAlgorithm::ExamineOverlapContainer ( )
protectedvirtual

Examine contents of overlap container, collect together best-matching 2D particles and modify clusters as required.

Implements lar_content::MatchingBaseAlgorithm.

Definition at line 623 of file ThreeViewTrackFragmentsAlgorithm.cc.

624 {
625  unsigned int repeatCounter(0);
626 
627  for (TensorToolVector::const_iterator iter = m_algorithmToolVector.begin(), iterEnd = m_algorithmToolVector.end(); iter != iterEnd;)
628  {
629  if ((*iter)->Run(this, this->GetMatchingControl().GetOverlapTensor()))
630  {
631  iter = m_algorithmToolVector.begin();
632 
633  if (++repeatCounter > m_nMaxTensorToolRepeats)
634  break;
635  }
636  else
637  {
638  ++iter;
639  }
640  }
641 }
createEngine this
TensorToolVector m_algorithmToolVector
The algorithm tool list.
unsigned int m_nMaxTensorToolRepeats
The maximum number of repeat loops over tensor tools.
void lar_content::ThreeViewTrackFragmentsAlgorithm::GetFragmentOverlapResult ( const pandora::CartesianPointVector &  projectedPositions,
const pandora::CaloHitList &  matchedHits,
const pandora::ClusterList &  matchedClusters,
FragmentOverlapResult fragmentOverlapResult 
) const
protected

Get the populated fragment overlap result.

Parameters
projectedPositionsthe list of projected positions
matchedHitsthe list of matched hits
matchedClustersthe list of matched clusters
fragmentOverlapResultto receive the populated fragment overlap result

Definition at line 521 of file ThreeViewTrackFragmentsAlgorithm.cc.

523 {
524  float chi2Sum(0.f);
525  unsigned int nMatchedSamplingPoints(0);
526 
527  CaloHitVector sortedMatchedHits(matchedHits.begin(), matchedHits.end());
528  std::sort(sortedMatchedHits.begin(), sortedMatchedHits.end(), LArClusterHelper::SortHitsByPosition);
529 
530  for (const CartesianVector &projectedPosition : projectedPositions)
531  {
532  float closestDistanceSquared(std::numeric_limits<float>::max());
533 
534  for (const CaloHit *const pCaloHit : matchedHits)
535  {
536  const float distanceSquared((pCaloHit->GetPositionVector() - projectedPosition).GetMagnitudeSquared());
537 
538  if (distanceSquared < closestDistanceSquared)
539  closestDistanceSquared = distanceSquared;
540  }
541 
542  if (closestDistanceSquared < m_maxPointDisplacementSquared)
543  {
544  ++nMatchedSamplingPoints;
545  chi2Sum += closestDistanceSquared;
546  }
547  }
548 
549  fragmentOverlapResult = FragmentOverlapResult(nMatchedSamplingPoints, projectedPositions.size(), chi2Sum, matchedHits, matchedClusters);
550 }
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)
float m_maxPointDisplacementSquared
maximum allowed distance (squared) between projected points and associated hits
StatusCode lar_content::ThreeViewTrackFragmentsAlgorithm::GetMatchedClusters ( const pandora::CaloHitList &  matchedHits,
const HitToClusterMap hitToClusterMap,
pandora::ClusterList &  matchedClusters,
const pandora::Cluster *&  pBestMatchedCluster 
) const
protected

Get the list of the relevant clusters and the address of the single best matched cluster.

Parameters
matchedHitsthe list of matched calo hits
hitToClusterMapthe hit to cluster map
matchedClustersto receive the list of matched clusters
pBestMatchedClusterto receive the address of the single best matched cluster
Returns
statusCode, faster than throwing in regular use-cases

Definition at line 470 of file ThreeViewTrackFragmentsAlgorithm.cc.

472 {
473  ClusterToMatchedHitsMap clusterToMatchedHitsMap;
474 
475  for (CaloHitList::const_iterator iter = matchedHits.begin(), iterEnd = matchedHits.end(); iter != iterEnd; ++iter)
476  {
477  const CaloHit *const pCaloHit = *iter;
478  HitToClusterMap::const_iterator cIter = hitToClusterMap.find(pCaloHit);
479 
480  if (hitToClusterMap.end() == cIter)
481  throw StatusCodeException(STATUS_CODE_FAILURE);
482 
483  ++clusterToMatchedHitsMap[cIter->second];
484 
485  if (matchedClusters.end() == std::find(matchedClusters.begin(), matchedClusters.end(), cIter->second))
486  matchedClusters.push_back(cIter->second);
487  }
488 
489  if (matchedClusters.empty())
490  return STATUS_CODE_NOT_FOUND;
491 
492  pBestMatchedCluster = nullptr;
493  unsigned int bestClusterMatchedHits(0);
494  float tieBreakerBestEnergy(0.f);
495 
496  ClusterVector sortedClusters;
497  for (const auto &mapEntry : clusterToMatchedHitsMap)
498  sortedClusters.push_back(mapEntry.first);
499  std::sort(sortedClusters.begin(), sortedClusters.end(), LArClusterHelper::SortByNHits);
500 
501  for (const Cluster *const pCluster : sortedClusters)
502  {
503  const unsigned int nMatchedHits(clusterToMatchedHitsMap.at(pCluster));
504 
505  if ((nMatchedHits > bestClusterMatchedHits) || ((nMatchedHits == bestClusterMatchedHits) && (pCluster->GetHadronicEnergy() > tieBreakerBestEnergy)))
506  {
507  pBestMatchedCluster = pCluster;
508  bestClusterMatchedHits = nMatchedHits;
509  tieBreakerBestEnergy = pCluster->GetHadronicEnergy();
510  }
511  }
512 
513  if (nullptr == pBestMatchedCluster)
514  return STATUS_CODE_NOT_FOUND;
515 
516  return STATUS_CODE_SUCCESS;
517 }
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.
std::unordered_map< const pandora::Cluster *, unsigned int > ClusterToMatchedHitsMap
std::vector< art::Ptr< recob::Cluster > > ClusterVector
StatusCode lar_content::ThreeViewTrackFragmentsAlgorithm::GetMatchedHits ( const pandora::ClusterList &  inputClusterList,
const pandora::CartesianPointVector &  projectedPositions,
HitToClusterMap hitToClusterMap,
pandora::CaloHitList &  matchedCaloHits 
) const
protected

Get the list of hits associated with the projected positions and a useful hit to cluster map.

Parameters
inputClusterListthe input cluster list
projectedPositionsthe list of projected positions
hitToClusterMapto receive the hit to cluster map
matchedCaloHitsto receive the list of associated calo hits
Returns
statusCode, faster than throwing in regular use-cases

Definition at line 416 of file ThreeViewTrackFragmentsAlgorithm.cc.

418 {
419  CaloHitVector availableCaloHits;
420 
421  for (ClusterList::const_iterator iter = inputClusterList.begin(), iterEnd = inputClusterList.end(); iter != iterEnd; ++iter)
422  {
423  const Cluster *const pCluster = *iter;
424 
425  if (!pCluster->IsAvailable())
426  continue;
427 
428  CaloHitList caloHitList;
429  pCluster->GetOrderedCaloHitList().FillCaloHitList(caloHitList);
430  availableCaloHits.insert(availableCaloHits.end(), caloHitList.begin(), caloHitList.end());
431 
432  for (CaloHitList::const_iterator hIter = caloHitList.begin(), hIterEnd = caloHitList.end(); hIter != hIterEnd; ++hIter)
433  hitToClusterMap.insert(HitToClusterMap::value_type(*hIter, pCluster));
434  }
435 
436  std::sort(availableCaloHits.begin(), availableCaloHits.end(), LArClusterHelper::SortHitsByPosition);
437 
438  for (const CartesianVector &projectedPosition : projectedPositions)
439  {
440  const CaloHit *pClosestCaloHit(nullptr);
441  float closestDistanceSquared(std::numeric_limits<float>::max()), tieBreakerBestEnergy(0.f);
442 
443  for (const CaloHit *const pCaloHit : availableCaloHits)
444  {
445  const float distanceSquared((pCaloHit->GetPositionVector() - projectedPosition).GetMagnitudeSquared());
446 
447  if ((distanceSquared < closestDistanceSquared) ||
448  ((std::fabs(distanceSquared - closestDistanceSquared) < std::numeric_limits<float>::epsilon()) &&
449  (pCaloHit->GetHadronicEnergy() > tieBreakerBestEnergy)))
450  {
451  pClosestCaloHit = pCaloHit;
452  closestDistanceSquared = distanceSquared;
453  tieBreakerBestEnergy = pCaloHit->GetHadronicEnergy();
454  }
455  }
456 
457  if ((closestDistanceSquared < m_maxPointDisplacementSquared) && (nullptr != pClosestCaloHit) &&
458  (matchedHits.end() == std::find(matchedHits.begin(), matchedHits.end(), pClosestCaloHit)))
459  matchedHits.push_back(pClosestCaloHit);
460  }
461 
462  if (matchedHits.empty())
463  return STATUS_CODE_NOT_FOUND;
464 
465  return STATUS_CODE_SUCCESS;
466 }
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)
float m_maxPointDisplacementSquared
maximum allowed distance (squared) between projected points and associated hits
StatusCode lar_content::ThreeViewTrackFragmentsAlgorithm::GetProjectedPositions ( const TwoDSlidingFitResult fitResult1,
const TwoDSlidingFitResult fitResult2,
pandora::CartesianPointVector &  projectedPositions 
) const
protected

Get the list of projected positions, in the third view, corresponding to a pair of sliding fit results.

Parameters
fitResult1the first sliding fit result
fitResult2the second sliding fit result
projectedPositionsto receive the list of projected positions
Returns
statusCode, faster than throwing in regular use-cases

Definition at line 273 of file ThreeViewTrackFragmentsAlgorithm.cc.

275 {
276  const Cluster *const pCluster1(fitResult1.GetCluster());
277  const Cluster *const pCluster2(fitResult2.GetCluster());
278 
279  // Check hit types
280  const HitType hitType1(LArClusterHelper::GetClusterHitType(pCluster1));
281  const HitType hitType2(LArClusterHelper::GetClusterHitType(pCluster2));
282  const HitType hitType3((TPC_VIEW_U != hitType1 && TPC_VIEW_U != hitType2)
283  ? TPC_VIEW_U
284  : (TPC_VIEW_V != hitType1 && TPC_VIEW_V != hitType2)
285  ? TPC_VIEW_V
286  : (TPC_VIEW_W != hitType1 && TPC_VIEW_W != hitType2) ? TPC_VIEW_W : HIT_CUSTOM);
287 
288  if (HIT_CUSTOM == hitType3)
289  return STATUS_CODE_INVALID_PARAMETER;
290 
291  // Check absolute and fractional overlap in x coordinate
292  float xMin1(0.f), xMax1(0.f), xMin2(0.f), xMax2(0.f);
293  pCluster1->GetClusterSpanX(xMin1, xMax1);
294  pCluster2->GetClusterSpanX(xMin2, xMax2);
295 
296  const float xOverlap(std::min(xMax1, xMax2) - std::max(xMin1, xMin2));
297  const float xSpan(std::max(xMax1, xMax2) - std::min(xMin1, xMin2));
298 
299  if ((xOverlap < m_minXOverlap) || (xSpan < std::numeric_limits<float>::epsilon()) || ((xOverlap / xSpan) < m_minXOverlapFraction))
300  return STATUS_CODE_NOT_FOUND;
301 
302  // Identify vertex and end positions (2D)
303  const CartesianVector minPosition1(fitResult1.GetGlobalMinLayerPosition());
304  const CartesianVector maxPosition1(fitResult1.GetGlobalMaxLayerPosition());
305  const CartesianVector minPosition2(fitResult2.GetGlobalMinLayerPosition());
306  const CartesianVector maxPosition2(fitResult2.GetGlobalMaxLayerPosition());
307 
308  const float dx_A(std::fabs(minPosition2.GetX() - minPosition1.GetX()));
309  const float dx_B(std::fabs(maxPosition2.GetX() - maxPosition1.GetX()));
310  const float dx_C(std::fabs(maxPosition2.GetX() - minPosition1.GetX()));
311  const float dx_D(std::fabs(minPosition2.GetX() - maxPosition1.GetX()));
312 
313  if (std::min(dx_C, dx_D) > std::max(dx_A, dx_B) && std::min(dx_A, dx_B) > std::max(dx_C, dx_D))
314  return STATUS_CODE_NOT_FOUND;
315 
316  const CartesianVector &vtxPosition1(minPosition1);
317  const CartesianVector &endPosition1(maxPosition1);
318  const CartesianVector &vtxPosition2((dx_A < dx_C) ? minPosition2 : maxPosition2);
319  const CartesianVector &endPosition2((dx_A < dx_C) ? maxPosition2 : minPosition2);
320 
321  // Calculate vertex and end positions (3D)
322  float vtxChi2(0.f);
323  CartesianVector vtxPosition3D(0.f, 0.f, 0.f);
324  LArGeometryHelper::MergeTwoPositions3D(this->GetPandora(), hitType1, hitType2, vtxPosition1, vtxPosition2, vtxPosition3D, vtxChi2);
325 
326  float endChi2(0.f);
327  CartesianVector endPosition3D(0.f, 0.f, 0.f);
328  LArGeometryHelper::MergeTwoPositions3D(this->GetPandora(), hitType1, hitType2, endPosition1, endPosition2, endPosition3D, endChi2);
329 
330  const CartesianVector vtxProjection3(LArGeometryHelper::ProjectPosition(this->GetPandora(), vtxPosition3D, hitType3));
331  const CartesianVector endProjection3(LArGeometryHelper::ProjectPosition(this->GetPandora(), endPosition3D, hitType3));
332 
333  const float samplingPitch(0.5f * LArGeometryHelper::GetWireZPitch(this->GetPandora()));
334  const float nSamplingPoints((endProjection3 - vtxProjection3).GetMagnitude() / samplingPitch);
335 
336  if (nSamplingPoints < 1.f)
337  return STATUS_CODE_NOT_FOUND;
338 
339  // Loop over trajectory points
340  bool foundLastPosition(false);
341  CartesianVector lastPosition(0.f, 0.f, 0.f);
342 
343  for (float iSample = 0.5f; iSample < nSamplingPoints; iSample += 1.f)
344  {
345  const CartesianVector linearPosition3D(vtxPosition3D + (endPosition3D - vtxPosition3D) * (iSample / nSamplingPoints));
346  const CartesianVector linearPosition1(LArGeometryHelper::ProjectPosition(this->GetPandora(), linearPosition3D, hitType1));
347  const CartesianVector linearPosition2(LArGeometryHelper::ProjectPosition(this->GetPandora(), linearPosition3D, hitType2));
348 
349  float chi2(0.f);
350  CartesianVector fitPosition1(0.f, 0.f, 0.f), fitPosition2(0.f, 0.f, 0.f);
351 
352  if ((STATUS_CODE_SUCCESS != fitResult1.GetGlobalFitProjection(linearPosition1, fitPosition1)) ||
353  (STATUS_CODE_SUCCESS != fitResult2.GetGlobalFitProjection(linearPosition2, fitPosition2)))
354  {
355  continue;
356  }
357 
358  float rL1(0.f), rL2(0.f), rT1(0.f), rT2(0.f);
359  fitResult1.GetLocalPosition(fitPosition1, rL1, rT1);
360  fitResult2.GetLocalPosition(fitPosition2, rL2, rT2);
361 
362  const float x(0.5 * (fitPosition1.GetX() + fitPosition2.GetX()));
363  CartesianVector position1(0.f, 0.f, 0.f), position2(0.f, 0.f, 0.f), position3(0.f, 0.f, 0.f);
364 
365  try
366  {
367  const FitSegment &fitSegment1 = fitResult1.GetFitSegment(rL1);
368  const FitSegment &fitSegment2 = fitResult2.GetFitSegment(rL2);
369 
370  if ((STATUS_CODE_SUCCESS != fitResult1.GetTransverseProjection(x, fitSegment1, position1)) ||
371  (STATUS_CODE_SUCCESS != fitResult2.GetTransverseProjection(x, fitSegment2, position2)))
372  {
373  continue;
374  }
375  }
376  catch (StatusCodeException &statusCodeException)
377  {
378  if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
379  throw statusCodeException;
380 
381  continue;
382  }
383 
384  LArGeometryHelper::MergeTwoPositions(this->GetPandora(), hitType1, hitType2, position1, position2, position3, chi2);
385 
386  // TODO For highly multi-valued x, projected positions can be unreliable. Need to make interpolation more robust for these cases.
387  if (foundLastPosition)
388  {
389  const float thisDisplacement((lastPosition - position3).GetMagnitude());
390  if (thisDisplacement > 2.f * samplingPitch)
391  {
392  const float nExtraPoints(thisDisplacement / samplingPitch);
393  for (float iExtra = 0.5f; iExtra < nExtraPoints; iExtra += 1.f)
394  {
395  const CartesianVector extraPosition(position3 + (lastPosition - position3) * (iExtra / nExtraPoints));
396  projectedPositions.push_back(extraPosition);
397  }
398  }
399  }
400 
401  projectedPositions.push_back(position3);
402 
403  lastPosition = position3;
404  foundLastPosition = true;
405  }
406 
407  // Bail out if list of projected positions is empty
408  if (projectedPositions.empty())
409  return STATUS_CODE_NOT_FOUND;
410 
411  return STATUS_CODE_SUCCESS;
412 }
static void MergeTwoPositions3D(const pandora::Pandora &pandora, const pandora::HitType view1, const pandora::HitType view2, const pandora::CartesianVector &position1, const pandora::CartesianVector &position2, pandora::CartesianVector &position3D, float &chiSquared)
Merge 2D positions from two views to give unified 3D position.
process_name opflash particleana ie x
static pandora::CartesianVector ProjectPosition(const pandora::Pandora &pandora, const pandora::CartesianVector &position3D, const pandora::HitType view)
Project 3D position into a given 2D view.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
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).
float m_minXOverlapFraction
requirement on minimum X overlap fraction for associated clusters
float m_minXOverlap
requirement on minimum X overlap for associated clusters
void lar_content::ThreeViewTrackFragmentsAlgorithm::PerformMainLoop ( )
protectedvirtual

Main loop over cluster combinations in order to populate the overlap container. Responsible for calling CalculateOverlapResult.

Reimplemented from lar_content::NViewMatchingAlgorithm< ThreeViewMatchingControl< FragmentOverlapResult > >.

Definition at line 117 of file ThreeViewTrackFragmentsAlgorithm.cc.

118 {
119  ClusterList clusterListU(this->GetSelectedClusterList(TPC_VIEW_U));
120  ClusterList clusterListV(this->GetSelectedClusterList(TPC_VIEW_V));
121  ClusterList clusterListW(this->GetSelectedClusterList(TPC_VIEW_W));
122  clusterListU.sort(LArClusterHelper::SortByNHits);
123  clusterListV.sort(LArClusterHelper::SortByNHits);
124  clusterListW.sort(LArClusterHelper::SortByNHits);
125 
126  for (const Cluster *const pClusterU : clusterListU)
127  {
128  for (const Cluster *const pClusterV : clusterListV)
129  this->CalculateOverlapResult(pClusterU, pClusterV, nullptr);
130  }
131 
132  for (const Cluster *const pClusterU : clusterListU)
133  {
134  for (const Cluster *const pClusterW : clusterListW)
135  this->CalculateOverlapResult(pClusterU, nullptr, pClusterW);
136  }
137 
138  for (const Cluster *const pClusterV : clusterListV)
139  {
140  for (const Cluster *const pClusterW : clusterListW)
141  this->CalculateOverlapResult(nullptr, pClusterV, pClusterW);
142  }
143 }
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 CalculateOverlapResult(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV, const pandora::Cluster *const pClusterW)
Calculate cluster overlap result and store in container.
const pandora::ClusterList & GetSelectedClusterList(const pandora::HitType hitType) const
Get the selected cluster list corresponding to a specified hit type.
StatusCode lar_content::ThreeViewTrackFragmentsAlgorithm::ReadSettings ( const pandora::TiXmlHandle  xmlHandle)
protectedvirtual

Reimplemented from lar_content::NViewTrackMatchingAlgorithm< ThreeViewMatchingControl< FragmentOverlapResult > >.

Definition at line 645 of file ThreeViewTrackFragmentsAlgorithm.cc.

646 {
647  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithm(*this, xmlHandle, "ClusterRebuilding", m_reclusteringAlgorithmName));
648 
649  AlgorithmToolVector algorithmToolVector;
650  PANDORA_RETURN_RESULT_IF(STATUS_CODE_SUCCESS, !=, XmlHelper::ProcessAlgorithmToolList(*this, xmlHandle, "TrackTools", algorithmToolVector));
651 
652  for (AlgorithmToolVector::const_iterator iter = algorithmToolVector.begin(), iterEnd = algorithmToolVector.end(); iter != iterEnd; ++iter)
653  {
654  FragmentTensorTool *const pFragmentTensorTool(dynamic_cast<FragmentTensorTool *>(*iter));
655 
656  if (!pFragmentTensorTool)
657  return STATUS_CODE_INVALID_PARAMETER;
658 
659  m_algorithmToolVector.push_back(pFragmentTensorTool);
660  }
661 
662  PANDORA_RETURN_RESULT_IF_AND_IF(
663  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "NMaxTensorToolRepeats", m_nMaxTensorToolRepeats));
664 
665  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinXOverlap", m_minXOverlap));
666 
667  PANDORA_RETURN_RESULT_IF_AND_IF(
668  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinXOverlapFraction", m_minXOverlapFraction));
669 
670  float maxPointDisplacement = std::sqrt(m_maxPointDisplacementSquared);
671  PANDORA_RETURN_RESULT_IF_AND_IF(
672  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxPointDisplacement", maxPointDisplacement));
673  m_maxPointDisplacementSquared = maxPointDisplacement * maxPointDisplacement;
674 
675  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=,
676  XmlHelper::ReadValue(xmlHandle, "MinMatchedSamplingPointFraction", m_minMatchedSamplingPointFraction));
677 
678  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinMatchedHits", m_minMatchedHits));
679 
680  return BaseAlgorithm::ReadSettings(xmlHandle);
681 }
virtual pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
unsigned int m_minMatchedHits
minimum number of matched calo hits
std::string m_reclusteringAlgorithmName
Name of daughter algorithm to use for cluster re-building.
TensorToolVector m_algorithmToolVector
The algorithm tool list.
unsigned int m_nMaxTensorToolRepeats
The maximum number of repeat loops over tensor tools.
float m_minXOverlapFraction
requirement on minimum X overlap fraction for associated clusters
float m_maxPointDisplacementSquared
maximum allowed distance (squared) between projected points and associated hits
float m_minXOverlap
requirement on minimum X overlap for associated clusters
float m_minMatchedSamplingPointFraction
minimum fraction of matched sampling points
void lar_content::ThreeViewTrackFragmentsAlgorithm::RebuildClusters ( const pandora::ClusterList &  rebuildList,
pandora::ClusterList &  newClusters 
) const

Rebuild clusters after fragmentation.

Parameters
rebuildListthe list of clusters containing hits to be rebuilt
newClustersthe output list of clusters

Definition at line 102 of file ThreeViewTrackFragmentsAlgorithm.cc.

103 {
104  const ClusterList *pNewClusterList = nullptr;
105  std::string oldClusterListName, newClusterListName;
106 
107  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::InitializeReclustering(*this, TrackList(), rebuildList, oldClusterListName));
108  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=,
109  PandoraContentApi::RunClusteringAlgorithm(*this, m_reclusteringAlgorithmName, pNewClusterList, newClusterListName));
110 
111  newClusters.insert(newClusters.end(), pNewClusterList->begin(), pNewClusterList->end());
112  PANDORA_THROW_RESULT_IF(STATUS_CODE_SUCCESS, !=, PandoraContentApi::EndReclustering(*this, newClusterListName));
113 }
std::string m_reclusteringAlgorithmName
Name of daughter algorithm to use for cluster re-building.
void lar_content::ThreeViewTrackFragmentsAlgorithm::UpdateForNewCluster ( const pandora::Cluster *const  pNewCluster)
virtual

Update to reflect addition of a new cluster to the problem space.

Parameters
pNewClusteraddress of the new cluster

Reimplemented from lar_content::NViewTrackMatchingAlgorithm< ThreeViewMatchingControl< FragmentOverlapResult > >.

Definition at line 33 of file ThreeViewTrackFragmentsAlgorithm.cc.

34 {
35  try
36  {
37  this->AddToSlidingFitCache(pNewCluster);
38  }
39  catch (StatusCodeException &statusCodeException)
40  {
41  if (STATUS_CODE_FAILURE == statusCodeException.GetStatusCode())
42  throw statusCodeException;
43 
44  return;
45  }
46 
47  const HitType hitType(LArClusterHelper::GetClusterHitType(pNewCluster));
48 
49  if (!((TPC_VIEW_U == hitType) || (TPC_VIEW_V == hitType) || (TPC_VIEW_W == hitType)))
50  throw StatusCodeException(STATUS_CODE_FAILURE);
51 
52  // ATTN This is non-standard usage, supported here only (for legacy purposes)
53  MatchingType &matchingControl(this->GetMatchingControl());
54  ClusterList &clusterList((TPC_VIEW_U == hitType) ? matchingControl.m_clusterListU
55  : (TPC_VIEW_V == hitType) ? matchingControl.m_clusterListV : matchingControl.m_clusterListW);
56 
57  if (clusterList.end() != std::find(clusterList.begin(), clusterList.end(), pNewCluster))
58  throw StatusCodeException(STATUS_CODE_ALREADY_PRESENT);
59 
60  clusterList.push_back(pNewCluster);
61 
62  ClusterList clusterList1(this->GetSelectedClusterList((TPC_VIEW_U == hitType) ? TPC_VIEW_V : TPC_VIEW_U));
63  ClusterList clusterList2(this->GetSelectedClusterList((TPC_VIEW_W == hitType) ? TPC_VIEW_V : TPC_VIEW_W));
64  clusterList1.sort(LArClusterHelper::SortByNHits);
65  clusterList2.sort(LArClusterHelper::SortByNHits);
66 
67  for (const Cluster *const pCluster1 : clusterList1)
68  {
69  if (TPC_VIEW_U == hitType)
70  {
71  this->CalculateOverlapResult(pNewCluster, pCluster1, nullptr);
72  }
73  else if (TPC_VIEW_V == hitType)
74  {
75  this->CalculateOverlapResult(pCluster1, pNewCluster, nullptr);
76  }
77  else
78  {
79  this->CalculateOverlapResult(pCluster1, nullptr, pNewCluster);
80  }
81  }
82 
83  for (const Cluster *const pCluster2 : clusterList2)
84  {
85  if (TPC_VIEW_U == hitType)
86  {
87  this->CalculateOverlapResult(pNewCluster, nullptr, pCluster2);
88  }
89  else if (TPC_VIEW_V == hitType)
90  {
91  this->CalculateOverlapResult(nullptr, pNewCluster, pCluster2);
92  }
93  else
94  {
95  this->CalculateOverlapResult(nullptr, pCluster2, pNewCluster);
96  }
97  }
98 }
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.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
void CalculateOverlapResult(const pandora::Cluster *const pClusterU, const pandora::Cluster *const pClusterV, const pandora::Cluster *const pClusterW)
Calculate cluster overlap result and store in container.
const pandora::ClusterList & GetSelectedClusterList(const pandora::HitType hitType) const
Get the selected cluster list corresponding to a specified hit type.

Member Data Documentation

TensorToolVector lar_content::ThreeViewTrackFragmentsAlgorithm::m_algorithmToolVector
protected

The algorithm tool list.

Definition at line 147 of file ThreeViewTrackFragmentsAlgorithm.h.

float lar_content::ThreeViewTrackFragmentsAlgorithm::m_maxPointDisplacementSquared
protected

maximum allowed distance (squared) between projected points and associated hits

Definition at line 153 of file ThreeViewTrackFragmentsAlgorithm.h.

unsigned int lar_content::ThreeViewTrackFragmentsAlgorithm::m_minMatchedHits
protected

minimum number of matched calo hits

Definition at line 155 of file ThreeViewTrackFragmentsAlgorithm.h.

float lar_content::ThreeViewTrackFragmentsAlgorithm::m_minMatchedSamplingPointFraction
protected

minimum fraction of matched sampling points

Definition at line 154 of file ThreeViewTrackFragmentsAlgorithm.h.

float lar_content::ThreeViewTrackFragmentsAlgorithm::m_minXOverlap
protected

requirement on minimum X overlap for associated clusters

Definition at line 151 of file ThreeViewTrackFragmentsAlgorithm.h.

float lar_content::ThreeViewTrackFragmentsAlgorithm::m_minXOverlapFraction
protected

requirement on minimum X overlap fraction for associated clusters

Definition at line 152 of file ThreeViewTrackFragmentsAlgorithm.h.

unsigned int lar_content::ThreeViewTrackFragmentsAlgorithm::m_nMaxTensorToolRepeats
protected

The maximum number of repeat loops over tensor tools.

Definition at line 149 of file ThreeViewTrackFragmentsAlgorithm.h.

std::string lar_content::ThreeViewTrackFragmentsAlgorithm::m_reclusteringAlgorithmName
protected

Name of daughter algorithm to use for cluster re-building.

Definition at line 144 of file ThreeViewTrackFragmentsAlgorithm.h.


The documentation for this class was generated from the following files: