mpcaHydro 2.2.4__tar.gz → 2.2.5__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/PKG-INFO +1 -1
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/pyproject.toml +1 -1
- mpcahydro-2.2.5/tests/integration/test_data_manager.py +20 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/tests/integration/test_wiski.py +0 -2
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/tests/integration/test_wiski_integration.py +16 -26
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/tests/test_data_manager_functions.py +18 -18
- mpcahydro-2.2.4/tests/integration/test.json +0 -258
- mpcahydro-2.2.4/tests/integration/test.sqlite +0 -0
- mpcahydro-2.2.4/tests/integration/test_data_manager.py +0 -120
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/.gitattributes +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/.gitignore +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/README.md +0 -0
- /mpcahydro-2.2.4/src/mpcaHydro/wiski.py → /mpcahydro-2.2.5/src/mpcaHydro/WISKI.py +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/__init__.py +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/csg.py +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/data/EQUIS_PARAMETER_XREF.csv +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/data/WISKI_EQUIS_XREF.csv +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/data/WISKI_QUALITY_CODES.csv +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/data/outlet.duckdb +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/data/stations_EQUIS.gpkg +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/data/stations_wiski.gpkg +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/data/wiskiweb01.pca.state.mn.us.crt +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/equis.py +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/outlets.py +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/pywisk.py +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/reports.py +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/sql/analytics_tables.sql +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/sql/outlets_schema.sql +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/sql/schemas.sql +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/sql/staging_tables.sql +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/sql/views_analytics.sql +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/sql/views_outlets.sql +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/sql/views_reports.sql +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/sql_loader.py +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/swd.py +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/warehouse.py +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/warehouse_functions.py +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/src/mpcaHydro/xref.py +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/tests/integration/README.md +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/tests/integration/conftest.py +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/tests/integration/test_data_manager_integration.py +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/tests/integration/test_equis_integration.py +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/tests/integration/test_warehouse.py +0 -0
- {mpcahydro-2.2.4 → mpcahydro-2.2.5}/tests/pixi.toml +0 -0
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
|
|
2
|
+
from mpcaHydro import data_manager_functions as dmf
|
|
3
|
+
from mpcaHydro import wiski
|
|
4
|
+
|
|
5
|
+
station_ids = ['E67013001']
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
dmf.download_wiski_data(con,station_ids,start_year = 2010,)
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
station_ids = ['H67009001',
|
|
13
|
+
'H67012001',
|
|
14
|
+
'H67013001',
|
|
15
|
+
'H67014001',
|
|
16
|
+
'H67016001',
|
|
17
|
+
'H67014002',
|
|
18
|
+
'E67013001',
|
|
19
|
+
'W67036001',
|
|
20
|
+
'W67004001']
|
|
@@ -10,10 +10,6 @@ from unittest.mock import patch, MagicMock
|
|
|
10
10
|
import pytest
|
|
11
11
|
import pandas as pd
|
|
12
12
|
|
|
13
|
-
# Test ids
|
|
14
|
-
|
|
15
|
-
TS_ID_FLOW = 169928010 # Example flow ts_id for station H67014001
|
|
16
|
-
|
|
17
13
|
|
|
18
14
|
# Check if warehouse module can be imported (requires data files)
|
|
19
15
|
try:
|
|
@@ -98,11 +94,18 @@ class TestWiskiDownload:
|
|
|
98
94
|
"""Test that get_ts returns timeseries data (requires network)."""
|
|
99
95
|
from mpcaHydro import pywisk
|
|
100
96
|
|
|
101
|
-
|
|
97
|
+
# First get a valid ts_id
|
|
98
|
+
station_ids = ['H67014001']
|
|
99
|
+
df_ts = pywisk.get_ts_ids(station_nos=station_ids, parametertype_id='11500') # Flow
|
|
102
100
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
101
|
+
if not df_ts.empty:
|
|
102
|
+
ts_id = df_ts['ts_id'].iloc[0]
|
|
103
|
+
df = pywisk.get_ts(ts_id, start_date='2020-01-01', end_date='2020-01-31')
|
|
104
|
+
|
|
105
|
+
assert isinstance(df, pd.DataFrame)
|
|
106
|
+
if not df.empty:
|
|
107
|
+
assert 'Timestamp' in df.columns
|
|
108
|
+
assert 'Value' in df.columns
|
|
106
109
|
|
|
107
110
|
|
|
108
111
|
class TestWiskiDataWithMock:
|
|
@@ -111,40 +114,27 @@ class TestWiskiDataWithMock:
|
|
|
111
114
|
@requires_warehouse
|
|
112
115
|
def test_download_with_mock_data(self):
|
|
113
116
|
"""Test WISKI download flow with mocked service."""
|
|
114
|
-
from mpcaHydro import
|
|
117
|
+
from mpcaHydro import data_manager_functions as dmf
|
|
115
118
|
from mpcaHydro import warehouse
|
|
116
119
|
|
|
117
120
|
# Create mock data that mimics WISKI download format
|
|
118
|
-
['Timestamp', 'Value', 'Quality Code', 'Quality Code Name',
|
|
119
|
-
'ts_unitsymbol', 'ts_name', 'ts_id', 'station_no', 'station_name',
|
|
120
|
-
'station_latitude', 'station_longitude', 'parametertype_id',
|
|
121
|
-
'parametertype_name', 'stationparameter_no', 'stationparameter_name',
|
|
122
|
-
'wplmn_flag']
|
|
123
121
|
mock_wiski_data = pd.DataFrame({
|
|
122
|
+
'station_no': ['H67014001', 'H67014001'],
|
|
124
123
|
'Timestamp': ['2020-01-01 00:00', '2020-01-01 01:00'],
|
|
125
124
|
'Value': [100.0, 105.0],
|
|
126
125
|
'Quality Code': [1, 1],
|
|
127
|
-
'Quality Code Name': ['Good', 'Good'],
|
|
128
126
|
'ts_unitsymbol': ['cfs', 'cfs'],
|
|
129
|
-
'ts_name': ['Discharge', 'Discharge'],
|
|
130
|
-
'ts_id': [TS_ID_FLOW, TS_ID_FLOW],
|
|
131
|
-
'station_no': ['H67014001', 'H67014001'],
|
|
132
|
-
'station_name': ['Station H67014001', 'Station H67014001'],
|
|
133
|
-
'station_latitude': [46.0, 46.0],
|
|
134
|
-
'station_longitude': [-94.0, -94.0],
|
|
135
127
|
'parametertype_id': ['11500', '11500'],
|
|
136
128
|
'parametertype_name': ['Discharge', 'Discharge'],
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
'wplmn_flag': [0, 0]})
|
|
140
|
-
|
|
129
|
+
})
|
|
130
|
+
|
|
141
131
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
142
132
|
db_path = Path(tmpdir) / 'test.duckdb'
|
|
143
133
|
warehouse.init_db(db_path.as_posix(), reset=True)
|
|
144
134
|
|
|
145
135
|
with warehouse.connect(db_path.as_posix(), read_only=False) as con:
|
|
146
136
|
# Load mock data directly
|
|
147
|
-
warehouse.
|
|
137
|
+
warehouse.load_df_to_table(con, mock_wiski_data, 'staging.wiski')
|
|
148
138
|
|
|
149
139
|
# Verify data loaded
|
|
150
140
|
result = con.execute("SELECT COUNT(*) FROM staging.wiski").fetchone()[0]
|
|
@@ -13,14 +13,14 @@ class TestConstants:
|
|
|
13
13
|
|
|
14
14
|
def test_agg_defaults(self):
|
|
15
15
|
"""Test aggregation defaults are properly defined."""
|
|
16
|
-
from mpcaHydro.
|
|
16
|
+
from mpcaHydro.data_manager_functions import AGG_DEFAULTS
|
|
17
17
|
assert 'cfs' in AGG_DEFAULTS
|
|
18
18
|
assert AGG_DEFAULTS['cfs'] == 'mean'
|
|
19
19
|
assert AGG_DEFAULTS['lb'] == 'sum'
|
|
20
20
|
|
|
21
21
|
def test_unit_defaults(self):
|
|
22
22
|
"""Test unit defaults are properly defined."""
|
|
23
|
-
from mpcaHydro.
|
|
23
|
+
from mpcaHydro.data_manager_functions import UNIT_DEFAULTS
|
|
24
24
|
assert 'Q' in UNIT_DEFAULTS
|
|
25
25
|
assert UNIT_DEFAULTS['Q'] == 'cfs'
|
|
26
26
|
assert UNIT_DEFAULTS['TSS'] == 'mg/l'
|
|
@@ -32,13 +32,13 @@ class TestGetDbPath:
|
|
|
32
32
|
|
|
33
33
|
def test_get_db_path_string(self):
|
|
34
34
|
"""Test get_db_path with string input."""
|
|
35
|
-
from mpcaHydro.
|
|
35
|
+
from mpcaHydro.data_manager_functions import get_db_path
|
|
36
36
|
result = get_db_path('/some/folder')
|
|
37
37
|
assert result == Path('/some/folder/observations.duckdb')
|
|
38
38
|
|
|
39
39
|
def test_get_db_path_path(self):
|
|
40
40
|
"""Test get_db_path with Path input."""
|
|
41
|
-
from mpcaHydro.
|
|
41
|
+
from mpcaHydro.data_manager_functions import get_db_path
|
|
42
42
|
result = get_db_path(Path('/another/folder'))
|
|
43
43
|
assert result == Path('/another/folder/observations.duckdb')
|
|
44
44
|
|
|
@@ -48,14 +48,14 @@ class TestValidation:
|
|
|
48
48
|
|
|
49
49
|
def test_valid_constituents_in_unit_defaults(self):
|
|
50
50
|
"""Test that key constituents have unit defaults defined."""
|
|
51
|
-
from mpcaHydro.
|
|
51
|
+
from mpcaHydro.data_manager_functions import UNIT_DEFAULTS
|
|
52
52
|
expected_constituents = ['Q', 'TSS', 'TP', 'OP', 'TKN', 'N', 'WT']
|
|
53
53
|
for const in expected_constituents:
|
|
54
54
|
assert const in UNIT_DEFAULTS, f"Constituent {const} missing from UNIT_DEFAULTS"
|
|
55
55
|
|
|
56
56
|
def test_valid_units_in_agg_defaults(self):
|
|
57
57
|
"""Test that common units have aggregation defaults defined."""
|
|
58
|
-
from mpcaHydro.
|
|
58
|
+
from mpcaHydro.data_manager_functions import AGG_DEFAULTS
|
|
59
59
|
expected_units = ['mg/l', 'lb', 'cfs', 'degf']
|
|
60
60
|
for unit in expected_units:
|
|
61
61
|
assert unit in AGG_DEFAULTS, f"Unit {unit} missing from AGG_DEFAULTS"
|
|
@@ -66,14 +66,14 @@ class TestDataManagerFunctionsInterface:
|
|
|
66
66
|
|
|
67
67
|
def test_get_db_path_returns_path(self):
|
|
68
68
|
"""Test get_db_path returns a Path object."""
|
|
69
|
-
from mpcaHydro.
|
|
69
|
+
from mpcaHydro.data_manager_functions import get_db_path
|
|
70
70
|
result = get_db_path('/test/path')
|
|
71
71
|
assert isinstance(result, Path)
|
|
72
72
|
assert result.name == 'observations.duckdb'
|
|
73
73
|
|
|
74
74
|
def test_constants_are_dicts(self):
|
|
75
75
|
"""Test constants are dictionaries."""
|
|
76
|
-
from mpcaHydro.
|
|
76
|
+
from mpcaHydro.data_manager_functions import AGG_DEFAULTS, UNIT_DEFAULTS
|
|
77
77
|
assert isinstance(AGG_DEFAULTS, dict)
|
|
78
78
|
assert isinstance(UNIT_DEFAULTS, dict)
|
|
79
79
|
|
|
@@ -83,12 +83,12 @@ class TestDropStationFunctions:
|
|
|
83
83
|
|
|
84
84
|
def test_drop_wiski_station_data_exists(self):
|
|
85
85
|
"""Test drop_wiski_station_data function exists and is callable."""
|
|
86
|
-
from mpcaHydro.
|
|
86
|
+
from mpcaHydro.data_manager_functions import drop_wiski_station_data
|
|
87
87
|
assert callable(drop_wiski_station_data)
|
|
88
88
|
|
|
89
89
|
def test_drop_equis_station_data_exists(self):
|
|
90
90
|
"""Test drop_equis_station_data function exists and is callable."""
|
|
91
|
-
from mpcaHydro.
|
|
91
|
+
from mpcaHydro.data_manager_functions import drop_equis_station_data
|
|
92
92
|
assert callable(drop_equis_station_data)
|
|
93
93
|
|
|
94
94
|
|
|
@@ -98,7 +98,7 @@ class TestDownloadFunctionsReplaceParameter:
|
|
|
98
98
|
def test_download_wiski_data_has_replace_param(self):
|
|
99
99
|
"""Test download_wiski_data accepts replace parameter."""
|
|
100
100
|
import inspect
|
|
101
|
-
from mpcaHydro.
|
|
101
|
+
from mpcaHydro.data_manager_functions import download_wiski_data
|
|
102
102
|
sig = inspect.signature(download_wiski_data)
|
|
103
103
|
assert 'replace' in sig.parameters
|
|
104
104
|
assert sig.parameters['replace'].default is False
|
|
@@ -106,7 +106,7 @@ class TestDownloadFunctionsReplaceParameter:
|
|
|
106
106
|
def test_download_equis_data_has_replace_param(self):
|
|
107
107
|
"""Test download_equis_data accepts replace parameter."""
|
|
108
108
|
import inspect
|
|
109
|
-
from mpcaHydro.
|
|
109
|
+
from mpcaHydro.data_manager_functions import download_equis_data
|
|
110
110
|
sig = inspect.signature(download_equis_data)
|
|
111
111
|
assert 'replace' in sig.parameters
|
|
112
112
|
assert sig.parameters['replace'].default is False
|
|
@@ -117,12 +117,12 @@ class TestDataManagerWrapper:
|
|
|
117
117
|
|
|
118
118
|
def test_wrapper_exists(self):
|
|
119
119
|
"""Test DataManagerWrapper class exists."""
|
|
120
|
-
from mpcaHydro.
|
|
120
|
+
from mpcaHydro.data_manager_functions import DataManagerWrapper
|
|
121
121
|
assert DataManagerWrapper is not None
|
|
122
122
|
|
|
123
123
|
def test_wrapper_can_be_instantiated(self):
|
|
124
124
|
"""Test DataManagerWrapper can be instantiated with a path."""
|
|
125
|
-
from mpcaHydro.
|
|
125
|
+
from mpcaHydro.data_manager_functions import DataManagerWrapper
|
|
126
126
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
127
127
|
db_path = Path(tmpdir) / 'test.duckdb'
|
|
128
128
|
wrapper = DataManagerWrapper(db_path)
|
|
@@ -130,7 +130,7 @@ class TestDataManagerWrapper:
|
|
|
130
130
|
|
|
131
131
|
def test_wrapper_has_expected_methods(self):
|
|
132
132
|
"""Test DataManagerWrapper has all expected methods."""
|
|
133
|
-
from mpcaHydro.
|
|
133
|
+
from mpcaHydro.data_manager_functions import DataManagerWrapper
|
|
134
134
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
135
135
|
db_path = Path(tmpdir) / 'test.duckdb'
|
|
136
136
|
wrapper = DataManagerWrapper(db_path)
|
|
@@ -163,7 +163,7 @@ class TestDataManagerWrapper:
|
|
|
163
163
|
def test_wrapper_download_methods_have_replace_param(self):
|
|
164
164
|
"""Test wrapper download methods have replace parameter."""
|
|
165
165
|
import inspect
|
|
166
|
-
from mpcaHydro.
|
|
166
|
+
from mpcaHydro.data_manager_functions import DataManagerWrapper
|
|
167
167
|
with tempfile.TemporaryDirectory() as tmpdir:
|
|
168
168
|
db_path = Path(tmpdir) / 'test.duckdb'
|
|
169
169
|
wrapper = DataManagerWrapper(db_path)
|
|
@@ -180,13 +180,13 @@ class TestModuleExports:
|
|
|
180
180
|
|
|
181
181
|
def test_drop_functions_exported(self):
|
|
182
182
|
"""Test drop functions are exported from data_manager_functions."""
|
|
183
|
-
from mpcaHydro.
|
|
183
|
+
from mpcaHydro.data_manager_functions import drop_wiski_station_data, drop_equis_station_data
|
|
184
184
|
assert callable(drop_wiski_station_data)
|
|
185
185
|
assert callable(drop_equis_station_data)
|
|
186
186
|
|
|
187
187
|
def test_wrapper_exported(self):
|
|
188
188
|
"""Test DataManagerWrapper is exported from data_manager_functions."""
|
|
189
|
-
from mpcaHydro.
|
|
189
|
+
from mpcaHydro.data_manager_functions import DataManagerWrapper
|
|
190
190
|
assert DataManagerWrapper is not None
|
|
191
191
|
|
|
192
192
|
|
|
@@ -1,258 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"repository_name": "Clearwater",
|
|
3
|
-
"locations": [
|
|
4
|
-
{
|
|
5
|
-
"location_id": 1,
|
|
6
|
-
"location_name": "Clearwater Outlet",
|
|
7
|
-
"repository_name": "Clearwater",
|
|
8
|
-
"reach_ids": [
|
|
9
|
-
650
|
|
10
|
-
],
|
|
11
|
-
"upstream_reach_ids": [
|
|
12
|
-
649,
|
|
13
|
-
648
|
|
14
|
-
],
|
|
15
|
-
"flow_station_ids": [
|
|
16
|
-
"E66050001"
|
|
17
|
-
],
|
|
18
|
-
"stations": [
|
|
19
|
-
{
|
|
20
|
-
"station_id": "E66050001",
|
|
21
|
-
"station_origin": "wiski",
|
|
22
|
-
"repository_name": "Clearwater",
|
|
23
|
-
"true_reach_id": 650,
|
|
24
|
-
"observations": [
|
|
25
|
-
{
|
|
26
|
-
"constituent": "Q",
|
|
27
|
-
"start_year": 2000,
|
|
28
|
-
"end_year": 2023,
|
|
29
|
-
"avg_samples_per_year": 365.0,
|
|
30
|
-
"median_samples_per_year": 365.0,
|
|
31
|
-
"years_with_data": 24,
|
|
32
|
-
"total_samples": 8760,
|
|
33
|
-
"metrics": [
|
|
34
|
-
{
|
|
35
|
-
"name": "NSE",
|
|
36
|
-
"target": 0.5,
|
|
37
|
-
"weight": 1.0,
|
|
38
|
-
"enabled": true
|
|
39
|
-
},
|
|
40
|
-
{
|
|
41
|
-
"name": "logNSE",
|
|
42
|
-
"target": 0.5,
|
|
43
|
-
"weight": 1.0,
|
|
44
|
-
"enabled": true
|
|
45
|
-
},
|
|
46
|
-
{
|
|
47
|
-
"name": "Pbias",
|
|
48
|
-
"target": 10.0,
|
|
49
|
-
"weight": 1.0,
|
|
50
|
-
"enabled": true
|
|
51
|
-
},
|
|
52
|
-
{
|
|
53
|
-
"name": "monthly_average",
|
|
54
|
-
"target": 15.0,
|
|
55
|
-
"weight": 0.5,
|
|
56
|
-
"enabled": true
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
"name": "annual_average",
|
|
60
|
-
"target": 15.0,
|
|
61
|
-
"weight": 0.5,
|
|
62
|
-
"enabled": true
|
|
63
|
-
},
|
|
64
|
-
{
|
|
65
|
-
"name": "percentile_10",
|
|
66
|
-
"target": 20.0,
|
|
67
|
-
"weight": 0.5,
|
|
68
|
-
"enabled": true
|
|
69
|
-
},
|
|
70
|
-
{
|
|
71
|
-
"name": "percentile_90",
|
|
72
|
-
"target": 20.0,
|
|
73
|
-
"weight": 0.5,
|
|
74
|
-
"enabled": true
|
|
75
|
-
},
|
|
76
|
-
{
|
|
77
|
-
"name": "seasonal_average",
|
|
78
|
-
"target": 15.0,
|
|
79
|
-
"weight": 0.5,
|
|
80
|
-
"enabled": true
|
|
81
|
-
}
|
|
82
|
-
],
|
|
83
|
-
"derived_from": []
|
|
84
|
-
}
|
|
85
|
-
],
|
|
86
|
-
"comments": "Primary flow monitoring station"
|
|
87
|
-
},
|
|
88
|
-
{
|
|
89
|
-
"station_id": "S002-118",
|
|
90
|
-
"station_origin": "equis",
|
|
91
|
-
"repository_name": "Clearwater",
|
|
92
|
-
"true_reach_id": 650,
|
|
93
|
-
"observations": [
|
|
94
|
-
{
|
|
95
|
-
"constituent": "TSS",
|
|
96
|
-
"start_year": 2005,
|
|
97
|
-
"end_year": 2020,
|
|
98
|
-
"avg_samples_per_year": 12.0,
|
|
99
|
-
"median_samples_per_year": 10.0,
|
|
100
|
-
"years_with_data": 15,
|
|
101
|
-
"total_samples": 180,
|
|
102
|
-
"metrics": [
|
|
103
|
-
{
|
|
104
|
-
"name": "Pbias",
|
|
105
|
-
"target": 25.0,
|
|
106
|
-
"weight": 1.0,
|
|
107
|
-
"enabled": true
|
|
108
|
-
},
|
|
109
|
-
{
|
|
110
|
-
"name": "monthly_average",
|
|
111
|
-
"target": 25.0,
|
|
112
|
-
"weight": 0.5,
|
|
113
|
-
"enabled": true
|
|
114
|
-
},
|
|
115
|
-
{
|
|
116
|
-
"name": "seasonal_average",
|
|
117
|
-
"target": 25.0,
|
|
118
|
-
"weight": 0.5,
|
|
119
|
-
"enabled": true
|
|
120
|
-
}
|
|
121
|
-
],
|
|
122
|
-
"derived_from": []
|
|
123
|
-
},
|
|
124
|
-
{
|
|
125
|
-
"constituent": "TP",
|
|
126
|
-
"start_year": 2005,
|
|
127
|
-
"end_year": 2020,
|
|
128
|
-
"avg_samples_per_year": 12.0,
|
|
129
|
-
"median_samples_per_year": 10.0,
|
|
130
|
-
"years_with_data": 15,
|
|
131
|
-
"total_samples": 180,
|
|
132
|
-
"metrics": [
|
|
133
|
-
{
|
|
134
|
-
"name": "Pbias",
|
|
135
|
-
"target": 25.0,
|
|
136
|
-
"weight": 1.0,
|
|
137
|
-
"enabled": true
|
|
138
|
-
},
|
|
139
|
-
{
|
|
140
|
-
"name": "monthly_average",
|
|
141
|
-
"target": 25.0,
|
|
142
|
-
"weight": 0.5,
|
|
143
|
-
"enabled": true
|
|
144
|
-
},
|
|
145
|
-
{
|
|
146
|
-
"name": "seasonal_average",
|
|
147
|
-
"target": 25.0,
|
|
148
|
-
"weight": 0.5,
|
|
149
|
-
"enabled": true
|
|
150
|
-
}
|
|
151
|
-
],
|
|
152
|
-
"derived_from": []
|
|
153
|
-
},
|
|
154
|
-
{
|
|
155
|
-
"constituent": "TP_load",
|
|
156
|
-
"start_year": null,
|
|
157
|
-
"end_year": null,
|
|
158
|
-
"avg_samples_per_year": null,
|
|
159
|
-
"median_samples_per_year": null,
|
|
160
|
-
"years_with_data": null,
|
|
161
|
-
"total_samples": null,
|
|
162
|
-
"metrics": [
|
|
163
|
-
{
|
|
164
|
-
"name": "Pbias",
|
|
165
|
-
"target": 30.0,
|
|
166
|
-
"weight": 1.0,
|
|
167
|
-
"enabled": true
|
|
168
|
-
}
|
|
169
|
-
],
|
|
170
|
-
"derived_from": [
|
|
171
|
-
"TP",
|
|
172
|
-
"Q"
|
|
173
|
-
]
|
|
174
|
-
}
|
|
175
|
-
],
|
|
176
|
-
"comments": "Water quality monitoring station"
|
|
177
|
-
}
|
|
178
|
-
],
|
|
179
|
-
"watershed_constraints": [
|
|
180
|
-
{
|
|
181
|
-
"constituent": "TP",
|
|
182
|
-
"target_rate": 0.5,
|
|
183
|
-
"min_rate": 0.2,
|
|
184
|
-
"max_rate": 1.0,
|
|
185
|
-
"landcover_constraints": [
|
|
186
|
-
{
|
|
187
|
-
"landcover_type": "forest",
|
|
188
|
-
"constituent": "TP",
|
|
189
|
-
"target_rate": 0.1,
|
|
190
|
-
"min_rate": 0.05,
|
|
191
|
-
"max_rate": 0.2
|
|
192
|
-
},
|
|
193
|
-
{
|
|
194
|
-
"landcover_type": "agricultural",
|
|
195
|
-
"constituent": "TP",
|
|
196
|
-
"target_rate": 0.8,
|
|
197
|
-
"min_rate": 0.4,
|
|
198
|
-
"max_rate": 1.5
|
|
199
|
-
}
|
|
200
|
-
]
|
|
201
|
-
}
|
|
202
|
-
],
|
|
203
|
-
"notes": "Example calibration location combining flow and water quality stations"
|
|
204
|
-
}
|
|
205
|
-
],
|
|
206
|
-
"default_metrics": [
|
|
207
|
-
{
|
|
208
|
-
"name": "NSE",
|
|
209
|
-
"target": 0.5,
|
|
210
|
-
"weight": 1.0,
|
|
211
|
-
"enabled": true
|
|
212
|
-
},
|
|
213
|
-
{
|
|
214
|
-
"name": "logNSE",
|
|
215
|
-
"target": 0.5,
|
|
216
|
-
"weight": 1.0,
|
|
217
|
-
"enabled": true
|
|
218
|
-
},
|
|
219
|
-
{
|
|
220
|
-
"name": "Pbias",
|
|
221
|
-
"target": 10.0,
|
|
222
|
-
"weight": 1.0,
|
|
223
|
-
"enabled": true
|
|
224
|
-
},
|
|
225
|
-
{
|
|
226
|
-
"name": "monthly_average",
|
|
227
|
-
"target": 15.0,
|
|
228
|
-
"weight": 0.5,
|
|
229
|
-
"enabled": true
|
|
230
|
-
},
|
|
231
|
-
{
|
|
232
|
-
"name": "annual_average",
|
|
233
|
-
"target": 15.0,
|
|
234
|
-
"weight": 0.5,
|
|
235
|
-
"enabled": true
|
|
236
|
-
},
|
|
237
|
-
{
|
|
238
|
-
"name": "percentile_10",
|
|
239
|
-
"target": 20.0,
|
|
240
|
-
"weight": 0.5,
|
|
241
|
-
"enabled": true
|
|
242
|
-
},
|
|
243
|
-
{
|
|
244
|
-
"name": "percentile_90",
|
|
245
|
-
"target": 20.0,
|
|
246
|
-
"weight": 0.5,
|
|
247
|
-
"enabled": true
|
|
248
|
-
},
|
|
249
|
-
{
|
|
250
|
-
"name": "seasonal_average",
|
|
251
|
-
"target": 15.0,
|
|
252
|
-
"weight": 0.5,
|
|
253
|
-
"enabled": true
|
|
254
|
-
}
|
|
255
|
-
],
|
|
256
|
-
"general_constraints": [],
|
|
257
|
-
"version": "1.0"
|
|
258
|
-
}
|
|
Binary file
|
|
@@ -1,120 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
from mpcaHydro import calibration_config, calibration_dataclasses, outlets, warehouse_functions as dmf
|
|
3
|
-
from mpcaHydro import wiski
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
dm = dmf.DataManagerWrapper('test_db.duckb',True)
|
|
7
|
-
station_ids = ['E67013001']
|
|
8
|
-
|
|
9
|
-
dm.download_wiski_data(station_ids)
|
|
10
|
-
|
|
11
|
-
dmf.download_wiski_data(con,station_ids,start_year = 2010,)
|
|
12
|
-
|
|
13
|
-
station_ids = ['H67012001']
|
|
14
|
-
dm.download_wiski_data(station_ids)
|
|
15
|
-
|
|
16
|
-
model_name = 'Rum'
|
|
17
|
-
config = calibration_config.create_config(model_name)
|
|
18
|
-
|
|
19
|
-
parts = {value: subdf.copy() for value, subdf in outlets.get_outlets_by_model(model_name).groupby('outlet_id') }
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
folder_path = Path('C:/Users/mfratki/Documents/Projects/Tests')
|
|
24
|
-
oracle_username = 'MFRATKI'
|
|
25
|
-
oracle_password = 'Deltat#3xg4duw1'
|
|
26
|
-
oracle_connection = equis.connect(oracle_username, oracle_password)
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
for model_name in Repository.valid_models():
|
|
30
|
-
wiski_stations = outlets.mapped_wiski_stations(model_name)
|
|
31
|
-
equis_stations = outlets.mapped_equis_stations(model_name)
|
|
32
|
-
wiski_info = wiski.info(wiski_stations)
|
|
33
|
-
equis_info = equis.info(equis_stations,oracle_connection)
|
|
34
|
-
stations = []
|
|
35
|
-
|
|
36
|
-
for station_id, info in wiski_info.groupby('station_id'):
|
|
37
|
-
observations = []
|
|
38
|
-
for constituent in info['constituent'].unique():
|
|
39
|
-
metrics = calibration_config.get_default_timeseries_metrics()
|
|
40
|
-
observations.append(calibration_dataclasses.Observation(constituent,
|
|
41
|
-
1996,
|
|
42
|
-
2024,
|
|
43
|
-
metrics = metrics))
|
|
44
|
-
#TODO: get_Default_timeseries_metrics(constituent)
|
|
45
|
-
|
|
46
|
-
stations.append(calibration_dataclasses.Station(station_id,
|
|
47
|
-
'wiski',
|
|
48
|
-
model_name,
|
|
49
|
-
observations = observations))
|
|
50
|
-
|
|
51
|
-
for station_id, info in equis_info.groupby('station_id'):
|
|
52
|
-
observations = []
|
|
53
|
-
for constituent in info['constituent'].unique():
|
|
54
|
-
metrics = calibration_config.get_default_discrete_metrics()
|
|
55
|
-
observations.append(calibration_dataclasses.Observation(constituent,
|
|
56
|
-
1996,
|
|
57
|
-
2024,
|
|
58
|
-
metrics = metrics))
|
|
59
|
-
#TODO: get_Default_timeseries_metrics(constituent)
|
|
60
|
-
|
|
61
|
-
stations.append(calibration_dataclasses.Station(station_id,
|
|
62
|
-
'equis',
|
|
63
|
-
model_name,
|
|
64
|
-
observations = observations))
|
|
65
|
-
|
|
66
|
-
locations = []
|
|
67
|
-
locs = outlets.get_outlets_by_model(model_name)
|
|
68
|
-
for outlet_id, info in locs.groupby('outlet_id'):
|
|
69
|
-
loc_stations = []
|
|
70
|
-
for station_id,station_origin in zip(info['station_id'],info['station_origin']):
|
|
71
|
-
for station in stations:
|
|
72
|
-
if station.station_id == station_id and station.station_origin == station_origin:
|
|
73
|
-
loc_stations.append(station)
|
|
74
|
-
reach_ids = info['reach_id'].tolist()
|
|
75
|
-
locations.append(calibration_dataclasses.Location(outlet_id,
|
|
76
|
-
str(outlet_id),
|
|
77
|
-
model_name,
|
|
78
|
-
reach_ids,
|
|
79
|
-
stations = loc_stations))
|
|
80
|
-
|
|
81
|
-
config = calibration_dataclasses.CalibrationConfig(model_name,
|
|
82
|
-
locations)
|
|
83
|
-
|
|
84
|
-
df = wiski.info(wiski_stations)
|
|
85
|
-
|
|
86
|
-
obs = calibration_dataclasses.Observation('Q',
|
|
87
|
-
1996,
|
|
88
|
-
2024)
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
for location in locations:
|
|
92
|
-
reach_ids = location.reach_ids
|
|
93
|
-
upstream_reach_ids = location.upstream_reach_ids
|
|
94
|
-
flow_station_ids = []
|
|
95
|
-
station_ids = location.station_ids
|
|
96
|
-
|
|
97
|
-
calibration_dataclasses.Observation(constituent,)
|
|
98
|
-
|
|
99
|
-
calibration_dataclasses.Station(station_id,
|
|
100
|
-
station_origin,
|
|
101
|
-
model_name
|
|
102
|
-
)
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
calibration_dataclasses.Location(1,
|
|
106
|
-
'test',
|
|
107
|
-
model_name,
|
|
108
|
-
reach_ids,
|
|
109
|
-
upstream_reach_ids,
|
|
110
|
-
flow_station_ids,
|
|
111
|
-
station_ids,[])
|
|
112
|
-
station_ids = ['H67009001',
|
|
113
|
-
'H67012001',
|
|
114
|
-
'H67013001',
|
|
115
|
-
'H67014001',
|
|
116
|
-
'H67016001',
|
|
117
|
-
'H67014002',
|
|
118
|
-
'E67013001',
|
|
119
|
-
'W67036001',
|
|
120
|
-
'W67004001']
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|