Estimating relatedness between parents and children in a haploid model

3 views
Skip to first unread message

Alexander Mackintosh

unread,
Jan 13, 2026, 11:02:44 AM (yesterday) Jan 13
to slim-discuss
Hi,

I am interested in obtaining the genetic relatedness between a child and its two parents within a SLiM simulation. For a diploid model this will always be 0.5. However, I am simulating a clonal haploid population with rare sexual reproduction. Offspring that are produced by sex will have a recombinant genome and will share some proportion of the genome with each parent (not exactly 0.5), and I would like to record this information each generation. I saw that there is a relatedness function in SLiM, but my understanding is that this gives the pedigree relatedness and so would always return 0.5.

One way to do this would be to output treesequences without simplification, then match the SLiM ID of individuals produced by sex in the simulation to nodes in the treesequence. I anticipate that the file would be huge given 200,000 generations and a population size of 10,000, and I would prefer a solution that is not limited by this.

My current thinking is that if I can gain access to the sampled recombination points during sexual reproduction then perhaps I could calculate relatedness from that and record values during the simulation. Would this be possible? Or perhaps there is another solution that I am missing?

Any help would be really appreciated.

Best wishes,

Alex

Ben Haller

unread,
Jan 13, 2026, 12:56:12 PM (yesterday) Jan 13
to slim-d...@googlegroups.com
Hi Alex!  Interesting idea!  Yes, I think you could implement this pretty easily like so:

initialize() {

initializeSLiMModelType("nonWF");

initializeSLiMOptions(keepPedigrees=T);

initializeMutationType("m1", 1.0, "f", 0.0);

initializeGenomicElementType("g1", m1, 1.0);

initializeChromosome(1, 1e9, type="H");

initializeGenomicElement(g1);

initializeMutationRate(1e-7);

initializeRecombinationRate(1e-8);

}

1 late() {

sim.addSubpop("p1", 100);

}

reproduction() {

if (runif(1) < 0.90)

{

// reproduce clonally, recording no breakpoints

subpop.addCloned(individual);

}

else

{

// reproduce sexually, recording breakpoints

mate = p1.sampleIndividuals(1, exclude=individual);

if (runif(1) <= 0.5)

{

initialStrand = individual.haploidGenome1;

secondStrand = mate.haploidGenome1;

parent1 = individual;

parent2 = mate;

}

else

{

initialStrand = mate.haploidGenome1;

secondStrand = individual.haploidGenome1;

parent1 = mate;

parent2 = individual;

}

breaks = sim.chromosome.drawBreakpoints(parent1, NULL);

offspring = subpop.addRecombinant(initialStrand, secondStrand, breaks,

NULL, NULL, NULL, parent1=parent1, parent2=parent2, randomizeStrands=F);

offspring.setValue("breaks", breaks);

}

}

2: early() {

// non-overlapping generations

adults = p1.subsetIndividuals(minAge=1);

sim.killIndividuals(adults);

}

2 late() {

for (ind in p1.individuals)

{

breaks = ind.getValue("breaks");

if (isNULL(breaks))

catn("individual " + ind.pedigreeID + " was cloned from parent " + ind.pedigreeParentIDs[0]);

else

catn("individual " + ind.pedigreeID + " had parents " + paste(ind.pedigreeParentIDs) + " with breakpoints {" + paste(breaks) + "}");

// ...could figure out ancestry proportions here, from that information...

}

}

The key element is using a nonWF model with addRecombinant() to make the sexual offspring, which allows you to use drawBreakpoints() to draw the breakpoints yourself so that you can record them. It's also important to use randomizeStrands=F so that you know which parent provided the initial copy strand; this way you know that the first parent of the individual, according to pedigree tracking, provided the initial copy strand and so you can trace the ancestry back to the correct parent. If you used randomizeStrands=T (which is the default) you wouldn't be able to trace back that way; you wouldn't know which parent provided the initial copy strand.

Using this information to go back one generation, getting ancestry fractions from the two parents, shouldn't be too hard. Going back any further than that seems like it would start to be quite a headache, but it is probably do-able with some elbow grease. :-O

If you get a working solution, even for just one generation back, it'd be great if you posted it here and/or provided it as a PR for the SLiM-Extras repository; I think it might be of interest to others. 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/d4d26a55-5a6d-4948-9f55-a15fa49515d2n%40googlegroups.com.

Reply all
Reply to author
Forward
0 new messages