Skip to content

Commit 09e3cc4

Browse files
authored
TS Pattern (#87)
* ts-pattern test * finalize tests and TS-pattern support for regular timeseries
1 parent b75ab16 commit 09e3cc4

7 files changed

Lines changed: 46 additions & 6 deletions

File tree

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[tool.poetry]
22
name = "hec-dss-python"
3-
version = "0.1.21"
3+
version = "0.1.22"
44
description = "Python wrapper for the HEC-DSS file database C library."
55
authors = ["Hydrologic Engineering Center"]
66
license = "MIT"

setup.cfg

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[metadata]
22
name = hecdss
3-
version = 0.1.21
3+
version = 0.1.22
44
author = Hydrologic Engineering Center
55
author_email =hec.dss@usace.army.mil
66
description = Python wrapper for the HEC-DSS file database C library.
@@ -20,6 +20,7 @@ python_requires = >=3.8
2020
include_package_data = True
2121
install_requires =
2222
numpy
23+
tzdata
2324

2425
[options.packages.find]
2526
where=src

src/hecdss/catalog.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from .record_type import RecordType
22
from .dsspath import DssPath
33
from datetime import datetime
4+
import re
45

56
class Catalog:
67
"""manage list of objects inside a DSS database"""
@@ -47,7 +48,7 @@ def __create_condensed_catalog(self):
4748
cleanPath = str(path.path_without_date())
4849
raw_paths[cleanPath.lower()] = rawPath
4950
self.recordTypeDict[cleanPath.lower()] = recordType
50-
if(path.D != "TS-Pattern"):
51+
if re.match(r"^\d{2}[A-Za-z]{3}\d{4}$", path.D): # Check if path.D matches the format 'DDMMMYYYY'
5152
tsRecords = self.timeSeriesDictNoDates.setdefault(cleanPath.lower(), [])
5253
t = datetime.strptime(path.D,"%d%b%Y")
5354
tsRecords.append(t)

src/hecdss/download_hecdss.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ def download_and_unzip(url, zip_file, destination_dir):
3636
print(f"Failed to download zip file. Status code: {response.status_code}")
3737

3838
base_url = "https://www.hec.usace.army.mil/nexus/repository/maven-public/mil/army/usace/hec/hecdss/"
39-
version = "7-IU-10"
39+
version = "7-IU-16"
4040

4141
destination_dir = Path(__file__).parent.joinpath("lib")
4242
zip_url = f"{base_url}{version}-win-x86_64/hecdss-{version}-win-x86_64.zip"

src/hecdss/hecdss.py

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,11 @@ def get(self, pathname: str, startdatetime=None, enddatetime=None, trim=False):
105105
varies: RegularTimeSeries, PairedData, Grid, or Array.
106106
"""
107107
if type == RecordType.RegularTimeSeries or type == RecordType.IrregularTimeSeries:
108-
new_pathname = DssPath(pathname).path_without_date().__str__()
108+
new_pathname = pathname
109+
if(DssPath(pathname).D.lower() != "ts-pattern"):
110+
new_pathname = DssPath(pathname).path_without_date().__str__()
111+
elif type == RecordType.IrregularTimeSeries:
112+
raise ValueError("ts-pattern is not fully supported for irregular time series")
109113
ts = self._get_timeseries(new_pathname, startdatetime, enddatetime, trim)
110114
return ts
111115
elif type == RecordType.PairedData:
@@ -315,7 +319,7 @@ def _get_julian_time_range(self, pathname, boolFullSet):
315319
firstSeconds = [0]
316320
lastValidJulian = [0]
317321
lastSeconds = [0]
318-
self._native.hec_dss_tsGetDateTimeRange(
322+
status = self._native.hec_dss_tsGetDateTimeRange(
319323
pathname,
320324
boolFullSet,
321325
firstValidJulian,
@@ -464,8 +468,17 @@ def _get_timeseries(self, pathname, startDateTime, endDateTime, trim):
464468
timeZoneName = timeZoneName[0]
465469
if(timeZoneName):
466470
new_times = [i.replace(tzinfo=ZoneInfo(timeZoneName)) for i in new_times]
471+
elif (DssPath(pathname).D.lower() == "ts-pattern"):
472+
new_times = []
473+
start_date = _startDateTime - timedelta(seconds=interval_seconds)
474+
467475
location_info = self._get_location_info(pathname)
468476
ts = ts.create(values=values, times=new_times, quality=quality, units=units, data_type=data_type, start_date=start_date, time_granularity_seconds=time_granularity_seconds, julian_base_date=julian_base_date, time_zone_name=timeZoneName, path=pathname, location_info=location_info)
477+
478+
if (DssPath(pathname).D.lower() == "ts-pattern"):
479+
new_interval = ts._get_interval_path()
480+
ts._interval_to_times(new_interval)
481+
469482
return ts
470483

471484
def _get_location_info(self, pathname: str):
@@ -561,6 +574,8 @@ def put(self, container) -> int:
561574
self._catalog = None
562575
elif type(container) is IrregularTimeSeries:
563576
its = container
577+
if (DssPath(its.id).D.lower() == "ts-pattern"):
578+
raise ValueError("ts-pattern is not fully supported for irregular time series")
564579
# def hec_dss_tsStoreRegular(dss, pathname, startDate, startTime, valueArray, qualityArray,
565580
# saveAsFloat, units, type):
566581
start_date_base = (datetime(1900, 1, 1)+timedelta(days=its.julian_base_date))

tests/data/Depth_Area_01.dss

2.01 MB
Binary file not shown.

tests/test_basics.py

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,29 @@ def test_delete_range(self):
209209
dss.delete(path, False, t1, t2)
210210
assert (not("//SACRAMENTO/PRECIP-INC/01Jan1882/1Day/OBS/" in dss.get_catalog().uncondensed_paths))
211211

212+
def test_Read_TS_Pattern_Regular(self):
213+
with HecDss(self.test_files.get_copy("Depth_Area_01.dss")) as dss:
214+
path = "//010010-B/FLOW-UNIT GRAPH/TS-Pattern/5Minute/DAA:Depth-Area 01>010005-C/"
215+
tsc = dss.get(path)
216+
assert(len(tsc.values) > 0)
217+
218+
def test_Write_TS_Pattern_Regular(self):
219+
with HecDss(self.test_files.get_copy("Depth_Area_01.dss")) as dss:
220+
path = "//010010-B/FLOW-UNIT GRAPH/TS-Pattern/5Minute/DAA:Depth-Area 01>010005-C/"
221+
tsc = dss.get(path)
222+
tsc.id = "//010010-B/FLOW-UNIT GRAPH/TS-Pattern/5Minute/DAA:Depth-Area 01>010005-C-modified2/"
223+
tsc.times = [i.replace(year=2023) for i in tsc.times]
224+
tsc.start_date = tsc.start_date.replace(year=2023)
225+
dss.put(tsc)
226+
tsc2 = dss.get(tsc.id)
227+
assert(len(tsc2.values) > 0)
228+
229+
def test_path_empty_parts(self):
230+
with HecDss(self.test_files.get_copy("Depth_Area_01.dss")) as dss:
231+
path = "//010020-R/STORAGE-FLOW///DAA:Depth-Area 01>010025-R/"
232+
tsc = dss.get(path)
233+
assert (len(tsc.values) > 0)
234+
212235
if __name__ == "__main__":
213236
unittest.main()
214237
# test_catalog()

0 commit comments

Comments
 (0)