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/nn/__init__.py
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
"""Scitex nn module."""
|
|
3
3
|
|
|
4
4
|
from ._AxiswiseDropout import AxiswiseDropout
|
|
5
|
-
from ._BNet import BHead, BNet, BNet_config
|
|
6
|
-
from ._BNet_Res import BHead, BNet, BNet_config
|
|
5
|
+
from ._BNet import BHead as BHead_v1, BNet as BNet_v1, BNet_config as BNet_config_v1
|
|
6
|
+
from ._BNet_Res import BHead as BHead_Res, BNet as BNet_Res, BNet_config as BNet_config_Res
|
|
7
7
|
from ._ChannelGainChanger import ChannelGainChanger
|
|
8
8
|
from ._DropoutChannels import DropoutChannels
|
|
9
9
|
from ._Filters import BandPassFilter, BandStopFilter, BaseFilter1D, DifferentiableBandPassFilter, GaussianFilter, HighPassFilter, LowPassFilter
|
|
10
10
|
from ._FreqGainChanger import FreqGainChanger
|
|
11
|
-
|
|
11
|
+
# Removed duplicate GaussianFilter import - already imported from _Filters
|
|
12
12
|
from ._Hilbert import Hilbert
|
|
13
13
|
from ._MNet_1000 import MNet1000, MNet_1000, MNet_config, ReshapeLayer, SwapLayer
|
|
14
14
|
from ._ModulationIndex import ModulationIndex
|
|
@@ -23,12 +23,12 @@ from ._Wavelet import Wavelet
|
|
|
23
23
|
|
|
24
24
|
__all__ = [
|
|
25
25
|
"AxiswiseDropout",
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
26
|
+
"BHead_v1",
|
|
27
|
+
"BHead_Res",
|
|
28
|
+
"BNet_v1",
|
|
29
|
+
"BNet_Res",
|
|
30
|
+
"BNet_config_v1",
|
|
31
|
+
"BNet_config_Res",
|
|
32
32
|
"BandPassFilter",
|
|
33
33
|
"BandStopFilter",
|
|
34
34
|
"BaseFilter1D",
|
|
@@ -37,7 +37,6 @@ __all__ = [
|
|
|
37
37
|
"DropoutChannels",
|
|
38
38
|
"FreqGainChanger",
|
|
39
39
|
"GaussianFilter",
|
|
40
|
-
"GaussianFilter",
|
|
41
40
|
"HighPassFilter",
|
|
42
41
|
"Hilbert",
|
|
43
42
|
"LowPassFilter",
|
scitex/path/__init__.py
CHANGED
|
@@ -10,15 +10,27 @@ from ._increment_version import increment_version
|
|
|
10
10
|
from ._mk_spath import mk_spath
|
|
11
11
|
from ._path import get_this_path, this_path
|
|
12
12
|
from ._split import split
|
|
13
|
+
from ._symlink import (
|
|
14
|
+
symlink,
|
|
15
|
+
is_symlink,
|
|
16
|
+
readlink,
|
|
17
|
+
resolve_symlinks,
|
|
18
|
+
create_relative_symlink,
|
|
19
|
+
unlink_symlink,
|
|
20
|
+
list_symlinks,
|
|
21
|
+
fix_broken_symlinks,
|
|
22
|
+
)
|
|
13
23
|
from ._this_path import get_this_path, this_path
|
|
14
24
|
from ._version import find_latest, increment_version
|
|
15
25
|
|
|
16
26
|
__all__ = [
|
|
17
27
|
"clean",
|
|
28
|
+
"create_relative_symlink",
|
|
18
29
|
"find_dir",
|
|
19
30
|
"find_file",
|
|
20
31
|
"find_git_root",
|
|
21
32
|
"find_latest",
|
|
33
|
+
"fix_broken_symlinks",
|
|
22
34
|
"get_data_path_from_a_package",
|
|
23
35
|
"get_spath",
|
|
24
36
|
"get_this_path",
|
|
@@ -26,8 +38,14 @@ __all__ = [
|
|
|
26
38
|
"getsize",
|
|
27
39
|
"increment_version",
|
|
28
40
|
"increment_version",
|
|
41
|
+
"is_symlink",
|
|
42
|
+
"list_symlinks",
|
|
29
43
|
"mk_spath",
|
|
44
|
+
"readlink",
|
|
45
|
+
"resolve_symlinks",
|
|
30
46
|
"split",
|
|
47
|
+
"symlink",
|
|
31
48
|
"this_path",
|
|
32
49
|
"this_path",
|
|
50
|
+
"unlink_symlink",
|
|
33
51
|
]
|
scitex/path/_clean.py
CHANGED
|
@@ -27,6 +27,10 @@ def clean(path_string):
|
|
|
27
27
|
str
|
|
28
28
|
Normalized path string
|
|
29
29
|
"""
|
|
30
|
+
# Convert Path objects to strings to avoid AttributeError
|
|
31
|
+
if hasattr(path_string, '__fspath__'): # Check if it's a path-like object
|
|
32
|
+
path_string = str(path_string)
|
|
33
|
+
|
|
30
34
|
if not path_string:
|
|
31
35
|
return ""
|
|
32
36
|
|
scitex/path/_find.py
CHANGED
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
#!./env/bin/python3
|
|
6
6
|
# -*- coding: utf-8 -*-
|
|
7
7
|
# Time-stamp: "2024-04-17 09:34:43"
|
|
8
|
-
# Author: Yusuke Watanabe (
|
|
8
|
+
# Author: Yusuke Watanabe (ywatanabe@scitex.ai)
|
|
9
9
|
|
|
10
10
|
"""
|
|
11
11
|
This script does XYZ.
|
|
@@ -15,7 +15,6 @@ import fnmatch
|
|
|
15
15
|
import os
|
|
16
16
|
import sys
|
|
17
17
|
|
|
18
|
-
import matplotlib.pyplot as plt
|
|
19
18
|
import scitex
|
|
20
19
|
|
|
21
20
|
|
|
@@ -90,13 +89,19 @@ def _find(rootdir, type="f", exp=["*"]):
|
|
|
90
89
|
|
|
91
90
|
|
|
92
91
|
if __name__ == "__main__":
|
|
92
|
+
# Import matplotlib only when running as script
|
|
93
|
+
try:
|
|
94
|
+
import matplotlib.pyplot as plt
|
|
95
|
+
except ImportError:
|
|
96
|
+
plt = None
|
|
97
|
+
|
|
93
98
|
# Start
|
|
94
|
-
CONFIG, sys.stdout, sys.stderr, plt, CC = scitex.
|
|
99
|
+
CONFIG, sys.stdout, sys.stderr, plt, CC = scitex.session.start(sys, plt)
|
|
95
100
|
|
|
96
101
|
# (YOUR AWESOME CODE)
|
|
97
102
|
|
|
98
103
|
# Close
|
|
99
|
-
scitex.
|
|
104
|
+
scitex.session.close(CONFIG)
|
|
100
105
|
|
|
101
106
|
# EOF
|
|
102
107
|
|
scitex/path/_symlink.py
ADDED
|
@@ -0,0 +1,348 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Timestamp: "2025-09-16 15:11:33 (ywatanabe)"
|
|
4
|
+
# File: /ssh:sp:/home/ywatanabe/proj/scitex_repo/src/scitex/path/_symlink.py
|
|
5
|
+
# ----------------------------------------
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
import os
|
|
8
|
+
__FILE__ = __file__
|
|
9
|
+
__DIR__ = os.path.dirname(__FILE__)
|
|
10
|
+
# ----------------------------------------
|
|
11
|
+
|
|
12
|
+
"""Symlink creation and management utilities for SciTeX."""
|
|
13
|
+
|
|
14
|
+
# from scitex import logging
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
from typing import Optional, Union
|
|
17
|
+
|
|
18
|
+
from scitex import logging
|
|
19
|
+
|
|
20
|
+
logger = logging.getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def symlink(
|
|
24
|
+
src: Union[str, Path],
|
|
25
|
+
dst: Union[str, Path],
|
|
26
|
+
overwrite: bool = False,
|
|
27
|
+
target_is_directory: Optional[bool] = None,
|
|
28
|
+
relative: bool = False,
|
|
29
|
+
) -> Path:
|
|
30
|
+
"""
|
|
31
|
+
Create a symbolic link pointing to src named dst.
|
|
32
|
+
|
|
33
|
+
Args:
|
|
34
|
+
src: Source path (target of the symlink)
|
|
35
|
+
dst: Destination path (the symlink to create)
|
|
36
|
+
overwrite: If True, remove existing dst before creating symlink
|
|
37
|
+
target_is_directory: On Windows, specify if target is directory (auto-detected if None)
|
|
38
|
+
relative: If True, create relative symlink instead of absolute
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
Path object of the created symlink
|
|
42
|
+
|
|
43
|
+
Raises:
|
|
44
|
+
FileExistsError: If dst exists and overwrite=False
|
|
45
|
+
FileNotFoundError: If src doesn't exist
|
|
46
|
+
OSError: If symlink creation fails
|
|
47
|
+
|
|
48
|
+
Examples:
|
|
49
|
+
>>> import scitex as stx
|
|
50
|
+
>>> # Create absolute symlink
|
|
51
|
+
>>> stx.path.symlink("/path/to/source", "/path/to/link")
|
|
52
|
+
|
|
53
|
+
>>> # Create relative symlink
|
|
54
|
+
>>> stx.path.symlink("../source", "link", relative=True)
|
|
55
|
+
|
|
56
|
+
>>> # Overwrite existing symlink
|
|
57
|
+
>>> stx.path.symlink("/path/to/new_source", "/path/to/link", overwrite=True)
|
|
58
|
+
"""
|
|
59
|
+
src_path = Path(src)
|
|
60
|
+
dst_path = Path(dst)
|
|
61
|
+
|
|
62
|
+
# Note: We allow creating symlinks to non-existent targets
|
|
63
|
+
# This is valid in Unix/Linux and useful for testing
|
|
64
|
+
|
|
65
|
+
# Handle existing destination
|
|
66
|
+
if dst_path.exists() or dst_path.is_symlink():
|
|
67
|
+
if not overwrite:
|
|
68
|
+
raise FileExistsError(f"Destination already exists: {dst_path}")
|
|
69
|
+
else:
|
|
70
|
+
# Remove existing file/symlink
|
|
71
|
+
if dst_path.is_symlink():
|
|
72
|
+
dst_path.unlink()
|
|
73
|
+
elif dst_path.is_file():
|
|
74
|
+
dst_path.unlink()
|
|
75
|
+
elif dst_path.is_dir():
|
|
76
|
+
import shutil
|
|
77
|
+
|
|
78
|
+
shutil.rmtree(dst_path)
|
|
79
|
+
# logger.info(f"Removed existing destination: {dst_path}")
|
|
80
|
+
|
|
81
|
+
# Create parent directory if needed
|
|
82
|
+
dst_path.parent.mkdir(parents=True, exist_ok=True)
|
|
83
|
+
|
|
84
|
+
# Determine if target is directory (for Windows)
|
|
85
|
+
if target_is_directory is None and src_path.exists():
|
|
86
|
+
target_is_directory = src_path.is_dir()
|
|
87
|
+
|
|
88
|
+
# Create symlink
|
|
89
|
+
try:
|
|
90
|
+
if relative:
|
|
91
|
+
# Calculate relative path from dst to src
|
|
92
|
+
if src_path.is_absolute():
|
|
93
|
+
# src is absolute, calculate relative from dst
|
|
94
|
+
try:
|
|
95
|
+
rel_path = os.path.relpath(src_path, dst_path.parent)
|
|
96
|
+
src_for_link = Path(rel_path)
|
|
97
|
+
except ValueError:
|
|
98
|
+
# Can't create relative path (e.g., different drives on Windows)
|
|
99
|
+
logger.warning(
|
|
100
|
+
f"Cannot create relative path from {dst_path} to {src_path}, using absolute"
|
|
101
|
+
)
|
|
102
|
+
src_for_link = src_path.absolute()
|
|
103
|
+
else:
|
|
104
|
+
# Both paths are relative, need to resolve them first
|
|
105
|
+
# to calculate the correct relative path
|
|
106
|
+
src_abs = src_path.resolve()
|
|
107
|
+
dst_parent_abs = dst_path.parent.resolve()
|
|
108
|
+
try:
|
|
109
|
+
rel_path = os.path.relpath(src_abs, dst_parent_abs)
|
|
110
|
+
src_for_link = Path(rel_path)
|
|
111
|
+
except ValueError:
|
|
112
|
+
# Can't create relative path
|
|
113
|
+
logger.warning(
|
|
114
|
+
f"Cannot create relative path from {dst_path} to {src_path}"
|
|
115
|
+
)
|
|
116
|
+
src_for_link = src_path
|
|
117
|
+
else:
|
|
118
|
+
src_for_link = src_path.absolute()
|
|
119
|
+
|
|
120
|
+
dst_path.symlink_to(
|
|
121
|
+
src_for_link, target_is_directory=target_is_directory
|
|
122
|
+
)
|
|
123
|
+
logger.success(f"Created symlink: {dst_path} -> {src_for_link}")
|
|
124
|
+
|
|
125
|
+
except OSError as e:
|
|
126
|
+
logger.warn(
|
|
127
|
+
f"Failed to create symlink from {dst_path} to {src_for_link}: {str(e)}"
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
# raise OSError(
|
|
131
|
+
# f"Failed to create symlink from {dst_path} to {src_for_link}: {e}"
|
|
132
|
+
# )
|
|
133
|
+
|
|
134
|
+
return dst_path
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def is_symlink(path: Union[str, Path]) -> bool:
|
|
138
|
+
"""
|
|
139
|
+
Check if a path is a symbolic link.
|
|
140
|
+
|
|
141
|
+
Args:
|
|
142
|
+
path: Path to check
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
True if path is a symlink, False otherwise
|
|
146
|
+
|
|
147
|
+
Examples:
|
|
148
|
+
>>> import scitex as stx
|
|
149
|
+
>>> stx.path.is_symlink("/path/to/link")
|
|
150
|
+
False
|
|
151
|
+
"""
|
|
152
|
+
return Path(path).is_symlink()
|
|
153
|
+
|
|
154
|
+
|
|
155
|
+
def readlink(path: Union[str, Path]) -> Path:
|
|
156
|
+
"""
|
|
157
|
+
Return the path to which the symbolic link points.
|
|
158
|
+
|
|
159
|
+
Args:
|
|
160
|
+
path: Symlink path to read
|
|
161
|
+
|
|
162
|
+
Returns:
|
|
163
|
+
Path object pointing to the symlink target
|
|
164
|
+
|
|
165
|
+
Raises:
|
|
166
|
+
OSError: If path is not a symlink
|
|
167
|
+
|
|
168
|
+
Examples:
|
|
169
|
+
>>> import scitex as stx
|
|
170
|
+
>>> target = stx.path.readlink("/path/to/link")
|
|
171
|
+
>>> print(target)
|
|
172
|
+
"""
|
|
173
|
+
path = Path(path)
|
|
174
|
+
if not path.is_symlink():
|
|
175
|
+
raise OSError(f"Path is not a symbolic link: {path}")
|
|
176
|
+
|
|
177
|
+
return Path(os.readlink(path))
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
def resolve_symlinks(path: Union[str, Path]) -> Path:
|
|
181
|
+
"""
|
|
182
|
+
Resolve all symbolic links in a path.
|
|
183
|
+
|
|
184
|
+
Args:
|
|
185
|
+
path: Path potentially containing symlinks
|
|
186
|
+
|
|
187
|
+
Returns:
|
|
188
|
+
Fully resolved absolute path
|
|
189
|
+
|
|
190
|
+
Examples:
|
|
191
|
+
>>> import scitex as stx
|
|
192
|
+
>>> resolved = stx.path.resolve_symlinks("/path/with/symlinks")
|
|
193
|
+
>>> print(resolved)
|
|
194
|
+
"""
|
|
195
|
+
return Path(path).resolve()
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
def create_relative_symlink(
|
|
199
|
+
src: Union[str, Path], dst: Union[str, Path], overwrite: bool = False
|
|
200
|
+
) -> Path:
|
|
201
|
+
"""
|
|
202
|
+
Create a relative symbolic link.
|
|
203
|
+
|
|
204
|
+
This is a convenience wrapper around symlink() with relative=True.
|
|
205
|
+
|
|
206
|
+
Args:
|
|
207
|
+
src: Source path (target of the symlink)
|
|
208
|
+
dst: Destination path (the symlink to create)
|
|
209
|
+
overwrite: If True, remove existing dst before creating symlink
|
|
210
|
+
|
|
211
|
+
Returns:
|
|
212
|
+
Path object of the created symlink
|
|
213
|
+
|
|
214
|
+
Examples:
|
|
215
|
+
>>> import scitex as stx
|
|
216
|
+
>>> # Create relative symlink from current dir to parent dir file
|
|
217
|
+
>>> stx.path.create_relative_symlink("../data/file.txt", "link_to_file")
|
|
218
|
+
"""
|
|
219
|
+
return symlink(src, dst, overwrite=overwrite, relative=True)
|
|
220
|
+
|
|
221
|
+
|
|
222
|
+
def unlink_symlink(path: Union[str, Path], missing_ok: bool = True) -> None:
|
|
223
|
+
"""
|
|
224
|
+
Remove a symbolic link.
|
|
225
|
+
|
|
226
|
+
Args:
|
|
227
|
+
path: Symlink to remove
|
|
228
|
+
missing_ok: If True, don't raise error if symlink doesn't exist
|
|
229
|
+
|
|
230
|
+
Raises:
|
|
231
|
+
FileNotFoundError: If symlink doesn't exist and missing_ok=False
|
|
232
|
+
OSError: If path is not a symlink
|
|
233
|
+
|
|
234
|
+
Examples:
|
|
235
|
+
>>> import scitex as stx
|
|
236
|
+
>>> stx.path.unlink_symlink("/path/to/link")
|
|
237
|
+
"""
|
|
238
|
+
path = Path(path)
|
|
239
|
+
|
|
240
|
+
if not path.exists() and not path.is_symlink():
|
|
241
|
+
if missing_ok:
|
|
242
|
+
return
|
|
243
|
+
raise FileNotFoundError(f"Symlink does not exist: {path}")
|
|
244
|
+
|
|
245
|
+
if not path.is_symlink():
|
|
246
|
+
raise OSError(f"Path is not a symbolic link: {path}")
|
|
247
|
+
|
|
248
|
+
path.unlink()
|
|
249
|
+
# logger.info(f"Removed symlink: {path}")
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def list_symlinks(
|
|
253
|
+
directory: Union[str, Path], recursive: bool = False
|
|
254
|
+
) -> list[Path]:
|
|
255
|
+
"""
|
|
256
|
+
List all symbolic links in a directory.
|
|
257
|
+
|
|
258
|
+
Args:
|
|
259
|
+
directory: Directory to search
|
|
260
|
+
recursive: If True, search recursively
|
|
261
|
+
|
|
262
|
+
Returns:
|
|
263
|
+
List of Path objects for all symlinks found
|
|
264
|
+
|
|
265
|
+
Examples:
|
|
266
|
+
>>> import scitex as stx
|
|
267
|
+
>>> symlinks = stx.path.list_symlinks("/path/to/dir")
|
|
268
|
+
>>> for link in symlinks:
|
|
269
|
+
... print(f"{link} -> {stx.path.readlink(link)}")
|
|
270
|
+
"""
|
|
271
|
+
directory = Path(directory)
|
|
272
|
+
symlinks = []
|
|
273
|
+
|
|
274
|
+
if recursive:
|
|
275
|
+
for path in directory.rglob("*"):
|
|
276
|
+
if path.is_symlink():
|
|
277
|
+
symlinks.append(path)
|
|
278
|
+
else:
|
|
279
|
+
for path in directory.iterdir():
|
|
280
|
+
if path.is_symlink():
|
|
281
|
+
symlinks.append(path)
|
|
282
|
+
|
|
283
|
+
return symlinks
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def fix_broken_symlinks(
|
|
287
|
+
directory: Union[str, Path],
|
|
288
|
+
recursive: bool = False,
|
|
289
|
+
remove: bool = False,
|
|
290
|
+
new_target: Optional[Union[str, Path]] = None,
|
|
291
|
+
) -> dict:
|
|
292
|
+
"""
|
|
293
|
+
Find and optionally fix broken symbolic links.
|
|
294
|
+
|
|
295
|
+
Args:
|
|
296
|
+
directory: Directory to search
|
|
297
|
+
recursive: If True, search recursively
|
|
298
|
+
remove: If True, remove broken symlinks
|
|
299
|
+
new_target: If provided, repoint broken symlinks to this target
|
|
300
|
+
|
|
301
|
+
Returns:
|
|
302
|
+
Dictionary with 'found', 'fixed', and 'removed' lists of paths
|
|
303
|
+
|
|
304
|
+
Examples:
|
|
305
|
+
>>> import scitex as stx
|
|
306
|
+
>>> # Find broken symlinks
|
|
307
|
+
>>> result = stx.path.fix_broken_symlinks("/path/to/dir")
|
|
308
|
+
>>> print(f"Found {len(result['found'])} broken symlinks")
|
|
309
|
+
|
|
310
|
+
>>> # Remove broken symlinks
|
|
311
|
+
>>> result = stx.path.fix_broken_symlinks("/path/to/dir", remove=True)
|
|
312
|
+
"""
|
|
313
|
+
directory = Path(directory)
|
|
314
|
+
result = {"found": [], "fixed": [], "removed": []}
|
|
315
|
+
|
|
316
|
+
symlinks = list_symlinks(directory, recursive=recursive)
|
|
317
|
+
|
|
318
|
+
for link in symlinks:
|
|
319
|
+
try:
|
|
320
|
+
# Check if target exists
|
|
321
|
+
target = Path(os.readlink(link))
|
|
322
|
+
if (
|
|
323
|
+
not link.parent.joinpath(target).exists()
|
|
324
|
+
and not target.is_absolute()
|
|
325
|
+
):
|
|
326
|
+
# Relative link with non-existent target
|
|
327
|
+
result["found"].append(link)
|
|
328
|
+
elif target.is_absolute() and not target.exists():
|
|
329
|
+
# Absolute link with non-existent target
|
|
330
|
+
result["found"].append(link)
|
|
331
|
+
except (OSError, ValueError):
|
|
332
|
+
result["found"].append(link)
|
|
333
|
+
|
|
334
|
+
# Fix or remove broken symlinks
|
|
335
|
+
for link in result["found"]:
|
|
336
|
+
if remove:
|
|
337
|
+
link.unlink()
|
|
338
|
+
result["removed"].append(link)
|
|
339
|
+
# logger.info(f"Removed broken symlink: {link}")
|
|
340
|
+
elif new_target:
|
|
341
|
+
link.unlink()
|
|
342
|
+
symlink(new_target, link)
|
|
343
|
+
result["fixed"].append(link)
|
|
344
|
+
# logger.info(f"Fixed symlink: {link} -> {new_target}")
|
|
345
|
+
|
|
346
|
+
return result
|
|
347
|
+
|
|
348
|
+
# EOF
|
scitex/path/_version.py
CHANGED
|
@@ -8,7 +8,7 @@ import re
|
|
|
8
8
|
import sys
|
|
9
9
|
from glob import glob
|
|
10
10
|
|
|
11
|
-
|
|
11
|
+
# matplotlib imported in functions that need it
|
|
12
12
|
|
|
13
13
|
|
|
14
14
|
# Functions
|
|
@@ -82,14 +82,15 @@ def increment_version(dirname, fname, ext, version_prefix="_v"):
|
|
|
82
82
|
|
|
83
83
|
if __name__ == "__main__":
|
|
84
84
|
import scitex
|
|
85
|
+
import matplotlib.pyplot as plt
|
|
85
86
|
|
|
86
87
|
# Start
|
|
87
|
-
CONFIG, sys.stdout, sys.stderr, plt, CC = scitex.
|
|
88
|
+
CONFIG, sys.stdout, sys.stderr, plt, CC = scitex.session.start(sys, plt)
|
|
88
89
|
|
|
89
90
|
# (YOUR AWESOME CODE)
|
|
90
91
|
|
|
91
92
|
# Close
|
|
92
|
-
scitex.
|
|
93
|
+
scitex.session.close(CONFIG)
|
|
93
94
|
|
|
94
95
|
# EOF
|
|
95
96
|
|
scitex/pd/__init__.py
CHANGED
|
@@ -5,6 +5,7 @@ from ._find_indi import find_indi
|
|
|
5
5
|
from ._find_pval import find_pval, _find_pval_col
|
|
6
6
|
from ._force_df import force_df
|
|
7
7
|
from ._from_xyz import from_xyz
|
|
8
|
+
from ._get_unique import get_unique
|
|
8
9
|
from ._ignore_SettingWithCopyWarning import ignore_SettingWithCopyWarning, ignore_setting_with_copy_warning
|
|
9
10
|
from ._melt_cols import melt_cols
|
|
10
11
|
from ._merge_columns import merge_cols, merge_columns
|
|
@@ -23,6 +24,7 @@ __all__ = [
|
|
|
23
24
|
"_find_pval_col",
|
|
24
25
|
"force_df",
|
|
25
26
|
"from_xyz",
|
|
27
|
+
"get_unique",
|
|
26
28
|
"ignore_SettingWithCopyWarning",
|
|
27
29
|
"ignore_setting_with_copy_warning",
|
|
28
30
|
"melt_cols",
|
scitex/pd/_get_unique.py
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
# -*- coding: utf-8 -*-
|
|
3
|
+
# Timestamp: "2025-09-18 18:42:11 (ywatanabe)"
|
|
4
|
+
# File: /ssh:sp:/home/ywatanabe/proj/scitex_repo/src/scitex/pd/_get_unique.py
|
|
5
|
+
# ----------------------------------------
|
|
6
|
+
from __future__ import annotations
|
|
7
|
+
import os
|
|
8
|
+
__FILE__ = __file__
|
|
9
|
+
__DIR__ = os.path.dirname(__FILE__)
|
|
10
|
+
# ----------------------------------------
|
|
11
|
+
|
|
12
|
+
"""
|
|
13
|
+
Extract unique values from DataFrame columns.
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from typing import Any, Optional
|
|
17
|
+
|
|
18
|
+
import pandas as pd
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def get_unique(
|
|
22
|
+
df: pd.DataFrame,
|
|
23
|
+
column: str,
|
|
24
|
+
default: Optional[Any] = None,
|
|
25
|
+
raise_on_multiple: bool = False,
|
|
26
|
+
) -> Any:
|
|
27
|
+
"""Get value from column if it contains a unique value.
|
|
28
|
+
|
|
29
|
+
Args:
|
|
30
|
+
df: DataFrame to extract from
|
|
31
|
+
column: Column name to check
|
|
32
|
+
default: Default value if column doesn't exist or has multiple unique values
|
|
33
|
+
raise_on_multiple: If True, raise ValueError when multiple unique values exist
|
|
34
|
+
|
|
35
|
+
Returns:
|
|
36
|
+
The unique value if exactly one exists, otherwise default value
|
|
37
|
+
|
|
38
|
+
Examples:
|
|
39
|
+
>>> import pandas as pd
|
|
40
|
+
>>> df = pd.DataFrame({'patient_id': ['P01', 'P01', 'P01']})
|
|
41
|
+
>>> get_unique(df, 'patient_id')
|
|
42
|
+
'P01'
|
|
43
|
+
|
|
44
|
+
>>> df = pd.DataFrame({'patient_id': ['P01', 'P02']})
|
|
45
|
+
>>> get_unique(df, 'patient_id', default='Unknown')
|
|
46
|
+
'Unknown'
|
|
47
|
+
|
|
48
|
+
>>> # Raise error on multiple values
|
|
49
|
+
>>> get_unique(df, 'patient_id', raise_on_multiple=True)
|
|
50
|
+
ValueError: Column 'patient_id' has 2 unique values: ['P01', 'P02']
|
|
51
|
+
"""
|
|
52
|
+
if column not in df.columns:
|
|
53
|
+
if raise_on_multiple:
|
|
54
|
+
raise KeyError(f"Column '{column}' not found in DataFrame")
|
|
55
|
+
return default
|
|
56
|
+
|
|
57
|
+
unique_values = df[column].unique()
|
|
58
|
+
|
|
59
|
+
if len(unique_values) == 1:
|
|
60
|
+
return unique_values[0]
|
|
61
|
+
|
|
62
|
+
if len(unique_values) > 1 and raise_on_multiple:
|
|
63
|
+
raise ValueError(
|
|
64
|
+
f"Column '{column}' has {len(unique_values)} unique values: "
|
|
65
|
+
f"{list(unique_values[:5])}"
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
return default
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
if __name__ == "__main__":
|
|
72
|
+
# Test the function
|
|
73
|
+
import pandas as pd
|
|
74
|
+
|
|
75
|
+
# Test case 1: Unique value
|
|
76
|
+
df1 = pd.DataFrame({"patient_id": ["P01", "P01", "P01"]})
|
|
77
|
+
assert get_unique(df1, "patient_id") == "P01"
|
|
78
|
+
print("✓ Test 1 passed: Unique value extracted")
|
|
79
|
+
|
|
80
|
+
# Test case 2: Multiple values with default
|
|
81
|
+
df2 = pd.DataFrame({"patient_id": ["P01", "P02"]})
|
|
82
|
+
assert get_unique(df2, "patient_id", default="Unknown") == "Unknown"
|
|
83
|
+
print("✓ Test 2 passed: Default returned for multiple values")
|
|
84
|
+
|
|
85
|
+
# Test case 3: Missing column
|
|
86
|
+
assert get_unique(df1, "missing_col", default="N/A") == "N/A"
|
|
87
|
+
print("✓ Test 3 passed: Default returned for missing column")
|
|
88
|
+
|
|
89
|
+
# Test case 4: Raise on multiple
|
|
90
|
+
try:
|
|
91
|
+
get_unique(df2, "patient_id", raise_on_multiple=True)
|
|
92
|
+
assert False, "Should have raised ValueError"
|
|
93
|
+
except ValueError as e:
|
|
94
|
+
assert "has 2 unique values" in str(e)
|
|
95
|
+
print("✓ Test 4 passed: ValueError raised for multiple values")
|
|
96
|
+
|
|
97
|
+
print("\nAll tests passed!")
|
|
98
|
+
|
|
99
|
+
# EOF
|