Python API#
from bio2zarr import bgen
root = bgen.convert("input.bgen", "output.vcz")
probabilities = root["call_GP"]
dosages = root["call_DS"]
call_GP is present for unphased records and call_HP for phased records;
mixed input produces both. Phasing is not converted to hard genotype calls.
call_PLOIDY, call_BGEN_MISSING and variant_bgen_phased retain the
original data model and missingness. Multiallelic input adds an
alt_alleles dimension to call_DS; entirely biallelic input retains
two-dimensional dosage. See bgen2zarr for probability ordering,
padding and exact layout-1 preservation.
Omit the output path for a MemoryStore-backed group; use a .zip output
suffix for a ZipStore-backed group. All output modes return a zarr.Group.
Custom sample identifiers may be supplied directly:
root = bgen.convert(
"input.bgen",
sample_ids=["sample_a", "sample_b"],
variants_chunk_size=100,
samples_chunk_size=1000,
zarr_format=3,
)
The number of identifiers must match the BGEN sample count. See bgen2zarr for the supported data model and limitations.
Alternatively supply an Oxford .sample sidecar (not a plain ID list):
root = bgen.convert("input.bgen", "output.vcz", sample_file="input.sample")
# Explicitly use individual IDs instead of the default first identifier column.
root = bgen.convert(
"input.bgen", sample_file="input.sample", sample_id_column="ID_2"
)
The first column is the default identifier, following QCTOOL semantics.
The one-column Oxford reference format and vcztools’ ID_1 ID_2 missing
format are supported. Only IDs are imported, in unchanged BGEN sample order;
phenotype/covariate and missing columns are not imported or interpreted.
The file must contain exactly the BGEN sample count, with unique, nonmissing
selected IDs. Either explicit source overrides embedded identifiers.
sample_ids and sample_file are mutually exclusive; sample_id_column
requires sample_file. No sidecar is discovered automatically.
See bgen2zarr for structural validation and missing-ID rules.
Select output fields and storage settings with the same defaults as the CLI:
# Probabilities only, retaining the default float64 precision and zstd level 7.
root = bgen.convert("input.bgen", "probabilities.vcz", dosage=False)
# Smaller dosage-only output; this discards uncertainty and haplotype probabilities.
root = bgen.convert(
"input.bgen",
"dosage.vcz",
probabilities=False,
float_dtype="float32",
compressor="lz4",
compression_level=3,
zarr_format=3,
)
settings = root.attrs["bio2zarr_bgen"]
probabilities=True and dosage=True retain both by default; disabling
both raises ValueError before input access or output creation.
float_dtype accepts only "float64" (default) or "float32". Float32
rounds values and must not be treated as universally lossless; dosage is
computed in float64 before casting. Ploidy, missingness, the phase indicator
and variant/sample metadata remain in either mode. Codec settings apply to
schema-defined output arrays; auxiliary shared-writer arrays retain their
standard compression. See bgen2zarr for full tradeoffs.
Dimension discovery is configurable independently of storage:
# Default: actual sample-ploidy scan, discover phased/unphased records.
root = bgen.convert("input.bgen", dimension_source="actual")
# Allocate from declared ploidy bounds; loose bounds increase padding.
root = bgen.convert("input.bgen", dimension_source="declared")
# Independently known bound/model: no genotype-dimension discovery.
root = bgen.convert("input.bgen", max_ploidy=2, probability_model="unphased")
# Permit either phase model, deliberately allocating both GP and HP.
root = bgen.convert("input.bgen", max_ploidy=2, probability_model="mixed")
dimension_settings = root.attrs["bio2zarr_bgen_dimensions"]
max_ploidy accepts integers from 0 to 63 and is mutually exclusive with an
explicit dimension_source. probability_model defaults to "auto"; with
max_ploidy it still scans to discover which phase models are present.
Explicit "unphased" or "phased" assumptions and every provided ploidy bound
are checked during full decoding, including missing samples. Violations reject
conversion; no probability entries are truncated or silently discarded.
"mixed" always allocates both models. See bgen2zarr for the
codec-specific discovery matrix and the backend release requirement.
API reference#
- bio2zarr.bgen.convert(bgen_path, out=None, *, sample_ids=None, sample_file=None, sample_id_column=None, mode='r', variants_chunk_size=None, samples_chunk_size=None, worker_processes=0, show_progress=False, zarr_format=None, probabilities=True, dosage=True, float_dtype='float64', compressor='zstd', compression_level=7, dimension_source=None, probability_model='auto', max_ploidy=None)#
Convert BGEN genotype or phased haplotype probabilities to VCF Zarr.
Parameters#
- bgen_pathstr or Path
Local BGEN layout 1 (raw/zlib) or layout 2 (raw/zlib/zstd) file. Layout 2 supports phased/unphased, multiallelic and variable-ploidy data.
- outstr, Path, or None
Directory, .zip archive, or None for a MemoryStore-backed group.
- sample_idssequence of str, optional
Sample identifiers in file order, overriding embedded identifiers. Without either, identifiers sample_0, sample_1, … are generated.
- sample_filestr or Path, optional
Explicit UTF-8 Oxford .sample sidecar, overriding embedded identifiers. Mutually exclusive with sample_ids. No sidecar is discovered automatically. Rows must match BGEN sample order and count. Only IDs are imported; phenotype/covariate and missing columns are not imported or interpreted.
- sample_id_columnstr, optional
Identifier column name in sample_file; defaults to its first column (QCTOOL semantics). Select “ID_2” explicitly for individual IDs when the first column contains family IDs. Must have type 0.
- modestr
Returned group access mode, “r” (default) or “r+”. Zip output is read-only and requires “r”.
- variants_chunk_size, samples_chunk_sizeint, optional
Output chunk sizes. Defaults follow the other converters.
- worker_processesint
Parallel encoder processes; 0 (default) runs in the main process.
- show_progressbool
Display encoding progress.
- zarr_formatint, optional
Output format, 2 (default) or 3. BIO2ZARR_DEFAULT_ZARR_FORMAT overrides the default.
- probabilities, dosagebool
Retain GP/HP and/or derived DS (both default True). At least one is required. Dosage alone discards uncertainty and haplotype information.
- float_dtype{“float64”, “float32”}
GP/HP/DS storage precision, default float64. Float32 rounds values; dosage is always computed in float64 before the final cast.
- compressor{“zstd”, “lz4”}
Blosc codec for schema-defined output arrays, default zstd.
- compression_levelint
Blosc compression level from 0 to 9, default 7; byte shuffle is retained.
- dimension_source{“actual”, “declared”}, optional
Use actual sample ploidies (default), or declared BGEN ploidy bounds when discovering GP/HP widths. Declared bounds may increase padding. Mutually exclusive with max_ploidy.
- probability_model{“auto”, “unphased”, “phased”, “mixed”}
Discover phase models (default), or allocate the specified models. Explicit unphased/phased assumptions are checked during conversion. Mixed allocates both GP and HP even if one is unused.
- max_ploidyint, optional
User-supplied maximum sample ploidy, 0 to 63. With an explicit probability_model, skip genotype-dimension discovery entirely. With auto, still discover which phase models are present. Bounds are checked during conversion; no probabilities are truncated.
Returns#
- zarr.Group
VCZ data, including call_GP and/or call_HP, derived call_DS, sample ploidy and original missingness. No hard genotypes are inferred. The first BGEN allele is treated as reference.
Notes#
An existing bgen-limix <input filename>.metafile sidecar is reused read-only. If absent, metadata is indexed in a temporary directory. Stale or variant-count-mismatched sidecars are rejected, not overwritten. Every supported encoding is read natively from the original file. Metadata discovery determines dimensions without decoding probabilities. Each native float64 batch is decoded once and shared across all fields. Batches stop at output variant-chunk boundaries and are subdivided to keep estimated working buffers within 256 MiB per worker. Output is assembled one field/sample-chunk slab at a time; native reads include all samples. This is a buffer budget, not a bound on total process RSS or codec scratch. Directory/zip output is staged beside the destination and renamed only after validation and encoding succeed; no intermediate genotype copy is written. ICF conversion is not currently implemented. Probabilities default to float64 to retain the backend’s precision, including independently rounded layout-1 values and 32-bit layout-2 probabilities. Explicit float32 output rounds values without renormalizing.