scitex 2.4.3__py3-none-any.whl → 2.7.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 +19 -8
- scitex/__main__.py +2 -1
- scitex/__version__.py +1 -1
- scitex/_optional_deps.py +13 -20
- scitex/ai/__init__.py +5 -0
- scitex/ai/_gen_ai/_Anthropic.py +3 -1
- scitex/ai/_gen_ai/_BaseGenAI.py +3 -2
- scitex/ai/_gen_ai/_DeepSeek.py +1 -1
- scitex/ai/_gen_ai/_Google.py +3 -2
- scitex/ai/_gen_ai/_Llama.py +4 -2
- scitex/ai/_gen_ai/_OpenAI.py +3 -1
- scitex/ai/_gen_ai/_PARAMS.py +1 -0
- scitex/ai/_gen_ai/_Perplexity.py +3 -1
- scitex/ai/_gen_ai/__init__.py +1 -0
- scitex/ai/_gen_ai/_format_output_func.py +3 -1
- scitex/ai/classification/CrossValidationExperiment.py +8 -14
- scitex/ai/classification/examples/timeseries_cv_demo.py +128 -112
- scitex/ai/classification/reporters/_BaseClassificationReporter.py +2 -0
- scitex/ai/classification/reporters/_ClassificationReporter.py +30 -45
- scitex/ai/classification/reporters/_MultiClassificationReporter.py +8 -11
- scitex/ai/classification/reporters/_SingleClassificationReporter.py +126 -182
- scitex/ai/classification/reporters/__init__.py +1 -1
- scitex/ai/classification/reporters/reporter_utils/_Plotter.py +213 -119
- scitex/ai/classification/reporters/reporter_utils/__init__.py +28 -36
- scitex/ai/classification/reporters/reporter_utils/aggregation.py +125 -143
- scitex/ai/classification/reporters/reporter_utils/data_models.py +128 -120
- scitex/ai/classification/reporters/reporter_utils/reporting.py +507 -340
- scitex/ai/classification/reporters/reporter_utils/storage.py +4 -1
- scitex/ai/classification/reporters/reporter_utils/validation.py +141 -154
- scitex/ai/classification/timeseries/_TimeSeriesBlockingSplit.py +204 -129
- scitex/ai/classification/timeseries/_TimeSeriesCalendarSplit.py +215 -171
- scitex/ai/classification/timeseries/_TimeSeriesMetadata.py +17 -17
- scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +67 -143
- scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit_v01-not-using-n_splits.py +67 -143
- scitex/ai/classification/timeseries/_TimeSeriesStrategy.py +12 -13
- scitex/ai/classification/timeseries/_TimeSeriesStratifiedSplit.py +231 -144
- scitex/ai/classification/timeseries/__init__.py +2 -4
- scitex/ai/classification/timeseries/_normalize_timestamp.py +3 -0
- scitex/ai/clustering/_pca.py +0 -1
- scitex/ai/clustering/_umap.py +1 -2
- scitex/ai/feature_extraction/__init__.py +10 -8
- scitex/ai/feature_extraction/vit.py +0 -1
- scitex/ai/feature_selection/feature_selection.py +3 -8
- scitex/ai/metrics/_calc_conf_mat.py +2 -0
- scitex/ai/metrics/_calc_feature_importance.py +3 -7
- scitex/ai/metrics/_calc_pre_rec_auc.py +5 -5
- scitex/ai/metrics/_calc_roc_auc.py +4 -2
- scitex/ai/metrics/_calc_seizure_prediction_metrics.py +35 -20
- scitex/ai/metrics/_calc_silhouette_score.py +1 -3
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger.py +0 -3
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger2020.py +0 -3
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger913A.py +0 -3
- scitex/ai/optim/_optimizers.py +1 -1
- scitex/ai/plt/__init__.py +6 -1
- scitex/ai/plt/_plot_feature_importance.py +1 -3
- scitex/ai/plt/_plot_learning_curve.py +9 -24
- scitex/ai/plt/_plot_optuna_study.py +4 -3
- scitex/ai/plt/_plot_pre_rec_curve.py +9 -15
- scitex/ai/plt/_plot_roc_curve.py +6 -8
- scitex/ai/plt/_stx_conf_mat.py +121 -122
- scitex/ai/sampling/undersample.py +3 -2
- scitex/ai/sklearn/__init__.py +2 -2
- scitex/ai/training/_LearningCurveLogger.py +23 -10
- scitex/ai/utils/_check_params.py +0 -1
- scitex/benchmark/__init__.py +15 -25
- scitex/benchmark/benchmark.py +124 -117
- scitex/benchmark/monitor.py +117 -107
- scitex/benchmark/profiler.py +61 -58
- scitex/bridge/__init__.py +110 -0
- scitex/bridge/_helpers.py +149 -0
- scitex/bridge/_plt_vis.py +529 -0
- scitex/bridge/_protocol.py +283 -0
- scitex/bridge/_stats_plt.py +261 -0
- scitex/bridge/_stats_vis.py +265 -0
- scitex/browser/__init__.py +0 -2
- scitex/browser/auth/__init__.py +0 -0
- scitex/browser/auth/google.py +16 -11
- scitex/browser/automation/CookieHandler.py +2 -3
- scitex/browser/collaboration/__init__.py +3 -0
- scitex/browser/collaboration/auth_helpers.py +3 -1
- scitex/browser/collaboration/collaborative_agent.py +2 -0
- scitex/browser/collaboration/interactive_panel.py +2 -2
- scitex/browser/collaboration/shared_session.py +20 -11
- scitex/browser/collaboration/standard_interactions.py +1 -0
- scitex/browser/core/BrowserMixin.py +12 -30
- scitex/browser/core/ChromeProfileManager.py +9 -24
- scitex/browser/debugging/_browser_logger.py +15 -25
- scitex/browser/debugging/_failure_capture.py +9 -2
- scitex/browser/debugging/_highlight_element.py +15 -6
- scitex/browser/debugging/_show_grid.py +5 -6
- scitex/browser/debugging/_sync_session.py +4 -3
- scitex/browser/debugging/_test_monitor.py +14 -5
- scitex/browser/debugging/_visual_cursor.py +46 -35
- scitex/browser/interaction/click_center.py +4 -3
- scitex/browser/interaction/click_with_fallbacks.py +7 -10
- scitex/browser/interaction/close_popups.py +79 -66
- scitex/browser/interaction/fill_with_fallbacks.py +8 -8
- scitex/browser/pdf/__init__.py +3 -1
- scitex/browser/pdf/click_download_for_chrome_pdf_viewer.py +11 -10
- scitex/browser/pdf/detect_chrome_pdf_viewer.py +3 -6
- scitex/browser/remote/CaptchaHandler.py +109 -96
- scitex/browser/remote/ZenRowsAPIClient.py +91 -97
- scitex/browser/remote/ZenRowsBrowserManager.py +138 -112
- scitex/browser/stealth/HumanBehavior.py +4 -9
- scitex/browser/stealth/StealthManager.py +11 -26
- scitex/capture/__init__.py +17 -17
- scitex/capture/__main__.py +2 -3
- scitex/capture/capture.py +23 -51
- scitex/capture/cli.py +14 -39
- scitex/capture/gif.py +5 -9
- scitex/capture/mcp_server.py +7 -20
- scitex/capture/session.py +4 -3
- scitex/capture/utils.py +18 -53
- scitex/cli/__init__.py +1 -1
- scitex/cli/cloud.py +158 -116
- scitex/cli/config.py +224 -0
- scitex/cli/main.py +41 -40
- scitex/cli/scholar.py +60 -27
- scitex/cli/security.py +14 -20
- scitex/cli/web.py +87 -90
- scitex/cli/writer.py +51 -45
- scitex/cloud/__init__.py +14 -11
- scitex/cloud/_matplotlib_hook.py +6 -6
- scitex/config/README.md +313 -0
- scitex/config/{PriorityConfig.py → _PriorityConfig.py} +114 -17
- scitex/config/_ScitexConfig.py +319 -0
- scitex/config/__init__.py +41 -9
- scitex/config/_paths.py +325 -0
- scitex/config/default.yaml +81 -0
- scitex/context/_suppress_output.py +2 -3
- scitex/db/_BaseMixins/_BaseBackupMixin.py +3 -1
- scitex/db/_BaseMixins/_BaseBatchMixin.py +3 -1
- scitex/db/_BaseMixins/_BaseBlobMixin.py +3 -1
- scitex/db/_BaseMixins/_BaseImportExportMixin.py +1 -3
- scitex/db/_BaseMixins/_BaseIndexMixin.py +3 -1
- scitex/db/_BaseMixins/_BaseMaintenanceMixin.py +1 -3
- scitex/db/_BaseMixins/_BaseQueryMixin.py +3 -1
- scitex/db/_BaseMixins/_BaseRowMixin.py +3 -1
- scitex/db/_BaseMixins/_BaseTableMixin.py +3 -1
- scitex/db/_BaseMixins/_BaseTransactionMixin.py +1 -3
- scitex/db/_BaseMixins/__init__.py +1 -1
- scitex/db/__init__.py +9 -1
- scitex/db/__main__.py +8 -21
- scitex/db/_check_health.py +15 -31
- scitex/db/_delete_duplicates.py +7 -4
- scitex/db/_inspect.py +22 -38
- scitex/db/_inspect_optimized.py +89 -85
- scitex/db/_postgresql/_PostgreSQL.py +0 -1
- scitex/db/_postgresql/_PostgreSQLMixins/_BlobMixin.py +3 -1
- scitex/db/_postgresql/_PostgreSQLMixins/_ConnectionMixin.py +1 -3
- scitex/db/_postgresql/_PostgreSQLMixins/_ImportExportMixin.py +1 -3
- scitex/db/_postgresql/_PostgreSQLMixins/_MaintenanceMixin.py +1 -4
- scitex/db/_postgresql/_PostgreSQLMixins/_QueryMixin.py +3 -3
- scitex/db/_postgresql/_PostgreSQLMixins/_RowMixin.py +3 -1
- scitex/db/_postgresql/_PostgreSQLMixins/_TransactionMixin.py +1 -3
- scitex/db/_postgresql/__init__.py +1 -1
- scitex/db/_sqlite3/_SQLite3.py +2 -4
- scitex/db/_sqlite3/_SQLite3Mixins/_ArrayMixin.py +11 -12
- scitex/db/_sqlite3/_SQLite3Mixins/_ArrayMixin_v01-need-_hash-col.py +19 -14
- scitex/db/_sqlite3/_SQLite3Mixins/_BatchMixin.py +3 -1
- scitex/db/_sqlite3/_SQLite3Mixins/_BlobMixin.py +7 -7
- scitex/db/_sqlite3/_SQLite3Mixins/_ColumnMixin.py +118 -111
- scitex/db/_sqlite3/_SQLite3Mixins/_ConnectionMixin.py +8 -10
- scitex/db/_sqlite3/_SQLite3Mixins/_GitMixin.py +17 -45
- scitex/db/_sqlite3/_SQLite3Mixins/_ImportExportMixin.py +1 -3
- scitex/db/_sqlite3/_SQLite3Mixins/_IndexMixin.py +3 -1
- scitex/db/_sqlite3/_SQLite3Mixins/_QueryMixin.py +3 -4
- scitex/db/_sqlite3/_SQLite3Mixins/_RowMixin.py +9 -9
- scitex/db/_sqlite3/_SQLite3Mixins/_TableMixin.py +18 -11
- scitex/db/_sqlite3/_SQLite3Mixins/__init__.py +1 -0
- scitex/db/_sqlite3/__init__.py +1 -1
- scitex/db/_sqlite3/_delete_duplicates.py +13 -11
- scitex/decorators/__init__.py +29 -4
- scitex/decorators/_auto_order.py +43 -43
- scitex/decorators/_batch_fn.py +12 -6
- scitex/decorators/_cache_disk.py +8 -9
- scitex/decorators/_cache_disk_async.py +8 -7
- scitex/decorators/_combined.py +19 -13
- scitex/decorators/_converters.py +16 -3
- scitex/decorators/_deprecated.py +32 -22
- scitex/decorators/_numpy_fn.py +18 -4
- scitex/decorators/_pandas_fn.py +17 -5
- scitex/decorators/_signal_fn.py +17 -3
- scitex/decorators/_torch_fn.py +32 -15
- scitex/decorators/_xarray_fn.py +23 -9
- scitex/dev/_analyze_code_flow.py +0 -2
- scitex/dict/_DotDict.py +15 -19
- scitex/dict/_flatten.py +1 -0
- scitex/dict/_listed_dict.py +1 -0
- scitex/dict/_pop_keys.py +1 -0
- scitex/dict/_replace.py +1 -0
- scitex/dict/_safe_merge.py +1 -0
- scitex/dict/_to_str.py +2 -3
- scitex/dsp/__init__.py +13 -4
- scitex/dsp/_crop.py +3 -1
- scitex/dsp/_detect_ripples.py +3 -1
- scitex/dsp/_modulation_index.py +3 -1
- scitex/dsp/_time.py +3 -1
- scitex/dsp/_wavelet.py +0 -1
- scitex/dsp/example.py +0 -5
- scitex/dsp/filt.py +4 -0
- scitex/dsp/utils/__init__.py +4 -1
- scitex/dsp/utils/pac.py +3 -3
- scitex/dt/_normalize_timestamp.py +4 -1
- scitex/errors.py +3 -6
- scitex/etc/__init__.py +1 -1
- scitex/gen/_DimHandler.py +6 -6
- scitex/gen/__init__.py +5 -1
- scitex/gen/_deprecated_close.py +1 -0
- scitex/gen/_deprecated_start.py +5 -3
- scitex/gen/_detect_environment.py +44 -41
- scitex/gen/_detect_notebook_path.py +51 -47
- scitex/gen/_embed.py +1 -1
- scitex/gen/_get_notebook_path.py +81 -62
- scitex/gen/_inspect_module.py +0 -1
- scitex/gen/_norm.py +16 -7
- scitex/gen/_norm_cache.py +78 -65
- scitex/gen/_print_config.py +0 -3
- scitex/gen/_src.py +2 -3
- scitex/gen/_title_case.py +3 -2
- scitex/gen/_to_even.py +8 -8
- scitex/gen/_transpose.py +3 -3
- scitex/gen/misc.py +0 -3
- scitex/gists/_SigMacro_processFigure_S.py +2 -2
- scitex/gists/_SigMacro_toBlue.py +2 -2
- scitex/gists/__init__.py +4 -1
- scitex/git/_branch.py +19 -11
- scitex/git/_clone.py +23 -15
- scitex/git/_commit.py +10 -12
- scitex/git/_init.py +15 -38
- scitex/git/_remote.py +9 -3
- scitex/git/_result.py +3 -0
- scitex/git/_retry.py +2 -5
- scitex/git/_types.py +4 -0
- scitex/git/_validation.py +8 -8
- scitex/git/_workflow.py +4 -4
- scitex/io/__init__.py +2 -1
- scitex/io/_glob.py +2 -2
- scitex/io/_json2md.py +3 -3
- scitex/io/_load.py +11 -8
- scitex/io/_load_cache.py +71 -71
- scitex/io/_load_configs.py +2 -3
- scitex/io/_load_modules/_H5Explorer.py +6 -12
- scitex/io/_load_modules/_ZarrExplorer.py +3 -3
- scitex/io/_load_modules/_bibtex.py +62 -63
- scitex/io/_load_modules/_canvas.py +166 -0
- scitex/io/_load_modules/_catboost.py +7 -2
- scitex/io/_load_modules/_hdf5.py +2 -0
- scitex/io/_load_modules/_image.py +5 -1
- scitex/io/_load_modules/_matlab.py +3 -1
- scitex/io/_load_modules/_optuna.py +0 -1
- scitex/io/_load_modules/_pdf.py +38 -29
- scitex/io/_load_modules/_sqlite3.py +1 -0
- scitex/io/_load_modules/_txt.py +2 -0
- scitex/io/_load_modules/_xml.py +9 -9
- scitex/io/_load_modules/_zarr.py +12 -10
- scitex/io/_metadata.py +76 -37
- scitex/io/_qr_utils.py +18 -13
- scitex/io/_save.py +228 -63
- scitex/io/_save_modules/__init__.py +7 -2
- scitex/io/_save_modules/_bibtex.py +66 -61
- scitex/io/_save_modules/_canvas.py +355 -0
- scitex/io/_save_modules/_catboost.py +2 -2
- scitex/io/_save_modules/_csv.py +4 -4
- scitex/io/_save_modules/_excel.py +5 -9
- scitex/io/_save_modules/_hdf5.py +9 -21
- scitex/io/_save_modules/_html.py +5 -5
- scitex/io/_save_modules/_image.py +105 -8
- scitex/io/_save_modules/_joblib.py +2 -2
- scitex/io/_save_modules/_json.py +51 -6
- scitex/io/_save_modules/_listed_dfs_as_csv.py +2 -1
- scitex/io/_save_modules/_listed_scalars_as_csv.py +2 -1
- scitex/io/_save_modules/_matlab.py +2 -2
- scitex/io/_save_modules/_numpy.py +6 -8
- scitex/io/_save_modules/_pickle.py +4 -4
- scitex/io/_save_modules/_plotly.py +3 -3
- scitex/io/_save_modules/_tex.py +23 -25
- scitex/io/_save_modules/_text.py +2 -2
- scitex/io/_save_modules/_yaml.py +9 -9
- scitex/io/_save_modules/_zarr.py +15 -15
- scitex/io/utils/__init__.py +2 -1
- scitex/io/utils/h5_to_zarr.py +173 -155
- scitex/linalg/__init__.py +1 -1
- scitex/linalg/_geometric_median.py +4 -3
- scitex/logging/_Tee.py +5 -7
- scitex/logging/__init__.py +18 -19
- scitex/logging/_config.py +4 -1
- scitex/logging/_context.py +6 -5
- scitex/logging/_formatters.py +2 -3
- scitex/logging/_handlers.py +19 -20
- scitex/logging/_levels.py +9 -17
- scitex/logging/_logger.py +74 -15
- scitex/logging/_print_capture.py +17 -17
- scitex/nn/_BNet.py +1 -3
- scitex/nn/_Filters.py +6 -2
- scitex/nn/_ModulationIndex.py +3 -1
- scitex/nn/_PAC.py +3 -2
- scitex/nn/_PSD.py +0 -1
- scitex/nn/__init__.py +16 -3
- scitex/path/_clean.py +10 -8
- scitex/path/_find.py +1 -1
- scitex/path/_get_spath.py +1 -2
- scitex/path/_mk_spath.py +1 -1
- scitex/path/_symlink.py +5 -10
- scitex/pd/__init__.py +4 -1
- scitex/pd/_force_df.py +24 -24
- scitex/pd/_get_unique.py +1 -0
- scitex/pd/_merge_columns.py +1 -1
- scitex/pd/_round.py +11 -7
- scitex/pd/_to_xy.py +0 -1
- scitex/plt/REQUESTS.md +191 -0
- scitex/plt/__init__.py +185 -87
- scitex/plt/_subplots/_AxesWrapper.py +22 -6
- scitex/plt/_subplots/_AxisWrapper.py +100 -39
- scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin.py +74 -52
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin.py +183 -73
- scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin.py +61 -45
- scitex/plt/_subplots/_AxisWrapperMixins/_TrackingMixin.py +26 -14
- scitex/plt/_subplots/_AxisWrapperMixins/_UnitAwareMixin.py +80 -73
- scitex/plt/_subplots/_FigWrapper.py +93 -60
- scitex/plt/_subplots/_SubplotsWrapper.py +135 -68
- scitex/plt/_subplots/__init__.py +10 -0
- scitex/plt/_subplots/_export_as_csv.py +89 -47
- scitex/plt/_subplots/_export_as_csv_formatters/__init__.py +1 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_annotate.py +6 -4
- scitex/plt/_subplots/_export_as_csv_formatters/_format_bar.py +88 -38
- scitex/plt/_subplots/_export_as_csv_formatters/_format_barh.py +25 -31
- scitex/plt/_subplots/_export_as_csv_formatters/_format_boxplot.py +53 -23
- scitex/plt/_subplots/_export_as_csv_formatters/_format_contour.py +38 -25
- scitex/plt/_subplots/_export_as_csv_formatters/_format_contourf.py +17 -9
- scitex/plt/_subplots/_export_as_csv_formatters/_format_errorbar.py +70 -124
- scitex/plt/_subplots/_export_as_csv_formatters/_format_eventplot.py +12 -10
- scitex/plt/_subplots/_export_as_csv_formatters/_format_fill.py +31 -17
- scitex/plt/_subplots/_export_as_csv_formatters/_format_fill_between.py +33 -21
- scitex/plt/_subplots/_export_as_csv_formatters/_format_hexbin.py +14 -4
- scitex/plt/_subplots/_export_as_csv_formatters/_format_hist.py +43 -29
- scitex/plt/_subplots/_export_as_csv_formatters/_format_hist2d.py +14 -4
- scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow.py +27 -11
- scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow2d.py +7 -5
- scitex/plt/_subplots/_export_as_csv_formatters/_format_matshow.py +9 -7
- scitex/plt/_subplots/_export_as_csv_formatters/_format_pie.py +15 -6
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot.py +128 -34
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_box.py +52 -27
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_imshow.py +1 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_kde.py +16 -17
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter.py +7 -5
- scitex/plt/_subplots/_export_as_csv_formatters/_format_quiver.py +10 -8
- scitex/plt/_subplots/_export_as_csv_formatters/_format_scatter.py +17 -6
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_barplot.py +43 -26
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_boxplot.py +68 -47
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_heatmap.py +52 -64
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_histplot.py +55 -50
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_jointplot.py +9 -11
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_kdeplot.py +63 -29
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_lineplot.py +4 -4
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_pairplot.py +6 -4
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_scatterplot.py +44 -40
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_stripplot.py +46 -39
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_swarmplot.py +46 -39
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_violinplot.py +75 -94
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stem.py +12 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_step.py +12 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_streamplot.py +10 -8
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_conf_mat.py +17 -15
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_ecdf.py +10 -9
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_fillv.py +35 -31
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_heatmap.py +18 -18
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_image.py +24 -18
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_joyplot.py +9 -7
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_line.py +34 -23
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_mean_ci.py +15 -13
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_mean_std.py +12 -10
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_median_iqr.py +15 -13
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_raster.py +11 -9
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_rectangle.py +84 -56
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_scatter_hist.py +35 -32
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_shaded_line.py +46 -30
- scitex/plt/_subplots/_export_as_csv_formatters/_format_stx_violin.py +51 -51
- scitex/plt/_subplots/_export_as_csv_formatters/_format_text.py +32 -31
- scitex/plt/_subplots/_export_as_csv_formatters/_format_violin.py +34 -31
- scitex/plt/_subplots/_export_as_csv_formatters/_format_violinplot.py +44 -37
- scitex/plt/_subplots/_export_as_csv_formatters/verify_formatters.py +91 -74
- scitex/plt/_tpl.py +6 -5
- scitex/plt/ax/_plot/__init__.py +24 -0
- scitex/plt/ax/_plot/_add_fitted_line.py +12 -11
- scitex/plt/ax/_plot/_plot_circular_hist.py +3 -1
- scitex/plt/ax/_plot/_plot_statistical_shaded_line.py +25 -19
- scitex/plt/ax/_plot/_stx_conf_mat.py +6 -3
- scitex/plt/ax/_plot/_stx_ecdf.py +5 -3
- scitex/plt/ax/_plot/_stx_fillv.py +4 -2
- scitex/plt/ax/_plot/_stx_heatmap.py +7 -4
- scitex/plt/ax/_plot/_stx_image.py +7 -5
- scitex/plt/ax/_plot/_stx_joyplot.py +32 -10
- scitex/plt/ax/_plot/_stx_raster.py +26 -11
- scitex/plt/ax/_plot/_stx_rectangle.py +2 -2
- scitex/plt/ax/_plot/_stx_shaded_line.py +15 -11
- scitex/plt/ax/_plot/_stx_violin.py +3 -1
- scitex/plt/ax/_style/_add_marginal_ax.py +6 -4
- scitex/plt/ax/_style/_auto_scale_axis.py +14 -10
- scitex/plt/ax/_style/_extend.py +3 -1
- scitex/plt/ax/_style/_force_aspect.py +5 -3
- scitex/plt/ax/_style/_format_units.py +2 -2
- scitex/plt/ax/_style/_hide_spines.py +5 -1
- scitex/plt/ax/_style/_map_ticks.py +5 -3
- scitex/plt/ax/_style/_rotate_labels.py +5 -4
- scitex/plt/ax/_style/_rotate_labels_v01.py +73 -63
- scitex/plt/ax/_style/_set_log_scale.py +120 -85
- scitex/plt/ax/_style/_set_meta.py +99 -76
- scitex/plt/ax/_style/_set_supxyt.py +33 -16
- scitex/plt/ax/_style/_set_xyt.py +27 -18
- scitex/plt/ax/_style/_share_axes.py +15 -5
- scitex/plt/ax/_style/_show_spines.py +58 -57
- scitex/plt/ax/_style/_style_barplot.py +1 -1
- scitex/plt/ax/_style/_style_boxplot.py +25 -14
- scitex/plt/ax/_style/_style_errorbar.py +0 -0
- scitex/plt/ax/_style/_style_scatter.py +1 -1
- scitex/plt/ax/_style/_style_suptitles.py +3 -3
- scitex/plt/ax/_style/_style_violinplot.py +8 -2
- scitex/plt/color/__init__.py +34 -2
- scitex/plt/color/_add_hue_col.py +1 -0
- scitex/plt/color/_colors.py +0 -1
- scitex/plt/color/_get_colors_from_conf_matap.py +3 -1
- scitex/plt/color/_vizualize_colors.py +0 -1
- scitex/plt/docs/FIGURE_ARCHITECTURE.md +315 -0
- scitex/plt/gallery/README.md +75 -0
- scitex/plt/gallery/__init__.py +29 -0
- scitex/plt/gallery/_generate.py +153 -0
- scitex/plt/gallery/_plots.py +594 -0
- scitex/plt/gallery/_registry.py +153 -0
- scitex/plt/styles/__init__.py +9 -9
- scitex/plt/styles/_plot_defaults.py +62 -61
- scitex/plt/styles/_plot_postprocess.py +126 -77
- scitex/plt/styles/_style_loader.py +0 -0
- scitex/plt/styles/presets.py +43 -18
- scitex/plt/templates/research-master/scitex/vis/gallery/area/fill_between.json +110 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/area/fill_betweenx.json +88 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/area/stx_fill_between.json +103 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/area/stx_fillv.json +106 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/bar.json +92 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/barh.json +92 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/boxplot.json +92 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_bar.json +84 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_barh.json +84 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_box.json +83 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_boxplot.json +93 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_violin.json +91 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/stx_violinplot.json +91 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/categorical/violinplot.json +91 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/contour/contour.json +97 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/contour/contourf.json +98 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/contour/stx_contour.json +84 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/distribution/hist.json +101 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/distribution/hist2d.json +96 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/distribution/stx_ecdf.json +95 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/distribution/stx_joyplot.json +95 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/distribution/stx_kde.json +93 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/grid/imshow.json +95 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/grid/matshow.json +95 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_conf_mat.json +83 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_heatmap.json +92 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_image.json +121 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/grid/stx_imshow.json +84 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/line/plot.json +110 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/line/step.json +92 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/line/stx_line.json +95 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/line/stx_shaded_line.json +96 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/scatter/hexbin.json +95 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/scatter/scatter.json +95 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/scatter/stem.json +92 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/scatter/stx_scatter.json +84 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/special/pie.json +94 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/special/stx_raster.json +109 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/special/stx_rectangle.json +108 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/statistical/errorbar.json +93 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_errorbar.json +84 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_mean_ci.json +96 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_mean_std.json +96 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/statistical/stx_median_iqr.json +96 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/vector/quiver.json +99 -0
- scitex/plt/templates/research-master/scitex/vis/gallery/vector/streamplot.json +100 -0
- scitex/plt/utils/__init__.py +39 -2
- scitex/plt/utils/_close.py +8 -3
- scitex/plt/utils/_collect_figure_metadata.py +3033 -265
- scitex/plt/utils/_colorbar.py +15 -17
- scitex/plt/utils/_configure_mpl.py +22 -14
- scitex/plt/utils/_crop.py +60 -27
- scitex/plt/utils/_csv_column_naming.py +288 -0
- scitex/plt/utils/_dimension_viewer.py +7 -19
- scitex/plt/utils/_figure_from_axes_mm.py +70 -16
- scitex/plt/utils/_figure_mm.py +3 -2
- scitex/plt/utils/_get_actual_font.py +5 -4
- scitex/plt/utils/_histogram_utils.py +52 -48
- scitex/plt/utils/_is_valid_axis.py +19 -13
- scitex/plt/utils/_mk_colorbar.py +3 -3
- scitex/plt/utils/_scientific_captions.py +202 -139
- scitex/plt/utils/_scitex_config.py +98 -98
- scitex/plt/utils/_units.py +0 -0
- scitex/plt/utils/metadata/__init__.py +36 -0
- scitex/plt/utils/metadata/_artist_extraction.py +119 -0
- scitex/plt/utils/metadata/_axes_metadata.py +93 -0
- scitex/plt/utils/metadata/_collection_artists.py +292 -0
- scitex/plt/utils/metadata/_core.py +208 -0
- scitex/plt/utils/metadata/_csv_column_extraction.py +186 -0
- scitex/plt/utils/metadata/_csv_hash.py +115 -0
- scitex/plt/utils/metadata/_csv_verification.py +95 -0
- scitex/plt/utils/metadata/_data_linkage.py +263 -0
- scitex/plt/utils/metadata/_dimensions.py +239 -0
- scitex/plt/utils/metadata/_figure_metadata.py +58 -0
- scitex/plt/utils/metadata/_image_text_artists.py +168 -0
- scitex/plt/utils/metadata/_label_parsing.py +82 -0
- scitex/plt/utils/metadata/_legend_extraction.py +120 -0
- scitex/plt/utils/metadata/_line_artists.py +367 -0
- scitex/plt/utils/metadata/_line_semantic_handling.py +173 -0
- scitex/plt/utils/metadata/_patch_artists.py +211 -0
- scitex/plt/utils/metadata/_plot_content.py +26 -0
- scitex/plt/utils/metadata/_plot_type_detection.py +184 -0
- scitex/plt/utils/metadata/_precision.py +134 -0
- scitex/plt/utils/metadata/_precision_config.py +68 -0
- scitex/plt/utils/metadata/_precision_sections.py +211 -0
- scitex/plt/utils/metadata/_recipe_extraction.py +267 -0
- scitex/plt/utils/metadata/_style_parsing.py +174 -0
- scitex/repro/_RandomStateManager.py +33 -38
- scitex/repro/__init__.py +16 -7
- scitex/repro/_gen_ID.py +7 -9
- scitex/repro/_gen_timestamp.py +7 -6
- scitex/repro/_hash_array.py +8 -12
- scitex/reproduce/__init__.py +1 -1
- scitex/resource/_get_processor_usages.py +3 -1
- scitex/resource/_log_processor_usages.py +3 -1
- scitex/rng/__init__.py +1 -1
- scitex/schema/README.md +178 -0
- scitex/schema/__init__.py +144 -0
- scitex/schema/_canvas.py +444 -0
- scitex/schema/_stats.py +762 -0
- scitex/schema/_validation.py +590 -0
- scitex/scholar/.legacy/Scholar.py +5 -12
- scitex/scholar/.legacy/_Scholar.py +66 -99
- scitex/scholar/.legacy/_ScholarAPI.py +75 -66
- scitex/scholar/.legacy/_tmp/search_engine/_BaseSearchEngine.py +3 -3
- scitex/scholar/.legacy/_tmp/search_engine/_UnifiedSearcher.py +4 -9
- scitex/scholar/.legacy/_tmp/search_engine/__init__.py +14 -21
- scitex/scholar/.legacy/_tmp/search_engine/local/_LocalSearchEngine.py +40 -37
- scitex/scholar/.legacy/_tmp/search_engine/local/_VectorSearchEngine.py +31 -28
- scitex/scholar/.legacy/_tmp/search_engine/web/_ArxivSearchEngine.py +74 -65
- scitex/scholar/.legacy/_tmp/search_engine/web/_CrossRefSearchEngine.py +122 -116
- scitex/scholar/.legacy/_tmp/search_engine/web/_GoogleScholarSearchEngine.py +65 -59
- scitex/scholar/.legacy/_tmp/search_engine/web/_PubMedSearchEngine.py +121 -107
- scitex/scholar/.legacy/_tmp/search_engine/web/_SemanticScholarSearchEngine.py +5 -12
- scitex/scholar/.legacy/database/_DatabaseEntry.py +49 -45
- scitex/scholar/.legacy/database/_DatabaseIndex.py +131 -94
- scitex/scholar/.legacy/database/_LibraryManager.py +65 -63
- scitex/scholar/.legacy/database/_PaperDatabase.py +138 -124
- scitex/scholar/.legacy/database/_ScholarDatabaseIntegration.py +14 -36
- scitex/scholar/.legacy/database/_StorageIntegratedDB.py +192 -156
- scitex/scholar/.legacy/database/_ZoteroCompatibleDB.py +300 -237
- scitex/scholar/.legacy/database/__init__.py +2 -1
- scitex/scholar/.legacy/database/manage.py +92 -84
- scitex/scholar/.legacy/lookup/_LookupIndex.py +157 -101
- scitex/scholar/.legacy/lookup/__init__.py +2 -1
- scitex/scholar/.legacy/metadata/doi/batch/_MetadataHandlerForBatchDOIResolution.py +4 -9
- scitex/scholar/.legacy/metadata/doi/batch/_ProgressManagerForBatchDOIResolution.py +10 -23
- scitex/scholar/.legacy/metadata/doi/batch/_SourceStatsManagerForBatchDOIResolution.py +4 -9
- scitex/scholar/.legacy/metadata/doi/batch/__init__.py +3 -1
- scitex/scholar/.legacy/metadata/doi/resolvers/_BatchDOIResolver.py +10 -25
- scitex/scholar/.legacy/metadata/doi/resolvers/_BibTeXDOIResolver.py +19 -49
- scitex/scholar/.legacy/metadata/doi/resolvers/_DOIResolver.py +1 -0
- scitex/scholar/.legacy/metadata/doi/resolvers/_SingleDOIResolver.py +8 -20
- scitex/scholar/.legacy/metadata/doi/sources/.combined-SemanticScholarSource/_SemanticScholarSource.py +37 -35
- scitex/scholar/.legacy/metadata/doi/sources/.combined-SemanticScholarSource/_SemanticScholarSourceEnhanced.py +49 -37
- scitex/scholar/.legacy/metadata/doi/sources/_ArXivSource.py +11 -30
- scitex/scholar/.legacy/metadata/doi/sources/_BaseDOISource.py +19 -47
- scitex/scholar/.legacy/metadata/doi/sources/_CrossRefLocalSource.py +1 -0
- scitex/scholar/.legacy/metadata/doi/sources/_CrossRefSource.py +12 -33
- scitex/scholar/.legacy/metadata/doi/sources/_OpenAlexSource.py +8 -20
- scitex/scholar/.legacy/metadata/doi/sources/_PubMedSource.py +10 -27
- scitex/scholar/.legacy/metadata/doi/sources/_SemanticScholarSource.py +11 -29
- scitex/scholar/.legacy/metadata/doi/sources/_SourceManager.py +8 -21
- scitex/scholar/.legacy/metadata/doi/sources/_SourceResolutionStrategy.py +24 -55
- scitex/scholar/.legacy/metadata/doi/sources/_SourceRotationManager.py +8 -21
- scitex/scholar/.legacy/metadata/doi/sources/_URLDOISource.py +9 -16
- scitex/scholar/.legacy/metadata/doi/sources/_UnifiedSource.py +8 -22
- scitex/scholar/.legacy/metadata/doi/sources/__init__.py +1 -0
- scitex/scholar/.legacy/metadata/doi/utils/_PubMedConverter.py +4 -8
- scitex/scholar/.legacy/metadata/doi/utils/_RateLimitHandler.py +17 -43
- scitex/scholar/.legacy/metadata/doi/utils/_TextNormalizer.py +8 -18
- scitex/scholar/.legacy/metadata/doi/utils/_URLDOIExtractor.py +4 -8
- scitex/scholar/.legacy/metadata/doi/utils/__init__.py +1 -0
- scitex/scholar/.legacy/metadata/doi/utils/_to_complete_metadata_structure.py +1 -0
- scitex/scholar/.legacy/metadata/enrichment/_LibraryEnricher.py +2 -3
- scitex/scholar/.legacy/metadata/enrichment/enrichers/_ImpactFactorEnricher.py +6 -12
- scitex/scholar/.legacy/metadata/enrichment/enrichers/_SmartEnricher.py +5 -10
- scitex/scholar/.legacy/metadata/enrichment/sources/_UnifiedMetadataSource.py +4 -5
- scitex/scholar/.legacy/metadata/query_to_full_meta_json.py +8 -12
- scitex/scholar/.legacy/metadata/urls/_URLMetadataHandler.py +3 -3
- scitex/scholar/.legacy/metadata/urls/_ZoteroTranslatorRunner.py +15 -21
- scitex/scholar/.legacy/metadata/urls/__init__.py +3 -3
- scitex/scholar/.legacy/metadata/urls/_finder.py +4 -6
- scitex/scholar/.legacy/metadata/urls/_handler.py +7 -15
- scitex/scholar/.legacy/metadata/urls/_resolver.py +6 -12
- scitex/scholar/.legacy/search/_Embedder.py +74 -69
- scitex/scholar/.legacy/search/_SemanticSearch.py +91 -90
- scitex/scholar/.legacy/search/_SemanticSearchEngine.py +104 -109
- scitex/scholar/.legacy/search/_UnifiedSearcher.py +530 -471
- scitex/scholar/.legacy/search/_VectorDatabase.py +111 -92
- scitex/scholar/.legacy/search/__init__.py +1 -0
- scitex/scholar/.legacy/storage/_EnhancedStorageManager.py +182 -154
- scitex/scholar/.legacy/storage/__init__.py +2 -1
- scitex/scholar/__init__.py +0 -2
- scitex/scholar/__main__.py +1 -3
- scitex/scholar/auth/ScholarAuthManager.py +13 -36
- scitex/scholar/auth/core/AuthenticationGateway.py +15 -29
- scitex/scholar/auth/core/BrowserAuthenticator.py +22 -57
- scitex/scholar/auth/core/StrategyResolver.py +10 -27
- scitex/scholar/auth/core/__init__.py +5 -1
- scitex/scholar/auth/gateway/_OpenURLLinkFinder.py +11 -21
- scitex/scholar/auth/gateway/_OpenURLResolver.py +10 -18
- scitex/scholar/auth/gateway/_resolve_functions.py +3 -3
- scitex/scholar/auth/providers/BaseAuthenticator.py +1 -0
- scitex/scholar/auth/providers/EZProxyAuthenticator.py +7 -14
- scitex/scholar/auth/providers/OpenAthensAuthenticator.py +29 -57
- scitex/scholar/auth/providers/ShibbolethAuthenticator.py +87 -73
- scitex/scholar/auth/session/AuthCacheManager.py +12 -22
- scitex/scholar/auth/session/SessionManager.py +4 -6
- scitex/scholar/auth/sso/BaseSSOAutomator.py +13 -19
- scitex/scholar/auth/sso/OpenAthensSSOAutomator.py +16 -45
- scitex/scholar/auth/sso/SSOAutomator.py +8 -15
- scitex/scholar/auth/sso/UniversityOfMelbourneSSOAutomator.py +13 -23
- scitex/scholar/browser/ScholarBrowserManager.py +31 -56
- scitex/scholar/browser/__init__.py +1 -0
- scitex/scholar/browser/utils/click_and_wait.py +3 -4
- scitex/scholar/browser/utils/close_unwanted_pages.py +4 -7
- scitex/scholar/browser/utils/wait_redirects.py +15 -40
- scitex/scholar/citation_graph/__init__.py +0 -0
- scitex/scholar/citation_graph/builder.py +3 -7
- scitex/scholar/citation_graph/database.py +4 -11
- scitex/scholar/citation_graph/example.py +5 -10
- scitex/scholar/citation_graph/models.py +0 -0
- scitex/scholar/cli/_url_utils.py +1 -1
- scitex/scholar/cli/chrome.py +5 -3
- scitex/scholar/cli/download_pdf.py +13 -14
- scitex/scholar/cli/handlers/bibtex_handler.py +4 -12
- scitex/scholar/cli/handlers/doi_handler.py +1 -3
- scitex/scholar/cli/handlers/project_handler.py +6 -20
- scitex/scholar/cli/open_browser.py +41 -39
- scitex/scholar/cli/open_browser_auto.py +31 -39
- scitex/scholar/cli/open_browser_monitored.py +27 -24
- scitex/scholar/config/ScholarConfig.py +5 -8
- scitex/scholar/config/__init__.py +1 -0
- scitex/scholar/config/core/_CascadeConfig.py +3 -3
- scitex/scholar/config/core/_PathManager.py +16 -28
- scitex/scholar/core/Paper.py +79 -78
- scitex/scholar/core/Papers.py +16 -27
- scitex/scholar/core/Scholar.py +98 -229
- scitex/scholar/core/journal_normalizer.py +52 -49
- scitex/scholar/core/oa_cache.py +27 -23
- scitex/scholar/core/open_access.py +17 -8
- scitex/scholar/docs/template.py +4 -3
- scitex/scholar/docs/to_claude/examples/example-python-project-scitex/scripts/mnist/clf_svm.py +0 -0
- scitex/scholar/docs/to_claude/examples/example-python-project-scitex/scripts/mnist/download.py +0 -0
- scitex/scholar/docs/to_claude/examples/example-python-project-scitex/scripts/mnist/plot_conf_mat.py +0 -0
- scitex/scholar/docs/to_claude/examples/example-python-project-scitex/scripts/mnist/plot_digits.py +0 -0
- scitex/scholar/docs/to_claude/examples/example-python-project-scitex/scripts/mnist/plot_umap_space.py +0 -0
- scitex/scholar/examples/00_config.py +10 -9
- scitex/scholar/examples/01_auth.py +3 -0
- scitex/scholar/examples/02_browser.py +14 -10
- scitex/scholar/examples/03_01-engine.py +3 -0
- scitex/scholar/examples/03_02-engine-for-bibtex.py +4 -3
- scitex/scholar/examples/04_01-url.py +9 -9
- scitex/scholar/examples/04_02-url-for-bibtex.py +7 -3
- scitex/scholar/examples/04_02-url-for-dois.py +87 -97
- scitex/scholar/examples/05_download_pdf.py +10 -4
- scitex/scholar/examples/06_find_and_download.py +6 -6
- scitex/scholar/examples/06_parse_bibtex.py +17 -17
- scitex/scholar/examples/07_storage_integration.py +6 -9
- scitex/scholar/examples/99_fullpipeline-for-bibtex.py +14 -15
- scitex/scholar/examples/99_fullpipeline-for-one-entry.py +31 -23
- scitex/scholar/examples/99_maintenance.py +3 -0
- scitex/scholar/examples/dev.py +2 -3
- scitex/scholar/examples/zotero_integration.py +11 -18
- scitex/scholar/impact_factor/ImpactFactorEngine.py +7 -9
- scitex/scholar/impact_factor/estimation/__init__.py +4 -4
- scitex/scholar/impact_factor/estimation/core/__init__.py +3 -7
- scitex/scholar/impact_factor/estimation/core/cache_manager.py +223 -211
- scitex/scholar/impact_factor/estimation/core/calculator.py +165 -131
- scitex/scholar/impact_factor/estimation/core/journal_matcher.py +217 -172
- scitex/scholar/impact_factor/jcr/ImpactFactorJCREngine.py +6 -14
- scitex/scholar/impact_factor/jcr/build_database.py +4 -3
- scitex/scholar/integration/base.py +9 -17
- scitex/scholar/integration/mendeley/exporter.py +2 -4
- scitex/scholar/integration/mendeley/importer.py +3 -3
- scitex/scholar/integration/mendeley/linker.py +3 -3
- scitex/scholar/integration/mendeley/mapper.py +9 -6
- scitex/scholar/integration/zotero/__main__.py +26 -43
- scitex/scholar/integration/zotero/exporter.py +15 -11
- scitex/scholar/integration/zotero/importer.py +12 -10
- scitex/scholar/integration/zotero/linker.py +8 -12
- scitex/scholar/integration/zotero/mapper.py +17 -12
- scitex/scholar/metadata_engines/.combined-SemanticScholarSource/_SemanticScholarSource.py +37 -35
- scitex/scholar/metadata_engines/.combined-SemanticScholarSource/_SemanticScholarSourceEnhanced.py +47 -35
- scitex/scholar/metadata_engines/ScholarEngine.py +21 -43
- scitex/scholar/metadata_engines/__init__.py +1 -0
- scitex/scholar/metadata_engines/individual/ArXivEngine.py +15 -37
- scitex/scholar/metadata_engines/individual/CrossRefEngine.py +15 -42
- scitex/scholar/metadata_engines/individual/CrossRefLocalEngine.py +24 -45
- scitex/scholar/metadata_engines/individual/OpenAlexEngine.py +11 -21
- scitex/scholar/metadata_engines/individual/PubMedEngine.py +10 -27
- scitex/scholar/metadata_engines/individual/SemanticScholarEngine.py +28 -35
- scitex/scholar/metadata_engines/individual/URLDOIEngine.py +11 -22
- scitex/scholar/metadata_engines/individual/_BaseDOIEngine.py +20 -49
- scitex/scholar/metadata_engines/utils/_PubMedConverter.py +4 -8
- scitex/scholar/metadata_engines/utils/_URLDOIExtractor.py +5 -10
- scitex/scholar/metadata_engines/utils/__init__.py +2 -0
- scitex/scholar/metadata_engines/utils/_metadata2bibtex.py +3 -0
- scitex/scholar/metadata_engines/utils/_standardize_metadata.py +2 -3
- scitex/scholar/pdf_download/ScholarPDFDownloader.py +25 -37
- scitex/scholar/pdf_download/strategies/chrome_pdf_viewer.py +11 -19
- scitex/scholar/pdf_download/strategies/direct_download.py +5 -9
- scitex/scholar/pdf_download/strategies/manual_download_fallback.py +3 -3
- scitex/scholar/pdf_download/strategies/manual_download_utils.py +6 -13
- scitex/scholar/pdf_download/strategies/open_access_download.py +49 -31
- scitex/scholar/pdf_download/strategies/response_body.py +8 -19
- scitex/scholar/pipelines/ScholarPipelineBibTeX.py +9 -18
- scitex/scholar/pipelines/ScholarPipelineMetadataParallel.py +25 -26
- scitex/scholar/pipelines/ScholarPipelineMetadataSingle.py +62 -23
- scitex/scholar/pipelines/ScholarPipelineParallel.py +13 -30
- scitex/scholar/pipelines/ScholarPipelineSearchParallel.py +299 -220
- scitex/scholar/pipelines/ScholarPipelineSearchSingle.py +202 -165
- scitex/scholar/pipelines/ScholarPipelineSingle.py +25 -51
- scitex/scholar/pipelines/SearchQueryParser.py +55 -55
- scitex/scholar/search_engines/ScholarSearchEngine.py +31 -27
- scitex/scholar/search_engines/_BaseSearchEngine.py +20 -23
- scitex/scholar/search_engines/individual/ArXivSearchEngine.py +53 -35
- scitex/scholar/search_engines/individual/CrossRefSearchEngine.py +47 -40
- scitex/scholar/search_engines/individual/OpenAlexSearchEngine.py +55 -50
- scitex/scholar/search_engines/individual/PubMedSearchEngine.py +8 -10
- scitex/scholar/search_engines/individual/SemanticScholarSearchEngine.py +55 -49
- scitex/scholar/storage/BibTeXHandler.py +150 -95
- scitex/scholar/storage/PaperIO.py +3 -6
- scitex/scholar/storage/ScholarLibrary.py +70 -49
- scitex/scholar/storage/_DeduplicationManager.py +52 -25
- scitex/scholar/storage/_LibraryCacheManager.py +19 -46
- scitex/scholar/storage/_LibraryManager.py +65 -175
- scitex/scholar/url_finder/ScholarURLFinder.py +9 -25
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_direct_links.py +1 -1
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_href.py +6 -10
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_navigation.py +4 -6
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_publisher_patterns.py +8 -15
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_zotero_translators.py +3 -3
- scitex/scholar/url_finder/strategies/find_supplementary_urls_by_href.py +3 -3
- scitex/scholar/url_finder/translators/core/patterns.py +6 -4
- scitex/scholar/url_finder/translators/core/registry.py +6 -9
- scitex/scholar/url_finder/translators/individual/BOFiP_Impots.py +60 -52
- scitex/scholar/url_finder/translators/individual/Baidu_Scholar.py +54 -62
- scitex/scholar/url_finder/translators/individual/Bangkok_Post.py +38 -44
- scitex/scholar/url_finder/translators/individual/Baruch_Foundation.py +43 -47
- scitex/scholar/url_finder/translators/individual/Beobachter.py +46 -50
- scitex/scholar/url_finder/translators/individual/Bezneng_Gajit.py +37 -41
- scitex/scholar/url_finder/translators/individual/BibLaTeX.py +59 -52
- scitex/scholar/url_finder/translators/individual/BibTeX.py +83 -79
- scitex/scholar/url_finder/translators/individual/Biblio_com.py +48 -51
- scitex/scholar/url_finder/translators/individual/Bibliontology_RDF.py +58 -56
- scitex/scholar/url_finder/translators/individual/Camara_Brasileira_do_Livro_ISBN.py +102 -99
- scitex/scholar/url_finder/translators/individual/CanLII.py +49 -43
- scitex/scholar/url_finder/translators/individual/Canada_com.py +36 -40
- scitex/scholar/url_finder/translators/individual/Canadian_Letters_and_Images.py +43 -43
- scitex/scholar/url_finder/translators/individual/Canadiana_ca.py +77 -66
- scitex/scholar/url_finder/translators/individual/Cascadilla_Proceedings_Project.py +68 -62
- scitex/scholar/url_finder/translators/individual/Central_and_Eastern_European_Online_Library_Journals.py +60 -60
- scitex/scholar/url_finder/translators/individual/Champlain_Society_Collection.py +63 -61
- scitex/scholar/url_finder/translators/individual/Chicago_Journal_of_Theoretical_Computer_Science.py +74 -58
- scitex/scholar/url_finder/translators/individual/Christian_Science_Monitor.py +32 -38
- scitex/scholar/url_finder/translators/individual/Columbia_University_Press.py +51 -47
- scitex/scholar/url_finder/translators/individual/Common_Place.py +66 -57
- scitex/scholar/url_finder/translators/individual/Cornell_LII.py +66 -62
- scitex/scholar/url_finder/translators/individual/Cornell_University_Press.py +38 -45
- scitex/scholar/url_finder/translators/individual/CourtListener.py +52 -56
- scitex/scholar/url_finder/translators/individual/DAI_Zenon.py +53 -54
- scitex/scholar/url_finder/translators/individual/access_medicine.py +27 -33
- scitex/scholar/url_finder/translators/individual/acm.py +1 -1
- scitex/scholar/url_finder/translators/individual/acm_digital_library.py +93 -63
- scitex/scholar/url_finder/translators/individual/airiti.py +3 -1
- scitex/scholar/url_finder/translators/individual/aosic.py +3 -1
- scitex/scholar/url_finder/translators/individual/archive_ouverte_aosic.py +3 -1
- scitex/scholar/url_finder/translators/individual/archive_ouverte_en_sciences_de_l_information_et_de_la_communication___aosic_.py +6 -2
- scitex/scholar/url_finder/translators/individual/artforum.py +35 -27
- scitex/scholar/url_finder/translators/individual/arxiv.py +1 -1
- scitex/scholar/url_finder/translators/individual/arxiv_org.py +8 -4
- scitex/scholar/url_finder/translators/individual/atlanta_journal_constitution.py +22 -18
- scitex/scholar/url_finder/translators/individual/atypon_journals.py +19 -11
- scitex/scholar/url_finder/translators/individual/austlii_and_nzlii.py +48 -44
- scitex/scholar/url_finder/translators/individual/australian_dictionary_of_biography.py +21 -17
- scitex/scholar/url_finder/translators/individual/bailii.py +22 -19
- scitex/scholar/url_finder/translators/individual/bbc.py +46 -42
- scitex/scholar/url_finder/translators/individual/bbc_genome.py +37 -25
- scitex/scholar/url_finder/translators/individual/biblioteca_nacional_de_maestros.py +24 -20
- scitex/scholar/url_finder/translators/individual/bibliotheque_archives_nationale_quebec_pistard.py +42 -43
- scitex/scholar/url_finder/translators/individual/bibliotheque_archives_nationales_quebec.py +87 -81
- scitex/scholar/url_finder/translators/individual/bibliotheque_nationale_france.py +39 -37
- scitex/scholar/url_finder/translators/individual/bibsys.py +32 -28
- scitex/scholar/url_finder/translators/individual/bioconductor.py +58 -52
- scitex/scholar/url_finder/translators/individual/biomed_central.py +23 -15
- scitex/scholar/url_finder/translators/individual/biorxiv.py +26 -13
- scitex/scholar/url_finder/translators/individual/blogger.py +39 -43
- scitex/scholar/url_finder/translators/individual/bloomberg.py +48 -52
- scitex/scholar/url_finder/translators/individual/bloomsbury_food_library.py +37 -37
- scitex/scholar/url_finder/translators/individual/bluesky.py +30 -28
- scitex/scholar/url_finder/translators/individual/bnf_isbn.py +1 -1
- scitex/scholar/url_finder/translators/individual/bocc.py +66 -60
- scitex/scholar/url_finder/translators/individual/boe.py +52 -52
- scitex/scholar/url_finder/translators/individual/brill.py +3 -1
- scitex/scholar/url_finder/translators/individual/business_standard.py +36 -38
- scitex/scholar/url_finder/translators/individual/cabi_cab_abstracts.py +39 -41
- scitex/scholar/url_finder/translators/individual/cambridge.py +3 -1
- scitex/scholar/url_finder/translators/individual/cambridge_core.py +30 -24
- scitex/scholar/url_finder/translators/individual/caod.py +50 -46
- scitex/scholar/url_finder/translators/individual/cbc.py +91 -67
- scitex/scholar/url_finder/translators/individual/ccfr_bnf.py +49 -53
- scitex/scholar/url_finder/translators/individual/cia_world_factbook.py +43 -33
- scitex/scholar/url_finder/translators/individual/crossref_rest.py +208 -174
- scitex/scholar/url_finder/translators/individual/current_affairs.py +29 -35
- scitex/scholar/url_finder/translators/individual/dabi.py +70 -66
- scitex/scholar/url_finder/translators/individual/dagens_nyheter.py +3 -1
- scitex/scholar/url_finder/translators/individual/dagstuhl.py +10 -15
- scitex/scholar/url_finder/translators/individual/dar_almandumah.py +13 -9
- scitex/scholar/url_finder/translators/individual/dart_europe.py +19 -22
- scitex/scholar/url_finder/translators/individual/data_gov.py +2 -2
- scitex/scholar/url_finder/translators/individual/databrary.py +27 -28
- scitex/scholar/url_finder/translators/individual/datacite_json.py +152 -137
- scitex/scholar/url_finder/translators/individual/dataverse.py +68 -64
- scitex/scholar/url_finder/translators/individual/daum_news.py +38 -38
- scitex/scholar/url_finder/translators/individual/dblp.py +4 -8
- scitex/scholar/url_finder/translators/individual/dblp_computer_science_bibliography.py +8 -3
- scitex/scholar/url_finder/translators/individual/dbpia.py +5 -3
- scitex/scholar/url_finder/translators/individual/defense_technical_information_center.py +30 -28
- scitex/scholar/url_finder/translators/individual/delpher.py +102 -79
- scitex/scholar/url_finder/translators/individual/demographic_research.py +35 -31
- scitex/scholar/url_finder/translators/individual/denik_cz.py +58 -54
- scitex/scholar/url_finder/translators/individual/depatisnet.py +7 -10
- scitex/scholar/url_finder/translators/individual/der_freitag.py +81 -66
- scitex/scholar/url_finder/translators/individual/der_spiegel.py +56 -54
- scitex/scholar/url_finder/translators/individual/digibib_net.py +3 -1
- scitex/scholar/url_finder/translators/individual/digizeitschriften.py +3 -1
- scitex/scholar/url_finder/translators/individual/dpla.py +13 -14
- scitex/scholar/url_finder/translators/individual/dspace.py +2 -2
- scitex/scholar/url_finder/translators/individual/ebrary.py +3 -1
- scitex/scholar/url_finder/translators/individual/ebscohost.py +3 -1
- scitex/scholar/url_finder/translators/individual/electronic_colloquium_on_computational_complexity.py +3 -1
- scitex/scholar/url_finder/translators/individual/elife.py +3 -1
- scitex/scholar/url_finder/translators/individual/elsevier_health_journals.py +3 -1
- scitex/scholar/url_finder/translators/individual/emerald.py +3 -1
- scitex/scholar/url_finder/translators/individual/emerald_insight.py +3 -1
- scitex/scholar/url_finder/translators/individual/epicurious.py +3 -1
- scitex/scholar/url_finder/translators/individual/eurogamerusgamer.py +3 -1
- scitex/scholar/url_finder/translators/individual/fachportal_padagogik.py +3 -1
- scitex/scholar/url_finder/translators/individual/frontiers.py +1 -1
- scitex/scholar/url_finder/translators/individual/gale_databases.py +3 -1
- scitex/scholar/url_finder/translators/individual/gms_german_medical_science.py +6 -2
- scitex/scholar/url_finder/translators/individual/ieee_computer_society.py +6 -2
- scitex/scholar/url_finder/translators/individual/ieee_xplore.py +41 -35
- scitex/scholar/url_finder/translators/individual/inter_research_science_center.py +6 -2
- scitex/scholar/url_finder/translators/individual/jisc_historical_texts.py +3 -1
- scitex/scholar/url_finder/translators/individual/jstor.py +14 -12
- scitex/scholar/url_finder/translators/individual/korean_national_library.py +3 -1
- scitex/scholar/url_finder/translators/individual/la_times.py +3 -1
- scitex/scholar/url_finder/translators/individual/landesbibliographie_baden_wurttemberg.py +3 -1
- scitex/scholar/url_finder/translators/individual/legislative_insight.py +3 -1
- scitex/scholar/url_finder/translators/individual/libraries_tasmania.py +3 -1
- scitex/scholar/url_finder/translators/individual/library_catalog__koha_.py +3 -1
- scitex/scholar/url_finder/translators/individual/lingbuzz.py +2 -2
- scitex/scholar/url_finder/translators/individual/max_planck_institute_for_the_history_of_science_virtual_laboratory_library.py +3 -1
- scitex/scholar/url_finder/translators/individual/mdpi.py +12 -6
- scitex/scholar/url_finder/translators/individual/microbiology_society_journals.py +3 -1
- scitex/scholar/url_finder/translators/individual/midas_journals.py +3 -1
- scitex/scholar/url_finder/translators/individual/nagoya_university_opac.py +3 -1
- scitex/scholar/url_finder/translators/individual/nature_publishing_group.py +32 -19
- scitex/scholar/url_finder/translators/individual/ntsb_accident_reports.py +3 -1
- scitex/scholar/url_finder/translators/individual/openedition_journals.py +8 -4
- scitex/scholar/url_finder/translators/individual/orcid.py +16 -15
- scitex/scholar/url_finder/translators/individual/oxford.py +25 -19
- scitex/scholar/url_finder/translators/individual/oxford_dictionaries_premium.py +3 -1
- scitex/scholar/url_finder/translators/individual/ozon_ru.py +3 -1
- scitex/scholar/url_finder/translators/individual/plos.py +9 -12
- scitex/scholar/url_finder/translators/individual/polygon.py +3 -1
- scitex/scholar/url_finder/translators/individual/primo.py +3 -1
- scitex/scholar/url_finder/translators/individual/project_muse.py +3 -1
- scitex/scholar/url_finder/translators/individual/pubfactory_journals.py +3 -1
- scitex/scholar/url_finder/translators/individual/pubmed.py +71 -65
- scitex/scholar/url_finder/translators/individual/pubmed_central.py +8 -6
- scitex/scholar/url_finder/translators/individual/rechtspraak_nl.py +3 -1
- scitex/scholar/url_finder/translators/individual/sage_journals.py +25 -17
- scitex/scholar/url_finder/translators/individual/sciencedirect.py +36 -17
- scitex/scholar/url_finder/translators/individual/semantics_visual_library.py +3 -1
- scitex/scholar/url_finder/translators/individual/silverchair.py +70 -52
- scitex/scholar/url_finder/translators/individual/sora.py +3 -1
- scitex/scholar/url_finder/translators/individual/springer.py +15 -11
- scitex/scholar/url_finder/translators/individual/ssrn.py +3 -3
- scitex/scholar/url_finder/translators/individual/stanford_encyclopedia_of_philosophy.py +3 -1
- scitex/scholar/url_finder/translators/individual/superlib.py +3 -1
- scitex/scholar/url_finder/translators/individual/treesearch.py +3 -1
- scitex/scholar/url_finder/translators/individual/university_of_chicago_press_books.py +3 -1
- scitex/scholar/url_finder/translators/individual/vlex.py +3 -1
- scitex/scholar/url_finder/translators/individual/web_of_science.py +3 -1
- scitex/scholar/url_finder/translators/individual/web_of_science_nextgen.py +3 -1
- scitex/scholar/url_finder/translators/individual/wiley.py +31 -25
- scitex/scholar/url_finder/translators/individual/wilson_center_digital_archive.py +3 -1
- scitex/scholar/utils/bibtex/_parse_bibtex.py +3 -3
- scitex/scholar/utils/cleanup/_cleanup_scholar_processes.py +5 -9
- scitex/scholar/utils/text/_TextNormalizer.py +249 -176
- scitex/scholar/utils/validation/DOIValidator.py +31 -28
- scitex/scholar/utils/validation/__init__.py +0 -0
- scitex/scholar/utils/validation/validate_library_dois.py +61 -57
- scitex/scholar/zotero/__init__.py +1 -1
- scitex/security/cli.py +7 -20
- scitex/security/github.py +45 -32
- scitex/session/__init__.py +8 -9
- scitex/session/_decorator.py +60 -41
- scitex/session/_lifecycle.py +39 -39
- scitex/session/_manager.py +24 -20
- scitex/sh/__init__.py +4 -3
- scitex/sh/_execute.py +10 -7
- scitex/sh/_security.py +3 -3
- scitex/sh/_types.py +2 -3
- scitex/stats/__init__.py +57 -6
- scitex/stats/_schema.py +42 -569
- scitex/stats/auto/__init__.py +188 -0
- scitex/stats/auto/_context.py +331 -0
- scitex/stats/auto/_formatting.py +679 -0
- scitex/stats/auto/_rules.py +901 -0
- scitex/stats/auto/_selector.py +554 -0
- scitex/stats/auto/_styles.py +721 -0
- scitex/stats/correct/__init__.py +4 -4
- scitex/stats/correct/_correct_bonferroni.py +43 -34
- scitex/stats/correct/_correct_fdr.py +14 -40
- scitex/stats/correct/_correct_fdr_.py +39 -46
- scitex/stats/correct/_correct_holm.py +14 -32
- scitex/stats/correct/_correct_sidak.py +36 -21
- scitex/stats/descriptive/_circular.py +20 -21
- scitex/stats/descriptive/_describe.py +19 -5
- scitex/stats/descriptive/_nan.py +5 -7
- scitex/stats/descriptive/_real.py +4 -3
- scitex/stats/effect_sizes/__init__.py +10 -11
- scitex/stats/effect_sizes/_cliffs_delta.py +35 -32
- scitex/stats/effect_sizes/_cohens_d.py +30 -31
- scitex/stats/effect_sizes/_epsilon_squared.py +19 -22
- scitex/stats/effect_sizes/_eta_squared.py +23 -27
- scitex/stats/effect_sizes/_prob_superiority.py +18 -21
- scitex/stats/posthoc/__init__.py +3 -3
- scitex/stats/posthoc/_dunnett.py +75 -55
- scitex/stats/posthoc/_games_howell.py +61 -43
- scitex/stats/posthoc/_tukey_hsd.py +42 -34
- scitex/stats/power/__init__.py +2 -2
- scitex/stats/power/_power.py +56 -56
- scitex/stats/tests/__init__.py +1 -1
- scitex/stats/tests/correlation/__init__.py +1 -1
- scitex/stats/tests/correlation/_test_pearson.py +28 -38
- scitex/stats/utils/__init__.py +14 -17
- scitex/stats/utils/_effect_size.py +85 -78
- scitex/stats/utils/_formatters.py +49 -43
- scitex/stats/utils/_normalizers.py +7 -14
- scitex/stats/utils/_power.py +56 -56
- scitex/str/__init__.py +1 -0
- scitex/str/_clean_path.py +3 -3
- scitex/str/_factor_out_digits.py +86 -58
- scitex/str/_format_plot_text.py +180 -111
- scitex/str/_latex.py +19 -19
- scitex/str/_latex_fallback.py +9 -10
- scitex/str/_parse.py +3 -6
- scitex/str/_print_debug.py +13 -13
- scitex/str/_printc.py +2 -0
- scitex/str/_search.py +3 -3
- scitex/template/.legacy/_clone_project.py +9 -13
- scitex/template/__init__.py +10 -2
- scitex/template/_clone_project.py +7 -2
- scitex/template/_copy.py +1 -0
- scitex/template/_customize.py +3 -6
- scitex/template/_git_strategy.py +2 -3
- scitex/template/_rename.py +1 -0
- scitex/template/clone_pip_project.py +6 -7
- scitex/template/clone_research.py +7 -10
- scitex/template/clone_singularity.py +6 -7
- scitex/template/clone_writer_directory.py +6 -7
- scitex/tex/_preview.py +26 -11
- scitex/tex/_to_vec.py +10 -7
- scitex/torch/__init__.py +11 -1
- scitex/types/_ArrayLike.py +2 -0
- scitex/types/_is_listed_X.py +3 -3
- scitex/units.py +110 -77
- scitex/utils/_compress_hdf5.py +3 -3
- scitex/utils/_email.py +8 -4
- scitex/utils/_notify.py +14 -8
- scitex/utils/_search.py +6 -6
- scitex/utils/_verify_scitex_format.py +17 -42
- scitex/utils/_verify_scitex_format_v01.py +12 -34
- scitex/utils/template.py +4 -3
- scitex/vis/README.md +246 -615
- scitex/vis/__init__.py +138 -78
- scitex/vis/backend/__init__.py +3 -3
- scitex/vis/backend/{export.py → _export.py} +1 -1
- scitex/vis/backend/{parser.py → _parser.py} +1 -3
- scitex/vis/backend/{render.py → _render.py} +1 -1
- scitex/vis/canvas.py +435 -0
- scitex/vis/docs/CANVAS_ARCHITECTURE.md +307 -0
- scitex/vis/editor/__init__.py +1 -1
- scitex/vis/editor/_dearpygui_editor.py +1976 -0
- scitex/vis/editor/_defaults.py +140 -110
- scitex/vis/editor/_edit.py +90 -42
- scitex/vis/editor/_flask_editor.py +37 -0
- scitex/vis/editor/_mpl_editor.py +63 -48
- scitex/vis/editor/_qt_editor.py +916 -0
- scitex/vis/editor/_tkinter_editor.py +146 -89
- scitex/vis/editor/flask_editor/__init__.py +21 -0
- scitex/vis/editor/flask_editor/_bbox.py +529 -0
- scitex/vis/editor/flask_editor/_core.py +168 -0
- scitex/vis/editor/flask_editor/_plotter.py +567 -0
- scitex/vis/editor/flask_editor/_renderer.py +393 -0
- scitex/vis/editor/flask_editor/_utils.py +80 -0
- scitex/vis/editor/flask_editor/templates/__init__.py +33 -0
- scitex/vis/editor/flask_editor/templates/_html.py +513 -0
- scitex/vis/editor/flask_editor/templates/_scripts.py +1261 -0
- scitex/vis/editor/flask_editor/templates/_styles.py +739 -0
- scitex/vis/io/__init__.py +84 -21
- scitex/vis/io/_canvas.py +230 -0
- scitex/vis/io/_data.py +208 -0
- scitex/vis/io/_directory.py +205 -0
- scitex/vis/io/_export.py +463 -0
- scitex/vis/io/{load.py → _load.py} +1 -1
- scitex/vis/io/_panel.py +432 -0
- scitex/vis/io/{save.py → _save.py} +0 -0
- scitex/vis/model/__init__.py +7 -7
- scitex/vis/model/{annotations.py → _annotations.py} +2 -4
- scitex/vis/model/{axes.py → _axes.py} +1 -1
- scitex/vis/model/{figure.py → _figure.py} +0 -0
- scitex/vis/model/{guides.py → _guides.py} +1 -1
- scitex/vis/model/{plot.py → _plot.py} +2 -4
- scitex/vis/model/{plot_types.py → _plot_types.py} +0 -0
- scitex/vis/model/{styles.py → _styles.py} +0 -0
- scitex/vis/utils/__init__.py +2 -2
- scitex/vis/utils/{defaults.py → _defaults.py} +1 -2
- scitex/vis/utils/{validate.py → _validate.py} +3 -9
- scitex/web/__init__.py +7 -1
- scitex/web/_scraping.py +54 -38
- scitex/web/_search_pubmed.py +30 -14
- scitex/writer/.legacy/Writer_v01-refactored.py +4 -4
- scitex/writer/.legacy/_compile.py +18 -28
- scitex/writer/Writer.py +8 -21
- scitex/writer/__init__.py +11 -11
- scitex/writer/_clone_writer_project.py +2 -6
- scitex/writer/_compile/__init__.py +1 -0
- scitex/writer/_compile/_parser.py +1 -0
- scitex/writer/_compile/_runner.py +35 -38
- scitex/writer/_compile/_validator.py +1 -0
- scitex/writer/_compile/manuscript.py +1 -0
- scitex/writer/_compile/revision.py +1 -0
- scitex/writer/_compile/supplementary.py +1 -0
- scitex/writer/_compile_async.py +5 -12
- scitex/writer/_project/__init__.py +1 -0
- scitex/writer/_project/_create.py +10 -25
- scitex/writer/_project/_trees.py +4 -9
- scitex/writer/_project/_validate.py +2 -3
- scitex/writer/_validate_tree_structures.py +7 -18
- scitex/writer/dataclasses/__init__.py +8 -10
- scitex/writer/dataclasses/config/_CONSTANTS.py +2 -3
- scitex/writer/dataclasses/config/_WriterConfig.py +4 -9
- scitex/writer/dataclasses/contents/_ManuscriptContents.py +14 -25
- scitex/writer/dataclasses/contents/_RevisionContents.py +21 -16
- scitex/writer/dataclasses/contents/_SupplementaryContents.py +21 -24
- scitex/writer/dataclasses/core/_Document.py +2 -3
- scitex/writer/dataclasses/core/_DocumentSection.py +8 -23
- scitex/writer/dataclasses/results/_CompilationResult.py +2 -3
- scitex/writer/dataclasses/results/_LaTeXIssue.py +3 -6
- scitex/writer/dataclasses/results/_SaveSectionsResponse.py +20 -9
- scitex/writer/dataclasses/results/_SectionReadResponse.py +24 -10
- scitex/writer/dataclasses/tree/_ConfigTree.py +7 -4
- scitex/writer/dataclasses/tree/_ManuscriptTree.py +10 -13
- scitex/writer/dataclasses/tree/_RevisionTree.py +16 -17
- scitex/writer/dataclasses/tree/_ScriptsTree.py +10 -5
- scitex/writer/dataclasses/tree/_SharedTree.py +10 -13
- scitex/writer/dataclasses/tree/_SupplementaryTree.py +15 -14
- scitex/writer/utils/.legacy_git_retry.py +3 -8
- scitex/writer/utils/_parse_latex_logs.py +2 -3
- scitex/writer/utils/_parse_script_args.py +20 -23
- scitex/writer/utils/_watch.py +5 -5
- {scitex-2.4.3.dist-info → scitex-2.7.0.dist-info}/METADATA +12 -11
- {scitex-2.4.3.dist-info → scitex-2.7.0.dist-info}/RECORD +1075 -958
- scitex/db/_sqlite3/_SQLite3Mixins/_ColumnMixin_v01-indentation-issues.py +0 -583
- scitex/plt/_subplots/_export_as_csv_formatters.py +0 -112
- scitex/vis/DJANGO_INTEGRATION.md +0 -677
- scitex/vis/editor/_web_editor.py +0 -1440
- scitex/vis/tmp.txt +0 -239
- {scitex-2.4.3.dist-info → scitex-2.7.0.dist-info}/WHEEL +0 -0
- {scitex-2.4.3.dist-info → scitex-2.7.0.dist-info}/entry_points.txt +0 -0
- {scitex-2.4.3.dist-info → scitex-2.7.0.dist-info}/licenses/LICENSE +0 -0
scitex/io/_save.py
CHANGED
|
@@ -61,6 +61,7 @@ from ._save_modules import save_torch
|
|
|
61
61
|
from ._save_modules import save_yaml
|
|
62
62
|
from ._save_modules import save_zarr
|
|
63
63
|
from ._save_modules._bibtex import save_bibtex
|
|
64
|
+
from ._save_modules._canvas import save_canvas
|
|
64
65
|
|
|
65
66
|
logger = logging.getLogger()
|
|
66
67
|
|
|
@@ -160,6 +161,7 @@ def save(
|
|
|
160
161
|
auto_crop: bool = True,
|
|
161
162
|
crop_margin_mm: float = 1.0,
|
|
162
163
|
metadata_extra: dict = None,
|
|
164
|
+
json_schema: str = "recipe",
|
|
163
165
|
**kwargs,
|
|
164
166
|
) -> None:
|
|
165
167
|
"""
|
|
@@ -202,6 +204,11 @@ def save(
|
|
|
202
204
|
}
|
|
203
205
|
}
|
|
204
206
|
Default is None.
|
|
207
|
+
json_schema : str, optional
|
|
208
|
+
Schema type for JSON metadata output. Options:
|
|
209
|
+
- "recipe": Minimal schema with method calls + data refs (default, ~95% smaller)
|
|
210
|
+
- "verbose": Full schema with all artist details
|
|
211
|
+
Default is "recipe".
|
|
205
212
|
**kwargs
|
|
206
213
|
Additional keyword arguments to pass to the underlying save function of the specific format.
|
|
207
214
|
|
|
@@ -295,9 +302,7 @@ def save(
|
|
|
295
302
|
elif var in frame.f_globals:
|
|
296
303
|
format_dict[var] = frame.f_globals[var]
|
|
297
304
|
else:
|
|
298
|
-
raise ValueError(
|
|
299
|
-
f"Invalid variable name in f-string: {var}"
|
|
300
|
-
)
|
|
305
|
+
raise ValueError(f"Invalid variable name in f-string: {var}")
|
|
301
306
|
|
|
302
307
|
# Use str.format() which is safe
|
|
303
308
|
specified_path = path_content.format(**format_dict)
|
|
@@ -369,7 +374,7 @@ def save(
|
|
|
369
374
|
or ("<stdin>" in script_path)
|
|
370
375
|
or env_type in ["ipython", "interactive"]
|
|
371
376
|
):
|
|
372
|
-
script_path = f
|
|
377
|
+
script_path = f"/tmp/{_os.getenv('USER')}"
|
|
373
378
|
sdir = script_path
|
|
374
379
|
else:
|
|
375
380
|
# Unknown environment, use current directory
|
|
@@ -426,6 +431,7 @@ def save(
|
|
|
426
431
|
auto_crop=auto_crop,
|
|
427
432
|
crop_margin_mm=crop_margin_mm,
|
|
428
433
|
metadata_extra=metadata_extra,
|
|
434
|
+
json_schema=json_schema,
|
|
429
435
|
**kwargs,
|
|
430
436
|
)
|
|
431
437
|
|
|
@@ -435,6 +441,9 @@ def save(
|
|
|
435
441
|
return Path(spath)
|
|
436
442
|
# return True
|
|
437
443
|
|
|
444
|
+
except AssertionError:
|
|
445
|
+
# Re-raise assertion errors - these are validation failures that should stop execution
|
|
446
|
+
raise
|
|
438
447
|
except Exception as e:
|
|
439
448
|
logger.error(
|
|
440
449
|
f"Error occurred while saving: {str(e)}\n"
|
|
@@ -470,9 +479,7 @@ def _symlink_to(spath_final, symlink_to, verbose):
|
|
|
470
479
|
|
|
471
480
|
# Ensure the symlink directory exists (only if there is a directory component)
|
|
472
481
|
symlink_dir = _os.path.dirname(symlink_to)
|
|
473
|
-
if
|
|
474
|
-
symlink_dir
|
|
475
|
-
): # Only create directory if there's a directory component
|
|
482
|
+
if symlink_dir: # Only create directory if there's a directory component
|
|
476
483
|
_os.makedirs(symlink_dir, exist_ok=True)
|
|
477
484
|
|
|
478
485
|
# Remove existing symlink or file
|
|
@@ -483,9 +490,7 @@ def _symlink_to(spath_final, symlink_to, verbose):
|
|
|
483
490
|
|
|
484
491
|
if verbose:
|
|
485
492
|
symlink_to_full = (
|
|
486
|
-
os.path.realpath(symlink_to)
|
|
487
|
-
+ "/"
|
|
488
|
-
+ os.path.basename(spath_final)
|
|
493
|
+
os.path.realpath(symlink_to) + "/" + os.path.basename(spath_final)
|
|
489
494
|
)
|
|
490
495
|
logger.success(f"Symlinked: {spath_final} -> {symlink_to_full}")
|
|
491
496
|
|
|
@@ -501,6 +506,7 @@ def _save(
|
|
|
501
506
|
auto_crop=False,
|
|
502
507
|
crop_margin_mm=1.0,
|
|
503
508
|
metadata_extra=None,
|
|
509
|
+
json_schema="recipe",
|
|
504
510
|
**kwargs,
|
|
505
511
|
):
|
|
506
512
|
# Don't use object's own save method - use consistent handlers
|
|
@@ -510,6 +516,11 @@ def _save(
|
|
|
510
516
|
# Get file extension
|
|
511
517
|
ext = _os.path.splitext(spath)[1].lower()
|
|
512
518
|
|
|
519
|
+
# Handle .canvas directories (special case - path ends with .canvas)
|
|
520
|
+
if spath.endswith(".canvas"):
|
|
521
|
+
save_canvas(obj, spath, **kwargs)
|
|
522
|
+
return
|
|
523
|
+
|
|
513
524
|
# Try dispatch dictionary first for O(1) lookup
|
|
514
525
|
if ext in _FILE_HANDLERS:
|
|
515
526
|
# Check if handler needs special parameters
|
|
@@ -534,6 +545,7 @@ def _save(
|
|
|
534
545
|
auto_crop=auto_crop,
|
|
535
546
|
crop_margin_mm=crop_margin_mm,
|
|
536
547
|
metadata_extra=metadata_extra,
|
|
548
|
+
json_schema=json_schema,
|
|
537
549
|
**kwargs,
|
|
538
550
|
)
|
|
539
551
|
elif ext in [".hdf5", ".h5", ".zarr"]:
|
|
@@ -563,9 +575,7 @@ def _save(
|
|
|
563
575
|
logger.success(f"Saved to: ./{rel_path} ({file_size})")
|
|
564
576
|
|
|
565
577
|
|
|
566
|
-
def _save_separate_legends(
|
|
567
|
-
obj, spath, symlink_from_cwd=False, dry_run=False, **kwargs
|
|
568
|
-
):
|
|
578
|
+
def _save_separate_legends(obj, spath, symlink_from_cwd=False, dry_run=False, **kwargs):
|
|
569
579
|
"""Save separate legend files if ax.legend('separate') was used."""
|
|
570
580
|
if dry_run:
|
|
571
581
|
return
|
|
@@ -647,6 +657,7 @@ def _handle_image_with_csv(
|
|
|
647
657
|
auto_crop=True,
|
|
648
658
|
crop_margin_mm=1.0,
|
|
649
659
|
metadata_extra=None,
|
|
660
|
+
json_schema="recipe",
|
|
650
661
|
**kwargs,
|
|
651
662
|
):
|
|
652
663
|
"""Handle image file saving with optional CSV export and auto-cropping."""
|
|
@@ -655,7 +666,7 @@ def _handle_image_with_csv(
|
|
|
655
666
|
|
|
656
667
|
# Auto-collect metadata from scitex figures if not explicitly provided
|
|
657
668
|
collected_metadata = None
|
|
658
|
-
if
|
|
669
|
+
if "metadata" not in kwargs or kwargs["metadata"] is None:
|
|
659
670
|
try:
|
|
660
671
|
# Check if this is a matplotlib figure or scitex wrapper
|
|
661
672
|
import matplotlib.figure
|
|
@@ -663,92 +674,154 @@ def _handle_image_with_csv(
|
|
|
663
674
|
fig_mpl = None
|
|
664
675
|
if isinstance(obj, matplotlib.figure.Figure):
|
|
665
676
|
fig_mpl = obj
|
|
666
|
-
elif hasattr(obj,
|
|
677
|
+
elif hasattr(obj, "_fig_mpl"): # FigWrapper
|
|
667
678
|
fig_mpl = obj._fig_mpl
|
|
668
|
-
elif hasattr(obj,
|
|
679
|
+
elif hasattr(obj, "figure") and isinstance(
|
|
680
|
+
obj.figure, matplotlib.figure.Figure
|
|
681
|
+
):
|
|
669
682
|
fig_mpl = obj.figure
|
|
670
683
|
|
|
671
684
|
# If we have a figure, try to collect metadata
|
|
672
685
|
if fig_mpl is not None:
|
|
673
|
-
# Get
|
|
686
|
+
# Get axes from scitex wrapper if available (for multi-axes support)
|
|
687
|
+
# Priority: FigWrapper.axes (AxesWrapper) > mpl axes with _scitex_wrapper > mpl axes
|
|
674
688
|
ax = None
|
|
675
|
-
|
|
676
|
-
|
|
689
|
+
|
|
690
|
+
# First try to get AxesWrapper from FigWrapper (obj)
|
|
691
|
+
if hasattr(obj, "axes"):
|
|
692
|
+
# obj is FigWrapper, get its axes (could be AxisWrapper or AxesWrapper)
|
|
693
|
+
ax = obj.axes
|
|
694
|
+
elif hasattr(fig_mpl, "axes") and len(fig_mpl.axes) > 0:
|
|
695
|
+
mpl_ax = fig_mpl.axes[0]
|
|
696
|
+
# Try to get scitex wrapper which has history for recipe schema
|
|
697
|
+
if hasattr(mpl_ax, '_scitex_wrapper'):
|
|
698
|
+
ax = mpl_ax._scitex_wrapper
|
|
699
|
+
else:
|
|
700
|
+
ax = mpl_ax
|
|
677
701
|
|
|
678
702
|
# Collect metadata using scitex's metadata collector
|
|
679
703
|
try:
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
704
|
+
if json_schema == "recipe":
|
|
705
|
+
from scitex.plt.utils import collect_recipe_metadata
|
|
706
|
+
auto_metadata = collect_recipe_metadata(
|
|
707
|
+
fig_mpl, ax,
|
|
708
|
+
auto_crop=auto_crop,
|
|
709
|
+
crop_margin_mm=crop_margin_mm,
|
|
710
|
+
)
|
|
711
|
+
else:
|
|
712
|
+
from scitex.plt.utils import collect_figure_metadata
|
|
713
|
+
auto_metadata = collect_figure_metadata(fig_mpl, ax)
|
|
686
714
|
|
|
687
715
|
if auto_metadata:
|
|
688
|
-
kwargs[
|
|
716
|
+
kwargs["metadata"] = auto_metadata
|
|
689
717
|
collected_metadata = auto_metadata # Save for JSON export
|
|
690
718
|
if verbose:
|
|
691
|
-
|
|
719
|
+
schema_name = "recipe" if json_schema == "recipe" else "verbose"
|
|
720
|
+
logger.info(f" • Auto-collected metadata ({schema_name} schema)")
|
|
692
721
|
except ImportError:
|
|
693
722
|
pass # collect_figure_metadata not available
|
|
694
723
|
except Exception as e:
|
|
695
724
|
if verbose:
|
|
696
725
|
import warnings
|
|
726
|
+
|
|
697
727
|
warnings.warn(f"Could not auto-collect metadata: {e}")
|
|
698
728
|
except Exception:
|
|
699
729
|
pass # Silently continue if auto-collection fails
|
|
700
730
|
else:
|
|
701
731
|
# Use explicitly provided metadata
|
|
702
|
-
collected_metadata = kwargs.get(
|
|
732
|
+
collected_metadata = kwargs.get("metadata")
|
|
703
733
|
|
|
704
734
|
# Merge metadata_extra with collected_metadata
|
|
705
735
|
if metadata_extra is not None and collected_metadata is not None:
|
|
706
736
|
# Deep merge: metadata_extra takes precedence
|
|
707
737
|
import copy
|
|
738
|
+
|
|
708
739
|
collected_metadata = copy.deepcopy(collected_metadata)
|
|
709
740
|
|
|
710
741
|
# If metadata_extra has plot_type and it doesn't exist in collected, add it
|
|
711
|
-
if
|
|
712
|
-
collected_metadata[
|
|
742
|
+
if "plot_type" in metadata_extra:
|
|
743
|
+
collected_metadata["plot_type"] = metadata_extra["plot_type"]
|
|
713
744
|
|
|
714
745
|
# Merge style information
|
|
715
|
-
if
|
|
716
|
-
collected_metadata[
|
|
746
|
+
if "style" in metadata_extra:
|
|
747
|
+
collected_metadata["style"] = metadata_extra["style"]
|
|
717
748
|
|
|
718
749
|
# Merge any other fields from metadata_extra
|
|
719
750
|
for key, value in metadata_extra.items():
|
|
720
|
-
if key not in [
|
|
751
|
+
if key not in ["plot_type", "style"]:
|
|
721
752
|
collected_metadata[key] = value
|
|
722
753
|
|
|
723
754
|
# Update kwargs metadata for image saving
|
|
724
|
-
kwargs[
|
|
755
|
+
kwargs["metadata"] = collected_metadata
|
|
725
756
|
|
|
726
757
|
save_image(obj, spath, verbose=verbose, **kwargs)
|
|
727
758
|
|
|
728
759
|
# Auto-crop if requested (only for raster formats)
|
|
760
|
+
crop_offset = None
|
|
729
761
|
if auto_crop and not dry_run:
|
|
730
762
|
# Get file extension
|
|
731
763
|
ext = spath.lower()
|
|
732
764
|
|
|
733
765
|
# Only crop raster formats (PNG, JPEG, TIFF)
|
|
734
766
|
# Skip vector formats (PDF, SVG) as they don't benefit from cropping
|
|
735
|
-
if ext.endswith((
|
|
767
|
+
if ext.endswith((".png", ".jpg", ".jpeg", ".tiff", ".tif")):
|
|
736
768
|
try:
|
|
737
769
|
from scitex.plt.utils._crop import crop
|
|
738
770
|
|
|
739
771
|
# Convert mm to pixels (assuming 300 DPI)
|
|
740
772
|
# 1mm at 300 DPI = 11.81 pixels ≈ 12 pixels
|
|
741
|
-
dpi = kwargs.get(
|
|
773
|
+
dpi = kwargs.get("dpi", 300)
|
|
742
774
|
margin_px = int(crop_margin_mm * dpi / 25.4) # 25.4mm per inch
|
|
743
775
|
|
|
744
|
-
# Crop the saved image in place
|
|
745
|
-
|
|
776
|
+
# Crop the saved image in place, get crop offset for metadata adjustment
|
|
777
|
+
_, crop_offset = crop(
|
|
778
|
+
spath,
|
|
779
|
+
output_path=spath,
|
|
780
|
+
margin=margin_px,
|
|
781
|
+
overwrite=True,
|
|
782
|
+
verbose=False,
|
|
783
|
+
return_offset=True,
|
|
784
|
+
)
|
|
785
|
+
|
|
786
|
+
# Adjust axes_bbox_px in metadata to account for crop offset
|
|
787
|
+
if crop_offset and collected_metadata:
|
|
788
|
+
if "axes_bbox_px" in collected_metadata:
|
|
789
|
+
bbox = collected_metadata["axes_bbox_px"]
|
|
790
|
+
# Subtract crop offset from all coordinates
|
|
791
|
+
# left/upper is where the crop started
|
|
792
|
+
left_offset = crop_offset["left"]
|
|
793
|
+
upper_offset = crop_offset["upper"]
|
|
794
|
+
bbox["x0"] = bbox.get("x0", 0) - left_offset
|
|
795
|
+
bbox["x1"] = bbox.get("x1", 0) - left_offset
|
|
796
|
+
bbox["y0"] = bbox.get("y0", 0) - upper_offset
|
|
797
|
+
bbox["y1"] = bbox.get("y1", 0) - upper_offset
|
|
798
|
+
# Update width/height to match new image size
|
|
799
|
+
# (bbox width/height shouldn't change, but figure size does)
|
|
800
|
+
|
|
801
|
+
# Also update figure size in metadata
|
|
802
|
+
if "figure" in collected_metadata:
|
|
803
|
+
fig_meta = collected_metadata["figure"]
|
|
804
|
+
if "size_px" in fig_meta:
|
|
805
|
+
fig_meta["size_px"] = [
|
|
806
|
+
crop_offset["new_width"],
|
|
807
|
+
crop_offset["new_height"],
|
|
808
|
+
]
|
|
809
|
+
if "dimensions" in collected_metadata:
|
|
810
|
+
dim_meta = collected_metadata["dimensions"]
|
|
811
|
+
if "figure_size_px" in dim_meta:
|
|
812
|
+
dim_meta["figure_size_px"] = [
|
|
813
|
+
crop_offset["new_width"],
|
|
814
|
+
crop_offset["new_height"],
|
|
815
|
+
]
|
|
746
816
|
|
|
747
817
|
if verbose:
|
|
748
|
-
logger.info(
|
|
818
|
+
logger.info(
|
|
819
|
+
f" • Auto-cropped with {crop_margin_mm}mm margin ({margin_px}px at {dpi} DPI)"
|
|
820
|
+
)
|
|
749
821
|
|
|
750
822
|
except Exception as e:
|
|
751
823
|
import warnings
|
|
824
|
+
|
|
752
825
|
warnings.warn(f"Auto-crop failed: {e}. Image saved without cropping.")
|
|
753
826
|
|
|
754
827
|
# Handle separate legend saving
|
|
@@ -766,11 +839,12 @@ def _handle_image_with_csv(
|
|
|
766
839
|
|
|
767
840
|
# Check if the path contains an image extension directory (e.g., ./png/, ./jpg/)
|
|
768
841
|
# If so, save CSV in a parallel ./csv/ directory
|
|
769
|
-
image_extensions = [
|
|
842
|
+
image_extensions = ["png", "jpg", "jpeg", "gif", "tiff", "tif", "svg", "pdf"]
|
|
770
843
|
parent_dir = _os.path.dirname(spath)
|
|
771
844
|
parent_name = _os.path.basename(parent_dir)
|
|
772
845
|
filename_without_ext = _os.path.splitext(_os.path.basename(spath))[0]
|
|
773
846
|
|
|
847
|
+
csv_path = None # Initialize to avoid UnboundLocalError when CSV export is skipped
|
|
774
848
|
try:
|
|
775
849
|
# Get the figure object that may contain plot data
|
|
776
850
|
fig_obj = _get_figure_with_data(obj)
|
|
@@ -786,7 +860,9 @@ def _handle_image_with_csv(
|
|
|
786
860
|
# Create parallel csv/ directory
|
|
787
861
|
grandparent_dir = _os.path.dirname(parent_dir)
|
|
788
862
|
csv_dir = _os.path.join(grandparent_dir, "csv")
|
|
789
|
-
csv_path = _os.path.join(
|
|
863
|
+
csv_path = _os.path.join(
|
|
864
|
+
csv_dir, filename_without_ext + ".csv"
|
|
865
|
+
)
|
|
790
866
|
else:
|
|
791
867
|
# Save CSV in same directory as image
|
|
792
868
|
csv_path = _os.path.splitext(spath)[0] + ".csv"
|
|
@@ -804,20 +880,59 @@ def _handle_image_with_csv(
|
|
|
804
880
|
no_csv=True,
|
|
805
881
|
)
|
|
806
882
|
|
|
883
|
+
# Update metadata with actual CSV info (after export)
|
|
884
|
+
# This ensures column names match exactly, including any
|
|
885
|
+
# deduplication suffixes added by pandas
|
|
886
|
+
if collected_metadata is not None:
|
|
887
|
+
try:
|
|
888
|
+
from scitex.plt.utils._collect_figure_metadata import (
|
|
889
|
+
_compute_csv_hash,
|
|
890
|
+
)
|
|
891
|
+
|
|
892
|
+
# Ensure data section exists
|
|
893
|
+
if "data" not in collected_metadata:
|
|
894
|
+
collected_metadata["data"] = {}
|
|
895
|
+
|
|
896
|
+
# Get actual column names from exported DataFrame
|
|
897
|
+
actual_columns = list(csv_data.columns)
|
|
898
|
+
|
|
899
|
+
# Update data section with csv_path (relative to JSON)
|
|
900
|
+
# Since JSON and CSV are in the same or parallel directories,
|
|
901
|
+
# use just the filename for simplicity
|
|
902
|
+
collected_metadata["data"]["csv_path"] = _os.path.basename(csv_path)
|
|
903
|
+
|
|
904
|
+
# Update columns to use flat list of actual columns
|
|
905
|
+
collected_metadata["data"]["columns_actual"] = actual_columns
|
|
906
|
+
|
|
907
|
+
# Compute hash of actual CSV data
|
|
908
|
+
collected_metadata["data"]["csv_hash"] = _compute_csv_hash(
|
|
909
|
+
csv_data
|
|
910
|
+
)
|
|
911
|
+
except Exception:
|
|
912
|
+
pass # Silently continue if update fails
|
|
913
|
+
|
|
807
914
|
# Create symlink_to for CSV if it was specified for the image
|
|
808
915
|
if symlink_to:
|
|
809
916
|
# Apply same directory transformation for symlink
|
|
810
917
|
symlink_parent_dir = _os.path.dirname(symlink_to)
|
|
811
918
|
symlink_parent_name = _os.path.basename(symlink_parent_dir)
|
|
812
|
-
symlink_filename_without_ext = _os.path.splitext(
|
|
919
|
+
symlink_filename_without_ext = _os.path.splitext(
|
|
920
|
+
_os.path.basename(symlink_to)
|
|
921
|
+
)[0]
|
|
813
922
|
|
|
814
923
|
if symlink_parent_name.lower() in image_extensions:
|
|
815
|
-
symlink_grandparent_dir = _os.path.dirname(
|
|
924
|
+
symlink_grandparent_dir = _os.path.dirname(
|
|
925
|
+
symlink_parent_dir
|
|
926
|
+
)
|
|
816
927
|
csv_symlink_to = _os.path.join(
|
|
817
|
-
symlink_grandparent_dir,
|
|
928
|
+
symlink_grandparent_dir,
|
|
929
|
+
"csv",
|
|
930
|
+
symlink_filename_without_ext + ".csv",
|
|
818
931
|
)
|
|
819
932
|
else:
|
|
820
|
-
csv_symlink_to =
|
|
933
|
+
csv_symlink_to = (
|
|
934
|
+
_os.path.splitext(symlink_to)[0] + ".csv"
|
|
935
|
+
)
|
|
821
936
|
|
|
822
937
|
_symlink_to(csv_path, csv_symlink_to, True)
|
|
823
938
|
|
|
@@ -836,14 +951,24 @@ def _handle_image_with_csv(
|
|
|
836
951
|
]
|
|
837
952
|
if isinstance(original_path, str):
|
|
838
953
|
# Apply same directory transformation for symlink
|
|
839
|
-
orig_parent_dir = _os.path.dirname(
|
|
840
|
-
|
|
841
|
-
|
|
954
|
+
orig_parent_dir = _os.path.dirname(
|
|
955
|
+
original_path
|
|
956
|
+
)
|
|
957
|
+
orig_parent_name = _os.path.basename(
|
|
958
|
+
orig_parent_dir
|
|
959
|
+
)
|
|
960
|
+
orig_filename_without_ext = _os.path.splitext(
|
|
961
|
+
_os.path.basename(original_path)
|
|
962
|
+
)[0]
|
|
842
963
|
|
|
843
964
|
if orig_parent_name.lower() in image_extensions:
|
|
844
|
-
orig_grandparent_dir = _os.path.dirname(
|
|
965
|
+
orig_grandparent_dir = _os.path.dirname(
|
|
966
|
+
orig_parent_dir
|
|
967
|
+
)
|
|
845
968
|
csv_relative = _os.path.join(
|
|
846
|
-
orig_grandparent_dir,
|
|
969
|
+
orig_grandparent_dir,
|
|
970
|
+
"csv",
|
|
971
|
+
orig_filename_without_ext + ".csv",
|
|
847
972
|
)
|
|
848
973
|
else:
|
|
849
974
|
csv_relative = original_path.replace(
|
|
@@ -859,9 +984,7 @@ def _handle_image_with_csv(
|
|
|
859
984
|
else:
|
|
860
985
|
# Fallback to basename if we can't find the original path
|
|
861
986
|
csv_cwd = (
|
|
862
|
-
_os.getcwd()
|
|
863
|
-
+ "/"
|
|
864
|
-
+ _os.path.basename(csv_path)
|
|
987
|
+
_os.getcwd() + "/" + _os.path.basename(csv_path)
|
|
865
988
|
)
|
|
866
989
|
_symlink(csv_path, csv_cwd, True, True)
|
|
867
990
|
|
|
@@ -873,14 +996,18 @@ def _handle_image_with_csv(
|
|
|
873
996
|
if parent_name.lower() in image_extensions:
|
|
874
997
|
grandparent_dir = _os.path.dirname(parent_dir)
|
|
875
998
|
csv_dir = _os.path.join(grandparent_dir, "csv")
|
|
876
|
-
csv_sigmaplot_path = _os.path.join(
|
|
999
|
+
csv_sigmaplot_path = _os.path.join(
|
|
1000
|
+
csv_dir, filename_without_ext + "_for_sigmaplot.csv"
|
|
1001
|
+
)
|
|
877
1002
|
else:
|
|
878
1003
|
csv_sigmaplot_path = spath.replace(
|
|
879
1004
|
ext_wo_dot, "csv"
|
|
880
1005
|
).replace(".csv", "_for_sigmaplot.csv")
|
|
881
1006
|
|
|
882
1007
|
# Ensure parent directory exists
|
|
883
|
-
_os.makedirs(
|
|
1008
|
+
_os.makedirs(
|
|
1009
|
+
_os.path.dirname(csv_sigmaplot_path), exist_ok=True
|
|
1010
|
+
)
|
|
884
1011
|
# Save directly using _save to avoid path doubling
|
|
885
1012
|
# Don't pass image-specific kwargs to CSV save
|
|
886
1013
|
_save(
|
|
@@ -896,12 +1023,18 @@ def _handle_image_with_csv(
|
|
|
896
1023
|
if symlink_to:
|
|
897
1024
|
symlink_parent_dir = _os.path.dirname(symlink_to)
|
|
898
1025
|
symlink_parent_name = _os.path.basename(symlink_parent_dir)
|
|
899
|
-
symlink_filename_without_ext = _os.path.splitext(
|
|
1026
|
+
symlink_filename_without_ext = _os.path.splitext(
|
|
1027
|
+
_os.path.basename(symlink_to)
|
|
1028
|
+
)[0]
|
|
900
1029
|
|
|
901
1030
|
if symlink_parent_name.lower() in image_extensions:
|
|
902
|
-
symlink_grandparent_dir = _os.path.dirname(
|
|
1031
|
+
symlink_grandparent_dir = _os.path.dirname(
|
|
1032
|
+
symlink_parent_dir
|
|
1033
|
+
)
|
|
903
1034
|
csv_sigmaplot_symlink_to = _os.path.join(
|
|
904
|
-
symlink_grandparent_dir,
|
|
1035
|
+
symlink_grandparent_dir,
|
|
1036
|
+
"csv",
|
|
1037
|
+
symlink_filename_without_ext + "_for_sigmaplot.csv",
|
|
905
1038
|
)
|
|
906
1039
|
else:
|
|
907
1040
|
csv_sigmaplot_symlink_to = (
|
|
@@ -938,7 +1071,16 @@ def _handle_image_with_csv(
|
|
|
938
1071
|
# If so, save JSON in a parallel ./json/ directory
|
|
939
1072
|
# Example: ./path/to/output/png/fig.png -> ./path/to/output/json/fig.json
|
|
940
1073
|
# Example: ./path/to/output/fig.png -> ./path/to/output/fig.json (same dir)
|
|
941
|
-
image_extensions = [
|
|
1074
|
+
image_extensions = [
|
|
1075
|
+
"png",
|
|
1076
|
+
"jpg",
|
|
1077
|
+
"jpeg",
|
|
1078
|
+
"gif",
|
|
1079
|
+
"tiff",
|
|
1080
|
+
"tif",
|
|
1081
|
+
"svg",
|
|
1082
|
+
"pdf",
|
|
1083
|
+
]
|
|
942
1084
|
parent_dir = _os.path.dirname(spath)
|
|
943
1085
|
parent_name = _os.path.basename(parent_dir)
|
|
944
1086
|
filename_without_ext = _os.path.splitext(_os.path.basename(spath))[0]
|
|
@@ -966,17 +1108,29 @@ def _handle_image_with_csv(
|
|
|
966
1108
|
no_csv=True,
|
|
967
1109
|
)
|
|
968
1110
|
|
|
1111
|
+
# Verify CSV/JSON consistency (data_ref must match columns_actual)
|
|
1112
|
+
# Only check for verbose schema - recipe schema uses different data_ref structure
|
|
1113
|
+
if csv_path and not dry_run and json_schema != "recipe":
|
|
1114
|
+
from scitex.plt.utils._collect_figure_metadata import (
|
|
1115
|
+
assert_csv_json_consistency,
|
|
1116
|
+
)
|
|
1117
|
+
assert_csv_json_consistency(csv_path, json_path)
|
|
1118
|
+
|
|
969
1119
|
# Create symlink_to for JSON if it was specified for the image
|
|
970
1120
|
if symlink_to:
|
|
971
1121
|
# Apply same directory transformation for symlink
|
|
972
1122
|
symlink_parent_dir = _os.path.dirname(symlink_to)
|
|
973
1123
|
symlink_parent_name = _os.path.basename(symlink_parent_dir)
|
|
974
|
-
symlink_filename_without_ext = _os.path.splitext(
|
|
1124
|
+
symlink_filename_without_ext = _os.path.splitext(
|
|
1125
|
+
_os.path.basename(symlink_to)
|
|
1126
|
+
)[0]
|
|
975
1127
|
|
|
976
1128
|
if symlink_parent_name.lower() in image_extensions:
|
|
977
1129
|
symlink_grandparent_dir = _os.path.dirname(symlink_parent_dir)
|
|
978
1130
|
json_symlink_to = _os.path.join(
|
|
979
|
-
symlink_grandparent_dir,
|
|
1131
|
+
symlink_grandparent_dir,
|
|
1132
|
+
"json",
|
|
1133
|
+
symlink_filename_without_ext + ".json",
|
|
980
1134
|
)
|
|
981
1135
|
else:
|
|
982
1136
|
json_symlink_to = _os.path.splitext(symlink_to)[0] + ".json"
|
|
@@ -998,12 +1152,16 @@ def _handle_image_with_csv(
|
|
|
998
1152
|
# Apply same directory transformation for symlink
|
|
999
1153
|
orig_parent_dir = _os.path.dirname(original_path)
|
|
1000
1154
|
orig_parent_name = _os.path.basename(orig_parent_dir)
|
|
1001
|
-
orig_filename_without_ext = _os.path.splitext(
|
|
1155
|
+
orig_filename_without_ext = _os.path.splitext(
|
|
1156
|
+
_os.path.basename(original_path)
|
|
1157
|
+
)[0]
|
|
1002
1158
|
|
|
1003
1159
|
if orig_parent_name.lower() in image_extensions:
|
|
1004
1160
|
orig_grandparent_dir = _os.path.dirname(orig_parent_dir)
|
|
1005
1161
|
json_relative = _os.path.join(
|
|
1006
|
-
orig_grandparent_dir,
|
|
1162
|
+
orig_grandparent_dir,
|
|
1163
|
+
"json",
|
|
1164
|
+
orig_filename_without_ext + ".json",
|
|
1007
1165
|
)
|
|
1008
1166
|
else:
|
|
1009
1167
|
json_relative = original_path.replace(
|
|
@@ -1019,15 +1177,22 @@ def _handle_image_with_csv(
|
|
|
1019
1177
|
json_cwd = _os.getcwd() + "/" + _os.path.basename(json_path)
|
|
1020
1178
|
_symlink(json_path, json_cwd, True, True)
|
|
1021
1179
|
|
|
1180
|
+
except AssertionError:
|
|
1181
|
+
# Re-raise assertion errors - these are validation failures that should stop execution
|
|
1182
|
+
raise
|
|
1022
1183
|
except Exception as e:
|
|
1023
1184
|
import warnings
|
|
1185
|
+
|
|
1024
1186
|
warnings.warn(f"JSON metadata export failed: {e}")
|
|
1025
1187
|
import traceback
|
|
1188
|
+
|
|
1026
1189
|
traceback.print_exc()
|
|
1027
1190
|
|
|
1028
1191
|
|
|
1029
1192
|
# Dispatch dictionary for O(1) file format lookup
|
|
1030
1193
|
_FILE_HANDLERS = {
|
|
1194
|
+
# Canvas directory format (scitex.vis)
|
|
1195
|
+
".canvas": save_canvas,
|
|
1031
1196
|
# Excel formats
|
|
1032
1197
|
".xlsx": save_excel,
|
|
1033
1198
|
".xls": save_excel,
|
|
@@ -21,7 +21,10 @@ to that specific format.
|
|
|
21
21
|
from ._csv import _save_csv as save_csv
|
|
22
22
|
from ._excel import save_excel
|
|
23
23
|
from ._numpy import _save_npy as save_npy, _save_npz as save_npz
|
|
24
|
-
from ._pickle import
|
|
24
|
+
from ._pickle import (
|
|
25
|
+
_save_pickle as save_pickle,
|
|
26
|
+
_save_pickle_gz as save_pickle_compressed,
|
|
27
|
+
)
|
|
25
28
|
from ._joblib import _save_joblib as save_joblib
|
|
26
29
|
from ._torch import _save_torch as save_torch
|
|
27
30
|
from ._json import _save_json as save_json
|
|
@@ -39,7 +42,9 @@ from ._bibtex import save_bibtex
|
|
|
39
42
|
|
|
40
43
|
# Import additional save utilities
|
|
41
44
|
from ._listed_dfs_as_csv import _save_listed_dfs_as_csv as save_listed_dfs_as_csv
|
|
42
|
-
from ._listed_scalars_as_csv import
|
|
45
|
+
from ._listed_scalars_as_csv import (
|
|
46
|
+
_save_listed_scalars_as_csv as save_listed_scalars_as_csv,
|
|
47
|
+
)
|
|
43
48
|
from ._optuna_study_as_csv_and_pngs import save_optuna_study_as_csv_and_pngs
|
|
44
49
|
|
|
45
50
|
# Define what gets imported with "from scitex.io._save_modules import *"
|