Skip to content

Commit

Permalink
feat: change ModelSpec to allow for simple array of input/output var …
Browse files Browse the repository at this point in the history
…names (#495)

Fixes #494
  • Loading branch information
chrispcampbell authored Jun 5, 2024
1 parent af4abbe commit 3130901
Show file tree
Hide file tree
Showing 22 changed files with 382 additions and 106 deletions.
3 changes: 1 addition & 2 deletions examples/hello-world/sde.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ export async function config() {
modelSpec: async () => {
return {
inputs: [{ varName: 'Y', defaultValue: 0, minValue: -10, maxValue: 10 }],
outputs: [{ varName: 'Z' }],
datFiles: []
outputs: [{ varName: 'Z' }]
}
},

Expand Down
28 changes: 6 additions & 22 deletions examples/house-game/sde.config.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import { copyFile } from 'fs/promises'
import { dirname, join as joinPath } from 'path'
import { fileURLToPath } from 'url'

Expand All @@ -10,21 +9,6 @@ const packagePath = (...parts) => joinPath(__dirname, 'packages', ...parts)
const appPath = (...parts) => packagePath('app', ...parts)
const generatedFilePath = (...parts) => appPath('src', 'model', 'generated', ...parts)

function input(varName, defaultValue) {
return {
varName,
defaultValue,
minValue: defaultValue,
maxValue: defaultValue
}
}

function output(varName) {
return {
varName
}
}

export async function config() {
return {
// Specify the Vensim model to read
Expand All @@ -34,13 +18,13 @@ export async function config() {
modelSpec: async () => {
return {
inputs: [
input('additional houses required value', 0),
input('average house life', 0),
input('time to plan to build', 3),
input('time to build houses', 6),
input('time to respond to gap', 8)
'additional houses required value',
'average house life',
'time to plan to build',
'time to build houses',
'time to respond to gap'
],
outputs: [output('number of houses required'), output('houses completed')],
outputs: ['number of houses required', 'houses completed'],
datFiles: ['../model/houses.dat']
}
},
Expand Down
4 changes: 2 additions & 2 deletions packages/build/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,7 @@ export async function config() {
modelSpec: async () => {
return {
inputs: [{ varName: 'Y', defaultValue: 0, minValue: -10, maxValue: 10 }],
outputs: [{ varName: 'Z' }],
datFiles: []
outputs: [{ varName: 'Z' }]
}
}
}
Expand All @@ -41,3 +40,4 @@ export async function config() {
- [Plugin](interfaces/Plugin.md)
- [BuildContext](classes/BuildContext.md)
- [ResolvedConfig](interfaces/ResolvedConfig.md)
- [ResolvedModelSpec](interfaces/ResolvedModelSpec.md)
22 changes: 11 additions & 11 deletions packages/build/docs/interfaces/InputSpec.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,14 @@ Describes a model input variable.

## Properties

### varName

**varName**: `string`

The variable name (as used in the modeling tool).

___

### inputId

`Optional` **inputId**: `string`
Expand All @@ -19,32 +27,24 @@ note that this approach will be less resilient to renames.

___

### varName

**varName**: `string`

The variable name (as used in the modeling tool).

___

### defaultValue

**defaultValue**: `number`
`Optional` **defaultValue**: `number`

The default value for the input.

___

### minValue

**minValue**: `number`
`Optional` **minValue**: `number`

The minimum value for the input.

___

### maxValue

**maxValue**: `number`
`Optional` **maxValue**: `number`

The maximum value for the input.
20 changes: 13 additions & 7 deletions packages/build/docs/interfaces/ModelSpec.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,31 +3,37 @@
# Interface: ModelSpec

Describes a model (e.g., a Vensim mdl file) and the input/output variables
that should be included in the model generated by SDE.
that should be included in the model generated by SDEverywhere.

## Properties

### inputs

**inputs**: [`InputSpec`](InputSpec.md)[]
**inputs**: `string`[] \| [`InputSpec`](InputSpec.md)[]

The input variable specs.
The input variables for the model. This can either be a simple array of
input variable names, or an array of `InputSpec` instances.

The builder requires only variable names for the purposes of generating
a model, but some plugins may require full `InputSpec` instances.

___

### outputs

**outputs**: [`OutputSpec`](OutputSpec.md)[]
**outputs**: `string`[] \| [`OutputSpec`](OutputSpec.md)[]

The output variable specs.
The output variables for the model. This can either be a simple array of
output variable names, or an array of `OutputSpec` instances.

___

### datFiles

**datFiles**: `string`[]
`Optional` **datFiles**: `string`[]

The dat files to be included with the SDE `spec.json` file.
The dat files that provide the data for exogenous data variables in the
model.

___

Expand Down
6 changes: 3 additions & 3 deletions packages/build/docs/interfaces/Plugin.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ Called before the "generate model" steps are performed.
| Name | Type | Description |
| :------ | :------ | :------ |
| `context` | [`BuildContext`](../classes/BuildContext.md) | The build context (for logging, etc). |
| `modelSpec` | [`ModelSpec`](ModelSpec.md) | The spec that controls how the model is generated. |
| `modelSpec` | [`ResolvedModelSpec`](ResolvedModelSpec.md) | The spec that controls how the model is generated. |

#### Returns

Expand Down Expand Up @@ -153,7 +153,7 @@ files are copied to their destination).
| Name | Type | Description |
| :------ | :------ | :------ |
| `context` | [`BuildContext`](../classes/BuildContext.md) | The build context (for logging, etc). |
| `modelSpec` | [`ModelSpec`](ModelSpec.md) | The spec that controls how the model is generated. |
| `modelSpec` | [`ResolvedModelSpec`](ResolvedModelSpec.md) | The spec that controls how the model is generated. |

#### Returns

Expand All @@ -176,7 +176,7 @@ have been copied to their destination.
| Name | Type | Description |
| :------ | :------ | :------ |
| `context` | [`BuildContext`](../classes/BuildContext.md) | The build context (for logging, etc). |
| `modelSpec` | [`ModelSpec`](ModelSpec.md) | The spec that controls how the model is generated. |
| `modelSpec` | [`ResolvedModelSpec`](ResolvedModelSpec.md) | The spec that controls how the model is generated. |

#### Returns

Expand Down
69 changes: 69 additions & 0 deletions packages/build/docs/interfaces/ResolvedModelSpec.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
[@sdeverywhere/build](../index.md) / ResolvedModelSpec

# Interface: ResolvedModelSpec

Describes a model (e.g., a Vensim mdl file) and the input/output variables
that should be included in the model generated by SDEverywhere. This is
largely the same as the `ModelSpec` interface, except this one has been
fully resolved (paths have been validated, input and output variables have
been checked, etc). This is the spec object that will be passed to plugin
functions.

## Properties

### inputVarNames

**inputVarNames**: `string`[]

The input variable names for the model. This will be defined regardless
of whether `ModelSpec.inputs` was defined as an array of variable names
or an array of `InputSpec` instances. (The input variable names are
derived from the `InputSpec` instances as needed.)

___

### inputs

**inputs**: [`InputSpec`](InputSpec.md)[]

The input variable specs for the model.

___

### outputVarNames

**outputVarNames**: `string`[]

The output variable names for the model. This will be defined regardless
of whether `ModelSpec.outputs` was defined as an array of variable names
or an array of `OutputSpec` instances. (The output variable names are
derived from the `OutputSpec` instances as needed.)

___

### outputs

**outputs**: [`OutputSpec`](OutputSpec.md)[]

The output variable specs for the model.

___

### datFiles

**datFiles**: `string`[]

The dat files that provide the data for exogenous data variables in the
model.

___

### options

`Optional` **options**: `Object`

Additional options included with the SDE `spec.json` file.

#### Index signature

[key: `string`]: `any`
7 changes: 7 additions & 0 deletions packages/build/docs/types/VarName.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[@sdeverywhere/build](../index.md) / VarName

# Type alias: VarName

**VarName**: `string`

A variable name as used in the modeling tool.
85 changes: 73 additions & 12 deletions packages/build/src/_shared/model-spec.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
// Copyright (c) 2022 Climate Interactive / New Venture Fund

/** A variable name as used in the modeling tool. */
export type VarName = string

/**
* Describes a model input variable.
*/
export interface InputSpec {
/** The variable name (as used in the modeling tool). */
varName: VarName

/**
* The stable input identifier. It is recommended to set this to a value (for example, a
* numeric string like what `plugin-config` uses) that is separate from `varName` and is
Expand All @@ -14,40 +20,95 @@ export interface InputSpec {
*/
inputId?: string

/** The variable name (as used in the modeling tool). */
varName: string

/** The default value for the input. */
defaultValue: number
defaultValue?: number

/** The minimum value for the input. */
minValue: number
minValue?: number

/** The maximum value for the input. */
maxValue: number
maxValue?: number
}

/**
* Describes a model output variable.
*/
export interface OutputSpec {
/** The variable name (as used in the modeling tool). */
varName: string
varName: VarName
}

/**
* Describes a model (e.g., a Vensim mdl file) and the input/output variables
* that should be included in the model generated by SDE.
* that should be included in the model generated by SDEverywhere.
*/
export interface ModelSpec {
/** The input variable specs. */
/**
* The input variables for the model. This can either be a simple array of
* input variable names, or an array of `InputSpec` instances.
*
* The builder requires only variable names for the purposes of generating
* a model, but some plugins may require full `InputSpec` instances.
*/
inputs: VarName[] | InputSpec[]

/**
* The output variables for the model. This can either be a simple array of
* output variable names, or an array of `OutputSpec` instances.
*/
outputs: VarName[] | OutputSpec[]

/**
* The dat files that provide the data for exogenous data variables in the
* model.
*/
datFiles?: string[]

/** Additional options included with the SDE `spec.json` file. */
// TODO: Remove references to `spec.json`
// eslint-disable-next-line @typescript-eslint/no-explicit-any
options?: { [key: string]: any }
}

/**
* Describes a model (e.g., a Vensim mdl file) and the input/output variables
* that should be included in the model generated by SDEverywhere. This is
* largely the same as the `ModelSpec` interface, except this one has been
* fully resolved (paths have been validated, input and output variables have
* been checked, etc). This is the spec object that will be passed to plugin
* functions.
*/
export interface ResolvedModelSpec {
/**
* The input variable names for the model. This will be defined regardless
* of whether `ModelSpec.inputs` was defined as an array of variable names
* or an array of `InputSpec` instances. (The input variable names are
* derived from the `InputSpec` instances as needed.)
*/
inputVarNames: VarName[]

/**
* The input variable specs for the model.
*/
inputs: InputSpec[]

/** The output variable specs. */
/**
* The output variable names for the model. This will be defined regardless
* of whether `ModelSpec.outputs` was defined as an array of variable names
* or an array of `OutputSpec` instances. (The output variable names are
* derived from the `OutputSpec` instances as needed.)
*/
outputVarNames: VarName[]

/**
* The output variable specs for the model.
*/
outputs: OutputSpec[]

/** The dat files to be included with the SDE `spec.json` file. */
// TODO: Remove references to `spec.json`
/**
* The dat files that provide the data for exogenous data variables in the
* model.
*/
datFiles: string[]

/** Additional options included with the SDE `spec.json` file. */
Expand Down
Loading

0 comments on commit 3130901

Please sign in to comment.