Пример #1
0
    def __call__(self, pop):
        """
        Main public interface to this demography model.  When the model object is called in every time step,
        this method creates a new migration matrix.

        After migration, the stat function is called to inventory the subpopulation sizes, which are then
        returned since they're handed to the RandomSelection mating operator.

        If a new network slice is not active, the migration matrix from the previous step is applied again,
        and the new subpopulation sizes are returns to the RandomSelection mating operator as before.

        :return: A list of the subpopulation sizes for each subpopulation
        """
        if 'gen' not in pop.vars():
            gen = 0
        else:
            gen = pop.dvars().gen

        ######### Do the per tick processing ##########

        log.debug("========= Processing network  =============")
        # self._dbg_slice_pop_start(pop,gen)

        # update the migration matrix
        self._cached_migration_matrix = self._calculate_migration_matrix(gen)

        sim.migrate(pop, self._cached_migration_matrix)
        sim.stat(pop, popSize=True)
        # cache the new subpopulation names and sizes for debug and logging purposes
        # before returning them to the calling function
        self.subpopulation_names = sorted(str(list(pop.subPopNames())))
        self.subpop_sizes = pop.subPopSizes()
        #print(self.subpop_sizes)
        return pop.subPopSizes()
Пример #2
0
def migration(pop):
    #Extract the number of populations 'numpop'
    sim.stat(pop, popSize=True)
    subsize = pop.dvars().subPopSize
    numpop = len(subsize)
    #First iteration step is 2
    #i reflects the number of pops (2,4,8,16...)
    i = 2
    #j reflects the number of steps (1,2,3...)
    j = 1
    #Seeding iterative process to construct migration rate matrix
    #a is a 2x2 matrix
    a = zeros((2, 2))
    a[1][0] = 1
    a[0][1] = 1
    while i < numpop:
        #while the number of pops is not reached
        #note that for numpop=2, the loop is not activate
        #i doubles
        i = 2 * i
        #incrementing j
        j += 1
        #tmp is a submatrix 2x2 containing the 'migration coefficient' i/2 (1/2 for 4 pops, 1/4 for 8 pops, etc..)
        tmp = zeros(((i / 2), (i / 2))) + (float(1) / (i / 2))
        #a is updated to contain the coefficients in anti-diag submatrices
        #a is now 4x4, then 8x8 for 16 pops
        a = hstack((vstack((a, tmp)), vstack((tmp, a))))
#End while
#the matrix needs to be scaled to sum to 1
#the sum to 1 is needed for m (migration rate) to be a relevant biological parameter
#Scaled by the number of steps j (each step adding exactly 1 to each row (1, or 2*1/2 or 4*1/4, etc...))
    res = (a / j) * m
    #res is an array, we need a nested list
    A = res.tolist()
    #And now migration finally happens !
    sim.migrate(pop, rate=A)
    return True
Пример #3
0
    def __call__(self, pop):
        """
        Main public interface to this demography model.  When the model object is called in every time step,
        this method determines whether a new network slice is now active.  If so, the requisite changes
        to subpopulations are made (adding/deleting subpopulations), and then the new migration matrix is
        applied.

        After migration, the stat function is called to inventory the subpopulation sizes, which are then
        returned since they're handed to the RandomSelection mating operator.

        If a new network slice is not active, the migration matrix from the previous step is applied again,
        and the new subpopulation sizes are returns to the RandomSelection mating operator as before.

        :return: A list of the subpopulation sizes for each subpopulation
        """
        if 'gen' not in pop.vars():
            gen = 0
        else:
            gen = pop.dvars().gen

        # At the first time slice, start tracking duration for assemblages that exist at min(self.times)
        # which is also the end of the burn-in time
        # After this point, further changes are recorded as nodes are added/deleted
        if gen == min(self.times):
            starting_subpops = pop.subPopNames()
            for subpop in starting_subpops:
                self.node_origin_time[subpop] = min(self.times)

        # At the very end of the simulation, after the last slice time, we finish off the
        # duration times of assemblages that exist at sim_length.
        if gen == self.sim_length - 1:
            log.debug(
                "End of simulation: recording exit time for assemblages present at sim_length"
            )
            ending_subpops = pop.subPopNames()
            for subpop in ending_subpops:
                self.node_exit_time[subpop] = self.sim_length

        ######### Do the per tick processing ##########

        if self.is_change_time(gen) == False:
            pass
        else:
            slice_for_time = self.time_to_sliceid_map[gen]
            log.debug(
                "========= Processing network slice %s at time %s =============",
                slice_for_time, gen)
            #self._dbg_slice_pop_start(pop,gen)

            # switch to a new network slice, first handling added and deleted subpops
            # then calculate a new migration matrix
            # then migrate according to the new matrix
            (added_subpops,
             deleted_subpops) = self._get_added_deleted_subpops_for_time(gen)

            # add new subpopulations
            #log.debug("time %s adding subpops: %s", gen, added_subpops)
            for sp in added_subpops:
                (origin_sp, origin_sp_name
                 ) = self._get_origin_subpop_for_new_subpopulation(
                     gen, pop, sp)

                log.debug(
                    "time %s new node: %s parent id: %s  parent name: %s", gen,
                    sp, origin_sp, origin_sp_name)

                sp_names = [origin_sp_name, sp]
                #log.debug("spnames: %s", sp_names)
                split_ids = pop.splitSubPop(origin_sp, [0.5, 0.5], sp_names)
                #log.debug("split return: %s", split_ids)
                # make sure all subpopulations are the same size, sampling from existing individuals with replacement
                numpops = pop.numSubPop()
                sizes = [self.init_subpop_size] * numpops
                pop.resize(sizes, propagate=True)

            # delete subpopulations
            #log.debug("time %s deleting subpops: %s", gen, deleted_subpops)
            for sp in deleted_subpops:
                #log.debug("pops: %s", pop.subPopNames())
                log.debug("time %s deleted subpop: %s", gen, sp)
                pop.removeSubPops(pop.subPopByName(sp))

            # update the migration matrix
            self._cached_migration_matrix = self._calculate_migration_matrix(
                gen)

            #self._dbg_slice_pop_end(pop,gen)

        sim.migrate(pop, self._cached_migration_matrix)
        sim.stat(pop, popSize=True)
        # cache the new subpopulation names and sizes for debug and logging purposes
        # before returning them to the calling function
        self.subpopulation_names = sorted(pop.subPopNames())
        self.subpop_sizes = pop.subPopSizes()
        return pop.subPopSizes()
Пример #4
0
# This file is part of simuPOP, a forward-time population genetics
# simulation environment. Please visit http://simupop.sourceforge.net
# for details.
#
# Copyright (C) 2004 - 2010 Bo Peng ([email protected])
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#

# This script is an example in the simuPOP user's guide. Please refer to
# the user's guide (http://simupop.sourceforge.net/manual) for a detailed
# description of this example.
#

import simuPOP as sim
pop = sim.Population([10] * 2, infoFields='migrate_to')
pop.setIndInfo([0, 1, 2, 3] * 5, 'migrate_to')
sim.migrate(pop, mode=sim.BY_IND_INFO)
pop.subPopSizes()
Пример #5
0
def migr(pop):
    numSP = pop.numSubPop()
    sim.migrate(pop, migrIslandRates(0.01, numSP))
    return True