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.
Files changed (572) hide show
  1. scitex/__init__.py +73 -0
  2. scitex/__main__.py +89 -0
  3. scitex/__version__.py +14 -0
  4. scitex/_sh.py +59 -0
  5. scitex/ai/_LearningCurveLogger.py +583 -0
  6. scitex/ai/__Classifiers.py +101 -0
  7. scitex/ai/__init__.py +55 -0
  8. scitex/ai/_gen_ai/_Anthropic.py +173 -0
  9. scitex/ai/_gen_ai/_BaseGenAI.py +336 -0
  10. scitex/ai/_gen_ai/_DeepSeek.py +175 -0
  11. scitex/ai/_gen_ai/_Google.py +161 -0
  12. scitex/ai/_gen_ai/_Groq.py +97 -0
  13. scitex/ai/_gen_ai/_Llama.py +142 -0
  14. scitex/ai/_gen_ai/_OpenAI.py +230 -0
  15. scitex/ai/_gen_ai/_PARAMS.py +565 -0
  16. scitex/ai/_gen_ai/_Perplexity.py +191 -0
  17. scitex/ai/_gen_ai/__init__.py +32 -0
  18. scitex/ai/_gen_ai/_calc_cost.py +78 -0
  19. scitex/ai/_gen_ai/_format_output_func.py +183 -0
  20. scitex/ai/_gen_ai/_genai_factory.py +71 -0
  21. scitex/ai/act/__init__.py +8 -0
  22. scitex/ai/act/_define.py +11 -0
  23. scitex/ai/classification/__init__.py +7 -0
  24. scitex/ai/classification/classification_reporter.py +1137 -0
  25. scitex/ai/classification/classifier_server.py +131 -0
  26. scitex/ai/classification/classifiers.py +101 -0
  27. scitex/ai/classification_reporter.py +1161 -0
  28. scitex/ai/classifier_server.py +131 -0
  29. scitex/ai/clustering/__init__.py +11 -0
  30. scitex/ai/clustering/_pca.py +115 -0
  31. scitex/ai/clustering/_umap.py +376 -0
  32. scitex/ai/early_stopping.py +149 -0
  33. scitex/ai/feature_extraction/__init__.py +56 -0
  34. scitex/ai/feature_extraction/vit.py +148 -0
  35. scitex/ai/genai/__init__.py +277 -0
  36. scitex/ai/genai/anthropic.py +177 -0
  37. scitex/ai/genai/anthropic_provider.py +320 -0
  38. scitex/ai/genai/anthropic_refactored.py +109 -0
  39. scitex/ai/genai/auth_manager.py +200 -0
  40. scitex/ai/genai/base_genai.py +336 -0
  41. scitex/ai/genai/base_provider.py +291 -0
  42. scitex/ai/genai/calc_cost.py +78 -0
  43. scitex/ai/genai/chat_history.py +307 -0
  44. scitex/ai/genai/cost_tracker.py +276 -0
  45. scitex/ai/genai/deepseek.py +188 -0
  46. scitex/ai/genai/deepseek_provider.py +251 -0
  47. scitex/ai/genai/format_output_func.py +183 -0
  48. scitex/ai/genai/genai_factory.py +71 -0
  49. scitex/ai/genai/google.py +169 -0
  50. scitex/ai/genai/google_provider.py +228 -0
  51. scitex/ai/genai/groq.py +104 -0
  52. scitex/ai/genai/groq_provider.py +248 -0
  53. scitex/ai/genai/image_processor.py +250 -0
  54. scitex/ai/genai/llama.py +155 -0
  55. scitex/ai/genai/llama_provider.py +214 -0
  56. scitex/ai/genai/mock_provider.py +127 -0
  57. scitex/ai/genai/model_registry.py +304 -0
  58. scitex/ai/genai/openai.py +230 -0
  59. scitex/ai/genai/openai_provider.py +293 -0
  60. scitex/ai/genai/params.py +565 -0
  61. scitex/ai/genai/perplexity.py +202 -0
  62. scitex/ai/genai/perplexity_provider.py +205 -0
  63. scitex/ai/genai/provider_base.py +302 -0
  64. scitex/ai/genai/provider_factory.py +370 -0
  65. scitex/ai/genai/response_handler.py +235 -0
  66. scitex/ai/layer/_Pass.py +21 -0
  67. scitex/ai/layer/__init__.py +10 -0
  68. scitex/ai/layer/_switch.py +8 -0
  69. scitex/ai/loss/_L1L2Losses.py +34 -0
  70. scitex/ai/loss/__init__.py +12 -0
  71. scitex/ai/loss/multi_task_loss.py +47 -0
  72. scitex/ai/metrics/__init__.py +9 -0
  73. scitex/ai/metrics/_bACC.py +51 -0
  74. scitex/ai/metrics/silhoute_score_block.py +496 -0
  75. scitex/ai/optim/Ranger_Deep_Learning_Optimizer/__init__.py +0 -0
  76. scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/__init__.py +3 -0
  77. scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger.py +207 -0
  78. scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger2020.py +238 -0
  79. scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger913A.py +215 -0
  80. scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/rangerqh.py +184 -0
  81. scitex/ai/optim/Ranger_Deep_Learning_Optimizer/setup.py +24 -0
  82. scitex/ai/optim/__init__.py +13 -0
  83. scitex/ai/optim/_get_set.py +31 -0
  84. scitex/ai/optim/_optimizers.py +71 -0
  85. scitex/ai/plt/__init__.py +21 -0
  86. scitex/ai/plt/_conf_mat.py +592 -0
  87. scitex/ai/plt/_learning_curve.py +194 -0
  88. scitex/ai/plt/_optuna_study.py +111 -0
  89. scitex/ai/plt/aucs/__init__.py +2 -0
  90. scitex/ai/plt/aucs/example.py +60 -0
  91. scitex/ai/plt/aucs/pre_rec_auc.py +223 -0
  92. scitex/ai/plt/aucs/roc_auc.py +246 -0
  93. scitex/ai/sampling/undersample.py +29 -0
  94. scitex/ai/sk/__init__.py +11 -0
  95. scitex/ai/sk/_clf.py +58 -0
  96. scitex/ai/sk/_to_sktime.py +100 -0
  97. scitex/ai/sklearn/__init__.py +26 -0
  98. scitex/ai/sklearn/clf.py +58 -0
  99. scitex/ai/sklearn/to_sktime.py +100 -0
  100. scitex/ai/training/__init__.py +7 -0
  101. scitex/ai/training/early_stopping.py +150 -0
  102. scitex/ai/training/learning_curve_logger.py +555 -0
  103. scitex/ai/utils/__init__.py +22 -0
  104. scitex/ai/utils/_check_params.py +50 -0
  105. scitex/ai/utils/_default_dataset.py +46 -0
  106. scitex/ai/utils/_format_samples_for_sktime.py +26 -0
  107. scitex/ai/utils/_label_encoder.py +134 -0
  108. scitex/ai/utils/_merge_labels.py +22 -0
  109. scitex/ai/utils/_sliding_window_data_augmentation.py +11 -0
  110. scitex/ai/utils/_under_sample.py +51 -0
  111. scitex/ai/utils/_verify_n_gpus.py +16 -0
  112. scitex/ai/utils/grid_search.py +148 -0
  113. scitex/context/__init__.py +9 -0
  114. scitex/context/_suppress_output.py +38 -0
  115. scitex/db/_BaseMixins/_BaseBackupMixin.py +30 -0
  116. scitex/db/_BaseMixins/_BaseBatchMixin.py +31 -0
  117. scitex/db/_BaseMixins/_BaseBlobMixin.py +81 -0
  118. scitex/db/_BaseMixins/_BaseConnectionMixin.py +43 -0
  119. scitex/db/_BaseMixins/_BaseImportExportMixin.py +39 -0
  120. scitex/db/_BaseMixins/_BaseIndexMixin.py +29 -0
  121. scitex/db/_BaseMixins/_BaseMaintenanceMixin.py +33 -0
  122. scitex/db/_BaseMixins/_BaseQueryMixin.py +52 -0
  123. scitex/db/_BaseMixins/_BaseRowMixin.py +32 -0
  124. scitex/db/_BaseMixins/_BaseSchemaMixin.py +44 -0
  125. scitex/db/_BaseMixins/_BaseTableMixin.py +66 -0
  126. scitex/db/_BaseMixins/_BaseTransactionMixin.py +52 -0
  127. scitex/db/_BaseMixins/__init__.py +30 -0
  128. scitex/db/_PostgreSQL.py +126 -0
  129. scitex/db/_PostgreSQLMixins/_BackupMixin.py +166 -0
  130. scitex/db/_PostgreSQLMixins/_BatchMixin.py +82 -0
  131. scitex/db/_PostgreSQLMixins/_BlobMixin.py +231 -0
  132. scitex/db/_PostgreSQLMixins/_ConnectionMixin.py +92 -0
  133. scitex/db/_PostgreSQLMixins/_ImportExportMixin.py +59 -0
  134. scitex/db/_PostgreSQLMixins/_IndexMixin.py +64 -0
  135. scitex/db/_PostgreSQLMixins/_MaintenanceMixin.py +175 -0
  136. scitex/db/_PostgreSQLMixins/_QueryMixin.py +108 -0
  137. scitex/db/_PostgreSQLMixins/_RowMixin.py +75 -0
  138. scitex/db/_PostgreSQLMixins/_SchemaMixin.py +126 -0
  139. scitex/db/_PostgreSQLMixins/_TableMixin.py +176 -0
  140. scitex/db/_PostgreSQLMixins/_TransactionMixin.py +57 -0
  141. scitex/db/_PostgreSQLMixins/__init__.py +34 -0
  142. scitex/db/_SQLite3.py +2136 -0
  143. scitex/db/_SQLite3Mixins/_BatchMixin.py +243 -0
  144. scitex/db/_SQLite3Mixins/_BlobMixin.py +229 -0
  145. scitex/db/_SQLite3Mixins/_ConnectionMixin.py +108 -0
  146. scitex/db/_SQLite3Mixins/_ImportExportMixin.py +80 -0
  147. scitex/db/_SQLite3Mixins/_IndexMixin.py +32 -0
  148. scitex/db/_SQLite3Mixins/_MaintenanceMixin.py +176 -0
  149. scitex/db/_SQLite3Mixins/_QueryMixin.py +83 -0
  150. scitex/db/_SQLite3Mixins/_RowMixin.py +75 -0
  151. scitex/db/_SQLite3Mixins/_TableMixin.py +183 -0
  152. scitex/db/_SQLite3Mixins/_TransactionMixin.py +71 -0
  153. scitex/db/_SQLite3Mixins/__init__.py +30 -0
  154. scitex/db/__init__.py +14 -0
  155. scitex/db/_delete_duplicates.py +397 -0
  156. scitex/db/_inspect.py +163 -0
  157. scitex/decorators/__init__.py +54 -0
  158. scitex/decorators/_auto_order.py +172 -0
  159. scitex/decorators/_batch_fn.py +127 -0
  160. scitex/decorators/_cache_disk.py +32 -0
  161. scitex/decorators/_cache_mem.py +12 -0
  162. scitex/decorators/_combined.py +98 -0
  163. scitex/decorators/_converters.py +282 -0
  164. scitex/decorators/_deprecated.py +26 -0
  165. scitex/decorators/_not_implemented.py +30 -0
  166. scitex/decorators/_numpy_fn.py +86 -0
  167. scitex/decorators/_pandas_fn.py +121 -0
  168. scitex/decorators/_preserve_doc.py +19 -0
  169. scitex/decorators/_signal_fn.py +95 -0
  170. scitex/decorators/_timeout.py +55 -0
  171. scitex/decorators/_torch_fn.py +136 -0
  172. scitex/decorators/_wrap.py +39 -0
  173. scitex/decorators/_xarray_fn.py +88 -0
  174. scitex/dev/__init__.py +15 -0
  175. scitex/dev/_analyze_code_flow.py +284 -0
  176. scitex/dev/_reload.py +59 -0
  177. scitex/dict/_DotDict.py +442 -0
  178. scitex/dict/__init__.py +18 -0
  179. scitex/dict/_listed_dict.py +42 -0
  180. scitex/dict/_pop_keys.py +36 -0
  181. scitex/dict/_replace.py +13 -0
  182. scitex/dict/_safe_merge.py +62 -0
  183. scitex/dict/_to_str.py +32 -0
  184. scitex/dsp/__init__.py +72 -0
  185. scitex/dsp/_crop.py +122 -0
  186. scitex/dsp/_demo_sig.py +331 -0
  187. scitex/dsp/_detect_ripples.py +212 -0
  188. scitex/dsp/_ensure_3d.py +18 -0
  189. scitex/dsp/_hilbert.py +78 -0
  190. scitex/dsp/_listen.py +702 -0
  191. scitex/dsp/_misc.py +30 -0
  192. scitex/dsp/_mne.py +32 -0
  193. scitex/dsp/_modulation_index.py +79 -0
  194. scitex/dsp/_pac.py +319 -0
  195. scitex/dsp/_psd.py +102 -0
  196. scitex/dsp/_resample.py +65 -0
  197. scitex/dsp/_time.py +36 -0
  198. scitex/dsp/_transform.py +68 -0
  199. scitex/dsp/_wavelet.py +212 -0
  200. scitex/dsp/add_noise.py +111 -0
  201. scitex/dsp/example.py +253 -0
  202. scitex/dsp/filt.py +155 -0
  203. scitex/dsp/norm.py +18 -0
  204. scitex/dsp/params.py +51 -0
  205. scitex/dsp/reference.py +43 -0
  206. scitex/dsp/template.py +25 -0
  207. scitex/dsp/utils/__init__.py +15 -0
  208. scitex/dsp/utils/_differential_bandpass_filters.py +120 -0
  209. scitex/dsp/utils/_ensure_3d.py +18 -0
  210. scitex/dsp/utils/_ensure_even_len.py +10 -0
  211. scitex/dsp/utils/_zero_pad.py +48 -0
  212. scitex/dsp/utils/filter.py +408 -0
  213. scitex/dsp/utils/pac.py +177 -0
  214. scitex/dt/__init__.py +8 -0
  215. scitex/dt/_linspace.py +130 -0
  216. scitex/etc/__init__.py +15 -0
  217. scitex/etc/wait_key.py +34 -0
  218. scitex/gen/_DimHandler.py +196 -0
  219. scitex/gen/_TimeStamper.py +244 -0
  220. scitex/gen/__init__.py +95 -0
  221. scitex/gen/_alternate_kwarg.py +13 -0
  222. scitex/gen/_cache.py +11 -0
  223. scitex/gen/_check_host.py +34 -0
  224. scitex/gen/_ci.py +12 -0
  225. scitex/gen/_close.py +222 -0
  226. scitex/gen/_embed.py +78 -0
  227. scitex/gen/_inspect_module.py +257 -0
  228. scitex/gen/_is_ipython.py +12 -0
  229. scitex/gen/_less.py +48 -0
  230. scitex/gen/_list_packages.py +139 -0
  231. scitex/gen/_mat2py.py +88 -0
  232. scitex/gen/_norm.py +170 -0
  233. scitex/gen/_paste.py +18 -0
  234. scitex/gen/_print_config.py +84 -0
  235. scitex/gen/_shell.py +48 -0
  236. scitex/gen/_src.py +111 -0
  237. scitex/gen/_start.py +451 -0
  238. scitex/gen/_symlink.py +55 -0
  239. scitex/gen/_symlog.py +27 -0
  240. scitex/gen/_tee.py +238 -0
  241. scitex/gen/_title2path.py +60 -0
  242. scitex/gen/_title_case.py +88 -0
  243. scitex/gen/_to_even.py +84 -0
  244. scitex/gen/_to_odd.py +34 -0
  245. scitex/gen/_to_rank.py +39 -0
  246. scitex/gen/_transpose.py +37 -0
  247. scitex/gen/_type.py +78 -0
  248. scitex/gen/_var_info.py +73 -0
  249. scitex/gen/_wrap.py +17 -0
  250. scitex/gen/_xml2dict.py +76 -0
  251. scitex/gen/misc.py +730 -0
  252. scitex/gen/path.py +0 -0
  253. scitex/general/__init__.py +5 -0
  254. scitex/gists/_SigMacro_processFigure_S.py +128 -0
  255. scitex/gists/_SigMacro_toBlue.py +172 -0
  256. scitex/gists/__init__.py +12 -0
  257. scitex/io/_H5Explorer.py +292 -0
  258. scitex/io/__init__.py +82 -0
  259. scitex/io/_cache.py +101 -0
  260. scitex/io/_flush.py +24 -0
  261. scitex/io/_glob.py +103 -0
  262. scitex/io/_json2md.py +113 -0
  263. scitex/io/_load.py +168 -0
  264. scitex/io/_load_configs.py +146 -0
  265. scitex/io/_load_modules/__init__.py +38 -0
  266. scitex/io/_load_modules/_catboost.py +66 -0
  267. scitex/io/_load_modules/_con.py +20 -0
  268. scitex/io/_load_modules/_db.py +24 -0
  269. scitex/io/_load_modules/_docx.py +42 -0
  270. scitex/io/_load_modules/_eeg.py +110 -0
  271. scitex/io/_load_modules/_hdf5.py +196 -0
  272. scitex/io/_load_modules/_image.py +19 -0
  273. scitex/io/_load_modules/_joblib.py +19 -0
  274. scitex/io/_load_modules/_json.py +18 -0
  275. scitex/io/_load_modules/_markdown.py +103 -0
  276. scitex/io/_load_modules/_matlab.py +37 -0
  277. scitex/io/_load_modules/_numpy.py +39 -0
  278. scitex/io/_load_modules/_optuna.py +155 -0
  279. scitex/io/_load_modules/_pandas.py +69 -0
  280. scitex/io/_load_modules/_pdf.py +31 -0
  281. scitex/io/_load_modules/_pickle.py +24 -0
  282. scitex/io/_load_modules/_torch.py +16 -0
  283. scitex/io/_load_modules/_txt.py +126 -0
  284. scitex/io/_load_modules/_xml.py +49 -0
  285. scitex/io/_load_modules/_yaml.py +23 -0
  286. scitex/io/_mv_to_tmp.py +19 -0
  287. scitex/io/_path.py +286 -0
  288. scitex/io/_reload.py +78 -0
  289. scitex/io/_save.py +539 -0
  290. scitex/io/_save_modules/__init__.py +66 -0
  291. scitex/io/_save_modules/_catboost.py +22 -0
  292. scitex/io/_save_modules/_csv.py +89 -0
  293. scitex/io/_save_modules/_excel.py +49 -0
  294. scitex/io/_save_modules/_hdf5.py +249 -0
  295. scitex/io/_save_modules/_html.py +48 -0
  296. scitex/io/_save_modules/_image.py +140 -0
  297. scitex/io/_save_modules/_joblib.py +25 -0
  298. scitex/io/_save_modules/_json.py +25 -0
  299. scitex/io/_save_modules/_listed_dfs_as_csv.py +57 -0
  300. scitex/io/_save_modules/_listed_scalars_as_csv.py +42 -0
  301. scitex/io/_save_modules/_matlab.py +24 -0
  302. scitex/io/_save_modules/_mp4.py +29 -0
  303. scitex/io/_save_modules/_numpy.py +57 -0
  304. scitex/io/_save_modules/_optuna_study_as_csv_and_pngs.py +38 -0
  305. scitex/io/_save_modules/_pickle.py +45 -0
  306. scitex/io/_save_modules/_plotly.py +27 -0
  307. scitex/io/_save_modules/_text.py +23 -0
  308. scitex/io/_save_modules/_torch.py +26 -0
  309. scitex/io/_save_modules/_yaml.py +29 -0
  310. scitex/life/__init__.py +10 -0
  311. scitex/life/_monitor_rain.py +49 -0
  312. scitex/linalg/__init__.py +17 -0
  313. scitex/linalg/_distance.py +63 -0
  314. scitex/linalg/_geometric_median.py +64 -0
  315. scitex/linalg/_misc.py +73 -0
  316. scitex/nn/_AxiswiseDropout.py +27 -0
  317. scitex/nn/_BNet.py +126 -0
  318. scitex/nn/_BNet_Res.py +164 -0
  319. scitex/nn/_ChannelGainChanger.py +44 -0
  320. scitex/nn/_DropoutChannels.py +50 -0
  321. scitex/nn/_Filters.py +489 -0
  322. scitex/nn/_FreqGainChanger.py +110 -0
  323. scitex/nn/_GaussianFilter.py +48 -0
  324. scitex/nn/_Hilbert.py +111 -0
  325. scitex/nn/_MNet_1000.py +157 -0
  326. scitex/nn/_ModulationIndex.py +221 -0
  327. scitex/nn/_PAC.py +414 -0
  328. scitex/nn/_PSD.py +40 -0
  329. scitex/nn/_ResNet1D.py +120 -0
  330. scitex/nn/_SpatialAttention.py +25 -0
  331. scitex/nn/_Spectrogram.py +161 -0
  332. scitex/nn/_SwapChannels.py +50 -0
  333. scitex/nn/_TransposeLayer.py +19 -0
  334. scitex/nn/_Wavelet.py +183 -0
  335. scitex/nn/__init__.py +63 -0
  336. scitex/os/__init__.py +8 -0
  337. scitex/os/_mv.py +50 -0
  338. scitex/parallel/__init__.py +8 -0
  339. scitex/parallel/_run.py +151 -0
  340. scitex/path/__init__.py +33 -0
  341. scitex/path/_clean.py +52 -0
  342. scitex/path/_find.py +108 -0
  343. scitex/path/_get_module_path.py +51 -0
  344. scitex/path/_get_spath.py +35 -0
  345. scitex/path/_getsize.py +18 -0
  346. scitex/path/_increment_version.py +87 -0
  347. scitex/path/_mk_spath.py +51 -0
  348. scitex/path/_path.py +19 -0
  349. scitex/path/_split.py +23 -0
  350. scitex/path/_this_path.py +19 -0
  351. scitex/path/_version.py +101 -0
  352. scitex/pd/__init__.py +41 -0
  353. scitex/pd/_find_indi.py +126 -0
  354. scitex/pd/_find_pval.py +113 -0
  355. scitex/pd/_force_df.py +154 -0
  356. scitex/pd/_from_xyz.py +71 -0
  357. scitex/pd/_ignore_SettingWithCopyWarning.py +34 -0
  358. scitex/pd/_melt_cols.py +81 -0
  359. scitex/pd/_merge_columns.py +221 -0
  360. scitex/pd/_mv.py +63 -0
  361. scitex/pd/_replace.py +62 -0
  362. scitex/pd/_round.py +93 -0
  363. scitex/pd/_slice.py +63 -0
  364. scitex/pd/_sort.py +91 -0
  365. scitex/pd/_to_numeric.py +53 -0
  366. scitex/pd/_to_xy.py +59 -0
  367. scitex/pd/_to_xyz.py +110 -0
  368. scitex/plt/__init__.py +36 -0
  369. scitex/plt/_subplots/_AxesWrapper.py +182 -0
  370. scitex/plt/_subplots/_AxisWrapper.py +249 -0
  371. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin.py +414 -0
  372. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin.py +896 -0
  373. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin.py +368 -0
  374. scitex/plt/_subplots/_AxisWrapperMixins/_TrackingMixin.py +185 -0
  375. scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +16 -0
  376. scitex/plt/_subplots/_FigWrapper.py +226 -0
  377. scitex/plt/_subplots/_SubplotsWrapper.py +171 -0
  378. scitex/plt/_subplots/__init__.py +111 -0
  379. scitex/plt/_subplots/_export_as_csv.py +232 -0
  380. scitex/plt/_subplots/_export_as_csv_formatters/__init__.py +61 -0
  381. scitex/plt/_subplots/_export_as_csv_formatters/_format_bar.py +90 -0
  382. scitex/plt/_subplots/_export_as_csv_formatters/_format_barh.py +49 -0
  383. scitex/plt/_subplots/_export_as_csv_formatters/_format_boxplot.py +46 -0
  384. scitex/plt/_subplots/_export_as_csv_formatters/_format_contour.py +39 -0
  385. scitex/plt/_subplots/_export_as_csv_formatters/_format_errorbar.py +125 -0
  386. scitex/plt/_subplots/_export_as_csv_formatters/_format_eventplot.py +72 -0
  387. scitex/plt/_subplots/_export_as_csv_formatters/_format_fill.py +34 -0
  388. scitex/plt/_subplots/_export_as_csv_formatters/_format_fill_between.py +36 -0
  389. scitex/plt/_subplots/_export_as_csv_formatters/_format_hist.py +79 -0
  390. scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow.py +59 -0
  391. scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow2d.py +32 -0
  392. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot.py +79 -0
  393. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_box.py +75 -0
  394. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_conf_mat.py +64 -0
  395. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_ecdf.py +44 -0
  396. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_fillv.py +70 -0
  397. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_heatmap.py +66 -0
  398. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_image.py +95 -0
  399. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_joyplot.py +67 -0
  400. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_kde.py +52 -0
  401. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_line.py +46 -0
  402. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_mean_ci.py +46 -0
  403. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_mean_std.py +46 -0
  404. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_median_iqr.py +46 -0
  405. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_raster.py +44 -0
  406. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_rectangle.py +103 -0
  407. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter_hist.py +82 -0
  408. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_shaded_line.py +58 -0
  409. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_violin.py +117 -0
  410. scitex/plt/_subplots/_export_as_csv_formatters/_format_scatter.py +30 -0
  411. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_barplot.py +51 -0
  412. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_boxplot.py +93 -0
  413. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_heatmap.py +94 -0
  414. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_histplot.py +92 -0
  415. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_jointplot.py +65 -0
  416. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_kdeplot.py +59 -0
  417. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_lineplot.py +58 -0
  418. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_pairplot.py +45 -0
  419. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_scatterplot.py +70 -0
  420. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_stripplot.py +75 -0
  421. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_swarmplot.py +75 -0
  422. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_violinplot.py +155 -0
  423. scitex/plt/_subplots/_export_as_csv_formatters/_format_violin.py +64 -0
  424. scitex/plt/_subplots/_export_as_csv_formatters/_format_violinplot.py +77 -0
  425. scitex/plt/_subplots/_export_as_csv_formatters/test_formatters.py +210 -0
  426. scitex/plt/_subplots/_export_as_csv_formatters/verify_formatters.py +342 -0
  427. scitex/plt/_subplots/_export_as_csv_formatters.py +115 -0
  428. scitex/plt/_tpl.py +28 -0
  429. scitex/plt/ax/__init__.py +114 -0
  430. scitex/plt/ax/_plot/__init__.py +53 -0
  431. scitex/plt/ax/_plot/_plot_circular_hist.py +124 -0
  432. scitex/plt/ax/_plot/_plot_conf_mat.py +136 -0
  433. scitex/plt/ax/_plot/_plot_cube.py +57 -0
  434. scitex/plt/ax/_plot/_plot_ecdf.py +84 -0
  435. scitex/plt/ax/_plot/_plot_fillv.py +55 -0
  436. scitex/plt/ax/_plot/_plot_heatmap.py +266 -0
  437. scitex/plt/ax/_plot/_plot_image.py +94 -0
  438. scitex/plt/ax/_plot/_plot_joyplot.py +76 -0
  439. scitex/plt/ax/_plot/_plot_raster.py +172 -0
  440. scitex/plt/ax/_plot/_plot_rectangle.py +69 -0
  441. scitex/plt/ax/_plot/_plot_scatter_hist.py +133 -0
  442. scitex/plt/ax/_plot/_plot_shaded_line.py +142 -0
  443. scitex/plt/ax/_plot/_plot_statistical_shaded_line.py +221 -0
  444. scitex/plt/ax/_plot/_plot_violin.py +343 -0
  445. scitex/plt/ax/_style/__init__.py +38 -0
  446. scitex/plt/ax/_style/_add_marginal_ax.py +44 -0
  447. scitex/plt/ax/_style/_add_panel.py +92 -0
  448. scitex/plt/ax/_style/_extend.py +64 -0
  449. scitex/plt/ax/_style/_force_aspect.py +37 -0
  450. scitex/plt/ax/_style/_format_label.py +23 -0
  451. scitex/plt/ax/_style/_hide_spines.py +84 -0
  452. scitex/plt/ax/_style/_map_ticks.py +182 -0
  453. scitex/plt/ax/_style/_rotate_labels.py +215 -0
  454. scitex/plt/ax/_style/_sci_note.py +279 -0
  455. scitex/plt/ax/_style/_set_log_scale.py +299 -0
  456. scitex/plt/ax/_style/_set_meta.py +261 -0
  457. scitex/plt/ax/_style/_set_n_ticks.py +37 -0
  458. scitex/plt/ax/_style/_set_size.py +16 -0
  459. scitex/plt/ax/_style/_set_supxyt.py +116 -0
  460. scitex/plt/ax/_style/_set_ticks.py +276 -0
  461. scitex/plt/ax/_style/_set_xyt.py +121 -0
  462. scitex/plt/ax/_style/_share_axes.py +264 -0
  463. scitex/plt/ax/_style/_shift.py +139 -0
  464. scitex/plt/ax/_style/_show_spines.py +333 -0
  465. scitex/plt/color/_PARAMS.py +70 -0
  466. scitex/plt/color/__init__.py +52 -0
  467. scitex/plt/color/_add_hue_col.py +41 -0
  468. scitex/plt/color/_colors.py +205 -0
  469. scitex/plt/color/_get_colors_from_cmap.py +134 -0
  470. scitex/plt/color/_interpolate.py +29 -0
  471. scitex/plt/color/_vizualize_colors.py +54 -0
  472. scitex/plt/utils/__init__.py +44 -0
  473. scitex/plt/utils/_calc_bacc_from_conf_mat.py +46 -0
  474. scitex/plt/utils/_calc_nice_ticks.py +101 -0
  475. scitex/plt/utils/_close.py +68 -0
  476. scitex/plt/utils/_colorbar.py +96 -0
  477. scitex/plt/utils/_configure_mpl.py +295 -0
  478. scitex/plt/utils/_histogram_utils.py +132 -0
  479. scitex/plt/utils/_im2grid.py +70 -0
  480. scitex/plt/utils/_is_valid_axis.py +78 -0
  481. scitex/plt/utils/_mk_colorbar.py +65 -0
  482. scitex/plt/utils/_mk_patches.py +26 -0
  483. scitex/plt/utils/_scientific_captions.py +638 -0
  484. scitex/plt/utils/_scitex_config.py +223 -0
  485. scitex/reproduce/__init__.py +14 -0
  486. scitex/reproduce/_fix_seeds.py +45 -0
  487. scitex/reproduce/_gen_ID.py +55 -0
  488. scitex/reproduce/_gen_timestamp.py +35 -0
  489. scitex/res/__init__.py +5 -0
  490. scitex/resource/__init__.py +13 -0
  491. scitex/resource/_get_processor_usages.py +281 -0
  492. scitex/resource/_get_specs.py +280 -0
  493. scitex/resource/_log_processor_usages.py +190 -0
  494. scitex/resource/_utils/__init__.py +31 -0
  495. scitex/resource/_utils/_get_env_info.py +481 -0
  496. scitex/resource/limit_ram.py +33 -0
  497. scitex/scholar/__init__.py +24 -0
  498. scitex/scholar/_local_search.py +454 -0
  499. scitex/scholar/_paper.py +244 -0
  500. scitex/scholar/_pdf_downloader.py +325 -0
  501. scitex/scholar/_search.py +393 -0
  502. scitex/scholar/_vector_search.py +370 -0
  503. scitex/scholar/_web_sources.py +457 -0
  504. scitex/stats/__init__.py +31 -0
  505. scitex/stats/_calc_partial_corr.py +17 -0
  506. scitex/stats/_corr_test_multi.py +94 -0
  507. scitex/stats/_corr_test_wrapper.py +115 -0
  508. scitex/stats/_describe_wrapper.py +90 -0
  509. scitex/stats/_multiple_corrections.py +63 -0
  510. scitex/stats/_nan_stats.py +93 -0
  511. scitex/stats/_p2stars.py +116 -0
  512. scitex/stats/_p2stars_wrapper.py +56 -0
  513. scitex/stats/_statistical_tests.py +73 -0
  514. scitex/stats/desc/__init__.py +40 -0
  515. scitex/stats/desc/_describe.py +189 -0
  516. scitex/stats/desc/_nan.py +289 -0
  517. scitex/stats/desc/_real.py +94 -0
  518. scitex/stats/multiple/__init__.py +14 -0
  519. scitex/stats/multiple/_bonferroni_correction.py +72 -0
  520. scitex/stats/multiple/_fdr_correction.py +400 -0
  521. scitex/stats/multiple/_multicompair.py +28 -0
  522. scitex/stats/tests/__corr_test.py +277 -0
  523. scitex/stats/tests/__corr_test_multi.py +343 -0
  524. scitex/stats/tests/__corr_test_single.py +277 -0
  525. scitex/stats/tests/__init__.py +22 -0
  526. scitex/stats/tests/_brunner_munzel_test.py +192 -0
  527. scitex/stats/tests/_nocorrelation_test.py +28 -0
  528. scitex/stats/tests/_smirnov_grubbs.py +98 -0
  529. scitex/str/__init__.py +113 -0
  530. scitex/str/_clean_path.py +75 -0
  531. scitex/str/_color_text.py +52 -0
  532. scitex/str/_decapitalize.py +58 -0
  533. scitex/str/_factor_out_digits.py +281 -0
  534. scitex/str/_format_plot_text.py +498 -0
  535. scitex/str/_grep.py +48 -0
  536. scitex/str/_latex.py +155 -0
  537. scitex/str/_latex_fallback.py +471 -0
  538. scitex/str/_mask_api.py +39 -0
  539. scitex/str/_mask_api_key.py +8 -0
  540. scitex/str/_parse.py +158 -0
  541. scitex/str/_print_block.py +47 -0
  542. scitex/str/_print_debug.py +68 -0
  543. scitex/str/_printc.py +62 -0
  544. scitex/str/_readable_bytes.py +38 -0
  545. scitex/str/_remove_ansi.py +23 -0
  546. scitex/str/_replace.py +134 -0
  547. scitex/str/_search.py +125 -0
  548. scitex/str/_squeeze_space.py +36 -0
  549. scitex/tex/__init__.py +10 -0
  550. scitex/tex/_preview.py +103 -0
  551. scitex/tex/_to_vec.py +116 -0
  552. scitex/torch/__init__.py +18 -0
  553. scitex/torch/_apply_to.py +34 -0
  554. scitex/torch/_nan_funcs.py +77 -0
  555. scitex/types/_ArrayLike.py +44 -0
  556. scitex/types/_ColorLike.py +21 -0
  557. scitex/types/__init__.py +14 -0
  558. scitex/types/_is_listed_X.py +70 -0
  559. scitex/utils/__init__.py +22 -0
  560. scitex/utils/_compress_hdf5.py +116 -0
  561. scitex/utils/_email.py +120 -0
  562. scitex/utils/_grid.py +148 -0
  563. scitex/utils/_notify.py +247 -0
  564. scitex/utils/_search.py +121 -0
  565. scitex/web/__init__.py +38 -0
  566. scitex/web/_search_pubmed.py +438 -0
  567. scitex/web/_summarize_url.py +158 -0
  568. scitex-2.0.0.dist-info/METADATA +307 -0
  569. scitex-2.0.0.dist-info/RECORD +572 -0
  570. scitex-2.0.0.dist-info/WHEEL +6 -0
  571. scitex-2.0.0.dist-info/licenses/LICENSE +7 -0
  572. 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
@@ -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:]}"
@@ -0,0 +1,8 @@
1
+ #!./env/bin/python3
2
+ # -*- coding: utf-8 -*-
3
+ # Time-stamp: "2024-06-10 20:48:30 (ywatanabe)"
4
+ # /home/ywatanabe/proj/scitex/src/scitex/gen/_mask_api_key.py
5
+
6
+
7
+ def mask_api(api_key):
8
+ return f"{api_key[:4]}****{api_key[-4:]}"
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