Skip to content

Commit

Permalink
datetime.timezone support in write_components() (#359)
Browse files Browse the repository at this point in the history
* added support for datetime timezones, including test

* updated whatsnew
  • Loading branch information
veenstrajelmer authored Oct 30, 2024
1 parent 6fdef68 commit 82715a3
Show file tree
Hide file tree
Showing 4 changed files with 68 additions and 1 deletion.
6 changes: 6 additions & 0 deletions docs/whats-new.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
# What's new

## UNRELEASED

### Feat
- `datetime.timezone` support in `hatyan.write_components()` to support components from ddlpy timeseries in [#359](https://github.com/Deltares/hatyan/pull/359)


## 2.9.0 (2024-09-11)

### Feat
Expand Down
14 changes: 13 additions & 1 deletion hatyan/components.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import matplotlib.pyplot as plt
from matplotlib.ticker import MaxNLocator
import datetime as dt
import numpy as np
import pandas as pd
import pytz
Expand Down Expand Up @@ -107,6 +108,16 @@ def plot_components(comp, comp_allperiods=None, comp_validation=None, sort_freqs
return fig, axs


def _get_tzone_minutes(tzone):
if isinstance(tzone, dt.timezone):
tzone_min = int(tzone.utcoffset(None).seconds/60)
elif isinstance(tzone, pytz._FixedOffset):
tzone_min = tzone._minutes
else:
raise NotImplementedError(f"tzone of type {type(tzone)} is not yet supported.")
return tzone_min


def write_components(comp, filename):
"""
Writes the provided analysis results to a file
Expand Down Expand Up @@ -153,7 +164,8 @@ def write_components(comp, filename):
tzone = metadata.pop('tzone')
if tzone is None:
raise ValueError("write_components() encountered tzone=None in components dataframe, not allowed.")
tzone_min = tzone._minutes

tzone_min = _get_tzone_minutes(tzone)
tstart_str = tstart.strftime("%Y%m%d %H%M")
tstop_str = tstop.strftime("%Y%m%d %H%M")

Expand Down
23 changes: 23 additions & 0 deletions tests/test_components.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,13 @@

import os
import pytest
import pandas as pd
import pytz
import datetime as dt
import numpy as np
import hatyan
from hatyan.metadata import metadata_from_obj
from hatyan.components import _get_tzone_minutes

dir_tests = os.path.dirname(__file__) #F9 doesnt work, only F5 (F5 also only method to reload external definition scripts)
dir_testdata = os.path.join(dir_tests,'data_unitsystemtests')
Expand Down Expand Up @@ -167,3 +171,22 @@ def test_merge_componentgroups_comparesettings():
comp_fromfile_fake = comp_fromfile.copy()
comp_fromfile_fake.attrs["source"] = 'foreman'
_ = hatyan.merge_componentgroups(comp_main=comp_fromfile, comp_sec=comp_fromfile_fake.loc[['SA','SM']])


@pytest.mark.unittest
def test_get_tzone_minutes():
# relevant for ddlpy timeseries
tstart = pd.Timestamp("2020-01-01 00:00:00 +01:00")
tzone_min = _get_tzone_minutes(tstart.tz)
assert isinstance(tstart.tz, dt.timezone)
assert tzone_min == 60

# hatyan dia timeseries
tstart = pd.Timestamp("2020-01-01 00:00:00", tz=pytz.FixedOffset(60))
tzone_min = _get_tzone_minutes(tstart.tz)
assert tzone_min == 60

tstart = pd.Timestamp("2020-01-01 00:00:00")
with pytest.raises(NotImplementedError) as e:
_get_tzone_minutes(tstart.tz)
assert "tzone of type <class 'NoneType'> is not yet supported" in str(e.value)
26 changes: 26 additions & 0 deletions tests/test_ddlpy_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,29 @@ def test_convert_hwlwstr2num(locations):

assert "HWLWcode" in ts_measwlHWLW.columns
assert np.array_equal(ts_measwlHWLW["HWLWcode"].values, hwlwcode_expected)


@pytest.mark.systemtest
def test_ddlpy_to_components(locations):
start_dt = "2022-01-01 00:00:00 +01:00"
end_dt = "2022-03-31 23:50:00 +01:00"

bool_grootheid = locations['Grootheid.Code'].isin(['WATHTE']) # measured waterlevels (not astro)
bool_groepering = locations['Groepering.Code'].isin(['NVT']) # timeseries (not extremes)
bool_hoedanigheid = locations['Hoedanigheid.Code'].isin(['NAP']) # vertical reference, only NAP
locs_ddl = locations.loc[bool_grootheid & bool_groepering & bool_hoedanigheid]

donar_loccode = "VLISSGN"
locs_ddl_one = locs_ddl.loc[donar_loccode]
ddl_df = ddlpy.measurements(locs_ddl_one, start_date=start_dt, end_date=end_dt)
df_meas = hatyan.ddlpy_to_hatyan(ddl_df)

ts_comp_nfac1_fualltimes0_xfac1_peryear0 = hatyan.analysis(ts=df_meas, const_list='month', nodalfactors=True, fu_alltimes=False, xfac=True, analysis_perperiod=False)

# TODO: manually setting attrs should not be necessary after improving hatyan.ddlpy_to_hatyan()
# https://github.com/Deltares/hatyan/issues/358
ts_comp_nfac1_fualltimes0_xfac1_peryear0.attrs['grootheid'] = "WATHTE"
ts_comp_nfac1_fualltimes0_xfac1_peryear0.attrs['eenheid'] = "cm"
ts_comp_nfac1_fualltimes0_xfac1_peryear0.attrs['vertref'] = "NAP"
ts_comp_nfac1_fualltimes0_xfac1_peryear0.attrs['station'] = donar_loccode
hatyan.write_components(ts_comp_nfac1_fualltimes0_xfac1_peryear0, filename='components_%.ana'%(donar_loccode))

0 comments on commit 82715a3

Please sign in to comment.