Skip to content

Commit 8b35f0f

Browse files
document new features on readme (#123)
* new features to readme * Apply suggestion from @ktarbet --------- Co-authored-by: Karl Tarbet <ktarbet@users.noreply.github.com>
1 parent 261e9a6 commit 8b35f0f

2 files changed

Lines changed: 84 additions & 25 deletions

File tree

Readme.md

Lines changed: 45 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,15 @@ pip install hecdss
3333
### Regular TimeSeries Data
3434
- **Stored object in Python**: Regular Timeseries data is stored as 2 arrays of values and times/interval and startdate.
3535
- **Attributes**: The TimeSeries object has the following attributes:
36-
- `start_date`: The start date of the time series data.
37-
- `times`: The times of the time series data.
38-
- `values`: The values of the time series data.
39-
- `interval`: The interval of the time series data.
40-
- `data_type`: the dss data type ("PER-AVER","PER-CUM", "INST-VAL", "INST-CUM", .. )
41-
- `units`: The units of the time series data.
42-
- `id`: The Path of the time series data.
36+
- `start_date (str)`: The start date of the time series data.
37+
- `times (list[datetime])`: The times of the time series data.
38+
- `values (nd.nparray[float])`: The values of the time series data.
39+
- `quality (list[int])`: The quality flags of the time series data.
40+
- `notes (list[str])`: The notes of the time series data.
41+
- `interval (str)`: The interval of the time series data.
42+
- `data_type (str)`: the dss data type ("PER-AVER","PER-CUM", "INST-VAL", "INST-CUM", .. )
43+
- `units (str)`: The units of the time series data.
44+
- `id (str)`: The Path of the time series data (Format: "/A/B/C/D/E/F/").
4345

4446
```python
4547
# example working with time-series data
@@ -60,21 +62,22 @@ with HecDss(file_path) as dss:
6062
### Irregular TimeSeries Data
6163
- **Stored object in Python**: Irregular Timeseries data is stored as 2 arrays of values and times.
6264
- **Attributes**: The TimeSeries object has the following attributes:
63-
- `times`: The times of the time series data.
64-
- `values`: The values of the time series data.
65+
- `times (list[datetime])`: The times of the time series data.
66+
- `values (np.ndarray[float])`: The values of the time series data.
6567
- `units`: The units of the time series data.
66-
- `data_type`: the dss data type ('INST-VAL', 'INST-CUM')
67-
- `data`: The time series data.
68-
- `id`: The Path of the time series data.
68+
- `quality (list[int])`: The quality flags of the time series data.
69+
- `notes (list[str])`: The notes of the time series data.
70+
- `data_type (str)`: the dss data type ('INST-VAL', 'INST-CUM')
71+
- `id (str)`: The Path of the time series data (Format: "/A/B/C/D/E/F/").
6972

7073

7174
### Paired Data
7275
- **Stored object in Python**: Paired data stored as aa (x, y) where y could be stored as a 2d numpy matrix.
7376
- **Attributes**: The PairedData object has the following attributes:
74-
- `ordinates`: The x values of the paired data
75-
- `values`: y values of the paired data stored as 2d numpy array.
76-
- `labels`: The labels of the paired data.
77-
- `id`: The Path of the paired data.
77+
- `ordinates (np.ndarray)`: The x values of the paired data
78+
- `values (np.ndarray[float])`: y values of the paired data stored as 2d numpy array.
79+
- `labels (list[str])`: The labels of the paired data.
80+
- `id (str)`: The Path of the paired data.
7881

7982
### Gridded Data
8083
- **Stored object in Python**: A 2d matrix stored as a numpy 2d object.
@@ -87,6 +90,7 @@ with HecDss(file_path) as dss:
8790
- * Supports storing and reading arrays of integers, floats, or doubles.
8891
- * Arrays are managed with ArrayContainer
8992

93+
9094
```python
9195
# Example working with an array
9296
with HecDss("my-dss-file.dss") as dss:
@@ -98,8 +102,33 @@ with HecDss(file_path) as dss:
98102
read_array = dss.get(array_ints.id)
99103
```
100104

105+
## CSV Functionality
106+
107+
### Time Series
108+
The `rts.to_csv` and `RegularTimeSeries.read_csv` methods can be used to convert time series data to `.csv` format. This can also be utilized alongside `pandas` methods to convert time series data to pandas DataFrames.
101109

110+
```python
111+
# Round trip CSV example with RegularTimeSeries and Pandas DataFrame
112+
import pandas as pd
113+
114+
file_path: str = "my-dss-file.dss"
115+
with HecDss(file_path) as dss:
116+
data_path: str = "/example/data/////"
117+
rts: RegularTimeSeries = dss.get(data_path)
118+
119+
csv_out: str = "example.csv"
120+
rts.to_csv(csv_out) # RegularTimeSeries -> CSV
121+
122+
df: pd.DataFrame = pd.read_csv(csv_out) # CSV -> DataFrame
123+
df_csv_path: str = "df_example.csv"
124+
# Index needs to be false for round-trip support
125+
df.to_csv(df_csv_path, index=False) # DataFrame -> CSV
126+
127+
with HecDss(file_path) as dss:
128+
RegularTimeSeries.read_csv(df_csv_path) # CSV -> RegularTimeSeries
129+
```
102130

131+
Additionally, `IrregularTimeSeries` and `PairedData` both have equivalent functionality with `.csv` conversion.
103132

104133

105134
### This libray is built using the API for future versions of HEC-DSS
@@ -153,7 +182,6 @@ These are the driving design ideas and goals of the hec-dss-python project (subj
153182
| hec_dss_native.py | native binding layer | isolate interactions with low level library(if performance is an issue this Ctypes layer can be replaced ) |
154183
| hec_dss.py | Programmer entry point ; Python API | Hides interactions with hec_dss_native, seek to be simple user experience |
155184
|catalog.py|manage list of DSS objects (catalog) | create condensed catalog perspective |
156-
|Pandas_Series_Utilities.py [future](https://github.com/HydrologicEngineeringCenter/hec-dss-python/issues/8) |NumPy/pandas support | provide features such as dataframes, separate from hec-dss.py; can be developed by different/parallel developers |
157185
|Easy to get started |nothing to install, just copy python files and shared library | require minimal privileges to install |
158186

159187

src/hecdss/regular_timeseries.py

Lines changed: 39 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,9 @@ def __init__(self):
2626
self.id = ""
2727
self.location_info = None
2828

29-
def add_data_point(self, date: datetime, value: float, flag: int = None, note: str = None):
29+
def add_data_point(
30+
self, date: datetime, value: float, flag: int = None, note: str = None
31+
):
3032
"""
3133
Adds a data point to the time series.
3234
@@ -117,6 +119,7 @@ def to_csv(self, file_path: str) -> None:
117119
file_path (str): The path to the .csv file where the data will be exported.
118120
"""
119121
from .dss_csv import timeseries_to_csv
122+
120123
timeseries_to_csv(self, file_path)
121124
print(f"Wrote RegularTimeSeries to .csv file at {file_path}.")
122125

@@ -184,9 +187,17 @@ def _interval_to_times(self, new_interval):
184187
Args:
185188
new_interval (int): The new interval in seconds.
186189
"""
187-
def is_leap(y): return y % 4 == 0 and y % 100 != 0 or y % 400 == 0
188-
def last_day(y, m): return 31 if m in (1, 3, 5, 7, 8, 10, 12) else 30 if m in (
189-
4, 6, 9, 11) else 29 if is_leap(y) else 28
190+
191+
def is_leap(y):
192+
return y % 4 == 0 and y % 100 != 0 or y % 400 == 0
193+
194+
def last_day(y, m):
195+
return (
196+
31
197+
if m in (1, 3, 5, 7, 8, 10, 12)
198+
else 30 if m in (4, 6, 9, 11) else 29 if is_leap(y) else 28
199+
)
200+
190201
if type(self.start_date) == datetime:
191202
tz = ZoneInfo(self.time_zone_name) if self.time_zone_name else None
192203
first_time = self.start_date.replace(microsecond=0, tzinfo=tz)
@@ -238,12 +249,16 @@ def _generate_times(self):
238249
"""
239250
Generates times for the time series based on the interval and start date.
240251
"""
241-
if (len(self.times) > 0 and self.start_date == ""):
252+
if len(self.times) > 0 and self.start_date == "":
242253
self.start_date = self.times[0]
243254

244-
x = [self._get_interval_times(), self._get_interval_path(), self._get_interval_interval()]
255+
x = [
256+
self._get_interval_times(),
257+
self._get_interval_path(),
258+
self._get_interval_interval(),
259+
]
245260
x = [i for i in x if i != "empty"]
246-
if (not all(i == x[0] for i in x)):
261+
if not all(i == x[0] for i in x):
247262
raise ValueError("inconsistent interval within arguments")
248263
elif len(x) != 3 and len(x) != 0:
249264
self._interval_to_interval(x[0])
@@ -262,17 +277,33 @@ def read_csv(file_path: str) -> "RegularTimeSeries":
262277
RegularTimeSeries: A new instance of RegularTimeSeries populated with the data from the .csv file.
263278
"""
264279
from .dss_csv import timeseries_read_csv
280+
265281
return timeseries_read_csv(RegularTimeSeries, file_path)
266282

267283
@staticmethod
268-
def create(values, times=[], quality=[], notes=[], units="", data_type="", interval="", start_date="", time_granularity_seconds=1, julian_base_date=0, time_zone_name="", path=None, location_info=None):
284+
def create(
285+
values,
286+
times=[],
287+
quality=[],
288+
notes=[],
289+
units="",
290+
data_type="",
291+
interval="",
292+
start_date="",
293+
time_granularity_seconds=1,
294+
julian_base_date=0,
295+
time_zone_name="",
296+
path=None,
297+
location_info=None,
298+
):
269299
"""
270300
Creates a new instance of the RegularTimeSeries class with the specified parameters.
271301
272302
Args:
273303
values (list): List of data values.
274304
times (list, optional): List of time values. Defaults to [].
275305
quality (list, optional): List of quality values. Defaults to [].
306+
notes (list[str]): The notes of the time series data.
276307
units (str, optional): Units of the data. Defaults to "".
277308
data_type (str, optional): Type of the data. Defaults to "".
278309
interval (str, optional): Interval of the time series. Defaults to "".

0 commit comments

Comments
 (0)