def test_rsr_integral(self): """Test calculating the integral of the relative spectral response function. """ with patch('pyspectral.radiance_tb_conversion.RelativeSpectralResponse' ) as mymock: instance = mymock.return_value instance.rsr = TEST_RSR instance.unit = '1e-6 m' instance.si_scale = 1e-6 refl37 = Calculator('EOS-Aqua', 'modis', '20') expected = 1.8563451e-07 # unit = 'm' (meter) self.assertAlmostEqual(refl37.rsr_integral, expected) with patch('pyspectral.radiance_tb_conversion.RelativeSpectralResponse' ) as mymock: instance = mymock.return_value instance.rsr = TEST_RSR_WN instance.unit = 'cm-1' instance.si_scale = 100. refl37 = Calculator('EOS-Aqua', 'modis', '20', wavespace='wavenumber') expected = 13000.385 # SI units = 'm-1' (1/meter) res = refl37.rsr_integral self.assertAlmostEqual(res / expected, 1.0, 6)
def test_reflectance(self): """Test the derivation of the reflective part of a 3.7 micron band""" with patch('pyspectral.radiance_tb_conversion.RelativeSpectralResponse' ) as mymock: instance = mymock.return_value instance.rsr = TEST_RSR instance.unit = '1e-6 m' instance.si_scale = 1e-6 with self.assertRaises(NotImplementedError): dummy = Calculator('Suomi-NPP', 'viirs', 10.8) refl37 = Calculator('Suomi-NPP', 'viirs', 3.7) self.assertEqual(refl37.bandwavelength, 3.7) self.assertEqual(refl37.bandname, '20') with patch('pyspectral.radiance_tb_conversion.RelativeSpectralResponse' ) as mymock: instance = mymock.return_value instance.rsr = TEST_RSR instance.unit = '1e-6 m' instance.si_scale = 1e-6 refl37 = Calculator('EOS-Aqua', 'modis', '20') sunz = np.array([80.]) tb3 = np.array([290.]) tb4 = np.array([282.]) refl = refl37.reflectance_from_tbs(sunz, tb3, tb4) self.assertAlmostEqual(refl.data[0], 0.251245010648, 6) tb3x = refl37.emissive_part_3x() self.assertAlmostEqual(tb3x, 276.213054, 6) sunz = np.array([80.]) tb3 = np.array([295.]) tb4 = np.array([282.]) refl = refl37.reflectance_from_tbs(sunz, tb3, tb4) self.assertAlmostEqual(refl.data[0], 0.452497961, 6) tb3x = refl37.emissive_part_3x() self.assertAlmostEqual(tb3x, 270.077268, 6) sunz = np.array([50.]) tb3 = np.array([300.]) tb4 = np.array([285.]) refl = refl37.reflectance_from_tbs(sunz, tb3, tb4) self.assertAlmostEqual(refl.data[0], 0.1189217, 6) tb3x = refl37.emissive_part_3x() self.assertAlmostEqual(tb3x, 282.455426, 6)
def get_reflectance(self, tb11, sun_zenith=None, tb13_4=None): """Get the reflectance part of an NIR channel""" try: from pyspectral.near_infrared_reflectance import Calculator except ImportError: LOG.info("Couldn't load pyspectral") # Check the wavelength, and if outside 3-4 microns this functionality # doesn't give any meaning and should not be supported if (self.wavelength_range[1] < 3.0 or self.wavelength_range[1] > 4.0): LOG.warning("Deriving the near infrared reflectance" + " of a band that is outside the 3-4 micron range" + " is not supported!\n\tWill do nothing...") return # Check if the sun-zenith angle was provided: if sun_zenith is None: lonlats = self.area.get_lonlats() sun_zenith = sza(self.info['time'], lonlats[0], lonlats[1]) try: refl39 = Calculator(self.info['satname'] + self.info['satnumber'], self.info['instrument_name'], self.name) except NameError: LOG.warning("pyspectral missing!") return return refl39.reflectance_from_tbs(sun_zenith, self.data, tb11, tb_ir_co2=tb13_4)
def _init_refl3x(self, projectables): """Initiate the 3.x reflectance derivations """ try: from pyspectral.near_infrared_reflectance import Calculator except ImportError: LOG.info("Couldn't load pyspectral") raise _nir, _tb11 = projectables self._refl3x = Calculator(_nir.attrs['platform_name'], _nir.attrs['sensor'], _nir.attrs['name'])
def _init_reflectance_calculator(self, metadata): """Initialize the 3.x reflectance derivations.""" if not Calculator: logger.info("Couldn't load pyspectral") raise ImportError( "No module named pyspectral.near_infrared_reflectance") reflectance_3x_calculator = Calculator( metadata['platform_name'], metadata['sensor'], metadata['name'], sunz_threshold=self.sun_zenith_threshold, masking_limit=self.masking_limit) return reflectance_3x_calculator
def __call__(self, projectables, optional_datasets=None, **info): """Get the reflectance part of an NIR channel. Not supposed to be used for wavelength outside [3, 4] µm. """ try: from pyspectral.near_infrared_reflectance import Calculator except ImportError: LOG.info("Couldn't load pyspectral") raise nir, tb11 = projectables LOG.info('Getting reflective part of %s', nir.info['name']) sun_zenith = None tb13_4 = None for dataset in optional_datasets: if (dataset.info['units'] == 'K' and "wavelengh" in dataset.info and dataset.info["wavelength"][0] <= 13.4 <= dataset.info["wavelength"][2]): tb13_4 = dataset elif dataset.info["standard_name"] == "solar_zenith_angle": sun_zenith = dataset # Check if the sun-zenith angle was provided: if sun_zenith is None: from pyorbital.astronomy import sun_zenith_angle as sza lons, lats = nir.info["area"].get_lonlats() sun_zenith = sza(nir.info['start_time'], lons, lats) refl39 = Calculator(nir.info['platform_name'], nir.info['sensor'], nir.id.wavelength[1]) proj = Dataset( refl39.reflectance_from_tbs(sun_zenith, nir, tb11, tb13_4) * 100, **nir.info) proj.info['units'] = '%' self.apply_modifier_info(nir, proj) return proj
p = Proj(proj='geos', h=sat_h, lon_0=sat_lon, sweep=sat_sweep, a=6378137.0) # Convert map points to latitude and longitude with the magic provided by Pyproj XX, YY = np.meshgrid(X, Y) lons, lats = p(XX, YY, inverse=True) # Get the year month day hour and minute to apply the zenith correction utc_time = datetime(int(year), int(month), int(day), int(hour), int(minutes)) sun_zenith = np.zeros((data1.shape[0], data1.shape[1])) sun_zenith = astronomy.sun_zenith_angle(utc_time, lons, lats) print("Solar Zenith Angle calculus finished") # Calculate the solar component (band 3.7 um) from pyspectral.near_infrared_reflectance import Calculator refl39 = Calculator('GOES-16', 'abi', 'ch7') data1b = refl39.reflectance_from_tbs(sun_zenith, data1, data2) print("Solar Component calculus finished") #------------------------------------------------------------------------------------------------------ #------------------------------------------------------------------------------------------------------ # RGB Components R = data3 G = data4 B = data1b # Minimuns and Maximuns Rmin = 0 Rmax = 1 Gmin = 0 Gmax = 0.7
solar_irr = SolarIrradianceSpectrum(TOTAL_IRRADIANCE_SPECTRUM_2000ASTM, dlambda=0.0005) from pyspectral.rsr_reader import RelativeSpectralResponse seviri = RelativeSpectralResponse('Meteosat-10', 'seviri') sflux = solar_irr.inband_solarflux(seviri.rsr['IR3.9']) ch39 = local_data['IR_039'] ch11 = local_data['IR_108'] ch13 = local_data['IR_134'] lonlats = ch39.area.get_lonlats() from pyorbital.astronomy import sun_zenith_angle sunz = sun_zenith_angle(tslot, lonlats[0], lonlats[1]) print("... create look-up-table") #refl37 = Calculator(rsr) refl37 = Calculator('Meteosat-9', 'seviri', 'IR3.9', solar_flux=sflux) #refl37.make_tb2rad_lut('/tmp/seviri_37_tb2rad_lut.npz') # new syntax -> #refl37.make_tb2rad_lut('IR3.9','/data/COALITION2/database/meteosat/SEVIRI/seviri_tb2rad_lut/') print("... calculate reflectance") r39 = refl37.reflectance_from_tbs(sunz, ch39.data, ch11.data, ch13.data) # , lookuptable='/tmp/seviri_37_tb2rad_lut.npz' import numpy as np r39 = np.ma.masked_array(r39, mask = np.logical_or(np.less(r39, -0.1), np.greater(r39, 3.0))) print("... show new RGB image") from mpop.imageo.geo_image import GeoImage img = GeoImage((local_data[0.8].data, local_data[1.6].data, r39 * 100), area, tslot, crange=((0, 100), (0, 70), (0, 30)), fill_value=(0, 0, 0), mode="RGB")
logging.getLogger("").setLevel(logging.DEBUG) LOG.addHandler(handler) ahi = RelativeSpectralResponse('Himawari-8', 'ahi') solar_irr = SolarIrradianceSpectrum(TOTAL_IRRADIANCE_SPECTRUM_2000ASTM, dlambda=0.005) sflux = solar_irr.inband_solarflux(ahi.rsr['ch7']) LOG.info("Solar flux over Band: " + str(sflux)) # sunz = [80., 80.5] # tb7 = [288.0, 390.0] # tb14 = [282.0, 272.0] # tb16 = [275.0, 269.0] sunz = np.random.rand(5500, 550) * 120. tb7 = np.random.rand(5500, 550) * 120. + 260.0 tb14 = np.random.rand(5500, 550) * 30. + 260.0 tb16 = np.random.rand(5500, 550) * 30. + 250.0 refl38 = Calculator( 'Himawari-8', 'ahi', 'ch7', detector='det-1', solar_flux=sflux, tb2rad_lut_filename='/tmp/tb2rad_lut_himawari_ahi_ir3.9.npz') x = refl38.reflectance_from_tbs(sunz, tb7, tb14) LOG.info("Reflectance: " + str(x[0, 0])) y = refl38.reflectance_from_tbs(sunz, tb7, tb14, tb16) LOG.info("Reflectance - co2 corrected: " + str(y[0, 0]))
def test_reflectance(self): """Test the derivation of the reflective part of a 3.7 micron band.""" with patch('pyspectral.radiance_tb_conversion.RelativeSpectralResponse') as mymock: instance = mymock.return_value # VIIRS doesn't have a channel '20' like MODIS so the generic # mapping this test will end up using will find 'ch20' for VIIRS viirs_rsr = {'ch20': TEST_RSR['20'], '99': TEST_RSR['99']} instance.rsr = viirs_rsr instance.unit = '1e-6 m' instance.si_scale = 1e-6 with self.assertRaises(NotImplementedError): dummy = Calculator('Suomi-NPP', 'viirs', 10.8) del dummy refl37 = Calculator('Suomi-NPP', 'viirs', 3.7) self.assertEqual(refl37.bandwavelength, 3.7) self.assertEqual(refl37.bandname, 'ch20') with patch('pyspectral.radiance_tb_conversion.RelativeSpectralResponse') as mymock: instance = mymock.return_value instance.rsr = TEST_RSR instance.unit = '1e-6 m' instance.si_scale = 1e-6 refl37 = Calculator('EOS-Aqua', 'modis', '20') sunz = np.array([80.]) tb3 = np.array([290.]) tb4 = np.array([282.]) refl = refl37.reflectance_from_tbs(sunz, tb3, tb4) np.testing.assert_allclose(refl[0], 0.251245010648, 6) tb3x = refl37.emissive_part_3x() np.testing.assert_allclose(tb3x, 276.213054, 6) sunz = np.array([80.]) tb3 = np.array([295.]) tb4 = np.array([282.]) refl = refl37.reflectance_from_tbs(sunz, tb3, tb4) np.testing.assert_allclose(refl[0], 0.452497961, 6) tb3x = refl37.emissive_part_3x() np.testing.assert_allclose(tb3x, 270.077268, 6) sunz = np.array([50.]) tb3 = np.array([300.]) tb4 = np.array([285.]) refl = refl37.reflectance_from_tbs(sunz, tb3, tb4) np.testing.assert_allclose(refl[0], 0.1189217, 6) tb3x = refl37.emissive_part_3x() np.testing.assert_allclose(tb3x, 282.455426, 6) sunz = np.array([50.]) tb3 = np.ma.masked_array([300.], mask=False) tb4 = np.ma.masked_array([285.], mask=False) refl = refl37.reflectance_from_tbs(sunz, tb3, tb4) self.assertTrue(hasattr(refl, 'mask')) try: import dask.array as da sunz = da.from_array([50.], chunks=10) tb3 = da.from_array([300.], chunks=10) tb4 = da.from_array([285.], chunks=10) refl = refl37.reflectance_from_tbs(sunz, tb3, tb4) self.assertTrue(hasattr(refl, 'compute')) except ImportError: pass
def test_reflectance(self): """Test the derivation of the reflective part of a 3.7 micron band.""" with patch('pyspectral.radiance_tb_conversion.RelativeSpectralResponse') as mymock: instance = mymock.return_value # VIIRS doesn't have a channel '20' like MODIS so the generic # mapping this test will end up using will find 'ch20' for VIIRS viirs_rsr = {'ch20': TEST_RSR['20'], '99': TEST_RSR['99']} instance.rsr = viirs_rsr instance.unit = '1e-6 m' instance.si_scale = 1e-6 with self.assertRaises(NotImplementedError): dummy = Calculator('Suomi-NPP', 'viirs', 10.8) del dummy refl37 = Calculator('Suomi-NPP', 'viirs', 3.7) self.assertEqual(refl37.bandwavelength, 3.7) self.assertEqual(refl37.bandname, 'ch20') # Default sunz-threshold used to stay on day side and away from terminator: self.assertEqual(refl37.sunz_threshold, 85.0) with patch('pyspectral.radiance_tb_conversion.RelativeSpectralResponse') as mymock: instance = mymock.return_value instance.rsr = TEST_RSR instance.unit = '1e-6 m' instance.si_scale = 1e-6 refl37 = Calculator('EOS-Aqua', 'modis', '20') self.assertEqual(refl37.sunz_threshold, TERMINATOR_LIMIT) self.assertEqual(refl37.masking_limit, TERMINATOR_LIMIT) refl37_sz88 = Calculator('EOS-Aqua', 'modis', '20', sunz_threshold=88.0, masking_limit=None) self.assertEqual(refl37_sz88.sunz_threshold, 88.0) self.assertIsNone(refl37_sz88.masking_limit) self.assertAlmostEqual(refl37_sz88.bandwavelength, 3.780282, 5) self.assertEqual(refl37_sz88.bandname, '20') sunz = 80. tb3 = 290. tb4 = 282. refl = refl37.reflectance_from_tbs(sunz, tb3, tb4) np.testing.assert_allclose(refl[0], 0.251245010648, 6) sunz = 85. tb3 = 290. tb4 = 282. refl = refl37.reflectance_from_tbs(sunz, tb3, tb4) np.testing.assert_allclose(refl[0], 1.12236884, 6) sunz = np.array([85.1]) refl = refl37.reflectance_from_tbs(sunz, tb3, tb4) self.assertTrue(np.isnan(refl[0])) refl_sz88 = refl37_sz88.reflectance_from_tbs(sunz, tb3, tb4) np.testing.assert_allclose(refl_sz88[0], 1.2064644, 6) sunz = np.array([86.0]) self.assertTrue(np.isnan(refl[0])) tb3x = refl37.emissive_part_3x() np.testing.assert_allclose(tb3x, 276.213054, 6) sunz = np.array([80.]) tb3 = np.array([295.]) tb4 = np.array([282.]) refl = refl37.reflectance_from_tbs(sunz, tb3, tb4) np.testing.assert_allclose(refl[0], 0.452497961, 6) tb3x = refl37.emissive_part_3x() np.testing.assert_allclose(tb3x, 270.077268, 6) sunz = np.array([50.]) tb3 = np.array([300.]) tb4 = np.array([285.]) refl = refl37.reflectance_from_tbs(sunz, tb3, tb4) np.testing.assert_allclose(refl[0], 0.1189217, 6) tb3x = refl37.emissive_part_3x() np.testing.assert_allclose(tb3x, 282.455426, 6) sunz = np.array([50.]) tb3 = np.ma.masked_array([300.], mask=False) tb4 = np.ma.masked_array([285.], mask=False) refl = refl37.reflectance_from_tbs(sunz, tb3, tb4) self.assertTrue(hasattr(refl, 'mask')) try: import dask.array as da sunz = da.from_array([50.], chunks=10) tb3 = da.from_array([300.], chunks=10) tb4 = da.from_array([285.], chunks=10) refl = refl37.reflectance_from_tbs(sunz, tb3, tb4) self.assertTrue(hasattr(refl, 'compute')) except ImportError: pass
class CycloneCellFast: __slots__ = [ "image", "i4_reflectance", "gts", "xmin", "xmax", "ymin", "ymax" ] A = 2 / (np.log(0.6 / 0.72)) B = 2 - A * np.log(0.72) from pyspectral.near_infrared_reflectance import Calculator calc = Calculator("Suomi-NPP", "viirs", "I4") def __init__(self, image: "CycloneImageFast", xmin, xmax, ymin, ymax): self.image = image self.xmin = xmin self.xmax = xmax self.ymin = ymin self.ymax = ymax self.i4_reflectance = self.calc.reflectance_from_tbs( self.zenith, self.i4, self.i5) assert not np.isnan(self.i4).all() and not np.isnan(self.i5).all() self.gts = self.glaciation_temperature_percentile() @property def i4(self): return self.image.raw_grid_I4[self.ymin:self.ymax, self.xmin:self.xmax] @property def i5(self): return self.image.raw_grid_I5[self.ymin:self.ymax, self.xmin:self.xmax] @property def zenith(self): return self.image.zenith[self.ymin:self.ymax, self.xmin:self.xmax] @property def satz(self): return self.image.satz[self.ymin:self.ymax, self.xmin:self.xmax] @property def raz(self): return self.image.raz[self.ymin:self.ymax, self.xmin:self.xmax] @property def i5_c(self): return self.i5 - ABSOLUTE_ZERO @property def i5_flat_c(self): return self.i5_flat - ABSOLUTE_ZERO @property def BTD(self): return self.i4_flat - (self.i5_flat) @property def BTD_ratio(self): return (self.i4_flat - (self.i5_flat)) / (self.i5_flat) @property def i4i5ratio(self): return (self.i4_flat) / (self.i5_flat) @property def good_gt(self): return (ABSOLUTE_ZERO - 45 < self.gt.value < ABSOLUTE_ZERO) and self.gt.error < 5 def bin_data_percentiles(self, percentiles, i4_band=None): i4_list, i5_list = [], [] if i4_band is None: i4_band = self.i4_flat gt_fit = GTFit(i4_band, self.i5_flat) for p in percentiles: i5, i4 = gt_fit.bin_data(np.percentile, 1, (p, )) i4_list.append(i4) i5_list.append(i5) return i4_list, i5_list def intersects(self, cell: "CycloneCellFast"): if cell is self: return True return cell.xmax > self.xmin and self.xmax > cell.xmin and self.ymax > cell.ymin and cell.ymax > self.ymin def plot(self, fig, ax, show=True): ax.imshow(self.i5) if show: plt.show() def plot_profile(self): fig, ax = plt.subplots(1, 2) self.plot(fig, ax[0], show=False) gt_fit = GTFit(self.i4_flat, self.i5_flat) gt_fit.piecewise_percentile(5, fig, ax[1]) plt.show() @property def gt(self): return self.gts[0][0] @property def gt_i4(self): return self.gts[0][1] @property def r2(self): return self.gts[0][2] @property def i4_flat(self): return self.i4[~np.isnan(self.i4)].flatten() @property def i4_reflectance_flat(self): return self.i4_reflectance[~np.isnan(self.i4_reflectance)].flatten() @property def i5_flat(self): return self.i5[~np.isnan(self.i5)].flatten() def glaciation_temperature_percentile(self, percentiles=(5, 50, 95)): gt_fit = GTFit(self.i4_reflectance_flat, self.i5_flat) return gt_fit.piecewise_percentile_multiple(percentiles, units="kelvin", i4_units="reflectance") def re(self, nan_out_of_range=False): from inspect_nc import get_re return np.array([[ get_re(self.i4_reflectance[y, x], self.satz[y, x], self.zenith[y, x], np.abs(self.raz[y, x]), nan_out_of_range=nan_out_of_range) for x in range(self.xmax - self.xmin) ] for y in range(self.ymax - self.ymin)])