From c750dd89f9ec472df8cf68f47a93c32813a3fef1 Mon Sep 17 00:00:00 2001 From: ecomodeller Date: Tue, 5 Mar 2024 07:33:39 +0000 Subject: [PATCH] deploy: 2bfaffd4bd83e88233eb766f3365965f2592429c --- api/DataArray.html | 6 ++ api/Dataset.html | 6 ++ api/Dfs0.html | 6 ++ api/Dfs1.html | 6 ++ api/Dfs2.html | 6 ++ api/Dfs3.html | 6 ++ api/Dfsu.html | 6 ++ api/EUMType.html | 6 ++ api/EUMUnit.html | 6 ++ api/Grid1D.html | 6 ++ api/Grid2D.html | 6 ++ api/Grid3D.html | 6 ++ api/ItemInfo.html | 6 ++ api/Mesh.html | 6 ++ api/PfsDocument.html | 6 ++ api/PfsSection.html | 6 ++ api/dataset._data_plot._DataArrayPlotter.html | 6 ++ ...ataset._data_plot._DataArrayPlotterFM.html | 6 ++ ...ot._DataArrayPlotterFMVerticalProfile.html | 6 ++ ...et._data_plot._DataArrayPlotterGrid1D.html | 6 ++ ...et._data_plot._DataArrayPlotterGrid2D.html | 6 ++ api/dfsu.Dfsu2DH.html | 6 ++ api/dfsu.Dfsu2DV.html | 6 ++ api/dfsu.Dfsu3D.html | 6 ++ api/dfsu.DfsuSpectral.html | 6 ++ api/generic.html | 6 ++ api/index.html | 6 ++ api/open.html | 6 ++ api/read.html | 6 ++ api/read_pfs.html | 6 ++ api/spatial.GeometryFM2D.html | 6 ++ api/spatial.GeometryFM3D.html | 6 ++ api/spatial.GeometryFMAreaSpectrum.html | 6 ++ api/spatial.GeometryFMLineSpectrum.html | 6 ++ api/spatial.GeometryFMPointSpectrum.html | 6 ++ api/spatial.GeometryFMVerticalColumn.html | 6 ++ api/spatial.GeometryFMVerticalProfile.html | 6 ++ ...atial._FM_geometry._GeometryFMPlotter.html | 6 ++ design.html | 6 ++ examples/Dfs2-Bathymetry.html | 50 ++++++----- examples/Dfsu-2D-interpolation.html | 64 +++++++------- examples/Generic.html | 72 ++++++++------- examples/Time-interpolation.html | 34 +++++--- examples/index.html | 14 ++- index.html | 8 +- search.json | 75 ++++++++++++++-- user-guide/data-structures.html | 6 ++ user-guide/dataarray.html | 26 +++--- user-guide/dataset.html | 6 ++ user-guide/dfs0.html | 12 ++- user-guide/dfs1.html | 10 ++- user-guide/dfs2.html | 16 ++-- user-guide/dfsu.html | 16 ++-- user-guide/eum.html | 30 ++++--- user-guide/generic.html | 6 ++ user-guide/getting-started.html | 16 ++-- user-guide/mesh.html | 87 ++++++++++++------- user-guide/pfs.html | 22 +++-- 58 files changed, 616 insertions(+), 188 deletions(-) diff --git a/api/DataArray.html b/api/DataArray.html index 03d4a944f..0dda8c185 100644 --- a/api/DataArray.html +++ b/api/DataArray.html @@ -238,6 +238,12 @@

Dfsu and Mesh Overview + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
  • Conventions :
    CF-1.6
    title :
    The GEBCO_2020 Grid - a continuous terrain model for oceans and land at 15 arc-second intervals
    institution :
    On behalf of the General Bathymetric Chart of the Oceans (GEBCO), the data are held at the British Oceanographic Data Centre (BODC).
    source :
    The GEBCO_2020 Grid is the latest global bathymetric product released by the General Bathymetric Chart of the Oceans (GEBCO) and has been developed through the Nippon Foundation-GEBCO Seabed 2030 Project. This is a collaborative project between the Nippon Foundation of Japan and GEBCO. The Seabed 2030 Project aims to bring together all available bathymetric data to produce the definitive map of the world ocean floor and make it available to all.
    history :
    Information on the development of the data set and the source data sets included in the grid can be found in the data set documentation available from https://www.gebco.net
    references :
    DOI: 10.5285/a29c5465-b138-234d-e053-6c86abc040b9
    comment :
    The data in the GEBCO_2020 Grid should not be used for navigation or any purpose relating to safety at sea.
    node_offset :
    1.0
  • -
    +
    ds.elevation.plot();
    @@ -763,7 +769,7 @@

    Dfs2 - Bathymetric data

    -
    +
    ds.elevation.sel(lon=12.74792, lat=55.865, method="nearest")
    @@ -1141,17 +1147,17 @@

    Dfs2 - Bathymetric data

    sdn_parameter_urn: SDN:P01::BATHHGHT sdn_parameter_name: Sea floor height (above mean sea level) {bathymetric... sdn_uom_urn: SDN:P06::ULAA - sdn_uom_name: Metres
    + sdn_uom_name: Metres

    Check ordering of dimensions, should be (y,x)

    -
    +
    ds.elevation.dims
    ('lat', 'lon')
    -
    +
    el = ds.elevation.values
     el.shape
    @@ -1159,37 +1165,37 @@

    Dfs2 - Bathymetric data

    Check that axes are increasing, S->N W->E

    -
    +
    ds.lat.values[0],ds.lat.values[-1] 
    (55.20208333333332, 56.29791666666665)
    -
    +
    ds.lat.values[0] < ds.lat.values[-1] 
    True
    -
    +
    ds.lon.values[0],ds.lon.values[-1] 
    (12.20208333333332, 13.097916666666663)
    -
    +
    el[0,0] # Bottom left
    -8
    -
    +
    el[-1,0] # Top Left
    -31
    -
    +
    geometry = mikeio.Grid2D(x=ds.lon.values, y=ds.lat.values, projection="LONG/LAT")
     geometry
    @@ -1199,7 +1205,7 @@

    Dfs2 - Bathymetric data

    projection: LONG/LAT
    -
    +
    da = mikeio.DataArray(data=el,
                    item=mikeio.ItemInfo("Elevation", mikeio.EUMType.Total_Water_Depth),
                    geometry=geometry,
    @@ -1214,7 +1220,7 @@ 

    Dfs2 - Bathymetric data

    geometry: Grid2D (ny=264, nx=216)
    -
    +
    da.plot();
    @@ -1224,7 +1230,7 @@

    Dfs2 - Bathymetric data

    -
    +
    da.plot(cmap='coolwarm', vmin=-100, vmax=100);
    @@ -1234,10 +1240,10 @@

    Dfs2 - Bathymetric data

    -
    +
    da.to_dfs("gebco.dfs2")
    -
    +
    ds = mikeio.read("gebco.dfs2")
     ds.Elevation.plot()
    @@ -1250,7 +1256,7 @@

    Dfs2 - Bathymetric data

    Clean up

    -
    +
    import os
     
     os.remove("gebco.dfs2")
    diff --git a/examples/Dfsu-2D-interpolation.html b/examples/Dfsu-2D-interpolation.html index 82dc0532f..6ab12b115 100644 --- a/examples/Dfsu-2D-interpolation.html +++ b/examples/Dfsu-2D-interpolation.html @@ -241,6 +241,12 @@

    Dfsu - 2D interpolation

    Dfsu and Mesh Overview
    + +
  • The interpolated data is then saved to a dfs2 file.
  • -
    +
    g = da.geometry.get_overset_grid(dx=0.1)
     g
    @@ -397,7 +403,7 @@

    Interpolate to grid

    -
    +
    da_grid = da.interp_like(g)
     da_grid
    @@ -408,7 +414,7 @@

    Interpolate to grid

    -
    +
    da_grid.plot();
    @@ -421,14 +427,14 @@

    Interpolate to grid

    Save to dfs2 file

    -
    +
    da_grid.to_dfs("wind_north_sea_interpolated.dfs2")

    Save to NetCDF

    -
    +
    xr_da = da_grid.to_xarray()
     xr_da.to_netcdf("wind_north_sea_interpolated.nc")
    @@ -449,7 +455,7 @@

    Save to GeoTiff

    This section requires the rasterio package.

    -
    +
    import numpy as np
     import rasterio
     from rasterio.transform import from_origin
    @@ -473,7 +479,7 @@ 

    Save to GeoTiff

    Interpolate to other mesh

    Interpolate the data from this coarse mesh onto a finer resolution mesh

    -
    +
    msh = mikeio.Mesh('../data/north_sea_2.mesh')
     msh
    @@ -483,7 +489,7 @@

    Interpolate to other mesh

    projection: LONG/LAT
    -
    +
    dsi = da.interp_like(msh)
     dsi
    @@ -494,7 +500,7 @@

    Interpolate to other mesh

    geometry: Dfsu2D (2259 elements, 1296 nodes)
    -
    +
    da[0].plot(figsize=(9,7), show_mesh=True);
    @@ -504,7 +510,7 @@

    Interpolate to other mesh

    -
    +
    dsi[0].plot(figsize=(9,7), show_mesh=True);
    @@ -516,14 +522,14 @@

    Interpolate to other mesh

    Note: 3 of the new elements are outside the original mesh and data are therefore NaN by default

    -
    +
    nan_elements = np.where(np.isnan(dsi[0].to_numpy()))[0]
     nan_elements
    array([ 249,  451, 1546])
    -
    +
    da.geometry.contains(msh.element_coordinates[nan_elements,:2])
    array([False, False, False])
    @@ -532,10 +538,10 @@

    We can force extrapolation to avoid the NaN values

    -
    +
    dat_interp = da.interp_like(msh, extrapolate=True)
    -
    +
    n_nan_elements = np.sum(np.isnan(dat_interp.values))
     n_nan_elements
    @@ -548,14 +554,14 @@

    Interpola

    We want to interpolate scatter data onto an existing mesh and create a new dfsu with the interpolated data.

    This uses lower level private utility methods not part of the public API.

    Interpolating from scatter data will soon be possible in a simpler way.

    -
    +
    from mikeio.spatial._utils import dist_in_meters
     from mikeio._interpolation import get_idw_interpolant
    -
    +
    dfs = mikeio.open("../data/wind_north_sea.dfsu")
    -
    +
    dfs.geometry.plot.mesh();
    @@ -565,7 +571,7 @@

    Interpola

    -
    +
    # scatter data: x,y,value for 4 points
     scatter= np.array([[1,50,1], [4, 52, 3], [8, 55, 2], [-1, 55, 1.5]])
     scatter
    @@ -582,35 +588,35 @@

    Interpola
  • calc IDW interpolatant weights
  • Interpolate
  • -
    +
    dist = dist_in_meters(scatter[:,:2], dfs.element_coordinates[0,:2])
     dist
    array([4.00139539, 3.18881018, 6.58769411, 2.69722991])
    -
    +
    w = get_idw_interpolant(dist, p=2)
     w
    array([0.19438779, 0.30607974, 0.07171749, 0.42781498])
    -
    +
    np.dot(scatter[:,2], w) # interpolated value in element 0
    1.8977844597276883

    Let’s do the same for all points in the mesh and plot in the end

    -
    +
    dati = np.zeros((1,dfs.n_elements))
     for j in range(dfs.n_elements):
         dist = dist_in_meters(scatter[:,:2], dfs.element_coordinates[j,:2])
         w = get_idw_interpolant(dist, p=2)
         dati[0,j] = np.dot(scatter[:,2], w)
    -
    +
    da = mikeio.DataArray(data=dati, geometry=dfs.geometry, time=dfs.start_time)
     da
    @@ -621,7 +627,7 @@

    Interpola geometry: Dfsu2D (958 elements, 570 nodes)

    -
    +
    da.plot(title="Interpolated scatter data");
    @@ -631,13 +637,13 @@

    Interpola

    -
    +
    da.to_dfs("interpolated_scatter.dfsu")

    Clean up

    -
    +
    import os
     
     os.remove("wind_north_sea_interpolated.dfs2")
    diff --git a/examples/Generic.html b/examples/Generic.html
    index 36858c658..7e139be0a 100644
    --- a/examples/Generic.html
    +++ b/examples/Generic.html
    @@ -243,6 +243,12 @@ 

    Generic dfs processing

    Dfsu and Mesh Overview
    + +
  • quantile: Create temporal quantiles of dfs file
  • -
    +
    import matplotlib.pyplot as plt
     import mikeio
     import mikeio.generic
    @@ -373,7 +379,7 @@

    Generic dfs processing

    Concatenation

    Take a look at these two files with overlapping timesteps.

    -
    +
    t1 = mikeio.read("../data/tide1.dfs1")
     t1
    @@ -385,7 +391,7 @@

    Concatenation

    0: Level <Water Level> (meter)
    -
    +
    t2 = mikeio.read("../data/tide2.dfs1")
     t2
    @@ -398,7 +404,7 @@

    Concatenation

    Plot one of the points along the line.

    -
    +
    plt.plot(t1.time,t1[0].isel(x=1).values, label="File 1")
     plt.plot(t2.time,t2[0].isel(x=1).values,'k+', label="File 2")
     plt.legend()
    @@ -410,15 +416,15 @@

    Concatenation

    -
    +
    mikeio.generic.concat(infilenames=["../data/tide1.dfs1",
                                        "../data/tide2.dfs1"],
                          outfilename="concat.dfs1")
    -
      0%|          | 0/2 [00:00<?, ?it/s]100%|██████████| 2/2 [00:00<00:00, 527.62it/s]
    +
      0%|          | 0/2 [00:00<?, ?it/s]100%|██████████| 2/2 [00:00<00:00, 582.99it/s]
    -
    +
    c = mikeio.read("concat.dfs1")
     c[0].isel(x=1).plot()
     c
    @@ -442,16 +448,16 @@

    Concatenation

    Difference between two files

    Take difference between two dfs files with same structure - e.g. to see the difference in result between two calibration runs

    -
    +
    fn1 = "../data/oresundHD_run1.dfsu"
     fn2 = "../data/oresundHD_run2.dfsu"
     fn_diff = "oresundHD_difference.dfsu"
     mikeio.generic.diff(fn1, fn2, fn_diff)
    -
      0%|          | 0/5 [00:00<?, ?it/s]100%|██████████| 5/5 [00:00<00:00, 2420.26it/s]
    +
      0%|          | 0/5 [00:00<?, ?it/s]100%|██████████| 5/5 [00:00<00:00, 2686.93it/s]
    -
    +
    _, ax = plt.subplots(1,3, sharey=True, figsize=(12,5))
     da = mikeio.read(fn1, time=-1)[0]
     da.plot(vmin=0.06, vmax=0.27, ax=ax[0], title='run 1')
    @@ -475,11 +481,11 @@ 

    Extract time s
  • time slice by specifying start and/or end
  • specific items
  • -
    +
    infile = "../data/tide1.dfs1"
     mikeio.generic.extract(infile, "extracted.dfs1", start='2019-01-02')
    -
    +
    e = mikeio.read("extracted.dfs1")
     e
    @@ -491,11 +497,11 @@

    Extract time s 0: Level <Water Level> (meter)

    -
    +
    infile = "../data/oresund_vertical_slice.dfsu"
     mikeio.generic.extract(infile, "extracted.dfsu", items='Salinity', end=-2)
    -
    +
    e = mikeio.read("extracted.dfsu")
     e
    @@ -516,7 +522,7 @@

    Extract time s

    Scaling

    Adding a constant e.g to adjust datum

    -
    +
    ds = mikeio.read("../data/gebco_sound.dfs2")
     ds.Elevation[0].plot();
    @@ -527,23 +533,23 @@

    Scaling

    -
    +
    ds['Elevation'][0,104,131].to_numpy()
    -1.0

    This is the processing step.

    -
    +
    mikeio.generic.scale("../data/gebco_sound.dfs2", 
                          "gebco_sound_local_datum.dfs2",
                          offset=-2.1
                          )
    -
      0%|          | 0/1 [00:00<?, ?it/s]100%|██████████| 1/1 [00:00<00:00, 1586.95it/s]
    +
      0%|          | 0/1 [00:00<?, ?it/s]100%|██████████| 1/1 [00:00<00:00, 1032.83it/s]
    -
    +
    ds2 = mikeio.read("gebco_sound_local_datum.dfs2")
     ds2['Elevation'][0].plot()
    @@ -554,7 +560,7 @@

    Scaling

    -
    +
    ds2['Elevation'][0,104,131].to_numpy()
    -3.1
    @@ -562,7 +568,7 @@

    Scaling

    Spatially varying correction

    -
    +
    import numpy as np
     factor = np.ones_like(ds['Elevation'][0].to_numpy())
     factor.shape
    @@ -571,7 +577,7 @@

    Spatially var

    Add some spatially varying factors, exaggerated values for educational purpose.

    -
    +
    factor[:,0:100] = 5.3
     factor[0:40,] = 0.1
     factor[150:,150:] = 10.7
    @@ -586,7 +592,7 @@ 

    Spatially var

    The 2d array must first be flipped upside down and then converted to a 1d vector using numpy.ndarray.flatten to match how data is stored in dfs files.

    -
    +
    factor_ud = np.flipud(factor)
     factor_vec  = factor_ud.flatten()
     mikeio.generic.scale("../data/gebco_sound.dfs2", 
    @@ -594,10 +600,10 @@ 

    Spatially var factor=factor_vec )

    -
      0%|          | 0/1 [00:00<?, ?it/s]100%|██████████| 1/1 [00:00<00:00, 1259.55it/s]
    +
      0%|          | 0/1 [00:00<?, ?it/s]100%|██████████| 1/1 [00:00<00:00, 1895.30it/s]
    -
    +
    ds3 = mikeio.read("gebco_sound_spatial.dfs2")
     ds3.Elevation[0].plot();
    @@ -612,15 +618,15 @@

    Spatially var

    Time average

    -
    +
    fn = "../data/NorthSea_HD_and_windspeed.dfsu"
     fn_avg = "Avg_NorthSea_HD_and_windspeed.dfsu"
     mikeio.generic.avg_time(fn, fn_avg)
    -
      0%|          | 0/66 [00:00<?, ?it/s]100%|██████████| 66/66 [00:00<00:00, 16045.91it/s]
    +
      0%|          | 0/66 [00:00<?, ?it/s]100%|██████████| 66/66 [00:00<00:00, 16490.38it/s]
    -
    +
    ds = mikeio.read(fn)
     ds.mean(axis=0).describe()   # alternative way of getting the time average
    @@ -684,7 +690,7 @@

    Time average

    -
    +
    ds_avg = mikeio.read(fn_avg)
     ds_avg.describe()
    @@ -752,12 +758,12 @@

    Time average

    Quantile

    Example that calculates the 25%, 50% and 75% percentile for all items in a dfsu file.

    -
    +
    fn = "../data/NorthSea_HD_and_windspeed.dfsu"
     fn_q = "Q_NorthSea_HD_and_windspeed.dfsu"
     mikeio.generic.quantile(fn, fn_q, q=[0.25,0.5,0.75])
    -
    +
    ds = mikeio.read(fn_q)
     ds
    @@ -774,7 +780,7 @@

    Quantile

    5: Quantile 0.75, Wind speed <Wind speed> (meter per sec)
    -
    +
    da_q75 = ds["Quantile 0.75, Wind speed"]
     da_q75.plot(title="75th percentile, wind speed", label="m/s")
    @@ -788,7 +794,7 @@

    Quantile

    Clean up

    -
    +
    import os
     os.remove("concat.dfs1")
     os.remove("oresundHD_difference.dfsu")
    diff --git a/examples/Time-interpolation.html b/examples/Time-interpolation.html
    index 210eb9eeb..de2fe9691 100644
    --- a/examples/Time-interpolation.html
    +++ b/examples/Time-interpolation.html
    @@ -241,6 +241,12 @@ 

    Time interpolation

    Dfsu and Mesh Overview
    + + + +

    Getting started

    -
    +
    import mikeio
     
     ds = mikeio.read("data/FakeLake.dfsu")
    diff --git a/search.json b/search.json
    index 26d299088..03d39bb7b 100644
    --- a/search.json
    +++ b/search.json
    @@ -908,7 +908,7 @@
         "href": "examples/Generic.html#concatenation",
         "title": "Generic dfs processing",
         "section": "Concatenation",
    -    "text": "Concatenation\nTake a look at these two files with overlapping timesteps.\n\nt1 = mikeio.read(\"../data/tide1.dfs1\")\nt1\n\n<mikeio.Dataset>\ndims: (time:97, x:10)\ntime: 2019-01-01 00:00:00 - 2019-01-03 00:00:00 (97 records)\ngeometry: Grid1D (n=10, dx=0.06667)\nitems:\n  0:  Level <Water Level> (meter)\n\n\n\nt2 = mikeio.read(\"../data/tide2.dfs1\")\nt2\n\n<mikeio.Dataset>\ndims: (time:97, x:10)\ntime: 2019-01-02 00:00:00 - 2019-01-04 00:00:00 (97 records)\ngeometry: Grid1D (n=10, dx=0.06667)\nitems:\n  0:  Level <Water Level> (meter)\n\n\nPlot one of the points along the line.\n\nplt.plot(t1.time,t1[0].isel(x=1).values, label=\"File 1\")\nplt.plot(t2.time,t2[0].isel(x=1).values,'k+', label=\"File 2\")\nplt.legend()\n\n\n\n\n\n\n\n\n\nmikeio.generic.concat(infilenames=[\"../data/tide1.dfs1\",\n                                   \"../data/tide2.dfs1\"],\n                     outfilename=\"concat.dfs1\")\n\n  0%|          | 0/2 [00:00<?, ?it/s]100%|██████████| 2/2 [00:00<00:00, 527.62it/s]\n\n\n\nc = mikeio.read(\"concat.dfs1\")\nc[0].isel(x=1).plot()\nc\n\n<mikeio.Dataset>\ndims: (time:145, x:10)\ntime: 2019-01-01 00:00:00 - 2019-01-04 00:00:00 (145 records)\ngeometry: Grid1D (n=10, dx=0.06667)\nitems:\n  0:  Level <Water Level> (meter)",
    +    "text": "Concatenation\nTake a look at these two files with overlapping timesteps.\n\nt1 = mikeio.read(\"../data/tide1.dfs1\")\nt1\n\n<mikeio.Dataset>\ndims: (time:97, x:10)\ntime: 2019-01-01 00:00:00 - 2019-01-03 00:00:00 (97 records)\ngeometry: Grid1D (n=10, dx=0.06667)\nitems:\n  0:  Level <Water Level> (meter)\n\n\n\nt2 = mikeio.read(\"../data/tide2.dfs1\")\nt2\n\n<mikeio.Dataset>\ndims: (time:97, x:10)\ntime: 2019-01-02 00:00:00 - 2019-01-04 00:00:00 (97 records)\ngeometry: Grid1D (n=10, dx=0.06667)\nitems:\n  0:  Level <Water Level> (meter)\n\n\nPlot one of the points along the line.\n\nplt.plot(t1.time,t1[0].isel(x=1).values, label=\"File 1\")\nplt.plot(t2.time,t2[0].isel(x=1).values,'k+', label=\"File 2\")\nplt.legend()\n\n\n\n\n\n\n\n\n\nmikeio.generic.concat(infilenames=[\"../data/tide1.dfs1\",\n                                   \"../data/tide2.dfs1\"],\n                     outfilename=\"concat.dfs1\")\n\n  0%|          | 0/2 [00:00<?, ?it/s]100%|██████████| 2/2 [00:00<00:00, 582.99it/s]\n\n\n\nc = mikeio.read(\"concat.dfs1\")\nc[0].isel(x=1).plot()\nc\n\n<mikeio.Dataset>\ndims: (time:145, x:10)\ntime: 2019-01-01 00:00:00 - 2019-01-04 00:00:00 (145 records)\ngeometry: Grid1D (n=10, dx=0.06667)\nitems:\n  0:  Level <Water Level> (meter)",
         "crumbs": [
           "Home",
           "Examples",
    @@ -920,7 +920,7 @@
         "href": "examples/Generic.html#difference-between-two-files",
         "title": "Generic dfs processing",
         "section": "Difference between two files",
    -    "text": "Difference between two files\nTake difference between two dfs files with same structure - e.g. to see the difference in result between two calibration runs\n\nfn1 = \"../data/oresundHD_run1.dfsu\"\nfn2 = \"../data/oresundHD_run2.dfsu\"\nfn_diff = \"oresundHD_difference.dfsu\"\nmikeio.generic.diff(fn1, fn2, fn_diff)\n\n  0%|          | 0/5 [00:00<?, ?it/s]100%|██████████| 5/5 [00:00<00:00, 2420.26it/s]\n\n\n\n_, ax = plt.subplots(1,3, sharey=True, figsize=(12,5))\nda = mikeio.read(fn1, time=-1)[0]\nda.plot(vmin=0.06, vmax=0.27, ax=ax[0], title='run 1')\nda = mikeio.read(fn2, time=-1)[0]\nda.plot(vmin=0.06, vmax=0.27, ax=ax[1], title='run 2')\nda = mikeio.read(fn_diff, time=-1)[0]\nda.plot(vmin=-0.1, vmax=0.1, cmap='coolwarm', ax=ax[2], title='difference');",
    +    "text": "Difference between two files\nTake difference between two dfs files with same structure - e.g. to see the difference in result between two calibration runs\n\nfn1 = \"../data/oresundHD_run1.dfsu\"\nfn2 = \"../data/oresundHD_run2.dfsu\"\nfn_diff = \"oresundHD_difference.dfsu\"\nmikeio.generic.diff(fn1, fn2, fn_diff)\n\n  0%|          | 0/5 [00:00<?, ?it/s]100%|██████████| 5/5 [00:00<00:00, 2686.93it/s]\n\n\n\n_, ax = plt.subplots(1,3, sharey=True, figsize=(12,5))\nda = mikeio.read(fn1, time=-1)[0]\nda.plot(vmin=0.06, vmax=0.27, ax=ax[0], title='run 1')\nda = mikeio.read(fn2, time=-1)[0]\nda.plot(vmin=0.06, vmax=0.27, ax=ax[1], title='run 2')\nda = mikeio.read(fn_diff, time=-1)[0]\nda.plot(vmin=-0.1, vmax=0.1, cmap='coolwarm', ax=ax[2], title='difference');",
         "crumbs": [
           "Home",
           "Examples",
    @@ -944,7 +944,7 @@
         "href": "examples/Generic.html#scaling",
         "title": "Generic dfs processing",
         "section": "Scaling",
    -    "text": "Scaling\nAdding a constant e.g to adjust datum\n\nds = mikeio.read(\"../data/gebco_sound.dfs2\")\nds.Elevation[0].plot();\n\n\n\n\n\n\n\n\n\nds['Elevation'][0,104,131].to_numpy()\n\n-1.0\n\n\nThis is the processing step.\n\nmikeio.generic.scale(\"../data/gebco_sound.dfs2\", \n                     \"gebco_sound_local_datum.dfs2\",\n                     offset=-2.1\n                     )\n\n  0%|          | 0/1 [00:00<?, ?it/s]100%|██████████| 1/1 [00:00<00:00, 1586.95it/s]\n\n\n\nds2 = mikeio.read(\"gebco_sound_local_datum.dfs2\")\nds2['Elevation'][0].plot()\n\n\n\n\n\n\n\n\n\nds2['Elevation'][0,104,131].to_numpy()\n\n-3.1\n\n\n\nSpatially varying correction\n\nimport numpy as np\nfactor = np.ones_like(ds['Elevation'][0].to_numpy())\nfactor.shape\n\n(264, 216)\n\n\nAdd some spatially varying factors, exaggerated values for educational purpose.\n\nfactor[:,0:100] = 5.3\nfactor[0:40,] = 0.1\nfactor[150:,150:] = 10.7\nplt.imshow(factor)\nplt.colorbar();\n\n\n\n\n\n\n\n\nThe 2d array must first be flipped upside down and then converted to a 1d vector using numpy.ndarray.flatten to match how data is stored in dfs files.\n\nfactor_ud = np.flipud(factor)\nfactor_vec  = factor_ud.flatten()\nmikeio.generic.scale(\"../data/gebco_sound.dfs2\", \n                     \"gebco_sound_spatial.dfs2\",\n                     factor=factor_vec\n                     )\n\n  0%|          | 0/1 [00:00<?, ?it/s]100%|██████████| 1/1 [00:00<00:00, 1259.55it/s]\n\n\n\nds3 = mikeio.read(\"gebco_sound_spatial.dfs2\")\nds3.Elevation[0].plot();",
    +    "text": "Scaling\nAdding a constant e.g to adjust datum\n\nds = mikeio.read(\"../data/gebco_sound.dfs2\")\nds.Elevation[0].plot();\n\n\n\n\n\n\n\n\n\nds['Elevation'][0,104,131].to_numpy()\n\n-1.0\n\n\nThis is the processing step.\n\nmikeio.generic.scale(\"../data/gebco_sound.dfs2\", \n                     \"gebco_sound_local_datum.dfs2\",\n                     offset=-2.1\n                     )\n\n  0%|          | 0/1 [00:00<?, ?it/s]100%|██████████| 1/1 [00:00<00:00, 1032.83it/s]\n\n\n\nds2 = mikeio.read(\"gebco_sound_local_datum.dfs2\")\nds2['Elevation'][0].plot()\n\n\n\n\n\n\n\n\n\nds2['Elevation'][0,104,131].to_numpy()\n\n-3.1\n\n\n\nSpatially varying correction\n\nimport numpy as np\nfactor = np.ones_like(ds['Elevation'][0].to_numpy())\nfactor.shape\n\n(264, 216)\n\n\nAdd some spatially varying factors, exaggerated values for educational purpose.\n\nfactor[:,0:100] = 5.3\nfactor[0:40,] = 0.1\nfactor[150:,150:] = 10.7\nplt.imshow(factor)\nplt.colorbar();\n\n\n\n\n\n\n\n\nThe 2d array must first be flipped upside down and then converted to a 1d vector using numpy.ndarray.flatten to match how data is stored in dfs files.\n\nfactor_ud = np.flipud(factor)\nfactor_vec  = factor_ud.flatten()\nmikeio.generic.scale(\"../data/gebco_sound.dfs2\", \n                     \"gebco_sound_spatial.dfs2\",\n                     factor=factor_vec\n                     )\n\n  0%|          | 0/1 [00:00<?, ?it/s]100%|██████████| 1/1 [00:00<00:00, 1895.30it/s]\n\n\n\nds3 = mikeio.read(\"gebco_sound_spatial.dfs2\")\nds3.Elevation[0].plot();",
         "crumbs": [
           "Home",
           "Examples",
    @@ -956,7 +956,7 @@
         "href": "examples/Generic.html#time-average",
         "title": "Generic dfs processing",
         "section": "Time average",
    -    "text": "Time average\n\nfn = \"../data/NorthSea_HD_and_windspeed.dfsu\"\nfn_avg = \"Avg_NorthSea_HD_and_windspeed.dfsu\"\nmikeio.generic.avg_time(fn, fn_avg)\n\n  0%|          | 0/66 [00:00<?, ?it/s]100%|██████████| 66/66 [00:00<00:00, 16045.91it/s]\n\n\n\nds = mikeio.read(fn)\nds.mean(axis=0).describe()   # alternative way of getting the time average\n\n\n\n\n\n\n\n\n\nSurface elevation\nWind speed\n\n\n\n\ncount\n958.000000\n958.000000\n\n\nmean\n0.449857\n12.772706\n\n\nstd\n0.178127\n2.367667\n\n\nmin\n0.114355\n6.498364\n\n\n25%\n0.373691\n11.199439\n\n\n50%\n0.431747\n12.984060\n\n\n75%\n0.479224\n14.658077\n\n\nmax\n1.202888\n16.677952\n\n\n\n\n\n\n\n\n\nds_avg = mikeio.read(fn_avg)\nds_avg.describe()\n\n\n\n\n\n\n\n\n\nSurface elevation\nWind speed\n\n\n\n\ncount\n958.000000\n958.000000\n\n\nmean\n0.449857\n12.772706\n\n\nstd\n0.178127\n2.367667\n\n\nmin\n0.114355\n6.498364\n\n\n25%\n0.373691\n11.199439\n\n\n50%\n0.431747\n12.984060\n\n\n75%\n0.479224\n14.658077\n\n\nmax\n1.202888\n16.677952",
    +    "text": "Time average\n\nfn = \"../data/NorthSea_HD_and_windspeed.dfsu\"\nfn_avg = \"Avg_NorthSea_HD_and_windspeed.dfsu\"\nmikeio.generic.avg_time(fn, fn_avg)\n\n  0%|          | 0/66 [00:00<?, ?it/s]100%|██████████| 66/66 [00:00<00:00, 16490.38it/s]\n\n\n\nds = mikeio.read(fn)\nds.mean(axis=0).describe()   # alternative way of getting the time average\n\n\n\n\n\n\n\n\n\nSurface elevation\nWind speed\n\n\n\n\ncount\n958.000000\n958.000000\n\n\nmean\n0.449857\n12.772706\n\n\nstd\n0.178127\n2.367667\n\n\nmin\n0.114355\n6.498364\n\n\n25%\n0.373691\n11.199439\n\n\n50%\n0.431747\n12.984060\n\n\n75%\n0.479224\n14.658077\n\n\nmax\n1.202888\n16.677952\n\n\n\n\n\n\n\n\n\nds_avg = mikeio.read(fn_avg)\nds_avg.describe()\n\n\n\n\n\n\n\n\n\nSurface elevation\nWind speed\n\n\n\n\ncount\n958.000000\n958.000000\n\n\nmean\n0.449857\n12.772706\n\n\nstd\n0.178127\n2.367667\n\n\nmin\n0.114355\n6.498364\n\n\n25%\n0.373691\n11.199439\n\n\n50%\n0.431747\n12.984060\n\n\n75%\n0.479224\n14.658077\n\n\nmax\n1.202888\n16.677952",
         "crumbs": [
           "Home",
           "Examples",
    @@ -1086,7 +1086,72 @@
         "href": "user-guide/mesh.html",
         "title": "Mesh",
         "section": "",
    -    "text": "read mesh file\nplot mesh\nconvert to shapely\ncheck if point is inside or outside mesh\nsubset mesh, plot subset\nchange z values\nchange boundary codes\n\n\nimport matplotlib.pyplot as plt\nimport mikeio\n\n\nmsh = mikeio.Mesh(\"../data/odense_rough.mesh\")\nmsh\n\n<Mesh>\nnumber of elements: 654\nnumber of nodes: 399\nprojection: UTM-33\n\n\n\nmsh.plot()\n\n\n\n\n\n\n\n\n\nmsh.plot.boundary_nodes(boundary_names=['Land','Open boundary']);\n\n\n\n\n\n\n\n\n\nConvert mesh to shapely\nConvert mesh to shapely MultiPolygon object, requires that the shapely library is installed.\n\nmp = msh.to_shapely()\nmp\n\n\n\n\n\n\n\n\nNow a lot of methods are available\n\nmp.area\n\n68931409.58160606\n\n\n\nmp.bounds\n\n(211068.501175313, 6153077.66681803, 224171.617336507, 6164499.42751662)\n\n\n\ndomain = mp.buffer(0)\ndomain\n\n\n\n\n\n\n\n\n\nopen_water = domain.buffer(-500)\n\ncoastalzone = domain - open_water\ncoastalzone\n\n\n\n\n\n\n\n\nFind if points are inside the domain\n\nfrom shapely.geometry import Point\n\np1 = Point(216000, 6162000)\np2 = Point(220000, 6156000)\nprint(mp.contains(p1))\nprint(mp.contains(p2))\n\nTrue\nFalse\n\n\nWe can get similar functionality from the .geometry attribute of the mesh object.\n\np1p2 = [[216000, 6162000], [220000, 6156000]]\nmsh.geometry.contains(p1p2)\n\narray([ True, False])\n\n\n\nax = msh.plot()\nax.scatter(p1.x, p1.y, marker=\"*\", s=200, c=\"red\", label=\"inside\")\nax.scatter(p2.x, p2.y, marker=\"+\", s=200, c=\"green\", label=\"outside\")\nax.legend();\n\n\n\n\n\n\n\n\n\n\nChange z values and boundary code\nAssume that we want to have a minimum depth of 2 meters and change the open boundary (code 2) to a closed one (code 1).\n\ng = msh.geometry\nprint(f'max z before: {g.node_coordinates[:,2].max()}')\nzc = g.node_coordinates[:,2]\nzc[zc>-2] = -2\ng.node_coordinates[:,2] = zc\nprint(f'max z after: {g.node_coordinates[:,2].max()}')\n\nmax z before: -0.200000002980232\nmax z after: -2.0\n\n\n\nc = g.codes\nc[c==2] = 1\ng.codes = c\n\nSave the modfied geometry to a new mesh file\n\ng.to_mesh(\"new_mesh.mesh\")\n\nCleanup\n\nimport os\n\nos.remove(\"new_mesh.mesh\")"
    +    "text": "import matplotlib.pyplot as plt\nimport mikeio",
    +    "crumbs": [
    +      "Home",
    +      "User Guide",
    +      "Mesh"
    +    ]
    +  },
    +  {
    +    "objectID": "user-guide/mesh.html#read-mesh-file",
    +    "href": "user-guide/mesh.html#read-mesh-file",
    +    "title": "Mesh",
    +    "section": "Read mesh file",
    +    "text": "Read mesh file\n\nmsh = mikeio.Mesh(\"../data/odense_rough.mesh\")\nmsh\n\n<Mesh>\nnumber of elements: 654\nnumber of nodes: 399\nprojection: UTM-33",
    +    "crumbs": [
    +      "Home",
    +      "User Guide",
    +      "Mesh"
    +    ]
    +  },
    +  {
    +    "objectID": "user-guide/mesh.html#plot-mesh",
    +    "href": "user-guide/mesh.html#plot-mesh",
    +    "title": "Mesh",
    +    "section": "Plot mesh",
    +    "text": "Plot mesh\n\nmsh.plot()\n\n\n\n\n\n\n\n\n\nmsh.plot.boundary_nodes(boundary_names=['Land','Open boundary']);",
    +    "crumbs": [
    +      "Home",
    +      "User Guide",
    +      "Mesh"
    +    ]
    +  },
    +  {
    +    "objectID": "user-guide/mesh.html#check-if-points-are-inside-the-domain",
    +    "href": "user-guide/mesh.html#check-if-points-are-inside-the-domain",
    +    "title": "Mesh",
    +    "section": "Check if points are inside the domain",
    +    "text": "Check if points are inside the domain\n\nfrom shapely.geometry import Point\n\np1 = Point(216000, 6162000)\np2 = Point(220000, 6156000)\nprint(mp.contains(p1))\nprint(mp.contains(p2))\n\nTrue\nFalse\n\n\nWe can get similar functionality from the .geometry attribute of the mesh object.\n\np1p2 = [[216000, 6162000], [220000, 6156000]]\nmsh.geometry.contains(p1p2)\n\narray([ True, False])\n\n\n\nax = msh.plot()\nax.scatter(p1.x, p1.y, marker=\"*\", s=200, c=\"red\", label=\"inside\")\nax.scatter(p2.x, p2.y, marker=\"+\", s=200, c=\"green\", label=\"outside\")\nax.legend();",
    +    "crumbs": [
    +      "Home",
    +      "User Guide",
    +      "Mesh"
    +    ]
    +  },
    +  {
    +    "objectID": "user-guide/mesh.html#change-z-values-and-boundary-code",
    +    "href": "user-guide/mesh.html#change-z-values-and-boundary-code",
    +    "title": "Mesh",
    +    "section": "Change z values and boundary code",
    +    "text": "Change z values and boundary code\nAssume that we want to have a minimum depth of 2 meters and change the open boundary (code 2) to a closed one (code 1).\n\ng = msh.geometry\nprint(f'max z before: {g.node_coordinates[:,2].max()}')\nzc = g.node_coordinates[:,2]\nzc[zc>-2] = -2\ng.node_coordinates[:,2] = zc\nprint(f'max z after: {g.node_coordinates[:,2].max()}')\n\nmax z before: -0.200000002980232\nmax z after: -2.0\n\n\n\nc = g.codes\nc[c==2] = 1\ng.codes = c",
    +    "crumbs": [
    +      "Home",
    +      "User Guide",
    +      "Mesh"
    +    ]
    +  },
    +  {
    +    "objectID": "user-guide/mesh.html#save-the-modfied-geometry-to-a-new-mesh-file",
    +    "href": "user-guide/mesh.html#save-the-modfied-geometry-to-a-new-mesh-file",
    +    "title": "Mesh",
    +    "section": "Save the modfied geometry to a new mesh file",
    +    "text": "Save the modfied geometry to a new mesh file\n\ng.to_mesh(\"new_mesh.mesh\")\n\nCleanup\n\nimport os\n\nos.remove(\"new_mesh.mesh\")",
    +    "crumbs": [
    +      "Home",
    +      "User Guide",
    +      "Mesh"
    +    ]
       },
       {
         "objectID": "user-guide/data-structures.html",
    diff --git a/user-guide/data-structures.html b/user-guide/data-structures.html
    index 91470e5d3..f19299b42 100644
    --- a/user-guide/data-structures.html
    +++ b/user-guide/data-structures.html
    @@ -206,6 +206,12 @@ 

    Dfsu and Mesh Overview
    + + +
  • values - a numpy.ndarray
  • Use DataArray’s string representation to get an overview of the DataArray

    -
    +
    import mikeio
     
     ds = mikeio.read("../data/HD2D.dfsu")
    @@ -375,7 +381,7 @@ 

    DataArray

    Temporal selection

    -
    +
    da.sel(time="1985-08-06 12:00")
    <mikeio.DataArray>
    @@ -386,7 +392,7 @@ 

    +
    da["1985-8-7":]
    <mikeio.DataArray>
    @@ -400,7 +406,7 @@ 

    Spatial selection

    The sel method finds the nearest element.

    -
    +
    da.sel(x=607002, y=6906734)
    <mikeio.DataArray>
    @@ -415,17 +421,17 @@ 

    Modifying values

    You can modify the values of a DataArray by changing its values:

    -
    +
    da.values[0, 3] = 5.0

    If you wish to change values of a subset of the DataArray you should be aware of the difference between a view and a copy of the data. Similar to NumPy, MIKE IO selection method will return a view of the data when using single index and slices, but a copy of the data using fancy indexing (a list of indicies or boolean indexing). Note that prior to release 1.3, MIKE IO would always return a copy.

    It is recommended to change the values using values property directly on the original DataArray (like above), but it is also possible to change the values of the original DataArray by working on a subset DataArray if it is selected with single index or slice as explained above.

    -
    +
    da_sub = da.isel(time=0)
     da_sub.values[:] = 5.0    # will change da

    Fancy indexing will return a copy and therefore not change the original:

    -
    +
    da_sub = da.isel(time=[0,1,2])
     da_sub.values[:] = 5.0    # will NOT change da
    @@ -433,7 +439,7 @@

    Modifying values

    Plotting

    The plotting of a DataArray is context-aware meaning that plotting behaviour depends on the geometry of the DataArray being plotted.

    -
    +
    da.plot()
    @@ -443,7 +449,7 @@

    -
    +
    da.plot.contourf()
    @@ -453,7 +459,7 @@

    -
    +
    da.plot.mesh()
    diff --git a/user-guide/dataset.html b/user-guide/dataset.html index c93c413ea..ca9d409b6 100644 --- a/user-guide/dataset.html +++ b/user-guide/dataset.html @@ -242,6 +242,12 @@

    Dfsu and Mesh Overview
    + + + + + + +
  • unit - an EUMUnit
  • The ItemInfo class has some sensible defaults, thus you can specify only a name or a type. If you don’t specify a unit, the default unit for that type will be used.

    -
    +
    from mikeio import ItemInfo, EUMType, EUMUnit
     
     item = ItemInfo("Viken", EUMType.Water_Level)
    @@ -354,47 +360,47 @@ 

    EUM

    Viken <Water Level> (meter)
    -
    +
    ItemInfo(EUMType.Wind_speed)
    Wind speed <Wind speed> (meter per sec)
    -
    +
    ItemInfo("Viken", EUMType.Water_Level, EUMUnit.feet)
    Viken <Water Level> (feet)

    Matching units for specific type:

    -
    +
    EUMType.Wind_speed.units
    [meter per sec, feet per sec, knot, km per hour, miles per hour]

    Default unit:

    -
    +
    EUMType.Precipitation_Rate.units[0]
    mm per day
    -
    +
    unit = EUMType.Precipitation_Rate.units[0]
     unit
    mm per day
    -
    +
    type(unit)
    <enum 'EUMUnit'>

    a [](mikeio.EUMUnit)` is encoded as integers, which you can utilize in some MIKE applications.

    -
    +
    int(unit)
     2004
    @@ -404,7 +410,7 @@

    EUM

    -
    +

    +
    +

    Plot mesh

    +
    msh.plot()
    @@ -370,7 +380,7 @@

    Mesh

    -
    +
    msh.plot.boundary_nodes(boundary_names=['Land','Open boundary']);
    @@ -380,10 +390,11 @@

    Mesh

    +

    Convert mesh to shapely

    Convert mesh to shapely MultiPolygon object, requires that the shapely library is installed.

    -
    +
    mp = msh.to_shapely()
     mp
    @@ -395,19 +406,19 @@

    Convert mesh to shapely

    Now a lot of methods are available

    -
    +
    mp.area
    68931409.58160606
    -
    +
    mp.bounds
    (211068.501175313, 6153077.66681803, 224171.617336507, 6164499.42751662)
    -
    +
    domain = mp.buffer(0)
     domain
    @@ -418,7 +429,7 @@

    Convert mesh to shapely

    -
    +
    open_water = domain.buffer(-500)
     
     coastalzone = domain - open_water
    @@ -431,8 +442,9 @@ 

    Convert mesh to shapely

    -

    Find if points are inside the domain

    -
    +
    +

    Check if points are inside the domain

    +
    from shapely.geometry import Point
     
     p1 = Point(216000, 6162000)
    @@ -445,14 +457,14 @@ 

    Convert mesh to shapely

    We can get similar functionality from the .geometry attribute of the mesh object.

    -
    +
    p1p2 = [[216000, 6162000], [220000, 6156000]]
     msh.geometry.contains(p1p2)
    array([ True, False])
    -
    +
    ax = msh.plot()
     ax.scatter(p1.x, p1.y, marker="*", s=200, c="red", label="inside")
     ax.scatter(p2.x, p2.y, marker="+", s=200, c="green", label="outside")
    @@ -466,10 +478,10 @@ 

    Convert mesh to shapely

    -
    -

    Change z values and boundary code

    +
    +

    Change z values and boundary code

    Assume that we want to have a minimum depth of 2 meters and change the open boundary (code 2) to a closed one (code 1).

    -
    +
    g = msh.geometry
     print(f'max z before: {g.node_coordinates[:,2].max()}')
     zc = g.node_coordinates[:,2]
    @@ -481,23 +493,26 @@ 

    Change z values and boundary code

    max z after: -2.0
    -
    +
    c = g.codes
     c[c==2] = 1
     g.codes = c
    -

    Save the modfied geometry to a new mesh file

    -
    +
    +
    +

    Save the modfied geometry to a new mesh file

    +
    g.to_mesh("new_mesh.mesh")

    Cleanup

    -
    +
    import os
     
     os.remove("new_mesh.mesh")
    +
    @@ -888,6 +903,18 @@

    Change z values and boundary code

    } }); +