Skip to content

Commit ff70092

Browse files
authored
Removing overdispersion, migration, vitaldynamics code and tests from DemographicsBase (Fix #32) (#39)
1 parent 4f42f63 commit ff70092

File tree

3 files changed

+1
-786
lines changed

3 files changed

+1
-786
lines changed

emod_api/demographics/demographics_base.py

Lines changed: 1 addition & 177 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,7 @@
11
import json
22
import math
33
import os
4-
import pathlib
54
import sys
6-
import tempfile
75
import warnings
86
from collections import Counter
97
from functools import partial
@@ -21,7 +19,6 @@
2119
from emod_api.demographics.age_distribution_old import AgeDistributionOld as AgeDistribution
2220
from emod_api.demographics.demographic_exceptions import InvalidNodeIdException
2321
from emod_api.demographics.mortality_distribution_old import MortalityDistributionOld as MortalityDistribution
24-
from emod_api.migration import migration
2522

2623

2724
class DemographicsBase(BaseInputFile):
@@ -366,43 +363,7 @@ def get_nodes_by_name(self, node_names: List[str]) -> Dict[str, Node]:
366363
if node_name in node_names}
367364
return requested_nodes
368365

369-
def SetMigrationPattern(self, pattern: str = "rwd"):
370-
"""
371-
Set migration pattern. Migration is enabled implicitly.
372-
It's unusual for the user to need to set this directly; normally used by emodpy.
373-
374-
Args:
375-
pattern: Possible values are "rwd" for Random Walk Diffusion and "srt" for Single Round Trips.
376-
"""
377-
if self.implicits is not None:
378-
if pattern.lower() == "srt":
379-
self.implicits.append(DT._set_migration_pattern_srt)
380-
elif pattern.lower() == "rwd":
381-
self.implicits.append(DT._set_migration_pattern_rwd)
382-
else:
383-
raise ValueError('Unknown migration pattern: %s. Possible values are "rwd" and "srt".', pattern)
384-
385-
def _SetRegionalMigrationFileName(self, file_name):
386-
"""
387-
Set path to migration file.
388-
389-
Args:
390-
file_name: Path to migration file.
391-
"""
392-
if self.implicits is not None:
393-
self.implicits.append(partial(DT._set_regional_migration_filenames, file_name=file_name))
394-
395-
def _SetLocalMigrationFileName(self, file_name):
396-
"""
397-
Set path to migration file.
398-
399-
Args:
400-
file_name: Path to migration file.
401-
"""
402-
if self.implicits is not None:
403-
self.implicits.append(partial(DT._set_local_migration_filename, file_name=file_name))
404-
405-
def _SetDemographicFileNames(self, file_names):
366+
def set_demographics_filenames(self, file_names: List[str]):
406367
"""
407368
Set paths to demographic file.
408369
@@ -412,127 +373,6 @@ def _SetDemographicFileNames(self, file_names):
412373
if self.implicits is not None:
413374
self.implicits.append(partial(DT._set_demographic_filenames, file_names=file_names))
414375

415-
def SetRoundTripMigration(self,
416-
gravity_factor: float,
417-
probability_of_return: float = 1.0,
418-
id_ref: str = 'short term commuting migration'):
419-
"""
420-
Set commuter/seasonal/temporary/round-trip migration rates. You can use the x_Local_Migration configuration
421-
parameter to tune/calibrate.
422-
423-
Args:
424-
gravity_factor: 'Big G' in gravity equation. Combines with 1, 1, and -2 as the other exponents.
425-
probability_of_return: Likelihood that an individual who 'commuter migrates' will return to the node
426-
of origin during the next migration (not timestep). Defaults to 1.0. Aka, travel,
427-
shed, return."
428-
id_ref: Text string that appears in the migration file itself; needs to match corresponding demographics
429-
file.
430-
"""
431-
if gravity_factor < 0:
432-
raise ValueError("gravity factor can't be negative.")
433-
434-
gravity_params = [gravity_factor, 1.0, 1.0, -2.0]
435-
if probability_of_return < 0 or probability_of_return > 1.0:
436-
raise ValueError(f"probability_of_return parameter passed by not a probability: {probability_of_return}")
437-
438-
mig = migration._from_demog_and_param_gravity(self, gravity_params=gravity_params,
439-
id_ref=id_ref,
440-
migration_type=migration.Migration.LOCAL)
441-
migration_file_path = tempfile.NamedTemporaryFile().name + ".bin"
442-
mig.to_file(migration_file_path)
443-
self.migration_files.append(migration_file_path)
444-
445-
if self.implicits is not None:
446-
self.implicits.append(partial(DT._set_local_migration_roundtrip_probability,
447-
probability_of_return=probability_of_return))
448-
self.implicits.append(partial(DT._set_local_migration_filename,
449-
file_name=pathlib.PurePath(migration_file_path).name))
450-
self.SetMigrationPattern("srt")
451-
452-
def SetOneWayMigration(self,
453-
rates_path: Union[str, os.PathLike],
454-
id_ref: str = 'long term migration'):
455-
"""
456-
Set one way migration. You can use the x_Regional_Migration configuration parameter to tune/calibrate.
457-
458-
Args:
459-
rates_path: Path to csv file with node-to-node migration rates. Format is: source (node id),destination
460-
(node id),rate.
461-
id_ref: Text string that appears in the migration file itself; needs to match corresponding demographics
462-
file.
463-
"""
464-
465-
mig = migration.from_csv(pathlib.Path(rates_path), id_ref=id_ref, mig_type=migration.Migration.REGIONAL)
466-
migration_file_path = tempfile.NamedTemporaryFile().name + ".bin"
467-
mig.to_file(migration_file_path)
468-
self.migration_files.append(migration_file_path)
469-
470-
if self.implicits is not None:
471-
self.implicits.append(partial(DT._set_regional_migration_roundtrip_probability, probability_of_return=0.0))
472-
self.implicits.append(partial(DT._set_regional_migration_filenames,
473-
file_name=pathlib.PurePath(migration_file_path).name))
474-
self.SetMigrationPattern("srt")
475-
476-
def SetSimpleVitalDynamics(self,
477-
crude_birth_rate: CrudeRate = CrudeRate(40),
478-
crude_death_rate: CrudeRate = CrudeRate(20),
479-
node_ids: List = None):
480-
"""
481-
Set fertility, mortality, and initial age with single birth rate and single mortality rate.
482-
483-
Args:
484-
crude_birth_rate: Birth rate, per year per kiloperson.
485-
crude_death_rate: Mortality rate, per year per kiloperson.
486-
node_ids: Optional list of nodes to limit these settings to.
487-
488-
"""
489-
490-
self.SetBirthRate(crude_birth_rate, node_ids)
491-
self.SetMortalityRate(crude_death_rate, node_ids)
492-
self.SetEquilibriumAgeDistFromBirthAndMortRates(crude_birth_rate, crude_death_rate, node_ids)
493-
494-
# TODO: is this useful in a way that warrants a special-case function in emodpy?
495-
# https://github.com/InstituteforDiseaseModeling/emod-api-old/issues/790
496-
def SetEquilibriumVitalDynamics(self,
497-
crude_birth_rate: CrudeRate = CrudeRate(40),
498-
node_ids: List = None):
499-
"""
500-
Set fertility, mortality, and initial age with single rate and mortality to achieve steady state population.
501-
502-
Args:
503-
crude_birth_rate: Birth rate. And mortality rate.
504-
node_ids: Optional list of nodes to limit these settings to.
505-
506-
"""
507-
508-
self.SetSimpleVitalDynamics(crude_birth_rate, crude_birth_rate, node_ids)
509-
510-
# TODO: is this useful in a way that warrants a special-case function in emodpy?
511-
# https://github.com/InstituteforDiseaseModeling/emod-api-old/issues/791
512-
def SetEquilibriumVitalDynamicsFromWorldBank(self,
513-
wb_births_df: pd.DataFrame,
514-
country: str,
515-
year: int,
516-
node_ids: List = None):
517-
"""
518-
Set steady-state fertility, mortality, and initial age with rates from world bank, for given country and year.
519-
520-
Args:
521-
wb_births_df: Pandas dataframe with World Bank birth rate by country and year.
522-
country: Country to pick from World Bank dataset.
523-
year: Year to pick from World Bank dataset.
524-
node_ids: Optional list of nodes to limit these settings to.
525-
526-
"""
527-
528-
try:
529-
birth_rate = CrudeRate(wb_births_df[wb_births_df['Country Name'] == country][str(year)].tolist()[0])
530-
# result_scale_factor = 2.74e-06 # assuming world bank units for input
531-
# birth_rate *= result_scale_factor # from births per 1000 pop per year to per person per day
532-
except Exception as ex:
533-
raise ValueError(f"Exception trying to find {year} and {country} in dataframe.\n{ex}")
534-
self.SetEquilibriumVitalDynamics(birth_rate, node_ids)
535-
536376
def SetDefaultIndividualAttributes(self):
537377
"""
538378
NOTE: This is very Measles-ish. We might want to move into MeaslesDemographics
@@ -888,22 +728,6 @@ def SetInitialAgeLikeSubSaharanAfrica(self, description=""):
888728

889729
self.SetInitialAgeExponential(description=description) # use default rate
890730

891-
def SetOverdispersion(self, new_overdispersion_value, nodes: List = None):
892-
"""
893-
Set the overdispersion value for the specified nodes (all if empty).
894-
"""
895-
if nodes is None:
896-
nodes = []
897-
898-
def enable_overdispersion(config):
899-
print("DEBUG: Setting 'Enable_Infection_Rate_Overdispersion' to 1.")
900-
config.parameters.Enable_Infection_Rate_Overdispersion = 1
901-
return config
902-
903-
if self.implicits is not None:
904-
self.implicits.append(enable_overdispersion)
905-
self.raw['Defaults']['NodeAttributes']["InfectivityOverdispersion"] = new_overdispersion_value
906-
907731
def SetInitPrevFromUniformDraw(self, min_init_prev, max_init_prev, description=""):
908732
"""
909733
Set Initial Prevalence (one value per node) drawn from an uniform distribution.

tests/test_config_demog.py

Lines changed: 0 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,6 @@ def get_config_as_object(self):
1919
def reset_config(self):
2020
self.config = self.get_config_as_object()
2121

22-
# Tests that if overdispersion is set, Enable_Infection_Rate_Overdispersion is True
23-
def test_age_dependent_transmission_config(self):
24-
for index in range(2):
25-
demog = Demographics.from_template_node()
26-
demog.SetDefaultProperties()
27-
if index:
28-
demog.SetOverdispersion(0.75)
29-
self.assertEqual(len(demog.implicits), 5 + index)
30-
demog.implicits[-1](self.config)
31-
if not index:
32-
self.assertEqual(self.config.parameters.Enable_Infection_Rate_Overdispersion, 0)
33-
else:
34-
self.assertEqual(self.config.parameters.Enable_Infection_Rate_Overdispersion, 1)
35-
3622
def test_set_birth_rate_config(self):
3723
demog = Demographics.from_template_node()
3824
self.config.parameters.Enable_Birth = 0 # since it is 1 by default

0 commit comments

Comments
 (0)