Skip to content

Commit 5d9e29f

Browse files
committed
add recipe 16.11, life-long monogamous mating
1 parent 709f2dc commit 5d9e29f

4 files changed

Lines changed: 169 additions & 1 deletion

File tree

QtSLiM/recipes.qrc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@
4949
<file>recipes/Recipe 8.3.3 - Haploids with recombination.txt</file>
5050
<file>recipes/Recipe 8.3.4 - Sex-chromosome evolution and null haplosomes.txt</file>
5151
<file>recipes/Recipe 8.3.5 - Modeling the full human genome.txt</file>
52+
<file>recipes/Recipe 8.3.6 - A model of bryophytes with UV sex determination.txt</file>
5253
<file>recipes/Recipe 8.3.7 - Output from multiple-chromosome models.txt</file>
5354
<file>recipes/Recipe 9.1 - Introducing adaptive mutations.txt</file>
5455
<file>recipes/Recipe 9.2 - Making sweeps conditional on fixation.txt</file>
@@ -142,6 +143,7 @@
142143
<file>recipes/Recipe 16.8 - Modeling haplodiploidy with addRecombinant().txt</file>
143144
<file>recipes/Recipe 16.9 - Complex multi-chromosome inheritance with addMultiRecombinant().txt</file>
144145
<file>recipes/Recipe 16.10 - Modeling pseudo-autosomal regions (PARs) with addMultiRecombinant().txt</file>
146+
<file>recipes/Recipe 16.11 - Life-long monogamous mating.txt</file>
145147
<file>recipes/Recipe 17.1 - A simple 2D continuous-space model.txt</file>
146148
<file>recipes/Recipe 17.2 - Spatial competition.txt</file>
147149
<file>recipes/Recipe 17.3 - Boundaries and boundary conditions I (stopping boundaries).txt</file>
@@ -211,6 +213,5 @@
211213
<file>recipes/Recipe 20.6 - A coevolutionary host-parasitoid trait-matching model.txt</file>
212214
<file>recipes/Recipe 20.7 - A coevolutionary host-parasite matching-allele model.txt</file>
213215
<file>recipes/Recipe 20.8 - Within-host reproduction in a host-pathogen model.txt</file>
214-
<file>recipes/Recipe 8.3.6 - A model of bryophytes with UV sex determination.txt</file>
215216
</qresource>
216217
</RCC>
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Keywords: monogamy, monogamous mating, nonWF, non-Wright-Fisher
2+
3+
initialize() {
4+
defineConstant("K", 500); // carrying capacity
5+
defineConstant("R_AGE_M", 3); // minimum age of reproduction (male)
6+
defineConstant("R_AGE_F", 4); // minimum age of reproduction (female)
7+
defineConstant("FECUN", 0.2); // mean fecundity per female per tick
8+
9+
initializeSLiMModelType("nonWF");
10+
initializeSex();
11+
}
12+
1 first() {
13+
sim.addSubpop("p1", K);
14+
p1.individuals.age = rdunif(K, min=0, max=15); // initial variation in age
15+
p1.individuals.tag = -1; // mark all individuals as unmated
16+
}
17+
first() {
18+
// find mated individuals whose mate has died, and mark them as unmated
19+
mated_individuals = p1.individuals;
20+
mated_individuals = mated_individuals[mated_individuals.tag >= 0];
21+
22+
if (size(mated_individuals) > 0)
23+
{
24+
tags = mated_individuals.tag;
25+
tag_counts = tabulate(tags, maxbin=size(mated_individuals)-1);
26+
tags_to_fix = which(tag_counts == 1);
27+
unmated_indices = match(tags_to_fix, tags);
28+
mated_individuals[unmated_indices].tag = -1;
29+
}
30+
31+
// find the next tag value to use for new mating pairs
32+
next_tag = max(p1.individuals.tag) + 1;
33+
34+
// find unmated individuals that are of reproductive age
35+
unmated_F = p1.subsetIndividuals(sex="F", tag=-1, minAge=R_AGE_F);
36+
unmated_M = p1.subsetIndividuals(sex="M", tag=-1, minAge=R_AGE_M);
37+
38+
// pair individuals randomly; some individuals may be left unpaired
39+
pair_count = min(size(unmated_F), size(unmated_M));
40+
unmated_F = sample(unmated_F, pair_count, replace=F);
41+
unmated_M = sample(unmated_M, pair_count, replace=F);
42+
43+
for (f in unmated_F, m in unmated_M, tag in seqLen(pair_count) + next_tag)
44+
{
45+
f.tag = tag;
46+
m.tag = tag;
47+
}
48+
}
49+
reproduction() {
50+
// find the subset of individuals that have a mate
51+
mated_F = p1.subsetIndividuals(sex="F");
52+
mated_F = mated_F[mated_F.tag >= 0];
53+
54+
mated_M = p1.subsetIndividuals(sex="M");
55+
mated_M = mated_M[mated_M.tag >= 0];
56+
57+
// look up the male for each female, by tag
58+
male_indices = match(mated_F.tag, mated_M.tag);
59+
mated_M = mated_M[male_indices];
60+
61+
pair_count = size(mated_F);
62+
63+
// produce offspring from each mated pair
64+
for (f in mated_F,
65+
m in mated_M,
66+
c in rpois(pair_count, FECUN),
67+
new_tag in seqLen(pair_count))
68+
{
69+
// re-tag paired individuals to compact tags down
70+
f.tag = new_tag;
71+
m.tag = new_tag;
72+
73+
offspring = p1.addCrossed(f, m, count=c);
74+
offspring.tag = -1; // mark offspring as unmated
75+
}
76+
77+
self.active = 0; // deactivate for the rest of the tick ("big bang")
78+
}
79+
early() {
80+
// density-dependent population regulation
81+
p1.fitnessScaling = K / p1.individualCount;
82+
}
83+
10000 late() { }
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
// Keywords: monogamy, monogamous mating, nonWF, non-Wright-Fisher
2+
3+
initialize() {
4+
defineConstant("K", 500); // carrying capacity
5+
defineConstant("R_AGE_M", 3); // minimum age of reproduction (male)
6+
defineConstant("R_AGE_F", 4); // minimum age of reproduction (female)
7+
defineConstant("FECUN", 0.2); // mean fecundity per female per tick
8+
9+
initializeSLiMModelType("nonWF");
10+
initializeSex();
11+
}
12+
1 first() {
13+
sim.addSubpop("p1", K);
14+
p1.individuals.age = rdunif(K, min=0, max=15); // initial variation in age
15+
p1.individuals.tag = -1; // mark all individuals as unmated
16+
}
17+
first() {
18+
// find mated individuals whose mate has died, and mark them as unmated
19+
mated_individuals = p1.individuals;
20+
mated_individuals = mated_individuals[mated_individuals.tag >= 0];
21+
22+
if (size(mated_individuals) > 0)
23+
{
24+
tags = mated_individuals.tag;
25+
tag_counts = tabulate(tags, maxbin=size(mated_individuals)-1);
26+
tags_to_fix = which(tag_counts == 1);
27+
unmated_indices = match(tags_to_fix, tags);
28+
mated_individuals[unmated_indices].tag = -1;
29+
}
30+
31+
// find the next tag value to use for new mating pairs
32+
next_tag = max(p1.individuals.tag) + 1;
33+
34+
// find unmated individuals that are of reproductive age
35+
unmated_F = p1.subsetIndividuals(sex="F", tag=-1, minAge=R_AGE_F);
36+
unmated_M = p1.subsetIndividuals(sex="M", tag=-1, minAge=R_AGE_M);
37+
38+
// pair individuals randomly; some individuals may be left unpaired
39+
pair_count = min(size(unmated_F), size(unmated_M));
40+
unmated_F = sample(unmated_F, pair_count, replace=F);
41+
unmated_M = sample(unmated_M, pair_count, replace=F);
42+
43+
for (f in unmated_F, m in unmated_M, tag in seqLen(pair_count) + next_tag)
44+
{
45+
f.tag = tag;
46+
m.tag = tag;
47+
}
48+
}
49+
reproduction() {
50+
// find the subset of individuals that have a mate
51+
mated_F = p1.subsetIndividuals(sex="F");
52+
mated_F = mated_F[mated_F.tag >= 0];
53+
54+
mated_M = p1.subsetIndividuals(sex="M");
55+
mated_M = mated_M[mated_M.tag >= 0];
56+
57+
// look up the male for each female, by tag
58+
male_indices = match(mated_F.tag, mated_M.tag);
59+
mated_M = mated_M[male_indices];
60+
61+
pair_count = size(mated_F);
62+
63+
// produce offspring from each mated pair
64+
for (f in mated_F,
65+
m in mated_M,
66+
c in rpois(pair_count, FECUN),
67+
new_tag in seqLen(pair_count))
68+
{
69+
// re-tag paired individuals to compact tags down
70+
f.tag = new_tag;
71+
m.tag = new_tag;
72+
73+
offspring = p1.addCrossed(f, m, count=c);
74+
offspring.tag = -1; // mark offspring as unmated
75+
}
76+
77+
self.active = 0; // deactivate for the rest of the tick ("big bang")
78+
}
79+
early() {
80+
// density-dependent population regulation
81+
p1.fitnessScaling = K / p1.individualCount;
82+
}
83+
10000 late() { }

VERSIONS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ Note that not every commit will be logged here; that is what the Github commit h
66

77

88
development head (in the master branch):
9+
add recipe 16.11, life-long monogamous mating
910

1011

1112
version 5.0 (Eidos version 4.0):

0 commit comments

Comments
 (0)