Tracking recent local ancestry

83 views
Skip to first unread message

Joshua Schraiber

unread,
Oct 4, 2023, 5:56:09 PM10/4/23
to slim-discuss
I'm trying to simulate an admixed population and keep track of local ancestry of mutations in the admixed population, by which I mean the most recent population that contributed that mutation to the individual. The difficulty is that the mutations are shared between the mixing populations---so subpopID won't work, since I actually care if an individual got a given mutation from ancestral population A or ancestral population B, not which population it arose in. Hopefully that makes sense.

Thanks!

Ben Haller

unread,
Oct 4, 2023, 7:04:13 PM10/4/23
to Joshua Schraiber, slim-discuss
Hi Joshua!

I think tree-sequence recording is probably what you want.  The recorded tree sequence can keep track of where the ancestry of a particular individual came from.  The only caveat is that you will probably need to force the tree sequence to specifically keep around ancestral individuals that migrated.  Happily, this is straightforward to do with the treeSeqRememberIndividuals() method; just pass it the migrant individuals in each tick.  In a nonWF model, you've moving those migrants yourself with takeMigrants(), so you've got them handy and can simply pass them over to treeSeqRememberIndividuals(); in a WF model, SLiM moves them for you but you can look them up, after offspring generation and thus migration has occurred, using the migrant flag of Individual.  Hopefully this gets you where you need to be.  Then you'll need to do some Python coding at the end to trace through the ancestry and determine what you want to know; I'm not good in Python, personally, but I recommend reading the pyslim documentation carefully to get the gist of things, trying to implement what you want, and then coming here if you have questions (probably to be answered by Peter Ralph or someone else, not me :->).  Good luck, happy modeling!

Cheers,
-B.

Benjamin C. Haller
Messer Lab
Cornell University


Joshua Schraiber wrote on 10/4/23 5:56 PM:
I'm trying to simulate an admixed population and keep track of local ancestry of mutations in the admixed population, by which I mean the most recent population that contributed that mutation to the individual. The difficulty is that the mutations are shared between the mixing populations---so subpopID won't work, since I actually care if an individual got a given mutation from ancestral population A or ancestral population B, not which population it arose in. Hopefully that makes sense.

Thanks!
--
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 on the web visit https://groups.google.com/d/msgid/slim-discuss/c7c9ab1f-4405-48f6-8190-b6a26cfddf3dn%40googlegroups.com.

Joshua Schraiber

unread,
Oct 4, 2023, 9:21:46 PM10/4/23
to Ben Haller, slim-discuss

Thanks Ben!

I think I had come to the conclusion that tree seqs would be useful for me, too. I took a look at the pyslim documentation, and unfortunately I think exactly the thing I would be interested in doing is in a todo for the future! "TODO: Add SLiM code which includes retaining and remembering, and perhaps some python code to show them."

I got something that seems to give me plausible results. Roughly what I'm doing is this (the times are artificially short just for debugging purposes):

initialize() {

initializeTreeSeq();

// .... other parameters

}

1 late() {

sim.addSubpop("p1", 1000);

}


1:2000 late() {

// ... evolution I want to happen in the ancestral pop

}

2000 early() {

sim.addSubpopSplit("p2", 1000, p1);

}


2000:2050 late() {

// ... evolution I want to happen in the split pops

}

2050 late() {

sim.treeSeqRememberIndividuals(sim.subpopulations.individuals); //I'm trying to remember the parents of the migrants, I think?

sim.addSubpop("p3", 1000);

p3.setMigrationRates(c(p1, p2), c(0.7, 0.3));

}

2051 late() {

p3.setMigrationRates(c(p1, p2), c(0.0, 0.0));

p1.setSubpopulationSize(0);

p2.setSubpopulationSize(0);

}


2061 late() {

sim.treeSeqOutput("~/Desktop/test_trees.trees");

sim.simulationFinished();

}


Then I load this into python with tskit, and my intuition is that I can traverse up the tree from each sample to the first remembered individual, and that should indicate their ancestry at that position? My naive implementation here seems to give me something plausible, although maybe there's something easier/faster that can be done?


ancestry = [] #initialize ancestry array
for tree in trees.trees(): #loop over trees
    ancestry.append([[] for i in range(1000)]) #For each tree, make an array of diploid ancestry for 1000 people
    for sample in tree.samples(): #loop over samples in the tree
        cur_ind = trees.node(sample).individual #get the individual index of the person
        if trees.node(sample).population!=2: continue #skip over the remembered individuals
        #traverse tree
        node = sample
        parent = tree.parent(node)
        while trees.node(parent).population==2: #if the parent is in the admixed population, then keep going
            node = parent
            parent = tree.parent(node)
        #add to my growing list
        ancestry[-1][cur_ind].append(trees.node(parent).population)


It'd be great if I could get some feedback and make sure that my intuition is right!


Thanks!

Josh



Ben Haller

unread,
Oct 5, 2023, 10:49:25 AM10/5/23
to Joshua Schraiber, slim-discuss
Hi Josh,

Looks reasonable to me, but like I said, I'm not a Python person.  :->


Cheers,
-B.

Benjamin C. Haller
Messer Lab
Cornell University


Joshua Schraiber wrote on 10/4/23 9:21 PM:

Peter Ralph

unread,
Oct 5, 2023, 11:59:03 AM10/5/23
to Joshua Schraiber, Ben Haller, slim-discuss
Hi, Josh!  That does look reasonable, but instead of your python code you could (should?) use Georgia Tsambos's tspop package, designed to do exactly this:
(and since Georgia has written this already, I'm not actually reading your python code...)

-- peter

From: 'Ben Haller' via slim-discuss <slim-d...@googlegroups.com>
Sent: Thursday, October 5, 2023 7:49 AM
To: Joshua Schraiber <jgsch...@gmail.com>
Cc: slim-discuss <slim-d...@googlegroups.com>
Subject: Re: Tracking recent local ancestry
 

Joshua Schraiber

unread,
Oct 5, 2023, 1:23:53 PM10/5/23
to Peter Ralph, Ben Haller, slim-discuss
Thanks Peter, this is even better than writing my own python code :)

You received this message because you are subscribed to a topic in the Google Groups "slim-discuss" group.
To unsubscribe from this topic, visit https://groups.google.com/d/topic/slim-discuss/0O4ynHxA8L4/unsubscribe.
To unsubscribe from this group and all its topics, send an email to slim-discuss...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/slim-discuss/PH0PR10MB472747357653EF6087D0FA7CA5CAA%40PH0PR10MB4727.namprd10.prod.outlook.com.
Reply all
Reply to author
Forward
0 new messages