LArSoft  v09_90_00
Liquid Argon Software toolkit - https://larsoft.org/
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 136 of file LArPandoraGeometry.cxx.

References lar_pandora::LArDaughterDriftVolume::GetCryostat(), lar_pandora::LArDaughterDriftVolume::GetTpc(), and GetTpcID().

Referenced by lar_pandora::LArPandoraInput::CreatePandoraHits2D().

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

References geo::kU, geo::kV, geo::kW, geo::kY, and ShouldSwitchUV().

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  }
Planes which measure V.
Definition: geo_types.h:136
Planes which measure Y direction.
Definition: geo_types.h:139
Planes which measure U.
Definition: geo_types.h:135
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:137
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 188 of file LArPandoraGeometry.cxx.

Referenced by GetDaughterVolumeID(), GetVolumeID(), and LoadGeometry().

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  }
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.

References GetTpcID().

Referenced by lar_pandora::LArPandoraInput::CreatePandoraHits2D(), and lar_pandora::LArPandoraInput::CreatePandoraReadoutGaps().

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

References lar_pandora::LArPandoraDetectorType::CheckDetectorGapSize(), lar_pandora::LArPandoraDetectorType::CreateDetectorGap(), f, lar_pandora::LArDriftVolume::GetCenterX(), lar_pandora::LArDriftVolume::GetCenterY(), lar_pandora::LArDriftVolume::GetCenterZ(), lar_pandora::detector_functions::GetDetectorType(), lar_pandora::LArDetectorGap::GetMaxGapSize(), lar_pandora::LArDriftVolume::GetVolumeID(), lar_pandora::LArDriftVolume::GetWidthX(), lar_pandora::LArDriftVolume::GetWidthY(), lar_pandora::LArDriftVolume::GetWidthZ(), lar_pandora::LArPandoraDetectorType::LoadDaughterDetectorGaps(), LoadGeometry(), X1, X2, Y1, Y2, Z1, and Z2.

Referenced by lar_pandora::LArPandora::beginJob().

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 
37  LArPandoraDetectorType* detType(detector_functions::GetDetectorType());
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  }
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
std::vector< LArDriftVolume > LArDriftVolumeList
intermediate_table::const_iterator const_iterator
Double_t X2
Definition: plot.C:263
TFile f
Definition: plotHisto.C:6
Double_t X1
Definition: plot.C:263
Double_t Y1
Definition: plot.C:263
Double_t Z2
Definition: plot.C:263
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.
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
Double_t Y2
Definition: plot.C:263
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 95 of file LArPandoraGeometry.cxx.

References GetTpcID().

Referenced by lar_pandora::LArPandora::beginJob(), and LoadDetectorGaps().

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

References f, lar_pandora::detector_functions::GetDetectorType(), geo::GeometryCore::Iterate(), geo::kPosX, lar_pandora::LArPandoraDetectorType::WireAngleU(), lar_pandora::LArPandoraDetectorType::WireAngleV(), lar_pandora::LArPandoraDetectorType::WireAngleW(), lar_pandora::LArPandoraDetectorType::WirePitchU(), lar_pandora::LArPandoraDetectorType::WirePitchV(), and lar_pandora::LArPandoraDetectorType::WirePitchW().

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).
237  LArPandoraDetectorType* detType(detector_functions::GetDetectorType());
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  }
details::range_type< T > Iterate() const
Initializes the specified ID with the ID of the first cryostat.
Definition: GeometryCore.h:541
Geometry information for a single TPC.
Definition: TPCGeo.h:36
Geometry information for a single cryostat.
Definition: CryostatGeo.h:43
TFile f
Definition: plotHisto.C:6
std::vector< LArDaughterDriftVolume > LArDaughterDriftVolumeList
LArPandoraDetectorType * GetDetectorType()
Factory class that returns the correct detector type interface.
Drift towards positive X values.
Definition: geo_types.h:166
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 395 of file LArPandoraGeometry.cxx.

References ShouldSwitchUV().

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

References geo::kPosX, and geo::GeometryCore::TPC().

Referenced by GetGlobalView(), and LoadGlobalDaughterGeometry().

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  }
Geometry information for a single TPC.
Definition: TPCGeo.h:36
TPCGeo const & TPC(TPCID const &tpcid=tpc_zero) const
Returns the specified TPC.
Definition: GeometryCore.h:722
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.
The data type to uniquely identify a TPC.
Definition: geo_types.h:381
Drift towards positive X values.
Definition: geo_types.h:166
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 212 of file LArPandoraGeometry.cxx.

References geo::GeometryCore::MaxPlanes().

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  }
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: