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.
Files changed (704) hide show
  1. scitex/__init__.py +53 -15
  2. scitex/__main__.py +72 -26
  3. scitex/__version__.py +1 -1
  4. scitex/_sh.py +145 -23
  5. scitex/ai/__init__.py +30 -16
  6. scitex/ai/_gen_ai/_Anthropic.py +5 -7
  7. scitex/ai/_gen_ai/_BaseGenAI.py +2 -2
  8. scitex/ai/_gen_ai/_DeepSeek.py +10 -2
  9. scitex/ai/_gen_ai/_Google.py +2 -2
  10. scitex/ai/_gen_ai/_Llama.py +2 -2
  11. scitex/ai/_gen_ai/_OpenAI.py +2 -2
  12. scitex/ai/_gen_ai/_PARAMS.py +51 -65
  13. scitex/ai/_gen_ai/_Perplexity.py +2 -2
  14. scitex/ai/_gen_ai/__init__.py +25 -14
  15. scitex/ai/_gen_ai/_format_output_func.py +4 -4
  16. scitex/ai/classification/{classifier_server.py → Classifier.py} +5 -5
  17. scitex/ai/classification/CrossValidationExperiment.py +374 -0
  18. scitex/ai/classification/__init__.py +43 -4
  19. scitex/ai/classification/reporters/_BaseClassificationReporter.py +281 -0
  20. scitex/ai/classification/reporters/_ClassificationReporter.py +773 -0
  21. scitex/ai/classification/reporters/_MultiClassificationReporter.py +406 -0
  22. scitex/ai/classification/reporters/_SingleClassificationReporter.py +1834 -0
  23. scitex/ai/classification/reporters/__init__.py +11 -0
  24. scitex/ai/classification/reporters/reporter_utils/_Plotter.py +1028 -0
  25. scitex/ai/classification/reporters/reporter_utils/__init__.py +80 -0
  26. scitex/ai/classification/reporters/reporter_utils/aggregation.py +457 -0
  27. scitex/ai/classification/reporters/reporter_utils/data_models.py +313 -0
  28. scitex/ai/classification/reporters/reporter_utils/reporting.py +1056 -0
  29. scitex/ai/classification/reporters/reporter_utils/storage.py +221 -0
  30. scitex/ai/classification/reporters/reporter_utils/validation.py +395 -0
  31. scitex/ai/classification/timeseries/_TimeSeriesBlockingSplit.py +568 -0
  32. scitex/ai/classification/timeseries/_TimeSeriesCalendarSplit.py +688 -0
  33. scitex/ai/classification/timeseries/_TimeSeriesMetadata.py +139 -0
  34. scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +1716 -0
  35. scitex/ai/classification/timeseries/_TimeSeriesSlidingWindowSplit_v01-not-using-n_splits.py +1685 -0
  36. scitex/ai/classification/timeseries/_TimeSeriesStrategy.py +84 -0
  37. scitex/ai/classification/timeseries/_TimeSeriesStratifiedSplit.py +610 -0
  38. scitex/ai/classification/timeseries/__init__.py +39 -0
  39. scitex/ai/classification/timeseries/_normalize_timestamp.py +436 -0
  40. scitex/ai/clustering/_umap.py +2 -2
  41. scitex/ai/feature_extraction/vit.py +1 -0
  42. scitex/ai/feature_selection/__init__.py +30 -0
  43. scitex/ai/feature_selection/feature_selection.py +364 -0
  44. scitex/ai/loss/multi_task_loss.py +1 -1
  45. scitex/ai/metrics/__init__.py +51 -4
  46. scitex/ai/metrics/_calc_bacc.py +61 -0
  47. scitex/ai/metrics/_calc_bacc_from_conf_mat.py +38 -0
  48. scitex/ai/metrics/_calc_clf_report.py +78 -0
  49. scitex/ai/metrics/_calc_conf_mat.py +93 -0
  50. scitex/ai/metrics/_calc_feature_importance.py +183 -0
  51. scitex/ai/metrics/_calc_mcc.py +61 -0
  52. scitex/ai/metrics/_calc_pre_rec_auc.py +116 -0
  53. scitex/ai/metrics/_calc_roc_auc.py +110 -0
  54. scitex/ai/metrics/_calc_seizure_prediction_metrics.py +490 -0
  55. scitex/ai/metrics/{silhoute_score_block.py → _calc_silhouette_score.py} +15 -8
  56. scitex/ai/metrics/_normalize_labels.py +83 -0
  57. scitex/ai/plt/__init__.py +47 -8
  58. scitex/ai/plt/{_conf_mat.py → _plot_conf_mat.py} +158 -87
  59. scitex/ai/plt/_plot_feature_importance.py +323 -0
  60. scitex/ai/plt/_plot_learning_curve.py +345 -0
  61. scitex/ai/plt/_plot_optuna_study.py +225 -0
  62. scitex/ai/plt/_plot_pre_rec_curve.py +290 -0
  63. scitex/ai/plt/_plot_roc_curve.py +255 -0
  64. scitex/ai/training/{learning_curve_logger.py → _LearningCurveLogger.py} +197 -213
  65. scitex/ai/training/__init__.py +2 -2
  66. scitex/ai/utils/grid_search.py +3 -3
  67. scitex/benchmark/__init__.py +52 -0
  68. scitex/benchmark/benchmark.py +400 -0
  69. scitex/benchmark/monitor.py +370 -0
  70. scitex/benchmark/profiler.py +297 -0
  71. scitex/browser/__init__.py +48 -0
  72. scitex/browser/automation/CookieHandler.py +216 -0
  73. scitex/browser/automation/__init__.py +7 -0
  74. scitex/browser/collaboration/__init__.py +55 -0
  75. scitex/browser/collaboration/auth_helpers.py +94 -0
  76. scitex/browser/collaboration/collaborative_agent.py +136 -0
  77. scitex/browser/collaboration/credential_manager.py +188 -0
  78. scitex/browser/collaboration/interactive_panel.py +400 -0
  79. scitex/browser/collaboration/persistent_browser.py +170 -0
  80. scitex/browser/collaboration/shared_session.py +383 -0
  81. scitex/browser/collaboration/standard_interactions.py +246 -0
  82. scitex/browser/collaboration/visual_feedback.py +181 -0
  83. scitex/browser/core/BrowserMixin.py +326 -0
  84. scitex/browser/core/ChromeProfileManager.py +446 -0
  85. scitex/browser/core/__init__.py +9 -0
  86. scitex/browser/debugging/__init__.py +18 -0
  87. scitex/browser/debugging/_browser_logger.py +657 -0
  88. scitex/browser/debugging/_highlight_element.py +143 -0
  89. scitex/browser/debugging/_show_grid.py +154 -0
  90. scitex/browser/interaction/__init__.py +24 -0
  91. scitex/browser/interaction/click_center.py +149 -0
  92. scitex/browser/interaction/click_with_fallbacks.py +206 -0
  93. scitex/browser/interaction/close_popups.py +498 -0
  94. scitex/browser/interaction/fill_with_fallbacks.py +209 -0
  95. scitex/browser/pdf/__init__.py +14 -0
  96. scitex/browser/pdf/click_download_for_chrome_pdf_viewer.py +200 -0
  97. scitex/browser/pdf/detect_chrome_pdf_viewer.py +198 -0
  98. scitex/browser/remote/CaptchaHandler.py +434 -0
  99. scitex/browser/remote/ZenRowsAPIClient.py +347 -0
  100. scitex/browser/remote/ZenRowsBrowserManager.py +570 -0
  101. scitex/browser/remote/__init__.py +11 -0
  102. scitex/browser/stealth/HumanBehavior.py +344 -0
  103. scitex/browser/stealth/StealthManager.py +1008 -0
  104. scitex/browser/stealth/__init__.py +9 -0
  105. scitex/browser/template.py +122 -0
  106. scitex/capture/__init__.py +110 -0
  107. scitex/capture/__main__.py +25 -0
  108. scitex/capture/capture.py +848 -0
  109. scitex/capture/cli.py +233 -0
  110. scitex/capture/gif.py +344 -0
  111. scitex/capture/mcp_server.py +961 -0
  112. scitex/capture/session.py +70 -0
  113. scitex/capture/utils.py +705 -0
  114. scitex/cli/__init__.py +17 -0
  115. scitex/cli/cloud.py +447 -0
  116. scitex/cli/main.py +42 -0
  117. scitex/cli/scholar.py +280 -0
  118. scitex/context/_suppress_output.py +5 -3
  119. scitex/db/__init__.py +30 -3
  120. scitex/db/__main__.py +75 -0
  121. scitex/db/_check_health.py +381 -0
  122. scitex/db/_delete_duplicates.py +25 -386
  123. scitex/db/_inspect.py +335 -114
  124. scitex/db/_inspect_optimized.py +301 -0
  125. scitex/db/{_PostgreSQL.py → _postgresql/_PostgreSQL.py} +3 -3
  126. scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_BackupMixin.py +1 -1
  127. scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_BatchMixin.py +1 -1
  128. scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_BlobMixin.py +1 -1
  129. scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_ConnectionMixin.py +1 -1
  130. scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_MaintenanceMixin.py +1 -1
  131. scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_QueryMixin.py +1 -1
  132. scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_SchemaMixin.py +1 -1
  133. scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_TransactionMixin.py +1 -1
  134. scitex/db/_postgresql/__init__.py +6 -0
  135. scitex/db/_sqlite3/_SQLite3.py +210 -0
  136. scitex/db/_sqlite3/_SQLite3Mixins/_ArrayMixin.py +581 -0
  137. scitex/db/_sqlite3/_SQLite3Mixins/_ArrayMixin_v01-need-_hash-col.py +517 -0
  138. scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_BatchMixin.py +1 -1
  139. scitex/db/_sqlite3/_SQLite3Mixins/_BlobMixin.py +281 -0
  140. scitex/db/_sqlite3/_SQLite3Mixins/_ColumnMixin.py +548 -0
  141. scitex/db/_sqlite3/_SQLite3Mixins/_ColumnMixin_v01-indentation-issues.py +583 -0
  142. scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_ConnectionMixin.py +29 -13
  143. scitex/db/_sqlite3/_SQLite3Mixins/_GitMixin.py +583 -0
  144. scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_ImportExportMixin.py +1 -1
  145. scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_IndexMixin.py +1 -1
  146. scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_MaintenanceMixin.py +2 -1
  147. scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_QueryMixin.py +37 -10
  148. scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_RowMixin.py +46 -6
  149. scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_TableMixin.py +56 -10
  150. scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/_TransactionMixin.py +1 -1
  151. scitex/db/{_SQLite3Mixins → _sqlite3/_SQLite3Mixins}/__init__.py +14 -2
  152. scitex/db/_sqlite3/__init__.py +7 -0
  153. scitex/db/_sqlite3/_delete_duplicates.py +274 -0
  154. scitex/decorators/__init__.py +2 -0
  155. scitex/decorators/_cache_disk.py +13 -5
  156. scitex/decorators/_cache_disk_async.py +49 -0
  157. scitex/decorators/_deprecated.py +175 -10
  158. scitex/decorators/_timeout.py +1 -1
  159. scitex/dev/_analyze_code_flow.py +2 -2
  160. scitex/dict/_DotDict.py +73 -15
  161. scitex/dict/_DotDict_v01-not-handling-recursive-instantiations.py +442 -0
  162. scitex/dict/_DotDict_v02-not-serializing-Path-object.py +446 -0
  163. scitex/dict/__init__.py +2 -0
  164. scitex/dict/_flatten.py +27 -0
  165. scitex/dsp/_crop.py +2 -2
  166. scitex/dsp/_demo_sig.py +2 -2
  167. scitex/dsp/_detect_ripples.py +2 -2
  168. scitex/dsp/_hilbert.py +2 -2
  169. scitex/dsp/_listen.py +6 -6
  170. scitex/dsp/_modulation_index.py +2 -2
  171. scitex/dsp/_pac.py +1 -1
  172. scitex/dsp/_psd.py +2 -2
  173. scitex/dsp/_resample.py +2 -1
  174. scitex/dsp/_time.py +3 -2
  175. scitex/dsp/_wavelet.py +3 -2
  176. scitex/dsp/add_noise.py +2 -2
  177. scitex/dsp/example.py +1 -0
  178. scitex/dsp/filt.py +10 -9
  179. scitex/dsp/template.py +3 -2
  180. scitex/dsp/utils/_differential_bandpass_filters.py +1 -1
  181. scitex/dsp/utils/pac.py +2 -2
  182. scitex/dt/_normalize_timestamp.py +432 -0
  183. scitex/errors.py +572 -0
  184. scitex/gen/_DimHandler.py +2 -2
  185. scitex/gen/__init__.py +37 -7
  186. scitex/gen/_deprecated_close.py +80 -0
  187. scitex/gen/_deprecated_start.py +26 -0
  188. scitex/gen/_detect_environment.py +152 -0
  189. scitex/gen/_detect_notebook_path.py +169 -0
  190. scitex/gen/_embed.py +6 -2
  191. scitex/gen/_get_notebook_path.py +257 -0
  192. scitex/gen/_less.py +1 -1
  193. scitex/gen/_list_packages.py +2 -2
  194. scitex/gen/_norm.py +44 -9
  195. scitex/gen/_norm_cache.py +269 -0
  196. scitex/gen/_src.py +3 -5
  197. scitex/gen/_title_case.py +3 -3
  198. scitex/io/__init__.py +28 -6
  199. scitex/io/_glob.py +13 -7
  200. scitex/io/_load.py +108 -21
  201. scitex/io/_load_cache.py +303 -0
  202. scitex/io/_load_configs.py +40 -15
  203. scitex/io/{_H5Explorer.py → _load_modules/_H5Explorer.py} +80 -17
  204. scitex/io/_load_modules/_ZarrExplorer.py +114 -0
  205. scitex/io/_load_modules/_bibtex.py +207 -0
  206. scitex/io/_load_modules/_hdf5.py +53 -178
  207. scitex/io/_load_modules/_json.py +5 -3
  208. scitex/io/_load_modules/_pdf.py +871 -16
  209. scitex/io/_load_modules/_sqlite3.py +15 -0
  210. scitex/io/_load_modules/_txt.py +41 -12
  211. scitex/io/_load_modules/_yaml.py +4 -3
  212. scitex/io/_load_modules/_zarr.py +126 -0
  213. scitex/io/_save.py +429 -171
  214. scitex/io/_save_modules/__init__.py +6 -0
  215. scitex/io/_save_modules/_bibtex.py +194 -0
  216. scitex/io/_save_modules/_csv.py +8 -4
  217. scitex/io/_save_modules/_excel.py +174 -15
  218. scitex/io/_save_modules/_hdf5.py +251 -226
  219. scitex/io/_save_modules/_image.py +1 -3
  220. scitex/io/_save_modules/_json.py +49 -4
  221. scitex/io/_save_modules/_listed_dfs_as_csv.py +1 -3
  222. scitex/io/_save_modules/_listed_scalars_as_csv.py +1 -3
  223. scitex/io/_save_modules/_tex.py +277 -0
  224. scitex/io/_save_modules/_yaml.py +42 -3
  225. scitex/io/_save_modules/_zarr.py +160 -0
  226. scitex/io/utils/__init__.py +20 -0
  227. scitex/io/utils/h5_to_zarr.py +616 -0
  228. scitex/linalg/_geometric_median.py +6 -2
  229. scitex/{gen/_tee.py → logging/_Tee.py} +43 -84
  230. scitex/logging/__init__.py +122 -0
  231. scitex/logging/_config.py +158 -0
  232. scitex/logging/_context.py +103 -0
  233. scitex/logging/_formatters.py +128 -0
  234. scitex/logging/_handlers.py +64 -0
  235. scitex/logging/_levels.py +35 -0
  236. scitex/logging/_logger.py +163 -0
  237. scitex/logging/_print_capture.py +95 -0
  238. scitex/ml/__init__.py +69 -0
  239. scitex/{ai/genai/anthropic.py → ml/_gen_ai/_Anthropic.py} +13 -19
  240. scitex/{ai/genai/base_genai.py → ml/_gen_ai/_BaseGenAI.py} +5 -5
  241. scitex/{ai/genai/deepseek.py → ml/_gen_ai/_DeepSeek.py} +11 -16
  242. scitex/{ai/genai/google.py → ml/_gen_ai/_Google.py} +7 -15
  243. scitex/{ai/genai/groq.py → ml/_gen_ai/_Groq.py} +1 -8
  244. scitex/{ai/genai/llama.py → ml/_gen_ai/_Llama.py} +3 -16
  245. scitex/{ai/genai/openai.py → ml/_gen_ai/_OpenAI.py} +3 -3
  246. scitex/{ai/genai/params.py → ml/_gen_ai/_PARAMS.py} +51 -65
  247. scitex/{ai/genai/perplexity.py → ml/_gen_ai/_Perplexity.py} +3 -14
  248. scitex/ml/_gen_ai/__init__.py +43 -0
  249. scitex/{ai/genai/calc_cost.py → ml/_gen_ai/_calc_cost.py} +1 -1
  250. scitex/{ai/genai/format_output_func.py → ml/_gen_ai/_format_output_func.py} +4 -4
  251. scitex/{ai/genai/genai_factory.py → ml/_gen_ai/_genai_factory.py} +8 -8
  252. scitex/ml/activation/__init__.py +8 -0
  253. scitex/ml/activation/_define.py +11 -0
  254. scitex/{ai/classifier_server.py → ml/classification/Classifier.py} +5 -5
  255. scitex/ml/classification/CrossValidationExperiment.py +374 -0
  256. scitex/ml/classification/__init__.py +46 -0
  257. scitex/ml/classification/reporters/_BaseClassificationReporter.py +281 -0
  258. scitex/ml/classification/reporters/_ClassificationReporter.py +773 -0
  259. scitex/ml/classification/reporters/_MultiClassificationReporter.py +406 -0
  260. scitex/ml/classification/reporters/_SingleClassificationReporter.py +1834 -0
  261. scitex/ml/classification/reporters/__init__.py +11 -0
  262. scitex/ml/classification/reporters/reporter_utils/_Plotter.py +1028 -0
  263. scitex/ml/classification/reporters/reporter_utils/__init__.py +80 -0
  264. scitex/ml/classification/reporters/reporter_utils/aggregation.py +457 -0
  265. scitex/ml/classification/reporters/reporter_utils/data_models.py +313 -0
  266. scitex/ml/classification/reporters/reporter_utils/reporting.py +1056 -0
  267. scitex/ml/classification/reporters/reporter_utils/storage.py +221 -0
  268. scitex/ml/classification/reporters/reporter_utils/validation.py +395 -0
  269. scitex/ml/classification/timeseries/_TimeSeriesBlockingSplit.py +568 -0
  270. scitex/ml/classification/timeseries/_TimeSeriesCalendarSplit.py +688 -0
  271. scitex/ml/classification/timeseries/_TimeSeriesMetadata.py +139 -0
  272. scitex/ml/classification/timeseries/_TimeSeriesSlidingWindowSplit.py +1716 -0
  273. scitex/ml/classification/timeseries/_TimeSeriesSlidingWindowSplit_v01-not-using-n_splits.py +1685 -0
  274. scitex/ml/classification/timeseries/_TimeSeriesStrategy.py +84 -0
  275. scitex/ml/classification/timeseries/_TimeSeriesStratifiedSplit.py +610 -0
  276. scitex/ml/classification/timeseries/__init__.py +39 -0
  277. scitex/ml/classification/timeseries/_normalize_timestamp.py +436 -0
  278. scitex/ml/clustering/__init__.py +11 -0
  279. scitex/ml/clustering/_pca.py +115 -0
  280. scitex/ml/clustering/_umap.py +376 -0
  281. scitex/ml/feature_extraction/__init__.py +56 -0
  282. scitex/ml/feature_extraction/vit.py +149 -0
  283. scitex/ml/feature_selection/__init__.py +30 -0
  284. scitex/ml/feature_selection/feature_selection.py +364 -0
  285. scitex/ml/loss/_L1L2Losses.py +34 -0
  286. scitex/ml/loss/__init__.py +12 -0
  287. scitex/ml/loss/multi_task_loss.py +47 -0
  288. scitex/ml/metrics/__init__.py +56 -0
  289. scitex/ml/metrics/_calc_bacc.py +61 -0
  290. scitex/ml/metrics/_calc_bacc_from_conf_mat.py +38 -0
  291. scitex/ml/metrics/_calc_clf_report.py +78 -0
  292. scitex/ml/metrics/_calc_conf_mat.py +93 -0
  293. scitex/ml/metrics/_calc_feature_importance.py +183 -0
  294. scitex/ml/metrics/_calc_mcc.py +61 -0
  295. scitex/ml/metrics/_calc_pre_rec_auc.py +116 -0
  296. scitex/ml/metrics/_calc_roc_auc.py +110 -0
  297. scitex/ml/metrics/_calc_seizure_prediction_metrics.py +490 -0
  298. scitex/ml/metrics/_calc_silhouette_score.py +503 -0
  299. scitex/ml/metrics/_normalize_labels.py +83 -0
  300. scitex/ml/optim/Ranger_Deep_Learning_Optimizer/__init__.py +0 -0
  301. scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/__init__.py +3 -0
  302. scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger.py +207 -0
  303. scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger2020.py +238 -0
  304. scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger913A.py +215 -0
  305. scitex/ml/optim/Ranger_Deep_Learning_Optimizer/ranger/rangerqh.py +184 -0
  306. scitex/ml/optim/Ranger_Deep_Learning_Optimizer/setup.py +24 -0
  307. scitex/ml/optim/__init__.py +13 -0
  308. scitex/ml/optim/_get_set.py +31 -0
  309. scitex/ml/optim/_optimizers.py +71 -0
  310. scitex/ml/plt/__init__.py +60 -0
  311. scitex/ml/plt/_plot_conf_mat.py +663 -0
  312. scitex/ml/plt/_plot_feature_importance.py +323 -0
  313. scitex/ml/plt/_plot_learning_curve.py +345 -0
  314. scitex/ml/plt/_plot_optuna_study.py +225 -0
  315. scitex/ml/plt/_plot_pre_rec_curve.py +290 -0
  316. scitex/ml/plt/_plot_roc_curve.py +255 -0
  317. scitex/ml/sk/__init__.py +11 -0
  318. scitex/ml/sk/_clf.py +58 -0
  319. scitex/ml/sk/_to_sktime.py +100 -0
  320. scitex/ml/sklearn/__init__.py +26 -0
  321. scitex/ml/sklearn/clf.py +58 -0
  322. scitex/ml/sklearn/to_sktime.py +100 -0
  323. scitex/{ai/training/early_stopping.py → ml/training/_EarlyStopping.py} +1 -2
  324. scitex/{ai → ml/training}/_LearningCurveLogger.py +198 -242
  325. scitex/ml/training/__init__.py +7 -0
  326. scitex/ml/utils/__init__.py +22 -0
  327. scitex/ml/utils/_check_params.py +50 -0
  328. scitex/ml/utils/_default_dataset.py +46 -0
  329. scitex/ml/utils/_format_samples_for_sktime.py +26 -0
  330. scitex/ml/utils/_label_encoder.py +134 -0
  331. scitex/ml/utils/_merge_labels.py +22 -0
  332. scitex/ml/utils/_sliding_window_data_augmentation.py +11 -0
  333. scitex/ml/utils/_under_sample.py +51 -0
  334. scitex/ml/utils/_verify_n_gpus.py +16 -0
  335. scitex/ml/utils/grid_search.py +148 -0
  336. scitex/nn/_BNet.py +15 -9
  337. scitex/nn/_Filters.py +2 -2
  338. scitex/nn/_ModulationIndex.py +2 -2
  339. scitex/nn/_PAC.py +1 -1
  340. scitex/nn/_Spectrogram.py +12 -3
  341. scitex/nn/__init__.py +9 -10
  342. scitex/path/__init__.py +18 -0
  343. scitex/path/_clean.py +4 -0
  344. scitex/path/_find.py +9 -4
  345. scitex/path/_symlink.py +348 -0
  346. scitex/path/_version.py +4 -3
  347. scitex/pd/__init__.py +2 -0
  348. scitex/pd/_get_unique.py +99 -0
  349. scitex/plt/__init__.py +114 -5
  350. scitex/plt/_subplots/_AxesWrapper.py +1 -3
  351. scitex/plt/_subplots/_AxisWrapper.py +7 -3
  352. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin.py +47 -13
  353. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin.py +160 -2
  354. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin.py +26 -4
  355. scitex/plt/_subplots/_AxisWrapperMixins/_UnitAwareMixin.py +322 -0
  356. scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +1 -0
  357. scitex/plt/_subplots/_FigWrapper.py +62 -6
  358. scitex/plt/_subplots/_export_as_csv.py +43 -27
  359. scitex/plt/_subplots/_export_as_csv_formatters/__init__.py +5 -4
  360. scitex/plt/_subplots/_export_as_csv_formatters/_format_annotate.py +81 -0
  361. scitex/plt/_subplots/_export_as_csv_formatters/_format_bar.py +1 -3
  362. scitex/plt/_subplots/_export_as_csv_formatters/_format_barh.py +20 -5
  363. scitex/plt/_subplots/_export_as_csv_formatters/_format_boxplot.py +1 -3
  364. scitex/plt/_subplots/_export_as_csv_formatters/_format_contour.py +1 -3
  365. scitex/plt/_subplots/_export_as_csv_formatters/_format_errorbar.py +35 -18
  366. scitex/plt/_subplots/_export_as_csv_formatters/_format_eventplot.py +1 -3
  367. scitex/plt/_subplots/_export_as_csv_formatters/_format_fill.py +1 -3
  368. scitex/plt/_subplots/_export_as_csv_formatters/_format_fill_between.py +1 -3
  369. scitex/plt/_subplots/_export_as_csv_formatters/_format_hist.py +1 -3
  370. scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow.py +1 -3
  371. scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow2d.py +1 -3
  372. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot.py +15 -3
  373. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_box.py +1 -3
  374. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_conf_mat.py +1 -3
  375. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_ecdf.py +1 -3
  376. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_fillv.py +1 -3
  377. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_heatmap.py +1 -3
  378. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_image.py +1 -3
  379. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_joyplot.py +1 -3
  380. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_kde.py +1 -3
  381. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_line.py +1 -3
  382. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_mean_ci.py +1 -3
  383. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_mean_std.py +1 -3
  384. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_median_iqr.py +1 -3
  385. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_raster.py +1 -3
  386. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_rectangle.py +1 -3
  387. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter.py +35 -0
  388. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter_hist.py +1 -3
  389. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_shaded_line.py +1 -3
  390. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_violin.py +1 -3
  391. scitex/plt/_subplots/_export_as_csv_formatters/_format_scatter.py +6 -4
  392. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_barplot.py +1 -3
  393. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_boxplot.py +1 -3
  394. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_heatmap.py +1 -3
  395. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_histplot.py +1 -3
  396. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_jointplot.py +1 -3
  397. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_kdeplot.py +1 -3
  398. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_lineplot.py +1 -3
  399. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_pairplot.py +1 -3
  400. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_scatterplot.py +1 -3
  401. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_stripplot.py +1 -3
  402. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_swarmplot.py +1 -3
  403. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_violinplot.py +1 -3
  404. scitex/plt/_subplots/_export_as_csv_formatters/_format_text.py +60 -0
  405. scitex/plt/_subplots/_export_as_csv_formatters/_format_violin.py +1 -3
  406. scitex/plt/_subplots/_export_as_csv_formatters/_format_violinplot.py +1 -3
  407. scitex/plt/_subplots/_export_as_csv_formatters/test_formatters.py +1 -3
  408. scitex/plt/_subplots/_export_as_csv_formatters.py +56 -59
  409. scitex/plt/ax/_style/_hide_spines.py +1 -3
  410. scitex/plt/ax/_style/_rotate_labels.py +180 -76
  411. scitex/plt/ax/_style/_rotate_labels_v01.py +248 -0
  412. scitex/plt/ax/_style/_set_meta.py +11 -4
  413. scitex/plt/ax/_style/_set_supxyt.py +3 -3
  414. scitex/plt/ax/_style/_set_xyt.py +3 -3
  415. scitex/plt/ax/_style/_share_axes.py +2 -2
  416. scitex/plt/color/__init__.py +4 -4
  417. scitex/plt/color/{_get_colors_from_cmap.py → _get_colors_from_conf_matap.py} +7 -7
  418. scitex/plt/utils/_configure_mpl.py +99 -86
  419. scitex/plt/utils/_histogram_utils.py +1 -3
  420. scitex/plt/utils/_is_valid_axis.py +1 -3
  421. scitex/plt/utils/_scitex_config.py +1 -0
  422. scitex/repro/__init__.py +75 -0
  423. scitex/{reproduce → repro}/_gen_ID.py +1 -1
  424. scitex/{reproduce → repro}/_gen_timestamp.py +1 -1
  425. scitex/repro_rng/_RandomStateManager.py +590 -0
  426. scitex/repro_rng/_RandomStateManager_v01-no-verbose-options.py +414 -0
  427. scitex/repro_rng/__init__.py +39 -0
  428. scitex/reproduce/__init__.py +25 -13
  429. scitex/reproduce/_hash_array.py +22 -0
  430. scitex/resource/_get_processor_usages.py +4 -4
  431. scitex/resource/_get_specs.py +2 -2
  432. scitex/resource/_log_processor_usages.py +2 -2
  433. scitex/rng/_RandomStateManager.py +590 -0
  434. scitex/rng/_RandomStateManager_v01-no-verbose-options.py +414 -0
  435. scitex/rng/__init__.py +39 -0
  436. scitex/scholar/__init__.py +309 -19
  437. scitex/scholar/__main__.py +319 -0
  438. scitex/scholar/auth/ScholarAuthManager.py +308 -0
  439. scitex/scholar/auth/__init__.py +12 -0
  440. scitex/scholar/auth/core/AuthenticationGateway.py +473 -0
  441. scitex/scholar/auth/core/BrowserAuthenticator.py +386 -0
  442. scitex/scholar/auth/core/StrategyResolver.py +309 -0
  443. scitex/scholar/auth/core/__init__.py +16 -0
  444. scitex/scholar/auth/gateway/_OpenURLLinkFinder.py +120 -0
  445. scitex/scholar/auth/gateway/_OpenURLResolver.py +209 -0
  446. scitex/scholar/auth/gateway/__init__.py +38 -0
  447. scitex/scholar/auth/gateway/_resolve_functions.py +101 -0
  448. scitex/scholar/auth/providers/BaseAuthenticator.py +166 -0
  449. scitex/scholar/auth/providers/EZProxyAuthenticator.py +484 -0
  450. scitex/scholar/auth/providers/OpenAthensAuthenticator.py +619 -0
  451. scitex/scholar/auth/providers/ShibbolethAuthenticator.py +686 -0
  452. scitex/scholar/auth/providers/__init__.py +18 -0
  453. scitex/scholar/auth/session/AuthCacheManager.py +189 -0
  454. scitex/scholar/auth/session/SessionManager.py +159 -0
  455. scitex/scholar/auth/session/__init__.py +11 -0
  456. scitex/scholar/auth/sso/BaseSSOAutomator.py +373 -0
  457. scitex/scholar/auth/sso/OpenAthensSSOAutomator.py +378 -0
  458. scitex/scholar/auth/sso/SSOAutomator.py +180 -0
  459. scitex/scholar/auth/sso/UniversityOfMelbourneSSOAutomator.py +380 -0
  460. scitex/scholar/auth/sso/__init__.py +15 -0
  461. scitex/scholar/browser/ScholarBrowserManager.py +705 -0
  462. scitex/scholar/browser/__init__.py +38 -0
  463. scitex/scholar/browser/utils/__init__.py +13 -0
  464. scitex/scholar/browser/utils/click_and_wait.py +205 -0
  465. scitex/scholar/browser/utils/close_unwanted_pages.py +140 -0
  466. scitex/scholar/browser/utils/wait_redirects.py +732 -0
  467. scitex/scholar/config/PublisherRules.py +132 -0
  468. scitex/scholar/config/ScholarConfig.py +126 -0
  469. scitex/scholar/config/__init__.py +17 -0
  470. scitex/scholar/core/Paper.py +627 -0
  471. scitex/scholar/core/Papers.py +722 -0
  472. scitex/scholar/core/Scholar.py +1975 -0
  473. scitex/scholar/core/__init__.py +9 -0
  474. scitex/scholar/impact_factor/ImpactFactorEngine.py +204 -0
  475. scitex/scholar/impact_factor/__init__.py +20 -0
  476. scitex/scholar/impact_factor/estimation/ImpactFactorEstimationEngine.py +0 -0
  477. scitex/scholar/impact_factor/estimation/__init__.py +40 -0
  478. scitex/scholar/impact_factor/estimation/build_database.py +0 -0
  479. scitex/scholar/impact_factor/estimation/core/__init__.py +28 -0
  480. scitex/scholar/impact_factor/estimation/core/cache_manager.py +523 -0
  481. scitex/scholar/impact_factor/estimation/core/calculator.py +355 -0
  482. scitex/scholar/impact_factor/estimation/core/journal_matcher.py +428 -0
  483. scitex/scholar/integration/__init__.py +59 -0
  484. scitex/scholar/integration/base.py +502 -0
  485. scitex/scholar/integration/mendeley/__init__.py +22 -0
  486. scitex/scholar/integration/mendeley/exporter.py +166 -0
  487. scitex/scholar/integration/mendeley/importer.py +236 -0
  488. scitex/scholar/integration/mendeley/linker.py +79 -0
  489. scitex/scholar/integration/mendeley/mapper.py +212 -0
  490. scitex/scholar/integration/zotero/__init__.py +27 -0
  491. scitex/scholar/integration/zotero/__main__.py +264 -0
  492. scitex/scholar/integration/zotero/exporter.py +351 -0
  493. scitex/scholar/integration/zotero/importer.py +372 -0
  494. scitex/scholar/integration/zotero/linker.py +415 -0
  495. scitex/scholar/integration/zotero/mapper.py +286 -0
  496. scitex/scholar/metadata_engines/ScholarEngine.py +588 -0
  497. scitex/scholar/metadata_engines/__init__.py +21 -0
  498. scitex/scholar/metadata_engines/individual/ArXivEngine.py +397 -0
  499. scitex/scholar/metadata_engines/individual/CrossRefEngine.py +274 -0
  500. scitex/scholar/metadata_engines/individual/CrossRefLocalEngine.py +263 -0
  501. scitex/scholar/metadata_engines/individual/OpenAlexEngine.py +350 -0
  502. scitex/scholar/metadata_engines/individual/PubMedEngine.py +329 -0
  503. scitex/scholar/metadata_engines/individual/SemanticScholarEngine.py +438 -0
  504. scitex/scholar/metadata_engines/individual/URLDOIEngine.py +410 -0
  505. scitex/scholar/metadata_engines/individual/_BaseDOIEngine.py +487 -0
  506. scitex/scholar/metadata_engines/individual/__init__.py +7 -0
  507. scitex/scholar/metadata_engines/utils/_PubMedConverter.py +469 -0
  508. scitex/scholar/metadata_engines/utils/_URLDOIExtractor.py +283 -0
  509. scitex/scholar/metadata_engines/utils/__init__.py +30 -0
  510. scitex/scholar/metadata_engines/utils/_metadata2bibtex.py +103 -0
  511. scitex/scholar/metadata_engines/utils/_standardize_metadata.py +376 -0
  512. scitex/scholar/pdf_download/ScholarPDFDownloader.py +579 -0
  513. scitex/scholar/pdf_download/__init__.py +5 -0
  514. scitex/scholar/pdf_download/strategies/__init__.py +38 -0
  515. scitex/scholar/pdf_download/strategies/chrome_pdf_viewer.py +376 -0
  516. scitex/scholar/pdf_download/strategies/direct_download.py +131 -0
  517. scitex/scholar/pdf_download/strategies/manual_download_fallback.py +167 -0
  518. scitex/scholar/pdf_download/strategies/manual_download_utils.py +996 -0
  519. scitex/scholar/pdf_download/strategies/response_body.py +207 -0
  520. scitex/scholar/pipelines/ScholarPipelineBibTeX.py +364 -0
  521. scitex/scholar/pipelines/ScholarPipelineParallel.py +478 -0
  522. scitex/scholar/pipelines/ScholarPipelineSingle.py +767 -0
  523. scitex/scholar/pipelines/__init__.py +49 -0
  524. scitex/scholar/storage/BibTeXHandler.py +1018 -0
  525. scitex/scholar/storage/PaperIO.py +468 -0
  526. scitex/scholar/storage/ScholarLibrary.py +182 -0
  527. scitex/scholar/storage/_DeduplicationManager.py +548 -0
  528. scitex/scholar/storage/_LibraryCacheManager.py +724 -0
  529. scitex/scholar/storage/_LibraryManager.py +1835 -0
  530. scitex/scholar/storage/__init__.py +28 -0
  531. scitex/scholar/url_finder/ScholarURLFinder.py +379 -0
  532. scitex/scholar/url_finder/__init__.py +7 -0
  533. scitex/scholar/url_finder/strategies/__init__.py +33 -0
  534. scitex/scholar/url_finder/strategies/find_pdf_urls_by_direct_links.py +261 -0
  535. scitex/scholar/url_finder/strategies/find_pdf_urls_by_dropdown.py +67 -0
  536. scitex/scholar/url_finder/strategies/find_pdf_urls_by_href.py +204 -0
  537. scitex/scholar/url_finder/strategies/find_pdf_urls_by_navigation.py +256 -0
  538. scitex/scholar/url_finder/strategies/find_pdf_urls_by_publisher_patterns.py +165 -0
  539. scitex/scholar/url_finder/strategies/find_pdf_urls_by_zotero_translators.py +163 -0
  540. scitex/scholar/url_finder/strategies/find_supplementary_urls_by_href.py +70 -0
  541. scitex/scholar/utils/__init__.py +22 -0
  542. scitex/scholar/utils/bibtex/__init__.py +9 -0
  543. scitex/scholar/utils/bibtex/_parse_bibtex.py +71 -0
  544. scitex/scholar/utils/cleanup/__init__.py +8 -0
  545. scitex/scholar/utils/cleanup/_cleanup_scholar_processes.py +96 -0
  546. scitex/scholar/utils/cleanup/cleanup_old_extractions.py +117 -0
  547. scitex/scholar/utils/text/_TextNormalizer.py +407 -0
  548. scitex/scholar/utils/text/__init__.py +9 -0
  549. scitex/scholar/zotero/__init__.py +38 -0
  550. scitex/session/__init__.py +51 -0
  551. scitex/session/_lifecycle.py +736 -0
  552. scitex/session/_manager.py +102 -0
  553. scitex/session/template.py +122 -0
  554. scitex/stats/__init__.py +30 -26
  555. scitex/stats/correct/__init__.py +21 -0
  556. scitex/stats/correct/_correct_bonferroni.py +551 -0
  557. scitex/stats/correct/_correct_fdr.py +634 -0
  558. scitex/stats/correct/_correct_holm.py +548 -0
  559. scitex/stats/correct/_correct_sidak.py +499 -0
  560. scitex/stats/descriptive/__init__.py +85 -0
  561. scitex/stats/descriptive/_circular.py +540 -0
  562. scitex/stats/descriptive/_describe.py +219 -0
  563. scitex/stats/descriptive/_nan.py +518 -0
  564. scitex/stats/descriptive/_real.py +189 -0
  565. scitex/stats/effect_sizes/__init__.py +41 -0
  566. scitex/stats/effect_sizes/_cliffs_delta.py +325 -0
  567. scitex/stats/effect_sizes/_cohens_d.py +342 -0
  568. scitex/stats/effect_sizes/_epsilon_squared.py +315 -0
  569. scitex/stats/effect_sizes/_eta_squared.py +302 -0
  570. scitex/stats/effect_sizes/_prob_superiority.py +296 -0
  571. scitex/stats/posthoc/__init__.py +19 -0
  572. scitex/stats/posthoc/_dunnett.py +463 -0
  573. scitex/stats/posthoc/_games_howell.py +383 -0
  574. scitex/stats/posthoc/_tukey_hsd.py +367 -0
  575. scitex/stats/power/__init__.py +19 -0
  576. scitex/stats/power/_power.py +433 -0
  577. scitex/stats/template.py +119 -0
  578. scitex/stats/utils/__init__.py +62 -0
  579. scitex/stats/utils/_effect_size.py +985 -0
  580. scitex/stats/utils/_formatters.py +270 -0
  581. scitex/stats/utils/_normalizers.py +927 -0
  582. scitex/stats/utils/_power.py +433 -0
  583. scitex/stats_v01/_EffectSizeCalculator.py +488 -0
  584. scitex/stats_v01/_StatisticalValidator.py +411 -0
  585. scitex/stats_v01/__init__.py +60 -0
  586. scitex/stats_v01/_additional_tests.py +415 -0
  587. scitex/{stats → stats_v01}/_p2stars.py +19 -5
  588. scitex/stats_v01/_two_sample_tests.py +141 -0
  589. scitex/stats_v01/desc/__init__.py +83 -0
  590. scitex/stats_v01/desc/_circular.py +540 -0
  591. scitex/stats_v01/desc/_describe.py +219 -0
  592. scitex/stats_v01/desc/_nan.py +518 -0
  593. scitex/{stats/desc/_nan.py → stats_v01/desc/_nan_v01-20250920_145731.py} +23 -12
  594. scitex/stats_v01/desc/_real.py +189 -0
  595. scitex/stats_v01/tests/__corr_test_optimized.py +221 -0
  596. scitex/stats_v01/tests/_corr_test_optimized.py +179 -0
  597. scitex/str/__init__.py +1 -3
  598. scitex/str/_clean_path.py +6 -2
  599. scitex/str/_latex_fallback.py +267 -160
  600. scitex/str/_parse.py +44 -36
  601. scitex/str/_printc.py +1 -3
  602. scitex/template/__init__.py +87 -0
  603. scitex/template/_create_project.py +267 -0
  604. scitex/template/create_pip_project.py +80 -0
  605. scitex/template/create_research.py +80 -0
  606. scitex/template/create_singularity.py +80 -0
  607. scitex/units.py +291 -0
  608. scitex/utils/_compress_hdf5.py +14 -3
  609. scitex/utils/_email.py +21 -2
  610. scitex/utils/_grid.py +6 -4
  611. scitex/utils/_notify.py +13 -10
  612. scitex/utils/_verify_scitex_format.py +589 -0
  613. scitex/utils/_verify_scitex_format_v01.py +370 -0
  614. scitex/utils/template.py +122 -0
  615. scitex/web/_search_pubmed.py +62 -16
  616. scitex-2.1.0.dist-info/LICENSE +21 -0
  617. scitex-2.1.0.dist-info/METADATA +677 -0
  618. scitex-2.1.0.dist-info/RECORD +919 -0
  619. {scitex-2.0.0.dist-info → scitex-2.1.0.dist-info}/WHEEL +1 -1
  620. scitex-2.1.0.dist-info/entry_points.txt +3 -0
  621. scitex/ai/__Classifiers.py +0 -101
  622. scitex/ai/classification/classification_reporter.py +0 -1137
  623. scitex/ai/classification/classifiers.py +0 -101
  624. scitex/ai/classification_reporter.py +0 -1161
  625. scitex/ai/genai/__init__.py +0 -277
  626. scitex/ai/genai/anthropic_provider.py +0 -320
  627. scitex/ai/genai/anthropic_refactored.py +0 -109
  628. scitex/ai/genai/auth_manager.py +0 -200
  629. scitex/ai/genai/base_provider.py +0 -291
  630. scitex/ai/genai/chat_history.py +0 -307
  631. scitex/ai/genai/cost_tracker.py +0 -276
  632. scitex/ai/genai/deepseek_provider.py +0 -251
  633. scitex/ai/genai/google_provider.py +0 -228
  634. scitex/ai/genai/groq_provider.py +0 -248
  635. scitex/ai/genai/image_processor.py +0 -250
  636. scitex/ai/genai/llama_provider.py +0 -214
  637. scitex/ai/genai/mock_provider.py +0 -127
  638. scitex/ai/genai/model_registry.py +0 -304
  639. scitex/ai/genai/openai_provider.py +0 -293
  640. scitex/ai/genai/perplexity_provider.py +0 -205
  641. scitex/ai/genai/provider_base.py +0 -302
  642. scitex/ai/genai/provider_factory.py +0 -370
  643. scitex/ai/genai/response_handler.py +0 -235
  644. scitex/ai/layer/_Pass.py +0 -21
  645. scitex/ai/layer/__init__.py +0 -10
  646. scitex/ai/layer/_switch.py +0 -8
  647. scitex/ai/metrics/_bACC.py +0 -51
  648. scitex/ai/plt/_learning_curve.py +0 -194
  649. scitex/ai/plt/_optuna_study.py +0 -111
  650. scitex/ai/plt/aucs/__init__.py +0 -2
  651. scitex/ai/plt/aucs/example.py +0 -60
  652. scitex/ai/plt/aucs/pre_rec_auc.py +0 -223
  653. scitex/ai/plt/aucs/roc_auc.py +0 -246
  654. scitex/ai/sampling/undersample.py +0 -29
  655. scitex/db/_SQLite3.py +0 -2136
  656. scitex/db/_SQLite3Mixins/_BlobMixin.py +0 -229
  657. scitex/gen/_close.py +0 -222
  658. scitex/gen/_start.py +0 -451
  659. scitex/general/__init__.py +0 -5
  660. scitex/io/_load_modules/_db.py +0 -24
  661. scitex/life/__init__.py +0 -10
  662. scitex/life/_monitor_rain.py +0 -49
  663. scitex/reproduce/_fix_seeds.py +0 -45
  664. scitex/res/__init__.py +0 -5
  665. scitex/scholar/_local_search.py +0 -454
  666. scitex/scholar/_paper.py +0 -244
  667. scitex/scholar/_pdf_downloader.py +0 -325
  668. scitex/scholar/_search.py +0 -393
  669. scitex/scholar/_vector_search.py +0 -370
  670. scitex/scholar/_web_sources.py +0 -457
  671. scitex/stats/desc/__init__.py +0 -40
  672. scitex-2.0.0.dist-info/METADATA +0 -307
  673. scitex-2.0.0.dist-info/RECORD +0 -572
  674. scitex-2.0.0.dist-info/licenses/LICENSE +0 -7
  675. /scitex/ai/{act → activation}/__init__.py +0 -0
  676. /scitex/ai/{act → activation}/_define.py +0 -0
  677. /scitex/ai/{early_stopping.py → training/_EarlyStopping.py} +0 -0
  678. /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_ImportExportMixin.py +0 -0
  679. /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_IndexMixin.py +0 -0
  680. /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_RowMixin.py +0 -0
  681. /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/_TableMixin.py +0 -0
  682. /scitex/db/{_PostgreSQLMixins → _postgresql/_PostgreSQLMixins}/__init__.py +0 -0
  683. /scitex/{stats → stats_v01}/_calc_partial_corr.py +0 -0
  684. /scitex/{stats → stats_v01}/_corr_test_multi.py +0 -0
  685. /scitex/{stats → stats_v01}/_corr_test_wrapper.py +0 -0
  686. /scitex/{stats → stats_v01}/_describe_wrapper.py +0 -0
  687. /scitex/{stats → stats_v01}/_multiple_corrections.py +0 -0
  688. /scitex/{stats → stats_v01}/_nan_stats.py +0 -0
  689. /scitex/{stats → stats_v01}/_p2stars_wrapper.py +0 -0
  690. /scitex/{stats → stats_v01}/_statistical_tests.py +0 -0
  691. /scitex/{stats/desc/_describe.py → stats_v01/desc/_describe_v01-20250920_145731.py} +0 -0
  692. /scitex/{stats/desc/_real.py → stats_v01/desc/_real_v01-20250920_145731.py} +0 -0
  693. /scitex/{stats → stats_v01}/multiple/__init__.py +0 -0
  694. /scitex/{stats → stats_v01}/multiple/_bonferroni_correction.py +0 -0
  695. /scitex/{stats → stats_v01}/multiple/_fdr_correction.py +0 -0
  696. /scitex/{stats → stats_v01}/multiple/_multicompair.py +0 -0
  697. /scitex/{stats → stats_v01}/tests/__corr_test.py +0 -0
  698. /scitex/{stats → stats_v01}/tests/__corr_test_multi.py +0 -0
  699. /scitex/{stats → stats_v01}/tests/__corr_test_single.py +0 -0
  700. /scitex/{stats → stats_v01}/tests/__init__.py +0 -0
  701. /scitex/{stats → stats_v01}/tests/_brunner_munzel_test.py +0 -0
  702. /scitex/{stats → stats_v01}/tests/_nocorrelation_test.py +0 -0
  703. /scitex/{stats → stats_v01}/tests/_smirnov_grubbs.py +0 -0
  704. {scitex-2.0.0.dist-info → scitex-2.1.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,736 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Timestamp: "2025-10-16 20:25:05 (ywatanabe)"
4
+ # File: /home/ywatanabe/proj/scitex_repo/src/scitex/session/_lifecycle.py
5
+ # ----------------------------------------
6
+ from __future__ import annotations
7
+ import os
8
+ __FILE__ = (
9
+ "./src/scitex/session/_lifecycle.py"
10
+ )
11
+ __DIR__ = os.path.dirname(__FILE__)
12
+ # ----------------------------------------
13
+
14
+ __FILE__ = __file__
15
+
16
+ """Session lifecycle management for SciTeX experiments.
17
+
18
+ This module contains the start() and close() functions that replace
19
+ scitex.session.start() and scitex.session.close() with enhanced session management.
20
+ """
21
+
22
+ import inspect
23
+ import os as _os
24
+ import re
25
+ import shutil
26
+ import sys as sys_module
27
+ import time
28
+ from datetime import datetime
29
+ from glob import glob as _glob
30
+ from pathlib import Path
31
+ from pprint import pprint
32
+ from time import sleep
33
+ from typing import Any, Dict, Optional, Tuple, Union
34
+
35
+ from ..logging import getLogger
36
+
37
+ logger = getLogger(__name__)
38
+
39
+ import matplotlib
40
+ import matplotlib.pyplot as plt_module
41
+
42
+ from ..dict import DotDict
43
+
44
+ # Lazy import to avoid circular dependency with scitex.gen
45
+ from ..io import flush
46
+ from ..io import save as scitex_io_save
47
+ from ..io._load import load
48
+ from ..io._load_configs import load_configs
49
+ from ..plt.utils._configure_mpl import configure_mpl
50
+ from ..repro._gen_ID import gen_ID
51
+ from ..rng import RandomStateManager
52
+ from ..str._clean_path import clean_path
53
+ from ..str._printc import printc as _printc
54
+ from ..utils._notify import notify as scitex_utils_notify
55
+ from ._manager import get_global_session_manager
56
+
57
+ # For development code flow analysis
58
+ try:
59
+ from ..dev._analyze_code_flow import analyze_code_flow
60
+ except ImportError:
61
+
62
+ def analyze_code_flow(file):
63
+ return "Code flow analysis not available"
64
+
65
+
66
+ def _print_header(
67
+ ID: str,
68
+ PID: int,
69
+ file: str,
70
+ args: Any,
71
+ configs: Dict[str, Any],
72
+ verbose: bool = True,
73
+ ) -> None:
74
+ """Prints formatted header with scitex version, ID, and PID information.
75
+
76
+ Parameters
77
+ ----------
78
+ ID : str
79
+ Unique identifier for the current run
80
+ PID : int
81
+ Process ID of the current Python process
82
+ file : str
83
+ File path of the calling script
84
+ args : Any
85
+ Command line arguments or configuration object
86
+ configs : Dict[str, Any]
87
+ Configuration dictionary to display
88
+ verbose : bool, optional
89
+ Whether to print detailed information, by default True
90
+ """
91
+
92
+ args_str = "Arguments:"
93
+ for arg, value in args._get_kwargs():
94
+ args_str += f"\n {arg}: {value}"
95
+
96
+ _printc(
97
+ (
98
+ f"SciTeX v{_get_scitex_version()}\n"
99
+ f"{ID} (PID: {PID})\n\n"
100
+ f"{file}\n\n"
101
+ f"{args_str}"
102
+ # f"{args}"
103
+ ),
104
+ char="=",
105
+ )
106
+
107
+ sleep(1)
108
+ if verbose:
109
+ print(f"\n{'-'*40}\n")
110
+ pprint(configs.to_dict())
111
+ print(f"\n{'-'*40}\n")
112
+ sleep(1)
113
+
114
+
115
+ def _initialize_env(IS_DEBUG: bool) -> Tuple[str, int]:
116
+ """Initialize environment with ID and PID.
117
+
118
+ Parameters
119
+ ----------
120
+ IS_DEBUG : bool
121
+ Debug mode flag
122
+
123
+ Returns
124
+ -------
125
+ tuple
126
+ (ID, PID) - Unique identifier and Process ID
127
+ """
128
+ ID = gen_ID(N=4) if not IS_DEBUG else "DEBUG_" + gen_ID(N=4)
129
+ PID = _os.getpid()
130
+ return ID, PID
131
+
132
+
133
+ def _setup_configs(
134
+ IS_DEBUG: bool,
135
+ ID: str,
136
+ PID: int,
137
+ file: str,
138
+ sdir: str,
139
+ relative_sdir: str,
140
+ verbose: bool,
141
+ ) -> Dict[str, Any]:
142
+ """Setup configuration dictionary with basic parameters.
143
+
144
+ Parameters
145
+ ----------
146
+ IS_DEBUG : bool
147
+ Debug mode flag
148
+ ID : str
149
+ Unique identifier
150
+ PID : int
151
+ Process ID
152
+ file : str
153
+ File path
154
+ sdir : str
155
+ Save directory path
156
+ relative_sdir : str
157
+ Relative save directory path
158
+ verbose : bool
159
+ Verbosity flag
160
+
161
+ Returns
162
+ -------
163
+ dict
164
+ Configuration dictionary
165
+ """
166
+ CONFIGS = load_configs(IS_DEBUG).to_dict()
167
+ CONFIGS.update(
168
+ {
169
+ "ID": ID,
170
+ "PID": PID,
171
+ "START_TIME": datetime.now(),
172
+ "FILE": file,
173
+ "SDIR": sdir,
174
+ "REL_SDIR": relative_sdir,
175
+ # Path object versions for convenience (maintain backward compatibility)
176
+ "SDIR_PATH": Path(sdir) if sdir else None,
177
+ "REL_SDIR_PATH": Path(relative_sdir) if relative_sdir else None,
178
+ "FILE_PATH": Path(file) if file else None,
179
+ }
180
+ )
181
+ return CONFIGS
182
+
183
+
184
+ def _setup_matplotlib(
185
+ plt: plt_module = None, agg: bool = False, **mpl_kwargs: Any
186
+ ) -> Tuple[Any, Optional[Dict[str, Any]]]:
187
+ """Configure matplotlib settings.
188
+
189
+ Parameters
190
+ ----------
191
+ plt : module
192
+ Matplotlib.pyplot module (will be replaced with scitex.plt)
193
+ agg : bool
194
+ Whether to use Agg backend
195
+ **mpl_kwargs : dict
196
+ Additional matplotlib configuration parameters
197
+
198
+ Returns
199
+ -------
200
+ tuple
201
+ (plt, CC) - Configured scitex.plt module and color cycle
202
+ """
203
+ if plt is not None:
204
+ plt.close("all")
205
+ _, CC = configure_mpl(plt, **mpl_kwargs)
206
+ CC["gray"] = CC["grey"]
207
+ if agg:
208
+ matplotlib.use("Agg")
209
+
210
+ # Replace matplotlib.pyplot with scitex.plt to get wrapped functions
211
+ import scitex.plt as stx_plt
212
+
213
+ return stx_plt, CC
214
+ return plt, None
215
+
216
+
217
+ def _simplify_relative_path(sdir: str) -> str:
218
+ """
219
+ Simplify the relative path by removing specific patterns.
220
+
221
+ Example
222
+ -------
223
+ sdir = '/home/user/scripts/memory-load/distance_between_gs_stats/RUNNING/2024Y-09M-12D-02h44m40s_GlBZ'
224
+ simplified_path = simplify_relative_path(sdir)
225
+ print(simplified_path)
226
+ # Output: './memory-load/distance_between_gs_stats/'
227
+
228
+ Parameters
229
+ ----------
230
+ sdir : str
231
+ The directory path to simplify
232
+
233
+ Returns
234
+ -------
235
+ str
236
+ Simplified relative path
237
+ """
238
+ base_path = _os.getcwd()
239
+ relative_sdir = _os.path.relpath(sdir, base_path) if base_path else sdir
240
+ simplified_path = relative_sdir.replace("scripts/", "./scripts/").replace(
241
+ "RUNNING/", ""
242
+ )
243
+ # Remove date-time pattern and random string
244
+ simplified_path = re.sub(
245
+ r"\d{4}Y-\d{2}M-\d{2}D-\d{2}h\d{2}m\d{2}s_\w+/?$", "", simplified_path
246
+ )
247
+ return simplified_path
248
+
249
+
250
+ def _get_debug_mode() -> bool:
251
+ """Get debug mode from configuration."""
252
+ try:
253
+ IS_DEBUG_PATH = "./config/IS_DEBUG.yaml"
254
+ if _os.path.exists(IS_DEBUG_PATH):
255
+ IS_DEBUG = load(IS_DEBUG_PATH).get("IS_DEBUG", False)
256
+ if IS_DEBUG == "true":
257
+ IS_DEBUG = True
258
+ else:
259
+ IS_DEBUG = False
260
+
261
+ except Exception as e:
262
+ print(e)
263
+ IS_DEBUG = False
264
+ return IS_DEBUG
265
+
266
+
267
+ def _clear_python_log_dir(log_dir: str) -> None:
268
+ """Clear Python log directory."""
269
+ try:
270
+ if _os.path.exists(log_dir):
271
+ _os.system(f"rm -rf {log_dir}")
272
+ except Exception as e:
273
+ print(f"Failed to clear directory {log_dir}: {e}")
274
+
275
+
276
+ def _get_scitex_version() -> str:
277
+ """Gets scitex version"""
278
+ try:
279
+ import scitex
280
+
281
+ return scitex.__version__
282
+ except Exception as e:
283
+ print(e)
284
+ return "(not found)"
285
+
286
+
287
+ def start(
288
+ sys: sys_module = None,
289
+ plt: plt_module = None,
290
+ file: Optional[str] = None,
291
+ sdir: Optional[Union[str, Path]] = None,
292
+ sdir_suffix: Optional[str] = None,
293
+ args: Optional[Any] = None,
294
+ os: Optional[Any] = None,
295
+ random: Optional[Any] = None,
296
+ np: Optional[Any] = None,
297
+ torch: Optional[Any] = None,
298
+ seed: int = 42,
299
+ agg: bool = False,
300
+ fig_size_mm: Tuple[int, int] = (160, 100),
301
+ fig_scale: float = 1.0,
302
+ dpi_display: int = 100,
303
+ dpi_save: int = 300,
304
+ fontsize="small",
305
+ autolayout=True,
306
+ show_execution_flow=False,
307
+ hide_top_right_spines: bool = True,
308
+ alpha: float = 0.9,
309
+ line_width: float = 1.0,
310
+ clear_logs: bool = False,
311
+ verbose: bool = True,
312
+ ) -> Tuple[DotDict, Any, Any, Any, Optional[Dict[str, Any]], Any]:
313
+ """Initialize experiment session with reproducibility settings.
314
+
315
+ This function replaces scitex.session.start() with enhanced session management.
316
+
317
+ Parameters
318
+ ----------
319
+ sys : module, optional
320
+ Python sys module for I/O redirection
321
+ plt : module, optional
322
+ Matplotlib pyplot module for plotting configuration
323
+ file : str, optional
324
+ Script file path. If None, automatically detected
325
+ sdir : Union[str, Path], optional
326
+ Save directory path. Can be a string or pathlib.Path object. If None, automatically generated
327
+ sdir_suffix : str, optional
328
+ Suffix to append to save directory
329
+ args : object, optional
330
+ Command line arguments or configuration object
331
+ os, random, np, torch : modules, optional
332
+ Modules for random seed fixing
333
+ seed : int, default=42
334
+ Random seed for reproducibility
335
+ agg : bool, default=False
336
+ Whether to use matplotlib Agg backend
337
+ fig_size_mm : tuple, default=(160, 100)
338
+ Figure size in millimeters
339
+ fig_scale : float, default=1.0
340
+ Scale factor for figure size
341
+ dpi_display, dpi_save : int
342
+ DPI for display and saving
343
+ fontsize : str, default='small'
344
+ Font size setting
345
+ autolayout : bool, default=True
346
+ Enable matplotlib autolayout
347
+ show_execution_flow : bool, default=False
348
+ Show code execution flow analysis
349
+ hide_top_right_spines : bool, default=True
350
+ Whether to hide top and right spines
351
+ alpha : float, default=0.9
352
+ Default alpha value for plots
353
+ line_width : float, default=1.0
354
+ Default line width for plots
355
+ clear_logs : bool, default=False
356
+ Whether to clear existing log directory
357
+ verbose : bool, default=True
358
+ Whether to print detailed information
359
+
360
+ Returns
361
+ -------
362
+ tuple
363
+ (CONFIGS, stdout, stderr, plt, CC, rng)
364
+ - CONFIGS: Configuration dictionary
365
+ - stdout, stderr: Redirected output streams
366
+ - plt: Configured matplotlib.pyplot module
367
+ - CC: Color cycle dictionary
368
+ - rng: Global RandomStateManager instance for reproducible random generation
369
+ """
370
+ IS_DEBUG = _get_debug_mode()
371
+ ID, PID = _initialize_env(IS_DEBUG)
372
+
373
+ # Convert Path objects to strings for internal processing
374
+ if sdir is not None and isinstance(sdir, Path):
375
+ sdir = str(sdir)
376
+
377
+ ########################################
378
+ # Defines SDIR (DO NOT MODIFY THIS SECTION)
379
+ ########################################
380
+ if sdir is None:
381
+ # Define __file__
382
+ if file:
383
+ caller_file = file
384
+ else:
385
+ caller_file = inspect.stack()[1].filename
386
+ if "ipython" in __file__:
387
+ caller_file = f"/tmp/{_os.getenv('USER')}.py"
388
+
389
+ # Convert to absolute path if relative and resolve symlinks
390
+ if not _os.path.isabs(caller_file):
391
+ caller_file = _os.path.realpath(_os.path.abspath(caller_file))
392
+ else:
393
+ # Even if already absolute, resolve symlinks to get the real path
394
+ caller_file = _os.path.realpath(caller_file)
395
+
396
+ # Define sdir
397
+ sdir = clean_path(
398
+ _os.path.splitext(caller_file)[0] + f"_out/RUNNING/{ID}/"
399
+ )
400
+
401
+ # Optional
402
+ if sdir_suffix:
403
+ sdir = sdir[:-1] + f"-{sdir_suffix}/"
404
+
405
+ if clear_logs:
406
+ _clear_python_log_dir(sdir + caller_file + "/")
407
+ _os.makedirs(sdir, exist_ok=True)
408
+ relative_sdir = _simplify_relative_path(sdir)
409
+ ########################################
410
+
411
+ # Setup configs after having all necessary parameters
412
+ CONFIGS = _setup_configs(
413
+ IS_DEBUG, ID, PID, file, sdir, relative_sdir, verbose
414
+ )
415
+
416
+ # Logging
417
+ if sys is not None:
418
+ flush(sys)
419
+ # Lazy import to avoid circular dependency
420
+ from ..logging._Tee import tee
421
+
422
+ sys.stdout, sys.stderr = tee(sys, sdir=sdir, verbose=verbose)
423
+ CONFIGS["sys"] = sys
424
+
425
+ # Redirect logging handlers to use the tee-wrapped streams
426
+ # This ensures that logger output is captured in the log files
427
+ import logging
428
+
429
+ # Update all existing StreamHandler instances to use our wrapped streams
430
+ for logger_name in list(logging.Logger.manager.loggerDict.keys()):
431
+ try:
432
+ logger = logging.getLogger(logger_name)
433
+ for handler in logger.handlers:
434
+ if isinstance(handler, logging.StreamHandler):
435
+ # StreamHandler typically uses stderr by default
436
+ if not hasattr(handler, "stream"):
437
+ continue
438
+ # Check if handler is using the original stderr or stdout
439
+ if handler.stream in (sys.__stderr__, sys.__stdout__):
440
+ # Replace with our tee-wrapped stream
441
+ handler.stream = (
442
+ sys.stderr
443
+ if handler.stream == sys.__stderr__
444
+ else sys.stdout
445
+ )
446
+ except Exception:
447
+ # Silently skip any logger that can't be updated
448
+ pass
449
+
450
+ # Also update the root logger handlers
451
+ try:
452
+ root_logger = logging.getLogger()
453
+ for handler in root_logger.handlers:
454
+ if isinstance(handler, logging.StreamHandler):
455
+ if not hasattr(handler, "stream"):
456
+ continue
457
+ # Check if handler is using the original stderr or stdout
458
+ if handler.stream in (sys.__stderr__, sys.__stdout__):
459
+ # Replace with our tee-wrapped stream
460
+ handler.stream = (
461
+ sys.stderr
462
+ if handler.stream == sys.__stderr__
463
+ else sys.stdout
464
+ )
465
+ except Exception:
466
+ # Silently skip if root logger can't be updated
467
+ pass
468
+
469
+ # Initialize RandomStateManager (automatically fixes all seeds)
470
+ rng = RandomStateManager(seed=seed, verbose=verbose)
471
+ if verbose:
472
+ logger.info(f"Initialized RandomStateManager with seed {seed}")
473
+
474
+ # Matplotlib configurations
475
+ plt, CC = _setup_matplotlib(
476
+ plt,
477
+ agg,
478
+ fig_size_mm=fig_size_mm,
479
+ fig_scale=fig_scale,
480
+ dpi_display=dpi_display,
481
+ dpi_save=dpi_save,
482
+ hide_top_right_spines=hide_top_right_spines,
483
+ alpha=alpha,
484
+ line_width=line_width,
485
+ fontsize=fontsize,
486
+ autolayout=autolayout,
487
+ verbose=verbose,
488
+ )
489
+
490
+ # Adds argument-parsed variables
491
+ if args is not None:
492
+ CONFIGS["ARGS"] = vars(args) if hasattr(args, "__dict__") else args
493
+
494
+ CONFIGS = DotDict(CONFIGS)
495
+
496
+ # Register session
497
+ session_manager = get_global_session_manager()
498
+ session_manager.create_session(ID, CONFIGS)
499
+
500
+ _print_header(ID, PID, file, args, CONFIGS, verbose)
501
+
502
+ if show_execution_flow:
503
+ structure = analyze_code_flow(file)
504
+ _printc(structure)
505
+
506
+ # Return appropriate values based on whether sys was provided
507
+ if sys is not None:
508
+ return CONFIGS, sys.stdout, sys.stderr, plt, CC, rng
509
+ else:
510
+ return CONFIGS, None, None, plt, CC, rng
511
+
512
+
513
+ def _format_diff_time(diff_time):
514
+ """Format time difference as HH:MM:SS."""
515
+ total_seconds = int(diff_time.total_seconds())
516
+ hours = total_seconds // 3600
517
+ minutes = (total_seconds % 3600) // 60
518
+ seconds = total_seconds % 60
519
+ diff_time_str = f"{hours:02d}:{minutes:02d}:{seconds:02d}"
520
+ return diff_time_str
521
+
522
+
523
+ def _process_timestamp(CONFIG, verbose=True):
524
+ """Process session timestamps."""
525
+ try:
526
+ CONFIG["END_TIME"] = datetime.now()
527
+ CONFIG["RUN_TIME"] = _format_diff_time(
528
+ CONFIG["END_TIME"] - CONFIG["START_TIME"]
529
+ )
530
+ if verbose:
531
+ print()
532
+ print(f"START TIME: {CONFIG['START_TIME']}")
533
+ print(f"END TIME: {CONFIG['END_TIME']}")
534
+ print(f"RUN TIME: {CONFIG['RUN_TIME']}")
535
+ print()
536
+
537
+ except Exception as e:
538
+ print(e)
539
+
540
+ return CONFIG
541
+
542
+
543
+ def _save_configs(CONFIG):
544
+ """Save configuration to files."""
545
+ scitex_io_save(
546
+ CONFIG, CONFIG["SDIR"] + "CONFIGS/CONFIG.pkl", verbose=False
547
+ )
548
+ scitex_io_save(
549
+ CONFIG, CONFIG["SDIR"] + "CONFIGS/CONFIG.yaml", verbose=False
550
+ )
551
+
552
+
553
+ def _escape_ansi_from_log_files(log_files):
554
+ """Remove ANSI escape sequences from log files.
555
+
556
+ Parameters
557
+ ----------
558
+ log_files : list
559
+ List of log file paths to clean
560
+ """
561
+ ansi_escape = re.compile(r"\x1B(?:[@-Z\\-_]|\[[0-?]*[ -/]*[@-~])")
562
+
563
+ # ANSI code escape
564
+ for f in log_files:
565
+ with open(f, "r", encoding="utf-8") as file:
566
+ content = file.read()
567
+ cleaned_content = ansi_escape.sub("", content)
568
+ with open(f, "w", encoding="utf-8") as file:
569
+ file.write(cleaned_content)
570
+
571
+
572
+ def _args_to_str(args_dict):
573
+ """Convert args dictionary to formatted string."""
574
+ if args_dict:
575
+ max_key_length = max(len(str(k)) for k in args_dict.keys())
576
+ return "\n".join(
577
+ f"{str(k):<{max_key_length}} : {str(v)}"
578
+ for k, v in sorted(args_dict.items())
579
+ )
580
+ else:
581
+ return ""
582
+
583
+
584
+ def running2finished(
585
+ CONFIG, exit_status=None, remove_src_dir=True, max_wait=60
586
+ ):
587
+ """Move session from RUNNING to FINISHED directory.
588
+
589
+ Parameters
590
+ ----------
591
+ CONFIG : dict
592
+ Session configuration dictionary
593
+ exit_status : int, optional
594
+ Exit status code (0=success, 1=error, None=finished)
595
+ remove_src_dir : bool, default=True
596
+ Whether to remove source directory after copy
597
+ max_wait : int, default=60
598
+ Maximum seconds to wait for copy operation
599
+
600
+ Returns
601
+ -------
602
+ dict
603
+ Updated configuration with new SDIR
604
+ """
605
+ if exit_status == 0:
606
+ dest_dir = CONFIG["SDIR"].replace("RUNNING/", "FINISHED_SUCCESS/")
607
+ elif exit_status == 1:
608
+ dest_dir = CONFIG["SDIR"].replace("RUNNING/", "FINISHED_ERROR/")
609
+ else: # exit_status is None:
610
+ dest_dir = CONFIG["SDIR"].replace("RUNNING/", "FINISHED/")
611
+
612
+ src_dir = CONFIG["SDIR"]
613
+ _os.makedirs(dest_dir, exist_ok=True)
614
+ try:
615
+
616
+ # Copy files individually
617
+ for item in _os.listdir(src_dir):
618
+ s = _os.path.join(src_dir, item)
619
+ d = _os.path.join(dest_dir, item)
620
+ if _os.path.isdir(s):
621
+ shutil.copytree(s, d)
622
+ else:
623
+ shutil.copy2(s, d)
624
+
625
+ start_time = time.time()
626
+ while (
627
+ not _os.path.exists(dest_dir)
628
+ and time.time() - start_time < max_wait
629
+ ):
630
+ time.sleep(0.1)
631
+ if _os.path.exists(dest_dir):
632
+
633
+ print()
634
+ logger.success(
635
+ f"Congratulations! The script completed: {dest_dir}",
636
+ )
637
+
638
+ if remove_src_dir:
639
+ shutil.rmtree(src_dir)
640
+
641
+ # Cleanup RUNNING when empty
642
+ running_base = os.path.dirname(src_dir.rstrip("/"))
643
+ if os.path.basename(running_base) == "RUNNING":
644
+ try:
645
+ os.rmdir(running_base)
646
+ except OSError:
647
+ pass
648
+
649
+ else:
650
+ print(f"Copy operation timed out after {max_wait} seconds")
651
+
652
+ CONFIG["SDIR"] = dest_dir
653
+ except Exception as e:
654
+ print(e)
655
+
656
+ finally:
657
+ return CONFIG
658
+
659
+
660
+ def close(CONFIG, message=":)", notify=False, verbose=True, exit_status=None):
661
+ """Close experiment session and finalize logging.
662
+
663
+ This function replaces scitex.session.close() with enhanced session management.
664
+
665
+ Parameters
666
+ ----------
667
+ CONFIG : DotDict
668
+ Configuration dictionary from start()
669
+ message : str, default=':)'
670
+ Completion message
671
+ notify : bool, default=False
672
+ Whether to send notification
673
+ verbose : bool, default=True
674
+ Whether to print verbose output
675
+ exit_status : int, optional
676
+ Exit status code (0=success, 1=error, None=finished)
677
+ """
678
+ sys = None # Initialize sys outside try block
679
+ try:
680
+ CONFIG.EXIT_STATUS = exit_status
681
+ CONFIG = CONFIG.to_dict()
682
+ CONFIG = _process_timestamp(CONFIG, verbose=verbose)
683
+ sys = CONFIG.pop("sys", None)
684
+ _save_configs(CONFIG)
685
+
686
+ # RUNNING to FINISHED
687
+ CONFIG = running2finished(CONFIG, exit_status=exit_status)
688
+
689
+ # ANSI code escape
690
+ log_files = _glob(CONFIG["SDIR"] + "logs/*.log")
691
+ _escape_ansi_from_log_files(log_files)
692
+
693
+ if CONFIG.get("ARGS"):
694
+ message += f"\n{_args_to_str(CONFIG.get('ARGS'))}"
695
+
696
+ if notify:
697
+ try:
698
+ message = (
699
+ f"[DEBUG]\n" + str(message)
700
+ if CONFIG.get("DEBUG", False)
701
+ else str(message)
702
+ )
703
+ scitex_utils_notify(
704
+ message=message,
705
+ ID=CONFIG["ID"],
706
+ file=CONFIG.get("FILE"),
707
+ attachment_paths=log_files,
708
+ verbose=verbose,
709
+ )
710
+ except Exception as e:
711
+ print(e)
712
+
713
+ # Close session
714
+ session_manager = get_global_session_manager()
715
+ session_manager.close_session(CONFIG["ID"])
716
+
717
+ finally:
718
+ # Only close if they're custom file objects (Tee objects)
719
+ if sys:
720
+ try:
721
+ # First, flush all outputs
722
+ if hasattr(sys, "stdout") and hasattr(sys.stdout, "flush"):
723
+ sys.stdout.flush()
724
+ if hasattr(sys, "stderr") and hasattr(sys.stderr, "flush"):
725
+ sys.stderr.flush()
726
+
727
+ # Then close Tee objects
728
+ if hasattr(sys, "stdout") and hasattr(sys.stdout, "_log_file"):
729
+ sys.stdout.close()
730
+ if hasattr(sys, "stderr") and hasattr(sys.stderr, "_log_file"):
731
+ sys.stderr.close()
732
+ except Exception:
733
+ # Silent fail to ensure logs are saved even if there's an error
734
+ pass
735
+
736
+ # EOF