grave is a Nextflow workflow for aligning, genotyping, and variant calling ancient or modern short-reads against a pangenome graph. A simplified summary of workflow steps is found here. A Wiki with further detail is available here.
Typically, the inputs to grave are a pangenome graph in .gbz format and a .csv samplesheet specifying FASTQ files (paired-end or merged/single-end).
Note
To compare the outcomes of graph versus linear reference-based alignment methods, grave can also be run in linear mode, taking a FASTA assembly instead of a graph.
Workflow outputs are described here.
More information on genotyping and variant calling is found here.
It is recommended to construct the graph with Minigraph-Cactus. Before doing so, read this section.
- Install Pixi:
curl -fsSL https://pixi.sh/install.sh | sh - Clone the Workflow repository:
git clone https://github.com/NBISweden/grave.git - Run
cd grave && pixi install
Note
The pixi project contains two environments:
default: installed with pixi install. This lacks apptainer (e.g. for systems with an existing Apptainer installation).
apptainer: installed with pixi install -e apptainer. This provides an Apptainer installation.
- At minimum,
gravecan be run withNextflowand eitherApptainer,Singularity, orDockerinstalled in$PATH - However, it is recommended to run it via
pixi pixiis a drop-in replacement forconda, andgraveuses it to install its basic dependencies.pixienvironments have an editable manifest file, thepixi.toml- Solved environments also have a
pixi.lockfile, which fixes the versions of all dependencies including transitive ones. The lockfile in this repository represents an environment that has been tested on Linux systems. - Installed
pixienvironments are found in the hidden folder.pixi/envs pixiwill automatically install an environment it lacks, if implied by another command (e.g.,pixi run -e apptainer ...will install theapptainerenvironment if it is not found).- You can run commands in a
pixienvironment by prefixing them withpixi run(or in a specific environment withpixi run -e <environment>). - Alternatively you can enter a software environment with
pixi shell(or a specific environment withpixi shell -e <environment>), similar toconda activate <environment> - To delete an environment:
rm -rf .pixi/envs/<environment_name>
-
To run a test with provided data:
pixi run test-apptainer -
Or using Docker:
pixi run test-docker
Tip
All pixi run commands use the default environment. To specify the apptainer environment:
pixi run -e apptainer test-apptainer
-
graveaccepts three types of reference:filtered_graph,unfiltered_graph, orlinear(i.e., FASTA assembly). -
Graphs should be in
.gbzformat, such as those produced by Minigraph-Cactus, a workflow within the Cactus package. Graph indexes are not required -gravewill create the necessary indexes for ancient and/or modern input samples. -
When using
Minigraph-Cactusfor graph construction, keep input assembly contig headers simple (see the official guidance here), and without special characters.
-
A filtered graph is one with depth filtering applied, i.e., nodes not represented in at least
depthhaplotypes are removed from the graph. Typically this is set to around 10% of the number of haplotypes (i.e.,40 pseudohaploid assembliesor20 phased assemblies->depth 4). -
The
MiniGraph-Cactusoption--giraffegenerates a graph filtered to depth 2. Depth is adjusted with the--filterparameter, e.g.:--giraffe --filter 10 -
The resulting graph can be provided to
gravewith--reference graph.d10.gbz --reference_type filtered_graph -
The cost of depth filtering is that rarer variants are lost from the graph. This should be considered when users are building a graph from relatively divergent assemblies, or when some constituent species have fewer haplotypes than others (e.g., an outgroup has a single haplotype, while the ingroup has many).
Important
- For samples with high coverage (e.g., 20X) and high purity in terms of endogenous content, the current best practice is to use an unfiltered graph. With this approach, K-mers from the reads are used to sample representative haplotypes from the graph, and reads are aligned to the subset.
- For samples with degraded, short, and low coverage endogenous content, plus high levels of contamination, filtered graphs are likely to be preferable, as we expect the K-mer-based subsampling to underperform.
- Running in unfiltered graph mode utilises K-mer profiling of the reads to sample representative haplotypes from the graph for mapping, read more here and here.
Important
See the above section, users should consider (or test) whether an unfiltered graph is appropriate for their samples.
-
To build an unfiltered graph, run
MiniGraph-Cactuswith option:--haplo(--giraffeis not required). -
The clipped, unfiltered graph can be provided to
gravewith--reference graph.gbz --reference_type unfiltered_graph
Complete a samplesheet.csv file, detailing file system paths to your reads. The layout is shown below:
Tip
The table below is an example. The file provided to grave must be in .csv format
| sample_id | library_id | repeat_number | sample_type | merged | fastq1 | fastq2 |
|---|---|---|---|---|---|---|
| ancientHuman1 | 1 | 1 | ancient | false | /path/to/read1.fq.gz | /path/to/read2.fq.gz |
| ancientHuman1 | 1 | 2 | ancient | false | /path/to/read1.fq.gz | /path/to/read2.fq.gz |
| ancientHuman1 | 2 | 1 | ancient | false | /path/to/read1.fq.gz | /path/to/read2.fq.gz |
| modernHuman7 | 1 | 1 | modern | false | /path/to/read1.fq.gz | /path/to/read2.fq.gz |
| mergedInput | 1 | 1 | ancient | true | /path/to/merged.fq.gz |
-
sample_id: unique sample identifier -
library_id: unique library identifier -
repeat_number: repeat number of the library -
sample_type: sample is ancient or modern - Note: this affects how the sample will be processed -
merged: whether the reads have already been merged (e.g., some ancient samples) -
fastq1: relative or absolute path to the first FASTQ -
fastq2: relative or absolute path to the second FASTQ
-
While in many cases defaults are sufficient, custom parameters can be set by editing a
params.ymlfile, and providing it on the command line when you execute the workflow (-params-file params.yml). -
Use
pixi run helpto see available parameters and their descriptions. -
An important parameter is
--steps, a string specifying which pipeline stages to run, e.g., (--steps 'index,preprocess'only indexes the input and preprocesses the reads). Some steps have their own dependencies, butgravewill notify the user immediately when an invalid combination is provided. The default is to run all possible steps for a typical graph reference. -
A selection of key parameters are expanded on below.
Important
The graph aligner vg giraffe uses a seed, cluster, chain, and extend strategy, with two important parameters: K-mer length (k) and window length (w). During graph indexing, minimisers are calculated from haplotype paths, by sliding across length w and taking the sequence (minimiser) of length k with the smallest hash value. The seeding stage of alignment involves computing exact matches between these minimisers and reads. Proximate seeds in the graph are clustered, clusters are chained together, and high-scoring chains serve as the starting point for extension.
Users should keep in mind that reads shorter than k+w-1 cannot be aligned, as they are too short for minimiser computation. Furthermore, with very short reads (~30 bp) users may notice fewer high quality alignments (MAPQ 30+) - this is expected if there are many comparably scoring chains entering extension, thus many comparably scoring mapping positions for a read.
To address these issues, grave uses different k and w defaults for modern and ancient reads:
Modern samples are run with giraffe defaults, emphasising higher specificity (k = 29, w = 11).
For aDNA reads, a reduced k and w results in a low-specificity, high-density index - relying on chaining to discriminate good matches from spurious ones. The grave aDNA defaults (k = 15, w = 3) balance performance across 30-70 bp reads, though a MAPQ filter of 30 is recommended to filter out alignments from contaminants. Users may find that adjusting these parameters for their particular dataset can improve performance, see the table below for general guidance.
Suggested further reading: Rubin et al., 2025, NAR Genomics and Bioinformatics. As the authors note, there is no single best setting for k and w in the aDNA context, as it depends on several factors related to the graph and reads.
Comparison of alignment parameters
| Alignment tool | |--- | Accurate | reads per | million | ---| | |--- | Inaccurate | reads per | million | ---| |
|---|---|---|---|---|---|---|---|---|---|---|
| Read length* | 30 | 40 | 50 | 60 | 70 | 30 | 40 | 50 | 60 | 70 |
grave: k-13/w-3 |
516,840 | 660,570 | 749,380 | 797,680 | 831,130 | 2,980 | 4,430 | 4,270 | 4,160 | 5,290 |
grave: k-15/w-3 |
459,420 | 654,470 | 754,550 | 803,160 | 837,050 | 2,790 | 4,420 | 4,910 | 3,980 | 4,840 |
grave: k-15/w-5 |
354,410 | 627,050 | 744,380 | 797,360 | 831,850 | 3,330 | 4,610 | 4,970 | 4,150 | 5,040 |
grave: k-19/w-3 |
396,080 | 603,760 | 740,410 | 805,890 | 841,830 | 6,910 | 4,600 | 5,150 | 4,500 | 4,910 |
grave: k-19/w-5 |
410,240 | 578,510 | 724,250 | 797,790 | 836,140 | 8,750 | 5,350 | 5,250 | 4,830 | 5,000 |
bwa aln: -l 16500 -n 0.01 -o 2** |
558,200 | 560,550 | 654,450 | 684,310 | 740,200 | 6,910 | 2,830 | 3,470 | 3,160 | 3,950 |
*~100k read pairs were generated per fragment length with NGSNGS from a related assembly not present in the benchmarking graph (sheep). Unmapped reads were removed and MAPQ 30 was applied.
**The bwa linear reference was the same used as the graph backbone (GCF_016772045.2).
Comparison of alignment run time
- 5 million reads per length were aligned using 48 CPUs
bwa alntargeted the sheep linear reference genomegiraffetargeted a sheep pangenome graph, and used thegravedefault indexing settings (k= 15,w= 3)
- NVIDIA Parabricks offers GPU-accelerated versions of a number of popular genomics tools, including
vg giraffe - This is an experimental feature in
graveselected with--gpu_giraffeand using thegpuprofile - The default resource request is for 1 GPU. To specify GPU number and/or type, a config file can be provided on the command-line, e.g.:
nextflow main.nf -profile gpu,<institution> -params-file params.yml -c gpu_configuration.config
process {
withName: 'GPU_GIRAFFE' {
accelerator = [ type: 'h100', request: 2 ] // 2x h100 GPUs
}
}
Important
Limitations:
- Only NVIDIA GPUs are supported, and the institutional config must be configured for GPU requests.
Parabricksupdates less frequently thanvg, thus outputs between the implemented versions may not be identical.- Some graph indexes are not compatible between the two tools and must be recomputed, due to underlying
vgversion differences. Parabricks 4.7.1surjects directly to BAM, disabling genotyping withvg call, which uses GAM.Parabricks 4.7.1does not support custom alignment scoring, such as mismatches/gap opens/gap extensions.gravedoes not support GPU-acceleratedgiraffefor multi-reference graphs. Please request it if you need it.
-
Minigraph-Cactusrequires at least one reference sample, usually the most contiguous reference assembly, e.g.:cactus-pangenome --reference GRCh38 -
If your graph has a single reference sample, you can skip this section.
-
Paths through the reference sample are called reference paths. Unless configured otherwise,
gravewill assume a single reference sample, and use rational defaults that assume the same, for examplesurjectwill transform GAM alignments to linear BAM relative to all reference paths in the graph. If there is more than one reference sample in the graph, this will cause undesirable outputs in certain steps, and errors in others. -
Therefore, if your graph was built with multiple reference samples, e.g.:
cactus-pangenome --reference GRCh38 chimp gorilla, it is required to rungravewith--multiple_references, and to provide one or more.pathsfiles. -
Each
.pathsfile contains a list of the reference paths in one reference sample, with one path name per line. -
The name of the
.pathsfile matters: the prefix must match a reference sample name provided in theseqFileofMinigraph-Cactus, and the suffix must be.paths, e.g.:GRCh38.paths,chimp.paths, andgorilla.paths
Tip
vg is packaged in the pixi environment, to see the reference samples in your graph run: pixi run vg paths --reference-paths --metadata -x myGraph.gbz | cut -f3 | tail -n+2 | sort | uniq
For a list of all reference path names from, for example GRCh38, run: pixi run vg paths --reference-paths --metadata -x myGraph.gbz | tail -n+2 | awk '$3 == "GRCh38"' | cut -f1 > GRCh38.paths
- For each
.pathsfile provided,gravewill run pipeline steps relative to that sample separately from the others, e.g.,surjectwill produce a separate.bamfile per reference sample, such that surjectingunknownSimian.1.gamtochimp.pathsandgorilla.pathswill produce:
unknownSimian.1.chimp.bam
unknownSimian.1.gorilla.bam
Example of how to run a local test (not recommended for production runs)
pixi run -e apptainer nextflow main.nf -profile apptainer,test -params-file params.yml
Running at scale (e.g., on SLURM cluster)
-
It is usually good practice to run
gravevia atmuxorscreensession rather than directly on the login node. An editable shell script that will do this for you is available inbin/slurm_submission.sh -
Institutional profiles are available via
nf-corefor many major HPC centres, see here. The example command below configuresgravefor the Dardel cluster in Stockholm, Sweden. -
When running on a cluster using the
slurmjob scheduler, ensure you provide a project allocation number using the--projectparameter. This can be on the command line or via theparams.ymlfile.
pixi run nextflow main.nf -profile pdc_kth -params-file params.yml --project example-allocation-12345
Tip
By default results are stored in the results directory. Exact outputs depend on the settings used
| Output directory | Description |
|---|---|
| 01_pipeline_info | Package versions, run parameters, and Nextflow trace reports (if set) |
| 02_reference | Reference statistics and reference FASTA files extracted from graphs with Pan-SN headers + index |
| 03_read_qc | Read QC reports |
| 04_mapped_reads | Mapped reads (library level GAM/BAM, surjected/merged/deduplicated BAM, alignment statistics, failed samples) |
| 05_post_mortem_damage | Post-mortem damage profiles (only for samples with the ancient metadata tag) |
| 06_genotyping | Genotyping outputs directly from the graph, and per sample |
| 07_variant_calling | Variant calling outputs per sample |
Tip
The workflow also computes graph indexes and snarls, stored in folders alongside the input graph (detected on repeat runs)
Tip
grave outputs BAM files surjected to reference assemblies in the graph, therefore users can use these in custom downstream tools
vg deconstructproduces a VCF file with a line for every snarl (bubble) in the graph. Allele information (reference vs alt) is taken from paths in the graph, read more here.
vg callgenotypes graph variants present in each mapped sample (i.e., no novel variant calling), read more here.- It takes GAM files as input, and therefore users should note that no deduplication is done prior to genotyping, see here.
Freebayesis integrated ingrave, read more here.
DeepVariantis integrated ingrave(currently recommended for human input data only), read more here.
-
gravecan be run in linear reference mode, mapping reads against a single FASTA reference instead of a graph. -
Ancient DNA alignment will be run with
BWA aln(-l 16500 -n 0.01 -o 2) and modern DNA withBWA MEM(default settings). -
To configure linear mode, set the parameter
reference_typetolinear, and provide a FASTA reference with thereferenceparameter.

