Skip to content

Add basic OBS package support - #1907

Draft
Huite wants to merge 1 commit into
masterfrom
obs
Draft

Add basic OBS package support#1907
Huite wants to merge 1 commit into
masterfrom
obs

Conversation

@Huite

@Huite Huite commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

EDIT: convert to draft button doesn't seem to be working...
This enables the basic GWF OBS package. I've also added basic support for the output readers.

The from_boolean_grid might make it relatively easy to write results of selected areas/subdomains.

In actual use, one might do:

gwf_model["obs"] = imod.mf6.GroundwaterFlowObservations.from_boolean_grid(
    mask=(idomain * idomain["layer"] == 1),
    obs_type="head",
    binary=True,
)

We can then obviously read the results back in, as is:

path_csv = r"test-twri\GWF_1\obs.csv"
path_bsv = r"test-twri\GWF_1\obs.bsv"
da1 = imod.mf6.out.open_obs_bsv(path_bsv)
da2 = imod.mf6.out.open_obs_csv(path_csv)

A minor utility then suffices to convert back to a gridded form:

def obs_to_grid(obs_da, template):
    time = obs_da["time"]
    coords = dict(template.coords)
    coords["time"] = time
    shape = (time.size, ) + template.shape
    return xr.DataArray(
        data=obs_da.data.reshape(shape),
        coords=coords,
        dims = ("time",) + template.dims,
    )

head1 = obs_to_grid(da1, template=idomain.isel(layer=0))
head2 = obs_to_grid(da2, template=idomain.isel(layer=0))

There are a number of relevant details, I'll make another note tomorrow.

@Huite
Huite marked this pull request as draft August 18, 2026 19:01
@sonarqubecloud

Copy link
Copy Markdown

@Huite

Huite commented Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

The output reading methods are fine, in my opinion. They just need some tests.

The input class needs more attention:

  • Schemata are still missing (but should be generally easy to write);
  • I'm unsure what the current option handling logic should be; I overloaded _render but perhaps there are cleaner ways;
  • obs_id2 is only required for FLOW-JA-FACE, not HEAD or DRAWDOWN. I currently just pad it with nan, this feels cleanest to me;
  • FLOW-JA-FACE would also be relevant to specify in grid form, but I'm not sure how. Could be omitted for now. The non-grid class will support it just fine.

The biggest question for me lies in the alternative from_boolean_grid constructor. It requires validation as well which would fit well in the form schemata, one might also imagine that a grid based class could be worthwhile, like the other intermediate classes.

obs_id is also relatively difficult to construct for a user, because its 2D (nobs * ndim). So for DIS it's shaped (nobs, 3), for DISV it's (nobs, 2) and for DISU it's (nobs, 1). So the grid form is probably more ergonomic in practice (or it should take a x, y, z constructor or something).

Finally, there is the question of whether we need to expose some official logic to put the OBS output back on a grid. The utility in the example above , e.g. will only work if an entire layer is observed. In practice, one might want to place observations in different layers via a pattern like DataArray, which may essentially contain random True values anywhere.
However, this becomes again more tedious with stuff like FLOW-JA-FACE entries.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants