Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 46 additions & 4 deletions autotest/dfns/__snapshots__/v2.0.0.dev2/utl-obs.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,59 @@
"tagged": false
},
"id": {
"type": "string",
"type": "union",
"longname": "time",
"description": "Text identifying cell where observation is located. For packages other than NPF, if boundary names are defined in the corresponding package input file, ID can be a boundary name. Otherwise ID is a cellid. If the model discretization is type DIS, cellid is three integers (layer, row, column). If the discretization is DISV, cellid is two integers (layer, cell number). If the discretization is DISU, cellid is one integer (node number).",
"tagged": false
"tagged": false,
"arms": {
"cellid": {
"type": "array",
"tagged": false,
"dtype": "integer",
"index": true,
"cellid": true,
"shape": [
"ncelldim"
]
},
"index": {
"type": "integer",
"tagged": false,
"index": true
},
"boundname": {
"type": "string",
"tagged": false
}
}
},
"id2": {
"type": "string",
"type": "union",
"longname": "time",
"description": "Text identifying cell adjacent to cell identified by ID. The form of ID2 is as described for ID. ID2 is used for intercell-flow observations of a GWF model, for three observation types of the LAK Package, for two observation types of the MAW Package, and one observation type of the UZF Package.",
"optional": true,
"tagged": false
"tagged": false,
"arms": {
"cellid": {
"type": "array",
"tagged": false,
"dtype": "integer",
"index": true,
"cellid": true,
"shape": [
"ncelldim"
]
},
"index": {
"type": "integer",
"tagged": false,
"index": true
},
"boundname": {
"type": "string",
"tagged": false
}
}
}
}
}
Expand Down
42 changes: 40 additions & 2 deletions autotest/dfns/__snapshots__/v2.0.0.dev2/utl-obs.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,56 @@ description = "a string of characters used to identify the observation type."
tagged = false

[blocks.continuous.fields.continuous.item.fields.id]
type = "string"
type = "union"
longname = "time"
description = "Text identifying cell where observation is located. For packages other than NPF, if boundary names are defined in the corresponding package input file, ID can be a boundary name. Otherwise ID is a cellid. If the model discretization is type DIS, cellid is three integers (layer, row, column). If the discretization is DISV, cellid is two integers (layer, cell number). If the discretization is DISU, cellid is one integer (node number)."
tagged = false

[blocks.continuous.fields.continuous.item.fields.id2]
[blocks.continuous.fields.continuous.item.fields.id.arms.cellid]
type = "array"
tagged = false
dtype = "integer"
index = true
cellid = true
shape = [
"ncelldim",
]

[blocks.continuous.fields.continuous.item.fields.id.arms.index]
type = "integer"
tagged = false
index = true

[blocks.continuous.fields.continuous.item.fields.id.arms.boundname]
type = "string"
tagged = false

[blocks.continuous.fields.continuous.item.fields.id2]
type = "union"
longname = "time"
description = "Text identifying cell adjacent to cell identified by ID. The form of ID2 is as described for ID. ID2 is used for intercell-flow observations of a GWF model, for three observation types of the LAK Package, for two observation types of the MAW Package, and one observation type of the UZF Package."
optional = true
tagged = false

[blocks.continuous.fields.continuous.item.fields.id2.arms.cellid]
type = "array"
tagged = false
dtype = "integer"
index = true
cellid = true
shape = [
"ncelldim",
]

[blocks.continuous.fields.continuous.item.fields.id2.arms.index]
type = "integer"
tagged = false
index = true

[blocks.continuous.fields.continuous.item.fields.id2.arms.boundname]
type = "string"
tagged = false

[blocks.continuous.header.field]
name = "output"
type = "record"
Expand Down
36 changes: 34 additions & 2 deletions autotest/dfns/__snapshots__/v2.0.0.dev2/utl-obs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,55 @@ blocks:
description: a string of characters used to identify the observation type.
tagged: false
id:
type: string
type: union
longname: time
description: Text identifying cell where observation is located. For packages other than
NPF, if boundary names are defined in the corresponding package input file, ID can be
a boundary name. Otherwise ID is a cellid. If the model discretization is type DIS, cellid
is three integers (layer, row, column). If the discretization is DISV, cellid is two integers
(layer, cell number). If the discretization is DISU, cellid is one integer (node number).
tagged: false
arms:
cellid:
type: array
tagged: false
dtype: integer
index: true
cellid: true
shape:
- ncelldim
index:
type: integer
tagged: false
index: true
boundname:
type: string
tagged: false
id2:
type: string
type: union
longname: time
description: Text identifying cell adjacent to cell identified by ID. The form of ID2 is
as described for ID. ID2 is used for intercell-flow observations of a GWF model, for three
observation types of the LAK Package, for two observation types of the MAW Package, and
one observation type of the UZF Package.
optional: true
tagged: false
arms:
cellid:
type: array
tagged: false
dtype: integer
index: true
cellid: true
shape:
- ncelldim
index:
type: integer
tagged: false
index: true
boundname:
type: string
tagged: false
header:
field:
name: output
Expand Down
50 changes: 46 additions & 4 deletions autotest/dfns/__snapshots__/v2.0.0.dev3/utl-obs.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,17 +42,59 @@
"tagged": false
},
"id": {
"type": "string",
"type": "union",
"longname": "time",
"description": "Text identifying cell where observation is located. For packages other than NPF, if boundary names are defined in the corresponding package input file, ID can be a boundary name. Otherwise ID is a cellid. If the model discretization is type DIS, cellid is three integers (layer, row, column). If the discretization is DISV, cellid is two integers (layer, cell number). If the discretization is DISU, cellid is one integer (node number).",
"tagged": false
"tagged": false,
"arms": {
"cellid": {
"type": "array",
"tagged": false,
"dtype": "integer",
"index": true,
"cellid": true,
"shape": [
"ncelldim"
]
},
"index": {
"type": "integer",
"tagged": false,
"index": true
},
"boundname": {
"type": "string",
"tagged": false
}
}
},
"id2": {
"type": "string",
"type": "union",
"longname": "time",
"description": "Text identifying cell adjacent to cell identified by ID. The form of ID2 is as described for ID. ID2 is used for intercell-flow observations of a GWF model, for three observation types of the LAK Package, for two observation types of the MAW Package, and one observation type of the UZF Package.",
"optional": true,
"tagged": false
"tagged": false,
"arms": {
"cellid": {
"type": "array",
"tagged": false,
"dtype": "integer",
"index": true,
"cellid": true,
"shape": [
"ncelldim"
]
},
"index": {
"type": "integer",
"tagged": false,
"index": true
},
"boundname": {
"type": "string",
"tagged": false
}
}
}
}
}
Expand Down
42 changes: 40 additions & 2 deletions autotest/dfns/__snapshots__/v2.0.0.dev3/utl-obs.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,56 @@ description = "a string of characters used to identify the observation type."
tagged = false

[blocks.continuous.fields.continuous.item.fields.id]
type = "string"
type = "union"
longname = "time"
description = "Text identifying cell where observation is located. For packages other than NPF, if boundary names are defined in the corresponding package input file, ID can be a boundary name. Otherwise ID is a cellid. If the model discretization is type DIS, cellid is three integers (layer, row, column). If the discretization is DISV, cellid is two integers (layer, cell number). If the discretization is DISU, cellid is one integer (node number)."
tagged = false

[blocks.continuous.fields.continuous.item.fields.id2]
[blocks.continuous.fields.continuous.item.fields.id.arms.cellid]
type = "array"
tagged = false
dtype = "integer"
index = true
cellid = true
shape = [
"ncelldim",
]

[blocks.continuous.fields.continuous.item.fields.id.arms.index]
type = "integer"
tagged = false
index = true

[blocks.continuous.fields.continuous.item.fields.id.arms.boundname]
type = "string"
tagged = false

[blocks.continuous.fields.continuous.item.fields.id2]
type = "union"
longname = "time"
description = "Text identifying cell adjacent to cell identified by ID. The form of ID2 is as described for ID. ID2 is used for intercell-flow observations of a GWF model, for three observation types of the LAK Package, for two observation types of the MAW Package, and one observation type of the UZF Package."
optional = true
tagged = false

[blocks.continuous.fields.continuous.item.fields.id2.arms.cellid]
type = "array"
tagged = false
dtype = "integer"
index = true
cellid = true
shape = [
"ncelldim",
]

[blocks.continuous.fields.continuous.item.fields.id2.arms.index]
type = "integer"
tagged = false
index = true

[blocks.continuous.fields.continuous.item.fields.id2.arms.boundname]
type = "string"
tagged = false

[blocks.continuous.header.field]
name = "output"
type = "record"
Expand Down
36 changes: 34 additions & 2 deletions autotest/dfns/__snapshots__/v2.0.0.dev3/utl-obs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -45,23 +45,55 @@ blocks:
description: a string of characters used to identify the observation type.
tagged: false
id:
type: string
type: union
longname: time
description: Text identifying cell where observation is located. For packages other than
NPF, if boundary names are defined in the corresponding package input file, ID can be
a boundary name. Otherwise ID is a cellid. If the model discretization is type DIS, cellid
is three integers (layer, row, column). If the discretization is DISV, cellid is two integers
(layer, cell number). If the discretization is DISU, cellid is one integer (node number).
tagged: false
arms:
cellid:
type: array
tagged: false
dtype: integer
index: true
cellid: true
shape:
- ncelldim
index:
type: integer
tagged: false
index: true
boundname:
type: string
tagged: false
id2:
type: string
type: union
longname: time
description: Text identifying cell adjacent to cell identified by ID. The form of ID2 is
as described for ID. ID2 is used for intercell-flow observations of a GWF model, for three
observation types of the LAK Package, for two observation types of the MAW Package, and
one observation type of the UZF Package.
optional: true
tagged: false
arms:
cellid:
type: array
tagged: false
dtype: integer
index: true
cellid: true
shape:
- ncelldim
index:
type: integer
tagged: false
index: true
boundname:
type: string
tagged: false
header:
field:
name: output
Expand Down
17 changes: 17 additions & 0 deletions autotest/dfns/test_migrate.py
Original file line number Diff line number Diff line change
Expand Up @@ -369,6 +369,23 @@ def test_migrate_marks_cellids(dfn_dir, name, block, cols):
assert (field.shape, field.index, field.cellid) == (["ncelldim"], True, True)


@pytest.mark.parametrize("col, optional", [("id", False), ("id2", True)])
def test_migrate_obs_id_union(dfn_dir, col, optional):
"""A v1 string with numeric_index (utl-obs's id/id2) becomes an untagged
union of a cellid, a 1-based index, and a boundname."""
component = _migrate_dev3(dfn_dir, "utl-obs")
item = component.blocks["continuous"].fields["continuous"].item
field = item.fields[col]
assert isinstance(field, v2.Union)
assert (field.tagged, field.optional) == (False, optional)
cellid, index, boundname = field.arms.values()
assert isinstance(cellid, v2.Array)
assert (cellid.shape, cellid.index, cellid.cellid) == (["ncelldim"], True, True)
assert isinstance(index, v2.Integer) and index.index
assert isinstance(boundname, v2.String)
assert not any(arm.tagged for arm in field.arms.values())


def test_migrate_sfr_ic_is_signed_index(dfn_dir):
component = _migrate_dev3(dfn_dir, "gwf-sfr")
item = component.blocks["connectiondata"].fields["connectiondata"].item
Expand Down
2 changes: 2 additions & 0 deletions docs/md/dfnspec.md
Original file line number Diff line number Diff line change
Expand Up @@ -529,6 +529,8 @@ Type `union`. Sum type.

`{string: Scalar | Array | Record}`. Subfields, required.

A union is usually keyword-led: each arm begins with its own keyword, which picks the arm. An untagged union's arms begin with a value instead, and the value alone may not pick the arm. `utl-obs`'s `id` is a cellid, a 1-based index (e.g. a lake number), or a boundname, depending on the parent package and the observation type. As with a runtime-resolved [foreign key](#primary-and-foreign-keys), the codec resolves which arm applies.

#### List

Type `list`. Collection type. Unlimited but for one rule: a list may not contain another list. Lists are distinct from arrays in two ways: a list element may be a composite type and a list admits sparse representations.
Expand Down
Loading
Loading