18 #include "cetlib/pow.h" 19 #include "cetlib_except/exception.h" 25 #include "TGeoManager.h" 26 #include "TGeoMatrix.h" 36 #include <type_traits> 42 T symmetricCapDelta(T
value, T limit)
45 return (value < -limit) ? -limit - value : (value > +limit) ? +limit - value : 0.0;
51 T symmetricCap(T value, T limit)
54 return value + symmetricCapDelta(value, limit);
81 : plane(plane), wMargin(wMargin), dMargin(dMargin)
91 using Projection_t = ROOT::Math::PositionVector2D<ROOT::Math::Cartesian2D<double>,
96 "Necessary maintenance: remove the now optional conversions");
120 auto makeProjection = [](
auto v) {
return Projection_t(v.X(), v.Y()); };
126 if (wireEnds[kFirstWireStart].
X() > wireEnds[kFirstWireEnd].
X())
127 std::swap(wireEnds[kFirstWireStart], wireEnds[kFirstWireEnd]);
132 if (wireEnds[kLastWireStart].
X() > wireEnds[kLastWireEnd].
X())
133 std::swap(wireEnds[kLastWireStart], wireEnds[kLastWireEnd]);
143 for (
auto const& aWireEnd : wireEnds) {
157 Vector_t const widthDir = {1.0, 0.0};
158 Vector_t const depthDir = {0.0, 1.0};
161 double const hp = plane.
WirePitch() / 2.0;
179 double const cosAngleWidth =
geo::vect::dot(wireCoordDir, widthDir);
180 double const cosAngleDepth =
geo::vect::dot(wireCoordDir, depthDir);
182 bool const bPositiveAngle =
none_or_both((wireCoordDir.X() >= 0), (wireCoordDir.Y() >= 0));
187 if (cosAngleWidth < 0) wireCoordDir = -wireCoordDir;
190 assert(wireEnds[kFirstWireEnd].
X() >= wireEnds[kFirstWireStart].
X());
191 bool const bAlongWidth
194 bool const bAlongDepth =
196 equal(std::max(wireEnds[kFirstWireStart].
Y(), wireEnds[kFirstWireEnd].
Y()),
198 equal(std::min(wireEnds[kFirstWireStart].
Y(), wireEnds[kFirstWireEnd].
Y()),
200 assert(!(bAlongWidth && bAlongDepth));
212 std::size_t
const iUpperWire = (cosAngleDepth > 0) ? kLastWireStart : kFirstWireStart;
214 double const maxUpperDistance =
216 std::min(wireEnds[iUpperWire].
Y(), wireEnds[iUpperWire ^ 0
x1].
Y());
219 activeArea.
depth.
upper += (hp - maxUpperDistance);
225 std::size_t
const iLowerWire = (cosAngleDepth > 0) ? kFirstWireStart : kLastWireStart;
227 double const maxLowerDistance =
228 std::max(wireEnds[iLowerWire].
Y(), wireEnds[iLowerWire ^ 0
x1].
Y()) -
231 activeArea.
depth.
lower -= (hp - maxLowerDistance);
234 else if (bAlongDepth) {
247 std::size_t
const iUpperWire = (cosAngleWidth > 0) ? kLastWireStart : kFirstWireStart;
249 double const maxUpperDistance =
251 std::min(wireEnds[iUpperWire].
X(), wireEnds[iUpperWire ^ 0
x1].
X());
253 activeArea.
width.
upper += (hp - maxUpperDistance);
262 std::size_t
const iLowerWire = (cosAngleWidth > 0) ? kFirstWireStart : kLastWireStart;
264 double const maxLowerDistance =
265 std::max(wireEnds[iLowerWire].
X(), wireEnds[iLowerWire ^ 0
x1].
X()) -
268 activeArea.
width.
lower -= (hp - maxLowerDistance);
271 else if (bPositiveAngle) {
280 std::size_t
const iUpperWire = (cosAngleWidth > 0) ? kLastWireStart : kFirstWireStart;
285 auto const upperDelta = (hp - upperDistance) * wireCoordDir;
295 std::size_t
const iLowerWire = (cosAngleWidth > 0) ? kFirstWireEnd : kLastWireEnd;
300 auto const lowerDelta = (hp - lowerDistance) * wireCoordDir;
313 std::size_t
const iUpperWire = (cosAngleWidth > 0) ? kLastWireStart : kFirstWireStart;
318 auto const upperDelta = (hp - upperDistance) * wireCoordDir;
328 std::size_t
const iLowerWire = (cosAngleWidth > 0) ? kFirstWireEnd : kLastWireEnd;
333 auto const lowerDelta = (hp - lowerDistance) * wireCoordDir;
343 if (wMargin != 0.0) {
347 if (dMargin != 0.0) {
384 template <
typename T>
385 static bool equal(T a, T b, T tol = T(1
e-5))
402 : fTrans(
std::move(trans))
403 , fVolume(node.GetVolume())
406 , fWire(
std::move(wires))
417 <<
"Plane geometry node " << node.IsA()->GetName() <<
"[" << node.GetName() <<
", #" 418 << node.GetNumber() <<
"] has no volume!\n";
437 TGeoBBox
const* pShape =
dynamic_cast<TGeoBBox const*
>(
fVolume->GetShape());
440 <<
"BoundingBox(): volume " <<
fVolume->IsA()->GetName() <<
" is not a TGeoBBox!";
444 unsigned int points = 0;
445 for (
double dx : {-(pShape->GetDX()), +(pShape->GetDX())}) {
446 for (
double dy : {-(pShape->GetDY()), +(pShape->GetDY())}) {
447 for (
double dz : {-(pShape->GetDZ()), +(pShape->GetDZ())}) {
469 throw cet::exception(
"WireOutOfRange") <<
"Request for non-existant wire " << iwire <<
"\n";
496 unsigned int verbosity )
const 498 std::ostringstream sstr;
506 double dMargin)
const 518 double dMargin)
const 531 return (deltaProj.X() == 0.) && (deltaProj.Y() == 0.);
544 return {(delta.X() == 0.0) ?
586 if ((nearestWireNo < 0) || ((
unsigned int)nearestWireNo >=
Nwires())) {
588 auto wireNo = nearestWireNo;
590 if (nearestWireNo < 0)
596 <<
"Can't find nearest wire for position " << pos <<
" in plane " << std::string(
ID())
597 <<
" approx wire number # " << wireNo <<
" (capped from " << nearestWireNo <<
")\n";
616 if (wireID)
return Wire(wireID);
621 <<
"Can't find nearest wire for position " << point <<
" in plane " << std::string(
ID())
622 <<
" approx wire number # " << closestID.
Wire <<
" (capped from " << wireID.
Wire <<
")\n";
630 return std::sqrt(cet::square(projDir.X() / projDir.Y()) + 1.0) *
fWirePitch;
637 double const r = dir.R();
665 for (
auto& wire :
fWire) {
692 default:
return "<UNSUPPORTED (" +
std::to_string((
int)view) +
")>";
699 switch (orientation) {
702 default:
return "unexpected";
break;
727 TGeoBBox
const* pShape =
dynamic_cast<TGeoBBox const*
>(
fVolume->GetShape());
730 <<
" is not a TGeoBBox! Dimensions won't be available.";
739 std::array<geo::Vector_t, 3U> sides;
740 size_t iSmallest = 3;
749 if (sides[iSide].Mag2() < sides[iSmallest].Mag2()) iSmallest = iSide;
753 if (sides[iSide].Mag2() < sides[iSmallest].Mag2()) iSmallest = iSide;
763 for (
size_t i = 0; i < 3; ++i)
764 if (i != iSmallest) kept[iKept++] = i;
772 size_t const iiWidth =
774 size_t const iWidth = kept[iiWidth];
775 size_t const iDepth = kept[1 - iiWidth];
787 const unsigned int NWires =
Nwires();
788 if (NWires < 2)
return {};
813 if (
fWire.size() < 2) {
816 <<
"PlaneGeo::UpdateOrientation(): only " <<
fWire.size() <<
" wires!\n";
830 <<
"Plane with unsupported orientation (normal: " << normal <<
")\n";
842 auto const iWire =
Nwires() / 2;
895 if (
std::abs(normalDir.Y()) != 1.0) {
913 else if ((ynw * yw) < 0)
915 else if ((ynw * yw) > 0)
940 else if ((znw * zw) < 0)
942 else if ((znw * zw) > 0)
1002 auto refWireNo =
Nwires() / 2;
1003 if (refWireNo ==
Nwires() - 1) --refWireNo;
1004 auto const& refWire =
Wire(refWireNo);
1005 auto const& WireDir = refWire.Direction();
1012 auto toNextWire =
Wire(refWireNo + 1).
GetCenter() - refWire.GetCenter();
1015 if (wireCoordDir.Dot(toNextWire) < 0) { wireCoordDir = -wireCoordDir; }
1045 auto firstWire =
fWire.cbegin(), wire = firstWire, wend =
fWire.cend();
1048 while (++wire != wend) {
1050 if (wirePitch < 1
e-4)
continue;
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.
Geometry description of a TPC wireThe wire is a single straight segment on a wire plane...
void initializeWireEnds()
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).
ROOT::Math::DisplacementVector2D< ROOT::Math::Cartesian2D< double >, WidthDepthReferenceTag > WidthDepthDisplacement_t
Type for vector projections in the plane frame base representation.
Point_t const & GetCenter() const
Returns the world coordinate of the center of the wire [cm].
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.
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.
Vector_t const & DepthDir() const
Return the direction of plane depth.
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
Point_t const & GetCenter() const
Returns the centre of the wire plane in world coordinates [cm].
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
Enumerate the possible plane projections.
Float_t x1[n_points_granero]
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.
void extendToInclude(Data_t)
Extends the range to include the specified point.
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.
constexpr auto abs(T v)
Returns the absolute value of the argument.
bool isProjectionOnPlane(geo::Point_t const &point) const
Returns if the projection of specified point is within the plane.
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.
WireID_t Wire
Index of the wire within its plane.
double WireCoordinate(geo::Point_t const &point) const
Returns the coordinate of the point on the plane, in wire units.
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
bool shouldFlipWire(geo::WireGeo const &wire) const
Whether the specified wire should have start and end swapped.
void round0(Vector &v, Scalar tol)
Returns a vector with all components rounded if close to 0.
Point_t GetStart() const
Returns the world coordinate of one end of the wire [cm].
Point_t GetEnd() const
Returns the world coordinate of one end of the wire [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.
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.
Planes that are in the horizontal plane.
Collection of exceptions for Geometry system.
Point_t GetBoxCenter() const
Returns the centre of the box representing 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 .
Vector_t Direction() const
decltype(auto) constexpr to_string(T &&obj)
ADL-aware version of std::to_string.
Planes that are in the vertical plane (e.g. ArgoNeuT).
geo::Point_t toWorldCoords(LocalPoint_t const &local) const
Transform point from local plane frame to world frame.
Vector_t const & GetWireDirection() const
Returns the direction of the wires.
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.
std::string indent(std::size_t const i)
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.
Utilities to extend the interface of geometry vectors.
constexpr Vector Xaxis()
Returns a x axis vector of the specified type.
ROOT::Math::DisplacementVector2D< ROOT::Math::Cartesian2D< double >, WireCoordinateReferenceTag > WireCoordProjection_t
Type for projections in the wire base representation.
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.
void UpdateAfterSorting(geo::PlaneID planeid, geo::BoxBoundedGeo const &TPCbox)
Performs all needed updates after the TPC has sorted the planes.
constexpr auto dot(Vector const &a, OtherVector const &b)
Return cross product of two vectors.
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.
ROOT::Math::DisplacementVector2D< ROOT::Math::Cartesian2D< double >, WidthDepthReferenceTag > WidthDepthProjection_t
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 ...
Data_t delta(Data_t v, Data_t margin=0.0) const
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 ...
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
Returns a volume including all the wires in the 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.
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.
Vector_t const & WidthDir() const
Return the direction of plane 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_t const & GetIncreasingWireDirection() const
Returns the direction of increasing wires.
Exception thrown on invalid wire number.
Vector_t const & GetNormalDirection() const
Returns the direction normal to the plane.
static double WirePitch(WireGeo const &w1, WireGeo const &w2)
Returns the pitch (distance on y/z plane) between two wires, in cm.
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 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.
Namespace collecting geometry-related classes utilities.
void SortWires(geo::GeoObjectSorter const &sorter)
Apply sorting to WireGeo objects.
Orient_t fOrientation
Is the plane vertical or horizontal?
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.
ROOT::Math::PositionVector2D< ROOT::Math::Cartesian2D< double >, geo::PlaneGeo::WidthDepthReferenceTag > Projection_t