Pandora
Pandora source code navigator
Loading...
Searching...
No Matches
LArPandoraGeometry.cxx
Go to the documentation of this file.
1
8
9#include "art/Framework/Services/Registry/ServiceHandle.h"
10#include "cetlib_except/exception.h"
11
12#include "larcore/Geometry/Geometry.h"
13#include "larcorealg/Geometry/PlaneGeo.h"
14#include "larcorealg/Geometry/TPCGeo.h"
15#include "larcorealg/Geometry/WireGeo.h"
16
19
20#include <iomanip>
21#include <set>
22
23namespace lar_pandora {
24
26 const bool useActiveBoundingBox)
27 {
28 // Detector gaps can only be loaded once - throw an exception if the output lists are already filled
29 if (!listOfGaps.empty())
30 throw cet::exception("LArPandora")
31 << " LArPandoraGeometry::LoadDetectorGaps --- the list of gaps already exists ";
32
33 // Loop over drift volumes and write out the dead regions at their boundaries
34 LArDriftVolumeList driftVolumeList;
35 LArPandoraGeometry::LoadGeometry(driftVolumeList, useActiveBoundingBox);
36
38
39 for (LArDriftVolumeList::const_iterator iter1 = driftVolumeList.begin(),
40 iterEnd1 = driftVolumeList.end();
41 iter1 != iterEnd1;
42 ++iter1) {
43 const LArDriftVolume& driftVolume1 = *iter1;
44
45 for (LArDriftVolumeList::const_iterator iter2 = iter1, iterEnd2 = driftVolumeList.end();
46 iter2 != iterEnd2;
47 ++iter2) {
48 const LArDriftVolume& driftVolume2 = *iter2;
49
50 if (driftVolume1.GetVolumeID() == driftVolume2.GetVolumeID()) continue;
51
52 const float maxDisplacement(LArDetectorGap::GetMaxGapSize());
53
54 const float deltaX(std::fabs(driftVolume1.GetCenterX() - driftVolume2.GetCenterX()));
55 const float deltaY(std::fabs(driftVolume1.GetCenterY() - driftVolume2.GetCenterY()));
56 const float deltaZ(std::fabs(driftVolume1.GetCenterZ() - driftVolume2.GetCenterZ()));
57
58 const float widthX(0.5f * (driftVolume1.GetWidthX() + driftVolume2.GetWidthX()));
59 const float widthY(0.5f * (driftVolume1.GetWidthY() + driftVolume2.GetWidthY()));
60 const float widthZ(0.5f * (driftVolume1.GetWidthZ() + driftVolume2.GetWidthZ()));
61
62 const float gapX(deltaX - widthX);
63 const float gapY(deltaY - widthY);
64 const float gapZ(deltaZ - widthZ);
65
66 const float X1((driftVolume1.GetCenterX() < driftVolume2.GetCenterX()) ?
67 (driftVolume1.GetCenterX() + 0.5f * driftVolume1.GetWidthX()) :
68 (driftVolume2.GetCenterX() + 0.5f * driftVolume2.GetWidthX()));
69 const float X2((driftVolume1.GetCenterX() > driftVolume2.GetCenterX()) ?
70 (driftVolume1.GetCenterX() - 0.5f * driftVolume1.GetWidthX()) :
71 (driftVolume2.GetCenterX() - 0.5f * driftVolume2.GetWidthX()));
72 const float Y1(std::min((driftVolume1.GetCenterY() - 0.5f * driftVolume1.GetWidthY()),
73 (driftVolume2.GetCenterY() - 0.5f * driftVolume2.GetWidthY())));
74 const float Y2(std::max((driftVolume1.GetCenterY() + 0.5f * driftVolume1.GetWidthY()),
75 (driftVolume2.GetCenterY() + 0.5f * driftVolume2.GetWidthY())));
76 const float Z1(std::min((driftVolume1.GetCenterZ() - 0.5f * driftVolume1.GetWidthZ()),
77 (driftVolume2.GetCenterZ() - 0.5f * driftVolume2.GetWidthZ())));
78 const float Z2(std::max((driftVolume1.GetCenterZ() + 0.5f * driftVolume1.GetWidthZ()),
79 (driftVolume2.GetCenterZ() + 0.5f * driftVolume2.GetWidthZ())));
80
81 geo::Vector_t gaps(gapX, gapY, gapZ), deltas(deltaX, deltaY, deltaZ);
82 if (detType->CheckDetectorGapSize(gaps, deltas, maxDisplacement)) {
83 geo::Point_t point1(X1, Y1, Z1), point2(X2, Y2, Z2);
84 geo::Vector_t widths(widthX, widthY, widthZ);
85 listOfGaps.emplace_back(detType->CreateDetectorGap(point1, point2, widths));
86 }
87 }
88
89 detType->LoadDaughterDetectorGaps(driftVolume1, LArDetectorGap::GetMaxGapSize(), listOfGaps);
90 }
91 }
92
93 //------------------------------------------------------------------------------------------------------------------------------------------
94
96 LArDriftVolumeMap& outputVolumeMap,
97 const bool useActiveBoundingBox)
98 {
99 if (!outputVolumeList.empty())
100 throw cet::exception("LArPandora")
101 << " LArPandoraGeometry::LoadGeometry --- the list of drift volumes already exists ";
102
103 LArPandoraGeometry::LoadGeometry(outputVolumeList, useActiveBoundingBox);
104
105 // Create mapping between tpc/cstat labels and drift volumes
106 for (const LArDriftVolume& driftVolume : outputVolumeList) {
107 for (const LArDaughterDriftVolume& tpcVolume : driftVolume.GetTpcVolumeList()) {
108 (void)outputVolumeMap.insert(LArDriftVolumeMap::value_type(
109 LArPandoraGeometry::GetTpcID(tpcVolume.GetCryostat(), tpcVolume.GetTpc()), driftVolume));
110 }
111 }
112 }
113
114 //------------------------------------------------------------------------------------------------------------------------------------------
115
116 unsigned int LArPandoraGeometry::GetVolumeID(const LArDriftVolumeMap& driftVolumeMap,
117 const unsigned int cstat,
118 const unsigned int tpc)
119 {
120 if (driftVolumeMap.empty())
121 throw cet::exception("LArPandora")
122 << " LArPandoraGeometry::GetVolumeID --- detector geometry map is empty";
123
124 LArDriftVolumeMap::const_iterator iter =
125 driftVolumeMap.find(LArPandoraGeometry::GetTpcID(cstat, tpc));
126
127 if (driftVolumeMap.end() == iter)
128 throw cet::exception("LArPandora")
129 << " LArPandoraGeometry::GetVolumeID --- found a TPC that doesn't belong to a drift volume";
130
131 return iter->second.GetVolumeID();
132 }
133
134 //------------------------------------------------------------------------------------------------------------------------------------------
135
137 const unsigned int cstat,
138 const unsigned int tpc)
139 {
140 if (driftVolumeMap.empty())
141 throw cet::exception("LArPandora")
142 << " LArPandoraGeometry::GetDaughterVolumeID --- detector geometry map is empty";
143
144 LArDriftVolumeMap::const_iterator iter =
145 driftVolumeMap.find(LArPandoraGeometry::GetTpcID(cstat, tpc));
146
147 if (driftVolumeMap.end() == iter)
148 throw cet::exception("LArPandora") << " LArPandoraGeometry::GetDaughterVolumeID --- found a "
149 "TPC volume that doesn't belong to a drift volume";
150
151 for (LArDaughterDriftVolumeList::const_iterator
152 iterDghtr = iter->second.GetTpcVolumeList().begin(),
153 iterDghtrEnd = iter->second.GetTpcVolumeList().end();
154 iterDghtr != iterDghtrEnd;
155 ++iterDghtr) {
156 const LArDaughterDriftVolume& daughterVolume(*iterDghtr);
157 if (cstat == daughterVolume.GetCryostat() && tpc == daughterVolume.GetTpc())
158 return std::distance(iter->second.GetTpcVolumeList().begin(), iterDghtr);
159 }
160 throw cet::exception("LArPandora")
161 << " LArPandoraGeometry::GetDaughterVolumeID --- found a daughter volume that doesn't belong "
162 "to the drift volume ";
163 }
164
165 //------------------------------------------------------------------------------------------------------------------------------------------
166
167 geo::View_t LArPandoraGeometry::GetGlobalView(const unsigned int cstat,
168 const unsigned int tpc,
169 const geo::View_t hit_View)
170 {
171 const bool switchUV(LArPandoraGeometry::ShouldSwitchUV(cstat, tpc));
172
173 // ATTN This implicitly assumes that there will be u, v and (maybe) one of either w or y views
174 if ((hit_View == geo::kW) || (hit_View == geo::kY)) { return hit_View; }
175 else if (hit_View == geo::kU) {
176 return (switchUV ? geo::kV : geo::kU);
177 }
178 else if (hit_View == geo::kV) {
179 return (switchUV ? geo::kU : geo::kV);
180 }
181
182 throw cet::exception("LArPandora")
183 << " LArPandoraGeometry::GetGlobalView --- found an unknown plane view (not U, V or W) ";
184 }
185
186 //------------------------------------------------------------------------------------------------------------------------------------------
187
188 unsigned int LArPandoraGeometry::GetTpcID(const unsigned int cstat, const unsigned int tpc)
189 {
190 // We assume there will never be more than 10000 TPCs in a cryostat!
191 if (tpc >= 10000)
192 throw cet::exception("LArPandora")
193 << " LArPandoraGeometry::GetTpcID --- found a TPC with an ID greater than 10000 ";
194
195 return ((10000 * cstat) + tpc);
196 }
197
198 //------------------------------------------------------------------------------------------------------------------------------------------
199
200 bool LArPandoraGeometry::ShouldSwitchUV(const unsigned int cstat, const unsigned int tpc)
201 {
202 // We determine whether U and V views should be switched by checking the drift direction
203 art::ServiceHandle<geo::Geometry const> theGeometry;
204 const geo::TPCGeo& theTpc{theGeometry->TPC(geo::TPCID(cstat, tpc))};
205
206 const bool isPositiveDrift(theTpc.DriftDirection() == geo::kPosX);
207 return LArPandoraGeometry::ShouldSwitchUV(isPositiveDrift);
208 }
209
210 //------------------------------------------------------------------------------------------------------------------------------------------
211
212 bool LArPandoraGeometry::ShouldSwitchUV(const bool isPositiveDrift)
213 {
214 // ATTN: In the dual phase scenario the wire planes pointing along two orthogonal directions and so interchanging U and V is unnecessary
215 art::ServiceHandle<geo::Geometry const> theGeometry;
216 if (theGeometry->MaxPlanes() == 2) return false;
217
218 // We assume that all multiple drift volume detectors have the APA - CPA - APA - CPA design
219 return isPositiveDrift;
220 }
221
222 //------------------------------------------------------------------------------------------------------------------------------------------
223
225 const bool useActiveBoundingBox)
226 {
227 // This method will group TPCs into "drift volumes" (these are regions of the detector that share a common drift direction,
228 // common range of x coordinates, and common detector parameters such as wire pitch and wire angle).
229 if (!driftVolumeList.empty())
230 throw cet::exception("LArPandora")
231 << " LArPandoraGeometry::LoadGeometry --- detector geometry has already been loaded ";
232
233 typedef std::set<unsigned int> UIntSet;
234
235 // Pandora requires three independent images, and ability to correlate features between images (via wire angles and transformation plugin).
236 art::ServiceHandle<geo::Geometry const> theGeometry;
238 const float wirePitchU(detType->WirePitchU());
239 const float wirePitchV(detType->WirePitchV());
240 const float wirePitchW(detType->WirePitchW());
241 const float maxDeltaTheta(0.01f); // leave this hard-coded for now
242
243 // Loop over cryostats
244 for (auto const& cryostat : theGeometry->Iterate<geo::CryostatGeo>()) {
245 auto const icstat = cryostat.ID().Cryostat;
246 UIntSet cstatList;
247
248 // Loop over TPCs in in this cryostat
249 for (auto const& theTpc1 : theGeometry->Iterate<geo::TPCGeo>(cryostat.ID())) {
250 auto const itpc1 = theTpc1.ID().TPC;
251 if (cstatList.end() != cstatList.find(itpc1)) continue;
252
253 // Use this TPC to seed a drift volume
254 cstatList.insert(itpc1);
255
256 const float wireAngleU(detType->WireAngleU(itpc1, icstat));
257 const float wireAngleV(detType->WireAngleV(itpc1, icstat));
258 const float wireAngleW(detType->WireAngleW(itpc1, icstat));
259
260 auto const worldCoord1 = theTpc1.GetCenter();
261
262 float driftMinX(useActiveBoundingBox ? theTpc1.ActiveBoundingBox().MinX() :
263 (worldCoord1.X() - theTpc1.ActiveHalfWidth()));
264 float driftMaxX(useActiveBoundingBox ? theTpc1.ActiveBoundingBox().MaxX() :
265 (worldCoord1.X() + theTpc1.ActiveHalfWidth()));
266 float driftMinY(useActiveBoundingBox ? theTpc1.ActiveBoundingBox().MinY() :
267 (worldCoord1.Y() - theTpc1.ActiveHalfHeight()));
268 float driftMaxY(useActiveBoundingBox ? theTpc1.ActiveBoundingBox().MaxY() :
269 (worldCoord1.Y() + theTpc1.ActiveHalfHeight()));
270 float driftMinZ(useActiveBoundingBox ? theTpc1.ActiveBoundingBox().MinZ() :
271 (worldCoord1.Z() - 0.5f * theTpc1.ActiveLength()));
272 float driftMaxZ(useActiveBoundingBox ? theTpc1.ActiveBoundingBox().MaxZ() :
273 (worldCoord1.Z() + 0.5f * theTpc1.ActiveLength()));
274
275 const double min1(
276 useActiveBoundingBox ?
277 (0.5 * (driftMinX + driftMaxX) - 0.25 * std::fabs(driftMaxX - driftMinX)) :
278 (worldCoord1.X() - 0.5 * theTpc1.ActiveHalfWidth()));
279 const double max1(
280 useActiveBoundingBox ?
281 (0.5 * (driftMinX + driftMaxX) + 0.25 * std::fabs(driftMaxX - driftMinX)) :
282 (worldCoord1.X() + 0.5 * theTpc1.ActiveHalfWidth()));
283
284 const bool isPositiveDrift(theTpc1.DriftDirection() == geo::kPosX);
285
286 UIntSet tpcList;
287 tpcList.insert(itpc1);
288
289 LArDaughterDriftVolumeList tpcVolumeList;
290 tpcVolumeList.emplace_back(LArDaughterDriftVolume(icstat,
291 itpc1,
292 0.5f * (driftMaxX + driftMinX),
293 0.5f * (driftMaxY + driftMinY),
294 0.5f * (driftMaxZ + driftMinZ),
295 (driftMaxX - driftMinX),
296 (driftMaxY - driftMinY),
297 (driftMaxZ - driftMinZ)));
298
299 // Now identify the other TPCs associated with this drift volume
300 for (auto const& theTpc2 : theGeometry->Iterate<geo::TPCGeo>(cryostat.ID())) {
301 auto const itpc2 = theTpc2.ID().TPC;
302 if (cstatList.end() != cstatList.find(itpc2)) continue;
303
304 if (theTpc1.DriftDirection() != theTpc2.DriftDirection()) continue;
305
306 const float dThetaU(detType->WireAngleU(itpc1, icstat) -
307 detType->WireAngleU(itpc2, icstat));
308 const float dThetaV(detType->WireAngleV(itpc1, icstat) -
309 detType->WireAngleV(itpc2, icstat));
310 const float dThetaW(detType->WireAngleW(itpc1, icstat) -
311 detType->WireAngleW(itpc2, icstat));
312 if (dThetaU > maxDeltaTheta || dThetaV > maxDeltaTheta || dThetaW > maxDeltaTheta)
313 continue;
314
315 auto const worldCoord2 = theTpc2.GetCenter();
316
317 const float driftMinX2(useActiveBoundingBox ?
318 theTpc2.ActiveBoundingBox().MinX() :
319 (worldCoord2.X() - theTpc2.ActiveHalfWidth()));
320 const float driftMaxX2(useActiveBoundingBox ?
321 theTpc2.ActiveBoundingBox().MaxX() :
322 (worldCoord2.X() + theTpc2.ActiveHalfWidth()));
323
324 const double min2(
325 useActiveBoundingBox ?
326 (0.5 * (driftMinX2 + driftMaxX2) - 0.25 * std::fabs(driftMaxX2 - driftMinX2)) :
327 (worldCoord2.X() - 0.5 * theTpc2.ActiveHalfWidth()));
328 const double max2(
329 useActiveBoundingBox ?
330 (0.5 * (driftMinX2 + driftMaxX2) + 0.25 * std::fabs(driftMaxX2 - driftMinX2)) :
331 (worldCoord2.X() + 0.5 * theTpc2.ActiveHalfWidth()));
332
333 if ((min2 > max1) || (min1 > max2)) continue;
334
335 cstatList.insert(itpc2);
336 tpcList.insert(itpc2);
337
338 const float driftMinY2(useActiveBoundingBox ?
339 theTpc2.ActiveBoundingBox().MinY() :
340 (worldCoord2.Y() - theTpc2.ActiveHalfHeight()));
341 const float driftMaxY2(useActiveBoundingBox ?
342 theTpc2.ActiveBoundingBox().MaxY() :
343 (worldCoord2.Y() + theTpc2.ActiveHalfHeight()));
344 const float driftMinZ2(useActiveBoundingBox ?
345 theTpc2.ActiveBoundingBox().MinZ() :
346 (worldCoord2.Z() - 0.5f * theTpc2.ActiveLength()));
347 const float driftMaxZ2(useActiveBoundingBox ?
348 theTpc2.ActiveBoundingBox().MaxZ() :
349 (worldCoord2.Z() + 0.5f * theTpc2.ActiveLength()));
350
351 driftMinX = std::min(driftMinX, driftMinX2);
352 driftMaxX = std::max(driftMaxX, driftMaxX2);
353 driftMinY = std::min(driftMinY, driftMinY2);
354 driftMaxY = std::max(driftMaxY, driftMaxY2);
355 driftMinZ = std::min(driftMinZ, driftMinZ2);
356 driftMaxZ = std::max(driftMaxZ, driftMaxZ2);
357
358 tpcVolumeList.emplace_back(LArDaughterDriftVolume(icstat,
359 itpc2,
360 0.5f * (driftMaxX2 + driftMinX2),
361 0.5f * (driftMaxY2 + driftMinY2),
362 0.5f * (driftMaxZ2 + driftMinZ2),
363 (driftMaxX2 - driftMinX2),
364 (driftMaxY2 - driftMinY2),
365 (driftMaxZ2 - driftMinZ2)));
366 }
367
368 // Create new daughter drift volume (volume ID = 0 to N-1)
369 driftVolumeList.emplace_back(driftVolumeList.size(),
370 isPositiveDrift,
371 wirePitchU,
372 wirePitchV,
373 wirePitchW,
374 wireAngleU,
375 wireAngleV,
376 wireAngleW,
377 0.5f * (driftMaxX + driftMinX),
378 0.5f * (driftMaxY + driftMinY),
379 0.5f * (driftMaxZ + driftMinZ),
380 (driftMaxX - driftMinX),
381 (driftMaxY - driftMinY),
382 (driftMaxZ - driftMinZ),
383 (wirePitchU + wirePitchV + wirePitchW + 0.1f),
384 tpcVolumeList);
385 }
386 }
387
388 if (driftVolumeList.empty())
389 throw cet::exception("LArPandora") << " LArPandoraGeometry::LoadGeometry --- failed to find "
390 "any drift volumes in this detector geometry ";
391 }
392
393 //------------------------------------------------------------------------------------------------------------------------------------------
394
396 LArDriftVolumeList& daughterVolumeList)
397 {
398 // This method will create one or more daughter volumes (these share a common drift orientation along the X-axis,
399 // have parallel or near-parallel wire angles, and similar wire pitches)
400 //
401 // ATTN: we assume that the U and V planes have equal and opposite wire orientations
402
403 if (!daughterVolumeList.empty())
404 throw cet::exception("LArPandora") << " LArPandoraGeometry::LoadGlobalDaughterGeometry --- "
405 "daughter geometry has already been loaded ";
406
407 if (driftVolumeList.empty())
408 throw cet::exception("LArPandora") << " LArPandoraGeometry::LoadGlobalDaughterGeometry --- "
409 "detector geometry has not yet been loaded ";
410
411 std::cout << "The size of the drif list is: " << driftVolumeList.size() << std::endl;
412 int count(0);
413 // Create daughter drift volumes
414 for (const LArDriftVolume& driftVolume : driftVolumeList) {
415 std::cout << "Looking at dau vol: " << count++ << std::endl;
416 const bool switchViews(LArPandoraGeometry::ShouldSwitchUV(driftVolume.IsPositiveDrift()));
417
418 const float daughterWirePitchU(switchViews ? driftVolume.GetWirePitchV() :
419 driftVolume.GetWirePitchU());
420 const float daughterWirePitchV(switchViews ? driftVolume.GetWirePitchU() :
421 driftVolume.GetWirePitchV());
422 const float daughterWirePitchW(driftVolume.GetWirePitchW());
423 const float daughterWireAngleU(switchViews ? driftVolume.GetWireAngleV() :
424 driftVolume.GetWireAngleU());
425 const float daughterWireAngleV(switchViews ? driftVolume.GetWireAngleU() :
426 driftVolume.GetWireAngleV());
427 const float daughterWireAngleW(driftVolume.GetWireAngleW());
428
429 daughterVolumeList.push_back(LArDriftVolume(driftVolume.GetVolumeID(),
430 driftVolume.IsPositiveDrift(),
431 daughterWirePitchU,
432 daughterWirePitchV,
433 daughterWirePitchW,
434 daughterWireAngleU,
435 daughterWireAngleV,
436 daughterWireAngleW,
437 driftVolume.GetCenterX(),
438 driftVolume.GetCenterY(),
439 driftVolume.GetCenterZ(),
440 driftVolume.GetWidthX(),
441 driftVolume.GetWidthY(),
442 driftVolume.GetWidthZ(),
443 driftVolume.GetSigmaUVZ(),
444 driftVolume.GetTpcVolumeList()));
445 }
446
447 if (daughterVolumeList.empty())
448 throw cet::exception("LArPandora") << " LArPandoraGeometry::LoadGlobalDaughterGeometry --- "
449 "failed to create daughter geometry list ";
450 }
451
452 //------------------------------------------------------------------------------------------------------------------------------------------
453 //------------------------------------------------------------------------------------------------------------------------------------------
454
455 LArDriftVolume::LArDriftVolume(const unsigned int volumeID,
456 const bool isPositiveDrift,
457 const float wirePitchU,
458 const float wirePitchV,
459 const float wirePitchW,
460 const float wireAngleU,
461 const float wireAngleV,
462 const float wireAngleW,
463 const float centerX,
464 const float centerY,
465 const float centerZ,
466 const float widthX,
467 const float widthY,
468 const float widthZ,
469 const float sigmaUVZ,
470 const LArDaughterDriftVolumeList& tpcVolumeList)
471 : m_volumeID(volumeID)
472 , m_isPositiveDrift(isPositiveDrift)
473 , m_wirePitchU(wirePitchU)
474 , m_wirePitchV(wirePitchV)
475 , m_wirePitchW(wirePitchW)
476 , m_wireAngleU(wireAngleU)
477 , m_wireAngleV(wireAngleV)
478 , m_wireAngleW(wireAngleW)
479 , m_centerX(centerX)
480 , m_centerY(centerY)
481 , m_centerZ(centerZ)
482 , m_widthX(widthX)
483 , m_widthY(widthY)
484 , m_widthZ(widthZ)
485 , m_sigmaUVZ(sigmaUVZ)
486 , m_tpcVolumeList(tpcVolumeList)
487 {}
488
489} // namespace lar_pandora
Helper functions for extracting detector geometry for use in reconsruction.
Helper functions for extracting detector geometry for use in reconsruction.
daughter drift volume class to hold properties of daughter drift volumes
unsigned int GetTpc() const
Return tpc ID.
unsigned int GetCryostat() const
Return cryostat ID.
static float GetMaxGapSize() noexcept
Get maximum gap size.
drift volume class to hold properties of drift volume
unsigned int GetVolumeID() const
Return unique ID.
float GetWidthY() const
Return Y span of drift volume.
float GetCenterY() const
Return Y position at centre of drift volume.
LArDriftVolume(const unsigned int volumeID, const bool isPositiveDrift, const float wirePitchU, const float wirePitchV, const float wirePitchW, const float wireAngleU, const float wireAngleV, const float wireAngleW, const float centerX, const float centerY, const float centerZ, const float widthX, const float widthY, const float widthZ, const float sigmaUVZ, const LArDaughterDriftVolumeList &tpcVolumeList)
Constructor.
float GetCenterX() const
Return X position at centre of drift volume.
float GetWidthX() const
Return X span of drift volume.
float GetCenterZ() const
Return Z position at centre of drift volume.
float GetWidthZ() const
Return Z span of drift volume.
Empty interface to map pandora to specifics in the LArSoft geometry.
virtual float WireAngleW(const geo::TPCID::TPCID_t tpc, const geo::CryostatID::CryostatID_t cstat) const =0
The angle of the wires in the mapped V view.
virtual float WirePitchW() const =0
The wire pitch of the mapped W view.
virtual float WireAngleV(const geo::TPCID::TPCID_t tpc, const geo::CryostatID::CryostatID_t cstat) const =0
The angle of the wires in the mapped V view.
virtual bool CheckDetectorGapSize(const geo::Vector_t &gaps, const geo::Vector_t &deltas, const float maxDisplacement) const =0
Check whether a gap size is small enough to be registered as a detector gap.
virtual void LoadDaughterDetectorGaps(const LArDriftVolume &driftVolume, const float maxDisplacement, LArDetectorGapList &listOfGaps) const =0
Create detector gaps for all daughter volumes in a logical TPC volume.
virtual LArDetectorGap CreateDetectorGap(const geo::Point_t &point1, const geo::Point_t &point2, const geo::Vector_t &widths) const =0
Create a detector gap.
virtual float WirePitchU() const =0
The wire pitch of the mapped U view.
virtual float WirePitchV() const =0
The wire pitch of the mapped V view.
virtual float WireAngleU(const geo::TPCID::TPCID_t tpc, const geo::CryostatID::CryostatID_t cstat) const =0
The angle of the wires in the mapped U view.
static void LoadDetectorGaps(LArDetectorGapList &listOfGaps, const bool useActiveBoundingBox)
Load the 2D gaps that go with the chosen geometry.
static bool ShouldSwitchUV(const unsigned int cstat, const unsigned int tpc)
Return whether U/V should be switched in global coordinate system for this cryostat/tpc.
static unsigned int GetDaughterVolumeID(const LArDriftVolumeMap &driftVolumeMap, const unsigned int cstat, const unsigned int tpc)
Get daughter volume ID from a specified cryostat/tpc pair.
static void LoadGeometry(LArDriftVolumeList &outputVolumeList, LArDriftVolumeMap &outputVolumeMap, const bool useActiveBoundingBox)
Load drift volume geometry.
static unsigned int GetVolumeID(const LArDriftVolumeMap &driftVolumeMap, const unsigned int cstat, const unsigned int tpc)
Get drift volume ID from a specified cryostat/tpc pair.
static geo::View_t GetGlobalView(const unsigned int cstat, const unsigned int tpc, const geo::View_t hit_View)
Convert to global coordinate system.
static unsigned int GetTpcID(const unsigned int cstat, const unsigned int tpc)
Generate a unique identifier for each TPC.
static void LoadGlobalDaughterGeometry(const LArDriftVolumeList &driftVolumeList, LArDriftVolumeList &daughterVolumeList)
This method will create one or more daughter volumes (these share a common drift orientation along th...
LArPandoraDetectorType * GetDetectorType()
Factory class that returns the correct detector type interface.
std::vector< LArDaughterDriftVolume > LArDaughterDriftVolumeList
std::vector< LArDetectorGap > LArDetectorGapList
std::vector< LArDriftVolume > LArDriftVolumeList
std::map< unsigned int, LArDriftVolume > LArDriftVolumeMap