scitex 2.8.1__py3-none-any.whl → 2.10.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (415) hide show
  1. scitex/__init__.py +15 -7
  2. scitex/__version__.py +1 -2
  3. scitex/_install_guide.py +250 -0
  4. scitex/_optional_deps.py +206 -39
  5. scitex/ai/_gen_ai/_Groq.py +2 -4
  6. scitex/ai/_gen_ai/_OpenAI.py +5 -2
  7. scitex/ai/_gen_ai/_Perplexity.py +20 -6
  8. scitex/audio/__init__.py +24 -15
  9. scitex/audio/_cross_process_lock.py +139 -0
  10. scitex/audio/_mcp_handlers.py +256 -0
  11. scitex/audio/_mcp_tool_schemas.py +203 -0
  12. scitex/audio/engines/elevenlabs_engine.py +5 -2
  13. scitex/audio/mcp_server.py +98 -457
  14. scitex/bridge/__init__.py +30 -19
  15. scitex/bridge/_figrecipe.py +245 -0
  16. scitex/bridge/_helpers.py +2 -1
  17. scitex/bridge/_plt_vis.py +23 -10
  18. scitex/bridge/_stats_plt.py +18 -5
  19. scitex/bridge/_stats_vis.py +16 -2
  20. scitex/browser/__init__.py +84 -44
  21. scitex/browser/automation/__init__.py +5 -1
  22. scitex/browser/core/BrowserMixin.py +17 -4
  23. scitex/browser/core/__init__.py +11 -2
  24. scitex/browser/remote/CaptchaHandler.py +1 -1
  25. scitex/browser/remote/ZenRowsAPIClient.py +1 -1
  26. scitex/capture/grid.py +487 -0
  27. scitex/capture/mcp_handlers.py +401 -0
  28. scitex/capture/mcp_tool_defs.py +192 -0
  29. scitex/capture/mcp_tools.py +241 -0
  30. scitex/capture/mcp_utils.py +30 -0
  31. scitex/cli/convert.py +421 -0
  32. scitex/cli/main.py +6 -4
  33. scitex/datetime/__init__.py +46 -0
  34. scitex/datetime/_linspace.py +100 -0
  35. scitex/datetime/_normalize_timestamp.py +306 -0
  36. scitex/db/_delete_duplicates.py +4 -4
  37. scitex/db/_sqlite3/_delete_duplicates.py +11 -2
  38. scitex/dev/plt/__init__.py +61 -62
  39. scitex/dev/plt/demo_plotters/__init__.py +0 -0
  40. scitex/dev/plt/demo_plotters/plot_mpl_axhline.py +28 -0
  41. scitex/dev/plt/demo_plotters/plot_mpl_axhspan.py +28 -0
  42. scitex/dev/plt/demo_plotters/plot_mpl_axvline.py +28 -0
  43. scitex/dev/plt/demo_plotters/plot_mpl_axvspan.py +28 -0
  44. scitex/dev/plt/demo_plotters/plot_mpl_bar.py +29 -0
  45. scitex/dev/plt/demo_plotters/plot_mpl_barh.py +29 -0
  46. scitex/dev/plt/demo_plotters/plot_mpl_boxplot.py +28 -0
  47. scitex/dev/plt/demo_plotters/plot_mpl_contour.py +31 -0
  48. scitex/dev/plt/demo_plotters/plot_mpl_contourf.py +31 -0
  49. scitex/dev/plt/demo_plotters/plot_mpl_errorbar.py +30 -0
  50. scitex/dev/plt/demo_plotters/plot_mpl_eventplot.py +28 -0
  51. scitex/dev/plt/demo_plotters/plot_mpl_fill.py +30 -0
  52. scitex/dev/plt/demo_plotters/plot_mpl_fill_between.py +31 -0
  53. scitex/dev/plt/demo_plotters/plot_mpl_hexbin.py +28 -0
  54. scitex/dev/plt/demo_plotters/plot_mpl_hist.py +28 -0
  55. scitex/dev/plt/demo_plotters/plot_mpl_hist2d.py +28 -0
  56. scitex/dev/plt/demo_plotters/plot_mpl_imshow.py +29 -0
  57. scitex/dev/plt/demo_plotters/plot_mpl_pcolormesh.py +31 -0
  58. scitex/dev/plt/demo_plotters/plot_mpl_pie.py +29 -0
  59. scitex/dev/plt/demo_plotters/plot_mpl_plot.py +29 -0
  60. scitex/dev/plt/demo_plotters/plot_mpl_quiver.py +31 -0
  61. scitex/dev/plt/demo_plotters/plot_mpl_scatter.py +28 -0
  62. scitex/dev/plt/demo_plotters/plot_mpl_stackplot.py +31 -0
  63. scitex/dev/plt/demo_plotters/plot_mpl_stem.py +29 -0
  64. scitex/dev/plt/demo_plotters/plot_mpl_step.py +29 -0
  65. scitex/dev/plt/demo_plotters/plot_mpl_violinplot.py +28 -0
  66. scitex/dev/plt/demo_plotters/plot_sns_barplot.py +29 -0
  67. scitex/dev/plt/demo_plotters/plot_sns_boxplot.py +29 -0
  68. scitex/dev/plt/demo_plotters/plot_sns_heatmap.py +28 -0
  69. scitex/dev/plt/demo_plotters/plot_sns_histplot.py +29 -0
  70. scitex/dev/plt/demo_plotters/plot_sns_kdeplot.py +29 -0
  71. scitex/dev/plt/demo_plotters/plot_sns_lineplot.py +31 -0
  72. scitex/dev/plt/demo_plotters/plot_sns_scatterplot.py +29 -0
  73. scitex/dev/plt/demo_plotters/plot_sns_stripplot.py +29 -0
  74. scitex/dev/plt/demo_plotters/plot_sns_swarmplot.py +29 -0
  75. scitex/dev/plt/demo_plotters/plot_sns_violinplot.py +29 -0
  76. scitex/dev/plt/demo_plotters/plot_stx_bar.py +29 -0
  77. scitex/dev/plt/demo_plotters/plot_stx_barh.py +29 -0
  78. scitex/dev/plt/demo_plotters/plot_stx_box.py +28 -0
  79. scitex/dev/plt/demo_plotters/plot_stx_boxplot.py +28 -0
  80. scitex/dev/plt/demo_plotters/plot_stx_conf_mat.py +28 -0
  81. scitex/dev/plt/demo_plotters/plot_stx_contour.py +31 -0
  82. scitex/dev/plt/demo_plotters/plot_stx_ecdf.py +28 -0
  83. scitex/dev/plt/demo_plotters/plot_stx_errorbar.py +30 -0
  84. scitex/dev/plt/demo_plotters/plot_stx_fill_between.py +31 -0
  85. scitex/dev/plt/demo_plotters/plot_stx_fillv.py +28 -0
  86. scitex/dev/plt/demo_plotters/plot_stx_heatmap.py +28 -0
  87. scitex/dev/plt/demo_plotters/plot_stx_image.py +28 -0
  88. scitex/dev/plt/demo_plotters/plot_stx_imshow.py +28 -0
  89. scitex/dev/plt/demo_plotters/plot_stx_joyplot.py +28 -0
  90. scitex/dev/plt/demo_plotters/plot_stx_kde.py +28 -0
  91. scitex/dev/plt/demo_plotters/plot_stx_line.py +28 -0
  92. scitex/dev/plt/demo_plotters/plot_stx_mean_ci.py +28 -0
  93. scitex/dev/plt/demo_plotters/plot_stx_mean_std.py +28 -0
  94. scitex/dev/plt/demo_plotters/plot_stx_median_iqr.py +28 -0
  95. scitex/dev/plt/demo_plotters/plot_stx_raster.py +28 -0
  96. scitex/dev/plt/demo_plotters/plot_stx_rectangle.py +28 -0
  97. scitex/dev/plt/demo_plotters/plot_stx_scatter.py +29 -0
  98. scitex/dev/plt/demo_plotters/plot_stx_shaded_line.py +29 -0
  99. scitex/dev/plt/demo_plotters/plot_stx_violin.py +28 -0
  100. scitex/dev/plt/demo_plotters/plot_stx_violinplot.py +28 -0
  101. scitex/dev/plt/mpl/get_dir_ax.py +46 -0
  102. scitex/dev/plt/mpl/get_signatures.py +176 -0
  103. scitex/dev/plt/mpl/get_signatures_details.py +522 -0
  104. scitex/dict/_pop_keys.py +1 -7
  105. scitex/dsp/__init__.py +15 -10
  106. scitex/dsp/add_noise.py +5 -2
  107. scitex/dsp/example.py +35 -22
  108. scitex/dsp/filt.py +8 -3
  109. scitex/dsp/reference.py +3 -2
  110. scitex/dsp/utils/__init__.py +2 -1
  111. scitex/dsp/utils/_differential_bandpass_filters.py +14 -4
  112. scitex/dt/__init__.py +39 -2
  113. scitex/errors.py +82 -521
  114. scitex/fig/__init__.py +4 -4
  115. scitex/fig/editor/edit/panel_loader.py +1 -1
  116. scitex/fig/io/_bundle.py +7 -7
  117. scitex/fts/README.md +262 -0
  118. scitex/fts/TODO.md +66 -0
  119. scitex/fts/__init__.py +90 -0
  120. scitex/fts/_bundle/README_IN_BUNDLE.md +102 -0
  121. scitex/fts/_bundle/_FTS.py +657 -0
  122. scitex/fts/_bundle/__init__.py +38 -0
  123. scitex/fts/_bundle/_children.py +216 -0
  124. scitex/fts/_bundle/_conversion/__init__.py +15 -0
  125. scitex/fts/_bundle/_conversion/_bundle2dict.py +44 -0
  126. scitex/fts/_bundle/_conversion/_dict2bundle.py +50 -0
  127. scitex/fts/_bundle/_dataclasses/_Axes.py +57 -0
  128. scitex/fts/_bundle/_dataclasses/_BBox.py +54 -0
  129. scitex/fts/_bundle/_dataclasses/_ColumnDef.py +72 -0
  130. scitex/fts/_bundle/_dataclasses/_DataFormat.py +40 -0
  131. scitex/fts/_bundle/_dataclasses/_DataInfo.py +135 -0
  132. scitex/fts/_bundle/_dataclasses/_DataSource.py +44 -0
  133. scitex/fts/_bundle/_dataclasses/_Node.py +319 -0
  134. scitex/fts/_bundle/_dataclasses/_NodeRefs.py +45 -0
  135. scitex/fts/_bundle/_dataclasses/_SizeMM.py +38 -0
  136. scitex/fts/_bundle/_dataclasses/__init__.py +35 -0
  137. scitex/fts/_bundle/_extractors/__init__.py +32 -0
  138. scitex/fts/_bundle/_extractors/_extract_bar.py +131 -0
  139. scitex/fts/_bundle/_extractors/_extract_line.py +71 -0
  140. scitex/fts/_bundle/_extractors/_extract_scatter.py +79 -0
  141. scitex/fts/_bundle/_loader.py +134 -0
  142. scitex/fts/_bundle/_mpl_helpers.py +389 -0
  143. scitex/fts/_bundle/_saver.py +269 -0
  144. scitex/fts/_bundle/_storage.py +200 -0
  145. scitex/fts/_bundle/_utils/__init__.py +55 -0
  146. scitex/fts/_bundle/_utils/_const.py +26 -0
  147. scitex/fts/_bundle/_utils/_errors.py +73 -0
  148. scitex/fts/_bundle/_utils/_generate.py +21 -0
  149. scitex/fts/_bundle/_utils/_types.py +76 -0
  150. scitex/fts/_bundle/_validation.py +434 -0
  151. scitex/fts/_bundle/_zipbundle.py +165 -0
  152. scitex/fts/_fig/__init__.py +22 -0
  153. scitex/fts/_fig/_backend/__init__.py +53 -0
  154. scitex/fts/_fig/_backend/_export.py +165 -0
  155. scitex/fts/_fig/_backend/_parser.py +188 -0
  156. scitex/fts/_fig/_backend/_render.py +538 -0
  157. scitex/fts/_fig/_composite.py +345 -0
  158. scitex/fts/_fig/_dataclasses/_ChannelEncoding.py +46 -0
  159. scitex/fts/_fig/_dataclasses/_Encoding.py +82 -0
  160. scitex/fts/_fig/_dataclasses/_Theme.py +441 -0
  161. scitex/fts/_fig/_dataclasses/_TraceEncoding.py +52 -0
  162. scitex/fts/_fig/_dataclasses/__init__.py +47 -0
  163. scitex/fts/_fig/_editor/__init__.py +14 -0
  164. scitex/fts/_fig/_editor/_cui/__init__.py +33 -0
  165. scitex/fts/_fig/_editor/_cui/_backend_detector.py +39 -0
  166. scitex/fts/_fig/_editor/_cui/_bundle_resolver.py +366 -0
  167. scitex/fts/_fig/_editor/_cui/_editor_launcher.py +175 -0
  168. scitex/fts/_fig/_editor/_cui/_manual_handler.py +52 -0
  169. scitex/fts/_fig/_editor/_cui/_panel_loader.py +246 -0
  170. scitex/fts/_fig/_editor/_cui/_path_resolver.py +66 -0
  171. scitex/fts/_fig/_editor/_defaults.py +300 -0
  172. scitex/fts/_fig/_editor/_gui/__init__.py +11 -0
  173. scitex/fts/_fig/_editor/_gui/_flask_editor/__init__.py +20 -0
  174. scitex/fts/_fig/_editor/_gui/_flask_editor/_bbox.py +1339 -0
  175. scitex/fts/_fig/_editor/_gui/_flask_editor/_core.py +1688 -0
  176. scitex/fts/_fig/_editor/_gui/_flask_editor/_plotter.py +664 -0
  177. scitex/fts/_fig/_editor/_gui/_flask_editor/_renderer.py +853 -0
  178. scitex/fts/_fig/_editor/_gui/_flask_editor/_utils.py +79 -0
  179. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/reset.css +41 -0
  180. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/typography.css +16 -0
  181. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/variables.css +85 -0
  182. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/buttons.css +217 -0
  183. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/context-menu.css +93 -0
  184. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/dropdown.css +57 -0
  185. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/forms.css +112 -0
  186. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/modal.css +59 -0
  187. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/sections.css +212 -0
  188. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/canvas.css +176 -0
  189. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/element-inspector.css +190 -0
  190. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/loading.css +59 -0
  191. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/overlay.css +45 -0
  192. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/panel-grid.css +95 -0
  193. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/selection.css +101 -0
  194. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/statistics.css +138 -0
  195. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/index.css +31 -0
  196. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/container.css +7 -0
  197. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/controls.css +56 -0
  198. scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/preview.css +78 -0
  199. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/axis.js +314 -0
  200. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/basic.js +107 -0
  201. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/distribute.js +54 -0
  202. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/canvas.js +172 -0
  203. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/dragging.js +258 -0
  204. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/resize.js +48 -0
  205. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/selection.js +71 -0
  206. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/api.js +288 -0
  207. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/state.js +143 -0
  208. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/utils.js +245 -0
  209. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/dev/element-inspector.js +992 -0
  210. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/bbox.js +339 -0
  211. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/element-drag.js +286 -0
  212. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/overlay.js +371 -0
  213. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/preview.js +293 -0
  214. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/main.js +426 -0
  215. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/context-menu.js +152 -0
  216. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/keyboard.js +265 -0
  217. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/controls.js +184 -0
  218. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/download.js +57 -0
  219. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/help.js +100 -0
  220. scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/theme.js +34 -0
  221. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/__init__.py +124 -0
  222. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_html.py +851 -0
  223. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_scripts.py +4932 -0
  224. scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_styles.py +1657 -0
  225. scitex/fts/_fig/_editor/_gui/_flask_editor.py +36 -0
  226. scitex/fts/_fig/_models/_Annotations.py +115 -0
  227. scitex/fts/_fig/_models/_Axes.py +152 -0
  228. scitex/fts/_fig/_models/_Figure.py +138 -0
  229. scitex/fts/_fig/_models/_Guides.py +104 -0
  230. scitex/fts/_fig/_models/_Plot.py +123 -0
  231. scitex/fts/_fig/_models/_Styles.py +245 -0
  232. scitex/fts/_fig/_models/__init__.py +80 -0
  233. scitex/fts/_fig/_models/_plot_types/__init__.py +156 -0
  234. scitex/fts/_fig/_models/_plot_types/_bar.py +43 -0
  235. scitex/fts/_fig/_models/_plot_types/_box.py +38 -0
  236. scitex/fts/_fig/_models/_plot_types/_distribution.py +36 -0
  237. scitex/fts/_fig/_models/_plot_types/_errorbar.py +60 -0
  238. scitex/fts/_fig/_models/_plot_types/_histogram.py +30 -0
  239. scitex/fts/_fig/_models/_plot_types/_image.py +61 -0
  240. scitex/fts/_fig/_models/_plot_types/_line.py +57 -0
  241. scitex/fts/_fig/_models/_plot_types/_scatter.py +30 -0
  242. scitex/fts/_fig/_models/_plot_types/_seaborn.py +121 -0
  243. scitex/fts/_fig/_models/_plot_types/_violin.py +36 -0
  244. scitex/fts/_fig/_utils/__init__.py +129 -0
  245. scitex/fts/_fig/_utils/_auto_layout.py +127 -0
  246. scitex/fts/_fig/_utils/_calc_bounds.py +111 -0
  247. scitex/fts/_fig/_utils/_const_sizes.py +48 -0
  248. scitex/fts/_fig/_utils/_convert_coords.py +77 -0
  249. scitex/fts/_fig/_utils/_get_template.py +178 -0
  250. scitex/fts/_fig/_utils/_normalize.py +73 -0
  251. scitex/fts/_fig/_utils/_plot_layout.py +397 -0
  252. scitex/fts/_fig/_utils/_validate.py +197 -0
  253. scitex/fts/_kinds/__init__.py +45 -0
  254. scitex/fts/_kinds/_figure/__init__.py +19 -0
  255. scitex/fts/_kinds/_figure/_composite.py +345 -0
  256. scitex/fts/_kinds/_plot/__init__.py +25 -0
  257. scitex/fts/_kinds/_plot/_backend/__init__.py +53 -0
  258. scitex/fts/_kinds/_plot/_backend/_export.py +165 -0
  259. scitex/fts/_kinds/_plot/_backend/_parser.py +188 -0
  260. scitex/fts/_kinds/_plot/_backend/_render.py +538 -0
  261. scitex/fts/_kinds/_plot/_dataclasses/_ChannelEncoding.py +46 -0
  262. scitex/fts/_kinds/_plot/_dataclasses/_Encoding.py +82 -0
  263. scitex/fts/_kinds/_plot/_dataclasses/_Theme.py +441 -0
  264. scitex/fts/_kinds/_plot/_dataclasses/_TraceEncoding.py +52 -0
  265. scitex/fts/_kinds/_plot/_dataclasses/__init__.py +47 -0
  266. scitex/fts/_kinds/_plot/_models/_Annotations.py +115 -0
  267. scitex/fts/_kinds/_plot/_models/_Axes.py +152 -0
  268. scitex/fts/_kinds/_plot/_models/_Figure.py +138 -0
  269. scitex/fts/_kinds/_plot/_models/_Guides.py +104 -0
  270. scitex/fts/_kinds/_plot/_models/_Plot.py +123 -0
  271. scitex/fts/_kinds/_plot/_models/_Styles.py +245 -0
  272. scitex/fts/_kinds/_plot/_models/__init__.py +80 -0
  273. scitex/fts/_kinds/_plot/_models/_plot_types/__init__.py +156 -0
  274. scitex/fts/_kinds/_plot/_models/_plot_types/_bar.py +43 -0
  275. scitex/fts/_kinds/_plot/_models/_plot_types/_box.py +38 -0
  276. scitex/fts/_kinds/_plot/_models/_plot_types/_distribution.py +36 -0
  277. scitex/fts/_kinds/_plot/_models/_plot_types/_errorbar.py +60 -0
  278. scitex/fts/_kinds/_plot/_models/_plot_types/_histogram.py +30 -0
  279. scitex/fts/_kinds/_plot/_models/_plot_types/_image.py +61 -0
  280. scitex/fts/_kinds/_plot/_models/_plot_types/_line.py +57 -0
  281. scitex/fts/_kinds/_plot/_models/_plot_types/_scatter.py +30 -0
  282. scitex/fts/_kinds/_plot/_models/_plot_types/_seaborn.py +121 -0
  283. scitex/fts/_kinds/_plot/_models/_plot_types/_violin.py +36 -0
  284. scitex/fts/_kinds/_plot/_utils/__init__.py +129 -0
  285. scitex/fts/_kinds/_plot/_utils/_auto_layout.py +127 -0
  286. scitex/fts/_kinds/_plot/_utils/_calc_bounds.py +111 -0
  287. scitex/fts/_kinds/_plot/_utils/_const_sizes.py +48 -0
  288. scitex/fts/_kinds/_plot/_utils/_convert_coords.py +77 -0
  289. scitex/fts/_kinds/_plot/_utils/_get_template.py +178 -0
  290. scitex/fts/_kinds/_plot/_utils/_normalize.py +73 -0
  291. scitex/fts/_kinds/_plot/_utils/_plot_layout.py +397 -0
  292. scitex/fts/_kinds/_plot/_utils/_validate.py +197 -0
  293. scitex/fts/_kinds/_shape/__init__.py +141 -0
  294. scitex/fts/_kinds/_stats/__init__.py +56 -0
  295. scitex/fts/_kinds/_stats/_dataclasses/_Stats.py +423 -0
  296. scitex/fts/_kinds/_stats/_dataclasses/__init__.py +48 -0
  297. scitex/fts/_kinds/_table/__init__.py +72 -0
  298. scitex/fts/_kinds/_table/_latex/__init__.py +93 -0
  299. scitex/fts/_kinds/_table/_latex/_editor/__init__.py +11 -0
  300. scitex/fts/_kinds/_table/_latex/_editor/_app.py +725 -0
  301. scitex/fts/_kinds/_table/_latex/_export.py +279 -0
  302. scitex/fts/_kinds/_table/_latex/_figure_exporter.py +153 -0
  303. scitex/fts/_kinds/_table/_latex/_stats_formatter.py +274 -0
  304. scitex/fts/_kinds/_table/_latex/_table_exporter.py +362 -0
  305. scitex/fts/_kinds/_table/_latex/_utils.py +369 -0
  306. scitex/fts/_kinds/_table/_latex/_validator.py +445 -0
  307. scitex/fts/_kinds/_text/__init__.py +77 -0
  308. scitex/fts/_schemas/data_info.schema.json +75 -0
  309. scitex/fts/_schemas/encoding.schema.json +90 -0
  310. scitex/fts/_schemas/node.schema.json +145 -0
  311. scitex/fts/_schemas/render_manifest.schema.json +62 -0
  312. scitex/fts/_schemas/stats.schema.json +132 -0
  313. scitex/fts/_schemas/theme.schema.json +141 -0
  314. scitex/fts/_stats/__init__.py +48 -0
  315. scitex/fts/_stats/_dataclasses/_Stats.py +423 -0
  316. scitex/fts/_stats/_dataclasses/__init__.py +48 -0
  317. scitex/fts/_tables/__init__.py +65 -0
  318. scitex/fts/_tables/_latex/__init__.py +93 -0
  319. scitex/fts/_tables/_latex/_editor/__init__.py +11 -0
  320. scitex/fts/_tables/_latex/_editor/_app.py +725 -0
  321. scitex/fts/_tables/_latex/_export.py +279 -0
  322. scitex/fts/_tables/_latex/_figure_exporter.py +153 -0
  323. scitex/fts/_tables/_latex/_stats_formatter.py +274 -0
  324. scitex/fts/_tables/_latex/_table_exporter.py +362 -0
  325. scitex/fts/_tables/_latex/_utils.py +369 -0
  326. scitex/fts/_tables/_latex/_validator.py +445 -0
  327. scitex/gen/__init__.py +66 -25
  328. scitex/gen/misc.py +28 -0
  329. scitex/io/__init__.py +47 -32
  330. scitex/io/_load.py +87 -36
  331. scitex/io/_load_modules/__init__.py +10 -7
  332. scitex/io/_load_modules/_pandas.py +6 -1
  333. scitex/io/_save.py +299 -1556
  334. scitex/io/_save_modules/__init__.py +76 -19
  335. scitex/io/_save_modules/_figure_utils.py +90 -0
  336. scitex/io/_save_modules/_image_csv.py +497 -0
  337. scitex/io/_save_modules/_legends.py +91 -0
  338. scitex/io/_save_modules/_pltz_bundle.py +356 -0
  339. scitex/io/_save_modules/_pltz_stx.py +536 -0
  340. scitex/io/_save_modules/_stx_bundle.py +104 -0
  341. scitex/io/_save_modules/_symlink.py +96 -0
  342. scitex/io/_save_modules/_yaml.py +1 -1
  343. scitex/io/_save_modules/_zarr.py +64 -18
  344. scitex/io/bundle/README.md +212 -0
  345. scitex/io/bundle/__init__.py +110 -0
  346. scitex/io/{_bundle.py → bundle/_core.py} +168 -97
  347. scitex/io/bundle/_nested.py +713 -0
  348. scitex/io/bundle/_types.py +74 -0
  349. scitex/io/{_zip_bundle.py → bundle/_zip.py} +93 -45
  350. scitex/io/utils/h5_to_zarr.py +1 -1
  351. scitex/logging/__init__.py +108 -13
  352. scitex/logging/_errors.py +508 -0
  353. scitex/logging/_formatters.py +30 -6
  354. scitex/logging/_warnings.py +261 -0
  355. scitex/plt/__init__.py +4 -1
  356. scitex/plt/_figrecipe.py +236 -0
  357. scitex/plt/_subplots/_AxisWrapper.py +6 -0
  358. scitex/plt/_subplots/_AxisWrapperMixins/_UnitAwareMixin.py +112 -1
  359. scitex/plt/_subplots/_FigWrapper.py +15 -0
  360. scitex/plt/_subplots/_SubplotsWrapper.py +125 -489
  361. scitex/plt/_subplots/_export_as_csv.py +11 -0
  362. scitex/plt/_subplots/_export_as_csv_formatters/__init__.py +2 -0
  363. scitex/plt/_subplots/_export_as_csv_formatters/_format_pcolormesh.py +66 -0
  364. scitex/plt/_subplots/_export_as_csv_formatters/_format_stackplot.py +62 -0
  365. scitex/plt/_subplots/_export_as_csv_formatters/test_formatters.py +208 -0
  366. scitex/plt/_subplots/_fonts.py +71 -0
  367. scitex/plt/_subplots/_mm_layout.py +282 -0
  368. scitex/plt/gallery/__init__.py +99 -2
  369. scitex/plt/styles/_plot_postprocess.py +3 -1
  370. scitex/plt/utils/_configure_mpl.py +16 -19
  371. scitex/repro/_RandomStateManager.py +13 -8
  372. scitex/resource/__init__.py +19 -1
  373. scitex/resource/_utils/_get_env_info.py +13 -25
  374. scitex/schema/__init__.py +149 -160
  375. scitex/schema/_encoding.py +273 -0
  376. scitex/schema/_figure_elements.py +406 -0
  377. scitex/schema/_theme.py +360 -0
  378. scitex/schema/_validation.py +0 -98
  379. scitex/scholar/__init__.py +56 -14
  380. scitex/scholar/auth/ScholarAuthManager.py +1 -1
  381. scitex/scholar/auth/__init__.py +11 -2
  382. scitex/scholar/auth/providers/BaseAuthenticator.py +1 -1
  383. scitex/scholar/auth/providers/EZProxyAuthenticator.py +1 -1
  384. scitex/scholar/auth/providers/OpenAthensAuthenticator.py +1 -1
  385. scitex/scholar/auth/providers/ShibbolethAuthenticator.py +1 -1
  386. scitex/scholar/config/ScholarConfig.py +1 -1
  387. scitex/scholar/core/Scholar.py +1 -1
  388. scitex/session/_decorator.py +18 -16
  389. scitex/session/_lifecycle.py +9 -11
  390. scitex/session/template.py +9 -8
  391. scitex/sh/test_sh.py +72 -0
  392. scitex/sh/test_sh_simple.py +61 -0
  393. scitex/stats/__init__.py +221 -97
  394. scitex/stats/_schema.py +21 -22
  395. scitex/stats/descriptive/_circular.py +212 -351
  396. scitex/stats/descriptive/_describe.py +81 -132
  397. scitex/stats/descriptive/_nan.py +205 -433
  398. scitex/stats/descriptive/_real.py +127 -141
  399. scitex/str/_format_plot_text.py +5 -5
  400. scitex/str/_latex.py +26 -84
  401. scitex/str/_latex_fallback.py +53 -47
  402. scitex/web/_search_pubmed.py +5 -4
  403. scitex/writer/tests/test_diff_between.py +451 -0
  404. scitex/writer/tests/test_document_section.py +311 -0
  405. scitex/writer/tests/test_document_workflow.py +393 -0
  406. scitex/writer/tests/test_writer.py +361 -0
  407. scitex/writer/tests/test_writer_integration.py +303 -0
  408. {scitex-2.8.1.dist-info → scitex-2.10.0.dist-info}/METADATA +364 -181
  409. {scitex-2.8.1.dist-info → scitex-2.10.0.dist-info}/RECORD +412 -97
  410. scitex/scholar/docs/to_claude/guidelines/examples/mgmt/ARCHITECTURE_EXAMPLE.md +0 -905
  411. scitex/scholar/docs/to_claude/guidelines/examples/mgmt/BULLETIN_BOARD_EXAMPLE.md +0 -99
  412. scitex/scholar/docs/to_claude/guidelines/examples/mgmt/PROJECT_DESCRIPTION_EXAMPLE.md +0 -96
  413. {scitex-2.8.1.dist-info → scitex-2.10.0.dist-info}/WHEEL +0 -0
  414. {scitex-2.8.1.dist-info → scitex-2.10.0.dist-info}/entry_points.txt +0 -0
  415. {scitex-2.8.1.dist-info → scitex-2.10.0.dist-info}/licenses/LICENSE +0 -0
scitex/fig/io/_bundle.py CHANGED
@@ -132,15 +132,15 @@ def load_figz_bundle(bundle_dir: Path) -> Dict[str, Any]:
132
132
  # Load from .pltz.d directories
133
133
  for pltz_dir in bundle_dir.glob("*.pltz.d"):
134
134
  plot_name = pltz_dir.stem.replace(".pltz", "")
135
- from scitex.io._bundle import load_bundle
136
- result["plots"][plot_name] = load_bundle(pltz_dir)
135
+ from scitex.io.bundle import load
136
+ result["plots"][plot_name] = load(pltz_dir)
137
137
 
138
138
  # Load from .pltz ZIP files
139
139
  for pltz_zip in bundle_dir.glob("*.pltz"):
140
140
  if pltz_zip.is_file():
141
141
  plot_name = pltz_zip.stem
142
- from scitex.io._bundle import load_bundle
143
- result["plots"][plot_name] = load_bundle(pltz_zip)
142
+ from scitex.io.bundle import load
143
+ result["plots"][plot_name] = load(pltz_zip)
144
144
 
145
145
  return result
146
146
 
@@ -381,10 +381,10 @@ def _copy_nested_pltz_bundles(plots: Dict[str, Any], dir_path: Path) -> None:
381
381
  shutil.rmtree(target_path)
382
382
  shutil.copytree(source_path, target_path)
383
383
  else:
384
- # Fallback to save_bundle (will lose images)
385
- from scitex.io._bundle import save_bundle, BundleType
384
+ # Fallback to save (will lose images)
385
+ from scitex.io.bundle import save, BundleType
386
386
  target_path = dir_path / f"{panel_id}.pltz.d"
387
- save_bundle(plot_source, target_path, bundle_type=BundleType.PLTZ)
387
+ save(plot_source, target_path, bundle_type=BundleType.PLTZ)
388
388
 
389
389
 
390
390
  def _generate_figz_overview(dir_path: Path, spec: Dict, data: Dict, basename: str) -> None:
scitex/fts/README.md ADDED
@@ -0,0 +1,262 @@
1
+ <!-- ---
2
+ !-- Timestamp: 2025-12-20 07:20:45
3
+ !-- Author: ywatanabe
4
+ !-- File: /home/ywatanabe/proj/scitex-code/src/scitex/fsb/README.md
5
+ !-- --- -->
6
+
7
+ # SciTeX FTS (Figure-Table-Statistics)
8
+
9
+ **FTS is the single source of truth for bundle schemas in SciTeX.**
10
+
11
+ FTS defines a standardized, self-contained format for reproducible scientific figures with:
12
+ - Complete data provenance
13
+ - Statistical analysis results
14
+ - Visual encoding specifications
15
+ - Theme/aesthetic configuration
16
+
17
+ ## Design Philosophy
18
+
19
+ ### Separation of Concerns
20
+
21
+ FTS strictly separates:
22
+
23
+ | Layer | File | Purpose | Affects Science? |
24
+ |-------|------|---------|------------------|
25
+ | **Node** | `spec.json` | Structure (id, type, bbox, children) | Yes |
26
+ | **Encoding** | `encoding.json` | Data-to-Visual mapping (columns, scales) | Yes |
27
+ | **Theme** | `theme.json` | Aesthetics (colors, fonts, lines) | No |
28
+ | **Stats** | `stats.json` | Statistical results with provenance | Yes |
29
+ | **Data Info** | `data_info.json` | Column metadata, units, data source | Yes |
30
+
31
+ **Key insight**: Theme changes don't affect reproducibility. Encoding changes do.
32
+
33
+ ### Canonical vs Artifacts
34
+
35
+ ```
36
+ bundle_root/
37
+ ├── canonical/ # Source of truth (editable, human-readable)
38
+ │ ├── spec.json # Main specification
39
+ │ ├── data.csv # Source data
40
+ │ ├── encoding.json # Data-to-visual mappings
41
+ │ ├── theme.json # Visual aesthetics
42
+ │ ├── stats.json # Statistical results
43
+ │ ├── data_info.json # Column metadata
44
+ │ └── runtime.json # Runtime configuration
45
+ ├── artifacts/ # Derived/cached (can be deleted and regenerated)
46
+ │ ├── cache/
47
+ │ │ ├── geometry_px.json
48
+ │ │ └── render_manifest.json
49
+ │ └── exports/
50
+ │ ├── figure.svg
51
+ │ ├── figure.png
52
+ │ └── figure.pdf
53
+ └── children/ # Child bundles (for multi-panel figures)
54
+ ├── panel_a/
55
+ └── panel_b/
56
+ ```
57
+
58
+ ## Quick Start
59
+
60
+ ```python
61
+ from scitex import fts
62
+
63
+ # Create a new bundle
64
+ bundle = fts.FTS("my_plot.zip", create=True, node_type="plot", name="My Plot")
65
+
66
+ # Set encoding (data-to-visual mapping)
67
+ bundle.encoding = {
68
+ "traces": [
69
+ {
70
+ "trace_id": "main",
71
+ "data_ref": "data/experiment.csv",
72
+ "x": {"column": "time", "scale": "linear"},
73
+ "y": {"column": "amplitude", "scale": "log"},
74
+ "color": {"column": "condition"},
75
+ }
76
+ ]
77
+ }
78
+
79
+ # Set theme (pure aesthetics)
80
+ bundle.theme = {
81
+ "colors": {"palette": ["#1f77b4", "#ff7f0e", "#2ca02c"]},
82
+ "typography": {"family": "Arial", "size_pt": 10},
83
+ "lines": {"width_pt": 1.5},
84
+ }
85
+
86
+ # Save
87
+ bundle.save()
88
+ ```
89
+
90
+ ## Module Structure
91
+
92
+ ```
93
+ scitex/fts/
94
+ ├── __init__.py # Public API exports
95
+ ├── _bundle.py # FTS class
96
+ ├── _models.py # Core models (Node, BBox, SizeMM, Axes)
97
+ ├── _encoding.py # Encoding models (TraceEncoding, ChannelEncoding)
98
+ ├── _theme.py # Theme models (Theme, Colors, Typography)
99
+ ├── _stats.py # Stats models (Analysis, StatResult, EffectSize)
100
+ ├── _data_info.py # Data info models (DataInfo, ColumnDef)
101
+ ├── _validation.py # JSON schema validation
102
+ ├── _conversion.py # scitex to FTS format conversion
103
+ └── schemas/ # JSON Schema definitions
104
+ ├── node.schema.json
105
+ ├── encoding.schema.json
106
+ ├── theme.schema.json
107
+ ├── stats.schema.json
108
+ └── data_info.schema.json
109
+ ```
110
+
111
+ ## Core Models
112
+
113
+ ### Node (spec.json)
114
+
115
+ Structural metadata for the bundle:
116
+
117
+ ```python
118
+ from scitex.fts import Node, BBox, SizeMM
119
+
120
+ node = Node(
121
+ id="plot_001",
122
+ type="plot", # figure, plot, text, shape, image
123
+ name="Figure 1A",
124
+ bbox_norm=BBox(x0=0, y0=0, x1=1, y1=1),
125
+ size_mm=SizeMM(width=85, height=60), # Single column
126
+ children=["panel_a", "panel_b"], # For figures
127
+ )
128
+ ```
129
+
130
+ ### Encoding (encoding.json)
131
+
132
+ Data-to-visual channel mappings:
133
+
134
+ ```python
135
+ from scitex.fts import Encoding, TraceEncoding, ChannelEncoding
136
+
137
+ encoding = Encoding(
138
+ traces=[
139
+ TraceEncoding(
140
+ trace_id="line_1",
141
+ data_ref="data/timeseries.csv",
142
+ x=ChannelEncoding(column="time_ms", scale="linear"),
143
+ y=ChannelEncoding(column="voltage_mV", scale="linear"),
144
+ color=ChannelEncoding(column="channel", scale="categorical"),
145
+ )
146
+ ]
147
+ )
148
+ ```
149
+
150
+ ### Theme (theme.json)
151
+
152
+ Pure aesthetics (doesn't affect scientific meaning):
153
+
154
+ ```python
155
+ from scitex.fts import Theme, Colors, Typography
156
+
157
+ theme = Theme(
158
+ colors=Colors(
159
+ palette=["#1f77b4", "#ff7f0e", "#2ca02c"],
160
+ background="#ffffff",
161
+ text="#000000",
162
+ ),
163
+ typography=Typography(
164
+ family="Arial",
165
+ size_pt=8,
166
+ title_size_pt=10,
167
+ ),
168
+ preset="nature", # Named presets: nature, science, dark
169
+ )
170
+ ```
171
+
172
+ ### Stats (stats/stats.json)
173
+
174
+ Statistical analysis results with full provenance:
175
+
176
+ ```python
177
+ from scitex.fts import Stats, Analysis, StatMethod, StatResult, EffectSize
178
+
179
+ stats = Stats(
180
+ analyses=[
181
+ Analysis(
182
+ result_id="ttest_1",
183
+ method=StatMethod(
184
+ name="t-test",
185
+ variant="independent",
186
+ parameters={"equal_var": False},
187
+ ),
188
+ inputs={
189
+ "groups": ["control", "treatment"],
190
+ "n_per_group": [30, 28],
191
+ },
192
+ results=StatResult(
193
+ statistic=2.45,
194
+ statistic_name="t",
195
+ p_value=0.018,
196
+ df=56,
197
+ effect_size=EffectSize(
198
+ name="cohens_d",
199
+ value=0.65,
200
+ ci_lower=0.12,
201
+ ci_upper=1.18,
202
+ ),
203
+ ),
204
+ )
205
+ ],
206
+ software={"python": "3.11", "scipy": "1.11.0"},
207
+ )
208
+ ```
209
+
210
+ ## Validation
211
+
212
+ Validate bundles against JSON schemas:
213
+
214
+ ```python
215
+ from scitex.fts import validate_bundle, validate_node
216
+
217
+ # Validate entire bundle
218
+ errors = validate_bundle("my_figure.zip")
219
+ if errors:
220
+ for filename, error_list in errors.items():
221
+ print(f"{filename}: {error_list}")
222
+
223
+ # Validate individual components
224
+ node_errors = validate_node({"id": "test", "type": "plot", "bbox_norm": {...}})
225
+ ```
226
+
227
+ ## Conversion Utilities
228
+
229
+ Convert between scitex internal format and FTS format:
230
+
231
+ ```python
232
+ from scitex.fts import from_scitex_spec, to_scitex_spec
233
+
234
+ # scitex spec to FTS format
235
+ fts_data = from_scitex_spec(spec_dict, style_dict)
236
+ # Returns: {"node": {...}, "encoding": {...}, "theme": {...}}
237
+
238
+ # FTS bundle to scitex format
239
+ spec, style = to_scitex_spec(bundle)
240
+ ```
241
+
242
+ ## Backward Compatibility
243
+
244
+ FTS is also available via the legacy import path:
245
+
246
+ ```python
247
+ # Old path (still works)
248
+ from scitex import fsb # Alias for fts
249
+
250
+ # New path (preferred)
251
+ from scitex import fts
252
+ ```
253
+
254
+ ## Best Practices
255
+
256
+ 1. **Always specify units in data_info.json** - Critical for reproducibility
257
+ 2. **Use encoding for data-driven styling** - Color by condition, size by value
258
+ 3. **Keep theme separate from encoding** - Enables style changes without data loss
259
+ 4. **Include stats provenance** - Software versions, parameters, correction methods
260
+ 5. **Use canonical/ for source files** - artifacts/ can be regenerated
261
+
262
+ <!-- EOF -->
scitex/fts/TODO.md ADDED
@@ -0,0 +1,66 @@
1
+ <!-- ---
2
+ !-- Timestamp: 2025-12-21 11:02:24
3
+ !-- Author: ywatanabe
4
+ !-- File: /home/ywatanabe/proj/scitex-code/src/scitex/fts/TODO.md
5
+ !-- --- -->
6
+
7
+ ## Simplify Things
8
+ ## Explict Names
9
+ ## Kinds
10
+ ### figure
11
+ ### plot
12
+
13
+ #### Current
14
+ ```
15
+ ├── artifacts
16
+ │   ├── cache
17
+ │   │   ├── geometry_px.json
18
+ │   │   ├── hitmap.png
19
+ │   │   ├── hitmap.svg
20
+ │   │   └── render_manifest.json
21
+ │   └── exports
22
+ │   ├── figure.pdf
23
+ │   ├── figure.png
24
+ │   └── figure.svg
25
+ ├── canonical
26
+ │   ├── data_info.json
27
+ │   ├── encoding.json
28
+ │   ├── spec.json
29
+ │   └── theme.json
30
+ ├── children
31
+ └── payload
32
+ └── data.csv
33
+
34
+ ```
35
+
36
+ #### Revised
37
+ ```
38
+ ├── artifacts
39
+ │   ├── cache
40
+ │   │   ├── coordinates/
41
+
42
+ │   │   ├── hitmap.png
43
+ │   │   ├── hitmap.svg
44
+ │   │   └── render_manifest.json
45
+ │   └── exports
46
+ │   ├── figure.pdf
47
+ │   ├── figure.png
48
+ │   └── figure.svg
49
+ ├── canonical
50
+ │   ├── data_info.json
51
+ │   ├── encoding.json
52
+ │   ├── spec.json
53
+ │   └── theme.json
54
+ ├── children
55
+ └── payload
56
+ └── data.csv
57
+
58
+ ```
59
+
60
+ ### image
61
+ ### shape
62
+ ### stats
63
+ ### table
64
+ ### text
65
+
66
+ <!-- EOF -->
scitex/fts/__init__.py ADDED
@@ -0,0 +1,90 @@
1
+ #!/usr/bin/env python3
2
+ # Timestamp: 2025-12-20
3
+ # File: /home/ywatanabe/proj/scitex-code/src/scitex/fts/__init__.py
4
+
5
+ """
6
+ SciTeX FTS (Figure-Table-Statistics) - The single source of truth for bundle schemas.
7
+
8
+ FTS defines a standardized format for reproducible scientific figures and tables:
9
+ - Self-contained bundles with data, visualization spec, and stats
10
+ - Clear separation: Node (structure), Encoding (data mapping), Theme (aesthetics)
11
+ - Full provenance tracking for scientific reproducibility
12
+
13
+ Usage:
14
+ from scitex.fts import FTS, Node, Encoding, Theme
15
+
16
+ # Create new bundle
17
+ bundle = FTS("my_plot.zip", create=True, node_type="plot")
18
+ bundle.encoding = {"traces": [{"trace_id": "t1", "x": {"column": "time"}}]}
19
+ bundle.save()
20
+
21
+ # Load existing bundle
22
+ bundle = FTS("my_plot.zip")
23
+ print(bundle.node.type) # "plot"
24
+ """
25
+
26
+ # Version
27
+ __version__ = "1.0.0"
28
+
29
+ # =============================================================================
30
+ # Public API - What users need
31
+ # =============================================================================
32
+
33
+ # FTS class (main entry point)
34
+ from ._bundle import FTS, create_bundle, from_matplotlib, load_bundle
35
+
36
+ # Core dataclasses users interact with
37
+ from ._bundle import Node, BBox, SizeMM, DataInfo
38
+ from ._fig import Encoding, Theme
39
+ from ._stats import Stats
40
+
41
+ # Type enumeration
42
+ from ._bundle import NodeType
43
+
44
+ # Error classes for exception handling
45
+ from ._bundle import (
46
+ BundleError,
47
+ BundleNotFoundError,
48
+ BundleValidationError,
49
+ )
50
+
51
+ # Availability flags
52
+ FTS_AVAILABLE = True
53
+ FTS_VERSION = __version__
54
+
55
+ # Legacy aliases for backwards compatibility
56
+ FSB = FTS
57
+ FSB_AVAILABLE = FTS_AVAILABLE
58
+ FSB_VERSION = FTS_VERSION
59
+
60
+ __all__ = [
61
+ # Version
62
+ "__version__",
63
+ "FTS_AVAILABLE",
64
+ "FTS_VERSION",
65
+ # Legacy aliases
66
+ "FSB_AVAILABLE",
67
+ "FSB_VERSION",
68
+ "FSB",
69
+ # FTS class
70
+ "FTS",
71
+ "load_bundle",
72
+ "create_bundle",
73
+ "from_matplotlib",
74
+ # Core dataclasses
75
+ "Node",
76
+ "Encoding",
77
+ "Theme",
78
+ "Stats",
79
+ "BBox",
80
+ "SizeMM",
81
+ "DataInfo",
82
+ # Types
83
+ "NodeType",
84
+ # Errors
85
+ "BundleError",
86
+ "BundleNotFoundError",
87
+ "BundleValidationError",
88
+ ]
89
+
90
+ # EOF
@@ -0,0 +1,102 @@
1
+ # FTS Bundle (Figure-Table-Statistics)
2
+
3
+ This is a self-contained scientific figure bundle created with SciTeX.
4
+
5
+ ## Bundle Structure
6
+
7
+ ```
8
+ bundle_root/
9
+ ├── README.md # This file
10
+ ├── canonical/ # Source of truth (editable)
11
+ │ ├── spec.json # Main specification (type, id, elements)
12
+ │ ├── data.csv # Source data
13
+ │ ├── encoding.json # Data-to-visual channel mappings
14
+ │ ├── theme.json # Visual aesthetics (colors, fonts)
15
+ │ ├── stats.json # Statistical analysis results
16
+ │ ├── data_info.json # Column metadata and units
17
+ │ └── runtime.json # Runtime configuration
18
+ ├── artifacts/ # Derived files (can be regenerated)
19
+ │ ├── cache/ # Computed values
20
+ │ └── exports/ # Rendered outputs (PNG, SVG, PDF)
21
+ └── children/ # Child bundles (for multi-panel figures)
22
+ ```
23
+
24
+ ## Key Files
25
+
26
+ ### canonical/spec.json
27
+ Main specification defining the bundle structure:
28
+ - `id`: Unique bundle identifier
29
+ - `type`: Bundle type (figure, plot, text, etc.)
30
+ - `bbox_norm`: Normalized bounding box (0-1 coordinates)
31
+ - `size_mm`: Physical size in millimeters
32
+ - `elements`: Child elements or references
33
+
34
+ ### canonical/encoding.json
35
+ Data-to-visual mappings for scientific reproducibility:
36
+ - `traces`: List of data series with column bindings
37
+ - Each trace maps data columns to visual channels (x, y, color, size)
38
+
39
+ ### canonical/theme.json
40
+ Pure visual aesthetics (can be changed without affecting data):
41
+ - `colors`: Color palette and scheme
42
+ - `typography`: Font settings
43
+ - `lines`: Line styles and widths
44
+ - `markers`: Marker styles
45
+
46
+ ### canonical/stats.json
47
+ Statistical analysis results with full provenance:
48
+ - `analyses`: List of statistical tests performed
49
+ - Each analysis includes method, inputs, and results
50
+ - `software`: Version information for reproducibility
51
+
52
+ ### canonical/data_info.json
53
+ Metadata about data columns:
54
+ - Column names, types, and units
55
+ - Data source and hash for integrity
56
+ - Basic statistics for validation
57
+
58
+ ## Opening This Bundle
59
+
60
+ ### With Python (SciTeX)
61
+ ```python
62
+ from scitex import fsb
63
+
64
+ # Load the bundle
65
+ bundle = fsb.Bundle("path/to/this/bundle.zip")
66
+
67
+ # Access components
68
+ print(bundle.node.name)
69
+ print(bundle.encoding)
70
+ print(bundle.theme)
71
+ ```
72
+
73
+ ### With Any JSON Tool
74
+ All files in `canonical/` are standard JSON and can be viewed/edited with any text editor or JSON tool.
75
+
76
+ ### Exported Figures
77
+ Ready-to-use figures are in `artifacts/exports/`:
78
+ - `figure.svg` - Vector format (scalable)
79
+ - `figure.png` - Raster format (web/screen)
80
+ - `figure.pdf` - Print format
81
+
82
+ ## Reproducibility
83
+
84
+ This bundle contains everything needed to reproduce the figure:
85
+ 1. **Data**: Original data in `canonical/data.csv`
86
+ 2. **Encoding**: How data maps to visuals in `encoding.json`
87
+ 3. **Stats**: Statistical results with full provenance
88
+ 4. **Software**: Version info in `stats.json`
89
+
90
+ To regenerate exports:
91
+ ```python
92
+ from scitex import fsb
93
+ bundle = fsb.Bundle("this_bundle.zip")
94
+ # Exports will be regenerated on render
95
+ ```
96
+
97
+ ## License
98
+
99
+ The figure and data in this bundle are subject to the license terms specified by the original author. Contact information may be found in `spec.json`.
100
+
101
+ ---
102
+ *Created with [SciTeX](https://scitex.ai) FTS v1.0.0*