Skip to content

Latest commit

 

History

2 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

magenpy LD Browser

A standalone JavaScript reader and browser UI for the Zarr hierarchy produced by magenpy.LDMatrix. The folder has no coupling to the Python package and can be moved to its own repository later.

The reader understands magenpy's compact CSR-like representation:

matrix/
  data       strict upper-triangle correlations
  indptr     row offsets
metadata/
  snps, a1, a2, maf, bp, cm, ldscore
root attrs   Chromosome, Sample size, Genome build, LD estimator, ...

It uses Zarrita for lazy, chunk-aware access to Zarr v2 and v3 stores. Integer LD values are dequantized using the same scale as magenpy.

Run the browser

Requires Node.js 20.19 or newer.

cd ld_browser
npm install
npm run dev

Open the URL printed by Vite. You can select a local .zarr directory or Zarr ZIP (the files stay in the browser), or enter an hf://, s3://, or HTTP(S) source.

In browsers that support showDirectoryPicker(), directory-backed Zarr stores are read lazily through a read-only filesystem handle. Other browsers fall back to the webkitdirectory file selector. The handle-based picker requires HTTPS or a trusted local development origin such as localhost.

npm test
npm run build

The normal test suite is offline. To additionally check the live public UKB archive on Hugging Face:

LD_BROWSER_LIVE_TEST=1 npm test

JavaScript API

import { LDMatrix } from "./src/LDMatrix.js";

const ld = await LDMatrix.fromUrl("https://example.org/chr_22.zarr/");
await ld.validate();

console.log(ld.summary());
console.log(await ld.get("rs123", "rs456"));
console.log(await ld.getRow("rs123", { symmetric: true, returnIndices: true }));

const upper = await ld.denseBlock(1000, 1100, { symmetric: false });
const symmetric = await ld.denseBlock(1000, 1100);
const product = await ld.dot(new Float64Array(ld.nSnps).fill(1));
const scores = await ld.computeLdScores();

Hugging Face and S3

fromUri() accepts the same Hugging Face URI form as huggingface_hub. It translates the URI to the Hub download endpoint and opens the nested chr_N group used by the magenpy archives:

const ukb = await LDMatrix.fromUri(
  "hf://datasets/shz9/ukb-ld/EUR/chr_22.zip",
);

// Pin a branch, tag, or full commit after the repository name.
const pinned = await LDMatrix.fromUri(
  "hf://datasets/shz9/ukb-ld@18d7b11873dbccd9ba463004f4e48e0dcb46f04b/EUR/chr_22.zip",
);

// Private or gated repositories can use a read token.
const privateLd = await LDMatrix.fromHuggingFace(uri, { token: hfToken });

Public S3 stores use virtual-hosted HTTPS URLs. The default region is us-east-2, matching magenpy's Python S3 reader:

const s3Ld = await LDMatrix.fromUri(
  "s3://my-public-bucket/ld/EUR/chr_22.zarr",
  { region: "eu-west-2" },
);

// Path-style S3-compatible service, such as MinIO or institutional storage.
const compatible = await LDMatrix.fromS3("s3://bucket/ld/chr_22.zarr", {
  endpoint: "https://objects.example.org",
  pathStyle: true,
});

Browser sources must allow CORS. Remote ZIPs must also support HEAD and byte-range requests. Private S3 stores require pre-signed URLs or a custom Zarrita fetchOptions.fetch function that applies AWS SigV4 signing.

Node.js also has a local-path entry point:

import { fromPath } from "magenpy-ld-browser/node";

const directory = await fromPath("./chr_22.zarr");
const zipped = await fromPath("./chr_22.zip");

LDMatrix.fromStore(store) accepts any Zarrita-compatible readable store. This is useful for S3 gateways, reference stores, authenticated fetch wrappers, or embedding the library in another application.

Supported operations

  • Lazy metadata and upper-triangle row reads
  • Numeric-index and rsID lookup
  • Pairwise correlations with implicit symmetry and unit diagonal
  • BP-range selection with the native upper triangle shown by default; symmetrization mirrors the cached block without another store read
  • CSV export of the current heatmap (unmaterialized lower-triangle cells remain blank)
  • Boolean/index masks and comma/newline-delimited SNP filtering
  • Hosted UKB ancestry and chromosome presets
  • Side-by-side comparison of up to four same-chromosome matrices from any mix of local directories, local ZIPs, hosted presets, and custom cloud sources
  • Variant metadata display including stored LD scores
  • Interactive tagging-variant discovery from comma/newline-delimited rsIDs using an r² threshold, with CSV export
  • Order-aware LD pruning of a supplied variant set using an r² threshold, with CSV export
  • Streaming matrix-vector multiplication
  • Corrected or uncorrected LD-score calculation
  • Greedy LD pruning and tagging-variant discovery
  • SNP-table generation and structural validation
  • Async row iteration

After a matrix opens, the browser presents three analysis modes: regional LD visualization, variant pruning, and tagging-variant discovery. The latter two run against the primary matrix. Their sparse computations read correlation chunks in batches and do not construct a dense chromosome-wide matrix.

The implementation is intentionally read-only. Constructing or mutating an LD store remains the responsibility of magenpy/Python, where validation and quantization behavior are already established.

About

Linkage disequilibrium (LD) browser: Explore LD patterns at genome-wise scale

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages