Passed
Pull Request — develop (#79)
by Angeline
01:23
created

test_c_aacgmv2   A

Complexity

Total Complexity 20

Size/Duplication

Total Lines 323
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 20
eloc 182
dl 0
loc 323
rs 10
c 0
b 0
f 0

17 Methods

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