LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
LArPandoraGeometry.cxx
Go to the documentation of this file.
1 
8 
10 #include "cetlib_except/exception.h"
11 
16 
19 
20 #include <iomanip>
21 #include <set>
22 
23 namespace 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 
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 
136  unsigned int LArPandoraGeometry::GetDaughterVolumeID(const LArDriftVolumeMap& driftVolumeMap,
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 
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 
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 
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
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
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).
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
details::range_type< T > Iterate() const
Initializes the specified ID with the ID of the first cryostat.
Definition: GeometryCore.h:541
float GetWidthZ() const
Return Z span of drift volume.
static geo::View_t GetGlobalView(const unsigned int cstat, const unsigned int tpc, const geo::View_t hit_View)
Convert to global coordinate system.
daughter drift volume class to hold properties of daughter drift volumes
static void LoadGeometry(LArDriftVolumeList &outputVolumeList, LArDriftVolumeMap &outputVolumeMap, const bool useActiveBoundingBox)
Load drift volume geometry.
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
Definition: geo_vectors.h:160
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.
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.
Helper functions for extracting detector geometry for use in reconsruction.
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
Planes which measure V.
Definition: geo_types.h:136
std::map< unsigned int, LArDriftVolume > LArDriftVolumeMap
unsigned int GetCryostat() const
Return cryostat ID.
Empty interface to map pandora to specifics in the LArSoft geometry.
Geometry information for a single TPC.
Definition: TPCGeo.h:36
std::vector< LArDriftVolume > LArDriftVolumeList
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.
intermediate_table::const_iterator const_iterator
virtual float WirePitchV() const =0
The wire pitch of the mapped V view.
Geometry information for a single cryostat.
Definition: CryostatGeo.h:43
Planes which measure Y direction.
Definition: geo_types.h:139
Double_t X2
Definition: plot.C:263
float GetCenterZ() const
Return Z position at centre of drift volume.
TPCGeo const & TPC(TPCID const &tpcid=tpc_zero) const
Returns the specified TPC.
Definition: GeometryCore.h:722
TFile f
Definition: plotHisto.C:6
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.
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.
Planes which measure U.
Definition: geo_types.h:135
unsigned int MaxPlanes() const
Returns the largest number of planes among all TPCs in this detector.
static unsigned int GetTpcID(const unsigned int cstat, const unsigned int tpc)
Generate a unique identifier for each TPC.
virtual float WirePitchU() const =0
The wire pitch of the mapped U 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.
float GetCenterX() const
Return X position at centre of drift volume.
Double_t X1
Definition: plot.C:263
Double_t Y1
Definition: plot.C:263
unsigned int GetVolumeID() const
Return unique ID.
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 void LoadGlobalDaughterGeometry(const LArDriftVolumeList &driftVolumeList, LArDriftVolumeList &daughterVolumeList)
This method will create one or more daughter volumes (these share a common drift orientation along th...
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.
static void LoadDetectorGaps(LArDetectorGapList &listOfGaps, const bool useActiveBoundingBox)
Load the 2D gaps that go with the chosen 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.
The data type to uniquely identify a TPC.
Definition: geo_types.h:381
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 WirePitchW() const =0
The wire pitch of the mapped W view.
Double_t Z2
Definition: plot.C:263
Encapsulate the geometry of a wire.
std::vector< LArDaughterDriftVolume > LArDaughterDriftVolumeList
Double_t Z1
Definition: plot.C:263
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:180
static float GetMaxGapSize() noexcept
Get maximum gap size.
LArPandoraDetectorType * GetDetectorType()
Factory class that returns the correct detector type interface.
Drift towards positive X values.
Definition: geo_types.h:166
Encapsulate the construction of a single detector plane.
std::vector< LArDetectorGap > LArDetectorGapList
float GetWidthY() const
Return Y span of drift volume.
float GetCenterY() const
Return Y position at centre of drift volume.
drift volume class to hold properties of drift volume
Planes which measure W (third view for Bo, MicroBooNE, etc).
Definition: geo_types.h:137
float GetWidthX() const
Return X span of drift volume.
Helper functions for extracting detector geometry for use in reconsruction.
art framework interface to geometry description
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
Double_t Y2
Definition: plot.C:263
Encapsulate the construction of a single detector plane.
unsigned int GetTpc() const
Return tpc ID.