setiastrosuitepro 1.6.0__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/__init__.py +2 -0
- setiastro/saspro/__init__.py +20 -0
- setiastro/saspro/__main__.py +784 -0
- setiastro/saspro/_generated/__init__.py +7 -0
- setiastro/saspro/_generated/build_info.py +2 -0
- setiastro/saspro/abe.py +1295 -0
- setiastro/saspro/abe_preset.py +196 -0
- setiastro/saspro/aberration_ai.py +694 -0
- setiastro/saspro/aberration_ai_preset.py +224 -0
- setiastro/saspro/accel_installer.py +218 -0
- setiastro/saspro/accel_workers.py +30 -0
- setiastro/saspro/add_stars.py +621 -0
- setiastro/saspro/astrobin_exporter.py +1007 -0
- setiastro/saspro/astrospike.py +153 -0
- setiastro/saspro/astrospike_python.py +1839 -0
- setiastro/saspro/autostretch.py +196 -0
- setiastro/saspro/backgroundneutral.py +560 -0
- setiastro/saspro/batch_convert.py +325 -0
- setiastro/saspro/batch_renamer.py +519 -0
- setiastro/saspro/blemish_blaster.py +488 -0
- setiastro/saspro/blink_comparator_pro.py +2923 -0
- setiastro/saspro/bundles.py +61 -0
- setiastro/saspro/bundles_dock.py +114 -0
- setiastro/saspro/cheat_sheet.py +168 -0
- setiastro/saspro/clahe.py +342 -0
- setiastro/saspro/comet_stacking.py +1377 -0
- setiastro/saspro/config.py +38 -0
- setiastro/saspro/config_bootstrap.py +40 -0
- setiastro/saspro/config_manager.py +316 -0
- setiastro/saspro/continuum_subtract.py +1617 -0
- setiastro/saspro/convo.py +1397 -0
- setiastro/saspro/convo_preset.py +414 -0
- setiastro/saspro/copyastro.py +187 -0
- setiastro/saspro/cosmicclarity.py +1564 -0
- setiastro/saspro/cosmicclarity_preset.py +407 -0
- setiastro/saspro/crop_dialog_pro.py +948 -0
- setiastro/saspro/crop_preset.py +189 -0
- setiastro/saspro/curve_editor_pro.py +2544 -0
- setiastro/saspro/curves_preset.py +375 -0
- setiastro/saspro/debayer.py +670 -0
- setiastro/saspro/debug_utils.py +29 -0
- setiastro/saspro/dnd_mime.py +35 -0
- setiastro/saspro/doc_manager.py +2634 -0
- setiastro/saspro/exoplanet_detector.py +2166 -0
- setiastro/saspro/file_utils.py +284 -0
- setiastro/saspro/fitsmodifier.py +744 -0
- setiastro/saspro/free_torch_memory.py +48 -0
- setiastro/saspro/frequency_separation.py +1343 -0
- setiastro/saspro/function_bundle.py +1594 -0
- setiastro/saspro/ghs_dialog_pro.py +660 -0
- setiastro/saspro/ghs_preset.py +284 -0
- setiastro/saspro/graxpert.py +634 -0
- setiastro/saspro/graxpert_preset.py +287 -0
- setiastro/saspro/gui/__init__.py +0 -0
- setiastro/saspro/gui/main_window.py +8494 -0
- setiastro/saspro/gui/mixins/__init__.py +33 -0
- setiastro/saspro/gui/mixins/dock_mixin.py +263 -0
- setiastro/saspro/gui/mixins/file_mixin.py +445 -0
- setiastro/saspro/gui/mixins/geometry_mixin.py +403 -0
- setiastro/saspro/gui/mixins/header_mixin.py +441 -0
- setiastro/saspro/gui/mixins/mask_mixin.py +421 -0
- setiastro/saspro/gui/mixins/menu_mixin.py +361 -0
- setiastro/saspro/gui/mixins/theme_mixin.py +367 -0
- setiastro/saspro/gui/mixins/toolbar_mixin.py +1324 -0
- setiastro/saspro/gui/mixins/update_mixin.py +309 -0
- setiastro/saspro/gui/mixins/view_mixin.py +435 -0
- setiastro/saspro/halobgon.py +462 -0
- setiastro/saspro/header_viewer.py +445 -0
- setiastro/saspro/headless_utils.py +88 -0
- setiastro/saspro/histogram.py +753 -0
- setiastro/saspro/history_explorer.py +939 -0
- setiastro/saspro/image_combine.py +414 -0
- setiastro/saspro/image_peeker_pro.py +1596 -0
- setiastro/saspro/imageops/__init__.py +37 -0
- setiastro/saspro/imageops/mdi_snap.py +292 -0
- setiastro/saspro/imageops/scnr.py +36 -0
- setiastro/saspro/imageops/starbasedwhitebalance.py +210 -0
- setiastro/saspro/imageops/stretch.py +244 -0
- setiastro/saspro/isophote.py +1179 -0
- setiastro/saspro/layers.py +208 -0
- setiastro/saspro/layers_dock.py +714 -0
- setiastro/saspro/lazy_imports.py +193 -0
- setiastro/saspro/legacy/__init__.py +2 -0
- setiastro/saspro/legacy/image_manager.py +2226 -0
- setiastro/saspro/legacy/numba_utils.py +3659 -0
- setiastro/saspro/legacy/xisf.py +1071 -0
- setiastro/saspro/linear_fit.py +534 -0
- setiastro/saspro/live_stacking.py +1830 -0
- setiastro/saspro/log_bus.py +5 -0
- setiastro/saspro/logging_config.py +460 -0
- setiastro/saspro/luminancerecombine.py +309 -0
- setiastro/saspro/main_helpers.py +201 -0
- setiastro/saspro/mask_creation.py +928 -0
- setiastro/saspro/masks_core.py +56 -0
- setiastro/saspro/mdi_widgets.py +353 -0
- setiastro/saspro/memory_utils.py +666 -0
- setiastro/saspro/metadata_patcher.py +75 -0
- setiastro/saspro/mfdeconv.py +3826 -0
- setiastro/saspro/mfdeconv_earlystop.py +71 -0
- setiastro/saspro/mfdeconvcudnn.py +3263 -0
- setiastro/saspro/mfdeconvsport.py +2382 -0
- setiastro/saspro/minorbodycatalog.py +567 -0
- setiastro/saspro/morphology.py +382 -0
- setiastro/saspro/multiscale_decomp.py +1290 -0
- setiastro/saspro/nbtorgb_stars.py +531 -0
- setiastro/saspro/numba_utils.py +3044 -0
- setiastro/saspro/numba_warmup.py +141 -0
- setiastro/saspro/ops/__init__.py +9 -0
- setiastro/saspro/ops/command_help_dialog.py +623 -0
- setiastro/saspro/ops/command_runner.py +217 -0
- setiastro/saspro/ops/commands.py +1594 -0
- setiastro/saspro/ops/script_editor.py +1102 -0
- setiastro/saspro/ops/scripts.py +1413 -0
- setiastro/saspro/ops/settings.py +560 -0
- setiastro/saspro/parallel_utils.py +554 -0
- setiastro/saspro/pedestal.py +121 -0
- setiastro/saspro/perfect_palette_picker.py +1053 -0
- setiastro/saspro/pipeline.py +110 -0
- setiastro/saspro/pixelmath.py +1600 -0
- setiastro/saspro/plate_solver.py +2435 -0
- setiastro/saspro/project_io.py +797 -0
- setiastro/saspro/psf_utils.py +136 -0
- setiastro/saspro/psf_viewer.py +549 -0
- setiastro/saspro/pyi_rthook_astroquery.py +95 -0
- setiastro/saspro/remove_green.py +314 -0
- setiastro/saspro/remove_stars.py +1625 -0
- setiastro/saspro/remove_stars_preset.py +404 -0
- setiastro/saspro/resources.py +472 -0
- setiastro/saspro/rgb_combination.py +207 -0
- setiastro/saspro/rgb_extract.py +19 -0
- setiastro/saspro/rgbalign.py +723 -0
- setiastro/saspro/runtime_imports.py +7 -0
- setiastro/saspro/runtime_torch.py +754 -0
- setiastro/saspro/save_options.py +72 -0
- setiastro/saspro/selective_color.py +1552 -0
- setiastro/saspro/sfcc.py +1425 -0
- setiastro/saspro/shortcuts.py +2807 -0
- setiastro/saspro/signature_insert.py +1099 -0
- setiastro/saspro/stacking_suite.py +17712 -0
- setiastro/saspro/star_alignment.py +7420 -0
- setiastro/saspro/star_alignment_preset.py +329 -0
- setiastro/saspro/star_metrics.py +49 -0
- setiastro/saspro/star_spikes.py +681 -0
- setiastro/saspro/star_stretch.py +470 -0
- setiastro/saspro/stat_stretch.py +502 -0
- setiastro/saspro/status_log_dock.py +78 -0
- setiastro/saspro/subwindow.py +3267 -0
- setiastro/saspro/supernovaasteroidhunter.py +1712 -0
- setiastro/saspro/swap_manager.py +99 -0
- setiastro/saspro/torch_backend.py +89 -0
- setiastro/saspro/torch_rejection.py +434 -0
- setiastro/saspro/view_bundle.py +1555 -0
- setiastro/saspro/wavescale_hdr.py +624 -0
- setiastro/saspro/wavescale_hdr_preset.py +100 -0
- setiastro/saspro/wavescalede.py +657 -0
- setiastro/saspro/wavescalede_preset.py +228 -0
- setiastro/saspro/wcs_update.py +374 -0
- setiastro/saspro/whitebalance.py +456 -0
- setiastro/saspro/widgets/__init__.py +48 -0
- setiastro/saspro/widgets/common_utilities.py +305 -0
- setiastro/saspro/widgets/graphics_views.py +122 -0
- setiastro/saspro/widgets/image_utils.py +518 -0
- setiastro/saspro/widgets/preview_dialogs.py +280 -0
- setiastro/saspro/widgets/spinboxes.py +275 -0
- setiastro/saspro/widgets/themed_buttons.py +13 -0
- setiastro/saspro/widgets/wavelet_utils.py +299 -0
- setiastro/saspro/window_shelf.py +185 -0
- setiastro/saspro/xisf.py +1123 -0
- setiastrosuitepro-1.6.0.dist-info/METADATA +266 -0
- setiastrosuitepro-1.6.0.dist-info/RECORD +174 -0
- setiastrosuitepro-1.6.0.dist-info/WHEEL +4 -0
- setiastrosuitepro-1.6.0.dist-info/entry_points.txt +6 -0
- setiastrosuitepro-1.6.0.dist-info/licenses/LICENSE +674 -0
- setiastrosuitepro-1.6.0.dist-info/licenses/license.txt +2580 -0
|
@@ -0,0 +1,217 @@
|
|
|
1
|
+
# ops/command_runner.py
|
|
2
|
+
from __future__ import annotations
|
|
3
|
+
from typing import Any, Dict, Optional, Callable
|
|
4
|
+
import inspect
|
|
5
|
+
|
|
6
|
+
from setiastro.saspro.ops.commands import get_spec, normalize_cid, CommandSpec
|
|
7
|
+
|
|
8
|
+
class CommandError(RuntimeError):
|
|
9
|
+
pass
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _merge_defaults(spec: CommandSpec, preset: Dict[str, Any]) -> Dict[str, Any]:
|
|
13
|
+
out = dict(preset or {})
|
|
14
|
+
for ps in spec.presets:
|
|
15
|
+
if ps.key not in out and ps.default is not None:
|
|
16
|
+
out[ps.key] = ps.default
|
|
17
|
+
return out
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def _validate_preset(spec: CommandSpec, preset: Dict[str, Any]) -> None:
|
|
21
|
+
# light validation only; don't be annoying for scripts
|
|
22
|
+
for ps in spec.presets:
|
|
23
|
+
if (not ps.optional) and (ps.key not in preset):
|
|
24
|
+
raise CommandError(f"{spec.id}: missing required preset key '{ps.key}'")
|
|
25
|
+
|
|
26
|
+
if ps.key not in preset:
|
|
27
|
+
continue
|
|
28
|
+
|
|
29
|
+
v = preset[ps.key]
|
|
30
|
+
t = ps.type
|
|
31
|
+
|
|
32
|
+
try:
|
|
33
|
+
if t == "float":
|
|
34
|
+
preset[ps.key] = float(v)
|
|
35
|
+
elif t == "int":
|
|
36
|
+
preset[ps.key] = int(v)
|
|
37
|
+
elif t == "bool":
|
|
38
|
+
preset[ps.key] = bool(v)
|
|
39
|
+
elif t == "str":
|
|
40
|
+
preset[ps.key] = str(v)
|
|
41
|
+
elif t == "enum":
|
|
42
|
+
sv = str(v).lower()
|
|
43
|
+
if ps.enum and sv not in [e.lower() for e in ps.enum]:
|
|
44
|
+
raise CommandError(f"{spec.id}: '{ps.key}' must be one of {ps.enum}, got {v}")
|
|
45
|
+
preset[ps.key] = v
|
|
46
|
+
except CommandError:
|
|
47
|
+
raise
|
|
48
|
+
except Exception:
|
|
49
|
+
raise CommandError(f"{spec.id}: bad value for '{ps.key}': {v!r}")
|
|
50
|
+
|
|
51
|
+
# numeric limits
|
|
52
|
+
if ps.type in ("float", "int"):
|
|
53
|
+
fv = float(preset[ps.key])
|
|
54
|
+
if ps.min is not None and fv < ps.min:
|
|
55
|
+
raise CommandError(f"{spec.id}: '{ps.key}' < min {ps.min}")
|
|
56
|
+
if ps.max is not None and fv > ps.max:
|
|
57
|
+
raise CommandError(f"{spec.id}: '{ps.key}' > max {ps.max}")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _resolve_target_doc(ctx, target_doc=None, on_base: bool=False):
|
|
61
|
+
"""
|
|
62
|
+
Resolve a doc for scripts:
|
|
63
|
+
- if target_doc passed: use it
|
|
64
|
+
- else prefer DocManager active doc (ROI-aware)
|
|
65
|
+
- else use ctx.active_document()
|
|
66
|
+
- if on_base True, swap to focused base doc when possible
|
|
67
|
+
"""
|
|
68
|
+
doc = target_doc
|
|
69
|
+
|
|
70
|
+
if doc is None:
|
|
71
|
+
# ✅ Prefer DocManager (it knows about ROI, LiveViewDocument, etc.)
|
|
72
|
+
app = getattr(ctx, "app", None)
|
|
73
|
+
dm = getattr(app, "doc_manager", None) if app is not None else None
|
|
74
|
+
if dm is not None:
|
|
75
|
+
try:
|
|
76
|
+
doc = dm.get_active_document()
|
|
77
|
+
except Exception:
|
|
78
|
+
doc = None
|
|
79
|
+
|
|
80
|
+
if doc is None:
|
|
81
|
+
try:
|
|
82
|
+
doc = ctx.active_document()
|
|
83
|
+
except Exception:
|
|
84
|
+
doc = None
|
|
85
|
+
|
|
86
|
+
if doc is None:
|
|
87
|
+
raise CommandError("No active document to run command on.")
|
|
88
|
+
|
|
89
|
+
if on_base:
|
|
90
|
+
app = getattr(ctx, "app", None)
|
|
91
|
+
dm = getattr(app, "doc_manager", None) if app is not None else None
|
|
92
|
+
if dm is not None:
|
|
93
|
+
try:
|
|
94
|
+
base = dm.get_focused_base_document()
|
|
95
|
+
if base is not None:
|
|
96
|
+
doc = base
|
|
97
|
+
except Exception:
|
|
98
|
+
pass
|
|
99
|
+
else:
|
|
100
|
+
# fallback to view.base_document if it exists
|
|
101
|
+
try:
|
|
102
|
+
view = ctx.active_view()
|
|
103
|
+
base_doc = getattr(view, "base_document", None)
|
|
104
|
+
if base_doc is not None:
|
|
105
|
+
doc = base_doc
|
|
106
|
+
except Exception:
|
|
107
|
+
pass
|
|
108
|
+
|
|
109
|
+
return doc
|
|
110
|
+
|
|
111
|
+
|
|
112
|
+
def _load_callable(spec: CommandSpec, app_window=None) -> Callable:
|
|
113
|
+
"""
|
|
114
|
+
Find the executor for this command. Priority:
|
|
115
|
+
1) spec.callable_name + import_path
|
|
116
|
+
2) spec.headless_method on app_window
|
|
117
|
+
"""
|
|
118
|
+
if spec.import_path and spec.callable_name:
|
|
119
|
+
mod = __import__(spec.import_path, fromlist=[spec.callable_name])
|
|
120
|
+
fn = getattr(mod, spec.callable_name, None)
|
|
121
|
+
if callable(fn):
|
|
122
|
+
return fn
|
|
123
|
+
raise CommandError(f"{spec.id}: callable '{spec.callable_name}' not found in {spec.import_path}")
|
|
124
|
+
|
|
125
|
+
if app_window and spec.headless_method:
|
|
126
|
+
fn = getattr(app_window, spec.headless_method, None)
|
|
127
|
+
if callable(fn):
|
|
128
|
+
return fn
|
|
129
|
+
raise CommandError(f"{spec.id}: app has no headless method '{spec.headless_method}'")
|
|
130
|
+
|
|
131
|
+
raise CommandError(f"{spec.id}: no executor defined in CommandSpec")
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
def run_command(ctx, command_id: str, preset: Optional[Dict[str, Any]] = None,
|
|
135
|
+
*, target_doc=None, on_base: bool=False, open_ui: bool=False):
|
|
136
|
+
"""
|
|
137
|
+
Script entry point:
|
|
138
|
+
- Normalizes CID
|
|
139
|
+
- merges defaults
|
|
140
|
+
- validates preset
|
|
141
|
+
- resolves target doc
|
|
142
|
+
- runs headless executor
|
|
143
|
+
"""
|
|
144
|
+
cid = normalize_cid(command_id)
|
|
145
|
+
spec = get_spec(cid)
|
|
146
|
+
if spec is None:
|
|
147
|
+
raise CommandError(f"Unknown command_id '{command_id}' (normalized='{cid}')")
|
|
148
|
+
|
|
149
|
+
preset = _merge_defaults(spec, dict(preset or {}))
|
|
150
|
+
_validate_preset(spec, preset)
|
|
151
|
+
|
|
152
|
+
# if scripts want UI, allow only if spec has ui_method
|
|
153
|
+
if open_ui:
|
|
154
|
+
if not spec.ui_method:
|
|
155
|
+
raise CommandError(f"{spec.id}: has no UI opener")
|
|
156
|
+
app = getattr(ctx, "app", None)
|
|
157
|
+
m = getattr(app, spec.ui_method, None)
|
|
158
|
+
if not callable(m):
|
|
159
|
+
raise CommandError(f"{spec.id}: UI method '{spec.ui_method}' not found on app")
|
|
160
|
+
return m(preset) if preset else m()
|
|
161
|
+
|
|
162
|
+
doc = _resolve_target_doc(ctx, target_doc=target_doc, on_base=on_base)
|
|
163
|
+
app = getattr(ctx, "app", None)
|
|
164
|
+
|
|
165
|
+
fn = _load_callable(spec, app_window=app)
|
|
166
|
+
|
|
167
|
+
|
|
168
|
+
try:
|
|
169
|
+
sig = inspect.signature(fn)
|
|
170
|
+
kwargs = {}
|
|
171
|
+
|
|
172
|
+
for name, p in sig.parameters.items():
|
|
173
|
+
lname = name.lower()
|
|
174
|
+
|
|
175
|
+
# ignore *args/**kwargs params
|
|
176
|
+
if p.kind in (inspect.Parameter.VAR_POSITIONAL, inspect.Parameter.VAR_KEYWORD):
|
|
177
|
+
continue
|
|
178
|
+
|
|
179
|
+
# ctx / context
|
|
180
|
+
if "ctx" in lname or "context" in lname:
|
|
181
|
+
kwargs[name] = ctx
|
|
182
|
+
continue
|
|
183
|
+
|
|
184
|
+
# app / main window
|
|
185
|
+
if lname in ("app", "main", "mw", "window", "app_window") or "main_window" in lname:
|
|
186
|
+
kwargs[name] = app
|
|
187
|
+
continue
|
|
188
|
+
|
|
189
|
+
# doc / target_doc
|
|
190
|
+
if lname in ("doc", "document", "target", "target_doc", "active_doc") or "document" in lname:
|
|
191
|
+
kwargs[name] = doc
|
|
192
|
+
continue
|
|
193
|
+
|
|
194
|
+
# preset / params
|
|
195
|
+
if lname in ("preset", "params", "options", "settings"):
|
|
196
|
+
kwargs[name] = preset
|
|
197
|
+
continue
|
|
198
|
+
|
|
199
|
+
# ✅ First try pure kwargs (best match for your headless via_preset funcs)
|
|
200
|
+
try:
|
|
201
|
+
return fn(**kwargs)
|
|
202
|
+
except TypeError:
|
|
203
|
+
# ---------- safe fallbacks ----------
|
|
204
|
+
# common module-level patterns
|
|
205
|
+
try:
|
|
206
|
+
return fn(app, doc, preset)
|
|
207
|
+
except TypeError:
|
|
208
|
+
try:
|
|
209
|
+
return fn(doc, preset)
|
|
210
|
+
except TypeError:
|
|
211
|
+
try:
|
|
212
|
+
return fn(doc)
|
|
213
|
+
except TypeError:
|
|
214
|
+
return fn(preset)
|
|
215
|
+
|
|
216
|
+
except Exception as e:
|
|
217
|
+
raise CommandError(f"{spec.id}: executor failed: {e}") from e
|