Passed
Pull Request — develop (#128)
by
unknown
04:24
created

TestFortranApex.setup_method()   A

Complexity

Conditions 1

Size

Total Lines 33
Code Lines 28

Duplication

Lines 0
Ratio 0 %

Importance

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