├── .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 | --------------------------------------------------------------------------------