rfmix-reader 0.2.1__tar.gz → 0.3.1__tar.gz

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 (36) hide show
  1. rfmix_reader-0.3.1/PKG-INFO +512 -0
  2. rfmix_reader-0.3.1/README.md +462 -0
  3. {rfmix_reader-0.2.1 → rfmix_reader-0.3.1}/pyproject.toml +12 -4
  4. rfmix_reader-0.3.1/rfmix_reader/__init__.py +103 -0
  5. rfmix_reader-0.3.1/rfmix_reader/cli/__init__.py +4 -0
  6. rfmix_reader-0.2.1/rfmix_reader/_cli.py → rfmix_reader-0.3.1/rfmix_reader/cli/create_binaries.py +13 -3
  7. rfmix_reader-0.3.1/rfmix_reader/cli/merge_phased_zarrs.py +44 -0
  8. rfmix_reader-0.3.1/rfmix_reader/cli/prepare_reference.py +71 -0
  9. rfmix_reader-0.3.1/rfmix_reader/io/__init__.py +14 -0
  10. rfmix_reader-0.2.1/rfmix_reader/_loci_bed.py → rfmix_reader-0.3.1/rfmix_reader/io/loci_bed.py +1 -5
  11. rfmix_reader-0.3.1/rfmix_reader/io/prepare_reference.py +107 -0
  12. rfmix_reader-0.2.1/rfmix_reader/_write_data.py → rfmix_reader-0.3.1/rfmix_reader/io/write_data.py +70 -33
  13. rfmix_reader-0.3.1/rfmix_reader/processing/__init__.py +20 -0
  14. rfmix_reader-0.3.1/rfmix_reader/processing/_hmm_lai.py +333 -0
  15. rfmix_reader-0.3.1/rfmix_reader/processing/imputation.py +332 -0
  16. rfmix_reader-0.3.1/rfmix_reader/processing/phase.py +1261 -0
  17. rfmix_reader-0.3.1/rfmix_reader/readers/__init__.py +8 -0
  18. rfmix_reader-0.2.1/rfmix_reader/_read_flare.py → rfmix_reader-0.3.1/rfmix_reader/readers/read_flare.py +25 -5
  19. rfmix_reader-0.2.1/rfmix_reader/_read_rfmix.py → rfmix_reader-0.3.1/rfmix_reader/readers/read_rfmix.py +97 -31
  20. rfmix_reader-0.2.1/rfmix_reader/_read_simu.py → rfmix_reader-0.3.1/rfmix_reader/readers/read_simu.py +11 -8
  21. rfmix_reader-0.2.1/rfmix_reader/_utils.py → rfmix_reader-0.3.1/rfmix_reader/utils.py +88 -10
  22. rfmix_reader-0.3.1/rfmix_reader/viz/__init__.py +17 -0
  23. rfmix_reader-0.2.1/rfmix_reader/_tagore.py → rfmix_reader-0.3.1/rfmix_reader/viz/tagore.py +1 -5
  24. rfmix_reader-0.2.1/rfmix_reader/_visualization.py → rfmix_reader-0.3.1/rfmix_reader/viz/visualization.py +2 -9
  25. rfmix_reader-0.2.1/PKG-INFO +0 -259
  26. rfmix_reader-0.2.1/README.md +0 -215
  27. rfmix_reader-0.2.1/rfmix_reader/.local.py +0 -648
  28. rfmix_reader-0.2.1/rfmix_reader/__init__.py +0 -92
  29. rfmix_reader-0.2.1/rfmix_reader/_imputation.py +0 -218
  30. {rfmix_reader-0.2.1 → rfmix_reader-0.3.1}/LICENSE +0 -0
  31. {rfmix_reader-0.2.1 → rfmix_reader-0.3.1}/rfmix_reader/_testing.py +0 -0
  32. {rfmix_reader-0.2.1 → rfmix_reader-0.3.1}/rfmix_reader/base.svg.p +0 -0
  33. /rfmix_reader-0.2.1/rfmix_reader/_chunk.py → /rfmix_reader-0.3.1/rfmix_reader/io/chunk.py +0 -0
  34. /rfmix_reader-0.2.1/rfmix_reader/_errorhandling.py → /rfmix_reader-0.3.1/rfmix_reader/io/errors.py +0 -0
  35. /rfmix_reader-0.2.1/rfmix_reader/_constants.py → /rfmix_reader-0.3.1/rfmix_reader/processing/constants.py +0 -0
  36. /rfmix_reader-0.2.1/rfmix_reader/_fb_read.py → /rfmix_reader-0.3.1/rfmix_reader/readers/fb_read.py +0 -0
@@ -0,0 +1,512 @@
1
+ Metadata-Version: 2.4
2
+ Name: rfmix-reader
3
+ Version: 0.3.1
4
+ Summary: RFMix-reader is a Python package designed to efficiently read and process output files generated by RFMix, a popular tool for estimating local ancestry in admixed populations. The package employs a lazy loading approach, which minimizes memory consumption by reading only the loci that are accessed by the user, rather than loading the entire dataset into memory at once.
5
+ License: GPL-3.0-or-later
6
+ License-File: LICENSE
7
+ Keywords: file parser,rfmix,gpu acceleration,local ancestry
8
+ Author: Kynon J.M. Benjamin
9
+ Author-email: kj.benjamin90@gmail.com
10
+ Maintainer: Kynon J.M. Benjamin
11
+ Maintainer-email: kj.benjamin90@gmail.com
12
+ Requires-Python: >=3.11,<3.15
13
+ Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
14
+ Classifier: Operating System :: OS Independent
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Provides-Extra: all
21
+ Provides-Extra: docs
22
+ Provides-Extra: gpu
23
+ Provides-Extra: io
24
+ Provides-Extra: tests
25
+ Provides-Extra: viz
26
+ Requires-Dist: cairosvg (>=2.7,<3.0) ; extra == "viz" or extra == "all"
27
+ Requires-Dist: cudf-cu12 ; extra == "all"
28
+ Requires-Dist: cupy-cuda12x ; extra == "all"
29
+ Requires-Dist: cyvcf2 (>=0.31)
30
+ Requires-Dist: dask (>=2025.1,<2026.0)
31
+ Requires-Dist: dask-cudf-cu12 ; extra == "all"
32
+ Requires-Dist: fonttools (>=4.61.0,<5.0.0)
33
+ Requires-Dist: matplotlib (>=3.10,<4.0) ; extra == "viz" or extra == "all"
34
+ Requires-Dist: numpy (>=1.23,<3)
35
+ Requires-Dist: pandas (>=2.0)
36
+ Requires-Dist: psutil (>=7,<8)
37
+ Requires-Dist: pyarrow ; extra == "io" or extra == "all"
38
+ Requires-Dist: seaborn (>=0.13,<0.14) ; extra == "viz" or extra == "all"
39
+ Requires-Dist: sphinx (>=7,<9) ; extra == "docs"
40
+ Requires-Dist: sphinx-autodoc-typehints (>=2,<3) ; extra == "docs"
41
+ Requires-Dist: sphinx-copybutton (>=0.5,<0.6) ; extra == "docs"
42
+ Requires-Dist: sphinx-rtd-theme (>=2,<3) ; extra == "docs"
43
+ Requires-Dist: torch (>=2.8) ; extra == "gpu" or extra == "all"
44
+ Requires-Dist: tqdm (>=4.66)
45
+ Project-URL: Bug Tracker, https://github.com/heart-gen/rfmix_reader/issues
46
+ Project-URL: homepage, https://rfmix-reader.readthedocs.io/en/latest/
47
+ Project-URL: repository, https://github.com/heart-gen/rfmix_reader.git
48
+ Description-Content-Type: text/markdown
49
+
50
+ # RFMix-reader
51
+ `RFMix-reader` is a Python package for efficiently reading and processing output
52
+ files generated by [`RFMix`](https://github.com/slowkoni/rfmix), a widely used tool
53
+ for estimating local ancestry in admixed populations.
54
+ It employs a **lazy loading approach** to minimize memory usage, and leverages **GPU acceleration**
55
+ for major speedups when available.
56
+
57
+ ---
58
+
59
+ ## Installation
60
+
61
+ `rfmix-reader` requires **Python 3.11+**. Install from PyPI:
62
+
63
+ ```bash
64
+ pip install rfmix-reader
65
+ ````
66
+
67
+ ### Installation Options
68
+
69
+ * **Basic install** (CPU only):
70
+
71
+ ```bash
72
+ pip install rfmix-reader
73
+ ```
74
+
75
+ * **With GPU acceleration** (`cupy`, `cudf`, `dask-cudf`, `torch`):
76
+
77
+ ```bash
78
+ pip install rfmix-reader[gpu]
79
+ ```
80
+
81
+ The default GPU extra targets **CUDA 12** wheels (`cupy-cuda12x`,
82
+ `cudf-cu12`, `dask-cudf-cu12`). Use the appropriate CUDA build strings if
83
+ your environment requires a different version.
84
+
85
+ * **With documentation tools** (`sphinx`, `sphinx-rtd-theme`):
86
+
87
+ ```bash
88
+ pip install rfmix-reader[docs]
89
+ ```
90
+
91
+ * **With testing tools** (`pytest`):
92
+
93
+ ```bash
94
+ pip install rfmix-reader[tests]
95
+ ```
96
+
97
+ ### GPU Notes
98
+
99
+ * PyTorch is **not** installed in the base package. It is pulled in only when you install the `[gpu]` extra (`pip install rfmix-reader[gpu]`) or add it yourself.
100
+ * Install a PyTorch wheel that matches your platform and CUDA version using the [official selector](https://pytorch.org/get-started/locally/). For example:
101
+ * **CUDA 12 (Linux/Windows):** `pip install torch --index-url https://download.pytorch.org/whl/cu121`
102
+ * **CUDA 11 (Linux/Windows):** `pip install torch --index-url https://download.pytorch.org/whl/cu118`
103
+ * **CPU-only:** `pip install torch --index-url https://download.pytorch.org/whl/cpu`
104
+ * RAPIDS (`cudf`, `cupy`) wheels are version- and CUDA-specific. See the [RAPIDS install guide](https://docs.rapids.ai/install).
105
+ * CPU-only installations will still run efficiently, just without GPU acceleration.
106
+
107
+ ---
108
+
109
+ ## Quickstart
110
+
111
+ ```python
112
+ from rfmix_reader import read_rfmix
113
+
114
+ # Load RFMix outputs (two-population admixture example)
115
+ file_path = "examples/two_populations/out/"
116
+ loci_df, g_anc, local_array = read_rfmix(file_path)
117
+
118
+ print(loci_df.head())
119
+ print(g_anc.head())
120
+ print(local_array.shape)
121
+ """See the phasing section below for how to phase per-chromosome outputs and
122
+ write them to Zarr with `phase_rfmix_chromosome_to_zarr`."""
123
+ ```
124
+
125
+ ---
126
+
127
+ ## Key Features
128
+
129
+ * **Lazy Loading**: Reads data on-the-fly, reducing memory footprint.
130
+ * **Efficient Access**: Query specific loci or regions of interest.
131
+ * **Seamless Integration**: Works smoothly with `pandas`, `dask`, and other analysis tools.
132
+ * **Loci Imputation**: Impute local ancestry loci to dense genotype variant sites.
133
+ * **GPU Acceleration**: Automatic CUDA acceleration via PyTorch/CuPy when available.
134
+
135
+ ---
136
+
137
+ ## Simulation Data
138
+
139
+ Test datasets for two- and three-population admixture are available on Synapse:
140
+ [Synapse Project syn61691659](https://www.synapse.org/Synapse:syn61691659).
141
+
142
+ ---
143
+
144
+ ## Usage
145
+
146
+ ### Binary Conversion
147
+
148
+ RFMix does not generate binary files directly.
149
+ Use `create_binaries` to generate them (also available as a CLI):
150
+
151
+ ```bash
152
+ create-binaries two_pops/out/
153
+ ```
154
+
155
+ ```python
156
+ from rfmix_reader import create_binaries
157
+
158
+ create_binaries("two_pops/out/", binary_dir="./binary_files")
159
+ ```
160
+
161
+ ### Preparing Reference Data for Phasing
162
+
163
+ Use `prepare-reference` to convert bgzipped, indexed reference VCF/BCF files
164
+ into per-chromosome VCF-Zarr stores that the phasing pipeline consumes.
165
+ The command writes one `<chrom>.zarr` directory per input file.
166
+
167
+ ```
168
+ prepare-reference -h
169
+ ```
170
+
171
+ ```
172
+ usage: prepare-reference [-h] [--chunk-length CHUNK_LENGTH]
173
+ [--samples-chunk-size SAMPLES_CHUNK_SIZE]
174
+ [--worker-processes WORKER_PROCESSES]
175
+ [--verbose | --no-verbose] [--version]
176
+ output_dir vcf_paths [vcf_paths ...]
177
+
178
+ Convert one or more bgzipped reference VCF/BCF files into Zarr stores.
179
+
180
+ positional arguments:
181
+ output_dir Directory where the Zarr outputs will be written.
182
+ vcf_paths Paths to reference VCF/BCF files (bgzipped and
183
+ indexed).
184
+
185
+ options:
186
+ -h, --help show this help message and exit
187
+ --chunk-length CHUNK_LENGTH
188
+ Genomic chunk size for the output Zarr stores
189
+ (default: 100000).
190
+ --samples-chunk-size SAMPLES_CHUNK_SIZE
191
+ Chunk size for samples in the output Zarr stores
192
+ (default: library chosen).
193
+ --worker-processes WORKER_PROCESSES
194
+ Number of worker processes to use for conversion
195
+ (default: 0, use library default).
196
+ --verbose, --no-verbose
197
+ Print progress messages (default: enabled).
198
+ --version Show the version of the program and exit.
199
+ ```
200
+
201
+ Example data preparation:
202
+
203
+ ```bash
204
+ # Sample annotations: two columns (no header): sample_id<TAB>group
205
+ cat > sample_annotations.tsv <<'EOF'
206
+ NA19700 AFR
207
+ NA19701 AFR
208
+ NA20847 EUR
209
+ EOF
210
+
211
+ # Convert chromosome VCFs into a reference store directory
212
+ prepare-reference refs/ 1kg_chr20.vcf.gz 1kg_chr21.vcf.gz \
213
+ --chunk-length 50000 --samples-chunk-size 512
214
+ ```
215
+
216
+ ### Main Function
217
+
218
+ Once binaries are available, process RFMix results:
219
+
220
+ ```python
221
+ from rfmix_reader import read_rfmix
222
+
223
+ loci, g_anc, admix = read_rfmix("two_pops/out/")
224
+ ```
225
+
226
+ ### Three Population Example
227
+
228
+ Binaries can also be generated on-the-fly within `read_rfmix` with
229
+ `generate_binary` set to `True`.
230
+
231
+ ```python
232
+ loci, g_anc, admix = read_rfmix("examples/three_populations/out/",
233
+ binary_dir="./binary_files",
234
+ generate_binary=True)
235
+ ```
236
+
237
+ ### Phasing data
238
+
239
+ For optimal memory and computational speed, phasing is done per
240
+ chromosome.
241
+
242
+ ```python
243
+ from rfmix_reader import phase_rfmix_chromosome_to_zarr
244
+
245
+ # Use the reference store + annotations during phasing
246
+ admix = phase_rfmix_chromosome_to_zarr(
247
+ file_prefix="two_pops/out/",
248
+ ref_zarr_root="refs",
249
+ sample_annot_path="sample_annotations.tsv",
250
+ output_path="./phased_chr21.zarr",
251
+ chrom="21",
252
+ )
253
+ ```
254
+
255
+ The chunking is suboptimal for phasing, so remember to
256
+ rechunk before using for optimal processing. This is only needed
257
+ when loading individual chromosomes. The merged data is already
258
+ optimized.
259
+
260
+ ```python
261
+ local_array = admix["local_ancestry"].chunk({"variant": 20000, "sample": 100})
262
+ # Compute into memory, if needed
263
+ local_array = local_array.compute()
264
+ ```
265
+
266
+ This also saves the data to Zarr for later merging or data processing.
267
+
268
+ ```bash
269
+ merge-phased-zarrs ./phased_all.zarr ./phased_chr21.zarr ./phased_chr22.zarr
270
+ ```
271
+ ### Loci Imputation
272
+
273
+ The imputation workflow now lives in ``rfmix_reader.processing.imputation`` and
274
+ is exported as ``interpolate_array``. It interpolates the local ancestry matrix
275
+ onto a denser variant grid and writes the result to ``<zarr_outdir>/local-ancestry.zarr``
276
+ as a Zarr array shaped ``(variants, samples, ancestries)``.
277
+
278
+ **Inputs**
279
+
280
+ * ``variant_loci_df``: a pandas DataFrame defining the variant grid. Provide at
281
+ least ``chrom``/``pos`` and an ``i`` column that points to the source RFMix
282
+ row index; rows with ``i`` set to ``NaN`` are treated as missing loci to
283
+ interpolate. Sort the frame by genomic coordinate, and include ``pos`` if you
284
+ plan to interpolate in base-pair space.
285
+ * ``admix``: the local ancestry Dask array returned by ``read_rfmix`` (shape
286
+ ``(loci, samples, ancestries)``).
287
+ * ``zarr_outdir``: an output directory where the new ``local-ancestry.zarr``
288
+ store will be created.
289
+
290
+ **Key options**
291
+
292
+ * ``interpolation``: ``"linear"`` (default), ``"nearest"``, or ``"stepwise"``.
293
+ * ``use_bp_positions``: set to ``True`` to interpolate along ``variant_loci_df['pos']``
294
+ rather than treating loci as equally spaced indices.
295
+ * ``chunk_size``/``batch_size``: tune how many rows are materialized at a time
296
+ when filling and interpolating the Zarr array.
297
+
298
+ **Workflow example**
299
+
300
+ ```python
301
+ import pandas as pd
302
+ from pathlib import Path
303
+ from rfmix_reader import interpolate_array, read_rfmix
304
+
305
+ # Load RFMix loci and local ancestry
306
+ loci_df, _, admix = read_rfmix("two_pops/out/", binary_dir="./binary_files")
307
+
308
+ # Build the variant grid by merging genotype sites with the RFMix loci index
309
+ variants = pd.read_parquet("genotypes/variants.parquet") # must include chrom/pos
310
+ variants = variants.drop_duplicates(subset=["chrom", "pos"]).sort_values("pos")
311
+ variant_loci_df = (
312
+ variants.merge(loci_df.to_pandas(), on=["chrom", "pos"], how="outer", indicator=True)
313
+ .loc[:, ["chrom", "pos", "i", "_merge"]]
314
+ )
315
+
316
+ z = interpolate_array(
317
+ variant_loci_df,
318
+ admix,
319
+ zarr_outdir=Path("./imputed_local_ancestry"),
320
+ interpolation="linear",
321
+ use_bp_positions=True,
322
+ chunk_size=50_000,
323
+ )
324
+ print(z)
325
+ ```
326
+
327
+ The interpolator uses GPU acceleration transparently when ``cupy`` and a CUDA
328
+ PyTorch build are available; otherwise it falls back to NumPy. All methods other
329
+ than ``"hmm"`` operate on diploid-summed trajectories and preserve the original
330
+ ancestry dimension.
331
+
332
+ ### Phasing workflow (`rfmix_reader.processing.phase`)
333
+
334
+ `rfmix_reader.processing.phase` implements gnomix-style tail-flip corrections
335
+ for local ancestry haplotypes. Phasing now lives outside `read_rfmix` so you can
336
+ process each chromosome independently and write outputs directly to Zarr.
337
+
338
+ #### Required reference inputs
339
+
340
+ * **VCF-Zarr reference** (`ref_zarr_root`): either a single `*.zarr` store or a
341
+ directory containing per-chromosome stores (e.g., `1.zarr`, `chr1.zarr`).
342
+ * **Sample annotations** (`sample_annot_path`): two-column file mapping
343
+ `sample_id` to `group` (ancestry label). One representative sample per group
344
+ is pulled to build reference haplotypes.
345
+
346
+ #### Per-chromosome pipeline
347
+
348
+ 1. (Optional) generate RFMix binary caches with `create_binaries`.
349
+ 2. Call `phase_rfmix_chromosome_to_zarr` for each chromosome you want to
350
+ process.
351
+ 3. Optionally concatenate those per-chromosome Zarr stores with
352
+ `merge_phased_zarrs`.
353
+
354
+ ```python
355
+ from rfmix_reader.processing.phase import (
356
+ PhasingConfig,
357
+ merge_phased_zarrs,
358
+ phase_rfmix_chromosome_to_zarr,
359
+ )
360
+
361
+ # Phase chromosome 21 and write to Zarr
362
+ dataset = phase_rfmix_chromosome_to_zarr(
363
+ file_prefix="examples/two_populations/out/",
364
+ ref_zarr_root="/refs/1kg_chr_zarr/",
365
+ sample_annot_path="/refs/1kg_annotations.tsv",
366
+ output_path="/tmp/phased_chr21.zarr",
367
+ chrom="21",
368
+ )
369
+
370
+ # Merge multiple per-chromosome Zarr stores
371
+ merged = merge_phased_zarrs(
372
+ ["/tmp/phased_chr21.zarr", "/tmp/phased_chr22.zarr"],
373
+ output_path="/tmp/phased_all.zarr",
374
+ )
375
+ ```
376
+
377
+ If you need fine-grained control, you can still start from unphased outputs and
378
+ call `phase_admix_dask_with_index` directly:
379
+
380
+ ```python
381
+ from rfmix_reader import read_rfmix
382
+ from rfmix_reader.processing.phase import PhasingConfig, phase_admix_dask_with_index
383
+
384
+ loci_df, g_anc, admix, X_raw = read_rfmix(
385
+ "examples/two_populations/out/",
386
+ return_original=True,
387
+ chrom="21",
388
+ )
389
+
390
+ config = PhasingConfig(window_size=100, min_block_len=10, max_mismatch_frac=0.3)
391
+ phased = phase_admix_dask_with_index(
392
+ admix=admix,
393
+ X_raw=X_raw,
394
+ positions=loci_df.physical_position.to_numpy(),
395
+ chrom=str(loci_df.chromosome.iloc[0]),
396
+ ref_zarr_root="/refs/1kg_chr_zarr/",
397
+ sample_annot_path="/refs/1kg_annotations.tsv",
398
+ config=config,
399
+ )
400
+ ```
401
+
402
+ ### Reading Haptools simulations
403
+
404
+ Use `read_simu` to load BGZF-compressed VCF files created by
405
+ `haptools simgenotype --pop_field`:
406
+
407
+ ```python
408
+ from rfmix_reader import read_simu
409
+
410
+ loci_df, g_anc, admix = read_simu("/path/to/simulations/")
411
+ ```
412
+
413
+ Haptools does **not** include the chromosome length in the `##contig`
414
+ header lines, but `read_simu` requires that metadata to index each VCF.
415
+ Copy the `contigs.txt` file Haptools generates from the FASTA you used
416
+ for simulation and reheader every file with the appropriate contig entry
417
+ before calling `read_simu`. The following snippet shows one approach
418
+ using `bcftools` and `tabix`:
419
+
420
+ ```bash
421
+ CONTIGS="../../three_populations/_m/contigs.txt"
422
+ VCFDIR="gt-files"
423
+ CHR="chr${SLURM_ARRAY_TASK_ID}"
424
+ OUT="${VCFDIR}/${CHR}.vcf.gz"
425
+ IN="${VCFDIR}/back/${CHR}.vcf.gz"
426
+
427
+ CONTIG_LINE=$(grep -w "ID=${CHR}" "$CONTIGS")
428
+ if [[ -z "$CONTIG_LINE" ]]; then
429
+ echo "ERROR: No contig line found for ${CHR} in $CONTIGS"
430
+ exit 1
431
+ fi
432
+
433
+ bcftools view -h "$IN" \
434
+ | sed "s/^##contig=<ID=${CHR}>.*/${CONTIG_LINE}/" > header.${CHR}.tmp
435
+ bcftools reheader -h header.${CHR}.tmp -o "$OUT" "$IN"
436
+ tabix -p vcf "$OUT"
437
+ ```
438
+
439
+ ### Visualization
440
+
441
+ `read_rfmix`, `read_flare`, and `read_simu` all return the same
442
+ `(loci_df, g_anc, admix)` tuple, so the plotting utilities in
443
+ `rfmix_reader._visualization` work identically for RFMix, FLARE, and
444
+ Haptools-simulated inputs. The snippet below shows the typical workflow
445
+ for each reader:
446
+
447
+ ```python
448
+ from rfmix_reader import (
449
+ plot_ancestry_by_chromosome,
450
+ plot_global_ancestry,
451
+ read_flare,
452
+ read_rfmix,
453
+ read_simu,
454
+ )
455
+
456
+ # RFMix run directory
457
+ loci_df, g_anc, admix = read_rfmix("two_pops/out/")
458
+ plot_global_ancestry(g_anc, save_path="rfmix_global.png")
459
+ plot_ancestry_by_chromosome(loci_df, admix, save_path="rfmix_local.png")
460
+
461
+ # FLARE output directory (contains *.anc.vcf.gz + global.anc.gz)
462
+ loci_df, g_anc, admix = read_flare("flare_runs/chr1/")
463
+ plot_global_ancestry(g_anc, save_path="flare_global.png")
464
+ plot_ancestry_by_chromosome(loci_df, admix, save_path="flare_local.png")
465
+
466
+ # Haptools simulations (after reheadering contigs)
467
+ loci_df, g_anc, admix = read_simu("/path/to/simulations/")
468
+ plot_global_ancestry(g_anc, save_path="simu_global.png")
469
+ plot_ancestry_by_chromosome(loci_df, admix, save_path="simu_local.png")
470
+ ```
471
+
472
+ `plot_global_ancestry` builds per-individual stacked bars of global
473
+ ancestry while `plot_ancestry_by_chromosome` summarizes local ancestry
474
+ along each chromosome, giving you quick visual QC for every supported
475
+ input format.
476
+
477
+ ---
478
+
479
+ ## Development Install
480
+
481
+ For contributors:
482
+
483
+ ```bash
484
+ git clone https://github.com/heart-gen/rfmix_reader.git
485
+ cd rfmix_reader
486
+ pip install -e ".[gpu,docs,tests]"
487
+ ```
488
+
489
+ ---
490
+
491
+ ## Citation
492
+
493
+ If you use this software, please cite:
494
+
495
+ [![DOI](https://zenodo.org/badge/807052842.svg)](https://zenodo.org/doi/10.5281/zenodo.12629787)
496
+
497
+ Benjamin, K. J. M. (2024). **RFMix-reader (Version 0.2.0)** \[Computer software].
498
+ [https://github.com/heart-gen/rfmix\_reader](https://github.com/heart-gen/rfmix_reader)
499
+
500
+ Kynon JM Benjamin. *"RFMix-reader: Accelerated reading and processing for local ancestry studies."*
501
+ **bioRxiv** (2024).
502
+ DOI: [10.1101/2024.07.13.603370](https://www.biorxiv.org/content/10.1101/2024.07.13.603370v2).
503
+
504
+ ---
505
+
506
+ ## Funding
507
+
508
+ This work was supported by the National Institutes of Health,
509
+ National Institute on Minority Health and Health Disparities (NIMHD)
510
+ K99MD016964 / R00MD016964.
511
+
512
+