test_fortranapex.TestFortranApex.setup_method()   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 33
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 28
nop 1
dl 0
loc 33
rs 9.208
c 0
b 0
f 0
1
# -*- coding: utf-8 -*-
2
"""Test the apexpy.fortranapex class
3
4
Notes
5
-----
6
Whenever function outputs are tested against hard-coded numbers, the test
7
results (numbers) were obtained by running the code that is tested.  Therefore,
8
these tests below only check that nothing changes when refactoring, etc., and
9
not if the results are actually correct.
10
11
These results are expected to change when IGRF is updated.
12
13
"""
14
15
from numpy.testing import assert_allclose
16
from importlib import resources
17
import os
18
import pytest
19
20
import apexpy
21
from apexpy import fortranapex as fa
22
23
24
class TestFortranApex(object):
25
    """Test class for the Python-wrapped Fortran functions."""
26
27
    def setup_method(self):
28
        """Initialize each test."""
29
        datafile = os.path.join(resources.files(apexpy), 'apexsh.dat')
30
        fa.loadapxsh(datafile, 2000)
31
32
        # Set the inputs
33
        self.lat = 60
34
        self.lon = 15
35
        self.height = 100
36
        self.refh = 300
37
        self.vecflg = 1
38
        self.precision = 1e-10
39
40
        # Set the output values
41
        self.glat = 50.979549407958984
42
        self.glon = -66.16891479492188
43
        self.error = 2.8316469524725107e-06
44
        self.qlat = 56.531288146972656
45
        self.qlon = 94.1068344116211
46
        self.mlat = 55.94841766357422
47
        self.mlon = 94.1068344116211
48
        self.f1 = [1.079783, 0.10027137]
49
        self.f2 = [-0.24546318, 0.90718889]
50
        self.fmag = 1.0041800737380981
51
        self.d1 = [0.9495701, 0.25693053, 0.09049474]
52
        self.d2 = [0.10011087, -1.0780545, -0.33892432]
53
        self.d3 = [0.00865356, 0.27327004, -0.8666646]
54
        self.dmag = 1.100391149520874
55
        self.e1 = [1.0269295, 0.08382964, 0.03668632]
56
        self.e2 = [0.24740215, -0.82374191, -0.25726584]
57
        self.e3 = [0.01047826, 0.33089194, -1.04941]
58
        self.out = None
59
        self.test_out = None
60
61
    def teardown_method(self):
62
        """Clean environment after each test."""
63
        del self.lat, self.lon, self.height, self.refh, self.vecflg
64
        del self.qlat, self.qlon, self.mlat, self.mlon, self.f1, self.f2
65
        del self.fmag, self.d1, self.d2, self.d3, self.dmag, self.e1
66
        del self.e2, self.e3, self.precision, self.glat, self.glon, self.error
67
        del self.out, self.test_out
68
69
    def run_test_evaluation(self, rtol=1e-5, atol=1e-5):
70
        """Run the evaluation of the test results.
71
72
        Parameters
73
        ----------
74
        rtol : float
75
            Relative tolerance, default value based on old code's precision
76
            (default=1e-5)
77
        atol : float
78
            Absolute tolerance, default value based on old code's precision
79
            (default=1e-5)
80
81
        """
82
83
        assert self.out is not None, "No results to test"
84
        assert self.test_out is not None, "No 'truth' results provided"
85
        assert len(self.out) == len(self.test_out), "Mismatched outputs"
86
87
        for i, out_val in enumerate(self.out):
88
            assert_allclose(out_val, self.test_out[i], rtol=rtol, atol=atol)
89
        return
90
91
    def test_apxg2q(self):
92
        """Test fortran apex geographic to quasi-dipole."""
93
        # Get the output
94
        self.out = fa.apxg2q(self.lat, self.lon, self.height, self.vecflg)
95
96
        # Test the output
97
        self.test_out = (self.qlat, self.qlon, self.f1, self.f2, self.fmag)
98
        self.run_test_evaluation()
99
        return
100
101
    def test_apxg2all(self):
102
        """Test fortran apex geographic to all outputs."""
103
        # Get the output
104
        self.out = fa.apxg2all(self.lat, self.lon, self.height, self.refh,
105
                               self.vecflg)
106
107
        # Test the output
108
        self.test_out = (self.qlat, self.qlon, self.mlat, self.mlon, self.f1,
109
                         self.f2, self.fmag, self.d1, self.d2, self.d3,
110
                         self.dmag, self.e1, self.e2, self.e3)
111
        self.run_test_evaluation()
112
        return
113
114
    def test_apxq2g(self):
115
        """ Test fortran quasi-dipole to geographic."""
116
        # Get the output
117
        self.out = fa.apxq2g(self.lat, self.lon, self.height, self.precision)
118
119
        # Test the output
120
        self.test_out = (self.glat, self.glon, self.error)
121
        self.run_test_evaluation()
122
        return
123
124
    @pytest.mark.parametrize("lat", [0, 30, 60, 89])
125
    @pytest.mark.parametrize("lon", [-179, -90, 0, 90, 179])
126
    def test_g2q2d(self, lat, lon):
127
        """ Test fortran geographic to quasi-dipole and back again.
128
129
        Parameters
130
        ----------
131
        lat : int or float
132
            Latitude in degrees N
133
        lon : int or float
134
            Longitude in degrees E
135
136
        """
137
        self.out = fa.apxg2q(lat, lon, self.height, 0)
138
        self.test_out = fa.apxq2g(self.out[0], self.out[1], self.height,
139
                                  self.precision)
140
141
        # Test the results againt the initial input
142
        assert_allclose(self.test_out[0], lat, atol=0.01)
143
        assert_allclose(self.test_out[1], lon, atol=0.01)
144
145
    def test_apxq2g_lowprecision(self):
146
        """Test low precision error value."""
147
        self.out = fa.apxq2g(self.lat, self.lon, self.height, -1)
148
149
        # Test the output
150
        self.test_out = (51.00891876220703, -66.11973571777344, -9999.0)
151
        self.run_test_evaluation()
152
        return
153