LArParticleIdPlugins.cc
Go to the documentation of this file.
1 /**
2  * @file larpandoracontent/LArPlugins/LArParticleIdPlugins.cc
3  *
4  * @brief Implementation of the lar particle id plugins class.
5  *
6  * $Log: $
7  */
8 
9 #include "Helpers/XmlHelper.h"
10 
11 #include "Objects/Cluster.h"
12 
16 
18 
20 
21 #include <algorithm>
22 #include <cmath>
23 
24 namespace lar_content
25 {
26 
27 using namespace pandora;
28 
30  m_layerFitHalfWindow(20),
31  m_minLayerOccupancy(0.75f),
32  m_maxTrackWidth(0.5f),
33  m_trackResidualQuantile(0.8f),
34  m_minClustersPassingId(2)
35 {
36 }
37 
38 //------------------------------------------------------------------------------------------------------------------------------------------
39 
40 bool LArParticleIdPlugins::LArMuonId::IsMatch(const Cluster *const pCluster) const
41 {
43  return false;
44 
45  const float slidingFitPitch(LArGeometryHelper::GetWireZPitch(this->GetPandora()));
46  const TwoDSlidingFitResult twoDSlidingFitResult(pCluster, m_layerFitHalfWindow, slidingFitPitch);
47 
48  if (this->GetMuonTrackWidth(twoDSlidingFitResult) > m_maxTrackWidth)
49  return false;
50 
51  return true;
52 }
53 
54 //------------------------------------------------------------------------------------------------------------------------------------------
55 
56 bool LArParticleIdPlugins::LArMuonId::IsMatch(const ParticleFlowObject *const pPfo) const
57 {
58  ClusterList clusterList;
59  LArPfoHelper::GetTwoDClusterList(pPfo, clusterList);
60 
61  if (clusterList.empty())
62  return false;
63 
64  unsigned int nClustersPassing(0);
65 
66  for (const Cluster *const pCluster : clusterList)
67  {
68  if (this->IsMatch(pCluster))
69  ++nClustersPassing;
70  }
71 
72  if (nClustersPassing < m_minClustersPassingId)
73  return false;
74 
75  return true;
76 }
77 
78 //------------------------------------------------------------------------------------------------------------------------------------------
79 
81 {
82  FloatVector residuals;
83  const OrderedCaloHitList &orderedCaloHitList(twoDSlidingFitResult.GetCluster()->GetOrderedCaloHitList());
84  const LayerFitResultMap &layerFitResultMap(twoDSlidingFitResult.GetLayerFitResultMap());
85 
86  for (OrderedCaloHitList::const_iterator iter = orderedCaloHitList.begin(); iter != orderedCaloHitList.end(); ++iter)
87  {
88  for (CaloHitList::const_iterator hitIter = iter->second->begin(), hitIterEnd = iter->second->end(); hitIter != hitIterEnd; ++hitIter)
89  {
90  float rL(0.f), rT(0.f);
91  twoDSlidingFitResult.GetLocalPosition((*hitIter)->GetPositionVector(), rL, rT);
92  const int layer(twoDSlidingFitResult.GetLayer(rL));
93 
94  LayerFitResultMap::const_iterator fitResultIter = layerFitResultMap.find(layer);
95 
96  if (layerFitResultMap.end() == fitResultIter)
97  continue;
98 
99  const double fitT(fitResultIter->second.GetFitT());
100  const double gradient(fitResultIter->second.GetGradient());
101  const double residualSquared((fitT - rT) * (fitT - rT) / (1. + gradient * gradient)); // angular correction (note: this is cheating!)
102  residuals.push_back(residualSquared);
103  }
104  }
105 
106  if (residuals.empty())
107  throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
108 
109  std::sort(residuals.begin(), residuals.end());
110  const float theQuantile(residuals[m_trackResidualQuantile * residuals.size()]);
111 
112  return std::sqrt(theQuantile);
113 }
114 
115 //------------------------------------------------------------------------------------------------------------------------------------------
116 
117 StatusCode LArParticleIdPlugins::LArMuonId::ReadSettings(const TiXmlHandle xmlHandle)
118 {
119  PANDORA_RETURN_RESULT_IF_AND_IF(
120  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "LayerFitHalfWindow", m_layerFitHalfWindow));
121 
122  PANDORA_RETURN_RESULT_IF_AND_IF(
123  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinLayerOccupancy", m_minLayerOccupancy));
124 
125  PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxTrackWidth", m_maxTrackWidth));
126 
127  PANDORA_RETURN_RESULT_IF_AND_IF(
128  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "TrackResidualQuantile", m_trackResidualQuantile));
129 
130  PANDORA_RETURN_RESULT_IF_AND_IF(
131  STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MinClustersPassingId", m_minClustersPassingId));
132 
133  return STATUS_CODE_SUCCESS;
134 }
135 
136 } // namespace lar_content
unsigned int m_layerFitHalfWindow
Layer fit half window, used for calculating sliding muon track width.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Header file for the pfo helper class.
static void GetTwoDClusterList(const pandora::ParticleFlowObject *const pPfo, pandora::ClusterList &clusterList)
Get the list of 2D clusters from an input pfo.
float m_trackResidualQuantile
Track residual quantile, used for calculating muon track width.
float GetMuonTrackWidth(const TwoDSlidingFitResult &twoDSlidingFitResult) const
Get the muon track width estimator for a provided sliding fit result.
intermediate_table::const_iterator const_iterator
Header file for the lar particle id plugins class.
static float GetWireZPitch(const pandora::Pandora &pandora, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
Header file for the geometry helper class.
Header file for the cluster helper class.
bool IsMatch(const pandora::Cluster *const pCluster) const
Header file for the lar two dimensional sliding fit result class.
std::map< int, LayerFitResult > LayerFitResultMap
const LayerFitResultMap & GetLayerFitResultMap() const
Get the layer fit result map.
static float GetLayerOccupancy(const pandora::Cluster *const pCluster)
Fraction of occupied layers in cluster.
float m_minLayerOccupancy
Min layer occupancy for for muon identification.
const pandora::Cluster * GetCluster() const
Get the address of the cluster, if originally provided.
float m_maxTrackWidth
Max muon track width estimator for muon identification.
Dft::FloatVector FloatVector
void GetLocalPosition(const pandora::CartesianVector &position, float &rL, float &rT) const
Get local sliding fit coordinates for a given global position.
int GetLayer(const float rL) const
Get layer number for given sliding linear fit longitudinal coordinate.
unsigned int m_minClustersPassingId
Match pfo if at sufficient clusters in pfo pass the cluster particle id logic.