Skip to main content
Ctrl+K

cellink

  • Tutorials
    • DonorData basics: creating, syncing, slicing, and saving
    • Tutorial: Pseudobulk eQTL Analysis with cellink
    • Tutorial: eQTL Analysis with JaxQTL and TensorQTL using cellink
    • Tutorial: Annotating Genetic Variants with cellink
    • Tutorial: Rare Variant Association Testing with cellink
    • Tutorial: LD Clumping and Identifying Independent Signals with cellink
    • Tutorial: Colocalization Analysis - Linking eQTLs to GWAS Signals with cellink
    • Tutorial: Integrating GWAS with Single-Cell Data using cellink
    • Tutorial: Spatially Resolved GWAS Mapping with gsMap
    • Tutorial: eQTL Analysis with SAIGE-QTL using cellink
    • Tutorial: Using EHR Data as Donor-Level Input in cellink
    • Tutorial: Using the MILDataset and PyTorch DataLoader in cellink
    • Tutorial: Cell-Level LDSC analysis
    • Merging AnnData objects for cell-level LDSC (Duncan lab dataset)
    • Tutorial: MAGMA Gene-Set and Gene Property Analysis
    • Tutorial: sc-linker via cellink
    • Tutorial: Donor Effect Decomposition with LIVI using cellink
  • API
    • DonorData
      • cellink.DonorData
    • Preprocessing pp
      • cellink.pp.variant_qc
      • cellink.pp.cell_level_obs_filter
      • cellink.pp.donor_level_obs_filter
      • cellink.pp.donor_level_var_filter
      • cellink.pp.log_transform
      • cellink.pp.low_abundance_filter
      • cellink.pp.missing_values_filter
      • cellink.pp.normalize
    • Input-Output io
      • cellink.io.from_sgkit_dataset
      • cellink.io.read_plink
      • cellink.io.read_bgen
      • cellink.io.read_sgkit_zarr
      • cellink.io.read_pgen_zarr
      • cellink.io.stream_pgen_to_zarr
      • cellink.io.read_dd
      • cellink.io.read_h5_dd
      • cellink.io.read_zarr_dd
      • cellink.io.to_plink
      • cellink.io.write_variants_to_vcf
    • Tools tl
      • cellink.tl.get_snp_df
      • cellink.tl.run_favor
      • cellink.tl.run_snpeff
      • cellink.tl.run_vep
      • cellink.tl.add_vep_annos_to_gdata
      • cellink.tl.combine_annotations
      • cellink.tl.aggregate_annotations_for_varm
      • cellink.tl.run_burden_test
      • cellink.tl.run_skat_test
      • cellink.tl.beta_weighting
      • cellink.tl.subset_genomic_region
      • cellink.tl.subset_gene
    • External tools tl.external
      • cellink.tl.external.run_jaxqtl
      • cellink.tl.external.read_jaxqtl_results
      • cellink.tl.external.run_tensorqtl
      • cellink.tl.external.read_tensorqtl_results
      • cellink.tl.external.configure_saigeqtl_runner
      • cellink.tl.external.get_saigeqtl_runner
      • cellink.tl.external.make_group_file
      • cellink.tl.external.run_saigeqtl
      • cellink.tl.external.read_saigeqtl_results
      • cellink.tl.external.run_mixmil
      • cellink.tl.external.calculate_ld
      • cellink.tl.external.calculate_pcs
      • cellink.tl.external.configure_ldsc_runner
      • cellink.tl.external.munge_sumstats
      • cellink.tl.external.make_annot_from_bimfile
      • cellink.tl.external.make_annot_from_donor_data
      • cellink.tl.external.estimate_ld_scores_from_bimfile
      • cellink.tl.external.estimate_ld_scores_from_donor_data
      • cellink.tl.external.compute_ld_scores_with_annotations_from_bimfile
      • cellink.tl.external.compute_ld_scores_with_annotations_from_donor_data
      • cellink.tl.external.estimate_heritability
      • cellink.tl.external.estimate_celltype_specific_heritability
      • cellink.tl.external.estimate_genetic_correlation
      • cellink.tl.external.generate_gene_coord_file
      • cellink.tl.external.generate_sldsc_genesets
      • cellink.tl.external.get_magma_gene_loc
      • cellink.tl.external.preprocess_for_sldsc
      • cellink.tl.external.run_magma_pipeline
      • cellink.tl.external.run_magma_annotate
      • cellink.tl.external.run_magma_gene_analysis
      • cellink.tl.external.run_magma_gsa
      • cellink.tl.external.run_magma_gpa
      • cellink.tl.external.genesets_dir_to_entrez_gmt
      • cellink.tl.external.load_ensembl_to_entrez_map
      • cellink.tl.external.scores_to_gmt
      • cellink.tl.external.scores_to_covar
      • cellink.tl.external.format_gsmap_sumstats
      • cellink.tl.external.load_gsmap_results
      • cellink.tl.external.compute_celltype_programs
      • cellink.tl.external.compute_diseaseprogression_programs
      • cellink.tl.external.compute_nmf_programs
      • cellink.tl.external.compute_joint_nmf_programs
      • cellink.tl.external.JointNMFWrapper
      • cellink.tl.external.compute_escore
      • cellink.tl.external.run_sclinker_heritability
      • cellink.tl.external.compute_ld_scores_for_sclinker
      • cellink.tl.external.load_sclinker_heritability_results
      • cellink.tl.external.download_sclinker_references
      • cellink.tl.external.download_sclinker_enhancer_links
      • cellink.tl.external.load_roadmap_links
      • cellink.tl.external.load_abc_links
      • cellink.tl.external.load_gene_annotation
      • cellink.tl.external.genescores_to_abc_road_bedgraph
      • cellink.tl.external.genescores_to_100kb_bedgraph
      • cellink.tl.external.genescores_to_annotations
      • cellink.tl.external.bedgraph_to_snp_annotation
      • cellink.tl.external.check_and_patch_ldsc_parse_bug
      • cellink.tl.external.run_scdrs
      • cellink.tl.external.run_seismic
      • cellink.tl.external.run_seismic_torch
      • cellink.tl.external.SparseScore
      • cellink.tl.external.RegressionNLL
      • cellink.tl.external.prepare_scprs_data
      • cellink.tl.external.get_plink_commands_per_cell
      • cellink.tl.external.write_slurm_array_job
      • cellink.tl.external.get_disease_relevant_cells
      • cellink.tl.external.run_scprs_pipeline
      • cellink.tl.external.LIVIRunner
      • cellink.tl.external.configure_livi_runner
      • cellink.tl.external.get_livi_runner
      • cellink.tl.external.train_livi
      • cellink.tl.external.infer_livi
      • cellink.tl.external.run_livi_association_testing
      • cellink.tl.external.save_livi_results
      • cellink.tl.external.load_livi_results
    • Plotting
      • cellink.pl.locus
      • cellink.pl.manhattan
      • cellink.pl.qq
      • cellink.pl.expression_by_genotype
      • cellink.pl.volcano
    • Machine Learning ml
      • cellink.ml.MILDataset
      • cellink.ml.mil_collate_fn
      • cellink.ml.DonorMILModel
    • Association Testing at
      • cellink.at.acat_test
      • cellink.at.compute_acat
      • cellink.at.GWAS
      • cellink.at.Skat
    • Utils
      • cellink.utils.column_normalize
      • cellink.utils.gaussianize
      • cellink.utils.one_hot_encode_genotypes
      • cellink.utils.dosage_per_strand
    • Resources
      • cellink.resources.get_1000genomes
      • cellink.resources.get_1000genomes_grch38
      • cellink.resources.get_dummy_onek1k
      • cellink.resources.get_onek1k
      • cellink.resources.get_eqtl_catalog_dataset_associations
      • cellink.resources.get_eqtl_catalog_datasets
      • cellink.resources.get_gwas_catalog_studies
      • cellink.resources.get_gwas_catalog_study
      • cellink.resources.get_gwas_catalog_study_summary_stats
      • cellink.resources.liftover_gwas_summary_stats
      • cellink.resources.get_pgs_catalog_score
      • cellink.resources.get_pgs_catalog_scores
      • cellink.resources.get_1000genomes_ld_scores
      • cellink.resources.get_1000genomes_ld_weights
      • cellink.resources.get_1000genomes_plink_files
      • cellink.resources.get_1000genomes_frq
      • cellink.resources.get_1000genomes_hapmap3
      • cellink.resources.merge_1000g_plink_chromosomes
    • PGEN → AnnData Conversion (cellink-pgen)
  • Changelog
  • Contributing guide
  • References
  • .md

PGEN → AnnData Conversion (cellink-pgen)

Contents

  • Installation
  • Basic Usage
  • Loading the Output
  • Dense vs Sparse Storage
  • Chunking and Memory Control
  • Compression
  • Other Options
  • Output Structure

PGEN → AnnData Conversion (cellink-pgen)#

cellink-pgen converts one or more PLINK2 .pgen files into a single AnnData-compatible Zarr v3 store. It streams dosage data in variant blocks, keeping memory use bounded regardless of dataset size, and produces output directly readable by cellink.io.read_pgen_zarr.

Installation#

pgenlib is required and installed via the optional extra:

pip install cellink[pgen]

Basic Usage#

# Single file, dense matrix (common variants)
cellink-pgen input.pgen -o output.zarr

# Single file, sparse matrix (rare variants)
cellink-pgen rare.pgen -o rare.zarr --sparse

# Merge multiple PGEN files into one matrix (same samples, disjoint variant sets)
cellink-pgen rare.pgen common.pgen -o combined.zarr

When multiple files are provided, variants are concatenated column-wise. All files must contain the same samples in the same order — obs is taken from the first file’s .psam.

Loading the Output#

from cellink.io import read_pgen_zarr

adata = read_pgen_zarr("combined.zarr")
# X is Dask-backed for dense stores; trigger computation with:
X = adata.X.compute()

Dense vs Sparse Storage#

The choice affects both write strategy and how X is stored on disk.

Dense (default): Genotype blocks are streamed directly into a pre-allocated Zarr dataset. X is stored as a chunked int8 array and returned as a Dask-backed array — reads remain lazy.

cellink-pgen common.pgen -o common.zarr

Sparse: Each variant block is converted to a scipy.csr_matrix, accumulated in memory, then written via AnnData.write_zarr. Use this when variant density is low (e.g. rare variant sets), as it avoids storing large stretches of zeros.

cellink-pgen rare.pgen -o rare.zarr --sparse

Chunking and Memory Control#

Argument

Default

Description

--chunk-samples

4096

Zarr chunk size along the sample axis

--chunk-variants

2048

Zarr chunk size along the variant axis

--memory-limit

10.0

Max RAM per read block, in GB

The read block size (vblock) is computed as:

vblock = min(chunk_variants, floor(memory_limit_gb × 1024³ / n_samples), n_variants)

This means --memory-limit acts as a hard cap: no single pgenlib.read_range call will allocate more than the specified amount. Each block is written immediately to Zarr before the next is read, keeping the working set small.

Chunk sizes directly affect downstream Dask task graphs. Smaller chunks increase parallelism but add scheduling overhead; the defaults (4096 × 2048) are a reasonable starting point for biobank-scale data.


Compression#

Blosc with bitshuffle is applied to the dense Zarr dataset:

Argument

Default

Options

--compressor

zstd

zstd, lz4, zlib

--compression-level

7

1–9

Bitshuffle is particularly effective for low-cardinality integer arrays like dosage-encoded genotypes (values 0, 1, 2), often yielding better compression than byteshuffle at the same level.


Other Options#

Argument

Description

--max-variants N

Cap variants per input file (useful for testing)

--max-samples N

Cap samples taken from the .psam


Output Structure#

For dense mode, the Zarr store is written manually to keep X out of AnnData’s normal write path (which would load it into memory). The layout is AnnData-compatible:

output.zarr/
├── X/          ← chunked int8 Zarr array, encoding-type: "array"
├── obs/        ← DataFrame from .psam (index: FID_IID)
├── var/        ← DataFrame from .pvar
├── uns/
├── obsm/
├── varm/
├── obsp/
├── varp/
└── layers/

Metadata is consolidated with zarr.consolidate_metadata at the end, making subsequent opens faster.

For sparse mode, AnnData.write_zarr handles the full write after the CSR matrix is assembled.

previous

cellink.resources.merge_1000g_plink_chromosomes

next

Changelog

Contents
  • Installation
  • Basic Usage
  • Loading the Output
  • Dense vs Sparse Storage
  • Chunking and Memory Control
  • Compression
  • Other Options
  • Output Structure

By Jan Engelmann, Lucas Arnoldt, Eva Holtkamp

© Copyright 2026, Theislab..