Oxbow Genomic Data I/O Library

repository·main·Indexed 41 days ago

https://github.com/abdenlab/oxbow

A genomic data I/O library that translates next-generation sequencing (NGS) file formats into Apache Arrow representations. It enables seamless integration of genomic data into Python, R, and Rust ecosystems, allowing conventional NGS files to be accessed as in-memory or larger-than-memory data frames. Version 0.8.1 supports sequence, alignment, variant call, interval feature, and UCSC BBI formats.

Tokens
53.3K
Snippets
188
Records
284
Agent score
51%

What's inside Oxbow

  1. Overview of Oxbow

    main

    Oxbow is a genomic data I/O library designed to model and translate next-generation sequencing (NGS) file formats into Apache Arrow representations. This allows genomic data to be used within the broader ecosystem of computational tools by providing access to conventional NGS files as in-memory or larger-than-memory data frames.

    Core functionality is implemented in Rust, with high-level bindings available for Python and R.

  2. Understand Oxbow coordinate conventions

    main

    Oxbow manages genomic coordinate systems to prevent off-by-one errors. It uses a two-character notation based on the base of the start and end coordinates:

    • "01": 0-based start, 1-based end (0-based, half-open). Used by BED, BigBed, and BigWig. Notation: [start, end).
    • "11": 1-based start, 1-based end (1-based, closed). Used by SAM, BAM, CRAM, VCF, BCF, GFF, and GTF. Notation: [start, end].

    Note that in both conventions, the end coordinate is numerically the same; only the start coordinate encoding changes. Oxbow defaults to the native convention of the file format being read.

  3. Understanding compression and indexing in Oxbow

    main

    Oxbow relies on specific compression and indexing patterns to provide efficient random access to genomic data:

    • BGZF (Blocked GNU Zip Format): A backwards-compatible "blocked" variant of GZIP. It allows for random access and indexing using companion index files (like TBI or CSI).
    • FASTA Indexing:
      • FAI indexes uncompressed FASTA records.
      • GZI is an additional file required to perform lookups in BGZF-compressed FASTA files.
    • CRAM Structure: CRAM is a hierarchical format organized into "containers" and "slices". Slices are the unit of random access. Slices consist of data "blocks" that support various encodings, including lossy ones. Note that reference-based CRAM compression requires the exact external reference sequences to decode sequence bases.
    • BigBed/BigWig: These binary formats support multiple resolutions and use deflate compression with an internal index for access.
  4. Understand Fragments and Partitions

    main

    Fragments

    Oxbow data sources are logically grouped into fragments.

    • A data source without random access (e.g., a simple stream) contains only a single fragment.
    • When you register range queries using .regions(), each query is mapped to a unique fragment. Each fragment generates its own independent stream of record batches.

    Dask Partitions

    When converting an Oxbow data source to a Dask data frame using .dd() or .to_dask(), oxbow maps its logical fragments to Dask partitions. Each partition is expected to be independently accessible and fit in memory.

    import ox
    
    # Single fragment (no regions defined)
    ds = ox.from_bam("data/sample.bam")
    print(ds.fragments())
    
    # Multiple fragments (one per region)
    ds_regions = ox.from_bam("data/sample.bam").regions(["chr1", "chr3", "chrX"])
    print(ds_regions.fragments())
    
    # Mapping fragments to Dask partitions
    df = (
        ox.from_bam("data/sample.bam")
        .regions(["chr1", "chrX", "chrY"])
        .dd()  # or .to_dask()
    )
    # Access a specific partition
    print(df.partitions[1].compute())
  5. Use BatchReaderDataset for Arrow-based data processing

    main
    The BatchReaderDataset class in oxbow.arrow is a high-level interface for working with datasets that can be read in batches, typically leveraging Apache Arrow. It provides a suite of methods for common data operations such as filtering, joining, sorting, and converting to different formats like Arrow Tables or batches. It is designed to handle large-scale data by allowing efficient scanning and batch iteration.
  6. Understanding the purpose of Oxbow

    main

    Oxbow is designed to alleviate the friction of the 'bioinformatic silo' by translating streams of records from conventional Next-Generation Sequencing (NGS) files into Apache Arrow representations on demand.

    Instead of using specialized, tightly-coupled bioinformatics toolsets that require complex and redundant I/O transformations, Oxbow allows you to treat NGS data as tabular/relational data. This enables you to use modern, general-purpose data technologies (which work directly on columnar Arrow representations with zero copying) for downstream analysis.

    Key capabilities include:

    • Interoperability: Makes NGS data accessible to a wide array of interchangeable data technologies.
    • Scalability: Supports datasets much larger than memory through streaming, lazy evaluation, and distributed computing.
  7. Oxbow package components and language bindings

    main

    Oxbow is organized as a multi-package monorepo with three primary components:

    1. rs-oxbow (oxbow/): The core Rust library providing parsing and streaming functionality.
    2. py-oxbow (py-oxbow/): Python bindings built using PyO3 and maturin.
    3. r-oxbow (r-oxbow/): R bindings built using rextendr (currently minimal and under development).

    All data I/O operations are performed in Rust, while Python and R users interact with high-level features exposed through these bindings.

  8. Build the oxbow Rust crate

    main

    You can build the oxbow crate using cargo. Navigate to the oxbow directory and run the build command. Use the --release flag for optimized non-debug builds.

    cd oxbow
    cargo build  # --release (for non-debug build)
  9. Set up the Oxbow (Rust + Python) development environment

    main

    Oxbow is a hybrid project where data I/O is handled in Rust and features are exposed via Python. To develop with the Python package (py-oxbow), you need Rust and the uv package manager.

    1. Install Rust using rustup.
    2. Install uv following the official instructions.
    3. Sync dependencies: Navigate to py-oxbow and run uv sync to create a virtual environment in py-oxbow/.venv containing all PEP 735-style dependency groups.
    # Install Rust
    curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
    
    # Setup Python dependencies
    cd py-oxbow
    uv sync
  10. Build and install the Rust-Python project

    main

    To build and install a local development version of the py-oxbow package into your virtual environment, use maturin via uvx.

    Use the --uv flag to ensure compatibility with the uv environment. For faster, non-debug builds, include the --release flag. After building, you can verify the installation by running uv run python and attempting to import oxbow.

    cd py-oxbow
    uvx maturin develop --uv
    
    # For a faster, non-debug build:
    uvx maturin develop --uv --release
    
    # Verify installation:
    uv run python
    >>> import oxbow as ox
  11. Get started with Oxbow

    main
    To begin using Oxbow for genomic data manipulation and high-performance analytics, follow the installation and quickstart guides available in the documentation. Oxbow is designed to bridge the gap between conventional genomic file formats and modern data analysis tooling.
  12. Install r-oxbow via remotes

    main

    To install the R interface for oxbow, you must first have a working Rust toolchain installed on your system.

    Windows Users: You must manually add the following Rust targets before installation:

    rustup target add x86_64-pc-windows-gnu
    rustup target add i686-pc-windows-gnu

    Once the Rust toolchain is configured, install the package using remotes::install_github or devtools::install_github specifying the r-oxbow subdirectory.

    remotes::install_github("abdenlab/oxbow", subdir="r-oxbow")