|
| 1 | +#!/usr/bin/env python |
| 2 | +# -*- coding: utf-8 -*- |
| 3 | +# Copyright (c) 2019 level1c4pps developers |
| 4 | +# |
| 5 | +# This file is part of level1c4pps |
| 6 | +# |
| 7 | +# level1c4pps is free software: you can redistribute it and/or modify it |
| 8 | +# under the terms of the GNU General Public License as published by |
| 9 | +# the Free Software Foundation, either version 3 of the License, or |
| 10 | +# (at your option) any later version. |
| 11 | +# |
| 12 | +# level1c4pps is distributed in the hope that it will be useful, but |
| 13 | +# WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 15 | +# General Public License for more details. |
| 16 | +# |
| 17 | +# You should have received a copy of the GNU General Public License |
| 18 | +# along with level1c4pps. If not, see <http://www.gnu.org/licenses/>. |
| 19 | +# Author(s): |
| 20 | + |
| 21 | +# Nina Hakansson <nina.hakansson@smhi.se> |
| 22 | + |
| 23 | +"""Unit tests for the vgac2pps_lib module.""" |
| 24 | + |
| 25 | +import netCDF4 |
| 26 | +import unittest |
| 27 | +from datetime import datetime |
| 28 | +try: |
| 29 | + from unittest import mock |
| 30 | +except ImportError: |
| 31 | + import mock |
| 32 | +from satpy import Scene |
| 33 | + |
| 34 | +import level1c4pps.vgac2pps_lib as vgac2pps |
| 35 | +import numpy as np |
| 36 | + |
| 37 | + |
| 38 | +class TestVgac2PPS(unittest.TestCase): |
| 39 | + """Test vgac2pps_lib.""" |
| 40 | + |
| 41 | + def setUp(self): |
| 42 | + """Create a test scene.""" |
| 43 | + vis006 = mock.MagicMock(attrs={'name': 'image0', |
| 44 | + 'wavelength': [1, 2, 3, 'um'], |
| 45 | + 'id_tag': 'ch_r06'}) |
| 46 | + ir_108 = mock.MagicMock(attrs={'name': 'image1', |
| 47 | + 'id_tag': 'ch_tb11', |
| 48 | + 'wavelength': [1, 2, 3, 'um'], |
| 49 | + 'start_time': datetime.utcnow(), |
| 50 | + 'end_time': datetime.utcnow(), |
| 51 | + 'history': 'dummy', |
| 52 | + 'platform_name': 'tirosn', |
| 53 | + 'orbit_number': 99999}) |
| 54 | + qual_f = mock.MagicMock(attrs={'name': 'qual_flags', |
| 55 | + 'id_tag': 'qual_flags'}) |
| 56 | + scan_t = mock.MagicMock(attrs={'name': 'scanline_timestamps'}) |
| 57 | + self.scene = Scene() |
| 58 | + self.scene.attrs['sensor'] = ['avhrr-1', 'avhrr-2', 'avhrr-3'] |
| 59 | + scene_dict = {'M05': vis006, 'M15': ir_108, |
| 60 | + 'qual_flags': qual_f, 'acq_time': scan_t} |
| 61 | + for key in scene_dict: |
| 62 | + pps_name = scene_dict[key].attrs['name'] |
| 63 | + self.scene[key] = scene_dict[key] |
| 64 | + self.scene[key].attrs['name'] = pps_name |
| 65 | + |
| 66 | + def test_get_encoding(self): |
| 67 | + """Test the encoding for VGAC.""" |
| 68 | + encoding_exp = { |
| 69 | + 'image0': {'dtype': 'int16', |
| 70 | + 'scale_factor': 0.01, |
| 71 | + 'zlib': True, |
| 72 | + 'complevel': 4, |
| 73 | + '_FillValue': -32767, |
| 74 | + 'add_offset': 0.0}, |
| 75 | + 'image1': {'dtype': 'int16', |
| 76 | + 'scale_factor': 0.01, |
| 77 | + '_FillValue': -32767, |
| 78 | + 'zlib': True, |
| 79 | + 'complevel': 4, |
| 80 | + 'add_offset': 273.15}, |
| 81 | + 'qual_flags': {'dtype': 'int16', 'zlib': True, |
| 82 | + 'complevel': 4, '_FillValue': -32001.0}, |
| 83 | + 'scanline_timestamps': {'dtype': 'int64', 'zlib': True, |
| 84 | + 'units': 'Milliseconds since 1970-01-01', |
| 85 | + 'complevel': 4, '_FillValue': -1.0}, |
| 86 | + } |
| 87 | + encoding = vgac2pps.get_encoding_viirs(self.scene) |
| 88 | + self.assertDictEqual(encoding, encoding_exp) |
| 89 | + |
| 90 | + def test_set_header_and_band_attrs(self): |
| 91 | + """Test to set header_and_band_attrs.""" |
| 92 | + vgac2pps.set_header_and_band_attrs(self.scene, orbit_n='12345') |
| 93 | + self.assertEqual(self.scene.attrs['orbit_number'], 12345) |
| 94 | + |
| 95 | + def test_process_one_scene(self): |
| 96 | + """Test process one scene for one example file.""" |
| 97 | + |
| 98 | + vgac2pps.process_one_scene( |
| 99 | + ['./level1c4pps/tests/VGAC_VJ102MOD_A2018305_1042_n004946_K005.nc'], |
| 100 | + out_path='./level1c4pps/tests/', |
| 101 | + ) |
| 102 | + filename = './level1c4pps/tests/S_NWC_viirs_noaa20_00000_20181101T1042080Z_20181101T1224090Z.nc' |
| 103 | + # written with hfnetcdf read with NETCDF4 ensure compatability |
| 104 | + pps_nc = netCDF4.Dataset(filename, 'r', format='NETCDF4') # Check compatability implicitly |
| 105 | + |
| 106 | + for key in ['start_time', 'end_time', 'history', 'instrument', |
| 107 | + 'orbit_number', 'platform', |
| 108 | + 'sensor', 'source']: |
| 109 | + if key not in pps_nc.__dict__.keys(): |
| 110 | + print("Missing in attributes:", key) |
| 111 | + self.assertTrue(key in pps_nc.__dict__.keys()) |
| 112 | + |
| 113 | + expected_vars = ['satzenith', 'azimuthdiff', |
| 114 | + 'satazimuth', 'sunazimuth', 'sunzenith', |
| 115 | + 'lon', 'lat', |
| 116 | + 'image1', 'image2', 'image3', 'image4', 'image5', |
| 117 | + 'image6', 'image7', 'image8', 'image9', |
| 118 | + 'scanline_timestamps', 'time', 'time_bnds'] |
| 119 | + for var in expected_vars: |
| 120 | + self.assertTrue(var in pps_nc.variables.keys()) |
| 121 | + |
| 122 | + np.testing.assert_almost_equal(pps_nc.variables['image1'].sun_earth_distance_correction_factor, |
| 123 | + 1.0, decimal=4) |
| 124 | + def test_process_one_scene_n19(self): |
| 125 | + """Test process one scene for one example file.""" |
| 126 | + |
| 127 | + vgac2pps.process_one_scene( |
| 128 | + ['./level1c4pps/tests/VGAC_VJ102MOD_A2018305_1042_n004946_K005.nc'], |
| 129 | + out_path='./level1c4pps/tests/', |
| 130 | + as_noaa19=True, |
| 131 | + ) |
| 132 | + filename = './level1c4pps/tests/S_NWC_avhrr_vgac20_00000_20181101T1042080Z_20181101T1224090Z.nc' |
| 133 | + filename_viirs = './level1c4pps/tests/S_NWC_viirs_noaa20_00000_20181101T1042080Z_20181101T1224090Z.nc' |
| 134 | + # written with hfnetcdf read with NETCDF4 ensure compatability |
| 135 | + pps_nc = netCDF4.Dataset(filename, 'r', format='NETCDF4') # Check compatability implicitly |
| 136 | + pps_nc_viirs = netCDF4.Dataset(filename_viirs, 'r', format='NETCDF4') # Check compatability implicitly |
| 137 | + |
| 138 | + for key in ['start_time', 'end_time', 'history', 'instrument', |
| 139 | + 'orbit_number', 'platform', |
| 140 | + 'sensor', 'source']: |
| 141 | + if key not in pps_nc.__dict__.keys(): |
| 142 | + print("Missing in attributes:", key) |
| 143 | + self.assertTrue(key in pps_nc.__dict__.keys()) |
| 144 | + |
| 145 | + expected_vars = ['satzenith', 'azimuthdiff', |
| 146 | + 'satazimuth', 'sunazimuth', 'sunzenith', |
| 147 | + 'lon', 'lat', |
| 148 | + 'image1', 'image2', 'image3', 'image4', 'image5', |
| 149 | + 'scanline_timestamps', 'time', 'time_bnds'] |
| 150 | + |
| 151 | + for var in expected_vars: |
| 152 | + self.assertTrue(var in pps_nc.variables.keys()) |
| 153 | + |
| 154 | + np.testing.assert_almost_equal(pps_nc.variables['image1'].sun_earth_distance_correction_factor, |
| 155 | + 1.0, decimal=4) |
| 156 | + |
| 157 | + np.testing.assert_equal(pps_nc.__dict__["platform"], "vgac20") |
| 158 | + self.assertTrue(np.abs(pps_nc.variables['image1'][0,0,0] - pps_nc_viirs.variables['image1'][0,0,0])>0.01) |
0 commit comments