LSST Applications g063fba187b+cac8b7c890,g0f08755f38+6aee506743,g1653933729+a8ce1bb630,g168dd56ebc+a8ce1bb630,g1a2382251a+b4475c5878,g1dcb35cd9c+8f9bc1652e,g20f6ffc8e0+6aee506743,g217e2c1bcf+73dee94bd0,g28da252d5a+1f19c529b9,g2bbee38e9b+3f2625acfc,g2bc492864f+3f2625acfc,g3156d2b45e+6e55a43351,g32e5bea42b+1bb94961c2,g347aa1857d+3f2625acfc,g35bb328faa+a8ce1bb630,g3a166c0a6a+3f2625acfc,g3e281a1b8c+c5dd892a6c,g3e8969e208+a8ce1bb630,g414038480c+5927e1bc1e,g41af890bb2+8a9e676b2a,g7af13505b9+809c143d88,g80478fca09+6ef8b1810f,g82479be7b0+f568feb641,g858d7b2824+6aee506743,g89c8672015+f4add4ffd5,g9125e01d80+a8ce1bb630,ga5288a1d22+2903d499ea,gb58c049af0+d64f4d3760,gc28159a63d+3f2625acfc,gcab2d0539d+b12535109e,gcf0d15dbbd+46a3f46ba9,gda6a2b7d83+46a3f46ba9,gdaeeff99f8+1711a396fd,ge79ae78c31+3f2625acfc,gef2f8181fd+0a71e47438,gf0baf85859+c1f95f4921,gfa517265be+6aee506743,gfa999e8aa5+17cd334064,w.2024.51
LSST Data Management Base Package
Loading...
Searching...
No Matches
Namespaces | Classes | Typedefs | Functions | Variables
lsst::sphgeom Namespace Reference

Namespaces

namespace  _continue_class
 
namespace  _healpixPixelization
 
namespace  _yaml
 
namespace  detail
 
namespace  pixelization_abc
 
namespace  python
 
namespace  version
 

Classes

class  Angle
 Angle represents an angle in radians. More...
 
class  AngleInterval
 AngleInterval represents closed intervals of arbitrary angles. More...
 
class  BigInteger
 BigInteger is an arbitrary precision signed integer class. More...
 
class  Box
 Box represents a rectangle in spherical coordinate space that contains its boundary. More...
 
class  Box3d
 Box3d represents a box in ℝ³. More...
 
class  Chunker
 Chunker subdivides the unit sphere into longitude-latitude boxes. More...
 
class  Circle
 Circle is a circular region on the unit sphere that contains its boundary. More...
 
class  CompoundRegion
 CompoundRegion is an intermediate base class for spherical regions that are comprised of a point-set operation on other nested regions. More...
 
class  ConvexPolygon
 ConvexPolygon is a closed convex polygon on the unit sphere. More...
 
class  Ellipse
 Ellipse is an elliptical region on the sphere. More...
 
class  HtmPixelization
 HtmPixelization provides HTM indexing of points and regions. More...
 
class  IntersectionRegion
 IntersectionRegion is a lazy point-set inersection of its operands. More...
 
class  Interval
 Interval represents a closed interval of the real numbers by its upper and lower bounds. More...
 
class  Interval1d
 Interval1d represents closed intervals of ℝ. More...
 
class  LonLat
 LonLat represents a spherical coordinate (longitude/latitude angle) pair. More...
 
class  Matrix3d
 A 3x3 matrix with real entries stored in double precision. More...
 
class  Mq3cPixelization
 Mq3cPixelization provides modified Q3C indexing of points and regions. More...
 
class  NormalizedAngle
 NormalizedAngle is an angle that lies in the range [0, 2π), with one exception - a NormalizedAngle can be NaN. More...
 
class  NormalizedAngleInterval
 NormalizedAngleInterval represents closed intervals of normalized angles, i.e. More...
 
class  Pixelization
 A Pixelization (or partitioning) of the sphere is a mapping between points on the sphere and a set of pixels (a.k.a. More...
 
class  Q3cPixelization
 Q3cPixelization provides Q3C indexing of points and regions. More...
 
class  RangeSet
 A RangeSet is a set of unsigned 64 bit integers. More...
 
class  Region
 Region is a minimal interface for 2-dimensional regions on the unit sphere. More...
 
struct  SubChunks
 SubChunks represents a set of sub-chunks of a particular chunk. More...
 
class  TriState
 TriState represents a boolean value with additional unknown state. More...
 
class  UnionRegion
 UnionRegion is a lazy point-set union of its operands. More...
 
class  UnitVector3d
 UnitVector3d is a unit vector in ℝ³ with components stored in double precision. More...
 
class  Vector3d
 Vector3d is a vector in ℝ³ with components stored in double precision. More...
 

Typedefs

using Relationship = std::bitset<3>
 Relationship describes how two sets are related.
 

Functions

Angle operator* (double a, Angle const &b)
 
std::ostreamoperator<< (std::ostream &, Angle const &)
 
double sin (Angle const &a)
 
double cos (Angle const &a)
 
double tan (Angle const &a)
 
Angle abs (Angle const &a)
 
std::ostreamoperator<< (std::ostream &, AngleInterval const &)
 
std::ostreamoperator<< (std::ostream &, Box const &)
 
std::ostreamoperator<< (std::ostream &, Box3d const &)
 
std::ostreamoperator<< (std::ostream &, Circle const &)
 
void encodeDouble (double item, std::vector< std::uint8_t > &buffer)
 encodeDouble appends an IEEE double in little-endian byte order to the end of buffer.
 
double decodeDouble (std::uint8_t const *buffer)
 decodeDouble extracts an IEEE double from the 8 byte little-endian byte sequence in buffer.
 
void encodeU64 (std::uint64_t item, std::vector< std::uint8_t > &buffer)
 encodeU64 appends an uint64 in little-endian byte order to the end of buffer.
 
std::uint64_t decodeU64 (std::uint8_t const *buffer)
 decodeU64 extracts an uint64 from the 8 byte little-endian byte sequence in buffer.
 
std::ostreamoperator<< (std::ostream &, ConvexPolygon const &)
 
std::uint64_t mortonIndex (std::uint32_t x, std::uint32_t y)
 mortonIndex interleaves the bits of x and y.
 
std::tuple< std::uint32_t, std::uint32_tmortonIndexInverse (std::uint64_t z)
 mortonIndexInverse separates the even and odd bits of z.
 
std::uint64_t mortonToHilbert (std::uint64_t z, int m)
 mortonToHilbert converts the 2m-bit Morton index z to the corresponding Hilbert index.
 
std::uint64_t hilbertToMorton (std::uint64_t h, int m)
 hilbertToMorton converts the 2m-bit Hilbert index h to the corresponding Morton index.
 
std::uint64_t hilbertIndex (std::uint32_t x, std::uint32_t y, int m)
 hilbertIndex returns the index of (x, y) in a 2-D Hilbert curve.
 
std::tuple< std::uint32_t, std::uint32_thilbertIndexInverse (std::uint64_t h, int m)
 hilbertIndexInverse returns the point (x, y) with Hilbert index h, where x and y are m bit integers.
 
std::ostreamoperator<< (std::ostream &, Ellipse const &)
 
std::ostreamoperator<< (std::ostream &, Interval1d const &)
 
std::ostreamoperator<< (std::ostream &, LonLat const &)
 
std::ostreamoperator<< (std::ostream &, Matrix3d const &)
 
NormalizedAngle const & abs (NormalizedAngle const &a)
 
std::ostreamoperator<< (std::ostream &, NormalizedAngleInterval const &)
 
int orientationExact (Vector3d const &a, Vector3d const &b, Vector3d const &c)
 orientationExact computes and returns the orientations of 3 vectors a, b and c, which need not be normalized but are assumed to have finite components.
 
int orientation (UnitVector3d const &a, UnitVector3d const &b, UnitVector3d const &c)
 orientation computes and returns the orientations of 3 unit vectors a, b and c.
 
int orientationX (UnitVector3d const &b, UnitVector3d const &c)
 orientationX(b, c) is equivalent to orientation(UnitVector3d::X(), b, c).
 
int orientationY (UnitVector3d const &b, UnitVector3d const &c)
 orientationY(b, c) is equivalent to orientation(UnitVector3d::Y(), b, c).
 
int orientationZ (UnitVector3d const &b, UnitVector3d const &c)
 orientationZ(b, c) is equivalent to orientation(UnitVector3d::Z(), b, c).
 
template<typename Pybind11Class >
void defineClass (Pybind11Class &cls)
 
void swap (RangeSet &a, RangeSet &b)
 
std::ostreamoperator<< (std::ostream &, RangeSet const &)
 
Relationship invert (Relationship r)
 Given the relationship between two sets A and B (i.e.
 
std::ostreamoperator<< (std::ostream &stream, TriState const &value)
 
std::ostreamoperator<< (std::ostream &, UnitVector3d const &)
 
double getMinSquaredChordLength (Vector3d const &v, Vector3d const &a, Vector3d const &b, Vector3d const &n)
 Let p be the unit vector closest to v that lies on the plane with normal n in the direction of the cross product of a and b.
 
double getMaxSquaredChordLength (Vector3d const &v, Vector3d const &a, Vector3d const &b, Vector3d const &n)
 Let p be the unit vector furthest from v that lies on the plane with normal n in the direction of the cross product of a and b.
 
Angle getMinAngleToCircle (Angle x, Angle c)
 getMinAngleToCircle returns the minimum angular separation between a point at latitude x and the points on the circle of constant latitude c.
 
Angle getMaxAngleToCircle (Angle x, Angle c)
 getMaxAngleToCircle returns the maximum angular separation between a point at latitude x and the points on the circle of constant latitude c.
 
Vector3d getWeightedCentroid (UnitVector3d const &v0, UnitVector3d const &v1, UnitVector3d const &v2)
 getWeightedCentroid returns the center of mass of the given spherical triangle (assuming a uniform mass distribution over the triangle surface), weighted by the triangle area.
 
Vector3d operator* (double s, Vector3d const &v)
 
std::ostreamoperator<< (std::ostream &, Vector3d const &)
 
template<>
void defineClass (py::class_< Angle > &cls)
 
template<>
void defineClass (py::class_< AngleInterval, std::shared_ptr< AngleInterval > > &cls)
 
template<>
void defineClass (py::class_< Box, std::unique_ptr< Box >, Region > &cls)
 
template<>
void defineClass (py::class_< Box3d, std::shared_ptr< Box3d > > &cls)
 
template<>
void defineClass (py::class_< Chunker, std::shared_ptr< Chunker > > &cls)
 
template<>
void defineClass (py::class_< Circle, std::unique_ptr< Circle >, Region > &cls)
 
template<>
void defineClass (py::class_< CompoundRegion, std::unique_ptr< CompoundRegion >, Region > &cls)
 
template<>
void defineClass (py::class_< UnionRegion, std::unique_ptr< UnionRegion >, CompoundRegion > &cls)
 
template<>
void defineClass (py::class_< IntersectionRegion, std::unique_ptr< IntersectionRegion >, CompoundRegion > &cls)
 
template<>
void defineClass (py::class_< ConvexPolygon, std::unique_ptr< ConvexPolygon >, Region > &cls)
 
void defineCurve (py::module &mod)
 
template<>
void defineClass (py::class_< Ellipse, std::unique_ptr< Ellipse >, Region > &cls)
 
template<>
void defineClass (py::class_< HtmPixelization, Pixelization > &cls)
 
template<>
void defineClass (py::class_< Interval1d, std::shared_ptr< Interval1d > > &cls)
 
template<>
void defineClass (py::class_< LonLat, std::shared_ptr< LonLat > > &cls)
 
template<>
void defineClass (py::class_< Matrix3d, std::shared_ptr< Matrix3d > > &cls)
 
template<>
void defineClass (py::class_< Mq3cPixelization, Pixelization > &cls)
 
template<>
void defineClass (py::class_< NormalizedAngle > &cls)
 
template<>
void defineClass (py::class_< NormalizedAngleInterval, std::shared_ptr< NormalizedAngleInterval > > &cls)
 
void defineOrientation (py::module &mod)
 
template<>
void defineClass (py::class_< Pixelization > &cls)
 
template<>
void defineClass (py::class_< Q3cPixelization, Pixelization > &cls)
 
template<>
void defineClass (py::class_< RangeSet, std::shared_ptr< RangeSet > > &cls)
 
template<>
void defineClass (py::class_< Region, std::unique_ptr< Region > > &cls)
 
void defineRelationship (py::module &mod)
 
void defineUtils (py::module &)
 
template<>
void defineClass (py::class_< UnitVector3d, std::shared_ptr< UnitVector3d > > &cls)
 
template<>
void defineClass (py::class_< Vector3d, std::shared_ptr< Vector3d > > &cls)
 
std::uint8_t log2 (std::uint64_t x)
 
std::uint8_t log2 (std::uint32_t x)
 

Variables

constexpr double PI = 3.1415926535897932384626433832795
 
constexpr double ONE_OVER_PI = 0.318309886183790671537767526745
 
constexpr double RAD_PER_DEG = 0.0174532925199432957692369076849
 
constexpr double DEG_PER_RAD = 57.2957795130823208767981548141
 
constexpr double MAX_ASIN_ERROR = 1.5e-8
 
constexpr double MAX_SQUARED_CHORD_LENGTH_ERROR = 2.5e-15
 
constexpr double EPSILON = 1.1102230246251565e-16
 

Detailed Description

lsst.sphgeom

Typedef Documentation

◆ Relationship

Relationship describes how two sets are related.

Definition at line 42 of file Relationship.h.

Function Documentation

◆ abs() [1/2]

Angle lsst::sphgeom::abs ( Angle const & a)
inline

Definition at line 113 of file Angle.h.

113{ return Angle(std::fabs(a.asRadians())); }
Angle represents an angle in radians.
Definition Angle.h:50
T fabs(T... args)

◆ abs() [2/2]

NormalizedAngle const & lsst::sphgeom::abs ( NormalizedAngle const & a)
inline

Definition at line 159 of file NormalizedAngle.h.

159{ return a; }
table::Key< int > a

◆ cos()

double lsst::sphgeom::cos ( Angle const & a)
inline

Definition at line 110 of file Angle.h.

110{ return std::cos(a.asRadians()); }
T cos(T... args)

◆ decodeDouble()

double lsst::sphgeom::decodeDouble ( std::uint8_t const * buffer)
inline

decodeDouble extracts an IEEE double from the 8 byte little-endian byte sequence in buffer.

Definition at line 77 of file codec.h.

77 {
78#ifdef OPTIMIZED_LITTLE_ENDIAN
79 return *reinterpret_cast<double const *>(buffer);
80#else
81 union { std::uint64_t u; double d; };
82 u = static_cast<std::uint64_t>(buffer[0]) +
83 (static_cast<std::uint64_t>(buffer[1]) << 8) +
84 (static_cast<std::uint64_t>(buffer[2]) << 16) +
85 (static_cast<std::uint64_t>(buffer[3]) << 24) +
86 (static_cast<std::uint64_t>(buffer[4]) << 32) +
87 (static_cast<std::uint64_t>(buffer[5]) << 40) +
88 (static_cast<std::uint64_t>(buffer[6]) << 48) +
89 (static_cast<std::uint64_t>(buffer[7]) << 56);
90 return d;
91#endif
92}

◆ decodeU64()

std::uint64_t lsst::sphgeom::decodeU64 ( std::uint8_t const * buffer)
inline

decodeU64 extracts an uint64 from the 8 byte little-endian byte sequence in buffer.

Definition at line 116 of file codec.h.

116 {
117#ifdef OPTIMIZED_LITTLE_ENDIAN
118 return *reinterpret_cast<std::uint64_t const *>(buffer);
119#else
120 std::uint64_t u = static_cast<std::uint64_t>(buffer[0]) +
121 (static_cast<std::uint64_t>(buffer[1]) << 8) +
122 (static_cast<std::uint64_t>(buffer[2]) << 16) +
123 (static_cast<std::uint64_t>(buffer[3]) << 24) +
124 (static_cast<std::uint64_t>(buffer[4]) << 32) +
125 (static_cast<std::uint64_t>(buffer[5]) << 40) +
126 (static_cast<std::uint64_t>(buffer[6]) << 48) +
127 (static_cast<std::uint64_t>(buffer[7]) << 56);
128 return u;
129#endif
130}

◆ defineClass() [1/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Angle > & cls)

Definition at line 43 of file _angle.cc.

43 {
44 cls.def_static("nan", &Angle::nan);
45 cls.def_static("fromDegrees", &Angle::fromDegrees);
46 cls.def_static("fromRadians", &Angle::fromRadians);
47
48 cls.def(py::init<>());
49 cls.def(py::init<double>(), "radians"_a);
50 cls.def(py::init<Angle>(), "angle"_a);
51 // Construct an Angle from a NormalizedAngle, enabling implicit
52 // conversion from NormalizedAngle to Angle in python via
53 // py::implicitly_convertible
54 cls.def(py::init(
55 [](NormalizedAngle &a) {
56 return new Angle(a.asRadians());
57 }),
58 "normalizedAngle"_a);
59
60 cls.def("__eq__", &Angle::operator==, py::is_operator());
61 cls.def("__ne__", &Angle::operator!=, py::is_operator());
62 cls.def("__lt__", &Angle::operator<, py::is_operator());
63 cls.def("__gt__", &Angle::operator>, py::is_operator());
64 cls.def("__le__", &Angle::operator<=, py::is_operator());
65 cls.def("__ge__", &Angle::operator>=, py::is_operator());
66
67 cls.def("__neg__", (Angle(Angle::*)() const) & Angle::operator-);
68 cls.def("__add__", &Angle::operator+, py::is_operator());
69 cls.def("__sub__",
70 (Angle(Angle::*)(Angle const &) const) & Angle::operator-,
71 py::is_operator());
72 cls.def("__mul__", &Angle::operator*, py::is_operator());
73 cls.def("__rmul__", &Angle::operator*, py::is_operator());
74 cls.def("__truediv__", (Angle(Angle::*)(double) const) & Angle::operator/,
75 py::is_operator());
76 cls.def("__truediv__",
77 (double (Angle::*)(Angle const &) const) & Angle::operator/,
78 py::is_operator());
79
80 cls.def("__iadd__", &Angle::operator+=);
81 cls.def("__isub__", &Angle::operator-=);
82 cls.def("__imul__", &Angle::operator*=);
83 cls.def("__itruediv__", &Angle::operator/=);
84
85 cls.def("asDegrees", &Angle::asDegrees);
86 cls.def("asRadians", &Angle::asRadians);
87 cls.def("isNormalized", &Angle::isNormalized);
88 cls.def("isNan", &Angle::isNan);
89
90 cls.def("__str__", [](Angle const &self) {
91 return py::str("{!s}").format(self.asRadians());
92 });
93 cls.def("__repr__", [](Angle const &self) {
94 return py::str("Angle({!r})").format(self.asRadians());
95 });
96
97 cls.def("__reduce__", [cls](Angle const &self) {
98 return py::make_tuple(cls, py::make_tuple(self.asRadians()));
99 });
100}
NormalizedAngle is an angle that lies in the range [0, 2π), with one exception - a NormalizedAngle ca...

◆ defineClass() [2/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< AngleInterval, std::shared_ptr< AngleInterval > > & cls)

Definition at line 43 of file _angleInterval.cc.

44 {
45 python::defineInterval<decltype(cls), AngleInterval, Angle>(cls);
46
47 cls.def_static("fromDegrees", &AngleInterval::fromDegrees, "x"_a, "y"_a);
48 cls.def_static("fromRadians", &AngleInterval::fromRadians, "x"_a, "y"_a);
49 cls.def_static("empty", &AngleInterval::empty);
50 cls.def_static("full", &AngleInterval::full);
51
52 cls.def(py::init<>());
53 cls.def(py::init<Angle>(), "x"_a);
54 cls.def(py::init<Angle, Angle>(), "x"_a, "y"_a);
55 cls.def(py::init<AngleInterval const &>(), "interval"_a);
56
57 cls.def("__str__", [](AngleInterval const &self) {
58 return py::str("[{!s}, {!s}]")
59 .format(self.getA().asRadians(), self.getB().asRadians());
60 });
61 cls.def("__repr__", [](AngleInterval const &self) {
62 return py::str("AngleInterval.fromRadians({!r}, {!r})")
63 .format(self.getA().asRadians(), self.getB().asRadians());
64 });
65}
double asRadians() const
asRadians returns the value of this angle in units of radians.
Definition Angle.h:92
AngleInterval represents closed intervals of arbitrary angles.
Scalar getA() const
getA returns the lower endpoint of this interval.
Definition Interval.h:83
Scalar getB() const
getB returns the upper endpoint of this interval.
Definition Interval.h:87

◆ defineClass() [3/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Box, std::unique_ptr< Box >, Region > & cls)

Definition at line 55 of file _box.cc.

55 {
56 cls.attr("TYPE_CODE") = py::int_(Box::TYPE_CODE);
57
58 cls.def_static("fromDegrees", &Box::fromDegrees, "lon1"_a, "lat1"_a,
59 "lon2"_a, "lat2"_a);
60 cls.def_static("fromRadians", &Box::fromRadians, "lon1"_a, "lat1"_a,
61 "lon2"_a, "lat2"_a);
62 cls.def_static("empty", &Box::empty);
63 cls.def_static("full", &Box::full);
64 cls.def_static("halfWidthForCircle", &Box::halfWidthForCircle, "radius"_a,
65 "lat"_a);
66 cls.def_static("allLongitudes", &Box::allLongitudes);
67 cls.def_static("allLatitudes", &Box::allLatitudes);
68
69 cls.def(py::init<>());
70 cls.def(py::init<LonLat const &>(), "point"_a);
71 cls.def(py::init<LonLat const &, LonLat const &>(), "point1"_a, "point2"_a);
72 cls.def(py::init<LonLat const &, Angle, Angle>(), "center"_a, "width"_a,
73 "height"_a);
74 cls.def(py::init<NormalizedAngleInterval const &, AngleInterval const &>(),
75 "lon"_a, "lat"_a);
76 cls.def(py::init<Box const &>(), "box"_a);
77
78 cls.def("__eq__", (bool (Box::*)(Box const &) const) & Box::operator==,
79 py::is_operator());
80 cls.def("__eq__", (bool (Box::*)(LonLat const &) const) & Box::operator==,
81 py::is_operator());
82 cls.def("__ne__", (bool (Box::*)(Box const &) const) & Box::operator!=,
83 py::is_operator());
84 cls.def("__ne__", (bool (Box::*)(LonLat const &) const) & Box::operator!=,
85 py::is_operator());
86 cls.def("__contains__",
87 (bool (Box::*)(LonLat const &) const) & Box::contains,
88 py::is_operator());
89 cls.def("__contains__", (bool (Box::*)(Box const &) const) & Box::contains,
90 py::is_operator());
91 // Rewrap this base class method since there are overloads in this subclass
92 cls.def("__contains__",
93 (bool (Box::*)(UnitVector3d const &) const) & Box::contains,
94 py::is_operator());
95
96 cls.def("getLon", &Box::getLon);
97 cls.def("getLat", &Box::getLat);
98 cls.def("isFull", &Box::isFull);
99 cls.def("getCenter", &Box::getCenter);
100 cls.def("getWidth", &Box::getWidth);
101 cls.def("getHeight", &Box::getHeight);
102 cls.def("contains", (bool (Box::*)(LonLat const &) const) & Box::contains);
103 cls.def("contains", (bool (Box::*)(Box const &) const) & Box::contains);
104 // Rewrap these base class methods since there are overloads in this subclass
105 cls.def("contains",
106 (bool (Box::*)(UnitVector3d const &) const) & Box::contains);
107 cls.def("contains", py::vectorize((bool (Box::*)(double, double, double) const)&Box::contains),
108 "x"_a, "y"_a, "z"_a);
109 cls.def("contains", py::vectorize((bool (Box::*)(double, double) const)&Box::contains),
110 "lon"_a, "lat"_a);
111 cls.def("isDisjointFrom",
112 (bool (Box::*)(LonLat const &) const) & Box::isDisjointFrom);
113 cls.def("isDisjointFrom",
114 (bool (Box::*)(Box const &) const) & Box::isDisjointFrom);
115 cls.def("intersects",
116 (bool (Box::*)(LonLat const &) const) & Box::intersects);
117 cls.def("intersects", (bool (Box::*)(Box const &) const) & Box::intersects);
118 cls.def("isWithin", (bool (Box::*)(LonLat const &) const) & Box::isWithin);
119 cls.def("isWithin", (bool (Box::*)(Box const &) const) & Box::isWithin);
120 cls.def("clipTo", (Box & (Box::*)(LonLat const &)) & Box::clipTo);
121 cls.def("clipTo", (Box & (Box::*)(Box const &)) & Box::clipTo);
122 cls.def("clippedTo", (Box(Box::*)(LonLat const &) const) & Box::clippedTo);
123 cls.def("clippedTo", (Box(Box::*)(Box const &) const) & Box::clippedTo);
124 cls.def("expandTo", (Box & (Box::*)(LonLat const &)) & Box::expandTo);
125 cls.def("expandTo", (Box & (Box::*)(Box const &)) & Box::expandTo);
126 cls.def("expandedTo",
127 (Box(Box::*)(LonLat const &) const) & Box::expandedTo);
128 cls.def("expandedTo", (Box(Box::*)(Box const &) const) & Box::expandedTo);
129 cls.def("dilateBy", (Box & (Box::*)(Angle)) & Box::dilateBy, "angle"_a);
130 cls.def("dilateBy", (Box & (Box::*)(Angle, Angle)) & Box::dilateBy,
131 "width"_a, "height"_a);
132 cls.def("dilatedBy", (Box(Box::*)(Angle) const) & Box::dilatedBy,
133 "angle"_a);
134 cls.def("dilatedBy", (Box(Box::*)(Angle, Angle) const) & Box::dilatedBy,
135 "width"_a, "height"_a);
136 cls.def("erodeBy", (Box & (Box::*)(Angle)) & Box::erodeBy, "angle"_a);
137 cls.def("erodeBy", (Box & (Box::*)(Angle, Angle)) & Box::erodeBy, "width"_a,
138 "height"_a);
139 cls.def("erodedBy", (Box(Box::*)(Angle) const) & Box::erodedBy, "angle"_a);
140 cls.def("erodedBy", (Box(Box::*)(Angle, Angle) const) & Box::erodedBy,
141 "width"_a, "height"_a);
142 cls.def("getArea", &Box::getArea);
143 cls.def("relate",
144 (Relationship(Box::*)(LonLat const &) const) & Box::relate,
145 "point"_a);
146 // Rewrap this base class method since there are overloads in this subclass
147 cls.def("relate",
148 (Relationship(Box::*)(Region const &) const) & Box::relate,
149 "region"_a);
150
151 // Note that the Region interface has already been wrapped.
152
153 cls.def("__str__", [](Box const &self) {
154 return py::str("Box({!s}, {!s})").format(self.getLon(), self.getLat());
155 });
156 cls.def("__repr__", [](Box const &self) {
157 return py::str("Box({!r}, {!r})").format(self.getLon(), self.getLat());
158 });
159 cls.def(py::pickle(&python::encode, &python::decode<Box>));
160}
Box represents a rectangle in spherical coordinate space that contains its boundary.
Definition Box.h:62
AngleInterval const & getLat() const
getLat returns the latitude interval of this box.
Definition Box.h:156
NormalizedAngleInterval const & getLon() const
getLon returns the longitude interval of this box.
Definition Box.h:153
LonLat represents a spherical coordinate (longitude/latitude angle) pair.
Definition LonLat.h:55
Region is a minimal interface for 2-dimensional regions on the unit sphere.
Definition Region.h:89
UnitVector3d is a unit vector in ℝ³ with components stored in double precision.

◆ defineClass() [4/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Box3d, std::shared_ptr< Box3d > > & cls)

Definition at line 45 of file _box3d.cc.

45 {
46 cls.def_static("empty", &Box3d::empty);
47 cls.def_static("full", &Box3d::full);
48 cls.def_static("aroundUnitSphere", &Box3d::aroundUnitSphere);
49
50 cls.def(py::init<>());
51 cls.def(py::init<Vector3d const &>(), "vector"_a);
52 cls.def(py::init<Vector3d const &, Vector3d const &>(), "vector1"_a,
53 "vector2"_a);
54 cls.def(py::init<Vector3d const &, double, double, double>(), "center"_a,
55 "halfWidth"_a, "halfHeight"_a, "halfDepth"_a);
56 cls.def(py::init<Interval1d const &, Interval1d const &,
57 Interval1d const &>(),
58 "x"_a, "y"_a, "z"_a);
59 cls.def(py::init<Box3d const &>(), "box3d"_a);
60
61 cls.def("__eq__",
62 (bool (Box3d::*)(Box3d const &) const) & Box3d::operator==,
63 py::is_operator());
64 cls.def("__eq__",
65 (bool (Box3d::*)(Vector3d const &) const) & Box3d::operator==,
66 py::is_operator());
67 cls.def("__ne__",
68 (bool (Box3d::*)(Box3d const &) const) & Box3d::operator!=,
69 py::is_operator());
70 cls.def("__ne__",
71 (bool (Box3d::*)(Vector3d const &) const) & Box3d::operator!=,
72 py::is_operator());
73 cls.def("__contains__",
74 (bool (Box3d::*)(Vector3d const &) const) & Box3d::contains,
75 py::is_operator());
76 cls.def("__contains__",
77 (bool (Box3d::*)(Box3d const &) const) & Box3d::contains,
78 py::is_operator());
79 cls.def("__len__", [](Box3d const &self) { return py::int_(3); });
80 cls.def("__getitem__", [](Box3d const &self, py::int_ row) {
81 return self(static_cast<int>(python::convertIndex(3, row)));
82 });
83
84 cls.def("x", &Box3d::x);
85 cls.def("y", &Box3d::y);
86 cls.def("z", &Box3d::z);
87 cls.def("isEmpty", &Box3d::isEmpty);
88 cls.def("isFull", &Box3d::isFull);
89 cls.def("getCenter", &Box3d::getCenter);
90 cls.def("getWidth", &Box3d::getWidth);
91 cls.def("getHeight", &Box3d::getHeight);
92 cls.def("getDepth", &Box3d::getDepth);
93
94 cls.def("contains",
95 (bool (Box3d::*)(Vector3d const &) const) & Box3d::contains);
96 cls.def("contains",
97 (bool (Box3d::*)(Box3d const &) const) & Box3d::contains);
98 cls.def("contains", py::vectorize((bool (Box3d::*)(double, double, double) const)&Box3d::contains),
99 "x"_a, "y"_a, "z"_a);
100 cls.def("isDisjointFrom",
101 (bool (Box3d::*)(Vector3d const &) const) & Box3d::isDisjointFrom);
102 cls.def("isDisjointFrom",
103 (bool (Box3d::*)(Box3d const &) const) & Box3d::isDisjointFrom);
104 cls.def("intersects",
105 (bool (Box3d::*)(Vector3d const &) const) & Box3d::intersects);
106 cls.def("intersects",
107 (bool (Box3d::*)(Box3d const &) const) & Box3d::intersects);
108 cls.def("isWithin",
109 (bool (Box3d::*)(Vector3d const &) const) & Box3d::isWithin);
110 cls.def("isWithin",
111 (bool (Box3d::*)(Box3d const &) const) & Box3d::isWithin);
112
113 cls.def("clipTo", (Box3d & (Box3d::*)(Vector3d const &)) & Box3d::clipTo);
114 cls.def("clipTo", (Box3d & (Box3d::*)(Box3d const &)) & Box3d::clipTo);
115 cls.def("clippedTo",
116 (Box3d(Box3d::*)(Vector3d const &) const) & Box3d::clippedTo);
117 cls.def("clippedTo",
118 (Box3d(Box3d::*)(Box3d const &) const) & Box3d::clippedTo);
119 cls.def("expandTo",
120 (Box3d & (Box3d::*)(Vector3d const &)) & Box3d::expandTo);
121 cls.def("expandTo", (Box3d & (Box3d::*)(Box3d const &)) & Box3d::expandTo);
122 cls.def("expandedTo",
123 (Box3d(Box3d::*)(Vector3d const &) const) & Box3d::expandedTo);
124 cls.def("expandedTo",
125 (Box3d(Box3d::*)(Box3d const &) const) & Box3d::expandedTo);
126
127 cls.def("dilateBy", (Box3d & (Box3d::*)(double)) & Box3d::dilateBy,
128 "radius"_a);
129 cls.def("dilateBy",
130 (Box3d & (Box3d::*)(double, double, double)) & Box3d::dilateBy,
131 "width"_a, "height"_a, "depth"_a);
132 cls.def("dilatedBy", (Box3d(Box3d::*)(double) const) & Box3d::dilatedBy,
133 "radius"_a);
134 cls.def("dilatedBy",
135 (Box3d(Box3d::*)(double, double, double) const) & Box3d::dilatedBy,
136 "width"_a, "height"_a, "depth"_a);
137 cls.def("erodeBy", (Box3d & (Box3d::*)(double)) & Box3d::erodeBy,
138 "radius"_a);
139 cls.def("erodeBy",
140 (Box3d & (Box3d::*)(double, double, double)) & Box3d::erodeBy,
141 "width"_a, "height"_a, "depth"_a);
142 cls.def("erodedBy", (Box3d(Box3d::*)(double) const) & Box3d::erodedBy,
143 "radius"_a);
144 cls.def("erodedBy",
145 (Box3d(Box3d::*)(double, double, double) const) & Box3d::erodedBy,
146 "width"_a, "height"_a, "depth"_a);
147
148 cls.def("relate",
149 (Relationship(Box3d::*)(Vector3d const &) const) & Box3d::relate);
150 cls.def("relate",
151 (Relationship(Box3d::*)(Box3d const &) const) & Box3d::relate);
152
153 cls.def("__str__", [](Box3d const &self) {
154 return py::str("[{!s},\n"
155 " {!s},\n"
156 " {!s}]")
157 .format(self.x(), self.y(), self.z());
158 });
159 cls.def("__repr__", [](Box3d const &self) {
160 return py::str("Box3d({!r},\n"
161 " {!r},\n"
162 " {!r})")
163 .format(self.x(), self.y(), self.z());
164 });
165 cls.def("__reduce__", [cls](Box3d const &self) {
166 return py::make_tuple(cls,
167 py::make_tuple(self.x(), self.y(), self.z()));
168 });
169}
Box3d represents a box in ℝ³.
Definition Box3d.h:49
Interval1d represents closed intervals of ℝ.
Definition Interval1d.h:47
Vector3d is a vector in ℝ³ with components stored in double precision.
Definition Vector3d.h:51
int row
Definition CR.cc:145

◆ defineClass() [5/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Chunker, std::shared_ptr< Chunker > > & cls)

Definition at line 50 of file _chunker.cc.

50 {
51 cls.def(py::init<int32_t, int32_t>(), "numStripes"_a,
52 "numSubStripesPerStripe"_a);
53
54 cls.def("__eq__", &Chunker::operator==, py::is_operator());
55 cls.def("__ne__", &Chunker::operator!=, py::is_operator());
56
57 cls.def_property_readonly("numStripes", &Chunker::getNumStripes);
58 cls.def_property_readonly("numSubStripesPerStripe",
59 &Chunker::getNumSubStripesPerStripe);
60
61 cls.def("getChunksIntersecting", &Chunker::getChunksIntersecting,
62 "region"_a);
63 cls.def("getSubChunksIntersecting",
64 [](Chunker const &self, Region const &region) {
65 py::list results;
66 for (auto const &sc : self.getSubChunksIntersecting(region)) {
67 results.append(py::make_tuple(sc.chunkId, sc.subChunkIds));
68 }
69 return results;
70 },
71 "region"_a);
72 cls.def("getAllChunks", &Chunker::getAllChunks);
73 cls.def("getAllSubChunks", &Chunker::getAllSubChunks, "chunkId"_a);
74
75 cls.def("getChunkBoundingBox", &Chunker::getChunkBoundingBox, "stripe"_a, "chunk"_a);
76 cls.def("getSubChunkBoundingBox", &Chunker::getSubChunkBoundingBox, "subStripe"_a, "subChunk"_a);
77
78 cls.def("getStripe", &Chunker::getStripe, "chunkId"_a);
79 cls.def("getChunk", &Chunker::getChunk, "chunkId"_a, "stripe"_a);
80
81
82 cls.def("__str__", &toString);
83 cls.def("__repr__", &toString);
84
85 cls.def("__reduce__", [cls](Chunker const &self) {
86 return py::make_tuple(cls,
87 py::make_tuple(self.getNumStripes(),
88 self.getNumSubStripesPerStripe()));
89 });
90}
Chunker subdivides the unit sphere into longitude-latitude boxes.
Definition Chunker.h:73

◆ defineClass() [6/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Circle, std::unique_ptr< Circle >, Region > & cls)

Definition at line 51 of file _circle.cc.

51 {
52 cls.attr("TYPE_CODE") = py::int_(Circle::TYPE_CODE);
53
54 cls.def_static("empty", &Circle::empty);
55 cls.def_static("full", &Circle::full);
56 cls.def_static("squaredChordLengthFor", &Circle::squaredChordLengthFor,
57 "openingAngle"_a);
58 cls.def_static("openingAngleFor", &Circle::openingAngleFor,
59 "squaredChordLength"_a);
60
61 cls.def(py::init<>());
62 cls.def(py::init<UnitVector3d const &>(), "center"_a);
63 cls.def(py::init<UnitVector3d const &, Angle>(), "center"_a, "angle"_a);
64 cls.def(py::init<UnitVector3d const &, double>(), "center"_a,
65 "squaredChordLength"_a);
66 cls.def(py::init<Circle const &>(), "circle"_a);
67
68 cls.def("__eq__", &Circle::operator==, py::is_operator());
69 cls.def("__ne__", &Circle::operator!=, py::is_operator());
70 cls.def("__contains__",
71 (bool (Circle::*)(Circle const &) const) & Circle::contains,
72 py::is_operator());
73 // Rewrap this base class method since there are overloads in this subclass
74 cls.def("__contains__",
75 (bool (Circle::*)(UnitVector3d const &) const) & Circle::contains,
76 py::is_operator());
77
78 cls.def("isFull", &Circle::isFull);
79 cls.def("getCenter", &Circle::getCenter);
80 cls.def("getSquaredChordLength", &Circle::getSquaredChordLength);
81 cls.def("getOpeningAngle", &Circle::getOpeningAngle);
82 cls.def("contains",
83 (bool (Circle::*)(Circle const &) const) & Circle::contains);
84 // Rewrap these base class methods since there are overloads in this subclass
85 cls.def("contains",
86 (bool (Circle::*)(UnitVector3d const &) const) & Circle::contains);
87 cls.def("contains", py::vectorize((bool (Circle::*)(double, double, double) const)&Circle::contains),
88 "x"_a, "y"_a, "z"_a);
89 cls.def("contains", py::vectorize((bool (Circle::*)(double, double) const)&Circle::contains),
90 "lon"_a, "lat"_a);
91
92 cls.def("isDisjointFrom",
93 (bool (Circle::*)(UnitVector3d const &) const) &
94 Circle::isDisjointFrom);
95 cls.def("isDisjointFrom",
96 (bool (Circle::*)(Circle const &) const) & Circle::isDisjointFrom);
97 cls.def("intersects",
98 (bool (Circle::*)(UnitVector3d const &) const) &
99 Circle::intersects);
100 cls.def("intersects",
101 (bool (Circle::*)(Circle const &) const) & Circle::intersects);
102 cls.def("isWithin",
103 (bool (Circle::*)(UnitVector3d const &) const) & Circle::isWithin);
104 cls.def("isWithin",
105 (bool (Circle::*)(Circle const &) const) & Circle::isWithin);
106 cls.def("clipTo",
107 (Circle & (Circle::*)(UnitVector3d const &)) & Circle::clipTo);
108 cls.def("clipTo", (Circle & (Circle::*)(Circle const &)) & Circle::clipTo);
109 cls.def("clippedTo",
110 (Circle(Circle::*)(UnitVector3d const &) const) &
111 Circle::clippedTo);
112 cls.def("clippedTo",
113 (Circle(Circle::*)(Circle const &) const) & Circle::clippedTo);
114 cls.def("expandTo",
115 (Circle & (Circle::*)(UnitVector3d const &)) & Circle::expandTo);
116 cls.def("expandTo",
117 (Circle & (Circle::*)(Circle const &)) & Circle::expandTo);
118 cls.def("expandedTo",
119 (Circle(Circle::*)(UnitVector3d const &) const) &
120 Circle::expandedTo);
121 cls.def("expandedTo",
122 (Circle(Circle::*)(Circle const &) const) & Circle::expandedTo);
123 cls.def("dilateBy", &Circle::dilateBy, "radius"_a);
124 cls.def("dilatedBy", &Circle::dilatedBy, "radius"_a);
125 cls.def("erodeBy", &Circle::erodeBy, "radius"_a);
126 cls.def("erodedBy", &Circle::erodedBy, "radius"_a);
127 cls.def("getArea", &Circle::getArea);
128 cls.def("complement", &Circle::complement);
129 cls.def("complemented", &Circle::complemented);
130
131 // Note that the Region interface has already been wrapped.
132
133 cls.def("__str__", [](Circle const &self) {
134 return py::str("Circle({!s}, {!s})")
135 .format(self.getCenter(), self.getOpeningAngle());
136 });
137 cls.def("__repr__", [](Circle const &self) {
138 return py::str("Circle({!r}, {!r})")
139 .format(self.getCenter(), self.getOpeningAngle());
140 });
141 cls.def(py::pickle(&python::encode, &python::decode<Circle>));
142}
Circle is a circular region on the unit sphere that contains its boundary.
Definition Circle.h:54
Angle getOpeningAngle() const
getOpeningAngle returns the opening angle of this circle - that is, the angle between its center vect...
Definition Circle.h:136
UnitVector3d const & getCenter() const
getCenter returns the center of this circle as a unit vector.
Definition Circle.h:126

◆ defineClass() [7/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< CompoundRegion, std::unique_ptr< CompoundRegion >, Region > & cls)

Definition at line 94 of file _compoundRegion.cc.

94 {
95 cls.def("nOperands", &CompoundRegion::nOperands);
96 cls.def("__len__", &CompoundRegion::nOperands);
97 cls.def(
98 "__iter__",
99 [](CompoundRegion const& region) {
100 return py::make_iterator(
101 CompoundIterator(region, 0U), CompoundIterator(region, region.nOperands())
102 );
103 },
104 py::return_value_policy::reference_internal // Keeps region alive while iterator is in use.
105 );
106 cls.def(
107 "cloneOperand",
108 [](CompoundRegion const &self, std::ptrdiff_t n) {
109 int nOperands = self.nOperands();
110 return self.getOperand(python::convertIndex(nOperands, n)).clone();
111 }
112 );
113}
CompoundRegion is an intermediate base class for spherical regions that are comprised of a point-set ...

◆ defineClass() [8/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< ConvexPolygon, std::unique_ptr< ConvexPolygon >, Region > & cls)

Definition at line 52 of file _convexPolygon.cc.

53 {
54 cls.attr("TYPE_CODE") = py::int_(ConvexPolygon::TYPE_CODE);
55
56 cls.def_static("convexHull", &ConvexPolygon::convexHull, "points"_a);
57
58 cls.def(py::init<std::vector<UnitVector3d> const &>(), "points"_a);
59 // Do not wrap the two unsafe (3 and 4 vertex) constructors
60 cls.def(py::init<ConvexPolygon const &>(), "convexPolygon"_a);
61
62 cls.def("__eq__", &ConvexPolygon::operator==, py::is_operator());
63 cls.def("__ne__", &ConvexPolygon::operator!=, py::is_operator());
64
65 cls.def("getVertices", &ConvexPolygon::getVertices);
66 cls.def("getCentroid", &ConvexPolygon::getCentroid);
67
68 // Note that much of the Region interface has already been wrapped. Here are bits that have not:
69 // (include overloads from Region that would otherwise be shadowed).
70 cls.def("contains", py::overload_cast<UnitVector3d const &>(&ConvexPolygon::contains, py::const_));
71 cls.def("contains", py::overload_cast<Region const &>(&ConvexPolygon::contains, py::const_));
72 cls.def("contains",
73 py::vectorize((bool (ConvexPolygon::*)(double, double, double) const)&ConvexPolygon::contains),
74 "x"_a, "y"_a, "z"_a);
75 cls.def("contains",
76 py::vectorize((bool (ConvexPolygon::*)(double, double) const)&ConvexPolygon::contains),
77 "lon"_a, "lat"_a);
78 cls.def("isDisjointFrom", &ConvexPolygon::isDisjointFrom);
79 cls.def("intersects", &ConvexPolygon::intersects);
80 cls.def("isWithin", &ConvexPolygon::isWithin);
81
82 cls.def("__repr__", [](ConvexPolygon const &self) {
83 return py::str("ConvexPolygon({!r})").format(self.getVertices());
84 });
85 cls.def(py::pickle(&python::encode, &python::decode<ConvexPolygon>));
86}
ConvexPolygon is a closed convex polygon on the unit sphere.
std::vector< UnitVector3d > const & getVertices() const

◆ defineClass() [9/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Ellipse, std::unique_ptr< Ellipse >, Region > & cls)

Definition at line 51 of file _ellipse.cc.

51 {
52 cls.attr("TYPE_CODE") = py::int_(Ellipse::TYPE_CODE);
53
54 cls.def_static("empty", &Ellipse::empty);
55 cls.def_static("full", &Ellipse::full);
56
57 cls.def(py::init<>());
58 cls.def(py::init<Circle const &>(), "circle"_a);
59 cls.def(py::init<UnitVector3d const &, Angle>(), "center"_a,
60 "angle"_a = Angle(0.0));
61 cls.def(py::init<UnitVector3d const &, UnitVector3d const &, Angle>(),
62 "focus1"_a, "focus2"_a, "alpha"_a);
63 cls.def(py::init<UnitVector3d const &, Angle, Angle, Angle>(), "center"_a,
64 "alpha"_a, "beta"_a, "orientation"_a);
65 cls.def(py::init<Ellipse const &>(), "ellipse"_a);
66
67 cls.def("__eq__", &Ellipse::operator==, py::is_operator());
68 cls.def("__ne__", &Ellipse::operator!=, py::is_operator());
69
70 cls.def("isFull", &Ellipse::isFull);
71 cls.def("isGreatCircle", &Ellipse::isGreatCircle);
72 cls.def("isCircle", &Ellipse::isCircle);
73 cls.def("getTransformMatrix", &Ellipse::getTransformMatrix);
74 cls.def("getCenter", &Ellipse::getCenter);
75 cls.def("getF1", &Ellipse::getF1);
76 cls.def("getF2", &Ellipse::getF2);
77 cls.def("getAlpha", &Ellipse::getAlpha);
78 cls.def("getBeta", &Ellipse::getBeta);
79 cls.def("getGamma", &Ellipse::getGamma);
80 cls.def("complement", &Ellipse::complement);
81 cls.def("complemented", &Ellipse::complemented);
82
83 // Note that the Region interface has already been wrapped.
84
85 cls.def("__str__", [](Ellipse const &self) {
86 return py::str("Ellipse({!s}, {!s}, {!s})")
87 .format(self.getF1(), self.getF2(), self.getAlpha());
88 });
89 cls.def("__repr__", [](Ellipse const &self) {
90 return py::str("Ellipse({!r}, {!r}, {!r})")
91 .format(self.getF1(), self.getF2(), self.getAlpha());
92 });
93 cls.def(py::pickle(&python::encode, &python::decode<Ellipse>));
94}
Ellipse is an elliptical region on the sphere.
Definition Ellipse.h:177
Angle getAlpha() const
getAlpha returns α, the first semi-axis length of the ellipse.
Definition Ellipse.h:259
UnitVector3d getF2() const
getF2 returns the second focal point of the ellipse.
Definition Ellipse.h:251
UnitVector3d getF1() const
getF1 returns the first focal point of the ellipse.
Definition Ellipse.h:245

◆ defineClass() [10/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< HtmPixelization, Pixelization > & cls)

Definition at line 42 of file _htmPixelization.cc.

42 {
43 cls.attr("MAX_LEVEL") = py::int_(HtmPixelization::MAX_LEVEL);
44
45 cls.def_static("level", &HtmPixelization::level, "i"_a);
46 cls.def_static("triangle", &HtmPixelization::triangle, "i"_a);
47 cls.def_static("asString", &HtmPixelization::asString, "i"_a);
48
49 cls.def(py::init<int>(), "level"_a);
50 cls.def(py::init<HtmPixelization const &>(), "htmPixelization"_a);
51
52 cls.def("getLevel", &HtmPixelization::getLevel);
53
54 cls.def("__eq__",
55 [](HtmPixelization const &self, HtmPixelization const &other) {
56 return self.getLevel() == other.getLevel();
57 });
58 cls.def("__ne__",
59 [](HtmPixelization const &self, HtmPixelization const &other) {
60 return self.getLevel() != other.getLevel();
61 });
62 cls.def("__repr__", [](HtmPixelization const &self) {
63 return py::str("HtmPixelization({!s})").format(self.getLevel());
64 });
65 cls.def("__reduce__", [cls](HtmPixelization const &self) {
66 return py::make_tuple(cls, py::make_tuple(self.getLevel()));
67 });
68}
HtmPixelization provides HTM indexing of points and regions.
int getLevel() const
getLevel returns the subdivision level of this pixelization.

◆ defineClass() [11/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< IntersectionRegion, std::unique_ptr< IntersectionRegion >, CompoundRegion > & cls)

Definition at line 124 of file _compoundRegion.cc.

124 {
125 cls.attr("TYPE_CODE") = py::int_(IntersectionRegion::TYPE_CODE);
126 cls.def(py::init(&_args_factory<IntersectionRegion>));
127 cls.def(py::pickle(&python::encode, &python::decode<IntersectionRegion>));
128 cls.def("__repr__", [](CompoundRegion const &self) { return _repr("IntersectionRegion", self); });
129}

◆ defineClass() [12/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Interval1d, std::shared_ptr< Interval1d > > & cls)

Definition at line 43 of file _interval1d.cc.

43 {
44 python::defineInterval<decltype(cls), Interval1d, double>(cls);
45
46 cls.def_static("empty", &Interval1d::empty);
47 cls.def_static("full", &Interval1d::full);
48
49 cls.def(py::init<>());
50 cls.def(py::init<double>(), "x"_a);
51 cls.def(py::init<double, double>(), "x"_a, "y"_a);
52 cls.def(py::init<Interval1d const &>(), "interval"_a);
53
54 cls.def("isFull", &Interval1d::isFull);
55
56 cls.def("__str__", [](Interval1d const &self) {
57 return py::str("[{!s}, {!s}]").format(self.getA(), self.getB());
58 });
59 cls.def("__repr__", [](Interval1d const &self) {
60 return py::str("Interval1d({!r}, {!r})")
61 .format(self.getA(), self.getB());
62 });
63}

◆ defineClass() [13/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< LonLat, std::shared_ptr< LonLat > > & cls)

Definition at line 43 of file _lonLat.cc.

43 {
44 cls.def_static("fromDegrees", &LonLat::fromDegrees);
45 cls.def_static("fromRadians", &LonLat::fromRadians);
46 cls.def_static("latitudeOf", &LonLat::latitudeOf);
47 cls.def_static("longitudeOf", &LonLat::longitudeOf);
48
49 cls.def(py::init<>());
50 cls.def(py::init<LonLat const &>());
51 cls.def(py::init<NormalizedAngle, Angle>(), "lon"_a, "lat"_a);
52 cls.def(py::init<Vector3d const &>(), "vector"_a);
53
54 cls.def("__eq__", &LonLat::operator==, py::is_operator());
55 cls.def("__nq__", &LonLat::operator!=, py::is_operator());
56
57 cls.def("getLon", &LonLat::getLon);
58 cls.def("getLat", &LonLat::getLat);
59
60 cls.def("__len__", [](LonLat const &self) { return py::int_(2); });
61 cls.def("__getitem__", [](LonLat const &self, py::object key) {
62 auto t = py::make_tuple(self.getLon(), self.getLat());
63 return t.attr("__getitem__")(key);
64 });
65 cls.def("__iter__", [](LonLat const &self) {
66 auto t = py::make_tuple(self.getLon(), self.getLat());
67 return t.attr("__iter__")();
68 });
69
70 cls.def("__str__", [](LonLat const &self) {
71 return py::str("[{!s}, {!s}]")
72 .format(self.getLon().asRadians(), self.getLat().asRadians());
73 });
74 cls.def("__repr__", [](LonLat const &self) {
75 return py::str("LonLat.fromRadians({!r}, {!r})")
76 .format(self.getLon().asRadians(), self.getLat().asRadians());
77 });
78 cls.def("__reduce__", [cls](LonLat const &self) {
79 return py::make_tuple(cls,
80 py::make_tuple(self.getLon(), self.getLat()));
81 });
82}

◆ defineClass() [14/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Matrix3d, std::shared_ptr< Matrix3d > > & cls)

Definition at line 49 of file _matrix3d.cc.

49 {
50 cls.def(py::init<>());
51 cls.def(py::init<double, double, double, double, double, double, double,
52 double, double>(),
53 "m00"_a, "m01"_a, "m02"_a, "m10"_a, "m11"_a, "m12"_a, "m20"_a,
54 "m21"_a, "m22"_a);
55 cls.def(py::init<Vector3d const &>(), "diagonal"_a);
56 cls.def(py::init<double>(), "scale"_a);
57 cls.def(py::init<Matrix3d const &>(), "matrix"_a);
58
59 cls.def("__eq__", &Matrix3d::operator==, py::is_operator());
60 cls.def("__ne__", &Matrix3d::operator!=, py::is_operator());
61
62 // Add bounds checking to getRow and getColumn
63 cls.def("getRow", &getRow, "row"_a);
64 cls.def("getColumn",
65 [](Matrix3d const &self, py::int_ col) {
66 return self.getColumn(
67 static_cast<int>(python::convertIndex(3, col)));
68 },
69 "col"_a);
70
71 cls.def("__len__", [](Matrix3d const &self) { return py::int_(3); });
72 cls.def("__getitem__", &getRow, py::is_operator());
73 cls.def("__getitem__",
74 [](Matrix3d const &self, py::tuple t) {
75 if (t.size() > 2) {
76 throw py::index_error("Too many indexes for Matrix3d");
77 } else if (t.size() == 0) {
78 return py::cast(self);
79 } else if (t.size() == 1) {
80 return py::cast(getRow(self, t[0].cast<py::int_>()));
81 }
82 return py::cast(
83 self(python::convertIndex(3, t[0].cast<py::int_>()),
84 python::convertIndex(3, t[1].cast<py::int_>())));
85 },
86 py::is_operator());
87
88 cls.def("inner", &Matrix3d::inner, "matrix"_a);
89 cls.def("getSquaredNorm", &Matrix3d::getSquaredNorm);
90 cls.def("getNorm", &Matrix3d::getNorm);
91
92 cls.def("__mul__",
93 (Vector3d(Matrix3d::*)(Vector3d const &) const) &
94 Matrix3d::operator*,
95 "vector"_a, py::is_operator());
96 cls.def("__mul__",
97 (Matrix3d(Matrix3d::*)(Matrix3d const &) const) &
98 Matrix3d::operator*,
99 "matrix"_a, py::is_operator());
100 cls.def("__add__", &Matrix3d::operator+, py::is_operator());
101 cls.def("__sub__", &Matrix3d::operator-, py::is_operator());
102
103 cls.def("cwiseProduct", &Matrix3d::cwiseProduct);
104 cls.def("transpose", &Matrix3d::transpose);
105 cls.def("inverse", &Matrix3d::inverse);
106
107 cls.def("__str__", [](Matrix3d const &self) {
108 return py::str("[[{!s}, {!s}, {!s}],\n"
109 " [{!s}, {!s}, {!s}],\n"
110 " [{!s}, {!s}, {!s}]]")
111 .format(self(0, 0), self(0, 1), self(0, 2), self(1, 0),
112 self(1, 1), self(1, 2), self(2, 0), self(2, 1),
113 self(2, 2));
114 });
115 cls.def("__repr__", [](Matrix3d const &self) {
116 return py::str("Matrix3d({!r}, {!r}, {!r},\n"
117 " {!r}, {!r}, {!r},\n"
118 " {!r}, {!r}, {!r})")
119 .format(self(0, 0), self(0, 1), self(0, 2), self(1, 0),
120 self(1, 1), self(1, 2), self(2, 0), self(2, 1),
121 self(2, 2));
122 });
123 cls.def("__reduce__", [cls](Matrix3d const &self) {
124 auto args = py::make_tuple(self(0, 0), self(0, 1), self(0, 2),
125 self(1, 0), self(1, 1), self(1, 2),
126 self(2, 0), self(2, 1), self(2, 2));
127 return py::make_tuple(cls, args);
128 });
129}
A 3x3 matrix with real entries stored in double precision.
Definition Matrix3d.h:45
Vector3d const & getColumn(int c) const
getColumn returns the c-th matrix column. Bounds are not checked.
Definition Matrix3d.h:94
int col
Definition CR.cc:144

◆ defineClass() [15/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Mq3cPixelization, Pixelization > & cls)

Definition at line 42 of file _mq3cPixelization.cc.

42 {
43 cls.attr("MAX_LEVEL") = py::int_(Mq3cPixelization::MAX_LEVEL);
44
45 cls.def_static("level", &Mq3cPixelization::level);
46 cls.def_static("quad", &Mq3cPixelization::quad);
47 cls.def_static("neighborhood", &Mq3cPixelization::neighborhood);
48 cls.def_static("asString", &Mq3cPixelization::asString);
49
50 cls.def(py::init<int>(), "level"_a);
51 cls.def(py::init<Mq3cPixelization const &>(), "mq3cPixelization"_a);
52
53 cls.def("getLevel", &Mq3cPixelization::getLevel);
54
55 cls.def("__eq__",
56 [](Mq3cPixelization const &self, Mq3cPixelization const &other) {
57 return self.getLevel() == other.getLevel();
58 });
59 cls.def("__ne__",
60 [](Mq3cPixelization const &self, Mq3cPixelization const &other) {
61 return self.getLevel() != other.getLevel();
62 });
63 cls.def("__repr__", [](Mq3cPixelization const &self) {
64 return py::str("Mq3cPixelization({!s})").format(self.getLevel());
65 });
66 cls.def("__reduce__", [cls](Mq3cPixelization const &self) {
67 return py::make_tuple(cls, py::make_tuple(self.getLevel()));
68 });
69}
Mq3cPixelization provides modified Q3C indexing of points and regions.
int getLevel() const
getLevel returns the subdivision level of this pixelization.

◆ defineClass() [16/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< NormalizedAngle > & cls)

Definition at line 44 of file _normalizedAngle.cc.

44 {
45 // Provide the equivalent of the NormalizedAngle to Angle C++ cast
46 // operator in Python
47 py::implicitly_convertible<NormalizedAngle, Angle>();
48
49 cls.def_static("nan", &NormalizedAngle::nan);
50 cls.def_static("fromDegrees", &NormalizedAngle::fromDegrees);
51 cls.def_static("fromRadians", &NormalizedAngle::fromRadians);
52 cls.def_static("between", &NormalizedAngle::between, "a"_a, "b"_a);
53 cls.def_static("center", &NormalizedAngle::center, "a"_a, "b"_a);
54
55 cls.def(py::init<>());
56 cls.def(py::init<NormalizedAngle const &>());
57 cls.def(py::init<Angle const &>());
58 cls.def(py::init<double>(), "radians"_a);
59 cls.def(py::init<LonLat const &, LonLat const &>(), "a"_a, "b"_a);
60 cls.def(py::init<Vector3d const &, Vector3d const &>(), "a"_a, "b"_a);
61
62 cls.def("__eq__", &NormalizedAngle::operator==, py::is_operator());
63 cls.def("__ne__", &NormalizedAngle::operator!=, py::is_operator());
64 cls.def("__lt__", &NormalizedAngle::operator<, py::is_operator());
65 cls.def("__gt__", &NormalizedAngle::operator>, py::is_operator());
66 cls.def("__le__", &NormalizedAngle::operator<=, py::is_operator());
67 cls.def("__ge__", &NormalizedAngle::operator>=, py::is_operator());
68
69 cls.def("__neg__",
70 (Angle(NormalizedAngle::*)() const) & NormalizedAngle::operator-);
71 cls.def("__add__", &NormalizedAngle::operator+, py::is_operator());
72 cls.def("__sub__",
73 (Angle(NormalizedAngle::*)(Angle const &) const) &
74 NormalizedAngle::operator-,
75 py::is_operator());
76 cls.def("__mul__", &NormalizedAngle::operator*, py::is_operator());
77 cls.def("__rmul__", &NormalizedAngle::operator*, py::is_operator());
78 cls.def("__truediv__",
79 (Angle(NormalizedAngle::*)(double) const) &
80 NormalizedAngle::operator/,
81 py::is_operator());
82 cls.def("__truediv__",
83 (double (NormalizedAngle::*)(Angle const &) const) &
84 NormalizedAngle::operator/,
85 py::is_operator());
86
87 cls.def("asDegrees", &NormalizedAngle::asDegrees);
88 cls.def("asRadians", &NormalizedAngle::asRadians);
89 cls.def("isNan", &NormalizedAngle::isNan);
90 cls.def("getAngleTo", &NormalizedAngle::getAngleTo);
91
92 cls.def("__str__", [](NormalizedAngle const &self) {
93 return py::str("{!s}").format(self.asRadians());
94 });
95 cls.def("__repr__", [](NormalizedAngle const &self) {
96 return py::str("NormalizedAngle({!r})").format(self.asRadians());
97 });
98
99 cls.def("__reduce__", [cls](NormalizedAngle const &self) {
100 return py::make_tuple(cls, py::make_tuple(self.asRadians()));
101 });
102}
double asRadians() const
asRadians returns the value of this angle in units of radians.

◆ defineClass() [17/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< NormalizedAngleInterval, std::shared_ptr< NormalizedAngleInterval > > & cls)

Definition at line 43 of file _normalizedAngleInterval.cc.

44 {
45 python::defineInterval<decltype(cls), NormalizedAngleInterval,
46 NormalizedAngle>(cls);
47
48 cls.def_static("fromDegrees", &NormalizedAngleInterval::fromDegrees, "x"_a,
49 "y"_a);
50 cls.def_static("fromRadians", &NormalizedAngleInterval::fromRadians, "x"_a,
51 "y"_a);
52 cls.def_static("empty", &NormalizedAngleInterval::empty);
53 cls.def_static("full", &NormalizedAngleInterval::full);
54
55 cls.def(py::init<>());
56 cls.def(py::init<Angle>(), "x"_a);
57 cls.def(py::init<NormalizedAngle>(), "x"_a);
58 cls.def(py::init<Angle, Angle>(), "x"_a, "y"_a);
59 cls.def(py::init<NormalizedAngle, NormalizedAngle>(), "x"_a, "y"_a);
60 cls.def(py::init<NormalizedAngleInterval const &>(), "angleInterval"_a);
61
62 cls.def("isEmpty", &NormalizedAngleInterval::isEmpty);
63 cls.def("isFull", &NormalizedAngleInterval::isFull);
64 cls.def("wraps", &NormalizedAngleInterval::wraps);
65
66 cls.def("__str__", [](NormalizedAngleInterval const &self) {
67 return py::str("[{!s}, {!s}]")
68 .format(self.getA().asRadians(), self.getB().asRadians());
69 });
70 cls.def("__repr__", [](NormalizedAngleInterval const &self) {
71 return py::str("NormalizedAngleInterval.fromRadians({!r},"
72 " {!r})")
73 .format(self.getA().asRadians(), self.getB().asRadians());
74 });
75}
NormalizedAngleInterval represents closed intervals of normalized angles, i.e.
NormalizedAngle getA() const
getA returns the first endpoint of this interval.
NormalizedAngle getB() const
getB returns the second endpoint of this interval.

◆ defineClass() [18/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Pixelization > & cls)

Definition at line 44 of file _pixelization.cc.

44 {
45 cls.def("universe", &Pixelization::universe);
46 cls.def("pixel", &Pixelization::pixel, "i"_a);
47 cls.def("index", &Pixelization::index, "i"_a);
48 cls.def("toString", &Pixelization::toString, "i"_a);
49 cls.def("envelope", &Pixelization::envelope, "region"_a, "maxRanges"_a = 0);
50 cls.def("interior", &Pixelization::interior, "region"_a, "maxRanges"_a = 0);
51}

◆ defineClass() [19/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Q3cPixelization, Pixelization > & cls)

Definition at line 42 of file _q3cPixelization.cc.

42 {
43 cls.attr("MAX_LEVEL") = py::int_(Q3cPixelization::MAX_LEVEL);
44
45 cls.def(py::init<int>(), "level"_a);
46 cls.def(py::init<Q3cPixelization const &>(), "q3cPixelization"_a);
47
48 cls.def("getLevel", &Q3cPixelization::getLevel);
49 cls.def("quad", &Q3cPixelization::quad);
50 cls.def("neighborhood", &Q3cPixelization::neighborhood);
51
52 cls.def("__eq__",
53 [](Q3cPixelization const &self, Q3cPixelization const &other) {
54 return self.getLevel() == other.getLevel();
55 });
56 cls.def("__ne__",
57 [](Q3cPixelization const &self, Q3cPixelization const &other) {
58 return self.getLevel() != other.getLevel();
59 });
60 cls.def("__repr__", [](Q3cPixelization const &self) {
61 return py::str("Q3cPixelization({!s})").format(self.getLevel());
62 });
63 cls.def("__reduce__", [cls](Q3cPixelization const &self) {
64 return py::make_tuple(cls, py::make_tuple(self.getLevel()));
65 });
66}
Q3cPixelization provides Q3C indexing of points and regions.
int getLevel() const
getLevel returns the subdivision level of this pixelization.

◆ defineClass() [20/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< RangeSet, std::shared_ptr< RangeSet > > & cls)

Definition at line 94 of file _rangeSet.cc.

94 {
95 cls.def(py::init<>());
96 cls.def(py::init<uint64_t>(), "integer"_a);
97 cls.def(py::init([](uint64_t a, uint64_t b) {
98 return new RangeSet(a, b);
99 }),
100 "first"_a, "last"_a);
101 cls.def(py::init<RangeSet const &>(), "rangeSet"_a);
102 cls.def(py::init(
103 [](py::iterable iterable) {
104 return new RangeSet(makeRangeSet(iterable));
105 }),
106 "iterable"_a);
107 cls.def("__eq__", &RangeSet::operator==, py::is_operator());
108 cls.def("__ne__", &RangeSet::operator!=, py::is_operator());
109
110 cls.def("insert", (void (RangeSet::*)(uint64_t)) & RangeSet::insert,
111 "integer"_a);
112 cls.def("insert",
113 (void (RangeSet::*)(uint64_t, uint64_t)) & RangeSet::insert,
114 "first"_a, "last"_a);
115 cls.def("erase", (void (RangeSet::*)(uint64_t)) & RangeSet::erase,
116 "integer"_a);
117 cls.def("erase", (void (RangeSet::*)(uint64_t, uint64_t)) & RangeSet::erase,
118 "first"_a, "last"_a);
119
120 cls.def("complement", &RangeSet::complement);
121 cls.def("complemented", &RangeSet::complemented);
122 cls.def("intersection", &RangeSet::intersection, "rangeSet"_a);
123 // In C++, the set union function is named join because union is a keyword.
124 // Python does not suffer from the same restriction.
125 cls.def("union", &RangeSet::join, "rangeSet"_a);
126 cls.def("difference", &RangeSet::difference, "rangeSet"_a);
127 cls.def("symmetricDifference", &RangeSet::symmetricDifference,
128 "rangeSet"_a);
129 cls.def("__invert__", &RangeSet::operator~, py::is_operator());
130 cls.def("__and__", &RangeSet::operator&, py::is_operator());
131 cls.def("__or__", &RangeSet::operator|, py::is_operator());
132 cls.def("__sub__", &RangeSet::operator-, py::is_operator());
133 cls.def("__xor__", &RangeSet::operator^, py::is_operator());
134 cls.def("__iand__", &RangeSet::operator&=);
135 cls.def("__ior__", &RangeSet::operator|=);
136 cls.def("__isub__", &RangeSet::operator-=);
137 cls.def("__ixor__", &RangeSet::operator^=);
138
139 cls.def("__len__", &RangeSet::size);
140 cls.def("__getitem__", [](RangeSet const &self, py::int_ i) {
141 auto j = python::convertIndex(static_cast<ptrdiff_t>(self.size()), i);
142 return py::cast(self.begin()[j]);
143 });
144
145 cls.def("intersects",
146 (bool (RangeSet::*)(uint64_t) const) & RangeSet::intersects,
147 "integer"_a);
148 cls.def("intersects",
149 (bool (RangeSet::*)(uint64_t, uint64_t) const) &
150 RangeSet::intersects,
151 "first"_a, "last"_a);
152 cls.def("intersects",
153 (bool (RangeSet::*)(RangeSet const &) const) & RangeSet::intersects,
154 "rangeSet"_a);
155
156 cls.def("contains",
157 (bool (RangeSet::*)(uint64_t) const) & RangeSet::contains,
158 "integer"_a);
159 cls.def("contains",
160 (bool (RangeSet::*)(uint64_t, uint64_t) const) & RangeSet::contains,
161 "first"_a, "last"_a);
162 cls.def("contains",
163 (bool (RangeSet::*)(RangeSet const &) const) & RangeSet::contains,
164 "rangeSet"_a);
165 cls.def("__contains__",
166 (bool (RangeSet::*)(uint64_t) const) & RangeSet::contains,
167 "integer"_a, py::is_operator());
168 cls.def("__contains__",
169 (bool (RangeSet::*)(uint64_t, uint64_t) const) & RangeSet::contains,
170 "first"_a, "last"_a, py::is_operator());
171 cls.def("__contains__",
172 (bool (RangeSet::*)(RangeSet const &) const) & RangeSet::contains,
173 "rangeSet"_a, py::is_operator());
174
175 cls.def("isWithin",
176 (bool (RangeSet::*)(uint64_t) const) & RangeSet::isWithin,
177 "integer"_a);
178 cls.def("isWithin",
179 (bool (RangeSet::*)(uint64_t, uint64_t) const) & RangeSet::isWithin,
180 "first"_a, "last"_a);
181 cls.def("isWithin",
182 (bool (RangeSet::*)(RangeSet const &) const) & RangeSet::isWithin,
183 "rangeSet"_a);
184
185 cls.def("isDisjointFrom",
186 (bool (RangeSet::*)(uint64_t) const) & RangeSet::isDisjointFrom,
187 "integer"_a);
188 cls.def("isDisjointFrom",
189 (bool (RangeSet::*)(uint64_t, uint64_t) const) &
190 RangeSet::isDisjointFrom,
191 "first"_a, "last"_a);
192 cls.def("isDisjointFrom",
193 (bool (RangeSet::*)(RangeSet const &) const) &
194 RangeSet::isDisjointFrom,
195 "rangeSet"_a);
196
197 cls.def("simplify", &RangeSet::simplify, "n"_a);
198 cls.def("simplified", &RangeSet::simplified, "n"_a);
199 cls.def("scale", &RangeSet::scale, "factor"_a);
200 cls.def("scaled", &RangeSet::scaled, "factor"_a);
201 cls.def("fill", &RangeSet::fill);
202 cls.def("clear", &RangeSet::clear);
203 cls.def("empty", &RangeSet::empty);
204 cls.def("full", &RangeSet::full);
205 cls.def("size", &RangeSet::size);
206 cls.def("cardinality", &RangeSet::cardinality);
207 // max_size() and swap() are omitted. The former is a C++ container
208 // requirement, and the latter doesn't seem relevant to Python.
209 cls.def("isValid", &RangeSet::cardinality);
210 cls.def("ranges", &ranges);
211
212 cls.def("__str__",
213 [](RangeSet const &self) { return py::str(ranges(self)); });
214 cls.def("__repr__", [](RangeSet const &self) {
215 return py::str("RangeSet({!s})").format(ranges(self));
216 });
217
218 cls.def("__reduce__", [cls](RangeSet const &self) {
219 return py::make_tuple(cls, py::make_tuple(ranges(self)));
220 });
221}
table::Key< int > b
A RangeSet is a set of unsigned 64 bit integers.
Definition RangeSet.h:106

◆ defineClass() [21/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Region, std::unique_ptr< Region > > & cls)

Definition at line 54 of file _region.cc.

54 {
55 cls.def("clone", &Region::clone);
56 cls.def("isEmpty", &Region::isEmpty);
57 cls.def("getBoundingBox", &Region::getBoundingBox);
58 cls.def("getBoundingBox3d", &Region::getBoundingBox3d);
59 cls.def("getBoundingCircle", &Region::getBoundingCircle);
60 cls.def("contains", py::overload_cast<UnitVector3d const &>(&Region::contains, py::const_),
61 "unitVector"_a);
62 cls.def("contains", py::vectorize((bool (Region::*)(double, double, double) const)&Region::contains),
63 "x"_a, "y"_a, "z"_a);
64 cls.def("contains", py::vectorize((bool (Region::*)(double, double) const)&Region::contains),
65 "lon"_a, "lat"_a);
66 cls.def("__contains__", py::overload_cast<UnitVector3d const &>(&Region::contains, py::const_),
67 py::is_operator());
68 // The per-subclass relate() overloads are used to implement
69 // double-dispatch in C++, and are not needed in Python.
70 cls.def("relate",
71 (Relationship(Region::*)(Region const &) const) & Region::relate,
72 "region"_a);
73 cls.def("overlaps",
74 (TriState(Region::*)(Region const &) const)&Region::overlaps,
75 "region"_a);
76 cls.def("encode", &python::encode);
77 cls.def_static("decode", &python::decode<Region>, "bytes"_a);
78 cls.def_static("decodeBase64", py::overload_cast<std::string_view const&>(&Region::decodeBase64),
79 "bytes"_a);
80 cls.def_static("decodeOverlapsBase64",
81 py::overload_cast<std::string_view const&>(&Region::decodeOverlapsBase64),
82 "bytes"_a);
83 cls.def_static("getRegions", Region::getRegions, "region"_a);
84}
TriState represents a boolean value with additional unknown state.
Definition TriState.h:46

◆ defineClass() [22/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< UnionRegion, std::unique_ptr< UnionRegion >, CompoundRegion > & cls)

Definition at line 116 of file _compoundRegion.cc.

116 {
117 cls.attr("TYPE_CODE") = py::int_(UnionRegion::TYPE_CODE);
118 cls.def(py::init(&_args_factory<UnionRegion>));
119 cls.def(py::pickle(&python::encode, &python::decode<UnionRegion>));
120 cls.def("__repr__", [](CompoundRegion const &self) { return _repr("UnionRegion", self); });
121}

◆ defineClass() [23/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< UnitVector3d, std::shared_ptr< UnitVector3d > > & cls)

Definition at line 46 of file _unitVector3d.cc.

46 {
47 // Provide the equivalent of the UnitVector3d to Vector3d C++ cast
48 // operator in Python
49 py::implicitly_convertible<UnitVector3d, Vector3d>();
50
51 cls.def_static(
52 "orthogonalTo",
53 (UnitVector3d(*)(Vector3d const &)) & UnitVector3d::orthogonalTo,
54 "vector"_a);
55 cls.def_static("orthogonalTo",
56 (UnitVector3d(*)(Vector3d const &, Vector3d const &)) &
57 UnitVector3d::orthogonalTo,
58 "vector1"_a, "vector2"_a);
59 cls.def_static("orthogonalTo",
60 (UnitVector3d(*)(NormalizedAngle const &)) &
61 UnitVector3d::orthogonalTo,
62 "meridian"_a);
63 cls.def_static("northFrom", &UnitVector3d::northFrom, "vector"_a);
64 cls.def_static("X", &UnitVector3d::X);
65 cls.def_static("Y", &UnitVector3d::Y);
66 cls.def_static("Z", &UnitVector3d::Z);
67 // The fromNormalized static factory functions are not exposed to
68 // Python, as they are easy to misuse and intended only for performance
69 // critical code (i.e. not Python).
70
71 cls.def(py::init<>());
72 cls.def(py::init<UnitVector3d const &>(), "unitVector"_a);
73 cls.def(py::init<Vector3d const &>(), "vector"_a);
74 cls.def(py::init<double, double, double>(), "x"_a, "y"_a, "z"_a);
75 cls.def(py::init<LonLat const &>(), "lonLat"_a);
76 cls.def(py::init<Angle, Angle>(), "lon"_a, "lat"_a);
77
78 cls.def("__eq__", &UnitVector3d::operator==, py::is_operator());
79 cls.def("__ne__", &UnitVector3d::operator!=, py::is_operator());
80 cls.def("__neg__",
81 (UnitVector3d(UnitVector3d::*)() const) & UnitVector3d::operator-);
82 cls.def("__add__", &UnitVector3d::operator+, py::is_operator());
83 cls.def("__sub__",
84 (Vector3d(UnitVector3d::*)(Vector3d const &) const) &
85 UnitVector3d::operator-,
86 py::is_operator());
87 cls.def("__mul__", &UnitVector3d::operator*, py::is_operator());
88 cls.def("__truediv__", &UnitVector3d::operator/, py::is_operator());
89
90 cls.def("x", &UnitVector3d::x);
91 cls.def("y", &UnitVector3d::y);
92 cls.def("z", &UnitVector3d::z);
93 cls.def("x", &UnitVector3d::dot);
94 cls.def("dot", &UnitVector3d::dot);
95 cls.def("cross", &UnitVector3d::cross);
96 cls.def("robustCross", &UnitVector3d::robustCross);
97 cls.def("cwiseProduct", &UnitVector3d::cwiseProduct);
98 cls.def("rotatedAround", &UnitVector3d::rotatedAround, "axis"_a, "angle"_a);
99
100 cls.def("__len__", [](UnitVector3d const &self) { return py::int_(3); });
101 cls.def("__getitem__", [](UnitVector3d const &self, py::int_ i) {
102 return self(python::convertIndex(3, i));
103 });
104
105 cls.def("__str__", [](UnitVector3d const &self) {
106 return py::str("[{!s}, {!s}, {!s}]")
107 .format(self.x(), self.y(), self.z());
108 });
109 cls.def("__repr__", [](UnitVector3d const &self) {
110 return py::str("UnitVector3d({!r}, {!r}, {!r})")
111 .format(self.x(), self.y(), self.z());
112 });
113
114 // Do not implement __reduce__ for pickling. Why? Given:
115 //
116 // u = UnitVector3d(x, y, z)
117 // v = UnitVector3d(u.x(), u.y(), u.z())
118 //
119 // u may not be identical to v, since the constructor normalizes its input
120 // components. Furthermore, UnitVector3d::fromNormalized is not visible to
121 // Python, and even if it were, pybind11 is currently incapable of returning
122 // a picklable reference to it.
123 cls.def(py::pickle([](UnitVector3d const &self) { return py::make_tuple(self.x(), self.y(), self.z()); },
124 [](py::tuple t) {
125 if (t.size() != 3) {
126 throw std::runtime_error("Tuple size = " + std::to_string(t.size()) +
127 "; must be 3 for a UnitVector3d");
128 }
129 return new UnitVector3d(UnitVector3d::fromNormalized(
130 t[0].cast<double>(), t[1].cast<double>(), t[2].cast<double>()));
131 }));
132}
T to_string(T... args)

◆ defineClass() [24/25]

template<>
void lsst::sphgeom::defineClass ( py::class_< Vector3d, std::shared_ptr< Vector3d > > & cls)

Definition at line 45 of file _vector3d.cc.

45 {
46 cls.def(py::init<>());
47 cls.def(py::init<double, double, double>(), "x"_a, "y"_a, "z"_a);
48 cls.def(py::init<Vector3d const &>(), "vector"_a);
49 // Construct a Vector3d from a UnitVector3d, enabling implicit
50 // conversion from UnitVector3d to Vector3d in python via
51 // py::implicitly_convertible
52 cls.def(py::init([](UnitVector3d const &u) {
53 return new Vector3d(u.x(), u.y(), u.z());
54 }));
55
56 cls.def("__eq__", &Vector3d::operator==, py::is_operator());
57 cls.def("__ne__", &Vector3d::operator!=, py::is_operator());
58 cls.def("__neg__", (Vector3d(Vector3d::*)() const) & Vector3d::operator-);
59 cls.def("__add__", &Vector3d::operator+, py::is_operator());
60 cls.def("__sub__",
61 (Vector3d(Vector3d::*)(Vector3d const &) const) &
62 Vector3d::operator-,
63 py::is_operator());
64 cls.def("__mul__", &Vector3d::operator*, py::is_operator());
65 cls.def("__truediv__", &Vector3d::operator/, py::is_operator());
66
67 cls.def("__iadd__", &Vector3d::operator+=);
68 cls.def("__isub__", &Vector3d::operator-=);
69 cls.def("__imul__", &Vector3d::operator*=);
70 cls.def("__itruediv__", &Vector3d::operator/=);
71
72 cls.def("x", &Vector3d::x);
73 cls.def("y", &Vector3d::y);
74 cls.def("z", &Vector3d::z);
75 cls.def("dot", &Vector3d::dot);
76 cls.def("getSquaredNorm", &Vector3d::getSquaredNorm);
77 cls.def("getNorm", &Vector3d::getNorm);
78 cls.def("isZero", &Vector3d::isZero);
79 cls.def("normalize", &Vector3d::normalize);
80 cls.def("isNormalized", &Vector3d::isNormalized);
81 cls.def("cross", &Vector3d::cross);
82 cls.def("cwiseProduct", &Vector3d::cwiseProduct);
83 cls.def("rotatedAround", &Vector3d::rotatedAround, "axis"_a, "angle"_a);
84
85 cls.def("__len__", [](Vector3d const &self) { return py::int_(3); });
86 cls.def("__getitem__", [](Vector3d const &self, py::int_ i) {
87 return self(python::convertIndex(3, i));
88 });
89
90 cls.def("__str__", [](Vector3d const &self) {
91 return py::str("[{!s}, {!s}, {!s}]")
92 .format(self.x(), self.y(), self.z());
93 });
94 cls.def("__repr__", [](Vector3d const &self) {
95 return py::str("Vector3d({!r}, {!r}, {!r})")
96 .format(self.x(), self.y(), self.z());
97 });
98
99 cls.def("__reduce__", [cls](Vector3d const &self) {
100 return py::make_tuple(cls,
101 py::make_tuple(self.x(), self.y(), self.z()));
102 });
103}

◆ defineClass() [25/25]

template<typename Pybind11Class >
void lsst::sphgeom::defineClass ( Pybind11Class & cls)

◆ defineCurve()

void lsst::sphgeom::defineCurve ( py::module & mod)

Definition at line 39 of file _curve.cc.

39 {
40 mod.def("log2", (uint8_t(*)(uint64_t)) & log2);
41 mod.def("mortonIndex", (uint64_t(*)(uint32_t, uint32_t)) & mortonIndex,
42 "x"_a, "y"_a);
43 mod.def("mortonIndexInverse",
44 (std::tuple<uint32_t, uint32_t>(*)(uint64_t)) & mortonIndexInverse,
45 "z"_a);
46 mod.def("mortonToHilbert", &mortonToHilbert, "z"_a, "m"_a);
47 mod.def("hilbertToMorton", &hilbertToMorton, "h"_a, "m"_a);
48 mod.def("hilbertIndex",
49 (uint64_t(*)(uint32_t, uint32_t, int)) & hilbertIndex, "x"_a, "y"_a,
50 "m"_a);
51 mod.def("hilbertIndexInverse",
52 (std::tuple<uint32_t, uint32_t>(*)(uint64_t, int)) &
53 hilbertIndexInverse,
54 "h"_a, "m"_a);
55}

◆ defineOrientation()

void lsst::sphgeom::defineOrientation ( py::module & mod)

Definition at line 39 of file _orientation.cc.

39 {
40 mod.def("orientationExact", &orientationExact, "a"_a, "b"_a, "c"_a);
41 mod.def("orientation", &orientation, "a"_a, "b"_a, "c"_a);
42 mod.def("orientationX", &orientationX, "b"_a, "c"_a);
43 mod.def("orientationY", &orientationY, "b"_a, "c"_a);
44 mod.def("orientationZ", &orientationZ, "b"_a, "c"_a);
45}

◆ defineRelationship()

void lsst::sphgeom::defineRelationship ( py::module & mod)

Definition at line 39 of file _relationship.cc.

39 {
40 mod.attr("DISJOINT") = py::cast(DISJOINT.to_ulong());
41 mod.attr("INTERSECTS") = py::cast(INTERSECTS.to_ulong());
42 mod.attr("CONTAINS") = py::cast(CONTAINS.to_ulong());
43 mod.attr("WITHIN") = py::cast(WITHIN.to_ulong());
44
45 mod.def("invert", &invert, "relationship"_a);
46}

◆ defineUtils()

void lsst::sphgeom::defineUtils ( py::module & mod)

Definition at line 44 of file _utils.cc.

44 {
45 mod.def("getMinSquaredChordLength", &getMinSquaredChordLength, "v"_a, "a"_a,
46 "b"_a, "n"_a);
47 mod.def("getMaxSquaredChordLength", &getMaxSquaredChordLength, "v"_a, "a"_a,
48 "b"_a, "n"_a);
49 mod.def("getMinAngleToCircle", &getMinAngleToCircle, "x"_a, "c"_a);
50 mod.def("getMaxAngleToCircle", &getMaxAngleToCircle, "x"_a, "c"_a);
51 mod.def("getWeightedCentroid", &getWeightedCentroid, "vector0"_a,
52 "vector1"_a, "vector2"_a);
53}

◆ encodeDouble()

void lsst::sphgeom::encodeDouble ( double item,
std::vector< std::uint8_t > & buffer )
inline

encodeDouble appends an IEEE double in little-endian byte order to the end of buffer.

Definition at line 57 of file codec.h.

57 {
58#ifdef OPTIMIZED_LITTLE_ENDIAN
59 auto ptr = reinterpret_cast<std::uint8_t const *>(&item);
60 buffer.insert(buffer.end(), ptr, ptr + 8);
61#else
62 union { std::uint64_t u; double d; };
63 d = item;
64 buffer.push_back(static_cast<std::uint8_t>(u));
65 buffer.push_back(static_cast<std::uint8_t>(u >> 8));
66 buffer.push_back(static_cast<std::uint8_t>(u >> 16));
67 buffer.push_back(static_cast<std::uint8_t>(u >> 24));
68 buffer.push_back(static_cast<std::uint8_t>(u >> 32));
69 buffer.push_back(static_cast<std::uint8_t>(u >> 40));
70 buffer.push_back(static_cast<std::uint8_t>(u >> 48));
71 buffer.push_back(static_cast<std::uint8_t>(u >> 56));
72#endif
73}
std::uint64_t * ptr
Definition RangeSet.cc:95
T end(T... args)
T insert(T... args)
T push_back(T... args)

◆ encodeU64()

void lsst::sphgeom::encodeU64 ( std::uint64_t item,
std::vector< std::uint8_t > & buffer )
inline

encodeU64 appends an uint64 in little-endian byte order to the end of buffer.

Definition at line 96 of file codec.h.

96 {
97#ifdef OPTIMIZED_LITTLE_ENDIAN
98 auto ptr = reinterpret_cast<std::uint8_t const *>(&item);
99 buffer.insert(buffer.end(), ptr, ptr + 8);
100#else
101 union { std::uint64_t u; double d; };
102 d = item;
103 buffer.push_back(static_cast<std::uint8_t>(u));
104 buffer.push_back(static_cast<std::uint8_t>(u >> 8));
105 buffer.push_back(static_cast<std::uint8_t>(u >> 16));
106 buffer.push_back(static_cast<std::uint8_t>(u >> 24));
107 buffer.push_back(static_cast<std::uint8_t>(u >> 32));
108 buffer.push_back(static_cast<std::uint8_t>(u >> 40));
109 buffer.push_back(static_cast<std::uint8_t>(u >> 48));
110 buffer.push_back(static_cast<std::uint8_t>(u >> 56));
111#endif
112}

◆ getMaxAngleToCircle()

Angle lsst::sphgeom::getMaxAngleToCircle ( Angle x,
Angle c )
inline

getMaxAngleToCircle returns the maximum angular separation between a point at latitude x and the points on the circle of constant latitude c.

Definition at line 75 of file utils.h.

75 {
77 if (abs(x) <= abs(c)) {
78 return a + Angle(PI) - 2.0 * abs(c);
79 }
80 if (a < abs(x)) {
81 return Angle(PI) - 2.0 * abs(c) - a;
82 }
83 return Angle(PI) + 2.0 * abs(c) - a;
84}
Angle getMinAngleToCircle(Angle x, Angle c)
getMinAngleToCircle returns the minimum angular separation between a point at latitude x and the poin...
Definition utils.h:69
Angle abs(Angle const &a)
Definition Angle.h:113

◆ getMaxSquaredChordLength()

double lsst::sphgeom::getMaxSquaredChordLength ( Vector3d const & v,
Vector3d const & a,
Vector3d const & b,
Vector3d const & n )

Let p be the unit vector furthest from v that lies on the plane with normal n in the direction of the cross product of a and b.

If p is in the interior of the great circle segment from a to b, then this helper function returns the squared chord length between p and v. Otherwise it returns 0 - the minimum squared chord length between any pair of points on the sphere.

Definition at line 65 of file utils.cc.

69{
70 Vector3d vxn = v.cross(n);
71 if (vxn.dot(a) < 0.0 && vxn.dot(b) > 0.0) {
72 // v is in the lune defined by the half great circle passing through
73 // n and -a and the half great circle passing through n and -b, so p
74 // is in the interior of the great circle segment from a to b. The
75 // angle θ between p and v satisfies ‖v‖ ‖n‖ sin θ = |v·n|,
76 // and ‖v‖ ‖n‖ cos θ = -‖v × n‖. The desired squared chord length is
77 // 4 sin²(θ/2).
78 double s = std::fabs(v.dot(n));
79 double c = - vxn.getNorm();
80 double d = std::sin(0.5 * std::atan2(s, c));
81 return 4.0 * d * d;
82 }
83 return 0.0;
84}
T atan2(T... args)
double dot(Vector3d const &v) const
dot returns the inner product of this vector and v.
Definition Vector3d.h:80
double getNorm() const
getNorm returns the L2 norm of this vector.
Definition Vector3d.h:88
Vector3d cross(Vector3d const &v) const
cross returns the cross product of this vector and v.
Definition Vector3d.h:108
T sin(T... args)

◆ getMinAngleToCircle()

Angle lsst::sphgeom::getMinAngleToCircle ( Angle x,
Angle c )
inline

getMinAngleToCircle returns the minimum angular separation between a point at latitude x and the points on the circle of constant latitude c.

Definition at line 69 of file utils.h.

69 {
70 return abs(x - c);
71}

◆ getMinSquaredChordLength()

double lsst::sphgeom::getMinSquaredChordLength ( Vector3d const & v,
Vector3d const & a,
Vector3d const & b,
Vector3d const & n )

Let p be the unit vector closest to v that lies on the plane with normal n in the direction of the cross product of a and b.

If p is in the interior of the great circle segment from a to b, then this function returns the squared chord length between p and v. Otherwise it returns 4 - the maximum squared chord length between any pair of points on the unit sphere.

Definition at line 43 of file utils.cc.

47{
48 Vector3d vxn = v.cross(n);
49 if (vxn.dot(a) > 0.0 && vxn.dot(b) < 0.0) {
50 // v is in the lune defined by the half great circle passing through
51 // n and a and the half great circle passing through n and b, so p
52 // is in the interior of the great circle segment from a to b. The
53 // angle θ between p and v satisfies ‖v‖ ‖n‖ sin θ = |v·n|,
54 // and ‖v‖ ‖n‖ cos θ = ‖v × n‖. The desired squared chord length is
55 // 4 sin²(θ/2).
56 double s = std::fabs(v.dot(n));
57 double c = vxn.getNorm();
58 double theta = (c == 0.0) ? 0.5 * PI : std::atan(s / c);
59 double d = std::sin(0.5 * theta);
60 return 4.0 * d * d;
61 }
62 return 4.0;
63}
STL namespace.

◆ getWeightedCentroid()

Vector3d lsst::sphgeom::getWeightedCentroid ( UnitVector3d const & v0,
UnitVector3d const & v1,
UnitVector3d const & v2 )

getWeightedCentroid returns the center of mass of the given spherical triangle (assuming a uniform mass distribution over the triangle surface), weighted by the triangle area.

Definition at line 86 of file utils.cc.

89{
90 // For the details, see:
91 //
92 // The centroid and inertia tensor for a spherical triangle
93 // John E. Brock
94 // 1974, Naval Postgraduate School, Monterey Calif.
95 //
96 // https://openlibrary.org/books/OL25493734M/The_centroid_and_inertia_tensor_for_a_spherical_triangle
97
98 Vector3d x01 = v0.robustCross(v1); // twice the cross product of v0 and v1
99 Vector3d x12 = v1.robustCross(v2);
100 Vector3d x20 = v2.robustCross(v0);
101 double s01 = 0.5 * x01.normalize(); // sine of the angle between v0 and v1
102 double s12 = 0.5 * x12.normalize();
103 double s20 = 0.5 * x20.normalize();
104 double c01 = v0.dot(v1); // cosine of the angle between v0 and v1
105 double c12 = v1.dot(v2);
106 double c20 = v2.dot(v0);
107 double a0 = (s12 == 0.0 && c12 == 0.0) ? 0.0 : std::atan2(s12, c12);
108 double a1 = (s20 == 0.0 && c20 == 0.0) ? 0.0 : std::atan2(s20, c20);
109 double a2 = (s01 == 0.0 && c01 == 0.0) ? 0.0 : std::atan2(s01, c01);
110 return 0.5 * (x01 * a2 + x12 * a0 + x20 * a1);
111}
double normalize()
normalize scales this vector to have unit norm and returns its norm prior to scaling.
Definition Vector3d.cc:49

◆ hilbertIndex()

std::uint64_t lsst::sphgeom::hilbertIndex ( std::uint32_t x,
std::uint32_t y,
int m )
inline

hilbertIndex returns the index of (x, y) in a 2-D Hilbert curve.

Only the m least significant bits of x and y are used. Computing the Hilbert index of a point has been measured to take 4 to 15 times as long as computing its Morton index on an Intel Core i7-3820QM CPU. With Xcode 7.3 and -O3, latency is ~19ns per call at a CPU frequency of 3.5 GHz.

Definition at line 356 of file curve.h.

356 {
357 return mortonToHilbert(mortonIndex(x, y), m);
358}
int y
Definition SpanSet.cc:48
int m
Definition SpanSet.cc:48
std::uint64_t mortonIndex(std::uint32_t x, std::uint32_t y)
mortonIndex interleaves the bits of x and y.
Definition curve.h:155
std::uint64_t mortonToHilbert(std::uint64_t z, int m)
mortonToHilbert converts the 2m-bit Morton index z to the corresponding Hilbert index.
Definition curve.h:243

◆ hilbertIndexInverse()

std::tuple< std::uint32_t, std::uint32_t > lsst::sphgeom::hilbertIndexInverse ( std::uint64_t h,
int m )
inline

hilbertIndexInverse returns the point (x, y) with Hilbert index h, where x and y are m bit integers.

Definition at line 368 of file curve.h.

368 {
370}
std::uint64_t hilbertToMorton(std::uint64_t h, int m)
hilbertToMorton converts the 2m-bit Hilbert index h to the corresponding Morton index.
Definition curve.h:297
std::tuple< std::uint32_t, std::uint32_t > mortonIndexInverse(std::uint64_t z)
mortonIndexInverse separates the even and odd bits of z.
Definition curve.h:202

◆ hilbertToMorton()

std::uint64_t lsst::sphgeom::hilbertToMorton ( std::uint64_t h,
int m )
inline

hilbertToMorton converts the 2m-bit Hilbert index h to the corresponding Morton index.

Definition at line 297 of file curve.h.

297 {
298 alignas(64) static std::uint8_t const HILBERT_INVERSE_LUT_3[256] = {
299 0x40, 0x02, 0x03, 0xc1, 0x04, 0x45, 0x47, 0x86,
300 0x0c, 0x4d, 0x4f, 0x8e, 0xcb, 0x89, 0x88, 0x4a,
301 0x20, 0x61, 0x63, 0xa2, 0x68, 0x2a, 0x2b, 0xe9,
302 0x6c, 0x2e, 0x2f, 0xed, 0xa7, 0xe6, 0xe4, 0x25,
303 0x30, 0x71, 0x73, 0xb2, 0x78, 0x3a, 0x3b, 0xf9,
304 0x7c, 0x3e, 0x3f, 0xfd, 0xb7, 0xf6, 0xf4, 0x35,
305 0xdf, 0x9d, 0x9c, 0x5e, 0x9b, 0xda, 0xd8, 0x19,
306 0x93, 0xd2, 0xd0, 0x11, 0x54, 0x16, 0x17, 0xd5,
307 0x00, 0x41, 0x43, 0x82, 0x48, 0x0a, 0x0b, 0xc9,
308 0x4c, 0x0e, 0x0f, 0xcd, 0x87, 0xc6, 0xc4, 0x05,
309 0x50, 0x12, 0x13, 0xd1, 0x14, 0x55, 0x57, 0x96,
310 0x1c, 0x5d, 0x5f, 0x9e, 0xdb, 0x99, 0x98, 0x5a,
311 0x70, 0x32, 0x33, 0xf1, 0x34, 0x75, 0x77, 0xb6,
312 0x3c, 0x7d, 0x7f, 0xbe, 0xfb, 0xb9, 0xb8, 0x7a,
313 0xaf, 0xee, 0xec, 0x2d, 0xe7, 0xa5, 0xa4, 0x66,
314 0xe3, 0xa1, 0xa0, 0x62, 0x28, 0x69, 0x6b, 0xaa,
315 0xff, 0xbd, 0xbc, 0x7e, 0xbb, 0xfa, 0xf8, 0x39,
316 0xb3, 0xf2, 0xf0, 0x31, 0x74, 0x36, 0x37, 0xf5,
317 0x9f, 0xde, 0xdc, 0x1d, 0xd7, 0x95, 0x94, 0x56,
318 0xd3, 0x91, 0x90, 0x52, 0x18, 0x59, 0x5b, 0x9a,
319 0x8f, 0xce, 0xcc, 0x0d, 0xc7, 0x85, 0x84, 0x46,
320 0xc3, 0x81, 0x80, 0x42, 0x08, 0x49, 0x4b, 0x8a,
321 0x60, 0x22, 0x23, 0xe1, 0x24, 0x65, 0x67, 0xa6,
322 0x2c, 0x6d, 0x6f, 0xae, 0xeb, 0xa9, 0xa8, 0x6a,
323 0xbf, 0xfe, 0xfc, 0x3d, 0xf7, 0xb5, 0xb4, 0x76,
324 0xf3, 0xb1, 0xb0, 0x72, 0x38, 0x79, 0x7b, 0xba,
325 0xef, 0xad, 0xac, 0x6e, 0xab, 0xea, 0xe8, 0x29,
326 0xa3, 0xe2, 0xe0, 0x21, 0x64, 0x26, 0x27, 0xe5,
327 0xcf, 0x8d, 0x8c, 0x4e, 0x8b, 0xca, 0xc8, 0x09,
328 0x83, 0xc2, 0xc0, 0x01, 0x44, 0x06, 0x07, 0xc5,
329 0x10, 0x51, 0x53, 0x92, 0x58, 0x1a, 0x1b, 0xd9,
330 0x5c, 0x1e, 0x1f, 0xdd, 0x97, 0xd6, 0xd4, 0x15
331 };
332 std::uint64_t z = 0;
333 std::uint64_t i = 0;
334 for (m = 2 * m; m >= 6;) {
335 m -= 6;
336 std::uint8_t j = HILBERT_INVERSE_LUT_3[i | ((h >> m) & 0x3f)];
337 z = (z << 6) | (j & 0x3f);
338 i = j & 0xc0;
339 }
340 if (m != 0) {
341 // m = 2 or 4
342 int r = 6 - m;
343 std::uint8_t j = HILBERT_INVERSE_LUT_3[i | ((h << r) & 0x3f)];
344 z = (z << m) | ((j & 0x3f) >> r);
345 }
346 return z;
347}
double z
Definition Match.cc:44

◆ invert()

Relationship lsst::sphgeom::invert ( Relationship r)
inline

Given the relationship between two sets A and B (i.e.

the output of A.relate(B)), invert returns the relationship between B and A (B.relate(A)).

Definition at line 62 of file Relationship.h.

62 {
63 // If A is disjoint from B, then B is disjoint from A. But if A contains B
64 // then B is within A, so the corresponding bits must be swapped.
65 return (r & DISJOINT) | ((r & CONTAINS) << 1) | ((r & WITHIN) >> 1);
66}

◆ log2() [1/2]

std::uint8_t lsst::sphgeom::log2 ( std::uint32_t x)
inline

log2 returns the index of the most significant 1 bit in x. If x is 0, the return value is 0.

A beautiful algorithm to find this index is presented in:

‍Using de Bruijn Sequences to Index a 1 in a Computer Word C. E. Leiserson, H. Prokop, and K. H. Randall. http://supertech.csail.mit.edu/papers/debruijn.pdf

Definition at line 132 of file curve.h.

132 {
133 // See https://graphics.stanford.edu/~seander/bithacks.html#IntegerLogDeBruijn
134 alignas(32) static std::uint8_t const PERFECT_HASH_TABLE[32] = {
135 0, 9, 1, 10, 13, 21, 2, 29, 11, 14, 16, 18, 22, 25, 3, 30,
136 8, 12, 20, 28, 15, 17, 24, 7, 19, 27, 23, 6, 26, 5, 4, 31
137 };
138 std::uint32_t const DE_BRUIJN_SEQUENCE = UINT32_C(0x07c4acdd);
139 x |= (x >> 1);
140 x |= (x >> 2);
141 x |= (x >> 4);
142 x |= (x >> 8);
143 x |= (x >> 16);
144 return PERFECT_HASH_TABLE[(DE_BRUIJN_SEQUENCE * x) >> 27];
145}

◆ log2() [2/2]

std::uint8_t lsst::sphgeom::log2 ( std::uint64_t x)
inline

log2 returns the index of the most significant 1 bit in x. If x is 0, the return value is 0.

A beautiful algorithm to find this index is presented in:

‍Using de Bruijn Sequences to Index a 1 in a Computer Word C. E. Leiserson, H. Prokop, and K. H. Randall. http://supertech.csail.mit.edu/papers/debruijn.pdf

Definition at line 105 of file curve.h.

105 {
106 alignas(64) static std::uint8_t const PERFECT_HASH_TABLE[64] = {
107 0, 1, 2, 7, 3, 13, 8, 19, 4, 25, 14, 28, 9, 34, 20, 40,
108 5, 17, 26, 38, 15, 46, 29, 48, 10, 31, 35, 54, 21, 50, 41, 57,
109 63, 6, 12, 18, 24, 27, 33, 39, 16, 37, 45, 47, 30, 53, 49, 56,
110 62, 11, 23, 32, 36, 44, 52, 55, 61, 22, 43, 51, 60, 42, 59, 58
111 };
112 std::uint64_t const DE_BRUIJN_SEQUENCE = UINT64_C(0x0218a392cd3d5dbf);
113 // First ensure that all bits below the MSB are set.
114 x |= (x >> 1);
115 x |= (x >> 2);
116 x |= (x >> 4);
117 x |= (x >> 8);
118 x |= (x >> 16);
119 x |= (x >> 32);
120 // Then, subtract them away.
121 x = x - (x >> 1);
122 // Multiplication by x is now a shift by the index i of the MSB.
123 //
124 // By definition, the value of the upper 6 bits of a 64-bit De Bruijn
125 // sequence left shifted by i is different for every value of i in
126 // [0, 64). It can therefore be used as an an index into a lookup table
127 // that recovers i. In other words, (DE_BRUIJN_SEQUENCE * x) >> 58 is a
128 // minimal perfect hash function for 64 bit powers of 2.
129 return PERFECT_HASH_TABLE[(DE_BRUIJN_SEQUENCE * x) >> 58];
130}

◆ mortonIndex()

std::uint64_t lsst::sphgeom::mortonIndex ( std::uint32_t x,
std::uint32_t y )
inline

mortonIndex interleaves the bits of x and y.

The 32 even bits of the return value will be the bits of x, and the 32 odd bits those of y. This is the z-value of (x,y) defined by the Morton order function. See https://en.wikipedia.org/wiki/Z-order_curve for more information.

Definition at line 155 of file curve.h.

155 {
156 // This is just a 64-bit extension of:
157 // http://graphics.stanford.edu/~seander/bithacks.html#InterleaveBMN
158 std::uint64_t b = y;
159 std::uint64_t a = x;
160 b = (b | (b << 16)) & UINT64_C(0x0000ffff0000ffff);
161 a = (a | (a << 16)) & UINT64_C(0x0000ffff0000ffff);
162 b = (b | (b << 8)) & UINT64_C(0x00ff00ff00ff00ff);
163 a = (a | (a << 8)) & UINT64_C(0x00ff00ff00ff00ff);
164 b = (b | (b << 4)) & UINT64_C(0x0f0f0f0f0f0f0f0f);
165 a = (a | (a << 4)) & UINT64_C(0x0f0f0f0f0f0f0f0f);
166 b = (b | (b << 2)) & UINT64_C(0x3333333333333333);
167 a = (a | (a << 2)) & UINT64_C(0x3333333333333333);
168 b = (b | (b << 1)) & UINT64_C(0x5555555555555555);
169 a = (a | (a << 1)) & UINT64_C(0x5555555555555555);
170 return a | (b << 1);
171 }

◆ mortonIndexInverse()

std::tuple< std::uint32_t, std::uint32_t > lsst::sphgeom::mortonIndexInverse ( std::uint64_t z)
inline

mortonIndexInverse separates the even and odd bits of z.

The 32 even bits of z are returned in the first element of the result tuple, and the 32 odd bits in the second. This is the inverse of mortonIndex().

Definition at line 202 of file curve.h.

202 {
203 std::uint64_t x = z & UINT64_C(0x5555555555555555);
204 std::uint64_t y = (z >> 1) & UINT64_C(0x5555555555555555);
205 x = (x | (x >> 1)) & UINT64_C(0x3333333333333333);
206 y = (y | (y >> 1)) & UINT64_C(0x3333333333333333);
207 x = (x | (x >> 2)) & UINT64_C(0x0f0f0f0f0f0f0f0f);
208 y = (y | (y >> 2)) & UINT64_C(0x0f0f0f0f0f0f0f0f);
209 x = (x | (x >> 4)) & UINT64_C(0x00ff00ff00ff00ff);
210 y = (y | (y >> 4)) & UINT64_C(0x00ff00ff00ff00ff);
211 x = (x | (x >> 8)) & UINT64_C(0x0000ffff0000ffff);
212 y = (y | (y >> 8)) & UINT64_C(0x0000ffff0000ffff);
213 return std::make_tuple(static_cast<std::uint32_t>(x | (x >> 16)),
214 static_cast<std::uint32_t>(y | (y >> 16)));
215 }
T make_tuple(T... args)

◆ mortonToHilbert()

std::uint64_t lsst::sphgeom::mortonToHilbert ( std::uint64_t z,
int m )
inline

mortonToHilbert converts the 2m-bit Morton index z to the corresponding Hilbert index.

Definition at line 243 of file curve.h.

243 {
244 alignas(64) static std::uint8_t const HILBERT_LUT_3[256] = {
245 0x40, 0xc3, 0x01, 0x02, 0x04, 0x45, 0x87, 0x46,
246 0x8e, 0x8d, 0x4f, 0xcc, 0x08, 0x49, 0x8b, 0x4a,
247 0xfa, 0x3b, 0xf9, 0xb8, 0x7c, 0xff, 0x3d, 0x3e,
248 0xf6, 0x37, 0xf5, 0xb4, 0xb2, 0xb1, 0x73, 0xf0,
249 0x10, 0x51, 0x93, 0x52, 0xde, 0x1f, 0xdd, 0x9c,
250 0x54, 0xd7, 0x15, 0x16, 0x58, 0xdb, 0x19, 0x1a,
251 0x20, 0x61, 0xa3, 0x62, 0xee, 0x2f, 0xed, 0xac,
252 0x64, 0xe7, 0x25, 0x26, 0x68, 0xeb, 0x29, 0x2a,
253 0x00, 0x41, 0x83, 0x42, 0xce, 0x0f, 0xcd, 0x8c,
254 0x44, 0xc7, 0x05, 0x06, 0x48, 0xcb, 0x09, 0x0a,
255 0x50, 0xd3, 0x11, 0x12, 0x14, 0x55, 0x97, 0x56,
256 0x9e, 0x9d, 0x5f, 0xdc, 0x18, 0x59, 0x9b, 0x5a,
257 0xba, 0xb9, 0x7b, 0xf8, 0xb6, 0xb5, 0x77, 0xf4,
258 0x3c, 0x7d, 0xbf, 0x7e, 0xf2, 0x33, 0xf1, 0xb0,
259 0x60, 0xe3, 0x21, 0x22, 0x24, 0x65, 0xa7, 0x66,
260 0xae, 0xad, 0x6f, 0xec, 0x28, 0x69, 0xab, 0x6a,
261 0xaa, 0xa9, 0x6b, 0xe8, 0xa6, 0xa5, 0x67, 0xe4,
262 0x2c, 0x6d, 0xaf, 0x6e, 0xe2, 0x23, 0xe1, 0xa0,
263 0x9a, 0x99, 0x5b, 0xd8, 0x96, 0x95, 0x57, 0xd4,
264 0x1c, 0x5d, 0x9f, 0x5e, 0xd2, 0x13, 0xd1, 0x90,
265 0x70, 0xf3, 0x31, 0x32, 0x34, 0x75, 0xb7, 0x76,
266 0xbe, 0xbd, 0x7f, 0xfc, 0x38, 0x79, 0xbb, 0x7a,
267 0xca, 0x0b, 0xc9, 0x88, 0x4c, 0xcf, 0x0d, 0x0e,
268 0xc6, 0x07, 0xc5, 0x84, 0x82, 0x81, 0x43, 0xc0,
269 0xea, 0x2b, 0xe9, 0xa8, 0x6c, 0xef, 0x2d, 0x2e,
270 0xe6, 0x27, 0xe5, 0xa4, 0xa2, 0xa1, 0x63, 0xe0,
271 0x30, 0x71, 0xb3, 0x72, 0xfe, 0x3f, 0xfd, 0xbc,
272 0x74, 0xf7, 0x35, 0x36, 0x78, 0xfb, 0x39, 0x3a,
273 0xda, 0x1b, 0xd9, 0x98, 0x5c, 0xdf, 0x1d, 0x1e,
274 0xd6, 0x17, 0xd5, 0x94, 0x92, 0x91, 0x53, 0xd0,
275 0x8a, 0x89, 0x4b, 0xc8, 0x86, 0x85, 0x47, 0xc4,
276 0x0c, 0x4d, 0x8f, 0x4e, 0xc2, 0x03, 0xc1, 0x80
277 };
278 std::uint64_t h = 0;
279 std::uint64_t i = 0;
280 for (m = 2 * m; m >= 6;) {
281 m -= 6;
282 std::uint8_t j = HILBERT_LUT_3[i | ((z >> m) & 0x3f)];
283 h = (h << 6) | (j & 0x3f);
284 i = j & 0xc0;
285 }
286 if (m != 0) {
287 // m = 2 or 4
288 int r = 6 - m;
289 std::uint8_t j = HILBERT_LUT_3[i | ((z << r) & 0x3f)];
290 h = (h << m) | ((j & 0x3f) >> r);
291 }
292 return h;
293}

◆ operator*() [1/2]

Angle lsst::sphgeom::operator* ( double a,
Angle const & b )
inline

Definition at line 105 of file Angle.h.

105{ return b * a; }

◆ operator*() [2/2]

Vector3d lsst::sphgeom::operator* ( double s,
Vector3d const & v )
inline

Definition at line 172 of file Vector3d.h.

172{ return v * s; }

◆ operator<<() [1/15]

std::ostream & lsst::sphgeom::operator<< ( std::ostream & os,
Angle const & a )

Definition at line 41 of file Angle.cc.

41 {
42 char buf[32];
43 std::snprintf(buf, sizeof(buf), "%.17g", a.asRadians());
44 return os << buf;
45}
T snprintf(T... args)

◆ operator<<() [2/15]

std::ostream & lsst::sphgeom::operator<< ( std::ostream & os,
AngleInterval const & i )

Definition at line 41 of file AngleInterval.cc.

41 {
42 return os << '[' << i.getA() << ", " << i.getB() << ']';
43}

◆ operator<<() [3/15]

std::ostream & lsst::sphgeom::operator<< ( std::ostream & os,
Box const & b )

Definition at line 502 of file Box.cc.

502 {
503 return os << "{\"Box\": [" << b.getLon() << ", " << b.getLat() << "]}";
504}

◆ operator<<() [4/15]

std::ostream & lsst::sphgeom::operator<< ( std::ostream & os,
Box3d const & b )

Definition at line 41 of file Box3d.cc.

41 {
42 return os << "{\"Box3d\": [" << b.x() << ", " << b.y() << ", " << b.z() << "]}";
43}

◆ operator<<() [5/15]

std::ostream & lsst::sphgeom::operator<< ( std::ostream & os,
Circle const & c )

Definition at line 388 of file Circle.cc.

388 {
389 char tail[32];
390 std::snprintf(tail, sizeof(tail), ", %.17g]}", c.getSquaredChordLength());
391 return os << "{\"Circle\": [" << c.getCenter() << tail;
392}

◆ operator<<() [6/15]

std::ostream & lsst::sphgeom::operator<< ( std::ostream & os,
ConvexPolygon const & p )

Definition at line 414 of file ConvexPolygon.cc.

414 {
415 typedef std::vector<UnitVector3d>::const_iterator VertexIterator;
416 VertexIterator v = p.getVertices().begin();
417 VertexIterator const end = p.getVertices().end();
418 os << "{\"ConvexPolygon\": [" << *v;
419 for (++v; v != end; ++v) { os << ", " << *v; }
420 os << "]}";
421 return os;
422}
int end
std::ostream * os
Definition Schema.cc:557

◆ operator<<() [7/15]

std::ostream & lsst::sphgeom::operator<< ( std::ostream & os,
Ellipse const & e )

Definition at line 419 of file Ellipse.cc.

419 {
420 os << "{\"Ellipse\": [" << e.getTransformMatrix() << ", "
421 << e.getAlpha() << ", " << e.getBeta() << "]}";
422 return os;
423}

◆ operator<<() [8/15]

std::ostream & lsst::sphgeom::operator<< ( std::ostream & os,
Interval1d const & i )

Definition at line 42 of file Interval1d.cc.

42 {
43 char buf[64];
44 std::snprintf(buf, sizeof(buf), "[%.17g, %.17g]", i.getA(), i.getB());
45 return os << buf;
46}

◆ operator<<() [9/15]

std::ostream & lsst::sphgeom::operator<< ( std::ostream & os,
LonLat const & p )

Definition at line 89 of file LonLat.cc.

89 {
90 return os << '[' << p.getLon() << ", " << p.getLat() << ']';
91}

◆ operator<<() [10/15]

std::ostream & lsst::sphgeom::operator<< ( std::ostream & os,
Matrix3d const & m )

Definition at line 42 of file Matrix3d.cc.

42 {
43 return os << '[' << m.getRow(0) << ", " << m.getRow(1) << ", " << m.getRow(2) << ']';
44}

◆ operator<<() [11/15]

std::ostream & lsst::sphgeom::operator<< ( std::ostream & os,
NormalizedAngleInterval const & i )

Definition at line 291 of file NormalizedAngleInterval.cc.

293{
294 return os << '[' << i.getA() << ", " << i.getB() << ']';
295}

◆ operator<<() [12/15]

std::ostream & lsst::sphgeom::operator<< ( std::ostream & os,
RangeSet const & s )

Definition at line 623 of file RangeSet.cc.

623 {
624 os << "{\"RangeSet\": [";
625 bool first = true;
626 for (auto const & t: s) {
627 if (!first) {
628 os << ", ";
629 }
630 first = false;
631 os << '[' << std::get<0>(t) << ", " << std::get<1>(t) << ']';
632 }
633 os << "]}";
634 return os;
635}

◆ operator<<() [13/15]

std::ostream & lsst::sphgeom::operator<< ( std::ostream & os,
UnitVector3d const & v )

Definition at line 80 of file UnitVector3d.cc.

80 {
81 return os << static_cast<Vector3d const &>(v);
82}

◆ operator<<() [14/15]

std::ostream & lsst::sphgeom::operator<< ( std::ostream & os,
Vector3d const & v )

Definition at line 141 of file Vector3d.cc.

141 {
142 char buf[128];
143 std::snprintf(buf, sizeof(buf), "[%.17g, %.17g, %.17g]",
144 v.x(), v.y(), v.z());
145 return os << buf;
146}

◆ operator<<() [15/15]

std::ostream & lsst::sphgeom::operator<< ( std::ostream & stream,
TriState const & value )
inline

Definition at line 131 of file TriState.h.

131 {
132 const char* str = "unknown";
133 if (value == true) {
134 str = "true";
135 } else if (value == false) {
136 str = "false";
137 }
138 return stream << str;
139}

◆ orientation()

int lsst::sphgeom::orientation ( UnitVector3d const & a,
UnitVector3d const & b,
UnitVector3d const & c )

orientation computes and returns the orientations of 3 unit vectors a, b and c.

The return value is +1 if the vectors are in counter-clockwise orientation, 0 if they are coplanar, colinear or identical, and -1 if they are in clockwise orientation.

This is equivalent to computing the sign of the scalar triple product a · (b x c), which is the sign of the determinant of the 3x3 matrix with a, b and c as columns/rows.

The implementation proceeds by first computing a double precision approximation, and then falling back to arbitrary precision arithmetic when necessary. Consequently, the result is exact.

Definition at line 142 of file orientation.cc.

145{
146 // This constant is a little more than 5ε, where ε = 2^-53. When multiplied
147 // by the permanent of |M|, it gives an error bound on the determinant of
148 // M. Here, M is a 3x3 matrix and |M| denotes the matrix obtained by
149 // taking the absolute value of each of its components. The derivation of
150 // this proceeds in the same manner as the derivation of the error bounds
151 // in section 4.3 of:
152 //
153 // Adaptive Precision Floating-Point Arithmetic
154 // and Fast Robust Geometric Predicates,
155 // Jonathan Richard Shewchuk,
156 // Discrete & Computational Geometry 18(3):305–363, October 1997.
157 //
158 // available online at http://www.cs.berkeley.edu/~jrs/papers/robustr.pdf
159 static double const relativeError = 5.6e-16;
160 // Because all 3 unit vectors are normalized, the maximum absolute value of
161 // any vector component, cross product component or dot product term in
162 // the calculation is very close to 1. The permanent of |M| must therefore
163 // be below 3 + c, where c is some small multiple of ε. This constant, a
164 // little larger than 3 * 5ε, is an upper bound on the absolute error in
165 // the determinant calculation.
166 static double const maxAbsoluteError = 1.7e-15;
167 // This constant accounts for floating point underflow (assuming hardware
168 // without gradual underflow, just to be conservative) in the computation
169 // of det(M). It is a little more than 14 * 2^-1022.
170 static double const minAbsoluteError = 4.0e-307;
171
172 double bycz = b.y() * c.z();
173 double bzcy = b.z() * c.y();
174 double bzcx = b.z() * c.x();
175 double bxcz = b.x() * c.z();
176 double bxcy = b.x() * c.y();
177 double bycx = b.y() * c.x();
178 double determinant = a.x() * (bycz - bzcy) +
179 a.y() * (bzcx - bxcz) +
180 a.z() * (bxcy - bycx);
181 if (determinant > maxAbsoluteError) {
182 return 1;
183 } else if (determinant < -maxAbsoluteError) {
184 return -1;
185 }
186 // Expend some more effort on what is hopefully a tighter error bound
187 // before falling back on arbitrary precision arithmetic.
188 double permanent = std::fabs(a.x()) * (std::fabs(bycz) + std::fabs(bzcy)) +
189 std::fabs(a.y()) * (std::fabs(bzcx) + std::fabs(bxcz)) +
190 std::fabs(a.z()) * (std::fabs(bxcy) + std::fabs(bycx));
191 double maxError = relativeError * permanent + minAbsoluteError;
192 if (determinant > maxError) {
193 return 1;
194 } else if (determinant < -maxError) {
195 return -1;
196 }
197 // Avoid the slow path when any two inputs are identical or antipodal.
198 if (a == b || b == c || a == c || a == -b || b == -c || a == -c) {
199 return 0;
200 }
201 return orientationExact(a, b, c);
202}
int orientationExact(Vector3d const &a, Vector3d const &b, Vector3d const &c)
orientationExact computes and returns the orientations of 3 vectors a, b and c, which need not be nor...

◆ orientationExact()

int lsst::sphgeom::orientationExact ( Vector3d const & a,
Vector3d const & b,
Vector3d const & c )

orientationExact computes and returns the orientations of 3 vectors a, b and c, which need not be normalized but are assumed to have finite components.

The return value is +1 if the vectors a, b, and c are in counter-clockwise orientation, 0 if they are coplanar, colinear, or identical, and -1 if they are in clockwise orientation. The implementation uses arbitrary precision arithmetic to avoid floating point rounding error, underflow and overflow.

Definition at line 83 of file orientation.cc.

86{
87 // Product mantissa storage buffers.
88 std::uint32_t mantissaBuffers[6][6];
89 // Product mantissas.
90 BigInteger mantissas[6] = {
91 BigInteger(mantissaBuffers[0], 6),
92 BigInteger(mantissaBuffers[1], 6),
93 BigInteger(mantissaBuffers[2], 6),
94 BigInteger(mantissaBuffers[3], 6),
95 BigInteger(mantissaBuffers[4], 6),
96 BigInteger(mantissaBuffers[5], 6)
97 };
98 BigFloat products[6] = {
99 BigFloat(&mantissas[0]),
100 BigFloat(&mantissas[1]),
101 BigFloat(&mantissas[2]),
102 BigFloat(&mantissas[3]),
103 BigFloat(&mantissas[4]),
104 BigFloat(&mantissas[5])
105 };
106 // An accumulator and its storage.
107 std::uint32_t accumulatorBuffer[512];
108 BigInteger accumulator(accumulatorBuffer,
109 sizeof(accumulatorBuffer) / sizeof(std::uint32_t));
110 // Compute the products in the determinant. Performing all multiplication
111 // up front means that each product mantissa occupies at most 3*53 bits.
112 computeProduct(products[0], a.x(), b.y(), c.z());
113 computeProduct(products[1], a.x(), b.z(), c.y());
114 computeProduct(products[2], a.y(), b.z(), c.x());
115 computeProduct(products[3], a.y(), b.x(), c.z());
116 computeProduct(products[4], a.z(), b.x(), c.y());
117 computeProduct(products[5], a.z(), b.y(), c.x());
118 mantissas[1].negate();
119 mantissas[3].negate();
120 mantissas[5].negate();
121 // Sort the array of products in descending exponent order.
122 std::sort(products, products + 6, [](BigFloat const & a, BigFloat const & b) {
123 return a.exponent > b.exponent;
124 });
125 // First, initialize the accumulator to the product with the highest
126 // exponent, then add the remaining products. Prior to each addition, we
127 // must shift the accumulated value so that its radix point lines up with
128 // the the radix point of the product to add.
129 //
130 // More precisely, at each step we have an accumulated value A·2ʲ and a
131 // product P·2ᵏ, and we update the accumulator to equal (A·2ʲ⁻ᵏ + P)·2ᵏ.
132 // Because the products were sorted beforehand, j ≥ k and 2ʲ⁻ᵏ is an
133 // integer.
134 accumulator = *products[0].mantissa;
135 for (int i = 1; i < 6; ++i) {
136 accumulator.multiplyPow2(products[i - 1].exponent - products[i].exponent);
137 accumulator.add(*products[i].mantissa);
138 }
139 return accumulator.getSign();
140}
BigInteger is an arbitrary precision signed integer class.
Definition BigInteger.h:51
void negate()
negate multiplies this integer by -1.
Definition BigInteger.h:109
T sort(T... args)
BigInteger * mantissa
int exponent

◆ orientationX()

int lsst::sphgeom::orientationX ( UnitVector3d const & b,
UnitVector3d const & c )

orientationX(b, c) is equivalent to orientation(UnitVector3d::X(), b, c).

Definition at line 234 of file orientation.cc.

234 {
235 int o = _orientationXYZ(b.y() * c.z(), b.z() * c.y());
236 return (o != 0) ? o : orientationExact(UnitVector3d::X(), b, c);
237}

◆ orientationY()

int lsst::sphgeom::orientationY ( UnitVector3d const & b,
UnitVector3d const & c )

orientationY(b, c) is equivalent to orientation(UnitVector3d::Y(), b, c).

Definition at line 239 of file orientation.cc.

239 {
240 int o = _orientationXYZ(b.z() * c.x(), b.x() * c.z());
241 return (o != 0) ? o : orientationExact(UnitVector3d::Y(), b, c);
242}

◆ orientationZ()

int lsst::sphgeom::orientationZ ( UnitVector3d const & b,
UnitVector3d const & c )

orientationZ(b, c) is equivalent to orientation(UnitVector3d::Z(), b, c).

Definition at line 244 of file orientation.cc.

244 {
245 int o = _orientationXYZ(b.x() * c.y(), b.y() * c.x());
246 return (o != 0) ? o : orientationExact(UnitVector3d::Z(), b, c);
247}

◆ sin()

double lsst::sphgeom::sin ( Angle const & a)
inline

Definition at line 109 of file Angle.h.

109{ return std::sin(a.asRadians()); }

◆ swap()

void lsst::sphgeom::swap ( RangeSet & a,
RangeSet & b )
inline

Definition at line 615 of file RangeSet.h.

615 {
616 a.swap(b);
617}

◆ tan()

double lsst::sphgeom::tan ( Angle const & a)
inline

Definition at line 111 of file Angle.h.

111{ return std::tan(a.asRadians()); }
T tan(T... args)

Variable Documentation

◆ DEG_PER_RAD

constexpr double lsst::sphgeom::DEG_PER_RAD = 57.2957795130823208767981548141
constexpr

Definition at line 46 of file constants.h.

◆ EPSILON

constexpr double lsst::sphgeom::EPSILON = 1.1102230246251565e-16
constexpr

Definition at line 61 of file constants.h.

◆ MAX_ASIN_ERROR

constexpr double lsst::sphgeom::MAX_ASIN_ERROR = 1.5e-8
constexpr

Definition at line 52 of file constants.h.

◆ MAX_SQUARED_CHORD_LENGTH_ERROR

constexpr double lsst::sphgeom::MAX_SQUARED_CHORD_LENGTH_ERROR = 2.5e-15
constexpr

Definition at line 57 of file constants.h.

◆ ONE_OVER_PI

constexpr double lsst::sphgeom::ONE_OVER_PI = 0.318309886183790671537767526745
constexpr

Definition at line 44 of file constants.h.

◆ PI

constexpr double lsst::sphgeom::PI = 3.1415926535897932384626433832795
constexpr

Definition at line 43 of file constants.h.

◆ RAD_PER_DEG

constexpr double lsst::sphgeom::RAD_PER_DEG = 0.0174532925199432957692369076849
constexpr

Definition at line 45 of file constants.h.