Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
ProtoShowerMatchingTool.cc
Go to the documentation of this file.
1
11
14
16
19
20using namespace pandora;
21
22namespace lar_content
23{
24
26 m_spineSlidingFitWindow(20),
27 m_maxXSeparation(5.f),
28 m_maxSeparation(5.f),
29 m_maxAngularDeviation(5.f)
30{
31}
32
33//------------------------------------------------------------------------------------------------------------------------------------------
34
35StatusCode ProtoShowerMatchingTool::Run(const ProtoShowerVector &protoShowerVectorU, const ProtoShowerVector &protoShowerVectorV,
36 const ProtoShowerVector &protoShowerVectorW, ProtoShowerMatchVector &protoShowerMatchVector)
37{
38 IntVector usedProtoShowersU, usedProtoShowersV, usedProtoShowersW;
39
40 bool added(false);
41
42 for (unsigned int uIndex = 0; uIndex < protoShowerVectorU.size(); ++uIndex)
43 {
44 added = false;
45
46 if (std::find(usedProtoShowersU.begin(), usedProtoShowersU.end(), uIndex) != usedProtoShowersU.end())
47 continue;
48
49 const ProtoShower &protoShowerU(protoShowerVectorU.at(uIndex));
50
51 for (unsigned int vIndex = 0; vIndex < protoShowerVectorV.size(); ++vIndex)
52 {
53 if (std::find(usedProtoShowersV.begin(), usedProtoShowersV.end(), vIndex) != usedProtoShowersV.end())
54 continue;
55
56 const ProtoShower &protoShowerV(protoShowerVectorV.at(vIndex));
57
58 for (unsigned int wIndex = 0; wIndex < protoShowerVectorW.size(); ++wIndex)
59 {
60 if (std::find(usedProtoShowersW.begin(), usedProtoShowersW.end(), wIndex) != usedProtoShowersW.end())
61 continue;
62
63 const ProtoShower &protoShowerW(protoShowerVectorW.at(wIndex));
65
66 if (!this->ArePathwaysConsistent(protoShowerU, protoShowerV, protoShowerW, consistency))
67 continue;
68
69 usedProtoShowersU.push_back(uIndex);
70 usedProtoShowersV.push_back(vIndex);
71 usedProtoShowersW.push_back(wIndex);
72
73 protoShowerMatchVector.push_back(ProtoShowerMatch(protoShowerU, protoShowerV, protoShowerW, consistency));
74
75 added = true;
76 break;
77 }
78
79 if (added)
80 break;
81 }
82 }
83
84 return STATUS_CODE_SUCCESS;
85}
86
87//------------------------------------------------------------------------------------------------------------------------------------------
88
90 const ProtoShower &protoShowerU, const ProtoShower &protoShowerV, const ProtoShower &protoShowerW, Consistency &consistency) const
91{
92 if (this->AreShowerStartsConsistent(protoShowerU, protoShowerV, protoShowerW))
93 {
94 consistency = Consistency::POSITION;
95 }
96 else if (this->AreDirectionsConsistent(protoShowerU, protoShowerV, protoShowerW))
97 {
98 consistency = Consistency::DIRECTION;
99 }
100 else
101 {
102 return false;
103 }
104
105 return true;
106}
107
108//------------------------------------------------------------------------------------------------------------------------------------------
109
110bool ProtoShowerMatchingTool::AreShowerStartsConsistent(const ProtoShower &protoShowerU, const ProtoShower &protoShowerV, const ProtoShower &protoShowerW) const
111{
112 const CartesianVector &showerStartU(protoShowerU.GetShowerCore().GetStartPosition());
113 const CartesianVector &showerStartV(protoShowerV.GetShowerCore().GetStartPosition());
114 const CartesianVector &showerStartW(protoShowerW.GetShowerCore().GetStartPosition());
115
116 const float xSeparationUV(std::fabs(showerStartU.GetX() - showerStartV.GetX()));
117 const float xSeparationUW(std::fabs(showerStartU.GetX() - showerStartW.GetX()));
118 const float xSeparationVW(std::fabs(showerStartV.GetX() - showerStartW.GetX()));
119
120 if ((xSeparationUV > m_maxXSeparation) || (xSeparationUW > m_maxXSeparation) || (xSeparationVW > m_maxXSeparation))
121 return false;
122
123 float chi2(0.f);
124 CartesianVector projectionU(0.f, 0.f, 0.f), projectionV(0.f, 0.f, 0.f), projectionW(0.f, 0.f, 0.f);
125
126 LArGeometryHelper::MergeTwoPositions(this->GetPandora(), TPC_VIEW_V, TPC_VIEW_W, showerStartV, showerStartW, projectionU, chi2);
127 LArGeometryHelper::MergeTwoPositions(this->GetPandora(), TPC_VIEW_W, TPC_VIEW_U, showerStartW, showerStartU, projectionV, chi2);
128 LArGeometryHelper::MergeTwoPositions(this->GetPandora(), TPC_VIEW_U, TPC_VIEW_V, showerStartU, showerStartV, projectionW, chi2);
129
130 const float separationU((projectionU - showerStartU).GetMagnitude());
131 const float separationV((projectionV - showerStartV).GetMagnitude());
132 const float separationW((projectionW - showerStartW).GetMagnitude());
133
134 const float metric((separationU + separationV + separationW) / 3.f);
135
136 return (metric < m_maxSeparation);
137}
138
139//------------------------------------------------------------------------------------------------------------------------------------------
140
141bool ProtoShowerMatchingTool::AreDirectionsConsistent(const ProtoShower &protoShowerU, const ProtoShower &protoShowerV, const ProtoShower &protoShowerW) const
142{
143 const CartesianVector &directionU1(protoShowerU.GetConnectionPathway().GetStartDirection());
144 const CartesianVector &directionV1(protoShowerV.GetConnectionPathway().GetStartDirection());
145 const CartesianVector &directionW1(protoShowerW.GetConnectionPathway().GetStartDirection());
146
147 if (this->AreDirectionsConsistent(directionU1, directionV1, directionW1))
148 {
149 return true;
150 }
151 else
152 {
153 const bool isDownstream(
154 protoShowerW.GetShowerCore().GetStartPosition().GetZ() > protoShowerW.GetConnectionPathway().GetStartPosition().GetZ());
155
156 CartesianPointVector spinePositionsU, spinePositionsV, spinePositionsW;
157
158 for (const CaloHit *const pCaloHit : protoShowerU.GetSpineHitList())
159 spinePositionsU.push_back(pCaloHit->GetPositionVector());
160
161 for (const CaloHit *const pCaloHit : protoShowerV.GetSpineHitList())
162 spinePositionsV.push_back(pCaloHit->GetPositionVector());
163
164 for (const CaloHit *const pCaloHit : protoShowerW.GetSpineHitList())
165 spinePositionsW.push_back(pCaloHit->GetPositionVector());
166
170
171 const CartesianVector directionU2(isDownstream ? spineFitU.GetGlobalMinLayerDirection() : spineFitU.GetGlobalMaxLayerDirection() * (-1.f));
172 const CartesianVector directionV2(isDownstream ? spineFitV.GetGlobalMinLayerDirection() : spineFitV.GetGlobalMaxLayerDirection() * (-1.f));
173 const CartesianVector directionW2(isDownstream ? spineFitW.GetGlobalMinLayerDirection() : spineFitW.GetGlobalMaxLayerDirection() * (-1.f));
174
175 return this->AreDirectionsConsistent(directionU2, directionV2, directionW2);
176 }
177
178 return false;
179}
180
181//------------------------------------------------------------------------------------------------------------------------------------------
182
184{
185 const CartesianVector wireAxis(0.f, 0.f, 1.f);
186
187 float wireDeviationU(directionU.GetOpeningAngle(wireAxis));
188 wireDeviationU = std::min(wireDeviationU, static_cast<float>(M_PI - wireDeviationU));
189
190 float wireDeviationV(directionV.GetOpeningAngle(wireAxis));
191 wireDeviationV = std::min(wireDeviationV, static_cast<float>(M_PI - wireDeviationV));
192
193 float wireDeviationW(directionW.GetOpeningAngle(wireAxis));
194 wireDeviationW = std::min(wireDeviationW, static_cast<float>(M_PI - wireDeviationW));
195
196 float radians((2.f * M_PI) / 180.f);
197 bool isIsochronous((wireDeviationU < radians) && (wireDeviationV < radians) && (wireDeviationW < radians));
198
199 if (isIsochronous)
200 {
201 // Enforce consistency
202 directionU = CartesianVector(std::fabs(directionU.GetX()), 0.f, directionU.GetZ());
203 directionV = CartesianVector(std::fabs(directionV.GetX()), 0.f, directionV.GetZ());
204 directionW = CartesianVector(std::fabs(directionW.GetX()), 0.f, directionW.GetZ());
205 }
206
207 if (directionU.GetX() * directionV.GetX() < 0.f)
208 return false;
209
210 if (directionU.GetX() * directionW.GetX() < 0.f)
211 return false;
212
213 if (directionV.GetX() * directionW.GetX() < 0.f)
214 return false;
215
216 const CartesianVector projectionU(LArGeometryHelper::MergeTwoDirections(this->GetPandora(), TPC_VIEW_V, TPC_VIEW_W, directionV, directionW));
217 const CartesianVector projectionV(LArGeometryHelper::MergeTwoDirections(this->GetPandora(), TPC_VIEW_W, TPC_VIEW_U, directionW, directionU));
218 const CartesianVector projectionW(LArGeometryHelper::MergeTwoDirections(this->GetPandora(), TPC_VIEW_U, TPC_VIEW_V, directionU, directionV));
219
220 float openingAngleU(directionU.GetOpeningAngle(projectionU) * 180.f / M_PI);
221 float openingAngleV(directionV.GetOpeningAngle(projectionV) * 180.f / M_PI);
222 float openingAngleW(directionW.GetOpeningAngle(projectionW) * 180.f / M_PI);
223
224 if (isIsochronous)
225 {
226 openingAngleU = std::min(openingAngleU, 180.f - openingAngleU);
227 openingAngleV = std::min(openingAngleV, 180.f - openingAngleV);
228 openingAngleW = std::min(openingAngleW, 180.f - openingAngleW);
229 }
230
231 if ((openingAngleU > m_maxAngularDeviation) || (openingAngleV > m_maxAngularDeviation) || (openingAngleW > m_maxAngularDeviation))
232 return false;
233
234 return true;
235}
236
237//------------------------------------------------------------------------------------------------------------------------------------------
238
240{
242 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "SpineSlidingFitWindow", m_spineSlidingFitWindow));
243
244 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxXSeparation", m_maxXSeparation));
245
246 PANDORA_RETURN_RESULT_IF_AND_IF(STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxSeparation", m_maxSeparation));
247
249 STATUS_CODE_SUCCESS, STATUS_CODE_NOT_FOUND, !=, XmlHelper::ReadValue(xmlHandle, "MaxAngularDeviation", m_maxAngularDeviation));
250
251 return STATUS_CODE_SUCCESS;
252}
253
254} // namespace lar_content
Grouping of header files for many classes of use in particle flow algorithms.
Header file for the algorithm tool class.
Header file for the connection pathway helper class.
Header file for the geometry helper class.
Header file for the ProtoShower class.
Header file for the lar two dimensional sliding fit result class.
Header file for the ProtoShower matching tool class.
#define PANDORA_RETURN_RESULT_IF_AND_IF(StatusCode1, StatusCode2, Operator, Command)
Definition StatusCodes.h:31
const pandora::CartesianVector & GetStartDirection() const
Get the start direction of the connection pathway.
const pandora::CartesianVector & GetStartPosition() const
Get the start position of the connection pathway.
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).
static float GetWirePitch(const pandora::Pandora &pandora, const pandora::HitType view, const float maxWirePitchDiscrepancy=0.01)
Return the wire pitch.
static pandora::CartesianVector MergeTwoDirections(const pandora::Pandora &pandora, const pandora::HitType view1, const pandora::HitType view2, const pandora::CartesianVector &direction1, const pandora::CartesianVector &direction2)
Merge two views (U,V) to give a third view (Z).
const ShowerCore & GetShowerCore() const
Get the shower core.
const ConnectionPathway & GetConnectionPathway() const
Get the connection pathway.
const pandora::CaloHitList & GetSpineHitList() const
Get the spine hit list.
ProtoShowerMatch class.
bool ArePathwaysConsistent(const ProtoShower &protoShowerU, const ProtoShower &protoShowerV, const ProtoShower &protoShowerW, Consistency &consistency) const
Determine whether three 2D connection pathways form a consistent 3D connection pathway.
float m_maxAngularDeviation
The max. opening angle between true and projected 2D initial directions for a match.
pandora::StatusCode ReadSettings(const pandora::TiXmlHandle xmlHandle)
Read the algorithm settings.
float m_maxXSeparation
The max. drift-coordinate separation between matched 2D shower start positions.
float m_maxSeparation
The max. average separation between true and projected 2D shower start positions for a match.
bool AreDirectionsConsistent(const ProtoShower &protoShowerU, const ProtoShower &protoShowerV, const ProtoShower &protoShowerW) const
Determine whether three 2D initial spine directions correspond to the same 3D initial spine direction...
bool AreShowerStartsConsistent(const ProtoShower &protoShowerU, const ProtoShower &protoShowerV, const ProtoShower &protoShowerW) const
Determine whether three 2D shower start positions correspond to the same 3D shower start position.
unsigned int m_spineSlidingFitWindow
The shower spine sliding fit window.
pandora::StatusCode Run(const ProtoShowerVector &protoShowerVectorU, const ProtoShowerVector &protoShowerVectorV, const ProtoShowerVector &protoShowerVectorW, ProtoShowerMatchVector &protoShowerMatchVector)
const pandora::CartesianVector & GetStartPosition() const
Get the start position of the shower core.
pandora::CartesianVector GetGlobalMinLayerDirection() const
Get global direction corresponding to the fit result in minimum fit layer.
pandora::CartesianVector GetGlobalMaxLayerDirection() const
Get global direction corresponding to the fit result in maximum fit layer.
CaloHit class.
Definition CaloHit.h:26
CartesianVector class.
float GetX() const
Get the cartesian x coordinate.
float GetZ() const
Get the cartesian z coordinate.
float GetOpeningAngle(const CartesianVector &rhs) const
Get the opening angle of the cartesian vector with respect to a second cartesian vector.
const Pandora & GetPandora() const
Get the associated pandora instance.
Definition Process.h:116
static StatusCode ReadValue(const TiXmlHandle &xmlHandle, const std::string &xmlElementName, T &t)
Read a value from an xml element.
Definition XmlHelper.h:136
std::vector< ProtoShower > ProtoShowerVector
Consistency
Consistency enumeration.
std::vector< ProtoShowerMatch > ProtoShowerMatchVector
std::vector< int > IntVector
std::vector< CartesianVector > CartesianPointVector
StatusCode
The StatusCode enum.