Source code for simplicity.phenotype.update

# This file is part of SIMPLICITY
# Copyright (C) 2025 Pietro Gerletti
#
# 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 <https://www.gnu.org/licenses/>.

# -*- coding: utf-8 -*-

import simplicity.phenotype.distance as dis
import numpy as np

[docs] def immune_waning_fitness_score(population,lineage_genome,consensus): # get the hamming distance from the weighted consensus distance_from_weighted_consensus = dis.hamming_iw(lineage_genome,consensus) # compute fitness score infected_fraction = min((population.diagnosed + population.recovered)/population.size,1) non_infected_fraction = max((population.size-(population.diagnosed + population.recovered))/population.size,0) fitness_score = infected_fraction*distance_from_weighted_consensus + non_infected_fraction/population.active_lineages_n #epsilon = 1e-6 # fitness floor #fitness_score = max(fitness_score, epsilon) return fitness_score
# def update_relative_fitness(population): # infectious_i_list = sorted(population.infectious_i) # fitness_inf = [population.individuals[i]['fitness_score'] for i in infectious_i_list] # fitsum = np.sum(fitness_inf) # for i in infectious_i_list : # population.individuals[i]['fitness_score'] /= fitsum
[docs] def update_fitness_factory(type): ''' Factory of fitness update function. Returns update_fitness, depending on selected phenotype model. Update_fitness computes and assigns the fitness score of every intra host lineage for all individuals to be updated. ''' if type == "linear": def update_fitness(population,individuals_to_update): # individuals - dictionary of individuals in the simulation # individuals_to_update - indices of individuals to be updated for individual in sorted(individuals_to_update): fitness = [] for lineage_name in population.individuals[individual]['IH_lineages']: lineage_genome = population.get_lineage_genome(lineage_name) fitness.append(dis.hamming(lineage_genome)) population.individuals[individual]['IH_lineages_fitness_score'] = fitness population.individuals[individual]['fitness_score'] = np.average(fitness) # # update relative fitness scores for the population # update_relative_fitness(population) return update_fitness elif type == "immune_waning": def update_fitness(population,individuals_to_update,consensus): # individuals - dictionary of individuals in the simulation # individuals_to_update - indices of individuals to be updated # consensus - consensus sequence for individual_index in sorted(individuals_to_update): fitness = [] for lineage_name in population.individuals[individual_index]['IH_lineages']: lineage_genome = population.get_lineage_genome(lineage_name) fitness.append(immune_waning_fitness_score(population,lineage_genome,consensus)) population.individuals[individual_index]['IH_lineages_fitness_score'] = fitness population.individuals[individual_index]['fitness_score'] = np.average(fitness) # # update relative fitness scores for the population # update_relative_fitness(population) return update_fitness