Manipulating the SFS

Manipulating the SFS#

Parsing yields Spectrum and Spectra objects. A Spectrum holds a single site-frequency spectrum; a Spectra holds a named collection, one entry per type, such as the neutral and selected spectra produced by a stratified parse. Both expose the operations needed to inspect and reshape spectra, including indexing, grouping, folding, resampling, serialisation, and plotting. The examples below build spectra directly to illustrate these operations, but in practice they are usually returned by the Parser.

import sfsutils as su
import matplotlib.pyplot as plt

# create spectra with two subtypes and two types
spectra = su.Spectra.from_spectra({
    "subtype1.type1": su.Spectrum.standard_kingman(10) * 1,
    "subtype1.type2": su.Spectrum.standard_kingman(10) * 2,
    "subtype2.type1": su.Spectrum.standard_kingman(10) * 3,
})

# plot spectra
spectra.plot();
../../_images/e43f72790389a459d21a3f86c9de6b6b7b0c8a68ddb10ba21b81e0a5ebadb25a.png

We access types by their index from which we obtain a Spectrum object.

sfs: su.Spectrum = spectra["subtype1.type1"]

sfs.plot();
../../_images/45e30c938111e62fade1e7b9605ef95248f7aa8f0913541b4daa6f7af0ec6b1b.png

We can also use wildcards to access multiple types at once.

spectra["subtype1.*"].plot();
../../_images/9e9d55e56b4214b740f157930ca31181de93434ac16c0b742aa8b172a998715d.png

Grouping#

To get rid of the subtypes, we can merge the spectra over the specified number of groups.

spectra.merge_groups(1).plot();
../../_images/595ee7c263fe10f4922cce37ecf33113a8cfcb377924edeaf11597ea8e8a1165.png

All subtypes for each type are merged into a single spectrum by adding them up.

Serialization#

We can also save the spectra to a file and restore them again.

spectra.to_file("out/spectra.csv")

spectra2 = su.Spectra.from_file("out/spectra.csv")

Prefixing#

Here we prefix the spectra with a string to distinguish them and then combine them into a single spectra object.

spectra.prefix('original').combine(spectra2.prefix('restored')).plot();
../../_images/897608d5f4b98990bb1cc520f165eb632c85197dad13b4912f04a6d49c52e8c7.png

For a complete reference of the available methods and properties, see Spectra and Spectrum.

Folded spectra#

Spectrum and Spectra objects can also be folded by collapsing the bins corresponding to the derived allele counts onto the bins corresponding to the ancestral allele counts. Folding discards information, which is particularly noticeable when beneficial mutations are present. However, folded spectra are easier to obtain, and are robust to misspecification of the ancestral state, which is often unknown. A spectrum reports whether it has been folded through its is_folded() method.

# create subplots
fig, (ax1, ax2) = plt.subplots(ncols=2, figsize=(7, 3))

# fold spectra object
spectra.fold().plot(ax=ax1)

# fold spectrum object
sfs.fold().plot(ax=ax2);
../../_images/147e40252394a610ac0db086743c1f56fac0b3e1f8c6d732766813b5f4d3e80c.png