Source code for satpy.tests.reader_tests.test_virr_l1b

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Copyright (c) 2016-2018 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/>.
"""Test for readers/virr_l1b.py."""
import os
import unittest
from unittest import mock

import dask.array as da
import numpy as np
import xarray as xr

from satpy.tests.reader_tests.test_hdf5_utils import FakeHDF5FileHandler


[docs] class FakeHDF5FileHandler2(FakeHDF5FileHandler): """Swap-in HDF5 File Handler."""
[docs] def make_test_data(self, dims): """Create fake test data.""" return xr.DataArray(da.from_array(np.ones([dim for dim in dims], dtype=np.float32) * 10, [dim for dim in dims]))
[docs] def _make_file(self, platform_id, geolocation_prefix, l1b_prefix, ECWN, Emissive_units): dim_0 = 19 dim_1 = 20 test_file = { # Satellite data. "/attr/Day Or Night Flag": "D", "/attr/Observing Beginning Date": "2018-12-25", "/attr/Observing Beginning Time": "21:41:47.090", "/attr/Observing Ending Date": "2018-12-25", "/attr/Observing Ending Time": "21:47:28.254", "/attr/Satellite Name": platform_id, "/attr/Sensor Identification Code": "VIRR", # Emissive data. l1b_prefix + "EV_Emissive": self.make_test_data([3, dim_0, dim_1]), l1b_prefix + "EV_Emissive/attr/valid_range": [0, 50000], l1b_prefix + "Emissive_Radiance_Scales": self.make_test_data([dim_0, dim_1]), l1b_prefix + "EV_Emissive/attr/units": Emissive_units, l1b_prefix + "Emissive_Radiance_Offsets": self.make_test_data([dim_0, dim_1]), "/attr/" + ECWN: [2610.31, 917.6268, 836.2546], # Reflectance data. l1b_prefix + "EV_RefSB": self.make_test_data([7, dim_0, dim_1]), l1b_prefix + "EV_RefSB/attr/valid_range": [0, 32767], l1b_prefix + "EV_RefSB/attr/units": "none", "/attr/RefSB_Cal_Coefficients": np.ones(14, dtype=np.float32) * 2 } for attribute in ["Latitude", "Longitude", geolocation_prefix + "SolarZenith", geolocation_prefix + "SensorZenith", geolocation_prefix + "SolarAzimuth", geolocation_prefix + "SensorAzimuth"]: test_file[attribute] = self.make_test_data([dim_0, dim_1]) test_file[attribute + "/attr/Intercept"] = 0. test_file[attribute + "/attr/units"] = "degrees" if "Solar" in attribute or "Sensor" in attribute: test_file[attribute + "/attr/Slope"] = .01 if "Azimuth" in attribute: test_file[attribute + "/attr/valid_range"] = [0, 18000] else: test_file[attribute + "/attr/valid_range"] = [-18000, 18000] else: test_file[attribute + "/attr/Slope"] = 1. if "Longitude" == attribute: test_file[attribute + "/attr/valid_range"] = [-180., 180.] else: test_file[attribute + "/attr/valid_range"] = [-90., 90.] return test_file
[docs] def get_test_content(self, filename, filename_info, filetype_info): """Mimic reader input file content.""" if filename_info["platform_id"] == "FY3B": return self._make_file("FY3B", "", "", "Emmisive_Centroid_Wave_Number", "milliWstts/m^2/cm^(-1)/steradian") return self._make_file(filename_info["platform_id"], "Geolocation/", "Data/", "Emissive_Centroid_Wave_Number", "none")
[docs] class TestVIRRL1BReader(unittest.TestCase): """Test VIRR L1B Reader.""" yaml_file = "virr_l1b.yaml"
[docs] def setUp(self): """Wrap HDF5 file handler with our own fake handler.""" from satpy._config import config_search_paths from satpy.readers.virr_l1b import VIRR_L1B self.reader_configs = config_search_paths(os.path.join("readers", self.yaml_file)) # http://stackoverflow.com/questions/12219967/how-to-mock-a-base-class-with-python-mock-library self.p = mock.patch.object(VIRR_L1B, "__bases__", (FakeHDF5FileHandler2,)) self.fake_handler = self.p.start() self.p.is_local = True
[docs] def tearDown(self): """Stop wrapping the HDF5 file handler.""" self.p.stop()
[docs] def _band_helper(self, attributes, units, calibration, standard_name, file_type, band_index_size, resolution): assert units == attributes["units"] assert calibration == attributes["calibration"] assert standard_name == attributes["standard_name"] assert file_type == attributes["file_type"] assert (attributes["band_index"] in range(band_index_size)) is True assert resolution == attributes["resolution"] assert ("longitude", "latitude") == attributes["coordinates"]
[docs] def _fy3_helper(self, platform_name, reader, Emissive_units): """Load channels and test accurate metadata.""" import datetime band_values = {"1": 22.0, "2": 22.0, "6": 22.0, "7": 22.0, "8": 22.0, "9": 22.0, "10": 22.0, "3": 496.542155, "4": 297.444511, "5": 288.956557, "solar_zenith_angle": .1, "satellite_zenith_angle": .1, "solar_azimuth_angle": .1, "satellite_azimuth_angle": .1, "longitude": 10} if platform_name == "FY3B": # updated 2015 coefficients band_values["1"] = -0.168 band_values["2"] = -0.2706 band_values["6"] = -1.5631 band_values["7"] = -0.2114 band_values["8"] = -0.171 band_values["9"] = -0.1606 band_values["10"] = -0.1328 datasets = reader.load([band for band in band_values]) for dataset in datasets: # Object returned by get_dataset. ds = datasets[dataset["name"]] attributes = ds.attrs assert isinstance(ds.data, da.Array) assert "virr" == attributes["sensor"] assert platform_name == attributes["platform_name"] assert datetime.datetime(2018, 12, 25, 21, 41, 47, 90000) == attributes["start_time"] assert datetime.datetime(2018, 12, 25, 21, 47, 28, 254000) == attributes["end_time"] assert (19, 20) == datasets[dataset["name"]].shape assert ("y", "x") == datasets[dataset["name"]].dims if dataset["name"] in ["1", "2", "6", "7", "8", "9", "10"]: self._band_helper(attributes, "%", "reflectance", "toa_bidirectional_reflectance", "virr_l1b", 7, 1000) elif dataset["name"] in ["3", "4", "5"]: self._band_helper(attributes, Emissive_units, "brightness_temperature", "toa_brightness_temperature", "virr_l1b", 3, 1000) elif dataset["name"] in ["longitude", "latitude"]: assert "degrees" == attributes["units"] assert (attributes["standard_name"] in ["longitude", "latitude"]) is True assert ["virr_l1b", "virr_geoxx"] == attributes["file_type"] assert 1000 == attributes["resolution"] else: assert "degrees" == attributes["units"] assert attributes["standard_name"] in ["solar_zenith_angle", "sensor_zenith_angle", "solar_azimuth_angle", "sensor_azimuth_angle"] assert ["virr_geoxx", "virr_l1b"] == attributes["file_type"] assert ("longitude", "latitude") == attributes["coordinates"] np.testing.assert_allclose(band_values[dataset["name"]], ds[ds.shape[0] // 2][ds.shape[1] // 2], rtol=1e-6) assert "valid_range" not in ds.attrs
[docs] def test_fy3b_file(self): """Test that FY3B files are recognized.""" from satpy.readers import load_reader FY3B_reader = load_reader(self.reader_configs) FY3B_file = FY3B_reader.select_files_from_pathnames(["tf2018359214943.FY3B-L_VIRRX_L1B.HDF"]) assert 1 == len(FY3B_file) FY3B_reader.create_filehandlers(FY3B_file) # Make sure we have some files assert FY3B_reader.file_handlers self._fy3_helper("FY3B", FY3B_reader, "milliWstts/m^2/cm^(-1)/steradian")
[docs] def test_fy3c_file(self): """Test that FY3C files are recognized.""" from satpy.readers import load_reader FY3C_reader = load_reader(self.reader_configs) FY3C_files = FY3C_reader.select_files_from_pathnames(["tf2018359143912.FY3C-L_VIRRX_GEOXX.HDF", "tf2018359143912.FY3C-L_VIRRX_L1B.HDF"]) assert 2 == len(FY3C_files) FY3C_reader.create_filehandlers(FY3C_files) # Make sure we have some files assert FY3C_reader.file_handlers self._fy3_helper("FY3C", FY3C_reader, "1")