-
Notifications
You must be signed in to change notification settings - Fork 351
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add a simple CLI for use in unified UI
Adds a simple CLI that: - reads input JSON (of type `ScenarioData`) from a specified input path - runs the model by calling into `run.ts` - writes output JSON (of type `AlgorithmResult`) into the specified output path This allows the model to be run in a unified model UI. Having this as part of the model repo enables the unified interface to keep up with model changes.
- Loading branch information
1 parent
3dc32dd
commit b327903
Showing
1 changed file
with
77 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
import * as fs from 'fs' | ||
import { run } from './run' | ||
import { ScenarioFlat, ScenarioData } from './types/Param.types' | ||
import { getAgeDistribution } from '../components/Main/state/getAgeDistribution' | ||
import { getSeverityDistribution } from '../components/Main/state/getSeverityDistribution' | ||
import { toInternal } from '../components/Main/state/getScenario' | ||
|
||
const handleRejection: NodeJS.UnhandledRejectionListener = (err) => { | ||
console.error(err) | ||
process.exit(1) | ||
} | ||
|
||
process.on('unhandledRejection', handleRejection) | ||
|
||
function readJsonFromFile<T>(arg: number) { | ||
const inputFilename = process.argv[arg] | ||
if (!inputFilename) { | ||
usage() | ||
} | ||
console.log(`Reading data from file ${inputFilename}`) | ||
const inputData = fs.readFileSync(inputFilename, 'utf8') | ||
const inputJson = JSON.parse(inputData) as T | ||
console.log(`Read input data`) | ||
return inputJson | ||
} | ||
|
||
async function main() { | ||
const scenarioData = readJsonFromFile<ScenarioData>(2) | ||
const outputFile = process.argv[3] | ||
if (!outputFile) { | ||
usage() | ||
} | ||
console.log(`Will write model output to ${outputFile}`) | ||
|
||
const scenario = toInternal(scenarioData.data) | ||
|
||
const params: ScenarioFlat = { | ||
...scenario.population, | ||
...scenario.epidemiological, | ||
...scenario.simulation, | ||
...scenario.mitigation, | ||
} | ||
// Read data from severityDistributions.json and perform JSON validation. | ||
// Use the model's default (and only) severity distribution. | ||
console.log(`Reading severity distribution data`) | ||
const DEFAULT_SEVERITY_DISTRIBUTION = 'China CDC' | ||
const severity = getSeverityDistribution(DEFAULT_SEVERITY_DISTRIBUTION) | ||
// Read data from ageDistribution.json and perform JSON validation. | ||
console.log(`Reading age distribution data`) | ||
const ageDistribution = getAgeDistribution(params.ageDistributionName) | ||
|
||
try { | ||
console.log('Running the model') | ||
const result = await run({ params, severity, ageDistribution }) | ||
console.log('Run complete') | ||
console.log(result) | ||
console.log(`Writing output to ${outputFile}`) | ||
fs.writeFileSync(outputFile, JSON.stringify(result)) | ||
} catch (error) { | ||
console.error(`Run failed: ${error}`) | ||
process.exit(1) | ||
} | ||
} | ||
|
||
function usage() { | ||
console.log( | ||
` | ||
Usage: | ||
cli <input-file> <output-file> | ||
Manually perform a single model run with the given input, writing the results to the given output file. | ||
`.trim(), | ||
) | ||
|
||
process.exit(1) | ||
} | ||
|
||
main() |