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
13 changes: 7 additions & 6 deletions modflow_devtools/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,13 +279,14 @@ def get_model_paths(
Find model directories recursively in the given location.
A model directory is any directory containing one or more
namefiles. Model directories can be filtered or excluded,
by prefix, pattern, namefile name, or packages used. The
directories are returned in order within scenario folders
by prefix, pattern, namefile name, or packages used. This
function attempts to sort model subdirectories of a shared
parent directory by the order in which the models must run,
such that groundwater flow model workspaces precede other
model types. This allows models which depend on the flow
model's outputs to consume its head or budget, and models
should successfully run in the sequence returned provided
input files (e.g. FMI) refer to output via relative paths.
model types, if the model directory names contain standard
model abbreviates (e.g. "gwf", "gwt", "gwe"). This allows
transport or other models to consume a flow model's head
or budget results.
"""

def keyfunc(v):
Expand Down
27 changes: 20 additions & 7 deletions modflow_devtools/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -105,8 +105,10 @@ def __init__(self) -> None:
def index(
self,
path: str | PathLike,
prefix: str = "",
prefix: str | None = None,
namefile: str = "mfsim.nam",
excluded: list[str] | None = None,
model_name_prefix: str = "",
):
"""
Add models found under the given path to the registry.
Expand All @@ -116,22 +118,33 @@ def index(
is idempotent and may be used to reload the registry e.g. if model
files have changed since the registry was created.

The `path` may consist of model subdirectories
at arbitrary depth. Model input subdirectories
are identified by the presence of a namefile
matching `namefile_pattern`.
The `path` may consist of model subdirectories at arbitrary depth.
Model subdirectories are identified by the presence of a namefile
matching `namefile_pattern`. Model subdirectories may be filtered
inclusively by `prefix` or exclusively by `excluded`

A `model_name_prefix` may be specified to avoid collisions with
models indexed from other directories. This prefix will be added
to the model name, which is derived from the relative path of the
model subdirectory under `path`.
"""

path = Path(path).expanduser().resolve().absolute()
if not path.is_dir():
raise NotADirectoryError(f"Directory path not found: {path}")
self._paths.add(path)

model_paths = get_model_paths(path, namefile=namefile)
model_paths = get_model_paths(
path, prefix=prefix, namefile=namefile, excluded=excluded
)
for model_path in model_paths:
model_path = model_path.expanduser().resolve().absolute()
rel_path = model_path.relative_to(path)
parts = [prefix, *list(rel_path.parts)] if prefix else list(rel_path.parts)
parts = (
[model_name_prefix, *list(rel_path.parts)]
if model_name_prefix
else list(rel_path.parts)
)
model_name = "/".join(parts)
self._models[model_name] = []
if len(rel_path.parts) > 1:
Expand Down