Skip to content

Commit

Permalink
Merge pull request #271 from mkelley/names-pkd-missing-j
Browse files Browse the repository at this point in the history
Fix Name.from_packed typo; add (un)packing tests.
  • Loading branch information
mkelley committed Sep 26, 2021
2 parents da3230c + 476b5db commit 61c9aba
Show file tree
Hide file tree
Showing 2 changed files with 159 additions and 52 deletions.
125 changes: 80 additions & 45 deletions sbpy/data/names.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,6 @@
"""

from ..exceptions import SbpyException
from .core import DataClass
from numpy import ndarray

__all__ = ['Names', 'TargetNameParseError', 'natural_sort_key']

Expand Down Expand Up @@ -68,11 +66,11 @@ class Names():

# packed numbers translation string
pkd = ('0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
'abcdefghifklmnopqrstuvwxyz')
'abcdefghijklmnopqrstuvwxyz')

@staticmethod
def to_packed(s):
"""Convert asteroid designation/number to packed identifier.
"""Convert designation or number to packed identifier.
Parameters
----------
Expand All @@ -91,37 +89,74 @@ def to_packed(s):
'J95A01A'
"""

if s.isdigit() and not s.isalpha():
if s.isdigit():
# number
s = int(s)
if s < 100000:
return ('{:05d}'.format(s))
return '{:05d}'.format(s)
elif s > 619999:
raise TargetNameParseError(
('{} cannot be turned into a '
'packed number').format(s))
'{} cannot be turned into a packed number'.format(s)
)
else:
mod = (s % 10000)
return ('{}{:04d}'.format(
Names.pkd[int((s-mod)/10000)],
mod))
elif s.isalnum and not s.isdigit() and not s.isalpha():
# designation
yr = s.strip()[:4]
yr = Names.pkd[int(float(yr[:2]))]+yr[2:]
let = s.strip()[4:7].strip()
num = s.strip()[7:].strip()
if num == '':
num = '00'
elif len(num) == 1:
num = '0' + num
elif len(num) > 2:
try:
num = Names.pkd[int(float(num[:-1]))]+num[-1]
except (IndexError, ValueError):
raise TargetNameParseError(
('{} cannot be turned into a '
'packed designation').format(s))
return '{}{:04d}'.format(
Names.pkd[int((s - mod) / 10000)], mod)
elif s.endswith('P-L'):
return 'PLS{}'.format(s[:4])
elif s[-3:] in ['T-1', 'T-2', 'T-3']:
return 'T{}S{}'.format(s[-1], s[:4])
elif s[:4].isdigit() and (s[5:].isalnum() or s[5:s.find('-')].isalnum()):
# cometary or minor planet temporary designation

# when the half-month and number are two digits: cometary
# when there is a trailing fragment designation: cometary
# otherwise: minor planet
if (
(s[5].isalpha() and s[6:].isdigit())
or (s[-2] == '-' and s[-1].isalpha())
):
if s[-2] == '-':
frag = s[-1]
num = s[6:-2]
else:
frag = '0'
num = s[6:]

if num == '':
num = '00'
elif len(num) == 1:
num = '0' + num
elif len(num) > 2:
try:
num = Names.pkd[int(num[:-1])]+num[-1]
except (IndexError, ValueError):
raise TargetNameParseError(
('{} cannot be turned into a '
'packed designation').format(s))
return '{}{}{}{}{}'.format(
Names.pkd[int(float(s[:2]))],
s[2:4],
s[5],
num,
frag.lower()
)
else:
yr = s.strip()[:4]
yr = Names.pkd[int(yr[:2])] + yr[2:]
let = s.strip()[4:7].strip()
num = s.strip()[7:].strip()
if num == '':
num = '00'
elif len(num) == 1:
num = '0' + num
elif len(num) > 2:
try:
num = Names.pkd[int(num[:-1])]+num[-1]
except (IndexError, ValueError):
raise TargetNameParseError(
('{} cannot be turned into a '
'packed designation').format(s))
return (yr + let[0] + num + let[1])

else:
Expand Down Expand Up @@ -156,33 +191,33 @@ def from_packed(p):
return int(str(Names.pkd.find(p[0])) + p[1:])

# old designation style, e.g.: 1989AB
if (len(p.strip()) < 7 and p[:4].isdigit() and
p[4:6].isalpha()):
if (len(p.strip()) < 7 and p[:4].isdigit() and p[4:6].isalpha()):
return p[:4]+' '+p[4:6]
# Palomar Survey
elif p.find("PLS") == 0:
elif p.startswith("PLS"):
return p[3:] + " P-L"
# Trojan Surveys
elif p.find("T1S") == 0:
elif p.startswith("T1S"):
return p[3:] + " T-1"
elif p.find("T2S") == 0:
elif p.startswith("T2S"):
return p[3:] + " T-2"
elif p.find("T3S") == 0:
elif p.startswith("T3S"):
return p[3:] + " T-3"
# insert blank in designations
elif (p[0:4].isdigit() and p[4:6].isalpha() and
p[4] != ' '):
return p[:4]+" "+p[4:]
elif (p[0:4].isdigit() and p[4:6].isalpha() and p[4] != ' '):
return p[:4] + " " + p[4:]
# MPC packed 7-digit designation
elif (p[0].isalpha() and p[1:3].isdigit() and
p[-1].isalpha() and p[-2].isdigit()):
yr = str(Names.pkd.find(p[0]))+p[1:3]
let = p[3]+p[-1]
num = str(Names.pkd.find(p[4]))+p[5]
num = num.lstrip("0")
return yr+' '+let+num
# nothing to do
elif (p[0].isalpha() and p[1:3].isdigit() and p[-2].isdigit()):
return '{}{} {}{}{}{}'.format(
str(Names.pkd.find(p[0])),
p[1:3],
p[3],
p[6] if (p[6].isalpha() and p[6].isupper()) else '',
(str(Names.pkd.find(p[4])) + p[5]).lstrip('0'),
'-{}'.format(p[6].upper()) if p[6].islower() else ''
)
else:
# nothing to do
return p

@staticmethod
Expand Down
86 changes: 79 additions & 7 deletions sbpy/data/tests/test_names.py
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,15 @@ def test_natural_sort_key():
assert all([i == t for i, t in zip(items, test)])


def test_pkd():
"""Regression test for #270.
Verify that all letters and numbers appear just once.
"""
assert len(set(Names.pkd)) == len(Names.pkd)


def test_asteroid_or_comet():
"""Test target name identification."""
for comet in comets:
Expand All @@ -83,23 +92,86 @@ def test_asteroid_or_comet():
'failed for {}'.format(asteroid)


def test_packed():
"""Test packed numbers and designations"""
assert Names.to_packed('1995 XA') == 'J95X00A'
assert Names.to_packed('2007 TA418') == 'K07Tf8A'
assert Names.to_packed('50000') == '50000'
assert Names.to_packed('100345') == 'A0345'
assert Names.to_packed('360017') == 'a0017'
def test_from_packed():
"""Test packed numbers and designations.
Test values from https://www.minorplanetcenter.net/iau/info/PackedDes.html
"""

# minor planets
assert Names.from_packed('J95X00A') == '1995 XA'
assert Names.from_packed('J95X01L') == '1995 XL1'
assert Names.from_packed('J95F13B') == '1995 FB13'
assert Names.from_packed('J98SA8Q') == '1998 SQ108'
assert Names.from_packed('J98SC7V') == '1998 SV127'
assert Names.from_packed('J98SG2S') == '1998 SS162'
assert Names.from_packed('K99AJ3Z') == '2099 AZ193'
assert Names.from_packed('K08Aa0A') == '2008 AA360'
assert Names.from_packed('K07Tf8A') == '2007 TA418'

# survey designations
assert Names.from_packed('PLS2040') == '2040 P-L'
assert Names.from_packed('T1S3138') == '3138 T-1'
assert Names.from_packed('T2S1010') == '1010 T-2'
assert Names.from_packed('T3S4101') == '4101 T-3'

# comets
assert Names.from_packed('J95A010') == '1995 A1'
assert Names.from_packed('J94P01b') == '1994 P1-B'
assert Names.from_packed('J94P010') == '1994 P1'
assert Names.from_packed('K48X130') == '2048 X13'
assert Names.from_packed('K33L89c') == '2033 L89-C'
assert Names.from_packed('K88AA30') == '2088 A103'

# a few other tests
assert Names.from_packed('50000') == 50000
assert Names.from_packed('A0345') == 100345
assert Names.from_packed('a0017') == 360017
assert Names.from_packed('1989AB') == '1989 AB'
assert Names.from_packed('2000 AA') == '2000 AA'


def test_to_packed():
"""Test packed numbers and designations.
Test values from https://www.minorplanetcenter.net/iau/info/PackedDes.html
"""

# minor planets
assert Names.to_packed('1995 XA') == 'J95X00A'
assert Names.to_packed('1995 XL1') == 'J95X01L'
assert Names.to_packed('1995 FB13') == 'J95F13B'
assert Names.to_packed('1998 SQ108') == 'J98SA8Q'
assert Names.to_packed('1998 SV127') == 'J98SC7V'
assert Names.to_packed('1998 SS162') == 'J98SG2S'
assert Names.to_packed('2099 AZ193') == 'K99AJ3Z'
assert Names.to_packed('2008 AA360') == 'K08Aa0A'
assert Names.to_packed('2007 TA418') == 'K07Tf8A'

# survey designations
assert Names.to_packed('2040 P-L') == 'PLS2040'
assert Names.to_packed('3138 T-1') == 'T1S3138'
assert Names.to_packed('1010 T-2') == 'T2S1010'
assert Names.to_packed('4101 T-3') == 'T3S4101'

# comets
assert Names.to_packed('1995 A1') == 'J95A010'
assert Names.to_packed('1994 P1-B') == 'J94P01b'
assert Names.to_packed('1994 P1') == 'J94P010'
assert Names.to_packed('2048 X13') == 'K48X130'
assert Names.to_packed('2033 L89-C') == 'K33L89c'
assert Names.to_packed('2088 A103') == 'K88AA30'

# a few other tests
assert Names.to_packed('50000') == '50000'
assert Names.to_packed('100345') == 'A0345'
assert Names.to_packed('360017') == 'a0017'
assert Names.to_packed('1989 AB') == 'J89A00B'
assert Names.to_packed('2000AA') == 'K00A00A'


def test_parse_comet():
"""Test comet name parsing."""

Expand Down

0 comments on commit 61c9aba

Please sign in to comment.