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.

IBS_example.sh — SLURM/local script for computing IBS neighbors
  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

COMPUTE_IBS

Path to the compiled computeIBSpbwt binary

BGEN_FILE

Phased BGEN v1.2 file for the chromosome of interest

SAMPLE_FILE

Oxford-format .sample file matching the BGEN

GENETIC_MAP

Eagle genetic map for the chromosome (download from Eagle website)

OUTPUT_FILE

Output path; use .tsv.gz for automatic gzip compression

FOCAL_BP

Base pair position at the center of the VNTR region (hg19: 160690000)

NUM_NEIGHBORS

Number of IBS neighbors per haplotype (recommended: 200)

THREADS

CPU threads; match to --cpus-per-task in the SLURM header

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