示例#1
0
 def generate_f_one(self, pop: sim.Population):
     """
     A very basic implementation of the F_1 cross between pairs of individuals. Relies on
     pre-formatting of desired mating pairs into an ordered list.
     [1, 3, 5, 11, 12, 9, 22, 2]
     The mating pattern would be:
     1x3, 5x11, 12x9, 22x2. Rearranging the order of the indices would change the mating
     pairs.
     :param pop:
     :type pop:
     :return:
     :rtype:
     """
     pop.dvars().generations[1] = 'F_1'
     pop.dvars().gen = 1
     pairs_of_founders = int(pop.popSize() / 2)
     self.odd_to_even(pop)
     print("Creating the F_one population from selected founders.")
     return pop.evolve(
         preOps=[
             sim.PyEval(r'"Generation: %d\n" % gen'),
             operators.CalcTripletFrequencies(),
             sim.PyExec('triplet_freq[gen]=tripletFreq'),
             sim.SplitSubPops(sizes=[2] * pairs_of_founders, randomize=False),
         ],
         matingScheme=sim.RandomMating(subPopSize=[1] * pairs_of_founders,
                                       ops=[sim.Recombinator(rates=0.01), sim.IdTagger(), sim.PedigreeTagger()]),
         gen=1,
     )
示例#2
0
 def _assertSize(self, sizes, initSize=[], startGen=0):
     '''This function is provided for testing purpose.
     '''
     self.intended_size = sizes
     pop = Population(size=initSize if initSize else self.init_size,
                      infoFields=self.info_fields)
     pop.dvars().gen = startGen
     pop.evolve(matingScheme=RandomSelection(subPopSize=self),
                postOps=PyOperator(self._checkSize, param=startGen),
                finalOps=PyOperator(self._checkSize, param=startGen),
                gen=self.num_gens)
示例#3
0
 def plot(self, filename='', title='', initSize=[]):
     '''Evolve a haploid population using a ``RandomSelection`` mating scheme
     using the demographic model. Print population size changes duringe evolution.
     An initial population size could be specified using parameter ``initSize``
     for a demographic model with dynamic initial population size. If a filename
     is specified and if matplotlib is available, this function draws a figure
     to depict the demographic model and save it to ``filename``. An optional
     ``title`` could be specified to the figure. Note that this function can
     not be plot demographic models that works for particular mating schemes
     (e.g. genotype dependent).'''
     if not self.init_size:
         if initSize:
             self.init_size = initSize
         else:
             raise ValueError(
                 'Specific self does not have a valid initial population size'
             )
     if filename and not has_plotter:
         raise RuntimeError(
             'This function requires module numpy and matplotlib')
     self.draw_figure = filename and has_plotter
     self.pop_regions = OrderedDict()
     self.pop_base = OrderedDict()
     #
     self._reset()
     if title:
         print(title)
     pop = Population(self.init_size, infoFields=self.info_fields, ploidy=1)
     pop.evolve(matingScheme=RandomSelection(subPopSize=self),
                postOps=PyOperator(self._recordPopSize),
                gen=self.num_gens)
     self._recordPopSize(pop)
     #
     if self.draw_figure:
         fig = plt.figure()
         ax = fig.add_subplot(111)
         ax.spines['right'].set_visible(False)
         ax.spines['top'].set_visible(False)
         ax.xaxis.set_ticks_position('bottom')
         ax.yaxis.set_ticks_position('left')
         for name, region in self.pop_regions.items():
             region = region.reshape(region.size / 4, 4)
             points = np.append(region[:, 0:2], region[::-1, 2:4], axis=0)
             plt.fill(points[:, 0],
                      points[:, 1],
                      label=name,
                      linewidth=0,
                      edgecolor='w')
         leg = plt.legend(loc=2)
         leg.draw_frame(False)
         if title:
             plt.title(title)
         plt.savefig(filename)
         plt.close()
示例#4
0
 def _assertSize(self, sizes, initSize=[], startGen=0):
     '''This function is provided for testing purpose.
     '''
     self.intended_size = sizes
     pop = Population(size=initSize if initSize else self.init_size,
         infoFields=self.info_fields)
     pop.dvars().gen = startGen
     pop.evolve(
         matingScheme=RandomSelection(subPopSize=self),
         postOps=PyOperator(self._checkSize, param=startGen),
         finalOps=PyOperator(self._checkSize, param=startGen),
         gen=self.num_gens
     )
示例#5
0
 def plot(self, filename='', title='', initSize=[]):
     '''Evolve a haploid population using a ``RandomSelection`` mating scheme
     using the demographic model. Print population size changes duringe evolution.
     An initial population size could be specified using parameter ``initSize``
     for a demographic model with dynamic initial population size. If a filename
     is specified and if matplotlib is available, this function draws a figure
     to depict the demographic model and save it to ``filename``. An optional
     ``title`` could be specified to the figure. Note that this function can
     not be plot demographic models that works for particular mating schemes
     (e.g. genotype dependent).'''
     if not self.init_size:
         if initSize:
             self.init_size = initSize
         else:
             raise ValueError('Specific self does not have a valid initial population size')
     if filename and not has_plotter:
         raise RuntimeError('This function requires module numpy and matplotlib')
     self.draw_figure = filename and has_plotter
     self.pop_regions = OrderedDict()
     self.pop_base = OrderedDict()
     #
     self._reset()
     if title:
         print(title)
     pop = Population(self.init_size, infoFields=self.info_fields, ploidy=1)
     pop.evolve(
         matingScheme=RandomSelection(subPopSize=self),
         postOps=PyOperator(self._recordPopSize),
         gen=self.num_gens
     )
     self._recordPopSize(pop)
     # 
     if self.draw_figure:
         fig = plt.figure()
         ax = fig.add_subplot(111)
         ax.spines['right'].set_visible(False)
         ax.spines['top'].set_visible(False)
         ax.xaxis.set_ticks_position('bottom')
         ax.yaxis.set_ticks_position('left')
         for name, region in self.pop_regions.items():
             region = region.reshape(region.size / 4, 4)
             points = np.append(region[:, 0:2],
                 region[::-1, 2:4], axis=0)
             plt.fill(points[:,0], points[:,1], label=name, linewidth=0, edgecolor='w')
         leg = plt.legend(loc=2)
         leg.draw_frame(False)
         if title:
             plt.title(title)
         plt.savefig(filename)
         plt.close()
示例#6
0
def calculate_additive_trait(pop: sim.Population, trait_information_field: str,
                             allele_effects_array: np.ndarray):
    """
    Calculates additive trait ``trait_information_field`` by summing allele
    effects at each qtl.

    :param pop:
    :param trait_information_field:
    :param allele_effects_array:
    :return:
    """
    for ind in pop.individuals():
        ind.setInfo(
            sum(allele_effects_array[range(pop.totNumLoci()),
                                     np.asarray(ind.genotype(ploidy=0))] +
                allele_effects_array[range(pop.totNumLoci()),
                                     np.asarray(ind.genotype(ploidy=1))]),
            trait_information_field)
示例#7
0
def meta_population_information_writer(meta_pop: sim.Population,
                                       info_field_list: list, filename: str):
    """
    Writes information equivalent to a simuPOP.utils Exporter; however, this function is much more
     flexible. I am uncertain of what information will be necessary in the future.
    :param info_field_list: List of information fields to be included in output file.
    :param filename: Name of output file.
    :return: CSV File 'filename'
    """

    for i in range(meta_pop.numSubPop()):
        full_filename = filename + "_" + str(i) + ".txt"
        with open(full_filename, 'w') as info:
            info_writer = csv.writer(info, delimiter=',')
            info_writer.writerow(info_field_list)
            for ind in meta_pop.individuals(i):
                info_writer.writerow(
                    [ind.ind_id, ind.mother_id, ind.father_id, ind.ge, ind.pe])
示例#8
0
 def _generate_f_two(self, pop: sim.Population) -> sim.Population:
     """
     Creates an F2 subpopulations generation by selfing the individuals of 'pop'. Works on a population with one
     or more subpopulations.
     """
     pop.vars()['generations'][2] = 'F_2'
     self.odd_to_even(pop)
     num_sub_pops = pop.numSubPop()
     progeny_per_individual = int(self.selected_population_size/2)
     print("Creating the F_two population.")
     return pop.evolve(
         preOps=[
             sim.MergeSubPops(),
             sim.PyEval(r'"Generation: %d\n" % gen'),
             operators.CalcTripletFreq(),
             sim.PyExec('triplet_freq[gen]=tripletFreq'),
             sim.SplitSubPops(sizes=[1]*num_sub_pops, randomize=False),
         ],
         matingScheme=sim.SelfMating(subPopSize=[progeny_per_individual] * num_sub_pops,
                                     numOffspring=progeny_per_individual,
                                     ops=[sim.Recombinator(rates=0.01), sim.IdTagger(), sim.PedigreeTagger()],
                                     ),
         gen=1,
     )
示例#9
0
 def _mate_and_merge(self, pop: sim.Population):
     starting_gen = pop.vars()['gen']
     print("Initiating recombinatorial convergence at generation: %d" % pop.dvars().gen)
     while pop.numSubPop() > 1:
         pop.vars()['generations'][pop.vars()['gen']] = 'IG'+str(pop.vars()['gen'] - starting_gen)
         self.pop_halver(pop)
         self.odd_to_even(pop)
         self.pairwise_merge_protocol(pop)
         sub_pop_sizes = list(pop.subPopSizes())
         pop.evolve(
             preOps=[
                 sim.MergeSubPops(),
                 sim.PyEval(r'"Generation: %d\n" % gen'),
                 operators.CalcTripletFreq(),
                 sim.PyExec('triplet_freq[gen]=tripletFreq'),
                 sim.SplitSubPops(sizes=sub_pop_sizes, randomize=False),
             ],
             matingScheme=sim.RandomMating(ops=[sim.Recombinator(rates=0.01),
                                                sim.IdTagger(), sim.PedigreeTagger()]),
             gen=1,
         )
示例#10
0
def find_minor_alleles(pop: sim.Population):
    minor_allele_frequencies = col.OrderedDict()
    minor_alleles = np.empty(pop.totNumLoci())
    for locus in range(pop.totNumLoci()):
        if len(list(pop.dvars().alleleFreq[locus].keys())) >= 2:
            minor_allele_frequencies[locus] = min(
                pop.dvars().alleleFreq[locus].values())
            for k in pop.dvars().alleleFreq[locus].keys():
                if pop.dvars(
                ).alleleFreq[locus][k] == minor_allele_frequencies[locus]:
                    minor_alleles[locus] = k
        elif len(list(pop.dvars().alleleFreq[locus].keys())) == 1:
            # If an allele is at fixation then we want to show a zero for the MAC format.
            minor_alleles[locus] = 7
    return minor_alleles
示例#11
0
def population_information_writer(pop: sim.Population, info_field_list: list,
                                  filename: str):
    """
    Writes information equivalent to a simuPOP.utils Exporter; however, this function is much more
     flexible. I am uncertain of what information will be necessary in the future.
    :param pop: sim.Population
    :param info_field_list: List of information fields to be included in output file.
    :param filename: Name of output file.
    :return: CSV File 'filename'
    """
    with open(filename, 'w') as info:
        info_writer = csv.writer(info, delimiter=',')
        info_writer.writerow(info_field_list)
        for ind in pop.individuals():
            info_writer.writerow([
                ind.ind_id, ind.mother_id, ind.father_id, ind.ge, ind.pe,
                ind.fitness,
                ind.genotype()
            ])
示例#12
0
def write_info_fields_to_file(pop: sim.Population, info_fields: list,
                              output_filename: str, fmt_string):
    """
    Utilize numpy's simple numpy.savetxt function to write various types of pop.IndInfo(info_string) to files.
    Superior solution to using csv.writer's for simple .txt output.
    + Example
    ----------
    pop.infoFields() = ('ind_id', 'ge', 'pe')
    info_fields = ['ind_id', 'ge', 'pe']
    info_array = np.array([pop.indInfo(info) for info in info_fields])
    np.savetxt(output_filename, info_array, delimiter='\t', newline='\n', header=">Generation: pop.dvars().gen",
        comments='')
    """
    info_array = np.array([pop.indInfo(info) for info in info_fields]).T
    np.savetxt(output_filename,
               info_array,
               fmt='%d\t%.2f\t%.2f',
               delimiter='\t',
               newline='\n',
               header=">Generation: 0\nID\tG\tP",
               comments='')
示例#13
0
# 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.
#

from simuPOP import InitGenotype, Population


def initGenotype(pop, *args, **kwargs):
    InitGenotype(*args, **kwargs).apply(pop)


pop = Population(1000, loci=[2, 3])
initGenotype(pop, freq=[.2, .3, .5])
示例#14
0
def table_for_development(prefounders: sim.Population, founders: list,
                          pop: sim.Population, replicate_type: str):
    """
    Function to generate a summary data table for population subjected to either drift or selection.

    :param prefounders: Population from which all populations are derived
    :param founders: List of integers specifying which prefounders to use in making a population
    :param pop: Population subjected to either drift or selection
    :param replicate_type: String either 'drift' or 'selection' reflecting whether 'pop' is subjected to drift or
    selection
    :return: hierarchically indexed pandas.DataFrame with frequency and effect data for all qtl
    """
    data = []
    columns = [
        'QTL', 'Chromosome', 'cM_Position', 'Singlet', 'SingletEffect',
        'SingletFrequency', 'Triplet', 'TripletEffect', 'NumberOfFounders'
    ]
    generational_columns = [
        pop.dvars().generations[i] for i in range(pop.dvars().gen)
    ]
    columns.extend(generational_columns)
    chromosomes, relative_positions = chromosome_abs_and_rel(pop)
    qtls = []
    stf = test_subloci_calc_freq(prefounders, pop)
    for i in range(len(pop.dvars().properQTL)):
        qtls.append(prefounders.dvars().properQTL[i] - 1)
        qtls.append(prefounders.dvars().properQTL[i])
        qtls.append(prefounders.dvars().properQTL[i] + 1)
    for qtl in pop.dvars().properQTL:
        for trip in sorted(list(pop.vars()['triplet_freq'][0][qtl].keys())):
            for i in range(3):
                datarow = [
                    qtl,  # locus
                    chromosomes[qtl],  # chromosome of locus
                    relative_positions[qtl] + index_to_cM(i),  # position in cM
                    trip[i],  # singlet
                    pop.dvars().alleleEffects[qtl + i - 1,
                                              int(trip[i])],  # singlet effect
                    stf[qtl, qtl + i - 1][trip[i]],  # singlet frequency
                    trip,  # triplet
                    sum([
                        pop.dvars().alleleEffects[
                            qtl - 1, int(trip[0])],  # triplet effect
                        pop.dvars().alleleEffects[qtl, int(trip[1])],
                        pop.dvars().alleleEffects[qtl + 1,
                                                  int(trip[2])]
                    ]),
                    len(founders)
                ]  # number of founders selected from prefounders
                frq_per_gen = [
                    pop.vars()['triplet_freq'][j][qtl][trip] for j in range(8)
                ]
                rep_frq_per_gen = [
                    pop.vars()[replicate_type + '_triplet_freq'][k][qtl][trip]
                    for k in range(8,
                                   pop.dvars().gen)
                ]
                frq_per_gen.extend(rep_frq_per_gen)
                datarow.extend(frq_per_gen)
                data.append(datarow)
    s = pd.DataFrame(data, columns=columns)
    for i in range(8, 13):
        for term in pop.dvars().mav_terms:
            s.set_value(term,
                        pop.dvars().generations[i],
                        pop.dvars().mavs[i, term])
    return s.fillna(0)