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