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:
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))
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:
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
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.
samples (numpy.array) – Array of individual indexes
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.