Hello everyone,
First of all, thanks
a lot for the amazing software that is SLiM!
I’m having an
issue, quite similar to this one
(https://groups.google.com/g/slim-discuss/c/W8wEYj9UNnw/m/ozG3MM73BQAJ).
I’m running some forward SLiM simulation (neutral simulations for now, but I’ll add some beneficial mutation later on) using a recombination map in order to emulate chromosomes and recapitate the trees using pyslim. However, I can’t seems to get the trees to get down to a single root and I always end up with 2 roots after recapitation.
I’ve included both my SLiM script and my python script. As they’re both part of a bigger pipeline, they might need some tweaks in order to be used for test purpose – even though I don’t think they’re especially original or hard to modify.
Oh, and here's an example of a rec_map.txt :
200_rec_map.txt
chr_size rec_rate
17000 1e-11
3000 1e-10
44000 1e-7
44000 1e-8
- SLiM script -
//// A HELPER FUNCTION FOR SETTING CONSTANTS THAT MIGHT BE CONFIGURED VIA COMMAND LINE.
function (void) defineCfgParam(string$ name, lifs value) {
if (!exists(name))
defineConstant(name, value);
}
// set up a simple neutral simulation
initialize() {
initializeTreeSeq();
defineCfgParam("sim_id", "test1");
defineCfgParam("Ne", 500);
defineCfgParam("mu", 1e-8);
defineCfgParam("s", 0.5);
initializeMutationRate(0);
// m1 mutation type: neutral
initializeMutationType("m1", 0.5, "f", 0.0);
// g1 genomic element type: uses m1 for all mutations
initializeGenomicElementType("g1", m1, 1);
// create "chromosomes" from "../parameters/sim_id_rec_map.txt" file
lines = readFile("../parameters/" + asString(sim_id) + "_rec_map.txt");
header = strsplit(lines[0], "\t");
if (header[0] != "chr_size"
| header[1] != "rec_rate") {
stop("Unexpected format!");
}
x = 0;
rates = NULL;
ends = NULL;
nchrs = length(lines) - 1;
for (line in lines[1:nchrs]) {
components = strsplit(line, "\t");
ends = c(ends, x + asInteger(components[0]), x + asInteger(components[0]) +1);
rates = c(rates, asFloat(components[1]), 0.5);
x = x + asInteger(components[0]) +1;
}
// remove the last base of the chr (if not, last base with 0.5 recombination rate)
rates = rates[0:(length(rates)-2)];
ends = ends[0:(length(ends)-2)];
// check the rates and ends
print(rates);
print(ends);
initializeGenomicElement(g1, 0, ends[length(ends)-1]);
initializeRecombinationRate(rates, ends);
}
// create a population of Ne individuals with selfing rate = s
1 {
sim.addSubpop("p1", Ne);
p1.setSelfingRate(s);
}
// output samples of 10 genomes periodically, all fixed mutations at end
//1000 late() { p1.outputSample(10); }
//2000 late() { p1.outputSample(10); }
2000 late() {
sim.treeSeqOutput("../results/" + asString(sim_id) + ".trees");
}
- python script -
# Keywords : python, tree-sequence recording, tree sequence recording, SLiM, ms, recombination, recombination map
# Input : SLiM simulation (.trees file, tree-seq recording)
# Output : sample of diploids in ms format
def trees2ms(sim_id):
# load the .trees file created by SLiM after the forward simulation
ts = pyslim.load("../results/" + str(sim_id) + ".trees")
ends = []
rates = []
x = 0
# use the recombination_map.txt file in order to create a recombination map "in ms format"
with open("../parameters/" + str(sim_id) + "_rec_map.txt", "r") as file:
header = file.readline().strip().split("\t")
assert(header[0] == "chr_size" and header[1] == "rec_rate")
for line in file:
components = line.split("\t")
ends.append(x + float(components[0]))
ends.append(x + float(components[0]) + 1)
rates.append(float(components[1]))
rates.append(0.5)
x = x + float(components[0]) + 1
# add a 0 at the beginning of positions lists : ms != SLiM when it comes to the way positions and ends are used
ends.insert(0, 0)
# add a 0 at the end of rates, as we've got one more "position"
rates.append(0.0)
# create the actual recombination map used by the .recapitate() function
recomb_map = msprime.RecombinationMap(ends, rates)
## see "https://pyslim.readthedocs.io/en/latest/tutorial.html#recapitation-with-a-nonuniform-recombination-map" for more info
rts = ts.recapitate(recombination_map=recomb_map, Ne=Ne)
rts.dump("../results/" + str(sim_id) + "_recap.trees") # save the recapitated trees
#assert(max([t.num_roots for t in rts.trees()]) == 1) # Il trouve 2 roots :/
rts = pyslim.SlimTreeSequence(msprime.mutate(rts, rate=mu, keep=True))
rts.dump("../results/" + str(sim_id) + "_recap_mut.trees") # save the recapitated & mutated trees
# Sample 20 individuals from the population
samp = 20
alive = rts.individuals_alive_at(0)
sample_inds = np.random.choice(alive, samp, replace=False)
# Simplify tree sequence to contain only 20 individuals
keep_nodes = []
for i in sample_inds:
keep_nodes.extend(rts.individual(i).nodes)
srts = rts.simplify(keep_nodes)
# Write the ms output
ms_output = open("../results/" + str(sim_id) + "_ms.txt", "w")
tskit.write_ms(srts, ms_output)
ms_output.close()
return()
if __name__ == '__main__' :
import msprime, tskit, pyslim, sys
import numpy as np
if (len(sys.argv) != 5) :
sys.exit("Argument missing")
else :
for arg in sys.argv:
if "=" in arg :
arg = arg.split("=")
if arg[0]== "sim_id":
sim_id = str(arg[1])
if arg[0] == "Ne":
Ne = int(arg[1])
if arg[0] == "mu":
mu = float(arg[1])
if arg[0]== "samp":
samp = int(arg[1])
trees2ms(sim_id)
If that's not it, I really don’t see what might be the issue so if anyone could help, it would be very much appreciated !
Cheers,
G. L-F
--
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/507f81a8-40a3-4a6a-8382-64a64aa29e7en%40googlegroups.com.