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')