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/errors.py
CHANGED
|
@@ -1,531 +1,102 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
|
-
# Timestamp: "2025-
|
|
4
|
-
# File: /home/ywatanabe/proj/
|
|
5
|
-
# ----------------------------------------
|
|
6
|
-
from __future__ import annotations
|
|
7
|
-
import os
|
|
8
|
-
|
|
9
|
-
__FILE__ = __file__
|
|
10
|
-
__DIR__ = os.path.dirname(__FILE__)
|
|
11
|
-
# ----------------------------------------
|
|
12
|
-
|
|
13
|
-
"""
|
|
14
|
-
1. Functionality:
|
|
15
|
-
- Provides comprehensive error and warning classes for the SciTeX framework
|
|
16
|
-
- Implements module-specific exceptions with clear error messages
|
|
17
|
-
- Supports context-aware error reporting for better debugging
|
|
18
|
-
2. Input:
|
|
19
|
-
- Error messages, context information, and optional suggestions
|
|
20
|
-
3. Output:
|
|
21
|
-
- Raised exceptions with detailed information for debugging
|
|
22
|
-
4. Prerequisites:
|
|
23
|
-
- Python 3.x
|
|
24
|
-
"""
|
|
25
|
-
|
|
26
|
-
"""Imports"""
|
|
27
|
-
import warnings as _warnings
|
|
28
|
-
from typing import Optional, Union
|
|
29
|
-
|
|
30
|
-
"""Base SciTeX Errors"""
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
class SciTeXError(Exception):
|
|
34
|
-
"""Base Exception class for all SciTeX errors."""
|
|
35
|
-
|
|
36
|
-
def __init__(
|
|
37
|
-
self,
|
|
38
|
-
message: str,
|
|
39
|
-
context: Optional[dict] = None,
|
|
40
|
-
suggestion: Optional[str] = None,
|
|
41
|
-
):
|
|
42
|
-
"""Initialize SciTeX error with detailed information.
|
|
43
|
-
|
|
44
|
-
Parameters
|
|
45
|
-
----------
|
|
46
|
-
message : str
|
|
47
|
-
The error message
|
|
48
|
-
context : dict, optional
|
|
49
|
-
Additional context information (e.g., file paths, variable values)
|
|
50
|
-
suggestion : str, optional
|
|
51
|
-
Suggested fix or action
|
|
52
|
-
"""
|
|
53
|
-
self.message = message
|
|
54
|
-
self.context = context or {}
|
|
55
|
-
self.suggestion = suggestion
|
|
56
|
-
|
|
57
|
-
# Build the full error message
|
|
58
|
-
error_parts = [f"SciTeX Error: {message}"]
|
|
59
|
-
|
|
60
|
-
if context:
|
|
61
|
-
error_parts.append("\nContext:")
|
|
62
|
-
for key, value in context.items():
|
|
63
|
-
error_parts.append(f" {key}: {value}")
|
|
64
|
-
|
|
65
|
-
if suggestion:
|
|
66
|
-
error_parts.append(f"\nSuggestion: {suggestion}")
|
|
67
|
-
|
|
68
|
-
super().__init__("\n".join(error_parts))
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
class SciTeXWarning(UserWarning):
|
|
72
|
-
"""Base warning class for all SciTeX warnings."""
|
|
73
|
-
|
|
74
|
-
pass
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
"""Configuration Errors"""
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
class ConfigurationError(SciTeXError):
|
|
81
|
-
"""Raised when there are issues with SciTeX configuration."""
|
|
82
|
-
|
|
83
|
-
pass
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
class ConfigFileNotFoundError(ConfigurationError):
|
|
87
|
-
"""Raised when a required configuration file is not found."""
|
|
88
|
-
|
|
89
|
-
def __init__(self, filepath: str):
|
|
90
|
-
super().__init__(
|
|
91
|
-
f"Configuration file not found: {filepath}",
|
|
92
|
-
context={"filepath": filepath},
|
|
93
|
-
suggestion="Ensure the configuration file exists in ./config/ directory",
|
|
94
|
-
)
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
class ConfigKeyError(ConfigurationError):
|
|
98
|
-
"""Raised when a required configuration key is missing."""
|
|
99
|
-
|
|
100
|
-
def __init__(self, key: str, available_keys: Optional[list] = None):
|
|
101
|
-
context = {"missing_key": key}
|
|
102
|
-
if available_keys:
|
|
103
|
-
context["available_keys"] = available_keys
|
|
104
|
-
|
|
105
|
-
super().__init__(
|
|
106
|
-
f"Configuration key '{key}' not found",
|
|
107
|
-
context=context,
|
|
108
|
-
suggestion=f"Add '{key}' to your configuration file or check for typos",
|
|
109
|
-
)
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
"""IO Errors"""
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
class IOError(SciTeXError):
|
|
116
|
-
"""Base class for input/output related errors."""
|
|
117
|
-
|
|
118
|
-
pass
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
class FileFormatError(IOError):
|
|
122
|
-
"""Raised when file format is not supported or incorrect."""
|
|
123
|
-
|
|
124
|
-
def __init__(
|
|
125
|
-
self,
|
|
126
|
-
filepath: str,
|
|
127
|
-
expected_format: Optional[str] = None,
|
|
128
|
-
actual_format: Optional[str] = None,
|
|
129
|
-
):
|
|
130
|
-
context = {"filepath": filepath}
|
|
131
|
-
if expected_format:
|
|
132
|
-
context["expected_format"] = expected_format
|
|
133
|
-
if actual_format:
|
|
134
|
-
context["actual_format"] = actual_format
|
|
135
|
-
|
|
136
|
-
message = f"File format error for: {filepath}"
|
|
137
|
-
if expected_format and actual_format:
|
|
138
|
-
message += f" (expected: {expected_format}, got: {actual_format})"
|
|
139
|
-
|
|
140
|
-
super().__init__(
|
|
141
|
-
message,
|
|
142
|
-
context=context,
|
|
143
|
-
suggestion="Check the file extension and content format",
|
|
144
|
-
)
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
class SaveError(IOError):
|
|
148
|
-
"""Raised when saving data fails."""
|
|
149
|
-
|
|
150
|
-
def __init__(self, filepath: str, reason: str):
|
|
151
|
-
super().__init__(
|
|
152
|
-
f"Failed to save to {filepath}: {reason}",
|
|
153
|
-
context={"filepath": filepath, "reason": reason},
|
|
154
|
-
suggestion="Check file permissions and disk space",
|
|
155
|
-
)
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
class LoadError(IOError):
|
|
159
|
-
"""Raised when loading data fails."""
|
|
160
|
-
|
|
161
|
-
def __init__(self, filepath: str, reason: str):
|
|
162
|
-
super().__init__(
|
|
163
|
-
f"Failed to load from {filepath}: {reason}",
|
|
164
|
-
context={"filepath": filepath, "reason": reason},
|
|
165
|
-
suggestion="Verify the file exists and is not corrupted",
|
|
166
|
-
)
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
"""Scholar Module Errors"""
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
class ScholarError(SciTeXError):
|
|
173
|
-
"""Base class for scholar module errors."""
|
|
174
|
-
|
|
175
|
-
pass
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
class SearchError(ScholarError):
|
|
179
|
-
"""Raised when paper search fails."""
|
|
180
|
-
|
|
181
|
-
def __init__(self, query: str, source: str, reason: str):
|
|
182
|
-
super().__init__(
|
|
183
|
-
f"Search failed for query '{query}' on {source}",
|
|
184
|
-
context={"query": query, "source": source, "reason": reason},
|
|
185
|
-
suggestion="Check your internet connection and API keys",
|
|
186
|
-
)
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
class EnrichmentError(ScholarError):
|
|
190
|
-
"""Raised when paper enrichment fails."""
|
|
191
|
-
|
|
192
|
-
def __init__(self, paper_title: str, reason: str):
|
|
193
|
-
super().__init__(
|
|
194
|
-
f"Failed to enrich paper: {paper_title}",
|
|
195
|
-
context={"paper_title": paper_title, "reason": reason},
|
|
196
|
-
suggestion="Verify journal information is available",
|
|
197
|
-
)
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
class PDFDownloadError(ScholarError):
|
|
201
|
-
"""Raised when PDF download fails."""
|
|
202
|
-
|
|
203
|
-
def __init__(self, url: str, reason: str):
|
|
204
|
-
super().__init__(
|
|
205
|
-
f"Failed to download PDF from {url}",
|
|
206
|
-
context={"url": url, "reason": reason},
|
|
207
|
-
suggestion="Check if the paper is open access",
|
|
208
|
-
)
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
class DOIResolutionError(ScholarError):
|
|
212
|
-
"""Raised when DOI resolution fails."""
|
|
213
|
-
|
|
214
|
-
def __init__(self, doi: str, reason: str):
|
|
215
|
-
super().__init__(
|
|
216
|
-
f"Failed to resolve DOI: {doi}",
|
|
217
|
-
context={"doi": doi, "reason": reason},
|
|
218
|
-
suggestion="Verify the DOI is correct and try again",
|
|
219
|
-
)
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
class PDFExtractionError(ScholarError):
|
|
223
|
-
"""Raised when PDF text extraction fails."""
|
|
224
|
-
|
|
225
|
-
def __init__(self, filepath: str, reason: str):
|
|
226
|
-
super().__init__(
|
|
227
|
-
f"Failed to extract text from PDF: {filepath}",
|
|
228
|
-
context={"filepath": filepath, "reason": reason},
|
|
229
|
-
suggestion="Ensure the PDF is not corrupted or encrypted",
|
|
230
|
-
)
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
class BibTeXEnrichmentError(ScholarError):
|
|
234
|
-
"""Raised when BibTeX enrichment fails."""
|
|
235
|
-
|
|
236
|
-
def __init__(self, bibtex_file: str, reason: str):
|
|
237
|
-
super().__init__(
|
|
238
|
-
f"Failed to enrich BibTeX file: {bibtex_file}",
|
|
239
|
-
context={"bibtex_file": bibtex_file, "reason": reason},
|
|
240
|
-
suggestion="Check the BibTeX format and ensure all entries are valid",
|
|
241
|
-
)
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
class TranslatorError(ScholarError):
|
|
245
|
-
"""Raised when Zotero translator operations fail."""
|
|
246
|
-
|
|
247
|
-
def __init__(self, translator_name: str, reason: str):
|
|
248
|
-
super().__init__(
|
|
249
|
-
f"Translator error in {translator_name}: {reason}",
|
|
250
|
-
context={"translator": translator_name, "reason": reason},
|
|
251
|
-
suggestion="Check translator compatibility and JavaScript environment",
|
|
252
|
-
)
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
class AuthenticationError(ScholarError):
|
|
256
|
-
"""Raised when authentication fails."""
|
|
257
|
-
|
|
258
|
-
def __init__(self, provider: str, reason: str = ""):
|
|
259
|
-
super().__init__(
|
|
260
|
-
f"Authentication failed for {provider}: {reason}",
|
|
261
|
-
context={"provider": provider, "reason": reason},
|
|
262
|
-
suggestion="Check your credentials and authentication settings",
|
|
263
|
-
)
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
"""Plotting Errors"""
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
class PlottingError(SciTeXError):
|
|
270
|
-
"""Base class for plotting-related errors."""
|
|
271
|
-
|
|
272
|
-
pass
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
class FigureNotFoundError(PlottingError):
|
|
276
|
-
"""Raised when attempting to operate on a non-existent figure."""
|
|
3
|
+
# Timestamp: "2025-12-21"
|
|
4
|
+
# File: /home/ywatanabe/proj/scitex-code/src/scitex/errors.py
|
|
277
5
|
|
|
278
|
-
|
|
279
|
-
super().__init__(
|
|
280
|
-
f"Figure {fig_id} not found",
|
|
281
|
-
context={"figure_id": fig_id},
|
|
282
|
-
suggestion="Ensure the figure was created before attempting to save/modify it",
|
|
283
|
-
)
|
|
6
|
+
"""Backwards-compatible re-export of errors from scitex.logging.
|
|
284
7
|
|
|
8
|
+
DEPRECATED: Import from scitex.logging instead.
|
|
285
9
|
|
|
286
|
-
|
|
287
|
-
|
|
10
|
+
# Old (deprecated)
|
|
11
|
+
from scitex.errors import SciTeXError, SaveError
|
|
288
12
|
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
context={"axis_info": axis_info} if axis_info else None,
|
|
293
|
-
suggestion="Check axis indices and subplot configuration",
|
|
294
|
-
)
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
"""Data Processing Errors"""
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
class DataError(SciTeXError):
|
|
301
|
-
"""Base class for data processing errors."""
|
|
302
|
-
|
|
303
|
-
pass
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
class ShapeError(DataError):
|
|
307
|
-
"""Raised when data shapes are incompatible."""
|
|
308
|
-
|
|
309
|
-
def __init__(self, expected_shape: tuple, actual_shape: tuple, operation: str):
|
|
310
|
-
super().__init__(
|
|
311
|
-
f"Shape mismatch in {operation}",
|
|
312
|
-
context={
|
|
313
|
-
"expected_shape": expected_shape,
|
|
314
|
-
"actual_shape": actual_shape,
|
|
315
|
-
"operation": operation,
|
|
316
|
-
},
|
|
317
|
-
suggestion="Reshape or transpose your data to match expected dimensions",
|
|
318
|
-
)
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
class DTypeError(DataError):
|
|
322
|
-
"""Raised when data types are incompatible."""
|
|
323
|
-
|
|
324
|
-
def __init__(self, expected_dtype: str, actual_dtype: str, operation: str):
|
|
325
|
-
super().__init__(
|
|
326
|
-
f"Data type mismatch in {operation}",
|
|
327
|
-
context={
|
|
328
|
-
"expected_dtype": expected_dtype,
|
|
329
|
-
"actual_dtype": actual_dtype,
|
|
330
|
-
"operation": operation,
|
|
331
|
-
},
|
|
332
|
-
suggestion=f"Convert data to {expected_dtype} using appropriate casting",
|
|
333
|
-
)
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
"""Path Errors"""
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
class PathError(SciTeXError):
|
|
340
|
-
"""Base class for path-related errors."""
|
|
341
|
-
|
|
342
|
-
pass
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
class InvalidPathError(PathError):
|
|
346
|
-
"""Raised when a path is invalid or doesn't follow SciTeX conventions."""
|
|
347
|
-
|
|
348
|
-
def __init__(self, path: str, reason: str):
|
|
349
|
-
super().__init__(
|
|
350
|
-
f"Invalid path: {path}",
|
|
351
|
-
context={"path": path, "reason": reason},
|
|
352
|
-
suggestion="Use relative paths starting with './' or '../'",
|
|
353
|
-
)
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
class PathNotFoundError(PathError):
|
|
357
|
-
"""Raised when a required path doesn't exist."""
|
|
358
|
-
|
|
359
|
-
def __init__(self, path: str):
|
|
360
|
-
super().__init__(
|
|
361
|
-
f"Path not found: {path}",
|
|
362
|
-
context={"path": path},
|
|
363
|
-
suggestion="Check if the path exists and is accessible",
|
|
364
|
-
)
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
"""Template Errors"""
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
class TemplateError(SciTeXError):
|
|
371
|
-
"""Base class for template-related errors."""
|
|
372
|
-
|
|
373
|
-
pass
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
class TemplateViolationError(TemplateError):
|
|
377
|
-
"""Raised when SciTeX template is not followed."""
|
|
378
|
-
|
|
379
|
-
def __init__(self, filepath: str, violation: str):
|
|
380
|
-
super().__init__(
|
|
381
|
-
f"Template violation in {filepath}: {violation}",
|
|
382
|
-
context={"filepath": filepath, "violation": violation},
|
|
383
|
-
suggestion="Follow the SciTeX template structure as defined in IMPORTANT-SCITEX-02-file-template.md",
|
|
384
|
-
)
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
"""Neural Network Errors"""
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
class NNError(SciTeXError):
|
|
391
|
-
"""Base class for neural network module errors."""
|
|
392
|
-
|
|
393
|
-
pass
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
class ModelError(NNError):
|
|
397
|
-
"""Raised when there are issues with neural network models."""
|
|
398
|
-
|
|
399
|
-
def __init__(self, model_name: str, reason: str):
|
|
400
|
-
super().__init__(
|
|
401
|
-
f"Model error in {model_name}: {reason}",
|
|
402
|
-
context={"model_name": model_name, "reason": reason},
|
|
403
|
-
)
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
"""Statistics Errors"""
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
class StatsError(SciTeXError):
|
|
410
|
-
"""Base class for statistics module errors."""
|
|
411
|
-
|
|
412
|
-
pass
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
class TestError(StatsError):
|
|
416
|
-
"""Raised when statistical tests fail."""
|
|
417
|
-
|
|
418
|
-
def __init__(self, test_name: str, reason: str):
|
|
419
|
-
super().__init__(
|
|
420
|
-
f"Statistical test '{test_name}' failed: {reason}",
|
|
421
|
-
context={"test_name": test_name, "reason": reason},
|
|
422
|
-
)
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
"""Warning Functions"""
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
def warn_deprecated(
|
|
429
|
-
old_function: str, new_function: str, version: Optional[str] = None
|
|
430
|
-
):
|
|
431
|
-
"""Issue a deprecation warning."""
|
|
432
|
-
message = f"{old_function} is deprecated. Use {new_function} instead."
|
|
433
|
-
if version:
|
|
434
|
-
message += f" Will be removed in version {version}."
|
|
435
|
-
_warnings.warn(message, DeprecationWarning, stacklevel=2)
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
def warn_performance(operation: str, suggestion: str):
|
|
439
|
-
"""Issue a performance warning."""
|
|
440
|
-
message = f"Performance warning in {operation}: {suggestion}"
|
|
441
|
-
_warnings.warn(message, SciTeXWarning, stacklevel=2)
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
def warn_data_loss(operation: str, detail: str):
|
|
445
|
-
"""Issue a data loss warning."""
|
|
446
|
-
message = f"Potential data loss in {operation}: {detail}"
|
|
447
|
-
_warnings.warn(message, SciTeXWarning, stacklevel=2)
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
"""Validation Helpers"""
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
def check_path(path: str) -> None:
|
|
454
|
-
"""Validate a path according to SciTeX conventions.
|
|
455
|
-
|
|
456
|
-
Parameters
|
|
457
|
-
----------
|
|
458
|
-
path : str
|
|
459
|
-
The path to validate
|
|
460
|
-
|
|
461
|
-
Raises
|
|
462
|
-
------
|
|
463
|
-
InvalidPathError
|
|
464
|
-
If the path doesn't follow SciTeX conventions
|
|
465
|
-
"""
|
|
466
|
-
if not isinstance(path, str):
|
|
467
|
-
raise InvalidPathError(str(path), "Path must be a string")
|
|
468
|
-
|
|
469
|
-
if not (path.startswith("./") or path.startswith("../")):
|
|
470
|
-
raise InvalidPathError(
|
|
471
|
-
path, "Path must be relative and start with './' or '../'"
|
|
472
|
-
)
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
def check_file_exists(filepath: str) -> None:
|
|
476
|
-
"""Check if a file exists.
|
|
477
|
-
|
|
478
|
-
Parameters
|
|
479
|
-
----------
|
|
480
|
-
filepath : str
|
|
481
|
-
The file path to check
|
|
482
|
-
|
|
483
|
-
Raises
|
|
484
|
-
------
|
|
485
|
-
PathNotFoundError
|
|
486
|
-
If the file doesn't exist
|
|
487
|
-
"""
|
|
488
|
-
import os
|
|
489
|
-
|
|
490
|
-
if not os.path.exists(filepath):
|
|
491
|
-
raise PathNotFoundError(filepath)
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
def check_shape_compatibility(shape1: tuple, shape2: tuple, operation: str) -> None:
|
|
495
|
-
"""Check if two shapes are compatible for an operation.
|
|
496
|
-
|
|
497
|
-
Parameters
|
|
498
|
-
----------
|
|
499
|
-
shape1 : tuple
|
|
500
|
-
First shape
|
|
501
|
-
shape2 : tuple
|
|
502
|
-
Second shape
|
|
503
|
-
operation : str
|
|
504
|
-
The operation being performed
|
|
505
|
-
|
|
506
|
-
Raises
|
|
507
|
-
------
|
|
508
|
-
ShapeError
|
|
509
|
-
If shapes are incompatible
|
|
510
|
-
"""
|
|
511
|
-
if shape1 != shape2:
|
|
512
|
-
raise ShapeError(shape1, shape2, operation)
|
|
13
|
+
# New (recommended)
|
|
14
|
+
from scitex.logging import SciTeXError, SaveError
|
|
15
|
+
"""
|
|
513
16
|
|
|
17
|
+
from __future__ import annotations
|
|
18
|
+
import warnings
|
|
19
|
+
|
|
20
|
+
# Issue deprecation warning on import
|
|
21
|
+
# stacklevel=1 so warning appears from scitex.errors (matches scitex.* filter)
|
|
22
|
+
warnings.warn(
|
|
23
|
+
"scitex.errors is deprecated. Import from scitex.logging instead. "
|
|
24
|
+
"Example: from scitex.logging import SciTeXError, UnitWarning",
|
|
25
|
+
DeprecationWarning,
|
|
26
|
+
stacklevel=1,
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
# Re-export everything from scitex.logging for backwards compatibility
|
|
30
|
+
from scitex.logging import (
|
|
31
|
+
# Warnings
|
|
32
|
+
SciTeXWarning,
|
|
33
|
+
UnitWarning,
|
|
34
|
+
StyleWarning,
|
|
35
|
+
SciTeXDeprecationWarning,
|
|
36
|
+
PerformanceWarning,
|
|
37
|
+
DataLossWarning,
|
|
38
|
+
warn_deprecated,
|
|
39
|
+
warn_performance,
|
|
40
|
+
warn_data_loss,
|
|
41
|
+
# Errors
|
|
42
|
+
SciTeXError,
|
|
43
|
+
ConfigurationError,
|
|
44
|
+
ConfigFileNotFoundError,
|
|
45
|
+
ConfigKeyError,
|
|
46
|
+
IOError,
|
|
47
|
+
FileFormatError,
|
|
48
|
+
SaveError,
|
|
49
|
+
LoadError,
|
|
50
|
+
ScholarError,
|
|
51
|
+
SearchError,
|
|
52
|
+
EnrichmentError,
|
|
53
|
+
PDFDownloadError,
|
|
54
|
+
DOIResolutionError,
|
|
55
|
+
PDFExtractionError,
|
|
56
|
+
BibTeXEnrichmentError,
|
|
57
|
+
TranslatorError,
|
|
58
|
+
AuthenticationError,
|
|
59
|
+
PlottingError,
|
|
60
|
+
FigureNotFoundError,
|
|
61
|
+
AxisError,
|
|
62
|
+
DataError,
|
|
63
|
+
ShapeError,
|
|
64
|
+
DTypeError,
|
|
65
|
+
PathError,
|
|
66
|
+
InvalidPathError,
|
|
67
|
+
PathNotFoundError,
|
|
68
|
+
TemplateError,
|
|
69
|
+
TemplateViolationError,
|
|
70
|
+
NNError,
|
|
71
|
+
ModelError,
|
|
72
|
+
StatsError,
|
|
73
|
+
TestError,
|
|
74
|
+
# Validation helpers
|
|
75
|
+
check_path,
|
|
76
|
+
check_file_exists,
|
|
77
|
+
check_shape_compatibility,
|
|
78
|
+
)
|
|
514
79
|
|
|
515
80
|
__all__ = [
|
|
516
|
-
#
|
|
517
|
-
"SciTeXError",
|
|
81
|
+
# Warnings
|
|
518
82
|
"SciTeXWarning",
|
|
519
|
-
|
|
83
|
+
"UnitWarning",
|
|
84
|
+
"StyleWarning",
|
|
85
|
+
"SciTeXDeprecationWarning",
|
|
86
|
+
"PerformanceWarning",
|
|
87
|
+
"DataLossWarning",
|
|
88
|
+
"warn_deprecated",
|
|
89
|
+
"warn_performance",
|
|
90
|
+
"warn_data_loss",
|
|
91
|
+
# Errors
|
|
92
|
+
"SciTeXError",
|
|
520
93
|
"ConfigurationError",
|
|
521
94
|
"ConfigFileNotFoundError",
|
|
522
95
|
"ConfigKeyError",
|
|
523
|
-
# IO
|
|
524
96
|
"IOError",
|
|
525
97
|
"FileFormatError",
|
|
526
98
|
"SaveError",
|
|
527
99
|
"LoadError",
|
|
528
|
-
# Scholar
|
|
529
100
|
"ScholarError",
|
|
530
101
|
"SearchError",
|
|
531
102
|
"EnrichmentError",
|
|
@@ -535,31 +106,21 @@ __all__ = [
|
|
|
535
106
|
"BibTeXEnrichmentError",
|
|
536
107
|
"TranslatorError",
|
|
537
108
|
"AuthenticationError",
|
|
538
|
-
# Plotting
|
|
539
109
|
"PlottingError",
|
|
540
110
|
"FigureNotFoundError",
|
|
541
111
|
"AxisError",
|
|
542
|
-
# Data
|
|
543
112
|
"DataError",
|
|
544
113
|
"ShapeError",
|
|
545
114
|
"DTypeError",
|
|
546
|
-
# Path
|
|
547
115
|
"PathError",
|
|
548
116
|
"InvalidPathError",
|
|
549
117
|
"PathNotFoundError",
|
|
550
|
-
# Template
|
|
551
118
|
"TemplateError",
|
|
552
119
|
"TemplateViolationError",
|
|
553
|
-
# Neural Network
|
|
554
120
|
"NNError",
|
|
555
121
|
"ModelError",
|
|
556
|
-
# Statistics
|
|
557
122
|
"StatsError",
|
|
558
123
|
"TestError",
|
|
559
|
-
# Warning functions
|
|
560
|
-
"warn_deprecated",
|
|
561
|
-
"warn_performance",
|
|
562
|
-
"warn_data_loss",
|
|
563
124
|
# Validation helpers
|
|
564
125
|
"check_path",
|
|
565
126
|
"check_file_exists",
|
scitex/fig/__init__.py
CHANGED
|
@@ -191,7 +191,7 @@ def save_figz(
|
|
|
191
191
|
"""
|
|
192
192
|
from pathlib import Path
|
|
193
193
|
import shutil
|
|
194
|
-
from scitex.io.
|
|
194
|
+
from scitex.io.bundle import save, BundleType
|
|
195
195
|
|
|
196
196
|
p = Path(path)
|
|
197
197
|
spath = str(path)
|
|
@@ -217,7 +217,7 @@ def save_figz(
|
|
|
217
217
|
# Store source path for direct copying
|
|
218
218
|
bundle_data['plots'][panel_id] = str(pltz_path)
|
|
219
219
|
|
|
220
|
-
return
|
|
220
|
+
return save(bundle_data, p, bundle_type=BundleType.FIGZ, as_zip=as_zip)
|
|
221
221
|
|
|
222
222
|
|
|
223
223
|
def load_figz(path):
|
|
@@ -243,9 +243,9 @@ def load_figz(path):
|
|
|
243
243
|
>>> panel_a = figure['panels']['A']
|
|
244
244
|
>>> print(panel_a['spec'], panel_a['data'])
|
|
245
245
|
"""
|
|
246
|
-
from scitex.io.
|
|
246
|
+
from scitex.io.bundle import load
|
|
247
247
|
|
|
248
|
-
bundle =
|
|
248
|
+
bundle = load(path)
|
|
249
249
|
|
|
250
250
|
if bundle['type'] != 'figz':
|
|
251
251
|
raise ValueError(f"Not a .figz bundle: {path}")
|
|
@@ -55,7 +55,7 @@ def load_panel_data(panel_path: Union[Path, str], is_zip: bool = None) -> Option
|
|
|
55
55
|
def _load_from_zip(panel_path: Path) -> Optional[Dict[str, Any]]:
|
|
56
56
|
"""Load panel data from a .pltz zip file."""
|
|
57
57
|
from PIL import Image
|
|
58
|
-
from scitex.io.
|
|
58
|
+
from scitex.io.bundle import ZipBundle
|
|
59
59
|
|
|
60
60
|
if not panel_path.exists():
|
|
61
61
|
return None
|