setiastrosuitepro 1.6.12__py3-none-any.whl → 1.7.3__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 (51) hide show
  1. setiastro/images/3dplanet.png +0 -0
  2. setiastro/images/TextureClarity.svg +56 -0
  3. setiastro/images/narrowbandnormalization.png +0 -0
  4. setiastro/images/planetarystacker.png +0 -0
  5. setiastro/saspro/__init__.py +9 -8
  6. setiastro/saspro/__main__.py +326 -285
  7. setiastro/saspro/_generated/build_info.py +2 -2
  8. setiastro/saspro/aberration_ai.py +128 -13
  9. setiastro/saspro/aberration_ai_preset.py +29 -3
  10. setiastro/saspro/astrospike_python.py +45 -3
  11. setiastro/saspro/blink_comparator_pro.py +116 -71
  12. setiastro/saspro/curve_editor_pro.py +72 -22
  13. setiastro/saspro/curves_preset.py +249 -47
  14. setiastro/saspro/doc_manager.py +4 -1
  15. setiastro/saspro/gui/main_window.py +326 -46
  16. setiastro/saspro/gui/mixins/file_mixin.py +41 -18
  17. setiastro/saspro/gui/mixins/menu_mixin.py +9 -0
  18. setiastro/saspro/gui/mixins/toolbar_mixin.py +123 -7
  19. setiastro/saspro/histogram.py +179 -7
  20. setiastro/saspro/imageops/narrowband_normalization.py +816 -0
  21. setiastro/saspro/imageops/serloader.py +1429 -0
  22. setiastro/saspro/layers.py +186 -10
  23. setiastro/saspro/layers_dock.py +198 -5
  24. setiastro/saspro/legacy/image_manager.py +10 -4
  25. setiastro/saspro/legacy/numba_utils.py +1 -1
  26. setiastro/saspro/live_stacking.py +24 -4
  27. setiastro/saspro/multiscale_decomp.py +30 -17
  28. setiastro/saspro/narrowband_normalization.py +1618 -0
  29. setiastro/saspro/planetprojection.py +3854 -0
  30. setiastro/saspro/remove_green.py +1 -1
  31. setiastro/saspro/resources.py +8 -0
  32. setiastro/saspro/rgbalign.py +456 -12
  33. setiastro/saspro/save_options.py +45 -13
  34. setiastro/saspro/ser_stack_config.py +102 -0
  35. setiastro/saspro/ser_stacker.py +2327 -0
  36. setiastro/saspro/ser_stacker_dialog.py +1865 -0
  37. setiastro/saspro/ser_tracking.py +228 -0
  38. setiastro/saspro/serviewer.py +1773 -0
  39. setiastro/saspro/sfcc.py +298 -64
  40. setiastro/saspro/shortcuts.py +14 -7
  41. setiastro/saspro/stacking_suite.py +21 -6
  42. setiastro/saspro/stat_stretch.py +179 -31
  43. setiastro/saspro/subwindow.py +38 -5
  44. setiastro/saspro/texture_clarity.py +593 -0
  45. setiastro/saspro/widgets/resource_monitor.py +122 -74
  46. {setiastrosuitepro-1.6.12.dist-info → setiastrosuitepro-1.7.3.dist-info}/METADATA +3 -2
  47. {setiastrosuitepro-1.6.12.dist-info → setiastrosuitepro-1.7.3.dist-info}/RECORD +51 -37
  48. {setiastrosuitepro-1.6.12.dist-info → setiastrosuitepro-1.7.3.dist-info}/WHEEL +0 -0
  49. {setiastrosuitepro-1.6.12.dist-info → setiastrosuitepro-1.7.3.dist-info}/entry_points.txt +0 -0
  50. {setiastrosuitepro-1.6.12.dist-info → setiastrosuitepro-1.7.3.dist-info}/licenses/LICENSE +0 -0
  51. {setiastrosuitepro-1.6.12.dist-info → setiastrosuitepro-1.7.3.dist-info}/licenses/license.txt +0 -0
@@ -120,37 +120,41 @@ def soft_threshold(x: np.ndarray, t: float):
120
120
  def apply_layer_ops(
121
121
  w: np.ndarray,
122
122
  bias_gain: float,
123
- thr_sigma: float, # threshold in units of σ
123
+ thr_sigma: float,
124
124
  amount: float,
125
125
  denoise_strength: float = 0.0,
126
126
  sigma: float | np.ndarray | None = None,
127
+ layer_index: int | None = None,
127
128
  *,
128
129
  mode: str = "μ–σ Thresholding",
129
130
  ):
130
131
  w2 = w
131
132
 
132
- # Normalize mode to something robust to label wording
133
133
  m = (mode or "").strip().lower()
134
134
  is_linear = m.startswith("linear")
135
-
136
- # --- Linear mode: strictly linear multiscale transform ---
137
135
  if is_linear:
138
- # Ignore thresholding and denoise; just apply gain
139
- if abs(bias_gain - 1.0) > 1e-6:
140
- return w * bias_gain
141
- return w
136
+ return w * bias_gain if abs(bias_gain - 1.0) > 1e-6 else w
142
137
 
143
- # --- μ–σ Thresholding mode (robust nonlinear) ---
144
138
  # 1) Noise reduction step (MMT-style NR)
145
139
  if denoise_strength > 0.0:
146
140
  if sigma is None:
147
141
  sigma = _robust_sigma(w2)
148
142
  sigma_f = float(sigma)
149
- # 3σ at denoise=1, scaled linearly
150
- t_dn = max(0.0, denoise_strength * 3.0 * sigma_f)
143
+
144
+ i = int(layer_index or 0)
145
+
146
+ # --- SMOOTH scaling option (pick ONE) ---
147
+ # Option A: linear growth (very controllable)
148
+ # scale = 1.0 + 0.75 * i
149
+
150
+ # Option B: sqrt growth of 2^i (gentle, "natural")
151
+ scale = (2.0 ** i) ** 0.5 # 1, 1.41, 2, 2.83, 4, ...
152
+
153
+ # Base: 3σ at denoise=1 for layer 0, increases by scale
154
+ t_dn = denoise_strength * 3.0 * scale * sigma_f
155
+
151
156
  if t_dn > 0.0:
152
157
  w_dn = soft_threshold(w2, t_dn)
153
- # Blend original vs denoised based on denoise_strength
154
158
  w2 = (1.0 - denoise_strength) * w2 + denoise_strength * w_dn
155
159
 
156
160
  # 2) Threshold in σ units + bias shaping
@@ -158,7 +162,7 @@ def apply_layer_ops(
158
162
  if sigma is None:
159
163
  sigma = _robust_sigma(w2)
160
164
  sigma_f = float(sigma)
161
- t = thr_sigma * sigma_f # convert N·σ → absolute threshold
165
+ t = thr_sigma * sigma_f
162
166
  if t > 0.0:
163
167
  wt = soft_threshold(w2, t)
164
168
  w2 = (1.0 - amount) * w2 + amount * wt
@@ -167,7 +171,6 @@ def apply_layer_ops(
167
171
  w2 = w2 * bias_gain
168
172
  return w2
169
173
 
170
-
171
174
  def _robust_sigma(arr: np.ndarray) -> float:
172
175
  """
173
176
  Robust per-layer sigma estimate using MAD, fallback to std if needed.
@@ -455,7 +458,7 @@ class MultiscaleDecompDialog(QDialog):
455
458
 
456
459
  # --- Spin boxes ---
457
460
  self.spin_gain = QDoubleSpinBox()
458
- self.spin_gain.setRange(0.0, 3.0)
461
+ self.spin_gain.setRange(0.0, 10.0)
459
462
  self.spin_gain.setSingleStep(0.05)
460
463
  self.spin_gain.setValue(1.0)
461
464
  self.spin_gain.setToolTip(
@@ -491,7 +494,7 @@ class MultiscaleDecompDialog(QDialog):
491
494
 
492
495
  # --- Sliders (int ranges, mapped to spins) ---
493
496
  self.slider_gain = QSlider(Qt.Orientation.Horizontal)
494
- self.slider_gain.setRange(0, 300) # 0..3.00
497
+ self.slider_gain.setRange(0, 1000) # 0..10.00
495
498
  self.slider_gain.setToolTip(self.spin_gain.toolTip())
496
499
 
497
500
  self.slider_thr = QSlider(Qt.Orientation.Horizontal)
@@ -748,6 +751,9 @@ class MultiscaleDecompDialog(QDialog):
748
751
  cfg = self.cfgs[i]
749
752
  if not cfg.enabled:
750
753
  return i, np.zeros_like(w)
754
+
755
+ layer_sigma = self.base_sigma * (2 ** i)
756
+
751
757
  sigma = self._layer_noise[i] if self._layer_noise and i < len(self._layer_noise) else None
752
758
  out = apply_layer_ops(
753
759
  w,
@@ -756,6 +762,7 @@ class MultiscaleDecompDialog(QDialog):
756
762
  cfg.amount,
757
763
  cfg.denoise,
758
764
  sigma,
765
+ layer_index=i,
759
766
  mode=mode,
760
767
  )
761
768
  return i, out
@@ -1264,11 +1271,17 @@ class MultiscaleDecompDialog(QDialog):
1264
1271
  cfg = self.cfgs[i]
1265
1272
  if not cfg.enabled:
1266
1273
  return i, np.zeros_like(w)
1274
+
1275
+ layer_sigma = base_sigma * (2 ** i)
1276
+
1267
1277
  return i, apply_layer_ops(
1268
1278
  w, cfg.bias_gain, cfg.thr, cfg.amount, cfg.denoise,
1269
- layer_noise[i], mode=mode
1279
+ layer_noise[i],
1280
+ layer_index=i,
1281
+ mode=mode
1270
1282
  )
1271
1283
 
1284
+
1272
1285
  tuned = [None] * len(details)
1273
1286
  max_workers = min(os.cpu_count() or 4, len(details) or 1)
1274
1287
  with ThreadPoolExecutor(max_workers=max_workers) as ex: