├── .git-blame-ignore-revs
├── .github
├── pull_request_template.md
└── workflows
│ ├── build.yaml
│ ├── cmake.yaml
│ ├── docstyle.yaml
│ ├── formatting.yaml
│ ├── lint.yaml
│ ├── rebase_checker.yaml
│ └── yamllint.yaml
├── .gitignore
├── .pre-commit-config.yaml
├── .yamllint.yaml
├── CMakeLists.txt
├── COPYRIGHT
├── LICENSE
├── MANIFEST.in
├── README.md
├── SConstruct
├── bsd_license.txt
├── doc
├── SConscript
├── doxygen.conf.in
├── htm.md
└── q3c.md
├── gpl-v3.0.txt
├── include
└── lsst
│ └── sphgeom
│ ├── Angle.h
│ ├── AngleInterval.h
│ ├── BigInteger.h
│ ├── Box.h
│ ├── Box3d.h
│ ├── Chunker.h
│ ├── Circle.h
│ ├── CompoundRegion.h
│ ├── ConvexPolygon.h
│ ├── Ellipse.h
│ ├── HtmPixelization.h
│ ├── Interval.h
│ ├── Interval1d.h
│ ├── LonLat.h
│ ├── Matrix3d.h
│ ├── Mq3cPixelization.h
│ ├── NormalizedAngle.h
│ ├── NormalizedAngleInterval.h
│ ├── Pixelization.h
│ ├── Q3cPixelization.h
│ ├── RangeSet.h
│ ├── Region.h
│ ├── Relationship.h
│ ├── TriState.h
│ ├── UnitVector3d.h
│ ├── Vector3d.h
│ ├── codec.h
│ ├── constants.h
│ ├── curve.h
│ ├── orientation.h
│ ├── python.h
│ ├── python
│ ├── interval.h
│ ├── relationship.h
│ ├── tristate.h
│ └── utils.h
│ └── utils.h
├── lib
└── SConscript
├── misc
└── makeHilbertLuts.py
├── pyproject.toml
├── python
└── lsst
│ ├── __init__.py
│ └── sphgeom
│ ├── CMakeLists.txt
│ ├── SConscript
│ ├── __init__.py
│ ├── _angle.cc
│ ├── _angleInterval.cc
│ ├── _box.cc
│ ├── _box3d.cc
│ ├── _chunker.cc
│ ├── _circle.cc
│ ├── _compoundRegion.cc
│ ├── _continue_class.py
│ ├── _convexPolygon.cc
│ ├── _curve.cc
│ ├── _ellipse.cc
│ ├── _healpixPixelization.py
│ ├── _htmPixelization.cc
│ ├── _interval1d.cc
│ ├── _lonLat.cc
│ ├── _matrix3d.cc
│ ├── _mq3cPixelization.cc
│ ├── _normalizedAngle.cc
│ ├── _normalizedAngleInterval.cc
│ ├── _orientation.cc
│ ├── _pixelization.cc
│ ├── _q3cPixelization.cc
│ ├── _rangeSet.cc
│ ├── _region.cc
│ ├── _relationship.cc
│ ├── _sphgeom.cc
│ ├── _unitVector3d.cc
│ ├── _utils.cc
│ ├── _vector3d.cc
│ ├── _yaml.py
│ ├── pixelization_abc.py
│ └── version.cmake
├── setup.cfg
├── setup.py
├── src
├── Angle.cc
├── AngleInterval.cc
├── BigInteger.cc
├── Box.cc
├── Box3d.cc
├── CMakeLists.txt
├── Chunker.cc
├── Circle.cc
├── CompoundRegion.cc
├── ConvexPolygon.cc
├── ConvexPolygonImpl.h
├── Ellipse.cc
├── HtmPixelization.cc
├── Interval1d.cc
├── LonLat.cc
├── Matrix3d.cc
├── Mq3cPixelization.cc
├── NormalizedAngle.cc
├── NormalizedAngleInterval.cc
├── PixelFinder.h
├── Q3cPixelization.cc
├── Q3cPixelizationImpl.h
├── RangeSet.cc
├── Region.cc
├── UnitVector3d.cc
├── Vector3d.cc
├── base64.hpp
├── orientation.cc
└── utils.cc
├── tests
├── CMakeLists.txt
├── SConscript
├── relationshipTestUtils.h
├── test.h
├── testAngle.cc
├── testAngleInterval.cc
├── testBigInteger.cc
├── testBox.cc
├── testBox3d.cc
├── testChunker.cc
├── testCircle.cc
├── testConvexPolygon.cc
├── testCurve.cc
├── testEllipse.cc
├── testHtmPixelization.cc
├── testInterval1d.cc
├── testLonLat.cc
├── testMatrix3d.cc
├── testMq3cPixelization.cc
├── testNormalizedAngle.cc
├── testNormalizedAngleInterval.cc
├── testOrientation.cc
├── testQ3cPixelization.cc
├── testRangeSet.cc
├── testUnitVector3d.cc
├── testVector3d.cc
├── test_Angle.py
├── test_AngleIntervals.py
├── test_Box.py
├── test_Box3d.py
├── test_Chunker.py
├── test_Circle.py
├── test_CompoundRegion.py
├── test_ConvexPolygon.py
├── test_Ellipse.py
├── test_HealpixPixelization.py
├── test_HtmPixelization.py
├── test_Interval1d.py
├── test_LonLat.py
├── test_Matrix3d.py
├── test_Mq3cPixelization.py
├── test_NormalizedAngle.py
├── test_Q3cPixelization.py
├── test_RangeSet.py
├── test_UnitVector3d.py
├── test_Vector3d.py
└── test_ivoa.py
└── ups
├── sphgeom.build
├── sphgeom.cfg
└── sphgeom.table
/.git-blame-ignore-revs:
--------------------------------------------------------------------------------
1 | # Reformat code with isort/black
2 | 4b97dad9311110ee7a3d30332af50242053bd543
3 |
--------------------------------------------------------------------------------
/.github/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ## Checklist
2 |
3 | - [ ] ran Jenkins
4 | - [ ] added a release note for user-visible changes to `doc/changes`
5 |
--------------------------------------------------------------------------------
/.github/workflows/cmake.yaml:
--------------------------------------------------------------------------------
1 | name: cmake
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request:
8 |
9 | jobs:
10 | cmake:
11 | runs-on: ubuntu-latest
12 | steps:
13 | - uses: actions/checkout@v4
14 | with:
15 | # Need to clone everything to determine version from git.
16 | fetch-depth: 0
17 |
18 | - name: Set up Python
19 | uses: actions/setup-python@v5
20 | with:
21 | python-version: "3.12"
22 |
23 | - name: Update Python packages
24 | run: pip install --upgrade setuptools
25 |
26 | - name: Install Python prereqs
27 | run: |
28 | pip install \
29 | numpy \
30 | pybind11[global] \
31 | pytest \
32 | pyyaml \
33 | hpgeom
34 |
35 | - name: CMake configure
36 | run: |
37 | cmake \
38 | -DCMAKE_INSTALL_PREFIX=${{github.workspace}}/build/install \
39 | -B ${{github.workspace}}/build
40 |
41 | - name: CMake build
42 | run: cmake --build ${{github.workspace}}/build --parallel `nproc`
43 |
44 | - name: CMake test
45 | working-directory: ${{github.workspace}}/build
46 | run: ctest
47 |
48 | - name: CMake install
49 | run: cmake --build ${{github.workspace}}/build --target install
50 |
51 | - name: Python tests
52 | env:
53 | PYTHONPATH: ${{github.workspace}}/build/install/python
54 | LD_LIBRARY_PATH: ${{github.workspace}}/build/install/lib
55 | run: pytest -r a -v
56 |
--------------------------------------------------------------------------------
/.github/workflows/docstyle.yaml:
--------------------------------------------------------------------------------
1 | name: Run docstyle
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request:
8 |
9 | jobs:
10 | call-workflow:
11 | uses: lsst/rubin_workflows/.github/workflows/docstyle.yaml@main
12 | with:
13 | args: "python/lsst/sphgeom/"
14 |
--------------------------------------------------------------------------------
/.github/workflows/formatting.yaml:
--------------------------------------------------------------------------------
1 | name: Check Python formatting
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request:
8 |
9 | jobs:
10 | call-workflow:
11 | uses: lsst/rubin_workflows/.github/workflows/formatting.yaml@main
12 |
--------------------------------------------------------------------------------
/.github/workflows/lint.yaml:
--------------------------------------------------------------------------------
1 | name: lint
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request:
8 |
9 | jobs:
10 | call-workflow:
11 | uses: lsst/rubin_workflows/.github/workflows/lint.yaml@main
12 | ruff:
13 | runs-on: ubuntu-latest
14 | steps:
15 | - uses: actions/checkout@v4
16 | - uses: chartboost/ruff-action@v1
17 |
--------------------------------------------------------------------------------
/.github/workflows/rebase_checker.yaml:
--------------------------------------------------------------------------------
1 | name: Check that 'main' is not merged into the development branch
2 |
3 | on: pull_request
4 |
5 | jobs:
6 | call-workflow:
7 | uses: lsst/rubin_workflows/.github/workflows/rebase_checker.yaml@main
8 |
--------------------------------------------------------------------------------
/.github/workflows/yamllint.yaml:
--------------------------------------------------------------------------------
1 | name: Lint YAML Files
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 | pull_request:
8 |
9 | jobs:
10 | call-workflow:
11 | uses: lsst/rubin_workflows/.github/workflows/yamllint.yaml@main
12 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *.dylib
2 | *.o
3 | *.os
4 | *.pyc
5 | *.so
6 | *~
7 | _build.*
8 | core.*
9 | .sconf_temp
10 | .sconsign.dblite
11 | .cache
12 | .pytest_cache
13 | pytest_session.txt
14 | .coverage
15 | config.log
16 | doc/doxygen.conf
17 | doc/html
18 | doc/xml
19 | doc/*.tag
20 | python/lsst/sphgeom/version.py
21 | tests/.tests/
22 | tests/testAngleInterval
23 | tests/testAngle
24 | tests/testBigInteger
25 | tests/testBox
26 | tests/testBox3d
27 | tests/testChunker
28 | tests/testCircle
29 | tests/testConvexPolygon
30 | tests/testCurve
31 | tests/testEllipse
32 | tests/testHtmPixelization
33 | tests/testInterval1d
34 | tests/testLonLat
35 | tests/testMatrix3d
36 | tests/testMq3cPixelization
37 | tests/testNormalizedAngleInterval
38 | tests/testNormalizedAngle
39 | tests/testOrientation
40 | tests/testQ3cPixelization
41 | tests/testRangeSet
42 | tests/testUnitVector3d
43 | tests/testVector3d
44 | tests/.cache/*
45 | ups/*.cfgc
46 | build/
47 | .eggs/
48 | *.egg-info/
49 | python/*.dist-info/
50 |
--------------------------------------------------------------------------------
/.pre-commit-config.yaml:
--------------------------------------------------------------------------------
1 | repos:
2 | - repo: https://github.com/pre-commit/pre-commit-hooks
3 | rev: v5.0.0
4 | hooks:
5 | - id: check-yaml
6 | args:
7 | - "--unsafe"
8 | - id: end-of-file-fixer
9 | - id: trailing-whitespace
10 | - id: check-toml
11 | - repo: https://github.com/astral-sh/ruff-pre-commit
12 | # Ruff version.
13 | rev: v0.9.6
14 | hooks:
15 | - id: ruff
16 | args: [--fix]
17 | - id: ruff-format
18 |
--------------------------------------------------------------------------------
/.yamllint.yaml:
--------------------------------------------------------------------------------
1 | extends: default
2 |
3 | rules:
4 | document-start: {present: false}
5 | line-length:
6 | max: 132
7 | allow-non-breakable-words: true
8 | allow-non-breakable-inline-mappings: true
9 | ignore: |
10 | /.github/workflows/lint.yaml
11 | truthy:
12 | # "on" as a key in workflows confuses things
13 | ignore: |
14 | /.github/workflows/
15 | indentation:
16 | indent-sequences: consistent
17 |
--------------------------------------------------------------------------------
/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | cmake_minimum_required(VERSION 3.1)
2 | project(sphgeom)
3 |
4 | enable_testing()
5 |
6 | add_subdirectory(python/lsst/sphgeom)
7 | add_subdirectory(src)
8 | add_subdirectory(tests)
9 |
--------------------------------------------------------------------------------
/COPYRIGHT:
--------------------------------------------------------------------------------
1 | Copyright 2019-2024 Association of Universities for Research in Astronomy, Inc. (AURA)
2 | Copyright 2015, 2018, 2020-2023 The Board of Trustees of the Leland Stanford Junior University, through SLAC National Accelerator Laboratory
3 | Copyright 2015-2017, 2021-2022 California Institute of Technology
4 | Copyright 2018-2019, 2021-2022 The Trustees of Princeton University
5 | Copyright 2016-2018 University of Washington
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | This software is dual licensed under the GNU General Public License and also
2 | under a 3-clause BSD license. Recipients may choose which of these licenses
3 | to use; please see the files gpl-3.0.txt and/or bsd_license.txt, respectively.
4 |
--------------------------------------------------------------------------------
/MANIFEST.in:
--------------------------------------------------------------------------------
1 | include LICENSE
2 | include README.md
3 | recursive-include include *.h
4 | recursive-include src *.h *.hpp
5 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | sphgeom: spherical geometry primitives
2 | ======================================
3 |
4 | Overview
5 | --------
6 |
7 | This low-level C++ library provides primitives for representing points and
8 | regions on the unit sphere, as well as support for partitioning the sphere.
9 | It can be used to answer the following sorts of questions:
10 |
11 | - *Is point X inside region Y?*
12 | - *Do two regions A and B intersect?*
13 | - *Which pieces of the sphere does region C overlap?*
14 |
15 | Regions can be serialized to binary strings, so that they may be stored
16 | efficiently in files or VARBINARY database columns. They can also be
17 | approximated with simpler regions - for example, one can ask for the
18 | bounding circle of a convex polygon.
19 |
20 | Python bindings that expose most of the C++ API are also provided via
21 | [pybind11](https://pybind11.readthedocs.io/).
22 |
23 | Points
24 | ------
25 |
26 | There are 3 different classes for points
27 |
28 | - *LonLat* for spherical coordinates,
29 | - *Vector3d* for Cartesian vectors in ℝ³ (not constrained to lie on the unit sphere)
30 | - *UnitVector3d* for vectors in ℝ³ with unit ℓ² norm.
31 |
32 | Regions
33 | -------
34 |
35 | Four basic spherical *Region* types are
36 | provided:
37 |
38 | - *Box*, a longitude/latitude angle box
39 | - *Circle*, a small circle defined by a center and opening angle/chord length
40 | - *Ellipse*, the intersection of an elliptical cone with the unit sphere
41 | - *ConvexPolygon*, a convex spherical polygon with unit vector vertices and great circle edges
42 |
43 | In addition to the spherical regions, there is a type for 3-D axis aligned
44 | boxes, *Box3d*. All spherical regions know how
45 | to compute their 3-D bounding boxes, which makes it possible to insert them
46 | into a 3-D [R-tree](https://en.wikipedia.org/wiki/R-tree). This is used by the
47 | exposure indexing task in the [daf_ingest](https://github.com/lsst/daf_ingest)
48 | package to spatially index exposure bounding polygons using the
49 | [SQLite](https://sqlite.org) 3
50 | [R*tree module](https://www.sqlite.org/rtree.html).
51 |
52 | A region can also determine its spatial
53 | relationship to another region, and
54 | test whether or not it contains a given unit vector.
55 |
56 | Pixelizations
57 | -------------
58 |
59 | This library also provides support for assigning points to pixels (a.k.a.
60 | cells or partitions) in a *Pixelization*
61 | (a.k.a. partitioning) of the sphere, and for determining which pixels
62 | intersect a region.
63 |
64 | Currently, the *Chunker* class implements
65 | the partitioning scheme employed by [Qserv](https://github.com/lsst/qserv).
66 | The *HtmPixelization* class implements
67 | the HTM (Hierarchical Triangular Mesh) pixelization. The
68 | *Q3cPixelization* and *Mq3cPixelization* classes implement
69 | the original Quad Tree Cube indexing scheme and a modified version with
70 | reduced pixel area variation.
71 |
72 | Installing with pip
73 | -------------------
74 |
75 | A simple pip-compatible installer is available. This only installs the
76 | Python bindings and the resulting installation is not usable for linking
77 | from C++. Some metadata (in particular the version number) are not set
78 | properly for the distribution. The main purpose for now is to allow
79 | other packages to pip install from the GitHub URL in their CI systems
80 | where sphgeom is a dependency.
81 |
82 | See Also
83 | --------
84 |
85 | #### Contributing
86 |
87 | For instructions on how to contribute, see http://dm.lsst.org/#contributing
88 | (or just send us a pull request).
89 |
90 | #### Support
91 |
92 | For help, see http://dm.lsst.org/#support.
93 |
--------------------------------------------------------------------------------
/SConstruct:
--------------------------------------------------------------------------------
1 | from lsst.sconsUtils import scripts
2 | scripts.BasicSConstruct("sphgeom")
3 |
--------------------------------------------------------------------------------
/bsd_license.txt:
--------------------------------------------------------------------------------
1 | For copyright information see the COPYRIGHT file included in the top-level
2 | directory of this distribution.
3 |
4 | Redistribution and use in source and binary forms, with or without modification,
5 | are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice,
8 | this list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright
11 | notice, this list of conditions and the following disclaimer in the
12 | documentation and/or other materials provided with the distribution.
13 |
14 | 3. Neither the names of the copyright holders nor the names of their
15 | contributors may be used to endorse or promote products derived from
16 | this software without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE
22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
--------------------------------------------------------------------------------
/doc/SConscript:
--------------------------------------------------------------------------------
1 | from lsst.sconsUtils import scripts
2 | scripts.BasicSConscript.doc()
3 |
--------------------------------------------------------------------------------
/doc/doxygen.conf.in:
--------------------------------------------------------------------------------
1 | FILE_PATTERNS += *.md
2 | INPUT += README.md
3 |
--------------------------------------------------------------------------------
/doc/htm.md:
--------------------------------------------------------------------------------
1 | HTM Indexing
2 | ============
3 |
4 | Overview {#htm-overview}
5 | ========
6 |
7 | The Hierarchical Triangular Mesh (HTM) is described in the work of A. Szalay,
8 | T. Budavari, G. Fekete at The Johns Hopkins University, and Jim Gray,
9 | Microsoft Research. See in particular the following paper:
10 |
11 | > "Indexing the Sphere with the Hierarchical Triangular Mesh"
12 | > Szalay, Alexander S.; Gray, Jim; Fekete, George; Kunszt, Peter Z.;
13 | > Kukol, Peter; Thakar, Ani
14 | > 2007, Arxiv e-prints
15 | >
16 | > http://arxiv.org/abs/cs/0701164
17 | > http://adsabs.harvard.edu/abs/2007cs........1164S
18 |
19 | To summarize very briefly: HTM partitions the unit sphere into 8 root triangles
20 | by splitting it with the planes x = 0, y = 0, and z = 0. A triangle is subdivided
21 | into 4 children by connecting the midpoints of its edges with geodesics, and each
22 | root triangle is recursively subdivided to a fixed subdivision level to obtain a
23 | pixelization of the sphere. The root triangles are assigned indexes 8-15, and the
24 | children of a triangle with index I are assigned indexes [4*I, 4*I + 4).
25 |
26 | Further References {#htm-references}
27 | ==================
28 |
29 | > Budavári, Tamás; Szalay, Alexander S.; Fekete, György
30 | > "Searchable Sky Coverage of Astronomical Observations:
31 | > Footprints and Exposures"
32 | > Publications of the Astronomical Society of Pacific,
33 | > Volume 122, Issue 897, pp. 1375-1388 (2010).
34 | >
35 | > http://adsabs.harvard.edu/abs/2010PASP..122.1375B
36 |
37 | > http://voservices.net/spherical/
38 |
--------------------------------------------------------------------------------
/include/lsst/sphgeom/AngleInterval.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | #ifndef LSST_SPHGEOM_ANGLEINTERVAL_H_
31 | #define LSST_SPHGEOM_ANGLEINTERVAL_H_
32 |
33 | /// \file
34 | /// \brief This file defines a class for representing angle intervals.
35 |
36 | #include
37 | #include
38 |
39 | #include "Angle.h"
40 | #include "Interval.h"
41 |
42 |
43 | namespace lsst {
44 | namespace sphgeom {
45 |
46 | /// `AngleInterval` represents closed intervals of arbitrary angles.
47 | class AngleInterval : public Interval {
48 | typedef Interval Base;
49 | public:
50 | // Factory functions
51 | static AngleInterval fromDegrees(double x, double y) {
52 | return AngleInterval(Angle::fromDegrees(x),
53 | Angle::fromDegrees(y));
54 | }
55 |
56 | static AngleInterval fromRadians(double x, double y) {
57 | return AngleInterval(Angle::fromRadians(x),
58 | Angle::fromRadians(y));
59 | }
60 |
61 | static AngleInterval empty() {
62 | return AngleInterval();
63 | }
64 |
65 | static AngleInterval full() {
66 | return AngleInterval(Angle(-std::numeric_limits::infinity()),
67 | Angle(std::numeric_limits::infinity()));
68 | }
69 |
70 | // Delegation to base class constructors
71 | AngleInterval() : Base() {}
72 |
73 | explicit AngleInterval(Angle x) : Base(x) {}
74 |
75 | AngleInterval(Angle x, Angle y) : Base(x, y) {}
76 |
77 | AngleInterval(Base const & base) : Base(base) {}
78 | };
79 |
80 | std::ostream & operator<<(std::ostream &, AngleInterval const &);
81 |
82 | }} // namespace lsst::sphgeom
83 |
84 | #endif // LSST_SPHGEOM_ANGLEINTERVAL_H_
85 |
--------------------------------------------------------------------------------
/include/lsst/sphgeom/HtmPixelization.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | #ifndef LSST_SPHGEOM_HTMPIXELIZATION_H_
31 | #define LSST_SPHGEOM_HTMPIXELIZATION_H_
32 |
33 | /// \file
34 | /// \brief This file declares a Pixelization subclass for the HTM
35 | /// indexing scheme.
36 |
37 | #include
38 | #include
39 |
40 | #include "ConvexPolygon.h"
41 | #include "Pixelization.h"
42 |
43 |
44 | namespace lsst {
45 | namespace sphgeom {
46 |
47 | /// `HtmPixelization` provides [HTM indexing](\ref htm-overview) of points
48 | /// and regions.
49 | ///
50 | /// Instances of this class are immutable and very cheap to copy.
51 | ///
52 | /// \warning Setting the `maxRanges` argument for envelope() or interior() to
53 | /// a non-zero value below 6 can result in very poor region pixelizations
54 | /// regardless of region size. For instance, if `maxRanges` is 1, a non-empty
55 | /// circle centered on an axis will be approximated by a hemisphere or the
56 | /// entire unit sphere, even as its radius tends to 0.
57 | class HtmPixelization : public Pixelization {
58 | public:
59 | /// `MAX_LEVEL` is the maximum supported HTM subdivision level.
60 | static constexpr int MAX_LEVEL = 24;
61 |
62 | /// `level` returns the subdivision level of the given HTM index.
63 | ///
64 | /// If i is not a valid HTM index, -1 is returned.
65 | static int level(std::uint64_t i);
66 |
67 | /// `triangle` returns the triangle corresponding to the given HTM index.
68 | ///
69 | /// If i is not a valid HTM index, a std::invalid_argument is thrown.
70 | static ConvexPolygon triangle(std::uint64_t i);
71 |
72 | /// `asString` converts the given HTM index to a human readable string.
73 | ///
74 | /// The first character in the return value is always 'N' or 'S',
75 | /// indicating whether the root triangle containing `i` is in the northern
76 | /// or southern hemisphere. The second character is the index of the root
77 | /// triangle within that hemisphere (a digit in [0-3]). Each subsequent
78 | /// character is a digit in [0-3] corresponding to a child trixel index,
79 | /// so that reading the string from left to right corresponds to descent
80 | /// of the HTM triangle-tree.
81 | ///
82 | /// If i is not a valid HTM index, a std::invalid_argument is thrown.
83 | static std::string asString(std::uint64_t i);
84 |
85 | /// This constructor creates an HTM pixelization of the sphere with
86 | /// the given subdivision level. If `level` ∉ [0, MAX_LEVEL],
87 | /// a std::invalid_argument is thrown.
88 | explicit HtmPixelization(int level);
89 |
90 | /// `getLevel` returns the subdivision level of this pixelization.
91 | int getLevel() const { return _level; }
92 |
93 | RangeSet universe() const override {
94 | return RangeSet(static_cast(8) << 2 * _level,
95 | static_cast(16) << 2 * _level);
96 | }
97 |
98 | std::unique_ptr pixel(std::uint64_t i) const override {
99 | return std::unique_ptr(new ConvexPolygon(triangle(i)));
100 | }
101 |
102 | std::uint64_t index(UnitVector3d const &) const override;
103 |
104 | std::string toString(std::uint64_t i) const override { return asString(i); }
105 |
106 | private:
107 | int _level;
108 |
109 | RangeSet _envelope(Region const &, size_t) const override;
110 | RangeSet _interior(Region const &, size_t) const override;
111 | };
112 |
113 | }} // namespace lsst::sphgeom
114 |
115 | #endif // LSST_SPHGEOM_HTMPIXELIZATION_H_
116 |
--------------------------------------------------------------------------------
/include/lsst/sphgeom/Interval1d.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | #ifndef LSST_SPHGEOM_INTERVAL1D_H_
31 | #define LSST_SPHGEOM_INTERVAL1D_H_
32 |
33 | /// \file
34 | /// \brief This file defines a class for representing intervals of ℝ.
35 |
36 | #include
37 | #include
38 |
39 | #include "Interval.h"
40 |
41 |
42 | namespace lsst {
43 | namespace sphgeom {
44 |
45 | /// `Interval1d` represents closed intervals of ℝ. It can represent
46 | /// both empty and full intervals, as well as single points.
47 | class Interval1d : public Interval {
48 | typedef Interval Base;
49 | public:
50 |
51 | static Interval1d empty() {
52 | return Interval1d();
53 | }
54 |
55 | static Interval1d full() {
56 | return Interval1d(-std::numeric_limits::infinity(),
57 | std::numeric_limits::infinity());
58 | }
59 |
60 | // Delegation to base class constructors
61 | Interval1d() : Base() {}
62 |
63 | explicit Interval1d(double x) : Base(x) {}
64 |
65 | Interval1d(double x, double y) : Base(x, y) {}
66 |
67 | Interval1d(Base const & base) : Base(base) {}
68 |
69 | /// `isFull` returns true if this interval = ℝ.
70 | bool isFull() const {
71 | return getA() == -std::numeric_limits::infinity() &&
72 | getB() == std::numeric_limits::infinity();
73 | }
74 | };
75 |
76 | std::ostream & operator<<(std::ostream &, Interval1d const &);
77 |
78 | }} // namespace lsst::sphgeom
79 |
80 | #endif // LSST_SPHGEOM_INTERVAL1D_H_
81 |
--------------------------------------------------------------------------------
/include/lsst/sphgeom/LonLat.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | #ifndef LSST_SPHGEOM_LONLAT_H_
31 | #define LSST_SPHGEOM_LONLAT_H_
32 |
33 | /// \file
34 | /// \brief This file contains a class representing spherical coordinates.
35 |
36 | #include
37 | #include
38 |
39 | #include "NormalizedAngle.h"
40 |
41 |
42 | namespace lsst{
43 | namespace sphgeom {
44 |
45 | class Vector3d;
46 |
47 | /// `LonLat` represents a spherical coordinate (longitude/latitude angle) pair.
48 | ///
49 | /// This class supports conversion from a `Vector3d`. All methods that accept a
50 | /// `Vector3d` parameter shall convert from vector to longitude/latitude
51 | /// coordinates according to the following conventions:
52 | /// * (1, 0, 0) → (0°, 0°)
53 | /// * (0, 1, 0) → (90°, 0°)
54 | /// * (0, 0, 1) → (0°, +90°)
55 | class LonLat {
56 | public:
57 | static LonLat fromDegrees(double lon, double lat) {
58 | return LonLat(NormalizedAngle::fromDegrees(lon),
59 | Angle::fromDegrees(lat));
60 | }
61 |
62 | static LonLat fromRadians(double lon, double lat) {
63 | return LonLat(NormalizedAngle::fromRadians(lon),
64 | Angle::fromRadians(lat));
65 | }
66 |
67 | /// `latitudeOf` returns the latitude of the point on the unit sphere
68 | /// corresponding to the direction of v.
69 | static Angle latitudeOf(Vector3d const & v);
70 |
71 | /// `longitudeOf` returns the longitude of the point on the unit sphere
72 | /// corresponding to the direction of v.
73 | static NormalizedAngle longitudeOf(Vector3d const & v);
74 |
75 | /// This constructor creates the point with longitude and latitude angle
76 | /// equal to zero.
77 | LonLat() {}
78 |
79 | /// This constructor creates the point with the given longitude and
80 | /// latitude angles.
81 | LonLat(NormalizedAngle lon, Angle lat);
82 |
83 | /// This constructor creates the point on the unit sphere corresponding
84 | /// to the direction of v.
85 | LonLat(Vector3d const & v);
86 |
87 | bool operator==(LonLat const & p) const {
88 | return _lon == p._lon && _lat == p._lat;
89 | }
90 |
91 | bool operator!=(LonLat const & p) const {
92 | return _lon != p._lon || _lat != p._lat;
93 | }
94 |
95 | NormalizedAngle getLon() const { return _lon; }
96 |
97 | Angle getLat() const { return _lat; }
98 |
99 | private:
100 | void _enforceInvariants();
101 |
102 | NormalizedAngle _lon;
103 | Angle _lat;
104 | };
105 |
106 | std::ostream & operator<<(std::ostream &, LonLat const &);
107 |
108 | }} // namespace lsst::sphgeom
109 |
110 | #endif // LSST_SPHGEOM_LONLAT_H_
111 |
--------------------------------------------------------------------------------
/include/lsst/sphgeom/Q3cPixelization.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | #ifndef LSST_SPHGEOM_Q3CPIXELIZATION_H_
31 | #define LSST_SPHGEOM_Q3CPIXELIZATION_H_
32 |
33 | /// \file
34 | /// \brief This file declares a Pixelization subclass for the Q3C indexing
35 | /// scheme.
36 |
37 | #include
38 | #include
39 |
40 | #include "ConvexPolygon.h"
41 | #include "Pixelization.h"
42 |
43 |
44 | namespace lsst {
45 | namespace sphgeom {
46 |
47 | /// `Q3cPixelization` provides [Q3C indexing](\ref q3c-original) of points
48 | /// and regions.
49 | ///
50 | /// Instances of this class are immutable and very cheap to copy.
51 | ///
52 | /// \warning Setting the `maxRanges` argument for envelope() or interior()
53 | /// to a non-zero value below 4 can result in very poor region pixelizations
54 | /// regardless of region size. For instance, if `maxRanges` is 1, a non-empty
55 | /// circle centered on an axis will be approximated by the indexes for an
56 | /// entire cube face, even as the circle radius tends to 0.
57 | class Q3cPixelization : public Pixelization {
58 | public:
59 | /// The maximum supported cube-face grid resolution is 2^30 by 2^30.
60 | static constexpr int MAX_LEVEL = 30;
61 |
62 | /// This constructor creates a Q3C pixelization of the sphere with
63 | /// the given subdivision level. If `level` ∉ [0, MAX_LEVEL],
64 | /// a std::invalid_argument is thrown.
65 | explicit Q3cPixelization(int level);
66 |
67 | /// `getLevel` returns the subdivision level of this pixelization.
68 | int getLevel() const { return _level; }
69 |
70 | /// `quad` returns the quadrilateral corresponding to the Q3C pixel with
71 | /// index `i`.
72 | ///
73 | /// If `i` is not a valid Q3C index, a std::invalid_argument is thrown.
74 | ConvexPolygon quad(std::uint64_t i) const;
75 |
76 | /// `neighborhood` returns the indexes of all pixels that share a vertex
77 | /// with pixel `i` (including `i` itself). A Q3C pixel has 8 - k adjacent
78 | /// pixels, where k is the number of vertices that are also root pixel
79 | /// vertices (0, 1, or 4).
80 | ///
81 | /// If `i` is not a valid Q3C index, a std::invalid_argument is thrown.
82 | std::vector neighborhood(std::uint64_t i) const;
83 |
84 | RangeSet universe() const override {
85 | return RangeSet(0, static_cast(6) << 2 * _level);
86 | }
87 |
88 | std::unique_ptr pixel(std::uint64_t i) const override;
89 |
90 | std::uint64_t index(UnitVector3d const & v) const override;
91 |
92 | /// `toString` converts the given Q3C index to a human readable string.
93 | ///
94 | /// The first two characters in the return value are always '+X', '+Y',
95 | /// '+Z', '-X', '-Y', or '-Z'. They give the normal vector of the cube
96 | /// face F containing `i`. Each subsequent character is a digit in [0-3]
97 | /// corresponding to a child pixel index, so that reading the string
98 | /// from left to right corresponds to descent of the quad-tree overlaid
99 | /// on F.
100 | ///
101 | /// If i is not a valid Q3C index, a std::invalid_argument is thrown.
102 | std::string toString(std::uint64_t i) const override;
103 |
104 | private:
105 | int _level;
106 |
107 | RangeSet _envelope(Region const & r, size_t maxRanges) const override;
108 | RangeSet _interior(Region const & r, size_t maxRanges) const override;
109 | };
110 |
111 | }} // namespace lsst::sphgeom
112 |
113 | #endif // LSST_SPHGEOM_Q3CPIXELIZATION_H_
114 |
--------------------------------------------------------------------------------
/include/lsst/sphgeom/Relationship.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | #ifndef LSST_SPHGEOM_RELATIONSHIP_H_
31 | #define LSST_SPHGEOM_RELATIONSHIP_H_
32 |
33 | #include
34 |
35 | /// \file
36 | /// \brief This file provides a type alias for describing set relationships.
37 |
38 | namespace lsst {
39 | namespace sphgeom {
40 |
41 | /// `Relationship` describes how two sets are related.
42 | using Relationship = std::bitset<3>;
43 |
44 | /// A is disjoint from B ⇔ A ⋂ B = ∅
45 | static constexpr Relationship DISJOINT(1);
46 |
47 | /// A intersects B ⇔ A ⋂ B ≠ ∅
48 | ///
49 | /// This is the complement of DISJOINT, hence no explicit
50 | /// bit is reserved for this relationship.
51 | static constexpr Relationship INTERSECTS(0);
52 |
53 | /// A contains B ⇔ A ⋂ B = B
54 | static constexpr Relationship CONTAINS(2);
55 |
56 | /// A is within B ⇔ A ⋂ B = A
57 | static constexpr Relationship WITHIN(4);
58 |
59 | /// Given the relationship between two sets A and B (i.e. the output of
60 | /// `A.relate(B)`), `invert` returns the relationship between B and A
61 | /// (`B.relate(A)`).
62 | inline Relationship invert(Relationship r) {
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 | }
67 |
68 | }} // namespace lsst::sphgeom
69 |
70 | #endif // LSST_SPHGEOM_RELATIONSHIP_H_
71 |
--------------------------------------------------------------------------------
/include/lsst/sphgeom/constants.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | #ifndef LSST_SPHGEOM_CONSTANTS_H_
31 | #define LSST_SPHGEOM_CONSTANTS_H_
32 |
33 | /// \file
34 | /// \brief This file contains common constants.
35 |
36 |
37 | namespace lsst {
38 | namespace sphgeom {
39 |
40 | // Note: given a compiler that does correctly rounded decimal to
41 | // binary floating point conversions, PI = 0x1.921fb54442d18p1 in
42 | // IEEE double precision format. This is less than π.
43 | constexpr double PI = 3.1415926535897932384626433832795;
44 | constexpr double ONE_OVER_PI = 0.318309886183790671537767526745;
45 | constexpr double RAD_PER_DEG = 0.0174532925199432957692369076849;
46 | constexpr double DEG_PER_RAD = 57.2957795130823208767981548141;
47 |
48 | // The maximum error of std::asin in IEEE double precision arithmetic,
49 | // assuming 1 ulp of error in its argument, is about
50 | // π/2 - arcsin (1 - 2⁻⁵³), or a little less than 1.5e-8 radians
51 | // (3.1 milliarcsec).
52 | constexpr double MAX_ASIN_ERROR = 1.5e-8;
53 |
54 | // The computation of squared chord length between two unit vectors
55 | // involves 8 elementary operations on numbers with magnitude ≤ 4. Its
56 | // maximum error can be shown to be < 2.5e-15.
57 | constexpr double MAX_SQUARED_CHORD_LENGTH_ERROR = 2.5e-15;
58 |
59 | // The largest value ε such that 1 + ε rounds to 1 in IEEE double
60 | // precision, assuming round-to-nearest-ties-to-even rounding.
61 | constexpr double EPSILON = 1.1102230246251565e-16;
62 |
63 | }} // namespace lsst::sphgeom
64 |
65 | #endif // LSST_SPHGEOM_CONSTANTS_H_
66 |
--------------------------------------------------------------------------------
/include/lsst/sphgeom/orientation.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | #ifndef LSST_SPHGEOM_ORIENTATION_H_
31 | #define LSST_SPHGEOM_ORIENTATION_H_
32 |
33 | /// \file
34 | /// \brief This file declares functions for orienting points on the sphere.
35 |
36 | #include "UnitVector3d.h"
37 |
38 |
39 | namespace lsst {
40 | namespace sphgeom {
41 |
42 | /// `orientationExact` computes and returns the orientations of 3 vectors a, b
43 | /// and c, which need not be normalized but are assumed to have finite
44 | /// components. The return value is +1 if the vectors a, b, and c are in
45 | /// counter-clockwise orientation, 0 if they are coplanar, colinear, or
46 | /// identical, and -1 if they are in clockwise orientation. The implementation
47 | /// uses arbitrary precision arithmetic to avoid floating point rounding error,
48 | /// underflow and overflow.
49 | int orientationExact(Vector3d const & a,
50 | Vector3d const & b,
51 | Vector3d const & c);
52 |
53 | /// `orientation` computes and returns the orientations of 3 unit vectors
54 | /// a, b and c. The return value is +1 if the vectors are in counter-clockwise
55 | /// orientation, 0 if they are coplanar, colinear or identical, and -1 if
56 | /// they are in clockwise orientation.
57 | ///
58 | /// This is equivalent to computing the sign of the scalar triple product
59 | /// a · (b x c), which is the sign of the determinant of the 3x3 matrix with
60 | /// a, b and c as columns/rows.
61 | ///
62 | /// The implementation proceeds by first computing a double precision
63 | /// approximation, and then falling back to arbitrary precision arithmetic
64 | /// when necessary. Consequently, the result is exact.
65 | int orientation(UnitVector3d const & a,
66 | UnitVector3d const & b,
67 | UnitVector3d const & c);
68 |
69 | /// `orientationX(b, c)` is equivalent to `orientation(UnitVector3d::X(), b, c)`.
70 | int orientationX(UnitVector3d const & b, UnitVector3d const & c);
71 |
72 | /// `orientationY(b, c)` is equivalent to `orientation(UnitVector3d::Y(), b, c)`.
73 | int orientationY(UnitVector3d const & b, UnitVector3d const & c);
74 |
75 | /// `orientationZ(b, c)` is equivalent to `orientation(UnitVector3d::Z(), b, c)`.
76 | int orientationZ(UnitVector3d const & b, UnitVector3d const & c);
77 |
78 | }} // namespace lsst::sphgeom
79 |
80 | #endif // LSST_SPHGEOM_ORIENTATION_H_
81 |
--------------------------------------------------------------------------------
/include/lsst/sphgeom/python.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | #ifndef PYTHON_LSST_SPHGEOM_SPHGEOM_H
31 | #define PYTHON_LSST_SPHGEOM_SPHGEOM_H
32 |
33 | namespace lsst {
34 | namespace sphgeom {
35 |
36 | template
37 | void defineClass(Pybind11Class &cls);
38 |
39 | } // sphgeom
40 | } // lsst
41 |
42 | #endif // PYTHON_LSST_SPHGEOM_SPHGEOM_H
43 |
--------------------------------------------------------------------------------
/include/lsst/sphgeom/python/relationship.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | #ifndef LSST_SPHGEOM_PYTHON_RELATIONSHIP_H_
31 | #define LSST_SPHGEOM_PYTHON_RELATIONSHIP_H_
32 |
33 | #include "pybind11/pybind11.h"
34 |
35 | #include "../Relationship.h"
36 |
37 | namespace pybind11 {
38 | namespace detail {
39 |
40 | /// This struct is a partial specialization of type_caster for
41 | /// for lsst::sphgeom::Relationship.
42 | ///
43 | /// It maps between std::bitset<3> and Python integers, avoiding the need to
44 | /// wrap the former. This header should be included by all wrappers for
45 | /// functions that consume or return Relationship instances.
46 | template <>
47 | struct type_caster {
48 | public:
49 | // Declare a local variable `value` of type lsst::sphgeom::Relationship,
50 | // and describe the Relationship type as an "int" in pybind11-generated
51 | // docstrings.
52 | PYBIND11_TYPE_CASTER(lsst::sphgeom::Relationship, _("int"));
53 |
54 | // Convert a Python object to an lsst::sphgeom::Relationship.
55 | bool load(handle src, bool) {
56 | value = lsst::sphgeom::Relationship(src.cast());
57 | return true;
58 | }
59 |
60 | // Convert an lsst::sphgeom::Relationship to a Python integer.
61 | static handle cast(lsst::sphgeom::Relationship src, return_value_policy,
62 | handle) {
63 | return PyLong_FromUnsignedLong(src.to_ulong());
64 | }
65 | };
66 |
67 | } // detail
68 | } // pybind11
69 |
70 | #endif // LSST_SPHGEOM_PYTHON_RELATIONSHIP_H_
71 |
--------------------------------------------------------------------------------
/include/lsst/sphgeom/python/tristate.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | #ifndef LSST_SPHGEOM_PYTHON_TRISTATE_H_
31 | #define LSST_SPHGEOM_PYTHON_TRISTATE_H_
32 |
33 | #include "pybind11/pybind11.h"
34 |
35 | #include "../TriState.h"
36 |
37 | namespace pybind11 {
38 | namespace detail {
39 |
40 | /// This struct is a partial specialization of type_caster for
41 | /// for lsst::sphgeom::TriState.
42 | ///
43 | /// It maps between TriState and Python bool or None, avoiding the need to
44 | /// wrap the former. This header should be included by all wrappers for
45 | /// functions that consume or return TriState instances.
46 | template <>
47 | struct type_caster {
48 | public:
49 | // Declare a local variable `value` of type lsst::sphgeom::TriState,
50 | // and describe the TriState type as an "bool | None" in pybind11-generated
51 | // docstrings.
52 | PYBIND11_TYPE_CASTER(lsst::sphgeom::TriState, _("bool | None"));
53 |
54 | // Convert a Python object to an lsst::sphgeom::TriState.
55 | bool load(handle src, bool) {
56 | if (src.is_none()) {
57 | value = lsst::sphgeom::TriState();
58 | } else {
59 | value = lsst::sphgeom::TriState(src.cast());
60 | }
61 | return true;
62 | }
63 |
64 | // Convert an lsst::sphgeom::TriState to a Python integer.
65 | static handle cast(lsst::sphgeom::TriState src, return_value_policy,
66 | handle) {
67 |
68 | if (src == true) {
69 | Py_RETURN_TRUE;
70 | } else if (src == false) {
71 | Py_RETURN_FALSE;
72 | }
73 | Py_RETURN_NONE;
74 | }
75 | };
76 |
77 | } // detail
78 | } // pybind11
79 |
80 | #endif // LSST_SPHGEOM_PYTHON_TRISTATE_H_
81 |
--------------------------------------------------------------------------------
/include/lsst/sphgeom/python/utils.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | #ifndef LSST_SPHGEOM_PYTHON_UTILS_H_
31 | #define LSST_SPHGEOM_PYTHON_UTILS_H_
32 |
33 | #include "pybind11/pybind11.h"
34 |
35 | #include
36 | #include
37 | #include
38 | #include
39 |
40 | #include "lsst/sphgeom/Region.h"
41 |
42 | namespace lsst {
43 | namespace sphgeom {
44 | namespace python {
45 |
46 | /// Convert a Python index `i` over a sequence with length `len` to a
47 | /// non-negative (C++ style) index, and perform a bounds-check.
48 | inline ptrdiff_t convertIndex(ptrdiff_t len, pybind11::int_ i) {
49 | auto j = static_cast(i);
50 | if ((j == -1 && PyErr_Occurred()) || j < -len || j >= len) {
51 | PyErr_Clear();
52 | throw pybind11::index_error(
53 | pybind11::str("Index {} not in range({}, {})")
54 | .format(i, -len, len));
55 | }
56 | return (j < 0) ? j + len : j;
57 | }
58 |
59 |
60 | /// Encode a Region as a pybind11 bytes object
61 | inline pybind11::bytes encode(Region const &self) {
62 | std::vector bytes = self.encode();
63 | return pybind11::bytes(reinterpret_cast(bytes.data()),
64 | bytes.size());
65 | }
66 |
67 | /// Decode a Region from a pybind11 bytes object.
68 | template
69 | std::unique_ptr decode(pybind11::bytes bytes) {
70 | std::uint8_t const *buffer = reinterpret_cast(
71 | PYBIND11_BYTES_AS_STRING(bytes.ptr()));
72 | size_t n = static_cast(PYBIND11_BYTES_SIZE(bytes.ptr()));
73 | return R::decode(buffer, n);
74 | }
75 |
76 | /// Create a vector of Region (or Region-subclass) pointers by copying the
77 | /// regions from a sized Python iterable (e.g. S == py::tuple).
78 | ///
79 | /// Note that the pybind11 built-in STL conversions don't work, because they
80 | /// use unique_ptr - we can't transfer ownership out of Python, and those
81 | /// converters don't know about our clone methods.
82 | template
83 | inline std::vector> convert_region_sequence(S const & seq) {
84 | std::vector> result;
85 | result.reserve(seq.size());
86 | for (pybind11::handle py_region : seq) {
87 | result.push_back(py_region.cast().clone());
88 | }
89 | return result;
90 | }
91 |
92 | } // python
93 | } // sphgeom
94 | } // lsst
95 |
96 | #endif // LSST_SPHGEOM_PYTHON_UTILS_H_
97 |
--------------------------------------------------------------------------------
/include/lsst/sphgeom/utils.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | #ifndef LSST_SPHGEOM_UTILS_H_
31 | #define LSST_SPHGEOM_UTILS_H_
32 |
33 | /// \file
34 | /// \brief This file declares miscellaneous utility functions.
35 |
36 | #include "Angle.h"
37 |
38 |
39 | namespace lsst {
40 | namespace sphgeom {
41 |
42 | // Forward declarations
43 | class Vector3d;
44 | class UnitVector3d;
45 |
46 | /// Let p be the unit vector closest to v that lies on the plane with
47 | /// normal n in the direction of the cross product of a and b. If p is in the
48 | /// interior of the great circle segment from a to b, then this function
49 | /// returns the squared chord length between p and v. Otherwise it returns 4 -
50 | /// the maximum squared chord length between any pair of points on the unit
51 | /// sphere.
52 | double getMinSquaredChordLength(Vector3d const & v,
53 | Vector3d const & a,
54 | Vector3d const & b,
55 | Vector3d const & n);
56 |
57 | /// Let p be the unit vector furthest from v that lies on the plane with
58 | /// normal n in the direction of the cross product of a and b. If p is in the
59 | /// interior of the great circle segment from a to b, then this helper function
60 | /// returns the squared chord length between p and v. Otherwise it returns 0 -
61 | /// the minimum squared chord length between any pair of points on the sphere.
62 | double getMaxSquaredChordLength(Vector3d const & v,
63 | Vector3d const & a,
64 | Vector3d const & b,
65 | Vector3d const & n);
66 |
67 | /// `getMinAngleToCircle` returns the minimum angular separation between a
68 | /// point at latitude x and the points on the circle of constant latitude c.
69 | inline Angle getMinAngleToCircle(Angle x, Angle c) {
70 | return abs(x - c);
71 | }
72 |
73 | /// `getMaxAngleToCircle` returns the maximum angular separation between a
74 | /// point at latitude x and the points on the circle of constant latitude c.
75 | inline Angle getMaxAngleToCircle(Angle x, Angle c) {
76 | Angle a = getMinAngleToCircle(x, c);
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 | }
85 |
86 | /// `getWeightedCentroid` returns the center of mass of the given spherical
87 | /// triangle (assuming a uniform mass distribution over the triangle surface),
88 | /// weighted by the triangle area.
89 | Vector3d getWeightedCentroid(UnitVector3d const & v0,
90 | UnitVector3d const & v1,
91 | UnitVector3d const & v2);
92 |
93 | }} // namespace lsst::sphgeom
94 |
95 | #endif // LSST_SPHGEOM_UTILS_H_
96 |
--------------------------------------------------------------------------------
/lib/SConscript:
--------------------------------------------------------------------------------
1 | from lsst.sconsUtils import scripts
2 | scripts.BasicSConscript.lib()
3 |
--------------------------------------------------------------------------------
/pyproject.toml:
--------------------------------------------------------------------------------
1 | [build-system]
2 | requires = [
3 | "setuptools",
4 | "lsst-versions >= 1.3.0",
5 | "wheel",
6 | "pybind11 >= 2.5.0",
7 | "numpy >= 1.18",
8 | ]
9 | build-backend = "setuptools.build_meta"
10 |
11 | [project]
12 | name = "lsst-sphgeom"
13 | description = "A spherical geometry library."
14 | requires-python = ">=3.10.0"
15 | license = {text = "BSD 3-Clause License"}
16 | readme = "README.md"
17 | authors = [
18 | {name="Rubin Observatory Data Management", email="dm-admin@lists.lsst.org"},
19 | ]
20 | classifiers = [
21 | "Intended Audience :: Science/Research",
22 | "License :: OSI Approved :: BSD License",
23 | "Operating System :: POSIX :: Linux",
24 | "Operating System :: MacOS :: MacOS X",
25 | "Programming Language :: Python :: 3",
26 | "Programming Language :: Python :: 3.10",
27 | "Programming Language :: Python :: 3.11",
28 | "Programming Language :: Python :: 3.12",
29 | "Programming Language :: Python :: 3.13",
30 | "Topic :: Scientific/Engineering :: Astronomy",
31 | ]
32 | keywords = ["lsst"]
33 | dependencies = [
34 | "numpy >=1.18",
35 | "hpgeom >=0.8.0"
36 | ]
37 | dynamic = ["version"]
38 |
39 | [project.urls]
40 | "Homepage" = "https://github.com/lsst/sphgeom"
41 |
42 | [project.optional-dependencies]
43 | test = [
44 | "pytest >= 3.2",
45 | ]
46 | yaml = ["pyyaml >= 5.1"]
47 |
48 | [tool.setuptools.packages.find]
49 | where = ["python"]
50 |
51 | [tool.setuptools]
52 | zip-safe = false
53 | license-files = ["COPYRIGHT", "LICENSE", "bsd_license.txt", "gpl-v3.0.txt"]
54 |
55 | [tool.setuptools.dynamic]
56 | version = { attr = "lsst_versions.get_lsst_version" }
57 |
58 | [tool.black]
59 | line-length = 110
60 | target-version = ["py310"]
61 |
62 | [tool.isort]
63 | profile = "black"
64 | line_length = 110
65 | known_first_party = ["lsst"]
66 |
67 | [tool.lsst_versions]
68 | write_to = "python/lsst/sphgeom/version.py"
69 |
70 | [tool.pytest.ini_options]
71 | addopts = "--import-mode=importlib" # Recommended as best practice
72 |
73 | [tool.pydocstyle]
74 | convention = "numpy"
75 | # Our coding style does not require docstrings for magic methods (D105)
76 | # Our docstyle documents __init__ at the class level (D107)
77 | # We allow methods to inherit docstrings and this is not compatible with D102.
78 | # Docstring at the very first line is not required
79 | # D200, D205 and D400 all complain if the first sentence of the docstring does
80 | # not fit on one line.
81 | add-ignore = ["D107", "D105", "D102", "D100", "D200", "D205", "D400", "D104"]
82 |
83 | [tool.coverage.report]
84 | show_missing = true
85 | exclude_lines = [
86 | "pragma: no cover",
87 | "raise AssertionError",
88 | "raise NotImplementedError",
89 | "if __name__ == .__main__.:",
90 | "if TYPE_CHECKING:",
91 | ]
92 |
93 | [tool.ruff]
94 | line-length = 110
95 | target-version = "py310"
96 | exclude = [
97 | "__init__.py",
98 | ]
99 |
100 | [tool.ruff.lint]
101 | ignore = [
102 | "N802",
103 | "N803",
104 | "N806",
105 | "N812",
106 | "N815",
107 | "N816",
108 | "N999",
109 | "D107",
110 | "D105",
111 | "D102",
112 | "D104",
113 | "D100",
114 | "D200",
115 | "D205",
116 | ]
117 | select = [
118 | "E", # pycodestyle
119 | "F", # pyflakes
120 | "N", # pep8-naming
121 | "W", # pycodestyle
122 | "D", # pydocstyle
123 | "UP", # pyupgrade
124 | "I", # isort
125 | "RUF022", # sort __all__
126 | "B", # bugbear
127 | "C4", # comprehensions
128 | ]
129 | extend-select = [
130 | "RUF100", # Warn about unused noqa
131 | ]
132 |
133 | [tool.ruff.lint.isort]
134 | known-first-party = ["lsst"]
135 |
136 | [tool.ruff.lint.pycodestyle]
137 | max-doc-length = 79
138 |
139 | [tool.ruff.lint.pydocstyle]
140 | convention = "numpy"
141 |
142 | [tool.ruff.format]
143 | docstring-code-format = true
144 | docstring-code-line-length = 79
145 |
--------------------------------------------------------------------------------
/python/lsst/__init__.py:
--------------------------------------------------------------------------------
1 | import pkgutil
2 |
3 | __path__ = pkgutil.extend_path(__path__, __name__)
4 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | find_package(pybind11 REQUIRED)
2 |
3 | pybind11_add_module(_sphgeom
4 | _angle.cc
5 | _angleInterval.cc
6 | _box3d.cc
7 | _box.cc
8 | _chunker.cc
9 | _circle.cc
10 | _compoundRegion.cc
11 | _convexPolygon.cc
12 | _curve.cc
13 | _ellipse.cc
14 | _htmPixelization.cc
15 | _interval1d.cc
16 | _lonLat.cc
17 | _matrix3d.cc
18 | _mq3cPixelization.cc
19 | _normalizedAngle.cc
20 | _normalizedAngleInterval.cc
21 | _orientation.cc
22 | _pixelization.cc
23 | _q3cPixelization.cc
24 | _rangeSet.cc
25 | _region.cc
26 | _relationship.cc
27 | _sphgeom.cc
28 | _unitVector3d.cc
29 | _utils.cc
30 | _vector3d.cc
31 | )
32 |
33 | target_link_libraries(_sphgeom PUBLIC sphgeom)
34 |
35 | install(TARGETS _sphgeom DESTINATION ${CMAKE_INSTALL_PREFIX}/python/lsst/sphgeom)
36 |
37 | install(
38 | DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/
39 | DESTINATION ${CMAKE_INSTALL_PREFIX}/python/lsst/sphgeom
40 | FILES_MATCHING PATTERN "*.py"
41 | )
42 |
43 | add_custom_target(sphgeom_version ALL
44 | ${CMAKE_COMMAND} -P ${CMAKE_CURRENT_SOURCE_DIR}/version.cmake
45 | BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/version.py
46 | )
47 |
48 | install(
49 | FILES ${CMAKE_CURRENT_BINARY_DIR}/version.py
50 | DESTINATION ${CMAKE_INSTALL_PREFIX}/python/lsst/sphgeom
51 | )
52 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/SConscript:
--------------------------------------------------------------------------------
1 | from lsst.sconsUtils import scripts
2 |
3 | scripts.BasicSConscript.pybind11(
4 | ["_sphgeom"],
5 | extraSrc={
6 | "_sphgeom": [
7 | "_angle.cc",
8 | "_angleInterval.cc",
9 | "_box.cc",
10 | "_box3d.cc",
11 | "_chunker.cc",
12 | "_circle.cc",
13 | "_compoundRegion.cc",
14 | "_convexPolygon.cc",
15 | "_curve.cc",
16 | "_ellipse.cc",
17 | "_htmPixelization.cc",
18 | "_interval1d.cc",
19 | "_lonLat.cc",
20 | "_matrix3d.cc",
21 | "_mq3cPixelization.cc",
22 | "_normalizedAngle.cc",
23 | "_normalizedAngleInterval.cc",
24 | "_orientation.cc",
25 | "_pixelization.cc",
26 | "_q3cPixelization.cc",
27 | "_rangeSet.cc",
28 | "_region.cc",
29 | "_relationship.cc",
30 | "_unitVector3d.cc",
31 | "_utils.cc",
32 | "_vector3d.cc",
33 | ]
34 | },
35 | addUnderscore=False
36 | )
37 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/__init__.py:
--------------------------------------------------------------------------------
1 | # This file is part of sphgeom.
2 | #
3 | # Developed for the LSST Data Management System.
4 | # This product includes software developed by the LSST Project
5 | # (http://www.lsst.org).
6 | # See the COPYRIGHT file at the top-level directory of this distribution
7 | # for details of code ownership.
8 | #
9 | # This software is dual licensed under the GNU General Public License and also
10 | # under a 3-clause BSD license. Recipients may choose which of these licenses
11 | # to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
12 | # respectively. If you choose the GPL option then the following text applies
13 | # (but note that there is still no warranty even if you opt for BSD instead):
14 | #
15 | # This program is free software: you can redistribute it and/or modify
16 | # it under the terms of the GNU General Public License as published by
17 | # the Free Software Foundation, either version 3 of the License, or
18 | # (at your option) any later version.
19 | #
20 | # This program is distributed in the hope that it will be useful,
21 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 | # GNU General Public License for more details.
24 | #
25 | # You should have received a copy of the GNU General Public License
26 | # along with this program. If not, see .
27 | #
28 |
29 | """lsst.sphgeom
30 | """
31 |
32 | from ._continue_class import *
33 | from ._healpixPixelization import *
34 | from ._sphgeom import *
35 | from ._sphgeom import Pixelization
36 | from ._yaml import *
37 | from .pixelization_abc import *
38 | from .version import *
39 |
40 | PixelizationABC.register(Pixelization)
41 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/_angle.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 | #include "pybind11/pybind11.h"
30 |
31 | #include "lsst/sphgeom/python.h"
32 |
33 | #include "lsst/sphgeom/Angle.h"
34 | #include "lsst/sphgeom/NormalizedAngle.h"
35 |
36 | namespace py = pybind11;
37 | using namespace pybind11::literals;
38 |
39 | namespace lsst {
40 | namespace sphgeom {
41 |
42 | template <>
43 | void defineClass(py::class_ &cls) {
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(), "radians"_a);
50 | cls.def(py::init(), "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 | }
101 |
102 | } // sphgeom
103 | } // lsst
104 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/_angleInterval.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 | #include "pybind11/pybind11.h"
30 |
31 | #include "lsst/sphgeom/python.h"
32 |
33 | #include "lsst/sphgeom/AngleInterval.h"
34 | #include "lsst/sphgeom/python/interval.h"
35 |
36 | namespace py = pybind11;
37 | using namespace pybind11::literals;
38 |
39 | namespace lsst {
40 | namespace sphgeom {
41 |
42 | template <>
43 | void defineClass(
44 | py::class_> &cls) {
45 | python::defineInterval(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(), "x"_a);
54 | cls.def(py::init(), "x"_a, "y"_a);
55 | cls.def(py::init(), "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 | }
66 |
67 | } // sphgeom
68 | } // lsst
69 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/_chunker.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 | #include "pybind11/pybind11.h"
30 | #include "pybind11/stl.h"
31 |
32 | #include "lsst/sphgeom/python.h"
33 |
34 | #include "lsst/sphgeom/Chunker.h"
35 |
36 | namespace py = pybind11;
37 | using namespace pybind11::literals;
38 |
39 | namespace lsst {
40 | namespace sphgeom {
41 |
42 | namespace {
43 | py::str toString(Chunker const &self) {
44 | return py::str("Chunker({!s}, {!s})")
45 | .format(self.getNumStripes(), self.getNumSubStripesPerStripe());
46 | }
47 | }
48 |
49 | template <>
50 | void defineClass(py::class_> &cls) {
51 | cls.def(py::init(), "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 ®ion) {
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 | }
91 |
92 | } // sphgeom
93 | } // lsst
94 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/_convexPolygon.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 | #include "pybind11/pybind11.h"
30 | #include "pybind11/stl.h"
31 | #include "pybind11/numpy.h"
32 |
33 | #include "lsst/sphgeom/python.h"
34 |
35 | #include "lsst/sphgeom/Box.h"
36 | #include "lsst/sphgeom/Box3d.h"
37 | #include "lsst/sphgeom/Circle.h"
38 | #include "lsst/sphgeom/ConvexPolygon.h"
39 | #include "lsst/sphgeom/Ellipse.h"
40 | #include "lsst/sphgeom/UnitVector3d.h"
41 |
42 | #include "lsst/sphgeom/python/relationship.h"
43 | #include "lsst/sphgeom/python/utils.h"
44 |
45 | namespace py = pybind11;
46 | using namespace pybind11::literals;
47 |
48 | namespace lsst {
49 | namespace sphgeom {
50 |
51 | template <>
52 | void defineClass(py::class_,
53 | Region> &cls) {
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 const &>(), "points"_a);
59 | // Do not wrap the two unsafe (3 and 4 vertex) constructors
60 | cls.def(py::init(), "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(&ConvexPolygon::contains, py::const_));
71 | cls.def("contains", py::overload_cast(&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));
86 | }
87 |
88 | } // sphgeom
89 | } // lsst
90 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/_curve.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 | #include "pybind11/pybind11.h"
30 |
31 | #include "lsst/sphgeom/curve.h"
32 |
33 | namespace py = pybind11;
34 | using namespace pybind11::literals;
35 |
36 | namespace lsst {
37 | namespace sphgeom {
38 |
39 | void defineCurve(py::module &mod) {
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(*)(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(*)(uint64_t, int)) &
53 | hilbertIndexInverse,
54 | "h"_a, "m"_a);
55 | }
56 |
57 | } // sphgeom
58 | } // lsst
59 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/_ellipse.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 | #include "pybind11/pybind11.h"
30 |
31 | #include "lsst/sphgeom/python.h"
32 |
33 | #include "lsst/sphgeom/Box.h"
34 | #include "lsst/sphgeom/Box3d.h"
35 | #include "lsst/sphgeom/Circle.h"
36 | #include "lsst/sphgeom/ConvexPolygon.h"
37 | #include "lsst/sphgeom/Ellipse.h"
38 | #include "lsst/sphgeom/Matrix3d.h"
39 | #include "lsst/sphgeom/UnitVector3d.h"
40 |
41 | #include "lsst/sphgeom/python/relationship.h"
42 | #include "lsst/sphgeom/python/utils.h"
43 |
44 | namespace py = pybind11;
45 | using namespace pybind11::literals;
46 |
47 | namespace lsst {
48 | namespace sphgeom {
49 |
50 | template <>
51 | void defineClass(py::class_, Region> &cls) {
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"_a);
59 | cls.def(py::init(), "center"_a,
60 | "angle"_a = Angle(0.0));
61 | cls.def(py::init(),
62 | "focus1"_a, "focus2"_a, "alpha"_a);
63 | cls.def(py::init(), "center"_a,
64 | "alpha"_a, "beta"_a, "orientation"_a);
65 | cls.def(py::init(), "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));
94 | }
95 |
96 | } // sphgeom
97 | } // lsst
98 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/_htmPixelization.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 | #include "pybind11/pybind11.h"
30 |
31 | #include "lsst/sphgeom/python.h"
32 |
33 | #include "lsst/sphgeom/HtmPixelization.h"
34 |
35 | namespace py = pybind11;
36 | using namespace pybind11::literals;
37 |
38 | namespace lsst {
39 | namespace sphgeom {
40 |
41 | template <>
42 | void defineClass(py::class_ &cls) {
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(), "level"_a);
50 | cls.def(py::init(), "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 | }
69 |
70 | } // sphgeom
71 | } // lsst
72 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/_interval1d.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 | #include "pybind11/pybind11.h"
30 |
31 | #include "lsst/sphgeom/python.h"
32 |
33 | #include "lsst/sphgeom/Interval1d.h"
34 | #include "lsst/sphgeom/python/interval.h"
35 |
36 | namespace py = pybind11;
37 | using namespace pybind11::literals;
38 |
39 | namespace lsst {
40 | namespace sphgeom {
41 |
42 | template <>
43 | void defineClass(py::class_> &cls) {
44 | python::defineInterval(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(), "x"_a);
51 | cls.def(py::init(), "x"_a, "y"_a);
52 | cls.def(py::init(), "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 | }
64 |
65 | } // sphgeom
66 | } // lsst
67 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/_lonLat.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 | #include "pybind11/pybind11.h"
30 |
31 | #include "lsst/sphgeom/python.h"
32 |
33 | #include "lsst/sphgeom/LonLat.h"
34 | #include "lsst/sphgeom/Vector3d.h"
35 |
36 | namespace py = pybind11;
37 | using namespace pybind11::literals;
38 |
39 | namespace lsst {
40 | namespace sphgeom {
41 |
42 | template <>
43 | void defineClass(py::class_> &cls) {
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());
51 | cls.def(py::init(), "lon"_a, "lat"_a);
52 | cls.def(py::init(), "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 | }
83 |
84 | } // sphgeom
85 | } // lsst
86 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/_mq3cPixelization.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 | #include "pybind11/pybind11.h"
30 |
31 | #include "lsst/sphgeom/python.h"
32 |
33 | #include "lsst/sphgeom/Mq3cPixelization.h"
34 |
35 | namespace py = pybind11;
36 | using namespace pybind11::literals;
37 |
38 | namespace lsst {
39 | namespace sphgeom {
40 |
41 | template <>
42 | void defineClass(py::class_ &cls) {
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(), "level"_a);
51 | cls.def(py::init(), "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 | }
70 |
71 | } // sphgeom
72 | } // lsst
73 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/_normalizedAngle.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 | #include "pybind11/pybind11.h"
30 |
31 | #include "lsst/sphgeom/python.h"
32 |
33 | #include "lsst/sphgeom/LonLat.h"
34 | #include "lsst/sphgeom/NormalizedAngle.h"
35 | #include "lsst/sphgeom/Vector3d.h"
36 |
37 | namespace py = pybind11;
38 | using namespace pybind11::literals;
39 |
40 | namespace lsst {
41 | namespace sphgeom {
42 |
43 | template <>
44 | void defineClass(py::class_ &cls) {
45 | // Provide the equivalent of the NormalizedAngle to Angle C++ cast
46 | // operator in Python
47 | py::implicitly_convertible();
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());
57 | cls.def(py::init());
58 | cls.def(py::init(), "radians"_a);
59 | cls.def(py::init(), "a"_a, "b"_a);
60 | cls.def(py::init(), "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 | }
103 |
104 | } // sphgeom
105 | } // lsst
106 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/_normalizedAngleInterval.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 | #include "pybind11/pybind11.h"
30 |
31 | #include "lsst/sphgeom/python.h"
32 |
33 | #include "lsst/sphgeom/NormalizedAngleInterval.h"
34 | #include "lsst/sphgeom/python/interval.h"
35 |
36 | namespace py = pybind11;
37 | using namespace pybind11::literals;
38 |
39 | namespace lsst {
40 | namespace sphgeom {
41 |
42 | template <>
43 | void defineClass(py::class_> &cls) {
45 | python::defineInterval(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(), "x"_a);
57 | cls.def(py::init(), "x"_a);
58 | cls.def(py::init(), "x"_a, "y"_a);
59 | cls.def(py::init(), "x"_a, "y"_a);
60 | cls.def(py::init(), "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 | }
76 |
77 | } // sphgeom
78 | } // lsst
79 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/_orientation.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 | #include "pybind11/pybind11.h"
30 |
31 | #include "lsst/sphgeom/orientation.h"
32 |
33 | namespace py = pybind11;
34 | using namespace pybind11::literals;
35 |
36 | namespace lsst {
37 | namespace sphgeom {
38 |
39 | void defineOrientation(py::module &mod) {
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 | }
46 |
47 | } // sphgeom
48 | } // lsst
49 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/_pixelization.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 | #include "pybind11/pybind11.h"
30 |
31 | #include "lsst/sphgeom/python.h"
32 |
33 | #include "lsst/sphgeom/Pixelization.h"
34 | #include "lsst/sphgeom/Region.h"
35 | #include "lsst/sphgeom/UnitVector3d.h"
36 |
37 | namespace py = pybind11;
38 | using namespace pybind11::literals;
39 |
40 | namespace lsst {
41 | namespace sphgeom {
42 |
43 | template <>
44 | void defineClass(py::class_ &cls) {
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 | }
52 |
53 | } // sphgeom
54 | } // lsst
55 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/_q3cPixelization.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 | #include "pybind11/pybind11.h"
30 |
31 | #include "lsst/sphgeom/python.h"
32 |
33 | #include "lsst/sphgeom/Q3cPixelization.h"
34 |
35 | namespace py = pybind11;
36 | using namespace pybind11::literals;
37 |
38 | namespace lsst {
39 | namespace sphgeom {
40 |
41 | template <>
42 | void defineClass(py::class_ &cls) {
43 | cls.attr("MAX_LEVEL") = py::int_(Q3cPixelization::MAX_LEVEL);
44 |
45 | cls.def(py::init(), "level"_a);
46 | cls.def(py::init(), "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 | }
67 |
68 | } // sphgeom
69 | } // lsst
70 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/_region.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 | #include "pybind11/pybind11.h"
30 | #include "pybind11/stl.h"
31 | #include "pybind11/numpy.h"
32 |
33 | #include "lsst/sphgeom/python.h"
34 |
35 | #include "lsst/sphgeom/Box.h"
36 | #include "lsst/sphgeom/Box3d.h"
37 | #include "lsst/sphgeom/Circle.h"
38 | #include "lsst/sphgeom/ConvexPolygon.h"
39 | #include "lsst/sphgeom/Ellipse.h"
40 | #include "lsst/sphgeom/Region.h"
41 | #include "lsst/sphgeom/UnitVector3d.h"
42 |
43 | #include "lsst/sphgeom/python/relationship.h"
44 | #include "lsst/sphgeom/python/tristate.h"
45 | #include "lsst/sphgeom/python/utils.h"
46 |
47 | namespace py = pybind11;
48 | using namespace pybind11::literals;
49 |
50 | namespace lsst {
51 | namespace sphgeom {
52 |
53 | template <>
54 | void defineClass(py::class_> &cls) {
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(&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(&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, "bytes"_a);
78 | cls.def_static("decodeBase64", py::overload_cast(&Region::decodeBase64),
79 | "bytes"_a);
80 | cls.def_static("decodeOverlapsBase64",
81 | py::overload_cast(&Region::decodeOverlapsBase64),
82 | "bytes"_a);
83 | cls.def_static("getRegions", Region::getRegions, "region"_a);
84 | }
85 |
86 | } // sphgeom
87 | } // lsst
88 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/_relationship.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 | #include "pybind11/pybind11.h"
30 |
31 | #include "lsst/sphgeom/python/relationship.h"
32 |
33 | namespace py = pybind11;
34 | using namespace pybind11::literals;
35 |
36 | namespace lsst {
37 | namespace sphgeom {
38 |
39 | void defineRelationship(py::module &mod) {
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 | }
47 |
48 | } // sphgeom
49 | } // lsst
50 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/_utils.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 | #include "pybind11/pybind11.h"
30 |
31 | #include "lsst/sphgeom/python.h"
32 |
33 | #include "lsst/sphgeom/Angle.h"
34 | #include "lsst/sphgeom/UnitVector3d.h"
35 | #include "lsst/sphgeom/utils.h"
36 | #include "lsst/sphgeom/Vector3d.h"
37 |
38 | namespace py = pybind11;
39 | using namespace pybind11::literals;
40 |
41 | namespace lsst {
42 | namespace sphgeom {
43 |
44 | void defineUtils(py::module &mod) {
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 | }
54 |
55 | } // sphgeom
56 | } // lsst
57 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/_vector3d.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 | #include "pybind11/pybind11.h"
30 |
31 | #include "lsst/sphgeom/python.h"
32 |
33 | #include "lsst/sphgeom/Angle.h"
34 | #include "lsst/sphgeom/UnitVector3d.h"
35 | #include "lsst/sphgeom/Vector3d.h"
36 | #include "lsst/sphgeom/python/utils.h"
37 |
38 | namespace py = pybind11;
39 | using namespace pybind11::literals;
40 |
41 | namespace lsst {
42 | namespace sphgeom {
43 |
44 | template <>
45 | void defineClass(py::class_> &cls) {
46 | cls.def(py::init<>());
47 | cls.def(py::init(), "x"_a, "y"_a, "z"_a);
48 | cls.def(py::init(), "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 | }
104 |
105 | } // sphgeom
106 | } // lsst
107 |
--------------------------------------------------------------------------------
/python/lsst/sphgeom/version.cmake:
--------------------------------------------------------------------------------
1 | execute_process(
2 | COMMAND git describe --all --always --dirty
3 | OUTPUT_VARIABLE GIT_REV
4 | ERROR_QUIET
5 | )
6 |
7 | if("${GIT_REV}" STREQUAL "")
8 | set(GIT_REV "unknown")
9 | endif()
10 |
11 | string(STRIP ${GIT_REV} GIT_REV)
12 | string(REGEX REPLACE "^(heads|tags)/" "" GIT_REV "${GIT_REV}")
13 | string(REPLACE "/" "_" GIT_REV "${GIT_REV}")
14 |
15 | set(VERSION_PY "__version__ = '${GIT_REV}'
16 | __all__ = ('__version__',)
17 | ")
18 |
19 | if(EXISTS ${CMAKE_CURRENT_BINARY_DIR}/version.py)
20 | file(READ ${CMAKE_CURRENT_BINARY_DIR}/version.py VERSION_PY_)
21 | else()
22 | set(VERSION_PY_ "")
23 | endif()
24 |
25 | if(NOT "${VERSION_PY}" STREQUAL "${VERSION_PY_}")
26 | file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/version.py "${VERSION_PY}")
27 | endif()
28 |
--------------------------------------------------------------------------------
/setup.cfg:
--------------------------------------------------------------------------------
1 | [flake8]
2 | max-line-length = 110
3 | max-doc-length = 79
4 | ignore = E133, E226, E228, N802, N803, N806, N812, N815, N816, W503
5 | exclude = __init__.py
6 |
--------------------------------------------------------------------------------
/setup.py:
--------------------------------------------------------------------------------
1 | """
2 | Basic setuptools description.
3 |
4 | This is not a complete definition.
5 |
6 | * Version number is not correct.
7 | * The shared library and include files are not installed. This makes it
8 | unusable with other python packages that directly reference the C++
9 | interface.
10 | """
11 |
12 | import glob
13 |
14 | from pybind11.setup_helpers import ParallelCompile, Pybind11Extension, build_ext
15 | from setuptools import setup
16 |
17 | # Optional multithreaded build.
18 | ParallelCompile("NPY_NUM_BUILD_JOBS").install()
19 |
20 | # Find the source code -- we can combine it into a single module
21 | pybind_src = sorted(glob.glob("python/lsst/sphgeom/*.cc"))
22 | cpp_src = sorted(glob.glob("src/*.cc"))
23 |
24 | # Very inefficient approach since this compiles the maing sphgeom
25 | # library code for every extension rather than building everything once
26 | ext_modules = [
27 | Pybind11Extension("lsst.sphgeom._sphgeom", sorted(cpp_src + pybind_src), include_dirs=["include"])
28 | ]
29 |
30 | setup(
31 | ext_modules=ext_modules,
32 | cmdclass={"build_ext": build_ext},
33 | )
34 |
--------------------------------------------------------------------------------
/src/Angle.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | /// \file
31 | /// \brief This file contains the Angle class implementation.
32 |
33 | #include "lsst/sphgeom/Angle.h"
34 |
35 | #include
36 | #include
37 |
38 | namespace lsst {
39 | namespace sphgeom {
40 |
41 | std::ostream & operator<<(std::ostream & os, Angle const & a) {
42 | char buf[32];
43 | std::snprintf(buf, sizeof(buf), "%.17g", a.asRadians());
44 | return os << buf;
45 | }
46 |
47 | }} // namespace lsst::sphgeom
48 |
--------------------------------------------------------------------------------
/src/AngleInterval.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | /// \file
31 | /// \brief This file contains the AngleInterval class implementation.
32 |
33 | #include "lsst/sphgeom/AngleInterval.h"
34 |
35 | #include
36 |
37 |
38 | namespace lsst {
39 | namespace sphgeom {
40 |
41 | std::ostream & operator<<(std::ostream & os, AngleInterval const & i) {
42 | return os << '[' << i.getA() << ", " << i.getB() << ']';
43 | }
44 |
45 | }} // namespace lsst::sphgeom
46 |
--------------------------------------------------------------------------------
/src/Box3d.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | /// \file
31 | /// \brief This file contains the Box3d class implementation.
32 |
33 | #include "lsst/sphgeom/Box3d.h"
34 |
35 | #include
36 |
37 |
38 | namespace lsst {
39 | namespace sphgeom {
40 |
41 | std::ostream & operator<<(std::ostream & os, Box3d const & b) {
42 | return os << "{\"Box3d\": [" << b.x() << ", " << b.y() << ", " << b.z() << "]}";
43 | }
44 |
45 | }} // namespace lsst::sphgeom
46 |
--------------------------------------------------------------------------------
/src/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | add_library(sphgeom SHARED)
2 |
3 | target_compile_features(sphgeom PRIVATE
4 | cxx_std_17
5 | )
6 |
7 | set_target_properties(sphgeom PROPERTIES
8 | CXX_EXTENSIONS OFF
9 | POSITION_INDEPENDENT_CODE ON
10 | )
11 |
12 | target_include_directories(sphgeom PUBLIC
13 | ${PROJECT_SOURCE_DIR}/include
14 | )
15 |
16 | target_sources(sphgeom PRIVATE
17 | Angle.cc
18 | AngleInterval.cc
19 | BigInteger.cc
20 | Box3d.cc
21 | Box.cc
22 | Chunker.cc
23 | Circle.cc
24 | CompoundRegion.cc
25 | ConvexPolygon.cc
26 | ConvexPolygonImpl.h
27 | Ellipse.cc
28 | HtmPixelization.cc
29 | Interval1d.cc
30 | LonLat.cc
31 | Matrix3d.cc
32 | Mq3cPixelization.cc
33 | NormalizedAngle.cc
34 | NormalizedAngleInterval.cc
35 | orientation.cc
36 | PixelFinder.h
37 | Q3cPixelization.cc
38 | Q3cPixelizationImpl.h
39 | RangeSet.cc
40 | Region.cc
41 | UnitVector3d.cc
42 | utils.cc
43 | Vector3d.cc
44 | )
45 |
46 | install(TARGETS sphgeom)
47 |
--------------------------------------------------------------------------------
/src/Interval1d.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | /// \file
31 | /// \brief This file contains the AngleInterval class implementation.
32 |
33 | #include "lsst/sphgeom/Interval1d.h"
34 |
35 | #include
36 | #include
37 |
38 |
39 | namespace lsst {
40 | namespace sphgeom {
41 |
42 | std::ostream & operator<<(std::ostream & os, Interval1d const & i) {
43 | char buf[64];
44 | std::snprintf(buf, sizeof(buf), "[%.17g, %.17g]", i.getA(), i.getB());
45 | return os << buf;
46 | }
47 |
48 | }} // namespace lsst::sphgeom
49 |
--------------------------------------------------------------------------------
/src/LonLat.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | /// \file
31 | /// \brief This file contains the LonLat class implementation.
32 |
33 | #include "lsst/sphgeom/LonLat.h"
34 |
35 | #include
36 | #include
37 |
38 | #include "lsst/sphgeom/Vector3d.h"
39 |
40 |
41 | namespace lsst {
42 | namespace sphgeom {
43 |
44 | Angle LonLat::latitudeOf(Vector3d const & v) {
45 | double d2 = v(0) * v(0) + v(1) * v(1);
46 | double lat = 0.0;
47 | if (v(2) != 0.0) {
48 | lat = std::atan2(v(2), sqrt(d2));
49 | if (std::fabs(lat) > 0.5 * PI) {
50 | lat = ::copysign(0.5 * PI, lat);
51 | }
52 | }
53 | return Angle(lat);
54 | }
55 |
56 | NormalizedAngle LonLat::longitudeOf(Vector3d const & v) {
57 | double d2 = v(0) * v(0) + v(1) * v(1);
58 | double lon = 0.0;
59 | if (d2 != 0.0) {
60 | lon = std::atan2(v(1), v(0));
61 | if (lon < 0.0) {
62 | lon += 2*PI;
63 | }
64 | }
65 | return NormalizedAngle(lon);
66 | }
67 |
68 |
69 | LonLat::LonLat(NormalizedAngle lon, Angle lat) : _lon(lon), _lat(lat) {
70 | if (std::fabs(_lat.asRadians()) > 0.5 * PI) {
71 | throw std::invalid_argument("invalid latitude angle");
72 | }
73 | _enforceInvariants();
74 | }
75 |
76 | LonLat::LonLat(Vector3d const & v) : _lon(longitudeOf(v)), _lat(latitudeOf(v)) {
77 | _enforceInvariants();
78 | }
79 |
80 | void LonLat::_enforceInvariants() {
81 | // Make sure that if one coordinate is NaN, the other is as well.
82 | if (_lon.isNan()) {
83 | _lat = Angle::nan();
84 | } else if (_lat.isNan()) {
85 | _lon = NormalizedAngle::nan();
86 | }
87 | }
88 |
89 | std::ostream & operator<<(std::ostream & os, LonLat const & p) {
90 | return os << '[' << p.getLon() << ", " << p.getLat() << ']';
91 | }
92 |
93 | }} // namespace lsst::sphgeom
94 |
--------------------------------------------------------------------------------
/src/Matrix3d.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | /// \file
31 | /// \brief This file contains the Matrix3d class implementation.
32 |
33 | #include "lsst/sphgeom/Matrix3d.h"
34 |
35 | #include
36 | #include
37 |
38 |
39 | namespace lsst {
40 | namespace sphgeom {
41 |
42 | std::ostream & operator<<(std::ostream & os, Matrix3d const & m) {
43 | return os << '[' << m.getRow(0) << ", " << m.getRow(1) << ", " << m.getRow(2) << ']';
44 | }
45 |
46 | }} // namespace lsst::sphgeom
47 |
--------------------------------------------------------------------------------
/src/NormalizedAngle.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | /// \file
31 | /// \brief This file contains the NormalizedAngle class implementation.
32 |
33 | #include "lsst/sphgeom/NormalizedAngle.h"
34 |
35 | #include "lsst/sphgeom/LonLat.h"
36 | #include "lsst/sphgeom/Vector3d.h"
37 |
38 |
39 | namespace lsst {
40 | namespace sphgeom {
41 |
42 | NormalizedAngle NormalizedAngle::between(NormalizedAngle const & a,
43 | NormalizedAngle const & b)
44 | {
45 | NormalizedAngle x;
46 | double a1 = std::fabs(a.asRadians() - b.asRadians());
47 | double a2 = 2.0 * PI - a1;
48 | x._a = Angle(std::min(a1, a2));
49 | return x;
50 | }
51 |
52 | NormalizedAngle NormalizedAngle::center(NormalizedAngle const & a,
53 | NormalizedAngle const & b)
54 | {
55 | NormalizedAngle x;
56 | double c = 0.5 * (a.asRadians() + b.asRadians());
57 | if (a <= b) {
58 | x._a = Angle(c);
59 | } else {
60 | // The result is (a + b + 2π) / 2, normalized to [0, 2π)
61 | x._a = Angle((c < PI) ? (c + PI) : (c - PI));
62 | }
63 | return x;
64 | }
65 |
66 | NormalizedAngle::NormalizedAngle(LonLat const & p1, LonLat const & p2) {
67 | double x = sin((p1.getLon() - p2.getLon()) * 0.5);
68 | x *= x;
69 | double y = sin((p1.getLat() - p2.getLat()) * 0.5);
70 | y *= y;
71 | double z = cos((p1.getLat() + p2.getLat()) * 0.5);
72 | z *= z;
73 | // Compute the square of the sine of half of the desired angle. This is
74 | // easily shown to be be one fourth of the squared Euclidian distance
75 | // (chord length) between p1 and p2.
76 | double sha2 = (x * (z - y) + y);
77 | // Avoid domain errors in asin and sqrt due to rounding errors.
78 | if (sha2 < 0.0) {
79 | _a = Angle(0.0);
80 | } else if (sha2 >= 1.0) {
81 | _a = Angle(PI);
82 | } else {
83 | _a = Angle(2.0 * std::asin(std::sqrt(sha2)));
84 | }
85 | }
86 |
87 | NormalizedAngle::NormalizedAngle(Vector3d const & v1, Vector3d const & v2) {
88 | double s = v1.cross(v2).getNorm();
89 | double c = v1.dot(v2);
90 | if (s == 0.0 && c == 0.0) {
91 | // Avoid the atan2(±0, -0) = ±PI special case.
92 | _a = Angle(0.0);
93 | } else {
94 | _a = Angle(std::atan2(s, c));
95 | }
96 | }
97 |
98 | }} // namespace lsst::sphgeom
99 |
--------------------------------------------------------------------------------
/src/UnitVector3d.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | /// \file
31 | /// \brief This file contains the Vector3d class implementation.
32 |
33 | #include "lsst/sphgeom/UnitVector3d.h"
34 |
35 | #include
36 |
37 |
38 | namespace lsst {
39 | namespace sphgeom {
40 |
41 | UnitVector3d UnitVector3d::orthogonalTo(Vector3d const & v) {
42 | if (std::fabs(v.x()) > std::fabs(v.y())) {
43 | return UnitVector3d(-v.z(), 0.0, v.x());
44 | }
45 | return UnitVector3d(0.0, v.z(), -v.y());
46 | }
47 |
48 | UnitVector3d UnitVector3d::orthogonalTo(Vector3d const & v1,
49 | Vector3d const & v2)
50 | {
51 | Vector3d n = (v2 + v1).cross(v2 - v1);
52 | if (n.isZero()) {
53 | return orthogonalTo(v1);
54 | }
55 | return UnitVector3d(n);
56 | }
57 |
58 | UnitVector3d UnitVector3d::northFrom(Vector3d const & v) {
59 | Vector3d n(-v.x() * v.z(),
60 | -v.y() * v.z(),
61 | v.x() * v.x() + v.y() * v.y());
62 | if (n.isZero()) {
63 | UnitVector3d u;
64 | u._v = Vector3d(-::copysign(1.0, v.z()), 0.0, 0.0);
65 | return u;
66 | }
67 | return UnitVector3d(n);
68 | }
69 |
70 | UnitVector3d::UnitVector3d(Angle lon, Angle lat) {
71 | double sinLon = sin(lon);
72 | double cosLon = cos(lon);
73 | double sinLat = sin(lat);
74 | double cosLat = cos(lat);
75 | _v = Vector3d(cosLon * cosLat,
76 | sinLon * cosLat,
77 | sinLat);
78 | }
79 |
80 | std::ostream & operator<<(std::ostream & os, UnitVector3d const & v) {
81 | return os << static_cast(v);
82 | }
83 |
84 | }} // namespace lsst::sphgeom
85 |
--------------------------------------------------------------------------------
/src/utils.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | /// \file
31 | /// \brief This file contains utility function implementations.
32 |
33 | #include "lsst/sphgeom/utils.h"
34 |
35 | #include
36 |
37 | #include "lsst/sphgeom/UnitVector3d.h"
38 |
39 |
40 | namespace lsst {
41 | namespace sphgeom {
42 |
43 | double getMinSquaredChordLength(Vector3d const & v,
44 | Vector3d const & a,
45 | Vector3d const & b,
46 | Vector3d const & n)
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 | }
64 |
65 | double getMaxSquaredChordLength(Vector3d const & v,
66 | Vector3d const & a,
67 | Vector3d const & b,
68 | Vector3d const & n)
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 | }
85 |
86 | Vector3d getWeightedCentroid(UnitVector3d const & v0,
87 | UnitVector3d const & v1,
88 | UnitVector3d const & v2)
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 | }
112 |
113 | }} // namespace lsst::sphgeom
114 |
--------------------------------------------------------------------------------
/tests/CMakeLists.txt:
--------------------------------------------------------------------------------
1 | FUNCTION(sphgeom_tests)
2 | FOREACH(TEST IN ITEMS ${ARGV})
3 | add_executable(${TEST} ${TEST}.cc)
4 | target_link_libraries(${TEST} PUBLIC sphgeom)
5 | add_test(NAME ${TEST} COMMAND ${TEST})
6 | ENDFOREACH()
7 | ENDFUNCTION()
8 |
9 | sphgeom_tests(
10 | testAngle
11 | testAngleInterval
12 | testBigInteger
13 | testBox
14 | testChunker
15 | testCircle
16 | testConvexPolygon
17 | testCurve
18 | testEllipse
19 | testHtmPixelization
20 | testInterval1d
21 | testLonLat
22 | testMatrix3d
23 | testMq3cPixelization
24 | testNormalizedAngle
25 | testNormalizedAngleInterval
26 | testOrientation
27 | testQ3cPixelization
28 | testRangeSet
29 | testUnitVector3d
30 | testVector3d
31 | )
32 |
--------------------------------------------------------------------------------
/tests/SConscript:
--------------------------------------------------------------------------------
1 | from lsst.sconsUtils import scripts
2 | scripts.BasicSConscript.tests(pyList=[])
3 |
--------------------------------------------------------------------------------
/tests/relationshipTestUtils.h:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | #ifndef LSST_SPHGEOM_RELATIONSHIPTESTUTILS_H_
31 | #define LSST_SPHGEOM_RELATIONSHIPTESTUTILS_H_
32 |
33 | /// \file
34 | /// \brief This file contains utility code for testing spatial
35 | /// relations between regions. It is useful both for
36 | /// spherical regions as well as for 1D intervals.
37 |
38 | #include "lsst/sphgeom/Relationship.h"
39 |
40 |
41 | namespace lsst {
42 | namespace sphgeom {
43 |
44 | // `checkRelationship` checks that evaluating the spatial predicates gives the
45 | // expected outcomes.
46 | template
47 | void checkRelationship(U const & u,
48 | V const & v,
49 | Relationship expectedRelationship)
50 | {
51 | bool shouldBeDisjointFrom = (expectedRelationship & DISJOINT) != 0;
52 | bool shouldIntersect = (expectedRelationship & DISJOINT) == 0;
53 | bool shouldContain = (expectedRelationship & CONTAINS) != 0;
54 | bool shouldBeWithin = (expectedRelationship & WITHIN) != 0;
55 | CHECK(u.contains(v) == shouldContain);
56 | CHECK(u.intersects(v) == shouldIntersect);
57 | CHECK(u.isWithin(v) == shouldBeWithin);
58 | CHECK(u.isDisjointFrom(v) == shouldBeDisjointFrom);
59 | CHECK(u.relate(v) == expectedRelationship);
60 | }
61 |
62 | template
63 | void checkDisjoint(U const & u, V const & v) {
64 | checkRelationship(u, v, DISJOINT);
65 | checkRelationship(v, u, DISJOINT);
66 | }
67 |
68 | template
69 | void checkIntersects(U const & u, V const & v) {
70 | checkRelationship(u, v, INTERSECTS);
71 | checkRelationship(v, u, INTERSECTS);
72 | }
73 |
74 | template
75 | void checkContains(U const & u, V const & v) {
76 | checkRelationship(u, v, CONTAINS);
77 | checkRelationship(v, u, WITHIN);
78 | }
79 |
80 | // `checkBasicProperties` verifies a few rudimentary identities that should
81 | // hold for a non-empty region r.
82 | template
83 | void checkBasicProperties(R const & r) {
84 | CHECK(!r.isEmpty());
85 | CHECK(r == r);
86 | CHECK(!(r != r));
87 | CHECK(r != R());
88 | // A non-empty region should contain and be disjoint from ∅.
89 | checkRelationship(r, R(), CONTAINS | DISJOINT);
90 | // ∅ should be within and disjoint from a non-empty region.
91 | checkRelationship(R(), r, WITHIN | DISJOINT);
92 | }
93 |
94 | // `checkPoints` verifies that the given lists of points, and regions
95 | // constructed from them, are contained in / disjoint from region r.
96 | template
97 | void checkPoints(Point const * in,
98 | size_t inLength,
99 | Point const * out,
100 | size_t outLength,
101 | R const & r)
102 | {
103 | for (unsigned i = 0; i < inLength; ++i) {
104 | Point p = in[i];
105 | checkRelationship(r, p, CONTAINS);
106 | checkContains(r, R(p));
107 | }
108 | for (unsigned i = 0; i < outLength; ++i) {
109 | Point p = out[i];
110 | checkRelationship(r, p, DISJOINT);
111 | checkDisjoint(r, R(p));
112 | }
113 | }
114 |
115 | }} // namespace lsst::sphgeom
116 |
117 | #endif // LSST_SPHGEOM_RELATIONSHIPTESTUTILS_H_
118 |
--------------------------------------------------------------------------------
/tests/testAngle.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | /// \file
31 | /// \brief This file contains tests for the Angle class.
32 |
33 | #include
34 | #include
35 |
36 | #include "lsst/sphgeom/NormalizedAngle.h"
37 |
38 | #include "test.h"
39 |
40 |
41 | using namespace lsst::sphgeom;
42 |
43 | TEST_CASE(Basic) {
44 | Angle a;
45 | CHECK(a.asRadians() == 0);
46 | CHECK(a.asDegrees() == 0);
47 | CHECK(a == a);
48 | CHECK(!(a != a));
49 | CHECK(Angle::fromDegrees(90.0).asRadians() == PI/2);
50 | CHECK(Angle::fromDegrees(180.0).asRadians() == PI);
51 | CHECK(Angle::fromDegrees(270.0).asRadians() == 3*PI/2);
52 | CHECK(Angle::fromRadians(PI/2).asDegrees() == 90.0);
53 | CHECK(Angle::fromRadians(PI).asDegrees() == 180.0);
54 | CHECK(Angle::fromRadians(3*PI/2).asDegrees() == 270.0);
55 | }
56 |
57 | TEST_CASE(Stream) {
58 | Angle a(1);
59 | std::stringstream ss;
60 | ss << a;
61 | CHECK(ss.str() == "1");
62 | ss.str(std::string());
63 | }
64 |
65 | TEST_CASE(Comparison) {
66 | Angle a1(1), a2(2);
67 | CHECK(a1 < a2);
68 | CHECK(a1 <= a2);
69 | CHECK(a1 == a1);
70 | CHECK(a1 != a2);
71 | CHECK(a2 > a1);
72 | CHECK(a2 >= a1);
73 | }
74 |
75 | TEST_CASE(Arithmetic) {
76 | Angle a1(1), a2(2), a3(3);
77 | Angle a4 = -a1;
78 | CHECK(a2 + a4 == a1);
79 | CHECK(a2 - a1 == a1);
80 | CHECK(a1 * 2 == a2);
81 | CHECK(a1 * 2 == 2 * a1);
82 | CHECK(a2 / 2 == a1);
83 | CHECK(a1 / a2 == 0.5);
84 | CHECK_CLOSE(sin(Angle(PI/6)), 0.5, 2);
85 | CHECK_CLOSE(cos(Angle(2*PI/3)), -0.5, 4);
86 | CHECK_CLOSE(tan(Angle(PI/4)), 1.0, 2);
87 | CHECK(abs(Angle(-1)) == Angle(1));
88 | CHECK(abs(Angle(1)) == Angle(1));
89 | }
90 |
91 | TEST_CASE(Normalization) {
92 | Angle a1(1), a10(10), mp(-PI);
93 | CHECK(a1.isNormalized());
94 | CHECK(NormalizedAngle(a1) == a1);
95 | CHECK(!mp.isNormalized());
96 | CHECK(!a10.isNormalized());
97 | }
98 |
99 | TEST_CASE(NaNValues) {
100 | CHECK(!Angle::nan().isNormalized());
101 | CHECK(Angle::nan().isNan());
102 | CHECK(std::isnan(Angle::nan().asRadians()));
103 | CHECK(std::isnan(Angle::nan().asDegrees()));
104 | // Check that arithmetic propagates NaNs
105 | CHECK((Angle::nan() * 2).isNan());
106 | CHECK((Angle::nan() / 2).isNan());
107 | CHECK((2 * Angle::nan()).isNan());
108 | CHECK((Angle::nan() + Angle(1)).isNan());
109 | CHECK((Angle(1) + Angle::nan()).isNan());
110 | CHECK((Angle::nan() - Angle(1)).isNan());
111 | CHECK((Angle(1) - Angle::nan()).isNan());
112 | }
113 |
--------------------------------------------------------------------------------
/tests/testChunker.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | /// \file
31 | /// \brief This file contains tests for the Chunker class.
32 |
33 | #include "lsst/sphgeom/Box.h"
34 | #include "lsst/sphgeom/Chunker.h"
35 |
36 | #include "test.h"
37 |
38 |
39 | using namespace lsst::sphgeom;
40 |
41 | TEST_CASE(ChunksIntersecting1) {
42 | int32_t expectedChunkIds[21] = {
43 | 6630, 6631, 6797, 6800, 6801, 6968, 6970, 6971,
44 | 7138, 7140, 7141, 7308, 7310, 7311, 7478, 7480,
45 | 7481, 7648, 7650, 7651, 7817
46 | };
47 | Box box = Box::fromDegrees(-0.1, -6, 4, 6);
48 | Chunker chunker(85, 14);
49 | CHECK(chunker.getNumStripes() == 85);
50 | CHECK(chunker.getNumSubStripesPerStripe() == 14);
51 | std::vector chunkIds = chunker.getChunksIntersecting(box);
52 | CHECK(chunkIds.size() == 21);
53 | for (size_t i = 0; i < chunkIds.size() && i < 21; ++i) {
54 | CHECK(chunkIds[i] == expectedChunkIds[i]);
55 | }
56 | }
57 |
58 | TEST_CASE(AllSubChunks) {
59 | std::vector expectedSubChunkIds = {
60 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,
61 | 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80,
62 | 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
63 | 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218,
64 | 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287,
65 | 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356,
66 | 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425,
67 | 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494,
68 | 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, 563,
69 | 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, 632,
70 | 690, 691, 692, 693, 694, 695, 696, 697, 698, 699, 700, 701,
71 | 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, 770
72 | };
73 | Chunker chunker(85, 12);
74 | std::vector subChunkIds = chunker.getAllSubChunks(9630);
75 | CHECK(subChunkIds == expectedSubChunkIds);
76 | }
77 |
--------------------------------------------------------------------------------
/tests/testCurve.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | /// \file
31 | /// \brief This file contains tests for space filling curve functions.
32 |
33 | #include "lsst/sphgeom/curve.h"
34 |
35 | #include "test.h"
36 |
37 | using namespace lsst::sphgeom;
38 |
39 | void checkMorton(uint32_t x, uint32_t y, uint64_t z) {
40 | CHECK(z == mortonIndex(x, y));
41 | uint32_t xi, yi;
42 | std::tie(xi, yi) = mortonIndexInverse(z);
43 | CHECK(x == xi);
44 | CHECK(y == yi);
45 | }
46 |
47 | void checkHilbert(uint32_t x, uint32_t y, uint32_t m, uint64_t h) {
48 | CHECK(h == hilbertIndex(x, y, m));
49 | uint32_t xi, yi;
50 | std::tie(xi, yi) = hilbertIndexInverse(h, m);
51 | CHECK(x == xi);
52 | CHECK(y == yi);
53 | }
54 |
55 | TEST_CASE(Log2) {
56 | for (uint32_t s = 0; s < 64; ++s) {
57 | uint32_t x32 = static_cast(1) << s;
58 | uint64_t x64 = static_cast(1) << s;
59 | if (s < 32) {
60 | CHECK(log2(x32) == s);
61 | }
62 | CHECK(log2(x64) == s);
63 | }
64 | CHECK(log2(static_cast(0)) == 0);
65 | CHECK(log2(static_cast(0)) == 0);
66 | }
67 |
68 | TEST_CASE(Morton) {
69 | checkMorton(0, 0, 0);
70 | checkMorton(1, 0, 1);
71 | checkMorton(0, 1, 2);
72 | checkMorton(1, 1, 3);
73 | checkMorton(0xffffffff, 0, UINT64_C(0x5555555555555555));
74 | checkMorton(0, 0xffffffff, UINT64_C(0xaaaaaaaaaaaaaaaa));
75 | checkMorton(0xffffffff, 0xffffffff, UINT64_C(0xffffffffffffffff));
76 | for (uint32_t xb = 0; xb < 32; ++xb) {
77 | for (uint32_t yb = 0; yb < 32; ++yb) {
78 | uint32_t x = static_cast(1) << xb;
79 | uint32_t y = static_cast(1) << yb;
80 | uint64_t z = (static_cast(1) << (2 * xb)) +
81 | (static_cast(1) << (2 * yb + 1));
82 | checkMorton(x, y, z);
83 | checkMorton(~x, ~y, ~z);
84 | }
85 | }
86 | }
87 |
88 | TEST_CASE(Hilbert) {
89 | // Check order 1 Hilbert lattice
90 | checkHilbert(0, 0, 1, 0);
91 | checkHilbert(0, 1, 1, 1);
92 | checkHilbert(1, 1, 1, 2);
93 | checkHilbert(1, 0, 1, 3);
94 | // Check order 2 Hilbert lattice
95 | uint32_t const points2[16][2] = {
96 | {0, 0}, {1, 0}, {1, 1}, {0, 1},
97 | {0, 2}, {0, 3}, {1, 3}, {1, 2},
98 | {2, 2}, {2, 3}, {3, 3}, {3, 2},
99 | {3, 1}, {2, 1}, {2, 0}, {3, 0}
100 | };
101 | for (uint32_t i = 0; i < 16; ++i) {
102 | checkHilbert(points2[i][0], points2[i][1], 2, i);
103 | }
104 | // Check order 3 Hilbert lattice
105 | uint32_t const points3[64][2] = {
106 | {0, 0}, {0, 1}, {1, 1}, {1, 0},
107 | {2, 0}, {3, 0}, {3, 1}, {2, 1},
108 | {2, 2}, {3, 2}, {3, 3}, {2, 3},
109 | {1, 3}, {1, 2}, {0, 2}, {0, 3},
110 | {0, 4}, {1, 4}, {1, 5}, {0, 5},
111 | {0, 6}, {0, 7}, {1, 7}, {1, 6},
112 | {2, 6}, {2, 7}, {3, 7}, {3, 6},
113 | {3, 5}, {2, 5}, {2, 4}, {3, 4},
114 | {4, 4}, {5, 4}, {5, 5}, {4, 5},
115 | {4, 6}, {4, 7}, {5, 7}, {5, 6},
116 | {6, 6}, {6, 7}, {7, 7}, {7, 6},
117 | {7, 5}, {6, 5}, {6, 4}, {7, 4},
118 | {7, 3}, {7, 2}, {6, 2}, {6, 3},
119 | {5, 3}, {4, 3}, {4, 2}, {5, 2},
120 | {5, 1}, {4, 1}, {4, 0}, {5, 0},
121 | {6, 0}, {6, 1}, {7, 1}, {7, 0}
122 | };
123 | for (uint32_t i = 0; i < 64; ++i) {
124 | checkHilbert(points3[i][0], points3[i][1], 3, i);
125 | }
126 | }
127 |
--------------------------------------------------------------------------------
/tests/testLonLat.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | /// \file
31 | /// \brief This file contains tests for the LonLat class.
32 |
33 | #include
34 |
35 | #include "lsst/sphgeom/LonLat.h"
36 | #include "lsst/sphgeom/Vector3d.h"
37 |
38 | #include "test.h"
39 |
40 |
41 | using namespace lsst::sphgeom;
42 |
43 | void checkClose(LonLat const & p1, LonLat const & p2, Angle threshold) {
44 | CHECK(NormalizedAngle(p1, p2) <= threshold);
45 | }
46 |
47 | TEST_CASE(Stream) {
48 | LonLat p = LonLat::fromRadians(2, 1);
49 | std::stringstream ss;
50 | ss << p;
51 | CHECK(ss.str() == "[2, 1]");
52 | }
53 |
54 | TEST_CASE(Construction) {
55 | Angle threshold(1e-15); // less than one billionth of an arcsecond
56 | checkClose(LonLat::fromDegrees(90, 45),
57 | LonLat::fromRadians(PI/2, PI/4), threshold);
58 | checkClose(LonLat::fromRadians(PI/2, PI/4),
59 | LonLat(NormalizedAngle(PI/2), Angle(PI/4)), threshold);
60 | // Note that Vector3dTest.cc also contains tests for the
61 | // LonLot(Vector3d const &) constructor.
62 | LonLat p1(Vector3d(1, 0, 0));
63 | checkClose(p1, LonLat::fromDegrees(0, 0), threshold);
64 | LonLat p2(Vector3d(0, -1, 0));
65 | checkClose(p2, LonLat::fromDegrees(270, 0), threshold);
66 | LonLat p3(Vector3d(0, 0, 1));
67 | checkClose(p3, LonLat::fromDegrees(0, 90), threshold);
68 | LonLat p4(Vector3d(0, 0, -1));
69 | checkClose(p4, LonLat::fromDegrees(0, -90), threshold);
70 | // Trying to create a LonLat having latitude of magnitude
71 | // > π/2 should fail.
72 | CHECK_THROW(LonLat::fromRadians(0, 2), std::invalid_argument);
73 | CHECK_THROW(LonLat::fromRadians(0, -2), std::invalid_argument);
74 | }
75 |
76 | TEST_CASE(ComponentAccess) {
77 | LonLat p = LonLat::fromRadians(2, 1);
78 | CHECK(p.getLon() == NormalizedAngle(2));
79 | CHECK(p.getLat() == Angle(1));
80 | }
81 |
82 | TEST_CASE(Comparison) {
83 | LonLat p1 = LonLat::fromRadians(1, 0.5);
84 | LonLat p2 = LonLat::fromRadians(0, 0.5);
85 | LonLat p3 = LonLat::fromRadians(1, 1.5);
86 | CHECK(p1 == p1);
87 | CHECK(p1 != p2);
88 | CHECK(p1 != p3);
89 | CHECK(!(p1 == p3));
90 | CHECK(!(p1 == p2));
91 | }
92 |
93 | TEST_CASE(NaNComponents) {
94 | double const NaN = std::numeric_limits::quiet_NaN();
95 | // Creating a LonLat with NaN components should not throw.
96 | LonLat p1 = LonLat::fromRadians(NaN, NaN);
97 | CHECK(p1 != p1);
98 | // If one component is NaN, the other should be as well.
99 | LonLat p2 = LonLat::fromRadians(NaN, 0.5);
100 | LonLat p3 = LonLat::fromRadians(0.5, NaN);
101 | CHECK(p2.getLon().isNan() && p2.getLat().isNan());
102 | CHECK(p3.getLon().isNan() && p3.getLat().isNan());
103 | }
104 |
--------------------------------------------------------------------------------
/tests/testOrientation.cc:
--------------------------------------------------------------------------------
1 | /*
2 | * This file is part of sphgeom.
3 | *
4 | * Developed for the LSST Data Management System.
5 | * This product includes software developed by the LSST Project
6 | * (http://www.lsst.org).
7 | * See the COPYRIGHT file at the top-level directory of this distribution
8 | * for details of code ownership.
9 | *
10 | * This software is dual licensed under the GNU General Public License and also
11 | * under a 3-clause BSD license. Recipients may choose which of these licenses
12 | * to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
13 | * respectively. If you choose the GPL option then the following text applies
14 | * (but note that there is still no warranty even if you opt for BSD instead):
15 | *
16 | * This program is free software: you can redistribute it and/or modify
17 | * it under the terms of the GNU General Public License as published by
18 | * the Free Software Foundation, either version 3 of the License, or
19 | * (at your option) any later version.
20 | *
21 | * This program is distributed in the hope that it will be useful,
22 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
23 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
24 | * GNU General Public License for more details.
25 | *
26 | * You should have received a copy of the GNU General Public License
27 | * along with this program. If not, see .
28 | */
29 |
30 | /// \file
31 | /// \brief This file contains tests for the orientation function.
32 |
33 | #include "lsst/sphgeom/orientation.h"
34 |
35 | #include "test.h"
36 |
37 | using namespace lsst::sphgeom;
38 |
39 | void checkOrientation(UnitVector3d const & v0,
40 | UnitVector3d const & v1,
41 | UnitVector3d const & v2,
42 | int expectedOrientation)
43 | {
44 | CHECK(orientation(v0, v1, v2) == expectedOrientation);
45 | CHECK(orientationExact(v0, v1, v2) == expectedOrientation);
46 | if (v0.y() == 0.0 && v0.z() == 0.0) {
47 | if (v0.x() > 0.0) {
48 | CHECK(orientationX(v1, v2) == expectedOrientation);
49 | } else {
50 | CHECK(-orientationX(v1, v2) == expectedOrientation);
51 | }
52 | }
53 | if (v0.x() == 0.0 && v0.z() == 0.0) {
54 | if (v0.y() > 0.0) {
55 | CHECK(orientationY(v1, v2) == expectedOrientation);
56 | } else {
57 | CHECK(-orientationY(v1, v2) == expectedOrientation);
58 | }
59 | }
60 | if (v0.x() == 0.0 && v0.y() == 0.0) {
61 | if (v0.z() > 0.0) {
62 | CHECK(orientationZ(v1, v2) == expectedOrientation);
63 | } else {
64 | CHECK(-orientationZ(v1, v2) == expectedOrientation);
65 | }
66 | }
67 | }
68 |
69 | void testOrientation(UnitVector3d const & v0,
70 | UnitVector3d const & v1,
71 | UnitVector3d const & v2,
72 | int expectedOrientation)
73 | {
74 | checkOrientation(v0, v1, v2, expectedOrientation);
75 | checkOrientation(v0, v1, v2, expectedOrientation);
76 | checkOrientation(v1, v2, v0, expectedOrientation);
77 | checkOrientation(v2, v0, v1, expectedOrientation);
78 | checkOrientation(v1, v0, v2, -expectedOrientation);
79 | checkOrientation(v0, v2, v1, -expectedOrientation);
80 | checkOrientation(v2, v1, v0, -expectedOrientation);
81 | checkOrientation(v0, v0, v1, 0);
82 | checkOrientation(v0, -v0, v1, 0);
83 | checkOrientation(v0, v1, v1, 0);
84 | checkOrientation(v0, v1, -v1, 0);
85 | checkOrientation(v0, v1, v0, 0);
86 | checkOrientation(v0, v1, -v0, 0);
87 | }
88 |
89 | TEST_CASE(Orientation) {
90 | testOrientation(
91 | UnitVector3d::X(), UnitVector3d::Y(), UnitVector3d::Z(), 1);
92 | testOrientation(
93 | -UnitVector3d::X(), -UnitVector3d::Y(), -UnitVector3d::Z(), -1);
94 | }
95 |
96 | TEST_CASE(OrientationUnderflow) {
97 | UnitVector3d v0 = UnitVector3d::X();
98 | UnitVector3d v1 = UnitVector3d::fromNormalized(1.0, 1.0e-300, 0.0);
99 | UnitVector3d v2 = UnitVector3d::fromNormalized(1.0, 0.0, 1.0e-300);
100 | testOrientation(v0, v1, v2, 1);
101 | }
102 |
103 | TEST_CASE(OrientationOverflow) {
104 | Vector3d v0(1.0e300, 0, 0);
105 | Vector3d v1(1.0e300, 1.0e300, 0.0);
106 | Vector3d v2(1.0e300, 0.0, 1.0e300);
107 | CHECK(orientationExact(v0, v1, v2) == 1);
108 | }
109 |
--------------------------------------------------------------------------------
/tests/test_Angle.py:
--------------------------------------------------------------------------------
1 | # This file is part of sphgeom.
2 | #
3 | # Developed for the LSST Data Management System.
4 | # This product includes software developed by the LSST Project
5 | # (http://www.lsst.org).
6 | # See the COPYRIGHT file at the top-level directory of this distribution
7 | # for details of code ownership.
8 | #
9 | # This software is dual licensed under the GNU General Public License and also
10 | # under a 3-clause BSD license. Recipients may choose which of these licenses
11 | # to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
12 | # respectively. If you choose the GPL option then the following text applies
13 | # (but note that there is still no warranty even if you opt for BSD instead):
14 | #
15 | # This program is free software: you can redistribute it and/or modify
16 | # it under the terms of the GNU General Public License as published by
17 | # the Free Software Foundation, either version 3 of the License, or
18 | # (at your option) any later version.
19 | #
20 | # This program is distributed in the hope that it will be useful,
21 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 | # GNU General Public License for more details.
24 | #
25 | # You should have received a copy of the GNU General Public License
26 | # along with this program. If not, see .
27 | #
28 |
29 | import pickle
30 | import unittest
31 |
32 | from lsst.sphgeom import Angle
33 |
34 |
35 | class AngleTestCase(unittest.TestCase):
36 | """Test the Angle class."""
37 |
38 | def testConstruction(self):
39 | a1 = Angle(1.0)
40 | a2 = Angle.fromRadians(1.0)
41 | a3 = Angle.fromDegrees(57.29577951308232)
42 | self.assertEqual(a1, a2)
43 | self.assertEqual(a1.asRadians(), 1.0)
44 | self.assertEqual(a1, a3)
45 | self.assertEqual(a1.asDegrees(), 57.29577951308232)
46 |
47 | def testComparisonOperators(self):
48 | a1 = Angle(1)
49 | a2 = Angle(2)
50 | self.assertNotEqual(a1, a2)
51 | self.assertLess(a1, a2)
52 | self.assertLessEqual(a1, a2)
53 | self.assertGreater(a2, a1)
54 | self.assertGreaterEqual(a2, a1)
55 |
56 | def testArithmeticOperators(self):
57 | a = Angle(1)
58 | b = -a
59 | self.assertEqual(a + b, Angle(0))
60 | self.assertEqual(a - b, 2.0 * a)
61 | self.assertEqual(a - b, a * 2.0)
62 | self.assertEqual(a / 1.0, a)
63 | self.assertEqual(a / a, 1.0)
64 | a += a
65 | a *= 2
66 | a -= b
67 | a /= 5
68 | self.assertEqual(a.asRadians(), 1)
69 |
70 | def testString(self):
71 | self.assertEqual(str(Angle(1)), "1.0")
72 | self.assertEqual(repr(Angle(1)), "Angle(1.0)")
73 | a = Angle(2.5)
74 | self.assertEqual(a, eval(repr(a), {"Angle": Angle}))
75 |
76 | def testPickle(self):
77 | a = Angle(1.5)
78 | b = pickle.loads(pickle.dumps(a))
79 | self.assertEqual(a, b)
80 |
81 |
82 | if __name__ == "__main__":
83 | unittest.main()
84 |
--------------------------------------------------------------------------------
/tests/test_Chunker.py:
--------------------------------------------------------------------------------
1 | # This file is part of sphgeom.
2 | #
3 | # Developed for the LSST Data Management System.
4 | # This product includes software developed by the LSST Project
5 | # (http://www.lsst.org).
6 | # See the COPYRIGHT file at the top-level directory of this distribution
7 | # for details of code ownership.
8 | #
9 | # This software is dual licensed under the GNU General Public License and also
10 | # under a 3-clause BSD license. Recipients may choose which of these licenses
11 | # to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
12 | # respectively. If you choose the GPL option then the following text applies
13 | # (but note that there is still no warranty even if you opt for BSD instead):
14 | #
15 | # This program is free software: you can redistribute it and/or modify
16 | # it under the terms of the GNU General Public License as published by
17 | # the Free Software Foundation, either version 3 of the License, or
18 | # (at your option) any later version.
19 | #
20 | # This program is distributed in the hope that it will be useful,
21 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 | # GNU General Public License for more details.
24 | #
25 | # You should have received a copy of the GNU General Public License
26 | # along with this program. If not, see .
27 |
28 | import pickle
29 | import unittest
30 |
31 | from lsst.sphgeom import Box, Chunker
32 |
33 |
34 | class ChunkerTestCase(unittest.TestCase):
35 | """Test Chunker."""
36 |
37 | def testConstruction(self):
38 | chunker = Chunker(85, 12)
39 | self.assertEqual(chunker.numStripes, 85)
40 | self.assertEqual(chunker.numSubStripesPerStripe, 12)
41 |
42 | def testComparisonOperators(self):
43 | c = Chunker(85, 12)
44 | self.assertEqual(c, c)
45 | self.assertEqual(c, Chunker(85, 12))
46 | self.assertNotEqual(c, Chunker(85, 10))
47 |
48 | def testIntersecting(self):
49 | b = Box.fromDegrees(273.6, 30.7, 273.7180105379097, 30.722546655347717)
50 | c = Chunker(85, 12)
51 | self.assertEqual(c.getChunksIntersecting(b), [9630, 9631, 9797])
52 | self.assertEqual(c.getSubChunksIntersecting(b), [(9630, [770]), (9631, [759]), (9797, [11])])
53 |
54 | def testString(self):
55 | chunker = Chunker(85, 12)
56 | self.assertEqual(str(chunker), "Chunker(85, 12)")
57 | self.assertEqual(repr(chunker), "Chunker(85, 12)")
58 | self.assertEqual(chunker, eval(repr(chunker), {"Chunker": Chunker}))
59 |
60 | def testPickle(self):
61 | a = Chunker(85, 12)
62 | b = pickle.loads(pickle.dumps(a))
63 | self.assertEqual(a, b)
64 |
65 | def testChunkBoundingBox(self):
66 | chunker = Chunker(200, 5)
67 | chunk_id = 3645
68 | stripe = chunker.getStripe(chunk_id)
69 | chunk_in_stripe = chunker.getChunk(chunk_id, stripe)
70 | bbox = chunker.getChunkBoundingBox(stripe, chunk_in_stripe)
71 | sbbox = chunker.getSubChunkBoundingBox(0, 0)
72 | self.assertEqual(stripe, 9)
73 | self.assertEqual(chunk_in_stripe, 45)
74 | b = Box.fromRadians(5.048988193233824, -1.4294246573883558, 5.1611879309330035, -1.413716694110407)
75 | self.assertAlmostEqual(bbox, b)
76 | sb = Box.fromRadians(0.0, -1.5707963267948966, 6.283185307179586, -1.5676547341363067)
77 | self.assertAlmostEqual(sbbox, sb)
78 |
79 |
80 | if __name__ == "__main__":
81 | unittest.main()
82 |
--------------------------------------------------------------------------------
/tests/test_Interval1d.py:
--------------------------------------------------------------------------------
1 | # This file is part of sphgeom.
2 | #
3 | # Developed for the LSST Data Management System.
4 | # This product includes software developed by the LSST Project
5 | # (http://www.lsst.org).
6 | # See the COPYRIGHT file at the top-level directory of this distribution
7 | # for details of code ownership.
8 | #
9 | # This software is dual licensed under the GNU General Public License and also
10 | # under a 3-clause BSD license. Recipients may choose which of these licenses
11 | # to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
12 | # respectively. If you choose the GPL option then the following text applies
13 | # (but note that there is still no warranty even if you opt for BSD instead):
14 | #
15 | # This program is free software: you can redistribute it and/or modify
16 | # it under the terms of the GNU General Public License as published by
17 | # the Free Software Foundation, either version 3 of the License, or
18 | # (at your option) any later version.
19 | #
20 | # This program is distributed in the hope that it will be useful,
21 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 | # GNU General Public License for more details.
24 | #
25 | # You should have received a copy of the GNU General Public License
26 | # along with this program. If not, see .
27 |
28 | import pickle
29 | import unittest
30 |
31 | from lsst.sphgeom import CONTAINS, DISJOINT, Interval1d
32 |
33 |
34 | class Interval1dTestCase(unittest.TestCase):
35 | """Test 1D intervals."""
36 |
37 | def testConstruction(self):
38 | i = Interval1d(1)
39 | self.assertEqual(i.getA(), i.getB())
40 | self.assertEqual(i.getA(), 1)
41 | i = Interval1d(1, 2)
42 | self.assertEqual(i, Interval1d(1, 2))
43 | self.assertTrue(Interval1d.empty().isEmpty())
44 |
45 | def testComparisonOperators(self):
46 | self.assertEqual(Interval1d(1), Interval1d(1, 1))
47 | self.assertEqual(Interval1d(1), 1)
48 | self.assertNotEqual(Interval1d(1, 1), Interval1d(2, 2))
49 | self.assertNotEqual(Interval1d(2, 2), 1)
50 |
51 | def testCenterAndSize(self):
52 | i = Interval1d(1, 2)
53 | self.assertEqual(i.getSize(), 1)
54 | self.assertEqual(i.getCenter(), 1.5)
55 |
56 | def testRelationships(self):
57 | i02 = Interval1d(0, 2)
58 | i13 = Interval1d(1, 3)
59 | i46 = Interval1d(4, 6)
60 | i06 = Interval1d(0, 6)
61 | self.assertTrue(i02.contains(1))
62 | self.assertTrue(i02.contains(Interval1d(0.5, 1.5)))
63 | self.assertTrue(i02.isDisjointFrom(3))
64 | self.assertTrue(i02.isDisjointFrom(i46))
65 | self.assertTrue(i02.intersects(1))
66 | self.assertTrue(i02.intersects(i13))
67 | self.assertTrue(Interval1d(1, 1).isWithin(i02))
68 | self.assertTrue(i02.isWithin(i06))
69 | r = i02.relate(1)
70 | self.assertEqual(r, CONTAINS)
71 | r = i46.relate(i02)
72 | self.assertEqual(r, DISJOINT)
73 |
74 | def testExpandingAndClipping(self):
75 | a = Interval1d(1, 2)
76 | b = a.expandedTo(3).expandedTo(Interval1d(2, 4)).clippedTo(Interval1d(0, 2)).clippedTo(1)
77 | a.expandTo(3).expandTo(Interval1d(2, 4))
78 | a.clipTo(Interval1d(0, 2)).clipTo(1)
79 | self.assertEqual(a, b)
80 | self.assertEqual(a, 1)
81 |
82 | def testDilationAndErosion(self):
83 | a = Interval1d(1, 3)
84 | b = a.dilatedBy(1).erodedBy(2)
85 | a.dilateBy(1).erodeBy(2)
86 | self.assertEqual(a, b)
87 | self.assertEqual(a, 2)
88 |
89 | def testString(self):
90 | i = Interval1d(1, 2)
91 | self.assertEqual(str(i), "[1.0, 2.0]")
92 | self.assertEqual(repr(i), "Interval1d(1.0, 2.0)")
93 | self.assertEqual(i, eval(repr(i), {"Interval1d": Interval1d}))
94 |
95 | def testPickle(self):
96 | a = Interval1d(1.5, 3.5)
97 | b = pickle.loads(pickle.dumps(a))
98 | self.assertEqual(a, b)
99 |
100 |
101 | if __name__ == "__main__":
102 | unittest.main()
103 |
--------------------------------------------------------------------------------
/tests/test_LonLat.py:
--------------------------------------------------------------------------------
1 | # This file is part of sphgeom.
2 | #
3 | # Developed for the LSST Data Management System.
4 | # This product includes software developed by the LSST Project
5 | # (http://www.lsst.org).
6 | # See the COPYRIGHT file at the top-level directory of this distribution
7 | # for details of code ownership.
8 | #
9 | # This software is dual licensed under the GNU General Public License and also
10 | # under a 3-clause BSD license. Recipients may choose which of these licenses
11 | # to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
12 | # respectively. If you choose the GPL option then the following text applies
13 | # (but note that there is still no warranty even if you opt for BSD instead):
14 | #
15 | # This program is free software: you can redistribute it and/or modify
16 | # it under the terms of the GNU General Public License as published by
17 | # the Free Software Foundation, either version 3 of the License, or
18 | # (at your option) any later version.
19 | #
20 | # This program is distributed in the hope that it will be useful,
21 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 | # GNU General Public License for more details.
24 | #
25 | # You should have received a copy of the GNU General Public License
26 | # along with this program. If not, see .
27 |
28 | import pickle
29 | import unittest
30 |
31 | from lsst.sphgeom import Angle, LonLat, NormalizedAngle, UnitVector3d
32 |
33 |
34 | class LonLatTestCase(unittest.TestCase):
35 | """Test LonLat."""
36 |
37 | def testConstruction(self):
38 | p = LonLat.fromDegrees(45, 45)
39 | self.assertEqual(p, LonLat(NormalizedAngle.fromDegrees(45), Angle.fromDegrees(45)))
40 | u = UnitVector3d(p)
41 | q = LonLat(u)
42 | self.assertAlmostEqual(p.getLon().asRadians(), q.getLon().asRadians(), places=13)
43 | self.assertAlmostEqual(p.getLat().asRadians(), q.getLat().asRadians(), places=13)
44 | self.assertAlmostEqual(p.getLon().asRadians(), LonLat.latitudeOf(u).asRadians(), places=13)
45 | self.assertAlmostEqual(p.getLon().asRadians(), LonLat.longitudeOf(u).asRadians(), places=13)
46 |
47 | def testComparisonOperators(self):
48 | self.assertEqual(LonLat.fromDegrees(45, 45), LonLat.fromDegrees(45, 45))
49 | self.assertNotEqual(LonLat.fromDegrees(0, 0), LonLat.fromDegrees(45, 45))
50 |
51 | def testString(self):
52 | p = LonLat.fromRadians(1, 1)
53 | self.assertEqual(str(p), "[1.0, 1.0]")
54 | self.assertEqual(repr(p), "LonLat.fromRadians(1.0, 1.0)")
55 | self.assertEqual(p, eval(repr(p), {"LonLat": LonLat}))
56 |
57 | def testPickle(self):
58 | p = LonLat.fromRadians(2, 1)
59 | q = pickle.loads(pickle.dumps(p))
60 | self.assertEqual(p, q)
61 |
62 |
63 | if __name__ == "__main__":
64 | unittest.main()
65 |
--------------------------------------------------------------------------------
/tests/test_Mq3cPixelization.py:
--------------------------------------------------------------------------------
1 | # This file is part of sphgeom.
2 | #
3 | # Developed for the LSST Data Management System.
4 | # This product includes software developed by the LSST Project
5 | # (http://www.lsst.org).
6 | # See the COPYRIGHT file at the top-level directory of this distribution
7 | # for details of code ownership.
8 | #
9 | # This software is dual licensed under the GNU General Public License and also
10 | # under a 3-clause BSD license. Recipients may choose which of these licenses
11 | # to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
12 | # respectively. If you choose the GPL option then the following text applies
13 | # (but note that there is still no warranty even if you opt for BSD instead):
14 | #
15 | # This program is free software: you can redistribute it and/or modify
16 | # it under the terms of the GNU General Public License as published by
17 | # the Free Software Foundation, either version 3 of the License, or
18 | # (at your option) any later version.
19 | #
20 | # This program is distributed in the hope that it will be useful,
21 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 | # GNU General Public License for more details.
24 | #
25 | # You should have received a copy of the GNU General Public License
26 | # along with this program. If not, see .
27 |
28 | import pickle
29 |
30 | try:
31 | import yaml
32 | except ImportError:
33 | yaml = None
34 |
35 | import unittest
36 |
37 | from lsst.sphgeom import Angle, Circle, Mq3cPixelization, RangeSet, UnitVector3d
38 |
39 |
40 | class Mq3cPixelizationTestCase(unittest.TestCase):
41 | """Test MQ3C pixelization."""
42 |
43 | def test_construction(self):
44 | with self.assertRaises(ValueError):
45 | Mq3cPixelization(-1)
46 | with self.assertRaises(ValueError):
47 | Mq3cPixelization(Mq3cPixelization.MAX_LEVEL + 1)
48 | m1 = Mq3cPixelization(0)
49 | self.assertEqual(m1.getLevel(), 0)
50 | m2 = Mq3cPixelization(1)
51 | m3 = Mq3cPixelization(m2)
52 | self.assertNotEqual(m1, m2)
53 | self.assertEqual(m2, m3)
54 |
55 | def test_indexing(self):
56 | pixelization = Mq3cPixelization(1)
57 | self.assertEqual(pixelization.index(UnitVector3d(0.5, -0.5, 1.0)), 53)
58 |
59 | def test_level(self):
60 | self.assertEqual(Mq3cPixelization.level(0), -1)
61 | for level in range(Mq3cPixelization.MAX_LEVEL + 1):
62 | for root in range(8, 10):
63 | index = root * 4**level
64 | self.assertEqual(Mq3cPixelization.level(index), -1)
65 | for root in range(10, 16):
66 | index = root * 4**level
67 | self.assertEqual(Mq3cPixelization.level(index), level)
68 |
69 | def test_envelope_and_interior(self):
70 | pixelization = Mq3cPixelization(1)
71 | c = Circle(UnitVector3d(1.0, -0.5, -0.5), Angle.fromDegrees(0.1))
72 | rs = pixelization.envelope(c)
73 | self.assertTrue(rs == RangeSet(44))
74 | rs = pixelization.envelope(c, 1)
75 | self.assertTrue(rs == RangeSet(44))
76 | self.assertTrue(rs.isWithin(pixelization.universe()))
77 | rs = pixelization.interior(c)
78 | self.assertTrue(rs.empty())
79 |
80 | def test_index_to_string(self):
81 | strings = ["+X", "+Y", "+Z", "-X", "-Y", "-Z"]
82 | for i in range(6):
83 | s0 = strings[i]
84 | components = [0.0] * 3
85 | components[i % 3] = 1.0 if i < 3 else -1.0
86 | v = UnitVector3d(*components)
87 | f = Mq3cPixelization(0).index(v)
88 | self.assertEqual(Mq3cPixelization.asString(f), s0)
89 | self.assertEqual(Mq3cPixelization(0).toString(f), s0)
90 | for j in range(4):
91 | s1 = s0 + str(j)
92 | self.assertEqual(Mq3cPixelization.asString(f * 4 + j), s1)
93 | self.assertEqual(Mq3cPixelization(1).toString(f * 4 + j), s1)
94 |
95 | def test_string(self):
96 | p = Mq3cPixelization(3)
97 | self.assertEqual(str(p), "Mq3cPixelization(3)")
98 | self.assertEqual(str(p), repr(p))
99 | self.assertEqual(p, eval(repr(p), {"Mq3cPixelization": Mq3cPixelization}))
100 |
101 | def test_pickle(self):
102 | a = Mq3cPixelization(20)
103 | b = pickle.loads(pickle.dumps(a))
104 | self.assertEqual(a, b)
105 |
106 | @unittest.skipIf(not yaml, "YAML module can not be imported")
107 | def test_yaml(self):
108 | a = Mq3cPixelization(20)
109 | b = yaml.safe_load(yaml.dump(a))
110 | self.assertEqual(a, b)
111 |
112 |
113 | if __name__ == "__main__":
114 | unittest.main()
115 |
--------------------------------------------------------------------------------
/tests/test_NormalizedAngle.py:
--------------------------------------------------------------------------------
1 | # This file is part of sphgeom.
2 | #
3 | # Developed for the LSST Data Management System.
4 | # This product includes software developed by the LSST Project
5 | # (http://www.lsst.org).
6 | # See the COPYRIGHT file at the top-level directory of this distribution
7 | # for details of code ownership.
8 | #
9 | # This software is dual licensed under the GNU General Public License and also
10 | # under a 3-clause BSD license. Recipients may choose which of these licenses
11 | # to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
12 | # respectively. If you choose the GPL option then the following text applies
13 | # (but note that there is still no warranty even if you opt for BSD instead):
14 | #
15 | # This program is free software: you can redistribute it and/or modify
16 | # it under the terms of the GNU General Public License as published by
17 | # the Free Software Foundation, either version 3 of the License, or
18 | # (at your option) any later version.
19 | #
20 | # This program is distributed in the hope that it will be useful,
21 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 | # GNU General Public License for more details.
24 | #
25 | # You should have received a copy of the GNU General Public License
26 | # along with this program. If not, see .
27 |
28 | import pickle
29 | import unittest
30 |
31 | from lsst.sphgeom import Angle, LonLat, NormalizedAngle, UnitVector3d
32 |
33 |
34 | class NormalizedAngleTestCase(unittest.TestCase):
35 | """Test normalized angle."""
36 |
37 | def testConstruction(self):
38 | a1 = NormalizedAngle(1.0)
39 | a2 = NormalizedAngle.fromRadians(1.0)
40 | a3 = NormalizedAngle.fromDegrees(57.29577951308232)
41 | self.assertEqual(a1, a2)
42 | self.assertEqual(a1.asRadians(), 1.0)
43 | self.assertEqual(a1, a3)
44 | self.assertEqual(a1.asDegrees(), 57.29577951308232)
45 | self.assertEqual(NormalizedAngle.between(NormalizedAngle(0), NormalizedAngle(1)), NormalizedAngle(1))
46 | a = NormalizedAngle.center(NormalizedAngle(0), NormalizedAngle(1))
47 | self.assertAlmostEqual(a.asRadians(), 0.5, places=15)
48 | a = NormalizedAngle(LonLat.fromDegrees(45, 0), LonLat.fromDegrees(90, 0))
49 | self.assertAlmostEqual(a.asDegrees(), 45.0, places=13)
50 | a = NormalizedAngle(UnitVector3d.Y(), UnitVector3d.Z())
51 | self.assertAlmostEqual(a.asDegrees(), 90.0, places=13)
52 |
53 | def testComparisonOperators(self):
54 | a1 = NormalizedAngle(1)
55 | a2 = NormalizedAngle(2)
56 | self.assertNotEqual(a1, a2)
57 | self.assertLess(a1, a2)
58 | self.assertLessEqual(a1, a2)
59 | self.assertGreater(a2, a1)
60 | self.assertGreaterEqual(a2, a1)
61 |
62 | def testArithmeticOperators(self):
63 | a = NormalizedAngle(1)
64 | b = -a
65 | self.assertEqual(a + b, Angle(0))
66 | self.assertEqual(a - b, 2.0 * a)
67 | self.assertEqual(a - b, a * 2.0)
68 | self.assertEqual(a / 1.0, a)
69 | self.assertEqual(a / a, 1.0)
70 |
71 | def testAngleTo(self):
72 | self.assertEqual(NormalizedAngle(1).getAngleTo(NormalizedAngle(2)), NormalizedAngle(1))
73 |
74 | def testString(self):
75 | self.assertEqual(str(NormalizedAngle(1)), "1.0")
76 | self.assertEqual(repr(NormalizedAngle(1)), "NormalizedAngle(1.0)")
77 | a = NormalizedAngle(0.5)
78 | self.assertEqual(a, eval(repr(a), {"NormalizedAngle": NormalizedAngle}))
79 |
80 | def testPickle(self):
81 | a = NormalizedAngle(1.5)
82 | b = pickle.loads(pickle.dumps(a))
83 | self.assertEqual(a, b)
84 |
85 |
86 | if __name__ == "__main__":
87 | unittest.main()
88 |
--------------------------------------------------------------------------------
/tests/test_Q3cPixelization.py:
--------------------------------------------------------------------------------
1 | # This file is part of sphgeom.
2 | #
3 | # Developed for the LSST Data Management System.
4 | # This product includes software developed by the LSST Project
5 | # (http://www.lsst.org).
6 | # See the COPYRIGHT file at the top-level directory of this distribution
7 | # for details of code ownership.
8 | #
9 | # This software is dual licensed under the GNU General Public License and also
10 | # under a 3-clause BSD license. Recipients may choose which of these licenses
11 | # to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
12 | # respectively. If you choose the GPL option then the following text applies
13 | # (but note that there is still no warranty even if you opt for BSD instead):
14 | #
15 | # This program is free software: you can redistribute it and/or modify
16 | # it under the terms of the GNU General Public License as published by
17 | # the Free Software Foundation, either version 3 of the License, or
18 | # (at your option) any later version.
19 | #
20 | # This program is distributed in the hope that it will be useful,
21 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 | # GNU General Public License for more details.
24 | #
25 | # You should have received a copy of the GNU General Public License
26 | # along with this program. If not, see .
27 |
28 | import pickle
29 |
30 | try:
31 | import yaml
32 | except ImportError:
33 | yaml = None
34 |
35 | import unittest
36 |
37 | from lsst.sphgeom import Angle, Circle, ConvexPolygon, Q3cPixelization, RangeSet, UnitVector3d
38 |
39 |
40 | class Q3cPixelizationTestCase(unittest.TestCase):
41 | """Test Q3C pixelization."""
42 |
43 | def test_construction(self):
44 | with self.assertRaises(ValueError):
45 | Q3cPixelization(-1)
46 | with self.assertRaises(ValueError):
47 | Q3cPixelization(Q3cPixelization.MAX_LEVEL + 1)
48 | q1 = Q3cPixelization(0)
49 | self.assertEqual(q1.getLevel(), 0)
50 | q2 = Q3cPixelization(1)
51 | q3 = Q3cPixelization(q2)
52 | self.assertNotEqual(q1, q2)
53 | self.assertEqual(q2, q3)
54 |
55 | def test_indexing(self):
56 | pixelization = Q3cPixelization(1)
57 | self.assertEqual(pixelization.index(UnitVector3d(0.5, -0.5, 1.0)), 0)
58 |
59 | def test_pixel(self):
60 | h = Q3cPixelization(1)
61 | self.assertIsInstance(h.pixel(10), ConvexPolygon)
62 |
63 | def test_envelope_and_interior(self):
64 | pixelization = Q3cPixelization(1)
65 | c = Circle(UnitVector3d(1.0, -0.5, -0.5), Angle.fromDegrees(0.1))
66 | rs = pixelization.envelope(c)
67 | self.assertTrue(rs == RangeSet(4))
68 | rs = pixelization.envelope(c, 1)
69 | self.assertTrue(rs == RangeSet(4))
70 | self.assertTrue(rs.isWithin(pixelization.universe()))
71 | rs = pixelization.interior(c)
72 | self.assertTrue(rs.empty())
73 |
74 | def test_index_to_string(self):
75 | strings = ["+X", "+Y", "+Z", "-X", "-Y", "-Z"]
76 | for i in range(6):
77 | s = strings[i]
78 | components = [0.0] * 3
79 | components[i % 3] = 1.0 if i < 3 else -1.0
80 | v = UnitVector3d(*components)
81 | f = Q3cPixelization(0).index(v)
82 | self.assertEqual(Q3cPixelization(0).toString(f), s)
83 | for j in range(4):
84 | self.assertEqual(Q3cPixelization(1).toString(f * 4 + j), s + str(j))
85 |
86 | def test_string(self):
87 | p = Q3cPixelization(3)
88 | self.assertEqual(str(p), "Q3cPixelization(3)")
89 | self.assertEqual(str(p), repr(p))
90 | self.assertEqual(p, eval(repr(p), {"Q3cPixelization": Q3cPixelization}))
91 |
92 | def test_pickle(self):
93 | a = Q3cPixelization(20)
94 | b = pickle.loads(pickle.dumps(a))
95 | self.assertEqual(a, b)
96 |
97 | @unittest.skipIf(not yaml, "YAML module can not be imported")
98 | def test_yaml(self):
99 | a = Q3cPixelization(20)
100 | b = yaml.safe_load(yaml.dump(a))
101 | self.assertEqual(a, b)
102 |
103 |
104 | if __name__ == "__main__":
105 | unittest.main()
106 |
--------------------------------------------------------------------------------
/tests/test_RangeSet.py:
--------------------------------------------------------------------------------
1 | # This file is part of sphgeom.
2 | #
3 | # Developed for the LSST Data Management System.
4 | # This product includes software developed by the LSST Project
5 | # (http://www.lsst.org).
6 | # See the COPYRIGHT file at the top-level directory of this distribution
7 | # for details of code ownership.
8 | #
9 | # This software is dual licensed under the GNU General Public License and also
10 | # under a 3-clause BSD license. Recipients may choose which of these licenses
11 | # to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
12 | # respectively. If you choose the GPL option then the following text applies
13 | # (but note that there is still no warranty even if you opt for BSD instead):
14 | #
15 | # This program is free software: you can redistribute it and/or modify
16 | # it under the terms of the GNU General Public License as published by
17 | # the Free Software Foundation, either version 3 of the License, or
18 | # (at your option) any later version.
19 | #
20 | # This program is distributed in the hope that it will be useful,
21 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 | # GNU General Public License for more details.
24 | #
25 | # You should have received a copy of the GNU General Public License
26 | # along with this program. If not, see .
27 |
28 | import pickle
29 | import unittest
30 |
31 | from lsst.sphgeom import RangeSet
32 |
33 |
34 | class RangeSetTestCase(unittest.TestCase):
35 | """Test RangeSet."""
36 |
37 | def testConstruction(self):
38 | s1 = RangeSet(1)
39 | s2 = RangeSet()
40 | s3 = RangeSet(2, 1)
41 | s4 = RangeSet(s3)
42 | self.assertTrue(s2.empty())
43 | self.assertEqual(s3, s4)
44 | self.assertEqual(s1, s3.complement())
45 |
46 | def testComparisonOperators(self):
47 | s1 = RangeSet(1)
48 | s2 = RangeSet(2)
49 | self.assertNotEqual(s1, s2)
50 | s1.insert(2)
51 | s2.insert(1)
52 | self.assertEqual(s1, s2)
53 | self.assertTrue(RangeSet(2, 1).contains(RangeSet(3, 4)))
54 | self.assertTrue(RangeSet(2, 1).contains(3, 4))
55 | self.assertTrue(RangeSet(2, 1).contains(3))
56 | self.assertTrue(RangeSet(2, 4).isWithin(RangeSet(1, 5)))
57 | self.assertTrue(RangeSet(2, 4).isWithin(1, 5))
58 | self.assertFalse(RangeSet(2, 4).isWithin(3))
59 | self.assertTrue(RangeSet(2, 4).intersects(RangeSet(3, 5)))
60 | self.assertTrue(RangeSet(2, 4).intersects(3, 5))
61 | self.assertTrue(RangeSet(2, 4).intersects(3))
62 | self.assertTrue(RangeSet(2, 4).isDisjointFrom(RangeSet(6, 8)))
63 | self.assertTrue(RangeSet(2, 4).isDisjointFrom(6, 8))
64 | self.assertTrue(RangeSet(2, 4).isDisjointFrom(6))
65 |
66 | def testSetOperators(self):
67 | a = RangeSet(1)
68 | b = ~a
69 | self.assertTrue((a | b).full())
70 | self.assertTrue((a & b).empty())
71 | self.assertEqual(a - b, a)
72 | self.assertEqual(b - a, b)
73 | a &= a
74 | b &= b
75 | c = (a ^ b) - RangeSet(2, 4)
76 | self.assertEqual(c, RangeSet(4, 2))
77 | c |= b
78 | self.assertTrue(c.full())
79 | c ^= c
80 | self.assertTrue(c.empty())
81 |
82 | def testRanges(self):
83 | s = RangeSet()
84 | s.insert(0, 1)
85 | s.insert(2, 3)
86 | self.assertEqual(s.ranges(), [(0, 1), (2, 3)])
87 | s = RangeSet(4, 2)
88 | self.assertEqual(list(s), [(0, 2), (4, 0)])
89 |
90 | def testString(self):
91 | s = RangeSet(1, 10)
92 | self.assertEqual(str(s), "[(1, 10)]")
93 | self.assertEqual(repr(s), "RangeSet([(1, 10)])")
94 | self.assertEqual(s, eval(repr(s), {"RangeSet": RangeSet}))
95 |
96 | def testPickle(self):
97 | r = RangeSet([2, 3, 5, 7, 11, 13, 17, 19])
98 | s = pickle.loads(pickle.dumps(r))
99 | self.assertEqual(r, s)
100 |
101 |
102 | if __name__ == "__main__":
103 | unittest.main()
104 |
--------------------------------------------------------------------------------
/tests/test_Vector3d.py:
--------------------------------------------------------------------------------
1 | # This file is part of sphgeom.
2 | #
3 | # Developed for the LSST Data Management System.
4 | # This product includes software developed by the LSST Project
5 | # (http://www.lsst.org).
6 | # See the COPYRIGHT file at the top-level directory of this distribution
7 | # for details of code ownership.
8 | #
9 | # This software is dual licensed under the GNU General Public License and also
10 | # under a 3-clause BSD license. Recipients may choose which of these licenses
11 | # to use; please see the files gpl-3.0.txt and/or bsd_license.txt,
12 | # respectively. If you choose the GPL option then the following text applies
13 | # (but note that there is still no warranty even if you opt for BSD instead):
14 | #
15 | # This program is free software: you can redistribute it and/or modify
16 | # it under the terms of the GNU General Public License as published by
17 | # the Free Software Foundation, either version 3 of the License, or
18 | # (at your option) any later version.
19 | #
20 | # This program is distributed in the hope that it will be useful,
21 | # but WITHOUT ANY WARRANTY; without even the implied warranty of
22 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 | # GNU General Public License for more details.
24 | #
25 | # You should have received a copy of the GNU General Public License
26 | # along with this program. If not, see .
27 |
28 | import math
29 | import pickle
30 | import unittest
31 |
32 | from lsst.sphgeom import Angle, UnitVector3d, Vector3d
33 |
34 |
35 | class Vector3dTestCase(unittest.TestCase):
36 | """Test 3D vector."""
37 |
38 | def testConstruction(self):
39 | v = Vector3d(1, 2, 3)
40 | self.assertEqual(v.x(), 1)
41 | self.assertEqual(v.y(), 2)
42 | self.assertEqual(v.z(), 3)
43 |
44 | def testComparison(self):
45 | v = Vector3d(1, 2, 3)
46 | self.assertEqual(v, Vector3d(1, 2, 3))
47 | self.assertNotEqual(v, Vector3d(1, 2, 4))
48 |
49 | def testIsZero(self):
50 | self.assertTrue(Vector3d(0, 0, 0).isZero())
51 | self.assertFalse(Vector3d(0, 0, 1).isZero())
52 |
53 | def testAccess(self):
54 | v = Vector3d(1, 2, 3)
55 | self.assertEqual(len(v), 3)
56 | self.assertEqual(v[0], 1)
57 | self.assertEqual(v[1], 2)
58 | self.assertEqual(v[2], 3)
59 | self.assertEqual(v[-3], 1)
60 | self.assertEqual(v[-2], 2)
61 | self.assertEqual(v[-1], 3)
62 | with self.assertRaises(IndexError):
63 | v[-4]
64 | with self.assertRaises(IndexError):
65 | v[3]
66 |
67 | def testNormal(self):
68 | v = Vector3d(0, 2, 0)
69 | self.assertEqual(v.getSquaredNorm(), 4)
70 | self.assertEqual(v.getNorm(), 2)
71 | v.normalize()
72 | self.assertTrue(v.isNormalized())
73 | self.assertEqual(v, Vector3d(0, 1, 0))
74 |
75 | def testDot(self):
76 | x = Vector3d(1, 0, 0)
77 | y = Vector3d(0, 1, 0)
78 | self.assertEqual(x.dot(y), 0)
79 |
80 | def testCross(self):
81 | x = Vector3d(1, 0, 0)
82 | y = Vector3d(0, 1, 0)
83 | self.assertEqual(x.cross(y), Vector3d(0, 0, 1))
84 |
85 | def testArithmeticOperators(self):
86 | self.assertEqual(-Vector3d(1, 1, 1), Vector3d(-1, -1, -1))
87 | self.assertEqual(Vector3d(1, 1, 1) * 2, Vector3d(2, 2, 2))
88 | self.assertEqual(Vector3d(2, 2, 2) / 2, Vector3d(1, 1, 1))
89 | self.assertEqual(Vector3d(1, 1, 1) + Vector3d(1, 1, 1), Vector3d(2, 2, 2))
90 | self.assertEqual(Vector3d(1, 1, 1) - Vector3d(1, 1, 1), Vector3d())
91 | v = Vector3d(1, 1, 1)
92 | v += Vector3d(3, 3, 3)
93 | v -= Vector3d(2, 2, 2)
94 | v *= 2.0
95 | v /= 4.0
96 | self.assertEqual(v, Vector3d(1, 1, 1))
97 | self.assertEqual(v.cwiseProduct(Vector3d(2, 3, 4)), Vector3d(2, 3, 4))
98 |
99 | def testRotation(self):
100 | v = Vector3d(0, 1, 0).rotatedAround(UnitVector3d.X(), Angle(0.5 * math.pi))
101 | self.assertAlmostEqual(v.x(), 0.0, places=15)
102 | self.assertAlmostEqual(v.y(), 0.0, places=15)
103 | self.assertAlmostEqual(v.z(), 1.0, places=15)
104 |
105 | def testString(self):
106 | v = Vector3d(1, 0, 0)
107 | self.assertEqual(str(v), "[1.0, 0.0, 0.0]")
108 | self.assertEqual(repr(v), "Vector3d(1.0, 0.0, 0.0)")
109 | self.assertEqual(v, eval(repr(v), {"Vector3d": Vector3d}))
110 |
111 | def testPickle(self):
112 | v = Vector3d(1, 2, 3)
113 | w = pickle.loads(pickle.dumps(v))
114 | self.assertEqual(v, w)
115 |
116 |
117 | if __name__ == "__main__":
118 | unittest.main()
119 |
--------------------------------------------------------------------------------
/ups/sphgeom.build:
--------------------------------------------------------------------------------
1 | @LSST BUILD@ &&
2 | build_lsst @PRODUCT@ @VERSION@ @REPOVERSION@
3 |
--------------------------------------------------------------------------------
/ups/sphgeom.cfg:
--------------------------------------------------------------------------------
1 | # -*- python -*-
2 |
3 | import lsst.sconsUtils
4 |
5 | dependencies = {
6 | "required": [],
7 | "buildRequired": ["pybind11"],
8 | }
9 |
10 | config = lsst.sconsUtils.Configuration(
11 | __file__,
12 | headers=[],
13 | hasDoxygenInclude=False,
14 | )
15 |
--------------------------------------------------------------------------------
/ups/sphgeom.table:
--------------------------------------------------------------------------------
1 | setupRequired(sconsUtils)
2 |
3 | envPrepend(LD_LIBRARY_PATH, ${PRODUCT_DIR}/lib)
4 | envPrepend(DYLD_LIBRARY_PATH, ${PRODUCT_DIR}/lib)
5 | envPrepend(LSST_LIBRARY_PATH, ${PRODUCT_DIR}/lib)
6 | envPrepend(PYTHONPATH, ${PRODUCT_DIR}/python)
7 |
--------------------------------------------------------------------------------