20 #include "cetlib_except/exception.h" 25 #include "TGeoManager.h" 28 #include "TGeoMatrix.h" 36 #include <type_traits> 44 T symmetricCapDelta(
T value,
T limit) {
46 return (value < -limit)
58 T symmetricCap(
T value,
T limit) {
60 return value + symmetricCapDelta(value, limit);
108 "Necessary maintenance: remove the now optional conversions" 117 double const wMargin = 0.0;
118 double const dMargin = 0.0;
140 if (wireEnds[kFirstWireStart].
X() > wireEnds[kFirstWireEnd].
X())
141 std::swap(wireEnds[kFirstWireStart], wireEnds[kFirstWireEnd]);
146 if (wireEnds[kLastWireStart].
X() > wireEnds[kLastWireEnd].
X())
147 std::swap(wireEnds[kLastWireStart], wireEnds[kLastWireEnd]);
157 for (
auto const& aWireEnd: wireEnds) {
171 Vector_t const widthDir = { 1.0, 0.0 };
172 Vector_t const depthDir = { 0.0, 1.0 };
175 double const hp = plane.
WirePitch() / 2.0;
193 double const cosAngleWidth =
geo::vect::dot(wireCoordDir, widthDir);
194 double const cosAngleDepth =
geo::vect::dot(wireCoordDir, depthDir);
196 bool const bPositiveAngle
197 =
none_or_both((wireCoordDir.X() >= 0), (wireCoordDir.Y() >= 0));
202 if (cosAngleWidth < 0) wireCoordDir = -wireCoordDir;
205 assert(wireEnds[kFirstWireEnd].
X() >= wireEnds[kFirstWireStart].
X());
206 bool const bAlongWidth
209 bool const bAlongDepth = !bAlongWidth &&
212 assert(!(bAlongWidth && bAlongDepth));
224 std::size_t
const iUpperWire
225 = (cosAngleDepth > 0)? kLastWireStart: kFirstWireStart;
227 double const maxUpperDistance = activeArea.
depth.
upper 229 (wireEnds[iUpperWire].
Y(), wireEnds[iUpperWire ^ 0
x1].
Y())
233 activeArea.
depth.
upper += (hp - maxUpperDistance);
239 std::size_t
const iLowerWire
240 = (cosAngleDepth > 0)? kFirstWireStart: kLastWireStart;
242 double const maxLowerDistance
244 (wireEnds[iLowerWire].
Y(), wireEnds[iLowerWire ^ 0
x1].
Y())
248 activeArea.
depth.
lower -= (hp - maxLowerDistance);
251 else if (bAlongDepth) {
264 std::size_t
const iUpperWire
265 = (cosAngleWidth > 0)? kLastWireStart: kFirstWireStart;
267 double const maxUpperDistance = activeArea.
width.
upper 269 (wireEnds[iUpperWire].
X(), wireEnds[iUpperWire ^ 0
x1].
X())
272 activeArea.
width.
upper += (hp - maxUpperDistance);
281 std::size_t
const iLowerWire
282 = (cosAngleWidth > 0)? kFirstWireStart: kLastWireStart;
284 double const maxLowerDistance
286 (wireEnds[iLowerWire].
X(), wireEnds[iLowerWire ^ 0
x1].
X())
290 activeArea.
width.
lower -= (hp - maxLowerDistance);
293 else if (bPositiveAngle) {
302 std::size_t
const iUpperWire
303 = (cosAngleWidth > 0)? kLastWireStart: kFirstWireStart;
310 auto const upperDelta = (hp - upperDistance) * wireCoordDir;
320 std::size_t
const iLowerWire
321 = (cosAngleWidth > 0)? kFirstWireEnd: kLastWireEnd;
328 auto const lowerDelta = (hp - lowerDistance) * wireCoordDir;
342 std::size_t
const iUpperWire
343 = (cosAngleWidth > 0)? kLastWireStart: kFirstWireStart;
350 auto const upperDelta = (hp - upperDistance) * wireCoordDir;
360 std::size_t
const iLowerWire
361 = (cosAngleWidth > 0)? kFirstWireEnd: kLastWireEnd;
368 auto const lowerDelta = (hp - lowerDistance) * wireCoordDir;
379 if (wMargin != 0.0) {
383 if (dMargin != 0.0) {
421 template <
typename T>
436 TGeoNode
const& node,
441 , fVolume(node.GetVolume())
455 <<
"Plane geometry node " << node.IsA()->GetName()
456 <<
"[" << node.GetName() <<
", #" << node.GetNumber()
457 <<
"] has no volume!\n";
475 TGeoBBox
const* pShape =
dynamic_cast<TGeoBBox
const*
>(
fVolume->GetShape());
478 <<
"BoundingBox(): volume " <<
fVolume->IsA()->GetName()
479 <<
"['" <<
fVolume->GetName() <<
"'] has a shape which is a " 480 << pShape->IsA()->GetName()
481 <<
", not a TGeoBBox!";
485 unsigned int points = 0;
486 for (
double dx: { -(pShape->GetDX()), +(pShape->GetDX()) }) {
487 for (
double dy: { -(pShape->GetDY()), +(pShape->GetDY()) }) {
488 for (
double dz: { -(pShape->GetDZ()), +(pShape->GetDZ()) }) {
510 <<
"Request for non-existant wire " << iwire <<
"\n";
535 std::array<double, 3>
A,
B;
540 return { A.data(), B.data() };
548 std::ostringstream sstr;
586 return (deltaProj.X() == 0.) && (deltaProj.Y() == 0.);
643 return point + deltaProj.X() * WidthDir<geo::Vector_t>() + deltaProj.Y() * DepthDir<geo::Vector_t>();
662 if ((nearestWireNo < 0) || ((
unsigned int) nearestWireNo >=
Nwires())) {
664 auto wireNo = nearestWireNo;
666 if (nearestWireNo < 0 ) wireNo = 0;
667 else wireNo =
Nwires() - 1;
670 <<
"Can't find nearest wire for position " << pos
671 <<
" in plane " <<
std::string(
ID()) <<
" approx wire number # " 672 << wireNo <<
" (capped from " << nearestWireNo <<
")\n";
691 if (wireID)
return Wire(wireID);
696 <<
"Can't find nearest wire for position " << point
697 <<
" in plane " <<
std::string(
ID()) <<
" approx wire number # " 698 << closestID.
Wire <<
" (capped from " << wireID.
Wire <<
")\n";
715 double const r = dir.R();
718 double const absWireCoordProj
744 for (
auto& wire:
fWire) {
779 switch (orientation) {
782 default:
return "unexpected";
break;
807 TGeoBBox
const* pShape =
dynamic_cast<TGeoBBox
const*
>(
fVolume->GetShape());
810 <<
"Volume " <<
fVolume->IsA()->GetName() <<
"['" <<
fVolume->GetName()
811 <<
"'] has a shape which is a " << pShape->IsA()->GetName()
812 <<
", not a TGeoBBox! Dimensions won't be available.";
821 std::array<geo::Vector_t, 3U> sides;
822 size_t iSmallest = 3;
833 if (sides[iSide].Mag2() < sides[iSmallest].Mag2()) iSmallest = iSide;
837 if (sides[iSide].Mag2() < sides[iSmallest].Mag2()) iSmallest = iSide;
848 for (
size_t i = 0; i < 3; ++i)
if (i != iSmallest) kept[iKept++] = i;
856 size_t const iiWidth =
859 size_t const iWidth = kept[iiWidth];
860 size_t const iDepth = kept[1 - iiWidth];
872 const unsigned int NWires =
Nwires();
873 if (NWires < 2)
return {};
899 if (
fWire.size() < 2) {
902 <<
"PlaneGeo::UpdateOrientation(): only " <<
fWire.size()
906 auto normal = GetNormalDirection<geo::Vector_t>();
917 <<
"Plane with unsupported orientation (normal: " << normal <<
")\n";
928 auto const iWire =
Nwires() / 2;
985 auto const& normalDir = GetNormalDirection<geo::Vector_t>();
986 auto const& wireDir = GetWireDirection<geo::Vector_t>();
989 if (
std::abs(normalDir.Y()) != 1.0) {
1001 double const closeToX
1003 double const closeToZ
1056 auto const towardCenter
1097 auto refWireNo =
Nwires() / 2;
1098 if (refWireNo ==
Nwires() - 1) --refWireNo;
1099 auto const& refWire =
Wire(refWireNo);
1105 auto wireCoordDir = GetNormalDirection<geo::Vector_t>().Cross(WireDir).Unit();
1112 if (wireCoordDir.Dot(toNextWire) < 0) {
1113 wireCoordDir = -wireCoordDir;
1144 auto firstWire =
fWire.cbegin(), wire = firstWire, wend =
fWire.cend();
1147 while (++wire != wend) {
1149 if (wirePitch < 1
e-4)
continue;
1200 fCenter = GetBoxCenter<geo::Point_t>();
static std::string OrientationName(geo::Orient_t orientation)
Returns the name of the specified orientation.
geo::WirePtr WirePtr(unsigned int iwire) const
Returns the wire number iwire from this plane.
void round01(Vector &v, Scalar tol)
Returns a vector with all components rounded if close to 0, -1 or +1.
void GetStart(double *xyz) const
Geometry description of a TPC wireThe wire is a single straight segment on a wire plane...
void initializeWireEnds()
Utilities to extend the interface of geometry vectors.
auto VectorSecondaryComponent(Vector_t const &v) const
Returns the secondary component of a vector.
void SetView(geo::View_t view)
Set the signal view (for TPCGeo).
WidthDepthProjection_t VectorWidthDepthProjection(geo::Vector_t const &v) const
Returns the projection of the specified vector on the plane.
geo::Point_t fCenter
Center of the plane, lying on the wire plane.
constexpr auto dot(Vector const &a, Vector const &b)
Return cross product of two vectors.
static std::string ViewName(geo::View_t view)
Returns the name of the specified view.
std::string PlaneInfo(std::string indent="", unsigned int verbosity=1) const
Returns a string with plane information.
void UpdateIncreasingWireDir()
Updates the cached direction to increasing wires.
double fWirePitch
Pitch of wires in this plane.
void SetSecondaryDir(Vector_t const &dir)
Change the secondary direction of the projection base.
std::vector< geo::WireGeo > WireCollection_t
void UpdateWirePitch()
Updates the stored wire pitch.
void UpdateWidthDepthDir()
Updates the cached depth and width direction.
double const dMargin
Margin subtracted from each side of depth.
static bool none_or_both(bool a, bool b)
Returns true if a and b are both true or both false (exclusive nor).
lar::util::simple_geo::Rectangle< double > Rect
Type for description of rectangles.
Vector_t const & NormalDir() const
Returns the plane normal axis direction.
WireGeo const & Wire(unsigned int iwire) const
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
auto mixedProduct(Vector const &a, Vector const &b, Vector const &c)
enum geo::_plane_orient Orient_t
Provides simple real number checks.
void UpdateOrientation()
Updates plane orientation.
geo::PlaneID fID
ID of this plane.
Planes which measure X direction.
The data type to uniquely identify a Plane.
Volume delimited by two points.
constexpr Vector Yaxis()
Returns a y axis vector of the specified type.
geo::PlaneGeo::WidthDepthDisplacement_t Vector_t
::geo::Point_t toPoint(Point const &p)
Convert the specified point into a geo::Point_t.
Point GetBoxCenter() const
Returns the centre of the box representing the plane.
bool isProjectionOnPlane(geo::Point_t const &point) const
Returns if the projection of specified point is within the plane.
::geo::Vector_t toVector(Vector const &v)
Convert the specified vector into a geo::Vector_t.
static constexpr std::size_t kLastWireStart
WidthDepthProjection_t PointWidthDepthProjection(geo::Point_t const &point) const
Returns the projection of the specified point on the plane.
static constexpr std::size_t kFirstWireStart
Planes which measure Z direction.
geo::WireGeo const & NearestWire(geo::Point_t const &pos) const
Returns the wire closest to the specified position.
Data_t delta(Data_t v, Data_t margin=0.0) const
WireID_t Wire
Index of the wire within its plane.
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
bool shouldFlipWire(geo::WireGeo const &wire) const
Whether the specified wire should have start and end swapped.
Vector GetNormalDirection() const
Returns the direction normal to the plane.
void round0(Vector &v, Scalar tol)
Returns a vector with all components rounded if close to 0.
static double WirePitch(geo::WireGeo const &w1, geo::WireGeo const &w2)
Returns the pitch (distance on y/z plane) between two wires, in cm.
PlaneGeo const & plane
Plane to work on.
WidthDepthProjection_t MoveProjectionToPlane(WidthDepthProjection_t const &proj) const
Returns the projection, moved onto the plane if necessary.
Vector GetIncreasingWireDirection() const
Returns the direction of increasing wires.
double ThetaZ() const
Returns angle of wire with respect to z axis in the Y-Z plane in radians.
geo::BoxBoundedGeo BoundingBox() const
Class for approximate comparisons.
Planes which measure Y direction.
void DetectGeometryDirections()
Sets the geometry directions.
Projection_t wireEnds[4]
Cache: wire end projections.
double InterWireProjectedDistance(WireCoordProjection_t const &projDir) const
Returns the distance between wires along the specified direction.
void DriftPoint(geo::Point_t &position, double distance) const
Shifts the position of an electron drifted by a distance.
Rect fActiveArea
Area covered by wires in frame base.
geo::PlaneGeo::Rect recomputeArea()
3-dimensional objects, potentially hits, clusters, prongs, etc.
double ThetaZ() const
Angle of the wires from positive z axis; .
void UpdatePlaneNormal(geo::BoxBoundedGeo const &TPCbox)
Updates the cached normal to plane versor; needs the TPC box coordinates.
TGeoVolume const * fVolume
Plane volume description.
ROOT::Math::DisplacementVector2D< ROOT::Math::Cartesian2D< double >, WidthDepthReferenceTag > WidthDepthProjection_t
Planes that are in the horizontal plane.
void extendToInclude(Data_t)
Extends the range to include the specified point.
lar::util::simple_geo::Volume Coverage() const
Returns a volume including all the wires in the plane.
auto makeVector3DComparison(RealType threshold)
Creates a Vector3DComparison from a RealComparisons object.
geo::WireID NearestWireID(geo::Point_t const &pos) const
Returns the ID of wire closest to the specified position.
WidthDepthDecomposer_t fDecompFrame
void UpdatePhiZ()
Updates the stored .
void swap(Handle< T > &a, Handle< T > &b)
Planes that are in the vertical plane (e.g. ArgoNeuT).
Collection of exceptions for Geometry system.
geo::Point_t toWorldCoords(LocalPoint_t const &local) const
Transform point from local plane frame to world frame.
ROOT::Math::DisplacementVector2D< ROOT::Math::Cartesian2D< double >, WireCoordinateReferenceTag > WireCoordProjection_t
Type for projections in the wire base representation.
WireCollection_t fWire
List of wires in this plane.
geo::Point_t MovePointOverPlane(geo::Point_t const &point) const
Returns the point, moved so that its projection is over the plane.
Point GetCenter() const
Returns the centre of the wire plane in world coordinates [cm].
Geometry information for a single wire plane.The plane is represented in the geometry by a solid whic...
double InterWireDistance(geo::Vector_t const &dir) const
Returns the distance between wires along the specified direction.
constexpr Vector Xaxis()
Returns a x axis vector of the specified type.
Class comparing 2D vectors.
Range_t width
Range along width direction.
void UpdateWirePitchSlow()
Updates the stored wire pitch with a slower, more robust algorithm.
const WireGeo & FirstWire() const
Return the first wire in the plane.
static int max(int a, int b)
void UpdateAfterSorting(geo::PlaneID planeid, geo::BoxBoundedGeo const &TPCbox)
Performs all needed updates after the TPC has sorted the planes.
ROOT::Math::DisplacementVector2D< ROOT::Math::Cartesian2D< double >, WidthDepthReferenceTag > WidthDepthDisplacement_t
Type for vector projections in the plane frame base representation.
static constexpr std::size_t kLastWireEnd
void UpdateView()
Updates the stored view.
Vector rounded01(Vector const &v, Scalar tol)
Returns a vector with all components rounded if close to 0, -1 or +1.
Encapsulate the geometry of a wire.
Vector DepthDir() const
Return the direction of plane depth.
constexpr Vector Zaxis()
Returns a z axis vector of the specified type.
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Range_t depth
Range along depth direction.
Tag for plane frame base vectors.
ActiveAreaCalculator(geo::PlaneGeo const &plane, double margin=0.0)
void SetOrigin(Point_t const &point)
Change the 3D point of the reference frame origin.
Vector_t const & SecondaryDir() const
Returns the plane secondary axis direction.
WidthDepthProjection_t DeltaFromPlane(WidthDepthProjection_t const &proj, double wMargin, double dMargin) const
Returns a projection vector that, added to the argument, gives a projection inside (or at the border ...
WidthDepthProjection_t DeltaFromActivePlane(WidthDepthProjection_t const &proj, double wMargin, double dMargin) const
Returns a projection vector that, added to the argument, gives a projection inside (or at the border ...
A base class aware of world box coordinatesAn object describing a simple shape can inherit from this ...
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
geo::Vector_t GetNormalAxis() const
Returns a direction normal to the plane (pointing is not defined).
Encapsulate the construction of a single detector plane.
void PrintPlaneInfo(Stream &&out, std::string indent="", unsigned int verbosity=1) const
Prints information about this plane.
double DistanceFromPlane(geo::Point_t const &point) const
Returns the distance of the specified point from the wire plane.
void SetBoundaries(Coord_t x_min, Coord_t x_max, Coord_t y_min, Coord_t y_max, Coord_t z_min, Coord_t z_max)
Sets the boundaries in world coordinates as specified.
void GetEnd(double *xyz) const
constexpr bool nonNegative(Value_t value) const
Returns whether value is larger than or equal() to zero.
geo::PlaneID const & ID() const
Returns the identifier of this plane.
double const wMargin
Margin subtracted from each side of width.
ActiveAreaCalculator(geo::PlaneGeo const &plane, double wMargin, double dMargin)
unsigned int Nwires() const
Number of wires in this plane.
geo::WireID ClosestWireID(geo::WireID::WireID_t wireNo) const
Returns the closest valid wire ID to the specified wire.
bool WireIDincreasesWithZ() const
Returns whether the higher z wires have higher wire ID.
void ExtendToInclude(Coord_t x, Coord_t y, Coord_t z)
Extends the current box to also include the specified point.
double fCosPhiZ
Cosine of .
Data_t upper
Ending coordinate.
Vector WidthDir() const
Return the direction of plane width.
Exception thrown on invalid wire number.
static constexpr std::size_t kFirstWireEnd
unsigned int WireID_t
Type for the ID number.
void UpdateWirePlaneCenter()
Updates the stored wire plane center.
WireDecomposer_t fDecompWire
static bool equal(T a, T b, T tol=T(1e-5))
Returns whether the two numbers are the same, lest a tolerance.
virtual void SortWires(std::vector< geo::WireGeo > &wgeo) const =0
void GetCenter(double *xyz, double localz=0.0) const
Fills the world coordinate of a point on the wire.
double WireCoordinate(Point const &point) const
Returns the coordinate of the point on the plane, in wire units.
void UpdateDecompWireOrigin()
Updates the position of the wire coordinate decomposition.
Class computing the active area of the plane.
void UpdateActiveArea()
Updates the internally used active area.
void includeAllWireEnds()
Collection of Physical constants used in LArSoft.
geo::Vector3DBase_t< PlaneGeoCoordinatesTag > LocalVector_t
Type of displacement vectors in the local GDML wire plane frame.
Data_t lower
Starting coordinate.
const WireGeo & LastWire() const
Return the last wire in the plane.
LArSoft geometry interface.
void SortWires(geo::GeoObjectSorter const &sorter)
Apply sorting to WireGeo objects.
Orient_t fOrientation
Is the plane vertical or horizontal?
ROOT::Math::PositionVector2D< ROOT::Math::Cartesian2D< double >, geo::PlaneGeo::WidthDepthReferenceTag > Projection_t
std::string to_string(ModuleType const mt)
void UpdateWireDir()
Updates the cached direction to wire.
geo::Point3DBase_t< PlaneGeoCoordinatesTag > LocalPoint_t
Type of points in the local GDML wire plane frame.
ROOT::Math::Transform3D TransformationMatrix
Type of transformation matrix used in geometry.
constexpr Point origin()
Returns a origin position with a point of the specified type.
cet::coded_exception< error, detail::translate > exception
double WirePitch() const
Return the wire pitch (in centimeters). It is assumed constant.
geo::PlaneGeo::Rect activeArea
Result.
PlaneGeo(TGeoNode const &node, geo::TransformationMatrix &&trans, WireCollection_t &&wires)
Construct a representation of a single plane of the detector.
void SetMainDir(Vector_t const &dir)
Change the main direction of the projection base.
geo::Point_t Center() const
Returns the center point of the box.