n49o7

Uni : AF-23 Simulation

May 4th, 2021 (edited)
917
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 2.70 KB | None | 0 0
  1. """
  2. Effect of outbreeding on genotype richness under arrhenotokous haploidiploidy.
  3.  
  4. [] population
  5. () individual
  6.  
  7. Example uses:
  8.  
  9. male = ('♂ a')
  10. female = ('♀ ac')
  11.  
  12. offspring(male, female, True)
  13.  
  14. has_diploid_males(('♂ aa', '♀ ac', '♂ a', '♂ c'), True)
  15.  
  16. males = [('aa'), ('b')]
  17. females = [('mn')]
  18.  
  19. run(*parse(males, females), True, False)
  20.  
  21. males = [('aa'), ('b')] + [('c')]
  22. females = [('mn')]
  23.  
  24. run(*parse(males, females), True, False)
  25. """
  26.  
  27. def f(sex, alleles):
  28.     return (f'{sex} {alleles}')
  29.  
  30. def offspring(male, female, sex_locus):
  31.     def a(i):
  32.         return i.split(' ')[-1]
  33.     def s(alleles):
  34.         sex = '♂' if alleles[0]==alleles[1] and sex_locus else '♀'
  35.         return f(sex, ''.join(sorted(alleles)))
  36.     male, female = (a(e) for e in (male, female))
  37.     x = itertools.product(male, female)
  38.     d = (s(i) for i in x)
  39.     h = (f('♂', i) for i in female)
  40.     return tuple(d) + tuple(h)
  41.  
  42. def has_diploid_males(offspring, count):
  43.     d = (e[0]=='♂' and e[2]==e[3] for e in offspring if len(e)==4)
  44.     return len([e for e in d if e]) if count else any(d)
  45.  
  46. def all_offspring(males, females, sex_locus, fertile_diploids):
  47.     def o(male, female):
  48.         return offspring(male, female, sex_locus)
  49.     if not fertile_diploids:
  50.         males = (e for e in males if len(e)<4)
  51.     i = itertools.product(males, females)
  52.     a = (o(male, female) for male, female in i)
  53.     x = functools.reduce(lambda x, y: {*x} | {*y}, a, {})
  54.     return tuple(x)
  55.  
  56. def sex_split(population):
  57.     males = [e for e in population if '♂' in e]
  58.     females = [e for e in population if '♀' in e]
  59.     return males, females
  60.  
  61. def summary(population):
  62.     m, f = (len(e) for e in sex_split(population))
  63.     w = len(population)
  64.     d = has_diploid_males(population, True)
  65.     return f'genotypes: {m} male, {f} female, {d} diploid male, {w} total'
  66.  
  67. def run(males, females, sex_locus, fertile_diploids, generations=5):
  68.     """
  69.        Parameters:
  70.        sex_locus: whether the alleles target the sex-determination locus
  71.        fertile_diploids: whether homozygous diploid males can reproduce
  72.    """
  73.     print(f'Generation 0:', end=' ')
  74.     population = tuple(males) + tuple(females)
  75.     print(summary(population))
  76.     print(population, end='\n\n')
  77.     for generation in range(1, generations):
  78.         print(f'Generation {generation}:', end=' ')
  79.         males, females = sex_split(population)
  80.         population = all_offspring(males, females, sex_locus, fertile_diploids) # !
  81.         print(summary(population))
  82.         print(population, end='\n\n')
  83.  
  84. def parse(males, females):
  85.     males = (f('♂', i) for i in males)
  86.     females = (f('♀', i) for i in females)
  87.     return males, females
Add Comment
Please, Sign In to add comment