#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Copyright (c) 2020 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/>.
"""Module for testing the satpy.readers.smos_l2_wind module."""
import datetime as dt
import os
import unittest
from unittest import mock
import numpy as np
import xarray as xr
from satpy.tests.reader_tests.test_netcdf_utils import FakeNetCDF4FileHandler
[docs]
class FakeNetCDF4FileHandlerSMOSL2WIND(FakeNetCDF4FileHandler):
"""Swap-in NetCDF4 File Handler."""
[docs]
def get_test_content(self, filename, filename_info, filetype_info):
"""Mimic reader input file content."""
from xarray import DataArray
dt_s = filename_info.get("start_time", dt.datetime(2020, 4, 22, 12, 0, 0))
dt_e = filename_info.get("end_time", dt.datetime(2020, 4, 22, 12, 0, 0))
if filetype_info["file_type"] == "smos_l2_wind":
file_content = {
"/attr/time_coverage_start": dt_s.strftime("%Y-%m-%dT%H:%M:%S Z"),
"/attr/time_coverage_end": dt_e.strftime("%Y-%m-%dT%H:%M:%S Z"),
"/attr/platform_shortname": "SM",
"/attr/platform": "SMOS",
"/attr/instrument": "MIRAS",
"/attr/processing_level": "L2",
"/attr/geospatial_bounds_vertical_crs": "EPSG:4623",
}
file_content["lat"] = np.arange(-90., 90.25, 0.25)
file_content["lat/shape"] = (len(file_content["lat"]),)
file_content["lat"] = DataArray(file_content["lat"], dims=("lat"))
file_content["lat"].attrs["_FillValue"] = -999.0
file_content["lon"] = np.arange(0., 360., 0.25)
file_content["lon/shape"] = (len(file_content["lon"]),)
file_content["lon"] = DataArray(file_content["lon"], dims=("lon"))
file_content["lon"].attrs["_FillValue"] = -999.0
file_content["wind_speed"] = np.ndarray(shape=(1, # Time dimension
len(file_content["lat"]),
len(file_content["lon"])))
file_content["wind_speed/shape"] = (1,
len(file_content["lat"]),
len(file_content["lon"]))
file_content["wind_speed"] = DataArray(file_content["wind_speed"], dims=("time", "lat", "lon"),
coords=[[1], file_content["lat"], file_content["lon"]])
file_content["wind_speed"].attrs["_FillValue"] = -999.0
else:
raise AssertionError()
return file_content
[docs]
class TestSMOSL2WINDReader(unittest.TestCase):
"""Test SMOS L2 WINDReader."""
yaml_file = "smos_l2_wind.yaml"
[docs]
def setUp(self):
"""Wrap NetCDF4 file handler with our own fake handler."""
from satpy._config import config_search_paths
from satpy.readers.smos_l2_wind import SMOSL2WINDFileHandler
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(SMOSL2WINDFileHandler, "__bases__", (FakeNetCDF4FileHandlerSMOSL2WIND,))
self.fake_handler = self.p.start()
self.p.is_local = True
[docs]
def tearDown(self):
"""Stop wrapping the NetCDF4 file handler."""
self.p.stop()
[docs]
def test_init(self):
"""Test basic initialization of this reader."""
from satpy.readers import load_reader
r = load_reader(self.reader_configs)
loadables = r.select_files_from_pathnames([
"SM_OPER_MIR_SCNFSW_20200420T021649_20200420T035013_110_001_7.nc",
])
assert len(loadables) == 1
r.create_filehandlers(loadables)
# make sure we have some files
assert r.file_handlers
[docs]
def test_load_wind_speed(self):
"""Load wind_speed dataset."""
from satpy.readers import load_reader
r = load_reader(self.reader_configs)
with mock.patch("satpy.readers.smos_l2_wind.netCDF4.Variable", xr.DataArray):
loadables = r.select_files_from_pathnames([
"SM_OPER_MIR_SCNFSW_20200420T021649_20200420T035013_110_001_7.nc",
])
r.create_filehandlers(loadables)
ds = r.load(["wind_speed"])
assert len(ds) == 1
for d in ds.values():
assert d.attrs["platform_shortname"] == "SM"
assert d.attrs["sensor"] == "MIRAS"
assert "area" in d.attrs
assert d.attrs["area"] is not None
assert "y" in d.dims
assert "x" in d.dims
assert d.shape == (719, 1440)
assert d.y[0].data == -89.75
assert d.y[d.shape[0] - 1].data == 89.75
[docs]
def test_load_lat(self):
"""Load lat dataset."""
from satpy.readers import load_reader
r = load_reader(self.reader_configs)
with mock.patch("satpy.readers.smos_l2_wind.netCDF4.Variable", xr.DataArray):
loadables = r.select_files_from_pathnames([
"SM_OPER_MIR_SCNFSW_20200420T021649_20200420T035013_110_001_7.nc",
])
r.create_filehandlers(loadables)
ds = r.load(["lat"])
assert len(ds) == 1
for d in ds.values():
assert "y" in d.dims
assert d.shape == (719,)
assert d.data[0] == -89.75
assert d.data[d.shape[0] - 1] == 89.75
[docs]
def test_load_lon(self):
"""Load lon dataset."""
from satpy.readers import load_reader
r = load_reader(self.reader_configs)
with mock.patch("satpy.readers.smos_l2_wind.netCDF4.Variable", xr.DataArray):
loadables = r.select_files_from_pathnames([
"SM_OPER_MIR_SCNFSW_20200420T021649_20200420T035013_110_001_7.nc",
])
r.create_filehandlers(loadables)
ds = r.load(["lon"])
assert len(ds) == 1
for d in ds.values():
assert "x" in d.dims
assert d.shape == (1440,)
assert d.data[0] == -180.0
assert d.data[d.shape[0] - 1] == 179.75
[docs]
def test_adjust_lon(self):
"""Load adjust longitude dataset."""
from xarray import DataArray
from satpy.readers.smos_l2_wind import SMOSL2WINDFileHandler
smos_l2_wind_fh = SMOSL2WINDFileHandler("SM_OPER_MIR_SCNFSW_20200420T021649_20200420T035013_110_001_7.nc",
{}, filetype_info={"file_type": "smos_l2_wind"})
data = DataArray(np.arange(0., 360., 0.25), dims=("lon"))
adjusted = smos_l2_wind_fh._adjust_lon_coord(data)
expected = DataArray(np.concatenate((np.arange(0, 180., 0.25),
np.arange(-180.0, 0, 0.25))),
dims=("lon"))
assert adjusted.data.tolist() == expected.data.tolist()
[docs]
def test_roll_dataset(self):
"""Load roll of dataset along the lon coordinate."""
from xarray import DataArray
from satpy.readers.smos_l2_wind import SMOSL2WINDFileHandler
smos_l2_wind_fh = SMOSL2WINDFileHandler("SM_OPER_MIR_SCNFSW_20200420T021649_20200420T035013_110_001_7.nc",
{}, filetype_info={"file_type": "smos_l2_wind"})
data = DataArray(np.arange(0., 360., 0.25), dims=("lon"))
data = smos_l2_wind_fh._adjust_lon_coord(data)
adjusted = smos_l2_wind_fh._roll_dataset_lon_coord(data)
expected = np.arange(-180., 180., 0.25)
assert adjusted.data.tolist() == expected.tolist()