Genetic maps#
Note
The lists of objects described here are passed to the recregions
parameter when initializing instances of fwdpy11.ModelParams
.
New in version 0.3.0: The methods described here replace a soon-to-be deprecated approach using fwdpy11.Region
.
Changed in version 0.12.0: Added ability to restrict crossover positions to discrete values.
The following example uses fwdpy11.PoissonInterval
to model two genomic regions of equal length.
The first region, spanning \([0, 5)\), has a mean of \(2 \times 10^{-3}\) crossovers per generation.
The second region, spanning [5, 10), has half as many crossovers per generation.
import fwdpy11
recregions = [
fwdpy11.PoissonInterval(beg=0, end=5, mean=2e-3),
fwdpy11.PoissonInterval(beg=5, end=10, mean=1e-3),
]
The number of breakpoints in each \([beg, end)\) interval is Poisson distributed with the given mean. The position of each breakpoint is uniform (and continuous) on \([beg, end)\).
These classes also allow us to specify breakpoints at a specific position with a specific probability.
The next example sets up 4 genomic regions, each 10 “units” long. Within each region, the mean number of breakpoints (per diploid, per generation) is \(1e-3\).
Between each region, a single recombination occurs with probability of
one-half, meaning that each region is assorting independently (50 cM
between each region).
NLOCI = 4
LOCUS_LENGTH = 10
RECRATE_PER_LOCUS = 1e-3
LOCUS_BOUNDARIES = [
(i, i + LOCUS_LENGTH) for i in range(0, NLOCI * LOCUS_LENGTH, LOCUS_LENGTH)
]
recregions = [fwdpy11.PoissonInterval(*i, RECRATE_PER_LOCUS) for i in LOCUS_BOUNDARIES]
for i in LOCUS_BOUNDARIES[:-1]:
recregions.append(fwdpy11.BinomialPoint(i[1], 0.5))
for i in recregions:
print(i)
fwdpy11.PoissonInterval(beg=0, end=10, mean=0.001, discrete=False)
fwdpy11.PoissonInterval(beg=10, end=20, mean=0.001, discrete=False)
fwdpy11.PoissonInterval(beg=20, end=30, mean=0.001, discrete=False)
fwdpy11.PoissonInterval(beg=30, end=40, mean=0.001, discrete=False)
fwdpy11.BinomialPoint(position=10, probability=0.5, discrete=False)
fwdpy11.BinomialPoint(position=20, probability=0.5, discrete=False)
fwdpy11.BinomialPoint(position=30, probability=0.5, discrete=False)
As an aside, this example is not creating objects in order by their positions. Such ordering is not required.
Beginning in version 0.12.0
, it is possible to restrict crossover positions to integer values.
For the examples given above, crossover positions are floating-point values sampled uniformly from \([beg, end)\).
To restrict positions to integer values, we pass discrete=True
when creating object instances:
recregions = [
fwdpy11.PoissonInterval(beg=0, end=5, mean=2e-3, discrete=True),
fwdpy11.PoissonInterval(beg=5, end=10, mean=1e-3, discrete=True),
]
Now, breakpoints from the first region will only take on values of 0
, 1
, 2
, 3
, or 4
.
Setting discrete=True
requires the following:
Values for
beg
andend
must beint
. Thus,1
is valid but1.0
will raise aTypeError
.end - beg
must be> 1
. This requirement prevents you from usingbeg=0
andend=1
, for example, which would result in the only possible crossover position being0
.You must be more careful when using
msprime
to start/finish a simulation. See here and here for details.
The following classes are available:
General comments#
Different \([beg, end)\) intervals may overlap. The interpretation of such a setup is up to you.
When using classes like
fwdpy11.PoissonInterval
, the recombination rate that you use to construct afwdpy11.ModelParams
instance is ignored, as the rates are stored in the individual objects.You do not need to specify regions with zero recombination. Their existence is implied given the total length of the genome being simulated (
fwdpy11.TableCollection.genome_length
).