Skip to content
marimaroPublic

About

SelHap: haplotype-based sample selection for pangenomes

Resources

Stars

2 stars

Watchers

0 watching

Forks

Latest commit

 

History

6 Commits

Folders and files

Repository files navigation

SelHap: haplotype-based sample selection for pangenomes

This is the documentation of SelHap, a pipeline to help selection of new accessions for pangenome projects. It was developed in the research group Domestication Genomics at the Leibniz Institute of Plant Genetics and Crop Research (IPK) Gatersleben.

logo

Typical use case

Selecting N new genomes that maximize haplotype novelty relative to an existing pangenome.

Given a set of candidate samples and a background dataset, SelHap ranks accessions based on their contribution of novel haplotypes.

Introduction

SelHap is a pipeline designed to identify new accessions that contribute novel haplotypes to an existing pangenome. As pangenomes mature, selecting additional genomes that add genuinely new sequence information becomes increasingly challenging. SelHap addresses this problem by prioritizing samples based on haplotype novelty relative to an existing pangenome dataset.

SelHap builds on the output of IntroBlocker (Wang et al., 2022), a tool that assigns ancestral haplotype groups (AHGs) to genomic bins to investigate fine-scale ancestry and evolutionary history. Using these haplotype clusters, SelHap identifies genomic segments that are not yet represented in a background dataset and ranks candidate samples according to their contribution of novel haplotypes. This differs from traditional approaches that maximize global genetic diversity rather than conditional novelty.

The pipeline requires a VCF file derived from whole-genome shotgun (WGS) data that includes both the existing pangenome accessions (background) and candidate samples. IntroBlocker is first used to cluster haplotypes across genomic bins. SelHap then processes these clusters to generate a ranked list of samples carrying novel haplotypes relative to the background dataset. In addition, SelHap can generate visualizations showing where these novel haplotypes occur across the genome.

Beyond pangenome expansion, SelHap can also be used to explore haplotype frequencies between groups of samples, for example when comparing domesticated and wild germplasm.

figure SelHap
Figure 1. Graphical overview of the SelHap pipeline. bg1-bg4: background samples. s1 and s2: samples being tested.

Requirements

SelHap requires the following R packages:

  • data.table

  • ggplot2

  • reshape2

1. Preparing the VCF file

SelHap requires a VCF file derived WGS data that includes both the background samples (e.g. existing pangenome accessions) and the candidate samples to be evaluated. All samples should be aligned to the same reference genome before variant calling to ensure consistent genomic coordinates.

The VCF should contain high-quality SNPs distributed across the genome, as these markers are used by IntroBlocker to define haplotype clusters. Standard filtering to remove low-quality variants and sites with excessive missing data is recommended.

The filtered VCF can then be used as input for IntroBlocker.

2. Running IntroBlocker

Instructions on how to run IntroBlocker are available here. Choose window size and SNP threshold according to the species genome size. For our barley project we used 2 Mb windows, cluster_thr=500 and smooth_thr=400. We recommend changing sample IDs to remove any special character other than "-".

3. Running SelHap

SelHap should be run in R, check library requirements above. Just load SelHap_v.1.0.R script to use it. Commands can be run with test data available on demo folder and further adapted to each use case, mainly changing input files, chrtotal, and number_of_samples.

3.1. Preparing environment

The following step loads the input files and generates the processed haplotype tables used by SelHap. These tables are derived from the IntroBlocker output and serve as the main input for the three SelHap modes (bin-haps, freq-haps, and select-by-region).

# load SelHap
source("SelHap_v1.0.R")

# input files
chr_list <- fread("chr_list.txt", header=F)
background <- fread("all_samples_pangenome.txt", header=F)[[1]]
tables <- read_tables(path=".")

# generate tables to be used as input for the other functions.
tables <- process_tables(tables, background, chrtotal=7)

chr_list is a text file with the list of chromosome names, such as "chr1", "1", or "chr1H", and so on.

background is a text file with sample names as they are in the VCF and IntroBlocker output, one per line. It will define which samples will be used as the background for the analysis. This could be the pangenome accessions, for example.

read_tables() will scan the selected path and read one file per chromosome with matching name like "chrName*.grp", or specifically "chr1H.grp".

3.2. Bin-haps mode

Binary-haps mode will select samples based on their presence or absence in the background. This mode is run iteratively, so the chosen sample from iteration 1 will become part of the background until it reaches number of selected iterations (number_of_samples).

selected_samples <- compute_bin_haps(tables = tables,
	background = background,
	chrtotal = 7,    		# total number of chromosomes
	out_prefix = "example_run_bin", # prefix for output file, optional
	number_of_samples = 5, 		# number of samples to selected, default=1
	chr_subset = NULL)

chr_subset can be NULL (all chromosomes), a vector of chromosome names from chr_list, or chromosome numbers/indices only.

Outputs bin-haps

Files are written using the prefix defined in out_prefix.

In most cases, users will only need the out_prefix_selected_samples_<n>_iterations.txt file, which is also saved to the object selected_samples (table below).

For plotting, the object bin_tables, saved also to out_prefix_binary_tables_first_iteration.Rds, should be used.

Table 1. Selected samples output after running bin-haps with 5 iterations for barley demo data.
Sample chr1H chr2H chr3H chr4H chr5H chr6H chr7H sum_stretches

core150-HOR-15254

180

50

736

8250

286

2941

2455

14898

core150-HOR-16149

312

202

71

480

198

11

4918

6192

core150-HOR-18300

3

66

45

8

22

5855

51

6050

core150-HOR-1048

51

50

894

58

91

3529

33

4706

core150-HOR-14557

124

2593

325

5

123

52

227

3449

Sum of stretches are calculated according to haplotype novelty. Each haplotype is compared to the background and gets 1 for absent in background and 0 for present in background. Missing values are not computed. To account for long novel haplotypes, we apply run-length encoding (RLE) and square the resulting segment lengths to weight longer haplotypes more strongly, so samples with longer novel haplotypes receive a higher score.

Scores for samples that were not selected tend to diminish across iterations, since the background is being fed with novel haplotypes.

Objects returned in the R environment
selected_samples

Variable defined when calling compute_bin_haps(). A table containing the samples selected by SelHap and their total number of novel haplotype stretches per chromosome. This object is also written to disk as a text file out_prefix_selected_samples_<n>_iterations.txt.

bin_tables

Binary haplotype tables corresponding to the first iteration. This is the object used for plotting. It is also written to disk as a Rds file out_prefix_binary_tables_first_iteration.Rds.

Files written to the output directory
out_prefix_selected_samples_<n>_iterations.txt

List of samples selected and per-chromosome stretches after n iterations (same as selected_samples).

out_prefix_binary_tables_first_iteration.Rds

Binary haplotype tables from the first iteration, where all samples are compared to the original background.

out_prefix_binary_tables_last_iteration.Rds

Binary haplotype tables from the final iteration, showing remaining samples. The background includes all previously selected samples.

out_prefix_all_stretches.txt

Table containing the number of novel haplotype stretches per sample across all chromosomes comparing to the initial background.

out_prefix_stretches_iteration_<n>.txt

Table containing the number of novel haplotype stretches per sample across all chromosomes for the remaining samples after the final iteration (i.e. relative to the final background).

Plotting results

When bin-haps is run iteratively, the background changes at each iteration as newly selected samples are added. Because of this, binary haplotype tables generated in later iterations are calculated relative to different backgrounds. To ensure that all samples are plotted relative to the same background, SelHap saves the binary haplotype tables (bin_tables) from the first iteration, where all samples are compared to the original background. These tables should be used for plotting.

# plotting all samples from 1st iteration
plot_results(bin_tables = bin_tables,
	plot_selected = F,
	out_prefix = "all_samples")

# plotting the 20 selected samples relative to the initial background (1st iteration table)
samples_to_plot <- selected_samples[, .(Sample)]
plot_results(bin_tables = bin_tables,
	plot_selected = T,
	selected = samples_to_plot,
	out_prefix = "20_selected_samples")

plot_selected is a logical value to plot all samples (F) from the input table or just a subset (T).

selected must be declared if plot_selected=T. List of sample names to be plotted (default=NULL).

3.3. Freq-haps mode

Frequency-haps mode assigns a score from 0 to 10 representing how frequent a haplotype is in the background dataset. Haplotypes absent from the background receive a score of 0, whereas more common haplotypes receive higher values up to 10. These scores are summed and ranked at the end. The higher the final score, the more novel/exclusive haplotypes the sample has.

Unlike bin-haps, this mode is not run iteratively and therefore the ranking and ordering of samples may differ from the iterative selection.

This mode is useful for exploring haplotype frequency patterns between groups of samples, for example when comparing domesticated and wild germplasm or different breeding pools.

freq_haps <- compute_freq_haps(tables = tables,
	background = background,
	chrtotal = 7,
	out_prefix = "example_run_freq",
	chr_subset = NULL)

Outputs freq-haps

Running freq-haps produces two objects in the R environment, which are also written to disk:

freq_haps

table containing all samples and their haplotype frequency scores. Saved as out_prefix_all_sample_scores_freq_haps.txt.

freq_tables

list of per-chromosome frequency tables used to compute the scores. Saved as out_prefix_freq_tables.Rds.

Table 2. Selected samples output after running compute_freq_haps with 5 iterations for barley demo data.
Sample chr1H chr2H chr3H chr4H chr5H chr6H chr7H sum_scores

core150-HOR-10702

972

1011

768

1199

775

547

948

6220

core50-HOR-14439

992

998

776

1180

781

518

963

6208

core150-HOR-16358

995

1012

789

1186

592

509

992

6075

core50-HOR-12184

979

1014

697

1163

746

540

910

6049

core50-HOR-17077

815

1000

764

1180

776

513

971

6019

Plotting results

# plot all samples
plot_results_freq(freq_tables = freq_tables,
	plot_selected = F,
	out_prefix = "all")

# plot specific samples
samples_to_plot <- freq[, .(Sample)]
plot_results_freq(freq_tables = freq_tables,
	plot_selected = T,
	selected = samples_to_plot,
	out_prefix = "selected_freq")

freq_tables is generated by compute_freq_haps.

plot_selected is a logical value to plot all samples (F) from the input table or just a subset (T).

selected must be declared if plot_selected=T. List of sample names to be plotted (default=NULL).

3.4. Select-by-region mode

This mode identifies samples carrying novel haplotypes within a specific genomic region using the bin_tables object generated by compute_bin_haps(). Because it is not iterative, the tables should be generated with only one iteration, ensuring that all samples are compared to the same background.

# for the same region in all chromosomes
regall <- select_by_region(bin_table = bin_tables,
	coordmin = 180, # start coordinate of the region
	coordmax = 300, # end coordinate of the region
	prop = 0.6) # minimum proportion of bins in the selected region that must contain novel haplotypes

# chromosome specific regions
reg1 <- select_by_region(bin_table = bin_tables,
	coordmin = 126,
	coordmax = 286,
	prop = 0.5,
	chr_subset = 1) # evaluated chromosome

reg2 <- select_by_region(bin_table = bin_tables,
	coordmin = 221,
	coordmax = 381,
	prop = 0.5,
	chr_subset = 2)

merged_regions <- rbind(reg1,reg2)
unique(merged_regions$Sample)

coordmin = start coordinate of the region.

coordmax = end coordinate of the region.

prop = minimum proportion of bins in the selected region that must contain novel haplotypes.

chr_subset = chromosome(s) where the region is evaluated. If omitted, the region is evaluated across all chromosomes.

About

SelHap: haplotype-based sample selection for pangenomes

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages