setiastrosuitepro 1.6.7__py3-none-any.whl → 1.6.10__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.

Files changed (37) hide show
  1. setiastro/images/abeicon.svg +16 -0
  2. setiastro/images/cosmic.svg +40 -0
  3. setiastro/images/cosmicsat.svg +24 -0
  4. setiastro/images/graxpert.svg +19 -0
  5. setiastro/images/linearfit.svg +32 -0
  6. setiastro/images/pixelmath.svg +42 -0
  7. setiastro/saspro/_generated/build_info.py +2 -2
  8. setiastro/saspro/add_stars.py +29 -5
  9. setiastro/saspro/blink_comparator_pro.py +74 -24
  10. setiastro/saspro/cosmicclarity.py +125 -18
  11. setiastro/saspro/crop_dialog_pro.py +96 -2
  12. setiastro/saspro/curve_editor_pro.py +60 -39
  13. setiastro/saspro/frequency_separation.py +1159 -208
  14. setiastro/saspro/gui/main_window.py +131 -31
  15. setiastro/saspro/gui/mixins/theme_mixin.py +160 -14
  16. setiastro/saspro/gui/mixins/update_mixin.py +121 -33
  17. setiastro/saspro/imageops/stretch.py +531 -62
  18. setiastro/saspro/layers.py +13 -9
  19. setiastro/saspro/layers_dock.py +183 -3
  20. setiastro/saspro/legacy/numba_utils.py +43 -0
  21. setiastro/saspro/live_stacking.py +158 -70
  22. setiastro/saspro/multiscale_decomp.py +47 -12
  23. setiastro/saspro/numba_utils.py +72 -2
  24. setiastro/saspro/ops/commands.py +18 -18
  25. setiastro/saspro/shortcuts.py +122 -12
  26. setiastro/saspro/signature_insert.py +688 -33
  27. setiastro/saspro/stacking_suite.py +523 -316
  28. setiastro/saspro/stat_stretch.py +688 -130
  29. setiastro/saspro/subwindow.py +302 -71
  30. setiastro/saspro/widgets/common_utilities.py +28 -21
  31. setiastro/saspro/widgets/resource_monitor.py +7 -7
  32. {setiastrosuitepro-1.6.7.dist-info → setiastrosuitepro-1.6.10.dist-info}/METADATA +1 -1
  33. {setiastrosuitepro-1.6.7.dist-info → setiastrosuitepro-1.6.10.dist-info}/RECORD +37 -31
  34. {setiastrosuitepro-1.6.7.dist-info → setiastrosuitepro-1.6.10.dist-info}/WHEEL +0 -0
  35. {setiastrosuitepro-1.6.7.dist-info → setiastrosuitepro-1.6.10.dist-info}/entry_points.txt +0 -0
  36. {setiastrosuitepro-1.6.7.dist-info → setiastrosuitepro-1.6.10.dist-info}/licenses/LICENSE +0 -0
  37. {setiastrosuitepro-1.6.7.dist-info → setiastrosuitepro-1.6.10.dist-info}/licenses/license.txt +0 -0
@@ -202,7 +202,7 @@ register(CommandSpec(
202
202
  "optional targets, inherit_target."
203
203
  ),
204
204
  call_style="ctx.run_command",
205
- import_path="pro.function_bundle", # <── important
205
+ import_path="setiastro.saspro.function_bundle", # <── important
206
206
  callable_name="run_function_bundle_command",# <── important
207
207
  notes=(
208
208
  "Use this command from scripts to run a saved Function Bundle or an "
@@ -274,7 +274,7 @@ register(CommandSpec(
274
274
  group="Bundles",
275
275
  summary="Internal bundle runner. steps=[...], targets='all_open'|[doc_ptrs], stop_on_error.",
276
276
  call_style="ctx.run_command",
277
- import_path="pro.function_bundle",
277
+ import_path="setiastro.saspro.function_bundle",
278
278
  callable_name="run_function_bundle_command",
279
279
  ))
280
280
 
@@ -388,7 +388,7 @@ register(CommandSpec(
388
388
  id="ghs",
389
389
  name="Generalized Hyperbolic Stretch",
390
390
  group="Stretch",
391
- import_path="pro.ghs_preset",
391
+ import_path="setiastro.saspro.ghs_preset",
392
392
  callable_name="apply_ghs_via_preset",
393
393
  ui_method="open_ghs_with_preset",
394
394
  summary=(
@@ -499,7 +499,7 @@ register(CommandSpec(
499
499
  id="curves",
500
500
  title="Curves",
501
501
  group="Stretch",
502
- import_path="pro.curves_preset",
502
+ import_path="setiastro.saspro.curves_preset",
503
503
  callable_name="apply_curves_via_preset",
504
504
  ui_method="open_curves_with_preset",
505
505
  summary=(
@@ -597,7 +597,7 @@ register(CommandSpec(
597
597
  id="abe",
598
598
  title="Automatic Background Extraction",
599
599
  group="Background",
600
- import_path="pro.abe_preset",
600
+ import_path="setiastro.saspro.abe_preset",
601
601
  callable_name="apply_abe_via_preset",
602
602
  ui_method="open_abe_with_preset", # ✅ matches your pro/abe_preset.py
603
603
  summary=(
@@ -683,7 +683,7 @@ register(CommandSpec(
683
683
  id="graxpert",
684
684
  title="GraXpert Gradient / Denoise",
685
685
  group="Background",
686
- import_path="pro.graxpert_preset",
686
+ import_path="setiastro.saspro.graxpert_preset",
687
687
  callable_name="run_graxpert_via_preset",
688
688
  # no ui_method here unless you want to open your optional preset dialog from drops
689
689
  # ui_method="open_graxpert_with_preset", # (only if/when you add one)
@@ -807,7 +807,7 @@ register(CommandSpec(
807
807
  id="background_neutral",
808
808
  name="Background Neutralization",
809
809
  group="Background",
810
- import_path="pro.backgroundneutral",
810
+ import_path="setiastro.saspro.backgroundneutral",
811
811
  callable_name="run_background_neutral_via_preset",
812
812
  summary=(
813
813
  "Neutralizes RGB background either automatically or using a user-specified "
@@ -865,7 +865,7 @@ register(CommandSpec(
865
865
  id="remove_green",
866
866
  name="Remove Green (SCNR)",
867
867
  group="Color",
868
- import_path="pro.remove_green",
868
+ import_path="setiastro.saspro.remove_green",
869
869
  callable_name="apply_remove_green_preset_to_doc",
870
870
  ui_method="open_remove_green_dialog",
871
871
  summary=(
@@ -1044,7 +1044,7 @@ register(CommandSpec(
1044
1044
  id="recombine_luminance",
1045
1045
  name="Recombine Luminance",
1046
1046
  group="Luminance",
1047
- import_path="pro.luminancerecombine",
1047
+ import_path="setiastro.saspro.luminancerecombine",
1048
1048
  callable_name="run_recombine_luminance_via_preset",
1049
1049
  ui_method="_recombine_luminance_ui",
1050
1050
  notes=(
@@ -1144,7 +1144,7 @@ register(CommandSpec(
1144
1144
  id="wavescale_hdr",
1145
1145
  name="WaveScale HDR",
1146
1146
  group="Contrast",
1147
- import_path="pro.wavescale_hdr_preset",
1147
+ import_path="setiastro.saspro.wavescale_hdr_preset",
1148
1148
  callable_name="run_wavescale_hdr_via_preset",
1149
1149
  ui_method="_open_wavescale_hdr", # or whatever your main window uses
1150
1150
  summary=(
@@ -1188,7 +1188,7 @@ register(CommandSpec(
1188
1188
  id="wavescale_dark_enhance",
1189
1189
  name="WaveScale Dark Enhance",
1190
1190
  group="Contrast",
1191
- import_path="pro.wavescalede_preset",
1191
+ import_path="setiastro.saspro.wavescalede_preset",
1192
1192
  callable_name="run_wavescalede_via_preset",
1193
1193
  ui_method="_open_wavescale_dark_enhance", # adjust if your main window uses a different name
1194
1194
  summary=(
@@ -1295,7 +1295,7 @@ register(CommandSpec(
1295
1295
  id="aberration_ai",
1296
1296
  title="Aberration AI",
1297
1297
  group="Optics",
1298
- import_path="pro.aberration_ai_preset",
1298
+ import_path="setiastro.saspro.aberration_ai_preset",
1299
1299
  callable_name="run_aberration_ai_via_preset",
1300
1300
  # ui_method="open_aberration_ai_dialog", # if you have one; otherwise omit
1301
1301
  presets=[
@@ -1338,7 +1338,7 @@ register(CommandSpec(
1338
1338
  id="convo",
1339
1339
  title="Convolution / Deconvolution",
1340
1340
  group="Blur & Sharpen",
1341
- import_path="pro.convo_preset",
1341
+ import_path="setiastro.saspro.convo_preset",
1342
1342
  callable_name="run_convo_via_preset",
1343
1343
  aliases=[
1344
1344
  "convolution",
@@ -1433,7 +1433,7 @@ register(CommandSpec(
1433
1433
  id="cosmic_clarity",
1434
1434
  title="Cosmic Clarity",
1435
1435
  group="AI",
1436
- import_path="pro.cosmicclarity_preset",
1436
+ import_path="setiastro.saspro.cosmicclarity_preset",
1437
1437
  callable_name="run_cosmicclarity_via_preset",
1438
1438
  presets=[
1439
1439
  PresetSpec("mode", "enum", default="sharpen",
@@ -1484,7 +1484,7 @@ register(CommandSpec(
1484
1484
  id="debayer",
1485
1485
  title="Debayer",
1486
1486
  group="Color / CFA",
1487
- import_path="pro.debayer",
1487
+ import_path="setiastro.saspro.debayer",
1488
1488
  callable_name="run_debayer_via_preset",
1489
1489
  presets=[
1490
1490
  PresetSpec(
@@ -1506,7 +1506,7 @@ register(CommandSpec(
1506
1506
  id="linear_fit",
1507
1507
  title="Linear Fit",
1508
1508
  group="Calibration",
1509
- import_path="pro.linear_fit",
1509
+ import_path="setiastro.saspro.linear_fit",
1510
1510
  callable_name="run_linear_fit_via_preset",
1511
1511
  presets=[
1512
1512
  PresetSpec(
@@ -1527,7 +1527,7 @@ register(CommandSpec(
1527
1527
  id="morphology",
1528
1528
  title="Morphology",
1529
1529
  group="Masks & Morphology",
1530
- import_path="pro.morphology",
1530
+ import_path="setiastro.saspro.morphology",
1531
1531
  callable_name="apply_morphology_to_doc",
1532
1532
  presets=[
1533
1533
  PresetSpec(
@@ -1556,7 +1556,7 @@ register(CommandSpec(
1556
1556
  id="remove_stars",
1557
1557
  title="Remove Stars",
1558
1558
  group="Star Tools",
1559
- import_path="pro.remove_stars_preset",
1559
+ import_path="setiastro.saspro.remove_stars_preset",
1560
1560
  callable_name="run_remove_stars_via_preset",
1561
1561
  replay_apply_name="apply_remove_stars_to_doc",
1562
1562
  presets=[
@@ -1919,50 +1919,160 @@ class ShortcutManager:
1919
1919
  # legacy single-remove (kept for callers)
1920
1920
  self.delete_by_id(sid, persist=True)
1921
1921
 
1922
-
1923
1922
  class _StatStretchPresetDialog(QDialog):
1923
+ """
1924
+ Preset editor for headless replay: command_id="stat_stretch"
1925
+
1926
+ Keys supported:
1927
+ target_median: float
1928
+ linked: bool
1929
+ normalize: bool
1930
+ apply_curves: bool
1931
+ curves_boost: float # 0..1
1932
+ blackpoint_sigma: float # 0..1 (matches your slider/100)
1933
+ no_black_clip: bool
1934
+ hdr_compress: bool
1935
+ hdr_amount: float # 0..1
1936
+ hdr_knee: float # 0..1
1937
+ luma_only: bool
1938
+ luma_mode: str # e.g. "rec709"
1939
+ """
1924
1940
  def __init__(self, parent=None, initial: dict | None = None):
1925
1941
  super().__init__(parent)
1926
1942
  self.setWindowTitle("Statistical Stretch — Preset")
1927
1943
  init = dict(initial or {})
1928
1944
 
1945
+ # --- Target median ---
1929
1946
  self.spin_target = QDoubleSpinBox()
1930
- self.spin_target.setRange(0.0, 1.0); self.spin_target.setDecimals(3)
1947
+ self.spin_target.setRange(0.0, 1.0)
1948
+ self.spin_target.setDecimals(3)
1931
1949
  self.spin_target.setSingleStep(0.01)
1932
1950
  self.spin_target.setValue(float(init.get("target_median", 0.25)))
1933
1951
 
1952
+ # --- Linked / Normalize ---
1934
1953
  self.chk_linked = QCheckBox("Linked RGB channels")
1935
1954
  self.chk_linked.setChecked(bool(init.get("linked", False)))
1936
1955
 
1937
1956
  self.chk_normalize = QCheckBox("Normalize to [0..1]")
1938
1957
  self.chk_normalize.setChecked(bool(init.get("normalize", False)))
1939
1958
 
1959
+ # --- Curves ---
1960
+ self.chk_curves = QCheckBox("Apply Curves")
1961
+ self.chk_curves.setChecked(bool(init.get("apply_curves", False)))
1962
+
1940
1963
  self.spin_curves = QDoubleSpinBox()
1941
- self.spin_curves.setRange(0.0, 1.0); self.spin_curves.setDecimals(2)
1964
+ self.spin_curves.setRange(0.0, 1.0)
1965
+ self.spin_curves.setDecimals(2)
1942
1966
  self.spin_curves.setSingleStep(0.05)
1943
- self.spin_curves.setValue(float(init.get("curves_boost", 0.0 if not init.get("apply_curves") else 0.20)))
1967
+ self.spin_curves.setValue(float(init.get("curves_boost", 0.0)))
1968
+ self.spin_curves.setEnabled(self.chk_curves.isChecked())
1969
+ self.chk_curves.toggled.connect(self.spin_curves.setEnabled)
1970
+
1971
+ # --- Blackpoint sigma ---
1972
+ self.spin_bp = QDoubleSpinBox()
1973
+ self.spin_bp.setRange(0.0, 1.0)
1974
+ self.spin_bp.setDecimals(2)
1975
+ self.spin_bp.setSingleStep(0.05)
1976
+ self.spin_bp.setValue(float(init.get("blackpoint_sigma", 0.0)))
1977
+
1978
+ self.chk_no_black_clip = QCheckBox("No black clip")
1979
+ self.chk_no_black_clip.setChecked(bool(init.get("no_black_clip", False)))
1980
+
1981
+ # --- HDR compress ---
1982
+ self.chk_hdr = QCheckBox("HDR compression")
1983
+ self.chk_hdr.setChecked(bool(init.get("hdr_compress", False)))
1984
+
1985
+ self.spin_hdr_amt = QDoubleSpinBox()
1986
+ self.spin_hdr_amt.setRange(0.0, 1.0)
1987
+ self.spin_hdr_amt.setDecimals(2)
1988
+ self.spin_hdr_amt.setSingleStep(0.05)
1989
+ self.spin_hdr_amt.setValue(float(init.get("hdr_amount", 0.0)))
1990
+
1991
+ self.spin_hdr_knee = QDoubleSpinBox()
1992
+ self.spin_hdr_knee.setRange(0.0, 1.0)
1993
+ self.spin_hdr_knee.setDecimals(2)
1994
+ self.spin_hdr_knee.setSingleStep(0.05)
1995
+ self.spin_hdr_knee.setValue(float(init.get("hdr_knee", 0.5)))
1996
+
1997
+ def _set_hdr_enabled(on: bool):
1998
+ on = bool(on)
1999
+ self.spin_hdr_amt.setEnabled(on)
2000
+ self.spin_hdr_knee.setEnabled(on)
2001
+
2002
+ _set_hdr_enabled(self.chk_hdr.isChecked())
2003
+ self.chk_hdr.toggled.connect(_set_hdr_enabled)
2004
+
2005
+ # --- Luma only ---
2006
+ self.chk_luma_only = QCheckBox("Luma-only mode")
2007
+ self.chk_luma_only.setChecked(bool(init.get("luma_only", False)))
2008
+
2009
+ self.cmb_luma = QComboBox()
2010
+ # keep in sync with your tool’s supported modes
2011
+ self.cmb_luma.addItems(["rec709", "avg", "hsp", "max"])
2012
+ init_mode = str(init.get("luma_mode", "rec709") or "rec709")
2013
+ idx = self.cmb_luma.findText(init_mode)
2014
+ if idx >= 0:
2015
+ self.cmb_luma.setCurrentIndex(idx)
2016
+
2017
+ self.cmb_luma.setEnabled(self.chk_luma_only.isChecked())
2018
+ self.chk_luma_only.toggled.connect(self.cmb_luma.setEnabled)
2019
+
2020
+ # --- Layout ---
2021
+ form = QFormLayout()
1944
2022
 
1945
- form = QFormLayout(self)
1946
2023
  form.addRow("Target median:", self.spin_target)
1947
2024
  form.addRow("", self.chk_linked)
1948
2025
  form.addRow("", self.chk_normalize)
2026
+
2027
+ form.addRow("", QLabel("— Tone shaping —"))
2028
+ form.addRow("", self.chk_curves)
1949
2029
  form.addRow("Curves boost (0–1):", self.spin_curves)
1950
- form.addRow(QLabel("Curves are applied only if boost > 0."))
1951
2030
 
1952
- btns = QDialogButtonBox(QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel, parent=self)
1953
- btns.accepted.connect(self.accept); btns.rejected.connect(self.reject)
2031
+ form.addRow("", QLabel("— Blackpoint / HDR —"))
2032
+ form.addRow("Blackpoint σ (0–1):", self.spin_bp)
2033
+ form.addRow("", self.chk_no_black_clip)
2034
+
2035
+ form.addRow("", self.chk_hdr)
2036
+ form.addRow("HDR amount (0–1):", self.spin_hdr_amt)
2037
+ form.addRow("HDR knee (0–1):", self.spin_hdr_knee)
2038
+
2039
+ form.addRow("", QLabel("— Luma mode —"))
2040
+ form.addRow("", self.chk_luma_only)
2041
+ form.addRow("Luma mode:", self.cmb_luma)
2042
+
2043
+ btns = QDialogButtonBox(
2044
+ QDialogButtonBox.StandardButton.Ok | QDialogButtonBox.StandardButton.Cancel,
2045
+ parent=self
2046
+ )
2047
+ btns.accepted.connect(self.accept)
2048
+ btns.rejected.connect(self.reject)
1954
2049
  form.addRow(btns)
1955
2050
 
2051
+ self.setLayout(form)
2052
+
1956
2053
  def result_dict(self) -> dict:
1957
- boost = float(self.spin_curves.value())
2054
+ hdr_on = bool(self.chk_hdr.isChecked())
2055
+ curves_on = bool(self.chk_curves.isChecked())
2056
+ luma_on = bool(self.chk_luma_only.isChecked())
2057
+
1958
2058
  return {
1959
2059
  "target_median": float(self.spin_target.value()),
1960
2060
  "linked": bool(self.chk_linked.isChecked()),
1961
2061
  "normalize": bool(self.chk_normalize.isChecked()),
1962
- "apply_curves": bool(boost > 0.0),
1963
- "curves_boost": boost,
2062
+
2063
+ "apply_curves": curves_on,
2064
+ "curves_boost": float(self.spin_curves.value()) if curves_on else 0.0,
2065
+
2066
+ "blackpoint_sigma": float(self.spin_bp.value()),
2067
+ "no_black_clip": bool(self.chk_no_black_clip.isChecked()),
2068
+
2069
+ "hdr_compress": hdr_on,
2070
+ "hdr_amount": float(self.spin_hdr_amt.value()) if hdr_on else 0.0,
2071
+ "hdr_knee": float(self.spin_hdr_knee.value()) if hdr_on else 0.0,
2072
+
2073
+ "luma_only": luma_on,
2074
+ "luma_mode": str(self.cmb_luma.currentText()) if luma_on else "rec709",
1964
2075
  }
1965
-
1966
2076
 
1967
2077
  class _StarStretchPresetDialog(QDialog):
1968
2078
  def __init__(self, parent=None, initial: dict | None = None):