Completed
Push — develop ( f92b69...710c13 )
by Adam
55s
created

TestRayleigh.test_rayleigh_init()   A

Complexity

Conditions 3

Size

Total Lines 23

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
dl 0
loc 23
rs 9.0856
c 0
b 0
f 0
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
4
# Copyright (c) 2016, 2017, 2018 Adam.Dybbroe
5
6
# Author(s):
7
8
#   Adam.Dybbroe <[email protected]>
9
10
# This program is free software: you can redistribute it and/or modify
11
# it under the terms of the GNU General Public License as published by
12
# the Free Software Foundation, either version 3 of the License, or
13
# (at your option) any later version.
14
15
# This program is distributed in the hope that it will be useful,
16
# but WITHOUT ANY WARRANTY; without even the implied warranty of
17
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18
# GNU General Public License for more details.
19
20
# You should have received a copy of the GNU General Public License
21
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
22
23
"""Unittest for the rayleigh correction utilities
24
"""
25
26
import sys
27
if sys.version_info < (2, 7):
28
    import unittest2 as unittest
29
else:
30
    import unittest
31
32
import numpy as np
33
from pyspectral import rayleigh
34
from pyspectral.rayleigh import BandFrequencyOutOfRange
35
from pyspectral.tests.data import (
36
    TEST_RAYLEIGH_LUT,
37
    TEST_RAYLEIGH_AZID_COORD,
38
    TEST_RAYLEIGH_SUNZ_COORD,
39
    TEST_RAYLEIGH_SATZ_COORD,
40
    TEST_RAYLEIGH_WVL_COORD)
41
42
43 View Code Duplication
TEST_RAYLEIGH_RESULT1 = np.array([10.40727436,   8.69775471], dtype='float32')
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
44
TEST_RAYLEIGH_RESULT2 = np.array([9.71695252,  8.51415601], dtype='float32')
45
46
47
import os
48
from mock import patch
49
50
# Mock some modules, so we don't need them for tests.
51
52
# sys.modules['pyresample'] = MagicMock()
53
54
55
class RelativeSpectralResponseTestData(object):
56
57
    """RSR test data"""
58
59
    def __init__(self):
60
        """Making a testdata set of relative spectral responses"""
61
62
        self.rsr = {}
63
        channel_names = ['ch12', 'ch13', 'ch10', 'ch11', 'ch16', 'ch14',
64
                         'ch15', 'ch1', 'ch2', 'ch3', 'ch4', 'ch5', 'ch6',
65
                         'ch7', 'ch8', 'ch9']
66
        wvl = [9.6372744012936646, 10.407492196078628, 7.3468642293967275,
67
               8.5926867614178715, 13.280724258676756, 11.239642285822033,
68
               12.380741429961382, 0.47063607733748003, 0.5099976405799187,
69
               0.63914891611559055, 0.85668832355426627, 1.6100814361999056,
70
               2.2568056299864101, 3.8853663735353847, 6.2428987228916233,
71
               6.9411756334211789]
72
        ch3_wvl = np.array([0.55518544, 0.56779468, 0.58099002, 0.59481323, 0.60931027,
73
                            0.62453163, 0.64053291, 0.65737575, 0.67512828, 0.69386619,
74
                            0.71367401])
75
        ch3_resp = np.array([2.61000005e-05, 1.07899999e-04, 3.26119992e-03,
76
                             2.90650606e-01, 9.02460396e-01, 9.60878074e-01,
77
                             9.97266889e-01, 9.94823873e-01, 7.18220174e-01,
78
                             8.31819978e-03, 9.34999989e-05])
79
80
        idx = 0
81
        for chname in channel_names:
82
            self.rsr[chname] = {'det-1': {}}
83
            self.rsr[chname]['det-1']['central_wavelength'] = wvl[idx]
84
            idx = idx + 1
85
86
        chname = 'ch3'
87
        self.rsr[chname]['det-1']['wavelength'] = ch3_wvl
88
        self.rsr[chname]['det-1']['response'] = ch3_resp
89
90
91
class TestRayleigh(unittest.TestCase):
92
93
    """Class for testing pyspectral.rayleigh"""
94
95
    def setUp(self):
96
        """Setup the test"""
97
98
        self.rsr = RelativeSpectralResponseTestData()
99
100
        # mymock:
101
        with patch('pyspectral.rayleigh.RelativeSpectralResponse') as mymock:
102
            instance = mymock.return_value
103
            instance.rsr = RelativeSpectralResponseTestData().rsr
104
            instance.unit = '1e-6 m'
105
            instance.si_scale = 1e-6
106
107
            self.viirs_rayleigh = rayleigh.Rayleigh('NOAA-20', 'viirs', atmosphere='midlatitude summer')
108
109
    def test_get_effective_wavelength(self):
110
        """Test getting the effective wavelength"""
111
112
        # mymock:
113
        with patch('pyspectral.rayleigh.RelativeSpectralResponse') as mymock:
114
            instance = mymock.return_value
115
            instance.rsr = RelativeSpectralResponseTestData().rsr
116
117
            this = rayleigh.Rayleigh('Himawari-8', 'ahi')
118
            with self.assertRaises(BandFrequencyOutOfRange):
119
                this.get_effective_wavelength(0.9)
120
121
            # Only ch3 (~0.63) testdata implemented yet...
122
            ewl = this.get_effective_wavelength(0.65)
123
            self.assertAlmostEqual(ewl, 0.6356167)
124
125
        # mymock:
126
        with patch('pyspectral.rayleigh.RelativeSpectralResponse') as mymock:
127
            instance = mymock.side_effect = IOError(
128
                'Fake that there is no spectral response file...')
129
130
            this = rayleigh.Rayleigh('Himawari-8', 'ahi')
131
            ewl = this.get_effective_wavelength(0.7)
132
            self.assertEqual(ewl, 0.7)
133
            ewl = this.get_effective_wavelength(0.9)
134
            self.assertEqual(ewl, 0.9)
135
            ewl = this.get_effective_wavelength(0.455)
136
            self.assertEqual(ewl, 0.455)
137
138
    @patch('os.path.exists')
139
    @patch('pyspectral.utils.download_luts')
140
    def test_rayleigh_init(self, download_luts, exists):
141
        """Test getting the effective wavelength"""
142
143
        download_luts.return_code = None
144
        exists.return_code = True
145
146
        # mymock:
147
        with patch('pyspectral.rayleigh.RelativeSpectralResponse') as mymock:
148
            instance = mymock.return_value
149
            instance.rsr = RelativeSpectralResponseTestData().rsr
150
151
            with self.assertRaises(AttributeError):
152
                this = rayleigh.Rayleigh('Himawari-8', 'ahi', atmosphere='unknown')
153
                this = rayleigh.Rayleigh('Himawari-8', 'ahi', aerosol_type='unknown')
154
155
            this = rayleigh.Rayleigh('Himawari-8', 'ahi', atmosphere='subarctic winter')
156
            self.assertTrue(os.path.basename(this.reflectance_lut_filename).endswith('subarctic_winter.h5'))
157
            self.assertTrue(this.sensor == 'ahi')
158
159
            this = rayleigh.Rayleigh('NOAA-19', 'avhrr/3', atmosphere='tropical')
160
            self.assertTrue(this.sensor == 'avhrr3')
161
162
    @patch('os.path.exists')
163
    @patch('pyspectral.utils.download_luts')
164
    @patch('pyspectral.rayleigh.get_reflectance_lut')
165
    def test_get_reflectance(self, get_reflectance_lut, download_luts, exists):
166
        """Test getting the reflectance correction"""
167
168
        rayl = TEST_RAYLEIGH_LUT
169
        wvl_coord = TEST_RAYLEIGH_WVL_COORD
170
        azid_coord = TEST_RAYLEIGH_AZID_COORD
171
        sunz_sec_coord = TEST_RAYLEIGH_SUNZ_COORD
172
        satz_sec_coord = TEST_RAYLEIGH_SATZ_COORD
173
174
        get_reflectance_lut.return_value = (rayl, wvl_coord, azid_coord,
175
                                            satz_sec_coord, sunz_sec_coord)
176
        download_luts.return_code = None
177
        exists.return_code = True
178
179
        sun_zenith = np.array([67., 32.])
180
        sat_zenith = np.array([45., 18.])
181
        azidiff = np.array([150., 110.])
182
        blueband = np.array([14., 5.])
183
        retv = self.viirs_rayleigh.get_reflectance(sun_zenith, sat_zenith, azidiff, 'M2', blueband)
184
        self.assertTrue(np.allclose(retv, TEST_RAYLEIGH_RESULT1))
185
186
        sun_zenith = np.array([60., 20.])
187
        sat_zenith = np.array([49., 26.])
188
        azidiff = np.array([140., 130.])
189
        blueband = np.array([12., 8.])
190
        retv = self.viirs_rayleigh.get_reflectance(sun_zenith, sat_zenith, azidiff, 'M2', blueband)
191
        self.assertTrue(np.allclose(retv, TEST_RAYLEIGH_RESULT2))
192
193
    def tearDown(self):
194
        """Clean up"""
195
        pass
196
197
198
def suite():
199
    """The test suite for test_rayleigh.
200
    """
201
    loader = unittest.TestLoader()
202
    mysuite = unittest.TestSuite()
203
    mysuite.addTest(loader.loadTestsFromTestCase(TestRayleigh))
204
205
    return mysuite
206