Skip to content

Commit

Permalink
Merge pull request #203 from desihub/desiname
Browse files Browse the repository at this point in the history
Add radec_to_desiname function
  • Loading branch information
akremin committed Nov 29, 2023
2 parents 93aca73 + 0b47719 commit 0f4e08d
Show file tree
Hide file tree
Showing 5 changed files with 147 additions and 3 deletions.
31 changes: 29 additions & 2 deletions .github/workflows/python-package.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ jobs:
fail-fast: true
matrix:
os: [ubuntu-latest]
python-version: ['3.8', '3.9', '3.10'] # , '3.11'] Astropy 5.0 may be incompatible with Python 3.11
python-version: ['3.9', '3.10'] #, '3.11'] There are still issues with Numpy <1.23 and 3.11.
numpy-version: ['<1.23']
astropy-version: ['==5.0', '<5.1', '<6.0']
astropy-version: ['<5.1', '<6.0', '<7.0']

steps:
- name: Checkout code
Expand Down Expand Up @@ -93,6 +93,33 @@ jobs:
- name: Test the documentation
run: sphinx-build -W --keep-going -b html doc doc/_build/html

api:
name: API doc completeness test
runs-on: ${{ matrix.os }}
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest]
python-version: ['3.10']

steps:
- name: Checkout code
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Set up Python ${{ matrix.python-version }}
uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python-version }}
- name: Install Python dependencies
run: |
python -m pip install --upgrade pip setuptools wheel
python -m pip install --editable .
- name: Generate api.rst
run: ./bin/desi_api_file --api ./api.rst desiutil
- name: Compare generated api.rst to checked-in version
run: diff --ignore-space-change --ignore-blank-lines ./api.rst ./doc/api.rst

style:
name: Style check
runs-on: ${{ matrix.os }}
Expand Down
3 changes: 3 additions & 0 deletions doc/api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ desiutil API
.. automodule:: desiutil.modules
:members:

.. automodule:: desiutil.names
:members:

.. automodule:: desiutil.plots
:members:

Expand Down
6 changes: 5 additions & 1 deletion doc/changes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,13 @@ Change Log
3.4.2 (unreleased)
------------------

* Fully support adding units and comments to FITS table columns (PR `#201`).
* Fully support adding units and comments to FITS table columns (PR `#201`_).
* Created :mod:`desiutil.names` and added a function to it that takes an RA
and DEC and produces a DESINAME that can be used to refer to a DESI
object at that sky location (PR `#203`_).

.. _`#201`: https://github.com/desihub/desiutil/pull/201
.. _`#203`: https://github.com/desihub/desiutil/pull/203

3.4.1 (2023-09-25)
------------------
Expand Down
64 changes: 64 additions & 0 deletions py/desiutil/names.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Licensed under a 3-clause BSD style license - see LICENSE.rst
# -*- coding: utf-8 -*-
"""
==============
desiutil.names
==============
This package contains functions for naming 'things' in DESI
or decoding those names.
"""
import numpy as np


def radec_to_desiname(target_ra, target_dec):
"""Convert the right ascension and declination of a DESI target
into the corresponding "DESINAME" for reference in publications.
Length of target_ra and target_dec must be the same if providing an
array or list. Note that these names are not unique for roughly
one percent of DESI targets, so also including TARGETID in
publications is highly recommended for uniqueness.
Parameters
----------
target_ra: array of :class:`float64`
Right ascension in degrees of target object(s). Can be float, double,
or array/list of floats or doubles
target_dec: array of :class:`float64`
Declination in degrees of target object(s). Can be float, double,
or array/list of floats or doubles
Returns
-------
array of :class:`str`
The DESI names referring to the input target RA and DEC's. Array is
the same length as the input arrays.
"""
# Convert to numpy array in case inputs are scalars or lists
target_ra, target_dec = np.atleast_1d(target_ra), np.atleast_1d(target_dec)

# Number of decimal places in final naming convention
precision = 4

# Truncate decimals to the given precision
ratrunc = np.trunc((10 ** precision) * target_ra).astype(int).astype(str)
dectrunc = np.trunc((10 ** precision) * target_dec).astype(int).astype(str)

# Loop over input values and create DESINAME as: DESI JXXX.XXXX+/-YY.YYYY
# Here J refers to J2000, which isn't strictly correct but is the closest
# IAU compliant term
desinames = []
for ra, dec in zip(ratrunc, dectrunc):
desiname = 'DESI J' + ra[:-precision].zfill(3) + '.' + ra[-precision:]
# Positive numbers need an explicit "+" while negative numbers
# already have a "-".
# zfill works properly with '-' but counts it in number of characters
# so need one more
if dec.startswith('-'):
desiname += dec[:-precision].zfill(3) + '.' + dec[-precision:]
else:
desiname += '+' + dec[:-precision].zfill(2) + '.' + dec[-precision:]
desinames.append(desiname)

return np.array(desinames)
46 changes: 46 additions & 0 deletions py/desiutil/test/test_names.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# Licensed under a 3-clause BSD style license - see LICENSE.rst
# -*- coding: utf-8 -*-
"""Test desiutil.names.
"""
import unittest
import numpy as np


class TestNames(unittest.TestCase):
"""Test desiutil.names
"""

@classmethod
def setUpClass(cls):
pass

@classmethod
def tearDownClass(cls):
pass

def test_radec_to_desiname(self):
"""Test MaskedArrayWithLimits
"""
from ..names import radec_to_desiname
ras = [6.2457354547234, 23.914121939862518, 36.23454570972834,
235.25235223446, 99.9999999999999]
decs = [29.974787585945496, -42.945872347904356, -0.9968423456,
8.45677345352345, 89.234958294953]
correct_names = np.array(['DESI J006.2457+29.9747',
'DESI J023.9141-42.9458',
'DESI J036.2345-00.9968',
'DESI J235.2523+08.4567',
'DESI J099.9999+89.2349'])
# Test scalar conversion
for ra, dec, correct_name in zip(ras, decs, correct_names):
outname = radec_to_desiname(ra, dec)
self.assertEqual(outname, correct_name)

# Test list conversion
outnames = radec_to_desiname(ras, decs)
self.assertTrue(np.alltrue(outnames == correct_names))

# Test array conversion
outnames = radec_to_desiname(np.array(ras),
np.array(decs))
self.assertTrue(np.alltrue(outnames == correct_names))

0 comments on commit 0f4e08d

Please sign in to comment.