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,927 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Timestamp: "2025-10-01 20:28:19 (ywatanabe)"
4
+ # File: /ssh:sp:/home/ywatanabe/proj/scitex_repo/src/scitex/stats/utils/_normalizers.py
5
+ # ----------------------------------------
6
+ from __future__ import annotations
7
+ import os
8
+ __FILE__ = __file__
9
+ __DIR__ = os.path.dirname(__FILE__)
10
+ # ----------------------------------------
11
+
12
+ """
13
+ Output format normalization utilities for scitex.stats.
14
+
15
+ Provides functions to convert between dict and DataFrame formats,
16
+ ensuring consistent output structure across all statistical tests.
17
+ """
18
+
19
+ from typing import Any, Dict, List, Literal, Optional, Union
20
+
21
+ import numpy as np
22
+ import pandas as pd
23
+
24
+ # Standard columns for statistical test outputs
25
+ STANDARD_COLUMNS = [
26
+ "test_method",
27
+ "statistic_name",
28
+ "statistic",
29
+ "alternative",
30
+ "n_samples",
31
+ "n_x",
32
+ "n_y",
33
+ "n_pairs",
34
+ "var_x",
35
+ "var_y",
36
+ "pvalue",
37
+ "pvalue_adjusted",
38
+ "pstars",
39
+ "alpha",
40
+ "alpha_adjusted",
41
+ "rejected",
42
+ "effect_size",
43
+ "effect_size_metric",
44
+ "effect_size_interpretation",
45
+ "effect_size_secondary",
46
+ "effect_size_secondary_metric",
47
+ "effect_size_secondary_interpretation",
48
+ "power",
49
+ "H0",
50
+ ]
51
+
52
+ # Default values for standard columns
53
+ STANDARD_DEFAULTS = {
54
+ "alternative": "two-sided",
55
+ "pstars": "ns",
56
+ "rejected": False,
57
+ "alpha": 0.05,
58
+ "alpha_adjusted": np.nan,
59
+ "pvalue_adjusted": np.nan,
60
+ "power": np.nan,
61
+ "n_samples": np.nan,
62
+ "n_x": np.nan,
63
+ "n_y": np.nan,
64
+ "n_pairs": np.nan,
65
+ "var_x": "",
66
+ "var_y": "",
67
+ }
68
+
69
+ # Column types
70
+ COLUMN_TYPES = {
71
+ "test_method": str,
72
+ "statistic_name": str,
73
+ "statistic": float,
74
+ "alternative": str,
75
+ "n_samples": "Int64", # Nullable integer
76
+ "n_x": "Int64",
77
+ "n_y": "Int64",
78
+ "n_pairs": "Int64",
79
+ "var_x": str,
80
+ "var_y": str,
81
+ "pvalue": float,
82
+ "pvalue_adjusted": float,
83
+ "pstars": str,
84
+ "alpha": float,
85
+ "alpha_adjusted": float,
86
+ "rejected": bool,
87
+ "effect_size": float,
88
+ "effect_size_metric": str,
89
+ "effect_size_interpretation": str,
90
+ "effect_size_secondary": float,
91
+ "effect_size_secondary_metric": str,
92
+ "effect_size_secondary_interpretation": str,
93
+ "power": float,
94
+ "H0": str,
95
+ }
96
+
97
+
98
+ def normalize_result(
99
+ result: Dict[str, Any], fill_missing: bool = True
100
+ ) -> Dict[str, Any]:
101
+ """
102
+ Normalize a test result dictionary to standard format.
103
+
104
+ Parameters
105
+ ----------
106
+ result : dict
107
+ Result dictionary from a statistical test
108
+ fill_missing : bool, default True
109
+ Whether to fill missing standard columns with defaults
110
+
111
+ Returns
112
+ -------
113
+ dict
114
+ Normalized result dictionary
115
+
116
+ Examples
117
+ --------
118
+ >>> result = {'pvalue': 0.023, 'statistic': 2.45}
119
+ >>> normalized = normalize_result(result)
120
+ >>> 'pstars' in normalized
121
+ True
122
+ """
123
+ normalized = result.copy()
124
+
125
+ if fill_missing:
126
+ for col, default in STANDARD_DEFAULTS.items():
127
+ if col not in normalized:
128
+ normalized[col] = default
129
+
130
+ # Use adjusted pvalue if available, otherwise use raw pvalue
131
+ pvalue_for_decision = normalized.get(
132
+ "pvalue_adjusted", normalized.get("pvalue")
133
+ )
134
+ alpha_for_decision = normalized.get(
135
+ "alpha_adjusted", normalized.get("alpha", 0.05)
136
+ )
137
+
138
+ # Compute pstars based on adjusted pvalue if available
139
+ if "pstars" not in normalized and pvalue_for_decision is not None:
140
+ from ._formatters import p2stars
141
+
142
+ normalized["pstars"] = p2stars(pvalue_for_decision)
143
+
144
+ # Compute rejected based on adjusted criteria if available
145
+ if "rejected" not in normalized and pvalue_for_decision is not None:
146
+ normalized["rejected"] = pvalue_for_decision < alpha_for_decision
147
+
148
+ return normalized
149
+
150
+
151
+ def to_dataframe(
152
+ results: Union[Dict[str, Any], List[Dict[str, Any]]],
153
+ normalize: bool = True,
154
+ ) -> pd.DataFrame:
155
+ """
156
+ Convert test result(s) to DataFrame.
157
+
158
+ Parameters
159
+ ----------
160
+ results : dict or list of dict
161
+ Single result dict or list of result dicts
162
+ normalize : bool, default True
163
+ Whether to normalize results before conversion
164
+
165
+ Returns
166
+ -------
167
+ pd.DataFrame
168
+ DataFrame with one row per result
169
+
170
+ Examples
171
+ --------
172
+ >>> result = {'var_x': 'A', 'var_y': 'B', 'pvalue': 0.01}
173
+ >>> df = to_dataframe(result)
174
+ >>> df.shape
175
+ (1, ...)
176
+
177
+ >>> results = [result1, result2, result3]
178
+ >>> df = to_dataframe(results)
179
+ >>> len(df)
180
+ 3
181
+ """
182
+ # Handle single dict
183
+ if isinstance(results, dict):
184
+ results = [results]
185
+
186
+ # Normalize if requested
187
+ if normalize:
188
+ results = [normalize_result(r) for r in results]
189
+
190
+ # Convert to DataFrame
191
+ df = pd.DataFrame(results)
192
+
193
+ return df
194
+
195
+
196
+ def force_dataframe(
197
+ results: Union[Dict[str, Any], List[Dict[str, Any]], pd.DataFrame],
198
+ columns: Optional[List[str]] = None,
199
+ fill_na: bool = True,
200
+ defaults: Optional[Dict[str, Any]] = None,
201
+ enforce_types: bool = True,
202
+ ) -> pd.DataFrame:
203
+ """
204
+ Ensure DataFrame output with consistent columns and types.
205
+
206
+ This is the main function for normalizing statistical test outputs
207
+ to a standard DataFrame format.
208
+
209
+ Parameters
210
+ ----------
211
+ results : dict, list of dict, or DataFrame
212
+ Test result(s) to normalize
213
+ columns : list of str, optional
214
+ Columns to include. If None, uses all columns in results.
215
+ If specified, ensures these columns exist (adds with NaN if missing).
216
+ fill_na : bool, default True
217
+ Whether to fill NaN values with defaults
218
+ defaults : dict, optional
219
+ Custom default values. Merged with STANDARD_DEFAULTS.
220
+ enforce_types : bool, default True
221
+ Whether to enforce correct dtypes for standard columns
222
+
223
+ Returns
224
+ -------
225
+ pd.DataFrame
226
+ Normalized DataFrame with consistent format
227
+
228
+ Examples
229
+ --------
230
+ >>> # Basic usage
231
+ >>> results = [
232
+ ... {'var_x': 'A', 'pvalue': 0.01},
233
+ ... {'var_x': 'B', 'pvalue': 0.05, 'effect_size': 0.5},
234
+ ... ]
235
+ >>> df = force_dataframe(results)
236
+ >>> 'effect_size' in df.columns
237
+ True
238
+ >>> df['effect_size'].isna().sum()
239
+ 1
240
+
241
+ >>> # Specify required columns
242
+ >>> df = force_dataframe(
243
+ ... results,
244
+ ... columns=['var_x', 'pvalue', 'pstars', 'rejected']
245
+ ... )
246
+ >>> set(df.columns) >= {'var_x', 'pvalue', 'pstars', 'rejected'}
247
+ True
248
+
249
+ >>> # Custom defaults
250
+ >>> df = force_dataframe(
251
+ ... results,
252
+ ... defaults={'effect_size': 0.0, 'pstars': 'ns'}
253
+ ... )
254
+ """
255
+ # Convert to DataFrame if needed
256
+ if not isinstance(results, pd.DataFrame):
257
+ df = to_dataframe(results, normalize=True)
258
+ else:
259
+ df = results.copy()
260
+
261
+ # Merge custom defaults with standard defaults
262
+ all_defaults = STANDARD_DEFAULTS.copy()
263
+ if defaults:
264
+ all_defaults.update(defaults)
265
+
266
+ # Ensure specified columns exist
267
+ if columns:
268
+ for col in columns:
269
+ if col not in df.columns:
270
+ default_val = all_defaults.get(col, np.nan)
271
+ df[col] = default_val
272
+
273
+ # Fill NaN values with defaults
274
+ if fill_na:
275
+ for col, default_val in all_defaults.items():
276
+ if col in df.columns:
277
+ df[col] = df[col].fillna(default_val)
278
+
279
+ # Enforce types for standard columns
280
+ if enforce_types:
281
+ for col, dtype in COLUMN_TYPES.items():
282
+ if col in df.columns:
283
+ try:
284
+ df[col] = df[col].astype(dtype)
285
+ except (ValueError, TypeError):
286
+ # Skip if conversion fails
287
+ pass
288
+
289
+ return df
290
+
291
+
292
+ def to_dict(df: pd.DataFrame, row: int = 0) -> Dict[str, Any]:
293
+ """
294
+ Convert DataFrame row to dictionary.
295
+
296
+ Parameters
297
+ ----------
298
+ df : pd.DataFrame
299
+ DataFrame containing test results
300
+ row : int, default 0
301
+ Row index to convert
302
+
303
+ Returns
304
+ -------
305
+ dict
306
+ Dictionary representation of the row
307
+
308
+ Examples
309
+ --------
310
+ >>> df = pd.DataFrame({'pvalue': [0.01, 0.05], 'var_x': ['A', 'B']})
311
+ >>> result = to_dict(df, row=1)
312
+ >>> result['var_x']
313
+ 'B'
314
+ """
315
+ return df.iloc[row].to_dict()
316
+
317
+
318
+ def combine_results(
319
+ results_list: List[Union[Dict, pd.DataFrame]], **kwargs
320
+ ) -> pd.DataFrame:
321
+ """
322
+ Combine multiple test results into a single DataFrame.
323
+
324
+ Parameters
325
+ ----------
326
+ results_list : list
327
+ List of result dicts or DataFrames
328
+ **kwargs : dict
329
+ Additional arguments passed to force_dataframe
330
+
331
+ Returns
332
+ -------
333
+ pd.DataFrame
334
+ Combined DataFrame with all results
335
+
336
+ Examples
337
+ --------
338
+ >>> r1 = test_ttest_ind(x1, y1, var_x='Control', var_y='Treatment')
339
+ >>> r2 = test_ttest_ind(x2, y2, var_x='Placebo', var_y='Drug')
340
+ >>> df = combine_results([r1, r2])
341
+ >>> len(df)
342
+ 2
343
+ """
344
+ # Convert all to DataFrames
345
+ dfs = []
346
+ for result in results_list:
347
+ if isinstance(result, dict):
348
+ df = to_dataframe(result)
349
+ elif isinstance(result, pd.DataFrame):
350
+ df = result
351
+ else:
352
+ raise TypeError(f"Expected dict or DataFrame, got {type(result)}")
353
+ dfs.append(df)
354
+
355
+ # Concatenate
356
+ combined = pd.concat(dfs, ignore_index=True)
357
+
358
+ # Normalize
359
+ return force_dataframe(combined, **kwargs)
360
+
361
+
362
+ def export_results(
363
+ results: Union[Dict[str, Any], List[Dict[str, Any]], pd.DataFrame],
364
+ path: str,
365
+ format: Optional[str] = None,
366
+ **kwargs,
367
+ ) -> str:
368
+ """
369
+ Export test results to various formats.
370
+
371
+ Parameters
372
+ ----------
373
+ results : dict, list of dict, or DataFrame
374
+ Test results to export
375
+ path : str
376
+ Output file path
377
+ format : str, optional
378
+ Output format: 'csv', 'txt', 'json', 'xlsx', 'latex'
379
+ If None, inferred from path extension
380
+ **kwargs : dict
381
+ Additional arguments passed to export function
382
+
383
+ Returns
384
+ -------
385
+ str
386
+ Path to exported file
387
+
388
+ Examples
389
+ --------
390
+ >>> result = test_ttest_ind(x, y)
391
+ >>> export_results(result, 'results.csv')
392
+ 'results.csv'
393
+
394
+ >>> # Multiple results
395
+ >>> results = [result1, result2, result3]
396
+ >>> export_results(results, 'results.xlsx')
397
+ 'results.xlsx'
398
+
399
+ >>> # LaTeX table
400
+ >>> export_results(results, 'results.tex', format='latex')
401
+ 'results.tex'
402
+ """
403
+ import os
404
+
405
+ # Infer format from extension if not provided
406
+ if format is None:
407
+ _, ext = os.path.splitext(path)
408
+ format = ext.lstrip(".").lower()
409
+
410
+ # Convert to DataFrame
411
+ if not isinstance(results, pd.DataFrame):
412
+ df = force_dataframe(results)
413
+ else:
414
+ df = results
415
+
416
+ # Export based on format
417
+ if format == "csv":
418
+ df.to_csv(path, index=False, **kwargs)
419
+ # Add signature as comment
420
+ with open(path, "a") as f:
421
+ f.write(f"\n# {_get_scitex_signature('excel')}\n")
422
+ elif format in ["txt", "tsv"]:
423
+ df.to_csv(path, index=False, sep="\t", **kwargs)
424
+ # Add signature
425
+ with open(path, "a") as f:
426
+ f.write(f"\n{_get_scitex_signature('text')}")
427
+ elif format == "json":
428
+ # Export JSON with metadata
429
+ import json
430
+
431
+ data = {
432
+ "data": df.to_dict("records"),
433
+ "metadata": {
434
+ "generated_by": "SciTeX Stats",
435
+ "timestamp": _get_scitex_signature("excel").split(" | ")[1],
436
+ "description": "Professional Statistical Analysis Framework for Scientific Computing",
437
+ },
438
+ }
439
+ with open(path, "w") as f:
440
+ json.dump(data, f, indent=2, **kwargs)
441
+ elif format == "xlsx":
442
+ df.to_excel(path, index=False, **kwargs)
443
+ elif format in ["latex", "tex"]:
444
+ latex_str = df.to_latex(index=False, **kwargs)
445
+ # Add signature as LaTeX comment
446
+ latex_str += f"\n% {_get_scitex_signature('excel')}\n"
447
+ with open(path, "w") as f:
448
+ f.write(latex_str)
449
+ else:
450
+ raise ValueError(
451
+ f"Unsupported format: {format}. "
452
+ f"Use 'csv', 'txt', 'json', 'xlsx', or 'latex'"
453
+ )
454
+
455
+ return path
456
+
457
+
458
+ def export_excel_styled(
459
+ results: Union[Dict[str, Any], List[Dict[str, Any]], pd.DataFrame],
460
+ path: str,
461
+ **kwargs,
462
+ ) -> str:
463
+ """ """
464
+ pass
465
+
466
+
467
+ def export_report(
468
+ results: Union[Dict[str, Any], List[Dict[str, Any]], pd.DataFrame],
469
+ path: str,
470
+ title: str = "Statistical Analysis Report",
471
+ include_summary: bool = True,
472
+ **kwargs,
473
+ ) -> str:
474
+ """
475
+ Export formatted report with colored highlights.
476
+
477
+ Parameters
478
+ ----------
479
+ results : dict, list of dict, or DataFrame
480
+ Test results to export
481
+ path : str
482
+ Output file path (supports .html, .md, .txt)
483
+ title : str, default "Statistical Analysis Report"
484
+ Report title
485
+ include_summary : bool, default True
486
+ Whether to include summary statistics
487
+ **kwargs : dict
488
+ Additional arguments
489
+
490
+ Returns
491
+ -------
492
+ str
493
+ Path to exported file
494
+
495
+ Notes
496
+ -----
497
+ Report includes:
498
+ - Summary statistics (counts of significant results)
499
+ - Full results table with color-coded significance
500
+ - Automatic detection of output format from extension
501
+
502
+ Examples
503
+ --------
504
+ >>> results = [result1, result2, result3]
505
+ >>> export_report(results, 'report.html', title='My Analysis')
506
+ 'report.html'
507
+
508
+ >>> export_report(results, 'report.md') # Markdown format
509
+ 'report.md'
510
+ """
511
+ import os
512
+
513
+ # Convert to DataFrame
514
+ if not isinstance(results, pd.DataFrame):
515
+ df = force_dataframe(results)
516
+ else:
517
+ df = results
518
+
519
+ # Detect format
520
+ _, ext = os.path.splitext(path)
521
+ format_type = ext.lstrip(".").lower()
522
+
523
+ # Generate report based on format
524
+ if format_type == "html":
525
+ return _export_report_html(df, path, title, include_summary)
526
+ elif format_type == "md":
527
+ return _export_report_markdown(df, path, title, include_summary)
528
+ else: # txt or other
529
+ return _export_report_text(df, path, title, include_summary)
530
+
531
+
532
+ def _get_scitex_signature(format_type="html"):
533
+ """Generate SciTeX Stats signature for branding."""
534
+ import datetime
535
+
536
+ timestamp = datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S")
537
+
538
+ if format_type == "html":
539
+ return f"""
540
+ <div style="margin-top: 30px; padding-top: 20px; border-top: 2px solid #ddd; text-align: center; color: #666; font-size: 12px;">
541
+ <p>Generated by <strong style="color: #4CAF50;">SciTeX Stats</strong> | {timestamp}</p>
542
+ <p style="font-size: 10px;">Professional Statistical Analysis Framework for Scientific Computing</p>
543
+ </div>
544
+ """
545
+ elif format_type == "markdown":
546
+ return f"\n\n---\n\n*Generated by **SciTeX Stats** | {timestamp}*\n\n*Professional Statistical Analysis Framework for Scientific Computing*\n"
547
+ elif format_type == "text":
548
+ return f"\n\n{'='*80}\nGenerated by SciTeX Stats | {timestamp}\nProfessional Statistical Analysis Framework for Scientific Computing\n{'='*80}\n"
549
+ else:
550
+ return f"Generated by SciTeX Stats | {timestamp}"
551
+
552
+
553
+ def _export_report_html(df, path, title, include_summary):
554
+ """Generate HTML report with styling."""
555
+ # Generate summary
556
+ summary_html = ""
557
+ if include_summary and "pvalue" in df.columns:
558
+ n_total = len(df)
559
+ n_sig_001 = (df["pvalue"] < 0.001).sum()
560
+ n_sig_01 = ((df["pvalue"] >= 0.001) & (df["pvalue"] < 0.01)).sum()
561
+ n_sig_05 = ((df["pvalue"] >= 0.01) & (df["pvalue"] < 0.05)).sum()
562
+ n_ns = (df["pvalue"] >= 0.05).sum()
563
+
564
+ summary_html = f"""
565
+ <div class="summary">
566
+ <h2>Summary</h2>
567
+ <ul>
568
+ <li>Total tests: {n_total}</li>
569
+ <li style="color: #FF6B6B; font-weight: bold;">p < 0.001 (***): {n_sig_001}</li>
570
+ <li style="color: #FFA500; font-weight: bold;">p < 0.01 (**): {n_sig_01}</li>
571
+ <li style="color: #FFE66D; font-weight: bold;">p < 0.05 (*): {n_sig_05}</li>
572
+ <li style="color: #999;">p >= 0.05 (ns): {n_ns}</li>
573
+ </ul>
574
+ </div>
575
+ """
576
+
577
+ # Style function for DataFrame
578
+ def style_pvalue(val):
579
+ if pd.isna(val):
580
+ return ""
581
+ if val < 0.001:
582
+ return (
583
+ "background-color: #FF6B6B; font-weight: bold; color: white;"
584
+ )
585
+ elif val < 0.01:
586
+ return (
587
+ "background-color: #FFA500; font-weight: bold; color: white;"
588
+ )
589
+ elif val < 0.05:
590
+ return "background-color: #FFE66D; font-weight: bold;"
591
+ else:
592
+ return "background-color: #E8E8E8;"
593
+
594
+ # Apply styling
595
+ if "pvalue" in df.columns:
596
+ styled = df.style.applymap(style_pvalue, subset=["pvalue"])
597
+ else:
598
+ styled = df.style
599
+
600
+ # Generate HTML
601
+ table_html = styled.to_html()
602
+
603
+ html_content = f"""
604
+ <!DOCTYPE html>
605
+ <html>
606
+ <head>
607
+ <title>{title}</title>
608
+ <style>
609
+ body {{
610
+ font-family: Arial, sans-serif;
611
+ margin: 20px;
612
+ background-color: #f5f5f5;
613
+ }}
614
+ h1 {{
615
+ color: #333;
616
+ border-bottom: 3px solid #4CAF50;
617
+ padding-bottom: 10px;
618
+ }}
619
+ .summary {{
620
+ background-color: white;
621
+ padding: 15px;
622
+ border-radius: 5px;
623
+ margin-bottom: 20px;
624
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
625
+ }}
626
+ table {{
627
+ border-collapse: collapse;
628
+ width: 100%;
629
+ background-color: white;
630
+ box-shadow: 0 2px 4px rgba(0,0,0,0.1);
631
+ }}
632
+ th {{
633
+ background-color: #4CAF50;
634
+ color: white;
635
+ padding: 12px;
636
+ text-align: left;
637
+ }}
638
+ td {{
639
+ padding: 10px;
640
+ border-bottom: 1px solid #ddd;
641
+ }}
642
+ tr:hover {{
643
+ background-color: #f5f5f5;
644
+ }}
645
+ </style>
646
+ </head>
647
+ <body>
648
+ <h1>{title}</h1>
649
+ {summary_html}
650
+ <h2>Results</h2>
651
+ {table_html}
652
+ {_get_scitex_signature('html')}
653
+ </body>
654
+ </html>
655
+ """
656
+
657
+ with open(path, "w") as f:
658
+ f.write(html_content)
659
+
660
+ return path
661
+
662
+
663
+ def _export_report_markdown(df, path, title, include_summary):
664
+ """Generate Markdown report."""
665
+ lines = [f"# {title}\n"]
666
+
667
+ # Summary
668
+ if include_summary and "pvalue" in df.columns:
669
+ n_total = len(df)
670
+ n_sig = (df["pvalue"] < 0.05).sum()
671
+ n_ns = (df["pvalue"] >= 0.05).sum()
672
+
673
+ lines.append("## Summary\n")
674
+ lines.append(f"- Total tests: {n_total}")
675
+ lines.append(f"- Significant (p < 0.05): {n_sig}")
676
+ lines.append(f"- Non-significant (p >= 0.05): {n_ns}\n")
677
+
678
+ # Table
679
+ lines.append("## Results\n")
680
+ lines.append(df.to_markdown(index=False))
681
+
682
+ # Add signature
683
+ lines.append(_get_scitex_signature("markdown"))
684
+
685
+ with open(path, "w") as f:
686
+ f.write("\n".join(lines))
687
+
688
+ return path
689
+
690
+
691
+ def _export_report_text(df, path, title, include_summary):
692
+ """Generate plain text report."""
693
+ lines = [title, "=" * len(title), ""]
694
+
695
+ # Summary
696
+ if include_summary and "pvalue" in df.columns:
697
+ n_total = len(df)
698
+ n_sig = (df["pvalue"] < 0.05).sum()
699
+
700
+ lines.append("SUMMARY")
701
+ lines.append(f"Total tests: {n_total}")
702
+ lines.append(f"Significant: {n_sig}")
703
+ lines.append("")
704
+
705
+ # Table
706
+ lines.append("RESULTS")
707
+ lines.append(df.to_string(index=False))
708
+
709
+ # Add signature
710
+ lines.append(_get_scitex_signature("text"))
711
+
712
+ with open(path, "w") as f:
713
+ f.write("\n".join(lines))
714
+
715
+ return path
716
+
717
+
718
+ def export_summary(
719
+ results: Union[Dict[str, Any], List[Dict[str, Any]], pd.DataFrame],
720
+ path: str,
721
+ columns: Optional[List[str]] = None,
722
+ format: Optional[str] = None,
723
+ **kwargs,
724
+ ) -> str:
725
+ """
726
+ Export summary of test results (selected columns only).
727
+
728
+ Parameters
729
+ ----------
730
+ results : dict, list of dict, or DataFrame
731
+ Test results to export
732
+ path : str
733
+ Output file path
734
+ columns : list of str, optional
735
+ Columns to include. Default: key columns for reporting
736
+ format : str, optional
737
+ Output format (inferred from extension if None)
738
+ **kwargs : dict
739
+ Additional arguments passed to export function
740
+
741
+ Returns
742
+ -------
743
+ str
744
+ Path to exported file
745
+
746
+ Examples
747
+ --------
748
+ >>> # Export only key columns
749
+ >>> export_summary(results, 'summary.csv')
750
+ 'summary.csv'
751
+
752
+ >>> # Custom columns
753
+ >>> export_summary(
754
+ ... results,
755
+ ... 'summary.xlsx',
756
+ ... columns=['var_x', 'var_y', 'pvalue', 'effect_size']
757
+ ... )
758
+ 'summary.xlsx'
759
+ """
760
+ # Default summary columns
761
+ if columns is None:
762
+ columns = [
763
+ "test_method",
764
+ "var_x",
765
+ "var_y",
766
+ "n_x",
767
+ "n_y",
768
+ "statistic",
769
+ "pvalue",
770
+ "pstars",
771
+ "rejected",
772
+ "effect_size",
773
+ "effect_size_metric",
774
+ "effect_size_interpretation",
775
+ ]
776
+
777
+ # Convert to DataFrame
778
+ if not isinstance(results, pd.DataFrame):
779
+ df = force_dataframe(results)
780
+ else:
781
+ df = results
782
+
783
+ # Select columns (only those that exist)
784
+ available_cols = [col for col in columns if col in df.columns]
785
+ df_summary = df[available_cols]
786
+
787
+ # Export
788
+ return export_results(df_summary, path, format=format, **kwargs)
789
+
790
+
791
+ def convert_results(
792
+ results: Union[Dict[str, Any], List[Dict[str, Any]], pd.DataFrame],
793
+ return_as: Literal[
794
+ "dict",
795
+ "dataframe",
796
+ "markdown",
797
+ "json",
798
+ "latex",
799
+ "html",
800
+ "text",
801
+ ] = "dict",
802
+ **kwargs,
803
+ ) -> Union[dict, List[dict], pd.DataFrame, str]:
804
+ """
805
+ Convert statistical test results to specified format.
806
+
807
+ This is a pure format converter - does NOT save files.
808
+ For saving, use scitex.io.save() after conversion.
809
+
810
+ Parameters
811
+ ----------
812
+ results : dict, list of dict, or DataFrame
813
+ Test results to convert
814
+ return_as : str, default 'dict'
815
+ Output format:
816
+ - 'dict': Python dictionary (single result) or list of dicts (multiple)
817
+ - 'dataframe': pandas DataFrame
818
+ - 'markdown': Markdown table string
819
+ - 'json': JSON string
820
+ - 'latex': LaTeX table string
821
+ - 'html': HTML table string
822
+ - 'text': Plain text table string
823
+ **kwargs : dict
824
+ Additional arguments passed to format functions
825
+
826
+ Returns
827
+ -------
828
+ output : dict, list, DataFrame, or str
829
+ Converted results in requested format
830
+
831
+ Notes
832
+ -----
833
+ This function only handles format conversion. To save results to files,
834
+ convert to DataFrame first, then use scitex.io.save():
835
+
836
+ >>> df = convert_results(results, return_as='dataframe')
837
+ >>> stx.io.save(df, 'results.xlsx')
838
+
839
+ Examples
840
+ --------
841
+ >>> result = {'pvalue': 0.01, 'var_x': 'A', 'var_y': 'B'}
842
+
843
+ # Convert to different formats
844
+ >>> convert_results(result, return_as='dict')
845
+ {'pvalue': 0.01, 'var_x': 'A', 'var_y': 'B'}
846
+
847
+ >>> df = convert_results(result, return_as='dataframe')
848
+ # Returns DataFrame
849
+
850
+ >>> convert_results(result, return_as='markdown')
851
+ '| var_x | var_y | pvalue |\\n|-------|-------|--------|...'
852
+
853
+ >>> latex_str = convert_results(result, return_as='latex')
854
+
855
+ # To save to file, use stx.io.save
856
+ >>> import scitex as stx
857
+ >>> df = convert_results(result, return_as='dataframe')
858
+ >>> stx.io.save(df, 'results.xlsx') # Uses stx.io.save for file operations
859
+ """
860
+ # Handle each format - pure conversion, no file I/O
861
+ if return_as == "dict":
862
+ if isinstance(results, dict):
863
+ return results
864
+ elif isinstance(results, list):
865
+ return results
866
+ elif isinstance(results, pd.DataFrame):
867
+ return (
868
+ results.to_dict("records")
869
+ if len(results) > 1
870
+ else to_dict(results, row=0)
871
+ )
872
+
873
+ elif return_as == "dataframe":
874
+ return force_dataframe(results)
875
+
876
+ elif return_as == "markdown":
877
+ df_out = force_dataframe(results)
878
+ return df_out.to_markdown(index=False, **kwargs)
879
+
880
+ elif return_as == "json":
881
+ df_out = force_dataframe(results)
882
+ return df_out.to_json(orient="records", indent=2, **kwargs)
883
+
884
+ elif return_as == "latex":
885
+ df_out = force_dataframe(results)
886
+ return df_out.to_latex(index=False, **kwargs)
887
+
888
+ elif return_as == "html":
889
+ df_out = force_dataframe(results)
890
+ return df_out.to_html(index=False, **kwargs)
891
+
892
+ elif return_as == "text":
893
+ df_out = force_dataframe(results)
894
+ return df_out.to_string(index=False, **kwargs)
895
+
896
+ elif return_as == "csv":
897
+ df_out = force_dataframe(results)
898
+ return df_out.to_csv(index=False, **kwargs)
899
+
900
+ else:
901
+ raise ValueError(
902
+ f"Unknown return_as format: {return_as}. "
903
+ f"Use 'dict', 'dataframe', 'markdown', 'json', 'latex', 'html', or 'text'"
904
+ )
905
+
906
+
907
+ # Convenience alias
908
+ as_dataframe = force_dataframe
909
+
910
+ __all__ = [
911
+ "normalize_result",
912
+ "to_dataframe",
913
+ "force_dataframe",
914
+ "to_dict",
915
+ "combine_results",
916
+ "convert_results",
917
+ "export_results",
918
+ "export_summary",
919
+ "export_excel_styled",
920
+ "export_report",
921
+ "as_dataframe",
922
+ "STANDARD_COLUMNS",
923
+ "STANDARD_DEFAULTS",
924
+ "COLUMN_TYPES",
925
+ ]
926
+
927
+ # EOF