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

TestRadTbConversions.test_get_bandname()   A

Complexity

Conditions 3

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
dl 0
loc 20
rs 9.4285
c 0
b 0
f 0
1
#!/usr/bin/env python
2
# -*- coding: utf-8 -*-
3
4
# Copyright (c) 2014-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
"""Testing the radiance to brightness temperature conversion"""
24
25
from pyspectral.radiance_tb_conversion import RadTbConverter
26
from pyspectral.radiance_tb_conversion import SeviriRadTbConverter
27
from pyspectral.utils import get_central_wave
28
import unittest
29
import numpy as np
30
from mock import patch
31
32
TEST_TBS = np.array([200., 270., 300., 302., 350.], dtype='float32')
33
34
TRUE_RADS = np.array([856.937353205, 117420.385297,
35
                      479464.582505, 521412.9511, 2928735.18944],
36
                     dtype='float64')
37
TRUE_RADS_SEVIRI = np.array([2.391091e-08,
38
                             2.559173e-06,
39
                             9.797091e-06,
40
                             1.061431e-05,
41
                             5.531423e-05],
42
                            dtype='float64')
43
44
TEST_RSR = {'20': {}}
45
TEST_RSR['20']['det-1'] = {}
46
TEST_RSR['20']['det-1']['wavelength'] = np.array([
47
    3.6123999, 3.6163599, 3.6264927, 3.6363862, 3.646468,
48
    3.6564937, 3.6664478, 3.6765388, 3.6865413, 3.6964585,
49
    3.7065142, 3.716509, 3.7264658, 3.7364102, 3.7463682,
50
    3.7563652, 3.7664226, 3.7763396, 3.7863384, 3.7964207,
51
    3.8063589, 3.8163606, 3.8264089, 3.8364836, 3.8463381,
52
    3.8563975, 3.8664163, 3.8763755, 3.8864797, 3.8964978,
53
    3.9064275, 3.9164873, 3.9264729, 3.9364026, 3.9465107,
54
    3.9535347], dtype='double')
55
56
TEST_RSR['20']['det-1']['response'] = np.array([
57
    0.01, 0.0118, 0.01987, 0.03226, 0.05028, 0.0849,
58
    0.16645, 0.33792, 0.59106, 0.81815, 0.96077, 0.92855,
59
    0.86008, 0.8661, 0.87697, 0.85412, 0.88922, 0.9541,
60
    0.95687, 0.91037, 0.91058, 0.94256, 0.94719, 0.94808,
61
    1., 0.92676, 0.67429, 0.44715, 0.27762, 0.14852,
62
    0.07141, 0.04151, 0.02925, 0.02085, 0.01414, 0.01], dtype='double')
63
64
TEST_RSR['20']['det-1']['central_wavelength'] = get_central_wave(TEST_RSR['20']['det-1']['wavelength'],
65
                                                                 TEST_RSR['20']['det-1']['response'])
66
67
68
SEV_RSR = {'IR3.9': {}}
69
SEV_RSR['IR3.9']['det-1'] = {}
70
WAVN = np.array([2083.33325195, 2091.00048828, 2098.72387695, 2106.50488281,
71
                 2114.34375, 2122.24121094, 2130.19775391, 2138.21435547,
72
                 2146.29101562, 2154.42944336, 2162.62963867, 2170.89257812,
73
                 2179.21899414, 2187.609375, 2196.06494141, 2204.58569336,
74
                 2213.17285156, 2221.82714844, 2230.54956055, 2239.34082031,
75
                 2248.20141602, 2257.13256836, 2266.13500977, 2275.20947266,
76
                 2284.35668945, 2293.57788086, 2302.87402344, 2312.24584961,
77
                 2321.6940918, 2331.21972656, 2340.82421875, 2350.5078125,
78
                 2360.27197266, 2370.11743164, 2380.0456543, 2390.05737305,
79
                 2400.15356445, 2410.33544922, 2420.60449219, 2430.9609375,
80
                 2441.40625, 2451.94189453, 2462.5690918, 2473.28857422,
81
                 2484.10180664, 2495.01025391, 2506.01416016, 2517.11645508,
82
                 2528.31713867, 2539.61816406, 2551.02050781, 2562.52587891,
83
                 2574.13525391, 2585.8503418, 2597.67236328, 2609.60351562,
84
                 2621.64453125, 2633.796875, 2646.06274414, 2658.44335938,
85
                 2670.94018555, 2683.55541992, 2696.28979492, 2709.14624023,
86
                 2722.12548828, 2735.22973633, 2748.4609375, 2761.82055664,
87
                 2775.31103516, 2788.93359375, 2802.69042969, 2816.58422852,
88
                 2830.61621094, 2844.78833008, 2859.10351562, 2873.56323242,
89
                 2888.17016602, 2902.92626953, 2917.83374023, 2932.89550781,
90
                 2948.11328125, 2963.48999023, 2979.02758789, 2994.72924805,
91
                 3010.59741211, 3026.63452148, 3042.84326172, 3059.22705078,
92
                 3075.78735352, 3092.52880859, 3109.45263672, 3126.56323242,
93
                 3143.86328125, 3161.35571289, 3179.04394531, 3196.9309082,
94
                 3215.02050781, 3233.31640625, 3251.82104492, 3270.5390625],
95
                dtype='float32')
96
97
RESP = np.array([5.85991074e-07, 5.05963471e-05, 1.54738867e-04,
98
                 8.75972546e-07, 2.23005936e-05, 6.17855985e-05,
99
                 1.41724333e-04, 1.87453145e-06, 3.19355922e-06,
100
                 1.08511595e-04, 2.12896630e-04, 5.65914146e-04,
101
                 5.93333738e-04, 2.45316158e-04, 1.77410198e-04,
102
                 3.18188017e-04, 5.27926895e-05, 1.41405777e-04,
103
                 1.64295849e-03, 2.69834511e-03, 4.89762053e-03,
104
                 2.71760323e-03, 2.49398337e-03, 4.83754929e-03,
105
                 1.08462553e-02, 5.53890038e-03, 8.30772892e-03,
106
                 1.33131407e-02, 2.89320182e-02, 4.69624363e-02,
107
                 6.85162693e-02, 1.17517754e-01, 2.26854816e-01,
108
                 3.69935125e-01, 5.16705751e-01, 6.70479536e-01,
109
                 8.18419516e-01, 9.00036395e-01, 9.59491372e-01,
110
                 9.60837066e-01, 9.63596582e-01, 9.77563441e-01,
111
                 9.98380423e-01, 9.98030603e-01, 9.93735969e-01,
112
                 9.84225452e-01, 9.98880267e-01, 1.00000000e+00,
113
                 9.90870714e-01, 9.75207090e-01, 9.68391836e-01,
114
                 9.73213553e-01, 9.75407243e-01, 9.57278728e-01,
115
                 9.68693912e-01, 9.78199899e-01, 9.73649919e-01,
116
                 9.81804073e-01, 9.71176386e-01, 9.72167253e-01,
117
                 9.60459769e-01, 9.40638900e-01, 9.24033165e-01,
118
                 9.16043043e-01, 8.79902899e-01, 8.11953366e-01,
119
                 6.69838488e-01, 4.60774124e-01, 2.68200457e-01,
120
                 1.34857073e-01, 6.40064552e-02, 3.31763141e-02,
121
                 1.24335978e-02, 6.22070907e-03, 2.53354642e-03,
122
                 1.81269188e-05, 4.63075470e-03, 1.78873568e-04,
123
                 1.01367442e-03, 1.28920563e-03, 4.91134451e-05,
124
                 6.77187869e-04, 2.44393433e-03, 2.62995227e-03,
125
                 6.38825062e-04, 1.70478446e-03, 1.03909883e-03,
126
                 1.27910142e-04, 2.95412028e-04, 8.80619162e-04,
127
                 2.42782771e-04, 7.55985593e-06, 3.55220342e-04,
128
                 8.71264958e-04, 2.01994626e-04, 8.14358555e-06,
129
                 2.14082262e-04, 1.07610082e-04, 5.82974189e-06,
130
                 4.16795141e-04], dtype='float32')
131
132
SEV_RSR['IR3.9']['det-1']['wavenumber'] = WAVN
133
SEV_RSR['IR3.9']['det-1']['response'] = RESP
134
135
VIIRS_RSR = {'I04': {}}
136
VIIRS_RSR['I04']['det-1'] = {}
137
I4_WAVELENGTH = np.array([0.0833394,  0.1022195,  0.130236,  0.16001581,  0.19955561,
138
                          0.24286181,  0.29621401,  0.35013291,  0.41273189,  0.47668689,
139
                          0.54601961,  0.59299731,  0.64459503,  0.67387378,  0.71287841,
140
                          0.74619591,  0.7725302,  0.7957828,  0.79547352,  0.82856262,
141
                          0.82099879,  0.83992928,  0.84202057,  0.84400982,  0.83308381,
142
                          0.85475749,  0.83983958,  0.84575808,  0.84324688,  0.84332639,
143
                          0.82304168,  0.83476579,  0.83626682,  0.82226139,  0.82139379,
144
                          0.81928378,  0.82413059,  0.8331368,  0.84240448,  0.858217,
145
                          0.86793423,  0.88952613,  0.91635668,  0.92613328,  0.92169321,
146
                          0.94074869,  0.94403398,  0.95178741,  0.95512831,  0.96271777,
147
                          0.965684,  0.94473231,  0.95947689,  0.94794488,  0.93577278,
148
                          0.91731572,  0.8803544,  0.86248928,  0.86056131,  0.86297452,
149
                          0.88312691,  0.91132039,  0.94761842,  0.96859932,  0.97495008,
150
                          0.97335148,  0.9552781,  0.98041701,  0.97318149,  0.97128302,
151
                          0.9795289,  0.97638869,  0.98553509,  0.97625399,  0.98542649,
152
                          0.98815048,  0.99496758,  0.98651272,  0.97830129,  0.95645708,
153
                          0.95295483,  0.91510731,  0.93925321,  0.9297964,  0.93927532,
154
                          0.942056,  0.95784009,  0.96388292,  0.96057928,  0.97130299,
155
                          0.98001093,  0.9716453,  0.96652049,  0.97841442,  0.96985549,
156
                          0.97240448,  1.,  0.99910343,  0.99543452,  0.98577332,
157
                          0.94873059,  0.91984153,  0.85985827,  0.78354579,  0.71279228,
158
                          0.60751349,  0.50684202,  0.41465551,  0.33605599,  0.2688629,
159
                          0.2085918,  0.1671019,  0.1307321,  0.1050327,  0.0833778],
160
                         dtype='float32')
161
I4_RESPONSE = np.array([3.51000977,  3.51399684,  3.51799059,  3.52198982,  3.52599406,
162
                        3.53000283,  3.53401518,  3.53803015,  3.54204679,  3.54595184,
163
                        3.54996943,  3.55398607,  3.55800128,  3.56201053,  3.56601906,
164
                        3.5700233,  3.57402253,  3.57790327,  3.58199954,  3.58597946,
165
                        3.58995199,  3.59402514,  3.59798145,  3.60203815,  3.60597777,
166
                        3.60990882,  3.61404991,  3.61796427,  3.62197948,  3.62598753,
167
                        3.62998843,  3.63398266,  3.63797164,  3.64195538,  3.64604282,
168
                        3.65001845,  3.65399408,  3.65796638,  3.66193819,  3.66601968,
169
                        3.66999412,  3.67408037,  3.67806101,  3.68194032,  3.68593097,
170
                        3.69003725,  3.69404101,  3.69805193,  3.70196342,  3.70599008,
171
                        3.70991707,  3.71407032,  3.71801329,  3.72207284,  3.72603106,
172
                        3.7299962,  3.73396754,  3.73805571,  3.74203897,  3.74602699,
173
                        3.75001884,  3.75401402,  3.75789952,  3.76200795,  3.76600695,
174
                        3.77000499,  3.77400184,  3.7779963,  3.78209734,  3.78597236,
175
                        3.7899549,  3.79393172,  3.79801106,  3.80197453,  3.80603933,
176
                        3.80998778,  3.81403589,  3.81796741,  3.8219986,  3.82602286,
177
                        3.8300364,  3.83393359,  3.83803844,  3.84202766,  3.84600878,
178
                        3.84998393,  3.85395193,  3.85802197,  3.86208749,  3.86604047,
179
                        3.86999369,  3.87394214,  3.87799811,  3.88194633,  3.88600349,
180
                        3.88995481,  3.89401698,  3.89797616,  3.90193915,  3.90601683,
181
                        3.90999269,  3.91408467,  3.91796803,  3.92196584,  3.92597222,
182
                        3.92998838,  3.93401074,  3.93804169,  3.94197202,  3.9459095,
183
                        3.95007277,  3.95402312,  3.95797944,  3.96194077,  3.96590614], dtype='float32')
184
185
VIIRS_RSR['I04']['det-1']['wavelength'] = I4_WAVELENGTH
186
VIIRS_RSR['I04']['det-1']['response'] = I4_RESPONSE
187
VIIRS_RSR['I04']['det-1']['central_wavelength'] = 3.7460763637226693
188
189
VIIRS_RSR['M12'] = {}
190
VIIRS_RSR['M12']['det-1'] = {}
191
M12_WAVELENGTH = np.array([3.50669217,  3.51322079,  3.51976728,  3.52643943,  3.53301215,
192
                           3.53959203,  3.546175,  3.55287051,  3.55944896,  3.56601906,
193
                           3.57257748,  3.57923317,  3.58575845,  3.59237552,  3.59907913,
194
                           3.60554028,  3.61219764,  3.6188333,  3.62544608,  3.63204026,
195
                           3.63861847,  3.64518261,  3.65184593,  3.65839601,  3.6649456,
196
                           3.67160821,  3.67827654,  3.68485141,  3.69144225,  3.69805193,
197
                           3.7045753,  3.71122766,  3.71779394,  3.72449064,  3.73098779,
198
                           3.73761344,  3.74425411,  3.75079513,  3.75745511,  3.76400733,
199
                           3.77067137,  3.77721882,  3.78386998,  3.79039693,  3.79702044,
200
                           3.80362248,  3.81020689,  3.81687641,  3.82341433,  3.8300364,
201
                           3.83652687,  3.84321165,  3.84976912,  3.85630941,  3.86294222], dtype='float32')
202
M12_RESPONSE = np.array([0.0064421,  0.0084001,  0.0109988,  0.0143879,  0.0197545,
203
                         0.0270981,  0.0370352,  0.0512599,  0.0715467,  0.0987869,
204
                         0.1393604,  0.195684,  0.26579589,  0.36917099,  0.509821,
205
                         0.63852757,  0.74241519,  0.82375473,  0.87010688,  0.89455551,
206
                         0.91357207,  0.92787379,  0.95018548,  0.97198248,  0.98594999,
207
                         0.99682951,  1.,  0.99573219,  0.98468697,  0.98146093,
208
                         0.97062051,  0.95142138,  0.927858,  0.9119851,  0.89879388,
209
                         0.89661211,  0.8987267,  0.89272481,  0.87440962,  0.83271909,
210
                         0.77336842,  0.69556081,  0.60315871,  0.49959281,  0.39389691,
211
                         0.302542,  0.2273816,  0.16862389,  0.1276994,  0.0968111,
212
                         0.0743906,  0.0573153,  0.0445903,  0.0345158,  0.0268065], dtype='float32')
213
214
VIIRS_RSR['M12']['det-1']['wavelength'] = M12_WAVELENGTH
215
VIIRS_RSR['M12']['det-1']['response'] = M12_RESPONSE
216
VIIRS_RSR['M12']['det-1']['central_wavelength'] = 3.6954317366170288
217
218
219
class RSRTestDataModis(object):
220
221
    """RSR test data for Aqua Modis"""
222
223
    def __init__(self):
224
        """Making a testdata set of relative spectral responses"""
225
226
        self.rsr = TEST_RSR
227
228
229
class TestSeviriConversions(unittest.TestCase):
230
231
    """Testing the conversions between radiances and brightness temperatures"""
232
233
    def setUp(self):
234
        """Set up"""
235
236
        with patch('pyspectral.radiance_tb_conversion.RelativeSpectralResponse') as mymock:
237
            instance = mymock.return_value
238
            instance.rsr = SEV_RSR
239
            instance.unit = 'cm-1'
240
            instance.si_scale = 100.
241
242
            self.sev1 = RadTbConverter('Meteosat-9', 'seviri', 'IR3.9',
243
                                       wavespace='wavenumber')
244
245
        self.sev2 = SeviriRadTbConverter('Meteosat-9', 'IR3.9')
246
247
    def test_rad2tb(self):
248
        """Unit testing the radiance to brightness temperature conversion"""
249
        res = self.sev1.tb2radiance(TEST_TBS, lut=False)
250
        self.assertTrue(np.allclose(TRUE_RADS_SEVIRI, res['radiance']))
251
252
    def test_conversion_simple(self):
253
        """Test the tb2radiance function to convert radiances to Tb's
254
        using tabulated coefficients based on a non-linear approximation
255
256
        """
257
        retv = self.sev2.tb2radiance(TEST_TBS)
258
        rads = retv['radiance']
259
        # Units space = wavenumber (cm-1):
260
        tbs = self.sev2.radiance2tb(rads)
261
        self.assertTrue(np.allclose(TEST_TBS, tbs))
262
263
        np.random.seed()
264
        tbs1 = 200.0 + np.random.random(50) * 150.0
265
        retv = self.sev2.tb2radiance(tbs1)
266
        rads = retv['radiance']
267
        tbs = self.sev2.radiance2tb(rads)
268
        self.assertTrue(np.allclose(tbs1, tbs))
269
270
    def test_conversions_methods(self):
271
        """Using the two diferent conversion methods to verify that they give
272
        approximately the same results. Conversion from Tb's to Radiances
273
        only
274
        """
275
        # Units space = wavenumber (cm-1):
276
        retv2 = self.sev2.tb2radiance(TEST_TBS)
277
        retv1 = self.sev1.tb2radiance(TEST_TBS)
278
279
        rads1 = retv1['radiance']
280
        rads2 = retv2['radiance']
281
        self.assertTrue(np.allclose(rads1, rads2))
282
283
    def tearDown(self):
284
        """Clean up"""
285
        pass
286
287
288
class TestRadTbConversions(unittest.TestCase):
289
290
    """Testing the conversions between radiances and brightness temperatures"""
291
292
    def setUp(self):
293
        """Set up"""
294
        # mymock:
295
        with patch('pyspectral.radiance_tb_conversion.RelativeSpectralResponse') as mymock:
296
            instance = mymock.return_value
297
            instance.rsr = TEST_RSR
298
            instance.unit = '1e-6 m'
299
            instance.si_scale = 1e-6
300
301
            self.modis = RadTbConverter('EOS-Aqua', 'modis', '20')
302
            self.modis2 = RadTbConverter('EOS-Aqua', 'modis', 3.75)
303
304
    @patch('os.path.exists')
305
    @patch('os.path.isfile')
306
    @patch('pyspectral.rsr_reader.RelativeSpectralResponse.load')
307
    @patch('pyspectral.rsr_reader.download_rsr')
308
    def test_get_bandname(self, download_rsr, load, isfile, exists):
309
        """Test getting the band name from the wave length
310
        """
311
        load.return_code = None
312
        download_rsr.return_code = None
313
        isfile.return_code = True
314
        exists.return_code = True
315
316
        with patch('pyspectral.radiance_tb_conversion.RelativeSpectralResponse') as mymock:
317
            instance = mymock.return_value
318
            instance.rsr = VIIRS_RSR
319
            instance.unit = 'm'
320
            instance.si_scale = 1.
321
322
            with self.assertRaises(AttributeError):
323
                _ = RadTbConverter('Suomi-NPP', 'viirs', 3.7)
324
325
    def test_rad2tb(self):
326
        """Unit testing the radiance to brightness temperature conversion"""
327
        res = self.modis.tb2radiance(TEST_TBS, lut=False)
328
        self.assertTrue(np.allclose(TRUE_RADS, res['radiance']))
329
330
        res = self.modis2.tb2radiance(TEST_TBS, lut=False)
331
        self.assertTrue(np.allclose(TRUE_RADS, res['radiance']))
332
333
        rad = res['radiance']
334
        tbs = self.modis.radiance2tb(rad)
335
        self.assertTrue(np.allclose(TEST_TBS, tbs, atol=0.25))
336
337
        res = self.modis.tb2radiance(TEST_TBS, lut=False, normalized=False)
338
        integral = self.modis.rsr_integral
339
        self.assertTrue(np.allclose(TRUE_RADS * integral, res['radiance']))
340
341
        res = self.modis.tb2radiance(237., lut=False)
342
        self.assertAlmostEqual(16570.592171157, res['radiance'])
343
344
        res = self.modis.tb2radiance(277., lut=False)
345
        self.assertAlmostEqual(167544.3823631, res['radiance'])
346
347
        res = self.modis.tb2radiance(1.1, lut=False)
348
        self.assertAlmostEqual(0.0, res['radiance'])
349
350
        res = self.modis.tb2radiance(11.1, lut=False)
351
        self.assertAlmostEqual(0.0, res['radiance'])
352
353
        res = self.modis.tb2radiance(100.1, lut=False)
354
        self.assertAlmostEqual(5.3940515573e-06, res['radiance'])
355
356
        res = self.modis.tb2radiance(200.1, lut=False)
357
        self.assertAlmostEqual(865.09776189, res['radiance'])
358
359
    def tearDown(self):
360
        """Clean up"""
361
        pass
362
363
364
def suite():
365
    """The suite for test_reflectance."""
366
    loader = unittest.TestLoader()
367
    mysuite = unittest.TestSuite()
368
    mysuite.addTest(loader.loadTestsFromTestCase(TestRadTbConversions))
369
    mysuite.addTest(loader.loadTestsFromTestCase(TestSeviriConversions))
370
371
    return mysuite
372