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.

Files changed (174) hide show
  1. setiastro/__init__.py +2 -0
  2. setiastro/saspro/__init__.py +20 -0
  3. setiastro/saspro/__main__.py +784 -0
  4. setiastro/saspro/_generated/__init__.py +7 -0
  5. setiastro/saspro/_generated/build_info.py +2 -0
  6. setiastro/saspro/abe.py +1295 -0
  7. setiastro/saspro/abe_preset.py +196 -0
  8. setiastro/saspro/aberration_ai.py +694 -0
  9. setiastro/saspro/aberration_ai_preset.py +224 -0
  10. setiastro/saspro/accel_installer.py +218 -0
  11. setiastro/saspro/accel_workers.py +30 -0
  12. setiastro/saspro/add_stars.py +621 -0
  13. setiastro/saspro/astrobin_exporter.py +1007 -0
  14. setiastro/saspro/astrospike.py +153 -0
  15. setiastro/saspro/astrospike_python.py +1839 -0
  16. setiastro/saspro/autostretch.py +196 -0
  17. setiastro/saspro/backgroundneutral.py +560 -0
  18. setiastro/saspro/batch_convert.py +325 -0
  19. setiastro/saspro/batch_renamer.py +519 -0
  20. setiastro/saspro/blemish_blaster.py +488 -0
  21. setiastro/saspro/blink_comparator_pro.py +2923 -0
  22. setiastro/saspro/bundles.py +61 -0
  23. setiastro/saspro/bundles_dock.py +114 -0
  24. setiastro/saspro/cheat_sheet.py +168 -0
  25. setiastro/saspro/clahe.py +342 -0
  26. setiastro/saspro/comet_stacking.py +1377 -0
  27. setiastro/saspro/config.py +38 -0
  28. setiastro/saspro/config_bootstrap.py +40 -0
  29. setiastro/saspro/config_manager.py +316 -0
  30. setiastro/saspro/continuum_subtract.py +1617 -0
  31. setiastro/saspro/convo.py +1397 -0
  32. setiastro/saspro/convo_preset.py +414 -0
  33. setiastro/saspro/copyastro.py +187 -0
  34. setiastro/saspro/cosmicclarity.py +1564 -0
  35. setiastro/saspro/cosmicclarity_preset.py +407 -0
  36. setiastro/saspro/crop_dialog_pro.py +948 -0
  37. setiastro/saspro/crop_preset.py +189 -0
  38. setiastro/saspro/curve_editor_pro.py +2544 -0
  39. setiastro/saspro/curves_preset.py +375 -0
  40. setiastro/saspro/debayer.py +670 -0
  41. setiastro/saspro/debug_utils.py +29 -0
  42. setiastro/saspro/dnd_mime.py +35 -0
  43. setiastro/saspro/doc_manager.py +2634 -0
  44. setiastro/saspro/exoplanet_detector.py +2166 -0
  45. setiastro/saspro/file_utils.py +284 -0
  46. setiastro/saspro/fitsmodifier.py +744 -0
  47. setiastro/saspro/free_torch_memory.py +48 -0
  48. setiastro/saspro/frequency_separation.py +1343 -0
  49. setiastro/saspro/function_bundle.py +1594 -0
  50. setiastro/saspro/ghs_dialog_pro.py +660 -0
  51. setiastro/saspro/ghs_preset.py +284 -0
  52. setiastro/saspro/graxpert.py +634 -0
  53. setiastro/saspro/graxpert_preset.py +287 -0
  54. setiastro/saspro/gui/__init__.py +0 -0
  55. setiastro/saspro/gui/main_window.py +8494 -0
  56. setiastro/saspro/gui/mixins/__init__.py +33 -0
  57. setiastro/saspro/gui/mixins/dock_mixin.py +263 -0
  58. setiastro/saspro/gui/mixins/file_mixin.py +445 -0
  59. setiastro/saspro/gui/mixins/geometry_mixin.py +403 -0
  60. setiastro/saspro/gui/mixins/header_mixin.py +441 -0
  61. setiastro/saspro/gui/mixins/mask_mixin.py +421 -0
  62. setiastro/saspro/gui/mixins/menu_mixin.py +361 -0
  63. setiastro/saspro/gui/mixins/theme_mixin.py +367 -0
  64. setiastro/saspro/gui/mixins/toolbar_mixin.py +1324 -0
  65. setiastro/saspro/gui/mixins/update_mixin.py +309 -0
  66. setiastro/saspro/gui/mixins/view_mixin.py +435 -0
  67. setiastro/saspro/halobgon.py +462 -0
  68. setiastro/saspro/header_viewer.py +445 -0
  69. setiastro/saspro/headless_utils.py +88 -0
  70. setiastro/saspro/histogram.py +753 -0
  71. setiastro/saspro/history_explorer.py +939 -0
  72. setiastro/saspro/image_combine.py +414 -0
  73. setiastro/saspro/image_peeker_pro.py +1596 -0
  74. setiastro/saspro/imageops/__init__.py +37 -0
  75. setiastro/saspro/imageops/mdi_snap.py +292 -0
  76. setiastro/saspro/imageops/scnr.py +36 -0
  77. setiastro/saspro/imageops/starbasedwhitebalance.py +210 -0
  78. setiastro/saspro/imageops/stretch.py +244 -0
  79. setiastro/saspro/isophote.py +1179 -0
  80. setiastro/saspro/layers.py +208 -0
  81. setiastro/saspro/layers_dock.py +714 -0
  82. setiastro/saspro/lazy_imports.py +193 -0
  83. setiastro/saspro/legacy/__init__.py +2 -0
  84. setiastro/saspro/legacy/image_manager.py +2226 -0
  85. setiastro/saspro/legacy/numba_utils.py +3659 -0
  86. setiastro/saspro/legacy/xisf.py +1071 -0
  87. setiastro/saspro/linear_fit.py +534 -0
  88. setiastro/saspro/live_stacking.py +1830 -0
  89. setiastro/saspro/log_bus.py +5 -0
  90. setiastro/saspro/logging_config.py +460 -0
  91. setiastro/saspro/luminancerecombine.py +309 -0
  92. setiastro/saspro/main_helpers.py +201 -0
  93. setiastro/saspro/mask_creation.py +928 -0
  94. setiastro/saspro/masks_core.py +56 -0
  95. setiastro/saspro/mdi_widgets.py +353 -0
  96. setiastro/saspro/memory_utils.py +666 -0
  97. setiastro/saspro/metadata_patcher.py +75 -0
  98. setiastro/saspro/mfdeconv.py +3826 -0
  99. setiastro/saspro/mfdeconv_earlystop.py +71 -0
  100. setiastro/saspro/mfdeconvcudnn.py +3263 -0
  101. setiastro/saspro/mfdeconvsport.py +2382 -0
  102. setiastro/saspro/minorbodycatalog.py +567 -0
  103. setiastro/saspro/morphology.py +382 -0
  104. setiastro/saspro/multiscale_decomp.py +1290 -0
  105. setiastro/saspro/nbtorgb_stars.py +531 -0
  106. setiastro/saspro/numba_utils.py +3044 -0
  107. setiastro/saspro/numba_warmup.py +141 -0
  108. setiastro/saspro/ops/__init__.py +9 -0
  109. setiastro/saspro/ops/command_help_dialog.py +623 -0
  110. setiastro/saspro/ops/command_runner.py +217 -0
  111. setiastro/saspro/ops/commands.py +1594 -0
  112. setiastro/saspro/ops/script_editor.py +1102 -0
  113. setiastro/saspro/ops/scripts.py +1413 -0
  114. setiastro/saspro/ops/settings.py +560 -0
  115. setiastro/saspro/parallel_utils.py +554 -0
  116. setiastro/saspro/pedestal.py +121 -0
  117. setiastro/saspro/perfect_palette_picker.py +1053 -0
  118. setiastro/saspro/pipeline.py +110 -0
  119. setiastro/saspro/pixelmath.py +1600 -0
  120. setiastro/saspro/plate_solver.py +2435 -0
  121. setiastro/saspro/project_io.py +797 -0
  122. setiastro/saspro/psf_utils.py +136 -0
  123. setiastro/saspro/psf_viewer.py +549 -0
  124. setiastro/saspro/pyi_rthook_astroquery.py +95 -0
  125. setiastro/saspro/remove_green.py +314 -0
  126. setiastro/saspro/remove_stars.py +1625 -0
  127. setiastro/saspro/remove_stars_preset.py +404 -0
  128. setiastro/saspro/resources.py +472 -0
  129. setiastro/saspro/rgb_combination.py +207 -0
  130. setiastro/saspro/rgb_extract.py +19 -0
  131. setiastro/saspro/rgbalign.py +723 -0
  132. setiastro/saspro/runtime_imports.py +7 -0
  133. setiastro/saspro/runtime_torch.py +754 -0
  134. setiastro/saspro/save_options.py +72 -0
  135. setiastro/saspro/selective_color.py +1552 -0
  136. setiastro/saspro/sfcc.py +1425 -0
  137. setiastro/saspro/shortcuts.py +2807 -0
  138. setiastro/saspro/signature_insert.py +1099 -0
  139. setiastro/saspro/stacking_suite.py +17712 -0
  140. setiastro/saspro/star_alignment.py +7420 -0
  141. setiastro/saspro/star_alignment_preset.py +329 -0
  142. setiastro/saspro/star_metrics.py +49 -0
  143. setiastro/saspro/star_spikes.py +681 -0
  144. setiastro/saspro/star_stretch.py +470 -0
  145. setiastro/saspro/stat_stretch.py +502 -0
  146. setiastro/saspro/status_log_dock.py +78 -0
  147. setiastro/saspro/subwindow.py +3267 -0
  148. setiastro/saspro/supernovaasteroidhunter.py +1712 -0
  149. setiastro/saspro/swap_manager.py +99 -0
  150. setiastro/saspro/torch_backend.py +89 -0
  151. setiastro/saspro/torch_rejection.py +434 -0
  152. setiastro/saspro/view_bundle.py +1555 -0
  153. setiastro/saspro/wavescale_hdr.py +624 -0
  154. setiastro/saspro/wavescale_hdr_preset.py +100 -0
  155. setiastro/saspro/wavescalede.py +657 -0
  156. setiastro/saspro/wavescalede_preset.py +228 -0
  157. setiastro/saspro/wcs_update.py +374 -0
  158. setiastro/saspro/whitebalance.py +456 -0
  159. setiastro/saspro/widgets/__init__.py +48 -0
  160. setiastro/saspro/widgets/common_utilities.py +305 -0
  161. setiastro/saspro/widgets/graphics_views.py +122 -0
  162. setiastro/saspro/widgets/image_utils.py +518 -0
  163. setiastro/saspro/widgets/preview_dialogs.py +280 -0
  164. setiastro/saspro/widgets/spinboxes.py +275 -0
  165. setiastro/saspro/widgets/themed_buttons.py +13 -0
  166. setiastro/saspro/widgets/wavelet_utils.py +299 -0
  167. setiastro/saspro/window_shelf.py +185 -0
  168. setiastro/saspro/xisf.py +1123 -0
  169. setiastrosuitepro-1.6.0.dist-info/METADATA +266 -0
  170. setiastrosuitepro-1.6.0.dist-info/RECORD +174 -0
  171. setiastrosuitepro-1.6.0.dist-info/WHEEL +4 -0
  172. setiastrosuitepro-1.6.0.dist-info/entry_points.txt +6 -0
  173. setiastrosuitepro-1.6.0.dist-info/licenses/LICENSE +674 -0
  174. setiastrosuitepro-1.6.0.dist-info/licenses/license.txt +2580 -0
@@ -0,0 +1,196 @@
1
+ # pro/abe_preset.py
2
+ from __future__ import annotations
3
+ import os
4
+ import numpy as np
5
+
6
+ from .abe import abe_run # core engine
7
+
8
+ # ---------- mask helpers (match ABEDialog semantics) ----------
9
+ def _active_mask_layer(doc):
10
+ mid = getattr(doc, "active_mask_id", None)
11
+ if not mid: return None, None, None
12
+ layer = getattr(doc, "masks", {}).get(mid)
13
+ if layer is None: return None, None, None
14
+ m = np.asarray(getattr(layer, "data", None))
15
+ if m is None or m.size == 0: return None, None, None
16
+ m = m.astype(np.float32, copy=False)
17
+ if m.dtype.kind in "ui":
18
+ m /= float(np.iinfo(m.dtype).max)
19
+ else:
20
+ mx = float(m.max()) if m.size else 1.0
21
+ if mx > 1.0: m /= mx
22
+ return np.clip(m, 0.0, 1.0), mid, getattr(layer, "name", "Mask")
23
+
24
+ def _resample_mask(mask: np.ndarray, out_hw: tuple[int,int]) -> np.ndarray:
25
+ mh, mw = mask.shape[:2]
26
+ th, tw = out_hw
27
+ if (mh, mw) == (th, tw): return mask
28
+ yi = np.linspace(0, mh - 1, th).astype(np.int32)
29
+ xi = np.linspace(0, mw - 1, tw).astype(np.int32)
30
+ return mask[yi][:, xi]
31
+
32
+ def _blend_with_mask_float(processed: np.ndarray, src: np.ndarray, doc) -> np.ndarray:
33
+ mask, _mid, _mname = _active_mask_layer(doc)
34
+ if mask is None:
35
+ return processed
36
+ out = processed.astype(np.float32, copy=False)
37
+ s = src.astype(np.float32, copy=False)
38
+
39
+ m = _resample_mask(mask, out.shape[:2])
40
+ # reconcile channels
41
+ if out.ndim == 2 and s.ndim == 3:
42
+ out = out[..., None]
43
+ if s.ndim == 2 and out.ndim == 3:
44
+ s = s[..., None]
45
+ if out.ndim == 3 and out.shape[2] == 3 and m.ndim == 2:
46
+ m = m[..., None]
47
+ blended = (m * out + (1.0 - m) * s).astype(np.float32, copy=False)
48
+ if blended.ndim == 3 and blended.shape[2] == 1:
49
+ blended = blended[..., 0]
50
+ return np.clip(blended, 0.0, 1.0)
51
+
52
+ # ---------- I/O helpers ----------
53
+ def _doc_image_float01(doc) -> np.ndarray | None:
54
+ img = getattr(doc, "image", None)
55
+ if img is None:
56
+ return None
57
+ arr = np.asarray(img)
58
+ if arr.dtype.kind in "ui":
59
+ return (arr.astype(np.float32) / np.iinfo(arr.dtype).max).clip(0.0, 1.0)
60
+ return np.clip(arr.astype(np.float32, copy=False), 0.0, 1.0)
61
+
62
+ # ---------- headless apply (NO EXCLUSION AREA) ----------
63
+ def apply_abe_via_preset(main_window, doc, preset: dict | None = None):
64
+ """
65
+ Run ABE headlessly (no exclusion polygons; exclusion_mask=None) using preset params.
66
+ Blends with the active mask layer (m*out + (1-m)*src) before committing.
67
+ """
68
+ p = dict(preset or {})
69
+ # NOTE: allow degree 0 (RBF-only) to match ABEDialog
70
+ degree = int(np.clip(p.get("degree", 2), 0, 6))
71
+ num_samples = int(np.clip(p.get("samples", 120), 20, 100000))
72
+ downsample = int(np.clip(p.get("downsample", 6), 1, 64))
73
+ patch_size = int(np.clip(p.get("patch", 15), 5, 151))
74
+ use_rbf = bool(p.get("rbf", True))
75
+ rbf_smooth = float(p.get("rbf_smooth", 1.0)) # dialog default = 100 × 0.01 = 1.0
76
+ make_bg_doc = bool(p.get("make_background_doc", False))
77
+
78
+ src01 = _doc_image_float01(doc)
79
+ if src01 is None:
80
+ return
81
+
82
+ # Sanitize params we actually used (this is what we’ll store for Replay)
83
+ params = {
84
+ "degree": degree,
85
+ "samples": num_samples,
86
+ "downsample": downsample,
87
+ "patch": patch_size,
88
+ "rbf": use_rbf,
89
+ "rbf_smooth": rbf_smooth,
90
+ "make_background_doc": make_bg_doc,
91
+ }
92
+
93
+ # 🔁 Remember this as the last headless command for Replay
94
+ try:
95
+ remember = getattr(main_window, "remember_last_headless_command", None)
96
+ if remember is None:
97
+ remember = getattr(main_window, "_remember_last_headless_command", None)
98
+ if callable(remember):
99
+ remember("abe", params, description="Automatic Background Extraction")
100
+ try:
101
+ if hasattr(main_window, "_log"):
102
+ main_window._log(
103
+ f"[Replay] ABE headless stored: command_id='abe', "
104
+ f"preset_keys={list(params.keys())}"
105
+ )
106
+ except Exception:
107
+ pass
108
+ except Exception:
109
+ # Do not block ABE if remembering fails
110
+ pass
111
+
112
+ # 🚫 No exclusion polygons in headless mode
113
+ corrected, bg = abe_run(
114
+ src01,
115
+ degree=degree, num_samples=num_samples, downsample=downsample, patch_size=patch_size,
116
+ use_rbf=use_rbf, rbf_smooth=rbf_smooth,
117
+ exclusion_mask=None, # ← force NO EXCLUSION AREA
118
+ return_background=True,
119
+ progress_cb=None
120
+ )
121
+
122
+ # Preserve mono vs color wrt original doc
123
+ out = corrected
124
+ if (
125
+ out.ndim == 3 and out.shape[2] == 3
126
+ and (doc.image.ndim == 2 or (doc.image.ndim == 3 and doc.image.shape[2] == 1))
127
+ ):
128
+ out = out[..., 0]
129
+
130
+ # mask-aware blend (like dialog)
131
+ out_masked = _blend_with_mask_float(out, src01, doc)
132
+
133
+ # Clean mask metadata
134
+ _marr, mid, mname = _active_mask_layer(doc)
135
+
136
+ meta = {
137
+ "step_name": "ABE",
138
+ "abe": {
139
+ "degree": degree,
140
+ "samples": num_samples,
141
+ "downsample": downsample,
142
+ "patch": patch_size,
143
+ "rbf": use_rbf,
144
+ "rbf_smooth": rbf_smooth,
145
+ "exclusion": "none", # explicit marker for audit/history
146
+ },
147
+ "masked": bool(mid),
148
+ "mask_id": mid,
149
+ "mask_name": mname,
150
+ "mask_blend": "m*out + (1-m)*src",
151
+ }
152
+
153
+ step_name = (
154
+ f"ABE (deg={degree}, samples={num_samples}, ds={downsample}, "
155
+ f"patch={patch_size}, rbf={'on' if use_rbf else 'off'}, s={rbf_smooth:.3f})"
156
+ )
157
+ doc.apply_edit(out_masked.astype(np.float32, copy=False),
158
+ step_name=step_name, metadata=meta)
159
+
160
+ if make_bg_doc and bg is not None:
161
+ dm = getattr(main_window, "docman", None)
162
+ if dm is not None:
163
+ base = os.path.splitext(doc.display_name())[0]
164
+ meta_bg = {
165
+ "bit_depth": "32-bit floating point",
166
+ "is_mono": (bg.ndim == 2),
167
+ "source": "ABE background (headless)",
168
+ "from_step": step_name,
169
+ }
170
+ doc_bg = dm.open_array(bg.astype(np.float32, copy=False),
171
+ metadata=meta_bg,
172
+ title=f"{base}_ABE_BG")
173
+ if hasattr(main_window, "_spawn_subwindow_for"):
174
+ main_window._spawn_subwindow_for(doc_bg)
175
+
176
+
177
+ # ---------- open dialog seeded from preset ----------
178
+ def open_abe_with_preset(main_window, preset: dict | None = None):
179
+ dm = getattr(main_window, "doc_manager", getattr(main_window, "docman", None))
180
+ doc = dm.get_active_document() if (dm and hasattr(dm, "get_active_document")) else getattr(dm, "active_document", None)
181
+ if doc is None:
182
+ return
183
+ from .abe import ABEDialog
184
+ dlg = ABEDialog(main_window, doc)
185
+ p = dict(preset or {})
186
+ try:
187
+ dlg.sp_degree.setValue(int(np.clip(p.get("degree", 2), 1, 6)))
188
+ dlg.sp_samples.setValue(int(np.clip(p.get("samples", 120), 20, 100000)))
189
+ dlg.sp_down.setValue(int(np.clip(p.get("downsample", 6), 1, 64)))
190
+ dlg.sp_patch.setValue(int(np.clip(p.get("patch", 15), 5, 151)))
191
+ dlg.chk_use_rbf.setChecked(bool(p.get("rbf", True)))
192
+ dlg.sp_rbf.setValue(int(np.clip(float(p.get("rbf_smooth", 1.0)) * 100.0, 0, 100000)))
193
+ # polygons intentionally untouched (== none)
194
+ except Exception:
195
+ pass
196
+ dlg.show(); dlg.raise_(); dlg.activateWindow()