setiastrosuitepro 1.6.1__py3-none-any.whl → 1.6.2__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.
- setiastro/images/Background_startup.jpg +0 -0
- setiastro/qml/ResourceMonitor.qml +126 -0
- setiastro/saspro/__main__.py +159 -23
- setiastro/saspro/_generated/build_info.py +2 -1
- setiastro/saspro/abe.py +62 -11
- setiastro/saspro/aberration_ai.py +3 -3
- setiastro/saspro/add_stars.py +5 -2
- setiastro/saspro/astrobin_exporter.py +3 -0
- setiastro/saspro/astrospike_python.py +3 -1
- setiastro/saspro/autostretch.py +4 -2
- setiastro/saspro/backgroundneutral.py +52 -10
- setiastro/saspro/batch_convert.py +3 -0
- setiastro/saspro/batch_renamer.py +3 -0
- setiastro/saspro/blemish_blaster.py +3 -0
- setiastro/saspro/cheat_sheet.py +50 -15
- setiastro/saspro/clahe.py +27 -1
- setiastro/saspro/comet_stacking.py +103 -38
- setiastro/saspro/convo.py +3 -0
- setiastro/saspro/copyastro.py +3 -0
- setiastro/saspro/cosmicclarity.py +70 -45
- setiastro/saspro/crop_dialog_pro.py +17 -0
- setiastro/saspro/curve_editor_pro.py +18 -0
- setiastro/saspro/debayer.py +3 -0
- setiastro/saspro/doc_manager.py +39 -16
- setiastro/saspro/fitsmodifier.py +3 -0
- setiastro/saspro/frequency_separation.py +8 -2
- setiastro/saspro/function_bundle.py +2 -0
- setiastro/saspro/generate_translations.py +715 -1
- setiastro/saspro/ghs_dialog_pro.py +3 -0
- setiastro/saspro/graxpert.py +3 -0
- setiastro/saspro/gui/main_window.py +275 -32
- setiastro/saspro/gui/mixins/dock_mixin.py +100 -1
- setiastro/saspro/gui/mixins/file_mixin.py +7 -0
- setiastro/saspro/gui/mixins/menu_mixin.py +28 -0
- setiastro/saspro/gui/statistics_dialog.py +47 -0
- setiastro/saspro/halobgon.py +29 -3
- setiastro/saspro/histogram.py +3 -0
- setiastro/saspro/history_explorer.py +2 -0
- setiastro/saspro/i18n.py +22 -10
- setiastro/saspro/image_combine.py +3 -0
- setiastro/saspro/image_peeker_pro.py +3 -0
- setiastro/saspro/imageops/stretch.py +5 -13
- setiastro/saspro/isophote.py +3 -0
- setiastro/saspro/legacy/numba_utils.py +64 -47
- setiastro/saspro/linear_fit.py +3 -0
- setiastro/saspro/live_stacking.py +13 -2
- setiastro/saspro/mask_creation.py +3 -0
- setiastro/saspro/mfdeconv.py +5 -0
- setiastro/saspro/morphology.py +30 -5
- setiastro/saspro/multiscale_decomp.py +3 -0
- setiastro/saspro/nbtorgb_stars.py +12 -2
- setiastro/saspro/numba_utils.py +148 -47
- setiastro/saspro/ops/scripts.py +77 -17
- setiastro/saspro/ops/settings.py +1 -43
- setiastro/saspro/perfect_palette_picker.py +1 -0
- setiastro/saspro/pixelmath.py +6 -2
- setiastro/saspro/plate_solver.py +2 -1
- setiastro/saspro/remove_green.py +18 -1
- setiastro/saspro/remove_stars.py +136 -162
- setiastro/saspro/resources.py +7 -0
- setiastro/saspro/rgb_combination.py +1 -0
- setiastro/saspro/rgbalign.py +4 -4
- setiastro/saspro/save_options.py +1 -0
- setiastro/saspro/sfcc.py +50 -8
- setiastro/saspro/signature_insert.py +3 -0
- setiastro/saspro/stacking_suite.py +630 -341
- setiastro/saspro/star_alignment.py +16 -1
- setiastro/saspro/star_spikes.py +116 -32
- setiastro/saspro/star_stretch.py +38 -1
- setiastro/saspro/stat_stretch.py +35 -3
- setiastro/saspro/subwindow.py +63 -2
- setiastro/saspro/supernovaasteroidhunter.py +3 -0
- setiastro/saspro/translations/all_source_strings.json +3654 -0
- setiastro/saspro/translations/ar_translations.py +3865 -0
- setiastro/saspro/translations/de_translations.py +16 -0
- setiastro/saspro/translations/es_translations.py +16 -0
- setiastro/saspro/translations/fr_translations.py +16 -0
- setiastro/saspro/translations/hi_translations.py +3571 -0
- setiastro/saspro/translations/integrate_translations.py +36 -0
- setiastro/saspro/translations/it_translations.py +16 -0
- setiastro/saspro/translations/ja_translations.py +16 -0
- setiastro/saspro/translations/pt_translations.py +16 -0
- setiastro/saspro/translations/ru_translations.py +2848 -0
- setiastro/saspro/translations/saspro_ar.qm +0 -0
- setiastro/saspro/translations/saspro_ar.ts +255 -0
- setiastro/saspro/translations/saspro_de.qm +0 -0
- setiastro/saspro/translations/saspro_de.ts +3 -3
- setiastro/saspro/translations/saspro_es.qm +0 -0
- setiastro/saspro/translations/saspro_es.ts +3 -3
- setiastro/saspro/translations/saspro_fr.qm +0 -0
- setiastro/saspro/translations/saspro_fr.ts +3 -3
- setiastro/saspro/translations/saspro_hi.qm +0 -0
- setiastro/saspro/translations/saspro_hi.ts +257 -0
- setiastro/saspro/translations/saspro_it.qm +0 -0
- setiastro/saspro/translations/saspro_it.ts +3 -3
- setiastro/saspro/translations/saspro_ja.qm +0 -0
- setiastro/saspro/translations/saspro_ja.ts +4 -4
- setiastro/saspro/translations/saspro_pt.qm +0 -0
- setiastro/saspro/translations/saspro_pt.ts +3 -3
- setiastro/saspro/translations/saspro_ru.qm +0 -0
- setiastro/saspro/translations/saspro_ru.ts +237 -0
- setiastro/saspro/translations/saspro_sw.qm +0 -0
- setiastro/saspro/translations/saspro_sw.ts +257 -0
- setiastro/saspro/translations/saspro_uk.qm +0 -0
- setiastro/saspro/translations/saspro_uk.ts +10771 -0
- setiastro/saspro/translations/saspro_zh.qm +0 -0
- setiastro/saspro/translations/saspro_zh.ts +3 -3
- setiastro/saspro/translations/sw_translations.py +3671 -0
- setiastro/saspro/translations/uk_translations.py +3700 -0
- setiastro/saspro/translations/zh_translations.py +16 -0
- setiastro/saspro/versioning.py +12 -6
- setiastro/saspro/view_bundle.py +3 -0
- setiastro/saspro/wavescale_hdr.py +22 -1
- setiastro/saspro/wavescalede.py +23 -1
- setiastro/saspro/whitebalance.py +39 -3
- setiastro/saspro/widgets/minigame/game.js +986 -0
- setiastro/saspro/widgets/minigame/index.html +53 -0
- setiastro/saspro/widgets/minigame/style.css +241 -0
- setiastro/saspro/widgets/resource_monitor.py +237 -0
- setiastro/saspro/widgets/wavelet_utils.py +52 -20
- setiastro/saspro/wimi.py +7996 -0
- setiastro/saspro/wims.py +578 -0
- {setiastrosuitepro-1.6.1.dist-info → setiastrosuitepro-1.6.2.dist-info}/METADATA +15 -4
- {setiastrosuitepro-1.6.1.dist-info → setiastrosuitepro-1.6.2.dist-info}/RECORD +128 -103
- {setiastrosuitepro-1.6.1.dist-info → setiastrosuitepro-1.6.2.dist-info}/WHEEL +0 -0
- {setiastrosuitepro-1.6.1.dist-info → setiastrosuitepro-1.6.2.dist-info}/entry_points.txt +0 -0
- {setiastrosuitepro-1.6.1.dist-info → setiastrosuitepro-1.6.2.dist-info}/licenses/LICENSE +0 -0
- {setiastrosuitepro-1.6.1.dist-info → setiastrosuitepro-1.6.2.dist-info}/licenses/license.txt +0 -0
|
@@ -59,7 +59,9 @@ TRANSLATIONS_ZH = {
|
|
|
59
59
|
"Post-alignment failed: {0}": "后对齐失败:{0}",
|
|
60
60
|
},
|
|
61
61
|
"AstroSuiteProMainWindow": {
|
|
62
|
+
"Start a new project? This closes all views and clears desktop shortcuts.": "开始新项目?这将关闭所有视图并清除桌面快捷方式。",
|
|
62
63
|
"&About": "关于(&A)",
|
|
64
|
+
"Statistics...": "统计...",
|
|
63
65
|
"&Edit": "编辑(&E)",
|
|
64
66
|
"&File": "文件(&F)",
|
|
65
67
|
"&Functions": "功能(&U)",
|
|
@@ -1135,6 +1137,7 @@ TRANSLATIONS_ZH = {
|
|
|
1135
1137
|
"Value": "值",
|
|
1136
1138
|
},
|
|
1137
1139
|
"FileMixin": {
|
|
1140
|
+
"Start a new project? This closes all views and clears desktop shortcuts.": "开始新项目?这将关闭所有视图并清除桌面快捷方式。",
|
|
1138
1141
|
"Failed to save:\n{e}": "保存失败:\n{e}",
|
|
1139
1142
|
"Failed to save:\n{msg}": "保存失败:\n{msg}",
|
|
1140
1143
|
"File not found": "未找到文件",
|
|
@@ -1698,6 +1701,8 @@ TRANSLATIONS_ZH = {
|
|
|
1698
1701
|
"Selective Color Correction": "选择性颜色校正",
|
|
1699
1702
|
},
|
|
1700
1703
|
"SettingsDialog": {
|
|
1704
|
+
"Restart required": "需要重启",
|
|
1705
|
+
"Language changed. Please manually restart the application to apply the new language.": "语言已更改。请手动重启应用以应用新语言。",
|
|
1701
1706
|
"ASTAP executable:": "ASTAP 可执行文件:",
|
|
1702
1707
|
"Astrometry.net API key:": "Astrometry.net API 密钥:",
|
|
1703
1708
|
"Check Now…": "立即检查…",
|
|
@@ -3656,4 +3661,15 @@ TRANSLATIONS_ZH = {
|
|
|
3656
3661
|
"Success": "成功",
|
|
3657
3662
|
"View in Aladin": "在 Aladin 中查看",
|
|
3658
3663
|
},
|
|
3664
|
+
|
|
3665
|
+
"StatisticsDialog": {
|
|
3666
|
+
"App Statistics": "应用统计",
|
|
3667
|
+
"Time Spent:": "花费时间:",
|
|
3668
|
+
"Images Opened:": "打开的图像:",
|
|
3669
|
+
"Tools Opened:": "打开的工具:",
|
|
3670
|
+
"Days": "天",
|
|
3671
|
+
"Hours": "小时",
|
|
3672
|
+
"Minutes": "分钟",
|
|
3673
|
+
"Close": "关闭",
|
|
3674
|
+
},
|
|
3659
3675
|
}
|
setiastro/saspro/versioning.py
CHANGED
|
@@ -46,26 +46,32 @@ def get_app_version(dist_name: str = "setiastrosuitepro") -> str:
|
|
|
46
46
|
Single source of truth for SASpro version.
|
|
47
47
|
|
|
48
48
|
Order:
|
|
49
|
-
|
|
49
|
+
0) build_info.py (best for PyInstaller frozen builds)
|
|
50
|
+
1) installed distribution metadata (best for pip installs)
|
|
50
51
|
2) pyproject.toml (best for running from source checkout)
|
|
51
52
|
3) safe fallback
|
|
52
53
|
"""
|
|
53
|
-
#
|
|
54
|
+
# 0) build_info (PyInstaller-friendly)
|
|
55
|
+
try:
|
|
56
|
+
from ._generated.build_info import APP_VERSION
|
|
57
|
+
if isinstance(APP_VERSION, str) and APP_VERSION.strip() and APP_VERSION.strip() != "0.0.0":
|
|
58
|
+
return APP_VERSION.strip()
|
|
59
|
+
except Exception:
|
|
60
|
+
pass
|
|
61
|
+
|
|
62
|
+
# 1) Installed package metadata
|
|
54
63
|
try:
|
|
55
64
|
from importlib.metadata import version as _dist_version
|
|
56
65
|
v = _dist_version(dist_name)
|
|
57
|
-
# If you want to *avoid* accidentally picking up a stale installed 0.1.0,
|
|
58
|
-
# you can reject that known-bad default:
|
|
59
66
|
if v and v != "0.1.0":
|
|
60
67
|
return v
|
|
61
68
|
except Exception:
|
|
62
69
|
pass
|
|
63
70
|
|
|
64
|
-
# 2) Source tree pyproject.toml
|
|
71
|
+
# 2) Source tree pyproject.toml
|
|
65
72
|
here = Path(__file__).resolve()
|
|
66
73
|
v2 = _read_pyproject_version(here.parent)
|
|
67
74
|
if v2:
|
|
68
75
|
return v2
|
|
69
76
|
|
|
70
|
-
# 3) Frozen / unknown: fallback
|
|
71
77
|
return "0.0.0"
|
setiastro/saspro/view_bundle.py
CHANGED
|
@@ -378,6 +378,7 @@ class SelectViewsDialog(QDialog):
|
|
|
378
378
|
super().__init__(parent)
|
|
379
379
|
self.setWindowTitle("Add Views to Bundle")
|
|
380
380
|
self.setWindowFlag(Qt.WindowType.Window, True)
|
|
381
|
+
self.setWindowModality(Qt.WindowModality.NonModal)
|
|
381
382
|
self.setModal(False)
|
|
382
383
|
#self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose, True)
|
|
383
384
|
self._boxes: list[QCheckBox] = []
|
|
@@ -510,6 +511,8 @@ class ViewBundleDialog(QDialog):
|
|
|
510
511
|
super().__init__(parent)
|
|
511
512
|
_pin_on_top_mac(self)
|
|
512
513
|
self.setWindowTitle("View Bundles")
|
|
514
|
+
self.setWindowFlag(Qt.WindowType.Window, True)
|
|
515
|
+
self.setWindowModality(Qt.WindowModality.NonModal)
|
|
513
516
|
self.setModal(False)
|
|
514
517
|
self.resize(900, 540)
|
|
515
518
|
self.setAcceptDrops(True)
|
|
@@ -199,6 +199,9 @@ class WaveScaleHDRDialogPro(QDialog):
|
|
|
199
199
|
import logging
|
|
200
200
|
logging.debug(f"Exception suppressed: {type(e).__name__}: {e}")
|
|
201
201
|
self.resize(980, 700)
|
|
202
|
+
self.setWindowFlag(Qt.WindowType.Window, True)
|
|
203
|
+
self.setWindowModality(Qt.WindowModality.NonModal)
|
|
204
|
+
self.setModal(False)
|
|
202
205
|
|
|
203
206
|
self._doc = doc
|
|
204
207
|
base = getattr(doc, "image", None)
|
|
@@ -606,8 +609,26 @@ class WaveScaleHDRDialogPro(QDialog):
|
|
|
606
609
|
except Exception:
|
|
607
610
|
pass
|
|
608
611
|
|
|
609
|
-
|
|
612
|
+
# Dialog stays open so user can apply to other images
|
|
613
|
+
# Refresh document reference for next operation
|
|
614
|
+
self._refresh_document_from_active()
|
|
610
615
|
|
|
616
|
+
def _refresh_document_from_active(self):
|
|
617
|
+
"""
|
|
618
|
+
Refresh the dialog's document reference to the currently active document.
|
|
619
|
+
This allows reusing the same dialog on different images.
|
|
620
|
+
"""
|
|
621
|
+
try:
|
|
622
|
+
main = self.parent()
|
|
623
|
+
if main and hasattr(main, "_active_doc"):
|
|
624
|
+
new_doc = main._active_doc()
|
|
625
|
+
if new_doc is not None and new_doc is not self._doc:
|
|
626
|
+
self._doc = new_doc
|
|
627
|
+
# Reset L channel and refresh preview for new document
|
|
628
|
+
self._L_original = None
|
|
629
|
+
self._last_preview = None
|
|
630
|
+
except Exception:
|
|
631
|
+
pass
|
|
611
632
|
|
|
612
633
|
|
|
613
634
|
def _schedule_mask_refresh(self, _value):
|
setiastro/saspro/wavescalede.py
CHANGED
|
@@ -201,6 +201,9 @@ class WaveScaleDarkEnhancerDialogPro(QDialog):
|
|
|
201
201
|
import logging
|
|
202
202
|
logging.debug(f"Exception suppressed: {type(e).__name__}: {e}")
|
|
203
203
|
self.resize(980, 700)
|
|
204
|
+
self.setWindowFlag(Qt.WindowType.Window, True)
|
|
205
|
+
self.setWindowModality(Qt.WindowModality.NonModal)
|
|
206
|
+
self.setModal(False)
|
|
204
207
|
|
|
205
208
|
self._doc = doc
|
|
206
209
|
base = getattr(doc, "image", None)
|
|
@@ -581,7 +584,26 @@ class WaveScaleDarkEnhancerDialogPro(QDialog):
|
|
|
581
584
|
# Never let replay wiring break the apply
|
|
582
585
|
pass
|
|
583
586
|
|
|
584
|
-
|
|
587
|
+
# Dialog stays open so user can apply to other images
|
|
588
|
+
# Refresh document reference for next operation
|
|
589
|
+
self._refresh_document_from_active()
|
|
590
|
+
|
|
591
|
+
def _refresh_document_from_active(self):
|
|
592
|
+
"""
|
|
593
|
+
Refresh the dialog's document reference to the currently active document.
|
|
594
|
+
This allows reusing the same dialog on different images.
|
|
595
|
+
"""
|
|
596
|
+
try:
|
|
597
|
+
main = self.parent()
|
|
598
|
+
if main and hasattr(main, "_active_doc"):
|
|
599
|
+
new_doc = main._active_doc()
|
|
600
|
+
if new_doc is not None and new_doc is not self._doc:
|
|
601
|
+
self._doc = new_doc
|
|
602
|
+
# Reset state and refresh for new document
|
|
603
|
+
self._L_original = None
|
|
604
|
+
self._last_preview = None
|
|
605
|
+
except Exception:
|
|
606
|
+
pass
|
|
585
607
|
|
|
586
608
|
|
|
587
609
|
# ─────────────────────────────────────────────────────────────────────────────
|
setiastro/saspro/whitebalance.py
CHANGED
|
@@ -191,10 +191,18 @@ def apply_white_balance_to_doc(doc, preset: Optional[Dict] = None):
|
|
|
191
191
|
class WhiteBalanceDialog(QDialog):
|
|
192
192
|
def __init__(self, parent, doc, icon: QIcon | None = None):
|
|
193
193
|
super().__init__(parent)
|
|
194
|
+
self._main = parent
|
|
194
195
|
self.doc = doc
|
|
196
|
+
|
|
197
|
+
# Connect to active document change signal
|
|
198
|
+
if hasattr(self._main, "currentDocumentChanged"):
|
|
199
|
+
self._main.currentDocumentChanged.connect(self._on_active_doc_changed)
|
|
195
200
|
if icon:
|
|
196
201
|
self.setWindowIcon(icon)
|
|
197
202
|
self.setWindowTitle(self.tr("White Balance"))
|
|
203
|
+
self.setWindowFlag(Qt.WindowType.Window, True)
|
|
204
|
+
self.setWindowModality(Qt.WindowModality.NonModal)
|
|
205
|
+
self.setModal(False)
|
|
198
206
|
self.resize(900, 600)
|
|
199
207
|
|
|
200
208
|
self._build_ui()
|
|
@@ -291,6 +299,18 @@ class WhiteBalanceDialog(QDialog):
|
|
|
291
299
|
self.manual_group.setVisible(t == "Manual")
|
|
292
300
|
self.star_group.setVisible(t == "Star-Based")
|
|
293
301
|
|
|
302
|
+
# ---- active document change ------------------------------------
|
|
303
|
+
def _on_active_doc_changed(self, doc):
|
|
304
|
+
"""Called when user clicks a different image window."""
|
|
305
|
+
if doc is None or getattr(doc, "image", None) is None:
|
|
306
|
+
return
|
|
307
|
+
self.doc = doc
|
|
308
|
+
# Force fresh star detection by temporarily disabling cache
|
|
309
|
+
old_reuse = self.chk_reuse.isChecked()
|
|
310
|
+
self.chk_reuse.setChecked(False)
|
|
311
|
+
self._update_star_preview()
|
|
312
|
+
self.chk_reuse.setChecked(old_reuse)
|
|
313
|
+
|
|
294
314
|
# ---- preview --------------------------------------------------------
|
|
295
315
|
def _update_star_preview(self):
|
|
296
316
|
if self.type_combo.currentText() != "Star-Based":
|
|
@@ -373,7 +393,8 @@ class WhiteBalanceDialog(QDialog):
|
|
|
373
393
|
|
|
374
394
|
# Use the headless helper so doc metadata is consistent
|
|
375
395
|
apply_white_balance_to_doc(self.doc, preset)
|
|
376
|
-
|
|
396
|
+
# Dialog stays open - refresh document for next operation
|
|
397
|
+
self._refresh_document_from_active()
|
|
377
398
|
|
|
378
399
|
elif mode == "Auto":
|
|
379
400
|
preset = {"mode": "auto"}
|
|
@@ -382,7 +403,8 @@ class WhiteBalanceDialog(QDialog):
|
|
|
382
403
|
_record_preset_for_replay(preset)
|
|
383
404
|
|
|
384
405
|
apply_white_balance_to_doc(self.doc, preset)
|
|
385
|
-
|
|
406
|
+
# Dialog stays open - refresh document for next operation
|
|
407
|
+
self._refresh_document_from_active()
|
|
386
408
|
|
|
387
409
|
else: # --- Star-Based: compute here so we can plot like SASv2 ---
|
|
388
410
|
thr = float(self.thr_slider.value())
|
|
@@ -449,8 +471,22 @@ class WhiteBalanceDialog(QDialog):
|
|
|
449
471
|
self.tr("White Balance"),
|
|
450
472
|
self.tr("Star-Based WB applied.\nDetected {0} stars.").format(int(star_count)),
|
|
451
473
|
)
|
|
452
|
-
|
|
474
|
+
# Dialog stays open - refresh document for next operation
|
|
475
|
+
self._refresh_document_from_active()
|
|
453
476
|
|
|
454
477
|
except Exception as e:
|
|
455
478
|
QMessageBox.critical(self, self.tr("White Balance"), self.tr("Failed to apply White Balance:\n{0}").format(e))
|
|
456
479
|
|
|
480
|
+
def _refresh_document_from_active(self):
|
|
481
|
+
"""
|
|
482
|
+
Refresh the dialog's document reference to the currently active document.
|
|
483
|
+
This allows reusing the same dialog on different images.
|
|
484
|
+
"""
|
|
485
|
+
try:
|
|
486
|
+
main = self.parent()
|
|
487
|
+
if main and hasattr(main, "_active_doc"):
|
|
488
|
+
new_doc = main._active_doc()
|
|
489
|
+
if new_doc is not None and new_doc is not self.doc:
|
|
490
|
+
self.doc = new_doc
|
|
491
|
+
except Exception:
|
|
492
|
+
pass
|