polars-bio 0.36 reads protein structures and sequence alignments as DataFrames

1 hour ago

polars-bio 0.36 reads protein structures and multiple sequence alignments into the same Polars frames you use for VCF and BAM. It also makes cloud reads parallel by default, opens the full 1000 Genomes PLINK 2 panel, and writes VCF headers back the way they came in.

Ask about this presentation

Chapters

  1. 0:00polars-bio 0.36
  2. 0:19Protein structures
  3. 0:44Sequence alignments
  4. 1:10Parallel cloud reads
  5. 1:38PLINK 2 filesets
  6. 2:04VCF round trips
  7. 2:29What behaves differently
  8. 2:51Upgrade
Show transcript
  1. polars-bio 0.36 reads protein structures and multiple sequence alignments into the same Polars frames you use for VCF and BAM. It also makes cloud reads parallel by default, opens the full 1000 Genomes PLINK 2 panel, and writes VCF headers back the way they came in.

    Slide text
    polars-bio 0.36.0 · 2026-09-21
    polars-bio polar bear logo

    polars-bio 0.36 reads protein structures and sequence alignments as DataFrames

    Cloud reads also run in parallel by default, the 1000 Genomes PLINK 2 panel opens, and VCF headers survive a round trip.

  2. The new structure readers take PDB or mmCIF files, a list or a local glob, and return a row per atom. Ask for residue level, and each row carries backbone coordinates and six angles, phi, psi and omega among them, in Angstroms and degrees. Foldcomp databases work too, decoding only the entries you select. Parsing runs in Rust, with no Gemmi or Biopython install.

    Slide text
    polars-bio 0.36.0 · protein structures

    Read PDB, mmCIF and Foldcomp files as atom or residue tables

    atoms = pb.scan_structures(
        ["experimental.pdb", "predictions/*.cif.gz"])
    residues = pb.scan_mmcif("protein.cif", level="residue")
    residues.select("chain_id", "auth_seq_id",
                    "phi_deg", "psi_deg", "omega_deg")
    subset = pb.scan_foldcomp("afdb",
        ids=["protein_1", "protein_2"], level="residue")
    Angstroms and degrees Backbone coordinates, phi, psi, omega and three bond angles per residue
    Parsed in Rust No Gemmi, Biopython or Foldcomp Python package needed
  3. A2M and A3M files load with the FASTA schema, each sequence exactly as written, inserts and gaps included. Stockholm gives one row per sequence per alignment, and a local, uncompressed Pfam seed file splits across partitions. For OpenProteinSet files with semicolon comments, pass a comment prefix. The readers are parity-tested against Easel, hh-suite and Biopython.

    Slide text
    polars-bio 0.36.0 · multiple sequence alignments

    A2M, A3M and Stockholm alignments load one row per sequence

    A2M · A3M read_a2m · scan_a3m · register_a3m …
    name
    description
    sequence · verbatim, case and gaps kept
    Stockholm read_sto · scan_sto · describe_sto
    alignment_id
    name
    sequence
    gs
    gr

    pb.scan_sto("Pfam-A.seed").group_by("alignment_id").len().collect()

    pb.scan_a3m("alignment.a3m.gz", comment_prefix=";")

    Tested against Easel, hh-suite and Biopython

  4. The concurrent fetches setting now defaults to 8 in more than 40 read, scan, describe and register functions. Whole-file reads from S3, Google Cloud Storage and HTTP become parallel ranged requests. On high-latency links, the old single connection took about twice as long as aws s3 cp. With 8 megabyte chunks, up to 64 megabytes can be in flight per stream. Set it to 1 to turn parallel fetching off.

    Slide text
    polars-bio 0.36.0 · object storage

    Reads from S3, GCS and HTTP now run up to 8 ranged requests at once

    0.35.1 · concurrent_fetches=1
    one sequential request
    0.36.0 · concurrent_fetches=8
    8 MiB ranged requests, up to 8 in flight at once
    About twice as long as aws s3 cp One sequential connection on high-latency links, before 0.36
    Up to 64 MiB in flight Per stream, with 8 MiB chunks. Pass concurrent_fetches=1 to turn it off
  5. In 0.35.1, the PGEN readers rejected the published 1000 Genomes fileset, because its compressed variant file passed a fixed 512 megabyte cap. Companion files are now streamed into a columnar table. That panel, about 75 million variants, opens in about 4 seconds within about 4 gigabytes, where the old layout would have needed about 45. Three new arguments set the limits.

    Slide text
    polars-bio 0.36.0 · PGEN

    The 1000 Genomes PLINK 2 panel now opens in about 4 seconds

    GRCh38 · 75.2M variants · 541 MiB .pvar.zst · rejected by 0.35.1 at a 512 MiB cap

    Memory to open it, previous per-row representation
    ~45 GB
    0.36.0 columnar variant table
    ~4 GB
    max_companion_bytes 4 GiB max_decompressed_companion_bytes 16 GiB max_variants 250M
  6. A scan and sink round trip used to rebuild the VCF header, losing the file date, the source, bcftools provenance and the PASS filter. For a local file, the header now goes back line for line. Turn on preserve record layout, and each record keeps its own INFO and FORMAT key order. And an INFO_AF column is written as the input's AF, so an annotation tool's AF stays out of it.

    Slide text
    polars-bio 0.36.0 · VCF writing

    sink_vcf writes a local file's header back line for line

    Dropped by a 0.35.1 round trip, kept now

    ##fileDate kept
    ##source kept
    ##bcftools_* kept
    PASS filter kept
    contigs beyond ID, length kept
    lf = pb.scan_vcf("variants.vcf.gz",
        preserve_record_layout=True)
    pb.sink_vcf(lf.filter(pl.col("qual") > 30),
        "filtered.vcf")

    Each record keeps its own INFO and FORMAT key order. Off by default; text VCF only.

    INFO_AF is written as the input's AF An annotation tool's own AF column stays out of that field
  7. If you compare outputs across versions, check these. Reads are parallel by default. Written VCF puts GT first in FORMAT, as the specification requires. A malformed BED record now raises an error where it used to disappear. And polars-config-meta 0.3.2 is required, because older versions dropped the source header on collect.

    Slide text
    polars-bio 0.36.0 · after you upgrade

    Existing pipelines can behave differently in four places

    What
    0.35.1
    0.36.0
    concurrent_fetches default
    1
    8 · pass 1 to turn it off
    FORMAT order from sink_vcf
    DP:GT
    GT first, as the VCF spec requires
    Malformed BED record
    silently dropped
    raises an error; BED3 keeps every interval
    polars-config-meta
    >=0.3.0
    >=0.3.2 · keeps metadata on collect()
  8. To upgrade, run pip install polars-bio. Linux arm64 now gets a pre-built wheel too. This release does not write the alignment formats, an A2M or A3M scan parses in one partition, Foldcomp needs a local path, and a VCF from cloud storage still has its header rebuilt. polars-bio 0.36 reads protein structures and sequence alignments as DataFrames.

    Slide text
    polars-bio 0.36.0 · upgrade
    $ pip install polars-bio

    Linux arm64 now gets a pre-built wheel, built and tested on native ARM runners.

    Not covered yet

    Writing A2M, A3M or Stockholm files
    Parallel parsing of an A2M or A3M scan
    Foldcomp from remote storage (local paths only)
    Verbatim headers for VCF read from cloud storage
    polars-bio polar bear logo

    biodatageeks.org/polars-bio

What happened in AI today, in your inbox

One short email each evening. Read it and you’re caught up.

Built in New York with ❤️