From 1c51e277d703252a287ff8e46589bc7e05e47094 Mon Sep 17 00:00:00 2001 From: wpbonelli Date: Sat, 3 May 2025 10:21:37 -0400 Subject: [PATCH] refactor(LocalRegistry): rework index method prefix parameters The parameter prefix is a string to prepend to model names. But the routine to search for model dirs also has a prefix param to filter the results. Switch the prefix parameter's semantics to match this, and pass it through, and add a new model_name_prefix parameter for model name modification. --- modflow_devtools/misc.py | 13 +++++++------ modflow_devtools/models.py | 27 ++++++++++++++++++++------- 2 files changed, 27 insertions(+), 13 deletions(-) diff --git a/modflow_devtools/misc.py b/modflow_devtools/misc.py index d9b32591..db19791f 100644 --- a/modflow_devtools/misc.py +++ b/modflow_devtools/misc.py @@ -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): diff --git a/modflow_devtools/models.py b/modflow_devtools/models.py index 58dd26cb..22f75876 100644 --- a/modflow_devtools/models.py +++ b/modflow_devtools/models.py @@ -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. @@ -116,10 +118,15 @@ 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() @@ -127,11 +134,17 @@ def index( 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: