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.
- scitex/__init__.py +15 -7
- scitex/__version__.py +1 -2
- scitex/_install_guide.py +250 -0
- scitex/_optional_deps.py +206 -39
- scitex/ai/_gen_ai/_Groq.py +2 -4
- scitex/ai/_gen_ai/_OpenAI.py +5 -2
- scitex/ai/_gen_ai/_Perplexity.py +20 -6
- scitex/audio/__init__.py +24 -15
- scitex/audio/_cross_process_lock.py +139 -0
- scitex/audio/_mcp_handlers.py +256 -0
- scitex/audio/_mcp_tool_schemas.py +203 -0
- scitex/audio/engines/elevenlabs_engine.py +5 -2
- scitex/audio/mcp_server.py +98 -457
- scitex/bridge/__init__.py +30 -19
- scitex/bridge/_figrecipe.py +245 -0
- scitex/bridge/_helpers.py +2 -1
- scitex/bridge/_plt_vis.py +23 -10
- scitex/bridge/_stats_plt.py +18 -5
- scitex/bridge/_stats_vis.py +16 -2
- scitex/browser/__init__.py +84 -44
- scitex/browser/automation/__init__.py +5 -1
- scitex/browser/core/BrowserMixin.py +17 -4
- scitex/browser/core/__init__.py +11 -2
- scitex/browser/remote/CaptchaHandler.py +1 -1
- scitex/browser/remote/ZenRowsAPIClient.py +1 -1
- scitex/capture/grid.py +487 -0
- scitex/capture/mcp_handlers.py +401 -0
- scitex/capture/mcp_tool_defs.py +192 -0
- scitex/capture/mcp_tools.py +241 -0
- scitex/capture/mcp_utils.py +30 -0
- scitex/cli/convert.py +421 -0
- scitex/cli/main.py +6 -4
- scitex/datetime/__init__.py +46 -0
- scitex/datetime/_linspace.py +100 -0
- scitex/datetime/_normalize_timestamp.py +306 -0
- scitex/db/_delete_duplicates.py +4 -4
- scitex/db/_sqlite3/_delete_duplicates.py +11 -2
- scitex/dev/plt/__init__.py +61 -62
- scitex/dev/plt/demo_plotters/__init__.py +0 -0
- scitex/dev/plt/demo_plotters/plot_mpl_axhline.py +28 -0
- scitex/dev/plt/demo_plotters/plot_mpl_axhspan.py +28 -0
- scitex/dev/plt/demo_plotters/plot_mpl_axvline.py +28 -0
- scitex/dev/plt/demo_plotters/plot_mpl_axvspan.py +28 -0
- scitex/dev/plt/demo_plotters/plot_mpl_bar.py +29 -0
- scitex/dev/plt/demo_plotters/plot_mpl_barh.py +29 -0
- scitex/dev/plt/demo_plotters/plot_mpl_boxplot.py +28 -0
- scitex/dev/plt/demo_plotters/plot_mpl_contour.py +31 -0
- scitex/dev/plt/demo_plotters/plot_mpl_contourf.py +31 -0
- scitex/dev/plt/demo_plotters/plot_mpl_errorbar.py +30 -0
- scitex/dev/plt/demo_plotters/plot_mpl_eventplot.py +28 -0
- scitex/dev/plt/demo_plotters/plot_mpl_fill.py +30 -0
- scitex/dev/plt/demo_plotters/plot_mpl_fill_between.py +31 -0
- scitex/dev/plt/demo_plotters/plot_mpl_hexbin.py +28 -0
- scitex/dev/plt/demo_plotters/plot_mpl_hist.py +28 -0
- scitex/dev/plt/demo_plotters/plot_mpl_hist2d.py +28 -0
- scitex/dev/plt/demo_plotters/plot_mpl_imshow.py +29 -0
- scitex/dev/plt/demo_plotters/plot_mpl_pcolormesh.py +31 -0
- scitex/dev/plt/demo_plotters/plot_mpl_pie.py +29 -0
- scitex/dev/plt/demo_plotters/plot_mpl_plot.py +29 -0
- scitex/dev/plt/demo_plotters/plot_mpl_quiver.py +31 -0
- scitex/dev/plt/demo_plotters/plot_mpl_scatter.py +28 -0
- scitex/dev/plt/demo_plotters/plot_mpl_stackplot.py +31 -0
- scitex/dev/plt/demo_plotters/plot_mpl_stem.py +29 -0
- scitex/dev/plt/demo_plotters/plot_mpl_step.py +29 -0
- scitex/dev/plt/demo_plotters/plot_mpl_violinplot.py +28 -0
- scitex/dev/plt/demo_plotters/plot_sns_barplot.py +29 -0
- scitex/dev/plt/demo_plotters/plot_sns_boxplot.py +29 -0
- scitex/dev/plt/demo_plotters/plot_sns_heatmap.py +28 -0
- scitex/dev/plt/demo_plotters/plot_sns_histplot.py +29 -0
- scitex/dev/plt/demo_plotters/plot_sns_kdeplot.py +29 -0
- scitex/dev/plt/demo_plotters/plot_sns_lineplot.py +31 -0
- scitex/dev/plt/demo_plotters/plot_sns_scatterplot.py +29 -0
- scitex/dev/plt/demo_plotters/plot_sns_stripplot.py +29 -0
- scitex/dev/plt/demo_plotters/plot_sns_swarmplot.py +29 -0
- scitex/dev/plt/demo_plotters/plot_sns_violinplot.py +29 -0
- scitex/dev/plt/demo_plotters/plot_stx_bar.py +29 -0
- scitex/dev/plt/demo_plotters/plot_stx_barh.py +29 -0
- scitex/dev/plt/demo_plotters/plot_stx_box.py +28 -0
- scitex/dev/plt/demo_plotters/plot_stx_boxplot.py +28 -0
- scitex/dev/plt/demo_plotters/plot_stx_conf_mat.py +28 -0
- scitex/dev/plt/demo_plotters/plot_stx_contour.py +31 -0
- scitex/dev/plt/demo_plotters/plot_stx_ecdf.py +28 -0
- scitex/dev/plt/demo_plotters/plot_stx_errorbar.py +30 -0
- scitex/dev/plt/demo_plotters/plot_stx_fill_between.py +31 -0
- scitex/dev/plt/demo_plotters/plot_stx_fillv.py +28 -0
- scitex/dev/plt/demo_plotters/plot_stx_heatmap.py +28 -0
- scitex/dev/plt/demo_plotters/plot_stx_image.py +28 -0
- scitex/dev/plt/demo_plotters/plot_stx_imshow.py +28 -0
- scitex/dev/plt/demo_plotters/plot_stx_joyplot.py +28 -0
- scitex/dev/plt/demo_plotters/plot_stx_kde.py +28 -0
- scitex/dev/plt/demo_plotters/plot_stx_line.py +28 -0
- scitex/dev/plt/demo_plotters/plot_stx_mean_ci.py +28 -0
- scitex/dev/plt/demo_plotters/plot_stx_mean_std.py +28 -0
- scitex/dev/plt/demo_plotters/plot_stx_median_iqr.py +28 -0
- scitex/dev/plt/demo_plotters/plot_stx_raster.py +28 -0
- scitex/dev/plt/demo_plotters/plot_stx_rectangle.py +28 -0
- scitex/dev/plt/demo_plotters/plot_stx_scatter.py +29 -0
- scitex/dev/plt/demo_plotters/plot_stx_shaded_line.py +29 -0
- scitex/dev/plt/demo_plotters/plot_stx_violin.py +28 -0
- scitex/dev/plt/demo_plotters/plot_stx_violinplot.py +28 -0
- scitex/dev/plt/mpl/get_dir_ax.py +46 -0
- scitex/dev/plt/mpl/get_signatures.py +176 -0
- scitex/dev/plt/mpl/get_signatures_details.py +522 -0
- scitex/dict/_pop_keys.py +1 -7
- scitex/dsp/__init__.py +15 -10
- scitex/dsp/add_noise.py +5 -2
- scitex/dsp/example.py +35 -22
- scitex/dsp/filt.py +8 -3
- scitex/dsp/reference.py +3 -2
- scitex/dsp/utils/__init__.py +2 -1
- scitex/dsp/utils/_differential_bandpass_filters.py +14 -4
- scitex/dt/__init__.py +39 -2
- scitex/errors.py +82 -521
- scitex/fig/__init__.py +4 -4
- scitex/fig/editor/edit/panel_loader.py +1 -1
- scitex/fig/io/_bundle.py +7 -7
- scitex/fts/README.md +262 -0
- scitex/fts/TODO.md +66 -0
- scitex/fts/__init__.py +90 -0
- scitex/fts/_bundle/README_IN_BUNDLE.md +102 -0
- scitex/fts/_bundle/_FTS.py +657 -0
- scitex/fts/_bundle/__init__.py +38 -0
- scitex/fts/_bundle/_children.py +216 -0
- scitex/fts/_bundle/_conversion/__init__.py +15 -0
- scitex/fts/_bundle/_conversion/_bundle2dict.py +44 -0
- scitex/fts/_bundle/_conversion/_dict2bundle.py +50 -0
- scitex/fts/_bundle/_dataclasses/_Axes.py +57 -0
- scitex/fts/_bundle/_dataclasses/_BBox.py +54 -0
- scitex/fts/_bundle/_dataclasses/_ColumnDef.py +72 -0
- scitex/fts/_bundle/_dataclasses/_DataFormat.py +40 -0
- scitex/fts/_bundle/_dataclasses/_DataInfo.py +135 -0
- scitex/fts/_bundle/_dataclasses/_DataSource.py +44 -0
- scitex/fts/_bundle/_dataclasses/_Node.py +319 -0
- scitex/fts/_bundle/_dataclasses/_NodeRefs.py +45 -0
- scitex/fts/_bundle/_dataclasses/_SizeMM.py +38 -0
- scitex/fts/_bundle/_dataclasses/__init__.py +35 -0
- scitex/fts/_bundle/_extractors/__init__.py +32 -0
- scitex/fts/_bundle/_extractors/_extract_bar.py +131 -0
- scitex/fts/_bundle/_extractors/_extract_line.py +71 -0
- scitex/fts/_bundle/_extractors/_extract_scatter.py +79 -0
- scitex/fts/_bundle/_loader.py +134 -0
- scitex/fts/_bundle/_mpl_helpers.py +389 -0
- scitex/fts/_bundle/_saver.py +269 -0
- scitex/fts/_bundle/_storage.py +200 -0
- scitex/fts/_bundle/_utils/__init__.py +55 -0
- scitex/fts/_bundle/_utils/_const.py +26 -0
- scitex/fts/_bundle/_utils/_errors.py +73 -0
- scitex/fts/_bundle/_utils/_generate.py +21 -0
- scitex/fts/_bundle/_utils/_types.py +76 -0
- scitex/fts/_bundle/_validation.py +434 -0
- scitex/fts/_bundle/_zipbundle.py +165 -0
- scitex/fts/_fig/__init__.py +22 -0
- scitex/fts/_fig/_backend/__init__.py +53 -0
- scitex/fts/_fig/_backend/_export.py +165 -0
- scitex/fts/_fig/_backend/_parser.py +188 -0
- scitex/fts/_fig/_backend/_render.py +538 -0
- scitex/fts/_fig/_composite.py +345 -0
- scitex/fts/_fig/_dataclasses/_ChannelEncoding.py +46 -0
- scitex/fts/_fig/_dataclasses/_Encoding.py +82 -0
- scitex/fts/_fig/_dataclasses/_Theme.py +441 -0
- scitex/fts/_fig/_dataclasses/_TraceEncoding.py +52 -0
- scitex/fts/_fig/_dataclasses/__init__.py +47 -0
- scitex/fts/_fig/_editor/__init__.py +14 -0
- scitex/fts/_fig/_editor/_cui/__init__.py +33 -0
- scitex/fts/_fig/_editor/_cui/_backend_detector.py +39 -0
- scitex/fts/_fig/_editor/_cui/_bundle_resolver.py +366 -0
- scitex/fts/_fig/_editor/_cui/_editor_launcher.py +175 -0
- scitex/fts/_fig/_editor/_cui/_manual_handler.py +52 -0
- scitex/fts/_fig/_editor/_cui/_panel_loader.py +246 -0
- scitex/fts/_fig/_editor/_cui/_path_resolver.py +66 -0
- scitex/fts/_fig/_editor/_defaults.py +300 -0
- scitex/fts/_fig/_editor/_gui/__init__.py +11 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/__init__.py +20 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/_bbox.py +1339 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/_core.py +1688 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/_plotter.py +664 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/_renderer.py +853 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/_utils.py +79 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/reset.css +41 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/typography.css +16 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/variables.css +85 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/buttons.css +217 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/context-menu.css +93 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/dropdown.css +57 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/forms.css +112 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/modal.css +59 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/sections.css +212 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/canvas.css +176 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/element-inspector.css +190 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/loading.css +59 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/overlay.css +45 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/panel-grid.css +95 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/selection.css +101 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/statistics.css +138 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/index.css +31 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/container.css +7 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/controls.css +56 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/preview.css +78 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/axis.js +314 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/basic.js +107 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/distribute.js +54 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/canvas.js +172 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/dragging.js +258 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/resize.js +48 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/selection.js +71 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/api.js +288 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/state.js +143 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/utils.js +245 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/dev/element-inspector.js +992 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/bbox.js +339 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/element-drag.js +286 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/overlay.js +371 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/preview.js +293 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/main.js +426 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/context-menu.js +152 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/keyboard.js +265 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/controls.js +184 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/download.js +57 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/help.js +100 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/theme.js +34 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/templates/__init__.py +124 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_html.py +851 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_scripts.py +4932 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_styles.py +1657 -0
- scitex/fts/_fig/_editor/_gui/_flask_editor.py +36 -0
- scitex/fts/_fig/_models/_Annotations.py +115 -0
- scitex/fts/_fig/_models/_Axes.py +152 -0
- scitex/fts/_fig/_models/_Figure.py +138 -0
- scitex/fts/_fig/_models/_Guides.py +104 -0
- scitex/fts/_fig/_models/_Plot.py +123 -0
- scitex/fts/_fig/_models/_Styles.py +245 -0
- scitex/fts/_fig/_models/__init__.py +80 -0
- scitex/fts/_fig/_models/_plot_types/__init__.py +156 -0
- scitex/fts/_fig/_models/_plot_types/_bar.py +43 -0
- scitex/fts/_fig/_models/_plot_types/_box.py +38 -0
- scitex/fts/_fig/_models/_plot_types/_distribution.py +36 -0
- scitex/fts/_fig/_models/_plot_types/_errorbar.py +60 -0
- scitex/fts/_fig/_models/_plot_types/_histogram.py +30 -0
- scitex/fts/_fig/_models/_plot_types/_image.py +61 -0
- scitex/fts/_fig/_models/_plot_types/_line.py +57 -0
- scitex/fts/_fig/_models/_plot_types/_scatter.py +30 -0
- scitex/fts/_fig/_models/_plot_types/_seaborn.py +121 -0
- scitex/fts/_fig/_models/_plot_types/_violin.py +36 -0
- scitex/fts/_fig/_utils/__init__.py +129 -0
- scitex/fts/_fig/_utils/_auto_layout.py +127 -0
- scitex/fts/_fig/_utils/_calc_bounds.py +111 -0
- scitex/fts/_fig/_utils/_const_sizes.py +48 -0
- scitex/fts/_fig/_utils/_convert_coords.py +77 -0
- scitex/fts/_fig/_utils/_get_template.py +178 -0
- scitex/fts/_fig/_utils/_normalize.py +73 -0
- scitex/fts/_fig/_utils/_plot_layout.py +397 -0
- scitex/fts/_fig/_utils/_validate.py +197 -0
- scitex/fts/_kinds/__init__.py +45 -0
- scitex/fts/_kinds/_figure/__init__.py +19 -0
- scitex/fts/_kinds/_figure/_composite.py +345 -0
- scitex/fts/_kinds/_plot/__init__.py +25 -0
- scitex/fts/_kinds/_plot/_backend/__init__.py +53 -0
- scitex/fts/_kinds/_plot/_backend/_export.py +165 -0
- scitex/fts/_kinds/_plot/_backend/_parser.py +188 -0
- scitex/fts/_kinds/_plot/_backend/_render.py +538 -0
- scitex/fts/_kinds/_plot/_dataclasses/_ChannelEncoding.py +46 -0
- scitex/fts/_kinds/_plot/_dataclasses/_Encoding.py +82 -0
- scitex/fts/_kinds/_plot/_dataclasses/_Theme.py +441 -0
- scitex/fts/_kinds/_plot/_dataclasses/_TraceEncoding.py +52 -0
- scitex/fts/_kinds/_plot/_dataclasses/__init__.py +47 -0
- scitex/fts/_kinds/_plot/_models/_Annotations.py +115 -0
- scitex/fts/_kinds/_plot/_models/_Axes.py +152 -0
- scitex/fts/_kinds/_plot/_models/_Figure.py +138 -0
- scitex/fts/_kinds/_plot/_models/_Guides.py +104 -0
- scitex/fts/_kinds/_plot/_models/_Plot.py +123 -0
- scitex/fts/_kinds/_plot/_models/_Styles.py +245 -0
- scitex/fts/_kinds/_plot/_models/__init__.py +80 -0
- scitex/fts/_kinds/_plot/_models/_plot_types/__init__.py +156 -0
- scitex/fts/_kinds/_plot/_models/_plot_types/_bar.py +43 -0
- scitex/fts/_kinds/_plot/_models/_plot_types/_box.py +38 -0
- scitex/fts/_kinds/_plot/_models/_plot_types/_distribution.py +36 -0
- scitex/fts/_kinds/_plot/_models/_plot_types/_errorbar.py +60 -0
- scitex/fts/_kinds/_plot/_models/_plot_types/_histogram.py +30 -0
- scitex/fts/_kinds/_plot/_models/_plot_types/_image.py +61 -0
- scitex/fts/_kinds/_plot/_models/_plot_types/_line.py +57 -0
- scitex/fts/_kinds/_plot/_models/_plot_types/_scatter.py +30 -0
- scitex/fts/_kinds/_plot/_models/_plot_types/_seaborn.py +121 -0
- scitex/fts/_kinds/_plot/_models/_plot_types/_violin.py +36 -0
- scitex/fts/_kinds/_plot/_utils/__init__.py +129 -0
- scitex/fts/_kinds/_plot/_utils/_auto_layout.py +127 -0
- scitex/fts/_kinds/_plot/_utils/_calc_bounds.py +111 -0
- scitex/fts/_kinds/_plot/_utils/_const_sizes.py +48 -0
- scitex/fts/_kinds/_plot/_utils/_convert_coords.py +77 -0
- scitex/fts/_kinds/_plot/_utils/_get_template.py +178 -0
- scitex/fts/_kinds/_plot/_utils/_normalize.py +73 -0
- scitex/fts/_kinds/_plot/_utils/_plot_layout.py +397 -0
- scitex/fts/_kinds/_plot/_utils/_validate.py +197 -0
- scitex/fts/_kinds/_shape/__init__.py +141 -0
- scitex/fts/_kinds/_stats/__init__.py +56 -0
- scitex/fts/_kinds/_stats/_dataclasses/_Stats.py +423 -0
- scitex/fts/_kinds/_stats/_dataclasses/__init__.py +48 -0
- scitex/fts/_kinds/_table/__init__.py +72 -0
- scitex/fts/_kinds/_table/_latex/__init__.py +93 -0
- scitex/fts/_kinds/_table/_latex/_editor/__init__.py +11 -0
- scitex/fts/_kinds/_table/_latex/_editor/_app.py +725 -0
- scitex/fts/_kinds/_table/_latex/_export.py +279 -0
- scitex/fts/_kinds/_table/_latex/_figure_exporter.py +153 -0
- scitex/fts/_kinds/_table/_latex/_stats_formatter.py +274 -0
- scitex/fts/_kinds/_table/_latex/_table_exporter.py +362 -0
- scitex/fts/_kinds/_table/_latex/_utils.py +369 -0
- scitex/fts/_kinds/_table/_latex/_validator.py +445 -0
- scitex/fts/_kinds/_text/__init__.py +77 -0
- scitex/fts/_schemas/data_info.schema.json +75 -0
- scitex/fts/_schemas/encoding.schema.json +90 -0
- scitex/fts/_schemas/node.schema.json +145 -0
- scitex/fts/_schemas/render_manifest.schema.json +62 -0
- scitex/fts/_schemas/stats.schema.json +132 -0
- scitex/fts/_schemas/theme.schema.json +141 -0
- scitex/fts/_stats/__init__.py +48 -0
- scitex/fts/_stats/_dataclasses/_Stats.py +423 -0
- scitex/fts/_stats/_dataclasses/__init__.py +48 -0
- scitex/fts/_tables/__init__.py +65 -0
- scitex/fts/_tables/_latex/__init__.py +93 -0
- scitex/fts/_tables/_latex/_editor/__init__.py +11 -0
- scitex/fts/_tables/_latex/_editor/_app.py +725 -0
- scitex/fts/_tables/_latex/_export.py +279 -0
- scitex/fts/_tables/_latex/_figure_exporter.py +153 -0
- scitex/fts/_tables/_latex/_stats_formatter.py +274 -0
- scitex/fts/_tables/_latex/_table_exporter.py +362 -0
- scitex/fts/_tables/_latex/_utils.py +369 -0
- scitex/fts/_tables/_latex/_validator.py +445 -0
- scitex/gen/__init__.py +66 -25
- scitex/gen/misc.py +28 -0
- scitex/io/__init__.py +47 -32
- scitex/io/_load.py +87 -36
- scitex/io/_load_modules/__init__.py +10 -7
- scitex/io/_load_modules/_pandas.py +6 -1
- scitex/io/_save.py +299 -1556
- scitex/io/_save_modules/__init__.py +76 -19
- scitex/io/_save_modules/_figure_utils.py +90 -0
- scitex/io/_save_modules/_image_csv.py +497 -0
- scitex/io/_save_modules/_legends.py +91 -0
- scitex/io/_save_modules/_pltz_bundle.py +356 -0
- scitex/io/_save_modules/_pltz_stx.py +536 -0
- scitex/io/_save_modules/_stx_bundle.py +104 -0
- scitex/io/_save_modules/_symlink.py +96 -0
- scitex/io/_save_modules/_yaml.py +1 -1
- scitex/io/_save_modules/_zarr.py +64 -18
- scitex/io/bundle/README.md +212 -0
- scitex/io/bundle/__init__.py +110 -0
- scitex/io/{_bundle.py → bundle/_core.py} +168 -97
- scitex/io/bundle/_nested.py +713 -0
- scitex/io/bundle/_types.py +74 -0
- scitex/io/{_zip_bundle.py → bundle/_zip.py} +93 -45
- scitex/io/utils/h5_to_zarr.py +1 -1
- scitex/logging/__init__.py +108 -13
- scitex/logging/_errors.py +508 -0
- scitex/logging/_formatters.py +30 -6
- scitex/logging/_warnings.py +261 -0
- scitex/plt/__init__.py +4 -1
- scitex/plt/_figrecipe.py +236 -0
- scitex/plt/_subplots/_AxisWrapper.py +6 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_UnitAwareMixin.py +112 -1
- scitex/plt/_subplots/_FigWrapper.py +15 -0
- scitex/plt/_subplots/_SubplotsWrapper.py +125 -489
- scitex/plt/_subplots/_export_as_csv.py +11 -0
- scitex/plt/_subplots/_export_as_csv_formatters/__init__.py +2 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_pcolormesh.py +66 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stackplot.py +62 -0
- scitex/plt/_subplots/_export_as_csv_formatters/test_formatters.py +208 -0
- scitex/plt/_subplots/_fonts.py +71 -0
- scitex/plt/_subplots/_mm_layout.py +282 -0
- scitex/plt/gallery/__init__.py +99 -2
- scitex/plt/styles/_plot_postprocess.py +3 -1
- scitex/plt/utils/_configure_mpl.py +16 -19
- scitex/repro/_RandomStateManager.py +13 -8
- scitex/resource/__init__.py +19 -1
- scitex/resource/_utils/_get_env_info.py +13 -25
- scitex/schema/__init__.py +149 -160
- scitex/schema/_encoding.py +273 -0
- scitex/schema/_figure_elements.py +406 -0
- scitex/schema/_theme.py +360 -0
- scitex/schema/_validation.py +0 -98
- scitex/scholar/__init__.py +56 -14
- scitex/scholar/auth/ScholarAuthManager.py +1 -1
- scitex/scholar/auth/__init__.py +11 -2
- scitex/scholar/auth/providers/BaseAuthenticator.py +1 -1
- scitex/scholar/auth/providers/EZProxyAuthenticator.py +1 -1
- scitex/scholar/auth/providers/OpenAthensAuthenticator.py +1 -1
- scitex/scholar/auth/providers/ShibbolethAuthenticator.py +1 -1
- scitex/scholar/config/ScholarConfig.py +1 -1
- scitex/scholar/core/Scholar.py +1 -1
- scitex/session/_decorator.py +18 -16
- scitex/session/_lifecycle.py +9 -11
- scitex/session/template.py +9 -8
- scitex/sh/test_sh.py +72 -0
- scitex/sh/test_sh_simple.py +61 -0
- scitex/stats/__init__.py +221 -97
- scitex/stats/_schema.py +21 -22
- scitex/stats/descriptive/_circular.py +212 -351
- scitex/stats/descriptive/_describe.py +81 -132
- scitex/stats/descriptive/_nan.py +205 -433
- scitex/stats/descriptive/_real.py +127 -141
- scitex/str/_format_plot_text.py +5 -5
- scitex/str/_latex.py +26 -84
- scitex/str/_latex_fallback.py +53 -47
- scitex/web/_search_pubmed.py +5 -4
- scitex/writer/tests/test_diff_between.py +451 -0
- scitex/writer/tests/test_document_section.py +311 -0
- scitex/writer/tests/test_document_workflow.py +393 -0
- scitex/writer/tests/test_writer.py +361 -0
- scitex/writer/tests/test_writer_integration.py +303 -0
- {scitex-2.8.1.dist-info → scitex-2.10.0.dist-info}/METADATA +364 -181
- {scitex-2.8.1.dist-info → scitex-2.10.0.dist-info}/RECORD +412 -97
- scitex/scholar/docs/to_claude/guidelines/examples/mgmt/ARCHITECTURE_EXAMPLE.md +0 -905
- scitex/scholar/docs/to_claude/guidelines/examples/mgmt/BULLETIN_BOARD_EXAMPLE.md +0 -99
- scitex/scholar/docs/to_claude/guidelines/examples/mgmt/PROJECT_DESCRIPTION_EXAMPLE.md +0 -96
- {scitex-2.8.1.dist-info → scitex-2.10.0.dist-info}/WHEEL +0 -0
- {scitex-2.8.1.dist-info → scitex-2.10.0.dist-info}/entry_points.txt +0 -0
- {scitex-2.8.1.dist-info → scitex-2.10.0.dist-info}/licenses/LICENSE +0 -0
scitex/session/_decorator.py
CHANGED
|
@@ -185,18 +185,19 @@ def _run_with_session(
|
|
|
185
185
|
func_globals["rng_manager"] = rng_manager
|
|
186
186
|
func_globals["logger"] = script_logger
|
|
187
187
|
|
|
188
|
-
# Log injected globals for user awareness
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
188
|
+
# Log injected globals for user awareness (only in verbose mode)
|
|
189
|
+
if verbose:
|
|
190
|
+
_decorator_logger.info("=" * 60)
|
|
191
|
+
_decorator_logger.info("Injected Global Variables (available in your function):")
|
|
192
|
+
_decorator_logger.info(" • CONFIG - Session configuration dict")
|
|
193
|
+
_decorator_logger.info(f" - CONFIG['ID']: {CONFIG['ID']}")
|
|
194
|
+
_decorator_logger.info(f" - CONFIG['SDIR_RUN']: {CONFIG['SDIR_RUN']}")
|
|
195
|
+
_decorator_logger.info(f" - CONFIG['PID']: {CONFIG['PID']}")
|
|
196
|
+
_decorator_logger.info(" • plt - matplotlib.pyplot (configured for session)")
|
|
197
|
+
_decorator_logger.info(" • COLORS - CustomColors (for consistent plotting)")
|
|
198
|
+
_decorator_logger.info(" • rng_manager - RandomStateManager (for reproducibility)")
|
|
199
|
+
_decorator_logger.info(" • logger - SciTeX logger (configured for your script)")
|
|
200
|
+
_decorator_logger.info("=" * 60)
|
|
200
201
|
|
|
201
202
|
# Run function
|
|
202
203
|
exit_status = 0
|
|
@@ -235,10 +236,11 @@ def _run_with_session(
|
|
|
235
236
|
if param_name in injection_map:
|
|
236
237
|
filtered_kwargs[param_name] = injection_map[param_name]
|
|
237
238
|
|
|
238
|
-
# Log injected arguments summary
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
239
|
+
# Log injected arguments summary (only in verbose mode)
|
|
240
|
+
if verbose:
|
|
241
|
+
args_summary = {k: type(v).__name__ for k, v in filtered_kwargs.items()}
|
|
242
|
+
_decorator_logger.info(f"Running {func.__name__} with injected parameters:")
|
|
243
|
+
_decorator_logger.info(args_summary, pprint=True, indent=2)
|
|
242
244
|
|
|
243
245
|
# Execute function
|
|
244
246
|
result = func(**filtered_kwargs)
|
scitex/session/_lifecycle.py
CHANGED
|
@@ -123,20 +123,18 @@ def _print_header(
|
|
|
123
123
|
|
|
124
124
|
_printc(
|
|
125
125
|
(
|
|
126
|
-
f"SciTeX v{_get_scitex_version()}\n"
|
|
127
|
-
f"{ID} (PID: {PID})\n\n"
|
|
126
|
+
f"SciTeX v{_get_scitex_version()} | {ID} (PID: {PID})\n\n"
|
|
128
127
|
f"{file}\n\n"
|
|
129
128
|
f"{args_str}"
|
|
130
|
-
# f"{args}"
|
|
131
129
|
),
|
|
132
130
|
char="=",
|
|
133
131
|
)
|
|
134
132
|
|
|
135
133
|
sleep(1)
|
|
136
134
|
if verbose:
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
135
|
+
from pprint import pformat
|
|
136
|
+
config_str = pformat(configs.to_dict())
|
|
137
|
+
logger.info(f"\n{'-' * 40}\n\n{config_str}\n\n{'-' * 40}\n")
|
|
140
138
|
sleep(1)
|
|
141
139
|
|
|
142
140
|
|
|
@@ -579,11 +577,11 @@ def _process_timestamp(CONFIG, verbose=True):
|
|
|
579
577
|
CONFIG["END_DATETIME"] - CONFIG["START_DATETIME"]
|
|
580
578
|
)
|
|
581
579
|
if verbose:
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
580
|
+
logger.info(
|
|
581
|
+
f"\nSTART TIME: {CONFIG['START_DATETIME']}\n"
|
|
582
|
+
f"END TIME: {CONFIG['END_DATETIME']}\n"
|
|
583
|
+
f"RUN DURATION: {CONFIG['RUN_DURATION']}\n"
|
|
584
|
+
)
|
|
587
585
|
|
|
588
586
|
except Exception as e:
|
|
589
587
|
print(e)
|
scitex/session/template.py
CHANGED
|
@@ -1,22 +1,23 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
2
|
# Timestamp: "2025-11-18 09:08:38 (ywatanabe)"
|
|
4
3
|
# File: /home/ywatanabe/proj/scitex-code/src/scitex/session/template.py
|
|
5
4
|
|
|
6
5
|
|
|
7
6
|
from pprint import pprint
|
|
8
|
-
import scitex as stx
|
|
9
7
|
|
|
8
|
+
from scitex import INJECTED
|
|
9
|
+
from scitex.session import session
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
|
|
12
|
+
@session(verbose=False)
|
|
12
13
|
def main(
|
|
13
14
|
arg1=None,
|
|
14
15
|
arg2=None,
|
|
15
|
-
CONFIG=
|
|
16
|
-
plt=
|
|
17
|
-
COLORS=
|
|
18
|
-
rng_manager=
|
|
19
|
-
logger=
|
|
16
|
+
CONFIG=INJECTED,
|
|
17
|
+
plt=INJECTED,
|
|
18
|
+
COLORS=INJECTED,
|
|
19
|
+
rng_manager=INJECTED,
|
|
20
|
+
logger=INJECTED,
|
|
20
21
|
):
|
|
21
22
|
"""Demonstration for scitex.session.session"""
|
|
22
23
|
pprint(CONFIG)
|
scitex/sh/test_sh.py
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Timestamp: "2025-10-29 07:23:59 (ywatanabe)"
|
|
4
|
+
# File: /home/ywatanabe/proj/scitex-code/src/scitex/sh/test_sh.py
|
|
5
|
+
# ----------------------------------------
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
|
|
10
|
+
__FILE__ = (
|
|
11
|
+
"./src/scitex/sh/test_sh.py"
|
|
12
|
+
)
|
|
13
|
+
__DIR__ = os.path.dirname(__FILE__)
|
|
14
|
+
# ----------------------------------------
|
|
15
|
+
|
|
16
|
+
__FILE__ = __file__
|
|
17
|
+
|
|
18
|
+
import sys
|
|
19
|
+
|
|
20
|
+
import matplotlib.pyplot as plt
|
|
21
|
+
|
|
22
|
+
import scitex
|
|
23
|
+
|
|
24
|
+
CONFIG, sys.stdout, sys.stderr, plt, CC = scitex.session.start(
|
|
25
|
+
sys, plt, verbose=False
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
# Test 1: Basic list command
|
|
29
|
+
print("Test 1: Basic list command")
|
|
30
|
+
result = scitex.sh(["echo", "Hello World"], verbose=True)
|
|
31
|
+
print(f"Result: {result}\n")
|
|
32
|
+
|
|
33
|
+
# Test 2: String command should be rejected
|
|
34
|
+
print("Test 2: String command rejection")
|
|
35
|
+
try:
|
|
36
|
+
result = scitex.sh("echo 'Hello'")
|
|
37
|
+
print("ERROR: Should have raised TypeError")
|
|
38
|
+
except TypeError as ee:
|
|
39
|
+
print(f"Correctly rejected: {ee}\n")
|
|
40
|
+
|
|
41
|
+
# Test 3: sh_run convenience function
|
|
42
|
+
print("Test 3: sh_run convenience function")
|
|
43
|
+
result = scitex.sh_run(["ls", "-la"])
|
|
44
|
+
print(f"Success: {result['success']}, Exit code: {result['exit_code']}\n")
|
|
45
|
+
|
|
46
|
+
# Test 4: Error handling
|
|
47
|
+
print("Test 4: Error handling")
|
|
48
|
+
result = scitex.sh_run(["cat", "/nonexistent/file"], verbose=False)
|
|
49
|
+
print(f"Success: {result['success']}")
|
|
50
|
+
print(f"Exit code: {result['exit_code']}")
|
|
51
|
+
print(f"Stderr: {result['stderr']}\n")
|
|
52
|
+
|
|
53
|
+
# Test 5: Security - quote function
|
|
54
|
+
print("Test 5: Security - quote function")
|
|
55
|
+
from scitex.sh import quote
|
|
56
|
+
|
|
57
|
+
dangerous_input = "file; rm -rf /"
|
|
58
|
+
safe_quoted = quote(dangerous_input)
|
|
59
|
+
print(f"Original: {dangerous_input}")
|
|
60
|
+
print(f"Quoted: {safe_quoted}\n")
|
|
61
|
+
|
|
62
|
+
# Test 6: Security - null byte rejection
|
|
63
|
+
print("Test 6: Security - null byte rejection")
|
|
64
|
+
try:
|
|
65
|
+
scitex.sh(["echo", "test\0malicious"])
|
|
66
|
+
print("ERROR: Should have raised ValueError")
|
|
67
|
+
except ValueError as ee:
|
|
68
|
+
print(f"Correctly rejected: {ee}\n")
|
|
69
|
+
|
|
70
|
+
scitex.session.close(CONFIG, verbose=False, notify=False)
|
|
71
|
+
|
|
72
|
+
# EOF
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Timestamp: "2025-10-29 07:24:00 (ywatanabe)"
|
|
4
|
+
# File: /home/ywatanabe/proj/scitex-code/src/scitex/sh/test_sh_simple.py
|
|
5
|
+
# ----------------------------------------
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
|
|
10
|
+
__FILE__ = (
|
|
11
|
+
"./src/scitex/sh/test_sh_simple.py"
|
|
12
|
+
)
|
|
13
|
+
__DIR__ = os.path.dirname(__FILE__)
|
|
14
|
+
# ----------------------------------------
|
|
15
|
+
|
|
16
|
+
__FILE__ = __file__
|
|
17
|
+
|
|
18
|
+
import sys
|
|
19
|
+
|
|
20
|
+
sys.path.insert(0, "/home/ywatanabe/proj/scitex_repo/src")
|
|
21
|
+
|
|
22
|
+
from scitex.sh import quote, sh, sh_run
|
|
23
|
+
|
|
24
|
+
# Test 1: Basic list command
|
|
25
|
+
print("Test 1: Basic list command")
|
|
26
|
+
result = sh(["echo", "Hello World"], verbose=True)
|
|
27
|
+
print(f"Result: {result}\n")
|
|
28
|
+
|
|
29
|
+
# Test 2: String command should be rejected
|
|
30
|
+
print("Test 2: String command rejection")
|
|
31
|
+
try:
|
|
32
|
+
result = sh_run("echo test")
|
|
33
|
+
print("ERROR: Should have raised TypeError")
|
|
34
|
+
except TypeError as ee:
|
|
35
|
+
print(f"Correctly rejected: {ee}\n")
|
|
36
|
+
|
|
37
|
+
# Test 3: Error handling
|
|
38
|
+
print("Test 3: Error handling")
|
|
39
|
+
result = sh_run(["cat", "/nonexistent/file"], verbose=False)
|
|
40
|
+
print(f"Success: {result['success']}")
|
|
41
|
+
print(f"Exit code: {result['exit_code']}")
|
|
42
|
+
print(f"Stderr: {result['stderr'][:50]}\n")
|
|
43
|
+
|
|
44
|
+
# Test 4: Security - quote function
|
|
45
|
+
print("Test 4: Security - quote function")
|
|
46
|
+
dangerous_input = "file; rm -rf /"
|
|
47
|
+
safe_quoted = quote(dangerous_input)
|
|
48
|
+
print(f"Original: {dangerous_input}")
|
|
49
|
+
print(f"Quoted: {safe_quoted}\n")
|
|
50
|
+
|
|
51
|
+
# Test 5: Security - null byte rejection
|
|
52
|
+
print("Test 5: Security - null byte rejection")
|
|
53
|
+
try:
|
|
54
|
+
sh(["echo", "test\0malicious"])
|
|
55
|
+
print("ERROR: Should have raised ValueError")
|
|
56
|
+
except ValueError as ee:
|
|
57
|
+
print(f"Correctly rejected: {ee}\n")
|
|
58
|
+
|
|
59
|
+
print("All tests passed!")
|
|
60
|
+
|
|
61
|
+
# EOF
|
scitex/stats/__init__.py
CHANGED
|
@@ -13,7 +13,6 @@ Organized submodules:
|
|
|
13
13
|
- tests: Statistical tests (correlation, etc.)
|
|
14
14
|
- descriptive: Descriptive statistics
|
|
15
15
|
- utils: Formatters and normalizers
|
|
16
|
-
- _schema: Core StatResult schema for standardized test results
|
|
17
16
|
|
|
18
17
|
Quick Start (Auto Selection):
|
|
19
18
|
----------------------------
|
|
@@ -32,44 +31,168 @@ Quick Start (Auto Selection):
|
|
|
32
31
|
"""
|
|
33
32
|
|
|
34
33
|
# Import organized submodules
|
|
35
|
-
from . import auto
|
|
36
|
-
from . import correct
|
|
37
|
-
from . import effect_sizes
|
|
38
|
-
from . import power
|
|
39
|
-
from . import utils
|
|
40
|
-
from . import posthoc
|
|
41
|
-
from . import descriptive
|
|
42
|
-
from . import tests
|
|
43
|
-
from . import _schema
|
|
44
|
-
|
|
45
|
-
# Export commonly used functions and classes for convenience
|
|
34
|
+
from . import auto, correct, descriptive, effect_sizes, posthoc, power, tests, utils
|
|
46
35
|
from .descriptive import describe
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
36
|
+
|
|
37
|
+
# Check if torch is available for GPU acceleration
|
|
38
|
+
try:
|
|
39
|
+
import torch
|
|
40
|
+
|
|
41
|
+
TORCH_AVAILABLE = True
|
|
42
|
+
except ImportError:
|
|
43
|
+
TORCH_AVAILABLE = False
|
|
54
44
|
|
|
55
45
|
# Export key auto module classes at top level for convenience
|
|
56
46
|
from .auto import (
|
|
47
|
+
TEST_RULES,
|
|
57
48
|
StatContext,
|
|
49
|
+
StatStyle,
|
|
58
50
|
TestRule,
|
|
59
|
-
TEST_RULES,
|
|
60
51
|
check_applicable,
|
|
61
|
-
|
|
52
|
+
format_test_line,
|
|
62
53
|
get_menu_items,
|
|
63
|
-
StatStyle,
|
|
64
54
|
get_stat_style,
|
|
65
|
-
format_test_line,
|
|
66
55
|
p_to_stars,
|
|
56
|
+
recommend_tests,
|
|
67
57
|
)
|
|
68
58
|
|
|
69
59
|
# =============================================================================
|
|
70
|
-
# .
|
|
60
|
+
# Stats Schema - Use scitex.fts.Stats as single source of truth
|
|
71
61
|
# =============================================================================
|
|
72
62
|
|
|
63
|
+
# For backward compatibility, re-export from fts
|
|
64
|
+
try:
|
|
65
|
+
from scitex.fts import Stats
|
|
66
|
+
|
|
67
|
+
FTS_AVAILABLE = True
|
|
68
|
+
except ImportError:
|
|
69
|
+
Stats = None
|
|
70
|
+
FTS_AVAILABLE = False
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
def test_result_to_stats(result: dict) -> "Stats":
|
|
74
|
+
"""Convert test result dict to FTS Stats schema.
|
|
75
|
+
|
|
76
|
+
Parameters
|
|
77
|
+
----------
|
|
78
|
+
result : dict
|
|
79
|
+
Test result dictionary. Supports both formats:
|
|
80
|
+
|
|
81
|
+
Legacy flat format (from examples):
|
|
82
|
+
- name: "Control vs Treatment"
|
|
83
|
+
- method: "t-test" # string
|
|
84
|
+
- p_value: 0.003
|
|
85
|
+
- effect_size: 1.21
|
|
86
|
+
- ci95: [0.5, 1.8]
|
|
87
|
+
|
|
88
|
+
New nested format (from test functions):
|
|
89
|
+
- method: {"name": "t-test", "variant": "independent"}
|
|
90
|
+
- results: {"statistic": 2.5, "statistic_name": "t", "p_value": 0.01}
|
|
91
|
+
|
|
92
|
+
Returns
|
|
93
|
+
-------
|
|
94
|
+
Stats
|
|
95
|
+
FTS Stats object suitable for bundle storage
|
|
96
|
+
|
|
97
|
+
Example
|
|
98
|
+
-------
|
|
99
|
+
>>> result = stats.t_test(x, y)
|
|
100
|
+
>>> fts_stats = stats.test_result_to_stats(result)
|
|
101
|
+
>>> bundle.stats = fts_stats
|
|
102
|
+
"""
|
|
103
|
+
if not FTS_AVAILABLE:
|
|
104
|
+
raise ImportError("scitex.fts is required for Stats conversion")
|
|
105
|
+
|
|
106
|
+
import uuid
|
|
107
|
+
|
|
108
|
+
from scitex.fts._stats._dataclasses._Stats import (
|
|
109
|
+
Analysis,
|
|
110
|
+
EffectSize,
|
|
111
|
+
StatMethod,
|
|
112
|
+
)
|
|
113
|
+
from scitex.fts._stats._dataclasses._Stats import (
|
|
114
|
+
StatResult as FTSStatResult,
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
# Handle legacy flat format vs new nested format
|
|
118
|
+
method_data = result.get("method", {})
|
|
119
|
+
if isinstance(method_data, str):
|
|
120
|
+
# Legacy format: method is a string
|
|
121
|
+
method = StatMethod(
|
|
122
|
+
name=method_data,
|
|
123
|
+
variant=None,
|
|
124
|
+
parameters={},
|
|
125
|
+
)
|
|
126
|
+
# Legacy format has flat p_value, effect_size
|
|
127
|
+
effect_size = None
|
|
128
|
+
es_val = result.get("effect_size")
|
|
129
|
+
if es_val is not None:
|
|
130
|
+
ci = result.get("ci95", [])
|
|
131
|
+
effect_size = EffectSize(
|
|
132
|
+
name="d",
|
|
133
|
+
value=float(es_val),
|
|
134
|
+
ci_lower=ci[0] if len(ci) > 0 else None,
|
|
135
|
+
ci_upper=ci[1] if len(ci) > 1 else None,
|
|
136
|
+
)
|
|
137
|
+
stat_result = FTSStatResult(
|
|
138
|
+
statistic=result.get("statistic", 0.0),
|
|
139
|
+
statistic_name=result.get("statistic_name", ""),
|
|
140
|
+
p_value=result.get("p_value", 1.0),
|
|
141
|
+
df=result.get("df"),
|
|
142
|
+
effect_size=effect_size,
|
|
143
|
+
significant=result.get("p_value", 1.0) < 0.05,
|
|
144
|
+
alpha=0.05,
|
|
145
|
+
)
|
|
146
|
+
analysis_name = result.get("name", "comparison")
|
|
147
|
+
else:
|
|
148
|
+
# New nested format
|
|
149
|
+
method = StatMethod(
|
|
150
|
+
name=method_data.get("name", "unknown"),
|
|
151
|
+
variant=method_data.get("variant"),
|
|
152
|
+
parameters=method_data.get("parameters", {}),
|
|
153
|
+
)
|
|
154
|
+
|
|
155
|
+
# Build result
|
|
156
|
+
results_data = result.get("results", {})
|
|
157
|
+
effect_size = None
|
|
158
|
+
if "effect_size" in results_data:
|
|
159
|
+
es = results_data["effect_size"]
|
|
160
|
+
effect_size = EffectSize(
|
|
161
|
+
name=es.get("name", ""),
|
|
162
|
+
value=es.get("value", 0.0),
|
|
163
|
+
ci_lower=es.get("ci_lower"),
|
|
164
|
+
ci_upper=es.get("ci_upper"),
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
stat_result = FTSStatResult(
|
|
168
|
+
statistic=results_data.get("statistic", 0.0),
|
|
169
|
+
statistic_name=results_data.get("statistic_name", ""),
|
|
170
|
+
p_value=results_data.get("p_value", 1.0),
|
|
171
|
+
df=results_data.get("df"),
|
|
172
|
+
effect_size=effect_size,
|
|
173
|
+
significant=results_data.get("significant"),
|
|
174
|
+
alpha=results_data.get("alpha", 0.05),
|
|
175
|
+
)
|
|
176
|
+
analysis_name = result.get("name", "analysis")
|
|
177
|
+
|
|
178
|
+
# Build analysis (name stored in inputs for reference)
|
|
179
|
+
inputs = result.get("inputs", {})
|
|
180
|
+
inputs["comparison_name"] = analysis_name
|
|
181
|
+
analysis = Analysis(
|
|
182
|
+
result_id=str(uuid.uuid4()),
|
|
183
|
+
method=method,
|
|
184
|
+
results=stat_result,
|
|
185
|
+
inputs=inputs,
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
return Stats(analyses=[analysis])
|
|
189
|
+
|
|
190
|
+
|
|
191
|
+
# =============================================================================
|
|
192
|
+
# .statsz Bundle Support - Using FTS
|
|
193
|
+
# =============================================================================
|
|
194
|
+
|
|
195
|
+
|
|
73
196
|
def save_statsz(
|
|
74
197
|
comparisons,
|
|
75
198
|
path,
|
|
@@ -77,22 +200,16 @@ def save_statsz(
|
|
|
77
200
|
as_zip=False,
|
|
78
201
|
):
|
|
79
202
|
"""
|
|
80
|
-
Save statistical results as
|
|
203
|
+
Save statistical results as an FTS bundle.
|
|
81
204
|
|
|
82
205
|
Parameters
|
|
83
206
|
----------
|
|
84
|
-
comparisons : list of dict
|
|
85
|
-
List of comparison results.
|
|
86
|
-
- name: Comparison name (e.g., "Control vs Treatment")
|
|
87
|
-
- method: Test method (e.g., "t-test")
|
|
88
|
-
- p_value: P-value
|
|
89
|
-
- effect_size: Effect size (optional)
|
|
90
|
-
- ci95: 95% confidence interval (optional)
|
|
91
|
-
- formatted: Star notation (optional)
|
|
207
|
+
comparisons : list of dict
|
|
208
|
+
List of comparison results.
|
|
92
209
|
path : str or Path
|
|
93
|
-
Output path (e.g., "
|
|
210
|
+
Output path (e.g., "results.zip").
|
|
94
211
|
metadata : dict, optional
|
|
95
|
-
Additional metadata
|
|
212
|
+
Additional metadata.
|
|
96
213
|
as_zip : bool, optional
|
|
97
214
|
If True, save as ZIP archive (default: False).
|
|
98
215
|
|
|
@@ -100,83 +217,89 @@ def save_statsz(
|
|
|
100
217
|
-------
|
|
101
218
|
Path
|
|
102
219
|
Path to saved bundle.
|
|
103
|
-
|
|
104
|
-
Examples
|
|
105
|
-
--------
|
|
106
|
-
>>> import scitex.stats as sstats
|
|
107
|
-
>>> comparisons = [
|
|
108
|
-
... {
|
|
109
|
-
... "name": "Control vs Treatment",
|
|
110
|
-
... "method": "t-test",
|
|
111
|
-
... "p_value": 0.003,
|
|
112
|
-
... "effect_size": 1.21,
|
|
113
|
-
... "ci95": [0.5, 1.8],
|
|
114
|
-
... "formatted": "**"
|
|
115
|
-
... }
|
|
116
|
-
... ]
|
|
117
|
-
>>> sstats.save_statsz(comparisons, "results.statsz.d")
|
|
118
220
|
"""
|
|
119
221
|
from pathlib import Path
|
|
120
|
-
|
|
222
|
+
|
|
223
|
+
from scitex.fts import FTS
|
|
121
224
|
|
|
122
225
|
p = Path(path)
|
|
226
|
+
if as_zip and not p.suffix == ".zip":
|
|
227
|
+
p = p.with_suffix(".zip")
|
|
123
228
|
|
|
124
|
-
#
|
|
125
|
-
|
|
126
|
-
for comp in comparisons:
|
|
127
|
-
if hasattr(comp, 'to_dict'):
|
|
128
|
-
comp_dicts.append(comp.to_dict())
|
|
129
|
-
elif hasattr(comp, '__dict__'):
|
|
130
|
-
comp_dicts.append(vars(comp))
|
|
131
|
-
else:
|
|
132
|
-
comp_dicts.append(comp)
|
|
229
|
+
# Create FTS bundle
|
|
230
|
+
bundle = FTS(p, create=True, node_type="stats")
|
|
133
231
|
|
|
134
|
-
#
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
232
|
+
# Convert comparisons to Stats
|
|
233
|
+
if comparisons:
|
|
234
|
+
if isinstance(comparisons[0], dict):
|
|
235
|
+
# Convert list of dicts to Stats
|
|
236
|
+
stats = Stats(analyses=[])
|
|
237
|
+
for comp in comparisons:
|
|
238
|
+
analysis_stats = test_result_to_stats(comp)
|
|
239
|
+
stats.analyses.extend(analysis_stats.analyses)
|
|
240
|
+
bundle.stats = stats
|
|
241
|
+
else:
|
|
242
|
+
# Already Stats objects
|
|
243
|
+
bundle.stats = comparisons
|
|
142
244
|
|
|
143
|
-
|
|
245
|
+
bundle.save()
|
|
246
|
+
return p
|
|
144
247
|
|
|
145
248
|
|
|
146
249
|
def load_statsz(path):
|
|
147
250
|
"""
|
|
148
|
-
Load a
|
|
251
|
+
Load a stats bundle using FTS.
|
|
149
252
|
|
|
150
253
|
Parameters
|
|
151
254
|
----------
|
|
152
255
|
path : str or Path
|
|
153
|
-
Path to
|
|
256
|
+
Path to bundle.
|
|
154
257
|
|
|
155
258
|
Returns
|
|
156
259
|
-------
|
|
157
260
|
dict
|
|
158
|
-
Stats data with
|
|
159
|
-
|
|
160
|
-
-
|
|
161
|
-
|
|
162
|
-
Examples
|
|
163
|
-
--------
|
|
164
|
-
>>> stats = scitex.stats.load_statsz("results.statsz.d")
|
|
165
|
-
>>> for comp in stats['comparisons']:
|
|
166
|
-
... print(f"{comp['name']}: p={comp['p_value']}")
|
|
261
|
+
Stats data with 'comparisons' and 'metadata'.
|
|
262
|
+
Each comparison is a flat dict with:
|
|
263
|
+
- name, method, p_value, effect_size, ci95, formatted
|
|
167
264
|
"""
|
|
168
|
-
from scitex.
|
|
265
|
+
from scitex.fts import FTS
|
|
266
|
+
|
|
267
|
+
bundle = FTS(path)
|
|
169
268
|
|
|
170
|
-
|
|
269
|
+
comparisons = []
|
|
270
|
+
if bundle.stats and bundle.stats.analyses:
|
|
271
|
+
for analysis in bundle.stats.analyses:
|
|
272
|
+
# Convert back to flat format for compatibility
|
|
273
|
+
ad = analysis.to_dict()
|
|
274
|
+
p_val = ad.get("results", {}).get("p_value", 1.0)
|
|
275
|
+
es_data = ad.get("results", {}).get("effect_size", {})
|
|
276
|
+
es_val = es_data.get("value", 0.0) if es_data else 0.0
|
|
277
|
+
ci = [es_data.get("ci_lower"), es_data.get("ci_upper")] if es_data else []
|
|
278
|
+
ci = [v for v in ci if v is not None]
|
|
171
279
|
|
|
172
|
-
|
|
173
|
-
|
|
280
|
+
# Format p-value as stars
|
|
281
|
+
if p_val < 0.001:
|
|
282
|
+
formatted = "***"
|
|
283
|
+
elif p_val < 0.01:
|
|
284
|
+
formatted = "**"
|
|
285
|
+
elif p_val < 0.05:
|
|
286
|
+
formatted = "*"
|
|
287
|
+
else:
|
|
288
|
+
formatted = "ns"
|
|
174
289
|
|
|
175
|
-
|
|
290
|
+
flat = {
|
|
291
|
+
"name": ad.get("inputs", {}).get("comparison_name", "comparison"),
|
|
292
|
+
"method": ad.get("method", {}).get("name", "unknown"),
|
|
293
|
+
"p_value": p_val,
|
|
294
|
+
"effect_size": es_val,
|
|
295
|
+
"ci95": ci,
|
|
296
|
+
"formatted": formatted,
|
|
297
|
+
}
|
|
298
|
+
comparisons.append(flat)
|
|
176
299
|
|
|
177
300
|
return {
|
|
178
|
-
|
|
179
|
-
|
|
301
|
+
"comparisons": comparisons,
|
|
302
|
+
"metadata": bundle.node.to_dict() if bundle.node else {},
|
|
180
303
|
}
|
|
181
304
|
|
|
182
305
|
|
|
@@ -184,20 +307,19 @@ __all__ = [
|
|
|
184
307
|
# Main submodules
|
|
185
308
|
"auto",
|
|
186
309
|
"correct",
|
|
310
|
+
"descriptive",
|
|
187
311
|
"effect_sizes",
|
|
188
312
|
"power",
|
|
189
313
|
"utils",
|
|
190
314
|
"posthoc",
|
|
191
|
-
"descriptive",
|
|
192
315
|
"tests",
|
|
193
|
-
|
|
194
|
-
# Schema exports
|
|
316
|
+
# Descriptive convenience export
|
|
195
317
|
"describe",
|
|
196
|
-
|
|
197
|
-
"
|
|
198
|
-
|
|
199
|
-
"
|
|
200
|
-
"
|
|
318
|
+
# Torch availability flag (for GPU acceleration)
|
|
319
|
+
"TORCH_AVAILABLE",
|
|
320
|
+
# Stats schema (from FTS)
|
|
321
|
+
"Stats",
|
|
322
|
+
"FTS_AVAILABLE",
|
|
201
323
|
# Auto module convenience exports
|
|
202
324
|
"StatContext",
|
|
203
325
|
"TestRule",
|
|
@@ -209,9 +331,11 @@ __all__ = [
|
|
|
209
331
|
"get_stat_style",
|
|
210
332
|
"format_test_line",
|
|
211
333
|
"p_to_stars",
|
|
212
|
-
#
|
|
334
|
+
# Conversion utilities
|
|
335
|
+
"test_result_to_stats",
|
|
336
|
+
# Bundle functions
|
|
213
337
|
"save_statsz",
|
|
214
338
|
"load_statsz",
|
|
215
339
|
]
|
|
216
340
|
|
|
217
|
-
__version__ = "2.
|
|
341
|
+
__version__ = "2.2.0"
|