Mitotic recombination in clonal population

53 views
Skip to first unread message

Yann Dussert

unread,
Oct 23, 2019, 8:50:02 AM10/23/19
to slim-discuss
Hi,

I'd like to model mitotic recombination (including mitotic gene conversion) in a clonal organism with SLiM.

I tried to use recombination() callbacks, which have no effect - which seems logical after re-reading the manual, since in the clonal case, recombination is totally ignored, from what I understand.

Is it possible to implement mitotic recombination using existing SLiM methods, or should I try to write my own bit of code to simulate recombination?

Thank you in advance for your answer.

Best regards,
Yann

Ben Haller

unread,
Oct 23, 2019, 10:01:51 AM10/23/19
to slim-discuss
Hi Yann.  I'm guessing you mean diploids?  If you mean haploids, recipe 16.14 might be quite close to what you want, but assuming not, then you probably want to leverage the addRecombinant() method to do the recombination you want, and the drawBreakpoints() method of sim.chromosome to draw recombination breakpoints using SLiM's standard algorithm.  In that case there is no recipe in the manual for precisely what you want to do, but recipes such as 16.13, 16.14, and 16.16 might shed some light on various angles of what you want.  Basically, in the reproduction() callback of a nonWF model you should be able to draw breakpoints with drawBreakpoints() and then call addRecombinant() to generate the offspring individual with whatever recombination is needed between whichever parental genomes you want to use.  If you only need simple gene conversion tracts, not complex gene conversion tracts with heteroduplex mismatch repair, you might even be able to use SLiM's built-in support for gene conversion (see section 1.5.6).

I hope this helps; feel free to ask again if you get stuck!  :->

Cheers,
-B.

Benjamin C. Haller
Messer Lab
Cornell University

Yann Dussert

unread,
Oct 28, 2019, 10:05:14 AM10/28/19
to slim-discuss
Hi,

Thank you for your reply.

Yes, I meant for diploids. I did see that nonWF models had some useful methods to produce recombination events, but I wanted to know if it was possible to do it using a WF model (partly because I am lazy, partly because eventually I will include QTLs and other things and it seemed simpler to stick to a WF model, for which there are a lot of examples).
I'll try with nonWF models and see what I can come up with.

Thanks again!

Best regards,
Yann

Ben Haller

unread,
Oct 28, 2019, 1:27:15 PM10/28/19
to slim-discuss
Hi Yann.  Sounds good.  See section 16.7 and 16.9 for examples of nonQF QTL-based models; the same techniques work in both model types.

Cheers,
-B.

Benjamin C. Haller
Messer Lab
Cornell University


Message has been deleted

Yann Dussert

unread,
Oct 29, 2019, 10:26:08 AM10/29/19
to slim-discuss
Hi again,

For Ben Haller: sorry for the previous message that has been deleted, but I misclicked before finishing post and had to redo it.

I think the following nonWF model properly simulates mitotic recombination for a clonal organism, by using addRecombinant() with the same individual as both parents and alternating genome1 and genome2 as the initial copy strand:

initialize()
{
    initializeSLiMModelType("nonWF");
    defineConstant("mu_base", 0); // mutation rate = 0 because I just want mutations that I introduce
    initializeMutationRate(mu_base);
    initializeMutationType("m1", 0.5, "f", 0.0);
    initializeGenomicElementType("g1", m1, 1.0);
    initializeGenomicElement(g1, 0, 1e4 - 1);
    initializeRecombinationRate(1e-6);
    initializeGeneConversion(0.8, 1000, 1.0);   
}
reproduction()
// Reproduction callback is launched every generation
{
    for (indv in sim.subpopulations.individuals)
    {
        breaks = sim.chromosome.drawBreakpoints(indv);
        subpop.addRecombinant(indv.genome1, indv.genome2, breaks, indv.genome2, indv.genome1, breaks);
    }
    self.active = 0;
}
1 early()
{
    sim.addSubpop("p1", 100);
}
1 late()
{
    // Add mutations on the genome1 of each indv to visualize recombination events
    allIndv = sim.subpopulations.individuals;
    allIndv.genome1.addNewDrawnMutation(m1, 1000);
    allIndv.genome1.addNewDrawnMutation(m1, 2000);
    allIndv.genome1.addNewDrawnMutation(m1, 3000);
    allIndv.genome1.addNewDrawnMutation(m1, 4000);
    allIndv.genome1.addNewDrawnMutation(m1, 5000);
    allIndv.genome1.addNewDrawnMutation(m1, 6000);
    allIndv.genome1.addNewDrawnMutation(m1, 7000);
}
early()
{
    // kills all non-juveniles to get non overlapping generations
    // note: newly generated juveniles have age == 0
    inds = sim.subpopulations.individuals;
    inds[inds.age > 0].fitnessScaling = 0.0;
}
10000 late()
{
    allIndv = sim.subpopulations.individuals;
    allIndv.genomes.outputVCF(filePath = "test.vcf");
}


From the resulting haplotypes, it seems to do what I want. However, gene conversion (with initializeGeneConversion(0.8, 1000, 1.0); for example) does not seem to work in this case: I do not see any cases of loss of heterozygosity.
From the manual, "gene conversion tracts are not explicitly supported by" addRecombinant(), but "crossover breakpoints [...] may be used to implement crossovers or simple gene conversion tracts". So is there something I should add to the code to add gene conversion?

Best regards,
Yann

Ben Haller

unread,
Oct 29, 2019, 11:13:13 AM10/29/19
to slim-discuss
Hi Yann.  Ah, I thought you were talking about a model of horizontal gene transfer between clonally reproducing diploids, or something like that.  But instead I guess you're talking about diploids that reproduce themselves by mitosis, but with recombination (and gene conversion) between their own two genomes during each mitosis event.  So there is no HGT at all, and each lineage is entirely clonal and isolated from each other lineage, but genetic material is getting swapped around between the genomes inside each lineage.  OK, fine.  (I'm curious: what type of organism does this?  What are you simulating?)  Your model looks fine for that purpose, apart from the issue you raised.

Regarding the gene conversion issue: yes, I think there is a problem with your model there.  From the SLiM perspective, where a pair of two parental genomes recombines to produce a single gamete that is used as one-half of a new offspring, simple gene conversion tracts can be treated like particular patterns of crossovers.  In particular, a crossover gene conversion tract results, effectively, in a switch in the copy strand at the start of the tract and then a switch back at the end, whereas a non-crossover gene conversion event results, effectively, in a switch in the copy strand at the start and no switch back at the end.  Section 1.5.6 has diagrams of this that should show precisely what I mean.  The breakpoints returned by drawBreakpoints() are simple crossover breakpoints that effectively accomplish these mechanics.  The tricky thing is that you want, in some sense, to generate both "gametes" resulting from recombination of the parental genomes, and then fuse those two "gametes" back together to create the new diploid offspring.  SLiM doesn't know how gene conversion works in that context; it doesn't know anything about what the other product of recombination looks like (the one that is not used, normally in SLiM, to form a gamete).  In your model you are currently using the exact same set of crossover breakpoints to produce both "gametes", and just changing which strand is the initial copy strand, so the products from your mitotic recombination are symmetric; any mutation gained by one "gamete" due to gene conversion is symmetrically lost by the other "gamete".  But you want these two "gametes" to be asymmetric, with genetic material within a given gene conversion tract either being duplicated or being lost.  There is no built-in support for that, since SLiM itself never generates the "other" gamete; you will need to generate the appropriate crossover breakpoints yourself.  I would suggest that you might still begin with a call to sim.chromosome.drawBreakpoints() as you do now, to get the starting set of breakpoints where gene conversion tracts will occur (with no call to initializeGeneConversion(), since you will roll your own gene conversion).  Then (following the general procedure outlined in section 1.5.6) you can select which breakpoints will be crossover gene conversions and which will be non-crossovers, draw the length before and the length after each breakpoint that become the span of each gene conversion tract, and finally, figure out the asymmetric set of non-gene-conversion crossover breakpoints that will represent the correct outcome for both "gametes", which you can pass to addRecombinant() as the two breakpoint vectors to be used.  This will probably be fairly messy coding; sorry.

Let me know if I have again completely misunderstood what you're trying to do here.  In any case, we should probably take this discussion off-list at this point, since I don't think it's likely to be of general interest; so please reply directly to me on email.  Thanks!

Cheers,
-B.

Benjamin C. Haller
Messer Lab
Cornell University


Reply all
Reply to author
Forward
0 new messages