Coverage for C:\src\imod-python\imod\msw\idf_mapping.py: 38%

1 import numpy as np

2 import xarray as xr

3

4 from imod.msw.fixed_format import VariableMetaData

5 from imod.msw.pkgbase import MetaSwapPackage

6 from imod.util.spatial import spatial_reference

7

8

9 class IdfMapping(MetaSwapPackage):

10 """

11 Describes svat location in the IDF grid.

12

13 Note that MetaSWAP can only write equidistant grids.

14 """

15

16 _file_name = "idf_svat.inp"

17 _metadata_dict = {

18 "svat": VariableMetaData(10, 1, 9999999, int),

19 "rows": VariableMetaData(10, 1, 9999999, int),

20 "columns": VariableMetaData(10, 1, 9999999, int),

21 "y_grid": VariableMetaData(15, -9999999.0, 9999999.0, float),

22 "x_grid": VariableMetaData(15, -9999999.0, 9999999.0, float),

23 }

24

25 _with_subunit = ()

26 _without_subunit = ("rows", "columns", "y_grid", "x_grid")

27 _to_fill = ()

28

29 # NOTE that it is stated in the IO manual: "The x- and y-coordinates should

30 # increase with increasing col, row." But the example works with decreasing

31 # y-coordinates.

32

33 def __init__(self, area, nodata):

34 super().__init__()

35

36 self.dataset["area"] = area

37 self.dataset["nodata"] = nodata

38

39 nrow = self.dataset.coords["y"].size

40 ncol = self.dataset.coords["x"].size

41

42 y_index = xr.DataArray(

43 np.arange(1, nrow + 1), coords={"y": self.dataset.coords["y"]}, dims=("y",)

44 )

45 x_index = xr.DataArray(

46 np.arange(1, ncol + 1), coords={"x": self.dataset.coords["x"]}, dims=("x",)

47 )

48 rows, columns = xr.broadcast(y_index, x_index)

49

50 self.dataset["rows"] = rows

51 self.dataset["columns"] = columns

52

53 y_grid, x_grid = xr.broadcast(self.dataset["y"], self.dataset["x"])

54

55 self.dataset["x_grid"] = x_grid

56 self.dataset["y_grid"] = y_grid

57

58 def get_output_settings(self):

59 grid = self.dataset["area"]

60 dx, xmin, _, dy, ymin, _ = spatial_reference(grid)

61 ncol = grid["x"].size

62 nrow = grid["y"].size

63

64 # If non-equidistant, spatial_reference returned a 1d array instead of

65 # float

66 if (not np.isscalar(dx)) or (not np.isscalar(dy)):

67 raise ValueError("MetaSWAP only supports equidistant grids")

68

69 nodata = self.dataset["nodata"].values

70

71 return dict(

72 simgro_opt=-1,

73 idf_per=1,

74 idf_dx=dx,

75 idf_dy=np.abs(dy),

76 idf_ncol=ncol,

77 idf_nrow=nrow,

78 idf_xmin=xmin,

79 idf_ymin=ymin,

80 idf_nodata=nodata,

81 )