aacgmv2.tests.test_c_aacgmv2   A
last analyzed

Complexity

Total Complexity 23

Size/Duplication

Total Lines 328
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 185
dl 0
loc 328
rs 10
c 0
b 0
f 0
wmc 23

17 Methods

Rating   Name   Duplication   Size   Complexity  
A TestCAACGMV2.test_inv_mlt_convert_yrsec() 0 24 1
A TestCAACGMV2.test_forbidden() 0 9 3
A TestCAACGMV2.test_convert_high_denied() 0 9 3
A TestCAACGMV2.setup_method() 0 22 1
A TestCAACGMV2.test_convert() 0 27 1
A TestCAACGMV2.test_mlt_convert_arr() 0 7 1
A TestCAACGMV2.test_mlt_convert() 0 18 1
A TestCAACGMV2.test_inv_mlt_convert_arr() 0 8 1
A TestCAACGMV2.test_mlt_convert_yrsec() 0 23 1
A TestCAACGMV2.test_convert_geocentric() 0 38 1
A TestCAACGMV2.test_fail_set_datetime() 0 8 3
A TestCAACGMV2.test_constants() 0 18 1
A TestCAACGMV2.test_set_datetime() 0 12 1
A TestCAACGMV2.test_convert_high() 0 30 1
A TestCAACGMV2.teardown_method() 0 5 1
A TestCAACGMV2.test_convert_arr() 0 24 1
A TestCAACGMV2.test_inv_mlt_convert() 0 18 1
1
"""Unit tests for the AACGMV2 wrapped C code."""
2
import datetime as dt
3
import numpy as np
4
import pytest
5
6
import aacgmv2
7
8
9
class TestCAACGMV2(object):
10
    """Unit tests for the AACGMV2 wrapped C code."""
11
12
    def setup_method(self):
13
        """Run before every method to create a clean testing setup."""
14
        self.date_args = [(2014, 3, 22, 3, 11, 0), (2018, 1, 1, 0, 0, 0)]
15
        self.long_date = [2014, 3, 22, 3, 11, 0]
16
        self.mlat = None
17
        self.mlon = None
18
        self.rshell = None
19
        self.bad_ind = None
20
        self.mlt = None
21
        self.lat_in = [45.5, 60]
22
        self.lon_in = [-23.5, 0]
23
        self.alt_in = [1135, 300]
24
        self.code = {'G2A': aacgmv2._aacgmv2.G2A, 'A2G': aacgmv2._aacgmv2.A2G,
25
                     'TG2A': aacgmv2._aacgmv2.G2A + aacgmv2._aacgmv2.TRACE,
26
                     'TA2G': aacgmv2._aacgmv2.A2G + aacgmv2._aacgmv2.TRACE}
27
        self.lat_comp = {'G2A': [48.1902, 58.2199], 'A2G': [30.7550, 50.4364],
28
                         'TG2A': [48.1954, 58.2194], 'TA2G': [30.7661, 50.4403]}
29
        self.lon_comp = {'G2A': [57.7505, 80.7290], 'A2G': [-94.1724, -77.5309],
30
                         'TG2A': [57.7456, 80.7371],
31
                         'TA2G': [-94.1727, -77.5426]}
32
        self.r_comp = {'G2A': [1.1775, 1.0457], 'A2G': [1133.6246, 305.7305],
33
                       'TG2A': [1.1775, 1.0457], 'TA2G': [1133.6282, 305.7319]}
34
35
    def teardown_method(self):
36
        """Run after every method to clean up previous testing."""
37
        del self.date_args, self.long_date, self.mlat, self.mlon, self.mlt
38
        del self.lat_in, self.lon_in, self.alt_in, self.lat_comp, self.lon_comp
39
        del self.r_comp, self.code, self.bad_ind
40
41
    @pytest.mark.parametrize('mattr,val', [(aacgmv2._aacgmv2.G2A, 0),
42
                                           (aacgmv2._aacgmv2.A2G, 1),
43
                                           (aacgmv2._aacgmv2.TRACE, 2),
44
                                           (aacgmv2._aacgmv2.ALLOWTRACE, 4),
45
                                           (aacgmv2._aacgmv2.BADIDEA, 8),
46
                                           (aacgmv2._aacgmv2.GEOCENTRIC, 16)])
47
    def test_constants(self, mattr, val):
48
        """Test module constants.
49
50
        Parameters
51
        ----------
52
        mattr : int
53
            Attribute holding an integer value
54
        val : int
55
            Expected integer value
56
57
        """
58
        np.testing.assert_equal(mattr, val)
59
60
    @pytest.mark.parametrize('idate', [0, 1])
61
    def test_set_datetime(self, idate):
62
        """Test set_datetime.
63
64
        Parameters
65
        ----------
66
        idate : int
67
            Integer date value
68
69
        """
70
        self.mlt = aacgmv2._aacgmv2.set_datetime(*self.date_args[idate])
71
        assert self.mlt is None, "MLT is {:}, not None".format(self.mlt)
72
73
    def test_fail_set_datetime(self):
74
        """Test unsuccessful set_datetime."""
75
        self.long_date[0] = 1013
76
        with pytest.raises(RuntimeError) as rerr:
77
            aacgmv2._aacgmv2.set_datetime(*self.long_date)
78
79
        if str(rerr).find("AACGM_v2_SetDateTime returned error code -1") < 0:
80
            raise AssertionError('unknown error message: {:}'.format(str(rerr)))
81
82
    @pytest.mark.parametrize('idate,ckey', [(0, 'G2A'), (1, 'G2A'),
83
                                            (0, 'A2G'), (1, 'A2G'),
84
                                            (0, 'TG2A'), (1, 'TG2A'),
85
                                            (0, 'TA2G'), (1, 'TA2G')])
86
    def test_convert(self, idate, ckey):
87
        """Test convert from geographic to magnetic coordinates.
88
89
        Parameters
90
        ----------
91
        idate : int
92
            Integer date value
93
        ckey : str
94
            Transforming string combination
95
96
        """
97
        aacgmv2._aacgmv2.set_datetime(*self.date_args[idate])
98
        (self.mlat, self.mlon,
99
         self.rshell) = aacgmv2._aacgmv2.convert(self.lat_in[idate],
100
                                                 self.lon_in[idate],
101
                                                 self.alt_in[idate],
102
                                                 self.code[ckey])
103
        np.testing.assert_almost_equal(self.mlat, self.lat_comp[ckey][idate],
104
                                       decimal=4)
105
        np.testing.assert_almost_equal(self.mlon, self.lon_comp[ckey][idate],
106
                                       decimal=4)
107
        np.testing.assert_almost_equal(self.rshell, self.r_comp[ckey][idate],
108
                                       decimal=4)
109
110
    @pytest.mark.parametrize('ckey', ['G2A', 'A2G', 'TG2A', 'TA2G'])
111
    def test_convert_arr(self, ckey):
112
        """Test convert_arr using from magnetic to geodetic coordinates.
113
114
        Parameters
115
        ----------
116
        ckey : str
117
            Transforming string combination
118
119
        """
120
        aacgmv2._aacgmv2.set_datetime(*self.date_args[0])
121
        (self.mlat, self.mlon, self.rshell,
122
         self.bad_ind) = aacgmv2._aacgmv2.convert_arr(self.lat_in, self.lon_in,
123
                                                      self.alt_in,
124
                                                      self.code[ckey])
125
126
        np.testing.assert_equal(len(self.mlat), len(self.lat_in))
127
        np.testing.assert_almost_equal(self.mlat[0], self.lat_comp[ckey][0],
128
                                       decimal=4)
129
        np.testing.assert_almost_equal(self.mlon[0], self.lon_comp[ckey][0],
130
                                       decimal=4)
131
        np.testing.assert_almost_equal(self.rshell[0], self.r_comp[ckey][0],
132
                                       decimal=4)
133
        np.testing.assert_equal(self.bad_ind[0], -1)
134
135
    def test_forbidden(self):
136
        """Test convert failure."""
137
        self.lat_in[0] = 7
138
        with pytest.raises(RuntimeError) as rerr:
139
            aacgmv2._aacgmv2.convert(self.lat_in[0], self.lon_in[0], 0,
140
                                     aacgmv2._aacgmv2.G2A)
141
142
        if str(rerr).find("AACGM_v2_Convert returned error code -1") < 0:
143
            raise AssertionError('unknown error message: {:}'.format(str(rerr)))
144
145
    def test_convert_high_denied(self):
146
        """Test for failure when converting to high alt geod to mag coords."""
147
        aacgmv2._aacgmv2.set_datetime(*self.date_args[0])
148
        with pytest.raises(RuntimeError) as rerr:
149
            aacgmv2._aacgmv2.convert(self.lat_in[0], self.lon_in[0], 5500,
150
                                     aacgmv2._aacgmv2.G2A)
151
152
        if str(rerr).find("AACGM_v2_Convert returned error code -4") < 0:
153
            raise AssertionError('unknown error message: {:}'.format(str(rerr)))
154
155
    @pytest.mark.parametrize('code,lat_comp,lon_comp,r_comp',
156
                             [(aacgmv2._aacgmv2.G2A + aacgmv2._aacgmv2.TRACE,
157
                               59.9753, 57.7294, 1.8626),
158
                              (aacgmv2._aacgmv2.G2A
159
                               + aacgmv2._aacgmv2.ALLOWTRACE, 59.9753, 57.7294,
160
                               1.8626),
161
                              (aacgmv2._aacgmv2.G2A + aacgmv2._aacgmv2.BADIDEA,
162
                               58.7286, 56.4296, 1.8626)])
163
    def test_convert_high(self, code, lat_comp, lon_comp, r_comp):
164
        """Test convert from high altitude geodetic to magnetic coordinates.
165
166
        Parameters
167
        ----------
168
        code : int
169
            Integer code value
170
        lat_comp : float
171
            Comparison latitude in degrees N
172
        lon_comp : float
173
            Comparison longitude in degrees E
174
        r_comp : float
175
            Comparison radius in Earth Radii.
176
177
        """
178
        aacgmv2._aacgmv2.set_datetime(*self.date_args[0])
179
        (self.mlat, self.mlon,
180
         self.rshell) = aacgmv2._aacgmv2.convert(self.lat_in[0], self.lon_in[0],
181
                                                 5500, code)
182
        np.testing.assert_almost_equal(self.mlat, lat_comp, decimal=4)
183
        np.testing.assert_almost_equal(self.mlon, lon_comp, decimal=4)
184
        np.testing.assert_almost_equal(self.rshell, r_comp, decimal=4)
185
186
    @pytest.mark.parametrize('code,lat_comp,lon_comp,r_comp',
187
                             [(aacgmv2._aacgmv2.G2A
188
                               + aacgmv2._aacgmv2.GEOCENTRIC, 48.3784, 57.7844,
189
                               1.1781),
190
                              (aacgmv2._aacgmv2.G2A
191
                               + aacgmv2._aacgmv2.GEOCENTRIC, 48.3784, 57.7844,
192
                               1.1781),
193
                              (aacgmv2._aacgmv2.A2G
194
                               + aacgmv2._aacgmv2.GEOCENTRIC, 30.6117, -94.1724,
195
                               1135.0000),
196
                              (aacgmv2._aacgmv2.G2A + aacgmv2._aacgmv2.TRACE
197
                               + aacgmv2._aacgmv2.GEOCENTRIC, 48.3836, 57.7793,
198
                               1.1781),
199
                              (aacgmv2._aacgmv2.A2G + aacgmv2._aacgmv2.TRACE
200
                               + aacgmv2._aacgmv2.GEOCENTRIC, 30.6227, -94.1727,
201
                               1135.0000)])
202
    def test_convert_geocentric(self, code, lat_comp, lon_comp, r_comp):
203
        """Test convert for different code inputs with geocentric coords.
204
205
        Parameters
206
        ----------
207
        code : int
208
            Integer code value
209
        lat_comp : float
210
            Comparison latitude in degrees N
211
        lon_comp : float
212
            Comparison longitude in degrees E
213
        r_comp : float
214
            Comparison radius in Earth Radii.
215
216
        """
217
        aacgmv2._aacgmv2.set_datetime(*self.date_args[0])
218
        (self.mlat, self.mlon,
219
         self.rshell) = aacgmv2._aacgmv2.convert(self.lat_in[0], self.lon_in[0],
220
                                                 self.alt_in[0], code)
221
        np.testing.assert_almost_equal(self.mlat, lat_comp, decimal=4)
222
        np.testing.assert_almost_equal(self.mlon, lon_comp, decimal=4)
223
        np.testing.assert_almost_equal(self.rshell, r_comp, decimal=4)
224
225
    @pytest.mark.parametrize('marg,mlt_comp',
226
                             [(12.0, -153.6033), (25.0, 41.3967),
227
                              (-1.0, 11.3967)])
228
    def test_inv_mlt_convert(self, marg, mlt_comp):
229
        """Test MLT inversion.
230
231
        Parameters
232
        ----------
233
        marg : float
234
            Input argument
235
        mlt_comp : float
236
            Expected output
237
238
        """
239
        self.long_date = list(self.long_date)
240
        self.long_date.append(marg)
241
        self.mlon = aacgmv2._aacgmv2.inv_mlt_convert(*self.long_date)
242
        np.testing.assert_almost_equal(self.mlon, mlt_comp, decimal=4)
243
244
    def test_inv_mlt_convert_arr(self):
245
        """Test array MLT inversion."""
246
        self.date_args = [[ldate for j in range(3)] for ldate in self.long_date]
247
        self.mlt = [12.0, 25.0, -1.0]
248
        self.lon_in = [-153.6033, 41.3967, 11.3967]
249
        self.mlon = aacgmv2._aacgmv2.inv_mlt_convert_arr(*self.date_args,
250
                                                         self.mlt)
251
        np.testing.assert_almost_equal(self.mlon, self.lon_in, decimal=4)
252
253
    @pytest.mark.parametrize('marg,mlt_comp',
254
                             [(12.0, -153.6033), (25.0, 41.3967),
255
                              (-1.0, 11.3967)])
256
    def test_inv_mlt_convert_yrsec(self, marg, mlt_comp):
257
        """Test MLT inversion with year and seconds of year.
258
259
        Parameters
260
        ----------
261
        marg : float
262
            Input argument
263
        mlt_comp : float
264
            Expected output
265
266
        """
267
        dtime = dt.datetime(*self.long_date)
268
        soy = (int(dtime.strftime("%j")) - 1) * 86400 + dtime.hour * 3600 \
269
            + dtime.minute * 60 + dtime.second
270
271
        self.mlon = aacgmv2._aacgmv2.inv_mlt_convert_yrsec(dtime.year, soy,
272
                                                           marg)
273
274
        np.testing.assert_almost_equal(self.mlon, mlt_comp, decimal=4)
275
276
        del dtime, soy
277
278
    @pytest.mark.parametrize('marg,mlt_comp',
279
                             [(270.0, 16.2402), (80.0, 3.5736),
280
                              (-90.0, 16.2402)])
281
    def test_mlt_convert(self, marg, mlt_comp):
282
        """Test MLT calculation with different longitudes.
283
284
        Parameters
285
        ----------
286
        marg : float
287
            Input argument
288
        mlt_comp : float
289
            Expected output
290
291
        """
292
        mlt_args = list(self.long_date)
293
        mlt_args.append(marg)
294
        self.mlt = aacgmv2._aacgmv2.mlt_convert(*mlt_args)
295
        np.testing.assert_almost_equal(self.mlt, mlt_comp, decimal=4)
296
297
    def test_mlt_convert_arr(self):
298
        """Test array MLT conversion."""
299
        self.date_args = [[ldate for j in range(3)] for ldate in self.long_date]
300
        self.mlon = [-153.6033, 41.3967, 11.3967]
301
        self.lon_in = [12.0, 1.0, 23.0]
302
        self.mlt = aacgmv2._aacgmv2.mlt_convert_arr(*self.date_args, self.mlon)
303
        np.testing.assert_almost_equal(self.mlt, self.lon_in, decimal=4)
304
305
    @pytest.mark.parametrize('marg,mlt_comp',
306
                             [(270.0, 16.2402), (80.0, 3.5736),
307
                              (-90.0, 16.2402)])
308
    def test_mlt_convert_yrsec(self, marg, mlt_comp):
309
        """Test MLT calculation using year and seconds of year.
310
311
        Parameters
312
        ----------
313
        marg : float
314
            Input argument
315
        mlt_comp : float
316
            Expected output
317
318
        """
319
        dtime = dt.datetime(*self.long_date)
320
        soy = (int(dtime.strftime("%j")) - 1) * 86400 + dtime.hour * 3600 \
321
            + dtime.minute * 60 + dtime.second
322
323
        self.mlt = aacgmv2._aacgmv2.mlt_convert_yrsec(dtime.year, soy, marg)
324
325
        np.testing.assert_almost_equal(self.mlt, mlt_comp, decimal=4)
326
327
        del dtime, soy
328