Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
LArGeometryHelper.cc
Go to the documentation of this file.
1
11
13#include "Geometry/LArTPC.h"
14
16
17#include "Pandora/Pandora.h"
18
21
23
25
26using namespace pandora;
27
28namespace lar_content
29{
30
31float LArGeometryHelper::MergeTwoPositions(const Pandora &pandora, const HitType view1, const HitType view2, const float position1, const float position2)
32{
33 if (view1 == view2)
34 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
35
36 if ((view1 == TPC_VIEW_U) && (view2 == TPC_VIEW_V))
37 {
38 return pandora.GetPlugins()->GetLArTransformationPlugin()->UVtoW(position1, position2);
39 }
40
41 if ((view1 == TPC_VIEW_V) && (view2 == TPC_VIEW_U))
42 {
43 return pandora.GetPlugins()->GetLArTransformationPlugin()->UVtoW(position2, position1);
44 }
45
46 if ((view1 == TPC_VIEW_W) && (view2 == TPC_VIEW_U))
47 {
48 return pandora.GetPlugins()->GetLArTransformationPlugin()->WUtoV(position1, position2);
49 }
50
51 if ((view1 == TPC_VIEW_U) && (view2 == TPC_VIEW_W))
52 {
53 return pandora.GetPlugins()->GetLArTransformationPlugin()->WUtoV(position2, position1);
54 }
55
56 if ((view1 == TPC_VIEW_V) && (view2 == TPC_VIEW_W))
57 {
58 return pandora.GetPlugins()->GetLArTransformationPlugin()->VWtoU(position1, position2);
59 }
60
61 if ((view1 == TPC_VIEW_W) && (view2 == TPC_VIEW_V))
62 {
63 return pandora.GetPlugins()->GetLArTransformationPlugin()->VWtoU(position2, position1);
64 }
65
66 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
67}
68
69//------------------------------------------------------------------------------------------------------------------------------------------
70
72 const Pandora &pandora, const HitType view1, const HitType view2, const CartesianVector &direction1, const CartesianVector &direction2)
73{
74 // x components must be consistent
75 if (direction1.GetX() * direction2.GetX() < 0.f)
76 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
77
78 // scale x components to a common value
79 const float s1((std::fabs(direction1.GetX()) > std::numeric_limits<float>::epsilon()) ? 100.f * std::fabs(direction2.GetX()) : 1.f);
80 const float s2((std::fabs(direction2.GetX()) > std::numeric_limits<float>::epsilon()) ? 100.f * std::fabs(direction1.GetX()) : 1.f);
81
82 float pX(s1 * direction1.GetX()), pU(0.f), pV(0.f), pW(0.f);
83 HitType newView(HIT_CUSTOM);
84
85 if ((view1 == TPC_VIEW_U) && (view2 == TPC_VIEW_V))
86 {
87 pU = s1 * direction1.GetZ();
88 pV = s2 * direction2.GetZ();
89 newView = TPC_VIEW_W;
90 }
91
92 if ((view1 == TPC_VIEW_V) && (view2 == TPC_VIEW_U))
93 {
94 pV = s1 * direction1.GetZ();
95 pU = s2 * direction2.GetZ();
96 newView = TPC_VIEW_W;
97 }
98
99 if ((view1 == TPC_VIEW_W) && (view2 == TPC_VIEW_U))
100 {
101 pW = s1 * direction1.GetZ();
102 pU = s2 * direction2.GetZ();
103 newView = TPC_VIEW_V;
104 }
105
106 if ((view1 == TPC_VIEW_U) && (view2 == TPC_VIEW_W))
107 {
108 pU = s1 * direction1.GetZ();
109 pW = s2 * direction2.GetZ();
110 newView = TPC_VIEW_V;
111 }
112
113 if ((view1 == TPC_VIEW_V) && (view2 == TPC_VIEW_W))
114 {
115 pV = s1 * direction1.GetZ();
116 pW = s2 * direction2.GetZ();
117 newView = TPC_VIEW_U;
118 }
119
120 if ((view1 == TPC_VIEW_W) && (view2 == TPC_VIEW_V))
121 {
122 pW = s1 * direction1.GetZ();
123 pV = s2 * direction2.GetZ();
124 newView = TPC_VIEW_U;
125 }
126
127 if (newView == TPC_VIEW_W)
128 return CartesianVector(pX, 0.f, pandora.GetPlugins()->GetLArTransformationPlugin()->UVtoW(pU, pV)).GetUnitVector();
129
130 if (newView == TPC_VIEW_U)
131 return CartesianVector(pX, 0.f, pandora.GetPlugins()->GetLArTransformationPlugin()->VWtoU(pV, pW)).GetUnitVector();
132
133 if (newView == TPC_VIEW_V)
134 return CartesianVector(pX, 0.f, pandora.GetPlugins()->GetLArTransformationPlugin()->WUtoV(pW, pU)).GetUnitVector();
135
136 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
137}
138
139//------------------------------------------------------------------------------------------------------------------------------------------
140
142 const CartesianVector &position1, const CartesianVector &position2, CartesianVector &position3, float &chiSquared)
143{
144 if (view1 == view2)
145 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
146
147 const float X3((position1.GetX() + position2.GetX()) / 2.f);
148 const float Z1(position1.GetZ());
149 const float Z2(position2.GetZ());
150 const float Z3(LArGeometryHelper::MergeTwoPositions(pandora, view1, view2, Z1, Z2));
151
152 position3.SetValues(X3, 0.f, Z3);
153 const float sigmaUVW(LArGeometryHelper::GetSigmaUVW(pandora));
154 chiSquared = ((X3 - position1.GetX()) * (X3 - position1.GetX()) + (X3 - position2.GetX()) * (X3 - position2.GetX())) / (sigmaUVW * sigmaUVW);
155}
156
157//------------------------------------------------------------------------------------------------------------------------------------------
158
159void LArGeometryHelper::MergeTwoPositions(const Pandora &pandora, const HitType view1, const HitType view2, const CartesianVector &position1,
160 const CartesianVector &position2, CartesianVector &outputU, CartesianVector &outputV, CartesianVector &outputW, float &chiSquared)
161{
162 if (view1 == view2)
163 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
164
165 CartesianVector position3(0.f, 0.f, 0.f);
166 LArGeometryHelper::MergeTwoPositions(pandora, view1, view2, position1, position2, position3, chiSquared);
167
168 float aveU(0.f), aveV(0.f), aveW(0.f);
169 const float Z1(position1.GetZ()), Z2(position2.GetZ()), Z3(position3.GetZ()), aveX(position3.GetX());
170
171 if ((view1 == TPC_VIEW_U) && (view2 == TPC_VIEW_V))
172 {
173 aveU = Z1;
174 aveV = Z2;
175 aveW = Z3;
176 }
177
178 if ((view1 == TPC_VIEW_V) && (view2 == TPC_VIEW_W))
179 {
180 aveV = Z1;
181 aveW = Z2;
182 aveU = Z3;
183 }
184
185 if ((view1 == TPC_VIEW_W) && (view2 == TPC_VIEW_U))
186 {
187 aveW = Z1;
188 aveU = Z2;
189 aveV = Z3;
190 }
191
192 if ((view1 == TPC_VIEW_V) && (view2 == TPC_VIEW_U))
193 {
194 aveV = Z1;
195 aveU = Z2;
196 aveW = Z3;
197 }
198
199 if ((view1 == TPC_VIEW_W) && (view2 == TPC_VIEW_V))
200 {
201 aveW = Z1;
202 aveV = Z2;
203 aveU = Z3;
204 }
205
206 if ((view1 == TPC_VIEW_U) && (view2 == TPC_VIEW_W))
207 {
208 aveU = Z1;
209 aveW = Z2;
210 aveV = Z3;
211 }
212
213 outputU.SetValues(aveX, 0.f, aveU);
214 outputV.SetValues(aveX, 0.f, aveV);
215 outputW.SetValues(aveX, 0.f, aveW);
216}
217
218//------------------------------------------------------------------------------------------------------------------------------------------
219
220void LArGeometryHelper::MergeThreePositions(const Pandora &pandora, const HitType view1, const HitType view2, const HitType view3,
221 const CartesianVector &position1, const CartesianVector &position2, const CartesianVector &position3, CartesianVector &outputU,
222 CartesianVector &outputV, CartesianVector &outputW, float &chiSquared)
223{
224 if ((view1 == view2) || (view2 == view3) || (view3 == view1))
225 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
226
227 if ((view1 == TPC_VIEW_U) && (view2 == TPC_VIEW_V))
228 {
229 return LArGeometryHelper::MergeThreePositions(pandora, position1, position2, position3, outputU, outputV, outputW, chiSquared);
230 }
231
232 if ((view1 == TPC_VIEW_V) && (view2 == TPC_VIEW_W))
233 {
234 return LArGeometryHelper::MergeThreePositions(pandora, position3, position1, position2, outputU, outputV, outputW, chiSquared);
235 }
236
237 if ((view1 == TPC_VIEW_W) && (view2 == TPC_VIEW_U))
238 {
239 return LArGeometryHelper::MergeThreePositions(pandora, position2, position3, position1, outputU, outputV, outputW, chiSquared);
240 }
241
242 if ((view1 == TPC_VIEW_V) && (view2 == TPC_VIEW_U))
243 {
244 return LArGeometryHelper::MergeThreePositions(pandora, position2, position1, position3, outputU, outputV, outputW, chiSquared);
245 }
246
247 if ((view1 == TPC_VIEW_W) && (view2 == TPC_VIEW_V))
248 {
249 return LArGeometryHelper::MergeThreePositions(pandora, position3, position2, position1, outputU, outputV, outputW, chiSquared);
250 }
251
252 if ((view1 == TPC_VIEW_U) && (view2 == TPC_VIEW_W))
253 {
254 return LArGeometryHelper::MergeThreePositions(pandora, position1, position3, position2, outputU, outputV, outputW, chiSquared);
255 }
256
257 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
258}
259
260//------------------------------------------------------------------------------------------------------------------------------------------
261
263 const CartesianVector &positionW, CartesianVector &outputU, CartesianVector &outputV, CartesianVector &outputW, float &chiSquared)
264{
265 const float YfromUV(pandora.GetPlugins()->GetLArTransformationPlugin()->UVtoY(positionU.GetZ(), positionV.GetZ()));
266 const float YfromUW(pandora.GetPlugins()->GetLArTransformationPlugin()->UWtoY(positionU.GetZ(), positionW.GetZ()));
267 const float YfromVW(pandora.GetPlugins()->GetLArTransformationPlugin()->VWtoY(positionV.GetZ(), positionW.GetZ()));
268
269 const float ZfromUV(pandora.GetPlugins()->GetLArTransformationPlugin()->UVtoZ(positionU.GetZ(), positionV.GetZ()));
270 const float ZfromUW(pandora.GetPlugins()->GetLArTransformationPlugin()->UWtoZ(positionU.GetZ(), positionW.GetZ()));
271 const float ZfromVW(pandora.GetPlugins()->GetLArTransformationPlugin()->VWtoZ(positionV.GetZ(), positionW.GetZ()));
272
273 // ATTN For detectors where w and z are equivalent, remain consistent with original treatment. TODO Use new treatment always.
274 const bool useOldWZEquivalentTreatment(std::fabs(ZfromUW - ZfromVW) < std::numeric_limits<float>::epsilon());
275 const float aveX((positionU.GetX() + positionV.GetX() + positionW.GetX()) / 3.f);
276 const float aveY(useOldWZEquivalentTreatment ? YfromUV : (YfromUV + YfromUW + YfromVW) / 3.f);
277 const float aveZ(useOldWZEquivalentTreatment ? (positionW.GetZ() + 2.f * ZfromUV) / 3.f : (ZfromUV + ZfromUW + ZfromVW) / 3.f);
278
279 const float aveU(pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoU(aveY, aveZ));
280 const float aveV(pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoV(aveY, aveZ));
281 const float aveW(pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoW(aveY, aveZ));
282
283 outputU.SetValues(aveX, 0.f, aveU);
284 outputV.SetValues(aveX, 0.f, aveV);
285 outputW.SetValues(aveX, 0.f, aveW);
286
287 const float sigmaUVW(LArGeometryHelper::GetSigmaUVW(pandora));
288 chiSquared = ((outputU.GetX() - positionU.GetX()) * (outputU.GetX() - positionU.GetX()) +
289 (outputV.GetX() - positionV.GetX()) * (outputV.GetX() - positionV.GetX()) +
290 (outputW.GetX() - positionW.GetX()) * (outputW.GetX() - positionW.GetX()) +
291 (outputU.GetZ() - positionU.GetZ()) * (outputU.GetZ() - positionU.GetZ()) +
292 (outputV.GetZ() - positionV.GetZ()) * (outputV.GetZ() - positionV.GetZ()) +
293 (outputW.GetZ() - positionW.GetZ()) * (outputW.GetZ() - positionW.GetZ())) /
294 (sigmaUVW * sigmaUVW);
295}
296
297//------------------------------------------------------------------------------------------------------------------------------------------
298
300 const CartesianVector &position1, const CartesianVector &position2, CartesianVector &position3D, float &chiSquared)
301{
302 CartesianVector positionU(0.f, 0.f, 0.f), positionV(0.f, 0.f, 0.f), positionW(0.f, 0.f, 0.f);
303 LArGeometryHelper::MergeTwoPositions(pandora, view1, view2, position1, position2, positionU, positionV, positionW, chiSquared);
304
305 position3D.SetValues(positionW.GetX(), pandora.GetPlugins()->GetLArTransformationPlugin()->UVtoY(positionU.GetZ(), positionV.GetZ()),
306 pandora.GetPlugins()->GetLArTransformationPlugin()->UVtoZ(positionU.GetZ(), positionV.GetZ()));
307}
308
309//------------------------------------------------------------------------------------------------------------------------------------------
310
311void LArGeometryHelper::MergeThreePositions3D(const Pandora &pandora, const HitType view1, const HitType view2, const HitType view3,
312 const CartesianVector &position1, const CartesianVector &position2, const CartesianVector &position3, CartesianVector &position3D, float &chiSquared)
313{
314 CartesianVector positionU(0.f, 0.f, 0.f), positionV(0.f, 0.f, 0.f), positionW(0.f, 0.f, 0.f);
315 LArGeometryHelper::MergeThreePositions(pandora, view1, view2, view3, position1, position2, position3, positionU, positionV, positionW, chiSquared);
316
317 position3D.SetValues(positionW.GetX(), pandora.GetPlugins()->GetLArTransformationPlugin()->UVtoY(positionU.GetZ(), positionV.GetZ()),
318 pandora.GetPlugins()->GetLArTransformationPlugin()->UVtoZ(positionU.GetZ(), positionV.GetZ()));
319}
320
321//------------------------------------------------------------------------------------------------------------------------------------------
322
324{
325 if (view == TPC_VIEW_U)
326 {
327 return CartesianVector(
328 position3D.GetX(), 0.f, pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoU(position3D.GetY(), position3D.GetZ()));
329 }
330
331 else if (view == TPC_VIEW_V)
332 {
333 return CartesianVector(
334 position3D.GetX(), 0.f, pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoV(position3D.GetY(), position3D.GetZ()));
335 }
336
337 else if (view == TPC_VIEW_W)
338 {
339 return CartesianVector(
340 position3D.GetX(), 0.f, pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoW(position3D.GetY(), position3D.GetZ()));
341 }
342
343 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
344}
345
346//------------------------------------------------------------------------------------------------------------------------------------------
347
349{
350 if (view == TPC_VIEW_U)
351 {
352 return CartesianVector(
353 direction3D.GetX(), 0.f, pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoU(direction3D.GetY(), direction3D.GetZ()))
354 .GetUnitVector();
355 }
356
357 else if (view == TPC_VIEW_V)
358 {
359 return CartesianVector(
360 direction3D.GetX(), 0.f, pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoV(direction3D.GetY(), direction3D.GetZ()))
361 .GetUnitVector();
362 }
363
364 else if (view == TPC_VIEW_W)
365 {
366 return CartesianVector(
367 direction3D.GetX(), 0.f, pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoW(direction3D.GetY(), direction3D.GetZ()))
368 .GetUnitVector();
369 }
370
371 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
372}
373
374//------------------------------------------------------------------------------------------------------------------------------------------
375
376float LArGeometryHelper::GetWirePitch(const Pandora &pandora, const HitType view, const float maxWirePitchDiscrepancy)
377{
378 if (view != TPC_VIEW_U && view != TPC_VIEW_V && view != TPC_VIEW_W)
379 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
380
381 const LArTPCMap &larTPCMap(pandora.GetGeometry()->GetLArTPCMap());
382
383 if (larTPCMap.empty())
384 {
385 std::cout << "LArGeometryHelper::GetWirePitch - LArTPC description not registered with Pandora as required " << std::endl;
386 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
387 }
388
389 const LArTPC *const pFirstLArTPC(larTPCMap.begin()->second);
390 const float wirePitch(view == TPC_VIEW_U ? pFirstLArTPC->GetWirePitchU()
391 : (view == TPC_VIEW_V ? pFirstLArTPC->GetWirePitchV() : pFirstLArTPC->GetWirePitchW()));
392
393 for (const LArTPCMap::value_type &mapEntry : larTPCMap)
394 {
395 const LArTPC *const pLArTPC(mapEntry.second);
396 const float alternateWirePitch(
397 view == TPC_VIEW_U ? pLArTPC->GetWirePitchU() : (view == TPC_VIEW_V ? pLArTPC->GetWirePitchV() : pLArTPC->GetWirePitchW()));
398
399 if (std::fabs(wirePitch - alternateWirePitch) > maxWirePitchDiscrepancy)
400 {
401 std::cout << "LArGeometryHelper::GetWirePitch - LArTPC configuration not supported" << std::endl;
402 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
403 }
404 }
405
406 return wirePitch;
407}
408
409//------------------------------------------------------------------------------------------------------------------------------------------
410
412{
413 if (view == TPC_VIEW_U)
414 {
415 return CartesianVector(0.f, pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoU(1.f, 0.f),
416 pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoU(0.f, 1.f));
417 }
418
419 else if (view == TPC_VIEW_V)
420 {
421 return CartesianVector(0.f, pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoV(1.f, 0.f),
422 pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoV(0.f, 1.f));
423 }
424
425 else if (view == TPC_VIEW_W)
426 {
427 return CartesianVector(0.f, pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoW(1.f, 0.f),
428 pandora.GetPlugins()->GetLArTransformationPlugin()->YZtoW(0.f, 1.f));
429 }
430
431 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
432}
433
434//------------------------------------------------------------------------------------------------------------------------------------------
435
436void LArGeometryHelper::GetCommonDaughterVolumes(const Cluster *const pCluster1, const Cluster *const pCluster2, UIntSet &intersect)
437{
438 UIntSet daughterVolumeIds1, daughterVolumeIds2;
439
440 LArClusterHelper::GetDaughterVolumeIDs(pCluster1, daughterVolumeIds1);
441 LArClusterHelper::GetDaughterVolumeIDs(pCluster2, daughterVolumeIds2);
442
443 std::set_intersection(daughterVolumeIds1.begin(), daughterVolumeIds1.end(), daughterVolumeIds2.begin(), daughterVolumeIds2.end(),
444 std::inserter(intersect, intersect.begin()));
445}
446
447//------------------------------------------------------------------------------------------------------------------------------------------
448
449bool LArGeometryHelper::IsInGap(const Pandora &pandora, const CartesianVector &testPoint2D, const HitType hitType, const float gapTolerance)
450{
451 // ATTN: input test point MUST be a 2D position vector
452 for (const DetectorGap *const pDetectorGap : pandora.GetGeometry()->GetDetectorGapList())
453 {
454 if (pDetectorGap->IsInGap(testPoint2D, hitType, gapTolerance))
455 return true;
456 }
457
458 return false;
459}
460
461//------------------------------------------------------------------------------------------------------------------------------------------
462
463bool LArGeometryHelper::IsInGap3D(const Pandora &pandora, const CartesianVector &testPoint3D, const HitType hitType, const float gapTolerance)
464{
465 const CartesianVector testPoint2D(LArGeometryHelper::ProjectPosition(pandora, testPoint3D, hitType));
466 return LArGeometryHelper::IsInGap(pandora, testPoint2D, hitType, gapTolerance);
467}
468
469//------------------------------------------------------------------------------------------------------------------------------------------
470
471bool LArGeometryHelper::IsXSamplingPointInGap(const Pandora &pandora, const float xSample, const TwoDSlidingFitResult &slidingFitResult, const float gapTolerance)
472{
473 const HitType hitType(LArClusterHelper::GetClusterHitType(slidingFitResult.GetCluster()));
474 const CartesianVector minLayerPosition(slidingFitResult.GetGlobalMinLayerPosition());
475 const CartesianVector maxLayerPosition(slidingFitResult.GetGlobalMaxLayerPosition());
476
477 const bool minLayerIsAtLowX(minLayerPosition.GetX() < maxLayerPosition.GetX());
478 const CartesianVector &lowXCoordinate(minLayerIsAtLowX ? minLayerPosition : maxLayerPosition);
479 const CartesianVector &highXCoordinate(minLayerIsAtLowX ? maxLayerPosition : minLayerPosition);
480
481 if ((xSample > lowXCoordinate.GetX()) && (xSample < highXCoordinate.GetX()))
482 {
483 CartesianVector slidingFitPosition(0.f, 0.f, 0.f);
484
485 if (STATUS_CODE_SUCCESS == slidingFitResult.GetGlobalFitPositionAtX(xSample, slidingFitPosition))
486 return (LArGeometryHelper::IsInGap(pandora, slidingFitPosition, hitType, gapTolerance));
487 }
488
489 const CartesianVector lowXDirection(
490 minLayerIsAtLowX ? slidingFitResult.GetGlobalMinLayerDirection() : slidingFitResult.GetGlobalMaxLayerDirection());
491 const CartesianVector highXDirection(
492 minLayerIsAtLowX ? slidingFitResult.GetGlobalMaxLayerDirection() : slidingFitResult.GetGlobalMinLayerDirection());
493
494 const bool sampleIsNearerToLowX(std::fabs(xSample - lowXCoordinate.GetX()) < std::fabs(xSample - highXCoordinate.GetX()));
495 const CartesianVector &startPosition(sampleIsNearerToLowX ? lowXCoordinate : highXCoordinate);
496 const CartesianVector &startDirection(sampleIsNearerToLowX ? lowXDirection : highXDirection);
497
498 if (std::fabs(startDirection.GetX()) < std::numeric_limits<float>::epsilon())
499 throw StatusCodeException(STATUS_CODE_NOT_FOUND);
500
501 const float pathLength((xSample - startPosition.GetX()) / startDirection.GetX());
502 const CartesianVector samplingPoint(startPosition + startDirection * pathLength);
503
504 return (LArGeometryHelper::IsInGap(pandora, samplingPoint, hitType, gapTolerance));
505}
506
507//------------------------------------------------------------------------------------------------------------------------------------------
508
509float LArGeometryHelper::CalculateGapDeltaZ(const Pandora &pandora, const float minZ, const float maxZ, const HitType hitType)
510{
511 if (maxZ - minZ < std::numeric_limits<float>::epsilon())
512 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
513
514 float gapDeltaZ(0.f);
515
516 for (const DetectorGap *const pDetectorGap : pandora.GetGeometry()->GetDetectorGapList())
517 {
518 const LineGap *const pLineGap = dynamic_cast<const LineGap *>(pDetectorGap);
519
520 if (!pLineGap)
521 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
522
523 const LineGapType lineGapType(pLineGap->GetLineGapType());
524
525 if (!(((TPC_VIEW_U == hitType) && (TPC_WIRE_GAP_VIEW_U == lineGapType)) || ((TPC_VIEW_V == hitType) && (TPC_WIRE_GAP_VIEW_V == lineGapType)) ||
526 ((TPC_VIEW_W == hitType) && (TPC_WIRE_GAP_VIEW_W == lineGapType))))
527 {
528 continue;
529 }
530
531 if ((pLineGap->GetLineStartZ() > maxZ) || (pLineGap->GetLineEndZ() < minZ))
532 continue;
533
534 const float gapMinZ(std::max(minZ, pLineGap->GetLineStartZ()));
535 const float gapMaxZ(std::min(maxZ, pLineGap->GetLineEndZ()));
536
537 if ((gapMaxZ - gapMinZ) > std::numeric_limits<float>::epsilon())
538 gapDeltaZ += (gapMaxZ - gapMinZ);
539 }
540
541 return gapDeltaZ;
542}
543
544//------------------------------------------------------------------------------------------------------------------------------------------
545
546float LArGeometryHelper::GetSigmaUVW(const Pandora &pandora, const float maxSigmaDiscrepancy)
547{
548 const LArTPCMap &larTPCMap(pandora.GetGeometry()->GetLArTPCMap());
549
550 if (larTPCMap.empty())
551 {
552 std::cout << "LArGeometryHelper::GetSigmaUVW - LArTPC description not registered with Pandora as required " << std::endl;
553 throw StatusCodeException(STATUS_CODE_NOT_INITIALIZED);
554 }
555
556 const LArTPC *const pFirstLArTPC(larTPCMap.begin()->second);
557 const float sigmaUVW(pFirstLArTPC->GetSigmaUVW());
558
559 for (const LArTPCMap::value_type &mapEntry : larTPCMap)
560 {
561 const LArTPC *const pLArTPC(mapEntry.second);
562
563 if (std::fabs(sigmaUVW - pLArTPC->GetSigmaUVW()) > maxSigmaDiscrepancy)
564 {
565 std::cout << "LArGeometryHelper::GetSigmaUVW - Plugin does not support provided LArTPC configurations " << std::endl;
566 throw StatusCodeException(STATUS_CODE_INVALID_PARAMETER);
567 }
568 }
569
570 return sigmaUVW;
571}
572
573} // namespace lar_content
Header file for the cartesian vector class.
Header file for the detector gap class.
Header file for the geometry manager class.
Header file for the cluster helper class.
Header file for the geometry helper class.
Header file for the lar tpc class.
Header file for the lar transformation plugin interface class.
Header file for the lar two dimensional sliding fit result class.
Header file for the pandora class.
Header file for the pandora plugin manager class.
static pandora::HitType GetClusterHitType(const pandora::Cluster *const pCluster)
Get the hit type associated with a two dimensional cluster.
static void GetDaughterVolumeIDs(const pandora::Cluster *const pCluster, UIntSet &daughterVolumeIds)
Get the set of the daughter volumes that contains the cluster.
static float GetSigmaUVW(const pandora::Pandora &pandora, const float maxSigmaDiscrepancy=0.01)
Find the sigmaUVW value for the detector geometry.
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).
std::set< unsigned int > UIntSet
static void GetCommonDaughterVolumes(const pandora::Cluster *const pCluster1, const pandora::Cluster *const pCluster2, UIntSet &intersect)
Return the set of common daughter volumes between two 2D clusters.
static pandora::CartesianVector GetWireAxis(const pandora::Pandora &pandora, const pandora::HitType view)
Return the wire axis (vector perpendicular to the wire direction and drift direction)
static void MergeThreePositions(const pandora::Pandora &pandora, const pandora::HitType view1, const pandora::HitType view2, const pandora::HitType view3, const pandora::CartesianVector &position1, const pandora::CartesianVector &position2, const pandora::CartesianVector &position3, pandora::CartesianVector &outputU, pandora::CartesianVector &outputV, pandora::CartesianVector &outputW, float &chiSquared)
Merge 2D positions from three views to give unified 2D positions for each view.
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 bool IsInGap(const pandora::Pandora &pandora, const pandora::CartesianVector &testPoint2D, const pandora::HitType hitType, const float gapTolerance=0.f)
Whether a 2D test point lies in a registered gap with the associated hit type.
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.
static bool IsXSamplingPointInGap(const pandora::Pandora &pandora, const float xSample, const TwoDSlidingFitResult &slidingFitResult, const float gapTolerance=0.f)
Whether there is a gap in a cluster (described via its sliding fit result) at a specified x sampling ...
static pandora::CartesianVector ProjectDirection(const pandora::Pandora &pandora, const pandora::CartesianVector &direction3D, const pandora::HitType view)
Project 3D direction into a given 2D view.
static bool IsInGap3D(const pandora::Pandora &pandora, const pandora::CartesianVector &testPoint3D, const pandora::HitType hitType, const float gapTolerance=0.f)
Whether a 3D test point lies in a registered gap with the associated hit type.
static void MergeThreePositions3D(const pandora::Pandora &pandora, const pandora::HitType view1, const pandora::HitType view2, const pandora::HitType view3, const pandora::CartesianVector &position1, const pandora::CartesianVector &position2, const pandora::CartesianVector &position3, pandora::CartesianVector &position3D, float &chiSquared)
Merge 2D positions from three views to give unified 3D position.
static float CalculateGapDeltaZ(const pandora::Pandora &pandora, const float minZ, const float maxZ, const pandora::HitType hitType)
Calculate the total distance within a given 2D region that is composed of detector gaps.
pandora::CartesianVector GetGlobalMinLayerPosition() const
Get global position corresponding to the fit result in minimum fit layer.
pandora::CartesianVector GetGlobalMinLayerDirection() const
Get global direction corresponding to the fit result in minimum fit layer.
pandora::CartesianVector GetGlobalMaxLayerPosition() const
Get global position corresponding to the fit result in maximum fit layer.
const pandora::Cluster * GetCluster() const
Get the address of the cluster, if originally provided.
pandora::CartesianVector GetGlobalMaxLayerDirection() const
Get global direction corresponding to the fit result in maximum fit layer.
pandora::StatusCode GetGlobalFitPositionAtX(const float x, pandora::CartesianVector &position) const
Get global fit position for a given input x coordinate.
CartesianVector class.
void SetValues(float x, float y, float z)
Set the values of cartesian vector components.
float GetX() const
Get the cartesian x coordinate.
CartesianVector GetUnitVector() const
Get a unit vector in the direction of the cartesian vector.
float GetZ() const
Get the cartesian z coordinate.
float GetY() const
Get the cartesian y coordinate.
Cluster class.
Definition Cluster.h:31
DetectorGap class.
Definition DetectorGap.h:25
LArTPC class.
Definition LArTPC.h:26
float GetWirePitchU() const
Get the u wire pitch, units mm.
Definition LArTPC.h:217
float GetWirePitchV() const
Get the v wire pitch, units mm.
Definition LArTPC.h:224
float GetWirePitchW() const
Get the w wire pitch, units mm.
Definition LArTPC.h:231
float GetSigmaUVW() const
Get the u, v, w resolution, units mm.
Definition LArTPC.h:259
LineGap class, associated only with 2D TPC hit types and applied only to the z coordinate when sampli...
Definition DetectorGap.h:50
float GetLineEndZ() const
Get the line end z coordinate.
LineGapType GetLineGapType() const
Get the line gap type.
float GetLineStartZ() const
Get the line start z coordinate.
Pandora class.
Definition Pandora.h:40
StatusCodeException class.
HitType
Calorimeter hit type enum.
std::map< unsigned int, const LArTPC * > LArTPCMap
LineGapType
Line gap type.