Skip to content

Commit 6b264fd

Browse files
committed
Updated tess functions according to modified codes
1 parent 7aef966 commit 6b264fd

1 file changed

Lines changed: 100 additions & 17 deletions

File tree

tests/test_calibration.py

Lines changed: 100 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ def test_calibration():
4141
}
4242

4343
# Objective configuration
44-
objectives = {
44+
objective_config = {
4545
'channel_sd_mon.txt': {
4646
'sim_col': 'flo_out',
4747
'obs_col': 'mean',
@@ -84,7 +84,7 @@ def test_calibration():
8484
txtinout_dir=tmp1_dir,
8585
extract_data=extract_data,
8686
observe_data=observe_data,
87-
objectives=objectives,
87+
objective_config=objective_config,
8888
algorithm='NSGA2',
8989
n_gen=2,
9090
pop_size=3
@@ -99,6 +99,23 @@ def test_calibration():
9999
assert os.path.exists(os.path.join(tmp2_dir, 'optimization_history.json'))
100100
assert os.path.exists(os.path.join(tmp2_dir, 'optimization_result.json'))
101101

102+
# Pass: compute sensitivity indices directly
103+
with tempfile.TemporaryDirectory() as tmp3_dir:
104+
output = pySWATPlus.SensitivityAnalyzer().simulation_and_indices(
105+
parameters=parameters,
106+
sample_number=1,
107+
sensim_dir=tmp3_dir,
108+
txtinout_dir=tmp1_dir,
109+
extract_data=extract_data,
110+
observe_data=observe_data,
111+
metric_config=objective_config
112+
)
113+
114+
assert isinstance(output, dict)
115+
assert len(output) == 1
116+
assert os.path.exists(os.path.join(tmp3_dir, 'sensitivity_indices.json'))
117+
assert os.path.exists(os.path.join(tmp3_dir, 'time.json'))
118+
102119

103120
def test_error_calibration():
104121

@@ -137,7 +154,7 @@ def test_error_calibration():
137154
}
138155

139156
# Objective configuration
140-
objectives = {
157+
objective_config = {
141158
'channel_sd_mon.txt': {
142159
'sim_col': 'flo_out',
143160
'obs_col': 'mean',
@@ -161,7 +178,7 @@ def test_error_calibration():
161178
txtinout_dir=tmp1_dir,
162179
extract_data=extract_data,
163180
observe_data=observe_data,
164-
objectives={
181+
objective_config={
165182
'channel_sd_monn.txt': {
166183
'sim_col': 'flo_out',
167184
'obs_col': 'mean',
@@ -172,7 +189,28 @@ def test_error_calibration():
172189
n_gen=2,
173190
pop_size=5
174191
)
175-
assert exc_info.value.args[0] == 'Mismatch of key names. Ensure extract_data, observe_data, and objectives have identical top-level keys.'
192+
assert 'Top-level keys mismatch' in exc_info.value.args[0]
193+
194+
# Error: PBIAS is not allowed as an indicator name
195+
with pytest.raises(Exception) as exc_info:
196+
pySWATPlus.Calibration(
197+
parameters=parameters,
198+
calsim_dir=tmp2_dir,
199+
txtinout_dir=tmp1_dir,
200+
extract_data=extract_data,
201+
observe_data=observe_data,
202+
objective_config={
203+
'channel_sd_mon.txt': {
204+
'sim_col': 'flo_out',
205+
'obs_col': 'mean',
206+
'indicator': 'PBIAS'
207+
}
208+
},
209+
algorithm='NSGA2',
210+
n_gen=2,
211+
pop_size=5
212+
)
213+
assert exc_info.value.args[0] == 'Indicator "PBIAS" is invalid in objective_config; it lacks a defined optimization direction'
176214

177215
# Error: invalid value type of top-key in observe_data
178216
with pytest.raises(Exception) as exc_info:
@@ -184,7 +222,7 @@ def test_error_calibration():
184222
observe_data={
185223
'channel_sd_mon.txt': []
186224
},
187-
objectives=objectives,
225+
objective_config=objective_config,
188226
algorithm='NSGA2',
189227
n_gen=2,
190228
pop_size=5
@@ -203,7 +241,7 @@ def test_error_calibration():
203241
'date_format': '%Y-%m-%d'
204242
}
205243
},
206-
objectives=objectives,
244+
objective_config=objective_config,
207245
algorithm='NSGA2',
208246
n_gen=2,
209247
pop_size=5
@@ -223,7 +261,7 @@ def test_error_calibration():
223261
'date_formatt': '%Y-%m-%d'
224262
}
225263
},
226-
objectives=objectives,
264+
objective_config=objective_config,
227265
algorithm='NSGA2',
228266
n_gen=2,
229267
pop_size=5
@@ -238,14 +276,14 @@ def test_error_calibration():
238276
txtinout_dir=tmp1_dir,
239277
extract_data=extract_data,
240278
observe_data=observe_data,
241-
objectives={
279+
objective_config={
242280
'channel_sd_mon.txt': []
243281
},
244282
algorithm='NSGA2',
245283
n_gen=2,
246284
pop_size=5
247285
)
248-
assert 'Expected "channel_sd_mon.txt" in "objectives" must be a dictionary' in exc_info.value.args[0]
286+
assert 'Expected "channel_sd_mon.txt" in objective_config must be a dictionary' in exc_info.value.args[0]
249287

250288
# Error: invalid length of sub-dictionary in objectives
251289
with pytest.raises(Exception) as exc_info:
@@ -255,7 +293,7 @@ def test_error_calibration():
255293
txtinout_dir=tmp1_dir,
256294
extract_data=extract_data,
257295
observe_data=observe_data,
258-
objectives={
296+
objective_config={
259297
'channel_sd_mon.txt': {
260298
'sim_col': 'flo_out',
261299
'obs_col': 'mean'
@@ -265,7 +303,7 @@ def test_error_calibration():
265303
n_gen=2,
266304
pop_size=5
267305
)
268-
assert 'Length of "channel_sd_mon.txt" sub-dictionary in "objectives" must be 3' in exc_info.value.args[0]
306+
assert 'Length of "channel_sd_mon.txt" sub-dictionary in objective_config must be 3' in exc_info.value.args[0]
269307

270308
# Error: invalid sub-key in objectives
271309
with pytest.raises(Exception) as exc_info:
@@ -275,7 +313,7 @@ def test_error_calibration():
275313
txtinout_dir=tmp1_dir,
276314
extract_data=extract_data,
277315
observe_data=observe_data,
278-
objectives={
316+
objective_config={
279317
'channel_sd_mon.txt': {
280318
'sim_col': 'flo_out',
281319
'obs_col': 'mean',
@@ -286,7 +324,7 @@ def test_error_calibration():
286324
n_gen=2,
287325
pop_size=5
288326
)
289-
assert 'Invalid sub-key "indicatorr" for "channel_sd_mon.txt" in "objectives"' in exc_info.value.args[0]
327+
assert 'Invalid sub-key "indicatorr" for "channel_sd_mon.txt" in objective_config' in exc_info.value.args[0]
290328

291329
# Error: invalid indicator in objectives
292330
with pytest.raises(Exception) as exc_info:
@@ -296,7 +334,7 @@ def test_error_calibration():
296334
txtinout_dir=tmp1_dir,
297335
extract_data=extract_data,
298336
observe_data=observe_data,
299-
objectives={
337+
objective_config={
300338
'channel_sd_mon.txt': {
301339
'sim_col': 'flo_out',
302340
'obs_col': 'mean',
@@ -307,7 +345,7 @@ def test_error_calibration():
307345
n_gen=2,
308346
pop_size=5
309347
)
310-
assert 'Invalid "indicator" value "RMSEE" for "channel_sd_mon.txt" in "objectives"' in exc_info.value.args[0]
348+
assert 'Invalid "indicator" value "RMSEE" for "channel_sd_mon.txt" in objective_config' in exc_info.value.args[0]
311349

312350
# Error: invalid algorithm name
313351
with pytest.raises(Exception) as exc_info:
@@ -317,9 +355,54 @@ def test_error_calibration():
317355
txtinout_dir=tmp1_dir,
318356
extract_data=extract_data,
319357
observe_data=observe_data,
320-
objectives=objectives,
358+
objective_config=objective_config,
321359
algorithm='NSGA',
322360
n_gen=2,
323361
pop_size=5
324362
).parameter_optimization()
325363
assert 'Invalid algorithm "NSGA"' in exc_info.value.args[0]
364+
365+
# Error: invalid algorithm for multiple objectives
366+
with pytest.raises(Exception) as exc_info:
367+
pySWATPlus.Calibration(
368+
parameters=parameters,
369+
calsim_dir=tmp2_dir,
370+
txtinout_dir=tmp1_dir,
371+
extract_data={
372+
'channel_sd_day.txt': {
373+
'has_units': True,
374+
'apply_filter': {'name': ['cha561']}
375+
},
376+
'channel_sd_mon.txt': {
377+
'has_units': True,
378+
'ref_day': 1,
379+
'apply_filter': {'name': ['cha561']}
380+
}
381+
},
382+
observe_data={
383+
'channel_sd_day.txt': {
384+
'obs_file': os.path.join(txtinout_dir, 'a_observe_discharge_monthly.csv'),
385+
'date_format': '%Y-%m-%d'
386+
},
387+
'channel_sd_mon.txt': {
388+
'obs_file': os.path.join(txtinout_dir, 'a_observe_discharge_monthly.csv'),
389+
'date_format': '%Y-%m-%d'
390+
}
391+
},
392+
objective_config={
393+
'channel_sd_day.txt': {
394+
'sim_col': 'flo_out',
395+
'obs_col': 'mean',
396+
'indicator': 'NSE'
397+
},
398+
'channel_sd_mon.txt': {
399+
'sim_col': 'flo_out',
400+
'obs_col': 'mean',
401+
'indicator': 'RMSE'
402+
}
403+
},
404+
algorithm='DE',
405+
n_gen=2,
406+
pop_size=5
407+
).parameter_optimization()
408+
assert 'Algorithm "DE" cannot handle multiple objectives' in exc_info.value.args[0]

0 commit comments

Comments
 (0)