All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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 22 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 140 of file LArPandoraGeometry.cxx.

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  }
static unsigned int GetTpcID(const unsigned int cstat, const unsigned int tpc)
Generate a unique identifier for each TPC.
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
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 172 of file LArPandoraGeometry.cxx.

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  }
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
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 195 of file LArPandoraGeometry.cxx.

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  }
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 119 of file LArPandoraGeometry.cxx.

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  }
static unsigned int GetTpcID(const unsigned int cstat, const unsigned int tpc)
Generate a unique identifier for each TPC.
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 26 of file LArPandoraGeometry.cxx.

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 
38  LArPandoraDetectorType* detType(detector_functions::GetDetectorType());
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  }
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 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
std::vector< LArDriftVolume > LArDriftVolumeList
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
static float GetMaxGapSize() noexcept
Get maximum gap size.
LArPandoraDetectorType * GetDetectorType()
Factory class that returns the correct detector type interface.
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
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 97 of file LArPandoraGeometry.cxx.

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  }
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.
j template void())
Definition: json.hpp:3108
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 234 of file LArPandoraGeometry.cxx.

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;
247  LArPandoraDetectorType* detType(detector_functions::GetDetectorType());
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  }
Geometry information for a single TPC.
Definition: TPCGeo.h:38
std::vector< LArDaughterDriftVolume > LArDaughterDriftVolumeList
LArPandoraDetectorType * GetDetectorType()
Factory class that returns the correct detector type interface.
Drift towards positive X values.
Definition: geo_types.h:161
void LocalToWorld(const double *tpc, double *world) const
Transform point from local TPC frame to world frame.
Definition: TPCGeo.h:563
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 410 of file LArPandoraGeometry.cxx.

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  }
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.
std::size_t count(Cont const &cont)
BEGIN_PROLOG could also be cout
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 208 of file LArPandoraGeometry.cxx.

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  }
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
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 221 of file LArPandoraGeometry.cxx.

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  }

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