From 110a8caef52733e005330b34eed8edc93147573f Mon Sep 17 00:00:00 2001 From: Scott Stewart Date: Wed, 6 Nov 2024 22:11:15 -0700 Subject: [PATCH 1/3] allow melt from not-last-day-of-month --- seaice_ecdr/intermediate_monthly.py | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/seaice_ecdr/intermediate_monthly.py b/seaice_ecdr/intermediate_monthly.py index 67bf7dfb..7c39b773 100644 --- a/seaice_ecdr/intermediate_monthly.py +++ b/seaice_ecdr/intermediate_monthly.py @@ -477,10 +477,20 @@ def calc_cdr_melt_onset_day_monthly( ) -> xr.DataArray: """Create the `cdr_melt_onset_day_monthly` variable.""" # Create `cdr_melt_onset_day_monthly`. This is the value from - # the last day of the month. - cdr_melt_onset_day_monthly = daily_melt_onset_for_month.sel( - time=daily_melt_onset_for_month.time.max() - ) + # the last day of the month unless the month is incomplete. + # xarray uses np.datetime64[ns] for time + max_date = daily_melt_onset_for_month.time.max() + if daily_melt_onset_for_month.time.dtype == np.datetime64(1, "ns").dtype: + unix_epoch = np.datetime64(0, "s") + one_second = np.timedelta64(1, "s") + for dt64 in daily_melt_onset_for_month.time.data: + seconds_since_epoch = (dt64 - unix_epoch) / one_second + date = dt.datetime.utcfromtimestamp(seconds_since_epoch).date() + if date.strftime("%j") == "244": + max_date = dt64 + logger.info(f"Found non-max date with melt: {max_date}") + + cdr_melt_onset_day_monthly = daily_melt_onset_for_month.sel(time=max_date) cdr_melt_onset_day_monthly.name = "cdr_melt_onset_day_monthly" cdr_melt_onset_day_monthly = cdr_melt_onset_day_monthly.drop_vars("time") From 44b47bc25c61a08f8a663d0b40f05e9e99a88a7b Mon Sep 17 00:00:00 2001 From: Trey Stafford Date: Thu, 7 Nov 2024 13:42:06 -0700 Subject: [PATCH 2/3] Simplify code to select DOY 244 if present for monthly melt onset --- seaice_ecdr/intermediate_monthly.py | 19 +++++++++---------- seaice_ecdr/tests/unit/test_monthly.py | 9 ++++++++- 2 files changed, 17 insertions(+), 11 deletions(-) diff --git a/seaice_ecdr/intermediate_monthly.py b/seaice_ecdr/intermediate_monthly.py index 7c39b773..1048e56f 100644 --- a/seaice_ecdr/intermediate_monthly.py +++ b/seaice_ecdr/intermediate_monthly.py @@ -479,16 +479,15 @@ def calc_cdr_melt_onset_day_monthly( # Create `cdr_melt_onset_day_monthly`. This is the value from # the last day of the month unless the month is incomplete. # xarray uses np.datetime64[ns] for time - max_date = daily_melt_onset_for_month.time.max() - if daily_melt_onset_for_month.time.dtype == np.datetime64(1, "ns").dtype: - unix_epoch = np.datetime64(0, "s") - one_second = np.timedelta64(1, "s") - for dt64 in daily_melt_onset_for_month.time.data: - seconds_since_epoch = (dt64 - unix_epoch) / one_second - date = dt.datetime.utcfromtimestamp(seconds_since_epoch).date() - if date.strftime("%j") == "244": - max_date = dt64 - logger.info(f"Found non-max date with melt: {max_date}") + doy_str_list = [ + date.strftime("%j") for date in daily_melt_onset_for_month.time.dt.date.values + ] + if "244" in doy_str_list: + day_244_idx = doy_str_list.index("244") + max_date = daily_melt_onset_for_month.time[day_244_idx].values + logger.info(f"Found non-max date with melt: {max_date}") + else: + max_date = daily_melt_onset_for_month.time.max() cdr_melt_onset_day_monthly = daily_melt_onset_for_month.sel(time=max_date) cdr_melt_onset_day_monthly.name = "cdr_melt_onset_day_monthly" diff --git a/seaice_ecdr/tests/unit/test_monthly.py b/seaice_ecdr/tests/unit/test_monthly.py index 901f3b46..5e6fc267 100644 --- a/seaice_ecdr/tests/unit/test_monthly.py +++ b/seaice_ecdr/tests/unit/test_monthly.py @@ -505,7 +505,14 @@ def test_calc_cdr_melt_onset_day_monthly(): data=_mock_data, dims=["y", "time"], coords=dict( - time=[dt.date(2022, 3, 1), dt.date(2022, 3, 2), dt.date(2022, 3, 3)], + time=[ + np.datetime64(date) + for date in [ + dt.date(2022, 3, 1), + dt.date(2022, 3, 2), + dt.date(2022, 3, 3), + ] + ], y=list(range(5)), ), ) From 782689efd7d838ddbfaabfa351b4bac02411ded9 Mon Sep 17 00:00:00 2001 From: Trey Stafford Date: Thu, 7 Nov 2024 13:45:42 -0700 Subject: [PATCH 3/3] Use `MELT_SEASON_LAST_DOY` constant in monthly melt field creation --- seaice_ecdr/intermediate_monthly.py | 10 ++++++---- seaice_ecdr/melt.py | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/seaice_ecdr/intermediate_monthly.py b/seaice_ecdr/intermediate_monthly.py index 1048e56f..e253d85a 100644 --- a/seaice_ecdr/intermediate_monthly.py +++ b/seaice_ecdr/intermediate_monthly.py @@ -44,6 +44,7 @@ from seaice_ecdr.constants import DEFAULT_BASE_OUTPUT_DIR from seaice_ecdr.days_treated_differently import months_of_cdr_missing_data from seaice_ecdr.intermediate_daily import get_ecdr_filepath +from seaice_ecdr.melt import MELT_SEASON_LAST_DOY from seaice_ecdr.nc_attrs import get_global_attrs from seaice_ecdr.platforms import PLATFORM_CONFIG, SUPPORTED_PLATFORM_ID from seaice_ecdr.tb_data import get_hemisphere_from_crs_da @@ -479,11 +480,12 @@ def calc_cdr_melt_onset_day_monthly( # Create `cdr_melt_onset_day_monthly`. This is the value from # the last day of the month unless the month is incomplete. # xarray uses np.datetime64[ns] for time - doy_str_list = [ - date.strftime("%j") for date in daily_melt_onset_for_month.time.dt.date.values + doy_list: list[int] = [ + int(date.strftime("%j")) + for date in daily_melt_onset_for_month.time.dt.date.values ] - if "244" in doy_str_list: - day_244_idx = doy_str_list.index("244") + if MELT_SEASON_LAST_DOY in doy_list: + day_244_idx = doy_list.index(MELT_SEASON_LAST_DOY) max_date = daily_melt_onset_for_month.time[day_244_idx].values logger.info(f"Found non-max date with melt: {max_date}") else: diff --git a/seaice_ecdr/melt.py b/seaice_ecdr/melt.py index d8bb6b24..4c2d87a4 100644 --- a/seaice_ecdr/melt.py +++ b/seaice_ecdr/melt.py @@ -35,8 +35,8 @@ import numpy.typing as npt # Start and end DOYs for the melt season (inclusive) -MELT_SEASON_FIRST_DOY = 60 -MELT_SEASON_LAST_DOY = 244 +MELT_SEASON_FIRST_DOY: int = 60 +MELT_SEASON_LAST_DOY: int = 244 # Flag value for grid cells before melting is detected or if no melt is ever # detected.