setiastrosuitepro 1.6.1.post1__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 +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 +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 +272 -29
- 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 +1 -0
- 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 +36 -5
- 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 +35 -15
- {setiastrosuitepro-1.6.1.post1.dist-info → setiastrosuitepro-1.6.2.dist-info}/METADATA +15 -4
- {setiastrosuitepro-1.6.1.post1.dist-info → setiastrosuitepro-1.6.2.dist-info}/RECORD +127 -104
- {setiastrosuitepro-1.6.1.post1.dist-info → setiastrosuitepro-1.6.2.dist-info}/WHEEL +0 -0
- {setiastrosuitepro-1.6.1.post1.dist-info → setiastrosuitepro-1.6.2.dist-info}/entry_points.txt +0 -0
- {setiastrosuitepro-1.6.1.post1.dist-info → setiastrosuitepro-1.6.2.dist-info}/licenses/LICENSE +0 -0
- {setiastrosuitepro-1.6.1.post1.dist-info → setiastrosuitepro-1.6.2.dist-info}/licenses/license.txt +0 -0
|
@@ -271,7 +271,16 @@ class CropDialogPro(QDialog):
|
|
|
271
271
|
def __init__(self, parent, document):
|
|
272
272
|
super().__init__(parent)
|
|
273
273
|
self.setWindowTitle(self.tr("Crop Tool"))
|
|
274
|
+
self.setWindowFlag(Qt.WindowType.Window, True)
|
|
275
|
+
self.setWindowModality(Qt.WindowModality.NonModal)
|
|
276
|
+
self.setModal(False)
|
|
277
|
+
self._main = parent
|
|
274
278
|
self.doc = document
|
|
279
|
+
|
|
280
|
+
# Connect to active document change signal
|
|
281
|
+
if hasattr(self._main, "currentDocumentChanged"):
|
|
282
|
+
self._main.currentDocumentChanged.connect(self._on_active_doc_changed)
|
|
283
|
+
|
|
275
284
|
self._rect_item: Optional[ResizableRotatableRectItem] = None
|
|
276
285
|
self._pix_item: Optional[QGraphicsPixmapItem] = None
|
|
277
286
|
self._drawing = False
|
|
@@ -463,6 +472,14 @@ class CropDialogPro(QDialog):
|
|
|
463
472
|
arr = arr[..., 0]
|
|
464
473
|
return np.clip(arr, 0.0, 1.0)
|
|
465
474
|
|
|
475
|
+
def _on_active_doc_changed(self, doc):
|
|
476
|
+
"""Called when user clicks a different image window."""
|
|
477
|
+
if doc is None or getattr(doc, "image", None) is None:
|
|
478
|
+
return
|
|
479
|
+
self.doc = doc
|
|
480
|
+
self._rect_item = None
|
|
481
|
+
self._load_from_doc()
|
|
482
|
+
|
|
466
483
|
def _load_from_doc(self):
|
|
467
484
|
self._full01 = self._img01_from_doc()
|
|
468
485
|
self._orig_h, self._orig_w = self._full01.shape[:2]
|
|
@@ -1016,7 +1016,16 @@ class CurvesDialogPro(QDialog):
|
|
|
1016
1016
|
def __init__(self, parent, document):
|
|
1017
1017
|
super().__init__(parent)
|
|
1018
1018
|
self.setWindowTitle(self.tr("Curves Editor"))
|
|
1019
|
+
self.setWindowFlag(Qt.WindowType.Window, True)
|
|
1020
|
+
self.setWindowModality(Qt.WindowModality.NonModal)
|
|
1021
|
+
self.setModal(False)
|
|
1022
|
+
self._main = parent
|
|
1019
1023
|
self.doc = document
|
|
1024
|
+
|
|
1025
|
+
# Connect to active document change signal
|
|
1026
|
+
if hasattr(self._main, "currentDocumentChanged"):
|
|
1027
|
+
self._main.currentDocumentChanged.connect(self._on_active_doc_changed)
|
|
1028
|
+
|
|
1020
1029
|
self._preview_img = None # downsampled float01
|
|
1021
1030
|
self._full_img = None # full-res float01
|
|
1022
1031
|
self._pix = None
|
|
@@ -1788,6 +1797,15 @@ class CurvesDialogPro(QDialog):
|
|
|
1788
1797
|
self._rebuild_presets_menu()
|
|
1789
1798
|
|
|
1790
1799
|
|
|
1800
|
+
# ----- active document change -----
|
|
1801
|
+
def _on_active_doc_changed(self, doc):
|
|
1802
|
+
"""Called when user clicks a different image window."""
|
|
1803
|
+
if doc is None or getattr(doc, "image", None) is None:
|
|
1804
|
+
return
|
|
1805
|
+
self.doc = doc
|
|
1806
|
+
self._load_from_doc()
|
|
1807
|
+
QTimer.singleShot(0, self._fit_after_load)
|
|
1808
|
+
|
|
1791
1809
|
# ----- data -----
|
|
1792
1810
|
def _load_from_doc(self):
|
|
1793
1811
|
img = self.doc.image
|
setiastro/saspro/debayer.py
CHANGED
|
@@ -402,6 +402,9 @@ class DebayerDialog(QDialog):
|
|
|
402
402
|
def __init__(self, parent, doc_manager, active_doc):
|
|
403
403
|
super().__init__(parent)
|
|
404
404
|
self.setWindowTitle(self.tr("Debayer"))
|
|
405
|
+
self.setWindowFlag(Qt.WindowType.Window, True)
|
|
406
|
+
self.setWindowModality(Qt.WindowModality.NonModal)
|
|
407
|
+
self.setModal(False)
|
|
405
408
|
self.dm = doc_manager
|
|
406
409
|
self.doc = active_doc
|
|
407
410
|
self.worker: Optional[_DebayerWorker] = None
|
setiastro/saspro/doc_manager.py
CHANGED
|
@@ -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
|
|
|
@@ -334,6 +334,8 @@ class FunctionBundleDialog(QDialog):
|
|
|
334
334
|
super().__init__(parent)
|
|
335
335
|
_pin_on_top_mac(self)
|
|
336
336
|
self.setWindowTitle("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)
|