Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
LArHitWidthHelper.cc
Go to the documentation of this file.
1
10
11using namespace pandora;
12
13namespace lar_content
14{
15
16LArHitWidthHelper::ConstituentHit::ConstituentHit(const CartesianVector &positionVector, const float hitWidth, const Cluster *const pParentClusterAddress) :
17 m_positionVector(positionVector),
18 m_hitWidth(hitWidth),
19 m_pParentClusterAddress(pParentClusterAddress)
20{
21}
22
23//------------------------------------------------------------------------------------------------------------------------------------------
24
26{
27 const CartesianVector &lhsPosition(lhs.GetPositionVector());
28 const CartesianVector &rhsPosition(rhs.GetPositionVector());
29
30 return (m_referencePoint.GetDistanceSquared(lhsPosition) < m_referencePoint.GetDistanceSquared(rhsPosition));
31}
32
33//------------------------------------------------------------------------------------------------------------------------------------------
34//------------------------------------------------------------------------------------------------------------------------------------------
35
37 const Cluster *const pCluster, const float maxConstituentHitWidth, const bool isUniformHits, const float hitWidthScalingFactor) :
38 m_pCluster(pCluster),
39 m_numCaloHits(pCluster->GetNCaloHits()),
40 m_constituentHitVector(LArHitWidthHelper::GetConstituentHits(pCluster, maxConstituentHitWidth, hitWidthScalingFactor, isUniformHits)),
41 m_totalWeight(LArHitWidthHelper::GetTotalClusterWeight(m_constituentHitVector)),
42 m_lowerXExtrema(LArHitWidthHelper::GetExtremalCoordinatesLowerX(m_constituentHitVector)),
43 m_higherXExtrema(LArHitWidthHelper::GetExtremalCoordinatesHigherX(m_constituentHitVector))
44{
45}
46
47//------------------------------------------------------------------------------------------------------------------------------------------
48
49LArHitWidthHelper::ClusterParameters::ClusterParameters(const Cluster *const pCluster, const unsigned int numCaloHits, const float totalWeight,
50 const LArHitWidthHelper::ConstituentHitVector &constituentHitVector, const CartesianVector &lowerXExtrema, const CartesianVector &higherXExtrema) :
51 m_pCluster(pCluster),
52 m_numCaloHits(numCaloHits),
53 m_constituentHitVector(constituentHitVector),
54 m_totalWeight(totalWeight),
55 m_lowerXExtrema(lowerXExtrema),
56 m_higherXExtrema(higherXExtrema)
57{
58}
59
60//------------------------------------------------------------------------------------------------------------------------------------------
61//------------------------------------------------------------------------------------------------------------------------------------------
62
64{
65 const LArHitWidthHelper::ClusterParameters &lhsClusterParameters(LArHitWidthHelper::GetClusterParameters(pLhs, m_clusterToParametersMap));
66 const LArHitWidthHelper::ClusterParameters &rhsClusterParameters(LArHitWidthHelper::GetClusterParameters(pRhs, m_clusterToParametersMap));
67
68 return (lhsClusterParameters.GetHigherXExtrema().GetX() < rhsClusterParameters.GetHigherXExtrema().GetX());
69}
70
71//------------------------------------------------------------------------------------------------------------------------------------------
72//------------------------------------------------------------------------------------------------------------------------------------------
73
75 const Cluster *const pCluster, const ClusterToParametersMap &clusterToParametersMap)
76{
77 if (clusterToParametersMap.empty())
78 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
79
80 const auto clusterParametersIter(clusterToParametersMap.find(pCluster));
81
82 if (clusterParametersIter == clusterToParametersMap.end())
83 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
84
85 return clusterParametersIter->second;
86}
87
88//------------------------------------------------------------------------------------------------------------------------------------------
89
90unsigned int LArHitWidthHelper::GetNProposedConstituentHits(const Cluster *const pCluster, const float maxConstituentHitWidth, const float hitWidthScalingFactor)
91{
92 if (maxConstituentHitWidth < std::numeric_limits<float>::epsilon())
93 {
94 std::cout << "LArHitWidthHelper::GetConstituentHits - Negative or equivalent to zero constitent hit width not allowed" << std::endl;
95 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
96 }
97
98 const OrderedCaloHitList &orderedCaloHitList(pCluster->GetOrderedCaloHitList());
99
100 if (orderedCaloHitList.empty())
101 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
102
103 unsigned int totalConstituentHits(0);
104 for (const OrderedCaloHitList::value_type &mapEntry : orderedCaloHitList)
105 {
106 for (const CaloHit *const pCaloHit : *mapEntry.second)
107 {
108 const float hitWidth = pCaloHit->GetCellSize1() * hitWidthScalingFactor;
109 const unsigned int numberOfConstituentHits = std::ceil(hitWidth / maxConstituentHitWidth);
110
111 totalConstituentHits += numberOfConstituentHits;
112 }
113 }
114
115 return totalConstituentHits;
116}
117
118//------------------------------------------------------------------------------------------------------------------------------------------
119
121 const Cluster *const pCluster, const float maxConstituentHitWidth, const float hitWidthScalingFactor, const bool isUniform)
122{
123 if (maxConstituentHitWidth < std::numeric_limits<float>::epsilon())
124 {
125 std::cout << "LArHitWidthHelper::GetConstituentHits - Negative or equivalent to zero constitent hit width not allowed" << std::endl;
126 throw StatusCodeException(STATUS_CODE_NOT_ALLOWED);
127 }
128
129 const OrderedCaloHitList &orderedCaloHitList(pCluster->GetOrderedCaloHitList());
130
131 if (orderedCaloHitList.empty())
132 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
133
134 ConstituentHitVector constituentHitVector;
135 for (const OrderedCaloHitList::value_type &mapEntry : orderedCaloHitList)
136 {
137 for (const CaloHit *const pCaloHit : *mapEntry.second)
138 {
139 const float hitWidth = pCaloHit->GetCellSize1() * hitWidthScalingFactor;
140 const unsigned int numberOfConstituentHits = std::ceil(hitWidth / maxConstituentHitWidth);
141 if (isUniform)
142 {
143 LArHitWidthHelper::SplitHitIntoConstituents(pCaloHit, pCluster, numberOfConstituentHits, maxConstituentHitWidth, constituentHitVector);
144 }
145 else
146 {
147 const float constituentHitWidth = hitWidth / numberOfConstituentHits;
148 LArHitWidthHelper::SplitHitIntoConstituents(pCaloHit, pCluster, numberOfConstituentHits, constituentHitWidth, constituentHitVector);
149 }
150 }
151 }
152
153 return constituentHitVector;
154}
155
156//------------------------------------------------------------------------------------------------------------------------------------------
157
158void LArHitWidthHelper::SplitHitIntoConstituents(const CaloHit *const pCaloHit, const Cluster *const pCluster,
159 const unsigned int numberOfConstituentHits, const float constituentHitWidth, LArHitWidthHelper::ConstituentHitVector &constituentHitVector)
160{
161 const CartesianVector &hitCenter(pCaloHit->GetPositionVector());
162 const bool isOdd(numberOfConstituentHits % 2 == 1);
163 float xDistanceFromCenter(0.f);
164
165 // find constituent hit centers by moving out from the original hit center position
166 unsigned int loopIterations(std::ceil(numberOfConstituentHits / 2.0));
167 for (unsigned int i = 0; i < loopIterations; ++i)
168 {
169 if (i == 0)
170 {
171 if (isOdd)
172 {
173 constituentHitVector.push_back(ConstituentHit(hitCenter, constituentHitWidth, pCluster));
174 continue;
175 }
176 else
177 {
178 xDistanceFromCenter += constituentHitWidth / 2;
179 }
180 }
181 else
182 {
183 xDistanceFromCenter += constituentHitWidth;
184 }
185
186 CartesianVector positivePosition(hitCenter + CartesianVector(xDistanceFromCenter, 0.f, 0.f)),
187 negativePosition(hitCenter - CartesianVector(xDistanceFromCenter, 0.f, 0.f));
188
189 constituentHitVector.push_back(ConstituentHit(positivePosition, constituentHitWidth, pCluster));
190 constituentHitVector.push_back(ConstituentHit(negativePosition, constituentHitWidth, pCluster));
191 }
192}
193
194//------------------------------------------------------------------------------------------------------------------------------------------
195
197{
198 float clusterWeight(0.f);
199 for (const ConstituentHit &constituentHit : constituentHitVector)
200 clusterWeight += constituentHit.GetHitWidth();
201
202 return clusterWeight;
203}
204
205//------------------------------------------------------------------------------------------------------------------------------------------
206
208{
209 float clusterWeight(0.f);
210 const OrderedCaloHitList &orderedCaloHitList(pCluster->GetOrderedCaloHitList());
211
212 for (const OrderedCaloHitList::value_type &mapEntry : orderedCaloHitList)
213 {
214 for (const CaloHit *const pCaloHit : *mapEntry.second)
215 clusterWeight += pCaloHit->GetCellSize1();
216 }
217
218 return clusterWeight;
219}
220
221//------------------------------------------------------------------------------------------------------------------------------------------
222
224{
225 CartesianPointVector constituentHitPositionVector;
226
227 for (const ConstituentHit &constituentHit : constituentHitVector)
228 constituentHitPositionVector.push_back(constituentHit.GetPositionVector());
229
230 return constituentHitPositionVector;
231}
232
233//------------------------------------------------------------------------------------------------------------------------------------------
234
236{
237 CartesianVector lowerXCoordinate(0.f, 0.f, 0.f), higherXCoordinate(0.f, 0.f, 0.f);
238 LArHitWidthHelper::GetExtremalCoordinatesX(constituentHitVector, lowerXCoordinate, higherXCoordinate);
239
240 return lowerXCoordinate;
241}
242
243//------------------------------------------------------------------------------------------------------------------------------------------
244
246{
247 CartesianVector lowerXCoordinate(0.f, 0.f, 0.f), higherXCoordinate(0.f, 0.f, 0.f);
248 LArHitWidthHelper::GetExtremalCoordinatesX(constituentHitVector, lowerXCoordinate, higherXCoordinate);
249
250 return higherXCoordinate;
251}
252
253//------------------------------------------------------------------------------------------------------------------------------------------
254
256 const ConstituentHitVector &constituentHitVector, CartesianVector &lowerXCoordinate, CartesianVector &higherXCoordinate)
257{
258 const CartesianPointVector &constituentHitPositionVector(GetConstituentHitPositionVector(constituentHitVector));
259
260 CartesianVector innerCoordinate(0.f, 0.f, 0.f), outerCoordinate(0.f, 0.f, 0.f);
261 LArClusterHelper::GetExtremalCoordinates(constituentHitPositionVector, innerCoordinate, outerCoordinate);
262
263 // set the lower/higher XCoordinate (in the event of a tie, use z)
264 const float deltaX(outerCoordinate.GetX() - innerCoordinate.GetX());
265 const float deltaZ(outerCoordinate.GetZ() - innerCoordinate.GetZ());
266
267 if ((deltaX > 0.f) || ((std::fabs(deltaX) < std::numeric_limits<float>::epsilon()) && (deltaZ > 0.f)))
268 {
269 lowerXCoordinate = innerCoordinate;
270 higherXCoordinate = outerCoordinate;
271 }
272 else
273 {
274 lowerXCoordinate = outerCoordinate;
275 higherXCoordinate = innerCoordinate;
276 }
277}
278
279//------------------------------------------------------------------------------------------------------------------------------------------
280
282 const CartesianVector &lineStart, const CartesianVector &lineDirection, const CaloHit *const pCaloHit)
283{
284 const CartesianVector &hitPosition(pCaloHit->GetPositionVector());
285
286 if (std::fabs(lineDirection.GetZ()) < std::numeric_limits<float>::epsilon())
287 return hitPosition;
288
289 float xOnLine(lineStart.GetX());
290 if (std::fabs(lineDirection.GetX()) > std::numeric_limits<float>::epsilon())
291 {
292 const float gradient(lineDirection.GetZ() / lineDirection.GetX());
293 xOnLine += ((hitPosition.GetZ() - lineStart.GetZ()) / gradient);
294 }
295
296 const float &hitWidth(pCaloHit->GetCellSize1());
297 const float hitLowXEdge(hitPosition.GetX() - (hitWidth * 0.5f));
298 const float hitHighXEdge(hitPosition.GetX() + (hitWidth * 0.5f));
299 const float closestPointX(xOnLine < hitLowXEdge ? hitLowXEdge : xOnLine > hitHighXEdge ? hitHighXEdge : xOnLine);
300
301 return CartesianVector(closestPointX, 0.f, hitPosition.GetZ());
302}
303
304//------------------------------------------------------------------------------------------------------------------------------------------
305
307{
308 const CartesianVector &hitPosition(pCaloHit->GetPositionVector());
309 const float hitWidth(pCaloHit->GetCellSize1());
310 const float hitLowXEdge(hitPosition.GetX() - (hitWidth * 0.5f));
311 const float hitHighXEdge(hitPosition.GetX() + (hitWidth * 0.5f));
312 const float modDeltaZ(std::fabs(hitPosition.GetZ() - point2D.GetZ()));
313
314 if ((hitLowXEdge < point2D.GetX()) && (hitHighXEdge > point2D.GetX()))
315 return modDeltaZ;
316
317 const float deltaX = hitLowXEdge > point2D.GetX() ? (point2D.GetX() - hitLowXEdge) : (point2D.GetX() - hitHighXEdge);
318
319 return std::sqrt((deltaX * deltaX) + (modDeltaZ * modDeltaZ));
320}
321
322//------------------------------------------------------------------------------------------------------------------------------------------
323
324float LArHitWidthHelper::GetClosestDistance(const CaloHit *const pThisCaloHit, const CaloHitList &caloHitList)
325{
326 float closestDistance(std::numeric_limits<float>::max());
327
328 for (const CaloHit *const pCaloHit : caloHitList)
329 {
330 const float separation(LArHitWidthHelper::GetClosestDistance(pThisCaloHit, pCaloHit));
331
332 if (separation < closestDistance)
333 closestDistance = separation;
334 }
335
336 return closestDistance;
337}
338
339//------------------------------------------------------------------------------------------------------------------------------------------
340
341float LArHitWidthHelper::GetClosestDistance(const CaloHit *const pCaloHit1, const CaloHit *const pCaloHit2)
342{
343 const CartesianVector &hitPosition1(pCaloHit1->GetPositionVector());
344 const float hitWidth1(pCaloHit1->GetCellSize1());
345 const float hitLowXEdge1(hitPosition1.GetX() - (hitWidth1 * 0.5f));
346 const float hitHighXEdge1(hitPosition1.GetX() + (hitWidth1 * 0.5f));
347
348 const CartesianVector &hitPosition2(pCaloHit2->GetPositionVector());
349 const float hitWidth2(pCaloHit2->GetCellSize1());
350 const float hitLowXEdge2(hitPosition2.GetX() - (hitWidth2 * 0.5f));
351 const float hitHighXEdge2(hitPosition2.GetX() + (hitWidth2 * 0.5f));
352
353 const float modDeltaZ(std::fabs(hitPosition1.GetZ() - hitPosition2.GetZ()));
354
355 // Partial overlap case
356 if ((hitLowXEdge1 < hitHighXEdge2) && (hitLowXEdge1 > hitLowXEdge2))
357 return modDeltaZ;
358
359 if ((hitHighXEdge1 > hitLowXEdge2) && (hitHighXEdge1 < hitHighXEdge2))
360 return modDeltaZ;
361
362 // Complete overlap case
363 if ((hitLowXEdge1 > hitLowXEdge2) && (hitHighXEdge1 < hitHighXEdge2))
364 return modDeltaZ;
365
366 if ((hitLowXEdge2 > hitLowXEdge1) && (hitHighXEdge2 < hitHighXEdge1))
367 return modDeltaZ;
368
369 const float deltaX = hitLowXEdge1 < hitLowXEdge2 ? (hitLowXEdge2 - hitHighXEdge1) : (hitLowXEdge1 - hitHighXEdge2);
370
371 return std::sqrt((deltaX * deltaX) + (modDeltaZ * modDeltaZ));
372}
373
374} // namespace lar_content
Header file for the cluster helper class.
Header file for the lar hit width helper class.
static void GetExtremalCoordinates(const pandora::ClusterList &clusterList, pandora::CartesianVector &innerCoordinate, pandora::CartesianVector &outerCoordinate)
Get positions of the two most distant calo hits in a list of cluster (ordered by Z)
const pandora::CartesianVector & GetHigherXExtrema() const
Returns the higher x extremal point of the constituent hits.
ClusterParameters(const pandora::Cluster *const pCluster, const float maxConsituentHitWidth, const bool isUniformHits, const float hitWidthScalingFactor)
Constructor.
bool operator()(const ConstituentHit &lhs, const ConstituentHit &rhs)
Sort constituent hits by their position relative to a referencePoint.
ConstituentHit(const pandora::CartesianVector &positionVector, const float hitWidth, const pandora::Cluster *const pParentClusterAddress)
Constructor.
const pandora::CartesianVector & GetPositionVector() const
Returns the constituent hit central position.
bool operator()(const pandora::Cluster *const pLhs, const pandora::Cluster *const pRhs)
Sort clusters by the higher x extremal point of their constituent hits.
LArHitWidthHelper class.
static void GetExtremalCoordinatesX(const ConstituentHitVector &constituentHitVector, pandora::CartesianVector &lowerXCoordinate, pandora::CartesianVector &higherXCoordinate)
Calculate the higher and lower x extremal points of the constituent hits.
static unsigned int GetNProposedConstituentHits(const pandora::Cluster *const pCluster, const float maxConstituentHitWidth, const float hitWidthScalingFactor)
Return the number of constituent hits that a given cluster would be broken into.
std::vector< ConstituentHit > ConstituentHitVector
static void SplitHitIntoConstituents(const pandora::CaloHit *const pCaloHit, const pandora::Cluster *const pCluster, const unsigned int numberOfConstituentHits, const float constituentHitWidth, ConstituentHitVector &constituentHitVector)
Break up the calo hit into constituent hits.
std::unordered_map< const pandora::Cluster *, const ClusterParameters > ClusterToParametersMap
static pandora::CartesianPointVector GetConstituentHitPositionVector(const ConstituentHitVector &constituentHitVector)
Obtain a vector of the contituent hit central positions.
static pandora::CartesianVector GetExtremalCoordinatesHigherX(const ConstituentHitVector &constituentHitVector)
Return the higher x extremal point of the constituent hits.
static const ClusterParameters & GetClusterParameters(const pandora::Cluster *const pCluster, const ClusterToParametersMap &clusterToParametersMap)
Return the cluster parameters of a given cluster, exception thrown if not found in map [cluster -> cl...
static float GetOriginalTotalClusterWeight(const pandora::Cluster *const pCluster)
Sum the widths of the original, unscaled hits contained within a cluster.
static pandora::CartesianVector GetClosestPointToLine2D(const pandora::CartesianVector &lineStart, const pandora::CartesianVector &lineDirection, const pandora::CaloHit *const pCaloHit)
Consider the hit width to find the closest position of a calo hit to a specified line.
static ConstituentHitVector GetConstituentHits(const pandora::Cluster *const pCluster, const float maxConstituentHitWidth, const float hitWidthScalingFactor, const bool isUniform)
Break up the cluster hits into constituent hits.
static float GetClosestDistance(const pandora::CaloHit *const pThisCaloHit, const pandora::CaloHitList &caloHitList)
Find the smallest separation between a hit and a list of hits, with the consideration of their hit wi...
static float GetTotalClusterWeight(const ConstituentHitVector &constituentHitVector)
Sum the widths of constituent hits.
static float GetClosestDistanceToPoint2D(const pandora::CaloHit *const pCaloHit, const pandora::CartesianVector &point2D)
Consider the hit width to find the smallest distance between a calo hit and a given point.
static pandora::CartesianVector GetExtremalCoordinatesLowerX(const ConstituentHitVector &constituentHitVector)
Return the lower x extremal point of the constituent hits.
CaloHit class.
Definition CaloHit.h:26
const CartesianVector & GetPositionVector() const
Get the position vector of center of calorimeter cell, units mm.
Definition CaloHit.h:350
float GetCellSize1() const
Get the cell size 1 [pointing: phi, rectangular: perpendicular to size 0 and thickness,...
Definition CaloHit.h:392
CartesianVector class.
float GetX() const
Get the cartesian x coordinate.
float GetZ() const
Get the cartesian z coordinate.
Cluster class.
Definition Cluster.h:31
const OrderedCaloHitList & GetOrderedCaloHitList() const
Get the ordered calo hit list.
Definition Cluster.h:470
Calo hit lists arranged by pseudo layer.
bool empty() const
Returns whether the map container is empty (i.e. whether its size is 0)
StatusCodeException class.
std::vector< CartesianVector > CartesianPointVector
MANAGED_CONTAINER< const CaloHit * > CaloHitList