diff --git a/.github/workflows/actions.yml b/.github/workflows/actions.yml index a414868..4fe9194 100644 --- a/.github/workflows/actions.yml +++ b/.github/workflows/actions.yml @@ -2,7 +2,7 @@ name: Continuous Integration env: PACKAGE: webgeocalc - PYTHON: 3.8 + PYTHON: 3.11 on: pull_request: diff --git a/.pylintrc b/.pylintrc index b8ab03a..d44e0a8 100644 --- a/.pylintrc +++ b/.pylintrc @@ -143,6 +143,7 @@ disable= C0103, # UPPER_CASE naming style (invalid-name) C0301, # Line too long (already handle by flake8) too-many-arguments, + too-many-positional-arguments, too-many-public-methods, too-many-lines, too-many-instance-attributes, @@ -344,8 +345,6 @@ max-module-lines=1000 # separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}. # `trailing-comma` allows a space between comma and closing bracket: (a, ). # `empty-line` allows space-only lines. -no-space-check=trailing-comma, - dict-separator # Allow the body of a class to be on the same line as the declaration if body # contains single statement. diff --git a/docs/api.rst b/docs/api.rst index 4cc7e92..e269146 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -38,7 +38,7 @@ and can be retrieved directly as items: 'WGC2 -- a WebGeocalc Server with enabled API at NAIF, JPL' >>> API['version'] -'2.2.9' +'2.7.6' Request kernel sets diff --git a/docs/calculation.rst b/docs/calculation.rst index 49279e0..056b6de 100644 --- a/docs/calculation.rst +++ b/docs/calculation.rst @@ -306,16 +306,16 @@ calculated in a desired reference frame: ... verbose = False, ... ).run() {'DATE': '2012-10-19 09:00:00.000000 UTC', - 'DISTANCE': 764142.63776247, - 'SPEED': 111.54765899, - 'X': 298292.85744169, - 'Y': -651606.58468976, - 'Z': 265224.81187627, - 'D_X_DT': -98.8032491, - 'D_Y_DT': -51.73211296, - 'D_Z_DT': -2.1416539, + 'DISTANCE': 764142.65053372, + 'SPEED': 111.54765158, + 'X': 298293.06093747, + 'Y': -651606.39373107, + 'Z': 265225.08895284, + 'D_X_DT': -98.80322113, + 'D_Y_DT': -51.73215012, + 'D_Z_DT': -2.14166057, 'TIME_AT_TARGET': '2012-10-19 08:59:57.451094 UTC', - 'LIGHT_TIME': 2.54890548} + 'LIGHT_TIME': 2.54890552} .. important:: @@ -388,7 +388,7 @@ Calculates the angular size of a target as seen by an observer. ... aberration_correction = 'CN+S', ... verbose = False, ... ).run() -{'DATE': '2012-10-19 08:24:00.000000 UTC', 'ANGULAR_SIZE': 0.03037939} +{'DATE': '2012-10-19 08:24:00.000000 UTC', 'ANGULAR_SIZE': 0.03032491} .. important:: @@ -425,13 +425,13 @@ another reference frame (Frame 2). ... verbose = False, ... ).run() {'DATE': '2012-10-19 08:24:00.000000 UTC', - 'ANGLE3': -20.58940104, - 'ANGLE2': 0.01874004, - 'ANGLE1': 0.00136319, - 'AV_X': 9.94596495e-07, - 'AV_Y': -7.23492228e-08, - 'AV_Z': -0.00634331, - 'AV_MAG': 0.00634331} + 'ANGLE3': -19.59511576, + 'ANGLE2': -0.00533619, + 'ANGLE1': -0.00345332, + 'AV_X': -2.8406831e-07, + 'AV_Y': 1.83751477e-07, + 'AV_Z': -0.00633942, + 'AV_MAG': 0.00633942} .. important:: @@ -479,13 +479,13 @@ target as seen from an observer. ... verbose = False, ... ).run() {'DATE': '2012-10-19 08:24:00.000000 UTC', - 'INCIDENCE_ANGLE': 24.78527742, - 'EMISSION_ANGLE': 25.56007298, - 'PHASE_ANGLE': 1.00079007, - 'OBSERVER_ALTITUDE': 967668.02765637, - 'TIME_AT_POINT': '2012-10-19 08:23:56.772207 UTC', - 'LIGHT_TIME': 3.2277931, - 'LTST': '13:15:59'} + 'INCIDENCE_ANGLE': 25.51886414, + 'EMISSION_ANGLE': 26.31058362, + 'PHASE_ANGLE': 1.00106425, + 'OBSERVER_ALTITUDE': 967670.28784259, + 'TIME_AT_POINT': '2012-10-19 08:23:56.772199 UTC', + 'LIGHT_TIME': 3.22780064, + 'LTST': '13:19:56'} .. important:: @@ -527,16 +527,16 @@ Calculates the sub-solar point on a target as seen from an observer. ... verbose = False, ... ).run() {'DATE': '2012-10-19 08:24:00.000000 UTC', - 'X': 234.00550655, - 'Y': -77.32612213, - 'Z': 67.42916937, - 'SUB_POINT_RADIUS': 255.50851089, - 'OBSERVER_ALTITUDE': 967644.15493281, - 'INCIDENCE_ANGLE': 4.49798357e-15, - 'EMISSION_ANGLE': 0.99611862, - 'PHASE_ANGLE': 0.99611862, - 'TIME_AT_POINT': '2012-10-19 08:23:56.772287 UTC', - 'LIGHT_TIME': 3.22771347} + 'X': 232.15437562, + 'Y': -81.18742303, + 'Z': 67.66010394, + 'SUB_POINT_RADIUS': 255.07830453, + 'OBSERVER_ALTITUDE': 967644.95641522, + 'INCIDENCE_ANGLE': 1.10177646e-14, + 'EMISSION_ANGLE': 0.99615507, + 'PHASE_ANGLE': 0.99615507, + 'TIME_AT_POINT': '2012-10-19 08:23:56.772284 UTC', + 'LIGHT_TIME': 3.22771614} .. important:: @@ -576,16 +576,16 @@ Calculate the sub-observer point on a target as seen from an observer. ... verbose = False, ... ).run() {'DATE': '2012-10-19 08:24:00.000000 UTC', - 'X': 232.5831733, - 'Y': -81.40386728, - 'Z': 67.35505213, - 'SUB_POINT_RADIUS': 255.45689491, - 'OBSERVER_ALTITUDE': 967644.11734179, - 'INCIDENCE_ANGLE': 0.99586304, - 'EMISSION_ANGLE': 1.66981544e-12, - 'PHASE_ANGLE': 0.99586304, - 'TIME_AT_POINT': '2012-10-19 08:23:56.772287 UTC', - 'LIGHT_TIME': 3.22771334, + 'X': 230.66149425, + 'Y': -85.24005493, + 'Z': 67.58656174, + 'SUB_POINT_RADIUS': 255.02653827, + 'OBSERVER_ALTITUDE': 967644.91882136, + 'INCIDENCE_ANGLE': 0.99589948, + 'EMISSION_ANGLE': 3.94425842e-12, + 'PHASE_ANGLE': 0.99589948, + 'TIME_AT_POINT': '2012-10-19 08:23:56.772284 UTC', + 'LIGHT_TIME': 3.22771602, 'LTST': '11:58:49'} .. important:: @@ -630,15 +630,15 @@ from an observer. ... verbose = False, ... ).run() {'DATE': '2012-10-14 00:00:00.000000 UTC', - 'LONGITUDE': 98.7675609, - 'LATITUDE': -38.69027976, - 'INTERCEPT_RADIUS': 57739.95803153, - 'OBSERVER_ALTITUDE': 1831047.67987589, - 'INCIDENCE_ANGLE': 123.05323675, - 'EMISSION_ANGLE': 5.8567773, - 'PHASE_ANGLE': 123.77530312, + 'LONGITUDE': 98.76797447, + 'LATITUDE': -38.69300277, + 'INTERCEPT_RADIUS': 57739.67660691, + 'OBSERVER_ALTITUDE': 1831047.98047459, + 'INCIDENCE_ANGLE': 123.05303919, + 'EMISSION_ANGLE': 5.8595724, + 'PHASE_ANGLE': 123.7753032, 'TIME_AT_POINT': '2012-10-14 00:00:00.000000 UTC', - 'LIGHT_TIME': 6.10771763, + 'LIGHT_TIME': 6.10771863, 'LTST': '20:03:06'} .. important:: @@ -679,17 +679,18 @@ central body. The orbit may be elliptical, parabolic, or hyperbolic. ... verbose = False, ... ).run() {'DATE': '2012-10-19 08:24:00.000000 UTC', - 'PERIFOCAL_DISTANCE': 474789.03917271, - 'ECCENTRICITY': 0.70348463, - 'INCLINATION': 38.18727034, - 'ASCENDING_NODE_LONGITUDE': 223.98123058, - 'ARGUMENT_OF_PERIAPSE': 71.59474487, - 'MEAN_ANOMALY_AT_EPOCH': 14.65461204, - 'ORBITING_BODY_RANGE': 753794.65101401, - 'ORBITING_BODY_SPEED': 8.77222231, - 'PERIOD': 2067101.2236748, + 'PERIFOCAL_DISTANCE': 474789.01814487, + 'ECCENTRICITY': 0.70348464, + 'INCLINATION': 38.18736036, + 'ASCENDING_NODE_LONGITUDE': 223.98121958, + 'ARGUMENT_OF_PERIAPSE': 71.59475294, + 'MEAN_ANOMALY_AT_EPOCH': 14.65461277, + 'ORBITING_BODY_RANGE': 753794.66333655, + 'ORBITING_BODY_SPEED': 8.77222221, + 'PERIOD': 2067101.1993984, 'CENTER_BODY_GM': 37931207.49865224} + .. important:: Calculation required parameters: @@ -771,7 +772,7 @@ Find time intervals when a coordinate of an observer-target position vector sati ... reference_value = 0.25, ... verbose = False, ... ).run() -{'DATE': '2012-10-19 08:39:33.812153 UTC', 'DURATION': 3394.10937738} +{'DATE': '2012-10-19 08:39:33.814938 UTC', 'DURATION': 3394.11539114} .. important:: diff --git a/docs/conf.py b/docs/conf.py index 37dd48c..f0305e9 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -25,7 +25,7 @@ source_suffix = '.rst' master_doc = 'index' -language = None +language = 'en' exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] # -- Options for HTML output ------------------------------------------------- diff --git a/examples/calculation.ipynb b/examples/calculation.ipynb index 7b8abed..e9635e2 100644 --- a/examples/calculation.ipynb +++ b/examples/calculation.ipynb @@ -113,7 +113,7 @@ "source": [ "Calculation(\n", " api = 'ESA',\n", - " kernels = 6,\n", + " kernels = 13,\n", " times = '2014-01-01T01:23:45.000',\n", " calculation_type = 'STATE_VECTOR',\n", " target = '67P/CHURYUMOV-GERASIMENKO (1969 R1)',\n", diff --git a/tests/test_api.py b/tests/test_api.py index d26d6e9..ff39997 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -18,8 +18,10 @@ def solar_system_kernel_set(): return { 'caption': 'Solar System Kernels', 'sclkId': '0', - 'description': 'Generic kernels for planets, satellites, and some asteroids ' - 'covering from 1950-01-01 to 2050-01-01.', + 'description': 'Generic kernels for planets, satellites, and some asteroids, ' + 'covering at least from 1950-01-01 to 2050-01-01, and including ' + 'the latest generic text PCK and the mars_iau2000_v1.tpc PCK ' + 'loaded in this order.', 'kernelSetId': '1', 'missionId': 'gen', } @@ -138,8 +140,8 @@ def test_api_metadata(): assert API['documentation'] == \ 'https://wgc2.jpl.nasa.gov:8443/webgeocalc/documents/api-info.html' assert API['contact'] == 'Boris Semenov ' - assert API['version'] == '2.2.9' - assert API['build_id'] == '5115 N67 14-JAN-2022' + assert API['version'] == '2.7.6' + assert API['build_id'] == '5363 N67 29-JAN-2025' with raises(KeyError): _ = API['foo'] diff --git a/tests/test_cli.py b/tests/test_cli.py index ccb43a7..d433fee 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -28,10 +28,10 @@ def test_cli_kernel_sets(capsys): assert ' - Solar System Kernels: (id: 1)' in captured.out assert 'Too many kernel sets contains \'Cassini\' in their names:' in captured.out - argv = '--api esa --kernel 6'.split() + argv = '--api esa --kernel 13'.split() cli_kernel_sets(argv) captured = capsys.readouterr() - assert ' - OPS -- Rosetta -- Operational: (id: 6)' in captured.out + assert ' - OPS -- Rosetta -- Operational: (id: 13)' in captured.out assert '' in captured.out @@ -53,7 +53,7 @@ def test_cli_bodies(capsys): captured = capsys.readouterr() assert captured.out == ' - TITAN: (id: 606)\n' - argv = '--api esa 6 --name 67P'.split() + argv = '--api esa 13 --name 67P'.split() cli_bodies(argv) captured = capsys.readouterr() assert captured.out == ' - 67P/CHURYUMOV-GERASIMENKO (1969 R1): (id: 1000012)\n' @@ -78,7 +78,7 @@ def test_cli_frames(capsys): assert ' - IAU_TITAN: (id: 10044)' in captured.out assert ' - J2000: (id: 1)' not in captured.out - argv = '--api esa 6 --name 67P'.split() + argv = '--api esa 13 --name 67P'.split() cli_frames(argv) captured = capsys.readouterr() assert '- 67P/C-G_CK: (id: -1000012000)' in captured.out @@ -104,7 +104,7 @@ def test_cli_instruments(capsys): assert ' - CASSINI_ISS_WAC: (id: -82361)' in captured.out assert ' - CASSINI_VIMS_IR: (id: -82370)' not in captured.out - argv = '--api esa 6 --name NAVCAM'.split() + argv = '--api esa 13 --name NAVCAM'.split() cli_instruments(argv) captured = capsys.readouterr() assert ' - ROS_NAVCAM-A: (id: -226170)' in captured.out @@ -191,7 +191,7 @@ def test_cli_angular_size_run(capsys): assert "timeSystem: UTC," in captured.out assert 'API status:\n[Calculation submit] Phase:' in captured.out assert 'Results:\nDATE:\n> 2012-10-19 08:24:00.000000 UTC' in captured.out - assert 'ANGULAR_SIZE:\n> 0.03037939' in captured.out + assert 'ANGULAR_SIZE:\n> 0.03032491' in captured.out def test_cli_frame_transformation_dry_run(capsys): @@ -386,7 +386,7 @@ def test_cli_state_vector_esa(capsys): captured = capsys.readouterr() assert 'API: http://spice.esac.esa.int/webgeocalc/api' in captured.out assert 'Payload:' in captured.out - assert "kernels: [{'type': 'KERNEL_SET', 'id': 6}]" in captured.out + assert "kernels: [{'type': 'KERNEL_SET', 'id': 13}]" in captured.out assert "times: ['2014-01-01T01:23:45.000']" in captured.out assert 'target: 67P/CHURYUMOV-GERASIMENKO (1969 R1)' in captured.out assert 'observer: ROSETTA ORBITER' in captured.out diff --git a/webgeocalc/api.py b/webgeocalc/api.py index 7b2fda4..ae3a285 100644 --- a/webgeocalc/api.py +++ b/webgeocalc/api.py @@ -62,7 +62,7 @@ def get(self, url): [ Solar System Kernels (id: 1), ...] """ - response = requests.get(self.url + url) + response = requests.get(self.url + url, timeout=60) if response.ok: return self.read(response.json()) @@ -95,7 +95,7 @@ def post(self, url, payload): ('0788aba2-d4e5-4028-9ef1-4867ad5385e0', 'COMPLETE') """ - response = requests.post(self.url + url, json=payload) + response = requests.post(self.url + url, json=payload, timeout=60) if response.ok: return self.read(response.json()) @@ -226,8 +226,8 @@ def kernel_set_id(self, kernel_set): if isinstance(kernel_set, KernelSetDetails): return int(kernel_set) - raise TypeError(f"'kernel_set' must be a 'int', a 'str' of a 'KernelSetDetails' object:\n' + \ - '>>> Type({kernel_set}) = {type(kernel_set)}") + raise TypeError(f"'kernel_set' must be a 'int', a 'str' of a 'KernelSetDetails' " + f"object:\n' + '>>> Type({kernel_set}) = {type(kernel_set)}") def bodies(self, kernel_set): """Get list of bodies available in a kernel set. diff --git a/webgeocalc/calculation.py b/webgeocalc/calculation.py index c9533cb..7a27075 100644 --- a/webgeocalc/calculation.py +++ b/webgeocalc/calculation.py @@ -1455,11 +1455,11 @@ def direction_vector_type(self, val): keys = self.params.keys() if val in ['VECTOR_IN_INSTRUMENT_FOV', 'VECTOR_IN_REFERENCE_FRAME']: - if not( + if not ( 'direction_vector_x' in keys and # noqa: W504 'direction_vector_y' in keys and # noqa: W504 'direction_vector_z' in keys - ) and not( + ) and not ( 'direction_vector_ra' in keys and # noqa: W504 'direction_vector_dec' in keys ):