MODFLOW-related functions

Functions specific to MODFLOW and flopy

mfobs.modflow.add_timesteps_to_perioddata(perioddata)[source]
mfobs.modflow.get_gwf_obs_input(gwf_obs_input_file, gwf_obs_block=None)[source]

Read the first BEGIN continuous FILEOUT block of an input file to the MODFLOW-6 GWF observation utility.

Parameters:
gwf_obs_input_filestr

Input file to MODFLOW-6 observation utility (contains layer information).

gwf_obs_blockNone or int

Optional argument to read a specific observation block or all blocks from GWF observation utility file. Value of None returns observations from all blocks. Integer value returns obs from a specifc block, in (zero-based) order from top to bottom. For example, a value of 0 would return the first obs block, value of 1 would return the second obs block, and so on.

mfobs.modflow.get_ij(transform, x, y)[source]

Return the row and column of a point or sequence of points in real-world coordinates. Uses the affine package. Basically,

  • to get an x, y: transform * (col, row)

  • the inverse, ~transform * (x, y) returns a fractional i, j location on the grid

Parameters:
transformaffine.Affine instance

An affine.Affine object describing the orientation of the model grid. Modflow-setup MFsetupGrid have this attached via the transform() property. Example:

modelgrid_transform=affine.Affine(1000.0, 0.0, 500955,
                                  0.0, -1000.0, 1205285)

for a uniform spacing of 1000 and upper left corner of 500955, 1205285 with a rotation of 45 degrees, counter-clockwise about the upper left corner:

modelgrid_transform=affine.Affine(1000.0, 0.0, 500955,
                                  0.0, -1000.0, 1205285).rotation(45.)

An affine.Affine instance can also be created from a Modflow-setup grid JSON file via the get_modelgrid_transform() function.

xscalar or sequence of x coordinates
yscalar or sequence of y coordinates
Returns:
irow or sequence of rows (zero-based)
jcolumn or sequence of columns (zero-based)
mfobs.modflow.get_kstp_kper(nstp)[source]

Given a sequence of the number of timesteps in each stress period, return a sequence of timestep, period tuples (kstp, kper) used by various flopy methods.

mfobs.modflow.get_layer(column_name)[source]

Pandas appends duplicate column names with a .*, where * is the number of duplicate names from left to right (e.g. obs, obs.1, obs.2, …). Modflow-setup writes observation input for each model layer, at each site location, with the same observation prefix (site identifier). MODFLOW-6 reports the result for each layer with duplicate column names, with layers increasing from left to right (e.g. obs, obs, obs, …).

Parse the layer number from column_name, returning zero if there is no ‘.’ separator.

Notes

The approach can’t be used if the model includes inactive cells (including pinched layers) at the locations of observations, because it assumes that the layer numbers are consecutive, starting at 0. For example, a pinched layer 2 in a 4 layer model would result in the observation being in layers 0, 1, 3, which would be misinterpreted as 0, 1, 2.

mfobs.modflow.get_mf6_single_variable_obs(perioddata, model_output_file, gwf_obs_input_file=None, variable=None, names_include_variable=False, abs=True, gwf_obs_block=None)[source]

Read raw MODFLOW-6 observation output from csv table with times along the row axis and observations along the column axis. Reshape (stack) results to be n times x n sites rows, with a single observation value in each row. If there is more than one time in a stress period, retain only the last time (so that there is one observation per stress period for each site. If an input file to the MODFLOW-6 observation utility is included, include the observation layer number in the output.

Parameters:
perioddatastr, pathlike or DataFrame

Path to csv file or pandas DataFrame with start/end dates for stress periods. Must have the following columns:

time

modflow simulation time, in days1

start_datetime

start date for each stress period

end_datetime

end date for each stress period

  1. Times in the time column must correspond to times in the time column of gage package output.

model_output_filestr

Path to MODFLOW-6 observation csv output (shape: n times rows x n obs columns).

gwf_obs_input_filestr

Input file to MODFLOW-6 observation utility (contains layer information).

variablestr

Variable name for observations. If supplied, observation prefixes will be named following the format <site number>-<variable>. If observations are already set up in MODFLOW with the format <site number>-<variable> and names_include_variable=True, then this is not needed. By default, None, in which case observation prefixes are the same as the site numbers.

names_include_variablebool

Option to indicate that the names in the MODFLOW observation input have the format <site number>-<variable> (which allows for multiple observations of different variables at a site). In this case, observation prefixes will be named from the MODFLOW observation names, and any variable argument will be ignored. By default, False, in which case the MODFLOW observation names are assumed to be the site numbers. Observation prefixes will be formulated from the MODFLOW names and variable.

absbool, optional

Option to convert simulated values to absolute values. For example, downstream-flow observations, which by convention are reported as negative by MODFLOW 6, but will be compared to positive observed values. By default, True.

gwf_obs_blockNone or int

Argument to read a specific observation block or all blocks from GWF observation utility file. Value of None returns observations from all blocks. Integer value returns obs from a specifc block, in (zero-based) order, from top to bottom. For example, a value of 0 would return the first obs block, value of 1 would return the second obs block, and so on. Modflow-setup writes all of the observation input to a single block, but observation input can be broken out into multiple blocks (one per file). By default, None (All blocks)

Returns:
resultsDataFrame

DataFrame with one head observation per row, with the following columns:

datetime

pandas datetimes, based on stress period start date

site_no

unique identifier for each site

variable

MODFLOW variable name for observed value

obsprefix

prefix of observation name (site identifier)

sim_obsval

simulated values

time

modflow simulation time, in days

per

modflow stress period1

  1. Stress period information is needed to differentiate between steady-state and transient observations that may have the same timestamp.

mfobs.modflow.get_mf_gage_package_obs(perioddata, gage_package_output_files, gwf_obs_input_file=None, variable='flow', abs=True)[source]

Read raw MODFLOW gage package text file output with times along the row axis and observations along the column axis. Reshape (stack) results to be n times x n sites rows, with a single observation value in each row.

Observations can be aggregated from the raw model output to the stress period level (aggregate_obs_to_stress_periods=True), which is often desired for models with monthly stress periods. If there is more than one time in a stress period, only the last timestep is retained (so that there is one observation per stress period for each site).

Alternatively, for models with daily stresses on daily timesteps (for example, GSFLOW), observations can be created for each timestep.

If an input file to the MODFLOW observation package is specified, include the observation layer number in the output.

Parameters:
perioddatastr, pathlike or DataFrame

Path to csv file or pandas DataFrame with start/end dates for stress periods. Must have the following columns:

time

modflow simulation time, in days1

start_datetime

start date for each stress period

end_datetime

end date for each stress period

  1. Times in the time column must correspond to times in the time column of gage package output.

gage_package_output_filesstr/pathlike, or list of pathlikes

Path to gage package output file(s). Multiple files will be concatenated into one output table.

model_obs_input_filestr

Input file to MODFLOW (hydmod or gage??) for observations.

variablestr or sequence

Variable(s) to read from gage package output.

absbool, optional

Option to convert simulated values to absolute values

Returns:
resultsDataFrame

DataFrame with one head observation per row, with the following columns:

datetime

pandas datetimes, based on stress period start date

site_no

unique identifier for each site

variable

PRMS variable name

obsprefix

prefix of observation name (site identifier)

sim_obsval

simulated values

time

modflow simulation time, in days

per

modflow stress period1

  1. Stress period information is needed to differentiate between steady-state and transient observations that may have the same timestamp.

mfobs.modflow.get_modelgrid_transform(grid_json_file, shift_to_cell_centers=False)[source]

Create an affine.Affine that describes the model grid from a json file. The affine package comes with rasterio as a dependency or can be installed separately.

Parameters:
grid_json_filestr

Model grid json file produced by modflow-setup

shift_to_cell_centersbool

By default, transform reflects the upper left corner of the first cell in the model, and any conversions of x, y coordinates to pixels will be relative to upper left corners. If shift_to_cell_centers=True, x,y points will be referenced to the nearest cell centers.

mfobs.modflow.get_modflow_mass_balance(modroot, outfile=None, write_ins=True)[source]

read in the percent discrepancy for inset and parent models

Parameters:
modroot: root name of the model scenario
outfile: filepath for output
write_ins: bool. whether or not to write instruction file
mfobs.modflow.get_perioddata(tdis_file, sto_file=None, start_datetime=None, end_datetime=None, include_timesteps=False, model_time_units=None)[source]

Make the perioddata table required by other modflow-obs functions from a MODFLOW-6 Temporal Discretization (TDIS) file.

Parameters:
tdis_filestr or pathlike

MODFLOW 6 TDIS, or MODFLOW-2005 style DIS Package file. Model version is determined from the extension (‘.tdis’ for MODFLOW 6; ‘.dis’ for MODFLOW-2005)

sto_filestr or pathlike

MODFLOW 6 STO Package file

start_datetimestr or pandas Timestamp

Start date for model, if start date isn’t specified in TDIS package file. Required for MODFLOW-2005 style models.

end_datetimestr or pandas Timestamp (optional)

End date of model, only required for GSFLOW models, where time-step specification is handled internally. end_datetime should be specified as midnight following the last full day simulated by the model. For example, if the model runs through 12/31/2019, end_datetime should be specified as 01/01/2020.

include_timestepsbool

If True, return a perioddata table with one row for each time step, otherwise, return one row per stress period. By default, False

model_time_unitsstr (optional)

Time unit of model, in text understandable by pandas (e.g. “days”). Specification of time units will override what is read from the TDIS or DIS package file.

Returns:
perioddataDataFrame
mfobs.modflow.get_site_no(obsprefix, obsprefix_includes_variable=True)[source]

Parse observation site number from an observation prefix string, which may include a variable at the end, delimited by a hyphen. Also split off any part of the string after a period (‘.’), for example index instance numbers appended by pandas.

Examples

>>> get_site_no('15266500')
'15266500'
>>> get_site_no('15266500-flow')
'15266500'
>>> get_site_no('bc-east-fork-s12-flow')
'bc-east-fork-s12'
>>> get_site_no('bc-east-fork-s12', obsprefix_includes_variable=False)
'bc-east-fork-s12'
>>> get_site_no('15266500.1')
'15266500'
mfobs.modflow.get_transmissivities(heads, hk, top, botm, i=None, j=None, x=None, y=None, modelgrid_transform=None, screen_top=None, screen_botm=None, include_zero_open_intervals=True, nodata=-999)[source]

Computes transmissivity in each model layer at specified locations and open intervals. A saturated thickness is determined for each row, column or x, y location supplied, based on the open interval (sctop, screen_botm), if supplied, otherwise the layer tops and bottoms and the water table are used.

Parameters:
heads2D array OR 3D array

numpy array of shape nlay by n locations (2D) OR complete heads array of the model for one time (3D)

hk3D numpy array

horizontal hydraulic conductivity values.

top2D numpy array

model top elevations.

botm3D numpy array

layer botm elevations.

i1D array-like of ints, of length n locations

zero-based row indices (optional; alternately specify x, y)

j1D array-like of ints, of length n locations

zero-based column indices (optional; alternately specify x, y)

x1D array-like of floats, of length n locations

x locations in real world coordinates (optional). If x and y are specified, a modelgrid_transform must also be provided.

y1D array-like of floats, of length n locations

y locations in real world coordinates (optional) If x and y are specified, a modelgrid_transform must also be provided.

modelgrid_transformaffine.Affine instance, optional

An affine.Affine object describing the orientation of the model grid. Only required for getting i, j if x and y are specified. Modflow-setup MFsetupGrid have this attached via the transform() property. Example:

modelgrid_transform=affine.Affine(1000.0, 0.0, 500955,
                                  0.0, -1000.0, 1205285)

for a uniform spacing of 1000 and upper left corner of 500955, 1205285 with a rotation of 45 degrees, counter-clockwise about the upper left corner:

modelgrid_transform=affine.Affine(1000.0, 0.0, 500955,
                                  0.0, -1000.0, 1205285).rotation(45.)

An affine.Affine instance can also be created from a Modflow-setup grid JSON file via the get_modelgrid_transform() function.

screen_top1D array-like of floats, of length n locations

open interval tops (optional; default is model top)

screen_botm1D array-like of floats, of length n locations

open interval bottoms (optional; default is model bottom)

include_zero_open_intervalsbool

In cases where the screen top and screen bottom elevations are equal, assign the model layer transmissivity for the cell containing the screen top/bottom.

nodatanumeric

optional; locations where heads=nodata will be assigned T=0

Returns:
T2D array of same shape as heads (nlay x n locations)

Transmissivities in each layer at each location

mfobs.modflow.read_mf6_block(filename, blockname)[source]
mfobs.modflow.read_mf6_lake_obs(f, perioddata, start_date='2012-01-01', keep_only_last_timestep=True)[source]
mfobs.modflow.read_mf_gage_package_output_files(gage_package_output_files, variable=None)[source]

Read one of more gage package output files into a single table. If multiple files are specified, a single variable to return must be specified.

Parameters:
gage_package_output_filesstr/pathlike, or list of pathlikes

Path to gage package output file(s). Multiple files will be concatenated into one output table.

variablestr

Variable to return. Only required if multiple files are specified to gage_package_output_files.

Returns:
dfDataFrame

Gage package output, with times along the row axis, and variables or sites along the column axis.