10 #include "cetlib_except/exception.h" 26 const bool useActiveBoundingBox)
29 if (!listOfGaps.empty())
31 <<
" LArPandoraGeometry::LoadDetectorGaps --- the list of gaps already exists ";
40 iterEnd1 = driftVolumeList.end();
62 const float gapX(deltaX - widthX);
63 const float gapY(deltaY - widthY);
64 const float gapZ(deltaZ - widthZ);
81 geo::Vector_t gaps(gapX, gapY, gapZ), deltas(deltaX, deltaY, deltaZ);
97 const bool useActiveBoundingBox)
99 if (!outputVolumeList.empty())
101 <<
" LArPandoraGeometry::LoadGeometry --- the list of drift volumes already exists ";
108 (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();
137 const unsigned int cstat,
138 const unsigned int tpc)
140 if (driftVolumeMap.empty())
142 <<
" LArPandoraGeometry::GetDaughterVolumeID --- detector geometry map is empty";
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";
152 iterDghtr = iter->second.GetTpcVolumeList().begin(),
153 iterDghtrEnd = iter->second.GetTpcVolumeList().end();
154 iterDghtr != iterDghtrEnd;
158 return std::distance(iter->second.GetTpcVolumeList().begin(), iterDghtr);
161 <<
" LArPandoraGeometry::GetDaughterVolumeID --- found a daughter volume that doesn't belong " 162 "to the drift volume ";
168 const unsigned int tpc,
174 if ((hit_View ==
geo::kW) || (hit_View ==
geo::kY)) {
return hit_View; }
175 else if (hit_View ==
geo::kU) {
178 else if (hit_View ==
geo::kV) {
183 <<
" LArPandoraGeometry::GetGlobalView --- found an unknown plane view (not U, V or W) ";
193 <<
" LArPandoraGeometry::GetTpcID --- found a TPC with an ID greater than 10000 ";
195 return ((10000 * cstat) + tpc);
206 const bool isPositiveDrift(theTpc.DriftDirection() ==
geo::kPosX);
216 if (theGeometry->
MaxPlanes() == 2)
return false;
219 return isPositiveDrift;
225 const bool useActiveBoundingBox)
229 if (!driftVolumeList.empty())
231 <<
" LArPandoraGeometry::LoadGeometry --- detector geometry has already been loaded ";
233 typedef std::set<unsigned int> UIntSet;
238 const float wirePitchU(detType->
WirePitchU());
239 const float wirePitchV(detType->
WirePitchV());
240 const float wirePitchW(detType->
WirePitchW());
241 const float maxDeltaTheta(0.01
f);
245 auto const icstat = cryostat.ID().Cryostat;
250 auto const itpc1 = theTpc1.ID().TPC;
251 if (cstatList.end() != cstatList.find(itpc1))
continue;
254 cstatList.insert(itpc1);
256 const float wireAngleU(detType->
WireAngleU(itpc1, icstat));
257 const float wireAngleV(detType->
WireAngleV(itpc1, icstat));
258 const float wireAngleW(detType->
WireAngleW(itpc1, icstat));
260 auto const worldCoord1 = theTpc1.GetCenter();
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()));
276 useActiveBoundingBox ?
277 (0.5 * (driftMinX + driftMaxX) - 0.25 * std::fabs(driftMaxX - driftMinX)) :
278 (worldCoord1.X() - 0.5 * theTpc1.ActiveHalfWidth()));
280 useActiveBoundingBox ?
281 (0.5 * (driftMinX + driftMaxX) + 0.25 * std::fabs(driftMaxX - driftMinX)) :
282 (worldCoord1.X() + 0.5 * theTpc1.ActiveHalfWidth()));
284 const bool isPositiveDrift(theTpc1.DriftDirection() ==
geo::kPosX);
287 tpcList.insert(itpc1);
292 0.5
f * (driftMaxX + driftMinX),
293 0.5
f * (driftMaxY + driftMinY),
294 0.5
f * (driftMaxZ + driftMinZ),
295 (driftMaxX - driftMinX),
296 (driftMaxY - driftMinY),
297 (driftMaxZ - driftMinZ)));
301 auto const itpc2 = theTpc2.ID().TPC;
302 if (cstatList.end() != cstatList.find(itpc2))
continue;
304 if (theTpc1.DriftDirection() != theTpc2.DriftDirection())
continue;
306 const float dThetaU(detType->
WireAngleU(itpc1, icstat) -
308 const float dThetaV(detType->
WireAngleV(itpc1, icstat) -
310 const float dThetaW(detType->
WireAngleW(itpc1, icstat) -
312 if (dThetaU > maxDeltaTheta || dThetaV > maxDeltaTheta || dThetaW > maxDeltaTheta)
315 auto const worldCoord2 = theTpc2.GetCenter();
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()));
325 useActiveBoundingBox ?
326 (0.5 * (driftMinX2 + driftMaxX2) - 0.25 * std::fabs(driftMaxX2 - driftMinX2)) :
327 (worldCoord2.X() - 0.5 * theTpc2.ActiveHalfWidth()));
329 useActiveBoundingBox ?
330 (0.5 * (driftMinX2 + driftMaxX2) + 0.25 * std::fabs(driftMaxX2 - driftMinX2)) :
331 (worldCoord2.X() + 0.5 * theTpc2.ActiveHalfWidth()));
333 if ((min2 > max1) || (min1 > max2))
continue;
335 cstatList.insert(itpc2);
336 tpcList.insert(itpc2);
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()));
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);
360 0.5
f * (driftMaxX2 + driftMinX2),
361 0.5
f * (driftMaxY2 + driftMinY2),
362 0.5
f * (driftMaxZ2 + driftMinZ2),
363 (driftMaxX2 - driftMinX2),
364 (driftMaxY2 - driftMinY2),
365 (driftMaxZ2 - driftMinZ2)));
369 driftVolumeList.emplace_back(driftVolumeList.size(),
377 0.5f * (driftMaxX + driftMinX),
378 0.5
f * (driftMaxY + driftMinY),
379 0.5f * (driftMaxZ + driftMinZ),
380 (driftMaxX - driftMinX),
381 (driftMaxY - driftMinY),
382 (driftMaxZ - driftMinZ),
383 (wirePitchU + wirePitchV + wirePitchW + 0.1f),
388 if (driftVolumeList.empty())
389 throw cet::exception(
"LArPandora") <<
" LArPandoraGeometry::LoadGeometry --- failed to find " 390 "any drift volumes in this detector geometry ";
403 if (!daughterVolumeList.empty())
404 throw cet::exception(
"LArPandora") <<
" LArPandoraGeometry::LoadGlobalDaughterGeometry --- " 405 "daughter geometry has already been loaded ";
407 if (driftVolumeList.empty())
408 throw cet::exception(
"LArPandora") <<
" LArPandoraGeometry::LoadGlobalDaughterGeometry --- " 409 "detector geometry has not yet been loaded ";
411 std::cout <<
"The size of the drif list is: " << driftVolumeList.size() << std::endl;
415 std::cout <<
"Looking at dau vol: " << count++ << std::endl;
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());
429 daughterVolumeList.push_back(
LArDriftVolume(driftVolume.GetVolumeID(),
430 driftVolume.IsPositiveDrift(),
437 driftVolume.GetCenterX(),
438 driftVolume.GetCenterY(),
439 driftVolume.GetCenterZ(),
440 driftVolume.GetWidthX(),
441 driftVolume.GetWidthY(),
442 driftVolume.GetWidthZ(),
443 driftVolume.GetSigmaUVZ(),
444 driftVolume.GetTpcVolumeList()));
447 if (daughterVolumeList.empty())
448 throw cet::exception(
"LArPandora") <<
" LArPandoraGeometry::LoadGlobalDaughterGeometry --- " 449 "failed to create daughter geometry list ";
456 const bool isPositiveDrift,
457 const float wirePitchU,
458 const float wirePitchV,
459 const float wirePitchW,
460 const float wireAngleU,
461 const float wireAngleV,
462 const float wireAngleW,
469 const float sigmaUVZ,
471 : m_volumeID(volumeID)
472 , m_isPositiveDrift(isPositiveDrift)
473 , m_wirePitchU(wirePitchU)
474 , m_wirePitchV(wirePitchV)
475 , m_wirePitchW(wirePitchW)
476 , m_wireAngleU(wireAngleU)
477 , m_wireAngleV(wireAngleV)
478 , m_wireAngleW(wireAngleW)
485 , m_sigmaUVZ(sigmaUVZ)
486 , m_tpcVolumeList(tpcVolumeList)
details::range_type< T > Iterate() const
Initializes the specified ID with the ID of the first cryostat.
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.
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
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.
virtual float WirePitchV() const =0
The wire pitch of the mapped V view.
Geometry information for a single cryostat.
Planes which measure Y direction.
float GetCenterZ() const
Return Z position at centre of drift volume.
TPCGeo const & TPC(TPCID const &tpcid=tpc_zero) const
Returns the specified TPC.
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.
static void LoadDetectorGaps(LArDetectorGapList &listOfGaps, const bool useActiveBoundingBox)
Load the 2D gaps that go with the chosen geometry.
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.
The data type to uniquely identify a TPC.
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.
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.
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.
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.
art framework interface to geometry description
cet::coded_exception< error, detail::translate > exception
Encapsulate the construction of a single detector plane.
unsigned int GetTpc() const
Return tpc ID.