Skip to content
This repository was archived by the owner on Nov 24, 2021. It is now read-only.

Commit 088d145

Browse files
authored
Merge pull request #20 from covid-modeling/adityasharad/covidsim-regions
CovidSim connector: Refactor regional parameter file lookup
2 parents a3f2767 + cf4e19b commit 088d145

File tree

2 files changed

+165
-48
lines changed

2 files changed

+165
-48
lines changed

packages/mrc-ide-covidsim/src/imperial.ts

Lines changed: 75 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -45,63 +45,91 @@ export class ImperialModel implements Model {
4545
this.threadCount = threadCount
4646
}
4747

48+
/** Gets the path to the administrative units parameter file for the given region. */
49+
private getAdminPath(region: string): string {
50+
if (region === 'US') {
51+
return path.join(this.dataDir, 'admin_units', 'United_States_admin.txt')
52+
} else if (COUNTRY_PARAMS_BY_ISO_CODE[region]) {
53+
const { adminFileName } = COUNTRY_PARAMS_BY_ISO_CODE[region]
54+
return path.join(this.dataDir, 'admin_units', adminFileName)
55+
} else {
56+
throw new Error(`Could not find admin file for region ${region}`)
57+
}
58+
}
59+
60+
/**
61+
* Gets the path to the population density parameter file for the given region.
62+
* Europe is used as the default.
63+
*/
64+
private getPopulationDensityPath(region: string, subregion?: string): string {
65+
let populationDensityFileName: string
66+
if (
67+
['AS', 'GU', 'PR', 'VI'].includes(region) ||
68+
(region === 'US' &&
69+
['US-AK', 'US-HI', 'US-AS', 'US-GU', 'US-PR', 'US-VI'].includes(
70+
subregion
71+
))
72+
) {
73+
populationDensityFileName = 'wpop_us_terr.txt'
74+
} else if (['US', 'CA'].includes(region)) {
75+
populationDensityFileName = 'wpop_usacan.txt'
76+
} else {
77+
populationDensityFileName = 'wpop_eur.txt'
78+
}
79+
return path.join(this.dataDir, 'populations', populationDensityFileName)
80+
}
81+
82+
/**
83+
* Gets the path to the pre-parameters template file for the given region.
84+
* The UK is used as the default for known regions.
85+
*/
86+
private getPreParametersTemplatePath(region: string): string {
87+
let preParamsFileName: string
88+
if (region === 'US') {
89+
preParamsFileName = 'preUS_R0=2.0.txt'
90+
} else if (COUNTRY_PARAMS_BY_ISO_CODE[region]) {
91+
preParamsFileName =
92+
COUNTRY_PARAMS_BY_ISO_CODE[region].preParamsFileName ??
93+
'preUK_R0=2.0.txt'
94+
} else {
95+
throw new Error(
96+
`Could not find pre-parameters template file for region ${region}`
97+
)
98+
}
99+
return path.join(this.dataDir, 'param_files', preParamsFileName)
100+
}
101+
102+
private getSubregionName(region: string, subregion: string): string {
103+
if (region === 'US') {
104+
return US_SUBREGIONS[subregion]
105+
} else if (COUNTRY_PARAMS_BY_ISO_CODE[region]) {
106+
const { subregions } = COUNTRY_PARAMS_BY_ISO_CODE[region]
107+
return subregions[subregion]
108+
} else {
109+
throw new Error(`Could not find subregions for region ${region}`)
110+
}
111+
}
112+
48113
inputs(input: input.ModelInput): ImperialRunnerModelInput {
49114
const inputFiles = []
50-
// Select the correct executable and static inputs based on the region.
51-
let adminPath,
52-
populationDensityPath,
53-
preParametersTemplatePath,
54-
subregionName
55115

56116
const modelPath = path.join(this.binDir, 'CovidSim')
57117

118+
// Select the correct static inputs based on the region.
119+
let adminPath = this.getAdminPath(input.region)
120+
const populationDensityPath = this.getPopulationDensityPath(
121+
input.region,
122+
input.subregion
123+
)
58124
const parametersTemplatePath = path.join(
59125
this.dataDir,
60126
'param_files',
61127
'p_NoInt.txt'
62128
)
63-
64-
// The US has its own executable, population density file, and pre-params file.
65-
if (input.region === 'US') {
66-
adminPath = path.join(
67-
this.dataDir,
68-
'admin_units',
69-
'United_States_admin.txt'
70-
)
71-
populationDensityPath = path.join(
72-
this.dataDir,
73-
'populations',
74-
'wpop_usacan.txt'
75-
)
76-
preParametersTemplatePath = path.join(
77-
this.dataDir,
78-
'param_files',
79-
'preUS_R0=2.0.txt'
80-
)
81-
subregionName = US_SUBREGIONS[input.subregion]
82-
} else if (COUNTRY_PARAMS_BY_ISO_CODE[input.region]) {
83-
const { adminFileName, subregions } = COUNTRY_PARAMS_BY_ISO_CODE[
84-
input.region
85-
]
86-
87-
adminPath = path.join(this.dataDir, 'admin_units', adminFileName)
88-
populationDensityPath = path.join(
89-
this.dataDir,
90-
'populations',
91-
'wpop_eur.txt'
92-
)
93-
94-
const preParamsFileName =
95-
COUNTRY_PARAMS_BY_ISO_CODE[input.region].preParamsFileName ??
96-
'preUK_R0=2.0.txt'
97-
98-
preParametersTemplatePath = path.join(
99-
this.dataDir,
100-
'param_files',
101-
preParamsFileName
102-
)
103-
subregionName = subregions[input.subregion]
104-
}
129+
const preParametersTemplatePath = this.getPreParametersTemplatePath(
130+
input.region
131+
)
132+
const subregionName = this.getSubregionName(input.region, input.subregion)
105133

106134
// Generate the intervention-related pre-parameters based on the input.
107135
inputFiles.push(preParametersTemplatePath)

packages/mrc-ide-covidsim/test/integration/imperial-integration-test.ts

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,100 @@
1-
import * as temp from 'temp'
21
import * as fs from 'fs'
2+
import * as path from 'path'
3+
import * as temp from 'temp'
34
import { assert } from 'chai'
45
import { ImperialModel } from '../../src/imperial'
56
import { BIN_DIR, MODEL_DATA_DIR } from '../../src/config'
67
import { input } from '@covid-modeling/api'
78

89
suite('imperial integration', () => {
10+
const testRegions = [
11+
{
12+
region: 'CA',
13+
subregion: undefined,
14+
expectedAdminPath: 'Canada_admin.txt',
15+
expectedPopulationDensityPath: 'wpop_usacan.txt',
16+
expectedPreParameterPath: 'preUK_R0=2.0.txt',
17+
},
18+
{
19+
region: 'NG',
20+
subregion: undefined,
21+
expectedAdminPath: 'Nigeria_admin.txt',
22+
expectedPopulationDensityPath: 'wpop_eur.txt',
23+
expectedPreParameterPath: 'preNG_R0=2.0.txt',
24+
},
25+
{
26+
region: 'RU',
27+
subregion: undefined,
28+
expectedAdminPath: 'Russia_admin.txt',
29+
expectedPopulationDensityPath: 'wpop_eur.txt',
30+
expectedPreParameterPath: 'preUK_R0=2.0.txt',
31+
},
32+
{
33+
region: 'GB',
34+
subregion: undefined,
35+
expectedAdminPath: 'United_Kingdom_admin.txt',
36+
expectedPopulationDensityPath: 'wpop_eur.txt',
37+
expectedPreParameterPath: 'preUK_R0=2.0.txt',
38+
},
39+
{
40+
region: 'US',
41+
subregion: undefined,
42+
expectedAdminPath: 'United_States_admin.txt',
43+
expectedPopulationDensityPath: 'wpop_usacan.txt',
44+
expectedPreParameterPath: 'preUS_R0=2.0.txt',
45+
},
46+
{
47+
region: 'US',
48+
subregion: 'US-NY',
49+
expectedAdminPath: 'admin-params.txt',
50+
expectedPopulationDensityPath: 'wpop_usacan.txt',
51+
expectedPreParameterPath: 'preUS_R0=2.0.txt',
52+
},
53+
]
54+
testRegions.forEach(testRegion => {
55+
test(`finds parameter files for region ${testRegion.region} and subregion ${testRegion.subregion}`, () => {
56+
const modelInput: input.ModelInput = {
57+
region: testRegion.region,
58+
subregion: testRegion.subregion,
59+
parameters: {
60+
calibrationDate: '2020-03-20',
61+
calibrationCaseCount: 500,
62+
calibrationDeathCount: 120,
63+
r0: null,
64+
interventionPeriods: [],
65+
},
66+
}
67+
68+
const logDir = temp.mkdirSync()
69+
const inputDir = temp.mkdirSync()
70+
const outputDir = temp.mkdirSync()
71+
const binDir = temp.mkdirSync()
72+
73+
const model = new ImperialModel(
74+
1,
75+
binDir,
76+
logDir,
77+
MODEL_DATA_DIR,
78+
inputDir,
79+
outputDir
80+
)
81+
82+
const runnerModelInput = model.inputs(modelInput)
83+
assert.equal(
84+
runnerModelInput.adminFilePath,
85+
path.join(inputDir, testRegion.expectedAdminPath)
86+
)
87+
assert.equal(
88+
runnerModelInput.populationDensityFilePath,
89+
path.join(
90+
MODEL_DATA_DIR,
91+
'populations',
92+
testRegion.expectedPopulationDensityPath
93+
)
94+
)
95+
})
96+
})
97+
998
test('run imperial model for Wyoming', async () => {
1099
const logDir = temp.mkdirSync()
11100
const inputDir = temp.mkdirSync()

0 commit comments

Comments
 (0)