Static Public Member Functions | Static Private Member Functions | List of all members
lar_pandora::LArPandoraGeometry Class Reference

LArPandoraGeometry class. More...

#include <LArPandoraGeometry.h>

Static Public Member Functions

static void LoadDetectorGaps (LArDetectorGapList &listOfGaps, const bool useActiveBoundingBox)
 Load the 2D gaps that go with the chosen geometry. More...
 
static void LoadGeometry (LArDriftVolumeList &outputVolumeList, LArDriftVolumeMap &outputVolumeMap, const bool useActiveBoundingBox)
 Load drift volume geometry. More...
 
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. More...
 
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. More...
 
static geo::View_t GetGlobalView (const unsigned int cstat, const unsigned int tpc, const geo::View_t hit_View)
 Convert to global coordinate system. More...
 

Static Private Member Functions

static unsigned int GetTpcID (const unsigned int cstat, const unsigned int tpc)
 Generate a unique identifier for each TPC. More...
 
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. More...
 
static bool ShouldSwitchUV (const bool isPositiveDrift)
 Return whether U/V should be switched in global coordinate system for this drift direction. More...
 
static void LoadGeometry (LArDriftVolumeList &driftVolumeList, const bool useActiveBoundingBox)
 This method will group TPCs into drift volumes (these are regions of the detector that share a common drift direction, common range of X coordinates, and common detector parameters such as wire pitch and wire angle). More...
 
static void LoadGlobalDaughterGeometry (const LArDriftVolumeList &driftVolumeList, LArDriftVolumeList &daughterVolumeList)
 This method will create one or more daughter volumes (these share a common drift orientation along the X-axis, have parallel or near-parallel wire angles, and similar wire pitches) More...
 

Detailed Description

LArPandoraGeometry class.

Definition at line 323 of file LArPandoraGeometry.h.

Member Function Documentation

unsigned int lar_pandora::LArPandoraGeometry::GetDaughterVolumeID ( const LArDriftVolumeMap driftVolumeMap,
const unsigned int  cstat,
const unsigned int  tpc 
)
static

Get daughter volume ID from a specified cryostat/tpc pair.

Parameters
driftVolumeMapthe output mapping between cryostat/tpc and drift volumes
cstatthe input cryostat unique ID
tpcthe input tpc unique ID

Definition at line 137 of file LArPandoraGeometry.cxx.

140  {
141  if (driftVolumeMap.empty())
142  throw cet::exception("LArPandora")
143  << " LArPandoraGeometry::GetDaughterVolumeID --- detector geometry map is empty";
144 
146  driftVolumeMap.find(LArPandoraGeometry::GetTpcID(cstat, tpc));
147 
148  if (driftVolumeMap.end() == iter)
149  throw cet::exception("LArPandora") << " LArPandoraGeometry::GetDaughterVolumeID --- found a "
150  "TPC volume that doesn't belong to a drift volume";
151 
153  iterDghtr = iter->second.GetTpcVolumeList().begin(),
154  iterDghtrEnd = iter->second.GetTpcVolumeList().end();
155  iterDghtr != iterDghtrEnd;
156  ++iterDghtr) {
157  const LArDaughterDriftVolume& daughterVolume(*iterDghtr);
158  if (cstat == daughterVolume.GetCryostat() && tpc == daughterVolume.GetTpc())
159  return std::distance(iter->second.GetTpcVolumeList().begin(), iterDghtr);
160  }
161  throw cet::exception("LArPandora")
162  << " LArPandoraGeometry::GetDaughterVolumeID --- found a daughter volume that doesn't belong "
163  "to the drift volume ";
164  }
intermediate_table::const_iterator const_iterator
static unsigned int GetTpcID(const unsigned int cstat, const unsigned int tpc)
Generate a unique identifier for each TPC.
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
geo::View_t lar_pandora::LArPandoraGeometry::GetGlobalView ( const unsigned int  cstat,
const unsigned int  tpc,
const geo::View_t  hit_View 
)
static

Convert to global coordinate system.

Parameters
cstatthe input cryostat
tpcthe input tpc
hit_Viewthe input view

Definition at line 169 of file LArPandoraGeometry.cxx.

172  {
173  const bool switchUV(LArPandoraGeometry::ShouldSwitchUV(cstat, tpc));
174 
175  // ATTN This implicitly assumes that there will be u, v and (maybe) one of either w or y views
176  if ((hit_View == geo::kW) || (hit_View == geo::kY)) { return hit_View; }
177  else if (hit_View == geo::kU) {
178  return (switchUV ? geo::kV : geo::kU);
179  }
180  else if (hit_View == geo::kV) {
181  return (switchUV ? geo::kU : geo::kV);
182  }
183  else {
184  throw cet::exception("LArPandora")
185  << " LArPandoraGeometry::GetGlobalView --- found an unknown plane view (not U, V or W) ";
186  }
187  }
Planes which measure V.
Definition: geo_types.h:130
Planes which measure Y direction.
Definition: geo_types.h:133
Planes which measure U.
Definition: geo_types.h:129
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.
Planes which measure W (third view for Bo, MicroBooNE, etc).
Definition: geo_types.h:131
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
unsigned int lar_pandora::LArPandoraGeometry::GetTpcID ( const unsigned int  cstat,
const unsigned int  tpc 
)
staticprivate

Generate a unique identifier for each TPC.

Parameters
cstatthe input cryostat
tpcthe input tpc

Definition at line 192 of file LArPandoraGeometry.cxx.

193  {
194  // We assume there will never be more than 10000 TPCs in a cryostat!
195  if (tpc >= 10000)
196  throw cet::exception("LArPandora")
197  << " LArPandoraGeometry::GetTpcID --- found a TPC with an ID greater than 10000 ";
198 
199  return ((10000 * cstat) + tpc);
200  }
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
unsigned int lar_pandora::LArPandoraGeometry::GetVolumeID ( const LArDriftVolumeMap driftVolumeMap,
const unsigned int  cstat,
const unsigned int  tpc 
)
static

Get drift volume ID from a specified cryostat/tpc pair.

Parameters
driftVolumeMapthe output mapping between cryostat/tpc and drift volumes
cstatthe input cryostat unique ID
tpcthe input tpc unique ID

Definition at line 116 of file LArPandoraGeometry.cxx.

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  }
intermediate_table::const_iterator const_iterator
static unsigned int GetTpcID(const unsigned int cstat, const unsigned int tpc)
Generate a unique identifier for each TPC.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
void lar_pandora::LArPandoraGeometry::LoadDetectorGaps ( LArDetectorGapList listOfGaps,
const bool  useActiveBoundingBox 
)
static

Load the 2D gaps that go with the chosen geometry.

Parameters
listOfGapsthe output list of 2D gaps.
useActiveBoundingBoxwhen true use ActiveBoundingBox instead of the default midpoint. Meant to handle offsets and things in a better way.

Definition at line 23 of file LArPandoraGeometry.cxx.

25  {
26  // Detector gaps can only be loaded once - throw an exception if the output lists are already filled
27  if (!listOfGaps.empty())
28  throw cet::exception("LArPandora")
29  << " LArPandoraGeometry::LoadDetectorGaps --- the list of gaps already exists ";
30 
31  // Loop over drift volumes and write out the dead regions at their boundaries
32  LArDriftVolumeList driftVolumeList;
33  LArPandoraGeometry::LoadGeometry(driftVolumeList, useActiveBoundingBox);
34 
35  LArPandoraDetectorType* detType(detector_functions::GetDetectorType());
36 
37  for (LArDriftVolumeList::const_iterator iter1 = driftVolumeList.begin(),
38  iterEnd1 = driftVolumeList.end();
39  iter1 != iterEnd1;
40  ++iter1) {
41  const LArDriftVolume& driftVolume1 = *iter1;
42 
43  for (LArDriftVolumeList::const_iterator iter2 = iter1, iterEnd2 = driftVolumeList.end();
44  iter2 != iterEnd2;
45  ++iter2) {
46  const LArDriftVolume& driftVolume2 = *iter2;
47 
48  if (driftVolume1.GetVolumeID() == driftVolume2.GetVolumeID()) continue;
49 
50  const float maxDisplacement(LArDetectorGap::GetMaxGapSize());
51 
52  const float deltaX(std::fabs(driftVolume1.GetCenterX() - driftVolume2.GetCenterX()));
53  const float deltaY(std::fabs(driftVolume1.GetCenterY() - driftVolume2.GetCenterY()));
54  const float deltaZ(std::fabs(driftVolume1.GetCenterZ() - driftVolume2.GetCenterZ()));
55 
56  const float widthX(0.5f * (driftVolume1.GetWidthX() + driftVolume2.GetWidthX()));
57  const float widthY(0.5f * (driftVolume1.GetWidthY() + driftVolume2.GetWidthY()));
58  const float widthZ(0.5f * (driftVolume1.GetWidthZ() + driftVolume2.GetWidthZ()));
59 
60  const float gapX(deltaX - widthX);
61  const float gapY(deltaY - widthY);
62  const float gapZ(deltaZ - widthZ);
63 
64  const float X1((driftVolume1.GetCenterX() < driftVolume2.GetCenterX()) ?
65  (driftVolume1.GetCenterX() + 0.5f * driftVolume1.GetWidthX()) :
66  (driftVolume2.GetCenterX() + 0.5f * driftVolume2.GetWidthX()));
67  const float X2((driftVolume1.GetCenterX() > driftVolume2.GetCenterX()) ?
68  (driftVolume1.GetCenterX() - 0.5f * driftVolume1.GetWidthX()) :
69  (driftVolume2.GetCenterX() - 0.5f * driftVolume2.GetWidthX()));
70  const float Y1(std::min((driftVolume1.GetCenterY() - 0.5f * driftVolume1.GetWidthY()),
71  (driftVolume2.GetCenterY() - 0.5f * driftVolume2.GetWidthY())));
72  const float Y2(std::max((driftVolume1.GetCenterY() + 0.5f * driftVolume1.GetWidthY()),
73  (driftVolume2.GetCenterY() + 0.5f * driftVolume2.GetWidthY())));
74  const float Z1(std::min((driftVolume1.GetCenterZ() - 0.5f * driftVolume1.GetWidthZ()),
75  (driftVolume2.GetCenterZ() - 0.5f * driftVolume2.GetWidthZ())));
76  const float Z2(std::max((driftVolume1.GetCenterZ() + 0.5f * driftVolume1.GetWidthZ()),
77  (driftVolume2.GetCenterZ() + 0.5f * driftVolume2.GetWidthZ())));
78 
79  geo::Vector_t gaps(gapX, gapY, gapZ), deltas(deltaX, deltaY, deltaZ);
80  if (detType->CheckDetectorGapSize(gaps, deltas, maxDisplacement)) {
81  geo::Point_t point1(X1, Y1, Z1), point2(X2, Y2, Z2);
82  geo::Vector_t widths(widthX, widthY, widthZ);
83  listOfGaps.emplace_back(detType->CreateDetectorGap(point1, point2, widths));
84  }
85  }
86 
87  detType->LoadDaughterDetectorGaps(driftVolume1, LArDetectorGap::GetMaxGapSize(), listOfGaps);
88  }
89  }
static void LoadGeometry(LArDriftVolumeList &outputVolumeList, LArDriftVolumeMap &outputVolumeMap, const bool useActiveBoundingBox)
Load drift volume geometry.
std::vector< LArDriftVolume > LArDriftVolumeList
intermediate_table::const_iterator const_iterator
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 int max(int a, int b)
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
static float GetMaxGapSize() noexcept
Get maximum gap size.
LArPandoraDetectorType * GetDetectorType()
Factory class that returns the correct detector type interface.
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
void lar_pandora::LArPandoraGeometry::LoadGeometry ( LArDriftVolumeList outputVolumeList,
LArDriftVolumeMap outputVolumeMap,
const bool  useActiveBoundingBox 
)
static

Load drift volume geometry.

Parameters
outputVolumeListthe output list of drift volumes
outputVolumeMapthe output mapping between cryostat/tpc and drift volumes
useActiveBoundingBoxwhen true use ActiveBoundingBox instead of the default midpoint. Meant to handle offsets and things in a better way.

Definition at line 94 of file LArPandoraGeometry.cxx.

97  {
98  if (!outputVolumeList.empty())
99  throw cet::exception("LArPandora")
100  << " LArPandoraGeometry::LoadGeometry --- the list of drift volumes already exists ";
101 
102  LArPandoraGeometry::LoadGeometry(outputVolumeList, useActiveBoundingBox);
103 
104  // Create mapping between tpc/cstat labels and drift volumes
105  for (const LArDriftVolume& driftVolume : outputVolumeList) {
106  for (const LArDaughterDriftVolume& tpcVolume : driftVolume.GetTpcVolumeList()) {
107  (void)outputVolumeMap.insert(LArDriftVolumeMap::value_type(
108  LArPandoraGeometry::GetTpcID(tpcVolume.GetCryostat(), tpcVolume.GetTpc()), driftVolume));
109  }
110  }
111  }
static void LoadGeometry(LArDriftVolumeList &outputVolumeList, LArDriftVolumeMap &outputVolumeMap, const bool useActiveBoundingBox)
Load drift volume geometry.
static unsigned int GetTpcID(const unsigned int cstat, const unsigned int tpc)
Generate a unique identifier for each TPC.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
void lar_pandora::LArPandoraGeometry::LoadGeometry ( LArDriftVolumeList driftVolumeList,
const bool  useActiveBoundingBox 
)
staticprivate

This method will group TPCs into drift volumes (these are regions of the detector that share a common drift direction, common range of X coordinates, and common detector parameters such as wire pitch and wire angle).

Parameters
driftVolumeListto receive the populated drift volume list
useActiveBoundingBoxwhen true use ActiveBoundingBox instead of the default midpoint. Meant to handle offsets and things in a better way.

Definition at line 231 of file LArPandoraGeometry.cxx.

233  {
234  // This method will group TPCs into "drift volumes" (these are regions of the detector that share a common drift direction,
235  // common range of x coordinates, and common detector parameters such as wire pitch and wire angle).
236  if (!driftVolumeList.empty())
237  throw cet::exception("LArPandora")
238  << " LArPandoraGeometry::LoadGeometry --- detector geometry has already been loaded ";
239 
240  typedef std::set<unsigned int> UIntSet;
241 
242  // Pandora requires three independent images, and ability to correlate features between images (via wire angles and transformation plugin).
244  LArPandoraDetectorType* detType(detector_functions::GetDetectorType());
245  const float wirePitchU(detType->WirePitchU());
246  const float wirePitchV(detType->WirePitchV());
247  const float wirePitchW(detType->WirePitchW());
248  const float maxDeltaTheta(0.01f); // leave this hard-coded for now
249 
250  // Loop over cryostats
251  for (unsigned int icstat = 0; icstat < theGeometry->Ncryostats(); ++icstat) {
252  UIntSet cstatList;
253 
254  // Loop over TPCs in in this cryostat
255  for (unsigned int itpc1 = 0; itpc1 < theGeometry->NTPC(icstat); ++itpc1) {
256  if (cstatList.end() != cstatList.find(itpc1)) continue;
257 
258  // Use this TPC to seed a drift volume
259  const geo::TPCGeo& theTpc1(theGeometry->TPC(itpc1, icstat));
260  cstatList.insert(itpc1);
261 
262  const float wireAngleU(detType->WireAngleU(itpc1, icstat));
263  const float wireAngleV(detType->WireAngleV(itpc1, icstat));
264  const float wireAngleW(detType->WireAngleW(itpc1, icstat));
265 
266  double localCoord1[3] = {0., 0., 0.};
267  double worldCoord1[3] = {0., 0., 0.};
268  theTpc1.LocalToWorld(localCoord1, worldCoord1);
269 
270  float driftMinX(useActiveBoundingBox ? theTpc1.ActiveBoundingBox().MinX() :
271  (worldCoord1[0] - theTpc1.ActiveHalfWidth()));
272  float driftMaxX(useActiveBoundingBox ? theTpc1.ActiveBoundingBox().MaxX() :
273  (worldCoord1[0] + theTpc1.ActiveHalfWidth()));
274  float driftMinY(useActiveBoundingBox ? theTpc1.ActiveBoundingBox().MinY() :
275  (worldCoord1[1] - theTpc1.ActiveHalfHeight()));
276  float driftMaxY(useActiveBoundingBox ? theTpc1.ActiveBoundingBox().MaxY() :
277  (worldCoord1[1] + theTpc1.ActiveHalfHeight()));
278  float driftMinZ(useActiveBoundingBox ? theTpc1.ActiveBoundingBox().MinZ() :
279  (worldCoord1[2] - 0.5f * theTpc1.ActiveLength()));
280  float driftMaxZ(useActiveBoundingBox ? theTpc1.ActiveBoundingBox().MaxZ() :
281  (worldCoord1[2] + 0.5f * theTpc1.ActiveLength()));
282 
283  const double min1(
284  useActiveBoundingBox ?
285  (0.5 * (driftMinX + driftMaxX) - 0.25 * std::fabs(driftMaxX - driftMinX)) :
286  (worldCoord1[0] - 0.5 * theTpc1.ActiveHalfWidth()));
287  const double max1(
288  useActiveBoundingBox ?
289  (0.5 * (driftMinX + driftMaxX) + 0.25 * std::fabs(driftMaxX - driftMinX)) :
290  (worldCoord1[0] + 0.5 * theTpc1.ActiveHalfWidth()));
291 
292  const bool isPositiveDrift(theTpc1.DriftDirection() == geo::kPosX);
293 
294  UIntSet tpcList;
295  tpcList.insert(itpc1);
296 
297  LArDaughterDriftVolumeList tpcVolumeList;
298  tpcVolumeList.emplace_back(LArDaughterDriftVolume(icstat,
299  itpc1,
300  0.5f * (driftMaxX + driftMinX),
301  0.5f * (driftMaxY + driftMinY),
302  0.5f * (driftMaxZ + driftMinZ),
303  (driftMaxX - driftMinX),
304  (driftMaxY - driftMinY),
305  (driftMaxZ - driftMinZ)));
306 
307  // Now identify the other TPCs associated with this drift volume
308  for (unsigned int itpc2 = itpc1 + 1; itpc2 < theGeometry->NTPC(icstat); ++itpc2) {
309  if (cstatList.end() != cstatList.find(itpc2)) continue;
310 
311  const geo::TPCGeo& theTpc2(theGeometry->TPC(itpc2, icstat));
312 
313  if (theTpc1.DriftDirection() != theTpc2.DriftDirection()) continue;
314 
315  const float dThetaU(detType->WireAngleU(itpc1, icstat) -
316  detType->WireAngleU(itpc2, icstat));
317  const float dThetaV(detType->WireAngleV(itpc1, icstat) -
318  detType->WireAngleV(itpc2, icstat));
319  const float dThetaW(detType->WireAngleW(itpc1, icstat) -
320  detType->WireAngleW(itpc2, icstat));
321  if (dThetaU > maxDeltaTheta || dThetaV > maxDeltaTheta || dThetaW > maxDeltaTheta)
322  continue;
323 
324  double localCoord2[3] = {0., 0., 0.};
325  double worldCoord2[3] = {0., 0., 0.};
326  theTpc2.LocalToWorld(localCoord2, worldCoord2);
327 
328  const float driftMinX2(useActiveBoundingBox ?
329  theTpc2.ActiveBoundingBox().MinX() :
330  (worldCoord2[0] - theTpc2.ActiveHalfWidth()));
331  const float driftMaxX2(useActiveBoundingBox ?
332  theTpc2.ActiveBoundingBox().MaxX() :
333  (worldCoord2[0] + theTpc2.ActiveHalfWidth()));
334 
335  const double min2(
336  useActiveBoundingBox ?
337  (0.5 * (driftMinX2 + driftMaxX2) - 0.25 * std::fabs(driftMaxX2 - driftMinX2)) :
338  (worldCoord2[0] - 0.5 * theTpc2.ActiveHalfWidth()));
339  const double max2(
340  useActiveBoundingBox ?
341  (0.5 * (driftMinX2 + driftMaxX2) + 0.25 * std::fabs(driftMaxX2 - driftMinX2)) :
342  (worldCoord2[0] + 0.5 * theTpc2.ActiveHalfWidth()));
343 
344  if ((min2 > max1) || (min1 > max2)) continue;
345 
346  cstatList.insert(itpc2);
347  tpcList.insert(itpc2);
348 
349  const float driftMinY2(useActiveBoundingBox ?
350  theTpc2.ActiveBoundingBox().MinY() :
351  (worldCoord2[1] - theTpc2.ActiveHalfHeight()));
352  const float driftMaxY2(useActiveBoundingBox ?
353  theTpc2.ActiveBoundingBox().MaxY() :
354  (worldCoord2[1] + theTpc2.ActiveHalfHeight()));
355  const float driftMinZ2(useActiveBoundingBox ?
356  theTpc2.ActiveBoundingBox().MinZ() :
357  (worldCoord2[2] - 0.5f * theTpc2.ActiveLength()));
358  const float driftMaxZ2(useActiveBoundingBox ?
359  theTpc2.ActiveBoundingBox().MaxZ() :
360  (worldCoord2[2] + 0.5f * theTpc2.ActiveLength()));
361 
362  driftMinX = std::min(driftMinX, driftMinX2);
363  driftMaxX = std::max(driftMaxX, driftMaxX2);
364  driftMinY = std::min(driftMinY, driftMinY2);
365  driftMaxY = std::max(driftMaxY, driftMaxY2);
366  driftMinZ = std::min(driftMinZ, driftMinZ2);
367  driftMaxZ = std::max(driftMaxZ, driftMaxZ2);
368 
369  tpcVolumeList.emplace_back(LArDaughterDriftVolume(icstat,
370  itpc2,
371  0.5f * (driftMaxX2 + driftMinX2),
372  0.5f * (driftMaxY2 + driftMinY2),
373  0.5f * (driftMaxZ2 + driftMinZ2),
374  (driftMaxX2 - driftMinX2),
375  (driftMaxY2 - driftMinY2),
376  (driftMaxZ2 - driftMinZ2)));
377  }
378 
379  // Create new daughter drift volume (volume ID = 0 to N-1)
380  driftVolumeList.emplace_back(driftVolumeList.size(),
381  isPositiveDrift,
382  wirePitchU,
383  wirePitchV,
384  wirePitchW,
385  wireAngleU,
386  wireAngleV,
387  wireAngleW,
388  0.5f * (driftMaxX + driftMinX),
389  0.5f * (driftMaxY + driftMinY),
390  0.5f * (driftMaxZ + driftMinZ),
391  (driftMaxX - driftMinX),
392  (driftMaxY - driftMinY),
393  (driftMaxZ - driftMinZ),
394  (wirePitchU + wirePitchV + wirePitchW + 0.1f),
395  tpcVolumeList);
396  }
397  }
398 
399  if (driftVolumeList.empty())
400  throw cet::exception("LArPandora") << " LArPandoraGeometry::LoadGeometry --- failed to find "
401  "any drift volumes in this detector geometry ";
402  }
Geometry information for a single TPC.
Definition: TPCGeo.h:38
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
static int max(int a, int b)
unsigned int NTPC(unsigned int cstat=0) const
Returns the total number of TPCs in the specified cryostat.
std::vector< LArDaughterDriftVolume > LArDaughterDriftVolumeList
LArPandoraDetectorType * GetDetectorType()
Factory class that returns the correct detector type interface.
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
Drift towards positive X values.
Definition: geo_types.h:161
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
void LocalToWorld(const double *tpc, double *world) const
Transform point from local TPC frame to world frame.
Definition: TPCGeo.h:563
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
void lar_pandora::LArPandoraGeometry::LoadGlobalDaughterGeometry ( const LArDriftVolumeList driftVolumeList,
LArDriftVolumeList daughterVolumeList 
)
staticprivate

This method will create one or more daughter volumes (these share a common drift orientation along the X-axis, have parallel or near-parallel wire angles, and similar wire pitches)

Parameters
driftVolumeListto receive the input drift volume list
parentVolumeListto receive the output daughter drift volume list

Definition at line 407 of file LArPandoraGeometry.cxx.

409  {
410  // This method will create one or more daughter volumes (these share a common drift orientation along the X-axis,
411  // have parallel or near-parallel wire angles, and similar wire pitches)
412  //
413  // ATTN: we assume that the U and V planes have equal and opposite wire orientations
414 
415  if (!daughterVolumeList.empty())
416  throw cet::exception("LArPandora") << " LArPandoraGeometry::LoadGlobalDaughterGeometry --- "
417  "daughter geometry has already been loaded ";
418 
419  if (driftVolumeList.empty())
420  throw cet::exception("LArPandora") << " LArPandoraGeometry::LoadGlobalDaughterGeometry --- "
421  "detector geometry has not yet been loaded ";
422 
423  std::cout << "The size of the drif list is: " << driftVolumeList.size() << std::endl;
424  int count(0);
425  // Create daughter drift volumes
426  for (const LArDriftVolume& driftVolume : driftVolumeList) {
427  std::cout << "Looking at dau vol: " << count++ << std::endl;
428  const bool switchViews(LArPandoraGeometry::ShouldSwitchUV(driftVolume.IsPositiveDrift()));
429 
430  const float daughterWirePitchU(switchViews ? driftVolume.GetWirePitchV() :
431  driftVolume.GetWirePitchU());
432  const float daughterWirePitchV(switchViews ? driftVolume.GetWirePitchU() :
433  driftVolume.GetWirePitchV());
434  const float daughterWirePitchW(driftVolume.GetWirePitchW());
435  const float daughterWireAngleU(switchViews ? driftVolume.GetWireAngleV() :
436  driftVolume.GetWireAngleU());
437  const float daughterWireAngleV(switchViews ? driftVolume.GetWireAngleU() :
438  driftVolume.GetWireAngleV());
439  const float daughterWireAngleW(driftVolume.GetWireAngleW());
440 
441  daughterVolumeList.push_back(LArDriftVolume(driftVolume.GetVolumeID(),
442  driftVolume.IsPositiveDrift(),
443  daughterWirePitchU,
444  daughterWirePitchV,
445  daughterWirePitchW,
446  daughterWireAngleU,
447  daughterWireAngleV,
448  daughterWireAngleW,
449  driftVolume.GetCenterX(),
450  driftVolume.GetCenterY(),
451  driftVolume.GetCenterZ(),
452  driftVolume.GetWidthX(),
453  driftVolume.GetWidthY(),
454  driftVolume.GetWidthZ(),
455  driftVolume.GetSigmaUVZ(),
456  driftVolume.GetTpcVolumeList()));
457  }
458 
459  if (daughterVolumeList.empty())
460  throw cet::exception("LArPandora") << " LArPandoraGeometry::LoadGlobalDaughterGeometry --- "
461  "failed to create daughter geometry list ";
462  }
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.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)
bool lar_pandora::LArPandoraGeometry::ShouldSwitchUV ( const unsigned int  cstat,
const unsigned int  tpc 
)
staticprivate

Return whether U/V should be switched in global coordinate system for this cryostat/tpc.

Parameters
cstatthe input cryostat
tpcthe input tpc

Definition at line 205 of file LArPandoraGeometry.cxx.

206  {
207  // We determine whether U and V views should be switched by checking the drift direction
209  const geo::TPCGeo& theTpc(theGeometry->TPC(tpc, cstat));
210 
211  const bool isPositiveDrift(theTpc.DriftDirection() == geo::kPosX);
212  return LArPandoraGeometry::ShouldSwitchUV(isPositiveDrift);
213  }
Geometry information for a single TPC.
Definition: TPCGeo.h:38
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.
Drift towards positive X values.
Definition: geo_types.h:161
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
bool lar_pandora::LArPandoraGeometry::ShouldSwitchUV ( const bool  isPositiveDrift)
staticprivate

Return whether U/V should be switched in global coordinate system for this drift direction.

Parameters
isPositiveDriftthe drift direction

Definition at line 218 of file LArPandoraGeometry.cxx.

219  {
220  // ATTN: In the dual phase scenario the wire planes pointing along two orthogonal directions and so interchanging U and V is unnecessary
222  if (theGeometry->MaxPlanes() == 2) return false;
223 
224  // We assume that all multiple drift volume detectors have the APA - CPA - APA - CPA design
225  return isPositiveDrift;
226  }
unsigned int MaxPlanes() const
Returns the largest number of planes among all TPCs in this detector.

The documentation for this class was generated from the following files: