10 #include "cetlib_except/exception.h" 27 const bool useActiveBoundingBox)
30 if (!listOfGaps.empty())
32 <<
" LArPandoraGeometry::LoadDetectorGaps --- the list of gaps already exists ";
41 iterEnd1 = driftVolumeList.end();
63 const float gapX(deltaX - widthX);
64 const float gapY(deltaY - widthY);
65 const float gapZ(deltaZ - widthZ);
82 geo::Vector_t gaps(gapX, gapY, gapZ), deltas(deltaX, deltaY, deltaZ);
98 const bool useActiveBoundingBox)
100 if (!outputVolumeList.empty())
102 <<
" LArPandoraGeometry::LoadGeometry --- the list of drift volumes already exists ";
109 (void)outputVolumeMap.insert(LArDriftVolumeMap::value_type(
118 const unsigned int cstat,
119 const unsigned int tpc)
121 if (driftVolumeMap.empty())
123 <<
" LArPandoraGeometry::GetVolumeID --- detector geometry map is empty";
128 if (driftVolumeMap.end() == iter)
130 <<
" LArPandoraGeometry::GetVolumeID --- found a TPC that doesn't belong to a drift volume";
132 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 ";
169 const unsigned int tpc,
175 if ((hit_View ==
geo::kW) || (hit_View ==
geo::kY)) {
return hit_View; }
176 else if (hit_View ==
geo::kU) {
179 else if (hit_View ==
geo::kV) {
184 <<
" LArPandoraGeometry::GetGlobalView --- found an unknown plane view (not U, V or W) ";
194 <<
" LArPandoraGeometry::GetTpcID --- found a TPC with an ID greater than 10000 ";
196 return ((10000 * cstat) + tpc);
206 const bool isPositiveDrift(theGeometry->
TPC({cstat, tpc}).
DriftSign() ==
217 if (wireReadoutGeom.MaxPlanes() == 2)
return false;
220 return isPositiveDrift;
226 const bool useActiveBoundingBox)
230 if (!driftVolumeList.empty())
232 <<
" LArPandoraGeometry::LoadGeometry --- detector geometry has already been loaded ";
234 typedef std::set<unsigned int> UIntSet;
239 const float wirePitchU(detType->
WirePitchU());
240 const float wirePitchV(detType->
WirePitchV());
241 const float wirePitchW(detType->
WirePitchW());
242 const float maxDeltaTheta(0.01
f);
246 auto const icstat = cryostat.ID().Cryostat;
250 for (
auto const& theTpc1 : theGeometry->Iterate<
geo::TPCGeo>(cryostat.ID())) {
251 auto const itpc1 = theTpc1.ID().TPC;
252 if (cstatList.end() != cstatList.find(itpc1))
continue;
255 cstatList.insert(itpc1);
257 const float wireAngleU(detType->
WireAngleU(itpc1, icstat));
258 const float wireAngleV(detType->
WireAngleV(itpc1, icstat));
259 const float wireAngleW(detType->
WireAngleW(itpc1, icstat));
261 auto const worldCoord1 = theTpc1.GetCenter();
263 float driftMinX(useActiveBoundingBox ? theTpc1.ActiveBoundingBox().MinX() :
264 (worldCoord1.X() - theTpc1.ActiveHalfWidth()));
265 float driftMaxX(useActiveBoundingBox ? theTpc1.ActiveBoundingBox().MaxX() :
266 (worldCoord1.X() + theTpc1.ActiveHalfWidth()));
267 float driftMinY(useActiveBoundingBox ? theTpc1.ActiveBoundingBox().MinY() :
268 (worldCoord1.Y() - theTpc1.ActiveHalfHeight()));
269 float driftMaxY(useActiveBoundingBox ? theTpc1.ActiveBoundingBox().MaxY() :
270 (worldCoord1.Y() + theTpc1.ActiveHalfHeight()));
271 float driftMinZ(useActiveBoundingBox ? theTpc1.ActiveBoundingBox().MinZ() :
272 (worldCoord1.Z() - 0.5f * theTpc1.ActiveLength()));
273 float driftMaxZ(useActiveBoundingBox ? theTpc1.ActiveBoundingBox().MaxZ() :
274 (worldCoord1.Z() + 0.5f * theTpc1.ActiveLength()));
277 useActiveBoundingBox ?
278 (0.5 * (driftMinX + driftMaxX) - 0.25 * std::fabs(driftMaxX - driftMinX)) :
279 (worldCoord1.X() - 0.5 * theTpc1.ActiveHalfWidth()));
281 useActiveBoundingBox ?
282 (0.5 * (driftMinX + driftMaxX) + 0.25 * std::fabs(driftMaxX - driftMinX)) :
283 (worldCoord1.X() + 0.5 * theTpc1.ActiveHalfWidth()));
288 tpcList.insert(itpc1);
293 0.5
f * (driftMaxX + driftMinX),
294 0.5
f * (driftMaxY + driftMinY),
295 0.5
f * (driftMaxZ + driftMinZ),
296 (driftMaxX - driftMinX),
297 (driftMaxY - driftMinY),
298 (driftMaxZ - driftMinZ)));
301 for (
auto const& theTpc2 : theGeometry->Iterate<
geo::TPCGeo>(cryostat.ID())) {
302 auto const itpc2 = theTpc2.ID().TPC;
303 if (cstatList.end() != cstatList.find(itpc2))
continue;
304 if (theTpc1.DriftSign() != theTpc2.DriftSign())
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)
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.
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
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.
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.
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.
geo::DriftSign DriftSign() const
Returns the expected drift direction based on geometry.
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
Drift towards positive values.
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.
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.
TPCGeo const & TPC(TPCID const &tpcid=details::tpc_zero) const
Returns the specified TPC.
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.