setiastrosuitepro 1.6.7__py3-none-any.whl → 1.7.0__py3-none-any.whl
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.
Potentially problematic release.
This version of setiastrosuitepro might be problematic. Click here for more details.
- setiastro/images/abeicon.svg +16 -0
- setiastro/images/colorwheel.svg +97 -0
- setiastro/images/cosmic.svg +40 -0
- setiastro/images/cosmicsat.svg +24 -0
- setiastro/images/graxpert.svg +19 -0
- setiastro/images/linearfit.svg +32 -0
- setiastro/images/narrowbandnormalization.png +0 -0
- setiastro/images/pixelmath.svg +42 -0
- setiastro/images/planetarystacker.png +0 -0
- setiastro/saspro/__main__.py +1 -1
- setiastro/saspro/_generated/build_info.py +2 -2
- setiastro/saspro/aberration_ai.py +49 -11
- setiastro/saspro/aberration_ai_preset.py +29 -3
- setiastro/saspro/add_stars.py +29 -5
- setiastro/saspro/backgroundneutral.py +73 -33
- setiastro/saspro/blink_comparator_pro.py +150 -55
- setiastro/saspro/convo.py +9 -6
- setiastro/saspro/cosmicclarity.py +125 -18
- setiastro/saspro/crop_dialog_pro.py +96 -2
- setiastro/saspro/curve_editor_pro.py +132 -61
- setiastro/saspro/curves_preset.py +249 -47
- setiastro/saspro/doc_manager.py +178 -11
- setiastro/saspro/frequency_separation.py +1159 -208
- setiastro/saspro/gui/main_window.py +340 -88
- setiastro/saspro/gui/mixins/dock_mixin.py +245 -24
- setiastro/saspro/gui/mixins/file_mixin.py +35 -16
- setiastro/saspro/gui/mixins/menu_mixin.py +31 -1
- setiastro/saspro/gui/mixins/theme_mixin.py +160 -14
- setiastro/saspro/gui/mixins/toolbar_mixin.py +132 -10
- setiastro/saspro/gui/mixins/update_mixin.py +121 -33
- setiastro/saspro/histogram.py +179 -7
- setiastro/saspro/imageops/narrowband_normalization.py +816 -0
- setiastro/saspro/imageops/serloader.py +769 -0
- setiastro/saspro/imageops/starbasedwhitebalance.py +23 -52
- setiastro/saspro/imageops/stretch.py +582 -62
- setiastro/saspro/layers.py +13 -9
- setiastro/saspro/layers_dock.py +183 -3
- setiastro/saspro/legacy/numba_utils.py +68 -48
- setiastro/saspro/live_stacking.py +181 -73
- setiastro/saspro/multiscale_decomp.py +77 -29
- setiastro/saspro/narrowband_normalization.py +1618 -0
- setiastro/saspro/numba_utils.py +72 -57
- setiastro/saspro/ops/commands.py +18 -18
- setiastro/saspro/ops/script_editor.py +5 -0
- setiastro/saspro/ops/scripts.py +119 -0
- setiastro/saspro/remove_green.py +1 -1
- setiastro/saspro/resources.py +4 -0
- setiastro/saspro/ser_stack_config.py +68 -0
- setiastro/saspro/ser_stacker.py +2245 -0
- setiastro/saspro/ser_stacker_dialog.py +1481 -0
- setiastro/saspro/ser_tracking.py +206 -0
- setiastro/saspro/serviewer.py +1242 -0
- setiastro/saspro/sfcc.py +602 -214
- setiastro/saspro/shortcuts.py +154 -25
- setiastro/saspro/signature_insert.py +688 -33
- setiastro/saspro/stacking_suite.py +853 -401
- setiastro/saspro/star_alignment.py +243 -122
- setiastro/saspro/stat_stretch.py +878 -131
- setiastro/saspro/subwindow.py +303 -74
- setiastro/saspro/whitebalance.py +24 -0
- setiastro/saspro/widgets/common_utilities.py +28 -21
- setiastro/saspro/widgets/resource_monitor.py +128 -80
- {setiastrosuitepro-1.6.7.dist-info → setiastrosuitepro-1.7.0.dist-info}/METADATA +2 -2
- {setiastrosuitepro-1.6.7.dist-info → setiastrosuitepro-1.7.0.dist-info}/RECORD +68 -51
- {setiastrosuitepro-1.6.7.dist-info → setiastrosuitepro-1.7.0.dist-info}/WHEEL +0 -0
- {setiastrosuitepro-1.6.7.dist-info → setiastrosuitepro-1.7.0.dist-info}/entry_points.txt +0 -0
- {setiastrosuitepro-1.6.7.dist-info → setiastrosuitepro-1.7.0.dist-info}/licenses/LICENSE +0 -0
- {setiastrosuitepro-1.6.7.dist-info → setiastrosuitepro-1.7.0.dist-info}/licenses/license.txt +0 -0
setiastro/saspro/shortcuts.py
CHANGED
|
@@ -503,7 +503,6 @@ class DraggableToolBar(QToolBar):
|
|
|
503
503
|
|
|
504
504
|
m.exec(gpos)
|
|
505
505
|
|
|
506
|
-
|
|
507
506
|
def contextMenuEvent(self, ev):
|
|
508
507
|
# Right-click on empty toolbar area
|
|
509
508
|
m = QMenu(self)
|
|
@@ -513,12 +512,12 @@ class DraggableToolBar(QToolBar):
|
|
|
513
512
|
act_lock = m.addAction(self.tr("Lock Toolbar Icons"))
|
|
514
513
|
act_lock.setCheckable(True)
|
|
515
514
|
act_lock.setChecked(is_locked)
|
|
516
|
-
|
|
515
|
+
|
|
517
516
|
def _toggle_lock(checked):
|
|
518
517
|
self._set_locked(checked)
|
|
519
|
-
|
|
518
|
+
|
|
520
519
|
act_lock.triggered.connect(_toggle_lock)
|
|
521
|
-
|
|
520
|
+
|
|
522
521
|
m.addSeparator()
|
|
523
522
|
|
|
524
523
|
# Submenu listing hidden actions for this toolbar
|
|
@@ -529,12 +528,13 @@ class DraggableToolBar(QToolBar):
|
|
|
529
528
|
any_hidden = False
|
|
530
529
|
if tb_hidden:
|
|
531
530
|
for act in tb_hidden.actions():
|
|
532
|
-
# Skip separators
|
|
533
531
|
if act.isSeparator():
|
|
534
532
|
continue
|
|
535
533
|
any_hidden = True
|
|
536
|
-
sub.addAction(
|
|
537
|
-
|
|
534
|
+
sub.addAction(
|
|
535
|
+
act.text() or (act.property("command_id") or act.objectName() or "item"),
|
|
536
|
+
lambda a=act: mw._unhide_action_from_hidden_toolbar(a)
|
|
537
|
+
)
|
|
538
538
|
|
|
539
539
|
if not any_hidden:
|
|
540
540
|
sub.setEnabled(False)
|
|
@@ -542,8 +542,15 @@ class DraggableToolBar(QToolBar):
|
|
|
542
542
|
m.addSeparator()
|
|
543
543
|
m.addAction(self.tr("Reset hidden icons"), self._reset_hidden_icons)
|
|
544
544
|
|
|
545
|
+
# ✅ NEW: Factory reset for all toolbars
|
|
546
|
+
m.addSeparator()
|
|
547
|
+
reset_all = m.addAction(self.tr("Reset ALL Toolbars (Factory Layout)"))
|
|
548
|
+
reset_all.setStatusTip(self.tr("Clears saved toolbar positions/orders/hidden state and restores defaults"))
|
|
549
|
+
reset_all.triggered.connect(lambda: getattr(self.window(), "_reset_all_toolbars_to_factory", lambda: None)())
|
|
550
|
+
|
|
545
551
|
m.exec(ev.globalPos())
|
|
546
552
|
|
|
553
|
+
|
|
547
554
|
def _reset_hidden_icons(self):
|
|
548
555
|
mw = self.window()
|
|
549
556
|
tb_hidden = getattr(mw, "_hidden_toolbar", lambda: None)()
|
|
@@ -1033,17 +1040,14 @@ class ShortcutCanvas(QWidget):
|
|
|
1033
1040
|
return False
|
|
1034
1041
|
sw = self._top_subwindow_at(e.position().toPoint())
|
|
1035
1042
|
if sw is None:
|
|
1036
|
-
|
|
1037
|
-
QApplication.processEvents()
|
|
1043
|
+
|
|
1038
1044
|
return False
|
|
1039
1045
|
try:
|
|
1040
1046
|
raw = bytes(md.data(MIME_CMD))
|
|
1041
1047
|
payload = _unpack_cmd_payload(raw) # your existing helper
|
|
1042
|
-
|
|
1043
|
-
QApplication.processEvents()
|
|
1048
|
+
|
|
1044
1049
|
except Exception as ex:
|
|
1045
|
-
|
|
1046
|
-
QApplication.processEvents()
|
|
1050
|
+
|
|
1047
1051
|
return False
|
|
1048
1052
|
self._mgr.apply_command_to_subwindow(sw, payload)
|
|
1049
1053
|
e.acceptProposedAction()
|
|
@@ -1545,6 +1549,7 @@ class ShortcutManager:
|
|
|
1545
1549
|
|
|
1546
1550
|
# ---- persistence (QSettings JSON blob) ----
|
|
1547
1551
|
def save_shortcuts(self):
|
|
1552
|
+
|
|
1548
1553
|
data = []
|
|
1549
1554
|
for sid, w in list(self.widgets.items()):
|
|
1550
1555
|
if _is_dead(w):
|
|
@@ -1845,6 +1850,7 @@ class ShortcutManager:
|
|
|
1845
1850
|
|
|
1846
1851
|
|
|
1847
1852
|
def clear(self):
|
|
1853
|
+
|
|
1848
1854
|
for sid, w in list(self.widgets.items()):
|
|
1849
1855
|
try:
|
|
1850
1856
|
if not _is_dead(w):
|
|
@@ -1919,50 +1925,173 @@ class ShortcutManager:
|
|
|
1919
1925
|
# legacy single-remove (kept for callers)
|
|
1920
1926
|
self.delete_by_id(sid, persist=True)
|
|
1921
1927
|
|
|
1922
|
-
|
|
1923
1928
|
class _StatStretchPresetDialog(QDialog):
|
|
1929
|
+
"""
|
|
1930
|
+
Preset editor for headless replay: command_id="stat_stretch"
|
|
1931
|
+
|
|
1932
|
+
Keys supported:
|
|
1933
|
+
target_median: float
|
|
1934
|
+
linked: bool
|
|
1935
|
+
normalize: bool
|
|
1936
|
+
apply_curves: bool
|
|
1937
|
+
curves_boost: float # 0..1
|
|
1938
|
+
blackpoint_sigma: float # 0..1 (matches your slider/100)
|
|
1939
|
+
no_black_clip: bool
|
|
1940
|
+
hdr_compress: bool
|
|
1941
|
+
hdr_amount: float # 0..1
|
|
1942
|
+
hdr_knee: float # 0..1
|
|
1943
|
+
luma_only: bool
|
|
1944
|
+
luma_mode: str # e.g. "rec709"
|
|
1945
|
+
luma_blend: float #0..1 (0=normal linked, 1=pure luma-only)
|
|
1946
|
+
"""
|
|
1924
1947
|
def __init__(self, parent=None, initial: dict | None = None):
|
|
1925
1948
|
super().__init__(parent)
|
|
1926
1949
|
self.setWindowTitle("Statistical Stretch — Preset")
|
|
1927
1950
|
init = dict(initial or {})
|
|
1928
1951
|
|
|
1952
|
+
# --- Target median ---
|
|
1929
1953
|
self.spin_target = QDoubleSpinBox()
|
|
1930
|
-
self.spin_target.setRange(0.0, 1.0)
|
|
1954
|
+
self.spin_target.setRange(0.0, 1.0)
|
|
1955
|
+
self.spin_target.setDecimals(3)
|
|
1931
1956
|
self.spin_target.setSingleStep(0.01)
|
|
1932
1957
|
self.spin_target.setValue(float(init.get("target_median", 0.25)))
|
|
1933
1958
|
|
|
1959
|
+
# --- Linked / Normalize ---
|
|
1934
1960
|
self.chk_linked = QCheckBox("Linked RGB channels")
|
|
1935
1961
|
self.chk_linked.setChecked(bool(init.get("linked", False)))
|
|
1936
1962
|
|
|
1937
1963
|
self.chk_normalize = QCheckBox("Normalize to [0..1]")
|
|
1938
1964
|
self.chk_normalize.setChecked(bool(init.get("normalize", False)))
|
|
1939
1965
|
|
|
1966
|
+
# --- Curves ---
|
|
1967
|
+
self.chk_curves = QCheckBox("Apply Curves")
|
|
1968
|
+
self.chk_curves.setChecked(bool(init.get("apply_curves", False)))
|
|
1969
|
+
|
|
1940
1970
|
self.spin_curves = QDoubleSpinBox()
|
|
1941
|
-
self.spin_curves.setRange(0.0, 1.0)
|
|
1971
|
+
self.spin_curves.setRange(0.0, 1.0)
|
|
1972
|
+
self.spin_curves.setDecimals(2)
|
|
1942
1973
|
self.spin_curves.setSingleStep(0.05)
|
|
1943
|
-
self.spin_curves.setValue(float(init.get("curves_boost", 0.0
|
|
1974
|
+
self.spin_curves.setValue(float(init.get("curves_boost", 0.0)))
|
|
1975
|
+
self.spin_curves.setEnabled(self.chk_curves.isChecked())
|
|
1976
|
+
self.chk_curves.toggled.connect(self.spin_curves.setEnabled)
|
|
1977
|
+
|
|
1978
|
+
# --- Blackpoint sigma ---
|
|
1979
|
+
self.spin_bp = QDoubleSpinBox()
|
|
1980
|
+
self.spin_bp.setRange(0.0, 1.0)
|
|
1981
|
+
self.spin_bp.setDecimals(2)
|
|
1982
|
+
self.spin_bp.setSingleStep(0.05)
|
|
1983
|
+
self.spin_bp.setValue(float(init.get("blackpoint_sigma", 0.0)))
|
|
1984
|
+
|
|
1985
|
+
self.chk_no_black_clip = QCheckBox("No black clip")
|
|
1986
|
+
self.chk_no_black_clip.setChecked(bool(init.get("no_black_clip", False)))
|
|
1987
|
+
|
|
1988
|
+
# --- HDR compress ---
|
|
1989
|
+
self.chk_hdr = QCheckBox("HDR compression")
|
|
1990
|
+
self.chk_hdr.setChecked(bool(init.get("hdr_compress", False)))
|
|
1991
|
+
|
|
1992
|
+
self.spin_hdr_amt = QDoubleSpinBox()
|
|
1993
|
+
self.spin_hdr_amt.setRange(0.0, 1.0)
|
|
1994
|
+
self.spin_hdr_amt.setDecimals(2)
|
|
1995
|
+
self.spin_hdr_amt.setSingleStep(0.05)
|
|
1996
|
+
self.spin_hdr_amt.setValue(float(init.get("hdr_amount", 0.0)))
|
|
1997
|
+
|
|
1998
|
+
self.spin_hdr_knee = QDoubleSpinBox()
|
|
1999
|
+
self.spin_hdr_knee.setRange(0.0, 1.0)
|
|
2000
|
+
self.spin_hdr_knee.setDecimals(2)
|
|
2001
|
+
self.spin_hdr_knee.setSingleStep(0.05)
|
|
2002
|
+
self.spin_hdr_knee.setValue(float(init.get("hdr_knee", 0.5)))
|
|
2003
|
+
|
|
2004
|
+
def _set_hdr_enabled(on: bool):
|
|
2005
|
+
on = bool(on)
|
|
2006
|
+
self.spin_hdr_amt.setEnabled(on)
|
|
2007
|
+
self.spin_hdr_knee.setEnabled(on)
|
|
2008
|
+
|
|
2009
|
+
_set_hdr_enabled(self.chk_hdr.isChecked())
|
|
2010
|
+
self.chk_hdr.toggled.connect(_set_hdr_enabled)
|
|
2011
|
+
|
|
2012
|
+
# --- Luma only ---
|
|
2013
|
+
self.chk_luma_only = QCheckBox("Luma-only mode")
|
|
2014
|
+
self.chk_luma_only.setChecked(bool(init.get("luma_only", False)))
|
|
2015
|
+
|
|
2016
|
+
self.cmb_luma = QComboBox()
|
|
2017
|
+
# keep in sync with your tool’s supported modes
|
|
2018
|
+
self.cmb_luma.addItems(["rec709", "avg", "hsp", "max"])
|
|
2019
|
+
init_mode = str(init.get("luma_mode", "rec709") or "rec709")
|
|
2020
|
+
idx = self.cmb_luma.findText(init_mode)
|
|
2021
|
+
if idx >= 0:
|
|
2022
|
+
self.cmb_luma.setCurrentIndex(idx)
|
|
2023
|
+
|
|
2024
|
+
self.spin_luma_blend = QDoubleSpinBox()
|
|
2025
|
+
self.spin_luma_blend.setRange(0.0, 1.0)
|
|
2026
|
+
self.spin_luma_blend.setDecimals(2)
|
|
2027
|
+
self.spin_luma_blend.setSingleStep(0.05)
|
|
2028
|
+
self.spin_luma_blend.setValue(float(init.get("luma_blend", 0.70)))
|
|
2029
|
+
|
|
2030
|
+
def _set_luma_enabled(on: bool):
|
|
2031
|
+
on = bool(on)
|
|
2032
|
+
self.cmb_luma.setEnabled(on)
|
|
2033
|
+
self.spin_luma_blend.setEnabled(on)
|
|
2034
|
+
|
|
2035
|
+
_set_luma_enabled(self.chk_luma_only.isChecked())
|
|
2036
|
+
self.chk_luma_only.toggled.connect(_set_luma_enabled)
|
|
2037
|
+
|
|
2038
|
+
# --- Layout ---
|
|
2039
|
+
form = QFormLayout()
|
|
1944
2040
|
|
|
1945
|
-
form = QFormLayout(self)
|
|
1946
2041
|
form.addRow("Target median:", self.spin_target)
|
|
1947
2042
|
form.addRow("", self.chk_linked)
|
|
1948
2043
|
form.addRow("", self.chk_normalize)
|
|
2044
|
+
|
|
2045
|
+
form.addRow("", QLabel("— Tone shaping —"))
|
|
2046
|
+
form.addRow("", self.chk_curves)
|
|
1949
2047
|
form.addRow("Curves boost (0–1):", self.spin_curves)
|
|
1950
|
-
form.addRow(QLabel("Curves are applied only if boost > 0."))
|
|
1951
2048
|
|
|
1952
|
-
|
|
1953
|
-
|
|
2049
|
+
form.addRow("", QLabel("— Blackpoint / HDR —"))
|
|
2050
|
+
form.addRow("Blackpoint σ (0–1):", self.spin_bp)
|
|
2051
|
+
form.addRow("", self.chk_no_black_clip)
|
|
2052
|
+
|
|
2053
|
+
form.addRow("", self.chk_hdr)
|
|
2054
|
+
form.addRow("HDR amount (0–1):", self.spin_hdr_amt)
|
|
2055
|
+
form.addRow("HDR knee (0–1):", self.spin_hdr_knee)
|
|
2056
|
+
|
|
2057
|
+
form.addRow("", QLabel("— Luma mode —"))
|
|
2058
|
+
form.addRow("", self.chk_luma_only)
|
|
2059
|
+
form.addRow("Luma mode:", self.cmb_luma)
|
|
2060
|
+
form.addRow("Luma blend (0–1):", self.spin_luma_blend)
|
|
2061
|
+
btns = QDialogButtonBox(
|
|
2062
|
+
QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel,
|
|
2063
|
+
parent=self
|
|
2064
|
+
)
|
|
2065
|
+
btns.accepted.connect(self.accept)
|
|
2066
|
+
btns.rejected.connect(self.reject)
|
|
1954
2067
|
form.addRow(btns)
|
|
1955
2068
|
|
|
2069
|
+
self.setLayout(form)
|
|
2070
|
+
|
|
1956
2071
|
def result_dict(self) -> dict:
|
|
1957
|
-
|
|
2072
|
+
hdr_on = bool(self.chk_hdr.isChecked())
|
|
2073
|
+
curves_on = bool(self.chk_curves.isChecked())
|
|
2074
|
+
luma_on = bool(self.chk_luma_only.isChecked())
|
|
2075
|
+
|
|
1958
2076
|
return {
|
|
1959
2077
|
"target_median": float(self.spin_target.value()),
|
|
1960
2078
|
"linked": bool(self.chk_linked.isChecked()),
|
|
1961
2079
|
"normalize": bool(self.chk_normalize.isChecked()),
|
|
1962
|
-
|
|
1963
|
-
"
|
|
2080
|
+
|
|
2081
|
+
"apply_curves": curves_on,
|
|
2082
|
+
"curves_boost": float(self.spin_curves.value()) if curves_on else 0.0,
|
|
2083
|
+
|
|
2084
|
+
"blackpoint_sigma": float(self.spin_bp.value()),
|
|
2085
|
+
"no_black_clip": bool(self.chk_no_black_clip.isChecked()),
|
|
2086
|
+
|
|
2087
|
+
"hdr_compress": hdr_on,
|
|
2088
|
+
"hdr_amount": float(self.spin_hdr_amt.value()) if hdr_on else 0.0,
|
|
2089
|
+
"hdr_knee": float(self.spin_hdr_knee.value()) if hdr_on else 0.0,
|
|
2090
|
+
|
|
2091
|
+
"luma_only": luma_on,
|
|
2092
|
+
"luma_mode": str(self.cmb_luma.currentText()) if luma_on else "rec709",
|
|
2093
|
+
"luma_blend": float(self.spin_luma_blend.value()) if luma_on else 0.0,
|
|
1964
2094
|
}
|
|
1965
|
-
|
|
1966
2095
|
|
|
1967
2096
|
class _StarStretchPresetDialog(QDialog):
|
|
1968
2097
|
def __init__(self, parent=None, initial: dict | None = None):
|