Step 1: Preparing the Input

SweepLink does not read VCF files directly. It reads allele counts per population and timepoint, plus a small meta file describing the sampling design. The sweeplink-vcf2input script builds both from a VCF and a sample list, dropping sites that carry no information along the way.

What we start from

Two files in tutorial/data:

  • example.vcf.gz — the genotypes, all samples from all timepoints in one VCF.

  • samples.txt — the sampling design.

The sample list is a tab-separated file with three named columns:

# time in generations before present
sample       population      time_in_gen
HG_TP01_0017 Pop1    130
HG_TP01_0072 Pop1    130
HG_TP02_0097 Pop1    115
HG_TP02_0008 Pop1    115
...
  • sample must match a sample name in the VCF header. Anything listed here but missing from the VCF is reported and skipped.

  • population groups individuals. Use a single value if you have one population.

  • time_in_gen is the sampling time. Which direction it runs is your choice, declared with --time-direction below. This example data has time in generations before present.

Running the conversion

sweeplink-vcf2input \
    --vcf data/example.vcf.gz \
    --samples data/samples.txt \
    --time-direction bp \
    --ploidy diploid \
    --min-segregating-timepoints 2 \
    --max-missing-total 0.2 \
    --out-prefix doc

Inputs

--vcf data/example.vcf.gz

The genotypes. Only biallelic SNPs are used.

--samples data/samples.txt

The sample list shown above.

--time-direction bp

Our times are before present, so 130 is the oldest sample and 0 the most recent. SweepLink works forward in time, so the script flips the axis for you. Use forward instead if your times already increase toward the present.

--ploidy diploid

Counts both alleles of each individual. Use pseudo-haploid for low-coverage ancient DNA, where only one allele per individual is drawn.

Filtering

--min-segregating-timepoints 2

Keep a site only if the allele is segregating (\(0 < C < N\)) at two or more timepoints. A site seen segregating once carries almost nothing about a trajectory.

--max-missing-total 0.2

Drop sites missing more than 20% of their genotypes.

Tip

Filtering is optional — sweepLink is stable on unfiltered data. But uninformative sites cost the same compute as informative ones, and there are usually a lot of them, so filtering mostly buys you time.

Output

--out-prefix doc

Names the two output files: doc_alleleCounts.txt and doc_meta.txt.

What it prints

Loaded data (individuals per population per timepoint):
       t0  t15  t29  t34  t52  t60  t78  t100  t106  t117  t130  total
Pop1    2   10    4    4    8    6   14    17    50    26   100    241
total   2   10    4    4    8    6   14    17    50    26   100    241

Filtered out:
  monomorphic: 245
  too_few_seg_timepoints: 109
Wrote 413 loci to doc_alleleCounts.txt
Wrote meta file to doc_meta.txt

The table is worth a second look before moving on — it is the quickest way to catch a mis-specified sample list. Here all 241 individuals were matched and spread over 11 timepoints, and the sample sizes are very uneven: 2 individuals at the oldest timepoint against 100 at the most recent. That is typical of ancient DNA, and sweepLink handles it, but it does mean the oldest timepoints carry much less information.

Of the 767 usable sites in the VCF, 354 were dropped — 245 monomorphic across the whole dataset, 109 segregating at only one timepoint — leaving 413 loci.

The output files

Allele counts — one row per locus: chromosome, position, then derived/total for each population × timepoint. Columns run oldest to most recent:

-    -       time_130BP_Pop1 time_115BP_Pop1 time_101BP_Pop1 ...     time_0BP_Pop1
1    579     3/4     15/20   5/8     ...     129/200
1    740     0/4     0/20    0/8     ...     1/200

Missing data is written 0/0.

Meta — one row per group: label, forward time, population. Note the time column: the oldest sample (130 before present) has become forward time 0.

time_130BP_Pop1      0       Pop1
time_115BP_Pop1      15      Pop1
time_101BP_Pop1      29      Pop1
time_96BP_Pop1       34      Pop1
...

Next

With doc_alleleCounts.txt and doc_meta.txt in hand, continue to Step 2: Inference.