diff --git a/changelog/150.feature.3.rst b/changelog/150.feature.3.rst new file mode 100644 index 00000000..69cf4b95 --- /dev/null +++ b/changelog/150.feature.3.rst @@ -0,0 +1 @@ +Updated `~.get_response` to enforce ``ccd_temperature`` as an `astropy.units.Quantity` diff --git a/changelog/150.feature.rst b/changelog/150.feature.rst new file mode 100644 index 00000000..69cf4b95 --- /dev/null +++ b/changelog/150.feature.rst @@ -0,0 +1 @@ +Updated `~.get_response` to enforce ``ccd_temperature`` as an `astropy.units.Quantity` diff --git a/sunkit_instruments/suvi/suvi.py b/sunkit_instruments/suvi/suvi.py index a1c4c822..1955a26a 100644 --- a/sunkit_instruments/suvi/suvi.py +++ b/sunkit_instruments/suvi/suvi.py @@ -100,8 +100,8 @@ def despike_l1b_array(data, dqf, filter_width=7): """ return _despike(data, dqf, filter_width) - -def get_response(request, spacecraft=16, ccd_temperature=-60.0, exposure_type="long"): +@u.quantity_input(ccd_temperature=u.deg_C) +def get_response(request, spacecraft=16, ccd_temperature=-60.0 * u.deg_C, exposure_type="long"): """ Get the SUVI instrument response for a specific wavelength channel, spacecraft, CCD temperature, and exposure type. @@ -113,13 +113,13 @@ def get_response(request, spacecraft=16, ccd_temperature=-60.0, exposure_type="l Parameters ---------- - request: `str` or {94 | 131 | 171 | 195 | 284 | 304}. + request: `str` or {94, 131, 171, 195, 284, 304} Either an L1b filename (FITS or netCDF), or an integer specifying the wavelength channel. spacecraft: `int`, optional. Which GOES spacecraft, default is 16. - ccd_temperature: `float`, optional. - The CCD temperature, in degrees Celsius, default is -60. + ccd_temperature: `astropy.units.Quantity` + The CCD temperature, in degrees Celsius, default is ``-60.0 * u.deg_C``. Needed for getting the correct gain number. exposure_type: {"long" | "short" | "short_flare"}, optional. The exposure type of the SUVI image. @@ -156,7 +156,8 @@ def get_response(request, spacecraft=16, ccd_temperature=-60.0, exposure_type="l header, _, _ = read_suvi(request) wavelength_channel = int(header["WAVELNTH"]) spacecraft = int(header["TELESCOP"].replace(" ", "").replace("G", "")) - ccd_temperature = (header["CCD_TMP1"] + header["CCD_TMP2"]) / 2.0 + ccd_temp_avg = (header["CCD_TMP1"] + header["CCD_TMP2"]) / 2.0 + ccd_temperature = ccd_temp_avg * u.deg_C exposure_type = "_".join( header["SCI_OBJ"].replace(" ", "").split(sep="_")[3:] ).replace("_exposure", "") @@ -195,7 +196,7 @@ def get_response(request, spacecraft=16, ccd_temperature=-60.0, exposure_type="l temp_x = gain_table[:, 0] gain_y = gain_table[:, 1] gain_vs_temp = interpolate.interp1d(temp_x, gain_y) - gain = gain_vs_temp(ccd_temperature) + gain = gain_vs_temp(ccd_temperature.to(u.deg_C).value) geometric_area = 19.362316 * u.cm * u.cm solid_angle = ((2.5 / 3600.0 * (np.pi / 180.0)) ** 2.0) * u.sr @@ -210,7 +211,7 @@ def get_response(request, spacecraft=16, ccd_temperature=-60.0, exposure_type="l "response": response, "wavelength_channel": wavelength_channel, "spacecraft": "GOES-" + str(spacecraft), - "ccd_temperature": ccd_temperature * u.deg_C, + "ccd_temperature": ccd_temperature, "exposure_type": exposure_type, "flight_model": FLIGHT_MODEL[spacecraft], "gain": float(gain), diff --git a/sunkit_instruments/suvi/tests/test_suvi.py b/sunkit_instruments/suvi/tests/test_suvi.py index 1a6657b4..9abf9910 100644 --- a/sunkit_instruments/suvi/tests/test_suvi.py +++ b/sunkit_instruments/suvi/tests/test_suvi.py @@ -1,9 +1,10 @@ import numpy as np import pytest +import astropy.units as u + from sunkit_instruments import suvi -# Test files are all remote data. pytestmark = pytest.mark.remote_data @@ -24,15 +25,31 @@ def test_suvi_despiking_nc(L1B_NC): def test_get_response_nc(L1B_NC): + header, _, _ = suvi.read_suvi(L1B_NC) l1b_nc_response = suvi.get_response(L1B_NC) assert l1b_nc_response["wavelength_channel"] == 171 + assert l1b_nc_response["ccd_temperature"] == (header["CCD_TMP1"] + header["CCD_TMP2"]) / 2.0 * u.deg_C def test_get_response_fits(L1B_FITS): + header, _, _ = suvi.read_suvi(L1B_FITS) l1b_fits_response = suvi.get_response(L1B_FITS) assert l1b_fits_response["wavelength_channel"] == 171 + assert l1b_fits_response["ccd_temperature"] == (header["CCD_TMP1"] + header["CCD_TMP2"]) / 2.0 * u.deg_C def test_get_response_wavelength(): response_195 = suvi.get_response(195) assert response_195["wavelength_channel"] == 195 + + +def test_get_response_explicit_temperature(): + temp = -70.0 * u.deg_C + response = suvi.get_response(195, ccd_temperature=temp) + assert response["ccd_temperature"] == temp + + +def test_get_response_invalid_temperature(): + temp = -70.0 # Without units + with pytest.raises(TypeError): + suvi.get_response(195, ccd_temperature=temp)