7 #include "cetlib_except/exception.h" 24 const bool useActiveBoundingBox)
27 if (!listOfGaps.empty())
29 <<
" LArPandoraGeometry::LoadDetectorGaps --- the list of gaps already exists ";
38 iterEnd1 = driftVolumeList.end();
60 const float gapX(deltaX - widthX);
61 const float gapY(deltaY - widthY);
62 const float gapZ(deltaZ - widthZ);
79 geo::Vector_t gaps(gapX, gapY, gapZ), deltas(deltaX, deltaY, deltaZ);
96 const bool useActiveBoundingBox)
98 if (!outputVolumeList.empty())
100 <<
" LArPandoraGeometry::LoadGeometry --- the list of drift volumes already exists ";
107 (void)outputVolumeMap.insert(LArDriftVolumeMap::value_type(
117 const unsigned int cstat,
118 const unsigned int tpc)
120 if (driftVolumeMap.empty())
122 <<
" LArPandoraGeometry::GetVolumeID --- detector geometry map is empty";
127 if (driftVolumeMap.end() == iter)
129 <<
" LArPandoraGeometry::GetVolumeID --- found a TPC that doesn't belong to a drift volume";
131 return iter->second.GetVolumeID();
138 const unsigned int cstat,
139 const unsigned int tpc)
141 if (driftVolumeMap.empty())
143 <<
" LArPandoraGeometry::GetDaughterVolumeID --- detector geometry map is empty";
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";
153 iterDghtr = iter->second.GetTpcVolumeList().begin(),
154 iterDghtrEnd = iter->second.GetTpcVolumeList().end();
155 iterDghtr != iterDghtrEnd;
159 return std::distance(iter->second.GetTpcVolumeList().begin(), iterDghtr);
162 <<
" LArPandoraGeometry::GetDaughterVolumeID --- found a daughter volume that doesn't belong " 163 "to the drift volume ";
170 const unsigned int tpc,
176 if ((hit_View ==
geo::kW) || (hit_View ==
geo::kY)) {
return hit_View; }
177 else if (hit_View ==
geo::kU) {
180 else if (hit_View ==
geo::kV) {
185 <<
" LArPandoraGeometry::GetGlobalView --- found an unknown plane view (not U, V or W) ";
197 <<
" LArPandoraGeometry::GetTpcID --- found a TPC with an ID greater than 10000 ";
199 return ((10000 * cstat) + tpc);
211 const bool isPositiveDrift(theTpc.DriftDirection() ==
geo::kPosX);
222 if (theGeometry->
MaxPlanes() == 2)
return false;
225 return isPositiveDrift;
232 const bool useActiveBoundingBox)
236 if (!driftVolumeList.empty())
238 <<
" LArPandoraGeometry::LoadGeometry --- detector geometry has already been loaded ";
240 typedef std::set<unsigned int> UIntSet;
245 const float wirePitchU(detType->
WirePitchU());
246 const float wirePitchV(detType->
WirePitchV());
247 const float wirePitchW(detType->
WirePitchW());
248 const float maxDeltaTheta(0.01
f);
251 for (
unsigned int icstat = 0; icstat < theGeometry->
Ncryostats(); ++icstat) {
255 for (
unsigned int itpc1 = 0; itpc1 < theGeometry->
NTPC(icstat); ++itpc1) {
256 if (cstatList.end() != cstatList.find(itpc1))
continue;
260 cstatList.insert(itpc1);
262 const float wireAngleU(detType->
WireAngleU(itpc1, icstat));
263 const float wireAngleV(detType->
WireAngleV(itpc1, icstat));
264 const float wireAngleW(detType->
WireAngleW(itpc1, icstat));
266 double localCoord1[3] = {0., 0., 0.};
267 double worldCoord1[3] = {0., 0., 0.};
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()));
284 useActiveBoundingBox ?
285 (0.5 * (driftMinX + driftMaxX) - 0.25 * std::fabs(driftMaxX - driftMinX)) :
286 (worldCoord1[0] - 0.5 * theTpc1.ActiveHalfWidth()));
288 useActiveBoundingBox ?
289 (0.5 * (driftMinX + driftMaxX) + 0.25 * std::fabs(driftMaxX - driftMinX)) :
290 (worldCoord1[0] + 0.5 * theTpc1.ActiveHalfWidth()));
292 const bool isPositiveDrift(theTpc1.DriftDirection() ==
geo::kPosX);
295 tpcList.insert(itpc1);
300 0.5
f * (driftMaxX + driftMinX),
301 0.5
f * (driftMaxY + driftMinY),
302 0.5
f * (driftMaxZ + driftMinZ),
303 (driftMaxX - driftMinX),
304 (driftMaxY - driftMinY),
305 (driftMaxZ - driftMinZ)));
308 for (
unsigned int itpc2 = itpc1 + 1; itpc2 < theGeometry->
NTPC(icstat); ++itpc2) {
309 if (cstatList.end() != cstatList.find(itpc2))
continue;
313 if (theTpc1.DriftDirection() != theTpc2.DriftDirection())
continue;
315 const float dThetaU(detType->
WireAngleU(itpc1, icstat) -
317 const float dThetaV(detType->
WireAngleV(itpc1, icstat) -
319 const float dThetaW(detType->
WireAngleW(itpc1, icstat) -
321 if (dThetaU > maxDeltaTheta || dThetaV > maxDeltaTheta || dThetaW > maxDeltaTheta)
324 double localCoord2[3] = {0., 0., 0.};
325 double worldCoord2[3] = {0., 0., 0.};
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()));
336 useActiveBoundingBox ?
337 (0.5 * (driftMinX2 + driftMaxX2) - 0.25 * std::fabs(driftMaxX2 - driftMinX2)) :
338 (worldCoord2[0] - 0.5 * theTpc2.ActiveHalfWidth()));
340 useActiveBoundingBox ?
341 (0.5 * (driftMinX2 + driftMaxX2) + 0.25 * std::fabs(driftMaxX2 - driftMinX2)) :
342 (worldCoord2[0] + 0.5 * theTpc2.ActiveHalfWidth()));
344 if ((min2 > max1) || (min1 > max2))
continue;
346 cstatList.insert(itpc2);
347 tpcList.insert(itpc2);
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()));
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);
371 0.5
f * (driftMaxX2 + driftMinX2),
372 0.5
f * (driftMaxY2 + driftMinY2),
373 0.5
f * (driftMaxZ2 + driftMinZ2),
374 (driftMaxX2 - driftMinX2),
375 (driftMaxY2 - driftMinY2),
376 (driftMaxZ2 - driftMinZ2)));
380 driftVolumeList.emplace_back(driftVolumeList.size(),
388 0.5f * (driftMaxX + driftMinX),
389 0.5
f * (driftMaxY + driftMinY),
390 0.5f * (driftMaxZ + driftMinZ),
391 (driftMaxX - driftMinX),
392 (driftMaxY - driftMinY),
393 (driftMaxZ - driftMinZ),
394 (wirePitchU + wirePitchV + wirePitchW + 0.1f),
399 if (driftVolumeList.empty())
400 throw cet::exception(
"LArPandora") <<
" LArPandoraGeometry::LoadGeometry --- failed to find " 401 "any drift volumes in this detector geometry ";
415 if (!daughterVolumeList.empty())
416 throw cet::exception(
"LArPandora") <<
" LArPandoraGeometry::LoadGlobalDaughterGeometry --- " 417 "daughter geometry has already been loaded ";
419 if (driftVolumeList.empty())
420 throw cet::exception(
"LArPandora") <<
" LArPandoraGeometry::LoadGlobalDaughterGeometry --- " 421 "detector geometry has not yet been loaded ";
423 std::cout <<
"The size of the drif list is: " << driftVolumeList.size() <<
std::endl;
427 std::cout <<
"Looking at dau vol: " << count++ <<
std::endl;
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());
441 daughterVolumeList.push_back(
LArDriftVolume(driftVolume.GetVolumeID(),
442 driftVolume.IsPositiveDrift(),
449 driftVolume.GetCenterX(),
450 driftVolume.GetCenterY(),
451 driftVolume.GetCenterZ(),
452 driftVolume.GetWidthX(),
453 driftVolume.GetWidthY(),
454 driftVolume.GetWidthZ(),
455 driftVolume.GetSigmaUVZ(),
456 driftVolume.GetTpcVolumeList()));
459 if (daughterVolumeList.empty())
460 throw cet::exception(
"LArPandora") <<
" LArPandoraGeometry::LoadGlobalDaughterGeometry --- " 461 "failed to create daughter geometry list ";
468 const bool isPositiveDrift,
469 const float wirePitchU,
470 const float wirePitchV,
471 const float wirePitchW,
472 const float wireAngleU,
473 const float wireAngleV,
474 const float wireAngleW,
481 const float sigmaUVZ,
483 : m_volumeID(volumeID)
484 , m_isPositiveDrift(isPositiveDrift)
485 , m_wirePitchU(wirePitchU)
486 , m_wirePitchV(wirePitchV)
487 , m_wirePitchW(wirePitchW)
488 , m_wireAngleU(wireAngleU)
489 , m_wireAngleV(wireAngleV)
490 , m_wireAngleW(wireAngleW)
497 , m_sigmaUVZ(sigmaUVZ)
498 , m_tpcVolumeList(tpcVolumeList)
float GetWidthZ() const
Return Z span of drift volume.
static geo::View_t GetGlobalView(const unsigned int cstat, const unsigned int tpc, const geo::View_t hit_View)
Convert to global coordinate system.
daughter drift volume class to hold properties of daughter drift volumes
static void LoadGeometry(LArDriftVolumeList &outputVolumeList, LArDriftVolumeMap &outputVolumeMap, const bool useActiveBoundingBox)
Load drift volume geometry.
virtual float WireAngleV(const geo::TPCID::TPCID_t tpc, const geo::CryostatID::CryostatID_t cstat) const =0
The angle of the wires in the mapped V view.
LArDriftVolume(const unsigned int volumeID, const bool isPositiveDrift, const float wirePitchU, const float wirePitchV, const float wirePitchW, const float wireAngleU, const float wireAngleV, const float wireAngleW, const float centerX, const float centerY, const float centerZ, const float widthX, const float widthY, const float widthZ, const float sigmaUVZ, const LArDaughterDriftVolumeList &tpcVolumeList)
Constructor.
Helper functions for extracting detector geometry for use in reconsruction.
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
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.
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.
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
virtual float WirePitchV() const =0
The wire pitch of the mapped V view.
unsigned int Ncryostats() const
Returns the number of cryostats in the detector.
Planes which measure Y direction.
art framework interface to geometry description
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.
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.
unsigned int MaxPlanes() const
Returns the largest number of planes among all TPCs in this detector.
static unsigned int GetTpcID(const unsigned int cstat, const unsigned int tpc)
Generate a unique identifier for each TPC.
virtual float WirePitchU() const =0
The wire pitch of the mapped U view.
virtual bool CheckDetectorGapSize(const geo::Vector_t &gaps, const geo::Vector_t &deltas, const float maxDisplacement) const =0
Check whether a gap size is small enough to be registered as a detector gap.
float GetCenterX() const
Return X position at centre of drift volume.
unsigned int GetVolumeID() const
Return unique ID.
static bool ShouldSwitchUV(const unsigned int cstat, const unsigned int tpc)
Return whether U/V should be switched in global coordinate system for this cryostat/tpc.
static void LoadGlobalDaughterGeometry(const LArDriftVolumeList &driftVolumeList, LArDriftVolumeList &daughterVolumeList)
This method will create one or more daughter volumes (these share a common drift orientation along th...
virtual void LoadDaughterDetectorGaps(const LArDriftVolume &driftVolume, const float maxDisplacement, LArDetectorGapList &listOfGaps) const =0
Create detector gaps for all daughter volumes in a logical TPC volume.
double distance(double x1, double y1, double z1, double x2, double y2, double z2)
static void LoadDetectorGaps(LArDetectorGapList &listOfGaps, const bool useActiveBoundingBox)
Load the 2D gaps that go with the chosen geometry.
static int max(int a, int b)
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 LArDetectorGap CreateDetectorGap(const geo::Point_t &point1, const geo::Point_t &point2, const geo::Vector_t &widths) const =0
Create a detector gap.
virtual float WirePitchW() const =0
The wire pitch of the mapped W view.
Encapsulate the geometry of a wire.
unsigned int NTPC(unsigned int cstat=0) const
Returns the total number of TPCs in the specified cryostat.
std::vector< LArDaughterDriftVolume > LArDaughterDriftVolumeList
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
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)
Drift towards positive X values.
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.
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
drift volume class to hold properties of drift volume
Planes which measure W (third view for Bo, MicroBooNE, etc).
float GetWidthX() const
Return X span of drift volume.
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.
cet::coded_exception< error, detail::translate > exception
QTextStream & endl(QTextStream &s)
Encapsulate the construction of a single detector plane.
unsigned int GetTpc() const
Return tpc ID.