scitex 2.0.0__py2.py3-none-any.whl → 2.1.0__py2.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 +53 -15
- scitex/__main__.py +72 -26
- scitex/__version__.py +1 -1
- scitex/_sh.py +145 -23
- scitex/ai/__init__.py +30 -16
- scitex/ai/_gen_ai/_Anthropic.py +5 -7
- scitex/ai/_gen_ai/_BaseGenAI.py +2 -2
- scitex/ai/_gen_ai/_DeepSeek.py +10 -2
- scitex/ai/_gen_ai/_Google.py +2 -2
- scitex/ai/_gen_ai/_Llama.py +2 -2
- scitex/ai/_gen_ai/_OpenAI.py +2 -2
- scitex/ai/_gen_ai/_PARAMS.py +51 -65
- scitex/ai/_gen_ai/_Perplexity.py +2 -2
- scitex/ai/_gen_ai/__init__.py +25 -14
- scitex/ai/_gen_ai/_format_output_func.py +4 -4
- scitex/ai/classification/{classifier_server.py → Classifier.py} +5 -5
- scitex/ai/classification/CrossValidationExperiment.py +374 -0
- scitex/ai/classification/__init__.py +43 -4
- scitex/ai/classification/reporters/_BaseClassificationReporter.py +281 -0
- scitex/ai/classification/reporters/_ClassificationReporter.py +773 -0
- scitex/ai/classification/reporters/_MultiClassificationReporter.py +406 -0
- scitex/ai/classification/reporters/_SingleClassificationReporter.py +1834 -0
- scitex/ai/classification/reporters/__init__.py +11 -0
- scitex/ai/classification/reporters/reporter_utils/_Plotter.py +1028 -0
- scitex/ai/classification/reporters/reporter_utils/__init__.py +80 -0
- scitex/ai/classification/reporters/reporter_utils/aggregation.py +457 -0
- scitex/ai/classification/reporters/reporter_utils/data_models.py +313 -0
- scitex/ai/classification/reporters/reporter_utils/reporting.py +1056 -0
- scitex/ai/classification/reporters/reporter_utils/storage.py +221 -0
- scitex/ai/classification/reporters/reporter_utils/validation.py +395 -0
- scitex/ai/classification/timeseries/_TimeSeriesBlockingSplit.py +568 -0
- scitex/ai/classification/timeseries/_TimeSeriesCalendarSplit.py +688 -0
- scitex/ai/classification/timeseries/_TimeSeriesMetadata.py +139 -0
- scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +1716 -0
- scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit_v01-not-using-n_splits.py +1685 -0
- scitex/ai/classification/timeseries/_TimeSeriesStrategy.py +84 -0
- scitex/ai/classification/timeseries/_TimeSeriesStratifiedSplit.py +610 -0
- scitex/ai/classification/timeseries/__init__.py +39 -0
- scitex/ai/classification/timeseries/_normalize_timestamp.py +436 -0
- scitex/ai/clustering/_umap.py +2 -2
- scitex/ai/feature_extraction/vit.py +1 -0
- scitex/ai/feature_selection/__init__.py +30 -0
- scitex/ai/feature_selection/feature_selection.py +364 -0
- scitex/ai/loss/multi_task_loss.py +1 -1
- scitex/ai/metrics/__init__.py +51 -4
- scitex/ai/metrics/_calc_bacc.py +61 -0
- scitex/ai/metrics/_calc_bacc_from_conf_mat.py +38 -0
- scitex/ai/metrics/_calc_clf_report.py +78 -0
- scitex/ai/metrics/_calc_conf_mat.py +93 -0
- scitex/ai/metrics/_calc_feature_importance.py +183 -0
- scitex/ai/metrics/_calc_mcc.py +61 -0
- scitex/ai/metrics/_calc_pre_rec_auc.py +116 -0
- scitex/ai/metrics/_calc_roc_auc.py +110 -0
- scitex/ai/metrics/_calc_seizure_prediction_metrics.py +490 -0
- scitex/ai/metrics/{silhoute_score_block.py → _calc_silhouette_score.py} +15 -8
- scitex/ai/metrics/_normalize_labels.py +83 -0
- scitex/ai/plt/__init__.py +47 -8
- scitex/ai/plt/{_conf_mat.py → _plot_conf_mat.py} +158 -87
- scitex/ai/plt/_plot_feature_importance.py +323 -0
- scitex/ai/plt/_plot_learning_curve.py +345 -0
- scitex/ai/plt/_plot_optuna_study.py +225 -0
- scitex/ai/plt/_plot_pre_rec_curve.py +290 -0
- scitex/ai/plt/_plot_roc_curve.py +255 -0
- scitex/ai/training/{learning_curve_logger.py → _LearningCurveLogger.py} +197 -213
- scitex/ai/training/__init__.py +2 -2
- scitex/ai/utils/grid_search.py +3 -3
- scitex/benchmark/__init__.py +52 -0
- scitex/benchmark/benchmark.py +400 -0
- scitex/benchmark/monitor.py +370 -0
- scitex/benchmark/profiler.py +297 -0
- scitex/browser/__init__.py +48 -0
- scitex/browser/automation/CookieHandler.py +216 -0
- scitex/browser/automation/__init__.py +7 -0
- scitex/browser/collaboration/__init__.py +55 -0
- scitex/browser/collaboration/auth_helpers.py +94 -0
- scitex/browser/collaboration/collaborative_agent.py +136 -0
- scitex/browser/collaboration/credential_manager.py +188 -0
- scitex/browser/collaboration/interactive_panel.py +400 -0
- scitex/browser/collaboration/persistent_browser.py +170 -0
- scitex/browser/collaboration/shared_session.py +383 -0
- scitex/browser/collaboration/standard_interactions.py +246 -0
- scitex/browser/collaboration/visual_feedback.py +181 -0
- scitex/browser/core/BrowserMixin.py +326 -0
- scitex/browser/core/ChromeProfileManager.py +446 -0
- scitex/browser/core/__init__.py +9 -0
- scitex/browser/debugging/__init__.py +18 -0
- scitex/browser/debugging/_browser_logger.py +657 -0
- scitex/browser/debugging/_highlight_element.py +143 -0
- scitex/browser/debugging/_show_grid.py +154 -0
- scitex/browser/interaction/__init__.py +24 -0
- scitex/browser/interaction/click_center.py +149 -0
- scitex/browser/interaction/click_with_fallbacks.py +206 -0
- scitex/browser/interaction/close_popups.py +498 -0
- scitex/browser/interaction/fill_with_fallbacks.py +209 -0
- scitex/browser/pdf/__init__.py +14 -0
- scitex/browser/pdf/click_download_for_chrome_pdf_viewer.py +200 -0
- scitex/browser/pdf/detect_chrome_pdf_viewer.py +198 -0
- scitex/browser/remote/CaptchaHandler.py +434 -0
- scitex/browser/remote/ZenRowsAPIClient.py +347 -0
- scitex/browser/remote/ZenRowsBrowserManager.py +570 -0
- scitex/browser/remote/__init__.py +11 -0
- scitex/browser/stealth/HumanBehavior.py +344 -0
- scitex/browser/stealth/StealthManager.py +1008 -0
- scitex/browser/stealth/__init__.py +9 -0
- scitex/browser/template.py +122 -0
- scitex/capture/__init__.py +110 -0
- scitex/capture/__main__.py +25 -0
- scitex/capture/capture.py +848 -0
- scitex/capture/cli.py +233 -0
- scitex/capture/gif.py +344 -0
- scitex/capture/mcp_server.py +961 -0
- scitex/capture/session.py +70 -0
- scitex/capture/utils.py +705 -0
- scitex/cli/__init__.py +17 -0
- scitex/cli/cloud.py +447 -0
- scitex/cli/main.py +42 -0
- scitex/cli/scholar.py +280 -0
- scitex/context/_suppress_output.py +5 -3
- scitex/db/__init__.py +30 -3
- scitex/db/__main__.py +75 -0
- scitex/db/_check_health.py +381 -0
- scitex/db/_delete_duplicates.py +25 -386
- scitex/db/_inspect.py +335 -114
- scitex/db/_inspect_optimized.py +301 -0
- scitex/db/{_PostgreSQL.py → _postgresql/_PostgreSQL.py} +3 -3
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_BackupMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_BatchMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_BlobMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_ConnectionMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_MaintenanceMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_QueryMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_SchemaMixin.py +1 -1
- scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_TransactionMixin.py +1 -1
- scitex/db/_postgresql/__init__.py +6 -0
- scitex/db/_sqlite3/_SQLite3.py +210 -0
- scitex/db/_sqlite3/_SQLite3Mixins/_ArrayMixin.py +581 -0
- scitex/db/_sqlite3/_SQLite3Mixins/_ArrayMixin_v01-need-_hash-col.py +517 -0
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_BatchMixin.py +1 -1
- scitex/db/_sqlite3/_SQLite3Mixins/_BlobMixin.py +281 -0
- scitex/db/_sqlite3/_SQLite3Mixins/_ColumnMixin.py +548 -0
- scitex/db/_sqlite3/_SQLite3Mixins/_ColumnMixin_v01-indentation-issues.py +583 -0
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_ConnectionMixin.py +29 -13
- scitex/db/_sqlite3/_SQLite3Mixins/_GitMixin.py +583 -0
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_ImportExportMixin.py +1 -1
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_IndexMixin.py +1 -1
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_MaintenanceMixin.py +2 -1
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_QueryMixin.py +37 -10
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_RowMixin.py +46 -6
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_TableMixin.py +56 -10
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_TransactionMixin.py +1 -1
- scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/__init__.py +14 -2
- scitex/db/_sqlite3/__init__.py +7 -0
- scitex/db/_sqlite3/_delete_duplicates.py +274 -0
- scitex/decorators/__init__.py +2 -0
- scitex/decorators/_cache_disk.py +13 -5
- scitex/decorators/_cache_disk_async.py +49 -0
- scitex/decorators/_deprecated.py +175 -10
- scitex/decorators/_timeout.py +1 -1
- scitex/dev/_analyze_code_flow.py +2 -2
- scitex/dict/_DotDict.py +73 -15
- scitex/dict/_DotDict_v01-not-handling-recursive-instantiations.py +442 -0
- scitex/dict/_DotDict_v02-not-serializing-Path-object.py +446 -0
- scitex/dict/__init__.py +2 -0
- scitex/dict/_flatten.py +27 -0
- scitex/dsp/_crop.py +2 -2
- scitex/dsp/_demo_sig.py +2 -2
- scitex/dsp/_detect_ripples.py +2 -2
- scitex/dsp/_hilbert.py +2 -2
- scitex/dsp/_listen.py +6 -6
- scitex/dsp/_modulation_index.py +2 -2
- scitex/dsp/_pac.py +1 -1
- scitex/dsp/_psd.py +2 -2
- scitex/dsp/_resample.py +2 -1
- scitex/dsp/_time.py +3 -2
- scitex/dsp/_wavelet.py +3 -2
- scitex/dsp/add_noise.py +2 -2
- scitex/dsp/example.py +1 -0
- scitex/dsp/filt.py +10 -9
- scitex/dsp/template.py +3 -2
- scitex/dsp/utils/_differential_bandpass_filters.py +1 -1
- scitex/dsp/utils/pac.py +2 -2
- scitex/dt/_normalize_timestamp.py +432 -0
- scitex/errors.py +572 -0
- scitex/gen/_DimHandler.py +2 -2
- scitex/gen/__init__.py +37 -7
- scitex/gen/_deprecated_close.py +80 -0
- scitex/gen/_deprecated_start.py +26 -0
- scitex/gen/_detect_environment.py +152 -0
- scitex/gen/_detect_notebook_path.py +169 -0
- scitex/gen/_embed.py +6 -2
- scitex/gen/_get_notebook_path.py +257 -0
- scitex/gen/_less.py +1 -1
- scitex/gen/_list_packages.py +2 -2
- scitex/gen/_norm.py +44 -9
- scitex/gen/_norm_cache.py +269 -0
- scitex/gen/_src.py +3 -5
- scitex/gen/_title_case.py +3 -3
- scitex/io/__init__.py +28 -6
- scitex/io/_glob.py +13 -7
- scitex/io/_load.py +108 -21
- scitex/io/_load_cache.py +303 -0
- scitex/io/_load_configs.py +40 -15
- scitex/io/{_H5Explorer.py → _load_modules/_H5Explorer.py} +80 -17
- scitex/io/_load_modules/_ZarrExplorer.py +114 -0
- scitex/io/_load_modules/_bibtex.py +207 -0
- scitex/io/_load_modules/_hdf5.py +53 -178
- scitex/io/_load_modules/_json.py +5 -3
- scitex/io/_load_modules/_pdf.py +871 -16
- scitex/io/_load_modules/_sqlite3.py +15 -0
- scitex/io/_load_modules/_txt.py +41 -12
- scitex/io/_load_modules/_yaml.py +4 -3
- scitex/io/_load_modules/_zarr.py +126 -0
- scitex/io/_save.py +429 -171
- scitex/io/_save_modules/__init__.py +6 -0
- scitex/io/_save_modules/_bibtex.py +194 -0
- scitex/io/_save_modules/_csv.py +8 -4
- scitex/io/_save_modules/_excel.py +174 -15
- scitex/io/_save_modules/_hdf5.py +251 -226
- scitex/io/_save_modules/_image.py +1 -3
- scitex/io/_save_modules/_json.py +49 -4
- scitex/io/_save_modules/_listed_dfs_as_csv.py +1 -3
- scitex/io/_save_modules/_listed_scalars_as_csv.py +1 -3
- scitex/io/_save_modules/_tex.py +277 -0
- scitex/io/_save_modules/_yaml.py +42 -3
- scitex/io/_save_modules/_zarr.py +160 -0
- scitex/io/utils/__init__.py +20 -0
- scitex/io/utils/h5_to_zarr.py +616 -0
- scitex/linalg/_geometric_median.py +6 -2
- scitex/{gen/_tee.py → logging/_Tee.py} +43 -84
- scitex/logging/__init__.py +122 -0
- scitex/logging/_config.py +158 -0
- scitex/logging/_context.py +103 -0
- scitex/logging/_formatters.py +128 -0
- scitex/logging/_handlers.py +64 -0
- scitex/logging/_levels.py +35 -0
- scitex/logging/_logger.py +163 -0
- scitex/logging/_print_capture.py +95 -0
- scitex/ml/__init__.py +69 -0
- scitex/{ai/genai/anthropic.py → ml/_gen_ai/_Anthropic.py} +13 -19
- scitex/{ai/genai/base_genai.py → ml/_gen_ai/_BaseGenAI.py} +5 -5
- scitex/{ai/genai/deepseek.py → ml/_gen_ai/_DeepSeek.py} +11 -16
- scitex/{ai/genai/google.py → ml/_gen_ai/_Google.py} +7 -15
- scitex/{ai/genai/groq.py → ml/_gen_ai/_Groq.py} +1 -8
- scitex/{ai/genai/llama.py → ml/_gen_ai/_Llama.py} +3 -16
- scitex/{ai/genai/openai.py → ml/_gen_ai/_OpenAI.py} +3 -3
- scitex/{ai/genai/params.py → ml/_gen_ai/_PARAMS.py} +51 -65
- scitex/{ai/genai/perplexity.py → ml/_gen_ai/_Perplexity.py} +3 -14
- scitex/ml/_gen_ai/__init__.py +43 -0
- scitex/{ai/genai/calc_cost.py → ml/_gen_ai/_calc_cost.py} +1 -1
- scitex/{ai/genai/format_output_func.py → ml/_gen_ai/_format_output_func.py} +4 -4
- scitex/{ai/genai/genai_factory.py → ml/_gen_ai/_genai_factory.py} +8 -8
- scitex/ml/activation/__init__.py +8 -0
- scitex/ml/activation/_define.py +11 -0
- scitex/{ai/classifier_server.py → ml/classification/Classifier.py} +5 -5
- scitex/ml/classification/CrossValidationExperiment.py +374 -0
- scitex/ml/classification/__init__.py +46 -0
- scitex/ml/classification/reporters/_BaseClassificationReporter.py +281 -0
- scitex/ml/classification/reporters/_ClassificationReporter.py +773 -0
- scitex/ml/classification/reporters/_MultiClassificationReporter.py +406 -0
- scitex/ml/classification/reporters/_SingleClassificationReporter.py +1834 -0
- scitex/ml/classification/reporters/__init__.py +11 -0
- scitex/ml/classification/reporters/reporter_utils/_Plotter.py +1028 -0
- scitex/ml/classification/reporters/reporter_utils/__init__.py +80 -0
- scitex/ml/classification/reporters/reporter_utils/aggregation.py +457 -0
- scitex/ml/classification/reporters/reporter_utils/data_models.py +313 -0
- scitex/ml/classification/reporters/reporter_utils/reporting.py +1056 -0
- scitex/ml/classification/reporters/reporter_utils/storage.py +221 -0
- scitex/ml/classification/reporters/reporter_utils/validation.py +395 -0
- scitex/ml/classification/timeseries/_TimeSeriesBlockingSplit.py +568 -0
- scitex/ml/classification/timeseries/_TimeSeriesCalendarSplit.py +688 -0
- scitex/ml/classification/timeseries/_TimeSeriesMetadata.py +139 -0
- scitex/ml/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +1716 -0
- scitex/ml/classification/timeseries/_TimeSeriesSlidingWindowSplit_v01-not-using-n_splits.py +1685 -0
- scitex/ml/classification/timeseries/_TimeSeriesStrategy.py +84 -0
- scitex/ml/classification/timeseries/_TimeSeriesStratifiedSplit.py +610 -0
- scitex/ml/classification/timeseries/__init__.py +39 -0
- scitex/ml/classification/timeseries/_normalize_timestamp.py +436 -0
- scitex/ml/clustering/__init__.py +11 -0
- scitex/ml/clustering/_pca.py +115 -0
- scitex/ml/clustering/_umap.py +376 -0
- scitex/ml/feature_extraction/__init__.py +56 -0
- scitex/ml/feature_extraction/vit.py +149 -0
- scitex/ml/feature_selection/__init__.py +30 -0
- scitex/ml/feature_selection/feature_selection.py +364 -0
- scitex/ml/loss/_L1L2Losses.py +34 -0
- scitex/ml/loss/__init__.py +12 -0
- scitex/ml/loss/multi_task_loss.py +47 -0
- scitex/ml/metrics/__init__.py +56 -0
- scitex/ml/metrics/_calc_bacc.py +61 -0
- scitex/ml/metrics/_calc_bacc_from_conf_mat.py +38 -0
- scitex/ml/metrics/_calc_clf_report.py +78 -0
- scitex/ml/metrics/_calc_conf_mat.py +93 -0
- scitex/ml/metrics/_calc_feature_importance.py +183 -0
- scitex/ml/metrics/_calc_mcc.py +61 -0
- scitex/ml/metrics/_calc_pre_rec_auc.py +116 -0
- scitex/ml/metrics/_calc_roc_auc.py +110 -0
- scitex/ml/metrics/_calc_seizure_prediction_metrics.py +490 -0
- scitex/ml/metrics/_calc_silhouette_score.py +503 -0
- scitex/ml/metrics/_normalize_labels.py +83 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/__init__.py +0 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/__init__.py +3 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger.py +207 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger2020.py +238 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger913A.py +215 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/rangerqh.py +184 -0
- scitex/ml/optim/Ranger_Deep_Learning_Optimizer/setup.py +24 -0
- scitex/ml/optim/__init__.py +13 -0
- scitex/ml/optim/_get_set.py +31 -0
- scitex/ml/optim/_optimizers.py +71 -0
- scitex/ml/plt/__init__.py +60 -0
- scitex/ml/plt/_plot_conf_mat.py +663 -0
- scitex/ml/plt/_plot_feature_importance.py +323 -0
- scitex/ml/plt/_plot_learning_curve.py +345 -0
- scitex/ml/plt/_plot_optuna_study.py +225 -0
- scitex/ml/plt/_plot_pre_rec_curve.py +290 -0
- scitex/ml/plt/_plot_roc_curve.py +255 -0
- scitex/ml/sk/__init__.py +11 -0
- scitex/ml/sk/_clf.py +58 -0
- scitex/ml/sk/_to_sktime.py +100 -0
- scitex/ml/sklearn/__init__.py +26 -0
- scitex/ml/sklearn/clf.py +58 -0
- scitex/ml/sklearn/to_sktime.py +100 -0
- scitex/{ai/training/early_stopping.py → ml/training/_EarlyStopping.py} +1 -2
- scitex/{ai → ml/training}/_LearningCurveLogger.py +198 -242
- scitex/ml/training/__init__.py +7 -0
- scitex/ml/utils/__init__.py +22 -0
- scitex/ml/utils/_check_params.py +50 -0
- scitex/ml/utils/_default_dataset.py +46 -0
- scitex/ml/utils/_format_samples_for_sktime.py +26 -0
- scitex/ml/utils/_label_encoder.py +134 -0
- scitex/ml/utils/_merge_labels.py +22 -0
- scitex/ml/utils/_sliding_window_data_augmentation.py +11 -0
- scitex/ml/utils/_under_sample.py +51 -0
- scitex/ml/utils/_verify_n_gpus.py +16 -0
- scitex/ml/utils/grid_search.py +148 -0
- scitex/nn/_BNet.py +15 -9
- scitex/nn/_Filters.py +2 -2
- scitex/nn/_ModulationIndex.py +2 -2
- scitex/nn/_PAC.py +1 -1
- scitex/nn/_Spectrogram.py +12 -3
- scitex/nn/__init__.py +9 -10
- scitex/path/__init__.py +18 -0
- scitex/path/_clean.py +4 -0
- scitex/path/_find.py +9 -4
- scitex/path/_symlink.py +348 -0
- scitex/path/_version.py +4 -3
- scitex/pd/__init__.py +2 -0
- scitex/pd/_get_unique.py +99 -0
- scitex/plt/__init__.py +114 -5
- scitex/plt/_subplots/_AxesWrapper.py +1 -3
- scitex/plt/_subplots/_AxisWrapper.py +7 -3
- scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin.py +47 -13
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin.py +160 -2
- scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin.py +26 -4
- scitex/plt/_subplots/_AxisWrapperMixins/_UnitAwareMixin.py +322 -0
- scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +1 -0
- scitex/plt/_subplots/_FigWrapper.py +62 -6
- scitex/plt/_subplots/_export_as_csv.py +43 -27
- scitex/plt/_subplots/_export_as_csv_formatters/__init__.py +5 -4
- scitex/plt/_subplots/_export_as_csv_formatters/_format_annotate.py +81 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_bar.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_barh.py +20 -5
- scitex/plt/_subplots/_export_as_csv_formatters/_format_boxplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_contour.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_errorbar.py +35 -18
- scitex/plt/_subplots/_export_as_csv_formatters/_format_eventplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_fill.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_fill_between.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_hist.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow2d.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot.py +15 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_box.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_conf_mat.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_ecdf.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_fillv.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_heatmap.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_image.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_joyplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_kde.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_line.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_mean_ci.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_mean_std.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_median_iqr.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_raster.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_rectangle.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter.py +35 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter_hist.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_shaded_line.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_violin.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_scatter.py +6 -4
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_barplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_boxplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_heatmap.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_histplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_jointplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_kdeplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_lineplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_pairplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_scatterplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_stripplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_swarmplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_violinplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_text.py +60 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_violin.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/_format_violinplot.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters/test_formatters.py +1 -3
- scitex/plt/_subplots/_export_as_csv_formatters.py +56 -59
- scitex/plt/ax/_style/_hide_spines.py +1 -3
- scitex/plt/ax/_style/_rotate_labels.py +180 -76
- scitex/plt/ax/_style/_rotate_labels_v01.py +248 -0
- scitex/plt/ax/_style/_set_meta.py +11 -4
- scitex/plt/ax/_style/_set_supxyt.py +3 -3
- scitex/plt/ax/_style/_set_xyt.py +3 -3
- scitex/plt/ax/_style/_share_axes.py +2 -2
- scitex/plt/color/__init__.py +4 -4
- scitex/plt/color/{_get_colors_from_cmap.py → _get_colors_from_conf_matap.py} +7 -7
- scitex/plt/utils/_configure_mpl.py +99 -86
- scitex/plt/utils/_histogram_utils.py +1 -3
- scitex/plt/utils/_is_valid_axis.py +1 -3
- scitex/plt/utils/_scitex_config.py +1 -0
- scitex/repro/__init__.py +75 -0
- scitex/{reproduce → repro}/_gen_ID.py +1 -1
- scitex/{reproduce → repro}/_gen_timestamp.py +1 -1
- scitex/repro_rng/_RandomStateManager.py +590 -0
- scitex/repro_rng/_RandomStateManager_v01-no-verbose-options.py +414 -0
- scitex/repro_rng/__init__.py +39 -0
- scitex/reproduce/__init__.py +25 -13
- scitex/reproduce/_hash_array.py +22 -0
- scitex/resource/_get_processor_usages.py +4 -4
- scitex/resource/_get_specs.py +2 -2
- scitex/resource/_log_processor_usages.py +2 -2
- scitex/rng/_RandomStateManager.py +590 -0
- scitex/rng/_RandomStateManager_v01-no-verbose-options.py +414 -0
- scitex/rng/__init__.py +39 -0
- scitex/scholar/__init__.py +309 -19
- scitex/scholar/__main__.py +319 -0
- scitex/scholar/auth/ScholarAuthManager.py +308 -0
- scitex/scholar/auth/__init__.py +12 -0
- scitex/scholar/auth/core/AuthenticationGateway.py +473 -0
- scitex/scholar/auth/core/BrowserAuthenticator.py +386 -0
- scitex/scholar/auth/core/StrategyResolver.py +309 -0
- scitex/scholar/auth/core/__init__.py +16 -0
- scitex/scholar/auth/gateway/_OpenURLLinkFinder.py +120 -0
- scitex/scholar/auth/gateway/_OpenURLResolver.py +209 -0
- scitex/scholar/auth/gateway/__init__.py +38 -0
- scitex/scholar/auth/gateway/_resolve_functions.py +101 -0
- scitex/scholar/auth/providers/BaseAuthenticator.py +166 -0
- scitex/scholar/auth/providers/EZProxyAuthenticator.py +484 -0
- scitex/scholar/auth/providers/OpenAthensAuthenticator.py +619 -0
- scitex/scholar/auth/providers/ShibbolethAuthenticator.py +686 -0
- scitex/scholar/auth/providers/__init__.py +18 -0
- scitex/scholar/auth/session/AuthCacheManager.py +189 -0
- scitex/scholar/auth/session/SessionManager.py +159 -0
- scitex/scholar/auth/session/__init__.py +11 -0
- scitex/scholar/auth/sso/BaseSSOAutomator.py +373 -0
- scitex/scholar/auth/sso/OpenAthensSSOAutomator.py +378 -0
- scitex/scholar/auth/sso/SSOAutomator.py +180 -0
- scitex/scholar/auth/sso/UniversityOfMelbourneSSOAutomator.py +380 -0
- scitex/scholar/auth/sso/__init__.py +15 -0
- scitex/scholar/browser/ScholarBrowserManager.py +705 -0
- scitex/scholar/browser/__init__.py +38 -0
- scitex/scholar/browser/utils/__init__.py +13 -0
- scitex/scholar/browser/utils/click_and_wait.py +205 -0
- scitex/scholar/browser/utils/close_unwanted_pages.py +140 -0
- scitex/scholar/browser/utils/wait_redirects.py +732 -0
- scitex/scholar/config/PublisherRules.py +132 -0
- scitex/scholar/config/ScholarConfig.py +126 -0
- scitex/scholar/config/__init__.py +17 -0
- scitex/scholar/core/Paper.py +627 -0
- scitex/scholar/core/Papers.py +722 -0
- scitex/scholar/core/Scholar.py +1975 -0
- scitex/scholar/core/__init__.py +9 -0
- scitex/scholar/impact_factor/ImpactFactorEngine.py +204 -0
- scitex/scholar/impact_factor/__init__.py +20 -0
- scitex/scholar/impact_factor/estimation/ImpactFactorEstimationEngine.py +0 -0
- scitex/scholar/impact_factor/estimation/__init__.py +40 -0
- scitex/scholar/impact_factor/estimation/build_database.py +0 -0
- scitex/scholar/impact_factor/estimation/core/__init__.py +28 -0
- scitex/scholar/impact_factor/estimation/core/cache_manager.py +523 -0
- scitex/scholar/impact_factor/estimation/core/calculator.py +355 -0
- scitex/scholar/impact_factor/estimation/core/journal_matcher.py +428 -0
- scitex/scholar/integration/__init__.py +59 -0
- scitex/scholar/integration/base.py +502 -0
- scitex/scholar/integration/mendeley/__init__.py +22 -0
- scitex/scholar/integration/mendeley/exporter.py +166 -0
- scitex/scholar/integration/mendeley/importer.py +236 -0
- scitex/scholar/integration/mendeley/linker.py +79 -0
- scitex/scholar/integration/mendeley/mapper.py +212 -0
- scitex/scholar/integration/zotero/__init__.py +27 -0
- scitex/scholar/integration/zotero/__main__.py +264 -0
- scitex/scholar/integration/zotero/exporter.py +351 -0
- scitex/scholar/integration/zotero/importer.py +372 -0
- scitex/scholar/integration/zotero/linker.py +415 -0
- scitex/scholar/integration/zotero/mapper.py +286 -0
- scitex/scholar/metadata_engines/ScholarEngine.py +588 -0
- scitex/scholar/metadata_engines/__init__.py +21 -0
- scitex/scholar/metadata_engines/individual/ArXivEngine.py +397 -0
- scitex/scholar/metadata_engines/individual/CrossRefEngine.py +274 -0
- scitex/scholar/metadata_engines/individual/CrossRefLocalEngine.py +263 -0
- scitex/scholar/metadata_engines/individual/OpenAlexEngine.py +350 -0
- scitex/scholar/metadata_engines/individual/PubMedEngine.py +329 -0
- scitex/scholar/metadata_engines/individual/SemanticScholarEngine.py +438 -0
- scitex/scholar/metadata_engines/individual/URLDOIEngine.py +410 -0
- scitex/scholar/metadata_engines/individual/_BaseDOIEngine.py +487 -0
- scitex/scholar/metadata_engines/individual/__init__.py +7 -0
- scitex/scholar/metadata_engines/utils/_PubMedConverter.py +469 -0
- scitex/scholar/metadata_engines/utils/_URLDOIExtractor.py +283 -0
- scitex/scholar/metadata_engines/utils/__init__.py +30 -0
- scitex/scholar/metadata_engines/utils/_metadata2bibtex.py +103 -0
- scitex/scholar/metadata_engines/utils/_standardize_metadata.py +376 -0
- scitex/scholar/pdf_download/ScholarPDFDownloader.py +579 -0
- scitex/scholar/pdf_download/__init__.py +5 -0
- scitex/scholar/pdf_download/strategies/__init__.py +38 -0
- scitex/scholar/pdf_download/strategies/chrome_pdf_viewer.py +376 -0
- scitex/scholar/pdf_download/strategies/direct_download.py +131 -0
- scitex/scholar/pdf_download/strategies/manual_download_fallback.py +167 -0
- scitex/scholar/pdf_download/strategies/manual_download_utils.py +996 -0
- scitex/scholar/pdf_download/strategies/response_body.py +207 -0
- scitex/scholar/pipelines/ScholarPipelineBibTeX.py +364 -0
- scitex/scholar/pipelines/ScholarPipelineParallel.py +478 -0
- scitex/scholar/pipelines/ScholarPipelineSingle.py +767 -0
- scitex/scholar/pipelines/__init__.py +49 -0
- scitex/scholar/storage/BibTeXHandler.py +1018 -0
- scitex/scholar/storage/PaperIO.py +468 -0
- scitex/scholar/storage/ScholarLibrary.py +182 -0
- scitex/scholar/storage/_DeduplicationManager.py +548 -0
- scitex/scholar/storage/_LibraryCacheManager.py +724 -0
- scitex/scholar/storage/_LibraryManager.py +1835 -0
- scitex/scholar/storage/__init__.py +28 -0
- scitex/scholar/url_finder/ScholarURLFinder.py +379 -0
- scitex/scholar/url_finder/__init__.py +7 -0
- scitex/scholar/url_finder/strategies/__init__.py +33 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_direct_links.py +261 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_dropdown.py +67 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_href.py +204 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_navigation.py +256 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_publisher_patterns.py +165 -0
- scitex/scholar/url_finder/strategies/find_pdf_urls_by_zotero_translators.py +163 -0
- scitex/scholar/url_finder/strategies/find_supplementary_urls_by_href.py +70 -0
- scitex/scholar/utils/__init__.py +22 -0
- scitex/scholar/utils/bibtex/__init__.py +9 -0
- scitex/scholar/utils/bibtex/_parse_bibtex.py +71 -0
- scitex/scholar/utils/cleanup/__init__.py +8 -0
- scitex/scholar/utils/cleanup/_cleanup_scholar_processes.py +96 -0
- scitex/scholar/utils/cleanup/cleanup_old_extractions.py +117 -0
- scitex/scholar/utils/text/_TextNormalizer.py +407 -0
- scitex/scholar/utils/text/__init__.py +9 -0
- scitex/scholar/zotero/__init__.py +38 -0
- scitex/session/__init__.py +51 -0
- scitex/session/_lifecycle.py +736 -0
- scitex/session/_manager.py +102 -0
- scitex/session/template.py +122 -0
- scitex/stats/__init__.py +30 -26
- scitex/stats/correct/__init__.py +21 -0
- scitex/stats/correct/_correct_bonferroni.py +551 -0
- scitex/stats/correct/_correct_fdr.py +634 -0
- scitex/stats/correct/_correct_holm.py +548 -0
- scitex/stats/correct/_correct_sidak.py +499 -0
- scitex/stats/descriptive/__init__.py +85 -0
- scitex/stats/descriptive/_circular.py +540 -0
- scitex/stats/descriptive/_describe.py +219 -0
- scitex/stats/descriptive/_nan.py +518 -0
- scitex/stats/descriptive/_real.py +189 -0
- scitex/stats/effect_sizes/__init__.py +41 -0
- scitex/stats/effect_sizes/_cliffs_delta.py +325 -0
- scitex/stats/effect_sizes/_cohens_d.py +342 -0
- scitex/stats/effect_sizes/_epsilon_squared.py +315 -0
- scitex/stats/effect_sizes/_eta_squared.py +302 -0
- scitex/stats/effect_sizes/_prob_superiority.py +296 -0
- scitex/stats/posthoc/__init__.py +19 -0
- scitex/stats/posthoc/_dunnett.py +463 -0
- scitex/stats/posthoc/_games_howell.py +383 -0
- scitex/stats/posthoc/_tukey_hsd.py +367 -0
- scitex/stats/power/__init__.py +19 -0
- scitex/stats/power/_power.py +433 -0
- scitex/stats/template.py +119 -0
- scitex/stats/utils/__init__.py +62 -0
- scitex/stats/utils/_effect_size.py +985 -0
- scitex/stats/utils/_formatters.py +270 -0
- scitex/stats/utils/_normalizers.py +927 -0
- scitex/stats/utils/_power.py +433 -0
- scitex/stats_v01/_EffectSizeCalculator.py +488 -0
- scitex/stats_v01/_StatisticalValidator.py +411 -0
- scitex/stats_v01/__init__.py +60 -0
- scitex/stats_v01/_additional_tests.py +415 -0
- scitex/{stats → stats_v01}/_p2stars.py +19 -5
- scitex/stats_v01/_two_sample_tests.py +141 -0
- scitex/stats_v01/desc/__init__.py +83 -0
- scitex/stats_v01/desc/_circular.py +540 -0
- scitex/stats_v01/desc/_describe.py +219 -0
- scitex/stats_v01/desc/_nan.py +518 -0
- scitex/{stats/desc/_nan.py → stats_v01/desc/_nan_v01-20250920_145731.py} +23 -12
- scitex/stats_v01/desc/_real.py +189 -0
- scitex/stats_v01/tests/__corr_test_optimized.py +221 -0
- scitex/stats_v01/tests/_corr_test_optimized.py +179 -0
- scitex/str/__init__.py +1 -3
- scitex/str/_clean_path.py +6 -2
- scitex/str/_latex_fallback.py +267 -160
- scitex/str/_parse.py +44 -36
- scitex/str/_printc.py +1 -3
- scitex/template/__init__.py +87 -0
- scitex/template/_create_project.py +267 -0
- scitex/template/create_pip_project.py +80 -0
- scitex/template/create_research.py +80 -0
- scitex/template/create_singularity.py +80 -0
- scitex/units.py +291 -0
- scitex/utils/_compress_hdf5.py +14 -3
- scitex/utils/_email.py +21 -2
- scitex/utils/_grid.py +6 -4
- scitex/utils/_notify.py +13 -10
- scitex/utils/_verify_scitex_format.py +589 -0
- scitex/utils/_verify_scitex_format_v01.py +370 -0
- scitex/utils/template.py +122 -0
- scitex/web/_search_pubmed.py +62 -16
- scitex-2.1.0.dist-info/LICENSE +21 -0
- scitex-2.1.0.dist-info/METADATA +677 -0
- scitex-2.1.0.dist-info/RECORD +919 -0
- {scitex-2.0.0.dist-info → scitex-2.1.0.dist-info}/WHEEL +1 -1
- scitex-2.1.0.dist-info/entry_points.txt +3 -0
- scitex/ai/__Classifiers.py +0 -101
- scitex/ai/classification/classification_reporter.py +0 -1137
- scitex/ai/classification/classifiers.py +0 -101
- scitex/ai/classification_reporter.py +0 -1161
- scitex/ai/genai/__init__.py +0 -277
- scitex/ai/genai/anthropic_provider.py +0 -320
- scitex/ai/genai/anthropic_refactored.py +0 -109
- scitex/ai/genai/auth_manager.py +0 -200
- scitex/ai/genai/base_provider.py +0 -291
- scitex/ai/genai/chat_history.py +0 -307
- scitex/ai/genai/cost_tracker.py +0 -276
- scitex/ai/genai/deepseek_provider.py +0 -251
- scitex/ai/genai/google_provider.py +0 -228
- scitex/ai/genai/groq_provider.py +0 -248
- scitex/ai/genai/image_processor.py +0 -250
- scitex/ai/genai/llama_provider.py +0 -214
- scitex/ai/genai/mock_provider.py +0 -127
- scitex/ai/genai/model_registry.py +0 -304
- scitex/ai/genai/openai_provider.py +0 -293
- scitex/ai/genai/perplexity_provider.py +0 -205
- scitex/ai/genai/provider_base.py +0 -302
- scitex/ai/genai/provider_factory.py +0 -370
- scitex/ai/genai/response_handler.py +0 -235
- scitex/ai/layer/_Pass.py +0 -21
- scitex/ai/layer/__init__.py +0 -10
- scitex/ai/layer/_switch.py +0 -8
- scitex/ai/metrics/_bACC.py +0 -51
- scitex/ai/plt/_learning_curve.py +0 -194
- scitex/ai/plt/_optuna_study.py +0 -111
- scitex/ai/plt/aucs/__init__.py +0 -2
- scitex/ai/plt/aucs/example.py +0 -60
- scitex/ai/plt/aucs/pre_rec_auc.py +0 -223
- scitex/ai/plt/aucs/roc_auc.py +0 -246
- scitex/ai/sampling/undersample.py +0 -29
- scitex/db/_SQLite3.py +0 -2136
- scitex/db/_SQLite3Mixins/_BlobMixin.py +0 -229
- scitex/gen/_close.py +0 -222
- scitex/gen/_start.py +0 -451
- scitex/general/__init__.py +0 -5
- scitex/io/_load_modules/_db.py +0 -24
- scitex/life/__init__.py +0 -10
- scitex/life/_monitor_rain.py +0 -49
- scitex/reproduce/_fix_seeds.py +0 -45
- scitex/res/__init__.py +0 -5
- scitex/scholar/_local_search.py +0 -454
- scitex/scholar/_paper.py +0 -244
- scitex/scholar/_pdf_downloader.py +0 -325
- scitex/scholar/_search.py +0 -393
- scitex/scholar/_vector_search.py +0 -370
- scitex/scholar/_web_sources.py +0 -457
- scitex/stats/desc/__init__.py +0 -40
- scitex-2.0.0.dist-info/METADATA +0 -307
- scitex-2.0.0.dist-info/RECORD +0 -572
- scitex-2.0.0.dist-info/licenses/LICENSE +0 -7
- /scitex/ai/{act → activation}/__init__.py +0 -0
- /scitex/ai/{act → activation}/_define.py +0 -0
- /scitex/ai/{early_stopping.py → training/_EarlyStopping.py} +0 -0
- /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_ImportExportMixin.py +0 -0
- /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_IndexMixin.py +0 -0
- /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_RowMixin.py +0 -0
- /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_TableMixin.py +0 -0
- /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/__init__.py +0 -0
- /scitex/{stats → stats_v01}/_calc_partial_corr.py +0 -0
- /scitex/{stats → stats_v01}/_corr_test_multi.py +0 -0
- /scitex/{stats → stats_v01}/_corr_test_wrapper.py +0 -0
- /scitex/{stats → stats_v01}/_describe_wrapper.py +0 -0
- /scitex/{stats → stats_v01}/_multiple_corrections.py +0 -0
- /scitex/{stats → stats_v01}/_nan_stats.py +0 -0
- /scitex/{stats → stats_v01}/_p2stars_wrapper.py +0 -0
- /scitex/{stats → stats_v01}/_statistical_tests.py +0 -0
- /scitex/{stats/desc/_describe.py → stats_v01/desc/_describe_v01-20250920_145731.py} +0 -0
- /scitex/{stats/desc/_real.py → stats_v01/desc/_real_v01-20250920_145731.py} +0 -0
- /scitex/{stats → stats_v01}/multiple/__init__.py +0 -0
- /scitex/{stats → stats_v01}/multiple/_bonferroni_correction.py +0 -0
- /scitex/{stats → stats_v01}/multiple/_fdr_correction.py +0 -0
- /scitex/{stats → stats_v01}/multiple/_multicompair.py +0 -0
- /scitex/{stats → stats_v01}/tests/__corr_test.py +0 -0
- /scitex/{stats → stats_v01}/tests/__corr_test_multi.py +0 -0
- /scitex/{stats → stats_v01}/tests/__corr_test_single.py +0 -0
- /scitex/{stats → stats_v01}/tests/__init__.py +0 -0
- /scitex/{stats → stats_v01}/tests/_brunner_munzel_test.py +0 -0
- /scitex/{stats → stats_v01}/tests/_nocorrelation_test.py +0 -0
- /scitex/{stats → stats_v01}/tests/_smirnov_grubbs.py +0 -0
- {scitex-2.0.0.dist-info → scitex-2.1.0.dist-info}/top_level.txt +0 -0
scitex/str/_latex_fallback.py
CHANGED
|
@@ -1,13 +1,22 @@
|
|
|
1
1
|
#!/usr/bin/env python3
|
|
2
2
|
# -*- coding: utf-8 -*-
|
|
3
|
+
# Timestamp: "2025-08-21 21:37:23 (ywatanabe)"
|
|
4
|
+
# File: /home/ywatanabe/proj/scitex_repo/src/scitex/str/_latex_fallback.py
|
|
5
|
+
# ----------------------------------------
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
import os
|
|
8
|
+
__FILE__ = __file__
|
|
9
|
+
__DIR__ = os.path.dirname(__FILE__)
|
|
10
|
+
# ----------------------------------------
|
|
11
|
+
|
|
3
12
|
# Time-stamp: "2025-06-05 12:00:00 (ywatanabe)"
|
|
4
|
-
|
|
13
|
+
|
|
5
14
|
|
|
6
15
|
"""
|
|
7
16
|
LaTeX Fallback Mechanism for SciTeX
|
|
8
17
|
|
|
9
18
|
This module provides a robust fallback system for LaTeX rendering issues.
|
|
10
|
-
When LaTeX compilation fails (e.g., missing fonts, Node.js conflicts),
|
|
19
|
+
When LaTeX compilation fails (e.g., missing fonts, Node.js conflicts),
|
|
11
20
|
it gracefully degrades to mathtext or plain text alternatives.
|
|
12
21
|
|
|
13
22
|
Functionality:
|
|
@@ -24,18 +33,24 @@ Prerequisites:
|
|
|
24
33
|
"""
|
|
25
34
|
|
|
26
35
|
import functools
|
|
27
|
-
import logging
|
|
28
36
|
import re
|
|
29
|
-
import
|
|
30
|
-
|
|
37
|
+
from typing import Any, Callable, Dict
|
|
38
|
+
|
|
39
|
+
# matplotlib imports moved to functions that need them
|
|
40
|
+
|
|
41
|
+
# Delay logging import to avoid circular dependency
|
|
42
|
+
# scitex.logging imports _Tee which imports scitex.str which imports this file
|
|
43
|
+
def _get_logger():
|
|
44
|
+
"""Get logger lazily to avoid circular import."""
|
|
45
|
+
from scitex import logging
|
|
46
|
+
return logging.getLogger(__name__)
|
|
31
47
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
48
|
+
# Use property-like access for logger
|
|
49
|
+
class _LoggerProxy:
|
|
50
|
+
def __getattr__(self, name):
|
|
51
|
+
return getattr(_get_logger(), name)
|
|
36
52
|
|
|
37
|
-
|
|
38
|
-
logger = logging.getLogger(__name__)
|
|
53
|
+
logger = _LoggerProxy()
|
|
39
54
|
|
|
40
55
|
# Global state for LaTeX capability
|
|
41
56
|
_latex_available = None
|
|
@@ -44,13 +59,14 @@ _fallback_mode = "auto" # "auto", "force_mathtext", "force_plain"
|
|
|
44
59
|
|
|
45
60
|
class LaTeXFallbackError(Exception):
|
|
46
61
|
"""Raised when LaTeX fallback mechanisms fail."""
|
|
62
|
+
|
|
47
63
|
pass
|
|
48
64
|
|
|
49
65
|
|
|
50
66
|
def set_fallback_mode(mode: str) -> None:
|
|
51
67
|
"""
|
|
52
68
|
Set the global fallback mode for LaTeX rendering.
|
|
53
|
-
|
|
69
|
+
|
|
54
70
|
Parameters
|
|
55
71
|
----------
|
|
56
72
|
mode : str
|
|
@@ -74,34 +90,41 @@ def get_fallback_mode() -> str:
|
|
|
74
90
|
def check_latex_capability() -> bool:
|
|
75
91
|
"""
|
|
76
92
|
Check if LaTeX rendering is available and working.
|
|
77
|
-
|
|
93
|
+
|
|
78
94
|
Returns
|
|
79
95
|
-------
|
|
80
96
|
bool
|
|
81
97
|
True if LaTeX is available, False otherwise
|
|
82
98
|
"""
|
|
83
|
-
global _latex_available
|
|
84
|
-
|
|
99
|
+
global _latex_available
|
|
100
|
+
|
|
101
|
+
# Import matplotlib here when actually needed
|
|
102
|
+
try:
|
|
103
|
+
import matplotlib.pyplot as plt
|
|
104
|
+
except ImportError:
|
|
105
|
+
_latex_available = False
|
|
106
|
+
return False
|
|
107
|
+
|
|
85
108
|
# If forcing a mode, return accordingly
|
|
86
109
|
if _fallback_mode == "force_mathtext" or _fallback_mode == "force_plain":
|
|
87
110
|
_latex_available = False
|
|
88
111
|
return False
|
|
89
|
-
|
|
112
|
+
|
|
90
113
|
# Cache the result if already determined
|
|
91
114
|
if _latex_available is not None:
|
|
92
115
|
return _latex_available
|
|
93
|
-
|
|
116
|
+
|
|
94
117
|
try:
|
|
95
118
|
# Test if LaTeX is configured
|
|
96
|
-
if not plt.rcParams.get(
|
|
119
|
+
if not plt.rcParams.get("text.usetex", False):
|
|
97
120
|
_latex_available = False
|
|
98
121
|
return False
|
|
99
|
-
|
|
122
|
+
|
|
100
123
|
# Try a simple LaTeX rendering test
|
|
101
124
|
fig, ax = plt.subplots(figsize=(1, 1))
|
|
102
125
|
try:
|
|
103
126
|
# Test with a simple LaTeX expression
|
|
104
|
-
text_obj = ax.text(0.5, 0.5, r
|
|
127
|
+
text_obj = ax.text(0.5, 0.5, r"$x^2$", usetex=True)
|
|
105
128
|
fig.canvas.draw() # Force rendering
|
|
106
129
|
_latex_available = True
|
|
107
130
|
result = True
|
|
@@ -111,9 +134,9 @@ def check_latex_capability() -> bool:
|
|
|
111
134
|
result = False
|
|
112
135
|
finally:
|
|
113
136
|
plt.close(fig)
|
|
114
|
-
|
|
137
|
+
|
|
115
138
|
return result
|
|
116
|
-
|
|
139
|
+
|
|
117
140
|
except Exception as e:
|
|
118
141
|
logger.debug(f"LaTeX capability check failed: {e}")
|
|
119
142
|
_latex_available = False
|
|
@@ -123,12 +146,12 @@ def check_latex_capability() -> bool:
|
|
|
123
146
|
def latex_to_mathtext(latex_str: str) -> str:
|
|
124
147
|
"""
|
|
125
148
|
Convert LaTeX syntax to matplotlib mathtext equivalent.
|
|
126
|
-
|
|
149
|
+
|
|
127
150
|
Parameters
|
|
128
151
|
----------
|
|
129
152
|
latex_str : str
|
|
130
153
|
LaTeX string to convert
|
|
131
|
-
|
|
154
|
+
|
|
132
155
|
Returns
|
|
133
156
|
-------
|
|
134
157
|
str
|
|
@@ -136,85 +159,79 @@ def latex_to_mathtext(latex_str: str) -> str:
|
|
|
136
159
|
"""
|
|
137
160
|
if not latex_str:
|
|
138
161
|
return latex_str
|
|
139
|
-
|
|
162
|
+
|
|
140
163
|
# Remove outer $ if present
|
|
141
164
|
text = latex_str.strip()
|
|
142
|
-
if text.startswith(
|
|
165
|
+
if text.startswith("$") and text.endswith("$"):
|
|
143
166
|
text = text[1:-1]
|
|
144
|
-
|
|
167
|
+
|
|
145
168
|
# Common LaTeX to mathtext conversions
|
|
146
169
|
conversions = {
|
|
147
170
|
# Greek letters
|
|
148
|
-
r
|
|
149
|
-
r
|
|
150
|
-
r
|
|
151
|
-
r
|
|
152
|
-
r
|
|
153
|
-
r
|
|
154
|
-
r
|
|
155
|
-
r
|
|
156
|
-
r
|
|
157
|
-
r
|
|
158
|
-
r
|
|
159
|
-
r
|
|
160
|
-
r
|
|
161
|
-
|
|
171
|
+
r"\\alpha": r"\alpha",
|
|
172
|
+
r"\\beta": r"\beta",
|
|
173
|
+
r"\\gamma": r"\gamma",
|
|
174
|
+
r"\\delta": r"\delta",
|
|
175
|
+
r"\\epsilon": r"\epsilon",
|
|
176
|
+
r"\\theta": r"\theta",
|
|
177
|
+
r"\\lambda": r"\lambda",
|
|
178
|
+
r"\\mu": r"\mu",
|
|
179
|
+
r"\\pi": r"\pi",
|
|
180
|
+
r"\\sigma": r"\sigma",
|
|
181
|
+
r"\\tau": r"\tau",
|
|
182
|
+
r"\\phi": r"\phi",
|
|
183
|
+
r"\\omega": r"\omega",
|
|
162
184
|
# Mathematical symbols
|
|
163
|
-
r
|
|
164
|
-
r
|
|
165
|
-
r
|
|
166
|
-
r
|
|
167
|
-
r
|
|
168
|
-
r
|
|
169
|
-
r
|
|
170
|
-
r
|
|
171
|
-
r
|
|
172
|
-
r
|
|
173
|
-
r
|
|
174
|
-
|
|
185
|
+
r"\\sum": r"\sum",
|
|
186
|
+
r"\\int": r"\int",
|
|
187
|
+
r"\\partial": r"\partial",
|
|
188
|
+
r"\\infty": r"\infty",
|
|
189
|
+
r"\\pm": r"\pm",
|
|
190
|
+
r"\\times": r"\times",
|
|
191
|
+
r"\\cdot": r"\cdot",
|
|
192
|
+
r"\\approx": r"\approx",
|
|
193
|
+
r"\\neq": r"\neq",
|
|
194
|
+
r"\\leq": r"\leq",
|
|
195
|
+
r"\\geq": r"\geq",
|
|
175
196
|
# Functions
|
|
176
|
-
r
|
|
177
|
-
r
|
|
178
|
-
r
|
|
179
|
-
r
|
|
180
|
-
r
|
|
181
|
-
r
|
|
182
|
-
|
|
197
|
+
r"\\sin": r"\sin",
|
|
198
|
+
r"\\cos": r"\cos",
|
|
199
|
+
r"\\tan": r"\tan",
|
|
200
|
+
r"\\log": r"\log",
|
|
201
|
+
r"\\ln": r"\ln",
|
|
202
|
+
r"\\exp": r"\exp",
|
|
183
203
|
# Formatting (limited mathtext support)
|
|
184
|
-
r
|
|
185
|
-
r
|
|
186
|
-
r
|
|
187
|
-
r
|
|
188
|
-
|
|
204
|
+
r"\\textbf\{([^}]+)\}": r"\mathbf{\1}",
|
|
205
|
+
r"\\mathbf\{([^}]+)\}": r"\mathbf{\1}",
|
|
206
|
+
r"\\textit\{([^}]+)\}": r"\mathit{\1}",
|
|
207
|
+
r"\\mathit\{([^}]+)\}": r"\mathit{\1}",
|
|
189
208
|
# Hats and accents
|
|
190
|
-
r
|
|
191
|
-
r
|
|
192
|
-
r
|
|
193
|
-
|
|
209
|
+
r"\\hat\{([^}]+)\}": r"\hat{\1}",
|
|
210
|
+
r"\\overrightarrow\{([^}]+)\}": r"\vec{\1}",
|
|
211
|
+
r"\\vec\{([^}]+)\}": r"\vec{\1}",
|
|
194
212
|
# Fractions (simple ones)
|
|
195
|
-
r
|
|
196
|
-
|
|
213
|
+
r"\\frac\{([^}]+)\}\{([^}]+)\}": r"\frac{\1}{\2}",
|
|
197
214
|
# Subscripts and superscripts (should work as-is)
|
|
198
215
|
# Powers and indices are handled naturally by mathtext
|
|
199
216
|
}
|
|
200
|
-
|
|
217
|
+
|
|
201
218
|
# Apply conversions
|
|
202
219
|
for latex_pattern, mathtext_replacement in conversions.items():
|
|
203
220
|
text = re.sub(latex_pattern, mathtext_replacement, text)
|
|
204
|
-
|
|
221
|
+
|
|
205
222
|
# Wrap in mathtext markers
|
|
206
|
-
return f
|
|
223
|
+
return f"${text}$"
|
|
207
224
|
|
|
208
225
|
|
|
209
226
|
def latex_to_unicode(latex_str: str) -> str:
|
|
210
227
|
"""
|
|
211
228
|
Convert LaTeX to Unicode plain text equivalent.
|
|
212
|
-
|
|
229
|
+
|
|
213
230
|
Parameters
|
|
214
231
|
----------
|
|
215
232
|
latex_str : str
|
|
216
233
|
LaTeX string to convert
|
|
217
|
-
|
|
234
|
+
|
|
218
235
|
Returns
|
|
219
236
|
-------
|
|
220
237
|
str
|
|
@@ -222,76 +239,145 @@ def latex_to_unicode(latex_str: str) -> str:
|
|
|
222
239
|
"""
|
|
223
240
|
if not latex_str:
|
|
224
241
|
return latex_str
|
|
225
|
-
|
|
242
|
+
|
|
226
243
|
# Remove outer $ if present
|
|
227
244
|
text = latex_str.strip()
|
|
228
|
-
if text.startswith(
|
|
245
|
+
if text.startswith("$") and text.endswith("$"):
|
|
229
246
|
text = text[1:-1]
|
|
230
|
-
|
|
247
|
+
|
|
231
248
|
# Greek letters to Unicode
|
|
232
249
|
greek_conversions = {
|
|
233
|
-
r
|
|
234
|
-
r
|
|
235
|
-
r
|
|
236
|
-
r
|
|
237
|
-
r
|
|
238
|
-
r
|
|
239
|
-
|
|
250
|
+
r"\\alpha": "α",
|
|
251
|
+
r"\\beta": "β",
|
|
252
|
+
r"\\gamma": "γ",
|
|
253
|
+
r"\\delta": "δ",
|
|
254
|
+
r"\\epsilon": "ε",
|
|
255
|
+
r"\\zeta": "ζ",
|
|
256
|
+
r"\\eta": "η",
|
|
257
|
+
r"\\theta": "θ",
|
|
258
|
+
r"\\iota": "ι",
|
|
259
|
+
r"\\kappa": "κ",
|
|
260
|
+
r"\\lambda": "λ",
|
|
261
|
+
r"\\mu": "μ",
|
|
262
|
+
r"\\nu": "ν",
|
|
263
|
+
r"\\xi": "ξ",
|
|
264
|
+
r"\\pi": "π",
|
|
265
|
+
r"\\rho": "ρ",
|
|
266
|
+
r"\\sigma": "σ",
|
|
267
|
+
r"\\tau": "τ",
|
|
268
|
+
r"\\upsilon": "υ",
|
|
269
|
+
r"\\phi": "φ",
|
|
270
|
+
r"\\chi": "χ",
|
|
271
|
+
r"\\psi": "ψ",
|
|
272
|
+
r"\\omega": "ω",
|
|
240
273
|
# Capital Greek
|
|
241
|
-
r
|
|
242
|
-
r
|
|
243
|
-
r
|
|
274
|
+
r"\\Gamma": "Γ",
|
|
275
|
+
r"\\Delta": "Δ",
|
|
276
|
+
r"\\Theta": "Θ",
|
|
277
|
+
r"\\Lambda": "Λ",
|
|
278
|
+
r"\\Xi": "Ξ",
|
|
279
|
+
r"\\Pi": "Π",
|
|
280
|
+
r"\\Sigma": "Σ",
|
|
281
|
+
r"\\Upsilon": "Υ",
|
|
282
|
+
r"\\Phi": "Φ",
|
|
283
|
+
r"\\Psi": "Ψ",
|
|
284
|
+
r"\\Omega": "Ω",
|
|
244
285
|
}
|
|
245
|
-
|
|
286
|
+
|
|
246
287
|
# Mathematical symbols to Unicode
|
|
247
288
|
symbol_conversions = {
|
|
248
|
-
r
|
|
249
|
-
r
|
|
250
|
-
r
|
|
251
|
-
r
|
|
289
|
+
r"\\pm": "±",
|
|
290
|
+
r"\\times": "×",
|
|
291
|
+
r"\\cdot": "·",
|
|
292
|
+
r"\\div": "÷",
|
|
293
|
+
r"\\neq": "≠",
|
|
294
|
+
r"\\leq": "≤",
|
|
295
|
+
r"\\geq": "≥",
|
|
296
|
+
r"\\approx": "≈",
|
|
297
|
+
r"\\infty": "∞",
|
|
298
|
+
r"\\partial": "∂",
|
|
299
|
+
r"\\sum": "∑",
|
|
300
|
+
r"\\int": "∫",
|
|
301
|
+
r"\\sqrt": "√",
|
|
302
|
+
r"\\angle": "∠",
|
|
303
|
+
r"\\degree": "°",
|
|
252
304
|
}
|
|
253
|
-
|
|
305
|
+
|
|
254
306
|
# Superscript numbers
|
|
255
307
|
superscript_conversions = {
|
|
256
|
-
r
|
|
257
|
-
r
|
|
258
|
-
r
|
|
259
|
-
r
|
|
260
|
-
r
|
|
308
|
+
r"\^0": "⁰",
|
|
309
|
+
r"\^1": "¹",
|
|
310
|
+
r"\^2": "²",
|
|
311
|
+
r"\^3": "³",
|
|
312
|
+
r"\^4": "⁴",
|
|
313
|
+
r"\^5": "⁵",
|
|
314
|
+
r"\^6": "⁶",
|
|
315
|
+
r"\^7": "⁷",
|
|
316
|
+
r"\^8": "⁸",
|
|
317
|
+
r"\^9": "⁹",
|
|
318
|
+
r"\^\{0\}": "⁰",
|
|
319
|
+
r"\^\{1\}": "¹",
|
|
320
|
+
r"\^\{2\}": "²",
|
|
321
|
+
r"\^\{3\}": "³",
|
|
322
|
+
r"\^\{4\}": "⁴",
|
|
323
|
+
r"\^\{5\}": "⁵",
|
|
324
|
+
r"\^\{6\}": "⁶",
|
|
325
|
+
r"\^\{7\}": "⁷",
|
|
326
|
+
r"\^\{8\}": "⁸",
|
|
327
|
+
r"\^\{9\}": "⁹",
|
|
261
328
|
}
|
|
262
|
-
|
|
329
|
+
|
|
263
330
|
# Subscript numbers
|
|
264
331
|
subscript_conversions = {
|
|
265
|
-
r
|
|
266
|
-
r
|
|
267
|
-
r
|
|
268
|
-
r
|
|
269
|
-
r
|
|
332
|
+
r"_0": "₀",
|
|
333
|
+
r"_1": "₁",
|
|
334
|
+
r"_2": "₂",
|
|
335
|
+
r"_3": "₃",
|
|
336
|
+
r"_4": "₄",
|
|
337
|
+
r"_5": "₅",
|
|
338
|
+
r"_6": "₆",
|
|
339
|
+
r"_7": "₇",
|
|
340
|
+
r"_8": "₈",
|
|
341
|
+
r"_9": "₉",
|
|
342
|
+
r"_\{0\}": "₀",
|
|
343
|
+
r"_\{1\}": "₁",
|
|
344
|
+
r"_\{2\}": "₂",
|
|
345
|
+
r"_\{3\}": "₃",
|
|
346
|
+
r"_\{4\}": "₄",
|
|
347
|
+
r"_\{5\}": "₅",
|
|
348
|
+
r"_\{6\}": "₆",
|
|
349
|
+
r"_\{7\}": "₇",
|
|
350
|
+
r"_\{8\}": "₈",
|
|
351
|
+
r"_\{9\}": "₉",
|
|
270
352
|
}
|
|
271
|
-
|
|
353
|
+
|
|
272
354
|
# Apply all conversions
|
|
273
|
-
all_conversions = {
|
|
274
|
-
|
|
275
|
-
|
|
355
|
+
all_conversions = {
|
|
356
|
+
**greek_conversions,
|
|
357
|
+
**symbol_conversions,
|
|
358
|
+
**superscript_conversions,
|
|
359
|
+
**subscript_conversions,
|
|
360
|
+
}
|
|
361
|
+
|
|
276
362
|
for latex_pattern, unicode_char in all_conversions.items():
|
|
277
363
|
text = re.sub(latex_pattern, unicode_char, text)
|
|
278
|
-
|
|
364
|
+
|
|
279
365
|
# Remove remaining LaTeX commands (simple cleanup)
|
|
280
|
-
text = re.sub(
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
366
|
+
text = re.sub(
|
|
367
|
+
r"\\[a-zA-Z]+\{([^}]*)\}", r"\1", text
|
|
368
|
+
) # \command{content} -> content
|
|
369
|
+
text = re.sub(r"\\[a-zA-Z]+", "", text) # \command -> remove
|
|
370
|
+
text = re.sub(r"[{}]", "", text) # Remove remaining braces
|
|
371
|
+
|
|
284
372
|
return text
|
|
285
373
|
|
|
286
374
|
|
|
287
375
|
def safe_latex_render(
|
|
288
|
-
text: str,
|
|
289
|
-
fallback_strategy: str = "auto",
|
|
290
|
-
preserve_math: bool = True
|
|
376
|
+
text: str, fallback_strategy: str = "auto", preserve_math: bool = True
|
|
291
377
|
) -> str:
|
|
292
378
|
"""
|
|
293
379
|
Safely render LaTeX text with automatic fallback.
|
|
294
|
-
|
|
380
|
+
|
|
295
381
|
Parameters
|
|
296
382
|
----------
|
|
297
383
|
text : str
|
|
@@ -300,7 +386,7 @@ def safe_latex_render(
|
|
|
300
386
|
Strategy when LaTeX fails: "auto", "mathtext", "unicode", "plain"
|
|
301
387
|
preserve_math : bool, optional
|
|
302
388
|
Whether to preserve mathematical notation in fallbacks
|
|
303
|
-
|
|
389
|
+
|
|
304
390
|
Returns
|
|
305
391
|
-------
|
|
306
392
|
str
|
|
@@ -308,12 +394,13 @@ def safe_latex_render(
|
|
|
308
394
|
"""
|
|
309
395
|
if not text or not isinstance(text, str):
|
|
310
396
|
return text
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
397
|
+
|
|
398
|
+
# Import matplotlib when needed
|
|
399
|
+
import matplotlib.pyplot as plt
|
|
400
|
+
|
|
314
401
|
# Determine if we should attempt LaTeX
|
|
315
|
-
use_latex =
|
|
316
|
-
|
|
402
|
+
use_latex = _fallback_mode == "auto" and check_latex_capability()
|
|
403
|
+
|
|
317
404
|
if use_latex:
|
|
318
405
|
# Try LaTeX first
|
|
319
406
|
try:
|
|
@@ -330,54 +417,54 @@ def safe_latex_render(
|
|
|
330
417
|
except Exception:
|
|
331
418
|
# Fall through to fallback strategies
|
|
332
419
|
pass
|
|
333
|
-
|
|
420
|
+
|
|
334
421
|
# Apply fallback strategy
|
|
335
422
|
if fallback_strategy == "auto":
|
|
336
423
|
# Automatically choose best fallback
|
|
337
|
-
if preserve_math and (
|
|
424
|
+
if preserve_math and ("$" in text or "\\" in text):
|
|
338
425
|
try:
|
|
339
426
|
return latex_to_mathtext(text)
|
|
340
427
|
except Exception:
|
|
341
428
|
return latex_to_unicode(text)
|
|
342
429
|
else:
|
|
343
430
|
return latex_to_unicode(text)
|
|
344
|
-
|
|
431
|
+
|
|
345
432
|
elif fallback_strategy == "mathtext":
|
|
346
433
|
return latex_to_mathtext(text)
|
|
347
|
-
|
|
434
|
+
|
|
348
435
|
elif fallback_strategy == "unicode":
|
|
349
436
|
return latex_to_unicode(text)
|
|
350
|
-
|
|
437
|
+
|
|
351
438
|
elif fallback_strategy == "plain":
|
|
352
439
|
# Strip all LaTeX and return plain text
|
|
353
440
|
plain = latex_to_unicode(text)
|
|
354
441
|
# Remove any remaining special characters
|
|
355
|
-
plain = re.sub(r
|
|
442
|
+
plain = re.sub(r"[^\w\s\(\)\[\].,;:!?-]", "", plain)
|
|
356
443
|
return plain
|
|
357
|
-
|
|
444
|
+
|
|
358
445
|
else:
|
|
359
446
|
raise ValueError(f"Unknown fallback strategy: {fallback_strategy}")
|
|
360
447
|
|
|
361
448
|
|
|
362
449
|
def latex_fallback_decorator(
|
|
363
|
-
fallback_strategy: str = "auto",
|
|
364
|
-
preserve_math: bool = True
|
|
450
|
+
fallback_strategy: str = "auto", preserve_math: bool = True
|
|
365
451
|
):
|
|
366
452
|
"""
|
|
367
453
|
Decorator to add LaTeX fallback capability to functions.
|
|
368
|
-
|
|
454
|
+
|
|
369
455
|
Parameters
|
|
370
456
|
----------
|
|
371
457
|
fallback_strategy : str, optional
|
|
372
458
|
Fallback strategy to use
|
|
373
459
|
preserve_math : bool, optional
|
|
374
460
|
Whether to preserve mathematical notation
|
|
375
|
-
|
|
461
|
+
|
|
376
462
|
Returns
|
|
377
463
|
-------
|
|
378
464
|
callable
|
|
379
465
|
Decorated function with LaTeX fallback
|
|
380
466
|
"""
|
|
467
|
+
|
|
381
468
|
def decorator(func: Callable) -> Callable:
|
|
382
469
|
@functools.wraps(func)
|
|
383
470
|
def wrapper(*args, **kwargs):
|
|
@@ -387,24 +474,38 @@ def latex_fallback_decorator(
|
|
|
387
474
|
# Check if this is a LaTeX-related error
|
|
388
475
|
error_str = str(e).lower()
|
|
389
476
|
latex_error_indicators = [
|
|
390
|
-
|
|
391
|
-
|
|
477
|
+
"latex",
|
|
478
|
+
"tex",
|
|
479
|
+
"dvi",
|
|
480
|
+
"tfm",
|
|
481
|
+
"font",
|
|
482
|
+
"usetex",
|
|
483
|
+
"kpathsea",
|
|
484
|
+
"dvipng",
|
|
485
|
+
"ghostscript",
|
|
392
486
|
]
|
|
393
|
-
|
|
394
|
-
if any(
|
|
487
|
+
|
|
488
|
+
if any(
|
|
489
|
+
indicator in error_str
|
|
490
|
+
for indicator in latex_error_indicators
|
|
491
|
+
):
|
|
395
492
|
logger.warning(f"LaTeX error in {func.__name__}: {e}")
|
|
396
|
-
logger.warning(
|
|
397
|
-
|
|
493
|
+
logger.warning(
|
|
494
|
+
"Falling back to alternative text rendering"
|
|
495
|
+
)
|
|
496
|
+
|
|
398
497
|
# Try to apply fallback to string arguments
|
|
399
498
|
new_args = []
|
|
400
499
|
for arg in args:
|
|
401
500
|
if isinstance(arg, str):
|
|
402
|
-
new_args.append(
|
|
403
|
-
|
|
404
|
-
|
|
501
|
+
new_args.append(
|
|
502
|
+
safe_latex_render(
|
|
503
|
+
arg, fallback_strategy, preserve_math
|
|
504
|
+
)
|
|
505
|
+
)
|
|
405
506
|
else:
|
|
406
507
|
new_args.append(arg)
|
|
407
|
-
|
|
508
|
+
|
|
408
509
|
new_kwargs = {}
|
|
409
510
|
for key, value in kwargs.items():
|
|
410
511
|
if isinstance(value, str):
|
|
@@ -413,39 +514,46 @@ def latex_fallback_decorator(
|
|
|
413
514
|
)
|
|
414
515
|
else:
|
|
415
516
|
new_kwargs[key] = value
|
|
416
|
-
|
|
517
|
+
|
|
518
|
+
# Import matplotlib when needed
|
|
519
|
+
import matplotlib.pyplot as plt
|
|
520
|
+
|
|
417
521
|
# Temporarily disable LaTeX for this call
|
|
418
|
-
original_usetex = plt.rcParams.get(
|
|
419
|
-
plt.rcParams[
|
|
420
|
-
|
|
522
|
+
original_usetex = plt.rcParams.get("text.usetex", False)
|
|
523
|
+
plt.rcParams["text.usetex"] = False
|
|
524
|
+
|
|
421
525
|
try:
|
|
422
526
|
result = func(*new_args, **new_kwargs)
|
|
423
527
|
return result
|
|
424
528
|
finally:
|
|
425
|
-
plt.rcParams[
|
|
529
|
+
plt.rcParams["text.usetex"] = original_usetex
|
|
426
530
|
else:
|
|
427
531
|
# Re-raise non-LaTeX errors
|
|
428
532
|
raise
|
|
533
|
+
|
|
429
534
|
return wrapper
|
|
535
|
+
|
|
430
536
|
return decorator
|
|
431
537
|
|
|
432
538
|
|
|
433
539
|
def get_latex_status() -> Dict[str, Any]:
|
|
434
540
|
"""
|
|
435
541
|
Get comprehensive LaTeX status information.
|
|
436
|
-
|
|
542
|
+
|
|
437
543
|
Returns
|
|
438
544
|
-------
|
|
439
545
|
Dict[str, Any]
|
|
440
546
|
Status information including capability, mode, and configuration
|
|
441
547
|
"""
|
|
548
|
+
import matplotlib.pyplot as plt
|
|
549
|
+
|
|
442
550
|
return {
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
551
|
+
"latex_available": check_latex_capability(),
|
|
552
|
+
"fallback_mode": get_fallback_mode(),
|
|
553
|
+
"usetex_enabled": plt.rcParams.get("text.usetex", False),
|
|
554
|
+
"mathtext_fontset": plt.rcParams.get("mathtext.fontset", "cm"),
|
|
555
|
+
"font_family": plt.rcParams.get("font.family", ["serif"]),
|
|
556
|
+
"cache_info": check_latex_capability.cache_info()._asdict(),
|
|
449
557
|
}
|
|
450
558
|
|
|
451
559
|
|
|
@@ -467,5 +575,4 @@ def reset_latex_cache() -> None:
|
|
|
467
575
|
global _latex_available
|
|
468
576
|
_latex_available = None
|
|
469
577
|
|
|
470
|
-
|
|
471
|
-
# EOF
|
|
578
|
+
# EOF
|