pg-sui 1.6.14.dev9__py3-none-any.whl → 1.6.16a3__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.
@@ -0,0 +1,292 @@
1
+ Metadata-Version: 2.4
2
+ Name: pg-sui
3
+ Version: 1.6.16a3
4
+ Summary: Python machine and deep learning API to impute missing genotypes
5
+ Author-email: "Drs. Bradley T. Martin and Tyler K. Chafin" <evobio721@gmail.com>
6
+ Maintainer-email: "Dr. Bradley T. Martin" <evobio721@gmail.com>
7
+ License: GNU General Public License v3 (GPLv3)
8
+ Project-URL: Homepage, https://github.com/btmartin721/PG-SUI
9
+ Project-URL: Documentation, https://pg-sui.readthedocs.io/en/latest/
10
+ Project-URL: Source, https://github.com/btmartin721/PG-SUI.git
11
+ Project-URL: BugTracker, https://github.com/btmartin721/PG-SUI/issues
12
+ Keywords: impute,imputation,AI,deep learning,machine learning,neural network,vae,autoencoder,ubp,nlpca,population genetics,unsupervised,supervised,bioinformatics,snp,genomics,genotype,missing data,data analysis,data science,statistics,data visualization,python
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Development Status :: 4 - Beta
17
+ Classifier: Environment :: Console
18
+ Classifier: Intended Audience :: Science/Research
19
+ Classifier: Intended Audience :: Developers
20
+ Classifier: Intended Audience :: Education
21
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
22
+ Classifier: Topic :: Scientific/Engineering :: Bio-Informatics
23
+ Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
24
+ Classifier: Topic :: Scientific/Engineering :: Information Analysis
25
+ Classifier: Topic :: Scientific/Engineering :: Visualization
26
+ Classifier: Operating System :: MacOS
27
+ Classifier: Operating System :: MacOS :: MacOS X
28
+ Classifier: Operating System :: Unix
29
+ Classifier: Operating System :: POSIX
30
+ Classifier: Natural Language :: English
31
+ Requires-Python: >=3.11
32
+ Description-Content-Type: text/markdown
33
+ License-File: LICENSE
34
+ Requires-Dist: matplotlib
35
+ Requires-Dist: numpy>=2.1
36
+ Requires-Dist: pandas>=2.2.2
37
+ Requires-Dist: scikit-learn>=1.4
38
+ Requires-Dist: scipy
39
+ Requires-Dist: seaborn
40
+ Requires-Dist: torch
41
+ Requires-Dist: tqdm
42
+ Requires-Dist: toytree
43
+ Requires-Dist: optuna
44
+ Requires-Dist: rich
45
+ Requires-Dist: rich[jupyter]
46
+ Requires-Dist: snpio
47
+ Provides-Extra: intel
48
+ Requires-Dist: scikit-learn-intelex; extra == "intel"
49
+ Provides-Extra: docs
50
+ Requires-Dist: sphinx; extra == "docs"
51
+ Requires-Dist: sphinx-rtd-theme; extra == "docs"
52
+ Requires-Dist: sphinx_autodoc_typehints; extra == "docs"
53
+ Requires-Dist: sphinxcontrib-napoleon; extra == "docs"
54
+ Requires-Dist: sphinxcontrib-programoutput; extra == "docs"
55
+ Provides-Extra: dev
56
+ Requires-Dist: twine; extra == "dev"
57
+ Requires-Dist: wheel; extra == "dev"
58
+ Requires-Dist: pytest; extra == "dev"
59
+ Requires-Dist: sphinx; extra == "dev"
60
+ Requires-Dist: sphinx-rtd-theme; extra == "dev"
61
+ Requires-Dist: sphinx-autodoc-typehints; extra == "dev"
62
+ Requires-Dist: sphinxcontrib-napoleon; extra == "dev"
63
+ Requires-Dist: sphinxcontrib-programoutput; extra == "dev"
64
+ Requires-Dist: requests; extra == "dev"
65
+ Provides-Extra: optional
66
+ Requires-Dist: PyObjC; extra == "optional"
67
+ Provides-Extra: gui
68
+ Requires-Dist: fastapi>=0.110; extra == "gui"
69
+ Requires-Dist: uvicorn[standard]>=0.23; extra == "gui"
70
+ Dynamic: license-file
71
+
72
+ # PG-SUI
73
+
74
+ ![PG-SUI Logo](https://github.com/btmartin721/PG-SUI/blob/master/img/pgsui-logo-faded.png)
75
+
76
+ Population Genomic Supervised and Unsupervised Imputation.
77
+
78
+ ## About PG-SUI
79
+
80
+ PG-SUI is a Python 3 API that uses machine learning to impute missing values from population genomic SNP data. There are several supervised and unsupervised machine learning algorithms available to impute missing data, as well as some non-machine learning imputers that are useful.
81
+
82
+ Below is some general information and a basic tutorial. For more detailed information, see our [API Documentation](https://pg-sui.readthedocs.io/en/latest/).
83
+
84
+ ### Unsupervised Imputation Methods
85
+
86
+ Unsupervised imputers include three custom neural network models:
87
+
88
+ + Variational Autoencoder (VAE) [1](#1)
89
+ + VAE models train themselves to reconstruct their input (i.e., the genotypes) [1](#1). To use VAE for imputation, the missing values are masked and the VAE model gets trained to reconstruct only on known values. Once the model is trained, it is then used to predict the missing values.
90
+ + Autoencoder [2](#2)
91
+ + A standard autoencoder that trains the input to predict itself [2](#2). As with VAE, missing values are masked and the model gets trained only on known values. Predictions are then made on the missing values.
92
+ + Non-linear Principal Component Analysis (NLPCA) [3](#3)
93
+ + NLPCA initializes random, reduced-dimensional input, then trains itself by using the known values (i.e., genotypes) as targets and refining the random input until it accurately predicts the genotype output [3](#3). The trained model can then predict the missing values.
94
+ + Unsupervised Backpropagation (UBP) [4](#4)
95
+ + UBP is an extension of NLPCA that runs over three phases [4](#4). Phase 1 refines the randomly generated, reduced-dimensional input in a single layer perceptron neural network to obtain good initial input values. Phase 2 uses the refined reduced-dimensional input from phase 1 as input into a multi-layer perceptron (MLP), but in Phase 2 only the neural network weights are refined. Phase three uses an MLP to refine both the weights and the reduced-dimensional input. Once the model is trained, it can be used to predict the missing values.
96
+
97
+ ### Supervised Imputation Methods
98
+
99
+ Supervised methods utilze the scikit-learn's ``IterativeImputer``, which is based on the MICE (Multivariate Imputation by Chained Equations) algorithm [5](#5), and iterates over each SNP site (i.e., feature) while uses the N nearest neighbor features to inform the imputation. The number of nearest features can be adjusted by users. IterativeImputer currently works with the following scikit-learn classifiers:
100
+
101
+ + ImputeRandomForest
102
+ + ImputeHistGradientBoosting
103
+
104
+ See the [scikit-learn documentation](https://scikit-learn.org) for more information on IterativeImputer and each of the classifiers.
105
+
106
+ ### Non-Machine Learning (Deterministic) Methods
107
+
108
+ We also include several deterministic options for imputing missing data, including:
109
+
110
+ + Per-population mode per SNP site
111
+ + Overall mode per SNP site
112
+
113
+ ## Installing PG-SUI
114
+
115
+ PG-SUI supports both pip and conda distributions. Both are kept current with up-to-date releases.
116
+
117
+ ### Installation with Pip
118
+
119
+ To install PG-SUI with pip, do the following. It is strongly recommended to install pg-sui in a virtual environment.
120
+
121
+ ``` shell
122
+ python3 -m venv .pgsui-venv
123
+ source .pgsui-venv/bin/activate
124
+ pip install pg-sui
125
+ ```
126
+
127
+ ### Installation with Anaconda
128
+
129
+ To install PG-SUI with Anaconda, do the following:
130
+
131
+ ``` shell
132
+ conda create -n pgsui-env python=3.12
133
+ conda activate pgsui-env
134
+ conda install -c btmartin721 pg-sui
135
+ ```
136
+
137
+ ### Docker Container
138
+
139
+ We also maintains a Docker image that comes with PG-SUI preinstalled. This can be useful for automated worklows such as Nextflow or Snakemake.
140
+
141
+ ``` shell
142
+ docker pull pg-sui:latest
143
+ ```
144
+
145
+ ### Optional MacOS GUI
146
+
147
+ PG-SUI ships an optional Electron GUI (Graphical User Interface) wrapper around the Python CLI. Currently for the GUI, only MacOS is supported.
148
+
149
+ 1. Install the Python-side extras (FastAPI/ uvicorn helper) if you want to serve from Python:
150
+ `pip install pg-sui[gui]`
151
+ 2. Install [Node.js](https://nodejs.org) and fetch the app dependencies:
152
+ `pgsui-gui-setup`
153
+ 3. Launch the graphical interface:
154
+ `pgsui-gui`
155
+
156
+ The GUI shells out to the same CLI underneath, so presets, overrides, and YAML configs behave identically.
157
+
158
+ ## Input Data
159
+
160
+ You can read your input files as a GenotypeData object from the [SNPio](https://snpio.readthedocs.io/en/latest/) package. SNPio supports the VCF, PHYLIP, STRUCTURE, and GENEPOP input file formats.
161
+
162
+ ``` python
163
+ # Import snpio. Automatically installed with pg-sui.
164
+ from snpio import VCFReader
165
+
166
+ # Read in VCF alignment.
167
+ # SNPio also supports PHYLIP, STRUCTURE, and GENEPOP input file formats.
168
+ data = VCFReader(
169
+ filename="pgsui/example_data/phylogen_subset14K.vcf.gz,
170
+ popmapfile="pgsui/example_data/popmaps/phylogen_nomx.popmap", # optional
171
+ force_popmap=True, # optional
172
+ )
173
+ ```
174
+
175
+ ## Supported Imputation Methods
176
+
177
+ There are several supported algorithms PG-SUI uses to impute missing data. Each one can be run by calling the corresponding class. You must provide a GenotypeData instance as the first positional argument.
178
+
179
+ You can import all the supported methods with the following:
180
+
181
+ ``` python
182
+ from pgsui import ImputeUBP, ImputeVAE, ImputeNLPCA, ImputeAutoencoder, ImputeRefAllele, ImputeMostFrequent, ImputeRandomForest, ImputeHistGradientBoosting
183
+ ```
184
+
185
+ ### Unsupervised Imputers
186
+
187
+ The four unsupervised imputers can be run by initializing them with the SNPio ``GenotypeData`` object and then calling ``fit()`` and ``transform()``.
188
+
189
+ ``` python
190
+ # Initialize the models, then fit and impute
191
+ vae = ImputeVAE(data) # Variational autoencoder
192
+ vae.fit()
193
+ vae_imputed = vae.transform()
194
+
195
+ nlpca = ImputeNLPCA(data) # Nonlinear PCA
196
+ nlpca.fit()
197
+ nlpca_imputed = nlpca.transform()
198
+
199
+ ubp = ImputeUBP(data) # Unsupervised backpropagation
200
+ ubp.fit()
201
+ ubp_imputed = ubp.transform()
202
+
203
+ ae = ImputeAutoencoder(data) # standard autoencoder
204
+ ae.fit()
205
+ ae_imputed = ae.transform()
206
+ ```
207
+
208
+ The ``*_imputed`` objects will be NumPy arrays that are compatible with SNPio's ``GenotypeData`` objects.
209
+
210
+ ### Supervised Imputers
211
+
212
+ Various supervised imputation options are supported, and these use the same API design.
213
+
214
+ ``` python
215
+ # Supervised IterativeImputer classifiers
216
+
217
+ # Random Forest
218
+ rf = ImputeRandomForest(data)
219
+ rf.fit()
220
+ imputed_rf = rf.transform()
221
+
222
+ # HistGradientBoosting
223
+ hgb = ImputeHistGradientBoosting(data)
224
+ hgb.fit()
225
+ imputed_hgb = hgb.transform()
226
+ ```
227
+
228
+ ### Non-machine learning methods
229
+
230
+ The following deterministic methods are supported. ``ImputeMostFrequent`` supports the mode-per-population or overall (global) mode options to inform imputation.
231
+
232
+ ``` python
233
+ # Per-population, per-locus mode
234
+ pop_mode = ImputeMostFrequent(data, by_populations=True)
235
+ pop_mode.fit()
236
+ imputed_pop_mode = pop_mode.transform()
237
+
238
+ # Per-locus mode
239
+ mode = ImputeMostFrequent(data, by_populations=False)
240
+ mode.fit()
241
+ imputed_mode = mode.transform()
242
+ ```
243
+
244
+ Or, always replace missing values with the reference allele.
245
+
246
+ ``` python
247
+ ref = ImputeRefAllele(data)
248
+ ref.fit()
249
+ imputed_ref = ref.transform()
250
+ ```
251
+
252
+ ## Command-Line Interface
253
+
254
+ Run the PG-SUI CLI with ``pg-sui`` (installed alongside the library). The CLI follows the same precedence model as the Python API:
255
+
256
+ ``code defaults < preset (--preset) < YAML (--config) < explicit CLI flags < --set key=value``.
257
+
258
+ Recent releases add explicit switches for the simulated-missingness workflow shared by the neural and supervised models:
259
+
260
+ + ``--sim-strategy`` selects one of ``random``, ``random_weighted``, ``random_weighted_inv``, ``nonrandom``, ``nonrandom_weighted``.
261
+ + ``--sim-prop`` sets the proportion of observed calls to temporarily mask when building the evaluation set.
262
+ + ``--simulate-missing`` disables simulated masking entirely (store-false flag); omit it to inherit preset/YAML defaults or re-enable via ``--set sim.simulate_missing=True``.
263
+
264
+ Example:
265
+
266
+ ``` shell
267
+ pg-sui \
268
+ --vcf data.vcf.gz \
269
+ --popmap pops.popmap \
270
+ --models ImputeUBP ImputeVAE \
271
+ --preset balanced \
272
+ --sim-strategy random_weighted_inv \
273
+ --sim-prop 0.25 \
274
+ --prefix ubp_and_vae \
275
+ --n-jobs 4 \
276
+ --tune-n-trials 100 \
277
+ --set tune.enabled=True
278
+ ```
279
+
280
+ CLI overrides cascade into every selected model, so a single invocation can evaluate multiple imputers with a consistent simulation strategy and output prefix.
281
+
282
+ ## References
283
+
284
+ 1. Kingma, D.P. & Welling, M. (2013). Auto-encoding variational bayes. In: Proceedings of the International Conference on Learning Representations (ICLR). arXiv:1312.6114 [stat.ML].
285
+
286
+ 2. Hinton, G.E., & Salakhutdinov, R.R. (2006). Reducing the dimensionality of data with neural networks. Science, 313(5786), 504-507.
287
+
288
+ 3. Scholz, M., Kaplan, F., Guy, C. L., Kopka, J., & Selbig, J. (2005). Non-linear PCA: a missing data approach. Bioinformatics, 21(20), 3887-3895.
289
+
290
+ 4. Gashler, M. S., Smith, M. R., Morris, R., & Martinez, T. (2016). Missing value imputation with unsupervised backpropagation. Computational Intelligence, 32(2), 196-215.
291
+
292
+ 5. Stef van Buuren, Karin Groothuis-Oudshoorn (2011). mice: Multivariate Imputation by Chained Equations in R. Journal of Statistical Software 45: 1-67.
@@ -1,10 +1,10 @@
1
- pg_sui-1.6.14.dev9.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
1
+ pg_sui-1.6.16a3.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
2
2
  pgsui/__init__.py,sha256=wQFzVX6vh8aUva1LCvP42jS7rcKCpkaU52YfZIy61q8,1493
3
- pgsui/_version.py,sha256=wKIKHCX5SmsO-4sA-OpkKAHVYuXeZ-aL_K4jO6bGQPU,719
4
- pgsui/cli.py,sha256=tYSXK_BvBv_8rpDEFGcqrV1OCwN48vMervVV-C-6H_A,29675
3
+ pgsui/_version.py,sha256=Ob9Wzde013P9zPCsc2eaS--ZJQaRFPqutqIvBNJDnP4,714
4
+ pgsui/cli.py,sha256=F6v7Bv073NgH3Ku_Lb6DSciTCLzM_o49ktrKnjkiHJg,30229
5
5
  pgsui/data_processing/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
6
6
  pgsui/data_processing/config.py,sha256=g5G7pjWG4uU2BRvBu_DpO0J_4X1Foa11X69imBWjaKA,20483
7
- pgsui/data_processing/containers.py,sha256=5bGA_u3czuTr8TMq6ZmQ-Wc1l-4Qh8-O2siBi3h-owc,51558
7
+ pgsui/data_processing/containers.py,sha256=mtVExBEQQXCID_TbngxY23I690d09WIzmJBdVa7HIo0,51513
8
8
  pgsui/data_processing/transformers.py,sha256=kdwOTmfDjgQ3RmiwQIK7LYL4vQUpgA4bob7NHYgnYRM,30998
9
9
  pgsui/electron/bootstrap.py,sha256=wnrXgX-hiqrMMFE9WGoD-UC8zeK2ZP6Kupu68PodVWI,1185
10
10
  pgsui/electron/launch.py,sha256=M60o_jub77kJL-B9d_sMB7LYuTzWlOnQXR09efmCX2o,1715
@@ -53,15 +53,15 @@ pgsui/impute/supervised/imputers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRk
53
53
  pgsui/impute/supervised/imputers/hist_gradient_boosting.py,sha256=5LZsee2R9tbshmgVvLDIjGDihiQPvp9XfbaGwzL35E8,11509
54
54
  pgsui/impute/supervised/imputers/random_forest.py,sha256=jpeaLjhzYrwRPc9nPasLgwOqBoHlBlymHMc3x5OkBWA,10393
55
55
  pgsui/impute/unsupervised/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
56
- pgsui/impute/unsupervised/base.py,sha256=ev9sWIMTB7WwKgkPW5MkSGrGr_BZaxvhkKiUUmvI5jo,46794
56
+ pgsui/impute/unsupervised/base.py,sha256=DqgP8QNKmbUaljzx_lWC_zFuWTUO3iiRseYTQEWNG0Q,46945
57
57
  pgsui/impute/unsupervised/callbacks.py,sha256=jkxncpKNRdssImv4N5c-Hq8VcA07QvxLoct7EqDW9RE,5026
58
58
  pgsui/impute/unsupervised/loss_functions.py,sha256=f18uQnerj0KF9xcU2I1_Y2OCKKguXXaEDaYhJg0XElY,10089
59
59
  pgsui/impute/unsupervised/nn_scorers.py,sha256=-rl5MBJm2GN6E1wPBIe1wMgdrHEHhYooUUxVbfcf1Z8,9758
60
60
  pgsui/impute/unsupervised/imputers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
61
- pgsui/impute/unsupervised/imputers/autoencoder.py,sha256=fREEWDcmL4DEpFTXFDQjb84sdf2yHSDoCLNWMDhHqe8,54018
62
- pgsui/impute/unsupervised/imputers/nlpca.py,sha256=fboE4gLv6M-mq2PPHSejtpSfShrhUfUSsngAinHgzVw,63797
63
- pgsui/impute/unsupervised/imputers/ubp.py,sha256=ThJh8J-txNaP3JZENtJeQJQim18U3vc2kxOW3vvnyqA,67021
64
- pgsui/impute/unsupervised/imputers/vae.py,sha256=zoOc9yEvAyUPGAew0x3clRvBb7SflMN0LPFuVO0rTsU,50598
61
+ pgsui/impute/unsupervised/imputers/autoencoder.py,sha256=k8GJ80hysAteT-QUmRRtWfPcvH-QjUFHrWBZGVuFH1c,57872
62
+ pgsui/impute/unsupervised/imputers/nlpca.py,sha256=AChGz0Gp9Yt0qF8vtrDI4t5iIr70LQRb-8pFGQBYLZo,69086
63
+ pgsui/impute/unsupervised/imputers/ubp.py,sha256=sBJ9VSW2tTzXVjnXogjhuj6GixRaH0HcQ2B7cK4y6tw,71361
64
+ pgsui/impute/unsupervised/imputers/vae.py,sha256=hK3ZOxyLjQqm-3Hcq2BMUZOghsJiDGYNRQjqA7zoncs,54713
65
65
  pgsui/impute/unsupervised/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
66
66
  pgsui/impute/unsupervised/models/autoencoder_model.py,sha256=mHmfTkldJNpN7Dy7RTS2RnkE2L_K1rChNjpjDvzRlEQ,12333
67
67
  pgsui/impute/unsupervised/models/nlpca_model.py,sha256=1NathvhsirBtd9UcmeJzRoVf7oi7PfDmRpt18Di63Cg,8021
@@ -74,8 +74,8 @@ pgsui/utils/misc.py,sha256=Mw5CsspFJkDAcCRufk-lO7fKyVoYK7PRYXkLXKswUjI,3065
74
74
  pgsui/utils/plotting.py,sha256=d5CTzGIpanu3j6rEB6fq_F1g8w_A2Ti_XiedRjIFFII,42444
75
75
  pgsui/utils/pretty_metrics.py,sha256=dtN7Ohcx3qJYCw4JeJCXvthGDdSV7bgE8v6EGwHSAE0,9862
76
76
  pgsui/utils/scorers.py,sha256=sL2upL2ZZMFBTMM4DiGiWeXrqc_fp1RRbleYCnuRUhw,12564
77
- pg_sui-1.6.14.dev9.dist-info/METADATA,sha256=F_9XvBZpZqKvrMnmD9TnwRuOkjXPEtnsUyGnRQu9orE,14443
78
- pg_sui-1.6.14.dev9.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
79
- pg_sui-1.6.14.dev9.dist-info/entry_points.txt,sha256=xidyl6yqQv7oj3XSzZC6Vv9l7aNgbHi_pjv-dJjGJds,129
80
- pg_sui-1.6.14.dev9.dist-info/top_level.txt,sha256=87-oDpfY6sDY_uN-OM2lcnrgPesifhzwqFOajp9ukz0,6
81
- pg_sui-1.6.14.dev9.dist-info/RECORD,,
77
+ pg_sui-1.6.16a3.dist-info/METADATA,sha256=G87-keKhu56QhKFiAeGQVSD36EH_W2uNf9u4wciAsmU,12320
78
+ pg_sui-1.6.16a3.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
79
+ pg_sui-1.6.16a3.dist-info/entry_points.txt,sha256=xidyl6yqQv7oj3XSzZC6Vv9l7aNgbHi_pjv-dJjGJds,129
80
+ pg_sui-1.6.16a3.dist-info/top_level.txt,sha256=87-oDpfY6sDY_uN-OM2lcnrgPesifhzwqFOajp9ukz0,6
81
+ pg_sui-1.6.16a3.dist-info/RECORD,,
pgsui/_version.py CHANGED
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '1.6.14.dev9'
32
- __version_tuple__ = version_tuple = (1, 6, 14, 'dev9')
31
+ __version__ = version = '1.6.16a3'
32
+ __version_tuple__ = version_tuple = (1, 6, 16, 'a3')
33
33
 
34
34
  __commit_id__ = commit_id = None
pgsui/cli.py CHANGED
@@ -185,6 +185,8 @@ def _args_to_cli_overrides(args: argparse.Namespace) -> dict:
185
185
  overrides["io.n_jobs"] = int(args.n_jobs)
186
186
  if hasattr(args, "seed"):
187
187
  overrides["io.seed"] = _parse_seed(args.seed)
188
+ if hasattr(args, "debug"):
189
+ overrides["io.debug"] = bool(args.debug)
188
190
 
189
191
  # Train
190
192
  if hasattr(args, "batch_size"):
@@ -589,6 +591,7 @@ def main(argv: Optional[List[str]] = None) -> int:
589
591
  help="Random seed: 'random', 'deterministic', or an integer.",
590
592
  )
591
593
  parser.add_argument("--verbose", action="store_true", help="Info-level logging.")
594
+ parser.add_argument("--debug", action="store_true", help="Debug-level logging.")
592
595
  parser.add_argument(
593
596
  "--log-file", default=argparse.SUPPRESS, help="Also write logs to a file."
594
597
  )
@@ -877,7 +880,17 @@ def main(argv: Optional[List[str]] = None) -> int:
877
880
  pth.mkdir(parents=True, exist_ok=True)
878
881
 
879
882
  logging.info(f"Writing imputed VCF for {name} to {pth} ...")
880
- gd_imp.write_vcf(pth / f"{name.lower()}_imputed.vcf.gz")
883
+
884
+ if fmt_final == "vcf":
885
+ gd_imp.write_vcf(pth / f"{name.lower()}_imputed.vcf.gz")
886
+ elif fmt_final == "phylip":
887
+ gd_imp.write_phylip(pth / f"{name.lower()}_imputed.phy")
888
+ elif fmt_final == "genepop":
889
+ gd_imp.write_genepop(pth / f"{name.lower()}_imputed.gen")
890
+ else:
891
+ logging.warning(
892
+ f"Output format {fmt_final} not supported for imputed data export."
893
+ )
881
894
 
882
895
  logging.info("All requested models processed.")
883
896