scitex 2.10.3__py3-none-any.whl → 2.13.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 +1 -4
- scitex/__main__.py +24 -5
- scitex/__version__.py +1 -1
- scitex/_install_guide.py +14 -2
- scitex/_optional_deps.py +33 -0
- scitex/ai/classification/reporters/_ClassificationReporter.py +1 -1
- scitex/ai/classification/timeseries/_TimeSeriesBlockingSplit.py +2 -2
- scitex/ai/classification/timeseries/_TimeSeriesCalendarSplit.py +2 -2
- scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +2 -2
- scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit_v01-not-using-n_splits.py +2 -2
- scitex/ai/classification/timeseries/_TimeSeriesStratifiedSplit.py +2 -2
- scitex/ai/classification/timeseries/_normalize_timestamp.py +1 -1
- scitex/ai/metrics/_calc_seizure_prediction_metrics.py +1 -1
- scitex/ai/plt/_plot_feature_importance.py +1 -1
- scitex/ai/plt/_plot_learning_curve.py +1 -1
- scitex/ai/plt/_plot_optuna_study.py +1 -1
- scitex/ai/plt/_plot_pre_rec_curve.py +1 -1
- scitex/ai/plt/_plot_roc_curve.py +1 -1
- scitex/ai/plt/_stx_conf_mat.py +1 -1
- scitex/ai/training/_LearningCurveLogger.py +1 -1
- scitex/audio/mcp_server.py +38 -8
- scitex/bridge/_figrecipe.py +1 -1
- scitex/bridge/_helpers.py +1 -1
- scitex/bridge/_plt_vis.py +1 -1
- scitex/bridge/_stats_plt.py +1 -1
- scitex/bridge/_stats_vis.py +2 -2
- scitex/browser/automation/CookieHandler.py +1 -1
- scitex/browser/core/BrowserMixin.py +1 -1
- scitex/browser/core/ChromeProfileManager.py +1 -1
- scitex/browser/debugging/_browser_logger.py +1 -1
- scitex/browser/debugging/_highlight_element.py +1 -1
- scitex/browser/debugging/_show_grid.py +1 -1
- scitex/browser/interaction/click_center.py +1 -1
- scitex/browser/interaction/click_with_fallbacks.py +1 -1
- scitex/browser/interaction/close_popups.py +1 -1
- scitex/browser/interaction/fill_with_fallbacks.py +1 -1
- scitex/browser/pdf/click_download_for_chrome_pdf_viewer.py +1 -1
- scitex/browser/pdf/detect_chrome_pdf_viewer.py +1 -1
- scitex/browser/stealth/HumanBehavior.py +1 -1
- scitex/browser/stealth/StealthManager.py +1 -1
- scitex/{fig → canvas}/__init__.py +84 -96
- scitex/canvas/_mcp_handlers.py +372 -0
- scitex/canvas/_mcp_tool_schemas.py +219 -0
- scitex/{fig → canvas}/backend/_parser.py +1 -1
- scitex/{fig → canvas}/canvas.py +13 -14
- scitex/{fts/_fig/_editor → canvas/editor}/_defaults.py +2 -2
- scitex/{fig → canvas}/editor/edit/__init__.py +11 -14
- scitex/{fig → canvas}/editor/edit/bundle_resolver.py +56 -48
- scitex/{fig → canvas}/editor/edit/editor_launcher.py +79 -26
- scitex/{fts/_fig/_editor/_cui/_panel_loader.py → canvas/editor/edit/panel_loader.py} +8 -8
- scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_bbox.py +2 -1
- scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_core.py +84 -84
- scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/_renderer.py +7 -6
- scitex/{fts/_fig/_editor/_gui/_flask_editor → canvas/editor/flask_editor}/static/css/features/canvas.css +2 -2
- scitex/{fig → canvas}/editor/flask_editor/static/css/features/panel-grid.css +1 -1
- scitex/{fig → canvas}/editor/flask_editor/static/js/core/api.js +3 -4
- scitex/{fig → canvas}/editor/flask_editor/static/js/editor/preview.js +5 -5
- scitex/{fig → canvas}/editor/flask_editor/templates/_html.py +3 -3
- scitex/{fig → canvas}/editor/flask_editor/templates/_scripts.py +10 -10
- scitex/{fig → canvas}/editor/flask_editor/templates/_styles.py +3 -3
- scitex/{fig → canvas}/io/__init__.py +32 -38
- scitex/{fig → canvas}/io/_bundle.py +217 -154
- scitex/{fig → canvas}/io/_canvas.py +1 -1
- scitex/{fig → canvas}/io/_data.py +1 -1
- scitex/{fig → canvas}/io/_export.py +1 -1
- scitex/{fig → canvas}/io/_load.py +1 -1
- scitex/{fig → canvas}/io/_panel.py +1 -1
- scitex/{fig → canvas}/io/_save.py +1 -1
- scitex/canvas/mcp_server.py +151 -0
- scitex/{fig → canvas}/model/__init__.py +1 -1
- scitex/{fig → canvas}/model/_annotations.py +1 -1
- scitex/{fig → canvas}/model/_axes.py +1 -1
- scitex/{fig → canvas}/model/_figure.py +1 -1
- scitex/{fig → canvas}/model/_guides.py +1 -1
- scitex/{fig → canvas}/model/_plot.py +1 -1
- scitex/{fig → canvas}/model/_styles.py +1 -1
- scitex/{fig → canvas}/utils/__init__.py +1 -1
- scitex/capture/mcp_server.py +41 -12
- scitex/cli/audio.py +233 -0
- scitex/cli/capture.py +307 -0
- scitex/cli/convert.py +10 -6
- scitex/cli/main.py +27 -4
- scitex/cli/repro.py +233 -0
- scitex/cli/resource.py +240 -0
- scitex/cli/stats.py +325 -0
- scitex/cli/template.py +236 -0
- scitex/cli/tex.py +286 -0
- scitex/cli/web.py +11 -12
- scitex/dev/__init__.py +3 -0
- scitex/dev/_pyproject.py +405 -0
- scitex/dev/plt/__init__.py +2 -2
- scitex/dev/plt/mpl/get_dir_ax.py +1 -1
- scitex/dev/plt/mpl/get_signatures.py +1 -1
- scitex/dev/plt/mpl/get_signatures_details.py +1 -1
- scitex/diagram/README.md +7 -7
- scitex/diagram/_mcp_handlers.py +400 -0
- scitex/diagram/_mcp_tool_schemas.py +157 -0
- scitex/diagram/mcp_server.py +151 -0
- scitex/dsp/_demo_sig.py +51 -5
- scitex/dsp/_mne.py +13 -2
- scitex/dsp/_modulation_index.py +15 -3
- scitex/dsp/_pac.py +23 -5
- scitex/dsp/_psd.py +16 -4
- scitex/dsp/_resample.py +24 -4
- scitex/dsp/_transform.py +16 -3
- scitex/dsp/add_noise.py +15 -1
- scitex/dsp/norm.py +17 -2
- scitex/dsp/reference.py +17 -1
- scitex/dsp/utils/_differential_bandpass_filters.py +20 -2
- scitex/dsp/utils/_zero_pad.py +18 -4
- scitex/dt/_normalize_timestamp.py +1 -1
- scitex/git/_session.py +1 -1
- scitex/io/__init__.py +7 -19
- scitex/io/_load.py +15 -19
- scitex/io/_load_modules/_canvas.py +2 -2
- scitex/io/_load_modules/_con.py +17 -6
- scitex/io/_load_modules/_eeg.py +28 -13
- scitex/io/_load_modules/_optuna.py +21 -63
- scitex/io/_load_modules/_torch.py +11 -3
- scitex/io/_save.py +11 -16
- scitex/io/_save_modules/__init__.py +6 -10
- scitex/io/_save_modules/_canvas.py +3 -3
- scitex/io/_save_modules/_optuna_study_as_csv_and_pngs.py +13 -2
- scitex/io/_save_modules/_plot_bundle.py +112 -0
- scitex/io/_save_modules/{_pltz_stx.py → _plot_scitex.py} +7 -7
- scitex/io/_save_modules/_stx_bundle.py +16 -16
- scitex/io/_save_modules/_torch.py +11 -3
- scitex/io/bundle/README.md +89 -80
- scitex/{fts/_bundle/_FTS.py → io/bundle/_Bundle.py} +197 -95
- scitex/io/bundle/__init__.py +67 -35
- scitex/{fts/_bundle → io/bundle}/_children.py +32 -40
- scitex/io/bundle/_core.py +184 -97
- scitex/{fts/_bundle/_dataclasses/_Node.py → io/bundle/_dataclasses/_Spec.py} +29 -23
- scitex/{fts/_bundle/_dataclasses/_NodeRefs.py → io/bundle/_dataclasses/_SpecRefs.py} +6 -6
- scitex/{fts/_bundle → io/bundle}/_dataclasses/__init__.py +4 -4
- scitex/{fts/_bundle → io/bundle}/_loader.py +19 -19
- scitex/io/bundle/_manifest.py +99 -0
- scitex/{fts/_bundle → io/bundle}/_mpl_helpers.py +119 -28
- scitex/io/bundle/_nested.py +113 -100
- scitex/{fts/_bundle → io/bundle}/_saver.py +13 -14
- scitex/{fts/_bundle → io/bundle}/_storage.py +3 -3
- scitex/io/bundle/_types.py +41 -16
- scitex/{fts/_bundle → io/bundle}/_validation.py +20 -18
- scitex/io/bundle/_zip.py +21 -31
- scitex/{fts/_kinds → io/bundle/kinds}/_plot/_backend/_parser.py +1 -1
- scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Annotations.py +1 -1
- scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Axes.py +1 -1
- scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Figure.py +1 -1
- scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_Guides.py +1 -1
- scitex/{fts/_kinds → io/bundle/kinds}/_plot/_models/_Plot.py +1 -1
- scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_Styles.py +1 -1
- scitex/{fts/_kinds → io/bundle/kinds}/_plot/_utils/_plot_layout.py +1 -1
- scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/__init__.py +1 -1
- scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_editor/_app.py +1 -1
- scitex/{fts/_tables → io/bundle/kinds/_table}/_latex/_export.py +1 -1
- scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_figure_exporter.py +1 -1
- scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_table_exporter.py +1 -1
- scitex/io/bundle/schemas/__init__.py +30 -0
- scitex/mcp_server.py +159 -0
- scitex/parallel/_run.py +5 -4
- scitex/path/_find.py +60 -83
- scitex/path/_get_module_path.py +23 -21
- scitex/path/_get_spath.py +6 -27
- scitex/path/_getsize.py +23 -9
- scitex/path/_increment_version.py +31 -38
- scitex/path/_mk_spath.py +26 -29
- scitex/path/_path.py +5 -12
- scitex/path/_split.py +27 -15
- scitex/path/_this_path.py +23 -9
- scitex/plt/_mcp_handlers.py +361 -0
- scitex/plt/_mcp_tool_schemas.py +169 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin/__init__.py +2 -1
- scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +2 -2
- scitex/plt/gallery/_generate.py +76 -50
- scitex/plt/io/__init__.py +17 -19
- scitex/plt/io/_bundle.py +99 -52
- scitex/plt/io/_layered_bundle.py +303 -168
- scitex/plt/mcp_server.py +205 -0
- scitex/plt/utils/_csv_column_naming.py +250 -118
- scitex/repro/README_RandomStateManager.md +3 -3
- scitex/repro/_RandomStateManager.py +14 -14
- scitex/repro/_gen_ID.py +1 -1
- scitex/repro/_gen_timestamp.py +1 -1
- scitex/repro/_hash_array.py +4 -4
- scitex/schema/__init__.py +69 -73
- scitex/schema/_canvas.py +1 -1
- scitex/schema/_stats.py +2 -2
- scitex/scholar/__main__.py +24 -2
- scitex/scholar/_mcp_handlers.py +685 -0
- scitex/scholar/_mcp_tool_schemas.py +339 -0
- scitex/scholar/docs/template.py +1 -1
- scitex/scholar/examples/07_storage_integration.py +1 -1
- scitex/scholar/impact_factor/jcr/ImpactFactorJCREngine.py +1 -1
- scitex/scholar/impact_factor/jcr/build_database.py +1 -1
- scitex/scholar/mcp_server.py +315 -0
- scitex/scholar/pdf_download/ScholarPDFDownloader.py +1 -1
- scitex/scholar/pipelines/ScholarPipelineBibTeX.py +1 -1
- scitex/scholar/pipelines/ScholarPipelineParallel.py +1 -1
- scitex/scholar/pipelines/ScholarPipelineSingle.py +1 -1
- scitex/scholar/storage/PaperIO.py +1 -1
- scitex/session/README.md +4 -4
- scitex/session/__init__.py +1 -1
- scitex/session/_decorator.py +9 -9
- scitex/session/_lifecycle.py +5 -5
- scitex/session/template.py +1 -1
- scitex/stats/__init__.py +30 -33
- scitex/stats/__main__.py +281 -0
- scitex/stats/_mcp_handlers.py +1191 -0
- scitex/stats/_mcp_tool_schemas.py +384 -0
- scitex/stats/_schema.py +1 -1
- scitex/stats/correct/_correct_bonferroni.py +1 -1
- scitex/stats/correct/_correct_fdr.py +1 -1
- scitex/stats/correct/_correct_fdr_.py +1 -1
- scitex/stats/correct/_correct_holm.py +1 -1
- scitex/stats/correct/_correct_sidak.py +1 -1
- scitex/stats/effect_sizes/_cliffs_delta.py +1 -1
- scitex/stats/effect_sizes/_cohens_d.py +1 -1
- scitex/stats/effect_sizes/_epsilon_squared.py +1 -1
- scitex/stats/effect_sizes/_eta_squared.py +1 -1
- scitex/stats/effect_sizes/_prob_superiority.py +1 -1
- scitex/stats/io/__init__.py +10 -11
- scitex/stats/io/_bundle.py +16 -16
- scitex/stats/mcp_server.py +405 -0
- scitex/stats/posthoc/_dunnett.py +1 -1
- scitex/stats/posthoc/_games_howell.py +1 -1
- scitex/stats/posthoc/_tukey_hsd.py +1 -1
- scitex/stats/power/_power.py +1 -1
- scitex/stats/utils/_effect_size.py +1 -1
- scitex/stats/utils/_formatters.py +1 -1
- scitex/stats/utils/_power.py +1 -1
- scitex/template/_mcp_handlers.py +259 -0
- scitex/template/_mcp_tool_schemas.py +112 -0
- scitex/template/mcp_server.py +186 -0
- scitex/utils/_verify_scitex_format.py +2 -2
- scitex/utils/template.py +1 -1
- scitex/web/__init__.py +12 -11
- scitex/web/_scraping.py +26 -265
- scitex/web/download_images.py +316 -0
- scitex/writer/Writer.py +1 -1
- scitex/writer/_clone_writer_project.py +1 -1
- scitex/writer/_validate_tree_structures.py +1 -1
- scitex/writer/dataclasses/config/_WriterConfig.py +1 -1
- scitex/writer/dataclasses/contents/_ManuscriptContents.py +1 -1
- scitex/writer/dataclasses/core/_Document.py +1 -1
- scitex/writer/dataclasses/core/_DocumentSection.py +1 -1
- scitex/writer/dataclasses/results/_CompilationResult.py +1 -1
- scitex/writer/dataclasses/results/_LaTeXIssue.py +1 -1
- scitex/writer/utils/.legacy_git_retry.py +7 -5
- scitex/writer/utils/_parse_latex_logs.py +1 -1
- scitex-2.13.0.dist-info/METADATA +1231 -0
- {scitex-2.10.3.dist-info → scitex-2.13.0.dist-info}/RECORD +376 -470
- scitex-2.13.0.dist-info/entry_points.txt +11 -0
- scitex/fig/editor/_defaults.py +0 -300
- scitex/fig/editor/edit/panel_loader.py +0 -232
- scitex/fig/editor/flask_editor/_bbox.py +0 -1299
- scitex/fig/editor/flask_editor/_core.py +0 -1429
- scitex/fig/editor/flask_editor/_renderer.py +0 -813
- scitex/fig/editor/flask_editor/static/css/features/canvas.css +0 -176
- scitex/fts/README.md +0 -262
- scitex/fts/TODO.md +0 -66
- scitex/fts/__init__.py +0 -90
- scitex/fts/_bundle/README_IN_BUNDLE.md +0 -102
- scitex/fts/_bundle/__init__.py +0 -38
- scitex/fts/_bundle/_utils/__init__.py +0 -55
- scitex/fts/_bundle/_utils/_const.py +0 -26
- scitex/fts/_bundle/_utils/_errors.py +0 -73
- scitex/fts/_bundle/_utils/_generate.py +0 -21
- scitex/fts/_bundle/_utils/_types.py +0 -76
- scitex/fts/_bundle/_zipbundle.py +0 -165
- scitex/fts/_fig/__init__.py +0 -22
- scitex/fts/_fig/_backend/_parser.py +0 -188
- scitex/fts/_fig/_editor/__init__.py +0 -14
- scitex/fts/_fig/_editor/_cui/__init__.py +0 -33
- scitex/fts/_fig/_editor/_cui/_backend_detector.py +0 -39
- scitex/fts/_fig/_editor/_cui/_bundle_resolver.py +0 -366
- scitex/fts/_fig/_editor/_cui/_editor_launcher.py +0 -175
- scitex/fts/_fig/_editor/_cui/_manual_handler.py +0 -52
- scitex/fts/_fig/_editor/_cui/_path_resolver.py +0 -66
- scitex/fts/_fig/_editor/_gui/__init__.py +0 -11
- scitex/fts/_fig/_editor/_gui/_flask_editor/__init__.py +0 -20
- scitex/fts/_fig/_editor/_gui/_flask_editor/_plotter.py +0 -664
- scitex/fts/_fig/_editor/_gui/_flask_editor/_utils.py +0 -79
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/reset.css +0 -41
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/typography.css +0 -16
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/base/variables.css +0 -85
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/buttons.css +0 -217
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/context-menu.css +0 -93
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/dropdown.css +0 -57
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/forms.css +0 -112
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/modal.css +0 -59
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/components/sections.css +0 -212
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/element-inspector.css +0 -190
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/loading.css +0 -59
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/overlay.css +0 -45
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/panel-grid.css +0 -95
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/selection.css +0 -101
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/features/statistics.css +0 -138
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/index.css +0 -31
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/container.css +0 -7
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/controls.css +0 -56
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/css/layout/preview.css +0 -78
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/axis.js +0 -314
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/basic.js +0 -107
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/alignment/distribute.js +0 -54
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/canvas.js +0 -172
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/dragging.js +0 -258
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/resize.js +0 -48
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/canvas/selection.js +0 -71
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/api.js +0 -288
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/state.js +0 -143
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/core/utils.js +0 -245
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/dev/element-inspector.js +0 -992
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/bbox.js +0 -339
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/element-drag.js +0 -286
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/overlay.js +0 -371
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/editor/preview.js +0 -293
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/main.js +0 -426
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/context-menu.js +0 -152
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/shortcuts/keyboard.js +0 -265
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/controls.js +0 -184
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/download.js +0 -57
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/help.js +0 -100
- scitex/fts/_fig/_editor/_gui/_flask_editor/static/js/ui/theme.js +0 -34
- scitex/fts/_fig/_editor/_gui/_flask_editor/templates/__init__.py +0 -124
- scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_html.py +0 -851
- scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_scripts.py +0 -4932
- scitex/fts/_fig/_editor/_gui/_flask_editor/templates/_styles.py +0 -1657
- scitex/fts/_fig/_editor/_gui/_flask_editor.py +0 -36
- scitex/fts/_fig/_models/_Annotations.py +0 -115
- scitex/fts/_fig/_models/_Axes.py +0 -152
- scitex/fts/_fig/_models/_Figure.py +0 -138
- scitex/fts/_fig/_models/_Plot.py +0 -123
- scitex/fts/_fig/_utils/_plot_layout.py +0 -397
- scitex/fts/_kinds/_figure/_composite.py +0 -345
- scitex/fts/_kinds/_plot/_backend/__init__.py +0 -53
- scitex/fts/_kinds/_plot/_backend/_export.py +0 -165
- scitex/fts/_kinds/_plot/_backend/_render.py +0 -538
- scitex/fts/_kinds/_plot/_dataclasses/_ChannelEncoding.py +0 -46
- scitex/fts/_kinds/_plot/_dataclasses/_Encoding.py +0 -82
- scitex/fts/_kinds/_plot/_dataclasses/_Theme.py +0 -441
- scitex/fts/_kinds/_plot/_dataclasses/_TraceEncoding.py +0 -52
- scitex/fts/_kinds/_plot/_dataclasses/__init__.py +0 -47
- scitex/fts/_kinds/_plot/_models/_Guides.py +0 -104
- scitex/fts/_kinds/_plot/_models/_Styles.py +0 -245
- scitex/fts/_kinds/_plot/_models/__init__.py +0 -80
- scitex/fts/_kinds/_plot/_models/_plot_types/__init__.py +0 -156
- scitex/fts/_kinds/_plot/_models/_plot_types/_bar.py +0 -43
- scitex/fts/_kinds/_plot/_models/_plot_types/_box.py +0 -38
- scitex/fts/_kinds/_plot/_models/_plot_types/_distribution.py +0 -36
- scitex/fts/_kinds/_plot/_models/_plot_types/_errorbar.py +0 -60
- scitex/fts/_kinds/_plot/_models/_plot_types/_histogram.py +0 -30
- scitex/fts/_kinds/_plot/_models/_plot_types/_image.py +0 -61
- scitex/fts/_kinds/_plot/_models/_plot_types/_line.py +0 -57
- scitex/fts/_kinds/_plot/_models/_plot_types/_scatter.py +0 -30
- scitex/fts/_kinds/_plot/_models/_plot_types/_seaborn.py +0 -121
- scitex/fts/_kinds/_plot/_models/_plot_types/_violin.py +0 -36
- scitex/fts/_kinds/_plot/_utils/__init__.py +0 -129
- scitex/fts/_kinds/_plot/_utils/_auto_layout.py +0 -127
- scitex/fts/_kinds/_plot/_utils/_calc_bounds.py +0 -111
- scitex/fts/_kinds/_plot/_utils/_const_sizes.py +0 -48
- scitex/fts/_kinds/_plot/_utils/_convert_coords.py +0 -77
- scitex/fts/_kinds/_plot/_utils/_get_template.py +0 -178
- scitex/fts/_kinds/_plot/_utils/_normalize.py +0 -73
- scitex/fts/_kinds/_plot/_utils/_validate.py +0 -197
- scitex/fts/_kinds/_table/_latex/_export.py +0 -279
- scitex/fts/_stats/__init__.py +0 -48
- scitex/fts/_stats/_dataclasses/_Stats.py +0 -423
- scitex/fts/_stats/_dataclasses/__init__.py +0 -48
- scitex/fts/_tables/__init__.py +0 -65
- scitex/fts/_tables/_latex/__init__.py +0 -93
- scitex/fts/_tables/_latex/_editor/__init__.py +0 -11
- scitex/fts/_tables/_latex/_editor/_app.py +0 -725
- scitex/fts/_tables/_latex/_figure_exporter.py +0 -153
- scitex/fts/_tables/_latex/_stats_formatter.py +0 -274
- scitex/fts/_tables/_latex/_table_exporter.py +0 -362
- scitex/fts/_tables/_latex/_utils.py +0 -369
- scitex/fts/_tables/_latex/_validator.py +0 -445
- scitex/io/_save_modules/_pltz_bundle.py +0 -356
- scitex-2.10.3.dist-info/METADATA +0 -952
- scitex-2.10.3.dist-info/entry_points.txt +0 -2
- /scitex/{fig → canvas}/README.md +0 -0
- /scitex/{fig → canvas}/backend/__init__.py +0 -0
- /scitex/{fig → canvas}/backend/_export.py +0 -0
- /scitex/{fig → canvas}/backend/_render.py +0 -0
- /scitex/{fig → canvas}/docs/CANVAS_ARCHITECTURE.md +0 -0
- /scitex/{fig → canvas}/editor/__init__.py +0 -0
- /scitex/{fig → canvas}/editor/_dearpygui_editor.py +0 -0
- /scitex/{fig → canvas}/editor/_flask_editor.py +0 -0
- /scitex/{fig → canvas}/editor/_mpl_editor.py +0 -0
- /scitex/{fig → canvas}/editor/_qt_editor.py +0 -0
- /scitex/{fig → canvas}/editor/_tkinter_editor.py +0 -0
- /scitex/{fig → canvas}/editor/edit/backend_detector.py +0 -0
- /scitex/{fig → canvas}/editor/edit/manual_handler.py +0 -0
- /scitex/{fig → canvas}/editor/edit/path_resolver.py +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/__init__.py +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/_plotter.py +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/_utils.py +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/base/reset.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/base/typography.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/base/variables.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/components/buttons.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/components/context-menu.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/components/dropdown.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/components/forms.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/components/modal.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/components/sections.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/features/element-inspector.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/features/loading.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/features/overlay.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/features/selection.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/features/statistics.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/index.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/container.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/controls.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/css/layout/preview.css +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/axis.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/basic.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/alignment/distribute.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/canvas.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/dragging.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/resize.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/canvas/selection.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/core/state.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/core/utils.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/dev/element-inspector.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/bbox.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/element-drag.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/editor/overlay.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/main.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/shortcuts/context-menu.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/shortcuts/keyboard.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/controls.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/download.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/help.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/static/js/ui/theme.js +0 -0
- /scitex/{fig → canvas}/editor/flask_editor/templates/__init__.py +0 -0
- /scitex/{fig → canvas}/io/_directory.py +0 -0
- /scitex/{fig → canvas}/model/_plot_types.py +0 -0
- /scitex/{fig → canvas}/utils/_defaults.py +0 -0
- /scitex/{fig → canvas}/utils/_validate.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_conversion/__init__.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_conversion/_bundle2dict.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_conversion/_dict2bundle.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_dataclasses/_Axes.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_dataclasses/_BBox.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_dataclasses/_ColumnDef.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataFormat.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataInfo.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_dataclasses/_DataSource.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_dataclasses/_SizeMM.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_extractors/__init__.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_bar.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_line.py +0 -0
- /scitex/{fts/_bundle → io/bundle}/_extractors/_extract_scatter.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/__init__.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_figure/__init__.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_figure}/_composite.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_plot/__init__.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/__init__.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/_export.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_backend/_render.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_ChannelEncoding.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_Encoding.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_Theme.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/_TraceEncoding.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_dataclasses/__init__.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/__init__.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/__init__.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_bar.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_box.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_distribution.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_errorbar.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_histogram.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_image.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_line.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_scatter.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_seaborn.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_models/_plot_types/_violin.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/__init__.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_auto_layout.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_calc_bounds.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_const_sizes.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_convert_coords.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_get_template.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_normalize.py +0 -0
- /scitex/{fts/_fig → io/bundle/kinds/_plot}/_utils/_validate.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_shape/__init__.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_stats/__init__.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_stats/_dataclasses/_Stats.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_stats/_dataclasses/__init__.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_table/__init__.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_editor/__init__.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_stats_formatter.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_utils.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_table/_latex/_validator.py +0 -0
- /scitex/{fts/_kinds → io/bundle/kinds}/_text/__init__.py +0 -0
- /scitex/{fts/_schemas → io/bundle/schemas}/data_info.schema.json +0 -0
- /scitex/{fts/_schemas → io/bundle/schemas}/encoding.schema.json +0 -0
- /scitex/{fts/_schemas → io/bundle/schemas}/node.schema.json +0 -0
- /scitex/{fts/_schemas → io/bundle/schemas}/render_manifest.schema.json +0 -0
- /scitex/{fts/_schemas → io/bundle/schemas}/stats.schema.json +0 -0
- /scitex/{fts/_schemas → io/bundle/schemas}/theme.schema.json +0 -0
- {scitex-2.10.3.dist-info → scitex-2.13.0.dist-info}/WHEEL +0 -0
- {scitex-2.10.3.dist-info → scitex-2.13.0.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
|
-
# -*- coding: utf-8 -*-
|
|
3
2
|
# Timestamp: 2025-12-08
|
|
4
3
|
# File: ./src/scitex/vis/__init__.py
|
|
5
4
|
"""
|
|
6
|
-
SciTeX Visualization Module (scitex.
|
|
5
|
+
SciTeX Visualization Module (scitex.canvas)
|
|
7
6
|
|
|
8
7
|
Canvas-based composition of publication-quality figures.
|
|
9
8
|
|
|
@@ -19,7 +18,7 @@ Quick Start:
|
|
|
19
18
|
>>> # Create canvas and add panels
|
|
20
19
|
>>> stx.vis.create_canvas("/output", "fig1")
|
|
21
20
|
>>> stx.vis.add_panel("/output", "fig1", "panel_a", source="plot.png",
|
|
22
|
-
...
|
|
21
|
+
... xy_mm=(10, 10), size_mm=(80, 60), label="A")
|
|
23
22
|
>>>
|
|
24
23
|
>>> # Save with stx.io (auto-exports PNG/PDF/SVG)
|
|
25
24
|
>>> canvas = stx.io.load("/output/fig1.canvas")
|
|
@@ -34,46 +33,31 @@ Directory Structure:
|
|
|
34
33
|
"""
|
|
35
34
|
|
|
36
35
|
# Submodules for advanced use
|
|
37
|
-
from . import io
|
|
38
|
-
from . import model
|
|
39
|
-
from . import backend
|
|
40
|
-
from . import utils
|
|
41
|
-
from . import editor
|
|
36
|
+
from . import backend, editor, io, model, utils
|
|
42
37
|
|
|
43
38
|
# Canvas class
|
|
44
39
|
from .canvas import Canvas
|
|
45
40
|
|
|
41
|
+
# Editor
|
|
42
|
+
from .editor import edit
|
|
43
|
+
|
|
44
|
+
# Data integrity
|
|
45
|
+
# Export (usually handled by stx.io.save, but available for explicit use)
|
|
46
46
|
# =============================================================================
|
|
47
47
|
# Primary API (minimal, reusable, flexible)
|
|
48
48
|
# =============================================================================
|
|
49
|
-
|
|
50
49
|
# Canvas operations
|
|
51
|
-
from .io import (
|
|
52
|
-
ensure_canvas_directory as create_canvas,
|
|
53
|
-
get_canvas_directory_path as get_canvas_path,
|
|
54
|
-
canvas_directory_exists as canvas_exists,
|
|
55
|
-
list_canvas_directories as list_canvases,
|
|
56
|
-
delete_canvas_directory as delete_canvas,
|
|
57
|
-
)
|
|
58
|
-
|
|
59
50
|
# Panel operations
|
|
60
|
-
from .io import
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
remove_panel,
|
|
65
|
-
list_panels,
|
|
66
|
-
)
|
|
67
|
-
|
|
68
|
-
# Export (usually handled by stx.io.save, but available for explicit use)
|
|
51
|
+
from .io import add_panel_from_image, add_panel_from_scitex
|
|
52
|
+
from .io import canvas_directory_exists as canvas_exists
|
|
53
|
+
from .io import delete_canvas_directory as delete_canvas
|
|
54
|
+
from .io import ensure_canvas_directory as create_canvas
|
|
69
55
|
from .io import export_canvas_to_file as export_canvas
|
|
70
|
-
|
|
71
|
-
|
|
56
|
+
from .io import get_canvas_directory_path as get_canvas_path
|
|
57
|
+
from .io import list_canvas_directories as list_canvases
|
|
58
|
+
from .io import list_panels, remove_panel, update_panel
|
|
72
59
|
from .io import verify_all_data_hashes as verify_data
|
|
73
60
|
|
|
74
|
-
# Editor
|
|
75
|
-
from .editor import edit
|
|
76
|
-
|
|
77
61
|
|
|
78
62
|
# =============================================================================
|
|
79
63
|
# Convenience wrapper for add_panel
|
|
@@ -83,8 +67,8 @@ def add_panel(
|
|
|
83
67
|
canvas_name,
|
|
84
68
|
panel_name,
|
|
85
69
|
source,
|
|
86
|
-
|
|
87
|
-
|
|
70
|
+
xy_mm=(0, 0),
|
|
71
|
+
size_mm=(50, 50),
|
|
88
72
|
label="",
|
|
89
73
|
bundle=False,
|
|
90
74
|
**kwargs,
|
|
@@ -102,10 +86,10 @@ def add_panel(
|
|
|
102
86
|
Name for the panel
|
|
103
87
|
source : str or Path
|
|
104
88
|
Source file (PNG, JPG, SVG)
|
|
105
|
-
|
|
106
|
-
(x_mm, y_mm) position on canvas
|
|
107
|
-
|
|
108
|
-
(width_mm, height_mm) panel size
|
|
89
|
+
xy_mm : tuple
|
|
90
|
+
(x_mm, y_mm) position on canvas in millimeters
|
|
91
|
+
size_mm : tuple
|
|
92
|
+
(width_mm, height_mm) panel size in millimeters
|
|
109
93
|
label : str
|
|
110
94
|
Panel label (A, B, C...)
|
|
111
95
|
bundle : bool
|
|
@@ -117,8 +101,8 @@ def add_panel(
|
|
|
117
101
|
|
|
118
102
|
source = Path(source)
|
|
119
103
|
panel_properties = {
|
|
120
|
-
"position": {"x_mm":
|
|
121
|
-
"size": {"width_mm":
|
|
104
|
+
"position": {"x_mm": xy_mm[0], "y_mm": xy_mm[1]},
|
|
105
|
+
"size": {"width_mm": size_mm[0], "height_mm": size_mm[1]},
|
|
122
106
|
**kwargs,
|
|
123
107
|
}
|
|
124
108
|
if label:
|
|
@@ -147,32 +131,33 @@ def add_panel(
|
|
|
147
131
|
|
|
148
132
|
|
|
149
133
|
# =============================================================================
|
|
150
|
-
# .
|
|
134
|
+
# .figure Bundle Support
|
|
151
135
|
# =============================================================================
|
|
152
136
|
|
|
153
|
-
|
|
137
|
+
|
|
138
|
+
def save_figure(
|
|
154
139
|
panels,
|
|
155
140
|
path,
|
|
156
141
|
spec=None,
|
|
157
142
|
as_zip=None,
|
|
158
143
|
):
|
|
159
144
|
"""
|
|
160
|
-
Save panels as a .
|
|
145
|
+
Save panels as a .figure publication figure bundle.
|
|
161
146
|
|
|
162
147
|
Parameters
|
|
163
148
|
----------
|
|
164
149
|
panels : dict
|
|
165
|
-
Dictionary mapping panel IDs to .
|
|
166
|
-
Example: {"A": "timecourse.
|
|
150
|
+
Dictionary mapping panel IDs to .plot bundle paths or data.
|
|
151
|
+
Example: {"A": "timecourse.plot", "B": "barplot.plot"}
|
|
167
152
|
path : str or Path
|
|
168
|
-
Output path (e.g., "Figure1.
|
|
169
|
-
- Path ending with ".
|
|
170
|
-
- Path ending with ".
|
|
153
|
+
Output path (e.g., "Figure1.figure.zip" or "Figure1.figure").
|
|
154
|
+
- Path ending with ".zip" creates ZIP archive
|
|
155
|
+
- Path ending with ".figure" creates directory bundle
|
|
171
156
|
spec : dict, optional
|
|
172
157
|
Figure specification. Auto-generated if None.
|
|
173
158
|
as_zip : bool, optional
|
|
174
159
|
If True, save as ZIP archive. If False, save as directory.
|
|
175
|
-
Default: auto-detect from path
|
|
160
|
+
Default: auto-detect from path.
|
|
176
161
|
|
|
177
162
|
Returns
|
|
178
163
|
-------
|
|
@@ -181,24 +166,25 @@ def save_figz(
|
|
|
181
166
|
|
|
182
167
|
Examples
|
|
183
168
|
--------
|
|
184
|
-
>>> import scitex.
|
|
169
|
+
>>> import scitex.canvas as sfig
|
|
185
170
|
>>> panels = {
|
|
186
|
-
... "A": "timecourse.
|
|
187
|
-
... "B": "barplot.
|
|
171
|
+
... "A": "timecourse.plot",
|
|
172
|
+
... "B": "barplot.plot"
|
|
188
173
|
... }
|
|
189
|
-
>>> sfig.
|
|
190
|
-
>>> sfig.
|
|
174
|
+
>>> sfig.save_figure(panels, "Figure1.figure.zip") # Creates ZIP
|
|
175
|
+
>>> sfig.save_figure(panels, "Figure1.figure") # Creates directory
|
|
191
176
|
"""
|
|
192
|
-
from pathlib import Path
|
|
193
177
|
import shutil
|
|
194
|
-
from
|
|
178
|
+
from pathlib import Path
|
|
179
|
+
|
|
180
|
+
from scitex.io.bundle import BundleType, save
|
|
195
181
|
|
|
196
182
|
p = Path(path)
|
|
197
183
|
spath = str(path)
|
|
198
184
|
|
|
199
185
|
# Auto-detect as_zip from path suffix if not specified
|
|
200
186
|
if as_zip is None:
|
|
201
|
-
as_zip =
|
|
187
|
+
as_zip = spath.endswith(".zip")
|
|
202
188
|
|
|
203
189
|
# Auto-generate spec if not provided
|
|
204
190
|
if spec is None:
|
|
@@ -206,28 +192,28 @@ def save_figz(
|
|
|
206
192
|
|
|
207
193
|
# Build bundle data - pass source paths directly for file copying
|
|
208
194
|
bundle_data = {
|
|
209
|
-
|
|
210
|
-
|
|
195
|
+
"spec": spec,
|
|
196
|
+
"plots": {},
|
|
211
197
|
}
|
|
212
198
|
|
|
213
199
|
# Pass source paths directly (not loaded data) to preserve all files
|
|
214
|
-
for panel_id,
|
|
215
|
-
|
|
216
|
-
if
|
|
200
|
+
for panel_id, plot_source in panels.items():
|
|
201
|
+
plot_path = Path(plot_source)
|
|
202
|
+
if plot_path.exists():
|
|
217
203
|
# Store source path for direct copying
|
|
218
|
-
bundle_data[
|
|
204
|
+
bundle_data["plots"][panel_id] = str(plot_path)
|
|
219
205
|
|
|
220
|
-
return save(bundle_data, p, bundle_type=BundleType.
|
|
206
|
+
return save(bundle_data, p, bundle_type=BundleType.FIGURE, as_zip=as_zip)
|
|
221
207
|
|
|
222
208
|
|
|
223
|
-
def
|
|
209
|
+
def load_figure(path):
|
|
224
210
|
"""
|
|
225
|
-
Load a .
|
|
211
|
+
Load a .figure bundle.
|
|
226
212
|
|
|
227
213
|
Parameters
|
|
228
214
|
----------
|
|
229
215
|
path : str or Path
|
|
230
|
-
Path to .
|
|
216
|
+
Path to .figure bundle (directory or ZIP).
|
|
231
217
|
|
|
232
218
|
Returns
|
|
233
219
|
-------
|
|
@@ -238,7 +224,7 @@ def load_figz(path):
|
|
|
238
224
|
|
|
239
225
|
Examples
|
|
240
226
|
--------
|
|
241
|
-
>>> figure = scitex.
|
|
227
|
+
>>> figure = scitex.canvas.load_figure("Figure1.figure")
|
|
242
228
|
>>> print(figure['spec']['figure']['title'])
|
|
243
229
|
>>> panel_a = figure['panels']['A']
|
|
244
230
|
>>> print(panel_a['spec'], panel_a['data'])
|
|
@@ -247,19 +233,19 @@ def load_figz(path):
|
|
|
247
233
|
|
|
248
234
|
bundle = load(path)
|
|
249
235
|
|
|
250
|
-
if bundle[
|
|
251
|
-
raise ValueError(f"Not a .
|
|
236
|
+
if bundle["type"] != "figure":
|
|
237
|
+
raise ValueError(f"Not a .figure bundle: {path}")
|
|
252
238
|
|
|
253
239
|
result = {
|
|
254
|
-
|
|
255
|
-
|
|
240
|
+
"spec": bundle.get("spec", {}),
|
|
241
|
+
"panels": {},
|
|
256
242
|
}
|
|
257
243
|
|
|
258
244
|
# Return spec and data for each panel (reconstruction is optional)
|
|
259
|
-
for panel_id, plot_bundle in bundle.get(
|
|
260
|
-
result[
|
|
261
|
-
|
|
262
|
-
|
|
245
|
+
for panel_id, plot_bundle in bundle.get("plots", {}).items():
|
|
246
|
+
result["panels"][panel_id] = {
|
|
247
|
+
"spec": plot_bundle.get("spec", {}),
|
|
248
|
+
"data": plot_bundle.get("data"),
|
|
263
249
|
}
|
|
264
250
|
|
|
265
251
|
return result
|
|
@@ -270,17 +256,17 @@ def _generate_figure_spec(panels):
|
|
|
270
256
|
from pathlib import Path
|
|
271
257
|
|
|
272
258
|
spec = {
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
259
|
+
"schema": {"name": "scitex.canvas.figure", "version": "1.0.0"},
|
|
260
|
+
"figure": {
|
|
261
|
+
"id": "figure",
|
|
262
|
+
"title": "",
|
|
263
|
+
"caption": "",
|
|
264
|
+
"styles": {
|
|
265
|
+
"size": {"width_mm": 180, "height_mm": 120},
|
|
266
|
+
"background": "#ffffff",
|
|
281
267
|
},
|
|
282
268
|
},
|
|
283
|
-
|
|
269
|
+
"panels": [],
|
|
284
270
|
}
|
|
285
271
|
|
|
286
272
|
# Auto-layout panels
|
|
@@ -305,15 +291,17 @@ def _generate_figure_spec(panels):
|
|
|
305
291
|
x = margin + col * (panel_w + margin)
|
|
306
292
|
y = margin + row * (panel_h + margin)
|
|
307
293
|
|
|
308
|
-
# Note: save_bundle uses panel_id for the directory name (e.g., A.
|
|
309
|
-
spec[
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
294
|
+
# Note: save_bundle uses panel_id for the directory name (e.g., A.plot)
|
|
295
|
+
spec["panels"].append(
|
|
296
|
+
{
|
|
297
|
+
"id": panel_id,
|
|
298
|
+
"label": panel_id,
|
|
299
|
+
"caption": "",
|
|
300
|
+
"plot": f"{panel_id}.plot",
|
|
301
|
+
"position": {"x_mm": x, "y_mm": y},
|
|
302
|
+
"size": {"width_mm": panel_w, "height_mm": panel_h},
|
|
303
|
+
}
|
|
304
|
+
)
|
|
317
305
|
|
|
318
306
|
return spec
|
|
319
307
|
|
|
@@ -344,9 +332,9 @@ __all__ = [
|
|
|
344
332
|
"verify_data",
|
|
345
333
|
# Editor
|
|
346
334
|
"edit",
|
|
347
|
-
# .
|
|
348
|
-
"
|
|
349
|
-
"
|
|
335
|
+
# .figure bundle
|
|
336
|
+
"save_figure",
|
|
337
|
+
"load_figure",
|
|
350
338
|
]
|
|
351
339
|
|
|
352
340
|
# EOF
|
|
@@ -0,0 +1,372 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# Timestamp: 2026-01-08
|
|
3
|
+
# File: src/scitex/canvas/_mcp_handlers.py
|
|
4
|
+
# ----------------------------------------
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
MCP Handler implementations for SciTeX canvas module.
|
|
8
|
+
|
|
9
|
+
Provides async handlers for multi-panel figure composition.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from __future__ import annotations
|
|
13
|
+
|
|
14
|
+
import asyncio
|
|
15
|
+
from typing import Optional
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
async def create_canvas_handler(
|
|
19
|
+
parent_dir: str,
|
|
20
|
+
canvas_name: str,
|
|
21
|
+
width_mm: float = 180,
|
|
22
|
+
height_mm: float = 120,
|
|
23
|
+
) -> dict:
|
|
24
|
+
"""
|
|
25
|
+
Create a new canvas workspace.
|
|
26
|
+
|
|
27
|
+
Parameters
|
|
28
|
+
----------
|
|
29
|
+
parent_dir : str
|
|
30
|
+
Parent directory for canvas
|
|
31
|
+
canvas_name : str
|
|
32
|
+
Name for the canvas
|
|
33
|
+
width_mm : float
|
|
34
|
+
Canvas width in mm
|
|
35
|
+
height_mm : float
|
|
36
|
+
Canvas height in mm
|
|
37
|
+
|
|
38
|
+
Returns
|
|
39
|
+
-------
|
|
40
|
+
dict
|
|
41
|
+
Success status and canvas info
|
|
42
|
+
"""
|
|
43
|
+
try:
|
|
44
|
+
import scitex.canvas as canvas_module
|
|
45
|
+
|
|
46
|
+
loop = asyncio.get_event_loop()
|
|
47
|
+
await loop.run_in_executor(
|
|
48
|
+
None,
|
|
49
|
+
lambda: canvas_module.create_canvas(
|
|
50
|
+
parent_dir,
|
|
51
|
+
canvas_name,
|
|
52
|
+
),
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
canvas_path = canvas_module.get_canvas_path(parent_dir, canvas_name)
|
|
56
|
+
|
|
57
|
+
return {
|
|
58
|
+
"success": True,
|
|
59
|
+
"canvas_name": canvas_name,
|
|
60
|
+
"canvas_path": str(canvas_path),
|
|
61
|
+
"size_mm": {"width": width_mm, "height": height_mm},
|
|
62
|
+
"message": f"Created canvas '{canvas_name}' at {canvas_path}",
|
|
63
|
+
}
|
|
64
|
+
except Exception as e:
|
|
65
|
+
return {
|
|
66
|
+
"success": False,
|
|
67
|
+
"error": str(e),
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
async def add_panel_handler(
|
|
72
|
+
parent_dir: str,
|
|
73
|
+
canvas_name: str,
|
|
74
|
+
panel_name: str,
|
|
75
|
+
source: str,
|
|
76
|
+
x_mm: float = 0,
|
|
77
|
+
y_mm: float = 0,
|
|
78
|
+
width_mm: float = 50,
|
|
79
|
+
height_mm: float = 50,
|
|
80
|
+
label: Optional[str] = None,
|
|
81
|
+
) -> dict:
|
|
82
|
+
"""
|
|
83
|
+
Add a panel to a canvas.
|
|
84
|
+
|
|
85
|
+
Parameters
|
|
86
|
+
----------
|
|
87
|
+
parent_dir : str
|
|
88
|
+
Parent directory containing canvas
|
|
89
|
+
canvas_name : str
|
|
90
|
+
Canvas name
|
|
91
|
+
panel_name : str
|
|
92
|
+
Name for this panel
|
|
93
|
+
source : str
|
|
94
|
+
Path to source file
|
|
95
|
+
x_mm, y_mm : float
|
|
96
|
+
Position in mm
|
|
97
|
+
width_mm, height_mm : float
|
|
98
|
+
Size in mm
|
|
99
|
+
label : str, optional
|
|
100
|
+
Panel label (A, B, C...)
|
|
101
|
+
|
|
102
|
+
Returns
|
|
103
|
+
-------
|
|
104
|
+
dict
|
|
105
|
+
Success status and panel info
|
|
106
|
+
"""
|
|
107
|
+
try:
|
|
108
|
+
import scitex.canvas as canvas_module
|
|
109
|
+
|
|
110
|
+
loop = asyncio.get_event_loop()
|
|
111
|
+
await loop.run_in_executor(
|
|
112
|
+
None,
|
|
113
|
+
lambda: canvas_module.add_panel(
|
|
114
|
+
parent_dir=parent_dir,
|
|
115
|
+
canvas_name=canvas_name,
|
|
116
|
+
panel_name=panel_name,
|
|
117
|
+
source=source,
|
|
118
|
+
xy_mm=(x_mm, y_mm),
|
|
119
|
+
size_mm=(width_mm, height_mm),
|
|
120
|
+
label=label or "",
|
|
121
|
+
),
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
return {
|
|
125
|
+
"success": True,
|
|
126
|
+
"canvas_name": canvas_name,
|
|
127
|
+
"panel_name": panel_name,
|
|
128
|
+
"source": source,
|
|
129
|
+
"position_mm": {"x": x_mm, "y": y_mm},
|
|
130
|
+
"size_mm": {"width": width_mm, "height": height_mm},
|
|
131
|
+
"label": label,
|
|
132
|
+
"message": f"Added panel '{panel_name}' to canvas '{canvas_name}'",
|
|
133
|
+
}
|
|
134
|
+
except Exception as e:
|
|
135
|
+
return {
|
|
136
|
+
"success": False,
|
|
137
|
+
"error": str(e),
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
async def list_panels_handler(
|
|
142
|
+
parent_dir: str,
|
|
143
|
+
canvas_name: str,
|
|
144
|
+
) -> dict:
|
|
145
|
+
"""
|
|
146
|
+
List all panels in a canvas.
|
|
147
|
+
|
|
148
|
+
Parameters
|
|
149
|
+
----------
|
|
150
|
+
parent_dir : str
|
|
151
|
+
Parent directory
|
|
152
|
+
canvas_name : str
|
|
153
|
+
Canvas name
|
|
154
|
+
|
|
155
|
+
Returns
|
|
156
|
+
-------
|
|
157
|
+
dict
|
|
158
|
+
Success status and panel list
|
|
159
|
+
"""
|
|
160
|
+
try:
|
|
161
|
+
import scitex.canvas as canvas_module
|
|
162
|
+
|
|
163
|
+
loop = asyncio.get_event_loop()
|
|
164
|
+
panels = await loop.run_in_executor(
|
|
165
|
+
None,
|
|
166
|
+
lambda: canvas_module.list_panels(parent_dir, canvas_name),
|
|
167
|
+
)
|
|
168
|
+
|
|
169
|
+
return {
|
|
170
|
+
"success": True,
|
|
171
|
+
"canvas_name": canvas_name,
|
|
172
|
+
"count": len(panels) if panels else 0,
|
|
173
|
+
"panels": panels or [],
|
|
174
|
+
}
|
|
175
|
+
except Exception as e:
|
|
176
|
+
return {
|
|
177
|
+
"success": False,
|
|
178
|
+
"error": str(e),
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
async def remove_panel_handler(
|
|
183
|
+
parent_dir: str,
|
|
184
|
+
canvas_name: str,
|
|
185
|
+
panel_name: str,
|
|
186
|
+
) -> dict:
|
|
187
|
+
"""
|
|
188
|
+
Remove a panel from a canvas.
|
|
189
|
+
|
|
190
|
+
Parameters
|
|
191
|
+
----------
|
|
192
|
+
parent_dir : str
|
|
193
|
+
Parent directory
|
|
194
|
+
canvas_name : str
|
|
195
|
+
Canvas name
|
|
196
|
+
panel_name : str
|
|
197
|
+
Panel to remove
|
|
198
|
+
|
|
199
|
+
Returns
|
|
200
|
+
-------
|
|
201
|
+
dict
|
|
202
|
+
Success status
|
|
203
|
+
"""
|
|
204
|
+
try:
|
|
205
|
+
import scitex.canvas as canvas_module
|
|
206
|
+
|
|
207
|
+
loop = asyncio.get_event_loop()
|
|
208
|
+
await loop.run_in_executor(
|
|
209
|
+
None,
|
|
210
|
+
lambda: canvas_module.remove_panel(parent_dir, canvas_name, panel_name),
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
return {
|
|
214
|
+
"success": True,
|
|
215
|
+
"canvas_name": canvas_name,
|
|
216
|
+
"panel_name": panel_name,
|
|
217
|
+
"message": f"Removed panel '{panel_name}' from canvas '{canvas_name}'",
|
|
218
|
+
}
|
|
219
|
+
except Exception as e:
|
|
220
|
+
return {
|
|
221
|
+
"success": False,
|
|
222
|
+
"error": str(e),
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
async def export_canvas_handler(
|
|
227
|
+
parent_dir: str,
|
|
228
|
+
canvas_name: str,
|
|
229
|
+
output_path: Optional[str] = None,
|
|
230
|
+
format: Optional[str] = None,
|
|
231
|
+
dpi: int = 300,
|
|
232
|
+
) -> dict:
|
|
233
|
+
"""
|
|
234
|
+
Export canvas to file.
|
|
235
|
+
|
|
236
|
+
Parameters
|
|
237
|
+
----------
|
|
238
|
+
parent_dir : str
|
|
239
|
+
Parent directory
|
|
240
|
+
canvas_name : str
|
|
241
|
+
Canvas name
|
|
242
|
+
output_path : str, optional
|
|
243
|
+
Output file path
|
|
244
|
+
format : str, optional
|
|
245
|
+
Output format (png, pdf, svg)
|
|
246
|
+
dpi : int
|
|
247
|
+
Output DPI
|
|
248
|
+
|
|
249
|
+
Returns
|
|
250
|
+
-------
|
|
251
|
+
dict
|
|
252
|
+
Success status and output path
|
|
253
|
+
"""
|
|
254
|
+
try:
|
|
255
|
+
from pathlib import Path
|
|
256
|
+
|
|
257
|
+
import scitex.canvas as canvas_module
|
|
258
|
+
|
|
259
|
+
# Build output path if not provided
|
|
260
|
+
if output_path is None:
|
|
261
|
+
canvas_path = canvas_module.get_canvas_path(parent_dir, canvas_name)
|
|
262
|
+
fmt = format or "png"
|
|
263
|
+
output_path = str(Path(canvas_path) / "exports" / f"{canvas_name}.{fmt}")
|
|
264
|
+
|
|
265
|
+
loop = asyncio.get_event_loop()
|
|
266
|
+
result_path = await loop.run_in_executor(
|
|
267
|
+
None,
|
|
268
|
+
lambda: canvas_module.export_canvas(
|
|
269
|
+
parent_dir,
|
|
270
|
+
canvas_name,
|
|
271
|
+
output_path,
|
|
272
|
+
),
|
|
273
|
+
)
|
|
274
|
+
|
|
275
|
+
return {
|
|
276
|
+
"success": True,
|
|
277
|
+
"canvas_name": canvas_name,
|
|
278
|
+
"output_path": str(result_path) if result_path else output_path,
|
|
279
|
+
"format": format or Path(output_path).suffix.lstrip("."),
|
|
280
|
+
"dpi": dpi,
|
|
281
|
+
"message": f"Exported canvas to {output_path}",
|
|
282
|
+
}
|
|
283
|
+
except Exception as e:
|
|
284
|
+
return {
|
|
285
|
+
"success": False,
|
|
286
|
+
"error": str(e),
|
|
287
|
+
}
|
|
288
|
+
|
|
289
|
+
|
|
290
|
+
async def list_canvases_handler(parent_dir: str) -> dict:
|
|
291
|
+
"""
|
|
292
|
+
List all canvases in a directory.
|
|
293
|
+
|
|
294
|
+
Parameters
|
|
295
|
+
----------
|
|
296
|
+
parent_dir : str
|
|
297
|
+
Directory to search
|
|
298
|
+
|
|
299
|
+
Returns
|
|
300
|
+
-------
|
|
301
|
+
dict
|
|
302
|
+
Success status and canvas list
|
|
303
|
+
"""
|
|
304
|
+
try:
|
|
305
|
+
import scitex.canvas as canvas_module
|
|
306
|
+
|
|
307
|
+
loop = asyncio.get_event_loop()
|
|
308
|
+
canvases = await loop.run_in_executor(
|
|
309
|
+
None,
|
|
310
|
+
lambda: canvas_module.list_canvases(parent_dir),
|
|
311
|
+
)
|
|
312
|
+
|
|
313
|
+
return {
|
|
314
|
+
"success": True,
|
|
315
|
+
"parent_dir": parent_dir,
|
|
316
|
+
"count": len(canvases) if canvases else 0,
|
|
317
|
+
"canvases": canvases or [],
|
|
318
|
+
}
|
|
319
|
+
except Exception as e:
|
|
320
|
+
return {
|
|
321
|
+
"success": False,
|
|
322
|
+
"error": str(e),
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
|
|
326
|
+
async def canvas_exists_handler(
|
|
327
|
+
parent_dir: str,
|
|
328
|
+
canvas_name: str,
|
|
329
|
+
) -> dict:
|
|
330
|
+
"""
|
|
331
|
+
Check if a canvas exists.
|
|
332
|
+
|
|
333
|
+
Parameters
|
|
334
|
+
----------
|
|
335
|
+
parent_dir : str
|
|
336
|
+
Parent directory
|
|
337
|
+
canvas_name : str
|
|
338
|
+
Canvas name
|
|
339
|
+
|
|
340
|
+
Returns
|
|
341
|
+
-------
|
|
342
|
+
dict
|
|
343
|
+
Success status and existence flag
|
|
344
|
+
"""
|
|
345
|
+
try:
|
|
346
|
+
import scitex.canvas as canvas_module
|
|
347
|
+
|
|
348
|
+
exists = canvas_module.canvas_exists(parent_dir, canvas_name)
|
|
349
|
+
|
|
350
|
+
return {
|
|
351
|
+
"success": True,
|
|
352
|
+
"canvas_name": canvas_name,
|
|
353
|
+
"exists": exists,
|
|
354
|
+
}
|
|
355
|
+
except Exception as e:
|
|
356
|
+
return {
|
|
357
|
+
"success": False,
|
|
358
|
+
"error": str(e),
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
__all__ = [
|
|
363
|
+
"create_canvas_handler",
|
|
364
|
+
"add_panel_handler",
|
|
365
|
+
"list_panels_handler",
|
|
366
|
+
"remove_panel_handler",
|
|
367
|
+
"export_canvas_handler",
|
|
368
|
+
"list_canvases_handler",
|
|
369
|
+
"canvas_exists_handler",
|
|
370
|
+
]
|
|
371
|
+
|
|
372
|
+
# EOF
|