setiastrosuitepro 1.6.7__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 (394) hide show
  1. setiastro/__init__.py +2 -0
  2. setiastro/data/SASP_data.fits +0 -0
  3. setiastro/data/catalogs/List_of_Galaxies_with_Distances_Gly.csv +488 -0
  4. setiastro/data/catalogs/astrobin_filters.csv +890 -0
  5. setiastro/data/catalogs/astrobin_filters_page1_local.csv +51 -0
  6. setiastro/data/catalogs/cali2.csv +63 -0
  7. setiastro/data/catalogs/cali2color.csv +65 -0
  8. setiastro/data/catalogs/celestial_catalog - original.csv +16471 -0
  9. setiastro/data/catalogs/celestial_catalog.csv +24031 -0
  10. setiastro/data/catalogs/detected_stars.csv +24784 -0
  11. setiastro/data/catalogs/fits_header_data.csv +46 -0
  12. setiastro/data/catalogs/test.csv +8 -0
  13. setiastro/data/catalogs/updated_celestial_catalog.csv +16471 -0
  14. setiastro/images/Astro_Spikes.png +0 -0
  15. setiastro/images/Background_startup.jpg +0 -0
  16. setiastro/images/HRDiagram.png +0 -0
  17. setiastro/images/LExtract.png +0 -0
  18. setiastro/images/LInsert.png +0 -0
  19. setiastro/images/Oxygenation-atm-2.svg.png +0 -0
  20. setiastro/images/RGB080604.png +0 -0
  21. setiastro/images/abeicon.png +0 -0
  22. setiastro/images/aberration.png +0 -0
  23. setiastro/images/acv_icon.png +0 -0
  24. setiastro/images/andromedatry.png +0 -0
  25. setiastro/images/andromedatry_satellited.png +0 -0
  26. setiastro/images/annotated.png +0 -0
  27. setiastro/images/aperture.png +0 -0
  28. setiastro/images/astrosuite.ico +0 -0
  29. setiastro/images/astrosuite.png +0 -0
  30. setiastro/images/astrosuitepro.icns +0 -0
  31. setiastro/images/astrosuitepro.ico +0 -0
  32. setiastro/images/astrosuitepro.png +0 -0
  33. setiastro/images/background.png +0 -0
  34. setiastro/images/background2.png +0 -0
  35. setiastro/images/benchmark.png +0 -0
  36. setiastro/images/big_moon_stabilizer_timeline.png +0 -0
  37. setiastro/images/big_moon_stabilizer_timeline_clean.png +0 -0
  38. setiastro/images/blaster.png +0 -0
  39. setiastro/images/blink.png +0 -0
  40. setiastro/images/clahe.png +0 -0
  41. setiastro/images/collage.png +0 -0
  42. setiastro/images/colorwheel.png +0 -0
  43. setiastro/images/contsub.png +0 -0
  44. setiastro/images/convo.png +0 -0
  45. setiastro/images/copyslot.png +0 -0
  46. setiastro/images/cosmic.png +0 -0
  47. setiastro/images/cosmicsat.png +0 -0
  48. setiastro/images/crop1.png +0 -0
  49. setiastro/images/cropicon.png +0 -0
  50. setiastro/images/curves.png +0 -0
  51. setiastro/images/cvs.png +0 -0
  52. setiastro/images/debayer.png +0 -0
  53. setiastro/images/denoise_cnn_custom.png +0 -0
  54. setiastro/images/denoise_cnn_graph.png +0 -0
  55. setiastro/images/disk.png +0 -0
  56. setiastro/images/dse.png +0 -0
  57. setiastro/images/exoicon.png +0 -0
  58. setiastro/images/eye.png +0 -0
  59. setiastro/images/first_quarter.png +0 -0
  60. setiastro/images/fliphorizontal.png +0 -0
  61. setiastro/images/flipvertical.png +0 -0
  62. setiastro/images/font.png +0 -0
  63. setiastro/images/freqsep.png +0 -0
  64. setiastro/images/full_moon.png +0 -0
  65. setiastro/images/functionbundle.png +0 -0
  66. setiastro/images/graxpert.png +0 -0
  67. setiastro/images/green.png +0 -0
  68. setiastro/images/gridicon.png +0 -0
  69. setiastro/images/halo.png +0 -0
  70. setiastro/images/hdr.png +0 -0
  71. setiastro/images/histogram.png +0 -0
  72. setiastro/images/hubble.png +0 -0
  73. setiastro/images/imagecombine.png +0 -0
  74. setiastro/images/invert.png +0 -0
  75. setiastro/images/isophote.png +0 -0
  76. setiastro/images/isophote_demo_figure.png +0 -0
  77. setiastro/images/isophote_demo_image.png +0 -0
  78. setiastro/images/isophote_demo_model.png +0 -0
  79. setiastro/images/isophote_demo_residual.png +0 -0
  80. setiastro/images/jwstpupil.png +0 -0
  81. setiastro/images/last_quarter.png +0 -0
  82. setiastro/images/linearfit.png +0 -0
  83. setiastro/images/livestacking.png +0 -0
  84. setiastro/images/mask.png +0 -0
  85. setiastro/images/maskapply.png +0 -0
  86. setiastro/images/maskcreate.png +0 -0
  87. setiastro/images/maskremove.png +0 -0
  88. setiastro/images/morpho.png +0 -0
  89. setiastro/images/mosaic.png +0 -0
  90. setiastro/images/multiscale_decomp.png +0 -0
  91. setiastro/images/nbtorgb.png +0 -0
  92. setiastro/images/neutral.png +0 -0
  93. setiastro/images/new_moon.png +0 -0
  94. setiastro/images/nuke.png +0 -0
  95. setiastro/images/openfile.png +0 -0
  96. setiastro/images/pedestal.png +0 -0
  97. setiastro/images/pen.png +0 -0
  98. setiastro/images/pixelmath.png +0 -0
  99. setiastro/images/platesolve.png +0 -0
  100. setiastro/images/ppp.png +0 -0
  101. setiastro/images/pro.png +0 -0
  102. setiastro/images/project.png +0 -0
  103. setiastro/images/psf.png +0 -0
  104. setiastro/images/redo.png +0 -0
  105. setiastro/images/redoicon.png +0 -0
  106. setiastro/images/rescale.png +0 -0
  107. setiastro/images/rgbalign.png +0 -0
  108. setiastro/images/rgbcombo.png +0 -0
  109. setiastro/images/rgbextract.png +0 -0
  110. setiastro/images/rotate180.png +0 -0
  111. setiastro/images/rotatearbitrary.png +0 -0
  112. setiastro/images/rotateclockwise.png +0 -0
  113. setiastro/images/rotatecounterclockwise.png +0 -0
  114. setiastro/images/satellite.png +0 -0
  115. setiastro/images/script.png +0 -0
  116. setiastro/images/selectivecolor.png +0 -0
  117. setiastro/images/simbad.png +0 -0
  118. setiastro/images/slot0.png +0 -0
  119. setiastro/images/slot1.png +0 -0
  120. setiastro/images/slot2.png +0 -0
  121. setiastro/images/slot3.png +0 -0
  122. setiastro/images/slot4.png +0 -0
  123. setiastro/images/slot5.png +0 -0
  124. setiastro/images/slot6.png +0 -0
  125. setiastro/images/slot7.png +0 -0
  126. setiastro/images/slot8.png +0 -0
  127. setiastro/images/slot9.png +0 -0
  128. setiastro/images/spcc.png +0 -0
  129. setiastro/images/spin_precession_vs_lunar_distance.png +0 -0
  130. setiastro/images/spinner.gif +0 -0
  131. setiastro/images/stacking.png +0 -0
  132. setiastro/images/staradd.png +0 -0
  133. setiastro/images/staralign.png +0 -0
  134. setiastro/images/starnet.png +0 -0
  135. setiastro/images/starregistration.png +0 -0
  136. setiastro/images/starspike.png +0 -0
  137. setiastro/images/starstretch.png +0 -0
  138. setiastro/images/statstretch.png +0 -0
  139. setiastro/images/supernova.png +0 -0
  140. setiastro/images/uhs.png +0 -0
  141. setiastro/images/undoicon.png +0 -0
  142. setiastro/images/upscale.png +0 -0
  143. setiastro/images/viewbundle.png +0 -0
  144. setiastro/images/waning_crescent_1.png +0 -0
  145. setiastro/images/waning_crescent_2.png +0 -0
  146. setiastro/images/waning_crescent_3.png +0 -0
  147. setiastro/images/waning_crescent_4.png +0 -0
  148. setiastro/images/waning_crescent_5.png +0 -0
  149. setiastro/images/waning_gibbous_1.png +0 -0
  150. setiastro/images/waning_gibbous_2.png +0 -0
  151. setiastro/images/waning_gibbous_3.png +0 -0
  152. setiastro/images/waning_gibbous_4.png +0 -0
  153. setiastro/images/waning_gibbous_5.png +0 -0
  154. setiastro/images/waxing_crescent_1.png +0 -0
  155. setiastro/images/waxing_crescent_2.png +0 -0
  156. setiastro/images/waxing_crescent_3.png +0 -0
  157. setiastro/images/waxing_crescent_4.png +0 -0
  158. setiastro/images/waxing_crescent_5.png +0 -0
  159. setiastro/images/waxing_gibbous_1.png +0 -0
  160. setiastro/images/waxing_gibbous_2.png +0 -0
  161. setiastro/images/waxing_gibbous_3.png +0 -0
  162. setiastro/images/waxing_gibbous_4.png +0 -0
  163. setiastro/images/waxing_gibbous_5.png +0 -0
  164. setiastro/images/whitebalance.png +0 -0
  165. setiastro/images/wimi_icon_256x256.png +0 -0
  166. setiastro/images/wimilogo.png +0 -0
  167. setiastro/images/wims.png +0 -0
  168. setiastro/images/wrench_icon.png +0 -0
  169. setiastro/images/xisfliberator.png +0 -0
  170. setiastro/qml/ResourceMonitor.qml +128 -0
  171. setiastro/saspro/__init__.py +20 -0
  172. setiastro/saspro/__main__.py +964 -0
  173. setiastro/saspro/_generated/__init__.py +7 -0
  174. setiastro/saspro/_generated/build_info.py +3 -0
  175. setiastro/saspro/abe.py +1379 -0
  176. setiastro/saspro/abe_preset.py +196 -0
  177. setiastro/saspro/aberration_ai.py +910 -0
  178. setiastro/saspro/aberration_ai_preset.py +224 -0
  179. setiastro/saspro/accel_installer.py +218 -0
  180. setiastro/saspro/accel_workers.py +30 -0
  181. setiastro/saspro/acv_exporter.py +379 -0
  182. setiastro/saspro/add_stars.py +627 -0
  183. setiastro/saspro/astrobin_exporter.py +1010 -0
  184. setiastro/saspro/astrospike.py +153 -0
  185. setiastro/saspro/astrospike_python.py +1841 -0
  186. setiastro/saspro/autostretch.py +198 -0
  187. setiastro/saspro/backgroundneutral.py +639 -0
  188. setiastro/saspro/batch_convert.py +328 -0
  189. setiastro/saspro/batch_renamer.py +522 -0
  190. setiastro/saspro/blemish_blaster.py +494 -0
  191. setiastro/saspro/blink_comparator_pro.py +3149 -0
  192. setiastro/saspro/bundles.py +61 -0
  193. setiastro/saspro/bundles_dock.py +114 -0
  194. setiastro/saspro/cheat_sheet.py +213 -0
  195. setiastro/saspro/clahe.py +371 -0
  196. setiastro/saspro/comet_stacking.py +1442 -0
  197. setiastro/saspro/common_tr.py +107 -0
  198. setiastro/saspro/config.py +38 -0
  199. setiastro/saspro/config_bootstrap.py +40 -0
  200. setiastro/saspro/config_manager.py +316 -0
  201. setiastro/saspro/continuum_subtract.py +1620 -0
  202. setiastro/saspro/convo.py +1403 -0
  203. setiastro/saspro/convo_preset.py +414 -0
  204. setiastro/saspro/copyastro.py +190 -0
  205. setiastro/saspro/cosmicclarity.py +1593 -0
  206. setiastro/saspro/cosmicclarity_preset.py +407 -0
  207. setiastro/saspro/crop_dialog_pro.py +1005 -0
  208. setiastro/saspro/crop_preset.py +189 -0
  209. setiastro/saspro/curve_editor_pro.py +2608 -0
  210. setiastro/saspro/curves_preset.py +375 -0
  211. setiastro/saspro/debayer.py +673 -0
  212. setiastro/saspro/debug_utils.py +29 -0
  213. setiastro/saspro/dnd_mime.py +35 -0
  214. setiastro/saspro/doc_manager.py +2727 -0
  215. setiastro/saspro/exoplanet_detector.py +2258 -0
  216. setiastro/saspro/file_utils.py +284 -0
  217. setiastro/saspro/fitsmodifier.py +748 -0
  218. setiastro/saspro/fix_bom.py +32 -0
  219. setiastro/saspro/free_torch_memory.py +48 -0
  220. setiastro/saspro/frequency_separation.py +1352 -0
  221. setiastro/saspro/function_bundle.py +1596 -0
  222. setiastro/saspro/generate_translations.py +3092 -0
  223. setiastro/saspro/ghs_dialog_pro.py +728 -0
  224. setiastro/saspro/ghs_preset.py +284 -0
  225. setiastro/saspro/graxpert.py +638 -0
  226. setiastro/saspro/graxpert_preset.py +287 -0
  227. setiastro/saspro/gui/__init__.py +0 -0
  228. setiastro/saspro/gui/main_window.py +8928 -0
  229. setiastro/saspro/gui/mixins/__init__.py +33 -0
  230. setiastro/saspro/gui/mixins/dock_mixin.py +375 -0
  231. setiastro/saspro/gui/mixins/file_mixin.py +450 -0
  232. setiastro/saspro/gui/mixins/geometry_mixin.py +503 -0
  233. setiastro/saspro/gui/mixins/header_mixin.py +441 -0
  234. setiastro/saspro/gui/mixins/mask_mixin.py +421 -0
  235. setiastro/saspro/gui/mixins/menu_mixin.py +391 -0
  236. setiastro/saspro/gui/mixins/theme_mixin.py +367 -0
  237. setiastro/saspro/gui/mixins/toolbar_mixin.py +1824 -0
  238. setiastro/saspro/gui/mixins/update_mixin.py +323 -0
  239. setiastro/saspro/gui/mixins/view_mixin.py +477 -0
  240. setiastro/saspro/gui/statistics_dialog.py +47 -0
  241. setiastro/saspro/halobgon.py +492 -0
  242. setiastro/saspro/header_viewer.py +448 -0
  243. setiastro/saspro/headless_utils.py +88 -0
  244. setiastro/saspro/histogram.py +760 -0
  245. setiastro/saspro/history_explorer.py +941 -0
  246. setiastro/saspro/i18n.py +168 -0
  247. setiastro/saspro/image_combine.py +421 -0
  248. setiastro/saspro/image_peeker_pro.py +1608 -0
  249. setiastro/saspro/imageops/__init__.py +37 -0
  250. setiastro/saspro/imageops/mdi_snap.py +292 -0
  251. setiastro/saspro/imageops/scnr.py +36 -0
  252. setiastro/saspro/imageops/starbasedwhitebalance.py +210 -0
  253. setiastro/saspro/imageops/stretch.py +236 -0
  254. setiastro/saspro/isophote.py +1186 -0
  255. setiastro/saspro/layers.py +208 -0
  256. setiastro/saspro/layers_dock.py +714 -0
  257. setiastro/saspro/lazy_imports.py +193 -0
  258. setiastro/saspro/legacy/__init__.py +2 -0
  259. setiastro/saspro/legacy/image_manager.py +2360 -0
  260. setiastro/saspro/legacy/numba_utils.py +3676 -0
  261. setiastro/saspro/legacy/xisf.py +1213 -0
  262. setiastro/saspro/linear_fit.py +537 -0
  263. setiastro/saspro/live_stacking.py +1854 -0
  264. setiastro/saspro/log_bus.py +5 -0
  265. setiastro/saspro/logging_config.py +460 -0
  266. setiastro/saspro/luminancerecombine.py +510 -0
  267. setiastro/saspro/main_helpers.py +201 -0
  268. setiastro/saspro/mask_creation.py +1090 -0
  269. setiastro/saspro/masks_core.py +56 -0
  270. setiastro/saspro/mdi_widgets.py +353 -0
  271. setiastro/saspro/memory_utils.py +666 -0
  272. setiastro/saspro/metadata_patcher.py +75 -0
  273. setiastro/saspro/mfdeconv.py +3909 -0
  274. setiastro/saspro/mfdeconv_earlystop.py +71 -0
  275. setiastro/saspro/mfdeconvcudnn.py +3312 -0
  276. setiastro/saspro/mfdeconvsport.py +2459 -0
  277. setiastro/saspro/minorbodycatalog.py +567 -0
  278. setiastro/saspro/morphology.py +411 -0
  279. setiastro/saspro/multiscale_decomp.py +1751 -0
  280. setiastro/saspro/nbtorgb_stars.py +541 -0
  281. setiastro/saspro/numba_utils.py +3145 -0
  282. setiastro/saspro/numba_warmup.py +141 -0
  283. setiastro/saspro/ops/__init__.py +9 -0
  284. setiastro/saspro/ops/command_help_dialog.py +623 -0
  285. setiastro/saspro/ops/command_runner.py +217 -0
  286. setiastro/saspro/ops/commands.py +1594 -0
  287. setiastro/saspro/ops/script_editor.py +1105 -0
  288. setiastro/saspro/ops/scripts.py +1476 -0
  289. setiastro/saspro/ops/settings.py +637 -0
  290. setiastro/saspro/parallel_utils.py +554 -0
  291. setiastro/saspro/pedestal.py +121 -0
  292. setiastro/saspro/perfect_palette_picker.py +1105 -0
  293. setiastro/saspro/pipeline.py +110 -0
  294. setiastro/saspro/pixelmath.py +1604 -0
  295. setiastro/saspro/plate_solver.py +2480 -0
  296. setiastro/saspro/project_io.py +797 -0
  297. setiastro/saspro/psf_utils.py +136 -0
  298. setiastro/saspro/psf_viewer.py +631 -0
  299. setiastro/saspro/pyi_rthook_astroquery.py +95 -0
  300. setiastro/saspro/remove_green.py +331 -0
  301. setiastro/saspro/remove_stars.py +1599 -0
  302. setiastro/saspro/remove_stars_preset.py +446 -0
  303. setiastro/saspro/resources.py +570 -0
  304. setiastro/saspro/rgb_combination.py +208 -0
  305. setiastro/saspro/rgb_extract.py +19 -0
  306. setiastro/saspro/rgbalign.py +727 -0
  307. setiastro/saspro/runtime_imports.py +7 -0
  308. setiastro/saspro/runtime_torch.py +754 -0
  309. setiastro/saspro/save_options.py +73 -0
  310. setiastro/saspro/selective_color.py +1614 -0
  311. setiastro/saspro/sfcc.py +1530 -0
  312. setiastro/saspro/shortcuts.py +3125 -0
  313. setiastro/saspro/signature_insert.py +1106 -0
  314. setiastro/saspro/stacking_suite.py +19069 -0
  315. setiastro/saspro/star_alignment.py +7383 -0
  316. setiastro/saspro/star_alignment_preset.py +329 -0
  317. setiastro/saspro/star_metrics.py +49 -0
  318. setiastro/saspro/star_spikes.py +769 -0
  319. setiastro/saspro/star_stretch.py +542 -0
  320. setiastro/saspro/stat_stretch.py +554 -0
  321. setiastro/saspro/status_log_dock.py +78 -0
  322. setiastro/saspro/subwindow.py +3523 -0
  323. setiastro/saspro/supernovaasteroidhunter.py +1719 -0
  324. setiastro/saspro/swap_manager.py +134 -0
  325. setiastro/saspro/torch_backend.py +89 -0
  326. setiastro/saspro/torch_rejection.py +434 -0
  327. setiastro/saspro/translations/all_source_strings.json +4726 -0
  328. setiastro/saspro/translations/ar_translations.py +4096 -0
  329. setiastro/saspro/translations/de_translations.py +3728 -0
  330. setiastro/saspro/translations/es_translations.py +4169 -0
  331. setiastro/saspro/translations/fr_translations.py +4090 -0
  332. setiastro/saspro/translations/hi_translations.py +3803 -0
  333. setiastro/saspro/translations/integrate_translations.py +271 -0
  334. setiastro/saspro/translations/it_translations.py +4728 -0
  335. setiastro/saspro/translations/ja_translations.py +3834 -0
  336. setiastro/saspro/translations/pt_translations.py +3847 -0
  337. setiastro/saspro/translations/ru_translations.py +3082 -0
  338. setiastro/saspro/translations/saspro_ar.qm +0 -0
  339. setiastro/saspro/translations/saspro_ar.ts +16019 -0
  340. setiastro/saspro/translations/saspro_de.qm +0 -0
  341. setiastro/saspro/translations/saspro_de.ts +14548 -0
  342. setiastro/saspro/translations/saspro_es.qm +0 -0
  343. setiastro/saspro/translations/saspro_es.ts +16202 -0
  344. setiastro/saspro/translations/saspro_fr.qm +0 -0
  345. setiastro/saspro/translations/saspro_fr.ts +15870 -0
  346. setiastro/saspro/translations/saspro_hi.qm +0 -0
  347. setiastro/saspro/translations/saspro_hi.ts +14855 -0
  348. setiastro/saspro/translations/saspro_it.qm +0 -0
  349. setiastro/saspro/translations/saspro_it.ts +19046 -0
  350. setiastro/saspro/translations/saspro_ja.qm +0 -0
  351. setiastro/saspro/translations/saspro_ja.ts +14980 -0
  352. setiastro/saspro/translations/saspro_pt.qm +0 -0
  353. setiastro/saspro/translations/saspro_pt.ts +15024 -0
  354. setiastro/saspro/translations/saspro_ru.qm +0 -0
  355. setiastro/saspro/translations/saspro_ru.ts +11835 -0
  356. setiastro/saspro/translations/saspro_sw.qm +0 -0
  357. setiastro/saspro/translations/saspro_sw.ts +15237 -0
  358. setiastro/saspro/translations/saspro_uk.qm +0 -0
  359. setiastro/saspro/translations/saspro_uk.ts +15248 -0
  360. setiastro/saspro/translations/saspro_zh.qm +0 -0
  361. setiastro/saspro/translations/saspro_zh.ts +15289 -0
  362. setiastro/saspro/translations/sw_translations.py +3897 -0
  363. setiastro/saspro/translations/uk_translations.py +3929 -0
  364. setiastro/saspro/translations/zh_translations.py +3910 -0
  365. setiastro/saspro/versioning.py +77 -0
  366. setiastro/saspro/view_bundle.py +1558 -0
  367. setiastro/saspro/wavescale_hdr.py +648 -0
  368. setiastro/saspro/wavescale_hdr_preset.py +101 -0
  369. setiastro/saspro/wavescalede.py +683 -0
  370. setiastro/saspro/wavescalede_preset.py +230 -0
  371. setiastro/saspro/wcs_update.py +374 -0
  372. setiastro/saspro/whitebalance.py +540 -0
  373. setiastro/saspro/widgets/__init__.py +48 -0
  374. setiastro/saspro/widgets/common_utilities.py +306 -0
  375. setiastro/saspro/widgets/graphics_views.py +122 -0
  376. setiastro/saspro/widgets/image_utils.py +518 -0
  377. setiastro/saspro/widgets/minigame/game.js +991 -0
  378. setiastro/saspro/widgets/minigame/index.html +53 -0
  379. setiastro/saspro/widgets/minigame/style.css +241 -0
  380. setiastro/saspro/widgets/preview_dialogs.py +280 -0
  381. setiastro/saspro/widgets/resource_monitor.py +313 -0
  382. setiastro/saspro/widgets/spinboxes.py +290 -0
  383. setiastro/saspro/widgets/themed_buttons.py +13 -0
  384. setiastro/saspro/widgets/wavelet_utils.py +331 -0
  385. setiastro/saspro/wimi.py +7367 -0
  386. setiastro/saspro/wims.py +588 -0
  387. setiastro/saspro/window_shelf.py +185 -0
  388. setiastro/saspro/xisf.py +1213 -0
  389. setiastrosuitepro-1.6.7.dist-info/METADATA +279 -0
  390. setiastrosuitepro-1.6.7.dist-info/RECORD +394 -0
  391. setiastrosuitepro-1.6.7.dist-info/WHEEL +4 -0
  392. setiastrosuitepro-1.6.7.dist-info/entry_points.txt +6 -0
  393. setiastrosuitepro-1.6.7.dist-info/licenses/LICENSE +674 -0
  394. setiastrosuitepro-1.6.7.dist-info/licenses/license.txt +2580 -0
@@ -0,0 +1,510 @@
1
+ #src/setiastro/saspro/luminancerecombine.py
2
+ from __future__ import annotations
3
+ import numpy as np
4
+ import cv2
5
+ from typing import Optional
6
+
7
+ from setiastro.saspro.headless_utils import normalize_headless_main, unwrap_docproxy
8
+ from setiastro.saspro.ops.command_runner import CommandError
9
+ import numpy as np
10
+
11
+ # Shared utilities
12
+ from setiastro.saspro.widgets.image_utils import (
13
+ extract_mask_from_document as _active_mask_array_from_doc,
14
+ to_float01_strict as _to_float01_strict,
15
+ )
16
+
17
+ _LUMA_REC709 = np.array([0.2126, 0.7152, 0.0722], dtype=np.float32)
18
+ _LUMA_REC601 = np.array([0.2990, 0.5870, 0.1140], dtype=np.float32)
19
+ _LUMA_REC2020 = np.array([0.2627, 0.6780, 0.0593], dtype=np.float32)
20
+
21
+ # ---- Luma profiles (UI selectable) ----
22
+ # Key = what the UI stores in self.luma_method / preset["mode"]
23
+ # weights must be length-3 (RGB), assumed linear
24
+ LUMA_PROFILES: dict[str, dict] = {
25
+ # --- Standard ---
26
+ "rec709": {"method": "rec709", "weights": _LUMA_REC709, "category": "Standard", "description": "Broadband RGB (Rec.709)"},
27
+ "rec601": {"method": "rec601", "weights": _LUMA_REC601, "category": "Standard", "description": "Rec.601"},
28
+ "rec2020": {"method": "rec2020", "weights": _LUMA_REC2020, "category": "Standard", "description": "Rec.2020"},
29
+ "equal": {"method": "equal", "weights": None, "category": "Standard", "description": "Equal RGB"},
30
+ "max": {"method": "max", "weights": None, "category": "Standard", "description": "Max (Narrowband mappings)"},
31
+ "median": {"method": "median", "weights": None, "category": "Standard", "description": "Median RGB"},
32
+ "snr": {"method": "snr", "weights": None, "category": "Standard", "description": "Unequal Noise (SNR)"},
33
+
34
+ # --- Sensors (examples — paste your whole list here) ---
35
+ "sensor:Sony IMX571 (ASI2600/QHY268)": {
36
+ "method": "custom",
37
+ "weights": np.array([0.2944, 0.5021, 0.2035], dtype=np.float32),
38
+ "category": "Sensors/Sony Modern BSI",
39
+ "description": "Sony IMX571 26MP APS-C BSI (STARVIS)",
40
+ "info": "Gold standard APS-C. Excellent balance for broadband.",
41
+ },
42
+ "sensor:Sony IMX533 (ASI533)": {
43
+ "method": "custom",
44
+ "weights": np.array([0.2910, 0.5072, 0.2018], dtype=np.float32),
45
+ "category": "Sensors/Sony Modern BSI",
46
+ "description": "Sony IMX533 9MP 1\" Square BSI (STARVIS)",
47
+ "info": "Popular square format. Very low noise.",
48
+ },
49
+ "sensor:Sony IMX455 (ASI6200/QHY600)": {
50
+ "weights": (0.2987, 0.5001, 0.2013),
51
+ "description": "Sony IMX455 61MP Full Frame BSI (STARVIS)",
52
+ "info": "Full frame reference sensor.",
53
+ "category": "Sony / Modern BSI",
54
+ },
55
+ "sensor:Sony IMX294 (ASI294)": {
56
+ "weights": (0.3068, 0.5008, 0.1925),
57
+ "description": "Sony IMX294 11.7MP 4/3\" BSI",
58
+ "info": "High sensitivity 4/3 format.",
59
+ "category": "Sony / Modern BSI",
60
+ },
61
+ "sensor:Sony IMX183 (ASI183)": {
62
+ "weights": (0.2967, 0.4983, 0.2050),
63
+ "description": "Sony IMX183 20MP 1\" BSI",
64
+ "info": "High resolution 1-inch sensor.",
65
+ "category": "Sony / Modern BSI",
66
+ },
67
+ "sensor:Sony IMX178 (ASI178)": {
68
+ "weights": (0.2346, 0.5206, 0.2448),
69
+ "description": "Sony IMX178 6.4MP 1/1.8\" BSI",
70
+ "info": "High resolution entry-level sensor.",
71
+ "category": "Sony / Modern BSI",
72
+ },
73
+ "sensor:Sony IMX224 (ASI224)": {
74
+ "weights": (0.3402, 0.4765, 0.1833),
75
+ "description": "Sony IMX224 1.27MP 1/3\" BSI",
76
+ "info": "Classic planetary sensor. High Red response.",
77
+ "category": "Sony / Modern BSI",
78
+ },
79
+
80
+ # --- SONY STARVIS 2 (NIR Optimized) ---
81
+ "sensor:Sony IMX585 (ASI585) - STARVIS 2": {
82
+ "weights": (0.3431, 0.4822, 0.1747),
83
+ "description": "Sony IMX585 8.3MP 1/1.2\" BSI (STARVIS 2)",
84
+ "info": "NIR optimized. Excellent for H-Alpha/Narrowband.",
85
+ "category": "Sony / STARVIS 2",
86
+ },
87
+ "sensor:Sony IMX662 (ASI662) - STARVIS 2": {
88
+ "weights": (0.3430, 0.4821, 0.1749),
89
+ "description": "Sony IMX662 2.1MP 1/2.8\" BSI (STARVIS 2)",
90
+ "info": "Planetary/Guiding. High Red/NIR sensitivity.",
91
+ "category": "Sony / STARVIS 2",
92
+ },
93
+ "sensor:Sony IMX678/715 - STARVIS 2": {
94
+ "weights": (0.3426, 0.4825, 0.1750),
95
+ "description": "Sony IMX678/715 BSI (STARVIS 2)",
96
+ "info": "High resolution planetary/security sensors.",
97
+ "category": "Sony / STARVIS 2",
98
+ },
99
+
100
+ # --- PANASONIC / OTHERS ---
101
+ "sensor:Panasonic MN34230 (ASI1600/QHY163)": {
102
+ "weights": (0.2650, 0.5250, 0.2100),
103
+ "description": "Panasonic MN34230 4/3\" CMOS",
104
+ "info": "Classic Mono/OSC sensor. Optimized weights.",
105
+ "category": "Panasonic",
106
+ },
107
+
108
+ # --- CANON DSLR (Averaged Profiles) ---
109
+ "sensor:Canon EOS (Modern - 60D/6D/R)": {
110
+ "weights": (0.2550, 0.5250, 0.2200),
111
+ "description": "Canon CMOS Profile (Modern)",
112
+ "info": "Balanced profile for most Canon EOS cameras (60D, 6D, 5D, R-series).",
113
+ "category": "Canon",
114
+ },
115
+ "sensor:Canon EOS (Legacy - 300D/40D)": {
116
+ "weights": (0.2400, 0.5400, 0.2200),
117
+ "description": "Canon CMOS Profile (Legacy)",
118
+ "info": "For older Canon models (Digic 2/3 era).",
119
+ "category": "Canon",
120
+ },
121
+
122
+ # --- NIKON DSLR (Averaged Profiles) ---
123
+ "sensor:Nikon DSLR (Modern - D5300/D850)": {
124
+ "weights": (0.2600, 0.5100, 0.2300),
125
+ "description": "Nikon CMOS Profile (Modern)",
126
+ "info": "Balanced profile for Nikon Expeed 4+ cameras.",
127
+ "category": "Nikon",
128
+ },
129
+
130
+ # --- SMART TELESCOPES ---
131
+ "sensor:ZWO Seestar S50": {
132
+ "weights": (0.3333, 0.4866, 0.1801),
133
+ "description": "ZWO Seestar S50 (IMX462)",
134
+ "info": "Specific profile for Seestar S50 smart telescope.",
135
+ "category": "Smart Telescopes",
136
+ },
137
+ "sensor:ZWO Seestar S30": {
138
+ "weights": (0.2928, 0.5053, 0.2019),
139
+ "description": "ZWO Seestar S30",
140
+ "info": "Specific profile for Seestar S30 smart telescope.",
141
+ "category": "Smart Telescopes",
142
+ },
143
+ }
144
+
145
+
146
+ # ---------- helpers ----------
147
+ def resolve_luma_profile_weights(mode: str | None):
148
+ """
149
+ Returns (resolved_method, weights_or_None, profile_name_or_None)
150
+
151
+ - Standard modes return (mode, None or standard weights, None)
152
+ - Sensor profiles return ("custom", weights, <profile display name>)
153
+ """
154
+ if mode is None:
155
+ mode = "rec709"
156
+ key = str(mode).strip()
157
+
158
+ # common aliases
159
+ alias = {
160
+ "rec.709": "rec709",
161
+ "rec-709": "rec709",
162
+ "rgb": "rec709",
163
+ "k": "rec709",
164
+ "rec.601": "rec601",
165
+ "rec-601": "rec601",
166
+ "rec.2020": "rec2020",
167
+ "rec-2020": "rec2020",
168
+ "nb_max": "max",
169
+ "narrowband": "max",
170
+ "snr_unequal": "snr",
171
+ "unequal_noise": "snr",
172
+ }
173
+ key = alias.get(key.lower(), key)
174
+
175
+ prof = LUMA_PROFILES.get(key)
176
+ if not prof:
177
+ # fallback
178
+ return ("rec709", _LUMA_REC709, None)
179
+
180
+ method = str(prof.get("method", "rec709")).strip().lower()
181
+ w = prof.get("weights", None)
182
+ if w is not None:
183
+ w = np.asarray(w, dtype=np.float32)
184
+
185
+ if key.startswith("sensor:"):
186
+ # Use "custom" path in compute_luminance by passing weights
187
+ # We'll return resolved_method="rec709" (ignored) and weights=w
188
+ # BUT to keep your API simple: return ("rec709", w, profile_name)
189
+ profile_name = key.split("sensor:", 1)[1].strip()
190
+ return ("rec709", w, profile_name)
191
+
192
+ # Standard modes
193
+ return (key, w, None)
194
+
195
+
196
+ def _estimate_noise_sigma_per_channel(img01: np.ndarray) -> np.ndarray:
197
+ # unchanged (but call with strict input)
198
+ a = img01
199
+ if a.ndim == 2:
200
+ a = a[..., None]
201
+ a = a[::4, ::4, :].astype(np.float32, copy=False)
202
+ med = np.median(a, axis=(0,1))
203
+ mad = np.median(np.abs(a - med), axis=(0,1))
204
+ sigma = 1.4826 * mad
205
+ sigma[sigma <= 1e-12] = 1e-12
206
+ return sigma.astype(np.float32)
207
+
208
+ # ---------- luminance compute (linear) ----------
209
+
210
+ def compute_luminance(
211
+ img: np.ndarray,
212
+ method: str | None = "rec709",
213
+ weights: Optional[np.ndarray] = None,
214
+ noise_sigma: Optional[np.ndarray] = None,
215
+ normalize_weights: bool = True
216
+ ) -> np.ndarray:
217
+ """
218
+ Returns 2-D linear luminance Y in [0,1] (float32).
219
+ No per-image normalization. If custom `weights` are supplied and
220
+ `normalize_weights=False`, their absolute sum is respected.
221
+ """
222
+ f = _to_float01_strict(img)
223
+
224
+ if f.ndim == 2:
225
+ return np.ascontiguousarray(f.astype(np.float32, copy=False))
226
+ if f.ndim != 3:
227
+ raise ValueError("compute_luminance: expected 2-D or 3-D array.")
228
+
229
+ H, W, C = f.shape
230
+ if C == 1:
231
+ return np.ascontiguousarray(f[..., 0].astype(np.float32, copy=False))
232
+
233
+ if weights is not None:
234
+ w = np.asarray(weights, dtype=np.float32)
235
+ if w.ndim != 1 or w.size not in (C, 3):
236
+ raise ValueError("weights must be 1-D with length equal to channel count or 3.")
237
+ if normalize_weights:
238
+ s = float(w.sum())
239
+ if s != 0.0:
240
+ w = w / s
241
+ useC = w.size
242
+ lum = np.tensordot(f[..., :useC], w, axes=([2], [0]))
243
+ elif method == "equal":
244
+ lum = f[..., :3].mean(axis=2)
245
+ elif method == "snr":
246
+ if noise_sigma is None:
247
+ raise ValueError("snr method requires noise_sigma per channel.")
248
+ ns = np.asarray(noise_sigma, dtype=np.float32)
249
+ if ns.ndim != 1 or ns.size not in (C, 3):
250
+ raise ValueError("noise_sigma must be 1-D with length equal to channel count or 3.")
251
+ useC = ns.size
252
+ w = 1.0 / (ns[:useC]**2 + 1e-12)
253
+ w = w / w.sum()
254
+ lum = np.tensordot(f[..., :useC], w, axes=([2],[0]))
255
+ elif method == "max":
256
+ lum = f.max(axis=2)
257
+ elif method == "median":
258
+ lum = np.median(f, axis=2)
259
+ elif method == "rec601":
260
+ lum = np.tensordot(f[..., :3], _LUMA_REC601, axes=([2],[0]))
261
+ elif method == "rec2020":
262
+ lum = np.tensordot(f[..., :3], _LUMA_REC2020, axes=([2],[0]))
263
+ else: # default rec709
264
+ lum = np.tensordot(f[..., :3], _LUMA_REC709, axes=([2],[0]))
265
+
266
+ return np.clip(lum.astype(np.float32, copy=False), 0.0, 1.0)
267
+
268
+ # ---------- luminance recombine (linear scaling) ----------
269
+
270
+ def recombine_luminance_linear_scale(
271
+ target_rgb: np.ndarray,
272
+ new_L: np.ndarray,
273
+ weights: np.ndarray = _LUMA_REC709,
274
+ eps: float = 1e-6,
275
+ blend: float = 1.0, # 0..1, 1=full replace
276
+ highlight_soft_knee: float = 0.0 # 0..1, optional protection
277
+ ) -> np.ndarray:
278
+ """
279
+ Replace linear luminance Y (w·RGB) with `new_L` by per-pixel scaling:
280
+ s = new_L / (Y + eps); RGB' = RGB * s
281
+ This preserves hue/chroma in linear space and round-trips when new_L==Y.
282
+ Optional: blend (mix with original) and highlight soft-knee protection.
283
+ """
284
+ rgb = _to_float01_strict(target_rgb)
285
+ if rgb.ndim != 3 or rgb.shape[2] != 3:
286
+ raise ValueError("Recombine Luminance requires an RGB target image.")
287
+
288
+ H, W, _ = rgb.shape
289
+ L = new_L.astype(np.float32)
290
+ if L.shape[:2] != (H, W):
291
+ L = cv2.resize(L, (W, H), interpolation=cv2.INTER_LINEAR)
292
+
293
+ w = np.asarray(weights, dtype=np.float32)
294
+ if w.shape != (3,):
295
+ raise ValueError("weights must be length-3 for RGB recombine.")
296
+
297
+ # current Y
298
+ Y = rgb[..., 0]*w[0] + rgb[..., 1]*w[1] + rgb[..., 2]*w[2]
299
+ s = L / (Y + eps)
300
+
301
+ if highlight_soft_knee > 0.0:
302
+ # compress extreme upsizing to avoid blowing out tiny Y
303
+ # knee in [0..1], higher = more protection
304
+ k = np.clip(highlight_soft_knee, 0.0, 1.0)
305
+ s = s / (1.0 + k*(s - 1.0))
306
+
307
+ out = rgb * s[..., None]
308
+ out = np.clip(out, 0.0, 1.0)
309
+
310
+ if 0.0 <= blend < 1.0:
311
+ out = rgb*(1.0 - blend) + out*blend
312
+
313
+ return out.astype(np.float32, copy=False)
314
+
315
+ def _resolve_active_doc_from(main, target_doc=None):
316
+ doc = target_doc
317
+ if doc is None:
318
+ d = getattr(main, "_active_doc", None)
319
+ doc = d() if callable(d) else d
320
+ doc = unwrap_docproxy(doc)
321
+ return doc
322
+
323
+
324
+ def apply_recombine_to_doc(
325
+ target_doc,
326
+ luminance_source_img: np.ndarray,
327
+ method: str = "rec709",
328
+ weights: Optional[np.ndarray] = None,
329
+ noise_sigma: Optional[np.ndarray] = None,
330
+ blend: float = 1.0,
331
+ soft_knee: float = 0.0
332
+ ):
333
+ """
334
+ Overwrite target_doc.image by recombining with luminance from source (RGB or mono).
335
+ Uses linear scaling recombine; honors destination mask if present.
336
+ """
337
+ base = _to_float01_strict(np.asarray(target_doc.image))
338
+
339
+ # Resolve profile (sensor profiles return weights w)
340
+ resolved_method, w, profile_name = resolve_luma_profile_weights(method)
341
+
342
+ # Caller override for weights wins (useful for custom UI / scripts)
343
+ if weights is not None:
344
+ w = np.asarray(weights, dtype=np.float32).reshape(-1)
345
+ if w.size != 3:
346
+ raise ValueError("weights must be a 3-element RGB vector")
347
+ elif w is not None:
348
+ w = np.asarray(w, dtype=np.float32).reshape(-1)
349
+ if w.size != 3:
350
+ w = None # ignore bad profile weights defensively
351
+
352
+ # Build L (mono source passes through; RGB is weighted)
353
+ src = _to_float01_strict(luminance_source_img)
354
+ if src.ndim == 2 or (src.ndim == 3 and src.shape[2] == 1):
355
+ L = src if src.ndim == 2 else src[..., 0]
356
+ # For mono L sources, we still want recombine weights to match the selected method/profile.
357
+ else:
358
+ # Noise sigma: if caller provided, use it; otherwise estimate when needed
359
+ ns = None
360
+ if resolved_method == "snr":
361
+ if noise_sigma is not None:
362
+ ns = np.asarray(noise_sigma, dtype=np.float32).reshape(-1)
363
+ else:
364
+ ns = _estimate_noise_sigma_per_channel(src)
365
+
366
+ # compute_luminance respects weights override; for sensor/custom profiles w is used
367
+ L = compute_luminance(src, method=resolved_method, weights=w, noise_sigma=ns)
368
+
369
+ # For scaling recombine, we need an actual RGB weight vector.
370
+ # If we don't have one from the chosen mode/profile, fall back sensibly.
371
+ if w is not None and w.size == 3:
372
+ recombine_w = w
373
+ else:
374
+ # If your resolver returns w=None for rec709/rec601/rec2020, fill explicitly here:
375
+ if resolved_method == "rec601":
376
+ recombine_w = _LUMA_REC601
377
+ elif resolved_method == "rec2020":
378
+ recombine_w = _LUMA_REC2020
379
+ else:
380
+ recombine_w = _LUMA_REC709
381
+
382
+ replaced = recombine_luminance_linear_scale(
383
+ base,
384
+ L,
385
+ weights=recombine_w,
386
+ blend=float(blend),
387
+ highlight_soft_knee=float(soft_knee),
388
+ )
389
+
390
+ # Metadata
391
+ md = {"step_name": "Recombine Luminance", "luma_method": resolved_method}
392
+ if profile_name:
393
+ md["luma_profile"] = profile_name
394
+ if w is not None:
395
+ md["luma_weights"] = np.asarray(w, dtype=np.float32).tolist()
396
+
397
+ target_doc.apply_edit(replaced.astype(np.float32, copy=False), metadata=md, step_name="Recombine Luminance")
398
+
399
+
400
+ def run_recombine_luminance_via_preset(main_or_ctx, preset=None, target_doc=None):
401
+ """
402
+ Headless entrypoint for recombine_luminance.
403
+
404
+ preset supports:
405
+ - source_doc_ptr: int (id(doc)) [highest priority]
406
+ - source_title: str [next priority]
407
+ - method, weights, blend, soft_knee (existing)
408
+ If neither source_* is given, first eligible non-target open doc is used.
409
+ """
410
+ from setiastro.saspro.luminancerecombine import apply_recombine_to_doc
411
+
412
+ p = dict(preset or {})
413
+ main, doc, dm = normalize_headless_main(main_or_ctx, target_doc)
414
+
415
+ # ---- Validate target ----
416
+ if doc is None or getattr(doc, "image", None) is None:
417
+ raise CommandError("recombine_luminance: no active RGB ImageDocument. Load an image first.")
418
+
419
+ # ---- Collect open docs (unwrapped) ----
420
+ open_docs = []
421
+ if dm is not None:
422
+ try:
423
+ if hasattr(dm, "all_documents") and callable(dm.all_documents):
424
+ open_docs = [unwrap_docproxy(d) for d in dm.all_documents()]
425
+ elif hasattr(dm, "_docs"):
426
+ open_docs = [unwrap_docproxy(d) for d in dm._docs]
427
+ except Exception:
428
+ open_docs = []
429
+
430
+ # Filter to docs that look like images
431
+ def _has_image(d):
432
+ return d is not None and getattr(d, "image", None) is not None
433
+
434
+ open_docs = [d for d in open_docs if _has_image(d)]
435
+
436
+ # ---- Resolve luminance source ----
437
+ src_doc = None
438
+
439
+ # 1) source_doc_ptr
440
+ src_ptr = p.get("source_doc_ptr", None)
441
+ if src_ptr is not None:
442
+ try:
443
+ src_ptr = int(src_ptr)
444
+ for d in open_docs:
445
+ if id(d) == src_ptr:
446
+ src_doc = d
447
+ break
448
+ except Exception:
449
+ src_doc = None
450
+
451
+ # 2) source_title
452
+ if src_doc is None:
453
+ st = p.get("source_title", None)
454
+ if st:
455
+ st_low = str(st).strip().lower()
456
+
457
+ def _title_of(d):
458
+ # prefer display_name() if available
459
+ try:
460
+ if hasattr(d, "display_name") and callable(d.display_name):
461
+ return str(d.display_name())
462
+ except Exception:
463
+ pass
464
+ # fallback to metadata display_name or file basename
465
+ try:
466
+ md = getattr(d, "metadata", {}) or {}
467
+ if md.get("display_name"):
468
+ return str(md["display_name"])
469
+ fp = md.get("file_path")
470
+ if fp:
471
+ import os
472
+ return os.path.basename(fp)
473
+ except Exception:
474
+ pass
475
+ return ""
476
+
477
+ for d in open_docs:
478
+ if d is doc:
479
+ continue
480
+ if _title_of(d).lower() == st_low:
481
+ src_doc = d
482
+ break
483
+
484
+ # 3) auto-pick first eligible non-target doc
485
+ if src_doc is None:
486
+ for d in open_docs:
487
+ if d is doc:
488
+ continue
489
+ src_doc = d
490
+ break
491
+
492
+ if src_doc is None:
493
+ raise CommandError(
494
+ "recombine_luminance: no luminance source found. "
495
+ "Open another image, or pass preset {'source_title': ...} "
496
+ "or {'source_doc_ptr': id(doc)}."
497
+ )
498
+
499
+ # ---- Execute recombine ----
500
+ src_img = np.asarray(src_doc.image)
501
+
502
+ apply_recombine_to_doc(
503
+ doc,
504
+ src_img,
505
+ method=p.get("method", "rec709"),
506
+ weights=p.get("weights", None),
507
+ blend=float(p.get("blend", 1.0)),
508
+ soft_knee=float(p.get("soft_knee", 0.0)),
509
+ )
510
+