Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates necessary to support 25km platforms for the ECDR #45

Merged
merged 26 commits into from
Feb 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
8f24078
add F17 BT params from cdralgos
Jan 17, 2024
7dd0e94
add F17 NT tiepoints
Jan 17, 2024
a61569e
fix mypy errors for adding nsidc0001
Jan 24, 2024
b4acad6
separate AMSRE and AMSR2 param routines
Jan 24, 2024
5fbded0
update CHANGELOG
Jan 24, 2024
05de629
Adjust typing for nt param functions expecting a `ValidSatellite`.
trey-stafford Jan 25, 2024
7750697
Merge pull request #40 from nsidc/add_f17_bt_params_trey
trey-stafford Jan 25, 2024
0c385bf
extend BT parameters to 0001 platforms
Jan 29, 2024
7134d9a
cause NT2 spillover to be adjustable
Jan 30, 2024
32b0c5a
Move SMMR-related params to its own module
trey-stafford Jan 31, 2024
04c2cc4
add support for f08, f11, f13
Jan 31, 2024
01a572d
Add code for transforming RSS tbs
trey-stafford Jan 31, 2024
c04f53b
Merge branch 'tb-rss-xfers' into support-smmr
trey-stafford Jan 31, 2024
79e43d3
Merge pull request #41 from nsidc/tb-rss-xfers
trey-stafford Jan 31, 2024
3d8bb7a
Merge pull request #43 from nsidc/improve_nt2_spillover
trey-stafford Jan 31, 2024
fb405aa
Merge pull request #44 from nsidc/add_dmsp_support
trey-stafford Jan 31, 2024
8dd3561
Merge pull request #42 from nsidc/support-smmr
trey-stafford Jan 31, 2024
aef28ef
Add CDR-specifc nt gradient thresholds
trey-stafford Feb 1, 2024
9fedfea
Remove OBE logger statement
trey-stafford Feb 1, 2024
475299a
Make getter for nt params more generic
trey-stafford Feb 1, 2024
5775ffc
Use f17 nt weather filter thresholds for AMSRE
trey-stafford Feb 1, 2024
ba66800
Matp ame nt tiepoints to amsr2 tiepoints
trey-stafford Feb 1, 2024
6c0f44d
Add TODO
trey-stafford Feb 1, 2024
681c8c4
Merge pull request #46 from nsidc/platform-specific-nt-gradient-thres…
trey-stafford Feb 1, 2024
078edaa
Merge pull request #47 from nsidc/generic-nt-params
trey-stafford Feb 1, 2024
b377047
add comment about keys to 0001 NT params dictionary
Feb 1, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,7 @@
internal infrastructure and unpublished data. It is now the responsibility of
other programs utlizing this library to provide masks, input TBs, etc.
* Replace `BootstrapAlgError` in `get_linfit` with a logged warning. Use default
slope and offset values instead of failing when there are less than 125 valid
pixels.
* Separate AMSR2 and AMSRE parameter coefficient specifications.

# v0.2.0

Expand Down
2 changes: 1 addition & 1 deletion pm_icecon/bt/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@
import numpy as np
import numpy.typing as npt
import xarray as xr
from pm_tb_data._types import Hemisphere
from pm_tb_data.fetch.a2l1c_625 import get_a2l1c_625_tbs
from pm_tb_data.fetch.amsr.au_si import get_au_si_tbs
from pm_tb_data.fetch.amsr.util import AMSR_RESOLUTIONS
from pm_tb_data._types import Hemisphere

import pm_icecon.bt.compute_bt_ic as bt
from pm_icecon.bt.params.ausi_amsr2 import get_amsr2_params
Expand Down
40 changes: 1 addition & 39 deletions pm_icecon/bt/compute_bt_ic.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import datetime as dt
import warnings
from functools import reduce
from typing import Literal, Sequence
from typing import Sequence

import numpy as np
import numpy.typing as npt
Expand All @@ -24,7 +24,6 @@
WeatherFilterParamsForSeason,
)
from pm_icecon.constants import DEFAULT_FLAG_VALUES
from pm_icecon.errors import UnexpectedSatelliteError


# TODO: this function very similar to `get_invalid_tbs_mask` in `compute_nt_ic`.
Expand Down Expand Up @@ -56,43 +55,6 @@ def _is_outofrange_tb(tb, min_tb, max_tb):
return is_bad_tb


def xfer_class_tbs(
*,
tb_v37: npt.NDArray,
tb_h37: npt.NDArray,
tb_v19: npt.NDArray,
tb_v22: npt.NDArray,
sat: Literal["f17", "f18"],
) -> dict[str, npt.NDArray[np.float32]]:
"""Transform selected CLASS (NRT) TBs for consistentcy with timeseries.

Some CLASS data should be transformed via linear regression for consistenicy
with other data sources (TODO: which ones exactly?)

TODO: make sure this description is...descriptive enough.
"""
# NRT regressions
if sat == "f17":
tb_v37 = (1.0170066 * tb_v37) + -4.9383355
tb_h37 = (1.0009720 * tb_h37) + -1.3709822
tb_v19 = (1.0140723 * tb_v19) + -3.4705583
tb_v22 = (0.99652931 * tb_v22) + -0.82305684
elif sat == "f18":
tb_v37 = (1.0104497 * tb_v37) + -3.3174017
tb_h37 = (0.98914390 * tb_h37) + 1.2031835
tb_v19 = (1.0057373 * tb_v19) + -0.92638520
tb_v22 = (0.98793409 * tb_v22) + 1.2108198
else:
raise UnexpectedSatelliteError(f"No such tb xform: {sat}")

return {
"tb_v37": tb_v37,
"tb_h37": tb_h37,
"tb_v19": tb_v19,
"tb_v22": tb_v22,
}


def get_adj_ad_line_offset(
*,
wtp_x: Tiepoint,
Expand Down
2 changes: 1 addition & 1 deletion pm_icecon/bt/params/ausi_amsr2.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,7 @@ def get_amsr2_params(
return bt_params


def get_ausi_bootstrap_params(
def get_ausi_amsr2_bootstrap_params(
*,
date: dt.date,
satellite: str,
Expand Down
204 changes: 204 additions & 0 deletions pm_icecon/bt/params/ausi_amsre.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
"""AMSRE Bootstrap parameters.

Bootstrap parameters for use with AMSRE derived from AU_SI products

For now, these parameters are copied from the AMSR2 Bootstrap parameters
CDR.
"""
import datetime as dt
from typing import cast

from pm_tb_data._types import Hemisphere

from pm_icecon.bt._types import Line, Tiepoint
from pm_icecon.bt.params._types import ParamsDict
from pm_icecon.bt.params.util import setup_bootstrap_params_dict
from pm_icecon.config.models.bt import (
BootstrapParams,
TbSetParams,
WeatherFilterParams,
WeatherFilterParamsForSeason,
)
from pm_icecon.gridid import get_gridid_hemisphere

GODDARD_AMSRE_NORTH_PARAMS = ParamsDict(
vh37_params=TbSetParams(
water_tie_point_set=(Tiepoint(207.2), Tiepoint(131.9)),
ice_tie_point_set=(Tiepoint(256.3), Tiepoint(241.2)),
lnline=Line(offset=-71.99, slope=1.20),
),
v1937_params=TbSetParams(
water_tie_point_set=(Tiepoint(207.2), Tiepoint(182.4)),
ice_tie_point_set=(Tiepoint(256.3), Tiepoint(258.9)),
lnline=Line(offset=48.26, slope=0.8048),
),
weather_filter_seasons=[
# November through April (`seas=1` in `boot_ice_amsru2_np.f`)
WeatherFilterParamsForSeason(
start_month=11,
end_month=4,
weather_filter_params=WeatherFilterParams(
wintrc=84.73,
wslope=0.5352,
wxlimt=18.39,
),
),
# May (`seas=2`) will get interpolated from the previous and next season
# June through Sept. (`seas=3`)
WeatherFilterParamsForSeason(
start_month=6,
end_month=9,
weather_filter_params=WeatherFilterParams(
wintrc=82.71,
wslope=0.5352,
wxlimt=23.34,
),
),
# October (`seas=4`) will get interpolated from the previous and next
# (first in this list) season.
],
)

GODDARD_AMSRE_SOUTH_PARAMS = ParamsDict(
vh37_params=TbSetParams(
water_tie_point_set=(Tiepoint(207.6), Tiepoint(131.9)),
ice_tie_point_set=(Tiepoint(259.4), Tiepoint(247.3)),
lnline=Line(offset=-90.62, slope=1.2759),
),
v1937_params=TbSetParams(
water_tie_point_set=(Tiepoint(207.6), Tiepoint(182.7)),
ice_tie_point_set=(Tiepoint(259.4), Tiepoint(261.6)),
lnline=Line(offset=62.89, slope=0.7618),
),
weather_filter_seasons=[
# Just one season for the S. hemisphere.
WeatherFilterParamsForSeason(
start_month=1,
end_month=12,
weather_filter_params=WeatherFilterParams(
wintrc=85.13,
wslope=0.5379,
wxlimt=18.596,
),
),
],
)

BOOTSTRAP_PARAMS_INITIAL_AMSRE_NORTH = dict(
bt_wtp_v37=GODDARD_AMSRE_NORTH_PARAMS["vh37_params"].water_tie_point_set[0],
bt_wtp_h37=GODDARD_AMSRE_NORTH_PARAMS["vh37_params"].water_tie_point_set[1],
bt_wtp_v19=GODDARD_AMSRE_NORTH_PARAMS["v1937_params"].water_tie_point_set[1],
bt_itp_v37=GODDARD_AMSRE_NORTH_PARAMS["vh37_params"].ice_tie_point_set[0],
bt_itp_h37=GODDARD_AMSRE_NORTH_PARAMS["vh37_params"].ice_tie_point_set[1],
bt_itp_v19=GODDARD_AMSRE_NORTH_PARAMS["v1937_params"].ice_tie_point_set[1],
vh37_lnline=GODDARD_AMSRE_NORTH_PARAMS["vh37_params"].lnline,
v1937_lnline=GODDARD_AMSRE_NORTH_PARAMS["v1937_params"].lnline,
weather_filter_seasons=[
# November through April (`seas=1` in `boot_ice_amsru2_np.f`)
WeatherFilterParamsForSeason(
start_month=11,
end_month=4,
weather_filter_params=WeatherFilterParams(
wintrc=84.73,
wslope=0.5352,
wxlimt=13.7,
),
),
# May (`seas=2`) will get interpolated from the previous and next season
# June through Sept. (`seas=3`)
WeatherFilterParamsForSeason(
start_month=6,
end_month=9,
weather_filter_params=WeatherFilterParams(
wintrc=82.71,
wslope=0.5352,
wxlimt=21.7,
),
),
# October (`seas=4`) will get interpolated from the previous and next
# (first in this list) season.
],
)

BOOTSTRAP_PARAMS_INITIAL_AMSRE_SOUTH = dict(
bt_wtp_v37=GODDARD_AMSRE_SOUTH_PARAMS["vh37_params"].water_tie_point_set[0],
bt_wtp_h37=GODDARD_AMSRE_SOUTH_PARAMS["vh37_params"].water_tie_point_set[1],
bt_wtp_v19=GODDARD_AMSRE_SOUTH_PARAMS["v1937_params"].water_tie_point_set[1],
bt_itp_v37=GODDARD_AMSRE_SOUTH_PARAMS["vh37_params"].ice_tie_point_set[0],
bt_itp_h37=GODDARD_AMSRE_SOUTH_PARAMS["vh37_params"].ice_tie_point_set[1],
bt_itp_v19=GODDARD_AMSRE_SOUTH_PARAMS["v1937_params"].ice_tie_point_set[1],
vh37_lnline=GODDARD_AMSRE_SOUTH_PARAMS["vh37_params"].lnline,
v1937_lnline=GODDARD_AMSRE_SOUTH_PARAMS["v1937_params"].lnline,
weather_filter_seasons=[
# Just one season for the S. hemisphere.
WeatherFilterParamsForSeason(
start_month=1,
end_month=12,
weather_filter_params=WeatherFilterParams(
wintrc=85.13,
wslope=0.5379,
wxlimt=14.3,
),
),
], # noqa (ignore "not used" flake8 warning)
)


CDR_AMSRE_NORTH_PARAMS = GODDARD_AMSRE_NORTH_PARAMS.copy()
_bt_north_weather_filter_seasons = BOOTSTRAP_PARAMS_INITIAL_AMSRE_NORTH[
"weather_filter_seasons"
]
_bt_north_weather_filter_seasons = cast(
list[WeatherFilterParamsForSeason], _bt_north_weather_filter_seasons
)
CDR_AMSRE_NORTH_PARAMS["weather_filter_seasons"] = _bt_north_weather_filter_seasons

CDR_AMSRE_SOUTH_PARAMS = GODDARD_AMSRE_SOUTH_PARAMS.copy()
_bt_south_weather_filter_seasons = BOOTSTRAP_PARAMS_INITIAL_AMSRE_SOUTH[
"weather_filter_seasons"
]
_bt_south_weather_filter_seasons = cast(
list[WeatherFilterParamsForSeason], _bt_south_weather_filter_seasons
)
CDR_AMSRE_SOUTH_PARAMS["weather_filter_seasons"] = _bt_south_weather_filter_seasons


def get_amsre_params(
*,
hemisphere: Hemisphere,
) -> BootstrapParams:
bt_params = BootstrapParams(
**(CDR_AMSRE_NORTH_PARAMS if hemisphere == "north" else CDR_AMSRE_SOUTH_PARAMS),
)

return bt_params


def get_ausi_amsre_bootstrap_params(
*,
date: dt.date,
satellite: str,
gridid: str,
) -> dict:
"""Assign the bootstrap parameters for this date, sat, grid."""
hemisphere = get_gridid_hemisphere(gridid)
if satellite == "amsre":
if hemisphere == "north":
initial_bt_params = BOOTSTRAP_PARAMS_INITIAL_AMSRE_NORTH
elif hemisphere == "south":
initial_bt_params = BOOTSTRAP_PARAMS_INITIAL_AMSRE_SOUTH
else:
raise ValueError(
"Could not initialize Bootstrap params for:\n"
f"satellite: {satellite}\n hemisphere: {hemisphere}"
)
else:
raise ValueError(
f"Bootstrap params not yet defined for:\n satellite: {satellite}"
)

bt_params = setup_bootstrap_params_dict(
initial_params_dict=initial_bt_params, date=date
)

return bt_params
Loading
Loading