def setUp(self, xr_): """Set up the tests.""" from satpy.readers.goes_imager_nc import GOESNCFileHandler, CALIB_COEFS self.coefs = CALIB_COEFS['GOES-15'] self.all_coefs = CALIB_COEFS self.channels = sorted(self.coefs.keys()) self.ir_channels = sorted([ch for ch in self.channels if not GOESNCFileHandler._is_vis(ch)]) self.vis_channels = sorted([ch for ch in self.channels if GOESNCFileHandler._is_vis(ch)]) # Mock file access to return a fake dataset. Choose a medium count value # (100) to avoid elements being masked due to invalid # radiance/reflectance/BT nrows = ncols = 300 self.counts = 100 * 32 * np.ones((1, nrows, ncols)) # emulate 10-bit self.lon = np.zeros((nrows, ncols)) # Dummy self.lat = np.repeat(np.linspace(-150, 150, nrows), ncols).reshape( nrows, ncols) # Includes invalid values to be masked xr_.open_dataset.return_value = xr.Dataset( {'data': xr.DataArray(data=self.counts, dims=('time', 'yc', 'xc')), 'lon': xr.DataArray(data=self.lon, dims=('yc', 'xc')), 'lat': xr.DataArray(data=self.lat, dims=('yc', 'xc')), 'time': xr.DataArray(data=np.array([0], dtype='datetime64[ms]'), dims=('time',)), 'bands': xr.DataArray(data=np.array([1]))}, attrs={'Satellite Sensor': 'G-15'}) # Instantiate reader using the mocked open_dataset() method self.reader = GOESNCFileHandler(filename='dummy', filename_info={}, filetype_info={})
class GOESNCFileHandlerTest(unittest.TestCase): """Test the file handler.""" longMessage = True @mock.patch('satpy.readers.goes_imager_nc.xr') def setUp(self, xr_): """Set up the tests.""" from satpy.readers.goes_imager_nc import CALIB_COEFS, GOESNCFileHandler self.coefs = CALIB_COEFS['GOES-15'] self.all_coefs = CALIB_COEFS self.channels = sorted(self.coefs.keys()) self.ir_channels = sorted( [ch for ch in self.channels if not GOESNCFileHandler._is_vis(ch)]) self.vis_channels = sorted( [ch for ch in self.channels if GOESNCFileHandler._is_vis(ch)]) # Mock file access to return a fake dataset. Choose a medium count value # (100) to avoid elements being masked due to invalid # radiance/reflectance/BT nrows = ncols = 300 self.counts = 100 * 32 * np.ones((1, nrows, ncols)) # emulate 10-bit self.lon = np.zeros((nrows, ncols)) # Dummy self.lat = np.repeat(np.linspace(-150, 150, nrows), ncols).reshape( nrows, ncols) # Includes invalid values to be masked xr_.open_dataset.return_value = xr.Dataset( { 'data': xr.DataArray(data=self.counts, dims=('time', 'yc', 'xc')), 'lon': xr.DataArray(data=self.lon, dims=('yc', 'xc')), 'lat': xr.DataArray(data=self.lat, dims=('yc', 'xc')), 'time': xr.DataArray(data=np.array([0], dtype='datetime64[ms]'), dims=('time', )), 'bands': xr.DataArray(data=np.array([1])) }, attrs={'Satellite Sensor': 'G-15'}) # Instantiate reader using the mocked open_dataset() method self.reader = GOESNCFileHandler(filename='dummy', filename_info={}, filetype_info={}) def test_get_dataset_coords(self): """Test whether coordinates returned by get_dataset() are correct.""" lon = self.reader.get_dataset(key=make_dataid(name='longitude'), info={}) lat = self.reader.get_dataset(key=make_dataid(name='latitude'), info={}) # ... this only compares the valid (unmasked) elements self.assertTrue(np.all(lat.to_masked_array() == self.lat), msg='get_dataset() returns invalid latitude') self.assertTrue(np.all(lon.to_masked_array() == self.lon), msg='get_dataset() returns invalid longitude') def test_get_dataset_counts(self): """Test whether counts returned by get_dataset() are correct.""" from satpy.readers.goes_imager_nc import ALTITUDE, UNKNOWN_SECTOR self.reader.meta.update({ 'lon0': -75.0, 'lat0': 0.0, 'sector': UNKNOWN_SECTOR, 'nadir_row': 1, 'nadir_col': 2, 'area_def_uni': 'some_area' }) attrs_exp = { 'orbital_parameters': { 'projection_longitude': -75.0, 'projection_latitude': 0.0, 'projection_altitude': ALTITUDE, 'yaw_flip': True }, 'platform_name': 'GOES-15', 'sensor': 'goes_imager', 'sector': UNKNOWN_SECTOR, 'nadir_row': 1, 'nadir_col': 2, 'area_def_uniform_sampling': 'some_area' } for ch in self.channels: counts = self.reader.get_dataset(key=make_dataid( name=ch, calibration='counts'), info={}) # ... this only compares the valid (unmasked) elements self.assertTrue(np.all(self.counts / 32. == counts.to_masked_array()), msg='get_dataset() returns invalid counts for ' 'channel {}'.format(ch)) # Check attributes self.assertDictEqual(counts.attrs, attrs_exp) def test_get_dataset_masks(self): """Test whether data and coordinates are masked consistently.""" # Requires that no element has been masked due to invalid # radiance/reflectance/BT (see setUp()). lon = self.reader.get_dataset(key=make_dataid(name='longitude'), info={}) lon_mask = lon.to_masked_array().mask for ch in self.channels: for calib in ('counts', 'radiance', 'reflectance', 'brightness_temperature'): try: data = self.reader.get_dataset(key=make_dataid( name=ch, calibration=calib), info={}) except ValueError: continue data_mask = data.to_masked_array().mask self.assertTrue(np.all(data_mask == lon_mask), msg='get_dataset() returns inconsistently ' 'masked {} in channel {}'.format(calib, ch)) def test_get_dataset_invalid(self): """Test handling of invalid calibrations.""" # VIS -> BT args = dict(key=make_dataid(name='00_7', calibration='brightness_temperature'), info={}) self.assertRaises(ValueError, self.reader.get_dataset, **args) # IR -> Reflectance args = dict(key=make_dataid(name='10_7', calibration='reflectance'), info={}) self.assertRaises(ValueError, self.reader.get_dataset, **args) # Unsupported calibration with pytest.raises(ValueError): args = dict(key=make_dataid(name='10_7', calibration='invalid'), info={}) def test_calibrate(self): """Test whether the correct calibration methods are called.""" for ch in self.channels: if self.reader._is_vis(ch): calibs = { 'radiance': '_viscounts2radiance', 'reflectance': '_calibrate_vis' } else: calibs = { 'radiance': '_ircounts2radiance', 'brightness_temperature': '_calibrate_ir' } for calib, method in calibs.items(): with mock.patch.object(self.reader, method) as target_func: self.reader.calibrate(counts=self.reader.nc['data'], calibration=calib, channel=ch) target_func.assert_called() def test_get_sector(self): """Test sector identification.""" from satpy.readers.goes_imager_nc import ( FULL_DISC, NORTH_HEMIS_EAST, NORTH_HEMIS_WEST, SOUTH_HEMIS_EAST, SOUTH_HEMIS_WEST, UNKNOWN_SECTOR, ) shapes_vis = { (10800, 20754): FULL_DISC, (7286, 13900): NORTH_HEMIS_EAST, (2301, 13840): SOUTH_HEMIS_EAST, (5400, 13200): NORTH_HEMIS_WEST, (4300, 11090): SOUTH_HEMIS_WEST, (123, 456): UNKNOWN_SECTOR } shapes_ir = { (2700, 5200): FULL_DISC, (1850, 3450): NORTH_HEMIS_EAST, (600, 3500): SOUTH_HEMIS_EAST, (1310, 3300): NORTH_HEMIS_WEST, (1099, 2800): SOUTH_HEMIS_WEST, (123, 456): UNKNOWN_SECTOR } shapes = shapes_ir.copy() shapes.update(shapes_vis) for (nlines, ncols), sector_ref in shapes.items(): if (nlines, ncols) in shapes_vis: channel = '00_7' else: channel = '10_7' sector = self.reader._get_sector(channel=channel, nlines=nlines, ncols=ncols) self.assertEqual(sector, sector_ref, msg='Incorrect sector identification')