Step 3: Results

Step 2’s inference has finished. Two things to do with it: look at the signal along the genome, and turn it into a list of loci under selection.

Note

What counts as “under selection”? By default, every one of the 100,000 MCMC samples must agree on the sign of s — no sample fell in a neutral state. That is deliberately strict; later on this page shows how to relax it and why the default is what it is.

The evidence and the landscape of selection

sweeplink-plot --prefix doc

That writes doc_selection.png. Nothing else is needed — the script reads the run’s settings out of doc.parameters.

Two-panel figure: evidence for selection and the landscape of |s| along two chromosomes. Background loci alternate grey and blue by chromosome, with a red dashed threshold line in the top panel; loci under selection are marked in red in the bottom panel.

Our scan. Chromosome 1 is flat, i.e. is neutral; everything is on chromosome 2, which is where the sweep was simulated.

Two-panel figure: evidence for selection and the landscape of |s| along two chromosomes. Background loci alternate grey and blue by chromosome, with a red dashed threshold line in the top panel; loci under selection are marked in red in the bottom panel.

Our scan. Chromosome 1 is flat, i.e. is neutral; everything is on chromosome 2, which is where the sweep was simulated.

The top panel is the evidence. Background loci are coloured only by which chromosome they are on (alternating grey and blue — no other meaning to that colour). The threshold is a red dashed line, all loci that are equal or above it, should be considered as “affected by selection”.

The bottom panel is the effect size of selection. The shaded area is the posterior mean of \(|s|\) at every locus — the magnitude of selection, tinted to match each chromosome’s colour above. Red dots mark the loci that passed the threshold.

Read together: the top panel says where there is something, the bottom says how strong it is.

Why the evidence axis is not a plain probability

The natural thing to plot would be the posterior probability itself. It does not work, because the posterior saturates:

50th percentile   0.00618
75th percentile   0.85172
90th percentile   0.99999
95th percentile   0.99999

The top 10% of loci all sit at the same value. With 100,000 MCMC samples, a locus where every sample agrees cannot be distinguished from another where every sample agrees — the resolution stops at one sample in 100,000. On a plain 0–1 axis they would all be crushed into the top sliver.

So the axis plots \(-\log_{10}(1-P)\) directly, which spreads the interesting range out into an ordinary, readable scale instead of crushing it into a sliver.

This is also why the reported posterior is never exactly 1. One pseudo-count is held on the neutral state, so a locus supported by all 100,000 samples reads \(100000/100001 = 0.99999\), not 1 — which keeps the axis finite instead of needing to plot infinity.

Tip

--region 2 zooms both panels to one chromosome, and --show opens the figure in an interactive window instead of writing a file. --out doc.svg gives a vector figure — best for a dataset this size, and what the figures on this page are. On a full genome, use PNG with --dpi 300 instead: a vector file stores one element per locus, so it grows with the data. For the rest — themes, direction markers — see sweeplink-plot.

The population size

We can also plot a posterior distribution of the inferred population size:

sweeplink-plot-posteriors --prefix doc
N:
  Pop1         82,899  [10**mean(log10 N)]
    median 58,653   IQR 27,781 - 175,700   95% 10,884 - 3,816,212
    range  4,821 - 265,842,000   sd 0.6618 (on log10)   n = 10,000
Violin plot of the posterior of N, on a log10 scale, showing a long right tail.

The posterior of N. Log10(N) by default — pass --linear for a raw N axis, though the tail above makes that much harder to read.

Violin plot of the posterior of N, on a log10 scale, showing a long right tail.

The posterior of population size N. It is in log-scale by default — pass --linear for a linear axis, though the tail above makes that much harder to read.

82,899 — the mean on the natural scale, 10^mean(log10 N) — is what the second round below fixes N at.

Extract loci under selection

sweeplink-extract --prefix doc --out-prefix doc_r2
Read 413 loci from 'doc_s_statePosteriors.txt' (100000 MCMC samples each;
selecting where at most 0 disagree, posterior >= 0.99999).

Selected 45 of 413 loci (18 positive, 27 negative).
  doc_r2_alleleCounts.txt
  doc_r2_meta.txt
  doc_r2_selected.txt

Second round: N fixed at the estimate of the first run, linkage off.
  Pop1: N = 82899 (from 10000 pooled samples)

  sweeplink infer \
      --counts doc_r2_alleleCounts.txt \
      --meta doc_r2_meta.txt \
      --mu_a_A 1e-8 \
      --N 82899 --log10N.update false \
      --linkage false \
      --out doc_r2

45 of 413 loci, and every one of them on chromosome 2 — which is where the sweep was simulated. Not one locus on chromosome 1 passed.

doc_r2_selected.txt lists them, including a posterior mean of s itself (signed — negative for the negative-direction loci):

chr  pos     direction       mean_s  samples_supporting      samples_against posterior       run
2    8126    negative        -0.0220707      100000  0       0.99999 doc
2    11896   negative        -0.0302666      100000  0       0.99999 doc
2    12639   negative        -0.0312808      100000  0       0.99999 doc
...

Note

Both directions show up around a sweep, and that is expected rather than a problem. As the selected haplotype rises it drags linked variants with it; a variant that happens to sit on the other haplotype is driven down, and shows up as negative selection. That is why 27 of the 45 are negative. The two-round procedure sharpens the estimates but does not try to separate the causal variant from its hitchhikers.

What counts as “under selection”

The default is strict: every MCMC sample must agree on the sign of s. No sample fell in a neutral state. Our experiments found this gives the best accuracy, so it is what you get with no arguments.

To relax it, say how many samples may disagree:

sweeplink-extract --prefix doc --out-prefix doc_loose --max-samples-against 5000

That keeps 85 loci instead of 45. The same threshold can also be written as a probability (--min-posterior 0.95) or in the evidence panel’s own units (--min-evidence 1.3) — all three select exactly the same 85 loci here. Pass whichever you used to sweeplink-plot as well, so the line in the figure matches the shortlist.

sweeplink-extract covers all three forms, the --direction filter, and the traps in --min-posterior.

Why N is fixed at 82,899

Note the line about N:

Pop1: N = 82899 (from 10000 pooled samples)

That value is \(10^{\text{mean}(\log_{10}N)}\) over the run’s MCMC samples, not the mean of N itself. The MCMC samples log10N, so N is strongly right-skewed and its arithmetic mean sits far out in the tail — doc_meanVar.txt reports N_Pop1 as 794,906, nearly ten times the 82,899 used here.

Warning

The second round treats N as a known, fixed value. The first round’s own posterior for N is genuinely uncertain — see Step 4: Refining for how much — so the second round’s estimates of s look more precise than the analysis as a whole justifies. Keep that in mind when reading them.

We already saw the shape of that skew above: the tail reaching past 10,000,000 is exactly what drags the mean so far from where almost all of the posterior actually sits.

sweeplink-plot-posteriors becomes more useful once you have several runs to compare — pass --prefix (or --dirs) more than one value, as you would for a dataset split by chromosome, and add --per-chromosome to see each run’s own violin alongside the pooled one, which is a quick way to check whether they actually agree. --params kappa nu mu (or betaMean betaESS) adds the linkage model’s own parameters to the figure — off by default, and skipped automatically wherever the run’s settings held them fixed (as they are here, with linkage on and a uniform prior).

Next

The three files written by sweeplink-extract are the input for Step 4: Refining.