setiastrosuitepro 1.6.0__py3-none-any.whl → 1.6.4.post1__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/data/SASP_data.fits +0 -0
- setiastro/data/catalogs/List_of_Galaxies_with_Distances_Gly.csv +488 -0
- setiastro/data/catalogs/astrobin_filters.csv +890 -0
- setiastro/data/catalogs/astrobin_filters_page1_local.csv +51 -0
- setiastro/data/catalogs/cali2.csv +63 -0
- setiastro/data/catalogs/cali2color.csv +65 -0
- setiastro/data/catalogs/celestial_catalog - original.csv +16471 -0
- setiastro/data/catalogs/celestial_catalog.csv +24031 -0
- setiastro/data/catalogs/detected_stars.csv +24784 -0
- setiastro/data/catalogs/fits_header_data.csv +46 -0
- setiastro/data/catalogs/test.csv +8 -0
- setiastro/data/catalogs/updated_celestial_catalog.csv +16471 -0
- setiastro/images/Astro_Spikes.png +0 -0
- setiastro/images/Background_startup.jpg +0 -0
- setiastro/images/HRDiagram.png +0 -0
- setiastro/images/LExtract.png +0 -0
- setiastro/images/LInsert.png +0 -0
- setiastro/images/Oxygenation-atm-2.svg.png +0 -0
- setiastro/images/RGB080604.png +0 -0
- setiastro/images/abeicon.png +0 -0
- setiastro/images/aberration.png +0 -0
- setiastro/images/andromedatry.png +0 -0
- setiastro/images/andromedatry_satellited.png +0 -0
- setiastro/images/annotated.png +0 -0
- setiastro/images/aperture.png +0 -0
- setiastro/images/astrosuite.ico +0 -0
- setiastro/images/astrosuite.png +0 -0
- setiastro/images/astrosuitepro.icns +0 -0
- setiastro/images/astrosuitepro.ico +0 -0
- setiastro/images/astrosuitepro.png +0 -0
- setiastro/images/background.png +0 -0
- setiastro/images/background2.png +0 -0
- setiastro/images/benchmark.png +0 -0
- setiastro/images/big_moon_stabilizer_timeline.png +0 -0
- setiastro/images/big_moon_stabilizer_timeline_clean.png +0 -0
- setiastro/images/blaster.png +0 -0
- setiastro/images/blink.png +0 -0
- setiastro/images/clahe.png +0 -0
- setiastro/images/collage.png +0 -0
- setiastro/images/colorwheel.png +0 -0
- setiastro/images/contsub.png +0 -0
- setiastro/images/convo.png +0 -0
- setiastro/images/copyslot.png +0 -0
- setiastro/images/cosmic.png +0 -0
- setiastro/images/cosmicsat.png +0 -0
- setiastro/images/crop1.png +0 -0
- setiastro/images/cropicon.png +0 -0
- setiastro/images/curves.png +0 -0
- setiastro/images/cvs.png +0 -0
- setiastro/images/debayer.png +0 -0
- setiastro/images/denoise_cnn_custom.png +0 -0
- setiastro/images/denoise_cnn_graph.png +0 -0
- setiastro/images/disk.png +0 -0
- setiastro/images/dse.png +0 -0
- setiastro/images/exoicon.png +0 -0
- setiastro/images/eye.png +0 -0
- setiastro/images/fliphorizontal.png +0 -0
- setiastro/images/flipvertical.png +0 -0
- setiastro/images/font.png +0 -0
- setiastro/images/freqsep.png +0 -0
- setiastro/images/functionbundle.png +0 -0
- setiastro/images/graxpert.png +0 -0
- setiastro/images/green.png +0 -0
- setiastro/images/gridicon.png +0 -0
- setiastro/images/halo.png +0 -0
- setiastro/images/hdr.png +0 -0
- setiastro/images/histogram.png +0 -0
- setiastro/images/hubble.png +0 -0
- setiastro/images/imagecombine.png +0 -0
- setiastro/images/invert.png +0 -0
- setiastro/images/isophote.png +0 -0
- setiastro/images/isophote_demo_figure.png +0 -0
- setiastro/images/isophote_demo_image.png +0 -0
- setiastro/images/isophote_demo_model.png +0 -0
- setiastro/images/isophote_demo_residual.png +0 -0
- setiastro/images/jwstpupil.png +0 -0
- setiastro/images/linearfit.png +0 -0
- setiastro/images/livestacking.png +0 -0
- setiastro/images/mask.png +0 -0
- setiastro/images/maskapply.png +0 -0
- setiastro/images/maskcreate.png +0 -0
- setiastro/images/maskremove.png +0 -0
- setiastro/images/morpho.png +0 -0
- setiastro/images/mosaic.png +0 -0
- setiastro/images/multiscale_decomp.png +0 -0
- setiastro/images/nbtorgb.png +0 -0
- setiastro/images/neutral.png +0 -0
- setiastro/images/nuke.png +0 -0
- setiastro/images/openfile.png +0 -0
- setiastro/images/pedestal.png +0 -0
- setiastro/images/pen.png +0 -0
- setiastro/images/pixelmath.png +0 -0
- setiastro/images/platesolve.png +0 -0
- setiastro/images/ppp.png +0 -0
- setiastro/images/pro.png +0 -0
- setiastro/images/project.png +0 -0
- setiastro/images/psf.png +0 -0
- setiastro/images/redo.png +0 -0
- setiastro/images/redoicon.png +0 -0
- setiastro/images/rescale.png +0 -0
- setiastro/images/rgbalign.png +0 -0
- setiastro/images/rgbcombo.png +0 -0
- setiastro/images/rgbextract.png +0 -0
- setiastro/images/rotate180.png +0 -0
- setiastro/images/rotatearbitrary.png +0 -0
- setiastro/images/rotateclockwise.png +0 -0
- setiastro/images/rotatecounterclockwise.png +0 -0
- setiastro/images/satellite.png +0 -0
- setiastro/images/script.png +0 -0
- setiastro/images/selectivecolor.png +0 -0
- setiastro/images/simbad.png +0 -0
- setiastro/images/slot0.png +0 -0
- setiastro/images/slot1.png +0 -0
- setiastro/images/slot2.png +0 -0
- setiastro/images/slot3.png +0 -0
- setiastro/images/slot4.png +0 -0
- setiastro/images/slot5.png +0 -0
- setiastro/images/slot6.png +0 -0
- setiastro/images/slot7.png +0 -0
- setiastro/images/slot8.png +0 -0
- setiastro/images/slot9.png +0 -0
- setiastro/images/spcc.png +0 -0
- setiastro/images/spin_precession_vs_lunar_distance.png +0 -0
- setiastro/images/spinner.gif +0 -0
- setiastro/images/stacking.png +0 -0
- setiastro/images/staradd.png +0 -0
- setiastro/images/staralign.png +0 -0
- setiastro/images/starnet.png +0 -0
- setiastro/images/starregistration.png +0 -0
- setiastro/images/starspike.png +0 -0
- setiastro/images/starstretch.png +0 -0
- setiastro/images/statstretch.png +0 -0
- setiastro/images/supernova.png +0 -0
- setiastro/images/uhs.png +0 -0
- setiastro/images/undoicon.png +0 -0
- setiastro/images/upscale.png +0 -0
- setiastro/images/viewbundle.png +0 -0
- setiastro/images/whitebalance.png +0 -0
- setiastro/images/wimi_icon_256x256.png +0 -0
- setiastro/images/wimilogo.png +0 -0
- setiastro/images/wims.png +0 -0
- setiastro/images/wrench_icon.png +0 -0
- setiastro/images/xisfliberator.png +0 -0
- setiastro/qml/ResourceMonitor.qml +126 -0
- setiastro/saspro/__main__.py +228 -67
- setiastro/saspro/_generated/build_info.py +2 -1
- setiastro/saspro/abe.py +76 -25
- setiastro/saspro/aberration_ai.py +14 -14
- setiastro/saspro/add_stars.py +15 -12
- setiastro/saspro/astrobin_exporter.py +61 -58
- setiastro/saspro/astrospike_python.py +3 -1
- setiastro/saspro/autostretch.py +4 -2
- setiastro/saspro/backgroundneutral.py +65 -14
- setiastro/saspro/batch_convert.py +8 -5
- setiastro/saspro/batch_renamer.py +39 -36
- setiastro/saspro/blemish_blaster.py +15 -12
- setiastro/saspro/blink_comparator_pro.py +605 -379
- setiastro/saspro/cheat_sheet.py +62 -17
- setiastro/saspro/clahe.py +34 -8
- setiastro/saspro/comet_stacking.py +103 -38
- setiastro/saspro/common_tr.py +107 -0
- setiastro/saspro/continuum_subtract.py +7 -7
- setiastro/saspro/convo.py +12 -9
- setiastro/saspro/copyastro.py +3 -0
- setiastro/saspro/cosmicclarity.py +77 -52
- setiastro/saspro/crop_dialog_pro.py +80 -45
- setiastro/saspro/curve_editor_pro.py +51 -33
- setiastro/saspro/debayer.py +6 -3
- setiastro/saspro/doc_manager.py +49 -19
- setiastro/saspro/exoplanet_detector.py +11 -11
- setiastro/saspro/fitsmodifier.py +48 -44
- setiastro/saspro/fix_bom.py +32 -0
- setiastro/saspro/frequency_separation.py +18 -12
- setiastro/saspro/function_bundle.py +18 -16
- setiastro/saspro/generate_translations.py +3092 -0
- setiastro/saspro/ghs_dialog_pro.py +19 -16
- setiastro/saspro/graxpert.py +3 -0
- setiastro/saspro/gui/main_window.py +471 -126
- setiastro/saspro/gui/mixins/dock_mixin.py +123 -11
- setiastro/saspro/gui/mixins/file_mixin.py +25 -20
- setiastro/saspro/gui/mixins/geometry_mixin.py +115 -15
- setiastro/saspro/gui/mixins/header_mixin.py +6 -6
- setiastro/saspro/gui/mixins/mask_mixin.py +8 -8
- setiastro/saspro/gui/mixins/menu_mixin.py +62 -33
- setiastro/saspro/gui/mixins/toolbar_mixin.py +382 -226
- setiastro/saspro/gui/mixins/update_mixin.py +26 -26
- setiastro/saspro/gui/statistics_dialog.py +47 -0
- setiastro/saspro/halobgon.py +29 -3
- setiastro/saspro/header_viewer.py +21 -18
- setiastro/saspro/histogram.py +29 -26
- setiastro/saspro/history_explorer.py +2 -0
- setiastro/saspro/i18n.py +168 -0
- setiastro/saspro/image_combine.py +3 -0
- setiastro/saspro/image_peeker_pro.py +52 -44
- 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 +180 -22
- setiastro/saspro/mfdeconv.py +5 -0
- setiastro/saspro/morphology.py +38 -13
- setiastro/saspro/multiscale_decomp.py +713 -256
- setiastro/saspro/nbtorgb_stars.py +12 -2
- setiastro/saspro/numba_utils.py +149 -48
- setiastro/saspro/ops/scripts.py +77 -17
- setiastro/saspro/ops/settings.py +177 -100
- setiastro/saspro/perfect_palette_picker.py +25 -7
- setiastro/saspro/pixelmath.py +114 -110
- setiastro/saspro/plate_solver.py +118 -108
- setiastro/saspro/remove_green.py +24 -7
- setiastro/saspro/remove_stars.py +136 -162
- setiastro/saspro/remove_stars_preset.py +55 -13
- setiastro/saspro/resources.py +46 -15
- setiastro/saspro/rgb_combination.py +19 -18
- setiastro/saspro/rgbalign.py +11 -11
- setiastro/saspro/save_options.py +5 -4
- setiastro/saspro/selective_color.py +84 -25
- setiastro/saspro/sfcc.py +119 -72
- setiastro/saspro/shortcuts.py +345 -36
- setiastro/saspro/signature_insert.py +4 -1
- setiastro/saspro/stacking_suite.py +2066 -1119
- setiastro/saspro/star_alignment.py +291 -331
- setiastro/saspro/star_spikes.py +137 -53
- setiastro/saspro/star_stretch.py +47 -10
- setiastro/saspro/stat_stretch.py +52 -16
- setiastro/saspro/status_log_dock.py +1 -1
- setiastro/saspro/subwindow.py +97 -36
- setiastro/saspro/supernovaasteroidhunter.py +68 -61
- 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 +3728 -0
- setiastro/saspro/translations/es_translations.py +4169 -0
- setiastro/saspro/translations/fr_translations.py +4090 -0
- setiastro/saspro/translations/hi_translations.py +3803 -0
- setiastro/saspro/translations/integrate_translations.py +271 -0
- setiastro/saspro/translations/it_translations.py +4728 -0
- setiastro/saspro/translations/ja_translations.py +3834 -0
- setiastro/saspro/translations/pt_translations.py +3847 -0
- 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 +14548 -0
- setiastro/saspro/translations/saspro_es.qm +0 -0
- setiastro/saspro/translations/saspro_es.ts +16202 -0
- setiastro/saspro/translations/saspro_fr.qm +0 -0
- setiastro/saspro/translations/saspro_fr.ts +15870 -0
- 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 +19046 -0
- setiastro/saspro/translations/saspro_ja.qm +0 -0
- setiastro/saspro/translations/saspro_ja.ts +14980 -0
- setiastro/saspro/translations/saspro_pt.qm +0 -0
- setiastro/saspro/translations/saspro_pt.ts +15024 -0
- 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 +15289 -0
- setiastro/saspro/translations/sw_translations.py +3897 -0
- setiastro/saspro/translations/uk_translations.py +3929 -0
- setiastro/saspro/translations/zh_translations.py +3910 -0
- setiastro/saspro/versioning.py +77 -0
- setiastro/saspro/view_bundle.py +20 -17
- setiastro/saspro/wavescale_hdr.py +54 -33
- setiastro/saspro/wavescale_hdr_preset.py +6 -5
- setiastro/saspro/wavescalede.py +54 -31
- setiastro/saspro/wavescalede_preset.py +9 -7
- setiastro/saspro/whitebalance.py +58 -22
- setiastro/saspro/widgets/common_utilities.py +12 -11
- 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/preview_dialogs.py +8 -8
- 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 +7996 -0
- setiastro/saspro/wims.py +578 -0
- setiastro/saspro/window_shelf.py +2 -2
- {setiastrosuitepro-1.6.0.dist-info → setiastrosuitepro-1.6.4.post1.dist-info}/METADATA +15 -3
- setiastrosuitepro-1.6.4.post1.dist-info/RECORD +368 -0
- setiastrosuitepro-1.6.0.dist-info/RECORD +0 -174
- {setiastrosuitepro-1.6.0.dist-info → setiastrosuitepro-1.6.4.post1.dist-info}/WHEEL +0 -0
- {setiastrosuitepro-1.6.0.dist-info → setiastrosuitepro-1.6.4.post1.dist-info}/entry_points.txt +0 -0
- {setiastrosuitepro-1.6.0.dist-info → setiastrosuitepro-1.6.4.post1.dist-info}/licenses/LICENSE +0 -0
- {setiastrosuitepro-1.6.0.dist-info → setiastrosuitepro-1.6.4.post1.dist-info}/licenses/license.txt +0 -0
|
@@ -42,8 +42,9 @@ class RGBCombinationDialogPro(QDialog):
|
|
|
42
42
|
"""
|
|
43
43
|
def __init__(self, parent, list_open_docs_fn=None, doc_manager=None):
|
|
44
44
|
super().__init__(parent)
|
|
45
|
-
self.setWindowTitle("RGB Combination")
|
|
45
|
+
self.setWindowTitle(self.tr("RGB Combination"))
|
|
46
46
|
self.setWindowFlag(Qt.WindowType.Window, True)
|
|
47
|
+
self.setWindowModality(Qt.WindowModality.NonModal)
|
|
47
48
|
self.setModal(False)
|
|
48
49
|
#self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose, True)
|
|
49
50
|
self._list_open_docs = list_open_docs_fn or (lambda: [])
|
|
@@ -55,28 +56,28 @@ class RGBCombinationDialogPro(QDialog):
|
|
|
55
56
|
self.b_path = None
|
|
56
57
|
|
|
57
58
|
# ── mode choose
|
|
58
|
-
self.load_files_radio = QRadioButton("Load Individual Files")
|
|
59
|
-
self.use_views_radio = QRadioButton("Use Open Views")
|
|
59
|
+
self.load_files_radio = QRadioButton(self.tr("Load Individual Files"))
|
|
60
|
+
self.use_views_radio = QRadioButton(self.tr("Use Open Views"))
|
|
60
61
|
self.use_views_radio.setChecked(True)
|
|
61
62
|
|
|
62
63
|
self.mode_group = QButtonGroup(self)
|
|
63
64
|
self.mode_group.addButton(self.load_files_radio)
|
|
64
65
|
self.mode_group.addButton(self.use_views_radio)
|
|
65
66
|
|
|
66
|
-
mode_box = QGroupBox("Select RGB Combination Mode")
|
|
67
|
+
mode_box = QGroupBox(self.tr("Select RGB Combination Mode"))
|
|
67
68
|
ml = QVBoxLayout(mode_box)
|
|
68
69
|
ml.addWidget(self.use_views_radio)
|
|
69
70
|
ml.addWidget(self.load_files_radio)
|
|
70
71
|
|
|
71
72
|
# ── file mode widgets
|
|
72
|
-
self.r_label = QLabel("Red: Not selected")
|
|
73
|
-
self.g_label = QLabel("Green: Not selected")
|
|
74
|
-
self.b_label = QLabel("Blue: Not selected")
|
|
75
|
-
self.btn_load_r = QPushButton("Load Red…"); self.btn_load_r.clicked.connect(lambda: self._pick_file("R"))
|
|
76
|
-
self.btn_load_g = QPushButton("Load Green…"); self.btn_load_g.clicked.connect(lambda: self._pick_file("G"))
|
|
77
|
-
self.btn_load_b = QPushButton("Load Blue…"); self.btn_load_b.clicked.connect(lambda: self._pick_file("B"))
|
|
78
|
-
|
|
79
|
-
file_box = QGroupBox("Files")
|
|
73
|
+
self.r_label = QLabel(self.tr("Red: Not selected"))
|
|
74
|
+
self.g_label = QLabel(self.tr("Green: Not selected"))
|
|
75
|
+
self.b_label = QLabel(self.tr("Blue: Not selected"))
|
|
76
|
+
self.btn_load_r = QPushButton(self.tr("Load Red…")); self.btn_load_r.clicked.connect(lambda: self._pick_file("R"))
|
|
77
|
+
self.btn_load_g = QPushButton(self.tr("Load Green…")); self.btn_load_g.clicked.connect(lambda: self._pick_file("G"))
|
|
78
|
+
self.btn_load_b = QPushButton(self.tr("Load Blue…")); self.btn_load_b.clicked.connect(lambda: self._pick_file("B"))
|
|
79
|
+
|
|
80
|
+
file_box = QGroupBox(self.tr("Files"))
|
|
80
81
|
fl = QVBoxLayout(file_box)
|
|
81
82
|
for lab, btn in [(self.r_label, self.btn_load_r),
|
|
82
83
|
(self.g_label, self.btn_load_g),
|
|
@@ -85,16 +86,16 @@ class RGBCombinationDialogPro(QDialog):
|
|
|
85
86
|
fl.addLayout(row)
|
|
86
87
|
|
|
87
88
|
# ── open-views widgets
|
|
88
|
-
views_box = QGroupBox("Select Open Views for R / G / B")
|
|
89
|
+
views_box = QGroupBox(self.tr("Select Open Views for R / G / B"))
|
|
89
90
|
vl = QHBoxLayout(views_box)
|
|
90
91
|
self.cmb_r = QComboBox(); self.cmb_g = QComboBox(); self.cmb_b = QComboBox()
|
|
91
|
-
vl.addLayout(self._labeled("Red:", self.cmb_r))
|
|
92
|
-
vl.addLayout(self._labeled("Green:", self.cmb_g))
|
|
93
|
-
vl.addLayout(self._labeled("Blue:", self.cmb_b))
|
|
92
|
+
vl.addLayout(self._labeled(self.tr("Red:"), self.cmb_r))
|
|
93
|
+
vl.addLayout(self._labeled(self.tr("Green:"), self.cmb_g))
|
|
94
|
+
vl.addLayout(self._labeled(self.tr("Blue:"), self.cmb_b))
|
|
94
95
|
|
|
95
96
|
# ── buttons
|
|
96
|
-
self.btn_combine = QPushButton("Combine")
|
|
97
|
-
self.btn_cancel = QPushButton("Cancel")
|
|
97
|
+
self.btn_combine = QPushButton(self.tr("Combine"))
|
|
98
|
+
self.btn_cancel = QPushButton(self.tr("Cancel"))
|
|
98
99
|
self.btn_cancel.clicked.connect(self.reject)
|
|
99
100
|
self.btn_combine.clicked.connect(self._combine)
|
|
100
101
|
|
setiastro/saspro/rgbalign.py
CHANGED
|
@@ -324,15 +324,12 @@ class RGBAlignWorker(QThread):
|
|
|
324
324
|
def _warp_channel(self, ch: np.ndarray, kind: str, X, ref_shape):
|
|
325
325
|
H, W = ref_shape[:2]
|
|
326
326
|
if kind == "affine":
|
|
327
|
-
|
|
328
|
-
return ch
|
|
327
|
+
# Just assume cv2 is available (standard dependency) for perf
|
|
329
328
|
A = np.asarray(X, dtype=np.float32).reshape(2, 3)
|
|
330
329
|
return cv2.warpAffine(ch, A, (W, H), flags=cv2.INTER_LANCZOS4,
|
|
331
330
|
borderMode=cv2.BORDER_CONSTANT, borderValue=0)
|
|
332
331
|
|
|
333
332
|
if kind == "homography":
|
|
334
|
-
if cv2 is None:
|
|
335
|
-
return ch
|
|
336
333
|
Hm = np.asarray(X, dtype=np.float32).reshape(3, 3)
|
|
337
334
|
return cv2.warpPerspective(ch, Hm, (W, H), flags=cv2.INTER_LANCZOS4,
|
|
338
335
|
borderMode=cv2.BORDER_CONSTANT, borderValue=0)
|
|
@@ -349,7 +346,10 @@ class RGBAlignWorker(QThread):
|
|
|
349
346
|
class RGBAlignDialog(QDialog):
|
|
350
347
|
def __init__(self, parent=None, document=None):
|
|
351
348
|
super().__init__(parent)
|
|
352
|
-
self.setWindowTitle("RGB Align")
|
|
349
|
+
self.setWindowTitle(self.tr("RGB Align"))
|
|
350
|
+
self.setWindowFlag(Qt.WindowType.Window, True)
|
|
351
|
+
self.setWindowModality(Qt.WindowModality.NonModal)
|
|
352
|
+
self.setModal(False)
|
|
353
353
|
self.parent = parent
|
|
354
354
|
# document could be a view; try to unwrap
|
|
355
355
|
self.doc_view = document
|
|
@@ -361,7 +361,7 @@ class RGBAlignDialog(QDialog):
|
|
|
361
361
|
"Select model and run."))
|
|
362
362
|
|
|
363
363
|
hl = QHBoxLayout()
|
|
364
|
-
hl.addWidget(QLabel("Alignment model:"))
|
|
364
|
+
hl.addWidget(QLabel(self.tr("Alignment model:")))
|
|
365
365
|
self.model_combo = QComboBox()
|
|
366
366
|
self.model_combo.addItems([
|
|
367
367
|
"EDGE", # ← first, new default
|
|
@@ -410,7 +410,7 @@ class RGBAlignDialog(QDialog):
|
|
|
410
410
|
|
|
411
411
|
# ── SEP controls ─────────────────────────
|
|
412
412
|
sep_row = QHBoxLayout()
|
|
413
|
-
sep_row.addWidget(QLabel("SEP sigma:"))
|
|
413
|
+
sep_row.addWidget(QLabel(self.tr("SEP sigma:")))
|
|
414
414
|
|
|
415
415
|
self.sep_spin = QSpinBox()
|
|
416
416
|
self.sep_spin.setRange(1, 100)
|
|
@@ -419,7 +419,7 @@ class RGBAlignDialog(QDialog):
|
|
|
419
419
|
"Higher = fewer stars, lower = more stars.")
|
|
420
420
|
sep_row.addWidget(self.sep_spin)
|
|
421
421
|
|
|
422
|
-
self.btn_trial_sep = QPushButton("Trial detect stars")
|
|
422
|
+
self.btn_trial_sep = QPushButton(self.tr("Trial detect stars"))
|
|
423
423
|
self.btn_trial_sep.setToolTip("Run SEP on the green channel with this sigma and report how many "
|
|
424
424
|
"stars it finds and how many are in the EDGE ring.")
|
|
425
425
|
self.btn_trial_sep.clicked.connect(self._trial_sep_detect)
|
|
@@ -428,7 +428,7 @@ class RGBAlignDialog(QDialog):
|
|
|
428
428
|
lay.addLayout(sep_row)
|
|
429
429
|
|
|
430
430
|
|
|
431
|
-
self.chk_new_doc = QCheckBox("Create new document (keep original)")
|
|
431
|
+
self.chk_new_doc = QCheckBox(self.tr("Create new document (keep original)"))
|
|
432
432
|
self.chk_new_doc.setChecked(True)
|
|
433
433
|
lay.addWidget(self.chk_new_doc)
|
|
434
434
|
|
|
@@ -449,8 +449,8 @@ class RGBAlignDialog(QDialog):
|
|
|
449
449
|
lay.addWidget(self.summary_box)
|
|
450
450
|
|
|
451
451
|
btns = QHBoxLayout()
|
|
452
|
-
self.btn_run = QPushButton("Align")
|
|
453
|
-
self.btn_close = QPushButton("Close")
|
|
452
|
+
self.btn_run = QPushButton(self.tr("Align"))
|
|
453
|
+
self.btn_close = QPushButton(self.tr("Close"))
|
|
454
454
|
btns.addWidget(self.btn_run)
|
|
455
455
|
btns.addWidget(self.btn_close)
|
|
456
456
|
lay.addLayout(btns)
|
setiastro/saspro/save_options.py
CHANGED
|
@@ -18,8 +18,9 @@ _BIT_DEPTHS = {
|
|
|
18
18
|
class SaveOptionsDialog(QDialog):
|
|
19
19
|
def __init__(self, parent, target_ext: str, current_bit_depth: str | None):
|
|
20
20
|
super().__init__(parent)
|
|
21
|
-
self.setWindowTitle("Save Options")
|
|
21
|
+
self.setWindowTitle(self.tr("Save Options"))
|
|
22
22
|
self.setWindowFlag(Qt.WindowType.Window, True)
|
|
23
|
+
self.setWindowModality(Qt.WindowModality.NonModal)
|
|
23
24
|
self.setModal(False)
|
|
24
25
|
#self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose, True)
|
|
25
26
|
|
|
@@ -48,11 +49,11 @@ class SaveOptionsDialog(QDialog):
|
|
|
48
49
|
if current_bit_depth in allowed:
|
|
49
50
|
self.combo.setCurrentText(current_bit_depth)
|
|
50
51
|
|
|
51
|
-
lbl = QLabel(
|
|
52
|
+
lbl = QLabel(self.tr("Choose bit depth for export:"))
|
|
52
53
|
lbl.setWordWrap(True)
|
|
53
54
|
|
|
54
|
-
btn_ok = QPushButton("OK")
|
|
55
|
-
btn_cancel = QPushButton("Cancel")
|
|
55
|
+
btn_ok = QPushButton(self.tr("OK"))
|
|
56
|
+
btn_cancel = QPushButton(self.tr("Cancel"))
|
|
56
57
|
btn_ok.clicked.connect(self.accept)
|
|
57
58
|
btn_cancel.clicked.connect(self.reject)
|
|
58
59
|
|
|
@@ -455,7 +455,7 @@ class SelectiveColorCorrection(QDialog):
|
|
|
455
455
|
"""
|
|
456
456
|
def __init__(self, doc_manager=None, document=None, parent=None, window_icon: QIcon | None = None):
|
|
457
457
|
super().__init__(parent)
|
|
458
|
-
self.setWindowTitle("Selective Color Correction")
|
|
458
|
+
self.setWindowTitle(self.tr("Selective Color Correction"))
|
|
459
459
|
if window_icon:
|
|
460
460
|
self.setWindowIcon(window_icon)
|
|
461
461
|
|
|
@@ -467,7 +467,7 @@ class SelectiveColorCorrection(QDialog):
|
|
|
467
467
|
|
|
468
468
|
self.img = np.clip(self.document.image.astype(np.float32), 0.0, 1.0)
|
|
469
469
|
self.preview_img = self.img.copy()
|
|
470
|
-
|
|
470
|
+
self._syncing_hue = False
|
|
471
471
|
self._imported_mask_full = None # full-res mask (H x W) float32 0..1
|
|
472
472
|
self._imported_mask_name = None # nice label to show in UI
|
|
473
473
|
self._use_imported_mask = False # checkbox state mirror
|
|
@@ -536,7 +536,7 @@ class SelectiveColorCorrection(QDialog):
|
|
|
536
536
|
left.setSpacing(8)
|
|
537
537
|
|
|
538
538
|
# ===== Mask group
|
|
539
|
-
gb_mask = QGroupBox("Mask")
|
|
539
|
+
gb_mask = QGroupBox(self.tr("Mask"))
|
|
540
540
|
gl = QGridLayout(gb_mask)
|
|
541
541
|
gl.setContentsMargins(8, 8, 8, 8)
|
|
542
542
|
gl.setHorizontalSpacing(10)
|
|
@@ -555,6 +555,36 @@ class SelectiveColorCorrection(QDialog):
|
|
|
555
555
|
self.hue_wheel.setSizePolicy(QSizePolicy.Policy.Minimum, QSizePolicy.Policy.Minimum)
|
|
556
556
|
gl.addWidget(self.hue_wheel, 1, 0, 7, 2)
|
|
557
557
|
|
|
558
|
+
# Wheel -> sliders/spins (so dragging wheel updates UI and mask)
|
|
559
|
+
def _wheel_to_sliders(s: int, e: int):
|
|
560
|
+
# If user is dragging the wheel, we’re now custom
|
|
561
|
+
if not self._setting_preset and self.dd_preset.currentText() != "Custom":
|
|
562
|
+
self.dd_preset.blockSignals(True)
|
|
563
|
+
self.dd_preset.setCurrentText("Custom")
|
|
564
|
+
self.dd_preset.blockSignals(False)
|
|
565
|
+
|
|
566
|
+
# Update BOTH sliders and spins, without ping-pong
|
|
567
|
+
self._syncing_hue = True
|
|
568
|
+
try:
|
|
569
|
+
s = int(s) % 360
|
|
570
|
+
e = int(e) % 360
|
|
571
|
+
|
|
572
|
+
for w, val in (
|
|
573
|
+
(self.sl_h1, s), (self.sp_h1, s),
|
|
574
|
+
(self.sl_h2, e), (self.sp_h2, e),
|
|
575
|
+
):
|
|
576
|
+
w.blockSignals(True)
|
|
577
|
+
w.setValue(val)
|
|
578
|
+
w.blockSignals(False)
|
|
579
|
+
finally:
|
|
580
|
+
self._syncing_hue = False
|
|
581
|
+
|
|
582
|
+
self._schedule_mask()
|
|
583
|
+
|
|
584
|
+
self.hue_wheel.rangeChanged.connect(_wheel_to_sliders)
|
|
585
|
+
|
|
586
|
+
|
|
587
|
+
|
|
558
588
|
# Helper: integer slider + spin (0..360)
|
|
559
589
|
def _deg_pair(grid: QGridLayout, label: str, row: int):
|
|
560
590
|
grid.addWidget(QLabel(label), row, 2)
|
|
@@ -574,7 +604,8 @@ class SelectiveColorCorrection(QDialog):
|
|
|
574
604
|
|
|
575
605
|
# Row 3: chroma + lightness
|
|
576
606
|
gl.addWidget(QLabel("Min chroma:"), 3, 2)
|
|
577
|
-
self.ds_minC = QDoubleSpinBox(); self.ds_minC.setRange(0,1); self.ds_minC.setSingleStep(0.05); self.ds_minC.setValue(0.
|
|
607
|
+
self.ds_minC = QDoubleSpinBox(); self.ds_minC.setRange(0,1); self.ds_minC.setSingleStep(0.05); self.ds_minC.setValue(0.05)
|
|
608
|
+
|
|
578
609
|
self.ds_minC.valueChanged.connect(self._recompute_mask_and_preview)
|
|
579
610
|
gl.addWidget(self.ds_minC, 3, 3)
|
|
580
611
|
|
|
@@ -652,7 +683,7 @@ class SelectiveColorCorrection(QDialog):
|
|
|
652
683
|
|
|
653
684
|
# ===== Adjustments
|
|
654
685
|
# CMY
|
|
655
|
-
gb_cmy = QGroupBox("Complementary colors (CMY)")
|
|
686
|
+
gb_cmy = QGroupBox(self.tr("Complementary colors (CMY)"))
|
|
656
687
|
glc = QGridLayout(gb_cmy)
|
|
657
688
|
self.sl_c, self.ds_c = self._slider_pair(glc, "Cyan:", 0)
|
|
658
689
|
self.sl_m, self.ds_m = self._slider_pair(glc, "Magenta:", 1)
|
|
@@ -660,7 +691,7 @@ class SelectiveColorCorrection(QDialog):
|
|
|
660
691
|
left.addWidget(gb_cmy)
|
|
661
692
|
|
|
662
693
|
# RGB
|
|
663
|
-
gb_rgb = QGroupBox("RGB Colors")
|
|
694
|
+
gb_rgb = QGroupBox(self.tr("RGB Colors"))
|
|
664
695
|
glr = QGridLayout(gb_rgb)
|
|
665
696
|
self.sl_r, self.ds_r = self._slider_pair(glr, "Red:", 0)
|
|
666
697
|
self.sl_g, self.ds_g = self._slider_pair(glr, "Green:", 1)
|
|
@@ -668,7 +699,7 @@ class SelectiveColorCorrection(QDialog):
|
|
|
668
699
|
left.addWidget(gb_rgb)
|
|
669
700
|
|
|
670
701
|
# LSC
|
|
671
|
-
gb_lsc = QGroupBox("Luminance, Chroma/Saturation, Contrast")
|
|
702
|
+
gb_lsc = QGroupBox(self.tr("Luminance, Chroma/Saturation, Contrast"))
|
|
672
703
|
gll = QGridLayout(gb_lsc)
|
|
673
704
|
self.sl_l, self.ds_l = self._slider_pair(gll, "Luminance:", 0)
|
|
674
705
|
self.sl_chroma, self.ds_chroma = self._slider_pair(gll, "Chroma (L-preserving):", 1)
|
|
@@ -741,10 +772,12 @@ class SelectiveColorCorrection(QDialog):
|
|
|
741
772
|
right.addLayout(zoom_row)
|
|
742
773
|
|
|
743
774
|
self.lbl_help = QLabel(
|
|
744
|
-
"🖱️ <b>Click</b>:
|
|
775
|
+
"🖱️ <b>Click</b>: show hue • "
|
|
776
|
+
"<b>Shift + Click</b>: select that color • "
|
|
745
777
|
"<b>Ctrl + Click & Drag</b>: pan • "
|
|
746
778
|
"<b>Ctrl + Wheel</b>: zoom"
|
|
747
779
|
)
|
|
780
|
+
|
|
748
781
|
self.lbl_help.setWordWrap(True)
|
|
749
782
|
self.lbl_help.setTextFormat(Qt.TextFormat.RichText)
|
|
750
783
|
self.lbl_help.setStyleSheet("color: #888; font-size: 11px;")
|
|
@@ -797,12 +830,20 @@ class SelectiveColorCorrection(QDialog):
|
|
|
797
830
|
w.valueChanged.connect(self._schedule_adjustments)
|
|
798
831
|
|
|
799
832
|
def _sliders_to_wheel(_=None):
|
|
833
|
+
if getattr(self, "_syncing_hue", False):
|
|
834
|
+
return
|
|
835
|
+
|
|
800
836
|
if not self._setting_preset and self.dd_preset.currentText() != "Custom":
|
|
837
|
+
self.dd_preset.blockSignals(True)
|
|
801
838
|
self.dd_preset.setCurrentText("Custom")
|
|
802
|
-
|
|
839
|
+
self.dd_preset.blockSignals(False)
|
|
840
|
+
|
|
841
|
+
s = int(self.sp_h1.value())
|
|
842
|
+
e = int(self.sp_h2.value())
|
|
803
843
|
self.hue_wheel.setRange(s, e, notify=False)
|
|
804
844
|
self._schedule_mask()
|
|
805
845
|
|
|
846
|
+
|
|
806
847
|
self.sp_h1.valueChanged.connect(_sliders_to_wheel)
|
|
807
848
|
self.sp_h2.valueChanged.connect(_sliders_to_wheel)
|
|
808
849
|
self.sl_h1.valueChanged.connect(_sliders_to_wheel)
|
|
@@ -973,7 +1014,7 @@ class SelectiveColorCorrection(QDialog):
|
|
|
973
1014
|
w.setValue(int(val))
|
|
974
1015
|
w.blockSignals(False)
|
|
975
1016
|
|
|
976
|
-
setv(self.ds_minC, 0.
|
|
1017
|
+
setv(self.ds_minC, 0.05)
|
|
977
1018
|
setv(self.ds_minL, 0.0)
|
|
978
1019
|
setv(self.ds_maxL, 1.0)
|
|
979
1020
|
setv(self.ds_smooth, 10.0)
|
|
@@ -1018,23 +1059,27 @@ class SelectiveColorCorrection(QDialog):
|
|
|
1018
1059
|
self._recompute_mask_and_preview()
|
|
1019
1060
|
|
|
1020
1061
|
|
|
1021
|
-
def _schedule_adjustments(self, delay_ms: int | None = None):
|
|
1062
|
+
def _schedule_adjustments(self, *_, delay_ms: int | None = None):
|
|
1022
1063
|
if delay_ms is None:
|
|
1023
1064
|
delay_ms = getattr(self, "_adj_delay_ms", 200)
|
|
1024
|
-
|
|
1065
|
+
|
|
1025
1066
|
if not hasattr(self, "_adj_timer"):
|
|
1026
1067
|
return
|
|
1027
|
-
self._adj_timer.stop()
|
|
1028
|
-
self._adj_timer.start(int(delay_ms))
|
|
1029
1068
|
|
|
1069
|
+
ms = max(1, int(delay_ms)) # never allow 0/negative
|
|
1070
|
+
self._adj_timer.stop()
|
|
1071
|
+
self._adj_timer.start(ms)
|
|
1030
1072
|
|
|
1031
|
-
def _schedule_mask(self, delay_ms: int | None = None):
|
|
1032
|
-
"""Debounce mask recomputation for hue changes."""
|
|
1073
|
+
def _schedule_mask(self, *_, delay_ms: int | None = None):
|
|
1033
1074
|
if delay_ms is None:
|
|
1034
|
-
delay_ms = self
|
|
1035
|
-
|
|
1075
|
+
delay_ms = getattr(self, "_mask_delay_ms", 200)
|
|
1076
|
+
|
|
1077
|
+
if not hasattr(self, "_mask_timer"):
|
|
1078
|
+
return
|
|
1079
|
+
|
|
1080
|
+
ms = max(1, int(delay_ms))
|
|
1036
1081
|
self._mask_timer.stop()
|
|
1037
|
-
self._mask_timer.start(
|
|
1082
|
+
self._mask_timer.start(ms)
|
|
1038
1083
|
|
|
1039
1084
|
|
|
1040
1085
|
def _sample_hue_deg_from_base(self, x: int, y: int) -> float | None:
|
|
@@ -1190,16 +1235,30 @@ class SelectiveColorCorrection(QDialog):
|
|
|
1190
1235
|
intervals = _PRESETS.get(txt, [])
|
|
1191
1236
|
if intervals:
|
|
1192
1237
|
lo, hi = (intervals[0][0], intervals[-1][1]) if len(intervals) > 1 else intervals[0]
|
|
1193
|
-
|
|
1194
|
-
|
|
1195
|
-
self.
|
|
1196
|
-
|
|
1197
|
-
|
|
1238
|
+
|
|
1239
|
+
# --- NEW: keep wheel + sliders + spins all in sync ---
|
|
1240
|
+
self._syncing_hue = True
|
|
1241
|
+
try:
|
|
1242
|
+
# update wheel silently
|
|
1243
|
+
self.hue_wheel.setRange(int(lo), int(hi), notify=False)
|
|
1244
|
+
|
|
1245
|
+
# update both sliders and spins (no ping-pong)
|
|
1246
|
+
for w, val in (
|
|
1247
|
+
(self.sl_h1, int(lo)), (self.sp_h1, int(lo)),
|
|
1248
|
+
(self.sl_h2, int(hi)), (self.sp_h2, int(hi)),
|
|
1249
|
+
):
|
|
1250
|
+
w.blockSignals(True)
|
|
1251
|
+
w.setValue(val)
|
|
1252
|
+
w.blockSignals(False)
|
|
1253
|
+
|
|
1254
|
+
self.hue_wheel.update() # ensure repaint
|
|
1255
|
+
finally:
|
|
1256
|
+
self._syncing_hue = False
|
|
1257
|
+
|
|
1198
1258
|
self._recompute_mask_and_preview()
|
|
1199
1259
|
finally:
|
|
1200
1260
|
self._setting_preset = False
|
|
1201
1261
|
|
|
1202
|
-
|
|
1203
1262
|
def _downsample(self, img, max_dim=1024):
|
|
1204
1263
|
h, w = img.shape[:2]
|
|
1205
1264
|
s = max(h, w)
|