Skip to content

Commit

Permalink
Language can be fr/en, update README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
lucduron committed Mar 2, 2024
1 parent 33de263 commit 742560b
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 19 deletions.
73 changes: 59 additions & 14 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,21 +1,65 @@
# xarray backend for Selafin formats

Supports lazy loading by default.

## Dev guide

to have the backend working in xarray, follow these steps
To have the backend working in xarray, follow these steps:

```
pip install xarray-selafin
```

## Read selafin
## Read Selafin

```python
import xarray as xr
ds = xr.open_dataset("input_file.slf", engine="selafin")
ds = xr.open_dataset("tests/data/r3d_tidal_flats.slf", engine="selafin")
ds = xr.open_dataset("tests/data/r3d_tidal_flats.slf", lang="fr", engine="selafin") # if variables are in French
```

```
<xarray.Dataset>
Dimensions: (time: 17, node: 648, plan: 21)
Coordinates:
x (node) float32 ...
y (node) float32 ...
* time (time) datetime64[ns] 1900-01-01 ... 1900-01-02T20:26:40
Dimensions without coordinates: node, plan
Data variables:
Z (time, node, plan) <class 'numpy.float64'> ...
U (time, node, plan) <class 'numpy.float64'> ...
V (time, node, plan) <class 'numpy.float64'> ...
W (time, node, plan) <class 'numpy.float64'> ...
MUD (time, node, plan) <class 'numpy.float64'> ...
Attributes:
title: Sloped flume Rouse profile test
language: en
float_size: 4
endian: >
params: (1, 0, 0, 0, 0, 0, 21, 5544, 0, 1)
ipobo: [ 1 264 263 ... 5411 5412 5413]
ikle2: [[155 153 156]\n [310 307 305]\n [308 310 305]\n ...\n [537 ...
ikle3: [[ 155 153 156 803 801 804]\n [ 310 307 305 ...
variables: {'Z': ('ELEVATION Z', 'M'), 'U': ('VELOCITY U', 'M/S'), 'V':...
date_start: (1900, 1, 1, 0, 0, 0)
```

## Indexing

```python
ds_last = ds.isel(time=-1) # last frame
```

## Manipulate variables

```python
ds = ds.assign(UTIMES100=lambda x: x.U * 100) # Add a new variable
# ds.attrs["variables"]["UTIMES100"] = ("UTIMES100", "My/Unit") # To provide variable name and unit (optional)
ds.drop_vars(["W"]) # Remove variable `VELOCITY W`
```

## Write selafin
## Write Selafin

```python
ds.selafin.write("output_file.slf")
Expand All @@ -40,13 +84,14 @@ ds.selafin.write("output_file.slf")

All attributes are optional except `ikle2`:

| Attribute | Description | Default value |
|------------|--------------------------------------------------------------------------|--------------------------|
| title | Serafin title | "" (empty string) |
| float_size | Float size | 4 (single precision) |
| endian | File endianness | ">" |
| params | Table of integer parameters | (can be rebuilt) |
| ikle2 | Connectivity table in 2D (1-indexed) | - |
| ikle3 | Connectivity table in 3D (1-indexed, only in 3D, optional) | (can be rebuilt from 2D) |
| variables | Dictionary with variable names and units (key is variable abbreviation) | - |
| date_start | Starting date with integers | (from first time serie) |
| Attribute | Description | Default value |
|------------|-------------------------------------------------------------------------|--------------------------|
| title | Serafin title | "" (empty string) |
| language | Language for variable detection | "en" |
| float_size | Float size | 4 (single precision) |
| endian | File endianness | ">" |
| params | Table of integer parameters | (can be rebuilt) |
| ikle2 | Connectivity table in 2D (1-indexed) | - |
| ikle3 | Connectivity table in 3D (1-indexed, only in 3D, optional) | (can be rebuilt from 2D) |
| variables | Dictionary with variable names and units (key is variable abbreviation) | - |
| date_start | Starting date with integers (year to seconds) | (from first time serie) |
6 changes: 5 additions & 1 deletion xarray_selafin/Serafin.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@

logger = logging.getLogger(__name__)


# Default language for variables
LANG = "en"

# Encoding Information Type (EIT) for Serafin title, variable names and units
SLF_EIT = "iso-8859-1"

Expand Down Expand Up @@ -129,7 +133,7 @@ class SerafinHeader:
[shape = nb_nodes]
"""

def __init__(self, title="", format_type="SERAFIN ", lang="en", endian=">"):
def __init__(self, title="", format_type="SERAFIN ", lang=LANG, endian=">"):
"""
@param title <str>: title of the simulation
@param format_type <str>:
Expand Down
15 changes: 11 additions & 4 deletions xarray_selafin/xarray_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ def compute_duration_between_datetime(t0, time_serie):
return (time_serie - t0).astype("timedelta64[s]").astype(float)


def read_serafin(f):
resin = Serafin.Read(f, "en")
def read_serafin(f, lang):
resin = Serafin.Read(f, lang)
resin.__enter__()
resin.read_header()
resin.get_time()
Expand Down Expand Up @@ -72,6 +72,10 @@ def write_serafin(fout, ds):
slf_header.date = (1900, 1, 1, 0, 0, 0)

# Variables
try:
slf_header.language = ds.attrs["language"]
except KeyError:
slf_header.language = Serafin.LANG
for var in ds.data_vars:
try:
name, unit = ds.attrs["variables"][var]
Expand Down Expand Up @@ -139,7 +143,7 @@ def write_serafin(fout, ds):
except KeyError:
slf_header.build_params()

resout = Serafin.Write(fout, "en", overwrite=True)
resout = Serafin.Write(fout, slf_header.language, overwrite=True)
resout.__enter__()
resout.write_header(slf_header)

Expand Down Expand Up @@ -256,10 +260,12 @@ def open_dataset(
*,
drop_variables=None,
decode_times=True,
# Below are custom arguments
lazy_loading=True,
lang=Serafin.LANG,
):
# Initialize SELAFIN reader
slf = read_serafin(filename_or_obj)
slf = read_serafin(filename_or_obj, lang)
is_2d = slf.header.is_2d

# Prepare dimensions, coordinates, and data variables
Expand Down Expand Up @@ -307,6 +313,7 @@ def open_dataset(
ds = xr.Dataset(data_vars=data_vars, coords=coords)

ds.attrs["title"] = slf.header.title.decode(Serafin.SLF_EIT).strip()
ds.attrs["language"] = slf.header.language
ds.attrs["float_size"] = slf.header.float_size
ds.attrs["endian"] = slf.header.endian
ds.attrs["params"] = slf.header.params
Expand Down

0 comments on commit 742560b

Please sign in to comment.