#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2019 Satpy developers
#
# This file is part of satpy.
#
# satpy is free software: you can redistribute it and/or modify it under the
# terms of the GNU General Public License as published by the Free Software
# Foundation, either version 3 of the License, or (at your option) any later
# version.
#
# satpy is distributed in the hope that it will be useful, but WITHOUT ANY
# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along with
# satpy. If not, see <http://www.gnu.org/licenses/>.
"""Tests for the 'fci_l1c_nc' reader."""
import logging
import os
from unittest import mock
import dask.array as da
import numpy as np
import numpy.testing
import pytest
import xarray as xr
from satpy.tests.reader_tests.test_netcdf_utils import FakeNetCDF4FileHandler
[docs]class FakeNetCDF4FileHandler2(FakeNetCDF4FileHandler):
"""Class for faking the NetCDF4 Filehandler."""
def _get_test_calib_for_channel_ir(self, chroot, meas):
from pyspectral.blackbody import C_SPEED as c
from pyspectral.blackbody import H_PLANCK as h
from pyspectral.blackbody import K_BOLTZMANN as k
xrda = xr.DataArray
data = {}
data[meas + "/radiance_to_bt_conversion_coefficient_wavenumber"] = xrda(955)
data[meas + "/radiance_to_bt_conversion_coefficient_a"] = xrda(1)
data[meas + "/radiance_to_bt_conversion_coefficient_b"] = xrda(0.4)
data[meas + "/radiance_to_bt_conversion_constant_c1"] = xrda(1e11 * 2 * h * c ** 2)
data[meas + "/radiance_to_bt_conversion_constant_c2"] = xrda(1e2 * h * c / k)
return data
def _get_test_calib_for_channel_vis(self, chroot, meas):
xrda = xr.DataArray
data = {}
data["state/celestial/earth_sun_distance"] = xrda(da.repeat(da.array([149597870.7]), 6000))
data[meas + "/channel_effective_solar_irradiance"] = xrda(50)
return data
def _get_test_content_for_channel(self, pat, ch):
xrda = xr.DataArray
nrows = 200
ncols = 11136
chroot = "data/{:s}"
meas = chroot + "/measured"
rad = meas + "/effective_radiance"
qual = meas + "/pixel_quality"
index_map = meas + "/index_map"
rad_conv_coeff = meas + "/radiance_unit_conversion_coefficient"
pos = meas + "/{:s}_position_{:s}"
shp = rad + "/shape"
x = meas + "/x"
y = meas + "/y"
data = {}
ch_str = pat.format(ch)
ch_path = rad.format(ch_str)
common_attrs = {
"scale_factor": 5,
"add_offset": 10,
"long_name": "Effective Radiance",
"units": "mW.m-2.sr-1.(cm-1)-1",
"ancillary_variables": "pixel_quality"
}
if ch == 38:
fire_line = da.ones((1, ncols), dtype="uint16", chunks=1024) * 5000
data_without_fires = da.ones((nrows - 1, ncols), dtype="uint16", chunks=1024)
d = xrda(
da.concatenate([fire_line, data_without_fires], axis=0),
dims=("y", "x"),
attrs={
"valid_range": [0, 8191],
"warm_scale_factor": 2,
"warm_add_offset": -300,
**common_attrs
}
)
else:
d = xrda(
da.ones((nrows, ncols), dtype="uint16", chunks=1024),
dims=("y", "x"),
attrs={
"valid_range": [0, 4095],
"warm_scale_factor": 1,
"warm_add_offset": 0,
**common_attrs
}
)
data[ch_path] = d
data[x.format(ch_str)] = xrda(
da.arange(1, ncols + 1, dtype="uint16"),
dims=("x",),
attrs={
"scale_factor": -5.58877772833e-05,
"add_offset": 0.155619515845,
}
)
data[y.format(ch_str)] = xrda(
da.arange(1, nrows + 1, dtype="uint16"),
dims=("y",),
attrs={
"scale_factor": -5.58877772833e-05,
"add_offset": 0.155619515845,
}
)
data[qual.format(ch_str)] = xrda(
da.arange(nrows * ncols, dtype="uint8").reshape(nrows, ncols) % 128,
dims=("y", "x"))
# add dummy data for index map starting from 100
data[index_map.format(ch_str)] = xrda(
(da.arange(nrows * ncols, dtype="uint16").reshape(nrows, ncols) % 6000) + 100,
dims=("y", "x"))
data[rad_conv_coeff.format(ch_str)] = xrda(1234.56)
data[pos.format(ch_str, "start", "row")] = xrda(0)
data[pos.format(ch_str, "start", "column")] = xrda(0)
data[pos.format(ch_str, "end", "row")] = xrda(nrows)
data[pos.format(ch_str, "end", "column")] = xrda(ncols)
if pat.startswith("ir") or pat.startswith("wv"):
data.update(self._get_test_calib_for_channel_ir(chroot.format(ch_str),
meas.format(ch_str)))
elif pat.startswith("vis") or pat.startswith("nir"):
data.update(self._get_test_calib_for_channel_vis(chroot.format(ch_str),
meas.format(ch_str)))
data[shp.format(ch_str)] = (nrows, ncols)
return data
def _get_test_content_all_channels(self):
chan_patterns = {
"vis_{:>02d}": (4, 5, 6, 8, 9),
"nir_{:>02d}": (13, 16, 22),
"ir_{:>02d}": (38, 87, 97, 105, 123, 133),
"wv_{:>02d}": (63, 73),
}
data = {}
for pat in chan_patterns:
for ch_num in chan_patterns[pat]:
data.update(self._get_test_content_for_channel(pat, ch_num))
return data
def _get_test_content_areadef(self):
data = {}
proj = "data/mtg_geos_projection"
attrs = {
"sweep_angle_axis": "y",
"perspective_point_height": "35786400.0",
"semi_major_axis": "6378137.0",
"longitude_of_projection_origin": "0.0",
"inverse_flattening": "298.257223563",
"units": "m"}
data[proj] = xr.DataArray(
0,
dims=(),
attrs=attrs)
# also set attributes cached, as this may be how they are accessed with
# the NetCDF4FileHandler
for (k, v) in attrs.items():
data[proj + "/attr/" + k] = v
return data
def _get_test_content_aux_data(self):
from satpy.readers.fci_l1c_nc import AUX_DATA
xrda = xr.DataArray
data = {}
indices_dim = 6000
for key, value in AUX_DATA.items():
# skip population of earth_sun_distance as this is already defined for reflectance calculation
if key == 'earth_sun_distance':
continue
data[value] = xrda(da.arange(indices_dim, dtype="float32"), dims=("index"))
# compute the last data entry to simulate the FCI caching
data[list(AUX_DATA.values())[-1]] = data[list(AUX_DATA.values())[-1]].compute()
data['index'] = xrda(da.arange(indices_dim, dtype="uint16")+100, dims=("index"))
return data
def _get_global_attributes(self):
data = {}
attrs = {"platform": "MTI1"}
for (k, v) in attrs.items():
data["/attr/" + k] = v
return data
[docs] def get_test_content(self, filename, filename_info, filetype_info):
"""Get the content of the test data."""
# mock global attributes
# - root groups global
# - other groups global
# mock data variables
# mock dimensions
#
# ... but only what satpy is using ...
D = {}
D.update(self._get_test_content_all_channels())
D.update(self._get_test_content_areadef())
D.update(self._get_test_content_aux_data())
D.update(self._get_global_attributes())
return D
[docs]class FakeNetCDF4FileHandler3(FakeNetCDF4FileHandler2):
"""Mock bad data."""
def _get_test_calib_for_channel_ir(self, chroot, meas):
from netCDF4 import default_fillvals
v = xr.DataArray(default_fillvals["f4"])
data = {}
data[meas + "/radiance_to_bt_conversion_coefficient_wavenumber"] = v
data[meas + "/radiance_to_bt_conversion_coefficient_a"] = v
data[meas + "/radiance_to_bt_conversion_coefficient_b"] = v
data[meas + "/radiance_to_bt_conversion_constant_c1"] = v
data[meas + "/radiance_to_bt_conversion_constant_c2"] = v
return data
def _get_test_calib_for_channel_vis(self, chroot, meas):
data = super()._get_test_calib_for_channel_vis(chroot, meas)
from netCDF4 import default_fillvals
v = xr.DataArray(default_fillvals["f4"])
data[meas + "/channel_effective_solar_irradiance"] = v
return data
[docs]class FakeNetCDF4FileHandler4(FakeNetCDF4FileHandler2):
"""Mock bad data for IDPF TO-DO's."""
def _get_test_calib_for_channel_vis(self, chroot, meas):
data = super()._get_test_calib_for_channel_vis(chroot, meas)
data["state/celestial/earth_sun_distance"] = xr.DataArray(da.repeat(da.array([30000000]), 6000))
return data
def _get_test_content_all_channels(self):
data = super()._get_test_content_all_channels()
data['data/vis_04/measured/x'].attrs['scale_factor'] *= -1
data['data/vis_04/measured/x'].attrs['scale_factor'] = \
np.float32(data['data/vis_04/measured/x'].attrs['scale_factor'])
data['data/vis_04/measured/x'].attrs['add_offset'] = \
np.float32(data['data/vis_04/measured/x'].attrs['add_offset'])
data['data/vis_04/measured/y'].attrs['scale_factor'] = \
np.float32(data['data/vis_04/measured/y'].attrs['scale_factor'])
data['data/vis_04/measured/y'].attrs['add_offset'] = \
np.float32(data['data/vis_04/measured/y'].attrs['add_offset'])
return data
[docs]@pytest.fixture
def reader_configs():
"""Return reader configs for FCI."""
from satpy._config import config_search_paths
return config_search_paths(
os.path.join("readers", "fci_l1c_nc.yaml"))
def _get_reader_with_filehandlers(filenames, reader_configs):
from satpy.readers import load_reader
reader = load_reader(reader_configs)
loadables = reader.select_files_from_pathnames(filenames)
reader.create_filehandlers(loadables)
return reader
[docs]class TestFCIL1cNCReader:
"""Initialize the unittest TestCase for the FCI L1c NetCDF Reader."""
yaml_file = "fci_l1c_nc.yaml"
_alt_handler = FakeNetCDF4FileHandler2
[docs] @pytest.fixture(autouse=True, scope="class")
def fake_handler(self):
"""Wrap NetCDF4 FileHandler with our own fake handler."""
# implementation strongly inspired by test_viirs_l1b.py
from satpy.readers.fci_l1c_nc import FCIL1cNCFileHandler
p = mock.patch.object(
FCIL1cNCFileHandler,
"__bases__",
(self._alt_handler,))
with p:
p.is_local = True
yield p
[docs]class TestFCIL1cNCReaderGoodData(TestFCIL1cNCReader):
"""Test FCI L1c NetCDF reader."""
_alt_handler = FakeNetCDF4FileHandler2
[docs] def test_file_pattern(self, reader_configs):
"""Test file pattern matching."""
from satpy.readers import load_reader
filenames = [
"W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-1C-RRAD-FDHSI-FD--"
"CHK-BODY--L2P-NC4E_C_EUMT_20170410114434_GTT_DEV_"
"20170410113925_20170410113934_N__C_0070_0067.nc",
"W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-1C-RRAD-FDHSI-FD--"
"CHK-BODY--L2P-NC4E_C_EUMT_20170410114442_GTT_DEV_"
"20170410113934_20170410113942_N__C_0070_0068.nc",
"W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-1C-RRAD-FDHSI-FD--"
"CHK-BODY--L2P-NC4E_C_EUMT_20170410114451_GTT_DEV_"
"20170410113942_20170410113951_N__C_0070_0069.nc",
"W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-1C-RRAD-FDHSI-FD--"
"CHK-BODY--L2P-NC4E_C_EUMT_20170410114500_GTT_DEV_"
"20170410113951_20170410114000_N__C_0070_0070.nc",
"W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-1C-RRAD-FDHSI-FD--"
"CHK-TRAIL--L2P-NC4E_C_EUMT_20170410114600_GTT_DEV_"
"20170410113000_20170410114000_N__C_0070_0071.nc",
]
reader = load_reader(reader_configs)
files = reader.select_files_from_pathnames(filenames)
# only 4 out of 5 above should match
assert len(files) == 4
_chans = {"solar": ["vis_04", "vis_05", "vis_06", "vis_08", "vis_09",
"nir_13", "nir_16", "nir_22"],
"terran": ["ir_38", "wv_63", "wv_73", "ir_87", "ir_97", "ir_105",
"ir_123", "ir_133"]}
[docs] def test_load_counts(self, reader_configs):
"""Test loading with counts."""
from satpy.tests.utils import make_dataid
# testing two filenames to test correctly combined
filenames = [
"W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-1C-RRAD-FDHSI-FD--"
"CHK-BODY--L2P-NC4E_C_EUMT_20170410114434_GTT_DEV_"
"20170410113925_20170410113934_N__C_0070_0067.nc",
"W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-1C-RRAD-FDHSI-FD--"
"CHK-BODY--L2P-NC4E_C_EUMT_20170410114442_GTT_DEV_"
"20170410113934_20170410113942_N__C_0070_0068.nc",
]
reader = _get_reader_with_filehandlers(filenames, reader_configs)
res = reader.load(
[make_dataid(name=name, calibration="counts") for name in
self._chans["solar"] + self._chans["terran"]], pad_data=False)
assert 16 == len(res)
for ch in self._chans["solar"] + self._chans["terran"]:
assert res[ch].shape == (200 * 2, 11136)
assert res[ch].dtype == np.uint16
assert res[ch].attrs["calibration"] == "counts"
assert res[ch].attrs["units"] == "count"
if ch == 'ir_38':
numpy.testing.assert_array_equal(res[ch][~0], 1)
numpy.testing.assert_array_equal(res[ch][0], 5000)
else:
numpy.testing.assert_array_equal(res[ch], 1)
[docs] def test_load_radiance(self, reader_configs):
"""Test loading with radiance."""
from satpy.tests.utils import make_dataid
filenames = [
"W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-1C-RRAD-FDHSI-FD--"
"CHK-BODY--L2P-NC4E_C_EUMT_20170410114434_GTT_DEV_"
"20170410113925_20170410113934_N__C_0070_0067.nc",
]
reader = _get_reader_with_filehandlers(filenames, reader_configs)
res = reader.load(
[make_dataid(name=name, calibration="radiance") for name in
self._chans["solar"] + self._chans["terran"]], pad_data=False)
assert 16 == len(res)
for ch in self._chans["solar"] + self._chans["terran"]:
assert res[ch].shape == (200, 11136)
assert res[ch].dtype == np.float64
assert res[ch].attrs["calibration"] == "radiance"
assert res[ch].attrs["units"] == 'mW m-2 sr-1 (cm-1)-1'
assert res[ch].attrs["radiance_unit_conversion_coefficient"] == 1234.56
if ch == 'ir_38':
numpy.testing.assert_array_equal(res[ch][~0], 15)
numpy.testing.assert_array_equal(res[ch][0], 9700)
else:
numpy.testing.assert_array_equal(res[ch], 15)
[docs] def test_load_reflectance(self, reader_configs):
"""Test loading with reflectance."""
from satpy.tests.utils import make_dataid
filenames = [
"W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-1C-RRAD-FDHSI-FD--"
"CHK-BODY--L2P-NC4E_C_EUMT_20170410114434_GTT_DEV_"
"20170410113925_20170410113934_N__C_0070_0067.nc",
]
reader = _get_reader_with_filehandlers(filenames, reader_configs)
res = reader.load(
[make_dataid(name=name, calibration="reflectance") for name in
self._chans["solar"]], pad_data=False)
assert 8 == len(res)
for ch in self._chans["solar"]:
assert res[ch].shape == (200, 11136)
assert res[ch].dtype == np.float64
assert res[ch].attrs["calibration"] == "reflectance"
assert res[ch].attrs["units"] == "%"
numpy.testing.assert_array_almost_equal(res[ch], 100 * 15 * 1 * np.pi / 50)
[docs] def test_load_bt(self, reader_configs, caplog):
"""Test loading with bt."""
from satpy.tests.utils import make_dataid
filenames = [
"W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-1C-RRAD-FDHSI-FD--"
"CHK-BODY--L2P-NC4E_C_EUMT_20170410114434_GTT_DEV_"
"20170410113925_20170410113934_N__C_0070_0067.nc",
]
reader = _get_reader_with_filehandlers(filenames, reader_configs)
with caplog.at_level(logging.WARNING):
res = reader.load(
[make_dataid(name=name, calibration="brightness_temperature") for
name in self._chans["terran"]], pad_data=False)
assert caplog.text == ""
for ch in self._chans["terran"]:
assert res[ch].shape == (200, 11136)
assert res[ch].dtype == np.float64
assert res[ch].attrs["calibration"] == "brightness_temperature"
assert res[ch].attrs["units"] == "K"
if ch == 'ir_38':
numpy.testing.assert_array_almost_equal(res[ch][~0], 209.68274099)
numpy.testing.assert_array_almost_equal(res[ch][0], 1888.851296)
else:
numpy.testing.assert_array_almost_equal(res[ch], 209.68274099)
[docs] def test_load_index_map(self, reader_configs):
"""Test loading of index_map."""
filenames = [
"W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-1C-RRAD-FDHSI-FD--"
"CHK-BODY--L2P-NC4E_C_EUMT_20170410114434_GTT_DEV_"
"20170410113925_20170410113934_N__C_0070_0067.nc"
]
reader = _get_reader_with_filehandlers(filenames, reader_configs)
res = reader.load(
[name + '_index_map' for name in
self._chans["solar"] + self._chans["terran"]], pad_data=False)
assert 16 == len(res)
for ch in self._chans["solar"] + self._chans["terran"]:
assert res[ch + '_index_map'].shape == (200, 11136)
numpy.testing.assert_array_equal(res[ch + '_index_map'][1, 1], 5237)
[docs] def test_load_aux_data(self, reader_configs):
"""Test loading of auxiliary data."""
from satpy.readers.fci_l1c_nc import AUX_DATA
filenames = [
"W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-1C-RRAD-FDHSI-FD--"
"CHK-BODY--L2P-NC4E_C_EUMT_20170410114434_GTT_DEV_"
"20170410113925_20170410113934_N__C_0070_0067.nc"
]
reader = _get_reader_with_filehandlers(filenames, reader_configs)
res = reader.load(['vis_04_' + key for key in AUX_DATA.keys()],
pad_data=False)
for aux in ['vis_04_' + key for key in AUX_DATA.keys()]:
assert res[aux].shape == (200, 11136)
if aux == 'vis_04_earth_sun_distance':
numpy.testing.assert_array_equal(res[aux][1, 1], 149597870.7)
else:
numpy.testing.assert_array_equal(res[aux][1, 1], 5137)
[docs] def test_load_composite(self):
"""Test that composites are loadable."""
# when dedicated composites for FCI are implemented in satpy,
# this method should probably move to a dedicated class and module
# in the tests.compositor_tests package
from satpy.composites.config_loader import load_compositor_configs_for_sensors
comps, mods = load_compositor_configs_for_sensors(['fci'])
assert len(comps["fci"]) > 0
assert len(mods["fci"]) > 0
[docs] def test_load_quality_only(self, reader_configs):
"""Test that loading quality only works."""
filenames = [
"W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-1C-RRAD-FDHSI-FD--"
"CHK-BODY--L2P-NC4E_C_EUMT_20170410114434_GTT_DEV_"
"20170410113925_20170410113934_N__C_0070_0067.nc",
]
reader = _get_reader_with_filehandlers(filenames, reader_configs)
res = reader.load(
[name + '_pixel_quality' for name in
self._chans["solar"] + self._chans["terran"]], pad_data=False)
assert 16 == len(res)
for ch in self._chans["solar"] + self._chans["terran"]:
assert res[ch + '_pixel_quality'].shape == (200, 11136)
numpy.testing.assert_array_equal(res[ch + '_pixel_quality'][1, 1], 1)
assert res[ch + '_pixel_quality'].attrs["name"] == ch + '_pixel_quality'
[docs] def test_excs(self, reader_configs):
"""Test that exceptions are raised where expected."""
from satpy.tests.utils import make_dataid
filenames = [
"W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-1C-RRAD-FDHSI-FD--"
"CHK-BODY--L2P-NC4E_C_EUMT_20170410114434_GTT_DEV_"
"20170410113925_20170410113934_N__C_0070_0067.nc",
]
reader = _get_reader_with_filehandlers(filenames, reader_configs)
with pytest.raises(ValueError):
reader.file_handlers["fci_l1c_fdhsi"][0].get_dataset(make_dataid(name="invalid"), {})
with pytest.raises(ValueError):
reader.file_handlers["fci_l1c_fdhsi"][0].get_dataset(
make_dataid(name="ir_123", calibration="unknown"),
{"units": "unknown"})
[docs] def test_area_definition_computation(self, reader_configs):
"""Test that the geolocation computation is correct."""
filenames = [
"W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-1C-RRAD-FDHSI-FD--"
"CHK-BODY--L2P-NC4E_C_EUMT_20170410114434_GTT_DEV_"
"20170410113925_20170410113934_N__C_0070_0067.nc",
]
reader = _get_reader_with_filehandlers(filenames, reader_configs)
res = reader.load(['ir_105', 'vis_06'], pad_data=False)
# test that area_ids are harmonisation-conform <platform>_<instrument>_<service>_<resolution>
assert res['vis_06'].attrs['area'].area_id == 'mtg_fci_fdss_1km'
assert res['ir_105'].attrs['area'].area_id == 'mtg_fci_fdss_2km'
area_def = res['ir_105'].attrs['area']
# test area extents computation
np.testing.assert_array_almost_equal(np.array(area_def.area_extent),
np.array([-5568062.23065902, 5168057.7600648,
16704186.692027, 5568062.23065902]))
# check that the projection is read in properly
assert area_def.crs.coordinate_operation.method_name == 'Geostationary Satellite (Sweep Y)'
assert area_def.crs.coordinate_operation.params[0].value == 0.0 # projection origin longitude
assert area_def.crs.coordinate_operation.params[1].value == 35786400.0 # projection height
assert area_def.crs.ellipsoid.semi_major_metre == 6378137.0
assert area_def.crs.ellipsoid.inverse_flattening == 298.257223563
assert area_def.crs.ellipsoid.is_semi_minor_computed
[docs]class TestFCIL1cNCReaderBadData(TestFCIL1cNCReader):
"""Test the FCI L1c NetCDF Reader for bad data input."""
_alt_handler = FakeNetCDF4FileHandler3
[docs] def test_handling_bad_data_ir(self, reader_configs, caplog):
"""Test handling of bad IR data."""
from satpy.tests.utils import make_dataid
filenames = [
"W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-1C-RRAD-FDHSI-FD--"
"CHK-BODY--L2P-NC4E_C_EUMT_20170410114434_GTT_DEV_"
"20170410113925_20170410113934_N__C_0070_0067.nc",
]
reader = _get_reader_with_filehandlers(filenames, reader_configs)
with caplog.at_level("ERROR"):
reader.load([make_dataid(
name="ir_123",
calibration="brightness_temperature")], pad_data=False)
assert "cannot produce brightness temperature" in caplog.text
[docs] def test_handling_bad_data_vis(self, reader_configs, caplog):
"""Test handling of bad VIS data."""
from satpy.tests.utils import make_dataid
filenames = [
"W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-1C-RRAD-FDHSI-FD--"
"CHK-BODY--L2P-NC4E_C_EUMT_20170410114434_GTT_DEV_"
"20170410113925_20170410113934_N__C_0070_0067.nc",
]
reader = _get_reader_with_filehandlers(filenames, reader_configs)
with caplog.at_level("ERROR"):
reader.load([make_dataid(
name="vis_04",
calibration="reflectance")], pad_data=False)
assert "cannot produce reflectance" in caplog.text
[docs]class TestFCIL1cNCReaderBadDataFromIDPF(TestFCIL1cNCReader):
"""Test the FCI L1c NetCDF Reader for bad data input."""
_alt_handler = FakeNetCDF4FileHandler4
[docs] def test_handling_bad_earthsun_distance(self, reader_configs, caplog):
"""Test handling of bad earth-sun distance data."""
from satpy.tests.utils import make_dataid
filenames = [
"W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-1C-RRAD-FDHSI-FD--"
"CHK-BODY--L2P-NC4E_C_EUMT_20170410114434_GTT_DEV_"
"20170410113925_20170410113934_N__C_0070_0067.nc",
]
reader = _get_reader_with_filehandlers(filenames, reader_configs)
res = reader.load([make_dataid(name=["vis_04"], calibration="reflectance")], pad_data=False)
numpy.testing.assert_array_almost_equal(res["vis_04"], 100 * 15 * 1 * np.pi / 50)
[docs] def test_bad_xy_coords(self, reader_configs):
"""Test that the geolocation computation is correct."""
filenames = [
"W_XX-EUMETSAT-Darmstadt,IMG+SAT,MTI1+FCI-1C-RRAD-FDHSI-FD--"
"CHK-BODY--L2P-NC4E_C_EUMT_20170410114434_GTT_DEV_"
"20170410113925_20170410113934_N__C_0070_0067.nc",
]
reader = _get_reader_with_filehandlers(filenames, reader_configs)
res = reader.load(['vis_04'], pad_data=False)
area_def = res['vis_04'].attrs['area']
# test area extents computation
np.testing.assert_array_almost_equal(np.array(area_def.area_extent),
np.array([-5568062.270889, 5168057.806632,
16704186.298937, 5568062.270889]))