Skip to content

Genomic operations

polars-bio implements the common genomic interval operations with a DataFrame API (both Polars and Pandas) and a native parallel engine. The comparison tables below map each operation to its equivalent in other libraries and link to the polars-bio API reference.

On this page: Interval operations ยท Pileup / depth

Genomic ranges operations

operation Bioframe polars-bio PyRanges0 PyRanges1 Pybedtools GenomicRanges
overlap overlap overlap join1 join_overlaps intersect2 find_overlaps3
nearest closest nearest nearest nearest_ranges closest4 nearest5
count_overlaps count_overlaps count_overlaps count_overlaps count_overlaps intersect6 count_overlaps
cluster cluster cluster cluster cluster_overlaps cluster
merge merge merge merge merge_overlaps merge reduce7
complement complement complement complement_ranges complement gaps8
subtract subtract subtract subtract subtract_overlaps subtract subtract
coverage coverage coverage coverage coverage coverage
expand expand expand extend extend_ranges slop resize
sort sort_bedframe sort sort sort_ranges sort sort
read_table read_table read_table read_bed read_bed BedTool read_bed

Note

  1. There is an overlap method in PyRanges, but its output is only limited to indices of intervals from the other Dataframe that overlap. In Bioframe's benchmark also join method instead of overlap was used.
  2. wa and wb options used to obtain a comparable output.
  3. Output contains only a list with the same length as query, containing hits to overlapping indices. Data transformation is required to obtain the same output as in other libraries. Since the performance was far worse than in more efficient libraries anyway, additional data transformation was not included in the benchmark.
  4. s=first was used to obtain a comparable output.
  5. select="arbitrary" was used to obtain a comparable output.
  6. -c flag used with intersect to count overlaps per feature.
  7. GenomicRanges exposes merge as reduce().
  8. GenomicRanges exposes complement as gaps().

Limitations

For now polars-bio uses int32 positions encoding for interval operations (issue) meaning that it does not support operation on chromosomes longer than 2Gb. int64 support is planned for future releases (issue).

Pileup operations

Per-base read depth computation from alignment files using CIGAR operations. Produces mosdepth-compatible coverage blocks.

Feature mosdepth samtools depth polars-bio
depth โœ… โœ… โœ…
import polars_bio as pb

# Compute per-base depth from a BAM file
df = pb.depth("alignments.bam").collect()

# With MAPQ filter (equivalent to samtools depth -q 20)
df = pb.depth("alignments.bam", min_mapping_quality=20).collect()

# Via SQL
df = pb.sql("SELECT * FROM depth('alignments.bam')").collect()

FastQC quality control

Streaming FastQC quality-control modules over FASTQ files (plain, .gz, or BGZF) in a single out-of-core pass. All 12 core modules are implemented and bit-exact against FastQC 0.12.1 (--nogroup), computed in parallel and merged, so results are identical regardless of the number of partitions.

Module Module Module
basic_stats per_base_quality per_seq_quality
per_base_content per_seq_gc per_base_n
seq_length overrepresented adapter_content
dup_levels per_tile_quality kmer_content
import polars_bio as pb

# One streaming pass computes every module; access each as a LazyFrame.
qc = pb.fastqc("reads_R1.fastq.gz")
qc.per_base_quality.collect()
qc.per_tile_quality.collect()
qc.summary().collect()          # PASS/WARN/FAIL status per module

# Compute only selected modules
qc = pb.fastqc("reads_R1.fastq.gz", modules=["basic_stats", "adapter_content"])

# Via SQL (tidy long-form output)
df = pb.sql("SELECT * FROM fastqc('reads_R1.fastq.gz')").collect()

Note

per_tile_quality and kmer_content reproduce FastQC's own subsampling (per-tile: 10% after the first 10k reads; kmer: 2% of reads, file-order dependent). Exact k-mer parity therefore requires a single-partition scan; the other ten modules are partition-invariant and exact on all reads. dup_levels/overrepresented use FastQC's 100k-unique observation cutoff, matching FastQC's estimate on high-diversity libraries.