scitex 2.0.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 +73 -0
- scitex/__main__.py +89 -0
- scitex/__version__.py +14 -0
- scitex/_sh.py +59 -0
- scitex/ai/_LearningCurveLogger.py +583 -0
- scitex/ai/__Classifiers.py +101 -0
- scitex/ai/__init__.py +55 -0
- scitex/ai/_gen_ai/_Anthropic.py +173 -0
- scitex/ai/_gen_ai/_BaseGenAI.py +336 -0
- scitex/ai/_gen_ai/_DeepSeek.py +175 -0
- scitex/ai/_gen_ai/_Google.py +161 -0
- scitex/ai/_gen_ai/_Groq.py +97 -0
- scitex/ai/_gen_ai/_Llama.py +142 -0
- scitex/ai/_gen_ai/_OpenAI.py +230 -0
- scitex/ai/_gen_ai/_PARAMS.py +565 -0
- scitex/ai/_gen_ai/_Perplexity.py +191 -0
- scitex/ai/_gen_ai/__init__.py +32 -0
- scitex/ai/_gen_ai/_calc_cost.py +78 -0
- scitex/ai/_gen_ai/_format_output_func.py +183 -0
- scitex/ai/_gen_ai/_genai_factory.py +71 -0
- scitex/ai/act/__init__.py +8 -0
- scitex/ai/act/_define.py +11 -0
- scitex/ai/classification/__init__.py +7 -0
- scitex/ai/classification/classification_reporter.py +1137 -0
- scitex/ai/classification/classifier_server.py +131 -0
- scitex/ai/classification/classifiers.py +101 -0
- scitex/ai/classification_reporter.py +1161 -0
- scitex/ai/classifier_server.py +131 -0
- scitex/ai/clustering/__init__.py +11 -0
- scitex/ai/clustering/_pca.py +115 -0
- scitex/ai/clustering/_umap.py +376 -0
- scitex/ai/early_stopping.py +149 -0
- scitex/ai/feature_extraction/__init__.py +56 -0
- scitex/ai/feature_extraction/vit.py +148 -0
- scitex/ai/genai/__init__.py +277 -0
- scitex/ai/genai/anthropic.py +177 -0
- scitex/ai/genai/anthropic_provider.py +320 -0
- scitex/ai/genai/anthropic_refactored.py +109 -0
- scitex/ai/genai/auth_manager.py +200 -0
- scitex/ai/genai/base_genai.py +336 -0
- scitex/ai/genai/base_provider.py +291 -0
- scitex/ai/genai/calc_cost.py +78 -0
- scitex/ai/genai/chat_history.py +307 -0
- scitex/ai/genai/cost_tracker.py +276 -0
- scitex/ai/genai/deepseek.py +188 -0
- scitex/ai/genai/deepseek_provider.py +251 -0
- scitex/ai/genai/format_output_func.py +183 -0
- scitex/ai/genai/genai_factory.py +71 -0
- scitex/ai/genai/google.py +169 -0
- scitex/ai/genai/google_provider.py +228 -0
- scitex/ai/genai/groq.py +104 -0
- scitex/ai/genai/groq_provider.py +248 -0
- scitex/ai/genai/image_processor.py +250 -0
- scitex/ai/genai/llama.py +155 -0
- scitex/ai/genai/llama_provider.py +214 -0
- scitex/ai/genai/mock_provider.py +127 -0
- scitex/ai/genai/model_registry.py +304 -0
- scitex/ai/genai/openai.py +230 -0
- scitex/ai/genai/openai_provider.py +293 -0
- scitex/ai/genai/params.py +565 -0
- scitex/ai/genai/perplexity.py +202 -0
- scitex/ai/genai/perplexity_provider.py +205 -0
- scitex/ai/genai/provider_base.py +302 -0
- scitex/ai/genai/provider_factory.py +370 -0
- scitex/ai/genai/response_handler.py +235 -0
- scitex/ai/layer/_Pass.py +21 -0
- scitex/ai/layer/__init__.py +10 -0
- scitex/ai/layer/_switch.py +8 -0
- scitex/ai/loss/_L1L2Losses.py +34 -0
- scitex/ai/loss/__init__.py +12 -0
- scitex/ai/loss/multi_task_loss.py +47 -0
- scitex/ai/metrics/__init__.py +9 -0
- scitex/ai/metrics/_bACC.py +51 -0
- scitex/ai/metrics/silhoute_score_block.py +496 -0
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/__init__.py +0 -0
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/__init__.py +3 -0
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger.py +207 -0
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger2020.py +238 -0
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger913A.py +215 -0
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/rangerqh.py +184 -0
- scitex/ai/optim/Ranger_Deep_Learning_Optimizer/setup.py +24 -0
- scitex/ai/optim/__init__.py +13 -0
- scitex/ai/optim/_get_set.py +31 -0
- scitex/ai/optim/_optimizers.py +71 -0
- scitex/ai/plt/__init__.py +21 -0
- scitex/ai/plt/_conf_mat.py +592 -0
- scitex/ai/plt/_learning_curve.py +194 -0
- scitex/ai/plt/_optuna_study.py +111 -0
- scitex/ai/plt/aucs/__init__.py +2 -0
- scitex/ai/plt/aucs/example.py +60 -0
- scitex/ai/plt/aucs/pre_rec_auc.py +223 -0
- scitex/ai/plt/aucs/roc_auc.py +246 -0
- scitex/ai/sampling/undersample.py +29 -0
- scitex/ai/sk/__init__.py +11 -0
- scitex/ai/sk/_clf.py +58 -0
- scitex/ai/sk/_to_sktime.py +100 -0
- scitex/ai/sklearn/__init__.py +26 -0
- scitex/ai/sklearn/clf.py +58 -0
- scitex/ai/sklearn/to_sktime.py +100 -0
- scitex/ai/training/__init__.py +7 -0
- scitex/ai/training/early_stopping.py +150 -0
- scitex/ai/training/learning_curve_logger.py +555 -0
- scitex/ai/utils/__init__.py +22 -0
- scitex/ai/utils/_check_params.py +50 -0
- scitex/ai/utils/_default_dataset.py +46 -0
- scitex/ai/utils/_format_samples_for_sktime.py +26 -0
- scitex/ai/utils/_label_encoder.py +134 -0
- scitex/ai/utils/_merge_labels.py +22 -0
- scitex/ai/utils/_sliding_window_data_augmentation.py +11 -0
- scitex/ai/utils/_under_sample.py +51 -0
- scitex/ai/utils/_verify_n_gpus.py +16 -0
- scitex/ai/utils/grid_search.py +148 -0
- scitex/context/__init__.py +9 -0
- scitex/context/_suppress_output.py +38 -0
- scitex/db/_BaseMixins/_BaseBackupMixin.py +30 -0
- scitex/db/_BaseMixins/_BaseBatchMixin.py +31 -0
- scitex/db/_BaseMixins/_BaseBlobMixin.py +81 -0
- scitex/db/_BaseMixins/_BaseConnectionMixin.py +43 -0
- scitex/db/_BaseMixins/_BaseImportExportMixin.py +39 -0
- scitex/db/_BaseMixins/_BaseIndexMixin.py +29 -0
- scitex/db/_BaseMixins/_BaseMaintenanceMixin.py +33 -0
- scitex/db/_BaseMixins/_BaseQueryMixin.py +52 -0
- scitex/db/_BaseMixins/_BaseRowMixin.py +32 -0
- scitex/db/_BaseMixins/_BaseSchemaMixin.py +44 -0
- scitex/db/_BaseMixins/_BaseTableMixin.py +66 -0
- scitex/db/_BaseMixins/_BaseTransactionMixin.py +52 -0
- scitex/db/_BaseMixins/__init__.py +30 -0
- scitex/db/_PostgreSQL.py +126 -0
- scitex/db/_PostgreSQLMixins/_BackupMixin.py +166 -0
- scitex/db/_PostgreSQLMixins/_BatchMixin.py +82 -0
- scitex/db/_PostgreSQLMixins/_BlobMixin.py +231 -0
- scitex/db/_PostgreSQLMixins/_ConnectionMixin.py +92 -0
- scitex/db/_PostgreSQLMixins/_ImportExportMixin.py +59 -0
- scitex/db/_PostgreSQLMixins/_IndexMixin.py +64 -0
- scitex/db/_PostgreSQLMixins/_MaintenanceMixin.py +175 -0
- scitex/db/_PostgreSQLMixins/_QueryMixin.py +108 -0
- scitex/db/_PostgreSQLMixins/_RowMixin.py +75 -0
- scitex/db/_PostgreSQLMixins/_SchemaMixin.py +126 -0
- scitex/db/_PostgreSQLMixins/_TableMixin.py +176 -0
- scitex/db/_PostgreSQLMixins/_TransactionMixin.py +57 -0
- scitex/db/_PostgreSQLMixins/__init__.py +34 -0
- scitex/db/_SQLite3.py +2136 -0
- scitex/db/_SQLite3Mixins/_BatchMixin.py +243 -0
- scitex/db/_SQLite3Mixins/_BlobMixin.py +229 -0
- scitex/db/_SQLite3Mixins/_ConnectionMixin.py +108 -0
- scitex/db/_SQLite3Mixins/_ImportExportMixin.py +80 -0
- scitex/db/_SQLite3Mixins/_IndexMixin.py +32 -0
- scitex/db/_SQLite3Mixins/_MaintenanceMixin.py +176 -0
- scitex/db/_SQLite3Mixins/_QueryMixin.py +83 -0
- scitex/db/_SQLite3Mixins/_RowMixin.py +75 -0
- scitex/db/_SQLite3Mixins/_TableMixin.py +183 -0
- scitex/db/_SQLite3Mixins/_TransactionMixin.py +71 -0
- scitex/db/_SQLite3Mixins/__init__.py +30 -0
- scitex/db/__init__.py +14 -0
- scitex/db/_delete_duplicates.py +397 -0
- scitex/db/_inspect.py +163 -0
- scitex/decorators/__init__.py +54 -0
- scitex/decorators/_auto_order.py +172 -0
- scitex/decorators/_batch_fn.py +127 -0
- scitex/decorators/_cache_disk.py +32 -0
- scitex/decorators/_cache_mem.py +12 -0
- scitex/decorators/_combined.py +98 -0
- scitex/decorators/_converters.py +282 -0
- scitex/decorators/_deprecated.py +26 -0
- scitex/decorators/_not_implemented.py +30 -0
- scitex/decorators/_numpy_fn.py +86 -0
- scitex/decorators/_pandas_fn.py +121 -0
- scitex/decorators/_preserve_doc.py +19 -0
- scitex/decorators/_signal_fn.py +95 -0
- scitex/decorators/_timeout.py +55 -0
- scitex/decorators/_torch_fn.py +136 -0
- scitex/decorators/_wrap.py +39 -0
- scitex/decorators/_xarray_fn.py +88 -0
- scitex/dev/__init__.py +15 -0
- scitex/dev/_analyze_code_flow.py +284 -0
- scitex/dev/_reload.py +59 -0
- scitex/dict/_DotDict.py +442 -0
- scitex/dict/__init__.py +18 -0
- scitex/dict/_listed_dict.py +42 -0
- scitex/dict/_pop_keys.py +36 -0
- scitex/dict/_replace.py +13 -0
- scitex/dict/_safe_merge.py +62 -0
- scitex/dict/_to_str.py +32 -0
- scitex/dsp/__init__.py +72 -0
- scitex/dsp/_crop.py +122 -0
- scitex/dsp/_demo_sig.py +331 -0
- scitex/dsp/_detect_ripples.py +212 -0
- scitex/dsp/_ensure_3d.py +18 -0
- scitex/dsp/_hilbert.py +78 -0
- scitex/dsp/_listen.py +702 -0
- scitex/dsp/_misc.py +30 -0
- scitex/dsp/_mne.py +32 -0
- scitex/dsp/_modulation_index.py +79 -0
- scitex/dsp/_pac.py +319 -0
- scitex/dsp/_psd.py +102 -0
- scitex/dsp/_resample.py +65 -0
- scitex/dsp/_time.py +36 -0
- scitex/dsp/_transform.py +68 -0
- scitex/dsp/_wavelet.py +212 -0
- scitex/dsp/add_noise.py +111 -0
- scitex/dsp/example.py +253 -0
- scitex/dsp/filt.py +155 -0
- scitex/dsp/norm.py +18 -0
- scitex/dsp/params.py +51 -0
- scitex/dsp/reference.py +43 -0
- scitex/dsp/template.py +25 -0
- scitex/dsp/utils/__init__.py +15 -0
- scitex/dsp/utils/_differential_bandpass_filters.py +120 -0
- scitex/dsp/utils/_ensure_3d.py +18 -0
- scitex/dsp/utils/_ensure_even_len.py +10 -0
- scitex/dsp/utils/_zero_pad.py +48 -0
- scitex/dsp/utils/filter.py +408 -0
- scitex/dsp/utils/pac.py +177 -0
- scitex/dt/__init__.py +8 -0
- scitex/dt/_linspace.py +130 -0
- scitex/etc/__init__.py +15 -0
- scitex/etc/wait_key.py +34 -0
- scitex/gen/_DimHandler.py +196 -0
- scitex/gen/_TimeStamper.py +244 -0
- scitex/gen/__init__.py +95 -0
- scitex/gen/_alternate_kwarg.py +13 -0
- scitex/gen/_cache.py +11 -0
- scitex/gen/_check_host.py +34 -0
- scitex/gen/_ci.py +12 -0
- scitex/gen/_close.py +222 -0
- scitex/gen/_embed.py +78 -0
- scitex/gen/_inspect_module.py +257 -0
- scitex/gen/_is_ipython.py +12 -0
- scitex/gen/_less.py +48 -0
- scitex/gen/_list_packages.py +139 -0
- scitex/gen/_mat2py.py +88 -0
- scitex/gen/_norm.py +170 -0
- scitex/gen/_paste.py +18 -0
- scitex/gen/_print_config.py +84 -0
- scitex/gen/_shell.py +48 -0
- scitex/gen/_src.py +111 -0
- scitex/gen/_start.py +451 -0
- scitex/gen/_symlink.py +55 -0
- scitex/gen/_symlog.py +27 -0
- scitex/gen/_tee.py +238 -0
- scitex/gen/_title2path.py +60 -0
- scitex/gen/_title_case.py +88 -0
- scitex/gen/_to_even.py +84 -0
- scitex/gen/_to_odd.py +34 -0
- scitex/gen/_to_rank.py +39 -0
- scitex/gen/_transpose.py +37 -0
- scitex/gen/_type.py +78 -0
- scitex/gen/_var_info.py +73 -0
- scitex/gen/_wrap.py +17 -0
- scitex/gen/_xml2dict.py +76 -0
- scitex/gen/misc.py +730 -0
- scitex/gen/path.py +0 -0
- scitex/general/__init__.py +5 -0
- scitex/gists/_SigMacro_processFigure_S.py +128 -0
- scitex/gists/_SigMacro_toBlue.py +172 -0
- scitex/gists/__init__.py +12 -0
- scitex/io/_H5Explorer.py +292 -0
- scitex/io/__init__.py +82 -0
- scitex/io/_cache.py +101 -0
- scitex/io/_flush.py +24 -0
- scitex/io/_glob.py +103 -0
- scitex/io/_json2md.py +113 -0
- scitex/io/_load.py +168 -0
- scitex/io/_load_configs.py +146 -0
- scitex/io/_load_modules/__init__.py +38 -0
- scitex/io/_load_modules/_catboost.py +66 -0
- scitex/io/_load_modules/_con.py +20 -0
- scitex/io/_load_modules/_db.py +24 -0
- scitex/io/_load_modules/_docx.py +42 -0
- scitex/io/_load_modules/_eeg.py +110 -0
- scitex/io/_load_modules/_hdf5.py +196 -0
- scitex/io/_load_modules/_image.py +19 -0
- scitex/io/_load_modules/_joblib.py +19 -0
- scitex/io/_load_modules/_json.py +18 -0
- scitex/io/_load_modules/_markdown.py +103 -0
- scitex/io/_load_modules/_matlab.py +37 -0
- scitex/io/_load_modules/_numpy.py +39 -0
- scitex/io/_load_modules/_optuna.py +155 -0
- scitex/io/_load_modules/_pandas.py +69 -0
- scitex/io/_load_modules/_pdf.py +31 -0
- scitex/io/_load_modules/_pickle.py +24 -0
- scitex/io/_load_modules/_torch.py +16 -0
- scitex/io/_load_modules/_txt.py +126 -0
- scitex/io/_load_modules/_xml.py +49 -0
- scitex/io/_load_modules/_yaml.py +23 -0
- scitex/io/_mv_to_tmp.py +19 -0
- scitex/io/_path.py +286 -0
- scitex/io/_reload.py +78 -0
- scitex/io/_save.py +539 -0
- scitex/io/_save_modules/__init__.py +66 -0
- scitex/io/_save_modules/_catboost.py +22 -0
- scitex/io/_save_modules/_csv.py +89 -0
- scitex/io/_save_modules/_excel.py +49 -0
- scitex/io/_save_modules/_hdf5.py +249 -0
- scitex/io/_save_modules/_html.py +48 -0
- scitex/io/_save_modules/_image.py +140 -0
- scitex/io/_save_modules/_joblib.py +25 -0
- scitex/io/_save_modules/_json.py +25 -0
- scitex/io/_save_modules/_listed_dfs_as_csv.py +57 -0
- scitex/io/_save_modules/_listed_scalars_as_csv.py +42 -0
- scitex/io/_save_modules/_matlab.py +24 -0
- scitex/io/_save_modules/_mp4.py +29 -0
- scitex/io/_save_modules/_numpy.py +57 -0
- scitex/io/_save_modules/_optuna_study_as_csv_and_pngs.py +38 -0
- scitex/io/_save_modules/_pickle.py +45 -0
- scitex/io/_save_modules/_plotly.py +27 -0
- scitex/io/_save_modules/_text.py +23 -0
- scitex/io/_save_modules/_torch.py +26 -0
- scitex/io/_save_modules/_yaml.py +29 -0
- scitex/life/__init__.py +10 -0
- scitex/life/_monitor_rain.py +49 -0
- scitex/linalg/__init__.py +17 -0
- scitex/linalg/_distance.py +63 -0
- scitex/linalg/_geometric_median.py +64 -0
- scitex/linalg/_misc.py +73 -0
- scitex/nn/_AxiswiseDropout.py +27 -0
- scitex/nn/_BNet.py +126 -0
- scitex/nn/_BNet_Res.py +164 -0
- scitex/nn/_ChannelGainChanger.py +44 -0
- scitex/nn/_DropoutChannels.py +50 -0
- scitex/nn/_Filters.py +489 -0
- scitex/nn/_FreqGainChanger.py +110 -0
- scitex/nn/_GaussianFilter.py +48 -0
- scitex/nn/_Hilbert.py +111 -0
- scitex/nn/_MNet_1000.py +157 -0
- scitex/nn/_ModulationIndex.py +221 -0
- scitex/nn/_PAC.py +414 -0
- scitex/nn/_PSD.py +40 -0
- scitex/nn/_ResNet1D.py +120 -0
- scitex/nn/_SpatialAttention.py +25 -0
- scitex/nn/_Spectrogram.py +161 -0
- scitex/nn/_SwapChannels.py +50 -0
- scitex/nn/_TransposeLayer.py +19 -0
- scitex/nn/_Wavelet.py +183 -0
- scitex/nn/__init__.py +63 -0
- scitex/os/__init__.py +8 -0
- scitex/os/_mv.py +50 -0
- scitex/parallel/__init__.py +8 -0
- scitex/parallel/_run.py +151 -0
- scitex/path/__init__.py +33 -0
- scitex/path/_clean.py +52 -0
- scitex/path/_find.py +108 -0
- scitex/path/_get_module_path.py +51 -0
- scitex/path/_get_spath.py +35 -0
- scitex/path/_getsize.py +18 -0
- scitex/path/_increment_version.py +87 -0
- scitex/path/_mk_spath.py +51 -0
- scitex/path/_path.py +19 -0
- scitex/path/_split.py +23 -0
- scitex/path/_this_path.py +19 -0
- scitex/path/_version.py +101 -0
- scitex/pd/__init__.py +41 -0
- scitex/pd/_find_indi.py +126 -0
- scitex/pd/_find_pval.py +113 -0
- scitex/pd/_force_df.py +154 -0
- scitex/pd/_from_xyz.py +71 -0
- scitex/pd/_ignore_SettingWithCopyWarning.py +34 -0
- scitex/pd/_melt_cols.py +81 -0
- scitex/pd/_merge_columns.py +221 -0
- scitex/pd/_mv.py +63 -0
- scitex/pd/_replace.py +62 -0
- scitex/pd/_round.py +93 -0
- scitex/pd/_slice.py +63 -0
- scitex/pd/_sort.py +91 -0
- scitex/pd/_to_numeric.py +53 -0
- scitex/pd/_to_xy.py +59 -0
- scitex/pd/_to_xyz.py +110 -0
- scitex/plt/__init__.py +36 -0
- scitex/plt/_subplots/_AxesWrapper.py +182 -0
- scitex/plt/_subplots/_AxisWrapper.py +249 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin.py +414 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin.py +896 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin.py +368 -0
- scitex/plt/_subplots/_AxisWrapperMixins/_TrackingMixin.py +185 -0
- scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +16 -0
- scitex/plt/_subplots/_FigWrapper.py +226 -0
- scitex/plt/_subplots/_SubplotsWrapper.py +171 -0
- scitex/plt/_subplots/__init__.py +111 -0
- scitex/plt/_subplots/_export_as_csv.py +232 -0
- scitex/plt/_subplots/_export_as_csv_formatters/__init__.py +61 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_bar.py +90 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_barh.py +49 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_boxplot.py +46 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_contour.py +39 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_errorbar.py +125 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_eventplot.py +72 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_fill.py +34 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_fill_between.py +36 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_hist.py +79 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow.py +59 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow2d.py +32 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot.py +79 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_box.py +75 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_conf_mat.py +64 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_ecdf.py +44 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_fillv.py +70 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_heatmap.py +66 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_image.py +95 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_joyplot.py +67 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_kde.py +52 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_line.py +46 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_mean_ci.py +46 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_mean_std.py +46 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_median_iqr.py +46 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_raster.py +44 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_rectangle.py +103 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter_hist.py +82 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_shaded_line.py +58 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_violin.py +117 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_scatter.py +30 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_barplot.py +51 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_boxplot.py +93 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_heatmap.py +94 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_histplot.py +92 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_jointplot.py +65 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_kdeplot.py +59 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_lineplot.py +58 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_pairplot.py +45 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_scatterplot.py +70 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_stripplot.py +75 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_swarmplot.py +75 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_violinplot.py +155 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_violin.py +64 -0
- scitex/plt/_subplots/_export_as_csv_formatters/_format_violinplot.py +77 -0
- scitex/plt/_subplots/_export_as_csv_formatters/test_formatters.py +210 -0
- scitex/plt/_subplots/_export_as_csv_formatters/verify_formatters.py +342 -0
- scitex/plt/_subplots/_export_as_csv_formatters.py +115 -0
- scitex/plt/_tpl.py +28 -0
- scitex/plt/ax/__init__.py +114 -0
- scitex/plt/ax/_plot/__init__.py +53 -0
- scitex/plt/ax/_plot/_plot_circular_hist.py +124 -0
- scitex/plt/ax/_plot/_plot_conf_mat.py +136 -0
- scitex/plt/ax/_plot/_plot_cube.py +57 -0
- scitex/plt/ax/_plot/_plot_ecdf.py +84 -0
- scitex/plt/ax/_plot/_plot_fillv.py +55 -0
- scitex/plt/ax/_plot/_plot_heatmap.py +266 -0
- scitex/plt/ax/_plot/_plot_image.py +94 -0
- scitex/plt/ax/_plot/_plot_joyplot.py +76 -0
- scitex/plt/ax/_plot/_plot_raster.py +172 -0
- scitex/plt/ax/_plot/_plot_rectangle.py +69 -0
- scitex/plt/ax/_plot/_plot_scatter_hist.py +133 -0
- scitex/plt/ax/_plot/_plot_shaded_line.py +142 -0
- scitex/plt/ax/_plot/_plot_statistical_shaded_line.py +221 -0
- scitex/plt/ax/_plot/_plot_violin.py +343 -0
- scitex/plt/ax/_style/__init__.py +38 -0
- scitex/plt/ax/_style/_add_marginal_ax.py +44 -0
- scitex/plt/ax/_style/_add_panel.py +92 -0
- scitex/plt/ax/_style/_extend.py +64 -0
- scitex/plt/ax/_style/_force_aspect.py +37 -0
- scitex/plt/ax/_style/_format_label.py +23 -0
- scitex/plt/ax/_style/_hide_spines.py +84 -0
- scitex/plt/ax/_style/_map_ticks.py +182 -0
- scitex/plt/ax/_style/_rotate_labels.py +215 -0
- scitex/plt/ax/_style/_sci_note.py +279 -0
- scitex/plt/ax/_style/_set_log_scale.py +299 -0
- scitex/plt/ax/_style/_set_meta.py +261 -0
- scitex/plt/ax/_style/_set_n_ticks.py +37 -0
- scitex/plt/ax/_style/_set_size.py +16 -0
- scitex/plt/ax/_style/_set_supxyt.py +116 -0
- scitex/plt/ax/_style/_set_ticks.py +276 -0
- scitex/plt/ax/_style/_set_xyt.py +121 -0
- scitex/plt/ax/_style/_share_axes.py +264 -0
- scitex/plt/ax/_style/_shift.py +139 -0
- scitex/plt/ax/_style/_show_spines.py +333 -0
- scitex/plt/color/_PARAMS.py +70 -0
- scitex/plt/color/__init__.py +52 -0
- scitex/plt/color/_add_hue_col.py +41 -0
- scitex/plt/color/_colors.py +205 -0
- scitex/plt/color/_get_colors_from_cmap.py +134 -0
- scitex/plt/color/_interpolate.py +29 -0
- scitex/plt/color/_vizualize_colors.py +54 -0
- scitex/plt/utils/__init__.py +44 -0
- scitex/plt/utils/_calc_bacc_from_conf_mat.py +46 -0
- scitex/plt/utils/_calc_nice_ticks.py +101 -0
- scitex/plt/utils/_close.py +68 -0
- scitex/plt/utils/_colorbar.py +96 -0
- scitex/plt/utils/_configure_mpl.py +295 -0
- scitex/plt/utils/_histogram_utils.py +132 -0
- scitex/plt/utils/_im2grid.py +70 -0
- scitex/plt/utils/_is_valid_axis.py +78 -0
- scitex/plt/utils/_mk_colorbar.py +65 -0
- scitex/plt/utils/_mk_patches.py +26 -0
- scitex/plt/utils/_scientific_captions.py +638 -0
- scitex/plt/utils/_scitex_config.py +223 -0
- scitex/reproduce/__init__.py +14 -0
- scitex/reproduce/_fix_seeds.py +45 -0
- scitex/reproduce/_gen_ID.py +55 -0
- scitex/reproduce/_gen_timestamp.py +35 -0
- scitex/res/__init__.py +5 -0
- scitex/resource/__init__.py +13 -0
- scitex/resource/_get_processor_usages.py +281 -0
- scitex/resource/_get_specs.py +280 -0
- scitex/resource/_log_processor_usages.py +190 -0
- scitex/resource/_utils/__init__.py +31 -0
- scitex/resource/_utils/_get_env_info.py +481 -0
- scitex/resource/limit_ram.py +33 -0
- scitex/scholar/__init__.py +24 -0
- scitex/scholar/_local_search.py +454 -0
- scitex/scholar/_paper.py +244 -0
- scitex/scholar/_pdf_downloader.py +325 -0
- scitex/scholar/_search.py +393 -0
- scitex/scholar/_vector_search.py +370 -0
- scitex/scholar/_web_sources.py +457 -0
- scitex/stats/__init__.py +31 -0
- scitex/stats/_calc_partial_corr.py +17 -0
- scitex/stats/_corr_test_multi.py +94 -0
- scitex/stats/_corr_test_wrapper.py +115 -0
- scitex/stats/_describe_wrapper.py +90 -0
- scitex/stats/_multiple_corrections.py +63 -0
- scitex/stats/_nan_stats.py +93 -0
- scitex/stats/_p2stars.py +116 -0
- scitex/stats/_p2stars_wrapper.py +56 -0
- scitex/stats/_statistical_tests.py +73 -0
- scitex/stats/desc/__init__.py +40 -0
- scitex/stats/desc/_describe.py +189 -0
- scitex/stats/desc/_nan.py +289 -0
- scitex/stats/desc/_real.py +94 -0
- scitex/stats/multiple/__init__.py +14 -0
- scitex/stats/multiple/_bonferroni_correction.py +72 -0
- scitex/stats/multiple/_fdr_correction.py +400 -0
- scitex/stats/multiple/_multicompair.py +28 -0
- scitex/stats/tests/__corr_test.py +277 -0
- scitex/stats/tests/__corr_test_multi.py +343 -0
- scitex/stats/tests/__corr_test_single.py +277 -0
- scitex/stats/tests/__init__.py +22 -0
- scitex/stats/tests/_brunner_munzel_test.py +192 -0
- scitex/stats/tests/_nocorrelation_test.py +28 -0
- scitex/stats/tests/_smirnov_grubbs.py +98 -0
- scitex/str/__init__.py +113 -0
- scitex/str/_clean_path.py +75 -0
- scitex/str/_color_text.py +52 -0
- scitex/str/_decapitalize.py +58 -0
- scitex/str/_factor_out_digits.py +281 -0
- scitex/str/_format_plot_text.py +498 -0
- scitex/str/_grep.py +48 -0
- scitex/str/_latex.py +155 -0
- scitex/str/_latex_fallback.py +471 -0
- scitex/str/_mask_api.py +39 -0
- scitex/str/_mask_api_key.py +8 -0
- scitex/str/_parse.py +158 -0
- scitex/str/_print_block.py +47 -0
- scitex/str/_print_debug.py +68 -0
- scitex/str/_printc.py +62 -0
- scitex/str/_readable_bytes.py +38 -0
- scitex/str/_remove_ansi.py +23 -0
- scitex/str/_replace.py +134 -0
- scitex/str/_search.py +125 -0
- scitex/str/_squeeze_space.py +36 -0
- scitex/tex/__init__.py +10 -0
- scitex/tex/_preview.py +103 -0
- scitex/tex/_to_vec.py +116 -0
- scitex/torch/__init__.py +18 -0
- scitex/torch/_apply_to.py +34 -0
- scitex/torch/_nan_funcs.py +77 -0
- scitex/types/_ArrayLike.py +44 -0
- scitex/types/_ColorLike.py +21 -0
- scitex/types/__init__.py +14 -0
- scitex/types/_is_listed_X.py +70 -0
- scitex/utils/__init__.py +22 -0
- scitex/utils/_compress_hdf5.py +116 -0
- scitex/utils/_email.py +120 -0
- scitex/utils/_grid.py +148 -0
- scitex/utils/_notify.py +247 -0
- scitex/utils/_search.py +121 -0
- scitex/web/__init__.py +38 -0
- scitex/web/_search_pubmed.py +438 -0
- scitex/web/_summarize_url.py +158 -0
- scitex-2.0.0.dist-info/METADATA +307 -0
- scitex-2.0.0.dist-info/RECORD +572 -0
- scitex-2.0.0.dist-info/WHEEL +6 -0
- scitex-2.0.0.dist-info/licenses/LICENSE +7 -0
- scitex-2.0.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,471 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Time-stamp: "2025-06-05 12:00:00 (ywatanabe)"
|
|
4
|
+
# File: ./src/scitex/str/_latex_fallback.py
|
|
5
|
+
|
|
6
|
+
"""
|
|
7
|
+
LaTeX Fallback Mechanism for SciTeX
|
|
8
|
+
|
|
9
|
+
This module provides a robust fallback system for LaTeX rendering issues.
|
|
10
|
+
When LaTeX compilation fails (e.g., missing fonts, Node.js conflicts),
|
|
11
|
+
it gracefully degrades to mathtext or plain text alternatives.
|
|
12
|
+
|
|
13
|
+
Functionality:
|
|
14
|
+
- Detect LaTeX rendering capabilities
|
|
15
|
+
- Convert LaTeX to mathtext equivalents
|
|
16
|
+
- Provide plain text fallbacks
|
|
17
|
+
- Cache LaTeX capability status
|
|
18
|
+
Input:
|
|
19
|
+
LaTeX strings and matplotlib configuration
|
|
20
|
+
Output:
|
|
21
|
+
Fallback-compatible strings for matplotlib
|
|
22
|
+
Prerequisites:
|
|
23
|
+
matplotlib
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
import functools
|
|
27
|
+
import logging
|
|
28
|
+
import re
|
|
29
|
+
import warnings
|
|
30
|
+
from typing import Dict, Optional, Tuple, Union, Callable, Any
|
|
31
|
+
|
|
32
|
+
import matplotlib
|
|
33
|
+
import matplotlib.pyplot as plt
|
|
34
|
+
from matplotlib import mathtext
|
|
35
|
+
import matplotlib.textpath as textpath
|
|
36
|
+
|
|
37
|
+
# Configure logging
|
|
38
|
+
logger = logging.getLogger(__name__)
|
|
39
|
+
|
|
40
|
+
# Global state for LaTeX capability
|
|
41
|
+
_latex_available = None
|
|
42
|
+
_fallback_mode = "auto" # "auto", "force_mathtext", "force_plain"
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
class LaTeXFallbackError(Exception):
|
|
46
|
+
"""Raised when LaTeX fallback mechanisms fail."""
|
|
47
|
+
pass
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
def set_fallback_mode(mode: str) -> None:
|
|
51
|
+
"""
|
|
52
|
+
Set the global fallback mode for LaTeX rendering.
|
|
53
|
+
|
|
54
|
+
Parameters
|
|
55
|
+
----------
|
|
56
|
+
mode : str
|
|
57
|
+
Fallback mode: "auto" (detect capability), "force_mathtext", or "force_plain"
|
|
58
|
+
"""
|
|
59
|
+
global _fallback_mode
|
|
60
|
+
if mode not in ["auto", "force_mathtext", "force_plain"]:
|
|
61
|
+
raise ValueError(f"Invalid fallback mode: {mode}")
|
|
62
|
+
_fallback_mode = mode
|
|
63
|
+
# Reset capability cache when mode changes
|
|
64
|
+
global _latex_available
|
|
65
|
+
_latex_available = None
|
|
66
|
+
|
|
67
|
+
|
|
68
|
+
def get_fallback_mode() -> str:
|
|
69
|
+
"""Get the current fallback mode."""
|
|
70
|
+
return _fallback_mode
|
|
71
|
+
|
|
72
|
+
|
|
73
|
+
@functools.lru_cache(maxsize=1)
|
|
74
|
+
def check_latex_capability() -> bool:
|
|
75
|
+
"""
|
|
76
|
+
Check if LaTeX rendering is available and working.
|
|
77
|
+
|
|
78
|
+
Returns
|
|
79
|
+
-------
|
|
80
|
+
bool
|
|
81
|
+
True if LaTeX is available, False otherwise
|
|
82
|
+
"""
|
|
83
|
+
global _latex_available, _fallback_mode
|
|
84
|
+
|
|
85
|
+
# If forcing a mode, return accordingly
|
|
86
|
+
if _fallback_mode == "force_mathtext" or _fallback_mode == "force_plain":
|
|
87
|
+
_latex_available = False
|
|
88
|
+
return False
|
|
89
|
+
|
|
90
|
+
# Cache the result if already determined
|
|
91
|
+
if _latex_available is not None:
|
|
92
|
+
return _latex_available
|
|
93
|
+
|
|
94
|
+
try:
|
|
95
|
+
# Test if LaTeX is configured
|
|
96
|
+
if not plt.rcParams.get('text.usetex', False):
|
|
97
|
+
_latex_available = False
|
|
98
|
+
return False
|
|
99
|
+
|
|
100
|
+
# Try a simple LaTeX rendering test
|
|
101
|
+
fig, ax = plt.subplots(figsize=(1, 1))
|
|
102
|
+
try:
|
|
103
|
+
# Test with a simple LaTeX expression
|
|
104
|
+
text_obj = ax.text(0.5, 0.5, r'$x^2$', usetex=True)
|
|
105
|
+
fig.canvas.draw() # Force rendering
|
|
106
|
+
_latex_available = True
|
|
107
|
+
result = True
|
|
108
|
+
except Exception as e:
|
|
109
|
+
logger.debug(f"LaTeX capability test failed: {e}")
|
|
110
|
+
_latex_available = False
|
|
111
|
+
result = False
|
|
112
|
+
finally:
|
|
113
|
+
plt.close(fig)
|
|
114
|
+
|
|
115
|
+
return result
|
|
116
|
+
|
|
117
|
+
except Exception as e:
|
|
118
|
+
logger.debug(f"LaTeX capability check failed: {e}")
|
|
119
|
+
_latex_available = False
|
|
120
|
+
return False
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
def latex_to_mathtext(latex_str: str) -> str:
|
|
124
|
+
"""
|
|
125
|
+
Convert LaTeX syntax to matplotlib mathtext equivalent.
|
|
126
|
+
|
|
127
|
+
Parameters
|
|
128
|
+
----------
|
|
129
|
+
latex_str : str
|
|
130
|
+
LaTeX string to convert
|
|
131
|
+
|
|
132
|
+
Returns
|
|
133
|
+
-------
|
|
134
|
+
str
|
|
135
|
+
Mathtext equivalent string
|
|
136
|
+
"""
|
|
137
|
+
if not latex_str:
|
|
138
|
+
return latex_str
|
|
139
|
+
|
|
140
|
+
# Remove outer $ if present
|
|
141
|
+
text = latex_str.strip()
|
|
142
|
+
if text.startswith('$') and text.endswith('$'):
|
|
143
|
+
text = text[1:-1]
|
|
144
|
+
|
|
145
|
+
# Common LaTeX to mathtext conversions
|
|
146
|
+
conversions = {
|
|
147
|
+
# Greek letters
|
|
148
|
+
r'\\alpha': r'\alpha',
|
|
149
|
+
r'\\beta': r'\beta',
|
|
150
|
+
r'\\gamma': r'\gamma',
|
|
151
|
+
r'\\delta': r'\delta',
|
|
152
|
+
r'\\epsilon': r'\epsilon',
|
|
153
|
+
r'\\theta': r'\theta',
|
|
154
|
+
r'\\lambda': r'\lambda',
|
|
155
|
+
r'\\mu': r'\mu',
|
|
156
|
+
r'\\pi': r'\pi',
|
|
157
|
+
r'\\sigma': r'\sigma',
|
|
158
|
+
r'\\tau': r'\tau',
|
|
159
|
+
r'\\phi': r'\phi',
|
|
160
|
+
r'\\omega': r'\omega',
|
|
161
|
+
|
|
162
|
+
# Mathematical symbols
|
|
163
|
+
r'\\sum': r'\sum',
|
|
164
|
+
r'\\int': r'\int',
|
|
165
|
+
r'\\partial': r'\partial',
|
|
166
|
+
r'\\infty': r'\infty',
|
|
167
|
+
r'\\pm': r'\pm',
|
|
168
|
+
r'\\times': r'\times',
|
|
169
|
+
r'\\cdot': r'\cdot',
|
|
170
|
+
r'\\approx': r'\approx',
|
|
171
|
+
r'\\neq': r'\neq',
|
|
172
|
+
r'\\leq': r'\leq',
|
|
173
|
+
r'\\geq': r'\geq',
|
|
174
|
+
|
|
175
|
+
# Functions
|
|
176
|
+
r'\\sin': r'\sin',
|
|
177
|
+
r'\\cos': r'\cos',
|
|
178
|
+
r'\\tan': r'\tan',
|
|
179
|
+
r'\\log': r'\log',
|
|
180
|
+
r'\\ln': r'\ln',
|
|
181
|
+
r'\\exp': r'\exp',
|
|
182
|
+
|
|
183
|
+
# Formatting (limited mathtext support)
|
|
184
|
+
r'\\textbf\{([^}]+)\}': r'\mathbf{\1}',
|
|
185
|
+
r'\\mathbf\{([^}]+)\}': r'\mathbf{\1}',
|
|
186
|
+
r'\\textit\{([^}]+)\}': r'\mathit{\1}',
|
|
187
|
+
r'\\mathit\{([^}]+)\}': r'\mathit{\1}',
|
|
188
|
+
|
|
189
|
+
# Hats and accents
|
|
190
|
+
r'\\hat\{([^}]+)\}': r'\hat{\1}',
|
|
191
|
+
r'\\overrightarrow\{([^}]+)\}': r'\vec{\1}',
|
|
192
|
+
r'\\vec\{([^}]+)\}': r'\vec{\1}',
|
|
193
|
+
|
|
194
|
+
# Fractions (simple ones)
|
|
195
|
+
r'\\frac\{([^}]+)\}\{([^}]+)\}': r'\frac{\1}{\2}',
|
|
196
|
+
|
|
197
|
+
# Subscripts and superscripts (should work as-is)
|
|
198
|
+
# Powers and indices are handled naturally by mathtext
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
# Apply conversions
|
|
202
|
+
for latex_pattern, mathtext_replacement in conversions.items():
|
|
203
|
+
text = re.sub(latex_pattern, mathtext_replacement, text)
|
|
204
|
+
|
|
205
|
+
# Wrap in mathtext markers
|
|
206
|
+
return f'${text}$'
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
def latex_to_unicode(latex_str: str) -> str:
|
|
210
|
+
"""
|
|
211
|
+
Convert LaTeX to Unicode plain text equivalent.
|
|
212
|
+
|
|
213
|
+
Parameters
|
|
214
|
+
----------
|
|
215
|
+
latex_str : str
|
|
216
|
+
LaTeX string to convert
|
|
217
|
+
|
|
218
|
+
Returns
|
|
219
|
+
-------
|
|
220
|
+
str
|
|
221
|
+
Unicode plain text equivalent
|
|
222
|
+
"""
|
|
223
|
+
if not latex_str:
|
|
224
|
+
return latex_str
|
|
225
|
+
|
|
226
|
+
# Remove outer $ if present
|
|
227
|
+
text = latex_str.strip()
|
|
228
|
+
if text.startswith('$') and text.endswith('$'):
|
|
229
|
+
text = text[1:-1]
|
|
230
|
+
|
|
231
|
+
# Greek letters to Unicode
|
|
232
|
+
greek_conversions = {
|
|
233
|
+
r'\\alpha': 'α', r'\\beta': 'β', r'\\gamma': 'γ', r'\\delta': 'δ',
|
|
234
|
+
r'\\epsilon': 'ε', r'\\zeta': 'ζ', r'\\eta': 'η', r'\\theta': 'θ',
|
|
235
|
+
r'\\iota': 'ι', r'\\kappa': 'κ', r'\\lambda': 'λ', r'\\mu': 'μ',
|
|
236
|
+
r'\\nu': 'ν', r'\\xi': 'ξ', r'\\pi': 'π', r'\\rho': 'ρ',
|
|
237
|
+
r'\\sigma': 'σ', r'\\tau': 'τ', r'\\upsilon': 'υ', r'\\phi': 'φ',
|
|
238
|
+
r'\\chi': 'χ', r'\\psi': 'ψ', r'\\omega': 'ω',
|
|
239
|
+
|
|
240
|
+
# Capital Greek
|
|
241
|
+
r'\\Gamma': 'Γ', r'\\Delta': 'Δ', r'\\Theta': 'Θ', r'\\Lambda': 'Λ',
|
|
242
|
+
r'\\Xi': 'Ξ', r'\\Pi': 'Π', r'\\Sigma': 'Σ', r'\\Upsilon': 'Υ',
|
|
243
|
+
r'\\Phi': 'Φ', r'\\Psi': 'Ψ', r'\\Omega': 'Ω',
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
# Mathematical symbols to Unicode
|
|
247
|
+
symbol_conversions = {
|
|
248
|
+
r'\\pm': '±', r'\\times': '×', r'\\cdot': '·', r'\\div': '÷',
|
|
249
|
+
r'\\neq': '≠', r'\\leq': '≤', r'\\geq': '≥', r'\\approx': '≈',
|
|
250
|
+
r'\\infty': '∞', r'\\partial': '∂', r'\\sum': '∑', r'\\int': '∫',
|
|
251
|
+
r'\\sqrt': '√', r'\\angle': '∠', r'\\degree': '°',
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
# Superscript numbers
|
|
255
|
+
superscript_conversions = {
|
|
256
|
+
r'\^0': '⁰', r'\^1': '¹', r'\^2': '²', r'\^3': '³', r'\^4': '⁴',
|
|
257
|
+
r'\^5': '⁵', r'\^6': '⁶', r'\^7': '⁷', r'\^8': '⁸', r'\^9': '⁹',
|
|
258
|
+
r'\^\{0\}': '⁰', r'\^\{1\}': '¹', r'\^\{2\}': '²', r'\^\{3\}': '³',
|
|
259
|
+
r'\^\{4\}': '⁴', r'\^\{5\}': '⁵', r'\^\{6\}': '⁶', r'\^\{7\}': '⁷',
|
|
260
|
+
r'\^\{8\}': '⁸', r'\^\{9\}': '⁹',
|
|
261
|
+
}
|
|
262
|
+
|
|
263
|
+
# Subscript numbers
|
|
264
|
+
subscript_conversions = {
|
|
265
|
+
r'_0': '₀', r'_1': '₁', r'_2': '₂', r'_3': '₃', r'_4': '₄',
|
|
266
|
+
r'_5': '₅', r'_6': '₆', r'_7': '₇', r'_8': '₈', r'_9': '₉',
|
|
267
|
+
r'_\{0\}': '₀', r'_\{1\}': '₁', r'_\{2\}': '₂', r'_\{3\}': '₃',
|
|
268
|
+
r'_\{4\}': '₄', r'_\{5\}': '₅', r'_\{6\}': '₆', r'_\{7\}': '₇',
|
|
269
|
+
r'_\{8\}': '₈', r'_\{9\}': '₉',
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
# Apply all conversions
|
|
273
|
+
all_conversions = {**greek_conversions, **symbol_conversions,
|
|
274
|
+
**superscript_conversions, **subscript_conversions}
|
|
275
|
+
|
|
276
|
+
for latex_pattern, unicode_char in all_conversions.items():
|
|
277
|
+
text = re.sub(latex_pattern, unicode_char, text)
|
|
278
|
+
|
|
279
|
+
# Remove remaining LaTeX commands (simple cleanup)
|
|
280
|
+
text = re.sub(r'\\[a-zA-Z]+\{([^}]*)\}', r'\1', text) # \command{content} -> content
|
|
281
|
+
text = re.sub(r'\\[a-zA-Z]+', '', text) # \command -> remove
|
|
282
|
+
text = re.sub(r'[{}]', '', text) # Remove remaining braces
|
|
283
|
+
|
|
284
|
+
return text
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
def safe_latex_render(
|
|
288
|
+
text: str,
|
|
289
|
+
fallback_strategy: str = "auto",
|
|
290
|
+
preserve_math: bool = True
|
|
291
|
+
) -> str:
|
|
292
|
+
"""
|
|
293
|
+
Safely render LaTeX text with automatic fallback.
|
|
294
|
+
|
|
295
|
+
Parameters
|
|
296
|
+
----------
|
|
297
|
+
text : str
|
|
298
|
+
Text that may contain LaTeX
|
|
299
|
+
fallback_strategy : str, optional
|
|
300
|
+
Strategy when LaTeX fails: "auto", "mathtext", "unicode", "plain"
|
|
301
|
+
preserve_math : bool, optional
|
|
302
|
+
Whether to preserve mathematical notation in fallbacks
|
|
303
|
+
|
|
304
|
+
Returns
|
|
305
|
+
-------
|
|
306
|
+
str
|
|
307
|
+
Safely rendered text
|
|
308
|
+
"""
|
|
309
|
+
if not text or not isinstance(text, str):
|
|
310
|
+
return text
|
|
311
|
+
|
|
312
|
+
global _fallback_mode
|
|
313
|
+
|
|
314
|
+
# Determine if we should attempt LaTeX
|
|
315
|
+
use_latex = (_fallback_mode == "auto" and check_latex_capability())
|
|
316
|
+
|
|
317
|
+
if use_latex:
|
|
318
|
+
# Try LaTeX first
|
|
319
|
+
try:
|
|
320
|
+
# Test rendering capability with the actual text
|
|
321
|
+
fig, ax = plt.subplots(figsize=(1, 1))
|
|
322
|
+
try:
|
|
323
|
+
ax.text(0.5, 0.5, text, usetex=True)
|
|
324
|
+
fig.canvas.draw()
|
|
325
|
+
plt.close(fig)
|
|
326
|
+
return text # LaTeX works
|
|
327
|
+
except Exception:
|
|
328
|
+
plt.close(fig)
|
|
329
|
+
raise LaTeXFallbackError("LaTeX rendering failed")
|
|
330
|
+
except Exception:
|
|
331
|
+
# Fall through to fallback strategies
|
|
332
|
+
pass
|
|
333
|
+
|
|
334
|
+
# Apply fallback strategy
|
|
335
|
+
if fallback_strategy == "auto":
|
|
336
|
+
# Automatically choose best fallback
|
|
337
|
+
if preserve_math and ('$' in text or '\\' in text):
|
|
338
|
+
try:
|
|
339
|
+
return latex_to_mathtext(text)
|
|
340
|
+
except Exception:
|
|
341
|
+
return latex_to_unicode(text)
|
|
342
|
+
else:
|
|
343
|
+
return latex_to_unicode(text)
|
|
344
|
+
|
|
345
|
+
elif fallback_strategy == "mathtext":
|
|
346
|
+
return latex_to_mathtext(text)
|
|
347
|
+
|
|
348
|
+
elif fallback_strategy == "unicode":
|
|
349
|
+
return latex_to_unicode(text)
|
|
350
|
+
|
|
351
|
+
elif fallback_strategy == "plain":
|
|
352
|
+
# Strip all LaTeX and return plain text
|
|
353
|
+
plain = latex_to_unicode(text)
|
|
354
|
+
# Remove any remaining special characters
|
|
355
|
+
plain = re.sub(r'[^\w\s\(\)\[\].,;:!?-]', '', plain)
|
|
356
|
+
return plain
|
|
357
|
+
|
|
358
|
+
else:
|
|
359
|
+
raise ValueError(f"Unknown fallback strategy: {fallback_strategy}")
|
|
360
|
+
|
|
361
|
+
|
|
362
|
+
def latex_fallback_decorator(
|
|
363
|
+
fallback_strategy: str = "auto",
|
|
364
|
+
preserve_math: bool = True
|
|
365
|
+
):
|
|
366
|
+
"""
|
|
367
|
+
Decorator to add LaTeX fallback capability to functions.
|
|
368
|
+
|
|
369
|
+
Parameters
|
|
370
|
+
----------
|
|
371
|
+
fallback_strategy : str, optional
|
|
372
|
+
Fallback strategy to use
|
|
373
|
+
preserve_math : bool, optional
|
|
374
|
+
Whether to preserve mathematical notation
|
|
375
|
+
|
|
376
|
+
Returns
|
|
377
|
+
-------
|
|
378
|
+
callable
|
|
379
|
+
Decorated function with LaTeX fallback
|
|
380
|
+
"""
|
|
381
|
+
def decorator(func: Callable) -> Callable:
|
|
382
|
+
@functools.wraps(func)
|
|
383
|
+
def wrapper(*args, **kwargs):
|
|
384
|
+
try:
|
|
385
|
+
return func(*args, **kwargs)
|
|
386
|
+
except Exception as e:
|
|
387
|
+
# Check if this is a LaTeX-related error
|
|
388
|
+
error_str = str(e).lower()
|
|
389
|
+
latex_error_indicators = [
|
|
390
|
+
'latex', 'tex', 'dvi', 'tfm', 'font', 'usetex',
|
|
391
|
+
'kpathsea', 'dvipng', 'ghostscript'
|
|
392
|
+
]
|
|
393
|
+
|
|
394
|
+
if any(indicator in error_str for indicator in latex_error_indicators):
|
|
395
|
+
logger.warning(f"LaTeX error in {func.__name__}: {e}")
|
|
396
|
+
logger.warning("Falling back to alternative text rendering")
|
|
397
|
+
|
|
398
|
+
# Try to apply fallback to string arguments
|
|
399
|
+
new_args = []
|
|
400
|
+
for arg in args:
|
|
401
|
+
if isinstance(arg, str):
|
|
402
|
+
new_args.append(safe_latex_render(
|
|
403
|
+
arg, fallback_strategy, preserve_math
|
|
404
|
+
))
|
|
405
|
+
else:
|
|
406
|
+
new_args.append(arg)
|
|
407
|
+
|
|
408
|
+
new_kwargs = {}
|
|
409
|
+
for key, value in kwargs.items():
|
|
410
|
+
if isinstance(value, str):
|
|
411
|
+
new_kwargs[key] = safe_latex_render(
|
|
412
|
+
value, fallback_strategy, preserve_math
|
|
413
|
+
)
|
|
414
|
+
else:
|
|
415
|
+
new_kwargs[key] = value
|
|
416
|
+
|
|
417
|
+
# Temporarily disable LaTeX for this call
|
|
418
|
+
original_usetex = plt.rcParams.get('text.usetex', False)
|
|
419
|
+
plt.rcParams['text.usetex'] = False
|
|
420
|
+
|
|
421
|
+
try:
|
|
422
|
+
result = func(*new_args, **new_kwargs)
|
|
423
|
+
return result
|
|
424
|
+
finally:
|
|
425
|
+
plt.rcParams['text.usetex'] = original_usetex
|
|
426
|
+
else:
|
|
427
|
+
# Re-raise non-LaTeX errors
|
|
428
|
+
raise
|
|
429
|
+
return wrapper
|
|
430
|
+
return decorator
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
def get_latex_status() -> Dict[str, Any]:
|
|
434
|
+
"""
|
|
435
|
+
Get comprehensive LaTeX status information.
|
|
436
|
+
|
|
437
|
+
Returns
|
|
438
|
+
-------
|
|
439
|
+
Dict[str, Any]
|
|
440
|
+
Status information including capability, mode, and configuration
|
|
441
|
+
"""
|
|
442
|
+
return {
|
|
443
|
+
'latex_available': check_latex_capability(),
|
|
444
|
+
'fallback_mode': get_fallback_mode(),
|
|
445
|
+
'usetex_enabled': plt.rcParams.get('text.usetex', False),
|
|
446
|
+
'mathtext_fontset': plt.rcParams.get('mathtext.fontset', 'cm'),
|
|
447
|
+
'font_family': plt.rcParams.get('font.family', ['serif']),
|
|
448
|
+
'cache_info': check_latex_capability.cache_info()._asdict(),
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
|
|
452
|
+
# Convenience functions
|
|
453
|
+
def enable_latex_fallback(mode: str = "auto") -> None:
|
|
454
|
+
"""Enable LaTeX fallback with specified mode."""
|
|
455
|
+
set_fallback_mode(mode)
|
|
456
|
+
|
|
457
|
+
|
|
458
|
+
def disable_latex_fallback() -> None:
|
|
459
|
+
"""Disable LaTeX fallback (force LaTeX usage)."""
|
|
460
|
+
global _latex_available
|
|
461
|
+
_latex_available = True # Force LaTeX usage
|
|
462
|
+
|
|
463
|
+
|
|
464
|
+
def reset_latex_cache() -> None:
|
|
465
|
+
"""Reset the LaTeX capability cache."""
|
|
466
|
+
check_latex_capability.cache_clear()
|
|
467
|
+
global _latex_available
|
|
468
|
+
_latex_available = None
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
# EOF
|
scitex/str/_mask_api.py
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!./env/bin/python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Time-stamp: "2024-06-10 20:48:53 (ywatanabe)"
|
|
4
|
+
# /home/ywatanabe/proj/scitex/src/scitex/gen/_mask_api_key.py
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def mask_api(api_key, n=4):
|
|
8
|
+
"""Mask an API key for secure display.
|
|
9
|
+
|
|
10
|
+
Replaces the middle portion of an API key with asterisks, keeping only
|
|
11
|
+
the first and last few characters visible. Useful for logging or displaying
|
|
12
|
+
API keys without exposing the full key.
|
|
13
|
+
|
|
14
|
+
Parameters
|
|
15
|
+
----------
|
|
16
|
+
api_key : str
|
|
17
|
+
The API key to mask.
|
|
18
|
+
n : int, optional
|
|
19
|
+
Number of characters to show at the beginning and end. Default is 4.
|
|
20
|
+
|
|
21
|
+
Returns
|
|
22
|
+
-------
|
|
23
|
+
str
|
|
24
|
+
Masked API key with format "{first_n}****{last_n}"
|
|
25
|
+
|
|
26
|
+
Examples
|
|
27
|
+
--------
|
|
28
|
+
>>> key = "sk-1234567890abcdefghijklmnop"
|
|
29
|
+
>>> print(mask_api(key))
|
|
30
|
+
'sk-1****mnop'
|
|
31
|
+
|
|
32
|
+
>>> print(mask_api(key, n=6))
|
|
33
|
+
'sk-123****lmnop'
|
|
34
|
+
|
|
35
|
+
>>> # Safe for logging
|
|
36
|
+
>>> print(f"Using API key: {mask_api(api_key)}")
|
|
37
|
+
'Using API key: sk-p****5678'
|
|
38
|
+
"""
|
|
39
|
+
return f"{api_key[:n]}****{api_key[-n:]}"
|
scitex/str/_parse.py
ADDED
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Time-stamp: "2024-11-16 17:11:15 (ywatanabe)"
|
|
4
|
+
# File: ./scitex_repo/src/scitex/str/_parse.py
|
|
5
|
+
|
|
6
|
+
THIS_FILE = "/home/ywatanabe/proj/scitex_repo/src/scitex/str/_parse.py"
|
|
7
|
+
|
|
8
|
+
import re
|
|
9
|
+
from typing import Dict, Union
|
|
10
|
+
|
|
11
|
+
from ..dict._DotDict import DotDict as _DotDict
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def parse(
|
|
15
|
+
input_str_or_pattern: str, pattern_or_input_str: str
|
|
16
|
+
) -> Union[Dict[str, Union[str, int]], str]:
|
|
17
|
+
"""
|
|
18
|
+
Bidirectional parser that attempts parsing in both directions.
|
|
19
|
+
|
|
20
|
+
Parameters
|
|
21
|
+
----------
|
|
22
|
+
input_str_or_pattern : str
|
|
23
|
+
Either the input string to parse or the pattern
|
|
24
|
+
pattern_or_input_str : str
|
|
25
|
+
Either the pattern to match against or the input string
|
|
26
|
+
|
|
27
|
+
Returns
|
|
28
|
+
-------
|
|
29
|
+
Union[Dict[str, Union[str, int]], str]
|
|
30
|
+
Parsed dictionary or formatted string
|
|
31
|
+
|
|
32
|
+
Raises
|
|
33
|
+
------
|
|
34
|
+
ValueError
|
|
35
|
+
If parsing fails in both directions
|
|
36
|
+
|
|
37
|
+
Examples
|
|
38
|
+
--------
|
|
39
|
+
>>> # Forward parsing
|
|
40
|
+
>>> parse("./data/Patient_23_002", "./data/Patient_{id}")
|
|
41
|
+
{'id': '23_002'}
|
|
42
|
+
|
|
43
|
+
>>> # Reverse parsing
|
|
44
|
+
>>> parse("./data/Patient_{id}", "./data/Patient_23_002")
|
|
45
|
+
{'id': '23_002'}
|
|
46
|
+
"""
|
|
47
|
+
# try:
|
|
48
|
+
# parsed = _parse(input_str_or_pattern, pattern_or_input_str)
|
|
49
|
+
# if parsed:
|
|
50
|
+
# return parsed
|
|
51
|
+
# except Exception as e:
|
|
52
|
+
# print(e)
|
|
53
|
+
|
|
54
|
+
# try:
|
|
55
|
+
# parsed = _parse(pattern_or_input_str, input_str_or_pattern)
|
|
56
|
+
# if parsed:
|
|
57
|
+
# return parsed
|
|
58
|
+
# except Exception as e:
|
|
59
|
+
# print(e)
|
|
60
|
+
errors = []
|
|
61
|
+
|
|
62
|
+
# Try first direction
|
|
63
|
+
try:
|
|
64
|
+
result = _parse(input_str_or_pattern, pattern_or_input_str)
|
|
65
|
+
if result:
|
|
66
|
+
return result
|
|
67
|
+
except ValueError as e:
|
|
68
|
+
errors.append(str(e))
|
|
69
|
+
# logging.warning(f"First attempt failed: {e}")
|
|
70
|
+
|
|
71
|
+
# Try reverse direction
|
|
72
|
+
try:
|
|
73
|
+
result = _parse(pattern_or_input_str, input_str_or_pattern)
|
|
74
|
+
if result:
|
|
75
|
+
return result
|
|
76
|
+
except ValueError as e:
|
|
77
|
+
errors.append(str(e))
|
|
78
|
+
# logging.warning(f"Second attempt failed: {e}")
|
|
79
|
+
|
|
80
|
+
raise ValueError(f"Parsing failed in both directions: {' | '.join(errors)}")
|
|
81
|
+
|
|
82
|
+
|
|
83
|
+
def _parse(string: str, expression: str) -> Dict[str, Union[str, int]]:
|
|
84
|
+
"""
|
|
85
|
+
Parse a string based on a given expression pattern.
|
|
86
|
+
|
|
87
|
+
Parameters
|
|
88
|
+
----------
|
|
89
|
+
string : str
|
|
90
|
+
The string to parse
|
|
91
|
+
expression : str
|
|
92
|
+
The expression pattern to match against the string
|
|
93
|
+
|
|
94
|
+
Returns
|
|
95
|
+
-------
|
|
96
|
+
Dict[str, Union[str, int]]
|
|
97
|
+
A dictionary containing parsed information
|
|
98
|
+
|
|
99
|
+
Raises
|
|
100
|
+
------
|
|
101
|
+
ValueError
|
|
102
|
+
If the string format does not match the given expression
|
|
103
|
+
If duplicate placeholders have inconsistent values
|
|
104
|
+
|
|
105
|
+
Example
|
|
106
|
+
-------
|
|
107
|
+
>>> string = "./data/mat_tmp/Patient_23_002/Data_2010_07_31/Hour_12/UTC_12_02_00.mat"
|
|
108
|
+
>>> expression = "./data/mat_tmp/Patient_{patient_id}/Data_{YYYY}_{MM}_{DD}/Hour_{HH}/UTC_{HH}_{mm}_00.mat"
|
|
109
|
+
>>> parse_str(string, expression)
|
|
110
|
+
# {'patient_id': '23_002', 'YYYY': 2010, 'MM': 7, 'DD': 31, 'HH': 12, 'mm': 2}
|
|
111
|
+
|
|
112
|
+
# Inconsistent version
|
|
113
|
+
>>> string = "./data/mat_tmp/Patient_23_002/Data_2010_07_31/Hour_12/UTC_99_02_00.mat"
|
|
114
|
+
>>> expression = "./data/mat_tmp/Patient_{patient_id}/Data_{YYYY}_{MM}_{DD}/Hour_{HH}/UTC_{HH}_{mm}_00.mat"
|
|
115
|
+
>>> parse_str(string, expression)
|
|
116
|
+
# ValueError: Inconsistent values for placeholder 'HH'
|
|
117
|
+
"""
|
|
118
|
+
|
|
119
|
+
# Formatting
|
|
120
|
+
string = string.replace("/./", "/")
|
|
121
|
+
expression = expression.replace('f"', "").replace('"', "")
|
|
122
|
+
|
|
123
|
+
placeholders = re.findall(r"{(\w+)}", expression)
|
|
124
|
+
pattern = re.sub(r"{(\w+)}", "([^/]+)", expression)
|
|
125
|
+
match = re.match(pattern, string)
|
|
126
|
+
|
|
127
|
+
if not match:
|
|
128
|
+
raise ValueError(
|
|
129
|
+
f"String format does not match expression: {string} vs {expression}"
|
|
130
|
+
)
|
|
131
|
+
# logging.warning(f"String format does not match the given expression. \nString input: {string}\nExpression: {expression}")
|
|
132
|
+
# return {}
|
|
133
|
+
|
|
134
|
+
groups = match.groups()
|
|
135
|
+
result = {}
|
|
136
|
+
|
|
137
|
+
for placeholder, value in zip(placeholders, groups):
|
|
138
|
+
if placeholder in result and result[placeholder] != value:
|
|
139
|
+
raise ValueError(f"Inconsistent values for placeholder '{placeholder}'")
|
|
140
|
+
result[placeholder] = value
|
|
141
|
+
|
|
142
|
+
return _DotDict(result)
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
if __name__ == "__main__":
|
|
146
|
+
string = "./data/mat_tmp/Patient_23_002/Data_2010_07_31/Hour_12/UTC_12_02_00.mat"
|
|
147
|
+
expression = "./data/mat_tmp/Patient_{patient_id}/Data_{YYYY}_{MM}_{DD}/Hour_{HH}/UTC_{HH}_{mm}_00.mat"
|
|
148
|
+
results = parse_str(string, expression)
|
|
149
|
+
print(results)
|
|
150
|
+
|
|
151
|
+
# Inconsistent version
|
|
152
|
+
string = "./data/mat_tmp/Patient_23_002/Data_2010_07_31/Hour_12/UTC_99_99_00.mat"
|
|
153
|
+
expression = "./data/mat_tmp/Patient_{patient_id}/Data_{YYYY}_{MM}_{DD}/Hour_{HH}/UTC_{HH}_{mm}_00.mat"
|
|
154
|
+
results = parse_str(string, expression) # this should raise error
|
|
155
|
+
print(results)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
# EOF
|