scitex 2.0.0__py2.py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (572) hide show
  1. scitex/__init__.py +73 -0
  2. scitex/__main__.py +89 -0
  3. scitex/__version__.py +14 -0
  4. scitex/_sh.py +59 -0
  5. scitex/ai/_LearningCurveLogger.py +583 -0
  6. scitex/ai/__Classifiers.py +101 -0
  7. scitex/ai/__init__.py +55 -0
  8. scitex/ai/_gen_ai/_Anthropic.py +173 -0
  9. scitex/ai/_gen_ai/_BaseGenAI.py +336 -0
  10. scitex/ai/_gen_ai/_DeepSeek.py +175 -0
  11. scitex/ai/_gen_ai/_Google.py +161 -0
  12. scitex/ai/_gen_ai/_Groq.py +97 -0
  13. scitex/ai/_gen_ai/_Llama.py +142 -0
  14. scitex/ai/_gen_ai/_OpenAI.py +230 -0
  15. scitex/ai/_gen_ai/_PARAMS.py +565 -0
  16. scitex/ai/_gen_ai/_Perplexity.py +191 -0
  17. scitex/ai/_gen_ai/__init__.py +32 -0
  18. scitex/ai/_gen_ai/_calc_cost.py +78 -0
  19. scitex/ai/_gen_ai/_format_output_func.py +183 -0
  20. scitex/ai/_gen_ai/_genai_factory.py +71 -0
  21. scitex/ai/act/__init__.py +8 -0
  22. scitex/ai/act/_define.py +11 -0
  23. scitex/ai/classification/__init__.py +7 -0
  24. scitex/ai/classification/classification_reporter.py +1137 -0
  25. scitex/ai/classification/classifier_server.py +131 -0
  26. scitex/ai/classification/classifiers.py +101 -0
  27. scitex/ai/classification_reporter.py +1161 -0
  28. scitex/ai/classifier_server.py +131 -0
  29. scitex/ai/clustering/__init__.py +11 -0
  30. scitex/ai/clustering/_pca.py +115 -0
  31. scitex/ai/clustering/_umap.py +376 -0
  32. scitex/ai/early_stopping.py +149 -0
  33. scitex/ai/feature_extraction/__init__.py +56 -0
  34. scitex/ai/feature_extraction/vit.py +148 -0
  35. scitex/ai/genai/__init__.py +277 -0
  36. scitex/ai/genai/anthropic.py +177 -0
  37. scitex/ai/genai/anthropic_provider.py +320 -0
  38. scitex/ai/genai/anthropic_refactored.py +109 -0
  39. scitex/ai/genai/auth_manager.py +200 -0
  40. scitex/ai/genai/base_genai.py +336 -0
  41. scitex/ai/genai/base_provider.py +291 -0
  42. scitex/ai/genai/calc_cost.py +78 -0
  43. scitex/ai/genai/chat_history.py +307 -0
  44. scitex/ai/genai/cost_tracker.py +276 -0
  45. scitex/ai/genai/deepseek.py +188 -0
  46. scitex/ai/genai/deepseek_provider.py +251 -0
  47. scitex/ai/genai/format_output_func.py +183 -0
  48. scitex/ai/genai/genai_factory.py +71 -0
  49. scitex/ai/genai/google.py +169 -0
  50. scitex/ai/genai/google_provider.py +228 -0
  51. scitex/ai/genai/groq.py +104 -0
  52. scitex/ai/genai/groq_provider.py +248 -0
  53. scitex/ai/genai/image_processor.py +250 -0
  54. scitex/ai/genai/llama.py +155 -0
  55. scitex/ai/genai/llama_provider.py +214 -0
  56. scitex/ai/genai/mock_provider.py +127 -0
  57. scitex/ai/genai/model_registry.py +304 -0
  58. scitex/ai/genai/openai.py +230 -0
  59. scitex/ai/genai/openai_provider.py +293 -0
  60. scitex/ai/genai/params.py +565 -0
  61. scitex/ai/genai/perplexity.py +202 -0
  62. scitex/ai/genai/perplexity_provider.py +205 -0
  63. scitex/ai/genai/provider_base.py +302 -0
  64. scitex/ai/genai/provider_factory.py +370 -0
  65. scitex/ai/genai/response_handler.py +235 -0
  66. scitex/ai/layer/_Pass.py +21 -0
  67. scitex/ai/layer/__init__.py +10 -0
  68. scitex/ai/layer/_switch.py +8 -0
  69. scitex/ai/loss/_L1L2Losses.py +34 -0
  70. scitex/ai/loss/__init__.py +12 -0
  71. scitex/ai/loss/multi_task_loss.py +47 -0
  72. scitex/ai/metrics/__init__.py +9 -0
  73. scitex/ai/metrics/_bACC.py +51 -0
  74. scitex/ai/metrics/silhoute_score_block.py +496 -0
  75. scitex/ai/optim/Ranger_Deep_Learning_Optimizer/__init__.py +0 -0
  76. scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/__init__.py +3 -0
  77. scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger.py +207 -0
  78. scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger2020.py +238 -0
  79. scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/ranger913A.py +215 -0
  80. scitex/ai/optim/Ranger_Deep_Learning_Optimizer/ranger/rangerqh.py +184 -0
  81. scitex/ai/optim/Ranger_Deep_Learning_Optimizer/setup.py +24 -0
  82. scitex/ai/optim/__init__.py +13 -0
  83. scitex/ai/optim/_get_set.py +31 -0
  84. scitex/ai/optim/_optimizers.py +71 -0
  85. scitex/ai/plt/__init__.py +21 -0
  86. scitex/ai/plt/_conf_mat.py +592 -0
  87. scitex/ai/plt/_learning_curve.py +194 -0
  88. scitex/ai/plt/_optuna_study.py +111 -0
  89. scitex/ai/plt/aucs/__init__.py +2 -0
  90. scitex/ai/plt/aucs/example.py +60 -0
  91. scitex/ai/plt/aucs/pre_rec_auc.py +223 -0
  92. scitex/ai/plt/aucs/roc_auc.py +246 -0
  93. scitex/ai/sampling/undersample.py +29 -0
  94. scitex/ai/sk/__init__.py +11 -0
  95. scitex/ai/sk/_clf.py +58 -0
  96. scitex/ai/sk/_to_sktime.py +100 -0
  97. scitex/ai/sklearn/__init__.py +26 -0
  98. scitex/ai/sklearn/clf.py +58 -0
  99. scitex/ai/sklearn/to_sktime.py +100 -0
  100. scitex/ai/training/__init__.py +7 -0
  101. scitex/ai/training/early_stopping.py +150 -0
  102. scitex/ai/training/learning_curve_logger.py +555 -0
  103. scitex/ai/utils/__init__.py +22 -0
  104. scitex/ai/utils/_check_params.py +50 -0
  105. scitex/ai/utils/_default_dataset.py +46 -0
  106. scitex/ai/utils/_format_samples_for_sktime.py +26 -0
  107. scitex/ai/utils/_label_encoder.py +134 -0
  108. scitex/ai/utils/_merge_labels.py +22 -0
  109. scitex/ai/utils/_sliding_window_data_augmentation.py +11 -0
  110. scitex/ai/utils/_under_sample.py +51 -0
  111. scitex/ai/utils/_verify_n_gpus.py +16 -0
  112. scitex/ai/utils/grid_search.py +148 -0
  113. scitex/context/__init__.py +9 -0
  114. scitex/context/_suppress_output.py +38 -0
  115. scitex/db/_BaseMixins/_BaseBackupMixin.py +30 -0
  116. scitex/db/_BaseMixins/_BaseBatchMixin.py +31 -0
  117. scitex/db/_BaseMixins/_BaseBlobMixin.py +81 -0
  118. scitex/db/_BaseMixins/_BaseConnectionMixin.py +43 -0
  119. scitex/db/_BaseMixins/_BaseImportExportMixin.py +39 -0
  120. scitex/db/_BaseMixins/_BaseIndexMixin.py +29 -0
  121. scitex/db/_BaseMixins/_BaseMaintenanceMixin.py +33 -0
  122. scitex/db/_BaseMixins/_BaseQueryMixin.py +52 -0
  123. scitex/db/_BaseMixins/_BaseRowMixin.py +32 -0
  124. scitex/db/_BaseMixins/_BaseSchemaMixin.py +44 -0
  125. scitex/db/_BaseMixins/_BaseTableMixin.py +66 -0
  126. scitex/db/_BaseMixins/_BaseTransactionMixin.py +52 -0
  127. scitex/db/_BaseMixins/__init__.py +30 -0
  128. scitex/db/_PostgreSQL.py +126 -0
  129. scitex/db/_PostgreSQLMixins/_BackupMixin.py +166 -0
  130. scitex/db/_PostgreSQLMixins/_BatchMixin.py +82 -0
  131. scitex/db/_PostgreSQLMixins/_BlobMixin.py +231 -0
  132. scitex/db/_PostgreSQLMixins/_ConnectionMixin.py +92 -0
  133. scitex/db/_PostgreSQLMixins/_ImportExportMixin.py +59 -0
  134. scitex/db/_PostgreSQLMixins/_IndexMixin.py +64 -0
  135. scitex/db/_PostgreSQLMixins/_MaintenanceMixin.py +175 -0
  136. scitex/db/_PostgreSQLMixins/_QueryMixin.py +108 -0
  137. scitex/db/_PostgreSQLMixins/_RowMixin.py +75 -0
  138. scitex/db/_PostgreSQLMixins/_SchemaMixin.py +126 -0
  139. scitex/db/_PostgreSQLMixins/_TableMixin.py +176 -0
  140. scitex/db/_PostgreSQLMixins/_TransactionMixin.py +57 -0
  141. scitex/db/_PostgreSQLMixins/__init__.py +34 -0
  142. scitex/db/_SQLite3.py +2136 -0
  143. scitex/db/_SQLite3Mixins/_BatchMixin.py +243 -0
  144. scitex/db/_SQLite3Mixins/_BlobMixin.py +229 -0
  145. scitex/db/_SQLite3Mixins/_ConnectionMixin.py +108 -0
  146. scitex/db/_SQLite3Mixins/_ImportExportMixin.py +80 -0
  147. scitex/db/_SQLite3Mixins/_IndexMixin.py +32 -0
  148. scitex/db/_SQLite3Mixins/_MaintenanceMixin.py +176 -0
  149. scitex/db/_SQLite3Mixins/_QueryMixin.py +83 -0
  150. scitex/db/_SQLite3Mixins/_RowMixin.py +75 -0
  151. scitex/db/_SQLite3Mixins/_TableMixin.py +183 -0
  152. scitex/db/_SQLite3Mixins/_TransactionMixin.py +71 -0
  153. scitex/db/_SQLite3Mixins/__init__.py +30 -0
  154. scitex/db/__init__.py +14 -0
  155. scitex/db/_delete_duplicates.py +397 -0
  156. scitex/db/_inspect.py +163 -0
  157. scitex/decorators/__init__.py +54 -0
  158. scitex/decorators/_auto_order.py +172 -0
  159. scitex/decorators/_batch_fn.py +127 -0
  160. scitex/decorators/_cache_disk.py +32 -0
  161. scitex/decorators/_cache_mem.py +12 -0
  162. scitex/decorators/_combined.py +98 -0
  163. scitex/decorators/_converters.py +282 -0
  164. scitex/decorators/_deprecated.py +26 -0
  165. scitex/decorators/_not_implemented.py +30 -0
  166. scitex/decorators/_numpy_fn.py +86 -0
  167. scitex/decorators/_pandas_fn.py +121 -0
  168. scitex/decorators/_preserve_doc.py +19 -0
  169. scitex/decorators/_signal_fn.py +95 -0
  170. scitex/decorators/_timeout.py +55 -0
  171. scitex/decorators/_torch_fn.py +136 -0
  172. scitex/decorators/_wrap.py +39 -0
  173. scitex/decorators/_xarray_fn.py +88 -0
  174. scitex/dev/__init__.py +15 -0
  175. scitex/dev/_analyze_code_flow.py +284 -0
  176. scitex/dev/_reload.py +59 -0
  177. scitex/dict/_DotDict.py +442 -0
  178. scitex/dict/__init__.py +18 -0
  179. scitex/dict/_listed_dict.py +42 -0
  180. scitex/dict/_pop_keys.py +36 -0
  181. scitex/dict/_replace.py +13 -0
  182. scitex/dict/_safe_merge.py +62 -0
  183. scitex/dict/_to_str.py +32 -0
  184. scitex/dsp/__init__.py +72 -0
  185. scitex/dsp/_crop.py +122 -0
  186. scitex/dsp/_demo_sig.py +331 -0
  187. scitex/dsp/_detect_ripples.py +212 -0
  188. scitex/dsp/_ensure_3d.py +18 -0
  189. scitex/dsp/_hilbert.py +78 -0
  190. scitex/dsp/_listen.py +702 -0
  191. scitex/dsp/_misc.py +30 -0
  192. scitex/dsp/_mne.py +32 -0
  193. scitex/dsp/_modulation_index.py +79 -0
  194. scitex/dsp/_pac.py +319 -0
  195. scitex/dsp/_psd.py +102 -0
  196. scitex/dsp/_resample.py +65 -0
  197. scitex/dsp/_time.py +36 -0
  198. scitex/dsp/_transform.py +68 -0
  199. scitex/dsp/_wavelet.py +212 -0
  200. scitex/dsp/add_noise.py +111 -0
  201. scitex/dsp/example.py +253 -0
  202. scitex/dsp/filt.py +155 -0
  203. scitex/dsp/norm.py +18 -0
  204. scitex/dsp/params.py +51 -0
  205. scitex/dsp/reference.py +43 -0
  206. scitex/dsp/template.py +25 -0
  207. scitex/dsp/utils/__init__.py +15 -0
  208. scitex/dsp/utils/_differential_bandpass_filters.py +120 -0
  209. scitex/dsp/utils/_ensure_3d.py +18 -0
  210. scitex/dsp/utils/_ensure_even_len.py +10 -0
  211. scitex/dsp/utils/_zero_pad.py +48 -0
  212. scitex/dsp/utils/filter.py +408 -0
  213. scitex/dsp/utils/pac.py +177 -0
  214. scitex/dt/__init__.py +8 -0
  215. scitex/dt/_linspace.py +130 -0
  216. scitex/etc/__init__.py +15 -0
  217. scitex/etc/wait_key.py +34 -0
  218. scitex/gen/_DimHandler.py +196 -0
  219. scitex/gen/_TimeStamper.py +244 -0
  220. scitex/gen/__init__.py +95 -0
  221. scitex/gen/_alternate_kwarg.py +13 -0
  222. scitex/gen/_cache.py +11 -0
  223. scitex/gen/_check_host.py +34 -0
  224. scitex/gen/_ci.py +12 -0
  225. scitex/gen/_close.py +222 -0
  226. scitex/gen/_embed.py +78 -0
  227. scitex/gen/_inspect_module.py +257 -0
  228. scitex/gen/_is_ipython.py +12 -0
  229. scitex/gen/_less.py +48 -0
  230. scitex/gen/_list_packages.py +139 -0
  231. scitex/gen/_mat2py.py +88 -0
  232. scitex/gen/_norm.py +170 -0
  233. scitex/gen/_paste.py +18 -0
  234. scitex/gen/_print_config.py +84 -0
  235. scitex/gen/_shell.py +48 -0
  236. scitex/gen/_src.py +111 -0
  237. scitex/gen/_start.py +451 -0
  238. scitex/gen/_symlink.py +55 -0
  239. scitex/gen/_symlog.py +27 -0
  240. scitex/gen/_tee.py +238 -0
  241. scitex/gen/_title2path.py +60 -0
  242. scitex/gen/_title_case.py +88 -0
  243. scitex/gen/_to_even.py +84 -0
  244. scitex/gen/_to_odd.py +34 -0
  245. scitex/gen/_to_rank.py +39 -0
  246. scitex/gen/_transpose.py +37 -0
  247. scitex/gen/_type.py +78 -0
  248. scitex/gen/_var_info.py +73 -0
  249. scitex/gen/_wrap.py +17 -0
  250. scitex/gen/_xml2dict.py +76 -0
  251. scitex/gen/misc.py +730 -0
  252. scitex/gen/path.py +0 -0
  253. scitex/general/__init__.py +5 -0
  254. scitex/gists/_SigMacro_processFigure_S.py +128 -0
  255. scitex/gists/_SigMacro_toBlue.py +172 -0
  256. scitex/gists/__init__.py +12 -0
  257. scitex/io/_H5Explorer.py +292 -0
  258. scitex/io/__init__.py +82 -0
  259. scitex/io/_cache.py +101 -0
  260. scitex/io/_flush.py +24 -0
  261. scitex/io/_glob.py +103 -0
  262. scitex/io/_json2md.py +113 -0
  263. scitex/io/_load.py +168 -0
  264. scitex/io/_load_configs.py +146 -0
  265. scitex/io/_load_modules/__init__.py +38 -0
  266. scitex/io/_load_modules/_catboost.py +66 -0
  267. scitex/io/_load_modules/_con.py +20 -0
  268. scitex/io/_load_modules/_db.py +24 -0
  269. scitex/io/_load_modules/_docx.py +42 -0
  270. scitex/io/_load_modules/_eeg.py +110 -0
  271. scitex/io/_load_modules/_hdf5.py +196 -0
  272. scitex/io/_load_modules/_image.py +19 -0
  273. scitex/io/_load_modules/_joblib.py +19 -0
  274. scitex/io/_load_modules/_json.py +18 -0
  275. scitex/io/_load_modules/_markdown.py +103 -0
  276. scitex/io/_load_modules/_matlab.py +37 -0
  277. scitex/io/_load_modules/_numpy.py +39 -0
  278. scitex/io/_load_modules/_optuna.py +155 -0
  279. scitex/io/_load_modules/_pandas.py +69 -0
  280. scitex/io/_load_modules/_pdf.py +31 -0
  281. scitex/io/_load_modules/_pickle.py +24 -0
  282. scitex/io/_load_modules/_torch.py +16 -0
  283. scitex/io/_load_modules/_txt.py +126 -0
  284. scitex/io/_load_modules/_xml.py +49 -0
  285. scitex/io/_load_modules/_yaml.py +23 -0
  286. scitex/io/_mv_to_tmp.py +19 -0
  287. scitex/io/_path.py +286 -0
  288. scitex/io/_reload.py +78 -0
  289. scitex/io/_save.py +539 -0
  290. scitex/io/_save_modules/__init__.py +66 -0
  291. scitex/io/_save_modules/_catboost.py +22 -0
  292. scitex/io/_save_modules/_csv.py +89 -0
  293. scitex/io/_save_modules/_excel.py +49 -0
  294. scitex/io/_save_modules/_hdf5.py +249 -0
  295. scitex/io/_save_modules/_html.py +48 -0
  296. scitex/io/_save_modules/_image.py +140 -0
  297. scitex/io/_save_modules/_joblib.py +25 -0
  298. scitex/io/_save_modules/_json.py +25 -0
  299. scitex/io/_save_modules/_listed_dfs_as_csv.py +57 -0
  300. scitex/io/_save_modules/_listed_scalars_as_csv.py +42 -0
  301. scitex/io/_save_modules/_matlab.py +24 -0
  302. scitex/io/_save_modules/_mp4.py +29 -0
  303. scitex/io/_save_modules/_numpy.py +57 -0
  304. scitex/io/_save_modules/_optuna_study_as_csv_and_pngs.py +38 -0
  305. scitex/io/_save_modules/_pickle.py +45 -0
  306. scitex/io/_save_modules/_plotly.py +27 -0
  307. scitex/io/_save_modules/_text.py +23 -0
  308. scitex/io/_save_modules/_torch.py +26 -0
  309. scitex/io/_save_modules/_yaml.py +29 -0
  310. scitex/life/__init__.py +10 -0
  311. scitex/life/_monitor_rain.py +49 -0
  312. scitex/linalg/__init__.py +17 -0
  313. scitex/linalg/_distance.py +63 -0
  314. scitex/linalg/_geometric_median.py +64 -0
  315. scitex/linalg/_misc.py +73 -0
  316. scitex/nn/_AxiswiseDropout.py +27 -0
  317. scitex/nn/_BNet.py +126 -0
  318. scitex/nn/_BNet_Res.py +164 -0
  319. scitex/nn/_ChannelGainChanger.py +44 -0
  320. scitex/nn/_DropoutChannels.py +50 -0
  321. scitex/nn/_Filters.py +489 -0
  322. scitex/nn/_FreqGainChanger.py +110 -0
  323. scitex/nn/_GaussianFilter.py +48 -0
  324. scitex/nn/_Hilbert.py +111 -0
  325. scitex/nn/_MNet_1000.py +157 -0
  326. scitex/nn/_ModulationIndex.py +221 -0
  327. scitex/nn/_PAC.py +414 -0
  328. scitex/nn/_PSD.py +40 -0
  329. scitex/nn/_ResNet1D.py +120 -0
  330. scitex/nn/_SpatialAttention.py +25 -0
  331. scitex/nn/_Spectrogram.py +161 -0
  332. scitex/nn/_SwapChannels.py +50 -0
  333. scitex/nn/_TransposeLayer.py +19 -0
  334. scitex/nn/_Wavelet.py +183 -0
  335. scitex/nn/__init__.py +63 -0
  336. scitex/os/__init__.py +8 -0
  337. scitex/os/_mv.py +50 -0
  338. scitex/parallel/__init__.py +8 -0
  339. scitex/parallel/_run.py +151 -0
  340. scitex/path/__init__.py +33 -0
  341. scitex/path/_clean.py +52 -0
  342. scitex/path/_find.py +108 -0
  343. scitex/path/_get_module_path.py +51 -0
  344. scitex/path/_get_spath.py +35 -0
  345. scitex/path/_getsize.py +18 -0
  346. scitex/path/_increment_version.py +87 -0
  347. scitex/path/_mk_spath.py +51 -0
  348. scitex/path/_path.py +19 -0
  349. scitex/path/_split.py +23 -0
  350. scitex/path/_this_path.py +19 -0
  351. scitex/path/_version.py +101 -0
  352. scitex/pd/__init__.py +41 -0
  353. scitex/pd/_find_indi.py +126 -0
  354. scitex/pd/_find_pval.py +113 -0
  355. scitex/pd/_force_df.py +154 -0
  356. scitex/pd/_from_xyz.py +71 -0
  357. scitex/pd/_ignore_SettingWithCopyWarning.py +34 -0
  358. scitex/pd/_melt_cols.py +81 -0
  359. scitex/pd/_merge_columns.py +221 -0
  360. scitex/pd/_mv.py +63 -0
  361. scitex/pd/_replace.py +62 -0
  362. scitex/pd/_round.py +93 -0
  363. scitex/pd/_slice.py +63 -0
  364. scitex/pd/_sort.py +91 -0
  365. scitex/pd/_to_numeric.py +53 -0
  366. scitex/pd/_to_xy.py +59 -0
  367. scitex/pd/_to_xyz.py +110 -0
  368. scitex/plt/__init__.py +36 -0
  369. scitex/plt/_subplots/_AxesWrapper.py +182 -0
  370. scitex/plt/_subplots/_AxisWrapper.py +249 -0
  371. scitex/plt/_subplots/_AxisWrapperMixins/_AdjustmentMixin.py +414 -0
  372. scitex/plt/_subplots/_AxisWrapperMixins/_MatplotlibPlotMixin.py +896 -0
  373. scitex/plt/_subplots/_AxisWrapperMixins/_SeabornMixin.py +368 -0
  374. scitex/plt/_subplots/_AxisWrapperMixins/_TrackingMixin.py +185 -0
  375. scitex/plt/_subplots/_AxisWrapperMixins/__init__.py +16 -0
  376. scitex/plt/_subplots/_FigWrapper.py +226 -0
  377. scitex/plt/_subplots/_SubplotsWrapper.py +171 -0
  378. scitex/plt/_subplots/__init__.py +111 -0
  379. scitex/plt/_subplots/_export_as_csv.py +232 -0
  380. scitex/plt/_subplots/_export_as_csv_formatters/__init__.py +61 -0
  381. scitex/plt/_subplots/_export_as_csv_formatters/_format_bar.py +90 -0
  382. scitex/plt/_subplots/_export_as_csv_formatters/_format_barh.py +49 -0
  383. scitex/plt/_subplots/_export_as_csv_formatters/_format_boxplot.py +46 -0
  384. scitex/plt/_subplots/_export_as_csv_formatters/_format_contour.py +39 -0
  385. scitex/plt/_subplots/_export_as_csv_formatters/_format_errorbar.py +125 -0
  386. scitex/plt/_subplots/_export_as_csv_formatters/_format_eventplot.py +72 -0
  387. scitex/plt/_subplots/_export_as_csv_formatters/_format_fill.py +34 -0
  388. scitex/plt/_subplots/_export_as_csv_formatters/_format_fill_between.py +36 -0
  389. scitex/plt/_subplots/_export_as_csv_formatters/_format_hist.py +79 -0
  390. scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow.py +59 -0
  391. scitex/plt/_subplots/_export_as_csv_formatters/_format_imshow2d.py +32 -0
  392. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot.py +79 -0
  393. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_box.py +75 -0
  394. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_conf_mat.py +64 -0
  395. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_ecdf.py +44 -0
  396. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_fillv.py +70 -0
  397. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_heatmap.py +66 -0
  398. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_image.py +95 -0
  399. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_joyplot.py +67 -0
  400. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_kde.py +52 -0
  401. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_line.py +46 -0
  402. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_mean_ci.py +46 -0
  403. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_mean_std.py +46 -0
  404. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_median_iqr.py +46 -0
  405. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_raster.py +44 -0
  406. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_rectangle.py +103 -0
  407. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_scatter_hist.py +82 -0
  408. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_shaded_line.py +58 -0
  409. scitex/plt/_subplots/_export_as_csv_formatters/_format_plot_violin.py +117 -0
  410. scitex/plt/_subplots/_export_as_csv_formatters/_format_scatter.py +30 -0
  411. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_barplot.py +51 -0
  412. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_boxplot.py +93 -0
  413. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_heatmap.py +94 -0
  414. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_histplot.py +92 -0
  415. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_jointplot.py +65 -0
  416. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_kdeplot.py +59 -0
  417. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_lineplot.py +58 -0
  418. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_pairplot.py +45 -0
  419. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_scatterplot.py +70 -0
  420. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_stripplot.py +75 -0
  421. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_swarmplot.py +75 -0
  422. scitex/plt/_subplots/_export_as_csv_formatters/_format_sns_violinplot.py +155 -0
  423. scitex/plt/_subplots/_export_as_csv_formatters/_format_violin.py +64 -0
  424. scitex/plt/_subplots/_export_as_csv_formatters/_format_violinplot.py +77 -0
  425. scitex/plt/_subplots/_export_as_csv_formatters/test_formatters.py +210 -0
  426. scitex/plt/_subplots/_export_as_csv_formatters/verify_formatters.py +342 -0
  427. scitex/plt/_subplots/_export_as_csv_formatters.py +115 -0
  428. scitex/plt/_tpl.py +28 -0
  429. scitex/plt/ax/__init__.py +114 -0
  430. scitex/plt/ax/_plot/__init__.py +53 -0
  431. scitex/plt/ax/_plot/_plot_circular_hist.py +124 -0
  432. scitex/plt/ax/_plot/_plot_conf_mat.py +136 -0
  433. scitex/plt/ax/_plot/_plot_cube.py +57 -0
  434. scitex/plt/ax/_plot/_plot_ecdf.py +84 -0
  435. scitex/plt/ax/_plot/_plot_fillv.py +55 -0
  436. scitex/plt/ax/_plot/_plot_heatmap.py +266 -0
  437. scitex/plt/ax/_plot/_plot_image.py +94 -0
  438. scitex/plt/ax/_plot/_plot_joyplot.py +76 -0
  439. scitex/plt/ax/_plot/_plot_raster.py +172 -0
  440. scitex/plt/ax/_plot/_plot_rectangle.py +69 -0
  441. scitex/plt/ax/_plot/_plot_scatter_hist.py +133 -0
  442. scitex/plt/ax/_plot/_plot_shaded_line.py +142 -0
  443. scitex/plt/ax/_plot/_plot_statistical_shaded_line.py +221 -0
  444. scitex/plt/ax/_plot/_plot_violin.py +343 -0
  445. scitex/plt/ax/_style/__init__.py +38 -0
  446. scitex/plt/ax/_style/_add_marginal_ax.py +44 -0
  447. scitex/plt/ax/_style/_add_panel.py +92 -0
  448. scitex/plt/ax/_style/_extend.py +64 -0
  449. scitex/plt/ax/_style/_force_aspect.py +37 -0
  450. scitex/plt/ax/_style/_format_label.py +23 -0
  451. scitex/plt/ax/_style/_hide_spines.py +84 -0
  452. scitex/plt/ax/_style/_map_ticks.py +182 -0
  453. scitex/plt/ax/_style/_rotate_labels.py +215 -0
  454. scitex/plt/ax/_style/_sci_note.py +279 -0
  455. scitex/plt/ax/_style/_set_log_scale.py +299 -0
  456. scitex/plt/ax/_style/_set_meta.py +261 -0
  457. scitex/plt/ax/_style/_set_n_ticks.py +37 -0
  458. scitex/plt/ax/_style/_set_size.py +16 -0
  459. scitex/plt/ax/_style/_set_supxyt.py +116 -0
  460. scitex/plt/ax/_style/_set_ticks.py +276 -0
  461. scitex/plt/ax/_style/_set_xyt.py +121 -0
  462. scitex/plt/ax/_style/_share_axes.py +264 -0
  463. scitex/plt/ax/_style/_shift.py +139 -0
  464. scitex/plt/ax/_style/_show_spines.py +333 -0
  465. scitex/plt/color/_PARAMS.py +70 -0
  466. scitex/plt/color/__init__.py +52 -0
  467. scitex/plt/color/_add_hue_col.py +41 -0
  468. scitex/plt/color/_colors.py +205 -0
  469. scitex/plt/color/_get_colors_from_cmap.py +134 -0
  470. scitex/plt/color/_interpolate.py +29 -0
  471. scitex/plt/color/_vizualize_colors.py +54 -0
  472. scitex/plt/utils/__init__.py +44 -0
  473. scitex/plt/utils/_calc_bacc_from_conf_mat.py +46 -0
  474. scitex/plt/utils/_calc_nice_ticks.py +101 -0
  475. scitex/plt/utils/_close.py +68 -0
  476. scitex/plt/utils/_colorbar.py +96 -0
  477. scitex/plt/utils/_configure_mpl.py +295 -0
  478. scitex/plt/utils/_histogram_utils.py +132 -0
  479. scitex/plt/utils/_im2grid.py +70 -0
  480. scitex/plt/utils/_is_valid_axis.py +78 -0
  481. scitex/plt/utils/_mk_colorbar.py +65 -0
  482. scitex/plt/utils/_mk_patches.py +26 -0
  483. scitex/plt/utils/_scientific_captions.py +638 -0
  484. scitex/plt/utils/_scitex_config.py +223 -0
  485. scitex/reproduce/__init__.py +14 -0
  486. scitex/reproduce/_fix_seeds.py +45 -0
  487. scitex/reproduce/_gen_ID.py +55 -0
  488. scitex/reproduce/_gen_timestamp.py +35 -0
  489. scitex/res/__init__.py +5 -0
  490. scitex/resource/__init__.py +13 -0
  491. scitex/resource/_get_processor_usages.py +281 -0
  492. scitex/resource/_get_specs.py +280 -0
  493. scitex/resource/_log_processor_usages.py +190 -0
  494. scitex/resource/_utils/__init__.py +31 -0
  495. scitex/resource/_utils/_get_env_info.py +481 -0
  496. scitex/resource/limit_ram.py +33 -0
  497. scitex/scholar/__init__.py +24 -0
  498. scitex/scholar/_local_search.py +454 -0
  499. scitex/scholar/_paper.py +244 -0
  500. scitex/scholar/_pdf_downloader.py +325 -0
  501. scitex/scholar/_search.py +393 -0
  502. scitex/scholar/_vector_search.py +370 -0
  503. scitex/scholar/_web_sources.py +457 -0
  504. scitex/stats/__init__.py +31 -0
  505. scitex/stats/_calc_partial_corr.py +17 -0
  506. scitex/stats/_corr_test_multi.py +94 -0
  507. scitex/stats/_corr_test_wrapper.py +115 -0
  508. scitex/stats/_describe_wrapper.py +90 -0
  509. scitex/stats/_multiple_corrections.py +63 -0
  510. scitex/stats/_nan_stats.py +93 -0
  511. scitex/stats/_p2stars.py +116 -0
  512. scitex/stats/_p2stars_wrapper.py +56 -0
  513. scitex/stats/_statistical_tests.py +73 -0
  514. scitex/stats/desc/__init__.py +40 -0
  515. scitex/stats/desc/_describe.py +189 -0
  516. scitex/stats/desc/_nan.py +289 -0
  517. scitex/stats/desc/_real.py +94 -0
  518. scitex/stats/multiple/__init__.py +14 -0
  519. scitex/stats/multiple/_bonferroni_correction.py +72 -0
  520. scitex/stats/multiple/_fdr_correction.py +400 -0
  521. scitex/stats/multiple/_multicompair.py +28 -0
  522. scitex/stats/tests/__corr_test.py +277 -0
  523. scitex/stats/tests/__corr_test_multi.py +343 -0
  524. scitex/stats/tests/__corr_test_single.py +277 -0
  525. scitex/stats/tests/__init__.py +22 -0
  526. scitex/stats/tests/_brunner_munzel_test.py +192 -0
  527. scitex/stats/tests/_nocorrelation_test.py +28 -0
  528. scitex/stats/tests/_smirnov_grubbs.py +98 -0
  529. scitex/str/__init__.py +113 -0
  530. scitex/str/_clean_path.py +75 -0
  531. scitex/str/_color_text.py +52 -0
  532. scitex/str/_decapitalize.py +58 -0
  533. scitex/str/_factor_out_digits.py +281 -0
  534. scitex/str/_format_plot_text.py +498 -0
  535. scitex/str/_grep.py +48 -0
  536. scitex/str/_latex.py +155 -0
  537. scitex/str/_latex_fallback.py +471 -0
  538. scitex/str/_mask_api.py +39 -0
  539. scitex/str/_mask_api_key.py +8 -0
  540. scitex/str/_parse.py +158 -0
  541. scitex/str/_print_block.py +47 -0
  542. scitex/str/_print_debug.py +68 -0
  543. scitex/str/_printc.py +62 -0
  544. scitex/str/_readable_bytes.py +38 -0
  545. scitex/str/_remove_ansi.py +23 -0
  546. scitex/str/_replace.py +134 -0
  547. scitex/str/_search.py +125 -0
  548. scitex/str/_squeeze_space.py +36 -0
  549. scitex/tex/__init__.py +10 -0
  550. scitex/tex/_preview.py +103 -0
  551. scitex/tex/_to_vec.py +116 -0
  552. scitex/torch/__init__.py +18 -0
  553. scitex/torch/_apply_to.py +34 -0
  554. scitex/torch/_nan_funcs.py +77 -0
  555. scitex/types/_ArrayLike.py +44 -0
  556. scitex/types/_ColorLike.py +21 -0
  557. scitex/types/__init__.py +14 -0
  558. scitex/types/_is_listed_X.py +70 -0
  559. scitex/utils/__init__.py +22 -0
  560. scitex/utils/_compress_hdf5.py +116 -0
  561. scitex/utils/_email.py +120 -0
  562. scitex/utils/_grid.py +148 -0
  563. scitex/utils/_notify.py +247 -0
  564. scitex/utils/_search.py +121 -0
  565. scitex/web/__init__.py +38 -0
  566. scitex/web/_search_pubmed.py +438 -0
  567. scitex/web/_summarize_url.py +158 -0
  568. scitex-2.0.0.dist-info/METADATA +307 -0
  569. scitex-2.0.0.dist-info/RECORD +572 -0
  570. scitex-2.0.0.dist-info/WHEEL +6 -0
  571. scitex-2.0.0.dist-info/licenses/LICENSE +7 -0
  572. scitex-2.0.0.dist-info/top_level.txt +1 -0
@@ -0,0 +1,166 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Time-stamp: "2024-11-24 23:06:03 (ywatanabe)"
4
+ # File: ./scitex_repo/src/scitex/db/_PostgreSQLMixins/_BackupMixin.py
5
+
6
+ THIS_FILE = (
7
+ "/home/ywatanabe/proj/scitex_repo/src/scitex/db/_PostgreSQLMixins/_BackupMixin.py"
8
+ )
9
+
10
+ import subprocess
11
+ import os
12
+ from typing import Optional, List
13
+ from .._BaseMixins._BaseBackupMixin import _BaseBackupMixin
14
+
15
+
16
+ class _BackupMixin(_BaseBackupMixin):
17
+ def backup_table(self, table: str, file_path: str) -> None:
18
+ """Backup a specific table using pg_dump"""
19
+ connection_params = self._get_connection_params()
20
+ cmd = [
21
+ "pg_dump",
22
+ "-h",
23
+ connection_params["host"],
24
+ "-p",
25
+ str(connection_params["port"]),
26
+ "-U",
27
+ connection_params["user"],
28
+ "-d",
29
+ connection_params["database"],
30
+ "-t",
31
+ table,
32
+ "-f",
33
+ file_path,
34
+ ]
35
+
36
+ env = os.environ.copy()
37
+ env["PGPASSWORD"] = connection_params["password"]
38
+
39
+ try:
40
+ subprocess.run(cmd, env=env, check=True, capture_output=True)
41
+ except subprocess.CalledProcessError as e:
42
+ raise Exception(f"Backup failed: {e.stderr.decode()}")
43
+
44
+ def restore_table(self, table: str, file_path: str) -> None:
45
+ """Restore a specific table from backup"""
46
+ self._check_writable()
47
+ connection_params = self._get_connection_params()
48
+ cmd = [
49
+ "psql",
50
+ "-h",
51
+ connection_params["host"],
52
+ "-p",
53
+ str(connection_params["port"]),
54
+ "-U",
55
+ connection_params["user"],
56
+ "-d",
57
+ connection_params["database"],
58
+ "-f",
59
+ file_path,
60
+ ]
61
+
62
+ env = os.environ.copy()
63
+ env["PGPASSWORD"] = connection_params["password"]
64
+
65
+ try:
66
+ subprocess.run(cmd, env=env, check=True, capture_output=True)
67
+ except subprocess.CalledProcessError as e:
68
+ raise Exception(f"Restore failed: {e.stderr.decode()}")
69
+
70
+ def backup_database(self, file_path: str) -> None:
71
+ """Backup entire database using pg_dump"""
72
+ connection_params = self._get_connection_params()
73
+ cmd = [
74
+ "pg_dump",
75
+ "-h",
76
+ connection_params["host"],
77
+ "-p",
78
+ str(connection_params["port"]),
79
+ "-U",
80
+ connection_params["user"],
81
+ "-d",
82
+ connection_params["database"],
83
+ "-F",
84
+ "c", # Custom format
85
+ "-f",
86
+ file_path,
87
+ ]
88
+
89
+ env = os.environ.copy()
90
+ env["PGPASSWORD"] = connection_params["password"]
91
+
92
+ try:
93
+ subprocess.run(cmd, env=env, check=True, capture_output=True)
94
+ except subprocess.CalledProcessError as e:
95
+ raise Exception(f"Database backup failed: {e.stderr.decode()}")
96
+
97
+ def restore_database(self, file_path: str) -> None:
98
+ """Restore entire database from backup"""
99
+ self._check_writable()
100
+ connection_params = self._get_connection_params()
101
+ cmd = [
102
+ "pg_restore",
103
+ "-h",
104
+ connection_params["host"],
105
+ "-p",
106
+ str(connection_params["port"]),
107
+ "-U",
108
+ connection_params["user"],
109
+ "-d",
110
+ connection_params["database"],
111
+ "--clean", # Clean (drop) database objects before recreating
112
+ file_path,
113
+ ]
114
+
115
+ env = os.environ.copy()
116
+ env["PGPASSWORD"] = connection_params["password"]
117
+
118
+ try:
119
+ subprocess.run(cmd, env=env, check=True, capture_output=True)
120
+ except subprocess.CalledProcessError as e:
121
+ raise Exception(f"Database restore failed: {e.stderr.decode()}")
122
+
123
+ def copy_table(
124
+ self, source_table: str, target_table: str, where: Optional[str] = None
125
+ ) -> None:
126
+ """Copy data from one table to another"""
127
+ self._check_writable()
128
+
129
+ # Get column names from source table
130
+ self.execute(
131
+ f"""
132
+ SELECT column_name
133
+ FROM information_schema.columns
134
+ WHERE table_name = %s
135
+ ORDER BY ordinal_position
136
+ """,
137
+ (source_table,),
138
+ )
139
+ columns: List[str] = [row[0] for row in self.cursor.fetchall()]
140
+ columns_str = ", ".join(columns)
141
+
142
+ # Create the target table with the same structure
143
+ self.execute(
144
+ f"CREATE TABLE IF NOT EXISTS {target_table} AS SELECT * FROM {source_table} WHERE 1=0"
145
+ )
146
+
147
+ # Copy data
148
+ query = f"INSERT INTO {target_table} ({columns_str}) SELECT {columns_str} FROM {source_table}"
149
+ if where:
150
+ query += f" WHERE {where}"
151
+
152
+ self.execute(query)
153
+
154
+ def _get_connection_params(self) -> dict:
155
+ """Extract connection parameters from the current connection"""
156
+ dsn = self.conn.get_dsn_parameters()
157
+ return {
158
+ "host": dsn.get("host", "localhost"),
159
+ "port": dsn.get("port", 5432),
160
+ "user": dsn.get("user", ""),
161
+ "password": dsn.get("password", ""),
162
+ "database": dsn.get("dbname", ""),
163
+ }
164
+
165
+
166
+ # EOF
@@ -0,0 +1,82 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Timestamp: "2025-02-27 22:14:16 (ywatanabe)"
4
+ # File: /home/ywatanabe/proj/scitex_dev/src/scitex/db/_PostgreSQLMixins/_BatchMixin.py
5
+
6
+ THIS_FILE = (
7
+ "/home/ywatanabe/proj/scitex_repo/src/scitex/db/_PostgreSQLMixins/_BatchMixin.py"
8
+ )
9
+
10
+ from typing import List, Any, Optional, Dict, Union
11
+ import pandas as pd
12
+ from .._BaseMixins._BaseBatchMixin import _BaseBatchMixin
13
+
14
+
15
+ class _BatchMixin(_BaseBatchMixin):
16
+ def insert_many(
17
+ self,
18
+ table: str,
19
+ records: List[Dict[str, Any]],
20
+ batch_size: Optional[int] = None,
21
+ ) -> None:
22
+ if not records:
23
+ return
24
+
25
+ query = self._prepare_insert_query(table, records[0])
26
+ if batch_size and batch_size > 0:
27
+ for i in range(0, len(records), batch_size):
28
+ batch = records[i : i + batch_size]
29
+ parameters = self._prepare_batch_parameters(batch)
30
+ self.executemany(query, parameters)
31
+ else:
32
+ parameters = self._prepare_batch_parameters(records)
33
+ self.executemany(query, parameters)
34
+
35
+ def _prepare_insert_query(self, table: str, record: Dict[str, Any]) -> str:
36
+ columns = list(record.keys())
37
+ placeholders = ["%s"] * len(columns)
38
+ columns_str = ", ".join(columns)
39
+ placeholders_str = ", ".join(placeholders)
40
+ return f"INSERT INTO {table} ({columns_str}) VALUES ({placeholders_str})"
41
+
42
+ def _prepare_batch_parameters(self, records: List[Dict[str, Any]]) -> List[tuple]:
43
+ if not records:
44
+ return []
45
+
46
+ columns = list(records[0].keys())
47
+ return [tuple(record[col] for col in columns) for record in records]
48
+
49
+ def dataframe_to_sql(
50
+ self, df: pd.DataFrame, table: str, if_exists: str = "fail"
51
+ ) -> None:
52
+ if if_exists not in ["fail", "replace", "append"]:
53
+ raise ValueError("if_exists must be one of 'fail', 'replace', or 'append'")
54
+
55
+ if if_exists == "replace":
56
+ self.execute(f"DROP TABLE IF EXISTS {table}")
57
+ # Create table based on DataFrame schema
58
+ columns = []
59
+ for col, dtype in df.dtypes.items():
60
+ pg_type = self._map_dtype_to_postgres(dtype)
61
+ columns.append(f"{col} {pg_type}")
62
+ columns_str = ", ".join(columns)
63
+ self.execute(f"CREATE TABLE {table} ({columns_str})")
64
+
65
+ records = df.to_dict("records")
66
+ self.insert_many(table, records)
67
+
68
+ def _map_dtype_to_postgres(self, dtype) -> str:
69
+ dtype_str = str(dtype)
70
+ if "int" in dtype_str:
71
+ return "INTEGER"
72
+ elif "float" in dtype_str:
73
+ return "REAL"
74
+ elif "datetime" in dtype_str:
75
+ return "TIMESTAMP"
76
+ elif "bool" in dtype_str:
77
+ return "BOOLEAN"
78
+ else:
79
+ return "TEXT"
80
+
81
+
82
+ # EOF
@@ -0,0 +1,231 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Timestamp: "2025-02-27 22:14:45 (ywatanabe)"
4
+ # File: /home/ywatanabe/proj/scitex_dev/src/scitex/db/_PostgreSQLMixins/_BlobMixin.py
5
+
6
+ THIS_FILE = "/home/ywatanabe/proj/scitex_repo/src/scitex/db/_PostgreSQLMixins/_BlobMixin.py"
7
+
8
+ import psycopg2
9
+ import numpy as np
10
+ from typing import Any as _Any
11
+ from typing import Dict, List, Optional, Tuple, Union
12
+ from .._BaseMixins._BaseBlobMixin import _BaseBlobMixin
13
+
14
+
15
+ class _BlobMixin(_BaseBlobMixin):
16
+ """BLOB data handling functionality for PostgreSQL"""
17
+
18
+ def save_array(
19
+ self,
20
+ table_name: str,
21
+ data: np.ndarray,
22
+ column: str = "data",
23
+ ids: Optional[Union[int, List[int]]] = None,
24
+ where: str = None,
25
+ additional_columns: Dict[str, _Any] = None,
26
+ batch_size: int = 1000,
27
+ ) -> None:
28
+ with self.transaction():
29
+ if not isinstance(data, (np.ndarray, list)):
30
+ raise ValueError("Input must be a NumPy array or list of arrays")
31
+
32
+ try:
33
+ if ids is not None:
34
+ if isinstance(ids, int):
35
+ ids = [ids]
36
+ data = [data]
37
+ if len(ids) != len(data):
38
+ raise ValueError("Length of ids must match number of arrays")
39
+
40
+ for id_, arr in zip(ids, data):
41
+ if not isinstance(arr, np.ndarray):
42
+ raise ValueError(
43
+ f"Element for id {id_} must be a NumPy array"
44
+ )
45
+
46
+ binary = psycopg2.Binary(arr.tobytes())
47
+ # binary = Binary(arr.tobytes())
48
+ columns = [
49
+ column,
50
+ f"{column}_dtype",
51
+ f"{column}_shape",
52
+ ]
53
+ values = [binary, str(arr.dtype), str(arr.shape)]
54
+
55
+ if additional_columns:
56
+ columns = list(additional_columns.keys()) + columns
57
+ values = list(additional_columns.values()) + values
58
+
59
+ update_cols = [f"{col}=%s" for col in columns]
60
+ query = f"UPDATE {table_name} SET {','.join(update_cols)} WHERE id=%s"
61
+ values.append(id_)
62
+ self.execute(query, values)
63
+
64
+ else:
65
+ if not isinstance(data, np.ndarray):
66
+ raise ValueError("Single input must be a NumPy array")
67
+
68
+ binary = psycopg2.Binary(arr.tobytes())
69
+ # binary = Binary(data.tobytes())
70
+ columns = [column, f"{column}_dtype", f"{column}_shape"]
71
+ values = [binary, str(data.dtype), str(data.shape)]
72
+
73
+ if additional_columns:
74
+ columns = list(additional_columns.keys()) + columns
75
+ values = list(additional_columns.values()) + values
76
+
77
+ if where is not None:
78
+ update_cols = [f"{col}=%s" for col in columns]
79
+ query = f"UPDATE {table_name} SET {','.join(update_cols)} WHERE {where}"
80
+ self.execute(query, values)
81
+ else:
82
+ placeholders = ",".join(["%s" for _ in columns])
83
+ columns_str = ",".join(columns)
84
+ query = f"INSERT INTO {table_name} ({columns_str}) VALUES ({placeholders})"
85
+ self.execute(query, values)
86
+
87
+ except Exception as err:
88
+ raise ValueError(f"Failed to save array: {err}")
89
+
90
+ def load_array(
91
+ self,
92
+ table_name: str,
93
+ column: str,
94
+ ids: Union[int, List[int], str] = "all",
95
+ where: str = None,
96
+ order_by: str = None,
97
+ batch_size: int = 128,
98
+ dtype: np.dtype = None,
99
+ shape: Optional[Tuple] = None,
100
+ ) -> Optional[np.ndarray]:
101
+ try:
102
+ if ids == "all":
103
+ query = f"SELECT id FROM {table_name}"
104
+ if where:
105
+ query += f" WHERE {where}"
106
+ self.execute(query)
107
+ ids = [row[0] for row in self.cursor.fetchall()]
108
+ elif isinstance(ids, int):
109
+ ids = [ids]
110
+
111
+ id_to_data = {}
112
+ unique_ids = list(set(ids))
113
+
114
+ for idx in range(0, len(unique_ids), batch_size):
115
+ batch_ids = unique_ids[idx : idx + batch_size]
116
+ placeholders = ",".join(["%s" for _ in batch_ids])
117
+
118
+ try:
119
+ query = f"""
120
+ SELECT id, {column},
121
+ {column}_dtype,
122
+ {column}_shape
123
+ FROM {table_name}
124
+ WHERE id IN ({placeholders})
125
+ """
126
+ self.execute(query, batch_ids)
127
+ has_metadata = True
128
+ except psycopg2.Error:
129
+ query = f"SELECT id, {column} FROM {table_name} WHERE id IN ({placeholders})"
130
+ self.execute(query, batch_ids)
131
+ has_metadata = False
132
+
133
+ if where:
134
+ query += f" AND {where}"
135
+ if order_by:
136
+ query += f" ORDER BY {order_by}"
137
+
138
+ results = self.cursor.fetchall()
139
+ if results:
140
+ for result in results:
141
+ if has_metadata:
142
+ id_val, blob, dtype_str, shape_str = result
143
+ data = np.frombuffer(
144
+ bytes(blob), dtype=np.dtype(dtype_str)
145
+ ).reshape(eval(shape_str))
146
+ else:
147
+ id_val, blob = result
148
+ data = (
149
+ np.frombuffer(bytes(blob), dtype=dtype)
150
+ if dtype
151
+ else np.frombuffer(bytes(blob))
152
+ )
153
+ if shape:
154
+ data = data.reshape(shape)
155
+ id_to_data[id_val] = data
156
+
157
+ all_data = [id_to_data[id_val] for id_val in ids if id_val in id_to_data]
158
+ return np.stack(all_data, axis=0) if all_data else None
159
+
160
+ except Exception as err:
161
+ raise ValueError(f"Failed to load array: {err}")
162
+
163
+ def binary_to_array(
164
+ self,
165
+ binary_data,
166
+ dtype_str=None,
167
+ shape_str=None,
168
+ dtype=None,
169
+ shape=None,
170
+ ):
171
+ if binary_data is None:
172
+ return None
173
+
174
+ binary_data = bytes(binary_data)
175
+ if dtype_str and shape_str:
176
+ return np.frombuffer(binary_data, dtype=np.dtype(dtype_str)).reshape(
177
+ eval(shape_str)
178
+ )
179
+ elif dtype and shape:
180
+ return np.frombuffer(binary_data, dtype=dtype).reshape(shape)
181
+ return binary_data
182
+
183
+ def get_array_dict(self, df, columns=None, dtype=None, shape=None):
184
+ result = {}
185
+ if columns is None:
186
+ columns = [
187
+ col
188
+ for col in df.columns
189
+ if not (col.endswith("_dtype") or col.endswith("_shape"))
190
+ ]
191
+
192
+ for col in columns:
193
+ if f"{col}_dtype" in df.columns and f"{col}_shape" in df.columns:
194
+ arrays = [
195
+ self.binary_to_array(
196
+ row[col], row[f"{col}_dtype"], row[f"{col}_shape"]
197
+ )
198
+ for _, row in df.iterrows()
199
+ ]
200
+ elif dtype and shape:
201
+ arrays = [
202
+ self.binary_to_array(x, dtype=dtype, shape=shape) for x in df[col]
203
+ ]
204
+ result[col] = np.stack(arrays)
205
+
206
+ return result
207
+
208
+ def decode_array_columns(self, df, columns=None, dtype=None, shape=None):
209
+ if columns is None:
210
+ columns = [
211
+ col
212
+ for col in df.columns
213
+ if not (col.endswith("_dtype") or col.endswith("_shape"))
214
+ ]
215
+
216
+ for col in columns:
217
+ if f"{col}_dtype" in df.columns and f"{col}_shape" in df.columns:
218
+ df[col] = df.apply(
219
+ lambda row: self.binary_to_array(
220
+ row[col], row[f"{col}_dtype"], row[f"{col}_shape"]
221
+ ),
222
+ axis=1,
223
+ )
224
+ elif dtype and shape:
225
+ df[col] = df[col].apply(
226
+ lambda x: self.binary_to_array(x, dtype=dtype, shape=shape)
227
+ )
228
+ return df
229
+
230
+
231
+ # EOF
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Timestamp: "2025-02-27 22:14:52 (ywatanabe)"
4
+ # File: /home/ywatanabe/proj/scitex_dev/src/scitex/db/_PostgreSQLMixins/_ConnectionMixin.py
5
+
6
+ THIS_FILE = (
7
+ "/home/ywatanabe/proj/scitex_repo/src/scitex/db/_PostgreSQLMixins/_ConnectionMixin.py"
8
+ )
9
+
10
+ from typing import Any, Tuple
11
+ import psycopg2
12
+
13
+ from .._BaseMixins._BaseConnectionMixin import _BaseConnectionMixin
14
+
15
+
16
+ class _ConnectionMixin(_BaseConnectionMixin):
17
+ def __init__(
18
+ self,
19
+ dbname: str,
20
+ user: str,
21
+ password: str,
22
+ host: str = "localhost",
23
+ port: int = 5432,
24
+ ):
25
+ super().__init__()
26
+ self.db_config = {
27
+ "dbname": dbname,
28
+ "user": user,
29
+ "password": password,
30
+ "host": host,
31
+ "port": port,
32
+ }
33
+ if dbname:
34
+ self.connect()
35
+
36
+ def connect(self) -> None:
37
+ if self.conn:
38
+ self.close()
39
+
40
+ self.conn = psycopg2.connect(**self.db_config)
41
+ self.cursor = self.conn.cursor()
42
+
43
+ with self.lock:
44
+ self.conn.autocommit = False
45
+ self.cursor.execute(
46
+ "SET SESSION CHARACTERISTICS AS TRANSACTION ISOLATION LEVEL READ COMMITTED"
47
+ )
48
+
49
+ def close(self) -> None:
50
+ if self.cursor:
51
+ self.cursor.close()
52
+ if self.conn:
53
+ try:
54
+ self.conn.close()
55
+ except psycopg2.Error:
56
+ pass
57
+ self.cursor = None
58
+ self.conn = None
59
+
60
+ def reconnect(self) -> None:
61
+ if self.db_config:
62
+ self.connect()
63
+ else:
64
+ raise ValueError("No database configuration specified for reconnection")
65
+
66
+ def execute(self, query: str, parameters: Tuple = None) -> Any:
67
+ """Execute a database query."""
68
+ if not self.cursor:
69
+ raise ConnectionError("Database not connected")
70
+
71
+ try:
72
+ self.cursor.execute(query, parameters)
73
+ self.conn.commit()
74
+ return self.cursor
75
+ except psycopg2.Error as err:
76
+ self.conn.rollback()
77
+ raise psycopg2.Error(f"Query execution failed: {err}")
78
+
79
+ def executemany(self, query: str, parameters: list) -> None:
80
+ """Execute multiple database queries."""
81
+ if not self.cursor:
82
+ raise ConnectionError("Database not connected")
83
+
84
+ try:
85
+ self.cursor.executemany(query, parameters)
86
+ self.conn.commit()
87
+ except psycopg2.Error as err:
88
+ self.conn.rollback()
89
+ raise psycopg2.Error(f"Batch query execution failed: {err}")
90
+
91
+
92
+ # EOF
@@ -0,0 +1,59 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Timestamp: "2025-02-27 22:14:59 (ywatanabe)"
4
+ # File: /home/ywatanabe/proj/scitex_dev/src/scitex/db/_PostgreSQLMixins/_ImportExportMixin.py
5
+
6
+ THIS_FILE = (
7
+ "/home/ywatanabe/proj/scitex_repo/src/scitex/db/_PostgreSQLMixins/_ImportExportMixin.py"
8
+ )
9
+
10
+ import pandas as pd
11
+ from typing import List
12
+ import psycopg2
13
+ from io import StringIO
14
+
15
+
16
+ class _ImportExportMixin:
17
+ def load_from_csv(
18
+ self,
19
+ table_name: str,
20
+ csv_path: str,
21
+ if_exists: str = "append",
22
+ batch_size: int = 10_000,
23
+ chunk_size: int = 100_000,
24
+ ) -> None:
25
+ with self.transaction():
26
+ try:
27
+ if if_exists == "replace":
28
+ self.execute(f"TRUNCATE TABLE {table_name}")
29
+
30
+ copy_sql = f"COPY {table_name} FROM STDIN WITH CSV HEADER"
31
+ with open(csv_path, "r") as f:
32
+ self.cursor.copy_expert(sql=copy_sql, file=f)
33
+
34
+ except (Exception, psycopg2.Error) as err:
35
+ raise ValueError(f"Failed to import from CSV: {err}")
36
+
37
+ def save_to_csv(
38
+ self,
39
+ table_name: str,
40
+ output_path: str,
41
+ columns: List[str] = ["*"],
42
+ where: str = None,
43
+ batch_size: int = 10_000,
44
+ ) -> None:
45
+ try:
46
+ columns_str = ", ".join(columns) if columns != ["*"] else "*"
47
+ query = f"COPY (SELECT {columns_str} FROM {table_name}"
48
+ if where:
49
+ query += f" WHERE {where}"
50
+ query += ") TO STDOUT WITH CSV HEADER"
51
+
52
+ with open(output_path, "w") as f:
53
+ self.cursor.copy_expert(sql=query, file=f)
54
+
55
+ except (Exception, psycopg2.Error) as err:
56
+ raise ValueError(f"Failed to export to CSV: {err}")
57
+
58
+
59
+ # EOF
@@ -0,0 +1,64 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Timestamp: "2025-02-27 22:15:05 (ywatanabe)"
4
+ # File: /home/ywatanabe/proj/scitex_dev/src/scitex/db/_PostgreSQLMixins/_IndexMixin.py
5
+
6
+ THIS_FILE = (
7
+ "/home/ywatanabe/proj/scitex_repo/src/scitex/db/_PostgreSQLMixins/_IndexMixin.py"
8
+ )
9
+
10
+ from typing import List
11
+ import psycopg2
12
+
13
+
14
+ class _IndexMixin:
15
+ def create_index(
16
+ self,
17
+ table_name: str,
18
+ column_names: List[str],
19
+ index_name: str = None,
20
+ unique: bool = False,
21
+ ) -> None:
22
+ try:
23
+ if index_name is None:
24
+ index_name = f"idx_{table_name}_{'_'.join(column_names)}"
25
+
26
+ unique_clause = "UNIQUE" if unique else ""
27
+ columns_str = ", ".join(column_names)
28
+
29
+ query = f"""
30
+ CREATE {unique_clause} INDEX IF NOT EXISTS {index_name}
31
+ ON {table_name} ({columns_str})
32
+ """
33
+ self.execute(query)
34
+
35
+ except (Exception, psycopg2.Error) as err:
36
+ raise ValueError(f"Failed to create index: {err}")
37
+
38
+ def drop_index(self, index_name: str) -> None:
39
+ try:
40
+ self.execute(f"DROP INDEX IF EXISTS {index_name}")
41
+ except (Exception, psycopg2.Error) as err:
42
+ raise ValueError(f"Failed to drop index: {err}")
43
+
44
+ def get_indexes(self, table_name: str = None) -> List[dict]:
45
+ try:
46
+ query = """
47
+ SELECT
48
+ schemaname,
49
+ tablename,
50
+ indexname,
51
+ indexdef
52
+ FROM
53
+ pg_indexes
54
+ """
55
+ if table_name:
56
+ query += f" WHERE tablename = '{table_name}'"
57
+
58
+ return self.execute(query).fetchall()
59
+
60
+ except (Exception, psycopg2.Error) as err:
61
+ raise ValueError(f"Failed to get indexes: {err}")
62
+
63
+
64
+ # EOF