planetarypy 0.76.2__tar.gz → 0.76.3__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {planetarypy-0.76.2 → planetarypy-0.76.3}/CHANGELOG.md +12 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/PKG-INFO +1 -1
- {planetarypy-0.76.2 → planetarypy-0.76.3}/pyproject.toml +3 -2
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/__init__.py +1 -1
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/instruments/mro/hirise.py +8 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/plotting.py +66 -47
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/search.py +5 -1
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/spice/archived_kernels.py +27 -9
- planetarypy-0.76.2/src/planetarypy/instruments/go/__init__.py +0 -0
- planetarypy-0.76.2/src/planetarypy/instruments/mro/__init__.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/.gitignore +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/AUTHORS.md +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/LICENSE +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/README.md +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/docs/README.md +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/catalog/__init__.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/catalog/_index_resolver.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/catalog/_mission_map.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/catalog/_objects.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/catalog/_parser.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/catalog/_pattern_resolver.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/catalog/_repo.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/catalog/_resolver.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/catalog/_schema.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/catalog/_url_rewrite.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/catalog/_validation.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/cli.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/config.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/constants/__init__.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/constants/_gm_jpl.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/constants/base.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/constants/iau2009.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/constants/iau2015.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/constants/nssdc/__init__.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/constants/nssdc/_loader.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/crs.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/data/__init__.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/datetime_format_converters.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/geo.py +0 -0
- {planetarypy-0.76.2/src/planetarypy/instruments → planetarypy-0.76.3/src/planetarypy/instruments/go}/__init__.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/instruments/go/ssi.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/instruments/mro/ctx/__init__.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/instruments/mro/ctx/ctx_calib.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/instruments/mro/ctx/ctx_edr.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/instruments/utils.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/io.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/isis/autoseed.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/pds/__init__.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/pds/dynamic_index.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/pds/dynamic_url_handlers.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/pds/index_fixes.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/pds/index_labels.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/pds/index_logging.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/pds/index_main.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/pds/meta_display.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/pds/static_index.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/pds/utils.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/psa.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/spice/__init__.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/spice/_deps.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/spice/config.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/spice/generic_kernels.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/spice/pckernels.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/spice/spicer.py +0 -0
- {planetarypy-0.76.2 → planetarypy-0.76.3}/src/planetarypy/utils.py +0 -0
|
@@ -5,6 +5,18 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.76.3] - 2026-06-17
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **PDS registry search: multi-filter queries no longer fail with HTTP 400.** `planetarypy.search` built its query string by joining clauses with ` and `, but the NASA PDS registry API requires the whole query wrapped in outer parentheses — so any search combining two or more filters (e.g. `target` + `observationals`, or a spatial bounding-box) returned `400 UnparsableQParamException` and only single-clause lookups worked. The query builder now wraps the joined clauses in `(...)`, matching what `pds.peppi` does. This also unblocks spatial searches via the `cart:Bounding_Coordinates.cart:*_bounding_coordinate` fields.
|
|
13
|
+
- **Archived SPICE metakernels with non-`'./data'` path conventions now load.** `archived_kernels.get_metakernel()` rewrote kernel paths by matching the literal `'./data'` in `PATH_VALUES`, which most NAIF archives use — but some (e.g. Hayabusa2's PDS4 archive) ship `'..'` instead. The rewrite silently no-opped on those, leaving an unresolvable relative path that broke `furnsh`. The rewrite is now convention-agnostic: it repoints whatever value the `PATH_VALUES` block holds to the absolute local kernel directory, leaving `KERNELS_TO_LOAD` symbol references intact.
|
|
14
|
+
- **`plotting.add_sun_indicator` no longer rescales the image.** The sun-direction glyph was drawn in data coordinates anchored in a corner; for any azimuth pointing past that corner, plotting the off-bounds marker triggered matplotlib autoscale, adding whitespace and pushing the indicator outside the frame. It is now drawn in axes-fraction coordinates with an inset anchor, so it stays inside the panel for any azimuth and never touches the data limits (this also removes a latent `origin='upper'`-only assumption).
|
|
15
|
+
|
|
16
|
+
### Changed
|
|
17
|
+
|
|
18
|
+
- **`plotting.add_sun_indicator` / `imshow_with_sun` are marked experimental.** They now carry an experimental note and emit a one-shot `UserWarning`. The azimuth-convention handoff is not yet validated end-to-end: these helpers expect azimuth clockwise-from-image-top (PDS `SUB_SOLAR_AZIMUTH`), whereas `Spicer.solar_azimuth_at` returns clockwise-from-north — they agree only when image-north points up.
|
|
19
|
+
|
|
8
20
|
## [0.76.2] - 2026-06-12
|
|
9
21
|
|
|
10
22
|
### Fixed
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: planetarypy
|
|
3
|
-
Version: 0.76.
|
|
3
|
+
Version: 0.76.3
|
|
4
4
|
Summary: Core package for planetary data tools. Includes PDS index utilities, SPICE integrations, and more.
|
|
5
5
|
Project-URL: Homepage, https://github.com/planetarypy/planetarypy
|
|
6
6
|
Project-URL: Repository, https://github.com/planetarypy/planetarypy
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "planetarypy"
|
|
7
|
-
version = "0.76.
|
|
7
|
+
version = "0.76.3"
|
|
8
8
|
description = "Core package for planetary data tools. Includes PDS index utilities, SPICE integrations, and more."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">= 3.11, <4"
|
|
@@ -185,6 +185,7 @@ DEP001 = [
|
|
|
185
185
|
# DEP002 = "declared dependency is not used in the codebase"
|
|
186
186
|
DEP002 = [
|
|
187
187
|
"lxml", # used at call time by pandas.read_html in spice/archived_kernels.py
|
|
188
|
+
"pyarrow", # parquet engine loaded internally by pandas to_parquet/read_parquet; never imported directly
|
|
188
189
|
"pytest", # CLI tool used in CI / dev; not imported from src
|
|
189
190
|
"pytest-cov",
|
|
190
191
|
"pytest-xdist",
|
|
@@ -201,7 +202,7 @@ DEP003 = [
|
|
|
201
202
|
]
|
|
202
203
|
|
|
203
204
|
[tool.bumpversion]
|
|
204
|
-
current_version = "0.76.
|
|
205
|
+
current_version = "0.76.3"
|
|
205
206
|
commit = true
|
|
206
207
|
tag = true
|
|
207
208
|
|
|
@@ -398,6 +398,14 @@ try:
|
|
|
398
398
|
except ImportError:
|
|
399
399
|
pass # catalog not available
|
|
400
400
|
|
|
401
|
+
# Register the HiRISE meta-display handler with the PDS meta dispatcher
|
|
402
|
+
try:
|
|
403
|
+
from planetarypy.pds.meta_display import register_meta_handler
|
|
404
|
+
register_meta_handler("mro.hirise.edr", format_meta)
|
|
405
|
+
register_meta_handler("mro.hirise.rdr", format_meta)
|
|
406
|
+
except ImportError:
|
|
407
|
+
pass # pds.meta_display not available
|
|
408
|
+
|
|
401
409
|
|
|
402
410
|
def _edr_base_url() -> URL:
|
|
403
411
|
"""Resolve EDR base URL from config."""
|
|
@@ -4,8 +4,14 @@ Provides common visualization helpers for planetary science:
|
|
|
4
4
|
percentile stretching, grayscale image display, sun direction indicators.
|
|
5
5
|
"""
|
|
6
6
|
|
|
7
|
+
import warnings
|
|
8
|
+
|
|
7
9
|
import numpy as np
|
|
8
10
|
|
|
11
|
+
# One-shot guard so a multi-panel figure doesn't emit the experimental
|
|
12
|
+
# warning once per subplot.
|
|
13
|
+
_SUN_INDICATOR_WARNED = False
|
|
14
|
+
|
|
9
15
|
|
|
10
16
|
def percentile_stretch(image, lo=1, hi=99):
|
|
11
17
|
"""Compute display limits from percentiles, ignoring zeros and NaN.
|
|
@@ -76,27 +82,34 @@ def imshow_gray(image, stretch="1,99", title=None, ax=None, **imshow_kwargs):
|
|
|
76
82
|
|
|
77
83
|
def add_sun_indicator(ax, sun_azimuth_deg, position="upper right",
|
|
78
84
|
length=0.12, color="yellow", inner_color="orange"):
|
|
79
|
-
"""Add a sun direction indicator to an image plot.
|
|
85
|
+
"""Add a sun direction indicator to an image plot. **Experimental.**
|
|
86
|
+
|
|
87
|
+
.. warning::
|
|
88
|
+
|
|
89
|
+
Experimental. The azimuth-convention handoff is not fully validated:
|
|
90
|
+
this function expects **clockwise-from-image-top** (the PDS
|
|
91
|
+
``SUB_SOLAR_AZIMUTH`` convention for *unprojected* images), but
|
|
92
|
+
:meth:`planetarypy.spice.spicer.Spicer.solar_azimuth_at` returns
|
|
93
|
+
**clockwise-from-north** (geographic). They agree only when image-north
|
|
94
|
+
points up; otherwise you must rotate by the image's north azimuth before
|
|
95
|
+
passing the value here. Placement and appearance may change.
|
|
80
96
|
|
|
81
|
-
The indicator
|
|
82
|
-
|
|
83
|
-
the
|
|
97
|
+
The indicator is a small compass glyph (sun ball + arrow) drawn in a corner,
|
|
98
|
+
pointing toward the sun. It is rendered in **axes-fraction coordinates**, so
|
|
99
|
+
it neither rescales the image nor depends on the image's ``origin``.
|
|
84
100
|
|
|
85
101
|
Parameters
|
|
86
102
|
----------
|
|
87
103
|
ax : matplotlib.axes.Axes
|
|
88
104
|
The axes containing the image.
|
|
89
105
|
sun_azimuth_deg : float
|
|
90
|
-
Solar azimuth in degrees, clockwise from image top.
|
|
91
|
-
This matches the PDS `SUB_SOLAR_AZIMUTH` convention for
|
|
92
|
-
unprojected images.
|
|
106
|
+
Solar azimuth in degrees, clockwise from image top (see warning).
|
|
93
107
|
position : str
|
|
94
|
-
|
|
95
|
-
"lower right", "lower left".
|
|
108
|
+
"upper right", "upper left", "lower right", "lower left".
|
|
96
109
|
length : float
|
|
97
|
-
|
|
110
|
+
Arrow length as a fraction of the axes (default 0.12).
|
|
98
111
|
color : str
|
|
99
|
-
Outer circle and
|
|
112
|
+
Outer circle and arrow color.
|
|
100
113
|
inner_color : str
|
|
101
114
|
Inner circle color (smaller, overlaid on outer).
|
|
102
115
|
|
|
@@ -104,56 +117,62 @@ def add_sun_indicator(ax, sun_azimuth_deg, position="upper right",
|
|
|
104
117
|
-------
|
|
105
118
|
ax : matplotlib.axes.Axes
|
|
106
119
|
"""
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
+
global _SUN_INDICATOR_WARNED
|
|
121
|
+
if not _SUN_INDICATOR_WARNED:
|
|
122
|
+
warnings.warn(
|
|
123
|
+
"add_sun_indicator is experimental: the azimuth convention "
|
|
124
|
+
"(clockwise-from-top vs Spicer's clockwise-from-north) is not fully "
|
|
125
|
+
"validated, and placement/appearance may change.",
|
|
126
|
+
UserWarning,
|
|
127
|
+
stacklevel=2,
|
|
128
|
+
)
|
|
129
|
+
_SUN_INDICATOR_WARNED = True
|
|
130
|
+
|
|
131
|
+
L = float(length)
|
|
132
|
+
# Inset the anchor by at least the arrow length so the glyph stays inside the
|
|
133
|
+
# axes for *any* azimuth. Axes-fraction coords (y up, independent of image
|
|
134
|
+
# origin); drawing here never touches the data limits, so the image is not
|
|
135
|
+
# rescaled — the bug the old data-coordinate corner placement had.
|
|
136
|
+
inset = L + 0.06
|
|
137
|
+
corners = {
|
|
138
|
+
"upper right": (1 - inset, 1 - inset),
|
|
139
|
+
"upper left": (inset, 1 - inset),
|
|
140
|
+
"lower right": (1 - inset, inset),
|
|
141
|
+
"lower left": (inset, inset),
|
|
120
142
|
}
|
|
121
|
-
cx, cy =
|
|
122
|
-
|
|
123
|
-
line_len = length * max(width, height)
|
|
124
|
-
az_rad = np.radians(sun_azimuth_deg)
|
|
125
|
-
# CW from top: dx = sin(az), dy = -cos(az) for origin='upper'
|
|
126
|
-
dx = line_len * np.sin(az_rad)
|
|
127
|
-
dy = -line_len * np.cos(az_rad)
|
|
143
|
+
cx, cy = corners.get(position, corners["upper right"])
|
|
128
144
|
|
|
129
|
-
|
|
145
|
+
az = np.radians(sun_azimuth_deg)
|
|
146
|
+
# Clockwise from top in axes-fraction space (y increases upward):
|
|
147
|
+
# 0deg -> up (+y), 90deg -> right (+x).
|
|
148
|
+
dx = L * np.sin(az)
|
|
149
|
+
dy = L * np.cos(az)
|
|
130
150
|
sx, sy = cx + dx, cy + dy
|
|
131
151
|
|
|
132
|
-
#
|
|
133
|
-
shrink = 0.
|
|
134
|
-
norm = np.hypot(dx, dy)
|
|
135
|
-
|
|
136
|
-
ax_dy = dy / norm * shrink
|
|
152
|
+
# Stop the arrow just short of the sun ball.
|
|
153
|
+
shrink = 0.12 * L
|
|
154
|
+
norm = np.hypot(dx, dy) or 1.0
|
|
155
|
+
tipx, tipy = sx - dx / norm * shrink, sy - dy / norm * shrink
|
|
137
156
|
|
|
138
157
|
ax.annotate("",
|
|
139
|
-
xy=(
|
|
140
|
-
|
|
158
|
+
xy=(tipx, tipy), xytext=(cx, cy),
|
|
159
|
+
xycoords="axes fraction", textcoords="axes fraction",
|
|
141
160
|
arrowprops=dict(arrowstyle="-|>", color=color, lw=2.5,
|
|
142
161
|
mutation_scale=20),
|
|
143
|
-
zorder=5)
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
ax.plot(sx, sy, "o", color=
|
|
147
|
-
|
|
148
|
-
|
|
162
|
+
zorder=5, annotation_clip=False)
|
|
163
|
+
ax.plot(sx, sy, "o", color=color, markersize=14, zorder=8,
|
|
164
|
+
transform=ax.transAxes, clip_on=False)
|
|
165
|
+
ax.plot(sx, sy, "o", color=inner_color, markersize=9, zorder=9,
|
|
166
|
+
transform=ax.transAxes, clip_on=False)
|
|
149
167
|
return ax
|
|
150
168
|
|
|
151
169
|
|
|
152
170
|
def imshow_with_sun(image, sun_azimuth_deg, title=None, ax=None,
|
|
153
171
|
stretch="1,99", sun_position="upper right", **imshow_kwargs):
|
|
154
|
-
"""Display a grayscale image with a sun direction indicator.
|
|
172
|
+
"""Display a grayscale image with a sun direction indicator. **Experimental.**
|
|
155
173
|
|
|
156
|
-
Combines `imshow_gray` with `add_sun_indicator
|
|
174
|
+
Combines `imshow_gray` with `add_sun_indicator` (see that function's
|
|
175
|
+
experimental warning about the azimuth convention).
|
|
157
176
|
|
|
158
177
|
Parameters
|
|
159
178
|
----------
|
|
@@ -119,7 +119,11 @@ def _build_q(
|
|
|
119
119
|
clauses.append(query)
|
|
120
120
|
if not clauses:
|
|
121
121
|
return None
|
|
122
|
-
|
|
122
|
+
# The PDS registry API requires the whole q wrapped in outer parentheses:
|
|
123
|
+
# a bare ``A and B`` returns HTTP 400 (UnparsableQParamException), while
|
|
124
|
+
# ``(A and B)`` parses. (peppi does the same in its ResultSet before sending.)
|
|
125
|
+
# Wrapping a single clause is harmless.
|
|
126
|
+
return "(" + " and ".join(clauses) + ")"
|
|
123
127
|
|
|
124
128
|
|
|
125
129
|
def _flatten(value: Any) -> Any:
|
|
@@ -20,6 +20,7 @@ __all__ = [
|
|
|
20
20
|
"list_cached_kernels",
|
|
21
21
|
]
|
|
22
22
|
|
|
23
|
+
import re
|
|
23
24
|
import zipfile
|
|
24
25
|
from datetime import timedelta
|
|
25
26
|
from io import BytesIO
|
|
@@ -516,18 +517,35 @@ class Subsetter:
|
|
|
516
517
|
else self.save_location
|
|
517
518
|
)
|
|
518
519
|
savepath = basepath / self.metakernel_file
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
self.z.open(self.metakernel_file) as infile,
|
|
522
|
-
):
|
|
523
|
-
for line in infile:
|
|
524
|
-
linestr = line.decode()
|
|
525
|
-
if "'./data'" in linestr:
|
|
526
|
-
linestr = linestr.replace("'./data'", f"'{savepath.parent}'")
|
|
527
|
-
outfile.write(linestr)
|
|
520
|
+
text = self.z.read(self.metakernel_file).decode()
|
|
521
|
+
savepath.write_text(_repoint_path_values(text, str(savepath.parent)))
|
|
528
522
|
return savepath
|
|
529
523
|
|
|
530
524
|
|
|
525
|
+
def _repoint_path_values(text: str, abspath: str) -> str:
|
|
526
|
+
"""Rewrite a metakernel's ``PATH_VALUES`` to the local kernel directory.
|
|
527
|
+
|
|
528
|
+
NAIF archive metakernels use different relative conventions for
|
|
529
|
+
``PATH_VALUES`` — most missions ship ``'./data'``, but some (e.g. Hayabusa2's
|
|
530
|
+
PDS4 archive) ship ``'..'``. Replace whatever single-quoted value the
|
|
531
|
+
``PATH_VALUES = ( … )`` block holds with ``abspath``, leaving every other line
|
|
532
|
+
(notably ``KERNELS_TO_LOAD``'s ``$SYMBOL/…`` references) untouched. The old
|
|
533
|
+
code matched the ``'./data'`` literal only, so it silently no-opped on ``'..'``
|
|
534
|
+
and left an unresolvable path that broke ``furnsh``.
|
|
535
|
+
"""
|
|
536
|
+
out = []
|
|
537
|
+
in_path_values = False
|
|
538
|
+
for line in text.splitlines(keepends=True):
|
|
539
|
+
if "PATH_VALUES" in line:
|
|
540
|
+
in_path_values = True
|
|
541
|
+
if in_path_values:
|
|
542
|
+
line = re.sub(r"'[^']*'", f"'{abspath}'", line)
|
|
543
|
+
if ")" in line:
|
|
544
|
+
in_path_values = False
|
|
545
|
+
out.append(line)
|
|
546
|
+
return "".join(out)
|
|
547
|
+
|
|
548
|
+
|
|
531
549
|
def get_metakernel_and_files(
|
|
532
550
|
mission: str, start: str, stop: str, save_location: str = None, quiet: bool = False
|
|
533
551
|
) -> str:
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|