Simplify and test new out-of-range exception

1. Remove “Timestamp” from the exception name since no timestamps are
   involved; the values are barycentric Julian dates.

2. Display Julian date values in the error message, since those are the
   actual time values that users will have submitted.

3. Remove the “min” and “max” attributes because it turns out that (even
   though I had forgotten!) those values are already available as
   attributes on the class.

4. Added a test to hopefully keep the new feature working.

5. Added the new feature to the changelog.
This commit is contained in:
Brandon Rhodes 2020-01-04 16:00:58 -05:00
parent 7c94589a25
commit 58b889b052
4 changed files with 36 additions and 22 deletions

View File

@ -351,6 +351,14 @@ https://github.com/brandon-rhodes/python-jplephem/
Changelog
---------
**(Next version)**
* The ``ValueError`` thrown when a compute method is given a Julian date
outside the range it supports is now a subclass ``OutOfRangeError``
that reminds the caller of the acceptible range of dates of the SPK
segment, and carries an array attribute indicating which input dates
were at fault.
**2019 December 13 Version 2.12**
* Replaced use of NumPy ``flip()`` with a reverse slice ``[::-1]`` after

View File

@ -1,20 +1,17 @@
"""A set of special exceptions that can be thrown by the jplephem library"""
class OutOfRangeTimestampError(ValueError):
"""
This exception is thrown if any input times are out of the range of
times jplephem can compute ephemeris for.
It has for properties:
class OutOfRangeError(ValueError):
"""One or more time values given were out of range for the ephemeris.
This exception is thrown if any input times are out of the range of
times supported by an ephemeris. It has two extra attributes:
- `message`: a string explaining what happened
- `out_of_range_times`: if the input `tdb` of times is an array,
this provides an array of booleans of the same length where `True`
means the corresponding date is out of range.
- `message` is a string explaining what happened,
- `min_timestamp` and `max_timestamp` are floats giving the minimum and
maximum supported times,
- `out_of_range_times` is an array of booleans where `True` means the
corresponding date in the input array is out of range and `False` means
it is correct.
"""
def __init__(self, message, min_timestamp, max_timestamp, out_of_range_times):
def __init__(self, message, out_of_range_times):
self.message = message
self.min_timestamp = min_timestamp
self.max_timestamp = max_timestamp
self.out_of_range_times = out_of_range_times

View File

@ -6,7 +6,7 @@ http://naif.jpl.nasa.gov/pub/naif/toolkit_docs/FORTRAN/req/spk.html
from numpy import array, empty, empty_like, interp, rollaxis
from .daf import DAF
from .descriptorlib import reify
from .exceptions import OutOfRangeTimestampError
from .exceptions import OutOfRangeError
from .names import target_names
T0 = 2451545.0
@ -228,13 +228,11 @@ class Segment(BaseSegment):
if (index < 0).any() or (index > n).any():
final_epoch = init + intlen * n
raise OutOfRangeTimestampError(
'segment only covers dates %.1f through %.1f' % (init,
final_epoch),
min_timestamp=init,
max_timestamp=final_epoch,
out_of_range_times=[True if i < 0 or i > n else False
for i in index])
raise OutOfRangeError(
'segment only covers dates %.1f through %.1f'
% (self.start_jd, self.end_jd),
out_of_range_times=(index < 0) | (index > n),
)
omegas = (index == n)
index[omegas] -= 1

View File

@ -15,6 +15,7 @@ from doctest import DocTestSuite, ELLIPSIS
from functools import partial
from io import BytesIO
from jplephem import Ephemeris, commandline
from jplephem.exceptions import OutOfRangeError
from jplephem.daf import DAF, FTPSTR, NAIF_DAF
from jplephem.spk import SPK
from struct import Struct
@ -329,6 +330,16 @@ class SPKTests(_CommonTests, TestCase):
initial_epoch, interval_length, coefficients = segment.load_array()
self.assertEqual(coefficients.shape, (3, 1760, 11))
def test_out_of_range_dates(self):
segment = self.spk[0,4]
tdb = np.array([-1e3, 0, +1e5]) + 2414990.0
try:
segment.compute_and_differentiate(tdb)
except OutOfRangeError as e:
self.assertEqual(str(e), 'segment only covers dates'
' 2414864.5 through 2471184.5')
self.assertIs(type(e.out_of_range_times), np.ndarray)
self.assertEqual(list(e.out_of_range_times), [True, False, True])
class LegacyTests(_CommonTests, TestCase):