function (integer$)countOfMutationsInSubpop(object<Subpopulation> subpop) {
muts = subpop.genomesNonNull.mutations;
muts = unique(muts, preserveOrder=F);
return size(muts);
}
1 early()
{
...
log.addCustomColumn("count_p1", "countOfMutationsInSubpop(p1);");
log.addCustomColumn("count_p2", "countOfMutationsInSubpop(p2);");
}
This adds a user-defined function that counts the number of segregating mutations in a given subpopulation by simply getting a vector containing every mutation in every genome in the subpopulation, uniquing that vector so each mutation occurs only once, and then returning the size of the uniqued vector. It uses the "preserveOrder=F" parameter to unique() to make that function perform much more efficiently (see the Eidos manual for details). It does not limit the count to mutations of type m1; you could add that in if you wish, either by hard-coding "mutationsOfType(m1)" into the code of the countOfMutationsInSubpop() function, or by having that function take an additional MutationType parameter, as you wish.
However, there is an alternative implementation that is probably far more efficient (I haven't tested it, but it should be); it defines the same user-defined function like this:
function (integer$)countOfMutationsInSubpop(object<Subpopulation> subpop) {
counts = sim.mutationCounts(subpop, NULL);
return sum(counts > 0);
}
This uses SLiM's own internal machinery for computing mutation counts/frequencies. It requests counts within the given subpopulation, and returns the number of mutations for which the count is greater than zero. If you wanted to adapt this to only count mutations of type m1, you would pass sim.mutationsOfType(m1) instead of NULL for the second parameter to mutationCounts().
So, there are two different approaches, one doing the count yourself in Eidos (probably inefficient), one having SLiM do it for you (probably efficient). The efficiency difference between the two will probably grow as the number of segregating mutations grows; for your model as given, with less than 100 mutations typically segregating, either approach should be perfectly fine, and the first approach might prove more flexible in some respects if you end up having additional requirements for the count that mutationCounts() doesn't support.Hi again Ben
I have been rerunning the SLiMgui code with more sensible values of mutation rate (now 1e-6) and population sizes (now 10000) and am now getting much better agreement between the two models.
However I would still be very grateful if you could check my version of the SLiMgui code is the proper version to compare with my deterministic model as detailed in my last post.
Thanks again
Richard
Hi Ben
Thanks for bearing with me.
My aim is to output allele frequencies (i.e., count of number of m1 IBS alleles divided by twice population size) in each subpopulation in a biallelic model.
As I understand it muts = unique(muts, preserveOrder=F) has the effect that countOfMutationsInSubpop() returns the number of distinct mutational lineages – which is not what I want. I found that by removing it I seem to be getting the needed number of IBS alleles. Have I made a mistake here?
I introduced m1.mutationStackPolicy = "f" in an attempt to make the model biallelic. Slim-discuss is very helpful and I now see that “l”, not “f”, is what I need.
My SLiMgui model agrees with my infinite-population deterministic model when h=0.5 but not when h=1. Attempting to remedy this I followed your suggestion to modify the fitness() callbacks using information from section 25.2. My intention in the code below is that the fitness of IBS m1 is the same whether m1 is homozygous or heterozygous, while the fitness of homozygous wild type is 1.0. Unfortunately the outputs of my slim and my infinite-population deterministic model do not converge on the same values. My code is as follows:
One last point that could perhaps explain the differences
between the model predictions: as I understand pp 16-17 of the manual, in
SLiMgui N parents are drawn at random after selection and mate within their
subpopulation before migration – is this correct?
Will be grateful for any help you can give
Best,
Richard Sibly