pyredshift 1.13__tar.gz → 1.15__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.
- {pyredshift-1.13 → pyredshift-1.15}/PKG-INFO +1 -1
- {pyredshift-1.13 → pyredshift-1.15}/setup.py +1 -1
- {pyredshift-1.13 → pyredshift-1.15}/src/pyredshift/pyredshift-help.html +11 -0
- {pyredshift-1.13 → pyredshift-1.15}/src/pyredshift/redshift.py +48 -6
- {pyredshift-1.13 → pyredshift-1.15}/src/pyredshift.egg-info/PKG-INFO +1 -1
- {pyredshift-1.13 → pyredshift-1.15}/LICENSE +0 -0
- {pyredshift-1.13 → pyredshift-1.15}/README.md +0 -0
- {pyredshift-1.13 → pyredshift-1.15}/pyproject.toml +0 -0
- {pyredshift-1.13 → pyredshift-1.15}/pyredshift +0 -0
- {pyredshift-1.13 → pyredshift-1.15}/setup.cfg +0 -0
- {pyredshift-1.13 → pyredshift-1.15}/src/pyredshift/__init__.py +0 -0
- {pyredshift-1.13 → pyredshift-1.15}/src/pyredshift/pyredshift.lines +0 -0
- {pyredshift-1.13 → pyredshift-1.15}/src/pyredshift.egg-info/SOURCES.txt +0 -0
- {pyredshift-1.13 → pyredshift-1.15}/src/pyredshift.egg-info/dependency_links.txt +0 -0
- {pyredshift-1.13 → pyredshift-1.15}/src/pyredshift.egg-info/requires.txt +0 -0
- {pyredshift-1.13 → pyredshift-1.15}/src/pyredshift.egg-info/top_level.txt +0 -0
|
@@ -13,7 +13,7 @@ from setuptools import setup
|
|
|
13
13
|
|
|
14
14
|
setup(
|
|
15
15
|
name="pyredshift",
|
|
16
|
-
version="1.
|
|
16
|
+
version="1.15",
|
|
17
17
|
description="Interactive redshifting of 1D astronomical spectra "
|
|
18
18
|
"(Python successor of pdlredshift / redshift.f)",
|
|
19
19
|
long_description=open("README.md").read(),
|
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
<h1>pyredshift help <span class="ver">v{version}</span></h1>
|
|
2
2
|
|
|
3
|
+
<p class="lineage">Karl's interactive redshift program. Thirty-four years
|
|
4
|
+
of redshifts by eye, now in its third language: <code>redshift.f</code>
|
|
5
|
+
(FIGARO/Fortran, Durham 1992) → <code>pdlredshift</code>
|
|
6
|
+
(Perl/PDL/PGPLOT 2018) → <code>pyredshift</code> (Python/matplotlib,
|
|
7
|
+
ported with Claude, 2026) — same keys, same beautiful crosshair,
|
|
8
|
+
faster carriage.</p>
|
|
9
|
+
|
|
10
|
+
<p class="lineage">Karl Glazebrook, Swinburne University of Technology.
|
|
11
|
+
MIT license.
|
|
12
|
+
<a href="https://github.com/karlglazebrook/pyredshift">github.com/karlglazebrook/pyredshift</a></p>
|
|
13
|
+
|
|
3
14
|
<input type="radio" name="tabs" id="tab-keys" checked>
|
|
4
15
|
<input type="radio" name="tabs" id="tab-lines">
|
|
5
16
|
<input type="radio" name="tabs" id="tab-guide">
|
|
@@ -56,6 +56,18 @@ V1.12 - The version number is shown by -h/-help and on the help page.
|
|
|
56
56
|
V1.13 - CSV reader: blank flux cells are bad pixels (NaN, plotted as
|
|
57
57
|
gaps) instead of desynchronising the wavelength and flux arrays;
|
|
58
58
|
rows with no wavelength are skipped.
|
|
59
|
+
V1.14 - Saving works properly: the toolbar save button no longer
|
|
60
|
+
truncates the output (the crosshair/readout blit machinery ran
|
|
61
|
+
during savefig and corrupted the file render), and the crosshair
|
|
62
|
+
and readout are no longer printed into saved PNGs/PDFs (savefig
|
|
63
|
+
draws animated artists - they now stay invisible outside blit
|
|
64
|
+
passes; the crosshair had been in 'p' output since V1.0).
|
|
65
|
+
- The backend chooser actually imports each backend before
|
|
66
|
+
choosing it, so a python without Qt falls back to MacOSX
|
|
67
|
+
instead of crashing at the first figure.
|
|
68
|
+
- Lineage/credits at the top of the help page.
|
|
69
|
+
V1.15 - Help-page credits link to the GitHub repo; lineage text in a
|
|
70
|
+
readable muted grey in both themes.
|
|
59
71
|
"""
|
|
60
72
|
|
|
61
73
|
import ctypes
|
|
@@ -69,10 +81,16 @@ from html.parser import HTMLParser
|
|
|
69
81
|
import numpy as np
|
|
70
82
|
import matplotlib
|
|
71
83
|
|
|
72
|
-
# Pick a GUI backend unless the user forced one via MPLBACKEND
|
|
84
|
+
# Pick a GUI backend unless the user forced one via MPLBACKEND.
|
|
85
|
+
# matplotlib.use() validates lazily (a missing Qt only explodes later at
|
|
86
|
+
# figure creation), so import the backend module to prove it really works.
|
|
73
87
|
if "MPLBACKEND" not in os.environ:
|
|
74
|
-
|
|
88
|
+
import importlib
|
|
89
|
+
for _backend, _mod in (("QtAgg", "backend_qtagg"),
|
|
90
|
+
("MacOSX", "backend_macosx"),
|
|
91
|
+
("TkAgg", "backend_tkagg")):
|
|
75
92
|
try:
|
|
93
|
+
importlib.import_module("matplotlib.backends." + _mod)
|
|
76
94
|
matplotlib.use(_backend)
|
|
77
95
|
break
|
|
78
96
|
except ImportError:
|
|
@@ -95,7 +113,7 @@ try:
|
|
|
95
113
|
except AttributeError:
|
|
96
114
|
pass
|
|
97
115
|
|
|
98
|
-
__version__ = "1.
|
|
116
|
+
__version__ = "1.15"
|
|
99
117
|
|
|
100
118
|
C_LIGHT = 2.99792458e8 # m/s
|
|
101
119
|
|
|
@@ -384,27 +402,38 @@ class StickyCursor(Cursor):
|
|
|
384
402
|
self.linev.set_data((xdata, xdata),
|
|
385
403
|
((figbb.y0 - axbb.y0) / axbb.height,
|
|
386
404
|
(figbb.y1 - axbb.y0) / axbb.height))
|
|
387
|
-
self.linev.set_visible(self.visible and self.vertOn)
|
|
388
405
|
self.lineh.set_data(((figbb.x0 - axbb.x0) / axbb.width,
|
|
389
406
|
(figbb.x1 - axbb.x0) / axbb.width),
|
|
390
407
|
(ydata, ydata))
|
|
391
|
-
self.lineh.set_visible(self.visible and self.horizOn)
|
|
392
408
|
if not (self.visible and (self.vertOn or self.horizOn)):
|
|
393
409
|
return
|
|
394
|
-
# Redraw
|
|
410
|
+
# Redraw. Animated artists still land in savefig output (bitten:
|
|
411
|
+
# crosshair printed into PDFs/PNGs), so they stay invisible except
|
|
412
|
+
# inside this blit pass - a save sees them switched off.
|
|
395
413
|
if self.useblit:
|
|
396
414
|
if self.background is not None:
|
|
397
415
|
self.canvas.restore_region(self.background)
|
|
416
|
+
self.linev.set_visible(self.vertOn)
|
|
417
|
+
self.lineh.set_visible(self.horizOn)
|
|
398
418
|
self.ax.draw_artist(self.linev)
|
|
399
419
|
self.ax.draw_artist(self.lineh)
|
|
420
|
+
self.linev.set_visible(False)
|
|
421
|
+
self.lineh.set_visible(False)
|
|
400
422
|
if readout_artist is not None:
|
|
401
423
|
set_readout_text(event) # restore wiped the corner -
|
|
424
|
+
readout_artist.set_visible(True)
|
|
402
425
|
fig.draw_artist(readout_artist) # redraw with fresh values
|
|
426
|
+
readout_artist.set_visible(False)
|
|
403
427
|
self.canvas.blit(figbb)
|
|
404
428
|
else:
|
|
429
|
+
self.linev.set_visible(self.visible and self.vertOn)
|
|
430
|
+
self.lineh.set_visible(self.visible and self.horizOn)
|
|
405
431
|
self.canvas.draw_idle()
|
|
406
432
|
|
|
407
433
|
def _redraw(self, event):
|
|
434
|
+
if self.canvas.is_saving():
|
|
435
|
+
return # savefig also fires draw_event: never blit the screen
|
|
436
|
+
# background into a file render (bitten: truncated PNGs)
|
|
408
437
|
if self.active and self._last_event is not None:
|
|
409
438
|
self.onmove(self._last_event)
|
|
410
439
|
elif readout_lastev is not None:
|
|
@@ -652,8 +681,11 @@ readout_lastev = None # last motion event, to survive full redraws
|
|
|
652
681
|
|
|
653
682
|
def make_readout():
|
|
654
683
|
global readout_artist, readout_bg, readout_lastev
|
|
684
|
+
# visible=False except inside blit passes: savefig draws animated
|
|
685
|
+
# artists (mpl 3.9), so this keeps the readout out of saved output
|
|
655
686
|
readout_artist = fig.text(0.995, 0.012, "", ha="right", va="bottom",
|
|
656
687
|
family="monospace", fontsize=8, animated=True,
|
|
688
|
+
visible=False,
|
|
657
689
|
color="white" if dark_mode else "black")
|
|
658
690
|
readout_bg = None
|
|
659
691
|
readout_lastev = None
|
|
@@ -668,6 +700,8 @@ def snapshot_readout(ev):
|
|
|
668
700
|
the cursor takes ITS (full-figure) snapshot; the cursor's _redraw
|
|
669
701
|
re-renders the readout after every repaint instead."""
|
|
670
702
|
global readout_bg
|
|
703
|
+
if fig.canvas.is_saving():
|
|
704
|
+
return # don't snapshot a file render as the screen background
|
|
671
705
|
W, H = fig.bbox.width, fig.bbox.height
|
|
672
706
|
box = Bbox([[0.40 * W, 0.0], [W, 0.055 * H]])
|
|
673
707
|
readout_bg = (fig.canvas.copy_from_bbox(box), box)
|
|
@@ -696,10 +730,14 @@ def set_readout_text(ev):
|
|
|
696
730
|
def update_readout(ev):
|
|
697
731
|
if readout_artist is None or readout_bg is None or f is None:
|
|
698
732
|
return
|
|
733
|
+
if fig.canvas.is_saving():
|
|
734
|
+
return # no blitting into a file render
|
|
699
735
|
set_readout_text(ev)
|
|
700
736
|
bg, box = readout_bg
|
|
701
737
|
fig.canvas.restore_region(bg)
|
|
738
|
+
readout_artist.set_visible(True)
|
|
702
739
|
fig.draw_artist(readout_artist)
|
|
740
|
+
readout_artist.set_visible(False)
|
|
703
741
|
fig.canvas.blit(box)
|
|
704
742
|
|
|
705
743
|
|
|
@@ -979,6 +1017,8 @@ body { font-family: -apple-system, "Helvetica Neue", sans-serif;
|
|
|
979
1017
|
color: %(fg)s; background: %(bg)s; line-height: 1.45; }
|
|
980
1018
|
h1 { font-size: 1.5em; border-bottom: 2px solid %(rule)s; padding-bottom: 0.2em; }
|
|
981
1019
|
h1 .ver { font-size: 0.6em; font-weight: normal; color: %(accent)s; }
|
|
1020
|
+
p.lineage { font-size: 0.85em; color: %(muted)s; margin-top: -0.3em; }
|
|
1021
|
+
a { color: %(accent)s; }
|
|
982
1022
|
h2 { font-size: 1.15em; color: %(accent)s; margin-top: 1.4em; }
|
|
983
1023
|
table { border-collapse: collapse; margin: 0.5em 0; }
|
|
984
1024
|
th, td { border: 1px solid %(rule)s; padding: 0.25em 0.7em; text-align: left; }
|
|
@@ -1014,8 +1054,10 @@ def show_help_browser(body):
|
|
|
1014
1054
|
return False
|
|
1015
1055
|
import webbrowser
|
|
1016
1056
|
colours = ({"fg": "#ddd", "bg": "#111", "rule": "#555",
|
|
1057
|
+
"muted": "#aaa",
|
|
1017
1058
|
"accent": "#f66", "thbg": "#222"} if dark_mode else
|
|
1018
1059
|
{"fg": "#111", "bg": "#fff", "rule": "#bbb",
|
|
1060
|
+
"muted": "#555",
|
|
1019
1061
|
"accent": "crimson", "thbg": "#f0f0f0"})
|
|
1020
1062
|
html = ("<!DOCTYPE html><html><head><meta charset='utf-8'>"
|
|
1021
1063
|
"<title>pyredshift help</title><style>%s</style></head>"
|
|
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
|