def _add_flow(self, requested_flow): flow = None f_source = requested_flow.get("origin") f_source = Compartment.deserialize(f_source) if f_source else None f_dest = requested_flow.get("to") f_dest = Compartment.deserialize(f_dest) if f_dest else None f_param = requested_flow["parameter"] f_type = requested_flow["type"] if f_type == Flow.STANDARD: flow = StandardFlow( source=f_source, dest=f_dest, param_name=f_param, param_func=self.get_parameter_value, ) elif f_type == Flow.INFECTION_FREQUENCY: flow = InfectionFrequencyFlow( source=f_source, dest=f_dest, param_name=f_param, param_func=self.get_parameter_value, find_infectious_multiplier=self.get_infection_frequency_multiplier, ) elif f_type == Flow.INFECTION_DENSITY: flow = InfectionDensityFlow( source=f_source, dest=f_dest, param_name=f_param, param_func=self.get_parameter_value, find_infectious_multiplier=self.get_infection_density_multiplier, ) elif f_type == Flow.DEATH: flow = InfectionDeathFlow( source=f_source, param_name=f_param, param_func=self.get_parameter_value ) elif f_type == Flow.IMPORT: flow = ImportFlow( dest=self.entry_compartment, param_name=f_param, param_func=self.get_parameter_value, ) if flow: self.flows.append(flow) return flow
def __init__( self, times: List[float], compartment_names: List[str], initial_conditions: Dict[str, float], parameters: Dict[str, float], requested_flows: List[dict], infectious_compartments: List[str], birth_approach: str, entry_compartment: str, starting_population: int, ): super().__init__( times=times, compartment_names=compartment_names, initial_conditions=initial_conditions, parameters=parameters, requested_flows=requested_flows, infectious_compartments=infectious_compartments, birth_approach=birth_approach, entry_compartment=entry_compartment, starting_population=starting_population, ) # Keeps track of Stratifications that have been applied. self.stratifications = [] # Keeps track of original, pre-stratified compartment names. self.original_compartment_names = [Compartment.deserialize(n) for n in compartment_names] # A list of the different sub-categories ('strains') of the diease that we are modelling. self.disease_strains = [self.DEFAULT_DISEASE_STRAIN] # Strata-based multipliers for compartmental infectiousness levels. self.infectiousness_levels = {} # Compartment-based overwrite values for compartmental infectiousness levels. self.individual_infectiousness_adjustments = [] # Mixing matrices a list of NxN arrays used to calculate force of infection. self.mixing_matrices = [] # A list of dicts that has the strata required to match a row in the mixing matrix. self.mixing_categories = [{}]
def test_deserialzie(): s = "infectedXlocation_hawaiiXage_15" c = Compartment.deserialize(s) assert c == Compartment( "infected", strat_names=["location", "age"], strat_values={ "location": "hawaii", "age": "15" }, ) assert c != Compartment( "infected", strat_names=["age", "location"], strat_values={ "location": "hawaii", "age": "15" }, ) assert str(c) == "infectedXlocation_hawaiiXage_15" assert hash(c) == hash("infectedXlocation_hawaiiXage_15")
def __init__( self, times: List[float], compartment_names: List[str], initial_conditions: Dict[str, float], parameters: Dict[str, float], requested_flows: List[dict], birth_approach: str, starting_population: int, infectious_compartments: List[str], entry_compartment: str, ): model_kwargs = { "times": times, "compartment_names": compartment_names, "initial_conditions": initial_conditions, "parameters": parameters, "requested_flows": requested_flows, "birth_approach": birth_approach, "starting_population": starting_population, "infectious_compartments": infectious_compartments, "entry_compartment": entry_compartment, } validate_model(model_kwargs) # Flows self.flows = [] self.time_variants = {} self.parameters = {} # Compartments self.compartment_names = [Compartment(n) for n in compartment_names] self.infectious_compartments = [Compartment(n) for n in infectious_compartments] # Derived outputs self.derived_outputs = {} self._derived_calc = DerivedOutputCalculator() self.times = times # Populate model compartments with the values set in `initial conditions`. self.compartment_values = np.zeros(len(compartment_names)) pop_remainder = starting_population - sum(initial_conditions.values()) for idx, comp_name in enumerate(compartment_names): if comp_name in initial_conditions: self.compartment_values[idx] = initial_conditions[comp_name] if comp_name == entry_compartment: self.compartment_values[idx] += pop_remainder self.birth_approach = birth_approach self.parameters = parameters self.parameters["crude_birth_rate"] = self.parameters.get("crude_birth_rate", 0) self.parameters["universal_death_rate"] = self.parameters.get("universal_death_rate", 0) # Add user-specified flows self.entry_compartment = Compartment.deserialize(entry_compartment) self.flows = [] for requested_flow in requested_flows: self._add_flow(requested_flow) # Add birth flows. if ( self.birth_approach == BirthApproach.ADD_CRUDE and self.parameters["crude_birth_rate"] > 0 ): flow = CrudeBirthFlow( dest=self.entry_compartment, param_name="crude_birth_rate", param_func=self.get_parameter_value, ) self.flows.append(flow) elif self.birth_approach == BirthApproach.REPLACE_DEATHS: self.total_deaths = 0 flow = ReplacementBirthFlow( dest=self.entry_compartment, get_total_deaths=self.get_total_deaths ) self.flows.append(flow) # Add non-disease death flows if requested if self.parameters["universal_death_rate"] > 0: for compartment_name in self.compartment_names: flow = UniversalDeathFlow( source=compartment_name, param_name="universal_death_rate", param_func=self.get_parameter_value, ) self.flows.append(flow) # Update indices for quick lookups. self._update_flow_compartment_indices() for idx, c in enumerate(self.compartment_names): c.idx = idx
def test_create_ageing_flows(): strat = Stratification( name="age", strata=["0", "10", "30", "40"], compartments=["S", "I"], comp_split_props={}, flow_adjustments={}, ) previous_compartments = [ Compartment("S", strat_names=["location"], strat_values={"location": "home"}), Compartment("S", strat_names=["location"], strat_values={"location": "work"}), Compartment("I", strat_names=["location"], strat_values={"location": "home"}), Compartment("I", strat_names=["location"], strat_values={"location": "work"}), Compartment("R", strat_names=["location"], strat_values={"location": "home"}), Compartment("R", strat_names=["location"], strat_values={"location": "work"}), ] ageing_flows, ageing_params = AgeingFlow.create(strat, previous_compartments, _get_param_value) assert ageing_params == {"ageing0to10": 0.1, "ageing10to30": 0.05, "ageing30to40": 0.1} flow = ageing_flows[0] assert flow.source == Compartment.deserialize("SXlocation_homeXage_0") assert flow.dest == Compartment.deserialize("SXlocation_homeXage_10") assert flow.param_name == "ageing0to10" assert flow.param_func == _get_param_value flow = ageing_flows[1] assert flow.source == Compartment.deserialize("SXlocation_workXage_0") assert flow.dest == Compartment.deserialize("SXlocation_workXage_10") assert flow.param_name == "ageing0to10" assert flow.param_func == _get_param_value flow = ageing_flows[2] assert flow.source == Compartment.deserialize("IXlocation_homeXage_0") assert flow.dest == Compartment.deserialize("IXlocation_homeXage_10") assert flow.param_name == "ageing0to10" assert flow.param_func == _get_param_value flow = ageing_flows[3] assert flow.source == Compartment.deserialize("IXlocation_workXage_0") assert flow.dest == Compartment.deserialize("IXlocation_workXage_10") assert flow.param_name == "ageing0to10" assert flow.param_func == _get_param_value flow = ageing_flows[4] assert flow.source == Compartment.deserialize("SXlocation_homeXage_10") assert flow.dest == Compartment.deserialize("SXlocation_homeXage_30") assert flow.param_name == "ageing10to30" assert flow.param_func == _get_param_value flow = ageing_flows[5] assert flow.source == Compartment.deserialize("SXlocation_workXage_10") assert flow.dest == Compartment.deserialize("SXlocation_workXage_30") assert flow.param_name == "ageing10to30" assert flow.param_func == _get_param_value flow = ageing_flows[6] assert flow.source == Compartment.deserialize("IXlocation_homeXage_10") assert flow.dest == Compartment.deserialize("IXlocation_homeXage_30") assert flow.param_name == "ageing10to30" assert flow.param_func == _get_param_value flow = ageing_flows[7] assert flow.source == Compartment.deserialize("IXlocation_workXage_10") assert flow.dest == Compartment.deserialize("IXlocation_workXage_30") assert flow.param_name == "ageing10to30" assert flow.param_func == _get_param_value flow = ageing_flows[8] assert flow.source == Compartment.deserialize("SXlocation_homeXage_30") assert flow.dest == Compartment.deserialize("SXlocation_homeXage_40") assert flow.param_name == "ageing30to40" assert flow.param_func == _get_param_value flow = ageing_flows[9] assert flow.source == Compartment.deserialize("SXlocation_workXage_30") assert flow.dest == Compartment.deserialize("SXlocation_workXage_40") assert flow.param_name == "ageing30to40" assert flow.param_func == _get_param_value flow = ageing_flows[10] assert flow.source == Compartment.deserialize("IXlocation_homeXage_30") assert flow.dest == Compartment.deserialize("IXlocation_homeXage_40") assert flow.param_name == "ageing30to40" assert flow.param_func == _get_param_value flow = ageing_flows[11] assert flow.source == Compartment.deserialize("IXlocation_workXage_30") assert flow.dest == Compartment.deserialize("IXlocation_workXage_40") assert flow.param_name == "ageing30to40" assert flow.param_func == _get_param_value