Workflows (WDL)¶
The same pipeline as WDL workflows, for Cromwell (as on Verily Workbench) or
miniwdl. Each runs manifold-genetics in the published
container.
All of them, and their example inputs, are in wdl/.
| file | what it does |
|---|---|
wdl/manifold_genetics.wdl |
manifold-genetics pipeline as one task, for a cohort you already have |
wdl/aou_prepare.wdl |
All of Us, step 1: fetch a release and intersect it with HGDP+1KGP |
wdl/prepare.wdl |
any other biobank, step 1: the same, from PLINK files you already have |
wdl/analyse.wdl |
step 2, any prepared cohort: subsample, PCA, then 2-D PHATE, UMAP and PCA figures |
wdl/analyse_3d.wdl |
after analyse: 3-D PHATE, UMAP and PCA (HTML and MP4) from its PCA |
wdl/admixture.wdl |
after analyse, optional: Neural Admixture per experiment, and its figures on the published embeddings |
All of Us (Verily Workbench)¶
You need a controlled-tier workspace with the release attached, and a bucket of your own for results (Resources → New → Cloud Storage bucket).
- Add the workflows. Workflows → Add workflow → WDL →
https://github.com/MattScicluna/manifold_genetics, then pickwdl/aou_prepare.wdl; add again forwdl/analyse.wdl,wdl/analyse_3d.wdlandwdl/admixture.wdl. (Workflows added before they moved intowdl/point at the old root path; add them again.) -
Run
aou_prepareonce per release. It writes the prepared cohort to<output_dir>/prepared/.input value output_dire.g. gs://<bucket>/aou_v9workspace_cdr$WORKSPACE_CDRin any appcdr_storage_path$CDR_STORAGE_PATH(default: v9)reference_bed/bim/famthe HGDP+1KGP reference, population in the FID topmed_referenceoptional bravo-dbsnp-all.hrc_format.tab.gz; turns on the WRayner check against TOPMed, as the published preprocessing ran it -
Run
analysewithcohort_dir=<output_dir>/preparedand the sameoutput_dir. Each experiment writes<output_dir>/<name>/: PCA, embeddings, 2-D figures, metrics and logs. - Run
analyse_3dwith the sameoutput_dirfor the 3-D figures. It reads each experiment's PCA, soexperimentsmust name those folders. - Run
admixture(optional) with the samecohort_dirandoutput_dir. It writesoutputs/admixture/(Q matrices of the fit set for K = 2 to 10; of the whole cohort too withinfer_project, which needs about one byte per genotype of the cohort in memory) and colours every embedding already inoutputs/embeddings/by admixture. It runs on a GPU (gpu_type, defaultnvidia-tesla-t4) in the-gpuimage, so the workspace needs GPU quota.
The default experiments are the manuscript's: balanced (10,000 each of the
four largest groups plus everyone else) and geosketch_90k. Each is a name and
the arguments to subsample; a list of your own replaces
them. Keep the geosketch size close to the balanced set's, so the two fit sets
are comparable.
The embeddings are their own task, so with call caching a change to their
settings reruns only them and the figures. PHATE and UMAP are fit on the fit
set's 20 PCs, and the PCA figures show its first two (analyse) or three
(analyse_3d).
Workflow machines pull the image through the All of Us Docker Hub mirror
(us-central1-docker.pkg.dev/all-of-us-rw-prod/aou-rw-gar-remote-repo-docker-prod/mattscicluna/manifold-genetics:<tag>).
Set docker to a sha-<commit> or version tag: the mirror can keep serving
a stale image under a branch tag.
Follow the All of Us dissemination rules before sharing figures or counts.
The reference panel
aou_prepare needs an HGDP+1KGP reference restricted to the array's
positions. The public acquire hgdp panel is LD-pruned before
intersection and keeps too few array SNPs, and the one used so far is an
internal extract, so for now the step cannot be reproduced from outside
(#172).
Any biobank (UK Biobank, your own)¶
prepare.wdl replaces step 1 for a cohort you already have as GRCh38 PLINK
files, with chromosomes as chr1 or 1. It runs the same preprocess step as
aou_prepare, writes the same <output_dir>/prepared/, and analyse.wdl then
runs on it unchanged.
| input | value |
|---|---|
output_dir |
a bucket or a local path |
cohort_bed/bim/fam |
the biobank's genotypes |
cohort_labels |
CSV: sample_id plus the columns to colour by |
reference_bed/bim/fam |
HGDP+1KGP, restricted to the cohort's positions (below) |
reference_labels |
optional CSV: sample_id, Population, ...; default: population from the FID |
reference_has_chr_prefix |
true if the reference's chromosomes are chr1 |
topmed_reference |
optional bravo-dbsnp-all.hrc_format.tab.gz: turns on the WRayner check against TOPMed, as in aou_prepare; without it WRayner is skipped, as in the published UK Biobank preprocessing |
cohort_colormap, reference_colormap |
optional colormap JSONs that take precedence |
Labels with published colours (HGDP+1KGP populations and regions, UK Biobank
self_described_ancestry and superpopulations, All of Us race and ethnicity)
are drawn in them; any other value gets a generated colour.
The reference¶
The reference is the one input that differs between biobanks: the same
HGDP+1KGP samples, restricted to the positions on your array before any LD
pruning, so that pruning happens after the intersection. A panel pruned on its
own first keeps only a sample of positions, and few of them are on any given
array: CARTaGENE's GSA array shares 18,796 positions with the pruned panel,
below the 50,000 preprocess requires. Restrict an unpruned panel by position,
since variant IDs often differ (chr1:... against 1:...):
awk '{ sub(/^chr/, "", $1); print $1, $4, $4, $2 }' cohort.bim > positions.txt
plink --bfile hgdp1kgp_unpruned --extract range positions.txt --make-bed --out reference
A public build of that panel is #172.
UK Biobank, end to end¶
The published UK Biobank figures, rerun with these two workflows (miniwdl + Apptainer on a cluster, 486,748 samples):
prepare: the UK Biobank array with HGDP+1KGP at its positions, 5 minutes, giving 3,340 reference samples and 120,849 SNPs, as in the manuscript.analyse: the experiments inwdl/analyse.biobank.inputs.json:balanced(10,000 British, 5,000 Irish and everyone else, 59,264 samples) andgeosketch_60kto match. 3 h 20 on 16 CPUs and 128 GB, withpca_memory_gb100 andembed_memory_gb32; peak memory 118 GB while both experiments ran their PCA at once.geosketchtakes longer because it runs PCA twice: once on a random 100,000 to choose the sketch, then on the sketch.
"analyse.experiments": [
{"name": "balanced", "subsample_args": "--group 'self_described_ancestry=^British$:10000' --group 'self_described_ancestry=^Irish$:5000' --include-rest --seed 42"},
{"name": "geosketch_60k", "subsample_args": "--geosketch 60000 --seed 42"}
]
Each experiment's folder has PCA, the 2-D PHATE and UMAP embeddings and their
figures; analyse_3d with wdl/analyse_3d.biobank.inputs.json adds the 3-D
ones and the rotating videos (outputs/figures/embeddings_3d/*.mp4).
Outside Verily¶
Any WDL runner works. output_dir may be a local path, and the tasks then copy
results there instead of to a bucket:
miniwdl run wdl/prepare.wdl -i prepare.json
miniwdl run wdl/analyse.wdl -i analyse.json
miniwdl run wdl/analyse_3d.wdl -i analyse_3d.json
On a cluster without Docker, wdl/miniwdl.apptainer.cfg runs the same image
with Apptainer. Set its paths, and pull the image once on a node with internet,
as its comments show. Two of its settings matter:
allow_any_input = true:analyse.wdlreads files undercohort_dir(andanalyse_3d.wdlunderoutput_dir), which miniwdl otherwise refuses.cpu_maxandmemory_max: set them to the job's allocation. miniwdl otherwise schedules tasks against the whole node.
Then run both steps in one batch job, for example with SLURM: