Skip to content

Commit 3f838c4

Browse files
committed
Added a dt scale factor test
1 parent d26e4be commit 3f838c4

File tree

2 files changed

+81
-32
lines changed

2 files changed

+81
-32
lines changed

openet/ssebop/image.py

Lines changed: 33 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,6 @@ def __init__(
4242
et_reference_resample=None,
4343
et_reference_date_type=None,
4444
dt_source='projects/earthengine-legacy/assets/projects/usgs-ssebop/dt/daymet_median_v6',
45-
# dt_scale_factor=None,
4645
tcorr_source='FANO',
4746
tmax_source='projects/earthengine-legacy/assets/projects/usgs-ssebop/tmax/daymet_v4_mean_1981_2010',
4847
elr_flag=False,
@@ -103,6 +102,7 @@ def __init__(
103102
dt_resample : {'nearest', 'bilinear'}
104103
tcorr_resample : {'nearest', 'bilinear'}
105104
tmax_resample : {'nearest', 'bilinear'}
105+
dt_scale_factor : float
106106
elev_source : str or float
107107
min_pixels_per_image : int
108108
min_pixels_per_grid_cell : int
@@ -173,9 +173,10 @@ def __init__(
173173

174174
# Model input parameters
175175
self._dt_source = dt_source
176-
# self._dt_scale_factor = dt_scale_factor
177176
self._tcorr_source = tcorr_source
178177
self._tmax_source = tmax_source
178+
179+
# TODO: Move into keyword args section below
179180
self._elr_flag = elr_flag
180181
self._dt_min = float(dt_min)
181182
self._dt_max = float(dt_max)
@@ -203,6 +204,8 @@ def __init__(
203204
# self.et_fraction_type = 'alfalfa'
204205

205206
self.reflectance_type = reflectance_type
207+
if reflectance_type not in ['SR', 'TOA']:
208+
raise ValueError('reflectance_type must "SR" or "TOA"')
206209

207210
# Image projection and geotransform
208211
self.crs = image.projection().crs()
@@ -215,21 +218,23 @@ def __init__(
215218
# CGM - What is the right way to process kwargs with default values?
216219
self.kwargs = kwargs
217220

218-
# CGM - Should these be checked in the methods they are used in instead?
219-
# Set the resample method as properties so they can be modified
220-
if 'dt_resample' in kwargs.keys():
221-
self._dt_resample = kwargs['dt_resample'].lower()
221+
if 'dt_scale_factor' in kwargs.keys():
222+
self._dt_scale_factor = kwargs['dt_scale_factor']
222223
else:
223-
self._dt_resample = 'bilinear'
224-
225-
# if 'dt_scale_factor' in kwargs.keys():
226-
# self._dt_scale_factor = kwargs['dt_scale_factor']
224+
self._dt_scale_factor = None
227225

228226
if 'elev_source' in kwargs.keys():
229227
self._elev_source = kwargs['elev_source']
230228
else:
231229
self._elev_source = None
232230

231+
# CGM - Should these be checked in the methods they are used in instead?
232+
# Set the resample method as properties so they can be modified
233+
if 'dt_resample' in kwargs.keys():
234+
self._dt_resample = kwargs['dt_resample'].lower()
235+
else:
236+
self._dt_resample = 'bilinear'
237+
233238
if 'tmax_resample' in kwargs.keys():
234239
self._tmax_resample = kwargs['tmax_resample'].lower()
235240
else:
@@ -503,6 +508,20 @@ def dt(self):
503508
If `self._dt_source` is not supported.
504509
505510
"""
511+
if self._dt_scale_factor is None:
512+
if (type(self._dt_source) is str and
513+
'projects/usgs-ssebop/dt/daymet_median_v6' in self._dt_source):
514+
self._dt_scale_factor = 0.01
515+
else:
516+
self._dt_scale_factor = 1.0
517+
elif (type(self._dt_scale_factor) is str and
518+
utils.is_number(self._dt_scale_factor)):
519+
self._dt_scale_factor = float(self._dt_scale_factor)
520+
elif utils.is_number(self._dt_scale_factor):
521+
pass
522+
else:
523+
raise ValueError(f'Unsupported dt_scale_factor: {self._dt_scale_factor}')
524+
506525
if utils.is_number(self._dt_source):
507526
dt_img = ee.Image.constant(float(self._dt_source))
508527
# Use precomputed dT median assets
@@ -514,8 +533,7 @@ def dt(self):
514533
.filter(ee.Filter.calendarRange(self._doy, self._doy, 'day_of_year'))
515534
# MF: Optional scale factor only applied for string ID dT collections, and
516535
# no clamping used for string ID dT collections.
517-
# dt_img = ee.Image(dt_coll.first()).multiply(self._dt_scale_factor)
518-
dt_img = ee.Image(dt_coll.first()).multiply(0.01)
536+
dt_img = ee.Image(dt_coll.first()).multiply(self._dt_scale_factor)
519537
elif self._dt_source.upper() == 'DAYMET_MEDIAN_V0':
520538
dt_coll = ee.ImageCollection(PROJECT_FOLDER + '/dt/daymet_median_v0')\
521539
.filter(ee.Filter.calendarRange(self._doy, self._doy, 'day_of_year'))
@@ -529,6 +547,9 @@ def dt(self):
529547
.filter(ee.Filter.calendarRange(self._doy, self._doy, 'day_of_year'))
530548
dt_img = ee.Image(dt_coll.first()).clamp(self._dt_min, self._dt_max)
531549
elif self._dt_source.upper() == 'CIMIS':
550+
# CGM - Should we check this here or catch the exception in elev()
551+
# if self._elev_source is None:
552+
# raise Exception('elev_source must be set if dt_source="CIMIS"')
532553
input_img = ee.Image(
533554
ee.ImageCollection('projects/earthengine-legacy/assets/'
534555
'projects/climate-engine/cimis/daily')\

openet/ssebop/tests/test_c_image.py

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -75,15 +75,16 @@ def default_image_args(lst=305, ndvi=0.8,
7575
et_reference_resample='nearest',
7676
et_reference_date_type=None,
7777
dt_source=18,
78-
elev_source=67,
79-
elr_flag=False,
8078
tcorr_source=0.9744,
8179
tmax_source=310.15,
80+
dt_scale_factor=None,
81+
elev_source=67,
82+
elr_flag=False,
83+
et_fraction_type='alfalfa',
84+
reflectance_type='TOA',
8285
dt_resample='nearest',
8386
tmax_resample='nearest',
8487
tcorr_resample='nearest',
85-
et_fraction_type='alfalfa',
86-
reflectance_type='TOA',
8788
):
8889
return {
8990
'image': default_image(lst=lst, ndvi=ndvi),
@@ -93,15 +94,16 @@ def default_image_args(lst=305, ndvi=0.8,
9394
'et_reference_resample': et_reference_resample,
9495
'et_reference_date_type': et_reference_date_type,
9596
'dt_source': dt_source,
96-
'elev_source': elev_source,
97-
'elr_flag': elr_flag,
9897
'tcorr_source': tcorr_source,
9998
'tmax_source': tmax_source,
99+
'dt_scale_factor': dt_scale_factor,
100+
'elev_source': elev_source,
101+
'elr_flag': elr_flag,
102+
'et_fraction_type': et_fraction_type,
103+
'reflectance_type': reflectance_type,
100104
'dt_resample': dt_resample,
101105
'tmax_resample': tmax_resample,
102106
'tcorr_resample': tcorr_resample,
103-
'et_fraction_type': et_fraction_type,
104-
'reflectance_type': reflectance_type,
105107
}
106108

107109

@@ -113,15 +115,16 @@ def default_image_obj(lst=305, ndvi=0.8,
113115
et_reference_resample='nearest',
114116
et_reference_date_type=None,
115117
dt_source=18,
116-
elev_source=67,
117-
elr_flag=False,
118118
tcorr_source=0.9744,
119119
tmax_source=310.15,
120+
dt_scale_factor=None,
121+
elev_source=67,
122+
elr_flag=False,
123+
et_fraction_type='alfalfa',
124+
reflectance_type='TOA',
120125
dt_resample='nearest',
121126
tmax_resample='nearest',
122127
tcorr_resample='nearest',
123-
et_fraction_type='alfalfa',
124-
reflectance_type='TOA',
125128
):
126129
return ssebop.Image(**default_image_args(
127130
lst=lst, ndvi=ndvi,
@@ -131,15 +134,16 @@ def default_image_obj(lst=305, ndvi=0.8,
131134
et_reference_resample=et_reference_resample,
132135
et_reference_date_type=et_reference_date_type,
133136
dt_source=dt_source,
134-
elev_source=elev_source,
135-
elr_flag=elr_flag,
136137
tcorr_source=tcorr_source,
137138
tmax_source=tmax_source,
139+
dt_scale_factor=dt_scale_factor,
140+
elev_source=elev_source,
141+
elr_flag=elr_flag,
142+
et_fraction_type=et_fraction_type,
143+
reflectance_type=reflectance_type,
138144
dt_resample=dt_resample,
139145
tmax_resample=tmax_resample,
140146
tcorr_resample=tcorr_resample,
141-
et_fraction_type=et_fraction_type,
142-
reflectance_type=reflectance_type,
143147
))
144148

145149

@@ -153,14 +157,15 @@ def test_Image_init_default_parameters():
153157
assert m._dt_source == 'projects/earthengine-legacy/assets/projects/usgs-ssebop/dt/daymet_median_v6'
154158
assert m._tcorr_source == 'FANO'
155159
assert m._tmax_source == 'projects/earthengine-legacy/assets/projects/usgs-ssebop/tmax/daymet_v4_mean_1981_2010'
156-
assert m._elr_flag == False
157160
assert m._dt_min == 5
158161
assert m._dt_max == 25
159-
assert m._dt_resample == 'bilinear'
162+
assert m._dt_scale_factor == None
160163
assert m._elev_source == None
164+
assert m._elr_flag == False
165+
assert m.reflectance_type == 'SR'
166+
assert m._dt_resample == 'bilinear'
161167
assert m._tmax_resample == 'bilinear'
162168
assert m._tcorr_resample == 'bilinear'
163-
assert m.reflectance_type == 'SR'
164169

165170

166171
# Todo: Break these up into separate functions?
@@ -222,7 +227,9 @@ def test_Image_lst_properties():
222227

223228
@pytest.mark.parametrize(
224229
'elev_source',
225-
[None, '', 'DEADBEEF']
230+
[None],
231+
# TODO: Non-image strings should raise an exception
232+
# ['', 'DEADBEEF']
226233
# TODO: Check what happens if source is an image collection
227234
# [None, '', 'DEADBEEF']
228235
)
@@ -356,6 +363,27 @@ def test_Image_dt_source_exception():
356363
utils.getinfo(default_image_obj(dt_source='').dt)
357364

358365

366+
@pytest.mark.parametrize(
367+
'dt_source, factor, doy, xy, expected',
368+
[
369+
['projects/usgs-ssebop/dt/daymet_median_v6', 0.01, SCENE_DOY, TEST_POINT, 20.77],
370+
['projects/usgs-ssebop/dt/daymet_median_v6', 1.0, SCENE_DOY, TEST_POINT, 2077],
371+
# Scale factor is only applied to collection ID sources
372+
['projects/usgs-ssebop/dt/daymet_median_v2', 2.0, SCENE_DOY, TEST_POINT, 2 * 19.5982],
373+
['DAYMET_MEDIAN_V2', 2.0, SCENE_DOY, TEST_POINT, 19.5982],
374+
# None will default to 0.01 for v6 and fall back to 1.0 for all other sources
375+
['projects/usgs-ssebop/dt/daymet_median_v6', None, SCENE_DOY, TEST_POINT, 20.77],
376+
['projects/usgs-ssebop/dt/daymet_median_v2', None, SCENE_DOY, TEST_POINT, 19.5982],
377+
]
378+
)
379+
def test_Image_dt_scale_factor(dt_source, factor, doy, xy, expected, tol=0.001):
380+
"""Test that dT scale factor changes the dT values"""
381+
m = default_image_obj(dt_source=dt_source, dt_scale_factor=factor)
382+
m._doy = doy
383+
output = utils.point_image_value(ee.Image(m.dt), xy)
384+
assert abs(output['dt'] - expected) <= tol
385+
386+
359387
@pytest.mark.parametrize(
360388
'doy, dt_min, dt_max',
361389
[

0 commit comments

Comments
 (0)