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,243 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Time-stamp: "2024-11-29 04:36:14 (ywatanabe)"
4
+ # File: ./scitex_repo/src/scitex/db/_SQLite3Mixins/_BatchMixin.py
5
+
6
+ THIS_FILE = "/home/ywatanabe/proj/scitex_repo/src/scitex/db/_SQLite3Mixins/_BatchMixin.py"
7
+
8
+ """
9
+ Functionality:
10
+ * Provides batch database operations for SQLite3
11
+ * Handles batch inserts, updates, replacements with transaction safety
12
+ * Supports foreign key inheritance and where clause filtering
13
+
14
+ Input:
15
+ * Table name, row data as dictionaries, and operation parameters
16
+ * Support for batch size control and conditional operations
17
+
18
+ Output:
19
+ * None, but executes database operations with transaction safety
20
+
21
+ Prerequisites:
22
+ * SQLite3 database connection
23
+ * Table schema must exist
24
+ * Foreign key constraints must be enabled if using inherit_foreign
25
+ """
26
+
27
+ from typing import Any as _Any
28
+ from typing import Dict, List, Optional
29
+ from .._BaseMixins._BaseBatchMixin import _BaseBatchMixin
30
+ import sqlite3
31
+
32
+
33
+ class _BatchMixin:
34
+ """Batch operations functionality"""
35
+
36
+ def _run_many(
37
+ self,
38
+ sql_command,
39
+ table_name: str,
40
+ rows: List[Dict[str, _Any]],
41
+ batch_size: int = 1000,
42
+ inherit_foreign: bool = True,
43
+ where: Optional[str] = None,
44
+ columns: Optional[List[str]] = None,
45
+ ) -> None:
46
+ try:
47
+ if batch_size <= 0:
48
+ raise ValueError("Batch size must be positive")
49
+
50
+ table_name = f'"{table_name.replace("`", "``")}"'
51
+
52
+ # Validate table exists and get schema
53
+ schema = self.get_table_schema(table_name)
54
+ table_columns = set(schema["name"])
55
+
56
+ # Replace the problematic code block with:
57
+ if columns:
58
+ valid_columns = [
59
+ col
60
+ for col in columns
61
+ if col in table_columns and col.isidentifier()
62
+ ]
63
+ else:
64
+ valid_columns = [
65
+ col
66
+ for col in rows[0].keys()
67
+ if col in table_columns and col.isidentifier()
68
+ ]
69
+
70
+ if not valid_columns:
71
+ raise ValueError("No valid columns found")
72
+
73
+ if not table_name or not isinstance(table_name, str):
74
+ raise ValueError("Invalid table name")
75
+ if not isinstance(rows, list):
76
+ raise ValueError("Rows must be a list of dictionaries")
77
+ if rows and not all(isinstance(row, dict) for row in rows):
78
+ raise ValueError("All rows must be dictionaries")
79
+
80
+ # Validate table exists
81
+ self.execute(f"SELECT 1 FROM {table_name} LIMIT 1")
82
+
83
+ assert sql_command.upper() in [
84
+ "INSERT",
85
+ "REPLACE",
86
+ "INSERT OR REPLACE",
87
+ "UPDATE",
88
+ ]
89
+
90
+ if not rows:
91
+ return
92
+
93
+ if sql_command.upper() == "UPDATE":
94
+ valid_columns = columns if columns else [col for col in rows[0].keys()]
95
+ set_clause = ",".join([f"{col}=?" for col in valid_columns])
96
+ where_clause = where if where else "1=1"
97
+
98
+ # Modified query construction
99
+ query = f"UPDATE {table_name} SET {set_clause} WHERE {where_clause}"
100
+ params = []
101
+
102
+ for row in rows:
103
+ row_params = [row[col] for col in valid_columns]
104
+ if where:
105
+ # Add any parameters needed for WHERE clause
106
+ row_params.extend(
107
+ [row[col] for col in where.split() if col in row]
108
+ )
109
+ params.append(tuple(row_params))
110
+
111
+ self.executemany(query, params)
112
+ return
113
+
114
+ if where:
115
+ filtered_rows = []
116
+ for row in rows:
117
+ try:
118
+ test_query = f"SELECT 1 FROM (SELECT {','.join('? as ' + k for k in row.keys())}) WHERE {where}"
119
+ values = tuple(row.values())
120
+ result = self.execute(test_query, values).fetchone()
121
+ if result:
122
+ filtered_rows.append(row)
123
+ except Exception as e:
124
+ print(f"Warning: Where clause evaluation failed for row: {e}")
125
+ rows = filtered_rows
126
+ schema = self.get_table_schema(table_name)
127
+ table_columns = set(schema["name"])
128
+ valid_columns = [col for col in rows[0].keys()]
129
+
130
+ if inherit_foreign:
131
+ fk_query = f"PRAGMA foreign_key_list({table_name})"
132
+ foreign_keys = self.execute(fk_query).fetchall()
133
+
134
+ for row in rows:
135
+ for fk in foreign_keys:
136
+ ref_table, from_col, to_col = fk[2], fk[3], fk[4]
137
+ if from_col not in row or row[from_col] is None:
138
+ if to_col in row:
139
+ query = f"SELECT {from_col} FROM {ref_table} WHERE {to_col} = ?"
140
+ result = self.execute(query, (row[to_col],)).fetchone()
141
+ if result:
142
+ row[from_col] = result[0]
143
+
144
+ columns = valid_columns
145
+ placeholders = ",".join(["?" for _ in columns])
146
+ query = f"{sql_command} INTO {table_name} ({','.join(columns)}) VALUES ({placeholders})"
147
+
148
+ for idx in range(0, len(rows), batch_size):
149
+ batch = rows[idx : idx + batch_size]
150
+ values = [[row.get(col) for col in valid_columns] for row in batch]
151
+ self.executemany(query, values)
152
+
153
+ except sqlite3.Error as e:
154
+ self.rollback()
155
+ raise ValueError(f"Batch operation failed: {e}")
156
+
157
+ def update_many(
158
+ self,
159
+ table_name: str,
160
+ rows: List[Dict[str, _Any]],
161
+ batch_size: int = 1000,
162
+ where: Optional[str] = None,
163
+ columns: Optional[List[str]] = None,
164
+ ) -> None:
165
+ with self.transaction():
166
+ self._run_many(
167
+ sql_command="UPDATE",
168
+ table_name=table_name,
169
+ rows=rows,
170
+ batch_size=batch_size,
171
+ inherit_foreign=False,
172
+ where=where,
173
+ columns=columns,
174
+ )
175
+
176
+ def insert_many(
177
+ self,
178
+ table_name: str,
179
+ rows: List[Dict[str, _Any]],
180
+ batch_size: int = 1000,
181
+ inherit_foreign: bool = True,
182
+ where: Optional[str] = None,
183
+ ) -> None:
184
+ with self.transaction():
185
+ self._run_many(
186
+ sql_command="INSERT",
187
+ table_name=table_name,
188
+ rows=rows,
189
+ batch_size=batch_size,
190
+ inherit_foreign=inherit_foreign,
191
+ where=where,
192
+ )
193
+
194
+ def replace_many(
195
+ self,
196
+ table_name: str,
197
+ rows: List[Dict[str, _Any]],
198
+ batch_size: int = 1000,
199
+ inherit_foreign: bool = True,
200
+ where: Optional[str] = None,
201
+ ) -> None:
202
+ with self.transaction():
203
+ self._run_many(
204
+ sql_command="REPLACE",
205
+ table_name=table_name,
206
+ rows=rows,
207
+ batch_size=batch_size,
208
+ inherit_foreign=inherit_foreign,
209
+ where=where,
210
+ )
211
+
212
+ def delete_where(
213
+ self, table_name: str, where: str, limit: Optional[int] = None
214
+ ) -> None:
215
+ with self.transaction():
216
+ if not where or not isinstance(where, str):
217
+ raise ValueError("Invalid where clause")
218
+ params = []
219
+ query = f"DELETE FROM {table_name} WHERE {where}"
220
+ if limit is not None:
221
+ if not isinstance(limit, int) or limit <= 0:
222
+ raise ValueError("Limit must be a positive integer")
223
+ query += f" LIMIT {limit}"
224
+ self.execute(query, params)
225
+
226
+ def update_where(
227
+ self,
228
+ table_name: str,
229
+ updates: Dict[str, _Any],
230
+ where: str,
231
+ limit: Optional[int] = None,
232
+ ) -> None:
233
+ with self.transaction():
234
+ if not updates:
235
+ raise ValueError("Updates dictionary cannot be empty")
236
+ set_clause = ", ".join([f"{col} = ?" for col in updates.keys()])
237
+ query = f"UPDATE {table_name} SET {set_clause} WHERE {where}"
238
+ if limit is not None:
239
+ query += f" LIMIT {limit}"
240
+ self.execute(query, tuple(updates.values()))
241
+
242
+
243
+ # EOF
@@ -0,0 +1,229 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Time-stamp: "2024-12-01 05:13:49 (ywatanabe)"
4
+ # File: ./scitex_repo/src/scitex/db/_SQLite3Mixins/_BlobMixin.py
5
+
6
+ THIS_FILE = "/home/ywatanabe/proj/scitex_repo/src/scitex/db/_SQLite3Mixins/_BlobMixin.py"
7
+
8
+ import sqlite3
9
+ from typing import Any as _Any
10
+ from typing import Dict, List, Optional, Tuple, Union
11
+
12
+ import numpy as np
13
+ from .._BaseMixins._BaseBlobMixin import _BaseBlobMixin
14
+
15
+
16
+ class _BlobMixin:
17
+ """BLOB data handling functionality"""
18
+
19
+ def save_array(
20
+ self,
21
+ table_name: str,
22
+ data: np.ndarray,
23
+ column: str = "data",
24
+ ids: Optional[Union[int, List[int]]] = None,
25
+ where: str = None,
26
+ additional_columns: Dict[str, _Any] = None,
27
+ batch_size: int = 1000,
28
+ ) -> None:
29
+ with self.lock:
30
+ if not isinstance(data, (np.ndarray, list)):
31
+ raise ValueError("Input must be a NumPy array or list of arrays")
32
+
33
+ try:
34
+ if ids is not None:
35
+ if isinstance(ids, int):
36
+ ids = [ids]
37
+ data = [data]
38
+ if len(ids) != len(data):
39
+ raise ValueError("Length of ids must match number of arrays")
40
+
41
+ for id_, arr in zip(ids, data):
42
+ if not isinstance(arr, np.ndarray):
43
+ raise ValueError(
44
+ f"Element for id {id_} must be a NumPy array"
45
+ )
46
+
47
+ 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}=?" for col in columns]
60
+ query = f"UPDATE {table_name} SET {','.join(update_cols)} WHERE id=?"
61
+ values.append(id_)
62
+ self.execute(query, tuple(values))
63
+
64
+ else:
65
+ if not isinstance(data, np.ndarray):
66
+ raise ValueError("Single input must be a NumPy array")
67
+
68
+ binary = data.tobytes()
69
+ columns = [column, f"{column}_dtype", f"{column}_shape"]
70
+ values = [binary, str(data.dtype), str(data.shape)]
71
+
72
+ if additional_columns:
73
+ columns = list(additional_columns.keys()) + columns
74
+ values = list(additional_columns.values()) + values
75
+
76
+ if where is not None:
77
+ update_cols = [f"{col}=?" for col in columns]
78
+ query = f"UPDATE {table_name} SET {','.join(update_cols)} WHERE {where}"
79
+ self.execute(query, tuple(values))
80
+ else:
81
+ placeholders = ",".join(["?" for _ in columns])
82
+ columns_str = ",".join(columns)
83
+ query = f"INSERT INTO {table_name} ({columns_str}) VALUES ({placeholders})"
84
+ self.execute(query, tuple(values))
85
+
86
+ except Exception as err:
87
+ raise ValueError(f"Failed to save array: {err}")
88
+
89
+ def load_array(
90
+ self,
91
+ table_name: str,
92
+ column: str,
93
+ ids: Union[int, List[int], str] = "all",
94
+ where: str = None,
95
+ order_by: str = None,
96
+ batch_size: int = 128,
97
+ dtype: np.dtype = None,
98
+ shape: Optional[Tuple] = None,
99
+ ) -> Optional[np.ndarray]:
100
+ try:
101
+ if ids == "all":
102
+ query = f"SELECT id FROM {table_name}"
103
+ if where:
104
+ query += f" WHERE {where}"
105
+ self.cursor.execute(query)
106
+ ids = [row[0] for row in self.cursor.fetchall()]
107
+ elif isinstance(ids, int):
108
+ ids = [ids]
109
+
110
+ id_to_data = {}
111
+ unique_ids = list(set(ids))
112
+
113
+ for idx in range(0, len(unique_ids), batch_size):
114
+ batch_ids = unique_ids[idx : idx + batch_size]
115
+ placeholders = ",".join("?" for _ in batch_ids)
116
+
117
+ try:
118
+ query = f"""
119
+ SELECT id, {column},
120
+ {column}_dtype,
121
+ {column}_shape
122
+ FROM {table_name}
123
+ WHERE id IN ({placeholders})
124
+ """
125
+ self.cursor.execute(query, tuple(batch_ids))
126
+ has_metadata = True
127
+ except sqlite3.OperationalError:
128
+ query = f"SELECT id, {column} FROM {table_name} WHERE id IN ({placeholders})"
129
+ self.cursor.execute(query, tuple(batch_ids))
130
+ has_metadata = False
131
+
132
+ if where:
133
+ query += f" AND {where}"
134
+ if order_by:
135
+ query += f" ORDER BY {order_by}"
136
+
137
+ results = self.cursor.fetchall()
138
+ if results:
139
+ for result in results:
140
+ if has_metadata:
141
+ id_val, blob, dtype_str, shape_str = result
142
+ data = np.frombuffer(
143
+ blob, dtype=np.dtype(dtype_str)
144
+ ).reshape(eval(shape_str))
145
+ else:
146
+ id_val, blob = result
147
+ data = (
148
+ np.frombuffer(blob, dtype=dtype)
149
+ if dtype
150
+ else np.frombuffer(blob)
151
+ )
152
+ if shape:
153
+ data = data.reshape(shape)
154
+ id_to_data[id_val] = data
155
+
156
+ all_data = [id_to_data[id_val] for id_val in ids if id_val in id_to_data]
157
+ return np.stack(all_data, axis=0) if all_data else None
158
+
159
+ except Exception as err:
160
+ raise ValueError(f"Failed to load array: {err}")
161
+
162
+ def binary_to_array(
163
+ self,
164
+ binary_data,
165
+ dtype_str=None,
166
+ shape_str=None,
167
+ dtype=None,
168
+ shape=None,
169
+ ):
170
+ if binary_data is None:
171
+ return None
172
+
173
+ if dtype_str and shape_str:
174
+ return np.frombuffer(binary_data, dtype=np.dtype(dtype_str)).reshape(
175
+ eval(shape_str)
176
+ )
177
+ elif dtype and shape:
178
+ return np.frombuffer(binary_data, dtype=dtype).reshape(shape)
179
+ return binary_data
180
+
181
+ def get_array_dict(self, df, columns=None, dtype=None, shape=None):
182
+ result = {}
183
+ if columns is None:
184
+ columns = [
185
+ col
186
+ for col in df.columns
187
+ if not (col.endswith("_dtype") or col.endswith("_shape"))
188
+ ]
189
+
190
+ for col in columns:
191
+ if f"{col}_dtype" in df.columns and f"{col}_shape" in df.columns:
192
+ arrays = [
193
+ self.binary_to_array(
194
+ row[col], row[f"{col}_dtype"], row[f"{col}_shape"]
195
+ )
196
+ for _, row in df.iterrows()
197
+ ]
198
+ elif dtype and shape:
199
+ arrays = [
200
+ self.binary_to_array(x, dtype=dtype, shape=shape) for x in df[col]
201
+ ]
202
+ result[col] = np.stack(arrays)
203
+
204
+ return result
205
+
206
+ def decode_array_columns(self, df, columns=None, dtype=None, shape=None):
207
+ if columns is None:
208
+ columns = [
209
+ col
210
+ for col in df.columns
211
+ if not (col.endswith("_dtype") or col.endswith("_shape"))
212
+ ]
213
+
214
+ for col in columns:
215
+ if f"{col}_dtype" in df.columns and f"{col}_shape" in df.columns:
216
+ df[col] = df.apply(
217
+ lambda row: self.binary_to_array(
218
+ row[col], row[f"{col}_dtype"], row[f"{col}_shape"]
219
+ ),
220
+ axis=1,
221
+ )
222
+ elif dtype and shape:
223
+ df[col] = df[col].apply(
224
+ lambda x: self.binary_to_array(x, dtype=dtype, shape=shape)
225
+ )
226
+ return df
227
+
228
+
229
+ # EOF
@@ -0,0 +1,108 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Time-stamp: "2024-11-29 04:33:58 (ywatanabe)"
4
+ # File: ./scitex_repo/src/scitex/db/_SQLite3Mixins/_ConnectionMixin.py
5
+
6
+ THIS_FILE = (
7
+ "/home/ywatanabe/proj/scitex_repo/src/scitex/db/_SQLite3Mixins/_ConnectionMixin.py"
8
+ )
9
+
10
+ """
11
+ 1. Functionality:
12
+ - Manages SQLite database connections with thread-safe operations
13
+ - Handles database journal files and transaction states
14
+ 2. Input:
15
+ - Database file path
16
+ 3. Output:
17
+ - Managed SQLite connection and cursor objects
18
+ 4. Prerequisites:
19
+ - sqlite3
20
+ - threading
21
+ """
22
+
23
+ import sqlite3
24
+ import threading
25
+ from typing import Optional
26
+ import os
27
+ import shutil
28
+ import tempfile
29
+ from .._BaseMixins._BaseConnectionMixin import _BaseConnectionMixin
30
+ import contextlib
31
+
32
+
33
+ class _ConnectionMixin:
34
+ """Connection management functionality"""
35
+
36
+ def __init__(self, db_path: str, use_temp_db: bool = False):
37
+ self.lock = threading.Lock()
38
+ self._maintenance_lock = threading.Lock()
39
+ self.db_path = db_path
40
+ self.conn = None
41
+ self.cursor = None
42
+ self.temp_path = None # Initialize temp_path attribute
43
+ if db_path:
44
+ self.connect(db_path, use_temp_db)
45
+
46
+ def __enter__(self):
47
+ return self
48
+
49
+ def __exit__(self, exc_type, exc_val, exc_tb):
50
+ self.close()
51
+
52
+ def _create_temp_copy(self, db_path: str) -> str:
53
+ """Creates temporary copy of database."""
54
+ temp_dir = tempfile.gettempdir()
55
+ self.temp_path = os.path.join(temp_dir, f"temp_{os.path.basename(db_path)}")
56
+ shutil.copy2(db_path, self.temp_path)
57
+ return self.temp_path
58
+
59
+ def connect(self, db_path: str, use_temp_db: bool = False) -> None:
60
+ if self.conn:
61
+ self.close()
62
+
63
+ path_to_connect = self._create_temp_copy(db_path) if use_temp_db else db_path
64
+
65
+ self.conn = sqlite3.connect(path_to_connect, timeout=60.0)
66
+ self.cursor = self.conn.cursor()
67
+
68
+ with self.lock:
69
+ # WAL mode settings
70
+ self.cursor.execute("PRAGMA journal_mode = WAL")
71
+ self.cursor.execute("PRAGMA synchronous = NORMAL")
72
+ self.cursor.execute("PRAGMA busy_timeout = 60000")
73
+ self.cursor.execute("PRAGMA mmap_size = 30000000000")
74
+ self.cursor.execute("PRAGMA temp_store = MEMORY")
75
+ self.cursor.execute("PRAGMA cache_size = -2000")
76
+ self.conn.commit()
77
+
78
+ def close(self) -> None:
79
+ if self.cursor:
80
+ self.cursor.close()
81
+ if self.conn:
82
+ try:
83
+ self.conn.rollback()
84
+ self.conn.close()
85
+ except sqlite3.Error:
86
+ pass
87
+ self.cursor = None
88
+ self.conn = None
89
+
90
+ if (
91
+ hasattr(self, "temp_path")
92
+ and self.temp_path
93
+ and os.path.exists(self.temp_path)
94
+ ):
95
+ try:
96
+ os.remove(self.temp_path)
97
+ self.temp_path = None
98
+ except OSError:
99
+ pass
100
+
101
+ def reconnect(self, use_temp_db: bool = False) -> None:
102
+ if self.db_path:
103
+ self.connect(self.db_path, use_temp_db)
104
+ else:
105
+ raise ValueError("No database path specified for reconnection")
106
+
107
+
108
+ # EOF
@@ -0,0 +1,80 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Time-stamp: "2024-11-25 01:36:18 (ywatanabe)"
4
+ # File: ./scitex_repo/src/scitex/db/_SQLite3Mixins/_ImportExportMixin.py
5
+
6
+ THIS_FILE = (
7
+ "/home/ywatanabe/proj/scitex_repo/src/scitex/db/_SQLite3Mixins/_ImportExportMixin.py"
8
+ )
9
+
10
+ from typing import List
11
+
12
+ import pandas as pd
13
+
14
+ from .._BaseMixins._BaseImportExportMixin import _BaseImportExportMixin
15
+
16
+
17
+ class _ImportExportMixin:
18
+ """Import/Export functionality"""
19
+
20
+ def load_from_csv(
21
+ self,
22
+ table_name: str,
23
+ csv_path: str,
24
+ if_exists: str = "append",
25
+ batch_size: int = 10_000,
26
+ chunk_size: int = 100_000,
27
+ ) -> None:
28
+ with self.transaction():
29
+ try:
30
+ for chunk in pd.read_csv(csv_path, chunksize=chunk_size):
31
+ chunk.to_sql(
32
+ table_name,
33
+ self.conn,
34
+ if_exists=if_exists,
35
+ index=False,
36
+ chunksize=batch_size,
37
+ )
38
+ if_exists = "append"
39
+ except FileNotFoundError:
40
+ raise FileNotFoundError(f"CSV file not found: {csv_path}")
41
+ except Exception as err:
42
+ raise ValueError(f"Failed to import from CSV: {err}")
43
+
44
+ def save_to_csv(
45
+ self,
46
+ table_name: str,
47
+ output_path: str,
48
+ columns: List[str] = ["*"],
49
+ where: str = None,
50
+ batch_size: int = 10_000,
51
+ ) -> None:
52
+ try:
53
+ df = self.get_rows(
54
+ columns=columns,
55
+ table_name=table_name,
56
+ where=where,
57
+ limit=batch_size,
58
+ offset=0,
59
+ )
60
+ df.to_csv(output_path, index=False, mode="w")
61
+
62
+ offset = batch_size
63
+ while len(df) == batch_size:
64
+ df = self.get_rows(
65
+ columns=columns,
66
+ table_name=table_name,
67
+ where=where,
68
+ limit=batch_size,
69
+ offset=offset,
70
+ )
71
+ if len(df) > 0:
72
+ df.to_csv(output_path, index=False, mode="a", header=False)
73
+ offset += batch_size
74
+ except PermissionError:
75
+ raise PermissionError(f"Cannot write to: {output_path}")
76
+ except Exception as err:
77
+ raise ValueError(f"Failed to export to CSV: {err}")
78
+
79
+
80
+ # EOF
@@ -0,0 +1,32 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+ # Time-stamp: "2024-11-25 01:36:45 (ywatanabe)"
4
+ # File: ./scitex_repo/src/scitex/db/_SQLite3Mixins/_IndexMixin.py
5
+
6
+ THIS_FILE = "/home/ywatanabe/proj/scitex_repo/src/scitex/db/_SQLite3Mixins/_IndexMixin.py"
7
+
8
+ from typing import List
9
+ from .._BaseMixins._BaseIndexMixin import _BaseIndexMixin
10
+
11
+
12
+ class _IndexMixin:
13
+ """Index management functionality"""
14
+
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
+ if index_name is None:
23
+ index_name = f"idx_{table_name}_{'_'.join(column_names)}"
24
+ unique_clause = "UNIQUE" if unique else ""
25
+ query = f"CREATE {unique_clause} INDEX IF NOT EXISTS {index_name} ON {table_name} ({','.join(column_names)})"
26
+ self.execute(query)
27
+
28
+ def drop_index(self, index_name: str) -> None:
29
+ self.execute(f"DROP INDEX IF EXISTS {index_name}")
30
+
31
+
32
+ # EOF