Time series analysis

fwdpy11 allows populations to be analyzed during the course of a simulation. Any valid callable type may be used. The most useful such type will be a class defining __call__ to update member data, as was done in introexample.

There are built-in types to handle common scenarios:

class fwdpy11.RandomAncientSamples

Preserve random samples of individuals at predetermined time points.

This type randomly samples diploids at predetermined time points. For example, if we wanted to randomly sample 10 diploids every N generations for the first 9N generations of a simulation:

import fwdpy11
import numpy as np

N = 1000
seed = 42
samplesize = 10
r = fwdpy11.RandomAncientSamples(seed, samplesize, np.arange(0, 10*N, N))
__init__(self: fwdpy11._fwdpy11.RandomAncientSamples, seed: int, samplesize: int, timepoints: numpy.ndarray[uint32])None

When implementing your own callables, the arguments to the type must be of the following form:

def timeseries_fxn(pop, sampler):
    pass

The first argument is the population itself. The second is an instance of the following class:

class fwdpy11.SampleRecorder

Allow recording of ancient samples during simulations with tree sequences.

Instances of this type are never created by a user. Rather, they are generated internally and passed to user-defined callable types. These types are responsible for passing in the indexes of individuals to be preserved as samples in the tree sequences. Two member functions exist for such recording. The first function adds samples one at a time:

add_sample(self: fwdpy11._fwdpy11.SampleRecorder, individual_index: int)None

Add the index of an individual to the list of samples

Parameters

individual_index (int) – The index of the individual to preserve

The second is more efficient, adding in “batch” mode via a numpy array with dtype uint32:

assign(self: fwdpy11._fwdpy11.SampleRecorder, samples: numpy.ndarray[uint32])None

Add a list of individuals to the list of samples.

Parameters

samples (numpy.array) – Array of individual indexes

The numpy.dtype of samples must be np.uint32.

The following is essentially pseudocode to illustrate the process:

import fwdpy11
s = fwdpy11.SampleRecorder()
s.add_sample(10)
s.assign(np.arange(10, dtype=np.uint32))

The important thing to keep in mind is that user-defined callable types can do essentially anything. For example, in introexample, summaries of trait variation were also recorded. When recording samples to preserve, “anything goes”. For example, you could pick samples with the top x and the lowest y fitnesses. You could pick individuals based on their genetic load, whether or not they carry a specific variant, etc.. It is up to you.