setiastrosuitepro 1.6.2__py3-none-any.whl → 1.6.12__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 (162) hide show
  1. setiastro/images/abeicon.svg +16 -0
  2. setiastro/images/acv_icon.png +0 -0
  3. setiastro/images/colorwheel.svg +97 -0
  4. setiastro/images/cosmic.svg +40 -0
  5. setiastro/images/cosmicsat.svg +24 -0
  6. setiastro/images/first_quarter.png +0 -0
  7. setiastro/images/full_moon.png +0 -0
  8. setiastro/images/graxpert.svg +19 -0
  9. setiastro/images/last_quarter.png +0 -0
  10. setiastro/images/linearfit.svg +32 -0
  11. setiastro/images/new_moon.png +0 -0
  12. setiastro/images/pixelmath.svg +42 -0
  13. setiastro/images/rotatearbitrary.png +0 -0
  14. setiastro/images/waning_crescent_1.png +0 -0
  15. setiastro/images/waning_crescent_2.png +0 -0
  16. setiastro/images/waning_crescent_3.png +0 -0
  17. setiastro/images/waning_crescent_4.png +0 -0
  18. setiastro/images/waning_crescent_5.png +0 -0
  19. setiastro/images/waning_gibbous_1.png +0 -0
  20. setiastro/images/waning_gibbous_2.png +0 -0
  21. setiastro/images/waning_gibbous_3.png +0 -0
  22. setiastro/images/waning_gibbous_4.png +0 -0
  23. setiastro/images/waning_gibbous_5.png +0 -0
  24. setiastro/images/waxing_crescent_1.png +0 -0
  25. setiastro/images/waxing_crescent_2.png +0 -0
  26. setiastro/images/waxing_crescent_3.png +0 -0
  27. setiastro/images/waxing_crescent_4.png +0 -0
  28. setiastro/images/waxing_crescent_5.png +0 -0
  29. setiastro/images/waxing_gibbous_1.png +0 -0
  30. setiastro/images/waxing_gibbous_2.png +0 -0
  31. setiastro/images/waxing_gibbous_3.png +0 -0
  32. setiastro/images/waxing_gibbous_4.png +0 -0
  33. setiastro/images/waxing_gibbous_5.png +0 -0
  34. setiastro/qml/ResourceMonitor.qml +84 -82
  35. setiastro/saspro/__main__.py +20 -1
  36. setiastro/saspro/_generated/build_info.py +2 -2
  37. setiastro/saspro/abe.py +37 -4
  38. setiastro/saspro/aberration_ai.py +237 -21
  39. setiastro/saspro/acv_exporter.py +379 -0
  40. setiastro/saspro/add_stars.py +33 -6
  41. setiastro/saspro/backgroundneutral.py +114 -37
  42. setiastro/saspro/blemish_blaster.py +4 -1
  43. setiastro/saspro/blink_comparator_pro.py +548 -275
  44. setiastro/saspro/clahe.py +4 -1
  45. setiastro/saspro/continuum_subtract.py +4 -1
  46. setiastro/saspro/convo.py +13 -7
  47. setiastro/saspro/cosmicclarity.py +129 -18
  48. setiastro/saspro/crop_dialog_pro.py +134 -8
  49. setiastro/saspro/curve_editor_pro.py +109 -42
  50. setiastro/saspro/doc_manager.py +246 -16
  51. setiastro/saspro/exoplanet_detector.py +120 -28
  52. setiastro/saspro/frequency_separation.py +1158 -204
  53. setiastro/saspro/function_bundle.py +16 -16
  54. setiastro/saspro/ghs_dialog_pro.py +81 -16
  55. setiastro/saspro/graxpert.py +1 -0
  56. setiastro/saspro/gui/main_window.py +519 -289
  57. setiastro/saspro/gui/mixins/dock_mixin.py +276 -42
  58. setiastro/saspro/gui/mixins/geometry_mixin.py +105 -5
  59. setiastro/saspro/gui/mixins/menu_mixin.py +28 -1
  60. setiastro/saspro/gui/mixins/theme_mixin.py +160 -14
  61. setiastro/saspro/gui/mixins/toolbar_mixin.py +416 -27
  62. setiastro/saspro/gui/mixins/update_mixin.py +138 -36
  63. setiastro/saspro/gui/mixins/view_mixin.py +42 -0
  64. setiastro/saspro/halobgon.py +4 -0
  65. setiastro/saspro/histogram.py +5 -1
  66. setiastro/saspro/image_combine.py +4 -0
  67. setiastro/saspro/image_peeker_pro.py +4 -0
  68. setiastro/saspro/imageops/starbasedwhitebalance.py +23 -52
  69. setiastro/saspro/imageops/stretch.py +582 -62
  70. setiastro/saspro/isophote.py +4 -0
  71. setiastro/saspro/layers.py +13 -9
  72. setiastro/saspro/layers_dock.py +183 -3
  73. setiastro/saspro/legacy/image_manager.py +154 -20
  74. setiastro/saspro/legacy/numba_utils.py +67 -47
  75. setiastro/saspro/legacy/xisf.py +240 -98
  76. setiastro/saspro/live_stacking.py +180 -79
  77. setiastro/saspro/luminancerecombine.py +228 -27
  78. setiastro/saspro/mask_creation.py +174 -15
  79. setiastro/saspro/mfdeconv.py +113 -35
  80. setiastro/saspro/mfdeconvcudnn.py +119 -70
  81. setiastro/saspro/mfdeconvsport.py +112 -35
  82. setiastro/saspro/morphology.py +4 -0
  83. setiastro/saspro/multiscale_decomp.py +748 -255
  84. setiastro/saspro/numba_utils.py +72 -57
  85. setiastro/saspro/ops/commands.py +18 -18
  86. setiastro/saspro/ops/script_editor.py +10 -2
  87. setiastro/saspro/ops/scripts.py +122 -0
  88. setiastro/saspro/perfect_palette_picker.py +37 -3
  89. setiastro/saspro/plate_solver.py +84 -49
  90. setiastro/saspro/psf_viewer.py +119 -37
  91. setiastro/saspro/remove_stars_preset.py +55 -13
  92. setiastro/saspro/resources.py +97 -11
  93. setiastro/saspro/rgbalign.py +4 -0
  94. setiastro/saspro/selective_color.py +83 -21
  95. setiastro/saspro/sfcc.py +364 -152
  96. setiastro/saspro/shortcuts.py +253 -49
  97. setiastro/saspro/signature_insert.py +692 -33
  98. setiastro/saspro/stacking_suite.py +1610 -574
  99. setiastro/saspro/star_alignment.py +522 -453
  100. setiastro/saspro/star_spikes.py +4 -0
  101. setiastro/saspro/star_stretch.py +38 -3
  102. setiastro/saspro/stat_stretch.py +743 -128
  103. setiastro/saspro/status_log_dock.py +1 -1
  104. setiastro/saspro/subwindow.py +786 -360
  105. setiastro/saspro/supernovaasteroidhunter.py +1 -1
  106. setiastro/saspro/swap_manager.py +77 -42
  107. setiastro/saspro/translations/all_source_strings.json +1588 -516
  108. setiastro/saspro/translations/ar_translations.py +915 -684
  109. setiastro/saspro/translations/de_translations.py +442 -463
  110. setiastro/saspro/translations/es_translations.py +277 -47
  111. setiastro/saspro/translations/fr_translations.py +279 -47
  112. setiastro/saspro/translations/hi_translations.py +253 -21
  113. setiastro/saspro/translations/integrate_translations.py +3 -2
  114. setiastro/saspro/translations/it_translations.py +1211 -161
  115. setiastro/saspro/translations/ja_translations.py +3340 -3107
  116. setiastro/saspro/translations/pt_translations.py +3315 -3337
  117. setiastro/saspro/translations/ru_translations.py +351 -117
  118. setiastro/saspro/translations/saspro_ar.qm +0 -0
  119. setiastro/saspro/translations/saspro_ar.ts +15902 -138
  120. setiastro/saspro/translations/saspro_de.qm +0 -0
  121. setiastro/saspro/translations/saspro_de.ts +14428 -133
  122. setiastro/saspro/translations/saspro_es.qm +0 -0
  123. setiastro/saspro/translations/saspro_es.ts +11503 -7821
  124. setiastro/saspro/translations/saspro_fr.qm +0 -0
  125. setiastro/saspro/translations/saspro_fr.ts +11168 -7812
  126. setiastro/saspro/translations/saspro_hi.qm +0 -0
  127. setiastro/saspro/translations/saspro_hi.ts +14733 -135
  128. setiastro/saspro/translations/saspro_it.qm +0 -0
  129. setiastro/saspro/translations/saspro_it.ts +14347 -7821
  130. setiastro/saspro/translations/saspro_ja.qm +0 -0
  131. setiastro/saspro/translations/saspro_ja.ts +14860 -137
  132. setiastro/saspro/translations/saspro_pt.qm +0 -0
  133. setiastro/saspro/translations/saspro_pt.ts +14904 -137
  134. setiastro/saspro/translations/saspro_ru.qm +0 -0
  135. setiastro/saspro/translations/saspro_ru.ts +11766 -168
  136. setiastro/saspro/translations/saspro_sw.qm +0 -0
  137. setiastro/saspro/translations/saspro_sw.ts +15115 -135
  138. setiastro/saspro/translations/saspro_uk.qm +0 -0
  139. setiastro/saspro/translations/saspro_uk.ts +11206 -6729
  140. setiastro/saspro/translations/saspro_zh.qm +0 -0
  141. setiastro/saspro/translations/saspro_zh.ts +10581 -7812
  142. setiastro/saspro/translations/sw_translations.py +282 -56
  143. setiastro/saspro/translations/uk_translations.py +264 -35
  144. setiastro/saspro/translations/zh_translations.py +282 -47
  145. setiastro/saspro/view_bundle.py +17 -17
  146. setiastro/saspro/wavescale_hdr.py +4 -1
  147. setiastro/saspro/wavescalede.py +4 -1
  148. setiastro/saspro/whitebalance.py +84 -12
  149. setiastro/saspro/widgets/common_utilities.py +28 -21
  150. setiastro/saspro/widgets/minigame/game.js +11 -6
  151. setiastro/saspro/widgets/resource_monitor.py +133 -57
  152. setiastro/saspro/widgets/spinboxes.py +28 -13
  153. setiastro/saspro/wimi.py +92 -721
  154. setiastro/saspro/wims.py +46 -36
  155. setiastro/saspro/window_shelf.py +2 -2
  156. setiastro/saspro/xisf.py +101 -11
  157. {setiastrosuitepro-1.6.2.dist-info → setiastrosuitepro-1.6.12.dist-info}/METADATA +8 -7
  158. {setiastrosuitepro-1.6.2.dist-info → setiastrosuitepro-1.6.12.dist-info}/RECORD +162 -128
  159. {setiastrosuitepro-1.6.2.dist-info → setiastrosuitepro-1.6.12.dist-info}/WHEEL +0 -0
  160. {setiastrosuitepro-1.6.2.dist-info → setiastrosuitepro-1.6.12.dist-info}/entry_points.txt +0 -0
  161. {setiastrosuitepro-1.6.2.dist-info → setiastrosuitepro-1.6.12.dist-info}/licenses/LICENSE +0 -0
  162. {setiastrosuitepro-1.6.2.dist-info → setiastrosuitepro-1.6.12.dist-info}/licenses/license.txt +0 -0
@@ -24,7 +24,7 @@ from setiastro.saspro.legacy.image_manager import load_image, save_image
24
24
  from setiastro.saspro.legacy.numba_utils import bulk_cosmetic_correction_numba
25
25
  from setiastro.saspro.imageops.stretch import stretch_mono_image, stretch_color_image
26
26
  from setiastro.saspro.star_alignment import PolyGradientRemoval
27
- from pro import minorbodycatalog as mbc
27
+ from setiastro.saspro import minorbodycatalog as mbc
28
28
  from setiastro.saspro.plate_solver import PlateSolverDialog as PlateSolver
29
29
  from setiastro.saspro.widgets.themed_buttons import themed_toolbtn
30
30
 
@@ -1,10 +1,5 @@
1
- import os
2
- import shutil
3
- import tempfile
4
- import uuid
5
- import pickle
6
- import atexit
7
- import threading
1
+ import os, shutil, tempfile, uuid, atexit, threading
2
+ from collections import OrderedDict
8
3
  import numpy as np
9
4
 
10
5
  class SwapManager:
@@ -14,66 +9,110 @@ class SwapManager:
14
9
  def __new__(cls, *args, **kwargs):
15
10
  with cls._lock:
16
11
  if cls._instance is None:
17
- cls._instance = super(SwapManager, cls).__new__(cls)
12
+ cls._instance = super().__new__(cls)
18
13
  cls._instance._initialized = False
19
14
  return cls._instance
20
15
 
21
- def __init__(self):
16
+ def __init__(self, *, cache_bytes: int = 1_000_000_000):
22
17
  if self._initialized:
23
18
  return
24
19
  self._initialized = True
25
-
26
- # Create a unique temp directory for this session
27
- self.temp_dir = os.path.join(tempfile.gettempdir(), "SetiAstroSuitePro_Swap", str(uuid.uuid4()))
20
+
21
+ self.temp_dir = os.path.join(
22
+ tempfile.gettempdir(), "SetiAstroSuitePro_Swap", str(uuid.uuid4())
23
+ )
28
24
  os.makedirs(self.temp_dir, exist_ok=True)
29
-
30
- # Register cleanup on exit
31
25
  atexit.register(self.cleanup_all)
32
26
 
27
+ # LRU of in-RAM states: swap_id -> ndarray
28
+ self._cache = OrderedDict()
29
+ self._cache_bytes = int(cache_bytes)
30
+ self._cache_used = 0
31
+ self._cache_lock = threading.Lock()
32
+
33
33
  def get_swap_path(self, swap_id: str) -> str:
34
- return os.path.join(self.temp_dir, f"{swap_id}.swap")
34
+ # store as .npy (fast + supports mmap)
35
+ return os.path.join(self.temp_dir, f"{swap_id}.npy")
36
+
37
+ def _arr_nbytes(self, a: np.ndarray) -> int:
38
+ try:
39
+ return int(a.nbytes)
40
+ except Exception:
41
+ return 0
42
+
43
+ def _cache_put(self, swap_id: str, arr: np.ndarray):
44
+ if arr is None:
45
+ return
46
+ n = self._arr_nbytes(arr)
47
+ if n <= 0:
48
+ return
35
49
 
36
- def save_state(self, image: np.ndarray) -> str:
37
- """
38
- Save the image array to a swap file.
39
- Returns the unique swap_id.
40
- """
50
+ with self._cache_lock:
51
+ # If already present, refresh
52
+ old = self._cache.pop(swap_id, None)
53
+ if old is not None:
54
+ self._cache_used -= self._arr_nbytes(old)
55
+
56
+ self._cache[swap_id] = arr
57
+ self._cache_used += n
58
+
59
+ # Evict LRU until under budget
60
+ while self._cache_used > self._cache_bytes and self._cache:
61
+ k, v = self._cache.popitem(last=False)
62
+ self._cache_used -= self._arr_nbytes(v)
63
+
64
+ def _cache_get(self, swap_id: str):
65
+ with self._cache_lock:
66
+ arr = self._cache.pop(swap_id, None)
67
+ if arr is None:
68
+ return None
69
+ # move to MRU
70
+ self._cache[swap_id] = arr
71
+ return arr
72
+
73
+ def save_state(self, image: np.ndarray) -> str | None:
41
74
  swap_id = uuid.uuid4().hex
42
75
  path = self.get_swap_path(swap_id)
43
-
44
- # We only save the image data to disk. Metadata is kept in RAM by the caller.
45
- # Using pickle for simplicity and robustness with numpy arrays.
46
- # For pure numpy arrays, np.save might be slightly faster, but pickle is more flexible if we change what we store.
47
- # Let's stick to pickle for now as per plan.
48
76
  try:
49
- with open(path, "wb") as f:
50
- pickle.dump(image, f, protocol=pickle.HIGHEST_PROTOCOL)
77
+ # Write fast .npy
78
+ np.save(path, image, allow_pickle=False)
79
+ # Optionally keep it hot in RAM too (depends how you use it)
80
+ self._cache_put(swap_id, image)
81
+ return swap_id
51
82
  except Exception as e:
52
83
  print(f"[SwapManager] Failed to save state {swap_id}: {e}")
53
84
  return None
54
-
55
- return swap_id
56
85
 
57
86
  def load_state(self, swap_id: str) -> np.ndarray | None:
58
- """
59
- Load the image array from the swap file.
60
- """
87
+ #print("[SwapManager] LOAD", swap_id)
88
+ # First: try RAM
89
+ hot = self._cache_get(swap_id)
90
+ if hot is not None:
91
+ return hot
92
+
61
93
  path = self.get_swap_path(swap_id)
62
94
  if not os.path.exists(path):
63
95
  print(f"[SwapManager] Swap file not found: {path}")
64
96
  return None
65
-
97
+
66
98
  try:
67
- with open(path, "rb") as f:
68
- return pickle.load(f)
99
+ # mmap_mode="r" is extremely fast; convert to real ndarray only if needed
100
+ arr = np.load(path, mmap_mode="r", allow_pickle=False)
101
+ # If your pipeline needs a writable array, materialize:
102
+ # arr = np.array(arr, copy=True)
103
+ # Cache the loaded array (mmap object still OK to cache; you can decide)
104
+ self._cache_put(swap_id, np.array(arr, copy=False))
105
+ return np.array(arr, copy=False)
69
106
  except Exception as e:
70
107
  print(f"[SwapManager] Failed to load state {swap_id}: {e}")
71
108
  return None
72
109
 
73
110
  def delete_state(self, swap_id: str):
74
- """
75
- Delete a specific swap file.
76
- """
111
+ with self._cache_lock:
112
+ old = self._cache.pop(swap_id, None)
113
+ if old is not None:
114
+ self._cache_used -= self._arr_nbytes(old)
115
+
77
116
  path = self.get_swap_path(swap_id)
78
117
  try:
79
118
  if os.path.exists(path):
@@ -82,13 +121,9 @@ class SwapManager:
82
121
  print(f"[SwapManager] Failed to delete state {swap_id}: {e}")
83
122
 
84
123
  def cleanup_all(self):
85
- """
86
- Delete the entire temporary directory for this session.
87
- """
88
124
  try:
89
125
  if os.path.exists(self.temp_dir):
90
126
  shutil.rmtree(self.temp_dir, ignore_errors=True)
91
- # print(f"[SwapManager] Cleaned up {self.temp_dir}")
92
127
  except Exception as e:
93
128
  print(f"[SwapManager] Cleanup failed: {e}")
94
129