From a505f5898df984cc7a7bc3b08a53d5603023b445 Mon Sep 17 00:00:00 2001 From: Greg Orzell Date: Wed, 3 Jun 2020 15:18:03 +0200 Subject: [PATCH] api: Start to explore major changes we may need to make to the model input API. Explore how we can provide more data for both calibration and inteventions to the models and their connectors. The goal is give them more flexibiity by providing more of the data we have on hand and allowing them to decide how to best use it to configure their model. --- packages/api/package.json | 2 +- packages/api/schema/input.json | 130 ++++++++++++++++++++++++++------ packages/api/schema/output.json | 130 ++++++++++++++++++++++++++------ packages/api/schema/runner.json | 130 ++++++++++++++++++++++++++------ packages/api/src/model-input.ts | 67 ++++++++++------ 5 files changed, 361 insertions(+), 98 deletions(-) diff --git a/packages/api/package.json b/packages/api/package.json index c9a6e98..959cf16 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -1,6 +1,6 @@ { "name": "@covid-modeling/api", - "version": "0.10.0", + "version": "0.11.0", "main": "dist/src/index", "types": "dist/src/index.d.ts", "scripts": { diff --git a/packages/api/schema/input.json b/packages/api/schema/input.json index b38dffd..3c8089e 100644 --- a/packages/api/schema/input.json +++ b/packages/api/schema/input.json @@ -2,6 +2,66 @@ "$ref": "#/definitions/ModelInput", "$schema": "http://json-schema.org/draft-07/schema#", "definitions": { + "Actual": { + "additionalProperties": false, + "properties": { + "cases": { + "type": "number" + }, + "cumulativeCases": { + "type": "number" + }, + "cumulativeDeaths": { + "type": "number" + }, + "date": { + "$ref": "#/definitions/ISODate" + }, + "deaths": { + "type": "number" + }, + "mobility": { + "type": "number" + } + }, + "required": [ + "date", + "cases", + "cumulativeCases", + "deaths", + "cumulativeDeaths" + ], + "type": "object" + }, + "HistoricalData": { + "additionalProperties": false, + "properties": { + "actuals": { + "items": { + "$ref": "#/definitions/Actual" + }, + "type": "array" + }, + "endDate": { + "$ref": "#/definitions/ISODate" + }, + "totalCases": { + "description": "The total number of confirmed cases in the region before the calibration date.", + "type": "number" + }, + "totalDeaths": { + "description": "The total number of deaths in the region before the calibration date.", + "type": "number" + } + }, + "required": [ + "endDate", + "totalCases", + "totalDeaths", + "actuals" + ], + "type": "object" + }, "ISODate": { "type": "string" }, @@ -13,40 +73,68 @@ ], "type": "string" }, - "InterventionPeriod": { + "Intervention": { "additionalProperties": false, "properties": { - "caseIsolation": { - "$ref": "#/definitions/Intensity", - "description": "The level to which individuals with symptoms self-isolate." + "intensity": { + "$ref": "#/definitions/Intensity" }, "reductionPopulationContact": { - "description": "The estimated reduction in population contact resulting from\nall of the above interventions. Some models require this generalized\nparameter instead of the individual interventions.", "type": "number" }, - "schoolClosure": { - "$ref": "#/definitions/Intensity", - "description": "The level of school closure in the region." + "type": { + "$ref": "#/definitions/InterventionType" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + "InterventionPeriod": { + "additionalProperties": false, + "properties": { + "endDate": { + "$ref": "#/definitions/ISODate" }, - "socialDistancing": { - "$ref": "#/definitions/Intensity", - "description": "The level of social distancing in the region." + "inteventions": { + "items": { + "$ref": "#/definitions/Intervention" + }, + "type": "array" + }, + "reductionPopulationContact": { + "description": "The estimated reduction in population contact resulting from\nall of the above interventions. Some models require this generalized\nparameter instead of the individual interventions.", + "type": "number" }, "startDate": { "$ref": "#/definitions/ISODate", "description": "An ISO-8601 string encoding the date that these interventions begin." - }, - "voluntaryHomeQuarantine": { - "$ref": "#/definitions/Intensity", - "description": "The level to which entire households self-isolate when one member\nof the household has symptoms." } }, "required": [ "startDate", + "endDate", + "inteventions", "reductionPopulationContact" ], "type": "object" }, + "InterventionType": { + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "type": "number" + }, "ModelInput": { "additionalProperties": false, "description": "A generalized description of the input to an epidemiological model.", @@ -70,18 +158,13 @@ "ModelParameters": { "additionalProperties": false, "properties": { - "calibrationCaseCount": { - "description": "The total number of confirmed cases in the region before the calibration date.", - "type": "number" + "calibrationData": { + "$ref": "#/definitions/HistoricalData" }, "calibrationDate": { "$ref": "#/definitions/ISODate", "description": "An ISO-8601 string encoding the date of the most recent case data in the region." }, - "calibrationDeathCount": { - "description": "The total number of deaths in the region before the calibration date.", - "type": "number" - }, "interventionPeriods": { "description": "A list of time periods, each with a different set of interventions.", "items": { @@ -99,8 +182,7 @@ }, "required": [ "calibrationDate", - "calibrationCaseCount", - "calibrationDeathCount", + "calibrationData", "r0", "interventionPeriods" ], diff --git a/packages/api/schema/output.json b/packages/api/schema/output.json index 6e5ad80..bacb134 100644 --- a/packages/api/schema/output.json +++ b/packages/api/schema/output.json @@ -2,6 +2,66 @@ "$ref": "#/definitions/ModelOutput", "$schema": "http://json-schema.org/draft-07/schema#", "definitions": { + "Actual": { + "additionalProperties": false, + "properties": { + "cases": { + "type": "number" + }, + "cumulativeCases": { + "type": "number" + }, + "cumulativeDeaths": { + "type": "number" + }, + "date": { + "$ref": "#/definitions/ISODate" + }, + "deaths": { + "type": "number" + }, + "mobility": { + "type": "number" + } + }, + "required": [ + "date", + "cases", + "cumulativeCases", + "deaths", + "cumulativeDeaths" + ], + "type": "object" + }, + "HistoricalData": { + "additionalProperties": false, + "properties": { + "actuals": { + "items": { + "$ref": "#/definitions/Actual" + }, + "type": "array" + }, + "endDate": { + "$ref": "#/definitions/ISODate" + }, + "totalCases": { + "description": "The total number of confirmed cases in the region before the calibration date.", + "type": "number" + }, + "totalDeaths": { + "description": "The total number of deaths in the region before the calibration date.", + "type": "number" + } + }, + "required": [ + "endDate", + "totalCases", + "totalDeaths", + "actuals" + ], + "type": "object" + }, "ISODate": { "type": "string" }, @@ -13,40 +73,68 @@ ], "type": "string" }, - "InterventionPeriod": { + "Intervention": { "additionalProperties": false, "properties": { - "caseIsolation": { - "$ref": "#/definitions/Intensity", - "description": "The level to which individuals with symptoms self-isolate." + "intensity": { + "$ref": "#/definitions/Intensity" }, "reductionPopulationContact": { - "description": "The estimated reduction in population contact resulting from\nall of the above interventions. Some models require this generalized\nparameter instead of the individual interventions.", "type": "number" }, - "schoolClosure": { - "$ref": "#/definitions/Intensity", - "description": "The level of school closure in the region." + "type": { + "$ref": "#/definitions/InterventionType" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + "InterventionPeriod": { + "additionalProperties": false, + "properties": { + "endDate": { + "$ref": "#/definitions/ISODate" }, - "socialDistancing": { - "$ref": "#/definitions/Intensity", - "description": "The level of social distancing in the region." + "inteventions": { + "items": { + "$ref": "#/definitions/Intervention" + }, + "type": "array" + }, + "reductionPopulationContact": { + "description": "The estimated reduction in population contact resulting from\nall of the above interventions. Some models require this generalized\nparameter instead of the individual interventions.", + "type": "number" }, "startDate": { "$ref": "#/definitions/ISODate", "description": "An ISO-8601 string encoding the date that these interventions begin." - }, - "voluntaryHomeQuarantine": { - "$ref": "#/definitions/Intensity", - "description": "The level to which entire households self-isolate when one member\nof the household has symptoms." } }, "required": [ "startDate", + "endDate", + "inteventions", "reductionPopulationContact" ], "type": "object" }, + "InterventionType": { + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "type": "number" + }, "ModelInput": { "additionalProperties": false, "description": "A generalized description of the input to an epidemiological model.", @@ -132,18 +220,13 @@ "ModelParameters": { "additionalProperties": false, "properties": { - "calibrationCaseCount": { - "description": "The total number of confirmed cases in the region before the calibration date.", - "type": "number" + "calibrationData": { + "$ref": "#/definitions/HistoricalData" }, "calibrationDate": { "$ref": "#/definitions/ISODate", "description": "An ISO-8601 string encoding the date of the most recent case data in the region." }, - "calibrationDeathCount": { - "description": "The total number of deaths in the region before the calibration date.", - "type": "number" - }, "interventionPeriods": { "description": "A list of time periods, each with a different set of interventions.", "items": { @@ -161,8 +244,7 @@ }, "required": [ "calibrationDate", - "calibrationCaseCount", - "calibrationDeathCount", + "calibrationData", "r0", "interventionPeriods" ], diff --git a/packages/api/schema/runner.json b/packages/api/schema/runner.json index ca713bb..a931cce 100644 --- a/packages/api/schema/runner.json +++ b/packages/api/schema/runner.json @@ -2,6 +2,66 @@ "$ref": "#/definitions/RequestInput", "$schema": "http://json-schema.org/draft-07/schema#", "definitions": { + "Actual": { + "additionalProperties": false, + "properties": { + "cases": { + "type": "number" + }, + "cumulativeCases": { + "type": "number" + }, + "cumulativeDeaths": { + "type": "number" + }, + "date": { + "$ref": "#/definitions/ISODate" + }, + "deaths": { + "type": "number" + }, + "mobility": { + "type": "number" + } + }, + "required": [ + "date", + "cases", + "cumulativeCases", + "deaths", + "cumulativeDeaths" + ], + "type": "object" + }, + "HistoricalData": { + "additionalProperties": false, + "properties": { + "actuals": { + "items": { + "$ref": "#/definitions/Actual" + }, + "type": "array" + }, + "endDate": { + "$ref": "#/definitions/ISODate" + }, + "totalCases": { + "description": "The total number of confirmed cases in the region before the calibration date.", + "type": "number" + }, + "totalDeaths": { + "description": "The total number of deaths in the region before the calibration date.", + "type": "number" + } + }, + "required": [ + "endDate", + "totalCases", + "totalDeaths", + "actuals" + ], + "type": "object" + }, "ISODate": { "type": "string" }, @@ -13,40 +73,68 @@ ], "type": "string" }, - "InterventionPeriod": { + "Intervention": { "additionalProperties": false, "properties": { - "caseIsolation": { - "$ref": "#/definitions/Intensity", - "description": "The level to which individuals with symptoms self-isolate." + "intensity": { + "$ref": "#/definitions/Intensity" }, "reductionPopulationContact": { - "description": "The estimated reduction in population contact resulting from\nall of the above interventions. Some models require this generalized\nparameter instead of the individual interventions.", "type": "number" }, - "schoolClosure": { - "$ref": "#/definitions/Intensity", - "description": "The level of school closure in the region." + "type": { + "$ref": "#/definitions/InterventionType" + } + }, + "required": [ + "type" + ], + "type": "object" + }, + "InterventionPeriod": { + "additionalProperties": false, + "properties": { + "endDate": { + "$ref": "#/definitions/ISODate" }, - "socialDistancing": { - "$ref": "#/definitions/Intensity", - "description": "The level of social distancing in the region." + "inteventions": { + "items": { + "$ref": "#/definitions/Intervention" + }, + "type": "array" + }, + "reductionPopulationContact": { + "description": "The estimated reduction in population contact resulting from\nall of the above interventions. Some models require this generalized\nparameter instead of the individual interventions.", + "type": "number" }, "startDate": { "$ref": "#/definitions/ISODate", "description": "An ISO-8601 string encoding the date that these interventions begin." - }, - "voluntaryHomeQuarantine": { - "$ref": "#/definitions/Intensity", - "description": "The level to which entire households self-isolate when one member\nof the household has symptoms." } }, "required": [ "startDate", + "endDate", + "inteventions", "reductionPopulationContact" ], "type": "object" }, + "InterventionType": { + "enum": [ + 0, + 1, + 2, + 3, + 4, + 5, + 6, + 7, + 8, + 9 + ], + "type": "number" + }, "Model": { "additionalProperties": false, "properties": { @@ -86,18 +174,13 @@ "ModelParameters": { "additionalProperties": false, "properties": { - "calibrationCaseCount": { - "description": "The total number of confirmed cases in the region before the calibration date.", - "type": "number" + "calibrationData": { + "$ref": "#/definitions/HistoricalData" }, "calibrationDate": { "$ref": "#/definitions/ISODate", "description": "An ISO-8601 string encoding the date of the most recent case data in the region." }, - "calibrationDeathCount": { - "description": "The total number of deaths in the region before the calibration date.", - "type": "number" - }, "interventionPeriods": { "description": "A list of time periods, each with a different set of interventions.", "items": { @@ -115,8 +198,7 @@ }, "required": [ "calibrationDate", - "calibrationCaseCount", - "calibrationDeathCount", + "calibrationData", "r0", "interventionPeriods" ], diff --git a/packages/api/src/model-input.ts b/packages/api/src/model-input.ts index 2ac673b..2915d2c 100644 --- a/packages/api/src/model-input.ts +++ b/packages/api/src/model-input.ts @@ -13,15 +13,7 @@ export interface ModelParameters { */ calibrationDate: ISODate - /** - * The total number of confirmed cases in the region before the calibration date. - */ - calibrationCaseCount: number - - /** - * The total number of deaths in the region before the calibration date. - */ - calibrationDeathCount: number + calibrationData: HistoricalData /** * The assumed reproduction number for the virus. If this is null, then each @@ -35,33 +27,39 @@ export interface ModelParameters { interventionPeriods: InterventionPeriod[] } -export interface InterventionPeriod { +export interface HistoricalData { + endDate: ISODate /** - * An ISO-8601 string encoding the date that these interventions begin. + * The total number of confirmed cases in the region before the calibration date. */ - startDate: ISODate + totalCases: number /** - * The level of social distancing in the region. + * The total number of deaths in the region before the calibration date. */ - socialDistancing?: Intensity + totalDeaths: number - /** - * The level of school closure in the region. - */ - schoolClosure?: Intensity + actuals: Actual[] +} +export interface Actual { + date: ISODate + cases: number + cumulativeCases: number + deaths: number + cumulativeDeaths: number + // Eventually we might want to have a sub object with more specific types of mobility? + mobility?: number +} +export interface InterventionPeriod { /** - * The level to which individuals with symptoms self-isolate. + * An ISO-8601 string encoding the date that these interventions begin. */ - caseIsolation?: Intensity + startDate: ISODate - /** - * The level to which entire households self-isolate when one member - * of the household has symptoms. - */ - voluntaryHomeQuarantine?: Intensity + endDate: ISODate + inteventions: Intervention[] /** * The estimated reduction in population contact resulting from * all of the above interventions. Some models require this generalized @@ -70,6 +68,12 @@ export interface InterventionPeriod { reductionPopulationContact: number } +export interface Intervention { + type: InterventionType + intensity?: Intensity + reductionPopulationContact?: number +} + export type ISODate = string export enum Intensity { @@ -77,3 +81,16 @@ export enum Intensity { Moderate = 'moderate', Aggressive = 'aggressive', } + +export enum InterventionType { + CaseIsolation, + VoluntaryHomeQuarantine, + SocialDistancing, + SchoolClosure, + WorkplaceClosure, + CancelPublicEvents, + RestrictGatherings, + StayAtHome, + RestrictInternalMovement, + RestrictInternationalTravel, +}