IBS/IBD Neighbor Computation Example¶
This example shows how to run computeIBSpbwt to produce the IBS neighbors file
required by GRiD Step 5 (haplotype inference). The script targets LPA KIV-2 on
chromosome 6 in hg19, but the same pattern applies to any locus — adjust
CHR, FOCAL_BP, and the matching BGEN/genetic-map files accordingly.
Before running, compile computeIBSpbwt.cpp and obtain the required input files.
See the Computing IBS/IBD Neighbors page for full instructions.
1#!/bin/bash
2
3set -euo pipefail
4
5module load samtools
6
7NUM_NEIGHBORS=200
8FOCAL_BP="" # LPA KIV-2 region center, eg 160,626,361
9while [[ $# -gt 0 ]]; do
10 case $1 in
11 --neighbors)
12 NUM_NEIGHBORS="$2"; shift 2 ;;
13 --focal-bp)
14 FOCAL_BP="$2"; shift 2 ;;
15 -h|--help)
16 echo "Usage: $0 [--neighbors N]"
17 exit 0 ;;
18 *)
19 echo "Unknown argument: $1"
20 exit 1 ;;
21 esac
22done
23
24# Paths and parameters
25WORK_DIR="${WORK_DIR:-$(pwd)}"
26LOG_DIR="$WORK_DIR/logs"
27DATA_DIR="$WORK_DIR/data"
28OUTPUT_DIR="$WORK_DIR/output"
29mkdir -p "$DATA_DIR" "$LOG_DIR" "$OUTPUT_DIR"
30
31THREADS="${SLURM_CPUS_PER_TASK:-$(nproc)}"
32
33timestamp() { date '+%Y-%m-%d %H:%M:%S'; }
34log() { echo "[$(timestamp)] $*" | tee -a "$LOG_DIR/IBS.log"; }
35
36download_with_retry() {
37 local url="$1"
38 local out="$2"
39 local attempt
40
41 for attempt in 1 2 3 4 5; do
42 if wget -q --tries=1 --timeout=60 -O "$out" "$url"; then
43 return 0
44 fi
45 rm -f "$out"
46 sleep $(( attempt * 3 + RANDOM % 3 ))
47 done
48
49 echo "ERROR: failed to download $url after 5 attempts" >&2
50 return 1
51}
52
53# Dependency check
54MISSING=()
55for cmd in qctool wget samtools; do
56 command -v "$cmd" &>/dev/null || MISSING+=("$cmd")
57done
58if [[ ${#MISSING[@]} -gt 0 ]]; then
59 log "ERROR: missing required tools: ${MISSING[*]}"
60 log " qctool: https://www.well.ox.ac.uk/~gav/qctool_v2/"
61 log " samtools: conda install -c bioconda samtools"
62 exit 1
63fi
64
65COMPUTE_IBS="$WORK_DIR/computeIBSpbwt"
66if [[ ! -f "$COMPUTE_IBS" ]]; then
67 log "Downloading computeIBSpbwt binary..."
68 download_with_retry \
69 "https://raw.githubusercontent.com/mhujoel/STRs/main/cpp_files/computeIBSpbwt" \
70 "$COMPUTE_IBS"
71 chmod +x "$COMPUTE_IBS"
72fi
73
74# 1000 Genomes public URLs
75PHASED_VCF_URL="https://ftp.1000genomes.ebi.ac.uk/vol1/ftp/data_collections/1000G_2504_high_coverage/working/20220422_3202_phased_SNV_INDEL_SV/1kGP_high_coverage_Illumina.chr6.filtered.SNV_INDEL_SV_phased_panel.vcf.gz"
76GENETIC_MAP_URL="https://alkesgroup.broadinstitute.org/Eagle/downloads/tables/genetic_map_hg38_withX.txt.gz"
77REGIONS_FILE_URL="https://raw.githubusercontent.com/caterer-z-t/GRiD/main/files/734_possible_coding_vntr_regions.IBD2R_gt_0.25.uniq.txt"
78
79# Parameters
80# Fetch static inputs
81if [[ ! -f "$DATA_DIR/regions.txt" ]]; then
82 log "Downloading VNTR regions file..."
83 download_with_retry \
84 "$REGIONS_FILE_URL" \
85 "$DATA_DIR/regions.txt"
86fi
87
88read -r CHR START END < <(awk '$7=="LPA" {print $1, $2, $3; exit}' "$DATA_DIR/regions.txt") || true
89if [[ -z "${CHR:-}" || -z "${START:-}" || -z "${END:-}" ]]; then
90 log "ERROR: Could not parse LPA coordinates from regions.txt"
91 exit 1
92fi
93REGION="chr${CHR}:${START}-${END}"
94
95PHASED_VCF="$DATA_DIR/1kGP_chr6_phased.vcf.gz"
96LPA_VCF="$DATA_DIR/1kGP_chr6_LPA_phased.vcf.gz"
97BGEN_FILE="$DATA_DIR/1kGP_chr6_LPA_phased.bgen"
98SAMPLE_FILE="$DATA_DIR/1kGP_chr6_LPA_phased.sample"
99GENETIC_MAP="$DATA_DIR/genetic_map_hg38_chr6.txt"
100OUTPUT_FILE="$DATA_DIR/ibs_neighbors_chr6.tsv.gz"
101
102# Download 1000G phased VCF for chr6
103if [[ ! -f "$LPA_VCF" ]]; then
104 log "Streaming LPA region from 1000G phased VCF..."
105
106 # Fetch index alongside to enable remote tabix streaming
107 download_with_retry \
108 "${PHASED_VCF_URL}.tbi" \
109 "${PHASED_VCF}.tbi"
110
111 # Pull only the LPA window
112 tabix -h "$PHASED_VCF_URL" "$REGION" \
113 | bgzip > "$LPA_VCF"
114 tabix -p vcf "$LPA_VCF"
115
116 rm -f "${PHASED_VCF}.tbi"
117
118 log "LPA phased VCF ready: $LPA_VCF"
119else
120 log "LPA phased VCF already present — skipping."
121fi
122
123# Phase 2 — Convert phased VCF → BGEN v1.2
124if [[ ! -f "$BGEN_FILE" ]]; then
125 log "Converting phased VCF to BGEN v1.2..."
126 qctool \
127 -g "$LPA_VCF" \
128 -og "$BGEN_FILE" \
129 -os "$SAMPLE_FILE" \
130 -ofiletype bgen_v1.2 \
131 -bgen-bits 16 \
132 -bgen-permitted-input-rounding-error 0 \
133 >> "$LOG_DIR/qctool.log" 2>&1
134 log "BGEN file ready: $BGEN_FILE"
135else
136 log "BGEN file already present — skipping."
137fi
138
139# Download Eagle genetic map for hg38
140if [[ ! -f "$GENETIC_MAP" ]]; then
141 log "Downloading Eagle hg38 genetic map..."
142 download_with_retry \
143 "$GENETIC_MAP_URL" \
144 "$GENETIC_MAP"
145 log "Genetic map ready: $GENETIC_MAP"
146else
147 log "Genetic map already present — skipping."
148fi
149
150# Phase 4 — Run computeIBSpbwt
151log "Computing IBS/IBD neighbors..."
152log " CHR=$CHR FOCAL_BP=$FOCAL_BP NEIGHBORS=$NUM_NEIGHBORS THREADS=$THREADS"
153
154"$COMPUTE_IBS" \
155 "$CHR" \
156 "$FOCAL_BP" \
157 "$BGEN_FILE" \
158 "$SAMPLE_FILE" \
159 "$GENETIC_MAP" \
160 "$NUM_NEIGHBORS"\
161 "$THREADS" \
162 "$OUTPUT_FILE"
Key Parameters¶
Edit the Paths and Parameters sections at the top of the script before submitting:
Variable |
Description |
|---|---|
|
Path to the compiled |
|
Phased BGEN v1.2 file for the chromosome of interest |
|
Oxford-format |
|
Eagle genetic map for the chromosome (download from Eagle website) |
|
Output path; use |
|
Base pair position at the center of the VNTR region (hg19: |
|
Number of IBS neighbors per haplotype (recommended: |
|
CPU threads; match to |
Usage¶
Submit to SLURM:
sbatch IBS_example.sh
Or run locally:
bash IBS_example.sh
Passing Output to GRiD¶
Once complete, point to the output file in your GRiD config:
compute_haploid_genotypes:
run: True
output_file_prefix: "haploid_genotypes"
ibs_output: "path/to/ibs_neighbors_chr6.tsv.gz"
min_neighbors: 1
max_neighbors: 10
n_iters: 100