Test Failed
Pull Request — master (#9)
by Angeline
03:32
created

test_py_aacgmv2   F

Complexity

Total Complexity 221

Size/Duplication

Total Lines 667
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 221
eloc 495
dl 0
loc 667
rs 1.3673
c 0
b 0
f 0

65 Methods

Rating   Name   Duplication   Size   Complexity  
A TestPyAACGMV2.test_convert_str_to_bit_a2g() 0 3 2
A TestPyAACGMV2.teardown() 0 3 1
B TestPyAACGMV2.test_get_aacgm_coord_arr_location_failure() 0 9 6
A TestPyAACGMV2.test_mlt_convert_arr() 0 7 1
A TestPyAACGMV2.test_convert_bool_to_bit_geocentric() 0 4 2
C TestPyAACGMV2.test_convert_latlon_arr_list() 0 20 9
A TestPyAACGMV2.test_warning_below_ground_get_aacgm_coord_arr() 0 11 3
A TestPyAACGMV2.test_convert_bool_to_bit_a2g() 0 3 2
A TestPyAACGMV2.test_convert_str_to_bit_spaces() 0 4 2
B TestPyAACGMV2.test_get_aacgm_coord_arr_single_val() 0 11 5
B TestPyAACGMV2.test_convert_latlon_arr_badidea_failure() 0 10 6
A TestPyAACGMV2.test_convert_latlon_datetime_date() 0 7 4
A TestPyAACGMV2.setup() 0 5 1
A TestPyAACGMV2.test_get_aacgm_coord_badidea_failure() 0 6 2
A TestPyAACGMV2.test_convert_str_to_bit_invalid() 0 3 2
A TestPyAACGMV2.test_inv_convert_mlt_arr() 0 7 1
A TestPyAACGMV2.test_convert_latlon_arr_maxalt_failure() 0 5 2
A TestPyAACGMV2.test_get_aacgm_coord_datetime_date() 0 8 1
A TestPyAACGMV2.test_convert_str_to_bit_allowtrace() 0 4 2
A TestPyAACGMV2.test_mlt_convert_mlon_wrapping() 0 7 1
A TestPyAACGMV2.test_convert_bool_to_bit_badidea() 0 4 2
A TestPyAACGMV2.test_get_aacgm_coord_maxalt_failure() 0 7 2
A TestPyAACGMV2.test_convert_str_to_bit_geocentric() 0 4 2
A TestPyAACGMV2.test_convert_bool_to_bit_trace() 0 3 2
A TestPyAACGMV2.test_module_parameters() 0 10 3
A TestPyAACGMV2.test_convert_bool_to_bit_allowtrace() 0 4 2
A TestPyAACGMV2.test_inv_convert_mlt_list() 0 7 1
A TestPyAACGMV2.test_convert_latlon_arr_datetime_date() 0 9 4
A TestPyAACGMV2.test_inv_convert_mlt_single() 0 9 1
F TestPyAACGMV2.test_get_aacgm_coord_arr_arr() 0 27 9
A TestPyAACGMV2.test_convert_latlon_location_failure() 0 4 2
A TestPyAACGMV2.test_convert_latlon() 0 6 1
A TestPyAACGMV2.test_get_aacgm_coord_location_failure() 0 4 2
A TestPyAACGMV2.test_get_aacgm_coord() 0 6 1
A TestPyAACGMV2.test_get_aacgm_coord_arr_time_failure() 0 5 2
D TestPyAACGMV2.test_get_aacgm_coord_arr_list() 0 23 9
B TestPyAACGMV2.test_get_aacgm_coord_arr_badidea_failure() 0 11 6
D TestPyAACGMV2.test_convert_latlon_arr_arr() 0 23 9
B TestPyAACGMV2.test_convert_latlon_arr_single_val() 0 10 5
A TestPyAACGMV2.test_convert_str_to_bit_badidea() 0 3 2
A TestPyAACGMV2.test_convert_str_to_bit_trace() 0 3 2
A TestPyAACGMV2.test_get_aacgm_coord_time_failure() 0 4 2
A TestPyAACGMV2.test_convert_latlon_lat_failure() 0 7 3
A TestPyAACGMV2.test_convert_latlon_time_failure() 0 4 2
A TestPyAACGMV2.test_inv_convert_mlt_wrapping() 0 7 1
B TestPyAACGMV2.test_get_aacgm_coord_mlat_failure() 0 19 7
C TestPyAACGMV2.test_module_structure() 0 11 10
F TestPyAACGMV2.test_convert_latlon_arr_unequal() 0 57 17
A TestPyAACGMV2.test_convert_bool_to_bit_g2a() 0 3 2
A TestPyAACGMV2.test_convert_latlon_maxalt_failure() 0 5 2
F TestPyAACGMV2.test_get_aacgm_coord_arr_unequal() 0 58 17
A TestPyAACGMV2.test_warning_below_ground_convert_latlon() 0 10 3
A TestPyAACGMV2.test_convert_latlon_arr_lat_failure() 0 4 2
A TestPyAACGMV2.test_get_aacgm_coord_arr_mlat_failure() 0 11 4
A TestPyAACGMV2.test_mlt_convert_single() 0 7 1
B TestPyAACGMV2.test_convert_latlon_arr_location_failure() 0 8 6
A TestPyAACGMV2.test_mlt_convert_list() 0 7 1
A TestPyAACGMV2.test_convert_latlon_badidea_failure() 0 5 2
A TestPyAACGMV2.test_get_aacgm_coord_arr_maxalt_failure() 0 7 2
A TestPyAACGMV2.test_convert_str_to_bit_lowercase() 0 3 2
A TestPyAACGMV2.test_get_aacgm_coord_arr_datetime_date() 0 9 1
A TestPyAACGMV2.test_convert_latlon_arr_time_failure() 0 4 2
A TestPyAACGMV2.test_warning_below_ground_get_aacgm_coord() 0 10 3
A TestPyAACGMV2.test_convert_str_to_bit_g2a() 0 3 2
A TestPyAACGMV2.test_warning_below_ground_convert_latlon_arr() 0 11 3

How to fix   Complexity   

Complexity

Complex classes like test_py_aacgmv2 often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
# -*- coding: utf-8 -*-
2
from __future__ import division, absolute_import, unicode_literals
3
4
import datetime as dt
5
import numpy as np
6
import pytest
7
import aacgmv2
8
9
class TestPyAACGMV2:
10
    def setup(self):
11
        """Runs before every method to create a clean testing setup"""
12
        self.date_args = (2015, 1, 1, 0, 0, 0, aacgmv2.AACGM_v2_DAT_PREFIX)
13
        self.dtime = dt.datetime(2015, 1, 1, 0, 0, 0)
14
        self.ddate = dt.date(2015, 1, 1)
15
16
    def teardown(self):
17
        """Runs after every method to clean up previous testing"""
18
        del self.date_args, self.dtime, self.ddate
19
20
    def test_module_structure(self):
21
        """Test module structure"""
22
        assert aacgmv2
23
        assert aacgmv2.convert_bool_to_bit
24
        assert aacgmv2.convert_str_to_bit
25
        assert aacgmv2.convert_mlt
26
        assert aacgmv2.convert_latlon
27
        assert aacgmv2.convert_latlon_arr
28
        assert aacgmv2.get_aacgm_coord
29
        assert aacgmv2.get_aacgm_coord_arr
30
        assert aacgmv2.wrapper
31
32
    def test_module_parameters(self):
33
        """Test module constants"""
34
        from os import path
35
36
        path1 = path.join("aacgmv2", "aacgmv2", "aacgm_coeffs",
37
                          "aacgm_coeffs-12-")
38
        assert aacgmv2.AACGM_v2_DAT_PREFIX.find(path1) >= 0
39
40
        path2 = path.join("aacgmv2", "aacgmv2", "igrf12coeffs.txt")
41
        assert aacgmv2.IGRF_12_COEFFS.find(path2) >= 0
42
43
    def test_convert_latlon(self):
44
        """Test single value latlon conversion"""
45
        lat, lon, r = aacgmv2.convert_latlon(60, 0, 300, self.dtime)
46
        np.testing.assert_almost_equal(lat, 58.2258, decimal=4)
47
        np.testing.assert_almost_equal(lon, 81.1685, decimal=4)
48
        np.testing.assert_almost_equal(r, 1.0457, decimal=4)
49
50
    def test_convert_latlon_badidea_failure(self):
51
        """Test single value latlon conversion with a bad flag"""
52
        code = "G2A | BADIDEA"
53
        lat, lon, r = aacgmv2.convert_latlon(60, 0, 3000, self.dtime, code)
54
        assert np.isnan(lat) & np.isnan(lon) & np.isnan(r)
55
56
    def test_convert_latlon_location_failure(self):
57
        """Test single value latlon conversion with a bad location"""
58
        lat, lon, r = aacgmv2.convert_latlon(0, 0, 0, self.dtime)
59
        assert np.isnan(lat) & np.isnan(lon) & np.isnan(r)
60
61
    def test_convert_latlon_time_failure(self):
62
        """Test single value latlon conversion with a bad datetime"""
63
        with pytest.raises(AssertionError):
64
            lat, lon, r = aacgmv2.convert_latlon(60, 0, 300, None)
65
66
    def test_convert_latlon_arr_single_val(self):
67
        """Test array latlon conversion for a single value"""
68
        lat, lon, r = aacgmv2.convert_latlon_arr(60, 0, 300, self.dtime)
69
        assert isinstance(lat, np.ndarray)
70
        assert isinstance(lon, np.ndarray)
71
        assert isinstance(r, np.ndarray)
72
        assert r.shape == lon.shape and lat.shape == r.shape and r.shape == (1,)
73
        np.testing.assert_allclose(lat, [58.2257709], rtol=1e-4)
74
        np.testing.assert_allclose(lon, [81.16846959], rtol=1e-4)
75
        np.testing.assert_allclose(r, [1.04566346], rtol=1e-4)
76
77
    def test_convert_latlon_arr_list(self):
78
        """Test array latlon conversion for list input"""
79
        lat, lon, r = aacgmv2.convert_latlon_arr([60], [0], [300], self.dtime)
80
        assert isinstance(lat, np.ndarray)
81
        assert isinstance(lon, np.ndarray)
82
        assert isinstance(r, np.ndarray)
83
        assert r.shape == lon.shape and lat.shape == r.shape and r.shape == (1,)
84
        np.testing.assert_allclose(lat, [58.2257709], rtol=1e-4)
85
        np.testing.assert_allclose(lon, [81.16846959], rtol=1e-4)
86
        np.testing.assert_allclose(r, [1.04566346], rtol=1e-4)
87
88
        lat, lon, r = aacgmv2.convert_latlon_arr([60, 61], [0, 0], [300, 300],
89
                                                 self.dtime)
90
        assert isinstance(lat, np.ndarray)
91
        assert isinstance(lon, np.ndarray)
92
        assert isinstance(r, np.ndarray)
93
        assert r.shape == lon.shape and lat.shape == r.shape and r.shape == (2,)
94
        np.testing.assert_allclose(lat, [58.22577090, 59.31860933], rtol=1e-4)
95
        np.testing.assert_allclose(lon, [81.16846959, 81.61398933], rtol=1e-4)
96
        np.testing.assert_allclose(r, [1.04566346, 1.04561304], rtol=1e-4)
97
98
    def test_convert_latlon_arr_arr(self):
99
        """Test array latlon conversion for array input"""
100
        lat, lon, r = aacgmv2.convert_latlon_arr(np.array([60]), np.array([0]),
101
                                                 np.array([300]), self.dtime)
102
        assert isinstance(lat, np.ndarray)
103
        assert isinstance(lon, np.ndarray)
104
        assert isinstance(r, np.ndarray)
105
        assert r.shape == lon.shape and lat.shape == r.shape and r.shape == (1,)
106
        np.testing.assert_allclose(lat, [58.2257709], rtol=1e-4)
107
        np.testing.assert_allclose(lon, [81.16846959], rtol=1e-4)
108
        np.testing.assert_allclose(r, [1.04566346], rtol=1e-4)
109
110
        lat, lon, r = aacgmv2.convert_latlon_arr(np.array([60, 61]),
111
                                                 np.array([0, 0]),
112
                                                 np.array([300, 300]),
113
                                                 self.dtime)
114
        assert isinstance(lat, np.ndarray)
115
        assert isinstance(lon, np.ndarray)
116
        assert isinstance(r, np.ndarray)
117
        assert r.shape == lon.shape and lat.shape == r.shape and r.shape == (2,)
118
        np.testing.assert_allclose(lat, [58.22577090, 59.31860933], rtol=1e-4)
119
        np.testing.assert_allclose(lon, [81.16846959, 81.61398933], rtol=1e-4)
120
        np.testing.assert_allclose(r, [1.04566346, 1.04561304], rtol=1e-4)
121
122
    def test_convert_latlon_arr_unequal(self):
123
        """Test array latlon conversion for unequal sized input"""
124
        lat, lon, r = aacgmv2.convert_latlon_arr([60, 61], 0, 300, self.dtime)
125
        assert isinstance(lat, np.ndarray)
126
        assert isinstance(lon, np.ndarray)
127
        assert isinstance(r, np.ndarray)
128
        assert r.shape == lon.shape and lat.shape == r.shape and r.shape == (2,)
129
        np.testing.assert_allclose(lat, [58.22577090, 59.31860933], rtol=1e-4)
130
        np.testing.assert_allclose(lon, [81.16846959, 81.61398933], rtol=1e-4)
131
        np.testing.assert_allclose(r, [1.04566346, 1.04561304], rtol=1e-4)
132
133
        lat, lon, r = aacgmv2.convert_latlon_arr(np.array([60, 61]), 0, 300,
134
                                                 self.dtime)
135
        assert isinstance(lat, np.ndarray)
136
        assert isinstance(lon, np.ndarray)
137
        assert isinstance(r, np.ndarray)
138
        assert r.shape == lon.shape and lat.shape == r.shape and r.shape == (2,)
139
        np.testing.assert_allclose(lat, [58.22577090, 59.31860933], rtol=1e-4)
140
        np.testing.assert_allclose(lon, [81.16846959, 81.61398933], rtol=1e-4)
141
        np.testing.assert_allclose(r, [1.04566346, 1.04561304], rtol=1e-4)
142
143
        lat, lon, r = aacgmv2.convert_latlon_arr(np.array([[60, 61, 62],
144
                                                           [63, 64, 65]]), 0,
145
                                                 300, self.dtime)
146
        assert isinstance(lat, np.ndarray)
147
        assert isinstance(lon, np.ndarray)
148
        assert isinstance(r, np.ndarray)
149
        assert r.shape == lon.shape and lat.shape == r.shape and \
150
            r.shape == (2, 3)
151
        np.testing.assert_allclose(lat, [[58.2257709, 59.3186093, 60.4039740],
152
                                         [61.4819893, 62.5527635, 63.6163840]],
153
                                   rtol=1e-4)
154
        np.testing.assert_allclose(lon, [[81.1684696, 81.6139893, 82.0871880],
155
                                         [82.5909499, 83.1285895, 83.7039272]],
156
                                   rtol=1e-4)
157
        np.testing.assert_allclose(r, [[1.04566346, 1.04561304, 1.04556369],
158
                                       [1.04551548, 1.04546847, 1.04542272]],
159
                                   rtol=1e-4)
160
161
        lat, lon, r = aacgmv2.convert_latlon_arr(np.array([[60, 61, 62],
162
                                                           [63, 64, 65]]), [0],
163
                                                 [300], self.dtime)
164
        assert isinstance(lat, np.ndarray)
165
        assert isinstance(lon, np.ndarray)
166
        assert isinstance(r, np.ndarray)
167
        assert r.shape == lon.shape and lat.shape == r.shape and \
168
            r.shape == (2, 3)
169
        
170
        np.testing.assert_allclose(lat, [[58.2257709, 59.3186093, 60.4039740],
171
                                         [61.4819893, 62.5527635, 63.6163840]],
172
                                   rtol=1e-4)
173
        np.testing.assert_allclose(lon, [[81.1684696, 81.6139893, 82.0871880],
174
                                         [82.5909499, 83.1285895, 83.7039272]],
175
                                   rtol=1e-4)
176
        np.testing.assert_allclose(r, [[1.04566346, 1.04561304, 1.04556369],
177
                                       [1.04551548, 1.04546847, 1.04542272]],
178
                                   rtol=1e-4)
179
180
    def test_convert_latlon_arr_badidea_failure(self):
181
        """Test array latlon conversion failure for BADIDEA"""
182
        code = "G2A | BADIDEA"
183
        lat, lon, r = aacgmv2.convert_latlon_arr([60], [0], [3000], self.dtime,
184
                                                 code)
185
        assert isinstance(lat, np.ndarray)
186
        assert isinstance(lon, np.ndarray)
187
        assert isinstance(r, np.ndarray)
188
        assert r.shape == lon.shape and lat.shape == r.shape and r.shape == (1,)
189
        assert np.all([np.isnan(lat), np.isnan(lon), np.isnan(r)])
190
191
    def test_convert_latlon_arr_location_failure(self):
192
        """Test array latlon conversion with a bad location"""
193
        lat, lon, r = aacgmv2.convert_latlon_arr([0], [0], [0], self.dtime)
194
        assert isinstance(lat, np.ndarray)
195
        assert isinstance(lon, np.ndarray)
196
        assert isinstance(r, np.ndarray)
197
        assert r.shape == lon.shape and lat.shape == r.shape and r.shape == (1,)
198
        assert np.all([np.isnan(lat), np.isnan(lon), np.isnan(r)])
199
200
    def test_convert_latlon_arr_time_failure(self):
201
        """Test array latlon conversion with a bad time"""
202
        with pytest.raises(AssertionError):
203
            lat, lon, r = aacgmv2.convert_latlon_arr([60], [0], [300], None)
204
205
    def test_convert_latlon_datetime_date(self):
206
        """Test single latlon conversion with date and datetime input"""
207
        lat_1, lon_1, r_1 = aacgmv2.convert_latlon(60, 0, 300, self.ddate)
208
        lat_2, lon_2, r_2 = aacgmv2.convert_latlon(60, 0, 300, self.dtime)
209
        assert lat_1 == lat_2
210
        assert lon_1 == lon_2
211
        assert r_1 == r_2
212
213
    def test_convert_latlon_arr_datetime_date(self):
214
        """Test array latlon conversion with date and datetime input"""
215
        lat_1, lon_1, r_1 = aacgmv2.convert_latlon_arr([60], [0], [300],
216
                                                       self.ddate)
217
        lat_2, lon_2, r_2 = aacgmv2.convert_latlon_arr([60], [0], [300],
218
                                                       self.dtime)
219
        assert lat_1 == lat_2
220
        assert lon_1 == lon_2
221
        assert r_1 == r_2
222
223
    def test_warning_below_ground_convert_latlon(self):
224
        """ Test that a warning is issued if altitude is below zero"""
225
        import logbook
226
        lwarn = u"conversion not intended for altitudes < 0 km"
227
228
        with logbook.TestHandler() as handler:
229
            lat, lon, r = aacgmv2.convert_latlon(60, 0, -1, self.dtime)
230
            assert handler.has_warning(lwarn)
231
232
        handler.close()
233
234
    def test_warning_below_ground_convert_latlon_arr(self):
235
        """ Test that a warning is issued if altitude is below zero"""
236
        import logbook
237
        lwarn = u"conversion not intended for altitudes < 0 km"
238
239
        with logbook.TestHandler() as handler:
240
            lat, lon, r = aacgmv2.convert_latlon_arr([60], [0], [-1],
241
                                                     self.dtime)
242
            assert handler.has_warning(lwarn)
243
244
        handler.close()
245
246
    def test_convert_latlon_maxalt_failure(self):
247
        """For a single value, test failure for an altitude too high for
248
        coefficients"""
249
        lat, lon, r = aacgmv2.convert_latlon(60, 0, 2001, self.dtime)
250
        assert np.isnan(lat) & np.isnan(lon) & np.isnan(r)
251
252
    def test_convert_latlon_arr_maxalt_failure(self):
253
        """For an array, test failure for an altitude too high for
254
        coefficients"""
255
        lat, lon, r = aacgmv2.convert_latlon_arr([60], [0], [2001], self.dtime)
256
        assert np.all([np.isnan(lat), np.isnan(lon), np.isnan(r)])
257
258
    def test_convert_latlon_lat_failure(self):
259
        """Test error return for co-latitudes above 90 for a single value"""
260
        with pytest.raises(AssertionError):
261
            aacgmv2.convert_latlon(91, 0, 300, self.dtime)
262
263
        with pytest.raises(AssertionError):
264
            aacgmv2.convert_latlon(-91, 0, 300, self.dtime)
265
266
    def test_convert_latlon_arr_lat_failure(self):
267
        """Test error return for co-latitudes above 90 for an array"""
268
        with pytest.raises(AssertionError):
269
            aacgmv2.convert_latlon_arr([91, 60, -91], 0, 300, self.dtime)
270
271
    def test_get_aacgm_coord(self):
272
        """Test single value AACGMV2 calculation, defaults to TRACE"""
273
        mlat, mlon, mlt = aacgmv2.get_aacgm_coord(60, 0, 300, self.dtime)
274
        np.testing.assert_almost_equal(mlat, 58.2247, decimal=4)
275
        np.testing.assert_almost_equal(mlon, 81.1761, decimal=4)
276
        np.testing.assert_almost_equal(mlt, 0.1889, decimal=4)
277
278
    def test_get_aacgm_coord_badidea_failure(self):
279
        """Test single value AACGMV2 calculation with a bad flag"""
280
        method = "BADIDEA"
281
        mlat, mlon, mlt = aacgmv2.get_aacgm_coord(60, 0, 3000, self.dtime,
282
                                              method=method)
283
        assert np.isnan(mlat) & np.isnan(mlon) & np.isnan(mlt)
284
285
    def test_get_aacgm_coord_location_failure(self):
286
        """Test single value AACGMV2 calculation with a bad location"""
287
        mlat, mlon, mlt = aacgmv2.get_aacgm_coord(0, 0, 0, self.dtime)
288
        assert np.isnan(mlat) & np.isnan(mlon) & np.isnan(mlt)
289
290
    def test_get_aacgm_coord_time_failure(self):
291
        """Test single value AACGMV2 calculation with a bad datetime"""
292
        with pytest.raises(AssertionError):
293
            mlat, mlon, mlt = aacgmv2.get_aacgm_coord(60, 0, 300, None)
294
295
    def test_get_aacgm_coord_arr_single_val(self):
296
        """Test array AACGMV2 calculation for a single value"""
297
        mlat, mlon, mlt = aacgmv2.get_aacgm_coord_arr(60, 0, 300, self.dtime)
298
        assert isinstance(mlat, np.ndarray)
299
        assert isinstance(mlon, np.ndarray)
300
        assert isinstance(mlt, np.ndarray)
301
        assert mlt.shape == mlon.shape and mlat.shape == mlt.shape and \
302
            mlt.shape == (1,)
303
        np.testing.assert_allclose(mlat, [58.22474610], rtol=1e-4)
304
        np.testing.assert_allclose(mlon, [81.17611033], rtol=1e-4)
305
        np.testing.assert_allclose(mlt, [0.18891995], rtol=1e-4)
306
307
    def test_get_aacgm_coord_arr_list(self):
308
        """Test array AACGMV2 calculation for list input"""
309
        mlat, mlon, mlt = aacgmv2.get_aacgm_coord_arr([60], [0], [300],
310
                                                      self.dtime)
311
        assert isinstance(mlat, np.ndarray)
312
        assert isinstance(mlon, np.ndarray)
313
        assert isinstance(mlt, np.ndarray)
314
        assert mlt.shape == mlon.shape and mlat.shape == mlt.shape and \
315
            mlt.shape == (1,)
316
        np.testing.assert_allclose(mlat, [58.22474610], rtol=1e-4)
317
        np.testing.assert_allclose(mlon, [81.17611033], rtol=1e-4)
318
        np.testing.assert_allclose(mlt, [0.18891995], rtol=1e-4)
319
320
        mlat, mlon, mlt = aacgmv2.get_aacgm_coord_arr([60, 61], [0, 0],
321
                                                      [300, 300], self.dtime)
322
        assert isinstance(mlat, np.ndarray)
323
        assert isinstance(mlon, np.ndarray)
324
        assert isinstance(mlt, np.ndarray)
325
        assert mlt.shape == mlon.shape and mlat.shape == mlt.shape and \
326
            mlt.shape == (2,)
327
        np.testing.assert_allclose(mlat, [58.22474610, 59.31648007], rtol=1e-4)
328
        np.testing.assert_allclose(mlon, [81.17611033, 81.62281360], rtol=1e-4)
329
        np.testing.assert_allclose(mlt, [0.18891995, 0.21870017], rtol=1e-4)
330
331
    def test_get_aacgm_coord_arr_arr(self):
332
        """Test array AACGMV2 calculation for array input"""
333
        mlat, mlon, mlt = aacgmv2.get_aacgm_coord_arr(np.array([60]),
334
                                                      np.array([0]),
335
                                                      np.array([300]),
336
                                                      self.dtime)
337
        assert isinstance(mlat, np.ndarray)
338
        assert isinstance(mlon, np.ndarray)
339
        assert isinstance(mlt, np.ndarray)
340
        assert mlt.shape == mlon.shape and mlat.shape == mlt.shape and \
341
            mlt.shape == (1,)
342
        np.testing.assert_almost_equal(mlat[0], 58.2247, decimal=4)
343
        np.testing.assert_almost_equal(mlon[0], 81.1761, decimal=4)
344
        np.testing.assert_almost_equal(mlt[0], 0.1889, decimal=4)
345
346
        mlat, mlon, mlt = aacgmv2.get_aacgm_coord_arr(np.array([60, 61]),
347
                                                 np.array([0, 0]),
348
                                                 np.array([300, 300]),
349
                                                 self.dtime)
350
        assert isinstance(mlat, np.ndarray)
351
        assert isinstance(mlon, np.ndarray)
352
        assert isinstance(mlt, np.ndarray)
353
        assert mlt.shape == mlon.shape and mlat.shape == mlt.shape and \
354
            mlt.shape == (2,)
355
        np.testing.assert_allclose(mlat, [58.22474610, 59.31648007], rtol=1e-4)
356
        np.testing.assert_allclose(mlon, [81.17611033, 81.62281360], rtol=1e-4)
357
        np.testing.assert_allclose(mlt, [0.18891995, 0.21870017], rtol=1e-4)
358
359
    def test_get_aacgm_coord_arr_unequal(self):
360
        """Test array AACGMV2 calculation for unequal sized input"""
361
        mlat, mlon, mlt = aacgmv2.get_aacgm_coord_arr([60, 61], 0, 300,
362
                                                      self.dtime)
363
        assert isinstance(mlat, np.ndarray)
364
        assert isinstance(mlon, np.ndarray)
365
        assert isinstance(mlt, np.ndarray)
366
        assert mlt.shape == mlon.shape and mlat.shape == mlt.shape and \
367
            mlt.shape == (2,)
368
        np.testing.assert_allclose(mlat, [58.22474610, 59.31648007], rtol=1e-4)
369
        np.testing.assert_allclose(mlon, [81.17611033, 81.62281360], rtol=1e-4)
370
        np.testing.assert_allclose(mlt, [0.18891995, 0.21870017], rtol=1e-4)
371
372
        mlat, mlon, mlt = aacgmv2.get_aacgm_coord_arr(np.array([60, 61]), 0,
373
                                                      300, self.dtime)
374
        assert isinstance(mlat, np.ndarray)
375
        assert isinstance(mlon, np.ndarray)
376
        assert isinstance(mlt, np.ndarray)
377
        assert mlt.shape == mlon.shape and mlat.shape == mlt.shape and \
378
            mlt.shape == (2,)
379
        np.testing.assert_allclose(mlat, [58.22474610, 59.31648007], rtol=1e-4)
380
        np.testing.assert_allclose(mlon, [81.17611033, 81.62281360], rtol=1e-4)
381
        np.testing.assert_allclose(mlt, [0.18891995, 0.21870017], rtol=1e-4)
382
383
        mlat, mlon, mlt = aacgmv2.get_aacgm_coord_arr(np.array([[60, 61, 62],
384
                                                           [63, 64, 65]]), 0,
385
                                                 300, self.dtime)
386
        assert isinstance(mlat, np.ndarray)
387
        assert isinstance(mlon, np.ndarray)
388
        assert isinstance(mlt, np.ndarray)
389
        assert mlt.shape == mlon.shape and mlat.shape == mlt.shape and \
390
            mlt.shape == (2, 3)
391
        np.testing.assert_allclose(mlat, [[58.2247461, 59.3164801, 60.4008651],
392
                                          [61.4780560, 62.5481858, 63.6113609]],
393
                                   rtol=1e-4)
394
        np.testing.assert_allclose(mlon, [[81.1761103, 81.6228136, 82.0969646],
395
                                          [82.6013918, 83.1393547, 83.7146224]],
396
                                   rtol=1e-4)
397
        np.testing.assert_allclose(mlt, [[0.18891995, 0.21870017, 0.25031024],
398
                                         [0.28393872, 0.31980291, 0.35815409]],
399
                                   rtol=1e-4)
400
401
        mlat, mlon, mlt = aacgmv2.get_aacgm_coord_arr(np.array([[60, 61, 62],
402
                                                                [63, 64, 65]]),
403
                                                      [0], [300], self.dtime)
404
        assert isinstance(mlat, np.ndarray)
405
        assert isinstance(mlon, np.ndarray)
406
        assert isinstance(mlt, np.ndarray)
407
        assert mlt.shape == mlon.shape and mlat.shape == mlt.shape and \
408
            mlt.shape == (2, 3)
409
        np.testing.assert_allclose(mlat, [[58.2247, 59.3165, 60.4009],
410
                                          [61.4781, 62.5482, 63.6114]],
411
                                   rtol=1e-3)
412
        np.testing.assert_allclose(mlon, [[81.1761, 81.6228, 82.0970],
413
                                          [82.6014, 83.1394, 83.7146]],
414
                                   rtol=1e-3)
415
        np.testing.assert_allclose(mlt, [[0.1889, 0.2187, 0.2503],
416
                                         [0.2839, 0.3198, 0.3582]], rtol=1e-3)
417
418
    def test_get_aacgm_coord_arr_badidea_failure(self):
419
        """Test array AACGMV2 calculation failure for BADIDEA"""
420
        method = "BADIDEA"
421
        mlat, mlon, mlt = aacgmv2.get_aacgm_coord_arr([60], [0], [3000],
422
                                                      self.dtime, method=method)
423
        assert isinstance(mlat, np.ndarray)
424
        assert isinstance(mlon, np.ndarray)
425
        assert isinstance(mlt, np.ndarray)
426
        assert mlt.shape == mlon.shape and mlat.shape == mlt.shape and \
427
            mlt.shape == (1,)
428
        assert np.all([np.isnan(mlat), np.isnan(mlon), np.isnan(mlt)])
429
430
    def test_get_aacgm_coord_arr_location_failure(self):
431
        """Test array AACGMV2 calculation with a bad location"""
432
        mlat, mlon, mlt = aacgmv2.get_aacgm_coord_arr([0], [0], [0], self.dtime)
433
        assert isinstance(mlat, np.ndarray)
434
        assert isinstance(mlon, np.ndarray)
435
        assert isinstance(mlt, np.ndarray)
436
        assert mlt.shape == mlon.shape and mlat.shape == mlt.shape and \
437
            mlt.shape == (1,)
438
        assert np.all([np.isnan(mlat), np.isnan(mlon), np.isnan(mlt)])
439
440
    def test_get_aacgm_coord_arr_time_failure(self):
441
        """Test array AACGMV2 calculation with a bad time"""
442
        with pytest.raises(AssertionError):
443
            mlat, mlon, mlt = aacgmv2.get_aacgm_coord_arr([60], [0], [300],
444
                                                          None)
445
446
    def test_get_aacgm_coord_datetime_date(self):
447
        """Test single AACGMV2 calculation with date and datetime input"""
448
        mlat_1, mlon_1, mlt_1 = aacgmv2.get_aacgm_coord(60, 0, 300, self.ddate)
449
        mlat_2, mlon_2, mlt_2 = aacgmv2.get_aacgm_coord(60, 0, 300, self.dtime)
450
451
        np.testing.assert_almost_equal(mlat_1, mlat_2, decimal=6)
452
        np.testing.assert_almost_equal(mlon_1, mlon_2, decimal=6)
453
        np.testing.assert_almost_equal(mlt_1, mlt_2, decimal=6)
454
455
    def test_get_aacgm_coord_arr_datetime_date(self):
456
        """Test array AACGMV2 calculation with date and datetime input"""
457
        mlat_1, mlon_1, mlt_1 = aacgmv2.get_aacgm_coord_arr([60], [0], [300],
458
                                                       self.ddate)
459
        mlat_2, mlon_2, mlt_2 = aacgmv2.get_aacgm_coord_arr([60], [0], [300],
460
                                                       self.dtime)
461
        np.testing.assert_almost_equal(mlat_1, mlat_2, decimal=6)
462
        np.testing.assert_almost_equal(mlon_1, mlon_2, decimal=6)
463
        np.testing.assert_almost_equal(mlt_1, mlt_2, decimal=6)
464
465
    def test_warning_below_ground_get_aacgm_coord(self):
466
        """ Test that a warning is issued if altitude is below zero"""
467
        import logbook
468
        lwarn = u"conversion not intended for altitudes < 0 km"
469
470
        with logbook.TestHandler() as handler:
471
            mlat, mlon, mlt = aacgmv2.get_aacgm_coord(60, 0, -1, self.dtime)
472
            assert handler.has_warning(lwarn)
473
474
        handler.close()
475
        
476
    def test_warning_below_ground_get_aacgm_coord_arr(self):
477
        """ Test that a warning is issued if altitude is below zero"""
478
        import logbook
479
        lwarn = u"conversion not intended for altitudes < 0 km"
480
481
        with logbook.TestHandler() as handler:
482
            mlat, mlon, mlt = aacgmv2.get_aacgm_coord_arr([60], [0], [-1],
483
                                                     self.dtime)
484
            assert handler.has_warning(lwarn)
485
486
        handler.close()
487
488
    def test_get_aacgm_coord_maxalt_failure(self):
489
        """For a single value, test failure for an altitude too high for
490
        coefficients"""
491
        method = ""
492
        mlat, mlon, mlt = aacgmv2.get_aacgm_coord(60, 0, 2001, self.dtime,
493
                                                  method=method)
494
        assert np.isnan(mlat) & np.isnan(mlon) & np.isnan(mlt)
495
496
    def test_get_aacgm_coord_arr_maxalt_failure(self):
497
        """For an array, test failure for an altitude too high for
498
        coefficients"""
499
        method = ""
500
        mlat, mlon, mlt = aacgmv2.get_aacgm_coord_arr([60], [0], [2001],
501
                                                      self.dtime, method=method)
502
        assert np.all([np.isnan(mlat), np.isnan(mlon), np.isnan(mlt)])
503
504
    def test_get_aacgm_coord_mlat_failure(self):
505
        """Test error return for co-latitudes above 90 for a single value"""
506
        import logbook
507
        lerr = u"unrealistic latitude"
508
509
        with logbook.TestHandler() as hhigh:
510
            with pytest.raises(AssertionError):
511
                mlat, mlon, mlt = aacgmv2.get_aacgm_coord(91, 0, 300,
512
                                                          self.dtime)
513
                assert hhigh.has_error(lerr)
514
515
        with logbook.TestHandler() as hlow:
516
            with pytest.raises(AssertionError):
517
                mlat, mlon, mlt = aacgmv2.get_aacgm_coord(-91, 0, 300,
518
                                                          self.dtime)
519
                assert hlow.has_error(lerr)
520
521
        hhigh.close()
522
        hlow.close()
523
524
    def test_get_aacgm_coord_arr_mlat_failure(self):
525
        """Test error return for co-latitudes above 90 for an array"""
526
        import logbook
527
        lerr = u"unrealistic latitude"
528
529
        with logbook.TestHandler() as handler:
530
            with pytest.raises(AssertionError):
531
                aacgmv2.get_aacgm_coord_arr([91, 60, -91], 0, 300, self.dtime)
532
                assert handler.has_error(lerr)
533
534
        handler.close()
535
536
    def test_convert_str_to_bit_g2a(self):
537
        """Test conversion from string code to bit G2A"""
538
        assert aacgmv2.convert_str_to_bit("G2A") == aacgmv2._aacgmv2.G2A
539
540
    def test_convert_str_to_bit_a2g(self):
541
        """Test conversion from string code to bit A2G"""
542
        assert aacgmv2.convert_str_to_bit("A2G") == aacgmv2._aacgmv2.A2G
543
544
    def test_convert_str_to_bit_trace(self):
545
        """Test conversion from string code to bit TRACE"""
546
        assert aacgmv2.convert_str_to_bit("TRACE") == aacgmv2._aacgmv2.TRACE
547
548
    def test_convert_str_to_bit_allowtrace(self):
549
        """Test conversion from string code to bit ALLOWTRACE"""
550
        assert aacgmv2.convert_str_to_bit("ALLOWTRACE") == \
551
            aacgmv2._aacgmv2.ALLOWTRACE
552
553
    def test_convert_str_to_bit_badidea(self):
554
        """Test conversion from string code to bit BADIDEA"""
555
        assert aacgmv2.convert_str_to_bit("BADIDEA") == aacgmv2._aacgmv2.BADIDEA
556
557
    def test_convert_str_to_bit_geocentric(self):
558
        """Test conversion from string code to bit GEOCENTRIC"""
559
        assert aacgmv2.convert_str_to_bit("GEOCENTRIC") == \
560
            aacgmv2._aacgmv2.GEOCENTRIC
561
562
    def test_convert_str_to_bit_lowercase(self):
563
        """Test conversion from string code to bit for a lowercase code"""
564
        assert aacgmv2.convert_str_to_bit("g2a") == aacgmv2._aacgmv2.G2A
565
566
    def test_convert_str_to_bit_spaces(self):
567
        """Test conversion from string code to bit for a code with spaces"""
568
        assert aacgmv2.convert_str_to_bit("G2A | trace") == \
569
            aacgmv2._aacgmv2.G2A + aacgmv2._aacgmv2.TRACE
570
571
    def test_convert_str_to_bit_invalid(self):
572
        """Test conversion from string code to bit for an invalid code"""
573
        assert aacgmv2.convert_str_to_bit("ggoogg|") == aacgmv2._aacgmv2.G2A
574
575
    def test_convert_bool_to_bit_g2a(self):
576
        """Test conversion from string code to bit G2A"""
577
        assert aacgmv2.convert_bool_to_bit() == aacgmv2._aacgmv2.G2A
578
579
    def test_convert_bool_to_bit_a2g(self):
580
        """Test conversion from string code to bit A2G"""
581
        assert aacgmv2.convert_bool_to_bit(a2g=True) == aacgmv2._aacgmv2.A2G
582
583
    def test_convert_bool_to_bit_trace(self):
584
        """Test conversion from string code to bit TRACE"""
585
        assert aacgmv2.convert_bool_to_bit(trace=True) == aacgmv2._aacgmv2.TRACE
586
587
    def test_convert_bool_to_bit_allowtrace(self):
588
        """Test conversion from string code to bit ALLOWTRACE"""
589
        assert aacgmv2.convert_bool_to_bit(allowtrace=True) == \
590
            aacgmv2._aacgmv2.ALLOWTRACE
591
592
    def test_convert_bool_to_bit_badidea(self):
593
        """Test conversion from string code to bit BADIDEA"""
594
        assert aacgmv2.convert_bool_to_bit(badidea=True) == \
595
            aacgmv2._aacgmv2.BADIDEA
596
597
    def test_convert_bool_to_bit_geocentric(self):
598
        """Test conversion from string code to bit GEOCENTRIC"""
599
        assert aacgmv2.convert_bool_to_bit(geocentric=True) == \
600
            aacgmv2._aacgmv2.GEOCENTRIC
601
602
    def test_inv_convert_mlt_single(self):
603
        """Test MLT inversion for a single value"""
604
        mlon_1 = aacgmv2.convert_mlt(12.0, self.dtime, m2a=True)
605
        mlon_2 = aacgmv2.convert_mlt(25.0, self.dtime, m2a=True)
606
        mlon_3 = aacgmv2.convert_mlt(-1.0, self.dtime, m2a=True)
607
608
        np.testing.assert_almost_equal(mlon_1, -101.657689, decimal=4)
609
        np.testing.assert_almost_equal(mlon_2, 93.34231102, decimal=4)
610
        np.testing.assert_almost_equal(mlon_3, 63.34231102, decimal=4)
611
612
    def test_inv_convert_mlt_list(self):
613
        """Test MLT inversion for a list"""
614
        mlt_list = [12.0, 25.0, -1.0]
615
        mlon = aacgmv2.convert_mlt(mlt_list, self.dtime, m2a=True)
616
617
        np.testing.assert_allclose(mlon, [-101.657689, 93.342311, 63.342311],
618
                                   rtol=1.0e-4)
619
620
    def test_inv_convert_mlt_arr(self):
621
        """Test MLT inversion for an array"""
622
        mlt_arr = np.array([12.0, 25.0, -1.0])
623
        mlon = aacgmv2.convert_mlt(mlt_arr, self.dtime, m2a=True)
624
625
        np.testing.assert_allclose(mlon, [-101.657689, 93.342311, 63.342311],
626
                                   rtol=1.0e-4)
627
628
    def test_inv_convert_mlt_wrapping(self):
629
        """Test MLT wrapping"""
630
        mlt_arr = np.array([1.0, 25.0, -1.0, 23.0])
631
        mlon = aacgmv2.convert_mlt(mlt_arr, self.dtime, m2a=True)
632
633
        np.testing.assert_almost_equal(mlon[0], mlon[1], decimal=6)
634
        np.testing.assert_almost_equal(mlon[2], mlon[3], decimal=6)
635
636
    def test_mlt_convert_mlon_wrapping(self):
637
        """Test mlon wrapping"""
638
        mlon_arr = np.array([270.0, -90.0, 1.0, 361.0])
639
        mlt = aacgmv2.convert_mlt(mlon_arr, self.dtime, m2a=False)
640
641
        np.testing.assert_almost_equal(mlt[0], mlt[1], decimal=6)
642
        np.testing.assert_almost_equal(mlt[2], mlt[3], decimal=6)
643
644
    def test_mlt_convert_single(self):
645
        """Test MLT calculation for a single value"""
646
        mlt_1 = aacgmv2.convert_mlt(270.0, self.dtime, m2a=False)
647
        mlt_2 = aacgmv2.convert_mlt(80.0, self.dtime, m2a=False)
648
649
        np.testing.assert_almost_equal(mlt_1, 12.77717927, decimal=4)
650
        np.testing.assert_almost_equal(mlt_2, 0.1105126, decimal=4)
651
652
    def test_mlt_convert_list(self):
653
        """Test MLT calculation for a list"""
654
        mlon_list = [270.0, 80.0, -95.0]
655
        mlt = aacgmv2.convert_mlt(mlon_list, self.dtime, m2a=False)
656
657
        np.testing.assert_allclose(mlt, [12.77717927, 0.1105126, 12.44384593],
658
                                   rtol=1.0e-4)
659
660
    def test_mlt_convert_arr(self):
661
        """Test MLT calculation for an array"""
662
        mlon_arr = np.array([270.0, 80.0, -95.0])
663
        mlt = aacgmv2.convert_mlt(mlon_arr, self.dtime, m2a=False)
664
665
        np.testing.assert_allclose(mlt, [12.77717927, 0.1105126, 12.44384593],
666
                                   rtol=1.0e-4)
667