IBS/IBD Neighbor Computation Example¶
This example demonstrates Stage 2 of the GRiD workflow: using computeIBSpbwt to generate the IBS neighbors file required by GRiD for haploid copy number estimation (Step 5).
The script automatically sources locus coordinates (chromosome and focal midpoint) derived during Stage 1 from data/pipeline_vars.sh.
1#!/bin/bash
2#SBATCH --job-name=grid_ibs
3#SBATCH --output=slurm/%x.out
4#SBATCH --error=slurm/%x.err
5#SBATCH --time=2-00:00:00
6#SBATCH --cpus-per-task=4
7#SBATCH --mem=100G
8
9# Stage 2 of 3 — compute IBS neighbors (needed for haploid CN estimation).
10# Submit after 01_prep_data.sh completes; sources data/pipeline_vars.sh for
11# CHR/FOCAL_BP rather than re-deriving them, so this can't disagree with
12# stage 1's locus coordinates.
13#
14# Usage: sbatch 02_run_ibs.sh (from the same working directory as stage 1)
15
16set -euo pipefail
17
18module load samtools
19
20NUM_NEIGHBORS=200
21while [[ $# -gt 0 ]]; do
22 case $1 in
23 --num-neighbors) NUM_NEIGHBORS="$2"; shift 2 ;;
24 -h|--help)
25 echo "Usage: $0 [--num-neighbors N]"
26 exit 0 ;;
27 *)
28 echo "Unknown argument: $1"
29 exit 1 ;;
30 esac
31done
32
33WORK_DIR="${WORK_DIR:-$(pwd)}"
34LOG_DIR="$WORK_DIR/logs"
35DATA_DIR="$WORK_DIR/data"
36OUTPUT_DIR="$WORK_DIR/output"
37QC_DIR="$WORK_DIR/qctool"
38mkdir -p "$DATA_DIR" "$LOG_DIR" "$OUTPUT_DIR" "$WORK_DIR/slurm" "$QC_DIR"
39
40THREADS="${SLURM_CPUS_PER_TASK:-$(nproc)}"
41
42timestamp() { date '+%Y-%m-%d %H:%M:%S'; }
43log() { echo "[$(timestamp)] $*" | tee -a "$LOG_DIR/IBS.log"; }
44
45download_with_retry() {
46 local url="$1" out="$2" attempt
47 for attempt in 1 2 3 4 5; do
48 if wget -q --tries=1 --timeout=60 -O "$out" "$url"; then
49 return 0
50 fi
51 rm -f "$out"
52 sleep $(( attempt * 3 + RANDOM % 3 ))
53 done
54 echo "ERROR: failed to download $url after 5 attempts" >&2
55 return 1
56}
57
58# --- Load locus coordinates written by 01_prep_data.sh ---
59VARS_FILE="$DATA_DIR/pipeline_vars.sh"
60if [[ ! -f "$VARS_FILE" ]]; then
61 echo "ERROR: $VARS_FILE not found — run 01_prep_data.sh first."
62 exit 1
63fi
64source "$VARS_FILE"
65
66if ! command -v "$WORK_DIR/qctool/qctool" &> /dev/null; then
67 log "Installing qctool..."
68
69 download_with_retry \
70 "https://zenodo.org/records/22307601/files/qctool.gz?download=1" \
71 "$QC_DIR/qctool.gz"
72
73 gunzip -f "$QC_DIR/qctool.gz"
74
75 chmod +x "$WORK_DIR/qctool/qctool"
76fi
77
78MISSING=()
79for cmd in "$WORK_DIR/qctool/qctool" wget samtools; do
80 command -v "$cmd" &>/dev/null || MISSING+=("$cmd")
81done
82if [[ ${#MISSING[@]} -gt 0 ]]; then
83 log "ERROR: missing required tools: ${MISSING[*]}"
84 exit 1
85fi
86
87COMPUTE_IBS="$WORK_DIR/computeIBSpbwt"
88if [[ ! -f "$COMPUTE_IBS" ]]; then
89 log "Downloading computeIBSpbwt binary..."
90 download_with_retry \
91 "https://raw.githubusercontent.com/mhujoel/STRs/main/cpp_files/computeIBSpbwt" \
92 "$COMPUTE_IBS"
93 chmod +x "$COMPUTE_IBS"
94fi
95
96PHASED_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.chr${CHR}.filtered.SNV_INDEL_SV_phased_panel.vcf.gz"
97GENETIC_MAP_URL="https://alkesgroup.broadinstitute.org/Eagle/downloads/tables/genetic_map_hg38_withX.txt.gz"
98
99LPA_VCF="$DATA_DIR/1kGP_chr${CHR}_LPA_phased.vcf.gz"
100BGEN_FILE="$DATA_DIR/1kGP_chr${CHR}_LPA_phased.bgen"
101SAMPLE_FILE="$DATA_DIR/1kGP_chr${CHR}_LPA_phased.sample"
102GENETIC_MAP="$DATA_DIR/genetic_map_hg38_chr${CHR}.txt"
103OUTPUT_FILE="$DATA_DIR/ibs_neighbors_chr${CHR}.tsv.gz"
104
105# --- Stream LPA region from the 1000G phased VCF ---
106if [[ ! -f "$LPA_VCF" ]]; then
107 log "Streaming LPA region from 1000G phased VCF..."
108 tabix -h "$PHASED_VCF_URL" "$REGION" | bgzip > "$LPA_VCF"
109 tabix -p vcf "$LPA_VCF"
110 find "$WORK_DIR" -maxdepth 1 -name "*.tbi" ! -path "${LPA_VCF}.tbi" -delete
111 log "LPA phased VCF ready: $LPA_VCF"
112else
113 log "LPA phased VCF already present — skipping."
114fi
115
116# --- Convert phased VCF -> BGEN v1.2 ---
117if [[ ! -f "$BGEN_FILE" ]]; then
118 log "Converting phased VCF to BGEN v1.2..."
119 "$WORK_DIR/qctool/qctool" \
120 -g "$LPA_VCF" \
121 -og "$BGEN_FILE" \
122 -os "$SAMPLE_FILE" \
123 -ofiletype bgen_v1.2 \
124 -bgen-bits 16 \
125 -bgen-permitted-input-rounding-error 0 \
126 >> "$LOG_DIR/qctool.log" 2>&1
127 log "BGEN file ready: $BGEN_FILE"
128else
129 log "BGEN file already present — skipping."
130fi
131
132# --- Download + decompress + filter Eagle genetic map ---
133# The map's chrom column is bare (e.g. "6"), not "chr6" — filtering on
134# "chr${CHR}" here would silently match nothing and produce a header-only
135# file, so this must stay as the bare chromosome number.
136if [[ ! -f "$GENETIC_MAP" ]]; then
137 log "Downloading Eagle hg38 genetic map..."
138 wget -q -O - "$GENETIC_MAP_URL" \
139 | gunzip \
140 | awk -v c="${CHR}" 'NR==1 || $1==c' \
141 > "$GENETIC_MAP"
142 log "Genetic map ready: $GENETIC_MAP"
143else
144 log "Genetic map already present — skipping."
145fi
146
147# --- Run computeIBSpbwt ---
148log "Computing IBS neighbors..."
149log " CHR=$CHR FOCAL_BP=$FOCAL_BP NEIGHBORS=$NUM_NEIGHBORS THREADS=$THREADS"
150
151"$COMPUTE_IBS" \
152 "$CHR" \
153 "$FOCAL_BP" \
154 "$BGEN_FILE" \
155 "$SAMPLE_FILE" \
156 "$GENETIC_MAP" \
157 "$NUM_NEIGHBORS"\
158 "$THREADS" \
159 "$OUTPUT_FILE"
160
161log "IBS neighbors written to: $OUTPUT_FILE"
162log "Next: submit 03_generate_config_and_run.sh"
Key Parameters & Environment Variables¶
The coordinates and variables used by 02-run-ibs.sh are sourced dynamically from Stage 1 (data/pipeline_vars.sh) or can be passed via command line options:
Parameter / Variable |
Description |
|---|---|
|
Number of IBS neighbors per haplotype (default: |
|
Target chromosome (e.g., |
|
Base pair position at center of VNTR (e.g., LPA KIV-2 midpoint in hg38, exported by Stage 1). |
|
Path to the auto-downloaded or local |
|
1000 Genomes high-coverage phased VCF URL streamed for the target region via |
|
Eagle hg38 genetic map auto-downloaded and filtered for chromosome |
|
Compressed output path ( |
Usage¶
Submit to SLURM after 01-prep-data.sh completes:
sbatch examples/02-run-ibs.sh
Override the default number of neighbors:
sbatch examples/02-run-ibs.sh --num-neighbors 100
Passing Output to GRiD¶
Stage 3 (03-run-grid.sh) automatically detects data/ibs_neighbors_chr${CHR}.tsv.gz upon completion and embeds the path directly into config.yaml:
compute_haploid_genotypes:
run: True
output_file_prefix: "haploid_genotypes"
ibs_output: "data/ibs_neighbors_chr6.tsv.gz"
min_neighbors: 1
max_neighbors: 10
n_iters: 100
method: "ibs"