From 72515e60ece58911605582f5d75548d5c1c5a45a Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Wed, 1 May 2024 09:51:28 +0200 Subject: [PATCH 01/53] Issue #964 from imod5 classmethbod DIS (#981) Fixes #964 # Description Implements from_imod5 classmethod to StructuredDiscretization classmethod. NOTE: I had to modify the default regridding method of "idomain" as the "mode" method appears to have a bug with perfectly aligned structured grids. This bug requires further investigation. Will post an issue if found. # Checklist - [x] Links to correct issue - [ ] Update changelog, if changes affect users - [x] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [x] Unit tests were added - [ ] **If feature added**: Added/extended example --- imod/mf6/dis.py | 92 ++++++++++++- imod/mf6/package.py | 23 +--- imod/mf6/utilities/grid.py | 19 +++ imod/mf6/utilities/imod5_converter.py | 28 ++++ imod/mf6/utilities/package.py | 23 ++++ imod/mf6/utilities/regrid.py | 122 +++++++++++------- imod/schemata.py | 15 +++ imod/tests/test_mf6/test_mf6_dis.py | 82 ++++++++++++ .../test_mf6/test_utilities/test_grid.py | 29 +++++ .../test_utilities/test_imod5_converter.py | 75 +++++++++++ imod/typing/grid.py | 10 ++ 11 files changed, 448 insertions(+), 70 deletions(-) create mode 100644 imod/mf6/utilities/imod5_converter.py create mode 100644 imod/tests/test_mf6/test_utilities/test_grid.py create mode 100644 imod/tests/test_mf6/test_utilities/test_imod5_converter.py diff --git a/imod/mf6/dis.py b/imod/mf6/dis.py index 9af84b0c3..bd0fcc142 100644 --- a/imod/mf6/dis.py +++ b/imod/mf6/dis.py @@ -1,13 +1,20 @@ import pathlib +from copy import deepcopy from typing import Optional, Tuple import numpy as np import imod -from imod.logging import init_log_decorator +from imod.logging import init_log_decorator, standard_log_decorator from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.package import Package -from imod.mf6.utilities.regrid import RegridderType +from imod.mf6.utilities.grid import create_smallest_target_grid +from imod.mf6.utilities.imod5_converter import convert_ibound_to_idomain +from imod.mf6.utilities.regrid import ( + RegridderType, + RegridderWeightsCache, + _regrid_package_data, +) from imod.mf6.validation import DisBottomSchema from imod.schemata import ( ActiveCellsConnectedSchema, @@ -17,7 +24,10 @@ DTypeSchema, IdentityNoDataSchema, IndexesSchema, + UniqueValuesSchema, + ValidationError, ) +from imod.typing.grid import GridDataArray class StructuredDiscretization(Package, IRegridPackage): @@ -88,7 +98,10 @@ class StructuredDiscretization(Package, IRegridPackage): _regrid_method = { "top": (RegridderType.OVERLAP, "mean"), "bottom": (RegridderType.OVERLAP, "mean"), - "idomain": (RegridderType.OVERLAP, "mode"), + "idomain": ( + RegridderType.OVERLAP, + "median", + ), # TODO: Change back to 'mode' when xugrid 0.9.1 released } _skip_mask_arrays = ["bottom"] @@ -151,3 +164,76 @@ def _validate(self, schemata, **kwargs): def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: return self._regrid_method + + @classmethod + @standard_log_decorator() + def from_imod5_data( + cls, + imod5_data: dict[str, dict[str, GridDataArray]], + regridder_types: Optional[dict[str, tuple[RegridderType, str]]] = None, + ) -> "StructuredDiscretization": + """ + Construct package from iMOD5 data, loaded with the + :func:`imod.formats.prj.open_projectfile_data` function. + + Method regrids all variables to a target grid with the smallest extent + and smallest cellsize available in all the grids. Consequently it + converts iMODFLOW data to MODFLOW 6 data. + + .. note:: + + The method expects the iMOD5 model to be fully 3D, not quasi-3D. + + Parameters + ---------- + imod5_data: dict + Dictionary with iMOD5 data. This can be constructed from the + :func:`imod.formats.prj.open_projectfile_data` method. + regridder_types: dict, optional + Optional dictionary with regridder types for a specific variable. + Use this to override default regridding methods. + + Returns + ------- + Modflow 6 StructuredDiscretization package. + + """ + data = { + "idomain": imod5_data["bnd"]["ibound"].astype(np.int32), + "top": imod5_data["top"]["top"], + "bottom": imod5_data["bot"]["bottom"], + } + + target_grid = create_smallest_target_grid(*data.values()) + + # For some reason ``get_regrid_methods`` cannot be called in a + # classmethod. + regridder_settings = deepcopy(cls._regrid_method) + if regridder_types is not None: + regridder_settings.update(regridder_types) + + regrid_context = RegridderWeightsCache(data["idomain"], target_grid) + + new_package_data = _regrid_package_data( + data, target_grid, regridder_settings, regrid_context + ) + + # Validate iMOD5 data + UniqueValuesSchema([-1, 0, 1]).validate(imod5_data["bnd"]["ibound"]) + if not np.all( + new_package_data["top"][1:].data == new_package_data["bottom"][:-1].data + ): + raise ValidationError( + "Model discretization not fully 3D. Make sure TOP[n+1] matches BOT[n]" + ) + + thickness = new_package_data["top"] - new_package_data["bottom"] + new_package_data["idomain"] = convert_ibound_to_idomain( + new_package_data["idomain"], thickness + ) + + # TOP 3D -> TOP 2D + # Assume iMOD5 data provided as fully 3D and not Quasi-3D + new_package_data["top"] = new_package_data["top"].sel(layer=1, drop=True) + + return cls(**new_package_data) diff --git a/imod/mf6/package.py b/imod/mf6/package.py index db7ea5774..69907ebe7 100644 --- a/imod/mf6/package.py +++ b/imod/mf6/package.py @@ -23,6 +23,7 @@ PackageBase, ) from imod.mf6.utilities.mask import _mask +from imod.mf6.utilities.package import _is_valid from imod.mf6.utilities.regrid import ( RegridderType, RegridderWeightsCache, @@ -77,25 +78,9 @@ def sel(self): f"{__class__.__name__}(**{self._pkg_id}.dataset.sel(**selection))" ) - def _valid(self, value): - """ - Filters values that are None, False, or a numpy.bool_ False. - Needs to be this specific, since 0.0 and 0 are valid values, but are - equal to a boolean False. - """ - # Test singletons - if value is False or value is None: - return False - # Test numpy bool (not singleton) - elif isinstance(value, np.bool_) and not value: - return False - # When dumping to netCDF and reading back, None will have been - # converted into a NaN. Only check NaN if it's a floating type to avoid - # TypeErrors. - elif np.issubdtype(type(value), np.floating) and np.isnan(value): - return False - else: - return True + @staticmethod + def _valid(value: Any) -> bool: + return _is_valid(value) @staticmethod def _number_format(dtype: type): diff --git a/imod/mf6/utilities/grid.py b/imod/mf6/utilities/grid.py index d5d5ac8be..c643fd94c 100644 --- a/imod/mf6/utilities/grid.py +++ b/imod/mf6/utilities/grid.py @@ -80,3 +80,22 @@ def create_geometric_grid_info(active: xr.DataArray) -> pd.DataFrame: "dy": dy.flatten(), } ) + + +def create_smallest_target_grid(*grids: xr.DataArray) -> xr.DataArray: + """ + Create smallest target grid from multiple structured grids. This is the grid + with smallest extent and finest resolution amongst all provided grids. + """ + dx_ls, xmin_ls, xmax_ls, dy_ls, ymin_ls, ymax_ls = zip( + *[imod.util.spatial.spatial_reference(grid) for grid in grids] + ) + + dx = min(dx_ls) + xmin = max(xmin_ls) + xmax = min(xmax_ls) + dy = max(dy_ls) + ymax = min(ymax_ls) + ymin = max(ymin_ls) + + return imod.util.spatial.empty_2d(dx, xmin, xmax, dy, ymin, ymax) diff --git a/imod/mf6/utilities/imod5_converter.py b/imod/mf6/utilities/imod5_converter.py new file mode 100644 index 000000000..221f2efb2 --- /dev/null +++ b/imod/mf6/utilities/imod5_converter.py @@ -0,0 +1,28 @@ +import numpy as np +import xarray as xr + +from imod.typing.grid import full_like + + +def convert_ibound_to_idomain( + ibound: xr.DataArray, thickness: xr.DataArray +) -> xr.DataArray: + # Convert IBOUND to IDOMAIN + # -1 to 1, these will have to be filled with + # CHD cells. + idomain = np.abs(ibound) + + # Thickness <= 0 -> IDOMAIN = -1 + active_and_zero_thickness = (thickness <= 0) & (idomain == 1) + # Don't make cells at top or bottom vpt, these should be inactive. + # First, set all potential vpts to nan to be able to utilize ffill and bfill + idomain_float = idomain.where(~active_and_zero_thickness) + passthrough = (idomain_float.ffill("layer") == 1) & ( + idomain_float.bfill("layer") == 1 + ) + # Then fill nans where passthrough with -1 + idomain_float = idomain_float.combine_first( + full_like(idomain_float, -1.0, dtype=float).where(passthrough) + ) + # Fill the remaining nans at tops and bottoms with 0 + return idomain_float.fillna(0).astype(int) diff --git a/imod/mf6/utilities/package.py b/imod/mf6/utilities/package.py index 2a9f2aada..6d0c84239 100644 --- a/imod/mf6/utilities/package.py +++ b/imod/mf6/utilities/package.py @@ -1,3 +1,5 @@ +from typing import Any + import numpy as np import xarray as xr @@ -25,3 +27,24 @@ def get_repeat_stress(times) -> xr.DataArray: data=np.column_stack((keys, values)), dims=("repeat", "repeat_items"), ) + + +def _is_valid(value: Any) -> bool: + """ + Filters values that are None, False, or a numpy.bool_ False. + Needs to be this specific, since 0.0 and 0 are valid values, but are + equal to a boolean False. + """ + # Test singletons + if value is False or value is None: + return False + # Test numpy bool (not singleton) + elif isinstance(value, np.bool_) and not value: + return False + # When dumping to netCDF and reading back, None will have been + # converted into a NaN. Only check NaN if it's a floating type to avoid + # TypeErrors. + elif np.issubdtype(type(value), np.floating) and np.isnan(value): + return False + else: + return True diff --git a/imod/mf6/utilities/regrid.py b/imod/mf6/utilities/regrid.py index caa12de45..a44f570ee 100644 --- a/imod/mf6/utilities/regrid.py +++ b/imod/mf6/utilities/regrid.py @@ -21,9 +21,15 @@ from imod.mf6.interfaces.isimulation import ISimulation from imod.mf6.statusinfo import NestedStatusInfo from imod.mf6.utilities.clip import clip_by_grid +from imod.mf6.utilities.package import _is_valid from imod.mf6.utilities.regridding_types import RegridderType from imod.schemata import ValidationError -from imod.typing.grid import GridDataArray, get_grid_geometry_hash, ones_like +from imod.typing.grid import ( + GridDataArray, + GridDataset, + get_grid_geometry_hash, + ones_like, +) class RegridderWeightsCache: @@ -135,60 +141,102 @@ def assign_coord_if_present( def _regrid_array( - package: IRegridPackage, - varname: str, + da: GridDataArray, regridder_collection: RegridderWeightsCache, regridder_name: str, regridder_function: str, target_grid: GridDataArray, ) -> Optional[GridDataArray]: """ - Regrids a data_array. The array is specified by its key in the dataset. - Each data-array can represent: - -a scalar value, valid for the whole grid - -an array of a different scalar per layer - -an array with a value per grid block - -None + Regrids a GridDataArray. Each DataArray can represent: + - a scalar value, valid for the whole grid + - an array of a different scalar per layer + - an array with a value per grid block + - None """ # skip regridding for arrays with no valid values (such as "None") - if not package._valid(package.dataset[varname].values[()]): + if not _is_valid(da.values[()]): return None # the dataarray might be a scalar. If it is, then it does not need regridding. - if is_scalar(package.dataset[varname]): - return package.dataset[varname].values[()] + if is_scalar(da): + return da.values[()] - if isinstance(package.dataset[varname], xr.DataArray): - coords = package.dataset[varname].coords + if isinstance(da, xr.DataArray): + coords = da.coords # if it is an xr.DataArray it may be layer-based; then no regridding is needed if not ("x" in coords and "y" in coords): - return package.dataset[varname] + return da # if it is an xr.DataArray it needs the dx, dy coordinates for regridding, which are otherwise not mandatory if not ("dx" in coords and "dy" in coords): raise ValueError( - f"DataArray {varname} does not have both a dx and dy coordinates" + f"GridDataArray {da.name} does not have both a dx and dy coordinates" ) # obtain an instance of a regridder for the chosen method regridder = regridder_collection.get_regridder( - package.dataset[varname], + da, target_grid, regridder_name, regridder_function, ) # store original dtype of data - original_dtype = package.dataset[varname].dtype + original_dtype = da.dtype # regrid data array - regridded_array = regridder.regrid(package.dataset[varname]) + regridded_array = regridder.regrid(da) # reconvert the result to the same dtype as the original return regridded_array.astype(original_dtype) +def _regrid_package_data( + package_data: dict[str, GridDataArray] | GridDataset, + target_grid: GridDataArray, + regridder_settings: dict[str, tuple[RegridderType, str]], + regrid_context: RegridderWeightsCache, + new_package_data: Optional[dict[str, GridDataArray]] = {}, +) -> dict[str, GridDataArray]: + """ + Regrid package data. Loops over regridder settings to regrid variables one + by one. Variables not existent in the package data are skipped. Regridded + package data is added to a dictionary, which can optionally be provided as + argument to extend. + """ + for ( + varname, + regridder_type_and_function, + ) in regridder_settings.items(): + regridder_function = None + regridder_name = regridder_type_and_function[0] + if len(regridder_type_and_function) > 1: + regridder_function = regridder_type_and_function[1] + + # skip variables that are not in this dataset + if varname not in package_data.keys(): + continue + + # regrid the variable + new_package_data[varname] = _regrid_array( + package_data[varname], + regrid_context, + regridder_name, + regridder_function, + target_grid, + ) + # set dx and dy if present in target_grid + new_package_data[varname] = assign_coord_if_present( + "dx", target_grid, new_package_data[varname] + ) + new_package_data[varname] = assign_coord_if_present( + "dy", target_grid, new_package_data[varname] + ) + return new_package_data + + def _get_unique_regridder_types(model: IModel) -> defaultdict[RegridderType, list[str]]: """ This function loops over the packages and collects all regridder-types that are in use. @@ -261,36 +309,14 @@ def _regrid_like( regridder_settings.update(regridder_types) new_package_data = package.get_non_grid_data(list(regridder_settings.keys())) + new_package_data = _regrid_package_data( + package.dataset, + target_grid, + regridder_settings, + regrid_context, + new_package_data=new_package_data, + ) - for ( - varname, - regridder_type_and_function, - ) in regridder_settings.items(): - regridder_function = None - regridder_name = regridder_type_and_function[0] - if len(regridder_type_and_function) > 1: - regridder_function = regridder_type_and_function[1] - - # skip variables that are not in this dataset - if varname not in package.dataset.keys(): - continue - - # regrid the variable - new_package_data[varname] = _regrid_array( - package, - varname, - regrid_context, - regridder_name, - regridder_function, - target_grid, - ) - # set dx and dy if present in target_grid - new_package_data[varname] = assign_coord_if_present( - "dx", target_grid, new_package_data[varname] - ) - new_package_data[varname] = assign_coord_if_present( - "dy", target_grid, new_package_data[varname] - ) if hasattr(package, "auxiliary_data_fields"): expand_transient_auxiliary_variables(package) diff --git a/imod/schemata.py b/imod/schemata.py index 5aae2b157..e2302c733 100644 --- a/imod/schemata.py +++ b/imod/schemata.py @@ -479,6 +479,21 @@ def validate(self, obj: GridDataArray, **kwargs) -> None: ) +class UniqueValuesSchema(BaseSchema): + def __init__(self, other_value: list) -> None: + """ + Validate if unique values in other values list + """ + self.other_value = other_value + + def validate(self, obj: GridDataArray, **kwargs) -> None: + unique_values = np.unique(obj) + if not np.all(np.isin(unique_values, self.other_value)): + raise ValidationError( + f"Unique values not matching: {self.other_value}, got unique values: {unique_values}" + ) + + def _notnull(obj): """ Helper function; does the same as xr.DataArray.notnull. This function is to diff --git a/imod/tests/test_mf6/test_mf6_dis.py b/imod/tests/test_mf6/test_mf6_dis.py index ec12f0838..85f0b8e96 100644 --- a/imod/tests/test_mf6/test_mf6_dis.py +++ b/imod/tests/test_mf6/test_mf6_dis.py @@ -10,6 +10,14 @@ from imod.schemata import ValidationError +def _load_imod5_data_in_memory(imod5_data): + """For debugging purposes, load everything in memory""" + for pkg in imod5_data.values(): + for vardata in pkg.values(): + if isinstance(vardata, xr.DataArray): + vardata.load() + + @pytest.fixture(scope="function") def idomain_and_bottom(): nlay = 3 @@ -189,3 +197,77 @@ def test_write_ascii_griddata_2d_3d(idomain_and_bottom, tmp_path): with open(directory / "dis/botm.dat") as f: bottom_content = f.readlines() assert len(bottom_content) == 1 + + +def test_from_imod5_data__idomain_values(tmp_path): + data = imod.data.imod5_projectfile_data(tmp_path) + imod5_data = data[0] + ibound = imod5_data["bnd"]["ibound"] + # Fix data, as it contains floating values like 0.34, 0.25 etc. + ibound = ibound.where(ibound <= 0, 1) + imod5_data["bnd"]["ibound"] = ibound + _load_imod5_data_in_memory(imod5_data) + + dis = imod.mf6.StructuredDiscretization.from_imod5_data(imod5_data) + + # Test if idomain has appropriate count + assert (dis["idomain"] == -1).sum() == 371824 + assert (dis["idomain"] == 0).sum() == 176912 + assert (dis["idomain"] == 1).sum() == 703936 + + +def test_from_imod5_data__grid_extent(tmp_path): + data = imod.data.imod5_projectfile_data(tmp_path) + imod5_data = data[0] + ibound = imod5_data["bnd"]["ibound"] + # Fix data, as it contains floating values like 0.34, 0.25 etc. + ibound = ibound.where(ibound <= 0, 1) + imod5_data["bnd"]["ibound"] = ibound + _load_imod5_data_in_memory(imod5_data) + + dis = imod.mf6.StructuredDiscretization.from_imod5_data(imod5_data) + + # Test if regridded to smallest grid resolution + assert dis["top"].dx == 25.0 + assert dis["top"].dy == -25.0 + assert (dis.dataset.coords["x"][1] - dis.dataset.coords["x"][0]) == 25.0 + assert (dis.dataset.coords["y"][1] - dis.dataset.coords["y"][0]) == -25.0 + + # Test extent + assert dis.dataset.coords["y"].min() == 360712.5 + assert dis.dataset.coords["y"].max() == 365287.5 + assert dis.dataset.coords["x"].min() == 194712.5 + assert dis.dataset.coords["x"].max() == 199287.5 + + +def test_from_imod5_data__write(tmp_path): + data = imod.data.imod5_projectfile_data(tmp_path) + imod5_data = data[0] + ibound = imod5_data["bnd"]["ibound"] + # Fix data, as it contains floating values like 0.34, 0.25 etc. + ibound = ibound.where(ibound <= 0, 1) + imod5_data["bnd"]["ibound"] = ibound + _load_imod5_data_in_memory(imod5_data) + + directory = tmp_path / "dis_griddata" + directory.mkdir() + write_context = WriteContext(simulation_directory=directory) + + dis = imod.mf6.StructuredDiscretization.from_imod5_data(imod5_data) + + # Test if package written without ValidationError + dis.write(pkgname="dis", globaltimes=[], write_context=write_context) + + # Assert if files written + assert (directory / "dis/top.dat").exists() + assert (directory / "dis/botm.dat").exists() + + +def test_from_imod5_data__validation_error(tmp_path): + data = imod.data.imod5_projectfile_data(tmp_path) + imod5_data = data[0] + + _load_imod5_data_in_memory(imod5_data) + + with pytest.raises(ValidationError): + imod.mf6.StructuredDiscretization.from_imod5_data(imod5_data) diff --git a/imod/tests/test_mf6/test_utilities/test_grid.py b/imod/tests/test_mf6/test_utilities/test_grid.py new file mode 100644 index 000000000..9e444146a --- /dev/null +++ b/imod/tests/test_mf6/test_utilities/test_grid.py @@ -0,0 +1,29 @@ +import numpy as np + +from imod.mf6.utilities.grid import create_smallest_target_grid +from imod.util.spatial import empty_2d + + +def test_create_smallest_target_grid(): + # Three grids with aligned cell edges at each 100m + grid1 = empty_2d(dx=25.0, xmin=100.0, xmax=300.0, dy=-25.0, ymin=100.0, ymax=300.0) + grid2 = empty_2d(dx=50.0, xmin=0.0, xmax=200.0, dy=-50.0, ymin=0.0, ymax=200.0) + grid3 = empty_2d(dx=20.0, xmin=0.0, xmax=400.0, dy=-20.0, ymin=0.0, ymax=400.0) + + actual = create_smallest_target_grid(grid1, grid2, grid3) + + assert actual.coords["dx"] == 20.0 + assert actual.coords["dy"] == -20.0 + assert np.all(actual.coords["x"].values == [110.0, 130.0, 150.0, 170.0, 190.0]) + assert np.all(actual.coords["y"].values == [190.0, 170.0, 150.0, 130.0, 110.0]) + + # Two grids with barely aligned cell edges. + grid1 = empty_2d(dx=50.0, xmin=110.0, xmax=220.0, dy=-50.0, ymin=110.0, ymax=220.0) + grid2 = empty_2d(dx=20.0, xmin=0.0, xmax=400.0, dy=-20.0, ymin=0.0, ymax=400.0) + + actual = create_smallest_target_grid(grid1, grid2) + + assert actual.coords["dx"] == 20.0 + assert actual.coords["dy"] == -20.0 + assert np.all(actual.coords["x"].values == [120.0, 140.0, 160.0, 180.0, 200.0]) + assert np.all(actual.coords["y"].values == [210.0, 190.0, 170.0, 150.0, 130.0]) diff --git a/imod/tests/test_mf6/test_utilities/test_imod5_converter.py b/imod/tests/test_mf6/test_utilities/test_imod5_converter.py new file mode 100644 index 000000000..826c1b440 --- /dev/null +++ b/imod/tests/test_mf6/test_utilities/test_imod5_converter.py @@ -0,0 +1,75 @@ +import pytest +import xarray as xr +from pytest_cases import parametrize_with_cases + +from imod.mf6.utilities.imod5_converter import convert_ibound_to_idomain +from imod.util import empty_3d + + +@pytest.fixture(scope="function") +def template_grid(): + dx = 50.0 + dy = -50.0 + xmin = 0.0 + xmax = 100.0 + ymin = 0.0 + ymax = 100.0 + layer = [1, 2, 3, 4, 5] + + return empty_3d(dx, xmin, xmax, dy, ymin, ymax, layer).fillna(1.0) + + +class IboundCases: + def case_active(self): + thickness = [1.0, 1.0, 1.0, 1.0, 1.0] + ibound = [1, 1, 1, 1, 1] + idomain = [1, 1, 1, 1, 1] + return thickness, ibound, idomain + + def case_inactive(self): + thickness = [1.0, 1.0, 1.0, 1.0, 1.0] + ibound = [0, 1, 1, 1, 0] + idomain = [0, 1, 1, 1, 0] + return thickness, ibound, idomain + + def case_min1(self): + thickness = [1.0, 1.0, 1.0, 1.0, 1.0] + ibound = [1, -1, 1, -1, 0] + idomain = [1, 1, 1, 1, 0] + return thickness, ibound, idomain + + def case_all_inactive(self): + thickness = [1.0, 0.0, 0.0, 0.0, 1.0] + ibound = [0, 0, 0, 0, 0] + idomain = [0, 0, 0, 0, 0] + return thickness, ibound, idomain + + def case_vpt(self): + thickness = [1.0, 0.0, 1.0, 0.0, 1.0] + ibound = [1, 1, 1, 1, 1] + idomain = [1, -1, 1, -1, 1] + return thickness, ibound, idomain + + def case_vpt_zero_thickness_at_edge(self): + thickness = [1.0, 0.0, 1.0, 0.0, 1.0] + ibound = [0, 1, 1, 1, 0] + idomain = [0, 0, 1, 0, 0] + return thickness, ibound, idomain + + def case_mixed(self): + thickness = [1.0, 0.0, 1.0, 0.0, 1.0] + ibound = [1, -1, 1, 1, 0] + idomain = [1, -1, 1, 0, 0] + return thickness, ibound, idomain + + +@parametrize_with_cases(argnames="thickness,ibound,expected", cases=IboundCases) +def test_convert_ibound_to_idomain(template_grid, thickness, ibound, expected): + layer = template_grid.coords["layer"] + thickness = xr.ones_like(layer) * thickness * template_grid + ibound = xr.ones_like(layer) * ibound * template_grid + expected = xr.ones_like(layer) * expected * template_grid + + actual = convert_ibound_to_idomain(ibound, thickness) + + assert actual.equals(expected) diff --git a/imod/typing/grid.py b/imod/typing/grid.py index 2a74d7b25..cff9eaa0b 100644 --- a/imod/typing/grid.py +++ b/imod/typing/grid.py @@ -41,6 +41,16 @@ def nan_like(grid: xu.UgridDataArray, dtype=np.float32, *args, **kwargs): return xu.full_like(grid, fill_value=np.nan, dtype=dtype, *args, **kwargs) +@typedispatch +def full_like(grid: xr.DataArray, fill_value, *args, **kwargs): + return xr.full_like(grid, fill_value, *args, **kwargs) + + +@typedispatch +def full_like(grid: xu.UgridDataArray, fill_value, *args, **kwargs): + return xu.full_like(grid, fill_value, *args, **kwargs) + + @typedispatch def is_unstructured(grid: xu.UgridDataArray | xu.UgridDataset) -> bool: return True From 721d5c33944a48df6d349a042bee08a9fa60d51d Mon Sep 17 00:00:00 2001 From: luitjansl <64598682+luitjansl@users.noreply.github.com> Date: Tue, 7 May 2024 13:11:07 +0200 Subject: [PATCH 02/53] Issue #965 npf from imod5 (#1010) Fixes #965 # Description Adds a function to import an npf package from an imod5 project file. Adds tests. # Checklist - [x] Links to correct issue - [ ] Update changelog, if changes affect users - [x] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [x] Unit tests were added - [ ] **If feature added**: Added/extended example --------- Co-authored-by: Joeri van Engelen --- imod/mf6/npf.py | 81 +++++++++++++++++- imod/mf6/utilities/imod5_converter.py | 16 ++++ imod/mf6/utilities/regrid.py | 2 +- imod/tests/conftest.py | 1 + .../backward_compatibility_fixture.py | 20 +++++ imod/tests/test_mf6/test_mf6_dis.py | 11 +-- imod/tests/test_mf6/test_mf6_npf.py | 85 +++++++++++++++++++ 7 files changed, 206 insertions(+), 10 deletions(-) create mode 100644 imod/tests/fixtures/backward_compatibility_fixture.py diff --git a/imod/mf6/npf.py b/imod/mf6/npf.py index f644faebf..e23d6f09e 100644 --- a/imod/mf6/npf.py +++ b/imod/mf6/npf.py @@ -1,12 +1,19 @@ import warnings +from copy import deepcopy from typing import Optional, Tuple import numpy as np +import xarray as xr from imod.logging import init_log_decorator from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.package import Package -from imod.mf6.utilities.regrid import RegridderType +from imod.mf6.utilities.imod5_converter import fill_missing_layers +from imod.mf6.utilities.regrid import ( + RegridderType, + RegridderWeightsCache, + _regrid_package_data, +) from imod.mf6.validation import PKG_DIMS_SCHEMA from imod.schemata import ( AllValueSchema, @@ -17,6 +24,7 @@ IndexesSchema, ) from imod.typing import GridDataArray +from imod.typing.grid import zeros_like def _dataarray_to_bool(griddataarray: GridDataArray) -> bool: @@ -461,3 +469,74 @@ def _validate(self, schemata, **kwargs): def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: return self._regrid_method + + @classmethod + def from_imod5_data( + cls, + imod5_data: dict[str, dict[str, GridDataArray]], + target_grid: GridDataArray, + regridder_types: Optional[dict[str, tuple[RegridderType, str]]] = None, + ) -> "NodePropertyFlow": + """ + Construct an npf-package from iMOD5 data, loaded with the + :func:`imod.formats.prj.open_projectfile_data` function. + + .. note:: + + The method expects the iMOD5 model to be fully 3D, not quasi-3D. + + Parameters + ---------- + imod5_data: dict + Dictionary with iMOD5 data. This can be constructed from the + :func:`imod.formats.prj.open_projectfile_data` method. + target_grid: GridDataArray + The grid that should be used for the new package. Does not + need to be identical to one of the input grids. + regridder_types: dict, optional + Optional dictionary with regridder types for a specific variable. + Use this to override default regridding methods. + + Returns + ------- + Modflow 6 npf package. + + """ + + data = { + "k": imod5_data["khv"]["kh"], + } + has_vertical_anisotropy = ( + "kva" in imod5_data.keys() + and "vertical_anisotropy" in imod5_data["kva"].keys() + ) + has_horizontal_anisotropy = "ani" in imod5_data.keys() + + if has_vertical_anisotropy: + data["k33"] = data["k"] * imod5_data["kva"]["vertical_anisotropy"] + if has_horizontal_anisotropy: + if not np.all(np.isnan(imod5_data["ani"]["factor"].values)): + factor = imod5_data["ani"]["factor"] + factor = fill_missing_layers(factor, target_grid, 1) + data["k22"] = data["k"] * factor + if not np.all(np.isnan(imod5_data["ani"]["angle"].values)): + angle1 = imod5_data["ani"]["angle"] + angle1 = 90.0 - angle1 + angle1 = xr.where(angle1 < 0, 360.0 + angle1, angle1) + angle1 = fill_missing_layers(angle1, target_grid, 0) + data["angle1"] = angle1 + + icelltype = zeros_like(target_grid, dtype=int) + + regridder_settings = deepcopy(cls._regrid_method) + if regridder_types is not None: + regridder_settings.update(regridder_types) + + regrid_context = RegridderWeightsCache(data["k"], target_grid) + + new_package_data = _regrid_package_data( + data, target_grid, regridder_settings, regrid_context, {} + ) + new_package_data["icelltype"] = icelltype + + return NodePropertyFlow(**new_package_data) diff --git a/imod/mf6/utilities/imod5_converter.py b/imod/mf6/utilities/imod5_converter.py index 221f2efb2..b13dfdb19 100644 --- a/imod/mf6/utilities/imod5_converter.py +++ b/imod/mf6/utilities/imod5_converter.py @@ -1,3 +1,5 @@ +from typing import Union + import numpy as np import xarray as xr @@ -26,3 +28,17 @@ def convert_ibound_to_idomain( ) # Fill the remaining nans at tops and bottoms with 0 return idomain_float.fillna(0).astype(int) + + +def fill_missing_layers( + source: xr.DataArray, full: xr.DataArray, fillvalue: Union[float | int] +) -> xr.DataArray: + """ + This function takes a source grid in which the layer dimension is + incomplete. It creates a result-grid which has the same layers as the "full" + grid, which is assumed to have all layers. The result has the values in the + source for the layers that are in the source. For the other layers, the + fillvalue is assigned. + """ + layer = full.coords["layer"] + return source.reindex(layer=layer, fill_value=fillvalue) diff --git a/imod/mf6/utilities/regrid.py b/imod/mf6/utilities/regrid.py index a44f570ee..dc48f9b6d 100644 --- a/imod/mf6/utilities/regrid.py +++ b/imod/mf6/utilities/regrid.py @@ -198,7 +198,7 @@ def _regrid_package_data( target_grid: GridDataArray, regridder_settings: dict[str, tuple[RegridderType, str]], regrid_context: RegridderWeightsCache, - new_package_data: Optional[dict[str, GridDataArray]] = {}, + new_package_data: dict[str, GridDataArray] = {}, ) -> dict[str, GridDataArray]: """ Regrid package data. Loops over regridder settings to regrid variables one diff --git a/imod/tests/conftest.py b/imod/tests/conftest.py index 80abb3889..1150a8ad3 100644 --- a/imod/tests/conftest.py +++ b/imod/tests/conftest.py @@ -1,5 +1,6 @@ import pytest +from .fixtures.backward_compatibility_fixture import imod5_dataset from .fixtures.flow_basic_fixture import ( basic_dis, basic_dis__topsystem, diff --git a/imod/tests/fixtures/backward_compatibility_fixture.py b/imod/tests/fixtures/backward_compatibility_fixture.py new file mode 100644 index 000000000..8ec8a2576 --- /dev/null +++ b/imod/tests/fixtures/backward_compatibility_fixture.py @@ -0,0 +1,20 @@ +import pytest +import xarray as xr + +import imod + + +@pytest.fixture(scope="module") +def imod5_dataset(): + tmp_path = imod.util.temporary_directory() + data = imod.data.imod5_projectfile_data(tmp_path) + _load_imod5_data_in_memory(data[0]) + return data[0] + + +def _load_imod5_data_in_memory(imod5_data): + """For debugging purposes, load everything in memory""" + for pkg in imod5_data.values(): + for vardata in pkg.values(): + if isinstance(vardata, xr.DataArray): + vardata.load() diff --git a/imod/tests/test_mf6/test_mf6_dis.py b/imod/tests/test_mf6/test_mf6_dis.py index 85f0b8e96..03fbbb73d 100644 --- a/imod/tests/test_mf6/test_mf6_dis.py +++ b/imod/tests/test_mf6/test_mf6_dis.py @@ -8,14 +8,9 @@ import imod from imod.mf6.write_context import WriteContext from imod.schemata import ValidationError - - -def _load_imod5_data_in_memory(imod5_data): - """For debugging purposes, load everything in memory""" - for pkg in imod5_data.values(): - for vardata in pkg.values(): - if isinstance(vardata, xr.DataArray): - vardata.load() +from imod.tests.fixtures.backward_compatibility_fixture import ( + _load_imod5_data_in_memory, +) @pytest.fixture(scope="function") diff --git a/imod/tests/test_mf6/test_mf6_npf.py b/imod/tests/test_mf6/test_mf6_npf.py index da2c68779..6c4715805 100644 --- a/imod/tests/test_mf6/test_mf6_npf.py +++ b/imod/tests/test_mf6/test_mf6_npf.py @@ -1,6 +1,7 @@ import pathlib import re import textwrap +from copy import deepcopy import numpy as np import pytest @@ -208,3 +209,87 @@ def test_configure_xt3d(tmp_path): assert "xt3d" not in rendered assert "rhs" not in rendered assert not npf.get_xt3d_option() + + +@pytest.mark.usefixtures("imod5_dataset") +def test_npf_from_imod5_isotropic(imod5_dataset, tmp_path): + data = deepcopy(imod5_dataset) + # throw out kva (=vertical anisotropy array) and ani (=horizontal anisotropy array) + data.pop("kva") + data.pop("ani") + + target_grid = data["khv"]["kh"] + npf = imod.mf6.NodePropertyFlow.from_imod5_data(data, target_grid) + + # Test array values are the same for k ( disregarding the locations where k == np.nan) + k_nan_removed = xr.where(np.isnan(npf.dataset["k"]), 0, npf.dataset["k"]) + np.testing.assert_allclose(k_nan_removed, data["khv"]["kh"].values) + + rendered_npf = npf.render(tmp_path, "npf", None, None) + assert "k22" not in rendered_npf + assert "k33" not in rendered_npf + assert "angle1" not in rendered_npf + assert "angle2" not in rendered_npf + assert "angle3" not in rendered_npf + + +@pytest.mark.usefixtures("imod5_dataset") +def test_npf_from_imod5_horizontal_anisotropy(imod5_dataset, tmp_path): + data = deepcopy(imod5_dataset) + # throw out kva (=vertical anisotropy array) + data.pop("kva") + + target_grid = data["khv"]["kh"] + data["ani"]["angle"].values[:, :, :] = 135.0 + data["ani"]["factor"].values[:, :, :] = 0.1 + npf = imod.mf6.NodePropertyFlow.from_imod5_data(data, target_grid) + + # Test array values for k22 and angle1 + for layer in npf.dataset["k"].coords["layer"].values: + ds_layer = npf.dataset.sel({"layer": layer}) + + ds_layer = ds_layer.fillna(0.0) + + if layer in data["ani"]["factor"].coords["layer"].values: + np.testing.assert_allclose( + ds_layer["k"].values * 0.1, ds_layer["k22"].values, atol=1e-10 + ) + assert np.all(ds_layer["angle1"].values == 315.0) + else: + assert np.all(ds_layer["k"].values == ds_layer["k22"].values) + assert np.all(ds_layer["angle1"].values == 0.0) + + rendered_npf = npf.render(tmp_path, "npf", None, None) + assert "k22" in rendered_npf + assert "k33" not in rendered_npf + assert "angle1" in rendered_npf + assert "angle2" not in rendered_npf + assert "angle3" not in rendered_npf + + +@pytest.mark.usefixtures("imod5_dataset") +def test_npf_from_imod5_vertical_anisotropy(imod5_dataset, tmp_path): + data = deepcopy(imod5_dataset) + # throw out ani (=horizontal anisotropy array) + data.pop("ani") + + data["kva"]["vertical_anisotropy"].values[:] = 0.1 + target_grid = data["khv"]["kh"] + + npf = imod.mf6.NodePropertyFlow.from_imod5_data(data, target_grid) + + # Test array values for k33 + for layer in npf.dataset["k"].coords["layer"].values: + k_layer = npf.dataset["k"].sel({"layer": layer}) + k33_layer = npf.dataset["k33"].sel({"layer": layer}) + + k_layer = xr.where(np.isnan(k_layer), 0.0, k_layer) + k33_layer = xr.where(np.isnan(k33_layer), 0.0, k33_layer) + np.testing.assert_allclose(k_layer.values * 0.1, k33_layer.values, atol=1e-10) + + rendered_npf = npf.render(tmp_path, "npf", None, None) + assert "k22" not in rendered_npf + assert "k33" in rendered_npf + assert "angle1" not in rendered_npf + assert "angle2" not in rendered_npf + assert "angle3" not in rendered_npf From 741ac1d780dc4c69cfd5fe8b60c90e5aa6bd7c2c Mon Sep 17 00:00:00 2001 From: luitjan Date: Wed, 8 May 2024 10:05:44 +0200 Subject: [PATCH 03/53] fixed tests after merge --- imod/mf6/dis.py | 2 +- imod/mf6/npf.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/imod/mf6/dis.py b/imod/mf6/dis.py index bd0fcc142..1eabddd69 100644 --- a/imod/mf6/dis.py +++ b/imod/mf6/dis.py @@ -212,7 +212,7 @@ def from_imod5_data( if regridder_types is not None: regridder_settings.update(regridder_types) - regrid_context = RegridderWeightsCache(data["idomain"], target_grid) + regrid_context = RegridderWeightsCache() new_package_data = _regrid_package_data( data, target_grid, regridder_settings, regrid_context diff --git a/imod/mf6/npf.py b/imod/mf6/npf.py index e23d6f09e..41757bbc2 100644 --- a/imod/mf6/npf.py +++ b/imod/mf6/npf.py @@ -532,7 +532,7 @@ def from_imod5_data( if regridder_types is not None: regridder_settings.update(regridder_types) - regrid_context = RegridderWeightsCache(data["k"], target_grid) + regrid_context = RegridderWeightsCache() new_package_data = _regrid_package_data( data, target_grid, regridder_settings, regrid_context, {} From 65ba5f2f661457c61bd811becdf1e282f2345335 Mon Sep 17 00:00:00 2001 From: luitjansl <64598682+luitjansl@users.noreply.github.com> Date: Wed, 8 May 2024 17:10:37 +0200 Subject: [PATCH 04/53] Issue #961 flow packages from imod5 (#1023) Fixes #961 # Description implements importing from a imod5 project file for storage and initial conditions. # Checklist - [X] Links to correct issue - [ ] Update changelog, if changes affect users - [X] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [X] Unit tests were added - [ ] **If feature added**: Added/extended example --------- Co-authored-by: Joeri van Engelen --- imod/mf6/ic.py | 55 +++++++++++++++++++++++- imod/mf6/sto.py | 66 ++++++++++++++++++++++++++++- imod/tests/test_mf6/test_mf6_ic.py | 15 +++++++ imod/tests/test_mf6/test_mf6_sto.py | 30 +++++++++++++ imod/typing/grid.py | 2 +- 5 files changed, 165 insertions(+), 3 deletions(-) diff --git a/imod/mf6/ic.py b/imod/mf6/ic.py index 462a79ee4..4547fde8c 100644 --- a/imod/mf6/ic.py +++ b/imod/mf6/ic.py @@ -1,4 +1,5 @@ import warnings +from copy import deepcopy from typing import Optional, Tuple import numpy as np @@ -6,9 +7,14 @@ from imod.logging import init_log_decorator from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.package import Package -from imod.mf6.utilities.regrid import RegridderType +from imod.mf6.utilities.regrid import ( + RegridderType, + RegridderWeightsCache, + _regrid_package_data, +) from imod.mf6.validation import PKG_DIMS_SCHEMA from imod.schemata import DTypeSchema, IdentityNoDataSchema, IndexesSchema +from imod.typing import GridDataArray class InitialConditions(Package, IRegridPackage): @@ -98,3 +104,50 @@ def render(self, directory, pkgname, globaltimes, binary): def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: return self._regrid_method + + @classmethod + def from_imod5_data( + cls, + imod5_data: dict[str, dict[str, GridDataArray]], + target_grid: GridDataArray, + regridder_types: Optional[dict[str, tuple[RegridderType, str]]] = None, + ) -> "InitialConditions": + """ + Construct an InitialConditions-package from iMOD5 data, loaded with the + :func:`imod.formats.prj.open_projectfile_data` function. + + .. note:: + + The method expects the iMOD5 model to be fully 3D, not quasi-3D. + + Parameters + ---------- + imod5_data: dict + Dictionary with iMOD5 data. This can be constructed from the + :func:`imod.formats.prj.open_projectfile_data` method. + target_grid: GridDataArray + The grid that should be used for the new package. Does not + need to be identical to one of the input grids. + regridder_types: dict, optional + Optional dictionary with regridder types for a specific variable. + Use this to override default regridding methods. + + Returns + ------- + Modflow 6 InitialConditions package. + """ + + data = { + "start": imod5_data["shd"]["head"], + } + + regridder_settings = deepcopy(cls._regrid_method) + if regridder_types is not None: + regridder_settings.update(regridder_types) + + regrid_context = RegridderWeightsCache() + + new_package_data = _regrid_package_data( + data, target_grid, regridder_settings, regrid_context, {} + ) + return cls(**new_package_data) diff --git a/imod/mf6/sto.py b/imod/mf6/sto.py index a772cc9f5..e873cda85 100644 --- a/imod/mf6/sto.py +++ b/imod/mf6/sto.py @@ -1,4 +1,5 @@ import abc +from copy import deepcopy from typing import Optional, Tuple import numpy as np @@ -6,7 +7,11 @@ from imod.logging import init_log_decorator from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.package import Package -from imod.mf6.utilities.regrid import RegridderType +from imod.mf6.utilities.regrid import ( + RegridderType, + RegridderWeightsCache, + _regrid_package_data, +) from imod.mf6.validation import PKG_DIMS_SCHEMA from imod.schemata import ( AllValueSchema, @@ -15,6 +20,8 @@ IdentityNoDataSchema, IndexesSchema, ) +from imod.typing import GridDataArray +from imod.typing.grid import zeros_like class Storage(Package): @@ -331,3 +338,60 @@ def render(self, directory, pkgname, globaltimes, binary): def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: return self._regrid_method + + @classmethod + def from_imod5_data( + cls, + imod5_data: dict[str, dict[str, GridDataArray]], + target_grid: GridDataArray, + regridder_types: Optional[dict[str, tuple[RegridderType, str]]] = None, + ) -> "StorageCoefficient": + """ + Construct a StorageCoefficient-package from iMOD5 data, loaded with the + :func:`imod.formats.prj.open_projectfile_data` function. + + .. note:: + + The method expects the iMOD5 model to be fully 3D, not quasi-3D. + + Parameters + ---------- + imod5_data: dict + Dictionary with iMOD5 data. This can be constructed from the + :func:`imod.formats.prj.open_projectfile_data` method. + target_grid: GridDataArray + The grid that should be used for the new package. Does not + need to be identical to one of the input grids. + regridder_types: dict, optional + Optional dictionary with regridder types for a specific variable. + Use this to override default regridding methods. + + Returns + ------- + Modflow 6 StorageCoefficient package. Its specific yield is 0 and it's transient if any storage_coefficient + is larger than 0. All cells are set to inconvertible (they stay confined throughout the simulation) + """ + + data = { + "storage_coefficient": imod5_data["sto"]["storage_coefficient"], + } + + regridder_settings = deepcopy(cls._regrid_method) + if regridder_types is not None: + regridder_settings.update(regridder_types) + + regrid_context = RegridderWeightsCache() + + new_package_data = _regrid_package_data( + data, target_grid, regridder_settings, regrid_context, {} + ) + + new_package_data["convertible"] = zeros_like( + new_package_data["storage_coefficient"], dtype=int + ) + new_package_data["transient"] = np.any( + new_package_data["storage_coefficient"].values > 0 + ) + new_package_data["specific_yield"] = None + + return cls(**new_package_data) diff --git a/imod/tests/test_mf6/test_mf6_ic.py b/imod/tests/test_mf6/test_mf6_ic.py index ef3ebecbf..8c9112c51 100644 --- a/imod/tests/test_mf6/test_mf6_ic.py +++ b/imod/tests/test_mf6/test_mf6_ic.py @@ -1,5 +1,6 @@ import pathlib import textwrap +from copy import deepcopy import pytest @@ -40,3 +41,17 @@ def test_validate_false(): def test_wrong_arguments(): with pytest.raises(ValueError): imod.mf6.InitialConditions(head=0.0, start=1.0) + + +@pytest.mark.usefixtures("imod5_dataset") +def test_from_imod5(imod5_dataset, tmp_path): + data = deepcopy(imod5_dataset) + + target_grid = data["khv"]["kh"] + + ic = imod.mf6.InitialConditions.from_imod5_data(data, target_grid) + + ic._validate_init_schemata(True) + + rendered_ic = ic.render(tmp_path, "ic", None, False) + assert "strt" in rendered_ic diff --git a/imod/tests/test_mf6/test_mf6_sto.py b/imod/tests/test_mf6/test_mf6_sto.py index 185f67482..6d90bc9e8 100644 --- a/imod/tests/test_mf6/test_mf6_sto.py +++ b/imod/tests/test_mf6/test_mf6_sto.py @@ -1,5 +1,6 @@ import pathlib import textwrap +from copy import deepcopy import numpy as np import pytest @@ -428,3 +429,32 @@ def test_check_nan_in_active_cell(sy_layered, convertible, dis): for var, error in errors.items(): assert var == "storage_coefficient" + + +@pytest.mark.usefixtures("imod5_dataset") +def test_from_imod5(imod5_dataset, tmp_path): + data = deepcopy(imod5_dataset) + + target_grid = data["khv"]["kh"] + + sto = imod.mf6.StorageCoefficient.from_imod5_data(data, target_grid) + + assert not sto.dataset["save_flows"] + assert sto.dataset["transient"] + assert sto.dataset["storage_coefficient"].values[0] == 0.15 + assert np.all(sto.dataset["storage_coefficient"].values[1:] == 1e-5) + assert sto.dataset["specific_yield"].values[()] is None + + rendered_sto = sto.render(tmp_path, "sto", None, False) + assert "ss" in rendered_sto + + +@pytest.mark.usefixtures("imod5_dataset") +def test_from_imod5_steady_state(imod5_dataset): + data = deepcopy(imod5_dataset) + data["sto"]["storage_coefficient"].values[:] = 0 + target_grid = data["khv"]["kh"] + + sto = imod.mf6.StorageCoefficient.from_imod5_data(data, target_grid) + + assert not sto.dataset["transient"] diff --git a/imod/typing/grid.py b/imod/typing/grid.py index 2b642882f..bba56763f 100644 --- a/imod/typing/grid.py +++ b/imod/typing/grid.py @@ -46,7 +46,7 @@ def full_like(grid: xr.DataArray, fill_value, *args, **kwargs): return xr.full_like(grid, fill_value, *args, **kwargs) -@typedispatch +@typedispatch # type: ignore [no-redef] def full_like(grid: xu.UgridDataArray, fill_value, *args, **kwargs): return xu.full_like(grid, fill_value, *args, **kwargs) From 637da9df7e074d7521d43abfd9c33eb43e516e9d Mon Sep 17 00:00:00 2001 From: luitjan Date: Wed, 8 May 2024 17:36:31 +0200 Subject: [PATCH 05/53] added # noqa: F811 --- imod/typing/grid.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imod/typing/grid.py b/imod/typing/grid.py index f14812a4e..73c3452a7 100644 --- a/imod/typing/grid.py +++ b/imod/typing/grid.py @@ -47,7 +47,7 @@ def full_like(grid: xr.DataArray, fill_value, *args, **kwargs): @typedispatch # type: ignore [no-redef] -def full_like(grid: xu.UgridDataArray, fill_value, *args, **kwargs): +def full_like(grid: xu.UgridDataArray, fill_value, *args, **kwargs): # noqa: F811 return xu.full_like(grid, fill_value, *args, **kwargs) From 9b9a2e3193c3c5d334e5d69ebc088a5946d6a190 Mon Sep 17 00:00:00 2001 From: luitjansl <64598682+luitjansl@users.noreply.github.com> Date: Tue, 21 May 2024 14:45:20 +0200 Subject: [PATCH 06/53] Issue #969 imod5 import recharge (#1031) Fixes #969 # Description implements importing recharge packages from a project file. The recharge can be imported using a planar grid, in which case it assigns the recharge to the uppermost active cell for each column. The recharge can also be imported from a non-planar (so fully 3d) grid in which case it is just regridded to the target grid. # Checklist - [X] Links to correct issue - [ ] Update changelog, if changes affect users - [X] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [X] Unit tests were added - [ ] **If feature added**: Added/extended example --------- Co-authored-by: Joeri van Engelen --- imod/mf6/rch.py | 80 ++++++++++++- .../backward_compatibility_fixture.py | 11 +- imod/tests/test_mf6/test_mf6_dis.py | 51 +++----- imod/tests/test_mf6/test_mf6_rch.py | 111 ++++++++++++++++++ imod/tests/test_typing/test_typing_grid.py | 47 +++++++- imod/typing/grid.py | 27 +++++ 6 files changed, 289 insertions(+), 38 deletions(-) diff --git a/imod/mf6/rch.py b/imod/mf6/rch.py index 3584bed71..c78beafe2 100644 --- a/imod/mf6/rch.py +++ b/imod/mf6/rch.py @@ -1,12 +1,19 @@ +from copy import deepcopy from typing import Optional, Tuple import numpy as np from imod.logging import init_log_decorator from imod.mf6.boundary_condition import BoundaryCondition +from imod.mf6.dis import StructuredDiscretization from imod.mf6.interfaces.iregridpackage import IRegridPackage -from imod.mf6.utilities.regrid import RegridderType +from imod.mf6.utilities.regrid import ( + RegridderType, + RegridderWeightsCache, + _regrid_package_data, +) from imod.mf6.validation import BOUNDARY_DIMS_SCHEMA, CONC_DIMS_SCHEMA +from imod.prepare.topsystem.allocation import ALLOCATION_OPTION, allocate_rch_cells from imod.schemata import ( AllInsideNoDataSchema, AllNoDataSchema, @@ -18,6 +25,11 @@ IndexesSchema, OtherCoordsSchema, ) +from imod.typing import GridDataArray +from imod.typing.grid import ( + enforce_dim_order, + is_planar_grid, +) class Recharge(BoundaryCondition, IRegridPackage): @@ -152,3 +164,69 @@ def _validate(self, schemata, **kwargs): def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: return self._regrid_method + + @classmethod + def from_imod5_data( + cls, + imod5_data: dict[str, dict[str, GridDataArray]], + dis_pkg: StructuredDiscretization, + regridder_types: Optional[dict[str, tuple[RegridderType, str]]] = None, + ) -> "Recharge": + """ + Construct an rch-package from iMOD5 data, loaded with the + :func:`imod.formats.prj.open_projectfile_data` function. + + .. note:: + + The method expects the iMOD5 model to be fully 3D, not quasi-3D. + + Parameters + ---------- + imod5_data: dict + Dictionary with iMOD5 data. This can be constructed from the + :func:`imod.formats.prj.open_projectfile_data` method. + dis_pkg: GridDataArray + The discretization package for the simulation. Its grid does not + need to be identical to one of the input grids. + regridder_types: dict, optional + Optional dictionary with regridder types for a specific variable. + Use this to override default regridding methods. + + Returns + ------- + Modflow 6 rch package. + + """ + new_idomain = dis_pkg.dataset["idomain"] + data = { + "rate": imod5_data["rch"]["rate"], + } + new_package_data = {} + + # first regrid the inputs to the target grid. + regridder_settings = deepcopy(cls._regrid_method) + if regridder_types is not None: + regridder_settings.update(regridder_types) + + regrid_context = RegridderWeightsCache() + + new_package_data = _regrid_package_data( + data, new_idomain, regridder_settings, regrid_context, {} + ) + + # if rate has only layer 0, then it is planar. + if is_planar_grid(new_package_data["rate"]): + planar_rate_regridded = new_package_data["rate"].isel(layer=0, drop=True) + # create an array indicating in which cells rch is active + is_rch_cell = allocate_rch_cells( + ALLOCATION_OPTION.at_first_active, + new_idomain == 1, + planar_rate_regridded, + ) + + # remove rch from cells where it is not allocated and broadcast over layers. + rch_rate = planar_rate_regridded.where(is_rch_cell) + rch_rate = enforce_dim_order(rch_rate) + new_package_data["rate"] = rch_rate + + return Recharge(**new_package_data) diff --git a/imod/tests/fixtures/backward_compatibility_fixture.py b/imod/tests/fixtures/backward_compatibility_fixture.py index 8ec8a2576..955c8bbf7 100644 --- a/imod/tests/fixtures/backward_compatibility_fixture.py +++ b/imod/tests/fixtures/backward_compatibility_fixture.py @@ -8,8 +8,15 @@ def imod5_dataset(): tmp_path = imod.util.temporary_directory() data = imod.data.imod5_projectfile_data(tmp_path) - _load_imod5_data_in_memory(data[0]) - return data[0] + data = data[0] + + _load_imod5_data_in_memory(data) + + # Fix data for ibound as it contains floating values like 0.34, 0.25 etc. + ibound = data["bnd"]["ibound"] + ibound = ibound.where(ibound <= 0, 1) + data["bnd"]["ibound"] = ibound + return data def _load_imod5_data_in_memory(imod5_data): diff --git a/imod/tests/test_mf6/test_mf6_dis.py b/imod/tests/test_mf6/test_mf6_dis.py index 03fbbb73d..73e3a7324 100644 --- a/imod/tests/test_mf6/test_mf6_dis.py +++ b/imod/tests/test_mf6/test_mf6_dis.py @@ -194,16 +194,9 @@ def test_write_ascii_griddata_2d_3d(idomain_and_bottom, tmp_path): assert len(bottom_content) == 1 -def test_from_imod5_data__idomain_values(tmp_path): - data = imod.data.imod5_projectfile_data(tmp_path) - imod5_data = data[0] - ibound = imod5_data["bnd"]["ibound"] - # Fix data, as it contains floating values like 0.34, 0.25 etc. - ibound = ibound.where(ibound <= 0, 1) - imod5_data["bnd"]["ibound"] = ibound - _load_imod5_data_in_memory(imod5_data) - - dis = imod.mf6.StructuredDiscretization.from_imod5_data(imod5_data) +@pytest.mark.usefixtures("imod5_dataset") +def test_from_imod5_data__idomain_values(imod5_dataset): + dis = imod.mf6.StructuredDiscretization.from_imod5_data(imod5_dataset) # Test if idomain has appropriate count assert (dis["idomain"] == -1).sum() == 371824 @@ -211,16 +204,9 @@ def test_from_imod5_data__idomain_values(tmp_path): assert (dis["idomain"] == 1).sum() == 703936 -def test_from_imod5_data__grid_extent(tmp_path): - data = imod.data.imod5_projectfile_data(tmp_path) - imod5_data = data[0] - ibound = imod5_data["bnd"]["ibound"] - # Fix data, as it contains floating values like 0.34, 0.25 etc. - ibound = ibound.where(ibound <= 0, 1) - imod5_data["bnd"]["ibound"] = ibound - _load_imod5_data_in_memory(imod5_data) - - dis = imod.mf6.StructuredDiscretization.from_imod5_data(imod5_data) +@pytest.mark.usefixtures("imod5_dataset") +def test_from_imod5_data__grid_extent(imod5_dataset): + dis = imod.mf6.StructuredDiscretization.from_imod5_data(imod5_dataset) # Test if regridded to smallest grid resolution assert dis["top"].dx == 25.0 @@ -235,20 +221,13 @@ def test_from_imod5_data__grid_extent(tmp_path): assert dis.dataset.coords["x"].max() == 199287.5 -def test_from_imod5_data__write(tmp_path): - data = imod.data.imod5_projectfile_data(tmp_path) - imod5_data = data[0] - ibound = imod5_data["bnd"]["ibound"] - # Fix data, as it contains floating values like 0.34, 0.25 etc. - ibound = ibound.where(ibound <= 0, 1) - imod5_data["bnd"]["ibound"] = ibound - _load_imod5_data_in_memory(imod5_data) - +@pytest.mark.usefixtures("imod5_dataset") +def test_from_imod5_data__write(imod5_dataset, tmp_path): directory = tmp_path / "dis_griddata" directory.mkdir() write_context = WriteContext(simulation_directory=directory) - dis = imod.mf6.StructuredDiscretization.from_imod5_data(imod5_data) + dis = imod.mf6.StructuredDiscretization.from_imod5_data(imod5_dataset) # Test if package written without ValidationError dis.write(pkgname="dis", globaltimes=[], write_context=write_context) @@ -259,10 +238,14 @@ def test_from_imod5_data__write(tmp_path): def test_from_imod5_data__validation_error(tmp_path): - data = imod.data.imod5_projectfile_data(tmp_path) - imod5_data = data[0] + # don't use the fixture "imod5_dataset" for this test, because we don't want the + # ibound cleanup. Without this cleanup we get a validation error, + # which is what we want to test here. - _load_imod5_data_in_memory(imod5_data) + tmp_path = imod.util.temporary_directory() + data = imod.data.imod5_projectfile_data(tmp_path) + data = data[0] + _load_imod5_data_in_memory(data) with pytest.raises(ValidationError): - imod.mf6.StructuredDiscretization.from_imod5_data(imod5_data) + imod.mf6.StructuredDiscretization.from_imod5_data(data) diff --git a/imod/tests/test_mf6/test_mf6_rch.py b/imod/tests/test_mf6/test_mf6_rch.py index 43567bd80..4f3e37da9 100644 --- a/imod/tests/test_mf6/test_mf6_rch.py +++ b/imod/tests/test_mf6/test_mf6_rch.py @@ -2,14 +2,17 @@ import re import tempfile import textwrap +from copy import deepcopy import numpy as np import pytest import xarray as xr import imod +from imod.mf6.dis import StructuredDiscretization from imod.mf6.write_context import WriteContext from imod.schemata import ValidationError +from imod.typing.grid import is_planar_grid, is_transient_data_grid, nan_like @pytest.fixture(scope="function") @@ -324,3 +327,111 @@ def test_clip_box(rch_dict): selection = rch.clip_box(x_min=10.0, x_max=20.0, y_min=10.0, y_max=20.0) assert selection["rate"].dims == ("y", "x") assert selection["rate"].shape == (1, 1) + + +@pytest.mark.usefixtures("imod5_dataset") +def test_planar_rch_from_imod5_constant(imod5_dataset, tmp_path): + data = deepcopy(imod5_dataset) + target_discretization = StructuredDiscretization.from_imod5_data(data) + + # create a planar grid with time-independent recharge + data["rch"]["rate"]["layer"].values[0] = 0 + assert not is_transient_data_grid(data["rch"]["rate"]) + assert is_planar_grid(data["rch"]["rate"]) + + # Act + rch = imod.mf6.Recharge.from_imod5_data(data, target_discretization) + + # Assert + rendered_rch = rch.render(tmp_path, "rch", None, None) + assert "maxbound 33856" in rendered_rch + assert rendered_rch.count("begin period") == 1 + # teardown + data["rch"]["rate"]["layer"].values[0] = 1 + + +@pytest.mark.usefixtures("imod5_dataset") +def test_planar_rch_from_imod5_transient(imod5_dataset, tmp_path): + data = deepcopy(imod5_dataset) + target_discretization = StructuredDiscretization.from_imod5_data(data) + + # create a grid with recharge for 3 timesteps + input_recharge = data["rch"]["rate"].copy(deep=True) + input_recharge = input_recharge.expand_dims({"time": [0, 1, 2]}) + + # make it planar by setting the layer coordinate to 0 + input_recharge = input_recharge.assign_coords({"layer": [0]}) + + # update the data set + data["rch"]["rate"] = input_recharge + assert is_transient_data_grid(data["rch"]["rate"]) + assert is_planar_grid(data["rch"]["rate"]) + + # act + rch = imod.mf6.Recharge.from_imod5_data(data, target_discretization) + + # assert + rendered_rch = rch.render(tmp_path, "rch", [0, 1, 2], None) + assert rendered_rch.count("begin period") == 3 + assert "maxbound 33856" in rendered_rch + + +@pytest.mark.usefixtures("imod5_dataset") +def test_non_planar_rch_from_imod5_constant(imod5_dataset, tmp_path): + data = deepcopy(imod5_dataset) + target_discretization = StructuredDiscretization.from_imod5_data(data) + + # make the first layer of the target grid inactive + target_grid = target_discretization.dataset["idomain"] + target_grid.loc[{"layer": 1}] = 0 + + # the input for recharge is on the second layer of the targetgrid + original_rch = data["rch"]["rate"].copy(deep=True) + data["rch"]["rate"] = data["rch"]["rate"].assign_coords({"layer": [0]}) + input_recharge = nan_like(data["khv"]["kh"]) + input_recharge.loc[{"layer": 2}] = data["rch"]["rate"].isel(layer=0) + + # update the data set + + data["rch"]["rate"] = input_recharge + assert not is_planar_grid(data["rch"]["rate"]) + assert not is_transient_data_grid(data["rch"]["rate"]) + + # act + rch = imod.mf6.Recharge.from_imod5_data(data, target_discretization) + + # assert + rendered_rch = rch.render(tmp_path, "rch", None, None) + assert rendered_rch.count("begin period") == 1 + assert "maxbound 33856" in rendered_rch + + # teardown + data["rch"]["rate"] = original_rch + + +@pytest.mark.usefixtures("imod5_dataset") +def test_non_planar_rch_from_imod5_transient(imod5_dataset, tmp_path): + data = deepcopy(imod5_dataset) + target_discretization = StructuredDiscretization.from_imod5_data(data) + # make the first layer of the target grid inactive + target_grid = target_discretization.dataset["idomain"] + target_grid.loc[{"layer": 1}] = 0 + + # the input for recharge is on the second layer of the targetgrid + input_recharge = nan_like(data["rch"]["rate"]) + input_recharge = input_recharge.assign_coords({"layer": [2]}) + input_recharge.loc[{"layer": 2}] = data["rch"]["rate"].sel(layer=1) + input_recharge = input_recharge.expand_dims({"time": [0, 1, 2]}) + + # update the data set + data["rch"]["rate"] = input_recharge + assert not is_planar_grid(data["rch"]["rate"]) + assert is_transient_data_grid(data["rch"]["rate"]) + + # act + rch = imod.mf6.Recharge.from_imod5_data(data, target_discretization) + + # assert + rendered_rch = rch.render(tmp_path, "rch", [0, 1, 2], None) + assert rendered_rch.count("begin period") == 3 + assert "maxbound 33856" in rendered_rch diff --git a/imod/tests/test_typing/test_typing_grid.py b/imod/tests/test_typing/test_typing_grid.py index 10a0bb953..cf16e0b4e 100644 --- a/imod/tests/test_typing/test_typing_grid.py +++ b/imod/tests/test_typing/test_typing_grid.py @@ -1,7 +1,12 @@ import xarray as xr import xugrid as xu -from imod.typing.grid import enforce_dim_order, preserve_gridtype +from imod.typing.grid import ( + enforce_dim_order, + is_planar_grid, + is_transient_data_grid, + preserve_gridtype, +) def test_preserve_gridtype__single_output(basic_unstructured_dis): @@ -64,3 +69,43 @@ def test_enforce_dim_order__unstructured(basic_unstructured_dis): assert actual.dims == ibound.dims assert isinstance(actual, type(ibound)) + + +def test_is_planar_grid(basic_dis, basic_unstructured_dis): + discretizations = [basic_dis, basic_unstructured_dis] + for discr in discretizations: + ibound, _, _ = discr + + # layer coordinates is present + assert not is_planar_grid(ibound) + + # set layer coordinates as present but empty + bottom_layer = ibound.sel(layer=3) + assert is_planar_grid(bottom_layer) + + # set layer coordinates as present and not empty or 0 + bottom_layer = bottom_layer.expand_dims({"layer": [9]}) + assert not is_planar_grid(bottom_layer) + + # set layer coordinates as present and 0 + bottom_layer.coords["layer"].values[0] = 0 + assert is_planar_grid(bottom_layer) + + +def test_is_transient_data_grid(basic_dis, basic_unstructured_dis): + discretizations = [basic_dis, basic_unstructured_dis] + + for discr in discretizations: + ibound, _, _ = discr + + # no time coordinate + assert not is_transient_data_grid(ibound) + + # time coordinate but with single value + ibound = ibound.expand_dims({"time": [1]}) + assert not is_transient_data_grid(ibound) + + # time coordinate but with several values + ibound, _, _ = discr + ibound = ibound.expand_dims({"time": [1, 2]}) + assert is_transient_data_grid(ibound) diff --git a/imod/typing/grid.py b/imod/typing/grid.py index 73c3452a7..69e2a0d51 100644 --- a/imod/typing/grid.py +++ b/imod/typing/grid.py @@ -398,3 +398,30 @@ def decorator(*args, **kwargs): return x return decorator + + +def is_planar_grid( + grid: xr.DataArray | xr.Dataset | xu.UgridDataArray | xu.UgridDataset, +) -> bool: + # Returns True if the grid is planar. It has then a layer coordinate with + # length 1 and value 0, or an empty layer coordinate axis, or no layer coordinate at all + # and it should have either x, y coordinates or cellface/edge coordinates. + if not is_spatial_2D(grid): + return False + if "layer" not in grid.coords: + return True + if grid["layer"].shape == (): + return True + if grid["layer"][0] == 0 and len(grid["layer"]) == 1: + return True + return False + + +def is_transient_data_grid( + grid: xr.DataArray | xr.Dataset | xu.UgridDataArray | xu.UgridDataset, +): + # Returns True if there is a time coordinate on the object with more than one value. + if "time" in grid.coords: + if len(grid["time"]) > 1: + return True + return False From b84b577991206c6c42dfd89287c3cafda36c589c Mon Sep 17 00:00:00 2001 From: luitjansl <64598682+luitjansl@users.noreply.github.com> Date: Fri, 24 May 2024 11:21:14 +0200 Subject: [PATCH 07/53] Issue #967 drn conversion (#1046) Fixes #967 # Description implements importing drainage packages from imod5 data. Adds tests. Methods for allocation and conductivity assignment can be specified per package, but it requires knowledge on what the packages are called in the imod5 project file (like "drn-1" and "drn-2"). If not specified, defaults are in place. # Checklist - [X] Links to correct issue - [ ] Update changelog, if changes affect users - [X] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [X] Unit tests were added - [ ] **If feature added**: Added/extended example --------- Co-authored-by: Joeri van Engelen --- imod/mf6/drn.py | 106 +++++++++++++++++++++++++++- imod/tests/test_mf6/test_mf6_drn.py | 29 ++++++++ 2 files changed, 134 insertions(+), 1 deletion(-) diff --git a/imod/mf6/drn.py b/imod/mf6/drn.py index 66a4d868e..0bb30fa0f 100644 --- a/imod/mf6/drn.py +++ b/imod/mf6/drn.py @@ -1,12 +1,24 @@ +from copy import deepcopy from typing import Optional, Tuple import numpy as np from imod.logging import init_log_decorator from imod.mf6.boundary_condition import BoundaryCondition +from imod.mf6.dis import StructuredDiscretization from imod.mf6.interfaces.iregridpackage import IRegridPackage -from imod.mf6.utilities.regrid import RegridderType +from imod.mf6.npf import NodePropertyFlow +from imod.mf6.utilities.regrid import ( + RegridderType, + RegridderWeightsCache, + _regrid_package_data, +) from imod.mf6.validation import BOUNDARY_DIMS_SCHEMA, CONC_DIMS_SCHEMA +from imod.prepare.topsystem.allocation import ALLOCATION_OPTION, allocate_drn_cells +from imod.prepare.topsystem.conductance import ( + DISTRIBUTING_OPTION, + distribute_drn_conductance, +) from imod.schemata import ( AllInsideNoDataSchema, AllNoDataSchema, @@ -18,6 +30,8 @@ IndexesSchema, OtherCoordsSchema, ) +from imod.typing import GridDataArray +from imod.typing.grid import enforce_dim_order, is_planar_grid class Drainage(BoundaryCondition, IRegridPackage): @@ -155,3 +169,93 @@ def _validate(self, schemata, **kwargs): def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: return self._regrid_method + + @classmethod + def from_imod5_data( + cls, + key: str, + imod5_data: dict[str, dict[str, GridDataArray]], + target_discretization: StructuredDiscretization, + target_npf: NodePropertyFlow, + allocation_option: ALLOCATION_OPTION, + distributing_option: DISTRIBUTING_OPTION, + regridder_types: dict[str, tuple[RegridderType, str]], + ) -> "Drainage": + """ + Construct a drainage-package from iMOD5 data, loaded with the + :func:`imod.formats.prj.open_projectfile_data` function. + + .. note:: + + The method expects the iMOD5 model to be fully 3D, not quasi-3D. + + Parameters + ---------- + imod5_data: dict + Dictionary with iMOD5 data. This can be constructed from the + :func:`imod.formats.prj.open_projectfile_data` method. + target_discretization: StructuredDiscretization package + The grid that should be used for the new package. Does not + need to be identical to one of the input grids. + target_npf: NodePropertyFlow package + The conductivity information, used to compute drainage flux + allocation_option: ALLOCATION_OPTION + allocation option. + distributing_option: dict[str, DISTRIBUTING_OPTION] + distributing option. + regridder_types: dict, optional + Optional dictionary with regridder types for a specific variable. + Use this to override default regridding methods. + + Returns + ------- + A list of Modflow 6 Drainage packages. + """ + + target_top = target_discretization.dataset["top"] + target_bottom = target_discretization.dataset["bottom"] + target_idomain = target_discretization.dataset["idomain"] + + data = { + "elevation": imod5_data[key]["elevation"], + "conductance": imod5_data[key]["conductance"], + } + is_planar = is_planar_grid(data["elevation"]) + + regridder_settings = deepcopy(cls._regrid_method) + if regridder_types is not None: + regridder_settings.update(regridder_types) + + regrid_context = RegridderWeightsCache() + + regridded_package_data = _regrid_package_data( + data, target_idomain, regridder_settings, regrid_context, {} + ) + + conductance = regridded_package_data["conductance"] + + if is_planar: + planar_elevation = regridded_package_data["elevation"] + + drn_allocation = allocate_drn_cells( + allocation_option, + target_idomain == 1, + target_top, + target_bottom, + planar_elevation, + ) + + layered_elevation = planar_elevation.where(drn_allocation) + layered_elevation = enforce_dim_order(layered_elevation) + regridded_package_data["elevation"] = layered_elevation + + regridded_package_data["conductance"] = distribute_drn_conductance( + distributing_option, + drn_allocation, + conductance, + target_top, + target_bottom, + target_npf.dataset["k"], + planar_elevation, + ) + return Drainage(**regridded_package_data) diff --git a/imod/tests/test_mf6/test_mf6_drn.py b/imod/tests/test_mf6/test_mf6_drn.py index 0887a4532..94ef64fa8 100644 --- a/imod/tests/test_mf6/test_mf6_drn.py +++ b/imod/tests/test_mf6/test_mf6_drn.py @@ -7,9 +7,14 @@ import xarray as xr import imod +import imod.mf6.drn from imod.logging import LoggerType, LogLevel +from imod.mf6.dis import StructuredDiscretization +from imod.mf6.npf import NodePropertyFlow from imod.mf6.utilities.package import get_repeat_stress from imod.mf6.write_context import WriteContext +from imod.prepare.topsystem.allocation import ALLOCATION_OPTION +from imod.prepare.topsystem.conductance import DISTRIBUTING_OPTION from imod.schemata import ValidationError @@ -465,3 +470,27 @@ def test_html_repr(drainage): html_string = imod.mf6.Drainage(**drainage)._repr_html_() assert isinstance(html_string, str) assert html_string.split("")[0] == "
Drainage" + + +@pytest.mark.usefixtures("imod5_dataset") +def test_from_imod5(imod5_dataset, tmp_path): + target_dis = StructuredDiscretization.from_imod5_data(imod5_dataset) + target_npf = NodePropertyFlow.from_imod5_data( + imod5_dataset, target_dis.dataset["idomain"] + ) + + drn_2 = imod.mf6.Drainage.from_imod5_data( + "drn-2", + imod5_dataset, + target_dis, + target_npf, + allocation_option=ALLOCATION_OPTION.at_elevation, + distributing_option=DISTRIBUTING_OPTION.by_crosscut_thickness, + regridder_types={}, + ) + + assert isinstance(drn_2, imod.mf6.Drainage) + + # write the packages for write validation + write_context = WriteContext(simulation_directory=tmp_path, use_binary=False) + drn_2.write("mydrn", [1], write_context) From 5a2da62690ced296d6247326d7305b355e57f91f Mon Sep 17 00:00:00 2001 From: luitjan Date: Wed, 29 May 2024 11:40:05 +0200 Subject: [PATCH 08/53] merged master into this branch --- docs/api/changelog.rst | 42 + docs/api/index.rst | 4 +- docs/api/mf6.rst | 27 + .../mf6/different_ways_to_regrid_models.py | 3 +- examples/user-guide/08-regridding.py | 7 +- imod/mf6/adv.py | 6 - imod/mf6/chd.py | 17 +- imod/mf6/cnc.py | 8 - imod/mf6/dis.py | 16 +- imod/mf6/disv.py | 14 +- imod/mf6/drn.py | 13 +- imod/mf6/dsp.py | 23 +- imod/mf6/evt.py | 31 +- imod/mf6/ghb.py | 17 +- imod/mf6/hfb.py | 8 +- imod/mf6/ic.py | 21 +- imod/mf6/interfaces/iregridpackage.py | 4 +- imod/mf6/mst.py | 20 +- imod/mf6/npf.py | 24 +- imod/mf6/oc.py | 7 +- imod/mf6/package.py | 38 +- imod/mf6/rch.py | 19 +- imod/mf6/regrid/__init__.py | 16 + imod/mf6/regrid/regrid_schemes.py | 468 ++++++ imod/mf6/riv.py | 16 +- imod/mf6/ssm.py | 8 - imod/mf6/sto.py | 31 +- imod/mf6/utilities/regrid.py | 58 +- imod/mf6/wel.py | 6 - ...6_regrid.py => test_mf6_regrid_package.py} | 0 imod/tests/test_mf6/test_mf6_regrid_scheme.py | 80 + .../test_mf6/test_mf6_regrid_simulation.py | 34 +- pixi.lock | 1369 ++++++++++------- pixi.toml | 1 + pyproject.toml | 2 + 35 files changed, 1533 insertions(+), 925 deletions(-) create mode 100644 imod/mf6/regrid/__init__.py create mode 100644 imod/mf6/regrid/regrid_schemes.py rename imod/tests/test_mf6/{test_mf6_regrid.py => test_mf6_regrid_package.py} (100%) create mode 100644 imod/tests/test_mf6/test_mf6_regrid_scheme.py diff --git a/docs/api/changelog.rst b/docs/api/changelog.rst index 129a8e815..597bed3aa 100644 --- a/docs/api/changelog.rst +++ b/docs/api/changelog.rst @@ -6,6 +6,48 @@ All notable changes to this project will be documented in this file. The format is based on `Keep a Changelog`_, and this project adheres to `Semantic Versioning`_. +[Unreleased] +------------ + +Added +~~~~~ +- Added objects with regrid settings. These can be used to provide custom + settings: :class:`imod.mf6.regrid.ConstantHeadRegridMethod`, + :class:`imod.mf6.regrid.DiscretizationRegridMethod`, + :class:`imod.mf6.regrid.DispersionRegridMethod`, + :class:`imod.mf6.regrid.DrainageRegridMethod`, + :class:`imod.mf6.regrid.EmptyRegridMethod`, + :class:`imod.mf6.regrid.EvapotranspirationRegridMethod`, + :class:`imod.mf6.regrid.GeneralHeadBoundaryRegridMethod`, + :class:`imod.mf6.regrid.InitialConditionsRegridMethod`, + :class:`imod.mf6.regrid.MobileStorageTransferRegridMethod`, + :class:`imod.mf6.regrid.NodePropertyFlowRegridMethod`, + :class:`imod.mf6.regrid.RechargeRegridMethod`, + :class:`imod.mf6.regrid.RiverRegridMethod`, + :class:`imod.mf6.regrid.SpecificStorageRegridMethod`, + :class:`imod.mf6.regrid.StorageCoefficientRegridMethod`. + +Changed +~~~~~~~ +- Instead of providing a dictionary with settings to ``Package.regrid_like``, + provide one of the following ``RegridMethod`` objects: + :class:`imod.mf6.regrid.ConstantHeadRegridMethod`, + :class:`imod.mf6.regrid.DiscretizationRegridMethod`, + :class:`imod.mf6.regrid.DispersionRegridMethod`, + :class:`imod.mf6.regrid.DrainageRegridMethod`, + :class:`imod.mf6.regrid.EmptyRegridMethod`, + :class:`imod.mf6.regrid.EvapotranspirationRegridMethod`, + :class:`imod.mf6.regrid.GeneralHeadBoundaryRegridMethod`, + :class:`imod.mf6.regrid.InitialConditionsRegridMethod`, + :class:`imod.mf6.regrid.MobileStorageTransferRegridMethod`, + :class:`imod.mf6.regrid.NodePropertyFlowRegridMethod`, + :class:`imod.mf6.regrid.RechargeRegridMethod`, + :class:`imod.mf6.regrid.RiverRegridMethod`, + :class:`imod.mf6.regrid.SpecificStorageRegridMethod`, + :class:`imod.mf6.regrid.StorageCoefficientRegridMethod`. + + + [0.17.1] - 2024-05-16 --------------------- diff --git a/docs/api/index.rst b/docs/api/index.rst index d3718a629..173c1453d 100644 --- a/docs/api/index.rst +++ b/docs/api/index.rst @@ -6,6 +6,8 @@ This page provides an auto-generated summary of imod's API. .. toctree:: :maxdepth: 2 + changelog + io prepare select @@ -19,5 +21,3 @@ This page provides an auto-generated summary of imod's API. flow msw metamod - - changelog diff --git a/docs/api/mf6.rst b/docs/api/mf6.rst index 1a8f6f599..bfa8b3017 100644 --- a/docs/api/mf6.rst +++ b/docs/api/mf6.rst @@ -101,3 +101,30 @@ Transport Packages MassSourceLoading SourceSinkMixing SourceSinkMixing.from_flow_model + + +.. currentmodule:: imod.mf6.regrid + +Regrid +====== + +Regrid Method Settings +---------------------- + +.. autosummary:: + :toctree: generated/mf6/regrid + + ConstantHeadRegridMethod + DiscretizationRegridMethod + DispersionRegridMethod + DrainageRegridMethod + EmptyRegridMethod + EvapotranspirationRegridMethod + GeneralHeadBoundaryRegridMethod + InitialConditionsRegridMethod + MobileStorageTransferRegridMethod + NodePropertyFlowRegridMethod + RechargeRegridMethod + RiverRegridMethod + SpecificStorageRegridMethod + StorageCoefficientRegridMethod \ No newline at end of file diff --git a/examples/mf6/different_ways_to_regrid_models.py b/examples/mf6/different_ways_to_regrid_models.py index 8be3b1f89..af0bbc774 100644 --- a/examples/mf6/different_ways_to_regrid_models.py +++ b/examples/mf6/different_ways_to_regrid_models.py @@ -25,6 +25,7 @@ import xarray as xr from example_models import create_twri_simulation +from imod.mf6.regrid import NodePropertyFlowRegridMethod from imod.mf6.utilities.regrid import RegridderType, RegridderWeightsCache # %% @@ -98,7 +99,7 @@ # a performance increase if that package uses the same regridding method, # because initializing a regridder is costly. -regridder_types = {"k": (RegridderType.CENTROIDLOCATOR, None)} +regridder_types = NodePropertyFlowRegridMethod(k=(RegridderType.CENTROIDLOCATOR,)) regrid_context = RegridderWeightsCache() npf_regridded = model["npf"].regrid_like( target_grid=target_grid, diff --git a/examples/user-guide/08-regridding.py b/examples/user-guide/08-regridding.py index 9e19455c8..178e6044f 100644 --- a/examples/user-guide/08-regridding.py +++ b/examples/user-guide/08-regridding.py @@ -199,9 +199,10 @@ # Regrid the recharge package with a custom regridder. In this case we opt # for the centroid locator regridder. This regridder is similar to using a # "nearest neighbour" lookup. +from imod.mf6.regrid import RechargeRegridMethod from imod.mf6.utilities.regrid import RegridderType -regridder_types = {"rate": (RegridderType.CENTROIDLOCATOR, None)} +regridder_types = RechargeRegridMethod(rate=(RegridderType.CENTROIDLOCATOR,)) regridded_recharge = original_rch_package.regrid_like( target_grid, @@ -412,6 +413,8 @@ def plot_histograms_side_by_side(array_original, array_regridded, title): # # This code snippet prints all default methods: # +from dataclasses import asdict + import pandas as pd from imod.tests.fixtures.package_instance_creation import ALL_PACKAGE_INSTANCES @@ -428,7 +431,7 @@ def plot_histograms_side_by_side(array_original, array_regridded, title): for pkg in ALL_PACKAGE_INSTANCES: if hasattr(pkg, "_regrid_method"): package_name = type(pkg).__name__ - regrid_methods = pkg._regrid_method + regrid_methods = asdict(pkg.get_regrid_methods()) for array_name in regrid_methods.keys(): method_name = regrid_methods[array_name][0].name function_name = "" diff --git a/imod/mf6/adv.py b/imod/mf6/adv.py index 187fe658a..c988c63ff 100644 --- a/imod/mf6/adv.py +++ b/imod/mf6/adv.py @@ -10,17 +10,14 @@ """ from copy import deepcopy -from typing import Optional, Tuple from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.package import Package -from imod.mf6.utilities.regrid import RegridderType class Advection(Package, IRegridPackage): _pkg_id = "adv" _template = Package._initialize_template(_pkg_id) - _regrid_method: dict[str, tuple[RegridderType, str]] = {} def __init__(self, scheme: str): dict_dataset = {"scheme": scheme} @@ -37,9 +34,6 @@ def mask(self, _) -> Package: """ return deepcopy(self) - def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: - return self._regrid_method - class AdvectionUpstream(Advection): """ diff --git a/imod/mf6/chd.py b/imod/mf6/chd.py index 36e4f2fa5..65e1bf3e0 100644 --- a/imod/mf6/chd.py +++ b/imod/mf6/chd.py @@ -1,11 +1,9 @@ -from typing import Optional, Tuple - import numpy as np from imod.logging import init_log_decorator from imod.mf6.boundary_condition import BoundaryCondition from imod.mf6.interfaces.iregridpackage import IRegridPackage -from imod.mf6.utilities.regrid import RegridderType +from imod.mf6.regrid.regrid_schemes import ConstantHeadRegridMethod from imod.mf6.validation import BOUNDARY_DIMS_SCHEMA, CONC_DIMS_SCHEMA from imod.schemata import ( AllInsideNoDataSchema, @@ -108,14 +106,7 @@ class ConstantHead(BoundaryCondition, IRegridPackage): _keyword_map = {} _auxiliary_data = {"concentration": "species"} _template = BoundaryCondition._initialize_template(_pkg_id) - - _regrid_method = { - "head": ( - RegridderType.OVERLAP, - "mean", - ), # TODO: should be set to barycentric once supported - "concentration": (RegridderType.OVERLAP, "mean"), - } + _regrid_method = ConstantHeadRegridMethod() @init_log_decorator() def __init__( @@ -141,6 +132,7 @@ def __init__( "repeat_stress": repeat_stress, } super().__init__(dict_dataset) + self._validate_init_schemata(validate) def _validate(self, schemata, **kwargs): @@ -149,6 +141,3 @@ def _validate(self, schemata, **kwargs): errors = super()._validate(schemata, **kwargs) return errors - - def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: - return self._regrid_method diff --git a/imod/mf6/cnc.py b/imod/mf6/cnc.py index d67c1b454..4a2ab64da 100644 --- a/imod/mf6/cnc.py +++ b/imod/mf6/cnc.py @@ -1,11 +1,8 @@ -from typing import Optional, Tuple - import numpy as np from imod.logging import init_log_decorator from imod.mf6.boundary_condition import BoundaryCondition from imod.mf6.interfaces.iregridpackage import IRegridPackage -from imod.mf6.utilities.regridding_types import RegridderType from imod.mf6.validation import BOUNDARY_DIMS_SCHEMA from imod.schemata import ( AllInsideNoDataSchema, @@ -53,8 +50,6 @@ class ConstantConcentration(BoundaryCondition, IRegridPackage): _period_data = ("concentration",) _template = BoundaryCondition._initialize_template(_pkg_id) - _regrid_method: dict[str, tuple[RegridderType, str]] = {} - _init_schemata = { "concentration": [ DTypeSchema(np.floating), @@ -91,6 +86,3 @@ def __init__( } super().__init__(dict_dataset) self._validate_init_schemata(validate) - - def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: - return self._regrid_method diff --git a/imod/mf6/dis.py b/imod/mf6/dis.py index 26d2458d0..f810731e7 100644 --- a/imod/mf6/dis.py +++ b/imod/mf6/dis.py @@ -1,6 +1,6 @@ import pathlib from copy import deepcopy -from typing import List, Optional, Tuple +from typing import List, Optional import numpy as np @@ -9,6 +9,7 @@ from imod.mf6.interfaces.imaskingsettings import IMaskingSettings from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.package import Package +from imod.mf6.regrid.regrid_schemes import DiscretizationRegridMethod from imod.mf6.utilities.grid import create_smallest_target_grid from imod.mf6.utilities.imod5_converter import convert_ibound_to_idomain from imod.mf6.utilities.regrid import ( @@ -95,15 +96,7 @@ class StructuredDiscretization(Package, IRegridPackage, IMaskingSettings): _grid_data = {"top": np.float64, "bottom": np.float64, "idomain": np.int32} _keyword_map = {"bottom": "botm"} _template = Package._initialize_template(_pkg_id) - - _regrid_method = { - "top": (RegridderType.OVERLAP, "mean"), - "bottom": (RegridderType.OVERLAP, "mean"), - "idomain": ( - RegridderType.OVERLAP, - "median", - ), # TODO: Change back to 'mode' when xugrid 0.9.1 released - } + _regrid_method = DiscretizationRegridMethod() @property def skip_variables(self) -> List[str]: @@ -165,9 +158,6 @@ def _validate(self, schemata, **kwargs): return errors - def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: - return self._regrid_method - @classmethod @standard_log_decorator() def from_imod5_data( diff --git a/imod/mf6/disv.py b/imod/mf6/disv.py index b35ee7a98..59d9e56c8 100644 --- a/imod/mf6/disv.py +++ b/imod/mf6/disv.py @@ -1,4 +1,4 @@ -from typing import List, Optional, Tuple +from typing import List import numpy as np import pandas as pd @@ -7,7 +7,7 @@ from imod.mf6.interfaces.imaskingsettings import IMaskingSettings from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.package import Package -from imod.mf6.utilities.regrid import RegridderType +from imod.mf6.regrid.regrid_schemes import DiscretizationRegridMethod from imod.mf6.validation import DisBottomSchema from imod.mf6.write_context import WriteContext from imod.schemata import ( @@ -67,12 +67,7 @@ class VerticesDiscretization(Package, IRegridPackage, IMaskingSettings): _grid_data = {"top": np.float64, "bottom": np.float64, "idomain": np.int32} _keyword_map = {"bottom": "botm"} _template = Package._initialize_template(_pkg_id) - - _regrid_method = { - "top": (RegridderType.OVERLAP, "mean"), - "bottom": (RegridderType.OVERLAP, "mean"), - "idomain": (RegridderType.OVERLAP, "mode"), - } + _regrid_method = DiscretizationRegridMethod() @property def skip_variables(self) -> List[str]: @@ -159,6 +154,3 @@ def _validate(self, schemata, **kwargs): errors = super()._validate(schemata, **kwargs) return errors - - def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: - return self._regrid_method diff --git a/imod/mf6/drn.py b/imod/mf6/drn.py index 0bb30fa0f..57dadbffd 100644 --- a/imod/mf6/drn.py +++ b/imod/mf6/drn.py @@ -1,5 +1,4 @@ from copy import deepcopy -from typing import Optional, Tuple import numpy as np @@ -8,6 +7,7 @@ from imod.mf6.dis import StructuredDiscretization from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.npf import NodePropertyFlow +from imod.mf6.regrid.regrid_schemes import DrainageRegridMethod from imod.mf6.utilities.regrid import ( RegridderType, RegridderWeightsCache, @@ -124,12 +124,7 @@ class Drainage(BoundaryCondition, IRegridPackage): _keyword_map = {} _template = BoundaryCondition._initialize_template(_pkg_id) _auxiliary_data = {"concentration": "species"} - - _regrid_method = { - "elevation": (RegridderType.OVERLAP, "mean"), - "conductance": (RegridderType.RELATIVEOVERLAP, "conductance"), - "concentration": (RegridderType.OVERLAP, "mean"), - } + _regrid_method = DrainageRegridMethod() @init_log_decorator() def __init__( @@ -157,7 +152,6 @@ def __init__( "repeat_stress": repeat_stress, } super().__init__(dict_dataset) - self._validate_init_schemata(validate) def _validate(self, schemata, **kwargs): @@ -167,9 +161,6 @@ def _validate(self, schemata, **kwargs): return errors - def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: - return self._regrid_method - @classmethod def from_imod5_data( cls, diff --git a/imod/mf6/dsp.py b/imod/mf6/dsp.py index 063169a76..0d9e2c37a 100644 --- a/imod/mf6/dsp.py +++ b/imod/mf6/dsp.py @@ -1,11 +1,9 @@ -from typing import Optional, Tuple - import numpy as np from imod.logging import init_log_decorator from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.package import Package -from imod.mf6.utilities.regrid import RegridderType +from imod.mf6.regrid.regrid_schemes import DispersionRegridMethod from imod.mf6.validation import PKG_DIMS_SCHEMA from imod.schemata import ( CompatibleSettingsSchema, @@ -147,21 +145,7 @@ class Dispersion(Package, IRegridPackage): IdentityNoDataSchema(other="idomain", is_other_notnull=(">", 0)), ), } - - _regrid_method = { - "diffusion_coefficient": (RegridderType.OVERLAP, "mean"), - "longitudinal_horizontal": (RegridderType.OVERLAP, "mean"), - "transversal_horizontal1": ( - RegridderType.OVERLAP, - "mean", - ), - "longitudinal_vertical": ( - RegridderType.OVERLAP, - "mean", - ), - "transversal_horizontal2": (RegridderType.OVERLAP, "mean"), - "transversal_vertical": (RegridderType.OVERLAP, "mean"), - } + _regrid_method = DispersionRegridMethod() @init_log_decorator() def __init__( @@ -195,6 +179,3 @@ def _validate(self, schemata, **kwargs): errors = super()._validate(schemata, **kwargs) return errors - - def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: - return self._regrid_method diff --git a/imod/mf6/evt.py b/imod/mf6/evt.py index e6af3351a..cdeede33a 100644 --- a/imod/mf6/evt.py +++ b/imod/mf6/evt.py @@ -1,11 +1,11 @@ -from typing import Optional, Tuple +from typing import Optional import numpy as np from imod.logging import init_log_decorator from imod.mf6.boundary_condition import BoundaryCondition from imod.mf6.interfaces.iregridpackage import IRegridPackage -from imod.mf6.utilities.regrid import RegridderType +from imod.mf6.regrid.regrid_schemes import EvapotranspirationRegridMethod from imod.mf6.validation import BOUNDARY_DIMS_SCHEMA, CONC_DIMS_SCHEMA from imod.schemata import ( AllInsideNoDataSchema, @@ -165,29 +165,7 @@ class Evapotranspiration(BoundaryCondition, IRegridPackage): _keyword_map = {} _template = BoundaryCondition._initialize_template(_pkg_id) _auxiliary_data = {"concentration": "species"} - - _regrid_method = { - "surface": ( - RegridderType.OVERLAP, - "mean", - ), - "rate": ( - RegridderType.OVERLAP, - "mean", - ), - "depth": ( - RegridderType.OVERLAP, - "mean", - ), - "proportion_rate": ( - RegridderType.OVERLAP, - "mean", - ), - "proportion_depth": ( - RegridderType.OVERLAP, - "mean", - ), - } + _regrid_method = EvapotranspirationRegridMethod() @init_log_decorator() def __init__( @@ -255,6 +233,3 @@ def _get_bin_ds(self): bin_ds = unstack_dim_into_variable(bin_ds, "segment") return bin_ds - - def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: - return self._regrid_method diff --git a/imod/mf6/ghb.py b/imod/mf6/ghb.py index d8f52b6f3..68d8930f7 100644 --- a/imod/mf6/ghb.py +++ b/imod/mf6/ghb.py @@ -1,11 +1,9 @@ -from typing import Optional, Tuple - import numpy as np from imod.logging import init_log_decorator from imod.mf6.boundary_condition import BoundaryCondition from imod.mf6.interfaces.iregridpackage import IRegridPackage -from imod.mf6.utilities.regrid import RegridderType +from imod.mf6.regrid.regrid_schemes import GeneralHeadBoundaryRegridMethod from imod.mf6.validation import BOUNDARY_DIMS_SCHEMA, CONC_DIMS_SCHEMA from imod.schemata import ( AllInsideNoDataSchema, @@ -113,15 +111,7 @@ class GeneralHeadBoundary(BoundaryCondition, IRegridPackage): _keyword_map = {} _template = BoundaryCondition._initialize_template(_pkg_id) _auxiliary_data = {"concentration": "species"} - - _regrid_method = { - "head": ( - RegridderType.OVERLAP, - "mean", - ), # TODO set to barycentric once supported - "conductance": (RegridderType.RELATIVEOVERLAP, "conductance"), - "concentration": (RegridderType.OVERLAP, "mean"), - } + _regrid_method = GeneralHeadBoundaryRegridMethod() @init_log_decorator() def __init__( @@ -157,6 +147,3 @@ def _validate(self, schemata, **kwargs): errors = super()._validate(schemata, **kwargs) return errors - - def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: - return self._regrid_method diff --git a/imod/mf6/hfb.py b/imod/mf6/hfb.py index 9bfb5243a..5163005fa 100644 --- a/imod/mf6/hfb.py +++ b/imod/mf6/hfb.py @@ -18,7 +18,6 @@ from imod.mf6.mf6_hfb_adapter import Mf6HorizontalFlowBarrier from imod.mf6.package import Package from imod.mf6.utilities.grid import broadcast_to_full_domain -from imod.mf6.utilities.regrid import RegridderType from imod.schemata import EmptyIndexesSchema from imod.typing import GridDataArray from imod.util.imports import MissingOptionalModule @@ -286,8 +285,6 @@ class HorizontalFlowBarrierBase(BoundaryCondition, ILineDataPackage): _init_schemata = {} _write_schemata = {"geometry": [EmptyIndexesSchema()]} - _regrid_method: dict[str, Tuple[RegridderType, str]] = {} - def __init__( self, geometry: "gpd.GeoDataFrame", @@ -295,12 +292,8 @@ def __init__( ) -> None: dict_dataset = {"print_input": print_input} super().__init__(dict_dataset) - self.line_data = geometry - def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: - return self._regrid_method - def _get_variable_names_for_gdf(self) -> list[str]: return [ self._get_variable_name(), @@ -589,6 +582,7 @@ def clip_box( cls = type(self) new = cls.__new__(cls) new.dataset = copy.deepcopy(self.dataset) + new.line_data = self.line_data return new def mask(self, _) -> Package: diff --git a/imod/mf6/ic.py b/imod/mf6/ic.py index 4547fde8c..aeb586b32 100644 --- a/imod/mf6/ic.py +++ b/imod/mf6/ic.py @@ -1,17 +1,15 @@ import warnings from copy import deepcopy -from typing import Optional, Tuple +from typing import Optional import numpy as np from imod.logging import init_log_decorator from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.package import Package -from imod.mf6.utilities.regrid import ( - RegridderType, - RegridderWeightsCache, - _regrid_package_data, -) +from imod.mf6.regrid.regrid_schemes import InitialConditionsRegridMethod +from imod.mf6.utilities.regrid import RegridderWeightsCache, _regrid_package_data +from imod.mf6.utilities.regridding_types import RegridderType from imod.mf6.validation import PKG_DIMS_SCHEMA from imod.schemata import DTypeSchema, IdentityNoDataSchema, IndexesSchema from imod.typing import GridDataArray @@ -67,13 +65,7 @@ class InitialConditions(Package, IRegridPackage): _grid_data = {"start": np.float64} _keyword_map = {"start": "strt"} _template = Package._initialize_template(_pkg_id) - - _regrid_method = { - "start": ( - RegridderType.OVERLAP, - "mean", - ), # TODO set to barycentric once supported - } + _regrid_method = InitialConditionsRegridMethod() @init_log_decorator() def __init__(self, start=None, head=None, validate: bool = True): @@ -102,9 +94,6 @@ def render(self, directory, pkgname, globaltimes, binary): ) return self._template.render(d) - def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: - return self._regrid_method - @classmethod def from_imod5_data( cls, diff --git a/imod/mf6/interfaces/iregridpackage.py b/imod/mf6/interfaces/iregridpackage.py index af6ece0ee..c05e4bb4a 100644 --- a/imod/mf6/interfaces/iregridpackage.py +++ b/imod/mf6/interfaces/iregridpackage.py @@ -2,7 +2,7 @@ from typing import Optional from imod.mf6.interfaces.ipackage import IPackage -from imod.mf6.utilities.regridding_types import RegridderType +from imod.mf6.regrid.regrid_schemes import RegridMethodType class IRegridPackage(IPackage, abc.ABC): @@ -11,5 +11,5 @@ class IRegridPackage(IPackage, abc.ABC): """ @abc.abstractmethod - def get_regrid_methods(self) -> Optional[dict[str, tuple[RegridderType, str]]]: + def get_regrid_methods(self) -> Optional[RegridMethodType]: raise NotImplementedError diff --git a/imod/mf6/mst.py b/imod/mf6/mst.py index 9057c4973..e4a825bdf 100644 --- a/imod/mf6/mst.py +++ b/imod/mf6/mst.py @@ -1,11 +1,9 @@ -from typing import Optional, Tuple - import numpy as np from imod.logging import init_log_decorator from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.package import Package -from imod.mf6.utilities.regrid import RegridderType +from imod.mf6.regrid.regrid_schemes import MobileStorageTransferRegridMethod from imod.mf6.validation import PKG_DIMS_SCHEMA from imod.schemata import ( AllValueSchema, @@ -99,18 +97,7 @@ class MobileStorageTransfer(Package, IRegridPackage): "distcoef": (IdentityNoDataSchema(other="idomain", is_other_notnull=(">", 0)),), "sp2": (IdentityNoDataSchema(other="idomain", is_other_notnull=(">", 0)),), } - - _regrid_method = { - "porosity": (RegridderType.OVERLAP, "mean"), - "decay": (RegridderType.OVERLAP, "mean"), - "decay_sorbed": ( - RegridderType.OVERLAP, - "mean", - ), - "bulk_density": (RegridderType.OVERLAP, "mean"), - "distcoef": (RegridderType.OVERLAP, "mean"), - "sp2": (RegridderType.OVERLAP, "mean"), - } + _regrid_method = MobileStorageTransferRegridMethod() @init_log_decorator() def __init__( @@ -145,6 +132,3 @@ def __init__( } super().__init__(dict_dataset) self._validate_init_schemata(validate) - - def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: - return self._regrid_method diff --git a/imod/mf6/npf.py b/imod/mf6/npf.py index 41757bbc2..a76e7fb19 100644 --- a/imod/mf6/npf.py +++ b/imod/mf6/npf.py @@ -1,6 +1,6 @@ import warnings from copy import deepcopy -from typing import Optional, Tuple +from typing import Optional import numpy as np import xarray as xr @@ -8,6 +8,7 @@ from imod.logging import init_log_decorator from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.package import Package +from imod.mf6.regrid.regrid_schemes import NodePropertyFlowRegridMethod from imod.mf6.utilities.imod5_converter import fill_missing_layers from imod.mf6.utilities.regrid import ( RegridderType, @@ -345,23 +346,7 @@ class NodePropertyFlow(Package, IRegridPackage): "rhs_option": "rhs", } _template = Package._initialize_template(_pkg_id) - - _regrid_method = { - "icelltype": (RegridderType.OVERLAP, "mean"), - "k": (RegridderType.OVERLAP, "geometric_mean"), # horizontal if angle2 = 0 - "k22": ( - RegridderType.OVERLAP, - "geometric_mean", - ), # horizontal if angle2 = 0 & angle3 = 0 - "k33": ( - RegridderType.OVERLAP, - "harmonic_mean", - ), # vertical if angle2 = 0 & angle3 = 0 - "angle1": (RegridderType.OVERLAP, "mean"), - "angle2": (RegridderType.OVERLAP, "mean"), - "angle3": (RegridderType.OVERLAP, "mean"), - "rewet_layer": (RegridderType.OVERLAP, "mean"), - } + _regrid_method = NodePropertyFlowRegridMethod() @init_log_decorator() def __init__( @@ -467,9 +452,6 @@ def _validate(self, schemata, **kwargs): return errors - def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: - return self._regrid_method - @classmethod def from_imod5_data( cls, diff --git a/imod/mf6/oc.py b/imod/mf6/oc.py index 21f84e16b..a01095168 100644 --- a/imod/mf6/oc.py +++ b/imod/mf6/oc.py @@ -1,7 +1,7 @@ import collections import os from pathlib import Path -from typing import Optional, Tuple, Union +from typing import Union import numpy as np @@ -9,7 +9,6 @@ from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.package import Package from imod.mf6.utilities.dataset import is_dataarray_none -from imod.mf6.utilities.regrid import RegridderType from imod.mf6.write_context import WriteContext from imod.schemata import DTypeSchema @@ -82,7 +81,6 @@ class OutputControl(Package, IRegridPackage): } _write_schemata = {} - _regrid_method: dict[str, Tuple[RegridderType, str]] = {} @init_log_decorator() def __init__( @@ -209,6 +207,3 @@ def write( @property def is_budget_output(self) -> bool: return self.dataset["save_budget"].values[()] is not None - - def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: - return self._regrid_method diff --git a/imod/mf6/package.py b/imod/mf6/package.py index 3b694b758..d6d09c759 100644 --- a/imod/mf6/package.py +++ b/imod/mf6/package.py @@ -3,6 +3,7 @@ import abc import pathlib from collections import defaultdict +from copy import deepcopy from typing import Any, Mapping, Optional, Tuple, Union import cftime @@ -22,10 +23,10 @@ TRANSPORT_PACKAGES, PackageBase, ) +from imod.mf6.regrid.regrid_schemes import EmptyRegridMethod, RegridMethodType from imod.mf6.utilities.mask import mask_package from imod.mf6.utilities.package import _is_valid from imod.mf6.utilities.regrid import ( - RegridderType, RegridderWeightsCache, _regrid_like, ) @@ -58,6 +59,7 @@ class Package(PackageBase, IPackage, abc.ABC): _init_schemata: dict[str, list[SchemaType] | Tuple[SchemaType, ...]] = {} _write_schemata: dict[str, list[SchemaType] | Tuple[SchemaType, ...]] = {} _keyword_map: dict[str, str] = {} + _regrid_method: RegridMethodType = EmptyRegridMethod() def __init__(self, allargs: Mapping[str, GridDataArray | float | int | bool | str]): super().__init__(allargs) @@ -540,35 +542,38 @@ def regrid_like( self, target_grid: GridDataArray, regrid_context: RegridderWeightsCache, - regridder_types: Optional[dict[str, Tuple[RegridderType, str]]] = None, + regridder_types: Optional[RegridMethodType] = None, ) -> "Package": """ - Creates a package of the same type as this package, based on another discretization. - It regrids all the arrays in this package to the desired discretization, and leaves the options - unmodified. At the moment only regridding to a different planar grid is supported, meaning - ``target_grid`` has different ``"x"`` and ``"y"`` or different ``cell2d`` coords. + Creates a package of the same type as this package, based on another + discretization. It regrids all the arrays in this package to the desired + discretization, and leaves the options unmodified. At the moment only + regridding to a different planar grid is supported, meaning + ``target_grid`` has different ``"x"`` and ``"y"`` or different + ``cell2d`` coords. - The regridding methods can be specified in the _regrid_method attribute of the package. These are the defaults - that specify how each array should be regridded. These defaults can be overridden using the input - parameters of this function. + The default regridding methods are specified in the ``_regrid_method`` + attribute of the package. These defaults can be overridden using the + input parameters of this function. Examples -------- To regrid the npf package with a non-default method for the k-field, call regrid_like with these arguments: - >>> new_npf = npf.regrid_like(like, {"k": (imod.RegridderType.OVERLAP, "mean")}) + >>> regridder_types = imod.mf6.regrid.NodePropertyFlowRegridMethod(k=(imod.RegridderType.OVERLAP, "mean")) + >>> new_npf = npf.regrid_like(like, RegridderWeightsCache, regridder_types) Parameters ---------- target_grid: xr.DataArray or xu.UgridDataArray - a grid defined over the same discretization as the one we want to regrid the package to - regridder_types: dict(str->(regridder type,str)) - dictionary mapping arraynames (str) to a tuple of regrid type (a specialization class of BaseRegridder) and function name (str) - this dictionary can be used to override the default mapping method. - regrid_context: Optional RegridderWeightsCache + a grid defined over the same discretization as the one we want to regrid the package to. + regrid_context: RegridderWeightsCache, optional stores regridder weights for different regridders. Can be used to speed up regridding, if the same regridders are used several times for regridding different arrays. + regridder_types: RegridMethodType, optional + dictionary mapping arraynames (str) to a tuple of regrid type (a specialization class of BaseRegridder) and function name (str) + this dictionary can be used to override the default mapping method. Returns ------- @@ -631,3 +636,6 @@ def is_regridding_supported(self) -> bool: def is_clipping_supported(self) -> bool: return True + + def get_regrid_methods(self) -> RegridMethodType: + return deepcopy(self._regrid_method) diff --git a/imod/mf6/rch.py b/imod/mf6/rch.py index c78beafe2..b8ec1a5af 100644 --- a/imod/mf6/rch.py +++ b/imod/mf6/rch.py @@ -1,5 +1,5 @@ from copy import deepcopy -from typing import Optional, Tuple +from typing import Optional import numpy as np @@ -7,11 +7,9 @@ from imod.mf6.boundary_condition import BoundaryCondition from imod.mf6.dis import StructuredDiscretization from imod.mf6.interfaces.iregridpackage import IRegridPackage -from imod.mf6.utilities.regrid import ( - RegridderType, - RegridderWeightsCache, - _regrid_package_data, -) +from imod.mf6.regrid.regrid_schemes import RechargeRegridMethod +from imod.mf6.utilities.regrid import RegridderWeightsCache, _regrid_package_data +from imod.mf6.utilities.regridding_types import RegridderType from imod.mf6.validation import BOUNDARY_DIMS_SCHEMA, CONC_DIMS_SCHEMA from imod.prepare.topsystem.allocation import ALLOCATION_OPTION, allocate_rch_cells from imod.schemata import ( @@ -121,11 +119,7 @@ class Recharge(BoundaryCondition, IRegridPackage): _template = BoundaryCondition._initialize_template(_pkg_id) _auxiliary_data = {"concentration": "species"} - - _regrid_method = { - "rate": (RegridderType.OVERLAP, "mean"), - "concentration": (RegridderType.OVERLAP, "mean"), - } + _regrid_method = RechargeRegridMethod() @init_log_decorator() def __init__( @@ -162,9 +156,6 @@ def _validate(self, schemata, **kwargs): return errors - def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: - return self._regrid_method - @classmethod def from_imod5_data( cls, diff --git a/imod/mf6/regrid/__init__.py b/imod/mf6/regrid/__init__.py new file mode 100644 index 000000000..9e8d7775c --- /dev/null +++ b/imod/mf6/regrid/__init__.py @@ -0,0 +1,16 @@ +from imod.mf6.regrid.regrid_schemes import ( + ConstantHeadRegridMethod, + DiscretizationRegridMethod, + DispersionRegridMethod, + DrainageRegridMethod, + EmptyRegridMethod, + EvapotranspirationRegridMethod, + GeneralHeadBoundaryRegridMethod, + InitialConditionsRegridMethod, + MobileStorageTransferRegridMethod, + NodePropertyFlowRegridMethod, + RechargeRegridMethod, + RiverRegridMethod, + SpecificStorageRegridMethod, + StorageCoefficientRegridMethod, +) diff --git a/imod/mf6/regrid/regrid_schemes.py b/imod/mf6/regrid/regrid_schemes.py new file mode 100644 index 000000000..7d6c6e69f --- /dev/null +++ b/imod/mf6/regrid/regrid_schemes.py @@ -0,0 +1,468 @@ +from typing import ClassVar, Protocol, Tuple, TypeAlias + +from pydantic import ConfigDict +from pydantic.dataclasses import dataclass + +from imod.mf6.utilities.regridding_types import RegridderType + +_RegridVarType: TypeAlias = Tuple[RegridderType, str] | Tuple[RegridderType] +_CONFIG = ConfigDict(extra="forbid") + + +class RegridMethodType(Protocol): + # Work around that type annotation is a bit hard on dataclasses, as they + # don't expose a class interface. + # Adapted from: https://stackoverflow.com/a/55240861 + # "As already noted in comments, checking for this attribute is currently the + # most reliable way to ascertain that something is a dataclass" + # See also: + # https://github.com/python/mypy/issues/6568#issuecomment-1324196557 + + __dataclass_fields__: ClassVar[dict] + + +@dataclass(config=_CONFIG) +class ConstantHeadRegridMethod(RegridMethodType): + """ + Object containing regridder methods for the :class:`imod.mf6.ConstantHead` + package. This can be provided to the ``regrid_like`` method to regrid with + custom settings. + + Parameters + ---------- + head: tuple, default (RegridderType.OVERLAP, "mean") + concentration: tuple, default (RegridderType.OVERLAP, "mean") + + Examples + -------- + Regrid with custom settings: + + >>> regrid_method = ConstantHeadRegridMethod(head=(RegridderType.BARYCENTRIC,)) + >>> chd.regrid_like(target_grid, RegridderWeightsCache(), regrid_method) + + The RegridderType.OVERLAP and RegridderType.RELATIVEOVERLAP require an extra + method as string. + + >>> regrid_method = ConstantHeadRegridMethod(head=(RegridderType.OVERLAP, "max",)) + """ + + head: _RegridVarType = ( + RegridderType.OVERLAP, + "mean", + ) # TODO: should be set to barycentric once supported + concentration: _RegridVarType = (RegridderType.OVERLAP, "mean") + + +@dataclass(config=_CONFIG) +class DiscretizationRegridMethod(RegridMethodType): + """ + Object containing regridder methods for the + :class:`imod.mf6.StructuredDiscretization` and + :class:`imod.mf6.VerticesDiscretization` packages. This can be provided to + the ``regrid_like`` method to regrid with custom settings. + + Parameters + ---------- + top: tuple, default (RegridderType.OVERLAP, "mean") + bottom: tuple, default (RegridderType.OVERLAP, "mean") + idomain: tuple, default (RegridderType.OVERLAP, "mode") + + Examples + -------- + Regrid with custom settings: + + >>> regrid_method = DiscretizationRegridMethod(top=(RegridderType.BARYCENTRIC,)) + >>> dis.regrid_like(target_grid, RegridderWeightsCache(), regrid_method) + + The RegridderType.OVERLAP and RegridderType.RELATIVEOVERLAP require an extra + method as string. + + >>> regrid_method = DiscretizationRegridMethod(top=(RegridderType.OVERLAP, "max",)) + """ + + top: _RegridVarType = (RegridderType.OVERLAP, "mean") + bottom: _RegridVarType = (RegridderType.OVERLAP, "mean") + idomain: _RegridVarType = (RegridderType.OVERLAP, "mode") + + +@dataclass(config=_CONFIG) +class DispersionRegridMethod(RegridMethodType): + """ + Object containing regridder methods for the :class:`imod.mf6.Dispersion` + package. This can be provided to the ``regrid_like`` method to regrid with + custom settings. + + Parameters + ---------- + diffusion_coefficient: tuple, default (RegridderType.OVERLAP, "mean") + longitudinal_horizontal: tuple, default (RegridderType.OVERLAP, "mean") + transversal_horizontal: tuple, default (RegridderType.OVERLAP, "mean") + longitudinal_vertical: tuple, default (RegridderType.OVERLAP, "mean") + transversal_horizontal2: tuple, default (RegridderType.OVERLAP, "mean") + transversal_vertical: tuple, default (RegridderType.OVERLAP, "mean") + + Examples + -------- + Regrid with custom settings: + + >>> regrid_method = DispersionRegridMethod(longitudinal_horizontal=(RegridderType.BARYCENTRIC,)) + >>> dsp.regrid_like(target_grid, RegridderWeightsCache(), regrid_method) + + The RegridderType.OVERLAP and RegridderType.RELATIVEOVERLAP require an extra + method as string. + + >>> regrid_method = DispersionRegridMethod(longitudinal_horizontal=(RegridderType.OVERLAP, "max",)) + """ + + diffusion_coefficient: _RegridVarType = (RegridderType.OVERLAP, "mean") + longitudinal_horizontal: _RegridVarType = (RegridderType.OVERLAP, "mean") + transversal_horizontal1: _RegridVarType = (RegridderType.OVERLAP, "mean") + longitudinal_vertical: _RegridVarType = (RegridderType.OVERLAP, "mean") + transversal_horizontal2: _RegridVarType = (RegridderType.OVERLAP, "mean") + transversal_vertical: _RegridVarType = (RegridderType.OVERLAP, "mean") + + +@dataclass(config=_CONFIG) +class DrainageRegridMethod(RegridMethodType): + """ + Object containing regridder methods for the :class:`imod.mf6.Drainage` + package. This can be provided to the ``regrid_like`` method to regrid with + custom settings. + + Parameters + ---------- + elevation: tuple, default (RegridderType.OVERLAP, "mean") + conductance: tuple, default (RegridderType.RELATIVEOVERLAP,"conductance") + concentration: tuple, default (RegridderType.OVERLAP, "mean") + + Examples + -------- + Regrid with custom settings: + + >>> regrid_method = DrainageRegridMethod(elevation=(RegridderType.BARYCENTRIC,)) + >>> drn.regrid_like(target_grid, RegridderWeightsCache(), regrid_method) + + The RegridderType.OVERLAP and RegridderType.RELATIVEOVERLAP require an extra + method as string. + + >>> regrid_method = DrainageRegridMethod(elevation=(RegridderType.OVERLAP, "max",)) + """ + + elevation: _RegridVarType = (RegridderType.OVERLAP, "mean") + conductance: _RegridVarType = (RegridderType.RELATIVEOVERLAP, "conductance") + concentration: _RegridVarType = (RegridderType.OVERLAP, "mean") + + +@dataclass(config=_CONFIG) +class EmptyRegridMethod(RegridMethodType): + pass + + +@dataclass(config=_CONFIG) +class EvapotranspirationRegridMethod(RegridMethodType): + """ + Object containing regridder methods for the + :class:`imod.mf6.Evapotranspiration` package. This can be provided to the + ``regrid_like`` method to regrid with custom settings. + + Parameters + ---------- + surface: tuple, default (RegridderType.OVERLAP, "mean") + rate: tuple, default (RegridderType.OVERLAP, "mean") + depth: tuple, default (RegridderType.OVERLAP, "mean") + proportion_rate: tuple, default (RegridderType.OVERLAP, "mean") + proportion_depth: tuple, default (RegridderType.OVERLAP, "mean") + + Examples + -------- + Regrid with custom settings: + + >>> regrid_method = EvapotranspirationRegridMethod(surface=(RegridderType.BARYCENTRIC,)) + >>> evt.regrid_like(target_grid, RegridderWeightsCache(), regrid_method) + + The RegridderType.OVERLAP and RegridderType.RELATIVEOVERLAP require an extra + method as string. + + >>> regrid_method = EvapotranspirationRegridMethod(surface=(RegridderType.OVERLAP, "max",)) + """ + + surface: _RegridVarType = (RegridderType.OVERLAP, "mean") + rate: _RegridVarType = (RegridderType.OVERLAP, "mean") + depth: _RegridVarType = (RegridderType.OVERLAP, "mean") + proportion_rate: _RegridVarType = (RegridderType.OVERLAP, "mean") + proportion_depth: _RegridVarType = (RegridderType.OVERLAP, "mean") + + +@dataclass(config=_CONFIG) +class GeneralHeadBoundaryRegridMethod(RegridMethodType): + """ + Object containing regridder methods for the + :class:`imod.mf6.GeneralHeadBoundary` package. This can be provided to the + ``regrid_like`` method to regrid with custom settings. + + Parameters + ---------- + head: tuple, default (RegridderType.OVERLAP, "mean") + conductance: tuple, default (RegridderType.RELATIVEOVERLAP,"conductance") + concentration: tuple, default (RegridderType.OVERLAP, "mean") + + Examples + -------- + Regrid with custom settings: + + >>> regrid_method = GeneralHeadBoundaryRegridMethod(head=(RegridderType.BARYCENTRIC,)) + >>> ghb.regrid_like(target_grid, RegridderWeightsCache(), regrid_method) + + The RegridderType.OVERLAP and RegridderType.RELATIVEOVERLAP require an extra + method as string. + + >>> regrid_method = GeneralHeadBoundaryRegridMethod(head=(RegridderType.OVERLAP, "max",)) + """ + + head: _RegridVarType = ( + RegridderType.OVERLAP, + "mean", + ) # TODO set to barycentric once supported + conductance: _RegridVarType = (RegridderType.RELATIVEOVERLAP, "conductance") + concentration: _RegridVarType = (RegridderType.OVERLAP, "mean") + + +@dataclass(config=_CONFIG) +class InitialConditionsRegridMethod(RegridMethodType): + """ + Object containing regridder methods for the + :class:`imod.mf6.InitialConditions` package. This can be provided to the + ``regrid_like`` method to regrid with custom settings. + + Parameters + ---------- + start: tuple, default (RegridderType.OVERLAP, "mean") + + Examples + -------- + Regrid with custom settings: + + >>> regrid_method = InitialConditionsRegridMethod(start=(RegridderType.BARYCENTRIC,)) + >>> ic.regrid_like(target_grid, RegridderWeightsCache(), regrid_method) + + The RegridderType.OVERLAP and RegridderType.RELATIVEOVERLAP require an extra + method as string. + + >>> regrid_method = InitialConditionsRegridMethod(start=(RegridderType.OVERLAP, "max",)) + """ + + start: _RegridVarType = ( + RegridderType.OVERLAP, + "mean", + ) # TODO set to barycentric once supported + + +@dataclass(config=_CONFIG) +class MobileStorageTransferRegridMethod(RegridMethodType): + """ + Object containing regridder methods for the + :class:`imod.mf6.MobileStorageTransfer` package. This can be provided to the + ``regrid_like`` method to regrid with custom settings. + + Parameters + ---------- + porosity: tuple, default (RegridderType.OVERLAP, "mean") + decay: tuple, default (RegridderType.OVERLAP, "mean") + decay_sorbed: tuple, default (RegridderType.OVERLAP, "mean") + bulk_density: tuple, default (RegridderType.OVERLAP, "mean") + distcoef: tuple, default (RegridderType.OVERLAP, "mean") + sp2: tuple, default (RegridderType.OVERLAP, "mean") + + Examples + -------- + Regrid with custom settings: + + >>> regrid_method = MobileStorageTransferRegridMethod(porosity=(RegridderType.BARYCENTRIC,)) + >>> mst.regrid_like(target_grid, RegridderWeightsCache(), regrid_method) + + The RegridderType.OVERLAP and RegridderType.RELATIVEOVERLAP require an extra + method as string. + + >>> regrid_method = MobileStorageTransferRegridMethod(porosity=(RegridderType.OVERLAP, "max",)) + """ + + porosity: _RegridVarType = (RegridderType.OVERLAP, "mean") + decay: _RegridVarType = (RegridderType.OVERLAP, "mean") + decay_sorbed: _RegridVarType = (RegridderType.OVERLAP, "mean") + bulk_density: _RegridVarType = (RegridderType.OVERLAP, "mean") + distcoef: _RegridVarType = (RegridderType.OVERLAP, "mean") + sp2: _RegridVarType = (RegridderType.OVERLAP, "mean") + + +@dataclass(config=_CONFIG) +class NodePropertyFlowRegridMethod(RegridMethodType): + """ + Object containing regridder methods for the + :class:`imod.mf6.NodePropertyFlow` package. This can be provided to the + ``regrid_like`` method to regrid with custom settings. + + Parameters + ---------- + icelltype: tuple, defaults (RegridderType.OVERLAP, "mean") + k: tuple, defaults ( RegridderType.OVERLAP,"geometric_mean") + k22: tuple, defaults (RegridderType.OVERLAP,"geometric_mean") + k33: tuple, defaults (RegridderType.OVERLAP,"harmonic_mean") + angle1: tuple, defaults (RegridderType.OVERLAP, "mean") + angle2: tuple, defaults (RegridderType.OVERLAP, "mean") + angle3: tuple, defaults (RegridderType.OVERLAP, "mean") + rewet_layer: tuple, defaults (RegridderType.OVERLAP, "mean") + + Examples + -------- + Regrid with custom settings: + + >>> regrid_method = NodePropertyFlowRegridMethod(k=(RegridderType.BARYCENTRIC,)) + >>> npf.regrid_like(target_grid, RegridderWeightsCache(), regrid_method) + + The RegridderType.OVERLAP and RegridderType.RELATIVEOVERLAP require an extra + method as string. + + >>> regrid_method = NodePropertyFlowRegridMethod(k=(RegridderType.OVERLAP, "max",)) + """ + + icelltype: _RegridVarType = (RegridderType.OVERLAP, "mode") + k: _RegridVarType = ( + RegridderType.OVERLAP, + "geometric_mean", + ) # horizontal if angle2 = 0 + k22: _RegridVarType = ( + RegridderType.OVERLAP, + "geometric_mean", + ) # horizontal if angle2 = 0 & angle3 = 0 + k33: _RegridVarType = ( + RegridderType.OVERLAP, + "harmonic_mean", + ) # vertical if angle2 = 0 & angle3 = 0 + angle1: _RegridVarType = (RegridderType.OVERLAP, "mean") + angle2: _RegridVarType = (RegridderType.OVERLAP, "mean") + angle3: _RegridVarType = (RegridderType.OVERLAP, "mean") + rewet_layer: _RegridVarType = (RegridderType.OVERLAP, "mean") + + +@dataclass(config=_CONFIG) +class RechargeRegridMethod(RegridMethodType): + """ + Object containing regridder methods for the :class:`imod.mf6.Recharge` + package. This can be provided to the ``regrid_like`` method to regrid with + custom settings. + + Parameters + ---------- + rate: tuple, defaults (RegridderType.OVERLAP, "mean") + concentration: tuple, defaults (RegridderType.OVERLAP, "mean") + + Examples + -------- + Regrid with custom settings: + + >>> regrid_method = RechargeRegridMethod(rate=(RegridderType.BARYCENTRIC,)) + >>> rch.regrid_like(target_grid, RegridderWeightsCache(), regrid_method) + + The RegridderType.OVERLAP and RegridderType.RELATIVEOVERLAP require an extra + method as string. + + >>> regrid_method = RechargeRegridMethod(rate=(RegridderType.OVERLAP, "max",)) + """ + + rate: _RegridVarType = (RegridderType.OVERLAP, "mean") + concentration: _RegridVarType = (RegridderType.OVERLAP, "mean") + + +@dataclass(config=_CONFIG) +class RiverRegridMethod(RegridMethodType): + """ + Object containing regridder methods for the :class:`imod.mf6.River` package. + This can be provided to the ``regrid_like`` method to regrid with custom + settings. + + Parameters + ---------- + stage: tuple, default (RegridderType.OVERLAP, "mean") + conductance: tuple, default (RegridderType.RELATIVEOVERLAP, "conductance") + bottom_elevation: tuple, default (RegridderType.OVERLAP, "mean") + concentration: tuple, default (RegridderType.OVERLAP, "mean") + + Examples + -------- + Regrid with custom settings: + + >>> regrid_method = RiverRegridMethod(stage=(RegridderType.BARYCENTRIC,)) + >>> riv.regrid_like(target_grid, RegridderWeightsCache(), regrid_method) + + The RegridderType.OVERLAP and RegridderType.RELATIVEOVERLAP require an extra + method as string. + + >>> regrid_method = RiverRegridMethod(stage=(RegridderType.OVERLAP, "max",)) + """ + + stage: _RegridVarType = (RegridderType.OVERLAP, "mean") + conductance: _RegridVarType = (RegridderType.RELATIVEOVERLAP, "conductance") + bottom_elevation: _RegridVarType = (RegridderType.OVERLAP, "mean") + concentration: _RegridVarType = (RegridderType.OVERLAP, "mean") + + +@dataclass(config=_CONFIG) +class SpecificStorageRegridMethod(RegridMethodType): + """ + Object containing regridder methods for the + :class:`imod.mf6.SpecificStorage` package. This can be provided to the + ``regrid_like`` method to regrid with custom settings. + + Parameters + ---------- + convertible: tuple, default (RegridderType.OVERLAP, "mode") + specific_storage: tuple, default (RegridderType.OVERLAP, "mean") + specific_yield: tuple, default (RegridderType.OVERLAP, "mean") + + Examples + -------- + Regrid with custom settings: + + >>> regrid_method = SpecificStorageRegridMethod(specific_storage=(RegridderType.BARYCENTRIC,)) + >>> sto.regrid_like(target_grid, RegridderWeightsCache(), regrid_method) + + The RegridderType.OVERLAP and RegridderType.RELATIVEOVERLAP require an extra + method as string. + + >>> regrid_method = SpecificStorageRegridMethod(specific_storage=(RegridderType.OVERLAP, "max",)) + """ + + convertible: _RegridVarType = (RegridderType.OVERLAP, "mode") + specific_storage: _RegridVarType = (RegridderType.OVERLAP, "mean") + specific_yield: _RegridVarType = (RegridderType.OVERLAP, "mean") + + +@dataclass(config=_CONFIG) +class StorageCoefficientRegridMethod(RegridMethodType): + """ + Object containing regridder methods for the + :class:`imod.mf6.StorageCoefficient` package. This can be provided to the + ``regrid_like`` method to regrid with custom settings. + + Parameters + ---------- + convertible: tuple, default (RegridderType.OVERLAP, "mode") + storage_coefficient: tuple, default (RegridderType.OVERLAP, "mean") + specific_yield: tuple, default (RegridderType.OVERLAP, "mean") + + Examples + -------- + Regrid with custom settings: + + >>> regrid_method = StorageCoefficientRegridMethod(storage_coefficient=(RegridderType.BARYCENTRIC,)) + >>> sto.regrid_like(target_grid, RegridderWeightsCache(), regrid_method) + + The RegridderType.OVERLAP and RegridderType.RELATIVEOVERLAP require an extra + method as string. + + >>> regrid_method = StorageCoefficientRegridMethod(storage_coefficient=(RegridderType.OVERLAP, "max",)) + """ + + convertible: _RegridVarType = (RegridderType.OVERLAP, "mode") + storage_coefficient: _RegridVarType = (RegridderType.OVERLAP, "mean") + specific_yield: _RegridVarType = (RegridderType.OVERLAP, "mean") diff --git a/imod/mf6/riv.py b/imod/mf6/riv.py index f3f05fa86..8c4c0358c 100644 --- a/imod/mf6/riv.py +++ b/imod/mf6/riv.py @@ -1,11 +1,9 @@ -from typing import Optional, Tuple - import numpy as np from imod.logging import init_log_decorator from imod.mf6.boundary_condition import BoundaryCondition from imod.mf6.interfaces.iregridpackage import IRegridPackage -from imod.mf6.utilities.regrid import RegridderType +from imod.mf6.regrid.regrid_schemes import RiverRegridMethod from imod.mf6.validation import BOUNDARY_DIMS_SCHEMA, CONC_DIMS_SCHEMA from imod.schemata import ( AllInsideNoDataSchema, @@ -125,13 +123,7 @@ class River(BoundaryCondition, IRegridPackage): _template = BoundaryCondition._initialize_template(_pkg_id) _auxiliary_data = {"concentration": "species"} - - _regrid_method = { - "stage": (RegridderType.OVERLAP, "mean"), - "conductance": (RegridderType.RELATIVEOVERLAP, "conductance"), - "bottom_elevation": (RegridderType.OVERLAP, "mean"), - "concentration": (RegridderType.OVERLAP, "mean"), - } + _regrid_method = RiverRegridMethod() @init_log_decorator() def __init__( @@ -161,7 +153,6 @@ def __init__( "repeat_stress": repeat_stress, } super().__init__(dict_dataset) - self._validate_init_schemata(validate) def _validate(self, schemata, **kwargs): @@ -171,6 +162,3 @@ def _validate(self, schemata, **kwargs): errors = super()._validate(schemata, **kwargs) return errors - - def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: - return self._regrid_method diff --git a/imod/mf6/ssm.py b/imod/mf6/ssm.py index b7616117a..bc64ce224 100644 --- a/imod/mf6/ssm.py +++ b/imod/mf6/ssm.py @@ -1,12 +1,9 @@ -from typing import Optional, Tuple - import numpy as np from imod.logging import init_log_decorator, logger from imod.mf6 import GroundwaterFlowModel from imod.mf6.boundary_condition import BoundaryCondition from imod.mf6.interfaces.iregridpackage import IRegridPackage -from imod.mf6.utilities.regrid import RegridderType from imod.schemata import DTypeSchema @@ -43,8 +40,6 @@ class SourceSinkMixing(BoundaryCondition, IRegridPackage): _write_schemata = {} - _regrid_method: dict[str, Tuple[RegridderType, str]] = {} - @init_log_decorator() def __init__( self, @@ -170,6 +165,3 @@ def from_flow_model( save_flows=save_flows, validate=validate, ) - - def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: - return self._regrid_method diff --git a/imod/mf6/sto.py b/imod/mf6/sto.py index e873cda85..a8f6fbff9 100644 --- a/imod/mf6/sto.py +++ b/imod/mf6/sto.py @@ -1,17 +1,18 @@ import abc from copy import deepcopy -from typing import Optional, Tuple +from typing import Optional import numpy as np from imod.logging import init_log_decorator from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.package import Package -from imod.mf6.utilities.regrid import ( - RegridderType, - RegridderWeightsCache, - _regrid_package_data, +from imod.mf6.regrid.regrid_schemes import ( + SpecificStorageRegridMethod, + StorageCoefficientRegridMethod, ) +from imod.mf6.utilities.regrid import RegridderWeightsCache, _regrid_package_data +from imod.mf6.utilities.regridding_types import RegridderType from imod.mf6.validation import PKG_DIMS_SCHEMA from imod.schemata import ( AllValueSchema, @@ -165,13 +166,8 @@ class SpecificStorage(StorageBase): ), } - _regrid_method = { - "convertible": (RegridderType.OVERLAP, "mode"), - "specific_storage": (RegridderType.OVERLAP, "mean"), - "specific_yield": (RegridderType.OVERLAP, "mean"), - } - _template = Package._initialize_template(_pkg_id) + _regrid_method = SpecificStorageRegridMethod() @init_log_decorator() def __init__( @@ -197,9 +193,6 @@ def render(self, directory, pkgname, globaltimes, binary): d = self._render_dict(directory, pkgname, globaltimes, binary) return self._template.render(d) - def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: - return self._regrid_method - class StorageCoefficient(StorageBase): """ @@ -303,13 +296,8 @@ class StorageCoefficient(StorageBase): ), } - _regrid_method = { - "convertible": (RegridderType.OVERLAP, "mode"), - "storage_coefficient": (RegridderType.OVERLAP, "mean"), - "specific_yield": (RegridderType.OVERLAP, "mean"), - } - _template = Package._initialize_template(_pkg_id) + _regrid_method = StorageCoefficientRegridMethod() @init_log_decorator() def __init__( @@ -336,9 +324,6 @@ def render(self, directory, pkgname, globaltimes, binary): d["storagecoefficient"] = True return self._template.render(d) - def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: - return self._regrid_method - @classmethod def from_imod5_data( cls, diff --git a/imod/mf6/utilities/regrid.py b/imod/mf6/utilities/regrid.py index 442d2338b..ddc738dd8 100644 --- a/imod/mf6/utilities/regrid.py +++ b/imod/mf6/utilities/regrid.py @@ -1,6 +1,7 @@ import abc import copy from collections import defaultdict +from dataclasses import asdict from typing import Any, Dict, Optional, Tuple, Union import xarray as xr @@ -18,6 +19,7 @@ from imod.mf6.interfaces.ipointdatapackage import IPointDataPackage from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.interfaces.isimulation import ISimulation +from imod.mf6.regrid.regrid_schemes import EmptyRegridMethod, RegridMethodType from imod.mf6.statusinfo import NestedStatusInfo from imod.mf6.utilities.clip import clip_by_grid from imod.mf6.utilities.package import _is_valid @@ -35,10 +37,13 @@ class RegridderWeightsCache: """ - This class stores any number of regridders that can regrid a single source grid to a single target grid. - By storing the regridders, we make sure the regridders can be re-used for different arrays on the same grid. - Regridders are stored based on their type (`see these docs`_) and planar coordinates (x, y). - This is important because computing the regridding weights is a costly affair. + This class stores any number of regridders that can regrid a single source + grid to a single target grid. By storing the regridders, we make sure the + regridders can be re-used for different arrays on the same grid. Regridders + are stored based on their type (`see these + docs`_) + and planar coordinates (x, y). This is important because computing the + regridding weights is a costly affair. """ def __init__( @@ -74,9 +79,8 @@ def get_regridder( ) -> BaseRegridder: """ returns a regridder of the specified type and with the specified method. - The desired type can be passed through the argument "regridder_type" as an enumerator or - as a class. - The following two are equivalent: + The desired type can be passed through the argument "regridder_type" as + an enumerator or as a class. The following two are equivalent: instancesCollection.get_regridder(RegridderType.OVERLAP, "mean") instancesCollection.get_regridder(xu.OverlapRegridder, "mean") @@ -240,9 +244,9 @@ def _get_unique_regridder_types(model: IModel) -> defaultdict[RegridderType, lis methods: defaultdict = defaultdict(list) regrid_packages = [pkg for pkg in model.values() if isinstance(pkg, IRegridPackage)] regrid_packages_with_methods = { - pkg: pkg.get_regrid_methods().items() # type: ignore # noqa: union-attr + pkg: asdict(pkg.get_regrid_methods()).items() # type: ignore # noqa: union-attr for pkg in regrid_packages - if pkg.get_regrid_methods() is not None + if not isinstance(pkg.get_regrid_methods(), EmptyRegridMethod) } for pkg, regrid_methods in regrid_packages_with_methods.items(): @@ -262,35 +266,38 @@ def _regrid_like( package: IRegridPackage, target_grid: GridDataArray, regrid_context: RegridderWeightsCache, - regridder_types: Optional[dict[str, tuple[RegridderType, str]]] = None, + regridder_types: Optional[RegridMethodType] = None, ) -> IPackage: """ - Creates a package of the same type as this package, based on another discretization. - It regrids all the arrays in this package to the desired discretization, and leaves the options - unmodified. At the moment only regridding to a different planar grid is supported, meaning - ``target_grid`` has different ``"x"`` and ``"y"`` or different ``cell2d`` coords. + Creates a package of the same type as this package, based on another + discretization. It regrids all the arrays in this package to the desired + discretization, and leaves the options unmodified. At the moment only + regridding to a different planar grid is supported, meaning ``target_grid`` + has different ``"x"`` and ``"y"`` or different ``cell2d`` coords. - The regridding methods can be specified in the _regrid_method attribute of the package. These are the defaults - that specify how each array should be regridded. These defaults can be overridden using the input - parameters of this function. + The default regridding methods are specified in the ``_regrid_method`` + attribute of the package. These defaults can be overridden using the + input parameters of this function. Examples -------- To regrid the npf package with a non-default method for the k-field, call regrid_like with these arguments: - >>> new_npf = npf.regrid_like(like, {"k": (imod.RegridderType.OVERLAP, "mean")}) - + >>> regridder_types = imod.mf6.regrid.NodePropertyFlowRegridMethod(k=(imod.RegridderType.OVERLAP, "mean")) + >>> new_npf = npf.regrid_like(like, RegridderWeightsCache, regridder_types) Parameters ---------- + package: IRegridPackage: + package to regrid target_grid: xr.DataArray or xu.UgridDataArray a grid defined over the same discretization as the one we want to regrid the package to - regridder_types: dict(str->(regridder type,str)) - dictionary mapping arraynames (str) to a tuple of regrid type (a specialization class of BaseRegridder) and function name (str) - this dictionary can be used to override the default mapping method. regrid_context: RegridderWeightsCache stores regridder weights for different regridders. Can be used to speed up regridding, if the same regridders are used several times for regridding different arrays. + regridder_types: RegridMethodType, optional + dictionary mapping arraynames (str) to a tuple of regrid type (a specialization class of BaseRegridder) and function name (str) + this dictionary can be used to override the default mapping method. Returns ------- @@ -305,9 +312,10 @@ def _regrid_like( if hasattr(package, "auxiliary_data_fields"): remove_expanded_auxiliary_variables_from_dataset(package) - regridder_settings = package.get_regrid_methods() - if regridder_types is not None: - regridder_settings.update(regridder_types) + if regridder_types is None: + regridder_settings = asdict(package.get_regrid_methods(), dict_factory=dict) + else: + regridder_settings = asdict(regridder_types, dict_factory=dict) new_package_data = package.get_non_grid_data(list(regridder_settings.keys())) new_package_data = _regrid_package_data( diff --git a/imod/mf6/wel.py b/imod/mf6/wel.py index 6659501e7..080046c99 100644 --- a/imod/mf6/wel.py +++ b/imod/mf6/wel.py @@ -21,7 +21,6 @@ from imod.mf6.mf6_wel_adapter import Mf6Wel from imod.mf6.package import Package from imod.mf6.utilities.dataset import remove_inactive -from imod.mf6.utilities.regrid import RegridderType from imod.mf6.validation import validation_pkg_error_message from imod.mf6.write_context import WriteContext from imod.prepare import assign_wells @@ -185,8 +184,6 @@ def y(self) -> npt.NDArray[np.float64]: "concentration": [AnyNoDataSchema(), EmptyIndexesSchema()], } - _regrid_method: dict[str, Tuple[RegridderType, str]] = {} - @init_log_decorator() def __init__( self, @@ -612,9 +609,6 @@ def mask(self, domain: GridDataArray) -> Well: ) return mask_2D(self, domain_2d) - def get_regrid_methods(self) -> Optional[dict[str, Tuple[RegridderType, str]]]: - return self._regrid_method - class WellDisStructured(DisStructuredBoundaryCondition): """ diff --git a/imod/tests/test_mf6/test_mf6_regrid.py b/imod/tests/test_mf6/test_mf6_regrid_package.py similarity index 100% rename from imod/tests/test_mf6/test_mf6_regrid.py rename to imod/tests/test_mf6/test_mf6_regrid_package.py diff --git a/imod/tests/test_mf6/test_mf6_regrid_scheme.py b/imod/tests/test_mf6/test_mf6_regrid_scheme.py new file mode 100644 index 000000000..2a6240330 --- /dev/null +++ b/imod/tests/test_mf6/test_mf6_regrid_scheme.py @@ -0,0 +1,80 @@ +from dataclasses import asdict + +import pytest +from pydantic import ValidationError +from pytest_cases import parametrize, parametrize_with_cases + +from imod.mf6.regrid.regrid_schemes import ( + ConstantHeadRegridMethod, + DiscretizationRegridMethod, + DispersionRegridMethod, + DrainageRegridMethod, + EmptyRegridMethod, + EvapotranspirationRegridMethod, + GeneralHeadBoundaryRegridMethod, + InitialConditionsRegridMethod, + MobileStorageTransferRegridMethod, + NodePropertyFlowRegridMethod, + RechargeRegridMethod, + RiverRegridMethod, + SpecificStorageRegridMethod, + StorageCoefficientRegridMethod, +) +from imod.mf6.utilities.regrid import RegridderType + +ALL_REGRID_METHODS = [ + ConstantHeadRegridMethod, + DiscretizationRegridMethod, + DispersionRegridMethod, + DrainageRegridMethod, + EmptyRegridMethod, + EvapotranspirationRegridMethod, + GeneralHeadBoundaryRegridMethod, + InitialConditionsRegridMethod, + MobileStorageTransferRegridMethod, + NodePropertyFlowRegridMethod, + RechargeRegridMethod, + RiverRegridMethod, + SpecificStorageRegridMethod, + StorageCoefficientRegridMethod, +] + + +# Forward regrid methods to case functions to generate readable test ids +@parametrize(regrid_method=ALL_REGRID_METHODS) +def case_regrid(regrid_method): + return regrid_method + + +def tuple_centroid(): + return (RegridderType.CENTROIDLOCATOR, "max") + + +def tuple_barycentric(): + return (RegridderType.BARYCENTRIC,) + + +@parametrize_with_cases("regrid_method", cases=".") +def test_regrid_method(regrid_method): + regrid_method_instance = regrid_method() + assert isinstance(regrid_method_instance, regrid_method) + + +@parametrize_with_cases("regrid_method", cases=".") +@parametrize_with_cases("tuple_values", cases=".", prefix="tuple_") +def test_regrid_method_custom(regrid_method, tuple_values): + for key in asdict(regrid_method()).keys(): + kwargs = {key: tuple_values} + regrid_method_instance = regrid_method(**kwargs) + assert isinstance(regrid_method_instance, regrid_method) + + +@parametrize_with_cases("regrid_method", cases=".") +def test_regrid_method_incorrect_input(regrid_method): + with pytest.raises(ValidationError): + regrid_method(non_existent_var=999) + + for key in asdict(regrid_method()).keys(): + kwargs = {key: "wrong_value_type"} + with pytest.raises(ValidationError): + regrid_method(**kwargs) diff --git a/imod/tests/test_mf6/test_mf6_regrid_simulation.py b/imod/tests/test_mf6/test_mf6_regrid_simulation.py index 9ac5a95d2..5d5e0a817 100644 --- a/imod/tests/test_mf6/test_mf6_regrid_simulation.py +++ b/imod/tests/test_mf6/test_mf6_regrid_simulation.py @@ -4,6 +4,8 @@ import pytest import imod +from imod.mf6.regrid.regrid_schemes import ConstantHeadRegridMethod +from imod.mf6.utilities.regrid import RegridderWeightsCache from imod.mf6.utilities.regridding_types import RegridderType from imod.tests.fixtures.mf6_modelrun_fixture import assert_simulation_can_run from imod.tests.fixtures.mf6_small_models_fixture import ( @@ -56,26 +58,16 @@ def test_regridded_simulation_has_required_packages( @pytest.mark.usefixtures("circle_model") -def test_regrid_with_methods_without_functions(circle_model, tmp_path): +def test_regrid_with_custom_method(circle_model): simulation = circle_model idomain = circle_model["GWF_1"].domain - # redefine the default regridding method for the constant head package, - # assign a default method that does not have a function - old_regrid_method = imod.mf6.ConstantHead._regrid_method - imod.mf6.ConstantHead._regrid_method = { - "head": (RegridderType.BARYCENTRIC,), - "concentration": (RegridderType.BARYCENTRIC,), - } - regridding_succeeded = False - - # try regridding the simulation with the new default method - try: - simulation.regrid_like("regridded", idomain) - regridding_succeeded = True - finally: - # Set the regrid_method back to its old value. It is a class variable - # and not an instance variable, so if we don't put it back all chd - # packages will be affected in the next tests - imod.mf6.ConstantHead._regrid_method = old_regrid_method - - assert regridding_succeeded + chd_pkg = circle_model["GWF_1"].pop("chd") + + simulation_regridded = simulation.regrid_like("regridded", idomain) + regrid_method = ConstantHeadRegridMethod( + head=(RegridderType.BARYCENTRIC,), concentration=(RegridderType.BARYCENTRIC,) + ) + regrid_context = RegridderWeightsCache() + simulation_regridded["GWF_1"]["chd"] = chd_pkg.regrid_like( + idomain, regrid_context=regrid_context, regridder_types=regrid_method + ) diff --git a/pixi.lock b/pixi.lock index 4055321c1..8f1a98ef0 100644 --- a/pixi.lock +++ b/pixi.lock @@ -13,6 +13,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.11-hd590300_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/aom-3.8.2-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asciitree-0.3.3-py_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/atk-1.0-2.38.0-hd4edc92_1.tar.bz2 @@ -82,11 +83,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.5.0-hcb278e6_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.37-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.38-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fasteners-0.17.3-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/ffmpeg-6.1.1-gpl_hee4b679_108.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/fiona-1.9.6-py311hf8e0aa6_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/flopy-3.6.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/flopy-3.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/fltk-1.3.9-hea138e6_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/fmt-10.2.1-h00ab1b0_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/folium-0.16.0-pyhd8ed1ab_0.conda @@ -97,7 +98,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.14.2-h14ed4e7_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.51.0-py311h459d7ec_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.52.1-py311h331c9d8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/freeimage-3.18.0-h4b96d29_20.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/freetype-2.12.1-h267a509_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/freexl-2.0.0-h743c826_0.conda @@ -135,7 +136,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/hatchling-1.24.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/hdf4-4.2.15-h2a13503_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/hdf5-1.14.3-nompi_h4f84152_101.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.4-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.6-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-73.2-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 @@ -153,18 +154,18 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/json-c-0.17-h7ab15ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/jsoncpp-1.9.5-h4bd325d_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/jxrlib-1.1-hd590300_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/kealib-1.5.3-h2f55d51_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/kealib-1.5.3-hee9dde6_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/keyring-25.2.1-pyha804496_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.5-py311h9547e67_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.2-h659d440_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lame-3.100-h166bdaf_1003.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.16-hb7c19ff_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-h55db66e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h27087fc_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20240116.2-cxx17_h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.3-h59595ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.7.2-h2aa1ff5_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.7.4-hfca40fe_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-15.0.2-he70291f_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-15.0.2-hac33072_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-15.0.2-hac33072_3_cpu.conda @@ -186,7 +187,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang13-15.0.7-default_h5d6823c_5.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h4637d8d_4.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.7.1-hca28451_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.8.0-hca28451_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.19-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.120-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20191231-he28a2e2_2.tar.bz2 @@ -313,7 +314,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/openexr-3.2.2-haf962dd_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/openh264-2.4.1-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.2-h488ebb8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.0-hd590300_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.0-h4ab18f5_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/orc-2.0.0-h17fec99_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/p11-kit-0.24.1-hc5aa10d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.0-pyhd8ed1ab_0.conda @@ -345,6 +346,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/pyarrow-15.0.2-py311h78dcc79_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyarrow-hotfix-0.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.18.2-py311h5ecf98a_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pymetis-2023.1.1-py311hf4706e4_2.conda @@ -374,19 +377,19 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/re2-2023.09.01-h7f4b329_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/readme_renderer-42.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.31.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-toolbelt-1.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-2.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rioxarray-0.15.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/rtree-1.2.0-py311h3bb2b0f_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.4.4-py311hae69bc3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.4.5-py311hae69bc3_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/s2n-1.4.12-h06160fa_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/scikit-learn-1.4.2-py311he08f58d_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/scipy-1.13.0-py311h517d4fd_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/scikit-learn-1.5.0-py311he08f58d_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/scipy-1.13.1-py311h517d4fd_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/scooby-0.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/secretstorage-3.3.3-py311h38be061_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-8.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-8.1.0-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/shapely-2.0.4-py311h0bed3d6_1.conda @@ -420,7 +423,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/toolz-0.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.4-py311h459d7ec_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.66.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.17-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.22-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/twine-5.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.11.0-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.11.0-pyha770c72_0.conda @@ -434,7 +437,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/vtk-base-9.2.6-qt_py311h1234567_220.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/vtk-io-ffmpeg-9.2.6-qt_py311h1234567_220.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/x264-1!164.3095-h166bdaf_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/x265-3.5-h924138e_3.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.5.0-pyhd8ed1ab_0.conda @@ -478,6 +481,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/aiohttp-3.9.5-py311he705e18_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/aom-3.8.2-h73e2aa4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asciitree-0.3.3-py_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/atk-1.0-2.38.0-h1d18e73_1.tar.bz2 @@ -544,11 +548,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/expat-2.5.0-hf0c8a7f_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.37-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.38-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fasteners-0.17.3-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/ffmpeg-6.1.1-gpl_h6b92a41_108.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/fiona-1.9.6-py311hd2ff552_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/flopy-3.6.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/flopy-3.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/fltk-1.3.9-he73b29e_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/fmt-10.2.1-h7728843_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/folium-0.16.0-pyhd8ed1ab_0.conda @@ -559,7 +563,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/fontconfig-2.14.2-h5bb23bf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-64/fonttools-4.51.0-py311he705e18_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/fonttools-4.52.1-py311h72ae277_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/freeimage-3.18.0-hdc0ade2_20.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/freetype-2.12.1-h60636b9_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/freexl-2.0.0-h3ec172f_0.conda @@ -597,7 +601,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/hatchling-1.24.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/hdf4-4.2.15-h8138101_7.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/hdf5-1.14.3-nompi_hb512a33_101.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.4-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.6-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-73.2-hf5e326d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 @@ -614,7 +618,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/json-c-0.17-h8e11ae5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/jsoncpp-1.9.5-h940c156_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/jxrlib-1.1-h10d778d_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/kealib-1.5.3-h5f07ac3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/kealib-1.5.3-hb2b617a_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/keyring-25.2.1-pyh534df25_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/kiwisolver-1.4.5-py311h5fe6e05_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/krb5-1.21.2-hb884880_0.conda @@ -623,7 +627,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/lerc-4.0.0-hb486fe8_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/libabseil-20240116.2-cxx17_hc1bcbd7_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libaec-1.1.3-h73e2aa4_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libarchive-3.7.2-hd35d340_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libarchive-3.7.4-h20e244c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-15.0.2-h965e444_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-acero-15.0.2-ha0df490_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-dataset-15.0.2-ha0df490_3_cpu.conda @@ -643,7 +647,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/libclang-15.0.7-default_h7151d67_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libclang13-15.0.7-default_h0edc4dd_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libcrc32c-1.1.2-he49afe7_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.7.1-h726d00d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.8.0-hf9fcc65_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-17.0.6-h88467a6_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.19-ha4e1b8e_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libedit-3.1.20191231-h0678c8f_2.tar.bz2 @@ -755,7 +759,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/openexr-3.2.2-h3f0570e_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/openh264-2.4.1-h73e2aa4_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.2-h7310d3a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.0-hd75f5a5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.0-h87427d6_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/orc-2.0.0-hf146577_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/p11-kit-0.24.1-h65f8906_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.0-pyhd8ed1ab_0.conda @@ -785,6 +789,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/pyarrow-15.0.2-py311ha429d19_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyarrow-hotfix-0.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.18.2-py311h2786eb7_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pymetis-2023.1.1-py311h5fe6d0d_2.conda @@ -811,17 +817,17 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/re2-2023.09.01-hb168e87_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h9e318b2_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/readme_renderer-42.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.31.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-toolbelt-1.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-2.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rioxarray-0.15.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/rtree-1.2.0-py311hbc1f44b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.4.4-py311h148dfb1_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/scikit-learn-1.4.2-py311h3c3ac6d_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/scipy-1.13.0-py311hd5d9b8d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.4.5-py311h9a97b26_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/scikit-learn-1.5.0-py311h3c3ac6d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/scipy-1.13.1-py311h40a1ab3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/scooby-0.10.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-8.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-8.1.0-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/shapely-2.0.4-py311h2a2259d_1.conda @@ -854,7 +860,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/toolz-0.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tornado-6.4-py311he705e18_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.66.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.17-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.22-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/twine-5.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.11.0-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.11.0-pyha770c72_0.conda @@ -867,7 +873,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/vtk-base-9.2.6-qt_py311h1234567_220.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/vtk-io-ffmpeg-9.2.6-qt_py311h1234567_220.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/x264-1!164.3095-h775f41a_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/x265-3.5-hbb4e6a2_3.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.5.0-pyhd8ed1ab_0.conda @@ -902,6 +908,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aiohttp-3.9.5-py311h05b510d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aom-3.8.2-h078ce10_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asciitree-0.3.3-py_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/atk-1.0-2.38.0-hcb7b3dd_1.tar.bz2 @@ -968,11 +975,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/expat-2.5.0-hb7217d7_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.37-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.38-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fasteners-0.17.3-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ffmpeg-6.1.1-gpl_h4f1e072_108.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fiona-1.9.6-py311h1c26527_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/flopy-3.6.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/flopy-3.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fltk-1.3.9-h31b9a01_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fmt-10.2.1-h2ffa867_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/folium-0.16.0-pyhd8ed1ab_0.conda @@ -983,7 +990,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fontconfig-2.14.2-h82840c6_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.51.0-py311h05b510d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.52.1-py311hd3f4193_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/freeimage-3.18.0-hd0e3f39_20.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.12.1-hadb7bae_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/freexl-2.0.0-hfbad9fb_0.conda @@ -1021,7 +1028,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/hatchling-1.24.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/hdf4-4.2.15-h2ee6834_7.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/hdf5-1.14.3-nompi_h751145d_101.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.4-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.6-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-73.2-hc8870d7_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 @@ -1038,7 +1045,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/json-c-0.17-h40ed0f5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/jsoncpp-1.9.5-hc021e02_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/jxrlib-1.1-h93a5062_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/kealib-1.5.3-h210d843_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/kealib-1.5.3-h848a2d4_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/keyring-25.2.1-pyh534df25_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.4.5-py311he4fd1f5_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.21.2-h92f50d5_0.conda @@ -1047,7 +1054,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lerc-4.0.0-h9a09cb3_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20240116.2-cxx17_hebf3989_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libaec-1.1.3-hebf3989_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarchive-3.7.2-hcacb583_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarchive-3.7.4-h83d404f_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-15.0.2-h3ee1d8f_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-acero-15.0.2-h3f3aa29_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-dataset-15.0.2-h3f3aa29_3_cpu.conda @@ -1067,7 +1074,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-15.0.7-default_he012953_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang13-15.0.7-default_h83d0a53_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcrc32c-1.1.2-hbdafb3b_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.7.1-h2d989ff_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.8.0-h7b6f9a7_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-17.0.6-h5f092b4_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.19-hb547adb_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20191231-hc8eb9b7_2.tar.bz2 @@ -1179,7 +1186,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openexr-3.2.2-h2c51e1d_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openh264-2.4.1-hebf3989_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.2-h9f1df11_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.0-h0d3ecfb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.0-hfb2fe0b_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/orc-2.0.0-h4aad248_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/p11-kit-0.24.1-h29577a5_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.0-pyhd8ed1ab_0.conda @@ -1209,6 +1216,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyarrow-15.0.2-py311h3003323_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyarrow-hotfix-0.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.18.2-py311h5d190b6_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pymetis-2023.1.1-py311h006cce6_2.conda @@ -1235,17 +1244,17 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/re2-2023.09.01-h4cba328_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h92ec313_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/readme_renderer-42.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.31.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-toolbelt-1.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-2.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rioxarray-0.15.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rtree-1.2.0-py311hd698ff7_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.4.4-py311hd374d79_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scikit-learn-1.4.2-py311hbfb48bc_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.13.0-py311hceeca8c_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.4.5-py311hd374d79_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scikit-learn-1.5.0-py311hbfb48bc_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.13.1-py311hceeca8c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/scooby-0.10.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-8.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-8.1.0-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/shapely-2.0.4-py311h1273ac6_1.conda @@ -1278,7 +1287,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/toolz-0.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.4-py311h05b510d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.66.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.17-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.22-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/twine-5.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.11.0-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.11.0-pyha770c72_0.conda @@ -1291,7 +1300,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/vtk-base-9.2.6-qt_py311h1234567_220.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/vtk-io-ffmpeg-9.2.6-qt_py311h1234567_220.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/x264-1!164.3095-h57fd34a_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/x265-3.5-hbc6ce65_3.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.5.0-pyhd8ed1ab_0.conda @@ -1326,6 +1335,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/aiohttp-3.9.5-py311ha68e1ae_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/aom-3.8.2-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asciitree-0.3.3-py_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-23.2.0-pyh71513ae_0.conda @@ -1391,11 +1401,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/expat-2.5.0-h63175ca_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.37-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.38-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fasteners-0.17.3-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/ffmpeg-6.1.1-gpl_h66c0b5b_108.conda - conda: https://conda.anaconda.org/conda-forge/win-64/fiona-1.9.6-py311hbcf8545_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/flopy-3.6.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/flopy-3.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/fltk-1.3.9-h01c93fd_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/fmt-10.2.1-h181d51b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/folium-0.16.0-pyhd8ed1ab_0.conda @@ -1406,7 +1416,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.14.2-hbde0cde_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.51.0-py311ha68e1ae_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.52.1-py311he736701_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/freeimage-3.18.0-h2b56e36_20.conda - conda: https://conda.anaconda.org/conda-forge/win-64/freetype-2.12.1-hdaf720e_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/freexl-2.0.0-h8276f4a_0.conda @@ -1438,7 +1448,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/hatchling-1.24.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/hdf4-4.2.15-h5557f11_7.conda - conda: https://conda.anaconda.org/conda-forge/win-64/hdf5-1.14.3-nompi_h73e8ff5_101.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.4-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.6-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/icu-73.2-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 @@ -1447,7 +1457,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-7.1.0-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/intel-openmp-2024.1.0-h57928b3_965.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/intel-openmp-2024.1.0-h57928b3_966.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.classes-3.4.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.context-5.3.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.functools-4.0.0-pyhd8ed1ab_0.conda @@ -1455,7 +1465,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/joblib-1.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/jsoncpp-1.9.5-h2d74725_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/jxrlib-1.1-hcfcfb64_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/kealib-1.5.3-hd248416_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/kealib-1.5.3-h6c43f9b_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/keyring-25.2.1-pyh7428d3b_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.5-py311h005e61a_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.21.2-heb0366b_0.conda @@ -1463,7 +1473,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/lerc-4.0.0-h63175ca_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/libabseil-20240116.2-cxx17_h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libaec-1.1.3-h63175ca_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libarchive-3.7.2-h313118b_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libarchive-3.7.4-haf234dc_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-15.0.2-h45212c0_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-acero-15.0.2-h8681a6d_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-dataset-15.0.2-h8681a6d_3_cpu.conda @@ -1482,7 +1492,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/libclang-15.0.7-default_h3a3e6c3_5.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libclang13-15.0.7-default_hf64faad_5.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libcrc32c-1.1.2-h0e60522_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.7.1-hd5e4a3a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.8.0-hd5e4a3a_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.19-hcfcfb64_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libevent-2.1.12-h3671451_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.5.0-h63175ca_1.conda @@ -1568,7 +1578,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/openexr-3.2.2-h72640d8_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/openh264-2.4.1-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.2-h3d672ee_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.0-hcfcfb64_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.0-h2466b09_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/orc-2.0.0-h7e885a9_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandamesh-0.1.5-pyhd8ed1ab_0.conda @@ -1599,6 +1609,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/pyarrow-15.0.2-py311h05400ba_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyarrow-hotfix-0.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.18.2-py311h533ab2d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pymetis-2023.1.1-py311hca2ccfb_2.conda @@ -1627,17 +1639,17 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/rasterio-1.3.9-py311h02f6225_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/re2-2023.09.01-hd3b24a8_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/readme_renderer-42.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.31.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-toolbelt-1.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-2.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rioxarray-0.15.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/rtree-1.2.0-py311hcacb13a_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.4.4-py311ha637bb9_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/scikit-learn-1.4.2-py311hdcb8d17_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/scipy-1.13.0-py311hd4686c6_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.4.5-py311ha637bb9_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/scikit-learn-1.5.0-py311hdcb8d17_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/scipy-1.13.1-py311hd4686c6_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/scooby-0.10.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-8.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-8.1.0-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/shapely-2.0.4-py311hcd532c9_1.conda @@ -1671,7 +1683,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/toolz-0.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.4-py311ha68e1ae_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.66.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.17-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.22-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/twine-5.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.11.0-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.11.0-pyha770c72_0.conda @@ -1680,15 +1692,15 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/uriparser-0.9.8-h5a68840_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/utfcpp-4.0.5-h57928b3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-hcf57466_18.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.38.33130-h82b7239_18.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.38.33130-hcb4865c_18.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-ha32ba9b_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.38.33135-h835141b_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.38.33135-h22015db_20.conda - conda: https://conda.anaconda.org/conda-forge/win-64/vtk-9.2.6-qt_py311h1234567_220.conda - conda: https://conda.anaconda.org/conda-forge/win-64/vtk-base-9.2.6-qt_py311h1234567_220.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/win32_setctime-1.1.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyhd8ed1ab_6.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/x264-1!164.3095-h8ffe710_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/x265-3.5-h2d74725_3.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.5.0-pyhd8ed1ab_0.conda @@ -1732,6 +1744,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.11-hd590300_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/aom-3.8.2-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-23.1.0-pyhd8ed1ab_0.conda @@ -1816,11 +1829,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.5.0-hcb278e6_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.37-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.38-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fasteners-0.17.3-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/ffmpeg-6.1.1-gpl_hee4b679_108.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/fiona-1.9.6-py311hf8e0aa6_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/flopy-3.6.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/flopy-3.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/fltk-1.3.9-hea138e6_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/fmt-10.2.1-h00ab1b0_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/folium-0.16.0-pyhd8ed1ab_0.conda @@ -1831,7 +1844,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.14.2-h14ed4e7_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.51.0-py311h459d7ec_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.52.1-py311h331c9d8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/freeimage-3.18.0-h4b96d29_20.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/freetype-2.12.1-h267a509_2.conda @@ -1876,7 +1889,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.27.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.0.1-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.4-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.6-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-73.2-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 @@ -1905,29 +1918,29 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.22.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-1.0.0-pyhd8ed1ab_10.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.2.5-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_console-6.6.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/jupyter_core-5.7.2-py311h38be061_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.10-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/jxrlib-1.1-hd590300_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/kealib-1.5.3-h2f55d51_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/kealib-1.5.3-hee9dde6_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/keyring-25.2.1-pyha804496_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/keyutils-1.6.1-h166bdaf_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/kiwisolver-1.4.5-py311h9547e67_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.2-h659d440_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lame-3.100-h166bdaf_1003.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.16-hb7c19ff_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-h55db66e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h27087fc_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20240116.2-cxx17_h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.3-h59595ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.7.2-h2aa1ff5_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.7.4-hfca40fe_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-15.0.2-he70291f_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-15.0.2-hac33072_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-15.0.2-hac33072_3_cpu.conda @@ -1949,7 +1962,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang13-15.0.7-default_h5d6823c_5.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h4637d8d_4.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.7.1-hca28451_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.8.0-hca28451_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.19-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.120-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20191231-he28a2e2_2.tar.bz2 @@ -2087,7 +2100,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/openexr-3.2.2-haf962dd_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/openh264-2.4.1-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.2-h488ebb8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.0-hd590300_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.0-h4ab18f5_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/orc-2.0.0-h17fec99_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/p11-kit-0.24.1-hc5aa10d_0.tar.bz2 @@ -2131,6 +2144,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/pyarrow-15.0.2-py311h78dcc79_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyarrow-hotfix-0.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.18.2-py311h5ecf98a_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pymetis-2023.1.1-py311hf4706e4_2.conda @@ -2166,7 +2181,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/readme_renderer-42.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.35.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.31.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-toolbelt-1.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-2.0.0-pyhd8ed1ab_0.tar.bz2 @@ -2175,14 +2190,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/rioxarray-0.15.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.18.1-py311h5ecf98a_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/rtree-1.2.0-py311h3bb2b0f_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.4.4-py311hae69bc3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.4.5-py311hae69bc3_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/s2n-1.4.12-h06160fa_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/scikit-learn-1.4.2-py311he08f58d_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/scipy-1.13.0-py311h517d4fd_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/scikit-learn-1.5.0-py311he08f58d_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/scipy-1.13.1-py311h517d4fd_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/scooby-0.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/secretstorage-3.3.3-py311h38be061_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-1.8.3-pyh0d859eb_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-8.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-8.1.0-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/shapely-2.0.4-py311h0bed3d6_1.conda @@ -2221,7 +2236,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.4-py311h459d7ec_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.66.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.17-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.22-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/twine-5.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/types-python-dateutil-2.9.0.20240316-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.11.0-hd8ed1ab_0.conda @@ -2243,7 +2258,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.8.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.10-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/x264-1!164.3095-h166bdaf_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/x265-3.5-h924138e_3.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.5.0-pyhd8ed1ab_0.conda @@ -2288,6 +2303,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/aiohttp-3.9.5-py311he705e18_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/aom-3.8.2-h73e2aa4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_0.conda @@ -2370,11 +2386,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/expat-2.5.0-hf0c8a7f_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.37-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.38-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fasteners-0.17.3-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/ffmpeg-6.1.1-gpl_h6b92a41_108.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/fiona-1.9.6-py311hd2ff552_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/flopy-3.6.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/flopy-3.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/fltk-1.3.9-he73b29e_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/fmt-10.2.1-h7728843_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/folium-0.16.0-pyhd8ed1ab_0.conda @@ -2385,7 +2401,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/fontconfig-2.14.2-h5bb23bf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-64/fonttools-4.51.0-py311he705e18_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/fonttools-4.52.1-py311h72ae277_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/freeimage-3.18.0-hdc0ade2_20.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/freetype-2.12.1-h60636b9_2.conda @@ -2430,7 +2446,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.27.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.0.1-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.4-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.6-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-73.2-hf5e326d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 @@ -2458,18 +2474,18 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.22.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-1.0.0-pyhd8ed1ab_10.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.2.5-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_console-6.6.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/jupyter_core-5.7.2-py311h6eed73b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.10-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/jxrlib-1.1-h10d778d_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/kealib-1.5.3-h5f07ac3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/kealib-1.5.3-hb2b617a_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/keyring-25.2.1-pyh534df25_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/kiwisolver-1.4.5-py311h5fe6e05_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/krb5-1.21.2-hb884880_0.conda @@ -2478,7 +2494,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/lerc-4.0.0-hb486fe8_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/libabseil-20240116.2-cxx17_hc1bcbd7_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libaec-1.1.3-h73e2aa4_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libarchive-3.7.2-hd35d340_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libarchive-3.7.4-h20e244c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-15.0.2-h965e444_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-acero-15.0.2-ha0df490_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libarrow-dataset-15.0.2-ha0df490_3_cpu.conda @@ -2498,7 +2514,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/libclang-15.0.7-default_h7151d67_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libclang13-15.0.7-default_h0edc4dd_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libcrc32c-1.1.2-he49afe7_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.7.1-h726d00d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.8.0-hf9fcc65_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libcxx-17.0.6-h88467a6_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libdeflate-1.19-ha4e1b8e_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libedit-3.1.20191231-h0678c8f_2.tar.bz2 @@ -2621,7 +2637,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/openexr-3.2.2-h3f0570e_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/openh264-2.4.1-h73e2aa4_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.2-h7310d3a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.0-hd75f5a5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.0-h87427d6_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/orc-2.0.0-hf146577_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/p11-kit-0.24.1-h65f8906_0.tar.bz2 @@ -2663,6 +2679,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/pyarrow-15.0.2-py311ha429d19_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyarrow-hotfix-0.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.18.2-py311h2786eb7_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pymetis-2023.1.1-py311h5fe6d0d_2.conda @@ -2697,7 +2715,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h9e318b2_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/readme_renderer-42.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.35.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.31.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-toolbelt-1.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-2.0.0-pyhd8ed1ab_0.tar.bz2 @@ -2706,12 +2724,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/rioxarray-0.15.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/rpds-py-0.18.1-py311h295b1db_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/rtree-1.2.0-py311hbc1f44b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.4.4-py311h148dfb1_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/scikit-learn-1.4.2-py311h3c3ac6d_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/scipy-1.13.0-py311hd5d9b8d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.4.5-py311h9a97b26_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/scikit-learn-1.5.0-py311h3c3ac6d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/scipy-1.13.1-py311h40a1ab3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/scooby-0.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-1.8.3-pyh31c8845_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-8.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-8.1.0-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/shapely-2.0.4-py311h2a2259d_1.conda @@ -2749,7 +2767,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/tornado-6.4-py311he705e18_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.66.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.17-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.22-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/twine-5.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/types-python-dateutil-2.9.0.20240316-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.11.0-hd8ed1ab_0.conda @@ -2770,7 +2788,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.8.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.10-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/x264-1!164.3095-h775f41a_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/x265-3.5-hbb4e6a2_3.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.5.0-pyhd8ed1ab_0.conda @@ -2806,6 +2824,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aiohttp-3.9.5-py311h05b510d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aom-3.8.2-h078ce10_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_0.conda @@ -2888,11 +2907,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/expat-2.5.0-hb7217d7_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.37-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.38-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fasteners-0.17.3-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ffmpeg-6.1.1-gpl_h4f1e072_108.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fiona-1.9.6-py311h1c26527_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/flopy-3.6.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/flopy-3.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fltk-1.3.9-h31b9a01_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fmt-10.2.1-h2ffa867_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/folium-0.16.0-pyhd8ed1ab_0.conda @@ -2903,7 +2922,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fontconfig-2.14.2-h82840c6_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.51.0-py311h05b510d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.52.1-py311hd3f4193_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/freeimage-3.18.0-hd0e3f39_20.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.12.1-hadb7bae_2.conda @@ -2948,7 +2967,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.27.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.0.1-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.4-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.6-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-73.2-hc8870d7_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 @@ -2976,18 +2995,18 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.22.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-1.0.0-pyhd8ed1ab_10.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.2.5-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_console-6.6.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/jupyter_core-5.7.2-py311h267d04e_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.10-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/jxrlib-1.1-h93a5062_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/kealib-1.5.3-h210d843_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/kealib-1.5.3-h848a2d4_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/keyring-25.2.1-pyh534df25_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/kiwisolver-1.4.5-py311he4fd1f5_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/krb5-1.21.2-h92f50d5_0.conda @@ -2996,7 +3015,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/lerc-4.0.0-h9a09cb3_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20240116.2-cxx17_hebf3989_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libaec-1.1.3-hebf3989_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarchive-3.7.2-hcacb583_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarchive-3.7.4-h83d404f_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-15.0.2-h3ee1d8f_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-acero-15.0.2-h3f3aa29_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-dataset-15.0.2-h3f3aa29_3_cpu.conda @@ -3016,7 +3035,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-15.0.7-default_he012953_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang13-15.0.7-default_h83d0a53_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcrc32c-1.1.2-hbdafb3b_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.7.1-h2d989ff_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.8.0-h7b6f9a7_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-17.0.6-h5f092b4_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.19-hb547adb_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20191231-hc8eb9b7_2.tar.bz2 @@ -3139,7 +3158,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openexr-3.2.2-h2c51e1d_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openh264-2.4.1-hebf3989_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.2-h9f1df11_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.0-h0d3ecfb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.0-hfb2fe0b_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/orc-2.0.0-h4aad248_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/p11-kit-0.24.1-h29577a5_0.tar.bz2 @@ -3181,6 +3200,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyarrow-15.0.2-py311h3003323_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyarrow-hotfix-0.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.18.2-py311h5d190b6_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pymetis-2023.1.1-py311h006cce6_2.conda @@ -3215,7 +3236,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h92ec313_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/readme_renderer-42.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.35.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.31.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-toolbelt-1.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-2.0.0-pyhd8ed1ab_0.tar.bz2 @@ -3224,12 +3245,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/rioxarray-0.15.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.18.1-py311h98c6a39_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rtree-1.2.0-py311hd698ff7_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.4.4-py311hd374d79_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scikit-learn-1.4.2-py311hbfb48bc_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.13.0-py311hceeca8c_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.4.5-py311hd374d79_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scikit-learn-1.5.0-py311hbfb48bc_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.13.1-py311hceeca8c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/scooby-0.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-1.8.3-pyh31c8845_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-8.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-8.1.0-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/shapely-2.0.4-py311h1273ac6_1.conda @@ -3267,7 +3288,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.4-py311h05b510d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.66.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.17-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.22-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/twine-5.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/types-python-dateutil-2.9.0.20240316-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.11.0-hd8ed1ab_0.conda @@ -3288,7 +3309,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.8.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.10-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/x264-1!164.3095-h57fd34a_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/x265-3.5-hbc6ce65_3.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.5.0-pyhd8ed1ab_0.conda @@ -3324,6 +3345,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/aiohttp-3.9.5-py311ha68e1ae_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/aom-3.8.2-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-23.1.0-pyhd8ed1ab_0.conda @@ -3404,11 +3426,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/expat-2.5.0-h63175ca_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.37-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.38-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fasteners-0.17.3-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/ffmpeg-6.1.1-gpl_h66c0b5b_108.conda - conda: https://conda.anaconda.org/conda-forge/win-64/fiona-1.9.6-py311hbcf8545_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/flopy-3.6.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/flopy-3.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/fltk-1.3.9-h01c93fd_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/fmt-10.2.1-h181d51b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/folium-0.16.0-pyhd8ed1ab_0.conda @@ -3419,7 +3441,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.14.2-hbde0cde_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.51.0-py311ha68e1ae_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.52.1-py311he736701_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/freeimage-3.18.0-h2b56e36_20.conda - conda: https://conda.anaconda.org/conda-forge/win-64/freetype-2.12.1-hdaf720e_2.conda @@ -3458,7 +3480,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.27.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.0.1-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.4-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.6-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/icu-73.2-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 @@ -3467,7 +3489,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-7.1.0-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/intel-openmp-2024.1.0-h57928b3_965.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/intel-openmp-2024.1.0-h57928b3_966.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.3-pyha63f2e9_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-8.24.0-pyh7428d3b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.2-pyhd8ed1ab_1.conda @@ -3486,18 +3508,18 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.22.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-1.0.0-pyhd8ed1ab_10.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter-lsp-2.2.5-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_console-6.6.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/jupyter_core-5.7.2-py311h1ea47a8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.0-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.10-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/jxrlib-1.1-hcfcfb64_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/kealib-1.5.3-hd248416_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/kealib-1.5.3-h6c43f9b_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/keyring-25.2.1-pyh7428d3b_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/kiwisolver-1.4.5-py311h005e61a_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/krb5-1.21.2-heb0366b_0.conda @@ -3505,7 +3527,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/lerc-4.0.0-h63175ca_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/libabseil-20240116.2-cxx17_h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libaec-1.1.3-h63175ca_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libarchive-3.7.2-h313118b_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libarchive-3.7.4-haf234dc_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-15.0.2-h45212c0_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-acero-15.0.2-h8681a6d_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-dataset-15.0.2-h8681a6d_3_cpu.conda @@ -3524,7 +3546,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/libclang-15.0.7-default_h3a3e6c3_5.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libclang13-15.0.7-default_hf64faad_5.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libcrc32c-1.1.2-h0e60522_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.7.1-hd5e4a3a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.8.0-hd5e4a3a_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.19-hcfcfb64_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libevent-2.1.12-h3671451_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.5.0-h63175ca_1.conda @@ -3621,7 +3643,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/openexr-3.2.2-h72640d8_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/openh264-2.4.1-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.2-h3d672ee_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.0-hcfcfb64_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.0-h2466b09_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/orc-2.0.0-h7e885a9_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.0-pyhd8ed1ab_0.conda @@ -3662,6 +3684,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/pyarrow-15.0.2-py311h05400ba_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyarrow-hotfix-0.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.18.2-py311h533ab2d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pymetis-2023.1.1-py311hca2ccfb_2.conda @@ -3698,7 +3722,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/re2-2023.09.01-hd3b24a8_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/readme_renderer-42.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.35.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.31.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-toolbelt-1.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-2.0.0-pyhd8ed1ab_0.tar.bz2 @@ -3707,12 +3731,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/rioxarray-0.15.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.18.1-py311h533ab2d_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/rtree-1.2.0-py311hcacb13a_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.4.4-py311ha637bb9_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/scikit-learn-1.4.2-py311hdcb8d17_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/scipy-1.13.0-py311hd4686c6_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.4.5-py311ha637bb9_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/scikit-learn-1.5.0-py311hdcb8d17_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/scipy-1.13.1-py311hd4686c6_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/scooby-0.10.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/send2trash-1.8.3-pyh5737063_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-scm-8.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools_scm-8.1.0-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/shapely-2.0.4-py311hcd532c9_1.conda @@ -3751,7 +3775,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.4-py311ha68e1ae_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.66.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.17-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.22-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/twine-5.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/types-python-dateutil-2.9.0.20240316-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.11.0-hd8ed1ab_0.conda @@ -3763,9 +3787,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/uriparser-0.9.8-h5a68840_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/utfcpp-4.0.5-h57928b3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-hcf57466_18.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.38.33130-h82b7239_18.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.38.33130-hcb4865c_18.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-ha32ba9b_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.38.33135-h835141b_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.38.33135-h22015db_20.conda - conda: https://conda.anaconda.org/conda-forge/win-64/vtk-9.2.6-qt_py311h1234567_220.conda - conda: https://conda.anaconda.org/conda-forge/win-64/vtk-base-9.2.6-qt_py311h1234567_220.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_0.conda @@ -3777,7 +3801,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/win32_setctime-1.1.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyhd8ed1ab_6.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/winpty-0.4.3-4.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/x264-1!164.3095-h8ffe710_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/x265-3.5-h2d74725_3.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.5.0-pyhd8ed1ab_0.conda @@ -3818,7 +3842,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hd590300_5.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.2.2-hbcca054_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-h55db66e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_7.conda @@ -3827,11 +3851,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-hd590300_5.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h59595ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.0-hd590300_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.0-h4ab18f5_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.10.12-hd12c33a_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda @@ -3843,11 +3867,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.45.3-h92b6c6a_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.2.13-h8a1eda9_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h5846eda_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.0-hd75f5a5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.0-h87427d6_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.10.12-had23ca6_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h9e318b2_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h1abcd95_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda @@ -3859,11 +3883,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.45.3-h091b4b1_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.2.13-h53f4e23_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-hb89a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.0-h0d3ecfb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.0-hfb2fe0b_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.10.12-h01493a6_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h92ec313_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda @@ -3874,16 +3898,16 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.4.2-h8ffe710_5.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.45.3-hcfcfb64_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.2.13-hcfcfb64_5.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.0-hcfcfb64_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.0-h2466b09_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.10.12-h4de0772_0_cpython.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h5226925_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-hcf57466_18.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.38.33130-h82b7239_18.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.38.33130-hcb4865c_18.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-ha32ba9b_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.38.33135-h835141b_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.38.33135-h22015db_20.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/xz-5.2.6-h8d14728_0.tar.bz2 py311: @@ -3895,7 +3919,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hd590300_5.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.2.2-hbcca054_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-h55db66e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_7.conda @@ -3904,11 +3928,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-hd590300_5.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h59595ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.0-hd590300_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.0-h4ab18f5_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.11.0-he550d4f_1_cpython.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda @@ -3920,11 +3944,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.45.3-h92b6c6a_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.2.13-h8a1eda9_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h5846eda_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.0-hd75f5a5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.0-h87427d6_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.11.0-he7542f4_1_cpython.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h9e318b2_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h1abcd95_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda @@ -3936,11 +3960,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.45.3-h091b4b1_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.2.13-h53f4e23_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-hb89a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.0-h0d3ecfb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.0-hfb2fe0b_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.11.0-h3ba56d0_1_cpython.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h92ec313_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda @@ -3951,16 +3975,16 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.4.2-h8ffe710_5.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.45.3-hcfcfb64_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.2.13-hcfcfb64_5.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.0-hcfcfb64_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.0-h2466b09_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.11.0-hcf16a7b_0_cpython.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h5226925_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-hcf57466_18.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.38.33130-h82b7239_18.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.38.33130-hcb4865c_18.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-ha32ba9b_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.38.33135-h835141b_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.38.33135-h22015db_20.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/xz-5.2.6-h8d14728_0.tar.bz2 py312: @@ -3972,7 +3996,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hd590300_5.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.2.2-hbcca054_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-h55db66e_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.6.2-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_7.conda @@ -3982,11 +4006,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-hd590300_5.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h59595ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.0-hd590300_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.0-h4ab18f5_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.12.0-hab00c5b_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda @@ -3999,11 +4023,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.45.3-h92b6c6a_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.2.13-h8a1eda9_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h5846eda_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.0-hd75f5a5_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.0-h87427d6_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.12.0-h30d4d87_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h9e318b2_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tk-8.6.13-h1abcd95_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda @@ -4016,11 +4040,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.45.3-h091b4b1_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.2.13-h53f4e23_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-hb89a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.0-h0d3ecfb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.0-hfb2fe0b_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.12.0-h47c9636_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h92ec313_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda @@ -4032,16 +4056,16 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.4.2-h8ffe710_5.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.45.3-hcfcfb64_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.2.13-hcfcfb64_5.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.0-hcfcfb64_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.0-h2466b09_3.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.12.0-h2628c8c_0_cpython.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h5226925_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-hcf57466_18.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.38.33130-h82b7239_18.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.38.33130-hcb4865c_18.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-ha32ba9b_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.38.33135-h835141b_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.38.33135-h22015db_20.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/xz-5.2.6-h8d14728_0.tar.bz2 packages: @@ -4252,6 +4276,24 @@ packages: license_family: GPL size: 554699 timestamp: 1709396557528 +- kind: conda + name: annotated-types + version: 0.7.0 + build: pyhd8ed1ab_0 + subdir: noarch + noarch: python + url: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_0.conda + sha256: 668f0825b6c18e4012ca24a0070562b6ec801ebc7008228a428eb52b4038873f + md5: 7e9f4612544c8edbfd6afad17f1bd045 + depends: + - python >=3.7 + - typing-extensions >=4.0.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/annotated-types + size: 18235 + timestamp: 1716290348421 - kind: conda name: anyio version: 4.3.0 @@ -6045,6 +6087,28 @@ packages: - pkg:pypi/html5lib size: 131220 timestamp: 1696630354218 +- kind: conda + name: bleach + version: 6.1.0 + build: pyhd8ed1ab_0 + subdir: noarch + noarch: python + url: https://conda.anaconda.org/conda-forge/noarch/bleach-6.1.0-pyhd8ed1ab_0.conda + sha256: 845e77ef495376c5c3c328ccfd746ca0ef1978150cae8eae61a300fe7755fb08 + md5: 0ed9d7c0e9afa7c025807a9a8136ea3e + depends: + - packaging + - python >=3.6 + - setuptools + - six >=1.9.0 + - webencodings + license: Apache-2.0 + license_family: Apache + purls: + - pkg:pypi/html5lib + - pkg:pypi/bleach + size: 131220 + timestamp: 1696630354218 - kind: conda name: blosc version: 1.21.5 @@ -7719,8 +7783,8 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/debugpy - pkg:pypi/bytecode + - pkg:pypi/debugpy size: 2272457 timestamp: 1707444947065 - kind: conda @@ -7739,8 +7803,8 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/debugpy - pkg:pypi/bytecode + - pkg:pypi/debugpy size: 2302395 timestamp: 1707444677899 - kind: conda @@ -7758,8 +7822,8 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/debugpy - pkg:pypi/bytecode + - pkg:pypi/debugpy size: 2241280 timestamp: 1707444917914 - kind: conda @@ -8184,13 +8248,13 @@ packages: timestamp: 1680191057827 - kind: conda name: fastcore - version: 1.5.37 + version: 1.5.38 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.37-pyhd8ed1ab_0.conda - sha256: dd863c5d18ce319ca63dcee37f0ea1592934e7d5b950bd8f251ccc8fc0e3b08c - md5: 6c03fb8012011473cf8c259c186baaa5 + url: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.38-pyhd8ed1ab_0.conda + sha256: 7a7ed120dc58ccbee58703a004260cc9b854cf7a37e6fce7e74b560c90abed61 + md5: 00f60ed1765a03e1e4d7784204d2611f depends: - packaging - pip @@ -8199,8 +8263,8 @@ packages: license_family: APACHE purls: - pkg:pypi/fastcore - size: 65697 - timestamp: 1715947551238 + size: 65435 + timestamp: 1716241472396 - kind: conda name: fasteners version: 0.17.3 @@ -8516,13 +8580,13 @@ packages: timestamp: 1709930913431 - kind: conda name: flopy - version: 3.6.0 + version: 3.7.0 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/flopy-3.6.0-pyhd8ed1ab_0.conda - sha256: 0525eddba2fb99ec250b15c79809a4d27f7bdd8f32abb61d84a5f033a9d0e40b - md5: 355fb151791096ec88146d4e7e083e13 + url: https://conda.anaconda.org/conda-forge/noarch/flopy-3.7.0-pyhd8ed1ab_0.conda + sha256: cede82da9023f5753fb7eea1d5968ab01f410fd39e23d0765c460b7b36bf006e + md5: 5e6f2953dbda961fdc3fe44a68b01f56 depends: - matplotlib-base >=1.4.0 - numpy >=1.15.0,<2.0.0 @@ -8531,8 +8595,8 @@ packages: license: CC0-1.0 purls: - pkg:pypi/flopy - size: 782991 - timestamp: 1707393859656 + size: 806923 + timestamp: 1716563541302 - kind: conda name: fltk version: 1.3.9 @@ -8882,35 +8946,35 @@ packages: timestamp: 1566932280397 - kind: conda name: fonttools - version: 4.51.0 - build: py311h05b510d_0 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.51.0-py311h05b510d_0.conda - sha256: eb302bff243557c00376f6132c70b613de58c89fb056f48dd356c418c24817a2 - md5: 24f53a9bde6f321549791406abbe7171 + version: 4.52.1 + build: py311h331c9d8_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.52.1-py311h331c9d8_0.conda + sha256: f51437c1b041aa54e2f855c281cb25c34ce8dcd0aee4690f4455486a0264360f + md5: bb70cda5777de08084a402a2cdc13935 depends: - brotli + - libgcc-ng >=12 - munkres - python >=3.11,<3.12.0a0 - - python >=3.11,<3.12.0a0 *_cpython - python_abi 3.11.* *_cp311 license: MIT license_family: MIT purls: - pkg:pypi/fonttools - size: 2779777 - timestamp: 1712345091169 + size: 2867305 + timestamp: 1716599957226 - kind: conda name: fonttools - version: 4.51.0 - build: py311h459d7ec_0 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.51.0-py311h459d7ec_0.conda - sha256: 117bc8eb7bb390911faa0b816d404d776669b088c41a9caba7b7561cd2f67970 - md5: 17e1997cc17c571d5ad27bd0159f616c + version: 4.52.1 + build: py311h72ae277_0 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/fonttools-4.52.1-py311h72ae277_0.conda + sha256: 1f5802e75da75c6965de18a3087d8c40e4930c4a6b19819a7d8464530c3b3cad + md5: ce4d32074d0359168fb7e15f86d71305 depends: + - __osx >=10.13 - brotli - - libgcc-ng >=12 - munkres - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 @@ -8918,49 +8982,51 @@ packages: license_family: MIT purls: - pkg:pypi/fonttools - size: 2827021 - timestamp: 1712344736242 + size: 2809382 + timestamp: 1716599933616 - kind: conda name: fonttools - version: 4.51.0 - build: py311ha68e1ae_0 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.51.0-py311ha68e1ae_0.conda - sha256: 7f130b53d957624bfea553cab96cf85a9d51bcf0ddcfc4e68f655bc8321cc744 - md5: 5d497f05b17751c8e4c60103aa20d2d6 + version: 4.52.1 + build: py311hd3f4193_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.52.1-py311hd3f4193_0.conda + sha256: 528c74dac3fdc173bda3511812c72d606f47341fce3f83d1aa66b869918ef8ae + md5: 43feeef0eea8c063c5376fa20202b2e2 depends: + - __osx >=11.0 - brotli - munkres - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython - python_abi 3.11.* *_cp311 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 license: MIT license_family: MIT purls: - pkg:pypi/fonttools - size: 2417702 - timestamp: 1712345179311 + size: 2774040 + timestamp: 1716600147215 - kind: conda name: fonttools - version: 4.51.0 - build: py311he705e18_0 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/fonttools-4.51.0-py311he705e18_0.conda - sha256: b3c868d3f98675b0e69530e75ee943349c98fc8e3c7c121fe123067c1a70e3bc - md5: edf0af3a7002844b5b59605c9725625b + version: 4.52.1 + build: py311he736701_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.52.1-py311he736701_0.conda + sha256: d44640193c1ace889e62096002bdc00cb129b3b1d977ecc5e9980243b259576b + md5: 7846db32c06191242745fbeafb0956cf depends: - brotli - munkres - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: MIT license_family: MIT purls: - pkg:pypi/fonttools - size: 2753573 - timestamp: 1712344918883 + size: 2465026 + timestamp: 1716600423899 - kind: conda name: fqdn version: 1.5.1 @@ -11415,13 +11481,13 @@ packages: timestamp: 1619110249723 - kind: conda name: hypothesis - version: 6.102.4 + version: 6.102.6 build: pyha770c72_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.4-pyha770c72_0.conda - sha256: 0c21a218e2d9c1e22ad709d4a9b7e612a8e600f726e17bad4f1dd162a86d69e1 - md5: d239b7d9ae557e14baa00ef02fc4fe2b + url: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.6-pyha770c72_0.conda + sha256: f1d77ab1e3492fdeb821c7b25475ae0f46f9166d335dfd28f068b0e5e7c1ab72 + md5: a00817ace8643038bbe6a08508cc4970 depends: - attrs >=19.2.0 - backports.zoneinfo >=0.2.1 @@ -11434,8 +11500,8 @@ packages: license_family: MOZILLA purls: - pkg:pypi/hypothesis - size: 330902 - timestamp: 1715758740816 + size: 330506 + timestamp: 1716516895176 - kind: conda name: icu version: '73.2' @@ -11661,16 +11727,16 @@ packages: - kind: conda name: intel-openmp version: 2024.1.0 - build: h57928b3_965 - build_number: 965 + build: h57928b3_966 + build_number: 966 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/intel-openmp-2024.1.0-h57928b3_965.conda - sha256: 7b029e476ad6d401d645636ee3e4b40130bfcc9534f7415209dd5b666c6dd292 - md5: c66eb2fd33b999ccc258aef85689758e - license: LicenseRef-ProprietaryIntel + url: https://conda.anaconda.org/conda-forge/win-64/intel-openmp-2024.1.0-h57928b3_966.conda + sha256: 77465396f2636c8b3b3a587f1636ee35c17a73e2a2c7e0ea0957b05f84704cf3 + md5: 35d7ea07ad6c878bd7240d2d6c1b8657 + license: LicenseRef-IntelSimplifiedSoftwareOct2022 license_family: Proprietary - size: 1617555 - timestamp: 1712943333029 + size: 1616293 + timestamp: 1716560867765 - kind: conda name: ipykernel version: 6.29.3 @@ -12285,13 +12351,13 @@ packages: timestamp: 1712707521811 - kind: conda name: jupyter_client - version: 8.6.1 + version: 8.6.2 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.1-pyhd8ed1ab_0.conda - sha256: c7d10d7941fd2e61480e49d3b2b21a530af4ae4b0d449a1746a72a38bacb63e2 - md5: c03972cfce69ad913d520c652e5ed908 + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_client-8.6.2-pyhd8ed1ab_0.conda + sha256: 634f065cdd1d0aacd4bb6848ebf240dcebc8578135d65f4ad4aa42b2276c4e0c + md5: 3cdbb2fa84490e5fd44c9f9806c0d292 depends: - importlib_metadata >=4.8.3 - jupyter_core >=4.12,!=5.0.* @@ -12304,8 +12370,8 @@ packages: license_family: BSD purls: - pkg:pypi/jupyter-client - size: 106042 - timestamp: 1710255955150 + size: 106248 + timestamp: 1716472312833 - kind: conda name: jupyter_console version: 6.6.3 @@ -12488,14 +12554,13 @@ packages: timestamp: 1710262791393 - kind: conda name: jupyterlab - version: 4.2.0 - build: pyhd8ed1ab_1 - build_number: 1 + version: 4.2.1 + build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.0-pyhd8ed1ab_1.conda - sha256: 0d0b14a5fc77ad76cd34191b888c8a5ce6060e553ed4d413bd2a2cd6651196ba - md5: 49af95b55515a65d14f6ea82422c321d + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.1-pyhd8ed1ab_0.conda + sha256: 507f87a6449a7d5d23ad24fcba41aed150770df18ae877a4fdf9da78039f1682 + md5: 3e7290af6190b29c7017d6a8fb0eaeea depends: - async-lru >=1.0.0 - httpx >=0.25.0 @@ -12517,8 +12582,8 @@ packages: license_family: BSD purls: - pkg:pypi/jupyterlab - size: 7982250 - timestamp: 1715435694295 + size: 7734905 + timestamp: 1716470384098 - kind: conda name: jupyterlab_pygments version: 0.3.0 @@ -12542,13 +12607,13 @@ packages: timestamp: 1707149279640 - kind: conda name: jupyterlab_server - version: 2.27.1 + version: 2.27.2 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.1-pyhd8ed1ab_0.conda - sha256: 64d7713782482a28fedd590537ff8edd737a2c736c8384366fb20a83273d233c - md5: d97923b777ce837cf67e7858ac600834 + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.2-pyhd8ed1ab_0.conda + sha256: d4b9f9f46b3c494d678b4f003d7a2f7ac834dba641bd02332079dde5a9a85c98 + md5: d1cb7b113daaadd89e5aa6a32b28bf0d depends: - babel >=2.10 - importlib-metadata >=4.8.3 @@ -12565,8 +12630,8 @@ packages: license_family: BSD purls: - pkg:pypi/jupyterlab-server - size: 49223 - timestamp: 1713899139823 + size: 49349 + timestamp: 1716434054129 - kind: conda name: jupyterlab_widgets version: 3.0.10 @@ -12647,66 +12712,72 @@ packages: - kind: conda name: kealib version: 1.5.3 - build: h210d843_0 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/kealib-1.5.3-h210d843_0.conda - sha256: f9bae19e49eda17d32b1ca6cabe501e09b00ba10f6d061fc8a14086a8455710e - md5: 0153b4907333b9005f48d19584e4153e + build: h6c43f9b_1 + build_number: 1 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/kealib-1.5.3-h6c43f9b_1.conda + sha256: b4b2cee0ad62ae1f8e4a541d34074c575df935682c023fdf1c21c9c5c9995fa9 + md5: a20c9e3598a55ca3e61cad90ef33ada3 depends: - hdf5 >=1.14.3,<1.14.4.0a0 - - libcxx >=15 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: MIT license_family: MIT - size: 139228 - timestamp: 1703116483044 + size: 133355 + timestamp: 1716158947179 - kind: conda name: kealib version: 1.5.3 - build: h2f55d51_0 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/kealib-1.5.3-h2f55d51_0.conda - sha256: ee0934ff426d3cab015055808bed33eb9d20f635ec14bc421c596f4b70927102 - md5: f7e7077802927590efc8bf7328208f12 + build: h848a2d4_1 + build_number: 1 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/kealib-1.5.3-h848a2d4_1.conda + sha256: f17ee2e89bce1923222148956c3b3ab2e859b60f82568a3241593239a8412546 + md5: dafdda3213a216870027af0c76f204c7 depends: + - __osx >=11.0 - hdf5 >=1.14.3,<1.14.4.0a0 - - libgcc-ng >=12 - - libstdcxx-ng >=12 + - libcxx >=16 license: MIT license_family: MIT - size: 172990 - timestamp: 1703115976887 + size: 142911 + timestamp: 1716158475936 - kind: conda name: kealib version: 1.5.3 - build: h5f07ac3_0 + build: hb2b617a_1 + build_number: 1 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/kealib-1.5.3-h5f07ac3_0.conda - sha256: 54a847faf2d2aea83c149d98634646edb8e7f346faefc6af1aa52106200b43aa - md5: 7a0924f6214e4c17b6062b21d1240253 + url: https://conda.anaconda.org/conda-forge/osx-64/kealib-1.5.3-hb2b617a_1.conda + sha256: 3150dedf047284e8b808a169dfe630d818d8513b79d08a5404b90973c61c6914 + md5: e24e1fa559fd29c34593d6a47b459443 depends: + - __osx >=10.13 - hdf5 >=1.14.3,<1.14.4.0a0 - - libcxx >=15 + - libcxx >=16 license: MIT license_family: MIT - size: 149513 - timestamp: 1703116284587 + size: 152270 + timestamp: 1716158359765 - kind: conda name: kealib version: 1.5.3 - build: hd248416_0 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/kealib-1.5.3-hd248416_0.conda - sha256: 833a9f8acc1982a174267f8cd12d161cbafc42fdaeb7beb075975977b5ee56f5 - md5: b65b0092dade29117f6e87c8d11a2394 + build: hee9dde6_1 + build_number: 1 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/kealib-1.5.3-hee9dde6_1.conda + sha256: d607ddb5906a335cb3665dd81f3adec4af248cf398147693b470b65d887408e7 + md5: c5b7b29e2b66107553d0366538257a51 depends: - hdf5 >=1.14.3,<1.14.4.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - libgcc-ng >=12 + - libstdcxx-ng >=12 license: MIT license_family: MIT - size: 133421 - timestamp: 1703116732437 + size: 170709 + timestamp: 1716158265533 - kind: conda name: keyring version: 25.2.1 @@ -13050,17 +13121,17 @@ packages: - kind: conda name: ld_impl_linux-64 version: '2.40' - build: h55db66e_0 + build: hf3520f5_1 + build_number: 1 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-h55db66e_0.conda - sha256: ef969eee228cfb71e55146eaecc6af065f468cb0bc0a5239bc053b39db0b5f09 - md5: 10569984e7db886e4f1abc2b47ad79a1 + url: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_1.conda + sha256: cb54a873c1c84c47f7174093889686b626946b8143905ec0f76a56785b26a304 + md5: 33b7851c39c25da14f6a233a8ccbeeca constrains: - binutils_impl_linux-64 2.40 license: GPL-3.0-only - license_family: GPL - size: 713322 - timestamp: 1713651222435 + size: 707934 + timestamp: 1716583433869 - kind: conda name: lerc version: 4.0.0 @@ -13252,98 +13323,96 @@ packages: timestamp: 1711021498493 - kind: conda name: libarchive - version: 3.7.2 - build: h2aa1ff5_1 - build_number: 1 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.7.2-h2aa1ff5_1.conda - sha256: 340ed0bb02fe26a2b2e29cedf6559e2999b820f434e745c108e788d629ae4b17 - md5: 3bf887827d1968275978361a6e405e4f + version: 3.7.4 + build: h20e244c_0 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/libarchive-3.7.4-h20e244c_0.conda + sha256: 9e46db25e976630e6738b351d76d9b79047ae232638b82f9f45eba774caaef8a + md5: 82a85fa38e83366009b7f4b2cef4deb8 depends: + - __osx >=10.13 - bzip2 >=1.0.8,<2.0a0 - - libgcc-ng >=12 - - libxml2 >=2.12.2,<3.0.0a0 + - libiconv >=1.17,<2.0a0 + - libxml2 >=2.12.7,<3.0a0 - libzlib >=1.2.13,<1.3.0a0 - lz4-c >=1.9.3,<1.10.0a0 - lzo >=2.10,<3.0a0 - - openssl >=3.2.0,<4.0a0 + - openssl >=3.3.0,<4.0a0 - xz >=5.2.6,<6.0a0 - - zstd >=1.5.5,<1.6.0a0 + - zstd >=1.5.6,<1.6.0a0 license: BSD-2-Clause license_family: BSD - size: 866168 - timestamp: 1701994227275 + size: 742682 + timestamp: 1716394747351 - kind: conda name: libarchive - version: 3.7.2 - build: h313118b_1 - build_number: 1 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libarchive-3.7.2-h313118b_1.conda - sha256: 8dd608299e8bc56e0337c6653028e552fea8b952af10fbcc2f4008274add11a1 - md5: 4b84938cdb30e9cc2dc413208e917e11 + version: 3.7.4 + build: h83d404f_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libarchive-3.7.4-h83d404f_0.conda + sha256: 5301d7dc52c2e1f87b229606033c475caf87cd94ef5a5efb3af565a62b88127e + md5: 8b604ee634caafd92f2ff2fab6a1f75a depends: + - __osx >=11.0 - bzip2 >=1.0.8,<2.0a0 - - libxml2 >=2.12.2,<3.0.0a0 + - libiconv >=1.17,<2.0a0 + - libxml2 >=2.12.7,<3.0a0 - libzlib >=1.2.13,<1.3.0a0 - lz4-c >=1.9.3,<1.10.0a0 - lzo >=2.10,<3.0a0 - - openssl >=3.2.0,<4.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - openssl >=3.3.0,<4.0a0 - xz >=5.2.6,<6.0a0 - - zstd >=1.5.5,<1.6.0a0 + - zstd >=1.5.6,<1.6.0a0 license: BSD-2-Clause license_family: BSD - size: 964623 - timestamp: 1701994828221 + size: 775700 + timestamp: 1716394811506 - kind: conda name: libarchive - version: 3.7.2 - build: hcacb583_1 - build_number: 1 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libarchive-3.7.2-hcacb583_1.conda - sha256: 307dd9984deccab782a834022a708ba070950d3d0f3b370ce9331ad1db013576 - md5: 1c8c447ce71bf5f769674b621142a73a + version: 3.7.4 + build: haf234dc_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/libarchive-3.7.4-haf234dc_0.conda + sha256: 3ab13c269949874c4538b22eeb83a36d2c55b4a4ea6628bef1bab4c724ee5a1b + md5: 86de12ebf8d7fffeba4ca9dbf13e9733 depends: - bzip2 >=1.0.8,<2.0a0 - - libiconv >=1.17,<2.0a0 - - libxml2 >=2.12.2,<3.0.0a0 + - libxml2 >=2.12.7,<3.0a0 - libzlib >=1.2.13,<1.3.0a0 - lz4-c >=1.9.3,<1.10.0a0 - lzo >=2.10,<3.0a0 - - openssl >=3.2.0,<4.0a0 + - openssl >=3.3.0,<4.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 - xz >=5.2.6,<6.0a0 - - zstd >=1.5.5,<1.6.0a0 + - zstd >=1.5.6,<1.6.0a0 license: BSD-2-Clause license_family: BSD - size: 783812 - timestamp: 1701994487530 + size: 957632 + timestamp: 1716395481752 - kind: conda name: libarchive - version: 3.7.2 - build: hd35d340_1 - build_number: 1 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/libarchive-3.7.2-hd35d340_1.conda - sha256: f458515a49c56e117e05fe607493b7683a7bf06d2a625b59e378dbbf7f308895 - md5: 8c7b79b20a67287a87b39df8a8c8dcc4 + version: 3.7.4 + build: hfca40fe_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.7.4-hfca40fe_0.conda + sha256: c30970e5e6515c662d00bb74e7c1b09ebe0c8c92c772b952a41a5725e2dcc936 + md5: 32ddb97f897740641d8d46a829ce1704 depends: - bzip2 >=1.0.8,<2.0a0 - - libiconv >=1.17,<2.0a0 - - libxml2 >=2.12.2,<3.0.0a0 + - libgcc-ng >=12 + - libxml2 >=2.12.7,<3.0a0 - libzlib >=1.2.13,<1.3.0a0 - lz4-c >=1.9.3,<1.10.0a0 - lzo >=2.10,<3.0a0 - - openssl >=3.2.0,<4.0a0 + - openssl >=3.3.0,<4.0a0 - xz >=5.2.6,<6.0a0 - - zstd >=1.5.5,<1.6.0a0 + - zstd >=1.5.6,<1.6.0a0 license: BSD-2-Clause license_family: BSD - size: 745686 - timestamp: 1701994485309 + size: 871853 + timestamp: 1716394516418 - kind: conda name: libarrow version: 15.0.2 @@ -14796,70 +14865,51 @@ packages: timestamp: 1689195353551 - kind: conda name: libcurl - version: 8.7.1 - build: h2d989ff_0 + version: 8.8.0 + build: h7b6f9a7_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.7.1-h2d989ff_0.conda - sha256: 973ac9368efca712a8fd19fe68524d7d9a3087fd88ad6b7fcdf60c3d2e19a498 - md5: 34b9171710f0d9bf093d55bdc36ff355 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.8.0-h7b6f9a7_0.conda + sha256: b83aa249e7c8abc1aa56593ad50d1b4c0a52f5f3d5fd7c489c2ccfc3a548f391 + md5: 245b30f99dc5379ebe1c78899be8d3f5 depends: - krb5 >=1.21.2,<1.22.0a0 - libnghttp2 >=1.58.0,<2.0a0 - libssh2 >=1.11.0,<2.0a0 - libzlib >=1.2.13,<1.3.0a0 - - openssl >=3.2.1,<4.0a0 - - zstd >=1.5.5,<1.6.0a0 - license: curl - license_family: MIT - size: 358080 - timestamp: 1711548548174 -- kind: conda - name: libcurl - version: 8.7.1 - build: h726d00d_0 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.7.1-h726d00d_0.conda - sha256: 06cb1bd3bbaf905213777d6ade190ac4c7fb7a20dfe0cf901c977dbbc6cec265 - md5: fa58e5eaa12006bc3289a71357bef167 - depends: - - krb5 >=1.21.2,<1.22.0a0 - - libnghttp2 >=1.58.0,<2.0a0 - - libssh2 >=1.11.0,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 - - openssl >=3.2.1,<4.0a0 - - zstd >=1.5.5,<1.6.0a0 + - openssl >=3.3.0,<4.0a0 + - zstd >=1.5.6,<1.6.0a0 license: curl license_family: MIT - size: 378176 - timestamp: 1711548390530 + size: 364890 + timestamp: 1716378993833 - kind: conda name: libcurl - version: 8.7.1 + version: 8.8.0 build: hca28451_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.7.1-hca28451_0.conda - sha256: 82a75e9a5d9ee5b2f487d850ec5d4edc18a56eb9527608a95a916c40baae3843 - md5: 755c7f876815003337d2c61ff5d047e5 + url: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.8.0-hca28451_0.conda + sha256: 45aec0ffc6fe3fd4c0083b815aa102b8103380acc2b6714fb272d921acc68ab2 + md5: f21c27f076a07907e70c49bb57bd0f20 depends: - krb5 >=1.21.2,<1.22.0a0 - libgcc-ng >=12 - libnghttp2 >=1.58.0,<2.0a0 - libssh2 >=1.11.0,<2.0a0 - libzlib >=1.2.13,<1.3.0a0 - - openssl >=3.2.1,<4.0a0 - - zstd >=1.5.5,<1.6.0a0 + - openssl >=3.3.0,<4.0a0 + - zstd >=1.5.6,<1.6.0a0 license: curl license_family: MIT - size: 398293 - timestamp: 1711548114077 + size: 405535 + timestamp: 1716378550673 - kind: conda name: libcurl - version: 8.7.1 + version: 8.8.0 build: hd5e4a3a_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.7.1-hd5e4a3a_0.conda - sha256: 8dd272362e2aeb1d4f49333ff57e07eb4da2bbabce20110a2416df9152ba03e0 - md5: 3396aff340d0903e8814c2852d631e4e + url: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.8.0-hd5e4a3a_0.conda + sha256: 169fb0a11dd3a1f0adbb93b275f9752aa24b64e73d0c8e220aa10213c6ee74ff + md5: 4f86149dc6228f1e5617faa2cce90f94 depends: - krb5 >=1.21.2,<1.22.0a0 - libssh2 >=1.11.0,<2.0a0 @@ -14869,8 +14919,27 @@ packages: - vc14_runtime >=14.29.30139 license: curl license_family: MIT - size: 331262 - timestamp: 1711548608132 + size: 334903 + timestamp: 1716379079949 +- kind: conda + name: libcurl + version: 8.8.0 + build: hf9fcc65_0 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/libcurl-8.8.0-hf9fcc65_0.conda + sha256: 1eb3e00586ddbf662877e62d1108bd2ff539fbeee34c52edf1d6c5fa3c9f4435 + md5: 276894efcbca23aa674e280e90bc5673 + depends: + - krb5 >=1.21.2,<1.22.0a0 + - libnghttp2 >=1.58.0,<2.0a0 + - libssh2 >=1.11.0,<2.0a0 + - libzlib >=1.2.13,<1.3.0a0 + - openssl >=3.3.0,<4.0a0 + - zstd >=1.5.6,<1.6.0a0 + license: curl + license_family: MIT + size: 385778 + timestamp: 1716378974624 - kind: conda name: libcxx version: 17.0.6 @@ -22494,71 +22563,77 @@ packages: - kind: conda name: openssl version: 3.3.0 - build: h0d3ecfb_0 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.0-h0d3ecfb_0.conda - sha256: 51f9be8fe929c2bb3243cd0707b6dfcec27541f8284b4bd9b063c288fc46f482 - md5: 25b0e522c3131886a637e347b2ca0c0f + build: h2466b09_3 + build_number: 3 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.0-h2466b09_3.conda + sha256: 11b2513fceb20102bdc7f7656a59005acb9ecd0886b7cbfb9c13c2c953f2429b + md5: d7fec5d3bb8fc0c8e266bf1ad350cec5 depends: - ca-certificates + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 constrains: - pyopenssl >=22.1 license: Apache-2.0 license_family: Apache - size: 2888226 - timestamp: 1714466346030 + size: 8368468 + timestamp: 1716471282135 - kind: conda name: openssl version: 3.3.0 - build: hcfcfb64_0 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.0-hcfcfb64_0.conda - sha256: ca7573b7503711b53b2464fa35e4efa6f89dcd3d436fb5f128722b853e356dfd - md5: a6c544c9f060740c625dbf6d92cf3495 + build: h4ab18f5_3 + build_number: 3 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.0-h4ab18f5_3.conda + sha256: 33dcea0ed3a61b2de6b66661cdd55278640eb99d676cd129fbff3e53641fa125 + md5: 12ea6d0d4ed54530eaed18e4835c1f7c depends: - ca-certificates - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - libgcc-ng >=12 constrains: - pyopenssl >=22.1 license: Apache-2.0 license_family: Apache - size: 8358240 - timestamp: 1714468180752 + size: 2891147 + timestamp: 1716468354865 - kind: conda name: openssl version: 3.3.0 - build: hd590300_0 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.0-hd590300_0.conda - sha256: fdbf05e4db88c592366c90bb82e446edbe33c6e49e5130d51c580b2629c0b5d5 - md5: c0f3abb4a16477208bbd43a39bd56f18 + build: h87427d6_3 + build_number: 3 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.0-h87427d6_3.conda + sha256: 58ffbdce44ac18c6632a2ce1531d06e3fb2e855d40728ba3a2b709158b9a1c33 + md5: ec504fefb403644d893adffb6e7a2dbe depends: + - __osx >=10.13 - ca-certificates - - libgcc-ng >=12 constrains: - pyopenssl >=22.1 license: Apache-2.0 license_family: Apache - size: 2895187 - timestamp: 1714466138265 + size: 2542959 + timestamp: 1716468436467 - kind: conda name: openssl version: 3.3.0 - build: hd75f5a5_0 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.0-hd75f5a5_0.conda - sha256: d3889b0c89c2742e92e20f01e8f298b64c221df5d577c639b823a0bfe314e2e3 - md5: eb8c33aa7929a7714eab8b90c1d88afe + build: hfb2fe0b_3 + build_number: 3 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.0-hfb2fe0b_3.conda + sha256: 6f41c163ab57e7499dff092be4498614651f0f6432e12c2b9f06859a8bc39b75 + md5: 730f618b008b3c13c1e3f973408ddd67 depends: + - __osx >=11.0 - ca-certificates constrains: - pyopenssl >=22.1 license: Apache-2.0 license_family: Apache - size: 2541802 - timestamp: 1714467068742 + size: 2893954 + timestamp: 1716468329572 - kind: conda name: orc version: 2.0.0 @@ -24335,6 +24410,109 @@ packages: - pkg:pypi/pycparser size: 105098 timestamp: 1711811634025 +- kind: conda + name: pydantic + version: 2.7.1 + build: pyhd8ed1ab_0 + subdir: noarch + noarch: python + url: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.1-pyhd8ed1ab_0.conda + sha256: 176862eeca911df9e21a239a19cee1608f899f969e7bc3b3df1da63aaf97c42b + md5: f5dac044e2aaccf73b85053f6db360b5 + depends: + - annotated-types >=0.4.0 + - pydantic-core 2.18.2 + - python >=3.7 + - typing-extensions >=4.6.1 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pydantic + size: 282275 + timestamp: 1713905769522 +- kind: conda + name: pydantic-core + version: 2.18.2 + build: py311h2786eb7_0 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.18.2-py311h2786eb7_0.conda + sha256: 4d248c3885923fd351c2e5550f24d5839939213980e6341de17fe34c5959fccb + md5: c8826b4af1d40b4f73879cacfbc38a21 + depends: + - __osx >=10.12 + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - typing-extensions >=4.6.0,!=4.7.0 + constrains: + - __osx >=10.12 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pydantic-core + size: 1547397 + timestamp: 1713862554543 +- kind: conda + name: pydantic-core + version: 2.18.2 + build: py311h533ab2d_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.18.2-py311h533ab2d_0.conda + sha256: fe4f47005534f327b7ebc93c832d734096d582b7bb5ca45740e83d3f1704ebac + md5: 1234b7b8ac68b728d48df4a04cab7553 + depends: + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - typing-extensions >=4.6.0,!=4.7.0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pydantic-core + size: 1573013 + timestamp: 1713862871656 +- kind: conda + name: pydantic-core + version: 2.18.2 + build: py311h5d190b6_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.18.2-py311h5d190b6_0.conda + sha256: df7966a775e5ac77025f804dee9f29b2cd61958963c71b90266f4e40c098781f + md5: a3634cb616e56058c5d887e092dfa18d + depends: + - __osx >=11.0 + - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython + - python_abi 3.11.* *_cp311 + - typing-extensions >=4.6.0,!=4.7.0 + constrains: + - __osx >=11.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pydantic-core + size: 1446637 + timestamp: 1713862610908 +- kind: conda + name: pydantic-core + version: 2.18.2 + build: py311h5ecf98a_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.18.2-py311h5ecf98a_0.conda + sha256: 111af1d677aaff1b386090872c3009b8989941684af63605fd7700d2b1c99da9 + md5: 0935eb48085bd65556bb16488866bb47 + depends: + - libgcc-ng >=12 + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + - typing-extensions >=4.6.0,!=4.7.0 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pydantic-core + size: 1617503 + timestamp: 1713862117041 - kind: conda name: pydata-sphinx-theme version: 0.15.2 @@ -26175,13 +26353,13 @@ packages: timestamp: 1714619625532 - kind: conda name: requests - version: 2.31.0 + version: 2.32.2 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/requests-2.31.0-pyhd8ed1ab_0.conda - sha256: 9f629d6fd3c8ac5f2a198639fe7af87c4db2ac9235279164bfe0fcb49d8c4bad - md5: a30144e4156cdbb236f99ebb49828f8b + url: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.2-pyhd8ed1ab_0.conda + sha256: 115b796fddc846bee6f47e3c57d04d12fa93a47a7a8ef639cefdc05203c1bf00 + md5: e1643b34b19df8c028a4f00bf5df58a6 depends: - certifi >=2017.4.17 - charset-normalizer >=2,<4 @@ -26194,8 +26372,8 @@ packages: license_family: APACHE purls: - pkg:pypi/requests - size: 56690 - timestamp: 1684774408600 + size: 57885 + timestamp: 1716354575895 - kind: conda name: requests-toolbelt version: 1.0.0 @@ -26463,12 +26641,12 @@ packages: timestamp: 1705698221128 - kind: conda name: ruff - version: 0.4.4 - build: py311h148dfb1_0 + version: 0.4.5 + build: py311h9a97b26_0 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.4.4-py311h148dfb1_0.conda - sha256: 4958b7ad1a4a81213ce0a9c09e58cd02f1cf30b078a83e071c83e6d3c77c6a69 - md5: cef91564767c889c9ecf93b55f2019a8 + url: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.4.5-py311h9a97b26_0.conda + sha256: 41a3f0fedb259e35b9a36a897d691272d1bae0ca7895779cfe5be66c301a703f + md5: 49c4fbc7dc7937c175a630a821662fd3 depends: - __osx >=10.13 - libcxx >=16 @@ -26480,16 +26658,16 @@ packages: license_family: MIT purls: - pkg:pypi/ruff - size: 6081260 - timestamp: 1715290991063 + size: 6157307 + timestamp: 1716663909398 - kind: conda name: ruff - version: 0.4.4 + version: 0.4.5 build: py311ha637bb9_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/ruff-0.4.4-py311ha637bb9_0.conda - sha256: 682509e4882b048b50618414e0f13da2168f9943f79a8a2fe1f2dea5a46bc80c - md5: aa48d308400b3ac5f52cee7a13410e1b + url: https://conda.anaconda.org/conda-forge/win-64/ruff-0.4.5-py311ha637bb9_0.conda + sha256: 6fbb33bd5f61c09dd65fc4b980d4cff4042c3645207fef6b94048ff90454bba6 + md5: 9fcf089b1b221784828f730ba94f6aa5 depends: - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 @@ -26500,16 +26678,16 @@ packages: license_family: MIT purls: - pkg:pypi/ruff - size: 6195301 - timestamp: 1715291134485 + size: 6304897 + timestamp: 1716664840002 - kind: conda name: ruff - version: 0.4.4 + version: 0.4.5 build: py311hae69bc3_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.4.4-py311hae69bc3_0.conda - sha256: cb6410c19ca43fbc4434bfa453112a19b3723835ee6afe2f21b3a68cbddcecfa - md5: f73b29a9123e36bac882516229ca100d + url: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.4.5-py311hae69bc3_0.conda + sha256: 97cc0b3427c087390fd4280c2d23ced896766ae5addb6689fba949c678b365d8 + md5: d386545bc0cda284346ba0cb69d0beeb depends: - libgcc-ng >=12 - libstdcxx-ng >=12 @@ -26519,16 +26697,16 @@ packages: license_family: MIT purls: - pkg:pypi/ruff - size: 6282727 - timestamp: 1715289638058 + size: 6385504 + timestamp: 1716663699654 - kind: conda name: ruff - version: 0.4.4 + version: 0.4.5 build: py311hd374d79_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.4.4-py311hd374d79_0.conda - sha256: 00199058a448a6efe1b856a4b6b258fd664ec3ac1836af0c659c7a00c513fc31 - md5: 4f8025e6fc8f40062a87cbe5e0240182 + url: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.4.5-py311hd374d79_0.conda + sha256: 4a5b506c50d3cb2e23da83fb3c414e929a82062f425034531d6ac7572bd89f18 + md5: 64ee770a55753ed7e2b4630c481eb7f7 depends: - __osx >=11.0 - libcxx >=16 @@ -26541,8 +26719,8 @@ packages: license_family: MIT purls: - pkg:pypi/ruff - size: 5809315 - timestamp: 1715290267564 + size: 5875862 + timestamp: 1716663891215 - kind: conda name: s2n version: 1.4.12 @@ -26560,73 +26738,71 @@ packages: timestamp: 1713325107791 - kind: conda name: scikit-learn - version: 1.4.2 + version: 1.5.0 build: py311h3c3ac6d_1 build_number: 1 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/scikit-learn-1.4.2-py311h3c3ac6d_1.conda - sha256: 2cf5eba017eb53d09dcad6116615cb2209321d134e46f4501c4bd435525db156 - md5: eb6f2d36c84d6702eab64ffbe166f3fa + url: https://conda.anaconda.org/conda-forge/osx-64/scikit-learn-1.5.0-py311h3c3ac6d_1.conda + sha256: b056a9cc59711b2f86d114289a3d8800e9057ebc15a2bd0659f4c8326b8a89fe + md5: d8edd327c45efef9fb9319c85c08226d depends: - __osx >=10.13 - joblib >=1.2.0 - libcxx >=16 - llvm-openmp >=16.0.6 - - llvm-openmp >=18.1.5 - numpy >=1.19,<3 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 - scipy - - threadpoolctl >=2.0.0 + - threadpoolctl >=3.1.0 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/scikit-learn - size: 9363425 - timestamp: 1715869957926 + size: 9693995 + timestamp: 1716490407141 - kind: conda name: scikit-learn - version: 1.4.2 + version: 1.5.0 build: py311hbfb48bc_1 build_number: 1 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/scikit-learn-1.4.2-py311hbfb48bc_1.conda - sha256: e21e11fee63202ba6dc59df71af1db16351468b0a8c742a7080b1cb2f852c59a - md5: eb4b192b29d412853c75a15102dfd832 + url: https://conda.anaconda.org/conda-forge/osx-arm64/scikit-learn-1.5.0-py311hbfb48bc_1.conda + sha256: 95fe4cf505effa93a734508b77fef4bba0e6d396f8d0a077b10d4f5873fca561 + md5: f80b6aacea4b2e164efeb011e619015d depends: - __osx >=11.0 - joblib >=1.2.0 - libcxx >=16 - llvm-openmp >=16.0.6 - - llvm-openmp >=18.1.5 - numpy >=1.19,<3 - python >=3.11,<3.12.0a0 - python >=3.11,<3.12.0a0 *_cpython - python_abi 3.11.* *_cp311 - scipy - - threadpoolctl >=2.0.0 + - threadpoolctl >=3.1.0 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/scikit-learn - size: 9449312 - timestamp: 1715870005992 + size: 9717750 + timestamp: 1716490464370 - kind: conda name: scikit-learn - version: 1.4.2 + version: 1.5.0 build: py311hdcb8d17_1 build_number: 1 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/scikit-learn-1.4.2-py311hdcb8d17_1.conda - sha256: e38cac2faa50b04ae06da6a7c9690ad8f893f2b3318b052ac15710221f32e231 - md5: 4179839852432a4e95b5ff86dd5faa9c + url: https://conda.anaconda.org/conda-forge/win-64/scikit-learn-1.5.0-py311hdcb8d17_1.conda + sha256: 207fcefb67c23162b4cf25d5ce984443dbb55642745cd596e82337c423c8b0c4 + md5: ed198cc4457b2034ee1028adacd8124d depends: - joblib >=1.2.0 - numpy >=1.19,<3 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 - scipy - - threadpoolctl >=2.0.0 + - threadpoolctl >=3.1.0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 @@ -26634,17 +26810,17 @@ packages: license_family: BSD purls: - pkg:pypi/scikit-learn - size: 9070251 - timestamp: 1715870319512 + size: 9469162 + timestamp: 1716491005147 - kind: conda name: scikit-learn - version: 1.4.2 + version: 1.5.0 build: py311he08f58d_1 build_number: 1 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/scikit-learn-1.4.2-py311he08f58d_1.conda - sha256: b818f7df6ae949012a38b41b6577ac2319569971b1a063c0386447ec2c6c09ed - md5: fd4a80e35c05513590b33c83fc81dcc7 + url: https://conda.anaconda.org/conda-forge/linux-64/scikit-learn-1.5.0-py311he08f58d_1.conda + sha256: 8f4150216761b2dcd5d55066c74c46fd3a2bc823178c730acd18bf050f85ef8a + md5: d55e4dde3b30272090f33ddd367c580b depends: - _openmp_mutex >=4.5 - joblib >=1.2.0 @@ -26654,30 +26830,30 @@ packages: - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 - scipy - - threadpoolctl >=2.0.0 + - threadpoolctl >=3.1.0 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/scikit-learn - size: 10331975 - timestamp: 1715869752060 + size: 10543139 + timestamp: 1716490200240 - kind: conda name: scipy - version: 1.13.0 - build: py311h517d4fd_1 - build_number: 1 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/scipy-1.13.0-py311h517d4fd_1.conda - sha256: dd14400515cf0ee248293b85a0f4b9f989a430f28e5611db5dff2eee56127816 - md5: a86b8bea39e292a23b2cf9a750f49ea1 + version: 1.13.1 + build: py311h40a1ab3_0 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/scipy-1.13.1-py311h40a1ab3_0.conda + sha256: 058a04f1c13a6812884c1bcc9295b2b259ef48685ad30ce8c24e86226e7a43b4 + md5: e7f86277ec9b453bdf2fc1ef54740033 depends: + - __osx >=10.13 - libblas >=3.9.0,<4.0a0 - libcblas >=3.9.0,<4.0a0 - - libgcc-ng >=12 - - libgfortran-ng + - libcxx >=16 + - libgfortran 5.* - libgfortran5 >=12.3.0 + - libgfortran5 >=13.2.0 - liblapack >=3.9.0,<4.0a0 - - libstdcxx-ng >=12 - numpy <2.3 - numpy >=1.19,<3 - python >=3.11,<3.12.0a0 @@ -26686,91 +26862,87 @@ packages: license_family: BSD purls: - pkg:pypi/scipy - size: 17260178 - timestamp: 1714795125642 + size: 16418198 + timestamp: 1716471483674 - kind: conda name: scipy - version: 1.13.0 - build: py311hceeca8c_1 - build_number: 1 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.13.0-py311hceeca8c_1.conda - sha256: 466ef6d19091ad5a8dce8c499cc54d29f0dcb396331900b2080424d52fa15232 - md5: be406411b55eab396da245dbf63eb865 + version: 1.13.1 + build: py311h517d4fd_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/scipy-1.13.1-py311h517d4fd_0.conda + sha256: f2312e5565f39308639f982729c151c2c75d5eaf86ac2863e19765f9797f7f3b + md5: 764b0e055f59dbd7d114d32b8c6e55e6 depends: - - __osx >=11.0 - libblas >=3.9.0,<4.0a0 - libcblas >=3.9.0,<4.0a0 - - libcxx >=16 - - libgfortran 5.* + - libgcc-ng >=12 + - libgfortran-ng - libgfortran5 >=12.3.0 - - libgfortran5 >=13.2.0 - liblapack >=3.9.0,<4.0a0 + - libstdcxx-ng >=12 - numpy <2.3 - numpy >=1.19,<3 - python >=3.11,<3.12.0a0 - - python >=3.11,<3.12.0a0 *_cpython - python_abi 3.11.* *_cp311 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/scipy - size: 15627072 - timestamp: 1714796789637 + size: 17347738 + timestamp: 1716471208504 - kind: conda name: scipy - version: 1.13.0 - build: py311hd4686c6_1 - build_number: 1 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/scipy-1.13.0-py311hd4686c6_1.conda - sha256: fac9e20c3bd0371ea325ad62f978c9db3fa1591b8ddd0e67c7caa4888174b418 - md5: f01532161760c8e09c4f21a7e9a1e16e + version: 1.13.1 + build: py311hceeca8c_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.13.1-py311hceeca8c_0.conda + sha256: 5fd68198ac99720a1cfc3d5e4f534909917ab02b5feb8bc6a70553f54ae65fb7 + md5: af2deddee1cc1f11a8a5799a64ecfe3a depends: + - __osx >=11.0 - libblas >=3.9.0,<4.0a0 - libcblas >=3.9.0,<4.0a0 + - libcxx >=16 + - libgfortran 5.* + - libgfortran5 >=12.3.0 + - libgfortran5 >=13.2.0 - liblapack >=3.9.0,<4.0a0 - numpy <2.3 - numpy >=1.19,<3 - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython - python_abi 3.11.* *_cp311 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/scipy - size: 15753538 - timestamp: 1714796604770 + size: 15597027 + timestamp: 1716471638954 - kind: conda name: scipy - version: 1.13.0 - build: py311hd5d9b8d_1 - build_number: 1 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/scipy-1.13.0-py311hd5d9b8d_1.conda - sha256: be28ef6313697646211ca2e64850c137ff1cac7f06c9a7a26b8393b58ba616d5 - md5: a6c59edf565f6e1484913893ddfffe19 + version: 1.13.1 + build: py311hd4686c6_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/scipy-1.13.1-py311hd4686c6_0.conda + sha256: d692402c159ab3c23a722d3d168b013f21193ab01ce1a913582e6db7fe2f0ecf + md5: 980070a1c48686998f8256d0c4d76cf2 depends: - - __osx >=10.9 - libblas >=3.9.0,<4.0a0 - libcblas >=3.9.0,<4.0a0 - - libcxx >=16 - - libgfortran 5.* - - libgfortran5 >=12.3.0 - - libgfortran5 >=13.2.0 - liblapack >=3.9.0,<4.0a0 - numpy <2.3 - numpy >=1.19,<3 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/scipy - size: 16553685 - timestamp: 1714795053678 + size: 15555238 + timestamp: 1716472827028 - kind: conda name: scooby version: 0.10.0 @@ -26867,36 +27039,36 @@ packages: timestamp: 1712585816346 - kind: conda name: setuptools - version: 69.5.1 + version: 70.0.0 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda - sha256: 72d143408507043628b32bed089730b6d5f5445eccc44b59911ec9f262e365e7 - md5: 7462280d81f639363e6e63c81276bd9e + url: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda + sha256: daa4638d288cfdf3b0ecea395d8efa25cafc4ebf4026464a36c797c84541d2be + md5: c8ddb4f34a208df4dd42509a0f6a1c89 depends: - python >=3.8 license: MIT license_family: MIT purls: - pkg:pypi/setuptools - size: 501790 - timestamp: 1713094963112 + size: 483015 + timestamp: 1716368141661 - kind: conda name: setuptools - version: 69.5.1 + version: 70.0.0 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/setuptools-69.5.1-pyhd8ed1ab_0.conda - sha256: 72d143408507043628b32bed089730b6d5f5445eccc44b59911ec9f262e365e7 - md5: 7462280d81f639363e6e63c81276bd9e + url: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda + sha256: daa4638d288cfdf3b0ecea395d8efa25cafc4ebf4026464a36c797c84541d2be + md5: c8ddb4f34a208df4dd42509a0f6a1c89 depends: - python >=3.8 license: MIT license_family: MIT - size: 501790 - timestamp: 1713094963112 + size: 483015 + timestamp: 1716368141661 - kind: conda name: setuptools-scm version: 8.1.0 @@ -27621,6 +27793,7 @@ packages: - libhwloc >=2.10.0,<2.10.1.0a0 - libstdcxx-ng >=12 license: Apache-2.0 + license_family: APACHE size: 194111 timestamp: 1716030795319 - kind: conda @@ -27637,6 +27810,7 @@ packages: - libcxx >=16 - libhwloc >=2.10.0,<2.10.1.0a0 license: Apache-2.0 + license_family: APACHE size: 172122 timestamp: 1716030842899 - kind: conda @@ -27653,6 +27827,7 @@ packages: - libcxx >=16 - libhwloc >=2.10.0,<2.10.1.0a0 license: Apache-2.0 + license_family: APACHE size: 127893 timestamp: 1716030910416 - kind: conda @@ -27670,6 +27845,7 @@ packages: - vc >=14.2,<15 - vc14_runtime >=14.29.30139 license: Apache-2.0 + license_family: APACHE size: 161771 timestamp: 1716031112705 - kind: conda @@ -28219,21 +28395,21 @@ packages: timestamp: 1713535244513 - kind: conda name: trove-classifiers - version: 2024.5.17 + version: 2024.5.22 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.17-pyhd8ed1ab_0.conda - sha256: 37da4db453e80f88965ee945565f6a28f6dcf4c00bc62f2f3c4c83ee219609a3 - md5: af83a15fac578ddf2a621ad195986c37 + url: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.22-pyhd8ed1ab_0.conda + sha256: f1bf2f01ab4cf799bc3c561eb9247709f7f63f8fc151a99ffd247bda50a5ee28 + md5: a887538e7f6697ed52a487dbaa0ebff5 depends: - python >=3.7 license: Apache-2.0 license_family: Apache purls: - pkg:pypi/trove-classifiers - size: 18431 - timestamp: 1715951449039 + size: 18449 + timestamp: 1716451864560 - kind: conda name: twine version: 5.1.0 @@ -28553,52 +28729,52 @@ packages: - kind: conda name: vc version: '14.3' - build: hcf57466_18 - build_number: 18 + build: ha32ba9b_20 + build_number: 20 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-hcf57466_18.conda - sha256: 447a8d8292a7b2107dcc18afb67f046824711a652725fc0f522c368e7a7b8318 - md5: 20e1e652a4c740fa719002a8449994a2 + url: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-ha32ba9b_20.conda + sha256: 16cb562ce210ee089060f4aa52f3225a571c83885632a870ea2297d460e3bb00 + md5: 2abfb5cb1b9d41a50f765d60f0be563d depends: - - vc14_runtime >=14.38.33130 + - vc14_runtime >=14.38.33135 track_features: - vc14 license: BSD-3-Clause license_family: BSD - size: 16977 - timestamp: 1702511255313 + size: 17122 + timestamp: 1716231244564 - kind: conda name: vc14_runtime - version: 14.38.33130 - build: h82b7239_18 - build_number: 18 + version: 14.38.33135 + build: h835141b_20 + build_number: 20 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.38.33130-h82b7239_18.conda - sha256: bf94c9af4b2e9cba88207001197e695934eadc96a5c5e4cd7597e950aae3d8ff - md5: 8be79fdd2725ddf7bbf8a27a4c1f79ba + url: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.38.33135-h835141b_20.conda + sha256: 05b07e0dd3fd49dcc98a365ff661ed6b65e2f0266b4bb03d273131ffdba663be + md5: e971b35a5765862fabc4ba6e5ddf9470 depends: - ucrt >=10.0.20348.0 constrains: - - vs2015_runtime 14.38.33130.* *_18 + - vs2015_runtime 14.38.33135.* *_20 license: LicenseRef-ProprietaryMicrosoft license_family: Proprietary - size: 749868 - timestamp: 1702511239004 + size: 744189 + timestamp: 1716231234745 - kind: conda name: vs2015_runtime - version: 14.38.33130 - build: hcb4865c_18 - build_number: 18 + version: 14.38.33135 + build: h22015db_20 + build_number: 20 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.38.33130-hcb4865c_18.conda - sha256: a2fec221f361d6263c117f4ea6d772b21c90a2f8edc6f3eb0eadec6bfe8843db - md5: 10d42885e3ed84e575b454db30f1aa93 + url: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.38.33135-h22015db_20.conda + sha256: 2cebabc39766ea051e577762d813ad4151e9d0ff96f3ff3374d575a272951416 + md5: bb4f5ab332e46e1b022d8842e72905b1 depends: - - vc14_runtime >=14.38.33130 + - vc14_runtime >=14.38.33135 license: BSD-3-Clause license_family: BSD - size: 16988 - timestamp: 1702511261442 + size: 17124 + timestamp: 1716231247457 - kind: conda name: vtk version: 9.2.6 @@ -29097,23 +29273,22 @@ packages: size: 1176306 - kind: conda name: wslink - version: 2.0.2 + version: 2.0.4 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.2-pyhd8ed1ab_0.conda - sha256: 388dc4cfbcf0b6aed0e1d89b4a0443edcc10f5998f4a014e8bcc4954d669e881 - md5: 0c046a28359b6c6f82b3a8adbf7d2f90 + url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.4-pyhd8ed1ab_0.conda + sha256: 8d6b0866c964f3af11afb7bee9dafaddb794cf2b2216e5ebcf1ccbc45d43750f + md5: d51c40c9af5f104d4bb16598efc5b53d depends: - aiohttp <4 - msgpack-python >=1,<2 - python >=3.7 license: BSD-3-Clause - license_family: BSD purls: - pkg:pypi/wslink - size: 33963 - timestamp: 1713491049717 + size: 34198 + timestamp: 1716591663821 - kind: conda name: x264 version: 1!164.3095 diff --git a/pixi.toml b/pixi.toml index 5011871b2..0dfae7866 100644 --- a/pixi.toml +++ b/pixi.toml @@ -82,6 +82,7 @@ numpy = "*" pandamesh = "*" pandas = "*" pooch = "*" +pydantic = "*" pydata-sphinx-theme = "*" pymetis = "*" pyproj = "*" diff --git a/pyproject.toml b/pyproject.toml index 801566753..08f259879 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -22,6 +22,7 @@ classifiers = [ "Programming Language :: Python :: 3", "Programming Language :: Python :: 3.10", "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", "Programming Language :: Python :: Implementation :: CPython", "Topic :: Scientific/Engineering" ] @@ -37,6 +38,7 @@ dependencies = [ "numpy", "pandas", "pooch", + "pydantic", "scipy", "tomli >= 1.1.0", "tomli_w", From 62ba721deec63abd8929f8660378e618633359f8 Mon Sep 17 00:00:00 2001 From: luitjan Date: Wed, 29 May 2024 14:14:03 +0200 Subject: [PATCH 09/53] fixed tests after merge --- imod/mf6/dis.py | 12 +++++------- imod/mf6/drn.py | 9 +++++---- imod/mf6/ic.py | 9 +++++---- imod/mf6/npf.py | 9 +++++---- imod/mf6/package.py | 5 +++-- imod/mf6/rch.py | 9 +++++---- imod/mf6/sto.py | 9 +++++---- imod/tests/test_mf6/test_mf6_drn.py | 2 +- 8 files changed, 34 insertions(+), 30 deletions(-) diff --git a/imod/mf6/dis.py b/imod/mf6/dis.py index f810731e7..13fe9bd12 100644 --- a/imod/mf6/dis.py +++ b/imod/mf6/dis.py @@ -1,5 +1,5 @@ import pathlib -from copy import deepcopy +from dataclasses import asdict from typing import List, Optional import numpy as np @@ -199,12 +199,10 @@ def from_imod5_data( target_grid = create_smallest_target_grid(*data.values()) - # For some reason ``get_regrid_methods`` cannot be called in a - # classmethod. - regridder_settings = deepcopy(cls._regrid_method) - if regridder_types is not None: - regridder_settings.update(regridder_types) - + if regridder_types is None: + regridder_settings = asdict(cls.get_regrid_methods(), dict_factory=dict) + else: + regridder_settings = asdict(regridder_types, dict_factory=dict) regrid_context = RegridderWeightsCache() new_package_data = _regrid_package_data( diff --git a/imod/mf6/drn.py b/imod/mf6/drn.py index 57dadbffd..3cbf1fa4e 100644 --- a/imod/mf6/drn.py +++ b/imod/mf6/drn.py @@ -1,4 +1,4 @@ -from copy import deepcopy +from dataclasses import asdict import numpy as np @@ -213,9 +213,10 @@ def from_imod5_data( } is_planar = is_planar_grid(data["elevation"]) - regridder_settings = deepcopy(cls._regrid_method) - if regridder_types is not None: - regridder_settings.update(regridder_types) + if regridder_types is None: + regridder_settings = asdict(cls.get_regrid_methods(), dict_factory=dict) + else: + regridder_settings = asdict(regridder_types, dict_factory=dict) regrid_context = RegridderWeightsCache() diff --git a/imod/mf6/ic.py b/imod/mf6/ic.py index aeb586b32..a5e5006f3 100644 --- a/imod/mf6/ic.py +++ b/imod/mf6/ic.py @@ -1,5 +1,5 @@ import warnings -from copy import deepcopy +from dataclasses import asdict from typing import Optional import numpy as np @@ -130,9 +130,10 @@ def from_imod5_data( "start": imod5_data["shd"]["head"], } - regridder_settings = deepcopy(cls._regrid_method) - if regridder_types is not None: - regridder_settings.update(regridder_types) + if regridder_types is None: + regridder_settings = asdict(cls.get_regrid_methods(), dict_factory=dict) + else: + regridder_settings = asdict(regridder_types, dict_factory=dict) regrid_context = RegridderWeightsCache() diff --git a/imod/mf6/npf.py b/imod/mf6/npf.py index a76e7fb19..8ef70b9e7 100644 --- a/imod/mf6/npf.py +++ b/imod/mf6/npf.py @@ -1,5 +1,5 @@ import warnings -from copy import deepcopy +from dataclasses import asdict from typing import Optional import numpy as np @@ -510,9 +510,10 @@ def from_imod5_data( icelltype = zeros_like(target_grid, dtype=int) - regridder_settings = deepcopy(cls._regrid_method) - if regridder_types is not None: - regridder_settings.update(regridder_types) + if regridder_types is None: + regridder_settings = asdict(cls.get_regrid_methods(), dict_factory=dict) + else: + regridder_settings = asdict(regridder_types, dict_factory=dict) regrid_context = RegridderWeightsCache() diff --git a/imod/mf6/package.py b/imod/mf6/package.py index d6d09c759..9f84e215a 100644 --- a/imod/mf6/package.py +++ b/imod/mf6/package.py @@ -637,5 +637,6 @@ def is_regridding_supported(self) -> bool: def is_clipping_supported(self) -> bool: return True - def get_regrid_methods(self) -> RegridMethodType: - return deepcopy(self._regrid_method) + @classmethod + def get_regrid_methods(cls) -> RegridMethodType: + return deepcopy(cls._regrid_method) diff --git a/imod/mf6/rch.py b/imod/mf6/rch.py index b8ec1a5af..b840b002e 100644 --- a/imod/mf6/rch.py +++ b/imod/mf6/rch.py @@ -1,4 +1,4 @@ -from copy import deepcopy +from dataclasses import asdict from typing import Optional import numpy as np @@ -195,9 +195,10 @@ def from_imod5_data( new_package_data = {} # first regrid the inputs to the target grid. - regridder_settings = deepcopy(cls._regrid_method) - if regridder_types is not None: - regridder_settings.update(regridder_types) + if regridder_types is None: + regridder_settings = asdict(cls.get_regrid_methods(), dict_factory=dict) + else: + regridder_settings = asdict(regridder_types, dict_factory=dict) regrid_context = RegridderWeightsCache() diff --git a/imod/mf6/sto.py b/imod/mf6/sto.py index a8f6fbff9..5fae6aeb5 100644 --- a/imod/mf6/sto.py +++ b/imod/mf6/sto.py @@ -1,5 +1,5 @@ import abc -from copy import deepcopy +from dataclasses import asdict from typing import Optional import numpy as np @@ -361,9 +361,10 @@ def from_imod5_data( "storage_coefficient": imod5_data["sto"]["storage_coefficient"], } - regridder_settings = deepcopy(cls._regrid_method) - if regridder_types is not None: - regridder_settings.update(regridder_types) + if regridder_types is None: + regridder_settings = asdict(cls.get_regrid_methods(), dict_factory=dict) + else: + regridder_settings = asdict(regridder_types, dict_factory=dict) regrid_context = RegridderWeightsCache() diff --git a/imod/tests/test_mf6/test_mf6_drn.py b/imod/tests/test_mf6/test_mf6_drn.py index 94ef64fa8..369ed26b8 100644 --- a/imod/tests/test_mf6/test_mf6_drn.py +++ b/imod/tests/test_mf6/test_mf6_drn.py @@ -486,7 +486,7 @@ def test_from_imod5(imod5_dataset, tmp_path): target_npf, allocation_option=ALLOCATION_OPTION.at_elevation, distributing_option=DISTRIBUTING_OPTION.by_crosscut_thickness, - regridder_types={}, + regridder_types=None, ) assert isinstance(drn_2, imod.mf6.Drainage) From 3f20b3e94b82800d8562aadb74d2fb4255daf8be Mon Sep 17 00:00:00 2001 From: luitjan Date: Wed, 29 May 2024 16:16:23 +0200 Subject: [PATCH 10/53] fixed mypy errors --- imod/mf6/dis.py | 5 ++--- imod/mf6/drn.py | 6 +++--- imod/mf6/ic.py | 8 +++++--- imod/mf6/npf.py | 8 +++++--- imod/mf6/rch.py | 5 ++--- imod/mf6/sto.py | 4 ++-- 6 files changed, 19 insertions(+), 17 deletions(-) diff --git a/imod/mf6/dis.py b/imod/mf6/dis.py index 13fe9bd12..28d5ffbf9 100644 --- a/imod/mf6/dis.py +++ b/imod/mf6/dis.py @@ -9,11 +9,10 @@ from imod.mf6.interfaces.imaskingsettings import IMaskingSettings from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.package import Package -from imod.mf6.regrid.regrid_schemes import DiscretizationRegridMethod +from imod.mf6.regrid.regrid_schemes import DiscretizationRegridMethod, RegridMethodType from imod.mf6.utilities.grid import create_smallest_target_grid from imod.mf6.utilities.imod5_converter import convert_ibound_to_idomain from imod.mf6.utilities.regrid import ( - RegridderType, RegridderWeightsCache, _regrid_package_data, ) @@ -163,7 +162,7 @@ def _validate(self, schemata, **kwargs): def from_imod5_data( cls, imod5_data: dict[str, dict[str, GridDataArray]], - regridder_types: Optional[dict[str, tuple[RegridderType, str]]] = None, + regridder_types: Optional[RegridMethodType] = None, ) -> "StructuredDiscretization": """ Construct package from iMOD5 data, loaded with the diff --git a/imod/mf6/drn.py b/imod/mf6/drn.py index 3cbf1fa4e..062271515 100644 --- a/imod/mf6/drn.py +++ b/imod/mf6/drn.py @@ -1,4 +1,5 @@ from dataclasses import asdict +from typing import Optional import numpy as np @@ -7,9 +8,8 @@ from imod.mf6.dis import StructuredDiscretization from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.npf import NodePropertyFlow -from imod.mf6.regrid.regrid_schemes import DrainageRegridMethod +from imod.mf6.regrid.regrid_schemes import DrainageRegridMethod, RegridMethodType from imod.mf6.utilities.regrid import ( - RegridderType, RegridderWeightsCache, _regrid_package_data, ) @@ -170,7 +170,7 @@ def from_imod5_data( target_npf: NodePropertyFlow, allocation_option: ALLOCATION_OPTION, distributing_option: DISTRIBUTING_OPTION, - regridder_types: dict[str, tuple[RegridderType, str]], + regridder_types: Optional[RegridMethodType] = None, ) -> "Drainage": """ Construct a drainage-package from iMOD5 data, loaded with the diff --git a/imod/mf6/ic.py b/imod/mf6/ic.py index a5e5006f3..58b40374f 100644 --- a/imod/mf6/ic.py +++ b/imod/mf6/ic.py @@ -7,9 +7,11 @@ from imod.logging import init_log_decorator from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.package import Package -from imod.mf6.regrid.regrid_schemes import InitialConditionsRegridMethod +from imod.mf6.regrid.regrid_schemes import ( + InitialConditionsRegridMethod, + RegridMethodType, +) from imod.mf6.utilities.regrid import RegridderWeightsCache, _regrid_package_data -from imod.mf6.utilities.regridding_types import RegridderType from imod.mf6.validation import PKG_DIMS_SCHEMA from imod.schemata import DTypeSchema, IdentityNoDataSchema, IndexesSchema from imod.typing import GridDataArray @@ -99,7 +101,7 @@ def from_imod5_data( cls, imod5_data: dict[str, dict[str, GridDataArray]], target_grid: GridDataArray, - regridder_types: Optional[dict[str, tuple[RegridderType, str]]] = None, + regridder_types: Optional[RegridMethodType] = None, ) -> "InitialConditions": """ Construct an InitialConditions-package from iMOD5 data, loaded with the diff --git a/imod/mf6/npf.py b/imod/mf6/npf.py index 8ef70b9e7..abba5c4d5 100644 --- a/imod/mf6/npf.py +++ b/imod/mf6/npf.py @@ -8,10 +8,12 @@ from imod.logging import init_log_decorator from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.package import Package -from imod.mf6.regrid.regrid_schemes import NodePropertyFlowRegridMethod +from imod.mf6.regrid.regrid_schemes import ( + NodePropertyFlowRegridMethod, + RegridMethodType, +) from imod.mf6.utilities.imod5_converter import fill_missing_layers from imod.mf6.utilities.regrid import ( - RegridderType, RegridderWeightsCache, _regrid_package_data, ) @@ -457,7 +459,7 @@ def from_imod5_data( cls, imod5_data: dict[str, dict[str, GridDataArray]], target_grid: GridDataArray, - regridder_types: Optional[dict[str, tuple[RegridderType, str]]] = None, + regridder_types: Optional[RegridMethodType] = None, ) -> "NodePropertyFlow": """ Construct an npf-package from iMOD5 data, loaded with the diff --git a/imod/mf6/rch.py b/imod/mf6/rch.py index b840b002e..05099abec 100644 --- a/imod/mf6/rch.py +++ b/imod/mf6/rch.py @@ -7,9 +7,8 @@ from imod.mf6.boundary_condition import BoundaryCondition from imod.mf6.dis import StructuredDiscretization from imod.mf6.interfaces.iregridpackage import IRegridPackage -from imod.mf6.regrid.regrid_schemes import RechargeRegridMethod +from imod.mf6.regrid.regrid_schemes import RechargeRegridMethod, RegridMethodType from imod.mf6.utilities.regrid import RegridderWeightsCache, _regrid_package_data -from imod.mf6.utilities.regridding_types import RegridderType from imod.mf6.validation import BOUNDARY_DIMS_SCHEMA, CONC_DIMS_SCHEMA from imod.prepare.topsystem.allocation import ALLOCATION_OPTION, allocate_rch_cells from imod.schemata import ( @@ -161,7 +160,7 @@ def from_imod5_data( cls, imod5_data: dict[str, dict[str, GridDataArray]], dis_pkg: StructuredDiscretization, - regridder_types: Optional[dict[str, tuple[RegridderType, str]]] = None, + regridder_types: Optional[RegridMethodType] = None, ) -> "Recharge": """ Construct an rch-package from iMOD5 data, loaded with the diff --git a/imod/mf6/sto.py b/imod/mf6/sto.py index 5fae6aeb5..ad4fa03e2 100644 --- a/imod/mf6/sto.py +++ b/imod/mf6/sto.py @@ -8,11 +8,11 @@ from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.package import Package from imod.mf6.regrid.regrid_schemes import ( + RegridMethodType, SpecificStorageRegridMethod, StorageCoefficientRegridMethod, ) from imod.mf6.utilities.regrid import RegridderWeightsCache, _regrid_package_data -from imod.mf6.utilities.regridding_types import RegridderType from imod.mf6.validation import PKG_DIMS_SCHEMA from imod.schemata import ( AllValueSchema, @@ -329,7 +329,7 @@ def from_imod5_data( cls, imod5_data: dict[str, dict[str, GridDataArray]], target_grid: GridDataArray, - regridder_types: Optional[dict[str, tuple[RegridderType, str]]] = None, + regridder_types: Optional[RegridMethodType] = None, ) -> "StorageCoefficient": """ Construct a StorageCoefficient-package from iMOD5 data, loaded with the From fc6e1b75ca9398431d6ea9ad511ad6d2c4d612ae Mon Sep 17 00:00:00 2001 From: luitjan Date: Wed, 29 May 2024 16:16:48 +0200 Subject: [PATCH 11/53] uopdated docstrings --- imod/mf6/dis.py | 4 ++-- imod/mf6/drn.py | 4 ++-- imod/mf6/ic.py | 4 ++-- imod/mf6/npf.py | 4 ++-- imod/mf6/rch.py | 4 ++-- imod/mf6/sto.py | 4 ++-- 6 files changed, 12 insertions(+), 12 deletions(-) diff --git a/imod/mf6/dis.py b/imod/mf6/dis.py index 28d5ffbf9..329249224 100644 --- a/imod/mf6/dis.py +++ b/imod/mf6/dis.py @@ -181,8 +181,8 @@ def from_imod5_data( imod5_data: dict Dictionary with iMOD5 data. This can be constructed from the :func:`imod.formats.prj.open_projectfile_data` method. - regridder_types: dict, optional - Optional dictionary with regridder types for a specific variable. + regridder_types: RegridMethodType, optional + Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. Returns diff --git a/imod/mf6/drn.py b/imod/mf6/drn.py index 062271515..4eb83d1af 100644 --- a/imod/mf6/drn.py +++ b/imod/mf6/drn.py @@ -194,8 +194,8 @@ def from_imod5_data( allocation option. distributing_option: dict[str, DISTRIBUTING_OPTION] distributing option. - regridder_types: dict, optional - Optional dictionary with regridder types for a specific variable. + regridder_types: RegridMethodType, optional + Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. Returns diff --git a/imod/mf6/ic.py b/imod/mf6/ic.py index 58b40374f..65161a3b2 100644 --- a/imod/mf6/ic.py +++ b/imod/mf6/ic.py @@ -119,8 +119,8 @@ def from_imod5_data( target_grid: GridDataArray The grid that should be used for the new package. Does not need to be identical to one of the input grids. - regridder_types: dict, optional - Optional dictionary with regridder types for a specific variable. + regridder_types: RegridMethodType, optional + Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. Returns diff --git a/imod/mf6/npf.py b/imod/mf6/npf.py index abba5c4d5..99401f0e9 100644 --- a/imod/mf6/npf.py +++ b/imod/mf6/npf.py @@ -477,8 +477,8 @@ def from_imod5_data( target_grid: GridDataArray The grid that should be used for the new package. Does not need to be identical to one of the input grids. - regridder_types: dict, optional - Optional dictionary with regridder types for a specific variable. + regridder_types: RegridMethodType, optional + Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. Returns diff --git a/imod/mf6/rch.py b/imod/mf6/rch.py index 05099abec..37993ee38 100644 --- a/imod/mf6/rch.py +++ b/imod/mf6/rch.py @@ -178,8 +178,8 @@ def from_imod5_data( dis_pkg: GridDataArray The discretization package for the simulation. Its grid does not need to be identical to one of the input grids. - regridder_types: dict, optional - Optional dictionary with regridder types for a specific variable. + regridder_types: RegridMethodType, optional + Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. Returns diff --git a/imod/mf6/sto.py b/imod/mf6/sto.py index ad4fa03e2..8be0c92c5 100644 --- a/imod/mf6/sto.py +++ b/imod/mf6/sto.py @@ -347,8 +347,8 @@ def from_imod5_data( target_grid: GridDataArray The grid that should be used for the new package. Does not need to be identical to one of the input grids. - regridder_types: dict, optional - Optional dictionary with regridder types for a specific variable. + regridder_types: RegridMethodType, optional + Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. Returns From a31d86ff63dd24079f433dbff4da29cb56a124bf Mon Sep 17 00:00:00 2001 From: luitjansl <64598682+luitjansl@users.noreply.github.com> Date: Thu, 30 May 2024 11:04:45 +0200 Subject: [PATCH 12/53] Issue #1041 import simulation (#1059) Fixes #1041 # Description Adds a function that imports a simulation from an imod5 project file. It creates a simulation, containing 1 GroundwaterFlowModel, containing the packages for which we support importing currently. This includes the mandatory flow packages like NPF and STO, and some boundary conditions (like DRN and RCH) but not yet CHD or WEL. # Checklist - [X] Links to correct issue - [ ] Update changelog, if changes affect users - [X] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [X] Unit tests were added - [ ] **If feature added**: Added/extended example --------- Co-authored-by: Joeri van Engelen --- imod/mf6/model_gwf.py | 92 +++++++++++++++++++ imod/mf6/simulation.py | 66 ++++++++++++- imod/mf6/sto.py | 8 +- .../topsystem/default_allocation_methods.py | 40 ++++++++ imod/tests/test_mf6/test_mf6_simulation.py | 24 +++++ 5 files changed, 222 insertions(+), 8 deletions(-) create mode 100644 imod/prepare/topsystem/default_allocation_methods.py diff --git a/imod/mf6/model_gwf.py b/imod/mf6/model_gwf.py index 76fa6318a..8736abd47 100644 --- a/imod/mf6/model_gwf.py +++ b/imod/mf6/model_gwf.py @@ -6,9 +6,21 @@ import numpy as np from imod.logging import init_log_decorator +from imod.logging.logging_decorators import standard_log_decorator from imod.mf6 import ConstantHead from imod.mf6.clipped_boundary_condition_creator import create_clipped_boundary +from imod.mf6.dis import StructuredDiscretization +from imod.mf6.drn import Drainage +from imod.mf6.ic import InitialConditions from imod.mf6.model import Modflow6Model +from imod.mf6.npf import NodePropertyFlow +from imod.mf6.rch import Recharge +from imod.mf6.sto import StorageCoefficient +from imod.mf6.utilities.regridding_types import RegridderType +from imod.prepare.topsystem.default_allocation_methods import ( + SimulationAllocationOptions, + SimulationDistributingOptions, +) from imod.typing import GridDataArray @@ -153,3 +165,83 @@ def update_buoyancy_package(self, transport_models_per_flow_model) -> None: transport_models_old = buoyancy_package.get_transport_model_names() if len(transport_models_old) == len(transport_models_per_flow_model): buoyancy_package.update_transport_models(transport_models_per_flow_model) + + @classmethod + @standard_log_decorator() + def from_imod5_data( + cls, + imod5_data: dict[str, dict[str, GridDataArray]], + allocation_options: SimulationAllocationOptions, + distributing_options: SimulationDistributingOptions, + regridder_types: Optional[dict[str, tuple[RegridderType, str]]] = None, + ) -> "GroundwaterFlowModel": + """ + Imports a GroundwaterFlowModel (GWF) from the data in an IMOD5 project file. + It adds the packages for which import from imod5 is supported. + Some packages (like OC) must be added manually later. + + + Parameters + ---------- + imod5_data: dict[str, dict[str, GridDataArray]] + dictionary containing the arrays mentioned in the project file as xarray datasets, + under the key of the package type to which it belongs + allocation_options: SimulationAllocationOptions + object containing the allocation options per package type. + If you want a package to have a different allocation option, + then it should be imported separately + distributing_options: SimulationDistributingOptions + object containing the conductivity distribution options per package type. + If you want a package to have a different allocation option, + then it should be imported separately + regridder_types: Optional[dict[str, dict[str, tuple[RegridderType, str]]]] + the first key is the package name. The second key is the array name, and the value is + the RegridderType tuple (method + function) + + Returns + ------- + A GWF model containing the packages that could be imported form IMOD5. Users must still + add the OC package to the model. + + """ + # first import the singleton packages + # import discretization + dis_pkg = StructuredDiscretization.from_imod5_data(imod5_data, regridder_types) + grid = dis_pkg.dataset["idomain"] + + # import npf + npf_pkg = NodePropertyFlow.from_imod5_data(imod5_data, grid, regridder_types) + + # import sto + sto_pkg = StorageCoefficient.from_imod5_data(imod5_data, grid, regridder_types) + + # import initial conditions + ic_pkg = InitialConditions.from_imod5_data(imod5_data, grid, regridder_types) + + # import recharge + rch_pkg = Recharge.from_imod5_data(imod5_data, dis_pkg, regridder_types) + + result = GroundwaterFlowModel() + result["dis"] = dis_pkg + result["npf"] = npf_pkg + result["sto"] = sto_pkg + result["ic"] = ic_pkg + result["rch"] = rch_pkg + + # now import the non-singleton packages + # import drainage + imod5_keys = list(imod5_data.keys()) + drainage_keys = [key for key in imod5_keys if key[0:3] == "drn"] + for drn_key in drainage_keys: + drn_pkg = Drainage.from_imod5_data( + drn_key, + imod5_data, + dis_pkg, + npf_pkg, + allocation_options.drn, + distributing_option=distributing_options.drn, + regridder_types=regridder_types, + ) + result[drn_key] = drn_pkg + + return result diff --git a/imod/mf6/simulation.py b/imod/mf6/simulation.py index 8741c7c79..55132520e 100644 --- a/imod/mf6/simulation.py +++ b/imod/mf6/simulation.py @@ -24,7 +24,7 @@ from imod.mf6.gwfgwf import GWFGWF from imod.mf6.gwfgwt import GWFGWT from imod.mf6.gwtgwt import GWTGWT -from imod.mf6.ims import Solution +from imod.mf6.ims import Solution, SolutionPresetModerate from imod.mf6.interfaces.imodel import IModel from imod.mf6.interfaces.isimulation import ISimulation from imod.mf6.model import Modflow6Model @@ -41,7 +41,12 @@ from imod.mf6.statusinfo import NestedStatusInfo from imod.mf6.utilities.mask import _mask_all_models from imod.mf6.utilities.regrid import _regrid_like +from imod.mf6.utilities.regridding_types import RegridderType from imod.mf6.write_context import WriteContext +from imod.prepare.topsystem.default_allocation_methods import ( + SimulationAllocationOptions, + SimulationDistributingOptions, +) from imod.schemata import ValidationError from imod.typing import GridDataArray, GridDataset from imod.typing.grid import ( @@ -1308,3 +1313,62 @@ def mask_all_models( -1 sets cells to vertical passthrough """ _mask_all_models(self, mask) + + @classmethod + @standard_log_decorator() + def from_imod5_data( + cls, + imod5_data: dict[str, dict[str, GridDataArray]], + allocation_options: SimulationAllocationOptions, + distributing_options: SimulationDistributingOptions, + regridder_types: Optional[dict[str, tuple[RegridderType, str]]] = None, + ) -> "Modflow6Simulation": + """ + Imports a GroundwaterFlowModel (GWF) from the data in an IMOD5 project file. + It adds the packages for which import from imod5 is supported. + Some packages (like OC) must be added manually later. + + + Parameters + ---------- + imod5_data: dict[str, dict[str, GridDataArray]] + dictionary containing the arrays mentioned in the project file as xarray datasets, + under the key of the package type to which it belongs + allocation_options: SimulationAllocationOptions + object containing the allocation options per package type. + If you want a package to have a different allocation option, + then it should be imported separately + distributing_options: SimulationDistributingOptions + object containing the conductivity distribution options per package type. + If you want a package to have a different allocation option, + then it should be imported separately + regridder_types: Optional[dict[str, dict[str, tuple[RegridderType, str]]]] + the first key is the package name. The second key is the array name, and the value is + the RegridderType tuple (method + function) + + Returns + ------- + """ + simulation = Modflow6Simulation("imported_simulation") + + # import GWF model, + groundwaterFlowModel = GroundwaterFlowModel.from_imod5_data( + imod5_data, + allocation_options, + distributing_options, + regridder_types, + ) + simulation["imported_model"] = groundwaterFlowModel + + # generate ims package + solution = SolutionPresetModerate( + ["imported_model"], + print_option="all", + ) + simulation["ims"] = solution + + # cleanup packages for validation + idomain = groundwaterFlowModel.domain + simulation.mask_all_models(idomain) + + return simulation diff --git a/imod/mf6/sto.py b/imod/mf6/sto.py index 8be0c92c5..ef3f49580 100644 --- a/imod/mf6/sto.py +++ b/imod/mf6/sto.py @@ -290,10 +290,6 @@ class StorageCoefficient(StorageBase): AllValueSchema(">=", 0.0), IdentityNoDataSchema(other="idomain", is_other_notnull=(">", 0)), ), - "convertible": ( - IdentityNoDataSchema(other="idomain", is_other_notnull=(">", 0)), - # No need to check coords: dataset ensures they align with idomain. - ), } _template = Package._initialize_template(_pkg_id) @@ -372,9 +368,7 @@ def from_imod5_data( data, target_grid, regridder_settings, regrid_context, {} ) - new_package_data["convertible"] = zeros_like( - new_package_data["storage_coefficient"], dtype=int - ) + new_package_data["convertible"] = zeros_like(target_grid, dtype=int) new_package_data["transient"] = np.any( new_package_data["storage_coefficient"].values > 0 ) diff --git a/imod/prepare/topsystem/default_allocation_methods.py b/imod/prepare/topsystem/default_allocation_methods.py new file mode 100644 index 000000000..770e96b22 --- /dev/null +++ b/imod/prepare/topsystem/default_allocation_methods.py @@ -0,0 +1,40 @@ +from dataclasses import dataclass + +from imod.prepare.topsystem.allocation import ALLOCATION_OPTION +from imod.prepare.topsystem.conductance import DISTRIBUTING_OPTION + + +@dataclass() +class SimulationAllocationOptions: + """ + Object containing allocation otpions, specified per packages type on + importing fron imod5. Can be used to set defaults when importing a + simulation or a GroundwaterFlowModel from imod5. + + Parameters + ---------- + drn: allocation option to be used for drainage packages + riv: allocation option to be used for river packages + + """ + + drn: ALLOCATION_OPTION = ALLOCATION_OPTION.first_active_to_elevation + riv: ALLOCATION_OPTION = ALLOCATION_OPTION.stage_to_riv_bot + + +@dataclass() +class SimulationDistributingOptions: + """ + Object containing conductivity distribution methods, specified per packages + type. Can be used to set defaults when importing a simulation or a + GroundwaterFlowModel from imod5. + + Parameters + ---------- + drn: distribution option to be used for drainage packages + riv: distribution option to be used for river packages + + """ + + drn: DISTRIBUTING_OPTION = DISTRIBUTING_OPTION.by_corrected_transmissivity + riv: DISTRIBUTING_OPTION = DISTRIBUTING_OPTION.by_corrected_transmissivity diff --git a/imod/tests/test_mf6/test_mf6_simulation.py b/imod/tests/test_mf6/test_mf6_simulation.py index b295917f3..fc2373fff 100644 --- a/imod/tests/test_mf6/test_mf6_simulation.py +++ b/imod/tests/test_mf6/test_mf6_simulation.py @@ -18,7 +18,13 @@ import imod from imod.mf6.model import Modflow6Model from imod.mf6.multimodel.modelsplitter import PartitionInfo +from imod.mf6.oc import OutputControl +from imod.mf6.simulation import Modflow6Simulation from imod.mf6.statusinfo import NestedStatusInfo, StatusInfo +from imod.prepare.topsystem.default_allocation_methods import ( + SimulationAllocationOptions, + SimulationDistributingOptions, +) from imod.schemata import ValidationError from imod.tests.fixtures.mf6_small_models_fixture import ( grid_data_structured, @@ -461,3 +467,21 @@ def compare_submodel_partition_info(first: PartitionInfo, second: PartitionInfo) return (first.id == second.id) and np.array_equal( first.active_domain, second.active_domain ) + + +@pytest.mark.usefixtures("imod5_dataset") +def test_import_from_imod5(imod5_dataset, tmp_path): + default_simulation_allocation_options = SimulationAllocationOptions + default_simulation_distributing_options = SimulationDistributingOptions + simulation = Modflow6Simulation.from_imod5_data( + imod5_dataset, + default_simulation_allocation_options, + default_simulation_distributing_options, + ) + + simulation["imported_model"] = OutputControl(save_head="last", save_budget="last") + + simulation.create_time_discretization(["01-01-2003", "02-01-2003"]) + + # write and validate the simulation + simulation.write(tmp_path, False, True, False) From b7498571d2024707d8652255191094789eb42942 Mon Sep 17 00:00:00 2001 From: luitjansl <64598682+luitjansl@users.noreply.github.com> Date: Mon, 3 Jun 2024 16:41:08 +0200 Subject: [PATCH 13/53] adding import of filter top and bottom (#1063) Fixes #1053 # Description On importing wells, the filter top and bottom are now parsed and stored in the project file data structure # Checklist - [X] Links to correct issue - [X] Update changelog, if changes affect users - [X] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [X] Unit tests were added - [ ] **If feature added**: Added/extended example --- docs/api/changelog.rst | 8 ++++++++ imod/formats/prj/prj.py | 6 +++--- imod/tests/test_mf6/test_import_prj.py | 6 ++++++ 3 files changed, 17 insertions(+), 3 deletions(-) diff --git a/docs/api/changelog.rst b/docs/api/changelog.rst index 597bed3aa..50772f85c 100644 --- a/docs/api/changelog.rst +++ b/docs/api/changelog.rst @@ -6,6 +6,14 @@ All notable changes to this project will be documented in this file. The format is based on `Keep a Changelog`_, and this project adheres to `Semantic Versioning`_. + +[Unreleased- feature branch] +---------------------------- + +Changed +~~~~~~~ +- :function:`open_projectfile_data` now also imports well filter top and bottom. + [Unreleased] ------------ diff --git a/imod/formats/prj/prj.py b/imod/formats/prj/prj.py index b9fe406db..d5154cddc 100644 --- a/imod/formats/prj/prj.py +++ b/imod/formats/prj/prj.py @@ -806,9 +806,9 @@ def _read_package_ipf( df_assoc["x"] = row[1] df_assoc["y"] = row[2] df_assoc["id"] = path_assoc.stem - if layer <= 0: - df_assoc["top"] = row[4] - df_assoc["bottom"] = row[5] + if "filt_top" in row._fields and "filt_bot" in row._fields: + df_assoc["filt_top"] = row.filt_top + df_assoc["filt_bot"] = row.filt_bot dfs.append(df_assoc) df = pd.concat(dfs, ignore_index=True, sort=False) df["rate"] = df["rate"] * factor + addition diff --git a/imod/tests/test_mf6/test_import_prj.py b/imod/tests/test_mf6/test_import_prj.py index 43c2516b4..e5297f1c8 100644 --- a/imod/tests/test_mf6/test_import_prj.py +++ b/imod/tests/test_mf6/test_import_prj.py @@ -192,6 +192,12 @@ def test_import_ipf(tmp_path): result_snippet_1[0]["wel-3"]["dataframe"]["rate"] == 2 * result_snippet_0[0]["wel-2"]["dataframe"]["rate"] + 1.3 ) + assert np.all(result_snippet_1[0]["wel-1"]["dataframe"]["filt_top"] == 11.0) + assert np.all(result_snippet_1[0]["wel-1"]["dataframe"]["filt_bot"] == 6.0) + assert np.all(result_snippet_1[0]["wel-2"]["dataframe"]["filt_top"] == 11.0) + assert np.all(result_snippet_1[0]["wel-2"]["dataframe"]["filt_bot"] == 6.0) + assert np.all(result_snippet_1[0]["wel-3"]["dataframe"]["filt_top"] == 11.0) + assert np.all(result_snippet_1[0]["wel-3"]["dataframe"]["filt_bot"] == 6.0) def snippet_boundary_condition(factor: float, addition: float): From 0eed7f8ff9b1e5ad3a4cc5b956350ed40fb308b6 Mon Sep 17 00:00:00 2001 From: luitjansl <64598682+luitjansl@users.noreply.github.com> Date: Fri, 7 Jun 2024 13:30:34 +0200 Subject: [PATCH 14/53] Issue #1051 validate well filters (#1062) Fixes #1051 # Description Now validates that well top > well bottom. # Checklist - [X] Links to correct issue - [ ] Update changelog, if changes affect users - [X] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [X] Unit tests were added - [ ] **If feature added**: Added/extended example --- docs/api/changelog.rst | 1 + imod/mf6/wel.py | 13 ++++++++++++- imod/tests/test_mf6/test_mf6_wel.py | 23 +++++++++++++++++++++++ 3 files changed, 36 insertions(+), 1 deletion(-) diff --git a/docs/api/changelog.rst b/docs/api/changelog.rst index 50772f85c..15a4f0318 100644 --- a/docs/api/changelog.rst +++ b/docs/api/changelog.rst @@ -12,6 +12,7 @@ The format is based on `Keep a Changelog`_, and this project adheres to Changed ~~~~~~~ +- :class:`imod.mf6.Well` now also validates that well filter top is above well filter bottom - :function:`open_projectfile_data` now also imports well filter top and bottom. [Unreleased] diff --git a/imod/mf6/wel.py b/imod/mf6/wel.py index 080046c99..e10ec3b4b 100644 --- a/imod/mf6/wel.py +++ b/imod/mf6/wel.py @@ -12,6 +12,7 @@ import imod from imod.logging import init_log_decorator +from imod.logging.logging_decorators import standard_log_decorator from imod.mf6.boundary_condition import ( BoundaryCondition, DisStructuredBoundaryCondition, @@ -26,6 +27,7 @@ from imod.prepare import assign_wells from imod.prepare.layer import create_layered_top from imod.schemata import ( + AllValueSchema, AnyNoDataSchema, DTypeSchema, EmptyIndexesSchema, @@ -177,7 +179,11 @@ def y(self) -> npt.NDArray[np.float64]: } _write_schemata = { "screen_top": [AnyNoDataSchema(), EmptyIndexesSchema()], - "screen_bottom": [AnyNoDataSchema(), EmptyIndexesSchema()], + "screen_bottom": [ + AnyNoDataSchema(), + EmptyIndexesSchema(), + AllValueSchema("<", "screen_top"), + ], "y": [AnyNoDataSchema(), EmptyIndexesSchema()], "x": [AnyNoDataSchema(), EmptyIndexesSchema()], "rate": [AnyNoDataSchema(), EmptyIndexesSchema()], @@ -363,6 +369,11 @@ def __create_wells_df(self) -> pd.DataFrame: return wells_df + @standard_log_decorator() + def _validate(self, schemata: dict, **kwargs) -> dict[str, list[ValidationError]]: + kwargs["screen_top"] = self.dataset["screen_top"] + return Package._validate(self, schemata, **kwargs) + def __create_assigned_wells( self, wells_df: pd.DataFrame, diff --git a/imod/tests/test_mf6/test_mf6_wel.py b/imod/tests/test_mf6/test_mf6_wel.py index e91714826..c95d5b7e0 100644 --- a/imod/tests/test_mf6/test_mf6_wel.py +++ b/imod/tests/test_mf6/test_mf6_wel.py @@ -68,6 +68,29 @@ def test_to_mf6_pkg__validate(well_high_lvl_test_data_stationary): assert len(errors) == 1 +def test_to_mf6_pkg__validate_filter_top(well_high_lvl_test_data_stationary): + # Arrange + x, y, screen_top, screen_bottom, rate_wel, concentration = ( + well_high_lvl_test_data_stationary + ) + screen_top = [-2.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] + screen_bottom = [0.0, -2.0, -2.0, -2.0, -2.0, -2.0, -2.0, -2.0] + well_test_data = (x, y, screen_top, screen_bottom, rate_wel, concentration) + + wel = imod.mf6.Well(*well_test_data) + + # Act + kwargs = {"screen_top": wel.dataset["screen_top"]} + errors = wel._validate(wel._write_schemata, **kwargs) + + # Assert + assert len(errors) == 1 + assert ( + str(errors["screen_bottom"][0]) + == "not all values comply with criterion: < screen_top" + ) + + def test_to_mf6_pkg__high_lvl_multilevel(basic_dis, well_high_lvl_test_data_stationary): """ Test with stationary wells where the first 4 well screens extend over 2 layers. From 047f54517e3ceddf48a16d3e804828b4cefb164f Mon Sep 17 00:00:00 2001 From: luitjansl <64598682+luitjansl@users.noreply.github.com> Date: Fri, 7 Jun 2024 16:45:26 +0200 Subject: [PATCH 15/53] Issue #968 import river (#1061) Fixes #968 # Description Imports riverpackages from IMOD5. The infiltration factor (which does not exist in MF6) is accounted for by creating a drainage package. # Checklist - [x] Links to correct issue - [ ] Update changelog, if changes affect users - [x] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [x] Unit tests were added - [ ] **If feature added**: Added/extended example --------- Co-authored-by: Joeri van Engelen --- imod/mf6/model_gwf.py | 21 +- imod/mf6/riv.py | 254 ++++++++++++++++++++- imod/tests/test_mf6/test_mf6_riv.py | 77 +++++++ imod/tests/test_mf6/test_mf6_simulation.py | 8 +- 4 files changed, 354 insertions(+), 6 deletions(-) diff --git a/imod/mf6/model_gwf.py b/imod/mf6/model_gwf.py index 8736abd47..6d5e98376 100644 --- a/imod/mf6/model_gwf.py +++ b/imod/mf6/model_gwf.py @@ -15,8 +15,9 @@ from imod.mf6.model import Modflow6Model from imod.mf6.npf import NodePropertyFlow from imod.mf6.rch import Recharge +from imod.mf6.regrid.regrid_schemes import RegridMethodType +from imod.mf6.riv import River from imod.mf6.sto import StorageCoefficient -from imod.mf6.utilities.regridding_types import RegridderType from imod.prepare.topsystem.default_allocation_methods import ( SimulationAllocationOptions, SimulationDistributingOptions, @@ -173,7 +174,7 @@ def from_imod5_data( imod5_data: dict[str, dict[str, GridDataArray]], allocation_options: SimulationAllocationOptions, distributing_options: SimulationDistributingOptions, - regridder_types: Optional[dict[str, tuple[RegridderType, str]]] = None, + regridder_types: Optional[RegridMethodType] = None, ) -> "GroundwaterFlowModel": """ Imports a GroundwaterFlowModel (GWF) from the data in an IMOD5 project file. @@ -206,6 +207,7 @@ def from_imod5_data( """ # first import the singleton packages # import discretization + dis_pkg = StructuredDiscretization.from_imod5_data(imod5_data, regridder_types) grid = dis_pkg.dataset["idomain"] @@ -244,4 +246,19 @@ def from_imod5_data( ) result[drn_key] = drn_pkg + # import rivers ( and drainage to account for infiltration factor) + riv_keys = [key for key in imod5_keys if key[0:3] == "riv"] + for riv_key in riv_keys: + riv_pkg, drn_pkg = River.from_imod5_data( + riv_key, + imod5_data, + dis_pkg, + allocation_options.riv, + distributing_options.riv, + regridder_types, + ) + if riv_pkg is not None: + result[riv_key + "riv"] = riv_pkg + if drn_pkg is not None: + result[riv_key + "drn"] = drn_pkg return result diff --git a/imod/mf6/riv.py b/imod/mf6/riv.py index 8c4c0358c..50a90c605 100644 --- a/imod/mf6/riv.py +++ b/imod/mf6/riv.py @@ -1,10 +1,28 @@ +from dataclasses import asdict +from typing import Optional, Tuple + import numpy as np +import xarray as xr +from imod import logging from imod.logging import init_log_decorator +from imod.logging.loglevel import LogLevel from imod.mf6.boundary_condition import BoundaryCondition +from imod.mf6.dis import StructuredDiscretization +from imod.mf6.drn import Drainage from imod.mf6.interfaces.iregridpackage import IRegridPackage -from imod.mf6.regrid.regrid_schemes import RiverRegridMethod +from imod.mf6.regrid.regrid_schemes import RegridMethodType, RiverRegridMethod +from imod.mf6.utilities.regrid import ( + RegridderType, + RegridderWeightsCache, + _regrid_package_data, +) from imod.mf6.validation import BOUNDARY_DIMS_SCHEMA, CONC_DIMS_SCHEMA +from imod.prepare.topsystem.allocation import ALLOCATION_OPTION, allocate_riv_cells +from imod.prepare.topsystem.conductance import ( + DISTRIBUTING_OPTION, + distribute_riv_conductance, +) from imod.schemata import ( AllInsideNoDataSchema, AllNoDataSchema, @@ -16,6 +34,8 @@ IndexesSchema, OtherCoordsSchema, ) +from imod.typing import GridDataArray +from imod.typing.grid import enforce_dim_order, is_planar_grid class River(BoundaryCondition, IRegridPackage): @@ -162,3 +182,235 @@ def _validate(self, schemata, **kwargs): errors = super()._validate(schemata, **kwargs) return errors + + @classmethod + def from_imod5_data( + cls, + key: str, + imod5_data: dict[str, dict[str, GridDataArray]], + target_discretization: StructuredDiscretization, + allocation_option_riv: ALLOCATION_OPTION, + distributing_option_riv: DISTRIBUTING_OPTION, + regridder_types: Optional[RegridMethodType] = None, + ) -> Tuple[Optional["River"], Optional[Drainage]]: + """ + Construct a river-package from iMOD5 data, loaded with the + :func:`imod.formats.prj.open_projectfile_data` function. + + .. note:: + + The method expects the iMOD5 model to be fully 3D, not quasi-3D. + + Parameters + ---------- + imod5_data: dict + Dictionary with iMOD5 data. This can be constructed from the + :func:`imod.formats.prj.open_projectfile_data` method. + target_discretization: StructuredDiscretization package + The grid that should be used for the new package. Does not + need to be identical to one of the input grids. + allocation_option: ALLOCATION_OPTION + allocation option. + distributing_option: dict[str, DISTRIBUTING_OPTION] + distributing option. + regridder_types: RegridMethodType, optional + Optional dataclass with regridder types for a specific variable. + Use this to override default regridding methods. + + Returns + ------- + A MF6 river package, and a drainage package to account + for the infiltration factor which exists in IMOD5 but not in MF6. + Both the river package and the drainage package can be None, + this can happen if the infiltration factor is 0 or 1 everywhere. + """ + + logger = logging.logger + # gather discretrizations + target_top = target_discretization.dataset["top"] + target_bottom = target_discretization.dataset["bottom"] + target_idomain = target_discretization.dataset["idomain"] + + # gather input data + data = { + "conductance": imod5_data[key]["conductance"].copy(deep=True), + "stage": imod5_data[key]["stage"].copy(deep=True), + "bottom_elevation": imod5_data[key]["bottom_elevation"].copy(deep=True), + "infiltration_factor": imod5_data[key]["infiltration_factor"].copy( + deep=True + ), + } + is_planar_conductance = is_planar_grid(data["conductance"]) + + # set up regridder methods + if regridder_types is None: + regridder_settings = asdict(cls.get_regrid_methods(), dict_factory=dict) + else: + regridder_settings = asdict(regridder_types, dict_factory=dict) + if "infiltration_factor" not in regridder_settings.keys(): + regridder_settings["infiltration_factor"] = (RegridderType.OVERLAP, "mean") + + regrid_context = RegridderWeightsCache() + + # regrid the input data + regridded_package_data = _regrid_package_data( + data, target_idomain, regridder_settings, regrid_context, {} + ) + + conductance = regridded_package_data["conductance"] + infiltration_factor = regridded_package_data["infiltration_factor"] + + if is_planar_conductance: + riv_allocation = allocate_riv_cells( + allocation_option_riv, + target_idomain == 1, + target_top, + target_bottom, + regridded_package_data["stage"], + regridded_package_data["bottom_elevation"], + ) + + regridded_package_data["conductance"] = distribute_riv_conductance( + distributing_option_riv, + riv_allocation[0], + conductance, + target_top, + target_bottom, + conductance, + regridded_package_data["stage"], + regridded_package_data["bottom_elevation"], + ) + + # create layered arrays of stage and bottom elevation + layered_stage = regridded_package_data["stage"].where(riv_allocation[0]) + layered_stage = enforce_dim_order(layered_stage) + regridded_package_data["stage"] = layered_stage + + layered_bottom_elevation = regridded_package_data["bottom_elevation"].where( + riv_allocation[0] + ) + layered_bottom_elevation = enforce_dim_order(layered_bottom_elevation) + + # due to regridding, the layered_bottom_elevation could be smaller than the + # bottom, so here we overwrite it with bottom if that's + # the case. + + if np.any((target_bottom > layered_bottom_elevation).values[()]): + logger.log( + loglevel=LogLevel.WARNING, + message="Note: riv bottom was detected below model bottom. Updated the riv's bottom.", + additional_depth=0, + ) + layered_bottom_elevation = xr.where( + target_bottom > layered_bottom_elevation, + target_bottom, + layered_bottom_elevation, + ) + + regridded_package_data["bottom_elevation"] = layered_bottom_elevation + + # update the conductance of the river package to account for the infiltration + # factor + drain_conductance, river_conductance = cls.split_conductance( + regridded_package_data["conductance"], infiltration_factor + ) + regridded_package_data["conductance"] = river_conductance + regridded_package_data.pop("infiltration_factor") + + river_package = River(**regridded_package_data) + # create a drainage package with the conductance we computed from the infiltration factor + drainage_package = cls.create_infiltration_factor_drain( + regridded_package_data["stage"], + drain_conductance, + ) + # remove River package if its mask is False everywhere + mask = ~np.isnan(river_conductance) + if np.any(mask): + river_package = river_package.mask(mask) + else: + river_package = None + + # remove Drainage package if its mask is False everywhere + mask = ~np.isnan(drain_conductance) + if np.any(mask): + drainage_package = drainage_package.mask(mask) + else: + drainage_package = None + return (river_package, drainage_package) + + @classmethod + def create_infiltration_factor_drain( + cls, + drain_elevation: GridDataArray, + drain_conductance: GridDataArray, + ): + """ + Create a drainage package from the river package, to account for the infiltration factor. + This factor is optional in imod5, but it does not exist in MF6, so we mimic its effect + with a Drainage boundary. + """ + + mask = ~np.isnan(drain_conductance) + drainage = Drainage(drain_elevation, drain_conductance) + drainage.mask(mask) + return drainage + + @classmethod + def split_conductance(cls, conductance, infiltration_factor): + """ + Seperates (exfiltration) conductance with an infiltration factor (iMODFLOW) into + a drainage conductance and a river conductance following methods explained in Zaadnoordijk (2009). + + Parameters + ---------- + conductance : xr.DataArray or float + Exfiltration conductance. Is the default conductance provided to the iMODFLOW river package + infiltration_factor : xr.DataArray or float + Infiltration factor. The exfiltration conductance is multiplied with this factor to compute + the infiltration conductance. If 0, no infiltration takes place; if 1, infiltration is equal to exfiltration + + Returns + ------- + drainage_conductance : xr.DataArray + conductance for the drainage package + river_conductance : xr.DataArray + conductance for the river package + + Derivation + ---------- + From Zaadnoordijk (2009): + [1] cond_RIV = A/ci + [2] cond_DRN = A * (ci-cd) / (ci*cd) + Where cond_RIV and cond_DRN repsectively are the River and Drainage conductance [L^2/T], + A is the cell area [L^2] and ci and cd respectively are the infiltration and exfiltration resistance [T] + + Taking f as the infiltration factor and cond_d as the exfiltration conductance, we can write (iMOD manual): + [3] ci = cd * (1/f) + [4] cond_d = A/cd + + We can then rewrite equations 1 and 2 to: + [5] cond_RIV = f * cond_d + [6] cond_DRN = (1-f) * cond_d + + References + ---------- + Zaadnoordijk, W. (2009). + Simulating Piecewise-Linear Surface Water and Ground Water Interactions with MODFLOW. + Ground Water. + https://ngwa.onlinelibrary.wiley.com/doi/10.1111/j.1745-6584.2009.00582.x + + iMOD manual v5.2 (2020) + https://oss.deltares.nl/web/imod/ + + """ + if np.any(infiltration_factor > 1): + raise ValueError("The infiltration factor should not exceed 1") + + drainage_conductance = conductance * (1 - infiltration_factor) + + river_conductance = conductance * infiltration_factor + + # clean up the packages + drainage_conductance = drainage_conductance.where(drainage_conductance > 0) + river_conductance = river_conductance.where(river_conductance > 0) + return drainage_conductance, river_conductance diff --git a/imod/tests/test_mf6/test_mf6_riv.py b/imod/tests/test_mf6/test_mf6_riv.py index 84a83062b..ff32bab47 100644 --- a/imod/tests/test_mf6/test_mf6_riv.py +++ b/imod/tests/test_mf6/test_mf6_riv.py @@ -10,8 +10,12 @@ from pytest_cases import parametrize_with_cases import imod +from imod.mf6.dis import StructuredDiscretization from imod.mf6.write_context import WriteContext +from imod.prepare.topsystem.allocation import ALLOCATION_OPTION +from imod.prepare.topsystem.conductance import DISTRIBUTING_OPTION from imod.schemata import ValidationError +from imod.typing.grid import ones_like, zeros_like @pytest.fixture(scope="function") @@ -387,3 +391,76 @@ def test_write_concentration_period_data(concentration_fc): assert ( data.count("2") == 1755 ) # the number 2 is in the concentration data, and in the cell indices. + + +@pytest.mark.usefixtures("imod5_dataset") +def test_import_river_from_imod5(imod5_dataset, tmp_path): + globaltimes = [np.datetime64("2000-01-01")] + target_dis = StructuredDiscretization.from_imod5_data(imod5_dataset) + + (riv, drn) = imod.mf6.River.from_imod5_data( + "riv-1", + imod5_dataset, + target_dis, + ALLOCATION_OPTION.at_elevation, + DISTRIBUTING_OPTION.by_crosscut_thickness, + regridder_types=None, + ) + + write_context = WriteContext(simulation_directory=tmp_path) + riv.write("riv", globaltimes, write_context) + drn.write("drn", globaltimes, write_context) + + errors = riv._validate( + imod.mf6.River._write_schemata, + idomain=target_dis.dataset["idomain"], + bottom=target_dis.dataset["bottom"], + ) + assert len(errors) == 0 + + errors = drn._validate( + imod.mf6.Drainage._write_schemata, + idomain=target_dis.dataset["idomain"], + bottom=target_dis.dataset["bottom"], + ) + assert len(errors) == 0 + + +@pytest.mark.usefixtures("imod5_dataset") +def test_import_river_from_imod5_infiltration_factors(imod5_dataset): + target_dis = StructuredDiscretization.from_imod5_data(imod5_dataset) + + original_infiltration_factor = imod5_dataset["riv-1"]["infiltration_factor"] + imod5_dataset["riv-1"]["infiltration_factor"] = ones_like( + original_infiltration_factor + ) + + (riv, drn) = imod.mf6.River.from_imod5_data( + "riv-1", + imod5_dataset, + target_dis, + ALLOCATION_OPTION.at_elevation, + DISTRIBUTING_OPTION.by_crosscut_thickness, + regridder_types=None, + ) + + assert riv is not None + assert drn is None + + imod5_dataset["riv-1"]["infiltration_factor"] = zeros_like( + original_infiltration_factor + ) + (riv, drn) = imod.mf6.River.from_imod5_data( + "riv-1", + imod5_dataset, + target_dis, + ALLOCATION_OPTION.at_elevation, + DISTRIBUTING_OPTION.by_crosscut_thickness, + regridder_types=None, + ) + + assert riv is None + assert drn is not None + + # teardown + imod5_dataset["riv-1"]["infiltration_factor"] = original_infiltration_factor diff --git a/imod/tests/test_mf6/test_mf6_simulation.py b/imod/tests/test_mf6/test_mf6_simulation.py index fc2373fff..4c4051f9e 100644 --- a/imod/tests/test_mf6/test_mf6_simulation.py +++ b/imod/tests/test_mf6/test_mf6_simulation.py @@ -479,9 +479,11 @@ def test_import_from_imod5(imod5_dataset, tmp_path): default_simulation_distributing_options, ) - simulation["imported_model"] = OutputControl(save_head="last", save_budget="last") + simulation["imported_model"]["output"] = OutputControl( + save_head="last", save_budget="last" + ) simulation.create_time_discretization(["01-01-2003", "02-01-2003"]) - # write and validate the simulation - simulation.write(tmp_path, False, True, False) + # write and validate the simulation. + simulation.write(tmp_path, binary=False, validate=True) From 04ec40a90325ac7f9c7204e3599f3ddfc16b46cc Mon Sep 17 00:00:00 2001 From: luitjansl <64598682+luitjansl@users.noreply.github.com> Date: Fri, 14 Jun 2024 15:23:31 +0200 Subject: [PATCH 16/53] Issue #1052 log filtered wells (#1067) Fixes #1052 # Description when importing wells from imod5: If not all wells could be assigned to the modflow6 model (this can be due to inactive cells, or due to constraints of minimum thickness/permeability) then a log message will be generated to document in the log file that not all wells were successfully imported. # Checklist - [X] Links to correct issue - [X] Update changelog, if changes affect users - [X] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [X] Unit tests were added - [ ] **If feature added**: Added/extended example --------- Co-authored-by: Joeri van Engelen --- docs/api/changelog.rst | 1 + imod/mf6/wel.py | 39 ++++++++-- imod/tests/test_mf6/test_mf6_wel.py | 107 ++++++++++++++++++++++++++++ 3 files changed, 141 insertions(+), 6 deletions(-) diff --git a/docs/api/changelog.rst b/docs/api/changelog.rst index 15a4f0318..13d2b17ab 100644 --- a/docs/api/changelog.rst +++ b/docs/api/changelog.rst @@ -14,6 +14,7 @@ Changed ~~~~~~~ - :class:`imod.mf6.Well` now also validates that well filter top is above well filter bottom - :function:`open_projectfile_data` now also imports well filter top and bottom. +- :class:`imod.mf6.Well` now logs a warning if any wells are removed during writing. [Unreleased] ------------ diff --git a/imod/mf6/wel.py b/imod/mf6/wel.py index e10ec3b4b..210b780ab 100644 --- a/imod/mf6/wel.py +++ b/imod/mf6/wel.py @@ -1,5 +1,6 @@ from __future__ import annotations +import textwrap import warnings from typing import Any, Optional, Tuple, Union @@ -11,7 +12,8 @@ import xugrid as xu import imod -from imod.logging import init_log_decorator +from imod.logging import init_log_decorator, logger +from imod.logging.loglevel import LogLevel from imod.logging.logging_decorators import standard_log_decorator from imod.mf6.boundary_condition import ( BoundaryCondition, @@ -414,7 +416,7 @@ def __create_dataset_vars( """ Create dataset with all variables (rate, concentration), with a similar shape as the cellids. """ - data_vars = ["rate"] + data_vars = ["id", "rate"] if "concentration" in wells_assigned.columns: data_vars.append("concentration") @@ -548,9 +550,6 @@ def to_mf6_pkg( Parameters ---------- - is_partitioned: bool - validate: bool - Run validation before converting active: {xarry.DataArray, xugrid.UgridDataArray} Grid with active cells. top: {xarry.DataArray, xugrid.UgridDataArray} @@ -559,6 +558,11 @@ def to_mf6_pkg( Grid with bottom of model layers. k: {xarry.DataArray, xugrid.UgridDataArray} Grid with hydraulic conductivities. + validate: bool + Run validation before converting + is_partitioned: bool + Set to true if model has been partitioned + Returns ------- Mf6Wel @@ -574,11 +578,11 @@ def to_mf6_pkg( minimum_thickness = self.dataset["minimum_thickness"].item() wells_df = self.__create_wells_df() + nwells_df = len(wells_df["id"].unique()) wells_assigned = self.__create_assigned_wells( wells_df, active, top, bottom, k, minimum_k, minimum_thickness ) - nwells_df = len(wells_df["id"].unique()) nwells_assigned = ( 0 if wells_assigned.empty else len(wells_assigned["id"].unique()) ) @@ -602,8 +606,31 @@ def to_mf6_pkg( ds["print_flows"] = self["print_flows"].values[()] ds["print_input"] = self["print_input"].values[()] + filtered_wells = [ + id for id in wells_df["id"].unique() if id not in ds["id"].values + ] + if len(filtered_wells) > 0: + message = self.to_mf6_package_information(filtered_wells) + logger.log(loglevel=LogLevel.WARNING, message=message, additional_depth=2) + + ds = ds.drop_vars("id") + return Mf6Wel(**ds.data_vars) + def to_mf6_package_information(self, filtered_wells): + message = textwrap.dedent( + """Some wells were not placed in the MF6 well package. This + can be due to inactive cells or permeability/thickness constraints.\n""" + ) + if len(filtered_wells) < 10: + message += "The filtered wells are: \n" + else: + message += " The first 10 unplaced wells are: \n" + + for i in range(min(10, len(filtered_wells))): + message += f" id = {filtered_wells[i]} x = {self.dataset['x'][int(filtered_wells[i])].values[()]} y = {self.dataset['y'][int(filtered_wells[i])].values[()]} \n" + return message + def mask(self, domain: GridDataArray) -> Well: """ Mask wells based on two-dimensional domain. For three-dimensional diff --git a/imod/tests/test_mf6/test_mf6_wel.py b/imod/tests/test_mf6/test_mf6_wel.py index c95d5b7e0..443398b5f 100644 --- a/imod/tests/test_mf6/test_mf6_wel.py +++ b/imod/tests/test_mf6/test_mf6_wel.py @@ -1,4 +1,5 @@ import pathlib +import sys import tempfile import textwrap from contextlib import nullcontext as does_not_raise @@ -10,6 +11,8 @@ from pytest_cases import parametrize_with_cases import imod +from imod.logging.config import LoggerType +from imod.logging.loglevel import LogLevel from imod.mf6.utilities.grid import broadcast_to_full_domain from imod.mf6.write_context import WriteContext from imod.schemata import ValidationError @@ -179,6 +182,110 @@ def test_to_mf6_pkg__high_lvl_transient(basic_dis, well_high_lvl_test_data_trans np.testing.assert_equal(mf6_ds["rate"].values, rate_expected) +def test_to_mf6_pkg__logging_with_message( + tmp_path, basic_dis, well_high_lvl_test_data_transient +): + # Arrange + logfile_path = tmp_path / "logfile.txt" + idomain, top, bottom = basic_dis + modified_well_fixture = list(well_high_lvl_test_data_transient) + + # create an idomain where layer 1 is active and layer 2 and 3 are inactive. + # layer 1 has a bottom at -6, layer 2 at -35 and layer 3 at -120 + # so only wells that have a filter top above -6 will end up in the simulation + active = idomain == 1 + + active.loc[1, :, :] = True + active.loc[2:, :, :] = False + + # modify the well filter top and filter bottoms so that + # well 0 is not placed + # well 1 is partially placed + # well 2 is fully placed + # well 3 is partially placed + # wells 4 to 7 are nog placed + modified_well_fixture[2] = [ + -6.0, + -3.0, + 0.0, + 0.0, + -6.0, + -6.0, + -6.0, + -6.0, + ] + modified_well_fixture[3] = [ + -102.0, + -102.0, + -6, + -102.0, + -1020.0, + -1020.0, + -1020.0, + -1020.0, + ] + + with open(logfile_path, "w") as sys.stdout: + imod.logging.configure( + LoggerType.PYTHON, + log_level=LogLevel.DEBUG, + add_default_file_handler=False, + add_default_stream_handler=True, + ) + + wel = imod.mf6.Well(*modified_well_fixture) + + k = xr.ones_like(idomain) + _ = wel.to_mf6_pkg(active, top, bottom, k) + + # the wells that were fully or partially placed should not appear in the log message + # but all the wells that are completely left out should be listed + with open(logfile_path, "r") as log_file: + log = log_file.read() + assert "Some wells were not placed" in log + assert "id = 1" not in log + assert "id = 2" not in log + assert "id = 3" not in log + assert "id = 0" in log + assert "id = 4" in log + assert "id = 5" in log + assert "id = 6" in log + assert "id = 7" in log + + +def test_to_mf6_pkg__logging_without_message( + tmp_path, basic_dis, well_high_lvl_test_data_transient +): + # This test activates logging, and then converts a high level well package to + # an MF6 package, in such a way that all the wells can be placed. + # Logging is active, and the log file should not include the "Some wells were not placed" + # message + logfile_path = tmp_path / "logfile.txt" + idomain, top, bottom = basic_dis + + with open(logfile_path, "w") as sys.stdout: + imod.logging.configure( + LoggerType.PYTHON, + log_level=LogLevel.DEBUG, + add_default_file_handler=False, + add_default_stream_handler=True, + ) + + wel = imod.mf6.Well(*well_high_lvl_test_data_transient) + active = idomain == 1 + k = xr.ones_like(idomain) + + active.loc[1, :, :] = True + active.loc[2:, :, :] = True + + # Act + _ = wel.to_mf6_pkg(active, top, bottom, k) + + with open(logfile_path, "r") as log_file: + log = log_file.read() + assert "Some wells were not placed" not in log + + @pytest.mark.parametrize("save_flows", [True, False]) @pytest.mark.parametrize("print_input", [True, False]) @pytest.mark.parametrize("print_flows", [True, False]) From f2e70aaa9ec525a39cd7cbbd853353e3aeb960cc Mon Sep 17 00:00:00 2001 From: luitjansl <64598682+luitjansl@users.noreply.github.com> Date: Fri, 14 Jun 2024 16:31:41 +0200 Subject: [PATCH 17/53] Issue #502 hfb import (#1070) Fixes #502 # Description Converts hfb's from imod5 to mf6, but only in the following cases: - the hfb has an assgined layer that is not zero - the hfb is mappable to the LayeredHorizontalFlowBarrierResistance class. It creates a single mf6 hfb package containing all the hfb's that are present in the model domain area. The hfb package is added to the simulation. # Checklist - [X] Links to correct issue - [ ] Update changelog, if changes affect users - [X] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [X] Unit tests were added - [ ] **If feature added**: Added/extended example --------- Co-authored-by: Joeri van Engelen --- imod/mf6/hfb.py | 27 +++++++++++++++++++++- imod/mf6/model_gwf.py | 8 +++++++ imod/tests/test_mf6/test_mf6_hfb.py | 16 +++++++++++++ imod/tests/test_mf6/test_mf6_simulation.py | 2 +- 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/imod/mf6/hfb.py b/imod/mf6/hfb.py index 5163005fa..c61146a35 100644 --- a/imod/mf6/hfb.py +++ b/imod/mf6/hfb.py @@ -1080,5 +1080,30 @@ def _compute_barrier_values( edge_index, idomain, ) - return barrier_values + + @classmethod + def from_imod5_dataset(cls, imod5_data: dict[str, dict[str, GridDataArray]]): + imod5_keys = list(imod5_data.keys()) + hfb_keys = [key for key in imod5_keys if key[0:3] == "hfb"] + if len(hfb_keys) == 0: + raise ValueError("no hfb keys present.") + + compound_dataframe = None + for hfb_key in hfb_keys: + hfb_dict = imod5_data[hfb_key] + if not list(hfb_dict.keys()) == ["geodataframe", "layer"]: + raise ValueError("hfb is not a LayeredHorizontalFlowBarrierResistance") + layer = hfb_dict["layer"] + if layer == 0: + raise ValueError( + "assigning to layer 0 is not supported yet for import of HFB's" + ) + geometry_layer = hfb_dict["geodataframe"] + geometry_layer["layer"] = layer + if compound_dataframe is None: + compound_dataframe = geometry_layer + else: + compound_dataframe = compound_dataframe._append(geometry_layer) + + return LayeredHorizontalFlowBarrierResistance(compound_dataframe) diff --git a/imod/mf6/model_gwf.py b/imod/mf6/model_gwf.py index 6d5e98376..be0b9eb69 100644 --- a/imod/mf6/model_gwf.py +++ b/imod/mf6/model_gwf.py @@ -11,6 +11,7 @@ from imod.mf6.clipped_boundary_condition_creator import create_clipped_boundary from imod.mf6.dis import StructuredDiscretization from imod.mf6.drn import Drainage +from imod.mf6.hfb import LayeredHorizontalFlowBarrierResistance from imod.mf6.ic import InitialConditions from imod.mf6.model import Modflow6Model from imod.mf6.npf import NodePropertyFlow @@ -261,4 +262,11 @@ def from_imod5_data( result[riv_key + "riv"] = riv_pkg if drn_pkg is not None: result[riv_key + "drn"] = drn_pkg + + # import hfb + hfb_keys = [key for key in imod5_keys if key[0:3] == "hfb"] + if len(hfb_keys) != 0: + hfb = LayeredHorizontalFlowBarrierResistance.from_imod5_dataset(imod5_data) + result["hfb"] = hfb + return result diff --git a/imod/tests/test_mf6/test_mf6_hfb.py b/imod/tests/test_mf6/test_mf6_hfb.py index 3e7c61109..81a242d16 100644 --- a/imod/tests/test_mf6/test_mf6_hfb.py +++ b/imod/tests/test_mf6/test_mf6_hfb.py @@ -16,7 +16,9 @@ LayeredHorizontalFlowBarrierMultiplier, LayeredHorizontalFlowBarrierResistance, ) +from imod.mf6.dis import StructuredDiscretization from imod.mf6.hfb import to_connected_cells_dataset +from imod.mf6.npf import NodePropertyFlow from imod.mf6.utilities.regrid import RegridderWeightsCache from imod.tests.fixtures.flow_basic_fixture import BasicDisSettings from imod.typing.grid import ones_like @@ -440,3 +442,17 @@ def test_set_options(print_input, parameterizable_basic_dis): k = ones_like(top) mf6_package = hfb.to_mf6_pkg(idomain, top, bottom, k) assert mf6_package.dataset["print_input"].values[()] == print_input + + +@pytest.mark.usefixtures("imod5_dataset") +def test_hfb_from_imod5(imod5_dataset, tmp_path): + target_dis = StructuredDiscretization.from_imod5_data(imod5_dataset) + target_npf = NodePropertyFlow.from_imod5_data( + imod5_dataset, target_dis.dataset["idomain"] + ) + + hfb = LayeredHorizontalFlowBarrierResistance.from_imod5_dataset(imod5_dataset) + hfb_package = hfb.to_mf6_pkg( + target_dis["idomain"], target_dis["top"], target_dis["bottom"], target_npf["k"] + ) + assert list(np.unique(hfb_package["layer"].values)) == [3, 21] diff --git a/imod/tests/test_mf6/test_mf6_simulation.py b/imod/tests/test_mf6/test_mf6_simulation.py index 4c4051f9e..3e9dda2dd 100644 --- a/imod/tests/test_mf6/test_mf6_simulation.py +++ b/imod/tests/test_mf6/test_mf6_simulation.py @@ -479,7 +479,7 @@ def test_import_from_imod5(imod5_dataset, tmp_path): default_simulation_distributing_options, ) - simulation["imported_model"]["output"] = OutputControl( + simulation["imported_model"]["oc"] = OutputControl( save_head="last", save_budget="last" ) From 2e7bc8508e30d77b84431cebdcc707a6e73cee22 Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Tue, 18 Jun 2024 14:47:25 +0200 Subject: [PATCH 18/53] Issue #502 hfb import (#1078) Follow-up on: https://github.com/Deltares/imod-python/pull/1070 # Description For some reason, I erronously merged #1070. This implements my suggestion to concatenate pandas dataframes. # Checklist - [x] Links to correct issue - [ ] Update changelog, if changes affect users - [x] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [ ] Unit tests were added - [ ] **If feature added**: Added/extended example --------- Co-authored-by: luitjan --- imod/mf6/hfb.py | 11 +++++------ imod/mf6/wel.py | 2 +- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/imod/mf6/hfb.py b/imod/mf6/hfb.py index c61146a35..45d4460c6 100644 --- a/imod/mf6/hfb.py +++ b/imod/mf6/hfb.py @@ -4,10 +4,11 @@ import typing from copy import deepcopy from enum import Enum -from typing import TYPE_CHECKING, Optional, Tuple +from typing import TYPE_CHECKING, List, Optional, Tuple import cftime import numpy as np +import pandas as pd import xarray as xr import xugrid as xu from fastcore.dispatch import typedispatch @@ -1089,7 +1090,7 @@ def from_imod5_dataset(cls, imod5_data: dict[str, dict[str, GridDataArray]]): if len(hfb_keys) == 0: raise ValueError("no hfb keys present.") - compound_dataframe = None + dataframe_ls: List[gpd.GeoDataFrame] = [] for hfb_key in hfb_keys: hfb_dict = imod5_data[hfb_key] if not list(hfb_dict.keys()) == ["geodataframe", "layer"]: @@ -1101,9 +1102,7 @@ def from_imod5_dataset(cls, imod5_data: dict[str, dict[str, GridDataArray]]): ) geometry_layer = hfb_dict["geodataframe"] geometry_layer["layer"] = layer - if compound_dataframe is None: - compound_dataframe = geometry_layer - else: - compound_dataframe = compound_dataframe._append(geometry_layer) + dataframe_ls.append(geometry_layer) + compound_dataframe = pd.concat(dataframe_ls, ignore_index=True) return LayeredHorizontalFlowBarrierResistance(compound_dataframe) diff --git a/imod/mf6/wel.py b/imod/mf6/wel.py index 210b780ab..7a2fa8783 100644 --- a/imod/mf6/wel.py +++ b/imod/mf6/wel.py @@ -13,8 +13,8 @@ import imod from imod.logging import init_log_decorator, logger -from imod.logging.loglevel import LogLevel from imod.logging.logging_decorators import standard_log_decorator +from imod.logging.loglevel import LogLevel from imod.mf6.boundary_condition import ( BoundaryCondition, DisStructuredBoundaryCondition, From 90b245d4557ae89949d07c7c4a9bd7b03efd791c Mon Sep 17 00:00:00 2001 From: luitjan Date: Wed, 26 Jun 2024 16:07:07 +0200 Subject: [PATCH 19/53] Merge branch 'master' into imod5_converter_feature_branch # Conflicts: # pixi.lock --- pixi.lock | 10378 ++++++++++++++++++++++++++-------------------------- 1 file changed, 5113 insertions(+), 5265 deletions(-) diff --git a/pixi.lock b/pixi.lock index 8f1a98ef0..4559ec07b 100644 --- a/pixi.lock +++ b/pixi.lock @@ -12,26 +12,26 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/aiohttp-3.9.5-py311h459d7ec_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.11-hd590300_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.12-h4ab18f5_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aom-3.8.2-h59595ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.0-hac33072_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asciitree-0.3.3-py_2.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/atk-1.0-2.38.0-hd4edc92_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/atk-1.0-2.38.0-h04ea711_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.1-h166bdaf_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-23.2.0-pyh71513ae_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.7.17-he0b1f16_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.6.11-heb1d5e4_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.9.15-hd590300_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.2.18-hce8ee76_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.4.2-h01f5eca_8.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.8.1-hdb68c23_10.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.14.7-hbfbeace_6.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.10.3-h50844eb_4.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.5.7-hb7bd14b_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.1.15-hce8ee76_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.1.18-hce8ee76_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.26.6-hf567797_4.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.267-hbf3e495_6.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.7.20-h5f1c8d9_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.6.12-h2ba76a8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.9.17-h4ab18f5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.2.18-h36a0aea_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.4.2-h161de36_10.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.8.1-h63f54a0_13.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.14.8-h96d4d28_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.10.4-hcc7299c_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.5.9-h10bd90f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.1.16-h36a0aea_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.1.18-h36a0aea_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.26.8-h4f3a3cc_11.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.267-h51dfee4_8.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.11.1-h91d86a7_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.10.0-h00ab1b0_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.5.0-h94269e2_4.conda @@ -51,12 +51,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/build-0.7.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hd590300_5.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.28.1-hd590300_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.2.2-hbcca054_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.6.2-hbcca054_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.0-h3faef2a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.2.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-1.16.0-py311hb3a22ac_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/cfitsio-4.3.1-hbdc6101_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/cftime-1.6.3-py311h18e1886_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cfitsio-4.4.0-hbdc6101_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cftime-1.6.4-py311h18e1886_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.3.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.1.7-unix_pyh707e725_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1-py_0.tar.bz2 @@ -66,8 +66,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/contextily-1.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.2.1-py311h9547e67_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/coverage-7.5.1-py311h331c9d8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-42.0.7-py311h4a61cc7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/coverage-7.5.3-py311h331c9d8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-42.0.8-py311h4a61cc7_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cytoolz-0.12.3-py311h459d7ec_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/dask-2023.12.1-pyhd8ed1ab_0.conda @@ -82,10 +82,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/eigen-3.4.0-h00ab1b0_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.5.0-hcb278e6_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.38-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.6.2-h59595ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.45-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fasteners-0.17.3-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/ffmpeg-6.1.1-gpl_hee4b679_108.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ffmpeg-6.1.1-gpl_he44c6f3_112.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/fiona-1.9.6-py311hf8e0aa6_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/flopy-3.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/fltk-1.3.9-hea138e6_0.conda @@ -98,15 +98,15 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.14.2-h14ed4e7_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.52.1-py311h331c9d8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.53.0-py311h331c9d8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/freeimage-3.18.0-h4b96d29_20.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/freetype-2.12.1-h267a509_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/freexl-2.0.0-h743c826_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/fribidi-1.0.10-h36c2ea0_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/frozenlist-1.4.1-py311h459d7ec_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2024.5.0-pyhff2d567_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/gdal-3.8.4-py311h8be719e_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/gdk-pixbuf-2.42.10-h829c605_5.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2024.6.0-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gdal-3.8.4-py311h8be719e_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gdk-pixbuf-2.42.12-hb9ae30d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/geographiclib-2.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-0.14.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-base-0.14.4-pyha770c72_0.conda @@ -116,27 +116,27 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/gettext-0.22.5-h59595ed_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gettext-tools-0.22.5-h59595ed_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-he1b5a44_1004.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/gh-2.49.2-he0e2781_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gh-2.51.0-he0e2781_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gl2ps-1.4.2-h0708190_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/glew-2.1.0-h9c3ff4c_2.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/glib-2.78.4-hfc55251_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.78.4-hfc55251_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.0-hed5481d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/glib-2.80.2-hf974151_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.80.2-hb6ce0ca_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-h59595ed_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gmsh-4.12.2-h6b98cf8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gnutls-3.7.9-hb077bed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.13-h59595ed_1003.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/graphviz-9.0.0-h78e8752_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.22.9-h8e1006c_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.22.9-h98fc4e7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/graphviz-11.0.0-hc68bbd7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.24.4-h9ad1361_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.24.4-haf2f30d_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gtk2-2.24.33-h280cfa0_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gts-0.7.6-h977cf35_4.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-8.3.0-h3d44ed6_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-8.5.0-hfac3d4d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hatchling-1.24.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/hdf4-4.2.15-h2a13503_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/hdf5-1.14.3-nompi_h4f84152_101.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.6-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/hdf5-1.14.3-nompi_hdf9ad27_105.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.103.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-73.2-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 @@ -161,18 +161,15 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.2-h659d440_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lame-3.100-h166bdaf_1003.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.16-hb7c19ff_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_6.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h27087fc_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20240116.2-cxx17_h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.3-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.7.4-hfca40fe_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-15.0.2-he70291f_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-15.0.2-hac33072_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-15.0.2-hac33072_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-flight-15.0.2-hd42f311_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-flight-sql-15.0.2-h9241762_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-gandiva-15.0.2-hd4ab825_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-15.0.2-h9241762_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-16.1.0-hefa796f_1_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-16.1.0-hac33072_1_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-16.1.0-hac33072_1_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-16.1.0-h7e0c224_1_cpu.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libasprintf-0.22.5-h661eb56_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libasprintf-devel-0.22.5-h661eb56_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libass-0.17.1-h8fe9dca_1.conda @@ -183,32 +180,33 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.1.0-hd590300_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libcap-2.69-h0f662aa_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-22_linux64_openblas.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang-15.0.7-default_h127d8a8_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang13-15.0.7-default_h5d6823c_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp15-15.0.7-default_h127d8a8_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp18.1-18.1.7-default_h9bb3924_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang13-18.1.7-default_h087397f_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h4637d8d_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.8.0-hca28451_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.19-hd590300_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.20-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.120-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20191231-he28a2e2_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.5.0-hcb278e6_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.6.2-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libflac-1.4.3-h59595ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_10.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcrypt-1.10.3-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgd-2.3.3-h119a65a_9.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgdal-3.8.4-h9323651_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgdal-3.8.4-h7c88fdf_5.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-0.22.5-h59595ed_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-devel-0.22.5-h59595ed_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.2.0-h69a702a_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-13.2.0-hca663fb_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.78.4-h783c2da_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.2.0-h69a702a_10.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-13.2.0-h3d2ce59_10.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.80.2-hf974151_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libglu-9.0.0-hac7e632_1003.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.22.0-h9be4e54_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.22.0-hc7a4891_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_10.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.23.0-h9be4e54_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.23.0-hc7a4891_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgpg-error-1.49-h4f305b6_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.62.2-h15f2491_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.10.0-default_h5622ce7_1001.conda @@ -219,59 +217,59 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-22_linux64_openblas.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm14-14.0.6-hcd5def8_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm15-15.0.7-hb3ce162_4.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm16-16.0.6-hb3ce162_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libnetcdf-4.9.2-nompi_h9612171_113.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm18-18.1.7-hb77312f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnetcdf-4.9.2-nompi_h135f659_114.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.58.0-h47da74e_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libnl-3.9.0-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.4-h7f98852_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.27-pthreads_h413a1c8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-2024.0.0-h2da1b83_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-auto-batch-plugin-2024.0.0-hb045406_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-auto-plugin-2024.0.0-hb045406_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-hetero-plugin-2024.0.0-h5c03a75_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-cpu-plugin-2024.0.0-h2da1b83_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-gpu-plugin-2024.0.0-h2da1b83_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-ir-frontend-2024.0.0-h5c03a75_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-onnx-frontend-2024.0.0-h07e8aee_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-paddle-frontend-2024.0.0-h07e8aee_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-pytorch-frontend-2024.0.0-he02047a_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-tensorflow-frontend-2024.0.0-h39126c6_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-tensorflow-lite-frontend-2024.0.0-he02047a_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-2024.1.0-h2da1b83_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-auto-batch-plugin-2024.1.0-hb045406_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-auto-plugin-2024.1.0-hb045406_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-hetero-plugin-2024.1.0-h5c03a75_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-cpu-plugin-2024.1.0-h2da1b83_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-gpu-plugin-2024.1.0-h2da1b83_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-npu-plugin-2024.1.0-he02047a_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-ir-frontend-2024.1.0-h5c03a75_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-onnx-frontend-2024.1.0-h07e8aee_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-paddle-frontend-2024.1.0-h07e8aee_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-pytorch-frontend-2024.1.0-he02047a_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-tensorflow-frontend-2024.1.0-h39126c6_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-tensorflow-lite-frontend-2024.1.0-he02047a_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libopus-1.3.1-h7f98852_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/libparquet-15.0.2-h6a7eafb_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libparquet-16.1.0-h6a7eafb_1_cpu.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.43-h2797004_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libpq-16.3-ha72fbe1_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-4.25.3-h08a7969_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libraw-0.21.1-h2a13503_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2023.09.01-h5a48ba9_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/librsvg-2.56.3-he3f83f7_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/librsvg-2.58.0-hadf69e7_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/librttopo-1.1.0-h8917695_15.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc60ed4a_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libspatialindex-1.9.3-he02047a_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libspatialindex-2.0.0-he02047a_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libspatialite-5.1.0-h7bd4643_4.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.45.3-h2797004_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.46.0-hde9e2c9_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.0-h0841786_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-hc0a3c3a_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-hc0a3c3a_10.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-255-h3516f8a_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libtasn1-4.19.0-h166bdaf_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libtheora-1.1.1-h7f98852_1005.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.19.0-hb90f79a_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.6.0-ha9c0a0a_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.6.0-h1dd3fc0_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libunistring-0.9.10-h7f98852_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.8.0-h166bdaf_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libva-2.21.0-hd590300_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libva-2.21.0-h4ab18f5_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h9c3ff4c_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/libvpx-1.14.0-h59595ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libvpx-1.14.1-hac33072_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-1.4.0-h2c329e2_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.4.0-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.15-h0b41bf4_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.7.0-h662e7e4_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.12.7-hc051c1a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.12.7-hc051c1a_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzip-1.10.1-h2629f0a_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-hd590300_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-h4ab18f5_6.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/llvmlite-0.42.0-py311ha6695c7_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/loguru-0.7.2-py311h38be061_1.conda @@ -287,18 +285,18 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mercantile-1.2.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/metis-5.1.1-h59595ed_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/minizip-4.0.5-h0ab5242_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.2.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/minizip-4.0.6-h9d307f2_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/mpg123-1.32.6-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.0.8-py311h52f7536_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/multidict-6.0.5-py311h459d7ec_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.10.0-py311h331c9d8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/mysql-common-8.0.33-hf1915f5_6.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/mysql-libs-8.0.33-hca2cd23_6.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/mysql-common-8.3.0-hf1915f5_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/mysql-libs-8.3.0-hca2cd23_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h59595ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/netcdf4-1.6.5-nompi_py311h74118c1_101.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/netcdf4-1.6.5-nompi_py311h74118c1_102.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/nettle-3.9.1-h7ab15ed_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/nh3-0.2.17-py311h46250e7_0.conda @@ -309,46 +307,47 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/numcodecs-0.12.1-py311h4332511_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-1.26.4-py311h64a7726_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/occt-7.7.2-all_h4c9f3c6_201.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/occt-7.7.2-novtk_h130ccc2_101.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ocl-icd-2.3.2-hd590300_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/openexr-3.2.2-haf962dd_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/openh264-2.4.1-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.2-h488ebb8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.0-h4ab18f5_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.1-h4ab18f5_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/orc-2.0.0-h17fec99_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/p11-kit-0.24.1-hc5aa10d_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandamesh-0.1.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.2-py311h14de704_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pango-1.52.1-ha41ecd1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pango-1.54.0-h84a9a3c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/partd-1.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.42-hcad00b1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.43-hcad00b1_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pep517-0.13.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-10.3.0-py311h18e6fac_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pixman-0.43.2-h59595ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.11.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.2.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/poppler-24.02.0-h590f24d_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/poppler-24.03.0-h590f24d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/poppler-data-0.4.12-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/postgresql-16.3-h8e811e2_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/proj-9.3.1-h1d62c97_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-5.9.8-py311h459d7ec_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-h36c2ea0_1001.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/pugixml-1.14-h59595ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-16.1-hb77b528_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-hb77b528_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/py-triangle-20230923-py311h459d7ec_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pyarrow-15.0.2-py311h78dcc79_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyarrow-16.1.0-py311h781c19f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-16.1.0-py311h8e2c35d_0_cpu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyarrow-hotfix-0.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.18.2-py311h5ecf98a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.18.4-py311h5ecf98a_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pymetis-2023.1.1-py311hf4706e4_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.1.2-pyhd8ed1ab_0.conda @@ -360,7 +359,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-benchmark-4.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cases-3.8.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-5.0.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.5.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.11.0-he550d4f_1_cpython.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gmsh-4.12.2-h57928b3_0.conda @@ -368,23 +367,23 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2024.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python_abi-3.11-4_cp311.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pyvista-0.43.8-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyvista-0.43.9-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.1-py311h459d7ec_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.8-h5810be5_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.8-hc9dc06e_21.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.7.1-h2471661_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/rapidjson-1.1.0.post20240409-hac33072_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/rasterio-1.3.9-py311ha38370a_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/rdma-core-51.0-hd3aeb46_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/re2-2023.09.01-h7f4b329_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/readme_renderer-42.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-toolbelt-1.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-2.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rioxarray-0.15.5-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/rtree-1.2.0-py311h3bb2b0f_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.4.5-py311hae69bc3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/s2n-1.4.12-h06160fa_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rtree-1.2.0-py311ha1603b9_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.4.9-py311hae69bc3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/s2n-1.4.13-he19d79f_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/scikit-learn-1.5.0-py311he08f58d_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/scipy-1.13.1-py311h517d4fd_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/scooby-0.10.0-pyhd8ed1ab_0.conda @@ -400,7 +399,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/snuggs-1.4.7-py_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.5-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/spdlog-1.12.0-hd2e6256_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/spdlog-1.13.0-hd2e6256_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-5.0.0-pyh6c4a22f_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-gallery-0.16.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-1.0.8-pyhd8ed1ab_0.conda @@ -409,45 +408,46 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-1.0.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.10-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.45.3-h2c6b66d_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/svt-av1-2.0.0-h59595ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.46.0-h6d4b2fc_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/svt-av1-2.1.0-hac33072_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tbb-2021.12.0-h297d8ca_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tbb-devel-2021.12.0-h7c56ddd_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tiledb-2.20.1-hcf523ab_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tiledb-2.21.2-h27f064a_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-w-1.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/toolz-0.12.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.4-py311h459d7ec_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.4.1-py311h331c9d8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.66.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.22-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/twine-5.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.11.0-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.11.0-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tzcode-2024a-h3f72095_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ucx-1.15.0-ha691c75_8.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/uriparser-0.9.8-hac33072_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/utfcpp-4.0.5-ha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/vtk-9.2.6-qt_py311h1234567_220.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/vtk-base-9.2.6-qt_py311h1234567_220.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/vtk-io-ffmpeg-9.2.6-qt_py311h1234567_220.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/vtk-9.3.0-qt_py311h1234567_200.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/vtk-base-9.3.0-qt_py311h1234567_200.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/vtk-io-ffmpeg-9.3.0-qt_py311h1234567_200.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/wayland-1.23.0-h5291e77_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/x264-1!164.3095-h166bdaf_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/x265-3.5-h924138e_3.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.5.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.6.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.0-hd590300_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.4-hd590300_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-h8ee46fc_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.0-h8ee46fc_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.9-hd590300_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.1-h8ee46fc_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xerces-c-3.2.5-hac6953d_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.41-hd590300_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.42-h4ab18f5_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-fixesproto-5.0-h7f98852_1002.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-kbproto-1.0.7-h7f98852_1002.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.1-hd590300_0.conda @@ -465,14 +465,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-xf86vidmodeproto-2.3.1-h7f98852_1002.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-xproto-7.0.31-h7f98852_1007.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.10.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h7f98852_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/yarl-1.9.4-py311h459d7ec_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-2.18.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-2.18.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zict-3.0.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.2.13-hd590300_5.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.19.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.2.13-h4ab18f5_6.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.6-ha6fb4c9_0.conda - pypi: https://files.pythonhosted.org/packages/50/fa/a2561d6837cd45a3971c514222e94d3ded3f105993ddcf4983ed68ce3da3/mypy2junit-1.9.0-py3-none-any.whl osx-64: @@ -518,12 +518,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/build-0.7.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h10d778d_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.28.1-h10d778d_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/ca-certificates-2024.2.2-h8857fd0_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ca-certificates-2024.6.2-h8857fd0_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/cairo-1.18.0-h99e66fa_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.2.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/cffi-1.16.0-py311hc0b63fd_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/cfitsio-4.3.1-h60fb419_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/cftime-1.6.3-py311hce3442d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/cftime-1.6.4-py311hce3442d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.3.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.1.7-unix_pyh707e725_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1-py_0.tar.bz2 @@ -533,7 +533,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/contextily-1.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.2.1-py311h1d816ee_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/coverage-7.5.1-py311h42a8b16_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/coverage-7.5.3-py311h72ae277_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/cytoolz-0.12.3-py311he705e18_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/dask-2023.12.1-pyhd8ed1ab_0.conda @@ -548,7 +548,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/expat-2.5.0-hf0c8a7f_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.38-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.45-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fasteners-0.17.3-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/ffmpeg-6.1.1-gpl_h6b92a41_108.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/fiona-1.9.6-py311hd2ff552_0.conda @@ -563,13 +563,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/fontconfig-2.14.2-h5bb23bf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-64/fonttools-4.52.1-py311h72ae277_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/fonttools-4.53.0-py311h72ae277_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/freeimage-3.18.0-hdc0ade2_20.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/freetype-2.12.1-h60636b9_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/freexl-2.0.0-h3ec172f_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/fribidi-1.0.10-hbcb3906_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/frozenlist-1.4.1-py311he705e18_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2024.5.0-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2024.6.0-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/gdal-3.8.4-py311haaa0e4f_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/gdk-pixbuf-2.42.10-hd9e0ca3_5.conda - conda: https://conda.anaconda.org/conda-forge/noarch/geographiclib-2.0-pyhd8ed1ab_0.tar.bz2 @@ -581,13 +581,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/gettext-0.22.5-h5ff76d1_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/gettext-tools-0.22.5-h5ff76d1_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/gflags-2.2.2-hb1e8313_1004.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-64/gh-2.49.2-he13f2d6_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/gh-2.51.0-he13f2d6_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/giflib-5.2.2-h10d778d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/gl2ps-1.4.2-h4cff582_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/glew-2.1.0-h046ec9c_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/glib-2.78.4-h2d185b6_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/glib-tools-2.78.4-h2d185b6_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/glog-0.7.0-h31b1b29_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/glog-0.7.1-h2790a97_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/gmp-6.3.0-h73e2aa4_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/gmsh-4.12.2-h48a2193_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/gnutls-3.7.9-h1951705_0.conda @@ -600,8 +600,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/harfbuzz-8.3.0-hf45c392_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hatchling-1.24.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/hdf4-4.2.15-h8138101_7.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/hdf5-1.14.3-nompi_hb512a33_101.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.6-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/hdf5-1.14.3-nompi_h687a608_105.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.103.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-73.2-hf5e326d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 @@ -676,7 +676,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/libllvm14-14.0.6-hc8e404f_4.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libllvm15-15.0.7-hbedff68_4.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libllvm16-16.0.6-hbedff68_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libnetcdf-4.9.2-nompi_h7760872_113.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libnetcdf-4.9.2-nompi_h7334405_114.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.58.0-h64cf6d3_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libogg-1.3.4-h35c211d_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/libopenblas-0.3.27-openmp_hfef2a42_0.conda @@ -700,9 +700,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/libre2-11-2023.09.01-h81f5012_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/librsvg-2.56.3-h1877882_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/librttopo-1.1.0-hf05f67e_15.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libspatialindex-1.9.3-hf036a51_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libspatialindex-2.0.0-hf036a51_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libspatialite-5.1.0-hebe6af1_4.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.45.3-h92b6c6a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.46.0-h1b8f9f3_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libssh2-1.11.0-hd019ec5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libtasn1-4.19.0-hb7f2c08_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/libtheora-1.1.1-h0d85af4_1005.tar.bz2 @@ -711,14 +711,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/libunistring-0.9.10-h0d85af4_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/libutf8proc-2.8.0-hb7f2c08_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/libvorbis-1.3.7-h046ec9c_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-64/libvpx-1.14.0-h73e2aa4_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libvpx-1.14.1-hf036a51_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libwebp-1.4.0-hc207709_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.4.0-h10d778d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libxcb-1.15-hb7f2c08_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.12.7-h3e169fe_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.12.7-h3e169fe_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libzip-1.10.1-hc158999_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.2.13-h8a1eda9_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-18.1.5-h39e0ece_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.2.13-h87427d6_6.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-18.1.7-h15ab845_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/llvmlite-0.42.0-py311hb5c2e0a_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/loguru-0.7.2-py311h6eed73b_1.conda @@ -734,8 +734,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mercantile-1.2.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/metis-5.1.1-h73e2aa4_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/minizip-4.0.5-h37d7099_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.2.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/minizip-4.0.6-ha2864c9_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/msgpack-python-1.0.8-py311h46c8309_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/multidict-6.0.5-py311h5547dcb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2 @@ -744,7 +744,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/mysql-common-8.0.33-h1d20c9b_6.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/mysql-libs-8.0.33-hed35180_6.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h5846eda_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/netcdf4-1.6.5-nompi_py311hab941cd_101.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/netcdf4-1.6.5-nompi_py311hab941cd_102.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/nettle-3.9.1-h8e11ae5_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/nh3-0.2.17-py311hd64b9fd_0.conda @@ -759,10 +759,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/openexr-3.2.2-h3f0570e_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/openh264-2.4.1-h73e2aa4_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.2-h7310d3a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.0-h87427d6_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.1-h87427d6_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/orc-2.0.0-hf146577_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/p11-kit-0.24.1-h65f8906_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandamesh-0.1.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pandas-2.2.2-py311hfdcbad3_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pango-1.52.1-h7f2093b_0.conda @@ -773,10 +773,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/pillow-10.3.0-py311h1b85569_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pixman-0.43.4-h73e2aa4_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.11.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.2.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/poppler-24.02.0-h0c752f9_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/poppler-data-0.4.12-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/postgresql-16.3-h1d90168_0.conda @@ -789,9 +789,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/pyarrow-15.0.2-py311ha429d19_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyarrow-hotfix-0.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.18.2-py311h2786eb7_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.18.4-py311h295b1db_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pymetis-2023.1.1-py311h5fe6d0d_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.1.2-pyhd8ed1ab_0.conda @@ -801,7 +801,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-benchmark-4.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cases-3.8.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-5.0.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.5.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.11.0-he7542f4_1_cpython.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gmsh-4.12.2-h57928b3_0.conda @@ -809,7 +809,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2024.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/python_abi-3.11-4_cp311.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pyvista-0.43.8-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyvista-0.43.9-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.1-py311h2725bcf_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/qt-main-5.15.8-h4385fff_19.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/rapidjson-1.1.0.post20240409-hf036a51_1.conda @@ -817,13 +817,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/re2-2023.09.01-hb168e87_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h9e318b2_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/readme_renderer-42.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-toolbelt-1.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-2.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rioxarray-0.15.5-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/rtree-1.2.0-py311hbc1f44b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.4.5-py311h9a97b26_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/rtree-1.2.0-py311h6785ca5_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.4.9-py311h9a97b26_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/scikit-learn-1.5.0-py311h3c3ac6d_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/scipy-1.13.1-py311h40a1ab3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/scooby-0.10.0-pyhd8ed1ab_0.conda @@ -846,7 +846,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-1.0.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.10-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/sqlite-3.45.3-h7461747_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/sqlite-3.46.0-h28673e1_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/svt-av1-2.0.0-h73e2aa4_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tbb-2021.12.0-h3c5361c_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tbb-devel-2021.12.0-h7393e1e_1.conda @@ -858,25 +858,25 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-w-1.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/toolz-0.12.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/tornado-6.4-py311he705e18_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/tornado-6.4.1-py311h72ae277_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.66.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.22-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/twine-5.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.11.0-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.11.0-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tzcode-2024a-h10d778d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/uriparser-0.9.8-h6aefe2f_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/utfcpp-4.0.5-h694c41f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/vtk-9.2.6-qt_py311h1234567_220.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/vtk-base-9.2.6-qt_py311h1234567_220.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/vtk-io-ffmpeg-9.2.6-qt_py311h1234567_220.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/vtk-9.2.6-qt_py311h1234567_223.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/vtk-base-9.2.6-qt_py311h1234567_223.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/vtk-io-ffmpeg-9.2.6-qt_py311h1234567_223.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/x264-1!164.3095-h775f41a_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/x265-3.5-hbb4e6a2_3.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.5.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.6.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/xerces-c-3.2.5-hbbe9ea5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-fixesproto-5.0-h0d85af4_1002.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-kbproto-1.0.7-h35c211d_1002.tar.bz2 @@ -892,14 +892,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-xextproto-7.3.0-hb7f2c08_1003.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-xproto-7.0.31-h35c211d_1007.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.10.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/xz-5.2.6-h775f41a_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h0d85af4_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/yarl-1.9.4-py311he705e18_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-2.18.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-2.18.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zict-3.0.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/zlib-1.2.13-h8a1eda9_5.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.19.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/zlib-1.2.13-h87427d6_6.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.6-h915ae27_0.conda - pypi: https://files.pythonhosted.org/packages/50/fa/a2561d6837cd45a3971c514222e94d3ded3f105993ddcf4983ed68ce3da3/mypy2junit-1.9.0-py3-none-any.whl osx-arm64: @@ -909,23 +909,23 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aom-3.8.2-h078ce10_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aom-3.9.0-h537b5a7_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asciitree-0.3.3-py_2.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/atk-1.0-2.38.0-hcb7b3dd_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/atk-1.0-2.38.0-hd03087b_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-23.2.0-pyh71513ae_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-auth-0.7.17-h382b9c6_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-cal-0.6.11-hd34e5fa_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-common-0.9.15-h93a5062_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-compression-0.2.18-hd34e5fa_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-event-stream-0.4.2-h247c08a_8.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-http-0.8.1-hf9e830b_10.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-io-0.14.7-h33d81b3_6.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-mqtt-0.10.3-h5f4abda_4.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-s3-0.5.7-h606a3d2_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-sdkutils-0.1.15-hd34e5fa_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-checksums-0.1.18-hd34e5fa_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-crt-cpp-0.26.6-h13f0230_4.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-sdk-cpp-1.11.267-h134aaec_6.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-auth-0.7.20-h5cf208e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-cal-0.6.12-h35c0bb2_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-common-0.9.17-h03532ee_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-compression-0.2.18-h35c0bb2_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-event-stream-0.4.2-h7d5773a_10.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-http-0.8.1-h00faecf_13.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-io-0.14.8-h6dd71cf_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-mqtt-0.10.4-h92d7a41_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-s3-0.5.9-he1e208d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-sdkutils-0.1.16-h35c0bb2_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-checksums-0.1.18-h35c0bb2_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-crt-cpp-0.26.8-h5cd1ed2_11.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-sdk-cpp-1.11.267-h108e708_8.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/azure-core-cpp-1.11.1-he231e37_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/azure-storage-blobs-cpp-12.10.0-h2ffa867_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/azure-storage-common-cpp-12.5.0-h09a5875_4.conda @@ -945,12 +945,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/build-0.7.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-h93a5062_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.28.1-h93a5062_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ca-certificates-2024.2.2-hf0a4a13_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ca-certificates-2024.6.2-hf0a4a13_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cairo-1.18.0-hd1e100b_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.2.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-1.16.0-py311h4a08483_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cfitsio-4.3.1-h808cd33_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cftime-1.6.3-py311h5d790af_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cfitsio-4.4.0-h808cd33_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cftime-1.6.4-py311h5d790af_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.3.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.1.7-unix_pyh707e725_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1-py_0.tar.bz2 @@ -960,7 +960,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/contextily-1.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.2.1-py311hcc98501_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.5.1-py311hd3f4193_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.5.3-py311hd3f4193_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cytoolz-0.12.3-py311h05b510d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/dask-2023.12.1-pyhd8ed1ab_0.conda @@ -974,10 +974,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/eigen-3.4.0-h1995070_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/expat-2.5.0-hb7217d7_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.38-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/expat-2.6.2-hebf3989_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.45-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fasteners-0.17.3-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ffmpeg-6.1.1-gpl_h4f1e072_108.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ffmpeg-6.1.1-gpl_hc16618e_112.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fiona-1.9.6-py311h1c26527_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/flopy-3.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fltk-1.3.9-h31b9a01_0.conda @@ -990,15 +990,15 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fontconfig-2.14.2-h82840c6_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.52.1-py311hd3f4193_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.53.0-py311hd3f4193_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/freeimage-3.18.0-hd0e3f39_20.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.12.1-hadb7bae_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/freexl-2.0.0-hfbad9fb_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fribidi-1.0.10-h27ca646_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/frozenlist-1.4.1-py311h05b510d_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2024.5.0-pyhff2d567_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gdal-3.8.4-py311h43f0207_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gdk-pixbuf-2.42.10-hcea6d13_5.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2024.6.0-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gdal-3.8.4-py311h43f0207_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gdk-pixbuf-2.42.12-h7ddc832_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/geographiclib-2.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-0.14.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-base-0.14.4-pyha770c72_0.conda @@ -1008,27 +1008,27 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gettext-0.22.5-h8fbad5d_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gettext-tools-0.22.5-h8fbad5d_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gflags-2.2.2-hc88da5d_1004.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gh-2.49.2-h163aea0_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gh-2.51.0-h163aea0_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/giflib-5.2.2-h93a5062_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gl2ps-1.4.2-h17b34a0_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/glew-2.1.0-h9f76cd9_2.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/glib-2.78.4-h1059232_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/glib-tools-2.78.4-h1059232_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/glog-0.7.0-hc6770e3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/glib-2.80.2-h535f939_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/glib-tools-2.80.2-h4c882b9_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/glog-0.7.1-heb240a5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gmp-6.3.0-hebf3989_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gmsh-4.12.2-hd427cfb_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gnutls-3.7.9-hd26332c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/graphite2-1.3.13-hebf3989_1003.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/graphviz-9.0.0-h3face73_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gst-plugins-base-1.22.9-h09b4b5e_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gstreamer-1.22.9-h551c6ff_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/graphviz-11.0.0-h9bb9bc9_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gst-plugins-base-1.24.4-h8a8f8c8_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gstreamer-1.24.4-h430e707_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gtk2-2.24.33-h7895bb2_4.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gts-0.7.6-he42f4ea_4.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/harfbuzz-8.3.0-h8f0ba13_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/harfbuzz-8.5.0-h1836168_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hatchling-1.24.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/hdf4-4.2.15-h2ee6834_7.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/hdf5-1.14.3-nompi_h751145d_101.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.6-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/hdf5-1.14.3-nompi_hec07895_105.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.103.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-73.2-hc8870d7_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 @@ -1055,13 +1055,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20240116.2-cxx17_hebf3989_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libaec-1.1.3-hebf3989_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarchive-3.7.4-h83d404f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-15.0.2-h3ee1d8f_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-acero-15.0.2-h3f3aa29_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-dataset-15.0.2-h3f3aa29_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-flight-15.0.2-h224147a_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-flight-sql-15.0.2-hb630850_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-gandiva-15.0.2-h5fa1bb3_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-substrait-15.0.2-hd92e347_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-16.1.0-h23f55cf_1_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-acero-16.1.0-h00cdb27_1_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-dataset-16.1.0-h00cdb27_1_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-substrait-16.1.0-hc68f6b8_1_cpu.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libasprintf-0.22.5-h8fbad5d_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libasprintf-devel-0.22.5-h8fbad5d_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libass-0.17.1-hf7da4fe_1.conda @@ -1071,26 +1068,26 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.1.0-hb547adb_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.1.0-hb547adb_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.9.0-22_osxarm64_openblas.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-15.0.7-default_he012953_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang13-15.0.7-default_h83d0a53_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp16-16.0.6-default_hb63da90_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang13-18.1.7-default_hb9c8b4a_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcrc32c-1.1.2-hbdafb3b_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.8.0-h7b6f9a7_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-17.0.6-h5f092b4_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.19-hb547adb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.20-h93a5062_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20191231-hc8eb9b7_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libevent-2.1.12-h2757513_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.5.0-hb7217d7_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.6.2-hebf3989_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.4.2-h3422bc3_5.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgd-2.3.3-hfdf3952_9.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgdal-3.8.4-ha86f356_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgdal-3.8.4-h7181668_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgettextpo-0.22.5-h8fbad5d_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgettextpo-devel-0.22.5-h8fbad5d_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-5.0.0-13_2_0_hd922786_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-13.2.0-hf226fd6_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libglib-2.78.4-h1635a5e_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgoogle-cloud-2.22.0-hbebe991_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgoogle-cloud-storage-2.22.0-h8a76758_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libglib-2.80.2-h535f939_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgoogle-cloud-2.23.0-hbebe991_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgoogle-cloud-storage-2.23.0-h8a76758_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgrpc-1.62.2-h9c18a4f_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libhwloc-2.10.0-default_h7685b71_1001.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.17-h0d3ecfb_2.conda @@ -1101,51 +1098,51 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libkml-1.3.0-h1eb4d9f_1018.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.9.0-22_osxarm64_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm14-14.0.6-hd1a9a77_4.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm15-15.0.7-h2621b3d_4.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm16-16.0.6-haab561b_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnetcdf-4.9.2-nompi_h291a7c2_113.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm18-18.1.7-hdac5640_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnetcdf-4.9.2-nompi_he469be0_114.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.58.0-ha4dd798_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libogg-1.3.4-h27ca646_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.27-openmp_h6c19121_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-2024.0.0-h200475e_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-arm-cpu-plugin-2024.0.0-h200475e_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-auto-batch-plugin-2024.0.0-hfaea8b3_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-auto-plugin-2024.0.0-hfaea8b3_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-hetero-plugin-2024.0.0-hc7e6747_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-ir-frontend-2024.0.0-hc7e6747_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-onnx-frontend-2024.0.0-h25b35cd_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-paddle-frontend-2024.0.0-h25b35cd_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-pytorch-frontend-2024.0.0-h3f3aa29_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-tensorflow-frontend-2024.0.0-hbc2fe69_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-tensorflow-lite-frontend-2024.0.0-h3f3aa29_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-2024.1.0-h5c9529b_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-arm-cpu-plugin-2024.1.0-h5c9529b_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-auto-batch-plugin-2024.1.0-hcd65546_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-auto-plugin-2024.1.0-hcd65546_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-hetero-plugin-2024.1.0-h88cb26a_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-ir-frontend-2024.1.0-h88cb26a_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-onnx-frontend-2024.1.0-h32b5460_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-paddle-frontend-2024.1.0-h32b5460_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-pytorch-frontend-2024.1.0-h00cdb27_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-tensorflow-frontend-2024.1.0-h2741c3b_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-tensorflow-lite-frontend-2024.1.0-h00cdb27_7.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopus-1.3.1-h27ca646_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libparquet-15.0.2-h5304c63_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libparquet-16.1.0-hcf52c46_1_cpu.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.43-h091b4b1_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libpq-16.3-h7afe498_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libprotobuf-4.25.3-hbfab5d5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libraw-0.21.1-h2ee6834_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libre2-11-2023.09.01-h7b2c953_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/librsvg-2.56.3-h55a2576_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/librsvg-2.58.0-hb3d354b_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/librttopo-1.1.0-hc8f776e_15.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libspatialindex-1.9.3-h00cdb27_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libspatialindex-2.0.0-h00cdb27_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libspatialite-5.1.0-h69abc6b_4.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.45.3-h091b4b1_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.46.0-hfb93653_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.0-h7a5bd25_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libtasn1-4.19.0-h1a8c8d9_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libtheora-1.1.1-h3422bc3_1005.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libthrift-0.19.0-h026a170_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.6.0-ha8a6c65_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.6.0-h07db509_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libunistring-0.9.10-h3422bc3_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libutf8proc-2.8.0-h1a8c8d9_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libvorbis-1.3.7-h9f76cd9_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libvpx-1.14.0-h078ce10_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libvpx-1.14.1-h7bae524_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-1.4.0-h54798ee_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.4.0-h93a5062_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.15-hf346824_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.12.7-ha661575_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.12.7-ha661575_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzip-1.10.1-ha0bc3c6_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.2.13-h53f4e23_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-18.1.5-hde57baf_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.2.13-hfb2fe0b_6.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-18.1.7-hde57baf_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvmlite-0.42.0-py311hf5d242d_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/loguru-0.7.2-py311h267d04e_1.conda @@ -1161,17 +1158,17 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mercantile-1.2.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/metis-5.1.1-hebf3989_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/minizip-4.0.5-hc35e051_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.2.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/minizip-4.0.6-h0615dfd_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgpack-python-1.0.8-py311h6bde47b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/multidict-6.0.5-py311he2be06e_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.10.0-py311hd23d018_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mysql-common-8.0.33-hf9e6398_6.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mysql-libs-8.0.33-he3dca8b_6.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mysql-common-8.3.0-hd1853d3_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mysql-libs-8.3.0-hf036fc4_4.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-hb89a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/netcdf4-1.6.5-nompi_py311hd61c382_101.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/netcdf4-1.6.5-nompi_py311hd61c382_102.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nettle-3.9.1-h40ed0f5_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nh3-0.2.17-py311h94f323b_0.conda @@ -1182,29 +1179,29 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numcodecs-0.12.1-py311hb9542d7_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-1.26.4-py311h7125741_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/occt-7.7.2-all_h1e2436f_201.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/occt-7.7.2-novtk_h5f4376a_101.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openexr-3.2.2-h2c51e1d_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openh264-2.4.1-hebf3989_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.2-h9f1df11_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.0-hfb2fe0b_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.1-hfb2fe0b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/orc-2.0.0-h4aad248_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/p11-kit-0.24.1-h29577a5_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandamesh-0.1.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pandas-2.2.2-py311h4b4568b_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pango-1.52.1-hb067d4f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pango-1.54.0-h5cb9fbc_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/partd-1.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pcre2-10.42-h26f9a81_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pcre2-10.43-h26f9a81_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pep517-0.13.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pillow-10.3.0-py311h0b5d0a1_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pixman-0.43.4-hebf3989_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.11.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.2.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/poppler-24.02.0-h896e6cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/poppler-24.03.0-h896e6cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/poppler-data-0.4.12-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/postgresql-16.3-hdfa2ec6_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/proj-9.3.1-h93d94ba_0.conda @@ -1213,12 +1210,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pugixml-1.14-h13dd4ca_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/py-triangle-20230923-py311h05b510d_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyarrow-15.0.2-py311h3003323_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyarrow-16.1.0-py311hf3b2ce4_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyarrow-core-16.1.0-py311hbc16ef1_0_cpu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyarrow-hotfix-0.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.18.2-py311h5d190b6_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.18.4-py311h98c6a39_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pymetis-2023.1.1-py311h006cce6_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.1.2-pyhd8ed1ab_0.conda @@ -1228,7 +1226,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-benchmark-4.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cases-3.8.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-5.0.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.5.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.11.0-h3ba56d0_1_cpython.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gmsh-4.12.2-h57928b3_0.conda @@ -1236,21 +1234,21 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2024.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python_abi-3.11-4_cp311.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pyvista-0.43.8-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyvista-0.43.9-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.1-py311heffc1b2_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/qt-main-5.15.8-h6bf1bb6_19.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/qt6-main-6.7.1-h845717a_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rapidjson-1.1.0.post20240409-h00cdb27_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rasterio-1.3.9-py311h31af29f_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/re2-2023.09.01-h4cba328_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h92ec313_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/readme_renderer-42.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-toolbelt-1.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-2.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rioxarray-0.15.5-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rtree-1.2.0-py311hd698ff7_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.4.5-py311hd374d79_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rtree-1.2.0-py311h46a7578_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.4.9-py311hd374d79_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scikit-learn-1.5.0-py311hbfb48bc_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.13.1-py311hceeca8c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/scooby-0.10.0-pyhd8ed1ab_0.conda @@ -1264,7 +1262,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/snuggs-1.4.7-py_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.5-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/spdlog-1.12.0-he64bfa9_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/spdlog-1.13.0-h5fcca99_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-5.0.0-pyh6c4a22f_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-gallery-0.16.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-1.0.8-pyhd8ed1ab_0.conda @@ -1273,37 +1271,37 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-1.0.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.10-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/sqlite-3.45.3-hf2abe2d_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/svt-av1-2.0.0-h078ce10_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/sqlite-3.46.0-h5838104_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/svt-av1-2.1.0-h7bae524_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tbb-2021.12.0-h420ef59_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tbb-devel-2021.12.0-h94f16c5_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tiledb-2.20.1-hca4efeb_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tiledb-2.21.2-hf0716ca_4.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-w-1.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/toolz-0.12.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.4-py311h05b510d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.4.1-py311hd3f4193_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.66.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.22-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/twine-5.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.11.0-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.11.0-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tzcode-2024a-h93a5062_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/uriparser-0.9.8-h00cdb27_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/utfcpp-4.0.5-hce30654_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/vtk-9.2.6-qt_py311h1234567_220.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/vtk-base-9.2.6-qt_py311h1234567_220.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/vtk-io-ffmpeg-9.2.6-qt_py311h1234567_220.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/vtk-9.3.0-qt_py311h1234567_200.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/vtk-base-9.3.0-qt_py311h1234567_200.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/vtk-io-ffmpeg-9.3.0-qt_py311h1234567_200.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/x264-1!164.3095-h57fd34a_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/x265-3.5-hbc6ce65_3.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.5.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.6.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xerces-c-3.2.5-hf393695_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-fixesproto-5.0-h3422bc3_1002.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-kbproto-1.0.7-h27ca646_1002.tar.bz2 @@ -1319,14 +1317,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-xextproto-7.3.0-h1a8c8d9_1003.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-xproto-7.0.31-h27ca646_1007.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.10.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xz-5.2.6-h57fd34a_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h3422bc3_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yarl-1.9.4-py311h05b510d_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-2.18.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-2.18.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zict-3.0.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.2.13-h53f4e23_5.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.19.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.2.13-hfb2fe0b_6.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.6-hb46c0d2_0.conda - pypi: https://files.pythonhosted.org/packages/50/fa/a2561d6837cd45a3971c514222e94d3ded3f105993ddcf4983ed68ce3da3/mypy2junit-1.9.0-py3-none-any.whl win-64: @@ -1336,22 +1334,22 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aom-3.8.2-h63175ca_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aom-3.9.0-he0c23c2_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asciitree-0.3.3-py_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-23.2.0-pyh71513ae_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-auth-0.7.17-hb40cdec_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-cal-0.6.11-ha21e00f_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-common-0.9.15-hcfcfb64_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-compression-0.2.18-ha21e00f_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-event-stream-0.4.2-hf668b60_8.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-http-0.8.1-hd704247_10.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-io-0.14.7-h14865c8_6.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-mqtt-0.10.3-h748201e_4.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-s3-0.5.7-h5da7064_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-sdkutils-0.1.15-ha21e00f_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-checksums-0.1.18-ha21e00f_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-crt-cpp-0.26.6-h5bc0ceb_4.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-sdk-cpp-1.11.267-h5d77392_6.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-auth-0.7.20-h6823eb1_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-cal-0.6.12-hc83774a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-common-0.9.17-h2466b09_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-compression-0.2.18-hc83774a_4.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-event-stream-0.4.2-hc6c0aac_10.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-http-0.8.1-hced5053_13.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-io-0.14.8-hebaacdb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-mqtt-0.10.4-hdafd9a4_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-s3-0.5.9-h7a83f0e_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-sdkutils-0.1.16-hc83774a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-checksums-0.1.18-hc83774a_4.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-crt-cpp-0.26.8-h672a689_11.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-sdk-cpp-1.11.267-h12f3f85_8.conda - conda: https://conda.anaconda.org/conda-forge/win-64/azure-core-cpp-1.11.1-h249a519_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/azure-storage-blobs-cpp-12.10.0-h91493d7_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/azure-storage-common-cpp-12.5.0-h91493d7_4.conda @@ -1371,12 +1369,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/build-0.7.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-hcfcfb64_5.conda - conda: https://conda.anaconda.org/conda-forge/win-64/c-ares-1.28.1-hcfcfb64_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ca-certificates-2024.2.2-h56e8100_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ca-certificates-2024.6.2-h56e8100_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.0-h1fef639_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.2.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-1.16.0-py311ha68e1ae_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/cfitsio-4.3.1-h9b0cee5_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/cftime-1.6.3-py311h0a17f05_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cfitsio-4.4.0-h9b0cee5_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cftime-1.6.4-py311h0a17f05_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.3.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.1.7-win_pyh7428d3b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1-py_0.tar.bz2 @@ -1386,7 +1384,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/colorama-0.4.6-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/contextily-1.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/contourpy-1.2.1-py311h005e61a_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/coverage-7.5.1-py311he736701_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/coverage-7.5.3-py311he736701_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/cytoolz-0.12.3-py311ha68e1ae_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/dask-2023.12.1-pyhd8ed1ab_0.conda @@ -1400,10 +1398,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/eigen-3.4.0-h91493d7_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/expat-2.5.0-h63175ca_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.38-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/expat-2.6.2-h63175ca_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.45-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fasteners-0.17.3-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/ffmpeg-6.1.1-gpl_h66c0b5b_108.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ffmpeg-6.1.1-gpl_h7cec250_112.conda - conda: https://conda.anaconda.org/conda-forge/win-64/fiona-1.9.6-py311hbcf8545_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/flopy-3.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/fltk-1.3.9-h01c93fd_0.conda @@ -1416,14 +1414,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.14.2-hbde0cde_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.52.1-py311he736701_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.53.0-py311he736701_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/freeimage-3.18.0-h2b56e36_20.conda - conda: https://conda.anaconda.org/conda-forge/win-64/freetype-2.12.1-hdaf720e_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/freexl-2.0.0-h8276f4a_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/fribidi-1.0.10-h8d14728_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/frozenlist-1.4.1-py311ha68e1ae_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2024.5.0-pyhff2d567_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/gdal-3.8.4-py311h21a6730_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2024.6.0-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/gdal-3.8.4-py311h21a6730_5.conda - conda: https://conda.anaconda.org/conda-forge/noarch/geographiclib-2.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-0.14.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-base-0.14.4-pyha770c72_0.conda @@ -1431,24 +1429,22 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/geos-3.12.1-h1537add_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/geotiff-1.7.1-hbf5ca3a_15.conda - conda: https://conda.anaconda.org/conda-forge/win-64/getopt-win32-0.1-hcfcfb64_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/gettext-0.22.5-h5728263_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/gettext-tools-0.22.5-h7d00a51_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/gh-2.49.2-h36e2d1d_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/gh-2.51.0-h36e2d1d_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/gl2ps-1.4.2-h0597ee9_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/glew-2.1.0-h39d44d4_2.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/glib-2.78.4-h12be248_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/glib-tools-2.78.4-h12be248_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/glib-2.80.2-h0df6a38_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/glib-tools-2.80.2-h2f9d560_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/gmsh-4.12.2-hcc95203_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.13-h63175ca_1003.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/graphviz-9.0.0-h51cb2cd_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/gst-plugins-base-1.22.9-h001b923_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/gstreamer-1.22.9-hb4038d2_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/graphviz-11.0.0-h09e431a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/gst-plugins-base-1.24.4-hba88be7_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/gstreamer-1.24.4-h5006eae_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/gts-0.7.6-h6b5321d_4.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/harfbuzz-8.3.0-h7ab893a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/harfbuzz-8.5.0-h81778c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hatchling-1.24.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/hdf4-4.2.15-h5557f11_7.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/hdf5-1.14.3-nompi_h73e8ff5_101.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.6-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/hdf5-1.14.3-nompi_h2b43c12_105.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.103.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/icu-73.2-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 @@ -1474,36 +1470,28 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/libabseil-20240116.2-cxx17_h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libaec-1.1.3-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libarchive-3.7.4-haf234dc_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-15.0.2-h45212c0_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-acero-15.0.2-h8681a6d_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-dataset-15.0.2-h8681a6d_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-flight-15.0.2-h83a3238_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-flight-sql-15.0.2-h21569af_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-gandiva-15.0.2-h05de715_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-substrait-15.0.2-hea7f8fd_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libasprintf-0.22.5-h5728263_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libasprintf-devel-0.22.5-h5728263_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-16.1.0-h107e38f_1_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-acero-16.1.0-he0c23c2_1_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-dataset-16.1.0-he0c23c2_1_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-substrait-16.1.0-h1f0e801_1_cpu.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.9.0-22_win64_mkl.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libboost-headers-1.85.0-h57928b3_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.1.0-hcfcfb64_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.1.0-hcfcfb64_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.1.0-hcfcfb64_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.9.0-22_win64_mkl.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libclang-15.0.7-default_h3a3e6c3_5.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libclang13-15.0.7-default_hf64faad_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libclang13-18.1.7-default_h97ce8ae_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libcrc32c-1.1.2-h0e60522_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.8.0-hd5e4a3a_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.19-hcfcfb64_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.20-hcfcfb64_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libevent-2.1.12-h3671451_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.5.0-h63175ca_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.6.2-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.4.2-h8ffe710_5.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/libgd-2.3.3-h312136b_9.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libgdal-3.8.4-h7c2897a_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libgettextpo-0.22.5-h5728263_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libgettextpo-devel-0.22.5-h5728263_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.78.4-h16e383f_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libgoogle-cloud-2.22.0-h9cad5c0_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libgoogle-cloud-storage-2.22.0-hb581fae_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgdal-3.8.4-hf83a0e2_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.80.2-h0df6a38_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgoogle-cloud-2.23.0-h68df31e_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgoogle-cloud-storage-2.23.0-hb581fae_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libgrpc-1.62.2-h5273850_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.10.0-default_h8125262_1001.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.17-hcfcfb64_2.conda @@ -1512,31 +1500,31 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.0.0-hcfcfb64_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libkml-1.3.0-haf3e7a6_1018.conda - conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.9.0-22_win64_mkl.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libnetcdf-4.9.2-nompi_h07c049d_113.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libnetcdf-4.9.2-nompi_h92078aa_114.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libogg-1.3.4-h8ffe710_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/libopus-1.3.1-h8ffe710_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/libparquet-15.0.2-h39135fc_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libparquet-16.1.0-h178134c_1_cpu.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.43-h19919ed_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libpq-16.3-hab9416b_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libprotobuf-4.25.3-h503648d_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libraw-0.21.1-h5557f11_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libre2-11-2023.09.01-hf8d8778_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/librttopo-1.1.0-h94c4f80_15.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libspatialindex-1.9.3-h5a68840_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libspatialindex-2.0.0-h5a68840_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libspatialite-5.1.0-hf2f0abc_4.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.45.3-hcfcfb64_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.46.0-h2466b09_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.0-h7dfc565_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libtheora-1.1.1-h8d14728_1005.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/libthrift-0.19.0-ha2b3283_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.6.0-h6e2ebb7_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.6.0-hddb2be6_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libutf8proc-2.8.0-h82a8f57_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/libvorbis-1.3.7-h0e60522_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-1.4.0-h2466b09_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.4.0-hcfcfb64_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libxcb-1.15-hcd874cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.12.7-h283a6d9_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.12.7-h283a6d9_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libzip-1.10.1-h1d365fa_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.2.13-hcfcfb64_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.2.13-h2466b09_6.conda - conda: https://conda.anaconda.org/conda-forge/win-64/llvmlite-0.42.0-py311h5bc0dda_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/loguru-0.7.2-py311h1ea47a8_1.conda @@ -1557,16 +1545,16 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mercantile-1.2.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/metis-5.1.1-h63175ca_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/minizip-4.0.5-h5bed578_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/minizip-4.0.6-hb638d1e_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2024.1.0-h66d3029_692.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.2.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/msgpack-python-1.0.8-py311h3257749_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/msys2-conda-epoch-20160418-1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/multidict-6.0.5-py311ha68e1ae_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.10.0-py311he736701_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/netcdf4-1.6.5-nompi_py311hb75404a_101.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/netcdf4-1.6.5-nompi_py311hb75404a_102.conda - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/nh3-0.2.17-py311h633b200_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/nlohmann_json-3.11.3-h1537add_0.conda @@ -1574,29 +1562,29 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/numcodecs-0.12.1-py311hda3d55a_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-1.26.4-py311h0b4df5a_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/occt-7.7.2-all_h165458f_201.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/occt-7.7.2-novtk_hdfb195f_101.conda - conda: https://conda.anaconda.org/conda-forge/win-64/openexr-3.2.2-h72640d8_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/openh264-2.4.1-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.2-h3d672ee_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.0-h2466b09_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.1-h2466b09_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/orc-2.0.0-h7e885a9_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandamesh-0.1.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pandas-2.2.2-py311hcf9f919_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pango-1.52.1-h07c897b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pango-1.54.0-h2231ffd_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/partd-1.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.42-h17e33f8_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.43-h17e33f8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pep517-0.13.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/pillow-10.3.0-py311h6819b35_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pixman-0.43.4-h63175ca_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.11.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.2.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/poppler-24.02.0-hc2f3c52_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/poppler-24.03.0-hc2f3c52_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/poppler-data-0.4.12-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/postgresql-16.3-h7f155c9_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/proj-9.3.1-he13c7e8_0.conda @@ -1606,12 +1594,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/pugixml-1.14-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/py-triangle-20230923-py311ha68e1ae_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pyarrow-15.0.2-py311h05400ba_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyarrow-16.1.0-py311h3810d55_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyarrow-core-16.1.0-py311h65ac0bd_0_cpu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyarrow-hotfix-0.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.18.2-py311h533ab2d_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.18.4-py311h533ab2d_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pymetis-2023.1.1-py311hca2ccfb_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.1.2-pyhd8ed1ab_0.conda @@ -1623,7 +1612,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-benchmark-4.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cases-3.8.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-5.0.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.5.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.11.0-hcf16a7b_0_cpython.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gmsh-4.12.2-h57928b3_0.conda @@ -1631,21 +1620,22 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2024.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/python_abi-3.11-4_cp311.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pyvista-0.43.8-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyvista-0.43.9-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-ctypes-0.2.2-py311h1ea47a8_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.1-py311ha68e1ae_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/qt-main-5.15.8-h9e85ed6_19.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/qt-main-5.15.8-hcef0176_21.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.7.1-h9e9f2d0_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/rapidjson-1.1.0.post20240409-he0c23c2_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/rasterio-1.3.9-py311h02f6225_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/re2-2023.09.01-hd3b24a8_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/readme_renderer-42.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-toolbelt-1.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-2.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rioxarray-0.15.5-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/rtree-1.2.0-py311hcacb13a_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.4.5-py311ha637bb9_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/rtree-1.2.0-py311h44d53c4_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.4.9-py311ha637bb9_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/scikit-learn-1.5.0-py311hdcb8d17_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/scipy-1.13.1-py311hd4686c6_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/scooby-0.10.0-pyhd8ed1ab_0.conda @@ -1660,7 +1650,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/snuggs-1.4.7-py_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.5-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/spdlog-1.12.0-h64d2f7d_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/spdlog-1.13.0-h64d2f7d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-5.0.0-pyh6c4a22f_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-gallery-0.16.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-1.0.8-pyhd8ed1ab_0.conda @@ -1669,41 +1659,41 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-1.0.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.10-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/sqlite-3.45.3-hcfcfb64_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/svt-av1-2.0.0-h63175ca_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/sqlite-3.46.0-h2466b09_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/svt-av1-2.1.0-he0c23c2_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2021.12.0-hc790b64_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-devel-2021.12.0-hb551fcf_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tiledb-2.20.1-hc9ddcec_7.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tiledb-2.21.2-hf39fa12_4.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h5226925_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-w-1.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/toolz-0.12.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.4-py311ha68e1ae_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.4.1-py311he736701_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.66.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.22-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/twine-5.1.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.11.0-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.11.0-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/uriparser-0.9.8-h5a68840_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/utfcpp-4.0.5-h57928b3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-ha32ba9b_20.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.38.33135-h835141b_20.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.38.33135-h22015db_20.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vtk-9.2.6-qt_py311h1234567_220.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vtk-base-9.2.6-qt_py311h1234567_220.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h8a93ad2_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.40.33810-ha82c5b3_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.40.33810-h3bf8584_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vtk-9.3.0-qt_py311h1234567_200.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vtk-base-9.3.0-qt_py311h1234567_200.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/win32_setctime-1.1.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyhd8ed1ab_6.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/x264-1!164.3095-h8ffe710_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/x265-3.5-h2d74725_3.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.5.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.6.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/xerces-c-3.2.5-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-fixesproto-5.0-hcd874cb_1002.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-kbproto-1.0.7-hcd874cb_1002.tar.bz2 @@ -1721,14 +1711,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-xextproto-7.3.0-hcd874cb_1003.conda - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-xproto-7.0.31-hcd874cb_1007.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.10.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/xz-5.2.6-h8d14728_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h8ffe710_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/yarl-1.9.4-py311ha68e1ae_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-2.18.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-2.18.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zict-3.0.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/zlib-1.2.13-hcfcfb64_5.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.19.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zlib-1.2.13-h2466b09_6.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.6-h0ea2cb4_0.conda - pypi: https://files.pythonhosted.org/packages/50/fa/a2561d6837cd45a3971c514222e94d3ded3f105993ddcf4983ed68ce3da3/mypy2junit-1.9.0-py3-none-any.whl interactive: @@ -1743,32 +1733,32 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/aiohttp-3.9.5-py311h459d7ec_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.11-hd590300_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.12-h4ab18f5_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.3.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aom-3.8.2-h59595ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.0-hac33072_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-23.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/argon2-cffi-bindings-21.2.0-py311h459d7ec_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/asciitree-0.3.3-py_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-2.4.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.0.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/atk-1.0-2.38.0-hd4edc92_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/linux-64/atk-1.0-2.38.0-h04ea711_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/attr-2.5.1-h166bdaf_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-23.2.0-pyh71513ae_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.7.17-he0b1f16_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.6.11-heb1d5e4_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.9.15-hd590300_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.2.18-hce8ee76_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.4.2-h01f5eca_8.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.8.1-hdb68c23_10.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.14.7-hbfbeace_6.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.10.3-h50844eb_4.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.5.7-hb7bd14b_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.1.15-hce8ee76_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.1.18-hce8ee76_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.26.6-hf567797_4.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.267-hbf3e495_6.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.7.20-h5f1c8d9_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.6.12-h2ba76a8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.9.17-h4ab18f5_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.2.18-h36a0aea_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.4.2-h161de36_10.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.8.1-h63f54a0_13.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.14.8-h96d4d28_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.10.4-hcc7299c_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.5.9-h10bd90f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.1.16-h36a0aea_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.1.18-h36a0aea_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.26.8-h4f3a3cc_11.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.267-h51dfee4_8.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/azure-core-cpp-1.11.1-h91d86a7_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/azure-storage-blobs-cpp-12.10.0-h00ab1b0_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/azure-storage-common-cpp-12.5.0-h94269e2_4.conda @@ -1789,14 +1779,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/build-0.7.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hd590300_5.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/c-ares-1.28.1-hd590300_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.2.2-hbcca054_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.6.2-hbcca054_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/cairo-1.18.0-h3faef2a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.2.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cffi-1.16.0-py311hb3a22ac_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/cfitsio-4.3.1-hbdc6101_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/cftime-1.6.3-py311h18e1886_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cfitsio-4.4.0-hbdc6101_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cftime-1.6.4-py311h18e1886_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.3.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.1.7-unix_pyh707e725_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1-py_0.tar.bz2 @@ -1807,8 +1797,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/contextily-1.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/contourpy-1.2.1-py311h9547e67_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/coverage-7.5.1-py311h331c9d8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-42.0.7-py311h4a61cc7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/coverage-7.5.3-py311h331c9d8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/cryptography-42.0.8-py311h4a61cc7_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/cytoolz-0.12.3-py311h459d7ec_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/dask-2023.12.1-pyhd8ed1ab_0.conda @@ -1828,10 +1818,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.0.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.5.0-hcb278e6_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.38-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/expat-2.6.2-h59595ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.45-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fasteners-0.17.3-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/ffmpeg-6.1.1-gpl_hee4b679_108.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ffmpeg-6.1.1-gpl_he44c6f3_112.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/fiona-1.9.6-py311hf8e0aa6_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/flopy-3.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/fltk-1.3.9-hea138e6_0.conda @@ -1844,16 +1834,16 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/fontconfig-2.14.2-h14ed4e7_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.52.1-py311h331c9d8_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.53.0-py311h331c9d8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/freeimage-3.18.0-h4b96d29_20.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/freetype-2.12.1-h267a509_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/freexl-2.0.0-h743c826_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/fribidi-1.0.10-h36c2ea0_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/frozenlist-1.4.1-py311h459d7ec_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2024.5.0-pyhff2d567_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/gdal-3.8.4-py311h8be719e_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/gdk-pixbuf-2.42.10-h829c605_5.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2024.6.0-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gdal-3.8.4-py311h8be719e_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gdk-pixbuf-2.42.12-hb9ae30d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/geographiclib-2.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-0.14.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-base-0.14.4-pyha770c72_0.conda @@ -1863,33 +1853,33 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/gettext-0.22.5-h59595ed_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gettext-tools-0.22.5-h59595ed_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gflags-2.2.2-he1b5a44_1004.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/gh-2.49.2-he0e2781_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gh-2.51.0-he0e2781_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/giflib-5.2.2-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gl2ps-1.4.2-h0708190_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/glew-2.1.0-h9c3ff4c_2.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/glib-2.78.4-hfc55251_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.78.4-hfc55251_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.0-hed5481d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/glib-2.80.2-hf974151_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.80.2-hb6ce0ca_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gmp-6.3.0-h59595ed_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gmsh-4.12.2-h6b98cf8_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gnutls-3.7.9-hb077bed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/graphite2-1.3.13-h59595ed_1003.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/graphviz-9.0.0-h78e8752_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.22.9-h8e1006c_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.22.9-h98fc4e7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/graphviz-11.0.0-hc68bbd7_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.24.4-h9ad1361_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.24.4-haf2f30d_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gtk2-2.24.33-h280cfa0_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/gts-0.7.6-h977cf35_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.14.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.1.0-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-8.3.0-h3d44ed6_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-8.5.0-hfac3d4d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hatchling-1.24.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/hdf4-4.2.15-h2a13503_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/hdf5-1.14.3-nompi_h4f84152_101.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/hdf5-1.14.3-nompi_hdf9ad27_105.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.0.0-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.27.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.0.1-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.6-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.103.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/icu-73.2-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 @@ -1898,9 +1888,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-7.1.0-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.3-pyhd33586a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-8.24.0-pyh707e725_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.4-pyh3099207_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-8.25.0-pyh707e725_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.classes-3.4.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.context-5.3.0-pyhd8ed1ab_1.conda @@ -1912,7 +1902,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/json-c-0.17-h7ab15ed_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.9.25-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/jsoncpp-1.9.5-h4bd325d_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/jsonpointer-2.4-py311h38be061_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/jsonpointer-3.0.0-py311h38be061_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.22.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2023.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.22.0-pyhd8ed1ab_0.conda @@ -1922,12 +1912,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_console-6.6.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/jupyter_core-5.7.2-py311h38be061_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.10.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.10-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.11-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/jxrlib-1.1-hd590300_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/kealib-1.5.3-hee9dde6_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/keyring-25.2.1-pyha804496_0.conda @@ -1936,18 +1926,15 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/krb5-1.21.2-h659d440_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lame-3.100-h166bdaf_1003.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/lcms2-2.16-hb7c19ff_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_6.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/lerc-4.0.0-h27087fc_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libabseil-20240116.2-cxx17_h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libaec-1.1.3-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libarchive-3.7.4-hfca40fe_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-15.0.2-he70291f_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-15.0.2-hac33072_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-15.0.2-hac33072_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-flight-15.0.2-hd42f311_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-flight-sql-15.0.2-h9241762_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-gandiva-15.0.2-hd4ab825_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-15.0.2-h9241762_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-16.1.0-hefa796f_1_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-16.1.0-hac33072_1_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-16.1.0-hac33072_1_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-16.1.0-h7e0c224_1_cpu.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libasprintf-0.22.5-h661eb56_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libasprintf-devel-0.22.5-h661eb56_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libass-0.17.1-h8fe9dca_1.conda @@ -1958,32 +1945,33 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/libbrotlienc-1.1.0-hd590300_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libcap-2.69-h0f662aa_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libcblas-3.9.0-22_linux64_openblas.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang-15.0.7-default_h127d8a8_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang13-15.0.7-default_h5d6823c_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp15-15.0.7-default_h127d8a8_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp18.1-18.1.7-default_h9bb3924_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libclang13-18.1.7-default_h087397f_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libcrc32c-1.1.2-h9c3ff4c_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libcups-2.3.3-h4637d8d_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libcurl-8.8.0-hca28451_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.19-hd590300_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.20-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libdrm-2.4.120-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libedit-3.1.20191231-he28a2e2_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libev-4.33-hd590300_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libevent-2.1.12-hf998b51_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.5.0-hcb278e6_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.6.2-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libflac-1.4.3-h59595ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_10.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcrypt-1.10.3-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgd-2.3.3-h119a65a_9.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgdal-3.8.4-h9323651_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgdal-3.8.4-h7c88fdf_5.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-0.22.5-h59595ed_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgettextpo-devel-0.22.5-h59595ed_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.2.0-h69a702a_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-13.2.0-hca663fb_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.78.4-h783c2da_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.2.0-h69a702a_10.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-13.2.0-h3d2ce59_10.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.80.2-hf974151_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libglu-9.0.0-hac7e632_1003.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.22.0-h9be4e54_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.22.0-hc7a4891_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_10.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.23.0-h9be4e54_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.23.0-hc7a4891_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgpg-error-1.49-h4f305b6_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libgrpc-1.62.2-h15f2491_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libhwloc-2.10.0-default_h5622ce7_1001.conda @@ -1994,60 +1982,60 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/liblapack-3.9.0-22_linux64_openblas.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm14-14.0.6-hcd5def8_4.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm15-15.0.7-hb3ce162_4.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm16-16.0.6-hb3ce162_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libnetcdf-4.9.2-nompi_h9612171_113.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libllvm18-18.1.7-hb77312f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libnetcdf-4.9.2-nompi_h135f659_114.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libnghttp2-1.58.0-h47da74e_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libnl-3.9.0-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libogg-1.3.4-h7f98852_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenblas-0.3.27-pthreads_h413a1c8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-2024.0.0-h2da1b83_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-auto-batch-plugin-2024.0.0-hb045406_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-auto-plugin-2024.0.0-hb045406_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-hetero-plugin-2024.0.0-h5c03a75_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-cpu-plugin-2024.0.0-h2da1b83_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-gpu-plugin-2024.0.0-h2da1b83_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-ir-frontend-2024.0.0-h5c03a75_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-onnx-frontend-2024.0.0-h07e8aee_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-paddle-frontend-2024.0.0-h07e8aee_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-pytorch-frontend-2024.0.0-he02047a_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-tensorflow-frontend-2024.0.0-h39126c6_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-tensorflow-lite-frontend-2024.0.0-he02047a_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-2024.1.0-h2da1b83_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-auto-batch-plugin-2024.1.0-hb045406_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-auto-plugin-2024.1.0-hb045406_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-hetero-plugin-2024.1.0-h5c03a75_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-cpu-plugin-2024.1.0-h2da1b83_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-gpu-plugin-2024.1.0-h2da1b83_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-npu-plugin-2024.1.0-he02047a_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-ir-frontend-2024.1.0-h5c03a75_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-onnx-frontend-2024.1.0-h07e8aee_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-paddle-frontend-2024.1.0-h07e8aee_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-pytorch-frontend-2024.1.0-he02047a_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-tensorflow-frontend-2024.1.0-h39126c6_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-tensorflow-lite-frontend-2024.1.0-he02047a_7.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libopus-1.3.1-h7f98852_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/libparquet-15.0.2-h6a7eafb_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libparquet-16.1.0-h6a7eafb_1_cpu.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libpciaccess-0.18-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libpng-1.6.43-h2797004_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libpq-16.3-ha72fbe1_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libprotobuf-4.25.3-h08a7969_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libraw-0.21.1-h2a13503_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libre2-11-2023.09.01-h5a48ba9_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/librsvg-2.56.3-he3f83f7_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/librsvg-2.58.0-hadf69e7_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/librttopo-1.1.0-h8917695_15.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libsndfile-1.2.2-hc60ed4a_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libsodium-1.0.18-h36c2ea0_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/libspatialindex-1.9.3-he02047a_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libspatialindex-2.0.0-he02047a_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libspatialite-5.1.0-h7bd4643_4.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.45.3-h2797004_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.46.0-hde9e2c9_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libssh2-1.11.0-h0841786_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-hc0a3c3a_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-hc0a3c3a_10.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libsystemd0-255-h3516f8a_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libtasn1-4.19.0-h166bdaf_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libtheora-1.1.1-h7f98852_1005.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libthrift-0.19.0-hb90f79a_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.6.0-ha9c0a0a_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.6.0-h1dd3fc0_3.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libunistring-0.9.10-h7f98852_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libutf8proc-2.8.0-h166bdaf_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libva-2.21.0-hd590300_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libva-2.21.0-h4ab18f5_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libvorbis-1.3.7-h9c3ff4c_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/libvpx-1.14.0-h59595ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libvpx-1.14.1-hac33072_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-1.4.0-h2c329e2_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libwebp-base-1.4.0-hd590300_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libxcb-1.15-h0b41bf4_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libxkbcommon-1.7.0-h662e7e4_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.12.7-hc051c1a_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.12.7-hc051c1a_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libzip-1.10.1-h2629f0a_3.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-hd590300_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-h4ab18f5_6.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/llvmlite-0.42.0-py311ha6695c7_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/loguru-0.7.2-py311h38be061_1.conda @@ -2064,30 +2052,30 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mercantile-1.2.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/metis-5.1.1-h59595ed_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/minizip-4.0.5-h0ab5242_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/minizip-4.0.6-h9d307f2_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.0.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.2.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/mpg123-1.32.6-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/msgpack-python-1.0.8-py311h52f7536_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/multidict-6.0.5-py311h459d7ec_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/mypy-1.10.0-py311h331c9d8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/mysql-common-8.0.33-hf1915f5_6.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/mysql-libs-8.0.33-hca2cd23_6.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/mysql-common-8.3.0-hf1915f5_4.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/mysql-libs-8.3.0-hca2cd23_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.4-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.16.4-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.4-hd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.16.4-hd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/netcdf4-1.6.5-nompi_py311h74118c1_101.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/netcdf4-1.6.5-nompi_py311h74118c1_102.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/nettle-3.9.1-h7ab15ed_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/nh3-0.2.17-py311h46250e7_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/nlohmann_json-3.11.3-h59595ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-7.2.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-7.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/nspr-4.35-h27087fc_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/nss-3.100-hca3bf56_0.conda @@ -2095,58 +2083,59 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/numcodecs-0.12.1-py311h4332511_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-1.26.4-py311h64a7726_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/occt-7.7.2-all_h4c9f3c6_201.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/occt-7.7.2-novtk_h130ccc2_101.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ocl-icd-2.3.2-hd590300_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/openexr-3.2.2-haf962dd_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/openh264-2.4.1-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/openjpeg-2.5.2-h488ebb8_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.0-h4ab18f5_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.1-h4ab18f5_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/orc-2.0.0-h17fec99_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/p11-kit-0.24.1-hc5aa10d_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandamesh-0.1.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pandas-2.2.2-py311h14de704_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pandoc-3.2-ha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/pango-1.52.1-ha41ecd1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pango-1.54.0-h84a9a3c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/partd-1.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.42-hcad00b1_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.43-hcad00b1_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pep517-0.13.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-py_1003.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/pillow-10.3.0-py311h18e6fac_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pixman-0.43.2-h59595ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.11.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pkgutil-resolve-name-1.3.10-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.2.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/poppler-24.02.0-h590f24d_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/poppler-24.03.0-h590f24d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/poppler-data-0.4.12-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/postgresql-16.3-h8e811e2_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/proj-9.3.1-h1d62c97_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.42-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.42-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.47-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.47-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/psutil-5.9.8-py311h459d7ec_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pthread-stubs-0.4-h36c2ea0_1001.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd3deb0d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/pugixml-1.14-h59595ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-16.1-hb77b528_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-hb77b528_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.2-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/py-triangle-20230923-py311h459d7ec_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pyarrow-15.0.2-py311h78dcc79_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyarrow-16.1.0-py311h781c19f_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-16.1.0-py311h8e2c35d_0_cpu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyarrow-hotfix-0.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.18.2-py311h5ecf98a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.18.4-py311h5ecf98a_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pymetis-2023.1.1-py311hf4706e4_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.1.2-pyhd8ed1ab_0.conda @@ -2158,30 +2147,30 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-benchmark-4.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cases-3.8.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-5.0.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.5.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.11.0-he550d4f_1_cpython.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.19.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.20.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gmsh-4.12.2-h57928b3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-graphviz-0.20.3-pyh717bed2_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2024.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python_abi-3.11-4_cp311.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pyvista-0.43.8-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyvista-0.43.9-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pyyaml-6.0.1-py311h459d7ec_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/pyzmq-26.0.3-py311h08a0b41_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.8-h5810be5_19.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.8-hc9dc06e_21.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.7.1-h2471661_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/qtconsole-base-5.5.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/qtpy-2.4.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/rapidjson-1.1.0.post20240409-hac33072_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/rasterio-1.3.9-py311ha38370a_2.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/rdma-core-51.0-hd3aeb46_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/re2-2023.09.01-h7f4b329_2.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/readme_renderer-42.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.35.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-toolbelt-1.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-2.0.0-pyhd8ed1ab_0.tar.bz2 @@ -2189,9 +2178,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rioxarray-0.15.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/rpds-py-0.18.1-py311h5ecf98a_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/rtree-1.2.0-py311h3bb2b0f_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.4.5-py311hae69bc3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/s2n-1.4.12-h06160fa_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/rtree-1.2.0-py311ha1603b9_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.4.9-py311hae69bc3_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/s2n-1.4.13-he19d79f_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/scikit-learn-1.5.0-py311he08f58d_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/scipy-1.13.1-py311h517d4fd_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/scooby-0.10.0-pyhd8ed1ab_0.conda @@ -2209,7 +2198,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/snuggs-1.4.7-py_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.5-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/spdlog-1.12.0-hd2e6256_2.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/spdlog-1.13.0-hd2e6256_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-5.0.0-pyh6c4a22f_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-gallery-0.16.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-1.0.8-pyhd8ed1ab_0.conda @@ -2218,57 +2207,58 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-1.0.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.10-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.45.3-h2c6b66d_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.46.0-h6d4b2fc_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/svt-av1-2.0.0-h59595ed_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/svt-av1-2.1.0-hac33072_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tbb-2021.12.0-h297d8ca_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tbb-devel-2021.12.0-h7c56ddd_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh0d859eb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tiledb-2.20.1-hcf523ab_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tiledb-2.21.2-h27f064a_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/tk-8.6.13-noxft_h4845f30_101.conda - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-w-1.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/toolz-0.12.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.4-py311h459d7ec_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.4.1-py311h331c9d8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.66.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.22-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/twine-5.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/types-python-dateutil-2.9.0.20240316-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.11.0-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.11.0-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/tzcode-2024a-h3f72095_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ucx-1.15.0-ha691c75_8.conda - conda: https://conda.anaconda.org/conda-forge/noarch/uri-template-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/uriparser-0.9.8-hac33072_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/utfcpp-4.0.5-ha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/vtk-9.2.6-qt_py311h1234567_220.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/vtk-base-9.2.6-qt_py311h1234567_220.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/vtk-io-ffmpeg-9.2.6-qt_py311h1234567_220.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/vtk-9.3.0-qt_py311h1234567_200.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/vtk-base-9.3.0-qt_py311h1234567_200.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/vtk-io-ffmpeg-9.3.0-qt_py311h1234567_200.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/wayland-1.23.0-h5291e77_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-1.13-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-24.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.8.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.10-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.11-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/x264-1!164.3095-h166bdaf_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/x265-3.5-h924138e_3.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.5.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.6.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-0.4.0-hd590300_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.4-hd590300_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-image-0.4.0-h8ee46fc_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-keysyms-0.4.0-h8ee46fc_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-renderutil-0.3.9-hd590300_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-wm-0.4.1-h8ee46fc_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xerces-c-3.2.5-hac6953d_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.41-hd590300_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.42-h4ab18f5_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-fixesproto-5.0-h7f98852_1002.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-kbproto-1.0.7-h7f98852_1002.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-libice-1.1.1-hd590300_0.conda @@ -2286,15 +2276,15 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-xf86vidmodeproto-2.3.1-h7f98852_1002.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-xproto-7.0.31-h7f98852_1007.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.10.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h7f98852_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/yarl-1.9.4-py311h459d7ec_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-2.18.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-2.18.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zeromq-4.3.5-h75354e8_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zict-3.0.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.2.13-hd590300_5.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.19.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.2.13-h4ab18f5_6.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/zstd-1.5.6-ha6fb4c9_0.conda - pypi: https://files.pythonhosted.org/packages/50/fa/a2561d6837cd45a3971c514222e94d3ded3f105993ddcf4983ed68ce3da3/mypy2junit-1.9.0-py3-none-any.whl osx-64: @@ -2304,7 +2294,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.3.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/aom-3.8.2-h73e2aa4_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-23.1.0-pyhd8ed1ab_0.conda @@ -2348,14 +2338,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/build-0.7.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h10d778d_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/c-ares-1.28.1-h10d778d_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/ca-certificates-2024.2.2-h8857fd0_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ca-certificates-2024.6.2-h8857fd0_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/cairo-1.18.0-h99e66fa_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.2.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/cffi-1.16.0-py311hc0b63fd_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/cfitsio-4.3.1-h60fb419_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/cftime-1.6.3-py311hce3442d_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/cftime-1.6.4-py311hce3442d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.3.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.1.7-unix_pyh707e725_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1-py_0.tar.bz2 @@ -2366,7 +2356,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/contextily-1.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/contourpy-1.2.1-py311h1d816ee_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/coverage-7.5.1-py311h42a8b16_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/coverage-7.5.3-py311h72ae277_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/cytoolz-0.12.3-py311he705e18_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/dask-2023.12.1-pyhd8ed1ab_0.conda @@ -2386,7 +2376,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/expat-2.5.0-hf0c8a7f_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.38-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.45-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fasteners-0.17.3-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/ffmpeg-6.1.1-gpl_h6b92a41_108.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/fiona-1.9.6-py311hd2ff552_0.conda @@ -2401,14 +2391,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/fontconfig-2.14.2-h5bb23bf_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-64/fonttools-4.52.1-py311h72ae277_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/fonttools-4.53.0-py311h72ae277_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/freeimage-3.18.0-hdc0ade2_20.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/freetype-2.12.1-h60636b9_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/freexl-2.0.0-h3ec172f_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/fribidi-1.0.10-hbcb3906_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/frozenlist-1.4.1-py311he705e18_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2024.5.0-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2024.6.0-pyhff2d567_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/gdal-3.8.4-py311haaa0e4f_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/gdk-pixbuf-2.42.10-hd9e0ca3_5.conda - conda: https://conda.anaconda.org/conda-forge/noarch/geographiclib-2.0-pyhd8ed1ab_0.tar.bz2 @@ -2420,13 +2410,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/gettext-0.22.5-h5ff76d1_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/gettext-tools-0.22.5-h5ff76d1_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/gflags-2.2.2-hb1e8313_1004.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-64/gh-2.49.2-he13f2d6_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/gh-2.51.0-he13f2d6_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/giflib-5.2.2-h10d778d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/gl2ps-1.4.2-h4cff582_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/glew-2.1.0-h046ec9c_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/glib-2.78.4-h2d185b6_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/glib-tools-2.78.4-h2d185b6_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/glog-0.7.0-h31b1b29_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/glog-0.7.1-h2790a97_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/gmp-6.3.0-h73e2aa4_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/gmsh-4.12.2-h48a2193_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/gnutls-3.7.9-h1951705_0.conda @@ -2441,12 +2431,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/harfbuzz-8.3.0-hf45c392_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hatchling-1.24.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/hdf4-4.2.15-h8138101_7.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/hdf5-1.14.3-nompi_hb512a33_101.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/hdf5-1.14.3-nompi_h687a608_105.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.0.0-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.27.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.0.1-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.6-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.103.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/icu-73.2-hf5e326d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 @@ -2455,9 +2445,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-7.1.0-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.3-pyh3cd1d5f_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-8.24.0-pyh707e725_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.4-pyh57ce528_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-8.25.0-pyh707e725_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.classes-3.4.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.context-5.3.0-pyhd8ed1ab_1.conda @@ -2468,7 +2458,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/json-c-0.17-h8e11ae5_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.9.25-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/jsoncpp-1.9.5-h940c156_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-64/jsonpointer-2.4-py311h6eed73b_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/jsonpointer-3.0.0-py311h6eed73b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.22.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2023.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.22.0-pyhd8ed1ab_0.conda @@ -2478,12 +2468,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_console-6.6.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/jupyter_core-5.7.2-py311h6eed73b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.10.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.10-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.11-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/jxrlib-1.1-h10d778d_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/kealib-1.5.3-hb2b617a_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/keyring-25.2.1-pyh534df25_0.conda @@ -2543,7 +2533,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/libllvm14-14.0.6-hc8e404f_4.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libllvm15-15.0.7-hbedff68_4.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libllvm16-16.0.6-hbedff68_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libnetcdf-4.9.2-nompi_h7760872_113.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libnetcdf-4.9.2-nompi_h7334405_114.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libnghttp2-1.58.0-h64cf6d3_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libogg-1.3.4-h35c211d_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/libopenblas-0.3.27-openmp_hfef2a42_0.conda @@ -2568,9 +2558,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/librsvg-2.56.3-h1877882_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/librttopo-1.1.0-hf05f67e_15.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libsodium-1.0.18-hbcb3906_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-64/libspatialindex-1.9.3-hf036a51_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libspatialindex-2.0.0-hf036a51_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libspatialite-5.1.0-hebe6af1_4.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.45.3-h92b6c6a_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.46.0-h1b8f9f3_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libssh2-1.11.0-hd019ec5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libtasn1-4.19.0-hb7f2c08_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/libtheora-1.1.1-h0d85af4_1005.tar.bz2 @@ -2579,14 +2569,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/libunistring-0.9.10-h0d85af4_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/libutf8proc-2.8.0-hb7f2c08_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/libvorbis-1.3.7-h046ec9c_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-64/libvpx-1.14.0-h73e2aa4_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libvpx-1.14.1-hf036a51_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libwebp-1.4.0-hc207709_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libwebp-base-1.4.0-h10d778d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libxcb-1.15-hb7f2c08_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.12.7-h3e169fe_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.12.7-h3e169fe_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libzip-1.10.1-hc158999_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.2.13-h8a1eda9_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-18.1.5-h39e0ece_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.2.13-h87427d6_6.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-18.1.7-h15ab845_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/llvmlite-0.42.0-py311hb5c2e0a_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/loguru-0.7.2-py311h6eed73b_1.conda @@ -2603,9 +2593,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mercantile-1.2.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/metis-5.1.1-h73e2aa4_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/minizip-4.0.5-h37d7099_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/minizip-4.0.6-ha2864c9_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.0.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.2.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/msgpack-python-1.0.8-py311h46c8309_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/multidict-6.0.5-py311h5547dcb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2 @@ -2614,18 +2604,18 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/mysql-common-8.0.33-h1d20c9b_6.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/mysql-libs-8.0.33-hed35180_6.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.4-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.16.4-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.4-hd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.16.4-hd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h5846eda_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/netcdf4-1.6.5-nompi_py311hab941cd_101.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/netcdf4-1.6.5-nompi_py311hab941cd_102.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/nettle-3.9.1-h8e11ae5_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/nh3-0.2.17-py311hd64b9fd_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/nlohmann_json-3.11.3-h73e2aa4_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-7.2.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-7.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/nspr-4.35-hea0b92c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/nss-3.100-h6606ded_0.conda @@ -2637,11 +2627,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/openexr-3.2.2-h3f0570e_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/openh264-2.4.1-h73e2aa4_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/openjpeg-2.5.2-h7310d3a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.0-h87427d6_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.1-h87427d6_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/orc-2.0.0-hf146577_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/p11-kit-0.24.1-h65f8906_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandamesh-0.1.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pandas-2.2.2-py311hfdcbad3_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pandoc-3.2-h694c41f_0.conda @@ -2657,18 +2647,18 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/pillow-10.3.0-py311h1b85569_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pixman-0.43.4-h73e2aa4_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.11.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pkgutil-resolve-name-1.3.10-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.2.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/poppler-24.02.0-h0c752f9_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/poppler-data-0.4.12-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/postgresql-16.3-h1d90168_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/proj-9.3.1-h81faed2_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.42-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.42-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.47-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.47-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/psutil-5.9.8-py311he705e18_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pthread-stubs-0.4-hc929b4f_1001.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd3deb0d_0.tar.bz2 @@ -2679,9 +2669,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/pyarrow-15.0.2-py311ha429d19_3_cpu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyarrow-hotfix-0.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.18.2-py311h2786eb7_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.18.4-py311h295b1db_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pymetis-2023.1.1-py311h5fe6d0d_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pyobjc-core-10.2-py311h9b70068_0.conda @@ -2693,17 +2683,17 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-benchmark-4.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cases-3.8.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-5.0.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.5.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.11.0-he7542f4_1_cpython.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.19.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.20.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gmsh-4.12.2-h57928b3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-graphviz-0.20.3-pyh717bed2_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2024.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/python_abi-3.11-4_cp311.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pyvista-0.43.8-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyvista-0.43.9-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pyyaml-6.0.1-py311h2725bcf_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/pyzmq-26.0.3-py311h89e2aaa_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/qt-main-5.15.8-h4385fff_19.conda @@ -2715,7 +2705,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h9e318b2_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/readme_renderer-42.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.35.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-toolbelt-1.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-2.0.0-pyhd8ed1ab_0.tar.bz2 @@ -2723,8 +2713,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rioxarray-0.15.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/rpds-py-0.18.1-py311h295b1db_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/rtree-1.2.0-py311hbc1f44b_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.4.5-py311h9a97b26_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/rtree-1.2.0-py311h6785ca5_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.4.9-py311h9a97b26_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/scikit-learn-1.5.0-py311h3c3ac6d_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/scipy-1.13.1-py311h40a1ab3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/scooby-0.10.0-pyhd8ed1ab_0.conda @@ -2749,7 +2739,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-1.0.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.10-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/sqlite-3.45.3-h7461747_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/sqlite-3.46.0-h28673e1_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/svt-av1-2.0.0-h73e2aa4_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/tbb-2021.12.0-h3c5361c_1.conda @@ -2764,14 +2754,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-w-1.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/toolz-0.12.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/tornado-6.4-py311he705e18_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/tornado-6.4.1-py311h72ae277_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.66.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.22-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/twine-5.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/types-python-dateutil-2.9.0.20240316-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.11.0-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.11.0-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/tzcode-2024a-h10d778d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda @@ -2779,19 +2769,19 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/uriparser-0.9.8-h6aefe2f_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/utfcpp-4.0.5-h694c41f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/vtk-9.2.6-qt_py311h1234567_220.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/vtk-base-9.2.6-qt_py311h1234567_220.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/vtk-io-ffmpeg-9.2.6-qt_py311h1234567_220.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/vtk-9.2.6-qt_py311h1234567_223.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/vtk-base-9.2.6-qt_py311h1234567_223.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/vtk-io-ffmpeg-9.2.6-qt_py311h1234567_223.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-1.13-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-24.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.8.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.10-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.11-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/x264-1!164.3095-h775f41a_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/x265-3.5-hbb4e6a2_3.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.5.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.6.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/xerces-c-3.2.5-hbbe9ea5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-fixesproto-5.0-h0d85af4_1002.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-kbproto-1.0.7-h35c211d_1002.tar.bz2 @@ -2807,15 +2797,15 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-xextproto-7.3.0-hb7f2c08_1003.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-xproto-7.0.31-h35c211d_1007.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.10.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/xz-5.2.6-h775f41a_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h0d85af4_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/yarl-1.9.4-py311he705e18_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-2.18.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-2.18.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/zeromq-4.3.5-hde137ed_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zict-3.0.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/zlib-1.2.13-h8a1eda9_5.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.19.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/zlib-1.2.13-h87427d6_6.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/zstd-1.5.6-h915ae27_0.conda - pypi: https://files.pythonhosted.org/packages/50/fa/a2561d6837cd45a3971c514222e94d3ded3f105993ddcf4983ed68ce3da3/mypy2junit-1.9.0-py3-none-any.whl osx-arm64: @@ -2825,8 +2815,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.3.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aom-3.8.2-h078ce10_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aom-3.9.0-h537b5a7_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/appnope-0.1.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-23.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/argon2-cffi-bindings-21.2.0-py311heffc1b2_4.conda @@ -2834,21 +2824,21 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/asciitree-0.3.3-py_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-2.4.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.0.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/atk-1.0-2.38.0-hcb7b3dd_1.tar.bz2 + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/atk-1.0-2.38.0-hd03087b_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-23.2.0-pyh71513ae_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-auth-0.7.17-h382b9c6_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-cal-0.6.11-hd34e5fa_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-common-0.9.15-h93a5062_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-compression-0.2.18-hd34e5fa_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-event-stream-0.4.2-h247c08a_8.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-http-0.8.1-hf9e830b_10.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-io-0.14.7-h33d81b3_6.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-mqtt-0.10.3-h5f4abda_4.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-s3-0.5.7-h606a3d2_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-sdkutils-0.1.15-hd34e5fa_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-checksums-0.1.18-hd34e5fa_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-crt-cpp-0.26.6-h13f0230_4.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-sdk-cpp-1.11.267-h134aaec_6.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-auth-0.7.20-h5cf208e_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-cal-0.6.12-h35c0bb2_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-common-0.9.17-h03532ee_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-compression-0.2.18-h35c0bb2_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-event-stream-0.4.2-h7d5773a_10.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-http-0.8.1-h00faecf_13.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-io-0.14.8-h6dd71cf_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-mqtt-0.10.4-h92d7a41_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-s3-0.5.9-he1e208d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-sdkutils-0.1.16-h35c0bb2_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-checksums-0.1.18-h35c0bb2_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-crt-cpp-0.26.8-h5cd1ed2_11.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/aws-sdk-cpp-1.11.267-h108e708_8.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/azure-core-cpp-1.11.1-he231e37_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/azure-storage-blobs-cpp-12.10.0-h2ffa867_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/azure-storage-common-cpp-12.5.0-h09a5875_4.conda @@ -2869,14 +2859,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/build-0.7.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-h93a5062_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/c-ares-1.28.1-h93a5062_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ca-certificates-2024.2.2-hf0a4a13_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ca-certificates-2024.6.2-hf0a4a13_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cairo-1.18.0-hd1e100b_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.2.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cffi-1.16.0-py311h4a08483_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cfitsio-4.3.1-h808cd33_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cftime-1.6.3-py311h5d790af_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cfitsio-4.4.0-h808cd33_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cftime-1.6.4-py311h5d790af_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.3.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.1.7-unix_pyh707e725_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1-py_0.tar.bz2 @@ -2887,7 +2877,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/contextily-1.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/contourpy-1.2.1-py311hcc98501_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.5.1-py311hd3f4193_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.5.3-py311hd3f4193_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/cytoolz-0.12.3-py311h05b510d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/dask-2023.12.1-pyhd8ed1ab_0.conda @@ -2906,10 +2896,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.0.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/expat-2.5.0-hb7217d7_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.38-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/expat-2.6.2-hebf3989_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.45-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fasteners-0.17.3-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ffmpeg-6.1.1-gpl_h4f1e072_108.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ffmpeg-6.1.1-gpl_hc16618e_112.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fiona-1.9.6-py311h1c26527_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/flopy-3.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fltk-1.3.9-h31b9a01_0.conda @@ -2922,16 +2912,16 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fontconfig-2.14.2-h82840c6_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.52.1-py311hd3f4193_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.53.0-py311hd3f4193_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/freeimage-3.18.0-hd0e3f39_20.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/freetype-2.12.1-hadb7bae_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/freexl-2.0.0-hfbad9fb_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/fribidi-1.0.10-h27ca646_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/frozenlist-1.4.1-py311h05b510d_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2024.5.0-pyhff2d567_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gdal-3.8.4-py311h43f0207_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gdk-pixbuf-2.42.10-hcea6d13_5.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2024.6.0-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gdal-3.8.4-py311h43f0207_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gdk-pixbuf-2.42.12-h7ddc832_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/geographiclib-2.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-0.14.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-base-0.14.4-pyha770c72_0.conda @@ -2941,33 +2931,33 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gettext-0.22.5-h8fbad5d_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gettext-tools-0.22.5-h8fbad5d_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gflags-2.2.2-hc88da5d_1004.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gh-2.49.2-h163aea0_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gh-2.51.0-h163aea0_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/giflib-5.2.2-h93a5062_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gl2ps-1.4.2-h17b34a0_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/glew-2.1.0-h9f76cd9_2.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/glib-2.78.4-h1059232_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/glib-tools-2.78.4-h1059232_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/glog-0.7.0-hc6770e3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/glib-2.80.2-h535f939_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/glib-tools-2.80.2-h4c882b9_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/glog-0.7.1-heb240a5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gmp-6.3.0-hebf3989_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gmsh-4.12.2-hd427cfb_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gnutls-3.7.9-hd26332c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/graphite2-1.3.13-hebf3989_1003.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/graphviz-9.0.0-h3face73_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gst-plugins-base-1.22.9-h09b4b5e_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gstreamer-1.22.9-h551c6ff_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/graphviz-11.0.0-h9bb9bc9_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gst-plugins-base-1.24.4-h8a8f8c8_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gstreamer-1.24.4-h430e707_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gtk2-2.24.33-h7895bb2_4.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/gts-0.7.6-he42f4ea_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.14.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.1.0-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/harfbuzz-8.3.0-h8f0ba13_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/harfbuzz-8.5.0-h1836168_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hatchling-1.24.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/hdf4-4.2.15-h2ee6834_7.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/hdf5-1.14.3-nompi_h751145d_101.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/hdf5-1.14.3-nompi_hec07895_105.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.0.0-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.27.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.0.1-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.6-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.103.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/icu-73.2-hc8870d7_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 @@ -2976,9 +2966,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_metadata-7.1.0-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.3-pyh3cd1d5f_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-8.24.0-pyh707e725_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.4-pyh57ce528_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-8.25.0-pyh707e725_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.classes-3.4.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.context-5.3.0-pyhd8ed1ab_1.conda @@ -2989,7 +2979,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/json-c-0.17-h40ed0f5_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.9.25-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/jsoncpp-1.9.5-hc021e02_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/jsonpointer-2.4-py311h267d04e_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/jsonpointer-3.0.0-py311h267d04e_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.22.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2023.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.22.0-pyhd8ed1ab_0.conda @@ -2999,12 +2989,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_console-6.6.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/jupyter_core-5.7.2-py311h267d04e_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.10.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.10-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.11-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/jxrlib-1.1-h93a5062_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/kealib-1.5.3-h848a2d4_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/keyring-25.2.1-pyh534df25_0.conda @@ -3016,13 +3006,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libabseil-20240116.2-cxx17_hebf3989_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libaec-1.1.3-hebf3989_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarchive-3.7.4-h83d404f_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-15.0.2-h3ee1d8f_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-acero-15.0.2-h3f3aa29_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-dataset-15.0.2-h3f3aa29_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-flight-15.0.2-h224147a_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-flight-sql-15.0.2-hb630850_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-gandiva-15.0.2-h5fa1bb3_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-substrait-15.0.2-hd92e347_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-16.1.0-h23f55cf_1_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-acero-16.1.0-h00cdb27_1_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-dataset-16.1.0-h00cdb27_1_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-substrait-16.1.0-hc68f6b8_1_cpu.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libasprintf-0.22.5-h8fbad5d_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libasprintf-devel-0.22.5-h8fbad5d_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libass-0.17.1-hf7da4fe_1.conda @@ -3032,26 +3019,26 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlidec-1.1.0-hb547adb_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libbrotlienc-1.1.0-hb547adb_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcblas-3.9.0-22_osxarm64_openblas.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-15.0.7-default_he012953_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang13-15.0.7-default_h83d0a53_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp16-16.0.6-default_hb63da90_8.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libclang13-18.1.7-default_hb9c8b4a_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcrc32c-1.1.2-hbdafb3b_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcurl-8.8.0-h7b6f9a7_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libcxx-17.0.6-h5f092b4_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.19-hb547adb_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.20-h93a5062_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libedit-3.1.20191231-hc8eb9b7_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libev-4.33-h93a5062_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libevent-2.1.12-h2757513_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.5.0-hb7217d7_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.6.2-hebf3989_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.4.2-h3422bc3_5.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgd-2.3.3-hfdf3952_9.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgdal-3.8.4-ha86f356_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgdal-3.8.4-h7181668_5.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgettextpo-0.22.5-h8fbad5d_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgettextpo-devel-0.22.5-h8fbad5d_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran-5.0.0-13_2_0_hd922786_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgfortran5-13.2.0-hf226fd6_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libglib-2.78.4-h1635a5e_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgoogle-cloud-2.22.0-hbebe991_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgoogle-cloud-storage-2.22.0-h8a76758_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libglib-2.80.2-h535f939_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgoogle-cloud-2.23.0-hbebe991_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgoogle-cloud-storage-2.23.0-h8a76758_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libgrpc-1.62.2-h9c18a4f_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libhwloc-2.10.0-default_h7685b71_1001.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libiconv-1.17-h0d3ecfb_2.conda @@ -3062,52 +3049,52 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libkml-1.3.0-h1eb4d9f_1018.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/liblapack-3.9.0-22_osxarm64_openblas.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm14-14.0.6-hd1a9a77_4.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm15-15.0.7-h2621b3d_4.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm16-16.0.6-haab561b_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnetcdf-4.9.2-nompi_h291a7c2_113.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm18-18.1.7-hdac5640_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnetcdf-4.9.2-nompi_he469be0_114.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libnghttp2-1.58.0-ha4dd798_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libogg-1.3.4-h27ca646_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenblas-0.3.27-openmp_h6c19121_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-2024.0.0-h200475e_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-arm-cpu-plugin-2024.0.0-h200475e_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-auto-batch-plugin-2024.0.0-hfaea8b3_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-auto-plugin-2024.0.0-hfaea8b3_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-hetero-plugin-2024.0.0-hc7e6747_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-ir-frontend-2024.0.0-hc7e6747_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-onnx-frontend-2024.0.0-h25b35cd_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-paddle-frontend-2024.0.0-h25b35cd_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-pytorch-frontend-2024.0.0-h3f3aa29_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-tensorflow-frontend-2024.0.0-hbc2fe69_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-tensorflow-lite-frontend-2024.0.0-h3f3aa29_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-2024.1.0-h5c9529b_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-arm-cpu-plugin-2024.1.0-h5c9529b_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-auto-batch-plugin-2024.1.0-hcd65546_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-auto-plugin-2024.1.0-hcd65546_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-hetero-plugin-2024.1.0-h88cb26a_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-ir-frontend-2024.1.0-h88cb26a_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-onnx-frontend-2024.1.0-h32b5460_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-paddle-frontend-2024.1.0-h32b5460_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-pytorch-frontend-2024.1.0-h00cdb27_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-tensorflow-frontend-2024.1.0-h2741c3b_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-tensorflow-lite-frontend-2024.1.0-h00cdb27_7.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libopus-1.3.1-h27ca646_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libparquet-15.0.2-h5304c63_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libparquet-16.1.0-hcf52c46_1_cpu.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libpng-1.6.43-h091b4b1_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libpq-16.3-h7afe498_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libprotobuf-4.25.3-hbfab5d5_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libraw-0.21.1-h2ee6834_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libre2-11-2023.09.01-h7b2c953_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/librsvg-2.56.3-h55a2576_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/librsvg-2.58.0-hb3d354b_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/librttopo-1.1.0-hc8f776e_15.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsodium-1.0.18-h27ca646_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libspatialindex-1.9.3-h00cdb27_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libspatialindex-2.0.0-h00cdb27_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libspatialite-5.1.0-h69abc6b_4.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.45.3-h091b4b1_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.46.0-hfb93653_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libssh2-1.11.0-h7a5bd25_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libtasn1-4.19.0-h1a8c8d9_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libtheora-1.1.1-h3422bc3_1005.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libthrift-0.19.0-h026a170_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.6.0-ha8a6c65_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.6.0-h07db509_3.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libunistring-0.9.10-h3422bc3_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libutf8proc-2.8.0-h1a8c8d9_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libvorbis-1.3.7-h9f76cd9_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libvpx-1.14.0-h078ce10_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libvpx-1.14.1-h7bae524_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-1.4.0-h54798ee_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libwebp-base-1.4.0-h93a5062_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxcb-1.15-hf346824_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.12.7-ha661575_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.12.7-ha661575_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzip-1.10.1-ha0bc3c6_3.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.2.13-h53f4e23_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-18.1.5-hde57baf_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.2.13-hfb2fe0b_6.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-18.1.7-hde57baf_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/llvmlite-0.42.0-py311hf5d242d_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/loguru-0.7.2-py311h267d04e_1.conda @@ -3124,29 +3111,29 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mercantile-1.2.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/metis-5.1.1-hebf3989_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/minizip-4.0.5-hc35e051_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/minizip-4.0.6-h0615dfd_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.0.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.2.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/msgpack-python-1.0.8-py311h6bde47b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/multidict-6.0.5-py311he2be06e_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/munkres-1.1.4-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mypy-1.10.0-py311hd23d018_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mysql-common-8.0.33-hf9e6398_6.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mysql-libs-8.0.33-he3dca8b_6.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mysql-common-8.3.0-hd1853d3_4.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/mysql-libs-8.3.0-hf036fc4_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.4-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.16.4-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.4-hd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.16.4-hd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-hb89a1cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/netcdf4-1.6.5-nompi_py311hd61c382_101.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/netcdf4-1.6.5-nompi_py311hd61c382_102.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nettle-3.9.1-h40ed0f5_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nh3-0.2.17-py311h94f323b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nlohmann_json-3.11.3-hebf3989_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-7.2.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-7.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nspr-4.35-hb7217d7_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nss-3.100-hc6e9f88_0.conda @@ -3154,42 +3141,42 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numcodecs-0.12.1-py311hb9542d7_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-1.26.4-py311h7125741_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/occt-7.7.2-all_h1e2436f_201.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/occt-7.7.2-novtk_h5f4376a_101.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openexr-3.2.2-h2c51e1d_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openh264-2.4.1-hebf3989_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openjpeg-2.5.2-h9f1df11_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.0-hfb2fe0b_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.1-hfb2fe0b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/orc-2.0.0-h4aad248_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/p11-kit-0.24.1-h29577a5_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandamesh-0.1.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pandas-2.2.2-py311h4b4568b_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pandoc-3.2-hce30654_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pango-1.52.1-hb067d4f_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pango-1.54.0-h5cb9fbc_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/partd-1.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pcre2-10.42-h26f9a81_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pcre2-10.43-h26f9a81_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pep517-0.13.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pexpect-4.9.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-py_1003.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pillow-10.3.0-py311h0b5d0a1_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pixman-0.43.4-hebf3989_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.11.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pkgutil-resolve-name-1.3.10-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.2.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/poppler-24.02.0-h896e6cb_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/poppler-24.03.0-h896e6cb_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/poppler-data-0.4.12-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/postgresql-16.3-hdfa2ec6_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/proj-9.3.1-h93d94ba_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.42-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.42-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.47-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.47-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/psutil-5.9.8-py311h05b510d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pthread-stubs-0.4-h27ca646_1001.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/ptyprocess-0.7.0-pyhd3deb0d_0.tar.bz2 @@ -3197,12 +3184,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.2-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/py-triangle-20230923-py311h05b510d_2.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyarrow-15.0.2-py311h3003323_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyarrow-16.1.0-py311hf3b2ce4_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyarrow-core-16.1.0-py311hbc16ef1_0_cpu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyarrow-hotfix-0.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.18.2-py311h5d190b6_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.18.4-py311h98c6a39_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pymetis-2023.1.1-py311h006cce6_2.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyobjc-core-10.2-py311h665608e_0.conda @@ -3214,20 +3202,20 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-benchmark-4.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cases-3.8.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-5.0.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.5.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.11.0-h3ba56d0_1_cpython.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.19.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.20.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gmsh-4.12.2-h57928b3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-graphviz-0.20.3-pyh717bed2_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2024.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python_abi-3.11-4_cp311.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pyvista-0.43.8-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyvista-0.43.9-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyyaml-6.0.1-py311heffc1b2_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/pyzmq-26.0.3-py311h9bed540_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/qt-main-5.15.8-h6bf1bb6_19.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/qt6-main-6.7.1-h845717a_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/qtconsole-base-5.5.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/qtpy-2.4.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rapidjson-1.1.0.post20240409-h00cdb27_1.conda @@ -3236,7 +3224,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h92ec313_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/readme_renderer-42.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.35.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-toolbelt-1.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-2.0.0-pyhd8ed1ab_0.tar.bz2 @@ -3244,8 +3232,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rioxarray-0.15.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rpds-py-0.18.1-py311h98c6a39_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rtree-1.2.0-py311hd698ff7_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.4.5-py311hd374d79_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/rtree-1.2.0-py311h46a7578_1.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.4.9-py311hd374d79_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scikit-learn-1.5.0-py311hbfb48bc_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/scipy-1.13.1-py311hceeca8c_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/scooby-0.10.0-pyhd8ed1ab_0.conda @@ -3261,7 +3249,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/snuggs-1.4.7-py_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.5-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/spdlog-1.12.0-he64bfa9_2.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/spdlog-1.13.0-h5fcca99_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-5.0.0-pyh6c4a22f_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-gallery-0.16.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-1.0.8-pyhd8ed1ab_0.conda @@ -3270,29 +3258,29 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-1.0.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.10-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/sqlite-3.45.3-hf2abe2d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/sqlite-3.46.0-h5838104_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/svt-av1-2.0.0-h078ce10_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/svt-av1-2.1.0-h7bae524_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tbb-2021.12.0-h420ef59_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tbb-devel-2021.12.0-h94f16c5_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh31c8845_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tiledb-2.20.1-hca4efeb_7.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tiledb-2.21.2-hf0716ca_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tk-8.6.13-h5083fa2_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-w-1.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/toolz-0.12.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.4-py311h05b510d_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.4.1-py311hd3f4193_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.66.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.22-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/twine-5.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/types-python-dateutil-2.9.0.20240316-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.11.0-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.11.0-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/tzcode-2024a-h93a5062_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda @@ -3300,19 +3288,19 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/uriparser-0.9.8-h00cdb27_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/utfcpp-4.0.5-hce30654_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/vtk-9.2.6-qt_py311h1234567_220.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/vtk-base-9.2.6-qt_py311h1234567_220.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/vtk-io-ffmpeg-9.2.6-qt_py311h1234567_220.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/vtk-9.3.0-qt_py311h1234567_200.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/vtk-base-9.3.0-qt_py311h1234567_200.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/vtk-io-ffmpeg-9.3.0-qt_py311h1234567_200.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-1.13-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-24.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.8.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.10-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.11-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/x264-1!164.3095-h57fd34a_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/x265-3.5-hbc6ce65_3.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.5.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.6.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xerces-c-3.2.5-hf393695_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-fixesproto-5.0-h3422bc3_1002.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-kbproto-1.0.7-h27ca646_1002.tar.bz2 @@ -3328,15 +3316,15 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-xextproto-7.3.0-h1a8c8d9_1003.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-xproto-7.0.31-h27ca646_1007.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.10.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xz-5.2.6-h57fd34a_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h3422bc3_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yarl-1.9.4-py311h05b510d_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-2.18.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-2.18.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zeromq-4.3.5-hcc0f68c_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zict-3.0.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.2.13-h53f4e23_5.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.19.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.2.13-hfb2fe0b_6.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/zstd-1.5.6-hb46c0d2_0.conda - pypi: https://files.pythonhosted.org/packages/50/fa/a2561d6837cd45a3971c514222e94d3ded3f105993ddcf4983ed68ce3da3/mypy2junit-1.9.0-py3-none-any.whl win-64: @@ -3346,8 +3334,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/aiosignal-1.3.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/alabaster-0.7.16-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/annotated-types-0.7.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.3.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aom-3.8.2-h63175ca_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/anyio-4.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aom-3.9.0-he0c23c2_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/argon2-cffi-23.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/argon2-cffi-bindings-21.2.0-py311ha68e1ae_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/arrow-1.3.0-pyhd8ed1ab_0.conda @@ -3355,19 +3343,19 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/asttokens-2.4.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/async-lru-2.0.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/attrs-23.2.0-pyh71513ae_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-auth-0.7.17-hb40cdec_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-cal-0.6.11-ha21e00f_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-common-0.9.15-hcfcfb64_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-compression-0.2.18-ha21e00f_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-event-stream-0.4.2-hf668b60_8.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-http-0.8.1-hd704247_10.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-io-0.14.7-h14865c8_6.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-mqtt-0.10.3-h748201e_4.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-s3-0.5.7-h5da7064_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-sdkutils-0.1.15-ha21e00f_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-checksums-0.1.18-ha21e00f_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-crt-cpp-0.26.6-h5bc0ceb_4.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/aws-sdk-cpp-1.11.267-h5d77392_6.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-auth-0.7.20-h6823eb1_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-cal-0.6.12-hc83774a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-common-0.9.17-h2466b09_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-compression-0.2.18-hc83774a_4.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-event-stream-0.4.2-hc6c0aac_10.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-http-0.8.1-hced5053_13.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-io-0.14.8-hebaacdb_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-mqtt-0.10.4-hdafd9a4_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-s3-0.5.9-h7a83f0e_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-c-sdkutils-0.1.16-hc83774a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-checksums-0.1.18-hc83774a_4.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-crt-cpp-0.26.8-h672a689_11.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/aws-sdk-cpp-1.11.267-h12f3f85_8.conda - conda: https://conda.anaconda.org/conda-forge/win-64/azure-core-cpp-1.11.1-h249a519_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/azure-storage-blobs-cpp-12.10.0-h91493d7_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/azure-storage-common-cpp-12.5.0-h91493d7_4.conda @@ -3388,14 +3376,14 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/build-0.7.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-hcfcfb64_5.conda - conda: https://conda.anaconda.org/conda-forge/win-64/c-ares-1.28.1-hcfcfb64_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ca-certificates-2024.2.2-h56e8100_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ca-certificates-2024.6.2-h56e8100_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cached-property-1.5.2-hd8ed1ab_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/cached_property-1.5.2-pyha770c72_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/cairo-1.18.0-h1fef639_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.2.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.6.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/cffi-1.16.0-py311ha68e1ae_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/cfitsio-4.3.1-h9b0cee5_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/cftime-1.6.3-py311h0a17f05_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cfitsio-4.4.0-h9b0cee5_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/cftime-1.6.4-py311h0a17f05_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/charset-normalizer-3.3.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-8.1.7-win_pyh7428d3b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/click-plugins-1.1.1-py_0.tar.bz2 @@ -3406,7 +3394,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/comm-0.2.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/contextily-1.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/contourpy-1.2.1-py311h005e61a_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/coverage-7.5.1-py311he736701_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/coverage-7.5.3-py311he736701_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/cycler-0.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/cytoolz-0.12.3-py311ha68e1ae_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/dask-2023.12.1-pyhd8ed1ab_0.conda @@ -3425,10 +3413,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/exceptiongroup-1.2.0-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/execnet-2.1.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/executing-2.0.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/expat-2.5.0-h63175ca_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.38-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/expat-2.6.2-h63175ca_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.45-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fasteners-0.17.3-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/ffmpeg-6.1.1-gpl_h66c0b5b_108.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ffmpeg-6.1.1-gpl_h7cec250_112.conda - conda: https://conda.anaconda.org/conda-forge/win-64/fiona-1.9.6-py311hbcf8545_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/flopy-3.7.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/fltk-1.3.9-h01c93fd_0.conda @@ -3441,15 +3429,15 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/fontconfig-2.14.2-hbde0cde_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-ecosystem-1-0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/fonts-conda-forge-1-0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.52.1-py311he736701_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.53.0-py311he736701_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/fqdn-1.5.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/freeimage-3.18.0-h2b56e36_20.conda - conda: https://conda.anaconda.org/conda-forge/win-64/freetype-2.12.1-hdaf720e_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/freexl-2.0.0-h8276f4a_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/fribidi-1.0.10-h8d14728_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/frozenlist-1.4.1-py311ha68e1ae_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2024.5.0-pyhff2d567_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/gdal-3.8.4-py311h21a6730_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/fsspec-2024.6.0-pyhff2d567_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/gdal-3.8.4-py311h21a6730_5.conda - conda: https://conda.anaconda.org/conda-forge/noarch/geographiclib-2.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-0.14.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/geopandas-base-0.14.4-pyha770c72_0.conda @@ -3457,30 +3445,28 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/geos-3.12.1-h1537add_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/geotiff-1.7.1-hbf5ca3a_15.conda - conda: https://conda.anaconda.org/conda-forge/win-64/getopt-win32-0.1-hcfcfb64_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/gettext-0.22.5-h5728263_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/gettext-tools-0.22.5-h7d00a51_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/gh-2.49.2-h36e2d1d_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/gh-2.51.0-h36e2d1d_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/gl2ps-1.4.2-h0597ee9_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/glew-2.1.0-h39d44d4_2.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/glib-2.78.4-h12be248_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/glib-tools-2.78.4-h12be248_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/glib-2.80.2-h0df6a38_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/glib-tools-2.80.2-h2f9d560_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/gmsh-4.12.2-hcc95203_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/graphite2-1.3.13-h63175ca_1003.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/graphviz-9.0.0-h51cb2cd_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/gst-plugins-base-1.22.9-h001b923_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/gstreamer-1.22.9-hb4038d2_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/graphviz-11.0.0-h09e431a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/gst-plugins-base-1.24.4-hba88be7_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/gstreamer-1.24.4-h5006eae_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/gts-0.7.6-h6b5321d_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/h11-0.14.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/h2-4.1.0-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/harfbuzz-8.3.0-h7ab893a_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/harfbuzz-8.5.0-h81778c3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hatchling-1.24.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/hdf4-4.2.15-h5557f11_7.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/hdf5-1.14.3-nompi_h73e8ff5_101.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/hdf5-1.14.3-nompi_h2b43c12_105.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hpack-4.0.0-pyh9f0ad1d_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/httpcore-1.0.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/httpx-0.27.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/hyperframe-6.0.1-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.6-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.103.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/icu-73.2-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/idna-3.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/imagesize-1.4.1-pyhd8ed1ab_0.tar.bz2 @@ -3490,9 +3476,9 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/importlib_resources-6.4.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/iniconfig-2.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/intel-openmp-2024.1.0-h57928b3_966.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.3-pyha63f2e9_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-8.24.0-pyh7428d3b_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.2-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.4-pyh4bbf305_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipython-8.25.0-pyh7428d3b_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/isoduration-20.11.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.classes-3.4.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jaraco.context-5.3.0-pyhd8ed1ab_1.conda @@ -3502,7 +3488,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/joblib-1.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/json5-0.9.25-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/jsoncpp-1.9.5-h2d74725_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/jsonpointer-2.4-py311h1ea47a8_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/jsonpointer-3.0.0-py311h1ea47a8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-4.22.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-specifications-2023.12.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jsonschema-with-format-nongpl-4.22.0-pyhd8ed1ab_0.conda @@ -3512,12 +3498,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_console-6.6.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/jupyter_core-5.7.2-py311h1ea47a8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_events-0.10.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyter_server_terminals-0.5.3-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_pygments-0.3.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_server-2.27.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.10-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.11-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/jxrlib-1.1-hcfcfb64_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/kealib-1.5.3-h6c43f9b_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/keyring-25.2.1-pyh7428d3b_0.conda @@ -3528,36 +3514,28 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/libabseil-20240116.2-cxx17_h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libaec-1.1.3-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libarchive-3.7.4-haf234dc_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-15.0.2-h45212c0_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-acero-15.0.2-h8681a6d_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-dataset-15.0.2-h8681a6d_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-flight-15.0.2-h83a3238_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-flight-sql-15.0.2-h21569af_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-gandiva-15.0.2-h05de715_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-substrait-15.0.2-hea7f8fd_3_cpu.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libasprintf-0.22.5-h5728263_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libasprintf-devel-0.22.5-h5728263_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-16.1.0-h107e38f_1_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-acero-16.1.0-he0c23c2_1_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-dataset-16.1.0-he0c23c2_1_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libarrow-substrait-16.1.0-h1f0e801_1_cpu.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libblas-3.9.0-22_win64_mkl.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libboost-headers-1.85.0-h57928b3_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlicommon-1.1.0-hcfcfb64_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlidec-1.1.0-hcfcfb64_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libbrotlienc-1.1.0-hcfcfb64_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libcblas-3.9.0-22_win64_mkl.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libclang-15.0.7-default_h3a3e6c3_5.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libclang13-15.0.7-default_hf64faad_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libclang13-18.1.7-default_h97ce8ae_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libcrc32c-1.1.2-h0e60522_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/libcurl-8.8.0-hd5e4a3a_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.19-hcfcfb64_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.20-hcfcfb64_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libevent-2.1.12-h3671451_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.5.0-h63175ca_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.6.2-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.4.2-h8ffe710_5.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/libgd-2.3.3-h312136b_9.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libgdal-3.8.4-h7c2897a_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libgettextpo-0.22.5-h5728263_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libgettextpo-devel-0.22.5-h5728263_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.78.4-h16e383f_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libgoogle-cloud-2.22.0-h9cad5c0_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libgoogle-cloud-storage-2.22.0-hb581fae_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgdal-3.8.4-hf83a0e2_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libglib-2.80.2-h0df6a38_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgoogle-cloud-2.23.0-h68df31e_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libgoogle-cloud-storage-2.23.0-hb581fae_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libgrpc-1.62.2-h5273850_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libhwloc-2.10.0-default_h8125262_1001.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libiconv-1.17-hcfcfb64_2.conda @@ -3566,10 +3544,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/libjpeg-turbo-3.0.0-hcfcfb64_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libkml-1.3.0-haf3e7a6_1018.conda - conda: https://conda.anaconda.org/conda-forge/win-64/liblapack-3.9.0-22_win64_mkl.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libnetcdf-4.9.2-nompi_h07c049d_113.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libnetcdf-4.9.2-nompi_h92078aa_114.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libogg-1.3.4-h8ffe710_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/libopus-1.3.1-h8ffe710_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/libparquet-15.0.2-h39135fc_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libparquet-16.1.0-h178134c_1_cpu.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libpng-1.6.43-h19919ed_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libpq-16.3-hab9416b_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libprotobuf-4.25.3-h503648d_0.conda @@ -3577,21 +3555,21 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/libre2-11-2023.09.01-hf8d8778_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/librttopo-1.1.0-h94c4f80_15.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libsodium-1.0.18-h8d14728_1.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/libspatialindex-1.9.3-h5a68840_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libspatialindex-2.0.0-h5a68840_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libspatialite-5.1.0-hf2f0abc_4.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.45.3-hcfcfb64_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.46.0-h2466b09_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libssh2-1.11.0-h7dfc565_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libtheora-1.1.1-h8d14728_1005.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/libthrift-0.19.0-ha2b3283_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.6.0-h6e2ebb7_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.6.0-hddb2be6_3.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libutf8proc-2.8.0-h82a8f57_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/libvorbis-1.3.7-h0e60522_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-1.4.0-h2466b09_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libwebp-base-1.4.0-hcfcfb64_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libxcb-1.15-hcd874cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.12.7-h283a6d9_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.12.7-h283a6d9_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libzip-1.10.1-h1d365fa_3.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.2.13-hcfcfb64_5.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.2.13-h2466b09_6.conda - conda: https://conda.anaconda.org/conda-forge/win-64/llvmlite-0.42.0-py311h5bc0dda_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/locket-1.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/loguru-0.7.2-py311h1ea47a8_1.conda @@ -3613,10 +3591,10 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/mdurl-0.1.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mercantile-1.2.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/metis-5.1.1-h63175ca_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/minizip-4.0.5-h5bed578_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/minizip-4.0.6-hb638d1e_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mistune-3.0.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/mkl-2024.1.0-h66d3029_692.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.2.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/msgpack-python-1.0.8-py311h3257749_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/msys2-conda-epoch-20160418-1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/multidict-6.0.5-py311ha68e1ae_0.conda @@ -3624,56 +3602,56 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/mypy-1.10.0-py311he736701_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/mypy_extensions-1.0.0-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbclient-0.10.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.4-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.4-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.16.4-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.4-hd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.4-pyhd8ed1ab_1.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.16.4-hd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nbformat-5.10.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/nest-asyncio-1.6.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/netcdf4-1.6.5-nompi_py311hb75404a_101.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/netcdf4-1.6.5-nompi_py311hb75404a_102.conda - conda: https://conda.anaconda.org/conda-forge/noarch/networkx-3.3-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/nh3-0.2.17-py311h633b200_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/nlohmann_json-3.11.3-h1537add_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-7.2.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-7.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/numba-0.59.1-py311h2c0921f_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/numcodecs-0.12.1-py311hda3d55a_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-1.26.4-py311h0b4df5a_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/occt-7.7.2-all_h165458f_201.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/occt-7.7.2-novtk_hdfb195f_101.conda - conda: https://conda.anaconda.org/conda-forge/win-64/openexr-3.2.2-h72640d8_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/openh264-2.4.1-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/openjpeg-2.5.2-h3d672ee_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.0-h2466b09_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.1-h2466b09_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/orc-2.0.0-h7e885a9_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/overrides-7.7.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/packaging-24.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandamesh-0.1.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pandas-2.2.2-py311hcf9f919_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pandoc-3.2-h57928b3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pandocfilters-1.5.0-pyhd8ed1ab_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/pango-1.52.1-h07c897b_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pango-1.54.0-h2231ffd_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/parso-0.8.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/partd-1.4.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pathspec-0.12.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.42-h17e33f8_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.43-h17e33f8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pep517-0.13.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pickleshare-0.7.5-py_1003.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/pillow-10.3.0-py311h6819b35_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pixman-0.43.4-h63175ca_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.11.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pkgutil-resolve-name-1.3.10-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/platformdirs-4.2.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pluggy-1.5.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/ply-3.11-pyhd8ed1ab_2.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/poppler-24.02.0-hc2f3c52_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/poppler-24.03.0-hc2f3c52_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/poppler-data-0.4.12-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/postgresql-16.3-h7f155c9_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/proj-9.3.1-he13c7e8_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/prometheus_client-0.20.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.42-pyha770c72_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.42-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.47-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.47-hd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/psutil-5.9.8-py311ha68e1ae_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pthread-stubs-0.4-hcd874cb_1001.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/pthreads-win32-2.9.1-hfa6e2cd_3.tar.bz2 @@ -3681,12 +3659,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pure_eval-0.2.2-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/py-cpuinfo-9.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/py-triangle-20230923-py311ha68e1ae_2.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pyarrow-15.0.2-py311h05400ba_3_cpu.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyarrow-16.1.0-py311h3810d55_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pyarrow-core-16.1.0-py311h65ac0bd_0_cpu.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyarrow-hotfix-0.6-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pycparser-2.22-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.18.2-py311h533ab2d_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.18.4-py311h533ab2d_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pygments-2.18.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pymetis-2023.1.1-py311hca2ccfb_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pyparsing-3.1.2-pyhd8ed1ab_0.conda @@ -3698,23 +3677,24 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-benchmark-4.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cases-3.8.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-5.0.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.5.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.11.0-hcf16a7b_0_cpython.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.19.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.20.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gmsh-4.12.2-h57928b3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-graphviz-0.20.3-pyh717bed2_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-json-logger-2.0.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2024.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/python_abi-3.11-4_cp311.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytz-2024.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/pyvista-0.43.8-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pyvista-0.43.9-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-306-py311h12c1d0e_2.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pywin32-ctypes-0.2.2-py311h1ea47a8_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pywinpty-2.0.13-py311h12c1d0e_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pyyaml-6.0.1-py311ha68e1ae_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/pyzmq-26.0.3-py311h484c95c_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/qt-main-5.15.8-h9e85ed6_19.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/qt-main-5.15.8-hcef0176_21.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.7.1-h9e9f2d0_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/qtconsole-base-5.5.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/qtpy-2.4.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/rapidjson-1.1.0.post20240409-he0c23c2_1.conda @@ -3722,7 +3702,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/re2-2023.09.01-hd3b24a8_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/readme_renderer-42.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/referencing-0.35.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/requests-toolbelt-1.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3339-validator-0.1.4-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/rfc3986-2.0.0-pyhd8ed1ab_0.tar.bz2 @@ -3730,8 +3710,8 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/rich-13.7.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/rioxarray-0.15.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/rpds-py-0.18.1-py311h533ab2d_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/rtree-1.2.0-py311hcacb13a_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.4.5-py311ha637bb9_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/rtree-1.2.0-py311h44d53c4_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ruff-0.4.9-py311ha637bb9_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/scikit-learn-1.5.0-py311hdcb8d17_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/scipy-1.13.1-py311hd4686c6_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/scooby-0.10.0-pyhd8ed1ab_0.conda @@ -3748,7 +3728,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/snuggs-1.4.7-py_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/sortedcontainers-2.4.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/soupsieve-2.5-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/spdlog-1.12.0-h64d2f7d_2.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/spdlog-1.13.0-h64d2f7d_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-5.0.0-pyh6c4a22f_1.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/sphinx-gallery-0.16.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-applehelp-1.0.8-pyhd8ed1ab_0.conda @@ -3757,29 +3737,29 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-jsmath-1.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-qthelp-1.0.7-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/sphinxcontrib-serializinghtml-1.1.10-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/sqlite-3.45.3-hcfcfb64_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/sqlite-3.46.0-h2466b09_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/stack_data-0.6.2-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/svt-av1-2.0.0-h63175ca_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/svt-av1-2.1.0-he0c23c2_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-2021.12.0-hc790b64_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tbb-devel-2021.12.0-hb551fcf_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tblib-3.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/terminado-0.18.1-pyh5737063_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/threadpoolctl-3.5.0-pyhc1e730c_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tiledb-2.20.1-hc9ddcec_7.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tiledb-2.21.2-hf39fa12_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tinycss2-1.3.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h5226925_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/toml-0.10.2-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-2.0.1-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/tomli-w-1.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/toolz-0.12.1-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.4-py311ha68e1ae_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/tornado-6.4.1-py311he736701_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tqdm-4.66.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/traitlets-5.14.3-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/trove-classifiers-2024.5.22-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/twine-5.1.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/types-python-dateutil-2.9.0.20240316-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.11.0-hd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.11.0-pyha770c72_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/typing_utils-0.1.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_0.tar.bz2 @@ -3787,24 +3767,24 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/uriparser-0.9.8-h5a68840_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/urllib3-2.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/utfcpp-4.0.5-h57928b3_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-ha32ba9b_20.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.38.33135-h835141b_20.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.38.33135-h22015db_20.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vtk-9.2.6-qt_py311h1234567_220.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vtk-base-9.2.6-qt_py311h1234567_220.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h8a93ad2_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.40.33810-ha82c5b3_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.40.33810-h3bf8584_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vtk-9.3.0-qt_py311h1234567_200.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vtk-base-9.3.0-qt_py311h1234567_200.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wcwidth-0.2.13-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-1.13-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/webcolors-24.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/webencodings-0.5.1-pyhd8ed1ab_2.conda - conda: https://conda.anaconda.org/conda-forge/noarch/websocket-client-1.8.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.10-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.11-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/win32_setctime-1.1.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/win_inet_pton-1.1.0-pyhd8ed1ab_6.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/winpty-0.4.3-4.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.4-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/x264-1!164.3095-h8ffe710_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/x265-3.5-h2d74725_3.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.5.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.6.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/xerces-c-3.2.5-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-fixesproto-5.0-hcd874cb_1002.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-kbproto-1.0.7-hcd874cb_1002.tar.bz2 @@ -3822,15 +3802,15 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-xextproto-7.3.0-hcd874cb_1003.conda - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-xproto-7.0.31-hcd874cb_1007.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.10.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.4.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/xz-5.2.6-h8d14728_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h8ffe710_2.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/yarl-1.9.4-py311ha68e1ae_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-2.18.1-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zarr-2.18.2-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zeromq-4.3.5-he1f189c_4.conda - conda: https://conda.anaconda.org/conda-forge/noarch/zict-3.0.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/zlib-1.2.13-hcfcfb64_5.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/zipp-3.19.2-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/zlib-1.2.13-h2466b09_6.conda - conda: https://conda.anaconda.org/conda-forge/win-64/zstd-1.5.6-h0ea2cb4_0.conda - pypi: https://files.pythonhosted.org/packages/50/fa/a2561d6837cd45a3971c514222e94d3ded3f105993ddcf4983ed68ce3da3/mypy2junit-1.9.0-py3-none-any.whl py310: @@ -3841,17 +3821,17 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hd590300_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.2.2-hbcca054_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.6.2-hbcca054_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_6.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_10.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_10.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.45.3-h2797004_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.46.0-hde9e2c9_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-hd590300_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-h4ab18f5_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h59595ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.0-h4ab18f5_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.1-h4ab18f5_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.10.12-hd12c33a_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda @@ -3862,12 +3842,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2 osx-64: - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h10d778d_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/ca-certificates-2024.2.2-h8857fd0_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ca-certificates-2024.6.2-h8857fd0_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.4.2-h0d85af4_5.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.45.3-h92b6c6a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.2.13-h8a1eda9_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.46.0-h1b8f9f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-h87427d6_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h5846eda_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.0-h87427d6_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.1-h87427d6_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.10.12-had23ca6_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h9e318b2_1.conda @@ -3878,12 +3858,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/xz-5.2.6-h775f41a_0.tar.bz2 osx-arm64: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-h93a5062_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ca-certificates-2024.2.2-hf0a4a13_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ca-certificates-2024.6.2-hf0a4a13_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.4.2-h3422bc3_5.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.45.3-h091b4b1_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.2.13-h53f4e23_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.46.0-hfb93653_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-hfb2fe0b_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-hb89a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.0-hfb2fe0b_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.1-hfb2fe0b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.10.12-h01493a6_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h92ec313_1.conda @@ -3894,20 +3874,20 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xz-5.2.6-h57fd34a_0.tar.bz2 win-64: - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-hcfcfb64_5.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ca-certificates-2024.2.2-h56e8100_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ca-certificates-2024.6.2-h56e8100_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.4.2-h8ffe710_5.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.45.3-hcfcfb64_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.2.13-hcfcfb64_5.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.0-h2466b09_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.46.0-h2466b09_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.1-h2466b09_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.10.12-h4de0772_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h5226925_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-ha32ba9b_20.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.38.33135-h835141b_20.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.38.33135-h22015db_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h8a93ad2_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.40.33810-ha82c5b3_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.40.33810-h3bf8584_20.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/xz-5.2.6-h8d14728_0.tar.bz2 py311: @@ -3918,17 +3898,17 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hd590300_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.2.2-hbcca054_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.6.2-hbcca054_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_6.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_10.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_10.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.45.3-h2797004_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.46.0-hde9e2c9_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-hd590300_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-h4ab18f5_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h59595ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.0-h4ab18f5_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.1-h4ab18f5_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.11.0-he550d4f_1_cpython.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda @@ -3939,12 +3919,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2 osx-64: - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h10d778d_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/ca-certificates-2024.2.2-h8857fd0_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ca-certificates-2024.6.2-h8857fd0_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.4.2-h0d85af4_5.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.45.3-h92b6c6a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.2.13-h8a1eda9_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.46.0-h1b8f9f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-h87427d6_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h5846eda_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.0-h87427d6_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.1-h87427d6_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.11.0-he7542f4_1_cpython.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h9e318b2_1.conda @@ -3955,12 +3935,12 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/xz-5.2.6-h775f41a_0.tar.bz2 osx-arm64: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-h93a5062_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ca-certificates-2024.2.2-hf0a4a13_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ca-certificates-2024.6.2-hf0a4a13_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.4.2-h3422bc3_5.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.45.3-h091b4b1_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.2.13-h53f4e23_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.46.0-hfb93653_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-hfb2fe0b_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-hb89a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.0-hfb2fe0b_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.1-hfb2fe0b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.11.0-h3ba56d0_1_cpython.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h92ec313_1.conda @@ -3971,20 +3951,20 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xz-5.2.6-h57fd34a_0.tar.bz2 win-64: - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-hcfcfb64_5.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ca-certificates-2024.2.2-h56e8100_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ca-certificates-2024.6.2-h56e8100_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.4.2-h8ffe710_5.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.45.3-hcfcfb64_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.2.13-hcfcfb64_5.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.0-h2466b09_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.46.0-h2466b09_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.1-h2466b09_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.11.0-hcf16a7b_0_cpython.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h5226925_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-ha32ba9b_20.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.38.33135-h835141b_20.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.38.33135-h22015db_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h8a93ad2_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.40.33810-ha82c5b3_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.40.33810-h3bf8584_20.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/xz-5.2.6-h8d14728_0.tar.bz2 py312: @@ -3995,18 +3975,18 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/_libgcc_mutex-0.1-conda_forge.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/_openmp_mutex-4.5-2_gnu.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/bzip2-1.0.8-hd590300_5.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.2.2-hbcca054_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_1.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.6.2-hbcca054_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_6.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.6.2-h59595ed_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libffi-3.4.2-h7f98852_5.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_7.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_7.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_10.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_10.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libnsl-2.0.1-hd590300_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.45.3-h2797004_0.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.46.0-hde9e2c9_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/libuuid-2.38.1-h0b41bf4_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-hd590300_5.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-h4ab18f5_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/ncurses-6.5-h59595ed_0.conda - - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.0-h4ab18f5_3.conda + - conda: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.1-h4ab18f5_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.12.0-hab00c5b_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/readline-8.2-h8228510_1.conda @@ -4017,13 +3997,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2 osx-64: - conda: https://conda.anaconda.org/conda-forge/osx-64/bzip2-1.0.8-h10d778d_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/ca-certificates-2024.2.2-h8857fd0_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/ca-certificates-2024.6.2-h8857fd0_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libexpat-2.6.2-h73e2aa4_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/libffi-3.4.2-h0d85af4_5.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.45.3-h92b6c6a_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.2.13-h8a1eda9_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.46.0-h1b8f9f3_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-h87427d6_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/ncurses-6.5-h5846eda_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.0-h87427d6_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.1-h87427d6_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.12.0-h30d4d87_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/readline-8.2-h9e318b2_1.conda @@ -4034,13 +4014,13 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/xz-5.2.6-h775f41a_0.tar.bz2 osx-arm64: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/bzip2-1.0.8-h93a5062_5.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ca-certificates-2024.2.2-hf0a4a13_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ca-certificates-2024.6.2-hf0a4a13_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.6.2-hebf3989_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libffi-3.4.2-h3422bc3_5.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.45.3-h091b4b1_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.2.13-h53f4e23_5.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.46.0-hfb93653_0.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-hfb2fe0b_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/ncurses-6.5-hb89a1cb_0.conda - - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.0-hfb2fe0b_3.conda + - conda: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.1-hfb2fe0b_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.12.0-h47c9636_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/readline-8.2-h92ec313_1.conda @@ -4051,21 +4031,21 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xz-5.2.6-h57fd34a_0.tar.bz2 win-64: - conda: https://conda.anaconda.org/conda-forge/win-64/bzip2-1.0.8-hcfcfb64_5.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/ca-certificates-2024.2.2-h56e8100_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/ca-certificates-2024.6.2-h56e8100_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.6.2-h63175ca_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/libffi-3.4.2-h8ffe710_5.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.45.3-hcfcfb64_0.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.2.13-hcfcfb64_5.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.0-h2466b09_3.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.46.0-h2466b09_0.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_1.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.1-h2466b09_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pip-24.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.12.0-h2628c8c_0_cpython.conda - conda: https://conda.anaconda.org/conda-forge/noarch/setuptools-70.0.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/tk-8.6.13-h5226925_1.conda - conda: https://conda.anaconda.org/conda-forge/noarch/tzdata-2024a-h0c530f3_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/ucrt-10.0.22621.0-h57928b3_0.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-ha32ba9b_20.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.38.33135-h835141b_20.conda - - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.38.33135-h22015db_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h8a93ad2_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.40.33810-ha82c5b3_20.conda + - conda: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.40.33810-h3bf8584_20.conda - conda: https://conda.anaconda.org/conda-forge/noarch/wheel-0.43.0-pyhd8ed1ab_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/xz-5.2.6-h8d14728_0.tar.bz2 packages: @@ -4263,19 +4243,18 @@ packages: timestamp: 1704848898483 - kind: conda name: alsa-lib - version: 1.2.11 - build: hd590300_1 - build_number: 1 + version: 1.2.12 + build: h4ab18f5_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.11-hd590300_1.conda - sha256: 0e2b75b9834a6e520b13db516f7cf5c9cea8f0bbc9157c978444173dacb98fec - md5: 0bb492cca54017ea314b809b1ee3a176 + url: https://conda.anaconda.org/conda-forge/linux-64/alsa-lib-1.2.12-h4ab18f5_0.conda + sha256: 64b95dd06d7ca6b54cea03b02da8f1657b9899ca376d0ca7b47823064f55fb16 + md5: 7ed427f0871fd41cb1d9c17727c17589 depends: - libgcc-ng >=12 license: LGPL-2.1-or-later license_family: GPL - size: 554699 - timestamp: 1709396557528 + size: 555868 + timestamp: 1718118368236 - kind: conda name: annotated-types version: 0.7.0 @@ -4296,13 +4275,13 @@ packages: timestamp: 1716290348421 - kind: conda name: anyio - version: 4.3.0 + version: 4.4.0 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/anyio-4.3.0-pyhd8ed1ab_0.conda - sha256: 86aca4a31c09f9b4dbdb332cd9a6a7dbab62ca734d3f832651c0ab59c6a7f52e - md5: ac95aa8ed65adfdde51132595c79aade + url: https://conda.anaconda.org/conda-forge/noarch/anyio-4.4.0-pyhd8ed1ab_0.conda + sha256: 84ac9429812495f12939ab4994f2634f7cacd254f6234a0c2c0243daed15a7ee + md5: 1fa97c6e8db1f82c64ff17a5efc4ae8e depends: - exceptiongroup >=1.0.2 - idna >=2.8 @@ -4310,73 +4289,74 @@ packages: - sniffio >=1.1 - typing_extensions >=4.1 constrains: - - trio >=0.23 - uvloop >=0.17 + - trio >=0.23 license: MIT license_family: MIT purls: - pkg:pypi/anyio - size: 102331 - timestamp: 1708355504396 + size: 104255 + timestamp: 1717693144467 - kind: conda name: aom version: 3.8.2 - build: h078ce10_0 + build: h73e2aa4_0 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/aom-3.8.2-h73e2aa4_0.conda + sha256: 967d05b46e0a8153c57070a94262d38ffc03378803c1faa0bad258e8635d3775 + md5: a519a6b9f8f0e2ce1b4ee77cbc6a0a09 + depends: + - libcxx >=16 + license: BSD-2-Clause + license_family: BSD + size: 2922373 + timestamp: 1710388791338 +- kind: conda + name: aom + version: 3.9.0 + build: h537b5a7_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/aom-3.8.2-h078ce10_0.conda - sha256: d3a6cb707373a8d2d219259ad017a35c20fc3618e39c87db0d6200af0f984379 - md5: 3c5057d1d4494caab891ed6f276c3f63 + url: https://conda.anaconda.org/conda-forge/osx-arm64/aom-3.9.0-h537b5a7_0.conda + sha256: f039f04af46012e28d78c2ab81615d7e92305e5512f915b55ecbf18519a416bb + md5: 73720568ee5ed2217afacb3241493b12 depends: + - __osx >=11.0 - libcxx >=16 license: BSD-2-Clause license_family: BSD - size: 2204439 - timestamp: 1710388305837 + size: 2251406 + timestamp: 1713925883308 - kind: conda name: aom - version: 3.8.2 - build: h59595ed_0 + version: 3.9.0 + build: hac33072_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/aom-3.8.2-h59595ed_0.conda - sha256: 49b1352e2b9710b7b5400c0f2a86c0bb805091ecfc6c84d3dbf064effe33bfbf - md5: 625e1fed28a5139aed71b3a76117ef84 + url: https://conda.anaconda.org/conda-forge/linux-64/aom-3.9.0-hac33072_0.conda + sha256: eef9b630ec0d3a3835c388b00685002d67d1d44db2af6c734921bdf65035654f + md5: 93a3bf248e5bc729807db198a9c89f07 depends: - libgcc-ng >=12 - libstdcxx-ng >=12 license: BSD-2-Clause license_family: BSD - size: 2696998 - timestamp: 1710388229587 + size: 2701135 + timestamp: 1713925435201 - kind: conda name: aom - version: 3.8.2 - build: h63175ca_0 + version: 3.9.0 + build: he0c23c2_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/aom-3.8.2-h63175ca_0.conda - sha256: dd79f4e3660ab169f4e2d9bf2d9e74001dcf6dfaa8d1168373b3450af5282286 - md5: 6691dd6833a29c95e3a16e08841a0f43 + url: https://conda.anaconda.org/conda-forge/win-64/aom-3.9.0-he0c23c2_0.conda + sha256: 324cc117c8357c2d376314d16b4532b0abacccb197a3f1c9077e4c2e896c164e + md5: 12fabceb3d880581a35c78b4d195f829 depends: - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 license: BSD-2-Clause license_family: BSD - size: 1968537 - timestamp: 1710388705950 -- kind: conda - name: aom - version: 3.8.2 - build: h73e2aa4_0 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/aom-3.8.2-h73e2aa4_0.conda - sha256: 967d05b46e0a8153c57070a94262d38ffc03378803c1faa0bad258e8635d3775 - md5: a519a6b9f8f0e2ce1b4ee77cbc6a0a09 - depends: - - libcxx >=16 - license: BSD-2-Clause - license_family: BSD - size: 2922373 - timestamp: 1710388791338 + size: 1972773 + timestamp: 1713925809773 - kind: conda name: appnope version: 0.1.4 @@ -4572,30 +4552,31 @@ packages: - kind: conda name: atk-1.0 version: 2.38.0 - build: h1d18e73_1 - build_number: 1 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/atk-1.0-2.38.0-h1d18e73_1.tar.bz2 - sha256: 7af1f86cfc85b1e57547e2a81c069095545ff6a52f3f8e15184df954dce446dd - md5: 5a538295f97a484ee332aacc131718b5 + build: h04ea711_2 + build_number: 2 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/atk-1.0-2.38.0-h04ea711_2.conda + sha256: df682395d05050cd1222740a42a551281210726a67447e5258968dd55854302e + md5: f730d54ba9cd543666d7220c9f7ed563 depends: - - libcxx >=14.0.4 - - libglib >=2.74.1,<3.0a0 + - libgcc-ng >=12 + - libglib >=2.80.0,<3.0a0 + - libstdcxx-ng >=12 constrains: - atk-1.0 2.38.0 license: LGPL-2.0-or-later license_family: LGPL - size: 367515 - timestamp: 1667421223751 + size: 355900 + timestamp: 1713896169874 - kind: conda name: atk-1.0 version: 2.38.0 - build: hcb7b3dd_1 + build: h1d18e73_1 build_number: 1 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/atk-1.0-2.38.0-hcb7b3dd_1.tar.bz2 - sha256: d40f103467fd2fa426072691919fd135a4fed4a2b03cd12256ff0fee37a98249 - md5: 3c98bfeed7717a9cf5af18c295f49f3a + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/atk-1.0-2.38.0-h1d18e73_1.tar.bz2 + sha256: 7af1f86cfc85b1e57547e2a81c069095545ff6a52f3f8e15184df954dce446dd + md5: 5a538295f97a484ee332aacc131718b5 depends: - libcxx >=14.0.4 - libglib >=2.74.1,<3.0a0 @@ -4603,27 +4584,28 @@ packages: - atk-1.0 2.38.0 license: LGPL-2.0-or-later license_family: LGPL - size: 373158 - timestamp: 1667421529784 + size: 367515 + timestamp: 1667421223751 - kind: conda name: atk-1.0 version: 2.38.0 - build: hd4edc92_1 - build_number: 1 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/atk-1.0-2.38.0-hd4edc92_1.tar.bz2 - sha256: 2f9314de13c1f0b54510a2afa0cdc02c0e3f828fccfc4277734f9590b11a65f1 - md5: 6c72ec3e660a51736913ef6ea68c454b + build: hd03087b_2 + build_number: 2 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/atk-1.0-2.38.0-hd03087b_2.conda + sha256: b0747f9b1bc03d1932b4d8c586f39a35ac97e7e72fe6e63f2b2a2472d466f3c1 + md5: 57301986d02d30d6805fdce6c99074ee depends: - - libgcc-ng >=12 - - libglib >=2.74.1,<3.0a0 - - libstdcxx-ng >=12 + - __osx >=11.0 + - libcxx >=16 + - libglib >=2.80.0,<3.0a0 + - libintl >=0.22.5,<1.0a0 constrains: - atk-1.0 2.38.0 license: LGPL-2.0-or-later license_family: LGPL - size: 551928 - timestamp: 1667420962627 + size: 347530 + timestamp: 1713896411580 - kind: conda name: attr version: 2.5.1 @@ -4656,48 +4638,6 @@ packages: - pkg:pypi/attrs size: 54582 timestamp: 1704011393776 -- kind: conda - name: aws-c-auth - version: 0.7.17 - build: h382b9c6_2 - build_number: 2 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-auth-0.7.17-h382b9c6_2.conda - sha256: 50c87bf0fa68b5a6b9d2fbde5a17b1cf8c5f81ddbf659d78452de779598b1177 - md5: f38724f2e96212bf6c5c96861dc887f1 - depends: - - __osx >=11.0 - - aws-c-cal >=0.6.11,<0.6.12.0a0 - - aws-c-common >=0.9.15,<0.9.16.0a0 - - aws-c-http >=0.8.1,<0.8.2.0a0 - - aws-c-io >=0.14.7,<0.14.8.0a0 - - aws-c-sdkutils >=0.1.15,<0.1.16.0a0 - license: Apache-2.0 - license_family: Apache - size: 89585 - timestamp: 1712670760388 -- kind: conda - name: aws-c-auth - version: 0.7.17 - build: hb40cdec_2 - build_number: 2 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/aws-c-auth-0.7.17-hb40cdec_2.conda - sha256: 3a86263b08f8a454ebbc21ffa9f71a3daa86e32e2605e125878bec2d46147c32 - md5: 1d8527b98fbf4a803e92c2ee3d241ed8 - depends: - - aws-c-cal >=0.6.11,<0.6.12.0a0 - - aws-c-common >=0.9.15,<0.9.16.0a0 - - aws-c-http >=0.8.1,<0.8.2.0a0 - - aws-c-io >=0.14.7,<0.14.8.0a0 - - aws-c-sdkutils >=0.1.15,<0.1.16.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: Apache-2.0 - license_family: Apache - size: 100109 - timestamp: 1712671026674 - kind: conda name: aws-c-auth version: 0.7.17 @@ -4720,41 +4660,63 @@ packages: timestamp: 1712670722676 - kind: conda name: aws-c-auth - version: 0.7.17 - build: he0b1f16_2 - build_number: 2 + version: 0.7.20 + build: h5cf208e_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-auth-0.7.20-h5cf208e_0.conda + sha256: ca095f3d6678d3073b912722a53ac4489f2e78e79e7075731464b7be4210d458 + md5: 8b6134a6e4ab346a4f7c3aaeb90073c8 + depends: + - __osx >=11.0 + - aws-c-cal >=0.6.12,<0.6.13.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 + - aws-c-http >=0.8.1,<0.8.2.0a0 + - aws-c-io >=0.14.8,<0.14.9.0a0 + - aws-c-sdkutils >=0.1.16,<0.1.17.0a0 + license: Apache-2.0 + license_family: Apache + size: 91004 + timestamp: 1715287760264 +- kind: conda + name: aws-c-auth + version: 0.7.20 + build: h5f1c8d9_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.7.17-he0b1f16_2.conda - sha256: 607755dd09088b0d7898733edbe91aea979c599dc8d710b0d267b71424673032 - md5: ea6d998135d5f8932cffc91381104690 + url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-auth-0.7.20-h5f1c8d9_0.conda + sha256: 12f53171a2cb544a83be9866bf41f7a15aa7ff032d9f91ea6fd2ca4c34c84768 + md5: 418775183961dc1ee1c326a473118f98 depends: - - aws-c-cal >=0.6.11,<0.6.12.0a0 - - aws-c-common >=0.9.15,<0.9.16.0a0 + - aws-c-cal >=0.6.12,<0.6.13.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 - aws-c-http >=0.8.1,<0.8.2.0a0 - - aws-c-io >=0.14.7,<0.14.8.0a0 - - aws-c-sdkutils >=0.1.15,<0.1.16.0a0 + - aws-c-io >=0.14.8,<0.14.9.0a0 + - aws-c-sdkutils >=0.1.16,<0.1.17.0a0 - libgcc-ng >=12 license: Apache-2.0 license_family: Apache - size: 104450 - timestamp: 1712670541560 + size: 105856 + timestamp: 1715287622406 - kind: conda - name: aws-c-cal - version: 0.6.11 - build: ha21e00f_0 + name: aws-c-auth + version: 0.7.20 + build: h6823eb1_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/aws-c-cal-0.6.11-ha21e00f_0.conda - sha256: 3925aa37d9cbceb4cceb10ac1f602ca9e86bbea53ebbc2f560b97f51989c56bc - md5: 683d416db152019f181c34e74a3fd0a2 + url: https://conda.anaconda.org/conda-forge/win-64/aws-c-auth-0.7.20-h6823eb1_0.conda + sha256: 793d992fd896784263483d5428a3ec797f42ab6ce896fcb549e0a4b6c48540d4 + md5: bdb3ab44dcc47c12d640fc6c14888bc1 depends: - - aws-c-common >=0.9.15,<0.9.16.0a0 + - aws-c-cal >=0.6.12,<0.6.13.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 + - aws-c-http >=0.8.1,<0.8.2.0a0 + - aws-c-io >=0.14.8,<0.14.9.0a0 + - aws-c-sdkutils >=0.1.16,<0.1.17.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 license: Apache-2.0 license_family: Apache - size: 45832 - timestamp: 1712495134572 + size: 100860 + timestamp: 1715288041401 - kind: conda name: aws-c-cal version: 0.6.11 @@ -4771,34 +4733,52 @@ packages: timestamp: 1712495186044 - kind: conda name: aws-c-cal - version: 0.6.11 - build: hd34e5fa_0 + version: 0.6.12 + build: h2ba76a8_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.6.12-h2ba76a8_0.conda + sha256: 1aafd1dcbfefce4e4c78fc5301d24dbdcffc3dcaae41bf43fde326d1525c1869 + md5: da9257187c044a2a8f52507fea68a4c3 + depends: + - aws-c-common >=0.9.17,<0.9.18.0a0 + - libgcc-ng >=12 + - openssl >=3.2.1,<4.0a0 + license: Apache-2.0 + license_family: Apache + size: 46544 + timestamp: 1714177543437 +- kind: conda + name: aws-c-cal + version: 0.6.12 + build: h35c0bb2_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-cal-0.6.11-hd34e5fa_0.conda - sha256: 8296f9ad5415f6e640862116c4c3f4c1bc555ea05eab2ec32e112073cd697d79 - md5: 92d0e6abc836c1c00facbd08d3b01ce9 + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-cal-0.6.12-h35c0bb2_0.conda + sha256: 7ee38b2e1a74d9300a5daa3e5d8e3721da80cfd2b8c4d0fe7d245b6c0b005345 + md5: f3cafdf2cf60715acf0af9fcc6e314af depends: - - aws-c-common >=0.9.15,<0.9.16.0a0 + - __osx >=11.0 + - aws-c-common >=0.9.17,<0.9.18.0a0 license: Apache-2.0 license_family: Apache - size: 39697 - timestamp: 1712495118765 + size: 39878 + timestamp: 1714177800511 - kind: conda name: aws-c-cal - version: 0.6.11 - build: heb1d5e4_0 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-cal-0.6.11-heb1d5e4_0.conda - sha256: f1b40106a70cc294aab350daa97c760a9875073f58a5b7a25370c31fed8a2c15 - md5: 98784bb35b316e2ba8698f4a75326e9a + version: 0.6.12 + build: hc83774a_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/aws-c-cal-0.6.12-hc83774a_0.conda + sha256: 2b65433ffbcaf69649d238c2749794b81dd8e1c7d7baf832efe93f991ca0ed94 + md5: 4dcf49759f88c084396204addd0eb7b1 depends: - - aws-c-common >=0.9.15,<0.9.16.0a0 - - libgcc-ng >=12 - - openssl >=3.2.1,<4.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: Apache-2.0 license_family: Apache - size: 46257 - timestamp: 1712494861919 + size: 46200 + timestamp: 1714178039916 - kind: conda name: aws-c-common version: 0.9.15 @@ -4813,147 +4793,171 @@ packages: timestamp: 1712101871696 - kind: conda name: aws-c-common - version: 0.9.15 - build: h93a5062_0 + version: 0.9.17 + build: h03532ee_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-common-0.9.15-h93a5062_0.conda - sha256: ae4a47f032886a7175fe6e7ccbf1233cbe06bdfc747fc707afd83d2bdff43dff - md5: 4ca05bd64cc4decc54089fcd0cc69082 + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-common-0.9.17-h03532ee_0.conda + sha256: aa8320812d64a61d135eae8f14d3a33ee4a8be93d017af8f0f093818574321cc + md5: f6f9dddf7d48c6260eed53331bc368ca + depends: + - __osx >=11.0 license: Apache-2.0 license_family: Apache - size: 204504 - timestamp: 1712101989588 + size: 205818 + timestamp: 1713863980341 - kind: conda name: aws-c-common - version: 0.9.15 - build: hcfcfb64_0 + version: 0.9.17 + build: h2466b09_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/aws-c-common-0.9.15-hcfcfb64_0.conda - sha256: 038e4c01a81ac7807e9942009e2db88dea977754f4d2f35f822367132d9a8abf - md5: 6e02bac6dfcf279e2b0b2a3602d7b49b + url: https://conda.anaconda.org/conda-forge/win-64/aws-c-common-0.9.17-h2466b09_0.conda + sha256: c8e58a552ee66729f78bbdf78cfd1a9813ad5f7be2c5f7c460fa2f7c19031d33 + md5: 45f674089045f64c35d1ba0485842b99 depends: - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 license: Apache-2.0 license_family: Apache - size: 223866 - timestamp: 1712102088444 + size: 224504 + timestamp: 1713864277252 - kind: conda name: aws-c-common - version: 0.9.15 - build: hd590300_0 + version: 0.9.17 + build: h4ab18f5_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.9.15-hd590300_0.conda - sha256: e4251e5fa2656140628f40b74e61cf5048dfd4346f6d81517d346b371113496e - md5: ad8955a300fd09e97e76c38638ac7157 + url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-common-0.9.17-h4ab18f5_0.conda + sha256: e3a6fb2fd7079fc92022facbba5eae1b6d7d3ecd28f894bcde4cd3964280c3ee + md5: 97d60c6b52391872febd35fab0a30159 depends: - libgcc-ng >=12 license: Apache-2.0 license_family: Apache - size: 226559 - timestamp: 1712101677803 + size: 227784 + timestamp: 1713863751252 - kind: conda name: aws-c-compression version: 0.2.18 - build: h53e3db5_3 - build_number: 3 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/aws-c-compression-0.2.18-h53e3db5_3.conda - sha256: b35df886c7a8751fb5d1204510335241ddc9115fb4970c65ac12bbb307f6f8ad - md5: b4341460c51c457c6e5ac58d76f44d17 + build: h35c0bb2_4 + build_number: 4 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-compression-0.2.18-h35c0bb2_4.conda + sha256: 9ac120311a289b84f63b5c9b612595d088ee53fcdea6830d8a37b4f9797c0294 + md5: 175f51c07a9a003b2d88234888dc2aa1 depends: - - aws-c-common >=0.9.15,<0.9.16.0a0 + - __osx >=11.0 + - aws-c-common >=0.9.17,<0.9.18.0a0 license: Apache-2.0 license_family: Apache - size: 17976 - timestamp: 1712138779036 + size: 18096 + timestamp: 1714044195309 - kind: conda name: aws-c-compression version: 0.2.18 - build: ha21e00f_3 - build_number: 3 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/aws-c-compression-0.2.18-ha21e00f_3.conda - sha256: c0e05c48a2420bf1e192ba61d9f41fad075186fa12f9018fef4a52f31883f0ee - md5: 15ff0ff5c09bd7c0c6dea51e5ef427b4 + build: h36a0aea_4 + build_number: 4 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.2.18-h36a0aea_4.conda + sha256: 7f16b562f9644e5dbc66082886d303601e9fb993dc1cf556ad4517bdf87f30aa + md5: ce9d15eeabc21f9936410382e20c2908 depends: - - aws-c-common >=0.9.15,<0.9.16.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - aws-c-common >=0.9.17,<0.9.18.0a0 + - libgcc-ng >=12 license: Apache-2.0 license_family: Apache - size: 22479 - timestamp: 1712139181716 + size: 19189 + timestamp: 1714043806611 - kind: conda name: aws-c-compression version: 0.2.18 - build: hce8ee76_3 + build: h53e3db5_3 build_number: 3 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-compression-0.2.18-hce8ee76_3.conda - sha256: ab0617f2d66d5d88fc6c7edb6ecd4589e0a744ccaeff95765371c9cabdb29722 - md5: b19224a5179ecb512c4aac9f8a6d57a7 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/aws-c-compression-0.2.18-h53e3db5_3.conda + sha256: b35df886c7a8751fb5d1204510335241ddc9115fb4970c65ac12bbb307f6f8ad + md5: b4341460c51c457c6e5ac58d76f44d17 depends: - aws-c-common >=0.9.15,<0.9.16.0a0 - - libgcc-ng >=12 license: Apache-2.0 license_family: Apache - size: 19134 - timestamp: 1712138634166 + size: 17976 + timestamp: 1712138779036 - kind: conda name: aws-c-compression version: 0.2.18 - build: hd34e5fa_3 - build_number: 3 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-compression-0.2.18-hd34e5fa_3.conda - sha256: c501b4f00d1518956aa3fb45378e0dacdec941cca5d78e8d8ba07b46674fa877 - md5: 194b36e2ac364c12c7fa89e84391722d + build: hc83774a_4 + build_number: 4 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/aws-c-compression-0.2.18-hc83774a_4.conda + sha256: 7084083b98b4f40542374d6f2b8cb36c40c22cd49a1f4df1da9c9e1278e768de + md5: a9c2159343eb5cd1b62589f209b1e623 depends: - - aws-c-common >=0.9.15,<0.9.16.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: Apache-2.0 license_family: Apache - size: 18089 - timestamp: 1712138821785 + size: 22670 + timestamp: 1714044311775 - kind: conda name: aws-c-event-stream version: 0.4.2 - build: h01f5eca_8 - build_number: 8 + build: h161de36_10 + build_number: 10 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.4.2-h01f5eca_8.conda - sha256: 688b81ed93151868df2717556d3b93dcfaf6bf129a1474f14e0c993095816d3f - md5: afb85fc0f01032d115c57c961950e7d8 + url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-event-stream-0.4.2-h161de36_10.conda + sha256: 31877ce699b8dfc8bad3bb82d908e9b3f3788af6ba6ab3fb141ad673c8d191d2 + md5: a7a334cb2d24e31a9bf0e7e3d01b14cb depends: - - aws-c-common >=0.9.15,<0.9.16.0a0 - - aws-c-io >=0.14.7,<0.14.8.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 + - aws-c-io >=0.14.8,<0.14.9.0a0 - aws-checksums >=0.1.18,<0.1.19.0a0 - libgcc-ng >=12 - libstdcxx-ng >=12 license: Apache-2.0 license_family: Apache - size: 53700 - timestamp: 1712507243610 + size: 53763 + timestamp: 1715026272209 - kind: conda name: aws-c-event-stream version: 0.4.2 - build: h247c08a_8 - build_number: 8 + build: h7d5773a_10 + build_number: 10 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-event-stream-0.4.2-h247c08a_8.conda - sha256: f4a8ee85ed51793bdfaa5ff863db5fa02eb1935e25857109b8650af2c66f46c5 - md5: 47912c9d76ebf3146dc5c5358fe94a97 + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-event-stream-0.4.2-h7d5773a_10.conda + sha256: c957e08847be2356dabea00f9f29a35bee51c8f3435812b9ffacad5c17b57586 + md5: 117c8e1a963c44316e3eed40592ff580 depends: - - aws-c-common >=0.9.15,<0.9.16.0a0 - - aws-c-io >=0.14.7,<0.14.8.0a0 + - __osx >=11.0 + - aws-c-common >=0.9.17,<0.9.18.0a0 + - aws-c-io >=0.14.8,<0.14.9.0a0 - aws-checksums >=0.1.18,<0.1.19.0a0 - libcxx >=16 license: Apache-2.0 license_family: Apache - size: 46788 - timestamp: 1712507379999 + size: 46956 + timestamp: 1715026300336 +- kind: conda + name: aws-c-event-stream + version: 0.4.2 + build: hc6c0aac_10 + build_number: 10 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/aws-c-event-stream-0.4.2-hc6c0aac_10.conda + sha256: de0e11d8690d8430b33213fed285c0872314f4c95b85b59ac7cd4b9b5c12cb78 + md5: 154013fe21be2e4f6206b894537a95a3 + depends: + - aws-c-common >=0.9.17,<0.9.18.0a0 + - aws-c-io >=0.14.8,<0.14.9.0a0 + - aws-checksums >=0.1.18,<0.1.19.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: Apache-2.0 + license_family: Apache + size: 54934 + timestamp: 1715026670796 - kind: conda name: aws-c-event-stream version: 0.4.2 @@ -4973,25 +4977,24 @@ packages: size: 46574 timestamp: 1712507348124 - kind: conda - name: aws-c-event-stream - version: 0.4.2 - build: hf668b60_8 - build_number: 8 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/aws-c-event-stream-0.4.2-hf668b60_8.conda - sha256: cc2b8b8338b51b1c05827532e22902005fb68cbb7c85b3e8c6917531721923cd - md5: 61ff0e83fdad92ccf13812b54c447507 + name: aws-c-http + version: 0.8.1 + build: h00faecf_13 + build_number: 13 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-http-0.8.1-h00faecf_13.conda + sha256: f47540726b8c7b8d5d7e28d1e64731d1a22b35ec079a8f982740e7ec823ae1b0 + md5: 3ee817ca3693f0a3e05b5605939404a9 depends: - - aws-c-common >=0.9.15,<0.9.16.0a0 - - aws-c-io >=0.14.7,<0.14.8.0a0 - - aws-checksums >=0.1.18,<0.1.19.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - __osx >=11.0 + - aws-c-cal >=0.6.12,<0.6.13.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 + - aws-c-compression >=0.2.18,<0.2.19.0a0 + - aws-c-io >=0.14.8,<0.14.9.0a0 license: Apache-2.0 license_family: Apache - size: 54179 - timestamp: 1712507805607 + size: 151560 + timestamp: 1715026356984 - kind: conda name: aws-c-http version: 0.8.1 @@ -5014,211 +5017,185 @@ packages: - kind: conda name: aws-c-http version: 0.8.1 - build: hd704247_10 - build_number: 10 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/aws-c-http-0.8.1-hd704247_10.conda - sha256: 8a869b0f15bd85eb46b4faa14cadb691d756f8a74279edede1d769fea62d0acc - md5: 6abc1e3bdf18f682c7f42a08669b5662 + build: h63f54a0_13 + build_number: 13 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.8.1-h63f54a0_13.conda + sha256: 679f62ea3e7cca58c8068f2770440636e79c645554e4c7ff52036567a755a5d2 + md5: dd5266145d7b778c9e9a0508a503e564 depends: - - aws-c-cal >=0.6.11,<0.6.12.0a0 - - aws-c-common >=0.9.15,<0.9.16.0a0 + - aws-c-cal >=0.6.12,<0.6.13.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 - aws-c-compression >=0.2.18,<0.2.19.0a0 - - aws-c-io >=0.14.7,<0.14.8.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc >=14.3,<15 - - vc14_runtime >=14.29.30139 - - vc14_runtime >=14.38.33130 + - aws-c-io >=0.14.8,<0.14.9.0a0 + - libgcc-ng >=12 license: Apache-2.0 license_family: Apache - size: 180594 - timestamp: 1712655088873 + size: 195229 + timestamp: 1715026240632 - kind: conda name: aws-c-http version: 0.8.1 - build: hdb68c23_10 - build_number: 10 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-http-0.8.1-hdb68c23_10.conda - sha256: a13e77f6b40de79b33711f70b8180943053cc162efdb357bc9cd577f0ac69818 - md5: cb6065938167da2d2f078c2f08473b84 + build: hced5053_13 + build_number: 13 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/aws-c-http-0.8.1-hced5053_13.conda + sha256: ceb7941ae41e11fc287af579261eaca539cc22fcac641aa0ebd254c23aee8c64 + md5: 4bf3b37a30279d31584e3efb0ab2c722 depends: - - aws-c-cal >=0.6.11,<0.6.12.0a0 - - aws-c-common >=0.9.15,<0.9.16.0a0 + - aws-c-cal >=0.6.12,<0.6.13.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 - aws-c-compression >=0.2.18,<0.2.19.0a0 - - aws-c-io >=0.14.7,<0.14.8.0a0 - - libgcc-ng >=12 + - aws-c-io >=0.14.8,<0.14.9.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: Apache-2.0 license_family: Apache - size: 195362 - timestamp: 1712654535499 -- kind: conda - name: aws-c-http - version: 0.8.1 - build: hf9e830b_10 - build_number: 10 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-http-0.8.1-hf9e830b_10.conda - sha256: 6c06720a8700f65e68ad740b5dd0e559242f62a179067c029792d226b3b065fc - md5: 532e961f28b3c8fcdcb0ecb1e017961d - depends: - - __osx >=11.0 - - aws-c-cal >=0.6.11,<0.6.12.0a0 - - aws-c-common >=0.9.15,<0.9.16.0a0 - - aws-c-compression >=0.2.18,<0.2.19.0a0 - - aws-c-io >=0.14.7,<0.14.8.0a0 - license: Apache-2.0 - license_family: Apache - size: 151666 - timestamp: 1712654734379 + size: 181269 + timestamp: 1715026840322 - kind: conda name: aws-c-io version: 0.14.7 - build: h14865c8_6 + build: h6254544_6 build_number: 6 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/aws-c-io-0.14.7-h14865c8_6.conda - sha256: 63046d2b42b5d7fb94fa90a261c1dbef729b458e5a2465ea8dbb74959baca0f0 - md5: e26a1f9f7170b5e683b22a6a7e95d945 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/aws-c-io-0.14.7-h6254544_6.conda + sha256: 5d2327f3742cfabd53bf8c935eb2cffd50e3ea8c03c9fee12940b2ffb94ad1cb + md5: 9c997fbd219f8db5714dbdc240e355a0 depends: + - __osx >=10.9 - aws-c-cal >=0.6.11,<0.6.12.0a0 - aws-c-common >=0.9.15,<0.9.16.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 license: Apache-2.0 license_family: Apache - size: 159681 - timestamp: 1713347479651 + size: 137495 + timestamp: 1713347345969 - kind: conda name: aws-c-io - version: 0.14.7 - build: h33d81b3_6 - build_number: 6 + version: 0.14.8 + build: h6dd71cf_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-io-0.14.7-h33d81b3_6.conda - sha256: a93a3e23c0407cbfaa9807784a32c96a00fea32b2d015f0be59c0cb79cc4aaa5 - md5: def574dc950fa350d49db8438ca5d1af + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-io-0.14.8-h6dd71cf_0.conda + sha256: 949742437538cc0db5da9e21c92ccb3c32a1426980523412e5cbf6ec1990c073 + md5: 50142d1519ed7fb7bbe588084deab2ae depends: - __osx >=11.0 - - aws-c-cal >=0.6.11,<0.6.12.0a0 - - aws-c-common >=0.9.15,<0.9.16.0a0 + - aws-c-cal >=0.6.12,<0.6.13.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 license: Apache-2.0 license_family: Apache - size: 137603 - timestamp: 1713347142779 + size: 138046 + timestamp: 1714868179631 - kind: conda name: aws-c-io - version: 0.14.7 - build: h6254544_6 - build_number: 6 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/aws-c-io-0.14.7-h6254544_6.conda - sha256: 5d2327f3742cfabd53bf8c935eb2cffd50e3ea8c03c9fee12940b2ffb94ad1cb - md5: 9c997fbd219f8db5714dbdc240e355a0 + version: 0.14.8 + build: h96d4d28_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.14.8-h96d4d28_0.conda + sha256: 70fba744853744151087d0bfe5cd65bdc08089cf713b6b83bf81f878c51ab1b6 + md5: 417d99cf69a0e6f40251815ca7622273 depends: - - __osx >=10.9 - - aws-c-cal >=0.6.11,<0.6.12.0a0 - - aws-c-common >=0.9.15,<0.9.16.0a0 + - aws-c-cal >=0.6.12,<0.6.13.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 + - libgcc-ng >=12 + - s2n >=1.4.13,<1.4.14.0a0 license: Apache-2.0 license_family: Apache - size: 137495 - timestamp: 1713347345969 + size: 157952 + timestamp: 1714867798089 - kind: conda name: aws-c-io - version: 0.14.7 - build: hbfbeace_6 - build_number: 6 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-io-0.14.7-hbfbeace_6.conda - sha256: 10c8df9b71be8aba9b1aad48b123fc81896eb7b73c686042bed4a9e77d92e812 - md5: d6382461de9a91a2665e964f92d8da0a + version: 0.14.8 + build: hebaacdb_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/aws-c-io-0.14.8-hebaacdb_0.conda + sha256: 89eb826f187901450b4ebb731ad995f71fa317dc417b31ed621b5e16a0f86b94 + md5: e421ac978195e777aae02059bc129479 depends: - - aws-c-cal >=0.6.11,<0.6.12.0a0 - - aws-c-common >=0.9.15,<0.9.16.0a0 - - libgcc-ng >=12 - - s2n >=1.4.12,<1.4.13.0a0 + - aws-c-cal >=0.6.12,<0.6.13.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: Apache-2.0 license_family: Apache - size: 158124 - timestamp: 1713346977725 + size: 159899 + timestamp: 1714868367395 - kind: conda name: aws-c-mqtt version: 0.10.3 - build: h50844eb_4 + build: hd66502f_4 build_number: 4 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.10.3-h50844eb_4.conda - sha256: e80a6cea0a3d954cdb63b49d80a62f1982bb13722c0c99ba83b15820e61d4760 - md5: e72fdd8942f266ea79c70ec085661d6c + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/aws-c-mqtt-0.10.3-hd66502f_4.conda + sha256: 7c1f640276ad3be6095bf12c1debecde3458321d18eedca40daec6d0036ef0f9 + md5: 89e656a48d3c1e094366648d33320ff0 depends: + - __osx >=10.9 - aws-c-common >=0.9.15,<0.9.16.0a0 - aws-c-http >=0.8.1,<0.8.2.0a0 - aws-c-io >=0.14.7,<0.14.8.0a0 - - libgcc-ng >=12 license: Apache-2.0 license_family: Apache - size: 163794 - timestamp: 1712547607752 + size: 139268 + timestamp: 1712547737430 - kind: conda name: aws-c-mqtt - version: 0.10.3 - build: h5f4abda_4 - build_number: 4 + version: 0.10.4 + build: h92d7a41_2 + build_number: 2 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-mqtt-0.10.3-h5f4abda_4.conda - sha256: ee1296c91f1624a67199b4885f79d3123a9bbc5b7def6de056f0d8c1c4525d0d - md5: 49dfa5667f57d5a7f9716ff06f80d28f + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-mqtt-0.10.4-h92d7a41_2.conda + sha256: 81437ee8a65a445bec24df4cd584cb9e3d24f48cfa1a03e05f170fe125f96544 + md5: 128936f3f7c991bd9e112af42d1f9c30 depends: - __osx >=11.0 - - aws-c-common >=0.9.15,<0.9.16.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 - aws-c-http >=0.8.1,<0.8.2.0a0 - - aws-c-io >=0.14.7,<0.14.8.0a0 + - aws-c-io >=0.14.8,<0.14.9.0a0 license: Apache-2.0 license_family: Apache - size: 118034 - timestamp: 1712547383899 + size: 118084 + timestamp: 1715057770501 - kind: conda name: aws-c-mqtt - version: 0.10.3 - build: h748201e_4 - build_number: 4 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/aws-c-mqtt-0.10.3-h748201e_4.conda - sha256: eeec7e222cb8ecf0df2e5d5c17a511ba8b16af22b12bdf6d6a9540b6e6aeb3bd - md5: 235f22fb6ae78c9807273f7726021465 + version: 0.10.4 + build: hcc7299c_2 + build_number: 2 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-mqtt-0.10.4-hcc7299c_2.conda + sha256: fcb732bc33d0aeead35a10eb7ee76494bfc68dcd06c9299e9c381c6e9e93ff7b + md5: 7003778c651fa3ba815cfdf065d769af depends: - - aws-c-common >=0.9.15,<0.9.16.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 - aws-c-http >=0.8.1,<0.8.2.0a0 - - aws-c-io >=0.14.7,<0.14.8.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc >=14.3,<15 - - vc14_runtime >=14.29.30139 - - vc14_runtime >=14.38.33130 + - aws-c-io >=0.14.8,<0.14.9.0a0 + - libgcc-ng >=12 license: Apache-2.0 license_family: Apache - size: 158520 - timestamp: 1712547856285 + size: 164142 + timestamp: 1715057917794 - kind: conda name: aws-c-mqtt - version: 0.10.3 - build: hd66502f_4 - build_number: 4 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/aws-c-mqtt-0.10.3-hd66502f_4.conda - sha256: 7c1f640276ad3be6095bf12c1debecde3458321d18eedca40daec6d0036ef0f9 - md5: 89e656a48d3c1e094366648d33320ff0 + version: 0.10.4 + build: hdafd9a4_2 + build_number: 2 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/aws-c-mqtt-0.10.4-hdafd9a4_2.conda + sha256: e4d358f85bce410f4b06b4e60d5aa477b141c9d4ee70f8309aa2ed59cde8d299 + md5: 6d3ac34a5145d83e007eeda33b45fdba depends: - - __osx >=10.9 - - aws-c-common >=0.9.15,<0.9.16.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 - aws-c-http >=0.8.1,<0.8.2.0a0 - - aws-c-io >=0.14.7,<0.14.8.0a0 + - aws-c-io >=0.14.8,<0.14.9.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: Apache-2.0 license_family: Apache - size: 139268 - timestamp: 1712547737430 + size: 158222 + timestamp: 1715058316429 - kind: conda name: aws-c-s3 version: 0.5.7 @@ -5242,70 +5219,67 @@ packages: timestamp: 1712685831186 - kind: conda name: aws-c-s3 - version: 0.5.7 - build: h5da7064_1 - build_number: 1 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/aws-c-s3-0.5.7-h5da7064_1.conda - sha256: 0da7ee2d40bd6ed559a4aa52430dd71c8abde10c193f7ea8799a221cb1ceeef0 - md5: 4b80f4d4191132572fe83b622442918a + version: 0.5.9 + build: h10bd90f_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.5.9-h10bd90f_0.conda + sha256: f7e0101a3e629e55d2afc6265c25e8f7dc207119eaed860c682afa2cdd083c1f + md5: 5cd6a7eb8c0e45be0e49a9c6351ff42b depends: - - aws-c-auth >=0.7.17,<0.7.18.0a0 - - aws-c-cal >=0.6.11,<0.6.12.0a0 - - aws-c-common >=0.9.15,<0.9.16.0a0 + - aws-c-auth >=0.7.20,<0.7.21.0a0 + - aws-c-cal >=0.6.12,<0.6.13.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 - aws-c-http >=0.8.1,<0.8.2.0a0 - - aws-c-io >=0.14.7,<0.14.8.0a0 + - aws-c-io >=0.14.8,<0.14.9.0a0 - aws-checksums >=0.1.18,<0.1.19.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - libgcc-ng >=12 + - openssl >=3.3.0,<4.0a0 license: Apache-2.0 license_family: Apache - size: 104398 - timestamp: 1712686192455 + size: 109841 + timestamp: 1715619697604 - kind: conda name: aws-c-s3 - version: 0.5.7 - build: h606a3d2_1 - build_number: 1 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-s3-0.5.7-h606a3d2_1.conda - sha256: 7365e76ad87e39bf58eea10515001007e275bbd270981f3a1641c840f052017a - md5: 9bd413b520a8768af02e3a5810e9a42a + version: 0.5.9 + build: h7a83f0e_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/aws-c-s3-0.5.9-h7a83f0e_0.conda + sha256: dc43a11f938365792455dfe2b2d26194dfaa4c3367967ab156f2af8666923012 + md5: 1fcee9f1b1ffa9ef65a3c54330b73f0e depends: - - __osx >=11.0 - - aws-c-auth >=0.7.17,<0.7.18.0a0 - - aws-c-cal >=0.6.11,<0.6.12.0a0 - - aws-c-common >=0.9.15,<0.9.16.0a0 + - aws-c-auth >=0.7.20,<0.7.21.0a0 + - aws-c-cal >=0.6.12,<0.6.13.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 - aws-c-http >=0.8.1,<0.8.2.0a0 - - aws-c-io >=0.14.7,<0.14.8.0a0 + - aws-c-io >=0.14.8,<0.14.9.0a0 - aws-checksums >=0.1.18,<0.1.19.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: Apache-2.0 license_family: Apache - size: 93368 - timestamp: 1712686042460 + size: 105667 + timestamp: 1715620221686 - kind: conda name: aws-c-s3 - version: 0.5.7 - build: hb7bd14b_1 - build_number: 1 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-s3-0.5.7-hb7bd14b_1.conda - sha256: 94e2d5174ba344357801a44c303f513ae40f37c2defcc3d3747809ac11be1e27 - md5: 82bd3d7da86d969c62ff541bab19526a + version: 0.5.9 + build: he1e208d_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-s3-0.5.9-he1e208d_0.conda + sha256: c5f113e37c670982abc0a6e1b000186e4c94a6838d2a283dce6726ca92a882d0 + md5: 64f5167f45ce390443e4e80ff37671c6 depends: - - aws-c-auth >=0.7.17,<0.7.18.0a0 - - aws-c-cal >=0.6.11,<0.6.12.0a0 - - aws-c-common >=0.9.15,<0.9.16.0a0 + - __osx >=11.0 + - aws-c-auth >=0.7.20,<0.7.21.0a0 + - aws-c-cal >=0.6.12,<0.6.13.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 - aws-c-http >=0.8.1,<0.8.2.0a0 - - aws-c-io >=0.14.7,<0.14.8.0a0 + - aws-c-io >=0.14.8,<0.14.9.0a0 - aws-checksums >=0.1.18,<0.1.19.0a0 - - libgcc-ng >=12 - - openssl >=3.2.1,<4.0a0 license: Apache-2.0 license_family: Apache - size: 108249 - timestamp: 1712685968385 + size: 94038 + timestamp: 1715619886520 - kind: conda name: aws-c-sdkutils version: 0.1.15 @@ -5323,128 +5297,127 @@ packages: timestamp: 1712146120263 - kind: conda name: aws-c-sdkutils - version: 0.1.15 - build: ha21e00f_3 - build_number: 3 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/aws-c-sdkutils-0.1.15-ha21e00f_3.conda - sha256: 1c72977356cbac9e805c0325692628edf4d30c3bb09fbe5ddd91d709f410bcc5 - md5: 7b10fea2a5418a3ad31507a8e3019019 + version: 0.1.16 + build: h35c0bb2_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-sdkutils-0.1.16-h35c0bb2_0.conda + sha256: 152df9a5014a27bb33ecba29ce996cfb51e1b6ee825be40d052125f766efbb18 + md5: 75bc7553b500d2edc8f5eed68d04d981 depends: - - aws-c-common >=0.9.15,<0.9.16.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - __osx >=11.0 + - aws-c-common >=0.9.17,<0.9.18.0a0 license: Apache-2.0 license_family: Apache - size: 53883 - timestamp: 1712146320267 + size: 48666 + timestamp: 1714208582795 - kind: conda name: aws-c-sdkutils - version: 0.1.15 - build: hce8ee76_3 - build_number: 3 + version: 0.1.16 + build: h36a0aea_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.1.15-hce8ee76_3.conda - sha256: 72fd73a5de0730997a36bf20ac1cb8cf7c67e40225c280b3dc5e46bc61c7d157 - md5: 0c4f0205a1ae4ca6c89af922ec54271c + url: https://conda.anaconda.org/conda-forge/linux-64/aws-c-sdkutils-0.1.16-h36a0aea_0.conda + sha256: 214fe6443dcd092287f739af2f9bc1d06e20014515363b3569fd4c74144f6a9d + md5: 2555c5ffa3a60fde5a940c5c9f4327cc depends: - - aws-c-common >=0.9.15,<0.9.16.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 - libgcc-ng >=12 license: Apache-2.0 license_family: Apache - size: 55146 - timestamp: 1712145768196 + size: 54920 + timestamp: 1714208472161 - kind: conda name: aws-c-sdkutils - version: 0.1.15 - build: hd34e5fa_3 - build_number: 3 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-c-sdkutils-0.1.15-hd34e5fa_3.conda - sha256: e128818c57f6273df6dc64d7c3868eb179011766d790a8a93ad152fa26be4b9d - md5: d4afb2c3ed05bf792183ffdbc723aaeb + version: 0.1.16 + build: hc83774a_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/aws-c-sdkutils-0.1.16-hc83774a_0.conda + sha256: 79d6542d6896d7d3f94d8f457924a241193bb2a8399ff929e544f774337238eb + md5: 3bdb282923a48cdd48233212a596bdae depends: - - aws-c-common >=0.9.15,<0.9.16.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: Apache-2.0 license_family: Apache - size: 49627 - timestamp: 1712146003862 + size: 53570 + timestamp: 1714208897748 - kind: conda name: aws-checksums version: 0.1.18 - build: h53e3db5_3 - build_number: 3 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/aws-checksums-0.1.18-h53e3db5_3.conda - sha256: b62bcee0d6accf5b9e790cdb6171678ac6c865acc9df46249f36e554654f218b - md5: 2e78e8a3675a597ff8deaf118c7b714b + build: h35c0bb2_4 + build_number: 4 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-checksums-0.1.18-h35c0bb2_4.conda + sha256: 3b7320a5b17d3d7dcf816e60f19122635219c4e1be4dd53cf9ae454b9ed2422d + md5: f0177671ec47f34998666eeb7cd227f9 depends: - - aws-c-common >=0.9.15,<0.9.16.0a0 + - __osx >=11.0 + - aws-c-common >=0.9.17,<0.9.18.0a0 license: Apache-2.0 license_family: Apache - size: 48730 - timestamp: 1712146097053 + size: 49223 + timestamp: 1714051341844 - kind: conda name: aws-checksums version: 0.1.18 - build: ha21e00f_3 - build_number: 3 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/aws-checksums-0.1.18-ha21e00f_3.conda - sha256: c7759b8b3c163916ab47ae0f65549ce7c4e78d54bf9daadd5fa035b4b04500bb - md5: a593ee36f55e9af14d7a7f9f8f854fcc + build: h36a0aea_4 + build_number: 4 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.1.18-h36a0aea_4.conda + sha256: 224ead1679870e28005bfa7d27e8dd702f09837005610c6b06c52a95641da30b + md5: bd99b76853edcc6fae6a901900bba995 depends: - - aws-c-common >=0.9.15,<0.9.16.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - aws-c-common >=0.9.17,<0.9.18.0a0 + - libgcc-ng >=12 license: Apache-2.0 license_family: Apache - size: 52267 - timestamp: 1712145968515 + size: 50174 + timestamp: 1714050863900 - kind: conda name: aws-checksums version: 0.1.18 - build: hce8ee76_3 + build: h53e3db5_3 build_number: 3 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/aws-checksums-0.1.18-hce8ee76_3.conda - sha256: de0ba47fc8feaaa087d9128e4b5402af72bd46af52b885dee87adfb9e285a816 - md5: 9aa734a17b9b0b793c7696435fe7789a + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/aws-checksums-0.1.18-h53e3db5_3.conda + sha256: b62bcee0d6accf5b9e790cdb6171678ac6c865acc9df46249f36e554654f218b + md5: 2e78e8a3675a597ff8deaf118c7b714b depends: - aws-c-common >=0.9.15,<0.9.16.0a0 - - libgcc-ng >=12 license: Apache-2.0 license_family: Apache - size: 50068 - timestamp: 1712145648515 + size: 48730 + timestamp: 1712146097053 - kind: conda name: aws-checksums version: 0.1.18 - build: hd34e5fa_3 - build_number: 3 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-checksums-0.1.18-hd34e5fa_3.conda - sha256: d91ba44e14b31c5fe13fd78a567fc6cf76c62ad8bfaba250e317b354a75c64dd - md5: 69f9b2281805ff1e0c87962d74de1360 + build: hc83774a_4 + build_number: 4 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/aws-checksums-0.1.18-hc83774a_4.conda + sha256: 401aa17135aea3af343e7d4730c2ea878bee3da72824850423168549667d3008 + md5: 197196903f52fbd3e55a26b1e30561a6 depends: - - aws-c-common >=0.9.15,<0.9.16.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: Apache-2.0 license_family: Apache - size: 48999 - timestamp: 1712145929885 + size: 52400 + timestamp: 1714051200378 - kind: conda name: aws-crt-cpp version: 0.26.6 - build: h13f0230_4 + build: hfb53d2e_4 build_number: 4 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-crt-cpp-0.26.6-h13f0230_4.conda - sha256: abf4618412f03fad2f3a1d4dd15200237afce54e1d1eff5eb17f834aa7acd32d - md5: 4e2b2d2f1ae778ed49d542974403fb60 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/aws-crt-cpp-0.26.6-hfb53d2e_4.conda + sha256: bcb8587d5c1689009badefc13320ba161479aab9affa8d205583059dabe576bd + md5: a4491c9681a6bf71a226c544990c9112 depends: - - __osx >=11.0 + - __osx >=10.9 - aws-c-auth >=0.7.17,<0.7.18.0a0 - aws-c-cal >=0.6.11,<0.6.12.0a0 - aws-c-common >=0.9.15,<0.9.16.0a0 @@ -5457,84 +5430,84 @@ packages: - libcxx >=16 license: Apache-2.0 license_family: Apache - size: 220730 - timestamp: 1712752845989 + size: 283365 + timestamp: 1712752909519 - kind: conda name: aws-crt-cpp - version: 0.26.6 - build: h5bc0ceb_4 - build_number: 4 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/aws-crt-cpp-0.26.6-h5bc0ceb_4.conda - sha256: 901ec0e31aa75ae80935a051a1387f55e2b3e0e4a97b31635b88310505e4afa2 - md5: 056f3eaae2910ed8aca0f17cb2378f6f + version: 0.26.8 + build: h4f3a3cc_11 + build_number: 11 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.26.8-h4f3a3cc_11.conda + sha256: 3fc936c26ca513608977320aba42adbe8d6eaeabdf153076537f60fdcc6dd93d + md5: 09c816a52369923fb5e37823556b1eb7 depends: - - aws-c-auth >=0.7.17,<0.7.18.0a0 - - aws-c-cal >=0.6.11,<0.6.12.0a0 - - aws-c-common >=0.9.15,<0.9.16.0a0 + - aws-c-auth >=0.7.20,<0.7.21.0a0 + - aws-c-cal >=0.6.12,<0.6.13.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 - aws-c-event-stream >=0.4.2,<0.4.3.0a0 - aws-c-http >=0.8.1,<0.8.2.0a0 - - aws-c-io >=0.14.7,<0.14.8.0a0 - - aws-c-mqtt >=0.10.3,<0.10.4.0a0 - - aws-c-s3 >=0.5.7,<0.5.8.0a0 - - aws-c-sdkutils >=0.1.15,<0.1.16.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - aws-c-io >=0.14.8,<0.14.9.0a0 + - aws-c-mqtt >=0.10.4,<0.10.5.0a0 + - aws-c-s3 >=0.5.9,<0.5.10.0a0 + - aws-c-sdkutils >=0.1.16,<0.1.17.0a0 + - libgcc-ng >=12 + - libstdcxx-ng >=12 license: Apache-2.0 license_family: Apache - size: 246123 - timestamp: 1712753024280 + size: 340309 + timestamp: 1716300886925 - kind: conda name: aws-crt-cpp - version: 0.26.6 - build: hf567797_4 - build_number: 4 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/aws-crt-cpp-0.26.6-hf567797_4.conda - sha256: 45007f9367f9f41185a5b274a1dc6c44ceae9fb0a4e44eae3542deaab53559fb - md5: ffb662b31aef333e68a00dd17fda2027 + version: 0.26.8 + build: h5cd1ed2_11 + build_number: 11 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-crt-cpp-0.26.8-h5cd1ed2_11.conda + sha256: 54bb963190ab67c28fc15fc9bcdd2650487d0184ffed29154c293ba073d1c4b8 + md5: cceb6e6316256f11d2b975bb4e00dd9d depends: - - aws-c-auth >=0.7.17,<0.7.18.0a0 - - aws-c-cal >=0.6.11,<0.6.12.0a0 - - aws-c-common >=0.9.15,<0.9.16.0a0 + - __osx >=11.0 + - aws-c-auth >=0.7.20,<0.7.21.0a0 + - aws-c-cal >=0.6.12,<0.6.13.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 - aws-c-event-stream >=0.4.2,<0.4.3.0a0 - aws-c-http >=0.8.1,<0.8.2.0a0 - - aws-c-io >=0.14.7,<0.14.8.0a0 - - aws-c-mqtt >=0.10.3,<0.10.4.0a0 - - aws-c-s3 >=0.5.7,<0.5.8.0a0 - - aws-c-sdkutils >=0.1.15,<0.1.16.0a0 - - libgcc-ng >=12 - - libstdcxx-ng >=12 + - aws-c-io >=0.14.8,<0.14.9.0a0 + - aws-c-mqtt >=0.10.4,<0.10.5.0a0 + - aws-c-s3 >=0.5.9,<0.5.10.0a0 + - aws-c-sdkutils >=0.1.16,<0.1.17.0a0 + - libcxx >=16 license: Apache-2.0 license_family: Apache - size: 335145 - timestamp: 1712752545390 + size: 224367 + timestamp: 1716301212739 - kind: conda name: aws-crt-cpp - version: 0.26.6 - build: hfb53d2e_4 - build_number: 4 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/aws-crt-cpp-0.26.6-hfb53d2e_4.conda - sha256: bcb8587d5c1689009badefc13320ba161479aab9affa8d205583059dabe576bd - md5: a4491c9681a6bf71a226c544990c9112 + version: 0.26.8 + build: h672a689_11 + build_number: 11 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/aws-crt-cpp-0.26.8-h672a689_11.conda + sha256: 1f0c33aa118591a4454afb202e6bbfaec956a2e46f54298f242ab0221682fc40 + md5: 13436e11b88d0574524de9e3f3330332 depends: - - __osx >=10.9 - - aws-c-auth >=0.7.17,<0.7.18.0a0 - - aws-c-cal >=0.6.11,<0.6.12.0a0 - - aws-c-common >=0.9.15,<0.9.16.0a0 + - aws-c-auth >=0.7.20,<0.7.21.0a0 + - aws-c-cal >=0.6.12,<0.6.13.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 - aws-c-event-stream >=0.4.2,<0.4.3.0a0 - aws-c-http >=0.8.1,<0.8.2.0a0 - - aws-c-io >=0.14.7,<0.14.8.0a0 - - aws-c-mqtt >=0.10.3,<0.10.4.0a0 - - aws-c-s3 >=0.5.7,<0.5.8.0a0 - - aws-c-sdkutils >=0.1.15,<0.1.16.0a0 - - libcxx >=16 + - aws-c-io >=0.14.8,<0.14.9.0a0 + - aws-c-mqtt >=0.10.4,<0.10.5.0a0 + - aws-c-s3 >=0.5.9,<0.5.10.0a0 + - aws-c-sdkutils >=0.1.16,<0.1.17.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: Apache-2.0 license_family: Apache - size: 283365 - timestamp: 1712752909519 + size: 248588 + timestamp: 1716301395438 - kind: conda name: aws-sdk-cpp version: 1.11.267 @@ -5552,7 +5525,7 @@ packages: - aws-crt-cpp >=0.26.6,<0.26.7.0a0 - libcurl >=8.7.1,<9.0a0 - libcxx >=16 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.2.1,<4.0a0 license: Apache-2.0 license_family: Apache @@ -5561,71 +5534,71 @@ packages: - kind: conda name: aws-sdk-cpp version: 1.11.267 - build: h134aaec_6 - build_number: 6 + build: h108e708_8 + build_number: 8 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-sdk-cpp-1.11.267-h134aaec_6.conda - sha256: 5eff7b834368f9e710cded2e7c0a56f1595b5b617f310547874df10c275cd6a0 - md5: 25727bad6dc72a38c856c3e9a578ebc7 + url: https://conda.anaconda.org/conda-forge/osx-arm64/aws-sdk-cpp-1.11.267-h108e708_8.conda + sha256: 7e7c6d017b86287e4d645209a094860559188e59aba1cbe31965348aeb5be921 + md5: bd77e7719bc124f92dab0f8c6c682215 depends: - __osx >=11.0 - - aws-c-common >=0.9.15,<0.9.16.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 - aws-c-event-stream >=0.4.2,<0.4.3.0a0 - aws-checksums >=0.1.18,<0.1.19.0a0 - - aws-crt-cpp >=0.26.6,<0.26.7.0a0 + - aws-crt-cpp >=0.26.8,<0.26.9.0a0 - libcurl >=8.7.1,<9.0a0 - libcxx >=16 - - libzlib >=1.2.13,<1.3.0a0 - - openssl >=3.2.1,<4.0a0 + - libzlib >=1.2.13,<2.0.0a0 + - openssl >=3.3.0,<4.0a0 license: Apache-2.0 license_family: Apache - size: 3411167 - timestamp: 1712754307571 + size: 3341757 + timestamp: 1715176512891 - kind: conda name: aws-sdk-cpp version: 1.11.267 - build: h5d77392_6 - build_number: 6 + build: h12f3f85_8 + build_number: 8 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/aws-sdk-cpp-1.11.267-h5d77392_6.conda - sha256: 9f21b50aaf0eecdc885151dc754fdc5902194e82850629686a0f2f2572b95760 - md5: 1d1a457905f69984e81e541d1ede18e7 + url: https://conda.anaconda.org/conda-forge/win-64/aws-sdk-cpp-1.11.267-h12f3f85_8.conda + sha256: 8717821ee98cc8c4f9f1e5be8a89a40ff68f6139be7b0461640c2db60ebcaf2a + md5: 7f43d81e0a58785839ed2b5bd92984d1 depends: - - aws-c-common >=0.9.15,<0.9.16.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 - aws-c-event-stream >=0.4.2,<0.4.3.0a0 - aws-checksums >=0.1.18,<0.1.19.0a0 - - aws-crt-cpp >=0.26.6,<0.26.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - aws-crt-cpp >=0.26.8,<0.26.9.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 license: Apache-2.0 license_family: Apache - size: 3435756 - timestamp: 1712754553202 + size: 3426476 + timestamp: 1715176833996 - kind: conda name: aws-sdk-cpp version: 1.11.267 - build: hbf3e495_6 - build_number: 6 + build: h51dfee4_8 + build_number: 8 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.267-hbf3e495_6.conda - sha256: f9cc828d2eba6a0490e0e79795360dfd744e5042f7105311ab0e5927b56121eb - md5: a6caf5a0d9ca940d95f21d40afe8f857 + url: https://conda.anaconda.org/conda-forge/linux-64/aws-sdk-cpp-1.11.267-h51dfee4_8.conda + sha256: 8fb8f648d1ae7d4f2005c130686b569eec998f8fda37d0f24e50fc069428484b + md5: 188857656abd6d1a4dcc471c619b0de5 depends: - - aws-c-common >=0.9.15,<0.9.16.0a0 + - aws-c-common >=0.9.17,<0.9.18.0a0 - aws-c-event-stream >=0.4.2,<0.4.3.0a0 - aws-checksums >=0.1.18,<0.1.19.0a0 - - aws-crt-cpp >=0.26.6,<0.26.7.0a0 + - aws-crt-cpp >=0.26.8,<0.26.9.0a0 - libcurl >=8.7.1,<9.0a0 - libgcc-ng >=12 - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 - - openssl >=3.2.1,<4.0a0 + - libzlib >=1.2.13,<2.0.0a0 + - openssl >=3.3.0,<4.0a0 license: Apache-2.0 license_family: Apache - size: 3643894 - timestamp: 1712753061178 + size: 3620978 + timestamp: 1715175553502 - kind: conda name: azure-core-cpp version: 1.11.1 @@ -6087,28 +6060,6 @@ packages: - pkg:pypi/html5lib size: 131220 timestamp: 1696630354218 -- kind: conda - name: bleach - version: 6.1.0 - build: pyhd8ed1ab_0 - subdir: noarch - noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/bleach-6.1.0-pyhd8ed1ab_0.conda - sha256: 845e77ef495376c5c3c328ccfd746ca0ef1978150cae8eae61a300fe7755fb08 - md5: 0ed9d7c0e9afa7c025807a9a8136ea3e - depends: - - packaging - - python >=3.6 - - setuptools - - six >=1.9.0 - - webencodings - license: Apache-2.0 - license_family: Apache - purls: - - pkg:pypi/html5lib - - pkg:pypi/bleach - size: 131220 - timestamp: 1696630354218 - kind: conda name: blosc version: 1.21.5 @@ -6121,7 +6072,7 @@ packages: depends: - __osx >=11.0 - libcxx >=16 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - snappy >=1.2.0,<1.3.0a0 - zstd >=1.5.5,<1.6.0a0 @@ -6141,7 +6092,7 @@ packages: depends: - __osx >=10.9 - libcxx >=16 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - snappy >=1.2.0,<1.3.0a0 - zstd >=1.5.5,<1.6.0a0 @@ -6159,7 +6110,7 @@ packages: sha256: a74c8a91bee3947f9865abd057ce33a1ebb728f04041bfd47bc478fdc133ca22 md5: 06c7d9a1cdecef43921be8b577a61ee7 depends: - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - snappy >=1.2.0,<1.3.0a0 - ucrt >=10.0.20348.0 @@ -6184,7 +6135,7 @@ packages: depends: - libgcc-ng >=12 - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - snappy >=1.2.0,<1.3.0a0 - zstd >=1.5.5,<1.6.0a0 @@ -6676,48 +6627,48 @@ packages: timestamp: 1711819445938 - kind: conda name: ca-certificates - version: 2024.2.2 + version: 2024.6.2 build: h56e8100_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/ca-certificates-2024.2.2-h56e8100_0.conda - sha256: 4d587088ecccd393fec3420b64f1af4ee1a0e6897a45cfd5ef38055322cea5d0 - md5: 63da060240ab8087b60d1357051ea7d6 + url: https://conda.anaconda.org/conda-forge/win-64/ca-certificates-2024.6.2-h56e8100_0.conda + sha256: d872d11558ebeaeb87bcf9086e97c075a1a2dfffed2d0e97570cf197ab29e3d8 + md5: 12a3a2b3a00a21bbb390d4de5ad8dd0f license: ISC - size: 155886 - timestamp: 1706843918052 + size: 156530 + timestamp: 1717311907623 - kind: conda name: ca-certificates - version: 2024.2.2 + version: 2024.6.2 build: h8857fd0_0 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/ca-certificates-2024.2.2-h8857fd0_0.conda - sha256: 54a794aedbb4796afeabdf54287b06b1d27f7b13b3814520925f4c2c80f58ca9 - md5: f2eacee8c33c43692f1ccfd33d0f50b1 + url: https://conda.anaconda.org/conda-forge/osx-64/ca-certificates-2024.6.2-h8857fd0_0.conda + sha256: ba0614477229fcb0f0666356f2c4686caa66f0ed1446e7c9666ce234abe2bacf + md5: 3c23a8cab15ae51ebc9efdc229fccecf license: ISC - size: 155665 - timestamp: 1706843838227 + size: 156145 + timestamp: 1717311781754 - kind: conda name: ca-certificates - version: 2024.2.2 + version: 2024.6.2 build: hbcca054_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.2.2-hbcca054_0.conda - sha256: 91d81bfecdbb142c15066df70cc952590ae8991670198f92c66b62019b251aeb - md5: 2f4327a1cbe7f022401b236e915a5fef + url: https://conda.anaconda.org/conda-forge/linux-64/ca-certificates-2024.6.2-hbcca054_0.conda + sha256: 979af0932b2a5a26112044891a2d79e402e5ae8166f50fa48b8ebae47c0a2d65 + md5: 847c3c2905cc467cea52c24f9cfa8080 license: ISC - size: 155432 - timestamp: 1706843687645 + size: 156035 + timestamp: 1717311767102 - kind: conda name: ca-certificates - version: 2024.2.2 + version: 2024.6.2 build: hf0a4a13_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/ca-certificates-2024.2.2-hf0a4a13_0.conda - sha256: 49bc3439816ac72d0c0e0f144b8cc870fdcc4adec2e861407ec818d8116b2204 - md5: fb416a1795f18dcc5a038bc2dc54edf9 + url: https://conda.anaconda.org/conda-forge/osx-arm64/ca-certificates-2024.6.2-hf0a4a13_0.conda + sha256: f5fd189d48965df396d060eb48628cbd9f083f1a1ea79c5236f60d655c7b9633 + md5: b534f104f102479402f88f73adf750f5 license: ISC - size: 155725 - timestamp: 1706844034242 + size: 156299 + timestamp: 1717311742040 - kind: conda name: cached-property version: 1.5.2 @@ -6767,7 +6718,7 @@ packages: - icu >=73.2,<74.0a0 - libglib >=2.78.0,<3.0a0 - libpng >=1.6.39,<1.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - pixman >=0.42.2,<1.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 @@ -6794,7 +6745,7 @@ packages: - libpng >=1.6.39,<1.7.0a0 - libstdcxx-ng >=12 - libxcb >=1.15,<1.16.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - pixman >=0.42.2,<1.0a0 - xorg-libice >=1.1.1,<2.0a0 - xorg-libsm >=1.2.4,<2.0a0 @@ -6822,7 +6773,7 @@ packages: - libcxx >=16.0.6 - libglib >=2.78.0,<3.0a0 - libpng >=1.6.39,<1.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - pixman >=0.42.2,<1.0a0 - zlib license: LGPL-2.1-only or MPL-1.1 @@ -6845,7 +6796,7 @@ packages: - libcxx >=16.0.6 - libglib >=2.78.0,<3.0a0 - libpng >=1.6.39,<1.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - pixman >=0.42.2,<1.0a0 - zlib license: LGPL-2.1-only or MPL-1.1 @@ -6853,20 +6804,20 @@ packages: timestamp: 1697028755150 - kind: conda name: certifi - version: 2024.2.2 + version: 2024.6.2 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.2.2-pyhd8ed1ab_0.conda - sha256: f1faca020f988696e6b6ee47c82524c7806380b37cfdd1def32f92c326caca54 - md5: 0876280e409658fc6f9e75d035960333 + url: https://conda.anaconda.org/conda-forge/noarch/certifi-2024.6.2-pyhd8ed1ab_0.conda + sha256: f101b8f9155b79d623601214eb719747ffe1c2ad3ff6c4e600f59163bd5f4803 + md5: 8821ec1c8fcdc9e1d291d7b9f6e9968a depends: - python >=3.7 license: ISC purls: - pkg:pypi/certifi - size: 160559 - timestamp: 1707022289175 + size: 160543 + timestamp: 1718025161969 - kind: conda name: cffi version: 1.16.0 @@ -6961,72 +6912,74 @@ packages: - libgfortran 5.* - libgfortran5 >=12.3.0 - libgfortran5 >=13.2.0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: LicenseRef-fitsio size: 804415 timestamp: 1700704377677 - kind: conda name: cfitsio - version: 4.3.1 - build: h808cd33_0 + version: 4.4.0 + build: h808cd33_1 + build_number: 1 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/cfitsio-4.3.1-h808cd33_0.conda - sha256: 9395bd24ef552ac6063e2d6a6fc57e5c7067a74b8d8ee3f06d8389baffacf016 - md5: 22b61b2ad129db82da2eee76710f7551 + url: https://conda.anaconda.org/conda-forge/osx-arm64/cfitsio-4.4.0-h808cd33_1.conda + sha256: e45dd58d752e30718422e596b5f98f679c19335c10bd426adb917ca4c5a5b697 + md5: 9413cd7e8cad79ef5bca73e1ca5a994f depends: - bzip2 >=1.0.8,<2.0a0 - - libcurl >=8.4.0,<9.0a0 + - libcurl >=8.7.1,<9.0a0 - libgfortran 5.* - libgfortran5 >=12.3.0 - libgfortran5 >=13.2.0 - - libzlib >=1.2.13,<1.3.0a0 - license: LicenseRef-fitsio - size: 761043 - timestamp: 1700704372096 + - libzlib >=1.2.13,<2.0.0a0 + license: NASA-1.3 + size: 801718 + timestamp: 1713454359210 - kind: conda name: cfitsio - version: 4.3.1 - build: h9b0cee5_0 + version: 4.4.0 + build: h9b0cee5_1 + build_number: 1 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/cfitsio-4.3.1-h9b0cee5_0.conda - sha256: 9fb11c689bb4c88e031c931cae23b09880e7a8c17713261844c16f5e88f349f2 - md5: eb7f15f7b2160dec9e803a86dcbe1d03 + url: https://conda.anaconda.org/conda-forge/win-64/cfitsio-4.4.0-h9b0cee5_1.conda + sha256: fa2e681a696beec5db97e228453c5b1b18a44032110fd81f386a5861c1131042 + md5: c1e9056348e8df1bc6b85fd7ae1f6766 depends: - - libcurl >=8.4.0,<9.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libcurl >=8.7.1,<9.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 - license: LicenseRef-fitsio - size: 563597 - timestamp: 1700704657931 + license: NASA-1.3 + size: 604815 + timestamp: 1713454571329 - kind: conda name: cfitsio - version: 4.3.1 - build: hbdc6101_0 + version: 4.4.0 + build: hbdc6101_1 + build_number: 1 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/cfitsio-4.3.1-hbdc6101_0.conda - sha256: b91003bff71351a0132c84d69fbb5afcfa90e57d83f76a180c6a5a0289099fb1 - md5: dcea02841b33a9c49f74ca9328de919a + url: https://conda.anaconda.org/conda-forge/linux-64/cfitsio-4.4.0-hbdc6101_1.conda + sha256: 7113a60bc4d7cdb6881d01c91e0f1f88f5f625bb7d4c809677d08679c66dda7f + md5: 0ba5a427a51923dcdfe1121115ac8293 depends: - bzip2 >=1.0.8,<2.0a0 - - libcurl >=8.4.0,<9.0a0 + - libcurl >=8.7.1,<9.0a0 - libgcc-ng >=12 - libgfortran-ng - libgfortran5 >=12.3.0 - - libzlib >=1.2.13,<1.3.0a0 - license: LicenseRef-fitsio - size: 875191 - timestamp: 1700704197213 + - libzlib >=1.2.13,<2.0.0a0 + license: NASA-1.3 + size: 914335 + timestamp: 1713454048942 - kind: conda name: cftime - version: 1.6.3 - build: py311h0a17f05_1 - build_number: 1 + version: 1.6.4 + build: py311h0a17f05_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/cftime-1.6.3-py311h0a17f05_1.conda - sha256: 0b3a7f294d6a33600274fec2249d638440aa981c24ec6f276f341430076ae851 - md5: 5fc5fd4567cf8b6b78a4d467ae03a5f2 + url: https://conda.anaconda.org/conda-forge/win-64/cftime-1.6.4-py311h0a17f05_0.conda + sha256: 795d5127d34f78d62e42ac184f0c75d4687a032726e9784374839d99156f6355 + md5: be0158556407bb5e8e78ec665812634d depends: - numpy >=1.19,<3 - python >=3.11,<3.12.0a0 @@ -7038,17 +6991,16 @@ packages: license_family: MIT purls: - pkg:pypi/cftime - size: 186946 - timestamp: 1715919822576 + size: 187708 + timestamp: 1718097030515 - kind: conda name: cftime - version: 1.6.3 - build: py311h18e1886_1 - build_number: 1 + version: 1.6.4 + build: py311h18e1886_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/cftime-1.6.3-py311h18e1886_1.conda - sha256: 5f06e8809edbf2e4818db00dfe07629fb57d90d884ef1f6075013a4791076640 - md5: f1beb063aad4446eb146d8b88420a4ea + url: https://conda.anaconda.org/conda-forge/linux-64/cftime-1.6.4-py311h18e1886_0.conda + sha256: bc3784d8622bab058c2a76ded90559e8acf19cea2768bc2bcac5e525890647b0 + md5: 0eb1e6c7d10285ec12e01f73d1896d93 depends: - libgcc-ng >=12 - numpy >=1.19,<3 @@ -7058,17 +7010,16 @@ packages: license_family: MIT purls: - pkg:pypi/cftime - size: 248700 - timestamp: 1715919327343 + size: 250491 + timestamp: 1718096595206 - kind: conda name: cftime - version: 1.6.3 - build: py311h5d790af_1 - build_number: 1 + version: 1.6.4 + build: py311h5d790af_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/cftime-1.6.3-py311h5d790af_1.conda - sha256: a58d9cb038a41cb172db453ff958504961860edd8b6a9a8f15ccd1f74f436ca2 - md5: a241c8c62c3cd785aba0c8a1abef711e + url: https://conda.anaconda.org/conda-forge/osx-arm64/cftime-1.6.4-py311h5d790af_0.conda + sha256: a3548d9f89fa41144a55dd5f2b696d4212bdfa24eef2e0e866be34b23ca47b4c + md5: ac42ae0d4cb643c229313a9dc2857449 depends: - __osx >=11.0 - numpy >=1.19,<3 @@ -7079,17 +7030,16 @@ packages: license_family: MIT purls: - pkg:pypi/cftime - size: 205352 - timestamp: 1715919584652 + size: 206929 + timestamp: 1718096847756 - kind: conda name: cftime - version: 1.6.3 - build: py311hce3442d_1 - build_number: 1 + version: 1.6.4 + build: py311hce3442d_0 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/cftime-1.6.3-py311hce3442d_1.conda - sha256: 32e13e7e86812c92a5b5086c4c80f2b7ab0b7c048998fce39e06758ff38f30c5 - md5: 4025282c58b2a63a09a3e055ca5d10f6 + url: https://conda.anaconda.org/conda-forge/osx-64/cftime-1.6.4-py311hce3442d_0.conda + sha256: 2df629f269bb8c82a5c9310f37ea278ee62987a6745110b794562f21f8708956 + md5: d7d27c26b91d3ebb7efdae3e0afa619a depends: - __osx >=10.13 - numpy >=1.19,<3 @@ -7099,8 +7049,8 @@ packages: license_family: MIT purls: - pkg:pypi/cftime - size: 211741 - timestamp: 1715919363404 + size: 213388 + timestamp: 1718096811666 - kind: conda name: charset-normalizer version: 3.3.2 @@ -7432,12 +7382,12 @@ packages: timestamp: 1712430316704 - kind: conda name: coverage - version: 7.5.1 + version: 7.5.3 build: py311h331c9d8_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/coverage-7.5.1-py311h331c9d8_0.conda - sha256: 2ecb21dc0efec42419c50f63daf1db0d6910f47db1b2653ebc5c43f76302024e - md5: 9f35e13e3b9e05e153b78f42662061f6 + url: https://conda.anaconda.org/conda-forge/linux-64/coverage-7.5.3-py311h331c9d8_0.conda + sha256: 88e0063cf333147890aafacc2f87360867991241af827a111d97433b7055691e + md5: 543dd05fd661e4e9c9deb3b37093d6a2 depends: - libgcc-ng >=12 - python >=3.11,<3.12.0a0 @@ -7447,18 +7397,18 @@ packages: license_family: APACHE purls: - pkg:pypi/coverage - size: 369007 - timestamp: 1714846741185 + size: 369467 + timestamp: 1716931054680 - kind: conda name: coverage - version: 7.5.1 - build: py311h42a8b16_0 + version: 7.5.3 + build: py311h72ae277_0 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/coverage-7.5.1-py311h42a8b16_0.conda - sha256: d2ca14f7d750652eb3a4f7a674b5a8ce65bae3586a699b613a83e66d879eef5d - md5: 043b439c3c4ae4b8a91aba062ef27d10 + url: https://conda.anaconda.org/conda-forge/osx-64/coverage-7.5.3-py311h72ae277_0.conda + sha256: 9dc466b8736f436190ae4936f1f57e12c0a81d2ce6f93e2f761ac6e8acb7a8bc + md5: a34013943f5189b08a14f8254a809461 depends: - - __osx >=10.9 + - __osx >=10.13 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 - tomli @@ -7466,16 +7416,16 @@ packages: license_family: APACHE purls: - pkg:pypi/coverage - size: 367115 - timestamp: 1714846868088 + size: 367953 + timestamp: 1716931110483 - kind: conda name: coverage - version: 7.5.1 + version: 7.5.3 build: py311hd3f4193_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.5.1-py311hd3f4193_0.conda - sha256: 6eaa811402fc3433bd891179410a434d0826da1f44579eccccc9dbb632769403 - md5: 81834421a20531c880f6c0a5342f3922 + url: https://conda.anaconda.org/conda-forge/osx-arm64/coverage-7.5.3-py311hd3f4193_0.conda + sha256: dcdfa3b24affe7399654f2e8429c15e05a54b8cce32583263a0731c37b62dcbc + md5: 402a8b40b9c9423f40a32be066b467be depends: - __osx >=11.0 - python >=3.11,<3.12.0a0 @@ -7486,16 +7436,16 @@ packages: license_family: APACHE purls: - pkg:pypi/coverage - size: 368146 - timestamp: 1714846963260 + size: 368732 + timestamp: 1716931397116 - kind: conda name: coverage - version: 7.5.1 + version: 7.5.3 build: py311he736701_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/coverage-7.5.1-py311he736701_0.conda - sha256: 844aea7ee1ff29d72f20406debb68b2e9bdd51f83299e6fb2e0b1f9b97e7e8e0 - md5: 44beec11cad6c9cd78fdd3594d62817b + url: https://conda.anaconda.org/conda-forge/win-64/coverage-7.5.3-py311he736701_0.conda + sha256: 16b1692a5ea5254842267e3f66489ecc009ff0d63c0d02148d756e32495c0947 + md5: eead686af955162027fb5825e83a3131 depends: - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 @@ -7507,28 +7457,28 @@ packages: license_family: APACHE purls: - pkg:pypi/coverage - size: 385417 - timestamp: 1714847169739 + size: 395283 + timestamp: 1716931857373 - kind: conda name: cryptography - version: 42.0.7 + version: 42.0.8 build: py311h4a61cc7_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/cryptography-42.0.7-py311h4a61cc7_0.conda - sha256: 00722024aae2e542f613a49576e61d4d2cbe2b0217203c9d1bfb363bee2be18c - md5: 251f3a7b306a8b212d42d585b3d06f36 + url: https://conda.anaconda.org/conda-forge/linux-64/cryptography-42.0.8-py311h4a61cc7_0.conda + sha256: 887557c1cc5083f68e531ffe98bb95e0ea2e99fb36f9d12f7f66c4cad2de7502 + md5: 962bcc96f59a31b62c43ac2b306812af depends: - cffi >=1.12 - libgcc-ng >=12 - - openssl >=3.3.0,<4.0a0 + - openssl >=3.3.1,<4.0a0 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 license: Apache-2.0 AND BSD-3-Clause AND PSF-2.0 AND MIT license_family: BSD purls: - pkg:pypi/cryptography - size: 1993803 - timestamp: 1715044315586 + size: 1994262 + timestamp: 1717559614443 - kind: conda name: cycler version: 0.12.1 @@ -7783,8 +7733,8 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/bytecode - pkg:pypi/debugpy + - pkg:pypi/bytecode size: 2272457 timestamp: 1707444947065 - kind: conda @@ -7803,8 +7753,8 @@ packages: license: MIT license_family: MIT purls: - - pkg:pypi/bytecode - pkg:pypi/debugpy + - pkg:pypi/bytecode size: 2302395 timestamp: 1707444677899 - kind: conda @@ -8188,73 +8138,70 @@ packages: - kind: conda name: expat version: 2.5.0 - build: h63175ca_1 + build: hf0c8a7f_1 build_number: 1 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/expat-2.5.0-h63175ca_1.conda - sha256: 3bcd88290cd462d5573c2923c796599d0dece2ff9d9c9d6c914d31e9c5881aaf - md5: 87c77fe1b445aedb5c6d207dd236fa3e + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/expat-2.5.0-hf0c8a7f_1.conda + sha256: 15c04a5a690b337b50fb7550cce057d843cf94dd0109d576ec9bc3448a8571d0 + md5: e12630038077877cbb6c7851e139c17c depends: - - libexpat 2.5.0 h63175ca_1 + - libexpat 2.5.0 hf0c8a7f_1 license: MIT license_family: MIT - size: 226571 - timestamp: 1680190888036 + size: 120323 + timestamp: 1680191057827 - kind: conda name: expat - version: 2.5.0 - build: hb7217d7_1 - build_number: 1 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/expat-2.5.0-hb7217d7_1.conda - sha256: 9f06afbe4604decf6a2e8e7e87f5ca218a3e9049d57d5b3fcd538ca6240d21a0 - md5: 624fa0dd6fdeaa650b71a62296fdfedf + version: 2.6.2 + build: h59595ed_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/expat-2.6.2-h59595ed_0.conda + sha256: 89916c536ae5b85bb8bf0cfa27d751e274ea0911f04e4a928744735c14ef5155 + md5: 53fb86322bdb89496d7579fe3f02fd61 depends: - - libexpat 2.5.0 hb7217d7_1 + - libexpat 2.6.2 h59595ed_0 + - libgcc-ng >=12 license: MIT license_family: MIT - size: 117851 - timestamp: 1680190940654 + size: 137627 + timestamp: 1710362144873 - kind: conda name: expat - version: 2.5.0 - build: hcb278e6_1 - build_number: 1 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/expat-2.5.0-hcb278e6_1.conda - sha256: 36dfeb4375059b3bba75ce9b38c29c69fd257342a79e6cf20e9f25c1523f785f - md5: 8b9b5aca60558d02ddaa09d599e55920 + version: 2.6.2 + build: h63175ca_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/expat-2.6.2-h63175ca_0.conda + sha256: f5a13d4bc591a4dc210954f492dd59a0ecf9b9d2ab28bf2ece755ca8f69ec1b4 + md5: 52f9dec6758ceb8ce0ea8af9fa13eb1a depends: - - libexpat 2.5.0 hcb278e6_1 - - libgcc-ng >=12 + - libexpat 2.6.2 h63175ca_0 license: MIT license_family: MIT - size: 136778 - timestamp: 1680190541750 + size: 229627 + timestamp: 1710362661692 - kind: conda name: expat - version: 2.5.0 - build: hf0c8a7f_1 - build_number: 1 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/expat-2.5.0-hf0c8a7f_1.conda - sha256: 15c04a5a690b337b50fb7550cce057d843cf94dd0109d576ec9bc3448a8571d0 - md5: e12630038077877cbb6c7851e139c17c + version: 2.6.2 + build: hebf3989_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/expat-2.6.2-hebf3989_0.conda + sha256: 9ac22553a4d595d7e4c9ca9aa09a0b38da65314529a7a7008edc73d3f9e7904a + md5: de0cff0ec74f273c4b6aa281479906c3 depends: - - libexpat 2.5.0 hf0c8a7f_1 + - libexpat 2.6.2 hebf3989_0 license: MIT license_family: MIT - size: 120323 - timestamp: 1680191057827 + size: 124594 + timestamp: 1710362455984 - kind: conda name: fastcore - version: 1.5.38 + version: 1.5.45 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.38-pyhd8ed1ab_0.conda - sha256: 7a7ed120dc58ccbee58703a004260cc9b854cf7a37e6fce7e74b560c90abed61 - md5: 00f60ed1765a03e1e4d7784204d2611f + url: https://conda.anaconda.org/conda-forge/noarch/fastcore-1.5.45-pyhd8ed1ab_0.conda + sha256: 2790fb7d2ce395c225d28c408852de577efa11bbc3b0a8f1ad7b34ab0e3440c8 + md5: 19c1e345354ac14fc60ae3f04867751c depends: - packaging - pip @@ -8263,8 +8210,8 @@ packages: license_family: APACHE purls: - pkg:pypi/fastcore - size: 65435 - timestamp: 1716241472396 + size: 69043 + timestamp: 1717918238998 - kind: conda name: fasteners version: 0.17.3 @@ -8285,13 +8232,14 @@ packages: - kind: conda name: ffmpeg version: 6.1.1 - build: gpl_h4f1e072_108 + build: gpl_h6b92a41_108 build_number: 108 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/ffmpeg-6.1.1-gpl_h4f1e072_108.conda - sha256: c4e171ec03ca367926a64e64d4ffba65ea7f8e68b8c69a6dc91ee490063f7e7f - md5: 696ed7a1cb702ca44b8deaf2698703ea + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/ffmpeg-6.1.1-gpl_h6b92a41_108.conda + sha256: b1d3f50780db24a5656dfb51129fc36e38a369f23d9d3c8edd5de6d8d8cd7e36 + md5: 5bcbd435d3b3204d0ef0916ff3e3032c depends: + - __osx >=10.13 - aom >=3.8.2,<3.9.0a0 - bzip2 >=1.0.8,<2.0a0 - dav1d >=1.2.1,<1.2.2.0a0 @@ -8306,10 +8254,10 @@ packages: - libcxx >=16 - libiconv >=1.17,<2.0a0 - libopenvino >=2024.0.0,<2024.0.1.0a0 - - libopenvino-arm-cpu-plugin >=2024.0.0,<2024.0.1.0a0 - libopenvino-auto-batch-plugin >=2024.0.0,<2024.0.1.0a0 - libopenvino-auto-plugin >=2024.0.0,<2024.0.1.0a0 - libopenvino-hetero-plugin >=2024.0.0,<2024.0.1.0a0 + - libopenvino-intel-cpu-plugin >=2024.0.0,<2024.0.1.0a0 - libopenvino-ir-frontend >=2024.0.0,<2024.0.1.0a0 - libopenvino-onnx-frontend >=2024.0.0,<2024.0.1.0a0 - libopenvino-paddle-frontend >=2024.0.0,<2024.0.1.0a0 @@ -8319,7 +8267,7 @@ packages: - libopus >=1.3.1,<2.0a0 - libvpx >=1.14.0,<1.15.0a0 - libxml2 >=2.12.6,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openh264 >=2.4.1,<2.4.2.0a0 - svt-av1 >=2.0.0,<2.0.1.0a0 - x264 >=1!164.3095,<1!165 @@ -8327,31 +8275,31 @@ packages: - xz >=5.2.6,<6.0a0 license: GPL-2.0-or-later license_family: GPL - size: 8661815 - timestamp: 1712658165543 + size: 9694369 + timestamp: 1712658377331 - kind: conda name: ffmpeg version: 6.1.1 - build: gpl_h66c0b5b_108 - build_number: 108 + build: gpl_h7cec250_112 + build_number: 112 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/ffmpeg-6.1.1-gpl_h66c0b5b_108.conda - sha256: b3e1c32f150a4f8afba0ba304af7a1cb073d5d46f8e29a671ce9c0ae1cf965c3 - md5: 3918f1f54a5d4ae01671879fa8649a37 + url: https://conda.anaconda.org/conda-forge/win-64/ffmpeg-6.1.1-gpl_h7cec250_112.conda + sha256: 9ad26b3e0f762082232dbf4eb238e16a9408731529bc8371d7b7535617dccf74 + md5: 9a067705dc2087668e0af15faf2092e8 depends: - - aom >=3.8.2,<3.9.0a0 + - aom >=3.9.0,<3.10.0a0 - bzip2 >=1.0.8,<2.0a0 - dav1d >=1.2.1,<1.2.2.0a0 - fontconfig >=2.14.2,<3.0a0 - fonts-conda-ecosystem - freetype >=2.12.1,<3.0a0 - - harfbuzz >=8.3.0,<9.0a0 + - harfbuzz >=8.5.0,<9.0a0 - libiconv >=1.17,<2.0a0 - libopus >=1.3.1,<2.0a0 - - libxml2 >=2.12.6,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libxml2 >=2.12.7,<3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openh264 >=2.4.1,<2.4.2.0a0 - - svt-av1 >=2.0.0,<2.0.1.0a0 + - svt-av1 >=2.1.0,<2.1.1.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 @@ -8360,20 +8308,20 @@ packages: - xz >=5.2.6,<6.0a0 license: GPL-2.0-or-later license_family: GPL - size: 9616766 - timestamp: 1712658196820 + size: 9612317 + timestamp: 1716146642551 - kind: conda name: ffmpeg version: 6.1.1 - build: gpl_h6b92a41_108 - build_number: 108 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/ffmpeg-6.1.1-gpl_h6b92a41_108.conda - sha256: b1d3f50780db24a5656dfb51129fc36e38a369f23d9d3c8edd5de6d8d8cd7e36 - md5: 5bcbd435d3b3204d0ef0916ff3e3032c + build: gpl_hc16618e_112 + build_number: 112 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/ffmpeg-6.1.1-gpl_hc16618e_112.conda + sha256: 96c1ac05e5a46b2023816a8dcb7adc8a32aea35933f27802f88053ecb0cd2f1d + md5: 4c170cbb2109cd40318db2f09724a031 depends: - - __osx >=10.13 - - aom >=3.8.2,<3.9.0a0 + - __osx >=11.0 + - aom >=3.9.0,<3.10.0a0 - bzip2 >=1.0.8,<2.0a0 - dav1d >=1.2.1,<1.2.2.0a0 - fontconfig >=2.14.2,<3.0a0 @@ -8381,46 +8329,46 @@ packages: - freetype >=2.12.1,<3.0a0 - gmp >=6.3.0,<7.0a0 - gnutls >=3.7.9,<3.8.0a0 - - harfbuzz >=8.3.0,<9.0a0 + - harfbuzz >=8.5.0,<9.0a0 - lame >=3.100,<3.101.0a0 - libass >=0.17.1,<0.17.2.0a0 - libcxx >=16 - libiconv >=1.17,<2.0a0 - - libopenvino >=2024.0.0,<2024.0.1.0a0 - - libopenvino-auto-batch-plugin >=2024.0.0,<2024.0.1.0a0 - - libopenvino-auto-plugin >=2024.0.0,<2024.0.1.0a0 - - libopenvino-hetero-plugin >=2024.0.0,<2024.0.1.0a0 - - libopenvino-intel-cpu-plugin >=2024.0.0,<2024.0.1.0a0 - - libopenvino-ir-frontend >=2024.0.0,<2024.0.1.0a0 - - libopenvino-onnx-frontend >=2024.0.0,<2024.0.1.0a0 - - libopenvino-paddle-frontend >=2024.0.0,<2024.0.1.0a0 - - libopenvino-pytorch-frontend >=2024.0.0,<2024.0.1.0a0 - - libopenvino-tensorflow-frontend >=2024.0.0,<2024.0.1.0a0 - - libopenvino-tensorflow-lite-frontend >=2024.0.0,<2024.0.1.0a0 + - libopenvino >=2024.1.0,<2024.1.1.0a0 + - libopenvino-arm-cpu-plugin >=2024.1.0,<2024.1.1.0a0 + - libopenvino-auto-batch-plugin >=2024.1.0,<2024.1.1.0a0 + - libopenvino-auto-plugin >=2024.1.0,<2024.1.1.0a0 + - libopenvino-hetero-plugin >=2024.1.0,<2024.1.1.0a0 + - libopenvino-ir-frontend >=2024.1.0,<2024.1.1.0a0 + - libopenvino-onnx-frontend >=2024.1.0,<2024.1.1.0a0 + - libopenvino-paddle-frontend >=2024.1.0,<2024.1.1.0a0 + - libopenvino-pytorch-frontend >=2024.1.0,<2024.1.1.0a0 + - libopenvino-tensorflow-frontend >=2024.1.0,<2024.1.1.0a0 + - libopenvino-tensorflow-lite-frontend >=2024.1.0,<2024.1.1.0a0 - libopus >=1.3.1,<2.0a0 - libvpx >=1.14.0,<1.15.0a0 - - libxml2 >=2.12.6,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libxml2 >=2.12.7,<3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openh264 >=2.4.1,<2.4.2.0a0 - - svt-av1 >=2.0.0,<2.0.1.0a0 + - svt-av1 >=2.1.0,<2.1.1.0a0 - x264 >=1!164.3095,<1!165 - x265 >=3.5,<3.6.0a0 - xz >=5.2.6,<6.0a0 license: GPL-2.0-or-later license_family: GPL - size: 9694369 - timestamp: 1712658377331 + size: 8653035 + timestamp: 1716145819735 - kind: conda name: ffmpeg version: 6.1.1 - build: gpl_hee4b679_108 - build_number: 108 + build: gpl_he44c6f3_112 + build_number: 112 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/ffmpeg-6.1.1-gpl_hee4b679_108.conda - sha256: daa3955e9d087197a90c4464d75260b73ab77e06feb1158f7814f2bff8489134 - md5: 66701e0a42c7f02d79d3856942f14e05 + url: https://conda.anaconda.org/conda-forge/linux-64/ffmpeg-6.1.1-gpl_he44c6f3_112.conda + sha256: a4cfb76c9a1e58f755869e0cc33707a5e3473f0c8d0d49ddaa10e84e87909486 + md5: 51a49318bcd4e848e867a5b9ea5b6545 depends: - - aom >=3.8.2,<3.9.0a0 + - aom >=3.9.0,<3.10.0a0 - bzip2 >=1.0.8,<2.0a0 - dav1d >=1.2.1,<1.2.2.0a0 - fontconfig >=2.14.2,<3.0a0 @@ -8428,40 +8376,41 @@ packages: - freetype >=2.12.1,<3.0a0 - gmp >=6.3.0,<7.0a0 - gnutls >=3.7.9,<3.8.0a0 - - harfbuzz >=8.3.0,<9.0a0 + - harfbuzz >=8.5.0,<9.0a0 - lame >=3.100,<3.101.0a0 - libass >=0.17.1,<0.17.2.0a0 - libgcc-ng >=12 - libiconv >=1.17,<2.0a0 - - libopenvino >=2024.0.0,<2024.0.1.0a0 - - libopenvino-auto-batch-plugin >=2024.0.0,<2024.0.1.0a0 - - libopenvino-auto-plugin >=2024.0.0,<2024.0.1.0a0 - - libopenvino-hetero-plugin >=2024.0.0,<2024.0.1.0a0 - - libopenvino-intel-cpu-plugin >=2024.0.0,<2024.0.1.0a0 - - libopenvino-intel-gpu-plugin >=2024.0.0,<2024.0.1.0a0 - - libopenvino-ir-frontend >=2024.0.0,<2024.0.1.0a0 - - libopenvino-onnx-frontend >=2024.0.0,<2024.0.1.0a0 - - libopenvino-paddle-frontend >=2024.0.0,<2024.0.1.0a0 - - libopenvino-pytorch-frontend >=2024.0.0,<2024.0.1.0a0 - - libopenvino-tensorflow-frontend >=2024.0.0,<2024.0.1.0a0 - - libopenvino-tensorflow-lite-frontend >=2024.0.0,<2024.0.1.0a0 + - libopenvino >=2024.1.0,<2024.1.1.0a0 + - libopenvino-auto-batch-plugin >=2024.1.0,<2024.1.1.0a0 + - libopenvino-auto-plugin >=2024.1.0,<2024.1.1.0a0 + - libopenvino-hetero-plugin >=2024.1.0,<2024.1.1.0a0 + - libopenvino-intel-cpu-plugin >=2024.1.0,<2024.1.1.0a0 + - libopenvino-intel-gpu-plugin >=2024.1.0,<2024.1.1.0a0 + - libopenvino-intel-npu-plugin >=2024.1.0,<2024.1.1.0a0 + - libopenvino-ir-frontend >=2024.1.0,<2024.1.1.0a0 + - libopenvino-onnx-frontend >=2024.1.0,<2024.1.1.0a0 + - libopenvino-paddle-frontend >=2024.1.0,<2024.1.1.0a0 + - libopenvino-pytorch-frontend >=2024.1.0,<2024.1.1.0a0 + - libopenvino-tensorflow-frontend >=2024.1.0,<2024.1.1.0a0 + - libopenvino-tensorflow-lite-frontend >=2024.1.0,<2024.1.1.0a0 - libopus >=1.3.1,<2.0a0 - libstdcxx-ng >=12 - libva >=2.21.0,<3.0a0 - libvpx >=1.14.0,<1.15.0a0 - libxcb >=1.15,<1.16.0a0 - - libxml2 >=2.12.6,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libxml2 >=2.12.7,<3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openh264 >=2.4.1,<2.4.2.0a0 - - svt-av1 >=2.0.0,<2.0.1.0a0 + - svt-av1 >=2.1.0,<2.1.1.0a0 - x264 >=1!164.3095,<1!165 - x265 >=3.5,<3.6.0a0 - xorg-libx11 >=1.8.9,<2.0a0 - xz >=5.2.6,<6.0a0 license: GPL-2.0-or-later license_family: GPL - size: 9782121 - timestamp: 1712657205196 + size: 9788322 + timestamp: 1716145697248 - kind: conda name: fiona version: 1.9.6 @@ -8609,7 +8558,7 @@ packages: - libjpeg-turbo >=3.0.0,<4.0a0 - libpng >=1.6.39,<1.7.0a0 - libxcb >=1.15,<1.16.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - vc >=14.1,<15 - vc14_runtime >=14.16.27033 - xorg-libice >=1.1.1,<2.0a0 @@ -8638,7 +8587,7 @@ packages: - libjpeg-turbo >=3.0.0,<4.0a0 - libpng >=1.6.39,<1.7.0a0 - libxcb >=1.15,<1.16.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - xorg-libice >=1.1.1,<2.0a0 - xorg-libsm >=1.2.4,<2.0a0 - xorg-libx11 >=1.8.7,<2.0a0 @@ -8665,7 +8614,7 @@ packages: - libjpeg-turbo >=3.0.0,<4.0a0 - libpng >=1.6.39,<1.7.0a0 - libxcb >=1.15,<1.16.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - xorg-libice >=1.1.1,<2.0a0 - xorg-libsm >=1.2.4,<2.0a0 - xorg-libx11 >=1.8.7,<2.0a0 @@ -8694,7 +8643,7 @@ packages: - libpng >=1.6.39,<1.7.0a0 - libstdcxx-ng >=12 - libxcb >=1.15,<1.16.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - xorg-libice >=1.1.1,<2.0a0 - xorg-libsm >=1.2.4,<2.0a0 - xorg-libx11 >=1.8.7,<2.0a0 @@ -8854,7 +8803,7 @@ packages: - freetype >=2.12.1,<3.0a0 - libgcc-ng >=12 - libuuid >=2.32.1,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: MIT license_family: MIT size: 272010 @@ -8870,7 +8819,7 @@ packages: depends: - expat >=2.5.0,<3.0a0 - freetype >=2.12.1,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: MIT license_family: MIT size: 237068 @@ -8886,7 +8835,7 @@ packages: depends: - expat >=2.5.0,<3.0a0 - freetype >=2.12.1,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: MIT license_family: MIT size: 237668 @@ -8903,7 +8852,7 @@ packages: - expat >=2.5.0,<3.0a0 - freetype >=2.12.1,<3.0a0 - libiconv >=1.17,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vs2015_runtime >=14.29.30139 @@ -8946,12 +8895,12 @@ packages: timestamp: 1566932280397 - kind: conda name: fonttools - version: 4.52.1 + version: 4.53.0 build: py311h331c9d8_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.52.1-py311h331c9d8_0.conda - sha256: f51437c1b041aa54e2f855c281cb25c34ce8dcd0aee4690f4455486a0264360f - md5: bb70cda5777de08084a402a2cdc13935 + url: https://conda.anaconda.org/conda-forge/linux-64/fonttools-4.53.0-py311h331c9d8_0.conda + sha256: 13420d73202fd50060fdfe70f06cdc1a04383abae37304c4d6854e03157a9ba3 + md5: 2daef6c4ce74840c8d7a431498be83e9 depends: - brotli - libgcc-ng >=12 @@ -8962,16 +8911,16 @@ packages: license_family: MIT purls: - pkg:pypi/fonttools - size: 2867305 - timestamp: 1716599957226 + size: 2877227 + timestamp: 1717209330665 - kind: conda name: fonttools - version: 4.52.1 + version: 4.53.0 build: py311h72ae277_0 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/fonttools-4.52.1-py311h72ae277_0.conda - sha256: 1f5802e75da75c6965de18a3087d8c40e4930c4a6b19819a7d8464530c3b3cad - md5: ce4d32074d0359168fb7e15f86d71305 + url: https://conda.anaconda.org/conda-forge/osx-64/fonttools-4.53.0-py311h72ae277_0.conda + sha256: 8ff94990a8da63f19d22b899bf3c466ce282d6ac42739eb6f0bbb53e946f8607 + md5: d4db6648ab108506846370a184180bf1 depends: - __osx >=10.13 - brotli @@ -8982,16 +8931,16 @@ packages: license_family: MIT purls: - pkg:pypi/fonttools - size: 2809382 - timestamp: 1716599933616 + size: 2805129 + timestamp: 1717209382370 - kind: conda name: fonttools - version: 4.52.1 + version: 4.53.0 build: py311hd3f4193_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.52.1-py311hd3f4193_0.conda - sha256: 528c74dac3fdc173bda3511812c72d606f47341fce3f83d1aa66b869918ef8ae - md5: 43feeef0eea8c063c5376fa20202b2e2 + url: https://conda.anaconda.org/conda-forge/osx-arm64/fonttools-4.53.0-py311hd3f4193_0.conda + sha256: 21738d562152db20c5f39e127692de5bbfdaf50be0d5bfb64f580e1d9ab716f7 + md5: 57b04e03c4628afe2a8baf80fe5a59b7 depends: - __osx >=11.0 - brotli @@ -9003,16 +8952,16 @@ packages: license_family: MIT purls: - pkg:pypi/fonttools - size: 2774040 - timestamp: 1716600147215 + size: 2785025 + timestamp: 1717209426909 - kind: conda name: fonttools - version: 4.52.1 + version: 4.53.0 build: py311he736701_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.52.1-py311he736701_0.conda - sha256: d44640193c1ace889e62096002bdc00cb129b3b1d977ecc5e9980243b259576b - md5: 7846db32c06191242745fbeafb0956cf + url: https://conda.anaconda.org/conda-forge/win-64/fonttools-4.53.0-py311he736701_0.conda + sha256: fc89fbaf0326e1b79f1aaacaffc3cea1663cb6bf4f93f9d81dbff5c3e8a59ebc + md5: 010f57b69dbcd70304c2d3867a14627c depends: - brotli - munkres @@ -9025,8 +8974,8 @@ packages: license_family: MIT purls: - pkg:pypi/fonttools - size: 2465026 - timestamp: 1716600423899 + size: 2469143 + timestamp: 1717209940047 - kind: conda name: fqdn version: 1.5.1 @@ -9062,7 +9011,7 @@ packages: - libraw >=0.21.1,<0.22.0a0 - libtiff >=4.6.0,<4.7.0a0 - libwebp-base >=1.3.2,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openexr >=3.2.2,<3.3.0a0 - openjpeg >=2.5.2,<3.0a0 - ucrt >=10.0.20348.0 @@ -9090,7 +9039,7 @@ packages: - libstdcxx-ng >=12 - libtiff >=4.6.0,<4.7.0a0 - libwebp-base >=1.3.2,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openexr >=3.2.2,<3.3.0a0 - openjpeg >=2.5.2,<3.0a0 license: GPL-2.0-or-later OR GPL-3.0-or-later OR FreeImage @@ -9114,7 +9063,7 @@ packages: - libraw >=0.21.1,<0.22.0a0 - libtiff >=4.6.0,<4.7.0a0 - libwebp-base >=1.3.2,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openexr >=3.2.2,<3.3.0a0 - openjpeg >=2.5.2,<3.0a0 license: GPL-2.0-or-later OR GPL-3.0-or-later OR FreeImage @@ -9138,7 +9087,7 @@ packages: - libraw >=0.21.1,<0.22.0a0 - libtiff >=4.6.0,<4.7.0a0 - libwebp-base >=1.3.2,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openexr >=3.2.2,<3.3.0a0 - openjpeg >=2.5.2,<3.0a0 license: GPL-2.0-or-later OR GPL-3.0-or-later OR FreeImage @@ -9156,7 +9105,7 @@ packages: depends: - libgcc-ng >=12 - libpng >=1.6.39,<1.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: GPL-2.0-only OR FTL size: 634972 timestamp: 1694615932610 @@ -9171,7 +9120,7 @@ packages: md5: 25152fce119320c980e5470e64834b50 depends: - libpng >=1.6.39,<1.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: GPL-2.0-only OR FTL size: 599300 timestamp: 1694616137838 @@ -9186,7 +9135,7 @@ packages: md5: e6085e516a3e304ce41a8ee08b9b89ad depends: - libpng >=1.6.39,<1.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: GPL-2.0-only OR FTL size: 596430 timestamp: 1694616332835 @@ -9201,7 +9150,7 @@ packages: md5: 3761b23693f768dc75a8fd0a73ca053f depends: - libpng >=1.6.39,<1.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 @@ -9400,33 +9349,34 @@ packages: timestamp: 1702645839241 - kind: conda name: fsspec - version: 2024.5.0 + version: 2024.6.0 build: pyhff2d567_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/fsspec-2024.5.0-pyhff2d567_0.conda - sha256: 34149798edaf7f67251ee09612cd50b52ee8a69b45e63ddb79732085ae7423cd - md5: d73e9932511ef7670b2cc0ebd9dfbd30 + url: https://conda.anaconda.org/conda-forge/noarch/fsspec-2024.6.0-pyhff2d567_0.conda + sha256: 0c5a476ea0e82f9f7a1a0dbdb118eef2300addc0e25f6c1d1329d36e65002d5c + md5: ad6af3f92e71b1579ac2362b6cf29105 depends: - python >=3.8 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/fsspec - size: 216196 - timestamp: 1715865901761 + size: 132958 + timestamp: 1717498629896 - kind: conda name: gdal version: 3.8.4 - build: py311h21a6730_0 + build: py311h21a6730_5 + build_number: 5 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/gdal-3.8.4-py311h21a6730_0.conda - sha256: bc24bc2b1450b7204482f83d0bb0a45d610b0114cb8fab4f8f7a3ae424c83d8b - md5: f506f77d5573f902fed9653973e65d8a + url: https://conda.anaconda.org/conda-forge/win-64/gdal-3.8.4-py311h21a6730_5.conda + sha256: 287deb5b52c1bd96b1f90af91c3950849de1e29dc97355c2039c11966ff57792 + md5: 3ae0797c272519dc4d3925aa89019057 depends: - hdf5 >=1.14.3,<1.14.4.0a0 - - libgdal 3.8.4 h7c2897a_0 - - libxml2 >=2.12.5,<3.0a0 + - libgdal 3.8.4 hf83a0e2_5 + - libxml2 >=2.12.6,<3.0a0 - numpy >=1.23.5,<2.0a0 - openssl >=3.2.1,<4.0a0 - python >=3.11,<3.12.0a0 @@ -9438,21 +9388,22 @@ packages: license_family: MIT purls: - pkg:pypi/gdal - size: 1632885 - timestamp: 1708281647106 + size: 1632043 + timestamp: 1711287133402 - kind: conda name: gdal version: 3.8.4 - build: py311h43f0207_0 + build: py311h43f0207_5 + build_number: 5 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/gdal-3.8.4-py311h43f0207_0.conda - sha256: 452b2486f50802dd8c8754320c832aa5bae8f3a5e6967ef5c72ef01932449507 - md5: 4ddc8810dd43a3406dca1d5fffb6201d + url: https://conda.anaconda.org/conda-forge/osx-arm64/gdal-3.8.4-py311h43f0207_5.conda + sha256: e556b5e54ab97fa85568182bd1fd328d28d8d57eaaf4d44b37acebba2b8fa599 + md5: d8e61aba08abe3ce4db36cf8a17b16fd depends: - hdf5 >=1.14.3,<1.14.4.0a0 - libcxx >=16 - - libgdal 3.8.4 ha86f356_0 - - libxml2 >=2.12.5,<3.0a0 + - libgdal 3.8.4 h7181668_5 + - libxml2 >=2.12.6,<3.0a0 - numpy >=1.23.5,<2.0a0 - openssl >=3.2.1,<4.0a0 - python >=3.11,<3.12.0a0 @@ -9462,22 +9413,23 @@ packages: license_family: MIT purls: - pkg:pypi/gdal - size: 1647713 - timestamp: 1708281173819 + size: 1648278 + timestamp: 1711287177532 - kind: conda name: gdal version: 3.8.4 - build: py311h8be719e_0 + build: py311h8be719e_5 + build_number: 5 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/gdal-3.8.4-py311h8be719e_0.conda - sha256: 8c54dabcc6152c22da82e69bdf7923ea58370986056aa0a0757bc24a4824be0d - md5: de4d128805c8e1cbe408a93be1f715f3 + url: https://conda.anaconda.org/conda-forge/linux-64/gdal-3.8.4-py311h8be719e_5.conda + sha256: 839f519668585e79b577ad74172b23d0509079213522e1f15b23b52640c8c645 + md5: de467dcf47e6877fabff111dbe98b4b3 depends: - hdf5 >=1.14.3,<1.14.4.0a0 - libgcc-ng >=12 - - libgdal 3.8.4 h9323651_0 + - libgdal 3.8.4 h7c88fdf_5 - libstdcxx-ng >=12 - - libxml2 >=2.12.5,<3.0a0 + - libxml2 >=2.12.6,<3.0a0 - numpy >=1.23.5,<2.0a0 - openssl >=3.2.1,<4.0a0 - python >=3.11,<3.12.0a0 @@ -9486,8 +9438,8 @@ packages: license_family: MIT purls: - pkg:pypi/gdal - size: 1683746 - timestamp: 1708279785540 + size: 1682610 + timestamp: 1711286124328 - kind: conda name: gdal version: 3.8.4 @@ -9514,12 +9466,12 @@ packages: - kind: conda name: gdk-pixbuf version: 2.42.10 - build: h829c605_5 + build: hd9e0ca3_5 build_number: 5 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/gdk-pixbuf-2.42.10-h829c605_5.conda - sha256: bacd1cc3ed77699dec11ea5a670160db3cf701f1b19f34f1a19be36cae25c396 - md5: 8fdb82e5d9694dd8e9ed9ac8fdf48a26 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/gdk-pixbuf-2.42.10-hd9e0ca3_5.conda + sha256: e15a0923d2640020dc7f2ff2b04f09face4ddce6484e09f78752cd0e65ad1cdf + md5: 308cefd960b6ba51bdbdc5ba9e9b2377 depends: - libglib >=2.78.4,<3.0a0 - libjpeg-turbo >=3.0.0,<4.0a0 @@ -9527,44 +9479,45 @@ packages: - libtiff >=4.6.0,<4.7.0a0 license: LGPL-2.1-or-later license_family: LGPL - size: 573339 - timestamp: 1710203544212 + size: 550156 + timestamp: 1710203904195 - kind: conda name: gdk-pixbuf - version: 2.42.10 - build: hcea6d13_5 - build_number: 5 + version: 2.42.12 + build: h7ddc832_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/gdk-pixbuf-2.42.10-hcea6d13_5.conda - sha256: 1259c6a32269074b85e870a2afaa426f96cba6ebad547c3e152c941e46036e3a - md5: bbf4bb664dedbec6d3a8fb8b6d90b710 + url: https://conda.anaconda.org/conda-forge/osx-arm64/gdk-pixbuf-2.42.12-h7ddc832_0.conda + sha256: 72bcf0a4d3f9aa6d99d7d1d224d19f76ccdb3a4fa85e60f77d17e17985c81bd2 + md5: 151309a7e1eb57a3c2ab8088a1d74f3e depends: - - libglib >=2.78.4,<3.0a0 + - __osx >=11.0 + - libglib >=2.80.2,<3.0a0 + - libintl >=0.22.5,<1.0a0 - libjpeg-turbo >=3.0.0,<4.0a0 - libpng >=1.6.43,<1.7.0a0 - libtiff >=4.6.0,<4.7.0a0 license: LGPL-2.1-or-later license_family: LGPL - size: 548239 - timestamp: 1710203926272 + size: 509570 + timestamp: 1715783199780 - kind: conda name: gdk-pixbuf - version: 2.42.10 - build: hd9e0ca3_5 - build_number: 5 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/gdk-pixbuf-2.42.10-hd9e0ca3_5.conda - sha256: e15a0923d2640020dc7f2ff2b04f09face4ddce6484e09f78752cd0e65ad1cdf - md5: 308cefd960b6ba51bdbdc5ba9e9b2377 + version: 2.42.12 + build: hb9ae30d_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/gdk-pixbuf-2.42.12-hb9ae30d_0.conda + sha256: d5283b95a8d49dcd88d29b360d8b38694aaa905d968d156d72ab71d32b38facb + md5: 201db6c2d9a3c5e46573ac4cb2e92f4f depends: - - libglib >=2.78.4,<3.0a0 + - libgcc-ng >=12 + - libglib >=2.80.2,<3.0a0 - libjpeg-turbo >=3.0.0,<4.0a0 - libpng >=1.6.43,<1.7.0a0 - libtiff >=4.6.0,<4.7.0a0 license: LGPL-2.1-or-later license_family: LGPL - size: 550156 - timestamp: 1710203904195 + size: 528149 + timestamp: 1715782983957 - kind: conda name: geographiclib version: '2.0' @@ -9715,7 +9668,7 @@ packages: - libcxx >=16.0.6 - libjpeg-turbo >=3.0.0,<4.0a0 - libtiff >=4.6.0,<4.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - proj >=9.3.1,<9.3.2.0a0 - zlib license: MIT @@ -9736,7 +9689,7 @@ packages: - libjpeg-turbo >=3.0.0,<4.0a0 - libstdcxx-ng >=12 - libtiff >=4.6.0,<4.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - proj >=9.3.1,<9.3.2.0a0 - zlib license: MIT @@ -9757,7 +9710,7 @@ packages: - libcxx >=16.0.6 - libjpeg-turbo >=3.0.0,<4.0a0 - libtiff >=4.6.0,<4.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - proj >=9.3.1,<9.3.2.0a0 - zlib license: MIT @@ -9776,7 +9729,7 @@ packages: depends: - libjpeg-turbo >=3.0.0,<4.0a0 - libtiff >=4.6.0,<4.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - proj >=9.3.1,<9.3.2.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 @@ -9803,27 +9756,6 @@ packages: license_family: GPL size: 21903 timestamp: 1694400856979 -- kind: conda - name: gettext - version: 0.22.5 - build: h5728263_2 - build_number: 2 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/gettext-0.22.5-h5728263_2.conda - sha256: cd4ef93fd052a4fe89a4db963c9d69e60c8a434d41968fc9dc8726db67191582 - md5: da84216f88a8c89eb943c683ceb34d7d - depends: - - gettext-tools 0.22.5 h7d00a51_2 - - libasprintf 0.22.5 h5728263_2 - - libasprintf-devel 0.22.5 h5728263_2 - - libgettextpo 0.22.5 h5728263_2 - - libgettextpo-devel 0.22.5 h5728263_2 - - libiconv >=1.17,<2.0a0 - - libintl 0.22.5 h5728263_2 - - libintl-devel 0.22.5 h5728263_2 - license: LGPL-2.1-or-later AND GPL-3.0-or-later - size: 34028 - timestamp: 1712517225377 - kind: conda name: gettext version: 0.22.5 @@ -9919,25 +9851,6 @@ packages: license_family: GPL size: 2501207 timestamp: 1712512940076 -- kind: conda - name: gettext-tools - version: 0.22.5 - build: h7d00a51_2 - build_number: 2 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/gettext-tools-0.22.5-h7d00a51_2.conda - sha256: e3621dc3d48399c89bf0dd512a6a398d354429b3b84219473d674aa56e0feef2 - md5: ef1c3bb48c013099c4872640a5f2096c - depends: - - libiconv >=1.17,<2.0a0 - - libintl 0.22.5 h5728263_2 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: GPL-3.0-or-later - license_family: GPL - size: 3415835 - timestamp: 1712516856107 - kind: conda name: gettext-tools version: 0.22.5 @@ -10002,62 +9915,62 @@ packages: timestamp: 1594303828933 - kind: conda name: gh - version: 2.49.2 + version: 2.51.0 build: h163aea0_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/gh-2.49.2-h163aea0_0.conda - sha256: 89f8afba7b3bec850e033da6001814ed3bd376d8e7c64e0d54d013de40f6d941 - md5: 8857b9e44a2435724669764082e83141 + url: https://conda.anaconda.org/conda-forge/osx-arm64/gh-2.51.0-h163aea0_0.conda + sha256: b2a98fc8ba67c7859e7061d734825a4c110df83be643981af8561603e08a94b2 + md5: 4675337bf06f8e5a4287cc1acac2bb1a depends: - __osx >=11.0 license: Apache-2.0 license_family: APACHE - size: 19995489 - timestamp: 1715692064810 + size: 20003902 + timestamp: 1718381597314 - kind: conda name: gh - version: 2.49.2 + version: 2.51.0 build: h36e2d1d_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/gh-2.49.2-h36e2d1d_0.conda - sha256: 4ddaa62af3503b38876ff485162352801dac171fb7712972dcca1ac6c114ebf6 - md5: 2450fdd43ec0041d45fb4d8170f5ac07 + url: https://conda.anaconda.org/conda-forge/win-64/gh-2.51.0-h36e2d1d_0.conda + sha256: da2b59aed685298d9d15713b8940f2a7c57a4780a2c98f67ffcdf66fffcd5a98 + md5: 552a61611a963cb12de50865b3aa7e14 depends: - ucrt >=10.0.20348.0 - vc >=14.3,<15 - - vc14_runtime >=14.38.33130 + - vc14_runtime >=14.40.33810 license: Apache-2.0 license_family: APACHE - size: 21210055 - timestamp: 1715692529530 + size: 21218150 + timestamp: 1718381892765 - kind: conda name: gh - version: 2.49.2 + version: 2.51.0 build: he0e2781_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/gh-2.49.2-he0e2781_0.conda - sha256: e820b4be62633bd4ab281096270077f5cd5b330fd89ac48bf70523a7327f6228 - md5: 6f669b0bb33b2e220527ede8e763ac80 + url: https://conda.anaconda.org/conda-forge/linux-64/gh-2.51.0-he0e2781_0.conda + sha256: 45ae3540b5e260b6784af8d5ef77fcc7231983b6d981238b97394f1a99fe0004 + md5: 0a0f4507e3943b900eb1ddf23ba6fa01 license: Apache-2.0 license_family: APACHE - size: 21230691 - timestamp: 1715691907163 + size: 21265759 + timestamp: 1718381554495 - kind: conda name: gh - version: 2.49.2 + version: 2.51.0 build: he13f2d6_0 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/gh-2.49.2-he13f2d6_0.conda - sha256: a64d1ca6629787fd2e4424edf64793c4218af1d731a29f9d28769a68af82b1d8 - md5: 90f96de87ad5b2d76f89a0d39547f537 + url: https://conda.anaconda.org/conda-forge/osx-64/gh-2.51.0-he13f2d6_0.conda + sha256: 211f46f768b43c37f30b6a94567f0cf0ac1ad437c92dcf97ef552bf8d29a0c7e + md5: dc81e125677c0ed6bf42f70e25fb34a0 depends: - __osx >=10.13 constrains: - __osx>=10.12 license: Apache-2.0 license_family: APACHE - size: 20953858 - timestamp: 1715692068822 + size: 20981076 + timestamp: 1718381438988 - kind: conda name: giflib version: 5.2.2 @@ -10227,188 +10140,187 @@ packages: - kind: conda name: glib version: 2.78.4 - build: h1059232_0 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/glib-2.78.4-h1059232_0.conda - sha256: 4e80bcda21dc40f34eeb62cefc67d0b518c93b17b66218523271db542743c2de - md5: 2f6ccb35c7f116c8c42ba24090878191 + build: h2d185b6_0 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/glib-2.78.4-h2d185b6_0.conda + sha256: 546775c50a28dcbe22b784d6cc4e8ba3774aac59517858529742657b0563c326 + md5: 0383ef91e41caea857176363c2bf7387 depends: - gettext >=0.21.1,<1.0a0 - - glib-tools 2.78.4 h1059232_0 + - glib-tools 2.78.4 h2d185b6_0 - libcxx >=16 - - libglib 2.78.4 h1635a5e_0 - - libzlib >=1.2.13,<1.3.0a0 + - libglib 2.78.4 hab64008_0 + - libzlib >=1.2.13,<2.0.0a0 - python * license: LGPL-2.1-or-later - size: 487372 - timestamp: 1708286196601 + size: 488242 + timestamp: 1708285214506 - kind: conda name: glib - version: 2.78.4 - build: h12be248_0 + version: 2.80.2 + build: h0df6a38_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/glib-2.78.4-h12be248_0.conda - sha256: 941aaf433be2b147738b4f2729008faa6639ed55b59381605f1cfb8d0dabac27 - md5: 0080f150ed83685497f841f4b70fca1f + url: https://conda.anaconda.org/conda-forge/win-64/glib-2.80.2-h0df6a38_0.conda + sha256: 8d4ebee8bfef919212e8c692f88cfa3f5f393501338ca1f1df83bbc2f0f3b6e7 + md5: a728ca6f04c33ecb0f39eeda5fbd0e23 depends: - - gettext >=0.21.1,<1.0a0 - - glib-tools 2.78.4 h12be248_0 - - libglib 2.78.4 h16e383f_0 - - libzlib >=1.2.13,<1.3.0a0 + - glib-tools 2.80.2 h2f9d560_0 + - libffi >=3.4,<4.0a0 + - libglib 2.80.2 h0df6a38_0 + - libintl >=0.22.5,<1.0a0 + - libintl-devel - python * - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 license: LGPL-2.1-or-later - size: 506268 - timestamp: 1708285308336 + size: 571410 + timestamp: 1715253202444 - kind: conda name: glib - version: 2.78.4 - build: h2d185b6_0 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/glib-2.78.4-h2d185b6_0.conda - sha256: 546775c50a28dcbe22b784d6cc4e8ba3774aac59517858529742657b0563c326 - md5: 0383ef91e41caea857176363c2bf7387 + version: 2.80.2 + build: h535f939_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/glib-2.80.2-h535f939_0.conda + sha256: 49394397c5fee963b2b5d53b954ac2de0df9e1d5dde31a2f83e66a28ddd9948d + md5: 9b69f620f2a8153ba4467fedc09e89f1 depends: - - gettext >=0.21.1,<1.0a0 - - glib-tools 2.78.4 h2d185b6_0 - - libcxx >=16 - - libglib 2.78.4 hab64008_0 - - libzlib >=1.2.13,<1.3.0a0 + - __osx >=11.0 + - glib-tools 2.80.2 h4c882b9_0 + - libffi >=3.4,<4.0a0 + - libglib 2.80.2 h535f939_0 + - libintl >=0.22.5,<1.0a0 + - libintl-devel - python * license: LGPL-2.1-or-later - size: 488242 - timestamp: 1708285214506 + size: 582907 + timestamp: 1715253076009 - kind: conda name: glib - version: 2.78.4 - build: hfc55251_0 + version: 2.80.2 + build: hf974151_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/glib-2.78.4-hfc55251_0.conda - sha256: 316c95dcbde46b7418d2b667a7e0c1d05101b673cd8c691d78d8699600a07a5b - md5: f36a7b2420c3fc3c48a3d609841d8fee + url: https://conda.anaconda.org/conda-forge/linux-64/glib-2.80.2-hf974151_0.conda + sha256: d10a0f194d2c125617352a81a4ff43a17cf5835e88e8f151da9f9710e2db176d + md5: d427988dc3dbd0a4c136f52db356cc6a depends: - - gettext >=0.21.1,<1.0a0 - - glib-tools 2.78.4 hfc55251_0 + - glib-tools 2.80.2 hb6ce0ca_0 + - libffi >=3.4,<4.0a0 - libgcc-ng >=12 - - libglib 2.78.4 h783c2da_0 - - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libglib 2.80.2 hf974151_0 - python * license: LGPL-2.1-or-later - size: 489127 - timestamp: 1708284952839 + size: 600389 + timestamp: 1715252749399 - kind: conda name: glib-tools version: 2.78.4 - build: h1059232_0 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/glib-tools-2.78.4-h1059232_0.conda - sha256: f1632c489417ba8c15098efd9f74344069ca16979a3fb86fac6d5c4eb4525c3f - md5: 101e7bcfcd49a513190a06f893053209 + build: h2d185b6_0 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/glib-tools-2.78.4-h2d185b6_0.conda + sha256: bf3d98bd8a1e0b105d124468c3ca276194c1a06ddc4a9dc44a77df65c44f8eb8 + md5: f91cde30ad552c39b485bb5ad0ce454c depends: - libcxx >=16 - - libglib 2.78.4 h1635a5e_0 - - libzlib >=1.2.13,<1.3.0a0 + - libglib 2.78.4 hab64008_0 + - libzlib >=1.2.13,<2.0.0a0 license: LGPL-2.1-or-later - size: 96889 - timestamp: 1708286050218 + size: 97529 + timestamp: 1708285134585 - kind: conda name: glib-tools - version: 2.78.4 - build: h12be248_0 + version: 2.80.2 + build: h2f9d560_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/glib-tools-2.78.4-h12be248_0.conda - sha256: 936c16a45216916d3fecce9353953bac0dcf3e24cf4999d5cab7b7e601dd274c - md5: 9e2a4c1cace3fbdeb11f20578484ddaf + url: https://conda.anaconda.org/conda-forge/win-64/glib-tools-2.80.2-h2f9d560_0.conda + sha256: 2ac7b9cf3cf57a7cec3c431133a989cc783673858fb4225232c03e5ae28bd1db + md5: 42fc785d9db7ab051a206fbf882ecf2e depends: - - libglib 2.78.4 h16e383f_0 - - libzlib >=1.2.13,<1.3.0a0 + - libglib 2.80.2 h0df6a38_0 + - libintl >=0.22.5,<1.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 license: LGPL-2.1-or-later - size: 145970 - timestamp: 1708285241564 + size: 94852 + timestamp: 1715253157140 - kind: conda name: glib-tools - version: 2.78.4 - build: h2d185b6_0 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/glib-tools-2.78.4-h2d185b6_0.conda - sha256: bf3d98bd8a1e0b105d124468c3ca276194c1a06ddc4a9dc44a77df65c44f8eb8 - md5: f91cde30ad552c39b485bb5ad0ce454c + version: 2.80.2 + build: h4c882b9_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/glib-tools-2.80.2-h4c882b9_0.conda + sha256: ca3e432221f78abfa0f4401ab340a018ad13f8ef1a2bb4b95978a620b2006e87 + md5: cbb22f46214f22c8e73c09175f516fab depends: - - libcxx >=16 - - libglib 2.78.4 hab64008_0 - - libzlib >=1.2.13,<1.3.0a0 + - __osx >=11.0 + - libglib 2.80.2 h535f939_0 + - libintl >=0.22.5,<1.0a0 license: LGPL-2.1-or-later - size: 97529 - timestamp: 1708285134585 + size: 98331 + timestamp: 1715253041090 - kind: conda name: glib-tools - version: 2.78.4 - build: hfc55251_0 + version: 2.80.2 + build: hb6ce0ca_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.78.4-hfc55251_0.conda - sha256: e94494b895f77ba54922ffb1dcfb7f1a987591b823eb5ce608afb2e2391d7d82 - md5: d184ba1bf15a2bbb3be6118c90fd487d + url: https://conda.anaconda.org/conda-forge/linux-64/glib-tools-2.80.2-hb6ce0ca_0.conda + sha256: 221cd047f998301b96b1517d9f7d3fb0e459e8ee18778a1211f302496f6e110d + md5: a965aeaf060289528a3fbe09326edae2 depends: - libgcc-ng >=12 - - libglib 2.78.4 h783c2da_0 - - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libglib 2.80.2 hf974151_0 license: LGPL-2.1-or-later - size: 111383 - timestamp: 1708284914557 + size: 114359 + timestamp: 1715252713902 - kind: conda name: glog - version: 0.7.0 - build: h31b1b29_0 + version: 0.7.1 + build: h2790a97_0 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/glog-0.7.0-h31b1b29_0.conda - sha256: 49d39c6b0c38d9f2badfc37450ea45a40493669561d588ee81d9e5b7ed4478b7 - md5: bda05f8f4c205124348c764dd82db33a + url: https://conda.anaconda.org/conda-forge/osx-64/glog-0.7.1-h2790a97_0.conda + sha256: dd56547db8625eb5c91bb0a9fbe8bd6f5c7fbf5b6059d46365e94472c46b24f9 + md5: 06cf91665775b0da395229cd4331b27d depends: - - __osx >=10.12 + - __osx >=10.13 - gflags >=2.2.2,<2.3.0a0 - libcxx >=16 license: BSD-3-Clause license_family: BSD - size: 115506 - timestamp: 1708261022187 + size: 117017 + timestamp: 1718284325443 - kind: conda name: glog - version: 0.7.0 - build: hc6770e3_0 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/glog-0.7.0-hc6770e3_0.conda - sha256: eba67027affe097ef11e4e9ffbb131a5b2ca3494d1b50e5cc1dd337813b1ab5c - md5: 359f6720ba65b7a38b46a85d5ae13338 + version: 0.7.1 + build: hbabe93e_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.1-hbabe93e_0.conda + sha256: dc824dc1d0aa358e28da2ecbbb9f03d932d976c8dca11214aa1dcdfcbd054ba2 + md5: ff862eebdfeb2fd048ae9dc92510baca depends: - gflags >=2.2.2,<2.3.0a0 - - libcxx >=16 + - libgcc-ng >=12 + - libstdcxx-ng >=12 license: BSD-3-Clause license_family: BSD - size: 110059 - timestamp: 1708261049813 + size: 143452 + timestamp: 1718284177264 - kind: conda name: glog - version: 0.7.0 - build: hed5481d_0 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/glog-0.7.0-hed5481d_0.conda - sha256: 19f41db8f189ed9caec68ffb9ec97d5518b5ee6b58e0636d185f392f688a84a1 - md5: a9ea19c48e11754899299f8123070f4e + version: 0.7.1 + build: heb240a5_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/glog-0.7.1-heb240a5_0.conda + sha256: 9fc77de416953aa959039db72bc41bfa4600ae3ff84acad04a7d0c1ab9552602 + md5: fef68d0a95aa5b84b5c1a4f6f3bf40e1 depends: + - __osx >=11.0 - gflags >=2.2.2,<2.3.0a0 - - libgcc-ng >=12 - - libstdcxx-ng >=12 + - libcxx >=16 license: BSD-3-Clause license_family: BSD - size: 143596 - timestamp: 1708260910243 + size: 112215 + timestamp: 1718284365403 - kind: conda name: gmp version: 6.3.0 @@ -10469,7 +10381,7 @@ packages: - libjpeg-turbo >=3.0.0,<4.0a0 - liblapack >=3.9.0,<4.0a0 - libpng >=1.6.39,<1.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - occt >=7.7.2,<7.8.0a0 - zlib license: GPL-2.0-or-later @@ -10497,7 +10409,7 @@ packages: - liblapack >=3.9.0,<4.0a0 - libpng >=1.6.39,<1.7.0a0 - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - occt >=7.7.2,<7.8.0a0 - xorg-libx11 >=1.8.7,<2.0a0 - xorg-libxext >=1.3.4,<2.0a0 @@ -10526,7 +10438,7 @@ packages: - libjpeg-turbo >=3.0.0,<4.0a0 - liblapack >=3.9.0,<4.0a0 - libpng >=1.6.39,<1.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - occt >=7.7.2,<7.8.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 @@ -10555,7 +10467,7 @@ packages: - libjpeg-turbo >=3.0.0,<4.0a0 - liblapack >=3.9.0,<4.0a0 - libpng >=1.6.39,<1.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - occt >=7.7.2,<7.8.0a0 - zlib license: GPL-2.0-or-later @@ -10689,12 +10601,12 @@ packages: - kind: conda name: graphviz version: 9.0.0 - build: h3face73_1 + build: hee74176_1 build_number: 1 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/graphviz-9.0.0-h3face73_1.conda - sha256: af4c47cf50fa0b9dbe39a0dfdcd26e1b1127fcf6d3cdd37cbb860c5a276aa57e - md5: 0a0e14b01da92c28f763123d146168a6 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/graphviz-9.0.0-hee74176_1.conda + sha256: 3080dc2f9ea708af0ea94d49348cff05884a149214a5e225e9647eff4cdac849 + md5: 7cd479251093c332aa9fe93cfb8f698b depends: - __osx >=10.9 - cairo >=1.18.0,<2.0a0 @@ -10708,138 +10620,91 @@ packages: - libglib >=2.78.1,<3.0a0 - librsvg >=2.56.3,<3.0a0 - libwebp-base >=1.3.2,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - pango >=1.50.14,<2.0a0 license: EPL-1.0 license_family: Other - size: 4613242 - timestamp: 1700902036256 + size: 4712901 + timestamp: 1700901972742 - kind: conda name: graphviz - version: 9.0.0 - build: h51cb2cd_1 - build_number: 1 + version: 11.0.0 + build: h09e431a_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/graphviz-9.0.0-h51cb2cd_1.conda - sha256: 6ec8b6be4e155b1928340961d4806460a21f55709aa092d90695eb531c1d145e - md5: 9e73e70557ae3c1c9d4bdf70f47dd141 + url: https://conda.anaconda.org/conda-forge/win-64/graphviz-11.0.0-h09e431a_0.conda + sha256: 9a41d852f32f5654980492934cc547776b94b3910e5c86beff3cb58eeddd08a5 + md5: c6c2ec410aa5e77e09948bf7a4367c00 depends: - cairo >=1.18.0,<2.0a0 - getopt-win32 >=0.1,<0.2.0a0 - gts >=0.7.6,<0.8.0a0 - - libexpat >=2.5.0,<3.0a0 + - libexpat >=2.6.2,<3.0a0 - libgd >=2.3.3,<2.4.0a0 - - libglib >=2.78.1,<3.0a0 - - libwebp-base >=1.3.2,<2.0a0 + - libglib >=2.80.2,<3.0a0 + - libwebp-base >=1.4.0,<2.0a0 + - libzlib >=1.2.13,<2.0.0a0 - pango >=1.50.14,<2.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 license: EPL-1.0 license_family: Other - size: 1134308 - timestamp: 1700902326239 + size: 1161689 + timestamp: 1716134918752 - kind: conda name: graphviz - version: 9.0.0 - build: h78e8752_1 - build_number: 1 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/graphviz-9.0.0-h78e8752_1.conda - sha256: 1813800d655c120a3941d543a6fc64e3c178c737f1c84f6b7ebe1f19f27fa4fb - md5: a3f4cd4a512ec5db35ffbf25ba11f537 + version: 11.0.0 + build: h9bb9bc9_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/graphviz-11.0.0-h9bb9bc9_0.conda + sha256: ced49a72b8f3c92a76d3f07bb75be2a64d3572d433f2711d36003e1b565d1d4e + md5: c004a0e5dfbe0ce38af9ab4684abd236 depends: + - __osx >=11.0 - cairo >=1.18.0,<2.0a0 - fonts-conda-ecosystem - - gdk-pixbuf >=2.42.10,<3.0a0 + - gdk-pixbuf >=2.42.12,<3.0a0 - gtk2 - gts >=0.7.6,<0.8.0a0 - - libexpat >=2.5.0,<3.0a0 - - libgcc-ng >=12 + - libcxx >=16 + - libexpat >=2.6.2,<3.0a0 - libgd >=2.3.3,<2.4.0a0 - - libglib >=2.78.1,<3.0a0 - - librsvg >=2.56.3,<3.0a0 - - libstdcxx-ng >=12 - - libwebp-base >=1.3.2,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libglib >=2.80.2,<3.0a0 + - librsvg >=2.58.0,<3.0a0 + - libwebp-base >=1.4.0,<2.0a0 + - libzlib >=1.2.13,<2.0.0a0 - pango >=1.50.14,<2.0a0 license: EPL-1.0 license_family: Other - size: 2310834 - timestamp: 1700901584973 + size: 5047991 + timestamp: 1716134413760 - kind: conda name: graphviz - version: 9.0.0 - build: hee74176_1 - build_number: 1 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/graphviz-9.0.0-hee74176_1.conda - sha256: 3080dc2f9ea708af0ea94d49348cff05884a149214a5e225e9647eff4cdac849 - md5: 7cd479251093c332aa9fe93cfb8f698b + version: 11.0.0 + build: hc68bbd7_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/graphviz-11.0.0-hc68bbd7_0.conda + sha256: 7e7ca0901c0d2de455718ec7a0974e2091c38e608f90a4ba98084e4902d93c17 + md5: 52a531ef95358086a56086c45d97ab75 depends: - - __osx >=10.9 - cairo >=1.18.0,<2.0a0 - fonts-conda-ecosystem - - gdk-pixbuf >=2.42.10,<3.0a0 + - gdk-pixbuf >=2.42.12,<3.0a0 - gtk2 - gts >=0.7.6,<0.8.0a0 - - libcxx >=16.0.6 - - libexpat >=2.5.0,<3.0a0 + - libexpat >=2.6.2,<3.0a0 + - libgcc-ng >=12 - libgd >=2.3.3,<2.4.0a0 - - libglib >=2.78.1,<3.0a0 - - librsvg >=2.56.3,<3.0a0 - - libwebp-base >=1.3.2,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libglib >=2.80.2,<3.0a0 + - librsvg >=2.58.0,<3.0a0 + - libstdcxx-ng >=12 + - libwebp-base >=1.4.0,<2.0a0 + - libzlib >=1.2.13,<2.0.0a0 - pango >=1.50.14,<2.0a0 license: EPL-1.0 license_family: Other - size: 4712901 - timestamp: 1700901972742 -- kind: conda - name: gst-plugins-base - version: 1.22.9 - build: h001b923_1 - build_number: 1 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/gst-plugins-base-1.22.9-h001b923_1.conda - sha256: e2c37128de5bdc12e3656c9c50e7b1459d8890ea656b866e68293e334356b652 - md5: ef961ec5b46ac75cebd3d68460691c27 - depends: - - gettext >=0.21.1,<1.0a0 - - gstreamer 1.22.9 hb4038d2_1 - - libglib >=2.78.4,<3.0a0 - - libogg >=1.3.4,<1.4.0a0 - - libvorbis >=1.3.7,<1.4.0a0 - - libzlib >=1.2.13,<1.3.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: LGPL-2.0-or-later - license_family: LGPL - size: 2035564 - timestamp: 1711211913043 -- kind: conda - name: gst-plugins-base - version: 1.22.9 - build: h09b4b5e_0 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/gst-plugins-base-1.22.9-h09b4b5e_0.conda - sha256: 8856911ccef5b9829601b08f19c7353cd5b86c8e58e87d7eb30d0511a2e23689 - md5: de6c7944b3378db095218f0c76f0a054 - depends: - - gettext >=0.21.1,<1.0a0 - - gstreamer 1.22.9 h551c6ff_0 - - libcxx >=15 - - libglib >=2.78.3,<3.0a0 - - libogg >=1.3.4,<1.4.0a0 - - libopus >=1.3.1,<2.0a0 - - libpng >=1.6.39,<1.7.0a0 - - libvorbis >=1.3.7,<1.4.0a0 - - libzlib >=1.2.13,<1.3.0a0 - license: LGPL-2.0-or-later - license_family: LGPL - size: 1917386 - timestamp: 1706155193009 + size: 2304422 + timestamp: 1716134196230 - kind: conda name: gst-plugins-base version: 1.22.9 @@ -10857,50 +10722,94 @@ packages: - libopus >=1.3.1,<2.0a0 - libpng >=1.6.39,<1.7.0a0 - libvorbis >=1.3.7,<1.4.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: LGPL-2.0-or-later license_family: LGPL size: 2344738 timestamp: 1706155251056 - kind: conda name: gst-plugins-base - version: 1.22.9 - build: h8e1006c_0 + version: 1.24.4 + build: h8a8f8c8_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/gst-plugins-base-1.24.4-h8a8f8c8_0.conda + sha256: fafe0f33831a3bbb963f654c4f7a02a555591ee176de06d57cc16c82a2569885 + md5: 05d2fa13307d6e949f883b9de658e154 + depends: + - __osx >=11.0 + - gstreamer 1.24.4 h430e707_0 + - libcxx >=16 + - libglib >=2.80.2,<3.0a0 + - libintl >=0.22.5,<1.0a0 + - libogg >=1.3.4,<1.4.0a0 + - libopus >=1.3.1,<2.0a0 + - libpng >=1.6.43,<1.7.0a0 + - libvorbis >=1.3.7,<1.4.0a0 + - libzlib >=1.2.13,<2.0a0 + license: LGPL-2.0-or-later + license_family: LGPL + size: 1963869 + timestamp: 1717008851890 +- kind: conda + name: gst-plugins-base + version: 1.24.4 + build: h9ad1361_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.22.9-h8e1006c_0.conda - sha256: a4312c96a670fdbf9ff0c3efd935e42fa4b655ff33dcc52c309b76a2afaf03f0 - md5: 614b81f8ed66c56b640faee7076ad14a + url: https://conda.anaconda.org/conda-forge/linux-64/gst-plugins-base-1.24.4-h9ad1361_0.conda + sha256: 4726f1905bbc84b44c8a78a53c0b2bc20b0f6780614b897e83bdfb9f1f94e9d5 + md5: 147cce520ec59367549fd0d96d404213 depends: - __glibc >=2.17,<3.0.a0 - - alsa-lib >=1.2.10,<1.3.0.0a0 - - gettext >=0.21.1,<1.0a0 - - gstreamer 1.22.9 h98fc4e7_0 - - libexpat >=2.5.0,<3.0a0 + - alsa-lib >=1.2.11,<1.3.0a0 + - gstreamer 1.24.4 haf2f30d_0 + - libexpat >=2.6.2,<3.0a0 - libgcc-ng >=12 - - libglib >=2.78.3,<3.0a0 + - libglib >=2.80.2,<3.0a0 - libogg >=1.3.4,<1.4.0a0 - libopus >=1.3.1,<2.0a0 - - libpng >=1.6.39,<1.7.0a0 + - libpng >=1.6.43,<1.7.0a0 - libstdcxx-ng >=12 - libvorbis >=1.3.7,<1.4.0a0 - libxcb >=1.15,<1.16.0a0 - - libzlib >=1.2.13,<1.3.0a0 - - xorg-libx11 >=1.8.7,<2.0a0 + - libzlib >=1.2.13,<2.0a0 + - xorg-libx11 >=1.8.9,<2.0a0 - xorg-libxau >=1.0.11,<2.0a0 - xorg-libxext >=1.3.4,<2.0a0 - xorg-libxrender >=0.9.11,<0.10.0a0 license: LGPL-2.0-or-later license_family: LGPL - size: 2709696 - timestamp: 1706154948546 + size: 2784812 + timestamp: 1717008701241 +- kind: conda + name: gst-plugins-base + version: 1.24.4 + build: hba88be7_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/gst-plugins-base-1.24.4-hba88be7_0.conda + sha256: 76ad01a5d20a37f0113fedd79ee74cc9d9fff24bf8e396ce2f70a7d358de6b13 + md5: 0b1d683d462029446924fa87a50dda12 + depends: + - gstreamer 1.24.4 h5006eae_0 + - libglib >=2.80.2,<3.0a0 + - libintl >=0.22.5,<1.0a0 + - libogg >=1.3.4,<1.4.0a0 + - libvorbis >=1.3.7,<1.4.0a0 + - libzlib >=1.2.13,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: LGPL-2.0-or-later + license_family: LGPL + size: 2065294 + timestamp: 1717009247100 - kind: conda name: gstreamer version: 1.22.9 - build: h551c6ff_0 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/gstreamer-1.22.9-h551c6ff_0.conda - sha256: 9c4944fe57ceddaf007abe4cec9a28486186bf25535ef176f089bc6cb24efe45 - md5: f5025efbcae14c20393d6e55eef2e1b4 + build: hf63bbb8_0 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/gstreamer-1.22.9-hf63bbb8_0.conda + sha256: be9d64972f997e1f865673cbb059a8c653f1fb38ff5e6c6a049699823bad0d9f + md5: 1581bb03c4655191284a3eab9ee8690d depends: - gettext >=0.21.1,<1.0a0 - glib >=2.78.3,<3.0a0 @@ -10909,67 +10818,66 @@ packages: - libiconv >=1.17,<2.0a0 license: LGPL-2.0-or-later license_family: LGPL - size: 1344295 - timestamp: 1706154905073 + size: 1781693 + timestamp: 1706154946526 - kind: conda name: gstreamer - version: 1.22.9 - build: h98fc4e7_0 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.22.9-h98fc4e7_0.conda - sha256: aa2395bf1790f72d2706bac77430f765ec1318ca22e60e791c13ae452c045263 - md5: bcc7157b06fce7f5e055402a8135dfd8 + version: 1.24.4 + build: h430e707_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/gstreamer-1.24.4-h430e707_0.conda + sha256: 607113a57f64eed2a4e6bc254620e93ca66d23466beb1c79b78ac3059156143c + md5: 73dec96255be4192c5de3b26e94ef995 depends: - - __glibc >=2.17,<3.0.a0 - - gettext >=0.21.1,<1.0a0 - - glib >=2.78.3,<3.0a0 - - libgcc-ng >=12 - - libglib >=2.78.3,<3.0a0 + - __osx >=11.0 + - glib >=2.80.2,<3.0a0 + - libcxx >=16 + - libglib >=2.80.2,<3.0a0 - libiconv >=1.17,<2.0a0 - - libstdcxx-ng >=12 + - libintl >=0.22.5,<1.0a0 license: LGPL-2.0-or-later license_family: LGPL - size: 1981554 - timestamp: 1706154826325 + size: 1352411 + timestamp: 1717008621458 - kind: conda name: gstreamer - version: 1.22.9 - build: hb4038d2_1 - build_number: 1 + version: 1.24.4 + build: h5006eae_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/gstreamer-1.22.9-hb4038d2_1.conda - sha256: 4d42bc24434db62c093748ea3ad0b6ba3872b6810b761363585513ebd79b4f87 - md5: 70557ab875e72c1f21e8d2351aeb9c54 + url: https://conda.anaconda.org/conda-forge/win-64/gstreamer-1.24.4-h5006eae_0.conda + sha256: 6653ba5b7f698020a6278fc12afd41b8f76b7477af4a5eb732ff0b8fafaa1b0a + md5: 3d7ebad364d5f63a1ae54eecb35aee31 depends: - - gettext >=0.21.1,<1.0a0 - - glib >=2.78.4,<3.0a0 - - libglib >=2.78.4,<3.0a0 + - glib >=2.80.2,<3.0a0 + - libglib >=2.80.2,<3.0a0 - libiconv >=1.17,<2.0a0 + - libintl >=0.22.5,<1.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 license: LGPL-2.0-or-later license_family: LGPL - size: 1936661 - timestamp: 1711211717228 + size: 2029614 + timestamp: 1717009051538 - kind: conda name: gstreamer - version: 1.22.9 - build: hf63bbb8_0 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/gstreamer-1.22.9-hf63bbb8_0.conda - sha256: be9d64972f997e1f865673cbb059a8c653f1fb38ff5e6c6a049699823bad0d9f - md5: 1581bb03c4655191284a3eab9ee8690d + version: 1.24.4 + build: haf2f30d_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/gstreamer-1.24.4-haf2f30d_0.conda + sha256: d20031196ed30ee5eb1e225f6cf0ed605d95158612589602a9d893a7386a4608 + md5: 926c2c7ee7a0b48d6d70783a33f7bc80 depends: - - gettext >=0.21.1,<1.0a0 - - glib >=2.78.3,<3.0a0 - - libcxx >=15 - - libglib >=2.78.3,<3.0a0 + - __glibc >=2.17,<3.0.a0 + - glib >=2.80.2,<3.0a0 + - libgcc-ng >=12 + - libglib >=2.80.2,<3.0a0 - libiconv >=1.17,<2.0a0 + - libstdcxx-ng >=12 license: LGPL-2.0-or-later license_family: LGPL - size: 1781693 - timestamp: 1706154946526 + size: 2019311 + timestamp: 1717008522417 - kind: conda name: gtk2 version: 2.24.33 @@ -11141,84 +11049,84 @@ packages: - kind: conda name: harfbuzz version: 8.3.0 - build: h3d44ed6_0 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-8.3.0-h3d44ed6_0.conda - sha256: 4b55aea03b18a4084b750eee531ad978d4a3690f63019132c26c6ad26bbe3aed - md5: 5a6f6c00ef982a9bc83558d9ac8f64a0 + build: hf45c392_0 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/harfbuzz-8.3.0-hf45c392_0.conda + sha256: c6ea14e4f4869bc78b27276c09832af845dfa415585362ed6064e37a1b5fe9c5 + md5: 41d890485f909e4ecdc608741718c75e depends: + - __osx >=10.9 - cairo >=1.18.0,<2.0a0 - freetype >=2.12.1,<3.0a0 - graphite2 - icu >=73.2,<74.0a0 - - libgcc-ng >=12 + - libcxx >=16.0.6 - libglib >=2.78.1,<3.0a0 - - libstdcxx-ng >=12 license: MIT license_family: MIT - size: 1547473 - timestamp: 1699925311766 + size: 1342172 + timestamp: 1699925847743 - kind: conda name: harfbuzz - version: 8.3.0 - build: h7ab893a_0 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/harfbuzz-8.3.0-h7ab893a_0.conda - sha256: 5365595303d95810d10662b46f9e857cedc82757cc7b5576bda30e15d66bb3ad - md5: b8ef0beb91df83c5e6038c9509b9f730 + version: 8.5.0 + build: h1836168_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/harfbuzz-8.5.0-h1836168_0.conda + sha256: 91121ed30fa7d775f1cf7ae5de2f7852d66a604269509c4bb108b143315d8321 + md5: aa22b942b980c17612d344adcd0f8798 depends: + - __osx >=11.0 - cairo >=1.18.0,<2.0a0 - freetype >=2.12.1,<3.0a0 - graphite2 - icu >=73.2,<74.0a0 - - libglib >=2.78.1,<3.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - libcxx >=16 + - libglib >=2.80.2,<3.0a0 license: MIT license_family: MIT - size: 1070592 - timestamp: 1699926990335 + size: 1320454 + timestamp: 1715701618297 - kind: conda name: harfbuzz - version: 8.3.0 - build: h8f0ba13_0 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/harfbuzz-8.3.0-h8f0ba13_0.conda - sha256: 55e95aee9e5be7ada5a1cccedf1bb74c1362a7504cb0251fb48bcfa8bbd7cae3 - md5: 71e7f9ba27feae122733bb9f1bfe594c + version: 8.5.0 + build: h81778c3_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/harfbuzz-8.5.0-h81778c3_0.conda + sha256: f633a33dfe5c799a571af41e3515fc706a6f4988701d39e7b5d37811a1745bb9 + md5: 2ff854071c04998038c0e1db4c9232f7 depends: - - __osx >=10.9 - cairo >=1.18.0,<2.0a0 - freetype >=2.12.1,<3.0a0 - graphite2 - icu >=73.2,<74.0a0 - - libcxx >=16.0.6 - - libglib >=2.78.1,<3.0a0 + - libglib >=2.80.2,<3.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: MIT license_family: MIT - size: 1295036 - timestamp: 1699925935335 + size: 1098168 + timestamp: 1715702362769 - kind: conda name: harfbuzz - version: 8.3.0 - build: hf45c392_0 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/harfbuzz-8.3.0-hf45c392_0.conda - sha256: c6ea14e4f4869bc78b27276c09832af845dfa415585362ed6064e37a1b5fe9c5 - md5: 41d890485f909e4ecdc608741718c75e + version: 8.5.0 + build: hfac3d4d_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/harfbuzz-8.5.0-hfac3d4d_0.conda + sha256: a141fc55f8bfdab7db03fe9d8e61cb0f8c8b5970ed6540eda2db7186223f4444 + md5: f5126317dd0ce0ba26945e411ecc6960 depends: - - __osx >=10.9 - cairo >=1.18.0,<2.0a0 - freetype >=2.12.1,<3.0a0 - graphite2 - icu >=73.2,<74.0a0 - - libcxx >=16.0.6 - - libglib >=2.78.1,<3.0a0 + - libgcc-ng >=12 + - libglib >=2.80.2,<3.0a0 + - libstdcxx-ng >=12 license: MIT license_family: MIT - size: 1342172 - timestamp: 1699925847743 + size: 1598244 + timestamp: 1715701061364 - kind: conda name: hatchling version: 1.24.2 @@ -11256,7 +11164,7 @@ packages: - libgcc-ng >=12 - libjpeg-turbo >=3.0.0,<4.0a0 - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: BSD-3-Clause license_family: BSD size: 756742 @@ -11273,7 +11181,7 @@ packages: depends: - libcxx >=15.0.7 - libjpeg-turbo >=3.0.0,<4.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: BSD-3-Clause license_family: BSD size: 762257 @@ -11289,7 +11197,7 @@ packages: md5: 84344a916a73727c1326841007b52ca8 depends: - libjpeg-turbo >=3.0.0,<4.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 @@ -11309,7 +11217,7 @@ packages: depends: - libcxx >=15.0.7 - libjpeg-turbo >=3.0.0,<4.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: BSD-3-Clause license_family: BSD size: 724103 @@ -11317,90 +11225,92 @@ packages: - kind: conda name: hdf5 version: 1.14.3 - build: nompi_h4f84152_101 - build_number: 101 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/hdf5-1.14.3-nompi_h4f84152_101.conda - sha256: e7d2591bc77d47e9f3fc57d94a817dc9385f4079d930a93475fe45aa2ba81d47 - md5: 7e98860d08eea82c8057abd78864fcb4 - depends: - - libaec >=1.1.3,<2.0a0 - - libcurl >=8.7.1,<9.0a0 - - libgcc-ng >=12 - - libgfortran-ng - - libgfortran5 >=12.3.0 - - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 - - openssl >=3.3.0,<4.0a0 - license: BSD-3-Clause - license_family: BSD - size: 3884115 - timestamp: 1714575562551 -- kind: conda - name: hdf5 - version: 1.14.3 - build: nompi_h73e8ff5_101 - build_number: 101 + build: nompi_h2b43c12_105 + build_number: 105 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/hdf5-1.14.3-nompi_h73e8ff5_101.conda - sha256: b4d50137e1f2f2b62e4da626ee64f9233457fef3de62c3a8dbd01f41cf2cebe4 - md5: b746fce22796d2e2d8b37bdd45d12d78 + url: https://conda.anaconda.org/conda-forge/win-64/hdf5-1.14.3-nompi_h2b43c12_105.conda + sha256: 56c803607a64b5117a8b4bcfdde722e4fa40970ddc4c61224b0981cbb70fb005 + md5: 5788de34381caf624b78c4981618dc0a depends: - libaec >=1.1.3,<2.0a0 - - libcurl >=8.7.1,<9.0a0 - - libzlib >=1.2.13,<1.3.0a0 - - openssl >=3.3.0,<4.0a0 + - libcurl >=8.8.0,<9.0a0 + - libzlib >=1.2.13,<2.0a0 + - openssl >=3.3.1,<4.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 license: BSD-3-Clause license_family: BSD - size: 2041847 - timestamp: 1714575202830 + size: 2039111 + timestamp: 1717587493910 - kind: conda name: hdf5 version: 1.14.3 - build: nompi_h751145d_101 - build_number: 101 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/hdf5-1.14.3-nompi_h751145d_101.conda - sha256: a3dddabbcf7be15cf363b5583c0dcaaeedf688e864894cd0531b716627c7707f - md5: f5b2b516eb1eabe3897e9fc5f958f4af + build: nompi_h687a608_105 + build_number: 105 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/hdf5-1.14.3-nompi_h687a608_105.conda + sha256: 98f8350730d09e8ad7b62ca6d6be38ee2324b11bbcd1a5fe2cac619b12cd68d7 + md5: 98544299f6bb2ef4d7362506a3dde886 depends: + - __osx >=10.13 - libaec >=1.1.3,<2.0a0 - - libcurl >=8.7.1,<9.0a0 + - libcurl >=8.8.0,<9.0a0 - libcxx >=16 - libgfortran 5.* - libgfortran5 >=12.3.0 - libgfortran5 >=13.2.0 - - libzlib >=1.2.13,<1.3.0a0 - - openssl >=3.3.0,<4.0a0 + - libzlib >=1.2.13,<2.0a0 + - openssl >=3.3.1,<4.0a0 license: BSD-3-Clause license_family: BSD - size: 3460229 - timestamp: 1714575369873 + size: 3733954 + timestamp: 1717588360008 - kind: conda name: hdf5 version: 1.14.3 - build: nompi_hb512a33_101 - build_number: 101 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/hdf5-1.14.3-nompi_hb512a33_101.conda - sha256: f3b120d80d47ae9d081d950ac4f568f806d62b40385e23fb743cf351596cbeb3 - md5: d0138c4f90c0d206e0d8a7a8f7d2882e + build: nompi_hdf9ad27_105 + build_number: 105 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/hdf5-1.14.3-nompi_hdf9ad27_105.conda + sha256: 2278fa07da6f96e807d402cd55480624d67d2dee202191aaaf278ce5ab23605a + md5: 7e1729554e209627636a0f6fabcdd115 depends: - libaec >=1.1.3,<2.0a0 - - libcurl >=8.7.1,<9.0a0 + - libcurl >=8.8.0,<9.0a0 + - libgcc-ng >=12 + - libgfortran-ng + - libgfortran5 >=12.3.0 + - libstdcxx-ng >=12 + - libzlib >=1.2.13,<2.0a0 + - openssl >=3.3.1,<4.0a0 + license: BSD-3-Clause + license_family: BSD + size: 3911675 + timestamp: 1717587866574 +- kind: conda + name: hdf5 + version: 1.14.3 + build: nompi_hec07895_105 + build_number: 105 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/hdf5-1.14.3-nompi_hec07895_105.conda + sha256: 5d87a1b63862e7da78c7bd9c17dea3526c0462c11df9004943cfa4569cc25dd3 + md5: f9c8c7304d52c8846eab5d6c34219812 + depends: + - __osx >=11.0 + - libaec >=1.1.3,<2.0a0 + - libcurl >=8.8.0,<9.0a0 - libcxx >=16 - libgfortran 5.* - libgfortran5 >=12.3.0 - libgfortran5 >=13.2.0 - - libzlib >=1.2.13,<1.3.0a0 - - openssl >=3.3.0,<4.0a0 + - libzlib >=1.2.13,<2.0a0 + - openssl >=3.3.1,<4.0a0 license: BSD-3-Clause license_family: BSD - size: 3738247 - timestamp: 1714576725695 + size: 3445248 + timestamp: 1717587775787 - kind: conda name: hpack version: 4.0.0 @@ -11481,13 +11391,13 @@ packages: timestamp: 1619110249723 - kind: conda name: hypothesis - version: 6.102.6 + version: 6.103.2 build: pyha770c72_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.102.6-pyha770c72_0.conda - sha256: f1d77ab1e3492fdeb821c7b25475ae0f46f9166d335dfd28f068b0e5e7c1ab72 - md5: a00817ace8643038bbe6a08508cc4970 + url: https://conda.anaconda.org/conda-forge/noarch/hypothesis-6.103.2-pyha770c72_0.conda + sha256: 6af1b27ff33740b9d52365fb6e76cb91bb64c98e1296edf9e0716825a68c9ec6 + md5: 995931bf54e37308520c97113785e9b8 depends: - attrs >=19.2.0 - backports.zoneinfo >=0.2.1 @@ -11497,11 +11407,10 @@ packages: - setuptools - sortedcontainers >=2.1.0,<3.0.0 license: MPL-2.0 - license_family: MOZILLA purls: - pkg:pypi/hypothesis - size: 330506 - timestamp: 1716516895176 + size: 330649 + timestamp: 1718419599719 - kind: conda name: icu version: '73.2' @@ -11601,7 +11510,7 @@ packages: md5: e95ef5164e69abc370842b41438065fa depends: - libcxx >=16 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: BSD-3-Clause license_family: BSD size: 154276 @@ -11615,7 +11524,7 @@ packages: sha256: fa7e36df9074ac6d1e67bd655a784b280e83d1cbac24fecdc5c21c716b832809 md5: c6849d593fda3d4992a8126d251f50c3 depends: - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 @@ -11633,7 +11542,7 @@ packages: md5: 39c1f288d263e971db74f8803e28dabd depends: - libcxx >=16 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: BSD-3-Clause license_family: BSD size: 155338 @@ -11649,7 +11558,7 @@ packages: depends: - libgcc-ng >=12 - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: BSD-3-Clause license_family: BSD size: 162530 @@ -11739,16 +11648,15 @@ packages: timestamp: 1716560867765 - kind: conda name: ipykernel - version: 6.29.3 - build: pyh3cd1d5f_0 + version: 6.29.4 + build: pyh3099207_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.3-pyh3cd1d5f_0.conda - sha256: ef2f9c1d83afd693db3793c368c5c6afcd37a416958ece490a2e1fbcd85012eb - md5: 28e74fca8d8abf09c1ed0d190a17e307 + url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.4-pyh3099207_0.conda + sha256: 202ab54ddc21011bf7ed7c8fa705767c9e7735a52281b010516faf3924bf0584 + md5: 36baf4c745655019de1f29df2535a72b depends: - - __osx - - appnope + - __linux - comm >=0.1.1 - debugpy >=1.6.5 - ipython >=7.23.1 @@ -11766,17 +11674,17 @@ packages: license_family: BSD purls: - pkg:pypi/ipykernel - size: 119602 - timestamp: 1708996878886 + size: 119357 + timestamp: 1717717635566 - kind: conda name: ipykernel - version: 6.29.3 - build: pyha63f2e9_0 + version: 6.29.4 + build: pyh4bbf305_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.3-pyha63f2e9_0.conda - sha256: 93ff46322a2512e9fb4ba456b1f0120d2f628a4b851f3102561a351e528d24d0 - md5: d86f243bdd45a8019050e7326ed7bb2e + url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.4-pyh4bbf305_0.conda + sha256: c97cda9457c782ef6e52ec45ce48bd4a36cfa6ae1546b1de99b5cedc467dc341 + md5: 899877a9ae762c02f2142b0531bee6a4 depends: - __win - comm >=0.1.1 @@ -11796,19 +11704,20 @@ packages: license_family: BSD purls: - pkg:pypi/ipykernel - size: 119670 - timestamp: 1708996955969 + size: 119848 + timestamp: 1717717929035 - kind: conda name: ipykernel - version: 6.29.3 - build: pyhd33586a_0 + version: 6.29.4 + build: pyh57ce528_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.3-pyhd33586a_0.conda - sha256: 0314f15e666fd9a4fb653aae37d2cf4dc6bc3a18c0d9c2671a6a0783146adcfa - md5: e0deff12c601ce5cb7476f93718f3168 + url: https://conda.anaconda.org/conda-forge/noarch/ipykernel-6.29.4-pyh57ce528_0.conda + sha256: 634d840cf7ab02a31b164f7eca0e855b2b9aa9b3aff52a64b758bbbaf44a31de + md5: 1e991f9ed4a81d3482d46edbeb54721a depends: - - __linux + - __osx + - appnope - comm >=0.1.1 - debugpy >=1.6.5 - ipython >=7.23.1 @@ -11826,17 +11735,17 @@ packages: license_family: BSD purls: - pkg:pypi/ipykernel - size: 119050 - timestamp: 1708996727913 + size: 119929 + timestamp: 1717717677848 - kind: conda name: ipython - version: 8.24.0 + version: 8.25.0 build: pyh707e725_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/ipython-8.24.0-pyh707e725_0.conda - sha256: d3ce492dac53a8f1c6cd682a25313f02993a1333b5e4787a15259a6e7cb28562 - md5: 1fb1f1fcbe053a762748dbf0ae4cfd0d + url: https://conda.anaconda.org/conda-forge/noarch/ipython-8.25.0-pyh707e725_0.conda + sha256: 4a53d39e44ce8bb7ce75f50b9e2f594e0bac12812cfe1e7525bb285d64a69d78 + md5: 98466a37c08f3bdbb500786271859517 depends: - __unix - decorator @@ -11855,17 +11764,17 @@ packages: license_family: BSD purls: - pkg:pypi/ipython - size: 596366 - timestamp: 1715263505659 + size: 598836 + timestamp: 1717182833704 - kind: conda name: ipython - version: 8.24.0 + version: 8.25.0 build: pyh7428d3b_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/ipython-8.24.0-pyh7428d3b_0.conda - sha256: 437b21b8d4dc3cc119deda857e2f180c470d956a30af41790f622d750021b51f - md5: 5c51b5f02a949233a2130284ff7fc416 + url: https://conda.anaconda.org/conda-forge/noarch/ipython-8.25.0-pyh7428d3b_0.conda + sha256: a6db9bc794ccb0e654e313aa165af340a0f60349f6667707783dd96c1b1ed6b1 + md5: fdead7917816e9d03238fbd4da9a674e depends: - __win - colorama @@ -11884,31 +11793,30 @@ packages: license_family: BSD purls: - pkg:pypi/ipython - size: 597669 - timestamp: 1715263693378 + size: 597676 + timestamp: 1717183379377 - kind: conda name: ipywidgets - version: 8.1.2 - build: pyhd8ed1ab_1 - build_number: 1 + version: 8.1.3 + build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.2-pyhd8ed1ab_1.conda - sha256: 0123e54e4a5850baf2f50b5c03e4812274318ad26fcd130220b6ccedfad9bb07 - md5: 34072973a80ea997df2ee52c0f6fef78 + url: https://conda.anaconda.org/conda-forge/noarch/ipywidgets-8.1.3-pyhd8ed1ab_0.conda + sha256: 161b5132d8f4d0c344205ec238c7f268edb517d6da66a1f497342ff26590da00 + md5: a1323654e9d87b16642ef02a03b98b32 depends: - comm >=0.1.3 - ipython >=6.1.0 - - jupyterlab_widgets >=3.0.10,<3.1.0 + - jupyterlab_widgets >=3.0.11,<3.1.0 - python >=3.7 - traitlets >=4.3.1 - - widgetsnbextension >=4.0.10,<4.1.0 + - widgetsnbextension >=4.0.11,<4.1.0 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/ipywidgets - size: 113743 - timestamp: 1715139776347 + size: 113787 + timestamp: 1716897741733 - kind: conda name: isoduration version: 20.11.0 @@ -12169,13 +12077,12 @@ packages: timestamp: 1640883236813 - kind: conda name: jsonpointer - version: '2.4' - build: py311h1ea47a8_3 - build_number: 3 + version: 3.0.0 + build: py311h1ea47a8_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/jsonpointer-2.4-py311h1ea47a8_3.conda - sha256: 13042586b08e8caa60615e7c42d05601f9421e8bda5df932e3ef9d2401bf2435 - md5: db8fc59f9215e668e602f769d0bf67bb + url: https://conda.anaconda.org/conda-forge/win-64/jsonpointer-3.0.0-py311h1ea47a8_0.conda + sha256: 50cda289c46d043cbfd0f4fd0b6ec6793e6bfc6b4e307baa40486a391d501215 + md5: fb9c38edbc17bbaa549a8fdc933ada68 depends: - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 @@ -12183,17 +12090,16 @@ packages: license_family: BSD purls: - pkg:pypi/jsonpointer - size: 34654 - timestamp: 1695397742357 + size: 42767 + timestamp: 1718283925914 - kind: conda name: jsonpointer - version: '2.4' - build: py311h267d04e_3 - build_number: 3 + version: 3.0.0 + build: py311h267d04e_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/jsonpointer-2.4-py311h267d04e_3.conda - sha256: 807d6c44f3e34139bfd25db4409381a6ce37fad2902c58f10fa7e1c30a64333d - md5: b6008a5b9180e58a235f5e45432dfe2e + url: https://conda.anaconda.org/conda-forge/osx-arm64/jsonpointer-3.0.0-py311h267d04e_0.conda + sha256: 05ead39da575f7e25ad1e07755cf24e4b389bb2de945a14049b93e51034b47f9 + md5: d962e72d8c1d0efb22f0e54e8e97cd71 depends: - python >=3.11,<3.12.0a0 - python >=3.11,<3.12.0a0 *_cpython @@ -12202,17 +12108,16 @@ packages: license_family: BSD purls: - pkg:pypi/jsonpointer - size: 18841 - timestamp: 1695397944650 + size: 18410 + timestamp: 1718283680472 - kind: conda name: jsonpointer - version: '2.4' - build: py311h38be061_3 - build_number: 3 + version: 3.0.0 + build: py311h38be061_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/jsonpointer-2.4-py311h38be061_3.conda - sha256: 976f7bf3c3a49c3066f36b67c12ae06b31542e53b843bb4362f31c9e449c6c46 - md5: 41d52d822edf991bf0e6b08c1921a8ec + url: https://conda.anaconda.org/conda-forge/linux-64/jsonpointer-3.0.0-py311h38be061_0.conda + sha256: 30a3947da86b74e09b1013d232f40b4b960c192b7dce35407e89b10e3e28cdc7 + md5: 01a505ab9b4e3af12baa98b82f5fcafa depends: - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 @@ -12220,17 +12125,16 @@ packages: license_family: BSD purls: - pkg:pypi/jsonpointer - size: 18389 - timestamp: 1695397377176 + size: 17919 + timestamp: 1718283458583 - kind: conda name: jsonpointer - version: '2.4' - build: py311h6eed73b_3 - build_number: 3 + version: 3.0.0 + build: py311h6eed73b_0 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/jsonpointer-2.4-py311h6eed73b_3.conda - sha256: b0ba738e1dbf3b69558557cd1e63310364e045b8c8e7f73fdce7e71928b5f22a - md5: ed1c23d0e55abd27d8b9e31c58105140 + url: https://conda.anaconda.org/conda-forge/osx-64/jsonpointer-3.0.0-py311h6eed73b_0.conda + sha256: b98237f5071161a30b711062b1c9306a2f7abea0b97fabfeff662919f40d1f00 + md5: e6239ae1b58ab3e7f6863ee46dba46b5 depends: - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 @@ -12238,8 +12142,8 @@ packages: license_family: BSD purls: - pkg:pypi/jsonpointer - size: 18557 - timestamp: 1695397765266 + size: 18107 + timestamp: 1718283517513 - kind: conda name: jsonschema version: 4.22.0 @@ -12501,13 +12405,13 @@ packages: timestamp: 1710805759187 - kind: conda name: jupyter_server - version: 2.14.0 + version: 2.14.1 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.0-pyhd8ed1ab_0.conda - sha256: 719be928812cd582713f96d0681a91890cf9d0e5fcb9d2e4ef4b09fc3ab4df4c - md5: b82b9798563dea0cd8e4e3074227f04c + url: https://conda.anaconda.org/conda-forge/noarch/jupyter_server-2.14.1-pyhd8ed1ab_0.conda + sha256: 58628ef004ba0f754cc01b33199b6aefd94f5aed7fbf7afd2b796d8b5c4ef22c + md5: 174af03c6e6038edd32021a48aa003c4 depends: - anyio >=3.1.0 - argon2-cffi @@ -12532,8 +12436,8 @@ packages: license_family: BSD purls: - pkg:pypi/jupyter-server - size: 324713 - timestamp: 1712884350803 + size: 324369 + timestamp: 1717122163377 - kind: conda name: jupyter_server_terminals version: 0.5.3 @@ -12554,13 +12458,13 @@ packages: timestamp: 1710262791393 - kind: conda name: jupyterlab - version: 4.2.1 + version: 4.2.2 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.1-pyhd8ed1ab_0.conda - sha256: 507f87a6449a7d5d23ad24fcba41aed150770df18ae877a4fdf9da78039f1682 - md5: 3e7290af6190b29c7017d6a8fb0eaeea + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab-4.2.2-pyhd8ed1ab_0.conda + sha256: e882a917d8727cc06cbd79bdd2d6c5406b2536448401ca12be462d2f60720509 + md5: 405a9d330af26391c8001d56b3ef4239 depends: - async-lru >=1.0.0 - httpx >=0.25.0 @@ -12575,6 +12479,7 @@ packages: - notebook-shim >=0.2 - packaging - python >=3.8 + - setuptools >=40.1.0 - tomli >=1.2.2 - tornado >=6.2.0 - traitlets @@ -12582,8 +12487,8 @@ packages: license_family: BSD purls: - pkg:pypi/jupyterlab - size: 7734905 - timestamp: 1716470384098 + size: 8191962 + timestamp: 1718030382389 - kind: conda name: jupyterlab_pygments version: 0.3.0 @@ -12634,13 +12539,13 @@ packages: timestamp: 1716434054129 - kind: conda name: jupyterlab_widgets - version: 3.0.10 + version: 3.0.11 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.10-pyhd8ed1ab_0.conda - sha256: 7c14d0b377ddd2e21f23d2f55fbd827aca726860e504a131b67ef936aef2b8c4 - md5: 16b73b2c4ff7dda8bbecf88aadfe2027 + url: https://conda.anaconda.org/conda-forge/noarch/jupyterlab_widgets-3.0.11-pyhd8ed1ab_0.conda + sha256: 14053a987d44da2f36d79e28147d4e2551cda2559cba6144103b677ef26616a8 + md5: fc0cb2abcfcec65ecbdcde4289b62fea depends: - python >=3.7 constrains: @@ -12649,8 +12554,8 @@ packages: license_family: BSD purls: - pkg:pypi/jupyterlab-widgets - size: 187135 - timestamp: 1707422097508 + size: 186467 + timestamp: 1716891738104 - kind: conda name: jxrlib version: '1.1' @@ -13121,17 +13026,17 @@ packages: - kind: conda name: ld_impl_linux-64 version: '2.40' - build: hf3520f5_1 - build_number: 1 + build: hf3520f5_6 + build_number: 6 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_1.conda - sha256: cb54a873c1c84c47f7174093889686b626946b8143905ec0f76a56785b26a304 - md5: 33b7851c39c25da14f6a233a8ccbeeca + url: https://conda.anaconda.org/conda-forge/linux-64/ld_impl_linux-64-2.40-hf3520f5_6.conda + sha256: f3ed562d9b21ad01cba3de368ee869b3424ed7fd93b550a7d4c57ae219d243ee + md5: deae631c9a587b4cfd33aa082491329b constrains: - binutils_impl_linux-64 2.40 license: GPL-3.0-only - size: 707934 - timestamp: 1716583433869 + size: 708001 + timestamp: 1718519178402 - kind: conda name: lerc version: 4.0.0 @@ -13334,7 +13239,7 @@ packages: - bzip2 >=1.0.8,<2.0a0 - libiconv >=1.17,<2.0a0 - libxml2 >=2.12.7,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - lzo >=2.10,<3.0a0 - openssl >=3.3.0,<4.0a0 @@ -13357,7 +13262,7 @@ packages: - bzip2 >=1.0.8,<2.0a0 - libiconv >=1.17,<2.0a0 - libxml2 >=2.12.7,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - lzo >=2.10,<3.0a0 - openssl >=3.3.0,<4.0a0 @@ -13378,7 +13283,7 @@ packages: depends: - bzip2 >=1.0.8,<2.0a0 - libxml2 >=2.12.7,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - lzo >=2.10,<3.0a0 - openssl >=3.3.0,<4.0a0 @@ -13403,7 +13308,7 @@ packages: - bzip2 >=1.0.8,<2.0a0 - libgcc-ng >=12 - libxml2 >=2.12.7,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - lzo >=2.10,<3.0a0 - openssl >=3.3.0,<4.0a0 @@ -13416,14 +13321,14 @@ packages: - kind: conda name: libarrow version: 15.0.2 - build: h3ee1d8f_3_cpu + build: h965e444_3_cpu build_number: 3 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-15.0.2-h3ee1d8f_3_cpu.conda - sha256: 05266538b1794582e16d18bf24bd20ec5c86165b4042808308c758a1b9784bf8 - md5: 95ab876a5159bdcc5f9cc2594b365fe2 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/libarrow-15.0.2-h965e444_3_cpu.conda + sha256: a6886cff57529f1ab71e3327b37ea5b55b9d31764c4322abfe3391e7401f56a1 + md5: db0e69e54efa4f0aa778a77a039f7f53 depends: - - __osx >=11.0 + - __osx >=10.13 - aws-crt-cpp >=0.26.6,<0.26.7.0a0 - aws-sdk-cpp >=1.11.267,<1.11.268.0a0 - bzip2 >=1.0.8,<2.0a0 @@ -13437,172 +13342,137 @@ packages: - libgoogle-cloud-storage >=2.22.0,<2.23.0a0 - libre2-11 >=2023.9.1,<2024.0a0 - libutf8proc >=2.8.0,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - orc >=2.0.0,<2.0.1.0a0 - re2 - snappy >=1.2.0,<1.3.0a0 - zstd >=1.5.5,<1.6.0a0 constrains: + - arrow-cpp <0.0a0 - apache-arrow-proc =*=cpu - parquet-cpp <0.0a0 - - arrow-cpp <0.0a0 license: Apache-2.0 license_family: APACHE - size: 5096884 - timestamp: 1712780742425 + size: 5717595 + timestamp: 1712757257079 - kind: conda name: libarrow - version: 15.0.2 - build: h45212c0_3_cpu - build_number: 3 + version: 16.1.0 + build: h107e38f_1_cpu + build_number: 1 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libarrow-15.0.2-h45212c0_3_cpu.conda - sha256: a027b9d4345e21136d96d038b822c2743a8bcb2d1b5dba059403b0179d78268d - md5: 13fd341602fce774d7443904afa76fcf + url: https://conda.anaconda.org/conda-forge/win-64/libarrow-16.1.0-h107e38f_1_cpu.conda + sha256: 1aa9e2cc25d0c0ca71d5b4e8d6d3dc5032d297318950da3c0fae701f133a2fb3 + md5: 961bea6b676d58fcef28f6e5fecc296c depends: - - aws-crt-cpp >=0.26.6,<0.26.7.0a0 + - aws-crt-cpp >=0.26.8,<0.26.9.0a0 - aws-sdk-cpp >=1.11.267,<1.11.268.0a0 - bzip2 >=1.0.8,<2.0a0 - libabseil * cxx17* - - libabseil >=20240116.1,<20240117.0a0 + - libabseil >=20240116.2,<20240117.0a0 - libbrotlidec >=1.1.0,<1.2.0a0 - libbrotlienc >=1.1.0,<1.2.0a0 - libcrc32c >=1.1.2,<1.2.0a0 - libcurl >=8.7.1,<9.0a0 - - libgoogle-cloud >=2.22.0,<2.23.0a0 - - libgoogle-cloud-storage >=2.22.0,<2.23.0a0 + - libgoogle-cloud >=2.23.0,<2.24.0a0 + - libgoogle-cloud-storage >=2.23.0,<2.24.0a0 - libre2-11 >=2023.9.1,<2024.0a0 - libutf8proc >=2.8.0,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - - openssl >=3.2.1,<4.0a0 - orc >=2.0.0,<2.0.1.0a0 - re2 - snappy >=1.2.0,<1.3.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 - - zstd >=1.5.5,<1.6.0a0 + - zstd >=1.5.6,<1.6.0a0 constrains: - - apache-arrow-proc =*=cpu - arrow-cpp <0.0a0 + - apache-arrow-proc =*=cpu - parquet-cpp <0.0a0 license: Apache-2.0 license_family: APACHE - size: 5067006 - timestamp: 1712757111785 + size: 5126580 + timestamp: 1715995378966 - kind: conda name: libarrow - version: 15.0.2 - build: h965e444_3_cpu - build_number: 3 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/libarrow-15.0.2-h965e444_3_cpu.conda - sha256: a6886cff57529f1ab71e3327b37ea5b55b9d31764c4322abfe3391e7401f56a1 - md5: db0e69e54efa4f0aa778a77a039f7f53 + version: 16.1.0 + build: h23f55cf_1_cpu + build_number: 1 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-16.1.0-h23f55cf_1_cpu.conda + sha256: 44680d03c85b4f3fb61d75dade954c66b5a0ef5cbdfc82afdff33e542fa2b608 + md5: 69c9265b8b5a41a9ed48a087c1f78bf9 depends: - - __osx >=10.13 - - aws-crt-cpp >=0.26.6,<0.26.7.0a0 + - __osx >=11.0 + - aws-crt-cpp >=0.26.8,<0.26.9.0a0 - aws-sdk-cpp >=1.11.267,<1.11.268.0a0 - bzip2 >=1.0.8,<2.0a0 - glog >=0.7.0,<0.8.0a0 - libabseil * cxx17* - - libabseil >=20240116.1,<20240117.0a0 + - libabseil >=20240116.2,<20240117.0a0 - libbrotlidec >=1.1.0,<1.2.0a0 - libbrotlienc >=1.1.0,<1.2.0a0 - libcxx >=16 - - libgoogle-cloud >=2.22.0,<2.23.0a0 - - libgoogle-cloud-storage >=2.22.0,<2.23.0a0 + - libgoogle-cloud >=2.23.0,<2.24.0a0 + - libgoogle-cloud-storage >=2.23.0,<2.24.0a0 - libre2-11 >=2023.9.1,<2024.0a0 - libutf8proc >=2.8.0,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - orc >=2.0.0,<2.0.1.0a0 - re2 - snappy >=1.2.0,<1.3.0a0 - - zstd >=1.5.5,<1.6.0a0 + - zstd >=1.5.6,<1.6.0a0 constrains: - arrow-cpp <0.0a0 - apache-arrow-proc =*=cpu - parquet-cpp <0.0a0 license: Apache-2.0 license_family: APACHE - size: 5717595 - timestamp: 1712757257079 + size: 5198724 + timestamp: 1715994288957 - kind: conda name: libarrow - version: 15.0.2 - build: he70291f_3_cpu - build_number: 3 + version: 16.1.0 + build: hefa796f_1_cpu + build_number: 1 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libarrow-15.0.2-he70291f_3_cpu.conda - sha256: 27157f7cc429ea43093983cfbab3d6a031c10e4330d686f062075b9729f6a982 - md5: d09f7d5d311728e9e4cd386d86a1e55f + url: https://conda.anaconda.org/conda-forge/linux-64/libarrow-16.1.0-hefa796f_1_cpu.conda + sha256: d74149bb76eb952aa38cc5a591c03b1b186ad01a12861860c31550f2da7d7ca7 + md5: 9b96a5f974932e802cdeda54733b4c53 depends: - - aws-crt-cpp >=0.26.6,<0.26.7.0a0 + - aws-crt-cpp >=0.26.8,<0.26.9.0a0 - aws-sdk-cpp >=1.11.267,<1.11.268.0a0 - bzip2 >=1.0.8,<2.0a0 + - gflags >=2.2.2,<2.3.0a0 - glog >=0.7.0,<0.8.0a0 - libabseil * cxx17* - - libabseil >=20240116.1,<20240117.0a0 + - libabseil >=20240116.2,<20240117.0a0 - libbrotlidec >=1.1.0,<1.2.0a0 - libbrotlienc >=1.1.0,<1.2.0a0 - libgcc-ng >=12 - - libgoogle-cloud >=2.22.0,<2.23.0a0 - - libgoogle-cloud-storage >=2.22.0,<2.23.0a0 + - libgoogle-cloud >=2.23.0,<2.24.0a0 + - libgoogle-cloud-storage >=2.23.0,<2.24.0a0 - libre2-11 >=2023.9.1,<2024.0a0 - libstdcxx-ng >=12 - libutf8proc >=2.8.0,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - orc >=2.0.0,<2.0.1.0a0 - re2 - snappy >=1.2.0,<1.3.0a0 - - zstd >=1.5.5,<1.6.0a0 + - zstd >=1.5.6,<1.6.0a0 constrains: - parquet-cpp <0.0a0 - - apache-arrow-proc =*=cpu - arrow-cpp <0.0a0 + - apache-arrow-proc =*=cpu license: Apache-2.0 license_family: APACHE - size: 8170462 - timestamp: 1712756370701 -- kind: conda - name: libarrow-acero - version: 15.0.2 - build: h3f3aa29_3_cpu - build_number: 3 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-acero-15.0.2-h3f3aa29_3_cpu.conda - sha256: 175d3c97ca9c392dbb2706cee96b4a7d62b47cbf7961681a78fa22902e4fd284 - md5: 27eb94e27b82689a354bad54cad7b331 - depends: - - __osx >=11.0 - - libarrow 15.0.2 h3ee1d8f_3_cpu - - libcxx >=16 - license: Apache-2.0 - license_family: APACHE - size: 484098 - timestamp: 1712780876773 -- kind: conda - name: libarrow-acero - version: 15.0.2 - build: h8681a6d_3_cpu - build_number: 3 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libarrow-acero-15.0.2-h8681a6d_3_cpu.conda - sha256: d1261bfe5bb67a85b9ab61ada5597e13efa1c44e6124ae82accc635ec0dc7153 - md5: 9257ec84ae8e63151a20a22bb92ca547 - depends: - - libarrow 15.0.2 h45212c0_3_cpu - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: Apache-2.0 - license_family: APACHE - size: 445686 - timestamp: 1712757192079 + size: 8300809 + timestamp: 1715994674614 - kind: conda name: libarrow-acero version: 15.0.2 @@ -13622,60 +13492,56 @@ packages: timestamp: 1712757408748 - kind: conda name: libarrow-acero - version: 15.0.2 - build: hac33072_3_cpu - build_number: 3 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-15.0.2-hac33072_3_cpu.conda - sha256: ce25b573fd32e6e9c6cec37d82a375f69125912018246a7d78dfa116952c5105 - md5: f70ae2fa9f50bed63564a6190f2cff35 + version: 16.1.0 + build: h00cdb27_1_cpu + build_number: 1 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-acero-16.1.0-h00cdb27_1_cpu.conda + sha256: 4d333b9dd616436940ff24d2ca978dc676c19604a5127b46690a0fc6d5ea60da + md5: 3303cefbdf2bce8a1b88ac1ae70ca163 depends: - - libarrow 15.0.2 he70291f_3_cpu - - libgcc-ng >=12 - - libstdcxx-ng >=12 + - __osx >=11.0 + - libarrow 16.1.0 h23f55cf_1_cpu + - libcxx >=16 license: Apache-2.0 license_family: APACHE - size: 597913 - timestamp: 1712756407762 + size: 487011 + timestamp: 1715994433224 - kind: conda - name: libarrow-dataset - version: 15.0.2 - build: h3f3aa29_3_cpu - build_number: 3 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-dataset-15.0.2-h3f3aa29_3_cpu.conda - sha256: b7ac6339c5f862ff1c83dfff527edbc1f40bf0a363d1156264c01f29d556b1ee - md5: 6fbd639064597f4f3329073fe2231cb8 + name: libarrow-acero + version: 16.1.0 + build: hac33072_1_cpu + build_number: 1 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libarrow-acero-16.1.0-hac33072_1_cpu.conda + sha256: 307751feaca7bcc1e57694f7c8c33616859a5f408197a14fd0d23da89f13bf27 + md5: fcdd73184457b7055f7ca16ffc6d6711 depends: - - __osx >=11.0 - - libarrow 15.0.2 h3ee1d8f_3_cpu - - libarrow-acero 15.0.2 h3f3aa29_3_cpu - - libcxx >=16 - - libparquet 15.0.2 h5304c63_3_cpu + - libarrow 16.1.0 hefa796f_1_cpu + - libgcc-ng >=12 + - libstdcxx-ng >=12 license: Apache-2.0 license_family: APACHE - size: 488622 - timestamp: 1712782155853 + size: 600002 + timestamp: 1715994720678 - kind: conda - name: libarrow-dataset - version: 15.0.2 - build: h8681a6d_3_cpu - build_number: 3 + name: libarrow-acero + version: 16.1.0 + build: he0c23c2_1_cpu + build_number: 1 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libarrow-dataset-15.0.2-h8681a6d_3_cpu.conda - sha256: d78258e30d5409b354fe8d7e7d8b8fb28603fdfa880b072c6fb4f61fb7e4a4fa - md5: 653c38fe4662c9245d2b647dc10c8907 + url: https://conda.anaconda.org/conda-forge/win-64/libarrow-acero-16.1.0-he0c23c2_1_cpu.conda + sha256: 8ddbbaa4f26196beeb0c66357723f851c8f698901ce90e114ede8ebe675b9955 + md5: 4a073ed514345d1968f2aa4ebec62967 depends: - - libarrow 15.0.2 h45212c0_3_cpu - - libarrow-acero 15.0.2 h8681a6d_3_cpu - - libparquet 15.0.2 h39135fc_3_cpu + - libarrow 16.1.0 h107e38f_1_cpu - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 license: Apache-2.0 license_family: APACHE - size: 430894 - timestamp: 1712757431442 + size: 445964 + timestamp: 1715995451276 - kind: conda name: libarrow-dataset version: 15.0.2 @@ -13697,44 +13563,62 @@ packages: timestamp: 1712758274474 - kind: conda name: libarrow-dataset - version: 15.0.2 - build: hac33072_3_cpu - build_number: 3 + version: 16.1.0 + build: h00cdb27_1_cpu + build_number: 1 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-dataset-16.1.0-h00cdb27_1_cpu.conda + sha256: 230edc1c0ecb59b43129d0b30ac898186cb0699ae6da5a23fc649477d76184ea + md5: 06eaab63f0b7d5bce1d73feb1b047b06 + depends: + - __osx >=11.0 + - libarrow 16.1.0 h23f55cf_1_cpu + - libarrow-acero 16.1.0 h00cdb27_1_cpu + - libcxx >=16 + - libparquet 16.1.0 hcf52c46_1_cpu + license: Apache-2.0 + license_family: APACHE + size: 493736 + timestamp: 1715995642694 +- kind: conda + name: libarrow-dataset + version: 16.1.0 + build: hac33072_1_cpu + build_number: 1 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-15.0.2-hac33072_3_cpu.conda - sha256: 0e380506725c77f9a102be1ad96c27f3881de74d32aef737e369d95e0e0f61dc - md5: 59df0b7cf76763437ac3a5865c23af80 + url: https://conda.anaconda.org/conda-forge/linux-64/libarrow-dataset-16.1.0-hac33072_1_cpu.conda + sha256: 94c02c9d4a4af5d7f18b10083672fb7834065b124206ddf11811852e147ff666 + md5: 855feea87f42887b22accedd41fa0755 depends: - - libarrow 15.0.2 he70291f_3_cpu - - libarrow-acero 15.0.2 hac33072_3_cpu + - libarrow 16.1.0 hefa796f_1_cpu + - libarrow-acero 16.1.0 hac33072_1_cpu - libgcc-ng >=12 - - libparquet 15.0.2 h6a7eafb_3_cpu + - libparquet 16.1.0 h6a7eafb_1_cpu - libstdcxx-ng >=12 license: Apache-2.0 license_family: APACHE - size: 585627 - timestamp: 1712756482313 + size: 579347 + timestamp: 1715994808494 - kind: conda - name: libarrow-flight - version: 15.0.2 - build: h224147a_3_cpu - build_number: 3 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-flight-15.0.2-h224147a_3_cpu.conda - sha256: 1be64be8ec9302d40fa2b02af392cd50d4097f4d3cc4288ae9c857477bde7009 - md5: fc0d5678771622e7ce3133669117741b + name: libarrow-dataset + version: 16.1.0 + build: he0c23c2_1_cpu + build_number: 1 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/libarrow-dataset-16.1.0-he0c23c2_1_cpu.conda + sha256: e6d380a191e3b9c818a271ba080b248ec530866db369ad0c6de9ac2112c74039 + md5: f067f327c230283d927dcd02b5af96aa depends: - - __osx >=11.0 - - libabseil * cxx17* - - libabseil >=20240116.1,<20240117.0a0 - - libarrow 15.0.2 h3ee1d8f_3_cpu - - libcxx >=16 - - libgrpc >=1.62.1,<1.63.0a0 - - libprotobuf >=4.25.3,<4.25.4.0a0 + - libarrow 16.1.0 h107e38f_1_cpu + - libarrow-acero 16.1.0 he0c23c2_1_cpu + - libparquet 16.1.0 h178134c_1_cpu + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: Apache-2.0 license_family: APACHE - size: 311478 - timestamp: 1712781158729 + size: 427421 + timestamp: 1715995726807 - kind: conda name: libarrow-flight version: 15.0.2 @@ -13756,89 +13640,6 @@ packages: license_family: APACHE size: 322118 timestamp: 1712757592284 -- kind: conda - name: libarrow-flight - version: 15.0.2 - build: h83a3238_3_cpu - build_number: 3 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libarrow-flight-15.0.2-h83a3238_3_cpu.conda - sha256: f731aac25489768982967bbacddfadd21c885bb4370fe7c95fe1822df3c1eb23 - md5: 88a05164d4b11f758862f8a25de71a93 - depends: - - libabseil * cxx17* - - libabseil >=20240116.1,<20240117.0a0 - - libarrow 15.0.2 h45212c0_3_cpu - - libgrpc >=1.62.1,<1.63.0a0 - - libprotobuf >=4.25.3,<4.25.4.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: Apache-2.0 - license_family: APACHE - size: 289195 - timestamp: 1712757249110 -- kind: conda - name: libarrow-flight - version: 15.0.2 - build: hd42f311_3_cpu - build_number: 3 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libarrow-flight-15.0.2-hd42f311_3_cpu.conda - sha256: fd38c1cd423684b7d42e02a30af61fec73b407b50cc0d84975e5f6574140aac6 - md5: 2481d3c17be3a1e8876b733001901162 - depends: - - libabseil * cxx17* - - libabseil >=20240116.1,<20240117.0a0 - - libarrow 15.0.2 he70291f_3_cpu - - libgcc-ng >=12 - - libgrpc >=1.62.1,<1.63.0a0 - - libprotobuf >=4.25.3,<4.25.4.0a0 - - libstdcxx-ng >=12 - - ucx >=1.15.0,<1.16.0a0 - license: Apache-2.0 - license_family: APACHE - size: 506382 - timestamp: 1712756425619 -- kind: conda - name: libarrow-flight-sql - version: 15.0.2 - build: h21569af_3_cpu - build_number: 3 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libarrow-flight-sql-15.0.2-h21569af_3_cpu.conda - sha256: 5f273e01a945aff32a5e0e515fbee25eb30b1b22868b44603203699274d1e84d - md5: 92d097be346d744875118cdcb8d760ee - depends: - - libarrow 15.0.2 h45212c0_3_cpu - - libarrow-flight 15.0.2 h83a3238_3_cpu - - libprotobuf >=4.25.3,<4.25.4.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: Apache-2.0 - license_family: APACHE - size: 235418 - timestamp: 1712757483688 -- kind: conda - name: libarrow-flight-sql - version: 15.0.2 - build: h9241762_3_cpu - build_number: 3 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libarrow-flight-sql-15.0.2-h9241762_3_cpu.conda - sha256: 6c4678e6b0193344dec99053e1bfc25c0c9bc384a29f7f33896dfc1d7cb6ca48 - md5: 1f74636cb22b3f6bc88a13843249e06f - depends: - - libarrow 15.0.2 he70291f_3_cpu - - libarrow-flight 15.0.2 hd42f311_3_cpu - - libgcc-ng >=12 - - libprotobuf >=4.25.3,<4.25.4.0a0 - - libstdcxx-ng >=12 - license: Apache-2.0 - license_family: APACHE - size: 194961 - timestamp: 1712756499434 - kind: conda name: libarrow-flight-sql version: 15.0.2 @@ -13858,143 +13659,30 @@ packages: license_family: APACHE size: 153610 timestamp: 1712758355472 -- kind: conda - name: libarrow-flight-sql - version: 15.0.2 - build: hb630850_3_cpu - build_number: 3 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-flight-sql-15.0.2-hb630850_3_cpu.conda - sha256: 017e917b1f42be97339c6b0caca72e2482dcbbb2384deb556a81deb19dbe136e - md5: 895c0a37b5737390e8258992ca40b1af - depends: - - __osx >=11.0 - - libarrow 15.0.2 h3ee1d8f_3_cpu - - libarrow-flight 15.0.2 h224147a_3_cpu - - libcxx >=16 - - libprotobuf >=4.25.3,<4.25.4.0a0 - license: Apache-2.0 - license_family: APACHE - size: 153183 - timestamp: 1712782254555 -- kind: conda - name: libarrow-gandiva - version: 15.0.2 - build: h05de715_3_cpu - build_number: 3 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libarrow-gandiva-15.0.2-h05de715_3_cpu.conda - sha256: b9eb1ac7aac05f13fc2a2ceef560f2e10f69f79a034790bbc0106422568fde32 - md5: f8e762220d4001bc95611c32d532e929 - depends: - - libabseil * cxx17* - - libabseil >=20240116.1,<20240117.0a0 - - libarrow 15.0.2 h45212c0_3_cpu - - libre2-11 >=2023.9.1,<2024.0a0 - - libutf8proc >=2.8.0,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 - - openssl >=3.2.1,<4.0a0 - - re2 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - - zstd >=1.5.5,<1.6.0a0 - license: Apache-2.0 - license_family: APACHE - size: 10720285 - timestamp: 1712757303438 -- kind: conda - name: libarrow-gandiva - version: 15.0.2 - build: h5fa1bb3_3_cpu - build_number: 3 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-gandiva-15.0.2-h5fa1bb3_3_cpu.conda - sha256: c9600b37f9f4619409c19310b72921c6247e701a3594e9318da337369beabf14 - md5: 3a454bd44559d7045911efb4043c4589 - depends: - - __osx >=11.0 - - libabseil * cxx17* - - libabseil >=20240116.1,<20240117.0a0 - - libarrow 15.0.2 h3ee1d8f_3_cpu - - libcxx >=16 - - libllvm16 >=16.0.6,<16.1.0a0 - - libre2-11 >=2023.9.1,<2024.0a0 - - libutf8proc >=2.8.0,<3.0a0 - - openssl >=3.2.1,<4.0a0 - - re2 - license: Apache-2.0 - license_family: APACHE - size: 686815 - timestamp: 1712781929049 - kind: conda name: libarrow-gandiva version: 15.0.2 build: h6ac0def_3_cpu build_number: 3 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/libarrow-gandiva-15.0.2-h6ac0def_3_cpu.conda - sha256: 2500da9593a55363ac16c8f92165ea7002023a1f38d57e6d54968d7922530d7b - md5: 3fb063fbce68efaa7b7ce614dfa7f6ea - depends: - - __osx >=10.13 - - libabseil * cxx17* - - libabseil >=20240116.1,<20240117.0a0 - - libarrow 15.0.2 h965e444_3_cpu - - libcxx >=16 - - libllvm16 >=16.0.6,<16.1.0a0 - - libre2-11 >=2023.9.1,<2024.0a0 - - libutf8proc >=2.8.0,<3.0a0 - - openssl >=3.2.1,<4.0a0 - - re2 - license: Apache-2.0 - license_family: APACHE - size: 699945 - timestamp: 1712758054471 -- kind: conda - name: libarrow-gandiva - version: 15.0.2 - build: hd4ab825_3_cpu - build_number: 3 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libarrow-gandiva-15.0.2-hd4ab825_3_cpu.conda - sha256: 9eda95ecfcb985726ad947720c711c7941d25be83d6ed47316bc8aa50febef2b - md5: b7f70a642aef9013a2787b0025c53f01 + url: https://conda.anaconda.org/conda-forge/osx-64/libarrow-gandiva-15.0.2-h6ac0def_3_cpu.conda + sha256: 2500da9593a55363ac16c8f92165ea7002023a1f38d57e6d54968d7922530d7b + md5: 3fb063fbce68efaa7b7ce614dfa7f6ea depends: + - __osx >=10.13 - libabseil * cxx17* - libabseil >=20240116.1,<20240117.0a0 - - libarrow 15.0.2 he70291f_3_cpu - - libgcc-ng >=12 + - libarrow 15.0.2 h965e444_3_cpu + - libcxx >=16 - libllvm16 >=16.0.6,<16.1.0a0 - libre2-11 >=2023.9.1,<2024.0a0 - - libstdcxx-ng >=12 - libutf8proc >=2.8.0,<3.0a0 - openssl >=3.2.1,<4.0a0 - re2 license: Apache-2.0 license_family: APACHE - size: 896197 - timestamp: 1712756445172 -- kind: conda - name: libarrow-substrait - version: 15.0.2 - build: h9241762_3_cpu - build_number: 3 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-15.0.2-h9241762_3_cpu.conda - sha256: c7db9a7e0b1e2407afee9775fabba2f8894b0a0fb8040653596099d3d59e8980 - md5: d3c3294783206de4e7ad3880d1c9cefe - depends: - - libarrow 15.0.2 he70291f_3_cpu - - libarrow-acero 15.0.2 hac33072_3_cpu - - libarrow-dataset 15.0.2 hac33072_3_cpu - - libgcc-ng >=12 - - libprotobuf >=4.25.3,<4.25.4.0a0 - - libstdcxx-ng >=12 - license: Apache-2.0 - license_family: APACHE - size: 519375 - timestamp: 1712756517131 + size: 699945 + timestamp: 1712758054471 - kind: conda name: libarrow-substrait version: 15.0.2 @@ -14017,59 +13705,71 @@ packages: timestamp: 1712758489827 - kind: conda name: libarrow-substrait - version: 15.0.2 - build: hd92e347_3_cpu - build_number: 3 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-substrait-15.0.2-hd92e347_3_cpu.conda - sha256: 7a34dcd03bcc856311354ea0cb1c3c7ac99bd378cb296d47255d85424784635a - md5: 3b19f7c20b40456cc0dc3dfe9dfa5ad9 + version: 16.1.0 + build: h1f0e801_1_cpu + build_number: 1 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/libarrow-substrait-16.1.0-h1f0e801_1_cpu.conda + sha256: 35ffd1273ac36eec8805641efaea8a0da16d8d83c7ee900c85cfe368a06ef28b + md5: ffab58a154b77a805582ad6da4820dfc depends: - - __osx >=11.0 - - libarrow 15.0.2 h3ee1d8f_3_cpu - - libarrow-acero 15.0.2 h3f3aa29_3_cpu - - libarrow-dataset 15.0.2 h3f3aa29_3_cpu - - libcxx >=16 + - libabseil * cxx17* + - libabseil >=20240116.2,<20240117.0a0 + - libarrow 16.1.0 h107e38f_1_cpu + - libarrow-acero 16.1.0 he0c23c2_1_cpu + - libarrow-dataset 16.1.0 he0c23c2_1_cpu - libprotobuf >=4.25.3,<4.25.4.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: Apache-2.0 license_family: APACHE - size: 440628 - timestamp: 1712782400566 + size: 383630 + timestamp: 1715995846327 - kind: conda name: libarrow-substrait - version: 15.0.2 - build: hea7f8fd_3_cpu - build_number: 3 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libarrow-substrait-15.0.2-hea7f8fd_3_cpu.conda - sha256: 47117ff8827b492ea7d71a9b8bab047dfe38c6aaf7483ab6db7c58bf6b114fca - md5: a1964f4e3a87a384bcc2f0c865e6fae2 + version: 16.1.0 + build: h7e0c224_1_cpu + build_number: 1 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libarrow-substrait-16.1.0-h7e0c224_1_cpu.conda + sha256: bdda210900089f9a722ac92f5b128b872aef954760cdb514257c76ed4a3b7bae + md5: 0f04b3b2867e724c72e20a29f2f76169 depends: - libabseil * cxx17* - - libabseil >=20240116.1,<20240117.0a0 - - libarrow 15.0.2 h45212c0_3_cpu - - libarrow-acero 15.0.2 h8681a6d_3_cpu - - libarrow-dataset 15.0.2 h8681a6d_3_cpu + - libabseil >=20240116.2,<20240117.0a0 + - libarrow 16.1.0 hefa796f_1_cpu + - libarrow-acero 16.1.0 hac33072_1_cpu + - libarrow-dataset 16.1.0 hac33072_1_cpu + - libgcc-ng >=12 - libprotobuf >=4.25.3,<4.25.4.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - libstdcxx-ng >=12 license: Apache-2.0 license_family: APACHE - size: 361131 - timestamp: 1712757536502 + size: 549723 + timestamp: 1715994849336 - kind: conda - name: libasprintf - version: 0.22.5 - build: h5728263_2 - build_number: 2 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libasprintf-0.22.5-h5728263_2.conda - sha256: 5722a4a260355c9233680a3424a977433f25826ca0a1c05af403d62b805681bc - md5: 75a6982b9ff0a8db0f53303527b07af8 - license: LGPL-2.1-or-later - size: 49778 - timestamp: 1712515968238 + name: libarrow-substrait + version: 16.1.0 + build: hc68f6b8_1_cpu + build_number: 1 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libarrow-substrait-16.1.0-hc68f6b8_1_cpu.conda + sha256: a6d5810809618cbfac9072053e7502e17d2d3ba78b583132a2f2f17558a27330 + md5: 0badaad3eeee595d03a8e8578c70a361 + depends: + - __osx >=11.0 + - libabseil * cxx17* + - libabseil >=20240116.2,<20240117.0a0 + - libarrow 16.1.0 h23f55cf_1_cpu + - libarrow-acero 16.1.0 h00cdb27_1_cpu + - libarrow-dataset 16.1.0 h00cdb27_1_cpu + - libcxx >=16 + - libprotobuf >=4.25.3,<4.25.4.0a0 + license: Apache-2.0 + license_family: APACHE + size: 473018 + timestamp: 1715995863417 - kind: conda name: libasprintf version: 0.22.5 @@ -14109,20 +13809,6 @@ packages: license: LGPL-2.1-or-later size: 40630 timestamp: 1712512727388 -- kind: conda - name: libasprintf-devel - version: 0.22.5 - build: h5728263_2 - build_number: 2 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libasprintf-devel-0.22.5-h5728263_2.conda - sha256: d5c711d9da4e35d29f4f2191664075c64cbf8cd481a35bf7ef3a527018eb0184 - md5: 8377da2cc31200d7181d2e48d60e4c7b - depends: - - libasprintf 0.22.5 h5728263_2 - license: LGPL-2.1-or-later - size: 36272 - timestamp: 1712516175913 - kind: conda name: libasprintf-devel version: 0.22.5 @@ -14182,7 +13868,7 @@ packages: - fribidi >=1.0.10,<2.0a0 - harfbuzz >=8.1.1,<9.0a0 - libexpat >=2.5.0,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: ISC license_family: OTHER size: 125235 @@ -14204,7 +13890,7 @@ packages: - harfbuzz >=8.1.1,<9.0a0 - libexpat >=2.5.0,<3.0a0 - libgcc-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: ISC license_family: OTHER size: 126896 @@ -14225,7 +13911,7 @@ packages: - fribidi >=1.0.10,<2.0a0 - harfbuzz >=8.1.1,<9.0a0 - libexpat >=2.5.0,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: ISC license_family: OTHER size: 110763 @@ -14646,45 +14332,6 @@ packages: license_family: BSD size: 5191513 timestamp: 1712543043641 -- kind: conda - name: libclang - version: 15.0.7 - build: default_h127d8a8_5 - build_number: 5 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libclang-15.0.7-default_h127d8a8_5.conda - sha256: 606b79c8a4a926334191d79f4a1447aac1d82c43344e3a603cbba31ace859b8f - md5: 09b94dd3a7e304df5b83176239347920 - depends: - - libclang13 15.0.7 default_h5d6823c_5 - - libgcc-ng >=12 - - libllvm15 >=15.0.7,<15.1.0a0 - - libstdcxx-ng >=12 - license: Apache-2.0 WITH LLVM-exception - license_family: Apache - size: 133467 - timestamp: 1711064002817 -- kind: conda - name: libclang - version: 15.0.7 - build: default_h3a3e6c3_5 - build_number: 5 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libclang-15.0.7-default_h3a3e6c3_5.conda - sha256: 562dea76c17c30ed6d78734a9e40008f45cdab15611439d7d4e8250e0040f3ef - md5: 26e1a5a4ff7f8e3f5fb89be829818a75 - depends: - - libclang13 15.0.7 default_hf64faad_5 - - libxml2 >=2.12.6,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - - zstd >=1.5.5,<1.6.0a0 - license: Apache-2.0 WITH LLVM-exception - license_family: Apache - size: 148436 - timestamp: 1711068015076 - kind: conda name: libclang version: 15.0.7 @@ -14703,22 +14350,55 @@ packages: size: 133819 timestamp: 1711067667338 - kind: conda - name: libclang + name: libclang-cpp15 version: 15.0.7 - build: default_he012953_5 + build: default_h127d8a8_5 build_number: 5 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp15-15.0.7-default_h127d8a8_5.conda + sha256: 9b0238e705a33da74ca82efd03974f499550f7dada1340cc9cb7c35a92411ed8 + md5: d0a9633b53cdc319b8a1a532ae7822b8 + depends: + - libgcc-ng >=12 + - libllvm15 >=15.0.7,<15.1.0a0 + - libstdcxx-ng >=12 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 17206402 + timestamp: 1711063711931 +- kind: conda + name: libclang-cpp16 + version: 16.0.6 + build: default_hb63da90_8 + build_number: 8 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-15.0.7-default_he012953_5.conda - sha256: 1db1d44e3332f810b8623ad0c3e340a0f06145340727c69c994fe9d5a2fa6ced - md5: 998f002cb2418dbb8fb003cc774aece0 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libclang-cpp16-16.0.6-default_hb63da90_8.conda + sha256: e23bfec4fbd4ecd0ce98d0a61df0c3c8c9da32534d8b1fe509c2b60c810ba913 + md5: 076ad35c90bdd646e9e48af5cd2a08dc depends: - - libclang13 15.0.7 default_h83d0a53_5 + - __osx >=11.0 - libcxx >=16.0.6 - - libllvm15 >=15.0.7,<15.1.0a0 + - libllvm16 >=16.0.6,<16.1.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 11910689 + timestamp: 1718121809860 +- kind: conda + name: libclang-cpp18.1 + version: 18.1.7 + build: default_h9bb3924_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libclang-cpp18.1-18.1.7-default_h9bb3924_0.conda + sha256: 710556634edf342cbfcb01d454e8644d4a0ac674eed0a9aebfc1fe86ea8c0bf6 + md5: bff3d36fbd1b1a2f1e6d34aa3eb6b58c + depends: + - libgcc-ng >=12 + - libllvm18 >=18.1.7,<18.2.0a0 + - libstdcxx-ng >=12 license: Apache-2.0 WITH LLVM-exception license_family: Apache - size: 134103 - timestamp: 1711087430932 + size: 19272701 + timestamp: 1717818801492 - kind: conda name: libclang13 version: 15.0.7 @@ -14737,56 +14417,54 @@ packages: timestamp: 1711067548768 - kind: conda name: libclang13 - version: 15.0.7 - build: default_h5d6823c_5 - build_number: 5 + version: 18.1.7 + build: default_h087397f_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libclang13-15.0.7-default_h5d6823c_5.conda - sha256: 91ecfcf545a5d4588e9fad5db2b5b04eeef18cae1c03b790829ef8b978f06ccd - md5: 2d694a9ffdcc30e89dea34a8dcdab6ae + url: https://conda.anaconda.org/conda-forge/linux-64/libclang13-18.1.7-default_h087397f_0.conda + sha256: d981a2734c3af6217dd42c1bccc13b99fc3ca5a64c379739612d6cf67f992a1d + md5: 536526073c2e7f9056fdce8584da779e depends: - libgcc-ng >=12 - - libllvm15 >=15.0.7,<15.1.0a0 + - libllvm18 >=18.1.7,<18.2.0a0 - libstdcxx-ng >=12 license: Apache-2.0 WITH LLVM-exception license_family: Apache - size: 9583734 - timestamp: 1711063939856 + size: 11057579 + timestamp: 1717819075043 - kind: conda name: libclang13 - version: 15.0.7 - build: default_h83d0a53_5 - build_number: 5 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libclang13-15.0.7-default_h83d0a53_5.conda - sha256: b795d46bbef1e5662d958689a704e9298fb8def78fd8cd8e15b5afcb04fca496 - md5: 74ba94cc03689cc5c71eed7f8050c5d0 + version: 18.1.7 + build: default_h97ce8ae_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/libclang13-18.1.7-default_h97ce8ae_0.conda + sha256: c3c53f959a79747f78a31764af41b82e3c2b3f4576737581ba0237d33cdee85f + md5: a005e5fd30f14fcd2bc3e5ac57aa45a7 depends: - - libcxx >=16.0.6 - - libllvm15 >=15.0.7,<15.1.0a0 + - libzlib >=1.2.13,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - zstd >=1.5.6,<1.6.0a0 license: Apache-2.0 WITH LLVM-exception license_family: Apache - size: 6453696 - timestamp: 1711087319296 + size: 25318021 + timestamp: 1717824973079 - kind: conda name: libclang13 - version: 15.0.7 - build: default_hf64faad_5 - build_number: 5 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libclang13-15.0.7-default_hf64faad_5.conda - sha256: b952b85a6124442be3fe8af23d56f123548f7b28067f60615f7233197469a02d - md5: 2f96c58f89abccb04bbc8cd57961111f + version: 18.1.7 + build: default_hb9c8b4a_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libclang13-18.1.7-default_hb9c8b4a_0.conda + sha256: b90c5cd6e4aa49f26339b52464273c2020bdc24fb7fc596a7b80f4a79b0c1162 + md5: df9346ad9c343cf8ae933da34c092fa2 depends: - - libzlib >=1.2.13,<1.3.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - - zstd >=1.5.5,<1.6.0a0 + - __osx >=11.0 + - libcxx >=16.0.6 + - libllvm18 >=18.1.7,<18.2.0a0 license: Apache-2.0 WITH LLVM-exception license_family: Apache - size: 21892425 - timestamp: 1711067804682 + size: 7582344 + timestamp: 1717813859720 - kind: conda name: libcrc32c version: 1.1.2 @@ -14858,7 +14536,7 @@ packages: - krb5 >=1.21.1,<1.22.0a0 - libgcc-ng >=12 - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: Apache-2.0 license_family: Apache size: 4519402 @@ -14875,7 +14553,7 @@ packages: - krb5 >=1.21.2,<1.22.0a0 - libnghttp2 >=1.58.0,<2.0a0 - libssh2 >=1.11.0,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.3.0,<4.0a0 - zstd >=1.5.6,<1.6.0a0 license: curl @@ -14895,7 +14573,7 @@ packages: - libgcc-ng >=12 - libnghttp2 >=1.58.0,<2.0a0 - libssh2 >=1.11.0,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.3.0,<4.0a0 - zstd >=1.5.6,<1.6.0a0 license: curl @@ -14913,7 +14591,7 @@ packages: depends: - krb5 >=1.21.2,<1.22.0a0 - libssh2 >=1.11.0,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 @@ -14933,7 +14611,7 @@ packages: - krb5 >=1.21.2,<1.22.0a0 - libnghttp2 >=1.58.0,<2.0a0 - libssh2 >=1.11.0,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.3.0,<4.0a0 - zstd >=1.5.6,<1.6.0a0 license: curl @@ -14982,46 +14660,46 @@ packages: timestamp: 1694922440450 - kind: conda name: libdeflate - version: '1.19' - build: hb547adb_0 + version: '1.20' + build: h93a5062_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.19-hb547adb_0.conda - sha256: 6a3d188a6ae845a742dc85c5fb3f7eb1e252726cd74f0b8a7fa25ec09db6b87a - md5: f8c1eb0e99e90b55965c6558578537cc + url: https://conda.anaconda.org/conda-forge/osx-arm64/libdeflate-1.20-h93a5062_0.conda + sha256: 6d16cccb141b6bb05c38107b335089046664ea1d6611601d3f6e7e4227a99925 + md5: 97efeaeba2a9a82bdf46fc6d025e3a57 license: MIT license_family: MIT - size: 52841 - timestamp: 1694924330786 + size: 54481 + timestamp: 1711196723486 - kind: conda name: libdeflate - version: '1.19' + version: '1.20' build: hcfcfb64_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.19-hcfcfb64_0.conda - sha256: e2886a84eaa0fbeca1d1d810270f234431d190402b4a79acf756ca2d16000354 - md5: 002b1b723b44dbd286b9e3708762433c + url: https://conda.anaconda.org/conda-forge/win-64/libdeflate-1.20-hcfcfb64_0.conda + sha256: 6628a5b76ad70c1a0909563c637ddc446ee824739ba7c348d4da2f0aa6ac9527 + md5: b12b5bde5eb201a1df75e49320cc938a depends: - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 license: MIT license_family: MIT - size: 153203 - timestamp: 1694922596415 + size: 155358 + timestamp: 1711197066985 - kind: conda name: libdeflate - version: '1.19' + version: '1.20' build: hd590300_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.19-hd590300_0.conda - sha256: 985ad27aa0ba7aad82afa88a8ede6a1aacb0aaca950d710f15d85360451e72fd - md5: 1635570038840ee3f9c71d22aa5b8b6d + url: https://conda.anaconda.org/conda-forge/linux-64/libdeflate-1.20-hd590300_0.conda + sha256: f8e0f25c382b1d0b87a9b03887a34dbd91485453f1ea991fef726dba57373612 + md5: 8e88f9389f1165d7c0936fe40d9a9a79 depends: - libgcc-ng >=12 license: MIT license_family: MIT - size: 67080 - timestamp: 1694922285678 + size: 71500 + timestamp: 1711196523408 - kind: conda name: libdrm version: 2.4.120 @@ -15188,53 +14866,6 @@ packages: license_family: BSD size: 427426 timestamp: 1685725977222 -- kind: conda - name: libexpat - version: 2.5.0 - build: h63175ca_1 - build_number: 1 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libexpat-2.5.0-h63175ca_1.conda - sha256: 794b2a9be72f176a2767c299574d330ffb76b2ed75d7fd20bee3bbadce5886cf - md5: 636cc3cbbd2e28bcfd2f73b2044aac2c - constrains: - - expat 2.5.0.* - license: MIT - license_family: MIT - size: 138689 - timestamp: 1680190844101 -- kind: conda - name: libexpat - version: 2.5.0 - build: hb7217d7_1 - build_number: 1 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libexpat-2.5.0-hb7217d7_1.conda - sha256: 7d143a9c991579ad4207f84c632650a571c66329090daa32b3c87cf7311c3381 - md5: 5a097ad3d17e42c148c9566280481317 - constrains: - - expat 2.5.0.* - license: MIT - license_family: MIT - size: 63442 - timestamp: 1680190916539 -- kind: conda - name: libexpat - version: 2.5.0 - build: hcb278e6_1 - build_number: 1 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libexpat-2.5.0-hcb278e6_1.conda - sha256: 74c98a563777ae2ad71f1f74d458a8ab043cee4a513467c159ccf159d0e461f3 - md5: 6305a3dd2752c76335295da4e581f2fd - depends: - - libgcc-ng >=12 - constrains: - - expat 2.5.0.* - license: MIT - license_family: MIT - size: 77980 - timestamp: 1680190528313 - kind: conda name: libexpat version: 2.5.0 @@ -15386,21 +15017,20 @@ packages: - kind: conda name: libgcc-ng version: 13.2.0 - build: h77fa898_7 - build_number: 7 + build: h77fa898_10 + build_number: 10 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_7.conda - sha256: 62af2b89acbe74a21606c8410c276e57309c0a2ab8a9e8639e3c8131c0b60c92 - md5: 72ec1b1b04c4d15d4204ece1ecea5978 + url: https://conda.anaconda.org/conda-forge/linux-64/libgcc-ng-13.2.0-h77fa898_10.conda + sha256: 78931358d83ff585d0cd448632366a5cbe6bcf41a66c07e8178200008127c2b5 + md5: bbb96c5e7a11ef8ca2b666fe9fe3d199 depends: - _libgcc_mutex 0.1 conda_forge - _openmp_mutex >=4.5 constrains: - - libgomp 13.2.0 h77fa898_7 + - libgomp 13.2.0 h77fa898_10 license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - size: 775806 - timestamp: 1715016057793 + size: 802677 + timestamp: 1718485010755 - kind: conda name: libgcrypt version: 1.10.3 @@ -15438,7 +15068,7 @@ packages: - libtiff >=4.6.0,<4.7.0a0 - libwebp - libwebp-base >=1.3.2,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - zlib license: GD license_family: BSD @@ -15466,7 +15096,7 @@ packages: - libtiff >=4.6.0,<4.7.0a0 - libwebp - libwebp-base >=1.3.2,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - zlib license: GD license_family: BSD @@ -15493,7 +15123,7 @@ packages: - libtiff >=4.6.0,<4.7.0a0 - libwebp - libwebp-base >=1.3.2,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 @@ -15525,7 +15155,7 @@ packages: - libtiff >=4.6.0,<4.7.0a0 - libwebp - libwebp-base >=1.3.2,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - zlib license: GD license_family: BSD @@ -15568,7 +15198,7 @@ packages: - libtiff >=4.6.0,<4.7.0a0 - libwebp-base >=1.3.2,<2.0a0 - libxml2 >=2.12.5,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - openjpeg >=2.5.0,<3.0a0 - openssl >=3.2.1,<4.0a0 @@ -15587,68 +15217,70 @@ packages: - kind: conda name: libgdal version: 3.8.4 - build: h7c2897a_0 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libgdal-3.8.4-h7c2897a_0.conda - sha256: bb861002a1ac8dda09b8b55fe616ba5f086d68c5ff05c5246bdac28d747bcbff - md5: a9cf2825eb54cb14bad6bcf6020634e0 + build: h7181668_5 + build_number: 5 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libgdal-3.8.4-h7181668_5.conda + sha256: 7bb93c93ab3264a22af70d3aa3787b11f4092a0dcb2b6f838bbf3c2e2ee5bfb2 + md5: 795df87e28f1df475c180064e86e3917 depends: - blosc >=1.21.5,<2.0a0 - - cfitsio >=4.3.1,<4.3.2.0a0 + - cfitsio >=4.4.0,<4.4.1.0a0 - freexl >=2.0.0,<3.0a0 - geos >=3.12.1,<3.12.2.0a0 - geotiff >=1.7.1,<1.8.0a0 + - giflib >=5.2.1,<5.3.0a0 - hdf4 >=4.2.15,<4.2.16.0a0 - hdf5 >=1.14.3,<1.14.4.0a0 + - json-c >=0.17,<0.18.0a0 - kealib >=1.5.3,<1.6.0a0 - lerc >=4.0.0,<5.0a0 - - libaec >=1.1.2,<2.0a0 + - libaec >=1.1.3,<2.0a0 - libarchive >=3.7.2,<3.8.0a0 - - libcurl >=8.5.0,<9.0a0 - - libdeflate >=1.19,<1.20.0a0 - - libexpat >=2.5.0,<3.0a0 + - libcurl >=8.6.0,<9.0a0 + - libcxx >=16 + - libdeflate >=1.20,<1.21.0a0 + - libexpat >=2.6.2,<3.0a0 - libiconv >=1.17,<2.0a0 - libjpeg-turbo >=3.0.0,<4.0a0 - libkml >=1.3.0,<1.4.0a0 - libnetcdf >=4.9.2,<4.9.3.0a0 - - libpng >=1.6.42,<1.7.0a0 + - libpng >=1.6.43,<1.7.0a0 - libpq >=16.2,<17.0a0 - libspatialite >=5.1.0,<5.2.0a0 - - libsqlite >=3.45.1,<4.0a0 + - libsqlite >=3.45.2,<4.0a0 - libtiff >=4.6.0,<4.7.0a0 - libwebp-base >=1.3.2,<2.0a0 - - libxml2 >=2.12.5,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libxml2 >=2.12.6,<3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - - openjpeg >=2.5.0,<3.0a0 + - openjpeg >=2.5.2,<3.0a0 - openssl >=3.2.1,<4.0a0 - - pcre2 >=10.42,<10.43.0a0 - - poppler >=24.2.0,<24.3.0a0 + - pcre2 >=10.43,<10.44.0a0 + - poppler >=24.3.0,<24.4.0a0 - postgresql - proj >=9.3.1,<9.3.2.0a0 - - tiledb >=2.20.0,<2.21.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - tiledb >=2.21.1,<2.22.0a0 - xerces-c >=3.2.5,<3.3.0a0 - xz >=5.2.6,<6.0a0 - zstd >=1.5.5,<1.6.0a0 license: MIT license_family: MIT - size: 8653044 - timestamp: 1708280801946 + size: 8508601 + timestamp: 1711286913611 - kind: conda name: libgdal version: 3.8.4 - build: h9323651_0 + build: h7c88fdf_5 + build_number: 5 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libgdal-3.8.4-h9323651_0.conda - sha256: af88738b2eda7d388daad5bd7dd8fe66efbaba300921ecb6fb03d9c5823a950d - md5: f0444ecc68c3f7d0855c9dd6bc3424a7 + url: https://conda.anaconda.org/conda-forge/linux-64/libgdal-3.8.4-h7c88fdf_5.conda + sha256: caad3fbd31a1572a5688d27bcf863acc36866eeaf73c4af67e5e40480e87772e + md5: 750bfb344a8690e7089c8c2b303f252a depends: - __glibc >=2.17,<3.0.a0 - blosc >=1.21.5,<2.0a0 - - cfitsio >=4.3.1,<4.3.2.0a0 + - cfitsio >=4.4.0,<4.4.1.0a0 - freexl >=2.0.0,<3.0a0 - geos >=3.12.1,<3.12.2.0a0 - geotiff >=1.7.1,<1.8.0a0 @@ -15658,110 +15290,95 @@ packages: - json-c >=0.17,<0.18.0a0 - kealib >=1.5.3,<1.6.0a0 - lerc >=4.0.0,<5.0a0 - - libaec >=1.1.2,<2.0a0 + - libaec >=1.1.3,<2.0a0 - libarchive >=3.7.2,<3.8.0a0 - - libcurl >=8.5.0,<9.0a0 - - libdeflate >=1.19,<1.20.0a0 - - libexpat >=2.5.0,<3.0a0 + - libcurl >=8.6.0,<9.0a0 + - libdeflate >=1.20,<1.21.0a0 + - libexpat >=2.6.2,<3.0a0 - libgcc-ng >=12 - libiconv >=1.17,<2.0a0 - libjpeg-turbo >=3.0.0,<4.0a0 - libkml >=1.3.0,<1.4.0a0 - libnetcdf >=4.9.2,<4.9.3.0a0 - - libpng >=1.6.42,<1.7.0a0 + - libpng >=1.6.43,<1.7.0a0 - libpq >=16.2,<17.0a0 - libspatialite >=5.1.0,<5.2.0a0 - - libsqlite >=3.45.1,<4.0a0 + - libsqlite >=3.45.2,<4.0a0 - libstdcxx-ng >=12 - libtiff >=4.6.0,<4.7.0a0 - libuuid >=2.38.1,<3.0a0 - libwebp-base >=1.3.2,<2.0a0 - - libxml2 >=2.12.5,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libxml2 >=2.12.6,<3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - - openjpeg >=2.5.0,<3.0a0 + - openjpeg >=2.5.2,<3.0a0 - openssl >=3.2.1,<4.0a0 - - pcre2 >=10.42,<10.43.0a0 - - poppler >=24.2.0,<24.3.0a0 + - pcre2 >=10.43,<10.44.0a0 + - poppler >=24.3.0,<24.4.0a0 - postgresql - proj >=9.3.1,<9.3.2.0a0 - - tiledb >=2.20.0,<2.21.0a0 + - tiledb >=2.21.1,<2.22.0a0 - xerces-c >=3.2.5,<3.3.0a0 - xz >=5.2.6,<6.0a0 - zstd >=1.5.5,<1.6.0a0 license: MIT license_family: MIT - size: 11090543 - timestamp: 1708279552744 + size: 11113700 + timestamp: 1711285696664 - kind: conda name: libgdal version: 3.8.4 - build: ha86f356_0 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libgdal-3.8.4-ha86f356_0.conda - sha256: bff62d710f8a3ae6a0c4671c0584a7680e9e3a468003367ddf5bee8c90ff0079 - md5: a5d5f05fd2c03b0f1ba4863c8a1a0632 + build: hf83a0e2_5 + build_number: 5 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/libgdal-3.8.4-hf83a0e2_5.conda + sha256: 98e0e290f8cc76e66a386283240e35158bd22960b18301a7ca281a2aecaba01b + md5: 0efb428de61baca5231bdf6ef0a4de2d depends: - blosc >=1.21.5,<2.0a0 - - cfitsio >=4.3.1,<4.3.2.0a0 + - cfitsio >=4.4.0,<4.4.1.0a0 - freexl >=2.0.0,<3.0a0 - geos >=3.12.1,<3.12.2.0a0 - geotiff >=1.7.1,<1.8.0a0 - - giflib >=5.2.1,<5.3.0a0 - hdf4 >=4.2.15,<4.2.16.0a0 - hdf5 >=1.14.3,<1.14.4.0a0 - - json-c >=0.17,<0.18.0a0 - kealib >=1.5.3,<1.6.0a0 - lerc >=4.0.0,<5.0a0 - - libaec >=1.1.2,<2.0a0 + - libaec >=1.1.3,<2.0a0 - libarchive >=3.7.2,<3.8.0a0 - - libcurl >=8.5.0,<9.0a0 - - libcxx >=16 - - libdeflate >=1.19,<1.20.0a0 - - libexpat >=2.5.0,<3.0a0 + - libcurl >=8.6.0,<9.0a0 + - libdeflate >=1.20,<1.21.0a0 + - libexpat >=2.6.2,<3.0a0 - libiconv >=1.17,<2.0a0 - libjpeg-turbo >=3.0.0,<4.0a0 - libkml >=1.3.0,<1.4.0a0 - libnetcdf >=4.9.2,<4.9.3.0a0 - - libpng >=1.6.42,<1.7.0a0 + - libpng >=1.6.43,<1.7.0a0 - libpq >=16.2,<17.0a0 - libspatialite >=5.1.0,<5.2.0a0 - - libsqlite >=3.45.1,<4.0a0 + - libsqlite >=3.45.2,<4.0a0 - libtiff >=4.6.0,<4.7.0a0 - libwebp-base >=1.3.2,<2.0a0 - - libxml2 >=2.12.5,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libxml2 >=2.12.6,<3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - - openjpeg >=2.5.0,<3.0a0 + - openjpeg >=2.5.2,<3.0a0 - openssl >=3.2.1,<4.0a0 - - pcre2 >=10.42,<10.43.0a0 - - poppler >=24.2.0,<24.3.0a0 + - pcre2 >=10.43,<10.44.0a0 + - poppler >=24.3.0,<24.4.0a0 - postgresql - proj >=9.3.1,<9.3.2.0a0 - - tiledb >=2.20.0,<2.21.0a0 - - xerces-c >=3.2.5,<3.3.0a0 - - xz >=5.2.6,<6.0a0 - - zstd >=1.5.5,<1.6.0a0 - license: MIT - license_family: MIT - size: 8525451 - timestamp: 1708280934006 -- kind: conda - name: libgettextpo - version: 0.22.5 - build: h5728263_2 - build_number: 2 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libgettextpo-0.22.5-h5728263_2.conda - sha256: 445ecfc4bf5b474c2ac79f716dcb8459a08a532ab13a785744665f086ef94c95 - md5: f4c826b19bf1ccee2a63a2c685039728 - depends: - - libiconv >=1.17,<2.0a0 - - libintl 0.22.5 h5728263_2 - license: GPL-3.0-or-later - license_family: GPL - size: 171210 - timestamp: 1712516290149 + - tiledb >=2.21.1,<2.22.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + - xerces-c >=3.2.5,<3.3.0a0 + - xz >=5.2.6,<6.0a0 + - zstd >=1.5.5,<1.6.0a0 + license: MIT + license_family: MIT + size: 8622989 + timestamp: 1711286830900 - kind: conda name: libgettextpo version: 0.22.5 @@ -15809,23 +15426,6 @@ packages: license_family: GPL size: 159856 timestamp: 1712512788407 -- kind: conda - name: libgettextpo-devel - version: 0.22.5 - build: h5728263_2 - build_number: 2 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libgettextpo-devel-0.22.5-h5728263_2.conda - sha256: bcee730b2be23ba9aa5de3471b78c4644d3b17d5a71e7fdc59bb40e252edb2f7 - md5: 6f42ec61abc6d52a4079800a640319c5 - depends: - - libgettextpo 0.22.5 h5728263_2 - - libiconv >=1.17,<2.0a0 - - libintl 0.22.5 h5728263_2 - license: GPL-3.0-or-later - license_family: GPL - size: 40312 - timestamp: 1712516436925 - kind: conda name: libgettextpo-devel version: 0.22.5 @@ -15909,18 +15509,17 @@ packages: - kind: conda name: libgfortran-ng version: 13.2.0 - build: h69a702a_7 - build_number: 7 + build: h69a702a_10 + build_number: 10 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.2.0-h69a702a_7.conda - sha256: a588e69f96b8e0983a8cdfdbf1dc75eb48189f5420ec71150c8d8cdc0a811a9b - md5: 1b84f26d9f4f6026e179e7805d5a15cd + url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran-ng-13.2.0-h69a702a_10.conda + sha256: de97f291cda4be906c9021c93a9d5d40eb65ab7bd5cba38dfa11f12597d7ef6a + md5: a78f7b3d951665c4c57578a8d3787993 depends: - - libgfortran5 13.2.0 hca663fb_7 + - libgfortran5 13.2.0 h3d2ce59_10 license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - size: 24314 - timestamp: 1715016272844 + size: 48629 + timestamp: 1718485240765 - kind: conda name: libgfortran5 version: 13.2.0 @@ -15941,20 +15540,19 @@ packages: - kind: conda name: libgfortran5 version: 13.2.0 - build: hca663fb_7 - build_number: 7 + build: h3d2ce59_10 + build_number: 10 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-13.2.0-hca663fb_7.conda - sha256: 754ab038115edce550fdccdc9ddf7dead2fa8346b8cdd4428c59ae1e83293978 - md5: c0bd771f09a326fdcd95a60b617795bf + url: https://conda.anaconda.org/conda-forge/linux-64/libgfortran5-13.2.0-h3d2ce59_10.conda + sha256: be5f5873c392bc4c25bee25cef2d30a9dab69c0d82ff1ddf687f9ece6d36f56c + md5: e3896e5c2dd1cbabaf4abb3254df47b0 depends: - libgcc-ng >=13.2.0 constrains: - libgfortran-ng 13.2.0 license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - size: 1441361 - timestamp: 1715016068766 + size: 1463819 + timestamp: 1718485020621 - kind: conda name: libgfortran5 version: 13.2.0 @@ -15975,86 +15573,84 @@ packages: - kind: conda name: libglib version: 2.78.4 - build: h1635a5e_0 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libglib-2.78.4-h1635a5e_0.conda - sha256: 8229251ab78074d16c372b5995f19f967321328fdf8723feab7efec66fe6cc03 - md5: 537ff7a85b63d478e563530dfe66a71e + build: hab64008_0 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/libglib-2.78.4-hab64008_0.conda + sha256: 122060ba63fd27e53672dbac7dc0b4f55a6432993446f4ed3c30a69a9457c615 + md5: ff7e302784375cfc3157b8120a18124d depends: - gettext >=0.21.1,<1.0a0 - libcxx >=16 - libffi >=3.4,<4.0a0 - libiconv >=1.17,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - pcre2 >=10.42,<10.43.0a0 constrains: - glib 2.78.4 *_0 license: LGPL-2.1-or-later - size: 2437234 - timestamp: 1708285905755 + size: 2474668 + timestamp: 1708285048757 - kind: conda name: libglib - version: 2.78.4 - build: h16e383f_0 + version: 2.80.2 + build: h0df6a38_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libglib-2.78.4-h16e383f_0.conda - sha256: d4350c4c8d7947b4f1b13918e04f07a35d2eb88cc1b6bccefe12eb92bd1aa660 - md5: 72dc4e1cdde0894015567c90f9c4e261 + url: https://conda.anaconda.org/conda-forge/win-64/libglib-2.80.2-h0df6a38_0.conda + sha256: 941bbe089a7a87fbe88324bfc7970a1688c7a765490e25b829ff73c7abc3fc5a + md5: ef9ae80bb2a15aee7a30180c057678ea depends: - - gettext >=0.21.1,<1.0a0 - libffi >=3.4,<4.0a0 - libiconv >=1.17,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 - - pcre2 >=10.42,<10.43.0a0 + - libintl >=0.22.5,<1.0a0 + - libzlib >=1.2.13,<2.0.0a0 + - pcre2 >=10.43,<10.44.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 constrains: - - glib 2.78.4 *_0 + - glib 2.80.2 *_0 license: LGPL-2.1-or-later - size: 2627113 - timestamp: 1708285165773 + size: 3749179 + timestamp: 1715253077632 - kind: conda name: libglib - version: 2.78.4 - build: h783c2da_0 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.78.4-h783c2da_0.conda - sha256: 3a03a5254d2fd29c1e0ffda7250e22991dfbf2c854301fd56c408d97a647cfbd - md5: d86baf8740d1a906b9716f2a0bac2f2d + version: 2.80.2 + build: h535f939_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libglib-2.80.2-h535f939_0.conda + sha256: 3f0c9f25748787ab5475c5ce8267184d6637e8a5b7ca55ef2f3a0d7bff2f537f + md5: 4ac7cb698ca919924e205af3ab3aacf3 depends: - - gettext >=0.21.1,<1.0a0 + - __osx >=11.0 - libffi >=3.4,<4.0a0 - - libgcc-ng >=12 - libiconv >=1.17,<2.0a0 - - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 - - pcre2 >=10.42,<10.43.0a0 + - libintl >=0.22.5,<1.0a0 + - libzlib >=1.2.13,<2.0.0a0 + - pcre2 >=10.43,<10.44.0a0 constrains: - - glib 2.78.4 *_0 + - glib 2.80.2 *_0 license: LGPL-2.1-or-later - size: 2692079 - timestamp: 1708284870228 + size: 3623970 + timestamp: 1715252979767 - kind: conda name: libglib - version: 2.78.4 - build: hab64008_0 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/libglib-2.78.4-hab64008_0.conda - sha256: 122060ba63fd27e53672dbac7dc0b4f55a6432993446f4ed3c30a69a9457c615 - md5: ff7e302784375cfc3157b8120a18124d + version: 2.80.2 + build: hf974151_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libglib-2.80.2-hf974151_0.conda + sha256: 93e03b6cf4765bc06d64fa3dac65f22c53ae4a30247bb0e2dea0bd9c47a3fb26 + md5: 72724f6a78ecb15559396966226d5838 depends: - - gettext >=0.21.1,<1.0a0 - - libcxx >=16 - libffi >=3.4,<4.0a0 + - libgcc-ng >=12 - libiconv >=1.17,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 - - pcre2 >=10.42,<10.43.0a0 + - libzlib >=1.2.13,<2.0.0a0 + - pcre2 >=10.43,<10.44.0a0 constrains: - - glib 2.78.4 *_0 + - glib 2.80.2 *_0 license: LGPL-2.1-or-later - size: 2474668 - timestamp: 1708285048757 + size: 3912673 + timestamp: 1715252654366 - kind: conda name: libglu version: 9.0.0 @@ -16077,18 +15673,17 @@ packages: - kind: conda name: libgomp version: 13.2.0 - build: h77fa898_7 - build_number: 7 + build: h77fa898_10 + build_number: 10 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_7.conda - sha256: 781444fa069d3b50e8ed667b750571cacda785761c7fc2a89ece1ac49693d4ad - md5: abf3fec87c2563697defa759dec3d639 + url: https://conda.anaconda.org/conda-forge/linux-64/libgomp-13.2.0-h77fa898_10.conda + sha256: bcea6ddfea86f0e6a1a831d1d2c3f36f7613b5e447229e19f978ded0d184cf5a + md5: 9404d1686e63142d41acc72ef876a588 depends: - _libgcc_mutex 0.1 conda_forge license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - size: 422336 - timestamp: 1715015995979 + size: 444719 + timestamp: 1718484940121 - kind: conda name: libgoogle-cloud version: 2.22.0 @@ -16115,163 +15710,161 @@ packages: timestamp: 1709738549021 - kind: conda name: libgoogle-cloud - version: 2.22.0 - build: h9be4e54_1 + version: 2.23.0 + build: h68df31e_1 build_number: 1 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.22.0-h9be4e54_1.conda - sha256: b9980209438b22113f4352df2b260bf43b2eb63a7b6325192ec5ae3a562872ed - md5: 4b4e36a91e7dabf7345b82d85767a7c3 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/libgoogle-cloud-2.23.0-h68df31e_1.conda + sha256: fba9e1d32302eec582bea67958d1c4fac446b231c579ae8fead45ee54f66490d + md5: a0ef5adaf00591f68185bc59c7ebcb48 depends: - libabseil * cxx17* - libabseil >=20240116.1,<20240117.0a0 - - libcurl >=8.5.0,<9.0a0 - - libgcc-ng >=12 - - libgrpc >=1.62.0,<1.63.0a0 + - libcurl >=8.7.1,<9.0a0 + - libgrpc >=1.62.2,<1.63.0a0 - libprotobuf >=4.25.3,<4.25.4.0a0 - - libstdcxx-ng >=12 - - openssl >=3.2.1,<4.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 constrains: - - libgoogle-cloud 2.22.0 *_1 + - libgoogle-cloud 2.23.0 *_1 license: Apache-2.0 license_family: Apache - size: 1209816 - timestamp: 1709737846418 + size: 14424 + timestamp: 1713800484262 - kind: conda name: libgoogle-cloud - version: 2.22.0 - build: h9cad5c0_1 + version: 2.23.0 + build: h9be4e54_1 build_number: 1 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libgoogle-cloud-2.22.0-h9cad5c0_1.conda - sha256: f76e892d13e1db405777c968787678d8ba912b7e4eef7f950fcdcca185e06e71 - md5: 63cd44a71f00d4e72844bf0e8be56be4 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-2.23.0-h9be4e54_1.conda + sha256: 680f5a9bc45aa905d9da086b16551438553649e05dd6b94b02b379b050602d5e + md5: 1042d8401bb268553f98e60120cdeb40 depends: - libabseil * cxx17* - libabseil >=20240116.1,<20240117.0a0 - - libcurl >=8.5.0,<9.0a0 - - libgrpc >=1.62.0,<1.63.0a0 + - libcurl >=8.7.1,<9.0a0 + - libgcc-ng >=12 + - libgrpc >=1.62.2,<1.63.0a0 - libprotobuf >=4.25.3,<4.25.4.0a0 + - libstdcxx-ng >=12 - openssl >=3.2.1,<4.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 constrains: - - libgoogle-cloud 2.22.0 *_1 + - libgoogle-cloud 2.23.0 *_1 license: Apache-2.0 license_family: Apache - size: 14420 - timestamp: 1709737037941 + size: 1214608 + timestamp: 1713798219648 - kind: conda name: libgoogle-cloud - version: 2.22.0 + version: 2.23.0 build: hbebe991_1 build_number: 1 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libgoogle-cloud-2.22.0-hbebe991_1.conda - sha256: a114b4d46eebede7e514abaf9203ea8c952a6382c5c57d1b989da062e3899bd7 - md5: ec7ea95b08e8cbc39fa16b6eafee36e6 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libgoogle-cloud-2.23.0-hbebe991_1.conda + sha256: db7c0dcebafc001ff9fe0ba618ed611721217b4ceefeef189ab79ef111056c02 + md5: fdbdbd1dc8e8ba458057be0a00db8ab1 depends: - libabseil * cxx17* - libabseil >=20240116.1,<20240117.0a0 - - libcurl >=8.5.0,<9.0a0 + - libcurl >=8.7.1,<9.0a0 - libcxx >=16 - - libgrpc >=1.62.0,<1.63.0a0 + - libgrpc >=1.62.2,<1.63.0a0 - libprotobuf >=4.25.3,<4.25.4.0a0 - openssl >=3.2.1,<4.0a0 constrains: - - libgoogle-cloud 2.22.0 *_1 + - libgoogle-cloud 2.23.0 *_1 license: Apache-2.0 license_family: Apache - size: 836916 - timestamp: 1709739767863 + size: 840819 + timestamp: 1713799797441 - kind: conda name: libgoogle-cloud-storage version: 2.22.0 - build: h8a76758_1 + build: ha67e85c_1 build_number: 1 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libgoogle-cloud-storage-2.22.0-h8a76758_1.conda - sha256: e23be5896fd78e0e8b1098aab8803192f0c4a328d3d30a57d20d80194045d793 - md5: a89fb5b36b08efaae128d4933e593315 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/libgoogle-cloud-storage-2.22.0-ha67e85c_1.conda + sha256: e4f351e55fe7c0656cb608eba8690063e3b407d25a855c9d1fd832486d4a1244 + md5: 0c25180c34b1a58d309b28386698fb6e depends: - libabseil - libcrc32c >=1.1.2,<1.2.0a0 - libcurl - libcxx >=16 - - libgoogle-cloud 2.22.0 hbebe991_1 - - libzlib >=1.2.13,<1.3.0a0 + - libgoogle-cloud 2.22.0 h651e89d_1 + - libzlib >=1.2.13,<2.0.0a0 - openssl license: Apache-2.0 license_family: Apache - size: 507478 - timestamp: 1709740510222 + size: 523045 + timestamp: 1709739227970 - kind: conda name: libgoogle-cloud-storage - version: 2.22.0 - build: ha67e85c_1 + version: 2.23.0 + build: h8a76758_1 build_number: 1 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/libgoogle-cloud-storage-2.22.0-ha67e85c_1.conda - sha256: e4f351e55fe7c0656cb608eba8690063e3b407d25a855c9d1fd832486d4a1244 - md5: 0c25180c34b1a58d309b28386698fb6e + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libgoogle-cloud-storage-2.23.0-h8a76758_1.conda + sha256: 3173b65b7e36e9fa0e6ddec69f39e4dd0e7ada38dbf2c1be006fddc2e7257b0c + md5: 356c74978867e07e12a939a092dcf30d depends: - libabseil - libcrc32c >=1.1.2,<1.2.0a0 - libcurl - libcxx >=16 - - libgoogle-cloud 2.22.0 h651e89d_1 - - libzlib >=1.2.13,<1.3.0a0 + - libgoogle-cloud 2.23.0 hbebe991_1 + - libzlib >=1.2.13,<2.0.0a0 - openssl license: Apache-2.0 license_family: Apache - size: 523045 - timestamp: 1709739227970 + size: 509643 + timestamp: 1713801031940 - kind: conda name: libgoogle-cloud-storage - version: 2.22.0 + version: 2.23.0 build: hb581fae_1 build_number: 1 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libgoogle-cloud-storage-2.22.0-hb581fae_1.conda - sha256: 5ee34f168948211db14874f521e6edf9b4032d533c61fd429caaa282be1d0e7b - md5: f63348292dea55cf834e631cf26e2669 + url: https://conda.anaconda.org/conda-forge/win-64/libgoogle-cloud-storage-2.23.0-hb581fae_1.conda + sha256: b7be440cb21b2c8c41064f1a334b9117ed5e4f0b98c5315650194161f7702283 + md5: af19093e2d4171ddef39e9d6457c4e2e depends: - libabseil - libcrc32c >=1.1.2,<1.2.0a0 - libcurl - - libgoogle-cloud 2.22.0 h9cad5c0_1 - - libzlib >=1.2.13,<1.3.0a0 - - openssl + - libgoogle-cloud 2.23.0 h68df31e_1 + - libzlib >=1.2.13,<2.0.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 license: Apache-2.0 license_family: Apache - size: 14330 - timestamp: 1709737542249 + size: 14323 + timestamp: 1713800995993 - kind: conda name: libgoogle-cloud-storage - version: 2.22.0 + version: 2.23.0 build: hc7a4891_1 build_number: 1 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.22.0-hc7a4891_1.conda - sha256: 0e00e1ca2a981db1c96071edf266bc29fd6f13ac484225de1736fc4dac5c64a8 - md5: 7811f043944e010e54640918ea82cecd + url: https://conda.anaconda.org/conda-forge/linux-64/libgoogle-cloud-storage-2.23.0-hc7a4891_1.conda + sha256: b85ce8b78e9262670a145a1639e253708e2a9eb9100d60ccec16f8e41d87a4bb + md5: ee99fb9107ffb579b58ee92a5fb14b06 depends: - libabseil - libcrc32c >=1.1.2,<1.2.0a0 - libcurl - libgcc-ng >=12 - - libgoogle-cloud 2.22.0 h9be4e54_1 + - libgoogle-cloud 2.23.0 h9be4e54_1 - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl license: Apache-2.0 license_family: Apache - size: 748818 - timestamp: 1709738181078 + size: 752661 + timestamp: 1713798390317 - kind: conda name: libgpg-error version: '1.49' @@ -16306,7 +15899,7 @@ packages: - libprotobuf >=4.25.3,<4.25.4.0a0 - libre2-11 >=2023.9.1,<2024.0a0 - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.2.1,<4.0a0 - re2 constrains: @@ -16331,7 +15924,7 @@ packages: - libcxx >=16 - libprotobuf >=4.25.3,<4.25.4.0a0 - libre2-11 >=2023.9.1,<2024.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.2.1,<4.0a0 - re2 constrains: @@ -16354,7 +15947,7 @@ packages: - libabseil >=20240116.1,<20240117.0a0 - libprotobuf >=4.25.3,<4.25.4.0a0 - libre2-11 >=2023.9.1,<2024.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.2.1,<4.0a0 - re2 - ucrt >=10.0.20348.0 @@ -16381,7 +15974,7 @@ packages: - libcxx >=16 - libprotobuf >=4.25.3,<4.25.4.0a0 - libre2-11 >=2023.9.1,<2024.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.2.1,<4.0a0 - re2 constrains: @@ -16720,7 +16313,7 @@ packages: - libexpat >=2.5.0,<3.0a0 - libgcc-ng >=12 - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - uriparser >=0.9.7,<1.0a0 license: BSD-3-Clause license_family: BSD @@ -16739,7 +16332,7 @@ packages: - libboost-headers - libcxx >=15.0.7 - libexpat >=2.5.0,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - uriparser >=0.9.7,<1.0a0 license: BSD-3-Clause license_family: BSD @@ -16758,7 +16351,7 @@ packages: - libboost-headers - libcxx >=15.0.7 - libexpat >=2.5.0,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - uriparser >=0.9.7,<1.0a0 license: BSD-3-Clause license_family: BSD @@ -16776,7 +16369,7 @@ packages: depends: - libboost-headers - libexpat >=2.5.0,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ucrt >=10.0.20348.0 - uriparser >=0.9.7,<1.0a0 - vc >=14.2,<15 @@ -16872,7 +16465,7 @@ packages: md5: ed06753e2ba7c66ed0ca7f19578fcb68 depends: - libcxx >=15 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: Apache-2.0 WITH LLVM-exception license_family: Apache size: 22467131 @@ -16889,7 +16482,7 @@ packages: depends: - libgcc-ng >=12 - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: Apache-2.0 WITH LLVM-exception license_family: Apache size: 31484415 @@ -16905,28 +16498,11 @@ packages: md5: 9f3dce5d26ea56a9000cd74c034582bd depends: - libcxx >=15 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: Apache-2.0 WITH LLVM-exception license_family: Apache size: 20571387 timestamp: 1690559110016 -- kind: conda - name: libllvm15 - version: 15.0.7 - build: h2621b3d_4 - build_number: 4 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm15-15.0.7-h2621b3d_4.conda - sha256: 63e22ccd4c1b80dfc7da169c65c62a878a46ef0e5771c3b0c091071e718ae1b1 - md5: 8d7f7a7286d99a2671df2619cb3bfb2c - depends: - - libcxx >=16 - - libxml2 >=2.12.1,<3.0.0a0 - - libzlib >=1.2.13,<1.3.0a0 - license: Apache-2.0 WITH LLVM-exception - license_family: Apache - size: 22049607 - timestamp: 1701372072765 - kind: conda name: libllvm15 version: 15.0.7 @@ -16940,7 +16516,7 @@ packages: - libgcc-ng >=12 - libstdcxx-ng >=12 - libxml2 >=2.12.1,<3.0.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - zstd >=1.5.5,<1.6.0a0 license: Apache-2.0 WITH LLVM-exception license_family: Apache @@ -16958,7 +16534,7 @@ packages: depends: - libcxx >=16 - libxml2 >=2.12.1,<3.0.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - zstd >=1.5.5,<1.6.0a0 license: Apache-2.0 WITH LLVM-exception license_family: Apache @@ -16976,31 +16552,12 @@ packages: depends: - libcxx >=16 - libxml2 >=2.12.1,<3.0.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - zstd >=1.5.5,<1.6.0a0 license: Apache-2.0 WITH LLVM-exception license_family: Apache size: 23347663 timestamp: 1701374993634 -- kind: conda - name: libllvm16 - version: 16.0.6 - build: hb3ce162_3 - build_number: 3 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libllvm16-16.0.6-hb3ce162_3.conda - sha256: 624fa4012397bc5a8c9269247bf9baa7d907eb59079aefc6f6fa6a40f10fd0ba - md5: a4d48c40dd5c60edbab7fd69c9a88967 - depends: - - libgcc-ng >=12 - - libstdcxx-ng >=12 - - libxml2 >=2.12.1,<3.0.0a0 - - libzlib >=1.2.13,<1.3.0a0 - - zstd >=1.5.5,<1.6.0a0 - license: Apache-2.0 WITH LLVM-exception - license_family: Apache - size: 35359734 - timestamp: 1701375139881 - kind: conda name: libllvm16 version: 16.0.6 @@ -17013,124 +16570,160 @@ packages: depends: - libcxx >=16 - libxml2 >=2.12.1,<3.0.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - zstd >=1.5.5,<1.6.0a0 license: Apache-2.0 WITH LLVM-exception license_family: Apache size: 25196932 timestamp: 1701379796962 +- kind: conda + name: libllvm18 + version: 18.1.7 + build: hb77312f_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libllvm18-18.1.7-hb77312f_0.conda + sha256: 9a9167b3e8e05abc517671fe45e5d40ae866d3e8195865ddad3c68131d059e25 + md5: bc0ea7e1f75a9b1c8467597fbbd9f86b + depends: + - libgcc-ng >=12 + - libstdcxx-ng >=12 + - libxml2 >=2.12.7,<3.0a0 + - libzlib >=1.2.13,<2.0a0 + - zstd >=1.5.6,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 38423980 + timestamp: 1717781615068 +- kind: conda + name: libllvm18 + version: 18.1.7 + build: hdac5640_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libllvm18-18.1.7-hdac5640_0.conda + sha256: 43257397b65120961fe0b922ef56021de9787c3a3226227a69c794a195658791 + md5: 25b48815b00f4309d59bade2d6deb468 + depends: + - __osx >=11.0 + - libcxx >=16 + - libxml2 >=2.12.7,<3.0a0 + - libzlib >=1.2.13,<2.0a0 + - zstd >=1.5.6,<1.6.0a0 + license: Apache-2.0 WITH LLVM-exception + license_family: Apache + size: 25787088 + timestamp: 1717772004969 - kind: conda name: libnetcdf version: 4.9.2 - build: nompi_h07c049d_113 - build_number: 113 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libnetcdf-4.9.2-nompi_h07c049d_113.conda - sha256: 4b06a7aa1fcfb3406e3eab9368089d612ea014402edd5deefb2f02b73cf3673d - md5: 2aa431a5a05e3679eea4faad0f47b119 + build: nompi_h135f659_114 + build_number: 114 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libnetcdf-4.9.2-nompi_h135f659_114.conda + sha256: 055572a4c8a1c3f9ac60071ee678f5ea49cfd7ac60a636d817988a6f9d6de6ae + md5: a908e463c710bd6b10a9eaa89fdf003c depends: - blosc >=1.21.5,<2.0a0 - bzip2 >=1.0.8,<2.0a0 - hdf4 >=4.2.15,<4.2.16.0a0 - hdf5 >=1.14.3,<1.14.4.0a0 - - libaec >=1.1.2,<2.0a0 - - libcurl >=8.5.0,<9.0a0 - - libxml2 >=2.12.2,<3.0.0a0 + - libaec >=1.1.3,<2.0a0 + - libcurl >=8.8.0,<9.0a0 + - libgcc-ng >=12 + - libstdcxx-ng >=12 + - libxml2 >=2.12.7,<3.0a0 - libzip >=1.10.1,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - libzlib >=1.2.13,<2.0a0 + - openssl >=3.3.1,<4.0a0 - zlib - - zstd >=1.5.5,<1.6.0a0 + - zstd >=1.5.6,<1.6.0a0 license: MIT license_family: MIT - size: 625091 - timestamp: 1702229854053 + size: 849172 + timestamp: 1717671645362 - kind: conda name: libnetcdf version: 4.9.2 - build: nompi_h291a7c2_113 - build_number: 113 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libnetcdf-4.9.2-nompi_h291a7c2_113.conda - sha256: e5c0e8071029fdffc4219fa03bf2cb05e910459e1d55da3bc0d8ab70ddd0325e - md5: ad4f2f848502515d706cecd73ac9ec86 + build: nompi_h7334405_114 + build_number: 114 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/libnetcdf-4.9.2-nompi_h7334405_114.conda + sha256: a4af96274a6c72d97e84dfc728ecc765af300de805d962a835c0841bb6a8f331 + md5: 32ffbe5b0b0134e49f6347f4de8c5dcc depends: - - __osx >=10.9 + - __osx >=10.13 - blosc >=1.21.5,<2.0a0 - bzip2 >=1.0.8,<2.0a0 - hdf4 >=4.2.15,<4.2.16.0a0 - hdf5 >=1.14.3,<1.14.4.0a0 - - libaec >=1.1.2,<2.0a0 - - libcurl >=8.5.0,<9.0a0 - - libcxx >=16.0.6 - - libxml2 >=2.12.2,<3.0.0a0 + - libaec >=1.1.3,<2.0a0 + - libcurl >=8.8.0,<9.0a0 + - libcxx >=16 + - libxml2 >=2.12.7,<3.0a0 - libzip >=1.10.1,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 - - openssl >=3.2.0,<4.0a0 + - libzlib >=1.2.13,<2.0a0 + - openssl >=3.3.1,<4.0a0 - zlib - - zstd >=1.5.5,<1.6.0a0 + - zstd >=1.5.6,<1.6.0a0 license: MIT license_family: MIT - size: 682144 - timestamp: 1702229583910 + size: 726205 + timestamp: 1717671847032 - kind: conda name: libnetcdf version: 4.9.2 - build: nompi_h7760872_113 - build_number: 113 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/libnetcdf-4.9.2-nompi_h7760872_113.conda - sha256: 3d6a950d82a8dfb9fa51c263e543cfa9c113703add20646ec85401e7b557da49 - md5: bce76ace6497221c2a2a02840aaceac5 + build: nompi_h92078aa_114 + build_number: 114 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/libnetcdf-4.9.2-nompi_h92078aa_114.conda + sha256: 111fb98bf02e717c69eb78388a5b03dc7af05bfa840ac51c2b31beb70bf42318 + md5: 819507db3802d9a179de4d161285c22f depends: - - __osx >=10.9 - blosc >=1.21.5,<2.0a0 - bzip2 >=1.0.8,<2.0a0 - hdf4 >=4.2.15,<4.2.16.0a0 - hdf5 >=1.14.3,<1.14.4.0a0 - - libaec >=1.1.2,<2.0a0 - - libcurl >=8.5.0,<9.0a0 - - libcxx >=16.0.6 - - libxml2 >=2.12.2,<3.0.0a0 + - libaec >=1.1.3,<2.0a0 + - libcurl >=8.8.0,<9.0a0 + - libxml2 >=2.12.7,<3.0a0 - libzip >=1.10.1,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 - - openssl >=3.2.0,<4.0a0 + - libzlib >=1.2.13,<2.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 - zlib - - zstd >=1.5.5,<1.6.0a0 + - zstd >=1.5.6,<1.6.0a0 license: MIT license_family: MIT - size: 724322 - timestamp: 1702229765562 + size: 624793 + timestamp: 1717672198533 - kind: conda name: libnetcdf version: 4.9.2 - build: nompi_h9612171_113 - build_number: 113 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libnetcdf-4.9.2-nompi_h9612171_113.conda - sha256: 0b4d984c7be21531e9254ce742e04101f7f7e77c0bbb7074855c0806c28323b0 - md5: b2414908e43c442ddc68e6148774a304 + build: nompi_he469be0_114 + build_number: 114 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libnetcdf-4.9.2-nompi_he469be0_114.conda + sha256: aeac591ba859f9cf775993e8b7f21e50803405d41ef363dc4981d114e8df88a8 + md5: 8fd3ce6d910ed831c130c391c4364d3f depends: + - __osx >=11.0 - blosc >=1.21.5,<2.0a0 - bzip2 >=1.0.8,<2.0a0 - hdf4 >=4.2.15,<4.2.16.0a0 - hdf5 >=1.14.3,<1.14.4.0a0 - - libaec >=1.1.2,<2.0a0 - - libcurl >=8.5.0,<9.0a0 - - libgcc-ng >=12 - - libstdcxx-ng >=12 - - libxml2 >=2.12.2,<3.0.0a0 + - libaec >=1.1.3,<2.0a0 + - libcurl >=8.8.0,<9.0a0 + - libcxx >=16 + - libxml2 >=2.12.7,<3.0a0 - libzip >=1.10.1,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 - - openssl >=3.2.0,<4.0a0 + - libzlib >=1.2.13,<2.0a0 + - openssl >=3.3.1,<4.0a0 - zlib - - zstd >=1.5.5,<1.6.0a0 + - zstd >=1.5.6,<1.6.0a0 license: MIT license_family: MIT - size: 849037 - timestamp: 1702229195031 + size: 681051 + timestamp: 1717671966211 - kind: conda name: libnghttp2 version: 1.58.0 @@ -17146,7 +16739,7 @@ packages: - libev >=4.33,<5.0a0 - libgcc-ng >=12 - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.2.0,<4.0a0 license: MIT license_family: MIT @@ -17167,7 +16760,7 @@ packages: - libcxx >=16.0.6 - libev >=4.33,<4.34.0a0 - libev >=4.33,<5.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.2.0,<4.0a0 license: MIT license_family: MIT @@ -17188,26 +16781,12 @@ packages: - libcxx >=16.0.6 - libev >=4.33,<4.34.0a0 - libev >=4.33,<5.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.2.0,<4.0a0 license: MIT license_family: MIT size: 565451 timestamp: 1702130473930 -- kind: conda - name: libnl - version: 3.9.0 - build: hd590300_0 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libnl-3.9.0-hd590300_0.conda - sha256: aae03117811e704c3f3666e8374dd2e632f1d78bef0c27330e7298b24004819e - md5: d27c451db4f1d3c983c78167d2fdabc2 - depends: - - libgcc-ng >=12 - license: LGPL-2.1-or-later - license_family: LGPL - size: 732866 - timestamp: 1702657849946 - kind: conda name: libnsl version: 2.0.1 @@ -17336,86 +16915,69 @@ packages: - kind: conda name: libopenvino version: 2024.0.0 - build: h200475e_5 + build: hcdf21a5_5 build_number: 5 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-2024.0.0-h200475e_5.conda - sha256: 76d61013cfcc4f2d36c9e28d4465c3721b005fcbc2a5bc6404755bfe71573694 - md5: ddc93f2550998187cd23f00386c6a220 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/libopenvino-2024.0.0-hcdf21a5_5.conda + sha256: 41f6bee366ed444d96414a8c2b2f973907c3d174aa221495a212e24808cbf477 + md5: 7d0085f4204bf52696ebb2d3d23a7e18 depends: - - __osx >=11.0 + - __osx >=10.13 - libcxx >=16 - pugixml >=1.14,<1.15.0a0 - tbb >=2021.11.0 - size: 3667136 - timestamp: 1712671410901 + size: 3968556 + timestamp: 1712673697018 - kind: conda name: libopenvino - version: 2024.0.0 - build: h2da1b83_5 - build_number: 5 + version: 2024.1.0 + build: h2da1b83_7 + build_number: 7 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-2024.0.0-h2da1b83_5.conda - sha256: ef0f39b7378663c296cddc184f0a028d6a5178fc61d145fd9407f635edb15de7 - md5: 87d1f91d897ed6678a615536a25fd13f + url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-2024.1.0-h2da1b83_7.conda + sha256: 8af6ecc01993cac30656a78a5e82f81b04a663623563776d4d0a6688597b925f + md5: 692bb11510bfceb34723c5115045096e depends: - __glibc >=2.17,<3.0.a0 - libgcc-ng >=12 - libstdcxx-ng >=12 - pugixml >=1.14,<1.15.0a0 - - tbb >=2021.11.0 - size: 5113894 - timestamp: 1712674184348 + - tbb >=2021.12.0 + size: 5106629 + timestamp: 1715781430418 - kind: conda name: libopenvino - version: 2024.0.0 - build: hcdf21a5_5 - build_number: 5 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/libopenvino-2024.0.0-hcdf21a5_5.conda - sha256: 41f6bee366ed444d96414a8c2b2f973907c3d174aa221495a212e24808cbf477 - md5: 7d0085f4204bf52696ebb2d3d23a7e18 - depends: - - __osx >=10.13 - - libcxx >=16 - - pugixml >=1.14,<1.15.0a0 - - tbb >=2021.11.0 - size: 3968556 - timestamp: 1712673697018 -- kind: conda - name: libopenvino-arm-cpu-plugin - version: 2024.0.0 - build: h200475e_5 - build_number: 5 + version: 2024.1.0 + build: h5c9529b_7 + build_number: 7 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-arm-cpu-plugin-2024.0.0-h200475e_5.conda - sha256: a1e2575c386bfc04e8febaf90d031e19db22eabd9ee37a8a1c26086daff2faae - md5: 8ea9b802fdac0a53a4dab2cde18dd45a + url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-2024.1.0-h5c9529b_7.conda + sha256: 8726ffae902a89256ef2ac47d558d371a81278b7217f89aff7b54d58c2274e21 + md5: 1087dc2e91d634ed72952e16328713c9 depends: - __osx >=11.0 - libcxx >=16 - - libopenvino 2024.0.0 h200475e_5 - pugixml >=1.14,<1.15.0a0 - - tbb >=2021.11.0 - size: 5914197 - timestamp: 1712671469472 + - tbb >=2021.12.0 + size: 3668866 + timestamp: 1715778736422 - kind: conda - name: libopenvino-auto-batch-plugin - version: 2024.0.0 - build: hb045406_5 - build_number: 5 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-auto-batch-plugin-2024.0.0-hb045406_5.conda - sha256: 51aff831cbb65ee29ddd977c66a5a0224b2580ea7fe131885054bc8effa74e4f - md5: ddbb87c004506e586b79b674f0696aa3 + name: libopenvino-arm-cpu-plugin + version: 2024.1.0 + build: h5c9529b_7 + build_number: 7 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-arm-cpu-plugin-2024.1.0-h5c9529b_7.conda + sha256: 9aec78ad00936f351521c681e65b12d1ab98a69f2b982b4d255ceedbef069118 + md5: f7b2bd460da8289623aa8164fe1686f4 depends: - - __glibc >=2.17,<3.0.a0 - - libgcc-ng >=12 - - libopenvino 2024.0.0 h2da1b83_5 - - libstdcxx-ng >=12 - - tbb >=2021.11.0 - size: 110915 - timestamp: 1712674229190 + - __osx >=11.0 + - libcxx >=16 + - libopenvino 2024.1.0 h5c9529b_7 + - pugixml >=1.14,<1.15.0a0 + - tbb >=2021.12.0 + size: 6072244 + timestamp: 1715778784198 - kind: conda name: libopenvino-auto-batch-plugin version: 2024.0.0 @@ -17434,37 +16996,37 @@ packages: timestamp: 1712673767712 - kind: conda name: libopenvino-auto-batch-plugin - version: 2024.0.0 - build: hfaea8b3_5 - build_number: 5 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-auto-batch-plugin-2024.0.0-hfaea8b3_5.conda - sha256: 1331f46bbb021c17dedc2a22037549356a7a6f0e32d5b2b0fd907ab474acd5f3 - md5: cced16c374da830c30de83586dc56f83 - depends: - - __osx >=11.0 - - libcxx >=16 - - libopenvino 2024.0.0 h200475e_5 - - tbb >=2021.11.0 - size: 102182 - timestamp: 1712671541106 -- kind: conda - name: libopenvino-auto-plugin - version: 2024.0.0 - build: hb045406_5 - build_number: 5 + version: 2024.1.0 + build: hb045406_7 + build_number: 7 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-auto-plugin-2024.0.0-hb045406_5.conda - sha256: 63c26a03ea8953cccde1302b26520ef53dccce6d1e234c25fc249c1ea75f14d1 - md5: 59aad82eda612aa46ba300576d536966 + url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-auto-batch-plugin-2024.1.0-hb045406_7.conda + sha256: 351ec3437b596bba8ad6c7686c50b3afe7e9b593efbf78ab82c3ec9b2ead9c13 + md5: d83d6787a9a002b626e20de84719da64 depends: - __glibc >=2.17,<3.0.a0 - libgcc-ng >=12 - - libopenvino 2024.0.0 h2da1b83_5 + - libopenvino 2024.1.0 h2da1b83_7 - libstdcxx-ng >=12 - - tbb >=2021.11.0 - size: 228961 - timestamp: 1712674245147 + - tbb >=2021.12.0 + size: 109706 + timestamp: 1715781464739 +- kind: conda + name: libopenvino-auto-batch-plugin + version: 2024.1.0 + build: hcd65546_7 + build_number: 7 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-auto-batch-plugin-2024.1.0-hcd65546_7.conda + sha256: 4f33af96871e51bd43bf2e4519456737533d146943967a74d88ba61adbc04c68 + md5: c7c7db5088ab20a79f430dfbc9426839 + depends: + - __osx >=11.0 + - libcxx >=16 + - libopenvino 2024.1.0 h5c9529b_7 + - tbb >=2021.12.0 + size: 101390 + timestamp: 1715778825618 - kind: conda name: libopenvino-auto-plugin version: 2024.0.0 @@ -17483,20 +17045,37 @@ packages: timestamp: 1712673810329 - kind: conda name: libopenvino-auto-plugin - version: 2024.0.0 - build: hfaea8b3_5 - build_number: 5 + version: 2024.1.0 + build: hb045406_7 + build_number: 7 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-auto-plugin-2024.1.0-hb045406_7.conda + sha256: ff26d185939a7acfe802a6075f1f9baa925e8ce46b27a573d687a2e647d6cc23 + md5: 928f79281dbcc73e8e8fc2096b993b97 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc-ng >=12 + - libopenvino 2024.1.0 h2da1b83_7 + - libstdcxx-ng >=12 + - tbb >=2021.12.0 + size: 229521 + timestamp: 1715781478553 +- kind: conda + name: libopenvino-auto-plugin + version: 2024.1.0 + build: hcd65546_7 + build_number: 7 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-auto-plugin-2024.0.0-hfaea8b3_5.conda - sha256: 31ed2b61a68254d607288280ba5fff4fe39e40106f0d500ce503c22191be5f62 - md5: 1affc4342a238127b4e52f5366c161c8 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-auto-plugin-2024.1.0-hcd65546_7.conda + sha256: 685bba1d57b5781d78a0319e85dcb1439f35fd6e020b313c0a5eb58ec7e2687e + md5: 177dab9aeb26988b68e23c09c960c59d depends: - __osx >=11.0 - libcxx >=16 - - libopenvino 2024.0.0 h200475e_5 - - tbb >=2021.11.0 - size: 199377 - timestamp: 1712671578810 + - libopenvino 2024.1.0 h5c9529b_7 + - tbb >=2021.12.0 + size: 204377 + timestamp: 1715778845526 - kind: conda name: libopenvino-hetero-plugin version: 2024.0.0 @@ -17515,55 +17094,37 @@ packages: timestamp: 1712673850284 - kind: conda name: libopenvino-hetero-plugin - version: 2024.0.0 - build: h5c03a75_5 - build_number: 5 + version: 2024.1.0 + build: h5c03a75_7 + build_number: 7 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-hetero-plugin-2024.0.0-h5c03a75_5.conda - sha256: 41ab26306eeadc35b1765ae49ea651429e39239e51140cbe695ecd7e5111d9c9 - md5: c69a1ed3e89dc16c7e1df30ed1fd73f7 + url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-hetero-plugin-2024.1.0-h5c03a75_7.conda + sha256: b87a5a4d503ad5abeee09d374d157bed0839be593e43c907d470394635e6c206 + md5: 34db2a8d0504a807a735da48234e2a1d depends: - __glibc >=2.17,<3.0.a0 - libgcc-ng >=12 - - libopenvino 2024.0.0 h2da1b83_5 + - libopenvino 2024.1.0 h2da1b83_7 - libstdcxx-ng >=12 - pugixml >=1.14,<1.15.0a0 - size: 179737 - timestamp: 1712674261368 + size: 191335 + timestamp: 1715781490616 - kind: conda name: libopenvino-hetero-plugin - version: 2024.0.0 - build: hc7e6747_5 - build_number: 5 + version: 2024.1.0 + build: h88cb26a_7 + build_number: 7 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-hetero-plugin-2024.0.0-hc7e6747_5.conda - sha256: fb593663da52d2f0b8b52b2dd0bfd02c910c7ec55847810c4e86430d1250e5fd - md5: 91b55825deed0aed37849e4804e591b6 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-hetero-plugin-2024.1.0-h88cb26a_7.conda + sha256: eaa44c2dbcd73af22a795f3c16ccda5089b17d4615eb532a557b952336ceea82 + md5: 8344c109fe70c5d11c5582bef0471bf0 depends: - __osx >=11.0 - libcxx >=16 - - libopenvino 2024.0.0 h200475e_5 - - pugixml >=1.14,<1.15.0a0 - size: 160337 - timestamp: 1712671618285 -- kind: conda - name: libopenvino-intel-cpu-plugin - version: 2024.0.0 - build: h2da1b83_5 - build_number: 5 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-cpu-plugin-2024.0.0-h2da1b83_5.conda - sha256: 41a31574f67e01e012ff7691c2bf2bcf24298307991f9e8b04b756bf0cd42be3 - md5: deb11c7339478aba1b5b7cf15c443396 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc-ng >=12 - - libopenvino 2024.0.0 h2da1b83_5 - - libstdcxx-ng >=12 + - libopenvino 2024.1.0 h5c9529b_7 - pugixml >=1.14,<1.15.0a0 - - tbb >=2021.11.0 - size: 10628363 - timestamp: 1712674280576 + size: 170507 + timestamp: 1715778866457 - kind: conda name: libopenvino-intel-cpu-plugin version: 2024.0.0 @@ -17581,25 +17142,59 @@ packages: - tbb >=2021.11.0 size: 9909609 timestamp: 1712673902257 +- kind: conda + name: libopenvino-intel-cpu-plugin + version: 2024.1.0 + build: h2da1b83_7 + build_number: 7 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-cpu-plugin-2024.1.0-h2da1b83_7.conda + sha256: ac6b60f13d501c21ea39c825f0335bcf4185839ec1256dcd3675ead84a20f590 + md5: 22ef5cad44c9e3caecbee37465c33fca + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc-ng >=12 + - libopenvino 2024.1.0 h2da1b83_7 + - libstdcxx-ng >=12 + - pugixml >=1.14,<1.15.0a0 + - tbb >=2021.12.0 + size: 10916042 + timestamp: 1715781503484 - kind: conda name: libopenvino-intel-gpu-plugin - version: 2024.0.0 - build: h2da1b83_5 - build_number: 5 + version: 2024.1.0 + build: h2da1b83_7 + build_number: 7 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-gpu-plugin-2024.0.0-h2da1b83_5.conda - sha256: 0d691749d38bf7a1b5f347336486c126af9591e427486aae92f465f6c0ea7d66 - md5: 1f5902112c12e9a8ae2bb4c51294d35a + url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-gpu-plugin-2024.1.0-h2da1b83_7.conda + sha256: 8e323857f7113ed364aeeed8b7ce6e8d7dd0bc6a44c23a7c64607a8171b10ac5 + md5: 98d53dafdd090d01ae50719eabe374e7 depends: - __glibc >=2.17,<3.0.a0 - libgcc-ng >=12 - - libopenvino 2024.0.0 h2da1b83_5 + - libopenvino 2024.1.0 h2da1b83_7 - libstdcxx-ng >=12 - ocl-icd >=2.3.2,<3.0a0 - pugixml >=1.14,<1.15.0a0 - - tbb >=2021.11.0 - size: 8353537 - timestamp: 1712674327020 + - tbb >=2021.12.0 + size: 8465032 + timestamp: 1715781541608 +- kind: conda + name: libopenvino-intel-npu-plugin + version: 2024.1.0 + build: he02047a_7 + build_number: 7 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-intel-npu-plugin-2024.1.0-he02047a_7.conda + sha256: c5b192bfc8563a4d554f105085499c4d76f99bf8e79bf898304446e51060e4a8 + md5: e766c8a98f4efef2e9be7146fad9b6f2 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc-ng >=12 + - libopenvino 2024.1.0 h2da1b83_7 + - libstdcxx-ng >=12 + size: 325218 + timestamp: 1715781572940 - kind: conda name: libopenvino-ir-frontend version: 2024.0.0 @@ -17618,70 +17213,37 @@ packages: timestamp: 1712673995491 - kind: conda name: libopenvino-ir-frontend - version: 2024.0.0 - build: h5c03a75_5 - build_number: 5 + version: 2024.1.0 + build: h5c03a75_7 + build_number: 7 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-ir-frontend-2024.0.0-h5c03a75_5.conda - sha256: c1e8556f42cd001ee03298c6b044730daae2adcc1af035df0edccf8eb4dd5261 - md5: 3a5e6778c907c33503be9c051a6424ae + url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-ir-frontend-2024.1.0-h5c03a75_7.conda + sha256: c71663f56030a9342d0860fa169bdd0d700e1f726fe082dc042fd8f56e94cf89 + md5: 1eb037f090cb525857b01702b2afb6a0 depends: - __glibc >=2.17,<3.0.a0 - libgcc-ng >=12 - - libopenvino 2024.0.0 h2da1b83_5 + - libopenvino 2024.1.0 h2da1b83_7 - libstdcxx-ng >=12 - pugixml >=1.14,<1.15.0a0 - size: 200926 - timestamp: 1712674364843 + size: 200300 + timestamp: 1715781585186 - kind: conda name: libopenvino-ir-frontend - version: 2024.0.0 - build: hc7e6747_5 - build_number: 5 + version: 2024.1.0 + build: h88cb26a_7 + build_number: 7 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-ir-frontend-2024.0.0-hc7e6747_5.conda - sha256: 17ce0aa165acda50d8b5081ba798c7b80973d370793d72a5ef85800c85328b2d - md5: ee068fe8f4447046729d5f55e3523eb7 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-ir-frontend-2024.1.0-h88cb26a_7.conda + sha256: 855d18d465bfc76b277f263dac39836ca3464185bbc88f143e4552292ad077d6 + md5: f7983222cb7bc2278a6f3b5ab392f961 depends: - __osx >=11.0 - libcxx >=16 - - libopenvino 2024.0.0 h200475e_5 + - libopenvino 2024.1.0 h5c9529b_7 - pugixml >=1.14,<1.15.0a0 - size: 170420 - timestamp: 1712671655665 -- kind: conda - name: libopenvino-onnx-frontend - version: 2024.0.0 - build: h07e8aee_5 - build_number: 5 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-onnx-frontend-2024.0.0-h07e8aee_5.conda - sha256: 68506cc32799197fecdceb50a220c8ad5092c0279192bd2c0ecc33f57beb2397 - md5: 5b9b0c983e7b14ba4764d75a9bf7a6f3 - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc-ng >=12 - - libopenvino 2024.0.0 h2da1b83_5 - - libprotobuf >=4.25.3,<4.25.4.0a0 - - libstdcxx-ng >=12 - size: 1586243 - timestamp: 1712674383761 -- kind: conda - name: libopenvino-onnx-frontend - version: 2024.0.0 - build: h25b35cd_5 - build_number: 5 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-onnx-frontend-2024.0.0-h25b35cd_5.conda - sha256: 54df073224fafd53aab49d4a4966f19d0b9759e5cc07f2c8a505f0b4825eecde - md5: 98933b62ed1ff14584fa373843922226 - depends: - - __osx >=11.0 - - libcxx >=16 - - libopenvino 2024.0.0 h200475e_5 - - libprotobuf >=4.25.3,<4.25.4.0a0 - size: 1198819 - timestamp: 1712671712616 + size: 172540 + timestamp: 1715778889089 - kind: conda name: libopenvino-onnx-frontend version: 2024.0.0 @@ -17699,38 +17261,38 @@ packages: size: 1266299 timestamp: 1712674054702 - kind: conda - name: libopenvino-paddle-frontend - version: 2024.0.0 - build: h07e8aee_5 - build_number: 5 + name: libopenvino-onnx-frontend + version: 2024.1.0 + build: h07e8aee_7 + build_number: 7 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-paddle-frontend-2024.0.0-h07e8aee_5.conda - sha256: 7ad02d506f4a67b37f1c3ec72c950d339c10c29a53a36326094fbbfa62ec3cd1 - md5: 77ba4135acc68fdade36cca31446c3e8 + url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-onnx-frontend-2024.1.0-h07e8aee_7.conda + sha256: 11f7fed90dd4d20072cfe12c21d61fbebebc37e0b7b465280413fa227acc8234 + md5: 019fb9bcd7ce0178fa85f3c610efb8c3 depends: - __glibc >=2.17,<3.0.a0 - libgcc-ng >=12 - - libopenvino 2024.0.0 h2da1b83_5 + - libopenvino 2024.1.0 h2da1b83_7 - libprotobuf >=4.25.3,<4.25.4.0a0 - libstdcxx-ng >=12 - size: 695337 - timestamp: 1712674402836 + size: 1602952 + timestamp: 1715781597824 - kind: conda - name: libopenvino-paddle-frontend - version: 2024.0.0 - build: h25b35cd_5 - build_number: 5 + name: libopenvino-onnx-frontend + version: 2024.1.0 + build: h32b5460_7 + build_number: 7 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-paddle-frontend-2024.0.0-h25b35cd_5.conda - sha256: c602a48a3048aa1ebf39b971a3b781a568b65ebabef2795855bcda13eab22ab9 - md5: d23ceb8301d70ec7e88bd0a98d00551d + url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-onnx-frontend-2024.1.0-h32b5460_7.conda + sha256: 7f36d68039feee50560fefd57cb42019a9e229419cda20ad5dbaa8c4e933e127 + md5: 85c22079620e259d235c15db5119535a depends: - __osx >=11.0 - libcxx >=16 - - libopenvino 2024.0.0 h200475e_5 + - libopenvino 2024.1.0 h5c9529b_7 - libprotobuf >=4.25.3,<4.25.4.0a0 - size: 414860 - timestamp: 1712671756869 + size: 1217054 + timestamp: 1715778923386 - kind: conda name: libopenvino-paddle-frontend version: 2024.0.0 @@ -17748,20 +17310,38 @@ packages: size: 427333 timestamp: 1712674101191 - kind: conda - name: libopenvino-pytorch-frontend - version: 2024.0.0 - build: h3f3aa29_5 - build_number: 5 + name: libopenvino-paddle-frontend + version: 2024.1.0 + build: h07e8aee_7 + build_number: 7 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-paddle-frontend-2024.1.0-h07e8aee_7.conda + sha256: 34d77b69af20ef0c6a6249eaf8ad01f0ca16279069a7853cd5a81a4656ecafca + md5: 991c28a11b0ace4b340a445b538cece8 + depends: + - __glibc >=2.17,<3.0.a0 + - libgcc-ng >=12 + - libopenvino 2024.1.0 h2da1b83_7 + - libprotobuf >=4.25.3,<4.25.4.0a0 + - libstdcxx-ng >=12 + size: 699818 + timestamp: 1715781612288 +- kind: conda + name: libopenvino-paddle-frontend + version: 2024.1.0 + build: h32b5460_7 + build_number: 7 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-pytorch-frontend-2024.0.0-h3f3aa29_5.conda - sha256: 350fbd4e97ff8fbd05621f407ec63379db9af1f684041c780ab0efb6ff620533 - md5: 47ad5a2082f96eb6c2907cf2cb2fec1a + url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-paddle-frontend-2024.1.0-h32b5460_7.conda + sha256: a008dbef3d6ea10af338860d1820b8057f55a1a05f021f54fc2d1f2463d1af9e + md5: 2b6c8d3def5f67fea73437ca3465a4f8 depends: - __osx >=11.0 - libcxx >=16 - - libopenvino 2024.0.0 h200475e_5 - size: 731152 - timestamp: 1712671796738 + - libopenvino 2024.1.0 h5c9529b_7 + - libprotobuf >=4.25.3,<4.25.4.0a0 + size: 413257 + timestamp: 1715778954275 - kind: conda name: libopenvino-pytorch-frontend version: 2024.0.0 @@ -17779,40 +17359,35 @@ packages: timestamp: 1712674144034 - kind: conda name: libopenvino-pytorch-frontend - version: 2024.0.0 - build: he02047a_5 - build_number: 5 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-pytorch-frontend-2024.0.0-he02047a_5.conda - sha256: 71795c64c5b6a853130fefb435376b836a6e42eac63117a03a78fa82d76f4af0 - md5: deb1f6397c3aa6dbb35d197499829623 + version: 2024.1.0 + build: h00cdb27_7 + build_number: 7 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-pytorch-frontend-2024.1.0-h00cdb27_7.conda + sha256: 753e78c65c9764bee2849fb3e9b208d481b4e0d98dea52e35e09f6f6353c72c3 + md5: 36280110a6124ba88b55709e3c863eca depends: - - __glibc >=2.17,<3.0.a0 - - libgcc-ng >=12 - - libopenvino 2024.0.0 h2da1b83_5 - - libstdcxx-ng >=12 - size: 1066396 - timestamp: 1712674419569 + - __osx >=11.0 + - libcxx >=16 + - libopenvino 2024.1.0 h5c9529b_7 + size: 764047 + timestamp: 1715778978049 - kind: conda - name: libopenvino-tensorflow-frontend - version: 2024.0.0 - build: h39126c6_5 - build_number: 5 + name: libopenvino-pytorch-frontend + version: 2024.1.0 + build: he02047a_7 + build_number: 7 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-tensorflow-frontend-2024.0.0-h39126c6_5.conda - sha256: d3302692d306eb59f99650393a5f3a7f9312bde5c2a3982432fb667ee4f1d89c - md5: 737f0ee3a70c84758333318afa86d46e + url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-pytorch-frontend-2024.1.0-he02047a_7.conda + sha256: 1ded27cc210e0e9f2411d5f5f7738b322d76a4ffb562deaac8f14065b4987f9b + md5: 2b231b8cdbd2495706526ac1ab3c821c depends: - __glibc >=2.17,<3.0.a0 - - libabseil * cxx17* - - libabseil >=20240116.1,<20240117.0a0 - libgcc-ng >=12 - - libopenvino 2024.0.0 h2da1b83_5 - - libprotobuf >=4.25.3,<4.25.4.0a0 + - libopenvino 2024.1.0 h2da1b83_7 - libstdcxx-ng >=12 - - snappy >=1.2.0,<1.3.0a0 - size: 1270703 - timestamp: 1712674438216 + size: 1103514 + timestamp: 1715781626871 - kind: conda name: libopenvino-tensorflow-frontend version: 2024.0.0 @@ -17834,38 +17409,43 @@ packages: timestamp: 1712674220872 - kind: conda name: libopenvino-tensorflow-frontend - version: 2024.0.0 - build: hbc2fe69_5 - build_number: 5 + version: 2024.1.0 + build: h2741c3b_7 + build_number: 7 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-tensorflow-frontend-2024.0.0-hbc2fe69_5.conda - sha256: 0b9c42f084c2905e596f4ffcb2c1a4e295e30bd06d945625c68711889000ac14 - md5: 1094e5981c128afd3fe8f71cfd7fc2ab + url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-tensorflow-frontend-2024.1.0-h2741c3b_7.conda + sha256: e2bf032acf3143a8465ebf0b99348743eb5187444c24bac5605c8f53835a6f6a + md5: 4c6e1074a312e0d1f7173ca01ac1b4cb depends: - __osx >=11.0 - libabseil * cxx17* - - libabseil >=20240116.1,<20240117.0a0 + - libabseil >=20240116.2,<20240117.0a0 - libcxx >=16 - - libopenvino 2024.0.0 h200475e_5 + - libopenvino 2024.1.0 h5c9529b_7 - libprotobuf >=4.25.3,<4.25.4.0a0 - snappy >=1.2.0,<1.3.0a0 - size: 881993 - timestamp: 1712671871242 + size: 912118 + timestamp: 1715779029656 - kind: conda - name: libopenvino-tensorflow-lite-frontend - version: 2024.0.0 - build: h3f3aa29_5 - build_number: 5 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-tensorflow-lite-frontend-2024.0.0-h3f3aa29_5.conda - sha256: dbbc7f6c3c29a8f9b28b7358dba24041744d64bf56bf7d1642e7bfb286152f5e - md5: ecb01a392bb579fed43a6c50a9e12b3b + name: libopenvino-tensorflow-frontend + version: 2024.1.0 + build: h39126c6_7 + build_number: 7 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-tensorflow-frontend-2024.1.0-h39126c6_7.conda + sha256: 0624a6ed8b2dee32a9a3bae1379d5d652d50123657e3ea870bbd7957c8ba090f + md5: d6aac92f4b03be8c86b09f40e1f5263a depends: - - __osx >=11.0 - - libcxx >=16 - - libopenvino 2024.0.0 h200475e_5 - size: 374882 - timestamp: 1712671910235 + - __glibc >=2.17,<3.0.a0 + - libabseil * cxx17* + - libabseil >=20240116.2,<20240117.0a0 + - libgcc-ng >=12 + - libopenvino 2024.1.0 h2da1b83_7 + - libprotobuf >=4.25.3,<4.25.4.0a0 + - libstdcxx-ng >=12 + - snappy >=1.2.0,<1.3.0a0 + size: 1317325 + timestamp: 1715781640910 - kind: conda name: libopenvino-tensorflow-lite-frontend version: 2024.0.0 @@ -17883,20 +17463,35 @@ packages: timestamp: 1712674261940 - kind: conda name: libopenvino-tensorflow-lite-frontend - version: 2024.0.0 - build: he02047a_5 - build_number: 5 + version: 2024.1.0 + build: h00cdb27_7 + build_number: 7 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libopenvino-tensorflow-lite-frontend-2024.1.0-h00cdb27_7.conda + sha256: 9ef485ab5e1b4ae161e0278605261fe8b930c627a62e6d76e518f3af762cd6b5 + md5: 002043b46dbefc3404a6725fbaf64568 + depends: + - __osx >=11.0 + - libcxx >=16 + - libopenvino 2024.1.0 h5c9529b_7 + size: 377832 + timestamp: 1715779055704 +- kind: conda + name: libopenvino-tensorflow-lite-frontend + version: 2024.1.0 + build: he02047a_7 + build_number: 7 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-tensorflow-lite-frontend-2024.0.0-he02047a_5.conda - sha256: 33d537f0a7d43e384e9808191f79ae2115213ff78d291bab3d57db9d9c66683a - md5: 5161e70dfbcd31a6e28b5d75c0b620e6 + url: https://conda.anaconda.org/conda-forge/linux-64/libopenvino-tensorflow-lite-frontend-2024.1.0-he02047a_7.conda + sha256: 44daba91a6048dadebe8f677a6e5ec4305e9d2092c985458c8c9db64af23a297 + md5: f7a46aa4f5c53423bf3e036da8c1b632 depends: - __glibc >=2.17,<3.0.a0 - libgcc-ng >=12 - - libopenvino 2024.0.0 h2da1b83_5 + - libopenvino 2024.1.0 h2da1b83_7 - libstdcxx-ng >=12 - size: 477616 - timestamp: 1712674457796 + size: 487278 + timestamp: 1715781654451 - kind: conda name: libopus version: 1.3.1 @@ -17957,80 +17552,80 @@ packages: - kind: conda name: libparquet version: 15.0.2 - build: h39135fc_3_cpu + build: h7cd3cfe_3_cpu build_number: 3 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libparquet-15.0.2-h39135fc_3_cpu.conda - sha256: 5fceb521197011855087e8bb06fcbed69f36305f06134e010ac68d9ee1905d33 - md5: 7682dc52680f8392ecb96b3181c0630f + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/libparquet-15.0.2-h7cd3cfe_3_cpu.conda + sha256: 9b9144697ef4637a0f164c9acb1be5297bedc4d86ad9ae97b97eaec872447104 + md5: 72f92d2ee538cb24f5d8c1870d96cf66 depends: - - libarrow 15.0.2 h45212c0_3_cpu + - __osx >=10.13 + - libarrow 15.0.2 h965e444_3_cpu + - libcxx >=16 - libthrift >=0.19.0,<0.19.1.0a0 - openssl >=3.2.1,<4.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 license: Apache-2.0 license_family: APACHE - size: 793915 - timestamp: 1712757376343 + size: 921797 + timestamp: 1712758165813 - kind: conda name: libparquet - version: 15.0.2 - build: h5304c63_3_cpu - build_number: 3 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libparquet-15.0.2-h5304c63_3_cpu.conda - sha256: 449bdee38a41f563eb1d215c3088164cd5abba412445ace4bb6976307f3fb2cb - md5: 148b767eb0b635975372eead52be1b58 + version: 16.1.0 + build: h178134c_1_cpu + build_number: 1 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/libparquet-16.1.0-h178134c_1_cpu.conda + sha256: 9c60cdab4427756d55050432311b3a4bc341378eedeb925c4ff45616fe447b91 + md5: da29ed68ed5514a7729ddea91bbd2249 depends: - - __osx >=11.0 - - libarrow 15.0.2 h3ee1d8f_3_cpu - - libcxx >=16 + - libarrow 16.1.0 h107e38f_1_cpu - libthrift >=0.19.0,<0.19.1.0a0 - - openssl >=3.2.1,<4.0a0 + - openssl >=3.3.0,<4.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: Apache-2.0 license_family: APACHE - size: 863153 - timestamp: 1712782061754 + size: 794065 + timestamp: 1715995667472 - kind: conda name: libparquet - version: 15.0.2 - build: h6a7eafb_3_cpu - build_number: 3 + version: 16.1.0 + build: h6a7eafb_1_cpu + build_number: 1 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libparquet-15.0.2-h6a7eafb_3_cpu.conda - sha256: a37a1416f3ae147a821e8144bda8b0ae31def625b0fdb848952e4f491366f375 - md5: d2827e2cf2df4f74f9c76417f559ca46 + url: https://conda.anaconda.org/conda-forge/linux-64/libparquet-16.1.0-h6a7eafb_1_cpu.conda + sha256: 00811890ca8f54db033a733f4711c2e6d9e130a288e79172e9ebedfb31badf6b + md5: cb6a5bc92eac2f308c8fb6a2b1ff057c depends: - - libarrow 15.0.2 he70291f_3_cpu + - libarrow 16.1.0 hefa796f_1_cpu - libgcc-ng >=12 - libstdcxx-ng >=12 - libthrift >=0.19.0,<0.19.1.0a0 - - openssl >=3.2.1,<4.0a0 + - openssl >=3.3.0,<4.0a0 license: Apache-2.0 license_family: APACHE - size: 1179560 - timestamp: 1712756464081 + size: 1185131 + timestamp: 1715994787423 - kind: conda name: libparquet - version: 15.0.2 - build: h7cd3cfe_3_cpu - build_number: 3 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/libparquet-15.0.2-h7cd3cfe_3_cpu.conda - sha256: 9b9144697ef4637a0f164c9acb1be5297bedc4d86ad9ae97b97eaec872447104 - md5: 72f92d2ee538cb24f5d8c1870d96cf66 + version: 16.1.0 + build: hcf52c46_1_cpu + build_number: 1 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libparquet-16.1.0-hcf52c46_1_cpu.conda + sha256: 392c30bd15ac6e328259709362db8ac942614ee21e547ca822fe4a366331ff5f + md5: 3382455473f164a2475c76a336ed757f depends: - - __osx >=10.13 - - libarrow 15.0.2 h965e444_3_cpu + - __osx >=11.0 + - libarrow 16.1.0 h23f55cf_1_cpu - libcxx >=16 - libthrift >=0.19.0,<0.19.1.0a0 - - openssl >=3.2.1,<4.0a0 + - openssl >=3.3.0,<4.0a0 license: Apache-2.0 license_family: APACHE - size: 921797 - timestamp: 1712758165813 + size: 880280 + timestamp: 1715995556835 - kind: conda name: libpciaccess version: '0.18' @@ -18054,7 +17649,7 @@ packages: sha256: 66c4713b07408398f2221229a1c1d5df57d65dc0902258113f2d9ecac4772495 md5: 77e684ca58d82cae9deebafb95b1a2b8 depends: - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: zlib-acknowledgement size: 264177 timestamp: 1708780447187 @@ -18067,7 +17662,7 @@ packages: sha256: 6ad31bf262a114de5bbe0c6ba73b29ed25239d0f46f9d59700310d2ea0b3c142 md5: 77e398acc32617a0384553aea29e866b depends: - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 @@ -18084,7 +17679,7 @@ packages: md5: 009981dd9cfcaa4dbfa25ffaed86bcae depends: - libgcc-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: zlib-acknowledgement size: 288221 timestamp: 1708780443939 @@ -18097,7 +17692,7 @@ packages: sha256: 13e646d24b5179e6b0a5ece4451a587d759f55d9a360b7015f8f96eff4524b8f md5: 65dcddb15965c9de2c0365cb14910532 depends: - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: zlib-acknowledgement size: 268524 timestamp: 1708780496420 @@ -18176,7 +17771,7 @@ packages: - libabseil >=20240116.1,<20240117.0a0 - libgcc-ng >=12 - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: BSD-3-Clause license_family: BSD size: 2811207 @@ -18194,7 +17789,7 @@ packages: - libabseil * cxx17* - libabseil >=20240116.1,<20240117.0a0 - libcxx >=16 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: BSD-3-Clause license_family: BSD size: 2216001 @@ -18210,7 +17805,7 @@ packages: depends: - libabseil * cxx17* - libabseil >=20240116.1,<20240117.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 @@ -18230,7 +17825,7 @@ packages: - libabseil * cxx17* - libabseil >=20240116.1,<20240117.0a0 - libcxx >=16 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: BSD-3-Clause license_family: BSD size: 2154402 @@ -18250,7 +17845,7 @@ packages: - libgcc-ng >=12 - libjpeg-turbo >=3.0.0,<4.0a0 - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: LGPL-2.1-only license_family: LGPL size: 637871 @@ -18268,7 +17863,7 @@ packages: - lcms2 >=2.15,<3.0a0 - libcxx >=15.0.7 - libjpeg-turbo >=3.0.0,<4.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: LGPL-2.1-only license_family: LGPL size: 589712 @@ -18285,7 +17880,7 @@ packages: depends: - lcms2 >=2.15,<3.0a0 - libjpeg-turbo >=3.0.0,<4.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 @@ -18306,7 +17901,7 @@ packages: - lcms2 >=2.15,<3.0a0 - libcxx >=15.0.7 - libjpeg-turbo >=3.0.0,<4.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: LGPL-2.1-only license_family: LGPL size: 594346 @@ -18412,43 +18007,47 @@ packages: timestamp: 1701547214362 - kind: conda name: librsvg - version: 2.56.3 - build: h55a2576_1 + version: 2.58.0 + build: hadf69e7_1 build_number: 1 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/librsvg-2.56.3-h55a2576_1.conda - sha256: 59043f2536d61a32378553c4fa7f56e97bca12165c37a45de9e7439a06f5ac16 - md5: d9624ec11650aa93e0b2c2612c3548f5 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/librsvg-2.58.0-hadf69e7_1.conda + sha256: eaba82901f01f3ede8b1307c64e0448df8c5e9af9c6b78600c5f63c91c122e45 + md5: 0e2b5bd9533043b41f9482ae9e2c16b5 depends: - cairo >=1.18.0,<2.0a0 + - freetype >=2.12.1,<3.0a0 - gdk-pixbuf >=2.42.10,<3.0a0 - - gettext >=0.21.1,<1.0a0 - - libglib >=2.78.1,<3.0a0 - - libxml2 >=2.12.1,<3.0.0a0 + - harfbuzz >=8.3.0,<9.0a0 + - libgcc-ng >=12 + - libglib >=2.80.0,<3.0a0 + - libpng >=1.6.43,<1.7.0a0 + - libxml2 >=2.12.6,<3.0a0 - pango >=1.50.14,<2.0a0 license: LGPL-2.1-or-later - size: 3832300 - timestamp: 1701547781584 + size: 5997596 + timestamp: 1713369512903 - kind: conda name: librsvg - version: 2.56.3 - build: he3f83f7_1 + version: 2.58.0 + build: hb3d354b_1 build_number: 1 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/librsvg-2.56.3-he3f83f7_1.conda - sha256: b82d0c60376da88a2bf15d35d17c176aa923917ad7de4bc62ddef6d02f3518fb - md5: 03bd1ddcc942867a19528877143b9852 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/librsvg-2.58.0-hb3d354b_1.conda + sha256: c57a7fc7b24e5d036b0f2e5c871af0b636d46455cf73497fc2a6a5f873542b65 + md5: eefc587613e6097d9c0b14188c292b5d depends: + - __osx >=11.0 - cairo >=1.18.0,<2.0a0 - gdk-pixbuf >=2.42.10,<3.0a0 - - gettext >=0.21.1,<1.0a0 - - libgcc-ng >=12 - - libglib >=2.78.1,<3.0a0 - - libxml2 >=2.12.1,<3.0.0a0 + - libglib >=2.80.0,<3.0a0 + - libxml2 >=2.12.6,<3.0a0 - pango >=1.50.14,<2.0a0 + constrains: + - __osx >=11.0 license: LGPL-2.1-or-later - size: 5897732 - timestamp: 1701546864628 + size: 4774673 + timestamp: 1713371158806 - kind: conda name: librttopo version: 1.1.0 @@ -18595,70 +18194,66 @@ packages: timestamp: 1605135849110 - kind: conda name: libspatialindex - version: 1.9.3 - build: h00cdb27_5 - build_number: 5 + version: 2.0.0 + build: h00cdb27_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libspatialindex-1.9.3-h00cdb27_5.conda - sha256: 6220aacc140ea36c2c02a8a3979718c77b8ed6352bcfed5772df050000b28cff - md5: d2d54252bba0dd6cc740c9c3ff3fbce6 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libspatialindex-2.0.0-h00cdb27_0.conda + sha256: 111087f37e3ab7aff44c1870c94ccb67a87fd4924be13ca56042f36f1d18f8bf + md5: 774e9c4f835cb9b9fee3c3af9cfe0c28 depends: - __osx >=11.0 - libcxx >=16 license: MIT license_family: MIT - size: 299496 - timestamp: 1715789257356 + size: 292305 + timestamp: 1717795904166 - kind: conda name: libspatialindex - version: 1.9.3 - build: h5a68840_5 - build_number: 5 + version: 2.0.0 + build: h5a68840_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libspatialindex-1.9.3-h5a68840_5.conda - sha256: aba140efc10a8f3dd0895a6bb581df50f325de381785a30efb42728f4755ac85 - md5: 97adbac1bbefbc8007bc9b47902fda68 + url: https://conda.anaconda.org/conda-forge/win-64/libspatialindex-2.0.0-h5a68840_0.conda + sha256: 7802e6c51d59bc7e062841c525d772656708cdc44e42b6556493d345f08d7e50 + md5: 667559340fdf805ee1652de7b73e2b59 depends: - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 license: MIT license_family: MIT - size: 349544 - timestamp: 1715789523831 + size: 279879 + timestamp: 1717796252114 - kind: conda name: libspatialindex - version: 1.9.3 - build: he02047a_5 - build_number: 5 + version: 2.0.0 + build: he02047a_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libspatialindex-1.9.3-he02047a_5.conda - sha256: 7ebebb444d6ca90d7fec78cf57289d0f22d93fd7ebdca9fc46f3c4e724b7b819 - md5: 659e6a5c5c7a811bd99e26375cb798b9 + url: https://conda.anaconda.org/conda-forge/linux-64/libspatialindex-2.0.0-he02047a_0.conda + sha256: 997a4fa13864dcb35ac9dfe87ed70fb3e9509dd071fa1951ac7f184e7ffcde5d + md5: e7d2dcd1a058149ff9731a8dca39566e depends: - __glibc >=2.17,<3.0.a0 - libgcc-ng >=12 - libstdcxx-ng >=12 license: MIT license_family: MIT - size: 2970213 - timestamp: 1715789020538 + size: 390882 + timestamp: 1717795885453 - kind: conda name: libspatialindex - version: 1.9.3 - build: hf036a51_5 - build_number: 5 + version: 2.0.0 + build: hf036a51_0 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/libspatialindex-1.9.3-hf036a51_5.conda - sha256: ca339b16e824ec27a43692557fc30a5ea93422b93c3e98307dfed2a6a84e7baa - md5: 256095bb52866eb63eba439b38f4c437 + url: https://conda.anaconda.org/conda-forge/osx-64/libspatialindex-2.0.0-hf036a51_0.conda + sha256: 3ccd90ec2601ae38d72548c273018d8957afc36ae91d6ac95b1a4fc6fddbb9e1 + md5: bc0fc87124943452971c04425ce8c524 depends: - __osx >=10.13 - libcxx >=16 license: MIT license_family: MIT - size: 311971 - timestamp: 1715789333532 + size: 308990 + timestamp: 1717796241227 - kind: conda name: libspatialite version: 5.1.0 @@ -18678,7 +18273,7 @@ packages: - librttopo >=1.1.0,<1.2.0a0 - libsqlite >=3.44.2,<4.0a0 - libxml2 >=2.12.2,<3.0.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - proj >=9.3.1,<9.3.2.0a0 - sqlite - zlib @@ -18704,7 +18299,7 @@ packages: - libsqlite >=3.44.2,<4.0a0 - libstdcxx-ng >=12 - libxml2 >=2.12.2,<3.0.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - proj >=9.3.1,<9.3.2.0a0 - sqlite - zlib @@ -18731,7 +18326,7 @@ packages: - librttopo >=1.1.0,<1.2.0a0 - libsqlite >=3.44.2,<4.0a0 - libxml2 >=2.12.2,<3.0.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - proj >=9.3.1,<9.3.2.0a0 - sqlite - zlib @@ -18755,7 +18350,7 @@ packages: - librttopo >=1.1.0,<1.2.0a0 - libsqlite >=3.44.2,<4.0a0 - libxml2 >=2.12.2,<3.0.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - proj >=9.3.1,<9.3.2.0a0 - sqlite - ucrt >=10.0.20348.0 @@ -18768,59 +18363,61 @@ packages: timestamp: 1702008651881 - kind: conda name: libsqlite - version: 3.45.3 - build: h091b4b1_0 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.45.3-h091b4b1_0.conda - sha256: 4337f466eb55bbdc74e168b52ec8c38f598e3664244ec7a2536009036e2066cc - md5: c8c1186c7f3351f6ffddb97b1f54fc58 + version: 3.46.0 + build: h1b8f9f3_0 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.46.0-h1b8f9f3_0.conda + sha256: 63af1a9e3284c7e4952364bafe7267e41e2d9d8bcc0e85a4ea4b0ec02d3693f6 + md5: 5dadfbc1a567fe6e475df4ce3148be09 depends: - - libzlib >=1.2.13,<1.3.0a0 + - __osx >=10.13 + - libzlib >=1.2.13,<2.0a0 license: Unlicense - size: 824794 - timestamp: 1713367748819 + size: 908643 + timestamp: 1718050720117 - kind: conda name: libsqlite - version: 3.45.3 - build: h2797004_0 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.45.3-h2797004_0.conda - sha256: e2273d6860eadcf714a759ffb6dc24a69cfd01f2a0ea9d6c20f86049b9334e0c - md5: b3316cbe90249da4f8e84cd66e1cc55b + version: 3.46.0 + build: h2466b09_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.46.0-h2466b09_0.conda + sha256: 662bd7e0d63c5b8c31cca19b91649e798319b93568a2ba8d1375efb91eeb251b + md5: 951b0a3a463932e17414cd9f047fa03d depends: - - libgcc-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: Unlicense - size: 859858 - timestamp: 1713367435849 + size: 876677 + timestamp: 1718051113874 - kind: conda name: libsqlite - version: 3.45.3 - build: h92b6c6a_0 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/libsqlite-3.45.3-h92b6c6a_0.conda - sha256: 4d44b68fb29dcbc2216a8cae0b274b02ef9b4ae05d1d0f785362ed30b91c9b52 - md5: 68e462226209f35182ef66eda0f794ff + version: 3.46.0 + build: hde9e2c9_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libsqlite-3.46.0-hde9e2c9_0.conda + sha256: daee3f68786231dad457d0dfde3f7f1f9a7f2018adabdbb864226775101341a8 + md5: 18aa975d2094c34aef978060ae7da7d8 depends: - - libzlib >=1.2.13,<1.3.0a0 + - libgcc-ng >=12 + - libzlib >=1.2.13,<2.0a0 license: Unlicense - size: 902546 - timestamp: 1713367776445 + size: 865346 + timestamp: 1718050628718 - kind: conda name: libsqlite - version: 3.45.3 - build: hcfcfb64_0 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libsqlite-3.45.3-hcfcfb64_0.conda - sha256: 06ec75faa51d7ec6d5db98889e869b579a9df19d7d3d9baff8359627da4a3b7e - md5: 73f5dc8e2d55d9a1e14b11f49c3b4a28 + version: 3.46.0 + build: hfb93653_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libsqlite-3.46.0-hfb93653_0.conda + sha256: 73048f9cb8647d3d3bfe6021c0b7d663e12cffbe9b4f31bd081e713b0a9ad8f9 + md5: 12300188028c9bc02da965128b91b517 depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - __osx >=11.0 + - libzlib >=1.2.13,<2.0a0 license: Unlicense - size: 870518 - timestamp: 1713367888406 + size: 830198 + timestamp: 1718050644825 - kind: conda name: libssh2 version: 1.11.0 @@ -18831,7 +18428,7 @@ packages: md5: 1f5a58e686b13bcfde88b93f547d23fe depends: - libgcc-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.1.1,<4.0a0 license: BSD-3-Clause license_family: BSD @@ -18846,7 +18443,7 @@ packages: sha256: bb57d0c53289721fff1eeb3103a1c6a988178e88d8a8f4345b0b91a35f0e0015 md5: 029f7dc931a3b626b94823bc77830b01 depends: - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.1.1,<4.0a0 license: BSD-3-Clause license_family: BSD @@ -18861,7 +18458,7 @@ packages: sha256: 813fd04eed2a2d5d9c36e53c554f9c1f08e9324e2922bd60c9c52dbbed2dbcec md5: dc262d03aae04fe26825062879141a41 depends: - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.1.1,<4.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 @@ -18879,7 +18476,7 @@ packages: sha256: f3886763b88f4b24265db6036535ef77b7b77ce91b1cbe588c0fbdd861eec515 md5: ca3a72efba692c59a90d4b9fc0dfe774 depends: - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.1.1,<4.0a0 license: BSD-3-Clause license_family: BSD @@ -18888,16 +18485,17 @@ packages: - kind: conda name: libstdcxx-ng version: 13.2.0 - build: hc0a3c3a_7 - build_number: 7 + build: hc0a3c3a_10 + build_number: 10 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-hc0a3c3a_7.conda - sha256: 35f1e08be0a84810c9075f5bd008495ac94e6c5fe306dfe4b34546f11fed850f - md5: 53ebd4c833fa01cb2c6353e99f905406 + url: https://conda.anaconda.org/conda-forge/linux-64/libstdcxx-ng-13.2.0-hc0a3c3a_10.conda + sha256: 9a5d43eed33fe8b2fd6adf71ef8f0253fd515e1440c9b7b7782db608e3085bea + md5: ea50441ab527f23ffa108ade07e2fde0 + depends: + - libgcc-ng 13.2.0 h77fa898_10 license: GPL-3.0-only WITH GCC-exception-3.1 - license_family: GPL - size: 3837704 - timestamp: 1715016117360 + size: 3862528 + timestamp: 1718485050139 - kind: conda name: libsystemd0 version: '255' @@ -19053,7 +18651,7 @@ packages: depends: - libcxx >=15.0.7 - libevent >=2.1.12,<2.1.13.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.1.3,<4.0a0 license: Apache-2.0 license_family: APACHE @@ -19071,7 +18669,7 @@ packages: depends: - libcxx >=15.0.7 - libevent >=2.1.12,<2.1.13.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.1.3,<4.0a0 license: Apache-2.0 license_family: APACHE @@ -19088,7 +18686,7 @@ packages: md5: d3432b9d4950e91d2fdf3bed91248ee0 depends: - libevent >=2.1.12,<2.1.13.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.1.3,<4.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 @@ -19110,7 +18708,7 @@ packages: - libevent >=2.1.12,<2.1.13.0a0 - libgcc-ng >=12 - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.1.3,<4.0a0 license: Apache-2.0 license_family: APACHE @@ -19119,89 +18717,89 @@ packages: - kind: conda name: libtiff version: 4.6.0 - build: h684deea_2 - build_number: 2 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.6.0-h684deea_2.conda - sha256: 1ef5bd7295f4316b111f70ad21356fb9f0de50b85a341cac9e3a61ac6487fdf1 - md5: 2ca10a325063e000ad6d2a5900061e0d + build: h07db509_3 + build_number: 3 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.6.0-h07db509_3.conda + sha256: 6df3e129682f6dc43826e5028e1807624b2a7634c4becbb50e56be9f77167f25 + md5: 28c9f8c6dd75666dfb296aea06c49cb8 depends: - lerc >=4.0.0,<5.0a0 - - libcxx >=15.0.7 - - libdeflate >=1.19,<1.20.0a0 + - libcxx >=16 + - libdeflate >=1.20,<1.21.0a0 - libjpeg-turbo >=3.0.0,<4.0a0 - libwebp-base >=1.3.2,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - xz >=5.2.6,<6.0a0 - zstd >=1.5.5,<1.6.0a0 license: HPND - size: 266501 - timestamp: 1695661828714 + size: 238349 + timestamp: 1711218119201 - kind: conda name: libtiff version: 4.6.0 - build: h6e2ebb7_2 - build_number: 2 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.6.0-h6e2ebb7_2.conda - sha256: f7b50b71840a5d8edd74a8bccf0c173ca2599bd136e366c35722272b4afa0500 - md5: 08d653b74ee2dec0131ad4259ffbb126 + build: h1dd3fc0_3 + build_number: 3 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.6.0-h1dd3fc0_3.conda + sha256: fc3b210f9584a92793c07396cb93e72265ff3f1fa7ca629128bf0a50d5cb15e4 + md5: 66f03896ffbe1a110ffda05c7a856504 depends: - lerc >=4.0.0,<5.0a0 - - libdeflate >=1.19,<1.20.0a0 + - libdeflate >=1.20,<1.21.0a0 + - libgcc-ng >=12 - libjpeg-turbo >=3.0.0,<4.0a0 - - libzlib >=1.2.13,<1.3.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - libstdcxx-ng >=12 + - libwebp-base >=1.3.2,<2.0a0 + - libzlib >=1.2.13,<2.0.0a0 - xz >=5.2.6,<6.0a0 - zstd >=1.5.5,<1.6.0a0 license: HPND - size: 787430 - timestamp: 1695662030293 + size: 282688 + timestamp: 1711217970425 - kind: conda name: libtiff version: 4.6.0 - build: ha8a6c65_2 + build: h684deea_2 build_number: 2 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libtiff-4.6.0-ha8a6c65_2.conda - sha256: b18ef36eb90f190db22c56ae5a080bccc16669c8f5b795a6211d7b0c00c18ff7 - md5: 596d6d949bab9a75a492d451f521f457 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/libtiff-4.6.0-h684deea_2.conda + sha256: 1ef5bd7295f4316b111f70ad21356fb9f0de50b85a341cac9e3a61ac6487fdf1 + md5: 2ca10a325063e000ad6d2a5900061e0d depends: - lerc >=4.0.0,<5.0a0 - libcxx >=15.0.7 - libdeflate >=1.19,<1.20.0a0 - libjpeg-turbo >=3.0.0,<4.0a0 - libwebp-base >=1.3.2,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - xz >=5.2.6,<6.0a0 - zstd >=1.5.5,<1.6.0a0 license: HPND - size: 246265 - timestamp: 1695661829324 + size: 266501 + timestamp: 1695661828714 - kind: conda name: libtiff version: 4.6.0 - build: ha9c0a0a_2 - build_number: 2 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libtiff-4.6.0-ha9c0a0a_2.conda - sha256: 45158f5fbee7ee3e257e6b9f51b9f1c919ed5518a94a9973fe7fa4764330473e - md5: 55ed21669b2015f77c180feb1dd41930 + build: hddb2be6_3 + build_number: 3 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/libtiff-4.6.0-hddb2be6_3.conda + sha256: 2e04844865cfe0286d70482c129f159542b325f4e45774aaff5fbe5027b30b0a + md5: 6d1828c9039929e2f185c5fa9d133018 depends: - lerc >=4.0.0,<5.0a0 - - libdeflate >=1.19,<1.20.0a0 - - libgcc-ng >=12 + - libdeflate >=1.20,<1.21.0a0 - libjpeg-turbo >=3.0.0,<4.0a0 - - libstdcxx-ng >=12 - - libwebp-base >=1.3.2,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 - xz >=5.2.6,<6.0a0 - zstd >=1.5.5,<1.6.0a0 license: HPND - size: 283198 - timestamp: 1695661593314 + size: 787198 + timestamp: 1711218639912 - kind: conda name: libunistring version: 0.9.10 @@ -19308,20 +18906,23 @@ packages: - kind: conda name: libva version: 2.21.0 - build: hd590300_0 + build: h4ab18f5_2 + build_number: 2 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libva-2.21.0-hd590300_0.conda - sha256: b4e3a3fa523a5ddd1eca7981c9d6a9b831a182950116cc5bda18c94a040b63bc - md5: e50a2609159a3e336fe4092738c00687 + url: https://conda.anaconda.org/conda-forge/linux-64/libva-2.21.0-h4ab18f5_2.conda + sha256: cdd0ffd791a677af28a5928c23474312fafeab718dfc93f6ce99569eb8eee8b3 + md5: 109300f4eeeb8a61498283565106b474 depends: - libdrm >=2.4.120,<2.5.0a0 - - xorg-libx11 >=1.8.7,<2.0a0 + - libgcc-ng >=12 + - xorg-libx11 >=1.8.9,<2.0a0 - xorg-libxext >=1.3.4,<2.0a0 - xorg-libxfixes + - libxcb >=1.15.0,<1.16.0 license: MIT license_family: MIT - size: 189313 - timestamp: 1710242676665 + size: 189921 + timestamp: 1717743848819 - kind: conda name: libvorbis version: 1.3.7 @@ -19386,47 +18987,49 @@ packages: timestamp: 1610609991029 - kind: conda name: libvpx - version: 1.14.0 - build: h078ce10_0 + version: 1.14.1 + build: h7bae524_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libvpx-1.14.0-h078ce10_0.conda - sha256: e202f23fca763d88ad8170f90fa380510c65f29b86cfe6fb29706843462cee4f - md5: 8a515c7875e4d61734f4ac964851f4a5 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libvpx-1.14.1-h7bae524_0.conda + sha256: 5d6458b5395cba0804846f156574aa8a34eef6d5f05d39e9932ddbb4215f8bd0 + md5: 95bee48afff34f203e4828444c2b2ae9 depends: + - __osx >=11.0 - libcxx >=16 license: BSD-3-Clause license_family: BSD - size: 1174097 - timestamp: 1707175717608 + size: 1178981 + timestamp: 1717860096742 - kind: conda name: libvpx - version: 1.14.0 - build: h59595ed_0 + version: 1.14.1 + build: hac33072_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libvpx-1.14.0-h59595ed_0.conda - sha256: b0e0500fc92f626baaa2cf926dece5ce7571c42a2db2d993a250d4c5da4d68ca - md5: 01c76c6d71097a0f3bd8683a8f255123 + url: https://conda.anaconda.org/conda-forge/linux-64/libvpx-1.14.1-hac33072_0.conda + sha256: e7d2daf409c807be48310fcc8924e481b62988143f582eb3a58c5523a6763b13 + md5: cde393f461e0c169d9ffb2fc70f81c33 depends: - libgcc-ng >=12 - libstdcxx-ng >=12 license: BSD-3-Clause license_family: BSD - size: 1019593 - timestamp: 1707175376125 + size: 1022466 + timestamp: 1717859935011 - kind: conda name: libvpx - version: 1.14.0 - build: h73e2aa4_0 + version: 1.14.1 + build: hf036a51_0 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/libvpx-1.14.0-h73e2aa4_0.conda - sha256: d3980ecf1e65bfbf7e1c57d6f41a66ab4f33c4fe6b71bf9414bb823e2db186fb - md5: 2c087711228029c8eab3301ddff1c386 + url: https://conda.anaconda.org/conda-forge/osx-64/libvpx-1.14.1-hf036a51_0.conda + sha256: 47e70e76988c11de97d539794fd4b03db69b75289ac02cdc35ae5a595ffcd973 + md5: 9b8744a702ffb1738191e094e6eb67dc depends: + - __osx >=10.13 - libcxx >=16 license: BSD-3-Clause license_family: BSD - size: 1294811 - timestamp: 1707175761017 + size: 1297054 + timestamp: 1717860051058 - kind: conda name: libwebp version: 1.4.0 @@ -19656,75 +19259,79 @@ packages: - kind: conda name: libxml2 version: 2.12.7 - build: h283a6d9_0 + build: h283a6d9_1 + build_number: 1 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.12.7-h283a6d9_0.conda - sha256: e246fefa745b56c022063ba1b69ff2965f280c6eee3de9821184e7c8f2475eab - md5: 1451be68a5549561979125c1827b79ed + url: https://conda.anaconda.org/conda-forge/win-64/libxml2-2.12.7-h283a6d9_1.conda + sha256: aef096aa784e61f860fab08974c6260836bf05d742fb69f304f0e9b7d557c99a + md5: 7ab2653cc21c44a1370ef3b409261b3d depends: - libiconv >=1.17,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 license: MIT license_family: MIT - size: 1615693 - timestamp: 1715606533379 + size: 1709896 + timestamp: 1717547244225 - kind: conda name: libxml2 version: 2.12.7 - build: h3e169fe_0 + build: h3e169fe_1 + build_number: 1 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.12.7-h3e169fe_0.conda - sha256: 88c3df35a981ae6dbdace4aba6f72e6b6767861925149ea47de07aae8c0cbe7b - md5: 4c04ba47fdd2ebecc1d3b6a77534d9ef + url: https://conda.anaconda.org/conda-forge/osx-64/libxml2-2.12.7-h3e169fe_1.conda + sha256: 75554b5ef4c61a97c1d2ddcaff2d87c5ee120ff6925c2b714e18b20727cafb98 + md5: ddb63049aa7bd9f08f2cdc5a1c144d1a depends: - __osx >=10.13 - icu >=73.2,<74.0a0 - libiconv >=1.17,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0a0 - xz >=5.2.6,<6.0a0 license: MIT license_family: MIT - size: 619612 - timestamp: 1715606442077 + size: 619297 + timestamp: 1717546472911 - kind: conda name: libxml2 version: 2.12.7 - build: ha661575_0 + build: ha661575_1 + build_number: 1 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.12.7-ha661575_0.conda - sha256: 10635eb2785aa9eb3d7f710c489e57eba71374f379b10da86bb257b941ab16ec - md5: 3de3b94d23f85429b87cf1e00c02582d + url: https://conda.anaconda.org/conda-forge/osx-arm64/libxml2-2.12.7-ha661575_1.conda + sha256: 0ea12032b53d3767564a058ccd5208c0a1724ed2f8074dd22257ff3859ea6a4e + md5: 8ea71a74847498c793b0a8e9054a177a depends: - __osx >=11.0 - icu >=73.2,<74.0a0 - libiconv >=1.17,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0a0 - xz >=5.2.6,<6.0a0 license: MIT license_family: MIT - size: 588608 - timestamp: 1715606346757 + size: 588487 + timestamp: 1717546487246 - kind: conda name: libxml2 version: 2.12.7 - build: hc051c1a_0 + build: hc051c1a_1 + build_number: 1 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.12.7-hc051c1a_0.conda - sha256: 2d8c402687f7045295d78d66688b140e3310857c7a070bba7547a3b9fcad5e7d - md5: 5d801a4906adc712d480afc362623b59 + url: https://conda.anaconda.org/conda-forge/linux-64/libxml2-2.12.7-hc051c1a_1.conda + sha256: 576ea9134176636283ff052897bf7a91ffd8ac35b2c505dfde2890ec52849698 + md5: 340278ded8b0dc3a73f3660bbb0adbc6 depends: - icu >=73.2,<74.0a0 - libgcc-ng >=12 - libiconv >=1.17,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0a0 - xz >=5.2.6,<6.0a0 license: MIT license_family: MIT - size: 705857 - timestamp: 1715606286167 + size: 704984 + timestamp: 1717546454837 - kind: conda name: libzip version: 1.10.1 @@ -19736,7 +19343,7 @@ packages: md5: 5c629cd12d89e2856c17b1dc5fcf44a4 depends: - bzip2 >=1.0.8,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.1.2,<4.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 @@ -19757,7 +19364,7 @@ packages: depends: - bzip2 >=1.0.8,<2.0a0 - libgcc-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.1.2,<4.0a0 license: BSD-3-Clause license_family: BSD @@ -19774,7 +19381,7 @@ packages: md5: e37c0da207079e488709043634d6a711 depends: - bzip2 >=1.0.8,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.1.2,<4.0a0 license: BSD-3-Clause license_family: BSD @@ -19791,7 +19398,7 @@ packages: md5: 6112b3173f3aa2f12a8f40d07a77cc35 depends: - bzip2 >=1.0.8,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.1.2,<4.0a0 license: BSD-3-Clause license_family: BSD @@ -19800,101 +19407,175 @@ packages: - kind: conda name: libzlib version: 1.2.13 - build: h53f4e23_5 - build_number: 5 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.2.13-h53f4e23_5.conda - sha256: ab1c8aefa2d54322a63aaeeefe9cf877411851738616c4068e0dccc66b9c758a - md5: 1a47f5236db2e06a320ffa0392f81bd8 + build: h2466b09_6 + build_number: 6 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.2.13-h2466b09_6.conda + sha256: 97f47db85265b596d08c044b6533013b7286fb66259c77d04da76b74414c896e + md5: 9f41e3481778398837720a84dd26b7b1 + depends: + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 constrains: - - zlib 1.2.13 *_5 + - zlib 1.2.13 *_6 license: Zlib license_family: Other - size: 48102 - timestamp: 1686575426584 + size: 56119 + timestamp: 1716874608785 - kind: conda name: libzlib version: 1.2.13 - build: h8a1eda9_5 - build_number: 5 + build: h4ab18f5_6 + build_number: 6 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-h4ab18f5_6.conda + sha256: 8ced4afed6322172182af503f21725d072a589a6eb918f8a58135c1e00d35980 + md5: 27329162c0dc732bcf67a4e0cd488125 + depends: + - libgcc-ng >=12 + constrains: + - zlib 1.2.13 *_6 + license: Zlib + license_family: Other + size: 61571 + timestamp: 1716874066944 +- kind: conda + name: libzlib + version: 1.2.13 + build: h87427d6_6 + build_number: 6 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.2.13-h8a1eda9_5.conda - sha256: fc58ad7f47ffea10df1f2165369978fba0a1cc32594aad778f5eec725f334867 - md5: 4a3ad23f6e16f99c04e166767193d700 + url: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.2.13-h87427d6_6.conda + sha256: 1c70fca0720685242b5c68956f310665c7ed43f04807aa4227322eee7925881c + md5: c0ef3c38a80c02ae1d86588c055184fc + depends: + - __osx >=10.13 constrains: - - zlib 1.2.13 *_5 + - zlib 1.2.13 *_6 license: Zlib license_family: Other - size: 59404 - timestamp: 1686575566695 + size: 57373 + timestamp: 1716874185419 - kind: conda name: libzlib version: 1.2.13 - build: hcfcfb64_5 - build_number: 5 + build: hfb2fe0b_6 + build_number: 6 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.2.13-hfb2fe0b_6.conda + sha256: 8b29a2386d99b8f58178951dcf19117b532cd9c4aa07623bf1667eae99755d32 + md5: 9c4e121cd926cab631bd1c4a61d18b17 + depends: + - __osx >=11.0 + constrains: + - zlib 1.2.13 *_6 + license: Zlib + license_family: Other + size: 46768 + timestamp: 1716874151980 +- kind: conda + name: libzlib + version: 1.3.1 + build: h2466b09_1 + build_number: 1 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.2.13-hcfcfb64_5.conda - sha256: c161822ee8130b71e08b6d282b9919c1de2c5274b29921a867bca0f7d30cad26 - md5: 5fdb9c6a113b6b6cb5e517fd972d5f41 + url: https://conda.anaconda.org/conda-forge/win-64/libzlib-1.3.1-h2466b09_1.conda + sha256: b13846a54a15243e15f96fec06b526d8155adc6a1ac2b6ed47a88f6a71a94b68 + md5: d4483ca8afc57ddf1f6dded53b36c17f depends: - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 constrains: - - zlib 1.2.13 *_5 + - zlib 1.3.1 *_1 license: Zlib license_family: Other - size: 55800 - timestamp: 1686575452215 + size: 56186 + timestamp: 1716874730539 - kind: conda name: libzlib - version: 1.2.13 - build: hd590300_5 - build_number: 5 + version: 1.3.1 + build: h4ab18f5_1 + build_number: 1 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.2.13-hd590300_5.conda - sha256: 370c7c5893b737596fd6ca0d9190c9715d89d888b8c88537ae1ef168c25e82e4 - md5: f36c115f1ee199da648e0597ec2047ad + url: https://conda.anaconda.org/conda-forge/linux-64/libzlib-1.3.1-h4ab18f5_1.conda + sha256: adf6096f98b537a11ae3729eaa642b0811478f0ea0402ca67b5108fe2cb0010d + md5: 57d7dc60e9325e3de37ff8dffd18e814 depends: - libgcc-ng >=12 constrains: - - zlib 1.2.13 *_5 + - zlib 1.3.1 *_1 + license: Zlib + license_family: Other + size: 61574 + timestamp: 1716874187109 +- kind: conda + name: libzlib + version: 1.3.1 + build: h87427d6_1 + build_number: 1 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/libzlib-1.3.1-h87427d6_1.conda + sha256: 80a62db652b1da0ccc100812a1d86e94f75028968991bfb17f9536f3aa72d91d + md5: b7575b5aa92108dcc9aaab0f05f2dbce + depends: + - __osx >=10.13 + constrains: + - zlib 1.3.1 *_1 + license: Zlib + license_family: Other + size: 57372 + timestamp: 1716874211519 +- kind: conda + name: libzlib + version: 1.3.1 + build: hfb2fe0b_1 + build_number: 1 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/libzlib-1.3.1-hfb2fe0b_1.conda + sha256: c34365dd37b0eab27b9693af32a1f7f284955517c2cc91f1b88a7ef4738ff03e + md5: 636077128927cf79fd933276dc3aed47 + depends: + - __osx >=11.0 + constrains: + - zlib 1.3.1 *_1 license: Zlib license_family: Other - size: 61588 - timestamp: 1686575217516 + size: 46921 + timestamp: 1716874262512 - kind: conda name: llvm-openmp - version: 18.1.5 - build: h39e0ece_0 + version: 18.1.7 + build: h15ab845_0 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-18.1.5-h39e0ece_0.conda - sha256: 9efba1424726d83271727c494138ad1d519d5fed301f1ee5825019eae56f5570 - md5: ee12a644568269838b91f901b2537425 + url: https://conda.anaconda.org/conda-forge/osx-64/llvm-openmp-18.1.7-h15ab845_0.conda + sha256: 66ab0feed5ed7ace0d9327bc7ae47500afb81ef51e6ef10a478af9d65dd60ac6 + md5: 57440310d92e93efd808c75fec50f94d depends: - - __osx >=10.9 + - __osx >=10.13 constrains: - - openmp 18.1.5|18.1.5.* + - openmp 18.1.7|18.1.7.* license: Apache-2.0 WITH LLVM-exception license_family: APACHE - size: 300438 - timestamp: 1714984682878 + size: 300573 + timestamp: 1717851511113 - kind: conda name: llvm-openmp - version: 18.1.5 + version: 18.1.7 build: hde57baf_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-18.1.5-hde57baf_0.conda - sha256: c9ecaaa3d83215753a54f66038480582eff632196ed0df7763ca320154d00526 - md5: 5b0ef7f8e9f413cbfd53573da96cae1b + url: https://conda.anaconda.org/conda-forge/osx-arm64/llvm-openmp-18.1.7-hde57baf_0.conda + sha256: 30121bc3ebf134d69bcb24ab1270bfa2beeb0ae59579b8acb67a38e3531c05d1 + md5: 2f651f8977594cc74852fa280785187a depends: - __osx >=11.0 constrains: - - openmp 18.1.5|18.1.5.* + - openmp 18.1.7|18.1.7.* license: Apache-2.0 WITH LLVM-exception license_family: APACHE - size: 276522 - timestamp: 1714984701521 + size: 276533 + timestamp: 1717851681081 - kind: conda name: llvmlite version: 0.42.0 @@ -19905,7 +19586,7 @@ packages: sha256: cd8b0fa4d488cb0fd995dbba71915a0a35fb248c857c632013efc3008d956039 md5: b35d44a8c735e61ebe05769f06ae8d12 depends: - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 - ucrt >=10.0.20348.0 @@ -19931,7 +19612,7 @@ packages: - libgcc-ng >=12 - libllvm14 >=14.0.6,<14.1.0a0 - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 license: BSD-2-Clause @@ -19952,7 +19633,7 @@ packages: depends: - libcxx >=16 - libllvm14 >=14.0.6,<14.1.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 license: BSD-2-Clause @@ -19973,7 +19654,7 @@ packages: depends: - libcxx >=16 - libllvm14 >=14.0.6,<14.1.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - python >=3.11,<3.12.0a0 - python >=3.11,<3.12.0a0 *_cpython - python_abi 3.11.* *_cp311 @@ -20803,85 +20484,87 @@ packages: timestamp: 1705681686807 - kind: conda name: minizip - version: 4.0.5 - build: h0ab5242_0 + version: 4.0.6 + build: h0615dfd_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/minizip-4.0.6-h0615dfd_0.conda + sha256: 05900c46fab43ea85bae07980252d858563c368b3d1bc52c3c4f38ed2f1d95c3 + md5: 9dfa5b7f791274f9bf60333cd8145cb6 + depends: + - __osx >=11.0 + - bzip2 >=1.0.8,<2.0a0 + - libcxx >=16 + - libiconv >=1.17,<2.0a0 + - libzlib >=1.2.13,<2.0a0 + - openssl >=3.3.0,<4.0a0 + - xz >=5.2.6,<6.0a0 + - zstd >=1.5.6,<1.6.0a0 + license: Zlib + license_family: Other + size: 78230 + timestamp: 1717296862525 +- kind: conda + name: minizip + version: 4.0.6 + build: h9d307f2_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/minizip-4.0.5-h0ab5242_0.conda - sha256: 1a56549751f4c4a7998e0a8bcff367c3992cb832c0b211d775cfd644e1ef5e6b - md5: 557396140c71eba588e96d597e0c61aa + url: https://conda.anaconda.org/conda-forge/linux-64/minizip-4.0.6-h9d307f2_0.conda + sha256: 5870271f8ce37344b503e6938357802e9b77ca9fe5e36104ae236b3ac720c23d + md5: 857b62ff5fc3b6282189798bf06aa2ca depends: - bzip2 >=1.0.8,<2.0a0 - libgcc-ng >=12 - libiconv >=1.17,<2.0a0 - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 - - openssl >=3.2.1,<4.0a0 + - libzlib >=1.2.13,<2.0a0 + - openssl >=3.3.0,<4.0a0 - xz >=5.2.6,<6.0a0 - - zstd >=1.5.5,<1.6.0a0 + - zstd >=1.5.6,<1.6.0a0 license: Zlib license_family: Other - size: 91279 - timestamp: 1709725664431 + size: 91278 + timestamp: 1717296749853 - kind: conda name: minizip - version: 4.0.5 - build: h37d7099_0 + version: 4.0.6 + build: ha2864c9_0 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/minizip-4.0.5-h37d7099_0.conda - sha256: 426f4db1d56cdefa478a5ece35ed7624860548ace87d6ad927c4c9c6a7a20fec - md5: 2203b2e83c20305b3d669556c345c8e9 + url: https://conda.anaconda.org/conda-forge/osx-64/minizip-4.0.6-ha2864c9_0.conda + sha256: 1371ca11e9c7b29462ea4593ab6b7c468fd25cabdcc341d5d6341f5869799cfd + md5: bbddee5790361176a50608d0c8c97e20 depends: + - __osx >=10.13 - bzip2 >=1.0.8,<2.0a0 - libcxx >=16 - libiconv >=1.17,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 - - openssl >=3.2.1,<4.0a0 + - libzlib >=1.2.13,<2.0a0 + - openssl >=3.3.0,<4.0a0 - xz >=5.2.6,<6.0a0 - - zstd >=1.5.5,<1.6.0a0 + - zstd >=1.5.6,<1.6.0a0 license: Zlib license_family: Other - size: 78099 - timestamp: 1709726140187 + size: 78742 + timestamp: 1717296910668 - kind: conda name: minizip - version: 4.0.5 - build: h5bed578_0 + version: 4.0.6 + build: hb638d1e_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/minizip-4.0.5-h5bed578_0.conda - sha256: 3b77d2f3e71df522e88e1ec4e30742257523ff3e42a4ae0d6c9c7605b4aa6e54 - md5: acd216ec6d40c7e05991dccc4f9165f2 + url: https://conda.anaconda.org/conda-forge/win-64/minizip-4.0.6-hb638d1e_0.conda + sha256: b334446aa40fe368ea816f5ee47145aea4408812a5a8d016db51923d7c465835 + md5: 43e2b972e258a25a1e01790ad0e3287a depends: - bzip2 >=1.0.8,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 - xz >=5.2.6,<6.0a0 - - zstd >=1.5.5,<1.6.0a0 - license: Zlib - license_family: Other - size: 85264 - timestamp: 1709726113246 -- kind: conda - name: minizip - version: 4.0.5 - build: hc35e051_0 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/minizip-4.0.5-hc35e051_0.conda - sha256: 7ad93499e224d49c4f342afb85e24681fa3ef8405e2b1e0a4cb549e90eb8486d - md5: 3698392e5f0823e563c306dde1d3a800 - depends: - - bzip2 >=1.0.8,<2.0a0 - - libcxx >=16 - - libiconv >=1.17,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 - - openssl >=3.2.1,<4.0a0 - - xz >=5.2.6,<6.0a0 - - zstd >=1.5.5,<1.6.0a0 + - zstd >=1.5.6,<1.6.0a0 license: Zlib license_family: Other - size: 77900 - timestamp: 1709726000723 + size: 85324 + timestamp: 1717296997985 - kind: conda name: mistune version: 3.0.2 @@ -20917,21 +20600,21 @@ packages: timestamp: 1712153746272 - kind: conda name: more-itertools - version: 10.2.0 + version: 10.3.0 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.2.0-pyhd8ed1ab_0.conda - sha256: 9e49e9484ff279453f0b55323a3f0c7cb97440c74f69eecda1f4ad29fae5cd3c - md5: d5c98e9706fdc5328d49a9bf2ce5fb42 + url: https://conda.anaconda.org/conda-forge/noarch/more-itertools-10.3.0-pyhd8ed1ab_0.conda + sha256: 9c485cc52dfd646ea584e9055c1bbaac8f27687d806c1ef00f299ec2e642ce04 + md5: a57fb23d0260a962a67c7d990ec1c812 depends: - python >=3.8 license: MIT license_family: MIT purls: - pkg:pypi/more-itertools - size: 54469 - timestamp: 1704738585811 + size: 56261 + timestamp: 1718048569497 - kind: conda name: mpg123 version: 1.32.6 @@ -21255,70 +20938,37 @@ packages: timestamp: 1698938422063 - kind: conda name: mysql-common - version: 8.0.33 - build: hf1915f5_6 - build_number: 6 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/mysql-common-8.0.33-hf1915f5_6.conda - sha256: c8b2c5c9d0d013a4f6ef96cb4b339bfdc53a74232d8c61ed08178e5b1ec4eb63 - md5: 80bf3b277c120dd294b51d404b931a75 - depends: - - libgcc-ng >=12 - - libstdcxx-ng >=12 - - openssl >=3.1.4,<4.0a0 - size: 753467 - timestamp: 1698937026421 -- kind: conda - name: mysql-common - version: 8.0.33 - build: hf9e6398_6 - build_number: 6 + version: 8.3.0 + build: hd1853d3_4 + build_number: 4 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/mysql-common-8.0.33-hf9e6398_6.conda - sha256: 9d60d7779c9c2e6c783521922ab715964fc966d827493877c3b6844dacf2b140 - md5: 5c969a77f976c028192f8120483e2f4d + url: https://conda.anaconda.org/conda-forge/osx-arm64/mysql-common-8.3.0-hd1853d3_4.conda + sha256: 4ed97297f0278c01ea21eb20335141d5bfb29f5820fabd03f8bc1cb74d3fe9a7 + md5: f93a6079f12ef00195d7d0b96ff98191 depends: - - __osx >=10.9 - - libcxx >=16.0.6 - - openssl >=3.1.4,<4.0a0 - size: 751501 - timestamp: 1698939564933 + - libcxx >=16 + - openssl >=3.2.1,<4.0a0 + license: GPL-2.0-or-later + license_family: GPL + size: 800889 + timestamp: 1709915847564 - kind: conda - name: mysql-libs - version: 8.0.33 - build: hca2cd23_6 - build_number: 6 + name: mysql-common + version: 8.3.0 + build: hf1915f5_4 + build_number: 4 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/mysql-libs-8.0.33-hca2cd23_6.conda - sha256: 78c905637dac79b197395065c169d452b8ca2a39773b58e45e23114f1cb6dcdb - md5: e87530d1b12dd7f4e0f856dc07358d60 - depends: - - libgcc-ng >=12 - - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 - - mysql-common 8.0.33 hf1915f5_6 - - openssl >=3.1.4,<4.0a0 - - zstd >=1.5.5,<1.6.0a0 - size: 1530126 - timestamp: 1698937116126 -- kind: conda - name: mysql-libs - version: 8.0.33 - build: he3dca8b_6 - build_number: 6 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/mysql-libs-8.0.33-he3dca8b_6.conda - sha256: 1544f64334c1d87a83df21b93d5b61429db4a9317ddb8b5e09ad3384adf88ad1 - md5: 98bbd77933bb5d947dce7ca552744871 + url: https://conda.anaconda.org/conda-forge/linux-64/mysql-common-8.3.0-hf1915f5_4.conda + sha256: 4cf6d29e091398735348550cb74cfd5006e04892d54b6b1ba916935f1af1a151 + md5: 784a4df6676c581ca624fbe460703a6d depends: - - __osx >=10.9 - - libcxx >=16.0.6 - - libzlib >=1.2.13,<1.3.0a0 - - mysql-common 8.0.33 hf9e6398_6 - - openssl >=3.1.4,<4.0a0 - - zstd >=1.5.5,<1.6.0a0 - size: 1510603 - timestamp: 1698939692982 + - libgcc-ng >=12 + - libstdcxx-ng >=12 + - openssl >=3.2.1,<4.0a0 + license: GPL-2.0-or-later + license_family: GPL + size: 784844 + timestamp: 1709910607121 - kind: conda name: mysql-libs version: 8.0.33 @@ -21331,12 +20981,51 @@ packages: depends: - __osx >=10.9 - libcxx >=16.0.6 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - mysql-common 8.0.33 h1d20c9b_6 - openssl >=3.1.4,<4.0a0 - zstd >=1.5.5,<1.6.0a0 size: 1493906 timestamp: 1698938538673 +- kind: conda + name: mysql-libs + version: 8.3.0 + build: hca2cd23_4 + build_number: 4 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/mysql-libs-8.3.0-hca2cd23_4.conda + sha256: c39cdd1a5829aeffc611f789bdfd4dbd4ce1aa829c73d728defec180b5265d91 + md5: 1b50eebe2a738a3146c154d2eceaa8b6 + depends: + - libgcc-ng >=12 + - libstdcxx-ng >=12 + - libzlib >=1.2.13,<2.0.0a0 + - mysql-common 8.3.0 hf1915f5_4 + - openssl >=3.2.1,<4.0a0 + - zstd >=1.5.5,<1.6.0a0 + license: GPL-2.0-or-later + license_family: GPL + size: 1537884 + timestamp: 1709910705541 +- kind: conda + name: mysql-libs + version: 8.3.0 + build: hf036fc4_4 + build_number: 4 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/mysql-libs-8.3.0-hf036fc4_4.conda + sha256: a48101c076f9a038bd3cfa822df2b20fdc0ccce88f9000c7bee8f6d53a1cc64e + md5: 9cb8011d749d99db2cba868053bcd8cb + depends: + - libcxx >=16 + - libzlib >=1.2.13,<2.0.0a0 + - mysql-common 8.3.0 hd1853d3_4 + - openssl >=3.2.1,<4.0a0 + - zstd >=1.5.5,<1.6.0a0 + license: GPL-2.0-or-later + license_family: GPL + size: 1541174 + timestamp: 1709915999617 - kind: conda name: nbclient version: 0.10.0 @@ -21361,28 +21050,30 @@ packages: - kind: conda name: nbconvert version: 7.16.4 - build: hd8ed1ab_0 + build: hd8ed1ab_1 + build_number: 1 subdir: noarch noarch: generic - url: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.4-hd8ed1ab_0.conda - sha256: 7a4a759b8930833cbfffbfd92da069f1d3fd43760ea629c8612b9e7ae9fff0e8 - md5: c9d64b8a7ee8e6bdbf0e7d8aa7f39601 + url: https://conda.anaconda.org/conda-forge/noarch/nbconvert-7.16.4-hd8ed1ab_1.conda + sha256: e014e8a583ca2f2fc751bf9093ee95bfd203bd189bafe0f512c0262fece69bce + md5: ab83e3b9ca2b111d8f332e9dc8b2170f depends: - - nbconvert-core 7.16.4 pyhd8ed1ab_0 - - nbconvert-pandoc 7.16.4 hd8ed1ab_0 + - nbconvert-core 7.16.4 pyhd8ed1ab_1 + - nbconvert-pandoc 7.16.4 hd8ed1ab_1 license: BSD-3-Clause license_family: BSD - size: 8434 - timestamp: 1714477296945 + size: 8335 + timestamp: 1718135538730 - kind: conda name: nbconvert-core version: 7.16.4 - build: pyhd8ed1ab_0 + build: pyhd8ed1ab_1 + build_number: 1 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.4-pyhd8ed1ab_0.conda - sha256: aa5bf61e42c63cec2b2c33e66cd0bb064846d62dd60f6ac62ae0d2bf17583900 - md5: 43d9cd74e3950ab09cbddf36f1706b9f + url: https://conda.anaconda.org/conda-forge/noarch/nbconvert-core-7.16.4-pyhd8ed1ab_1.conda + sha256: 074d858c5808e0a832acc0da37cd70de1565e8d6e17a62d5a11b3902b5e78319 + md5: e2d2abb421c13456a9a9f80272fdf543 depends: - beautifulsoup4 - bleach @@ -21402,30 +21093,31 @@ packages: - tinycss2 - traitlets >=5.0 constrains: + - nbconvert =7.16.4=*_1 - pandoc >=2.9.2,<4.0.0 - - nbconvert =7.16.4=*_0 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/nbconvert - size: 189004 - timestamp: 1714477286178 + size: 189599 + timestamp: 1718135529468 - kind: conda name: nbconvert-pandoc version: 7.16.4 - build: hd8ed1ab_0 + build: hd8ed1ab_1 + build_number: 1 subdir: noarch noarch: generic - url: https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.16.4-hd8ed1ab_0.conda - sha256: d3bd8b38a74825e9e502f3251fba167b303d7ad324cd4e41d459bfa3c118c9ee - md5: 391934bd1a79990c23df1d1809ddc821 + url: https://conda.anaconda.org/conda-forge/noarch/nbconvert-pandoc-7.16.4-hd8ed1ab_1.conda + sha256: 31df882e97b227e7e57a328a36840e65ea3247023ac2ce502fd5d4b621da8dbe + md5: 37cec2cf68f4c09563d8bc833791096b depends: - - nbconvert-core 7.16.4 pyhd8ed1ab_0 + - nbconvert-core 7.16.4 pyhd8ed1ab_1 - pandoc license: BSD-3-Clause license_family: BSD - size: 8479 - timestamp: 1714477291801 + size: 8371 + timestamp: 1718135533429 - kind: conda name: nbformat version: 5.10.4 @@ -21502,19 +21194,19 @@ packages: - kind: conda name: netcdf4 version: 1.6.5 - build: nompi_py311h74118c1_101 - build_number: 101 + build: nompi_py311h74118c1_102 + build_number: 102 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/netcdf4-1.6.5-nompi_py311h74118c1_101.conda - sha256: 67520d8fe813cf4b55f21d8b6aecbcceb10920f5507c7486741b42ad89be188f - md5: 153b3a81c6f11e87b87461247c3cf061 + url: https://conda.anaconda.org/conda-forge/linux-64/netcdf4-1.6.5-nompi_py311h74118c1_102.conda + sha256: 79d6d2f23dc13addd010a06a579409894de5646cb71d8e22244449c9d1165814 + md5: 5f98c1d56c5853270c7876bb1000a631 depends: - certifi - cftime - hdf5 >=1.14.3,<1.14.4.0a0 - libgcc-ng >=12 - libnetcdf >=4.9.2,<4.9.3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0a0 - numpy >=1.19,<3 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 @@ -21523,24 +21215,24 @@ packages: license_family: MIT purls: - pkg:pypi/netcdf4 - size: 557333 - timestamp: 1715939298381 + size: 556373 + timestamp: 1717691028237 - kind: conda name: netcdf4 version: 1.6.5 - build: nompi_py311hab941cd_101 - build_number: 101 + build: nompi_py311hab941cd_102 + build_number: 102 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/netcdf4-1.6.5-nompi_py311hab941cd_101.conda - sha256: 9057acee66024372329b07d81cd8bbc2980611d41c5dcef7c2a56dd8183d4b71 - md5: 60da528a482b4e7819febcb89e1a57e4 + url: https://conda.anaconda.org/conda-forge/osx-64/netcdf4-1.6.5-nompi_py311hab941cd_102.conda + sha256: bc044da2faeb8102fac74b0064ce4ce24f3422dd68f8f1381826e3f801ca2774 + md5: f948562ee50f95027bf255c1ddd5be96 depends: - __osx >=10.13 - certifi - cftime - hdf5 >=1.14.3,<1.14.4.0a0 - libnetcdf >=4.9.2,<4.9.3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0a0 - numpy >=1.19,<3 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 @@ -21549,23 +21241,23 @@ packages: license_family: MIT purls: - pkg:pypi/netcdf4 - size: 469277 - timestamp: 1715939070423 + size: 469009 + timestamp: 1717690800990 - kind: conda name: netcdf4 version: 1.6.5 - build: nompi_py311hb75404a_101 - build_number: 101 + build: nompi_py311hb75404a_102 + build_number: 102 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/netcdf4-1.6.5-nompi_py311hb75404a_101.conda - sha256: 5e1e1a890bd2038056996a00fa212d5f19e208c7807e1cfc191cee69ae8661e0 - md5: 68dd82ca7348168106ab2c7c0fa41a87 + url: https://conda.anaconda.org/conda-forge/win-64/netcdf4-1.6.5-nompi_py311hb75404a_102.conda + sha256: 0746aaf76a2ca5d701a72ebfd5125e363cd25cf08c41ba32873b7b427c4ea582 + md5: 1eafdb41d3e75890971a3aa8e19e3c00 depends: - certifi - cftime - hdf5 >=1.14.3,<1.14.4.0a0 - libnetcdf >=4.9.2,<4.9.3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0a0 - numpy >=1.19,<3 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 @@ -21577,24 +21269,24 @@ packages: license_family: MIT purls: - pkg:pypi/netcdf4 - size: 429721 - timestamp: 1715939453687 + size: 431615 + timestamp: 1717691332865 - kind: conda name: netcdf4 version: 1.6.5 - build: nompi_py311hd61c382_101 - build_number: 101 + build: nompi_py311hd61c382_102 + build_number: 102 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/netcdf4-1.6.5-nompi_py311hd61c382_101.conda - sha256: 46c496da5ea0e9e6e769c079467240ca3902c4acc187b5ecc9033599761a3c23 - md5: 523f6d24b6b3915b4722b5cf56b6e2bf + url: https://conda.anaconda.org/conda-forge/osx-arm64/netcdf4-1.6.5-nompi_py311hd61c382_102.conda + sha256: b6a534c32141fb914f1131719039471ab788418ecd8d632a56a79b52a49bc280 + md5: ed5c69e7df229251fed466b60f320f62 depends: - __osx >=11.0 - certifi - cftime - hdf5 >=1.14.3,<1.14.4.0a0 - libnetcdf >=4.9.2,<4.9.3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0a0 - numpy >=1.19,<3 - python >=3.11,<3.12.0a0 - python >=3.11,<3.12.0a0 *_cpython @@ -21604,8 +21296,8 @@ packages: license_family: MIT purls: - pkg:pypi/netcdf4 - size: 461494 - timestamp: 1715939543990 + size: 460864 + timestamp: 1717691495046 - kind: conda name: nettle version: 3.9.1 @@ -21794,13 +21486,13 @@ packages: timestamp: 1710905243663 - kind: conda name: notebook - version: 7.2.0 + version: 7.2.1 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/notebook-7.2.0-pyhd8ed1ab_0.conda - sha256: ae2d2d9d6d83457374ae42464aee22c1575355743065b1624ca5b8d6ac222f1b - md5: d90ee86e24611ac4f3c1cb60f841bc23 + url: https://conda.anaconda.org/conda-forge/noarch/notebook-7.2.1-pyhd8ed1ab_0.conda + sha256: 6b23256e63225ff15b0d5e91d49111936df05748bb31afa321b29556087f85f4 + md5: 08fa71a038c2cac2e636a5a456df15d5 depends: - jupyter_server >=2.4.0,<3 - jupyterlab >=4.2.0,<4.3 @@ -21812,8 +21504,8 @@ packages: license_family: BSD purls: - pkg:pypi/notebook - size: 4009405 - timestamp: 1715879797483 + size: 3899981 + timestamp: 1717767864474 - kind: conda name: notebook-shim version: 0.2.4 @@ -21887,7 +21579,7 @@ packages: - __osx >=10.13 - libcxx >=16 - libsqlite >=3.45.3,<4.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - nspr >=4.35,<5.0a0 license: MPL-2.0 license_family: MOZILLA @@ -21905,7 +21597,7 @@ packages: - __osx >=11.0 - libcxx >=16 - libsqlite >=3.45.3,<4.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - nspr >=4.35,<5.0a0 license: MPL-2.0 license_family: MOZILLA @@ -21924,7 +21616,7 @@ packages: - libgcc-ng >=12 - libsqlite >=3.45.3,<4.0a0 - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - nspr >=4.35,<5.0a0 license: MPL-2.0 license_family: MOZILLA @@ -22259,91 +21951,88 @@ packages: - kind: conda name: occt version: 7.7.2 - build: all_h165458f_201 + build: all_hd7ce604_201 build_number: 201 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/occt-7.7.2-all_h165458f_201.conda - sha256: 35195d25389785de571d6afc17a3bdb94ad9e27631add43f512320b47f181695 - md5: 14d366c0500933015b307549890d679a + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/occt-7.7.2-all_hd7ce604_201.conda + sha256: a72037e1bfa305f0746071cbfb1f483db33168b75ae4d37f48e7ee676cd28628 + md5: f3fbeb2ef8255009e42a086fd2482894 depends: - fontconfig >=2.14.2,<3.0a0 - fonts-conda-ecosystem - freeimage >=3.18.0,<3.19.0a0 - freetype >=2.12.1,<3.0a0 + - libcxx >=15.0.7 - rapidjson - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - vtk >=9.2.6,<9.2.7.0a0 license: LGPL-2.1-only license_family: LGPL - size: 24871333 - timestamp: 1696403641700 + size: 25620859 + timestamp: 1696403774494 - kind: conda name: occt version: 7.7.2 - build: all_h1e2436f_201 - build_number: 201 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/occt-7.7.2-all_h1e2436f_201.conda - sha256: 2bae67c23994fcd46846365ec444acbb54a691aa51b0833e85f9a1850b5831bf - md5: 5d0c38b11e119917ee83046ad6b13de4 + build: novtk_h130ccc2_101 + build_number: 101 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/occt-7.7.2-novtk_h130ccc2_101.conda + sha256: bc44d7a37b46ab71453df70d910af22be7e89dbdd8d8020441c3104ab8b2e2eb + md5: 4a7df4c1d4f8e053e232a08a674f5c9f depends: - fontconfig >=2.14.2,<3.0a0 - fonts-conda-ecosystem - freeimage >=3.18.0,<3.19.0a0 - freetype >=2.12.1,<3.0a0 - - libcxx >=15.0.7 + - libgcc-ng >=12 + - libstdcxx-ng >=12 - rapidjson - - vtk >=9.2.6,<9.2.7.0a0 + - xorg-libxt >=1.3.0,<2.0a0 license: LGPL-2.1-only license_family: LGPL - size: 24774594 - timestamp: 1696403892005 + size: 28477401 + timestamp: 1696401589947 - kind: conda name: occt version: 7.7.2 - build: all_h4c9f3c6_201 - build_number: 201 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/occt-7.7.2-all_h4c9f3c6_201.conda - sha256: 6d5d4358b3022387c8ea43345d346594e0576d8ad1d8976f938801b4d355114c - md5: c3433e65219e92395cba0cc048a45746 + build: novtk_h5f4376a_101 + build_number: 101 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/occt-7.7.2-novtk_h5f4376a_101.conda + sha256: d4c8363950a2919ec858ddbaed0a39adfbf10ebde955730c87fe63369d5c147a + md5: 5d28db29700879ae6f1e86ad06c13d6e depends: - fontconfig >=2.14.2,<3.0a0 - fonts-conda-ecosystem - freeimage >=3.18.0,<3.19.0a0 - freetype >=2.12.1,<3.0a0 - - libgcc-ng >=12 - - libstdcxx-ng >=12 + - libcxx >=15.0.7 - rapidjson - - vtk >=9.2.6,<9.2.7.0a0 - - xorg-libxt >=1.3.0,<2.0a0 license: LGPL-2.1-only license_family: LGPL - size: 28442268 - timestamp: 1696401541578 + size: 24558772 + timestamp: 1696403429797 - kind: conda name: occt version: 7.7.2 - build: all_hd7ce604_201 - build_number: 201 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/occt-7.7.2-all_hd7ce604_201.conda - sha256: a72037e1bfa305f0746071cbfb1f483db33168b75ae4d37f48e7ee676cd28628 - md5: f3fbeb2ef8255009e42a086fd2482894 + build: novtk_hdfb195f_101 + build_number: 101 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/occt-7.7.2-novtk_hdfb195f_101.conda + sha256: b30bfefe57de6d28a5afdb554086f0e0bd23132ca3168cd31ea11cb6c0946e58 + md5: ecbfd4ea0d437d3fde8e5feb0859c13e depends: - fontconfig >=2.14.2,<3.0a0 - fonts-conda-ecosystem - freeimage >=3.18.0,<3.19.0a0 - freetype >=2.12.1,<3.0a0 - - libcxx >=15.0.7 - rapidjson - - vtk >=9.2.6,<9.2.7.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: LGPL-2.1-only license_family: LGPL - size: 25620859 - timestamp: 1696403774494 + size: 24875675 + timestamp: 1696401524583 - kind: conda name: ocl-icd version: 2.3.2 @@ -22371,7 +22060,7 @@ packages: depends: - imath >=3.1.11,<3.1.12.0a0 - libcxx >=16 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: BSD-3-Clause license_family: BSD size: 1361156 @@ -22388,7 +22077,7 @@ packages: depends: - imath >=3.1.11,<3.1.12.0a0 - libcxx >=16 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: BSD-3-Clause license_family: BSD size: 1329934 @@ -22404,7 +22093,7 @@ packages: md5: 3cecd7892a09d59f64a3e119647630f9 depends: - imath >=3.1.11,<3.1.12.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 @@ -22425,7 +22114,7 @@ packages: - imath >=3.1.11,<3.1.12.0a0 - libgcc-ng >=12 - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: BSD-3-Clause license_family: BSD size: 1466865 @@ -22500,7 +22189,7 @@ packages: depends: - libpng >=1.6.43,<1.7.0a0 - libtiff >=4.6.0,<4.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 @@ -22521,7 +22210,7 @@ packages: - libpng >=1.6.43,<1.7.0a0 - libstdcxx-ng >=12 - libtiff >=4.6.0,<4.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: BSD-2-Clause license_family: BSD size: 341592 @@ -22538,7 +22227,7 @@ packages: - libcxx >=16 - libpng >=1.6.43,<1.7.0a0 - libtiff >=4.6.0,<4.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: BSD-2-Clause license_family: BSD size: 331273 @@ -22555,20 +22244,19 @@ packages: - libcxx >=16 - libpng >=1.6.43,<1.7.0a0 - libtiff >=4.6.0,<4.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: BSD-2-Clause license_family: BSD size: 316603 timestamp: 1709159627299 - kind: conda name: openssl - version: 3.3.0 - build: h2466b09_3 - build_number: 3 + version: 3.3.1 + build: h2466b09_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.0-h2466b09_3.conda - sha256: 11b2513fceb20102bdc7f7656a59005acb9ecd0886b7cbfb9c13c2c953f2429b - md5: d7fec5d3bb8fc0c8e266bf1ad350cec5 + url: https://conda.anaconda.org/conda-forge/win-64/openssl-3.3.1-h2466b09_0.conda + sha256: fbd63a41b854370a74e5f7ccc50d67f053d60c08e40389156e7924df0824d297 + md5: 27fe798366ef3a81715b13eedf699e2f depends: - ca-certificates - ucrt >=10.0.20348.0 @@ -22578,17 +22266,16 @@ packages: - pyopenssl >=22.1 license: Apache-2.0 license_family: Apache - size: 8368468 - timestamp: 1716471282135 + size: 8383610 + timestamp: 1717550042871 - kind: conda name: openssl - version: 3.3.0 - build: h4ab18f5_3 - build_number: 3 + version: 3.3.1 + build: h4ab18f5_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.0-h4ab18f5_3.conda - sha256: 33dcea0ed3a61b2de6b66661cdd55278640eb99d676cd129fbff3e53641fa125 - md5: 12ea6d0d4ed54530eaed18e4835c1f7c + url: https://conda.anaconda.org/conda-forge/linux-64/openssl-3.3.1-h4ab18f5_0.conda + sha256: 9691f8bd6394c5bb0b8d2f47cd1467b91bd5b1df923b69e6b517f54496ee4b50 + md5: a41fa0e391cc9e0d6b78ac69ca047a6c depends: - ca-certificates - libgcc-ng >=12 @@ -22596,17 +22283,16 @@ packages: - pyopenssl >=22.1 license: Apache-2.0 license_family: Apache - size: 2891147 - timestamp: 1716468354865 + size: 2896170 + timestamp: 1717546157673 - kind: conda name: openssl - version: 3.3.0 - build: h87427d6_3 - build_number: 3 + version: 3.3.1 + build: h87427d6_0 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.0-h87427d6_3.conda - sha256: 58ffbdce44ac18c6632a2ce1531d06e3fb2e855d40728ba3a2b709158b9a1c33 - md5: ec504fefb403644d893adffb6e7a2dbe + url: https://conda.anaconda.org/conda-forge/osx-64/openssl-3.3.1-h87427d6_0.conda + sha256: 272bee725877f417fef923f5e7852ebfe06b40b6bf3364f4498b2b3f568d5e2c + md5: 1bdad93ae01353340f194c5d879745db depends: - __osx >=10.13 - ca-certificates @@ -22614,17 +22300,16 @@ packages: - pyopenssl >=22.1 license: Apache-2.0 license_family: Apache - size: 2542959 - timestamp: 1716468436467 + size: 2547614 + timestamp: 1717546605131 - kind: conda name: openssl - version: 3.3.0 - build: hfb2fe0b_3 - build_number: 3 + version: 3.3.1 + build: hfb2fe0b_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.0-hfb2fe0b_3.conda - sha256: 6f41c163ab57e7499dff092be4498614651f0f6432e12c2b9f06859a8bc39b75 - md5: 730f618b008b3c13c1e3f973408ddd67 + url: https://conda.anaconda.org/conda-forge/osx-arm64/openssl-3.3.1-hfb2fe0b_0.conda + sha256: 6cb2d44f027b259be8cba2240bdf21af7b426e4132a73e0052f7173ab8b60ab0 + md5: c4a0bbd96a0da60bf265dac62c87f4e1 depends: - __osx >=11.0 - ca-certificates @@ -22632,8 +22317,8 @@ packages: - pyopenssl >=22.1 license: Apache-2.0 license_family: Apache - size: 2893954 - timestamp: 1716468329572 + size: 2891941 + timestamp: 1717545846389 - kind: conda name: orc version: 2.0.0 @@ -22647,7 +22332,7 @@ packages: - libgcc-ng >=12 - libprotobuf >=4.25.3,<4.25.4.0a0 - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - snappy >=1.2.0,<1.3.0a0 - zstd >=1.5.5,<1.6.0a0 @@ -22668,7 +22353,7 @@ packages: - __osx >=11.0 - libcxx >=16 - libprotobuf >=4.25.3,<4.25.4.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - snappy >=1.2.0,<1.3.0a0 - zstd >=1.5.5,<1.6.0a0 @@ -22687,7 +22372,7 @@ packages: md5: f61ae80fe162b09c627473932d5dc8c3 depends: - libprotobuf >=4.25.3,<4.25.4.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - snappy >=1.2.0,<1.3.0a0 - ucrt >=10.0.20348.0 @@ -22713,7 +22398,7 @@ packages: - __osx >=10.13 - libcxx >=16 - libprotobuf >=4.25.3,<4.25.4.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - snappy >=1.2.0,<1.3.0a0 - zstd >=1.5.5,<1.6.0a0 @@ -22787,21 +22472,21 @@ packages: timestamp: 1654868759643 - kind: conda name: packaging - version: '24.0' + version: '24.1' build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/packaging-24.0-pyhd8ed1ab_0.conda - sha256: a390182d74c31dfd713c16db888c92c277feeb6d1fe96ff9d9c105f9564be48a - md5: 248f521b64ce055e7feae3105e7abeb8 + url: https://conda.anaconda.org/conda-forge/noarch/packaging-24.1-pyhd8ed1ab_0.conda + sha256: 36aca948219e2c9fdd6d80728bcc657519e02f06c2703d8db3446aec67f51d81 + md5: cbe1bb1f21567018ce595d9c2be0f0db depends: - python >=3.8 license: Apache-2.0 license_family: APACHE purls: - pkg:pypi/packaging - size: 49832 - timestamp: 1710076089469 + size: 50290 + timestamp: 1718189540074 - kind: conda name: pandamesh version: 0.1.5 @@ -22991,11 +22676,11 @@ packages: - kind: conda name: pango version: 1.52.1 - build: h07c897b_0 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/pango-1.52.1-h07c897b_0.conda - sha256: 7c32ab437db0a4a4a4417c4f370b33c9655d4a3b404da8ce60995367ded3ea3f - md5: 29ef4f1131bebc13482e65226cc0c62c + build: h7f2093b_0 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/pango-1.52.1-h7f2093b_0.conda + sha256: 93ccddbcd2845bdbb5bc65ef3c7039170f1ccb4a1c21fa062986b82665ec513b + md5: 5525033b1743273720d851e430b3eaed depends: - cairo >=1.18.0,<2.0a0 - fontconfig >=2.14.2,<3.0a0 @@ -23006,69 +22691,73 @@ packages: - libglib >=2.78.4,<3.0a0 - libpng >=1.6.43,<1.7.0a0 license: LGPL-2.1-or-later - size: 448419 - timestamp: 1709762590439 + size: 420184 + timestamp: 1709762297359 - kind: conda name: pango - version: 1.52.1 - build: h7f2093b_0 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/pango-1.52.1-h7f2093b_0.conda - sha256: 93ccddbcd2845bdbb5bc65ef3c7039170f1ccb4a1c21fa062986b82665ec513b - md5: 5525033b1743273720d851e430b3eaed + version: 1.54.0 + build: h2231ffd_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/pango-1.54.0-h2231ffd_0.conda + sha256: f7910cc0ea1cff76adb2bcec81627e10d6b13f1956a47a69422b71cdc554bfe6 + md5: cef297f5eac752831efd6e680bf980bd depends: - cairo >=1.18.0,<2.0a0 - fontconfig >=2.14.2,<3.0a0 - fonts-conda-ecosystem - freetype >=2.12.1,<3.0a0 - fribidi >=1.0.10,<2.0a0 - - harfbuzz >=8.3.0,<9.0a0 - - libglib >=2.78.4,<3.0a0 + - harfbuzz >=8.5.0,<9.0a0 + - libglib >=2.80.2,<3.0a0 - libpng >=1.6.43,<1.7.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: LGPL-2.1-or-later - size: 420184 - timestamp: 1709762297359 + size: 451206 + timestamp: 1718027861472 - kind: conda name: pango - version: 1.52.1 - build: ha41ecd1_0 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/pango-1.52.1-ha41ecd1_0.conda - sha256: 53d3442fb39eb9f0ac36646769469f2f825afaeda984719002460efd7c3d354f - md5: 5c0cc002bf4eaa56448b0729efd6e96c + version: 1.54.0 + build: h5cb9fbc_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/pango-1.54.0-h5cb9fbc_0.conda + sha256: 45dd6dc3a5b737871f8bc6a5fd9857d37f6e411f33051ce8043af41c35c7fa02 + md5: e490cbccf161da2220fd9be3463c0fac depends: + - __osx >=11.0 - cairo >=1.18.0,<2.0a0 - fontconfig >=2.14.2,<3.0a0 - fonts-conda-ecosystem - freetype >=2.12.1,<3.0a0 - fribidi >=1.0.10,<2.0a0 - - harfbuzz >=8.3.0,<9.0a0 - - libgcc-ng >=12 - - libglib >=2.78.4,<3.0a0 + - harfbuzz >=8.5.0,<9.0a0 + - libglib >=2.80.2,<3.0a0 - libpng >=1.6.43,<1.7.0a0 license: LGPL-2.1-or-later - size: 444188 - timestamp: 1709762011295 + size: 417356 + timestamp: 1718027781756 - kind: conda name: pango - version: 1.52.1 - build: hb067d4f_0 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/pango-1.52.1-hb067d4f_0.conda - sha256: 9fd14a2f99d48c6c2729ec8bc0a5db2bd6442f2766a7393f930138409e829a91 - md5: bbd3e01b8988231317fc1f204d177795 + version: 1.54.0 + build: h84a9a3c_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/pango-1.54.0-h84a9a3c_0.conda + sha256: 3d0ef5a908f0429d7821d8a03a6f19ea7801245802c47f7c8c57163ea60e45c7 + md5: 7c51e110b2f059c0843269d3324e4b22 depends: - cairo >=1.18.0,<2.0a0 - fontconfig >=2.14.2,<3.0a0 - fonts-conda-ecosystem - freetype >=2.12.1,<3.0a0 - fribidi >=1.0.10,<2.0a0 - - harfbuzz >=8.3.0,<9.0a0 - - libglib >=2.78.4,<3.0a0 + - harfbuzz >=8.5.0,<9.0a0 + - libgcc-ng >=12 + - libglib >=2.80.2,<3.0a0 - libpng >=1.6.43,<1.7.0a0 license: LGPL-2.1-or-later - size: 413416 - timestamp: 1709762628624 + size: 448452 + timestamp: 1718027397723 - kind: conda name: parso version: 0.8.4 @@ -23132,60 +22821,60 @@ packages: md5: 41de8bab2d5e5cd6daaba1896e81d366 depends: - bzip2 >=1.0.8,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: BSD-3-Clause license_family: BSD size: 899794 timestamp: 1698610978148 - kind: conda name: pcre2 - version: '10.42' + version: '10.43' build: h17e33f8_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.42-h17e33f8_0.conda - sha256: 25e33b148478de58842ccc018fbabb414665de59270476e92c951203d4485bb1 - md5: 59610c61da3af020289a806ec9c6a7fd + url: https://conda.anaconda.org/conda-forge/win-64/pcre2-10.43-h17e33f8_0.conda + sha256: 9a82c7d49c4771342b398661862975efb9c30e7af600b5d2e08a0bf416fda492 + md5: d0485b8aa2cedb141a7bd27b4efa4c9c depends: - bzip2 >=1.0.8,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 license: BSD-3-Clause license_family: BSD - size: 880802 - timestamp: 1698611415241 + size: 818317 + timestamp: 1708118868321 - kind: conda name: pcre2 - version: '10.42' + version: '10.43' build: h26f9a81_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/pcre2-10.42-h26f9a81_0.conda - sha256: 0335a08349ecd8dce0b81699fcd61b58415e658fe953feb27316fbb994df0685 - md5: 3e12888ecc8ee1ebee2eef9b7856357a + url: https://conda.anaconda.org/conda-forge/osx-arm64/pcre2-10.43-h26f9a81_0.conda + sha256: 4bf7b5fa091f5e7ab0b78778458be1e81c1ffa182b63795734861934945a63a7 + md5: 1ddc87f00014612830f3235b5ad6d821 depends: - bzip2 >=1.0.8,<2.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: BSD-3-Clause license_family: BSD - size: 619848 - timestamp: 1698610997157 + size: 615219 + timestamp: 1708118184900 - kind: conda name: pcre2 - version: '10.42' + version: '10.43' build: hcad00b1_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.42-hcad00b1_0.conda - sha256: 3ca54ff0abcda964af7d4724d389ae20d931159ae1881cfe57ad4b0ab9e6a380 - md5: 679c8961826aa4b50653bce17ee52abe + url: https://conda.anaconda.org/conda-forge/linux-64/pcre2-10.43-hcad00b1_0.conda + sha256: 766dd986a7ed6197676c14699000bba2625fd26c8a890fcb7a810e5cf56155bc + md5: 8292dea9e022d9610a11fce5e0896ed8 depends: - bzip2 >=1.0.8,<2.0a0 - libgcc-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: BSD-3-Clause license_family: BSD - size: 1017235 - timestamp: 1698610864983 + size: 950847 + timestamp: 1708118050286 - kind: conda name: pep517 version: 0.13.0 @@ -23254,7 +22943,7 @@ packages: - libtiff >=4.6.0,<4.7.0a0 - libwebp-base >=1.3.2,<2.0a0 - libxcb >=1.15,<1.16.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openjpeg >=2.5.2,<3.0a0 - python >=3.11,<3.12.0a0 - python >=3.11,<3.12.0a0 *_cpython @@ -23281,7 +22970,7 @@ packages: - libtiff >=4.6.0,<4.7.0a0 - libwebp-base >=1.3.2,<2.0a0 - libxcb >=1.15,<1.16.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openjpeg >=2.5.2,<3.0a0 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 @@ -23306,7 +22995,7 @@ packages: - libtiff >=4.6.0,<4.7.0a0 - libwebp-base >=1.3.2,<2.0a0 - libxcb >=1.15,<1.16.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openjpeg >=2.5.2,<3.0a0 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 @@ -23331,7 +23020,7 @@ packages: - libtiff >=4.6.0,<4.7.0a0 - libwebp-base >=1.3.2,<2.0a0 - libxcb >=1.15,<1.16.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openjpeg >=2.5.2,<3.0a0 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 @@ -23441,21 +23130,21 @@ packages: timestamp: 1709239846651 - kind: conda name: pkginfo - version: 1.10.0 + version: 1.11.1 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.10.0-pyhd8ed1ab_0.conda - sha256: 3e833f907039646e34d23203cd5c9cc487a451d955d8c8d6581e18a8ccef4cee - md5: 8c6a4a704308f5d91f3a974a72db1096 + url: https://conda.anaconda.org/conda-forge/noarch/pkginfo-1.11.1-pyhd8ed1ab_0.conda + sha256: 8eb347932cd42fffe9370e82a31cfbabc40b2149c2b049cf087d4a78f5b3b53c + md5: 6a3e4fb1396215d0d88b3cc2f09de412 depends: - - python >=3.7 + - python >=3.8 license: MIT license_family: MIT purls: - pkg:pypi/pkginfo - size: 28142 - timestamp: 1709561205511 + size: 29692 + timestamp: 1717941209022 - kind: conda name: pkgutil-resolve-name version: 1.3.10 @@ -23527,13 +23216,13 @@ packages: timestamp: 1712243121626 - kind: conda name: pooch - version: 1.8.1 + version: 1.8.2 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.1-pyhd8ed1ab_0.conda - sha256: 63f95e626754f5e05e74f39c0f4866aa8bd40b933eef336077978d365d66ca7b - md5: d15917f33140f8d2ac9ca44db7ec8a25 + url: https://conda.anaconda.org/conda-forge/noarch/pooch-1.8.2-pyhd8ed1ab_0.conda + sha256: f2ee98740ac62ff46700c3cae8a18c78bdb3d6dd80832c6e691e789b844830d8 + md5: 8dab97d8a9616e07d779782995710aed depends: - packaging >=20.0 - platformdirs >=2.5.0 @@ -23543,8 +23232,8 @@ packages: license_family: BSD purls: - pkg:pypi/pooch - size: 52720 - timestamp: 1708448699261 + size: 54375 + timestamp: 1717777969967 - kind: conda name: poppler version: 24.02.0 @@ -23567,7 +23256,7 @@ packages: - libjpeg-turbo >=3.0.0,<4.0a0 - libpng >=1.6.42,<1.7.0a0 - libtiff >=4.6.0,<4.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - nspr >=4.35,<5.0a0 - nss >=3.97,<4.0a0 - openjpeg >=2.5.0,<3.0a0 @@ -23578,12 +23267,12 @@ packages: timestamp: 1707085713504 - kind: conda name: poppler - version: 24.02.0 + version: 24.03.0 build: h590f24d_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/poppler-24.02.0-h590f24d_0.conda - sha256: 55bb2deb67c76bd9f5592bf9765cc879cf11e555c4f8879292cbd5544e88887e - md5: 7e715c1572de09d6106c5a31fa70ffca + url: https://conda.anaconda.org/conda-forge/linux-64/poppler-24.03.0-h590f24d_0.conda + sha256: 0ea3e63ae3ba07bcae8cc541647c647c68aeec32dfbe3bbaeecc845833b27a6f + md5: c688853df9dcfed47200d0e28e5dfe11 depends: - cairo >=1.18.0,<2.0a0 - fontconfig >=2.14.2,<3.0a0 @@ -23592,29 +23281,29 @@ packages: - lcms2 >=2.16,<3.0a0 - libcurl >=8.5.0,<9.0a0 - libgcc-ng >=12 - - libglib >=2.78.3,<3.0a0 + - libglib >=2.78.4,<3.0a0 - libiconv >=1.17,<2.0a0 - libjpeg-turbo >=3.0.0,<4.0a0 - - libpng >=1.6.42,<1.7.0a0 + - libpng >=1.6.43,<1.7.0a0 - libstdcxx-ng >=12 - libtiff >=4.6.0,<4.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - nspr >=4.35,<5.0a0 - - nss >=3.97,<4.0a0 - - openjpeg >=2.5.0,<3.0a0 + - nss >=3.98,<4.0a0 + - openjpeg >=2.5.2,<3.0a0 - poppler-data license: GPL-2.0-only license_family: GPL - size: 1846319 - timestamp: 1707085261766 + size: 1846447 + timestamp: 1710150513789 - kind: conda name: poppler - version: 24.02.0 + version: 24.03.0 build: h896e6cb_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/poppler-24.02.0-h896e6cb_0.conda - sha256: c4d579795f329f1fe1b590d7cc3fc31d6b68f08e27b1f84e36ea3e9e05de5d6e - md5: 228b76f3de35d7bbe1374e52d1e0a5bb + url: https://conda.anaconda.org/conda-forge/osx-arm64/poppler-24.03.0-h896e6cb_0.conda + sha256: a68463831145e1faec9a39a39b1676379c8a67e9955ae8ff2bb4c7870a09df8e + md5: 9ceb412621711e3ea8742015c69aa7f9 depends: - cairo >=1.18.0,<2.0a0 - fontconfig >=2.14.2,<3.0a0 @@ -23624,48 +23313,48 @@ packages: - lcms2 >=2.16,<3.0a0 - libcurl >=8.5.0,<9.0a0 - libcxx >=16 - - libglib >=2.78.3,<3.0a0 + - libglib >=2.78.4,<3.0a0 - libiconv >=1.17,<2.0a0 - libjpeg-turbo >=3.0.0,<4.0a0 - - libpng >=1.6.42,<1.7.0a0 + - libpng >=1.6.43,<1.7.0a0 - libtiff >=4.6.0,<4.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - nspr >=4.35,<5.0a0 - - nss >=3.97,<4.0a0 - - openjpeg >=2.5.0,<3.0a0 + - nss >=3.98,<4.0a0 + - openjpeg >=2.5.2,<3.0a0 - poppler-data license: GPL-2.0-only license_family: GPL - size: 1484810 - timestamp: 1707086025982 + size: 1488739 + timestamp: 1710151570589 - kind: conda name: poppler - version: 24.02.0 + version: 24.03.0 build: hc2f3c52_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/poppler-24.02.0-hc2f3c52_0.conda - sha256: 21e97633c56c9c1330433cfb20d12609a5f419ebe33474480f1b4c32048b298f - md5: e740f88adfd0b75e6233066f6cbd4d82 + url: https://conda.anaconda.org/conda-forge/win-64/poppler-24.03.0-hc2f3c52_0.conda + sha256: e3d51588c6c97c0fa03c905049d5b9af139faad8e40545d809af44eef0a43f16 + md5: 76d65f5a02e1ed1d914d8b7368e1a59e depends: - cairo >=1.18.0,<2.0a0 - freetype >=2.12.1,<3.0a0 - lcms2 >=2.16,<3.0a0 - libcurl >=8.5.0,<9.0a0 - - libglib >=2.78.3,<3.0a0 + - libglib >=2.78.4,<3.0a0 - libiconv >=1.17,<2.0a0 - libjpeg-turbo >=3.0.0,<4.0a0 - - libpng >=1.6.42,<1.7.0a0 + - libpng >=1.6.43,<1.7.0a0 - libtiff >=4.6.0,<4.7.0a0 - - libzlib >=1.2.13,<1.3.0a0 - - openjpeg >=2.5.0,<3.0a0 + - libzlib >=1.2.13,<2.0.0a0 + - openjpeg >=2.5.2,<3.0a0 - poppler-data - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 license: GPL-2.0-only license_family: GPL - size: 2214905 - timestamp: 1707086181845 + size: 2315178 + timestamp: 1710151582969 - kind: conda name: poppler-data version: 0.4.12 @@ -23692,7 +23381,7 @@ packages: - krb5 >=1.21.2,<1.22.0a0 - libpq 16.3 h4501773_0 - libxml2 >=2.12.6,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.3.0,<4.0a0 - readline >=8.2,<9.0a0 - tzcode @@ -23712,7 +23401,7 @@ packages: - krb5 >=1.21.2,<1.22.0a0 - libpq 16.3 hab9416b_0 - libxml2 >=2.12.6,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.3.0,<4.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 @@ -23733,7 +23422,7 @@ packages: - libgcc-ng >=12 - libpq 16.3 ha72fbe1_0 - libxml2 >=2.12.6,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.3.0,<4.0a0 - readline >=8.2,<9.0a0 - tzcode @@ -23754,7 +23443,7 @@ packages: - krb5 >=1.21.2,<1.22.0a0 - libpq 16.3 h7afe498_0 - libxml2 >=2.12.6,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.3.0,<4.0a0 - readline >=8.2,<9.0a0 - tzcode @@ -23866,39 +23555,39 @@ packages: timestamp: 1707932844383 - kind: conda name: prompt-toolkit - version: 3.0.42 + version: 3.0.47 build: pyha770c72_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.42-pyha770c72_0.conda - sha256: 58525b2a9305fb154b2b0d43a48b9a6495441b80e4fbea44f2a34a597d2cef16 - md5: 0bf64bf10eee21f46ac83c161917fa86 + url: https://conda.anaconda.org/conda-forge/noarch/prompt-toolkit-3.0.47-pyha770c72_0.conda + sha256: d93ac5853e398aaa10f0dd7addd64b411f94ace1f9104d619cd250e19a5ac5b4 + md5: 1247c861065d227781231950e14fe817 depends: - python >=3.7 - wcwidth constrains: - - prompt_toolkit 3.0.42 + - prompt_toolkit 3.0.47 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/prompt-toolkit - size: 270398 - timestamp: 1702399557137 + size: 270710 + timestamp: 1718048095491 - kind: conda name: prompt_toolkit - version: 3.0.42 + version: 3.0.47 build: hd8ed1ab_0 subdir: noarch noarch: generic - url: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.42-hd8ed1ab_0.conda - sha256: fd2185d501bf34cb4c121f2f5ade9157ac75e1644a9da81355c4c8f9c1b82d4d - md5: 85a2189ecd2fcdd86e92b2d4ea8fe461 + url: https://conda.anaconda.org/conda-forge/noarch/prompt_toolkit-3.0.47-hd8ed1ab_0.conda + sha256: 081ef6c9fbc280940c8d65683371795a8876cd4994b3fbdd0ccda7cc3ee87f74 + md5: 3e0c82ddcfe27eb4ae77f887cfd9f45b depends: - - prompt-toolkit >=3.0.42,<3.0.43.0a0 + - prompt-toolkit >=3.0.47,<3.0.48.0a0 license: BSD-3-Clause license_family: BSD - size: 6846 - timestamp: 1702399567048 + size: 6784 + timestamp: 1718048101184 - kind: conda name: psutil version: 5.9.8 @@ -24119,25 +23808,24 @@ packages: timestamp: 1696182807580 - kind: conda name: pulseaudio-client - version: '16.1' - build: hb77b528_5 - build_number: 5 + version: '17.0' + build: hb77b528_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-16.1-hb77b528_5.conda - sha256: 9981c70893d95c8cac02e7edd1a9af87f2c8745b772d529f08b7f9dafbe98606 - md5: ac902ff3c1c6d750dd0dfc93a974ab74 + url: https://conda.anaconda.org/conda-forge/linux-64/pulseaudio-client-17.0-hb77b528_0.conda + sha256: b27c0c8671bd95c205a61aeeac807c095b60bc76eb5021863f919036d7a964fc + md5: 07f45f1be1c25345faddb8db0de8039b depends: - dbus >=1.13.6,<2.0a0 - libgcc-ng >=12 - - libglib >=2.76.4,<3.0a0 + - libglib >=2.78.3,<3.0a0 - libsndfile >=1.2.2,<1.3.0a0 - - libsystemd0 >=254 + - libsystemd0 >=255 constrains: - - pulseaudio 16.1 *_5 + - pulseaudio 17.0 *_0 license: LGPL-2.1-or-later license_family: LGPL - size: 754844 - timestamp: 1693928953742 + size: 757633 + timestamp: 1705690081905 - kind: conda name: pure_eval version: 0.2.2 @@ -24252,87 +23940,135 @@ packages: - kind: conda name: pyarrow version: 15.0.2 - build: py311h05400ba_3_cpu + build: py311ha429d19_3_cpu build_number: 3 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/pyarrow-15.0.2-py311h05400ba_3_cpu.conda - sha256: c3c84cd40fc4d3ce668a0306cc44b9c0ec089001d4acc8f0b77df24826f0781b - md5: bb833251eda25bcdab86d6603b954189 - depends: - - libarrow 15.0.2 h45212c0_3_cpu - - libarrow-acero 15.0.2 h8681a6d_3_cpu - - libarrow-dataset 15.0.2 h8681a6d_3_cpu - - libarrow-flight 15.0.2 h83a3238_3_cpu - - libarrow-flight-sql 15.0.2 h21569af_3_cpu - - libarrow-gandiva 15.0.2 h05de715_3_cpu - - libarrow-substrait 15.0.2 hea7f8fd_3_cpu - - libparquet 15.0.2 h39135fc_3_cpu + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/pyarrow-15.0.2-py311ha429d19_3_cpu.conda + sha256: ef4a23e700bdc3139a1dcb24f601dfd29529d8f82df7e12469d24f9aa7d22e8f + md5: 6800d5312e1c3330ce13b4c61f85a5f9 + depends: + - __osx >=10.13 + - libarrow 15.0.2 h965e444_3_cpu + - libarrow-acero 15.0.2 ha0df490_3_cpu + - libarrow-dataset 15.0.2 ha0df490_3_cpu + - libarrow-flight 15.0.2 h41520de_3_cpu + - libarrow-flight-sql 15.0.2 hb2e0ddf_3_cpu + - libarrow-gandiva 15.0.2 h6ac0def_3_cpu + - libarrow-substrait 15.0.2 hb2e0ddf_3_cpu + - libcxx >=16 + - libparquet 15.0.2 h7cd3cfe_3_cpu - numpy >=1.23.5,<2.0a0 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 constrains: - apache-arrow-proc =*=cpu license: Apache-2.0 license_family: APACHE purls: - pkg:pypi/pyarrow - size: 3496285 - timestamp: 1712758767659 + size: 4048360 + timestamp: 1712759133092 - kind: conda name: pyarrow - version: 15.0.2 - build: py311h3003323_3_cpu - build_number: 3 + version: 16.1.0 + build: py311h3810d55_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/pyarrow-16.1.0-py311h3810d55_0.conda + sha256: bb5727c64460825835665fc3433225393b4f6c0cc58e86a5ee8f39b84ae18d8f + md5: d953fa2670e99adf027174e3a85adbc4 + depends: + - libarrow-acero 16.1.0.* + - libarrow-dataset 16.1.0.* + - libarrow-substrait 16.1.0.* + - libparquet 16.1.0.* + - numpy >=1.23.5,<2.0a0 + - pyarrow-core 16.1.0 *_0_* + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + license: Apache-2.0 + license_family: APACHE + size: 26944 + timestamp: 1716006819417 +- kind: conda + name: pyarrow + version: 16.1.0 + build: py311h781c19f_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/pyarrow-16.1.0-py311h781c19f_0.conda + sha256: 9783572d9a71f04a32f9c53e9dec5c7f38721efdd68e8263f05b4c65f890c7a7 + md5: bd1348ebc8a3f45a18f5e3f01483a628 + depends: + - libarrow-acero 16.1.0.* + - libarrow-dataset 16.1.0.* + - libarrow-substrait 16.1.0.* + - libparquet 16.1.0.* + - numpy >=1.23.5,<2.0a0 + - pyarrow-core 16.1.0 *_0_* + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + license: Apache-2.0 + license_family: APACHE + size: 26414 + timestamp: 1716005979005 +- kind: conda + name: pyarrow + version: 16.1.0 + build: py311hf3b2ce4_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/pyarrow-15.0.2-py311h3003323_3_cpu.conda - sha256: 7ab7a74e47b8e484f78524db8eaa35bada99cccc519b6a9c7db8f11f6c7b92c2 - md5: aa3e351cbf0660bd549367fe2e4167f2 + url: https://conda.anaconda.org/conda-forge/osx-arm64/pyarrow-16.1.0-py311hf3b2ce4_0.conda + sha256: e55323996114b6d9a4a8c4ef54432e1481fdee636ea233d9e14ced7b60d38a07 + md5: 646d3c9a0ec557eebf3c5a0f4e605652 depends: - - __osx >=11.0 - - libarrow 15.0.2 h3ee1d8f_3_cpu - - libarrow-acero 15.0.2 h3f3aa29_3_cpu - - libarrow-dataset 15.0.2 h3f3aa29_3_cpu - - libarrow-flight 15.0.2 h224147a_3_cpu - - libarrow-flight-sql 15.0.2 hb630850_3_cpu - - libarrow-gandiva 15.0.2 h5fa1bb3_3_cpu - - libarrow-substrait 15.0.2 hd92e347_3_cpu - - libcxx >=16 - - libparquet 15.0.2 h5304c63_3_cpu + - libarrow-acero 16.1.0.* + - libarrow-dataset 16.1.0.* + - libarrow-substrait 16.1.0.* + - libparquet 16.1.0.* + - numpy >=1.23.5,<2.0a0 + - pyarrow-core 16.1.0 *_0_* + - python >=3.11,<3.12.0a0 + - python_abi 3.11.* *_cp311 + license: Apache-2.0 + license_family: APACHE + size: 26575 + timestamp: 1716005857336 +- kind: conda + name: pyarrow-core + version: 16.1.0 + build: py311h65ac0bd_0_cpu + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/pyarrow-core-16.1.0-py311h65ac0bd_0_cpu.conda + sha256: d36869575d81f160f2a553ec8f29498f0a6e2c067147f2b6a9d201165299805b + md5: b6350200d9a20ceba784a19364a21bd7 + depends: + - libarrow 16.1.0.* *cpu + - libzlib >=1.2.13,<2.0.0a0 - numpy >=1.23.5,<2.0a0 - python >=3.11,<3.12.0a0 - - python >=3.11,<3.12.0a0 *_cpython - python_abi 3.11.* *_cp311 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 constrains: - apache-arrow-proc =*=cpu license: Apache-2.0 license_family: APACHE purls: - pkg:pypi/pyarrow - size: 3993214 - timestamp: 1712784398192 + size: 3332572 + timestamp: 1716006160822 - kind: conda - name: pyarrow - version: 15.0.2 - build: py311h78dcc79_3_cpu - build_number: 3 + name: pyarrow-core + version: 16.1.0 + build: py311h8e2c35d_0_cpu subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/pyarrow-15.0.2-py311h78dcc79_3_cpu.conda - sha256: b8c1a223d7128a0de33d11e5b50ffd903b8b7eba6575cee4196051734c7d013d - md5: 0121744fe01473fa63c484e16ba3119c + url: https://conda.anaconda.org/conda-forge/linux-64/pyarrow-core-16.1.0-py311h8e2c35d_0_cpu.conda + sha256: cb4db7a0295c46f422e59cdda9dfd4a27e8b8e389ba75b595d136cb9d3a296bb + md5: c50b8f4436f4fc7b599122d14225322b depends: - - libarrow 15.0.2 he70291f_3_cpu - - libarrow-acero 15.0.2 hac33072_3_cpu - - libarrow-dataset 15.0.2 hac33072_3_cpu - - libarrow-flight 15.0.2 hd42f311_3_cpu - - libarrow-flight-sql 15.0.2 h9241762_3_cpu - - libarrow-gandiva 15.0.2 hd4ab825_3_cpu - - libarrow-substrait 15.0.2 h9241762_3_cpu + - libarrow 16.1.0.* *cpu - libgcc-ng >=12 - - libparquet 15.0.2 h6a7eafb_3_cpu - libstdcxx-ng >=12 + - libzlib >=1.2.13,<2.0.0a0 - numpy >=1.23.5,<2.0a0 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 @@ -24342,30 +24078,24 @@ packages: license_family: APACHE purls: - pkg:pypi/pyarrow - size: 4561847 - timestamp: 1712757933938 + size: 4460858 + timestamp: 1716005429456 - kind: conda - name: pyarrow - version: 15.0.2 - build: py311ha429d19_3_cpu - build_number: 3 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/pyarrow-15.0.2-py311ha429d19_3_cpu.conda - sha256: ef4a23e700bdc3139a1dcb24f601dfd29529d8f82df7e12469d24f9aa7d22e8f - md5: 6800d5312e1c3330ce13b4c61f85a5f9 + name: pyarrow-core + version: 16.1.0 + build: py311hbc16ef1_0_cpu + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/pyarrow-core-16.1.0-py311hbc16ef1_0_cpu.conda + sha256: fe6a5f800f2dba7ba4770a423bb5e02855c323bf47614ba26fd413ff36a51a75 + md5: 392ced12d2f2b66ab31619aeb673100e depends: - - __osx >=10.13 - - libarrow 15.0.2 h965e444_3_cpu - - libarrow-acero 15.0.2 ha0df490_3_cpu - - libarrow-dataset 15.0.2 ha0df490_3_cpu - - libarrow-flight 15.0.2 h41520de_3_cpu - - libarrow-flight-sql 15.0.2 hb2e0ddf_3_cpu - - libarrow-gandiva 15.0.2 h6ac0def_3_cpu - - libarrow-substrait 15.0.2 hb2e0ddf_3_cpu + - __osx >=11.0 + - libarrow 16.1.0.* *cpu - libcxx >=16 - - libparquet 15.0.2 h7cd3cfe_3_cpu + - libzlib >=1.2.13,<2.0.0a0 - numpy >=1.23.5,<2.0a0 - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython - python_abi 3.11.* *_cp311 constrains: - apache-arrow-proc =*=cpu @@ -24373,8 +24103,8 @@ packages: license_family: APACHE purls: - pkg:pypi/pyarrow - size: 4048360 - timestamp: 1712759133092 + size: 3845002 + timestamp: 1716005782278 - kind: conda name: pyarrow-hotfix version: '0.6' @@ -24412,34 +24142,34 @@ packages: timestamp: 1711811634025 - kind: conda name: pydantic - version: 2.7.1 + version: 2.7.4 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.1-pyhd8ed1ab_0.conda - sha256: 176862eeca911df9e21a239a19cee1608f899f969e7bc3b3df1da63aaf97c42b - md5: f5dac044e2aaccf73b85053f6db360b5 + url: https://conda.anaconda.org/conda-forge/noarch/pydantic-2.7.4-pyhd8ed1ab_0.conda + sha256: 329de082dbf174fa7ce3136eb747edfb5c63eb7c77d789ae275040b17fc92471 + md5: 20ebbfbc8ce3fc9d1955e9fd31accbb1 depends: - annotated-types >=0.4.0 - - pydantic-core 2.18.2 + - pydantic-core 2.18.4 - python >=3.7 - typing-extensions >=4.6.1 license: MIT license_family: MIT purls: - pkg:pypi/pydantic - size: 282275 - timestamp: 1713905769522 + size: 281971 + timestamp: 1718228801146 - kind: conda name: pydantic-core - version: 2.18.2 - build: py311h2786eb7_0 + version: 2.18.4 + build: py311h295b1db_0 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.18.2-py311h2786eb7_0.conda - sha256: 4d248c3885923fd351c2e5550f24d5839939213980e6341de17fe34c5959fccb - md5: c8826b4af1d40b4f73879cacfbc38a21 + url: https://conda.anaconda.org/conda-forge/osx-64/pydantic-core-2.18.4-py311h295b1db_0.conda + sha256: 1fa07bf5f4f1f2685ee01de43c037800eb2fa4228e70a8dfac60b98912463565 + md5: 48eeeced53f0a9e3ccb95ff414714f9b depends: - - __osx >=10.12 + - __osx >=10.13 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 - typing-extensions >=4.6.0,!=4.7.0 @@ -24449,16 +24179,16 @@ packages: license_family: MIT purls: - pkg:pypi/pydantic-core - size: 1547397 - timestamp: 1713862554543 + size: 1557312 + timestamp: 1717463197623 - kind: conda name: pydantic-core - version: 2.18.2 + version: 2.18.4 build: py311h533ab2d_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.18.2-py311h533ab2d_0.conda - sha256: fe4f47005534f327b7ebc93c832d734096d582b7bb5ca45740e83d3f1704ebac - md5: 1234b7b8ac68b728d48df4a04cab7553 + url: https://conda.anaconda.org/conda-forge/win-64/pydantic-core-2.18.4-py311h533ab2d_0.conda + sha256: 675d5c219b68d82af3649564f12e882c49cfafc4a6cc394d3a3ee00f6d14a047 + md5: e91b2e309604559af562f15b19e39917 depends: - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 @@ -24470,58 +24200,58 @@ packages: license_family: MIT purls: - pkg:pypi/pydantic-core - size: 1573013 - timestamp: 1713862871656 + size: 1582834 + timestamp: 1717463897801 - kind: conda name: pydantic-core - version: 2.18.2 - build: py311h5d190b6_0 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.18.2-py311h5d190b6_0.conda - sha256: df7966a775e5ac77025f804dee9f29b2cd61958963c71b90266f4e40c098781f - md5: a3634cb616e56058c5d887e092dfa18d + version: 2.18.4 + build: py311h5ecf98a_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.18.4-py311h5ecf98a_0.conda + sha256: 2c34d272a1afe39afbf4713a7f96366a579cb628a0321159e3015695b1e54913 + md5: c4de9699f095e3049dc02bcf811497b7 depends: - - __osx >=11.0 + - libgcc-ng >=12 - python >=3.11,<3.12.0a0 - - python >=3.11,<3.12.0a0 *_cpython - python_abi 3.11.* *_cp311 - typing-extensions >=4.6.0,!=4.7.0 - constrains: - - __osx >=11.0 license: MIT license_family: MIT purls: - pkg:pypi/pydantic-core - size: 1446637 - timestamp: 1713862610908 + size: 1627888 + timestamp: 1717463101283 - kind: conda name: pydantic-core - version: 2.18.2 - build: py311h5ecf98a_0 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/pydantic-core-2.18.2-py311h5ecf98a_0.conda - sha256: 111af1d677aaff1b386090872c3009b8989941684af63605fd7700d2b1c99da9 - md5: 0935eb48085bd65556bb16488866bb47 + version: 2.18.4 + build: py311h98c6a39_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/pydantic-core-2.18.4-py311h98c6a39_0.conda + sha256: ca8342ba184e1e9ce1367c7225cbd837516b3d69381a17fc53c434bb2a2a1f0f + md5: d7a6b069772e61897ab8ade15d268dde depends: - - libgcc-ng >=12 + - __osx >=11.0 - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython - python_abi 3.11.* *_cp311 - typing-extensions >=4.6.0,!=4.7.0 + constrains: + - __osx >=11.0 license: MIT license_family: MIT purls: - pkg:pypi/pydantic-core - size: 1617503 - timestamp: 1713862117041 + size: 1455801 + timestamp: 1717463380397 - kind: conda name: pydata-sphinx-theme - version: 0.15.2 + version: 0.15.3 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.2-pyhd8ed1ab_0.conda - sha256: 7046e72770e549f8f22865be737f3f8d0f49f11a5894fe48ccf44611941dba5a - md5: ce99859070b0e17ccc63234ca58f3ed8 + url: https://conda.anaconda.org/conda-forge/noarch/pydata-sphinx-theme-0.15.3-pyhd8ed1ab_0.conda + sha256: dc62ab4cd50c52c497004d8726e97962f2ba691ab8c8fecf0ee965ffcca8bdf9 + md5: 55e445f4fcb07f2471fb0e1102d36488 depends: - accessible-pygments - babel @@ -24531,13 +24261,13 @@ packages: - pygments >=2.7 - python >=3.9 - sphinx >=5.0 - - typing-extensions + - typing_extensions license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/pydata-sphinx-theme - size: 1375728 - timestamp: 1705630287042 + size: 1393230 + timestamp: 1716986842844 - kind: conda name: pygments version: 2.18.0 @@ -25040,25 +24770,25 @@ packages: timestamp: 1711411153367 - kind: conda name: pytest-xdist - version: 3.5.0 + version: 3.6.1 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.5.0-pyhd8ed1ab_0.conda - sha256: 8dc1d422e48e5a80eb72e26ed0135bb4843cf508d3b1cb006c3257c8639784d1 - md5: d5f595da2daead898ca958ac62f0307b + url: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_0.conda + sha256: c9f27ed55352bee2c9f7cc2fdaf12b322ee280b1989d7e763b4540d4fe7ec995 + md5: b39568655c127a9c4a44d178ac99b6d0 depends: - - execnet >=1.1 - - pytest >=6.2.0 - - python >=3.7 + - execnet >=2.1 + - pytest >=7.0.0 + - python >=3.8 constrains: - psutil >=3.0 license: MIT license_family: MIT purls: - pkg:pypi/pytest-xdist - size: 36516 - timestamp: 1700593072448 + size: 38320 + timestamp: 1718138508765 - kind: conda name: python version: 3.10.12 @@ -25071,7 +24801,7 @@ packages: - bzip2 >=1.0.8,<2.0a0 - libffi >=3.4,<4.0a0 - libsqlite >=3.42.0,<4.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ncurses >=6.4,<7.0a0 - openssl >=3.1.1,<4.0a0 - readline >=8.2,<9.0a0 @@ -25095,7 +24825,7 @@ packages: - bzip2 >=1.0.8,<2.0a0 - libffi >=3.4,<4.0a0 - libsqlite >=3.42.0,<4.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.1.1,<4.0a0 - tk >=8.6.12,<8.7.0a0 - tzdata @@ -25119,7 +24849,7 @@ packages: - bzip2 >=1.0.8,<2.0a0 - libffi >=3.4,<4.0a0 - libsqlite >=3.42.0,<4.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ncurses >=6.4,<7.0a0 - openssl >=3.1.1,<4.0a0 - readline >=8.2,<9.0a0 @@ -25147,7 +24877,7 @@ packages: - libnsl >=2.0.0,<2.1.0a0 - libsqlite >=3.42.0,<4.0a0 - libuuid >=2.38.1,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ncurses >=6.4,<7.0a0 - openssl >=3.1.1,<4.0a0 - readline >=8.2,<9.0a0 @@ -25172,7 +24902,7 @@ packages: - bzip2 >=1.0.8,<2.0a0 - libffi >=3.4,<4.0a0 - libsqlite >=3.40.0,<4.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ncurses >=6.3,<7.0a0 - openssl >=3.0.7,<4.0a0 - readline >=8.1.2,<9.0a0 @@ -25196,7 +24926,7 @@ packages: - bzip2 >=1.0.8,<2.0a0 - libffi >=3.4.2,<3.5.0a0 - libsqlite >=3.39.4,<4.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.0.5,<4.0a0 - tk >=8.6.12,<8.7.0a0 - tzdata @@ -25225,7 +24955,7 @@ packages: - libnsl >=2.0.0,<2.1.0a0 - libsqlite >=3.40.0,<4.0a0 - libuuid >=2.32.1,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ncurses >=6.3,<7.0a0 - openssl >=3.0.7,<4.0a0 - readline >=8.1.2,<9.0a0 @@ -25250,7 +24980,7 @@ packages: - bzip2 >=1.0.8,<2.0a0 - libffi >=3.4,<4.0a0 - libsqlite >=3.40.0,<4.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ncurses >=6.3,<7.0a0 - openssl >=3.0.7,<4.0a0 - readline >=8.1.2,<9.0a0 @@ -25275,7 +25005,7 @@ packages: - libexpat >=2.5.0,<3.0a0 - libffi >=3.4,<4.0a0 - libsqlite >=3.43.0,<4.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - openssl >=3.1.3,<4.0a0 - tk >=8.6.13,<8.7.0a0 - tzdata @@ -25301,7 +25031,7 @@ packages: - libexpat >=2.5.0,<3.0a0 - libffi >=3.4,<4.0a0 - libsqlite >=3.43.0,<4.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ncurses >=6.4,<7.0a0 - openssl >=3.1.3,<4.0a0 - readline >=8.2,<9.0a0 @@ -25326,7 +25056,7 @@ packages: - libexpat >=2.5.0,<3.0a0 - libffi >=3.4,<4.0a0 - libsqlite >=3.43.0,<4.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ncurses >=6.4,<7.0a0 - openssl >=3.1.3,<4.0a0 - readline >=8.2,<9.0a0 @@ -25355,7 +25085,7 @@ packages: - libnsl >=2.0.0,<2.1.0a0 - libsqlite >=3.43.0,<4.0a0 - libuuid >=2.38.1,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ncurses >=6.4,<7.0a0 - openssl >=3.1.3,<4.0a0 - readline >=8.2,<9.0a0 @@ -25387,21 +25117,21 @@ packages: timestamp: 1709299922152 - kind: conda name: python-fastjsonschema - version: 2.19.1 + version: 2.20.0 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.19.1-pyhd8ed1ab_0.conda - sha256: 38b2db169d65cc5595e3ce63294c4fdb6a242ecf71f70b3ad8cad3bd4230d82f - md5: 4d3ceee3af4b0f9a1f48f57176bf8625 + url: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.20.0-pyhd8ed1ab_0.conda + sha256: 7d8c931b89c9980434986b4deb22c2917b58d9936c3974139b9c10ae86fdfe60 + md5: b98d2018c01ce9980c03ee2850690fab depends: - python >=3.3 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/fastjsonschema - size: 225250 - timestamp: 1703781171097 + size: 226165 + timestamp: 1718477110630 - kind: conda name: python-gmsh version: 4.12.2 @@ -25550,13 +25280,13 @@ packages: timestamp: 1706886944988 - kind: conda name: pyvista - version: 0.43.8 + version: 0.43.9 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/pyvista-0.43.8-pyhd8ed1ab_0.conda - sha256: 3a7be5272e834bbf7248dbabe2c42bac4f2cc1821b04c569f43dce237b97b29f - md5: e0c5b99bd2a16284f55322d0fb28cb39 + url: https://conda.anaconda.org/conda-forge/noarch/pyvista-0.43.9-pyhd8ed1ab_0.conda + sha256: 0e4accf84c583009a50fdb855fce5de752b3f7ae465f04dd03e90c0bafd14d3d + md5: d17dc5575e9ec3d935981ded58ebba46 depends: - matplotlib-base >=3.0.1 - numpy @@ -25569,8 +25299,8 @@ packages: license_family: MIT purls: - pkg:pypi/pyvista - size: 1675864 - timestamp: 1715698441081 + size: 1678233 + timestamp: 1717661476179 - kind: conda name: pywin32 version: '306' @@ -25820,7 +25550,7 @@ packages: - libpng >=1.6.42,<1.7.0a0 - libpq >=16.2,<17.0a0 - libsqlite >=3.45.1,<4.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - mysql-libs >=8.0.33,<8.1.0a0 - nspr >=4.35,<5.0a0 - nss >=3.97,<4.0a0 @@ -25835,45 +25565,46 @@ packages: - kind: conda name: qt-main version: 5.15.8 - build: h5810be5_19 - build_number: 19 + build: hc9dc06e_21 + build_number: 21 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.8-h5810be5_19.conda - sha256: 41228ec12346d640ef1f549885d8438e98b1be0fdeb68cd1dd3938f255cbd719 - md5: 54866f708d43002a514d0b9b0f84bc11 + url: https://conda.anaconda.org/conda-forge/linux-64/qt-main-5.15.8-hc9dc06e_21.conda + sha256: 6b4594f6f2fad65a7ed52993f602e3ab183193755fe4a492aaa48e463b23105b + md5: b325046180590c868ce0dbf267b82eb8 depends: - __glibc >=2.17,<3.0.a0 - - alsa-lib >=1.2.10,<1.3.0.0a0 + - alsa-lib >=1.2.11,<1.3.0a0 - dbus >=1.13.6,<2.0a0 - fontconfig >=2.14.2,<3.0a0 - fonts-conda-ecosystem - freetype >=2.12.1,<3.0a0 - - gst-plugins-base >=1.22.9,<1.23.0a0 - - gstreamer >=1.22.9,<1.23.0a0 + - gst-plugins-base >=1.24.1,<1.25.0a0 + - gstreamer >=1.24.1,<1.25.0a0 - harfbuzz >=8.3.0,<9.0a0 - icu >=73.2,<74.0a0 - krb5 >=1.21.2,<1.22.0a0 - - libclang >=15.0.7,<16.0a0 + - libclang-cpp15 >=15.0.7,<15.1.0a0 - libclang13 >=15.0.7 - libcups >=2.3.3,<2.4.0a0 - libevent >=2.1.12,<2.1.13.0a0 - - libexpat >=2.5.0,<3.0a0 + - libexpat >=2.6.2,<3.0a0 - libgcc-ng >=12 - - libglib >=2.78.3,<3.0a0 + - libglib >=2.80.0,<3.0a0 - libjpeg-turbo >=3.0.0,<4.0a0 - - libpng >=1.6.42,<1.7.0a0 + - libllvm15 >=15.0.7,<15.1.0a0 + - libpng >=1.6.43,<1.7.0a0 - libpq >=16.2,<17.0a0 - - libsqlite >=3.45.1,<4.0a0 + - libsqlite >=3.45.2,<4.0a0 - libstdcxx-ng >=12 - libxcb >=1.15,<1.16.0a0 - - libxkbcommon >=1.6.0,<2.0a0 - - libxml2 >=2.12.5,<3.0a0 - - libzlib >=1.2.13,<1.3.0a0 - - mysql-libs >=8.0.33,<8.1.0a0 + - libxkbcommon >=1.7.0,<2.0a0 + - libxml2 >=2.12.6,<3.0a0 + - libzlib >=1.2.13,<2.0.0a0 + - mysql-libs >=8.3.0,<8.4.0a0 - nspr >=4.35,<5.0a0 - - nss >=3.97,<4.0a0 + - nss >=3.98,<4.0a0 - openssl >=3.2.1,<4.0a0 - - pulseaudio-client >=16.1,<16.2.0a0 + - pulseaudio-client >=17.0,<17.1.0a0 - xcb-util >=0.4.0,<0.5.0a0 - xcb-util-image >=0.4.0,<0.5.0a0 - xcb-util-keysyms >=0.4.0,<0.5.0a0 @@ -25881,7 +25612,7 @@ packages: - xcb-util-wm >=0.4.1,<0.5.0a0 - xorg-libice >=1.1.1,<2.0a0 - xorg-libsm >=1.2.4,<2.0a0 - - xorg-libx11 >=1.8.7,<2.0a0 + - xorg-libx11 >=1.8.9,<2.0a0 - xorg-libxext >=1.3.4,<2.0a0 - xorg-xf86vidmodeproto - zstd >=1.5.5,<1.6.0a0 @@ -25889,73 +25620,174 @@ packages: - qt 5.15.8 license: LGPL-3.0-only license_family: LGPL - size: 61337596 - timestamp: 1707958161584 + size: 61305384 + timestamp: 1712549380352 - kind: conda name: qt-main version: 5.15.8 - build: h6bf1bb6_19 - build_number: 19 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/qt-main-5.15.8-h6bf1bb6_19.conda - sha256: 11774126630e5816bb0725231f0915f3b303bc2fe54844190f5b4d7f5a02a265 - md5: 9abd8726afab7f8e7709f45a444c4844 + build: hcef0176_21 + build_number: 21 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/qt-main-5.15.8-hcef0176_21.conda + sha256: 7eb717efea95fb0f8384f7c59b709dbe3c7a2c1fabca60c8792760211c430251 + md5: 76544d3dfeff8fd52250df168cb0005b depends: - - gst-plugins-base >=1.22.9,<1.23.0a0 - - gstreamer >=1.22.9,<1.23.0a0 + - gst-plugins-base >=1.24.1,<1.25.0a0 + - gstreamer >=1.24.1,<1.25.0a0 - icu >=73.2,<74.0a0 - krb5 >=1.21.2,<1.22.0a0 - - libclang >=15.0.7,<16.0a0 - libclang13 >=15.0.7 - - libcxx >=14 - - libglib >=2.78.3,<3.0a0 + - libglib >=2.80.0,<3.0a0 - libjpeg-turbo >=3.0.0,<4.0a0 - - libpng >=1.6.42,<1.7.0a0 - - libpq >=16.2,<17.0a0 - - libsqlite >=3.45.1,<4.0a0 - - libzlib >=1.2.13,<1.3.0a0 - - mysql-libs >=8.0.33,<8.1.0a0 - - nspr >=4.35,<5.0a0 - - nss >=3.97,<4.0a0 + - libpng >=1.6.43,<1.7.0a0 + - libsqlite >=3.45.2,<4.0a0 + - libzlib >=1.2.13,<2.0.0a0 + - openssl >=3.2.1,<4.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 - zstd >=1.5.5,<1.6.0a0 constrains: - qt 5.15.8 license: LGPL-3.0-only license_family: LGPL - size: 51329823 - timestamp: 1707961383220 + size: 59806644 + timestamp: 1712551057454 - kind: conda - name: qt-main - version: 5.15.8 - build: h9e85ed6_19 - build_number: 19 + name: qt6-main + version: 6.7.1 + build: h2471661_2 + build_number: 2 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/qt6-main-6.7.1-h2471661_2.conda + sha256: a23a1e81eee7a1fbabc3ce682ba349de6c4d694178252d1cd96f2f300099325c + md5: ae062fb9d42d41102416a4a7e4adf3d2 + depends: + - __glibc >=2.17,<3.0.a0 + - alsa-lib >=1.2.11,<1.3.0a0 + - dbus >=1.13.6,<2.0a0 + - double-conversion >=3.3.0,<3.4.0a0 + - fontconfig >=2.14.2,<3.0a0 + - fonts-conda-ecosystem + - freetype >=2.12.1,<3.0a0 + - gst-plugins-base >=1.24.4,<1.25.0a0 + - gstreamer >=1.24.4,<1.25.0a0 + - harfbuzz >=8.5.0,<9.0a0 + - icu >=73.2,<74.0a0 + - krb5 >=1.21.2,<1.22.0a0 + - libclang-cpp18.1 >=18.1.6,<18.2.0a0 + - libclang13 >=18.1.6 + - libcups >=2.3.3,<2.4.0a0 + - libdrm >=2.4.120,<2.5.0a0 + - libgcc-ng >=12 + - libglib >=2.80.2,<3.0a0 + - libjpeg-turbo >=3.0.0,<4.0a0 + - libllvm18 >=18.1.6,<18.2.0a0 + - libpng >=1.6.43,<1.7.0a0 + - libpq >=16.3,<17.0a0 + - libsqlite >=3.45.3,<4.0a0 + - libstdcxx-ng >=12 + - libtiff >=4.6.0,<4.7.0a0 + - libwebp-base >=1.4.0,<2.0a0 + - libxcb >=1.15,<1.16.0a0 + - libxkbcommon >=1.7.0,<2.0a0 + - libxml2 >=2.12.7,<3.0a0 + - libzlib >=1.2.13,<2.0a0 + - mysql-libs >=8.3.0,<8.4.0a0 + - openssl >=3.3.0,<4.0a0 + - pcre2 >=10.43,<10.44.0a0 + - pulseaudio-client >=17.0,<17.1.0a0 + - wayland >=1.22.0,<2.0a0 + - xcb-util >=0.4.0,<0.5.0a0 + - xcb-util-cursor >=0.1.4,<0.2.0a0 + - xcb-util-image >=0.4.0,<0.5.0a0 + - xcb-util-keysyms >=0.4.0,<0.5.0a0 + - xcb-util-renderutil >=0.3.9,<0.4.0a0 + - xcb-util-wm >=0.4.1,<0.5.0a0 + - xorg-libice >=1.1.1,<2.0a0 + - xorg-libsm >=1.2.4,<2.0a0 + - xorg-libx11 >=1.8.9,<2.0a0 + - xorg-libxext >=1.3.4,<2.0a0 + - zstd >=1.5.6,<1.6.0a0 + constrains: + - qt 6.7.1 + license: LGPL-3.0-only + license_family: LGPL + size: 54851799 + timestamp: 1717049062342 +- kind: conda + name: qt6-main + version: 6.7.1 + build: h845717a_2 + build_number: 2 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/qt6-main-6.7.1-h845717a_2.conda + sha256: da8a9f45df68af0375005ec436f88224dbd2aa2214c1b47e7d57f915ea51d970 + md5: 9fac1875f08258e5476ab7ec18962668 + depends: + - __osx >=11.0 + - double-conversion >=3.3.0,<3.4.0a0 + - gst-plugins-base >=1.24.4,<1.25.0a0 + - gstreamer >=1.24.4,<1.25.0a0 + - harfbuzz >=8.5.0,<9.0a0 + - icu >=73.2,<74.0a0 + - krb5 >=1.21.2,<1.22.0a0 + - libclang-cpp16 >=16.0.6,<16.1.0a0 + - libclang13 >=16.0.6 + - libcxx >=16 + - libglib >=2.80.2,<3.0a0 + - libjpeg-turbo >=3.0.0,<4.0a0 + - libllvm16 >=16.0.6,<16.1.0a0 + - libpng >=1.6.43,<1.7.0a0 + - libpq >=16.3,<17.0a0 + - libsqlite >=3.45.3,<4.0a0 + - libtiff >=4.6.0,<4.7.0a0 + - libwebp-base >=1.4.0,<2.0a0 + - libzlib >=1.2.13,<2.0a0 + - mysql-libs >=8.3.0,<8.4.0a0 + - openssl >=3.3.0,<4.0a0 + - pcre2 >=10.43,<10.44.0a0 + - zstd >=1.5.6,<1.6.0a0 + constrains: + - qt 6.7.1 + license: LGPL-3.0-only + license_family: LGPL + size: 43991060 + timestamp: 1717052108766 +- kind: conda + name: qt6-main + version: 6.7.1 + build: h9e9f2d0_2 + build_number: 2 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/qt-main-5.15.8-h9e85ed6_19.conda - sha256: a132554a24f0617f54668479a29d9af80a2235653b08a4ebd200dcd30da971a8 - md5: 1e5fa5b05768a8eed9d8bb0bf5585b1f + url: https://conda.anaconda.org/conda-forge/win-64/qt6-main-6.7.1-h9e9f2d0_2.conda + sha256: 0d30210ac7c5a65039182e30d0ac325790bc5d805c1cc738c430aaaa3e6d611b + md5: 796cd980ad4dcbaf453359095fbfaf4d depends: - - gst-plugins-base >=1.22.9,<1.23.0a0 - - gstreamer >=1.22.9,<1.23.0a0 + - double-conversion >=3.3.0,<3.4.0a0 + - harfbuzz >=8.5.0,<9.0a0 - icu >=73.2,<74.0a0 - krb5 >=1.21.2,<1.22.0a0 - - libclang >=15.0.7,<16.0a0 - - libclang13 >=15.0.7 - - libglib >=2.78.3,<3.0a0 + - libclang13 >=18.1.6 + - libglib >=2.80.2,<3.0a0 - libjpeg-turbo >=3.0.0,<4.0a0 - - libpng >=1.6.42,<1.7.0a0 - - libsqlite >=3.45.1,<4.0a0 - - libzlib >=1.2.13,<1.3.0a0 - - openssl >=3.2.1,<4.0a0 + - libpng >=1.6.43,<1.7.0a0 + - libsqlite >=3.45.3,<4.0a0 + - libtiff >=4.6.0,<4.7.0a0 + - libwebp-base >=1.4.0,<2.0a0 + - libzlib >=1.2.13,<2.0a0 + - openssl >=3.3.0,<4.0a0 + - pcre2 >=10.43,<10.44.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 - - zstd >=1.5.5,<1.6.0a0 + - zstd >=1.5.6,<1.6.0a0 constrains: - - qt 5.15.8 + - qt 6.7.1 license: LGPL-3.0-only license_family: LGPL - size: 60081554 - timestamp: 1707957968211 + size: 96856289 + timestamp: 1717051638553 - kind: conda name: qtconsole-base version: 5.5.2 @@ -26188,23 +26020,6 @@ packages: - pkg:pypi/rasterio size: 7174788 timestamp: 1702441227310 -- kind: conda - name: rdma-core - version: '51.0' - build: hd3aeb46_0 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/rdma-core-51.0-hd3aeb46_0.conda - sha256: bcc774b60605b09701cfad41b2d6d9c3f052dd4adfc1f02bf1c929076f48fe30 - md5: 493598e1f28c01e316fda127715593aa - depends: - - __glibc >=2.17,<3.0.a0 - - libgcc-ng >=12 - - libnl >=3.9.0,<4.0a0 - - libstdcxx-ng >=12 - license: Linux-OpenIB - license_family: BSD - size: 4734659 - timestamp: 1711958296706 - kind: conda name: re2 version: 2023.09.01 @@ -26353,18 +26168,18 @@ packages: timestamp: 1714619625532 - kind: conda name: requests - version: 2.32.2 + version: 2.32.3 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.2-pyhd8ed1ab_0.conda - sha256: 115b796fddc846bee6f47e3c57d04d12fa93a47a7a8ef639cefdc05203c1bf00 - md5: e1643b34b19df8c028a4f00bf5df58a6 + url: https://conda.anaconda.org/conda-forge/noarch/requests-2.32.3-pyhd8ed1ab_0.conda + sha256: 5845ffe82a6fa4d437a2eae1e32a1ad308d7ad349f61e337c0a890fe04c513cc + md5: 5ede4753180c7a550a443c430dc8ab52 depends: - certifi >=2017.4.17 - charset-normalizer >=2,<4 - idna >=2.5,<4 - - python >=3.7 + - python >=3.8 - urllib3 >=1.21.1,<3 constrains: - chardet >=3.0.2,<6 @@ -26372,8 +26187,8 @@ packages: license_family: APACHE purls: - pkg:pypi/requests - size: 57885 - timestamp: 1716354575895 + size: 58810 + timestamp: 1717057174842 - kind: conda name: requests-toolbelt version: 1.0.0 @@ -26569,84 +26384,88 @@ packages: - kind: conda name: rtree version: 1.2.0 - build: py311h3bb2b0f_0 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/rtree-1.2.0-py311h3bb2b0f_0.conda - sha256: 1ebca72bb9683ec6e8acfc7d32de9fe23b2a714d9c5b197f8e342d7ff4399265 - md5: 6bbf9846cbb38ab4fd631357a3f4ede2 + build: py311h44d53c4_1 + build_number: 1 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/rtree-1.2.0-py311h44d53c4_1.conda + sha256: 78fecaad4f4b25ba60dc55af7fb5326d1b3512b8ed240eb45aabc1e86e50e77e + md5: a182e3a376af719a275136bfdbc3a70e depends: - - libspatialindex >=1.9.3,<1.9.4.0a0 + - libspatialindex >=2.0.0,<2.0.1.0a0 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 license: MIT license_family: MIT purls: - pkg:pypi/rtree - size: 63868 - timestamp: 1705698076612 + size: 63566 + timestamp: 1718099641772 - kind: conda name: rtree version: 1.2.0 - build: py311hbc1f44b_0 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/rtree-1.2.0-py311hbc1f44b_0.conda - sha256: b60dc5f1ff169cc7290be2364759a64a0dcc862804da856511e61761982efee3 - md5: 6cb743682b44e5b8fbaab3c9f430c5dd + build: py311h46a7578_1 + build_number: 1 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/rtree-1.2.0-py311h46a7578_1.conda + sha256: e9a104ff097088e39d5696dd2d379afac8820f446029eed79e44508cbe63d440 + md5: f3a0f0955a16876f1cbbb197c7b87e1b depends: - - libspatialindex >=1.9.3,<1.9.4.0a0 + - libspatialindex >=2.0.0,<2.0.1.0a0 - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython - python_abi 3.11.* *_cp311 license: MIT license_family: MIT purls: - pkg:pypi/rtree - size: 63708 - timestamp: 1705698312709 + size: 63532 + timestamp: 1718099560207 - kind: conda name: rtree version: 1.2.0 - build: py311hcacb13a_0 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/rtree-1.2.0-py311hcacb13a_0.conda - sha256: c449572e3db2b0daf5c3b426bb2ffa3b54baaeff08c6c84d5bce69964346e93a - md5: 43e6e9ac051d92d50296a3f10000da13 + build: py311h6785ca5_1 + build_number: 1 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/rtree-1.2.0-py311h6785ca5_1.conda + sha256: ddc278f720d51dccf73be6f3f570842246b90ecda6d567e53fb2d65fdc7fc6bc + md5: 083ab93aff19c6fb248a0b270e7eaad1 depends: - - libspatialindex >=1.9.3,<1.9.4.0a0 + - libspatialindex >=2.0.0,<2.0.1.0a0 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 license: MIT license_family: MIT purls: - pkg:pypi/rtree - size: 63643 - timestamp: 1705698251888 + size: 63318 + timestamp: 1718099451672 - kind: conda name: rtree version: 1.2.0 - build: py311hd698ff7_0 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/rtree-1.2.0-py311hd698ff7_0.conda - sha256: 1003759185a553652fbb6d5e0e4fb426abb85c6b588c25960eadae27d747a23b - md5: bdb16e41bd3a67e70a01879f27196be7 + build: py311ha1603b9_1 + build_number: 1 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/rtree-1.2.0-py311ha1603b9_1.conda + sha256: 9b9d5be1924ced85110f635331379354ba57d44c5416c5709070ddb111048ef6 + md5: 0737315cc9761f4060f9d52d12cea92e depends: - - libspatialindex >=1.9.3,<1.9.4.0a0 + - libspatialindex >=2.0.0,<2.0.1.0a0 - python >=3.11,<3.12.0a0 - - python >=3.11,<3.12.0a0 *_cpython - python_abi 3.11.* *_cp311 license: MIT license_family: MIT purls: - pkg:pypi/rtree - size: 63577 - timestamp: 1705698221128 + size: 63848 + timestamp: 1718099448786 - kind: conda name: ruff - version: 0.4.5 + version: 0.4.9 build: py311h9a97b26_0 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.4.5-py311h9a97b26_0.conda - sha256: 41a3f0fedb259e35b9a36a897d691272d1bae0ca7895779cfe5be66c301a703f - md5: 49c4fbc7dc7937c175a630a821662fd3 + url: https://conda.anaconda.org/conda-forge/osx-64/ruff-0.4.9-py311h9a97b26_0.conda + sha256: 602ac3bba622dda57f7ae58fbdf549c5ec566ad2fa165095289dec33640ed091 + md5: bc2c642e16d9e95a90dcc237fc5b5d82 depends: - __osx >=10.13 - libcxx >=16 @@ -26658,16 +26477,16 @@ packages: license_family: MIT purls: - pkg:pypi/ruff - size: 6157307 - timestamp: 1716663909398 + size: 6170351 + timestamp: 1718402177172 - kind: conda name: ruff - version: 0.4.5 + version: 0.4.9 build: py311ha637bb9_0 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/ruff-0.4.5-py311ha637bb9_0.conda - sha256: 6fbb33bd5f61c09dd65fc4b980d4cff4042c3645207fef6b94048ff90454bba6 - md5: 9fcf089b1b221784828f730ba94f6aa5 + url: https://conda.anaconda.org/conda-forge/win-64/ruff-0.4.9-py311ha637bb9_0.conda + sha256: 3b3cbe3f005f86a8e400c3ac1822a3bb82eaf3a61899015d2da40b47d8334cd0 + md5: 4b660bf499ffff4ddf379b5c4fc443e7 depends: - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 @@ -26678,16 +26497,16 @@ packages: license_family: MIT purls: - pkg:pypi/ruff - size: 6304897 - timestamp: 1716664840002 + size: 6298153 + timestamp: 1718403279477 - kind: conda name: ruff - version: 0.4.5 + version: 0.4.9 build: py311hae69bc3_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.4.5-py311hae69bc3_0.conda - sha256: 97cc0b3427c087390fd4280c2d23ced896766ae5addb6689fba949c678b365d8 - md5: d386545bc0cda284346ba0cb69d0beeb + url: https://conda.anaconda.org/conda-forge/linux-64/ruff-0.4.9-py311hae69bc3_0.conda + sha256: 45765e0262e9b9435b653467e7efc50831753e530db808468a95cfb5d211cd38 + md5: 97b1901b332439b6a3ba8c1ebee8e0ee depends: - libgcc-ng >=12 - libstdcxx-ng >=12 @@ -26697,16 +26516,16 @@ packages: license_family: MIT purls: - pkg:pypi/ruff - size: 6385504 - timestamp: 1716663699654 + size: 6383130 + timestamp: 1718401985491 - kind: conda name: ruff - version: 0.4.5 + version: 0.4.9 build: py311hd374d79_0 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.4.5-py311hd374d79_0.conda - sha256: 4a5b506c50d3cb2e23da83fb3c414e929a82062f425034531d6ac7572bd89f18 - md5: 64ee770a55753ed7e2b4630c481eb7f7 + url: https://conda.anaconda.org/conda-forge/osx-arm64/ruff-0.4.9-py311hd374d79_0.conda + sha256: edb688fcf874fda757e7034a55b21a7195a7b70fcddbbfb2acaeb3d0ca6446e4 + md5: 48cc00763083875f15a2cf4005ceefeb depends: - __osx >=11.0 - libcxx >=16 @@ -26719,23 +26538,23 @@ packages: license_family: MIT purls: - pkg:pypi/ruff - size: 5875862 - timestamp: 1716663891215 + size: 5879652 + timestamp: 1718402424223 - kind: conda name: s2n - version: 1.4.12 - build: h06160fa_0 + version: 1.4.13 + build: he19d79f_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/s2n-1.4.12-h06160fa_0.conda - sha256: fc5759c4d8136bb9048ed5cd2e8fd1a375104c3a7ec60fee1be0b06e7487d610 - md5: bf1899cfd6dea061a220fa7e96a1f4bd + url: https://conda.anaconda.org/conda-forge/linux-64/s2n-1.4.13-he19d79f_0.conda + sha256: a51daaf7d6affe149452b08a5cbc0568a0984306c558728050c56c48f8f11615 + md5: 51db7e9c0cd527aea7691e7405df33bf depends: - libgcc-ng >=12 - - openssl >=3.2.1,<4.0a0 + - openssl >=3.3.0,<4.0a0 license: Apache-2.0 license_family: Apache - size: 346689 - timestamp: 1713325107791 + size: 346686 + timestamp: 1714594242637 - kind: conda name: scikit-learn version: 1.5.0 @@ -27405,24 +27224,6 @@ packages: - pkg:pypi/soupsieve size: 36754 timestamp: 1693929424267 -- kind: conda - name: spdlog - version: 1.12.0 - build: h64d2f7d_2 - build_number: 2 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/spdlog-1.12.0-h64d2f7d_2.conda - sha256: 4b582768ebb9d234c0a9e0eae482733f167d53e316f0f48aac19a028a83a8570 - md5: e039fdff30fd25fbfc7cb91755d80a4f - depends: - - fmt >=10.1.1,<11.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: MIT - license_family: MIT - size: 160999 - timestamp: 1697421628776 - kind: conda name: spdlog version: 1.12.0 @@ -27442,38 +27243,52 @@ packages: timestamp: 1697421663869 - kind: conda name: spdlog - version: 1.12.0 - build: hd2e6256_2 - build_number: 2 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/spdlog-1.12.0-hd2e6256_2.conda - sha256: 34c2ac3ecafc109ea659087f2a429b8fd7c557eb75d072e723a9954472726e62 - md5: f37afc6ce10d45b9fae2f55ddc635b9f + version: 1.13.0 + build: h5fcca99_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/spdlog-1.13.0-h5fcca99_0.conda + sha256: 161ad4bb6de140ca00024dd5004b4ab99189767df7f83362d6c252c03213e29a + md5: 1907a70a6494b95f3961417e7a9564d2 depends: - - fmt >=10.1.1,<11.0a0 - - libgcc-ng >=12 - - libstdcxx-ng >=12 + - fmt >=10.2.1,<11.0a0 + - libcxx >=16 license: MIT license_family: MIT - size: 187863 - timestamp: 1697421353980 + size: 156731 + timestamp: 1713902551224 - kind: conda name: spdlog - version: 1.12.0 - build: he64bfa9_2 - build_number: 2 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/spdlog-1.12.0-he64bfa9_2.conda - sha256: 504a85024b9506de38801250a43da5360b8de87364b9bc4b70777ee9cc830429 - md5: ef84dce6d582965c3fc1e4a52ba51114 + version: 1.13.0 + build: h64d2f7d_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/spdlog-1.13.0-h64d2f7d_0.conda + sha256: 7c5c8d6e2df300f7887e5488a21b11d854ffbc51a1b149af4164d6cbd225fd7a + md5: e21d3d1aef3973f78ee161bb053c5922 depends: - - __osx >=10.9 - - fmt >=10.1.1,<11.0a0 - - libcxx >=16.0.6 + - fmt >=10.2.1,<11.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 + license: MIT + license_family: MIT + size: 161230 + timestamp: 1713902489730 +- kind: conda + name: spdlog + version: 1.13.0 + build: hd2e6256_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/spdlog-1.13.0-hd2e6256_0.conda + sha256: 2027b971e83a9c9d292c12880269fe08e782fe9b15b93b5a3ddc8697116e6750 + md5: 18f9348f064632785d54dbd1db9344bb + depends: + - fmt >=10.2.1,<11.0a0 + - libgcc-ng >=12 + - libstdcxx-ng >=12 license: MIT license_family: MIT - size: 156560 - timestamp: 1697421775628 + size: 188328 + timestamp: 1713902039030 - kind: conda name: sphinx version: 5.0.0 @@ -27637,69 +27452,71 @@ packages: timestamp: 1705118378942 - kind: conda name: sqlite - version: 3.45.3 - build: h2c6b66d_0 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.45.3-h2c6b66d_0.conda - sha256: 945ac702e2bd8cc59cc780dfc37c18255d5e538c8433dc290c0edbad2bcbaeb4 - md5: be7d70f2db41b674733667bdd69bd000 + version: 3.46.0 + build: h2466b09_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/sqlite-3.46.0-h2466b09_0.conda + sha256: 204edea00bb813d1e3da31dcd8caf1cb355ded08be3065ca53dea066bf75b827 + md5: f60e557d64002fe9955b929226adf81d depends: - - libgcc-ng >=12 - - libsqlite 3.45.3 h2797004_0 - - libzlib >=1.2.13,<1.3.0a0 - - ncurses >=6.4.20240210,<7.0a0 - - readline >=8.2,<9.0a0 + - libsqlite 3.46.0 h2466b09_0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: Unlicense - size: 848611 - timestamp: 1713367461306 + size: 885699 + timestamp: 1718051144579 - kind: conda name: sqlite - version: 3.45.3 - build: h7461747_0 + version: 3.46.0 + build: h28673e1_0 subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/sqlite-3.45.3-h7461747_0.conda - sha256: 73ab284ff41dd6aeb69f7a8a014018fbf8b019fd261ff4190fd5813b62d07b16 - md5: 4d9a56087e6150e84b94087a8c0fdf98 + url: https://conda.anaconda.org/conda-forge/osx-64/sqlite-3.46.0-h28673e1_0.conda + sha256: 7d868d34348615450c43cb4737b44987a0e45fdf4759502b323494dc8c931409 + md5: b76e50276ebb3131cb84aac8123ca75d depends: - - libsqlite 3.45.3 h92b6c6a_0 - - libzlib >=1.2.13,<1.3.0a0 - - ncurses >=6.4.20240210,<7.0a0 + - __osx >=10.13 + - libsqlite 3.46.0 h1b8f9f3_0 + - libzlib >=1.2.13,<2.0a0 + - ncurses >=6.5,<7.0a0 - readline >=8.2,<9.0a0 license: Unlicense - size: 901246 - timestamp: 1713367827855 + size: 912413 + timestamp: 1718050767696 - kind: conda name: sqlite - version: 3.45.3 - build: hcfcfb64_0 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/sqlite-3.45.3-hcfcfb64_0.conda - sha256: 9815ad33780f8679d21507ffd6e12184da47eab7b945b2e5df35e8af686aafe6 - md5: ef090bf29a90a1371888385e405a3a6f + version: 3.46.0 + build: h5838104_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/sqlite-3.46.0-h5838104_0.conda + sha256: e13b719f70b3a20f40b59f814d32483ae8cd95fef83224127b10091828026f7d + md5: 05c5dc8cd793dcfc5849d0569da9b175 depends: - - libsqlite 3.45.3 hcfcfb64_0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - __osx >=11.0 + - libsqlite 3.46.0 hfb93653_0 + - libzlib >=1.2.13,<2.0a0 + - ncurses >=6.5,<7.0a0 + - readline >=8.2,<9.0a0 license: Unlicense - size: 872907 - timestamp: 1713367918283 + size: 822635 + timestamp: 1718050678797 - kind: conda name: sqlite - version: 3.45.3 - build: hf2abe2d_0 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/sqlite-3.45.3-hf2abe2d_0.conda - sha256: 1d618ce2622e2e976f8f28ede2f14ae20f19f64eda706d9eda6419393c48015a - md5: 95ba63aee059cdfc10b7e3ee1dd4c15d + version: 3.46.0 + build: h6d4b2fc_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/sqlite-3.46.0-h6d4b2fc_0.conda + sha256: e849d576e52bf3e6fc5786f89b7d76978f2e2438587826c95570324cb572e52b + md5: 77ea8dff5cf8550cc8f5629a6af56323 depends: - - libsqlite 3.45.3 h091b4b1_0 - - libzlib >=1.2.13,<1.3.0a0 - - ncurses >=6.4.20240210,<7.0a0 + - libgcc-ng >=12 + - libsqlite 3.46.0 hde9e2c9_0 + - libzlib >=1.2.13,<2.0a0 + - ncurses >=6.5,<7.0a0 - readline >=8.2,<9.0a0 license: Unlicense - size: 812413 - timestamp: 1713367802027 + size: 860352 + timestamp: 1718050658212 - kind: conda name: stack_data version: 0.6.2 @@ -27723,62 +27540,63 @@ packages: - kind: conda name: svt-av1 version: 2.0.0 - build: h078ce10_0 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/svt-av1-2.0.0-h078ce10_0.conda - sha256: 9d5cb5e3ee41849d60de4997a83efaad2aaaa4d92782f5a8f293931bb3fc4b37 - md5: 9da0cd60486e8037b546f48dfdf00b71 + build: h73e2aa4_0 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/svt-av1-2.0.0-h73e2aa4_0.conda + sha256: 51414c2e9b9f26b71a94037e3969dbfa9f65a2feaf31b7fb0d9905b5fef0e56e + md5: 5eaa877d08099311d615c23a4549482d depends: - libcxx >=16 license: BSD-2-Clause license_family: BSD - size: 1415570 - timestamp: 1710374533383 + size: 2362393 + timestamp: 1710374582341 - kind: conda name: svt-av1 - version: 2.0.0 - build: h59595ed_0 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/svt-av1-2.0.0-h59595ed_0.conda - sha256: eee484177184c7876d258917ab3f209396e6fc59e9bf3603a3ebf1ce8b39df80 - md5: 207e01ffa0eb2d2efb83fb6f46365a21 + version: 2.1.0 + build: h7bae524_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/svt-av1-2.1.0-h7bae524_0.conda + sha256: 7982cf86eecccf7de0de591e7857d791ef4867c8c84175ccd16987a9a78b91d0 + md5: 8e29314734631f000cd98882b9bc3045 depends: - - libgcc-ng >=12 - - libstdcxx-ng >=12 + - __osx >=11.0 + - libcxx >=16 license: BSD-2-Clause license_family: BSD - size: 2633794 - timestamp: 1710374004661 + size: 1466326 + timestamp: 1716038247187 - kind: conda name: svt-av1 - version: 2.0.0 - build: h63175ca_0 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/svt-av1-2.0.0-h63175ca_0.conda - sha256: 0ece693f79e90819958e9e265b2b19409f36b4434aa132a58c993264a927d029 - md5: b3c5c51269efb1bc04502c6231506707 + version: 2.1.0 + build: hac33072_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/svt-av1-2.1.0-hac33072_0.conda + sha256: 7c2f1bb1e84c16aaa76f0d73acab7f6a6aec839c120229ac340e24b47a3db595 + md5: 2a08edb7cd75e56623f2712292a97325 depends: - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 - license: BSD-2-Clause - license_family: BSD - size: 2354231 - timestamp: 1710374384723 -- kind: conda - name: svt-av1 - version: 2.0.0 - build: h73e2aa4_0 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/svt-av1-2.0.0-h73e2aa4_0.conda - sha256: 51414c2e9b9f26b71a94037e3969dbfa9f65a2feaf31b7fb0d9905b5fef0e56e - md5: 5eaa877d08099311d615c23a4549482d + - libgcc-ng >=12 + - libstdcxx-ng >=12 + license: BSD-2-Clause + license_family: BSD + size: 2624396 + timestamp: 1716038239983 +- kind: conda + name: svt-av1 + version: 2.1.0 + build: he0c23c2_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/svt-av1-2.1.0-he0c23c2_0.conda + sha256: b56496d367ac8c694fced207bef70811f771a3ae5abfbd4929d4bf78b52fe917 + md5: 8927443e23db102a96493ee711e6b6b6 depends: - - libcxx >=16 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: BSD-2-Clause license_family: BSD - size: 2362393 - timestamp: 1710374582341 + size: 1954423 + timestamp: 1716038937984 - kind: conda name: tbb version: 2021.12.0 @@ -28027,7 +27845,7 @@ packages: - libcxx >=16 - libgoogle-cloud >=2.22.0,<2.23.0a0 - libgoogle-cloud-storage >=2.22.0,<2.23.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - openssl >=3.2.1,<4.0a0 - spdlog >=1.12.0,<1.13.0a0 @@ -28038,15 +27856,15 @@ packages: timestamp: 1712695191605 - kind: conda name: tiledb - version: 2.20.1 - build: hc9ddcec_7 - build_number: 7 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/tiledb-2.20.1-hc9ddcec_7.conda - sha256: c0eb2fa8be70fe826f1d7291a4f8b064bd00a790019ab4e8ec6cd2068f64e8e1 - md5: dc7608edd746f60604844c0af81a4165 + version: 2.21.2 + build: h27f064a_4 + build_number: 4 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/tiledb-2.21.2-h27f064a_4.conda + sha256: 953ea1e042c0af50fd73de62da30226e9193923a5f61159280a97a1b55f8ce43 + md5: d97cf4e89c7baa63ecf8906d1a0b6ee0 depends: - - aws-crt-cpp >=0.26.6,<0.26.7.0a0 + - aws-crt-cpp >=0.26.8,<0.26.9.0a0 - aws-sdk-cpp >=1.11.267,<1.11.268.0a0 - azure-core-cpp >=1.11.1,<1.11.2.0a0 - azure-storage-blobs-cpp >=12.10.0,<12.10.1.0a0 @@ -28055,34 +27873,33 @@ packages: - fmt >=10.2.1,<11.0a0 - libabseil * cxx17* - libabseil >=20240116.1,<20240117.0a0 - - libcrc32c >=1.1.2,<1.2.0a0 - libcurl >=8.7.1,<9.0a0 - - libgoogle-cloud >=2.22.0,<2.23.0a0 - - libgoogle-cloud-storage >=2.22.0,<2.23.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libgcc-ng >=12 + - libgoogle-cloud >=2.23.0,<2.24.0a0 + - libgoogle-cloud-storage >=2.23.0,<2.24.0a0 + - libstdcxx-ng >=12 + - libwebp-base >=1.4.0,<2.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - openssl >=3.2.1,<4.0a0 - - spdlog >=1.12.0,<1.13.0a0 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - spdlog >=1.13.0,<1.14.0a0 - zstd >=1.5.5,<1.6.0a0 license: MIT license_family: MIT - size: 3289289 - timestamp: 1712694792602 + size: 4353684 + timestamp: 1714059301627 - kind: conda name: tiledb - version: 2.20.1 - build: hca4efeb_7 - build_number: 7 + version: 2.21.2 + build: hf0716ca_4 + build_number: 4 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/tiledb-2.20.1-hca4efeb_7.conda - sha256: 6ed49564814ea1f634a5100681635bb167311d16c9e43dbd273cdf88db62773b - md5: d1054085da33daaaedf13b18178e24ee + url: https://conda.anaconda.org/conda-forge/osx-arm64/tiledb-2.21.2-hf0716ca_4.conda + sha256: 4069b6c5b889f4bc87fd4bf22ec31d9292c6c9d2bba1e55ef94ab1158d4fd074 + md5: 9e4bfcd3ebbb5ac622f9d74779ec6460 depends: - __osx >=11.0 - - aws-crt-cpp >=0.26.6,<0.26.7.0a0 + - aws-crt-cpp >=0.26.8,<0.26.9.0a0 - aws-sdk-cpp >=1.11.267,<1.11.268.0a0 - azure-core-cpp >=1.11.1,<1.11.2.0a0 - azure-storage-blobs-cpp >=12.10.0,<12.10.1.0a0 @@ -28093,28 +27910,29 @@ packages: - libabseil >=20240116.1,<20240117.0a0 - libcurl >=8.7.1,<9.0a0 - libcxx >=16 - - libgoogle-cloud >=2.22.0,<2.23.0a0 - - libgoogle-cloud-storage >=2.22.0,<2.23.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libgoogle-cloud >=2.23.0,<2.24.0a0 + - libgoogle-cloud-storage >=2.23.0,<2.24.0a0 + - libwebp-base >=1.4.0,<2.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - openssl >=3.2.1,<4.0a0 - - spdlog >=1.12.0,<1.13.0a0 + - spdlog >=1.13.0,<1.14.0a0 - zstd >=1.5.5,<1.6.0a0 license: MIT license_family: MIT - size: 3657467 - timestamp: 1712695371604 + size: 3510294 + timestamp: 1714061155110 - kind: conda name: tiledb - version: 2.20.1 - build: hcf523ab_7 - build_number: 7 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/tiledb-2.20.1-hcf523ab_7.conda - sha256: 62a0ff9050cb000c624fc91b5a9052609305f600270d78e6ae248ada3b6b32c6 - md5: 8d1f428e88db4424d08c7a823fffa116 + version: 2.21.2 + build: hf39fa12_4 + build_number: 4 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/tiledb-2.21.2-hf39fa12_4.conda + sha256: 29573d57e4ac57210dad94d1499871e705d439d9a370416d24a344f85c152874 + md5: 17098a5abd703bb6d2a71a4d7d4576a7 depends: - - aws-crt-cpp >=0.26.6,<0.26.7.0a0 + - aws-crt-cpp >=0.26.8,<0.26.9.0a0 - aws-sdk-cpp >=1.11.267,<1.11.268.0a0 - azure-core-cpp >=1.11.1,<1.11.2.0a0 - azure-storage-blobs-cpp >=12.10.0,<12.10.1.0a0 @@ -28123,20 +27941,23 @@ packages: - fmt >=10.2.1,<11.0a0 - libabseil * cxx17* - libabseil >=20240116.1,<20240117.0a0 + - libcrc32c >=1.1.2,<1.2.0a0 - libcurl >=8.7.1,<9.0a0 - - libgcc-ng >=12 - - libgoogle-cloud >=2.22.0,<2.23.0a0 - - libgoogle-cloud-storage >=2.22.0,<2.23.0a0 - - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libgoogle-cloud >=2.23.0,<2.24.0a0 + - libgoogle-cloud-storage >=2.23.0,<2.24.0a0 + - libwebp-base >=1.4.0,<2.0a0 + - libzlib >=1.2.13,<2.0.0a0 - lz4-c >=1.9.3,<1.10.0a0 - openssl >=3.2.1,<4.0a0 - - spdlog >=1.12.0,<1.13.0a0 + - spdlog >=1.13.0,<1.14.0a0 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 - zstd >=1.5.5,<1.6.0a0 license: MIT license_family: MIT - size: 4589082 - timestamp: 1712694183883 + size: 3171041 + timestamp: 1714059720932 - kind: conda name: tinycss2 version: 1.3.0 @@ -28165,7 +27986,7 @@ packages: sha256: 30412b2e9de4ff82d8c2a7e5d06a15f4f4fef1809a72138b6ccb53a33b26faf5 md5: bf830ba5afc507c6232d4ef0fb1a882d depends: - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: TCL license_family: BSD size: 3270220 @@ -28180,7 +28001,7 @@ packages: sha256: 72457ad031b4c048e5891f3f6cb27a53cb479db68a52d965f796910e71a403a8 md5: b50a57ba89c32b62428b71a875291c9b depends: - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: TCL license_family: BSD size: 3145523 @@ -28213,7 +28034,7 @@ packages: md5: d453b98d9c83e71da0741bb0ff4d76bc depends: - libgcc-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: TCL license_family: BSD size: 3318875 @@ -28288,77 +28109,79 @@ packages: timestamp: 1706112720607 - kind: conda name: tornado - version: '6.4' - build: py311h05b510d_0 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.4-py311h05b510d_0.conda - sha256: 29c07a81b52310f9679ca05a6f1d3d3ee8c1830f183f91ad8d46f99cc2fb6720 - md5: 241cd427ab1f38b72d6ddda3994c80a7 + version: 6.4.1 + build: py311h331c9d8_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.4.1-py311h331c9d8_0.conda + sha256: 753f5496ba6a69fc52bd58e55296d789b964d1ba1539420bfc10bcd0e1d016fb + md5: e29e451c96bf8e81a5760b7565c6ed2c depends: + - libgcc-ng >=12 - python >=3.11,<3.12.0a0 - - python >=3.11,<3.12.0a0 *_cpython - python_abi 3.11.* *_cp311 license: Apache-2.0 license_family: Apache purls: - pkg:pypi/tornado - size: 856729 - timestamp: 1708363632330 + size: 856038 + timestamp: 1717722984124 - kind: conda name: tornado - version: '6.4' - build: py311h459d7ec_0 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/tornado-6.4-py311h459d7ec_0.conda - sha256: 5bb1e24d1767e403183e4cc842d184b2da497e778f0311c5b1d023fb3af9e6b6 - md5: cc7727006191b8f3630936b339a76cd0 + version: 6.4.1 + build: py311h72ae277_0 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/tornado-6.4.1-py311h72ae277_0.conda + sha256: 0182804d203f702736883fd5b8a6df0ae7ef427ac0609d172b4c8e3bca8a30bd + md5: eefa3eeb81da03b9f46a2bb2a01dfef4 depends: - - libgcc-ng >=12 + - __osx >=10.13 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 license: Apache-2.0 license_family: Apache purls: - pkg:pypi/tornado - size: 853245 - timestamp: 1708363316040 + size: 859395 + timestamp: 1717722909139 - kind: conda name: tornado - version: '6.4' - build: py311ha68e1ae_0 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/tornado-6.4-py311ha68e1ae_0.conda - sha256: ce73a6cede35941e1d82098e37ab483e0f322503a87c48ea39e8ac05798f9e39 - md5: 7bbff4fa9c26e56821e2eb89466436b1 + version: 6.4.1 + build: py311hd3f4193_0 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/tornado-6.4.1-py311hd3f4193_0.conda + sha256: 4924c617390d88a6f85879b2892a42b3feeea4d1e5fb2f23b2175eeb2b41c7f2 + md5: 180f7d621916cb04e655d4eda068f4bc depends: + - __osx >=11.0 - python >=3.11,<3.12.0a0 + - python >=3.11,<3.12.0a0 *_cpython - python_abi 3.11.* *_cp311 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 license: Apache-2.0 license_family: Apache purls: - pkg:pypi/tornado - size: 856957 - timestamp: 1708363616871 + size: 857353 + timestamp: 1717722957594 - kind: conda name: tornado - version: '6.4' - build: py311he705e18_0 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/tornado-6.4-py311he705e18_0.conda - sha256: 0b994ce7984953d1d528b7e19a97db0b34da09398feaf592500df637719d5623 - md5: 40845aadca8df7ccc21c393ba3aa9eac + version: 6.4.1 + build: py311he736701_0 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/tornado-6.4.1-py311he736701_0.conda + sha256: 6efb2b0eaf5063c76288d1bf1a55488e9035d86bd63380de5ed4990499ca6859 + md5: d6b9b155b10baf4ee79602a0e6b8265f depends: - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: Apache-2.0 license_family: Apache purls: - pkg:pypi/tornado - size: 857610 - timestamp: 1708363541170 + size: 860084 + timestamp: 1717723311673 - kind: conda name: tqdm version: 4.66.4 @@ -28454,36 +28277,36 @@ packages: timestamp: 1710590028155 - kind: conda name: typing-extensions - version: 4.11.0 + version: 4.12.2 build: hd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.11.0-hd8ed1ab_0.conda - sha256: aecbd9c601ba5a6c128da8975276fd817b968a9edc969b7ae97aee76e80a14a6 - md5: 471e3988f8ca5e9eb3ce6be7eac3bcee + url: https://conda.anaconda.org/conda-forge/noarch/typing-extensions-4.12.2-hd8ed1ab_0.conda + sha256: d3b9a8ed6da7c9f9553c5fd8a4fca9c3e0ab712fa5f497859f82337d67533b73 + md5: 52d648bd608f5737b123f510bb5514b5 depends: - - typing_extensions 4.11.0 pyha770c72_0 + - typing_extensions 4.12.2 pyha770c72_0 license: PSF-2.0 license_family: PSF - size: 10093 - timestamp: 1712330094282 + size: 10097 + timestamp: 1717802659025 - kind: conda name: typing_extensions - version: 4.11.0 + version: 4.12.2 build: pyha770c72_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.11.0-pyha770c72_0.conda - sha256: a7e8714d14f854058e971a6ed44f18cc37cc685f98ddefb2e6b7899a0cc4d1a2 - md5: 6ef2fc37559256cf682d8b3375e89b80 + url: https://conda.anaconda.org/conda-forge/noarch/typing_extensions-4.12.2-pyha770c72_0.conda + sha256: 0fce54f8ec3e59f5ef3bb7641863be4e1bf1279623e5af3d3fa726e8f7628ddb + md5: ebe6952715e1d5eb567eeebf25250fa7 depends: - python >=3.8 license: PSF-2.0 license_family: PSF purls: - pkg:pypi/typing-extensions - size: 37583 - timestamp: 1712330089194 + size: 39888 + timestamp: 1717802653893 - kind: conda name: typing_utils version: 0.1.0 @@ -28566,25 +28389,6 @@ packages: license_family: PROPRIETARY size: 1283972 timestamp: 1666630199266 -- kind: conda - name: ucx - version: 1.15.0 - build: ha691c75_8 - build_number: 8 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/ucx-1.15.0-ha691c75_8.conda - sha256: 85b40ac6607c9e4e32bcb13e95da41ff48a10f813df0c1e74ff32412e1f7da35 - md5: 3f9bc6137b240642504a6c9b07a10c25 - depends: - - libgcc-ng >=12 - - libstdcxx-ng >=12 - - rdma-core >=51.0 - constrains: - - cuda-version >=11.2,<12 - license: BSD-3-Clause - license_family: BSD - size: 6842006 - timestamp: 1712025621683 - kind: conda name: uri-template version: 1.3.0 @@ -28729,125 +28533,126 @@ packages: - kind: conda name: vc version: '14.3' - build: ha32ba9b_20 + build: h8a93ad2_20 build_number: 20 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-ha32ba9b_20.conda - sha256: 16cb562ce210ee089060f4aa52f3225a571c83885632a870ea2297d460e3bb00 - md5: 2abfb5cb1b9d41a50f765d60f0be563d + url: https://conda.anaconda.org/conda-forge/win-64/vc-14.3-h8a93ad2_20.conda + sha256: 23ac5feb15a9adf3ab2b8c4dcd63650f8b7ae860c5ceb073e49cf71d203eddef + md5: 8558f367e1d7700554f7cdb823c46faf depends: - - vc14_runtime >=14.38.33135 + - vc14_runtime >=14.40.33810 track_features: - vc14 license: BSD-3-Clause license_family: BSD - size: 17122 - timestamp: 1716231244564 + size: 17391 + timestamp: 1717709040616 - kind: conda name: vc14_runtime - version: 14.38.33135 - build: h835141b_20 + version: 14.40.33810 + build: ha82c5b3_20 build_number: 20 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.38.33135-h835141b_20.conda - sha256: 05b07e0dd3fd49dcc98a365ff661ed6b65e2f0266b4bb03d273131ffdba663be - md5: e971b35a5765862fabc4ba6e5ddf9470 + url: https://conda.anaconda.org/conda-forge/win-64/vc14_runtime-14.40.33810-ha82c5b3_20.conda + sha256: af3cfa347e3d7c1277e9b964b0849a9a9f095bff61836cb3c3a89862fbc32e17 + md5: e39cc4c34c53654ec939558993d9dc5b depends: - ucrt >=10.0.20348.0 constrains: - - vs2015_runtime 14.38.33135.* *_20 + - vs2015_runtime 14.40.33810.* *_20 license: LicenseRef-ProprietaryMicrosoft license_family: Proprietary - size: 744189 - timestamp: 1716231234745 + size: 751934 + timestamp: 1717709031266 - kind: conda name: vs2015_runtime - version: 14.38.33135 - build: h22015db_20 + version: 14.40.33810 + build: h3bf8584_20 build_number: 20 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.38.33135-h22015db_20.conda - sha256: 2cebabc39766ea051e577762d813ad4151e9d0ff96f3ff3374d575a272951416 - md5: bb4f5ab332e46e1b022d8842e72905b1 + url: https://conda.anaconda.org/conda-forge/win-64/vs2015_runtime-14.40.33810-h3bf8584_20.conda + sha256: 0c2803f7a788c51f28235a7228dc2ab3f107b4b16ab0845a3e595c8c51e50a7a + md5: c21f1b4a3a30bbc3ef35a50957578e0e depends: - - vc14_runtime >=14.38.33135 + - vc14_runtime >=14.40.33810 license: BSD-3-Clause license_family: BSD - size: 17124 - timestamp: 1716231247457 + size: 17395 + timestamp: 1717709043353 - kind: conda name: vtk version: 9.2.6 - build: qt_py311h1234567_220 - build_number: 220 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/vtk-9.2.6-qt_py311h1234567_220.conda - sha256: 81117e36312bf14fe1d8d38466fd76e4d53e36ccc32b0e392ef4a045ce5dd937 - md5: bd6689b3212fc662bd6cbc57e29ec0dc + build: qt_py311h1234567_223 + build_number: 223 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/vtk-9.2.6-qt_py311h1234567_223.conda + sha256: c6dbf30dde717804bf95383e21cc743c6328e1f7443000bd7d5482b38023f9be + md5: 2cae1cee5950aabe3ac2c1ea3cb9c68a depends: - - vtk-base 9.2.6 qt_py311h1234567_220 - - vtk-io-ffmpeg 9.2.6 qt_py311h1234567_220 + - vtk-base 9.2.6 qt_py311h1234567_223 + - vtk-io-ffmpeg 9.2.6 qt_py311h1234567_223 license: BSD-3-Clause license_family: BSD - size: 14034 - timestamp: 1702970368865 + size: 20166 + timestamp: 1717780131668 - kind: conda name: vtk - version: 9.2.6 - build: qt_py311h1234567_220 - build_number: 220 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/vtk-9.2.6-qt_py311h1234567_220.conda - sha256: 48f1a21a6e563abe968e86787c3f0f7b717de7e81f93402d56031022add8f83a - md5: 294d2f9a8f2a76361e58451ad125f114 + version: 9.3.0 + build: qt_py311h1234567_200 + build_number: 200 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/vtk-9.3.0-qt_py311h1234567_200.conda + sha256: 7d106b368df6f5f0c12c861e3d8fd8632c9df2173c85fbb071dc76824789682e + md5: 39028986fae6fa420405cc54ec016485 depends: - - vtk-base 9.2.6 qt_py311h1234567_220 - - vtk-io-ffmpeg 9.2.6 qt_py311h1234567_220 + - vtk-base 9.3.0 qt_py311h1234567_200 + - vtk-io-ffmpeg 9.3.0 qt_py311h1234567_200 license: BSD-3-Clause license_family: BSD - size: 14190 - timestamp: 1702974908092 + size: 21173 + timestamp: 1718292068294 - kind: conda name: vtk - version: 9.2.6 - build: qt_py311h1234567_220 - build_number: 220 + version: 9.3.0 + build: qt_py311h1234567_200 + build_number: 200 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/vtk-9.2.6-qt_py311h1234567_220.conda - sha256: 8407839fe95616c93ba720a3c24fffed77bfd757f5165ae12218671bd886a0b7 - md5: 2322130a6917696ba211e30646f00588 + url: https://conda.anaconda.org/conda-forge/osx-arm64/vtk-9.3.0-qt_py311h1234567_200.conda + sha256: 8c8d677f7aeb05538d2bbca273263a09e048b525f823040163a766836714e852 + md5: 7b171ad8adfd42e1e9f3e89e73b85a07 depends: - - vtk-base 9.2.6 qt_py311h1234567_220 - - vtk-io-ffmpeg 9.2.6 qt_py311h1234567_220 + - vtk-base 9.3.0 qt_py311h1234567_200 + - vtk-io-ffmpeg 9.3.0 qt_py311h1234567_200 license: BSD-3-Clause license_family: BSD - size: 14245 - timestamp: 1702974445475 + size: 21348 + timestamp: 1718291510366 - kind: conda name: vtk - version: 9.2.6 - build: qt_py311h1234567_220 - build_number: 220 + version: 9.3.0 + build: qt_py311h1234567_200 + build_number: 200 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/vtk-9.2.6-qt_py311h1234567_220.conda - sha256: 4160e6f7bc6a9becc7e155190c190a9d378a621bd634fa66dbd0e321c28acf98 - md5: a1a0698d54b1c2da5b7c504e667387ee + url: https://conda.anaconda.org/conda-forge/win-64/vtk-9.3.0-qt_py311h1234567_200.conda + sha256: 183a769ba715813f49a98f5b96800a4abaf285e0ce2df1dd0079d9cc372a6432 + md5: 9511590d1e9cfba5191676749a82b2a7 depends: - - vtk-base 9.2.6 qt_py311h1234567_220 + - vtk-base 9.3.0 qt_py311h1234567_200 license: BSD-3-Clause license_family: BSD - size: 14427 - timestamp: 1702971847093 + size: 21762 + timestamp: 1718294193787 - kind: conda name: vtk-base version: 9.2.6 - build: qt_py311h1234567_220 - build_number: 220 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/vtk-base-9.2.6-qt_py311h1234567_220.conda - sha256: b386f75b0fd18e06c46fa1296fb3f57f12ae6f72fd291cb5fa42c35f16267c69 - md5: bbfafb0cc0483c89ea2289381dc157a5 + build: qt_py311h1234567_223 + build_number: 223 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/vtk-base-9.2.6-qt_py311h1234567_223.conda + sha256: 9b897f74ba67788afd0b83ddab0b650818a7baaf41d79ebc1273fcd64761a8e4 + md5: 2a4b21be4ccd349e077735c9b657be18 depends: + - __osx >=10.13 - double-conversion >=3.3.0,<3.4.0a0 - eigen - expat @@ -28856,20 +28661,18 @@ packages: - glew >=2.1.0,<2.2.0a0 - hdf5 >=1.14.3,<1.14.4.0a0 - jsoncpp >=1.9.5,<1.9.6.0a0 - - libexpat >=2.5.0,<2.6.0a0 - - libgcc-ng >=12 + - libcxx >=16 + - libexpat <2.6 + - libexpat >=2.5.0,<3.0a0 - libjpeg-turbo >=3.0.0,<4.0a0 - libnetcdf >=4.9.2,<4.9.3.0a0 - libogg >=1.3.4,<1.4.0a0 - - libpng >=1.6.39,<1.7.0a0 - - libsqlite >=3.44.2,<4.0a0 - - libstdcxx-ng >=12 + - libpng >=1.6.43,<1.7.0a0 + - libsqlite >=3.45.3,<4.0a0 - libtheora >=1.1.1,<1.2.0a0 - libtiff >=4.6.0,<4.7.0a0 - - libuuid >=2.38.1,<3.0a0 - - libxcb >=1.15,<1.16.0a0 - - libxml2 >=2.11.6,<3.0.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libxml2 >=2.12.7,<3.0a0 + - libzlib >=1.2.13,<2.0a0 - loguru - lz4-c >=1.9.3,<1.10.0a0 - nlohmann_json @@ -28880,34 +28683,29 @@ packages: - python_abi 3.11.* *_cp311 - qt-main >=5.15.8,<5.16.0a0 - sqlite - - tbb >=2021.11.0 + - tbb >=2021.12.0 - tbb-devel - tk >=8.6.13,<8.7.0a0 - utfcpp - wslink - - xorg-libice >=1.1.1,<2.0a0 - - xorg-libsm >=1.2.4,<2.0a0 - - xorg-libx11 >=1.8.7,<2.0a0 - - xorg-libxau >=1.0.11,<2.0a0 - - xorg-libxext >=1.3.4,<2.0a0 - - xorg-libxt >=1.3.0,<2.0a0 - zlib constrains: - paraview ==9999999999 license: BSD-3-Clause license_family: BSD - size: 41995108 - timestamp: 1702970254300 + size: 33292139 + timestamp: 1717780001441 - kind: conda name: vtk-base - version: 9.2.6 - build: qt_py311h1234567_220 - build_number: 220 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/vtk-base-9.2.6-qt_py311h1234567_220.conda - sha256: 58d455760f65cb1f0a55268bc8c93ce5f5038594ba8a5be2f67dae300fcfec52 - md5: cf107f27c4c32f5c2de29a96d8cb853a + version: 9.3.0 + build: qt_py311h1234567_200 + build_number: 200 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/vtk-base-9.3.0-qt_py311h1234567_200.conda + sha256: eb6eb4c93ec0380fe5106ab6ce63a1f32c7bbf6fa6392ba40f450944e8c524d4 + md5: 240bc54c11dc7b302fb04b431c44a4bb depends: + - __glibc >=2.17,<3.0.a0 - double-conversion >=3.3.0,<3.4.0a0 - eigen - expat @@ -28916,17 +28714,20 @@ packages: - glew >=2.1.0,<2.2.0a0 - hdf5 >=1.14.3,<1.14.4.0a0 - jsoncpp >=1.9.5,<1.9.6.0a0 - - libcxx >=14 - - libexpat >=2.5.0,<2.6.0a0 + - libexpat >=2.6.2,<3.0a0 + - libgcc-ng >=12 - libjpeg-turbo >=3.0.0,<4.0a0 - libnetcdf >=4.9.2,<4.9.3.0a0 - libogg >=1.3.4,<1.4.0a0 - - libpng >=1.6.39,<1.7.0a0 - - libsqlite >=3.44.2,<4.0a0 + - libpng >=1.6.43,<1.7.0a0 + - libsqlite >=3.46.0,<4.0a0 + - libstdcxx-ng >=12 - libtheora >=1.1.1,<1.2.0a0 - libtiff >=4.6.0,<4.7.0a0 - - libxml2 >=2.11.6,<3.0.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libuuid >=2.38.1,<3.0a0 + - libxcb >=1.15,<1.16.0a0 + - libxml2 >=2.12.7,<3.0a0 + - libzlib >=1.2.13,<2.0a0 - loguru - lz4-c >=1.9.3,<1.10.0a0 - nlohmann_json @@ -28935,30 +28736,37 @@ packages: - pugixml >=1.14,<1.15.0a0 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 - - qt-main >=5.15.8,<5.16.0a0 + - qt6-main >=6.7.1,<6.8.0a0 - sqlite - - tbb >=2021.11.0 + - tbb >=2021.12.0 - tbb-devel - tk >=8.6.13,<8.7.0a0 - utfcpp - wslink + - xorg-libice >=1.1.1,<2.0a0 + - xorg-libsm >=1.2.4,<2.0a0 + - xorg-libx11 >=1.8.9,<2.0a0 + - xorg-libxau >=1.0.11,<2.0a0 + - xorg-libxext >=1.3.4,<2.0a0 + - xorg-libxt >=1.3.0,<2.0a0 - zlib constrains: - paraview ==9999999999 license: BSD-3-Clause license_family: BSD - size: 33947481 - timestamp: 1702974770043 + size: 46160261 + timestamp: 1718291918070 - kind: conda name: vtk-base - version: 9.2.6 - build: qt_py311h1234567_220 - build_number: 220 + version: 9.3.0 + build: qt_py311h1234567_200 + build_number: 200 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/vtk-base-9.2.6-qt_py311h1234567_220.conda - sha256: 712c7ec3bb4fb614a223127d913d702f07487c36f10e9e65356f726f93df0a60 - md5: b9e7975875d2f7b4952b77450193c009 + url: https://conda.anaconda.org/conda-forge/osx-arm64/vtk-base-9.3.0-qt_py311h1234567_200.conda + sha256: 5a4da4fd346b06326fd99936eefd1809a3f16329bf7ad46afd4d354399cda101 + md5: cc826943cbe2e07fb9a07964684178b6 depends: + - __osx >=11.0 - double-conversion >=3.3.0,<3.4.0a0 - eigen - expat @@ -28967,17 +28775,17 @@ packages: - glew >=2.1.0,<2.2.0a0 - hdf5 >=1.14.3,<1.14.4.0a0 - jsoncpp >=1.9.5,<1.9.6.0a0 - - libcxx >=14 - - libexpat >=2.5.0,<2.6.0a0 + - libcxx >=16 + - libexpat >=2.6.2,<3.0a0 - libjpeg-turbo >=3.0.0,<4.0a0 - libnetcdf >=4.9.2,<4.9.3.0a0 - libogg >=1.3.4,<1.4.0a0 - - libpng >=1.6.39,<1.7.0a0 - - libsqlite >=3.44.2,<4.0a0 + - libpng >=1.6.43,<1.7.0a0 + - libsqlite >=3.46.0,<4.0a0 - libtheora >=1.1.1,<1.2.0a0 - libtiff >=4.6.0,<4.7.0a0 - - libxml2 >=2.11.6,<3.0.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libxml2 >=2.12.7,<3.0a0 + - libzlib >=1.2.13,<2.0a0 - loguru - lz4-c >=1.9.3,<1.10.0a0 - nlohmann_json @@ -28987,9 +28795,9 @@ packages: - python >=3.11,<3.12.0a0 - python >=3.11,<3.12.0a0 *_cpython - python_abi 3.11.* *_cp311 - - qt-main >=5.15.8,<5.16.0a0 + - qt6-main >=6.7.1,<6.8.0a0 - sqlite - - tbb >=2021.11.0 + - tbb >=2021.12.0 - tbb-devel - tk >=8.6.13,<8.7.0a0 - utfcpp @@ -28999,37 +28807,37 @@ packages: - paraview ==9999999999 license: BSD-3-Clause license_family: BSD - size: 32814113 - timestamp: 1702974313237 + size: 34410466 + timestamp: 1718291382892 - kind: conda name: vtk-base - version: 9.2.6 - build: qt_py311h1234567_220 - build_number: 220 + version: 9.3.0 + build: qt_py311h1234567_200 + build_number: 200 subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/vtk-base-9.2.6-qt_py311h1234567_220.conda - sha256: d0acfa933ccc506f9a95a2b3c6d7cfb832625a6236eff9b4856fb2f0310d8ecf - md5: 62f88566c6439efc3c603c9a570cded5 + url: https://conda.anaconda.org/conda-forge/win-64/vtk-base-9.3.0-qt_py311h1234567_200.conda + sha256: 98811f5418cab19e08c27e210fb947a0888f8e19cfc533ad0c8c1347d72d7ec1 + md5: 6e4c6e34f93ab9ec259e6da9eae4150b depends: - double-conversion >=3.3.0,<3.4.0a0 - eigen - expat - - ffmpeg >=6.1.0,<7.0a0 + - ffmpeg >=6.1.1,<7.0a0 - freetype >=2.12.1,<3.0a0 - gl2ps >=1.4.2,<1.4.3.0a0 - glew >=2.1.0,<2.2.0a0 - hdf5 >=1.14.3,<1.14.4.0a0 - jsoncpp >=1.9.5,<1.9.6.0a0 - - libexpat >=2.5.0,<2.6.0a0 + - libexpat >=2.6.2,<3.0a0 - libjpeg-turbo >=3.0.0,<4.0a0 - libnetcdf >=4.9.2,<4.9.3.0a0 - libogg >=1.3.4,<1.4.0a0 - - libpng >=1.6.39,<1.7.0a0 - - libsqlite >=3.44.2,<4.0a0 + - libpng >=1.6.43,<1.7.0a0 + - libsqlite >=3.46.0,<4.0a0 - libtheora >=1.1.1,<1.2.0a0 - libtiff >=4.6.0,<4.7.0a0 - - libxml2 >=2.11.6,<3.0.0a0 - - libzlib >=1.2.13,<1.3.0a0 + - libxml2 >=2.12.7,<3.0a0 + - libzlib >=1.2.13,<2.0a0 - loguru - lz4-c >=1.9.3,<1.10.0a0 - nlohmann_json @@ -29038,9 +28846,9 @@ packages: - pugixml >=1.14,<1.15.0a0 - python >=3.11,<3.12.0a0 - python_abi 3.11.* *_cp311 - - qt-main >=5.15.8,<5.16.0a0 + - qt6-main >=6.7.1,<6.8.0a0 - sqlite - - tbb >=2021.11.0 + - tbb >=2021.12.0 - tbb-devel - ucrt >=10.0.20348.0 - utfcpp @@ -29052,56 +28860,73 @@ packages: - paraview ==9999999999 license: BSD-3-Clause license_family: BSD - size: 31287736 - timestamp: 1702971720494 + size: 33340853 + timestamp: 1718294079048 - kind: conda name: vtk-io-ffmpeg version: 9.2.6 - build: qt_py311h1234567_220 - build_number: 220 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/vtk-io-ffmpeg-9.2.6-qt_py311h1234567_220.conda - sha256: fa5c8521fcc4d0da9acdbacebfc30c41b55199b77a0f72bbdb2bf297abda01ae - md5: 0e894286dd36bdc569d7fd4e8033f8d9 + build: qt_py311h1234567_223 + build_number: 223 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/vtk-io-ffmpeg-9.2.6-qt_py311h1234567_223.conda + sha256: e37e0d8151c50d9a085cc59dc6f1b623233f001a6efce5be30ba334262582416 + md5: 085af4438371363163d67cd6a0d1d017 depends: - - ffmpeg >=6.1.0,<7.0a0 - - vtk-base 9.2.6 qt_py311h1234567_220 + - ffmpeg >=6.1.1,<7.0a0 + - vtk-base 9.2.6 qt_py311h1234567_223 license: BSD-3-Clause license_family: BSD - size: 71816 - timestamp: 1702970362174 + size: 67823 + timestamp: 1717780126310 - kind: conda name: vtk-io-ffmpeg - version: 9.2.6 - build: qt_py311h1234567_220 - build_number: 220 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/vtk-io-ffmpeg-9.2.6-qt_py311h1234567_220.conda - sha256: 25af0aed3f416efbd43c80677967372ecb1c9e86ce05df460fdec7866d112f05 - md5: db63d54826cf262b3cb1366bc04f9feb + version: 9.3.0 + build: qt_py311h1234567_200 + build_number: 200 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/vtk-io-ffmpeg-9.3.0-qt_py311h1234567_200.conda + sha256: 521f53ba918fb019c454cbf281cfa1463bcab845ede75bc2e64fdc10981753c7 + md5: 6878b51bbcdd28e50e2575c83f420a19 depends: - - ffmpeg >=6.1.0,<7.0a0 - - vtk-base 9.2.6 qt_py311h1234567_220 + - ffmpeg >=6.1.1,<7.0a0 + - vtk-base 9.3.0 qt_py311h1234567_200 license: BSD-3-Clause license_family: BSD - size: 61699 - timestamp: 1702974896239 + size: 80521 + timestamp: 1718292064507 - kind: conda name: vtk-io-ffmpeg - version: 9.2.6 - build: qt_py311h1234567_220 - build_number: 220 + version: 9.3.0 + build: qt_py311h1234567_200 + build_number: 200 subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/vtk-io-ffmpeg-9.2.6-qt_py311h1234567_220.conda - sha256: c40bda28fb1adbea6ce58b311e9b6bdadb696958ef4df75abb39d9b7cf39b6e4 - md5: af24e1f6c5b7c955def5d20b232ce58f + url: https://conda.anaconda.org/conda-forge/osx-arm64/vtk-io-ffmpeg-9.3.0-qt_py311h1234567_200.conda + sha256: f5409d067047092a0fcb9023d1c0f8dca6b862e921ad95182877f60ce6295654 + md5: bba612d8877ed2e6b18c2d0876555888 depends: - - ffmpeg >=6.1.0,<7.0a0 - - vtk-base 9.2.6 qt_py311h1234567_220 + - ffmpeg >=6.1.1,<7.0a0 + - vtk-base 9.3.0 qt_py311h1234567_200 license: BSD-3-Clause license_family: BSD - size: 63768 - timestamp: 1702974438834 + size: 69800 + timestamp: 1718291506827 +- kind: conda + name: wayland + version: 1.23.0 + build: h5291e77_0 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/wayland-1.23.0-h5291e77_0.conda + sha256: 5f2572290dd09d5480abe6e0d9635c17031a12fd4e68578680e9f49444d6dd8b + md5: c13ca0abd5d1d31d0eebcf86d51da8a4 + depends: + - libexpat >=2.6.2,<3.0a0 + - libffi >=3.4,<4.0a0 + - libgcc-ng >=12 + - libstdcxx-ng >=12 + license: MIT + license_family: MIT + size: 322846 + timestamp: 1717119371478 - kind: conda name: wcwidth version: 0.2.13 @@ -29121,21 +28946,21 @@ packages: timestamp: 1704731373922 - kind: conda name: webcolors - version: '1.13' + version: 24.6.0 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/webcolors-1.13-pyhd8ed1ab_0.conda - sha256: 6e097d5fe92849ad3af2c2a313771ad2fbf1cadd4dc4afd552303b2bf3f85211 - md5: 166212fe82dad8735550030488a01d03 + url: https://conda.anaconda.org/conda-forge/noarch/webcolors-24.6.0-pyhd8ed1ab_0.conda + sha256: 6377de3bc05b80f25c5fe75f180a81fc8a6aa601d4b228161f75f78862d00a0f + md5: 419f2f6cf90fc7a6feee657752cd0f7b depends: - python >=3.5 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/webcolors - size: 18186 - timestamp: 1679900907305 + size: 18291 + timestamp: 1717667379821 - kind: conda name: webencodings version: 0.5.1 @@ -29207,21 +29032,21 @@ packages: timestamp: 1711546009410 - kind: conda name: widgetsnbextension - version: 4.0.10 + version: 4.0.11 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.10-pyhd8ed1ab_0.conda - sha256: 981b06c76a1a86bb84be09522768be0458274926b22f4b0225dfcdd30a6593e0 - md5: 521f489e3babeddeec638c2add7e9e64 + url: https://conda.anaconda.org/conda-forge/noarch/widgetsnbextension-4.0.11-pyhd8ed1ab_0.conda + sha256: 240582f3aff18f28b3500e76f727e1c58048bfc1a445c71b7087907a0a85a5e6 + md5: 95ba42a349c9d8eac28e30d0b637401f depends: - python >=3.7 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/widgetsnbextension - size: 886369 - timestamp: 1707420479741 + size: 1079940 + timestamp: 1716891774202 - kind: conda name: win32_setctime version: 1.1.0 @@ -29273,22 +29098,23 @@ packages: size: 1176306 - kind: conda name: wslink - version: 2.0.4 + version: 2.0.5 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.4-pyhd8ed1ab_0.conda - sha256: 8d6b0866c964f3af11afb7bee9dafaddb794cf2b2216e5ebcf1ccbc45d43750f - md5: d51c40c9af5f104d4bb16598efc5b53d + url: https://conda.anaconda.org/conda-forge/noarch/wslink-2.0.5-pyhd8ed1ab_0.conda + sha256: d4d8f466b4233215c829f70895c9ffd0b5c20471f6efc0ee0757a2395bc4de37 + md5: 27b10b9befdccabfbdbe231d7bf61718 depends: - aiohttp <4 - msgpack-python >=1,<2 - python >=3.7 license: BSD-3-Clause + license_family: BSD purls: - pkg:pypi/wslink - size: 34198 - timestamp: 1716591663821 + size: 34241 + timestamp: 1717715275785 - kind: conda name: x264 version: 1!164.3095 @@ -29410,45 +29236,46 @@ packages: timestamp: 1646609481185 - kind: conda name: xarray - version: 2024.5.0 - build: pyhd8ed1ab_0 + version: 2024.6.0 + build: pyhd8ed1ab_1 + build_number: 1 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.5.0-pyhd8ed1ab_0.conda - sha256: cc5b17254ea131dace72eb3cea1ded242aa650c5dee4e0453eae1ffd699c0141 - md5: e839fd0ae78a368c930f0b1feafa6736 + url: https://conda.anaconda.org/conda-forge/noarch/xarray-2024.6.0-pyhd8ed1ab_1.conda + sha256: 782aaa095b246f18c2486826d2a71d886b2b4b99c08378f2bfda5d61877e509b + md5: a6775bba72ade3fd777ccac04902202c depends: - numpy >=1.23 - packaging >=23.1 - pandas >=2.0 - python >=3.9 constrains: - - hdf5 >=1.12 - - distributed >=2023.4 + - sparse >=0.14 - nc-time-axis >=1.4 - - cartopy >=0.21 - - h5py >=3.8 - - h5netcdf >=1.1 - - toolz >=0.12 - - dask-core >=2023.4 + - netcdf4 >=1.6.0 - pint >=0.22 - - scipy >=1.10 - - numba >=0.56 - - cftime >=1.6 - - seaborn >=0.12 + - dask-core >=2023.4 + - toolz >=0.12 + - cartopy >=0.21 + - bottleneck >=1.3 - iris >=3.4 - zarr >=2.14 - - flox >=0.7 - - bottleneck >=1.3 - - sparse >=0.14 - matplotlib-base >=3.7 - - netcdf4 >=1.6.0 + - h5py >=3.8 + - hdf5 >=1.12 + - cftime >=1.6 + - h5netcdf >=1.1 + - flox >=0.7 + - distributed >=2023.4 + - seaborn >=0.12 + - numba >=0.56 + - scipy >=1.10 license: Apache-2.0 license_family: APACHE purls: - pkg:pypi/xarray - size: 786586 - timestamp: 1715608167507 + size: 788402 + timestamp: 1718302275503 - kind: conda name: xcb-util version: 0.4.0 @@ -29466,6 +29293,25 @@ packages: license_family: MIT size: 19728 timestamp: 1684639166048 +- kind: conda + name: xcb-util-cursor + version: 0.1.4 + build: hd590300_1 + build_number: 1 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/xcb-util-cursor-0.1.4-hd590300_1.conda + sha256: df147500874761501030227d6bb8889443480cd6fe00361bb046d9840f04d17b + md5: 1ecae8461689e44fe0f0e3d18e58e799 + depends: + - libgcc-ng >=12 + - libxcb >=1.13 + - libxcb >=1.15,<1.16.0a0 + - xcb-util-image >=0.4.0,<0.5.0a0 + - xcb-util-renderutil >=0.3.9,<0.4.0a0 + license: MIT + license_family: MIT + size: 20170 + timestamp: 1684687482843 - kind: conda name: xcb-util-image version: 0.4.0 @@ -29600,19 +29446,19 @@ packages: timestamp: 1703093076013 - kind: conda name: xkeyboard-config - version: '2.41' - build: hd590300_0 + version: '2.42' + build: h4ab18f5_0 subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.41-hd590300_0.conda - sha256: 56955610c0747ea7cb026bb8aa9ef165ff41d616e89894538173b8b7dd2ee49a - md5: 81f740407b45e3f9047b3174fa94eb9e + url: https://conda.anaconda.org/conda-forge/linux-64/xkeyboard-config-2.42-h4ab18f5_0.conda + sha256: 240caab7d9d85154ef373ecbac3ff9fb424add2029dbb124e949c6cbab2996dd + md5: b193af204da1bfb8c13882d131a14bd2 depends: - libgcc-ng >=12 - - xorg-libx11 >=1.8.7,<2.0a0 + - xorg-libx11 >=1.8.9,<2.0a0 license: MIT license_family: MIT - size: 898045 - timestamp: 1707104384997 + size: 388998 + timestamp: 1717817668629 - kind: conda name: xorg-fixesproto version: '5.0' @@ -30508,21 +30354,21 @@ packages: timestamp: 1714580639671 - kind: conda name: xyzservices - version: 2024.4.0 + version: 2024.6.0 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.4.0-pyhd8ed1ab_0.conda - sha256: 4e095631b52a78bbd9b53f28eb79b0c8f448d9509cf0451e99c2f3f85576f114 - md5: 93dffc47dadbe36a1a644f3f50d4979d + url: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.6.0-pyhd8ed1ab_0.conda + sha256: da2e54cb68776e62a708cb6d5f026229d8405ff4cfd8a2446f7d386f07ebc5c1 + md5: de631703d59e40af41c56c4b4e2928ab depends: - python >=3.8 license: BSD-3-Clause license_family: BSD purls: - pkg:pypi/xyzservices - size: 46179 - timestamp: 1712210047952 + size: 46663 + timestamp: 1717752234053 - kind: conda name: xz version: 5.2.6 @@ -30712,13 +30558,13 @@ packages: timestamp: 1705508591601 - kind: conda name: zarr - version: 2.18.1 + version: 2.18.2 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/zarr-2.18.1-pyhd8ed1ab_0.conda - sha256: 695d68cb93d795cdbdf518808606f219f7af102e3ef3cf0c4ecf0e35c000d293 - md5: 0f0db4b713b96c1a78cb92f7ead0a6a5 + url: https://conda.anaconda.org/conda-forge/noarch/zarr-2.18.2-pyhd8ed1ab_0.conda + sha256: 16685f7412d79345732e889595a881ee320b85abd44f7244c0f7e628d9d976ec + md5: 02f53038910b6fbc9d36bd5f663318e8 depends: - asciitree - fasteners @@ -30726,15 +30572,15 @@ packages: - numpy >=1.23 - python >=3.9 constrains: - - ipytree >=0.2.2 - - ipywidgets >=8.0.0 - notebook + - ipywidgets >=8.0.0 + - ipytree >=0.2.2 license: MIT license_family: MIT purls: - pkg:pypi/zarr - size: 159716 - timestamp: 1715917248627 + size: 160260 + timestamp: 1716779819794 - kind: conda name: zeromq version: 4.3.5 @@ -30827,85 +30673,87 @@ packages: timestamp: 1681770298596 - kind: conda name: zipp - version: 3.17.0 + version: 3.19.2 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/zipp-3.17.0-pyhd8ed1ab_0.conda - sha256: bced1423fdbf77bca0a735187d05d9b9812d2163f60ab426fc10f11f92ecbe26 - md5: 2e4d6bc0b14e10f895fc6791a7d9b26a + url: https://conda.anaconda.org/conda-forge/noarch/zipp-3.19.2-pyhd8ed1ab_0.conda + sha256: e3e9c8501f581bfdc4700b83ea283395e237ec6b9b5cbfbedb556e1da6f4fdc9 + md5: 49808e59df5535116f6878b2a820d6f4 depends: - python >=3.8 license: MIT license_family: MIT purls: - pkg:pypi/zipp - size: 18954 - timestamp: 1695255262261 + size: 20917 + timestamp: 1718013395428 - kind: conda name: zlib version: 1.2.13 - build: h53f4e23_5 - build_number: 5 - subdir: osx-arm64 - url: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.2.13-h53f4e23_5.conda - sha256: de0ee1e24aa6867058d3b852a15c8d7f49f262f5828772700c647186d4a96bbe - md5: a08383f223b10b71492d27566fafbf6c + build: h2466b09_6 + build_number: 6 + subdir: win-64 + url: https://conda.anaconda.org/conda-forge/win-64/zlib-1.2.13-h2466b09_6.conda + sha256: 7aebf311fdb9227deddaedc33ace85bc960f5116ffb31f3ff07db380dfca0b41 + md5: 86591a585a18e35d23279b6b384eb4b9 depends: - - libzlib 1.2.13 h53f4e23_5 + - libzlib 1.2.13 h2466b09_6 + - ucrt >=10.0.20348.0 + - vc >=14.2,<15 + - vc14_runtime >=14.29.30139 license: Zlib license_family: Other - size: 79577 - timestamp: 1686575471024 + size: 107894 + timestamp: 1716874644593 - kind: conda name: zlib version: 1.2.13 - build: h8a1eda9_5 - build_number: 5 - subdir: osx-64 - url: https://conda.anaconda.org/conda-forge/osx-64/zlib-1.2.13-h8a1eda9_5.conda - sha256: d1f4c82fd7bd240a78ce8905e931e68dca5f523c7da237b6b63c87d5625c5b35 - md5: 75a8a98b1c4671c5d2897975731da42d + build: h4ab18f5_6 + build_number: 6 + subdir: linux-64 + url: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.2.13-h4ab18f5_6.conda + sha256: 534824ea44939f3e59ca8ebb95e3ece6f50f9d2a0e69999fbc692311252ed6ac + md5: 559d338a4234c2ad6e676f460a093e67 depends: - - libzlib 1.2.13 h8a1eda9_5 + - libgcc-ng >=12 + - libzlib 1.2.13 h4ab18f5_6 license: Zlib license_family: Other - size: 90764 - timestamp: 1686575574678 + size: 92883 + timestamp: 1716874088980 - kind: conda name: zlib version: 1.2.13 - build: hcfcfb64_5 - build_number: 5 - subdir: win-64 - url: https://conda.anaconda.org/conda-forge/win-64/zlib-1.2.13-hcfcfb64_5.conda - sha256: 0f91b719c7558046bcd37fdc7ae4b9eb2b7a8e335beb8b59ae7ccb285a46aa46 - md5: a318e8622e11663f645cc7fa3260f462 + build: h87427d6_6 + build_number: 6 + subdir: osx-64 + url: https://conda.anaconda.org/conda-forge/osx-64/zlib-1.2.13-h87427d6_6.conda + sha256: 3091d48a579c08ba20885bc8856def925e9dee9d1a7d8713e3ce002eb29fcd19 + md5: 700b922d6d22e7deb5fb2964d0c8cf6a depends: - - libzlib 1.2.13 hcfcfb64_5 - - ucrt >=10.0.20348.0 - - vc >=14.2,<15 - - vc14_runtime >=14.29.30139 + - __osx >=10.13 + - libzlib 1.2.13 h87427d6_6 license: Zlib license_family: Other - size: 107711 - timestamp: 1686575474476 + size: 88732 + timestamp: 1716874218187 - kind: conda name: zlib version: 1.2.13 - build: hd590300_5 - build_number: 5 - subdir: linux-64 - url: https://conda.anaconda.org/conda-forge/linux-64/zlib-1.2.13-hd590300_5.conda - sha256: 9887a04d7e7cb14bd2b52fa01858f05a6d7f002c890f618d9fcd864adbfecb1b - md5: 68c34ec6149623be41a1933ab996a209 + build: hfb2fe0b_6 + build_number: 6 + subdir: osx-arm64 + url: https://conda.anaconda.org/conda-forge/osx-arm64/zlib-1.2.13-hfb2fe0b_6.conda + sha256: c09c9cb6de86d87b9267a6331c74cc8fb05bae5ee7749070a5e8883c3eff5424 + md5: 88cf27df3eff5813734b538461f4c8cf depends: - - libgcc-ng >=12 - - libzlib 1.2.13 hd590300_5 + - __osx >=11.0 + - libzlib 1.2.13 hfb2fe0b_6 license: Zlib license_family: Other - size: 92825 - timestamp: 1686575231103 + size: 78193 + timestamp: 1716874169064 - kind: conda name: zstd version: 1.5.6 @@ -30915,7 +30763,7 @@ packages: sha256: 768e30dc513568491818fb068ee867c57c514b553915536da09e5d10b4ebf3c3 md5: 9a17230f95733c04dc40a2b1e5491d74 depends: - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 - ucrt >=10.0.20348.0 - vc >=14.2,<15 - vc14_runtime >=14.29.30139 @@ -30933,7 +30781,7 @@ packages: md5: 4cb2cd56f039b129bb0e491c1164167e depends: - __osx >=10.9 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: BSD-3-Clause license_family: BSD size: 498900 @@ -30949,7 +30797,7 @@ packages: depends: - libgcc-ng >=12 - libstdcxx-ng >=12 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: BSD-3-Clause license_family: BSD size: 554846 @@ -30964,7 +30812,7 @@ packages: md5: d96942c06c3e84bfcc5efb038724a7fd depends: - __osx >=11.0 - - libzlib >=1.2.13,<1.3.0a0 + - libzlib >=1.2.13,<2.0.0a0 license: BSD-3-Clause license_family: BSD size: 405089 From 9f274bd8913e0d7d941e4e80cb30537956bb1870 Mon Sep 17 00:00:00 2001 From: luitjansl <64598682+luitjansl@users.noreply.github.com> Date: Wed, 26 Jun 2024 16:34:23 +0200 Subject: [PATCH 20/53] issue #1083 duplicate wells (#1086) Fixes #1083 # Description When importing wells, we now make sure that when the ipf file defines 2 or more wells with the same x, y , filter_top, filter_bottom and id, then the ID of the second well is appended with "_1", and so on for successive findings of a well with the same characteristics (_2, _3 etc). # Checklist - [X] Links to correct issue - [ ] Update changelog, if changes affect users - [X] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [X] Unit tests were added - [ ] **If feature added**: Added/extended example --- imod/formats/prj/prj.py | 36 +++++++++++++++++ imod/tests/test_mf6/test_import_prj.py | 53 ++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) diff --git a/imod/formats/prj/prj.py b/imod/formats/prj/prj.py index 100d4060a..89abdeebe 100644 --- a/imod/formats/prj/prj.py +++ b/imod/formats/prj/prj.py @@ -3,6 +3,7 @@ """ import shlex +import textwrap from collections import defaultdict from datetime import datetime from itertools import chain @@ -15,6 +16,8 @@ import xarray as xr import imod +import imod.logging +from imod.logging.loglevel import LogLevel FilePath = Union[str, "PathLike[str]"] @@ -784,6 +787,11 @@ def _read_package_ipf( ) -> Tuple[List[Dict[str, Any]], List[datetime]]: out = [] repeats = [] + + # we will store in this set the tuples of (x, y, id, well_top, well_bot) + # which should be unique for each well + imported_wells = {} + for entry in block_content["ipf"]: timestring = entry["time"] layer = entry["layer"] @@ -822,6 +830,34 @@ def _read_package_ipf( if "filt_top" in row._fields and "filt_bot" in row._fields: df_assoc["filt_top"] = row.filt_top df_assoc["filt_bot"] = row.filt_bot + + well_characteristics = ( + row[1], + row[2], + path_assoc.stem, + row.filt_top, + row.filt_bot, + ) + if well_characteristics not in imported_wells.keys(): + imported_wells[well_characteristics] = 0 + else: + suffix = imported_wells[well_characteristics] + 1 + imported_wells[well_characteristics] = suffix + df_assoc["id"] = df_assoc["id"] + f"_{suffix}" + + log_message = textwrap.dedent( + f"""A well with the same x, y, id, filter_top and filter_bot was already imported. + This happened at x = {row[1]}, y = { row[2]}, id = {path_assoc.stem} + Now the ID for this new well was appended with the suffix _{suffix}) + """ + ) + + imod.logging.logger.log( + loglevel=LogLevel.WARNING, + message=log_message, + additional_depth=2, + ) + dfs.append(df_assoc) df = pd.concat(dfs, ignore_index=True, sort=False) df["rate"] = df["rate"] * factor + addition diff --git a/imod/tests/test_mf6/test_import_prj.py b/imod/tests/test_mf6/test_import_prj.py index e5297f1c8..9cdff6a41 100644 --- a/imod/tests/test_mf6/test_import_prj.py +++ b/imod/tests/test_mf6/test_import_prj.py @@ -1,11 +1,15 @@ +import sys from textwrap import dedent from zipfile import ZipFile import numpy as np from numpy.testing import assert_allclose +import imod from imod.data.sample_data import create_pooch_registry, load_pooch_registry from imod.formats.prj import open_projectfile_data +from imod.logging.config import LoggerType +from imod.logging.loglevel import LogLevel registry = create_pooch_registry() registry = load_pooch_registry(registry) @@ -200,6 +204,55 @@ def test_import_ipf(tmp_path): assert np.all(result_snippet_1[0]["wel-3"]["dataframe"]["filt_bot"] == 6.0) +def test_import_ipf_unique_id_and_logging(tmp_path): + with ZipFile(fname_model) as archive: + archive.extractall(tmp_path) + + logfile_path = tmp_path / "logfile.txt" + + try: + with open(logfile_path, "w") as sys.stdout: + # start logging + imod.logging.configure( + LoggerType.PYTHON, + log_level=LogLevel.WARNING, + add_default_file_handler=False, + add_default_stream_handler=True, + ) + projects_file = tmp_path / "iMOD5_model_pooch" / "iMOD5_model.prj" + + file1 = open(projects_file, "w") + file1.write( + snippet_gen_import_ipf( + factor1=2.0, addition1=1.3, factor2=-1.0, addition2=0.0 + ) + ) + file1.close() + + # Act + result_snippet_1 = open_projectfile_data(projects_file) + finally: + # turn the logger off again + imod.logging.configure( + LoggerType.NULL, + log_level=LogLevel.WARNING, + add_default_file_handler=False, + add_default_stream_handler=False, + ) + + # test that id's were made unique + # Assert + assert np.all(result_snippet_1[0]["wel-1"]["dataframe"]["id"] == "extractions") + assert np.all(result_snippet_1[0]["wel-2"]["dataframe"]["id"] == "extractions_1") + assert np.all(result_snippet_1[0]["wel-3"]["dataframe"]["id"] == "extractions_2") + + with open(logfile_path, "r") as log_file: + log = log_file.read() + assert "This happened at x = 197910, y = 362860, id = extractions" in log + assert "appended with the suffix _1" in log + assert "appended with the suffix _2" in log + + def snippet_boundary_condition(factor: float, addition: float): return dedent(f"""\ 0001,(CHD),1, Constant Head From 879d52149e7c472914ba133b3a9a44f6a700d09c Mon Sep 17 00:00:00 2001 From: luitjansl <64598682+luitjansl@users.noreply.github.com> Date: Wed, 26 Jun 2024 17:54:52 +0200 Subject: [PATCH 21/53] Issue #1064 wel from imod (#1066) Fixes #1064 # Description Imports wells as grid-agnostic well packages, based on filter top and filter bottom, and x/y location as stated in the imod5_dataset object. # Checklist - [X] Links to correct issue - [ ] Update changelog, if changes affect users - [X] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [X] Unit tests were added - [ ] **If feature added**: Added/extended example --------- Co-authored-by: Joeri van Engelen --- imod/formats/prj/prj.py | 9 +- imod/mf6/wel.py | 40 ++++++ imod/tests/conftest.py | 4 + imod/tests/fixtures/imod5_well_data.py | 173 +++++++++++++++++++++++++ imod/tests/test_mf6/test_mf6_wel.py | 63 +++++++++ 5 files changed, 284 insertions(+), 5 deletions(-) create mode 100644 imod/tests/fixtures/imod5_well_data.py diff --git a/imod/formats/prj/prj.py b/imod/formats/prj/prj.py index 89abdeebe..30c199073 100644 --- a/imod/formats/prj/prj.py +++ b/imod/formats/prj/prj.py @@ -827,16 +827,15 @@ def _read_package_ipf( df_assoc["x"] = row[1] df_assoc["y"] = row[2] df_assoc["id"] = path_assoc.stem - if "filt_top" in row._fields and "filt_bot" in row._fields: - df_assoc["filt_top"] = row.filt_top - df_assoc["filt_bot"] = row.filt_bot + df_assoc["filt_top"] = row[4] + df_assoc["filt_bot"] = row[5] well_characteristics = ( row[1], row[2], path_assoc.stem, - row.filt_top, - row.filt_bot, + row[4], + row[5], ) if well_characteristics not in imported_wells.keys(): imported_wells[well_characteristics] = 0 diff --git a/imod/mf6/wel.py b/imod/mf6/wel.py index 7a2fa8783..07d361b4e 100644 --- a/imod/mf6/wel.py +++ b/imod/mf6/wel.py @@ -647,6 +647,46 @@ def mask(self, domain: GridDataArray) -> Well: ) return mask_2D(self, domain_2d) + @classmethod + def from_imod5_data( + cls, + key: str, + imod5_data: dict[str, dict[str, GridDataArray]], + minimum_k: float = 0.1, + minimum_thickness: float = 1.0, + ) -> "Well": + df: pd.DataFrame = imod5_data[key]["dataframe"] + + # Groupby unique wells, to get dataframes per time. + colnames_group = ["x", "y", "filt_top", "filt_bot", "id"] + wel_index, df_groups = zip(*df.groupby(colnames_group)) + # Unpack wel indices by zipping + x, y, filt_top, filt_bot, id = zip(*wel_index) + # Convert dataframes all groups to DataArrays + da_groups = [ + xr.DataArray( + df_group["rate"], dims=("time"), coords={"time": df_group["time"]} + ) + for df_group in df_groups + ] + # Assign index coordinates + da_groups = [ + da_group.expand_dims(dim="index").assign_coords(index=[i]) + for i, da_group in enumerate(da_groups) + ] + # Concatenate datarrays along index dimension + well_rate = xr.concat(da_groups, dim="index") + + return cls( + x=np.array(x, dtype=float), + y=np.array(y, dtype=float), + screen_top=np.array(filt_top, dtype=float), + screen_bottom=np.array(filt_bot, dtype=float), + rate=well_rate, + minimum_k=minimum_k, + minimum_thickness=minimum_thickness, + ) + class WellDisStructured(DisStructuredBoundaryCondition): """ diff --git a/imod/tests/conftest.py b/imod/tests/conftest.py index 1150a8ad3..5d9a74cab 100644 --- a/imod/tests/conftest.py +++ b/imod/tests/conftest.py @@ -19,6 +19,10 @@ ) from .fixtures.flow_example_fixture import imodflow_model from .fixtures.flow_transport_simulation_fixture import flow_transport_simulation +from .fixtures.imod5_well_data import ( + well_duplication_import_prj, + well_regular_import_prj, +) from .fixtures.mf6_circle_fixture import ( circle_model, circle_model_evt, diff --git a/imod/tests/fixtures/imod5_well_data.py b/imod/tests/fixtures/imod5_well_data.py new file mode 100644 index 000000000..f4904d383 --- /dev/null +++ b/imod/tests/fixtures/imod5_well_data.py @@ -0,0 +1,173 @@ +import os +import textwrap +from pathlib import Path + +import pytest + +import imod + +ipf_header = textwrap.dedent( + """\ + 3 + 18 + x + y + q_m3 + FilterTopLevel + FilterBottomLevel + putcode + FilterNo + ALIAS + StartDateTime + SurfaceLevel + WellTopLevel + WellBottomLevel + Status + Type + Comment + CommentBy + Site + Organisation + 3,txt """ +) + + +def projectfile_string(tmp_path): + return textwrap.dedent( + f"""\ + 0001,(WEL),1, Wells,[WRA] + 2000-01-01 00:00:00 + 001,002 + 1,2, 000, 1.000000 , 0.000000 , -999.9900 ,'{tmp_path}\ipf1.ipf' + 1,2, 000, 1.000000 , 0.000000 , -999.9900 ,'{tmp_path}\ipf2.ipf' + """ + ) + + +def ipf1_string_no_duplication(): + return textwrap.dedent( + f"""\ + {ipf_header} + 191231.52,406381.47,timeseries_wel1,4.11,-1.69,01-PP001,0,B46D0517,"30-11-1981 00:00",13.41,13.41,nan,Inactive,Vertical,"Oxmeer","User1 - Zeeland Water","Oxmeer","Zeeland Water" + 191171.96,406420.89,timeseries_wel1,3.78,-2.02,01-PP002,0,B46D0518,"30-11-1981 00:00",13.18,13.18,nan,Inactive,Vertical,"Oxmeer","User1 - Zeeland Water","Oxmeer","Zeeland Water" + 191112.11,406460.02,timeseries_wel1,3.81,-1.99,01-PP003,0,B46D0519,"30-11-1981 00:00",13.21,13.21,nan,Inactive,Vertical,"Oxmeer","User1 - Zeeland Water","Oxmeer","Zeeland Water" + """ + ) + + +def ipf1_string_duplication(): + return textwrap.dedent( + f"""\ + {ipf_header} + 191231.52,406381.47,timeseries_wel1,4.11,-1.69,01-PP001,0,B46D0517,"30-11-1981 00:00",13.41,13.41,nan,Inactive,Vertical,"Oxmeer","User1 - Zeeland Water","Oxmeer","Zeeland Water" + 191171.96,406420.89,timeseries_wel1,3.78,-2.02,01-PP002,0,B46D0518,"30-11-1981 00:00",13.18,13.18,nan,Inactive,Vertical,"Oxmeer","User1 - Zeeland Water","Oxmeer","Zeeland Water" + 191231.52,406381.47,other_timeseries_wel1,4.11,-1.69,01-PP001,0,B46D0517,"30-11-1981 00:00",13.41,13.41,nan,Inactive,Vertical,"Oxmeer","User1 - Zeeland Water","Oxmeer","Zeeland Water" + """ + ) + + +def ipf2_string(): + return textwrap.dedent( + f"""\ + {ipf_header} + 191231.52,406381.47,timeseries_wel1,4.11,-1.69,01-PP001,0,B46D0517,"30-11-1981 00:00",13.41,13.41,nan,Inactive,Vertical,"Oxmeer","User1 - Zeeland Water","Oxmeer","Zeeland Water" + 191171.96,406420.89,timeseries_wel1,3.78,-2.02,01-PP002,0,B46D0518,"30-11-1981 00:00",13.18,13.18,nan,Inactive,Vertical,"Oxmeer","User1 - Zeeland Water","Oxmeer","Zeeland Water" + 191112.11,406460.02,timeseries_wel1,3.81,-1.99,01-PP003,0,B46D0519,"30-11-1981 00:00",13.21,13.21,nan,Inactive,Vertical,"Oxmeer","User1 - Zeeland Water","Oxmeer","Zeeland Water" + """ + ) + + +def timeseries_string(): + return textwrap.dedent( + """\ + 374 + 2 + DATE,-9999.0 + MEASUREMENT,-9999.0 + 19811130,-676.1507971461288 + 19811231,-766.7777419354838 + 19820131,-847.6367741935485 + 19820228,-927.3857142857142 + 19820331,-859.2109677419355 + 19820430,-882.7713333333334 + """ + ) + + +def other_timeseries_string(): + return textwrap.dedent( + """\ + 374 + 2 + DATE,-9999.0 + MEASUREMENT,-9999.0 + 19811130,-174.1507971461288 + 19811231,-166.7777419354838 + 19820131,-147.6367741935485 + 19820228,-127.3857142857142 + 19820331,-159.2109677419355 + 19820430,-182.7713333333334 + """ + ) + + +def write_files( + projectfile_str, + ipf1_str, + ipf2_str, + timeseries_wel1_str, + tmp_path, + other_timeseries_string=None, +): + with open(Path(tmp_path) / "projectfile.prj", "w") as f: + f.write(projectfile_str) + + with open(Path(tmp_path) / "ipf1.ipf", "w") as f: + f.write(ipf1_str) + + with open(Path(tmp_path) / "ipf2.ipf", "w") as f: + f.write(ipf2_str) + + with open(Path(tmp_path) / "timeseries_wel1.txt", "w") as f: + f.write(timeseries_wel1_str) + + if other_timeseries_string is not None: + with open(Path(tmp_path) / "other_timeseries_wel1.txt", "w") as f: + f.write(other_timeseries_string) + + return Path(tmp_path) / "projectfile.prj" + + +@pytest.fixture(scope="session") +def well_regular_import_prj(): + tmp_path = imod.util.temporary_directory() + os.makedirs(tmp_path) + + projectfile_str = projectfile_string(tmp_path) + ipf1_str = ipf1_string_no_duplication() + ipf2_str = ipf2_string() + timeseries_well_str = timeseries_string() + + return write_files( + projectfile_str, ipf1_str, ipf2_str, timeseries_well_str, tmp_path + ) + + +@pytest.fixture(scope="session") +def well_duplication_import_prj(): + tmp_path = imod.util.temporary_directory() + os.makedirs(tmp_path) + + projectfile_str = projectfile_string(tmp_path) + ipf1_str = ipf1_string_duplication() + ipf2_str = ipf2_string() + timeseries_well_str = timeseries_string() + other_timeseries_well_str = other_timeseries_string() + return write_files( + projectfile_str, + ipf1_str, + ipf2_str, + timeseries_well_str, + tmp_path, + other_timeseries_well_str, + ) diff --git a/imod/tests/test_mf6/test_mf6_wel.py b/imod/tests/test_mf6/test_mf6_wel.py index 443398b5f..09d388220 100644 --- a/imod/tests/test_mf6/test_mf6_wel.py +++ b/imod/tests/test_mf6/test_mf6_wel.py @@ -11,9 +11,13 @@ from pytest_cases import parametrize_with_cases import imod +from imod.formats.prj.prj import open_projectfile_data from imod.logging.config import LoggerType from imod.logging.loglevel import LogLevel +from imod.mf6.dis import StructuredDiscretization +from imod.mf6.npf import NodePropertyFlow from imod.mf6.utilities.grid import broadcast_to_full_domain +from imod.mf6.wel import Well from imod.mf6.write_context import WriteContext from imod.schemata import ValidationError from imod.tests.fixtures.flow_basic_fixture import BasicDisSettings @@ -812,3 +816,62 @@ def test_render__concentration_dis_vertices_transient(well_test_data_transient): assert ( data.count(" 246 135") == 15 ) # check salinity and temperature was written to period data + + +@pytest.mark.usefixtures("imod5_dataset") +def test_import_and_convert_to_mf6(imod5_dataset, tmp_path): + target_dis = StructuredDiscretization.from_imod5_data(imod5_dataset) + target_npf = NodePropertyFlow.from_imod5_data( + imod5_dataset, target_dis.dataset["idomain"] + ) + + # import grid-agnostic well from imod5 data (it contains 1 well) + wel = Well.from_imod5_data("wel-1", imod5_dataset) + assert wel.dataset["x"].values[0] == 197910.0 + assert wel.dataset["y"].values[0] == 362860.0 + assert np.mean(wel.dataset["rate"].values) == -323.8936170212766 + + # convert to a gridded well + top = target_dis.dataset["top"] + bottom = target_dis.dataset["bottom"] + active = target_dis.dataset["idomain"] + k = target_npf.dataset["k"] + mf6_well = wel.to_mf6_pkg(active, top, bottom, k, True) + + # assert mf6 well properties + assert len(mf6_well.dataset["x"].values == 1) + assert mf6_well.dataset["x"].values[0] == 197910.0 + assert mf6_well.dataset["y"].values[0] == 362860.0 + assert np.mean(mf6_well.dataset["rate"].values) == -323.8936170212766 + + # write the package for validation + write_context = WriteContext(simulation_directory=tmp_path) + mf6_well.write("wel", [], write_context) + + +@pytest.mark.usefixtures("well_regular_import_prj") +def test_import_multiple_wells(well_regular_import_prj): + imod5dict = open_projectfile_data(well_regular_import_prj) + + # import grid-agnostic well from imod5 data (it contains 2 packages with 3 wells each) + wel1 = imod.mf6.Well.from_imod5_data("wel-1", imod5dict[0]) + wel2 = imod.mf6.Well.from_imod5_data("wel-2", imod5dict[0]) + + assert np.all(wel1.x == np.array([191112.11, 191171.96, 191231.52])) + assert np.all(wel2.x == np.array([191112.11, 191171.96, 191231.52])) + assert wel1.dataset["rate"].shape == (6, 3) + assert wel2.dataset["rate"].shape == (6, 3) + + +@pytest.mark.usefixtures("well_duplication_import_prj") +def test_import_from_imod5_with_duplication(well_duplication_import_prj): + imod5dict = open_projectfile_data(well_duplication_import_prj) + + # import grid-agnostic well from imod5 data (it contains 2 packages with 3 wells each) + wel1 = imod.mf6.Well.from_imod5_data("wel-1", imod5dict[0]) + wel2 = imod.mf6.Well.from_imod5_data("wel-2", imod5dict[0]) + + assert np.all(wel1.x == np.array([191171.96, 191231.52, 191231.52])) + assert np.all(wel2.x == np.array([191112.11, 191171.96, 191231.52])) + assert wel1.dataset["rate"].shape == (6, 3) + assert wel2.dataset["rate"].shape == (6, 3) From 36bc7a750b002f87dd4824ac80d15828589672aa Mon Sep 17 00:00:00 2001 From: luitjansl <64598682+luitjansl@users.noreply.github.com> Date: Fri, 28 Jun 2024 15:12:35 +0200 Subject: [PATCH 22/53] Issue #966 chd import or shd (#1088) Fixes #966 # Description Imports chd packages present in imod5_data. These packages are imported one by one. If none are present, then a chd package is created at all locations where ibound == -1. In that case the starting head of the simulation is assigned as the chd value for each cell with ibound == -1. # Checklist - [X] Links to correct issue - [ ] Update changelog, if changes affect users - [X] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [X] Unit tests were added - [ ] **If feature added**: Added/extended example --- imod/mf6/chd.py | 146 +++++++++++++++++++++++++++- imod/mf6/model_gwf.py | 12 +++ imod/tests/test_mf6/test_mf6_chd.py | 38 ++++++++ 3 files changed, 195 insertions(+), 1 deletion(-) diff --git a/imod/mf6/chd.py b/imod/mf6/chd.py index 65e1bf3e0..7e5c20d0a 100644 --- a/imod/mf6/chd.py +++ b/imod/mf6/chd.py @@ -1,9 +1,16 @@ +from dataclasses import asdict +from typing import Optional + import numpy as np from imod.logging import init_log_decorator +from imod.logging.logging_decorators import standard_log_decorator from imod.mf6.boundary_condition import BoundaryCondition +from imod.mf6.dis import StructuredDiscretization from imod.mf6.interfaces.iregridpackage import IRegridPackage -from imod.mf6.regrid.regrid_schemes import ConstantHeadRegridMethod +from imod.mf6.regrid.regrid_schemes import ConstantHeadRegridMethod, RegridMethodType +from imod.mf6.utilities.regrid import RegridderWeightsCache, _regrid_package_data +from imod.mf6.utilities.regridding_types import RegridderType from imod.mf6.validation import BOUNDARY_DIMS_SCHEMA, CONC_DIMS_SCHEMA from imod.schemata import ( AllInsideNoDataSchema, @@ -15,6 +22,7 @@ IndexesSchema, OtherCoordsSchema, ) +from imod.typing import GridDataArray class ConstantHead(BoundaryCondition, IRegridPackage): @@ -141,3 +149,139 @@ def _validate(self, schemata, **kwargs): errors = super()._validate(schemata, **kwargs) return errors + + @classmethod + @standard_log_decorator() + def from_imod5_data( + cls, + key: str, + imod5_data: dict[str, dict[str, GridDataArray]], + target_discretization: StructuredDiscretization, + regridder_types: Optional[RegridMethodType] = None, + ) -> "ConstantHead": + """ + Construct a ConstantHead-package from iMOD5 data, loaded with the + :func:`imod.formats.prj.open_projectfile_data` function. + + This function can be used if chd packages are defined in the imod5 data. + + If they are not, then imod5 assumed that at all the locations where ibound + = -1 a chd package is active with the starting head of the simulation + as a constant. In that case, use the from_imod5_shd_data function instead + of this one. + + The creation of a chd package from shd data should only be done if no chd + packages at all are present in the imod5_data + + + + Parameters + ---------- + key: str + The key used in the imod5 data dictionary that is used to refer + to the chd package that we want to import. + imod5_data: dict + Dictionary with iMOD5 data. This can be constructed from the + :func:`imod.formats.prj.open_projectfile_data` method. + target_discretization: StructuredDiscretization package + The grid that should be used for the new package. Does not + need to be identical to one of the input grids. + regridder_types: RegridMethodType, optional + Optional dataclass with regridder types for a specific variable. + Use this to override default regridding methods. + + Returns + ------- + A list of Modflow 6 ConstantHead packages. + """ + return cls._from_head_data( + imod5_data[key]["head"], + imod5_data["bnd"]["ibound"], + target_discretization, + regridder_types, + ) + + @classmethod + @standard_log_decorator() + def from_imod5_shd_data( + cls, + imod5_data: dict[str, dict[str, GridDataArray]], + target_discretization: StructuredDiscretization, + regridder_types: Optional[RegridMethodType] = None, + ) -> "ConstantHead": + """ + Construct a ConstantHead-package from iMOD5 data, loaded with the + :func:`imod.formats.prj.open_projectfile_data` function. + + This function can be used if no chd packages at all are defined in the imod5 data. + + In that case, imod5 assumed that at all the locations where ibound + = -1, a chd package is active with the starting head of the simulation + as a constant. + + So this function creates a single chd package that will be present at all locations where + ibound == -1. The assigned head will be the starting head, specified in the array "shd" + in the imod5 data. + + Parameters + ---------- + imod5_data: dict + Dictionary with iMOD5 data. This can be constructed from the + :func:`imod.formats.prj.open_projectfile_data` method. + target_discretization: StructuredDiscretization package + The grid that should be used for the new package. Does not + need to be identical to one of the input grids. + regridder_types: RegridMethodType, optional + Optional dataclass with regridder types for a specific variable. + Use this to override default regridding methods. + + Returns + ------- + A Modflow 6 ConstantHead package. + """ + return cls._from_head_data( + imod5_data["shd"]["head"], + imod5_data["bnd"]["ibound"], + target_discretization, + regridder_types, + ) + + @classmethod + def _from_head_data( + cls, + head: GridDataArray, + ibound: GridDataArray, + target_discretization: StructuredDiscretization, + regridder_types: Optional[RegridMethodType] = None, + ) -> "ConstantHead": + target_idomain = target_discretization.dataset["idomain"] + + if regridder_types is None: + regridder_settings = asdict(cls.get_regrid_methods(), dict_factory=dict) + else: + regridder_settings = asdict(regridder_types, dict_factory=dict) + + # appart from the arrays needed for the ConstantHead package, we will + # also regrid ibound. + regridder_settings["ibound"] = (RegridderType.OVERLAP, "mode") + + regrid_context = RegridderWeightsCache() + + data = {"head": head, "ibound": ibound} + + regridded_package_data = _regrid_package_data( + data, target_idomain, regridder_settings, regrid_context, {} + ) + head = regridded_package_data["head"] + ibound = regridded_package_data["ibound"] + + # select locations where ibound < 0 + head = head.where(ibound < 0) + + # select locations where idomain > 0 + head = head.where(target_idomain > 0) + + regridded_package_data["head"] = head + regridded_package_data.pop("ibound") + + return cls(**regridded_package_data) diff --git a/imod/mf6/model_gwf.py b/imod/mf6/model_gwf.py index be0b9eb69..0c5f13e54 100644 --- a/imod/mf6/model_gwf.py +++ b/imod/mf6/model_gwf.py @@ -269,4 +269,16 @@ def from_imod5_data( hfb = LayeredHorizontalFlowBarrierResistance.from_imod5_dataset(imod5_data) result["hfb"] = hfb + # import chd + chd_keys = [key for key in imod5_keys if key[0:3] == "chd"] + if len(chd_keys) == 0: + result["chd_from_shd"] = ConstantHead.from_imod5_shd_data( + imod5_data, dis_pkg, regridder_types + ) + else: + for chd_key in chd_keys: + result[chd_key] = ConstantHead.from_imod5_data( + chd_key, imod5_data, dis_pkg, regridder_types + ) + return result diff --git a/imod/tests/test_mf6/test_mf6_chd.py b/imod/tests/test_mf6/test_mf6_chd.py index 4b33dd57e..571df6dec 100644 --- a/imod/tests/test_mf6/test_mf6_chd.py +++ b/imod/tests/test_mf6/test_mf6_chd.py @@ -7,6 +7,7 @@ import xarray as xr import imod +from imod.mf6.dis import StructuredDiscretization from imod.mf6.write_context import WriteContext from imod.schemata import ValidationError @@ -192,3 +193,40 @@ def test_write_concentration_period_data(head_fc, concentration_fc): assert ( data.count("2") == 1755 ) # the number 2 is in the concentration data, and in the cell indices. + + +@pytest.mark.usefixtures("imod5_dataset") +def test_from_imod5(imod5_dataset, tmp_path): + target_dis = StructuredDiscretization.from_imod5_data(imod5_dataset) + + chd3 = imod.mf6.ConstantHead.from_imod5_data( + "chd-3", + imod5_dataset, + target_dis, + regridder_types=None, + ) + + assert isinstance(chd3, imod.mf6.ConstantHead) + assert np.count_nonzero(~np.isnan(chd3.dataset["head"].values)) == 589 + assert len(chd3.dataset["layer"].values) == 1 + + # write the packages for write validation + write_context = WriteContext(simulation_directory=tmp_path, use_binary=False) + chd3.write("chd3", [1], write_context) + + +@pytest.mark.usefixtures("imod5_dataset") +def test_from_imod5_shd(imod5_dataset, tmp_path): + target_dis = StructuredDiscretization.from_imod5_data(imod5_dataset) + + chd_shd = imod.mf6.ConstantHead.from_imod5_shd_data( + imod5_dataset, + target_dis, + regridder_types=None, + ) + + assert isinstance(chd_shd, imod.mf6.ConstantHead) + assert len(chd_shd.dataset["layer"].values) == 37 + # write the packages for write validation + write_context = WriteContext(simulation_directory=tmp_path, use_binary=False) + chd_shd.write("chd_shd", [1], write_context) From 0da466aea65085c52cb630791595fb47da3b947e Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Fri, 28 Jun 2024 16:30:15 +0200 Subject: [PATCH 23/53] Issue #598 layered hfb error (#1089) Fixes #598 # Description There was some confusion (also by me) about the use of the ``LayeredHorizontalFlowBarrier`` classes, so @HendrikKok explained me they were intended for single layers. I therefore changed the following to clarify: - Rename to ``SingleLayerHorizontalFlowBarrier`` classes - Throw ``ValidationError`` if multiple layers are added to dataset - Added missing test for SingleLayerHorizontalFlowBarrier class This means multiple SingleLayerHorizontalFlowBarrier need to be added to GroundwaterFlowModel object, whereas MODFLOW 6 only accepts one single HFB. So these have to be merged together. I think the best opportunity for this is to merge the low level ``Mf6HorizontalFlowBarrier`` objects. # Checklist - [x] Links to correct issue - [x] Update changelog, if changes affect users - [x] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [x] Unit tests were added - [ ] **If feature added**: Added/extended example --- docs/api/changelog.rst | 5 +- imod/mf6/__init__.py | 6 +- imod/mf6/hfb.py | 93 ++++++++++++---------- imod/mf6/model.py | 2 +- imod/mf6/model_gwf.py | 10 ++- imod/mf6/riv.py | 3 + imod/schemata.py | 15 ++++ imod/tests/test_mf6/test_mf6_hfb.py | 83 ++++++++++++++++--- imod/tests/test_mf6/test_mf6_simulation.py | 5 ++ 9 files changed, 163 insertions(+), 59 deletions(-) diff --git a/docs/api/changelog.rst b/docs/api/changelog.rst index 7db57326d..d36c88837 100644 --- a/docs/api/changelog.rst +++ b/docs/api/changelog.rst @@ -55,7 +55,10 @@ Changed :class:`imod.mf6.regrid.RiverRegridMethod`, :class:`imod.mf6.regrid.SpecificStorageRegridMethod`, :class:`imod.mf6.regrid.StorageCoefficientRegridMethod`. - +- Renamed ``imod.mf6.LayeredHorizontalFlowBarrier`` classes to + :class:`imod.mf6.SingleLayerHorizontalFlowBarrierResistance`, + :class:`imod.mf6.SingleLayerHorizontalFlowBarrierHydraulicCharacteristic`, + :class:`imod.mf6.SingleLayerHorizontalFlowBarrierMultiplier`, Fixed ~~~~~ diff --git a/imod/mf6/__init__.py b/imod/mf6/__init__.py index d72b1bdb8..d6225b065 100644 --- a/imod/mf6/__init__.py +++ b/imod/mf6/__init__.py @@ -21,9 +21,9 @@ HorizontalFlowBarrierHydraulicCharacteristic, HorizontalFlowBarrierMultiplier, HorizontalFlowBarrierResistance, - LayeredHorizontalFlowBarrierHydraulicCharacteristic, - LayeredHorizontalFlowBarrierMultiplier, - LayeredHorizontalFlowBarrierResistance, + SingleLayerHorizontalFlowBarrierHydraulicCharacteristic, + SingleLayerHorizontalFlowBarrierMultiplier, + SingleLayerHorizontalFlowBarrierResistance, ) from imod.mf6.ic import InitialConditions from imod.mf6.ims import ( diff --git a/imod/mf6/hfb.py b/imod/mf6/hfb.py index 45d4460c6..c2f51773f 100644 --- a/imod/mf6/hfb.py +++ b/imod/mf6/hfb.py @@ -4,11 +4,10 @@ import typing from copy import deepcopy from enum import Enum -from typing import TYPE_CHECKING, List, Optional, Tuple +from typing import TYPE_CHECKING, Dict, Optional, Tuple import cftime import numpy as np -import pandas as pd import xarray as xr import xugrid as xu from fastcore.dispatch import typedispatch @@ -19,7 +18,7 @@ from imod.mf6.mf6_hfb_adapter import Mf6HorizontalFlowBarrier from imod.mf6.package import Package from imod.mf6.utilities.grid import broadcast_to_full_domain -from imod.schemata import EmptyIndexesSchema +from imod.schemata import EmptyIndexesSchema, MaxNUniqueValuesSchema from imod.typing import GridDataArray from imod.util.imports import MissingOptionalModule @@ -343,7 +342,6 @@ def to_mf6_pkg( top: GridDataArray, bottom: GridDataArray, k: GridDataArray, - validate: bool = False, ) -> Mf6HorizontalFlowBarrier: """ Write package to Modflow 6 package. @@ -362,16 +360,11 @@ def to_mf6_pkg( Grid with bottom of model layers. k: GridDataArray Grid with hydraulic conductivities. - validate: bool - Run validation before converting Returns ------- """ - if validate: - self._validate(self._write_schemata) - top, bottom = broadcast_to_full_domain(idomain, top, bottom) k = idomain * k unstructured_grid, top, bottom, k = ( @@ -680,7 +673,7 @@ def __remove_edge_values_connected_to_inactive_cells( class HorizontalFlowBarrierHydraulicCharacteristic(HorizontalFlowBarrierBase): """ - Horizontal Flow Barrier (HFB) package + Horizontal Flow Barrier (HFB) package Input to the Horizontal Flow Barrier (HFB) Package is read from the file that has type "HFB6" in the Name File. Only one HFB Package can be @@ -741,9 +734,11 @@ def _compute_barrier_values( return barrier_values -class LayeredHorizontalFlowBarrierHydraulicCharacteristic(HorizontalFlowBarrierBase): +class SingleLayerHorizontalFlowBarrierHydraulicCharacteristic( + HorizontalFlowBarrierBase +): """ - Horizontal Flow Barrier (HFB) package + Horizontal Flow Barrier (HFB) package Input to the Horizontal Flow Barrier (HFB) Package is read from the file that has type "HFB6" in the Name File. Only one HFB Package can be @@ -755,8 +750,10 @@ class LayeredHorizontalFlowBarrierHydraulicCharacteristic(HorizontalFlowBarrierB geometry: gpd.GeoDataFrame Dataframe that describes: - geometry: the geometries of the barriers, - - hydraulic_characteristic: the hydraulic characteristic of the barriers - - layer: model layer for the barrier + - hydraulic_characteristic: the hydraulic characteristic of the + barriers + - layer: model layer for the barrier, only 1 single layer can be + entered. print_input: bool Examples @@ -775,6 +772,11 @@ class LayeredHorizontalFlowBarrierHydraulicCharacteristic(HorizontalFlowBarrierB """ + _write_schemata = { + "geometry": [EmptyIndexesSchema()], + "layer": [MaxNUniqueValuesSchema(1)], + } + @init_log_decorator() def __init__( self, @@ -806,7 +808,7 @@ def _compute_barrier_values( class HorizontalFlowBarrierMultiplier(HorizontalFlowBarrierBase): """ - Horizontal Flow Barrier (HFB) package + Horizontal Flow Barrier (HFB) package Input to the Horizontal Flow Barrier (HFB) Package is read from the file that has type "HFB6" in the Name File. Only one HFB Package can be @@ -872,24 +874,23 @@ def _compute_barrier_values( return barrier_values -class LayeredHorizontalFlowBarrierMultiplier(HorizontalFlowBarrierBase): +class SingleLayerHorizontalFlowBarrierMultiplier(HorizontalFlowBarrierBase): """ - Horizontal Flow Barrier (HFB) package + Horizontal Flow Barrier (HFB) package Input to the Horizontal Flow Barrier (HFB) Package is read from the file that has type "HFB6" in the Name File. Only one HFB Package can be specified for a GWF model. https://water.usgs.gov/water-resources/software/MODFLOW-6/mf6io_6.2.2.pdf - If parts of the barrier overlap a layer the multiplier is applied to the entire layer. - Parameters ---------- geometry: gpd.GeoDataFrame Dataframe that describes: - geometry: the geometries of the barriers, - multiplier: the multiplier of the barriers - - layer: model layer for the barrier + - layer: model layer for the barrier, only 1 single layer can be + entered. print_input: bool Examples @@ -908,6 +909,11 @@ class LayeredHorizontalFlowBarrierMultiplier(HorizontalFlowBarrierBase): """ + _write_schemata = { + "geometry": [EmptyIndexesSchema()], + "layer": [MaxNUniqueValuesSchema(1)], + } + @init_log_decorator() def __init__( self, @@ -1021,7 +1027,7 @@ def _compute_barrier_values( return barrier_values -class LayeredHorizontalFlowBarrierResistance(HorizontalFlowBarrierBase): +class SingleLayerHorizontalFlowBarrierResistance(HorizontalFlowBarrierBase): """ Horizontal Flow Barrier (HFB) package @@ -1036,7 +1042,8 @@ class LayeredHorizontalFlowBarrierResistance(HorizontalFlowBarrierBase): Dataframe that describes: - geometry: the geometries of the barriers, - resistance: the resistance of the barriers - - layer: model layer for the barrier + - layer: model layer for the barrier, only 1 single layer can be + entered. print_input: bool Examples @@ -1056,6 +1063,11 @@ class LayeredHorizontalFlowBarrierResistance(HorizontalFlowBarrierBase): """ + _write_schemata = { + "geometry": [EmptyIndexesSchema()], + "layer": [MaxNUniqueValuesSchema(1)], + } + @init_log_decorator() def __init__( self, @@ -1084,25 +1096,22 @@ def _compute_barrier_values( return barrier_values @classmethod - def from_imod5_dataset(cls, imod5_data: dict[str, dict[str, GridDataArray]]): + def from_imod5_dataset( + cls, key: str, imod5_data: Dict[str, Dict[str, GridDataArray]] + ): imod5_keys = list(imod5_data.keys()) - hfb_keys = [key for key in imod5_keys if key[0:3] == "hfb"] - if len(hfb_keys) == 0: - raise ValueError("no hfb keys present.") - - dataframe_ls: List[gpd.GeoDataFrame] = [] - for hfb_key in hfb_keys: - hfb_dict = imod5_data[hfb_key] - if not list(hfb_dict.keys()) == ["geodataframe", "layer"]: - raise ValueError("hfb is not a LayeredHorizontalFlowBarrierResistance") - layer = hfb_dict["layer"] - if layer == 0: - raise ValueError( - "assigning to layer 0 is not supported yet for import of HFB's" - ) - geometry_layer = hfb_dict["geodataframe"] - geometry_layer["layer"] = layer - dataframe_ls.append(geometry_layer) - compound_dataframe = pd.concat(dataframe_ls, ignore_index=True) + if key not in imod5_keys: + raise ValueError("hfb key not present.") + + hfb_dict = imod5_data[key] + if not list(hfb_dict.keys()) == ["geodataframe", "layer"]: + raise ValueError("hfb is not a SingleLayerHorizontalFlowBarrierResistance") + layer = hfb_dict["layer"] + if layer == 0: + raise ValueError( + "assigning to layer 0 is not supported yet for import of HFB's" + ) + geometry_layer = hfb_dict["geodataframe"] + geometry_layer["layer"] = layer - return LayeredHorizontalFlowBarrierResistance(compound_dataframe) + return cls(geometry_layer) diff --git a/imod/mf6/model.py b/imod/mf6/model.py index f3a5cc20a..2293425e8 100644 --- a/imod/mf6/model.py +++ b/imod/mf6/model.py @@ -274,7 +274,7 @@ def write( elif isinstance(pkg, imod.mf6.HorizontalFlowBarrierBase): top, bottom, idomain = self.__get_domain_geometry() k = self.__get_k() - mf6_hfb_pkg = pkg.to_mf6_pkg(idomain, top, bottom, k, validate) + mf6_hfb_pkg = pkg.to_mf6_pkg(idomain, top, bottom, k) mf6_hfb_pkg.write( pkgname=pkg_name, globaltimes=globaltimes, diff --git a/imod/mf6/model_gwf.py b/imod/mf6/model_gwf.py index 0c5f13e54..58e67fee2 100644 --- a/imod/mf6/model_gwf.py +++ b/imod/mf6/model_gwf.py @@ -11,7 +11,7 @@ from imod.mf6.clipped_boundary_condition_creator import create_clipped_boundary from imod.mf6.dis import StructuredDiscretization from imod.mf6.drn import Drainage -from imod.mf6.hfb import LayeredHorizontalFlowBarrierResistance +from imod.mf6.hfb import SingleLayerHorizontalFlowBarrierResistance from imod.mf6.ic import InitialConditions from imod.mf6.model import Modflow6Model from imod.mf6.npf import NodePropertyFlow @@ -266,8 +266,12 @@ def from_imod5_data( # import hfb hfb_keys = [key for key in imod5_keys if key[0:3] == "hfb"] if len(hfb_keys) != 0: - hfb = LayeredHorizontalFlowBarrierResistance.from_imod5_dataset(imod5_data) - result["hfb"] = hfb + for hfb_key in hfb_keys: + result[hfb_key] = ( + SingleLayerHorizontalFlowBarrierResistance.from_imod5_dataset( + hfb_key, imod5_data + ) + ) # import chd chd_keys = [key for key in imod5_keys if key[0:3] == "chd"] diff --git a/imod/mf6/riv.py b/imod/mf6/riv.py index 50a90c605..6720bf17e 100644 --- a/imod/mf6/riv.py +++ b/imod/mf6/riv.py @@ -203,6 +203,9 @@ def from_imod5_data( Parameters ---------- + key: str + Packagename of the package that needs to be converted to river + package. imod5_data: dict Dictionary with iMOD5 data. This can be constructed from the :func:`imod.formats.prj.open_projectfile_data` method. diff --git a/imod/schemata.py b/imod/schemata.py index a61308d64..95b5d6a3a 100644 --- a/imod/schemata.py +++ b/imod/schemata.py @@ -503,6 +503,21 @@ def validate(self, obj: GridDataArray, **kwargs) -> None: ) +class MaxNUniqueValuesSchema(BaseSchema): + """ + Fails if amount of unique values exceeds a limit. + """ + + def __init__(self, max_unique_values: int): + self.max_unique_values = max_unique_values + + def validate(self, obj: GridDataArray, **kwargs) -> None: + if len(np.unique(obj)) > self.max_unique_values: + raise ValidationError( + f"Amount of unique values exceeds limit of {self.max_unique_values}" + ) + + class UniqueValuesSchema(BaseSchema): def __init__(self, other_value: list) -> None: """ diff --git a/imod/tests/test_mf6/test_mf6_hfb.py b/imod/tests/test_mf6/test_mf6_hfb.py index 81a242d16..eaf822ff0 100644 --- a/imod/tests/test_mf6/test_mf6_hfb.py +++ b/imod/tests/test_mf6/test_mf6_hfb.py @@ -12,9 +12,9 @@ HorizontalFlowBarrierHydraulicCharacteristic, HorizontalFlowBarrierMultiplier, HorizontalFlowBarrierResistance, - LayeredHorizontalFlowBarrierHydraulicCharacteristic, - LayeredHorizontalFlowBarrierMultiplier, - LayeredHorizontalFlowBarrierResistance, + SingleLayerHorizontalFlowBarrierHydraulicCharacteristic, + SingleLayerHorizontalFlowBarrierMultiplier, + SingleLayerHorizontalFlowBarrierResistance, ) from imod.mf6.dis import StructuredDiscretization from imod.mf6.hfb import to_connected_cells_dataset @@ -153,10 +153,10 @@ def test_to_mf6_creates_mf6_adapter( @pytest.mark.parametrize( "barrier_class, barrier_value_name, barrier_value, expected_hydraulic_characteristic", [ - (LayeredHorizontalFlowBarrierResistance, "resistance", 1e3, 1e-3), - (LayeredHorizontalFlowBarrierMultiplier, "multiplier", 1.5, -1.5), + (SingleLayerHorizontalFlowBarrierResistance, "resistance", 1e3, 1e-3), + (SingleLayerHorizontalFlowBarrierMultiplier, "multiplier", 1.5, -1.5), ( - LayeredHorizontalFlowBarrierHydraulicCharacteristic, + SingleLayerHorizontalFlowBarrierHydraulicCharacteristic, "hydraulic_characteristic", 1e-3, 1e-3, @@ -195,7 +195,7 @@ def test_to_mf6_creates_mf6_adapter_layered( hfb = barrier_class(geometry, print_input) # Act. - _ = hfb.to_mf6_pkg(idomain, top, bottom, k, False) + _ = hfb.to_mf6_pkg(idomain, top, bottom, k) # Assert. snapped, _ = xu.snap_to_grid(geometry, grid=idomain, max_snap_distance=0.5) @@ -282,6 +282,69 @@ def test_to_mf6_different_z_boundaries( assert_array_equal(max_values_per_layer, 1.0 / expected_values) +@pytest.mark.parametrize( + "layer, expected_values", + [ + (2, np.array([1e3, 1e3, 1e3, 1e3, 1e3, 1e3, 1e3, 1e3])), # 2nd layer + ], +) +@patch("imod.mf6.mf6_hfb_adapter.Mf6HorizontalFlowBarrier.__new__", autospec=True) +def test_to_mf6_layered_hfb(mf6_flow_barrier_mock, basic_dis, layer, expected_values): + # Arrange. + idomain, top, bottom = basic_dis + k = ones_like(top) + + print_input = False + + barrier_y = [5.5, 5.5, 5.5] + barrier_x = [82.0, 40.0, 0.0] + + geometry = gpd.GeoDataFrame( + geometry=[shapely.linestrings(barrier_x, barrier_y)], + data={ + "resistance": [1e3], + "layer": [layer], + }, + ) + + hfb = SingleLayerHorizontalFlowBarrierResistance(geometry, print_input) + + # Act. + _ = hfb.to_mf6_pkg(idomain, top, bottom, k) + + # Assert. + _, args = mf6_flow_barrier_mock.call_args + barrier_values = args["hydraulic_characteristic"].values + assert_array_equal(barrier_values, 1.0 / expected_values) + expected_layer = np.full((8,), layer) + barrier_layer = args["layer"].values + assert_array_equal(barrier_layer, expected_layer) + + +def test_to_mf6_layered_hfb__error(): + """Throws error because multiple layers attached to one object.""" + # Arrange. + print_input = False + + barrier_y = [5.5, 5.5, 5.5] + barrier_x = [82.0, 40.0, 0.0] + + linestring = shapely.linestrings(barrier_x, barrier_y) + + geometry = gpd.GeoDataFrame( + geometry=[linestring, linestring], + data={ + "resistance": [1e3, 1e3], + "layer": [1, 2], + }, + ) + + hfb = SingleLayerHorizontalFlowBarrierResistance(geometry, print_input) + errors = hfb._validate(hfb._write_schemata) + + assert len(errors) > 0 + + @pytest.mark.parametrize( "barrier_x_loc, expected_number_barriers", [ @@ -451,8 +514,10 @@ def test_hfb_from_imod5(imod5_dataset, tmp_path): imod5_dataset, target_dis.dataset["idomain"] ) - hfb = LayeredHorizontalFlowBarrierResistance.from_imod5_dataset(imod5_dataset) + hfb = SingleLayerHorizontalFlowBarrierResistance.from_imod5_dataset( + "hfb-3", imod5_dataset + ) hfb_package = hfb.to_mf6_pkg( target_dis["idomain"], target_dis["top"], target_dis["bottom"], target_npf["k"] ) - assert list(np.unique(hfb_package["layer"].values)) == [3, 21] + assert list(np.unique(hfb_package["layer"].values)) == [7] diff --git a/imod/tests/test_mf6/test_mf6_simulation.py b/imod/tests/test_mf6/test_mf6_simulation.py index 3e9dda2dd..dccba0b04 100644 --- a/imod/tests/test_mf6/test_mf6_simulation.py +++ b/imod/tests/test_mf6/test_mf6_simulation.py @@ -485,5 +485,10 @@ def test_import_from_imod5(imod5_dataset, tmp_path): simulation.create_time_discretization(["01-01-2003", "02-01-2003"]) + # Remove HFB packages outside domain + # TODO: Build in support for hfb packages outside domain + for hfb_outside in ["hfb-24", "hfb-26"]: + simulation["imported_model"].pop(hfb_outside) + # write and validate the simulation. simulation.write(tmp_path, binary=False, validate=True) From 41dac1c065516912c7900b6f7321ef4a2aa5ec97 Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Wed, 3 Jul 2024 14:46:33 +0200 Subject: [PATCH 24/53] Issue #1090 merge mf6hfb (#1093) Fixes #1090 # Description This changeset implements the following: - Renames LayeredHorizontalFlowBarrier to SingleLayerHorizontalFlowBarrier - Moves duplictate logic into ``Package._from_dataset`` to construct package from a dataset - Adds function to merge multiple HFBs into a low-level single hfb mf6 adapter - Collect HFB packages into single list ``Model.write()`` and merge them with function - ``_prepare_barrier_dataset_for_mf6_adapter`` function to prepare some required coordinate differences # Checklist - [x] Links to correct issue - [x] Update changelog, if changes affect users - [x] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [x] Unit tests were added - [ ] **If feature added**: Added/extended example --- docs/api/changelog.rst | 5 + imod/mf6/hfb.py | 119 ++++++--- imod/mf6/interfaces/ipackagebase.py | 7 + imod/mf6/model.py | 39 ++- imod/mf6/package.py | 4 +- imod/mf6/pkgbase.py | 14 +- imod/mf6/utilities/clip.py | 8 +- imod/mf6/utilities/hfb.py | 67 ++++++ imod/mf6/wel.py | 4 +- imod/tests/test_mf6/test_mf6_hfb.py | 75 +++++- imod/tests/test_mf6/test_package_sanity.py | 9 + .../tests/test_mf6/test_utilities/test_hfb.py | 225 ++++++++++++++++++ 12 files changed, 520 insertions(+), 56 deletions(-) create mode 100644 imod/mf6/utilities/hfb.py create mode 100644 imod/tests/test_mf6/test_utilities/test_hfb.py diff --git a/docs/api/changelog.rst b/docs/api/changelog.rst index d36c88837..d95994d0a 100644 --- a/docs/api/changelog.rst +++ b/docs/api/changelog.rst @@ -9,6 +9,11 @@ The format is based on `Keep a Changelog`_, and this project adheres to [Unreleased- feature branch] ---------------------------- +Fixed +~~~~~ +- ``HorizontalFlowBarrier`` attached to :class:`imod.mf6.GroundwaterFlowModel` + are merged into a single horizontal flow barrier for MODFLOW 6 + Changed ~~~~~~~ diff --git a/imod/mf6/hfb.py b/imod/mf6/hfb.py index c2f51773f..682386d94 100644 --- a/imod/mf6/hfb.py +++ b/imod/mf6/hfb.py @@ -175,10 +175,8 @@ def to_connected_cells_dataset( }, ) - barrier_dataset = ( - barrier_dataset.stack(cell_id=("layer", "edge_index"), create_index=False) - .drop_vars("edge_index") - .reset_coords() + barrier_dataset = barrier_dataset.stack( + cell_id=("layer", "edge_index"), create_index=True ) return barrier_dataset.dropna("cell_id") @@ -272,6 +270,26 @@ def _vectorized_overlap(bounds_a: np.ndarray, bounds_b: np.ndarray): ) +def _prepare_barrier_dataset_for_mf6_adapter(dataset: xr.Dataset) -> xr.Dataset: + """ + Prepare barrier dataset for the initialization of Mf6HorizontalFlowBarrier. + The dataset is expected to have "edge_index" and "layer" coordinates and a + multi-index "cell_id" coordinate. The dataset contains as variables: + "cell_id1", "cell_id2", and "hydraulic_characteristic". + + - Reset coords to get a coordless "cell_id" dimension instead of a multi-index coord + - Assign "layer" as variable to dataset instead of as coord. + """ + # Store layer to work around multiindex issue where dropping the edge_index + # removes the layer as well. + layer = dataset.coords["layer"].values + # Drop leftover coordinate and reset cell_id. + dataset = dataset.drop_vars("edge_index").reset_coords() + # Attach layer again + dataset["layer"] = ("cell_id", layer) + return dataset + + class BarrierType(Enum): HydraulicCharacteristic = 0 Multiplier = 1 @@ -336,34 +354,29 @@ def _compute_barrier_values( ): raise NotImplementedError() - def to_mf6_pkg( + def _to_connected_cells_dataset( self, idomain: GridDataArray, top: GridDataArray, bottom: GridDataArray, k: GridDataArray, - ) -> Mf6HorizontalFlowBarrier: + ) -> xr.Dataset: """ - Write package to Modflow 6 package. - - Based on the model grid, top and bottoms, the layers in which the barrier belong are computed. If the - barrier only partially occupies a layer an effective resistance or hydraulic conductivity for that layer is - calculated. This calculation is skipped for the Multiplier type. - - Parameters - ---------- - idomain: GridDataArray - Grid with active cells. - top: GridDataArray - Grid with top of model layers. - bottom: GridDataArray - Grid with bottom of model layers. - k: GridDataArray - Grid with hydraulic conductivities. + Method does the following + - forces input grids to unstructured + - snaps lines to cell edges + - remove edge values connected to cell edges + - compute barrier values + - remove edge values to inactive cells + - finds connected cells in dataset Returns ------- - + dataset with connected cells, containing: + - cell_id1 + - cell_id2 + - layer + - value name """ top, bottom = broadcast_to_full_domain(idomain, top, bottom) k = idomain * k @@ -372,7 +385,7 @@ def to_mf6_pkg( if isinstance(idomain, xr.DataArray) else [idomain, top, bottom, k] ) - snapped_dataset, edge_index = self.__snap_to_grid(idomain) + snapped_dataset, edge_index = self._snap_to_grid(idomain) edge_index = self.__remove_invalid_edges(unstructured_grid, edge_index) barrier_values = self._compute_barrier_values( @@ -395,7 +408,7 @@ def to_mf6_pkg( ) ) - barrier_dataset = to_connected_cells_dataset( + return to_connected_cells_dataset( idomain, unstructured_grid.ugrid.grid, edge_index, @@ -406,10 +419,59 @@ def to_mf6_pkg( }, ) - barrier_dataset["print_input"] = self.dataset["print_input"] + def _to_mf6_pkg(self, barrier_dataset: xr.Dataset) -> Mf6HorizontalFlowBarrier: + """ + Internal method, which does the following + - final coordinate cleanup of barrier dataset + - adds missing options to dataset + + Parameters + ---------- + barrier_dataset: xr.Dataset + Xarray dataset with dimensions "cell_dims1", "cell_dims2", "cell_id". + Additional coordinates should be "layer" and "edge_index". + Returns + ------- + Mf6HorizontalFlowBarrier + """ + barrier_dataset["print_input"] = self.dataset["print_input"] + barrier_dataset = _prepare_barrier_dataset_for_mf6_adapter(barrier_dataset) return Mf6HorizontalFlowBarrier(**barrier_dataset.data_vars) + def to_mf6_pkg( + self, + idomain: GridDataArray, + top: GridDataArray, + bottom: GridDataArray, + k: GridDataArray, + ) -> Mf6HorizontalFlowBarrier: + """ + Write package to Modflow 6 package. + + Based on the model grid, top and bottoms, the layers in which the barrier belong are computed. If the + barrier only partially occupies a layer an effective resistance or hydraulic conductivity for that layer is + calculated. This calculation is skipped for the Multiplier type. + + Parameters + ---------- + idomain: GridDataArray + Grid with active cells. + top: GridDataArray + Grid with top of model layers. + bottom: GridDataArray + Grid with bottom of model layers. + k: GridDataArray + Grid with hydraulic conductivities. + + Returns + ------- + Mf6HorizontalFlowBarrier + Low level representation of the HFB package as MODFLOW 6 expects it. + """ + barrier_dataset = self._to_connected_cells_dataset(idomain, top, bottom, k) + return self._to_mf6_pkg(barrier_dataset) + def is_empty(self) -> bool: if super().is_empty(): return True @@ -574,8 +636,7 @@ def clip_box( sliced : Package """ cls = type(self) - new = cls.__new__(cls) - new.dataset = copy.deepcopy(self.dataset) + new = cls._from_dataset(copy.deepcopy(self.dataset)) new.line_data = self.line_data return new @@ -599,7 +660,7 @@ def __to_unstructured( return unstruct, top, bottom, k - def __snap_to_grid( + def _snap_to_grid( self, idomain: GridDataArray ) -> Tuple[xu.UgridDataset, np.ndarray]: if "layer" in self.dataset: diff --git a/imod/mf6/interfaces/ipackagebase.py b/imod/mf6/interfaces/ipackagebase.py index 038e20876..6351fe79d 100644 --- a/imod/mf6/interfaces/ipackagebase.py +++ b/imod/mf6/interfaces/ipackagebase.py @@ -2,6 +2,8 @@ import xarray as xr +from imod.typing import GridDataset + class IPackageBase(ABC): """ @@ -17,3 +19,8 @@ def dataset(self) -> xr.Dataset: @abstractmethod def dataset(self, value: xr.Dataset) -> None: raise NotImplementedError + + @classmethod + @abstractmethod + def _from_dataset(self, ds: GridDataset): + raise NotImplementedError diff --git a/imod/mf6/model.py b/imod/mf6/model.py index 2293425e8..da1eb450c 100644 --- a/imod/mf6/model.py +++ b/imod/mf6/model.py @@ -6,7 +6,7 @@ import pathlib from copy import deepcopy from pathlib import Path -from typing import Any, Optional, Tuple, Union +from typing import Any, List, Optional, Tuple, Union import cftime import jinja2 @@ -19,9 +19,11 @@ import imod from imod.logging import standard_log_decorator +from imod.mf6.hfb import HorizontalFlowBarrierBase from imod.mf6.interfaces.imodel import IModel from imod.mf6.package import Package from imod.mf6.statusinfo import NestedStatusInfo, StatusInfo, StatusInfoBase +from imod.mf6.utilities.hfb import merge_hfb_packages from imod.mf6.utilities.mask import _mask_all_packages from imod.mf6.utilities.regrid import RegridderWeightsCache, _regrid_like from imod.mf6.validation import pkg_errors_to_status_info @@ -30,6 +32,8 @@ from imod.typing import GridDataArray from imod.typing.grid import is_spatial_grid +HFB_PKGNAME = "hfb_merged" + class Modflow6Model(collections.UserDict, IModel, abc.ABC): _mandatory_packages: tuple[str, ...] = () @@ -145,12 +149,20 @@ def render(self, modelname: str, write_context: WriteContext): d = {k: v for k, v in self._options.items() if not (v is None or v is False)} packages = [] + has_hfb = False for pkgname, pkg in self.items(): # Add the six to the package id pkg_id = pkg._pkg_id + # Skip if hfb + if pkg_id == "hfb": + has_hfb = True + continue key = f"{pkg_id}6" path = dir_for_render / f"{pkgname}.{pkg_id}" packages.append((key, path.as_posix(), pkgname)) + if has_hfb: + path = dir_for_render / f"{HFB_PKGNAME}.hfb" + packages.append(("hfb6", path.as_posix(), HFB_PKGNAME)) d["packages"] = packages return self._template.render(d) @@ -252,6 +264,7 @@ def write( pkg_write_context = write_context.copy_with_new_write_directory( new_write_directory=modeldirectory ) + mf6_hfb_ls: List[HorizontalFlowBarrierBase] = [] for pkg_name, pkg in self.items(): try: if isinstance(pkg, imod.mf6.Well): @@ -265,21 +278,13 @@ def write( validate, pkg_write_context.is_partitioned, ) - mf6_well_pkg.write( pkgname=pkg_name, globaltimes=globaltimes, write_context=pkg_write_context, ) elif isinstance(pkg, imod.mf6.HorizontalFlowBarrierBase): - top, bottom, idomain = self.__get_domain_geometry() - k = self.__get_k() - mf6_hfb_pkg = pkg.to_mf6_pkg(idomain, top, bottom, k) - mf6_hfb_pkg.write( - pkgname=pkg_name, - globaltimes=globaltimes, - write_context=pkg_write_context, - ) + mf6_hfb_ls.append(pkg) else: pkg.write( pkgname=pkg_name, @@ -289,6 +294,20 @@ def write( except Exception as e: raise type(e)(f"{e}\nError occured while writing {pkg_name}") + if len(mf6_hfb_ls) > 0: + try: + pkg_name = HFB_PKGNAME + top, bottom, idomain = self.__get_domain_geometry() + k = self.__get_k() + mf6_hfb_pkg = merge_hfb_packages(mf6_hfb_ls, idomain, top, bottom, k) + mf6_hfb_pkg.write( + pkgname=pkg_name, + globaltimes=globaltimes, + write_context=pkg_write_context, + ) + except Exception as e: + raise type(e)(f"{e}\nError occured while writing {pkg_name}") + return NestedStatusInfo(modelname) @standard_log_decorator() diff --git a/imod/mf6/package.py b/imod/mf6/package.py index c046154cf..fb35785ba 100644 --- a/imod/mf6/package.py +++ b/imod/mf6/package.py @@ -516,9 +516,7 @@ def clip_box( selection = selection.sel(x=x_slice, y=y_slice) cls = type(self) - new = cls.__new__(cls) - new.dataset = selection - return new + return cls._from_dataset(selection) def mask(self, mask: GridDataArray) -> Any: """ diff --git a/imod/mf6/pkgbase.py b/imod/mf6/pkgbase.py index de1051893..477840d34 100644 --- a/imod/mf6/pkgbase.py +++ b/imod/mf6/pkgbase.py @@ -67,6 +67,16 @@ def _netcdf_encoding(self): """ return {} + @classmethod + def _from_dataset(cls, ds: GridDataset): + """ + Create package from dataset. Note that no initialization validation is + done. + """ + instance = cls.__new__(cls) + instance.dataset = ds + return instance + @classmethod def from_file(cls, path, **kwargs): """ @@ -120,6 +130,4 @@ def from_file(cls, path, **kwargs): if isinstance(stripped_value, numbers.Real) and np.isnan(stripped_value): # type: ignore[call-overload] dataset[key] = None - instance = cls.__new__(cls) - instance.dataset = dataset - return instance + return cls._from_dataset(dataset) diff --git a/imod/mf6/utilities/clip.py b/imod/mf6/utilities/clip.py index b574cf88e..c0f696e63 100644 --- a/imod/mf6/utilities/clip.py +++ b/imod/mf6/utilities/clip.py @@ -50,9 +50,7 @@ def clip_by_grid(package: IPackageBase, active: xu.UgridDataArray) -> IPackageBa clipped_dataset = package.dataset.isel(domain_slice, missing_dims="ignore") cls = type(package) - new = cls.__new__(cls) - new.dataset = clipped_dataset - return new + return cls._from_dataset(clipped_dataset) @typedispatch # type: ignore[no-redef] @@ -70,9 +68,7 @@ def clip_by_grid( # noqa: F811 selection = package.dataset.loc[{"index": is_inside_exterior}] cls = type(package) - new = cls.__new__(cls) - new.dataset = selection - return new + return cls._from_dataset(selection) def _filter_inactive_cells(package, active): diff --git a/imod/mf6/utilities/hfb.py b/imod/mf6/utilities/hfb.py new file mode 100644 index 000000000..82a70f4d1 --- /dev/null +++ b/imod/mf6/utilities/hfb.py @@ -0,0 +1,67 @@ +from typing import List + +import xarray as xr + +from imod.mf6.hfb import ( + HorizontalFlowBarrierBase, + _prepare_barrier_dataset_for_mf6_adapter, +) +from imod.mf6.mf6_hfb_adapter import Mf6HorizontalFlowBarrier +from imod.typing import GridDataArray + + +def inverse_sum(a: xr.Dataset) -> xr.Dataset: + """Sum of the inverse""" + return (1 / a).sum() + + +def merge_hfb_packages( + hfb_ls: List[HorizontalFlowBarrierBase], + idomain: GridDataArray, + top: GridDataArray, + bottom: GridDataArray, + k: GridDataArray, +) -> Mf6HorizontalFlowBarrier: + """ + Merges HorizontalFlowBarrier packages into single package as MODFLOW 6 + doesn't support multiple HFB packages. + + Parameters + ---------- + hfb_ls: list + List of HorizontalFlowBarrier packages. These will be merged into one. + Function takes settings like "print_input" from the first object in the + list. + idomain: GridDataArray + Grid with active cells. + top: GridDataArray + Grid with top of model layers. + bottom: GridDataArray + Grid with bottom of model layers. + k: GridDataArray + Grid with hydraulic conductivities. + """ + + barrier_ls = [ + hfb._to_connected_cells_dataset(idomain, top, bottom, k) for hfb in hfb_ls + ] + barrier_dataset = xr.concat(barrier_ls, dim="cell_id") + + # xarray GroupbyDataset doesn't allow reducing with different methods per variable. + # Therefore groupby twice: once for cell_id, once for hydraulic_characteristic. + cell_id_merged = ( + barrier_dataset[["cell_id1", "cell_id2"]].groupby("cell_id").first() + ) + hc_merged = 1 / barrier_dataset[["hydraulic_characteristic"]].groupby( + "cell_id" + ).map(inverse_sum) + # Force correct dim order + cell_id_merged = cell_id_merged.transpose("cell_dims1", "cell_dims2", "cell_id") + # Merge datasets into one + barrier_dataset_merged = xr.merge([cell_id_merged, hc_merged], join="exact") + # Set leftover options + barrier_dataset_merged["print_input"] = hfb_ls[0].dataset["print_input"] + barrier_dataset_merged = _prepare_barrier_dataset_for_mf6_adapter( + barrier_dataset_merged + ) + return Mf6HorizontalFlowBarrier(**barrier_dataset_merged.data_vars) diff --git a/imod/mf6/wel.py b/imod/mf6/wel.py index 07d361b4e..f05d1b0e8 100644 --- a/imod/mf6/wel.py +++ b/imod/mf6/wel.py @@ -65,9 +65,7 @@ def mask_2D(package: Well, domain_2d: GridDataArray) -> Well: selection = package.dataset.loc[{"index": is_inside_exterior}] cls = type(package) - new = cls.__new__(cls) - new.dataset = selection - return new + return cls._from_dataset(selection) class Well(BoundaryCondition, IPointDataPackage): diff --git a/imod/tests/test_mf6/test_mf6_hfb.py b/imod/tests/test_mf6/test_mf6_hfb.py index eaf822ff0..6468e293e 100644 --- a/imod/tests/test_mf6/test_mf6_hfb.py +++ b/imod/tests/test_mf6/test_mf6_hfb.py @@ -17,11 +17,16 @@ SingleLayerHorizontalFlowBarrierResistance, ) from imod.mf6.dis import StructuredDiscretization -from imod.mf6.hfb import to_connected_cells_dataset +from imod.mf6.hfb import ( + _prepare_barrier_dataset_for_mf6_adapter, + to_connected_cells_dataset, +) +from imod.mf6.ims import SolutionPresetSimple from imod.mf6.npf import NodePropertyFlow +from imod.mf6.simulation import Modflow6Simulation from imod.mf6.utilities.regrid import RegridderWeightsCache from imod.tests.fixtures.flow_basic_fixture import BasicDisSettings -from imod.typing.grid import ones_like +from imod.typing.grid import nan_like, ones_like @pytest.mark.parametrize("dis", ["basic_unstructured_dis", "basic_dis"]) @@ -90,6 +95,7 @@ def test_to_mf6_creates_mf6_adapter_init( expected_values = to_connected_cells_dataset( idomain, grid, edge_index, {barrier_value_name: expected_barrier_values} ) + expected_values = _prepare_barrier_dataset_for_mf6_adapter(expected_values) mf6_flow_barrier_mock.assert_called_once() @@ -218,6 +224,7 @@ def test_to_mf6_creates_mf6_adapter_layered( expected_values = to_connected_cells_dataset( idomain, grid, edge_index, {barrier_value_name: expected_barrier_values} ) + expected_values = _prepare_barrier_dataset_for_mf6_adapter(expected_values) mf6_flow_barrier_mock.assert_called_once() @@ -521,3 +528,67 @@ def test_hfb_from_imod5(imod5_dataset, tmp_path): target_dis["idomain"], target_dis["top"], target_dis["bottom"], target_npf["k"] ) assert list(np.unique(hfb_package["layer"].values)) == [7] + + +@pytest.mark.usefixtures("structured_flow_model") +def test_run_multiple_hfbs(tmp_path, structured_flow_model): + # Single layered model + structured_flow_model = structured_flow_model.clip_box(layer_max=1) + structured_flow_model["dis"]["bottom"] = structured_flow_model["dis"][ + "bottom" + ].isel(x=0, y=0, drop=True) + # Arrange boundary conditions into something simple: + # A linear decline from left to right, forced by chd + structured_flow_model.pop("rch") + chd_head = nan_like(structured_flow_model["chd"].dataset["head"]) + chd_head[:, :, 0] = 10.0 + chd_head[:, :, -1] = 0.0 + structured_flow_model["chd"].dataset["head"] = chd_head + + barrier_y = [11.0, 5.0, -1.0] + barrier_x = [5.0, 5.0, 5.0] + + geometry = gpd.GeoDataFrame( + geometry=[shapely.linestrings(barrier_x, barrier_y)], + data={ + "resistance": [1200.0], + "layer": [1], + }, + ) + + simulation_single = Modflow6Simulation("single_hfb") + structured_flow_model["hfb"] = SingleLayerHorizontalFlowBarrierResistance(geometry) + simulation_single["GWF"] = structured_flow_model + simulation_single["solver"] = SolutionPresetSimple(["GWF"]) + simulation_single.create_time_discretization(["2000-01-01", "2000-01-02"]) + simulation_single.write(tmp_path / "single") + simulation_single.run() + head_single = simulation_single.open_head() + + geometry = gpd.GeoDataFrame( + geometry=[shapely.linestrings(barrier_x, barrier_y)], + data={ + "resistance": [400.0], + "layer": [1], + }, + ) + + simulation_triple = Modflow6Simulation("triple_hfb") + structured_flow_model.pop("hfb") # Remove high resistance HFB package now. + structured_flow_model["hfb-1"] = SingleLayerHorizontalFlowBarrierResistance( + geometry + ) + structured_flow_model["hfb-2"] = SingleLayerHorizontalFlowBarrierResistance( + geometry + ) + structured_flow_model["hfb-3"] = SingleLayerHorizontalFlowBarrierResistance( + geometry + ) + simulation_triple["GWF"] = structured_flow_model + simulation_triple["solver"] = SolutionPresetSimple(["GWF"]) + simulation_triple.create_time_discretization(["2000-01-01", "2000-01-02"]) + simulation_triple.write(tmp_path / "triple") + simulation_triple.run() + head_triple = simulation_triple.open_head() + + xr.testing.assert_equal(head_single, head_triple) diff --git a/imod/tests/test_mf6/test_package_sanity.py b/imod/tests/test_mf6/test_package_sanity.py index 95ded8f19..545eb3d4a 100644 --- a/imod/tests/test_mf6/test_package_sanity.py +++ b/imod/tests/test_mf6/test_package_sanity.py @@ -108,3 +108,12 @@ def test_save_and_load(instance, tmp_path): def test_repr(instance): assert isinstance(instance.__repr__(), str) assert isinstance(instance._repr_html_(), str) + + +@pytest.mark.parametrize("instance", ALL_PACKAGE_INSTANCES) +def test_from_dataset(instance): + pkg_class = type(instance) + ds = instance.dataset + new_instance = pkg_class._from_dataset(ds) + assert isinstance(new_instance, pkg_class) + assert instance.dataset.equals(new_instance.dataset) diff --git a/imod/tests/test_mf6/test_utilities/test_hfb.py b/imod/tests/test_mf6/test_utilities/test_hfb.py new file mode 100644 index 000000000..4c0abd189 --- /dev/null +++ b/imod/tests/test_mf6/test_utilities/test_hfb.py @@ -0,0 +1,225 @@ +import geopandas as gpd +import numpy as np +import pytest +import shapely +import xarray as xr + +from imod.mf6.hfb import ( + HorizontalFlowBarrierResistance, + SingleLayerHorizontalFlowBarrierResistance, +) +from imod.mf6.utilities.hfb import merge_hfb_packages + + +@pytest.mark.usefixtures("structured_flow_model") +@pytest.fixture(scope="function") +def modellayers_single_layer(structured_flow_model): + model = structured_flow_model.clip_box(layer_max=1) + dis = model["dis"] + dis["bottom"] = dis["bottom"].isel(x=0, y=0, drop=True) + npf = model["npf"] + + return { + "idomain": dis["idomain"], + "top": dis["top"], + "bottom": dis["bottom"], + "k": npf["k"], + } + + +@pytest.mark.usefixtures("structured_flow_model") +@pytest.fixture(scope="function") +def modellayers(structured_flow_model): + model = structured_flow_model + dis = model["dis"] + dis["bottom"] = dis["bottom"].isel(x=0, y=0, drop=True) + npf = model["npf"] + + return { + "idomain": dis["idomain"], + "top": dis["top"], + "bottom": dis["bottom"], + "k": npf["k"], + } + + +def make_layer_geometry(resistance, layer): + barrier_y = [11.0, 5.0, -1.0] + barrier_x = [5.0, 5.0, 5.0] + + geometry = gpd.GeoDataFrame( + geometry=[shapely.linestrings(barrier_x, barrier_y)], + data={ + "resistance": [resistance], + "layer": [layer], + }, + ) + return geometry + + +def make_depth_geometry(resistance, top, bot): + barrier_y = [11.0, 5.0, -1.0] + barrier_x = [5.0, 5.0, 5.0] + + geometry = gpd.GeoDataFrame( + geometry=[shapely.linestrings(barrier_x, barrier_y)], + data={ + "resistance": [resistance], + "ztop": [top], + "zbottom": [bot], + }, + ) + return geometry + + +def test_merge_three_hfbs__single_layer(modellayers_single_layer): + """Merge three single layer hfbs, test for lenght""" + # Arrange + n_barriers = 3 + single_resistance = 400.0 + + geometry = make_layer_geometry(single_resistance, 1) + hfb_ls = [ + SingleLayerHorizontalFlowBarrierResistance(geometry) for _ in range(n_barriers) + ] + + # Act + mf6_hfb = merge_hfb_packages(hfb_ls, **modellayers_single_layer) + + # Assert + assert mf6_hfb["cell_id"].shape == (6,) + assert (mf6_hfb["layer"] == 1).all() + expected_resistance = n_barriers * single_resistance + assert (expected_resistance == 1 / mf6_hfb["hydraulic_characteristic"]).all() + + +def test_merge_three_hfbs__compare_single_hfb(modellayers_single_layer): + """ + Merge three single layer hfbs, compare with one hfb with tripled + resistance as created with a call to merge_hfb_packages. + """ + # Arrange + n_barriers = 3 + single_resistance = 400.0 + + geometry = make_layer_geometry(single_resistance, 1) + geometry_tripled = make_layer_geometry(n_barriers * single_resistance, 1) + + hfb_ls_triple = [ + SingleLayerHorizontalFlowBarrierResistance(geometry) for _ in range(n_barriers) + ] + hfb_ls_single = [SingleLayerHorizontalFlowBarrierResistance(geometry_tripled)] + + # Act + mf6_hfb_three = merge_hfb_packages(hfb_ls_triple, **modellayers_single_layer) + mf6_hfb_single = merge_hfb_packages(hfb_ls_single, **modellayers_single_layer) + + # Assert + xr.testing.assert_equal(mf6_hfb_single.dataset, mf6_hfb_three.dataset) + + +def test_merge_three_hfbs__to_mf6_pkg_single_layer(modellayers_single_layer): + """ + Merge three single layer hfbs, compare with one hfb with tripled + resistance as with a call to to_mf6_pkg. + """ + # Arrange + n_barriers = 3 + single_resistance = 400.0 + + geometry = make_layer_geometry(single_resistance, 1) + geometry_tripled = make_layer_geometry(n_barriers * single_resistance, 1) + + hfb_ls_triple = [ + SingleLayerHorizontalFlowBarrierResistance(geometry) for _ in range(n_barriers) + ] + hfb_ls_single = [SingleLayerHorizontalFlowBarrierResistance(geometry_tripled)] + + # Act + mf6_hfb_three = merge_hfb_packages(hfb_ls_triple, **modellayers_single_layer) + mf6_hfb_single = hfb_ls_single[0].to_mf6_pkg(**modellayers_single_layer) + + # Assert + xr.testing.assert_equal(mf6_hfb_single.dataset, mf6_hfb_three.dataset) + + +def test_merge_mixed_hfbs__single_layer(modellayers_single_layer): + """Merge mix of layer hfb and depth hfb.""" + # Arrange + n_barriers = 3 + single_resistance = 400.0 + + top = modellayers_single_layer["top"].values + bot = modellayers_single_layer["bottom"].values[0] + + geometry = make_layer_geometry(single_resistance, 1) + geometry_depth = make_depth_geometry(single_resistance, top, bot) + + hfb_ls_triple = [ + SingleLayerHorizontalFlowBarrierResistance(geometry), + HorizontalFlowBarrierResistance(geometry_depth), + HorizontalFlowBarrierResistance(geometry_depth), + ] + + # Act + mf6_hfb = merge_hfb_packages(hfb_ls_triple, **modellayers_single_layer) + + # Assert + assert mf6_hfb["cell_id"].shape == (6,) + assert (mf6_hfb["layer"] == 1).all() + expected_resistance = n_barriers * single_resistance + assert (expected_resistance == 1 / mf6_hfb["hydraulic_characteristic"]).all() + + +def test_merge_three_hfbs__multiple_single_layers(modellayers): + """Merge three single layer hfbs at different layers""" + # Arrange + n_barriers = 3 + single_resistance = 400.0 + + hfb_ls = [ + SingleLayerHorizontalFlowBarrierResistance( + make_layer_geometry(single_resistance, i) + ) + for i in range(1, n_barriers + 1) + ] + + # Act + mf6_hfb = merge_hfb_packages(hfb_ls, **modellayers) + + # Assert + assert mf6_hfb["cell_id"].shape == (18,) + assert np.all(np.unique(mf6_hfb["layer"]) == np.array([1, 2, 3])) + expected_resistance = single_resistance + assert (expected_resistance == 1 / mf6_hfb["hydraulic_characteristic"]).all() + + +def test_merge_mixed_hfbs__multiple_layer(modellayers): + """ + Merge three single layer hfbs at different layers plus one hfb spread across + the complete depth. + """ + # Arrange + n_barriers = 3 + single_resistance = 400.0 + + hfb_ls = [ + SingleLayerHorizontalFlowBarrierResistance( + make_layer_geometry(single_resistance, i) + ) + for i in range(1, n_barriers + 1) + ] + hfb_ls.append( + HorizontalFlowBarrierResistance( + make_depth_geometry(single_resistance, 10.0, -3.0) + ) + ) + + # Act + mf6_hfb = merge_hfb_packages(hfb_ls, **modellayers) + + # Assert + assert mf6_hfb["cell_id"].shape == (18,) + assert np.all(np.unique(mf6_hfb["layer"]) == np.array([1, 2, 3])) + expected_resistance = 2 * single_resistance + assert (expected_resistance == 1 / mf6_hfb["hydraulic_characteristic"]).all() From 5ceb19b944fe83dc9672fd1e1415c125808ed576 Mon Sep 17 00:00:00 2001 From: luitjansl <64598682+luitjansl@users.noreply.github.com> Date: Thu, 4 Jul 2024 13:12:05 +0200 Subject: [PATCH 25/53] Issue #1058 period bounds (#1098) Fixes #1058 # Description When importing models from imod5 we want to import the period data as well- specifically for ghb, drn and riv. This PR implements importing period data for these packages. Moved the function expand_repetitions to make it accessible from the packages that use it. # Checklist - [X] Links to correct issue - [ ] Update changelog, if changes affect users - [X] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [X] Unit tests were added - [ ] **If feature added**: Added/extended example --- imod/formats/prj/disv_conversion.py | 16 +- imod/mf6/dis.py | 16 +- imod/mf6/drn.py | 21 +- imod/mf6/ghb.py | 84 ++- imod/mf6/model_gwf.py | 14 +- imod/mf6/riv.py | 27 + imod/mf6/simulation.py | 6 + imod/tests/conftest.py | 5 +- .../backward_compatibility_fixture.py | 497 +++++++++++++++++- .../test_formats/test_disv_conversion.py | 1 - imod/tests/test_mf6/test_mf6_chd.py | 12 +- imod/tests/test_mf6/test_mf6_dis.py | 11 +- imod/tests/test_mf6/test_mf6_drn.py | 11 +- .../test_mf6/test_mf6_generalheadboundary.py | 27 + imod/tests/test_mf6/test_mf6_hfb.py | 7 +- imod/tests/test_mf6/test_mf6_ic.py | 2 +- imod/tests/test_mf6/test_mf6_npf.py | 6 +- imod/tests/test_mf6/test_mf6_rch.py | 8 +- imod/tests/test_mf6/test_mf6_riv.py | 81 ++- imod/tests/test_mf6/test_mf6_simulation.py | 7 +- imod/tests/test_mf6/test_mf6_sto.py | 6 +- imod/tests/test_mf6/test_mf6_wel.py | 9 +- imod/util/expand_repetitions.py | 17 + 23 files changed, 821 insertions(+), 70 deletions(-) create mode 100644 imod/tests/test_mf6/test_mf6_generalheadboundary.py create mode 100644 imod/util/expand_repetitions.py diff --git a/imod/formats/prj/disv_conversion.py b/imod/formats/prj/disv_conversion.py index f6e9c2f29..48bab7df4 100644 --- a/imod/formats/prj/disv_conversion.py +++ b/imod/formats/prj/disv_conversion.py @@ -5,7 +5,6 @@ from __future__ import annotations -import itertools import pickle from collections import Counter from datetime import datetime @@ -21,6 +20,7 @@ from imod.mf6.utilities.package import get_repeat_stress from imod.prepare.layer import get_upper_active_grid_cells from imod.typing import GridDataArray +from imod.util.expand_repetitions import expand_repetitions from imod.util.imports import MissingOptionalModule try: @@ -683,20 +683,6 @@ def merge_hfbs( } -def expand_repetitions( - repeat_stress: List[datetime], time_min: datetime, time_max: datetime -) -> Dict[datetime, datetime]: - expanded = {} - for year, date in itertools.product( - range(time_min.year, time_max.year + 1), - repeat_stress, - ): - newdate = date.replace(year=year) - if newdate < time_max: - expanded[newdate] = date - return expanded - - def convert_to_disv( projectfile_data, target, time_min=None, time_max=None, repeat_stress=None ): diff --git a/imod/mf6/dis.py b/imod/mf6/dis.py index b2618e4da..1cebeef5d 100644 --- a/imod/mf6/dis.py +++ b/imod/mf6/dis.py @@ -163,6 +163,7 @@ def from_imod5_data( cls, imod5_data: dict[str, dict[str, GridDataArray]], regridder_types: Optional[RegridMethodType] = None, + validate: bool = True, ) -> "StructuredDiscretization": """ Construct package from iMOD5 data, loaded with the @@ -209,13 +210,14 @@ def from_imod5_data( ) # Validate iMOD5 data - UniqueValuesSchema([-1, 0, 1]).validate(imod5_data["bnd"]["ibound"]) - if not np.all( - new_package_data["top"][1:].data == new_package_data["bottom"][:-1].data - ): - raise ValidationError( - "Model discretization not fully 3D. Make sure TOP[n+1] matches BOT[n]" - ) + if validate: + UniqueValuesSchema([-1, 0, 1]).validate(imod5_data["bnd"]["ibound"]) + if not np.all( + new_package_data["top"][1:].data == new_package_data["bottom"][:-1].data + ): + raise ValidationError( + "Model discretization not fully 3D. Make sure TOP[n+1] matches BOT[n]" + ) thickness = new_package_data["top"] - new_package_data["bottom"] new_package_data["idomain"] = convert_ibound_to_idomain( diff --git a/imod/mf6/drn.py b/imod/mf6/drn.py index 4eb83d1af..05b240064 100644 --- a/imod/mf6/drn.py +++ b/imod/mf6/drn.py @@ -1,4 +1,5 @@ from dataclasses import asdict +from datetime import datetime from typing import Optional import numpy as np @@ -32,6 +33,7 @@ ) from imod.typing import GridDataArray from imod.typing.grid import enforce_dim_order, is_planar_grid +from imod.util.expand_repetitions import expand_repetitions class Drainage(BoundaryCondition, IRegridPackage): @@ -166,10 +168,13 @@ def from_imod5_data( cls, key: str, imod5_data: dict[str, dict[str, GridDataArray]], + period_data: dict[str, list[datetime]], target_discretization: StructuredDiscretization, target_npf: NodePropertyFlow, allocation_option: ALLOCATION_OPTION, distributing_option: DISTRIBUTING_OPTION, + time_min: datetime, + time_max: datetime, regridder_types: Optional[RegridMethodType] = None, ) -> "Drainage": """ @@ -185,6 +190,9 @@ def from_imod5_data( imod5_data: dict Dictionary with iMOD5 data. This can be constructed from the :func:`imod.formats.prj.open_projectfile_data` method. + period_data: dict + Dictionary with iMOD5 period data. This can be constructed from the + :func:`imod.formats.prj.open_projectfile_data` method. target_discretization: StructuredDiscretization package The grid that should be used for the new package. Does not need to be identical to one of the input grids. @@ -194,13 +202,17 @@ def from_imod5_data( allocation option. distributing_option: dict[str, DISTRIBUTING_OPTION] distributing option. + time_min: datetime + Begin-time of the simulation. Used for expanding period data. + time_max: datetime + End-time of the simulation. Used for expanding period data. regridder_types: RegridMethodType, optional Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. Returns ------- - A list of Modflow 6 Drainage packages. + A Modflow 6 Drainage package. """ target_top = target_discretization.dataset["top"] @@ -250,4 +262,9 @@ def from_imod5_data( target_npf.dataset["k"], planar_elevation, ) - return Drainage(**regridded_package_data) + + drn = Drainage(**regridded_package_data) + repeat = period_data.get(key) + if repeat is not None: + drn.set_repeat_stress(expand_repetitions(repeat, time_min, time_max)) + return drn diff --git a/imod/mf6/ghb.py b/imod/mf6/ghb.py index 68d8930f7..fb40abc8f 100644 --- a/imod/mf6/ghb.py +++ b/imod/mf6/ghb.py @@ -1,9 +1,17 @@ +from dataclasses import asdict +from datetime import datetime +from typing import Optional + import numpy as np from imod.logging import init_log_decorator from imod.mf6.boundary_condition import BoundaryCondition from imod.mf6.interfaces.iregridpackage import IRegridPackage -from imod.mf6.regrid.regrid_schemes import GeneralHeadBoundaryRegridMethod +from imod.mf6.regrid.regrid_schemes import ( + GeneralHeadBoundaryRegridMethod, + RegridMethodType, +) +from imod.mf6.utilities.regrid import RegridderWeightsCache, _regrid_package_data from imod.mf6.validation import BOUNDARY_DIMS_SCHEMA, CONC_DIMS_SCHEMA from imod.schemata import ( AllInsideNoDataSchema, @@ -16,6 +24,8 @@ IndexesSchema, OtherCoordsSchema, ) +from imod.typing import GridDataArray +from imod.util.expand_repetitions import expand_repetitions class GeneralHeadBoundary(BoundaryCondition, IRegridPackage): @@ -147,3 +157,75 @@ def _validate(self, schemata, **kwargs): errors = super()._validate(schemata, **kwargs) return errors + + @classmethod + def from_imod5_data( + cls, + key: str, + imod5_data: dict[str, dict[str, GridDataArray]], + period_data: dict[str, list[datetime]], + target_discretization, + time_min: datetime, + time_max: datetime, + regridder_types: Optional[RegridMethodType] = None, + ) -> "GeneralHeadBoundary": + """ + Construct a GeneralHeadBoundary-package from iMOD5 data, loaded with the + :func:`imod.formats.prj.open_projectfile_data` function. + + .. note:: + + The method expects the iMOD5 model to be fully 3D, not quasi-3D. + + Parameters + ---------- + imod5_data: dict + Dictionary with iMOD5 data. This can be constructed from the + :func:`imod.formats.prj.open_projectfile_data` method. + period_data: dict + Dictionary with iMOD5 period data. This can be constructed from the + :func:`imod.formats.prj.open_projectfile_data` method. + target_discretization: StructuredDiscretization package + The grid that should be used for the new package. Does not + need to be identical to one of the input grids. + target_npf: NodePropertyFlow package + The conductivity information, used to compute drainage flux + allocation_option: ALLOCATION_OPTION + allocation option. + distributing_option: dict[str, DISTRIBUTING_OPTION] + distributing option. + time_min: datetime + Begin-time of the simulation. Used for expanding period data. + time_max: datetime + End-time of the simulation. Used for expanding period data. + regridder_types: RegridMethodType, optional + Optional dataclass with regridder types for a specific variable. + Use this to override default regridding methods. + + Returns + ------- + A Modflow 6 GeneralHeadBoundary packages. + """ + + idomain = target_discretization.dataset["idomain"] + data = { + "head": imod5_data[key]["head"], + "conductance": imod5_data[key]["conductance"], + } + + if regridder_types is None: + regridder_settings = asdict(cls.get_regrid_methods(), dict_factory=dict) + else: + regridder_settings = asdict(regridder_types, dict_factory=dict) + + regrid_context = RegridderWeightsCache() + + regridded_package_data = _regrid_package_data( + data, idomain, regridder_settings, regrid_context, {} + ) + + ghb = GeneralHeadBoundary(**regridded_package_data) + repeat = period_data.get(key) + if repeat is not None: + ghb.set_repeat_stress(expand_repetitions(repeat, time_min, time_max)) + return ghb diff --git a/imod/mf6/model_gwf.py b/imod/mf6/model_gwf.py index 58e67fee2..c7e182569 100644 --- a/imod/mf6/model_gwf.py +++ b/imod/mf6/model_gwf.py @@ -1,5 +1,6 @@ from __future__ import annotations +from datetime import datetime from typing import Optional import cftime @@ -173,8 +174,11 @@ def update_buoyancy_package(self, transport_models_per_flow_model) -> None: def from_imod5_data( cls, imod5_data: dict[str, dict[str, GridDataArray]], + period_data: dict[str, list[datetime]], allocation_options: SimulationAllocationOptions, distributing_options: SimulationDistributingOptions, + time_min: datetime, + time_max: datetime, regridder_types: Optional[RegridMethodType] = None, ) -> "GroundwaterFlowModel": """ @@ -209,7 +213,9 @@ def from_imod5_data( # first import the singleton packages # import discretization - dis_pkg = StructuredDiscretization.from_imod5_data(imod5_data, regridder_types) + dis_pkg = StructuredDiscretization.from_imod5_data( + imod5_data, regridder_types, False + ) grid = dis_pkg.dataset["idomain"] # import npf @@ -239,10 +245,13 @@ def from_imod5_data( drn_pkg = Drainage.from_imod5_data( drn_key, imod5_data, + period_data, dis_pkg, npf_pkg, allocation_options.drn, distributing_option=distributing_options.drn, + time_min=time_min, + time_max=time_max, regridder_types=regridder_types, ) result[drn_key] = drn_pkg @@ -253,7 +262,10 @@ def from_imod5_data( riv_pkg, drn_pkg = River.from_imod5_data( riv_key, imod5_data, + period_data, dis_pkg, + time_min, + time_max, allocation_options.riv, distributing_options.riv, regridder_types, diff --git a/imod/mf6/riv.py b/imod/mf6/riv.py index 6720bf17e..4e88f71b4 100644 --- a/imod/mf6/riv.py +++ b/imod/mf6/riv.py @@ -1,4 +1,5 @@ from dataclasses import asdict +from datetime import datetime from typing import Optional, Tuple import numpy as np @@ -36,6 +37,7 @@ ) from imod.typing import GridDataArray from imod.typing.grid import enforce_dim_order, is_planar_grid +from imod.util.expand_repetitions import expand_repetitions class River(BoundaryCondition, IRegridPackage): @@ -188,7 +190,10 @@ def from_imod5_data( cls, key: str, imod5_data: dict[str, dict[str, GridDataArray]], + period_data: dict[str, list[datetime]], target_discretization: StructuredDiscretization, + time_min: datetime, + time_max: datetime, allocation_option_riv: ALLOCATION_OPTION, distributing_option_riv: DISTRIBUTING_OPTION, regridder_types: Optional[RegridMethodType] = None, @@ -209,9 +214,16 @@ def from_imod5_data( imod5_data: dict Dictionary with iMOD5 data. This can be constructed from the :func:`imod.formats.prj.open_projectfile_data` method. + period_data: dict + Dictionary with iMOD5 period data. This can be constructed from the + :func:`imod.formats.prj.open_projectfile_data` method. target_discretization: StructuredDiscretization package The grid that should be used for the new package. Does not need to be identical to one of the input grids. + time_min: datetime + Begin-time of the simulation. Used for expanding period data. + time_max: datetime + End-time of the simulation. Used for expanding period data. allocation_option: ALLOCATION_OPTION allocation option. distributing_option: dict[str, DISTRIBUTING_OPTION] @@ -319,6 +331,9 @@ def from_imod5_data( ) regridded_package_data["conductance"] = river_conductance regridded_package_data.pop("infiltration_factor") + regridded_package_data["bottom_elevation"] = enforce_dim_order( + regridded_package_data["bottom_elevation"] + ) river_package = River(**regridded_package_data) # create a drainage package with the conductance we computed from the infiltration factor @@ -339,6 +354,18 @@ def from_imod5_data( drainage_package = drainage_package.mask(mask) else: drainage_package = None + + repeat = period_data.get(key) + if repeat is not None: + if river_package is not None: + river_package.set_repeat_stress( + expand_repetitions(repeat, time_min, time_max) + ) + if drainage_package is not None: + drainage_package.set_repeat_stress( + expand_repetitions(repeat, time_min, time_max) + ) + return (river_package, drainage_package) @classmethod diff --git a/imod/mf6/simulation.py b/imod/mf6/simulation.py index a7e4d85d8..4b7057e38 100644 --- a/imod/mf6/simulation.py +++ b/imod/mf6/simulation.py @@ -1322,8 +1322,11 @@ def mask_all_models( def from_imod5_data( cls, imod5_data: dict[str, dict[str, GridDataArray]], + period_data: dict[str, dict[str, GridDataArray]], allocation_options: SimulationAllocationOptions, distributing_options: SimulationDistributingOptions, + time_min, + time_max, regridder_types: Optional[dict[str, tuple[RegridderType, str]]] = None, ) -> "Modflow6Simulation": """ @@ -1357,8 +1360,11 @@ def from_imod5_data( # import GWF model, groundwaterFlowModel = GroundwaterFlowModel.from_imod5_data( imod5_data, + period_data, allocation_options, distributing_options, + time_min, + time_max, regridder_types, ) simulation["imported_model"] = groundwaterFlowModel diff --git a/imod/tests/conftest.py b/imod/tests/conftest.py index 5d9a74cab..4ec724725 100644 --- a/imod/tests/conftest.py +++ b/imod/tests/conftest.py @@ -1,6 +1,9 @@ import pytest -from .fixtures.backward_compatibility_fixture import imod5_dataset +from .fixtures.backward_compatibility_fixture import ( + imod5_dataset, + imod5_dataset_periods, +) from .fixtures.flow_basic_fixture import ( basic_dis, basic_dis__topsystem, diff --git a/imod/tests/fixtures/backward_compatibility_fixture.py b/imod/tests/fixtures/backward_compatibility_fixture.py index 955c8bbf7..b62b9193a 100644 --- a/imod/tests/fixtures/backward_compatibility_fixture.py +++ b/imod/tests/fixtures/backward_compatibility_fixture.py @@ -1,13 +1,20 @@ +from datetime import datetime +from zipfile import ZipFile + import pytest import xarray as xr import imod +from imod.data.sample_data import REGISTRY +from imod.formats.prj.prj import open_projectfile_data @pytest.fixture(scope="module") def imod5_dataset(): tmp_path = imod.util.temporary_directory() data = imod.data.imod5_projectfile_data(tmp_path) + + pd = data[1] data = data[0] _load_imod5_data_in_memory(data) @@ -16,7 +23,7 @@ def imod5_dataset(): ibound = data["bnd"]["ibound"] ibound = ibound.where(ibound <= 0, 1) data["bnd"]["ibound"] = ibound - return data + return data, pd def _load_imod5_data_in_memory(imod5_data): @@ -25,3 +32,491 @@ def _load_imod5_data_in_memory(imod5_data): for vardata in pkg.values(): if isinstance(vardata, xr.DataArray): vardata.load() + + +@pytest.fixture(scope="module") +def imod5_dataset_periods() -> tuple[dict[str, any], dict[str, list[datetime]]]: + tmp_path = imod.util.temporary_directory() + fname_model = REGISTRY.fetch("iMOD5_model.zip") + + with ZipFile(fname_model) as archive: + archive.extractall(tmp_path) + + with open(tmp_path / "iMOD5_model_pooch" / "iMOD5_model.prj", "w") as f: + f.write(period_prj) + + data = open_projectfile_data(tmp_path / "iMOD5_model_pooch" / "iMOD5_model.prj") + + grid_data = data[0] + period_data = data[1] + + _load_imod5_data_in_memory(grid_data) + + # Fix data for ibound as it contains floating values like 0.34, 0.25 etc. + ibound = grid_data["bnd"]["ibound"] + ibound = ibound.where(ibound <= 0, 1) + grid_data["bnd"]["ibound"] = ibound + return grid_data, period_data + + +period_prj = """\ +0001,(BND),1, Boundary Condition +001,37 +1,2,1,1.0,0.0,-999.99, '.\Database\BND\VERSION_1\IBOUND_L1.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,2,1.0,0.0,-999.99, '.\Database\BND\VERSION_1\IBOUND_L2.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,3,1.0,0.0,-999.99, '.\Database\BND\VERSION_1\IBOUND_L3.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,4,1.0,0.0,-999.99, '.\Database\BND\VERSION_1\IBOUND_L4.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,5,1.0,0.0,-999.99, '.\Database\BND\VERSION_1\IBOUND_L5.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,6,1.0,0.0,-999.99, '.\Database\BND\VERSION_1\IBOUND_L6.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,7,1.0,0.0,-999.99, '.\Database\BND\VERSION_1\IBOUND_L7.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,8,1.0,0.0,-999.99, '.\Database\BND\VERSION_1\IBOUND_L8.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,9,1.0,0.0,-999.99, '.\Database\BND\VERSION_1\IBOUND_L9.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,10,1.0,0.0,-999.99, '.\Database\BND\VERSION_1\IBOUND_L10.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,11,1.0,0.0,-999.99, '.\Database\BND\VERSION_1\IBOUND_L11.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,12,1.0,0.0,-999.99, '.\Database\BND\VERSION_1\IBOUND_L12.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,13,1.0,0.0,-999.99, '.\Database\BND\VERSION_1\IBOUND_L13.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,14,1.0,0.0,-999.99, '.\Database\BND\VERSION_1\IBOUND_L14.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,15,1.0,0.0,-999.99, '.\Database\BND\VERSION_1\IBOUND_L15.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,16,1.0,0.0,-999.99, '.\Database\BND\VERSION_1\IBOUND_L16.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,17,1.0,0.0,-999.99, '.\Database\BND\VERSION_1\IBOUND_L17.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,18,1.0,0.0,-999.99, '.\Database\BND\VERSION_1\IBOUND_L18.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,19,1.0,0.0,-999.99,'.\Database\BND\VERSION_1\IBOUND_L19.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,20,1.0,0.0,-999.99,'.\Database\BND\VERSION_1\IBOUND_L20.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,21,1.0,0.0,-999.99,'.\Database\BND\VERSION_1\IBOUND_L21.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,22,1.0,0.0,-999.99,'.\Database\BND\VERSION_1\IBOUND_L22.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,23,1.0,0.0,-999.99,'.\Database\BND\VERSION_1\IBOUND_L23.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,24,1.0,0.0,-999.99,'.\Database\BND\VERSION_1\IBOUND_L24.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,25,1.0,0.0,-999.99,'.\Database\BND\VERSION_1\IBOUND_L25.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,26,1.0,0.0,-999.99,'.\Database\BND\VERSION_1\IBOUND_L26.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,27,1.0,0.0,-999.99,'.\Database\BND\VERSION_1\IBOUND_L27.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,28,1.0,0.0,-999.99,'.\Database\BND\VERSION_1\IBOUND_L28.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,29,1.0,0.0,-999.99,'.\Database\BND\VERSION_1\IBOUND_L29.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,30,1.0,0.0,-999.99,'.\Database\BND\VERSION_1\IBOUND_L30.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,31,1.0,0.0,-999.99,'.\Database\BND\VERSION_1\IBOUND_L31.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,32,1.0,0.0,-999.99,'.\Database\BND\VERSION_1\IBOUND_L32.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,33,1.0,0.0,-999.99,'.\Database\BND\VERSION_1\IBOUND_L33.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,34,1.0,0.0,-999.99,'.\Database\BND\VERSION_1\IBOUND_L34.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,35,1.0,0.0,-999.99,'.\Database\BND\VERSION_1\IBOUND_L35.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,36,1.0,0.0,-999.99,'.\Database\BND\VERSION_1\IBOUND_L36.IDF' >>> (BND) Boundary Settings (IDF) <<< +1,2,37,1.0,0.0,-999.99,'.\Database\BND\VERSION_1\IBOUND_L37.IDF' >>> (BND) Boundary Settings (IDF) <<< + + +0001,(TOP),1, Top Elevation +001,37 +1,2,1,1.0,0.0,-999.99, '.\Database\TOP\VERSION_1\TOP_L1.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,2,1.0,0.0,-999.99, '.\Database\TOP\VERSION_1\TOP_L2.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,3,1.0,0.0,-999.99, '.\Database\TOP\VERSION_1\TOP_L3.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,4,1.0,0.0,-999.99, '.\Database\TOP\VERSION_1\TOP_L4.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,5,1.0,0.0,-999.99, '.\Database\TOP\VERSION_1\TOP_L5.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,6,1.0,0.0,-999.99, '.\Database\TOP\VERSION_1\TOP_L6.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,7,1.0,0.0,-999.99, '.\Database\TOP\VERSION_1\TOP_L7.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,8,1.0,0.0,-999.99, '.\Database\TOP\VERSION_1\TOP_L8.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,9,1.0,0.0,-999.99, '.\Database\TOP\VERSION_1\TOP_L9.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,10,1.0,0.0,-999.99, '.\Database\TOP\VERSION_1\TOP_L10.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,11,1.0,0.0,-999.99, '.\Database\TOP\VERSION_1\TOP_L11.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,12,1.0,0.0,-999.99, '.\Database\TOP\VERSION_1\TOP_L12.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,13,1.0,0.0,-999.99, '.\Database\TOP\VERSION_1\TOP_L13.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,14,1.0,0.0,-999.99, '.\Database\TOP\VERSION_1\TOP_L14.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,15,1.0,0.0,-999.99, '.\Database\TOP\VERSION_1\TOP_L15.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,16,1.0,0.0,-999.99, '.\Database\TOP\VERSION_1\TOP_L16.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,17,1.0,0.0,-999.99, '.\Database\TOP\VERSION_1\TOP_L17.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,18,1.0,0.0,-999.99, '.\Database\TOP\VERSION_1\TOP_L18.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,19,1.0,0.0,-999.99,'.\Database\TOP\VERSION_1\TOP_L19.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,20,1.0,0.0,-999.99,'.\Database\TOP\VERSION_1\TOP_L20.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,21,1.0,0.0,-999.99,'.\Database\TOP\VERSION_1\TOP_L21.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,22,1.0,0.0,-999.99,'.\Database\TOP\VERSION_1\TOP_L22.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,23,1.0,0.0,-999.99,'.\Database\TOP\VERSION_1\TOP_L23.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,24,1.0,0.0,-999.99,'.\Database\TOP\VERSION_1\TOP_L24.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,25,1.0,0.0,-999.99,'.\Database\TOP\VERSION_1\TOP_L25.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,26,1.0,0.0,-999.99,'.\Database\TOP\VERSION_1\TOP_L26.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,27,1.0,0.0,-999.99,'.\Database\TOP\VERSION_1\TOP_L27.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,28,1.0,0.0,-999.99,'.\Database\TOP\VERSION_1\TOP_L28.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,29,1.0,0.0,-999.99,'.\Database\TOP\VERSION_1\TOP_L29.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,30,1.0,0.0,-999.99,'.\Database\TOP\VERSION_1\TOP_L30.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,31,1.0,0.0,-999.99,'.\Database\TOP\VERSION_1\TOP_L31.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,32,1.0,0.0,-999.99,'.\Database\TOP\VERSION_1\TOP_L32.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,33,1.0,0.0,-999.99,'.\Database\TOP\VERSION_1\TOP_L33.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,34,1.0,0.0,-999.99,'.\Database\TOP\VERSION_1\TOP_L34.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,35,1.0,0.0,-999.99,'.\Database\TOP\VERSION_1\TOP_L35.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,36,1.0,0.0,-999.99,'.\Database\TOP\VERSION_1\TOP_L36.IDF' >>> (TOP) Top of Modellayer (IDF) <<< +1,2,37,1.0,0.0,-999.99,'.\Database\TOP\VERSION_1\TOP_L37.IDF' >>> (TOP) Top of Modellayer (IDF) <<< + + +0001,(BOT),1, Bottom Elevation +001,37 +1,2,1,1.0,0.0,-999.99, '.\Database\BOT\VERSION_1\BOT_L1.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,2,1.0,0.0,-999.99, '.\Database\BOT\VERSION_1\BOT_L2.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,3,1.0,0.0,-999.99, '.\Database\BOT\VERSION_1\BOT_L3.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,4,1.0,0.0,-999.99, '.\Database\BOT\VERSION_1\BOT_L4.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,5,1.0,0.0,-999.99, '.\Database\BOT\VERSION_1\BOT_L5.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,6,1.0,0.0,-999.99, '.\Database\BOT\VERSION_1\BOT_L6.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,7,1.0,0.0,-999.99, '.\Database\BOT\VERSION_1\BOT_L7.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,8,1.0,0.0,-999.99, '.\Database\BOT\VERSION_1\BOT_L8.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,9,1.0,0.0,-999.99, '.\Database\BOT\VERSION_1\BOT_L9.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,10,1.0,0.0,-999.99, '.\Database\BOT\VERSION_1\BOT_L10.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,11,1.0,0.0,-999.99, '.\Database\BOT\VERSION_1\BOT_L11.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,12,1.0,0.0,-999.99, '.\Database\BOT\VERSION_1\BOT_L12.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,13,1.0,0.0,-999.99, '.\Database\BOT\VERSION_1\BOT_L13.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,14,1.0,0.0,-999.99, '.\Database\BOT\VERSION_1\BOT_L14.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,15,1.0,0.0,-999.99, '.\Database\BOT\VERSION_1\BOT_L15.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,16,1.0,0.0,-999.99, '.\Database\BOT\VERSION_1\BOT_L16.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,17,1.0,0.0,-999.99, '.\Database\BOT\VERSION_1\BOT_L17.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,18,1.0,0.0,-999.99, '.\Database\BOT\VERSION_1\BOT_L18.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,19,1.0,0.0,-999.99,'.\Database\BOT\VERSION_1\BOT_L19.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,20,1.0,0.0,-999.99,'.\Database\BOT\VERSION_1\BOT_L20.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,21,1.0,0.0,-999.99,'.\Database\BOT\VERSION_1\BOT_L21.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,22,1.0,0.0,-999.99,'.\Database\BOT\VERSION_1\BOT_L22.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,23,1.0,0.0,-999.99,'.\Database\BOT\VERSION_1\BOT_L23.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,24,1.0,0.0,-999.99,'.\Database\BOT\VERSION_1\BOT_L24.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,25,1.0,0.0,-999.99,'.\Database\BOT\VERSION_1\BOT_L25.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,26,1.0,0.0,-999.99,'.\Database\BOT\VERSION_1\BOT_L26.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,27,1.0,0.0,-999.99,'.\Database\BOT\VERSION_1\BOT_L27.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,28,1.0,0.0,-999.99,'.\Database\BOT\VERSION_1\BOT_L28.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,29,1.0,0.0,-999.99,'.\Database\BOT\VERSION_1\BOT_L29.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,30,1.0,0.0,-999.99,'.\Database\BOT\VERSION_1\BOT_L30.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,31,1.0,0.0,-999.99,'.\Database\BOT\VERSION_1\BOT_L31.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,32,1.0,0.0,-999.99,'.\Database\BOT\VERSION_1\BOT_L32.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,33,1.0,0.0,-999.99,'.\Database\BOT\VERSION_1\BOT_L33.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,34,1.0,0.0,-999.99,'.\Database\BOT\VERSION_1\BOT_L34.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,35,1.0,0.0,-999.99,'.\Database\BOT\VERSION_1\BOT_L35.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,36,1.0,0.0,-999.99,'.\Database\BOT\VERSION_1\BOT_L36.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< +1,2,37,1.0,0.0,-999.99,'.\Database\BOT\VERSION_1\BOT_L37.IDF' >>> (BOT) Bottom of Modellayer (IDF) <<< + + +0001,(KHV),1, Horizontal Permeability +001,37 +1,1,1,1.0,0.0,1.0 >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,2,1.0,0.0,-999.99, '.\Database\KHV\VERSION_1\IPEST_KHV_L2.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,3,1.0,0.0,-999.99, '.\Database\KHV\VERSION_1\IPEST_KHV_L3.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,4,1.0,0.0,-999.99, '.\Database\KHV\VERSION_1\IPEST_KHV_L4.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,5,1.0,0.0,-999.99, '.\Database\KHV\VERSION_1\IPEST_KHV_L5.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,6,1.0,0.0,-999.99, '.\Database\KHV\VERSION_1\IPEST_KHV_L6.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,7,1.0,0.0,-999.99, '.\Database\KHV\VERSION_1\IPEST_KHV_L7.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,8,1.0,0.0,-999.99, '.\Database\KHV\VERSION_1\IPEST_KHV_L8.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,9,1.0,0.0,-999.99, '.\Database\KHV\VERSION_1\IPEST_KHV_L9.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,10,1.0,0.0,-999.99, '.\Database\KHV\VERSION_1\IPEST_KHV_L10.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,11,1.0,0.0,-999.99, '.\Database\KHV\VERSION_1\IPEST_KHV_L11.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,12,1.0,0.0,-999.99, '.\Database\KHV\VERSION_1\IPEST_KHV_L12.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,13,1.0,0.0,-999.99, '.\Database\KHV\VERSION_1\IPEST_KHV_L13.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,14,1.0,0.0,-999.99, '.\Database\KHV\VERSION_1\IPEST_KHV_L14.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,15,1.0,0.0,-999.99, '.\Database\KHV\VERSION_1\IPEST_KHV_L15.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,16,1.0,0.0,-999.99, '.\Database\KHV\VERSION_1\IPEST_KHV_L16.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,17,1.0,0.0,-999.99, '.\Database\KHV\VERSION_1\IPEST_KHV_L17.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,18,1.0,0.0,-999.99, '.\Database\KHV\VERSION_1\IPEST_KHV_L18.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,19,1.0,0.0,-999.99,'.\Database\KHV\VERSION_1\IPEST_KHV_L19.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,20,1.0,0.0,-999.99,'.\Database\KHV\VERSION_1\IPEST_KHV_L20.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,21,1.0,0.0,-999.99,'.\Database\KHV\VERSION_1\IPEST_KHV_L21.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,22,1.0,0.0,-999.99,'.\Database\KHV\VERSION_1\IPEST_KHV_L22.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,23,1.0,0.0,-999.99,'.\Database\KHV\VERSION_1\IPEST_KHV_L23.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,24,1.0,0.0,-999.99,'.\Database\KHV\VERSION_1\IPEST_KHV_L24.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,25,1.0,0.0,-999.99,'.\Database\KHV\VERSION_1\IPEST_KHV_L25.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,26,1.0,0.0,-999.99,'.\Database\KHV\VERSION_1\IPEST_KHV_L26.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,27,1.0,0.0,-999.99,'.\Database\KHV\VERSION_1\IPEST_KHV_L27.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,28,1.0,0.0,-999.99,'.\Database\KHV\VERSION_1\IPEST_KHV_L28.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,29,1.0,0.0,-999.99,'.\Database\KHV\VERSION_1\IPEST_KHV_L29.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,30,1.0,0.0,-999.99,'.\Database\KHV\VERSION_1\IPEST_KHV_L30.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,1,31,1.0,0.0,1.0 >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,32,1.0,0.0,-999.99,'.\Database\KHV\VERSION_1\IPEST_KHV_L32.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,33,1.0,0.0,-999.99,'.\Database\KHV\VERSION_1\IPEST_KHV_L33.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,34,1.0,0.0,-999.99,'.\Database\KHV\VERSION_1\IPEST_KHV_L34.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,35,1.0,0.0,-999.99,'.\Database\KHV\VERSION_1\IPEST_KHV_L35.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,36,1.0,0.0,-999.99,'.\Database\KHV\VERSION_1\IPEST_KHV_L36.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< +1,2,37,1.0,0.0,-999.99,'.\Database\KHV\VERSION_1\IPEST_KHV_L37.IDF' >>> (KHV) Horizontal Permeability (IDF) <<< + + +0001,(KVA),1, Vertical Anisotropy +001,37 +1,1,1,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,2,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,3,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,4,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,5,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,6,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,7,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,8,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,9,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,10,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,11,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,12,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,13,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,14,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,15,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,16,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,17,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,18,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,19,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,20,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,21,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,22,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,23,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,24,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,25,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,26,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,27,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,28,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,29,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,30,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,31,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,32,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,33,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,34,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,35,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,36,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,37,1.0,0.0,0.3,'' >>> (KVA) Vertical Anisotropy (IDF) <<< + +0001,(SHD),1, Starting Heads +001,37 +1,2,1,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L1.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,2,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L2.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,3,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L3.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,4,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L4.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,5,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L5.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,6,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L6.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,7,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L7.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,8,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L8.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,9,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L9.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,10,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L10.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,11,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L11.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,12,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L12.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,13,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L13.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,14,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L14.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,15,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L15.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,16,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L16.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,17,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L17.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,18,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L18.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,19,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L19.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,20,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L20.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,21,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L21.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,22,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L22.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,23,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L23.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,1,24,1.0,0.0,20.5, >>> (SHD) Starting Heads (IDF) <<< +1,1,25,1.0,0.0,20.5, >>> (SHD) Starting Heads (IDF) <<< +1,1,26,1.0,0.0,20.5, >>> (SHD) Starting Heads (IDF) <<< +1,1,27,1.0,0.0,20.5, >>> (SHD) Starting Heads (IDF) <<< +1,1,28,1.0,0.0,20.5, >>> (SHD) Starting Heads (IDF) <<< +1,1,29,1.0,0.0,20.5, >>> (SHD) Starting Heads (IDF) <<< +1,1,30,1.0,0.0,20.5, >>> (SHD) Starting Heads (IDF) <<< +1,1,31,1.0,0.0,20.5, >>> (SHD) Starting Heads (IDF) <<< +1,1,32,1.0,0.0,20.5, >>> (SHD) Starting Heads (IDF) <<< +1,1,33,1.0,0.0,20.5, >>> (SHD) Starting Heads (IDF) <<< +1,1,34,1.0,0.0,20.5, >>> (SHD) Starting Heads (IDF) <<< +1,1,35,1.0,0.0,20.5, >>> (SHD) Starting Heads (IDF) <<< +1,1,36,1.0,0.0,20.5, >>> (SHD) Starting Heads (IDF) <<< +1,1,37,1.0,0.0,20.5, >>> (SHD) Starting Heads (IDF) <<< + + +0001,(ANI),0, Anisotropy +002,04 +1,2,2,1.0,0.0,-999.99,'.\Database\ANI\VERSION_1\ANI_FACTOR.IDF' >>> (FCT) Factor (IDF) <<< +1,2,4,1.0,0.0,-999.99,'.\Database\ANI\VERSION_1\ANI_FACTOR.IDF' >>> (FCT) Factor (IDF) <<< +1,2,6,1.0,0.0,-999.99,'.\Database\ANI\VERSION_1\ANI_FACTOR.IDF' >>> (FCT) Factor (IDF) <<< +1,2,8,1.0,0.0,-999.99,'.\Database\ANI\VERSION_1\ANI_FACTOR.IDF' >>> (FCT) Factor (IDF) <<< +1,2,2,1.0,0.0,-999.99,'.\Database\ANI\VERSION_1\ANI_HOEK.IDF' >>> (FCT) Factor (IDF) <<< +1,2,4,1.0,0.0,-999.99,'.\Database\ANI\VERSION_1\ANI_HOEK.IDF' >>> (FCT) Factor (IDF) <<< +1,2,6,1.0,0.0,-999.99,'.\Database\ANI\VERSION_1\ANI_HOEK.IDF' >>> (FCT) Factor (IDF) <<< +1,2,8,1.0,0.0,-999.99,'.\Database\ANI\VERSION_1\ANI_HOEK.IDF' >>> (ANG) Angle (IDF) <<< + + +0001,(STO),1, Storage +001,37 +1,1,1,1.0,0.0,0.15,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,2,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,3,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,4,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,5,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,6,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,7,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,8,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,9,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,10,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,11,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,12,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,13,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,14,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,15,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,16,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,17,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,18,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,19,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,20,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,21,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,22,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,23,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,24,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,25,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,26,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,27,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,28,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,29,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,30,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,31,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,32,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,33,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,34,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,35,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,36,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< +1,1,37,1.0,0.0,1.0e-5,'' >>> (KVA) Vertical Anisotropy (IDF) <<< + +0001,(HFB),1, Horizontal Flow Barrier +001,26 + 1,2, 003, 1.000000 , 10.00000 , -999.9900 ,'.\Database\HFB\VERSION_1\IBV2_HOOFDBREUKEN_BX.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 005, 1.000000 , 1000.000 , -999.9900 ,'.\Database\HFB\VERSION_1\IBV2_HOOFDBREUKEN_SY.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 007, 1.000000 , 1000.000 , -999.9900 ,'.\Database\HFB\VERSION_1\IBV2_HOOFDBREUKEN_SY.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 009, 1.000000 , 1000.000 , -999.9900 ,'.\Database\HFB\VERSION_1\IBV2_HOOFDBREUKEN_SY.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 011, 1.000000 , 1000.000 , -999.9900 ,'.\Database\HFB\VERSION_1\IBV2_HOOFDBREUKEN_SY.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 013, 1.000000 , 1000.000 , -999.9900 ,'.\Database\HFB\VERSION_1\IBV2_HOOFDBREUKEN_SY.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 015, 1.000000 , 101000.0 , -999.9900 ,'.\Database\HFB\VERSION_1\IBV2_HOOFDBREUKEN_BR.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 021, 1.000000 , 400.0000 , -999.9900 , '.\Database\HFB\VERSION_1\IBV2_BREUKEN_BR.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 023, 1.000000 , 101000.0 , -999.9900 ,'.\Database\HFB\VERSION_1\IBV2_HOOFDBREUKEN_BR.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 023, 1.000000 , 400.0000 , -999.9900 , '.\Database\HFB\VERSION_1\IBV2_BREUKEN_BR.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 025, 1.000000 , 101000.0 , -999.9900 ,'.\Database\HFB\VERSION_1\IBV2_HOOFDBREUKEN_BR.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 025, 1.000000 , 400.0000 , -999.9900 , '.\Database\HFB\VERSION_1\IBV2_BREUKEN_BR.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 027, 1.000000 , 101000.0 , -999.9900 ,'.\Database\HFB\VERSION_1\IBV2_HOOFDBREUKEN_BR.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 027, 1.000000 , 400.0000 , -999.9900 , '.\Database\HFB\VERSION_1\IBV2_BREUKEN_BR.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 029, 1.000000 , 101000.0 , -999.9900 ,'.\Database\HFB\VERSION_1\IBV2_HOOFDBREUKEN_BR.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 031, 1.000000 , 400.0000 , -999.9900 , '.\Database\HFB\VERSION_1\IBV2_BREUKEN_BR.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 031, 1.000000 , 101000.0 , -999.9900 ,'.\Database\HFB\VERSION_1\IBV2_HOOFDBREUKEN_BR.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 031, 1.000000 , 400.0000 , -999.9900 , '.\Database\HFB\VERSION_1\IBV2_BREUKEN_BR.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 033, 1.000000 , 101000.0 , -999.9900 ,'.\Database\HFB\VERSION_1\IBV2_HOOFDBREUKEN_BR.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 033, 1.000000 , 101000.0 , -999.9900 ,'.\Database\HFB\VERSION_1\IBV2_HOOFDBREUKEN_BR.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 033, 1.000000 , 400.0000 , -999.9900 , '.\Database\HFB\VERSION_1\IBV2_BREUKEN_BR.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 033, 1.000000 , 400.0000 , -999.9900 , '.\Database\HFB\VERSION_1\IBV2_BREUKEN_BR.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 035, 1.000000 , 101000.0 , -999.9900 ,'.\Database\HFB\VERSION_1\IBV2_HOOFDBREUKEN_BR.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 035, 1.000000 , 400.0000 , -999.9900 , '.\Database\HFB\VERSION_1\IBV2_BREUKEN_BR.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 037, 1.000000 , 101000.0 , -999.9900 ,'.\Database\HFB\VERSION_1\IBV2_HOOFDBREUKEN_BR.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + 1,2, 037, 1.000000 , 400.0000 , -999.9900 , '.\Database\HFB\VERSION_1\IBV2_BREUKEN_BR.GEN' >>> (HFB) Horizontal Barrier Flow (GEN) <<< + +0002,(RIV),1, Rivers +winter +004,003 +1,2,0,1.0,0.0,-999.99,'.\Database\RIV\VERSION_1\RIVER_PRIMAIR\IPEST_RIVER_PRIMAIR_COND_GEMIDDELD.IDF' >>> (CON) Conductance (IDF) <<< +1,2,0,1.0,0.0,-999.99, '.\Database\RIV\VERSION_1\MAAS\IPEST_COND19912011.IDF' >>> (CON) Conductance (IDF) <<< +1,2,0,1.0,0.0,-999.99, '.\Database\RIV\VERSION_1\BELGIE\COND_CAT012.IDF' >>> (CON) Conductance (IDF) <<< +1,2,0,1.0,0.0,-999.99, '.\Database\RIV\VERSION_1\RIVER_PRIMAIR\RIVER_PRIMAIR_STAGE_GEMIDDELD.IDF' >>> (RST) River Stage (IDF) <<< +1,2,0,1.0,0.0,-999.99, '.\Database\RIV\VERSION_1\MAAS\STAGE19912011.IDF' >>> (RST) River Stage (IDF) <<< +1,2,0,1.0,0.0,-999.99, '.\Database\RIV\VERSION_1\BELGIE\STAGE_CAT012.IDF' >>> (RST) River Stage (IDF) <<< +1,2,0,1.0,0.0,-999.99, '.\Database\RIV\VERSION_1\RIVER_PRIMAIR\RIVER_PRIMAIR_BOTTOM_GEMIDDELD.IDF' >>> (RBT) River Bottom (IDF) <<< +1,2,0,1.0,0.0,-999.99, '.\Database\RIV\VERSION_1\MAAS\BOTTOM19912011.IDF' >>> (RBT) River Bottom (IDF) <<< +1,2,0,1.0,0.0,-999.99, '.\Database\RIV\VERSION_1\BELGIE\BOT_CAT012.IDF' >>> (RBT) River Bottom (IDF) <<< +1,2,0,1.0,0.0,-999.99, '.\Database\RIV\VERSION_1\RIVER_PRIMAIR\RIVER_PRIMAIR_INFFCT_GEMIDDELD.IDF' >>> (RIF) Infiltration Factor (IDF) <<< +1,2,0,1.0,0.0,-999.99, '.\Database\RIV\VERSION_1\MAAS\INFFCT19912011.IDF' >>> (RIF) Infiltration Factor (IDF) <<< +1,1,0,1.0,0.0,1.0, '' >>> (RIF) Infiltration Factor (IDF) <<< +summer +004,003 +1,2,0,1.0,0.0,-999.99,'.\Database\RIV\VERSION_1\RIVER_PRIMAIR\IPEST_RIVER_PRIMAIR_COND_GEMIDDELD.IDF' >>> (CON) Conductance (IDF) <<< +1,2,0,1.0,0.0,-999.99, '.\Database\RIV\VERSION_1\MAAS\IPEST_COND19912011.IDF' >>> (CON) Conductance (IDF) <<< +1,2,0,1.0,0.0,-999.99, '.\Database\RIV\VERSION_1\BELGIE\COND_CAT012.IDF' >>> (CON) Conductance (IDF) <<< +1,2,0,1.0,0.0,-999.99, '.\Database\RIV\VERSION_1\RIVER_PRIMAIR\RIVER_PRIMAIR_STAGE_GEMIDDELD.IDF' >>> (RST) River Stage (IDF) <<< +1,2,0,1.0,0.0,-999.99, '.\Database\RIV\VERSION_1\MAAS\STAGE19912011.IDF' >>> (RST) River Stage (IDF) <<< +1,2,0,1.0,0.0,-999.99, '.\Database\RIV\VERSION_1\BELGIE\STAGE_CAT012.IDF' >>> (RST) River Stage (IDF) <<< +1,2,0,1.0,0.0,-999.99, '.\Database\RIV\VERSION_1\RIVER_PRIMAIR\RIVER_PRIMAIR_BOTTOM_GEMIDDELD.IDF' >>> (RBT) River Bottom (IDF) <<< +1,2,0,1.0,0.0,-999.99, '.\Database\RIV\VERSION_1\MAAS\BOTTOM19912011.IDF' >>> (RBT) River Bottom (IDF) <<< +1,2,0,1.0,0.0,-999.99, '.\Database\RIV\VERSION_1\BELGIE\BOT_CAT012.IDF' >>> (RBT) River Bottom (IDF) <<< +1,2,0,1.0,0.0,-999.99, '.\Database\RIV\VERSION_1\RIVER_PRIMAIR\RIVER_PRIMAIR_INFFCT_GEMIDDELD.IDF' >>> (RIF) Infiltration Factor (IDF) <<< +1,2,0,1.0,0.0,-999.99, '.\Database\RIV\VERSION_1\MAAS\INFFCT19912011.IDF' >>> (RIF) Infiltration Factor (IDF) <<< +1,1,0,1.0,0.0,1.0, '' >>> (RIF) Infiltration Factor (IDF) <<< + + +0001,(RCH),1, Recharge +STEADY-STATE +001,001 +1,2,1,1.0,0.0,-999.99,'.\Database\RCH\VERSION_1\GWAANVULLING_MEAN_19940114-20111231.IDF' >>> (RCH) Recharge Rate (IDF) <<< + +0001,(WEL),1, Wells +STEADY-STATE +001,003 +1,2,5,1.0,0.0,-999.99, '.\Database\WEL\VERSION_1\WELLS_L3.IPF' >>> (WRA) Well Rate (IPF) <<< +1,2,7,1.0,0.0,-999.99, '.\Database\WEL\VERSION_1\WELLS_L4.IPF' >>> (WRA) Well Rate (IPF) <<< +1,2,9,1.0,0.0,-999.99, '.\Database\WEL\VERSION_1\WELLS_L5.IPF' >>> (WRA) Well Rate (IPF) <<< + +0002,(DRN),1, Drainage +winter +002,002 +1,2,1,1.0,0.0,-999.99, '.\Database\DRN\VERSION_1\IPEST_DRAINAGE_CONDUCTANCE.IDF' >>> (CON) Conductance (IDF) <<< +1,2,0,1.0,0.0,-999.99,'.\Database\DRN\VERSION_1\RIVER_SECUNDAIR\IPEST_RIVER_SECUNDAIR_COND_WINTER.IDF' >>> (CON) Conductance (IDF) <<< +1,2,1,1.0,0.0,-999.99, '.\Database\DRN\VERSION_1\DRAINAGE_STAGE.IDF' >>> (DEL) Drainage Level (IDF) <<< +1,2,0,1.0,0.0,-999.99, '.\Database\DRN\VERSION_1\RIVER_SECUNDAIR\RIVER_SECUNDAIR_BOTTOM_WINTER.IDF' >>> (DEL) Drainage Level (IDF) <<< +summer +002,002 +1,2,1,1.0,0.0,-999.99, '.\Database\DRN\VERSION_1\IPEST_DRAINAGE_CONDUCTANCE.IDF' >>> (CON) Conductance (IDF) <<< +1,2,0,1.0,0.0,-999.99,'.\Database\DRN\VERSION_1\RIVER_SECUNDAIR\IPEST_RIVER_SECUNDAIR_COND_WINTER.IDF' >>> (CON) Conductance (IDF) <<< +1,2,1,1.0,0.0,-999.99, '.\Database\DRN\VERSION_1\DRAINAGE_STAGE.IDF' >>> (DEL) Drainage Level (IDF) <<< +1,2,0,1.0,0.0,-999.99, '.\Database\DRN\VERSION_1\RIVER_SECUNDAIR\RIVER_SECUNDAIR_BOTTOM_WINTER.IDF' >>> (DEL) Drainage Level (IDF) <<< + + +0002,(GHB),1, general +winter +002,001 +1,2,1,1.0,0.0,-999.99, '.\Database\DRN\VERSION_1\IPEST_DRAINAGE_CONDUCTANCE.IDF' >>> (CON) Conductance (IDF) <<< +1,2,1,1.0,0.0,-999.99, '.\Database\DRN\VERSION_1\DRAINAGE_STAGE.IDF' >>> (DEL) Drainage Level (IDF) <<< +summer +002,001 +1,2,1,1.0,0.0,-999.99, '.\Database\DRN\VERSION_1\IPEST_DRAINAGE_CONDUCTANCE.IDF' >>> (CON) Conductance (IDF) <<< +1,2,1,1.0,0.0,-999.99, '.\Database\DRN\VERSION_1\DRAINAGE_STAGE.IDF' >>> (DEL) Drainage Level (IDF) <<< + +0001,(CHD),1, Constant Head +STEADY-STATE +001,37 +1,2,1,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L1.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,2,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L2.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,3,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L3.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,4,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L4.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,5,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L5.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,6,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L6.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,7,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L7.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,8,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L8.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,9,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L9.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,10,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L10.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,11,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L11.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,12,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L12.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,13,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L13.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,14,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L14.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,15,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L15.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,16,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L16.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,17,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L17.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,18,1.0,0.0,-999.99, '.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L18.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,19,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L19.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,20,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L20.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,21,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L21.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,22,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L22.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,23,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L23.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,24,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L24.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,25,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L25.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,26,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L26.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,27,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L27.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,28,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L28.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,29,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L29.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,30,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L30.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,31,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L31.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,32,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L32.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,33,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L33.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,34,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L34.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,35,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L35.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,36,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L36.IDF' >>> (SHD) Starting Heads (IDF) <<< +1,2,37,1.0,0.0,-999.99,'.\Database\SHD\VERSION_1\STATIONAIR\\25\HEAD_STEADY-STATE_L37.IDF' >>> (SHD) Starting Heads (IDF) <<< + + +0001,(PCG),1, Precondition Conjugate-Gradient + MXITER= 5000 + ITER1= 20 + HCLOSE= 0.1000000E-02 + RCLOSE= 0.1000000 + RELAX= 0.9800000 + NPCOND= 1 + IPRPCG= 1 + MUTPCG= 0 + DAMPPCG= 1.000000 + DAMPPCGT=1.000000 + IQERROR= 0 + QERROR= 0.1000000 + +Periods +summer +01-04-1990 00:00:00 +winter +01-10-1990 00:00:00 + +Species +"benzene",1 + +""" diff --git a/imod/tests/test_formats/test_disv_conversion.py b/imod/tests/test_formats/test_disv_conversion.py index 48e11fabc..2b7dbb950 100644 --- a/imod/tests/test_formats/test_disv_conversion.py +++ b/imod/tests/test_formats/test_disv_conversion.py @@ -25,7 +25,6 @@ def create_trigrid(ibound): return grid -@pytest.mark.skipif(xu_version_to_skip, reason="xugrid == 0.5.0 | xugrid < 0.4.0") @pytest.mark.usefixtures("imodflow_model") @pytest.mark.parametrize("create_grid", [create_quadgrid, create_trigrid]) def test_convert_to_disv(imodflow_model, tmp_path, create_grid): diff --git a/imod/tests/test_mf6/test_mf6_chd.py b/imod/tests/test_mf6/test_mf6_chd.py index 571df6dec..54ca67ceb 100644 --- a/imod/tests/test_mf6/test_mf6_chd.py +++ b/imod/tests/test_mf6/test_mf6_chd.py @@ -197,11 +197,13 @@ def test_write_concentration_period_data(head_fc, concentration_fc): @pytest.mark.usefixtures("imod5_dataset") def test_from_imod5(imod5_dataset, tmp_path): - target_dis = StructuredDiscretization.from_imod5_data(imod5_dataset) + imod5_data = imod5_dataset[0] + + target_dis = StructuredDiscretization.from_imod5_data(imod5_data) chd3 = imod.mf6.ConstantHead.from_imod5_data( "chd-3", - imod5_dataset, + imod5_data, target_dis, regridder_types=None, ) @@ -217,10 +219,12 @@ def test_from_imod5(imod5_dataset, tmp_path): @pytest.mark.usefixtures("imod5_dataset") def test_from_imod5_shd(imod5_dataset, tmp_path): - target_dis = StructuredDiscretization.from_imod5_data(imod5_dataset) + imod5_data = imod5_dataset[0] + + target_dis = StructuredDiscretization.from_imod5_data(imod5_data) chd_shd = imod.mf6.ConstantHead.from_imod5_shd_data( - imod5_dataset, + imod5_data, target_dis, regridder_types=None, ) diff --git a/imod/tests/test_mf6/test_mf6_dis.py b/imod/tests/test_mf6/test_mf6_dis.py index 73e3a7324..be502d8e5 100644 --- a/imod/tests/test_mf6/test_mf6_dis.py +++ b/imod/tests/test_mf6/test_mf6_dis.py @@ -196,7 +196,9 @@ def test_write_ascii_griddata_2d_3d(idomain_and_bottom, tmp_path): @pytest.mark.usefixtures("imod5_dataset") def test_from_imod5_data__idomain_values(imod5_dataset): - dis = imod.mf6.StructuredDiscretization.from_imod5_data(imod5_dataset) + imod5_data = imod5_dataset[0] + + dis = imod.mf6.StructuredDiscretization.from_imod5_data(imod5_data) # Test if idomain has appropriate count assert (dis["idomain"] == -1).sum() == 371824 @@ -206,7 +208,9 @@ def test_from_imod5_data__idomain_values(imod5_dataset): @pytest.mark.usefixtures("imod5_dataset") def test_from_imod5_data__grid_extent(imod5_dataset): - dis = imod.mf6.StructuredDiscretization.from_imod5_data(imod5_dataset) + imod5_data = imod5_dataset[0] + + dis = imod.mf6.StructuredDiscretization.from_imod5_data(imod5_data) # Test if regridded to smallest grid resolution assert dis["top"].dx == 25.0 @@ -226,8 +230,9 @@ def test_from_imod5_data__write(imod5_dataset, tmp_path): directory = tmp_path / "dis_griddata" directory.mkdir() write_context = WriteContext(simulation_directory=directory) + imod5_data = imod5_dataset[0] - dis = imod.mf6.StructuredDiscretization.from_imod5_data(imod5_dataset) + dis = imod.mf6.StructuredDiscretization.from_imod5_data(imod5_data) # Test if package written without ValidationError dis.write(pkgname="dis", globaltimes=[], write_context=write_context) diff --git a/imod/tests/test_mf6/test_mf6_drn.py b/imod/tests/test_mf6/test_mf6_drn.py index 369ed26b8..2b6565505 100644 --- a/imod/tests/test_mf6/test_mf6_drn.py +++ b/imod/tests/test_mf6/test_mf6_drn.py @@ -1,5 +1,6 @@ import pathlib import textwrap +from datetime import datetime import numpy as np import pandas as pd @@ -472,9 +473,10 @@ def test_html_repr(drainage): assert html_string.split("
")[0] == "
Drainage" -@pytest.mark.usefixtures("imod5_dataset") -def test_from_imod5(imod5_dataset, tmp_path): - target_dis = StructuredDiscretization.from_imod5_data(imod5_dataset) +def test_from_imod5(imod5_dataset_periods, tmp_path): + period_data = imod5_dataset_periods[1] + imod5_dataset = imod5_dataset_periods[0] + target_dis = StructuredDiscretization.from_imod5_data(imod5_dataset, validate=False) target_npf = NodePropertyFlow.from_imod5_data( imod5_dataset, target_dis.dataset["idomain"] ) @@ -482,10 +484,13 @@ def test_from_imod5(imod5_dataset, tmp_path): drn_2 = imod.mf6.Drainage.from_imod5_data( "drn-2", imod5_dataset, + period_data, target_dis, target_npf, allocation_option=ALLOCATION_OPTION.at_elevation, distributing_option=DISTRIBUTING_OPTION.by_crosscut_thickness, + time_min=datetime(2002, 2, 2), + time_max=datetime(2022, 2, 2), regridder_types=None, ) diff --git a/imod/tests/test_mf6/test_mf6_generalheadboundary.py b/imod/tests/test_mf6/test_mf6_generalheadboundary.py new file mode 100644 index 000000000..665d7c600 --- /dev/null +++ b/imod/tests/test_mf6/test_mf6_generalheadboundary.py @@ -0,0 +1,27 @@ +from datetime import datetime + +import imod +from imod.mf6.dis import StructuredDiscretization +from imod.mf6.write_context import WriteContext + + +def test_from_imod5(imod5_dataset_periods, tmp_path): + period_data = imod5_dataset_periods[1] + imod5_dataset = imod5_dataset_periods[0] + target_dis = StructuredDiscretization.from_imod5_data(imod5_dataset, validate=False) + + ghb = imod.mf6.GeneralHeadBoundary.from_imod5_data( + "ghb", + imod5_dataset, + period_data, + target_dis, + time_min=datetime(2002, 2, 2), + time_max=datetime(2022, 2, 2), + regridder_types=None, + ) + + assert isinstance(ghb, imod.mf6.GeneralHeadBoundary) + + # write the packages for write validation + write_context = WriteContext(simulation_directory=tmp_path, use_binary=False) + ghb.write("ghb", [1], write_context) diff --git a/imod/tests/test_mf6/test_mf6_hfb.py b/imod/tests/test_mf6/test_mf6_hfb.py index 6468e293e..925106039 100644 --- a/imod/tests/test_mf6/test_mf6_hfb.py +++ b/imod/tests/test_mf6/test_mf6_hfb.py @@ -516,13 +516,14 @@ def test_set_options(print_input, parameterizable_basic_dis): @pytest.mark.usefixtures("imod5_dataset") def test_hfb_from_imod5(imod5_dataset, tmp_path): - target_dis = StructuredDiscretization.from_imod5_data(imod5_dataset) + imod5_data = imod5_dataset[0] + target_dis = StructuredDiscretization.from_imod5_data(imod5_data) target_npf = NodePropertyFlow.from_imod5_data( - imod5_dataset, target_dis.dataset["idomain"] + imod5_data, target_dis.dataset["idomain"] ) hfb = SingleLayerHorizontalFlowBarrierResistance.from_imod5_dataset( - "hfb-3", imod5_dataset + "hfb-3", imod5_data ) hfb_package = hfb.to_mf6_pkg( target_dis["idomain"], target_dis["top"], target_dis["bottom"], target_npf["k"] diff --git a/imod/tests/test_mf6/test_mf6_ic.py b/imod/tests/test_mf6/test_mf6_ic.py index 8c9112c51..d1bc23623 100644 --- a/imod/tests/test_mf6/test_mf6_ic.py +++ b/imod/tests/test_mf6/test_mf6_ic.py @@ -45,7 +45,7 @@ def test_wrong_arguments(): @pytest.mark.usefixtures("imod5_dataset") def test_from_imod5(imod5_dataset, tmp_path): - data = deepcopy(imod5_dataset) + data = deepcopy(imod5_dataset[0]) target_grid = data["khv"]["kh"] diff --git a/imod/tests/test_mf6/test_mf6_npf.py b/imod/tests/test_mf6/test_mf6_npf.py index 6c4715805..266d71232 100644 --- a/imod/tests/test_mf6/test_mf6_npf.py +++ b/imod/tests/test_mf6/test_mf6_npf.py @@ -213,7 +213,7 @@ def test_configure_xt3d(tmp_path): @pytest.mark.usefixtures("imod5_dataset") def test_npf_from_imod5_isotropic(imod5_dataset, tmp_path): - data = deepcopy(imod5_dataset) + data = deepcopy(imod5_dataset[0]) # throw out kva (=vertical anisotropy array) and ani (=horizontal anisotropy array) data.pop("kva") data.pop("ani") @@ -235,7 +235,7 @@ def test_npf_from_imod5_isotropic(imod5_dataset, tmp_path): @pytest.mark.usefixtures("imod5_dataset") def test_npf_from_imod5_horizontal_anisotropy(imod5_dataset, tmp_path): - data = deepcopy(imod5_dataset) + data = deepcopy(imod5_dataset[0]) # throw out kva (=vertical anisotropy array) data.pop("kva") @@ -269,7 +269,7 @@ def test_npf_from_imod5_horizontal_anisotropy(imod5_dataset, tmp_path): @pytest.mark.usefixtures("imod5_dataset") def test_npf_from_imod5_vertical_anisotropy(imod5_dataset, tmp_path): - data = deepcopy(imod5_dataset) + data = deepcopy(imod5_dataset[0]) # throw out ani (=horizontal anisotropy array) data.pop("ani") diff --git a/imod/tests/test_mf6/test_mf6_rch.py b/imod/tests/test_mf6/test_mf6_rch.py index 4f3e37da9..a561afe72 100644 --- a/imod/tests/test_mf6/test_mf6_rch.py +++ b/imod/tests/test_mf6/test_mf6_rch.py @@ -331,7 +331,7 @@ def test_clip_box(rch_dict): @pytest.mark.usefixtures("imod5_dataset") def test_planar_rch_from_imod5_constant(imod5_dataset, tmp_path): - data = deepcopy(imod5_dataset) + data = deepcopy(imod5_dataset[0]) target_discretization = StructuredDiscretization.from_imod5_data(data) # create a planar grid with time-independent recharge @@ -352,7 +352,7 @@ def test_planar_rch_from_imod5_constant(imod5_dataset, tmp_path): @pytest.mark.usefixtures("imod5_dataset") def test_planar_rch_from_imod5_transient(imod5_dataset, tmp_path): - data = deepcopy(imod5_dataset) + data = deepcopy(imod5_dataset[0]) target_discretization = StructuredDiscretization.from_imod5_data(data) # create a grid with recharge for 3 timesteps @@ -378,7 +378,7 @@ def test_planar_rch_from_imod5_transient(imod5_dataset, tmp_path): @pytest.mark.usefixtures("imod5_dataset") def test_non_planar_rch_from_imod5_constant(imod5_dataset, tmp_path): - data = deepcopy(imod5_dataset) + data = deepcopy(imod5_dataset[0]) target_discretization = StructuredDiscretization.from_imod5_data(data) # make the first layer of the target grid inactive @@ -411,7 +411,7 @@ def test_non_planar_rch_from_imod5_constant(imod5_dataset, tmp_path): @pytest.mark.usefixtures("imod5_dataset") def test_non_planar_rch_from_imod5_transient(imod5_dataset, tmp_path): - data = deepcopy(imod5_dataset) + data = deepcopy(imod5_dataset[0]) target_discretization = StructuredDiscretization.from_imod5_data(data) # make the first layer of the target grid inactive target_grid = target_discretization.dataset["idomain"] diff --git a/imod/tests/test_mf6/test_mf6_riv.py b/imod/tests/test_mf6/test_mf6_riv.py index ff32bab47..d48cab220 100644 --- a/imod/tests/test_mf6/test_mf6_riv.py +++ b/imod/tests/test_mf6/test_mf6_riv.py @@ -2,6 +2,7 @@ import re import tempfile import textwrap +from datetime import datetime import numpy as np import pytest @@ -395,15 +396,20 @@ def test_write_concentration_period_data(concentration_fc): @pytest.mark.usefixtures("imod5_dataset") def test_import_river_from_imod5(imod5_dataset, tmp_path): + imod5_data = imod5_dataset[0] + period_data = imod5_dataset[1] globaltimes = [np.datetime64("2000-01-01")] - target_dis = StructuredDiscretization.from_imod5_data(imod5_dataset) + target_dis = StructuredDiscretization.from_imod5_data(imod5_data) (riv, drn) = imod.mf6.River.from_imod5_data( "riv-1", - imod5_dataset, + imod5_data, + period_data, target_dis, - ALLOCATION_OPTION.at_elevation, - DISTRIBUTING_OPTION.by_crosscut_thickness, + time_min=datetime(2000, 1, 1), + time_max=datetime(2002, 1, 1), + allocation_option_riv=ALLOCATION_OPTION.at_elevation, + distributing_option_riv=DISTRIBUTING_OPTION.by_crosscut_thickness, regridder_types=None, ) @@ -428,17 +434,65 @@ def test_import_river_from_imod5(imod5_dataset, tmp_path): @pytest.mark.usefixtures("imod5_dataset") def test_import_river_from_imod5_infiltration_factors(imod5_dataset): - target_dis = StructuredDiscretization.from_imod5_data(imod5_dataset) + imod5_data = imod5_dataset[0] + period_data = imod5_dataset[1] + target_dis = StructuredDiscretization.from_imod5_data(imod5_data) + + original_infiltration_factor = imod5_data["riv-1"]["infiltration_factor"] + imod5_data["riv-1"]["infiltration_factor"] = ones_like(original_infiltration_factor) + + (riv, drn) = imod.mf6.River.from_imod5_data( + "riv-1", + imod5_data, + period_data, + target_dis, + time_min=datetime(2000, 1, 1), + time_max=datetime(2002, 1, 1), + allocation_option_riv=ALLOCATION_OPTION.at_elevation, + distributing_option_riv=DISTRIBUTING_OPTION.by_crosscut_thickness, + regridder_types=None, + ) - original_infiltration_factor = imod5_dataset["riv-1"]["infiltration_factor"] - imod5_dataset["riv-1"]["infiltration_factor"] = ones_like( + assert riv is not None + assert drn is None + + imod5_data["riv-1"]["infiltration_factor"] = zeros_like( original_infiltration_factor ) + (riv, drn) = imod.mf6.River.from_imod5_data( + "riv-1", + imod5_data, + period_data, + target_dis, + time_min=datetime(2000, 1, 1), + time_max=datetime(2002, 1, 1), + allocation_option_riv=ALLOCATION_OPTION.at_elevation, + distributing_option_riv=DISTRIBUTING_OPTION.by_crosscut_thickness, + regridder_types=None, + ) + + assert riv is None + assert drn is not None + + # teardown + imod5_data["riv-1"]["infiltration_factor"] = original_infiltration_factor + + +def test_import_river_from_imod5_period_data(imod5_dataset_periods): + imod5_data = imod5_dataset_periods[0] + imod5_periods = imod5_dataset_periods[1] + target_dis = StructuredDiscretization.from_imod5_data(imod5_data, validate=False) + + original_infiltration_factor = imod5_data["riv-1"]["infiltration_factor"] + imod5_data["riv-1"]["infiltration_factor"] = ones_like(original_infiltration_factor) (riv, drn) = imod.mf6.River.from_imod5_data( "riv-1", - imod5_dataset, + imod5_data, + imod5_periods, target_dis, + datetime(2002, 2, 2), + datetime(2022, 2, 2), ALLOCATION_OPTION.at_elevation, DISTRIBUTING_OPTION.by_crosscut_thickness, regridder_types=None, @@ -447,13 +501,16 @@ def test_import_river_from_imod5_infiltration_factors(imod5_dataset): assert riv is not None assert drn is None - imod5_dataset["riv-1"]["infiltration_factor"] = zeros_like( + imod5_data["riv-1"]["infiltration_factor"] = zeros_like( original_infiltration_factor ) (riv, drn) = imod.mf6.River.from_imod5_data( "riv-1", - imod5_dataset, + imod5_data, + imod5_periods, target_dis, + datetime(2002, 2, 2), + datetime(2022, 2, 2), ALLOCATION_OPTION.at_elevation, DISTRIBUTING_OPTION.by_crosscut_thickness, regridder_types=None, @@ -463,4 +520,6 @@ def test_import_river_from_imod5_infiltration_factors(imod5_dataset): assert drn is not None # teardown - imod5_dataset["riv-1"]["infiltration_factor"] = original_infiltration_factor + imod5_dataset_periods[0]["riv-1"]["infiltration_factor"] = ( + original_infiltration_factor + ) diff --git a/imod/tests/test_mf6/test_mf6_simulation.py b/imod/tests/test_mf6/test_mf6_simulation.py index dccba0b04..96f4ceac5 100644 --- a/imod/tests/test_mf6/test_mf6_simulation.py +++ b/imod/tests/test_mf6/test_mf6_simulation.py @@ -471,12 +471,17 @@ def compare_submodel_partition_info(first: PartitionInfo, second: PartitionInfo) @pytest.mark.usefixtures("imod5_dataset") def test_import_from_imod5(imod5_dataset, tmp_path): + imod5_data = imod5_dataset[0] + period_data = imod5_dataset[1] default_simulation_allocation_options = SimulationAllocationOptions default_simulation_distributing_options = SimulationDistributingOptions simulation = Modflow6Simulation.from_imod5_data( - imod5_dataset, + imod5_data, + period_data, default_simulation_allocation_options, default_simulation_distributing_options, + datetime(2000, 1, 1), + datetime(2002, 1, 1), ) simulation["imported_model"]["oc"] = OutputControl( diff --git a/imod/tests/test_mf6/test_mf6_sto.py b/imod/tests/test_mf6/test_mf6_sto.py index 6d90bc9e8..e748f97e5 100644 --- a/imod/tests/test_mf6/test_mf6_sto.py +++ b/imod/tests/test_mf6/test_mf6_sto.py @@ -1,6 +1,5 @@ import pathlib import textwrap -from copy import deepcopy import numpy as np import pytest @@ -433,7 +432,7 @@ def test_check_nan_in_active_cell(sy_layered, convertible, dis): @pytest.mark.usefixtures("imod5_dataset") def test_from_imod5(imod5_dataset, tmp_path): - data = deepcopy(imod5_dataset) + data = imod5_dataset[0] target_grid = data["khv"]["kh"] @@ -451,7 +450,8 @@ def test_from_imod5(imod5_dataset, tmp_path): @pytest.mark.usefixtures("imod5_dataset") def test_from_imod5_steady_state(imod5_dataset): - data = deepcopy(imod5_dataset) + data = imod5_dataset[0] + data["sto"]["storage_coefficient"].values[:] = 0 target_grid = data["khv"]["kh"] diff --git a/imod/tests/test_mf6/test_mf6_wel.py b/imod/tests/test_mf6/test_mf6_wel.py index 09d388220..b81c26131 100644 --- a/imod/tests/test_mf6/test_mf6_wel.py +++ b/imod/tests/test_mf6/test_mf6_wel.py @@ -820,13 +820,12 @@ def test_render__concentration_dis_vertices_transient(well_test_data_transient): @pytest.mark.usefixtures("imod5_dataset") def test_import_and_convert_to_mf6(imod5_dataset, tmp_path): - target_dis = StructuredDiscretization.from_imod5_data(imod5_dataset) - target_npf = NodePropertyFlow.from_imod5_data( - imod5_dataset, target_dis.dataset["idomain"] - ) + data = imod5_dataset[0] + target_dis = StructuredDiscretization.from_imod5_data(data) + target_npf = NodePropertyFlow.from_imod5_data(data, target_dis.dataset["idomain"]) # import grid-agnostic well from imod5 data (it contains 1 well) - wel = Well.from_imod5_data("wel-1", imod5_dataset) + wel = Well.from_imod5_data("wel-1", data) assert wel.dataset["x"].values[0] == 197910.0 assert wel.dataset["y"].values[0] == 362860.0 assert np.mean(wel.dataset["rate"].values) == -323.8936170212766 diff --git a/imod/util/expand_repetitions.py b/imod/util/expand_repetitions.py new file mode 100644 index 000000000..28f2ec57e --- /dev/null +++ b/imod/util/expand_repetitions.py @@ -0,0 +1,17 @@ +import itertools +from datetime import datetime +from typing import Dict, List + + +def expand_repetitions( + repeat_stress: List[datetime], time_min: datetime, time_max: datetime +) -> Dict[datetime, datetime]: + expanded = {} + for year, date in itertools.product( + range(time_min.year, time_max.year + 1), + repeat_stress, + ): + newdate = date.replace(year=year) + if newdate < time_max: + expanded[newdate] = date + return expanded From e2d12704b3b345cc88658f5761e765a10743ad2b Mon Sep 17 00:00:00 2001 From: luitjansl <64598682+luitjansl@users.noreply.github.com> Date: Thu, 11 Jul 2024 09:33:52 +0200 Subject: [PATCH 26/53] added logging and error messages for well import when (#1104) Fixes #1095 # Description This PR adds logging to well import if the well was assigned to a layer. This layer will not be used and the user is informed of that in the log. If the filter_top and filter_bottom properties are not present in the imported dataset, both a log message and an exception is generated, as we can't import the well with this information missing # Checklist - [X] Links to correct issue - [ ] Update changelog, if changes affect users - [X] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [X] Unit tests were added - [ ] **If feature added**: Added/extended example --- imod/mf6/wel.py | 25 +++++++++ imod/tests/test_mf6/test_mf6_wel.py | 87 +++++++++++++++++++++++++++++ 2 files changed, 112 insertions(+) diff --git a/imod/mf6/wel.py b/imod/mf6/wel.py index f05d1b0e8..85705b579 100644 --- a/imod/mf6/wel.py +++ b/imod/mf6/wel.py @@ -653,6 +653,31 @@ def from_imod5_data( minimum_k: float = 0.1, minimum_thickness: float = 1.0, ) -> "Well": + if "layer" in imod5_data[key].keys(): + if imod5_data[key]["layer"] != 0: + log_msg = textwrap.dedent( + f""" + In well {key} a layer was assigned, but this is not + supported. Assignment will be done based on filter_top and + filter_bottom, and the chosen layer ({imod5_data[key]["layer"]}) + will be ignored.""" + ) + logger.log( + loglevel=LogLevel.WARNING, message=log_msg, additional_depth=2 + ) + + if ( + "filt_top" not in imod5_data[key]["dataframe"].columns + or "filt_bot" not in imod5_data[key]["dataframe"].columns + ): + log_msg = textwrap.dedent( + f""" + In well {key} the filt_top and filt_bot columns were not both found; + this is not supported for import.""" + ) + logger.log(loglevel=LogLevel.ERROR, message=log_msg, additional_depth=2) + raise ValueError(log_msg) + df: pd.DataFrame = imod5_data[key]["dataframe"] # Groupby unique wells, to get dataframes per time. diff --git a/imod/tests/test_mf6/test_mf6_wel.py b/imod/tests/test_mf6/test_mf6_wel.py index b81c26131..aafe90fd8 100644 --- a/imod/tests/test_mf6/test_mf6_wel.py +++ b/imod/tests/test_mf6/test_mf6_wel.py @@ -874,3 +874,90 @@ def test_import_from_imod5_with_duplication(well_duplication_import_prj): assert np.all(wel2.x == np.array([191112.11, 191171.96, 191231.52])) assert wel1.dataset["rate"].shape == (6, 3) assert wel2.dataset["rate"].shape == (6, 3) + + +@pytest.mark.parametrize("layer", [0, 1]) +@pytest.mark.usefixtures("well_regular_import_prj") +def test_logmessage_for_layer_assignment_import_imod5( + tmp_path, well_regular_import_prj, layer +): + imod5dict = open_projectfile_data(well_regular_import_prj) + + logfile_path = tmp_path / "logfile.txt" + imod5dict[0]["wel-1"]["layer"] = layer + + try: + with open(logfile_path, "w") as sys.stdout: + # start logging + imod.logging.configure( + LoggerType.PYTHON, + log_level=LogLevel.WARNING, + add_default_file_handler=False, + add_default_stream_handler=True, + ) + + _ = imod.mf6.Well.from_imod5_data("wel-1", imod5dict[0]) + + finally: + # turn the logger off again + imod.logging.configure( + LoggerType.NULL, + log_level=LogLevel.WARNING, + add_default_file_handler=False, + add_default_stream_handler=False, + ) + + # import grid-agnostic well from imod5 data (it contains 2 packages with 3 wells each) + with open(logfile_path, "r") as log_file: + log = log_file.read() + message_required = layer != 0 + message_present = ( + "In well wel-1 a layer was assigned, but this is not\nsupported" in log + ) + assert message_required == message_present + + +@pytest.mark.parametrize("remove", ["filt_top", "filt_bot", None]) +@pytest.mark.usefixtures("well_regular_import_prj") +def test_logmessage_for_missing_filter_settings( + tmp_path, well_regular_import_prj, remove +): + imod5dict = open_projectfile_data(well_regular_import_prj) + logfile_path = tmp_path / "logfile.txt" + if remove is not None: + imod5dict[0]["wel-1"]["dataframe"] = imod5dict[0]["wel-1"]["dataframe"].drop( + remove, axis=1 + ) + + try: + with open(logfile_path, "w") as sys.stdout: + # start logging + imod.logging.configure( + LoggerType.PYTHON, + log_level=LogLevel.WARNING, + add_default_file_handler=False, + add_default_stream_handler=True, + ) + + _ = imod.mf6.Well.from_imod5_data("wel-1", imod5dict[0]) + except Exception: + assert remove is not None + + finally: + # turn the logger off again + imod.logging.configure( + LoggerType.NULL, + log_level=LogLevel.WARNING, + add_default_file_handler=False, + add_default_stream_handler=False, + ) + + # import grid-agnostic well from imod5 data (it contains 2 packages with 3 wells each) + with open(logfile_path, "r") as log_file: + log = log_file.read() + message_required = remove is not None + message_present = ( + "In well wel-1 the filt_top and filt_bot columns were not both found;" + in log + ) + assert message_required == message_present From bc43915cacabc4b3218179b85fff262cf1c60b34 Mon Sep 17 00:00:00 2001 From: luitjansl <64598682+luitjansl@users.noreply.github.com> Date: Fri, 12 Jul 2024 17:11:32 +0200 Subject: [PATCH 27/53] Issue #1091 from_imod5_data using regrid_cache (#1105) Fixes #1091 # Description -the regrid_context was renamed to regrid_cache -we can now pass regridder settings to the from_imod5 import functions for simulation, model and packages -added tests. # Checklist - [X] Links to correct issue - [ ] Update changelog, if changes affect users - [ ] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [X] Unit tests were added - [ ] **If feature added**: Added/extended example --- .gitignore | 3 ++ .../mf6/different_ways_to_regrid_models.py | 4 +- examples/user-guide/08-regridding.py | 6 +-- imod/mf6/chd.py | 29 +++++------- imod/mf6/dis.py | 11 ++--- imod/mf6/drn.py | 16 +++---- imod/mf6/ghb.py | 10 ++-- imod/mf6/ic.py | 13 ++--- imod/mf6/model.py | 6 +-- imod/mf6/model_gwf.py | 45 +++++++++++++----- imod/mf6/npf.py | 13 ++--- imod/mf6/package.py | 6 +-- imod/mf6/rch.py | 16 +++---- imod/mf6/regrid/regrid_schemes.py | 5 ++ imod/mf6/riv.py | 20 +++----- imod/mf6/simulation.py | 15 ++++-- imod/mf6/sto.py | 15 ++---- imod/mf6/utilities/regrid.py | 47 +++++++++---------- imod/tests/test_mf6/test_mf6_hfb.py | 4 +- imod/tests/test_mf6/test_mf6_npf.py | 34 ++++++++++++++ .../tests/test_mf6/test_mf6_regrid_package.py | 24 +++++----- .../test_mf6/test_mf6_regrid_simulation.py | 4 +- imod/tests/test_mf6/test_mf6_simulation.py | 42 +++++++++++++++++ .../test_mf6_unsupported_grid_operations.py | 4 +- 24 files changed, 228 insertions(+), 164 deletions(-) diff --git a/.gitignore b/.gitignore index 3c0b0a2a1..fd95f7d8d 100644 --- a/.gitignore +++ b/.gitignore @@ -140,3 +140,6 @@ examples/data # pixi environments .pixi +/imod/tests/mydask.png +/imod/tests/unittest_report.xml +/imod/tests/examples_report.xml diff --git a/examples/mf6/different_ways_to_regrid_models.py b/examples/mf6/different_ways_to_regrid_models.py index af0bbc774..d789766f8 100644 --- a/examples/mf6/different_ways_to_regrid_models.py +++ b/examples/mf6/different_ways_to_regrid_models.py @@ -100,10 +100,10 @@ # because initializing a regridder is costly. regridder_types = NodePropertyFlowRegridMethod(k=(RegridderType.CENTROIDLOCATOR,)) -regrid_context = RegridderWeightsCache() +regrid_cache = RegridderWeightsCache() npf_regridded = model["npf"].regrid_like( target_grid=target_grid, - regrid_context=regrid_context, + regrid_cache=regrid_cache, regridder_types=regridder_types, ) new_model["npf"] = npf_regridded diff --git a/examples/user-guide/08-regridding.py b/examples/user-guide/08-regridding.py index 178e6044f..ee81e832c 100644 --- a/examples/user-guide/08-regridding.py +++ b/examples/user-guide/08-regridding.py @@ -191,9 +191,9 @@ # undergo custom regridding at this stage. from imod.mf6.utilities.regrid import RegridderWeightsCache -regrid_context = RegridderWeightsCache() +regrid_cache = RegridderWeightsCache() -regrid_context +regrid_cache # %% # Regrid the recharge package with a custom regridder. In this case we opt @@ -206,7 +206,7 @@ regridded_recharge = original_rch_package.regrid_like( target_grid, - regrid_context=regrid_context, + regrid_cache=regrid_cache, regridder_types=regridder_types, ) diff --git a/imod/mf6/chd.py b/imod/mf6/chd.py index 7e5c20d0a..b01a11350 100644 --- a/imod/mf6/chd.py +++ b/imod/mf6/chd.py @@ -1,4 +1,3 @@ -from dataclasses import asdict from typing import Optional import numpy as np @@ -8,9 +7,8 @@ from imod.mf6.boundary_condition import BoundaryCondition from imod.mf6.dis import StructuredDiscretization from imod.mf6.interfaces.iregridpackage import IRegridPackage -from imod.mf6.regrid.regrid_schemes import ConstantHeadRegridMethod, RegridMethodType +from imod.mf6.regrid.regrid_schemes import ConstantHeadRegridMethod from imod.mf6.utilities.regrid import RegridderWeightsCache, _regrid_package_data -from imod.mf6.utilities.regridding_types import RegridderType from imod.mf6.validation import BOUNDARY_DIMS_SCHEMA, CONC_DIMS_SCHEMA from imod.schemata import ( AllInsideNoDataSchema, @@ -157,7 +155,8 @@ def from_imod5_data( key: str, imod5_data: dict[str, dict[str, GridDataArray]], target_discretization: StructuredDiscretization, - regridder_types: Optional[RegridMethodType] = None, + regridder_types: Optional[ConstantHeadRegridMethod] = None, + regrid_cache: RegridderWeightsCache = RegridderWeightsCache(), ) -> "ConstantHead": """ Construct a ConstantHead-package from iMOD5 data, loaded with the @@ -199,6 +198,7 @@ def from_imod5_data( imod5_data["bnd"]["ibound"], target_discretization, regridder_types, + regrid_cache, ) @classmethod @@ -207,7 +207,8 @@ def from_imod5_shd_data( cls, imod5_data: dict[str, dict[str, GridDataArray]], target_discretization: StructuredDiscretization, - regridder_types: Optional[RegridMethodType] = None, + regridder_types: Optional[ConstantHeadRegridMethod] = None, + regrid_cache: RegridderWeightsCache = RegridderWeightsCache(), ) -> "ConstantHead": """ Construct a ConstantHead-package from iMOD5 data, loaded with the @@ -231,7 +232,7 @@ def from_imod5_shd_data( target_discretization: StructuredDiscretization package The grid that should be used for the new package. Does not need to be identical to one of the input grids. - regridder_types: RegridMethodType, optional + regridder_types: ConstantHeadRegridMethod, optional Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. @@ -244,6 +245,7 @@ def from_imod5_shd_data( imod5_data["bnd"]["ibound"], target_discretization, regridder_types, + regrid_cache, ) @classmethod @@ -252,25 +254,18 @@ def _from_head_data( head: GridDataArray, ibound: GridDataArray, target_discretization: StructuredDiscretization, - regridder_types: Optional[RegridMethodType] = None, + regridder_types: Optional[ConstantHeadRegridMethod] = None, + regrid_cache: RegridderWeightsCache = RegridderWeightsCache(), ) -> "ConstantHead": target_idomain = target_discretization.dataset["idomain"] if regridder_types is None: - regridder_settings = asdict(cls.get_regrid_methods(), dict_factory=dict) - else: - regridder_settings = asdict(regridder_types, dict_factory=dict) - - # appart from the arrays needed for the ConstantHead package, we will - # also regrid ibound. - regridder_settings["ibound"] = (RegridderType.OVERLAP, "mode") - - regrid_context = RegridderWeightsCache() + regridder_types = ConstantHead.get_regrid_methods() data = {"head": head, "ibound": ibound} regridded_package_data = _regrid_package_data( - data, target_idomain, regridder_settings, regrid_context, {} + data, target_idomain, regridder_types, regrid_cache, {} ) head = regridded_package_data["head"] ibound = regridded_package_data["ibound"] diff --git a/imod/mf6/dis.py b/imod/mf6/dis.py index 1cebeef5d..c120527bc 100644 --- a/imod/mf6/dis.py +++ b/imod/mf6/dis.py @@ -1,5 +1,4 @@ import pathlib -from dataclasses import asdict from typing import Any, List, Optional import numpy as np @@ -163,6 +162,7 @@ def from_imod5_data( cls, imod5_data: dict[str, dict[str, GridDataArray]], regridder_types: Optional[RegridMethodType] = None, + regrid_cache: RegridderWeightsCache = RegridderWeightsCache(), validate: bool = True, ) -> "StructuredDiscretization": """ @@ -182,7 +182,7 @@ def from_imod5_data( imod5_data: dict Dictionary with iMOD5 data. This can be constructed from the :func:`imod.formats.prj.open_projectfile_data` method. - regridder_types: RegridMethodType, optional + regridder_types: DiscretizationRegridMethod, optional Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. @@ -200,13 +200,10 @@ def from_imod5_data( target_grid = create_smallest_target_grid(*data.values()) if regridder_types is None: - regridder_settings = asdict(cls.get_regrid_methods(), dict_factory=dict) - else: - regridder_settings = asdict(regridder_types, dict_factory=dict) - regrid_context = RegridderWeightsCache() + regridder_types = StructuredDiscretization.get_regrid_methods() new_package_data = _regrid_package_data( - data, target_grid, regridder_settings, regrid_context + data, target_grid, regridder_types, regrid_cache ) # Validate iMOD5 data diff --git a/imod/mf6/drn.py b/imod/mf6/drn.py index 05b240064..3bae14d01 100644 --- a/imod/mf6/drn.py +++ b/imod/mf6/drn.py @@ -1,4 +1,3 @@ -from dataclasses import asdict from datetime import datetime from typing import Optional @@ -9,7 +8,7 @@ from imod.mf6.dis import StructuredDiscretization from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.npf import NodePropertyFlow -from imod.mf6.regrid.regrid_schemes import DrainageRegridMethod, RegridMethodType +from imod.mf6.regrid.regrid_schemes import DrainageRegridMethod from imod.mf6.utilities.regrid import ( RegridderWeightsCache, _regrid_package_data, @@ -175,7 +174,8 @@ def from_imod5_data( distributing_option: DISTRIBUTING_OPTION, time_min: datetime, time_max: datetime, - regridder_types: Optional[RegridMethodType] = None, + regridder_types: Optional[DrainageRegridMethod] = None, + regrid_cache: RegridderWeightsCache = RegridderWeightsCache(), ) -> "Drainage": """ Construct a drainage-package from iMOD5 data, loaded with the @@ -206,7 +206,7 @@ def from_imod5_data( Begin-time of the simulation. Used for expanding period data. time_max: datetime End-time of the simulation. Used for expanding period data. - regridder_types: RegridMethodType, optional + regridder_types: DrainageRegridMethod, optional Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. @@ -226,14 +226,10 @@ def from_imod5_data( is_planar = is_planar_grid(data["elevation"]) if regridder_types is None: - regridder_settings = asdict(cls.get_regrid_methods(), dict_factory=dict) - else: - regridder_settings = asdict(regridder_types, dict_factory=dict) - - regrid_context = RegridderWeightsCache() + regridder_types = Drainage.get_regrid_methods() regridded_package_data = _regrid_package_data( - data, target_idomain, regridder_settings, regrid_context, {} + data, target_idomain, regridder_types, regrid_cache, {} ) conductance = regridded_package_data["conductance"] diff --git a/imod/mf6/ghb.py b/imod/mf6/ghb.py index fb40abc8f..ee7b8f6d1 100644 --- a/imod/mf6/ghb.py +++ b/imod/mf6/ghb.py @@ -1,4 +1,3 @@ -from dataclasses import asdict from datetime import datetime from typing import Optional @@ -167,6 +166,7 @@ def from_imod5_data( target_discretization, time_min: datetime, time_max: datetime, + regrid_cache: RegridderWeightsCache = RegridderWeightsCache(), regridder_types: Optional[RegridMethodType] = None, ) -> "GeneralHeadBoundary": """ @@ -214,14 +214,10 @@ def from_imod5_data( } if regridder_types is None: - regridder_settings = asdict(cls.get_regrid_methods(), dict_factory=dict) - else: - regridder_settings = asdict(regridder_types, dict_factory=dict) - - regrid_context = RegridderWeightsCache() + regridder_types = GeneralHeadBoundaryRegridMethod() regridded_package_data = _regrid_package_data( - data, idomain, regridder_settings, regrid_context, {} + data, idomain, regridder_types, regrid_cache, {} ) ghb = GeneralHeadBoundary(**regridded_package_data) diff --git a/imod/mf6/ic.py b/imod/mf6/ic.py index fc615e9a9..09e0c6d32 100644 --- a/imod/mf6/ic.py +++ b/imod/mf6/ic.py @@ -1,5 +1,4 @@ import warnings -from dataclasses import asdict from typing import Any, Optional import numpy as np @@ -9,7 +8,6 @@ from imod.mf6.package import Package from imod.mf6.regrid.regrid_schemes import ( InitialConditionsRegridMethod, - RegridMethodType, ) from imod.mf6.utilities.regrid import RegridderWeightsCache, _regrid_package_data from imod.mf6.validation import PKG_DIMS_SCHEMA @@ -101,7 +99,8 @@ def from_imod5_data( cls, imod5_data: dict[str, dict[str, GridDataArray]], target_grid: GridDataArray, - regridder_types: Optional[RegridMethodType] = None, + regridder_types: Optional[InitialConditionsRegridMethod] = None, + regrid_cache: RegridderWeightsCache = RegridderWeightsCache(), ) -> "InitialConditions": """ Construct an InitialConditions-package from iMOD5 data, loaded with the @@ -133,13 +132,9 @@ def from_imod5_data( } if regridder_types is None: - regridder_settings = asdict(cls.get_regrid_methods(), dict_factory=dict) - else: - regridder_settings = asdict(regridder_types, dict_factory=dict) - - regrid_context = RegridderWeightsCache() + regridder_types = InitialConditions.get_regrid_methods() new_package_data = _regrid_package_data( - data, target_grid, regridder_settings, regrid_context, {} + data, target_grid, regridder_types, regrid_cache, {} ) return cls(**new_package_data) diff --git a/imod/mf6/model.py b/imod/mf6/model.py index da1eb450c..c0df91480 100644 --- a/imod/mf6/model.py +++ b/imod/mf6/model.py @@ -524,7 +524,7 @@ def regrid_like( self, target_grid: GridDataArray, validate: bool = True, - regrid_context: Optional[RegridderWeightsCache] = None, + regrid_cache: Optional[RegridderWeightsCache] = None, ) -> "Modflow6Model": """ Creates a model by regridding the packages of this model to another discretization. @@ -538,7 +538,7 @@ def regrid_like( a grid defined over the same discretization as the one we want to regrid the package to validate: bool set to true to validate the regridded packages - regrid_context: Optional RegridderWeightsCache + regrid_cache: Optional RegridderWeightsCache stores regridder weights for different regridders. Can be used to speed up regridding, if the same regridders are used several times for regridding different arrays. @@ -547,7 +547,7 @@ def regrid_like( a model with similar packages to the input model, and with all the data-arrays regridded to another discretization, similar to the one used in input argument "target_grid" """ - return _regrid_like(self, target_grid, validate, regrid_context) + return _regrid_like(self, target_grid, validate, regrid_cache) def mask_all_packages( self, diff --git a/imod/mf6/model_gwf.py b/imod/mf6/model_gwf.py index c7e182569..d9029158b 100644 --- a/imod/mf6/model_gwf.py +++ b/imod/mf6/model_gwf.py @@ -20,6 +20,7 @@ from imod.mf6.regrid.regrid_schemes import RegridMethodType from imod.mf6.riv import River from imod.mf6.sto import StorageCoefficient +from imod.mf6.utilities.regrid import RegridderWeightsCache from imod.prepare.topsystem.default_allocation_methods import ( SimulationAllocationOptions, SimulationDistributingOptions, @@ -179,7 +180,7 @@ def from_imod5_data( distributing_options: SimulationDistributingOptions, time_min: datetime, time_max: datetime, - regridder_types: Optional[RegridMethodType] = None, + regridder_types: dict[str, RegridMethodType], ) -> "GroundwaterFlowModel": """ Imports a GroundwaterFlowModel (GWF) from the data in an IMOD5 project file. @@ -200,9 +201,12 @@ def from_imod5_data( object containing the conductivity distribution options per package type. If you want a package to have a different allocation option, then it should be imported separately - regridder_types: Optional[dict[str, dict[str, tuple[RegridderType, str]]]] - the first key is the package name. The second key is the array name, and the value is - the RegridderType tuple (method + function) + time_min: datetime + Begin-time of the simulation. + time_max: datetime + End-time of the simulation. + regridder_types: dict[str, RegridMethodType] + the key is the package name. The value is a subclass of RegridMethodType. Returns ------- @@ -212,23 +216,32 @@ def from_imod5_data( """ # first import the singleton packages # import discretization + regrid_cache = RegridderWeightsCache() dis_pkg = StructuredDiscretization.from_imod5_data( - imod5_data, regridder_types, False + imod5_data, regridder_types.get("dis"), regrid_cache, False ) grid = dis_pkg.dataset["idomain"] # import npf - npf_pkg = NodePropertyFlow.from_imod5_data(imod5_data, grid, regridder_types) + npf_pkg = NodePropertyFlow.from_imod5_data( + imod5_data, grid, regridder_types.get("npf"), regrid_cache + ) # import sto - sto_pkg = StorageCoefficient.from_imod5_data(imod5_data, grid, regridder_types) + sto_pkg = StorageCoefficient.from_imod5_data( + imod5_data, grid, regridder_types.get("sto"), regrid_cache + ) # import initial conditions - ic_pkg = InitialConditions.from_imod5_data(imod5_data, grid, regridder_types) + ic_pkg = InitialConditions.from_imod5_data( + imod5_data, grid, regridder_types.get("ic"), regrid_cache + ) # import recharge - rch_pkg = Recharge.from_imod5_data(imod5_data, dis_pkg, regridder_types) + rch_pkg = Recharge.from_imod5_data( + imod5_data, dis_pkg, regridder_types.get("rch"), regrid_cache + ) result = GroundwaterFlowModel() result["dis"] = dis_pkg @@ -252,7 +265,8 @@ def from_imod5_data( distributing_option=distributing_options.drn, time_min=time_min, time_max=time_max, - regridder_types=regridder_types, + regridder_types=regridder_types.get(drn_key), + regrid_cache=regrid_cache, ) result[drn_key] = drn_pkg @@ -268,7 +282,8 @@ def from_imod5_data( time_max, allocation_options.riv, distributing_options.riv, - regridder_types, + regridder_types.get(riv_key), + regrid_cache, ) if riv_pkg is not None: result[riv_key + "riv"] = riv_pkg @@ -289,12 +304,16 @@ def from_imod5_data( chd_keys = [key for key in imod5_keys if key[0:3] == "chd"] if len(chd_keys) == 0: result["chd_from_shd"] = ConstantHead.from_imod5_shd_data( - imod5_data, dis_pkg, regridder_types + imod5_data, dis_pkg, regridder_types.get("chd_from_shd"), regrid_cache ) else: for chd_key in chd_keys: result[chd_key] = ConstantHead.from_imod5_data( - chd_key, imod5_data, dis_pkg, regridder_types + chd_key, + imod5_data, + dis_pkg, + regridder_types.get(chd_key), + regrid_cache, ) return result diff --git a/imod/mf6/npf.py b/imod/mf6/npf.py index 99401f0e9..67c51aecc 100644 --- a/imod/mf6/npf.py +++ b/imod/mf6/npf.py @@ -1,5 +1,4 @@ import warnings -from dataclasses import asdict from typing import Optional import numpy as np @@ -10,7 +9,6 @@ from imod.mf6.package import Package from imod.mf6.regrid.regrid_schemes import ( NodePropertyFlowRegridMethod, - RegridMethodType, ) from imod.mf6.utilities.imod5_converter import fill_missing_layers from imod.mf6.utilities.regrid import ( @@ -459,7 +457,8 @@ def from_imod5_data( cls, imod5_data: dict[str, dict[str, GridDataArray]], target_grid: GridDataArray, - regridder_types: Optional[RegridMethodType] = None, + regridder_types: Optional[NodePropertyFlowRegridMethod] = None, + regrid_cache: RegridderWeightsCache = RegridderWeightsCache(), ) -> "NodePropertyFlow": """ Construct an npf-package from iMOD5 data, loaded with the @@ -513,14 +512,10 @@ def from_imod5_data( icelltype = zeros_like(target_grid, dtype=int) if regridder_types is None: - regridder_settings = asdict(cls.get_regrid_methods(), dict_factory=dict) - else: - regridder_settings = asdict(regridder_types, dict_factory=dict) - - regrid_context = RegridderWeightsCache() + regridder_types = NodePropertyFlow.get_regrid_methods() new_package_data = _regrid_package_data( - data, target_grid, regridder_settings, regrid_context, {} + data, target_grid, regridder_types, regrid_cache, {} ) new_package_data["icelltype"] = icelltype diff --git a/imod/mf6/package.py b/imod/mf6/package.py index fb35785ba..0b81a18d1 100644 --- a/imod/mf6/package.py +++ b/imod/mf6/package.py @@ -543,7 +543,7 @@ def mask(self, mask: GridDataArray) -> Any: def regrid_like( self, target_grid: GridDataArray, - regrid_context: RegridderWeightsCache, + regrid_cache: RegridderWeightsCache, regridder_types: Optional[RegridMethodType] = None, ) -> "Package": """ @@ -570,7 +570,7 @@ def regrid_like( ---------- target_grid: xr.DataArray or xu.UgridDataArray a grid defined over the same discretization as the one we want to regrid the package to. - regrid_context: RegridderWeightsCache, optional + regrid_cache: RegridderWeightsCache, optional stores regridder weights for different regridders. Can be used to speed up regridding, if the same regridders are used several times for regridding different arrays. regridder_types: RegridMethodType, optional @@ -583,7 +583,7 @@ def regrid_like( similar to the one used in input argument "target_grid" """ try: - result = _regrid_like(self, target_grid, regrid_context, regridder_types) + result = _regrid_like(self, target_grid, regrid_cache, regridder_types) except ValueError as e: raise e except Exception: diff --git a/imod/mf6/rch.py b/imod/mf6/rch.py index 37993ee38..b9402cbb0 100644 --- a/imod/mf6/rch.py +++ b/imod/mf6/rch.py @@ -1,4 +1,3 @@ -from dataclasses import asdict from typing import Optional import numpy as np @@ -7,7 +6,7 @@ from imod.mf6.boundary_condition import BoundaryCondition from imod.mf6.dis import StructuredDiscretization from imod.mf6.interfaces.iregridpackage import IRegridPackage -from imod.mf6.regrid.regrid_schemes import RechargeRegridMethod, RegridMethodType +from imod.mf6.regrid.regrid_schemes import RechargeRegridMethod from imod.mf6.utilities.regrid import RegridderWeightsCache, _regrid_package_data from imod.mf6.validation import BOUNDARY_DIMS_SCHEMA, CONC_DIMS_SCHEMA from imod.prepare.topsystem.allocation import ALLOCATION_OPTION, allocate_rch_cells @@ -160,7 +159,8 @@ def from_imod5_data( cls, imod5_data: dict[str, dict[str, GridDataArray]], dis_pkg: StructuredDiscretization, - regridder_types: Optional[RegridMethodType] = None, + regridder_types: Optional[RechargeRegridMethod] = None, + regrid_cache: RegridderWeightsCache = RegridderWeightsCache(), ) -> "Recharge": """ Construct an rch-package from iMOD5 data, loaded with the @@ -178,7 +178,7 @@ def from_imod5_data( dis_pkg: GridDataArray The discretization package for the simulation. Its grid does not need to be identical to one of the input grids. - regridder_types: RegridMethodType, optional + regridder_types: RechargeRegridMethod, optional Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. @@ -195,14 +195,10 @@ def from_imod5_data( # first regrid the inputs to the target grid. if regridder_types is None: - regridder_settings = asdict(cls.get_regrid_methods(), dict_factory=dict) - else: - regridder_settings = asdict(regridder_types, dict_factory=dict) - - regrid_context = RegridderWeightsCache() + regridder_settings = Recharge.get_regrid_methods() new_package_data = _regrid_package_data( - data, new_idomain, regridder_settings, regrid_context, {} + data, new_idomain, regridder_settings, regrid_cache, {} ) # if rate has only layer 0, then it is planar. diff --git a/imod/mf6/regrid/regrid_schemes.py b/imod/mf6/regrid/regrid_schemes.py index 7d6c6e69f..33d496e39 100644 --- a/imod/mf6/regrid/regrid_schemes.py +++ b/imod/mf6/regrid/regrid_schemes.py @@ -20,6 +20,9 @@ class RegridMethodType(Protocol): __dataclass_fields__: ClassVar[dict] + def asdict(self) -> dict: + return vars(self) + @dataclass(config=_CONFIG) class ConstantHeadRegridMethod(RegridMethodType): @@ -51,6 +54,7 @@ class ConstantHeadRegridMethod(RegridMethodType): "mean", ) # TODO: should be set to barycentric once supported concentration: _RegridVarType = (RegridderType.OVERLAP, "mean") + ibound: _RegridVarType = (RegridderType.OVERLAP, "mode") @dataclass(config=_CONFIG) @@ -404,6 +408,7 @@ class RiverRegridMethod(RegridMethodType): conductance: _RegridVarType = (RegridderType.RELATIVEOVERLAP, "conductance") bottom_elevation: _RegridVarType = (RegridderType.OVERLAP, "mean") concentration: _RegridVarType = (RegridderType.OVERLAP, "mean") + infiltration_factor: _RegridVarType = (RegridderType.OVERLAP, "mean") @dataclass(config=_CONFIG) diff --git a/imod/mf6/riv.py b/imod/mf6/riv.py index 4e88f71b4..a730cff62 100644 --- a/imod/mf6/riv.py +++ b/imod/mf6/riv.py @@ -1,4 +1,3 @@ -from dataclasses import asdict from datetime import datetime from typing import Optional, Tuple @@ -12,9 +11,8 @@ from imod.mf6.dis import StructuredDiscretization from imod.mf6.drn import Drainage from imod.mf6.interfaces.iregridpackage import IRegridPackage -from imod.mf6.regrid.regrid_schemes import RegridMethodType, RiverRegridMethod +from imod.mf6.regrid.regrid_schemes import RiverRegridMethod from imod.mf6.utilities.regrid import ( - RegridderType, RegridderWeightsCache, _regrid_package_data, ) @@ -196,7 +194,8 @@ def from_imod5_data( time_max: datetime, allocation_option_riv: ALLOCATION_OPTION, distributing_option_riv: DISTRIBUTING_OPTION, - regridder_types: Optional[RegridMethodType] = None, + regridder_types: Optional[RiverRegridMethod] = None, + regrid_cache: RegridderWeightsCache = RegridderWeightsCache(), ) -> Tuple[Optional["River"], Optional[Drainage]]: """ Construct a river-package from iMOD5 data, loaded with the @@ -228,7 +227,7 @@ def from_imod5_data( allocation option. distributing_option: dict[str, DISTRIBUTING_OPTION] distributing option. - regridder_types: RegridMethodType, optional + regridder_types: RiverRegridMethod, optional Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. @@ -259,17 +258,10 @@ def from_imod5_data( # set up regridder methods if regridder_types is None: - regridder_settings = asdict(cls.get_regrid_methods(), dict_factory=dict) - else: - regridder_settings = asdict(regridder_types, dict_factory=dict) - if "infiltration_factor" not in regridder_settings.keys(): - regridder_settings["infiltration_factor"] = (RegridderType.OVERLAP, "mean") - - regrid_context = RegridderWeightsCache() - + regridder_types = River.get_regrid_methods() # regrid the input data regridded_package_data = _regrid_package_data( - data, target_idomain, regridder_settings, regrid_context, {} + data, target_idomain, regridder_types, regrid_cache, {} ) conductance = regridded_package_data["conductance"] diff --git a/imod/mf6/simulation.py b/imod/mf6/simulation.py index 4b7057e38..d5dd0cc69 100644 --- a/imod/mf6/simulation.py +++ b/imod/mf6/simulation.py @@ -37,11 +37,11 @@ from imod.mf6.multimodel.modelsplitter import create_partition_info, slice_model from imod.mf6.out import open_cbc, open_conc, open_hds from imod.mf6.package import Package +from imod.mf6.regrid.regrid_schemes import RegridMethodType from imod.mf6.ssm import SourceSinkMixing from imod.mf6.statusinfo import NestedStatusInfo from imod.mf6.utilities.mask import _mask_all_models from imod.mf6.utilities.regrid import _regrid_like -from imod.mf6.utilities.regridding_types import RegridderType from imod.mf6.write_context import WriteContext from imod.prepare.topsystem.default_allocation_methods import ( SimulationAllocationOptions, @@ -1327,7 +1327,7 @@ def from_imod5_data( distributing_options: SimulationDistributingOptions, time_min, time_max, - regridder_types: Optional[dict[str, tuple[RegridderType, str]]] = None, + regridder_types: dict[str, RegridMethodType] = {}, ) -> "Modflow6Simulation": """ Imports a GroundwaterFlowModel (GWF) from the data in an IMOD5 project file. @@ -1348,9 +1348,14 @@ def from_imod5_data( object containing the conductivity distribution options per package type. If you want a package to have a different allocation option, then it should be imported separately - regridder_types: Optional[dict[str, dict[str, tuple[RegridderType, str]]]] - the first key is the package name. The second key is the array name, and the value is - the RegridderType tuple (method + function) + time_min: datetime + Begin-time of the simulation. + time_max: datetime + End-time of the simulation. + regridder_types: dict[str, RegridMethodType] + the key is the package name. The value is the RegridMethodType + object containing the settings for regridding the package with the + specified key Returns ------- diff --git a/imod/mf6/sto.py b/imod/mf6/sto.py index 0e6de31b4..1822a433b 100644 --- a/imod/mf6/sto.py +++ b/imod/mf6/sto.py @@ -1,5 +1,4 @@ import abc -from dataclasses import asdict from typing import Any, Dict, Optional import numpy as np @@ -8,7 +7,6 @@ from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.package import Package from imod.mf6.regrid.regrid_schemes import ( - RegridMethodType, SpecificStorageRegridMethod, StorageCoefficientRegridMethod, ) @@ -327,7 +325,8 @@ def from_imod5_data( cls, imod5_data: dict[str, dict[str, GridDataArray]], target_grid: GridDataArray, - regridder_types: Optional[RegridMethodType] = None, + regridder_types: Optional[StorageCoefficientRegridMethod] = None, + regrid_cache: RegridderWeightsCache = RegridderWeightsCache(), ) -> "StorageCoefficient": """ Construct a StorageCoefficient-package from iMOD5 data, loaded with the @@ -345,7 +344,7 @@ def from_imod5_data( target_grid: GridDataArray The grid that should be used for the new package. Does not need to be identical to one of the input grids. - regridder_types: RegridMethodType, optional + regridder_types: StorageCoefficientRegridMethod, optional Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. @@ -360,14 +359,10 @@ def from_imod5_data( } if regridder_types is None: - regridder_settings = asdict(cls.get_regrid_methods(), dict_factory=dict) - else: - regridder_settings = asdict(regridder_types, dict_factory=dict) - - regrid_context = RegridderWeightsCache() + regridder_types = StorageCoefficient.get_regrid_methods() new_package_data = _regrid_package_data( - data, target_grid, regridder_settings, regrid_context, {} + data, target_grid, regridder_types, regrid_cache, {} ) new_package_data["convertible"] = zeros_like(target_grid, dtype=int) diff --git a/imod/mf6/utilities/regrid.py b/imod/mf6/utilities/regrid.py index ddc738dd8..356e10760 100644 --- a/imod/mf6/utilities/regrid.py +++ b/imod/mf6/utilities/regrid.py @@ -144,7 +144,7 @@ def _regrid_array( da: GridDataArray, regridder_collection: RegridderWeightsCache, regridder_name: Union[RegridderType, BaseRegridder], - regridder_function: str, + regridder_function: Optional[str], target_grid: GridDataArray, ) -> Optional[GridDataArray]: """ @@ -196,8 +196,8 @@ def _regrid_array( def _regrid_package_data( package_data: dict[str, GridDataArray] | GridDataset, target_grid: GridDataArray, - regridder_settings: dict[str, tuple[RegridderType, str]], - regrid_context: RegridderWeightsCache, + regridder_settings: RegridMethodType, + regrid_cache: RegridderWeightsCache, new_package_data: dict[str, GridDataArray] = {}, ) -> dict[str, GridDataArray]: """ @@ -206,11 +206,12 @@ def _regrid_package_data( package data is added to a dictionary, which can optionally be provided as argument to extend. """ + settings_dict = RegridMethodType.asdict(regridder_settings) for ( varname, regridder_type_and_function, - ) in regridder_settings.items(): - regridder_function = None + ) in settings_dict.items(): + regridder_function: Optional[str] = None regridder_name = regridder_type_and_function[0] if len(regridder_type_and_function) > 1: regridder_function = regridder_type_and_function[1] @@ -222,7 +223,7 @@ def _regrid_package_data( # regrid the variable new_package_data[varname] = _regrid_array( package_data[varname], - regrid_context, + regrid_cache, regridder_name, regridder_function, target_grid, @@ -265,7 +266,7 @@ def _get_unique_regridder_types(model: IModel) -> defaultdict[RegridderType, lis def _regrid_like( package: IRegridPackage, target_grid: GridDataArray, - regrid_context: RegridderWeightsCache, + regrid_cache: RegridderWeightsCache, regridder_types: Optional[RegridMethodType] = None, ) -> IPackage: """ @@ -292,7 +293,7 @@ def _regrid_like( package to regrid target_grid: xr.DataArray or xu.UgridDataArray a grid defined over the same discretization as the one we want to regrid the package to - regrid_context: RegridderWeightsCache + regrid_cache: RegridderWeightsCache stores regridder weights for different regridders. Can be used to speed up regridding, if the same regridders are used several times for regridding different arrays. regridder_types: RegridMethodType, optional @@ -313,16 +314,14 @@ def _regrid_like( remove_expanded_auxiliary_variables_from_dataset(package) if regridder_types is None: - regridder_settings = asdict(package.get_regrid_methods(), dict_factory=dict) - else: - regridder_settings = asdict(regridder_types, dict_factory=dict) + regridder_types = package._regrid_method - new_package_data = package.get_non_grid_data(list(regridder_settings.keys())) + new_package_data = package.get_non_grid_data(regridder_types.asdict().keys()) new_package_data = _regrid_package_data( package.dataset, target_grid, - regridder_settings, - regrid_context, + regridder_types, + regrid_cache, new_package_data=new_package_data, ) @@ -337,7 +336,7 @@ def _regrid_like( model: IModel, target_grid: GridDataArray, validate: bool = True, - regrid_context: Optional[RegridderWeightsCache] = None, + regrid_cache: Optional[RegridderWeightsCache] = None, ) -> IModel: """ Creates a model by regridding the packages of this model to another discretization. @@ -351,7 +350,7 @@ def _regrid_like( a grid defined over the same discretization as the one we want to regrid the package to validate: bool set to true to validate the regridded packages - regrid_context: Optional RegridderWeightsCache + regrid_cache: Optional RegridderWeightsCache stores regridder weights for different regridders. Can be used to speed up regridding, if the same regridders are used several times for regridding different arrays. @@ -366,18 +365,18 @@ def _regrid_like( f"regridding this model cannot be done due to the presence of package {error_with_object_name}" ) new_model = model.__class__() - if regrid_context is None: - regrid_context = RegridderWeightsCache() + if regrid_cache is None: + regrid_cache = RegridderWeightsCache() for pkg_name, pkg in model.items(): if isinstance(pkg, (IRegridPackage, ILineDataPackage, IPointDataPackage)): - new_model[pkg_name] = pkg.regrid_like(target_grid, regrid_context) + new_model[pkg_name] = pkg.regrid_like(target_grid, regrid_cache) else: raise NotImplementedError( f"regridding is not implemented for package {pkg_name} of type {type(pkg)}" ) methods = _get_unique_regridder_types(model) - output_domain = _get_regridding_domain(model, target_grid, regrid_context, methods) + output_domain = _get_regridding_domain(model, target_grid, regrid_cache, methods) new_model.mask_all_packages(output_domain) new_model.purge_empty_packages() if validate: @@ -423,7 +422,7 @@ def _regrid_like( raise ValueError( "Unable to regrid simulation. Regridding can only be done on simulations that have a single flow model." ) - regrid_context = RegridderWeightsCache() + regrid_cache = RegridderWeightsCache() models = simulation.get_models() for model_name, model in models.items(): @@ -436,7 +435,7 @@ def _regrid_like( result = simulation.__class__(regridded_simulation_name) for key, item in simulation.items(): if isinstance(item, IModel): - result[key] = item.regrid_like(target_grid, validate, regrid_context) + result[key] = item.regrid_like(target_grid, validate, regrid_cache) elif key == "gwtgwf_exchanges": pass elif isinstance(item, IPackage) and not isinstance(item, IRegridPackage): @@ -481,7 +480,7 @@ def _regrid_like(package: object, target_grid: GridDataArray, *_) -> None: def _get_regridding_domain( model: IModel, target_grid: GridDataArray, - regrid_context: RegridderWeightsCache, + regrid_cache: RegridderWeightsCache, methods: defaultdict[RegridderType, list[str]], ) -> GridDataArray: """ @@ -492,7 +491,7 @@ def _get_regridding_domain( idomain = model.domain included_in_all = ones_like(target_grid) regridders = [ - regrid_context.get_regridder(idomain, target_grid, regriddertype, function) + regrid_cache.get_regridder(idomain, target_grid, regriddertype, function) for regriddertype, functionlist in methods.items() for function in functionlist ] diff --git a/imod/tests/test_mf6/test_mf6_hfb.py b/imod/tests/test_mf6/test_mf6_hfb.py index 925106039..591a8b2ec 100644 --- a/imod/tests/test_mf6/test_mf6_hfb.py +++ b/imod/tests/test_mf6/test_mf6_hfb.py @@ -145,9 +145,9 @@ def test_to_mf6_creates_mf6_adapter( else: idomain_clipped = idomain.sel(x=slice(None, 54.0)) - regrid_context = RegridderWeightsCache() + regrid_cache = RegridderWeightsCache() - hfb_clipped = hfb.regrid_like(idomain_clipped.sel(layer=1), regrid_context) + hfb_clipped = hfb.regrid_like(idomain_clipped.sel(layer=1), regrid_cache) # Assert x, y = hfb_clipped.dataset["geometry"].values[0].xy diff --git a/imod/tests/test_mf6/test_mf6_npf.py b/imod/tests/test_mf6/test_mf6_npf.py index 266d71232..a73cb64f4 100644 --- a/imod/tests/test_mf6/test_mf6_npf.py +++ b/imod/tests/test_mf6/test_mf6_npf.py @@ -8,6 +8,7 @@ import xarray as xr import imod +from imod.mf6.utilities.regridding_types import RegridderType from imod.schemata import ValidationError @@ -293,3 +294,36 @@ def test_npf_from_imod5_vertical_anisotropy(imod5_dataset, tmp_path): assert "angle1" not in rendered_npf assert "angle2" not in rendered_npf assert "angle3" not in rendered_npf + + +@pytest.mark.usefixtures("imod5_dataset") +def test_npf_from_imod5_settings(imod5_dataset, tmp_path): + data = deepcopy(imod5_dataset[0]) + + # move the coordinates a bit so that it doesn't match the grid of k (and the regridding settings will matter) + target_grid = data["khv"]["kh"] + x = target_grid["x"].values + x += 50 + y = target_grid["y"].values + y += 50 + target_grid = target_grid.assign_coords({"x": x, "y": y}) + + settings = imod.mf6.NodePropertyFlow.get_regrid_methods() + settings_1 = deepcopy(settings) + settings_1.k = ( + RegridderType.OVERLAP, + "harmonic_mean", + ) + npf_1 = imod.mf6.NodePropertyFlow.from_imod5_data(data, target_grid, settings_1) + + settings_2 = deepcopy(settings) + settings_2.k = ( + RegridderType.OVERLAP, + "mode", + ) + npf_2 = imod.mf6.NodePropertyFlow.from_imod5_data(data, target_grid, settings_2) + + # assert that different settings lead to different results. + diff = npf_1.dataset["k"] - npf_2.dataset["k"] + diff = xr.where(np.isnan(diff), 0, diff) + assert diff.values.max() > 0.1 diff --git a/imod/tests/test_mf6/test_mf6_regrid_package.py b/imod/tests/test_mf6/test_mf6_regrid_package.py index 6ede32a39..8a700bae0 100644 --- a/imod/tests/test_mf6/test_mf6_regrid_package.py +++ b/imod/tests/test_mf6/test_mf6_regrid_package.py @@ -117,10 +117,10 @@ def test_regrid_structured(): structured_grid_packages = create_package_instances(is_structured=True) new_grid = grid_data_structured(np.float64, 12, 2.5) - regrid_context = RegridderWeightsCache() + regrid_cache = RegridderWeightsCache() new_packages = [] for package in structured_grid_packages: - new_packages.append(package.regrid_like(new_grid, regrid_context)) + new_packages.append(package.regrid_like(new_grid, regrid_cache)) new_idomain = new_packages[0].dataset["icelltype"] @@ -137,11 +137,11 @@ def test_regrid_unstructured(): """ unstructured_grid_packages = create_package_instances(is_structured=False) new_grid = grid_data_unstructured(np.float64, 12, 2.5) - regrid_context = RegridderWeightsCache() + regrid_cache = RegridderWeightsCache() new_packages = [] for package in unstructured_grid_packages: - new_packages.append(package.regrid_like(new_grid, regrid_context)) + new_packages.append(package.regrid_like(new_grid, regrid_cache)) new_idomain = new_packages[0].dataset["icelltype"] for new_package in new_packages: @@ -170,12 +170,12 @@ def test_regrid_structured_missing_dx_and_dy(): ) new_grid = grid_data_structured(np.float64, 12, 0.25) - regrid_context = RegridderWeightsCache() + regrid_cache = RegridderWeightsCache() with pytest.raises( ValueError, match="DataArray icelltype does not have both a dx and dy coordinates", ): - _ = package.regrid_like(new_grid, regrid_context) + _ = package.regrid_like(new_grid, regrid_cache) def test_regrid(tmp_path: Path): @@ -208,8 +208,8 @@ def test_regrid(tmp_path: Path): save_flows=True, alternative_cell_averaging="AMT-HMK", ) - regrid_context = RegridderWeightsCache() - new_npf = npf.regrid_like(k, regrid_context) + regrid_cache = RegridderWeightsCache() + new_npf = npf.regrid_like(k, regrid_cache) # check the rendered versions are the same, they contain the options new_rendered = new_npf.render(tmp_path, "regridded", None, False) @@ -247,8 +247,8 @@ def test_regridding_can_skip_validation(): # Regrid the package to a finer domain new_grid = grid_data_structured(np.float64, 1.0, 0.025) - regrid_context = RegridderWeightsCache() - regridded_package = sto_package.regrid_like(new_grid, regrid_context) + regrid_cache = RegridderWeightsCache() + regridded_package = sto_package.regrid_like(new_grid, regrid_cache) # Check that write validation still fails for the regridded package new_bottom = deepcopy(new_grid) @@ -293,8 +293,8 @@ def test_regridding_layer_based_array(): validate=False, ) new_grid = grid_data_structured(np.float64, 1.0, 0.025) - regrid_context = RegridderWeightsCache() - regridded_package = sto_package.regrid_like(new_grid, regrid_context) + regrid_cache = RegridderWeightsCache() + regridded_package = sto_package.regrid_like(new_grid, regrid_cache) assert ( regridded_package.dataset.coords["dx"].values[()] diff --git a/imod/tests/test_mf6/test_mf6_regrid_simulation.py b/imod/tests/test_mf6/test_mf6_regrid_simulation.py index 5d5e0a817..098356727 100644 --- a/imod/tests/test_mf6/test_mf6_regrid_simulation.py +++ b/imod/tests/test_mf6/test_mf6_regrid_simulation.py @@ -67,7 +67,7 @@ def test_regrid_with_custom_method(circle_model): regrid_method = ConstantHeadRegridMethod( head=(RegridderType.BARYCENTRIC,), concentration=(RegridderType.BARYCENTRIC,) ) - regrid_context = RegridderWeightsCache() + regrid_cache = RegridderWeightsCache() simulation_regridded["GWF_1"]["chd"] = chd_pkg.regrid_like( - idomain, regrid_context=regrid_context, regridder_types=regrid_method + idomain, regrid_cache=regrid_cache, regridder_types=regrid_method ) diff --git a/imod/tests/test_mf6/test_mf6_simulation.py b/imod/tests/test_mf6/test_mf6_simulation.py index 96f4ceac5..777f944a9 100644 --- a/imod/tests/test_mf6/test_mf6_simulation.py +++ b/imod/tests/test_mf6/test_mf6_simulation.py @@ -19,6 +19,11 @@ from imod.mf6.model import Modflow6Model from imod.mf6.multimodel.modelsplitter import PartitionInfo from imod.mf6.oc import OutputControl +from imod.mf6.regrid.regrid_schemes import ( + DiscretizationRegridMethod, + NodePropertyFlowRegridMethod, + StorageCoefficientRegridMethod, +) from imod.mf6.simulation import Modflow6Simulation from imod.mf6.statusinfo import NestedStatusInfo, StatusInfo from imod.prepare.topsystem.default_allocation_methods import ( @@ -497,3 +502,40 @@ def test_import_from_imod5(imod5_dataset, tmp_path): # write and validate the simulation. simulation.write(tmp_path, binary=False, validate=True) + + +@pytest.mark.usefixtures("imod5_dataset") +def test_import_from_imod5_nonstandard_regridding(imod5_dataset, tmp_path): + imod5_data = imod5_dataset[0] + period_data = imod5_dataset[1] + default_simulation_allocation_options = SimulationAllocationOptions + default_simulation_distributing_options = SimulationDistributingOptions + + regridding_option = {} + regridding_option["npf"] = NodePropertyFlowRegridMethod() + regridding_option["dis"] = DiscretizationRegridMethod() + regridding_option["sto"] = StorageCoefficientRegridMethod() + + simulation = Modflow6Simulation.from_imod5_data( + imod5_data, + period_data, + default_simulation_allocation_options, + default_simulation_distributing_options, + datetime(2000, 1, 1), + datetime(2002, 1, 1), + regridding_option, + ) + + simulation["imported_model"]["oc"] = OutputControl( + save_head="last", save_budget="last" + ) + + simulation.create_time_discretization(["01-01-2003", "02-01-2003"]) + + # Remove HFB packages outside domain + # TODO: Build in support for hfb packages outside domain + for hfb_outside in ["hfb-24", "hfb-26"]: + simulation["imported_model"].pop(hfb_outside) + + # write and validate the simulation. + simulation.write(tmp_path, binary=False, validate=True) diff --git a/imod/tests/test_mf6/test_mf6_unsupported_grid_operations.py b/imod/tests/test_mf6/test_mf6_unsupported_grid_operations.py index 7a2f807f5..eff33b966 100644 --- a/imod/tests/test_mf6/test_mf6_unsupported_grid_operations.py +++ b/imod/tests/test_mf6/test_mf6_unsupported_grid_operations.py @@ -57,9 +57,9 @@ def test_mf6_package_regrid_with_lakes(rectangle_with_lakes, tmp_path): simulation = rectangle_with_lakes package = simulation["GWF_1"]["lake"] new_grid = finer_grid(simulation["GWF_1"].domain) - regrid_context = RegridderWeightsCache() + regrid_cache = RegridderWeightsCache() with pytest.raises(ValueError, match="package(.+)not be regridded"): - _ = package.regrid_like(new_grid, regrid_context) + _ = package.regrid_like(new_grid, regrid_cache) @pytest.mark.usefixtures("rectangle_with_lakes") From 53d5c86f2cb161b57d5a2bca58053a6b3413e4fe Mon Sep 17 00:00:00 2001 From: luitjansl <64598682+luitjansl@users.noreply.github.com> Date: Thu, 18 Jul 2024 17:19:37 +0200 Subject: [PATCH 28/53] Issue #1112 mypy (#1113) Fixes #1112 # Description solves mypy issues on the feature branch # Checklist - [X] Links to correct issue - [ ] Update changelog, if changes affect users - [ ] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [ ] Unit tests were added - [ ] **If feature added**: Added/extended example --- imod/mf6/chd.py | 7 +++- imod/mf6/dis.py | 7 +++- imod/mf6/drn.py | 7 +++- imod/mf6/ghb.py | 7 +++- imod/mf6/ic.py | 9 +++-- imod/mf6/model_gwf.py | 58 +++++++++++++++++++++++++-------- imod/mf6/npf.py | 7 +++- imod/mf6/rch.py | 7 +++- imod/mf6/riv.py | 27 +++++++++------ imod/mf6/ssm.py | 5 +++ imod/mf6/sto.py | 11 ++++++- imod/mf6/wel.py | 16 ++++----- imod/util/expand_repetitions.py | 8 +++-- 13 files changed, 132 insertions(+), 44 deletions(-) diff --git a/imod/mf6/chd.py b/imod/mf6/chd.py index b01a11350..f3bf69ca5 100644 --- a/imod/mf6/chd.py +++ b/imod/mf6/chd.py @@ -1,3 +1,4 @@ +from copy import deepcopy from typing import Optional import numpy as np @@ -279,4 +280,8 @@ def _from_head_data( regridded_package_data["head"] = head regridded_package_data.pop("ibound") - return cls(**regridded_package_data) + return cls(**regridded_package_data, validate=True) + + @classmethod + def get_regrid_methods(cls) -> ConstantHeadRegridMethod: + return deepcopy(cls._regrid_method) diff --git a/imod/mf6/dis.py b/imod/mf6/dis.py index c120527bc..f69f0b329 100644 --- a/imod/mf6/dis.py +++ b/imod/mf6/dis.py @@ -1,4 +1,5 @@ import pathlib +from copy import deepcopy from typing import Any, List, Optional import numpy as np @@ -225,4 +226,8 @@ def from_imod5_data( # Assume iMOD5 data provided as fully 3D and not Quasi-3D new_package_data["top"] = new_package_data["top"].sel(layer=1, drop=True) - return cls(**new_package_data) + return cls(**new_package_data, validate=True) + + @classmethod + def get_regrid_methods(cls) -> DiscretizationRegridMethod: + return deepcopy(cls._regrid_method) diff --git a/imod/mf6/drn.py b/imod/mf6/drn.py index 3bae14d01..3ea05f755 100644 --- a/imod/mf6/drn.py +++ b/imod/mf6/drn.py @@ -1,3 +1,4 @@ +from copy import deepcopy from datetime import datetime from typing import Optional @@ -259,8 +260,12 @@ def from_imod5_data( planar_elevation, ) - drn = Drainage(**regridded_package_data) + drn = Drainage(**regridded_package_data, validate=True) repeat = period_data.get(key) if repeat is not None: drn.set_repeat_stress(expand_repetitions(repeat, time_min, time_max)) return drn + + @classmethod + def get_regrid_methods(cls) -> DrainageRegridMethod: + return deepcopy(cls._regrid_method) diff --git a/imod/mf6/ghb.py b/imod/mf6/ghb.py index ee7b8f6d1..812523eb4 100644 --- a/imod/mf6/ghb.py +++ b/imod/mf6/ghb.py @@ -1,3 +1,4 @@ +from copy import deepcopy from datetime import datetime from typing import Optional @@ -220,8 +221,12 @@ def from_imod5_data( data, idomain, regridder_types, regrid_cache, {} ) - ghb = GeneralHeadBoundary(**regridded_package_data) + ghb = GeneralHeadBoundary(**regridded_package_data, validate=True) repeat = period_data.get(key) if repeat is not None: ghb.set_repeat_stress(expand_repetitions(repeat, time_min, time_max)) return ghb + + @classmethod + def get_regrid_methods(cls) -> GeneralHeadBoundaryRegridMethod: + return deepcopy(cls._regrid_method) diff --git a/imod/mf6/ic.py b/imod/mf6/ic.py index 09e0c6d32..cc5b13dba 100644 --- a/imod/mf6/ic.py +++ b/imod/mf6/ic.py @@ -1,4 +1,5 @@ import warnings +from copy import deepcopy from typing import Any, Optional import numpy as np @@ -118,7 +119,7 @@ def from_imod5_data( target_grid: GridDataArray The grid that should be used for the new package. Does not need to be identical to one of the input grids. - regridder_types: RegridMethodType, optional + regridder_types: InitialConditionsRegridMethod, optional Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. @@ -137,4 +138,8 @@ def from_imod5_data( new_package_data = _regrid_package_data( data, target_grid, regridder_types, regrid_cache, {} ) - return cls(**new_package_data) + return cls(**new_package_data, validate=True) + + @classmethod + def get_regrid_methods(cls) -> InitialConditionsRegridMethod: + return deepcopy(cls._regrid_method) diff --git a/imod/mf6/model_gwf.py b/imod/mf6/model_gwf.py index d9029158b..c6828c13b 100644 --- a/imod/mf6/model_gwf.py +++ b/imod/mf6/model_gwf.py @@ -1,7 +1,7 @@ from __future__ import annotations from datetime import datetime -from typing import Optional +from typing import Optional, cast import cftime import numpy as np @@ -17,7 +17,17 @@ from imod.mf6.model import Modflow6Model from imod.mf6.npf import NodePropertyFlow from imod.mf6.rch import Recharge -from imod.mf6.regrid.regrid_schemes import RegridMethodType +from imod.mf6.regrid.regrid_schemes import ( + ConstantHeadRegridMethod, + DiscretizationRegridMethod, + DrainageRegridMethod, + InitialConditionsRegridMethod, + NodePropertyFlowRegridMethod, + RechargeRegridMethod, + RegridMethodType, + RiverRegridMethod, + StorageCoefficientRegridMethod, +) from imod.mf6.riv import River from imod.mf6.sto import StorageCoefficient from imod.mf6.utilities.regrid import RegridderWeightsCache @@ -219,28 +229,43 @@ def from_imod5_data( regrid_cache = RegridderWeightsCache() dis_pkg = StructuredDiscretization.from_imod5_data( - imod5_data, regridder_types.get("dis"), regrid_cache, False + imod5_data, + cast(DiscretizationRegridMethod, regridder_types.get("dis")), + regrid_cache, + False, ) grid = dis_pkg.dataset["idomain"] # import npf npf_pkg = NodePropertyFlow.from_imod5_data( - imod5_data, grid, regridder_types.get("npf"), regrid_cache + imod5_data, + grid, + cast(NodePropertyFlowRegridMethod, regridder_types.get("npf")), + regrid_cache, ) # import sto sto_pkg = StorageCoefficient.from_imod5_data( - imod5_data, grid, regridder_types.get("sto"), regrid_cache + imod5_data, + grid, + cast(StorageCoefficientRegridMethod, regridder_types.get("sto")), + regrid_cache, ) # import initial conditions ic_pkg = InitialConditions.from_imod5_data( - imod5_data, grid, regridder_types.get("ic"), regrid_cache + imod5_data, + grid, + cast(InitialConditionsRegridMethod, regridder_types.get("ic")), + regrid_cache, ) # import recharge rch_pkg = Recharge.from_imod5_data( - imod5_data, dis_pkg, regridder_types.get("rch"), regrid_cache + imod5_data, + dis_pkg, + cast(RechargeRegridMethod, regridder_types.get("ic")), + regrid_cache, ) result = GroundwaterFlowModel() @@ -265,7 +290,9 @@ def from_imod5_data( distributing_option=distributing_options.drn, time_min=time_min, time_max=time_max, - regridder_types=regridder_types.get(drn_key), + regridder_types=cast( + DrainageRegridMethod, regridder_types.get(drn_key) + ), regrid_cache=regrid_cache, ) result[drn_key] = drn_pkg @@ -273,7 +300,7 @@ def from_imod5_data( # import rivers ( and drainage to account for infiltration factor) riv_keys = [key for key in imod5_keys if key[0:3] == "riv"] for riv_key in riv_keys: - riv_pkg, drn_pkg = River.from_imod5_data( + riv_pkg, riv_drn_pkg = River.from_imod5_data( riv_key, imod5_data, period_data, @@ -282,13 +309,13 @@ def from_imod5_data( time_max, allocation_options.riv, distributing_options.riv, - regridder_types.get(riv_key), + cast(RiverRegridMethod, regridder_types.get(riv_key)), regrid_cache, ) if riv_pkg is not None: result[riv_key + "riv"] = riv_pkg - if drn_pkg is not None: - result[riv_key + "drn"] = drn_pkg + if riv_drn_pkg is not None: + result[riv_key + "drn"] = riv_drn_pkg # import hfb hfb_keys = [key for key in imod5_keys if key[0:3] == "hfb"] @@ -304,7 +331,10 @@ def from_imod5_data( chd_keys = [key for key in imod5_keys if key[0:3] == "chd"] if len(chd_keys) == 0: result["chd_from_shd"] = ConstantHead.from_imod5_shd_data( - imod5_data, dis_pkg, regridder_types.get("chd_from_shd"), regrid_cache + imod5_data, + dis_pkg, + cast(ConstantHeadRegridMethod, regridder_types.get("chd_from_shd")), + regrid_cache, ) else: for chd_key in chd_keys: @@ -312,7 +342,7 @@ def from_imod5_data( chd_key, imod5_data, dis_pkg, - regridder_types.get(chd_key), + cast(ConstantHeadRegridMethod, regridder_types.get(chd_key)), regrid_cache, ) diff --git a/imod/mf6/npf.py b/imod/mf6/npf.py index 67c51aecc..50c27c10f 100644 --- a/imod/mf6/npf.py +++ b/imod/mf6/npf.py @@ -1,4 +1,5 @@ import warnings +from copy import deepcopy from typing import Optional import numpy as np @@ -519,4 +520,8 @@ def from_imod5_data( ) new_package_data["icelltype"] = icelltype - return NodePropertyFlow(**new_package_data) + return NodePropertyFlow(**new_package_data, validate=True) + + @classmethod + def get_regrid_methods(cls) -> NodePropertyFlowRegridMethod: + return deepcopy(cls._regrid_method) diff --git a/imod/mf6/rch.py b/imod/mf6/rch.py index b9402cbb0..59524b9f3 100644 --- a/imod/mf6/rch.py +++ b/imod/mf6/rch.py @@ -1,3 +1,4 @@ +from copy import deepcopy from typing import Optional import numpy as np @@ -216,4 +217,8 @@ def from_imod5_data( rch_rate = enforce_dim_order(rch_rate) new_package_data["rate"] = rch_rate - return Recharge(**new_package_data) + return Recharge(**new_package_data, validate=True, fixed_cell=False) + + @classmethod + def get_regrid_methods(cls) -> RechargeRegridMethod: + return deepcopy(cls._regrid_method) diff --git a/imod/mf6/riv.py b/imod/mf6/riv.py index a730cff62..eb46339f2 100644 --- a/imod/mf6/riv.py +++ b/imod/mf6/riv.py @@ -1,3 +1,4 @@ +from copy import deepcopy from datetime import datetime from typing import Optional, Tuple @@ -327,7 +328,9 @@ def from_imod5_data( regridded_package_data["bottom_elevation"] ) - river_package = River(**regridded_package_data) + river_package = River(**regridded_package_data, validate=True) + optional_river_package: Optional[River] = None + optional_drainage_package: Optional[Drainage] = None # create a drainage package with the conductance we computed from the infiltration factor drainage_package = cls.create_infiltration_factor_drain( regridded_package_data["stage"], @@ -336,29 +339,29 @@ def from_imod5_data( # remove River package if its mask is False everywhere mask = ~np.isnan(river_conductance) if np.any(mask): - river_package = river_package.mask(mask) + optional_river_package = river_package.mask(mask) else: - river_package = None + optional_river_package = None # remove Drainage package if its mask is False everywhere mask = ~np.isnan(drain_conductance) if np.any(mask): - drainage_package = drainage_package.mask(mask) + optional_drainage_package = drainage_package.mask(mask) else: - drainage_package = None + optional_drainage_package = None repeat = period_data.get(key) if repeat is not None: - if river_package is not None: - river_package.set_repeat_stress( + if optional_river_package is not None: + optional_river_package.set_repeat_stress( expand_repetitions(repeat, time_min, time_max) ) - if drainage_package is not None: - drainage_package.set_repeat_stress( + if optional_drainage_package is not None: + optional_drainage_package.set_repeat_stress( expand_repetitions(repeat, time_min, time_max) ) - return (river_package, drainage_package) + return (optional_river_package, optional_drainage_package) @classmethod def create_infiltration_factor_drain( @@ -436,3 +439,7 @@ def split_conductance(cls, conductance, infiltration_factor): drainage_conductance = drainage_conductance.where(drainage_conductance > 0) river_conductance = river_conductance.where(river_conductance > 0) return drainage_conductance, river_conductance + + @classmethod + def get_regrid_methods(cls) -> RiverRegridMethod: + return deepcopy(cls._regrid_method) diff --git a/imod/mf6/ssm.py b/imod/mf6/ssm.py index bc64ce224..d9e8f6f22 100644 --- a/imod/mf6/ssm.py +++ b/imod/mf6/ssm.py @@ -4,6 +4,7 @@ from imod.mf6 import GroundwaterFlowModel from imod.mf6.boundary_condition import BoundaryCondition from imod.mf6.interfaces.iregridpackage import IRegridPackage +from imod.mf6.regrid.regrid_schemes import EmptyRegridMethod, RegridMethodType from imod.schemata import DTypeSchema @@ -165,3 +166,7 @@ def from_flow_model( save_flows=save_flows, validate=validate, ) + + @classmethod + def get_regrid_methods(cls) -> RegridMethodType: + return EmptyRegridMethod() diff --git a/imod/mf6/sto.py b/imod/mf6/sto.py index 1822a433b..8ac9ff3e5 100644 --- a/imod/mf6/sto.py +++ b/imod/mf6/sto.py @@ -1,4 +1,5 @@ import abc +from copy import deepcopy from typing import Any, Dict, Optional import numpy as np @@ -194,6 +195,10 @@ def render(self, directory, pkgname, globaltimes, binary): d = self._render_dict(directory, pkgname, globaltimes, binary) return self._template.render(d) + @classmethod + def get_regrid_methods(cls) -> SpecificStorageRegridMethod: + return deepcopy(cls._regrid_method) + class StorageCoefficient(StorageBase): """ @@ -371,4 +376,8 @@ def from_imod5_data( ) new_package_data["specific_yield"] = None - return cls(**new_package_data) + return cls(**new_package_data, validate=True, save_flows=False) + + @classmethod + def get_regrid_methods(cls) -> StorageCoefficientRegridMethod: + return deepcopy(cls._regrid_method) diff --git a/imod/mf6/wel.py b/imod/mf6/wel.py index 85705b579..2b5a58ccb 100644 --- a/imod/mf6/wel.py +++ b/imod/mf6/wel.py @@ -79,13 +79,13 @@ class Well(BoundaryCondition, IPointDataPackage): Parameters ---------- - y: float or list of floats + y: float or list of floats or np.array of floats is the y location of the well. - x: float or list of floats + x: float or list of floats or np.array of floats is the x location of the well. - screen_top: float or list of floats + screen_top: float or list of floats or np.array of floats is the top of the well screen. - screen_bottom: float or list of floats + screen_bottom: float or list of floats or np.array of floats is the bottom of the well screen. rate: float, list of floats or xr.DataArray is the volumetric well rate. A positive value indicates well @@ -193,10 +193,10 @@ def y(self) -> npt.NDArray[np.float64]: @init_log_decorator() def __init__( self, - x: list[float], - y: list[float], - screen_top: list[float], - screen_bottom: list[float], + x: np.ndarray | list[float], + y: np.ndarray | list[float], + screen_top: np.ndarray | list[float], + screen_bottom: np.ndarray | list[float], rate: list[float] | xr.DataArray, concentration: Optional[list[float] | xr.DataArray] = None, concentration_boundary_type="aux", diff --git a/imod/util/expand_repetitions.py b/imod/util/expand_repetitions.py index 28f2ec57e..e60437ebe 100644 --- a/imod/util/expand_repetitions.py +++ b/imod/util/expand_repetitions.py @@ -2,16 +2,18 @@ from datetime import datetime from typing import Dict, List +import numpy as np + def expand_repetitions( repeat_stress: List[datetime], time_min: datetime, time_max: datetime -) -> Dict[datetime, datetime]: +) -> Dict[np.datetime64, np.datetime64]: expanded = {} for year, date in itertools.product( range(time_min.year, time_max.year + 1), repeat_stress, ): - newdate = date.replace(year=year) + newdate = np.datetime64(date.replace(year=year)) if newdate < time_max: - expanded[newdate] = date + expanded[newdate] = np.datetime64(date) return expanded From c60acb37c607020e6391b7a05b1df13d32153c75 Mon Sep 17 00:00:00 2001 From: luitjansl <64598682+luitjansl@users.noreply.github.com> Date: Thu, 18 Jul 2024 18:00:36 +0200 Subject: [PATCH 29/53] Issue #1068 average well rate timeseries (#1102) Fixes #1068 # Description Implements averaging of well rate timeseries onto a set of desired times. The imported well will have rate changes at these desired times. This can be both finer and coarser than the input timeseries. These times do not need to be equidistant. With this fix, when importing a project from imod5 data, we first choose the output temporal discretization, and the well timeseries on output contain these times only. # Checklist - [X] Links to correct issue - [ ] Update changelog, if changes affect users - [X] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [X] Unit tests were added - [ ] **If feature added**: Added/extended example --------- Co-authored-by: Joeri van Engelen --- imod/mf6/model_gwf.py | 23 ++- imod/mf6/simulation.py | 7 +- imod/mf6/wel.py | 15 +- imod/tests/test_mf6/test_mf6_simulation.py | 12 +- imod/tests/test_mf6/test_mf6_wel.py | 51 +++++-- .../test_utilities/test_resampling.py | 140 ++++++++++++++++++ imod/util/expand_repetitions.py | 92 ++++++++++++ 7 files changed, 310 insertions(+), 30 deletions(-) create mode 100644 imod/tests/test_mf6/test_utilities/test_resampling.py diff --git a/imod/mf6/model_gwf.py b/imod/mf6/model_gwf.py index c6828c13b..b479827cf 100644 --- a/imod/mf6/model_gwf.py +++ b/imod/mf6/model_gwf.py @@ -31,6 +31,7 @@ from imod.mf6.riv import River from imod.mf6.sto import StorageCoefficient from imod.mf6.utilities.regrid import RegridderWeightsCache +from imod.mf6.wel import Well from imod.prepare.topsystem.default_allocation_methods import ( SimulationAllocationOptions, SimulationDistributingOptions, @@ -188,8 +189,7 @@ def from_imod5_data( period_data: dict[str, list[datetime]], allocation_options: SimulationAllocationOptions, distributing_options: SimulationDistributingOptions, - time_min: datetime, - time_max: datetime, + times: list[datetime], regridder_types: dict[str, RegridMethodType], ) -> "GroundwaterFlowModel": """ @@ -275,9 +275,16 @@ def from_imod5_data( result["ic"] = ic_pkg result["rch"] = rch_pkg - # now import the non-singleton packages - # import drainage + # now import the non-singleton packages' + + # import wells imod5_keys = list(imod5_data.keys()) + wel_keys = [key for key in imod5_keys if key[0:3] == "wel"] + for wel_key in wel_keys: + result[wel_key] = Well.from_imod5_data(wel_key, imod5_data, times) + + # import drainage + drainage_keys = [key for key in imod5_keys if key[0:3] == "drn"] for drn_key in drainage_keys: drn_pkg = Drainage.from_imod5_data( @@ -288,8 +295,8 @@ def from_imod5_data( npf_pkg, allocation_options.drn, distributing_option=distributing_options.drn, - time_min=time_min, - time_max=time_max, + time_min=times[0], + time_max=times[-1], regridder_types=cast( DrainageRegridMethod, regridder_types.get(drn_key) ), @@ -305,8 +312,8 @@ def from_imod5_data( imod5_data, period_data, dis_pkg, - time_min, - time_max, + times[0], + times[-1], allocation_options.riv, distributing_options.riv, cast(RiverRegridMethod, regridder_types.get(riv_key)), diff --git a/imod/mf6/simulation.py b/imod/mf6/simulation.py index d5dd0cc69..292308cb8 100644 --- a/imod/mf6/simulation.py +++ b/imod/mf6/simulation.py @@ -5,6 +5,7 @@ import subprocess import warnings from copy import deepcopy +from datetime import datetime from pathlib import Path from typing import Any, Callable, DefaultDict, Iterable, Optional, Union, cast @@ -1325,8 +1326,7 @@ def from_imod5_data( period_data: dict[str, dict[str, GridDataArray]], allocation_options: SimulationAllocationOptions, distributing_options: SimulationDistributingOptions, - time_min, - time_max, + times: list[datetime], regridder_types: dict[str, RegridMethodType] = {}, ) -> "Modflow6Simulation": """ @@ -1368,8 +1368,7 @@ def from_imod5_data( period_data, allocation_options, distributing_options, - time_min, - time_max, + times, regridder_types, ) simulation["imported_model"] = groundwaterFlowModel diff --git a/imod/mf6/wel.py b/imod/mf6/wel.py index 2b5a58ccb..cc7cdb67f 100644 --- a/imod/mf6/wel.py +++ b/imod/mf6/wel.py @@ -2,6 +2,7 @@ import textwrap import warnings +from datetime import datetime from typing import Any, Optional, Tuple, Union import cftime @@ -38,6 +39,7 @@ from imod.select.points import points_indices, points_values from imod.typing import GridDataArray from imod.typing.grid import is_spatial_grid, ones_like +from imod.util.expand_repetitions import resample_timeseries from imod.util.structured import values_within_range @@ -650,6 +652,7 @@ def from_imod5_data( cls, key: str, imod5_data: dict[str, dict[str, GridDataArray]], + times: list[datetime], minimum_k: float = 0.1, minimum_thickness: float = 1.0, ) -> "Well": @@ -683,14 +686,24 @@ def from_imod5_data( # Groupby unique wells, to get dataframes per time. colnames_group = ["x", "y", "filt_top", "filt_bot", "id"] wel_index, df_groups = zip(*df.groupby(colnames_group)) + + # resample per group + # Unpack wel indices by zipping x, y, filt_top, filt_bot, id = zip(*wel_index) + + # resample times per group + df_resampled_groups = [] + for df_group in df_groups: + df_group = resample_timeseries(df_group, times) + df_resampled_groups.append(df_group) + # Convert dataframes all groups to DataArrays da_groups = [ xr.DataArray( df_group["rate"], dims=("time"), coords={"time": df_group["time"]} ) - for df_group in df_groups + for df_group in df_resampled_groups ] # Assign index coordinates da_groups = [ diff --git a/imod/tests/test_mf6/test_mf6_simulation.py b/imod/tests/test_mf6/test_mf6_simulation.py index 777f944a9..88d123169 100644 --- a/imod/tests/test_mf6/test_mf6_simulation.py +++ b/imod/tests/test_mf6/test_mf6_simulation.py @@ -10,6 +10,7 @@ from unittest.mock import MagicMock import numpy as np +import pandas as pd import pytest import rasterio import xarray as xr @@ -480,15 +481,16 @@ def test_import_from_imod5(imod5_dataset, tmp_path): period_data = imod5_dataset[1] default_simulation_allocation_options = SimulationAllocationOptions default_simulation_distributing_options = SimulationDistributingOptions + + datelist = pd.date_range(start="1/1/1989", end="1/1/2013", freq="W") + simulation = Modflow6Simulation.from_imod5_data( imod5_data, period_data, default_simulation_allocation_options, default_simulation_distributing_options, - datetime(2000, 1, 1), - datetime(2002, 1, 1), + datelist, ) - simulation["imported_model"]["oc"] = OutputControl( save_head="last", save_budget="last" ) @@ -515,14 +517,14 @@ def test_import_from_imod5_nonstandard_regridding(imod5_dataset, tmp_path): regridding_option["npf"] = NodePropertyFlowRegridMethod() regridding_option["dis"] = DiscretizationRegridMethod() regridding_option["sto"] = StorageCoefficientRegridMethod() + times = pd.date_range(start="1/1/2018", end="12/1/2018", freq="ME") simulation = Modflow6Simulation.from_imod5_data( imod5_data, period_data, default_simulation_allocation_options, default_simulation_distributing_options, - datetime(2000, 1, 1), - datetime(2002, 1, 1), + times, regridding_option, ) diff --git a/imod/tests/test_mf6/test_mf6_wel.py b/imod/tests/test_mf6/test_mf6_wel.py index aafe90fd8..50deea31b 100644 --- a/imod/tests/test_mf6/test_mf6_wel.py +++ b/imod/tests/test_mf6/test_mf6_wel.py @@ -3,8 +3,10 @@ import tempfile import textwrap from contextlib import nullcontext as does_not_raise +from datetime import datetime import numpy as np +import pandas as pd import pytest import xarray as xr import xugrid as xu @@ -22,6 +24,15 @@ from imod.schemata import ValidationError from imod.tests.fixtures.flow_basic_fixture import BasicDisSettings +times = [ + datetime(1981, 11, 30), + datetime(1981, 12, 31), + datetime(1982, 1, 31), + datetime(1982, 2, 28), + datetime(1982, 3, 31), + datetime(1982, 4, 30), +] + def test_to_mf6_pkg__high_lvl_stationary(basic_dis, well_high_lvl_test_data_stationary): # Arrange @@ -824,12 +835,13 @@ def test_import_and_convert_to_mf6(imod5_dataset, tmp_path): target_dis = StructuredDiscretization.from_imod5_data(data) target_npf = NodePropertyFlow.from_imod5_data(data, target_dis.dataset["idomain"]) + times = list(pd.date_range(datetime(1989, 1, 1), datetime(2013, 1, 1), 8400)) + # import grid-agnostic well from imod5 data (it contains 1 well) - wel = Well.from_imod5_data("wel-1", data) + wel = Well.from_imod5_data("wel-1", data, times) assert wel.dataset["x"].values[0] == 197910.0 assert wel.dataset["y"].values[0] == 362860.0 - assert np.mean(wel.dataset["rate"].values) == -323.8936170212766 - + assert np.mean(wel.dataset["rate"].values) == -317.1681465863781 # convert to a gridded well top = target_dis.dataset["top"] bottom = target_dis.dataset["bottom"] @@ -838,10 +850,10 @@ def test_import_and_convert_to_mf6(imod5_dataset, tmp_path): mf6_well = wel.to_mf6_pkg(active, top, bottom, k, True) # assert mf6 well properties - assert len(mf6_well.dataset["x"].values == 1) + assert len(mf6_well.dataset["x"].values) == 1 assert mf6_well.dataset["x"].values[0] == 197910.0 assert mf6_well.dataset["y"].values[0] == 362860.0 - assert np.mean(mf6_well.dataset["rate"].values) == -323.8936170212766 + assert np.mean(mf6_well.dataset["rate"].values) == -317.1681465863781 # write the package for validation write_context = WriteContext(simulation_directory=tmp_path) @@ -851,10 +863,18 @@ def test_import_and_convert_to_mf6(imod5_dataset, tmp_path): @pytest.mark.usefixtures("well_regular_import_prj") def test_import_multiple_wells(well_regular_import_prj): imod5dict = open_projectfile_data(well_regular_import_prj) + times = [ + datetime(1981, 11, 30), + datetime(1981, 12, 31), + datetime(1982, 1, 31), + datetime(1982, 2, 28), + datetime(1982, 3, 31), + datetime(1982, 4, 30), + ] # import grid-agnostic well from imod5 data (it contains 2 packages with 3 wells each) - wel1 = imod.mf6.Well.from_imod5_data("wel-1", imod5dict[0]) - wel2 = imod.mf6.Well.from_imod5_data("wel-2", imod5dict[0]) + wel1 = imod.mf6.Well.from_imod5_data("wel-1", imod5dict[0], times) + wel2 = imod.mf6.Well.from_imod5_data("wel-2", imod5dict[0], times) assert np.all(wel1.x == np.array([191112.11, 191171.96, 191231.52])) assert np.all(wel2.x == np.array([191112.11, 191171.96, 191231.52])) @@ -865,10 +885,17 @@ def test_import_multiple_wells(well_regular_import_prj): @pytest.mark.usefixtures("well_duplication_import_prj") def test_import_from_imod5_with_duplication(well_duplication_import_prj): imod5dict = open_projectfile_data(well_duplication_import_prj) - + times = [ + datetime(1981, 11, 30), + datetime(1981, 12, 31), + datetime(1982, 1, 31), + datetime(1982, 2, 28), + datetime(1982, 3, 31), + datetime(1982, 4, 30), + ] # import grid-agnostic well from imod5 data (it contains 2 packages with 3 wells each) - wel1 = imod.mf6.Well.from_imod5_data("wel-1", imod5dict[0]) - wel2 = imod.mf6.Well.from_imod5_data("wel-2", imod5dict[0]) + wel1 = imod.mf6.Well.from_imod5_data("wel-1", imod5dict[0], times) + wel2 = imod.mf6.Well.from_imod5_data("wel-2", imod5dict[0], times) assert np.all(wel1.x == np.array([191171.96, 191231.52, 191231.52])) assert np.all(wel2.x == np.array([191112.11, 191171.96, 191231.52])) @@ -896,7 +923,7 @@ def test_logmessage_for_layer_assignment_import_imod5( add_default_stream_handler=True, ) - _ = imod.mf6.Well.from_imod5_data("wel-1", imod5dict[0]) + _ = imod.mf6.Well.from_imod5_data("wel-1", imod5dict[0], times) finally: # turn the logger off again @@ -939,7 +966,7 @@ def test_logmessage_for_missing_filter_settings( add_default_stream_handler=True, ) - _ = imod.mf6.Well.from_imod5_data("wel-1", imod5dict[0]) + _ = imod.mf6.Well.from_imod5_data("wel-1", imod5dict[0], times) except Exception: assert remove is not None diff --git a/imod/tests/test_mf6/test_utilities/test_resampling.py b/imod/tests/test_mf6/test_utilities/test_resampling.py new file mode 100644 index 000000000..e72549bb0 --- /dev/null +++ b/imod/tests/test_mf6/test_utilities/test_resampling.py @@ -0,0 +1,140 @@ +from datetime import datetime + +import pandas as pd + +from imod.util.expand_repetitions import resample_timeseries + + +def initialize_timeseries(times: list[datetime], rates: list[float]) -> pd.DataFrame: + timeseries = pd.DataFrame( + {}, columns=["time", "rate", "x", "y", "id", "filt_top", "filt_bot"] + ) + timeseries["time"] = times + timeseries["rate"] = rates + timeseries["x"] = 0 + timeseries["y"] = 0 + timeseries["id"] = "ID" + timeseries["filt_top"] = 20 + timeseries["filt_bot"] = 10 + + return timeseries + + +def test_timeseries_resampling(): + # In this test, we resample a timeseries for a coarser output discretization. + # The output times are a subset of the input times. + times = [datetime(1989, 1, i) for i in [1, 3, 4, 5, 6]] + rates = [i * 100 for i in range(1, 6)] + timeseries = initialize_timeseries(times, rates) + + new_dates = [datetime(1989, 1, 1), datetime(1989, 1, 5), datetime(1989, 1, 6)] + new_timeseries = resample_timeseries(timeseries, new_dates) + + expected_times = [datetime(1989, 1, i) for i in [1, 5, 6]] + expected_rates = [175.0, 400.0, 500.0] + expected_timeseries = initialize_timeseries(expected_times, expected_rates) + + assert new_timeseries.equals(expected_timeseries) + + +def test_timeseries_resampling_2(): + # In this test, we resample a timeseries for a coarser output discretization. + # The output times are a not a subset of the input times, and they begin earlier. + times = [datetime(1989, 1, 1, 14, 0, 0)] + times += [datetime(1989, 1, i) for i in [3, 4, 5, 6]] + rates = [i * 100 for i in range(1, 6)] + timeseries = initialize_timeseries(times, rates) + + # initialize data of lists. + + new_dates = [datetime(1989, 1, 1), datetime(1989, 1, 5), datetime(1989, 1, 6)] + new_timeseries = resample_timeseries(timeseries, new_dates) + + expected_times = [datetime(1989, 1, i) for i in [1, 5, 6]] + expected_rates = [160.416667, 400.0, 500.0] + expected_timeseries = initialize_timeseries(expected_times, expected_rates) + + pd.testing.assert_frame_equal( + new_timeseries, expected_timeseries, check_dtype=False + ) + + +def test_timeseries_resampling_3(): + # In this test, we resample a timeseries for a coarser output discretization. + # The output times are a subset of the input times. + + times = [datetime(1989, 1, i) for i in [1, 3, 4, 5]] + times += [datetime(1999, 1, 6)] # Ten years after last entry. + rates = [i * 100 for i in range(1, 6)] + timeseries = initialize_timeseries(times, rates) + + new_dates = [datetime(1989, 1, 1), datetime(1989, 1, 5), datetime(1989, 1, 6)] + new_timeseries = resample_timeseries(timeseries, new_dates) + + expected_times = [datetime(1989, 1, i) for i in [1, 5, 6]] + expected_rates = [175.0, 400.0, 400.0] + expected_timeseries = initialize_timeseries(expected_times, expected_rates) + + pd.testing.assert_frame_equal( + new_timeseries, expected_timeseries, check_dtype=False + ) + + +def test_timeseries_resampling_4(): + # In this test, we resample a timeseries for a coarser output discretization. + # The output times are a not a subset of the input times, and they end later. + # initialize data of lists. + + times = [datetime(1989, 1, i, 11, 0, 0) for i in [1, 2, 3, 4, 5]] + rates = [100, 100, 200, 300, 300] + timeseries = initialize_timeseries(times, rates) + + new_dates = [datetime(1989, 1, 1), datetime(1989, 1, 3), datetime(1999, 1, 4)] + new_timeseries = resample_timeseries(timeseries, new_dates) + + expected_times = [datetime(1989, 1, 1), datetime(1989, 1, 3), datetime(1999, 1, 4)] + expected_rates = [77.083333, 299.947532, 300] + expected_timeseries = initialize_timeseries(expected_times, expected_rates) + + pd.testing.assert_frame_equal( + new_timeseries, expected_timeseries, check_dtype=False + ) + + +def test_timeseries_resampling_coarsen_and_refine(): + # In this test, we resample a timeseries for a coarser output discretization. + # Then we refine it again to the original discretization. + # The coarsening was chosen so that after this the original timeseries should be obtained + + original_times = [datetime(1989, 1, i) for i in [1, 2, 3, 4, 5, 6]] + original_rates = [100, 100, 200, 200, 300, 300] + original_timeseries = initialize_timeseries(original_times, original_rates) + + coarse_times = [datetime(1989, 1, 1), datetime(1989, 1, 3), datetime(1989, 1, 5)] + coarse_timeseries = resample_timeseries(original_timeseries, coarse_times) + + re_refined_timeseries = resample_timeseries(coarse_timeseries, original_times) + + pd.testing.assert_frame_equal( + original_timeseries, re_refined_timeseries, check_dtype=False + ) + + +def test_timeseries_resampling_refine_and_coarsen(): + # In this test, we resample a timeseries for a finer output discretization. + # Then we coarsen it again to the original discretization. + # The refinement was chosen so that after this the original timeseries should be obtained + original_times = [datetime(1989, 1, i) for i in [1, 2, 3, 4, 5, 6]] + original_rates = [100, 100, 200, 200, 300, 300] + original_timeseries = initialize_timeseries(original_times, original_rates) + + refined_times = pd.date_range( + datetime(1989, 1, 1), datetime(1989, 1, 6), periods=121 + ) + refined_timeseries = resample_timeseries(original_timeseries, refined_times) + + re_coarsened_timeseries = resample_timeseries(refined_timeseries, original_times) + + pd.testing.assert_frame_equal( + original_timeseries, re_coarsened_timeseries, check_dtype=False + ) diff --git a/imod/util/expand_repetitions.py b/imod/util/expand_repetitions.py index e60437ebe..aa36e600c 100644 --- a/imod/util/expand_repetitions.py +++ b/imod/util/expand_repetitions.py @@ -3,11 +3,36 @@ from typing import Dict, List import numpy as np +import pandas as pd def expand_repetitions( repeat_stress: List[datetime], time_min: datetime, time_max: datetime ) -> Dict[np.datetime64, np.datetime64]: + """ + Given a list of repeat stresses, and the start and end time of the simulation, + this function returns a dictionary indicating what repeat stress should be used + at what time in the simulation. + + Parameters + ---------- + repeat_stress: list of datetime, optional + This dict list contains contains, per topic, the period alias (a string) to + its datetime. + time_min: datetime + starting time of the simulation + time_max: datetime + ending time of the simulation + + + returns: + -------- + A dictionary that can be used to repeat data for e.g.repeating stress periods such as + seasonality without duplicating the values. The ``repeat_items`` + dimension should have size 2: the first value is the "key", the second + value is the "value". For the "key" datetime, the data of the "value" + datetime will be used. + """ expanded = {} for year, date in itertools.product( range(time_min.year, time_max.year + 1), @@ -17,3 +42,70 @@ def expand_repetitions( if newdate < time_max: expanded[newdate] = np.datetime64(date) return expanded + + +def resample_timeseries(well_rate: pd.DataFrame, times: list[datetime]) -> pd.DataFrame: + """ + On input, well_rate is a dataframe containing a timeseries for rate for one well + while "times" is a list of datetimes. + This function creates a new dataframe containing a timeseries defined on the + times in "times". + + Parameters + ---------- + well_rate: pd.DataFrame + input timeseries for well + times: datetime + list of times on which the output datarame should have entries. + + returns: + -------- + a new dataframe containing a timeseries defined on the times in "times". + """ + output_frame = pd.DataFrame(times) + output_frame = output_frame.rename(columns={0: "time"}) + intermediate_df = pd.merge( + output_frame, + well_rate, + how="outer", + on="time", + ).fillna(method="ffill") + + # The entries before the start of the well timeseries do not have data yet, + # so we fill them in here. Keep rate to zero and pad the location columns with + # the first entry. + location_columns = ["x", "y", "id", "filt_top", "filt_bot"] + time_before_start_input = ( + intermediate_df["time"].values < well_rate["time"].values[0] + ) + if time_before_start_input[0]: + intermediate_df.loc[time_before_start_input, "rate"] = 0.0 + intermediate_df.loc[time_before_start_input, location_columns] = ( + well_rate.loc[0, location_columns], + ) + + # compute time difference from perious to current row + time_diff_col = intermediate_df["time"].diff() + intermediate_df.insert(7, "time_to_next", time_diff_col.values) + + # shift the new column 1 place down so that they become the time to the next row + intermediate_df["time_to_next"] = intermediate_df["time_to_next"].shift(-1) + + # Integrate by grouping by the period number + intermediate_df["duration_sec"] = intermediate_df["time_to_next"].dt.total_seconds() + intermediate_df["volume"] = ( + intermediate_df["rate"] * intermediate_df["duration_sec"] + ) + intermediate_df["period_nr"] = intermediate_df["time"].isin(times).cumsum() + gb = intermediate_df.groupby("period_nr") + + output_frame["rate"] = (gb["volume"].sum() / gb["duration_sec"].sum()).reset_index( + drop=True + ) + # If last value is nan (fell outside range), pad with last well rate. + if np.isnan(output_frame["rate"].values[-1]): + output_frame["rate"].values[-1] = well_rate["rate"].values[-1] + + columns_to_merge = ["time"] + location_columns + + return pd.merge(output_frame, intermediate_df[columns_to_merge], on="time") From 2a3599b71cb1ca94a1b03ba5901eed9ace42b2a4 Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Thu, 25 Jul 2024 16:14:20 +0200 Subject: [PATCH 30/53] Issue #678 hfb varying top bot (#1100) Fixes #678 # Description Support horizontal flow barriers with varying ztop and zbottom. Data is set up as vertical polygons, which is also what ``imod.formats.gen.read_gen()`` returns. The implementation is based on ``imod.formats.prj.disv_converter``. When we fix the wells, we are feature complete and the ``disv_converter`` can be removed. The use of the vertical dimension means a change in the public API: No longer are the "ztop" and "zbottom" variables in the geodataframe used. Setting up these vertical polygons from scratch is a bit of a hassle, so we could add some utility functions to help setting these up, in a later PR. # Checklist - [x] Links to correct issue - [x] Update changelog, if changes affect users - [x] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [x] Unit tests were added - [x] **If feature added**: Added/extended example --- docs/api/changelog.rst | 36 +- docs/api/prepare.rst | 3 + .../imod5_conversion.py | 4 + imod/formats/prj/disv_conversion.py | 30 +- imod/mf6/hfb.py | 222 +++++++++--- imod/mf6/model.py | 2 +- imod/mf6/utilities/clip.py | 57 ++- imod/mf6/utilities/hfb.py | 230 +++++++++--- imod/mf6/utilities/mf6hfb.py | 67 ++++ imod/prepare/__init__.py | 6 +- imod/prepare/hfb.py | 219 ++++++++++++ .../fixtures/mf6_small_models_fixture.py | 2 +- imod/tests/test_mf6/test_mf6_hfb.py | 332 +++++++++++++++--- .../test_mf6_partitioning_structured.py | 44 ++- .../test_mf6_partitioning_unstructured.py | 52 +-- .../tests/test_mf6/test_utilities/test_hfb.py | 246 +++---------- .../test_mf6/test_utilities/test_mf6hfb.py | 230 ++++++++++++ imod/tests/test_prepare/test_prepare_hfb.py | 106 ++++++ imod/typing/__init__.py | 18 +- imod/typing/grid.py | 6 +- 20 files changed, 1464 insertions(+), 448 deletions(-) create mode 100644 imod/mf6/utilities/mf6hfb.py create mode 100644 imod/prepare/hfb.py create mode 100644 imod/tests/test_mf6/test_utilities/test_mf6hfb.py create mode 100644 imod/tests/test_prepare/test_prepare_hfb.py diff --git a/docs/api/changelog.rst b/docs/api/changelog.rst index d95994d0a..852a80f42 100644 --- a/docs/api/changelog.rst +++ b/docs/api/changelog.rst @@ -9,17 +9,38 @@ The format is based on `Keep a Changelog`_, and this project adheres to [Unreleased- feature branch] ---------------------------- + Fixed ~~~~~ -- ``HorizontalFlowBarrier`` attached to :class:`imod.mf6.GroundwaterFlowModel` - are merged into a single horizontal flow barrier for MODFLOW 6 +- Multiple ``HorizontalFlowBarrier`` objects attached to + :class:`imod.mf6.GroundwaterFlowModel` are merged into a single horizontal + flow barrier for MODFLOW 6 Changed ~~~~~~~ - :class:`imod.mf6.Well` now also validates that well filter top is above well filter bottom -- :function:`open_projectfile_data` now also imports well filter top and bottom. +- :func:`open_projectfile_data` now also imports well filter top and bottom. - :class:`imod.mf6.Well` now logs a warning if any wells are removed during writing. +- :class:`imod.mf6.HorizontalFlowBarrierResistance`, + :class:`imod.mf6.HorizontalFlowBarrierMultiplier`, + :class:`imod.mf6.HorizontalFlowBarrierHydraulicCharacteristic` now uses + vertical Polygons instead of Linestrings as geometry, and ``"ztop"`` and + ``"zbottom"`` variables are not used anymore. See + :func:`imod.prepare.linestring_to_square_zpolygons` and + :func:`imod.prepare.linestring_to_trapezoid_zpolygons` to generate these + polygons. + +Added +~~~~~ + +- :func:`imod.prepare.linestring_to_square_zpolygons` and + :func:`imod.prepare.linestring_to_trapezoid_zpolygons` to generate + vertical polygons that can be used to specify horizontal flow barriers, specifically: + :class:`imod.mf6.HorizontalFlowBarrierResistance`, + :class:`imod.mf6.HorizontalFlowBarrierMultiplier`, + :class:`imod.mf6.HorizontalFlowBarrierHydraulicCharacteristic`. + [Unreleased] ------------ @@ -310,9 +331,12 @@ Added - Added Python 3.11 support. - The GWF-GWF exchange options are derived from user created packages (NPF, OC) and set automatically. -- Added the ``simulation_start_time`` and ``time_unit`` arguments. To the ``Modflow6Simulation.open_`` methods, and ``imod.mf6.out.open_`` functions. This converts the ``"time"`` coordinate to datetimes. -- added :meth:`imod.mf6.Modflow6Simulation.mask_all_models` to apply a mask to all models under a simulation, -provided the simulation is not split and the models use the same discretization. +- Added the ``simulation_start_time`` and ``time_unit`` arguments. To the + ``Modflow6Simulation.open_`` methods, and ``imod.mf6.out.open_`` functions. + This converts the ``"time"`` coordinate to datetimes. +- added :meth:`imod.mf6.Modflow6Simulation.mask_all_models` to apply a mask to + all models under a simulation, provided the simulation is not split and the + models use the same discretization. Changed diff --git a/docs/api/prepare.rst b/docs/api/prepare.rst index 47641986f..55ede360d 100644 --- a/docs/api/prepare.rst +++ b/docs/api/prepare.rst @@ -25,6 +25,9 @@ Prepare model input zonal_aggregate_polygons zonal_aggregate_raster + linestring_to_square_zpolygons + linestring_to_trapezoid_zpolygons + assign_wells get_lower_active_grid_cells diff --git a/examples/imod5-backwards-compatibility/imod5_conversion.py b/examples/imod5-backwards-compatibility/imod5_conversion.py index 88000dbb8..4a83b0fd0 100644 --- a/examples/imod5-backwards-compatibility/imod5_conversion.py +++ b/examples/imod5-backwards-compatibility/imod5_conversion.py @@ -47,6 +47,10 @@ data_prj["drn-1"]["conductance"] = data_prj["drn-1"]["conductance"].sel(layer=1) data_prj["drn-1"]["elevation"] = data_prj["drn-1"]["elevation"].sel(layer=1) +# Pop broken hfbs +data_prj.pop("hfb-24") +data_prj.pop("hfb-26") + # %% # Target grid # ----------- diff --git a/imod/formats/prj/disv_conversion.py b/imod/formats/prj/disv_conversion.py index 48bab7df4..4483b7ace 100644 --- a/imod/formats/prj/disv_conversion.py +++ b/imod/formats/prj/disv_conversion.py @@ -8,7 +8,7 @@ import pickle from collections import Counter from datetime import datetime -from typing import Dict, List, Optional, Tuple, cast +from typing import Dict, Optional, Tuple import numpy as np import pandas as pd @@ -646,28 +646,11 @@ def create_hfb( geometry=dataframe["geometry"].values, data={ "resistance": dataframe["resistance"].values, - "ztop": np.ones_like(dataframe["geometry"].values) * top.max().values, - "zbottom": np.ones_like(dataframe["geometry"].values) * bottom.min().values, + "layer": value["layer"], }, ) - model[key] = imod.mf6.HorizontalFlowBarrierResistance(barrier_gdf) - - -def merge_hfbs( - horizontal_flow_barriers: List[imod.mf6.HorizontalFlowBarrierResistance], -): - datasets = [] - for horizontal_flow_barrier in horizontal_flow_barriers: - datasets.append(horizontal_flow_barrier.dataset) - - combined_dataset = xr.concat(datasets, "index") - combined_dataset.coords["index"] = np.arange(combined_dataset.sizes["index"]) - - combined_dataframe = cast(gpd.GeoDataFrame, combined_dataset.to_dataframe()) - combined_dataframe.drop("print_input", axis=1, inplace=True) # noqa: PD002 - - return imod.mf6.HorizontalFlowBarrierResistance(combined_dataframe) + model[key] = imod.mf6.SingleLayerHorizontalFlowBarrierResistance(barrier_gdf) PKG_CONVERSION = { @@ -803,13 +786,6 @@ def convert_to_disv( except Exception as e: raise type(e)(f"{e}\nduring conversion of {key}") - # Treat hfb's separately: they must be merged into one, - # as MODFLOW6 only supports a single HFB. - hfb_keys = [key for key in model.keys() if key.split("-")[0] == "hfb"] - hfbs = [model.pop(key) for key in hfb_keys] - if hfbs: - model["hfb"] = merge_hfbs(hfbs) - transient = any("time" in pkg.dataset.dims for pkg in model.values()) if transient and (time_min is not None or time_max is not None): model = model.clip_box(time_min=time_min, time_max=time_max) diff --git a/imod/mf6/hfb.py b/imod/mf6/hfb.py index 682386d94..027cae283 100644 --- a/imod/mf6/hfb.py +++ b/imod/mf6/hfb.py @@ -4,10 +4,11 @@ import typing from copy import deepcopy from enum import Enum -from typing import TYPE_CHECKING, Dict, Optional, Tuple +from typing import TYPE_CHECKING, Dict, List, Optional, Tuple import cftime import numpy as np +import pandas as pd import xarray as xr import xugrid as xu from fastcore.dispatch import typedispatch @@ -17,9 +18,15 @@ from imod.mf6.interfaces.ilinedatapackage import ILineDataPackage from imod.mf6.mf6_hfb_adapter import Mf6HorizontalFlowBarrier from imod.mf6.package import Package +from imod.mf6.utilities.clip import clip_line_gdf_by_grid from imod.mf6.utilities.grid import broadcast_to_full_domain +from imod.mf6.utilities.hfb import ( + _create_zlinestring_from_bound_df, + _extract_hfb_bounds_from_zpolygons, + _prepare_index_names, +) from imod.schemata import EmptyIndexesSchema, MaxNUniqueValuesSchema -from imod.typing import GridDataArray +from imod.typing import GeoDataFrameType, GridDataArray, LineStringType from imod.util.imports import MissingOptionalModule if TYPE_CHECKING: @@ -30,16 +37,20 @@ except ImportError: gpd = MissingOptionalModule("geopandas") -try: + +if TYPE_CHECKING: import shapely -except ImportError: - shapely = MissingOptionalModule("shapely") +else: + try: + import shapely + except ImportError: + shapely = MissingOptionalModule("shapely") @typedispatch def _derive_connected_cell_ids( idomain: xr.DataArray, grid: xu.Ugrid2d, edge_index: np.ndarray -): +) -> xr.Dataset: """ Derive the cell ids of the connected cells of an edge on a structured grid. @@ -88,7 +99,7 @@ def _derive_connected_cell_ids( @typedispatch # type: ignore[no-redef] def _derive_connected_cell_ids( _: xu.UgridDataArray, grid: xu.Ugrid2d, edge_index: np.ndarray -): +) -> xr.Dataset: """ Derive the cell ids of the connected cells of an edge on an unstructured grid. @@ -182,12 +193,86 @@ def to_connected_cells_dataset( return barrier_dataset.dropna("cell_id") +def _make_linestring_from_polygon( + dataframe: GeoDataFrameType, +) -> List[LineStringType]: + """ + Make linestring from a polygon with one axis in the vertical dimension (z), + and one axis in the horizontal plane (x & y dimension). + """ + coordinates, index = shapely.get_coordinates(dataframe.geometry, return_index=True) + df = pd.DataFrame( + {"polygon_index": index, "x": coordinates[:, 0], "y": coordinates[:, 1]} + ) + df = df.drop_duplicates().reset_index(drop=True) + df = df.set_index("polygon_index") + + linestrings = [ + shapely.LineString(gb.values) for _, gb in df.groupby("polygon_index") + ] + + return linestrings + + +def _select_dataframe_with_snapped_line_index( + snapped_dataset: xr.Dataset, edge_index: np.ndarray, dataframe: GeoDataFrameType +): + """ + Select dataframe rows with line indices of snapped edges. Usually, the + broadcasting results in a larger dataframe where individual rows of input + dataframe are repeated for multiple edges. + """ + line_index = snapped_dataset["line_index"].values + line_index = line_index[edge_index].astype(int) + return dataframe.iloc[line_index] + + +def _extract_mean_hfb_bounds_from_dataframe( + dataframe: GeoDataFrameType, +) -> Tuple[pd.Series, pd.Series]: + """ + Extract hfb bounds from dataframe. Requires dataframe geometry to be of type + shapely "Z Polygon". + + For the upper z bounds, function takes the average of the depth of the two + upper nodes. The same holds for the lower z bounds, but then with the two + lower nodes. + + As a visual representation, this happens for each z bound: + + . . + \ >>> + \ . >>> --- . + \ / >>> - + . . + + """ + dataframe = _prepare_index_names(dataframe) + + if not dataframe.geometry.has_z.all(): + raise TypeError("GeoDataFrame geometry has no z, which is required.") + + lower, upper = _extract_hfb_bounds_from_zpolygons(dataframe) + # Compute means inbetween nodes. + index_names = lower.index.names + lower_mean = lower.groupby(index_names)["z"].mean() + upper_mean = upper.groupby(index_names)["z"].mean() + + # Assign to dataframe to map means to right index. + df_to_broadcast = dataframe.copy() + df_to_broadcast["lower"] = lower_mean + df_to_broadcast["upper"] = upper_mean + + return df_to_broadcast["lower"], df_to_broadcast["upper"] + + def _fraction_layer_overlap( snapped_dataset: xu.UgridDataset, edge_index: np.ndarray, + dataframe: GeoDataFrameType, top: xu.UgridDataArray, bottom: xu.UgridDataArray, -): +) -> xr.DataArray: """ Computes the fraction a barrier occupies inside a layer. """ @@ -200,11 +285,10 @@ def _fraction_layer_overlap( layer_bounds[..., 0] = typing.cast(np.ndarray, bottom_mean.values).T layer_bounds[..., 1] = typing.cast(np.ndarray, top_mean.values).T + zmin, zmax = _extract_mean_hfb_bounds_from_dataframe(dataframe) hfb_bounds = np.empty((n_edge, n_layer, 2), dtype=float) - hfb_bounds[..., 0] = ( - snapped_dataset["zbottom"].values[edge_index].reshape(n_edge, 1) - ) - hfb_bounds[..., 1] = snapped_dataset["ztop"].values[edge_index].reshape(n_edge, 1) + hfb_bounds[..., 0] = zmin.values[:, np.newaxis] + hfb_bounds[..., 1] = zmax.values[:, np.newaxis] overlap = _vectorized_overlap(hfb_bounds, layer_bounds) height = layer_bounds[..., 1] - layer_bounds[..., 0] @@ -243,7 +327,7 @@ def _mean_left_and_right( return xr.concat((uda_left, uda_right), dim="two").mean("two") -def _vectorized_overlap(bounds_a: np.ndarray, bounds_b: np.ndarray): +def _vectorized_overlap(bounds_a: np.ndarray, bounds_b: np.ndarray) -> np.ndarray: """ Vectorized overlap computation. Returns the overlap of 2 vectors along the same axis. If there is no overlap zero will be returned. @@ -319,7 +403,7 @@ def _get_variable_names_for_gdf(self) -> list[str]: ] + self._get_vertical_variables() @property - def line_data(self) -> "gpd.GeoDataFrame": + def line_data(self) -> GeoDataFrameType: variables_for_gdf = self._get_variable_names_for_gdf() return gpd.GeoDataFrame( self.dataset[variables_for_gdf].to_dataframe(), @@ -327,7 +411,7 @@ def line_data(self) -> "gpd.GeoDataFrame": ) @line_data.setter - def line_data(self, value: "gpd.GeoDataFrame") -> None: + def line_data(self, value: GeoDataFrameType) -> None: variables_for_gdf = self._get_variable_names_for_gdf() self.dataset = self.dataset.merge( value.to_xarray(), overwrite_vars=variables_for_gdf, join="right" @@ -477,7 +561,7 @@ def is_empty(self) -> bool: return True linestrings = self.dataset["geometry"] - only_empty_lines = all(ls.is_empty for ls in linestrings.values) + only_empty_lines = all(ls.is_empty for ls in linestrings.values.ravel()) return only_empty_lines def _resistance_layer( @@ -540,7 +624,12 @@ def _resistance_layer_overlap( snapped_dataset[self._get_variable_name()] ).values[edge_index] - fraction = _fraction_layer_overlap(snapped_dataset, edge_index, top, bottom) + dataframe = _select_dataframe_with_snapped_line_index( + snapped_dataset, edge_index, self.line_data + ) + fraction = _fraction_layer_overlap( + snapped_dataset, edge_index, dataframe, top, bottom + ) c_aquifer = 1.0 / k_mean inverse_c = (fraction / resistance) + ((1.0 - fraction) / c_aquifer) @@ -663,16 +752,40 @@ def __to_unstructured( def _snap_to_grid( self, idomain: GridDataArray ) -> Tuple[xu.UgridDataset, np.ndarray]: - if "layer" in self.dataset: + if "layer" in self._get_vertical_variables(): variable_names = [self._get_variable_name(), "geometry", "layer"] else: - variable_names = [self._get_variable_name(), "geometry", "ztop", "zbottom"] - barrier_dataframe = self.dataset[variable_names].to_dataframe() + variable_names = [self._get_variable_name(), "geometry"] + barrier_dataframe = gpd.GeoDataFrame( + self.dataset[variable_names].to_dataframe() + ) - snapped_dataset, _ = typing.cast( - xu.UgridDataset, - xu.snap_to_grid(barrier_dataframe, grid=idomain, max_snap_distance=0.5), + if "layer" not in self._get_vertical_variables(): + lower, _ = _extract_hfb_bounds_from_zpolygons(barrier_dataframe) + linestring = _create_zlinestring_from_bound_df(lower) + barrier_dataframe["geometry"] = linestring["geometry"] + + barrier_dataframe = clip_line_gdf_by_grid( + barrier_dataframe, idomain.sel(layer=1) ) + + # Work around issue where xu.snap_to_grid cannot handle snapping a + # dataset with multiple lines appropriately. This can be later replaced + # to a single call to xu.snap_to_grid if this bug is fixed: + # + snapped_dataset_rows: List[xr.Dataset] = [] + for index in barrier_dataframe.index: + # Index with list to return pd.DataFrame instead of pd.Series for + # xu.snap_to_grid. + row_df = barrier_dataframe.loc[[index]] + snapped_dataset_row, _ = typing.cast( + xu.UgridDataset, + xu.snap_to_grid(row_df, grid=idomain, max_snap_distance=0.5), + ) + snapped_dataset_row["line_index"] += index[0] # Set to original line index. + snapped_dataset_rows.append(snapped_dataset_row) + snapped_dataset = xu.merge(snapped_dataset_rows) + edge_index = np.argwhere( snapped_dataset[self._get_variable_name()].notnull().values ).ravel() @@ -747,21 +860,20 @@ class HorizontalFlowBarrierHydraulicCharacteristic(HorizontalFlowBarrierBase): Dataframe that describes: - geometry: the geometries of the barriers, - hydraulic_characteristic: the hydraulic characteristic of the barriers - - ztop: the top z-value of the barriers - - zbottom: the bottom z-value of the barriers print_input: bool Examples -------- - >>> barrier_x = [-1000.0, 0.0, 1000.0] - >>> barrier_y = [500.0, 250.0, 500.0] + >>> x = [-10.0, 0.0, 10.0] + >>> y = [10.0, 0.0, -10.0] + >>> ztop = [10.0, 20.0, 15.0] + >>> zbot = [-10.0, -20.0, 0.0] + >>> polygons = linestring_to_trapezoid_zpolygons(x, y, ztop, zbot) >>> barrier_gdf = gpd.GeoDataFrame( - >>> geometry=[shapely.linestrings(barrier_x, barrier_y),], + >>> geometry=polygons, >>> data={ - >>> "hydraulic_characteristic": [1e-3,], - >>> "ztop": [10.0,], - >>> "zbottom": [0.0,], + >>> "resistance": [1e-3, 1e-3], >>> }, >>> ) >>> hfb = imod.mf6.HorizontalFlowBarrierHydraulicCharacteristic(barrier_gdf) @@ -783,7 +895,7 @@ def _get_variable_name(self) -> str: return "hydraulic_characteristic" def _get_vertical_variables(self) -> list: - return ["ztop", "zbottom"] + return [] def _compute_barrier_values( self, snapped_dataset, edge_index, idomain, top, bottom, k @@ -884,21 +996,20 @@ class HorizontalFlowBarrierMultiplier(HorizontalFlowBarrierBase): Dataframe that describes: - geometry: the geometries of the barriers, - multiplier: the multiplier of the barriers - - ztop: the top z-value of the barriers - - zbottom: the bottom z-value of the barriers print_input: bool Examples -------- - >>> barrier_x = [-1000.0, 0.0, 1000.0] - >>> barrier_y = [500.0, 250.0, 500.0] + >>> x = [-10.0, 0.0, 10.0] + >>> y = [10.0, 0.0, -10.0] + >>> ztop = [10.0, 20.0, 15.0] + >>> zbot = [-10.0, -20.0, 0.0] + >>> polygons = linestring_to_trapezoid_zpolygons(x, y, ztop, zbot) >>> barrier_gdf = gpd.GeoDataFrame( - >>> geometry=[shapely.linestrings(barrier_x, barrier_y),], + >>> geometry=polygons, >>> data={ - >>> "multiplier": [1.5,], - >>> "ztop": [10.0,], - >>> "zbottom": [0.0,], + >>> "multiplier": [10.0, 10.0], >>> }, >>> ) >>> hfb = imod.mf6.HorizontalFlowBarrierMultiplier(barrier_gdf) @@ -920,12 +1031,17 @@ def _get_variable_name(self) -> str: return "multiplier" def _get_vertical_variables(self) -> list: - return ["ztop", "zbottom"] + return [] def _compute_barrier_values( self, snapped_dataset, edge_index, idomain, top, bottom, k ): - fraction = _fraction_layer_overlap(snapped_dataset, edge_index, top, bottom) + dataframe = _select_dataframe_with_snapped_line_index( + snapped_dataset, edge_index, self.line_data + ) + fraction = _fraction_layer_overlap( + snapped_dataset, edge_index, dataframe, top, bottom + ) barrier_values = ( fraction.where(fraction) @@ -1039,21 +1155,21 @@ class HorizontalFlowBarrierResistance(HorizontalFlowBarrierBase): Dataframe that describes: - geometry: the geometries of the barriers, - resistance: the resistance of the barriers - - ztop: the top z-value of the barriers - - zbottom: the bottom z-value of the barriers + print_input: bool Examples -------- - >>> barrier_x = [-1000.0, 0.0, 1000.0] - >>> barrier_y = [500.0, 250.0, 500.0] + >>> x = [-10.0, 0.0, 10.0] + >>> y = [10.0, 0.0, -10.0] + >>> ztop = [10.0, 20.0, 15.0] + >>> zbot = [-10.0, -20.0, 0.0] + >>> polygons = linestring_to_trapezoid_zpolygons(x, y, ztop, zbot) >>> barrier_gdf = gpd.GeoDataFrame( - >>> geometry=[shapely.linestrings(barrier_x, barrier_y),], + >>> geometry=polygons, >>> data={ - >>> "resistance": [1e3,], - >>> "ztop": [10.0,], - >>> "zbottom": [0.0,], + >>> "resistance": [1e3, 1e3], >>> }, >>> ) >>> hfb = imod.mf6.HorizontalFlowBarrierResistance(barrier_gdf) @@ -1076,7 +1192,7 @@ def _get_variable_name(self) -> str: return "resistance" def _get_vertical_variables(self) -> list: - return ["ztop", "zbottom"] + return [] def _compute_barrier_values( self, snapped_dataset, edge_index, idomain, top, bottom, k @@ -1170,7 +1286,9 @@ def from_imod5_dataset( layer = hfb_dict["layer"] if layer == 0: raise ValueError( - "assigning to layer 0 is not supported yet for import of HFB's" + "assigning to layer 0 is not supported for " + "SingleLayerHorizontalFlowBarrierResistance. " + "Try HorizontalFlowBarrierResistance class." ) geometry_layer = hfb_dict["geodataframe"] geometry_layer["layer"] = layer diff --git a/imod/mf6/model.py b/imod/mf6/model.py index c0df91480..031c7623d 100644 --- a/imod/mf6/model.py +++ b/imod/mf6/model.py @@ -23,8 +23,8 @@ from imod.mf6.interfaces.imodel import IModel from imod.mf6.package import Package from imod.mf6.statusinfo import NestedStatusInfo, StatusInfo, StatusInfoBase -from imod.mf6.utilities.hfb import merge_hfb_packages from imod.mf6.utilities.mask import _mask_all_packages +from imod.mf6.utilities.mf6hfb import merge_hfb_packages from imod.mf6.utilities.regrid import RegridderWeightsCache, _regrid_like from imod.mf6.validation import pkg_errors_to_status_info from imod.mf6.write_context import WriteContext diff --git a/imod/mf6/utilities/clip.py b/imod/mf6/utilities/clip.py index 4c4c4481c..31ef95fb3 100644 --- a/imod/mf6/utilities/clip.py +++ b/imod/mf6/utilities/clip.py @@ -11,7 +11,11 @@ from imod.mf6.interfaces.ipackagebase import IPackageBase from imod.mf6.interfaces.ipointdatapackage import IPointDataPackage from imod.mf6.utilities.grid import get_active_domain_slice -from imod.typing import GridDataArray +from imod.mf6.utilities.hfb import ( + clipped_hfb_zlinestrings_to_zpolygons, + hfb_zpolygons_to_zlinestrings, +) +from imod.typing import GeoDataFrameType, GridDataArray from imod.typing.grid import bounding_polygon, is_spatial_grid from imod.util.imports import MissingOptionalModule @@ -93,10 +97,18 @@ def _filter_inactive_cells(package, active): @typedispatch # type: ignore[no-redef, misc] def clip_by_grid(package: ILineDataPackage, active: GridDataArray) -> ILineDataPackage: # noqa: F811 """Clip LineDataPackage outside unstructured/structured grid.""" + clipped_line_data = clip_line_gdf_by_grid(package.line_data, active) - # Clip line with polygon - bounding_gdf = bounding_polygon(active) - clipped_line_data = package.line_data.clip(bounding_gdf) + # Create new instance + clipped_package = deepcopy(package) + clipped_package.line_data = clipped_line_data + return clipped_package + + +def _clip_linestring( + gdf_linestrings: GeoDataFrameType, bounding_gdf: GeoDataFrameType +) -> GeoDataFrameType: + clipped_line_data = gdf_linestrings.clip(bounding_gdf) # Catch edge case: when line crosses only vertex of polygon, a point # or multipoint is returned. Drop these. @@ -106,10 +118,35 @@ def clip_by_grid(package: ILineDataPackage, active: GridDataArray) -> ILineDataP ) clipped_line_data = clipped_line_data[~is_points] - # Convert MultiLineStrings to LineStrings - clipped_line_data = clipped_line_data.explode("geometry", ignore_index=True) + if clipped_line_data.index.shape[0] == 0: + # Shortcut if GeoDataFrame is empty + return clipped_line_data - # Create new instance - clipped_package = deepcopy(package) - clipped_package.line_data = clipped_line_data - return clipped_package + # Convert MultiLineStrings to LineStrings, index parts of MultiLineStrings + clipped_line_data = clipped_line_data.explode( + "geometry", ignore_index=False, index_parts=True + ) + if clipped_line_data.index.nlevels == 3: + index_names = ["bound", "index", "parts"] + else: + index_names = ["index", "parts"] + clipped_line_data.index = clipped_line_data.index.set_names(index_names) + return clipped_line_data + + +def clip_line_gdf_by_grid( + gdf: GeoDataFrameType, active: GridDataArray +) -> GeoDataFrameType: + """Clip GeoDataFrame by bounding polygon of grid""" + # Clip line with polygon + bounding_gdf = bounding_polygon(active) + + if (shapely.get_type_id(gdf.geometry) == shapely.GeometryType.POLYGON).any(): + # Shapely returns z linestrings when clipping our vertical z polygons. + # To work around this convert polygons to zlinestrings to clip. + # Consequently construct polygons from these clipped linestrings. + gdf_linestrings = hfb_zpolygons_to_zlinestrings(gdf) + clipped_linestrings = _clip_linestring(gdf_linestrings, bounding_gdf) + return clipped_hfb_zlinestrings_to_zpolygons(clipped_linestrings) + else: + return _clip_linestring(gdf, bounding_gdf) diff --git a/imod/mf6/utilities/hfb.py b/imod/mf6/utilities/hfb.py index 82a70f4d1..1b43763fe 100644 --- a/imod/mf6/utilities/hfb.py +++ b/imod/mf6/utilities/hfb.py @@ -1,67 +1,191 @@ -from typing import List +from typing import TYPE_CHECKING, Tuple -import xarray as xr +import pandas as pd -from imod.mf6.hfb import ( - HorizontalFlowBarrierBase, - _prepare_barrier_dataset_for_mf6_adapter, -) -from imod.mf6.mf6_hfb_adapter import Mf6HorizontalFlowBarrier -from imod.typing import GridDataArray +from imod.typing import GeoDataFrameType, GeoSeriesType +from imod.util.imports import MissingOptionalModule +if TYPE_CHECKING: + import geopandas as gpd +else: + try: + import geopandas as gpd + except ImportError: + gpd = MissingOptionalModule("geopandas") -def inverse_sum(a: xr.Dataset) -> xr.Dataset: - """Sum of the inverse""" - return (1 / a).sum() +try: + import shapely +except ImportError: + shapely = MissingOptionalModule("shapely") -def merge_hfb_packages( - hfb_ls: List[HorizontalFlowBarrierBase], - idomain: GridDataArray, - top: GridDataArray, - bottom: GridDataArray, - k: GridDataArray, -) -> Mf6HorizontalFlowBarrier: +def _create_zlinestring_from_bound_df(bound: pd.DataFrame) -> GeoDataFrameType: + """Create geodataframe with linestring geometry from dataframe with bounds.""" + bound = _prepare_index_names(bound) + # Make sure only x, y, z or x, y in columns + columns = sorted({"x", "y", "z"} & set(bound.columns)) + index_names = list(bound.index.names) + # Prevent multiindex to be created in groupby by avoiding list + if bound.index.name: + index_to_group = bound.index.name + else: + index_to_group = index_names + # Each linestring has its own index, therefore groupby index. + mapping_linestrings = [ + (g[0], shapely.LineString(g[1][columns].values)) + for g in bound.groupby(index_to_group) + ] + index, linestrings = zip(*mapping_linestrings) + + gdf = gpd.GeoDataFrame( + linestrings, index=index, columns=["geometry"], geometry="geometry" + ) + gdf.index = gdf.index.set_names(index_names) + return gdf + + +def _create_zpolygon_from_polygon_df(polygon_df: pd.DataFrame) -> GeoDataFrameType: + """ + Create geodataframe with polygon geometry from dataframe with polygon + nodes. The dataframe with nodes must have a multi-index with name ["index", + "parts"] """ - Merges HorizontalFlowBarrier packages into single package as MODFLOW 6 - doesn't support multiple HFB packages. + index_names = ["index", "parts"] + polygons = [ + (g[0], shapely.Polygon(g[1].values)) for g in polygon_df.groupby(index_names) + ] + index_tuples, polygons_data = list(zip(*polygons)) + multi_index = pd.MultiIndex.from_tuples(index_tuples, names=index_names) + return gpd.GeoDataFrame( + polygons_data, columns=["geometry"], index=multi_index, geometry="geometry" + ) - Parameters + +def _prepare_index_names( + dataframe: GeoDataFrameType, +) -> GeoDataFrameType: + """ + Prepare index names, if single index, index should be named 'index', if + multi-index, it should be '(index, parts)'; where 'index' refers to the line + index of the original linestrings provided by user and 'parts' to segment of + this linestring after clipping. If the line index was not named 'index', but + is None, this function sets it to 'index'. This is aligned with how pandas + names an unnamed index when calling df.reset_index(). + """ + index_names = dataframe.index.names + + match index_names: + case ["index"] | ["index", "parts"]: + return dataframe + case [None]: # Unnamed line index + new_index_names = ["index"] + case [None, "parts"]: # Unnamed line index + new_index_names = ["index", "parts"] + case _: + raise IndexError( + f"Index names should be ['index'] or ['index', 'parts']. Got {index_names}" + ) + + dataframe.index = dataframe.index.set_names(new_index_names) + return dataframe + + +def _extract_hfb_bounds_from_zpolygons( + dataframe: GeoDataFrameType, +) -> Tuple[pd.DataFrame, pd.DataFrame]: + """ + Extract hfb bounds from dataframe. Requires dataframe geometry to be of type + shapely "Z Polygon". + """ + dataframe = _prepare_index_names(dataframe) + + if not dataframe.geometry.has_z.all(): + raise TypeError("GeoDataFrame geometry has no z, which is required.") + + coordinates = dataframe.geometry.get_coordinates(include_z=True) + + groupby_names = list(dataframe.index.names) + ["x", "y"] + grouped = coordinates.reset_index().groupby(groupby_names) + + lower = grouped.min().reset_index(["x", "y"]) + upper = grouped.max().reset_index(["x", "y"]) + + return lower, upper + + +def hfb_zpolygons_to_zlinestrings(dataframe: GeoDataFrameType) -> GeoDataFrameType: + """ + Convert GeoDataFrame with zpolygons to zlinestrings. + + Paramaters ---------- - hfb_ls: list - List of HorizontalFlowBarrier packages. These will be merged into one. - Function takes settings like "print_input" from the first object in the - list. - idomain: GridDataArray - Grid with active cells. - top: GridDataArray - Grid with top of model layers. - bottom: GridDataArray - Grid with bottom of model layers. - k: GridDataArray - Grid with hydraulic conductivities. + dataframe: GeoDataFrame + GeoDataFrame with a Z Polygons as datatype. + + Returns + ------- + GeoDataFrame with upper and lower bound as linestrings. + The multi-index denotes whether linestring designates "upper" or "lower" + bound. """ + lower, upper = _extract_hfb_bounds_from_zpolygons(dataframe) + + lower_gdf = _create_zlinestring_from_bound_df(lower) + upper_gdf = _create_zlinestring_from_bound_df(upper) + + bounds_gdf = pd.concat( + [lower_gdf, upper_gdf], + keys=[ + "lower", + "upper", + ], + ) + + return bounds_gdf - barrier_ls = [ - hfb._to_connected_cells_dataset(idomain, top, bottom, k) for hfb in hfb_ls - ] - barrier_dataset = xr.concat(barrier_ls, dim="cell_id") - # xarray GroupbyDataset doesn't allow reducing with different methods per variable. - # Therefore groupby twice: once for cell_id, once for hydraulic_characteristic. - cell_id_merged = ( - barrier_dataset[["cell_id1", "cell_id2"]].groupby("cell_id").first() +def _flip_linestrings(df: pd.DataFrame) -> pd.DataFrame: + """ + Flip linestrings, preserve linestring order. + """ + # Add extra index ascending to sort with, with reset. + # This new index denotes unique nodes + df_reset = df.reset_index() + # Set to multi-index to prepare sort + df_multi = df_reset.set_index(["index", "parts", df_reset.index]) + # Sort, only reverse newly added index. + df_sorted = df_multi.sort_index( + level=[0, 1, 2], ascending=[True, True, False], axis=0 ) - hc_merged = 1 / barrier_dataset[["hydraulic_characteristic"]].groupby( - "cell_id" - ).map(inverse_sum) - # Force correct dim order - cell_id_merged = cell_id_merged.transpose("cell_dims1", "cell_dims2", "cell_id") - # Merge datasets into one - barrier_dataset_merged = xr.merge([cell_id_merged, hc_merged], join="exact") - # Set leftover options - barrier_dataset_merged["print_input"] = hfb_ls[0].dataset["print_input"] - barrier_dataset_merged = _prepare_barrier_dataset_for_mf6_adapter( - barrier_dataset_merged + # Drop index added for sorting + return df_sorted.reset_index(level=2, drop=True) + + +def clipped_hfb_zlinestrings_to_zpolygons( + bounds_gdf: GeoSeriesType, +) -> GeoDataFrameType: + """ + Convert clipped zlinestrings provided with bounds_gdf to zpolygons + + Parameters + ---------- + bounds_gdf: Dataframe + Dataframe with for each polygon an upper and lower shapely.LINESTRING, + indicated by index "upper" and "lower". + """ + # Empty Dataframe + if bounds_gdf.shape[0] == 0: + return bounds_gdf + + coordinates = bounds_gdf.get_coordinates(include_z=True) + # Sort index to ascending everywhere to be able to assign flip upper bound + # linestrings without errors. + coordinates = coordinates.sort_index( + level=[0, 1, 2], ascending=[True, True, True], axis=0 ) - return Mf6HorizontalFlowBarrier(**barrier_dataset_merged.data_vars) + # Reverse upper bound to prevent bowtie polygon from being made. + coordinates.loc["upper"] = _flip_linestrings(coordinates.loc["upper"]).values + # Drop index with "upper" and "lower" in it. + coordinates = coordinates.reset_index(level=0, drop=True) + + return _create_zpolygon_from_polygon_df(coordinates) diff --git a/imod/mf6/utilities/mf6hfb.py b/imod/mf6/utilities/mf6hfb.py new file mode 100644 index 000000000..82a70f4d1 --- /dev/null +++ b/imod/mf6/utilities/mf6hfb.py @@ -0,0 +1,67 @@ +from typing import List + +import xarray as xr + +from imod.mf6.hfb import ( + HorizontalFlowBarrierBase, + _prepare_barrier_dataset_for_mf6_adapter, +) +from imod.mf6.mf6_hfb_adapter import Mf6HorizontalFlowBarrier +from imod.typing import GridDataArray + + +def inverse_sum(a: xr.Dataset) -> xr.Dataset: + """Sum of the inverse""" + return (1 / a).sum() + + +def merge_hfb_packages( + hfb_ls: List[HorizontalFlowBarrierBase], + idomain: GridDataArray, + top: GridDataArray, + bottom: GridDataArray, + k: GridDataArray, +) -> Mf6HorizontalFlowBarrier: + """ + Merges HorizontalFlowBarrier packages into single package as MODFLOW 6 + doesn't support multiple HFB packages. + + Parameters + ---------- + hfb_ls: list + List of HorizontalFlowBarrier packages. These will be merged into one. + Function takes settings like "print_input" from the first object in the + list. + idomain: GridDataArray + Grid with active cells. + top: GridDataArray + Grid with top of model layers. + bottom: GridDataArray + Grid with bottom of model layers. + k: GridDataArray + Grid with hydraulic conductivities. + """ + + barrier_ls = [ + hfb._to_connected_cells_dataset(idomain, top, bottom, k) for hfb in hfb_ls + ] + barrier_dataset = xr.concat(barrier_ls, dim="cell_id") + + # xarray GroupbyDataset doesn't allow reducing with different methods per variable. + # Therefore groupby twice: once for cell_id, once for hydraulic_characteristic. + cell_id_merged = ( + barrier_dataset[["cell_id1", "cell_id2"]].groupby("cell_id").first() + ) + hc_merged = 1 / barrier_dataset[["hydraulic_characteristic"]].groupby( + "cell_id" + ).map(inverse_sum) + # Force correct dim order + cell_id_merged = cell_id_merged.transpose("cell_dims1", "cell_dims2", "cell_id") + # Merge datasets into one + barrier_dataset_merged = xr.merge([cell_id_merged, hc_merged], join="exact") + # Set leftover options + barrier_dataset_merged["print_input"] = hfb_ls[0].dataset["print_input"] + barrier_dataset_merged = _prepare_barrier_dataset_for_mf6_adapter( + barrier_dataset_merged + ) + return Mf6HorizontalFlowBarrier(**barrier_dataset_merged.data_vars) diff --git a/imod/prepare/__init__.py b/imod/prepare/__init__.py index 13032246d..caf5fc202 100644 --- a/imod/prepare/__init__.py +++ b/imod/prepare/__init__.py @@ -13,7 +13,11 @@ speed by making use of the Numba compiler, to be able to regrid large datasets. """ -from imod.prepare import spatial, subsoil, surface_water +from imod.prepare import hfb, spatial, subsoil, surface_water +from imod.prepare.hfb import ( + linestring_to_square_zpolygons, + linestring_to_trapezoid_zpolygons, +) from imod.prepare.layer import ( create_layered_top, get_lower_active_grid_cells, diff --git a/imod/prepare/hfb.py b/imod/prepare/hfb.py new file mode 100644 index 000000000..c56af9826 --- /dev/null +++ b/imod/prepare/hfb.py @@ -0,0 +1,219 @@ +from itertools import pairwise +from typing import TYPE_CHECKING, List, Tuple + +from imod.typing import PolygonType +from imod.util.imports import MissingOptionalModule + +if TYPE_CHECKING: + import shapely +else: + try: + import shapely + except ImportError: + shapely = MissingOptionalModule("shapely") + + +def _line_to_square_zpolygon( + x: Tuple[float, float], y: Tuple[float, float], z: Tuple[float, float] +) -> PolygonType: + """ + Creates polygon as follows:: + + xy0,z0 -- xy1,z0 + | | + | | + | | + xy0,z1 -- xy1,z1 + """ + return shapely.Polygon( + ( + (x[0], y[0], z[0]), + (x[0], y[0], z[1]), + (x[1], y[1], z[1]), + (x[1], y[1], z[0]), + ), + ) + + +def linestring_to_square_zpolygons( + barrier_x: List[float], + barrier_y: List[float], + barrier_ztop: List[float], + barrier_zbottom: List[float], +) -> List[PolygonType]: + """ + Create square vertical polygons from linestrings, with a varying ztop and + zbottom over the line. Note: If the lists of x and y values of length N, the + list of z values need to have length N-1. These are shaped as follows:: + + xy0,zt0 -- xy1,zt0 + | | + | xy1,zt1 ---- xy2,zt1 + | | | + xy0,zb0 -- xy1,zb0 | + | | + | | + xy1,zb1 ---- xy2,zb1 + + Parameters + ---------- + barrier_x: list of floats + x-locations of barrier, length N + barrier_y: list of floats + y-locations of barrier, length N + barrier_ztop: list of floats + top of barrier, length N-1 + barrier_zbot: list of floats + bottom of barrier, length N-1 + + Returns + ------- + List of polygons with z dimension. + + Examples + -------- + + >>> x = [-10.0, 0.0, 10.0] + >>> y = [10.0, 0.0, -10.0] + >>> ztop = [10.0, 20.0] + >>> zbot = [-10.0, -20.0] + >>> polygons = linestring_to_square_zpolygons(x, y, ztop, zbot) + + You can use these polygons to construct horizontal flow barriers: + + >>> geometry = gpd.GeoDataFrame(geometry=polygons, data={ + >>> "resistance": [1e3, 1e3], + >>> }, + >>> ) + >>> hfb = imod.mf6.HorizontalFlowBarrierResistance(geometry, print_input) + """ + n = len(barrier_x) + expected_lengths = (n, n, n - 1, n - 1) + actual_lengths = ( + len(barrier_x), + len(barrier_y), + len(barrier_ztop), + len(barrier_zbottom), + ) + if expected_lengths != actual_lengths: + raise ValueError( + "Lengths of barrier data, not properly made. For lengths: (x, y," + f" ztop, zbottom). Expected lengths: {expected_lengths}, received" + f" lengths: {actual_lengths}" + ) + + x_pairs = pairwise(barrier_x) + y_pairs = pairwise(barrier_y) + z_pairs = zip(barrier_ztop, barrier_zbottom) + return [ + _line_to_square_zpolygon(x, y, z) for x, y, z in zip(x_pairs, y_pairs, z_pairs) + ] + + +def _line_to_trapezoid_zpolygon( + x: Tuple[float, float], + y: Tuple[float, float], + zt: Tuple[float, float], + zb: Tuple[float, float], +) -> PolygonType: + """ + Creates polygon as follows:: + + xy0,zt0 + | \ + | \ + | xy1,zt1 + | | + | | + | xy1,zb1 + | / + | / + xy0,zb0 + """ + return shapely.Polygon( + ( + (x[0], y[0], zt[0]), + (x[0], y[0], zb[1]), + (x[1], y[1], zt[1]), + (x[1], y[1], zb[0]), + ), + ) + + +def linestring_to_trapezoid_zpolygons( + barrier_x: List[float], + barrier_y: List[float], + barrier_ztop: List[float], + barrier_zbottom: List[float], +) -> List[PolygonType]: + """ + Create trapezoid vertical polygons from linestrings, with a varying ztop and + zbottom over the line. These are shaped as follows:: + + xy0,zt0 xy2,zt2 + | \ / | + | \ / | + | xy1,zt1 | + | | | + | | | + | xy1,zb1 -- xy2,zb2 + | / + | / + xy0,zb0 + + Parameters + ---------- + barrier_x: list of floats + x-locations of barrier, length N + barrier_y: list of floats + y-locations of barrier, length N + barrier_ztop: list of floats + top of barrier, length N + barrier_zbot: list of floats + bottom of barrier, length N + + Returns + ------- + List of polygons with z dimension. + + Examples + -------- + + >>> x = [-10.0, 0.0, 10.0] + >>> y = [10.0, 0.0, -10.0] + >>> ztop = [10.0, 20.0, 15.0] + >>> zbot = [-10.0, -20.0, 0.0] + >>> polygons = linestring_to_trapezoid_zpolygons(x, y, ztop, zbot) + + You can use these polygons to construct horizontal flow barriers: + + >>> geometry = gpd.GeoDataFrame(geometry=polygons, data={ + >>> "resistance": [1e3, 1e3], + >>> }, + >>> ) + >>> hfb = imod.mf6.HorizontalFlowBarrierResistance(geometry, print_input) + """ + + n = len(barrier_x) + expected_lengths = (n, n, n, n) + actual_lengths = ( + len(barrier_x), + len(barrier_y), + len(barrier_ztop), + len(barrier_zbottom), + ) + if expected_lengths != actual_lengths: + raise ValueError( + "Lengths of barrier data, not properly made. For lengths: (x, y," + f" ztop, zbottom). Expected lengths: {expected_lengths}, received" + f" lengths: {actual_lengths}" + ) + + x_pairs = pairwise(barrier_x) + y_pairs = pairwise(barrier_y) + zt_pairs = pairwise(barrier_ztop) + zb_pairs = pairwise(barrier_zbottom) + return [ + _line_to_trapezoid_zpolygon(x, y, zt, zb) + for x, y, zt, zb in zip(x_pairs, y_pairs, zt_pairs, zb_pairs) + ] diff --git a/imod/tests/fixtures/mf6_small_models_fixture.py b/imod/tests/fixtures/mf6_small_models_fixture.py index f5354767f..cbea30bfe 100644 --- a/imod/tests/fixtures/mf6_small_models_fixture.py +++ b/imod/tests/fixtures/mf6_small_models_fixture.py @@ -25,7 +25,7 @@ def grid_data_structured( dims = ("layer", "y", "x") layer = np.arange(1, nlayer + 1) - coords = {"layer": layer, "y": y, "x": x, "dx": cellsize, "dy": cellsize} + coords = {"layer": layer, "y": y, "x": x, "dx": cellsize, "dy": -cellsize} structured_grid_data = xr.DataArray( np.ones(shape, dtype=dtype) * value, coords=coords, dims=dims diff --git a/imod/tests/test_mf6/test_mf6_hfb.py b/imod/tests/test_mf6/test_mf6_hfb.py index 591a8b2ec..fa2a5335b 100644 --- a/imod/tests/test_mf6/test_mf6_hfb.py +++ b/imod/tests/test_mf6/test_mf6_hfb.py @@ -1,12 +1,13 @@ +from copy import deepcopy from unittest.mock import patch import geopandas as gpd import numpy as np import pytest -import shapely import xarray as xr import xugrid as xu from numpy.testing import assert_array_equal +from shapely import Polygon, get_coordinates, linestrings from imod.mf6 import ( HorizontalFlowBarrierHydraulicCharacteristic, @@ -18,6 +19,8 @@ ) from imod.mf6.dis import StructuredDiscretization from imod.mf6.hfb import ( + _extract_mean_hfb_bounds_from_dataframe, + _make_linestring_from_polygon, _prepare_barrier_dataset_for_mf6_adapter, to_connected_cells_dataset, ) @@ -25,6 +28,10 @@ from imod.mf6.npf import NodePropertyFlow from imod.mf6.simulation import Modflow6Simulation from imod.mf6.utilities.regrid import RegridderWeightsCache +from imod.prepare.hfb import ( + linestring_to_square_zpolygons, + linestring_to_trapezoid_zpolygons, +) from imod.tests.fixtures.flow_basic_fixture import BasicDisSettings from imod.typing.grid import nan_like, ones_like @@ -59,15 +66,19 @@ def test_to_mf6_creates_mf6_adapter_init( print_input = False + barrier_ztop = [0.0, 0.0] + barrier_zbottom = [min(bottom.values), min(bottom.values)] barrier_y = [5.5, 5.5, 5.5] barrier_x = [82.0, 40.0, 0.0] + polygons = linestring_to_square_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbottom + ) + geometry = gpd.GeoDataFrame( - geometry=[shapely.linestrings(barrier_x, barrier_y)], + geometry=polygons, data={ - barrier_value_name: [barrier_value], - "ztop": [0.0], - "zbottom": [min(bottom.values)], + barrier_value_name: [barrier_value, barrier_value], }, ) @@ -77,7 +88,10 @@ def test_to_mf6_creates_mf6_adapter_init( _ = hfb.to_mf6_pkg(idomain, top, bottom, k) # Assert. - snapped, _ = xu.snap_to_grid(geometry, grid=idomain, max_snap_distance=0.5) + lines = _make_linestring_from_polygon(geometry) + gdf_line = deepcopy(geometry) + gdf_line["geometry"] = lines + snapped, _ = xu.snap_to_grid(gdf_line, grid=idomain, max_snap_distance=0.5) edge_index = np.argwhere(snapped[barrier_value_name].notnull().values).ravel() grid = ( @@ -110,34 +124,32 @@ def test_to_mf6_creates_mf6_adapter_init( @pytest.mark.parametrize("dis", ["basic_unstructured_dis", "basic_dis"]) -def test_to_mf6_creates_mf6_adapter( +def test_hfb_regrid( dis, request, ): - barrier_class, barrier_value_name, barrier_value = ( - HorizontalFlowBarrierResistance, - "resistance", - 1e3, - ) - # Arrange idomain, _, _ = request.getfixturevalue(dis) print_input = False + barrier_ztop = [0.0, 0.0] + barrier_zbottom = [-100.0, -100.0] barrier_y = [5.5, 5.5, 5.5] barrier_x = [82.0, 40.0, 0.0] + polygons = linestring_to_square_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbottom + ) + geometry = gpd.GeoDataFrame( - geometry=[shapely.linestrings(barrier_x, barrier_y)], + geometry=polygons, data={ - barrier_value_name: [barrier_value], - "ztop": [0.0], - "zbottom": [-100.0], + "resistance": [1e3, 1e3], }, ) - hfb = barrier_class(geometry, print_input) + hfb = HorizontalFlowBarrierResistance(geometry, print_input) # Act if isinstance(idomain, xu.UgridDataArray): @@ -150,9 +162,13 @@ def test_to_mf6_creates_mf6_adapter( hfb_clipped = hfb.regrid_like(idomain_clipped.sel(layer=1), regrid_cache) # Assert - x, y = hfb_clipped.dataset["geometry"].values[0].xy - np.testing.assert_allclose(x, [50.0, 40.0, 0.0]) - np.testing.assert_allclose(y, [5.5, 5.5, 5.5]) + geometries = hfb_clipped.dataset["geometry"].values.ravel() + + xyz_arr = get_coordinates(geometries[0], include_z=True) # 2nd polygon is clipped + + np.testing.assert_allclose(xyz_arr[:, 0], [40.0, 50.0, 50.0, 40.0, 40.0]) + np.testing.assert_allclose(xyz_arr[:, 1], [5.5, 5.5, 5.5, 5.5, 5.5]) + np.testing.assert_allclose(xyz_arr[:, 2], [-100.0, -100.0, 0.0, 0.0, -100.0]) @pytest.mark.parametrize("dis", ["basic_unstructured_dis", "basic_dis"]) @@ -190,7 +206,7 @@ def test_to_mf6_creates_mf6_adapter_layered( geometry = gpd.GeoDataFrame( geometry=[ - shapely.linestrings(barrier_x, barrier_y), + linestrings(barrier_x, barrier_y), ], data={ barrier_value_name: [barrier_value], @@ -244,7 +260,6 @@ def test_to_mf6_creates_mf6_adapter_layered( (-5.0, -35.0, np.array([1, 1e3, 1])), # 2nd layer (0.0, -35.0, np.array([1e3, 1e3, 1])), # 1st and 2nd layer (-5.0, -135.0, np.array([1, 1e3, 1e3])), # 2nd and 3th layer - (-5.0, -135.0, np.array([1, 1e3, 1e3])), # 2nd and 3th layer (100.0, -135.0, np.array([1e3, 1e3, 1e3])), # ztop out of bounds (0.0, -200.0, np.array([1e3, 1e3, 1e3])), # zbottom out of bounds (100.0, 50.0, np.array([1, 1, 1])), # z-range has no overlap with the domain @@ -256,7 +271,7 @@ def test_to_mf6_creates_mf6_adapter_layered( ], ) @patch("imod.mf6.mf6_hfb_adapter.Mf6HorizontalFlowBarrier.__new__", autospec=True) -def test_to_mf6_different_z_boundaries( +def test_to_mf6_different_constant_z_boundaries( mf6_flow_barrier_mock, basic_dis, ztop, zbottom, expected_values ): # Arrange. @@ -265,15 +280,19 @@ def test_to_mf6_different_z_boundaries( print_input = False + barrier_ztop = [ztop, ztop] + barrier_zbottom = [zbottom, zbottom] barrier_y = [5.5, 5.5, 5.5] barrier_x = [82.0, 40.0, 0.0] + polygons = linestring_to_square_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbottom + ) + geometry = gpd.GeoDataFrame( - geometry=[shapely.linestrings(barrier_x, barrier_y)], + geometry=polygons, data={ - "resistance": [1e3], - "ztop": [ztop], - "zbottom": [zbottom], + "resistance": [1e3, 1e3], }, ) @@ -289,6 +308,130 @@ def test_to_mf6_different_z_boundaries( assert_array_equal(max_values_per_layer, 1.0 / expected_values) +@pytest.mark.parametrize( + "barrier_ztop, barrier_zbottom, expected_values", + [ + ( + [0.0, -5.0], + [ + -35.0, + -35.0, + ], + np.array([[1e3, 1e3, 1], [1, 3e3, 1]]), + ), # 1st and 2nd layer, 2nd layer + ( + [100.0, 0.0], + [-135.0, -35.0], + np.array([[1e3, 1e3, 1e3], [3e3, 3e3, 1]]), + ), # ztop out of bounds, 1st and 2nd layer, + ( + [0.0, 100.0], + [-200.0, 50.0], + np.array([[1e3, 1e3, 1e3], [1, 1, 1]]), + ), # zbottom out of bounds, z-range has no overlap with the domain + ], +) +@patch("imod.mf6.mf6_hfb_adapter.Mf6HorizontalFlowBarrier.__new__", autospec=True) +def test_to_mf6_different_varying_square_z_boundaries( + mf6_flow_barrier_mock, basic_dis, barrier_ztop, barrier_zbottom, expected_values +): + """ + Test with square zpolygons with varying bounds. The second barrier is a + barrier that is so short it should be ignored. + """ + # Arrange. + idomain, top, bottom = basic_dis + k = ones_like(top) + + print_input = False + + # Insert second barrier values, which need to be ignored + barrier_ztop.insert(1, min(barrier_ztop)) + barrier_zbottom.insert(1, max(barrier_zbottom)) + barrier_y = [5.5, 5.5, 5.5, 5.5] + barrier_x = [0.0, 40.0, 41.0, 82.0] + + polygons = linestring_to_square_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbottom + ) + + geometry = gpd.GeoDataFrame( + geometry=polygons, + data={ + "resistance": [1e3, 2e3, 3e3], + }, + ) + + hfb = HorizontalFlowBarrierResistance(geometry, print_input) + + # Act. + _ = hfb.to_mf6_pkg(idomain, top, bottom, k) + + # Assert. + _, args = mf6_flow_barrier_mock.call_args + barrier_values = args["hydraulic_characteristic"].values.reshape(3, 8) + assert_array_equal(barrier_values[:, 3:5], 1.0 / expected_values.T) + + +@pytest.mark.parametrize( + "barrier_ztop, barrier_zbottom, expected_values", + [ + ( + [2.5, -2.5, -7.5], + [ + -35.0, + -35.0, + -35.0, + ], + np.array([[1e3, 1e3, 1], [1, 3e3, 1]]), + ), # 1st and 2nd layer, 2nd layer + ( + [200.0, 0.0, 0.0], + [-270.0, -35.0, -35.0], + np.array([[1e3, 1e3, 1e3], [3e3, 3e3, 1]]), + ), # ztop out of bounds, 1st and 2nd layer, + ( + [0.0, 200.0, 200.0], + [-400.0, 50.0, 50.0], + np.array([[1e3, 1e3, 1e3], [1, 1, 1]]), + ), # zbottom out of bounds, z-range has no overlap with the domain + ], +) +@patch("imod.mf6.mf6_hfb_adapter.Mf6HorizontalFlowBarrier.__new__", autospec=True) +def test_to_mf6_different_trapezoid_z_boundaries( + mf6_flow_barrier_mock, basic_dis, barrier_ztop, barrier_zbottom, expected_values +): + # Arrange. + idomain, top, bottom = basic_dis + k = ones_like(top) + + print_input = False + + barrier_y = [5.5, 5.5, 5.5] + barrier_x = [0.0, 40.0, 82.0] + + polygons = linestring_to_trapezoid_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbottom + ) + + geometry = gpd.GeoDataFrame( + geometry=polygons, + data={ + "resistance": [1e3, 3e3], + }, + ) + + hfb = HorizontalFlowBarrierResistance(geometry, print_input) + + # Act. + _ = hfb.to_mf6_pkg(idomain, top, bottom, k) + + # Assert. + _, args = mf6_flow_barrier_mock.call_args + barrier_values = args["hydraulic_characteristic"].values.reshape(3, 8) + assert_array_equal(barrier_values[:, 3:5], 1.0 / expected_values.T) + + @pytest.mark.parametrize( "layer, expected_values", [ @@ -307,7 +450,7 @@ def test_to_mf6_layered_hfb(mf6_flow_barrier_mock, basic_dis, layer, expected_va barrier_x = [82.0, 40.0, 0.0] geometry = gpd.GeoDataFrame( - geometry=[shapely.linestrings(barrier_x, barrier_y)], + geometry=[linestrings(barrier_x, barrier_y)], data={ "resistance": [1e3], "layer": [layer], @@ -336,7 +479,7 @@ def test_to_mf6_layered_hfb__error(): barrier_y = [5.5, 5.5, 5.5] barrier_x = [82.0, 40.0, 0.0] - linestring = shapely.linestrings(barrier_x, barrier_y) + linestring = linestrings(barrier_x, barrier_y) geometry = gpd.GeoDataFrame( geometry=[linestring, linestring], @@ -382,15 +525,19 @@ def test_to_mf6_remove_invalid_edges( ) k = ones_like(top) + barrier_ztop = [0.0] + barrier_zbottom = [-5.0] barrier_y = [0.0, 2.0] barrier_x = [barrier_x_loc, barrier_x_loc] + polygons = linestring_to_square_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbottom + ) + geometry = gpd.GeoDataFrame( - geometry=[shapely.linestrings(barrier_x, barrier_y)], + geometry=polygons, data={ "resistance": [1e3], - "ztop": [0], - "zbottom": [-5], }, ) @@ -439,15 +586,23 @@ def test_to_mf6_remove_barrier_parts_adjacent_to_inactive_cells( ] = inactivity_marker # make cell inactive k = ones_like(top) + barrier_ztop = [ + 0.0, + ] + barrier_zbottom = [ + -5.0, + ] barrier_y = [0.0, 2.0] barrier_x = [barrier_x_loc, barrier_x_loc] + polygons = linestring_to_square_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbottom + ) + geometry = gpd.GeoDataFrame( - geometry=[shapely.linestrings(barrier_x, barrier_y)], + geometry=polygons, data={ "resistance": [1e3], - "ztop": [0], - "zbottom": [-5], }, ) @@ -465,22 +620,27 @@ def test_to_mf6_remove_barrier_parts_adjacent_to_inactive_cells( def test_is_empty(): geometry = gpd.GeoDataFrame( - geometry=[shapely.linestrings([], [])], + geometry=[Polygon()], data={ "resistance": [], - "ztop": [], - "zbottom": [], }, ) hfb = HorizontalFlowBarrierResistance(geometry) assert hfb.is_empty() + barrier_ztop = [0.0, 0.0] + barrier_zbottom = [-5.0, -5.0] + barrier_y = [0.0, 2.0, 3.0] + barrier_x = [0.0, 0.0, 0.0] + + polygons = linestring_to_square_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbottom + ) + geometry = gpd.GeoDataFrame( - geometry=[shapely.linestrings([0, 0], [1, 1])], + geometry=polygons, data={ - "resistance": [1.0], - "ztop": [1.0], - "zbottom": [1.0], + "resistance": [1.0, 1.0], }, ) @@ -496,15 +656,21 @@ def test_is_empty(): @pytest.mark.parametrize("print_input", [True, False]) def test_set_options(print_input, parameterizable_basic_dis): idomain, top, bottom = parameterizable_basic_dis + + barrier_x = [-1000.0, 1000.0] + barrier_y = [0.3, 0.3] + barrier_ztop = [top.values[0]] + barrier_zbottom = [bottom.values[-1]] + + polygons = linestring_to_square_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbottom + ) + hfb = HorizontalFlowBarrierResistance( geometry=gpd.GeoDataFrame( - geometry=[ - shapely.linestrings([-1000.0, 1000.0], [0.3, 0.3]), - ], + geometry=polygons, data={ "resistance": [1e3], - "ztop": [10.0], - "zbottom": [0.0], }, ), print_input=print_input, @@ -550,7 +716,7 @@ def test_run_multiple_hfbs(tmp_path, structured_flow_model): barrier_x = [5.0, 5.0, 5.0] geometry = gpd.GeoDataFrame( - geometry=[shapely.linestrings(barrier_x, barrier_y)], + geometry=[linestrings(barrier_x, barrier_y)], data={ "resistance": [1200.0], "layer": [1], @@ -567,7 +733,7 @@ def test_run_multiple_hfbs(tmp_path, structured_flow_model): head_single = simulation_single.open_head() geometry = gpd.GeoDataFrame( - geometry=[shapely.linestrings(barrier_x, barrier_y)], + geometry=[linestrings(barrier_x, barrier_y)], data={ "resistance": [400.0], "layer": [1], @@ -593,3 +759,69 @@ def test_run_multiple_hfbs(tmp_path, structured_flow_model): head_triple = simulation_triple.open_head() xr.testing.assert_equal(head_single, head_triple) + + +def test_make_linestring_from_polygon(): + barrier_x = [-1000.0, 1000.0] + barrier_y = [0.3, 0.3] + barrier_ztop = [10.0] + barrier_zbottom = [-10.0] + + polygons = linestring_to_square_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbottom + ) + + gdf_polygons = gpd.GeoDataFrame( + geometry=polygons, + data={ + "resistance": [1e3], + }, + ) + + linestrings = _make_linestring_from_polygon(gdf_polygons) + + coordinates = get_coordinates(linestrings) + + np.testing.assert_allclose(barrier_x, coordinates[:, 0]) + np.testing.assert_allclose(barrier_y, coordinates[:, 1]) + + +def test_extract_hfb_bounds_from_dataframe(): + barrier_x = [-1000.0, 0.0, 1000.0] + barrier_y = [0.3, 0.3, 0.3] + barrier_ztop = [10.0, 20.0] + barrier_zbottom = [-10.0, -30.0] + + polygons = linestring_to_square_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbottom + ) + + gdf_polygons = gpd.GeoDataFrame( + geometry=polygons, + data={ + "resistance": [1e3, 1e3], + }, + ) + + zmin, zmax = _extract_mean_hfb_bounds_from_dataframe(gdf_polygons) + + np.testing.assert_equal(zmin.values, barrier_zbottom) + np.testing.assert_equal(zmax.values, barrier_ztop) + + +def test_extract_hfb_bounds_from_dataframe__fails(): + """Test if function throws error when providing a line.""" + barrier_x = [-1000.0, 0.0, 1000.0] + barrier_y = [0.3, 0.3, 0.3] + + line_data = linestrings(barrier_x, barrier_y) + + gdf_polygons = gpd.GeoDataFrame( + geometry=[line_data, line_data], + data={ + "resistance": [1e3, 1e3], + }, + ) + + with pytest.raises(TypeError): + _extract_mean_hfb_bounds_from_dataframe(gdf_polygons) diff --git a/imod/tests/test_mf6/test_multimodel/test_mf6_partitioning_structured.py b/imod/tests/test_mf6/test_multimodel/test_mf6_partitioning_structured.py index 2dc495849..2c609912e 100644 --- a/imod/tests/test_mf6/test_multimodel/test_mf6_partitioning_structured.py +++ b/imod/tests/test_mf6/test_multimodel/test_mf6_partitioning_structured.py @@ -6,13 +6,15 @@ import geopandas as gpd import numpy as np import pytest -import shapely import xarray as xr from pytest_cases import case, parametrize_with_cases import imod from imod.mf6 import Modflow6Simulation from imod.mf6.wel import Well +from imod.prepare.hfb import ( + linestring_to_square_zpolygons, +) from imod.typing.grid import zeros_like @@ -132,13 +134,17 @@ def case_hfb_vertical(self): # Vertical line at x = 52500.0 barrier_y = [0.0, 52500.0] barrier_x = [52500.0, 52500.0] + barrier_ztop = [10.0] + barrier_zbottom = [0.0] + + polygons = linestring_to_square_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbottom + ) return gpd.GeoDataFrame( - geometry=[shapely.linestrings(barrier_x, barrier_y)], + geometry=polygons, data={ "resistance": [10.0], - "ztop": [10.0], - "zbottom": [0.0], }, ) @@ -146,13 +152,17 @@ def case_hfb_horizontal(self): # Horizontal line at y = 52500.0 barrier_x = [0.0, 52500.0] barrier_y = [52500.0, 52500.0] + barrier_ztop = [10.0] + barrier_zbottom = [0.0] + + polygons = linestring_to_square_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbottom + ) return gpd.GeoDataFrame( - geometry=[shapely.linestrings(barrier_x, barrier_y)], + geometry=polygons, data={ "resistance": [10.0], - "ztop": [10.0], - "zbottom": [0.0], }, ) @@ -160,13 +170,17 @@ def case_hfb_horizontal_outside_domain(self): # Horizontal line at y = -100.0 running outside domain barrier_x = [0.0, 1_000_000.0] barrier_y = [52500.0, 52500.0] + barrier_ztop = [10.0] + barrier_zbottom = [0.0] + + polygons = linestring_to_square_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbottom + ) return gpd.GeoDataFrame( - geometry=[shapely.linestrings(barrier_x, barrier_y)], + geometry=polygons, data={ "resistance": [10.0], - "ztop": [10.0], - "zbottom": [0.0], }, ) @@ -174,13 +188,17 @@ def case_hfb_diagonal(self): # Diagonal line barrier_y = [0.0, 52500.0] barrier_x = [0.0, 52500.0] + barrier_ztop = [10.0] + barrier_zbottom = [0.0] + + polygons = linestring_to_square_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbottom + ) return gpd.GeoDataFrame( - geometry=[shapely.linestrings(barrier_x, barrier_y)], + geometry=polygons, data={ "resistance": [10.0], - "ztop": [10.0], - "zbottom": [0.0], }, ) diff --git a/imod/tests/test_mf6/test_multimodel/test_mf6_partitioning_unstructured.py b/imod/tests/test_mf6/test_multimodel/test_mf6_partitioning_unstructured.py index e01658222..127c3db21 100644 --- a/imod/tests/test_mf6/test_multimodel/test_mf6_partitioning_unstructured.py +++ b/imod/tests/test_mf6/test_multimodel/test_mf6_partitioning_unstructured.py @@ -4,12 +4,12 @@ import geopandas as gpd import numpy as np import pytest -import shapely import xugrid as xu from pytest_cases import parametrize_with_cases import imod from imod.mf6 import Modflow6Simulation +from imod.prepare.hfb import linestring_to_square_zpolygons from imod.typing.grid import zeros_like @@ -72,13 +72,17 @@ def case_hfb_vertical(self): # Vertical line at x = -100 barrier_y = [-990.0, 990.0] barrier_x = [-100.0, -100.0] + barrier_ztop = [10.0] + barrier_zbottom = [0.0] + + polygons = linestring_to_square_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbottom + ) return gpd.GeoDataFrame( - geometry=[shapely.linestrings(barrier_x, barrier_y)], + geometry=polygons, data={ "resistance": [10.0], - "ztop": [10.0], - "zbottom": [0.0], }, ) @@ -86,13 +90,17 @@ def case_hfb_horizontal(self): # Horizontal line at y = -100.0 barrier_x = [-990.0, 990.0] barrier_y = [-100.0, -100.0] + barrier_ztop = [10.0] + barrier_zbottom = [0.0] + + polygons = linestring_to_square_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbottom + ) return gpd.GeoDataFrame( - geometry=[shapely.linestrings(barrier_x, barrier_y)], + geometry=polygons, data={ "resistance": [10.0], - "ztop": [10.0], - "zbottom": [0.0], }, ) @@ -100,27 +108,17 @@ def case_hfb_horizontal_outside_domain(self): # Horizontal line at y = -100.0 running outside domain barrier_x = [-990.0, 10_000.0] barrier_y = [-100.0, -100.0] + barrier_ztop = [10.0] + barrier_zbottom = [0.0] - return gpd.GeoDataFrame( - geometry=[shapely.linestrings(barrier_x, barrier_y)], - data={ - "resistance": [10.0], - "ztop": [10.0], - "zbottom": [0.0], - }, + polygons = linestring_to_square_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbottom ) - def case_hfb_horizontal_origin(self): - # Horizontal line through origin - barrier_x = [-990.0, 990.0] - barrier_y = [0.0, 0.0] - return gpd.GeoDataFrame( - geometry=[shapely.linestrings(barrier_x, barrier_y)], + geometry=polygons, data={ "resistance": [10.0], - "ztop": [10.0], - "zbottom": [0.0], }, ) @@ -128,13 +126,17 @@ def case_hfb_diagonal(self): # Diagonal line barrier_y = [-480.0, 480.0] barrier_x = [-480.0, 480.0] + barrier_ztop = [10.0] + barrier_zbottom = [0.0] + + polygons = linestring_to_square_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbottom + ) return gpd.GeoDataFrame( - geometry=[shapely.linestrings(barrier_x, barrier_y)], + geometry=polygons, data={ "resistance": [10.0], - "ztop": [10.0], - "zbottom": [0.0], }, ) diff --git a/imod/tests/test_mf6/test_utilities/test_hfb.py b/imod/tests/test_mf6/test_utilities/test_hfb.py index 4c0abd189..e55aedd34 100644 --- a/imod/tests/test_mf6/test_utilities/test_hfb.py +++ b/imod/tests/test_mf6/test_utilities/test_hfb.py @@ -1,225 +1,61 @@ -import geopandas as gpd -import numpy as np +import pandas as pd import pytest -import shapely -import xarray as xr - -from imod.mf6.hfb import ( - HorizontalFlowBarrierResistance, - SingleLayerHorizontalFlowBarrierResistance, -) -from imod.mf6.utilities.hfb import merge_hfb_packages - - -@pytest.mark.usefixtures("structured_flow_model") -@pytest.fixture(scope="function") -def modellayers_single_layer(structured_flow_model): - model = structured_flow_model.clip_box(layer_max=1) - dis = model["dis"] - dis["bottom"] = dis["bottom"].isel(x=0, y=0, drop=True) - npf = model["npf"] - - return { - "idomain": dis["idomain"], - "top": dis["top"], - "bottom": dis["bottom"], - "k": npf["k"], - } - - -@pytest.mark.usefixtures("structured_flow_model") -@pytest.fixture(scope="function") -def modellayers(structured_flow_model): - model = structured_flow_model - dis = model["dis"] - dis["bottom"] = dis["bottom"].isel(x=0, y=0, drop=True) - npf = model["npf"] - - return { - "idomain": dis["idomain"], - "top": dis["top"], - "bottom": dis["bottom"], - "k": npf["k"], - } - - -def make_layer_geometry(resistance, layer): - barrier_y = [11.0, 5.0, -1.0] - barrier_x = [5.0, 5.0, 5.0] - - geometry = gpd.GeoDataFrame( - geometry=[shapely.linestrings(barrier_x, barrier_y)], - data={ - "resistance": [resistance], - "layer": [layer], - }, - ) - return geometry - - -def make_depth_geometry(resistance, top, bot): - barrier_y = [11.0, 5.0, -1.0] - barrier_x = [5.0, 5.0, 5.0] - - geometry = gpd.GeoDataFrame( - geometry=[shapely.linestrings(barrier_x, barrier_y)], - data={ - "resistance": [resistance], - "ztop": [top], - "zbottom": [bot], - }, - ) - return geometry - - -def test_merge_three_hfbs__single_layer(modellayers_single_layer): - """Merge three single layer hfbs, test for lenght""" - # Arrange - n_barriers = 3 - single_resistance = 400.0 - - geometry = make_layer_geometry(single_resistance, 1) - hfb_ls = [ - SingleLayerHorizontalFlowBarrierResistance(geometry) for _ in range(n_barriers) - ] - - # Act - mf6_hfb = merge_hfb_packages(hfb_ls, **modellayers_single_layer) - - # Assert - assert mf6_hfb["cell_id"].shape == (6,) - assert (mf6_hfb["layer"] == 1).all() - expected_resistance = n_barriers * single_resistance - assert (expected_resistance == 1 / mf6_hfb["hydraulic_characteristic"]).all() - - -def test_merge_three_hfbs__compare_single_hfb(modellayers_single_layer): - """ - Merge three single layer hfbs, compare with one hfb with tripled - resistance as created with a call to merge_hfb_packages. - """ - # Arrange - n_barriers = 3 - single_resistance = 400.0 - - geometry = make_layer_geometry(single_resistance, 1) - geometry_tripled = make_layer_geometry(n_barriers * single_resistance, 1) - hfb_ls_triple = [ - SingleLayerHorizontalFlowBarrierResistance(geometry) for _ in range(n_barriers) - ] - hfb_ls_single = [SingleLayerHorizontalFlowBarrierResistance(geometry_tripled)] +from imod.mf6.utilities.hfb import _prepare_index_names - # Act - mf6_hfb_three = merge_hfb_packages(hfb_ls_triple, **modellayers_single_layer) - mf6_hfb_single = merge_hfb_packages(hfb_ls_single, **modellayers_single_layer) - # Assert - xr.testing.assert_equal(mf6_hfb_single.dataset, mf6_hfb_three.dataset) - - -def test_merge_three_hfbs__to_mf6_pkg_single_layer(modellayers_single_layer): +def test_pandas_behavior_index_naming_expected(): """ - Merge three single layer hfbs, compare with one hfb with tripled - resistance as with a call to to_mf6_pkg. + Monitor whether pandas behaviour changes. Quite some logic in + mf6/utilities/hfb depends on specific index naming and how pandas behaves. + This tests if this behaviour goes unchanged. """ - # Arrange - n_barriers = 3 - single_resistance = 400.0 - - geometry = make_layer_geometry(single_resistance, 1) - geometry_tripled = make_layer_geometry(n_barriers * single_resistance, 1) - hfb_ls_triple = [ - SingleLayerHorizontalFlowBarrierResistance(geometry) for _ in range(n_barriers) - ] - hfb_ls_single = [SingleLayerHorizontalFlowBarrierResistance(geometry_tripled)] + df = pd.DataFrame(data={"col1": [1, 2], "col2": [1, 2]}) + df_reset = df.reset_index(drop=False) - # Act - mf6_hfb_three = merge_hfb_packages(hfb_ls_triple, **modellayers_single_layer) - mf6_hfb_single = hfb_ls_single[0].to_mf6_pkg(**modellayers_single_layer) + assert df.index.names == [None] + assert df.index.name is None + assert "index" in df_reset.columns - # Assert - xr.testing.assert_equal(mf6_hfb_single.dataset, mf6_hfb_three.dataset) + df_roundtrip = df_reset.set_index("index") + assert df_roundtrip.index.names == ["index"] + assert df_roundtrip.index.name == "index" -def test_merge_mixed_hfbs__single_layer(modellayers_single_layer): - """Merge mix of layer hfb and depth hfb.""" - # Arrange - n_barriers = 3 - single_resistance = 400.0 - top = modellayers_single_layer["top"].values - bot = modellayers_single_layer["bottom"].values[0] +def test_prepare_index_names(): + # Case 1: Single index, unnamed + df = pd.DataFrame(data={"col1": [1, 2], "col2": [1, 2]}) + df_prepared = _prepare_index_names(df.copy()) - geometry = make_layer_geometry(single_resistance, 1) - geometry_depth = make_depth_geometry(single_resistance, top, bot) + assert df_prepared.index.names == ["index"] - hfb_ls_triple = [ - SingleLayerHorizontalFlowBarrierResistance(geometry), - HorizontalFlowBarrierResistance(geometry_depth), - HorizontalFlowBarrierResistance(geometry_depth), - ] + # Case 2: Single index, named + df_index_named = df.copy() + df_index_named.index = df.index.set_names(["index"]) + df_prepared = _prepare_index_names(df_index_named) - # Act - mf6_hfb = merge_hfb_packages(hfb_ls_triple, **modellayers_single_layer) + assert df_prepared.index.names == ["index"] - # Assert - assert mf6_hfb["cell_id"].shape == (6,) - assert (mf6_hfb["layer"] == 1).all() - expected_resistance = n_barriers * single_resistance - assert (expected_resistance == 1 / mf6_hfb["hydraulic_characteristic"]).all() + # Case 3: Multi index, unnamed + df_renamed = df.rename(columns={"col1": "parts"}) + df_multi_unnamed = df_renamed.set_index([df.index, "parts"]) + assert df_multi_unnamed.index.names == [None, "parts"] + df_prepared = _prepare_index_names(df_multi_unnamed) + assert df_prepared.index.names == ["index", "parts"] -def test_merge_three_hfbs__multiple_single_layers(modellayers): - """Merge three single layer hfbs at different layers""" - # Arrange - n_barriers = 3 - single_resistance = 400.0 + # Case 4: Multi index, named + df_renamed = df_index_named.rename(columns={"col1": "parts"}) + df_multi_unnamed = df_renamed.set_index([df_renamed.index, "parts"]) + assert df_multi_unnamed.index.names == ["index", "parts"] + df_prepared = _prepare_index_names(df_multi_unnamed) - hfb_ls = [ - SingleLayerHorizontalFlowBarrierResistance( - make_layer_geometry(single_resistance, i) - ) - for i in range(1, n_barriers + 1) - ] + assert df_prepared.index.names == ["index", "parts"] - # Act - mf6_hfb = merge_hfb_packages(hfb_ls, **modellayers) - - # Assert - assert mf6_hfb["cell_id"].shape == (18,) - assert np.all(np.unique(mf6_hfb["layer"]) == np.array([1, 2, 3])) - expected_resistance = single_resistance - assert (expected_resistance == 1 / mf6_hfb["hydraulic_characteristic"]).all() - - -def test_merge_mixed_hfbs__multiple_layer(modellayers): - """ - Merge three single layer hfbs at different layers plus one hfb spread across - the complete depth. - """ - # Arrange - n_barriers = 3 - single_resistance = 400.0 - - hfb_ls = [ - SingleLayerHorizontalFlowBarrierResistance( - make_layer_geometry(single_resistance, i) - ) - for i in range(1, n_barriers + 1) - ] - hfb_ls.append( - HorizontalFlowBarrierResistance( - make_depth_geometry(single_resistance, 10.0, -3.0) - ) - ) - - # Act - mf6_hfb = merge_hfb_packages(hfb_ls, **modellayers) - - # Assert - assert mf6_hfb["cell_id"].shape == (18,) - assert np.all(np.unique(mf6_hfb["layer"]) == np.array([1, 2, 3])) - expected_resistance = 2 * single_resistance - assert (expected_resistance == 1 / mf6_hfb["hydraulic_characteristic"]).all() + # Case 5: Wrong index name + df_index_wrongname = df.copy() + df_index_wrongname.index = df.index.set_names(["wrong_name"]) + with pytest.raises(IndexError): + _prepare_index_names(df_index_wrongname) diff --git a/imod/tests/test_mf6/test_utilities/test_mf6hfb.py b/imod/tests/test_mf6/test_utilities/test_mf6hfb.py new file mode 100644 index 000000000..59027ae9a --- /dev/null +++ b/imod/tests/test_mf6/test_utilities/test_mf6hfb.py @@ -0,0 +1,230 @@ +import geopandas as gpd +import numpy as np +import pytest +import shapely +import xarray as xr + +from imod.mf6.hfb import ( + HorizontalFlowBarrierResistance, + SingleLayerHorizontalFlowBarrierResistance, +) +from imod.mf6.utilities.mf6hfb import merge_hfb_packages +from imod.prepare.hfb import linestring_to_square_zpolygons + + +@pytest.mark.usefixtures("structured_flow_model") +@pytest.fixture(scope="function") +def modellayers_single_layer(structured_flow_model): + model = structured_flow_model.clip_box(layer_max=1) + dis = model["dis"] + dis["bottom"] = dis["bottom"].isel(x=0, y=0, drop=True) + npf = model["npf"] + + return { + "idomain": dis["idomain"], + "top": dis["top"], + "bottom": dis["bottom"], + "k": npf["k"], + } + + +@pytest.mark.usefixtures("structured_flow_model") +@pytest.fixture(scope="function") +def modellayers(structured_flow_model): + model = structured_flow_model + dis = model["dis"] + dis["bottom"] = dis["bottom"].isel(x=0, y=0, drop=True) + npf = model["npf"] + + return { + "idomain": dis["idomain"], + "top": dis["top"], + "bottom": dis["bottom"], + "k": npf["k"], + } + + +def make_layer_geometry(resistance, layer): + barrier_y = [11.0, 5.0, -1.0] + barrier_x = [5.0, 5.0, 5.0] + + geometry = gpd.GeoDataFrame( + geometry=[shapely.linestrings(barrier_x, barrier_y)], + data={ + "resistance": [resistance], + "layer": [layer], + }, + ) + return geometry + + +def make_depth_geometry(resistance, top, bot): + barrier_y = [11.0, 5.0, -1.0] + barrier_x = [5.0, 5.0, 5.0] + barrier_ztop = [top, top] + barrier_zbottom = [bot, bot] + + polygons = linestring_to_square_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbottom + ) + + geometry = gpd.GeoDataFrame( + geometry=polygons, + data={ + "resistance": [resistance, resistance], + }, + ) + return geometry + + +def test_merge_three_hfbs__single_layer(modellayers_single_layer): + """Merge three single layer hfbs, test for lenght""" + # Arrange + n_barriers = 3 + single_resistance = 400.0 + + geometry = make_layer_geometry(single_resistance, 1) + hfb_ls = [ + SingleLayerHorizontalFlowBarrierResistance(geometry) for _ in range(n_barriers) + ] + + # Act + mf6_hfb = merge_hfb_packages(hfb_ls, **modellayers_single_layer) + + # Assert + assert mf6_hfb["cell_id"].shape == (6,) + assert (mf6_hfb["layer"] == 1).all() + expected_resistance = n_barriers * single_resistance + assert (expected_resistance == 1 / mf6_hfb["hydraulic_characteristic"]).all() + + +def test_merge_three_hfbs__compare_single_hfb(modellayers_single_layer): + """ + Merge three single layer hfbs, compare with one hfb with tripled + resistance as created with a call to merge_hfb_packages. + """ + # Arrange + n_barriers = 3 + single_resistance = 400.0 + + geometry = make_layer_geometry(single_resistance, 1) + geometry_tripled = make_layer_geometry(n_barriers * single_resistance, 1) + + hfb_ls_triple = [ + SingleLayerHorizontalFlowBarrierResistance(geometry) for _ in range(n_barriers) + ] + hfb_ls_single = [SingleLayerHorizontalFlowBarrierResistance(geometry_tripled)] + + # Act + mf6_hfb_three = merge_hfb_packages(hfb_ls_triple, **modellayers_single_layer) + mf6_hfb_single = merge_hfb_packages(hfb_ls_single, **modellayers_single_layer) + + # Assert + xr.testing.assert_equal(mf6_hfb_single.dataset, mf6_hfb_three.dataset) + + +def test_merge_three_hfbs__to_mf6_pkg_single_layer(modellayers_single_layer): + """ + Merge three single layer hfbs, compare with one hfb with tripled + resistance as with a call to to_mf6_pkg. + """ + # Arrange + n_barriers = 3 + single_resistance = 400.0 + + geometry = make_layer_geometry(single_resistance, 1) + geometry_tripled = make_layer_geometry(n_barriers * single_resistance, 1) + + hfb_ls_triple = [ + SingleLayerHorizontalFlowBarrierResistance(geometry) for _ in range(n_barriers) + ] + hfb_ls_single = [SingleLayerHorizontalFlowBarrierResistance(geometry_tripled)] + + # Act + mf6_hfb_three = merge_hfb_packages(hfb_ls_triple, **modellayers_single_layer) + mf6_hfb_single = hfb_ls_single[0].to_mf6_pkg(**modellayers_single_layer) + + # Assert + xr.testing.assert_equal(mf6_hfb_single.dataset, mf6_hfb_three.dataset) + + +def test_merge_mixed_hfbs__single_layer(modellayers_single_layer): + """Merge mix of layer hfb and depth hfb.""" + # Arrange + n_barriers = 3 + single_resistance = 400.0 + + top = float(modellayers_single_layer["top"].values) + bot = modellayers_single_layer["bottom"].values[0] + + geometry = make_layer_geometry(single_resistance, 1) + geometry_depth = make_depth_geometry(single_resistance, top, bot) + + hfb_ls_triple = [ + SingleLayerHorizontalFlowBarrierResistance(geometry), + HorizontalFlowBarrierResistance(geometry_depth), + HorizontalFlowBarrierResistance(geometry_depth), + ] + + # Act + mf6_hfb = merge_hfb_packages(hfb_ls_triple, **modellayers_single_layer) + + # Assert + assert mf6_hfb["cell_id"].shape == (6,) + assert (mf6_hfb["layer"] == 1).all() + expected_resistance = n_barriers * single_resistance + assert (expected_resistance == 1 / mf6_hfb["hydraulic_characteristic"]).all() + + +def test_merge_three_hfbs__multiple_single_layers(modellayers): + """Merge three single layer hfbs at different layers""" + # Arrange + n_barriers = 3 + single_resistance = 400.0 + + hfb_ls = [ + SingleLayerHorizontalFlowBarrierResistance( + make_layer_geometry(single_resistance, i) + ) + for i in range(1, n_barriers + 1) + ] + + # Act + mf6_hfb = merge_hfb_packages(hfb_ls, **modellayers) + + # Assert + assert mf6_hfb["cell_id"].shape == (18,) + assert np.all(np.unique(mf6_hfb["layer"]) == np.array([1, 2, 3])) + expected_resistance = single_resistance + assert (expected_resistance == 1 / mf6_hfb["hydraulic_characteristic"]).all() + + +def test_merge_mixed_hfbs__multiple_layer(modellayers): + """ + Merge three single layer hfbs at different layers plus one hfb spread across + the complete depth. + """ + # Arrange + n_barriers = 3 + single_resistance = 400.0 + + hfb_ls = [ + SingleLayerHorizontalFlowBarrierResistance( + make_layer_geometry(single_resistance, i) + ) + for i in range(1, n_barriers + 1) + ] + hfb_ls.append( + HorizontalFlowBarrierResistance( + make_depth_geometry(single_resistance, 10.0, -3.0) + ) + ) + + # Act + mf6_hfb = merge_hfb_packages(hfb_ls, **modellayers) + + # Assert + assert mf6_hfb["cell_id"].shape == (18,) + assert np.all(np.unique(mf6_hfb["layer"]) == np.array([1, 2, 3])) + expected_resistance = 2 * single_resistance + assert (expected_resistance == 1 / mf6_hfb["hydraulic_characteristic"]).all() diff --git a/imod/tests/test_prepare/test_prepare_hfb.py b/imod/tests/test_prepare/test_prepare_hfb.py new file mode 100644 index 000000000..a8e7a908d --- /dev/null +++ b/imod/tests/test_prepare/test_prepare_hfb.py @@ -0,0 +1,106 @@ +import numpy as np +import pytest +import shapely + +from imod.prepare.hfb import ( + linestring_to_square_zpolygons, + linestring_to_trapezoid_zpolygons, +) + + +def test_linestring_to_square_zpolygons(): + barrier_x = [-10.0, 0.0, 10.0] + barrier_y = [10.0, 0.0, -10.0] + barrier_ztop = [10.0, 20.0] + barrier_zbot = [-10.0, -20.0] + + polygons = linestring_to_square_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbot + ) + + assert len(polygons) == 2 + + coordinates_0 = shapely.get_coordinates(polygons[0], include_z=True) + expected_0 = np.array( + [ + [-10.0, 10.0, 10.0], + [-10.0, 10.0, -10.0], + [0.0, 0.0, -10.0], + [0.0, 0.0, 10.0], + [-10.0, 10.0, 10.0], + ] + ) + + coordinates_1 = shapely.get_coordinates(polygons[1], include_z=True) + expected_1 = np.array( + [ + [0.0, 0.0, 20.0], + [0.0, 0.0, -20.0], + [10.0, -10.0, -20.0], + [10.0, -10.0, 20.0], + [0.0, 0.0, 20.0], + ] + ) + + np.testing.assert_equal(coordinates_0, expected_0) + np.testing.assert_equal(coordinates_1, expected_1) + + +def test_linestring_to_trapezoid_zpolygons(): + barrier_x = [-10.0, 0.0, 10.0] + barrier_y = [10.0, 0.0, -10.0] + barrier_ztop = [10.0, 20.0, 15.0] + barrier_zbot = [-10.0, -20.0, 0.0] + + polygons = linestring_to_trapezoid_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbot + ) + + assert len(polygons) == 2 + + coordinates_0 = shapely.get_coordinates(polygons[0], include_z=True) + expected_0 = np.array( + [ + [-10.0, 10.0, 10.0], + [-10.0, 10.0, -20.0], + [0.0, 0.0, 20.0], + [0.0, 0.0, -10.0], + [-10.0, 10.0, 10.0], + ] + ) + + coordinates_1 = shapely.get_coordinates(polygons[1], include_z=True) + expected_1 = np.array( + [ + [0.0, 0.0, 20.0], + [0.0, 0.0, 0.0], + [10.0, -10.0, 15.0], + [10.0, -10.0, -20.0], + [0.0, 0.0, 20.0], + ] + ) + + np.testing.assert_equal(coordinates_0, expected_0) + np.testing.assert_equal(coordinates_1, expected_1) + + +def test_linestring_to_trapezoid_zpolygons__fails(): + barrier_x = [-10.0, 0.0, 10.0] + barrier_y = [10.0, 0.0, -10.0] + barrier_ztop = [10.0, 20.0] + barrier_zbot = [-10.0, -20.0] + + with pytest.raises(ValueError): + linestring_to_trapezoid_zpolygons( + barrier_x, barrier_y, barrier_ztop, barrier_zbot + ) + + +def test_linestring_to_square_zpolygons__fails(): + barrier_x = [-10.0, 0.0, 10.0] + barrier_y = [10.0, 0.0, -10.0] + barrier_ztop = [10.0, 20.0, 15.0] + barrier_zbot = [-10.0, -20.0, 0.0] + + with pytest.raises(ValueError): + linestring_to_square_zpolygons(barrier_x, barrier_y, barrier_ztop, barrier_zbot) diff --git a/imod/typing/__init__.py b/imod/typing/__init__.py index b67837e43..a5ca2f69e 100644 --- a/imod/typing/__init__.py +++ b/imod/typing/__init__.py @@ -2,7 +2,7 @@ Module to define type aliases. """ -from typing import TypeAlias, Union +from typing import TYPE_CHECKING, TypeAlias, TypeVar, Union import numpy as np import xarray as xr @@ -15,3 +15,19 @@ UnstructuredData: TypeAlias = Union[xu.UgridDataset, xu.UgridDataArray] FloatArray: TypeAlias = np.ndarray IntArray: TypeAlias = np.ndarray + + +# Types for optional dependencies. +if TYPE_CHECKING: + import geopandas as gpd + import shapely + + GeoDataFrameType: TypeAlias = gpd.GeoDataFrame + GeoSeriesType: TypeAlias = gpd.GeoSeries + PolygonType: TypeAlias = shapely.Polygon + LineStringType: TypeAlias = shapely.LineString +else: + GeoDataFrameType = TypeVar("GeoDataFrameType") + GeoSeriesType = TypeVar("GeoSeriesType") + PolygonType = TypeVar("PolygonType") + LineStringType = TypeVar("LineStringType") diff --git a/imod/typing/grid.py b/imod/typing/grid.py index 90d892d04..9daa867d7 100644 --- a/imod/typing/grid.py +++ b/imod/typing/grid.py @@ -8,7 +8,7 @@ import xugrid as xu from fastcore.dispatch import typedispatch -from imod.typing import GridDataArray, GridDataset, structured +from imod.typing import GeoDataFrameType, GridDataArray, GridDataset, structured from imod.util.spatial import _polygonize T = TypeVar("T") @@ -237,7 +237,7 @@ def merge_with_dictionary( @typedispatch -def bounding_polygon(active: xr.DataArray): +def bounding_polygon(active: xr.DataArray) -> GeoDataFrameType: """Return bounding polygon of active cells""" to_polygonize = active.where(active, other=np.nan) polygons_gdf = _polygonize(to_polygonize) @@ -247,7 +247,7 @@ def bounding_polygon(active: xr.DataArray): @typedispatch # type: ignore[no-redef] -def bounding_polygon(active: xu.UgridDataArray): # noqa: F811 +def bounding_polygon(active: xu.UgridDataArray) -> GeoDataFrameType: # noqa: F811 """Return bounding polygon of active cells""" active_indices = np.where(active > 0)[0] domain_slice = {f"{active.ugrid.grid.face_dimension}": active_indices} From 0f8a58cc70763856908968ca80bd999e410a7187 Mon Sep 17 00:00:00 2001 From: luitjansl <64598682+luitjansl@users.noreply.github.com> Date: Fri, 26 Jul 2024 10:06:38 +0200 Subject: [PATCH 31/53] Issue #1092 merge chd (#1118) Fixes #1092 # Description On import, chd packages that were split over layers are merged into a single chd package if the names of these packages are "chd-x" where x is a layer number. A function for this was added to mf6/utilities and not in the chd package to keep it hidden from users. # Checklist - [X] Links to correct issue - [ ] Update changelog, if changes affect users - [X] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [X] Unit tests were added - [ ] **If feature added**: Added/extended example --------- Co-authored-by: Joeri van Engelen --- imod/mf6/model_gwf.py | 11 ++++++- imod/mf6/utilities/chd_concat.py | 48 +++++++++++++++++++++++++++++ imod/tests/test_mf6/test_mf6_chd.py | 47 ++++++++++++++++++++++++++++ 3 files changed, 105 insertions(+), 1 deletion(-) create mode 100644 imod/mf6/utilities/chd_concat.py diff --git a/imod/mf6/model_gwf.py b/imod/mf6/model_gwf.py index b479827cf..5237d9b10 100644 --- a/imod/mf6/model_gwf.py +++ b/imod/mf6/model_gwf.py @@ -30,6 +30,7 @@ ) from imod.mf6.riv import River from imod.mf6.sto import StorageCoefficient +from imod.mf6.utilities.chd_concat import concat_layered_chd_packages from imod.mf6.utilities.regrid import RegridderWeightsCache from imod.mf6.wel import Well from imod.prepare.topsystem.default_allocation_methods import ( @@ -344,13 +345,21 @@ def from_imod5_data( regrid_cache, ) else: + chd_packages = {} for chd_key in chd_keys: - result[chd_key] = ConstantHead.from_imod5_data( + chd_packages[chd_key] = ConstantHead.from_imod5_data( chd_key, imod5_data, dis_pkg, cast(ConstantHeadRegridMethod, regridder_types.get(chd_key)), regrid_cache, ) + merged_chd = concat_layered_chd_packages( + "chd", chd_packages, remove_merged_packages=True + ) + if merged_chd is not None: + result["chd_merged"] = merged_chd + for key, chd_package in chd_packages.items(): + result[key] = chd_package return result diff --git a/imod/mf6/utilities/chd_concat.py b/imod/mf6/utilities/chd_concat.py new file mode 100644 index 000000000..8aae8ab40 --- /dev/null +++ b/imod/mf6/utilities/chd_concat.py @@ -0,0 +1,48 @@ +from typing import Optional + +import xarray as xr + +from imod.mf6.chd import ConstantHead + + +def concat_layered_chd_packages( + name: str, + dict_packages: dict[str, ConstantHead], + remove_merged_packages: bool = True, +) -> Optional[ConstantHead]: + """ + + Parameters + ---------- + name: str + The name of the package that was split over layers. + If they are called "chd-1" and so on then set name to "chd" + dict_packages: dict[str, ConstantHead] + dictionary with package names as key and the packages as values + remove_merged_packages: bool = True + set to True to remove merged packages from dict_packages + + This function merges chd-packages whose name starts with "name" into a a + single chd package. This is aimed at chd packages that are split over + layers- so we would have chd-1, chd-2 and so on and these packages would + define a chd package for layer 1, 2 and so on. This function merges them + into a single chd package. If remove_merged_packages is True, then the + packages that are concatenated are removed from the input dictionary, so + that this on output only contains the packages that were not merged. + """ + + candidate_keys = [k for k in dict_packages.keys() if name in k[0 : len(name)]] + if len(candidate_keys) == 0: + return None + + dataset_list = [] + for key in candidate_keys: + pack = dict_packages[key] + dataset_list.append(pack.dataset) + if remove_merged_packages: + dict_packages.pop(key) + + concat_dataset = xr.concat( + dataset_list, dim="layer", compat="equals", data_vars="different" + ) + return ConstantHead._from_dataset(concat_dataset) diff --git a/imod/tests/test_mf6/test_mf6_chd.py b/imod/tests/test_mf6/test_mf6_chd.py index 54ca67ceb..ef0a04108 100644 --- a/imod/tests/test_mf6/test_mf6_chd.py +++ b/imod/tests/test_mf6/test_mf6_chd.py @@ -7,7 +7,9 @@ import xarray as xr import imod +from imod.mf6.chd import ConstantHead from imod.mf6.dis import StructuredDiscretization +from imod.mf6.utilities.chd_concat import concat_layered_chd_packages from imod.mf6.write_context import WriteContext from imod.schemata import ValidationError @@ -234,3 +236,48 @@ def test_from_imod5_shd(imod5_dataset, tmp_path): # write the packages for write validation write_context = WriteContext(simulation_directory=tmp_path, use_binary=False) chd_shd.write("chd_shd", [1], write_context) + + +@pytest.mark.parametrize("remove_merged_packages", [True, False]) +@pytest.mark.usefixtures("imod5_dataset") +def test_concatenate_chd(imod5_dataset, tmp_path, remove_merged_packages): + # Arrange + imod5_data = imod5_dataset[0] + + target_dis = StructuredDiscretization.from_imod5_data(imod5_data) + chd_packages = {} + + # import a few chd packages per layer + for layer in range(1, 7): + key = f"chd-{layer}" + chd_packages[key] = imod.mf6.ConstantHead.from_imod5_data( + key, + imod5_data, + target_dis, + ) + + # import a few chd packages per layer but store them under another key + for layer in range(8, 16): + key = f"chd-{layer}" + other_key = f"other_chd-{layer}" + chd_packages[other_key] = imod.mf6.ConstantHead.from_imod5_data( + key, + imod5_data, + target_dis, + ) + + # Act + merged_package = concat_layered_chd_packages( + "chd", chd_packages, remove_merged_packages + ) + + # Assert + assert isinstance(merged_package, ConstantHead) + assert len(merged_package["layer"]) == 6 + if remove_merged_packages: + assert len(chd_packages) == 8 + else: + assert len(chd_packages) == 14 + # write the packages for write validation + write_context = WriteContext(simulation_directory=tmp_path, use_binary=False) + merged_package.write("merged_chd", [1], write_context) From 506020d34afaa8ec0a861c892e735dc333954ebd Mon Sep 17 00:00:00 2001 From: luitjansl <64598682+luitjansl@users.noreply.github.com> Date: Fri, 26 Jul 2024 15:03:55 +0200 Subject: [PATCH 32/53] Issue #1045 ghb allocation (#1119) Fixes #1045 # Description Enables using allocation options when importing a ghb from imod5 and it is planar (layer=0) # Checklist - [X] Links to correct issue - [ ] Update changelog, if changes affect users - [X] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [X] Unit tests were added - [ ] **If feature added**: Added/extended example --------- Co-authored-by: Joeri van Engelen --- imod/mf6/chd.py | 3 ++ imod/mf6/dis.py | 3 ++ imod/mf6/drn.py | 3 ++ imod/mf6/ghb.py | 53 +++++++++++++++++-- imod/mf6/ic.py | 3 ++ imod/mf6/model_gwf.py | 23 ++++++++ imod/mf6/npf.py | 3 ++ imod/mf6/rch.py | 3 ++ imod/mf6/riv.py | 3 ++ imod/mf6/sto.py | 3 ++ .../topsystem/default_allocation_methods.py | 2 + .../test_mf6/test_mf6_generalheadboundary.py | 43 ++++++++++++++- 12 files changed, 140 insertions(+), 5 deletions(-) diff --git a/imod/mf6/chd.py b/imod/mf6/chd.py index f3bf69ca5..c171a558b 100644 --- a/imod/mf6/chd.py +++ b/imod/mf6/chd.py @@ -236,6 +236,9 @@ def from_imod5_shd_data( regridder_types: ConstantHeadRegridMethod, optional Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. + regrid_cache:Optional RegridderWeightsCache + stores regridder weights for different regridders. Can be used to speed up regridding, + if the same regridders are used several times for regridding different arrays. Returns ------- diff --git a/imod/mf6/dis.py b/imod/mf6/dis.py index f69f0b329..aca17c137 100644 --- a/imod/mf6/dis.py +++ b/imod/mf6/dis.py @@ -186,6 +186,9 @@ def from_imod5_data( regridder_types: DiscretizationRegridMethod, optional Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. + regrid_cache:Optional RegridderWeightsCache + stores regridder weights for different regridders. Can be used to speed up regridding, + if the same regridders are used several times for regridding different arrays. Returns ------- diff --git a/imod/mf6/drn.py b/imod/mf6/drn.py index 3ea05f755..aef93f278 100644 --- a/imod/mf6/drn.py +++ b/imod/mf6/drn.py @@ -210,6 +210,9 @@ def from_imod5_data( regridder_types: DrainageRegridMethod, optional Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. + regrid_cache:Optional RegridderWeightsCache + stores regridder weights for different regridders. Can be used to speed up regridding, + if the same regridders are used several times for regridding different arrays. Returns ------- diff --git a/imod/mf6/ghb.py b/imod/mf6/ghb.py index 812523eb4..287627fe5 100644 --- a/imod/mf6/ghb.py +++ b/imod/mf6/ghb.py @@ -7,12 +7,18 @@ from imod.logging import init_log_decorator from imod.mf6.boundary_condition import BoundaryCondition from imod.mf6.interfaces.iregridpackage import IRegridPackage +from imod.mf6.npf import NodePropertyFlow from imod.mf6.regrid.regrid_schemes import ( GeneralHeadBoundaryRegridMethod, RegridMethodType, ) from imod.mf6.utilities.regrid import RegridderWeightsCache, _regrid_package_data from imod.mf6.validation import BOUNDARY_DIMS_SCHEMA, CONC_DIMS_SCHEMA +from imod.prepare.topsystem.allocation import ALLOCATION_OPTION, allocate_ghb_cells +from imod.prepare.topsystem.conductance import ( + DISTRIBUTING_OPTION, + distribute_ghb_conductance, +) from imod.schemata import ( AllInsideNoDataSchema, AllNoDataSchema, @@ -25,6 +31,7 @@ OtherCoordsSchema, ) from imod.typing import GridDataArray +from imod.typing.grid import enforce_dim_order, is_planar_grid from imod.util.expand_repetitions import expand_repetitions @@ -165,8 +172,11 @@ def from_imod5_data( imod5_data: dict[str, dict[str, GridDataArray]], period_data: dict[str, list[datetime]], target_discretization, + target_npf: NodePropertyFlow, time_min: datetime, time_max: datetime, + allocation_option: ALLOCATION_OPTION, + distributing_option: DISTRIBUTING_OPTION, regrid_cache: RegridderWeightsCache = RegridderWeightsCache(), regridder_types: Optional[RegridMethodType] = None, ) -> "GeneralHeadBoundary": @@ -190,15 +200,18 @@ def from_imod5_data( The grid that should be used for the new package. Does not need to be identical to one of the input grids. target_npf: NodePropertyFlow package - The conductivity information, used to compute drainage flux + The conductivity information, used to compute GHB flux allocation_option: ALLOCATION_OPTION allocation option. - distributing_option: dict[str, DISTRIBUTING_OPTION] - distributing option. time_min: datetime Begin-time of the simulation. Used for expanding period data. time_max: datetime End-time of the simulation. Used for expanding period data. + distributing_option: dict[str, DISTRIBUTING_OPTION] + distributing option. + regrid_cache:Optional RegridderWeightsCache + stores regridder weights for different regridders. Can be used to speed up regridding, + if the same regridders are used several times for regridding different arrays. regridder_types: RegridMethodType, optional Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. @@ -207,12 +220,16 @@ def from_imod5_data( ------- A Modflow 6 GeneralHeadBoundary packages. """ + target_top = target_discretization.dataset["top"] + target_bottom = target_discretization.dataset["bottom"] + target_idomain = target_discretization.dataset["idomain"] idomain = target_discretization.dataset["idomain"] data = { "head": imod5_data[key]["head"], "conductance": imod5_data[key]["conductance"], } + is_planar = is_planar_grid(data["conductance"]) if regridder_types is None: regridder_types = GeneralHeadBoundaryRegridMethod() @@ -220,6 +237,36 @@ def from_imod5_data( regridded_package_data = _regrid_package_data( data, idomain, regridder_types, regrid_cache, {} ) + if is_planar: + conductance = regridded_package_data["conductance"] + + planar_head = regridded_package_data["head"] + k = target_npf.dataset["k"] + + ghb_allocation = allocate_ghb_cells( + allocation_option, + target_idomain == 1, + target_top, + target_bottom, + planar_head, + ) + + layered_head = planar_head.where(ghb_allocation) + layered_head = enforce_dim_order(layered_head) + + regridded_package_data["head"] = layered_head + + if "layer" in conductance.coords: + conductance = conductance.isel({"layer": 0}, drop=True) + + regridded_package_data["conductance"] = distribute_ghb_conductance( + distributing_option, + ghb_allocation, + conductance, + target_top, + target_bottom, + k, + ) ghb = GeneralHeadBoundary(**regridded_package_data, validate=True) repeat = period_data.get(key) diff --git a/imod/mf6/ic.py b/imod/mf6/ic.py index cc5b13dba..017463c95 100644 --- a/imod/mf6/ic.py +++ b/imod/mf6/ic.py @@ -122,6 +122,9 @@ def from_imod5_data( regridder_types: InitialConditionsRegridMethod, optional Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. + regrid_cache:Optional RegridderWeightsCache + stores regridder weights for different regridders. Can be used to speed up regridding, + if the same regridders are used several times for regridding different arrays. Returns ------- diff --git a/imod/mf6/model_gwf.py b/imod/mf6/model_gwf.py index 5237d9b10..556e1351f 100644 --- a/imod/mf6/model_gwf.py +++ b/imod/mf6/model_gwf.py @@ -12,6 +12,7 @@ from imod.mf6.clipped_boundary_condition_creator import create_clipped_boundary from imod.mf6.dis import StructuredDiscretization from imod.mf6.drn import Drainage +from imod.mf6.ghb import GeneralHeadBoundary from imod.mf6.hfb import SingleLayerHorizontalFlowBarrierResistance from imod.mf6.ic import InitialConditions from imod.mf6.model import Modflow6Model @@ -21,6 +22,7 @@ ConstantHeadRegridMethod, DiscretizationRegridMethod, DrainageRegridMethod, + GeneralHeadBoundaryRegridMethod, InitialConditionsRegridMethod, NodePropertyFlowRegridMethod, RechargeRegridMethod, @@ -278,12 +280,33 @@ def from_imod5_data( # now import the non-singleton packages' + # import wells # import wells imod5_keys = list(imod5_data.keys()) wel_keys = [key for key in imod5_keys if key[0:3] == "wel"] for wel_key in wel_keys: result[wel_key] = Well.from_imod5_data(wel_key, imod5_data, times) + imod5_keys = list(imod5_data.keys()) + ghb_keys = [key for key in imod5_keys if key[0:3] == "ghb"] + for ghb_key in ghb_keys: + ghb_pkg = GeneralHeadBoundary.from_imod5_data( + ghb_key, + imod5_data, + period_data, + dis_pkg, + npf_pkg, + times[0], + times[-1], + allocation_options.ghb, + distributing_options.ghb, + regridder_types=cast( + GeneralHeadBoundaryRegridMethod, regridder_types.get(ghb_key) + ), + regrid_cache=regrid_cache, + ) + result[ghb_key] = ghb_pkg + # import drainage drainage_keys = [key for key in imod5_keys if key[0:3] == "drn"] diff --git a/imod/mf6/npf.py b/imod/mf6/npf.py index 50c27c10f..102518ee3 100644 --- a/imod/mf6/npf.py +++ b/imod/mf6/npf.py @@ -480,6 +480,9 @@ def from_imod5_data( regridder_types: RegridMethodType, optional Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. + regrid_cache:Optional RegridderWeightsCache + stores regridder weights for different regridders. Can be used to speed up regridding, + if the same regridders are used several times for regridding different arrays. Returns ------- diff --git a/imod/mf6/rch.py b/imod/mf6/rch.py index 59524b9f3..9568ecddd 100644 --- a/imod/mf6/rch.py +++ b/imod/mf6/rch.py @@ -182,6 +182,9 @@ def from_imod5_data( regridder_types: RechargeRegridMethod, optional Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. + regrid_cache:Optional RegridderWeightsCache + stores regridder weights for different regridders. Can be used to speed up regridding, + if the same regridders are used several times for regridding different arrays. Returns ------- diff --git a/imod/mf6/riv.py b/imod/mf6/riv.py index eb46339f2..19c4d35b4 100644 --- a/imod/mf6/riv.py +++ b/imod/mf6/riv.py @@ -231,6 +231,9 @@ def from_imod5_data( regridder_types: RiverRegridMethod, optional Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. + regrid_cache:Optional RegridderWeightsCache + stores regridder weights for different regridders. Can be used to speed up regridding, + if the same regridders are used several times for regridding different arrays. Returns ------- diff --git a/imod/mf6/sto.py b/imod/mf6/sto.py index 8ac9ff3e5..b39e805ad 100644 --- a/imod/mf6/sto.py +++ b/imod/mf6/sto.py @@ -352,6 +352,9 @@ def from_imod5_data( regridder_types: StorageCoefficientRegridMethod, optional Optional dataclass with regridder types for a specific variable. Use this to override default regridding methods. + regrid_cache:Optional RegridderWeightsCache + stores regridder weights for different regridders. Can be used to speed up regridding, + if the same regridders are used several times for regridding different arrays. Returns ------- diff --git a/imod/prepare/topsystem/default_allocation_methods.py b/imod/prepare/topsystem/default_allocation_methods.py index 770e96b22..5d7f61b3c 100644 --- a/imod/prepare/topsystem/default_allocation_methods.py +++ b/imod/prepare/topsystem/default_allocation_methods.py @@ -20,6 +20,7 @@ class SimulationAllocationOptions: drn: ALLOCATION_OPTION = ALLOCATION_OPTION.first_active_to_elevation riv: ALLOCATION_OPTION = ALLOCATION_OPTION.stage_to_riv_bot + ghb: ALLOCATION_OPTION = ALLOCATION_OPTION.at_elevation @dataclass() @@ -38,3 +39,4 @@ class SimulationDistributingOptions: drn: DISTRIBUTING_OPTION = DISTRIBUTING_OPTION.by_corrected_transmissivity riv: DISTRIBUTING_OPTION = DISTRIBUTING_OPTION.by_corrected_transmissivity + ghb: DISTRIBUTING_OPTION = DISTRIBUTING_OPTION.by_corrected_transmissivity diff --git a/imod/tests/test_mf6/test_mf6_generalheadboundary.py b/imod/tests/test_mf6/test_mf6_generalheadboundary.py index 665d7c600..bd9ca4648 100644 --- a/imod/tests/test_mf6/test_mf6_generalheadboundary.py +++ b/imod/tests/test_mf6/test_mf6_generalheadboundary.py @@ -2,22 +2,61 @@ import imod from imod.mf6.dis import StructuredDiscretization +from imod.mf6.npf import NodePropertyFlow from imod.mf6.write_context import WriteContext +from imod.prepare.topsystem.allocation import ALLOCATION_OPTION +from imod.prepare.topsystem.conductance import DISTRIBUTING_OPTION -def test_from_imod5(imod5_dataset_periods, tmp_path): +def test_from_imod5_non_planar(imod5_dataset_periods, tmp_path): period_data = imod5_dataset_periods[1] imod5_dataset = imod5_dataset_periods[0] target_dis = StructuredDiscretization.from_imod5_data(imod5_dataset, validate=False) + target_npf = NodePropertyFlow.from_imod5_data( + imod5_dataset, target_dis.dataset["idomain"] + ) + + ghb = imod.mf6.GeneralHeadBoundary.from_imod5_data( + "ghb", + imod5_dataset, + period_data, + target_dis, + target_npf, + time_min=datetime(2002, 2, 2), + time_max=datetime(2022, 2, 2), + allocation_option=ALLOCATION_OPTION.at_elevation, + distributing_option=DISTRIBUTING_OPTION.by_crosscut_thickness, + ) + + assert isinstance(ghb, imod.mf6.GeneralHeadBoundary) + + # write the packages for write validation + write_context = WriteContext(simulation_directory=tmp_path, use_binary=False) + ghb.write("ghb", [1], write_context) + + +def test_from_imod5_planar(imod5_dataset_periods, tmp_path): + period_data = imod5_dataset_periods[1] + imod5_dataset = imod5_dataset_periods[0] + target_dis = StructuredDiscretization.from_imod5_data(imod5_dataset, validate=False) + target_npf = NodePropertyFlow.from_imod5_data( + imod5_dataset, target_dis.dataset["idomain"] + ) + imod5_dataset["ghb"]["conductance"] = imod5_dataset["ghb"][ + "conductance" + ].assign_coords({"layer": [0]}) + imod5_dataset["ghb"]["head"] = imod5_dataset["ghb"]["head"].isel({"layer": 0}) ghb = imod.mf6.GeneralHeadBoundary.from_imod5_data( "ghb", imod5_dataset, period_data, target_dis, + target_npf, time_min=datetime(2002, 2, 2), time_max=datetime(2022, 2, 2), - regridder_types=None, + allocation_option=ALLOCATION_OPTION.at_elevation, + distributing_option=DISTRIBUTING_OPTION.by_layer_thickness, ) assert isinstance(ghb, imod.mf6.GeneralHeadBoundary) From 820e92f1308d2231ca1f9f0dd04243696ceec73f Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Mon, 29 Jul 2024 18:15:27 +0200 Subject: [PATCH 33/53] Issue #1122 layered well from imod5 data (#1123) Fixes #1122, should be merged after https://github.com/Deltares/imod-python/pull/1121 (so duplication in changeset) # Description Adds ``from_imod5_data`` method to ``LayeredWell`` object. # Checklist - [x] Links to correct issue - [x] Update changelog, if changes affect users - [x] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [x] Unit tests were added - [x] **If feature added**: Added/extended example --- docs/api/changelog.rst | 2 + imod/mf6/__init__.py | 2 +- imod/mf6/model.py | 3 +- imod/mf6/model_gwf.py | 10 +- imod/mf6/wel.py | 853 ++++++++++++++------- imod/tests/test_mf6/test_mf6_simulation.py | 33 +- imod/tests/test_mf6/test_mf6_wel.py | 347 +++++---- 7 files changed, 822 insertions(+), 428 deletions(-) diff --git a/docs/api/changelog.rst b/docs/api/changelog.rst index 852a80f42..8bdd35b79 100644 --- a/docs/api/changelog.rst +++ b/docs/api/changelog.rst @@ -40,6 +40,8 @@ Added :class:`imod.mf6.HorizontalFlowBarrierResistance`, :class:`imod.mf6.HorizontalFlowBarrierMultiplier`, :class:`imod.mf6.HorizontalFlowBarrierHydraulicCharacteristic`. +- :class:`imod.mf6.LayeredWell` to specify wells directly to layers instead + assigning them with filter depths. [Unreleased] diff --git a/imod/mf6/__init__.py b/imod/mf6/__init__.py index d6225b065..652602432 100644 --- a/imod/mf6/__init__.py +++ b/imod/mf6/__init__.py @@ -49,5 +49,5 @@ from imod.mf6.timedis import TimeDiscretization from imod.mf6.utilities.regrid import RegridderType, RegridderWeightsCache from imod.mf6.uzf import UnsaturatedZoneFlow -from imod.mf6.wel import Well, WellDisStructured, WellDisVertices +from imod.mf6.wel import LayeredWell, Well, WellDisStructured, WellDisVertices from imod.mf6.write_context import WriteContext diff --git a/imod/mf6/model.py b/imod/mf6/model.py index 031c7623d..a30b6291b 100644 --- a/imod/mf6/model.py +++ b/imod/mf6/model.py @@ -27,6 +27,7 @@ from imod.mf6.utilities.mf6hfb import merge_hfb_packages from imod.mf6.utilities.regrid import RegridderWeightsCache, _regrid_like from imod.mf6.validation import pkg_errors_to_status_info +from imod.mf6.wel import GridAgnosticWell from imod.mf6.write_context import WriteContext from imod.schemata import ValidationError from imod.typing import GridDataArray @@ -267,7 +268,7 @@ def write( mf6_hfb_ls: List[HorizontalFlowBarrierBase] = [] for pkg_name, pkg in self.items(): try: - if isinstance(pkg, imod.mf6.Well): + if isinstance(pkg, GridAgnosticWell): top, bottom, idomain = self.__get_domain_geometry() k = self.__get_k() mf6_well_pkg = pkg.to_mf6_pkg( diff --git a/imod/mf6/model_gwf.py b/imod/mf6/model_gwf.py index 556e1351f..456385ce5 100644 --- a/imod/mf6/model_gwf.py +++ b/imod/mf6/model_gwf.py @@ -34,7 +34,7 @@ from imod.mf6.sto import StorageCoefficient from imod.mf6.utilities.chd_concat import concat_layered_chd_packages from imod.mf6.utilities.regrid import RegridderWeightsCache -from imod.mf6.wel import Well +from imod.mf6.wel import LayeredWell, Well from imod.prepare.topsystem.default_allocation_methods import ( SimulationAllocationOptions, SimulationDistributingOptions, @@ -285,7 +285,13 @@ def from_imod5_data( imod5_keys = list(imod5_data.keys()) wel_keys = [key for key in imod5_keys if key[0:3] == "wel"] for wel_key in wel_keys: - result[wel_key] = Well.from_imod5_data(wel_key, imod5_data, times) + layer = imod5_data[wel_key]["layer"] + if layer == 0: + result[wel_key] = Well.from_imod5_data(wel_key, imod5_data, times) + else: + result[wel_key] = LayeredWell.from_imod5_data( + wel_key, imod5_data, times + ) imod5_keys = list(imod5_data.keys()) ghb_keys = [key for key in imod5_keys if key[0:3] == "ghb"] diff --git a/imod/mf6/wel.py b/imod/mf6/wel.py index cc7cdb67f..4505c417c 100644 --- a/imod/mf6/wel.py +++ b/imod/mf6/wel.py @@ -1,5 +1,6 @@ from __future__ import annotations +import abc import textwrap import warnings from datetime import datetime @@ -60,7 +61,7 @@ def _assign_dims(arg: Any) -> Tuple | xr.DataArray: return "index", arg -def mask_2D(package: Well, domain_2d: GridDataArray) -> Well: +def mask_2D(package: GridAgnosticWell, domain_2d: GridDataArray) -> GridAgnosticWell: point_active = points_values(domain_2d, x=package.x, y=package.y) is_inside_exterior = point_active == 1 @@ -70,7 +71,307 @@ def mask_2D(package: Well, domain_2d: GridDataArray) -> Well: return cls._from_dataset(selection) -class Well(BoundaryCondition, IPointDataPackage): +def _prepare_well_rates_from_groups( + unique_well_groups: pd.api.typing.DataFrameGroupBy, times: list[datetime] +) -> xr.DataArray: + """ + Prepare well rates from dataframe groups, grouped by unique well locations. + """ + # Resample times per group + df_resampled_groups = [ + resample_timeseries(df_group, times) for df_group in unique_well_groups + ] + # Convert dataframes all groups to DataArrays + da_groups = [ + xr.DataArray(df_group["rate"], dims=("time"), coords={"time": df_group["time"]}) + for df_group in df_resampled_groups + ] + # Assign index coordinates + da_groups = [ + da_group.expand_dims(dim="index").assign_coords(index=[i]) + for i, da_group in enumerate(da_groups) + ] + # Concatenate datarrays along index dimension + return xr.concat(da_groups, dim="index") + + +class GridAgnosticWell(BoundaryCondition, IPointDataPackage, abc.ABC): + """ + Abstract base class for grid agnostic wells + """ + + @property + def x(self) -> npt.NDArray[np.float64]: + return self.dataset["x"].values + + @property + def y(self) -> npt.NDArray[np.float64]: + return self.dataset["y"].values + + @classmethod + def is_grid_agnostic_package(cls) -> bool: + return True + + def _create_cellid(self, wells_assigned: pd.DataFrame, active: xr.DataArray): + like = ones_like(active) + + # Groupby index and select first, to unset any duplicate records + # introduced by the multi-indexed "time" dimension. + df_for_cellid = wells_assigned.groupby("index").first() + d_for_cellid = df_for_cellid[["x", "y", "layer"]].to_dict("list") + + return self._derive_cellid_from_points(like, **d_for_cellid) + + def _create_dataset_vars( + self, wells_assigned: pd.DataFrame, wells_df: pd.DataFrame, cellid: xr.DataArray + ) -> xr.Dataset: + """ + Create dataset with all variables (rate, concentration), with a similar shape as the cellids. + """ + data_vars = ["id", "rate"] + if "concentration" in wells_assigned.columns: + data_vars.append("concentration") + + ds_vars = wells_assigned[data_vars].to_xarray() + # "rate" variable in conversion from multi-indexed DataFrame to xarray + # DataArray results in duplicated values for "rate" along dimension + # "species". Select first species to reduce this again. + index_names = wells_df.index.names + if "species" in index_names: + ds_vars["rate"] = ds_vars["rate"].isel(species=0) + + # Carefully rename the dimension and set coordinates + d_rename = {"index": "ncellid"} + ds_vars = ds_vars.rename_dims(**d_rename).rename_vars(**d_rename) + ds_vars = ds_vars.assign_coords(**{"ncellid": cellid.coords["ncellid"].values}) + + return ds_vars + + @staticmethod + def _derive_cellid_from_points( + dst_grid: GridDataArray, + x: list, + y: list, + layer: list, + ) -> GridDataArray: + """ + Create DataArray with Modflow6 cell identifiers based on x, y coordinates + in a dataframe. For structured grid this DataArray contains 3 columns: + ``layer, row, column``. For unstructured grids, this contains 2 columns: + ``layer, cell2d``. + See also: https://water.usgs.gov/water-resources/software/MODFLOW-6/mf6io_6.4.0.pdf#page=35 + + Note + ---- + The "layer" coordinate should already be provided in the dataframe. + To determine the layer coordinate based on screen depts, look at + :func:`imod.prepare.wells.assign_wells`. + + Parameters + ---------- + dst_grid: {xr.DataArray, xu.UgridDataArray} + Destination grid to map the points to based on their x and y coordinates. + x: {list, np.array} + array-like with x-coordinates + y: {list, np.array} + array-like with y-coordinates + layer: {list, np.array} + array-like with layer-coordinates + + Returns + ------- + cellid : xr.DataArray + 2D DataArray with a ``ncellid`` rows and 3 to 2 columns, depending + on whether on a structured or unstructured grid.""" + + # Find indices belonging to x, y coordinates + indices_cell2d = points_indices(dst_grid, out_of_bounds="ignore", x=x, y=y) + # Convert cell2d indices from 0-based to 1-based. + indices_cell2d = {dim: index + 1 for dim, index in indices_cell2d.items()} + # Prepare layer indices, for later concatenation + + if isinstance(dst_grid, xu.UgridDataArray): + indices_layer = xr.DataArray( + layer, coords=indices_cell2d["mesh2d_nFaces"].coords + ) + face_dim = dst_grid.ugrid.grid.face_dimension + indices_cell2d_dims = [face_dim] + cell2d_coords = ["cell2d"] + else: + indices_layer = xr.DataArray(layer, coords=indices_cell2d["x"].coords) + indices_cell2d_dims = ["y", "x"] + cell2d_coords = ["row", "column"] + + # Prepare cellid array of the right shape. + cellid_ls = [indices_layer] + [ + indices_cell2d[dim] for dim in indices_cell2d_dims + ] + cellid = xr.concat(cellid_ls, dim="nmax_cellid") + # Rename generic dimension name "index" to ncellid. + cellid = cellid.rename(index="ncellid") + # Put dimensions in right order after concatenation. + cellid = cellid.transpose("ncellid", "nmax_cellid") + # Assign extra coordinate names. + coords = { + "nmax_cellid": ["layer"] + cell2d_coords, + "x": ("ncellid", x), + "y": ("ncellid", y), + } + cellid = cellid.assign_coords(**coords) + + return cellid + + def render(self, directory, pkgname, globaltimes, binary): + raise NotImplementedError( + f"{self.__class__.__name__} is a grid-agnostic package and does not have a render method. To render the package, first convert to a Modflow6 package by calling pkg.to_mf6_pkg()" + ) + + def write( + self, + pkgname: str, + globaltimes: Union[list[np.datetime64], np.ndarray], + write_context: WriteContext, + ): + raise NotImplementedError( + "To write a wel package first convert it to a MF6 well using to_mf6_pkg." + ) + + def mask(self, domain: GridDataArray) -> GridAgnosticWell: + """ + Mask wells based on two-dimensional domain. For three-dimensional + masking: Wells falling in inactive cells are automatically removed in + the call to write to Modflow 6 package. You can verify this by calling + the ``to_mf6_pkg`` method. + """ + + # Drop layer coordinate if present, otherwise a layer coordinate is assigned + # which causes conflicts downstream when assigning wells and deriving + # cellids. + domain_2d = domain.isel(layer=0, drop=True, missing_dims="ignore").drop_vars( + "layer", errors="ignore" + ) + return mask_2D(self, domain_2d) + + def to_mf6_pkg( + self, + active: GridDataArray, + top: GridDataArray, + bottom: GridDataArray, + k: GridDataArray, + validate: bool = False, + is_partitioned: bool = False, + ) -> Mf6Wel: + """ + Write package to Modflow 6 package. + + Based on the model grid and top and bottoms, cellids are determined. + When well screens hit multiple layers, groundwater extractions are + distributed based on layer transmissivities. Wells located in inactive + cells are removed. + + Note + ---- + The well distribution based on transmissivities assumes confined + aquifers. If wells fall dry (and the rate distribution has to be + recomputed at runtime), it is better to use the Multi-Aquifer Well + package. + + Parameters + ---------- + active: {xarry.DataArray, xugrid.UgridDataArray} + Grid with active cells. + top: {xarry.DataArray, xugrid.UgridDataArray} + Grid with top of model layers. + bottom: {xarry.DataArray, xugrid.UgridDataArray} + Grid with bottom of model layers. + k: {xarry.DataArray, xugrid.UgridDataArray} + Grid with hydraulic conductivities. + validate: bool + Run validation before converting + is_partitioned: bool + Set to true if model has been partitioned + + Returns + ------- + Mf6Wel + Object with wells as list based input. + """ + if validate: + errors = self._validate(self._write_schemata) + if len(errors) > 0: + message = validation_pkg_error_message(errors) + raise ValidationError(message) + + wells_df = self._create_wells_df() + nwells_df = len(wells_df["id"].unique()) + wells_assigned = self._assign_wells_to_layers(wells_df, active, top, bottom, k) + + nwells_assigned = ( + 0 if wells_assigned.empty else len(wells_assigned["id"].unique()) + ) + + if nwells_df == 0: + raise ValueError("No wells were assigned in package. None were present.") + + if not is_partitioned and nwells_df != nwells_assigned: + raise ValueError( + "One or more well(s) are completely invalid due to minimum conductivity and thickness constraints." + ) + + ds = xr.Dataset() + ds["cellid"] = self._create_cellid(wells_assigned, active) + + ds_vars = self._create_dataset_vars(wells_assigned, wells_df, ds["cellid"]) + ds = ds.assign(**ds_vars.data_vars) + + ds = remove_inactive(ds, active) + ds["save_flows"] = self["save_flows"].values[()] + ds["print_flows"] = self["print_flows"].values[()] + ds["print_input"] = self["print_input"].values[()] + + filtered_wells = [ + id for id in wells_df["id"].unique() if id not in ds["id"].values + ] + if len(filtered_wells) > 0: + message = self.to_mf6_package_information(filtered_wells) + logger.log(loglevel=LogLevel.WARNING, message=message, additional_depth=2) + + ds = ds.drop_vars("id") + + return Mf6Wel(**ds.data_vars) + + def to_mf6_package_information(self, filtered_wells): + message = textwrap.dedent( + """Some wells were not placed in the MF6 well package. This + can be due to inactive cells or permeability/thickness constraints.\n""" + ) + if len(filtered_wells) < 10: + message += "The filtered wells are: \n" + else: + message += " The first 10 unplaced wells are: \n" + + for i in range(min(10, len(filtered_wells))): + ids = filtered_wells[i] + x = self.dataset["x"][int(filtered_wells[i])].values[()] + y = self.dataset["y"][int(filtered_wells[i])].values[()] + message += f" id = {ids} x = {x} y = {y} \n" + return message + + def _create_wells_df(self): + raise NotImplementedError("Method in abstract base class called") + + def _assign_wells_to_layers( + self, + wells_df: pd.DataFrame, + active: GridDataArray, + top: GridDataArray, + bottom: GridDataArray, + k: GridDataArray, + ): + raise NotImplementedError("Method in abstract base class called") + + +class Well(GridAgnosticWell): """ Agnostic WEL package, which accepts x, y and a top and bottom of the well screens. @@ -160,14 +461,6 @@ class Well(BoundaryCondition, IPointDataPackage): >>> imod.mf6.Well(x, y, screen_top, screen_bottom, rate_transient) """ - @property - def x(self) -> npt.NDArray[np.float64]: - return self.dataset["x"].values - - @property - def y(self) -> npt.NDArray[np.float64]: - return self.dataset["y"].values - _pkg_id = "wel" _auxiliary_data = {"concentration": "species"} @@ -242,10 +535,6 @@ def __init__( self.dataset = self.dataset.assign_coords(index=index_coord) self._validate_init_schemata(validate) - @classmethod - def is_grid_agnostic_package(cls) -> bool: - return True - def clip_box( self, time_min: Optional[cftime.datetime | np.datetime64 | str] = None, @@ -289,7 +578,6 @@ def clip_box( y_max: optional, float top: optional, GridDataArray bottom: optional, GridDataArray - state_for_boundary: optional, GridDataArray Returns ------- @@ -350,17 +638,7 @@ def _find_well_value_at_layer( return value - def write( - self, - pkgname: str, - globaltimes: Union[list[np.datetime64], np.ndarray], - write_context: WriteContext, - ): - raise NotImplementedError( - "To write a wel package first convert it to a MF6 well using to_mf6_pkg." - ) - - def __create_wells_df(self) -> pd.DataFrame: + def _create_wells_df(self) -> pd.DataFrame: wells_df = self.dataset.to_dataframe() wells_df = wells_df.rename( columns={ @@ -376,15 +654,13 @@ def _validate(self, schemata: dict, **kwargs) -> dict[str, list[ValidationError] kwargs["screen_top"] = self.dataset["screen_top"] return Package._validate(self, schemata, **kwargs) - def __create_assigned_wells( + def _assign_wells_to_layers( self, wells_df: pd.DataFrame, active: GridDataArray, top: GridDataArray, bottom: GridDataArray, k: GridDataArray, - minimum_k: float, - minimum_thickness: float, ): # Ensure top, bottom & k # are broadcasted to 3d grid @@ -392,11 +668,13 @@ def __create_assigned_wells( bottom = like * bottom top_2d = (like * top).sel(layer=1) top_3d = bottom.shift(layer=1).fillna(top_2d) - k = like * k index_names = wells_df.index.names + minimum_k = self.dataset["minimum_k"].item() + minimum_thickness = self.dataset["minimum_thickness"].item() + # Unset multi-index, because assign_wells cannot deal with # multi-indices which is returned by self.dataset.to_dataframe() in # case of a "time" and "species" coordinate. @@ -410,242 +688,280 @@ def __create_assigned_wells( return wells_assigned - def __create_dataset_vars( - self, wells_assigned: pd.DataFrame, wells_df: pd.DataFrame, cellid: xr.DataArray - ) -> xr.Dataset: - """ - Create dataset with all variables (rate, concentration), with a similar shape as the cellids. - """ - data_vars = ["id", "rate"] - if "concentration" in wells_assigned.columns: - data_vars.append("concentration") - - ds_vars = wells_assigned[data_vars].to_xarray() - # "rate" variable in conversion from multi-indexed DataFrame to xarray - # DataArray results in duplicated values for "rate" along dimension - # "species". Select first species to reduce this again. - index_names = wells_df.index.names - if "species" in index_names: - ds_vars["rate"] = ds_vars["rate"].isel(species=0) - - # Carefully rename the dimension and set coordinates - d_rename = {"index": "ncellid"} - ds_vars = ds_vars.rename_dims(**d_rename).rename_vars(**d_rename) - ds_vars = ds_vars.assign_coords(**{"ncellid": cellid.coords["ncellid"].values}) - - return ds_vars - - def __create_cellid(self, wells_assigned: pd.DataFrame, active: xr.DataArray): - like = ones_like(active) - - # Groupby index and select first, to unset any duplicate records - # introduced by the multi-indexed "time" dimension. - df_for_cellid = wells_assigned.groupby("index").first() - d_for_cellid = df_for_cellid[["x", "y", "layer"]].to_dict("list") + @classmethod + def from_imod5_data( + cls, + key: str, + imod5_data: dict[str, dict[str, GridDataArray]], + times: list[datetime], + minimum_k: float = 0.1, + minimum_thickness: float = 1.0, + ) -> "Well": + pkg_data = imod5_data[key] + if "layer" in pkg_data.keys() and (pkg_data["layer"] != 0): + log_msg = textwrap.dedent( + f""" + In well {key} a layer was assigned, but this is not + supported. Assignment will be done based on filter_top and + filter_bottom, and the chosen layer ({pkg_data["layer"]}) + will be ignored.""" + ) + logger.log(loglevel=LogLevel.WARNING, message=log_msg, additional_depth=2) - return self.__derive_cellid_from_points(like, **d_for_cellid) + df: pd.DataFrame = pkg_data["dataframe"] - @staticmethod - def __derive_cellid_from_points( - dst_grid: GridDataArray, - x: list, - y: list, - layer: list, - ) -> GridDataArray: - """ - Create DataArray with Modflow6 cell identifiers based on x, y coordinates - in a dataframe. For structured grid this DataArray contains 3 columns: - ``layer, row, column``. For unstructured grids, this contains 2 columns: - ``layer, cell2d``. - See also: https://water.usgs.gov/water-resources/software/MODFLOW-6/mf6io_6.4.0.pdf#page=35 + if "filt_top" not in df.columns or "filt_bot" not in df.columns: + log_msg = textwrap.dedent( + f""" + In well {key} the filt_top and filt_bot columns were not both found; + this is not supported for import.""" + ) + logger.log(loglevel=LogLevel.ERROR, message=log_msg, additional_depth=2) + raise ValueError(log_msg) - Note - ---- - The "layer" coordinate should already be provided in the dataframe. - To determine the layer coordinate based on screen depts, look at - :func:`imod.prepare.wells.assign_wells`. + # Groupby unique wells, to get dataframes per time. + colnames_group = ["x", "y", "filt_top", "filt_bot", "id"] + wel_index, unique_well_groups = zip(*df.groupby(colnames_group)) - Parameters - ---------- - dst_grid: {xr.DataArray, xu.UgridDataArray} - Destination grid to map the points to based on their x and y coordinates. - x: {list, np.array} - array-like with x-coordinates - y: {list, np.array} - array-like with y-coordinates - layer: {list, np.array} - array-like with layer-coordinates + # Unpack wel indices by zipping + x, y, filt_top, filt_bot, id = zip(*wel_index) + well_rate = _prepare_well_rates_from_groups(unique_well_groups, times) - Returns - ------- - cellid : xr.DataArray - 2D DataArray with a ``ncellid`` rows and 3 to 2 columns, depending - on whether on a structured or unstructured grid.""" + return cls( + x=np.array(x, dtype=float), + y=np.array(y, dtype=float), + screen_top=np.array(filt_top, dtype=float), + screen_bottom=np.array(filt_bot, dtype=float), + rate=well_rate, + minimum_k=minimum_k, + minimum_thickness=minimum_thickness, + ) - # Find indices belonging to x, y coordinates - indices_cell2d = points_indices(dst_grid, out_of_bounds="ignore", x=x, y=y) - # Convert cell2d indices from 0-based to 1-based. - indices_cell2d = {dim: index + 1 for dim, index in indices_cell2d.items()} - # Prepare layer indices, for later concatenation - if isinstance(dst_grid, xu.UgridDataArray): - indices_layer = xr.DataArray( - layer, coords=indices_cell2d["mesh2d_nFaces"].coords - ) - face_dim = dst_grid.ugrid.grid.face_dimension - indices_cell2d_dims = [face_dim] - cell2d_coords = ["cell2d"] - else: - indices_layer = xr.DataArray(layer, coords=indices_cell2d["x"].coords) - indices_cell2d_dims = ["y", "x"] - cell2d_coords = ["row", "column"] +class LayeredWell(GridAgnosticWell): + """ + Agnostic WEL package, which accepts x, y and layers. - # Prepare cellid array of the right shape. - cellid_ls = [indices_layer] + [ - indices_cell2d[dim] for dim in indices_cell2d_dims - ] - cellid = xr.concat(cellid_ls, dim="nmax_cellid") - # Rename generic dimension name "index" to ncellid. - cellid = cellid.rename(index="ncellid") - # Put dimensions in right order after concatenation. - cellid = cellid.transpose("ncellid", "nmax_cellid") - # Assign extra coordinate names. - coords = { - "nmax_cellid": ["layer"] + cell2d_coords, - "x": ("ncellid", x), - "y": ("ncellid", y), - } - cellid = cellid.assign_coords(**coords) + This package can be written to any provided model grid. + Any number of WEL Packages can be specified for a single groundwater flow model. + https://water.usgs.gov/water-resources/software/MODFLOW-6/mf6io_6.0.4.pdf#page=63 - return cellid + Parameters + ---------- - def render(self, directory, pkgname, globaltimes, binary): - raise NotImplementedError( - f"{self.__class__.__name__} is a grid-agnostic package and does not have a render method. To render the package, first convert to a Modflow6 package by calling pkg.to_mf6_pkg()" - ) + y: float or list of floats or np.array of floats + is the y location of the well. + x: float or list of floats or np.array of floats + is the x location of the well. + layer: int or list of ints or np.array of ints + is the layer of the well. + rate: float, list of floats or xr.DataArray + is the volumetric well rate. A positive value indicates well + (injection) and a negative value indicates discharge (extraction) (q). + If provided as DataArray, an ``"index"`` dimension is required and an + optional ``"time"`` dimension and coordinate specify transient input. + In the latter case, it is important that dimensions are in the order: + ``("time", "index")`` + concentration: array of floats (xr.DataArray, optional) + if this flow package is used in simulations also involving transport, then this array is used + as the concentration for inflow over this boundary. + concentration_boundary_type: ({"AUX", "AUXMIXED"}, optional) + if this flow package is used in simulations also involving transport, then this keyword specifies + how outflow over this boundary is computed. + id: list of Any, optional + assign an identifier code to each well. if not provided, one will be generated + Must be convertible to string, and unique entries. + minimum_k: float, optional + on creating point wells, no point wells will be placed in cells with a lower horizontal conductivity than this + minimum_thickness: float, optional + on creating point wells, no point wells will be placed in cells with a lower thickness than this + print_input: ({True, False}, optional) + keyword to indicate that the list of well information will be written to + the listing file immediately after it is read. + Default is False. + print_flows: ({True, False}, optional) + Indicates that the list of well flow rates will be printed to the + listing file for every stress period time step in which "BUDGET PRINT" + is specified in Output Control. If there is no Output Control option + and PRINT FLOWS is specified, then flow rates are printed for the last + time step of each stress period. + Default is False. + save_flows: ({True, False}, optional) + Indicates that well flow terms will be written to the file specified + with "BUDGET FILEOUT" in Output Control. + Default is False. + observations: [Not yet supported.] + Default is None. + validate: {True, False} + Flag to indicate whether the package should be validated upon + initialization. This raises a ValidationError if package input is + provided in the wrong manner. Defaults to True. + repeat_stress: Optional[xr.DataArray] of datetimes + Used to repeat data for e.g. repeating stress periods such as + seasonality without duplicating the values. The DataArray should have + dimensions ``("repeat", "repeat_items")``. The ``repeat_items`` + dimension should have size 2: the first value is the "key", the second + value is the "value". For the "key" datetime, the data of the "value" + datetime will be used. Can also be set with a dictionary using the + ``set_repeat_stress`` method. - def to_mf6_pkg( - self, - active: GridDataArray, - top: GridDataArray, - bottom: GridDataArray, - k: GridDataArray, - validate: bool = False, - is_partitioned: bool = False, - ) -> Mf6Wel: - """ - Write package to Modflow 6 package. + Examples + --------- - Based on the model grid and top and bottoms, cellids are determined. - When well screens hit multiple layers, groundwater extractions are - distributed based on layer transmissivities. Wells located in inactive - cells are removed. + >>> layer = [1, 2] + >>> y = [83.0, 77.0] + >>> x = [81.0, 82.0] + >>> rate = [1.0, 1.0] - Note - ---- - The well distribution based on transmissivities assumes confined - aquifers. If wells fall dry (and the rate distribution has to be - recomputed at runtime), it is better to use the Multi-Aquifer Well - package. + >>> imod.mf6.LayeredWell(x, y, layer, rate) - Parameters - ---------- - active: {xarry.DataArray, xugrid.UgridDataArray} - Grid with active cells. - top: {xarry.DataArray, xugrid.UgridDataArray} - Grid with top of model layers. - bottom: {xarry.DataArray, xugrid.UgridDataArray} - Grid with bottom of model layers. - k: {xarry.DataArray, xugrid.UgridDataArray} - Grid with hydraulic conductivities. - validate: bool - Run validation before converting - is_partitioned: bool - Set to true if model has been partitioned + For a transient well: - Returns - ------- - Mf6Wel - Object with wells as list based input. - """ - if validate: - errors = self._validate(self._write_schemata) - if len(errors) > 0: - message = validation_pkg_error_message(errors) - raise ValidationError(message) + >>> weltimes = pd.date_range("2000-01-01", "2000-01-03") - minimum_k = self.dataset["minimum_k"].item() - minimum_thickness = self.dataset["minimum_thickness"].item() + >>> rate_factor_time = xr.DataArray([0.5, 1.0], coords={"time": weltimes}, dims=("time",)) + >>> rate_transient = rate_factor_time * xr.DataArray(rate, dims=("index",)) - wells_df = self.__create_wells_df() - nwells_df = len(wells_df["id"].unique()) - wells_assigned = self.__create_assigned_wells( - wells_df, active, top, bottom, k, minimum_k, minimum_thickness - ) + >>> imod.mf6.LayeredWell(x, y, layer, rate_transient) + """ - nwells_assigned = ( - 0 if wells_assigned.empty else len(wells_assigned["id"].unique()) - ) + _pkg_id = "wel" - if nwells_df == 0: - raise ValueError("No wells were assigned in package. None were present.") + _auxiliary_data = {"concentration": "species"} + _init_schemata = { + "layer": [DTypeSchema(np.integer)], + "y": [DTypeSchema(np.floating)], + "x": [DTypeSchema(np.floating)], + "rate": [DTypeSchema(np.floating)], + "concentration": [DTypeSchema(np.floating)], + } + _write_schemata = { + "layer": [AnyNoDataSchema(), EmptyIndexesSchema()], + "y": [AnyNoDataSchema(), EmptyIndexesSchema()], + "x": [AnyNoDataSchema(), EmptyIndexesSchema()], + "rate": [AnyNoDataSchema(), EmptyIndexesSchema()], + "concentration": [AnyNoDataSchema(), EmptyIndexesSchema()], + } - if not is_partitioned and nwells_df != nwells_assigned: - raise ValueError( - "One or more well(s) are completely invalid due to minimum conductivity and thickness constraints." - ) + @init_log_decorator() + def __init__( + self, + x: np.ndarray | list[float], + y: np.ndarray | list[float], + layer: np.ndarray | list[int], + rate: list[float] | xr.DataArray, + concentration: Optional[list[float] | xr.DataArray] = None, + concentration_boundary_type="aux", + id: Optional[list[Any]] = None, + minimum_k: float = 0.1, + minimum_thickness: float = 1.0, + print_input: bool = False, + print_flows: bool = False, + save_flows: bool = False, + observations=None, + validate: bool = True, + repeat_stress: Optional[xr.DataArray] = None, + ): + if id is None: + id = [str(i) for i in range(len(x))] + else: + set_id = set(id) + if len(id) != len(set_id): + raise ValueError("id's must be unique") + id = [str(i) for i in id] + dict_dataset = { + "layer": _assign_dims(layer), + "y": _assign_dims(y), + "x": _assign_dims(x), + "rate": _assign_dims(rate), + "id": _assign_dims(id), + "minimum_k": minimum_k, + "minimum_thickness": minimum_thickness, + "print_input": print_input, + "print_flows": print_flows, + "save_flows": save_flows, + "observations": observations, + "repeat_stress": repeat_stress, + "concentration": concentration, + "concentration_boundary_type": concentration_boundary_type, + } + super().__init__(dict_dataset) + # Set index as coordinate + index_coord = np.arange(self.dataset.dims["index"]) + self.dataset = self.dataset.assign_coords(index=index_coord) + self._validate_init_schemata(validate) - ds = xr.Dataset() - ds["cellid"] = self.__create_cellid(wells_assigned, active) + def clip_box( + self, + time_min: Optional[cftime.datetime | np.datetime64 | str] = None, + time_max: Optional[cftime.datetime | np.datetime64 | str] = None, + layer_min: Optional[int] = None, + layer_max: Optional[int] = None, + x_min: Optional[float] = None, + x_max: Optional[float] = None, + y_min: Optional[float] = None, + y_max: Optional[float] = None, + top: Optional[GridDataArray] = None, + bottom: Optional[GridDataArray] = None, + ) -> Package: + """ + Clip a package by a bounding box (time, layer, y, x). - ds_vars = self.__create_dataset_vars(wells_assigned, wells_df, ds["cellid"]) - ds = ds.assign(**ds_vars.data_vars) + Slicing intervals may be half-bounded, by providing None: - ds = remove_inactive(ds, active) - ds["save_flows"] = self["save_flows"].values[()] - ds["print_flows"] = self["print_flows"].values[()] - ds["print_input"] = self["print_input"].values[()] + * To select 500.0 <= x <= 1000.0: + ``clip_box(x_min=500.0, x_max=1000.0)``. + * To select x <= 1000.0: ``clip_box(x_min=None, x_max=1000.0)`` + or ``clip_box(x_max=1000.0)``. + * To select x >= 500.0: ``clip_box(x_min = 500.0, x_max=None.0)`` + or ``clip_box(x_min=1000.0)``. - filtered_wells = [ - id for id in wells_df["id"].unique() if id not in ds["id"].values - ] - if len(filtered_wells) > 0: - message = self.to_mf6_package_information(filtered_wells) - logger.log(loglevel=LogLevel.WARNING, message=message, additional_depth=2) + Parameters + ---------- + time_min: optional + time_max: optional + layer_min: optional, int + layer_max: optional, int + x_min: optional, float + x_max: optional, float + y_min: optional, float + y_max: optional, float + top: optional, GridDataArray + bottom: optional, GridDataArray - ds = ds.drop_vars("id") + Returns + ------- + sliced : Package + """ + # The super method will select in the time dimension without issues. + new = super().clip_box(time_min=time_min, time_max=time_max) - return Mf6Wel(**ds.data_vars) + ds = new.dataset - def to_mf6_package_information(self, filtered_wells): - message = textwrap.dedent( - """Some wells were not placed in the MF6 well package. This - can be due to inactive cells or permeability/thickness constraints.\n""" - ) - if len(filtered_wells) < 10: - message += "The filtered wells are: \n" - else: - message += " The first 10 unplaced wells are: \n" + # Initiate array of True with right shape to deal with case no spatial + # selection needs to be done. + in_bounds = np.full(ds.dims["index"], True) + # Select all variables along "index" dimension + in_bounds &= values_within_range(ds["x"], x_min, x_max) + in_bounds &= values_within_range(ds["y"], y_min, y_max) + in_bounds &= values_within_range(ds["layer"], layer_min, layer_max) + # Replace dataset with reduced dataset based on booleans + new.dataset = ds.loc[{"index": in_bounds}] - for i in range(min(10, len(filtered_wells))): - message += f" id = {filtered_wells[i]} x = {self.dataset['x'][int(filtered_wells[i])].values[()]} y = {self.dataset['y'][int(filtered_wells[i])].values[()]} \n" - return message + return new - def mask(self, domain: GridDataArray) -> Well: - """ - Mask wells based on two-dimensional domain. For three-dimensional - masking: Wells falling in inactive cells are automatically removed in - the call to write to Modflow 6 package. You can verify this by calling - the ``to_mf6_pkg`` method. - """ + def _create_wells_df(self) -> pd.DataFrame: + return self.dataset.to_dataframe() - # Drop layer coordinate if present, otherwise a layer coordinate is assigned - # which causes conflicts downstream when assigning wells and deriving - # cellids. - domain_2d = domain.isel(layer=0, drop=True, missing_dims="ignore").drop_vars( - "layer", errors="ignore" - ) - return mask_2D(self, domain_2d) + def _assign_wells_to_layers( + self, + wells_df: pd.DataFrame, + active: GridDataArray, + top: GridDataArray, + bottom: GridDataArray, + k: GridDataArray, + ): + return wells_df @classmethod def from_imod5_data( @@ -655,69 +971,32 @@ def from_imod5_data( times: list[datetime], minimum_k: float = 0.1, minimum_thickness: float = 1.0, - ) -> "Well": - if "layer" in imod5_data[key].keys(): - if imod5_data[key]["layer"] != 0: - log_msg = textwrap.dedent( - f""" - In well {key} a layer was assigned, but this is not - supported. Assignment will be done based on filter_top and - filter_bottom, and the chosen layer ({imod5_data[key]["layer"]}) - will be ignored.""" - ) - logger.log( - loglevel=LogLevel.WARNING, message=log_msg, additional_depth=2 - ) - - if ( - "filt_top" not in imod5_data[key]["dataframe"].columns - or "filt_bot" not in imod5_data[key]["dataframe"].columns - ): + ) -> "LayeredWell": + pkg_data = imod5_data[key] + + if ("layer" not in pkg_data.keys()) or (pkg_data["layer"] == 0): log_msg = textwrap.dedent( - f""" - In well {key} the filt_top and filt_bot columns were not both found; - this is not supported for import.""" + f"""In well {key} no layer was assigned, but this is required.""" ) logger.log(loglevel=LogLevel.ERROR, message=log_msg, additional_depth=2) - raise ValueError(log_msg) - df: pd.DataFrame = imod5_data[key]["dataframe"] + df: pd.DataFrame = pkg_data["dataframe"] - # Groupby unique wells, to get dataframes per time. - colnames_group = ["x", "y", "filt_top", "filt_bot", "id"] - wel_index, df_groups = zip(*df.groupby(colnames_group)) + # Add layer to dataframe. + df["layer"] = pkg_data["layer"] - # resample per group + # Groupby unique wells, to get dataframes per time. + colnames_group = ["x", "y", "layer", "id"] + wel_index, unique_well_groups = zip(*df.groupby(colnames_group)) # Unpack wel indices by zipping - x, y, filt_top, filt_bot, id = zip(*wel_index) - - # resample times per group - df_resampled_groups = [] - for df_group in df_groups: - df_group = resample_timeseries(df_group, times) - df_resampled_groups.append(df_group) - - # Convert dataframes all groups to DataArrays - da_groups = [ - xr.DataArray( - df_group["rate"], dims=("time"), coords={"time": df_group["time"]} - ) - for df_group in df_resampled_groups - ] - # Assign index coordinates - da_groups = [ - da_group.expand_dims(dim="index").assign_coords(index=[i]) - for i, da_group in enumerate(da_groups) - ] - # Concatenate datarrays along index dimension - well_rate = xr.concat(da_groups, dim="index") + x, y, layer, id = zip(*wel_index) + well_rate = _prepare_well_rates_from_groups(unique_well_groups, times) return cls( x=np.array(x, dtype=float), y=np.array(y, dtype=float), - screen_top=np.array(filt_top, dtype=float), - screen_bottom=np.array(filt_bot, dtype=float), + layer=np.array(layer, dtype=int), rate=well_rate, minimum_k=minimum_k, minimum_thickness=minimum_thickness, diff --git a/imod/tests/test_mf6/test_mf6_simulation.py b/imod/tests/test_mf6/test_mf6_simulation.py index 88d123169..893ffe9bf 100644 --- a/imod/tests/test_mf6/test_mf6_simulation.py +++ b/imod/tests/test_mf6/test_mf6_simulation.py @@ -17,6 +17,7 @@ import xugrid as xu import imod +from imod.mf6 import LayeredWell, Well from imod.mf6.model import Modflow6Model from imod.mf6.multimodel.modelsplitter import PartitionInfo from imod.mf6.oc import OutputControl @@ -507,7 +508,37 @@ def test_import_from_imod5(imod5_dataset, tmp_path): @pytest.mark.usefixtures("imod5_dataset") -def test_import_from_imod5_nonstandard_regridding(imod5_dataset, tmp_path): +def test_import_from_imod5__correct_well_type(imod5_dataset): + # Unpack + imod5_data = imod5_dataset[0] + period_data = imod5_dataset[1] + # Temporarily change layer number to 0, to force Well object instead of + # LayeredWell + original_wel_layer = imod5_data["wel-1"]["layer"] + imod5_data["wel-1"]["layer"] = 0 + # Other arrangement + default_simulation_allocation_options = SimulationAllocationOptions + default_simulation_distributing_options = SimulationDistributingOptions + datelist = pd.date_range(start="1/1/1989", end="1/1/2013", freq="W") + + # Act + simulation = Modflow6Simulation.from_imod5_data( + imod5_data, + period_data, + default_simulation_allocation_options, + default_simulation_distributing_options, + datelist, + ) + # Set layer back to right value (before AssertionError might be thrown) + imod5_data["wel-1"]["layer"] = original_wel_layer + # Assert + assert isinstance(simulation["imported_model"]["wel-1"], Well) + assert isinstance(simulation["imported_model"]["wel-2"], LayeredWell) + assert isinstance(simulation["imported_model"]["wel-3"], LayeredWell) + + +@pytest.mark.usefixtures("imod5_dataset") +def test_import_from_imod5__nonstandard_regridding(imod5_dataset, tmp_path): imod5_data = imod5_dataset[0] period_data = imod5_dataset[1] default_simulation_allocation_options = SimulationAllocationOptions diff --git a/imod/tests/test_mf6/test_mf6_wel.py b/imod/tests/test_mf6/test_mf6_wel.py index 50deea31b..dfa7304e7 100644 --- a/imod/tests/test_mf6/test_mf6_wel.py +++ b/imod/tests/test_mf6/test_mf6_wel.py @@ -10,7 +10,7 @@ import pytest import xarray as xr import xugrid as xu -from pytest_cases import parametrize_with_cases +from pytest_cases import parametrize, parametrize_with_cases import imod from imod.formats.prj.prj import open_projectfile_data @@ -19,7 +19,7 @@ from imod.mf6.dis import StructuredDiscretization from imod.mf6.npf import NodePropertyFlow from imod.mf6.utilities.grid import broadcast_to_full_domain -from imod.mf6.wel import Well +from imod.mf6.wel import LayeredWell, Well from imod.mf6.write_context import WriteContext from imod.schemata import ValidationError from imod.tests.fixtures.flow_basic_fixture import BasicDisSettings @@ -34,39 +34,155 @@ ] -def test_to_mf6_pkg__high_lvl_stationary(basic_dis, well_high_lvl_test_data_stationary): +class GridAgnosticWellCases: + def case_well_stationary(self, well_high_lvl_test_data_stationary): + obj = imod.mf6.Well(*well_high_lvl_test_data_stationary) + dims_expected = { + "ncellid": 8, + "nmax_cellid": 3, + "species": 2, + } + cellid_expected = np.array( + [ + [1, 1, 9], + [1, 2, 9], + [1, 1, 8], + [1, 2, 8], + [2, 3, 7], + [2, 4, 7], + [2, 3, 6], + [2, 4, 6], + ], + dtype=np.int64, + ) + rate_expected = np.array(np.ones((8,), dtype=np.float32)) + return obj, dims_expected, cellid_expected, rate_expected + + def case_well_stationary_multilevel(self, well_high_lvl_test_data_stationary): + x, y, screen_top, _, rate_wel, concentration = ( + well_high_lvl_test_data_stationary + ) + screen_bottom = [-20.0] * 8 + obj = imod.mf6.Well(x, y, screen_top, screen_bottom, rate_wel, concentration) + dims_expected = { + "ncellid": 12, + "nmax_cellid": 3, + "species": 2, + } + cellid_expected = np.array( + [ + [1, 1, 9], + [1, 2, 9], + [1, 1, 8], + [1, 2, 8], + [2, 1, 9], + [2, 2, 9], + [2, 1, 8], + [2, 2, 8], + [2, 3, 7], + [2, 4, 7], + [2, 3, 6], + [2, 4, 6], + ], + dtype=np.int64, + ) + rate_expected = np.array([0.25] * 4 + [0.75] * 4 + [1.0] * 4) + return obj, dims_expected, cellid_expected, rate_expected + + def case_well_transient(self, well_high_lvl_test_data_transient): + obj = imod.mf6.Well(*well_high_lvl_test_data_transient) + dims_expected = { + "ncellid": 8, + "time": 5, + "nmax_cellid": 3, + "species": 2, + } + cellid_expected = np.array( + [ + [1, 1, 9], + [1, 2, 9], + [1, 1, 8], + [1, 2, 8], + [2, 3, 7], + [2, 4, 7], + [2, 3, 6], + [2, 4, 6], + ], + dtype=np.int64, + ) + rate_expected = np.outer(np.ones((8,), dtype=np.float32), np.arange(5) + 1) + return obj, dims_expected, cellid_expected, rate_expected + + def case_layered_well_stationary(self, well_high_lvl_test_data_stationary): + x, y, _, _, rate_wel, concentration = well_high_lvl_test_data_stationary + layer = [1, 1, 1, 1, 2, 2, 2, 2] + obj = imod.mf6.LayeredWell(x, y, layer, rate_wel, concentration) + dims_expected = { + "ncellid": 8, + "nmax_cellid": 3, + "species": 2, + } + cellid_expected = np.array( + [ + [1, 1, 9], + [1, 2, 9], + [1, 1, 8], + [1, 2, 8], + [2, 3, 7], + [2, 4, 7], + [2, 3, 6], + [2, 4, 6], + ], + dtype=np.int64, + ) + rate_expected = np.array(np.ones((8,), dtype=np.float32)) + return obj, dims_expected, cellid_expected, rate_expected + + def case_layered_well_transient(self, well_high_lvl_test_data_transient): + x, y, _, _, rate_wel, concentration = well_high_lvl_test_data_transient + layer = [1, 1, 1, 1, 2, 2, 2, 2] + obj = imod.mf6.LayeredWell(x, y, layer, rate_wel, concentration) + dims_expected = { + "ncellid": 8, + "time": 5, + "nmax_cellid": 3, + "species": 2, + } + cellid_expected = np.array( + [ + [1, 1, 9], + [1, 2, 9], + [1, 1, 8], + [1, 2, 8], + [2, 3, 7], + [2, 4, 7], + [2, 3, 6], + [2, 4, 6], + ], + dtype=np.int64, + ) + rate_expected = np.outer(np.ones((8,), dtype=np.float32), np.arange(5) + 1) + return obj, dims_expected, cellid_expected, rate_expected + + +@parametrize_with_cases( + ["wel", "dims_expected", "cellid_expected", "rate_expected"], + cases=GridAgnosticWellCases, +) +def test_to_mf6_pkg(basic_dis, wel, dims_expected, cellid_expected, rate_expected): # Arrange idomain, top, bottom = basic_dis - wel = imod.mf6.Well(*well_high_lvl_test_data_stationary) active = idomain == 1 k = xr.ones_like(idomain) nmax_cellid_expected = np.array(["layer", "row", "column"]) - cellid_expected = np.array( - [ - [1, 1, 9], - [1, 2, 9], - [1, 1, 8], - [1, 2, 8], - [2, 3, 7], - [2, 4, 7], - [2, 3, 6], - [2, 4, 6], - ], - dtype=np.int64, - ) - rate_expected = np.array(np.ones((8,), dtype=np.float32)) # Act mf6_wel = wel.to_mf6_pkg(active, top, bottom, k) mf6_ds = mf6_wel.dataset # Assert - assert dict(mf6_ds.dims) == { - "ncellid": 8, - "nmax_cellid": 3, - "species": 2, - } + assert dict(mf6_ds.dims) == dims_expected np.testing.assert_equal(mf6_ds.coords["nmax_cellid"].values, nmax_cellid_expected) np.testing.assert_equal(mf6_ds["cellid"].values, cellid_expected) np.testing.assert_equal(mf6_ds["rate"].values, rate_expected) @@ -109,94 +225,6 @@ def test_to_mf6_pkg__validate_filter_top(well_high_lvl_test_data_stationary): ) -def test_to_mf6_pkg__high_lvl_multilevel(basic_dis, well_high_lvl_test_data_stationary): - """ - Test with stationary wells where the first 4 well screens extend over 2 layers. - Rates are distributed based on the fraction of the screen length in each layer. - In this case: The first layer should get 0.25, the second 0.75. - """ - # Arrange - idomain, top, bottom = basic_dis - x, y, screen_top, _, rate_wel, concentration = well_high_lvl_test_data_stationary - screen_bottom = [-20.0] * 8 - wel = imod.mf6.Well(x, y, screen_top, screen_bottom, rate_wel, concentration) - active = idomain == 1 - k = xr.ones_like(idomain) - - nmax_cellid_expected = np.array(["layer", "row", "column"]) - cellid_expected = np.array( - [ - [1, 1, 9], - [1, 2, 9], - [1, 1, 8], - [1, 2, 8], - [2, 1, 9], - [2, 2, 9], - [2, 1, 8], - [2, 2, 8], - [2, 3, 7], - [2, 4, 7], - [2, 3, 6], - [2, 4, 6], - ], - dtype=np.int64, - ) - rate_expected = np.array([0.25] * 4 + [0.75] * 4 + [1.0] * 4) - - # Act - mf6_wel = wel.to_mf6_pkg(active, top, bottom, k) - mf6_ds = mf6_wel.dataset - - # Assert - assert dict(mf6_ds.dims) == { - "ncellid": 12, - "nmax_cellid": 3, - "species": 2, - } - np.testing.assert_equal(mf6_ds.coords["nmax_cellid"].values, nmax_cellid_expected) - np.testing.assert_equal(mf6_ds["cellid"].values, cellid_expected) - np.testing.assert_equal(mf6_ds["rate"].values, rate_expected) - - -def test_to_mf6_pkg__high_lvl_transient(basic_dis, well_high_lvl_test_data_transient): - # Arrange - idomain, top, bottom = basic_dis - wel = imod.mf6.Well(*well_high_lvl_test_data_transient) - active = idomain == 1 - k = xr.ones_like(idomain) - - nmax_cellid_expected = np.array(["layer", "row", "column"]) - cellid_expected = np.array( - [ - [1, 1, 9], - [1, 2, 9], - [1, 1, 8], - [1, 2, 8], - [2, 3, 7], - [2, 4, 7], - [2, 3, 6], - [2, 4, 6], - ], - dtype=np.int64, - ) - rate_expected = np.outer(np.ones((8,), dtype=np.float32), np.arange(5) + 1) - - # Act - mf6_wel = wel.to_mf6_pkg(active, top, bottom, k) - mf6_ds = mf6_wel.dataset - - # Assert - assert dict(mf6_wel.dataset.dims) == { - "ncellid": 8, - "time": 5, - "nmax_cellid": 3, - "species": 2, - } - np.testing.assert_equal(mf6_ds.coords["nmax_cellid"].values, nmax_cellid_expected) - np.testing.assert_equal(mf6_ds["cellid"].values, cellid_expected) - np.testing.assert_equal(mf6_ds["rate"].values, rate_expected) - - def test_to_mf6_pkg__logging_with_message( tmp_path, basic_dis, well_high_lvl_test_data_transient ): @@ -350,7 +378,7 @@ def case_clip_xy(parameterizable_basic_dis): } expected_dims = {"index": 3, "species": 2} - return clip_arguments, expected_dims, does_not_raise() + return clip_arguments, expected_dims, does_not_raise(), does_not_raise() @staticmethod def case_clip_layer_max(parameterizable_basic_dis): @@ -358,7 +386,7 @@ def case_clip_layer_max(parameterizable_basic_dis): clip_arguments = {"layer_max": 2, "bottom": bottom, "top": top} expected_dims = {"index": 4, "species": 2} - return clip_arguments, expected_dims, does_not_raise() + return clip_arguments, expected_dims, does_not_raise(), does_not_raise() @staticmethod def case_clip_layer_min(parameterizable_basic_dis): @@ -366,7 +394,7 @@ def case_clip_layer_min(parameterizable_basic_dis): clip_arguments = {"layer_min": 5, "bottom": bottom, "top": top} expected_dims = {"index": 4, "species": 2} - return clip_arguments, expected_dims, does_not_raise() + return clip_arguments, expected_dims, does_not_raise(), does_not_raise() @staticmethod def case_clip_layer_min_layer_max(parameterizable_basic_dis): @@ -374,7 +402,7 @@ def case_clip_layer_min_layer_max(parameterizable_basic_dis): clip_arguments = {"layer_min": 1, "layer_max": 1, "bottom": bottom, "top": top} expected_dims = {"index": 4, "species": 2} - return clip_arguments, expected_dims, does_not_raise() + return clip_arguments, expected_dims, does_not_raise(), does_not_raise() @staticmethod def case_clip_top_is_scalar(parameterizable_basic_dis): @@ -383,7 +411,7 @@ def case_clip_top_is_scalar(parameterizable_basic_dis): clip_arguments = {"layer_max": 2, "bottom": bottom, "top": top} expected_dims = {"index": 4, "species": 2} - return clip_arguments, expected_dims, does_not_raise() + return clip_arguments, expected_dims, does_not_raise(), does_not_raise() @staticmethod def case_clip_top_is_non_layered_structuredgrid(parameterizable_basic_dis): @@ -394,7 +422,7 @@ def case_clip_top_is_non_layered_structuredgrid(parameterizable_basic_dis): clip_arguments = {"layer_max": 2, "bottom": bottom, "top": top} expected_dims = {"index": 4, "species": 2} - return clip_arguments, expected_dims, does_not_raise() + return clip_arguments, expected_dims, does_not_raise(), does_not_raise() @staticmethod def case_clip_top_is_layered_structuredgrid(parameterizable_basic_dis): @@ -404,7 +432,7 @@ def case_clip_top_is_layered_structuredgrid(parameterizable_basic_dis): clip_arguments = {"layer_max": 2, "bottom": bottom, "top": top} expected_dims = {"index": 4, "species": 2} - return clip_arguments, expected_dims, does_not_raise() + return clip_arguments, expected_dims, does_not_raise(), does_not_raise() @staticmethod def case_clip_top_is_non_layered_unstructuredgrid(parameterizable_basic_dis): @@ -418,7 +446,7 @@ def case_clip_top_is_non_layered_unstructuredgrid(parameterizable_basic_dis): clip_arguments = {"layer_max": 2, "bottom": bottom, "top": top} expected_dims = {"index": 4, "species": 2} - return clip_arguments, expected_dims, does_not_raise() + return clip_arguments, expected_dims, does_not_raise(), does_not_raise() @staticmethod def case_clip_top_is_layered_unstructuredgrid(parameterizable_basic_dis): @@ -430,23 +458,33 @@ def case_clip_top_is_layered_unstructuredgrid(parameterizable_basic_dis): clip_arguments = {"layer_max": 2, "bottom": bottom, "top": top} expected_dims = {"index": 4, "species": 2} - return clip_arguments, expected_dims, does_not_raise() + return clip_arguments, expected_dims, does_not_raise(), does_not_raise() @staticmethod def case_clip_missing_top(parameterizable_basic_dis): _, _, bottom = parameterizable_basic_dis clip_arguments = {"layer_max": 2, "bottom": bottom} - expected_dims = {} - return clip_arguments, expected_dims, pytest.raises(ValueError) + expected_dims = {"index": 4, "species": 2} + return ( + clip_arguments, + expected_dims, + pytest.raises(ValueError), + does_not_raise(), + ) @staticmethod def case_clip_missing_bottom(parameterizable_basic_dis): _, top, _ = parameterizable_basic_dis clip_arguments = {"layer_max": 2, "top": top} - expected_dims = {} - return clip_arguments, expected_dims, pytest.raises(ValueError) + expected_dims = {"index": 4, "species": 2} + return ( + clip_arguments, + expected_dims, + pytest.raises(ValueError), + does_not_raise(), + ) @pytest.mark.parametrize( @@ -466,10 +504,10 @@ def case_clip_missing_bottom(parameterizable_basic_dis): indirect=True, ) @parametrize_with_cases( - ("clip_box_args", "expected_dims", "expectation"), cases=ClipBoxCases + ("clip_box_args", "expected_dims", "expectation", "_"), cases=ClipBoxCases ) -def test_clip_box__high_lvl_stationary( - well_high_lvl_test_data_stationary, clip_box_args, expected_dims, expectation +def test_clip_box__well_stationary( + well_high_lvl_test_data_stationary, clip_box_args, expected_dims, expectation, _ ): # Arrange wel = imod.mf6.Well(*well_high_lvl_test_data_stationary) @@ -482,6 +520,40 @@ def test_clip_box__high_lvl_stationary( assert dict(ds.dims) == expected_dims +@pytest.mark.parametrize( + "parameterizable_basic_dis", + [ + BasicDisSettings( + nlay=10, + zstop=-10.0, + xstart=50.0, + xstop=100.0, + ystart=50.0, + ystop=100.0, + nrow=10, + ncol=10, + ) + ], + indirect=True, +) +@parametrize_with_cases( + ("clip_box_args", "expected_dims", "_", "expectation"), cases=ClipBoxCases +) +def test_clip_box__layered_well_stationary( + well_high_lvl_test_data_stationary, clip_box_args, expected_dims, _, expectation +): + x, y, _, _, rate_wel, concentration = well_high_lvl_test_data_stationary + layer = [1, 1, 1, 1, 9, 9, 9, 9] + wel = imod.mf6.LayeredWell(x, y, layer, rate_wel, concentration) + + with expectation: + # Act + ds = wel.clip_box(**clip_box_args).dataset + + # Assert + assert dict(ds.dims) == expected_dims + + @pytest.mark.parametrize( "parameterizable_basic_dis", [BasicDisSettings(nlay=10, zstop=-10.0)], @@ -550,7 +622,7 @@ def test_derive_cellid_from_points(basic_dis, well_high_lvl_test_data_stationary ) # Act - cellid = imod.mf6.wel.Well._Well__derive_cellid_from_points(idomain, x, y, layer) + cellid = imod.mf6.wel.Well._derive_cellid_from_points(idomain, x, y, layer) # Assert np.testing.assert_array_equal(cellid, cellid_expected) @@ -829,8 +901,9 @@ def test_render__concentration_dis_vertices_transient(well_test_data_transient): ) # check salinity and temperature was written to period data +@parametrize("wel_class", [Well, LayeredWell]) @pytest.mark.usefixtures("imod5_dataset") -def test_import_and_convert_to_mf6(imod5_dataset, tmp_path): +def test_import_and_convert_to_mf6(imod5_dataset, tmp_path, wel_class): data = imod5_dataset[0] target_dis = StructuredDiscretization.from_imod5_data(data) target_npf = NodePropertyFlow.from_imod5_data(data, target_dis.dataset["idomain"]) @@ -838,7 +911,7 @@ def test_import_and_convert_to_mf6(imod5_dataset, tmp_path): times = list(pd.date_range(datetime(1989, 1, 1), datetime(2013, 1, 1), 8400)) # import grid-agnostic well from imod5 data (it contains 1 well) - wel = Well.from_imod5_data("wel-1", data, times) + wel = wel_class.from_imod5_data("wel-1", data, times) assert wel.dataset["x"].values[0] == 197910.0 assert wel.dataset["y"].values[0] == 362860.0 assert np.mean(wel.dataset["rate"].values) == -317.1681465863781 @@ -860,8 +933,9 @@ def test_import_and_convert_to_mf6(imod5_dataset, tmp_path): mf6_well.write("wel", [], write_context) +@parametrize("wel_class", [Well, LayeredWell]) @pytest.mark.usefixtures("well_regular_import_prj") -def test_import_multiple_wells(well_regular_import_prj): +def test_import_multiple_wells(well_regular_import_prj, wel_class): imod5dict = open_projectfile_data(well_regular_import_prj) times = [ datetime(1981, 11, 30), @@ -873,8 +947,8 @@ def test_import_multiple_wells(well_regular_import_prj): ] # import grid-agnostic well from imod5 data (it contains 2 packages with 3 wells each) - wel1 = imod.mf6.Well.from_imod5_data("wel-1", imod5dict[0], times) - wel2 = imod.mf6.Well.from_imod5_data("wel-2", imod5dict[0], times) + wel1 = wel_class.from_imod5_data("wel-1", imod5dict[0], times) + wel2 = wel_class.from_imod5_data("wel-2", imod5dict[0], times) assert np.all(wel1.x == np.array([191112.11, 191171.96, 191231.52])) assert np.all(wel2.x == np.array([191112.11, 191171.96, 191231.52])) @@ -882,8 +956,9 @@ def test_import_multiple_wells(well_regular_import_prj): assert wel2.dataset["rate"].shape == (6, 3) +@parametrize("wel_class", [Well, LayeredWell]) @pytest.mark.usefixtures("well_duplication_import_prj") -def test_import_from_imod5_with_duplication(well_duplication_import_prj): +def test_import_from_imod5_with_duplication(well_duplication_import_prj, wel_class): imod5dict = open_projectfile_data(well_duplication_import_prj) times = [ datetime(1981, 11, 30), @@ -894,8 +969,8 @@ def test_import_from_imod5_with_duplication(well_duplication_import_prj): datetime(1982, 4, 30), ] # import grid-agnostic well from imod5 data (it contains 2 packages with 3 wells each) - wel1 = imod.mf6.Well.from_imod5_data("wel-1", imod5dict[0], times) - wel2 = imod.mf6.Well.from_imod5_data("wel-2", imod5dict[0], times) + wel1 = wel_class.from_imod5_data("wel-1", imod5dict[0], times) + wel2 = wel_class.from_imod5_data("wel-2", imod5dict[0], times) assert np.all(wel1.x == np.array([191171.96, 191231.52, 191231.52])) assert np.all(wel2.x == np.array([191112.11, 191171.96, 191231.52])) From b95291d916cff16ae4839b4100f6d10a5abdb6ec Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Mon, 29 Jul 2024 18:32:43 +0200 Subject: [PATCH 34/53] Issue #1122 review comments (#1128) Forgot to push fixes for review comments, this impelements this --- imod/mf6/model.py | 4 +- imod/mf6/wel.py | 58 ++++++++++++---------- imod/tests/test_mf6/test_package_sanity.py | 1 + 3 files changed, 35 insertions(+), 28 deletions(-) diff --git a/imod/mf6/model.py b/imod/mf6/model.py index a30b6291b..d3bf56cee 100644 --- a/imod/mf6/model.py +++ b/imod/mf6/model.py @@ -268,7 +268,7 @@ def write( mf6_hfb_ls: List[HorizontalFlowBarrierBase] = [] for pkg_name, pkg in self.items(): try: - if isinstance(pkg, GridAgnosticWell): + if issubclass(type(pkg), GridAgnosticWell): top, bottom, idomain = self.__get_domain_geometry() k = self.__get_k() mf6_well_pkg = pkg.to_mf6_pkg( @@ -284,7 +284,7 @@ def write( globaltimes=globaltimes, write_context=pkg_write_context, ) - elif isinstance(pkg, imod.mf6.HorizontalFlowBarrierBase): + elif issubclass(type(pkg), imod.mf6.HorizontalFlowBarrierBase): mf6_hfb_ls.append(pkg) else: pkg.write( diff --git a/imod/mf6/wel.py b/imod/mf6/wel.py index 4505c417c..fb5195b0a 100644 --- a/imod/mf6/wel.py +++ b/imod/mf6/wel.py @@ -112,7 +112,9 @@ def y(self) -> npt.NDArray[np.float64]: def is_grid_agnostic_package(cls) -> bool: return True - def _create_cellid(self, wells_assigned: pd.DataFrame, active: xr.DataArray): + def _create_cellid( + self, wells_assigned: pd.DataFrame, active: xr.DataArray + ) -> GridDataArray: like = ones_like(active) # Groupby index and select first, to unset any duplicate records @@ -123,7 +125,7 @@ def _create_cellid(self, wells_assigned: pd.DataFrame, active: xr.DataArray): return self._derive_cellid_from_points(like, **d_for_cellid) def _create_dataset_vars( - self, wells_assigned: pd.DataFrame, wells_df: pd.DataFrame, cellid: xr.DataArray + self, wells_assigned: pd.DataFrame, cellid: xr.DataArray ) -> xr.Dataset: """ Create dataset with all variables (rate, concentration), with a similar shape as the cellids. @@ -136,7 +138,7 @@ def _create_dataset_vars( # "rate" variable in conversion from multi-indexed DataFrame to xarray # DataArray results in duplicated values for "rate" along dimension # "species". Select first species to reduce this again. - index_names = wells_df.index.names + index_names = wells_assigned.index.names if "species" in index_names: ds_vars["rate"] = ds_vars["rate"].isel(species=0) @@ -321,7 +323,7 @@ def to_mf6_pkg( ds = xr.Dataset() ds["cellid"] = self._create_cellid(wells_assigned, active) - ds_vars = self._create_dataset_vars(wells_assigned, wells_df, ds["cellid"]) + ds_vars = self._create_dataset_vars(wells_assigned, ds["cellid"]) ds = ds.assign(**ds_vars.data_vars) ds = remove_inactive(ds, active) @@ -340,7 +342,7 @@ def to_mf6_pkg( return Mf6Wel(**ds.data_vars) - def to_mf6_package_information(self, filtered_wells): + def to_mf6_package_information(self, filtered_wells: pd.DataFrame) -> str: message = textwrap.dedent( """Some wells were not placed in the MF6 well package. This can be due to inactive cells or permeability/thickness constraints.\n""" @@ -357,7 +359,7 @@ def to_mf6_package_information(self, filtered_wells): message += f" id = {ids} x = {x} y = {y} \n" return message - def _create_wells_df(self): + def _create_wells_df(self) -> pd.DataFrame: raise NotImplementedError("Method in abstract base class called") def _assign_wells_to_layers( @@ -367,7 +369,7 @@ def _assign_wells_to_layers( top: GridDataArray, bottom: GridDataArray, k: GridDataArray, - ): + ) -> pd.DataFrame: raise NotImplementedError("Method in abstract base class called") @@ -382,15 +384,15 @@ class Well(GridAgnosticWell): Parameters ---------- - y: float or list of floats or np.array of floats + y: list of floats or np.array of floats is the y location of the well. - x: float or list of floats or np.array of floats + x: list of floats or np.array of floats is the x location of the well. - screen_top: float or list of floats or np.array of floats + screen_top: list of floats or np.array of floats is the top of the well screen. - screen_bottom: float or list of floats or np.array of floats + screen_bottom: list of floats or np.array of floats is the bottom of the well screen. - rate: float, list of floats or xr.DataArray + rate: list of floats or xr.DataArray is the volumetric well rate. A positive value indicates well (injection) and a negative value indicates discharge (extraction) (q). If provided as DataArray, an ``"index"`` dimension is required and an @@ -661,7 +663,7 @@ def _assign_wells_to_layers( top: GridDataArray, bottom: GridDataArray, k: GridDataArray, - ): + ) -> pd.DataFrame: # Ensure top, bottom & k # are broadcasted to 3d grid like = ones_like(active) @@ -701,10 +703,11 @@ def from_imod5_data( if "layer" in pkg_data.keys() and (pkg_data["layer"] != 0): log_msg = textwrap.dedent( f""" - In well {key} a layer was assigned, but this is not - supported. Assignment will be done based on filter_top and - filter_bottom, and the chosen layer ({pkg_data["layer"]}) - will be ignored.""" + In well {key} a layer was assigned, but this is not supported. + Assignment will be done based on filter_top and filter_bottom, + and the chosen layer ({pkg_data["layer"]}) will be ignored. To + specify by layer, use imod.mf6.LayeredWell. + """ ) logger.log(loglevel=LogLevel.WARNING, message=log_msg, additional_depth=2) @@ -713,8 +716,10 @@ def from_imod5_data( if "filt_top" not in df.columns or "filt_bot" not in df.columns: log_msg = textwrap.dedent( f""" - In well {key} the filt_top and filt_bot columns were not both found; - this is not supported for import.""" + In well {key} the filt_top and filt_bot columns were not both + found; this is not supported for import. To specify by layer, + use imod.mf6.LayeredWell. + """ ) logger.log(loglevel=LogLevel.ERROR, message=log_msg, additional_depth=2) raise ValueError(log_msg) @@ -742,20 +747,21 @@ class LayeredWell(GridAgnosticWell): """ Agnostic WEL package, which accepts x, y and layers. - This package can be written to any provided model grid. - Any number of WEL Packages can be specified for a single groundwater flow model. + This package can be written to any provided model grid, given that it has + enough layers. Any number of WEL Packages can be specified for a single + groundwater flow model. https://water.usgs.gov/water-resources/software/MODFLOW-6/mf6io_6.0.4.pdf#page=63 Parameters ---------- - y: float or list of floats or np.array of floats + y: list of floats or np.array of floats is the y location of the well. - x: float or list of floats or np.array of floats + x: list of floats or np.array of floats is the x location of the well. - layer: int or list of ints or np.array of ints + layer: list of ints or np.array of ints is the layer of the well. - rate: float, list of floats or xr.DataArray + rate: list of floats or xr.DataArray is the volumetric well rate. A positive value indicates well (injection) and a negative value indicates discharge (extraction) (q). If provided as DataArray, an ``"index"`` dimension is required and an @@ -960,7 +966,7 @@ def _assign_wells_to_layers( top: GridDataArray, bottom: GridDataArray, k: GridDataArray, - ): + ) -> pd.DataFrame: return wells_df @classmethod diff --git a/imod/tests/test_mf6/test_package_sanity.py b/imod/tests/test_mf6/test_package_sanity.py index 545eb3d4a..cfd2c0851 100644 --- a/imod/tests/test_mf6/test_package_sanity.py +++ b/imod/tests/test_mf6/test_package_sanity.py @@ -42,6 +42,7 @@ imod.mf6.HorizontalFlowBarrierHydraulicCharacteristic, imod.mf6.HorizontalFlowBarrierMultiplier, imod.mf6.HorizontalFlowBarrierResistance, + imod.mf6.LayeredWell, ] From 77adae960ae2452d2013fd90a8de0d6d817967ef Mon Sep 17 00:00:00 2001 From: luitjansl <64598682+luitjansl@users.noreply.github.com> Date: Thu, 1 Aug 2024 15:38:21 +0200 Subject: [PATCH 35/53] Issue #1120 import steady state lhm fixes (#1127) Fixes #1120 # Description this PR contains fixes made to be able to import a version of the LHM that is steady state. **Probably not all these changes should be merged. The review should reveal what to keep and what not.** Changes: -sto package can be absent in the imod5 project file. If that is the case, now a default sto package is made which imposes steady state. -rch package can now be absent in the project file. Then no recharge is present in the simulation. - allocation option and distribution option for river imports were hard coded to different defaults . The old defaults gave an error, which could be a new issue in itself. -also for GHB a new default was set, because the old one gave an error. This could be a new issue in itself. # Checklist - [X] Links to correct issue - [ ] Update changelog, if changes affect users - [X] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [X] Unit tests were added - [ ] **If feature added**: Added/extended example --------- Co-authored-by: Joeri van Engelen --- imod/mf6/model_gwf.py | 46 +++++++++++++------ imod/mf6/rch.py | 8 +++- imod/mf6/riv.py | 9 +++- imod/mf6/simulation.py | 8 ++-- imod/mf6/utilities/mask.py | 15 ++++++ .../topsystem/default_allocation_methods.py | 2 +- imod/tests/test_mf6/test_mf6_array_masking.py | 29 ++++++++++++ imod/tests/test_mf6/test_mf6_simulation.py | 42 +++++++++++++++++ 8 files changed, 135 insertions(+), 24 deletions(-) create mode 100644 imod/tests/test_mf6/test_mf6_array_masking.py diff --git a/imod/mf6/model_gwf.py b/imod/mf6/model_gwf.py index 456385ce5..1abfd05c3 100644 --- a/imod/mf6/model_gwf.py +++ b/imod/mf6/model_gwf.py @@ -40,6 +40,7 @@ SimulationDistributingOptions, ) from imod.typing import GridDataArray +from imod.typing.grid import zeros_like class GroundwaterFlowModel(Modflow6Model): @@ -248,12 +249,14 @@ def from_imod5_data( ) # import sto - sto_pkg = StorageCoefficient.from_imod5_data( - imod5_data, - grid, - cast(StorageCoefficientRegridMethod, regridder_types.get("sto")), - regrid_cache, - ) + sto_pkg = None + if "sto" in imod5_data.keys(): + sto_pkg = StorageCoefficient.from_imod5_data( + imod5_data, + grid, + cast(StorageCoefficientRegridMethod, regridder_types.get("sto")), + regrid_cache, + ) # import initial conditions ic_pkg = InitialConditions.from_imod5_data( @@ -264,23 +267,26 @@ def from_imod5_data( ) # import recharge - rch_pkg = Recharge.from_imod5_data( - imod5_data, - dis_pkg, - cast(RechargeRegridMethod, regridder_types.get("ic")), - regrid_cache, - ) + rch_pkg = None + if "rch" in imod5_data.keys(): + rch_pkg = Recharge.from_imod5_data( + imod5_data, + dis_pkg, + cast(RechargeRegridMethod, regridder_types.get("rch")), + regrid_cache, + ) result = GroundwaterFlowModel() result["dis"] = dis_pkg result["npf"] = npf_pkg - result["sto"] = sto_pkg + if sto_pkg is not None: + result["sto"] = sto_pkg result["ic"] = ic_pkg - result["rch"] = rch_pkg + if rch_pkg is not None: + result["rch"] = rch_pkg # now import the non-singleton packages' - # import wells # import wells imod5_keys = list(imod5_data.keys()) wel_keys = [key for key in imod5_keys if key[0:3] == "wel"] @@ -293,6 +299,7 @@ def from_imod5_data( wel_key, imod5_data, times ) + # import ghb's imod5_keys = list(imod5_data.keys()) ghb_keys = [key for key in imod5_keys if key[0:3] == "ghb"] for ghb_key in ghb_keys: @@ -391,4 +398,13 @@ def from_imod5_data( for key, chd_package in chd_packages.items(): result[key] = chd_package + if "sto" not in result.keys(): + zeros = zeros_like(grid, dtype=float) + result["sto"] = StorageCoefficient( + storage_coefficient=zeros, + specific_yield=zeros, + transient=False, + convertible=zeros.astype(int), + ) + return result diff --git a/imod/mf6/rch.py b/imod/mf6/rch.py index 9568ecddd..d21b99874 100644 --- a/imod/mf6/rch.py +++ b/imod/mf6/rch.py @@ -207,7 +207,13 @@ def from_imod5_data( # if rate has only layer 0, then it is planar. if is_planar_grid(new_package_data["rate"]): - planar_rate_regridded = new_package_data["rate"].isel(layer=0, drop=True) + if "layer" in new_package_data["rate"].dims: + planar_rate_regridded = new_package_data["rate"].isel( + layer=0, drop=True + ) + else: + planar_rate_regridded = new_package_data["rate"] + # create an array indicating in which cells rch is active is_rch_cell = allocate_rch_cells( ALLOCATION_OPTION.at_first_active, diff --git a/imod/mf6/riv.py b/imod/mf6/riv.py index 19c4d35b4..d91610651 100644 --- a/imod/mf6/riv.py +++ b/imod/mf6/riv.py @@ -335,9 +335,14 @@ def from_imod5_data( optional_river_package: Optional[River] = None optional_drainage_package: Optional[Drainage] = None # create a drainage package with the conductance we computed from the infiltration factor + drainage_arrays = { + "stage": regridded_package_data["stage"], + "conductance": drain_conductance, + } + drainage_package = cls.create_infiltration_factor_drain( - regridded_package_data["stage"], - drain_conductance, + drainage_arrays["stage"], + drainage_arrays["conductance"], ) # remove River package if its mask is False everywhere mask = ~np.isnan(river_conductance) diff --git a/imod/mf6/simulation.py b/imod/mf6/simulation.py index 292308cb8..810a42a1a 100644 --- a/imod/mf6/simulation.py +++ b/imod/mf6/simulation.py @@ -1348,10 +1348,8 @@ def from_imod5_data( object containing the conductivity distribution options per package type. If you want a package to have a different allocation option, then it should be imported separately - time_min: datetime - Begin-time of the simulation. - time_max: datetime - End-time of the simulation. + times: list[datetime] + time discretization of the model to be imported. regridder_types: dict[str, RegridMethodType] the key is the package name. The value is the RegridMethodType object containing the settings for regridding the package with the @@ -1383,5 +1381,5 @@ def from_imod5_data( # cleanup packages for validation idomain = groundwaterFlowModel.domain simulation.mask_all_models(idomain) - + simulation.create_time_discretization(additional_times=times) return simulation diff --git a/imod/mf6/utilities/mask.py b/imod/mf6/utilities/mask.py index 884f97648..e02b6442a 100644 --- a/imod/mf6/utilities/mask.py +++ b/imod/mf6/utilities/mask.py @@ -1,6 +1,7 @@ import numbers import numpy as np +import xarray as xr from fastcore.dispatch import typedispatch from xarray.core.utils import is_scalar @@ -129,3 +130,17 @@ def _adjust_mask_for_unlayered_data( array_mask = mask.isel(layer=0) return array_mask + + +def mask_arrays(arrays: dict[str, xr.DataArray]) -> dict[str, xr.DataArray]: + """ + This function takes a dictionary of xr.DataArrays. The arrays are assumed to have the same + coordinates. When a np.nan value is found in any array, the other arrays are also + set to np.nan at the same coordinates. + """ + masks = [xr.DataArray(~np.isnan(array)) for array in arrays.values()] + # Get total mask across all arrays + total_mask = xr.concat(masks[:], dim="arrays").all("arrays") + # Mask arrays with total mask + arrays_masked = {key: array.where(total_mask) for key, array in arrays.items()} + return arrays_masked diff --git a/imod/prepare/topsystem/default_allocation_methods.py b/imod/prepare/topsystem/default_allocation_methods.py index 5d7f61b3c..227188fc2 100644 --- a/imod/prepare/topsystem/default_allocation_methods.py +++ b/imod/prepare/topsystem/default_allocation_methods.py @@ -39,4 +39,4 @@ class SimulationDistributingOptions: drn: DISTRIBUTING_OPTION = DISTRIBUTING_OPTION.by_corrected_transmissivity riv: DISTRIBUTING_OPTION = DISTRIBUTING_OPTION.by_corrected_transmissivity - ghb: DISTRIBUTING_OPTION = DISTRIBUTING_OPTION.by_corrected_transmissivity + ghb: DISTRIBUTING_OPTION = DISTRIBUTING_OPTION.by_layer_transmissivity diff --git a/imod/tests/test_mf6/test_mf6_array_masking.py b/imod/tests/test_mf6/test_mf6_array_masking.py new file mode 100644 index 000000000..f0b30dbeb --- /dev/null +++ b/imod/tests/test_mf6/test_mf6_array_masking.py @@ -0,0 +1,29 @@ +import numpy as np +import xarray as xr + +from imod.mf6.utilities.mask import mask_arrays + + +def test_array_masking(): + x = [1] + y = [1, 2, 3] + layer = [1, 2] + coords = {"layer": layer, "y": y, "x": x} + dims = ("layer", "y", "x") + + array1 = xr.DataArray([[[1], [1], [1]], [[1], [1], [1]]], coords=coords, dims=dims) + array2 = xr.DataArray( + [[[np.nan], [1], [1]], [[1], [1], [1]]], coords=coords, dims=dims + ) + + masked_arrays = mask_arrays({"array1": array1, "array2": array2}) + + # element 0,0,0 should be nan in both arrays + assert np.isnan(masked_arrays["array1"].values[0, 0, 0]) + assert np.isnan(masked_arrays["array2"].values[0, 0, 0]) + + # there should be only 1 nan in both arrays + masked_arrays["array1"].values[0, 0, 0] = 1 + masked_arrays["array2"].values[0, 0, 0] = 1 + assert np.all(~np.isnan(masked_arrays["array1"].values)) + assert np.all(~np.isnan(masked_arrays["array2"].values)) diff --git a/imod/tests/test_mf6/test_mf6_simulation.py b/imod/tests/test_mf6/test_mf6_simulation.py index 893ffe9bf..f814cb9f4 100644 --- a/imod/tests/test_mf6/test_mf6_simulation.py +++ b/imod/tests/test_mf6/test_mf6_simulation.py @@ -572,3 +572,45 @@ def test_import_from_imod5__nonstandard_regridding(imod5_dataset, tmp_path): # write and validate the simulation. simulation.write(tmp_path, binary=False, validate=True) + + +@pytest.mark.usefixtures("imod5_dataset") +def test_import_from_imod5_no_storage_no_recharge(imod5_dataset, tmp_path): + # this test imports an imod5 simulation, but it has no recharge and no storage package. + imod5_data = imod5_dataset[0] + imod5_data.pop("sto") + imod5_data.pop("rch") + period_data = imod5_dataset[1] + + default_simulation_allocation_options = SimulationAllocationOptions + default_simulation_distributing_options = SimulationDistributingOptions + + times = pd.date_range(start="1/1/2018", end="12/1/2018", freq="ME") + + simulation = Modflow6Simulation.from_imod5_data( + imod5_data, + period_data, + default_simulation_allocation_options, + default_simulation_distributing_options, + times, + ) + + simulation["imported_model"]["oc"] = OutputControl( + save_head="last", save_budget="last" + ) + + simulation.create_time_discretization(["01-01-2003", "02-01-2003"]) + + # Remove HFB packages outside domain + # TODO: Build in support for hfb packages outside domain + for hfb_outside in ["hfb-24", "hfb-26"]: + simulation["imported_model"].pop(hfb_outside) + + # check storage is present and rch is absent + assert not simulation["imported_model"]["sto"].dataset["transient"].values[()] + package_keys = simulation["imported_model"].keys() + for key in package_keys: + assert key[0:3] != "rch" + + # write and validate the simulation. + simulation.write(tmp_path, binary=False, validate=True) From aa2f18408ae3e02a31dd36cd470850f5b61df0c5 Mon Sep 17 00:00:00 2001 From: luitjansl <64598682+luitjansl@users.noreply.github.com> Date: Thu, 8 Aug 2024 17:14:09 +0200 Subject: [PATCH 36/53] Issue #1139 apply factor and addition (#1140) Fixes #1139 # Description Loading project files turned out to be a time-sink for project file imports- especially when loading prj-file data with transient arrays such as chd-levels per timestep. These arrays were loaded in a function called "apply_factor_and_addition" which accounted for the fact that the user can specify a factor to multiply each array and a constant to add to it. These 2 (factor and addition) can be different for every timestep. Now they are applied at an earlier stage, when loading the ipf data. No new tests were added, because the tests in test_import_prj.py already test the application of factors and additions. (this PR is for improving performance and not changing behavior) # Checklist - [x] Links to correct issue - [ ] Update changelog, if changes affect users - [x] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [ ] Unit tests were added - [ ] **If feature added**: Added/extended example --- imod/formats/prj/prj.py | 115 ++++++++++++++++------------ imod/tests/test_mf6/test_mf6_wel.py | 4 +- 2 files changed, 68 insertions(+), 51 deletions(-) diff --git a/imod/formats/prj/prj.py b/imod/formats/prj/prj.py index 30c199073..192006d6e 100644 --- a/imod/formats/prj/prj.py +++ b/imod/formats/prj/prj.py @@ -522,7 +522,43 @@ def _try_read_with_func(func, path, *args, **kwargs): raise type(e)(f"{e}. Error thrown while opening file: {path}") -def _create_datarray_from_paths(paths: List[str], headers: List[Dict[str, Any]]): +def _get_array_transformation_parameters( + headers: List[Dict[str, Any]], key: str, dim: str +) -> Union[xr.DataArray | float]: + """ + In imod5 prj files one can add linear transformation parameters to transform + the data read from an idf file: we can specify a multiplication factor and a + constant that will be added to the values. The factor and addition + parameters can be can be scalar (if applied to 1 idf), or they can be + xr.DataArrays if the factor and addition are for example layer- or + time-dependent (if both we apply the transformations one at a time) + + Parameters + ---------- + headers: List[Dict[str, Any]] + prj-file lines which we want to import, serialized as a dictionary. + key: str + specifies the name of the transformation parameter in the idf file. + Usually "factor" or "addition" + dim: str + the name of the dimension over which transformation parameters are + expected to differ for the current import. Usually "time"or "layer" + """ + if dim in headers[0].keys(): + return xr.DataArray( + data=[header[key] for header in headers], + dims=(dim,), + coords={dim: [header[dim] for header in headers]}, + ) + else: + return headers[0][key] + + +def _create_dataarray_from_paths( + paths: List[str], headers: List[Dict[str, Any]], dim: str +) -> xr.DataArray: + factor = _get_array_transformation_parameters(headers, "factor", dim) + addition = _get_array_transformation_parameters(headers, "addition", dim) da = _try_read_with_func( imod.formats.array_io.reading._load, paths, @@ -530,22 +566,38 @@ def _create_datarray_from_paths(paths: List[str], headers: List[Dict[str, Any]]) _read=imod.idf._read, headers=headers, ) - return da + # Ensure factor and addition do not have more dimensions than da + if isinstance(factor, xr.DataArray): + missing_dims = set(factor.dims) - set(da.dims) + if missing_dims: + factor = factor.isel({d: 0 for d in missing_dims}, drop=True) + addition = addition.isel({d: 0 for d in missing_dims}, drop=True) + + return da * factor + addition -def _create_dataarray_from_values(values: List[float], headers: List[Dict[str, Any]]): + +def _create_dataarray_from_values( + values: List[float], headers: List[Dict[str, Any]], dim: str +): + factor = _get_array_transformation_parameters(headers, "factor", dim) + addition = _get_array_transformation_parameters(headers, "addition", dim) coords = _merge_coords(headers) firstdims = headers[0]["dims"] shape = [len(coord) for coord in coords.values()] da = xr.DataArray(np.reshape(values, shape), dims=firstdims, coords=coords) - return da + return da * factor + addition def _create_dataarray( - paths: List[str], headers: List[Dict[str, Any]], values: List[float] + paths: List[str], headers: List[Dict[str, Any]], values: List[float], dim: str ) -> xr.DataArray: """ Create a DataArray from a list of IDF paths, or from constant values. + + There are mixed cases possible, where some of the layers or stress periods + contain only a single constant value, and the others are specified as IDFs. + In that case, we cannot do a straightforward concatenation. """ values_valid = [] paths_valid = [] @@ -560,54 +612,19 @@ def _create_dataarray( paths_valid.append(path) if paths_valid and values_valid: - dap = _create_datarray_from_paths(paths_valid, headers_paths) - dav = _create_dataarray_from_values(values_valid, headers_values) + # Both lists contain entries: mixed case. + dap = _create_dataarray_from_paths(paths_valid, headers_paths, dim=dim) + dav = _create_dataarray_from_values(values_valid, headers_values, dim=dim) dap.name = "tmp" dav.name = "tmp" da = xr.merge((dap, dav), join="outer")["tmp"] elif paths_valid: - da = _create_datarray_from_paths(paths_valid, headers_paths) + # Only paths provided + da = _create_dataarray_from_paths(paths_valid, headers_paths, dim=dim) elif values_valid: - da = _create_dataarray_from_values(values_valid, headers_values) - - da = apply_factor_and_addition(headers, da) - return da - + # Only scalar values provided + da = _create_dataarray_from_values(values_valid, headers_values, dim=dim) -def apply_factor_and_addition(headers, da): - if not ("layer" in da.coords or "time" in da.dims): - factor = headers[0]["factor"] - addition = headers[0]["addition"] - da = da * factor + addition - elif "layer" in da.coords and "time" not in da.dims: - da = apply_factor_and_addition_per_layer(headers, da) - else: - header_per_time = defaultdict(list) - for time in da.coords["time"].values: - for header in headers: - if np.datetime64(header["time"]) == time: - header_per_time[time].append(header) - - for time in da.coords["time"]: - da.loc[{"time": time}] = apply_factor_and_addition( - header_per_time[np.datetime64(time.values)], - da.sel(time=time, drop=True), - ) - return da - - -def apply_factor_and_addition_per_layer(headers, da): - layer = da.coords["layer"].values - header_per_layer = {} - for header in headers: - if header["layer"] in header_per_layer.keys(): - raise ValueError("error in project file: layer repetition") - header_per_layer[header["layer"]] = header - addition_values = [header_per_layer[lay]["addition"] for lay in layer] - factor_values = [header_per_layer[lay]["factor"] for lay in layer] - addition = xr.DataArray(addition_values, coords={"layer": layer}, dims=("layer")) - factor = xr.DataArray(factor_values, coords={"layer": layer}, dims=("layer",)) - da = da * factor + addition return da @@ -631,7 +648,7 @@ def _open_package_idf( headers.append(header) values.append(value) - das[variable] = _create_dataarray(paths, headers, values) + das[variable] = _create_dataarray(paths, headers, values, dim="layer") return [das] @@ -758,7 +775,7 @@ def _open_boundary_condition_idf( for i, (paths, headers, values) in enumerate( zip(system_paths.values(), system_headers.values(), system_values.values()) ): - das[i][variable] = _create_dataarray(paths, headers, values) + das[i][variable] = _create_dataarray(paths, headers, values, dim="time") repeats = sorted(all_repeats) return das, repeats diff --git a/imod/tests/test_mf6/test_mf6_wel.py b/imod/tests/test_mf6/test_mf6_wel.py index dfa7304e7..93f95337a 100644 --- a/imod/tests/test_mf6/test_mf6_wel.py +++ b/imod/tests/test_mf6/test_mf6_wel.py @@ -1014,7 +1014,7 @@ def test_logmessage_for_layer_assignment_import_imod5( log = log_file.read() message_required = layer != 0 message_present = ( - "In well wel-1 a layer was assigned, but this is not\nsupported" in log + "In well wel-1 a layer was assigned, but this is not supported" in log ) assert message_required == message_present @@ -1059,7 +1059,7 @@ def test_logmessage_for_missing_filter_settings( log = log_file.read() message_required = remove is not None message_present = ( - "In well wel-1 the filt_top and filt_bot columns were not both found;" + "In well wel-1 the filt_top and filt_bot columns were not both\nfound;" in log ) assert message_required == message_present From a230bc920de6c5ad53f740d60e62c4c4c5a6cc04 Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Thu, 15 Aug 2024 08:00:01 +0200 Subject: [PATCH 37/53] Issue #1116 fix imod5 well import (#1142) Fixes #1116 # Description - ``open_projectfile_data`` now groups wells by ipf name - ``GridAgnosticWell.from_imod5_data`` now validates associated IPFs whether they meet our requirements - ``GridAgnosticWell.from_imod5_data`` deactivates unassociated IPFs if not present in certain timestep anymore - Remove imod.formats.prj.convert_to_disv - Adds lots of test cases to test the well import from projectfiles # Checklist - [x] Links to correct issue - [x] Update changelog, if changes affect users - [x] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [x] Unit tests were added - [ ] **If feature added**: Added/extended example --- docs/api/changelog.rst | 19 +- docs/api/io.rst | 1 - docs/api/mf6.rst | 9 + .../imod5_conversion.py | 152 ---- imod/formats/prj/__init__.py | 1 - imod/formats/prj/disv_conversion.py | 809 ------------------ imod/formats/prj/prj.py | 53 +- imod/mf6/model_gwf.py | 4 +- imod/mf6/wel.py | 349 ++++++-- imod/tests/conftest.py | 1 + imod/tests/fixtures/imod5_well_data.py | 98 ++- .../test_formats/test_disv_conversion.py | 69 -- imod/tests/test_formats/test_prj.py | 4 +- imod/tests/test_formats/test_prj_wel.py | 780 +++++++++++++++++ imod/tests/test_mf6/test_import_prj.py | 48 +- imod/tests/test_mf6/test_mf6_simulation.py | 12 +- imod/tests/test_mf6/test_mf6_wel.py | 51 +- 17 files changed, 1278 insertions(+), 1182 deletions(-) delete mode 100644 examples/imod5-backwards-compatibility/imod5_conversion.py delete mode 100644 imod/formats/prj/disv_conversion.py delete mode 100644 imod/tests/test_formats/test_disv_conversion.py create mode 100644 imod/tests/test_formats/test_prj_wel.py diff --git a/docs/api/changelog.rst b/docs/api/changelog.rst index 8bdd35b79..fff20e930 100644 --- a/docs/api/changelog.rst +++ b/docs/api/changelog.rst @@ -19,7 +19,8 @@ Fixed Changed ~~~~~~~ -- :class:`imod.mf6.Well` now also validates that well filter top is above well filter bottom +- :class:`imod.mf6.Well` now also validates that well filter top is above well + filter bottom - :func:`open_projectfile_data` now also imports well filter top and bottom. - :class:`imod.mf6.Well` now logs a warning if any wells are removed during writing. - :class:`imod.mf6.HorizontalFlowBarrierResistance`, @@ -30,19 +31,31 @@ Changed :func:`imod.prepare.linestring_to_square_zpolygons` and :func:`imod.prepare.linestring_to_trapezoid_zpolygons` to generate these polygons. +- :func:`open_projectfile_data` now returns well data grouped by ipf name, + instead of generic, separate number per entry. Added ~~~~~ +- :meth:`imod.mf6.Modflow6Simulation.from_imod5_data` to import imod5 data + loaded with :func:`imod.formats.prj.open_projectfile_data` as a MODFLOW 6 + simulation. - :func:`imod.prepare.linestring_to_square_zpolygons` and - :func:`imod.prepare.linestring_to_trapezoid_zpolygons` to generate - vertical polygons that can be used to specify horizontal flow barriers, specifically: + :func:`imod.prepare.linestring_to_trapezoid_zpolygons` to generate vertical + polygons that can be used to specify horizontal flow barriers, specifically: :class:`imod.mf6.HorizontalFlowBarrierResistance`, :class:`imod.mf6.HorizontalFlowBarrierMultiplier`, :class:`imod.mf6.HorizontalFlowBarrierHydraulicCharacteristic`. - :class:`imod.mf6.LayeredWell` to specify wells directly to layers instead assigning them with filter depths. +Removed +~~~~~~~ + +- :func:`imod.formats.prj.convert_to_disv` has been removed. This functionality + has been replaced by :meth:`imod.mf6.Modflow6Simulation.from_imod5_data`. To + convert a structured simulation to an unstructured simulation, call: + :meth:`imod.mf6.Modflow6Simulation.regrid_like` [Unreleased] ------------ diff --git a/docs/api/io.rst b/docs/api/io.rst index 69a12d91b..2d10b3bce 100644 --- a/docs/api/io.rst +++ b/docs/api/io.rst @@ -29,4 +29,3 @@ Input/output prj.read_projectfile prj.open_projectfile_data prj.read_timfile - prj.convert_to_disv diff --git a/docs/api/mf6.rst b/docs/api/mf6.rst index bfa8b3017..aaf9a1a44 100644 --- a/docs/api/mf6.rst +++ b/docs/api/mf6.rst @@ -74,6 +74,11 @@ Flow Packages HorizontalFlowBarrierHydraulicCharacteristic HorizontalFlowBarrierMultiplier HorizontalFlowBarrierResistance + LayeredWell + LayeredWell.from_imod5_data + LayeredWell.mask + LayeredWell.regrid_like + LayeredWell.to_mf6_pkg InitialConditions NodePropertyFlow Recharge @@ -82,6 +87,10 @@ Flow Packages StorageCoefficient UnsaturatedZoneFlow Well + Well.from_imod5_data + Well.mask + Well.regrid_like + Well.to_mf6_pkg WellDisStructured WellDisVertices diff --git a/examples/imod5-backwards-compatibility/imod5_conversion.py b/examples/imod5-backwards-compatibility/imod5_conversion.py deleted file mode 100644 index 4a83b0fd0..000000000 --- a/examples/imod5-backwards-compatibility/imod5_conversion.py +++ /dev/null @@ -1,152 +0,0 @@ -""" -This is an example of how to convert an existing iMOD5 model into an -unstructured Modflow 6 model. For this we'll use the ``convert_to_disv`` -function, which is still an experimental feature. In this example, we -have to work around the following issues in the converter: - -1. It expects no layer to be assigned for the rch and riv package. - In the example iMOD5 model, a layer is assigned to the rch and riv package. -2. The BarycentricInterpolator, used to compute starting heads, - introduced nans at the edges, whereas OverlapRegridder used to find the active - cells, suffers from no such thing. -3. CHDs are separated into different systems for each layer -4. Due to a bug with broadcasting n_times too many wells are generated: - 94 times & 94 indices. - -""" - -# %% -# Imports -# ------- -import numpy as np -import xugrid as xu - -import imod - -# %% -# Read data -# --------- -# -# For this example we'll get our data from the data shipped with iMOD Python. -# To read your own iMOD5 model, you can call -# :doc:`/api/generated/io/imod.formats.prj.open_projectfile_data` -temp_dir = imod.util.temporary_directory() - -data_prj, repeat_stress = imod.data.imod5_projectfile_data(temp_dir) - -data_prj - -# %% -# Cleanup -# ------- -# -# Remove layers -# TODO: If layer assigned, do not assign at depth? - -data_prj["rch"]["rate"] = data_prj["rch"]["rate"].sel(layer=1) -data_prj["drn-1"]["conductance"] = data_prj["drn-1"]["conductance"].sel(layer=1) -data_prj["drn-1"]["elevation"] = data_prj["drn-1"]["elevation"].sel(layer=1) - -# Pop broken hfbs -data_prj.pop("hfb-24") -data_prj.pop("hfb-26") - -# %% -# Target grid -# ----------- -# -# The rch rate is defined on a coarse grid, -# so we use this grid to make a lightweight example. - -dummy = data_prj["rch"]["rate"] -dummy.load() - -target = xu.UgridDataArray.from_structured(dummy) -triangular_grid = target.grid.triangulate() -voronoi_grid = triangular_grid.tesselate_centroidal_voronoi() - -voronoi_grid.plot() - -# %% -# Convert -# ------- -# -# We can convert the iMOD5 model to a Modflow6 model on the unstructured grid -# with the following function: - -mf6_model = imod.prj.convert_to_disv(data_prj, voronoi_grid) - -mf6_model - -# %% -# Cleanup -# ------- -# -# Clean starting head. Due to regridding, there is an empty edge at the -# bottom grid in starting head. - -edge = np.isnan(mf6_model["shd"]["start"].sel(layer=1)) -edge = edge & (mf6_model["disv"]["idomain"] == 1) -shd_mean_layer = mf6_model["shd"]["start"].mean(dim="mesh2d_nFaces") -mf6_model["shd"]["start"] = mf6_model["shd"]["start"].where(~edge, shd_mean_layer) - -# For some reason, all wells were broadcasted n_time times to index, -# resulting in 94 duplicate wells in a single cells -# Select 1, to reduce this. -# Furthermore rates we constant in time, but not along index - -for pkgname in ["wel-1", "wel-2"]: - rates = mf6_model[pkgname].dataset.isel(time=[1])["rate"].values - mf6_model[pkgname].dataset = mf6_model[pkgname].dataset.sel(index=[1], drop=False) - # Assign varying rates through to time to dataset - mf6_model[pkgname].dataset["rate"].values = rates.T - -# %% -# Assign to simulation -# -------------------- -# -# A Modflow 6 model is not a complete simulation, we still have to define a -# Modflow6Simulation and have to include some extra information - -mf6_sim = imod.mf6.Modflow6Simulation(name="mf6sim") -mf6_sim["gwf1"] = mf6_model - -# %% -# Set solver -mf6_sim["ims"] = imod.mf6.SolutionPresetModerate(modelnames=["gwf1"]) - -# %% -# Create time discretization, we'll only have to specify the end time. iMOD -# Python will take the other time steps from the stress packages. - -endtime = np.datetime64("2013-04-01T00:00:00.000000000") - -mf6_sim.create_time_discretization(additional_times=[endtime]) - - -# %% -# Write modflow 6 data - -modeldir = temp_dir / "mf6" -mf6_sim.write(directory=modeldir) - -# %% -# Run Modflow 6 simulation - -mf6_sim.run() - -# %% -# Read results from Modflow 6 simulation - -hds = imod.mf6.open_hds( - modeldir / "gwf1" / "gwf1.hds", modeldir / "gwf1" / "disv.disv.grb" -) - -hds.load() - -# %% -# Visualize - -hds.isel(time=-1, layer=4).ugrid.plot() - -# %% diff --git a/imod/formats/prj/__init__.py b/imod/formats/prj/__init__.py index f5a1a5831..c2bd90f23 100644 --- a/imod/formats/prj/__init__.py +++ b/imod/formats/prj/__init__.py @@ -1,2 +1 @@ -from imod.formats.prj.disv_conversion import convert_to_disv from imod.formats.prj.prj import open_projectfile_data, read_projectfile, read_timfile diff --git a/imod/formats/prj/disv_conversion.py b/imod/formats/prj/disv_conversion.py deleted file mode 100644 index 4483b7ace..000000000 --- a/imod/formats/prj/disv_conversion.py +++ /dev/null @@ -1,809 +0,0 @@ -""" -Most of the functionality here attempts to replicate what iMOD does with -project files. -""" - -from __future__ import annotations - -import pickle -from collections import Counter -from datetime import datetime -from typing import Dict, Optional, Tuple - -import numpy as np -import pandas as pd -import xarray as xr -import xugrid as xu - -import imod -from imod.mf6.model import Modflow6Model -from imod.mf6.utilities.package import get_repeat_stress -from imod.prepare.layer import get_upper_active_grid_cells -from imod.typing import GridDataArray -from imod.util.expand_repetitions import expand_repetitions -from imod.util.imports import MissingOptionalModule - -try: - import geopandas as gpd -except ImportError: - gpd = MissingOptionalModule("geopandas") - - -def hash_xy(da: xr.DataArray) -> Tuple[int]: - """ - Create a unique identifier based on the x and y coordinates of a DataArray. - """ - x = hash(pickle.dumps(da["x"].values)) - y = hash(pickle.dumps(da["y"].values)) - return x, y - - -class SingularTargetRegridderWeightsCache: - """ - Create a mapping of (source_coords, regridder_cls) => regridding weights. - - Allows re-use of the regridding weights, as computing the weights is the - most costly step. - - The regridder only processes x and y coordinates: we can hash these, - and get a unique identifier. The target is assumed to be constant. - """ - - def __init__(self, projectfile_data, target, cache_size: int): - # Collect the x-y coordinates of all x-y dimensioned DataArrays. - # Determine which regridding method to use. - # Count occurrences of both. - # Create and cache weights of the most common ones. - keys = [] - sources = {} - methods = {} - for pkgdict in projectfile_data.values(): - for variable, da in pkgdict.items(): - xydims = {"x", "y"} - - if isinstance(da, xr.DataArray) and xydims.issubset(da.dims): - # for initial condition, constant head, general head boundary - if variable == "head": - cls = xu.BarycentricInterpolator - method = None - elif variable == "conductance": - cls = xu.RelativeOverlapRegridder - method = "conductance" - else: - cls = xu.OverlapRegridder - method = "mean" - - x, y = hash_xy(da) - key = (x, y, cls) - keys.append(key) - sources[key] = da - methods[key] = method - - counter = Counter(keys) - self.target = target - self.weights = {} - for key, _ in counter.most_common(cache_size): - cls = key[2] - ugrid_source = xu.UgridDataArray.from_structured(sources[key]) - kwargs = {"source": ugrid_source, "target": target} - method = methods[key] - if method is not None: - kwargs["method"] = method - regridder = cls(**kwargs) - self.weights[key] = regridder.weights - - def regrid( - self, - source: xr.DataArray, - method: str = "mean", - original2d: Optional[xr.DataArray] = None, - ): - if source.dims[-2:] != ("y", "x"): # So it's a constant - if original2d is None: - raise ValueError("original2d must be provided for constant values") - source = source * xr.ones_like(original2d) - - kwargs = {"target": self.target} - if method == "barycentric": - cls = xu.BarycentricInterpolator - elif method == "conductance": - cls = xu.RelativeOverlapRegridder - kwargs["method"] = method - else: - cls = xu.OverlapRegridder - kwargs["method"] = method - - x, y = hash_xy(source) - key = (x, y, cls) - if key in self.weights: - kwargs["weights"] = self.weights[key] - regridder = cls.from_weights(**kwargs) - # Avoid creation of a UgridDataArray here - dims = source.dims[:-2] - coords = {k: source.coords[k] for k in dims} - facedim = self.target.face_dimension - face_source = xr.DataArray( - source.data.reshape(*source.shape[:-2], -1), - coords=coords, - dims=[*dims, facedim], - name=source.name, - ) - return xu.UgridDataArray( - regridder.regrid_dataarray(face_source, (facedim,)), - regridder._target.ugrid_topology, - ) - else: - ugrid_source = xu.UgridDataArray.from_structured(source) - kwargs["source"] = ugrid_source - regridder = cls(**kwargs) - return regridder.regrid(ugrid_source) - - -def raise_on_layer(value, variable: str): - da = value[variable] - if "layer" in da.dims: - raise ValueError(f"{variable} should not be assigned a layer") - return da - - -def finish(uda): - """ - Set dimension order, and drop empty layers. - """ - facedim = uda.ugrid.grid.face_dimension - dims = ("time", "layer", facedim) - return uda.transpose(*dims, missing_dims="ignore").dropna("layer", how="all") - - -def create_idomain(thickness): - """ - Find cells that should get a passthrough value: IDOMAIN = -1. - - We may find them by forward and back-filling: if they are filled in both, they - contain active cells in both directions, and the value should be set to -1. - """ - active = ( - thickness > 0 - ).compute() # TODO larger than a specific value for round off? - ones = xu.ones_like(active, dtype=float).where(active) - passthrough = ones.ffill("layer").notnull() & ones.bfill("layer").notnull() - idomain = ones.combine_first( - xu.full_like(active, -1.0, dtype=float).where(passthrough) - ) - return idomain.fillna(0).astype(int) - - -def create_disv( - cache, - top, - bottom, - ibound, -): - if top.dims == ("layer",): - if ibound.dims != ("layer", "y", "x"): - raise ValueError( - "Either ibound or top must have dimensions (layer, y, x) to " - "derive model extent. Both may not be provided as constants." - ) - top = top * xr.ones_like(ibound) - original2d = ibound.isel(layer=0, drop=True) - else: - original2d = top.isel(layer=0, drop=True) - - if bottom.dims == ("layer",): - bottom = bottom * xr.ones_like(ibound) - - top = top.compute() - bottom = bottom.compute() - disv_top = cache.regrid(top).compute() - disv_bottom = cache.regrid(bottom).compute() - thickness = disv_top - disv_bottom - idomain = create_idomain(thickness) - disv = imod.mf6.VerticesDiscretization( - top=disv_top.sel(layer=1), - bottom=disv_bottom, - idomain=idomain, - ) - active = idomain > 0 - return disv, disv_top, disv_bottom, active, original2d - - -def create_npf( - cache, - k, - vertical_anisotropy, - active, - original2d, -): - disv_k = cache.regrid(k, method="geometric_mean", original2d=original2d).where( - active - ) - k33 = k * vertical_anisotropy - disv_k33 = cache.regrid(k33, method="harmonic_mean", original2d=original2d).where( - active - ) - return imod.mf6.NodePropertyFlow( - icelltype=0, - k=disv_k, - k33=disv_k33, - ) - - -def create_chd( - cache, - model, - key, - value, - ibound, - active, - original2d, - repeat, - **kwargs, -): - head = value["head"] - - if "layer" in head.coords: - layer = head.layer - ibound = ibound.sel(layer=layer) - active = active.sel(layer=layer) - - disv_head = cache.regrid( - head, - method="barycentric", - original2d=original2d, - ) - valid = (ibound < 0) & active - - if not valid.any(): - return - - chd = imod.mf6.ConstantHead(head=disv_head.where(valid)) - if repeat is not None: - chd.dataset["repeat_stress"] = get_repeat_stress(repeat) - model[key] = chd - return - - -def create_drn( - cache, - model, - key, - value, - active, - top, - bottom, - original2d, - repeat, - **kwargs, -): - conductance = raise_on_layer(value, "conductance") - elevation = raise_on_layer(value, "elevation") - - disv_cond = cache.regrid( - conductance, - method="conductance", - original2d=original2d, - ) - disv_elev = cache.regrid(elevation, original2d=original2d) - valid = (disv_cond > 0) & disv_elev.notnull() & active - location = xu.ones_like(active, dtype=float) - location = location.where((disv_elev > bottom) & (disv_elev <= top)).where(valid) - disv_cond = finish(location * disv_cond) - disv_elev = finish(location * disv_elev) - - if disv_cond.isnull().all(): - return - - drn = imod.mf6.Drainage( - elevation=disv_elev, - conductance=disv_cond, - ) - if repeat is not None: - drn.dataset["repeat_stress"] = get_repeat_stress(repeat) - model[key] = drn - return - - -def create_ghb( - cache, - model, - key, - value, - active, - original2d, - repeat, - **kwargs, -): - conductance = value["conductance"] - head = value["head"] - - disv_cond = cache.regrid( - conductance, - method="conductance", - original2d=original2d, - ) - disv_head = cache.regrid( - head, - method="barycentric", - original2d=original2d, - ) - valid = (disv_cond > 0.0) & disv_head.notnull() & active - - ghb = imod.mf6.GeneralHeadBoundary( - conductance=disv_cond.where(valid), - head=disv_head.where(valid), - ) - if repeat is not None: - ghb.dataset["repeat_stress"] = get_repeat_stress(repeat) - model[key] = ghb - return - - -def create_riv( - cache, - model, - key, - value, - active, - original2d, - top, - bottom, - repeat, - **kwargs, -): - def assign_to_layer( - conductance, stage, elevation, infiltration_factor, top, bottom, active - ): - """ - Assign river boundary to multiple layers. Distribute the conductance based - on the vertical degree of overlap. - - Parameters - ---------- - conductance - stage: - water stage - elevation: - bottom elevation of the river - infiltration_factor - factor (generally <1) to reduce infiltration conductance compared - to drainage conductance. - top: - layer model top elevation - bottom: - layer model bottom elevation - active: - active or inactive cells (idomain > 0) - """ - valid = conductance > 0.0 - conductance = conductance.where(valid) - stage = stage.where(valid) - elevation = elevation.where(valid) - elevation = elevation.where(elevation <= stage, other=stage) - - # TODO: this removes too much when the stage is higher than the top... - # Instead: just cut through all layers until the bottom elevation. - # Then, assign a transmissivity weighted conductance. - water_top = stage.where(stage <= top) - water_bottom = elevation.where(elevation > bottom) - layer_height = top - bottom - layer_height = layer_height.where(active) # avoid 0 thickness layers - fraction = (water_top - water_bottom) / layer_height - # Set values of 0.0 to 1.0, but do not change NaN values: - fraction = fraction.where(~(fraction == 0.0), other=1.0) - location = xu.ones_like(fraction).where(fraction.notnull() & active) - - layered_conductance = finish(conductance * fraction) - layered_stage = finish(stage * location) - layered_elevation = finish(elevation * location) - infiltration_factor = finish(infiltration_factor * location) - - return ( - layered_conductance, - layered_stage, - layered_elevation, - infiltration_factor, - ) - - conductance = raise_on_layer(value, "conductance") - stage = raise_on_layer(value, "stage") - bottom_elevation = raise_on_layer(value, "bottom_elevation") - infiltration_factor = raise_on_layer(value, "infiltration_factor") - - disv_cond_2d = cache.regrid( - conductance, - method="conductance", - original2d=original2d, - ).compute() - disv_elev_2d = cache.regrid(bottom_elevation, original2d=original2d) - disv_stage_2d = cache.regrid(stage, original2d=original2d) - disv_inff_2d = cache.regrid(infiltration_factor, original2d=original2d) - - disv_cond, disv_stage, disv_elev, disv_inff = assign_to_layer( - conductance=disv_cond_2d, - stage=disv_stage_2d, - elevation=disv_elev_2d, - infiltration_factor=disv_inff_2d, - top=top, - bottom=bottom, - active=active, - ) - - if disv_cond.isnull().all(): - return - - # The infiltration factor may be 0. In that case, we need only create a DRN - # package. - drn = imod.mf6.Drainage( - conductance=(1.0 - disv_inff) * disv_cond, - elevation=disv_stage, - ) - if repeat is not None: - drn.dataset["repeat_stress"] = get_repeat_stress(repeat) - model[f"{key}-drn"] = drn - - riv_cond = disv_cond * disv_inff - riv_valid = riv_cond > 0.0 - if not riv_valid.any(): - return - - riv = imod.mf6.River( - stage=disv_stage.where(riv_valid), - conductance=riv_cond.where(riv_valid), - bottom_elevation=disv_elev.where(riv_valid), - ) - if repeat is not None: - riv.dataset["repeat_stress"] = get_repeat_stress(repeat) - model[key] = riv - - return - - -def create_rch( - cache, - model, - key, - value, - active, - original2d, - repeat, - **kwargs, -): - rate = raise_on_layer(value, "rate") * 0.001 - disv_rate = cache.regrid(rate, original2d=original2d).where(active) - # Find highest active layer - location = get_upper_active_grid_cells(active) - disv_rate = finish(disv_rate.where(location)) - - # Skip if there's no data - if disv_rate.isnull().all(): - return - - rch = imod.mf6.Recharge(rate=disv_rate) - if repeat is not None: - rch.dataset["repeat_stress"] = get_repeat_stress(repeat) - model[key] = rch - return - - -def create_evt( - cache, - model, - key, - value, - active, - original2d, - repeat, - **kwargs, -): - surface = raise_on_layer(value, "surface") - rate = raise_on_layer(value, "rate") * 0.001 - depth = raise_on_layer(value, "depth") - - # Find highest active layer - highest = active["layer"] == active["layer"].where(active).min() - location = highest.where(highest) - - disv_surface = cache.regrid(surface, original2d=original2d).where(active) - disv_surface = finish(disv_surface * location) - - disv_rate = cache.regrid(rate, original2d=original2d).where(active) - disv_rate = finish(disv_rate * location) - - disv_depth = cache.regrid(depth, original2d=original2d).where(active) - disv_depth = finish(disv_depth * location) - - # At depth 1.0, the rate is 0.0. - proportion_depth = xu.ones_like(disv_surface).where(disv_surface.notnull()) - proportion_rate = xu.zeros_like(disv_surface).where(disv_surface.notnull()) - - evt = imod.mf6.Evapotranspiration( - surface=disv_surface, - rate=disv_rate, - depth=disv_depth, - proportion_rate=proportion_rate, - proportion_depth=proportion_depth, - ) - if repeat is not None: - evt.dataset["repeat_stress"] = get_repeat_stress(repeat) - model[key] = evt - return - - -def create_sto( - cache, - storage_coefficient, - active, - original2d, - transient, -): - if storage_coefficient is None: - disv_coef = 0.0 - else: - disv_coef = cache.regrid(storage_coefficient, original2d=original2d).where( - active - ) - - sto = imod.mf6.StorageCoefficient( - storage_coefficient=disv_coef, - specific_yield=0.0, - transient=transient, - convertible=0, - ) - return sto - - -def create_wel( - cache, - model, - key, - value, - active, - top, - bottom, - k, - repeat, - **kwargs, -): - target = cache.target - dataframe = value["dataframe"] - layer = value["layer"] - - if layer <= 0: - dataframe = imod.prepare.assign_wells( - wells=dataframe, - top=top, - bottom=bottom, - k=k, - minimum_thickness=0.01, - minimum_k=1.0, - ) - else: - dataframe["index"] = np.arange(len(dataframe)) - dataframe["layer"] = layer - - first = dataframe.groupby("index").first() - well_layer = first["layer"].values - xy = np.column_stack([first["x"], first["y"]]) - cell2d = target.locate_points(xy) - valid = (cell2d >= 0) & active.values[well_layer - 1, cell2d] - - cell2d = cell2d[valid] + 1 - # Skip if no wells are located inside cells - if not valid.any(): - return - - if "time" in dataframe.columns: - # Ensure the well data is rectangular. - time = np.unique(dataframe["time"].values) - dataframe = dataframe.set_index("time") - # First ffill, then bfill! - dfs = [df.reindex(time).ffill().bfill() for _, df in dataframe.groupby("index")] - rate = ( - pd.concat(dfs) - .reset_index() - .set_index(["time", "index"])["rate"] - .to_xarray() - ) - else: - rate = xr.DataArray( - dataframe["rate"], coords={"index": dataframe["index"]}, dims=["index"] - ) - - # Don't forget to remove the out-of-bounds points. - rate = rate.where(xr.DataArray(valid, dims=["index"]), drop=True) - - wel = imod.mf6.WellDisVertices( - layer=well_layer, - cell2d=cell2d, - rate=rate, - ) - if repeat is not None: - wel.dataset["repeat_stress"] = get_repeat_stress(repeat) - - model[key] = wel - return - - -def create_ic(cache, model, key, value, active, **kwargs): - start = value["head"] - disv_start = cache.regrid(source=start, method="barycentric").where(active) - model[key] = imod.mf6.InitialConditions(start=disv_start) - return - - -def create_hfb( - model: Modflow6Model, - key: str, - value: Dict, - top: GridDataArray, - bottom: GridDataArray, - **kwargs, -) -> None: - dataframe = value["geodataframe"] - - barrier_gdf = gpd.GeoDataFrame( - geometry=dataframe["geometry"].values, - data={ - "resistance": dataframe["resistance"].values, - "layer": value["layer"], - }, - ) - - model[key] = imod.mf6.SingleLayerHorizontalFlowBarrierResistance(barrier_gdf) - - -PKG_CONVERSION = { - "chd": create_chd, - "drn": create_drn, - "evt": create_evt, - "ghb": create_ghb, - "hfb": create_hfb, - "shd": create_ic, - "rch": create_rch, - "riv": create_riv, - "wel": create_wel, -} - - -def convert_to_disv( - projectfile_data, target, time_min=None, time_max=None, repeat_stress=None -): - """ - Convert the contents of a project file to a MODFLOW6 DISV model. - - The ``time_min`` and ``time_max`` are **both** required when - ``repeat_stress`` is given. The entries in the Periods section of the - project file will be expanded to yearly repeats between ``time_min`` and - ``time_max``. - - Additionally, ``time_min`` and ``time_max`` may be used to slice the input - to a specific time domain. - - The returned model is steady-state if none of the packages contain a time - dimension. The model is transient if any of the packages contain a time - dimension. This can be changed by setting the "transient" value in the - storage package of the returned model. Storage coefficient input is - required for a transient model. - - Parameters - ---------- - projectfile_data: dict - Dictionary with the projectfile topics as keys, and the data - as xarray.DataArray, pandas.DataFrame, or geopandas.GeoDataFrame. - target: xu.Ugrid2d - The unstructured target topology. All data is transformed to match this - topology. - time_min: datetime, optional - Minimum starting time of a stress. - Required when ``repeat_stress`` is provided. - time_max: datetime, optional - Maximum starting time of a stress. - Required when ``repeat_stress`` is provided. - repeat_stress: dict of dict of string to datetime, optional - This dict contains contains, per topic, the period alias (a string) to - its datetime. - - Returns - ------- - disv_model: imod.mf6.GroundwaterFlowModel - - """ - if repeat_stress is not None: - if time_min is None or time_max is None: - raise ValueError( - "time_min and time_max are required when repeat_stress is given" - ) - - for arg in (time_min, time_max): - if arg is not None and not isinstance(arg, datetime): - raise TypeError( - "time_min and time_max must be datetime.datetime. " - f"Received: {type(arg).__name__}" - ) - - data = projectfile_data.copy() - model = imod.mf6.GroundwaterFlowModel() - - # Setup the regridding weights cache. - weights_cache = SingularTargetRegridderWeightsCache(data, target, cache_size=5) - - # Mandatory packages first. - ibound = data["bnd"]["ibound"].compute() - disv, top, bottom, active, original2d = create_disv( - cache=weights_cache, - top=data["top"]["top"], - bottom=data["bot"]["bottom"], - ibound=ibound, - ) - - npf = create_npf( - cache=weights_cache, - k=data["khv"]["kh"], - vertical_anisotropy=data["kva"]["vertical_anisotropy"], - active=active, - original2d=original2d, - ) - - model["npf"] = npf - model["disv"] = disv - model["oc"] = imod.mf6.OutputControl(save_head="all") - - # Used in other package construction: - k = npf["k"].compute() - new_ibound = weights_cache.regrid(source=ibound, method="minimum").compute() - - # Boundary conditions, one by one. - for key, value in data.items(): - pkg = key.split("-")[0] - convert = PKG_CONVERSION.get(pkg) - # Skip unsupported packages - if convert is None: - continue - - if repeat_stress is None: - repeat = None - else: - repeat = repeat_stress.get(key) - if repeat is not None: - repeat = expand_repetitions(repeat, time_min, time_max) - - try: - # conversion will update model instance - convert( - cache=weights_cache, - model=model, - key=key, - value=value, - ibound=new_ibound, - active=active, - original2d=original2d, - top=top, - bottom=bottom, - k=k, - repeat=repeat, - ) - except Exception as e: - raise type(e)(f"{e}\nduring conversion of {key}") - - transient = any("time" in pkg.dataset.dims for pkg in model.values()) - if transient and (time_min is not None or time_max is not None): - model = model.clip_box(time_min=time_min, time_max=time_max) - - sto_entry = data.get("sto") - if sto_entry is None: - if transient: - raise ValueError("storage input is required for a transient run") - storage_coefficient = None - else: - storage_coefficient = sto_entry["storage_coefficient"] - - model["sto"] = create_sto( - cache=weights_cache, - storage_coefficient=storage_coefficient, - active=active, - original2d=original2d, - transient=transient, - ) - - return model diff --git a/imod/formats/prj/prj.py b/imod/formats/prj/prj.py index 192006d6e..147463b13 100644 --- a/imod/formats/prj/prj.py +++ b/imod/formats/prj/prj.py @@ -5,6 +5,8 @@ import shlex import textwrap from collections import defaultdict +from dataclasses import asdict, dataclass +from dataclasses import field as data_field from datetime import datetime from itertools import chain from os import PathLike @@ -799,10 +801,34 @@ def _read_package_gen( return out +@dataclass +class IpfResult: + has_associated: bool = data_field(default_factory=bool) + dataframe: list[pd.DataFrame] = data_field(default_factory=list) + layer: list[int] = data_field(default_factory=list) + time: list[str] = data_field(default_factory=list) + factor: list[float] = data_field(default_factory=list) + addition: list[float] = data_field(default_factory=list) + + def append( + self, + dataframe: pd.DataFrame, + layer: int, + time: str, + factor: float, + addition: float, + ): + self.dataframe.append(dataframe) + self.layer.append(layer) + self.time.append(time) + self.factor.append(factor) + self.addition.append(addition) + + def _read_package_ipf( block_content: Dict[str, Any], periods: Dict[str, datetime] -) -> Tuple[List[Dict[str, Any]], List[datetime]]: - out = [] +) -> Tuple[Dict[str, Dict], List[datetime]]: + out = defaultdict(IpfResult) repeats = [] # we will store in this set the tuples of (x, y, id, well_top, well_bot) @@ -825,14 +851,16 @@ def _read_package_ipf( ipf_df, indexcol, ext = _try_read_with_func(imod.ipf._read_ipf, path) if indexcol == 0: # No associated files + has_associated = False columns = ("x", "y", "rate") if layer <= 0: df = ipf_df.iloc[:, :5] - columns = columns + ("top", "bottom") + columns = columns + ("filt_top", "filt_bot") else: df = ipf_df.iloc[:, :3] df.columns = columns else: + has_associated = True dfs = [] for row in ipf_df.itertuples(): filename = row[indexcol] @@ -878,14 +906,12 @@ def _read_package_ipf( df = pd.concat(dfs, ignore_index=True, sort=False) df["rate"] = df["rate"] * factor + addition - d = { - "dataframe": df, - "layer": layer, - "time": time, - } - out.append(d) + out[path.stem].has_associated = has_associated + out[path.stem].append(df, layer, time, factor, addition) + + out_dict_ls: dict[str, dict] = {key: asdict(o) for key, o in out.items()} repeats = sorted(repeats) - return out, repeats + return out_dict_ls, repeats def read_projectfile(path: FilePath) -> Dict[str, Any]: @@ -1038,7 +1064,12 @@ def open_projectfile_data(path: FilePath) -> Dict[str, Any]: raise type(e)(f"{e}. Errored while opening/reading data entries for: {key}") strippedkey = key.strip("(").strip(")") - if len(data) > 1: + if strippedkey == "wel": + for key, d in data.items(): + named_key = f"{strippedkey}-{key}" + prj_data[named_key] = d + repeat_stress[named_key] = repeats + elif len(data) > 1: for i, da in enumerate(data): numbered_key = f"{strippedkey}-{i + 1}" prj_data[numbered_key] = da diff --git a/imod/mf6/model_gwf.py b/imod/mf6/model_gwf.py index 1abfd05c3..c83bfd9bb 100644 --- a/imod/mf6/model_gwf.py +++ b/imod/mf6/model_gwf.py @@ -291,8 +291,8 @@ def from_imod5_data( imod5_keys = list(imod5_data.keys()) wel_keys = [key for key in imod5_keys if key[0:3] == "wel"] for wel_key in wel_keys: - layer = imod5_data[wel_key]["layer"] - if layer == 0: + layer = np.array(imod5_data[wel_key]["layer"]) + if np.any(layer == 0): result[wel_key] = Well.from_imod5_data(wel_key, imod5_data, times) else: result[wel_key] = LayeredWell.from_imod5_data( diff --git a/imod/mf6/wel.py b/imod/mf6/wel.py index fb5195b0a..24153ce1c 100644 --- a/imod/mf6/wel.py +++ b/imod/mf6/wel.py @@ -1,6 +1,7 @@ from __future__ import annotations import abc +import itertools import textwrap import warnings from datetime import datetime @@ -71,20 +72,13 @@ def mask_2D(package: GridAgnosticWell, domain_2d: GridDataArray) -> GridAgnostic return cls._from_dataset(selection) -def _prepare_well_rates_from_groups( - unique_well_groups: pd.api.typing.DataFrameGroupBy, times: list[datetime] +def _df_groups_to_da_rates( + unique_well_groups: pd.api.typing.DataFrameGroupBy, ) -> xr.DataArray: - """ - Prepare well rates from dataframe groups, grouped by unique well locations. - """ - # Resample times per group - df_resampled_groups = [ - resample_timeseries(df_group, times) for df_group in unique_well_groups - ] # Convert dataframes all groups to DataArrays da_groups = [ xr.DataArray(df_group["rate"], dims=("time"), coords={"time": df_group["time"]}) - for df_group in df_resampled_groups + for df_group in unique_well_groups ] # Assign index coordinates da_groups = [ @@ -95,11 +89,117 @@ def _prepare_well_rates_from_groups( return xr.concat(da_groups, dim="index") +def _prepare_well_rates_from_groups( + pkg_data: dict, + unique_well_groups: pd.api.typing.DataFrameGroupBy, + times: list[datetime], +) -> xr.DataArray: + """ + Prepare well rates from dataframe groups, grouped by unique well locations. + Resample timeseries if ipf with associated text files. + """ + has_associated = pkg_data["has_associated"] + start_times = times[:-1] # Starts stress periods. + if has_associated: + # Resample times per group + unique_well_groups = [ + resample_timeseries(df_group, start_times) + for df_group in unique_well_groups + ] + return _df_groups_to_da_rates(unique_well_groups) + + +def _prepare_df_ipf_associated( + pkg_data: dict, start_times: list[datetime], all_well_times: list[datetime] +) -> pd.DataFrame: + """Prepare dataframe for an ipf with associated timeseries in a textfile.""" + # Validate if associated wells are assigned multiple layers, factors, + # and additions. + for entry in ["layer", "factor", "addition"]: + uniques = set(pkg_data[entry]) + if len(uniques) > 1: + raise ValueError( + f"IPF with associated textfiles assigned multiple {entry}s: {uniques}" + ) + # Validate if associated wells are defined only on first timestep or all + # timesteps + is_defined_all = len(set(all_well_times) - set(pkg_data["time"])) == 0 + is_defined_first = (len(pkg_data["time"]) == 1) & ( + pkg_data["time"][0] == all_well_times[0] + ) + if not is_defined_all and not is_defined_first: + raise ValueError( + "IPF with associated textfiles assigned to wrong times. " + "Should be assigned to all times or only first time. " + f"PRJ times: {all_well_times}, package times: {pkg_data['time']}" + ) + df = pkg_data["dataframe"][0] + df["layer"] = pkg_data["layer"][0] + return df + + +def _prepare_df_ipf_unassociated( + pkg_data: dict, start_times: list[datetime] +) -> pd.DataFrame: + """Prepare dataframe for an ipf with no associated timeseries.""" + # Concatenate dataframes, assign layer and times + iter_dfs_dims = zip(pkg_data["dataframe"], pkg_data["time"], pkg_data["layer"]) + df = pd.concat([df.assign(time=t, layer=lay) for df, t, lay in iter_dfs_dims]) + # Prepare multi-index dataframe to convert to a multi-dimensional DataArray + # later. + df_multi = df.set_index(["time", "layer", df.index]) + df_multi.index = df_multi.index.set_names(["time", "layer", "ipf_row"]) + # Temporarily convert to DataArray with 2 dimensions, as it allows for + # multi-dimensional ffilling, instead pandas' ffilling the last value in a + # column of the flattened table. + ipf_row_index = pkg_data["dataframe"][0].index + # Forward fill location columns, only reindex layer, filt_top and filt_bot + # if present. + cols_ffill_if_present = {"x", "y", "filt_top", "filt_bot"} + cols_ffill = cols_ffill_if_present & set(df.columns) + da_multi = df_multi.to_xarray() + indexers = {"time": start_times, "ipf_row": ipf_row_index} + # Multi-dimensional reindex, forward fill well locations, fill well rates + # with 0.0. + df_ffilled = da_multi[cols_ffill].reindex(indexers, method="ffill").to_dataframe() + df_fill_zero = da_multi["rate"].reindex(indexers, fill_value=0.0).to_dataframe() + # Combine columns and reset dataframe back into a simple long table with + # single index. + df_out = pd.concat([df_ffilled, df_fill_zero], axis="columns") + return df_out.reset_index().drop(columns="ipf_row") + + +def _unpack_package_data( + pkg_data: dict, times: list[datetime], all_well_times: list[datetime] +) -> pd.DataFrame: + """Unpack package data to dataframe""" + start_times = times[:-1] # Starts stress periods. + has_associated = pkg_data["has_associated"] + if has_associated: + return _prepare_df_ipf_associated(pkg_data, start_times, all_well_times) + else: + return _prepare_df_ipf_unassociated(pkg_data, start_times) + + +def get_all_imod5_prj_well_times(imod5_data: dict) -> list[datetime]: + """Get all times a well data is defined on in a prj file""" + wel_keys = [key for key in imod5_data.keys() if key.startswith("wel")] + wel_times_per_pkg = [imod5_data[wel_key]["time"] for wel_key in wel_keys] + # Flatten list + wel_times_flat = itertools.chain.from_iterable(wel_times_per_pkg) + # Get unique times by converting to set and sorting. ``sorted`` also + # transforms set to a list again. + return sorted(set(wel_times_flat)) + + class GridAgnosticWell(BoundaryCondition, IPointDataPackage, abc.ABC): """ Abstract base class for grid agnostic wells """ + _imod5_depth_colnames: list[str] = [] + _depth_colnames: list[tuple[str, type]] = [] + @property def x(self) -> npt.NDArray[np.float64]: return self.dataset["x"].values @@ -372,6 +472,127 @@ def _assign_wells_to_layers( ) -> pd.DataFrame: raise NotImplementedError("Method in abstract base class called") + @classmethod + def _validate_imod5_depth_information( + cls, key: str, pkg_data: dict, df: pd.DataFrame + ) -> None: + raise NotImplementedError("Method in abstract base class called") + + @classmethod + def from_imod5_data( + cls, + key: str, + imod5_data: dict[str, dict[str, GridDataArray]], + times: list[datetime], + minimum_k: float = 0.1, + minimum_thickness: float = 1.0, + ) -> "GridAgnosticWell": + """ + Convert wells to imod5 data, loaded with + :func:`imod.formats.prj.open_projectfile_data`, to a Well object. As + iMOD5 handles wells differently than iMOD Python normally does, some + data transformations are made, which are outlined further. + + iMOD5 stores well information in IPF files and it supports two ways to + specify injection/extraction rates: + + 1. A timeseries of well rates, in an associated text file. We will + call these "associated wells" further in this text. + 2. Constant rates in an IPF file, without an associated text file. + We will call these "unassociated wells" further in this text. + + Depending on this, iMOD5 does different things, which we need to mimic + in this method. + + *Associated wells* + + Wells with timeseries in an associated textfile are processed as + follows: + + - Wells are validated if the following requirements are met + * Associated well entries in projectfile are defined on either all + timestamps or just the first + * Multiplication and addition factors need to remain constant through time + * Same associated well cannot be assigned to multiple layers + - The dataframe of the first projectfile timestamp is selected + - Rate timeseries are resampled with a time weighted mean to the + simulation times. + - When simulation times fall outside well timeseries range, the last + rate is forward filled. + + *Unassociated wells* + + Wells without associated textfiles are processed as follows: + + - When a unassociated well disappears from the next time entry in the + projectfile, the well is deactivated by ratting its rate to 0.0. This + is to prevent the well being activated again in case of any potential + forward filling at a later stage by + :meth:`imod.mf6.Modflow6Simulation.create_time_discretization` + + .. note:: + In case you are wondering why is this so complicated? There are two + main reasons: + + - iMOD5 is inconsistent in how it treats timeseries for grid data, + compared to point data. Whereas grids are forward filled when + there is no entry specified for a time entry, unassociated wells + are deactivated. Associated wells, however, are forward filled. + - Normally there are two levels in which times are defined: The + simulation times, which are the requested times for the + simulation, and projectfile times, on which data is defined. With + associated ipfs, times are defined in three + levels: There are simulation times (in iMOD5 in the ini + file), there are projectfile times, and there are times + defined in the associated textfiles on which data is defined. + + Parameters + ---------- + + key: str + Name of the well system in the imod5 data + imod5_data: dict + iMOD5 data loaded from a projectfile with + :func:`imod.formats.prj.open_projectfile_data` + times: list + Simulation times + minimum_k: float, optional + On creating point wells, no point wells will be placed in cells with + a lower horizontal conductivity than this. Wells are placed when + ``to_mf6_pkg`` is called. + minimum_thickness: float, optional + On creating point wells, no point wells will be placed in cells with + a lower thickness than this. Wells are placed when ``to_mf6_pkg`` is + called. + """ + pkg_data = imod5_data[key] + all_well_times = get_all_imod5_prj_well_times(imod5_data) + + df = _unpack_package_data(pkg_data, times, all_well_times) + cls._validate_imod5_depth_information(key, pkg_data, df) + + # Groupby unique wells, to get dataframes per time. + colnames_group = ["x", "y"] + cls._imod5_depth_colnames + # Associated wells need additional grouping by id + if pkg_data["has_associated"]: + colnames_group.append("id") + wel_index, unique_well_groups = zip(*df.groupby(colnames_group)) + + # Unpack wel indices by zipping + varnames = [("x", float), ("y", float)] + cls._depth_colnames + index_values = zip(*wel_index) + cls_input: dict[str, Any] = { + var: np.array(value, dtype=dtype) + for (var, dtype), value in zip(varnames, index_values) + } + cls_input["rate"] = _prepare_well_rates_from_groups( + pkg_data, unique_well_groups, times + ) + cls_input["minimum_k"] = minimum_k + cls_input["minimum_thickness"] = minimum_thickness + + return cls(**cls_input) + class Well(GridAgnosticWell): """ @@ -487,6 +708,12 @@ class Well(GridAgnosticWell): "concentration": [AnyNoDataSchema(), EmptyIndexesSchema()], } + _imod5_depth_colnames: list[str] = ["filt_top", "filt_bot"] + _depth_colnames: list[tuple[str, type]] = [ + ("screen_top", float), + ("screen_bottom", float), + ] + @init_log_decorator() def __init__( self, @@ -691,57 +918,32 @@ def _assign_wells_to_layers( return wells_assigned @classmethod - def from_imod5_data( - cls, - key: str, - imod5_data: dict[str, dict[str, GridDataArray]], - times: list[datetime], - minimum_k: float = 0.1, - minimum_thickness: float = 1.0, - ) -> "Well": - pkg_data = imod5_data[key] - if "layer" in pkg_data.keys() and (pkg_data["layer"] != 0): + def _validate_imod5_depth_information( + cls, key: str, pkg_data: dict, df: pd.DataFrame + ) -> None: + if "layer" in pkg_data.keys() and (np.any(np.array(pkg_data["layer"]) != 0)): log_msg = textwrap.dedent( f""" - In well {key} a layer was assigned, but this is not supported. - Assignment will be done based on filter_top and filter_bottom, - and the chosen layer ({pkg_data["layer"]}) will be ignored. To - specify by layer, use imod.mf6.LayeredWell. + In well {key} a layer was assigned, but this is not + supported for imod.mf6.Well. Assignment will be done based on + filter_top and filter_bottom, and the chosen layer + ({pkg_data["layer"]}) will be ignored. To specify by layer, use + imod.mf6.LayeredWell. """ ) logger.log(loglevel=LogLevel.WARNING, message=log_msg, additional_depth=2) - df: pd.DataFrame = pkg_data["dataframe"] - if "filt_top" not in df.columns or "filt_bot" not in df.columns: log_msg = textwrap.dedent( f""" - In well {key} the filt_top and filt_bot columns were not both - found; this is not supported for import. To specify by layer, - use imod.mf6.LayeredWell. + In well {key} the 'filt_top' and 'filt_bot' columns were + not both found; this is not supported for import. To specify by + layer, use imod.mf6.LayeredWell. """ ) logger.log(loglevel=LogLevel.ERROR, message=log_msg, additional_depth=2) raise ValueError(log_msg) - # Groupby unique wells, to get dataframes per time. - colnames_group = ["x", "y", "filt_top", "filt_bot", "id"] - wel_index, unique_well_groups = zip(*df.groupby(colnames_group)) - - # Unpack wel indices by zipping - x, y, filt_top, filt_bot, id = zip(*wel_index) - well_rate = _prepare_well_rates_from_groups(unique_well_groups, times) - - return cls( - x=np.array(x, dtype=float), - y=np.array(y, dtype=float), - screen_top=np.array(filt_top, dtype=float), - screen_bottom=np.array(filt_bot, dtype=float), - rate=well_rate, - minimum_k=minimum_k, - minimum_thickness=minimum_thickness, - ) - class LayeredWell(GridAgnosticWell): """ @@ -848,6 +1050,8 @@ class LayeredWell(GridAgnosticWell): "rate": [AnyNoDataSchema(), EmptyIndexesSchema()], "concentration": [AnyNoDataSchema(), EmptyIndexesSchema()], } + _imod5_depth_colnames: list[str] = ["layer"] + _depth_colnames: list[tuple[str, type]] = [("layer", int)] @init_log_decorator() def __init__( @@ -970,43 +1174,28 @@ def _assign_wells_to_layers( return wells_df @classmethod - def from_imod5_data( - cls, - key: str, - imod5_data: dict[str, dict[str, GridDataArray]], - times: list[datetime], - minimum_k: float = 0.1, - minimum_thickness: float = 1.0, - ) -> "LayeredWell": - pkg_data = imod5_data[key] - - if ("layer" not in pkg_data.keys()) or (pkg_data["layer"] == 0): + def _validate_imod5_depth_information( + cls, key: str, pkg_data: dict, df: pd.DataFrame + ) -> None: + if np.any(np.array(pkg_data["layer"]) == 0): log_msg = textwrap.dedent( - f"""In well {key} no layer was assigned, but this is required.""" + f""" + Well {key} in projectfile is assigned to layer 0, but should be > + 0 for LayeredWell + """ ) logger.log(loglevel=LogLevel.ERROR, message=log_msg, additional_depth=2) + raise ValueError(log_msg) - df: pd.DataFrame = pkg_data["dataframe"] - - # Add layer to dataframe. - df["layer"] = pkg_data["layer"] - - # Groupby unique wells, to get dataframes per time. - colnames_group = ["x", "y", "layer", "id"] - wel_index, unique_well_groups = zip(*df.groupby(colnames_group)) - - # Unpack wel indices by zipping - x, y, layer, id = zip(*wel_index) - well_rate = _prepare_well_rates_from_groups(unique_well_groups, times) - - return cls( - x=np.array(x, dtype=float), - y=np.array(y, dtype=float), - layer=np.array(layer, dtype=int), - rate=well_rate, - minimum_k=minimum_k, - minimum_thickness=minimum_thickness, - ) + if "layer" not in df.columns: + log_msg = textwrap.dedent( + f""" + IPF file {key} has no layer assigned, but this is required + for LayeredWell. + """ + ) + logger.log(loglevel=LogLevel.ERROR, message=log_msg, additional_depth=2) + raise ValueError(log_msg) class WellDisStructured(DisStructuredBoundaryCondition): diff --git a/imod/tests/conftest.py b/imod/tests/conftest.py index 4ec724725..d6bf65a6a 100644 --- a/imod/tests/conftest.py +++ b/imod/tests/conftest.py @@ -24,6 +24,7 @@ from .fixtures.flow_transport_simulation_fixture import flow_transport_simulation from .fixtures.imod5_well_data import ( well_duplication_import_prj, + well_mixed_ipfs, well_regular_import_prj, ) from .fixtures.mf6_circle_fixture import ( diff --git a/imod/tests/fixtures/imod5_well_data.py b/imod/tests/fixtures/imod5_well_data.py index f4904d383..3bddb7a42 100644 --- a/imod/tests/fixtures/imod5_well_data.py +++ b/imod/tests/fixtures/imod5_well_data.py @@ -6,7 +6,7 @@ import imod -ipf_header = textwrap.dedent( +ipf_associated_header = textwrap.dedent( """\ 3 18 @@ -31,6 +31,23 @@ 3,txt """ ) +ipf_simple_header = textwrap.dedent( + """\ + 13 + 9 + xcoord + ycoord + q_assigned + top + bot + col + row + lay + whichmodel + 0,txt + """ +) + def projectfile_string(tmp_path): return textwrap.dedent( @@ -47,7 +64,7 @@ def projectfile_string(tmp_path): def ipf1_string_no_duplication(): return textwrap.dedent( f"""\ - {ipf_header} + {ipf_associated_header} 191231.52,406381.47,timeseries_wel1,4.11,-1.69,01-PP001,0,B46D0517,"30-11-1981 00:00",13.41,13.41,nan,Inactive,Vertical,"Oxmeer","User1 - Zeeland Water","Oxmeer","Zeeland Water" 191171.96,406420.89,timeseries_wel1,3.78,-2.02,01-PP002,0,B46D0518,"30-11-1981 00:00",13.18,13.18,nan,Inactive,Vertical,"Oxmeer","User1 - Zeeland Water","Oxmeer","Zeeland Water" 191112.11,406460.02,timeseries_wel1,3.81,-1.99,01-PP003,0,B46D0519,"30-11-1981 00:00",13.21,13.21,nan,Inactive,Vertical,"Oxmeer","User1 - Zeeland Water","Oxmeer","Zeeland Water" @@ -58,7 +75,7 @@ def ipf1_string_no_duplication(): def ipf1_string_duplication(): return textwrap.dedent( f"""\ - {ipf_header} + {ipf_associated_header} 191231.52,406381.47,timeseries_wel1,4.11,-1.69,01-PP001,0,B46D0517,"30-11-1981 00:00",13.41,13.41,nan,Inactive,Vertical,"Oxmeer","User1 - Zeeland Water","Oxmeer","Zeeland Water" 191171.96,406420.89,timeseries_wel1,3.78,-2.02,01-PP002,0,B46D0518,"30-11-1981 00:00",13.18,13.18,nan,Inactive,Vertical,"Oxmeer","User1 - Zeeland Water","Oxmeer","Zeeland Water" 191231.52,406381.47,other_timeseries_wel1,4.11,-1.69,01-PP001,0,B46D0517,"30-11-1981 00:00",13.41,13.41,nan,Inactive,Vertical,"Oxmeer","User1 - Zeeland Water","Oxmeer","Zeeland Water" @@ -69,7 +86,7 @@ def ipf1_string_duplication(): def ipf2_string(): return textwrap.dedent( f"""\ - {ipf_header} + {ipf_associated_header} 191231.52,406381.47,timeseries_wel1,4.11,-1.69,01-PP001,0,B46D0517,"30-11-1981 00:00",13.41,13.41,nan,Inactive,Vertical,"Oxmeer","User1 - Zeeland Water","Oxmeer","Zeeland Water" 191171.96,406420.89,timeseries_wel1,3.78,-2.02,01-PP002,0,B46D0518,"30-11-1981 00:00",13.18,13.18,nan,Inactive,Vertical,"Oxmeer","User1 - Zeeland Water","Oxmeer","Zeeland Water" 191112.11,406460.02,timeseries_wel1,3.81,-1.99,01-PP003,0,B46D0519,"30-11-1981 00:00",13.21,13.21,nan,Inactive,Vertical,"Oxmeer","User1 - Zeeland Water","Oxmeer","Zeeland Water" @@ -77,10 +94,32 @@ def ipf2_string(): ) +def ipf_simple_string(): + return textwrap.dedent( + f"""\ + {ipf_simple_header} + 276875.0,584375.0,-0.2,1.7,1.7,1107,162,1,4.0 + 276875.0,584125.0,-0.1,4.7,4.7,1107,163,1,4.0 + 276625.0,583875.0,-0.0,0.07,0.07,1106,164,1,4.0 + 276875.0,583625.0,-0.1,-0.26,-0.26,1107,165,1,4.0 + 276875.0,583375.0,-0.4,-2.65,-2.65,1107,166,1,4.0 + 276875.0,583125.0,-0.1,3.1,3.1,1107,167,1,4.0 + 277125.0,582875.0,-0.9,-0.45,-0.45,1108,168,1,4.0 + 277125.0,582625.0,-0.6,-2.65,-2.65,1108,169,1,4.0 + 277125.0,582375.0,-0.3,-2.65,-2.65,1108,170,1,4.0 + 277125.0,582125.0,-0.2,-2.65,-2.65,1108,171,1,4.0 + 277125.0,581875.0,-0.2,-2.65,-2.65,1108,172,1,4.0 + 277125.0,581625.0,-0.3,2.54,2.54,1108,173,1,4.0 + 277125.0,581375.0,0.2,1.6,1.6,1108,174,1,4.0 + 277125.0,581125.0,0.5,0.6,0.6,1108,175,1,4.0 + """ + ) + + def timeseries_string(): return textwrap.dedent( """\ - 374 + 6 2 DATE,-9999.0 MEASUREMENT,-9999.0 @@ -97,7 +136,7 @@ def timeseries_string(): def other_timeseries_string(): return textwrap.dedent( """\ - 374 + 6 2 DATE,-9999.0 MEASUREMENT,-9999.0 @@ -111,7 +150,7 @@ def other_timeseries_string(): ) -def write_files( +def write_ipf_assoc_files( projectfile_str, ipf1_str, ipf2_str, @@ -138,6 +177,28 @@ def write_files( return Path(tmp_path) / "projectfile.prj" +def write_ipf_mixed_files( + ipf_assoc_str, ipf_simple_str, timeseries_wel1_str, other_timeseries_str, tmp_path +): + file_dict = { + "associated.ipf": ipf_assoc_str, + "simple1.ipf": ipf_simple_str, + "simple2.ipf": ipf_simple_str, + "simple3.ipf": ipf_simple_str, + "timeseries_wel1.txt": timeseries_wel1_str, + "other_timeseries_wel1.txt": other_timeseries_str, + } + + paths = [] + for file, string in file_dict.items(): + path = Path(tmp_path) / file + paths.append(path) + with open(path, "w") as f: + f.write(string) + + return paths + + @pytest.fixture(scope="session") def well_regular_import_prj(): tmp_path = imod.util.temporary_directory() @@ -148,7 +209,7 @@ def well_regular_import_prj(): ipf2_str = ipf2_string() timeseries_well_str = timeseries_string() - return write_files( + return write_ipf_assoc_files( projectfile_str, ipf1_str, ipf2_str, timeseries_well_str, tmp_path ) @@ -163,7 +224,7 @@ def well_duplication_import_prj(): ipf2_str = ipf2_string() timeseries_well_str = timeseries_string() other_timeseries_well_str = other_timeseries_string() - return write_files( + return write_ipf_assoc_files( projectfile_str, ipf1_str, ipf2_str, @@ -171,3 +232,22 @@ def well_duplication_import_prj(): tmp_path, other_timeseries_well_str, ) + + +@pytest.fixture(scope="session") +def well_mixed_ipfs(): + tmp_path = imod.util.temporary_directory() + os.makedirs(tmp_path) + + ipf_assoc_str = ipf1_string_duplication() + ipf_simple_str = ipf_simple_string() + timeseries_well_str = timeseries_string() + other_timeseries_well_str = other_timeseries_string() + + return write_ipf_mixed_files( + ipf_assoc_str, + ipf_simple_str, + timeseries_well_str, + other_timeseries_well_str, + tmp_path, + ) diff --git a/imod/tests/test_formats/test_disv_conversion.py b/imod/tests/test_formats/test_disv_conversion.py deleted file mode 100644 index 2b7dbb950..000000000 --- a/imod/tests/test_formats/test_disv_conversion.py +++ /dev/null @@ -1,69 +0,0 @@ -import numpy as np -import pytest -import xugrid as xu - -import imod - -# xugrid 0.5.0 introduced a bug which prevents disv_converter from functioning -# properly. Skip if this one occurs. -xu_version_to_skip = (xu.__version__ == "0.5.0") | (xu.__version__ < "0.4.0") - - -def create_quadgrid(ibound): - return xu.Ugrid2d.from_structured(ibound) - - -def create_trigrid(ibound): - import matplotlib - - dx, xmin, xmax, dy, ymin, ymax = imod.util.spatial.spatial_reference(ibound) - x = np.arange(xmin, xmax + dx, dx) - y = np.arange(ymin, ymax + abs(dy), abs(dy)) - node_y, node_x = [a.ravel() for a in np.meshgrid(x, y, indexing="ij")] - triangulation = matplotlib.tri.Triangulation(node_x, node_y) - grid = xu.Ugrid2d(node_x, node_y, -1, triangulation.triangles) - return grid - - -@pytest.mark.usefixtures("imodflow_model") -@pytest.mark.parametrize("create_grid", [create_quadgrid, create_trigrid]) -def test_convert_to_disv(imodflow_model, tmp_path, create_grid): - imodflow_model.write(tmp_path / "imodflow") - - data, repeats = imod.prj.open_projectfile_data(tmp_path / "imodflow/imodflow.prj") - tim_data = imod.prj.read_timfile(tmp_path / "imodflow/time_discretization.tim") - times = sorted([d["time"] for d in tim_data]) - target = create_grid(data["bnd"]["ibound"]) - - disv_model = imod.prj.convert_to_disv( - projectfile_data=data, - target=target, - time_min=times[0], - time_max=times[-1], - repeat_stress=repeats, - ) - - simulation = imod.mf6.Modflow6Simulation(name="disv") - simulation["gwf"] = disv_model - simulation["solver"] = imod.mf6.Solution( - modelnames=["gwf"], - print_option="summary", - outer_dvclose=1.0e-4, - outer_maximum=500, - under_relaxation=None, - inner_dvclose=1.0e-4, - inner_rclose=0.001, - inner_maximum=100, - linear_acceleration="cg", - scaling_method=None, - reordering_method=None, - relaxation_factor=0.97, - ) - simulation.create_time_discretization(times) - - modeldir = tmp_path / "disv" - simulation.write(modeldir) - simulation.run() - - head = imod.mf6.open_hds(modeldir / "gwf/gwf.hds", modeldir / "gwf/disv.disv.grb") - assert isinstance(head, xu.UgridDataArray) diff --git a/imod/tests/test_formats/test_prj.py b/imod/tests/test_formats/test_prj.py index 9aebf1a5a..296baef79 100644 --- a/imod/tests/test_formats/test_prj.py +++ b/imod/tests/test_formats/test_prj.py @@ -527,8 +527,8 @@ def test_open_projectfile_data(self): assert isinstance(content["ghb"]["head"], xr.DataArray) assert isinstance(content["rch"]["rate"], xr.DataArray) assert isinstance(content["cap"]["landuse"], xr.DataArray) - assert isinstance(content["wel-1"]["dataframe"], pd.DataFrame) - assert isinstance(content["wel-2"]["dataframe"], pd.DataFrame) + assert isinstance(content["wel-wells_l1"]["dataframe"][0], pd.DataFrame) + assert isinstance(content["wel-wells_l2"]["dataframe"][0], pd.DataFrame) assert isinstance(content["hfb-1"]["geodataframe"], gpd.GeoDataFrame) assert isinstance(content["hfb-2"]["geodataframe"], gpd.GeoDataFrame) assert isinstance(content["pcg"], dict) diff --git a/imod/tests/test_formats/test_prj_wel.py b/imod/tests/test_formats/test_prj_wel.py new file mode 100644 index 000000000..d05470c0c --- /dev/null +++ b/imod/tests/test_formats/test_prj_wel.py @@ -0,0 +1,780 @@ +from datetime import datetime +from shutil import copyfile +from textwrap import dedent +from typing import Union + +import numpy as np +import pytest +from pytest_cases import ( + get_all_cases, + get_parametrize_args, + parametrize, + parametrize_with_cases, +) + +from imod.formats.prj import open_projectfile_data +from imod.mf6 import LayeredWell, Well + + +class WellPrjCases: + """Cases for projectfile well records""" + + def case_simple__first(self): + return dedent( + """ + 0001,(WEL),1 + 1982-01-01 + 001,001 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + """ + ) + + def case_simple__first_multi_layer1(self): + return dedent( + """ + 0001,(WEL),1 + 1982-01-01 + 001,002 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + 1,2, 002, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + """ + ) + + def case_simple__first_multi_layer2(self): + return dedent( + """ + 0001,(WEL),1 + 1982-01-01 + 001,002 + 1,2, 000, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + """ + ) + + def case_simple__all_same(self): + return dedent( + """ + 0003,(WEL),1 + 1982-01-01 + 001,001 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + 1982-02-01 + 001,001 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + 1982-03-01 + 001,001 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + """ + ) + + def case_simple__all_same_multi_layer1(self): + return dedent( + """ + 0003,(WEL),1 + 1982-01-01 + 001,002 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + 1,2, 002, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + 1982-02-01 + 001,002 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + 1,2, 002, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + 1982-03-01 + 001,002 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + 1,2, 002, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + """ + ) + + def case_simple__all_same_multi_layer2(self): + return dedent( + """ + 0003,(WEL),1 + 1982-01-01 + 001,002 + 1,2, 000, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + 1982-02-01 + 001,002 + 1,2, 000, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + 1982-03-01 + 001,002 + 1,2, 000, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + """ + ) + + def case_simple__all_different1(self): + return dedent( + """ + 0003,(WEL),1 + 1982-01-01 + 001,001 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + 1982-02-01 + 001,001 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple2.ipf" + 1982-03-01 + 001,001 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple3.ipf" + """ + ) + + def case_simple__all_different2(self): + return dedent( + """ + 0003,(WEL),1 + 1982-01-01 + 001,001 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + 1982-02-01 + 001,002 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple2.ipf" + 1982-03-01 + 001,001 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple3.ipf" + """ + ) + + def case_simple__all_different3(self): + return dedent( + """ + 0003,(WEL),1 + 1982-01-01 + 001,001 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + 1982-02-01 + 001,001 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple2.ipf" + 1982-03-01 + 001,002 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple3.ipf" + """ + ) + + def case_associated__first(self): + return dedent( + """ + 0001,(WEL),1 + 1982-01-01 + 001,001 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/associated.ipf" + """ + ) + + def case_associated__all(self): + return dedent( + """ + 0003,(WEL),1 + 1982-01-01 + 001,001 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/associated.ipf" + 1982-02-01 + 001,001 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/associated.ipf" + 1982-03-01 + 001,001 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/associated.ipf" + """ + ) + + def case_associated__all_varying_factors(self): + return dedent( + """ + 0003,(WEL),1 + 1982-01-01 + 001,001 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/associated.ipf" + 1982-02-01 + 001,001 + 1,2, 001, 0.5, 0.0, -999.9900 ,"ipf/associated.ipf" + 1982-03-01 + 001,001 + 1,2, 001, 0.2, 0.0, -999.9900 ,"ipf/associated.ipf" + """ + ) + + def case_associated__multiple_layers_different_factors(self): + return dedent( + """ + 0001,(WEL),1 + 1982-01-01 + 001,002 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/associated.ipf" + 1,2, 002, 0.75, 0.0, -999.9900 ,"ipf/associated.ipf" + """ + ) + + def case_mixed__first(self): + return dedent( + """ + 0001,(WEL),1 + 1982-01-01 + 001,002 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/associated.ipf" + """ + ) + + def case_mixed__all(self): + return dedent( + """ + 0003,(WEL),1 + 1982-01-01 + 001,001 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/associated.ipf" + 1982-02-01 + 001,002 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/associated.ipf" + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + 1982-03-01 + 001,001 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/associated.ipf" + """ + ) + + def case_mixed__associated_second(self): + return dedent( + """ + 0002,(WEL),1 + 1982-01-01 + 001,001 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + 1982-02-01 + 001,001 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/associated.ipf" + """ + ) + + +class WellReadCases: + """Expected cases as interpreted by ``imod.formats.prj.open_projectfile_data``""" + + def case_simple__first(self): + return { + "wel-simple1": { + "has_associated": False, + "time": [datetime(1982, 1, 1)], + "layer": [1], + "factor": [1.0], + "addition": [0.0], + }, + } + + def case_simple__first_multi_layer1(self): + return { + "wel-simple1": { + "has_associated": False, + "time": [datetime(1982, 1, 1), datetime(1982, 1, 1)], + "layer": [1, 2], + "factor": [1.0, 1.0], + "addition": [0.0, 0.0], + }, + } + + def case_simple__first_multi_layer2(self): + return { + "wel-simple1": { + "has_associated": False, + "time": [datetime(1982, 1, 1), datetime(1982, 1, 1)], + "layer": [0, 1], + "factor": [1.0, 1.0], + "addition": [0.0, 0.0], + }, + } + + def case_simple__all_same(self): + return { + "wel-simple1": { + "has_associated": False, + "time": [ + datetime(1982, 1, 1), + datetime(1982, 2, 1), + datetime(1982, 3, 1), + ], + "layer": [1, 1, 1], + "factor": [1.0, 1.0, 1.0], + "addition": [0.0, 0.0, 0.0], + }, + } + + def case_simple__all_same_multi_layer1(self): + return { + "wel-simple1": { + "has_associated": False, + "time": [ + datetime(1982, 1, 1), + datetime(1982, 1, 1), + datetime(1982, 2, 1), + datetime(1982, 2, 1), + datetime(1982, 3, 1), + datetime(1982, 3, 1), + ], + "layer": [1, 2, 1, 2, 1, 2], + "factor": [1.0, 1.0, 1.0, 1.0, 1.0, 1.0], + "addition": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + }, + } + + def case_simple__all_same_multi_layer2(self): + return { + "wel-simple1": { + "has_associated": False, + "time": [ + datetime(1982, 1, 1), + datetime(1982, 1, 1), + datetime(1982, 2, 1), + datetime(1982, 2, 1), + datetime(1982, 3, 1), + datetime(1982, 3, 1), + ], + "layer": [0, 1, 0, 1, 0, 1], + "factor": [1.0, 1.0, 1.0, 1.0, 1.0, 1.0], + "addition": [0.0, 0.0, 0.0, 0.0, 0.0, 0.0], + }, + } + + def case_simple__all_different1(self): + return { + "wel-simple1": { + "has_associated": False, + "time": [datetime(1982, 1, 1)], + "layer": [1], + "factor": [1.0], + "addition": [0.0], + }, + "wel-simple2": { + "has_associated": False, + "time": [datetime(1982, 2, 1)], + "layer": [1], + "factor": [1.0], + "addition": [0.0], + }, + "wel-simple3": { + "has_associated": False, + "time": [datetime(1982, 3, 1)], + "layer": [1], + "factor": [1.0], + "addition": [0.0], + }, + } + + def case_simple__all_different2(self): + return { + "wel-simple1": { + "has_associated": False, + "time": [datetime(1982, 1, 1), datetime(1982, 2, 1)], + "layer": [1, 1], + "factor": [1.0, 1.0], + "addition": [0.0, 0.0], + }, + "wel-simple2": { + "has_associated": False, + "time": [datetime(1982, 2, 1)], + "layer": [1], + "factor": [1.0], + "addition": [0.0], + }, + "wel-simple3": { + "has_associated": False, + "time": [datetime(1982, 3, 1)], + "layer": [1], + "factor": [1.0], + "addition": [0.0], + }, + } + + def case_simple__all_different3(self): + return { + "wel-simple1": { + "has_associated": False, + "time": [datetime(1982, 1, 1), datetime(1982, 3, 1)], + "layer": [1, 1], + "factor": [1.0, 1.0], + "addition": [0.0, 0.0], + }, + "wel-simple2": { + "has_associated": False, + "time": [datetime(1982, 2, 1)], + "layer": [1], + "factor": [1.0], + "addition": [0.0], + }, + "wel-simple3": { + "has_associated": False, + "time": [datetime(1982, 3, 1)], + "layer": [1], + "factor": [1.0], + "addition": [0.0], + }, + } + + def case_associated__first(self): + return { + "wel-associated": { + "has_associated": True, + "time": [datetime(1982, 1, 1)], + "layer": [1], + "factor": [1.0], + "addition": [0.0], + } + } + + def case_associated__all(self): + return { + "wel-associated": { + "has_associated": True, + "time": [ + datetime(1982, 1, 1), + datetime(1982, 2, 1), + datetime(1982, 3, 1), + ], + "layer": [1, 1, 1], + "factor": [1.0, 1.0, 1.0], + "addition": [0.0, 0.0, 0.0], + }, + } + + def case_associated__all_varying_factors(self): + return { + "wel-associated": { + "has_associated": True, + "time": [ + datetime(1982, 1, 1), + datetime(1982, 2, 1), + datetime(1982, 3, 1), + ], + "layer": [1, 1, 1], + "factor": [1.0, 0.5, 0.2], + "addition": [0.0, 0.0, 0.0], + }, + } + + def case_associated__multiple_layers_different_factors(self): + return { + "wel-associated": { + "has_associated": True, + "time": [ + datetime(1982, 1, 1), + datetime(1982, 1, 1), + ], + "layer": [1, 2], + "factor": [1.0, 0.75], + "addition": [0.0, 0.0], + }, + } + + def case_mixed__first(self): + return { + "wel-simple1": { + "has_associated": False, + "time": [datetime(1982, 1, 1)], + "layer": [1], + "factor": [1.0], + "addition": [0.0], + }, + "wel-associated": { + "has_associated": True, + "time": [datetime(1982, 1, 1)], + "layer": [1], + "factor": [1.0], + "addition": [0.0], + }, + } + + def case_mixed__all(self): + return { + "wel-associated": { + "has_associated": True, + "time": [ + datetime(1982, 1, 1), + datetime(1982, 2, 1), + datetime(1982, 3, 1), + ], + "layer": [1, 1, 1], + "factor": [1.0, 1.0, 1.0], + "addition": [0.0, 0.0, 0.0], + }, + "wel-simple1": { + "has_associated": False, + "time": [datetime(1982, 2, 1)], + "layer": [1], + "factor": [1.0], + "addition": [0.0], + }, + } + + def case_mixed__associated_second(self): + return { + "wel-associated": { + "has_associated": True, + "time": [datetime(1982, 2, 1)], + "layer": [1], + "factor": [1.0], + "addition": [0.0], + }, + "wel-simple1": { + "has_associated": False, + "time": [datetime(1982, 1, 1)], + "layer": [1], + "factor": [1.0], + "addition": [0.0], + }, + } + + +class WellPackageCases: + """ + Expected cases as loaded with from_imod5_data. + Returns a tuple with as first element a bool whether the import is expected to fail + The second element specifies in which timesteps the rates are set to zero. + + Returns + ------- + fails, {wellname: datetime_set_to_zero} + """ + + def case_simple__first(self): + return { + "wel-simple1": (False, [datetime(1982, 2, 1), datetime(1982, 3, 1)]), + } + + def case_simple__first_multi_layer1(self): + return { + "wel-simple1": (False, [datetime(1982, 2, 1), datetime(1982, 3, 1)]), + } + + def case_simple__first_multi_layer2(self): + return { + "wel-simple1": (True, []), + } + + def case_simple__all_same(self): + return { + "wel-simple1": (False, []), + } + + def case_simple__all_same_multi_layer1(self): + return { + "wel-simple1": (False, []), + } + + def case_simple__all_same_multi_layer2(self): + return { + "wel-simple1": (True, []), + } + + def case_simple__all_different1(self): + return { + "wel-simple1": (False, [datetime(1982, 2, 1), datetime(1982, 3, 1)]), + "wel-simple2": (False, [datetime(1982, 3, 1)]), + "wel-simple3": (False, []), + } + + def case_simple__all_different2(self): + return { + "wel-simple1": (False, [datetime(1982, 3, 1)]), + "wel-simple2": (False, [datetime(1982, 3, 1)]), + "wel-simple3": (False, []), + } + + def case_simple__all_different3(self): + return { + "wel-simple1": (False, [datetime(1982, 2, 1)]), + "wel-simple2": (False, [datetime(1982, 3, 1)]), + "wel-simple3": (False, []), + } + + def case_associated__first(self): + return {"wel-associated": (False, [])} + + def case_associated__all(self): + return {"wel-associated": (False, [])} + + def case_associated__all_varying_factors(self): + return {"wel-associated": (True, [])} + + def case_associated__multiple_layers_different_factors(self): + return {"wel-associated": (True, [])} + + def case_mixed__first(self): + return { + "wel-simple1": (False, [datetime(1982, 2, 1), datetime(1982, 3, 1)]), + "wel-associated": (False, []), + } + + def case_mixed__all(self): + return { + "wel-simple1": (False, [datetime(1982, 3, 1)]), + "wel-associated": (False, []), + } + + def case_mixed__associated_second(self): + return { + "wel-simple1": (False, [datetime(1982, 2, 1), datetime(1982, 3, 1)]), + "wel-associated": (True, []), + } + + +# pytest_cases doesn't support any "zipped test cases", instead it takes the +# outer product of cases, when providing multiple case sets. +# https://github.com/smarie/python-pytest-cases/issues/284 +# To support this, we would like to retrieve all function arguments from the +# case classes and to zip them together, something like +# zip(input_args,expected). +def case_args_to_parametrize(cases, prefix): + """Manually retrieve all case args of a set in cases.""" + + # Decorate some dummy function to be able to call ``get_all_cases``. For some + # reason, pytest_cases requires a decorated function (despite telling us + # differently in the docs.) + @parametrize_with_cases("case", cases=cases) + def f(case): + return case + + all_cases = get_all_cases(f, cases=cases) + return get_parametrize_args(f, all_cases, prefix) + + +PRJ_ARGS = case_args_to_parametrize(WellPrjCases, "case_") +READ_ARGS = case_args_to_parametrize(WellReadCases, "case_") +PKG_ARGS = case_args_to_parametrize(WellPackageCases, "case_") + + +def setup_test_files(wel_case, wel_file, well_mixed_ipfs, tmp_path): + """ + Write string to projectfile, and copy ipf files to directory. + """ + with open(wel_file, "w") as f: + f.write(wel_case) + + ipf_dir = tmp_path / "ipf" + ipf_dir.mkdir(exist_ok=True) + + # copy files to test folder + for p in well_mixed_ipfs: + copyfile(p, ipf_dir / p.name) + + +def get_case_name(request): + id_name = request.node.callspec.id + # Verify right cases are matched. This can go wrong when case names are not + # inserted in the right order in Case class. + cases = id_name.split("-") + # First entry refers to wel obj, we can skip this. + assert cases[1] == cases[-1] + + return cases[1] + + +@parametrize("wel_case, expected", argvalues=list(zip(PRJ_ARGS, READ_ARGS))) +def test_open_projectfile_data_wells( + wel_case, expected, well_mixed_ipfs, tmp_path, request +): + # Arrange + case_name = get_case_name(request) + wel_file = tmp_path / f"{case_name}.prj" + setup_test_files(wel_case, wel_file, well_mixed_ipfs, tmp_path) + + # Act + data, _ = open_projectfile_data(wel_file) + assert len(set(expected.keys()) ^ set(data.keys())) == 0 + fields = ["time", "layer", "addition", "factor", "has_associated"] + for wel_name, wel_expected in expected.items(): + actual = data[wel_name] + for field in fields: + assert field in actual + assert actual[field] == wel_expected[field] + + +@parametrize("wel_case, expected_dict", argvalues=list(zip(PRJ_ARGS, PKG_ARGS))) +@parametrize("wel_cls", argvalues=[LayeredWell, Well]) +def test_from_imod5_data_wells( + wel_cls: Union[LayeredWell, Well], + wel_case, + expected_dict, + well_mixed_ipfs, + tmp_path, + request, +): + # Arrange + # Replace layer number to zero if non-layered well. + if wel_cls == Well: + wel_case = wel_case.replace("1,2, 001", "1,2, 000") + # Write prj and copy ipfs to right folder. + case_name = get_case_name(request) + wel_file = tmp_path / f"{case_name}.prj" + setup_test_files(wel_case, wel_file, well_mixed_ipfs, tmp_path) + + times = [datetime(1982, i + 1, 1) for i in range(4)] + + # Act + data, _ = open_projectfile_data(wel_file) + for wellname in data.keys(): + assert wellname in expected_dict.keys() + fails, expected_set_to_zero = expected_dict[wellname] + if fails: + with pytest.raises(ValueError): + wel_cls.from_imod5_data(wellname, data, times=times) + else: + well = wel_cls.from_imod5_data(wellname, data, times=times) + rate = well.dataset["rate"] + actual_set_to_zero = [ + t.values for t in rate.coords["time"] if (rate.sel(time=t) == 0.0).all() + ] + expected_set_to_zero = [ + np.datetime64(t, "ns") for t in expected_set_to_zero + ] + diff = set(actual_set_to_zero) ^ set(expected_set_to_zero) + assert len(diff) == 0 + + +@parametrize("wel_case, expected_dict", argvalues=list(zip(PRJ_ARGS, PKG_ARGS))) +@parametrize("wel_cls", argvalues=[LayeredWell, Well]) +def test_from_imod5_data_wells__outside_range( + wel_cls: Union[LayeredWell, Well], + wel_case, + expected_dict, + well_mixed_ipfs, + tmp_path, + request, +): + """ + Test when values are retrieved outside time domain of wells, should be all + set to zero for unassociated ipfs, and be forward filled with the last entry + for associated ipfs. + """ + # Arrange + # Replace layer number to zero if non-layered well. + if wel_cls == Well: + wel_case = wel_case.replace("1,2, 001", "1,2, 000") + # Write prj and copy ipfs to right folder. + case_name = get_case_name(request) + wel_file = tmp_path / f"{case_name}.prj" + setup_test_files(wel_case, wel_file, well_mixed_ipfs, tmp_path) + + times = [datetime(1985, i + 1, 1) for i in range(4)] + + # Act + data, _ = open_projectfile_data(wel_file) + for wellname in data.keys(): + assert wellname in expected_dict.keys() + fails, _ = expected_dict[wellname] + if fails: + with pytest.raises(ValueError): + wel_cls.from_imod5_data(wellname, data, times=times) + else: + well = wel_cls.from_imod5_data(wellname, data, times=times) + rate = well.dataset["rate"] + actual_set_to_zero = [ + t.values for t in rate.coords["time"] if (rate.sel(time=t) == 0.0).all() + ] + if data[wellname]["has_associated"]: + expected_set_to_zero = [] + else: + expected_set_to_zero = [np.datetime64(t, "ns") for t in times[:-1]] + diff = set(actual_set_to_zero) ^ set(expected_set_to_zero) + assert len(diff) == 0 diff --git a/imod/tests/test_mf6/test_import_prj.py b/imod/tests/test_mf6/test_import_prj.py index 9cdff6a41..c1f33a1eb 100644 --- a/imod/tests/test_mf6/test_import_prj.py +++ b/imod/tests/test_mf6/test_import_prj.py @@ -185,23 +185,35 @@ def test_import_ipf(tmp_path): result_snippet_1 = open_projectfile_data(projects_file) assert np.all( - result_snippet_1[0]["wel-1"]["dataframe"]["rate"] - == 2 * result_snippet_0[0]["wel-1"]["dataframe"]["rate"] + 1.3 + result_snippet_1[0]["wel-WELLS_L3"]["dataframe"][0]["rate"] + == 2 * result_snippet_0[0]["wel-WELLS_L3"]["dataframe"][0]["rate"] + 1.3 ) assert np.all( - result_snippet_1[0]["wel-2"]["dataframe"]["rate"] - == -1 * result_snippet_0[0]["wel-2"]["dataframe"]["rate"] + 0 + result_snippet_1[0]["wel-WELLS_L4"]["dataframe"][0]["rate"] + == -1 * result_snippet_0[0]["wel-WELLS_L4"]["dataframe"][0]["rate"] + 0 ) assert np.all( - result_snippet_1[0]["wel-3"]["dataframe"]["rate"] - == 2 * result_snippet_0[0]["wel-2"]["dataframe"]["rate"] + 1.3 + result_snippet_1[0]["wel-WELLS_L5"]["dataframe"][0]["rate"] + == 2 * result_snippet_0[0]["wel-WELLS_L4"]["dataframe"][0]["rate"] + 1.3 + ) + assert np.all( + result_snippet_1[0]["wel-WELLS_L3"]["dataframe"][0]["filt_top"] == 11.0 + ) + assert np.all( + result_snippet_1[0]["wel-WELLS_L3"]["dataframe"][0]["filt_bot"] == 6.0 + ) + assert np.all( + result_snippet_1[0]["wel-WELLS_L4"]["dataframe"][0]["filt_top"] == 11.0 + ) + assert np.all( + result_snippet_1[0]["wel-WELLS_L4"]["dataframe"][0]["filt_bot"] == 6.0 + ) + assert np.all( + result_snippet_1[0]["wel-WELLS_L5"]["dataframe"][0]["filt_top"] == 11.0 + ) + assert np.all( + result_snippet_1[0]["wel-WELLS_L5"]["dataframe"][0]["filt_bot"] == 6.0 ) - assert np.all(result_snippet_1[0]["wel-1"]["dataframe"]["filt_top"] == 11.0) - assert np.all(result_snippet_1[0]["wel-1"]["dataframe"]["filt_bot"] == 6.0) - assert np.all(result_snippet_1[0]["wel-2"]["dataframe"]["filt_top"] == 11.0) - assert np.all(result_snippet_1[0]["wel-2"]["dataframe"]["filt_bot"] == 6.0) - assert np.all(result_snippet_1[0]["wel-3"]["dataframe"]["filt_top"] == 11.0) - assert np.all(result_snippet_1[0]["wel-3"]["dataframe"]["filt_bot"] == 6.0) def test_import_ipf_unique_id_and_logging(tmp_path): @@ -242,9 +254,15 @@ def test_import_ipf_unique_id_and_logging(tmp_path): # test that id's were made unique # Assert - assert np.all(result_snippet_1[0]["wel-1"]["dataframe"]["id"] == "extractions") - assert np.all(result_snippet_1[0]["wel-2"]["dataframe"]["id"] == "extractions_1") - assert np.all(result_snippet_1[0]["wel-3"]["dataframe"]["id"] == "extractions_2") + assert np.all( + result_snippet_1[0]["wel-WELLS_L3"]["dataframe"][0]["id"] == "extractions" + ) + assert np.all( + result_snippet_1[0]["wel-WELLS_L4"]["dataframe"][0]["id"] == "extractions_1" + ) + assert np.all( + result_snippet_1[0]["wel-WELLS_L5"]["dataframe"][0]["id"] == "extractions_2" + ) with open(logfile_path, "r") as log_file: log = log_file.read() diff --git a/imod/tests/test_mf6/test_mf6_simulation.py b/imod/tests/test_mf6/test_mf6_simulation.py index f814cb9f4..b60643793 100644 --- a/imod/tests/test_mf6/test_mf6_simulation.py +++ b/imod/tests/test_mf6/test_mf6_simulation.py @@ -514,8 +514,8 @@ def test_import_from_imod5__correct_well_type(imod5_dataset): period_data = imod5_dataset[1] # Temporarily change layer number to 0, to force Well object instead of # LayeredWell - original_wel_layer = imod5_data["wel-1"]["layer"] - imod5_data["wel-1"]["layer"] = 0 + original_wel_layer = imod5_data["wel-WELLS_L3"]["layer"] + imod5_data["wel-WELLS_L3"]["layer"] = [0] * len(original_wel_layer) # Other arrangement default_simulation_allocation_options = SimulationAllocationOptions default_simulation_distributing_options = SimulationDistributingOptions @@ -530,11 +530,11 @@ def test_import_from_imod5__correct_well_type(imod5_dataset): datelist, ) # Set layer back to right value (before AssertionError might be thrown) - imod5_data["wel-1"]["layer"] = original_wel_layer + imod5_data["wel-WELLS_L3"]["layer"] = original_wel_layer # Assert - assert isinstance(simulation["imported_model"]["wel-1"], Well) - assert isinstance(simulation["imported_model"]["wel-2"], LayeredWell) - assert isinstance(simulation["imported_model"]["wel-3"], LayeredWell) + assert isinstance(simulation["imported_model"]["wel-WELLS_L3"], Well) + assert isinstance(simulation["imported_model"]["wel-WELLS_L4"], LayeredWell) + assert isinstance(simulation["imported_model"]["wel-WELLS_L5"], LayeredWell) @pytest.mark.usefixtures("imod5_dataset") diff --git a/imod/tests/test_mf6/test_mf6_wel.py b/imod/tests/test_mf6/test_mf6_wel.py index 93f95337a..9e8da6639 100644 --- a/imod/tests/test_mf6/test_mf6_wel.py +++ b/imod/tests/test_mf6/test_mf6_wel.py @@ -911,10 +911,10 @@ def test_import_and_convert_to_mf6(imod5_dataset, tmp_path, wel_class): times = list(pd.date_range(datetime(1989, 1, 1), datetime(2013, 1, 1), 8400)) # import grid-agnostic well from imod5 data (it contains 1 well) - wel = wel_class.from_imod5_data("wel-1", data, times) + wel = wel_class.from_imod5_data("wel-WELLS_L3", data, times) assert wel.dataset["x"].values[0] == 197910.0 assert wel.dataset["y"].values[0] == 362860.0 - assert np.mean(wel.dataset["rate"].values) == -317.1681465863781 + assert np.mean(wel.dataset["rate"].values) == -317.2059091946156 # convert to a gridded well top = target_dis.dataset["top"] bottom = target_dis.dataset["bottom"] @@ -926,7 +926,7 @@ def test_import_and_convert_to_mf6(imod5_dataset, tmp_path, wel_class): assert len(mf6_well.dataset["x"].values) == 1 assert mf6_well.dataset["x"].values[0] == 197910.0 assert mf6_well.dataset["y"].values[0] == 362860.0 - assert np.mean(mf6_well.dataset["rate"].values) == -317.1681465863781 + assert np.mean(mf6_well.dataset["rate"].values) == -317.2059091946156 # write the package for validation write_context = WriteContext(simulation_directory=tmp_path) @@ -936,7 +936,7 @@ def test_import_and_convert_to_mf6(imod5_dataset, tmp_path, wel_class): @parametrize("wel_class", [Well, LayeredWell]) @pytest.mark.usefixtures("well_regular_import_prj") def test_import_multiple_wells(well_regular_import_prj, wel_class): - imod5dict = open_projectfile_data(well_regular_import_prj) + imod5dict, _ = open_projectfile_data(well_regular_import_prj) times = [ datetime(1981, 11, 30), datetime(1981, 12, 31), @@ -945,21 +945,24 @@ def test_import_multiple_wells(well_regular_import_prj, wel_class): datetime(1982, 3, 31), datetime(1982, 4, 30), ] - + # Set layer to 1, to avoid validation error. + if wel_class is LayeredWell: + imod5dict["wel-ipf1"]["layer"] = [1] + imod5dict["wel-ipf2"]["layer"] = [1] # import grid-agnostic well from imod5 data (it contains 2 packages with 3 wells each) - wel1 = wel_class.from_imod5_data("wel-1", imod5dict[0], times) - wel2 = wel_class.from_imod5_data("wel-2", imod5dict[0], times) + wel1 = wel_class.from_imod5_data("wel-ipf1", imod5dict, times) + wel2 = wel_class.from_imod5_data("wel-ipf2", imod5dict, times) assert np.all(wel1.x == np.array([191112.11, 191171.96, 191231.52])) assert np.all(wel2.x == np.array([191112.11, 191171.96, 191231.52])) - assert wel1.dataset["rate"].shape == (6, 3) - assert wel2.dataset["rate"].shape == (6, 3) + assert wel1.dataset["rate"].shape == (5, 3) + assert wel2.dataset["rate"].shape == (5, 3) @parametrize("wel_class", [Well, LayeredWell]) @pytest.mark.usefixtures("well_duplication_import_prj") def test_import_from_imod5_with_duplication(well_duplication_import_prj, wel_class): - imod5dict = open_projectfile_data(well_duplication_import_prj) + imod5dict, _ = open_projectfile_data(well_duplication_import_prj) times = [ datetime(1981, 11, 30), datetime(1981, 12, 31), @@ -968,14 +971,18 @@ def test_import_from_imod5_with_duplication(well_duplication_import_prj, wel_cla datetime(1982, 3, 31), datetime(1982, 4, 30), ] + # Set layer to 1, to avoid validation error. + if wel_class is LayeredWell: + imod5dict["wel-ipf1"]["layer"] = [1] + imod5dict["wel-ipf2"]["layer"] = [1] # import grid-agnostic well from imod5 data (it contains 2 packages with 3 wells each) - wel1 = wel_class.from_imod5_data("wel-1", imod5dict[0], times) - wel2 = wel_class.from_imod5_data("wel-2", imod5dict[0], times) + wel1 = wel_class.from_imod5_data("wel-ipf1", imod5dict, times) + wel2 = wel_class.from_imod5_data("wel-ipf2", imod5dict, times) assert np.all(wel1.x == np.array([191171.96, 191231.52, 191231.52])) assert np.all(wel2.x == np.array([191112.11, 191171.96, 191231.52])) - assert wel1.dataset["rate"].shape == (6, 3) - assert wel2.dataset["rate"].shape == (6, 3) + assert wel1.dataset["rate"].shape == (5, 3) + assert wel2.dataset["rate"].shape == (5, 3) @pytest.mark.parametrize("layer", [0, 1]) @@ -986,7 +993,7 @@ def test_logmessage_for_layer_assignment_import_imod5( imod5dict = open_projectfile_data(well_regular_import_prj) logfile_path = tmp_path / "logfile.txt" - imod5dict[0]["wel-1"]["layer"] = layer + imod5dict[0]["wel-ipf1"]["layer"] = [layer] * len(imod5dict[0]["wel-ipf1"]["layer"]) try: with open(logfile_path, "w") as sys.stdout: @@ -998,7 +1005,7 @@ def test_logmessage_for_layer_assignment_import_imod5( add_default_stream_handler=True, ) - _ = imod.mf6.Well.from_imod5_data("wel-1", imod5dict[0], times) + _ = imod.mf6.Well.from_imod5_data("wel-ipf1", imod5dict[0], times) finally: # turn the logger off again @@ -1014,7 +1021,7 @@ def test_logmessage_for_layer_assignment_import_imod5( log = log_file.read() message_required = layer != 0 message_present = ( - "In well wel-1 a layer was assigned, but this is not supported" in log + "In well wel-ipf1 a layer was assigned, but this is not\nsupported" in log ) assert message_required == message_present @@ -1027,9 +1034,9 @@ def test_logmessage_for_missing_filter_settings( imod5dict = open_projectfile_data(well_regular_import_prj) logfile_path = tmp_path / "logfile.txt" if remove is not None: - imod5dict[0]["wel-1"]["dataframe"] = imod5dict[0]["wel-1"]["dataframe"].drop( - remove, axis=1 - ) + imod5dict[0]["wel-ipf1"]["dataframe"][0] = imod5dict[0]["wel-ipf1"][ + "dataframe" + ][0].drop(remove, axis=1) try: with open(logfile_path, "w") as sys.stdout: @@ -1041,7 +1048,7 @@ def test_logmessage_for_missing_filter_settings( add_default_stream_handler=True, ) - _ = imod.mf6.Well.from_imod5_data("wel-1", imod5dict[0], times) + _ = imod.mf6.Well.from_imod5_data("wel-ipf1", imod5dict[0], times) except Exception: assert remove is not None @@ -1059,7 +1066,7 @@ def test_logmessage_for_missing_filter_settings( log = log_file.read() message_required = remove is not None message_present = ( - "In well wel-1 the filt_top and filt_bot columns were not both\nfound;" + "In well wel-ipf1 the 'filt_top' and 'filt_bot' columns were\nnot both found;" in log ) assert message_required == message_present From 4f3b71675708c5a832fb78e05f679bb89158f95d Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Fri, 16 Aug 2024 19:12:00 +0200 Subject: [PATCH 38/53] Issue #1132 performance hfb (#1157) Fixes #1132 # Description This PR adds the following: - Increase performance for writing the HFB files, by using new xugrid create_snap_to_grid_dataframe. - Fixes error when multiple barriers in a single dataset would be snapped to same edge. These lines are now aggregated. - Add some basic infrastructure for user acceptance test for writing LHM, the path to the LHM projectfile should be set in a .env as LHM_PRJ. This can later be extended to TeamCity. This reduces the time spent writing the HFB packages from 34 minutes to 12.5 minutes on my local machine. I've profiled the causes of the remaining bottlenecks to writing. I'll post a follow-up issue for that. # Checklist - [x] Links to correct issue - [x] Update changelog, if changes affect users - [x] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [x] Unit tests were added - [ ] **If feature added**: Added/extended example --- docs/api/changelog.rst | 3 +- imod/mf6/hfb.py | 115 +++++++++++++++++----------- imod/tests/test_mf6/test_mf6_LHM.py | 94 +++++++++++++++++++++++ imod/tests/test_mf6/test_mf6_hfb.py | 72 +++++++++++++++++ imod/typing/grid.py | 29 +++++-- pixi.lock | 112 +++++++++++++++++++-------- pixi.toml | 14 +++- pyproject.toml | 1 + 8 files changed, 356 insertions(+), 84 deletions(-) create mode 100644 imod/tests/test_mf6/test_mf6_LHM.py diff --git a/docs/api/changelog.rst b/docs/api/changelog.rst index fff20e930..95985f29f 100644 --- a/docs/api/changelog.rst +++ b/docs/api/changelog.rst @@ -15,7 +15,8 @@ Fixed - Multiple ``HorizontalFlowBarrier`` objects attached to :class:`imod.mf6.GroundwaterFlowModel` are merged into a single horizontal flow barrier for MODFLOW 6 - +- Bug where error would be thrown when barriers in a ``HorizontalFlowBarrier`` + would be snapped to the same cell edge. These are now summed. Changed ~~~~~~~ diff --git a/imod/mf6/hfb.py b/imod/mf6/hfb.py index 027cae283..5713be0a7 100644 --- a/imod/mf6/hfb.py +++ b/imod/mf6/hfb.py @@ -8,6 +8,7 @@ import cftime import numpy as np +import numpy.typing as npt import pandas as pd import xarray as xr import xugrid as xu @@ -27,6 +28,7 @@ ) from imod.schemata import EmptyIndexesSchema, MaxNUniqueValuesSchema from imod.typing import GeoDataFrameType, GridDataArray, LineStringType +from imod.typing.grid import as_ugrid_dataarray from imod.util.imports import MissingOptionalModule if TYPE_CHECKING: @@ -374,6 +376,53 @@ def _prepare_barrier_dataset_for_mf6_adapter(dataset: xr.Dataset) -> xr.Dataset: return dataset +def _snap_to_grid_and_aggregate( + barrier_dataframe: GeoDataFrameType, grid2d: xu.Ugrid2d, vardict_agg: dict[str, str] +) -> tuple[xu.UgridDataset, npt.NDArray]: + """ + Snap barrier dataframe to grid and aggregate multiple lines with a list of + methods per variable. + + Parameters + ---------- + barrier_dataframe: geopandas.GeoDataFrame + GeoDataFrame with barriers, should have variable "line_index". + grid2d: xugrid.Ugrid2d + Grid to snap lines to + vardict_agg: dict + Mapping of variable name to aggregation method + + Returns + ------- + snapping_dataset: xugrid.UgridDataset + Dataset with all variables snapped and aggregated to cell edges + edge_index: numpy.array + 1D array with indices of cell edges that lines were snapped to + """ + snapping_df = xu.create_snap_to_grid_dataframe( + barrier_dataframe, grid2d, max_snap_distance=0.5 + ) + # Map other variables to snapping_df with line indices + line_index = snapping_df["line_index"] + vars_to_snap = list(vardict_agg.keys()) + if "line_index" in vars_to_snap: + vars_to_snap.remove("line_index") # snapping_df already has line_index + for varname in vars_to_snap: + snapping_df[varname] = barrier_dataframe[varname].iloc[line_index].to_numpy() + # Aggregate to grid edges + gb_edge = snapping_df.groupby("edge_index") + # Initialize dataset and dataarray with the right shape and dims + snapped_dataset = xu.UgridDataset(grids=[grid2d]) + new = xr.DataArray(np.full(grid2d.n_edge, np.nan), dims=[grid2d.edge_dimension]) + edge_index = np.array(list(gb_edge.indices.keys())) + # Aggregate with different methods per variable + for varname, method in vardict_agg.items(): + snapped_dataset[varname] = new.copy() + snapped_dataset[varname].data[edge_index] = gb_edge[varname].aggregate(method) + + return snapped_dataset, edge_index + + class BarrierType(Enum): HydraulicCharacteristic = 0 Multiplier = 1 @@ -464,10 +513,9 @@ def _to_connected_cells_dataset( """ top, bottom = broadcast_to_full_domain(idomain, top, bottom) k = idomain * k + # Enforce unstructured unstructured_grid, top, bottom, k = ( - self.__to_unstructured(idomain, top, bottom, k) - if isinstance(idomain, xr.DataArray) - else [idomain, top, bottom, k] + as_ugrid_dataarray(grid) for grid in [idomain, top, bottom, k] ) snapped_dataset, edge_index = self._snap_to_grid(idomain) edge_index = self.__remove_invalid_edges(unstructured_grid, edge_index) @@ -736,61 +784,36 @@ def mask(self, _) -> Package: """ return deepcopy(self) - @staticmethod - def __to_unstructured( - idomain: xr.DataArray, top: xr.DataArray, bottom: xr.DataArray, k: xr.DataArray - ) -> Tuple[ - xu.UgridDataArray, xu.UgridDataArray, xu.UgridDataArray, xu.UgridDataArray - ]: - unstruct = xu.UgridDataArray.from_structured(idomain) - top = xu.UgridDataArray.from_structured(top) - bottom = xu.UgridDataArray.from_structured(bottom) - k = xu.UgridDataArray.from_structured(k) - - return unstruct, top, bottom, k - def _snap_to_grid( self, idomain: GridDataArray ) -> Tuple[xu.UgridDataset, np.ndarray]: - if "layer" in self._get_vertical_variables(): - variable_names = [self._get_variable_name(), "geometry", "layer"] + variable_name = self._get_variable_name() + has_layer = "layer" in self._get_vertical_variables() + # Create geodataframe with barriers + if has_layer: + varnames_for_df = [variable_name, "geometry", "layer"] else: - variable_names = [self._get_variable_name(), "geometry"] + varnames_for_df = [variable_name, "geometry"] barrier_dataframe = gpd.GeoDataFrame( - self.dataset[variable_names].to_dataframe() + self.dataset[varnames_for_df].to_dataframe() ) - - if "layer" not in self._get_vertical_variables(): + # Convert vertical polygon to linestring + if not has_layer: lower, _ = _extract_hfb_bounds_from_zpolygons(barrier_dataframe) linestring = _create_zlinestring_from_bound_df(lower) barrier_dataframe["geometry"] = linestring["geometry"] - + # Clip barriers outside domain barrier_dataframe = clip_line_gdf_by_grid( barrier_dataframe, idomain.sel(layer=1) ) - - # Work around issue where xu.snap_to_grid cannot handle snapping a - # dataset with multiple lines appropriately. This can be later replaced - # to a single call to xu.snap_to_grid if this bug is fixed: - # - snapped_dataset_rows: List[xr.Dataset] = [] - for index in barrier_dataframe.index: - # Index with list to return pd.DataFrame instead of pd.Series for - # xu.snap_to_grid. - row_df = barrier_dataframe.loc[[index]] - snapped_dataset_row, _ = typing.cast( - xu.UgridDataset, - xu.snap_to_grid(row_df, grid=idomain, max_snap_distance=0.5), - ) - snapped_dataset_row["line_index"] += index[0] # Set to original line index. - snapped_dataset_rows.append(snapped_dataset_row) - snapped_dataset = xu.merge(snapped_dataset_rows) - - edge_index = np.argwhere( - snapped_dataset[self._get_variable_name()].notnull().values - ).ravel() - - return snapped_dataset, edge_index + # Prepare variable names and methods for aggregation + vardict_agg = {"line_index": "first", variable_name: "sum"} + if has_layer: + vardict_agg["layer"] = "first" + # Create grid from structured + grid2d = as_ugrid_dataarray(idomain.sel(layer=1)).grid + + return _snap_to_grid_and_aggregate(barrier_dataframe, grid2d, vardict_agg) @staticmethod def __remove_invalid_edges( diff --git a/imod/tests/test_mf6/test_mf6_LHM.py b/imod/tests/test_mf6/test_mf6_LHM.py new file mode 100644 index 000000000..a2b5cacea --- /dev/null +++ b/imod/tests/test_mf6/test_mf6_LHM.py @@ -0,0 +1,94 @@ +""" +LHM tests, these are pytest-marked with 'user_acceptance'. + +These require the LHM model to be available on the local drive. The tests looks +for the path to the projectfile needs to be included in a .env file, with the +environmental variable "LHM_PRJ" with the path to the projectfile. +""" + +import os +import sys + +import pandas as pd +import pytest + +import imod +from imod.formats.prj.prj import open_projectfile_data +from imod.logging.config import LoggerType +from imod.logging.loglevel import LogLevel +from imod.mf6.oc import OutputControl +from imod.mf6.regrid.regrid_schemes import ( + DiscretizationRegridMethod, + NodePropertyFlowRegridMethod, + StorageCoefficientRegridMethod, +) +from imod.mf6.simulation import Modflow6Simulation +from imod.mf6.utilities.mf6hfb import merge_hfb_packages +from imod.mf6.write_context import WriteContext +from imod.prepare.topsystem.default_allocation_methods import ( + SimulationAllocationOptions, + SimulationDistributingOptions, +) + + +# In function, not a fixture, to allow logging of the import. +def LHM_imod5_data(): + lhm_prjfile = os.environ["LHM_PRJ"] + data = open_projectfile_data(lhm_prjfile) + + imod5_data = data[0] + period_data = data[1] + default_simulation_allocation_options = SimulationAllocationOptions + default_simulation_distributing_options = SimulationDistributingOptions + + regridding_option = {} + regridding_option["npf"] = NodePropertyFlowRegridMethod() + regridding_option["dis"] = DiscretizationRegridMethod() + regridding_option["sto"] = StorageCoefficientRegridMethod() + times = pd.date_range(start="1/1/2018", end="12/1/2018", freq="ME") + + simulation = Modflow6Simulation.from_imod5_data( + imod5_data, + period_data, + default_simulation_allocation_options, + default_simulation_distributing_options, + times, + regridding_option, + ) + simulation["imported_model"]["oc"] = OutputControl( + save_head="last", save_budget="last" + ) + return simulation + + +@pytest.mark.user_acceptance +def test_mf6_LHM_write_HFB(tmp_path): + logfile_path = tmp_path / "logfile.txt" + with open(logfile_path, "w") as sys.stdout: + imod.logging.configure( + LoggerType.PYTHON, + log_level=LogLevel.DEBUG, + add_default_file_handler=False, + add_default_stream_handler=True, + ) + simulation = LHM_imod5_data() + model = simulation["imported_model"] + + mf6_hfb_ls = [] + for key, pkg in model.items(): + if issubclass(type(pkg), imod.mf6.HorizontalFlowBarrierBase): + mf6_hfb_ls.append(pkg) + pkg.dataset.load() + + top, bottom, idomain = model._Modflow6Model__get_domain_geometry() + k = model._Modflow6Model__get_k() + + mf6_hfb = merge_hfb_packages(mf6_hfb_ls, idomain, top, bottom, k) + + times = pd.date_range(start="1/1/2018", end="12/1/2018", freq="ME") + + out_dir = tmp_path / "LHM" + out_dir.mkdir(parents=True, exist_ok=True) + write_context = WriteContext(out_dir, use_binary=True, use_absolute_paths=False) + + mf6_hfb.write("hfb", times, write_context) diff --git a/imod/tests/test_mf6/test_mf6_hfb.py b/imod/tests/test_mf6/test_mf6_hfb.py index fa2a5335b..b4892b302 100644 --- a/imod/tests/test_mf6/test_mf6_hfb.py +++ b/imod/tests/test_mf6/test_mf6_hfb.py @@ -22,6 +22,7 @@ _extract_mean_hfb_bounds_from_dataframe, _make_linestring_from_polygon, _prepare_barrier_dataset_for_mf6_adapter, + _snap_to_grid_and_aggregate, to_connected_cells_dataset, ) from imod.mf6.ims import SolutionPresetSimple @@ -697,6 +698,77 @@ def test_hfb_from_imod5(imod5_dataset, tmp_path): assert list(np.unique(hfb_package["layer"].values)) == [7] +@pytest.mark.usefixtures("structured_flow_model") +def test_snap_to_grid_and_aggregate(structured_flow_model): + idomain = structured_flow_model["dis"]["idomain"] + grid2d = xu.Ugrid2d.from_structured(idomain) + + barrier_y = [11.0, 5.0, -1.0] + barrier_x = [5.0, 5.0, 5.0] + line = linestrings(barrier_x, barrier_y) + layer = [1, 1, 1] + + geometry_triple = gpd.GeoDataFrame( + geometry=[line, line, line], + data={ + "resistance": [400.0, 400.0, 400.0], + "layer": layer, + "line_index": [0, 1, 2], + }, + ) + geometry_triple = geometry_triple.set_index("line_index") + + vardict_agg = {"resistance": "sum", "layer": "first"} + + snapped_dataset, edge_index = _snap_to_grid_and_aggregate( + geometry_triple, grid2d, vardict_agg + ) + + argwhere_summed_expected = np.array([7, 20, 33, 46, 59, 72], dtype=np.int64) + argwhere_summed_actual = np.nonzero((snapped_dataset["resistance"] == 1200).values)[ + 0 + ] + + np.testing.assert_array_equal(argwhere_summed_actual, argwhere_summed_expected) + np.testing.assert_array_equal(edge_index, argwhere_summed_expected) + + +@pytest.mark.usefixtures("structured_flow_model") +def test_combine_linestrings(structured_flow_model): + dis = structured_flow_model["dis"] + top, bottom, idomain = ( + dis["top"], + dis["bottom"], + dis["idomain"], + ) + k = xr.ones_like(idomain) + + barrier_y = [11.0, 5.0, -1.0] + barrier_x = [5.0, 5.0, 5.0] + line = linestrings(barrier_x, barrier_y) + + geometry_single = gpd.GeoDataFrame( + geometry=[line], + data={ + "resistance": [1200.0], + "layer": [1], + }, + ) + geometry_triple = gpd.GeoDataFrame( + geometry=[line, line, line], + data={ + "resistance": [400.0, 400.0, 400.0], + "layer": [1, 1, 1], + }, + ) + hfb_single = SingleLayerHorizontalFlowBarrierResistance(geometry_single) + hfb_triple = SingleLayerHorizontalFlowBarrierResistance(geometry_triple) + mf6_hfb_single = hfb_single.to_mf6_pkg(idomain, top, bottom, k) + mf6_hfb_triple = hfb_triple.to_mf6_pkg(idomain, top, bottom, k) + + xr.testing.assert_equal(mf6_hfb_single.dataset, mf6_hfb_triple.dataset) + + @pytest.mark.usefixtures("structured_flow_model") def test_run_multiple_hfbs(tmp_path, structured_flow_model): # Single layered model diff --git a/imod/typing/grid.py b/imod/typing/grid.py index 9daa867d7..3381b32ae 100644 --- a/imod/typing/grid.py +++ b/imod/typing/grid.py @@ -365,9 +365,11 @@ def enforce_dim_order(grid: xu.UgridDataArray) -> xu.UgridDataArray: # noqa: F8 ) -def _enforce_unstructured(obj: GridDataArray, ugrid2d=xu.Ugrid2d) -> xu.UgridDataArray: - """Force obj to unstructured""" - return xu.UgridDataArray(xr.DataArray(obj), ugrid2d) +def _as_ugrid_dataarray_with_topology( + obj: GridDataArray, topology: xu.Ugrid2d +) -> xu.UgridDataArray: + """Force obj and topology to ugrid dataarray""" + return xu.UgridDataArray(xr.DataArray(obj), topology) def preserve_gridtype(func: Callable[P, T]) -> Callable[P, T]: @@ -399,8 +401,8 @@ def decorator(*args: P.args, **kwargs: P.kwargs): if unstructured: # Multiple grids returned if isinstance(x, tuple): - return tuple(_enforce_unstructured(i, grid) for i in x) - return _enforce_unstructured(x, grid) + return tuple(_as_ugrid_dataarray_with_topology(i, grid) for i in x) + return _as_ugrid_dataarray_with_topology(x, grid) return x return decorator @@ -431,3 +433,20 @@ def is_transient_data_grid( if len(grid["time"]) > 1: return True return False + + +@typedispatch +def as_ugrid_dataarray(grid: xr.DataArray) -> xu.UgridDataArray: + """Enforce GridDataArray to UgridDataArray""" + return xu.UgridDataArray.from_structured(grid) + + +@typedispatch # type: ignore[no-redef] +def as_ugrid_dataarray(grid: xu.UgridDataArray) -> xu.UgridDataArray: # noqa: F811 + """Enforce GridDataArray to UgridDataArray""" + return grid + + +@typedispatch # type: ignore[no-redef] +def as_ugrid_dataarray(grid: object) -> xu.UgridDataArray: # noqa: F811 + raise TypeError(f"Function doesn't support type {type(grid)}") diff --git a/pixi.lock b/pixi.lock index dc8d1e42e..6f2e4a544 100644 --- a/pixi.lock +++ b/pixi.lock @@ -306,7 +306,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/nspr-4.35-h27087fc_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/nss-3.102-h593d115_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/numba-0.60.0-py311h4bc866e_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.6-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/numcodecs-0.12.1-py311h4332511_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-1.26.4-py311h64a7726_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/occt-7.7.2-novtk_h130ccc2_101.conda @@ -362,9 +362,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-benchmark-4.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cases-3.8.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-5.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-dotenv-0.5.2-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.11.0-he550d4f_1_cpython.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gmsh-4.12.2-h57928b3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-graphviz-0.20.3-pyh717bed2_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2024.1-pyhd8ed1ab_0.conda @@ -468,7 +470,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-xextproto-7.3.0-h0b41bf4_1003.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-xf86vidmodeproto-2.3.1-h7f98852_1002.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-xproto-7.0.31-h7f98852_1007.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.11.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h7f98852_2.tar.bz2 @@ -758,7 +760,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/nspr-4.35-hea0b92c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/nss-3.102-he7eb89d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/numba-0.60.0-py311h0e5bd6a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.6-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/numcodecs-0.12.1-py311hbafa61a_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/numpy-1.26.4-py311hc43a94b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/occt-7.7.2-all_hd7ce604_201.conda @@ -808,9 +810,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-benchmark-4.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cases-3.8.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-5.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-dotenv-0.5.2-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.11.0-he7542f4_1_cpython.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gmsh-4.12.2-h57928b3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-graphviz-0.20.3-pyh717bed2_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2024.1-pyhd8ed1ab_0.conda @@ -898,7 +902,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-renderproto-0.11.1-h0d85af4_1002.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-xextproto-7.3.0-hb7f2c08_1003.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-xproto-7.0.31-h35c211d_1007.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.11.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/xz-5.2.6-h775f41a_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h0d85af4_2.tar.bz2 @@ -1180,7 +1184,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nspr-4.35-hb7217d7_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nss-3.102-hc42bcbf_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numba-0.60.0-py311h9506ed5_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.6-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numcodecs-0.12.1-py311hb9542d7_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-1.26.4-py311h7125741_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/occt-7.7.2-novtk_h5f4376a_101.conda @@ -1231,9 +1235,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-benchmark-4.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cases-3.8.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-5.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-dotenv-0.5.2-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.11.0-h3ba56d0_1_cpython.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gmsh-4.12.2-h57928b3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-graphviz-0.20.3-pyh717bed2_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2024.1-pyhd8ed1ab_0.conda @@ -1321,7 +1327,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-renderproto-0.11.1-h27ca646_1002.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-xextproto-7.3.0-h1a8c8d9_1003.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-xproto-7.0.31-h27ca646_1007.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.11.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xz-5.2.6-h57fd34a_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h3422bc3_2.tar.bz2 @@ -1565,7 +1571,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/nh3-0.2.18-py311h9363f20_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/nlohmann_json-3.11.3-h1537add_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/numba-0.60.0-py311h0673bce_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.6-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/numcodecs-0.12.1-py311hda3d55a_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-1.26.4-py311h0b4df5a_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/occt-7.7.2-novtk_hdfb195f_101.conda @@ -1619,9 +1625,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-benchmark-4.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cases-3.8.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-5.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-dotenv-0.5.2-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.11.0-hcf16a7b_0_cpython.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gmsh-4.12.2-h57928b3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-graphviz-0.20.3-pyh717bed2_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-tzdata-2024.1-pyhd8ed1ab_0.conda @@ -1717,7 +1725,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-renderproto-0.11.1-hcd874cb_1002.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-xextproto-7.3.0-hcd874cb_1003.conda - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-xproto-7.0.31-hcd874cb_1007.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.11.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/xz-5.2.6-h8d14728_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h8ffe710_2.tar.bz2 @@ -2087,7 +2095,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/nspr-4.35-h27087fc_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/nss-3.102-h593d115_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/numba-0.60.0-py311h4bc866e_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.6-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/numcodecs-0.12.1-py311h4332511_1.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/numpy-1.26.4-py311h64a7726_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/occt-7.7.2-novtk_h130ccc2_101.conda @@ -2155,9 +2163,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-benchmark-4.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cases-3.8.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-5.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-dotenv-0.5.2-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/python-3.11.0-he550d4f_1_cpython.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.20.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gmsh-4.12.2-h57928b3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-graphviz-0.20.3-pyh717bed2_0.conda @@ -2284,7 +2294,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-xextproto-7.3.0-h0b41bf4_1003.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-xf86vidmodeproto-2.3.1-h7f98852_1002.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/xorg-xproto-7.0.31-h7f98852_1007.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.11.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/linux-64/xz-5.2.6-h166bdaf_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/linux-64/yaml-0.2.5-h7f98852_2.tar.bz2 @@ -2628,7 +2638,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/nspr-4.35-hea0b92c_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/nss-3.102-he7eb89d_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/numba-0.60.0-py311h0e5bd6a_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.6-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/numcodecs-0.12.1-py311hbafa61a_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/numpy-1.26.4-py311hc43a94b_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/occt-7.7.2-all_hd7ce604_201.conda @@ -2692,9 +2702,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-benchmark-4.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cases-3.8.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-5.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-dotenv-0.5.2-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/python-3.11.0-he7542f4_1_cpython.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.20.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gmsh-4.12.2-h57928b3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-graphviz-0.20.3-pyh717bed2_0.conda @@ -2805,7 +2817,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-renderproto-0.11.1-h0d85af4_1002.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-xextproto-7.3.0-hb7f2c08_1003.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/xorg-xproto-7.0.31-h35c211d_1007.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.11.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-64/xz-5.2.6-h775f41a_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-64/yaml-0.2.5-h0d85af4_2.tar.bz2 @@ -3141,7 +3153,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nspr-4.35-hb7217d7_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/nss-3.102-hc42bcbf_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numba-0.60.0-py311h9506ed5_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.6-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numcodecs-0.12.1-py311hb9542d7_1.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/numpy-1.26.4-py311h7125741_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/occt-7.7.2-novtk_h5f4376a_101.conda @@ -3206,9 +3218,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-benchmark-4.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cases-3.8.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-5.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-dotenv-0.5.2-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/python-3.11.0-h3ba56d0_1_cpython.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.20.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gmsh-4.12.2-h57928b3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-graphviz-0.20.3-pyh717bed2_0.conda @@ -3319,7 +3333,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-renderproto-0.11.1-h27ca646_1002.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-xextproto-7.3.0-h1a8c8d9_1003.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xorg-xproto-7.0.31-h27ca646_1007.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.11.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/osx-arm64/xz-5.2.6-h57fd34a_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/osx-arm64/yaml-0.2.5-h3422bc3_2.tar.bz2 @@ -3616,7 +3630,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-7.2.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/notebook-shim-0.2.4-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/numba-0.60.0-py311h0673bce_0.conda - - conda: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.6-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.8-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/numcodecs-0.12.1-py311hda3d55a_1.conda - conda: https://conda.anaconda.org/conda-forge/win-64/numpy-1.26.4-py311h0b4df5a_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/occt-7.7.2-novtk_hdfb195f_101.conda @@ -3680,9 +3694,11 @@ environments: - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-benchmark-4.0.0-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cases-3.8.5-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-cov-5.0.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-dotenv-0.5.2-pyhd8ed1ab_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/pytest-xdist-3.6.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/python-3.11.0-hcf16a7b_0_cpython.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/noarch/python-dateutil-2.9.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.0.1-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-fastjsonschema-2.20.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-gmsh-4.12.2-h57928b3_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/python-graphviz-0.20.3-pyh717bed2_0.conda @@ -3804,7 +3820,7 @@ environments: - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-renderproto-0.11.1-hcd874cb_1002.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-xextproto-7.3.0-hcd874cb_1003.conda - conda: https://conda.anaconda.org/conda-forge/win-64/xorg-xproto-7.0.31-hcd874cb_1007.tar.bz2 - - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.10.0-pyhd8ed1ab_0.conda + - conda: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.11.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/noarch/xyzservices-2024.6.0-pyhd8ed1ab_0.conda - conda: https://conda.anaconda.org/conda-forge/win-64/xz-5.2.6-h8d14728_0.tar.bz2 - conda: https://conda.anaconda.org/conda-forge/win-64/yaml-0.2.5-h8ffe710_2.tar.bz2 @@ -22614,23 +22630,23 @@ packages: timestamp: 1718888718616 - kind: conda name: numba_celltree - version: 0.1.6 + version: 0.1.8 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.6-pyhd8ed1ab_0.conda - sha256: 0ecb9c31a9d6cc23c9099c391ca14645f9b0118f5a22818c88b5091e3d0d27b2 - md5: fa93424676054b2d1fcc7864c4e68698 + url: https://conda.anaconda.org/conda-forge/noarch/numba_celltree-0.1.8-pyhd8ed1ab_0.conda + sha256: 4b30d964bf034b41ce14842bf8fa3040b21878c0da1bdec15c5523ab785bc311 + md5: 02b10d14b2e6693519804fe90d41c589 depends: - numba >=0.50 - numpy - - python >=3.7 + - python >=3.9 license: MIT license_family: MIT purls: - pkg:pypi/numba-celltree?source=conda-forge-mapping - size: 32808 - timestamp: 1672825982456 + size: 33524 + timestamp: 1722763371483 - kind: conda name: numcodecs version: 0.12.1 @@ -25901,6 +25917,25 @@ packages: - pkg:pypi/pytest-cov?source=conda-forge-mapping size: 25507 timestamp: 1711411153367 +- kind: conda + name: pytest-dotenv + version: 0.5.2 + build: pyhd8ed1ab_0 + subdir: noarch + noarch: python + url: https://conda.anaconda.org/conda-forge/noarch/pytest-dotenv-0.5.2-pyhd8ed1ab_0.tar.bz2 + sha256: 43ab7de6af7b298a9199aea2bf6fa481a3059ba1068dd0967fe3a040ff6e9303 + md5: 11b16b526f60cc18748c3fe45d10315a + depends: + - pytest >=5.0.0 + - python >=3.6 + - python-dotenv >=0.9.1 + license: MIT + license_family: MIT + purls: + - pkg:pypi/pytest-dotenv?source=conda-forge-mapping + size: 7383 + timestamp: 1606859705188 - kind: conda name: pytest-xdist version: 3.6.1 @@ -26355,6 +26390,23 @@ packages: - pkg:pypi/python-dateutil?source=conda-forge-mapping size: 222742 timestamp: 1709299922152 +- kind: conda + name: python-dotenv + version: 1.0.1 + build: pyhd8ed1ab_0 + subdir: noarch + noarch: python + url: https://conda.anaconda.org/conda-forge/noarch/python-dotenv-1.0.1-pyhd8ed1ab_0.conda + sha256: 2d4c80364f03315d606a50eddd493dbacc078e21412c2462c0f781eec49b572c + md5: c2997ea9360ac4e015658804a7a84f94 + depends: + - python >=3.8 + license: BSD-3-Clause + license_family: BSD + purls: + - pkg:pypi/python-dotenv?source=conda-forge-mapping + size: 24278 + timestamp: 1706018281544 - kind: conda name: python-fastjsonschema version: 2.20.0 @@ -31926,18 +31978,18 @@ packages: timestamp: 1607292254607 - kind: conda name: xugrid - version: 0.10.0 + version: 0.11.0 build: pyhd8ed1ab_0 subdir: noarch noarch: python - url: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.10.0-pyhd8ed1ab_0.conda - sha256: cf9b0c63b573405d5ac34a35819d98c10884abb0d49b19af0fc7414f8f44fa00 - md5: 7ef2f388e3b2adcecfed74591bff2451 + url: https://conda.anaconda.org/conda-forge/noarch/xugrid-0.11.0-pyhd8ed1ab_0.conda + sha256: 1f4bef6a7edb21c173c6b69788a42a46e350275664a79de14dc9efcdb9460627 + md5: 1d2fe2eccb1568bee8641cdf359ff742 depends: - dask - geopandas - numba >=0.50 - - numba_celltree + - numba_celltree >=0.1.8 - numpy - pandas - pooch @@ -31949,8 +32001,8 @@ packages: license_family: MIT purls: - pkg:pypi/xugrid?source=conda-forge-mapping - size: 94214 - timestamp: 1714580639671 + size: 94836 + timestamp: 1722866212176 - kind: conda name: xyzservices version: 2024.6.0 diff --git a/pixi.toml b/pixi.toml index 98b6f3b76..eac3c0f4d 100644 --- a/pixi.toml +++ b/pixi.toml @@ -23,7 +23,7 @@ unittests = { cmd = [ "NUMBA_DISABLE_JIT=1", "pytest", "-n", "auto", - "-m", "not example", + "-m", "not example and not user_acceptance", "--cache-clear", "--verbose", "--junitxml=unittest_report.xml", @@ -41,6 +41,15 @@ examples = { cmd = [ "--verbose", "--junitxml=examples_report.xml", ], depends_on = ["install"], cwd = "imod/tests" } +# User acceptance tests, only works when paths to models are located on local +# drive and are specified in a .env file. +user_acceptance = { cmd = [ + "pytest", + "-m", "user_acceptance", + "--cache-clear", + "--verbose", + "--junitxml=user_acceptance_report.xml", +], depends_on = ["install"], cwd = "imod/tests" } test_import = { cmd = [ "python", "-c", @@ -87,6 +96,7 @@ pytest = "<8" # Newer version incompatible with pytest-cases pytest-benchmark = "*" pytest-cases = "*" pytest-cov = "*" +pytest-dotenv = "*" pytest-xdist = "*" python = "3.11" python-graphviz = "*" @@ -107,7 +117,7 @@ tqdm = "*" twine = "*" vtk = { version = ">=9.0", build = "*qt*", channel = "conda-forge" } xarray = ">=2023.08.0" -xugrid = ">=0.10.0" +xugrid = ">=0.11.0" zarr = "*" build = "*" diff --git a/pyproject.toml b/pyproject.toml index a84fc4762..dcaaaa437 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -157,6 +157,7 @@ ignore_missing_imports = true [tool.pytest.ini_options] markers = [ "example: marks test as example (deselect with '-m \"not example\"')", + "user_acceptance: marks user acceptance tests (deselect with '-m \"not user_acceptance\"')", ] [tool.hatch.version] From ccf9f217452e5ddb035b5103b34fa614ac1c339c Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Tue, 20 Aug 2024 11:33:54 +0200 Subject: [PATCH 39/53] Issue #1158 remaining hfb bottlenecks (#1159) Fixes #1158 # Description Fix remaining HFB bottlenecks. This reduces writing the HFB package from the LHM from 12.5 minutes to 2 minutes. - Cache results ``xu.Ugrid2d.from_structured``, as this is a costly operation - Use ``and`` instead of ``&`` operator in the ``scalar_None`` function, to enable shortcutting. - Remove ``mask_all_packages`` function in ``from_imod5_data``, call in tests. - Create separate pixi task for slow unittests, where just in time compilation is enabled. ``pixi run unittests`` still runs all unittests, by starting two pixi tasks ``unittests_njit`` & ``unittests_jit``. # Checklist - [x] Links to correct issue - [x] Update changelog, if changes affect users - [x] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [x] Unit tests were added - [ ] **If feature added**: Added/extended example --- .gitignore | 3 +- docs/api/changelog.rst | 2 + imod/mf6/simulation.py | 3 - imod/schemata.py | 2 +- imod/tests/test_mf6/test_mf6_chd.py | 1 + imod/tests/test_mf6/test_mf6_simulation.py | 28 ++++---- imod/tests/test_typing/test_typing_grid.py | 74 ++++++++++++++++++++++ imod/typing/grid.py | 52 ++++++++++++++- pixi.toml | 13 +++- pyproject.toml | 1 + 10 files changed, 157 insertions(+), 22 deletions(-) diff --git a/.gitignore b/.gitignore index fd95f7d8d..28f9b76a9 100644 --- a/.gitignore +++ b/.gitignore @@ -141,5 +141,4 @@ examples/data .pixi /imod/tests/mydask.png -/imod/tests/unittest_report.xml -/imod/tests/examples_report.xml +/imod/tests/*_report.xml diff --git a/docs/api/changelog.rst b/docs/api/changelog.rst index 95985f29f..525f330ef 100644 --- a/docs/api/changelog.rst +++ b/docs/api/changelog.rst @@ -17,6 +17,8 @@ Fixed flow barrier for MODFLOW 6 - Bug where error would be thrown when barriers in a ``HorizontalFlowBarrier`` would be snapped to the same cell edge. These are now summed. +- Improve performance validation upon Package initialization +- Improve performance writing ``HorizontalFlowBarrier`` objects Changed ~~~~~~~ diff --git a/imod/mf6/simulation.py b/imod/mf6/simulation.py index 810a42a1a..54613eb3c 100644 --- a/imod/mf6/simulation.py +++ b/imod/mf6/simulation.py @@ -1378,8 +1378,5 @@ def from_imod5_data( ) simulation["ims"] = solution - # cleanup packages for validation - idomain = groundwaterFlowModel.domain - simulation.mask_all_models(idomain) simulation.create_time_discretization(additional_times=times) return simulation diff --git a/imod/schemata.py b/imod/schemata.py index 95b5d6a3a..fd9d8d737 100644 --- a/imod/schemata.py +++ b/imod/schemata.py @@ -74,7 +74,7 @@ def scalar_None(obj): if not isinstance(obj, (xr.DataArray, xu.UgridDataArray)): return False else: - return (len(obj.shape) == 0) & (~obj.notnull()).all() + return (len(obj.shape) == 0) and (obj.isnull()).all() def align_other_obj_with_coords( diff --git a/imod/tests/test_mf6/test_mf6_chd.py b/imod/tests/test_mf6/test_mf6_chd.py index ef0a04108..c3b96b982 100644 --- a/imod/tests/test_mf6/test_mf6_chd.py +++ b/imod/tests/test_mf6/test_mf6_chd.py @@ -238,6 +238,7 @@ def test_from_imod5_shd(imod5_dataset, tmp_path): chd_shd.write("chd_shd", [1], write_context) +@pytest.mark.unittest_jit @pytest.mark.parametrize("remove_merged_packages", [True, False]) @pytest.mark.usefixtures("imod5_dataset") def test_concatenate_chd(imod5_dataset, tmp_path, remove_merged_packages): diff --git a/imod/tests/test_mf6/test_mf6_simulation.py b/imod/tests/test_mf6/test_mf6_simulation.py index b60643793..b9b78fdcb 100644 --- a/imod/tests/test_mf6/test_mf6_simulation.py +++ b/imod/tests/test_mf6/test_mf6_simulation.py @@ -476,6 +476,7 @@ def compare_submodel_partition_info(first: PartitionInfo, second: PartitionInfo) ) +@pytest.mark.unittest_jit @pytest.mark.usefixtures("imod5_dataset") def test_import_from_imod5(imod5_dataset, tmp_path): imod5_data = imod5_dataset[0] @@ -495,18 +496,20 @@ def test_import_from_imod5(imod5_dataset, tmp_path): simulation["imported_model"]["oc"] = OutputControl( save_head="last", save_budget="last" ) - simulation.create_time_discretization(["01-01-2003", "02-01-2003"]) - + # Cleanup # Remove HFB packages outside domain # TODO: Build in support for hfb packages outside domain for hfb_outside in ["hfb-24", "hfb-26"]: simulation["imported_model"].pop(hfb_outside) - + # Align NoData to domain + idomain = simulation["imported_model"].domain + simulation.mask_all_models(idomain) # write and validate the simulation. simulation.write(tmp_path, binary=False, validate=True) +@pytest.mark.unittest_jit @pytest.mark.usefixtures("imod5_dataset") def test_import_from_imod5__correct_well_type(imod5_dataset): # Unpack @@ -537,6 +540,7 @@ def test_import_from_imod5__correct_well_type(imod5_dataset): assert isinstance(simulation["imported_model"]["wel-WELLS_L5"], LayeredWell) +@pytest.mark.unittest_jit @pytest.mark.usefixtures("imod5_dataset") def test_import_from_imod5__nonstandard_regridding(imod5_dataset, tmp_path): imod5_data = imod5_dataset[0] @@ -558,22 +562,23 @@ def test_import_from_imod5__nonstandard_regridding(imod5_dataset, tmp_path): times, regridding_option, ) - simulation["imported_model"]["oc"] = OutputControl( save_head="last", save_budget="last" ) - simulation.create_time_discretization(["01-01-2003", "02-01-2003"]) - + # Cleanup # Remove HFB packages outside domain # TODO: Build in support for hfb packages outside domain for hfb_outside in ["hfb-24", "hfb-26"]: simulation["imported_model"].pop(hfb_outside) - + # Align NoData to domain + idomain = simulation["imported_model"].domain + simulation.mask_all_models(idomain) # write and validate the simulation. simulation.write(tmp_path, binary=False, validate=True) +@pytest.mark.unittest_jit @pytest.mark.usefixtures("imod5_dataset") def test_import_from_imod5_no_storage_no_recharge(imod5_dataset, tmp_path): # this test imports an imod5 simulation, but it has no recharge and no storage package. @@ -594,23 +599,22 @@ def test_import_from_imod5_no_storage_no_recharge(imod5_dataset, tmp_path): default_simulation_distributing_options, times, ) - simulation["imported_model"]["oc"] = OutputControl( save_head="last", save_budget="last" ) - simulation.create_time_discretization(["01-01-2003", "02-01-2003"]) - + # Cleanup # Remove HFB packages outside domain # TODO: Build in support for hfb packages outside domain for hfb_outside in ["hfb-24", "hfb-26"]: simulation["imported_model"].pop(hfb_outside) - # check storage is present and rch is absent assert not simulation["imported_model"]["sto"].dataset["transient"].values[()] package_keys = simulation["imported_model"].keys() for key in package_keys: assert key[0:3] != "rch" - + # Align NoData to domain + idomain = simulation["imported_model"].domain + simulation.mask_all_models(idomain) # write and validate the simulation. simulation.write(tmp_path, binary=False, validate=True) diff --git a/imod/tests/test_typing/test_typing_grid.py b/imod/tests/test_typing/test_typing_grid.py index a1129940b..ff7f398b0 100644 --- a/imod/tests/test_typing/test_typing_grid.py +++ b/imod/tests/test_typing/test_typing_grid.py @@ -1,7 +1,11 @@ +import numpy as np import xarray as xr import xugrid as xu from imod.typing.grid import ( + UGRID2D_FROM_STRUCTURED_CACHE, + GridCache, + as_ugrid_dataarray, enforce_dim_order, is_planar_grid, is_spatial_grid, @@ -145,3 +149,73 @@ def test_merge_dictionary__unstructured(basic_unstructured_dis): assert isinstance(uds["bottom"], xr.DataArray) assert uds["ibound"].dims == ("layer", "mesh2d_nFaces") assert uds["bottom"].dims == ("layer",) + + +def test_as_ugrid_dataarray__structured(basic_dis): + # Arrange + ibound, top, bottom = basic_dis + top_3d = top * ibound + bottom_3d = bottom * ibound + # Clear cache + UGRID2D_FROM_STRUCTURED_CACHE.clear() + # Act + ibound_disv = as_ugrid_dataarray(ibound) + top_disv = as_ugrid_dataarray(top_3d) + bottom_disv = as_ugrid_dataarray(bottom_3d) + # Assert + # Test types + assert isinstance(ibound_disv, xu.UgridDataArray) + assert isinstance(top_disv, xu.UgridDataArray) + assert isinstance(bottom_disv, xu.UgridDataArray) + # Test cache proper size + assert len(UGRID2D_FROM_STRUCTURED_CACHE.grid_cache) == 1 + # Test that data is different + assert np.all(ibound_disv != top_disv) + assert np.all(top_disv != bottom_disv) + # Test that grid is equal + assert np.all(ibound_disv.grid == top_disv.grid) + assert np.all(top_disv.grid == bottom_disv.grid) + + +def test_as_ugrid_dataarray__unstructured(basic_unstructured_dis): + # Arrange + ibound, top, bottom = basic_unstructured_dis + top_3d = enforce_dim_order(ibound * top) + bottom_3d = enforce_dim_order(ibound * bottom) + # Clear cache + UGRID2D_FROM_STRUCTURED_CACHE.clear() + # Act + ibound_disv = as_ugrid_dataarray(ibound) + top_disv = as_ugrid_dataarray(top_3d) + bottom_disv = as_ugrid_dataarray(bottom_3d) + # Assert + # Test types + assert isinstance(ibound_disv, xu.UgridDataArray) + assert isinstance(top_disv, xu.UgridDataArray) + assert isinstance(bottom_disv, xu.UgridDataArray) + assert len(UGRID2D_FROM_STRUCTURED_CACHE.grid_cache) == 0 + + +def test_ugrid2d_cache(basic_dis): + # Arrange + ibound, _, _ = basic_dis + # Act + cache = GridCache(xu.Ugrid2d.from_structured, max_cache_size=3) + for i in range(5): + ugrid2d = cache.get_grid(ibound[:, i:, :]) + # Assert + # Test types + assert isinstance(ugrid2d, xu.Ugrid2d) + # Test cache proper size + assert cache.max_cache_size == 3 + assert len(cache.grid_cache) == 3 + # Check if smallest grid in last cache list by checking if amount of faces + # correct + expected_size = ibound[0, i:, :].size + keys = list(cache.grid_cache.keys()) + last_ugrid = cache.grid_cache[keys[-1]] + actual_size = last_ugrid.n_face + assert expected_size == actual_size + # Test clear cache + cache.clear() + assert len(cache.grid_cache) == 0 diff --git a/imod/typing/grid.py b/imod/typing/grid.py index 3381b32ae..509da6aef 100644 --- a/imod/typing/grid.py +++ b/imod/typing/grid.py @@ -435,10 +435,58 @@ def is_transient_data_grid( return False +class GridCache: + """ + Cache grids in this object for a specific function, lookup grids based on + unique geometry hash. + """ + + def __init__(self, func: Callable, max_cache_size=5): + self.max_cache_size = max_cache_size + self.grid_cache: dict[int, GridDataArray] = {} + self.func = func + + def get_grid(self, grid: GridDataArray): + geom_hash = get_grid_geometry_hash(grid) + if geom_hash not in self.grid_cache.keys(): + if len(self.grid_cache.keys()) >= self.max_cache_size: + self.remove_first() + self.grid_cache[geom_hash] = self.func(grid) + return self.grid_cache[geom_hash] + + def remove_first(self): + keys = list(self.grid_cache.keys()) + self.grid_cache.pop(keys[0]) + + def clear(self): + self.grid_cache = {} + + +UGRID2D_FROM_STRUCTURED_CACHE = GridCache(xu.Ugrid2d.from_structured) + + @typedispatch def as_ugrid_dataarray(grid: xr.DataArray) -> xu.UgridDataArray: - """Enforce GridDataArray to UgridDataArray""" - return xu.UgridDataArray.from_structured(grid) + """ + Enforce GridDataArray to UgridDataArray, calls + xu.UgridDataArray.from_structured, which is a costly operation. Therefore + cache results. + """ + + topology = UGRID2D_FROM_STRUCTURED_CACHE.get_grid(grid) + + # Copied from: + # https://github.com/Deltares/xugrid/blob/3dee693763da1c4c0859a4f53ac38d4b99613a33/xugrid/core/wrap.py#L236 + # Note that "da" is renamed to "grid" and "grid" to "topology" + dims = grid.dims[:-2] + coords = {k: grid.coords[k] for k in dims} + face_da = xr.DataArray( + grid.data.reshape(*grid.shape[:-2], -1), + coords=coords, + dims=[*dims, topology.face_dimension], + name=grid.name, + ) + return xu.UgridDataArray(face_da, topology) @typedispatch # type: ignore[no-redef] diff --git a/pixi.toml b/pixi.toml index eac3c0f4d..e7c867b60 100644 --- a/pixi.toml +++ b/pixi.toml @@ -19,11 +19,12 @@ install_with_deps = "python -m pip install --editable ." format = "ruff check --fix .; ruff format ." lint = "ruff check . ; ruff format --check ." tests = { depends_on = ["unittests", "examples"] } -unittests = { cmd = [ +unittests = { depends_on = ["unittests_njit", "unittests_jit"] } +unittests_njit = { cmd = [ "NUMBA_DISABLE_JIT=1", "pytest", "-n", "auto", - "-m", "not example and not user_acceptance", + "-m", "not example and not user_acceptance and not unittest_jit", "--cache-clear", "--verbose", "--junitxml=unittest_report.xml", @@ -32,6 +33,14 @@ unittests = { cmd = [ "--cov-report=html:coverage", "--cov-config=.coveragerc" ], depends_on = ["install"], cwd = "imod/tests" } +unittests_jit = { cmd = [ + "pytest", + "-n", "auto", + "-m", "unittest_jit", + "--cache-clear", + "--verbose", + "--junitxml=unittest_jit_report.xml", +], depends_on = ["install"], cwd = "imod/tests" } examples = { cmd = [ "NUMBA_DISABLE_JIT=1", "pytest", diff --git a/pyproject.toml b/pyproject.toml index dcaaaa437..c265cabe8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -158,6 +158,7 @@ ignore_missing_imports = true markers = [ "example: marks test as example (deselect with '-m \"not example\"')", "user_acceptance: marks user acceptance tests (deselect with '-m \"not user_acceptance\"')", + "unittest_jit: marks unit tests that should be jitted (deselect with '-m \"not unittest_jit\"')" ] [tool.hatch.version] From 546ad47dfde34e9b2784878d75b13d09858b8c32 Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Fri, 23 Aug 2024 16:46:07 +0200 Subject: [PATCH 40/53] Issue #1166 steady state well import (#1169) Fixes #1166 and somewhat fixes #1163 # Description - Moves ``pd.to_datetime`` logic to separate place, use ``errors="coerce"`` setting, which turns datetimes beyond the year 2261 to ``pd.NaT``. These seem to be consequently ignored in the ``resample_timeseries``. - Truncate well names to max 16 characters - Support wells defined in "steady-state" entry in the projectfile. - Add test cases for this. # Checklist - [x] Links to correct issue - [ ] Update changelog, if changes affect users - [x] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [x] Unit tests were added - [ ] **If feature added**: Added/extended example --- imod/formats/ipf.py | 11 +- imod/mf6/model_gwf.py | 19 +- imod/mf6/wel.py | 47 ++++- imod/tests/conftest.py | 1 + imod/tests/fixtures/imod5_well_data.py | 36 ++++ imod/tests/test_formats/test_prj_wel.py | 252 +++++++++++++++++++----- imod/util/expand_repetitions.py | 24 ++- imod/util/time.py | 12 ++ 8 files changed, 333 insertions(+), 69 deletions(-) diff --git a/imod/formats/ipf.py b/imod/formats/ipf.py index 35cf82c6b..2e1e03f63 100644 --- a/imod/formats/ipf.py +++ b/imod/formats/ipf.py @@ -17,6 +17,7 @@ import pandas as pd import imod +from imod.util.time import to_pandas_datetime_series def _infer_delimwhitespace(line, ncol): @@ -230,15 +231,7 @@ def read_associated(path, kwargs={}): if nrow > 0 and itype == 1: time_column = colnames[0] - len_date = len(df[time_column].iloc[0]) - if len_date == 14: - df[time_column] = pd.to_datetime(df[time_column], format="%Y%m%d%H%M%S") - elif len_date == 8: - df[time_column] = pd.to_datetime(df[time_column], format="%Y%m%d") - else: - raise ValueError( - f"{path.name}: datetime format must be yyyymmddhhmmss or yyyymmdd" - ) + df[time_column] = to_pandas_datetime_series(df[time_column]) return df diff --git a/imod/mf6/model_gwf.py b/imod/mf6/model_gwf.py index c83bfd9bb..b97d6352c 100644 --- a/imod/mf6/model_gwf.py +++ b/imod/mf6/model_gwf.py @@ -1,5 +1,6 @@ from __future__ import annotations +import textwrap from datetime import datetime from typing import Optional, cast @@ -291,11 +292,25 @@ def from_imod5_data( imod5_keys = list(imod5_data.keys()) wel_keys = [key for key in imod5_keys if key[0:3] == "wel"] for wel_key in wel_keys: + wel_key_truncated = wel_key[:16] + if wel_key_truncated in result.keys(): + # Remove this when https://github.com/Deltares/imod-python/issues/1167 + # is resolved + msg = textwrap.dedent( + f"""Truncated key: '{wel_key_truncated}' already assigned to + imported model, please rename wells so that unique names are + formed after they are truncated to 16 characters for MODFLOW + 6. + """ + ) + raise KeyError(msg) layer = np.array(imod5_data[wel_key]["layer"]) if np.any(layer == 0): - result[wel_key] = Well.from_imod5_data(wel_key, imod5_data, times) + result[wel_key_truncated] = Well.from_imod5_data( + wel_key, imod5_data, times + ) else: - result[wel_key] = LayeredWell.from_imod5_data( + result[wel_key_truncated] = LayeredWell.from_imod5_data( wel_key, imod5_data, times ) diff --git a/imod/mf6/wel.py b/imod/mf6/wel.py index 24153ce1c..5e705307d 100644 --- a/imod/mf6/wel.py +++ b/imod/mf6/wel.py @@ -76,10 +76,18 @@ def _df_groups_to_da_rates( unique_well_groups: pd.api.typing.DataFrameGroupBy, ) -> xr.DataArray: # Convert dataframes all groups to DataArrays - da_groups = [ - xr.DataArray(df_group["rate"], dims=("time"), coords={"time": df_group["time"]}) - for df_group in unique_well_groups - ] + is_steady_state = "time" not in unique_well_groups[0].columns + if is_steady_state: + da_groups = [ + xr.DataArray(df_group["rate"].iloc[0]) for df_group in unique_well_groups + ] + else: + da_groups = [ + xr.DataArray( + df_group["rate"], dims=("time"), coords={"time": df_group["time"]} + ) + for df_group in unique_well_groups + ] # Assign index coordinates da_groups = [ da_group.expand_dims(dim="index").assign_coords(index=[i]) @@ -142,13 +150,22 @@ def _prepare_df_ipf_unassociated( pkg_data: dict, start_times: list[datetime] ) -> pd.DataFrame: """Prepare dataframe for an ipf with no associated timeseries.""" + is_steady_state = any(t is None for t in pkg_data["time"]) + if is_steady_state: + index_dicts = [{"layer": lay} for lay in pkg_data["layer"]] + else: + index_dicts = [ + {"time": t, "layer": lay} + for t, lay in zip(pkg_data["time"], pkg_data["layer"]) + ] # Concatenate dataframes, assign layer and times - iter_dfs_dims = zip(pkg_data["dataframe"], pkg_data["time"], pkg_data["layer"]) - df = pd.concat([df.assign(time=t, layer=lay) for df, t, lay in iter_dfs_dims]) + iter_dfs_dims = zip(pkg_data["dataframe"], index_dicts) + df = pd.concat([df.assign(**index_dict) for df, index_dict in iter_dfs_dims]) # Prepare multi-index dataframe to convert to a multi-dimensional DataArray # later. - df_multi = df.set_index(["time", "layer", df.index]) - df_multi.index = df_multi.index.set_names(["time", "layer", "ipf_row"]) + dimnames = list(index_dicts[0].keys()) + df_multi = df.set_index(dimnames + [df.index]) + df_multi.index = df_multi.index.set_names(dimnames + ["ipf_row"]) # Temporarily convert to DataArray with 2 dimensions, as it allows for # multi-dimensional ffilling, instead pandas' ffilling the last value in a # column of the flattened table. @@ -158,7 +175,9 @@ def _prepare_df_ipf_unassociated( cols_ffill_if_present = {"x", "y", "filt_top", "filt_bot"} cols_ffill = cols_ffill_if_present & set(df.columns) da_multi = df_multi.to_xarray() - indexers = {"time": start_times, "ipf_row": ipf_row_index} + indexers = {"ipf_row": ipf_row_index} + if not is_steady_state: + indexers["time"] = start_times # Multi-dimensional reindex, forward fill well locations, fill well rates # with 0.0. df_ffilled = da_multi[cols_ffill].reindex(indexers, method="ffill").to_dataframe() @@ -519,16 +538,24 @@ def from_imod5_data( simulation times. - When simulation times fall outside well timeseries range, the last rate is forward filled. + - Projectfile timestamps are not used. Even if assigned to a + "steady-state" timestamp, the resulting dataset still uses simulation + times. *Unassociated wells* Wells without associated textfiles are processed as follows: - When a unassociated well disappears from the next time entry in the - projectfile, the well is deactivated by ratting its rate to 0.0. This + projectfile, the well is deactivated by setting its rate to 0.0. This is to prevent the well being activated again in case of any potential forward filling at a later stage by :meth:`imod.mf6.Modflow6Simulation.create_time_discretization` + - Wells assigned to a "steady-state" entry in the projectfile will have + no "time" dimension in the resulting dataset. + - Times beyond the year 2261 are out of bounds for pandas. In associated + timeseries these are ignored, instead the last stage is forward + filled. .. note:: In case you are wondering why is this so complicated? There are two diff --git a/imod/tests/conftest.py b/imod/tests/conftest.py index d6bf65a6a..595741876 100644 --- a/imod/tests/conftest.py +++ b/imod/tests/conftest.py @@ -25,6 +25,7 @@ from .fixtures.imod5_well_data import ( well_duplication_import_prj, well_mixed_ipfs, + well_out_of_bounds_ipfs, well_regular_import_prj, ) from .fixtures.mf6_circle_fixture import ( diff --git a/imod/tests/fixtures/imod5_well_data.py b/imod/tests/fixtures/imod5_well_data.py index 3bddb7a42..a489588a3 100644 --- a/imod/tests/fixtures/imod5_well_data.py +++ b/imod/tests/fixtures/imod5_well_data.py @@ -150,6 +150,23 @@ def other_timeseries_string(): ) +def out_of_bounds_timeseries_string(): + return textwrap.dedent( + """\ + 6 + 2 + DATE,-9999.0 + MEASUREMENT,-9999.0 + 19811130,-174.1507971461288 + 19811231,-166.7777419354838 + 19820131,-147.6367741935485 + 19820228,-127.3857142857142 + 19820331,-159.2109677419355 + 29991112,-182.7713333333334 + """ + ) + + def write_ipf_assoc_files( projectfile_str, ipf1_str, @@ -251,3 +268,22 @@ def well_mixed_ipfs(): other_timeseries_well_str, tmp_path, ) + + +@pytest.fixture(scope="session") +def well_out_of_bounds_ipfs(): + tmp_path = imod.util.temporary_directory() + os.makedirs(tmp_path) + + ipf_assoc_str = ipf1_string_duplication() + ipf_simple_str = ipf_simple_string() + timeseries_well_str = timeseries_string() + other_timeseries_well_str = out_of_bounds_timeseries_string() + + return write_ipf_mixed_files( + ipf_assoc_str, + ipf_simple_str, + timeseries_well_str, + other_timeseries_well_str, + tmp_path, + ) diff --git a/imod/tests/test_formats/test_prj_wel.py b/imod/tests/test_formats/test_prj_wel.py index d05470c0c..6656653ef 100644 --- a/imod/tests/test_formats/test_prj_wel.py +++ b/imod/tests/test_formats/test_prj_wel.py @@ -4,6 +4,7 @@ from typing import Union import numpy as np +import pandas as pd import pytest from pytest_cases import ( get_all_cases, @@ -19,6 +20,37 @@ class WellPrjCases: """Cases for projectfile well records""" + def case_simple__steady_state(self): + return dedent( + """ + 0001,(WEL),1 + steady-state + 001,001 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + """ + ) + + def case_associated__steady_state(self): + return dedent( + """ + 0001,(WEL),1 + steady-state + 001,001 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/associated.ipf" + """ + ) + + def case_mixed__steady_state(self): + return dedent( + """ + 0001,(WEL),1 + steady-state + 001,002 + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/associated.ipf" + 1,2, 001, 1.0, 0.0, -999.9900 ,"ipf/simple1.ipf" + """ + ) + def case_simple__first(self): return dedent( """ @@ -253,6 +285,46 @@ def case_mixed__associated_second(self): class WellReadCases: """Expected cases as interpreted by ``imod.formats.prj.open_projectfile_data``""" + def case_simple__steady_state(self): + return { + "wel-simple1": { + "has_associated": False, + "time": [None], + "layer": [1], + "factor": [1.0], + "addition": [0.0], + }, + } + + def case_associated__steady_state(self): + return { + "wel-associated": { + "has_associated": True, + "time": [None], + "layer": [1], + "factor": [1.0], + "addition": [0.0], + }, + } + + def case_mixed__steady_state(self): + return { + "wel-simple1": { + "has_associated": False, + "time": [None], + "layer": [1], + "factor": [1.0], + "addition": [0.0], + }, + "wel-associated": { + "has_associated": True, + "time": [None], + "layer": [1], + "factor": [1.0], + "addition": [0.0], + }, + } + def case_simple__first(self): return { "wel-simple1": { @@ -534,88 +606,104 @@ class WellPackageCases: Returns ------- - fails, {wellname: datetime_set_to_zero} + {wellname: (fails, has_time, datetimes_set_to_zero)} """ + def case_simple__steady_state(self): + return { + "wel-simple1": (False, False, []), + } + + def case_associated__steady_state(self): + return { + "wel-associated": (False, True, []), + } + + def case_mixed__steady_state(self): + return { + "wel-associated": (False, True, []), + "wel-simple1": (False, False, []), + } + def case_simple__first(self): return { - "wel-simple1": (False, [datetime(1982, 2, 1), datetime(1982, 3, 1)]), + "wel-simple1": (False, True, [datetime(1982, 2, 1), datetime(1982, 3, 1)]), } def case_simple__first_multi_layer1(self): return { - "wel-simple1": (False, [datetime(1982, 2, 1), datetime(1982, 3, 1)]), + "wel-simple1": (False, True, [datetime(1982, 2, 1), datetime(1982, 3, 1)]), } def case_simple__first_multi_layer2(self): return { - "wel-simple1": (True, []), + "wel-simple1": (True, False, []), } def case_simple__all_same(self): return { - "wel-simple1": (False, []), + "wel-simple1": (False, True, []), } def case_simple__all_same_multi_layer1(self): return { - "wel-simple1": (False, []), + "wel-simple1": (False, True, []), } def case_simple__all_same_multi_layer2(self): return { - "wel-simple1": (True, []), + "wel-simple1": (True, False, []), } def case_simple__all_different1(self): return { - "wel-simple1": (False, [datetime(1982, 2, 1), datetime(1982, 3, 1)]), - "wel-simple2": (False, [datetime(1982, 3, 1)]), - "wel-simple3": (False, []), + "wel-simple1": (False, True, [datetime(1982, 2, 1), datetime(1982, 3, 1)]), + "wel-simple2": (False, True, [datetime(1982, 3, 1)]), + "wel-simple3": (False, True, []), } def case_simple__all_different2(self): return { - "wel-simple1": (False, [datetime(1982, 3, 1)]), - "wel-simple2": (False, [datetime(1982, 3, 1)]), - "wel-simple3": (False, []), + "wel-simple1": (False, True, [datetime(1982, 3, 1)]), + "wel-simple2": (False, True, [datetime(1982, 3, 1)]), + "wel-simple3": (False, True, []), } def case_simple__all_different3(self): return { - "wel-simple1": (False, [datetime(1982, 2, 1)]), - "wel-simple2": (False, [datetime(1982, 3, 1)]), - "wel-simple3": (False, []), + "wel-simple1": (False, True, [datetime(1982, 2, 1)]), + "wel-simple2": (False, True, [datetime(1982, 3, 1)]), + "wel-simple3": (False, True, []), } def case_associated__first(self): - return {"wel-associated": (False, [])} + return {"wel-associated": (False, True, [])} def case_associated__all(self): - return {"wel-associated": (False, [])} + return {"wel-associated": (False, True, [])} def case_associated__all_varying_factors(self): - return {"wel-associated": (True, [])} + return {"wel-associated": (True, False, [])} def case_associated__multiple_layers_different_factors(self): - return {"wel-associated": (True, [])} + return {"wel-associated": (True, False, [])} def case_mixed__first(self): return { - "wel-simple1": (False, [datetime(1982, 2, 1), datetime(1982, 3, 1)]), - "wel-associated": (False, []), + "wel-simple1": (False, True, [datetime(1982, 2, 1), datetime(1982, 3, 1)]), + "wel-associated": (False, True, []), } def case_mixed__all(self): return { - "wel-simple1": (False, [datetime(1982, 3, 1)]), - "wel-associated": (False, []), + "wel-simple1": (False, True, [datetime(1982, 3, 1)]), + "wel-associated": (False, True, []), } def case_mixed__associated_second(self): return { - "wel-simple1": (False, [datetime(1982, 2, 1), datetime(1982, 3, 1)]), - "wel-associated": (True, []), + "wel-simple1": (False, True, [datetime(1982, 2, 1), datetime(1982, 3, 1)]), + "wel-associated": (True, False, []), } @@ -690,6 +778,30 @@ def test_open_projectfile_data_wells( assert actual[field] == wel_expected[field] +@parametrize("wel_case, expected", argvalues=list(zip(PRJ_ARGS, READ_ARGS))) +def test_open_projectfile_data_out_of_bounds_wells( + wel_case, expected, well_out_of_bounds_ipfs, tmp_path, request +): + # Arrange + case_name = get_case_name(request) + wel_file = tmp_path / f"{case_name}.prj" + setup_test_files(wel_case, wel_file, well_out_of_bounds_ipfs, tmp_path) + + # Act + data, _ = open_projectfile_data(wel_file) + assert len(set(expected.keys()) ^ set(data.keys())) == 0 + fields = ["time", "layer", "addition", "factor", "has_associated"] + for wel_name, wel_expected in expected.items(): + actual = data[wel_name] + for field in fields: + assert field in actual + assert actual[field] == wel_expected[field] + if actual["has_associated"]: + timeseries = data["wel-associated"]["dataframe"][0]["time"] + # Test if last element NaT + assert timeseries.iloc[-1] is pd.NaT + + @parametrize("wel_case, expected_dict", argvalues=list(zip(PRJ_ARGS, PKG_ARGS))) @parametrize("wel_cls", argvalues=[LayeredWell, Well]) def test_from_imod5_data_wells( @@ -715,21 +827,27 @@ def test_from_imod5_data_wells( data, _ = open_projectfile_data(wel_file) for wellname in data.keys(): assert wellname in expected_dict.keys() - fails, expected_set_to_zero = expected_dict[wellname] + fails, has_time, expected_set_to_zero = expected_dict[wellname] if fails: with pytest.raises(ValueError): wel_cls.from_imod5_data(wellname, data, times=times) else: well = wel_cls.from_imod5_data(wellname, data, times=times) rate = well.dataset["rate"] - actual_set_to_zero = [ - t.values for t in rate.coords["time"] if (rate.sel(time=t) == 0.0).all() - ] - expected_set_to_zero = [ - np.datetime64(t, "ns") for t in expected_set_to_zero - ] - diff = set(actual_set_to_zero) ^ set(expected_set_to_zero) - assert len(diff) == 0 + if has_time: + actual_set_to_zero = [ + t.values + for t in rate.coords["time"] + if (rate.sel(time=t) == 0.0).all() + ] + expected_set_to_zero = [ + np.datetime64(t, "ns") for t in expected_set_to_zero + ] + diff = set(actual_set_to_zero) ^ set(expected_set_to_zero) + assert len(diff) == 0 + else: + assert "time" not in rate.dims + assert "time" not in rate.coords @parametrize("wel_case, expected_dict", argvalues=list(zip(PRJ_ARGS, PKG_ARGS))) @@ -762,19 +880,65 @@ def test_from_imod5_data_wells__outside_range( data, _ = open_projectfile_data(wel_file) for wellname in data.keys(): assert wellname in expected_dict.keys() - fails, _ = expected_dict[wellname] + fails, has_time, _ = expected_dict[wellname] if fails: with pytest.raises(ValueError): wel_cls.from_imod5_data(wellname, data, times=times) else: well = wel_cls.from_imod5_data(wellname, data, times=times) rate = well.dataset["rate"] - actual_set_to_zero = [ - t.values for t in rate.coords["time"] if (rate.sel(time=t) == 0.0).all() - ] - if data[wellname]["has_associated"]: - expected_set_to_zero = [] + if has_time: + actual_set_to_zero = [ + t.values + for t in rate.coords["time"] + if (rate.sel(time=t) == 0.0).all() + ] + if data[wellname]["has_associated"]: + expected_set_to_zero = [] + else: + expected_set_to_zero = [np.datetime64(t, "ns") for t in times[:-1]] + diff = set(actual_set_to_zero) ^ set(expected_set_to_zero) + assert len(diff) == 0 else: - expected_set_to_zero = [np.datetime64(t, "ns") for t in times[:-1]] - diff = set(actual_set_to_zero) ^ set(expected_set_to_zero) - assert len(diff) == 0 + assert "time" not in rate.dims + assert "time" not in rate.coords + + +@parametrize("wel_case, expected_dict", argvalues=list(zip(PRJ_ARGS, PKG_ARGS))) +@parametrize("wel_cls", argvalues=[LayeredWell, Well]) +def test_from_imod5_data_wells__wells_out_of_bounds( + wel_cls: Union[LayeredWell, Well], + wel_case, + expected_dict, + well_out_of_bounds_ipfs, + tmp_path, + request, +): + # Arrange + # Replace layer number to zero if non-layered well. + if wel_cls == Well: + wel_case = wel_case.replace("1,2, 001", "1,2, 000") + # Write prj and copy ipfs to right folder. + case_name = get_case_name(request) + wel_file = tmp_path / f"{case_name}.prj" + setup_test_files(wel_case, wel_file, well_out_of_bounds_ipfs, tmp_path) + + times = [datetime(1982, i + 3, 1) for i in range(4)] + + # Act + data, _ = open_projectfile_data(wel_file) + for wellname in data.keys(): + assert wellname in expected_dict.keys() + fails, _, _ = expected_dict[wellname] + if fails: + with pytest.raises(ValueError): + wel_cls.from_imod5_data(wellname, data, times=times) + else: + well = wel_cls.from_imod5_data(wellname, data, times=times) + if data[wellname]["has_associated"]: + # Last value in dataframe returned by open_projectfile is time + # NaT (out of bounds), so expect second last rate in dataframe + # as final rate in well package. + expected_last_rate = data[wellname]["dataframe"][0]["rate"].iloc[-2] + actual_last_rate = well.dataset["rate"].isel(index=1, time=-1).item() + assert actual_last_rate == expected_last_rate diff --git a/imod/util/expand_repetitions.py b/imod/util/expand_repetitions.py index aa36e600c..53d911bef 100644 --- a/imod/util/expand_repetitions.py +++ b/imod/util/expand_repetitions.py @@ -56,12 +56,14 @@ def resample_timeseries(well_rate: pd.DataFrame, times: list[datetime]) -> pd.Da well_rate: pd.DataFrame input timeseries for well times: datetime - list of times on which the output datarame should have entries. + list of times on which the output dataframe should have entries. returns: -------- a new dataframe containing a timeseries defined on the times in "times". """ + is_steady_state = len(times) == 0 + output_frame = pd.DataFrame(times) output_frame = output_frame.rename(columns={0: "time"}) intermediate_df = pd.merge( @@ -106,6 +108,20 @@ def resample_timeseries(well_rate: pd.DataFrame, times: list[datetime]) -> pd.Da if np.isnan(output_frame["rate"].values[-1]): output_frame["rate"].values[-1] = well_rate["rate"].values[-1] - columns_to_merge = ["time"] + location_columns - - return pd.merge(output_frame, intermediate_df[columns_to_merge], on="time") + if is_steady_state: + # Take first element, the slice is to force pandas to return it as + # dataframe instead of series. + location_dataframe = intermediate_df[location_columns].iloc[slice(0, 1), :] + # Concat along columns and drop time column + return pd.concat([output_frame, location_dataframe], axis=1).drop( + columns="time" + ) + else: + columns_to_merge = ["time"] + location_columns + return pd.merge( + output_frame, + intermediate_df[columns_to_merge], + on="time", + how="left", + validate="1:m", + ) diff --git a/imod/util/time.py b/imod/util/time.py index fcf5a8dda..75186b517 100644 --- a/imod/util/time.py +++ b/imod/util/time.py @@ -15,6 +15,18 @@ } +def to_pandas_datetime_series(series: pd.Series): + """ + Convert series to pandas datetime, uses length of first string to find the + appropriate format. This takes nanosecond as base. This only supports going + up to the year 2261; the function sets dates beyond this year silently to + pd.NaT. + """ + len_date = len(series.iloc[0]) + dt_format = DATETIME_FORMATS[len_date] + return pd.to_datetime(series, format=dt_format, errors="coerce") + + def to_datetime(s: str) -> datetime.datetime: """ Convert string to datetime. Part of the public API for backwards From 20e4bc20b0764120a3d481cee129c318f601e0d2 Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Tue, 3 Sep 2024 15:37:53 +0200 Subject: [PATCH 41/53] Issue #1164 cleanup utils (#1172) Fixes #1164 # Description This implements the following cleanup utilities for the robin boundary conditions, namely the DRN, GHB, and RIV. - Cleanup helper functions, which are part of the public API (so that people could also use them outside MODFLOW 6) - Cleanup methods to the River, GeneralHeadBoundary, Drain package for convenience. These call the corresponding helper function. Save the user the hassle of manually finding the right arguments to clean up grids. - Add a utility method: Call function on grids, which separates grid variables from settings, calls a function on them, and then merges these dicts again. - Converted the fixtures in ``test_mf6_riv`` to regular functions, as they were used as such anyway. Without this, RivDisCases could not be used outside the ``test_mf6_riv`` module, now it can be imported. # Checklist - [x] Links to correct issue - [x] Update changelog, if changes affect users - [x] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [x] Unit tests were added - [ ] **If feature added**: Added/extended example --- docs/api/changelog.rst | 8 + docs/api/mf6.rst | 9 + docs/api/prepare.rst | 4 + imod/mf6/drn.py | 18 +- imod/mf6/ghb.py | 19 +- imod/mf6/package.py | 27 ++- imod/mf6/riv.py | 18 +- imod/mf6/wel.py | 4 + imod/prepare/__init__.py | 1 + imod/prepare/cleanup.py | 219 ++++++++++++++++++++++++ imod/tests/test_mf6/test_mf6_riv.py | 116 +++++++++---- imod/tests/test_prepare/test_cleanup.py | 178 +++++++++++++++++++ 12 files changed, 584 insertions(+), 37 deletions(-) create mode 100644 imod/prepare/cleanup.py create mode 100644 imod/tests/test_prepare/test_cleanup.py diff --git a/docs/api/changelog.rst b/docs/api/changelog.rst index 525f330ef..b315052d4 100644 --- a/docs/api/changelog.rst +++ b/docs/api/changelog.rst @@ -51,6 +51,14 @@ Added :class:`imod.mf6.HorizontalFlowBarrierHydraulicCharacteristic`. - :class:`imod.mf6.LayeredWell` to specify wells directly to layers instead assigning them with filter depths. +- :func:`imod.prepare.cleanup_drn`, :func:`imod.prepare.cleanup_ghb`, + :func:`imod.prepare.cleanup_riv`. These are utility functions to clean up + drainage, general head boundaries, and rivers, respectively. +- :meth:`imod.mf6.Drainage.cleanup`, + :meth:`imod.mf6.GeneralHeadboundary.cleanup`, :meth:`imod.mf6.River.cleanup` + convenience methods to call the corresponding cleanup utility functions with + the appropriate arguments. + Removed ~~~~~~~ diff --git a/docs/api/mf6.rst b/docs/api/mf6.rst index aaf9a1a44..f7046786d 100644 --- a/docs/api/mf6.rst +++ b/docs/api/mf6.rst @@ -69,8 +69,14 @@ Flow Packages Buoyancy ConstantHead Drainage + Drainage.mask + Drainage.regrid_like + Drainage.cleanup Evapotranspiration GeneralHeadBoundary + GeneralHeadBoundary.mask + GeneralHeadBoundary.regrid_like + GeneralHeadBoundary.cleanup HorizontalFlowBarrierHydraulicCharacteristic HorizontalFlowBarrierMultiplier HorizontalFlowBarrierResistance @@ -83,6 +89,9 @@ Flow Packages NodePropertyFlow Recharge River + River.mask + River.regrid_like + River.cleanup SpecificStorage StorageCoefficient UnsaturatedZoneFlow diff --git a/docs/api/prepare.rst b/docs/api/prepare.rst index 55ede360d..b8aed4a19 100644 --- a/docs/api/prepare.rst +++ b/docs/api/prepare.rst @@ -47,3 +47,7 @@ Prepare model input distribute_drn_conductance distribute_ghb_conductance distribute_riv_conductance + + cleanup_drn + cleanup_ghb + cleanup_riv diff --git a/imod/mf6/drn.py b/imod/mf6/drn.py index aef93f278..7cc54b371 100644 --- a/imod/mf6/drn.py +++ b/imod/mf6/drn.py @@ -4,9 +4,10 @@ import numpy as np -from imod.logging import init_log_decorator +from imod.logging import init_log_decorator, standard_log_decorator from imod.mf6.boundary_condition import BoundaryCondition from imod.mf6.dis import StructuredDiscretization +from imod.mf6.disv import VerticesDiscretization from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.npf import NodePropertyFlow from imod.mf6.regrid.regrid_schemes import DrainageRegridMethod @@ -15,6 +16,7 @@ _regrid_package_data, ) from imod.mf6.validation import BOUNDARY_DIMS_SCHEMA, CONC_DIMS_SCHEMA +from imod.prepare.cleanup import cleanup_drn from imod.prepare.topsystem.allocation import ALLOCATION_OPTION, allocate_drn_cells from imod.prepare.topsystem.conductance import ( DISTRIBUTING_OPTION, @@ -163,6 +165,20 @@ def _validate(self, schemata, **kwargs): return errors + @standard_log_decorator() + def cleanup(self, dis: StructuredDiscretization | VerticesDiscretization) -> None: + """ + Clean up package inplace. This method calls + :func:`imod.prepare.cleanup.cleanup_drn`, see documentation of that + function for details on cleanup. + + dis: imod.mf6.StructuredDiscretization | imod.mf6.VerticesDiscretization + Model discretization package. + """ + dis_dict = {"idomain": dis.dataset["idomain"]} + cleaned_dict = self._call_func_on_grids(cleanup_drn, dis_dict) + super().__init__(cleaned_dict) + @classmethod def from_imod5_data( cls, diff --git a/imod/mf6/ghb.py b/imod/mf6/ghb.py index 287627fe5..e40d32b86 100644 --- a/imod/mf6/ghb.py +++ b/imod/mf6/ghb.py @@ -4,8 +4,10 @@ import numpy as np -from imod.logging import init_log_decorator +from imod.logging import init_log_decorator, standard_log_decorator from imod.mf6.boundary_condition import BoundaryCondition +from imod.mf6.dis import StructuredDiscretization +from imod.mf6.disv import VerticesDiscretization from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.npf import NodePropertyFlow from imod.mf6.regrid.regrid_schemes import ( @@ -14,6 +16,7 @@ ) from imod.mf6.utilities.regrid import RegridderWeightsCache, _regrid_package_data from imod.mf6.validation import BOUNDARY_DIMS_SCHEMA, CONC_DIMS_SCHEMA +from imod.prepare.cleanup import cleanup_ghb from imod.prepare.topsystem.allocation import ALLOCATION_OPTION, allocate_ghb_cells from imod.prepare.topsystem.conductance import ( DISTRIBUTING_OPTION, @@ -165,6 +168,20 @@ def _validate(self, schemata, **kwargs): return errors + @standard_log_decorator() + def cleanup(self, dis: StructuredDiscretization | VerticesDiscretization) -> None: + """ + Clean up package inplace. This method calls + :func:`imod.prepare.cleanup.cleanup_ghb`, see documentation of that + function for details on cleanup. + + dis: imod.mf6.StructuredDiscretization | imod.mf6.VerticesDiscretization + Model discretization package. + """ + dis_dict = {"idomain": dis.dataset["idomain"]} + cleaned_dict = self._call_func_on_grids(cleanup_ghb, dis_dict) + super().__init__(cleaned_dict) + @classmethod def from_imod5_data( cls, diff --git a/imod/mf6/package.py b/imod/mf6/package.py index 0b81a18d1..ab2fbbc7a 100644 --- a/imod/mf6/package.py +++ b/imod/mf6/package.py @@ -4,7 +4,7 @@ import pathlib from collections import defaultdict from copy import deepcopy -from typing import Any, Dict, List, Mapping, Optional, Tuple, Union +from typing import Any, Callable, Dict, List, Mapping, Optional, Tuple, Union import cftime import jinja2 @@ -81,6 +81,9 @@ def sel(self): f"{type(self).__name__}(**{self._pkg_id}.dataset.sel(**selection))" ) + def cleanup(self, dis: Any): + raise NotImplementedError("Method not implemented for this package.") + @staticmethod def _valid(value: Any) -> bool: return _is_valid(value) @@ -630,6 +633,28 @@ def get_non_grid_data(self, grid_names: list[str]) -> dict[str, Any]: result[name] = self.dataset[name].values[()] return result + def _call_func_on_grids( + self, func: Callable, dis: dict + ) -> dict[str, GridDataArray]: + """ + Call function on dictionary of grids and merge settings back into + dictionary. + + Parameters + ---------- + func: Callable + Function to call on all grids + """ + grid_varnames = list(self._write_schemata.keys()) + grids = { + varname: self.dataset[varname] + for varname in grid_varnames + if varname in self.dataset.keys() + } + cleaned_grids = func(**dis, **grids) + settings = self.get_non_grid_data(grid_varnames) + return cleaned_grids | settings + def is_splitting_supported(self) -> bool: return True diff --git a/imod/mf6/riv.py b/imod/mf6/riv.py index d91610651..0787f387c 100644 --- a/imod/mf6/riv.py +++ b/imod/mf6/riv.py @@ -6,10 +6,11 @@ import xarray as xr from imod import logging -from imod.logging import init_log_decorator +from imod.logging import init_log_decorator, standard_log_decorator from imod.logging.loglevel import LogLevel from imod.mf6.boundary_condition import BoundaryCondition from imod.mf6.dis import StructuredDiscretization +from imod.mf6.disv import VerticesDiscretization from imod.mf6.drn import Drainage from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.regrid.regrid_schemes import RiverRegridMethod @@ -18,6 +19,7 @@ _regrid_package_data, ) from imod.mf6.validation import BOUNDARY_DIMS_SCHEMA, CONC_DIMS_SCHEMA +from imod.prepare.cleanup import cleanup_riv from imod.prepare.topsystem.allocation import ALLOCATION_OPTION, allocate_riv_cells from imod.prepare.topsystem.conductance import ( DISTRIBUTING_OPTION, @@ -184,6 +186,20 @@ def _validate(self, schemata, **kwargs): return errors + @standard_log_decorator() + def cleanup(self, dis: StructuredDiscretization | VerticesDiscretization) -> None: + """ + Clean up package inplace. This method calls + :func:`imod.prepare.cleanup.cleanup_riv`, see documentation of that + function for details on cleanup. + + dis: imod.mf6.StructuredDiscretization | imod.mf6.VerticesDiscretization + Model discretization package. + """ + dis_dict = {"idomain": dis.dataset["idomain"], "bottom": dis.dataset["bottom"]} + cleaned_dict = self._call_func_on_grids(cleanup_riv, dis_dict) + super().__init__(cleaned_dict) + @classmethod def from_imod5_data( cls, diff --git a/imod/mf6/wel.py b/imod/mf6/wel.py index 5e705307d..b4072fd4d 100644 --- a/imod/mf6/wel.py +++ b/imod/mf6/wel.py @@ -30,6 +30,7 @@ from imod.mf6.validation import validation_pkg_error_message from imod.mf6.write_context import WriteContext from imod.prepare import assign_wells +from imod.prepare.cleanup import cleanup_wel from imod.prepare.layer import create_layered_top from imod.schemata import ( AllValueSchema, @@ -971,6 +972,9 @@ def _validate_imod5_depth_information( logger.log(loglevel=LogLevel.ERROR, message=log_msg, additional_depth=2) raise ValueError(log_msg) + def cleanup(self): + self.dataset = cleanup_wel(self.dataset) + class LayeredWell(GridAgnosticWell): """ diff --git a/imod/prepare/__init__.py b/imod/prepare/__init__.py index caf5fc202..2ea86c3cb 100644 --- a/imod/prepare/__init__.py +++ b/imod/prepare/__init__.py @@ -14,6 +14,7 @@ """ from imod.prepare import hfb, spatial, subsoil, surface_water +from imod.prepare.cleanup import cleanup_drn, cleanup_ghb, cleanup_riv from imod.prepare.hfb import ( linestring_to_square_zpolygons, linestring_to_trapezoid_zpolygons, diff --git a/imod/prepare/cleanup.py b/imod/prepare/cleanup.py new file mode 100644 index 000000000..0d6edf10d --- /dev/null +++ b/imod/prepare/cleanup.py @@ -0,0 +1,219 @@ +"""Cleanup utilities""" + +from enum import Enum +from typing import Optional + +import xarray as xr + +from imod.mf6.utilities.mask import mask_arrays +from imod.schemata import scalar_None +from imod.typing import GridDataArray, GridDataset + + +class AlignLevelsMode(Enum): + TOPDOWN = 0 + BOTTOMUP = 1 + + +def align_nodata(grids: dict[str, xr.DataArray]) -> dict[str, xr.DataArray]: + return mask_arrays(grids) + + +def align_interface_levels( + top: GridDataArray, + bottom: GridDataArray, + method: AlignLevelsMode = AlignLevelsMode.TOPDOWN, +) -> tuple[GridDataArray, GridDataArray]: + to_align = top < bottom + + match method: + case AlignLevelsMode.BOTTOMUP: + return top.where(~to_align, bottom), bottom + case AlignLevelsMode.TOPDOWN: + return top, bottom.where(~to_align, top) + case _: + raise TypeError(f"Unmatched case for method, got {method}") + + +def _cleanup_robin_boundary( + idomain: GridDataArray, grids: dict[str, GridDataArray] +) -> dict[str, GridDataArray]: + """Cleanup robin boundary condition (i.e. bc with conductance)""" + active = idomain == 1 + # Deactivate conductance cells outside active domain; this nodata + # inconsistency will be aligned in the final call to align_nodata + conductance = grids["conductance"].where(active) + concentration = grids["concentration"] + # Make conductance cells with erronous values inactive + grids["conductance"] = conductance.where(conductance > 0.0) + # Clip negative concentration cells to 0.0 + if (concentration is not None) and not scalar_None(concentration): + grids["concentration"] = concentration.clip(min=0.0) + else: + grids.pop("concentration") + + # Align nodata + return align_nodata(grids) + + +def cleanup_riv( + idomain: GridDataArray, + bottom: GridDataArray, + stage: GridDataArray, + conductance: GridDataArray, + bottom_elevation: GridDataArray, + concentration: Optional[GridDataArray] = None, +) -> dict[str, GridDataArray]: + """ + Clean up river data, fixes some common mistakes causing ValidationErrors by + doing the following: + + - Cells where conductance <= 0 are deactivated. + - Cells where concentration < 0 are set to 0.0. + - Cells outside active domain (idomain==1) are removed. + - Align NoData: If one variable has an inactive cell in one cell, ensure + this cell is deactivated for all variables. + - River bottom elevations below model bottom of a layer are set to model + bottom of that layer. + - River bottom elevations which exceed river stage are lowered to river + stage. + + Parameters + ---------- + idomain: xarray.DataArray | xugrid.UgridDataArray + MODFLOW 6 model domain. idomain==1 is considered active domain. + bottom: xarray.DataArray | xugrid.UgridDataArray + Grid with`model bottoms + stage: xarray.DataArray | xugrid.UgridDataArray + Grid with river stages + conductance: xarray.DataArray | xugrid.UgridDataArray + Grid with conductances + bottom_elevation: xarray.DataArray | xugrid.UgridDataArray + Grid with river bottom elevations + concentration: xarray.DataArray | xugrid.UgridDataArray, optional + Optional grid with concentrations + + Returns + ------- + dict[str, xarray.DataArray | xugrid.UgridDataArray] + Dict of cleaned up grids. Has keys: "stage", "conductance", + "bottom_elevation", "concentration". + """ + # Output dict + output_dict = { + "stage": stage, + "conductance": conductance, + "bottom_elevation": bottom_elevation, + "concentration": concentration, + } + output_dict = _cleanup_robin_boundary(idomain, output_dict) + if (output_dict["stage"] < bottom).any(): + raise ValueError( + "River stage below bottom of model layer, cannot fix this. " + "Probably rivers are assigned to the wrong layer, you can reallocate " + "river data to model layers with: " + "``imod.prepare.topsystem.allocate_riv_cells``." + ) + # Ensure bottom elevation above model bottom + output_dict["bottom_elevation"], _ = align_interface_levels( + output_dict["bottom_elevation"], bottom, AlignLevelsMode.BOTTOMUP + ) + # Ensure stage above bottom_elevation + output_dict["stage"], output_dict["bottom_elevation"] = align_interface_levels( + output_dict["stage"], output_dict["bottom_elevation"], AlignLevelsMode.TOPDOWN + ) + return output_dict + + +def cleanup_drn( + idomain: GridDataArray, + elevation: GridDataArray, + conductance: GridDataArray, + concentration: Optional[GridDataArray] = None, +) -> dict[str, GridDataArray]: + """ + Clean up drain data, fixes some common mistakes causing ValidationErrors by + doing the following: + + - Cells where conductance <= 0 are deactivated. + - Cells where concentration < 0 are set to 0.0. + - Cells outside active domain (idomain==1) are removed. + - Align NoData: If one variable has an inactive cell in one cell, ensure + this cell is deactivated for all variables. + + Parameters + ---------- + idomain: xarray.DataArray | xugrid.UgridDataArray + MODFLOW 6 model domain. idomain==1 is considered active domain. + elevation: xarray.DataArray | xugrid.UgridDataArray + Grid with drain elevations + conductance: xarray.DataArray | xugrid.UgridDataArray + Grid with conductances + concentration: xarray.DataArray | xugrid.UgridDataArray, optional + Optional grid with concentrations + + Returns + ------- + dict[str, xarray.DataArray | xugrid.UgridDataArray] + Dict of cleaned up grids. Has keys: "elevation", "conductance", + "concentration". + """ + # Output dict + output_dict = { + "elevation": elevation, + "conductance": conductance, + "concentration": concentration, + } + return _cleanup_robin_boundary(idomain, output_dict) + + +def cleanup_ghb( + idomain: GridDataArray, + head: GridDataArray, + conductance: GridDataArray, + concentration: Optional[GridDataArray] = None, +) -> dict[str, GridDataArray]: + """ + Clean up general head boundary data, fixes some common mistakes causing + ValidationErrors by doing the following: + + - Cells where conductance <= 0 are deactivated. + - Cells where concentration < 0 are set to 0.0. + - Cells outside active domain (idomain==1) are removed. + - Align NoData: If one variable has an inactive cell in one cell, ensure + this cell is deactivated for all variables. + + Parameters + ---------- + idomain: xarray.DataArray | xugrid.UgridDataArray + MODFLOW 6 model domain. idomain==1 is considered active domain. + head: xarray.DataArray | xugrid.UgridDataArray + Grid with heads + conductance: xarray.DataArray | xugrid.UgridDataArray + Grid with conductances + concentration: xarray.DataArray | xugrid.UgridDataArray, optional + Optional grid with concentrations + + Returns + ------- + dict[str, xarray.DataArray | xugrid.UgridDataArray] + Dict of cleaned up grids. Has keys: "head", "conductance", + "concentration". + """ + # Output dict + output_dict = { + "head": head, + "conductance": conductance, + "concentration": concentration, + } + return _cleanup_robin_boundary(idomain, output_dict) + + +def cleanup_wel(wel_ds: GridDataset): + """ + Clean up wells + + - Removes wells where the screen bottom elevation exceeds screen top. + """ + deactivate = wel_ds["screen_top"] < wel_ds["screen_bottom"] + return wel_ds.where(~deactivate, drop=True) diff --git a/imod/tests/test_mf6/test_mf6_riv.py b/imod/tests/test_mf6/test_mf6_riv.py index d48cab220..d57ef157b 100644 --- a/imod/tests/test_mf6/test_mf6_riv.py +++ b/imod/tests/test_mf6/test_mf6_riv.py @@ -12,14 +12,19 @@ import imod from imod.mf6.dis import StructuredDiscretization +from imod.mf6.disv import VerticesDiscretization from imod.mf6.write_context import WriteContext from imod.prepare.topsystem.allocation import ALLOCATION_OPTION from imod.prepare.topsystem.conductance import DISTRIBUTING_OPTION from imod.schemata import ValidationError from imod.typing.grid import ones_like, zeros_like +TYPE_DIS_PKG = { + xu.UgridDataArray: VerticesDiscretization, + xr.DataArray: StructuredDiscretization, +} + -@pytest.fixture(scope="function") def make_da(): x = [5.0, 15.0, 25.0] y = [25.0, 15.0, 5.0] @@ -34,9 +39,8 @@ def make_da(): ) -@pytest.fixture(scope="function") -def dis_dict(make_da): - da = make_da +def dis_dict(): + da = make_da() bottom = da - xr.DataArray( data=[1.5, 2.5], dims=("layer",), coords={"layer": [2, 3]} ) @@ -44,16 +48,15 @@ def dis_dict(make_da): return {"idomain": da.astype(int), "top": da.sel(layer=2), "bottom": bottom} -@pytest.fixture(scope="function") -def riv_dict(make_da): - da = make_da +def riv_dict(): + da = make_da() da[:, 1, 1] = np.nan bottom = da - xr.DataArray( data=[1.0, 2.0], dims=("layer",), coords={"layer": [2, 3]} ) - return {"stage": da, "conductance": da, "bottom_elevation": bottom} + return {"stage": da, "conductance": da.copy(), "bottom_elevation": bottom} def make_dict_unstructured(d): @@ -61,19 +64,19 @@ def make_dict_unstructured(d): class RivCases: - def case_structured(self, riv_dict): - return riv_dict + def case_structured(self): + return riv_dict() - def case_unstructured(self, riv_dict): - return make_dict_unstructured(riv_dict) + def case_unstructured(self): + return make_dict_unstructured(riv_dict()) class RivDisCases: - def case_structured(self, riv_dict, dis_dict): - return riv_dict, dis_dict + def case_structured(self): + return riv_dict(), dis_dict() - def case_unstructured(self, riv_dict, dis_dict): - return make_dict_unstructured(riv_dict), make_dict_unstructured(dis_dict) + def case_unstructured(self): + return make_dict_unstructured(riv_dict()), make_dict_unstructured(dis_dict()) @parametrize_with_cases("riv_data", cases=RivCases) @@ -118,19 +121,32 @@ def test_all_nan(riv_data, dis_data): errors = river._validate(river._write_schemata, **dis_data) assert len(errors) == 1 + assert "stage" in errors.keys() - for var, var_errors in errors.items(): - assert var == "stage" + +@parametrize_with_cases("riv_data,dis_data", cases=RivDisCases) +def test_validate_inconsistent_nan(riv_data, dis_data): + riv_data["stage"][..., 2] = np.nan + river = imod.mf6.River(**riv_data) + + errors = river._validate(river._write_schemata, **dis_data) + + assert len(errors) == 2 + assert "bottom_elevation" in errors.keys() + assert "conductance" in errors.keys() @parametrize_with_cases("riv_data,dis_data", cases=RivDisCases) -def test_inconsistent_nan(riv_data, dis_data): +def test_cleanup_inconsistent_nan(riv_data, dis_data): riv_data["stage"][..., 2] = np.nan river = imod.mf6.River(**riv_data) + type_grid = type(riv_data["stage"]) + dis_pkg = TYPE_DIS_PKG[type_grid](**dis_data) + river.cleanup(dis_pkg) errors = river._validate(river._write_schemata, **dis_data) - assert len(errors) == 1 + assert len(errors) == 0 @parametrize_with_cases("riv_data,dis_data", cases=RivDisCases) @@ -210,11 +226,11 @@ def test_check_dimsize_zero(): @parametrize_with_cases("riv_data,dis_data", cases=RivDisCases) -def test_check_zero_conductance(riv_data, dis_data): +def test_validate_zero_conductance(riv_data, dis_data): """ - Test for zero conductance + Test for validation zero conductance """ - riv_data["conductance"] = riv_data["conductance"] * 0.0 + riv_data["conductance"][..., 2] = 0.0 river = imod.mf6.River(**riv_data) @@ -226,9 +242,25 @@ def test_check_zero_conductance(riv_data, dis_data): @parametrize_with_cases("riv_data,dis_data", cases=RivDisCases) -def test_check_bottom_above_stage(riv_data, dis_data): +def test_cleanup_zero_conductance(riv_data, dis_data): """ - Check that river bottom is not above stage. + Cleanup zero conductance + """ + riv_data["conductance"][..., 2] = 0.0 + type_grid = type(riv_data["stage"]) + dis_pkg = TYPE_DIS_PKG[type_grid](**dis_data) + + river = imod.mf6.River(**riv_data) + river.cleanup(dis_pkg) + + errors = river._validate(river._write_schemata, **dis_data) + assert len(errors) == 0 + + +@parametrize_with_cases("riv_data,dis_data", cases=RivDisCases) +def test_validate_bottom_above_stage(riv_data, dis_data): + """ + Validate that river bottom is not above stage. """ riv_data["bottom_elevation"] = riv_data["bottom_elevation"] + 10.0 @@ -238,8 +270,26 @@ def test_check_bottom_above_stage(riv_data, dis_data): errors = river._validate(river._write_schemata, **dis_data) assert len(errors) == 1 - for var, var_errors in errors.items(): - assert var == "stage" + assert "stage" in errors.keys() + + +@parametrize_with_cases("riv_data,dis_data", cases=RivDisCases) +def test_cleanup_bottom_above_stage(riv_data, dis_data): + """ + Cleanup river bottom above stage. + """ + + riv_data["bottom_elevation"] = riv_data["bottom_elevation"] + 10.0 + type_grid = type(riv_data["stage"]) + dis_pkg = TYPE_DIS_PKG[type_grid](**dis_data) + + river = imod.mf6.River(**riv_data) + river.cleanup(dis_pkg) + + errors = river._validate(river._write_schemata, **dis_data) + + assert len(errors) == 0 + assert river.dataset["bottom_elevation"].equals(river.dataset["stage"]) @parametrize_with_cases("riv_data,dis_data", cases=RivDisCases) @@ -280,12 +330,12 @@ def test_check_boundary_outside_active_domain(riv_data, dis_data): assert len(errors) == 1 -def test_check_dim_monotonicity(riv_dict): +def test_check_dim_monotonicity(): """ Test if dimensions are monotonically increasing or, in case of the y coord, decreasing """ - riv_ds = xr.merge([riv_dict]) + riv_ds = xr.merge([riv_dict()]) message = textwrap.dedent( """ @@ -327,19 +377,19 @@ def test_check_dim_monotonicity(riv_dict): imod.mf6.River(**riv_ds.sel(layer=slice(None, None, -1))) -def test_validate_false(riv_dict): +def test_validate_false(): """ Test turning off validation """ - riv_ds = xr.merge([riv_dict]) + riv_ds = xr.merge([riv_dict()]) imod.mf6.River(validate=False, **riv_ds.sel(layer=slice(None, None, -1))) @pytest.mark.usefixtures("concentration_fc") -def test_render_concentration(riv_dict, concentration_fc): - riv_ds = xr.merge([riv_dict]) +def test_render_concentration(concentration_fc): + riv_ds = xr.merge([riv_dict()]) concentration = concentration_fc.sel( layer=[2, 3], time=np.datetime64("2000-01-01"), drop=True diff --git a/imod/tests/test_prepare/test_cleanup.py b/imod/tests/test_prepare/test_cleanup.py new file mode 100644 index 000000000..1802ca22d --- /dev/null +++ b/imod/tests/test_prepare/test_cleanup.py @@ -0,0 +1,178 @@ +from typing import Callable + +import numpy as np +import pytest +import xugrid as xu +from pytest_cases import parametrize, parametrize_with_cases + +from imod.prepare.cleanup import cleanup_drn, cleanup_ghb, cleanup_riv +from imod.tests.test_mf6.test_mf6_riv import RivDisCases +from imod.typing import GridDataArray + + +def _first(grid: GridDataArray): + """ + helper function to get first value, regardless of unstructured or + structured grid.""" + return grid.values.ravel()[0] + + +def _first_index(grid: GridDataArray) -> tuple: + if isinstance(grid, xu.UgridDataArray): + return (0, 0) + else: + return (0, 0, 0) + + +def _rename_data_dict(data: dict, func: Callable): + renamed = data.copy() + to_rename = _RENAME_DICT[func] + for src, dst in to_rename.items(): + mv_data = renamed.pop(src) + if dst is not None: + renamed[dst] = mv_data + return renamed + + +def _prepare_dis_dict(dis_dict: dict, func: Callable): + """Keep required dis args for specific cleanup functions""" + keep_vars = _KEEP_FROM_DIS_DICT[func] + return {var: dis_dict[var] for var in keep_vars} + + +_RENAME_DICT = { + cleanup_riv: {}, + cleanup_drn: {"stage": "elevation", "bottom_elevation": None}, + cleanup_ghb: {"stage": "head", "bottom_elevation": None}, +} + +_KEEP_FROM_DIS_DICT = { + cleanup_riv: ["idomain", "bottom"], + cleanup_drn: ["idomain"], + cleanup_ghb: ["idomain"], +} + + +@parametrize_with_cases("riv_data, dis_data", cases=RivDisCases) +@parametrize("cleanup_func", [cleanup_drn, cleanup_ghb, cleanup_riv]) +def test_cleanup__align_nodata(riv_data: dict, dis_data: dict, cleanup_func: Callable): + dis_dict = _prepare_dis_dict(dis_data, cleanup_func) + data_dict = _rename_data_dict(riv_data, cleanup_func) + # Assure conductance not modified by previous tests. + np.testing.assert_equal(_first(data_dict["conductance"]), 1.0) + idx = _first_index(data_dict["conductance"]) + # Arrange: Deactivate one cell + first_key = next(iter(data_dict.keys())) + data_dict[first_key][idx] = np.nan + # Act + data_cleaned = cleanup_func(**dis_dict, **data_dict) + # Assert + for key in data_cleaned.keys(): + np.testing.assert_equal(_first(data_cleaned[key][idx]), np.nan) + + +@parametrize_with_cases("riv_data, dis_data", cases=RivDisCases) +@parametrize("cleanup_func", [cleanup_drn, cleanup_ghb, cleanup_riv]) +def test_cleanup__zero_conductance( + riv_data: dict, dis_data: dict, cleanup_func: Callable +): + dis_dict = _prepare_dis_dict(dis_data, cleanup_func) + data_dict = _rename_data_dict(riv_data, cleanup_func) + # Assure conductance not modified by previous tests. + np.testing.assert_equal(_first(data_dict["conductance"]), 1.0) + idx = _first_index(data_dict["conductance"]) + # Arrange: Deactivate one cell + data_dict["conductance"][idx] = 0.0 + # Act + data_cleaned = cleanup_func(**dis_dict, **data_dict) + # Assert + for key in data_cleaned.keys(): + np.testing.assert_equal(_first(data_cleaned[key][idx]), np.nan) + + +@parametrize_with_cases("riv_data, dis_data", cases=RivDisCases) +@parametrize("cleanup_func", [cleanup_drn, cleanup_ghb, cleanup_riv]) +def test_cleanup__negative_concentration( + riv_data: dict, dis_data: dict, cleanup_func: Callable +): + dis_dict = _prepare_dis_dict(dis_data, cleanup_func) + data_dict = _rename_data_dict(riv_data, cleanup_func) + first_key = next(iter(data_dict.keys())) + # Create concentration data + data_dict["concentration"] = data_dict[first_key].copy() + # Assure conductance not modified by previous tests. + np.testing.assert_equal(_first(data_dict["conductance"]), 1.0) + idx = _first_index(data_dict["conductance"]) + # Arrange: Deactivate one cell + data_dict["concentration"][idx] = -10.0 + # Act + data_cleaned = cleanup_func(**dis_dict, **data_dict) + # Assert + np.testing.assert_equal(_first(data_cleaned["concentration"]), 0.0) + + +@parametrize_with_cases("riv_data, dis_data", cases=RivDisCases) +@parametrize("cleanup_func", [cleanup_drn, cleanup_ghb, cleanup_riv]) +def test_cleanup__outside_active_domain( + riv_data: dict, dis_data: dict, cleanup_func: Callable +): + dis_dict = _prepare_dis_dict(dis_data, cleanup_func) + data_dict = _rename_data_dict(riv_data, cleanup_func) + # Assure conductance not modified by previous tests. + np.testing.assert_equal(_first(data_dict["conductance"]), 1.0) + idx = _first_index(data_dict["conductance"]) + # Arrange: Deactivate one cell + dis_dict["idomain"][idx] = 0.0 + # Act + data_cleaned = cleanup_func(**dis_dict, **data_dict) + # Assert + for key in data_cleaned.keys(): + np.testing.assert_equal(_first(data_cleaned[key][idx]), np.nan) + + +@parametrize_with_cases("riv_data, dis_data", cases=RivDisCases) +def test_cleanup_riv__fix_bottom_elevation_to_bottom(riv_data: dict, dis_data: dict): + dis_dict = _prepare_dis_dict(dis_data, cleanup_riv) + # Arrange: Set bottom elevation model layer bottom + riv_data["bottom_elevation"] -= 3.0 + # Assure conductance not modified by previous tests. + np.testing.assert_equal(_first(riv_data["conductance"]), 1.0) + # Act + riv_data_cleaned = cleanup_riv(**dis_dict, **riv_data) + # Assert + # Account for cells inactive river cells. + riv_active = riv_data_cleaned["stage"].notnull() + expected = dis_dict["bottom"].where(riv_active) + + np.testing.assert_equal( + riv_data_cleaned["bottom_elevation"].values, expected.values + ) + + +@parametrize_with_cases("riv_data, dis_data", cases=RivDisCases) +def test_cleanup_riv__fix_bottom_elevation_to_stage(riv_data: dict, dis_data: dict): + dis_dict = _prepare_dis_dict(dis_data, cleanup_riv) + # Arrange: Set bottom elevation above stage + riv_data["bottom_elevation"] += 3.0 + # Assure conductance not modified by previous tests. + np.testing.assert_equal(_first(riv_data["conductance"]), 1.0) + # Act + riv_data_cleaned = cleanup_riv(**dis_dict, **riv_data) + # Assert + np.testing.assert_equal( + riv_data_cleaned["bottom_elevation"].values, riv_data_cleaned["stage"].values + ) + + +@parametrize_with_cases("riv_data, dis_data", cases=RivDisCases) +def test_cleanup_riv__raise_error(riv_data: dict, dis_data: dict): + """ + Test if error raised when stage below model layer bottom and see if user is + guided to the right prepare function. + """ + dis_dict = _prepare_dis_dict(dis_data, cleanup_riv) + # Arrange: Set bottom elevation above stage + riv_data["stage"] -= 10.0 + # Act + with pytest.raises(ValueError, match="imod.prepare.topsystem.allocate_riv_cells"): + cleanup_riv(**dis_dict, **riv_data) From fa2fcfce80dc42d807da7d87083889b4c18fe72e Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Mon, 9 Sep 2024 15:37:09 +0200 Subject: [PATCH 42/53] Issue #1176 assign wells with point filters (#1186) Fixes #1176 # Description - Assign wells with point filters (filters with a zero length) to layers. Before, these would be removed in the compute_overlap method. - Add test case for wells with a point filter - Set validation so that screen_top can equal screen_bottom - Rename vague variable name "df" to "df_factor" # Checklist - [x] Links to correct issue - [x] Update changelog, if changes affect users - [x] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [x] Unit tests were added - [ ] **If feature added**: Added/extended example --------- Co-authored-by: Sunny Titus <77051845+Manangka@users.noreply.github.com> --- docs/api/changelog.rst | 4 + imod/mf6/wel.py | 11 +- imod/prepare/wells.py | 124 ++++++++++++------ imod/select/points.py | 38 ++++-- imod/tests/test_mf6/test_mf6_wel.py | 30 ++++- .../{ => test_prepare}/test_assign_wells.py | 115 +++++++++------- 6 files changed, 217 insertions(+), 105 deletions(-) rename imod/tests/{ => test_prepare}/test_assign_wells.py (77%) diff --git a/docs/api/changelog.rst b/docs/api/changelog.rst index aa30abdaf..ce0665ce3 100644 --- a/docs/api/changelog.rst +++ b/docs/api/changelog.rst @@ -36,6 +36,10 @@ Changed polygons. - :func:`open_projectfile_data` now returns well data grouped by ipf name, instead of generic, separate number per entry. +- :class:`imod.mf6.Well` now supports wells which have a filter with zero + length, where ``"screen_top"`` equals ``"screen_bottom"``. +- :class:`imod.mf6.Well` shares the same default ``minimum_thickness`` as + :func:`imod.prepare.assign_wells`, which is 0.05, before this was 1.0. Added ~~~~~ diff --git a/imod/mf6/wel.py b/imod/mf6/wel.py index b4072fd4d..aaf598d42 100644 --- a/imod/mf6/wel.py +++ b/imod/mf6/wel.py @@ -18,6 +18,7 @@ from imod.logging import init_log_decorator, logger from imod.logging.logging_decorators import standard_log_decorator from imod.logging.loglevel import LogLevel +from imod.mf6 import StructuredDiscretization, VerticesDiscretization from imod.mf6.boundary_condition import ( BoundaryCondition, DisStructuredBoundaryCondition, @@ -339,7 +340,7 @@ def _derive_cellid_from_points( "x": ("ncellid", x), "y": ("ncellid", y), } - cellid = cellid.assign_coords(**coords) + cellid = cellid.assign_coords(coords=coords) return cellid @@ -505,7 +506,7 @@ def from_imod5_data( imod5_data: dict[str, dict[str, GridDataArray]], times: list[datetime], minimum_k: float = 0.1, - minimum_thickness: float = 1.0, + minimum_thickness: float = 0.05, ) -> "GridAgnosticWell": """ Convert wells to imod5 data, loaded with @@ -728,7 +729,7 @@ class Well(GridAgnosticWell): "screen_bottom": [ AnyNoDataSchema(), EmptyIndexesSchema(), - AllValueSchema("<", "screen_top"), + AllValueSchema("<=", "screen_top"), ], "y": [AnyNoDataSchema(), EmptyIndexesSchema()], "x": [AnyNoDataSchema(), EmptyIndexesSchema()], @@ -754,7 +755,7 @@ def __init__( concentration_boundary_type="aux", id: Optional[list[Any]] = None, minimum_k: float = 0.1, - minimum_thickness: float = 1.0, + minimum_thickness: float = 0.05, print_input: bool = False, print_flows: bool = False, save_flows: bool = False, @@ -972,7 +973,7 @@ def _validate_imod5_depth_information( logger.log(loglevel=LogLevel.ERROR, message=log_msg, additional_depth=2) raise ValueError(log_msg) - def cleanup(self): + def cleanup(self, _: StructuredDiscretization | VerticesDiscretization): self.dataset = cleanup_wel(self.dataset) diff --git a/imod/prepare/wells.py b/imod/prepare/wells.py index 7c69e2cb4..0f6d41517 100644 --- a/imod/prepare/wells.py +++ b/imod/prepare/wells.py @@ -2,17 +2,21 @@ Assign wells to layers. """ -from typing import Optional, Union +from typing import Optional import numpy as np +import numpy.typing as npt import pandas as pd import xarray as xr import xugrid as xu import imod +from imod.typing import GridDataArray -def vectorized_overlap(bounds_a, bounds_b): +def compute_vectorized_overlap( + bounds_a: npt.NDArray[np.float64], bounds_b: npt.NDArray[np.float64] +) -> npt.NDArray[np.float64]: """ Vectorized overlap computation. Compare with: @@ -25,30 +29,66 @@ def vectorized_overlap(bounds_a, bounds_b): ) -def compute_overlap(wells, top, bottom): - # layer bounds shape of (n_well, n_layer, 2) - layer_bounds = np.stack((bottom, top), axis=-1) +def compute_point_filter_overlap( + bounds_wells: npt.NDArray[np.float64], bounds_layers: npt.NDArray[np.float64] +) -> npt.NDArray[np.float64]: + """ + Special case for filters with zero filter length, these are set to layer + thickness. Filters which are not in a layer or have a nonzero filter length + are set to zero overlap. + """ + # Unwrap for readability + wells_top = bounds_wells[:, 1] + wells_bottom = bounds_wells[:, 0] + layers_top = bounds_layers[:, 1] + layers_bottom = bounds_layers[:, 0] + + has_zero_filter_length = wells_top == wells_bottom + in_layer = (layers_top >= wells_top) & (layers_bottom < wells_bottom) + layer_thickness = layers_top - layers_bottom + # Multiplication to set any elements not meeting the criteria to zero. + point_filter_overlap = ( + has_zero_filter_length.astype(float) * in_layer.astype(float) * layer_thickness + ) + return point_filter_overlap + + +def compute_overlap( + wells: pd.DataFrame, top: GridDataArray, bottom: GridDataArray +) -> npt.NDArray[np.float64]: + # layer bounds stack shape of (n_well, n_layer, 2) + layer_bounds_stack = np.stack((bottom, top), axis=-1) well_bounds = np.broadcast_to( np.stack( (wells["bottom"].to_numpy(), wells["top"].to_numpy()), axis=-1, )[np.newaxis, :, :], - layer_bounds.shape, + layer_bounds_stack.shape, + ).reshape(-1, 2) + layer_bounds = layer_bounds_stack.reshape(-1, 2) + + # Deal with filters with a nonzero length + interval_filter_overlap = compute_vectorized_overlap( + well_bounds, + layer_bounds, ) - overlap = vectorized_overlap( - well_bounds.reshape((-1, 2)), - layer_bounds.reshape((-1, 2)), + # Deal with filters with zero length + point_filter_overlap = compute_point_filter_overlap( + well_bounds, + layer_bounds, ) - return overlap + return np.maximum(interval_filter_overlap, point_filter_overlap) def locate_wells( wells: pd.DataFrame, - top: Union[xr.DataArray, xu.UgridDataArray], - bottom: Union[xr.DataArray, xu.UgridDataArray], - k: Optional[Union[xr.DataArray, xu.UgridDataArray]], + top: GridDataArray, + bottom: GridDataArray, + k: Optional[GridDataArray], validate: bool = True, -): +) -> tuple[ + npt.NDArray[np.object_], GridDataArray, GridDataArray, float | GridDataArray +]: if not isinstance(top, (xu.UgridDataArray, xr.DataArray)): raise TypeError( "top and bottom should be DataArray or UgridDataArray, received: " @@ -56,7 +96,7 @@ def locate_wells( ) # Default to a xy_k value of 1.0: weigh every layer equally. - xy_k = 1.0 + xy_k: float | GridDataArray = 1.0 first = wells.groupby("id").first() x = first["x"].to_numpy() y = first["y"].to_numpy() @@ -88,9 +128,9 @@ def locate_wells( def assign_wells( wells: pd.DataFrame, - top: Union[xr.DataArray, xu.UgridDataArray], - bottom: Union[xr.DataArray, xu.UgridDataArray], - k: Optional[Union[xr.DataArray, xu.UgridDataArray]] = None, + top: GridDataArray, + bottom: GridDataArray, + k: Optional[GridDataArray] = None, minimum_thickness: Optional[float] = 0.05, minimum_k: Optional[float] = 1.0, validate: bool = True, @@ -101,17 +141,19 @@ def assign_wells( thickness and minimum k should be set to avoid placing wells in clay layers. - Wells located outside of the grid are removed. + Wells where well screen_top equals screen_bottom are assigned to the layer + they are located in, without any subdivision. Wells located outside of the + grid are removed. Parameters ---------- - wells: pd.DataFrame + wells: pandas.DataFrame Should contain columns x, y, id, top, bottom, rate. - top: xr.DataArray or xu.UgridDataArray + top: xarray.DataArray or xugrid.UgridDataArray Top of the model layers. - bottom: xr.DataArray or xu.UgridDataArray + bottom: xarray.DataArray or xugrid.UgridDataArray Bottom of the model layers. - k: xr.DataArray or xu.UgridDataArray, optional + k: xarray.DataArray or xugrid.UgridDataArray, optional Horizontal conductivity of the model layers. minimum_thickness: float, optional, default: 0.01 minimum_k: float, optional, default: 1.0 @@ -145,36 +187,40 @@ def assign_wells( first = wells_in_bounds.groupby("id").first() overlap = compute_overlap(first, xy_top, xy_bottom) - if k is None: - k = 1.0 + if isinstance(xy_k, (xr.DataArray, xu.UgridDataArray)): + k_for_df = xy_k.values.ravel() else: - k = xy_k.values.ravel() + k_for_df = xy_k # Distribute rate according to transmissivity. n_layer, n_well = xy_top.shape - df = pd.DataFrame( + df_factor = pd.DataFrame( index=pd.Index(np.tile(first.index, n_layer), name="id"), data={ "layer": np.repeat(top["layer"], n_well), "overlap": overlap, - "k": k, - "transmissivity": overlap * k, + "k": k_for_df, + "transmissivity": overlap * k_for_df, }, ) # remove entries # -in very thin layers or when the wellbore penetrates the layer very little # -in low conductivity layers - df = df.loc[(df["overlap"] >= minimum_thickness) & (df["k"] >= minimum_k)] - df["rate"] = df["transmissivity"] / df.groupby("id")["transmissivity"].transform( - "sum" - ) + df_factor = df_factor.loc[ + (df_factor["overlap"] >= minimum_thickness) & (df_factor["k"] >= minimum_k) + ] + df_factor["rate"] = df_factor["transmissivity"] / df_factor.groupby("id")[ + "transmissivity" + ].transform("sum") # Create a unique index for every id-layer combination. - df["index"] = np.arange(len(df)) - df = df.reset_index() + df_factor["index"] = np.arange(len(df_factor)) + df_factor = df_factor.reset_index() # Get rid of those that are removed because of minimum thickness or # transmissivity. - wells_in_bounds = wells_in_bounds.loc[wells_in_bounds["id"].isin(df["id"].unique())] + wells_in_bounds = wells_in_bounds.loc[ + wells_in_bounds["id"].isin(df_factor["id"].unique()) + ] # Use pandas multi-index broadcasting. # Maintain all other columns as-is. @@ -182,7 +228,7 @@ def assign_wells( wells_in_bounds["overlap"] = 1.0 wells_in_bounds["k"] = 1.0 wells_in_bounds["transmissivity"] = 1.0 - columns = list(set(wells_in_bounds.columns).difference(df.columns)) + columns = list(set(wells_in_bounds.columns).difference(df_factor.columns)) indexes = ["id"] for dim in ["species", "time"]: @@ -190,9 +236,9 @@ def assign_wells( indexes.append(dim) columns.remove(dim) - df[columns] = 1 # N.B. integer! + df_factor[columns] = 1 # N.B. integer! assigned = ( - wells_in_bounds.set_index(indexes) * df.set_index(["id", "layer"]) + wells_in_bounds.set_index(indexes) * df_factor.set_index(["id", "layer"]) ).reset_index() return assigned diff --git a/imod/select/points.py b/imod/select/points.py index a083824d9..1cd8a909b 100644 --- a/imod/select/points.py +++ b/imod/select/points.py @@ -1,13 +1,16 @@ import warnings +from typing import Any import numpy as np +import numpy.typing as npt import xarray as xr import xugrid as xu import imod +from imod.typing import GridDataArray -def get_unstructured_cell2d_from_xy(uda, **points): +def get_unstructured_cell2d_from_xy(uda: xu.UgridDataArray, **points) -> npt.NDArray: # Unstructured grids always require to be tested both on x and y coordinates # to see if points are within bounds. for coord in ["x", "y"]: @@ -21,7 +24,7 @@ def get_unstructured_cell2d_from_xy(uda, **points): return uda.ugrid.grid.locate_points(xy) -def __check_and_get_points_shape(points) -> dict: +def __check_and_get_points_shape(points: dict) -> dict: """Check whether points have the right shape""" shapes = {} for coord, value in points.items(): @@ -36,13 +39,13 @@ def __check_and_get_points_shape(points) -> dict: return shapes -def __check_point_shapes_consistency(shapes): +def __check_point_shapes_consistency(shapes: dict): if not len(set(shapes.values())) == 1: msg = "\n".join([f"{coord}: {shape}" for coord, shape in shapes.items()]) raise ValueError(f"Shapes of coordinates do match each other:\n{msg}") -def _check_points(points): +def _check_points(points: dict): """ Check whether the array with points has the right and consistent shape. """ @@ -51,7 +54,7 @@ def _check_points(points): __check_point_shapes_consistency(shapes) -def __arr_like_points(points, fill_value): +def __arr_like_points(points: dict, fill_value: Any) -> npt.NDArray: """ Return array with the same shape as the first array provided in points. """ @@ -61,7 +64,7 @@ def __arr_like_points(points, fill_value): return np.full(shape, fill_value) -def points_in_bounds(da, **points): +def points_in_bounds(da: GridDataArray, **points) -> npt.NDArray[np.bool]: """ Returns whether points specified by keyword arguments fall within the bounds of ``da``. @@ -117,7 +120,7 @@ def points_in_bounds(da, **points): return in_bounds -def check_points_in_bounds(da, points, out_of_bounds): +def check_points_in_bounds(da: GridDataArray, points: dict, out_of_bounds: str): inside = points_in_bounds(da, **points) # Error handling msg = "Not all points are located within the bounds of the DataArray" @@ -137,7 +140,9 @@ def check_points_in_bounds(da, points, out_of_bounds): return points, inside -def _get_indices_1d(da, coordname, x): +def _get_indices_1d( + da: xr.DataArray, coordname: str, x: npt.NDArray[np.floating] +) -> npt.NDArray[np.intp]: x = np.atleast_1d(x) x_decreasing = da.indexes[coordname].is_monotonic_decreasing dx, xmin, _ = imod.util.spatial.coord_reference(da.coords[coordname]) @@ -172,7 +177,9 @@ def _get_indices_1d(da, coordname, x): return ixs -def points_indices(da, out_of_bounds="raise", **points): +def points_indices( + da: GridDataArray, out_of_bounds: str = "raise", **points +) -> dict[str, xr.DataArray]: """ Get the indices for points as defined by the arrays x and y. @@ -184,7 +191,7 @@ def points_indices(da, out_of_bounds="raise", **points): Parameters ---------- - da : xr.DataArray + da : xarray.DataArray | xu.UgridDataArray out_of_bounds : {"raise", "warn", "ignore"}, default: "raise" What to do if the points are not located in the bounds of the DataArray: @@ -246,7 +253,7 @@ def points_indices(da, out_of_bounds="raise", **points): return indices -def points_values(da, out_of_bounds="raise", **points): +def points_values(da: GridDataArray, out_of_bounds="raise", **points) -> GridDataArray: """ Get values from specified points. @@ -287,12 +294,17 @@ def points_values(da, out_of_bounds="raise", **points): indices = imod.select.points.points_indices( da, out_of_bounds=out_of_bounds, **iterable_points ) - selection = da.isel(**indices) + selection = da.isel(indexers=indices) return selection -def points_set_values(da, values, out_of_bounds="raise", **points): +def points_set_values( + da: GridDataArray, + values: int | float | npt.NDArray[np.number], + out_of_bounds: str = "raise", + **points, +): """ Set values at specified points. diff --git a/imod/tests/test_mf6/test_mf6_wel.py b/imod/tests/test_mf6/test_mf6_wel.py index 9e8da6639..c4893949c 100644 --- a/imod/tests/test_mf6/test_mf6_wel.py +++ b/imod/tests/test_mf6/test_mf6_wel.py @@ -89,6 +89,32 @@ def case_well_stationary_multilevel(self, well_high_lvl_test_data_stationary): rate_expected = np.array([0.25] * 4 + [0.75] * 4 + [1.0] * 4) return obj, dims_expected, cellid_expected, rate_expected + def case_well_point_filter(self, well_high_lvl_test_data_stationary): + x, y, screen_point, _, rate_wel, concentration = ( + well_high_lvl_test_data_stationary + ) + obj = imod.mf6.Well(x, y, screen_point, screen_point, rate_wel, concentration) + dims_expected = { + "ncellid": 8, + "nmax_cellid": 3, + "species": 2, + } + cellid_expected = np.array( + [ + [1, 1, 9], + [1, 2, 9], + [1, 1, 8], + [1, 2, 8], + [2, 3, 7], + [2, 4, 7], + [2, 3, 6], + [2, 4, 6], + ], + dtype=np.int64, + ) + rate_expected = np.array(np.ones((8,), dtype=np.float32)) + return obj, dims_expected, cellid_expected, rate_expected + def case_well_transient(self, well_high_lvl_test_data_transient): obj = imod.mf6.Well(*well_high_lvl_test_data_transient) dims_expected = { @@ -221,7 +247,7 @@ def test_to_mf6_pkg__validate_filter_top(well_high_lvl_test_data_stationary): assert len(errors) == 1 assert ( str(errors["screen_bottom"][0]) - == "not all values comply with criterion: < screen_top" + == "not all values comply with criterion: <= screen_top" ) @@ -911,7 +937,7 @@ def test_import_and_convert_to_mf6(imod5_dataset, tmp_path, wel_class): times = list(pd.date_range(datetime(1989, 1, 1), datetime(2013, 1, 1), 8400)) # import grid-agnostic well from imod5 data (it contains 1 well) - wel = wel_class.from_imod5_data("wel-WELLS_L3", data, times) + wel = wel_class.from_imod5_data("wel-WELLS_L3", data, times, minimum_thickness=1.0) assert wel.dataset["x"].values[0] == 197910.0 assert wel.dataset["y"].values[0] == 362860.0 assert np.mean(wel.dataset["rate"].values) == -317.2059091946156 diff --git a/imod/tests/test_assign_wells.py b/imod/tests/test_prepare/test_assign_wells.py similarity index 77% rename from imod/tests/test_assign_wells.py rename to imod/tests/test_prepare/test_assign_wells.py index 38f2669ce..ad22c9bd2 100644 --- a/imod/tests/test_assign_wells.py +++ b/imod/tests/test_prepare/test_assign_wells.py @@ -8,7 +8,7 @@ from imod.testing import assert_frame_equal -def test_vectorized_overlap(): +def test_compute_vectorized_overlap(): bounds_a = np.array( [ [0.0, 3.0], @@ -21,34 +21,57 @@ def test_vectorized_overlap(): [1.0, 2.0], ] ) - actual = prepwel.vectorized_overlap(bounds_a, bounds_b) + actual = prepwel.compute_vectorized_overlap(bounds_a, bounds_b) assert np.array_equal(actual, np.array([1.0, 1.0])) +def test_compute_point_filter_overlap(): + bounds_well = np.array( + [ + [0.0, 0.0], + [0.0, 0.0], + [0.0, 1.0], + [0.0, 0.0], + [0.0, 0.0], + ] + ) + bounds_layer = np.array( + [ + [1.0, 2.0], + [-1.0, 2.0], + [-1.0, 2.0], + [0.0, 0.0], + [-5.0, -4.0], + ] + ) + actual = prepwel.compute_point_filter_overlap(bounds_well, bounds_layer) + assert np.array_equal(actual, np.array([0.0, 3.0, 0.0, 0.0, 0.0])) + + def test_compute_overlap(): # Three wells wells = pd.DataFrame( { - "top": [5.0, 4.0, 3.0], - "bottom": [4.0, 2.0, -1.0], + "top": [5.0, 4.0, 3.0, 0.0], + "bottom": [4.0, 2.0, -1.0, 0.0], } ) top = xr.DataArray( data=[ - [10.0, 10.0, 10.0], - [0.0, 0.0, 0.0], + [10.0, 10.0, 10.0, 10.0], + [0.0, 0.0, 0.0, 0.0], ], dims=["layer", "index"], ) bottom = xr.DataArray( data=[ - [0.0, 0.0, 0.0], - [-10.0, -10.0, -10.0], + [0.0, 0.0, 0.0, 0.0], + [-10.0, -10.0, -10.0, -10.0], ], dims=["layer", "index"], ) actual = prepwel.compute_overlap(wells, top, bottom) - expected = np.array([1.0, 2.0, 3.0, 0.0, 0.0, 1.0]) + expected = np.array([1.0, 2.0, 3.0, 0.0, 0.0, 0.0, 1.0, 10.0]) assert np.allclose(actual, expected) @@ -79,7 +102,7 @@ def case_mix_wells(self): "id": [1, 2, 3, 4], "top": [5.0, 4.0, 3.0, 0.0], "bottom": [4.0, 2.0, -1.0, 0.0], - "rate": [1.0, 10.0, 100.0, 0.0], + "rate": [1.0, 10.0, 100.0, 0.1], } ) return wells, top, bottom, k @@ -109,7 +132,7 @@ def case_all_in_domain(self): "id": [1, 2, 3, 4], "top": [5.0, 4.0, 3.0, 0.0], "bottom": [4.0, 2.0, -1.0, 0.0], - "rate": [1.0, 10.0, 100.0, 0.0], + "rate": [1.0, 10.0, 100.0, 0.1], } ) @@ -190,17 +213,17 @@ def test_assign_wells__no_kh(self, wells, top, bottom, k): assert isinstance(actual, pd.DataFrame) expected = pd.DataFrame( { - "index": [0, 1, 2, 3], - "id": [1, 2, 3, 3], - "layer": [1, 1, 1, 2], - "bottom": [4.0, 2.0, -1.0, -1.0], - "overlap": [1.0, 2.0, 3.0, 1.0], - "rate": [1.0, 10.0, 75.0, 25.0], - "top": [5.0, 4.0, 3.0, 3.0], - "k": [1.0, 1.0, 1.0, 1.0], - "transmissivity": [1.0, 2.0, 3.0, 1.0], - "x": [0.6, 1.1, 2.3, 2.3], - "y": [0.6, 1.1, 2.3, 2.3], + "index": [0, 1, 2, 3, 4], + "id": [1, 2, 3, 3, 4], + "layer": [1, 1, 1, 2, 2], + "bottom": [4.0, 2.0, -1.0, -1.0, 0.0], + "overlap": [1.0, 2.0, 3.0, 1.0, 10.0], + "rate": [1.0, 10.0, 75.0, 25.0, 0.1], + "top": [5.0, 4.0, 3.0, 3.0, 0.0], + "k": [1.0, 1.0, 1.0, 1.0, 1.0], + "transmissivity": [1.0, 2.0, 3.0, 1.0, 10.0], + "x": [0.6, 1.1, 2.3, 2.3, 2.6], + "y": [0.6, 1.1, 2.3, 2.3, 2.6], } ) assert_frame_equal(actual, expected, check_like=True) @@ -218,17 +241,17 @@ def test_assign_wells(self, wells, top, bottom, k): assert isinstance(actual, pd.DataFrame) expected = pd.DataFrame( { - "index": [0, 1, 2, 3], - "id": [1, 2, 3, 3], - "layer": [1, 1, 1, 2], - "bottom": [4.0, 2.0, -1.0, -1.0], - "overlap": [1.0, 2.0, 3.0, 1.0], - "rate": [1.0, 10.0, 60.0, 40.0], - "top": [5.0, 4.0, 3.0, 3.0], - "k": [10.0, 10.0, 10.0, 20.0], - "transmissivity": [10.0, 20.0, 30.0, 20.0], - "x": [0.6, 1.1, 2.3, 2.3], - "y": [0.6, 1.1, 2.3, 2.3], + "index": [0, 1, 2, 3, 4], + "id": [1, 2, 3, 3, 4], + "layer": [1, 1, 1, 2, 2], + "bottom": [4.0, 2.0, -1.0, -1.0, 0.0], + "overlap": [1.0, 2.0, 3.0, 1.0, 10.0], + "rate": [1.0, 10.0, 60.0, 40.0, 0.1], + "top": [5.0, 4.0, 3.0, 3.0, 0.0], + "k": [10.0, 10.0, 10.0, 20.0, 20.0], + "transmissivity": [10.0, 20.0, 30.0, 20.0, 200.0], + "x": [0.6, 1.1, 2.3, 2.3, 2.6], + "y": [0.6, 1.1, 2.3, 2.3, 2.6], } ) assert_frame_equal(actual, expected, check_like=True) @@ -247,17 +270,17 @@ def test_assign_wells_minimum_thickness(self, wells, top, bottom, k): assert isinstance(actual, pd.DataFrame) expected = pd.DataFrame( { - "index": [0, 1], - "id": [2, 3], - "layer": [1, 1], - "bottom": [2.0, -1.0], - "overlap": [2.0, 3.0], - "rate": [10.0, 100.0], - "top": [4.0, 3.0], - "k": [10.0, 10.0], - "transmissivity": [20.0, 30.0], - "x": [1.1, 2.3], - "y": [1.1, 2.3], + "index": [0, 1, 2], + "id": [2, 3, 4], + "layer": [1, 1, 2], + "bottom": [2.0, -1.0, 0.0], + "overlap": [2.0, 3.0, 10.0], + "rate": [10.0, 100.0, 0.1], + "top": [4.0, 3.0, 0.0], + "k": [10.0, 10.0, 20.0], + "transmissivity": [20.0, 30.0, 200.0], + "x": [1.1, 2.3, 2.6], + "y": [1.1, 2.3, 2.6], } ) assert_frame_equal(actual, expected, check_like=True) @@ -281,7 +304,7 @@ def test_assign_wells_transient_rate(self, wells, top, bottom, k): bottom=bottom, k=k, ) - assert np.array_equal(actual["id"], np.repeat([1, 2, 3, 3], 5)) + assert np.array_equal(actual["id"], np.repeat([1, 2, 3, 3, 4], 5)) actual = prepwel.assign_wells( wells=transient_wells, @@ -290,7 +313,7 @@ def test_assign_wells_transient_rate(self, wells, top, bottom, k): k=k, minimum_thickness=1.01, ) - assert np.array_equal(actual["id"], np.repeat([2, 3], 5)) + assert np.array_equal(actual["id"], np.repeat([2, 3, 4], 5)) @parametrize_with_cases( "wells, top, bottom, k", cases=AssignWellCases.case_mix_wells From 657a0a8db7bb4d7a49d52aac5a81e4b115449fc2 Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Wed, 11 Sep 2024 18:23:08 +0200 Subject: [PATCH 43/53] Issue #1187 cleanup wells (#1206) Fixes #1187 # Description Adds cleanup utility for wells, as well as a method on the ``Well`` object. ``LayeredWell`` doesn't have ``cleanup`` method yet, as cleaning up almost purely focuses on adjusting filter screen levels for now. The function as well as the method are a bit more involved than the other cleanup utilities, because we are dealing here with a comparison of point data and grids. # Checklist - [x] Links to correct issue - [x] Update changelog, if changes affect users - [x] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [x] Unit tests were added - [ ] **If feature added**: Added/extended example --- docs/api/changelog.rst | 11 +- docs/api/mf6.rst | 1 + docs/api/prepare.rst | 1 + imod/mf6/wel.py | 41 +++++- imod/prepare/__init__.py | 2 +- imod/prepare/cleanup.py | 133 ++++++++++++++++++- imod/prepare/wells.py | 34 +++-- imod/tests/test_mf6/test_mf6_riv.py | 8 ++ imod/tests/test_mf6/test_mf6_wel.py | 46 +++++++ imod/tests/test_prepare/test_assign_wells.py | 4 +- imod/tests/test_prepare/test_cleanup.py | 74 ++++++++++- 11 files changed, 322 insertions(+), 33 deletions(-) diff --git a/docs/api/changelog.rst b/docs/api/changelog.rst index ce0665ce3..5ca3aef20 100644 --- a/docs/api/changelog.rst +++ b/docs/api/changelog.rst @@ -56,12 +56,13 @@ Added - :class:`imod.mf6.LayeredWell` to specify wells directly to layers instead assigning them with filter depths. - :func:`imod.prepare.cleanup_drn`, :func:`imod.prepare.cleanup_ghb`, - :func:`imod.prepare.cleanup_riv`. These are utility functions to clean up - drainage, general head boundaries, and rivers, respectively. + :func:`imod.prepare.cleanup_riv`, :func:`imod.prepare.cleanup_wel`. These are + utility functions to clean up drainage, general head boundaries, and rivers, + respectively. - :meth:`imod.mf6.Drainage.cleanup`, - :meth:`imod.mf6.GeneralHeadboundary.cleanup`, :meth:`imod.mf6.River.cleanup` - convenience methods to call the corresponding cleanup utility functions with - the appropriate arguments. + :meth:`imod.mf6.GeneralHeadboundary.cleanup`, :meth:`imod.mf6.River.cleanup`, + :meth:`imod.mf6.Well.cleanup` convenience methods to call the corresponding + cleanup utility functions with the appropriate arguments. Removed diff --git a/docs/api/mf6.rst b/docs/api/mf6.rst index e11ed45b4..aca682c48 100644 --- a/docs/api/mf6.rst +++ b/docs/api/mf6.rst @@ -97,6 +97,7 @@ Flow Packages StorageCoefficient UnsaturatedZoneFlow Well + Well.cleanup Well.from_imod5_data Well.mask Well.regrid_like diff --git a/docs/api/prepare.rst b/docs/api/prepare.rst index b8aed4a19..74c4aa75f 100644 --- a/docs/api/prepare.rst +++ b/docs/api/prepare.rst @@ -51,3 +51,4 @@ Prepare model input cleanup_drn cleanup_ghb cleanup_riv + cleanup_wel diff --git a/imod/mf6/wel.py b/imod/mf6/wel.py index aaf598d42..ed57ece73 100644 --- a/imod/mf6/wel.py +++ b/imod/mf6/wel.py @@ -15,6 +15,7 @@ import xugrid as xu import imod +import imod.mf6.utilities from imod.logging import init_log_decorator, logger from imod.logging.logging_decorators import standard_log_decorator from imod.logging.loglevel import LogLevel @@ -28,6 +29,7 @@ from imod.mf6.mf6_wel_adapter import Mf6Wel from imod.mf6.package import Package from imod.mf6.utilities.dataset import remove_inactive +from imod.mf6.utilities.grid import broadcast_to_full_domain from imod.mf6.validation import validation_pkg_error_message from imod.mf6.write_context import WriteContext from imod.prepare import assign_wells @@ -973,8 +975,43 @@ def _validate_imod5_depth_information( logger.log(loglevel=LogLevel.ERROR, message=log_msg, additional_depth=2) raise ValueError(log_msg) - def cleanup(self, _: StructuredDiscretization | VerticesDiscretization): - self.dataset = cleanup_wel(self.dataset) + @standard_log_decorator() + def cleanup(self, dis: StructuredDiscretization | VerticesDiscretization): + """ + Clean up package inplace. This method calls + :func:`imod.prepare.cleanup.cleanup_wel`, see documentation of that + function for details on cleanup. + + dis: imod.mf6.StructuredDiscretization | imod.mf6.VerticesDiscretization + Model discretization package. + """ + # Top and bottom should be forced to grids with a x, y coordinates + top, bottom = broadcast_to_full_domain(**dict(dis.dataset.data_vars)) + # Collect point variable datanames + point_varnames = list(self._write_schemata.keys()) + if "concentration" not in self.dataset.keys(): + point_varnames.remove("concentration") + point_varnames.append("id") + # Create dataset with purely point locations + point_ds = self.dataset[point_varnames] + # Take first item of irrelevant dimensions + point_ds = point_ds.isel(time=0, species=0, drop=True, missing_dims="ignore") + # Cleanup well dataframe + wells = point_ds.to_dataframe() + minimum_thickness = float(self.dataset["minimum_thickness"]) + cleaned_wells = cleanup_wel(wells, top.isel(layer=0), bottom, minimum_thickness) + # Select with ids in cleaned dataframe to drop points outside grid. + well_ids = cleaned_wells.index + dataset_cleaned = self.dataset.swap_dims({"index": "id"}).sel(id=well_ids) + # Assign adjusted screen top and bottom + dataset_cleaned["screen_top"] = cleaned_wells["screen_top"] + dataset_cleaned["screen_bottom"] = cleaned_wells["screen_bottom"] + # Ensure dtype of id is preserved + id_type = self.dataset["id"].dtype + dataset_cleaned = dataset_cleaned.swap_dims({"id": "index"}).reset_coords("id") + dataset_cleaned["id"] = dataset_cleaned["id"].astype(id_type) + # Override dataset + self.dataset = dataset_cleaned class LayeredWell(GridAgnosticWell): diff --git a/imod/prepare/__init__.py b/imod/prepare/__init__.py index 2ea86c3cb..03342c87e 100644 --- a/imod/prepare/__init__.py +++ b/imod/prepare/__init__.py @@ -14,7 +14,7 @@ """ from imod.prepare import hfb, spatial, subsoil, surface_water -from imod.prepare.cleanup import cleanup_drn, cleanup_ghb, cleanup_riv +from imod.prepare.cleanup import cleanup_drn, cleanup_ghb, cleanup_riv, cleanup_wel from imod.prepare.hfb import ( linestring_to_square_zpolygons, linestring_to_trapezoid_zpolygons, diff --git a/imod/prepare/cleanup.py b/imod/prepare/cleanup.py index 0d6edf10d..39a36b66b 100644 --- a/imod/prepare/cleanup.py +++ b/imod/prepare/cleanup.py @@ -3,11 +3,13 @@ from enum import Enum from typing import Optional +import pandas as pd import xarray as xr from imod.mf6.utilities.mask import mask_arrays +from imod.prepare.wells import locate_wells, validate_well_columnnames from imod.schemata import scalar_None -from imod.typing import GridDataArray, GridDataset +from imod.typing import GridDataArray class AlignLevelsMode(Enum): @@ -83,7 +85,7 @@ def cleanup_riv( idomain: xarray.DataArray | xugrid.UgridDataArray MODFLOW 6 model domain. idomain==1 is considered active domain. bottom: xarray.DataArray | xugrid.UgridDataArray - Grid with`model bottoms + Grid with model bottoms stage: xarray.DataArray | xugrid.UgridDataArray Grid with river stages conductance: xarray.DataArray | xugrid.UgridDataArray @@ -209,11 +211,128 @@ def cleanup_ghb( return _cleanup_robin_boundary(idomain, output_dict) -def cleanup_wel(wel_ds: GridDataset): +def _locate_wells_in_bounds( + wells: pd.DataFrame, top: GridDataArray, bottom: GridDataArray +) -> tuple[pd.DataFrame, pd.Series, pd.Series]: """ - Clean up wells + Locate wells in model bounds, wells outside bounds are dropped. Returned + dataframes and series have well "id" as index. - - Removes wells where the screen bottom elevation exceeds screen top. + Returns + ------- + wells_in_bounds: pd.DataFrame + wells in model boundaries. Has "id" as index. + xy_top_series: pd.Series + model top at well xy location. Has "id" as index. + xy_base_series: pd.Series + model base at well xy location. Has "id" as index. """ - deactivate = wel_ds["screen_top"] < wel_ds["screen_bottom"] - return wel_ds.where(~deactivate, drop=True) + id_in_bounds, xy_top, xy_bottom, _ = locate_wells( + wells, top, bottom, validate=False + ) + xy_base_model = xy_bottom.isel(layer=-1, drop=True) + + # Assign id as coordinates + xy_top = xy_top.assign_coords(id=("index", id_in_bounds)) + xy_base_model = xy_base_model.assign_coords(id=("index", id_in_bounds)) + # Create pandas dataframes/series with "id" as index. + xy_top_series = xy_top.to_dataframe(name="top").set_index("id")["top"] + xy_base_series = xy_base_model.to_dataframe(name="bottom").set_index("id")["bottom"] + wells_in_bounds = wells.set_index("id").loc[id_in_bounds] + return wells_in_bounds, xy_top_series, xy_base_series + + +def _clip_filter_screen_to_surface_level( + cleaned_wells: pd.DataFrame, xy_top_series: pd.Series +) -> pd.DataFrame: + cleaned_wells["screen_top"] = cleaned_wells["screen_top"].clip(upper=xy_top_series) + return cleaned_wells + + +def _drop_wells_below_model_base( + cleaned_wells: pd.DataFrame, xy_base_series: pd.Series +) -> pd.DataFrame: + is_below_base = cleaned_wells["screen_top"] >= xy_base_series + return cleaned_wells.loc[is_below_base] + + +def _clip_filter_bottom_to_model_base( + cleaned_wells: pd.DataFrame, xy_base_series: pd.Series +) -> pd.DataFrame: + cleaned_wells["screen_bottom"] = cleaned_wells["screen_bottom"].clip( + lower=xy_base_series + ) + return cleaned_wells + + +def _set_inverted_filters_to_point_filters(cleaned_wells: pd.DataFrame) -> pd.DataFrame: + # Convert all filters where screen bottom exceeds screen top to + # point filters + cleaned_wells["screen_bottom"] = cleaned_wells["screen_bottom"].clip( + upper=cleaned_wells["screen_top"] + ) + return cleaned_wells + + +def _set_ultrathin_filters_to_point_filters( + cleaned_wells: pd.DataFrame, minimum_thickness: float +) -> pd.DataFrame: + not_ultrathin_layer = ( + cleaned_wells["screen_top"] - cleaned_wells["screen_bottom"] + ) > minimum_thickness + cleaned_wells["screen_bottom"] = cleaned_wells["screen_bottom"].where( + not_ultrathin_layer, cleaned_wells["screen_top"] + ) + return cleaned_wells + + +def cleanup_wel( + wells: pd.DataFrame, + top: GridDataArray, + bottom: GridDataArray, + minimum_thickness: float = 0.05, +) -> pd.DataFrame: + """ + Clean up dataframe with wells, fixes some common mistakes in the following + order: + + 1. Wells outside grid bounds are dropped + 2. Filters above surface level are set to surface level + 3. Drop wells with filters entirely below base + 4. Clip filter screen_bottom to model base + 5. Clip filter screen_bottom to screen_top + 6. Well filters thinner than minimum thickness are made point filters + + Parameters + ---------- + wells: pandas.Dataframe + Dataframe with wells to be cleaned up. Requires columns ``"x", "y", + "id", "screen_top", "screen_bottom"`` + top: xarray.DataArray | xugrid.UgridDataArray + Grid with model top + bottom: xarray.DataArray | xugrid.UgridDataArray + Grid with model bottoms + minimum_thickness: float + Minimum thickness, filter thinner than this thickness are set to point + filters + + Returns + ------- + pandas.DataFrame + Cleaned well dataframe. + """ + validate_well_columnnames( + wells, names={"x", "y", "id", "screen_top", "screen_bottom"} + ) + + cleaned_wells, xy_top_series, xy_base_series = _locate_wells_in_bounds( + wells, top, bottom + ) + cleaned_wells = _clip_filter_screen_to_surface_level(cleaned_wells, xy_top_series) + cleaned_wells = _drop_wells_below_model_base(cleaned_wells, xy_base_series) + cleaned_wells = _clip_filter_bottom_to_model_base(cleaned_wells, xy_base_series) + cleaned_wells = _set_inverted_filters_to_point_filters(cleaned_wells) + cleaned_wells = _set_ultrathin_filters_to_point_filters( + cleaned_wells, minimum_thickness + ) + return cleaned_wells diff --git a/imod/prepare/wells.py b/imod/prepare/wells.py index 0f6d41517..bb1f00eaf 100644 --- a/imod/prepare/wells.py +++ b/imod/prepare/wells.py @@ -84,7 +84,7 @@ def locate_wells( wells: pd.DataFrame, top: GridDataArray, bottom: GridDataArray, - k: Optional[GridDataArray], + k: Optional[GridDataArray] = None, validate: bool = True, ) -> tuple[ npt.NDArray[np.object_], GridDataArray, GridDataArray, float | GridDataArray @@ -126,6 +126,22 @@ def locate_wells( return id_in_bounds, xy_top, xy_bottom, xy_k +def validate_well_columnnames( + wells: pd.DataFrame, names: set = {"x", "y", "id"} +) -> None: + missing = names.difference(wells.columns) + if missing: + raise ValueError(f"Columns are missing in wells dataframe: {missing}") + + +def validate_arg_types_equal(**kwargs): + types = [type(arg) for arg in (kwargs.values()) if arg is not None] + if len(set(types)) != 1: + members = ", ".join([t.__name__ for t in types]) + names = ", ".join(kwargs.keys()) + raise TypeError(f"{names} should be of the same type, received: {members}") + + def assign_wells( wells: pd.DataFrame, top: GridDataArray, @@ -166,19 +182,9 @@ def assign_wells( Wells with rate subdivided per layer. Contains the original columns of ``wells``, as well as layer, overlap, transmissivity. """ - - names = {"x", "y", "id", "top", "bottom", "rate"} - missing = names.difference(wells.columns) - if missing: - raise ValueError(f"Columns are missing in wells dataframe: {missing}") - - types = [type(arg) for arg in (top, bottom, k) if arg is not None] - if len(set(types)) != 1: - members = ",".join([t.__name__ for t in types]) - raise TypeError( - "top, bottom, and optionally k should be of the same type, " - f"received: {members}" - ) + columnnames = {"x", "y", "id", "top", "bottom", "rate"} + validate_well_columnnames(wells, columnnames) + validate_arg_types_equal(top=top, bottom=bottom, k=k) id_in_bounds, xy_top, xy_bottom, xy_k = locate_wells( wells, top, bottom, k, validate diff --git a/imod/tests/test_mf6/test_mf6_riv.py b/imod/tests/test_mf6/test_mf6_riv.py index d57ef157b..124ae2f83 100644 --- a/imod/tests/test_mf6/test_mf6_riv.py +++ b/imod/tests/test_mf6/test_mf6_riv.py @@ -71,6 +71,14 @@ def case_unstructured(self): return make_dict_unstructured(riv_dict()) +class DisCases: + def case_structured(self): + return dis_dict() + + def case_unstructured(self): + return make_dict_unstructured(dis_dict()) + + class RivDisCases: def case_structured(self): return riv_dict(), dis_dict() diff --git a/imod/tests/test_mf6/test_mf6_wel.py b/imod/tests/test_mf6/test_mf6_wel.py index c4893949c..2d4dbec7b 100644 --- a/imod/tests/test_mf6/test_mf6_wel.py +++ b/imod/tests/test_mf6/test_mf6_wel.py @@ -394,6 +394,32 @@ def test_is_empty(well_high_lvl_test_data_transient): assert wel_empty.is_empty() +def test_cleanup(basic_dis, well_high_lvl_test_data_transient): + # Arrange + wel = imod.mf6.Well(*well_high_lvl_test_data_transient) + ds_original = wel.dataset.copy() + idomain, top, bottom = basic_dis + top = top.isel(layer=0, drop=True) + deep_offset = 100.0 + dis_normal = imod.mf6.StructuredDiscretization(top, bottom, idomain) + dis_deep = imod.mf6.StructuredDiscretization( + top - deep_offset, bottom - deep_offset, idomain + ) + + # Nothing to be cleaned up with default discretization + wel.cleanup(dis_normal) + xr.testing.assert_identical(ds_original, wel.dataset) + + # Cleanup + wel.cleanup(dis_deep) + assert not ds_original.identical(wel.dataset) + # Wells filters should be placed downwards at surface level as point filters + np.testing.assert_array_almost_equal( + wel.dataset["screen_top"], wel.dataset["screen_bottom"] + ) + np.testing.assert_array_almost_equal(wel.dataset["screen_top"], top - deep_offset) + + class ClipBoxCases: @staticmethod def case_clip_xy(parameterizable_basic_dis): @@ -959,6 +985,26 @@ def test_import_and_convert_to_mf6(imod5_dataset, tmp_path, wel_class): mf6_well.write("wel", [], write_context) +@parametrize("wel_class", [Well]) +@pytest.mark.usefixtures("imod5_dataset") +def test_import_and_cleanup(imod5_dataset, wel_class: Well): + data = imod5_dataset[0] + target_dis = StructuredDiscretization.from_imod5_data(data) + + ntimes = 8399 + times = list(pd.date_range(datetime(1989, 1, 1), datetime(2013, 1, 1), ntimes + 1)) + + # Import grid-agnostic well from imod5 data (it contains 1 well) + wel = wel_class.from_imod5_data("wel-WELLS_L3", data, times) + assert len(wel.dataset.coords["time"]) == ntimes + # Cleanup + wel.cleanup(target_dis) + # Nothing to be cleaned, single well point is located properly, test that + # time coordinate has not been dropped. + assert "time" in wel.dataset.coords + assert len(wel.dataset.coords["time"]) == ntimes + + @parametrize("wel_class", [Well, LayeredWell]) @pytest.mark.usefixtures("well_regular_import_prj") def test_import_multiple_wells(well_regular_import_prj, wel_class): diff --git a/imod/tests/test_prepare/test_assign_wells.py b/imod/tests/test_prepare/test_assign_wells.py index ad22c9bd2..f72928d43 100644 --- a/imod/tests/test_prepare/test_assign_wells.py +++ b/imod/tests/test_prepare/test_assign_wells.py @@ -196,9 +196,9 @@ def test_assign_wells_errors(self, wells, top, bottom, k): with pytest.raises(ValueError, match="Columns are missing"): faulty_wells = pd.DataFrame({"id": [1], "x": [1.0], "y": [1.0]}) prepwel.assign_wells(faulty_wells, top, bottom, k) - with pytest.raises(TypeError, match="top, bottom, and optionally"): + with pytest.raises(TypeError, match="top, bottom, "): prepwel.assign_wells(wells, top, bottom.values) - with pytest.raises(TypeError, match="top, bottom, and optionally"): + with pytest.raises(TypeError, match="top, bottom, k"): prepwel.assign_wells(wells, top.values, bottom, k) @parametrize_with_cases( diff --git a/imod/tests/test_prepare/test_cleanup.py b/imod/tests/test_prepare/test_cleanup.py index 1802ca22d..b6b7861c4 100644 --- a/imod/tests/test_prepare/test_cleanup.py +++ b/imod/tests/test_prepare/test_cleanup.py @@ -1,12 +1,13 @@ from typing import Callable import numpy as np +import pandas as pd import pytest import xugrid as xu from pytest_cases import parametrize, parametrize_with_cases -from imod.prepare.cleanup import cleanup_drn, cleanup_ghb, cleanup_riv -from imod.tests.test_mf6.test_mf6_riv import RivDisCases +from imod.prepare.cleanup import cleanup_drn, cleanup_ghb, cleanup_riv, cleanup_wel +from imod.tests.test_mf6.test_mf6_riv import DisCases, RivDisCases from imod.typing import GridDataArray @@ -50,6 +51,7 @@ def _prepare_dis_dict(dis_dict: dict, func: Callable): cleanup_riv: ["idomain", "bottom"], cleanup_drn: ["idomain"], cleanup_ghb: ["idomain"], + cleanup_wel: ["top", "bottom"], } @@ -176,3 +178,71 @@ def test_cleanup_riv__raise_error(riv_data: dict, dis_data: dict): # Act with pytest.raises(ValueError, match="imod.prepare.topsystem.allocate_riv_cells"): cleanup_riv(**dis_dict, **riv_data) + + +@parametrize_with_cases("dis_data", cases=DisCases) +def test_cleanup_wel(dis_data: dict): + """ + Cleanup wells. + + Cases by id (on purpose not in order, to see if pandas' + sorting results in any issues): + + a: filter completely above surface level -> point filter in top layer + c: filter partly above surface level -> filter top set to surface level + b: filter completely below model base -> well should be removed + d: filter partly below model base -> filter bottom set to model base + f: well outside grid bounds -> well should be removed + e: utrathin filter -> filter should be forced to point filter + g: filter screen_bottom above screen_top -> filter should be forced to point filter + """ + # Arrange + dis_dict = _prepare_dis_dict(dis_data, cleanup_wel) + wel_dict = { + "id": ["a", "c", "b", "d", "f", "e", "g"], + "x": [17.0, 17.0, 17.0, 17.0, 40.0, 17.0, 17.0], + "y": [15.0, 15.0, 15.0, 15.0, 15.0, 15.0, 15.0], + "screen_top": [ + 2.0, + 2.0, + -7.0, + -1.0, + -1.0, + 1e-3, + 0.0, + ], + "screen_bottom": [ + 1.5, + 0.0, + -8.0, + -8.0, + -1.0, + 0.0, + 0.5, + ], + } + well_df = pd.DataFrame(wel_dict) + wel_expected = { + "id": ["a", "c", "d", "e", "g"], + "x": [17.0, 17.0, 17.0, 17.0, 17.0], + "y": [15.0, 15.0, 15.0, 15.0, 15.0], + "screen_top": [ + 1.0, + 1.0, + -1.0, + 1e-3, + 0.0, + ], + "screen_bottom": [ + 1.0, + 0.0, + -1.5, + 1e-3, + 0.0, + ], + } + well_expected_df = pd.DataFrame(wel_expected).set_index("id") + # Act + well_cleaned = cleanup_wel(well_df, **dis_dict) + # Assert + pd.testing.assert_frame_equal(well_cleaned, well_expected_df) From a25ea779449a63cc950933a0593f60dea93012bc Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Tue, 17 Sep 2024 10:49:09 +0200 Subject: [PATCH 44/53] Issue #1216 iMOD5 convert RCH unit (#1217) Fixes #1216 # Description iMOD5 interprets recharge rate in mm/d, whereas MODFLOW6 is unit consistent, and thus uses m/d. This PR adds a conversion function to do that. I updated the tests to also test if this conversion is done. # Checklist - [x] Links to correct issue - [ ] Update changelog, if changes affect users - [x] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [x] Unit tests were added - [ ] **If feature added**: Added/extended example --- imod/mf6/rch.py | 3 ++- imod/mf6/utilities/imod5_converter.py | 6 ++++++ imod/tests/test_mf6/test_mf6_rch.py | 28 +++++++++++++++++++++++---- 3 files changed, 32 insertions(+), 5 deletions(-) diff --git a/imod/mf6/rch.py b/imod/mf6/rch.py index d21b99874..afdd7129e 100644 --- a/imod/mf6/rch.py +++ b/imod/mf6/rch.py @@ -8,6 +8,7 @@ from imod.mf6.dis import StructuredDiscretization from imod.mf6.interfaces.iregridpackage import IRegridPackage from imod.mf6.regrid.regrid_schemes import RechargeRegridMethod +from imod.mf6.utilities.imod5_converter import convert_unit_rch_rate from imod.mf6.utilities.regrid import RegridderWeightsCache, _regrid_package_data from imod.mf6.validation import BOUNDARY_DIMS_SCHEMA, CONC_DIMS_SCHEMA from imod.prepare.topsystem.allocation import ALLOCATION_OPTION, allocate_rch_cells @@ -193,7 +194,7 @@ def from_imod5_data( """ new_idomain = dis_pkg.dataset["idomain"] data = { - "rate": imod5_data["rch"]["rate"], + "rate": convert_unit_rch_rate(imod5_data["rch"]["rate"]), } new_package_data = {} diff --git a/imod/mf6/utilities/imod5_converter.py b/imod/mf6/utilities/imod5_converter.py index 0ff7a9b42..e599c8522 100644 --- a/imod/mf6/utilities/imod5_converter.py +++ b/imod/mf6/utilities/imod5_converter.py @@ -30,6 +30,12 @@ def convert_ibound_to_idomain( return idomain_float.fillna(0).astype(int) +def convert_unit_rch_rate(rate: xr.DataArray) -> xr.DataArray: + """Convert recharge from iMOD5's mm/d to m/d""" + mm_to_m_conversion = 1e-3 + return rate * mm_to_m_conversion + + def fill_missing_layers( source: xr.DataArray, full: xr.DataArray, fillvalue: Union[float | int] ) -> xr.DataArray: diff --git a/imod/tests/test_mf6/test_mf6_rch.py b/imod/tests/test_mf6/test_mf6_rch.py index a561afe72..5119d9d11 100644 --- a/imod/tests/test_mf6/test_mf6_rch.py +++ b/imod/tests/test_mf6/test_mf6_rch.py @@ -341,9 +341,14 @@ def test_planar_rch_from_imod5_constant(imod5_dataset, tmp_path): # Act rch = imod.mf6.Recharge.from_imod5_data(data, target_discretization) + rendered_rch = rch.render(tmp_path, "rch", None, None) # Assert - rendered_rch = rch.render(tmp_path, "rch", None, None) + np.testing.assert_allclose( + data["rch"]["rate"].mean().values / 1e3, + rch.dataset["rate"].mean().values, + atol=1e-5, + ) assert "maxbound 33856" in rendered_rch assert rendered_rch.count("begin period") == 1 # teardown @@ -369,9 +374,14 @@ def test_planar_rch_from_imod5_transient(imod5_dataset, tmp_path): # act rch = imod.mf6.Recharge.from_imod5_data(data, target_discretization) + rendered_rch = rch.render(tmp_path, "rch", [0, 1, 2], None) # assert - rendered_rch = rch.render(tmp_path, "rch", [0, 1, 2], None) + np.testing.assert_allclose( + data["rch"]["rate"].mean().values / 1e3, + rch.dataset["rate"].mean().values, + atol=1e-5, + ) assert rendered_rch.count("begin period") == 3 assert "maxbound 33856" in rendered_rch @@ -399,9 +409,14 @@ def test_non_planar_rch_from_imod5_constant(imod5_dataset, tmp_path): # act rch = imod.mf6.Recharge.from_imod5_data(data, target_discretization) + rendered_rch = rch.render(tmp_path, "rch", None, None) # assert - rendered_rch = rch.render(tmp_path, "rch", None, None) + np.testing.assert_allclose( + data["rch"]["rate"].mean().values / 1e3, + rch.dataset["rate"].mean().values, + atol=1e-5, + ) assert rendered_rch.count("begin period") == 1 assert "maxbound 33856" in rendered_rch @@ -430,8 +445,13 @@ def test_non_planar_rch_from_imod5_transient(imod5_dataset, tmp_path): # act rch = imod.mf6.Recharge.from_imod5_data(data, target_discretization) + rendered_rch = rch.render(tmp_path, "rch", [0, 1, 2], None) # assert - rendered_rch = rch.render(tmp_path, "rch", [0, 1, 2], None) + np.testing.assert_allclose( + data["rch"]["rate"].mean().values / 1e3, + rch.dataset["rate"].mean().values, + atol=1e-5, + ) assert rendered_rch.count("begin period") == 3 assert "maxbound 33856" in rendered_rch From 2a6133ca132748043ff7741ec334243c4f9c2a33 Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Tue, 17 Sep 2024 10:51:42 +0200 Subject: [PATCH 45/53] Issue #1210 dissappearing rivs (#1213) Fixes #1210 # Description This PR modifies the allocation and conductance distribution methods somewhat, to allow boundary conditions to be allocated to the first model layer when located above model top. This is similar to how iMOD5 does these things. # Checklist - [x] Links to correct issue - [x] Update changelog, if changes affect users - [x] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [x] Unit tests were added - [ ] **If feature added**: Added/extended example --- docs/api/changelog.rst | 6 + imod/prepare/topsystem/allocation.py | 37 ++++- imod/prepare/topsystem/conductance.py | 33 +++- imod/tests/test_mf6/test_mf6_drn.py | 31 +++- imod/tests/test_prepare/test_topsystem.py | 190 ++++++++++++++++++++++ 5 files changed, 278 insertions(+), 19 deletions(-) diff --git a/docs/api/changelog.rst b/docs/api/changelog.rst index 5ca3aef20..0f087eed6 100644 --- a/docs/api/changelog.rst +++ b/docs/api/changelog.rst @@ -40,6 +40,12 @@ Changed length, where ``"screen_top"`` equals ``"screen_bottom"``. - :class:`imod.mf6.Well` shares the same default ``minimum_thickness`` as :func:`imod.prepare.assign_wells`, which is 0.05, before this was 1.0. +- :func:`imod.prepare.allocate_drn_cells`, + :func:`imod.prepare.allocate_ghb_cells`, + :func:`imod.prepare.allocate_riv_cells`, now allocate to the first model layer + when elevations are above model top for all methods in + :func:`imod.prepare.ALLOCATION_OPTION`. + Added ~~~~~ diff --git a/imod/prepare/topsystem/allocation.py b/imod/prepare/topsystem/allocation.py index c3c894116..aa2f570c4 100644 --- a/imod/prepare/topsystem/allocation.py +++ b/imod/prepare/topsystem/allocation.py @@ -314,6 +314,20 @@ def _enforce_layered_top(top: GridDataArray, bottom: GridDataArray): return create_layered_top(bottom, top) +def get_above_lower_bound(bottom_elevation: GridDataArray, top_layered: GridDataArray): + """ + Returns boolean array that indicates cells are above the lower vertical + limit of the topsystem. These are the cells located above the + bottom_elevation grid or in the first layer. + """ + top_layer_label = {"layer": min(top_layered.coords["layer"])} + is_above_lower_bound = bottom_elevation <= top_layered + # Bottom elevation above top surface is allowed, so these are set to True + # regardless. + is_above_lower_bound.loc[top_layer_label] = ~bottom_elevation.isnull() + return is_above_lower_bound + + @enforced_dim_order def _allocate_cells__stage_to_riv_bot( top: GridDataArray, @@ -351,7 +365,9 @@ def _allocate_cells__stage_to_riv_bot( top_layered = _enforce_layered_top(top, bottom) - riv_cells = (stage > bottom) & (bottom_elevation < top_layered) + is_above_lower_bound = get_above_lower_bound(bottom_elevation, top_layered) + is_below_upper_bound = stage > bottom + riv_cells = is_below_upper_bound & is_above_lower_bound return riv_cells, None @@ -394,7 +410,9 @@ def _allocate_cells__first_active_to_elevation( top_layered = _enforce_layered_top(top, bottom) - riv_cells = (upper_active_layer <= layer) & (bottom_elevation < top_layered) + is_above_lower_bound = get_above_lower_bound(bottom_elevation, top_layered) + is_below_upper_bound = upper_active_layer <= layer + riv_cells = is_below_upper_bound & is_above_lower_bound & active return riv_cells, None @@ -442,13 +460,13 @@ def _allocate_cells__stage_to_riv_bot_drn_above( PLANAR_GRID.validate(bottom_elevation) top_layered = _enforce_layered_top(top, bottom) - + is_above_lower_bound = get_above_lower_bound(bottom_elevation, top_layered) upper_active_layer = get_upper_active_layer_number(active) layer = active.coords["layer"] - drn_cells = (upper_active_layer <= layer) & (bottom >= stage) - riv_cells = ( - (upper_active_layer <= layer) & (bottom_elevation < top_layered) - ) != drn_cells + is_below_upper_bound = upper_active_layer <= layer + is_below_upper_bound_and_active = is_below_upper_bound & active + drn_cells = is_below_upper_bound_and_active & (bottom >= stage) + riv_cells = (is_below_upper_bound_and_active & is_above_lower_bound) != drn_cells return riv_cells, drn_cells @@ -482,8 +500,9 @@ def _allocate_cells__at_elevation( PLANAR_GRID.validate(elevation) top_layered = _enforce_layered_top(top, bottom) - - riv_cells = (elevation < top_layered) & (elevation >= bottom) + is_above_lower_bound = get_above_lower_bound(elevation, top_layered) + is_below_upper_bound = elevation >= bottom + riv_cells = is_below_upper_bound & is_above_lower_bound return riv_cells, None diff --git a/imod/prepare/topsystem/conductance.py b/imod/prepare/topsystem/conductance.py index f8d5ad92a..788397e06 100644 --- a/imod/prepare/topsystem/conductance.py +++ b/imod/prepare/topsystem/conductance.py @@ -3,7 +3,10 @@ import numpy as np -from imod.prepare.topsystem.allocation import _enforce_layered_top +from imod.prepare.topsystem.allocation import ( + _enforce_layered_top, + get_above_lower_bound, +) from imod.schemata import DimsSchema from imod.typing import GridDataArray from imod.typing.grid import ones_like, preserve_gridtype, zeros_like @@ -348,14 +351,23 @@ def _compute_crosscut_thickness( outside = zeros_like(allocated).astype(bool) if bc_top is not None: - upper_layer_bc = (bc_top < top_layered) & (bc_top > bottom) + top_is_above_lower_bound = get_above_lower_bound(bc_top, top_layered) + upper_layer_bc = top_is_above_lower_bound & (bc_top > bottom) outside = outside | (bc_top < bottom) thickness = thickness.where(~upper_layer_bc, thickness - (top_layered - bc_top)) if bc_bottom is not None: - lower_layer_bc = (bc_bottom < top_layered) & (bc_bottom > bottom) - outside = outside | (bc_bottom > top_layered) - thickness = thickness.where(~lower_layer_bc, thickness - (bc_bottom - bottom)) + bot_is_above_lower_bound = get_above_lower_bound(bc_bottom, top_layered) + lower_layer_bc = bot_is_above_lower_bound & (bc_bottom > bottom) + outside = outside | ~bot_is_above_lower_bound + corrected_thickness = thickness - (bc_bottom - bottom) + # Set top layer to 1.0, where top exceeds bc_bottom + top_layer_label = {"layer": min(top_layered.coords["layer"])} + is_above_surface = top_layered.loc[top_layer_label] < bc_bottom + corrected_thickness.loc[top_layer_label] = corrected_thickness.loc[ + top_layer_label + ].where(is_above_surface, 1.0) + thickness = thickness.where(~lower_layer_bc, corrected_thickness) thickness = thickness.where(~outside, 0.0) @@ -389,19 +401,26 @@ def _distribute_weights__by_corrected_transmissivity( if bc_top is not None: PLANAR_GRID.validate(bc_top) - upper_layer_bc = (bc_top < top_layered) & (bc_top > bottom) + top_is_above_lower_bound = get_above_lower_bound(bc_top, top_layered) + upper_layer_bc = top_is_above_lower_bound & (bc_top > bottom) # Computing vertical midpoint of river crosscutting layers. Fc = Fc.where(~upper_layer_bc, (bottom + bc_top) / 2) if bc_bottom is not None: PLANAR_GRID.validate(bc_bottom) - lower_layer_bc = (bc_bottom < top_layered) & (bc_bottom > bottom) + bot_is_above_lower_bound = get_above_lower_bound(bc_bottom, top_layered) + lower_layer_bc = bot_is_above_lower_bound & (bc_bottom > bottom) # Computing vertical midpoint of river crosscutting layers. Fc = Fc.where(~lower_layer_bc, (top_layered + bc_bottom) / 2) # Correction factor for mismatch between midpoints of crosscut layers and # layer midpoints. F = 1.0 - np.abs(midpoints - Fc) / (layer_thickness * 0.5) + # Negative values can be introduced when elevation above surface level, set + # these to 1.0. + top_layer_index = {"layer": min(top_layered.coords["layer"])} + F_top_layer = F.loc[top_layer_index] + F.loc[top_layer_index] = F_top_layer.where(F_top_layer >= 0.0, 1.0) transmissivity_corrected = transmissivity * F return transmissivity_corrected / transmissivity_corrected.sum(dim="layer") diff --git a/imod/tests/test_mf6/test_mf6_drn.py b/imod/tests/test_mf6/test_mf6_drn.py index 2b6565505..a2163ce5d 100644 --- a/imod/tests/test_mf6/test_mf6_drn.py +++ b/imod/tests/test_mf6/test_mf6_drn.py @@ -6,6 +6,7 @@ import pandas as pd import pytest import xarray as xr +from pytest_cases import parametrize_with_cases import imod import imod.mf6.drn @@ -16,6 +17,10 @@ from imod.mf6.write_context import WriteContext from imod.prepare.topsystem.allocation import ALLOCATION_OPTION from imod.prepare.topsystem.conductance import DISTRIBUTING_OPTION +from imod.prepare.topsystem.default_allocation_methods import ( + SimulationAllocationOptions, + SimulationDistributingOptions, +) from imod.schemata import ValidationError @@ -473,7 +478,20 @@ def test_html_repr(drainage): assert html_string.split("
")[0] == "
Drainage" -def test_from_imod5(imod5_dataset_periods, tmp_path): +class AllocationSettings: + def case_default(self): + return SimulationAllocationOptions.drn, SimulationDistributingOptions.drn + + def case_custom(self): + return ALLOCATION_OPTION.at_elevation, DISTRIBUTING_OPTION.by_crosscut_thickness + + +@parametrize_with_cases( + ["allocation_setting", "distribution_setting"], cases=AllocationSettings +) +def test_from_imod5( + imod5_dataset_periods, tmp_path, allocation_setting, distribution_setting +): period_data = imod5_dataset_periods[1] imod5_dataset = imod5_dataset_periods[0] target_dis = StructuredDiscretization.from_imod5_data(imod5_dataset, validate=False) @@ -487,8 +505,8 @@ def test_from_imod5(imod5_dataset_periods, tmp_path): period_data, target_dis, target_npf, - allocation_option=ALLOCATION_OPTION.at_elevation, - distributing_option=DISTRIBUTING_OPTION.by_crosscut_thickness, + allocation_option=allocation_setting, + distributing_option=distribution_setting, time_min=datetime(2002, 2, 2), time_max=datetime(2022, 2, 2), regridder_types=None, @@ -496,6 +514,13 @@ def test_from_imod5(imod5_dataset_periods, tmp_path): assert isinstance(drn_2, imod.mf6.Drainage) + pkg_errors = drn_2._validate( + schemata=drn_2._write_schemata, + idomain=target_dis["idomain"], + bottom=target_dis["bottom"], + ) + assert len(pkg_errors) == 0 + # write the packages for write validation write_context = WriteContext(simulation_directory=tmp_path, use_binary=False) drn_2.write("mydrn", [1], write_context) diff --git a/imod/tests/test_prepare/test_topsystem.py b/imod/tests/test_prepare/test_topsystem.py index f967cff0c..1ce825006 100644 --- a/imod/tests/test_prepare/test_topsystem.py +++ b/imod/tests/test_prepare/test_topsystem.py @@ -195,3 +195,193 @@ def test_distribute_ghb_conductance( actual = take_nth_layer_column(actual_da, 0) np.testing.assert_equal(actual, expected) + + +@parametrize_with_cases( + argnames="active,top,bottom,stage,bottom_elevation", + prefix="riv_", +) +@parametrize_with_cases( + argnames="option,expected_riv,expected_drn", prefix="allocation_", has_tag="riv" +) +def test_riv_allocation__elevation_above_surface_level( + active, top, bottom, stage, bottom_elevation, option, expected_riv, expected_drn +): + # Put elevations a lot above surface level. Need to be allocated to first + # layer. + actual_riv_da, actual_drn_da = allocate_riv_cells( + option, active, top, bottom, stage + 100.0, bottom_elevation + 100.0 + ) + + # Override expected values + expected_riv = [True, False, False, False] + if expected_drn: + expected_drn = [False, False, False, False] + + actual_riv = take_nth_layer_column(actual_riv_da, 0) + empty_riv = take_nth_layer_column(actual_riv_da, 1) + + if actual_drn_da is None: + actual_drn = None + empty_drn = None + else: + actual_drn = take_nth_layer_column(actual_drn_da, 0) + empty_drn = take_nth_layer_column(actual_drn_da, 1) + + np.testing.assert_equal(actual_riv, expected_riv) + np.testing.assert_equal(actual_drn, expected_drn) + assert np.all(~empty_riv) + if empty_drn is not None: + assert np.all(~empty_drn) + + +@parametrize_with_cases( + argnames="active,top,bottom,elevation", + prefix="drn_", +) +@parametrize_with_cases( + argnames="option,expected,_", prefix="allocation_", has_tag="drn" +) +def test_drn_allocation__elevation_above_surface_level( + active, top, bottom, elevation, option, expected, _ +): + # Put elevations a lot above surface level. Need to be allocated to first + # layer. + actual_da = allocate_drn_cells( + option, + active, + top, + bottom, + elevation + 100.0, + ) + + # Override expected + expected = [True, False, False, False] + + actual = take_nth_layer_column(actual_da, 0) + empty = take_nth_layer_column(actual_da, 1) + + np.testing.assert_equal(actual, expected) + assert np.all(~empty) + if empty is not None: + assert np.all(~empty) + + +@parametrize_with_cases( + argnames="active,top,bottom,head", + prefix="ghb_", +) +@parametrize_with_cases( + argnames="option,expected,_", prefix="allocation_", has_tag="ghb" +) +def test_ghb_allocation__elevation_above_surface_level( + active, top, bottom, head, option, expected, _ +): + # Put elevations a lot above surface level. Need to be allocated to first + # layer. + actual_da = allocate_ghb_cells( + option, + active, + top, + bottom, + head + 100.0, + ) + + # Override expected + expected = [True, False, False, False] + + actual = take_nth_layer_column(actual_da, 0) + empty = take_nth_layer_column(actual_da, 1) + + np.testing.assert_equal(actual, expected) + assert np.all(~empty) + if empty is not None: + assert np.all(~empty) + + +@parametrize_with_cases( + argnames="active,top,bottom,elevation", + prefix="drn_", +) +@parametrize_with_cases( + argnames="option,allocated_layer,_", prefix="distribution_", has_tag="drn" +) +def test_distribute_drn_conductance__above_surface_level( + active, top, bottom, elevation, option, allocated_layer, _ +): + allocated_layer.data = np.array([True, False, False, False]) + expected = [1.0, np.nan, np.nan, np.nan] + allocated = enforce_dim_order(active & allocated_layer) + k = xr.DataArray( + [2.0, 2.0, 1.0, 1.0], coords={"layer": [1, 2, 3, 4]}, dims=("layer",) + ) + + conductance = zeros_like(elevation) + 1.0 + + actual_da = distribute_drn_conductance( + option, allocated, conductance, top, bottom, k, elevation + 100.0 + ) + actual = take_nth_layer_column(actual_da, 0) + + np.testing.assert_equal(actual, expected) + + +@parametrize_with_cases( + argnames="active,top,bottom,stage,bottom_elevation", + prefix="riv_", +) +@parametrize_with_cases( + argnames="option,allocated_layer,_", prefix="distribution_", has_tag="riv" +) +def test_distribute_riv_conductance__above_surface_level( + active, top, bottom, stage, bottom_elevation, option, allocated_layer, _ +): + allocated_layer.data = np.array([True, False, False, False]) + expected = [1.0, np.nan, np.nan, np.nan] + allocated = enforce_dim_order(active & allocated_layer) + k = xr.DataArray( + [2.0, 2.0, 1.0, 1.0], coords={"layer": [1, 2, 3, 4]}, dims=("layer",) + ) + + conductance = zeros_like(bottom_elevation) + 1.0 + + actual_da = distribute_riv_conductance( + option, + allocated, + conductance, + top, + bottom, + k, + stage + 100.0, + bottom_elevation + 100.0, + ) + actual = take_nth_layer_column(actual_da, 0) + + np.testing.assert_equal(actual, expected) + + +@parametrize_with_cases( + argnames="active,top,bottom,elevation", + prefix="ghb_", +) +@parametrize_with_cases( + argnames="option,allocated_layer,_", prefix="distribution_", has_tag="ghb" +) +def test_distribute_ghb_conductance__above_surface_level( + active, top, bottom, elevation, option, allocated_layer, _ +): + allocated_layer.data = np.array([True, False, False, False]) + expected = [1.0, np.nan, np.nan, np.nan] + allocated = enforce_dim_order(active & allocated_layer) + k = xr.DataArray( + [2.0, 2.0, 1.0, 1.0], coords={"layer": [1, 2, 3, 4]}, dims=("layer",) + ) + + conductance = zeros_like(elevation) + 1.0 + + actual_da = distribute_ghb_conductance( + option, allocated, conductance, top, bottom, k + ) + actual = take_nth_layer_column(actual_da, 0) + + np.testing.assert_equal(actual, expected) From fe1c630c1755a6d9a8b7885389246370e5b8d137 Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Tue, 17 Sep 2024 14:46:49 +0200 Subject: [PATCH 46/53] Issue #1209 bypass value error well assign (#1211) Fixes #1209 # Description - Add setting to ``to_mf6_pkg``: ``error_on_well_removal``, which throws an error if wells are removed entirely during well assignment. - Separated code to collect filtered well ids in separate method. This method is now also called to collect ids of errors being removed in error message. - Added attribute ``_is_from_imod5`` to Modflow6Simulation to keep track if the simulation is loaded from iMOD5 data or not. Based on this, some validation settings might be set to be a bit more permissive. (Or call some extra cleanup?) - ``is_from_imod5`` property to WriteContext to keep track of the same thing within the writing context. # Checklist - [x] Links to correct issue - [x] Update changelog, if changes affect users - [x] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [x] Unit tests were added - [ ] **If feature added**: Added/extended example --- docs/api/changelog.rst | 6 ++ imod/logging/ilogger.py | 12 +-- imod/mf6/model.py | 5 +- imod/mf6/simulation.py | 4 + imod/mf6/wel.py | 90 +++++++++++++--------- imod/mf6/write_context.py | 9 +++ imod/tests/test_mf6/test_mf6_simulation.py | 24 ++++++ imod/tests/test_mf6/test_mf6_wel.py | 36 ++++++++- imod/tests/test_mf6/test_well_highlvl.py | 17 ++-- 9 files changed, 153 insertions(+), 50 deletions(-) diff --git a/docs/api/changelog.rst b/docs/api/changelog.rst index ac2c7c969..908b78b87 100644 --- a/docs/api/changelog.rst +++ b/docs/api/changelog.rst @@ -45,6 +45,12 @@ Changed :func:`imod.prepare.allocate_riv_cells`, now allocate to the first model layer when elevations are above model top for all methods in :func:`imod.prepare.ALLOCATION_OPTION`. +- :meth:`imod.mf6.Well.to_mf6_pkg` got a new argument: + ``error_on_well_removal``, which controls the behavior for when wells are + removed entirely during their assignment to layers. This replaces the + ``is_partioned`` argument. Note: if ``is_partioned`` was set to True before, + this means you need to set ``error_on_removal`` to False now to get the same + behavior. Added diff --git a/imod/logging/ilogger.py b/imod/logging/ilogger.py index 115035d2f..8297a09ff 100644 --- a/imod/logging/ilogger.py +++ b/imod/logging/ilogger.py @@ -9,7 +9,7 @@ class ILogger: """ @abstractmethod - def debug(self, message: str, additional_depth: int) -> None: + def debug(self, message: str, additional_depth: int = 0) -> None: """ Log message with severity ':attr:`~imod.logging.loglevel.LogLevel.DEBUG`'. @@ -24,7 +24,7 @@ def debug(self, message: str, additional_depth: int) -> None: raise NotImplementedError @abstractmethod - def info(self, message: str, additional_depth: int) -> None: + def info(self, message: str, additional_depth: int = 0) -> None: """ Log message with severity ':attr:`~imod.logging.loglevel.LogLevel.INFO`'. @@ -39,7 +39,7 @@ def info(self, message: str, additional_depth: int) -> None: raise NotImplementedError @abstractmethod - def warning(self, message: str, additional_depth: int) -> None: + def warning(self, message: str, additional_depth: int = 0) -> None: """ Log message with severity ':attr:`~imod.logging.loglevel.LogLevel.WARNING`'. @@ -54,7 +54,7 @@ def warning(self, message: str, additional_depth: int) -> None: raise NotImplementedError @abstractmethod - def error(self, message: str, additional_depth: int) -> None: + def error(self, message: str, additional_depth: int = 0) -> None: """ Log message with severity ':attr:`~imod.logging.loglevel.LogLevel.ERROR`'. @@ -69,7 +69,7 @@ def error(self, message: str, additional_depth: int) -> None: raise NotImplementedError @abstractmethod - def critical(self, message: str, additional_depth: int) -> None: + def critical(self, message: str, additional_depth: int = 0) -> None: """ Log message with severity ':attr:`~imod.logging.loglevel.LogLevel.CRITICAL`'. @@ -83,7 +83,7 @@ def critical(self, message: str, additional_depth: int) -> None: """ raise NotImplementedError - def log(self, loglevel: LogLevel, message: str, additional_depth: int) -> None: + def log(self, loglevel: LogLevel, message: str, additional_depth: int = 0) -> None: """ logs a message with the specified urgency level. """ diff --git a/imod/mf6/model.py b/imod/mf6/model.py index d3bf56cee..5f45b5bdd 100644 --- a/imod/mf6/model.py +++ b/imod/mf6/model.py @@ -271,13 +271,16 @@ def write( if issubclass(type(pkg), GridAgnosticWell): top, bottom, idomain = self.__get_domain_geometry() k = self.__get_k() + error_on_well_removal = (not pkg_write_context.is_partitioned) & ( + not pkg_write_context.is_from_imod5 + ) mf6_well_pkg = pkg.to_mf6_pkg( idomain, top, bottom, k, validate, - pkg_write_context.is_partitioned, + error_on_well_removal, ) mf6_well_pkg.write( pkgname=pkg_name, diff --git a/imod/mf6/simulation.py b/imod/mf6/simulation.py index 871a90e17..65a3f7bb8 100644 --- a/imod/mf6/simulation.py +++ b/imod/mf6/simulation.py @@ -97,6 +97,7 @@ def __init__(self, name): self.name = name self.directory = None self._initialize_template() + self._is_from_imod5 = False def __setitem__(self, key, value): super().__setitem__(key, value) @@ -255,6 +256,8 @@ def write( write_context = WriteContext(directory, binary, use_absolute_paths) if self.is_split(): write_context.is_partitioned = True + if self._is_from_imod5: + write_context.is_from_imod5 = True # Check models for required content for key, model in self.items(): @@ -1364,6 +1367,7 @@ def from_imod5_data( ------- """ simulation = Modflow6Simulation("imported_simulation") + simulation._is_from_imod5 = True # import GWF model, groundwaterFlowModel = GroundwaterFlowModel.from_imod5_data( diff --git a/imod/mf6/wel.py b/imod/mf6/wel.py index ed57ece73..5b3a507b0 100644 --- a/imod/mf6/wel.py +++ b/imod/mf6/wel.py @@ -236,32 +236,32 @@ def is_grid_agnostic_package(cls) -> bool: return True def _create_cellid( - self, wells_assigned: pd.DataFrame, active: xr.DataArray + self, assigned_wells: pd.DataFrame, active: xr.DataArray ) -> GridDataArray: like = ones_like(active) # Groupby index and select first, to unset any duplicate records # introduced by the multi-indexed "time" dimension. - df_for_cellid = wells_assigned.groupby("index").first() + df_for_cellid = assigned_wells.groupby("index").first() d_for_cellid = df_for_cellid[["x", "y", "layer"]].to_dict("list") return self._derive_cellid_from_points(like, **d_for_cellid) def _create_dataset_vars( - self, wells_assigned: pd.DataFrame, cellid: xr.DataArray + self, assigned_wells: pd.DataFrame, cellid: xr.DataArray ) -> xr.Dataset: """ Create dataset with all variables (rate, concentration), with a similar shape as the cellids. """ data_vars = ["id", "rate"] - if "concentration" in wells_assigned.columns: + if "concentration" in assigned_wells.columns: data_vars.append("concentration") - ds_vars = wells_assigned[data_vars].to_xarray() + ds_vars = assigned_wells[data_vars].to_xarray() # "rate" variable in conversion from multi-indexed DataFrame to xarray # DataArray results in duplicated values for "rate" along dimension # "species". Select first species to reduce this again. - index_names = wells_assigned.index.names + index_names = assigned_wells.index.names if "species" in index_names: ds_vars["rate"] = ds_vars["rate"].isel(species=0) @@ -348,7 +348,11 @@ def _derive_cellid_from_points( def render(self, directory, pkgname, globaltimes, binary): raise NotImplementedError( - f"{self.__class__.__name__} is a grid-agnostic package and does not have a render method. To render the package, first convert to a Modflow6 package by calling pkg.to_mf6_pkg()" + textwrap.dedent( + f"""{self.__class__.__name__} is a grid-agnostic package and does not + have a render method. To render the package, first convert to a + Modflow6 package by calling pkg.to_mf6_pkg()""" + ) ) def write( @@ -384,7 +388,7 @@ def to_mf6_pkg( bottom: GridDataArray, k: GridDataArray, validate: bool = False, - is_partitioned: bool = False, + error_on_well_removal: bool = True, ) -> Mf6Wel: """ Write package to Modflow 6 package. @@ -413,8 +417,9 @@ def to_mf6_pkg( Grid with hydraulic conductivities. validate: bool Run validation before converting - is_partitioned: bool - Set to true if model has been partitioned + error_on_well_removal: bool + Throw error if well is removed entirely during its assignment to + layers. Returns ------- @@ -429,24 +434,26 @@ def to_mf6_pkg( wells_df = self._create_wells_df() nwells_df = len(wells_df["id"].unique()) - wells_assigned = self._assign_wells_to_layers(wells_df, active, top, bottom, k) - - nwells_assigned = ( - 0 if wells_assigned.empty else len(wells_assigned["id"].unique()) - ) - if nwells_df == 0: - raise ValueError("No wells were assigned in package. None were present.") - - if not is_partitioned and nwells_df != nwells_assigned: - raise ValueError( - "One or more well(s) are completely invalid due to minimum conductivity and thickness constraints." + raise ValidationError( + "No wells were assigned in package. None were present." ) + assigned_wells = self._assign_wells_to_layers(wells_df, active, top, bottom, k) + filtered_assigned_well_ids = self.gather_filtered_well_ids( + assigned_wells, wells_df + ) + message_assign = self.to_mf6_package_information( + filtered_assigned_well_ids, reason_text="permeability/thickness constraints" + ) + if error_on_well_removal and len(filtered_assigned_well_ids) > 0: + logger.log(loglevel=LogLevel.ERROR, message=message_assign) + raise ValidationError(message_assign) + ds = xr.Dataset() - ds["cellid"] = self._create_cellid(wells_assigned, active) + ds["cellid"] = self._create_cellid(assigned_wells, active) - ds_vars = self._create_dataset_vars(wells_assigned, ds["cellid"]) + ds_vars = self._create_dataset_vars(assigned_wells, ds["cellid"]) ds = ds.assign(**ds_vars.data_vars) ds = remove_inactive(ds, active) @@ -454,21 +461,34 @@ def to_mf6_pkg( ds["print_flows"] = self["print_flows"].values[()] ds["print_input"] = self["print_input"].values[()] - filtered_wells = [ - id for id in wells_df["id"].unique() if id not in ds["id"].values - ] - if len(filtered_wells) > 0: - message = self.to_mf6_package_information(filtered_wells) - logger.log(loglevel=LogLevel.WARNING, message=message, additional_depth=2) + filtered_final_well_ids = self.gather_filtered_well_ids(ds, wells_df) + if len(filtered_final_well_ids) > 0: + reason_text = "inactive cells or permeability/thickness constraints" + message_end = self.to_mf6_package_information( + filtered_final_well_ids, reason_text=reason_text + ) + logger.log(loglevel=LogLevel.WARNING, message=message_end) ds = ds.drop_vars("id") return Mf6Wel(**ds.data_vars) - def to_mf6_package_information(self, filtered_wells: pd.DataFrame) -> str: + def gather_filtered_well_ids( + self, well_data_filtered: pd.DataFrame | xr.Dataset, well_data: pd.DataFrame + ) -> list[str]: + filtered_well_ids = [ + id + for id in well_data["id"].unique() + if id not in well_data_filtered["id"].values + ] + return filtered_well_ids + + def to_mf6_package_information( + self, filtered_wells: list[str], reason_text: str + ) -> str: message = textwrap.dedent( - """Some wells were not placed in the MF6 well package. This - can be due to inactive cells or permeability/thickness constraints.\n""" + f"""Some wells were not placed in the MF6 well package. This can be + due to {reason_text}.\n""" ) if len(filtered_wells) < 10: message += "The filtered wells are: \n" @@ -940,13 +960,13 @@ def _assign_wells_to_layers( # case of a "time" and "species" coordinate. wells_df = wells_df.reset_index() - wells_assigned = assign_wells( + assigned_wells = assign_wells( wells_df, top_3d, bottom, k, minimum_thickness, minimum_k, True ) # Set multi-index again - wells_assigned = wells_assigned.set_index(index_names).sort_index() + assigned_wells = assigned_wells.set_index(index_names).sort_index() - return wells_assigned + return assigned_wells @classmethod def _validate_imod5_depth_information( diff --git a/imod/mf6/write_context.py b/imod/mf6/write_context.py index a36fe7827..23587268c 100644 --- a/imod/mf6/write_context.py +++ b/imod/mf6/write_context.py @@ -44,6 +44,7 @@ def __init__( else self.__simulation_directory ) self.__is_partitioned = False + self.__is_from_imod5 = False def get_formatted_write_directory(self) -> Path: """ @@ -98,3 +99,11 @@ def is_partitioned(self) -> bool: @is_partitioned.setter def is_partitioned(self, value: bool) -> None: self.__is_partitioned = value + + @property + def is_from_imod5(self) -> bool: + return self.__is_from_imod5 + + @is_from_imod5.setter + def is_from_imod5(self, value: bool) -> None: + self.__is_from_imod5 = value diff --git a/imod/tests/test_mf6/test_mf6_simulation.py b/imod/tests/test_mf6/test_mf6_simulation.py index 5db6070a6..23ddfe676 100644 --- a/imod/tests/test_mf6/test_mf6_simulation.py +++ b/imod/tests/test_mf6/test_mf6_simulation.py @@ -510,6 +510,30 @@ def test_import_from_imod5(imod5_dataset, tmp_path): # write and validate the simulation. simulation.write(tmp_path, binary=False, validate=True) + # Test if simulation attribute appropiately set + assert simulation._is_from_imod5 is True + + +@pytest.mark.unittest_jit +@pytest.mark.usefixtures("imod5_dataset") +def test_is_from_imod5_attribute(imod5_dataset): + imod5_data = imod5_dataset[0] + period_data = imod5_dataset[1] + default_simulation_allocation_options = SimulationAllocationOptions + default_simulation_distributing_options = SimulationDistributingOptions + + datelist = pd.date_range(start="1/1/1989", end="1/1/1990", freq="W") + + simulation = Modflow6Simulation.from_imod5_data( + imod5_data, + period_data, + default_simulation_allocation_options, + default_simulation_distributing_options, + datelist, + ) + assert simulation._is_from_imod5 is True + assert Modflow6Simulation("test")._is_from_imod5 is False + @pytest.mark.unittest_jit @pytest.mark.usefixtures("imod5_dataset") diff --git a/imod/tests/test_mf6/test_mf6_wel.py b/imod/tests/test_mf6/test_mf6_wel.py index 2d4dbec7b..0ed1b43fc 100644 --- a/imod/tests/test_mf6/test_mf6_wel.py +++ b/imod/tests/test_mf6/test_mf6_wel.py @@ -272,7 +272,7 @@ def test_to_mf6_pkg__logging_with_message( # well 1 is partially placed # well 2 is fully placed # well 3 is partially placed - # wells 4 to 7 are nog placed + # wells 4 to 7 are not placed modified_well_fixture[2] = [ -6.0, -3.0, @@ -355,6 +355,40 @@ def test_to_mf6_pkg__logging_without_message( assert "Some wells were not placed" not in log +def test_to_mf6_pkg__error_on_all_wells_removed( + basic_dis, well_high_lvl_test_data_transient +): + """Drop all wells, then run to_mf6_pkg""" + idomain, top, bottom = basic_dis + + wel = imod.mf6.Well(*well_high_lvl_test_data_transient) + wel.dataset = wel.dataset.drop_sel(index=wel.dataset["index"]) + active = idomain == 1 + k = xr.ones_like(idomain) + + with pytest.raises(ValidationError, match="No wells were assigned in package"): + wel.to_mf6_pkg(active, top, bottom, k) + + +def test_to_mf6_pkg__error_on_well_removal( + basic_dis, well_high_lvl_test_data_transient +): + """Set k values at well location x=81 to 1e-3, causing it to be dropped. + Should throw error if error_on_well_removal = True""" + idomain, top, bottom = basic_dis + + wel = imod.mf6.Well(minimum_k=1.0, *well_high_lvl_test_data_transient) + active = idomain == 1 + k = xr.ones_like(idomain) + k.loc[{"x": 85.0}] = 1e-3 + + with pytest.raises(ValidationError, match="x = 81"): + wel.to_mf6_pkg(active, top, bottom, k, error_on_well_removal=True) + + mf6_wel = wel.to_mf6_pkg(active, top, bottom, k, error_on_well_removal=False) + assert mf6_wel.dataset.sizes["ncellid"] < wel.dataset.sizes["index"] + + @pytest.mark.parametrize("save_flows", [True, False]) @pytest.mark.parametrize("print_input", [True, False]) @pytest.mark.parametrize("print_flows", [True, False]) diff --git a/imod/tests/test_mf6/test_well_highlvl.py b/imod/tests/test_mf6/test_well_highlvl.py index ffa0935f9..cdf91c76a 100644 --- a/imod/tests/test_mf6/test_well_highlvl.py +++ b/imod/tests/test_mf6/test_well_highlvl.py @@ -13,6 +13,7 @@ import imod.tests.fixtures.mf6_circle_fixture import imod.tests.fixtures.mf6_twri_fixture from imod.mf6.write_context import WriteContext +from imod.schemata import ValidationError from imod.tests.fixtures.mf6_small_models_fixture import ( grid_data_structured, grid_data_structured_layered, @@ -149,7 +150,8 @@ def test_write_well_from_model_transient_rate( def test_write_all_wells_filtered_out( tmp_path: Path, twri_simulation: imod.mf6.Modflow6Simulation ): - # for this test, we leave the low conductivity of the twri model as is, so all wells get filtered out + # for this test, we leave the low conductivity of the twri model as is, so + # all wells get filtered out twri_simulation["GWF_1"]["well"] = imod.mf6.Well( x=[1.0, 6002.0], y=[3.0, 5004.0], @@ -160,15 +162,16 @@ def test_write_all_wells_filtered_out( validate=True, ) - with pytest.raises(ValueError): + with pytest.raises(ValidationError): twri_simulation.write(tmp_path, binary=False) def test_write_one_well_filtered_out( tmp_path: Path, twri_simulation: imod.mf6.Modflow6Simulation ): - # for this test, we increase the low conductivity of the twri model . But one of the wells violates the thickness constraint (the second one) - # and gets filtered out alltogether + # for this test, we increase the low conductivity of the twri model . But + # one of the wells violates the thickness constraint (the second one) and + # gets filtered out alltogether twri_simulation["GWF_1"]["npf"]["k"] *= 20000 twri_simulation["GWF_1"]["well"] = imod.mf6.Well( x=[1.0, 6002.0], @@ -180,7 +183,7 @@ def test_write_one_well_filtered_out( validate=True, ) - with pytest.raises(ValueError): + with pytest.raises(ValidationError): twri_simulation.write(tmp_path, binary=False) @@ -233,7 +236,7 @@ def test_constraints_are_configurable( twri_simulation["GWF_1"]["well"]["minimum_k"] = 1.0 twri_simulation["GWF_1"]["well"]["minimum_thickness"] = 1.0 - with pytest.raises(ValueError): + with pytest.raises(ValidationError): twri_simulation.write(tmp_path, binary=False) # reset the constraints again so that all constraints are met @@ -246,7 +249,7 @@ def test_constraints_are_configurable( twri_simulation["GWF_1"]["well"]["minimum_k"] = 1e-9 twri_simulation["GWF_1"]["well"]["minimum_thickness"] = 700.0 - with pytest.raises(ValueError): + with pytest.raises(ValidationError): twri_simulation.write(tmp_path, binary=False) From 46c2e85847d0b627d2dee1c80e5c6b9840a11882 Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Wed, 18 Sep 2024 15:27:04 +0200 Subject: [PATCH 47/53] Issue #1222 validation context (#1226) Fixes #1222 # Description - Add a ``ValidationContext`` dataclass - Add a ``_validation_context`` attribute to ``Modflow6Simulation``; this replaces the ``_is_from_imod5`` attribute. - The ``ValidationContext`` contains an attribute for strict well checks, turned on by default. This is set to False when calling ``from_imod5`` or for split simulations. - Adds a ``_to_mf6_pkg`` method in a similar design as proposed in #1223, this to preserve public API. - Refactor ``WriteContext``, to make it a dataclass again. I had to ignore type annotation for ``write_directory``, otherwise MyPy would throw errors. The whole property shebang presumably started with MyPy throwing errors. Reverting it back to a dataclass reduces the lines of code considerably, which makes it more maintainable. - Use jit for examples run, this speeds them up considerably. The examples ran into a TimeOut on TeamCity, and this reduces the change of that happening again. # Checklist - [x] Links to correct issue - [x] Update changelog, if changes affect users - [x] PR title starts with ``Issue #nr``, e.g. ``Issue #737`` - [ ] Unit tests were added - [ ] **If feature added**: Added/extended example --- docs/api/changelog.rst | 7 +-- imod/mf6/model.py | 17 ++--- imod/mf6/simulation.py | 12 ++-- imod/mf6/validation_context.py | 7 +++ imod/mf6/wel.py | 24 ++++++-- imod/mf6/write_context.py | 72 +++++----------------- imod/tests/test_mf6/test_circle.py | 19 +++--- imod/tests/test_mf6/test_ex01_twri.py | 4 +- imod/tests/test_mf6/test_mf6_logging.py | 6 +- imod/tests/test_mf6/test_mf6_model.py | 19 ++++-- imod/tests/test_mf6/test_mf6_simulation.py | 8 +-- imod/tests/test_mf6/test_mf6_wel.py | 4 +- imod/tests/test_mf6/test_well_highlvl.py | 6 +- pixi.toml | 1 - 14 files changed, 102 insertions(+), 104 deletions(-) create mode 100644 imod/mf6/validation_context.py diff --git a/docs/api/changelog.rst b/docs/api/changelog.rst index 908b78b87..86574b81c 100644 --- a/docs/api/changelog.rst +++ b/docs/api/changelog.rst @@ -46,12 +46,9 @@ Changed when elevations are above model top for all methods in :func:`imod.prepare.ALLOCATION_OPTION`. - :meth:`imod.mf6.Well.to_mf6_pkg` got a new argument: - ``error_on_well_removal``, which controls the behavior for when wells are + ``strict_well_validation``, which controls the behavior for when wells are removed entirely during their assignment to layers. This replaces the - ``is_partioned`` argument. Note: if ``is_partioned`` was set to True before, - this means you need to set ``error_on_removal`` to False now to get the same - behavior. - + ``is_partitioned`` argument. Added ~~~~~ diff --git a/imod/mf6/model.py b/imod/mf6/model.py index 5f45b5bdd..54ac24b07 100644 --- a/imod/mf6/model.py +++ b/imod/mf6/model.py @@ -27,6 +27,7 @@ from imod.mf6.utilities.mf6hfb import merge_hfb_packages from imod.mf6.utilities.regrid import RegridderWeightsCache, _regrid_like from imod.mf6.validation import pkg_errors_to_status_info +from imod.mf6.validation_context import ValidationContext from imod.mf6.wel import GridAgnosticWell from imod.mf6.write_context import WriteContext from imod.schemata import ValidationError @@ -240,7 +241,11 @@ def validate(self, model_name: str = "") -> StatusInfoBase: @standard_log_decorator() def write( - self, modelname, globaltimes, validate: bool, write_context: WriteContext + self, + modelname, + globaltimes, + write_context: WriteContext, + validate_context: ValidationContext, ) -> StatusInfoBase: """ Write model namefile @@ -250,7 +255,7 @@ def write( workdir = write_context.simulation_directory modeldirectory = workdir / modelname Path(modeldirectory).mkdir(exist_ok=True, parents=True) - if validate: + if validate_context.validate: model_status_info = self.validate(modelname) if model_status_info.has_errors(): return model_status_info @@ -271,16 +276,12 @@ def write( if issubclass(type(pkg), GridAgnosticWell): top, bottom, idomain = self.__get_domain_geometry() k = self.__get_k() - error_on_well_removal = (not pkg_write_context.is_partitioned) & ( - not pkg_write_context.is_from_imod5 - ) - mf6_well_pkg = pkg.to_mf6_pkg( + mf6_well_pkg = pkg._to_mf6_pkg( idomain, top, bottom, k, - validate, - error_on_well_removal, + validate_context, ) mf6_well_pkg.write( pkgname=pkg_name, diff --git a/imod/mf6/simulation.py b/imod/mf6/simulation.py index 65a3f7bb8..2a4af57e5 100644 --- a/imod/mf6/simulation.py +++ b/imod/mf6/simulation.py @@ -43,6 +43,7 @@ from imod.mf6.statusinfo import NestedStatusInfo from imod.mf6.utilities.mask import _mask_all_models from imod.mf6.utilities.regrid import _regrid_like +from imod.mf6.validation_context import ValidationContext from imod.mf6.write_context import WriteContext from imod.prepare.topsystem.default_allocation_methods import ( SimulationAllocationOptions, @@ -97,7 +98,7 @@ def __init__(self, name): self.name = name self.directory = None self._initialize_template() - self._is_from_imod5 = False + self._validation_context = ValidationContext() def __setitem__(self, key, value): super().__setitem__(key, value) @@ -254,10 +255,9 @@ def write( """ # create write context write_context = WriteContext(directory, binary, use_absolute_paths) + self._validation_context.validate = validate if self.is_split(): - write_context.is_partitioned = True - if self._is_from_imod5: - write_context.is_from_imod5 = True + self._validation_context.strict_well_validation = False # Check models for required content for key, model in self.items(): @@ -299,8 +299,8 @@ def write( value.write( modelname=key, globaltimes=globaltimes, - validate=validate, write_context=model_write_context, + validate_context=self._validation_context, ) ) elif isinstance(value, Package): @@ -1367,7 +1367,7 @@ def from_imod5_data( ------- """ simulation = Modflow6Simulation("imported_simulation") - simulation._is_from_imod5 = True + simulation._validation_context.strict_well_validation = False # import GWF model, groundwaterFlowModel = GroundwaterFlowModel.from_imod5_data( diff --git a/imod/mf6/validation_context.py b/imod/mf6/validation_context.py new file mode 100644 index 000000000..8b364ca53 --- /dev/null +++ b/imod/mf6/validation_context.py @@ -0,0 +1,7 @@ +from dataclasses import dataclass + + +@dataclass +class ValidationContext: + validate: bool = True + strict_well_validation: bool = True diff --git a/imod/mf6/wel.py b/imod/mf6/wel.py index 5b3a507b0..6d567cd84 100644 --- a/imod/mf6/wel.py +++ b/imod/mf6/wel.py @@ -31,6 +31,7 @@ from imod.mf6.utilities.dataset import remove_inactive from imod.mf6.utilities.grid import broadcast_to_full_domain from imod.mf6.validation import validation_pkg_error_message +from imod.mf6.validation_context import ValidationContext from imod.mf6.write_context import WriteContext from imod.prepare import assign_wells from imod.prepare.cleanup import cleanup_wel @@ -388,7 +389,7 @@ def to_mf6_pkg( bottom: GridDataArray, k: GridDataArray, validate: bool = False, - error_on_well_removal: bool = True, + strict_well_validation: bool = True, ) -> Mf6Wel: """ Write package to Modflow 6 package. @@ -415,9 +416,10 @@ def to_mf6_pkg( Grid with bottom of model layers. k: {xarry.DataArray, xugrid.UgridDataArray} Grid with hydraulic conductivities. - validate: bool + validate: bool, default True Run validation before converting - error_on_well_removal: bool + strict_well_validation: bool, default True + Set well validation strict: Throw error if well is removed entirely during its assignment to layers. @@ -426,7 +428,20 @@ def to_mf6_pkg( Mf6Wel Object with wells as list based input. """ - if validate: + validation_context = ValidationContext( + validate=validate, strict_well_validation=strict_well_validation + ) + return self._to_mf6_pkg(active, top, bottom, k, validation_context) + + def _to_mf6_pkg( + self, + active: GridDataArray, + top: GridDataArray, + bottom: GridDataArray, + k: GridDataArray, + validation_context: ValidationContext, + ) -> Mf6Wel: + if validation_context.validate: errors = self._validate(self._write_schemata) if len(errors) > 0: message = validation_pkg_error_message(errors) @@ -446,6 +461,7 @@ def to_mf6_pkg( message_assign = self.to_mf6_package_information( filtered_assigned_well_ids, reason_text="permeability/thickness constraints" ) + error_on_well_removal = validation_context.strict_well_validation if error_on_well_removal and len(filtered_assigned_well_ids) > 0: logger.log(loglevel=LogLevel.ERROR, message=message_assign) raise ValidationError(message_assign) diff --git a/imod/mf6/write_context.py b/imod/mf6/write_context.py index 23587268c..9679b2d3e 100644 --- a/imod/mf6/write_context.py +++ b/imod/mf6/write_context.py @@ -4,7 +4,6 @@ from dataclasses import dataclass from os.path import relpath from pathlib import Path -from typing import Optional, Union @dataclass @@ -28,23 +27,18 @@ class WriteContext: it will be set to the simulation_directrory. """ - def __init__( - self, - simulation_directory: Path = Path("."), - use_binary: bool = False, - use_absolute_paths: bool = False, - write_directory: Optional[Union[str, Path]] = None, - ): - self.__simulation_directory = Path(simulation_directory) - self.__use_binary = use_binary - self.__use_absolute_paths = use_absolute_paths - self.__write_directory = ( - Path(write_directory) - if write_directory is not None - else self.__simulation_directory + simulation_directory: Path = Path(".") + use_binary: bool = False + use_absolute_paths: bool = False + write_directory: Path = None # type: ignore + + def __post_init__(self): + self.simulation_directory = Path(self.simulation_directory) + self.write_directory = ( + Path(self.write_directory) + if self.write_directory is not None + else self.simulation_directory ) - self.__is_partitioned = False - self.__is_from_imod5 = False def get_formatted_write_directory(self) -> Path: """ @@ -53,34 +47,14 @@ def get_formatted_write_directory(self) -> Path: be relative to the simulation directory, which makes it usable by MF6. """ if self.use_absolute_paths: - return self.__write_directory - return Path(relpath(self.write_directory, self.__simulation_directory)) + return self.write_directory + return Path(relpath(self.write_directory, self.simulation_directory)) def copy_with_new_write_directory(self, new_write_directory: Path) -> WriteContext: new_context = deepcopy(self) - new_context.__write_directory = Path(new_write_directory) + new_context.write_directory = Path(new_write_directory) return new_context - @property - def simulation_directory(self) -> Path: - return self.__simulation_directory - - @property - def use_binary(self) -> bool: - return self.__use_binary - - @use_binary.setter - def use_binary(self, value) -> None: - self.__use_binary = value - - @property - def use_absolute_paths(self) -> bool: - return self.__use_absolute_paths - - @property - def write_directory(self) -> Path: - return self.__write_directory - @property def root_directory(self) -> Path: """ @@ -88,22 +62,6 @@ def root_directory(self) -> Path: that are in agreement with the use_absolute_paths setting. """ if self.use_absolute_paths: - return self.__simulation_directory + return self.simulation_directory else: return Path("") - - @property - def is_partitioned(self) -> bool: - return self.__is_partitioned - - @is_partitioned.setter - def is_partitioned(self, value: bool) -> None: - self.__is_partitioned = value - - @property - def is_from_imod5(self) -> bool: - return self.__is_from_imod5 - - @is_from_imod5.setter - def is_from_imod5(self, value: bool) -> None: - self.__is_from_imod5 = value diff --git a/imod/tests/test_mf6/test_circle.py b/imod/tests/test_mf6/test_circle.py index 19d40e8d9..063b1c81c 100644 --- a/imod/tests/test_mf6/test_circle.py +++ b/imod/tests/test_mf6/test_circle.py @@ -9,6 +9,7 @@ import imod from imod.logging import LoggerType, LogLevel +from imod.mf6.validation_context import ValidationContext from imod.mf6.write_context import WriteContext @@ -57,8 +58,8 @@ def test_gwfmodel_render(circle_model, tmp_path): simulation = circle_model globaltimes = simulation["time_discretization"]["time"].values gwfmodel = simulation["GWF_1"] - write_context = WriteContext() - actual = gwfmodel.render("GWF_1", write_context) + write_context1 = WriteContext() + actual = gwfmodel.render("GWF_1", write_context1) path = "GWF_1" expected = textwrap.dedent( f"""\ @@ -77,8 +78,9 @@ def test_gwfmodel_render(circle_model, tmp_path): """ ) assert actual == expected - context = WriteContext(tmp_path) - gwfmodel.write("GWF_1", globaltimes, True, context) + validation_context = ValidationContext(True) + write_context2 = WriteContext(tmp_path) + gwfmodel.write("GWF_1", globaltimes, write_context2, validation_context) assert (tmp_path / "GWF_1" / "GWF_1.nam").is_file() assert (tmp_path / "GWF_1").is_dir() @@ -110,8 +112,8 @@ def test_gwfmodel_render_evt(circle_model_evt, tmp_path): simulation = circle_model_evt globaltimes = simulation["time_discretization"]["time"].values gwfmodel = simulation["GWF_1"] - write_context = WriteContext() - actual = gwfmodel.render("GWF_1", write_context) + write_context1 = WriteContext() + actual = gwfmodel.render("GWF_1", write_context1) path = "GWF_1" expected = textwrap.dedent( f"""\ @@ -131,7 +133,8 @@ def test_gwfmodel_render_evt(circle_model_evt, tmp_path): """ ) assert actual == expected - context = WriteContext(tmp_path) - gwfmodel.write("GWF_1", globaltimes, True, context) + validation_context = ValidationContext(True) + write_context2 = WriteContext(tmp_path) + gwfmodel.write("GWF_1", globaltimes, write_context2, validation_context) assert (tmp_path / "GWF_1" / "GWF_1.nam").is_file() assert (tmp_path / "GWF_1").is_dir() diff --git a/imod/tests/test_mf6/test_ex01_twri.py b/imod/tests/test_mf6/test_ex01_twri.py index 40ead6a72..c6763c097 100644 --- a/imod/tests/test_mf6/test_ex01_twri.py +++ b/imod/tests/test_mf6/test_ex01_twri.py @@ -8,6 +8,7 @@ import xarray as xr import imod +from imod.mf6.validation_context import ValidationContext from imod.mf6.write_context import WriteContext from imod.schemata import ValidationError from imod.typing.grid import ones_like @@ -351,6 +352,7 @@ def test_gwfmodel_render(twri_model, tmp_path): globaltimes = simulation["time_discretization"]["time"].values gwfmodel = simulation["GWF_1"] path = Path(tmp_path.stem).as_posix() + validation_context = ValidationContext(tmp_path) write_context = WriteContext(tmp_path) actual = gwfmodel.render(path, write_context) expected = textwrap.dedent( @@ -373,7 +375,7 @@ def test_gwfmodel_render(twri_model, tmp_path): """ ) assert actual == expected - gwfmodel.write("GWF_1", globaltimes, True, write_context) + gwfmodel.write("GWF_1", globaltimes, write_context, validation_context) assert (tmp_path / "GWF_1" / "GWF_1.nam").is_file() assert (tmp_path / "GWF_1").is_dir() diff --git a/imod/tests/test_mf6/test_mf6_logging.py b/imod/tests/test_mf6/test_mf6_logging.py index 0b02740f9..16611de17 100644 --- a/imod/tests/test_mf6/test_mf6_logging.py +++ b/imod/tests/test_mf6/test_mf6_logging.py @@ -10,6 +10,7 @@ import imod from imod.logging import LoggerType, LogLevel, standard_log_decorator +from imod.mf6.validation_context import ValidationContext from imod.mf6.write_context import WriteContext out = StringIO() @@ -80,6 +81,7 @@ def test_write_model_is_logged( # arrange logfile_path = tmp_path / "logfile.txt" transport_model = flow_transport_simulation["tpt_c"] + validation_context = ValidationContext() write_context = WriteContext(simulation_directory=tmp_path, use_binary=True) globaltimes = np.array( [ @@ -95,7 +97,9 @@ def test_write_model_is_logged( add_default_file_handler=False, add_default_stream_handler=True, ) - transport_model.write("model.txt", globaltimes, True, write_context) + transport_model.write( + "model.txt", globaltimes, write_context, validation_context + ) # assert with open(logfile_path, "r") as log_file: diff --git a/imod/tests/test_mf6/test_mf6_model.py b/imod/tests/test_mf6/test_mf6_model.py index fc0c30084..a5597c5bb 100644 --- a/imod/tests/test_mf6/test_mf6_model.py +++ b/imod/tests/test_mf6/test_mf6_model.py @@ -16,6 +16,7 @@ from imod.mf6.model import Modflow6Model from imod.mf6.model_gwf import GroundwaterFlowModel from imod.mf6.package import Package +from imod.mf6.validation_context import ValidationContext from imod.mf6.write_context import WriteContext from imod.schemata import ValidationError @@ -105,6 +106,7 @@ def test_write_valid_model_without_error(self, tmpdir_factory): model_name = "Test model" model = Modflow6Model() # create write context + validation_context = ValidationContext() write_context = WriteContext(tmp_path) discretization_mock = MagicMock(spec_set=Package) @@ -119,7 +121,9 @@ def test_write_valid_model_without_error(self, tmpdir_factory): global_times_mock = MagicMock(spec_set=imod.mf6.TimeDiscretization) # Act. - status = model.write(model_name, global_times_mock, True, write_context) + status = model.write( + model_name, global_times_mock, write_context, validation_context + ) # Assert. assert not status.has_errors() @@ -130,6 +134,7 @@ def test_write_without_dis_pkg_return_error(self, tmpdir_factory): model_name = "Test model" model = Modflow6Model() # create write context + validation_context = ValidationContext() write_context = WriteContext(tmp_path) template_mock = MagicMock(spec_set=Template) @@ -139,7 +144,9 @@ def test_write_without_dis_pkg_return_error(self, tmpdir_factory): global_times_mock = MagicMock(spec_set=imod.mf6.TimeDiscretization) # Act. - status = model.write(model_name, global_times_mock, True, write_context) + status = model.write( + model_name, global_times_mock, write_context, validation_context + ) # Assert. assert status.has_errors() @@ -150,6 +157,7 @@ def test_write_with_invalid_pkg_returns_error(self, tmpdir_factory): model_name = "Test model" model = Modflow6Model() # create write context + validation_context = ValidationContext() write_context = WriteContext(tmp_path) discretization_mock = MagicMock(spec_set=Package) @@ -168,7 +176,7 @@ def test_write_with_invalid_pkg_returns_error(self, tmpdir_factory): # Act. status = model.write( - model_name, global_times_mock, True, write_context=write_context + model_name, global_times_mock, write_context, validation_context ) # Assert. @@ -178,6 +186,7 @@ def test_write_with_two_invalid_pkg_returns_two_errors(self, tmpdir_factory): # Arrange. tmp_path = tmpdir_factory.mktemp("TestSimulation") model_name = "Test model" + validation_context = ValidationContext() write_context = WriteContext(simulation_directory=tmp_path) model = Modflow6Model() @@ -205,7 +214,9 @@ def test_write_with_two_invalid_pkg_returns_two_errors(self, tmpdir_factory): # Act. write_context = WriteContext(tmp_path) - status = model.write(model_name, global_times_mock, True, write_context) + status = model.write( + model_name, global_times_mock, write_context, validation_context + ) # Assert. assert len(status.errors) == 2 diff --git a/imod/tests/test_mf6/test_mf6_simulation.py b/imod/tests/test_mf6/test_mf6_simulation.py index 23ddfe676..b2f757ea1 100644 --- a/imod/tests/test_mf6/test_mf6_simulation.py +++ b/imod/tests/test_mf6/test_mf6_simulation.py @@ -511,12 +511,12 @@ def test_import_from_imod5(imod5_dataset, tmp_path): simulation.write(tmp_path, binary=False, validate=True) # Test if simulation attribute appropiately set - assert simulation._is_from_imod5 is True + assert simulation._validation_context.strict_well_validation is False @pytest.mark.unittest_jit @pytest.mark.usefixtures("imod5_dataset") -def test_is_from_imod5_attribute(imod5_dataset): +def test_from_imod5__strict_well_validation_set(imod5_dataset): imod5_data = imod5_dataset[0] period_data = imod5_dataset[1] default_simulation_allocation_options = SimulationAllocationOptions @@ -531,8 +531,8 @@ def test_is_from_imod5_attribute(imod5_dataset): default_simulation_distributing_options, datelist, ) - assert simulation._is_from_imod5 is True - assert Modflow6Simulation("test")._is_from_imod5 is False + assert simulation._validation_context.strict_well_validation is False + assert Modflow6Simulation("test")._validation_context.strict_well_validation is True @pytest.mark.unittest_jit diff --git a/imod/tests/test_mf6/test_mf6_wel.py b/imod/tests/test_mf6/test_mf6_wel.py index 0ed1b43fc..6048524f6 100644 --- a/imod/tests/test_mf6/test_mf6_wel.py +++ b/imod/tests/test_mf6/test_mf6_wel.py @@ -383,9 +383,9 @@ def test_to_mf6_pkg__error_on_well_removal( k.loc[{"x": 85.0}] = 1e-3 with pytest.raises(ValidationError, match="x = 81"): - wel.to_mf6_pkg(active, top, bottom, k, error_on_well_removal=True) + wel.to_mf6_pkg(active, top, bottom, k, strict_well_validation=True) - mf6_wel = wel.to_mf6_pkg(active, top, bottom, k, error_on_well_removal=False) + mf6_wel = wel.to_mf6_pkg(active, top, bottom, k, strict_well_validation=False) assert mf6_wel.dataset.sizes["ncellid"] < wel.dataset.sizes["index"] diff --git a/imod/tests/test_mf6/test_well_highlvl.py b/imod/tests/test_mf6/test_well_highlvl.py index cdf91c76a..98479c99c 100644 --- a/imod/tests/test_mf6/test_well_highlvl.py +++ b/imod/tests/test_mf6/test_well_highlvl.py @@ -12,6 +12,7 @@ import imod.tests.fixtures import imod.tests.fixtures.mf6_circle_fixture import imod.tests.fixtures.mf6_twri_fixture +from imod.mf6.validation_context import ValidationContext from imod.mf6.write_context import WriteContext from imod.schemata import ValidationError from imod.tests.fixtures.mf6_small_models_fixture import ( @@ -80,10 +81,9 @@ def test_write_well(tmp_path: Path, grid_data, grid_data_layered, reference_outp k = 100.0 top = ones_like(active.sel(layer=1), dtype=np.float64) bottom = grid_data_layered(np.float64, -2.0, 10) + validation_context = ValidationContext(False) write_context = WriteContext(tmp_path) - mf6_pkg = well.to_mf6_pkg( - active, top, bottom, k, False, write_context.is_partitioned - ) + mf6_pkg = well._to_mf6_pkg(active, top, bottom, k, validation_context) mf6_pkg.write("packagename", globaltimes, write_context) assert pathlib.Path.exists(tmp_path / "packagename.wel") assert pathlib.Path.exists(tmp_path / "packagename" / "wel.dat") diff --git a/pixi.toml b/pixi.toml index eb470f664..0f15bfa1f 100644 --- a/pixi.toml +++ b/pixi.toml @@ -42,7 +42,6 @@ unittests_jit = { cmd = [ "--junitxml=unittest_jit_report.xml", ], depends_on = ["install"], cwd = "imod/tests" } examples = { cmd = [ - "NUMBA_DISABLE_JIT=1", "pytest", "-n", "auto", "-m", "example", From 64a71348c4d623ab416a9f3e1f84b1d39d8ca047 Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Wed, 18 Sep 2024 16:27:15 +0200 Subject: [PATCH 48/53] Use target_k to distribute_riv_conductance, align signatures of drn and riv --- imod/mf6/drn.py | 4 ++-- imod/mf6/riv.py | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/imod/mf6/drn.py b/imod/mf6/drn.py index 7cc54b371..cf1e1b1e4 100644 --- a/imod/mf6/drn.py +++ b/imod/mf6/drn.py @@ -187,10 +187,10 @@ def from_imod5_data( period_data: dict[str, list[datetime]], target_discretization: StructuredDiscretization, target_npf: NodePropertyFlow, - allocation_option: ALLOCATION_OPTION, - distributing_option: DISTRIBUTING_OPTION, time_min: datetime, time_max: datetime, + allocation_option: ALLOCATION_OPTION, + distributing_option: DISTRIBUTING_OPTION, regridder_types: Optional[DrainageRegridMethod] = None, regrid_cache: RegridderWeightsCache = RegridderWeightsCache(), ) -> "Drainage": diff --git a/imod/mf6/riv.py b/imod/mf6/riv.py index 0787f387c..b0ae22d3d 100644 --- a/imod/mf6/riv.py +++ b/imod/mf6/riv.py @@ -13,6 +13,7 @@ from imod.mf6.disv import VerticesDiscretization from imod.mf6.drn import Drainage from imod.mf6.interfaces.iregridpackage import IRegridPackage +from imod.mf6.npf import NodePropertyFlow from imod.mf6.regrid.regrid_schemes import RiverRegridMethod from imod.mf6.utilities.regrid import ( RegridderWeightsCache, @@ -207,6 +208,7 @@ def from_imod5_data( imod5_data: dict[str, dict[str, GridDataArray]], period_data: dict[str, list[datetime]], target_discretization: StructuredDiscretization, + target_npf: NodePropertyFlow, time_min: datetime, time_max: datetime, allocation_option_riv: ALLOCATION_OPTION, @@ -264,6 +266,7 @@ def from_imod5_data( target_top = target_discretization.dataset["top"] target_bottom = target_discretization.dataset["bottom"] target_idomain = target_discretization.dataset["idomain"] + target_k = target_npf.dataset["k"] # gather input data data = { @@ -303,7 +306,7 @@ def from_imod5_data( conductance, target_top, target_bottom, - conductance, + target_k, regridded_package_data["stage"], regridded_package_data["bottom_elevation"], ) From 4562fd34eb30da8d18926f71d76e9f61cfa2a802 Mon Sep 17 00:00:00 2001 From: Joeri van Engelen Date: Wed, 18 Sep 2024 16:45:04 +0200 Subject: [PATCH 49/53] Update flow model object and riv tests with new signatures --- imod/mf6/model_gwf.py | 5 +++-- imod/tests/test_mf6/test_mf6_riv.py | 12 ++++++++++++ 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/imod/mf6/model_gwf.py b/imod/mf6/model_gwf.py index b97d6352c..35e6b93b9 100644 --- a/imod/mf6/model_gwf.py +++ b/imod/mf6/model_gwf.py @@ -345,10 +345,10 @@ def from_imod5_data( period_data, dis_pkg, npf_pkg, + times[0], + times[-1], allocation_options.drn, distributing_option=distributing_options.drn, - time_min=times[0], - time_max=times[-1], regridder_types=cast( DrainageRegridMethod, regridder_types.get(drn_key) ), @@ -364,6 +364,7 @@ def from_imod5_data( imod5_data, period_data, dis_pkg, + npf_pkg, times[0], times[-1], allocation_options.riv, diff --git a/imod/tests/test_mf6/test_mf6_riv.py b/imod/tests/test_mf6/test_mf6_riv.py index 124ae2f83..7e57abcde 100644 --- a/imod/tests/test_mf6/test_mf6_riv.py +++ b/imod/tests/test_mf6/test_mf6_riv.py @@ -13,6 +13,7 @@ import imod from imod.mf6.dis import StructuredDiscretization from imod.mf6.disv import VerticesDiscretization +from imod.mf6.npf import NodePropertyFlow from imod.mf6.write_context import WriteContext from imod.prepare.topsystem.allocation import ALLOCATION_OPTION from imod.prepare.topsystem.conductance import DISTRIBUTING_OPTION @@ -458,12 +459,15 @@ def test_import_river_from_imod5(imod5_dataset, tmp_path): period_data = imod5_dataset[1] globaltimes = [np.datetime64("2000-01-01")] target_dis = StructuredDiscretization.from_imod5_data(imod5_data) + grid = target_dis.dataset["idomain"] + target_npf = NodePropertyFlow.from_imod5_data(imod5_data, grid) (riv, drn) = imod.mf6.River.from_imod5_data( "riv-1", imod5_data, period_data, target_dis, + target_npf, time_min=datetime(2000, 1, 1), time_max=datetime(2002, 1, 1), allocation_option_riv=ALLOCATION_OPTION.at_elevation, @@ -495,6 +499,8 @@ def test_import_river_from_imod5_infiltration_factors(imod5_dataset): imod5_data = imod5_dataset[0] period_data = imod5_dataset[1] target_dis = StructuredDiscretization.from_imod5_data(imod5_data) + grid = target_dis.dataset["idomain"] + target_npf = NodePropertyFlow.from_imod5_data(imod5_data, grid) original_infiltration_factor = imod5_data["riv-1"]["infiltration_factor"] imod5_data["riv-1"]["infiltration_factor"] = ones_like(original_infiltration_factor) @@ -504,6 +510,7 @@ def test_import_river_from_imod5_infiltration_factors(imod5_dataset): imod5_data, period_data, target_dis, + target_npf, time_min=datetime(2000, 1, 1), time_max=datetime(2002, 1, 1), allocation_option_riv=ALLOCATION_OPTION.at_elevation, @@ -522,6 +529,7 @@ def test_import_river_from_imod5_infiltration_factors(imod5_dataset): imod5_data, period_data, target_dis, + target_npf, time_min=datetime(2000, 1, 1), time_max=datetime(2002, 1, 1), allocation_option_riv=ALLOCATION_OPTION.at_elevation, @@ -540,6 +548,8 @@ def test_import_river_from_imod5_period_data(imod5_dataset_periods): imod5_data = imod5_dataset_periods[0] imod5_periods = imod5_dataset_periods[1] target_dis = StructuredDiscretization.from_imod5_data(imod5_data, validate=False) + grid = target_dis.dataset["idomain"] + target_npf = NodePropertyFlow.from_imod5_data(imod5_data, grid) original_infiltration_factor = imod5_data["riv-1"]["infiltration_factor"] imod5_data["riv-1"]["infiltration_factor"] = ones_like(original_infiltration_factor) @@ -549,6 +559,7 @@ def test_import_river_from_imod5_period_data(imod5_dataset_periods): imod5_data, imod5_periods, target_dis, + target_npf, datetime(2002, 2, 2), datetime(2022, 2, 2), ALLOCATION_OPTION.at_elevation, @@ -567,6 +578,7 @@ def test_import_river_from_imod5_period_data(imod5_dataset_periods): imod5_data, imod5_periods, target_dis, + target_npf, datetime(2002, 2, 2), datetime(2022, 2, 2), ALLOCATION_OPTION.at_elevation, From cd7d7da0e07f39b08e4d6aeb4c0b18c6b9037856 Mon Sep 17 00:00:00 2001 From: Hendrik Kok Date: Tue, 24 Sep 2024 08:28:06 +0200 Subject: [PATCH 50/53] update Sprinkling class --- imod/formats/prj/prj.py | 8 ++++ imod/msw/__init__.py | 2 +- imod/msw/coupler_mapping.py | 8 ++-- imod/msw/model.py | 6 +-- imod/msw/sprinkling.py | 90 ++++++++++++++++++++++++++++--------- 5 files changed, 84 insertions(+), 30 deletions(-) diff --git a/imod/formats/prj/prj.py b/imod/formats/prj/prj.py index 147463b13..7dc838c2a 100644 --- a/imod/formats/prj/prj.py +++ b/imod/formats/prj/prj.py @@ -1047,7 +1047,15 @@ def open_projectfile_data(path: FilePath) -> Dict[str, Any]: data, repeats = _read_package_ipf(block_content, periods) elif key == "(cap)": variables = set(METASWAP_VARS).intersection(block_content.keys()) + # check for optional ipf input + read_ipf = False + if 'path' in block_content['artifical_recharge_layer'][0]: + if 'ipf' in block_content['artifical_recharge_layer'][0]['path'].suffix.lower(): + variables.remove('artifical_recharge_layer') + read_ipf = True data = _open_package_idf(block_content, variables) + if read_ipf: + data[0]['artifical_recharge_dataframe'] = imod.ipf.read(block_content['artifical_recharge_layer'][0]['path']) elif key in ("extra", "(pcg)"): data = [block_content] elif key in KEYS: diff --git a/imod/msw/__init__.py b/imod/msw/__init__.py index bcbe174aa..81ec7a41f 100644 --- a/imod/msw/__init__.py +++ b/imod/msw/__init__.py @@ -15,5 +15,5 @@ from imod.msw.output_control import TimeOutputControl, VariableOutputControl from imod.msw.ponding import Ponding from imod.msw.scaling_factors import ScalingFactors -from imod.msw.sprinkling import Sprinkling +from imod.msw.sprinkling import Sprinkling, SprinklingMultipleSources from imod.msw.vegetation import AnnualCropFactors diff --git a/imod/msw/coupler_mapping.py b/imod/msw/coupler_mapping.py index b7294813a..0b0662e04 100644 --- a/imod/msw/coupler_mapping.py +++ b/imod/msw/coupler_mapping.py @@ -9,7 +9,6 @@ from imod.msw.fixed_format import VariableMetaData from imod.msw.pkgbase import MetaSwapPackage - class CouplerMapping(MetaSwapPackage): """ This contains the data to connect MODFLOW 6 cells to MetaSWAP svats. @@ -108,10 +107,9 @@ def _create_well_id(self, svat): well_column = self.well["column"] - 1 well_layer = self.well["layer"] - 1 - n_mod = self.idomain_active.sum() - mod_id = xr.full_like(self.idomain_active, 0, dtype=np.int64) - mod_id.values[self.idomain_active.values] = np.arange(1, n_mod + 1) - + n_mod = self.idomain_active.sum().compute() + mod_id = xr.full_like(self.idomain_active, 0, dtype=np.int64).compute() + mod_id.values[self.idomain_active.values] = np.arange(1, n_mod + 1) well_mod_id = mod_id[well_layer, well_row, well_column] well_mod_id = np.tile(well_mod_id, (n_subunit, 1)) diff --git a/imod/msw/model.py b/imod/msw/model.py index b8b965991..18cf7db4d 100644 --- a/imod/msw/model.py +++ b/imod/msw/model.py @@ -212,9 +212,9 @@ def write(self, directory: Union[str, Path]): """ # Model checks - self._check_required_packages() - self._check_vegetation_indices_in_annual_crop_factors() - self._check_landuse_indices_in_lookup_options() + # self._check_required_packages() + # self._check_vegetation_indices_in_annual_crop_factors() + # self._check_landuse_indices_in_lookup_options() # Force to Path directory = Path(directory) diff --git a/imod/msw/sprinkling.py b/imod/msw/sprinkling.py index fa043aee7..136f522da 100644 --- a/imod/msw/sprinkling.py +++ b/imod/msw/sprinkling.py @@ -22,8 +22,11 @@ class Sprinkling(MetaSwapPackage): max_abstraction_surfacewater: array of floats (xr.DataArray) Describes the maximum abstraction of surfacewater to SVAT units in m3 per day. This array must not have a subunit coordinate. + well_id: array of int (xr.DataArray) + Describes per svat the corresponing id of the well package + from which water is extracted. well: WellDisStructured - Describes the sprinkling of SVAT units coming groundwater. + Describes the source location for groundwater intake. """ _file_name = "scap_svat.inp" @@ -33,21 +36,19 @@ class Sprinkling(MetaSwapPackage): "max_abstraction_surfacewater_mm_d": VariableMetaData(8, None, None, str), "max_abstraction_groundwater_m3_d": VariableMetaData(8, 0.0, 1e9, float), "max_abstraction_surfacewater_m3_d": VariableMetaData(8, 0.0, 1e9, float), - "svat_groundwater": VariableMetaData(10, None, None, str), + "svat_groundwater": VariableMetaData(10, 1, 99999999, int), "layer": VariableMetaData(6, 1, 9999, int), "trajectory": VariableMetaData(10, None, None, str), } - _with_subunit = () - _without_subunit = ( + _with_subunit = ( "max_abstraction_groundwater_m3_d", - "max_abstraction_surfacewater_m3_d", - ) + "max_abstraction_surfacewater_m3_d",) + _without_subunit = () _to_fill = ( "max_abstraction_groundwater_mm_d", "max_abstraction_surfacewater_mm_d", - "svat_groundwater", "trajectory", ) @@ -62,27 +63,74 @@ def __init__( self.dataset["max_abstraction_surfacewater_m3_d"] = max_abstraction_surfacewater self.well = well - self._pkgcheck() + self._pkgcheck() + def _render(self, file, index, svat): well_row = self.well["row"] - 1 - well_column = self.well["column"] - 1 - well_layer = self.well["layer"] + layer = self.well["layer"] + max_rate = self.dataset["max_abstraction_groundwater_m3_d"] + + svat_source_target = svat.where(max_rate > 0).to_numpy() + svat_source_target = svat_source_target[np.isfinite(svat_source_target)].astype(dtype=np.int32) - n_subunit = svat["subunit"].size + if svat_source_target.size != well_row.size: + raise ValueError('Provided well-pacakge does not correspond with the abstraction rate') - well_svat = svat.values[:, well_row, well_column] - well_active = well_svat != 0 + data_dict = {"svat": svat_source_target, "layer": layer, "svat_groundwater": svat_source_target} + + for var in self._with_subunit: + array = self.dataset[var].where(max_rate > 0).to_numpy() + array = array[np.isfinite(array)] + data_dict[var] = array + + for var in self._to_fill: + data_dict[var] = "" - # Tile well_layers for each subunit - layer = np.tile(well_layer, (n_subunit, 1)) + dataframe = pd.DataFrame( + data=data_dict, columns=list(self._metadata_dict.keys()) + ) + + self._check_range(dataframe) - data_dict = {"svat": well_svat[well_active], "layer": layer[well_active]} + return self.write_dataframe_fixed_width(file, dataframe) - for var in self._without_subunit: - well_arr = self.dataset[var].values[well_row, well_column] - well_arr = np.tile(well_arr, (n_subunit, 1)) - data_dict[var] = well_arr[well_active] + +class SprinklingMultipleSources(Sprinkling): + + def __init__( + self, + max_abstraction_groundwater: xr.DataArray, + max_abstraction_surfacewater: xr.DataArray, + well: WellDisStructured, + well_id: xr.DataArray + ): + super().__init__(max_abstraction_groundwater, max_abstraction_surfacewater, well) + self.well_id = well_id + + + def _render(self, file, index, svat): + well_row = self.well["row"] - 1 + well_column = self.well["column"] - 1 + layer_source = self.well["layer"] + max_rate = self.dataset["max_abstraction_groundwater_m3_d"] + + svat_target = svat.where(max_rate > 0).to_numpy() + svat_target = svat_target[np.isfinite(svat_target)].astype(dtype=np.int32) + + well_id = self.well_id.where(max_rate > 0).to_numpy() + well_id = well_id[np.isfinite(well_id)].astype(dtype=np.int32) + + # always use the first svat as source + svat_source = svat.to_numpy()[0, well_row[well_id], well_column[well_id]] + layer_source = layer_source[well_id] + + data_dict = {"svat": svat_target, "layer": layer_source, "svat_groundwater": svat_source} + + for var in self._with_subunit: + array = self.dataset[var].where(max_rate > 0).to_numpy() + array = array[np.isfinite(array)] + data_dict[var] = array for var in self._to_fill: data_dict[var] = "" @@ -93,4 +141,4 @@ def _render(self, file, index, svat): self._check_range(dataframe) - return self.write_dataframe_fixed_width(file, dataframe) + return self.write_dataframe_fixed_width(file, dataframe) \ No newline at end of file From fa854cbf7cf6b5429fbcbbc5efc651b8de59728c Mon Sep 17 00:00:00 2001 From: Hendrik Kok Date: Wed, 2 Oct 2024 13:56:59 +0200 Subject: [PATCH 51/53] force to float64 --- imod/prepare/spatial.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imod/prepare/spatial.py b/imod/prepare/spatial.py index 993f7779d..0982a1ac2 100644 --- a/imod/prepare/spatial.py +++ b/imod/prepare/spatial.py @@ -233,7 +233,7 @@ def rasterize(geodataframe, like, column=None, fill=np.nan, **kwargs): """ if column is not None: - shapes = list(zip(geodataframe.geometry, geodataframe[column])) + shapes = list(zip(geodataframe.geometry, geodataframe[column].astype(dtype=np.float64))) else: shapes = list(geodataframe.geometry) From ee1bfdcc4ee3a3a4d1a4dc952eebe2616293f60d Mon Sep 17 00:00:00 2001 From: Hendrik Kok Date: Thu, 14 Nov 2024 09:45:24 +0100 Subject: [PATCH 52/53] fix _reder methode of Sprinkling class to allow multiple svats per well node --- imod/msw/sprinkling.py | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/imod/msw/sprinkling.py b/imod/msw/sprinkling.py index 136f522da..e380ebc87 100644 --- a/imod/msw/sprinkling.py +++ b/imod/msw/sprinkling.py @@ -67,17 +67,34 @@ def __init__( def _render(self, file, index, svat): + def ravel_per_subunit(array: xr.DataArray) -> np.ndarray: + # per defined well element, all subunits + array_out = array.to_numpy()[:, well_row, well_column].ravel() + # per defined well element, per defined subunits + return array_out[np.isfinite(array_out)] + well_row = self.well["row"] - 1 - layer = self.well["layer"] - max_rate = self.dataset["max_abstraction_groundwater_m3_d"] + well_column = self.well["column"] - 1 + well_layer = self.well["layer"] + max_rate_per_svat = self.dataset["max_abstraction_groundwater_m3_d"].where( + svat > 0 + ) + layer_per_svat = xr.full_like(max_rate_per_svat, np.nan) + layer_per_svat[:, well_row, well_column] = well_layer + + layer_source = ravel_per_subunit( + layer_per_svat.where(max_rate_per_svat > 0) + ).astype(dtype=np.int32) + svat_source_target = ravel_per_subunit( + svat.where(max_rate_per_svat > 0) + ).astype(dtype=np.int32) + + data_dict = { + "svat": svat_source_target, + "layer": layer_source, + "svat_groundwater": svat_source_target, + } - svat_source_target = svat.where(max_rate > 0).to_numpy() - svat_source_target = svat_source_target[np.isfinite(svat_source_target)].astype(dtype=np.int32) - - if svat_source_target.size != well_row.size: - raise ValueError('Provided well-pacakge does not correspond with the abstraction rate') - - data_dict = {"svat": svat_source_target, "layer": layer, "svat_groundwater": svat_source_target} for var in self._with_subunit: array = self.dataset[var].where(max_rate > 0).to_numpy() From edb443dafe84ba71e1dc7e2f0ce236f3dd3b7ff1 Mon Sep 17 00:00:00 2001 From: Hendrik Kok Date: Thu, 14 Nov 2024 10:58:37 +0100 Subject: [PATCH 53/53] fix typo --- imod/msw/sprinkling.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/imod/msw/sprinkling.py b/imod/msw/sprinkling.py index e380ebc87..70d38f07d 100644 --- a/imod/msw/sprinkling.py +++ b/imod/msw/sprinkling.py @@ -97,7 +97,7 @@ def ravel_per_subunit(array: xr.DataArray) -> np.ndarray: for var in self._with_subunit: - array = self.dataset[var].where(max_rate > 0).to_numpy() + array = self.dataset[var].where(max_rate_per_svat > 0).to_numpy() array = array[np.isfinite(array)] data_dict[var] = array