Skip to content

Commit 3d76eb5

Browse files
authored
Merge pull request #57 from Open-ET/v0p4_cleanup
v0.4.0 code cleanup
2 parents e52861e + 7293798 commit 3d76eb5

File tree

71 files changed

+133
-17709
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+133
-17709
lines changed

CONTRIBUTING.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ Create the conda environment:
3030

3131
.. code-block:: console
3232
33-
conda create --name openet python=3.6
33+
conda create --name openet python=3.9
3434
3535
Activate the environment:
3636

README.rst

Lines changed: 9 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,12 @@ The primary component of the SSEBop model is the Image() class. The Image class
2424
Input Collections
2525
=================
2626

27-
SSEBop ET can currently be computed for Landsat Collection 2 Level 2 (SR/ST) images and Landsat Collection 1 Top-Of-Atmosphere (TOA) images from the following Earth Engine image collections:
27+
SSEBop ET can currently be computed for Landsat Collection 2 Level 2 (SR/ST) images from the following Earth Engine image collections:
2828

2929
* LANDSAT/LC09/C02/T1_L2
3030
* LANDSAT/LC08/C02/T1_L2
3131
* LANDSAT/LE07/C02/T1_L2
3232
* LANDSAT/LT05/C02/T1_L2
33-
* LANDSAT/LC08/C01/T1_TOA or LANDSAT/LC08/C01/T1_RT_TOA
34-
* LANDSAT/LE07/C01/T1_TOA or LANDSAT/LE07/C01/T1_RT_TOA
35-
* LANDSAT/LT05/C01/T1_TOA
36-
3733

3834
**Note:** Users are encouraged to prioritize use of Collection 2 data where available. Collection 1 was produced by USGS until 2022-01-01, and maintained by Earth Engine until 2023-01-01. [`More Information <https://developers.google.com/earth-engine/guides/landsat#landsat-collection-status>`__]
3935

@@ -53,32 +49,6 @@ LANDSAT_8 SR_B1, SR_B2, SR_B3, SR_B4, SR_B5, SR_B6, SR_B7, ST_B10, QA_P
5349
LANDSAT_9 SR_B1, SR_B2, SR_B3, SR_B4, SR_B5, SR_B6, SR_B7, ST_B10, QA_PIXEL
5450
================= ======================================
5551

56-
Landsat Collection 1 TOA Input Image
57-
------------------------------------
58-
59-
To instantiate the class for a Landsat Collection 1 TOA image, use the Image.from_landsat_c1_toa() method.
60-
61-
The input Landsat image must have the following bands and properties:
62-
63-
================= ======================================
64-
SPACECRAFT_ID Band Names
65-
================= ======================================
66-
LANDSAT_5 B1, B2, B3, B4, B5, B7, B6, BQA
67-
LANDSAT_7 B1, B2, B3, B4, B5, B7, B6_VCID_1, BQA
68-
LANDSAT_8 B2, B3, B4, B5, B6, B7, B10, BQA
69-
================= ======================================
70-
71-
================= =============================================
72-
Property Description
73-
================= =============================================
74-
system:index - Landsat Scene ID
75-
- Must be in the Earth Engine format (e.g. LC08_044033_20170716)
76-
- Used to lookup the scene specific c-factor (DEPRECATED)
77-
system:time_start Image datetime in milliseconds since 1970
78-
SPACECRAFT_ID - Used to determine which Landsat type
79-
- Must be: LANDSAT_5, LANDSAT_7, or LANDSAT_8
80-
================= =============================================
81-
8252
Model Output
8353
------------
8454

@@ -95,8 +65,8 @@ Example
9565
9666
import openet.ssebop as ssebop
9767
98-
landsat_img = ee.Image('LANDSAT/LC08/C01/T1_RT_TOA/LC08_044033_20170716')
99-
et_fraction = ssebop.Image.from_landsat_c1_toa(landsat_img).et_fraction
68+
landsat_img = ee.Image('LANDSAT/LC08/C02/T1_L2/LC08_044033_20170716')
69+
et_fraction = ssebop.Image.from_landsat_c2_sr(landsat_img).et_fraction
10070
et_reference = ee.Image('IDAHO_EPSCOR/GRIDMET/20170716').select('etr')
10171
et_actual = et_fraction.multiply(et_reference)
10272
@@ -109,11 +79,13 @@ SSEBop images can also be built manually by instantiating the class with an ee.I
10979
11080
import openet.ssebop as ssebop
11181
112-
input_img = ee.Image([ee.Image(lst), ee.Image(ndvi)]) \
113-
.rename(['lst', 'ndvi']) \
82+
input_img = (
83+
ee.Image([ee.Image(lst), ee.Image(ndvi)])
84+
.rename(['lst', 'ndvi'])
11485
.set({
11586
'system:index': 'LC08_044033_20170716',
11687
'system:time_start': ee.Date.fromYMD(2017, 7, 16).millis()})
88+
)
11789
et_fraction = ssebop.Image(input_img).et_fraction
11890
11991
Example Notebooks
@@ -141,8 +113,6 @@ Land Surface Temperature is currently calculated in the SSEBop approach two ways
141113

142114
* Landsat Collection 2 Level-2 (ST band) images directly. More information can be found at: `USGS Landsat Collection 2 Level-2 Science Products <https://www.usgs.gov/core-science-systems/nli/landsat/landsat-collection-2-level-2-science-products>`__
143115

144-
* Landsat Collection 1 Top-of-Atmosphere images by including an on-the-fly function for calibration steps and atmospheric correction techniques. These include calculations for: (1) spectral radiance conversion to the at-sensor brightness temperature; (2) atmospheric absorption and re-emission value; and (3) surface emissivity. For additional information, users can refer to section 3.2 of the Methodology in Senay2016_.
145-
146116
Temperature Difference (dT)
147117
---------------------------
148118
The SSEBop ET model uses dT as a predefined temperature difference between Thot and Tcold for each pixel.
@@ -164,6 +134,7 @@ The 'FANO' parameter (default) can be implemented dynamically for each Landsat s
164134
.. code-block:: python
165135
166136
model_obj = model.Image.from_landsat_c2_sr(
137+
ee.Image('LANDSAT/LC08/C02/T1_L2/LC08_044033_20170716'),
167138
tcorr_source='FANO',
168139
)
169140
@@ -228,7 +199,7 @@ References
228199
| Senay, G.B., Parrish, G. E., Schauer, M., Friedrichs, M., Khand, K., Boiko, O., Kagone, S., Dittmeier, R., Arab, S., Ji, L. (2023). Improving the Operational Simplified Surface Energy Balance evapotranspiration model using the Forcing and Normalizing Operation. *Remote Sensing*, 15(1):260.
229200
| `https://doi.org/10.3390/rs15010260 <https://doi.org/10.3390/rs15010260>`__
230201
231-
.. |build| image:: https://github.com/Open-ET/openet-ssebop/workflows/build/badge.svg
202+
.. |build| image:: https://github.com/Open-ET/openet-ssebop/actions/workflows/build.yml/badge.svg
232203
:alt: Build status
233204
:target: https://github.com/Open-ET/openet-ssebop
234205
.. |version| image:: https://badge.fury.io/py/openet-ssebop.svg

examples/tcorr_gridded.ipynb

Lines changed: 0 additions & 531 deletions
This file was deleted.

openet/ssebop/collection.py

Lines changed: 1 addition & 154 deletions
Original file line numberDiff line numberDiff line change
@@ -161,30 +161,14 @@ def __init__(
161161
'LANDSAT/LC08/C02/T1_L2',
162162
'LANDSAT/LC09/C02/T1_L2',
163163
]
164-
self._landsat_c1_sr_collections = [
165-
'LANDSAT/LT04/C01/T1_SR',
166-
'LANDSAT/LT05/C01/T1_SR',
167-
'LANDSAT/LE07/C01/T1_SR',
168-
'LANDSAT/LC08/C01/T1_SR',
169-
]
170-
self._landsat_c1_toa_collections = [
171-
'LANDSAT/LT04/C01/T1_TOA',
172-
'LANDSAT/LT05/C01/T1_TOA',
173-
'LANDSAT/LE07/C01/T1_TOA',
174-
'LANDSAT/LC08/C01/T1_TOA',
175-
'LANDSAT/LE07/C01/T1_RT_TOA',
176-
'LANDSAT/LC08/C01/T1_RT_TOA',
177-
]
178164

179165
# If collections is a string, place in a list
180166
if type(self.collections) is str:
181167
self.collections = [self.collections]
182168

183169
# Check that collection IDs are supported
184170
for coll_id in self.collections:
185-
if (coll_id not in self._landsat_c2_sr_collections and
186-
coll_id not in self._landsat_c1_sr_collections and
187-
coll_id not in self._landsat_c1_toa_collections):
171+
if coll_id not in self._landsat_c2_sr_collections:
188172
raise ValueError(f'unsupported collection: {coll_id}')
189173

190174
# Check that collections don't have "duplicates"
@@ -348,143 +332,6 @@ def compute_vars(image):
348332

349333
variable_coll = variable_coll.merge(input_coll)
350334

351-
elif coll_id in self._landsat_c1_toa_collections:
352-
warnings.warn(
353-
'Support for Landsat C01 TOA image collections (LANDSAT/LXXX/C01/T1_TOA) '
354-
'is deprecated and will be removed in a future version',
355-
FutureWarning
356-
# DeprecationWarning, stacklevel=2
357-
)
358-
359-
input_coll = (
360-
ee.ImageCollection(coll_id)
361-
.filterDate(start_date, end_date)
362-
.filterBounds(self.geometry)
363-
.filterMetadata('DATA_TYPE', 'equals', 'L1TP')
364-
.filterMetadata('CLOUD_COVER_LAND', 'less_than', self.cloud_cover_max)
365-
.filterMetadata('CLOUD_COVER_LAND', 'greater_than', -0.5)
366-
)
367-
368-
# TODO: Move this to a separate function (maybe in utils.py?)
369-
# since it is identical for all the supported collections
370-
if (self.filter_args is None or
371-
not isinstance(self.filter_args, dict) or
372-
coll_id not in self.filter_args.keys()):
373-
pass
374-
elif isinstance(self.filter_args[coll_id], ee.ComputedObject):
375-
input_coll = input_coll.filter(self.filter_args[coll_id])
376-
elif isinstance(self.filter_args[coll_id], list):
377-
# TODO: This generic dictionary based filtering should
378-
# probably be removed since only the "equals" filter
379-
# has been implemented and the functionality is better
380-
# handled with the other approach.
381-
for f in copy.deepcopy(self.filter_args[coll_id]):
382-
try:
383-
filter_type = f.pop('type')
384-
except KeyError:
385-
continue
386-
if filter_type.lower() == 'equals':
387-
input_coll = input_coll.filter(ee.Filter.equals(**f))
388-
else:
389-
raise ValueError('Unsupported filter_arg parameter')
390-
391-
# TODO: Check if these bad images are in collection 1 SR
392-
# Time filters are to remove bad (L5) and pre-op (L8) images
393-
if 'LT05' in coll_id:
394-
input_coll = input_coll.filter(
395-
ee.Filter.lt('system:time_start', ee.Date('2011-12-31').millis())
396-
)
397-
elif 'LE07' in coll_id:
398-
input_coll = input_coll.filter(
399-
ee.Filter.lt('system:time_start', ee.Date('2022-01-01').millis())
400-
)
401-
elif 'LC08' in coll_id:
402-
input_coll = input_coll.filter(
403-
ee.Filter.gt('system:time_start', ee.Date('2013-04-01').millis())
404-
)
405-
406-
def compute_vars(image):
407-
model_obj = Image.from_landsat_c1_toa(
408-
toa_image=ee.Image(image), **self.model_args
409-
)
410-
return model_obj.calculate(variables)
411-
412-
# Skip going into image class if variables is not set so raw
413-
# landsat collection can be returned for getting image_id_list
414-
if variables:
415-
input_coll = ee.ImageCollection(input_coll.map(compute_vars))
416-
417-
variable_coll = variable_coll.merge(input_coll)
418-
419-
elif coll_id in self._landsat_c1_sr_collections:
420-
warnings.warn(
421-
'Support for Landsat C01 SR image collections (LANDSAT/LXXX/C01/T1_SR) '
422-
'is deprecated and will be removed in a future version',
423-
FutureWarning
424-
# DeprecationWarning, stacklevel=2
425-
)
426-
427-
input_coll = (
428-
ee.ImageCollection(coll_id)
429-
.filterDate(start_date, end_date)
430-
.filterBounds(self.geometry)
431-
.filterMetadata('CLOUD_COVER_LAND', 'less_than', self.cloud_cover_max)
432-
.filterMetadata('CLOUD_COVER_LAND', 'greater_than', -0.5)
433-
)
434-
435-
# TODO: Move this to a separate function (maybe in utils.py?)
436-
# since it is identical for all the supported collections
437-
if (self.filter_args is None or
438-
not isinstance(self.filter_args, dict) or
439-
coll_id not in self.filter_args.keys()):
440-
pass
441-
elif isinstance(self.filter_args[coll_id], ee.ComputedObject):
442-
input_coll = input_coll.filter(self.filter_args[coll_id])
443-
elif isinstance(self.filter_args[coll_id], list):
444-
# TODO: This generic dictionary based filtering should
445-
# probably be removed since only the "equals" filter
446-
# has been implemented and the functionality is better
447-
# handled with the other two options.
448-
for f in copy.deepcopy(self.filter_args[coll_id]):
449-
try:
450-
filter_type = f.pop('type')
451-
except KeyError:
452-
continue
453-
if filter_type.lower() == 'equals':
454-
input_coll = input_coll.filter(ee.Filter.equals(**f))
455-
else:
456-
raise ValueError('Unsupported filter_arg parameter')
457-
458-
# Time filters are to remove bad (L5) and pre-op (L8) images
459-
if 'LT05' in coll_id:
460-
input_coll = input_coll.filter(
461-
ee.Filter.lt('system:time_start', ee.Date('2011-12-31').millis())
462-
)
463-
elif 'LE07' in coll_id:
464-
input_coll = input_coll.filter(
465-
ee.Filter.lt('system:time_start', ee.Date('2022-01-01').millis())
466-
)
467-
elif 'LC08' in coll_id:
468-
input_coll = input_coll.filter(
469-
ee.Filter.gt('system:time_start', ee.Date('2013-04-01').millis())
470-
)
471-
472-
def compute_vars(image):
473-
model_obj = Image.from_landsat_c1_sr(
474-
sr_image=ee.Image(image), **self.model_args
475-
)
476-
return model_obj.calculate(variables)
477-
478-
# Skip going into image class if variables is not set so raw
479-
# landsat collection can be returned for getting image_id_list
480-
if variables:
481-
input_coll = ee.ImageCollection(input_coll.map(compute_vars))
482-
483-
variable_coll = variable_coll.merge(input_coll)
484-
485-
else:
486-
raise ValueError(f'unsupported collection: {coll_id}')
487-
488335
return variable_coll
489336

490337
def overpass(self, variables=None):

0 commit comments

Comments
 (0)