aegis_sim.submodels.genetics.composite.architecture

 1import numpy as np
 2from aegis_sim import constants
 3from aegis_sim import variables
 4
 5from aegis_sim.submodels.genetics.composite.interpreter import Interpreter
 6from aegis_sim import parameterization
 7from aegis_sim.submodels.genetics import ploider
 8
 9
10class CompositeArchitecture:
11    """
12
13    GUI
14    - when pleiotropy is not needed;
15    - it is quick, easy to analyze, delivers a diversity of phenotypes
16    - every trait (surv repr muta neut) can be evolvable or not
17    - if not evolvable, the value is set by !!!
18    - if evolvable, it can be agespecific or age-independent
19    - probability of a trait at each age is determined by a BITS_PER_LOCUS adjacent bits forming a "locus" / gene
20    - the method by which these loci are converted into a phenotypic value is the Interpreter type
21
22    """
23
24    def __init__(self, BITS_PER_LOCUS, AGE_LIMIT, THRESHOLD):
25        self.BITS_PER_LOCUS = BITS_PER_LOCUS
26        self.n_loci = sum(trait.length for trait in parameterization.traits.values())
27        self.length = self.n_loci * BITS_PER_LOCUS
28        self.AGE_LIMIT = AGE_LIMIT
29
30        self.evolvable = [trait for trait in parameterization.traits.values() if trait.evolvable]
31
32        self.interpreter = Interpreter(
33            self.BITS_PER_LOCUS,
34            THRESHOLD,
35        )
36
37    def get_number_of_bits(self):
38        return ploider.ploider.y * self.n_loci * self.BITS_PER_LOCUS
39
40    def get_shape(self):
41        return (ploider.ploider.y, self.n_loci, self.BITS_PER_LOCUS)
42
43    def init_genome_array(self, popsize):
44        # TODO enable agespecific False
45        array = variables.rng.random(size=(popsize, *self.get_shape()))
46
47        for trait in parameterization.traits.values():
48            array[:, :, trait.slice] = array[:, :, trait.slice] < trait.initgeno
49
50        return array
51
52    def compute(self, genomes):
53
54        if genomes.shape[1] == 1:  # Do not calculate mean if genomes are haploid
55            genomes = genomes[:, 0]
56        else:
57            genomes = ploider.ploider.diploid_to_haploid(genomes)
58
59        interpretome = np.zeros(shape=(genomes.shape[0], genomes.shape[1]), dtype=np.float32)
60        for trait in parameterization.traits.values():
61            loci = genomes[:, trait.slice]  # fetch
62            probs = self.interpreter.call(loci, trait.interpreter)  # interpret
63            # self.diffuse(probs)
64            interpretome[:, trait.slice] += probs  # add back
65
66        return interpretome
67
68    # def diffuse(self, probs):
69    #     window_size = parametermanager.parameters.DIFFUSION_FACTOR * 2 + 1
70    #     p = np.empty(shape=(probs.shape[0], probs.shape[1] + window_size - 1))
71    #     p[:, :window_size] = np.repeat(probs[:, 0], window_size).reshape(-1, window_size)
72    #     p[:, window_size - 1 :] = probs[:]
73    #     diffusome = np.convolve(p[0], np.ones(window_size) / window_size, mode="valid")
74
75    def get_map(self):
76        pass
class CompositeArchitecture:
11class CompositeArchitecture:
12    """
13
14    GUI
15    - when pleiotropy is not needed;
16    - it is quick, easy to analyze, delivers a diversity of phenotypes
17    - every trait (surv repr muta neut) can be evolvable or not
18    - if not evolvable, the value is set by !!!
19    - if evolvable, it can be agespecific or age-independent
20    - probability of a trait at each age is determined by a BITS_PER_LOCUS adjacent bits forming a "locus" / gene
21    - the method by which these loci are converted into a phenotypic value is the Interpreter type
22
23    """
24
25    def __init__(self, BITS_PER_LOCUS, AGE_LIMIT, THRESHOLD):
26        self.BITS_PER_LOCUS = BITS_PER_LOCUS
27        self.n_loci = sum(trait.length for trait in parameterization.traits.values())
28        self.length = self.n_loci * BITS_PER_LOCUS
29        self.AGE_LIMIT = AGE_LIMIT
30
31        self.evolvable = [trait for trait in parameterization.traits.values() if trait.evolvable]
32
33        self.interpreter = Interpreter(
34            self.BITS_PER_LOCUS,
35            THRESHOLD,
36        )
37
38    def get_number_of_bits(self):
39        return ploider.ploider.y * self.n_loci * self.BITS_PER_LOCUS
40
41    def get_shape(self):
42        return (ploider.ploider.y, self.n_loci, self.BITS_PER_LOCUS)
43
44    def init_genome_array(self, popsize):
45        # TODO enable agespecific False
46        array = variables.rng.random(size=(popsize, *self.get_shape()))
47
48        for trait in parameterization.traits.values():
49            array[:, :, trait.slice] = array[:, :, trait.slice] < trait.initgeno
50
51        return array
52
53    def compute(self, genomes):
54
55        if genomes.shape[1] == 1:  # Do not calculate mean if genomes are haploid
56            genomes = genomes[:, 0]
57        else:
58            genomes = ploider.ploider.diploid_to_haploid(genomes)
59
60        interpretome = np.zeros(shape=(genomes.shape[0], genomes.shape[1]), dtype=np.float32)
61        for trait in parameterization.traits.values():
62            loci = genomes[:, trait.slice]  # fetch
63            probs = self.interpreter.call(loci, trait.interpreter)  # interpret
64            # self.diffuse(probs)
65            interpretome[:, trait.slice] += probs  # add back
66
67        return interpretome
68
69    # def diffuse(self, probs):
70    #     window_size = parametermanager.parameters.DIFFUSION_FACTOR * 2 + 1
71    #     p = np.empty(shape=(probs.shape[0], probs.shape[1] + window_size - 1))
72    #     p[:, :window_size] = np.repeat(probs[:, 0], window_size).reshape(-1, window_size)
73    #     p[:, window_size - 1 :] = probs[:]
74    #     diffusome = np.convolve(p[0], np.ones(window_size) / window_size, mode="valid")
75
76    def get_map(self):
77        pass

GUI

  • when pleiotropy is not needed;
  • it is quick, easy to analyze, delivers a diversity of phenotypes
  • every trait (surv repr muta neut) can be evolvable or not
  • if not evolvable, the value is set by !!!
  • if evolvable, it can be agespecific or age-independent
  • probability of a trait at each age is determined by a BITS_PER_LOCUS adjacent bits forming a "locus" / gene
  • the method by which these loci are converted into a phenotypic value is the Interpreter type
CompositeArchitecture(BITS_PER_LOCUS, AGE_LIMIT, THRESHOLD)
25    def __init__(self, BITS_PER_LOCUS, AGE_LIMIT, THRESHOLD):
26        self.BITS_PER_LOCUS = BITS_PER_LOCUS
27        self.n_loci = sum(trait.length for trait in parameterization.traits.values())
28        self.length = self.n_loci * BITS_PER_LOCUS
29        self.AGE_LIMIT = AGE_LIMIT
30
31        self.evolvable = [trait for trait in parameterization.traits.values() if trait.evolvable]
32
33        self.interpreter = Interpreter(
34            self.BITS_PER_LOCUS,
35            THRESHOLD,
36        )
BITS_PER_LOCUS
n_loci
length
AGE_LIMIT
evolvable
interpreter
def get_number_of_bits(self):
38    def get_number_of_bits(self):
39        return ploider.ploider.y * self.n_loci * self.BITS_PER_LOCUS
def get_shape(self):
41    def get_shape(self):
42        return (ploider.ploider.y, self.n_loci, self.BITS_PER_LOCUS)
def init_genome_array(self, popsize):
44    def init_genome_array(self, popsize):
45        # TODO enable agespecific False
46        array = variables.rng.random(size=(popsize, *self.get_shape()))
47
48        for trait in parameterization.traits.values():
49            array[:, :, trait.slice] = array[:, :, trait.slice] < trait.initgeno
50
51        return array
def compute(self, genomes):
53    def compute(self, genomes):
54
55        if genomes.shape[1] == 1:  # Do not calculate mean if genomes are haploid
56            genomes = genomes[:, 0]
57        else:
58            genomes = ploider.ploider.diploid_to_haploid(genomes)
59
60        interpretome = np.zeros(shape=(genomes.shape[0], genomes.shape[1]), dtype=np.float32)
61        for trait in parameterization.traits.values():
62            loci = genomes[:, trait.slice]  # fetch
63            probs = self.interpreter.call(loci, trait.interpreter)  # interpret
64            # self.diffuse(probs)
65            interpretome[:, trait.slice] += probs  # add back
66
67        return interpretome
def get_map(self):
76    def get_map(self):
77        pass