scitex 2.7.0__py3-none-any.whl → 2.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.
Files changed (297) hide show
  1. scitex/__init__.py +6 -2
  2. scitex/__version__.py +1 -1
  3. scitex/audio/README.md +52 -0
  4. scitex/audio/__init__.py +384 -0
  5. scitex/audio/__main__.py +129 -0
  6. scitex/audio/_tts.py +334 -0
  7. scitex/audio/engines/__init__.py +44 -0
  8. scitex/audio/engines/base.py +275 -0
  9. scitex/audio/engines/elevenlabs_engine.py +143 -0
  10. scitex/audio/engines/gtts_engine.py +162 -0
  11. scitex/audio/engines/pyttsx3_engine.py +131 -0
  12. scitex/audio/mcp_server.py +757 -0
  13. scitex/bridge/_helpers.py +1 -1
  14. scitex/bridge/_plt_vis.py +1 -1
  15. scitex/bridge/_stats_vis.py +1 -1
  16. scitex/dev/plt/__init__.py +272 -0
  17. scitex/dev/plt/plot_mpl_axhline.py +28 -0
  18. scitex/dev/plt/plot_mpl_axhspan.py +28 -0
  19. scitex/dev/plt/plot_mpl_axvline.py +28 -0
  20. scitex/dev/plt/plot_mpl_axvspan.py +28 -0
  21. scitex/dev/plt/plot_mpl_bar.py +29 -0
  22. scitex/dev/plt/plot_mpl_barh.py +29 -0
  23. scitex/dev/plt/plot_mpl_boxplot.py +28 -0
  24. scitex/dev/plt/plot_mpl_contour.py +31 -0
  25. scitex/dev/plt/plot_mpl_contourf.py +31 -0
  26. scitex/dev/plt/plot_mpl_errorbar.py +30 -0
  27. scitex/dev/plt/plot_mpl_eventplot.py +28 -0
  28. scitex/dev/plt/plot_mpl_fill.py +30 -0
  29. scitex/dev/plt/plot_mpl_fill_between.py +31 -0
  30. scitex/dev/plt/plot_mpl_hexbin.py +28 -0
  31. scitex/dev/plt/plot_mpl_hist.py +28 -0
  32. scitex/dev/plt/plot_mpl_hist2d.py +28 -0
  33. scitex/dev/plt/plot_mpl_imshow.py +29 -0
  34. scitex/dev/plt/plot_mpl_pcolormesh.py +31 -0
  35. scitex/dev/plt/plot_mpl_pie.py +29 -0
  36. scitex/dev/plt/plot_mpl_plot.py +29 -0
  37. scitex/dev/plt/plot_mpl_quiver.py +31 -0
  38. scitex/dev/plt/plot_mpl_scatter.py +28 -0
  39. scitex/dev/plt/plot_mpl_stackplot.py +31 -0
  40. scitex/dev/plt/plot_mpl_stem.py +29 -0
  41. scitex/dev/plt/plot_mpl_step.py +29 -0
  42. scitex/dev/plt/plot_mpl_violinplot.py +28 -0
  43. scitex/dev/plt/plot_sns_barplot.py +29 -0
  44. scitex/dev/plt/plot_sns_boxplot.py +29 -0
  45. scitex/dev/plt/plot_sns_heatmap.py +28 -0
  46. scitex/dev/plt/plot_sns_histplot.py +29 -0
  47. scitex/dev/plt/plot_sns_kdeplot.py +29 -0
  48. scitex/dev/plt/plot_sns_lineplot.py +31 -0
  49. scitex/dev/plt/plot_sns_scatterplot.py +29 -0
  50. scitex/dev/plt/plot_sns_stripplot.py +29 -0
  51. scitex/dev/plt/plot_sns_swarmplot.py +29 -0
  52. scitex/dev/plt/plot_sns_violinplot.py +29 -0
  53. scitex/dev/plt/plot_stx_bar.py +29 -0
  54. scitex/dev/plt/plot_stx_barh.py +29 -0
  55. scitex/dev/plt/plot_stx_box.py +28 -0
  56. scitex/dev/plt/plot_stx_boxplot.py +28 -0
  57. scitex/dev/plt/plot_stx_conf_mat.py +28 -0
  58. scitex/dev/plt/plot_stx_contour.py +31 -0
  59. scitex/dev/plt/plot_stx_ecdf.py +28 -0
  60. scitex/dev/plt/plot_stx_errorbar.py +30 -0
  61. scitex/dev/plt/plot_stx_fill_between.py +31 -0
  62. scitex/dev/plt/plot_stx_fillv.py +28 -0
  63. scitex/dev/plt/plot_stx_heatmap.py +28 -0
  64. scitex/dev/plt/plot_stx_image.py +28 -0
  65. scitex/dev/plt/plot_stx_imshow.py +28 -0
  66. scitex/dev/plt/plot_stx_joyplot.py +28 -0
  67. scitex/dev/plt/plot_stx_kde.py +28 -0
  68. scitex/dev/plt/plot_stx_line.py +28 -0
  69. scitex/dev/plt/plot_stx_mean_ci.py +28 -0
  70. scitex/dev/plt/plot_stx_mean_std.py +28 -0
  71. scitex/dev/plt/plot_stx_median_iqr.py +28 -0
  72. scitex/dev/plt/plot_stx_raster.py +28 -0
  73. scitex/dev/plt/plot_stx_rectangle.py +28 -0
  74. scitex/dev/plt/plot_stx_scatter.py +29 -0
  75. scitex/dev/plt/plot_stx_shaded_line.py +29 -0
  76. scitex/dev/plt/plot_stx_violin.py +28 -0
  77. scitex/dev/plt/plot_stx_violinplot.py +28 -0
  78. scitex/fig/__init__.py +352 -0
  79. scitex/{vis → fig}/backend/_parser.py +1 -1
  80. scitex/{vis → fig}/canvas.py +1 -1
  81. scitex/{vis → fig}/editor/_defaults.py +70 -5
  82. scitex/fig/editor/_edit.py +751 -0
  83. scitex/{vis → fig}/editor/_qt_editor.py +181 -1
  84. scitex/fig/editor/flask_editor/_bbox.py +1276 -0
  85. scitex/fig/editor/flask_editor/_core.py +624 -0
  86. scitex/{vis → fig}/editor/flask_editor/_plotter.py +38 -4
  87. scitex/fig/editor/flask_editor/_renderer.py +739 -0
  88. scitex/{vis → fig}/editor/flask_editor/templates/__init__.py +1 -1
  89. scitex/fig/editor/flask_editor/templates/_html.py +834 -0
  90. scitex/fig/editor/flask_editor/templates/_scripts.py +3136 -0
  91. scitex/{vis → fig}/editor/flask_editor/templates/_styles.py +625 -18
  92. scitex/{vis → fig}/io/__init__.py +13 -1
  93. scitex/fig/io/_bundle.py +973 -0
  94. scitex/{vis → fig}/io/_canvas.py +1 -1
  95. scitex/{vis → fig}/io/_data.py +1 -1
  96. scitex/{vis → fig}/io/_export.py +1 -1
  97. scitex/{vis → fig}/io/_load.py +1 -1
  98. scitex/{vis → fig}/io/_panel.py +1 -1
  99. scitex/{vis → fig}/io/_save.py +1 -1
  100. scitex/{vis → fig}/model/__init__.py +1 -1
  101. scitex/{vis → fig}/model/_annotations.py +1 -1
  102. scitex/{vis → fig}/model/_axes.py +1 -1
  103. scitex/{vis → fig}/model/_figure.py +1 -1
  104. scitex/{vis → fig}/model/_guides.py +1 -1
  105. scitex/{vis → fig}/model/_plot.py +1 -1
  106. scitex/{vis → fig}/model/_styles.py +1 -1
  107. scitex/{vis → fig}/utils/__init__.py +1 -1
  108. scitex/io/__init__.py +10 -26
  109. scitex/io/_bundle.py +434 -0
  110. scitex/io/_flush.py +5 -2
  111. scitex/io/_load.py +98 -0
  112. scitex/io/_load_modules/_H5Explorer.py +5 -2
  113. scitex/io/_load_modules/_canvas.py +2 -2
  114. scitex/io/_load_modules/_image.py +3 -4
  115. scitex/io/_load_modules/_txt.py +4 -2
  116. scitex/io/_metadata.py +34 -324
  117. scitex/io/_metadata_modules/__init__.py +46 -0
  118. scitex/io/_metadata_modules/_embed.py +70 -0
  119. scitex/io/_metadata_modules/_read.py +64 -0
  120. scitex/io/_metadata_modules/_utils.py +79 -0
  121. scitex/io/_metadata_modules/embed_metadata_jpeg.py +74 -0
  122. scitex/io/_metadata_modules/embed_metadata_pdf.py +53 -0
  123. scitex/io/_metadata_modules/embed_metadata_png.py +26 -0
  124. scitex/io/_metadata_modules/embed_metadata_svg.py +62 -0
  125. scitex/io/_metadata_modules/read_metadata_jpeg.py +57 -0
  126. scitex/io/_metadata_modules/read_metadata_pdf.py +51 -0
  127. scitex/io/_metadata_modules/read_metadata_png.py +39 -0
  128. scitex/io/_metadata_modules/read_metadata_svg.py +44 -0
  129. scitex/io/_qr_utils.py +5 -3
  130. scitex/io/_save.py +548 -30
  131. scitex/io/_save_modules/_canvas.py +3 -3
  132. scitex/io/_save_modules/_image.py +5 -9
  133. scitex/io/_save_modules/_tex.py +7 -4
  134. scitex/io/utils/h5_to_zarr.py +11 -9
  135. scitex/msword/__init__.py +255 -0
  136. scitex/msword/profiles.py +357 -0
  137. scitex/msword/reader.py +753 -0
  138. scitex/msword/utils.py +289 -0
  139. scitex/msword/writer.py +362 -0
  140. scitex/plt/__init__.py +5 -2
  141. scitex/plt/_subplots/_AxesWrapper.py +6 -6
  142. scitex/plt/_subplots/_AxisWrapper.py +15 -9
  143. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/__init__.py +36 -0
  144. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/_labels.py +264 -0
  145. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/_metadata.py +213 -0
  146. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin/_visual.py +128 -0
  147. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/__init__.py +59 -0
  148. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_base.py +34 -0
  149. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_scientific.py +593 -0
  150. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_statistical.py +654 -0
  151. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/_stx_aliases.py +527 -0
  152. scitex/plt/_subplots/_AxisWrapperMixins/_RawMatplotlibMixin.py +321 -0
  153. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/__init__.py +33 -0
  154. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/_base.py +152 -0
  155. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin/_wrappers.py +600 -0
  156. scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +79 -5
  157. scitex/plt/_subplots/_FigWrapper.py +6 -6
  158. scitex/plt/_subplots/_SubplotsWrapper.py +28 -18
  159. scitex/plt/_subplots/_export_as_csv.py +35 -5
  160. scitex/plt/_subplots/_export_as_csv_formatters/__init__.py +8 -0
  161. scitex/plt/_subplots/_export_as_csv_formatters/_format_annotate.py +10 -21
  162. scitex/plt/_subplots/_export_as_csv_formatters/_format_eventplot.py +18 -7
  163. scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow2d.py +28 -12
  164. scitex/plt/_subplots/_export_as_csv_formatters/_format_matshow.py +10 -4
  165. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_imshow.py +13 -1
  166. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_kde.py +12 -2
  167. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter.py +10 -3
  168. scitex/plt/_subplots/_export_as_csv_formatters/_format_quiver.py +10 -4
  169. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_jointplot.py +18 -3
  170. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_lineplot.py +44 -36
  171. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_pairplot.py +14 -2
  172. scitex/plt/_subplots/_export_as_csv_formatters/_format_streamplot.py +11 -5
  173. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_bar.py +84 -0
  174. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_barh.py +85 -0
  175. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_conf_mat.py +14 -3
  176. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_contour.py +54 -0
  177. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_ecdf.py +14 -2
  178. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_errorbar.py +120 -0
  179. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_heatmap.py +16 -6
  180. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_image.py +29 -19
  181. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_imshow.py +63 -0
  182. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_joyplot.py +22 -5
  183. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_mean_ci.py +18 -14
  184. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_mean_std.py +18 -14
  185. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_median_iqr.py +18 -14
  186. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_raster.py +10 -2
  187. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_scatter.py +51 -0
  188. scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_scatter_hist.py +18 -9
  189. scitex/plt/ax/_plot/_stx_ecdf.py +4 -2
  190. scitex/plt/gallery/_generate.py +421 -14
  191. scitex/plt/io/__init__.py +53 -0
  192. scitex/plt/io/_bundle.py +490 -0
  193. scitex/plt/io/_layered_bundle.py +1343 -0
  194. scitex/plt/styles/SCITEX_STYLE.yaml +26 -0
  195. scitex/plt/styles/__init__.py +14 -0
  196. scitex/plt/styles/presets.py +78 -0
  197. scitex/plt/utils/__init__.py +13 -1
  198. scitex/plt/utils/_collect_figure_metadata.py +10 -14
  199. scitex/plt/utils/_configure_mpl.py +6 -18
  200. scitex/plt/utils/_crop.py +32 -14
  201. scitex/plt/utils/_csv_column_naming.py +54 -0
  202. scitex/plt/utils/_figure_mm.py +116 -1
  203. scitex/plt/utils/_hitmap.py +1643 -0
  204. scitex/plt/utils/metadata/__init__.py +25 -0
  205. scitex/plt/utils/metadata/_core.py +9 -10
  206. scitex/plt/utils/metadata/_dimensions.py +6 -3
  207. scitex/plt/utils/metadata/_editable_export.py +405 -0
  208. scitex/plt/utils/metadata/_geometry_extraction.py +570 -0
  209. scitex/schema/__init__.py +109 -16
  210. scitex/schema/_canvas.py +1 -1
  211. scitex/schema/_plot.py +1015 -0
  212. scitex/schema/_stats.py +2 -2
  213. scitex/stats/__init__.py +117 -0
  214. scitex/stats/io/__init__.py +29 -0
  215. scitex/stats/io/_bundle.py +156 -0
  216. scitex/tex/__init__.py +4 -0
  217. scitex/tex/_export.py +890 -0
  218. {scitex-2.7.0.dist-info → scitex-2.7.3.dist-info}/METADATA +11 -1
  219. {scitex-2.7.0.dist-info → scitex-2.7.3.dist-info}/RECORD +238 -170
  220. scitex/io/memo.md +0 -2827
  221. scitex/plt/REQUESTS.md +0 -191
  222. scitex/plt/_subplots/TODO.md +0 -53
  223. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin.py +0 -559
  224. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin.py +0 -1609
  225. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin.py +0 -447
  226. scitex/plt/templates/research-master/scitex/vis/gallery/area/fill_between.json +0 -110
  227. scitex/plt/templates/research-master/scitex/vis/gallery/area/fill_betweenx.json +0 -88
  228. scitex/plt/templates/research-master/scitex/vis/gallery/area/stx_fill_between.json +0 -103
  229. scitex/plt/templates/research-master/scitex/vis/gallery/area/stx_fillv.json +0 -106
  230. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/bar.json +0 -92
  231. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/barh.json +0 -92
  232. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/boxplot.json +0 -92
  233. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_bar.json +0 -84
  234. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_barh.json +0 -84
  235. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_box.json +0 -83
  236. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_boxplot.json +0 -93
  237. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_violin.json +0 -91
  238. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_violinplot.json +0 -91
  239. scitex/plt/templates/research-master/scitex/vis/gallery/categorical/violinplot.json +0 -91
  240. scitex/plt/templates/research-master/scitex/vis/gallery/contour/contour.json +0 -97
  241. scitex/plt/templates/research-master/scitex/vis/gallery/contour/contourf.json +0 -98
  242. scitex/plt/templates/research-master/scitex/vis/gallery/contour/stx_contour.json +0 -84
  243. scitex/plt/templates/research-master/scitex/vis/gallery/distribution/hist.json +0 -101
  244. scitex/plt/templates/research-master/scitex/vis/gallery/distribution/hist2d.json +0 -96
  245. scitex/plt/templates/research-master/scitex/vis/gallery/distribution/stx_ecdf.json +0 -95
  246. scitex/plt/templates/research-master/scitex/vis/gallery/distribution/stx_joyplot.json +0 -95
  247. scitex/plt/templates/research-master/scitex/vis/gallery/distribution/stx_kde.json +0 -93
  248. scitex/plt/templates/research-master/scitex/vis/gallery/grid/imshow.json +0 -95
  249. scitex/plt/templates/research-master/scitex/vis/gallery/grid/matshow.json +0 -95
  250. scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_conf_mat.json +0 -83
  251. scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_heatmap.json +0 -92
  252. scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_image.json +0 -121
  253. scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_imshow.json +0 -84
  254. scitex/plt/templates/research-master/scitex/vis/gallery/line/plot.json +0 -110
  255. scitex/plt/templates/research-master/scitex/vis/gallery/line/step.json +0 -92
  256. scitex/plt/templates/research-master/scitex/vis/gallery/line/stx_line.json +0 -95
  257. scitex/plt/templates/research-master/scitex/vis/gallery/line/stx_shaded_line.json +0 -96
  258. scitex/plt/templates/research-master/scitex/vis/gallery/scatter/hexbin.json +0 -95
  259. scitex/plt/templates/research-master/scitex/vis/gallery/scatter/scatter.json +0 -95
  260. scitex/plt/templates/research-master/scitex/vis/gallery/scatter/stem.json +0 -92
  261. scitex/plt/templates/research-master/scitex/vis/gallery/scatter/stx_scatter.json +0 -84
  262. scitex/plt/templates/research-master/scitex/vis/gallery/special/pie.json +0 -94
  263. scitex/plt/templates/research-master/scitex/vis/gallery/special/stx_raster.json +0 -109
  264. scitex/plt/templates/research-master/scitex/vis/gallery/special/stx_rectangle.json +0 -108
  265. scitex/plt/templates/research-master/scitex/vis/gallery/statistical/errorbar.json +0 -93
  266. scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_errorbar.json +0 -84
  267. scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_mean_ci.json +0 -96
  268. scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_mean_std.json +0 -96
  269. scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_median_iqr.json +0 -96
  270. scitex/plt/templates/research-master/scitex/vis/gallery/vector/quiver.json +0 -99
  271. scitex/plt/templates/research-master/scitex/vis/gallery/vector/streamplot.json +0 -100
  272. scitex/vis/__init__.py +0 -177
  273. scitex/vis/editor/_edit.py +0 -390
  274. scitex/vis/editor/flask_editor/_bbox.py +0 -529
  275. scitex/vis/editor/flask_editor/_core.py +0 -168
  276. scitex/vis/editor/flask_editor/_renderer.py +0 -393
  277. scitex/vis/editor/flask_editor/templates/_html.py +0 -513
  278. scitex/vis/editor/flask_editor/templates/_scripts.py +0 -1261
  279. /scitex/{vis → fig}/README.md +0 -0
  280. /scitex/{vis → fig}/backend/__init__.py +0 -0
  281. /scitex/{vis → fig}/backend/_export.py +0 -0
  282. /scitex/{vis → fig}/backend/_render.py +0 -0
  283. /scitex/{vis → fig}/docs/CANVAS_ARCHITECTURE.md +0 -0
  284. /scitex/{vis → fig}/editor/__init__.py +0 -0
  285. /scitex/{vis → fig}/editor/_dearpygui_editor.py +0 -0
  286. /scitex/{vis → fig}/editor/_flask_editor.py +0 -0
  287. /scitex/{vis → fig}/editor/_mpl_editor.py +0 -0
  288. /scitex/{vis → fig}/editor/_tkinter_editor.py +0 -0
  289. /scitex/{vis → fig}/editor/flask_editor/__init__.py +0 -0
  290. /scitex/{vis → fig}/editor/flask_editor/_utils.py +0 -0
  291. /scitex/{vis → fig}/io/_directory.py +0 -0
  292. /scitex/{vis → fig}/model/_plot_types.py +0 -0
  293. /scitex/{vis → fig}/utils/_defaults.py +0 -0
  294. /scitex/{vis → fig}/utils/_validate.py +0 -0
  295. {scitex-2.7.0.dist-info → scitex-2.7.3.dist-info}/WHEEL +0 -0
  296. {scitex-2.7.0.dist-info → scitex-2.7.3.dist-info}/entry_points.txt +0 -0
  297. {scitex-2.7.0.dist-info → scitex-2.7.3.dist-info}/licenses/LICENSE +0 -0
@@ -3,7 +3,7 @@
3
3
  # Timestamp: 2025-12-08
4
4
  # File: ./src/scitex/vis/io/canvas.py
5
5
  """
6
- Canvas JSON operations for scitex.vis.
6
+ Canvas JSON operations for scitex.fig.
7
7
 
8
8
  Handles saving, loading, and updating canvas.json files.
9
9
  """
@@ -3,7 +3,7 @@
3
3
  # Timestamp: 2025-12-08
4
4
  # File: ./src/scitex/vis/io/data.py
5
5
  """
6
- Data operations for scitex.vis.
6
+ Data operations for scitex.fig.
7
7
 
8
8
  Handles SHA256 hash computation and verification for data integrity.
9
9
  """
@@ -3,7 +3,7 @@
3
3
  # Timestamp: 2025-12-08
4
4
  # File: ./src/scitex/vis/io/export.py
5
5
  """
6
- Export operations for scitex.vis.
6
+ Export operations for scitex.fig.
7
7
 
8
8
  Handles composing and exporting canvas to various formats (PNG, PDF, SVG).
9
9
  """
@@ -115,7 +115,7 @@ def load_figure_model(
115
115
 
116
116
  Examples
117
117
  --------
118
- >>> from scitex.vis.io import load_figure_model
118
+ >>> from scitex.fig.io import load_figure_model
119
119
  >>> fig_model = load_figure_model("figure.json")
120
120
  >>> fig_model.width_mm
121
121
  180
@@ -3,7 +3,7 @@
3
3
  # Timestamp: 2025-12-08
4
4
  # File: ./src/scitex/vis/io/panel.py
5
5
  """
6
- Panel operations for scitex.vis.
6
+ Panel operations for scitex.fig.
7
7
 
8
8
  Handles adding, removing, updating, and listing panels within a canvas.
9
9
  Panels can be either 'scitex' type (full stx.plt output) or 'image' type (static image).
@@ -119,7 +119,7 @@ def save_figure_model(
119
119
 
120
120
  Examples
121
121
  --------
122
- >>> from scitex.vis.model import FigureModel
122
+ >>> from scitex.fig.model import FigureModel
123
123
  >>> fig_model = FigureModel(width_mm=180, height_mm=120)
124
124
  >>> save_figure_model(fig_model, "figure.json")
125
125
  PosixPath('figure.json')
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
  # File: ./src/scitex/vis/model/__init__.py
4
4
  """
5
- JSON models for scitex.vis figure specifications.
5
+ JSON models for scitex.fig figure specifications.
6
6
 
7
7
  This module provides dataclass-based models for representing
8
8
  publication-quality figures as JSON structures.
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python3
2
2
  # -*- coding: utf-8 -*-
3
3
  # File: ./src/scitex/vis/model/annotations.py
4
- """Annotation JSON model for scitex.vis."""
4
+ """Annotation JSON model for scitex.fig."""
5
5
 
6
6
  from typing import Optional, Dict, Any, Tuple
7
7
  from dataclasses import dataclass, field, asdict
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python3
2
2
  # -*- coding: utf-8 -*-
3
3
  # File: ./src/scitex/vis/model/axes.py
4
- """Axes JSON model for scitex.vis."""
4
+ """Axes JSON model for scitex.fig."""
5
5
 
6
6
  from typing import Optional, List, Dict, Any
7
7
  from dataclasses import dataclass, field, asdict
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python3
2
2
  # -*- coding: utf-8 -*-
3
3
  # File: ./src/scitex/vis/model/figure.py
4
- """Figure JSON model for scitex.vis."""
4
+ """Figure JSON model for scitex.fig."""
5
5
 
6
6
  from typing import Optional, List, Dict, Any
7
7
  from dataclasses import dataclass, field, asdict
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python3
2
2
  # -*- coding: utf-8 -*-
3
3
  # File: ./src/scitex/vis/model/guides.py
4
- """Guide elements (lines, spans) JSON model for scitex.vis."""
4
+ """Guide elements (lines, spans) JSON model for scitex.fig."""
5
5
 
6
6
  from typing import Optional, List, Dict, Any
7
7
  from dataclasses import dataclass, field, asdict
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env python3
2
2
  # -*- coding: utf-8 -*-
3
3
  # File: ./src/scitex/vis/model/plot.py
4
- """Plot JSON model for scitex.vis."""
4
+ """Plot JSON model for scitex.fig."""
5
5
 
6
6
  from typing import Optional, List, Dict, Any
7
7
  from dataclasses import dataclass, field, asdict
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
  # File: ./src/scitex/vis/model/styles.py
4
4
  """
5
- Style dataclasses for scitex.vis objects.
5
+ Style dataclasses for scitex.fig objects.
6
6
 
7
7
  Separating style properties from data makes:
8
8
  - UI property panels easy to auto-generate
@@ -2,7 +2,7 @@
2
2
  # -*- coding: utf-8 -*-
3
3
  # File: ./src/scitex/vis/utils/__init__.py
4
4
  """
5
- Utilities for scitex.vis.
5
+ Utilities for scitex.fig.
6
6
 
7
7
  Includes validation functions and default templates for
8
8
  common publication formats.
scitex/io/__init__.py CHANGED
@@ -13,6 +13,13 @@ __DIR__ = os.path.dirname(__FILE__)
13
13
  # Import commonly used functions directly
14
14
  from ._save import save
15
15
  from ._load import load
16
+
17
+ # Bundle I/O for .figz, .pltz, .statsz
18
+ # Users should use module-specific save/load functions:
19
+ # - scitex.plt.save_pltz() / load_pltz()
20
+ # - scitex.fig.save_figz() / load_figz()
21
+ # - scitex.stats.save_statsz() / load_statsz()
22
+ # Internal bundle functions available via scitex.io._bundle for module implementations
16
23
  from ._load_configs import load_configs
17
24
  from ._glob import glob, parse_glob
18
25
  from ._reload import reload
@@ -79,39 +86,16 @@ except ImportError:
79
86
  has_metadata = None
80
87
 
81
88
  __all__ = [
89
+ # Primary I/O
82
90
  "save",
83
91
  "load",
92
+ # Config loading
84
93
  "load_configs",
94
+ # File utilities
85
95
  "glob",
86
- "parse_glob",
87
96
  "reload",
88
97
  "flush",
89
98
  "cache",
90
- "H5Explorer",
91
- "explore_h5",
92
- "has_h5_key",
93
- "path",
94
- "mv_to_tmp",
95
- "json2md",
96
- "save_image",
97
- "save_text",
98
- "save_mp4",
99
- "save_listed_dfs_as_csv",
100
- "save_listed_scalars_as_csv",
101
- "save_optuna_study_as_csv_and_pngs",
102
- "ZarrExplorer",
103
- "explore_zarr",
104
- "has_zarr_key",
105
- "migrate_h5_to_zarr",
106
- "migrate_h5_to_zarr_batch",
107
- # Load cache control functions
108
- "get_cache_info",
109
- "configure_cache",
110
- "clear_load_cache",
111
- # Metadata functions
112
- "read_metadata",
113
- "embed_metadata",
114
- "has_metadata",
115
99
  ]
116
100
 
117
101
  # EOF
scitex/io/_bundle.py ADDED
@@ -0,0 +1,434 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Timestamp: "2025-12-13 (ywatanabe)"
4
+ # File: /home/ywatanabe/proj/scitex-code/src/scitex/io/_bundle.py
5
+
6
+ """
7
+ SciTeX Bundle I/O - Shared utilities for .figz, .pltz, and .statsz formats.
8
+
9
+ This module provides common bundle operations. Domain-specific logic is in:
10
+ - scitex.plt.io._bundle (pltz: hitmap, CSV, overview)
11
+ - scitex.fig.io._bundle (figz: panel composition, nested pltz)
12
+ - scitex.stats.io._bundle (statsz: comparison metadata)
13
+
14
+ Bundle formats:
15
+ .figz - Publication Figure Bundle (panels + layout)
16
+ .pltz - Reproducible Plot Bundle (data + spec + exports)
17
+ .statsz - Statistical Results Bundle (stats + metadata)
18
+
19
+ Each bundle can be:
20
+ - Directory form: Figure1.figz.d/
21
+ - ZIP archive form: Figure1.figz
22
+ """
23
+
24
+ import json
25
+ import shutil
26
+ import zipfile
27
+ from pathlib import Path
28
+ from typing import Any, Dict, List, Optional, Union
29
+
30
+ __all__ = [
31
+ "is_bundle",
32
+ "load_bundle",
33
+ "save_bundle",
34
+ "pack_bundle",
35
+ "unpack_bundle",
36
+ "validate_bundle",
37
+ "validate_spec",
38
+ "BundleType",
39
+ "BundleValidationError",
40
+ "BUNDLE_EXTENSIONS",
41
+ "get_bundle_type",
42
+ "dir_to_zip_path",
43
+ "zip_to_dir_path",
44
+ ]
45
+
46
+ # Bundle extensions
47
+ BUNDLE_EXTENSIONS = (".figz", ".pltz", ".statsz")
48
+
49
+
50
+ class BundleValidationError(ValueError):
51
+ """Error raised when bundle validation fails."""
52
+ pass
53
+
54
+
55
+ class BundleType:
56
+ """Bundle type constants."""
57
+ FIGZ = "figz"
58
+ PLTZ = "pltz"
59
+ STATSZ = "statsz"
60
+
61
+
62
+ def get_bundle_type(path: Union[str, Path]) -> Optional[str]:
63
+ """Get bundle type from path.
64
+
65
+ Args:
66
+ path: Path to bundle (directory or ZIP).
67
+
68
+ Returns:
69
+ Bundle type string or None if not a bundle.
70
+ """
71
+ p = Path(path)
72
+
73
+ # Directory bundle: ends with .figz.d, .pltz.d, .statsz.d
74
+ if p.is_dir() and p.suffix == ".d":
75
+ stem = p.stem # e.g., "Figure1.figz"
76
+ for ext in BUNDLE_EXTENSIONS:
77
+ if stem.endswith(ext):
78
+ return ext[1:] # Remove leading dot
79
+ return None
80
+
81
+ # ZIP bundle: ends with .figz, .pltz, .statsz
82
+ if p.suffix in BUNDLE_EXTENSIONS:
83
+ return p.suffix[1:] # Remove leading dot
84
+
85
+ return None
86
+
87
+
88
+ def is_bundle(path: Union[str, Path]) -> bool:
89
+ """Check if path is a SciTeX bundle (directory or ZIP).
90
+
91
+ Args:
92
+ path: Path to check.
93
+
94
+ Returns:
95
+ True if path is a bundle.
96
+ """
97
+ return get_bundle_type(path) is not None
98
+
99
+
100
+ def dir_to_zip_path(dir_path: Path) -> Path:
101
+ """Convert directory path to ZIP path.
102
+
103
+ Example: Figure1.figz.d/ -> Figure1.figz
104
+ """
105
+ if dir_path.suffix == ".d":
106
+ return dir_path.with_suffix("")
107
+ return dir_path
108
+
109
+
110
+ def zip_to_dir_path(zip_path: Path) -> Path:
111
+ """Convert ZIP path to directory path.
112
+
113
+ Example: Figure1.figz -> Figure1.figz.d/
114
+ """
115
+ return Path(str(zip_path) + ".d")
116
+
117
+
118
+ def pack_bundle(
119
+ dir_path: Union[str, Path], output_path: Optional[Union[str, Path]] = None
120
+ ) -> Path:
121
+ """Pack a bundle directory into a ZIP archive.
122
+
123
+ The ZIP archive includes the .d directory as a top-level folder so that
124
+ standard unzip extracts to: fname.pltz.d/fname.csv, fname.pltz.d/fname.json, etc.
125
+
126
+ Args:
127
+ dir_path: Path to bundle directory (e.g., Figure1.figz.d/).
128
+ output_path: Output ZIP path. Auto-generated if None.
129
+
130
+ Returns:
131
+ Path to created ZIP archive.
132
+ """
133
+ dir_path = Path(dir_path)
134
+
135
+ if not dir_path.is_dir():
136
+ raise ValueError(f"Not a directory: {dir_path}")
137
+
138
+ if output_path is None:
139
+ output_path = dir_to_zip_path(dir_path)
140
+ else:
141
+ output_path = Path(output_path)
142
+
143
+ # Get the directory name to use as top-level folder in ZIP
144
+ # e.g., "stx_line.pltz.d" for path "/path/to/stx_line.pltz.d"
145
+ dir_name = dir_path.name
146
+
147
+ # Create ZIP archive with directory structure preserved
148
+ with zipfile.ZipFile(output_path, "w", zipfile.ZIP_DEFLATED) as zf:
149
+ for file_path in dir_path.rglob("*"):
150
+ if file_path.is_file():
151
+ # Include directory name in archive path
152
+ # e.g., "stx_line.pltz.d/stx_line.csv"
153
+ rel_path = file_path.relative_to(dir_path)
154
+ arcname = Path(dir_name) / rel_path
155
+ zf.write(file_path, arcname)
156
+
157
+ return output_path
158
+
159
+
160
+ def unpack_bundle(
161
+ zip_path: Union[str, Path], output_path: Optional[Union[str, Path]] = None
162
+ ) -> Path:
163
+ """Unpack a bundle ZIP archive into a directory.
164
+
165
+ The ZIP archive contains a top-level .d directory, so extraction goes to
166
+ the parent directory. E.g., stx_line.pltz extracts to create stx_line.pltz.d/
167
+
168
+ Args:
169
+ zip_path: Path to bundle ZIP (e.g., Figure1.figz).
170
+ output_path: Output directory path. Auto-generated if None.
171
+
172
+ Returns:
173
+ Path to created directory.
174
+ """
175
+ zip_path = Path(zip_path)
176
+
177
+ if not zip_path.is_file():
178
+ raise ValueError(f"Not a file: {zip_path}")
179
+
180
+ # Determine extraction target
181
+ if output_path is None:
182
+ # Extract to same directory as ZIP file (ZIP contains .d folder structure)
183
+ extract_to = zip_path.parent
184
+ expected_dir = zip_to_dir_path(zip_path)
185
+ else:
186
+ output_path = Path(output_path)
187
+ extract_to = output_path.parent
188
+ expected_dir = output_path
189
+
190
+ # Extract ZIP archive (contains .d directory structure)
191
+ with zipfile.ZipFile(zip_path, "r") as zf:
192
+ zf.extractall(extract_to)
193
+
194
+ return expected_dir
195
+
196
+
197
+ def validate_spec(
198
+ spec: Dict[str, Any], bundle_type: str, strict: bool = False
199
+ ) -> List[str]:
200
+ """Validate a bundle specification against its schema.
201
+
202
+ Args:
203
+ spec: The specification dictionary to validate.
204
+ bundle_type: Bundle type ('figz', 'pltz', 'statsz').
205
+ strict: If True, raise BundleValidationError on failure.
206
+
207
+ Returns:
208
+ List of validation warning/error messages (empty if valid).
209
+
210
+ Raises:
211
+ BundleValidationError: If strict=True and validation fails.
212
+ """
213
+ errors = []
214
+
215
+ # Basic schema validation
216
+ if "schema" not in spec:
217
+ errors.append("Missing required field: schema")
218
+ elif not isinstance(spec["schema"], dict):
219
+ errors.append("'schema' field must be a dictionary")
220
+ else:
221
+ schema = spec["schema"]
222
+ if "name" not in schema:
223
+ errors.append("schema.name is required")
224
+ if "version" not in schema:
225
+ errors.append("schema.version is required")
226
+
227
+ # Delegate to domain-specific validators
228
+ if bundle_type == BundleType.FIGZ:
229
+ from scitex.fig.io._bundle import validate_figz_spec
230
+ errors.extend(validate_figz_spec(spec))
231
+ elif bundle_type == BundleType.PLTZ:
232
+ from scitex.plt.io._bundle import validate_pltz_spec
233
+ errors.extend(validate_pltz_spec(spec))
234
+ elif bundle_type == BundleType.STATSZ:
235
+ from scitex.stats.io._bundle import validate_statsz_spec
236
+ errors.extend(validate_statsz_spec(spec))
237
+ else:
238
+ errors.append(f"Unknown bundle type: {bundle_type}")
239
+
240
+ if strict and errors:
241
+ raise BundleValidationError("; ".join(errors))
242
+
243
+ return errors
244
+
245
+
246
+ def validate_bundle(
247
+ path: Union[str, Path], strict: bool = False
248
+ ) -> Dict[str, Any]:
249
+ """Validate a bundle and return validation results.
250
+
251
+ Args:
252
+ path: Path to bundle (directory or ZIP).
253
+ strict: If True, raise BundleValidationError on failure.
254
+
255
+ Returns:
256
+ Dictionary with:
257
+ - 'valid': bool
258
+ - 'errors': list of error messages
259
+ - 'bundle_type': detected bundle type
260
+ - 'spec': parsed spec (if available)
261
+
262
+ Raises:
263
+ BundleValidationError: If strict=True and validation fails.
264
+ """
265
+ result = {
266
+ "valid": True,
267
+ "errors": [],
268
+ "bundle_type": None,
269
+ "spec": None,
270
+ }
271
+
272
+ p = Path(path)
273
+
274
+ # Check bundle type
275
+ bundle_type = get_bundle_type(p)
276
+ if bundle_type is None:
277
+ result["valid"] = False
278
+ result["errors"].append(f"Not a valid bundle path: {path}")
279
+ if strict:
280
+ raise BundleValidationError(result["errors"][0])
281
+ return result
282
+
283
+ result["bundle_type"] = bundle_type
284
+
285
+ # Try to load and validate
286
+ try:
287
+ bundle = load_bundle(path)
288
+ spec = bundle.get("spec")
289
+ result["spec"] = spec
290
+
291
+ if spec is not None:
292
+ errors = validate_spec(spec, bundle_type, strict=False)
293
+ if errors:
294
+ result["valid"] = False
295
+ result["errors"].extend(errors)
296
+ else:
297
+ result["valid"] = False
298
+ result["errors"].append("Bundle has no spec")
299
+
300
+ except Exception as e:
301
+ result["valid"] = False
302
+ result["errors"].append(f"Failed to load bundle: {e}")
303
+
304
+ if strict and not result["valid"]:
305
+ raise BundleValidationError("; ".join(result["errors"]))
306
+
307
+ return result
308
+
309
+
310
+ def load_bundle(path: Union[str, Path]) -> Dict[str, Any]:
311
+ """Load bundle from directory or ZIP transparently.
312
+
313
+ Args:
314
+ path: Path to bundle (directory or ZIP).
315
+
316
+ Returns:
317
+ Bundle data as dictionary with:
318
+ - 'type': Bundle type ('figz', 'pltz', 'statsz')
319
+ - 'spec': Parsed JSON specification
320
+ - 'path': Original path
321
+ - 'is_zip': Whether loaded from ZIP
322
+ - Additional fields based on bundle type
323
+ """
324
+ p = Path(path)
325
+ bundle_type = get_bundle_type(p)
326
+
327
+ if bundle_type is None:
328
+ raise ValueError(f"Not a valid bundle: {path}")
329
+
330
+ result = {
331
+ "type": bundle_type,
332
+ "path": p,
333
+ "is_zip": False,
334
+ }
335
+
336
+ # Handle ZIP vs directory
337
+ if p.is_file() and p.suffix in BUNDLE_EXTENSIONS:
338
+ # ZIP archive - extract to temp and load
339
+ result["is_zip"] = True
340
+ import tempfile
341
+ temp_dir = Path(tempfile.mkdtemp())
342
+ with zipfile.ZipFile(p, "r") as zf:
343
+ zf.extractall(temp_dir)
344
+ bundle_dir = temp_dir
345
+ else:
346
+ bundle_dir = p
347
+
348
+ # Delegate to domain-specific loaders
349
+ if bundle_type == BundleType.FIGZ:
350
+ from scitex.fig.io._bundle import load_figz_bundle
351
+ result.update(load_figz_bundle(bundle_dir))
352
+ elif bundle_type == BundleType.PLTZ:
353
+ from scitex.plt.io import load_layered_pltz_bundle
354
+ result.update(load_layered_pltz_bundle(bundle_dir))
355
+ elif bundle_type == BundleType.STATSZ:
356
+ from scitex.stats.io._bundle import load_statsz_bundle
357
+ result.update(load_statsz_bundle(bundle_dir))
358
+
359
+ return result
360
+
361
+
362
+ def save_bundle(
363
+ data: Dict[str, Any],
364
+ path: Union[str, Path],
365
+ bundle_type: Optional[str] = None,
366
+ as_zip: bool = False,
367
+ ) -> Path:
368
+ """Save data as a bundle.
369
+
370
+ Args:
371
+ data: Bundle data dictionary.
372
+ path: Output path (with or without .d suffix).
373
+ bundle_type: Bundle type ('figz', 'pltz', 'statsz'). Auto-detected if None.
374
+ as_zip: If True, save as ZIP archive.
375
+
376
+ Returns:
377
+ Path to saved bundle.
378
+ """
379
+ p = Path(path)
380
+
381
+ # Determine bundle type
382
+ if bundle_type is None:
383
+ bundle_type = get_bundle_type(p)
384
+ if bundle_type is None:
385
+ raise ValueError(f"Cannot determine bundle type from path: {path}")
386
+
387
+ # Determine if saving as directory or ZIP
388
+ if as_zip or (p.suffix in BUNDLE_EXTENSIONS and not str(p).endswith(".d")):
389
+ save_as_zip = True
390
+ if p.suffix == ".d":
391
+ zip_path = dir_to_zip_path(p)
392
+ else:
393
+ zip_path = p
394
+ dir_path = zip_to_dir_path(zip_path)
395
+ else:
396
+ save_as_zip = False
397
+ if not str(p).endswith(".d"):
398
+ dir_path = Path(str(p) + ".d")
399
+ else:
400
+ dir_path = p
401
+
402
+ # Create directory
403
+ dir_path.mkdir(parents=True, exist_ok=True)
404
+
405
+ # Delegate to domain-specific savers
406
+ if bundle_type == BundleType.FIGZ:
407
+ from scitex.fig.io._bundle import save_figz_bundle
408
+ save_figz_bundle(data, dir_path)
409
+ elif bundle_type == BundleType.PLTZ:
410
+ # Note: This path is only reached when calling save_bundle() directly
411
+ # The main stx.io.save() flow uses _save_pltz_bundle() which handles layered format
412
+ from scitex.plt.io._bundle import save_pltz_bundle
413
+ save_pltz_bundle(data, dir_path)
414
+ elif bundle_type == BundleType.STATSZ:
415
+ from scitex.stats.io._bundle import save_statsz_bundle
416
+ save_statsz_bundle(data, dir_path)
417
+ else:
418
+ raise ValueError(f"Unknown bundle type: {bundle_type}")
419
+
420
+ # Pack to ZIP if requested
421
+ if save_as_zip:
422
+ pack_bundle(dir_path, zip_path)
423
+ shutil.rmtree(dir_path) # Remove temp directory
424
+ return zip_path
425
+
426
+ return dir_path
427
+
428
+
429
+ # Backward compatibility aliases
430
+ _get_bundle_type = get_bundle_type
431
+ _dir_to_zip_path = dir_to_zip_path
432
+ _zip_to_dir_path = zip_to_dir_path
433
+
434
+ # EOF
scitex/io/_flush.py CHANGED
@@ -5,7 +5,10 @@
5
5
 
6
6
  import os
7
7
  import sys
8
- import warnings
8
+
9
+ from scitex import logging
10
+
11
+ logger = logging.getLogger(__name__)
9
12
 
10
13
 
11
14
  def flush(sys=sys):
@@ -14,7 +17,7 @@ def flush(sys=sys):
14
17
  This ensures all pending write operations are completed.
15
18
  """
16
19
  if sys is None:
17
- warnings.warn("flush needs sys. Skipping.")
20
+ logger.warning("flush needs sys. Skipping.")
18
21
  else:
19
22
  sys.stdout.flush()
20
23
  sys.stderr.flush()