Switching from fitnessEffect() to fitnessScaling()

3 views
Skip to first unread message

Grace Rhodes

unread,
Feb 6, 2026, 11:45:39 AM (5 days ago) Feb 6
to slim-discuss
Hi all,

I'm currently using the fitnessEffect() callback to model selection against individuals who have at least one mutation on both their gene copies. I'm not using the built-in functionality for finding homozygotes because the selection should be the same on compound heterozygotes. I have a script that has the desired behavior, but it is very slow because I need to simulate a large number of individuals. My understanding is that fitnessScaling() is much more efficient than fitnessEffect() because it is vectorized, but when I have tried to switch to this I don't get the same behavior. Does anyone have any suggestions for how to do this with fitnessScaling() (or if it is possible)? My script and my initial attempt at using fitnessScaling() are below.

Thank you!

Grace

Script:
initialize() {
  setSeed(SEED);
initializeMutationRate(MUT_RATE);
// one mutation type: loss-of-function
initializeMutationType("m1", 0.0, "f", 0.0); // loss of function
initializeGenomicElementType("g1", m1, 1.0);
initializeGenomicElement(g1, 0, 12500);
initializeRecombinationRate(1e-8);
}
// initialize one pop'n with 100k individuals
1 early() {
sim.addSubpop("p1", 100000);
}

// after 2,000 ticks increase sample size to 800k
2000 early() {
  p1.setSubpopulationSize(800000);
}

2000:12000 fitnessEffect(){
num_lof = individual.haplosomes.countOfMutationsOfType(m1);
if ((num_lof[0]>0)&(num_lof[1]>0)) return asFloat(DELTA);
else return 1.0;
}

// output sample of individuals after another 10k generations
12000 late() {
  sim.subpopulations.individuals.haplosomes.outputHaplosomes();
}

Scaling attempt:
2000: late(){
inds = sim.subpopulations.individuals;
n_lof = inds.haplosomes.countOfMutationsOfType(m1);
inds.fitnessScaling((n_lof[0]>0)&(n_lof[1]>0)) ? DELTA else 1
}

Ben Haller

unread,
Feb 6, 2026, 12:15:50 PM (5 days ago) Feb 6
to slim-d...@googlegroups.com
Hi Grace!

I assume that fitnessScaling code gives you an error, in fact?  The error is because it is a property that you need to assign a value into; it looks like you are not doing any assignment, in the code you posted.

To start with, I'd recommend that you do a for loop over individuals, and treat each individual separately using the same code that you have in your fitnessEffect() callback now, but assigning the desired effect into fitnessScaling.  Vectorization of that code is then a separate step, once you've got the non-vectorized version working.

For that vectorization, since inds.haplosomes.countOfMutationsOfType() returns a vector of length 2 (one value per haplosome) it is difficult to incorporate into a vectorized algorithm.  You might have better luck using inds.haploidGenome1.countOfMutationsOfType() and inds.haploidGenome2.countOfMutationsOfType() to get separate logical vectors, and then proceeding with your vectorized calculations from there.  I think the ifelse() function will also be useful to you, since it is a vectorized version of the ?else operator you are using in your fitnessEffect() callback.  The SLiM workshop has a fair bit of discussion of vectorization, if you're unfamiliar with it.  If you remain stuck after working on this for a while, feel free to post again with your non-vectorized code using fitnessScaling.

I don't know whether any of this will actually speed up your model much, though, since it might be that the large majority of the runtime is spent in countOfMutationsOfType().  Searching through haplosomes to find/count mutations is just a very slow thing to do.  If the total number of mutations in your model is small, maybe it won't be too bad; if it is large, that will be the bottleneck for sure.  I notice that you appear to be modeling only one mutation type, m1, and then you're counting m1 mutations.  If so, rather than countOfMutationsOfType() you could just use the number of mutations in the haplosome – EXCEPT that I notice I never made a Haplosome property for that!  That's an oversight, whoops!  It has never come up before now, though; knowing the number of mutations is not usually useful, but in your case perhaps it is!  I've just opened an issue on this at https://github.com/MesserLab/SLiM/issues/612; this property will be added in the next version of SLiM.  (If you would like to have it sooner than that, and are happy to build SLiM from sources yourself following the instructions in chapter 2 of the manual, then please comment on the issue to say so, and I'll have it pushed to SLiM's GitHub repo ASAP).

I hope this helps!  Good luck and happy modeling!

Cheers,
-B.

Benjamin C. Haller
Messer Lab
Cornell University
--
SLiM forward genetic simulation: http://messerlab.org/slim/
---
You received this message because you are subscribed to the Google Groups "slim-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to slim-discuss...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/slim-discuss/a5d2f621-b0d8-490a-a07c-60249a8c0a45n%40googlegroups.com.

Reply all
Reply to author
Forward
0 new messages