Skip to main content

AdmixPy

Fast Python implementation of ADMIXTOOLS-style f-statistics, qpAdm, and qpWave.

Fast f-statistics, qpAdm, and qpWave in Python.

Installation

Requires Python 3.10 or newer.

Using a virtual environment is recommended:

python3 -m venv venv
source venv/bin/activate

Install the latest release from PyPI:

python -m pip install --upgrade pip
python -m pip install admixpy

Check that the package imports:

python -c "import admixpy; print(admixpy.__version__)"

Updating

Upgrade an existing installation to the latest release:

python -m pip install --upgrade admixpy

Alternative: installing from source

Create and activate a virtual environment:

python3 -m venv venv
source venv/bin/activate

Install the package from pyproject.toml:

python -m pip install --upgrade pip
python -m pip install -e .

Examples

Supported input layouts include EIGENSTRAT text, packed AncestryMap, TGENO, and SNP-major PLINK binary files (.bed/.bim/.fam). For .geno/.snp/.ind inputs, the genotype layout is detected from the file header/size; TGENO can also be provided as .tgeno/.snp/.ind.

Basic API

The main convenience wrappers are:

admixpy.f2(data, pop1=None, pop2=None, *, unique_only=True,
           resampling="pairwise_counts", **kwargs)
admixpy.fst(data, pop1=None, pop2=None, *, unique_only=True,
            resampling="pairwise_counts", fst_aggregation="block_ratios",
            **kwargs)
admixpy.f3(data, pop1=None, pop2=None, pop3=None, *, unique_only=True,
           resampling="pairwise_counts", verbose=True, **kwargs)
admixpy.f4(data, pop1, pop2=None, pop3=None, pop4=None, *, comb=True,
           unique_only=True, afprod=False, verbose=True, **kwargs)
admixpy.qpwave(data, left, right, ranks=None, left_base=None,
               right_base=None, rcond=1e-10, diag=0.0, max_nfev=None,
               verbose=True, **kwargs)
admixpy.qpadm(data, target, left=None, right=None, sources=None,
              fudge=0.0001, fudge_twice=False, iterations=20, getcov=True,
              return_f4=False, return_stats=False, return_cov=False,
              verbose=True, **kwargs)

The main convenience wrappers are f2, fst, f3, f4, qpwave, and qpadm.

data can be a supported genotype dataset prefix or precomputed f2 data. Population arguments can be strings or lists where the wrapper supports multiple combinations. For PLINK .bed/.bim/.fam input, population labels are read from the FID column of the .fam file.

For direct genotype input, f3, f4, qpwave, and qpadm default to allsnps=True, matching the ADMIXTOOLS1-style behavior of estimating each statistic from its available SNPs. For precomputed f2 input, allsnps defaults to False and the standard f2-based behavior is used. Pass allsnps=False to restrict direct-genotype models to SNPs shared across the required populations.

Direct genotype f3 also defaults to allsnps=True and is calculated per SNP. By default, its corrected numerator is divided by unbiased target heterozygosity. Set outgroupmode=True to return the unnormalized f3 numerator; that raw mode is directly comparable to f2-derived f3 and to original qp3Pop outgroup mode after removing the latter's factor of 1000.

Data Scope Recommended setting
Known modern diploid data All direct genotype statistics Keep defaults (ploidy auto-detected), or set adjust_pseudohaploid=False to force known diploid data
Ancient or mixed-ploidy data All direct genotype statistics adjust_pseudohaploid=True, apply_corr=True (auto-detected per sample)
ADMIXTOOLS2-normalized direct f3 f3 only outgroupmode=False (default)
Raw/original outgroup f3 f3 only outgroupmode=True
Diploid singleton target or repeated source f3 only Keep apply_corr=True; two called alleles make correction possible
Pseudohaploid singleton used only as a distinct source f3 only Allowed with apply_corr=True because it occurs linearly
Pseudohaploid singleton target or repeated source f3 only Unbiased correction is not possible; affected SNPs are excluded
Intentionally biased singleton estimate f3 only outgroupmode=True, apply_corr=False; exploratory/legacy
Missingness differs among populations or blocks f2, FST, f3, and cached f4 resampling="pairwise_counts" (default)
In-memory blocks without SNP counts Precomputed-block workflows resampling="nominal_blocks"; incomplete on-disk caches must be rebuilt
Maximum available SNPs per combination Direct f3/f4, qpWave, and qpAdm allsnps=True (direct-genotype default)
Common SNP set across a model Direct f3/f4, qpWave, and qpAdm allsnps=False
Use only polymorphic sites Direct f-statistics poly_only=True (drops non-polymorphic sites)

Direct f3 and f4 genotype calculations (including the f4 calculations for qpAdm and qpWave) read the genotype file once by default and hold the complete SNP-by-population allele-frequency and count tables in memory. For datasets that do not fit comfortably in RAM, set stream=True to use two bounded-memory passes with 250,000 SNPs per chunk by default. The chunk size can be adjusted with chunk_size.

Lower-level helpers are also exported for direct use, including allele-frequency conversion (anygeno_to_afs, eigenstrat_to_afs, plink_to_afs, packedancestrymap_to_afs, tgeno_to_afs), f2 block IO and access (get_f2, read_f2, write_f2), and block/statistical utilities such as iter_geno_to_afs, f3_stats_from_geno, block_covariance, jackknife_cov, stats_to_loo, and est_to_loo.

SNP selection, missingness, and small samples

By default, f2 excludes SNPs with identical allele frequencies in every loaded population, while fst retains them. This matches the ADMIXTOOLS default but means the two statistics can use different SNP sets. Use poly_only=True to both calls when they should be directly comparable.

AdmixPy uses resampling="pairwise_counts" as default for data with missing genotypes: each population pair is weighted by the SNP observations actually available for that pair. Pairwise f2 and fst result tables include n. Set resampling="nominal_blocks" to reproduce the older behavior in which every pair uses nominal block sizes. Raw-genotype f4 with allsnps=True already uses per-statistic counts on a common SNP intersection. Cached pairwise f3/f4 instead defines a pairwise-available estimator and cannot reconstruct that common intersection.

FST cache files additionally retain numerator and denominator sums. The default fst_aggregation="block_ratios" averages stored block estimates. Set fst_aggregation="pooled_components" to recompute full-data and leave-one-block-out FST as ratios of pooled numerator and denominator sums.

Bias-corrected f2 and FST require at least two independent allele observations in each population. SNP values with a count below two are excluded with a warning when apply_corr=True. Setting apply_corr=False explicitly requests the finite but sampling-biased raw estimate; the Hudson FST denominator remains (p1-p2)^2 + p1(1-p1) + p2(1-p2) in either mode.

Cache files without real per-pair SNP counts are rejected and must be rebuilt.

Run an f4 statistic from a supported genotype dataset prefix:

import admixpy

prefix = "/path/to/dataset_prefix"

result = admixpy.f4(
    prefix,
    "Mbuti",
    "Germany_ViesenhaeuserHof_EN",
    "Sardinian",
    "French",
)

print(result)

qpAdm can be run the same way from a Python REPL:

>>> import admixpy as a
>>> prefix = "/path/to/dataset_prefix"
>>> target = "Sardinian"
>>> left = ["Turkey_N", "Russia_Samara_EBA_Yamnaya", "Luxembourg_Loschbour_Mesolithic", "Iran_GanjDareh_N"]
>>> right = ["Chimp", "Turkey_Epipaleolithic", "Georgia_KotiasKlde_Mesolithic", "Russia_Vologda_Mesolithic", "Switzerland_Epipaleolithic", "Iran_BeltCave_Mesolithic"]
>>> res = a.qpadm(prefix, target=target, left=left, right=right)
>>> res
QpAdmResult(target='Sardinian')

weights:
                           left weight     se     z
                       Turkey_N  0.686  0.013 52.45
      Russia_Samara_EBA_Yamnaya  0.102  0.012  8.54
Luxembourg_Loschbour_Mesolithic  0.119 0.0064 18.57
               Iran_GanjDareh_N  0.094  0.013  7.11

rankdrop:
f4rank dof   chisq         p  p_nested
     3   2    0.53     0.769 9.39e-242
     2   6 1123.16 2.03e-239         0
     1  12 3317.58         0         0
     0  20 6849.91         0       NaN

popdrop:
 pat                                                                    dropped f4rank dof   chisq         p  feasible status
0000                                                                                 3   2    0.53     0.769      True   PASS
0001                                                           Iran_GanjDareh_N      2   3   58.58  1.18e-12      True   FAIL
0010                                            Luxembourg_Loschbour_Mesolithic      2   3   370.2  6.29e-80     False   FAIL
0100                                                  Russia_Samara_EBA_Yamnaya      2   3   73.09  9.29e-16      True   FAIL
1000                                                                   Turkey_N      2   3  825.23 1.46e-178     False   FAIL
 ...

Citation

AdmixPy implements methods from Patterson et al. (2012) and Maier et al. (2023).

License

MIT License .

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

admixpy-1.0.1.tar.gz (53.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

admixpy-1.0.1-py3-none-any.whl (42.0 kB view details)

Uploaded Python 3

File details

Details for the file admixpy-1.0.1.tar.gz.

File metadata

  • Download URL: admixpy-1.0.1.tar.gz
  • Upload date:
  • Size: 53.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for admixpy-1.0.1.tar.gz
Algorithm Hash digest
SHA256 2466b5dd287feac969536c6368bae6a7df6a8f959d3f2008170919be40efbfc4
MD5 e8233165bde8067f09c8df30340803a2
BLAKE2b-256 44c800abf5d683125d0a0eaef2167f1c65a0bd5e592cac43e6d323b6e35dccf0

See more details on using hashes here.

Provenance

The following attestation bundles were made for admixpy-1.0.1.tar.gz:

Publisher: publish.yml on system0x7/admixpy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file admixpy-1.0.1-py3-none-any.whl.

File metadata

  • Download URL: admixpy-1.0.1-py3-none-any.whl
  • Upload date:
  • Size: 42.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for admixpy-1.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 074963a0f8dac55a39a51e685a84495ba4281efa629e14abf513a5c051abefec
MD5 90decbec5755fc31efe139957b1621cb
BLAKE2b-256 573ac863cfe00f5383faed51cf372d6f2378989ed0155c3884329db9fb878f2a

See more details on using hashes here.

Provenance

The following attestation bundles were made for admixpy-1.0.1-py3-none-any.whl:

Publisher: publish.yml on system0x7/admixpy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

1.0.5

2 files

1.0.4

2 files

1.0.3

2 files

1.0.2

2 files

This release

1.0.1 This release

2 files

1.0.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page