setiastrosuitepro 1.6.1.post1__py3-none-any.whl → 1.6.4__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/Background_startup.jpg +0 -0
- setiastro/images/rotatearbitrary.png +0 -0
- setiastro/qml/ResourceMonitor.qml +126 -0
- setiastro/saspro/__main__.py +162 -25
- 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 +60 -9
- setiastro/saspro/batch_convert.py +3 -0
- setiastro/saspro/batch_renamer.py +3 -0
- setiastro/saspro/blemish_blaster.py +3 -0
- setiastro/saspro/blink_comparator_pro.py +474 -251
- 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 +28 -1
- setiastro/saspro/curve_editor_pro.py +18 -0
- setiastro/saspro/debayer.py +3 -0
- setiastro/saspro/doc_manager.py +40 -17
- setiastro/saspro/fitsmodifier.py +3 -0
- setiastro/saspro/frequency_separation.py +8 -2
- setiastro/saspro/function_bundle.py +18 -16
- 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 +364 -92
- setiastro/saspro/gui/mixins/dock_mixin.py +119 -7
- setiastro/saspro/gui/mixins/file_mixin.py +7 -0
- setiastro/saspro/gui/mixins/geometry_mixin.py +105 -5
- setiastro/saspro/gui/mixins/menu_mixin.py +29 -0
- setiastro/saspro/gui/mixins/toolbar_mixin.py +33 -10
- 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 +713 -256
- 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 +1 -0
- setiastro/saspro/remove_green.py +18 -1
- setiastro/saspro/remove_stars.py +136 -162
- setiastro/saspro/remove_stars_preset.py +55 -13
- setiastro/saspro/resources.py +36 -10
- setiastro/saspro/rgb_combination.py +1 -0
- setiastro/saspro/rgbalign.py +4 -4
- setiastro/saspro/save_options.py +1 -0
- setiastro/saspro/selective_color.py +79 -20
- setiastro/saspro/sfcc.py +50 -8
- setiastro/saspro/shortcuts.py +94 -21
- setiastro/saspro/signature_insert.py +3 -0
- setiastro/saspro/stacking_suite.py +924 -446
- setiastro/saspro/star_alignment.py +291 -331
- setiastro/saspro/star_spikes.py +116 -32
- setiastro/saspro/star_stretch.py +38 -1
- setiastro/saspro/stat_stretch.py +35 -3
- setiastro/saspro/status_log_dock.py +1 -1
- setiastro/saspro/subwindow.py +63 -2
- setiastro/saspro/supernovaasteroidhunter.py +3 -0
- setiastro/saspro/swap_manager.py +77 -42
- setiastro/saspro/translations/all_source_strings.json +4726 -0
- setiastro/saspro/translations/ar_translations.py +4096 -0
- setiastro/saspro/translations/de_translations.py +441 -446
- setiastro/saspro/translations/es_translations.py +278 -32
- setiastro/saspro/translations/fr_translations.py +280 -32
- setiastro/saspro/translations/hi_translations.py +3803 -0
- setiastro/saspro/translations/integrate_translations.py +38 -1
- setiastro/saspro/translations/it_translations.py +1211 -145
- setiastro/saspro/translations/ja_translations.py +556 -307
- setiastro/saspro/translations/pt_translations.py +3316 -3322
- setiastro/saspro/translations/ru_translations.py +3082 -0
- setiastro/saspro/translations/saspro_ar.qm +0 -0
- setiastro/saspro/translations/saspro_ar.ts +16019 -0
- setiastro/saspro/translations/saspro_de.qm +0 -0
- setiastro/saspro/translations/saspro_de.ts +14428 -133
- setiastro/saspro/translations/saspro_es.qm +0 -0
- setiastro/saspro/translations/saspro_es.ts +11503 -7821
- setiastro/saspro/translations/saspro_fr.qm +0 -0
- setiastro/saspro/translations/saspro_fr.ts +11168 -7812
- setiastro/saspro/translations/saspro_hi.qm +0 -0
- setiastro/saspro/translations/saspro_hi.ts +14855 -0
- setiastro/saspro/translations/saspro_it.qm +0 -0
- setiastro/saspro/translations/saspro_it.ts +14347 -7821
- setiastro/saspro/translations/saspro_ja.qm +0 -0
- setiastro/saspro/translations/saspro_ja.ts +14860 -137
- setiastro/saspro/translations/saspro_pt.qm +0 -0
- setiastro/saspro/translations/saspro_pt.ts +14904 -137
- setiastro/saspro/translations/saspro_ru.qm +0 -0
- setiastro/saspro/translations/saspro_ru.ts +11835 -0
- setiastro/saspro/translations/saspro_sw.qm +0 -0
- setiastro/saspro/translations/saspro_sw.ts +15237 -0
- setiastro/saspro/translations/saspro_uk.qm +0 -0
- setiastro/saspro/translations/saspro_uk.ts +15248 -0
- setiastro/saspro/translations/saspro_zh.qm +0 -0
- setiastro/saspro/translations/saspro_zh.ts +10581 -7812
- setiastro/saspro/translations/sw_translations.py +3897 -0
- setiastro/saspro/translations/uk_translations.py +3929 -0
- setiastro/saspro/translations/zh_translations.py +283 -32
- setiastro/saspro/versioning.py +36 -5
- setiastro/saspro/view_bundle.py +20 -17
- 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 +991 -0
- setiastro/saspro/widgets/minigame/index.html +53 -0
- setiastro/saspro/widgets/minigame/style.css +241 -0
- setiastro/saspro/widgets/resource_monitor.py +263 -0
- setiastro/saspro/widgets/spinboxes.py +18 -0
- setiastro/saspro/widgets/wavelet_utils.py +52 -20
- setiastro/saspro/wimi.py +100 -80
- setiastro/saspro/wims.py +33 -33
- setiastro/saspro/window_shelf.py +2 -2
- {setiastrosuitepro-1.6.1.post1.dist-info → setiastrosuitepro-1.6.4.dist-info}/METADATA +15 -4
- {setiastrosuitepro-1.6.1.post1.dist-info → setiastrosuitepro-1.6.4.dist-info}/RECORD +139 -115
- {setiastrosuitepro-1.6.1.post1.dist-info → setiastrosuitepro-1.6.4.dist-info}/WHEEL +0 -0
- {setiastrosuitepro-1.6.1.post1.dist-info → setiastrosuitepro-1.6.4.dist-info}/entry_points.txt +0 -0
- {setiastrosuitepro-1.6.1.post1.dist-info → setiastrosuitepro-1.6.4.dist-info}/licenses/LICENSE +0 -0
- {setiastrosuitepro-1.6.1.post1.dist-info → setiastrosuitepro-1.6.4.dist-info}/licenses/license.txt +0 -0
setiastro/saspro/doc_manager.py
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
#
|
|
1
|
+
# saspro/doc_manager.py
|
|
2
2
|
from __future__ import annotations
|
|
3
3
|
from PyQt6.QtCore import QObject, pyqtSignal, Qt, QTimer
|
|
4
4
|
from PyQt6.QtWidgets import QApplication, QMessageBox
|
|
@@ -2472,23 +2472,29 @@ class DocManager(QObject):
|
|
|
2472
2472
|
If a Preview tab is selected on the active ImageSubWindow, return a cached
|
|
2473
2473
|
_RoiViewDocument so tools and the Preview tab share the same instance.
|
|
2474
2474
|
Otherwise return the real ImageDocument.
|
|
2475
|
+
|
|
2476
|
+
IMPORTANT: Always check the currently active MDI subwindow first,
|
|
2477
|
+
as that's what the user expects to be the "active" document.
|
|
2475
2478
|
"""
|
|
2476
|
-
|
|
2477
|
-
|
|
2478
|
-
|
|
2479
|
-
|
|
2480
|
-
|
|
2481
|
-
|
|
2482
|
-
if
|
|
2483
|
-
|
|
2484
|
-
|
|
2485
|
-
|
|
2486
|
-
|
|
2487
|
-
|
|
2488
|
-
|
|
2489
|
-
|
|
2490
|
-
|
|
2491
|
-
|
|
2479
|
+
base_doc = None
|
|
2480
|
+
|
|
2481
|
+
# ALWAYS check the MDI active subwindow first - this is the source of truth
|
|
2482
|
+
try:
|
|
2483
|
+
if self._mdi is not None:
|
|
2484
|
+
sw = self._mdi.activeSubWindow()
|
|
2485
|
+
if sw is not None:
|
|
2486
|
+
w = sw.widget()
|
|
2487
|
+
base_doc = getattr(w, "document", None) or getattr(sw, "document", None)
|
|
2488
|
+
if base_doc is not None:
|
|
2489
|
+
self._active_doc = base_doc
|
|
2490
|
+
except Exception:
|
|
2491
|
+
pass
|
|
2492
|
+
|
|
2493
|
+
# Fallback to cached value only if MDI lookup failed
|
|
2494
|
+
if base_doc is None:
|
|
2495
|
+
if self._active_doc is not None and self._active_doc in self._docs:
|
|
2496
|
+
base_doc = self._active_doc
|
|
2497
|
+
else:
|
|
2492
2498
|
base_doc = self._docs[-1] if self._docs else None
|
|
2493
2499
|
|
|
2494
2500
|
# Non-image docs just pass through
|
|
@@ -2524,6 +2530,23 @@ class DocManager(QObject):
|
|
|
2524
2530
|
|
|
2525
2531
|
# Prefer explicit doc if given; otherwise fall back to "active"
|
|
2526
2532
|
view_doc = doc or self.get_active_document()
|
|
2533
|
+
|
|
2534
|
+
# DEBUG: Trace why LinearFit might fail
|
|
2535
|
+
# print(f"[DocManager] update_active_document target: {view_doc}, type: {type(view_doc).__name__}")
|
|
2536
|
+
|
|
2537
|
+
# NEW: Unwrap proxy objects (_DocProxy / LiveViewDocument)
|
|
2538
|
+
tname = type(view_doc).__name__
|
|
2539
|
+
if "LiveViewDocument" in tname:
|
|
2540
|
+
try:
|
|
2541
|
+
view_doc = view_doc._current()
|
|
2542
|
+
except Exception:
|
|
2543
|
+
pass
|
|
2544
|
+
elif "_DocProxy" in tname:
|
|
2545
|
+
try:
|
|
2546
|
+
view_doc = view_doc._target()
|
|
2547
|
+
except Exception:
|
|
2548
|
+
pass
|
|
2549
|
+
|
|
2527
2550
|
if view_doc is None:
|
|
2528
2551
|
raise RuntimeError("No active document")
|
|
2529
2552
|
|
setiastro/saspro/fitsmodifier.py
CHANGED
|
@@ -606,6 +606,9 @@ class BatchFITSHeaderDialog(QDialog):
|
|
|
606
606
|
def __init__(self, parent=None, preset_keyword: str = "", preset_value: str = "", preset_comment: str = ""):
|
|
607
607
|
super().__init__(parent)
|
|
608
608
|
self.setWindowTitle(self.tr("Batch Modify FITS Headers"))
|
|
609
|
+
self.setWindowFlag(Qt.WindowType.Window, True)
|
|
610
|
+
self.setWindowModality(Qt.WindowModality.NonModal)
|
|
611
|
+
self.setModal(False)
|
|
609
612
|
self.resize(520, 220)
|
|
610
613
|
|
|
611
614
|
v = QVBoxLayout(self)
|
|
@@ -708,10 +708,16 @@ class FrequencySeperationTab(QWidget):
|
|
|
708
708
|
|
|
709
709
|
# channel reconcile
|
|
710
710
|
if rch == 1 and ch == 3:
|
|
711
|
-
# convert RGB→mono (luma or
|
|
711
|
+
# convert RGB→mono (use weighted luma for consistency, or mean if desired. Original was mean)
|
|
712
712
|
a = a.mean(axis=2).astype(np.float32)
|
|
713
713
|
elif rch == 3 and ch == 1:
|
|
714
|
-
|
|
714
|
+
# Broadcast mono to 3 channels without copying
|
|
715
|
+
# (H,W,1) -> (H,W,3) via broadcasted view if consumer allows,
|
|
716
|
+
# but usually downstream (like subtraction) handles broadcasting fine.
|
|
717
|
+
# If explicit physical layout is needed, we must check usage.
|
|
718
|
+
# Here: used for subtraction (OK) and preview (OK).
|
|
719
|
+
# We return a view using broadcast_to or striding tricks.
|
|
720
|
+
a = np.broadcast_to(a, (ah, aw, 3))
|
|
715
721
|
|
|
716
722
|
return a
|
|
717
723
|
|
|
@@ -202,7 +202,7 @@ class FunctionBundleChip(QWidget):
|
|
|
202
202
|
from PyQt6.QtWidgets import QMenu # already imported at top, but safe
|
|
203
203
|
|
|
204
204
|
m = QMenu(self)
|
|
205
|
-
act_del = m.addAction("Delete Chip")
|
|
205
|
+
act_del = m.addAction(self._panel.tr("Delete Chip"))
|
|
206
206
|
act = m.exec(ev.globalPos())
|
|
207
207
|
if act is act_del:
|
|
208
208
|
try:
|
|
@@ -333,7 +333,9 @@ class FunctionBundleDialog(QDialog):
|
|
|
333
333
|
def __init__(self, parent: QWidget | None = None):
|
|
334
334
|
super().__init__(parent)
|
|
335
335
|
_pin_on_top_mac(self)
|
|
336
|
-
self.setWindowTitle("Function Bundles")
|
|
336
|
+
self.setWindowTitle(self.tr("Function Bundles"))
|
|
337
|
+
self.setWindowFlag(Qt.WindowType.Window, True)
|
|
338
|
+
self.setWindowModality(Qt.WindowModality.NonModal)
|
|
337
339
|
self.setModal(False)
|
|
338
340
|
self.resize(920, 560)
|
|
339
341
|
self.setAcceptDrops(True)
|
|
@@ -348,9 +350,9 @@ class FunctionBundleDialog(QDialog):
|
|
|
348
350
|
self.list.setSelectionMode(QAbstractItemView.SelectionMode.SingleSelection)
|
|
349
351
|
self.list.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
|
|
350
352
|
|
|
351
|
-
self.btn_new = QPushButton("New")
|
|
352
|
-
self.btn_dup = QPushButton("Duplicate")
|
|
353
|
-
self.btn_del = QPushButton("Delete")
|
|
353
|
+
self.btn_new = QPushButton(self.tr("New"))
|
|
354
|
+
self.btn_dup = QPushButton(self.tr("Duplicate"))
|
|
355
|
+
self.btn_del = QPushButton(self.tr("Delete"))
|
|
354
356
|
|
|
355
357
|
# right: steps
|
|
356
358
|
self.steps = QListWidget()
|
|
@@ -366,26 +368,26 @@ class FunctionBundleDialog(QDialog):
|
|
|
366
368
|
self.steps.setResizeMode(QListView.ResizeMode.Adjust) # recompute item layout on width change
|
|
367
369
|
self.steps.setUniformItemSizes(False)
|
|
368
370
|
|
|
369
|
-
self.add_hint = QLabel("Drop shortcuts here to add steps")
|
|
371
|
+
self.add_hint = QLabel(self.tr("Drop shortcuts here to add steps"))
|
|
370
372
|
self.add_hint.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
|
371
373
|
self.add_hint.setStyleSheet("color:#aaa; padding:6px; border:1px dashed #666; border-radius:6px;")
|
|
372
374
|
|
|
373
|
-
self.btn_edit_preset = QPushButton("Edit Preset…")
|
|
375
|
+
self.btn_edit_preset = QPushButton(self.tr("Edit Preset…"))
|
|
374
376
|
self.btn_edit_preset.setEnabled(False) # enabled when exactly one step is selected
|
|
375
377
|
|
|
376
|
-
self.btn_remove = QPushButton("Remove Selected")
|
|
377
|
-
self.btn_clear = QPushButton("Clear Steps")
|
|
378
|
-
self.btn_up = QPushButton("▲ Move Up")
|
|
379
|
-
self.btn_down = QPushButton("▼ Move Down")
|
|
378
|
+
self.btn_remove = QPushButton(self.tr("Remove Selected"))
|
|
379
|
+
self.btn_clear = QPushButton(self.tr("Clear Steps"))
|
|
380
|
+
self.btn_up = QPushButton(self.tr("▲ Move Up"))
|
|
381
|
+
self.btn_down = QPushButton(self.tr("▼ Move Down"))
|
|
380
382
|
|
|
381
|
-
self.btn_drag_bundle = QPushButton("Drag Bundle")
|
|
382
|
-
self.btn_run_active = QPushButton("Apply to Active View")
|
|
383
|
-
self.btn_apply_to_vbundle = QPushButton("Apply to View Bundle…")
|
|
384
|
-
self.btn_chip = QPushButton("Compress to Chip")
|
|
383
|
+
self.btn_drag_bundle = QPushButton(self.tr("Drag Bundle"))
|
|
384
|
+
self.btn_run_active = QPushButton(self.tr("Apply to Active View"))
|
|
385
|
+
self.btn_apply_to_vbundle = QPushButton(self.tr("Apply to View Bundle…"))
|
|
386
|
+
self.btn_chip = QPushButton(self.tr("Compress to Chip"))
|
|
385
387
|
|
|
386
388
|
# layout
|
|
387
389
|
left = QVBoxLayout()
|
|
388
|
-
left.addWidget(QLabel("Function Bundles"))
|
|
390
|
+
left.addWidget(QLabel(self.tr("Function Bundles")))
|
|
389
391
|
left.addWidget(self.list, 1)
|
|
390
392
|
row = QHBoxLayout()
|
|
391
393
|
row.addWidget(self.btn_new); row.addWidget(self.btn_dup); row.addWidget(self.btn_del)
|