Age is an important factor in many applications because it is related to many genetic (most obviously mating) and environmental factors that influence the evolution of a population. The evolution of age structured populations will lead to overlapping generations because parents can co-exist with their offspring in such a population. Although simuPOP is based on a discrete generation model, it can be used to simulate age structured populations.
To evolve an age structured population, you will need to
Example ageStructured gives an example of the evolution of age-structured population.
Example: Example of the evolution of age-structured population.
>>> import simuPOP as sim
>>> import random
>>> N = 10000
>>> pop = sim.Population(N, loci=1, infoFields=['age', 'ind_id', 'father_id', 'mother_id'])
>>> pop.setVirtualSplitter(sim.InfoSplitter(field='age', cutoff=[20, 50, 75]))
>>> def demoModel(gen, pop):
... '''A demographic model that keep a constant supply of new individuals'''
... # number of individuals that will die
... sim.stat(pop, popSize=True, subPops=[(0,3)])
... # individuals that will be kept, plus some new guys.
... return pop.popSize() - pop.dvars().popSize + N / 75
...
>>> def pene(geno, age, ind):
... 'Define an age-dependent penetrance function'
... # this disease does not occur in children
... if age < 16:
... return 0
... # if an individual is already affected, keep so
... if ind.affected():
... return 1
... # the probability of getting disease increases with age
... return (0., 0.001*age, 0.001*age)[sum(geno)]
...
>>> def outputstat(pop):
... 'Calculate and output statistics'
... sim.stat(pop, popSize=True, numOfAffected=True,
... subPops=[(0, sim.ALL_AVAIL)],
... vars=['popSize_sp', 'propOfAffected_sp'])
... for sp in range(3):
... print('%s: %.3f%% (size %d)' % (pop.subPopName((0,sp)),
... pop.dvars((0,sp)).propOfAffected * 100.,
... pop.dvars((0,sp)).popSize))
... #
... return True
...
>>>
>>> pop.evolve(
... initOps=[
... sim.InitSex(),
... # random assign age
... sim.InitInfo(lambda: random.randint(0, 75), infoFields='age'),
... # random genotype
... sim.InitGenotype(freq=[0.5, 0.5]),
... # assign an unique ID to everyone.
... sim.IdTagger(),
... sim.PyOutput('Prevalence of disease in each age group:\n'),
... ],
... # increase the age of everyone by 1 before mating.
... preOps=sim.InfoExec('age += 1'),
... matingScheme=sim.HeteroMating([
... # all individuals with age < 75 will be kept. Note that
... # CloneMating will keep individual sex, affection status and all
... # information fields (by default).
... sim.CloneMating(subPops=[(0,0), (0,1), (0,2)], weight=-1),
... # only individuals with age between 20 and 50 will mate and produce
... # offspring. The age of offspring will be zero.
... sim.RandomMating(ops=[
... sim.IdTagger(), # give new born an ID
... sim.PedigreeTagger(), # track parents of each individual
... sim.MendelianGenoTransmitter(), # transmit genotype
... ],
... numOffspring=(sim.UNIFORM_DISTRIBUTION, 1, 3),
... subPops=[(0,1)]),],
... subPopSize=demoModel),
... # number of individuals?
... postOps=[
... sim.PyPenetrance(func=pene, loci=0),
... sim.PyOperator(func=outputstat, step=20)
... ],
... gen = 200
... )
Prevalence of disease in each age group:
age < 20: 0.381% (size 2628)
20 <= age < 50: 2.504% (size 3953)
50 <= age < 75: 4.814% (size 3282)
age < 20: 0.639% (size 2660)
20 <= age < 50: 26.901% (size 3933)
50 <= age < 75: 50.407% (size 3313)
age < 20: 0.526% (size 2660)
20 <= age < 50: 27.720% (size 3961)
50 <= age < 75: 60.744% (size 3332)
age < 20: 0.489% (size 2660)
20 <= age < 50: 29.624% (size 3990)
50 <= age < 75: 62.121% (size 3300)
age < 20: 0.639% (size 2660)
20 <= age < 50: 28.045% (size 3990)
50 <= age < 75: 63.188% (size 3325)
age < 20: 0.564% (size 2660)
20 <= age < 50: 28.922% (size 3990)
50 <= age < 75: 60.722% (size 3325)
age < 20: 0.714% (size 2660)
20 <= age < 50: 28.371% (size 3990)
50 <= age < 75: 61.774% (size 3325)
age < 20: 0.526% (size 2660)
20 <= age < 50: 29.298% (size 3990)
50 <= age < 75: 60.451% (size 3325)
age < 20: 0.714% (size 2660)
20 <= age < 50: 29.649% (size 3990)
50 <= age < 75: 61.083% (size 3325)
age < 20: 0.414% (size 2660)
20 <= age < 50: 28.897% (size 3990)
50 <= age < 75: 63.218% (size 3325)
200L
>>>
>>> # draw two Pedigrees from the last age-structured population
>>> from simuPOP import sampling
>>> sample = sampling.drawNuclearFamilySample(pop, families=2, numOffspring=(2,3),
... affectedParents=(1,2), affectedOffspring=(1,3))
>>> sim.dump(sample)
Ploidy: 2 (diploid)
Chromosomes:
1: (AUTOSOME, 1 loci)
(1)
Information fields:
age ind_id father_id mother_id
population size: 8 (1 subpopulations with 8 Individuals)
Number of ancestral populations: 0
SubPopulation 0 (), 8 Individuals:
0: MA 1 | 0 | 41 31100 28012 27744
1: FA 1 | 1 | 34 31950 27515 26655
2: FA 1 | 1 | 66 27744 22633 22484
3: FA 1 | 0 | 74 26655 20957 20911
4: FU 1 | 0 | 41 31099 28012 27744
5: FU 0 | 1 | 34 31949 27515 26655
6: MA 1 | 0 | 64 28012 23909 23470
7: MU 1 | 1 | 68 27515 24745 21596
>>>