~awuerl/blitzortung-python/master

« back to all changes in this revision

Viewing changes to tests/test_calc.py

  • Committer: Andreas Würl
  • Date: 2016-09-14 20:39:51 UTC
  • mto: This revision was merged to the branch mainline in revision 392.
  • Revision ID: git-v1:0577158d36adaee55ba3f8a63918b601e8a4edd4
remove pandas dependency

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -*- coding: utf8 -*-
2
 
 
3
 
"""
4
 
 
5
 
   Copyright 2014-2016 Andreas Würl
6
 
 
7
 
   Licensed under the Apache License, Version 2.0 (the "License");
8
 
   you may not use this file except in compliance with the License.
9
 
   You may obtain a copy of the License at
10
 
 
11
 
       http://www.apache.org/licenses/LICENSE-2.0
12
 
 
13
 
   Unless required by applicable law or agreed to in writing, software
14
 
   distributed under the License is distributed on an "AS IS" BASIS,
15
 
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
 
   See the License for the specific language governing permissions and
17
 
   limitations under the License.
18
 
 
19
 
"""
20
 
 
21
 
import unittest
22
 
import math
23
 
import datetime
24
 
 
25
 
import pandas as pd
26
 
from mock import MagicMock, call
27
 
 
28
 
import blitzortung.builder
29
 
 
30
 
import blitzortung.calc
31
 
import blitzortung.types
32
 
 
33
 
 
34
 
class TestSignalVelocity(unittest.TestCase):
35
 
    def setUp(self):
36
 
        self.signal_velocity = blitzortung.calc.SignalVelocity()
37
 
 
38
 
    def test_get_distance_time(self):
39
 
        self.assertAlmostEqual(33440, self.signal_velocity.get_distance_time(10000.0))
40
 
 
41
 
    def test_get_time_distance(self):
42
 
        self.assertAlmostEqual(29.90429768, self.signal_velocity.get_time_distance(100))
43
 
 
44
 
 
45
 
class ThreePointSolutionTest(unittest.TestCase):
46
 
    def setUp(self):
47
 
        self.timestamp = datetime.datetime.utcnow()
48
 
        event_builder = blitzortung.builder.Event()
49
 
        event_builder.set_x(11.0)
50
 
        event_builder.set_y(49.0)
51
 
        event_builder.set_timestamp(self.timestamp)
52
 
        self.center_event = event_builder.build()
53
 
        self.radians_factor = math.pi / 180
54
 
        self.signal_velocity = blitzortung.calc.SignalVelocity()
55
 
 
56
 
    def test_get_solution_location(self):
57
 
        solution = blitzortung.calc.ThreePointSolution(self.center_event, 0, 100000, self.signal_velocity)
58
 
 
59
 
        self.assertAlmostEqual(solution.x, 11)
60
 
        self.assertAlmostEqual(solution.y, 49.89913151)
61
 
 
62
 
        solution = blitzortung.calc.ThreePointSolution(self.center_event, math.pi / 2, 100000, self.signal_velocity)
63
 
 
64
 
        self.assertAlmostEqual(solution.x, 12.3664992)
65
 
        self.assertAlmostEqual(solution.y, 48.9919072)
66
 
 
67
 
    def test_get_solution_timestamp(self):
68
 
        solution = blitzortung.calc.ThreePointSolution(self.center_event, 0, 100000, self.signal_velocity)
69
 
 
70
 
        timestamp = self.center_event.timestamp
71
 
        total_nanoseconds = timestamp.value - self.signal_velocity.get_distance_time(100000)
72
 
        strike_timestamp = pd.Timestamp(total_nanoseconds, tz=timestamp.tzinfo)
73
 
 
74
 
        self.assertEqual(strike_timestamp, solution.timestamp)
75
 
 
76
 
 
77
 
class ThreePointSolverTest(unittest.TestCase):
78
 
    def setUp(self):
79
 
        self.signal_velocity = blitzortung.calc.SignalVelocity()
80
 
        self.prepare_solution(11.5, 49.5)
81
 
 
82
 
    def prepare_solution(self, x_coord, y_coord):
83
 
        self.simulated_data = blitzortung.calc.SimulatedData(x_coord, y_coord)
84
 
        self.center_event = self.simulated_data.get_event_at(11.0, 49.0)
85
 
        self.event_1 = self.simulated_data.get_event_at(12.0, 49.0)
86
 
        self.event_2 = self.simulated_data.get_event_at(11.0, 50.0)
87
 
 
88
 
        self.events = [self.center_event, self.event_1, self.event_2]
89
 
 
90
 
    def test_solve_with_no_solution(self):
91
 
        self.prepare_solution(11.5, 49.0)
92
 
        self.event_1 = self.simulated_data.get_event_at(10.0, 49.0)
93
 
        self.event_2 = self.simulated_data.get_event_at(12.0, 49.0)
94
 
 
95
 
        self.events = [self.center_event, self.event_1, self.event_2]
96
 
 
97
 
        solver = blitzortung.calc.ThreePointSolver(self.events)
98
 
 
99
 
        solutions = solver.solutions
100
 
 
101
 
        self.assertEqual(0, len(solutions))
102
 
 
103
 
    def test_solve_with_one_solution(self):
104
 
        location = blitzortung.types.Point(11.7, 49.3)
105
 
        self.prepare_solution(location.x, location.y)
106
 
 
107
 
        solver = blitzortung.calc.ThreePointSolver(self.events)
108
 
 
109
 
        solutions = solver.solutions
110
 
 
111
 
        self.assertEqual(1, len(solutions))
112
 
        self.assertEqual(location, solutions[0])
113
 
 
114
 
    def test_solve_with_two_solutions(self):
115
 
        location = blitzortung.types.Point(11.1, 49.1)
116
 
        self.prepare_solution(location.x, location.y)
117
 
 
118
 
        solver = blitzortung.calc.ThreePointSolver(self.events)
119
 
 
120
 
        solutions = solver.solutions
121
 
 
122
 
        self.assertEqual(2, len(solutions))
123
 
 
124
 
        self.assertEqual(location, solutions[0])
125
 
 
126
 
        self.assertNotEqual(0.0, location.distance_to(solutions[1]))
127
 
 
128
 
    def test_get_solution_for_event_list(self):
129
 
        location = blitzortung.types.Point(11.1, 49.1)
130
 
        self.prepare_solution(location.x, location.y)
131
 
 
132
 
        solver = blitzortung.calc.ThreePointSolver(self.events)
133
 
 
134
 
        self.assertEqual(2, len(solver.solutions))
135
 
 
136
 
        solution = solver.get_solution()
137
 
 
138
 
        self.assertAlmostEqual(11.1, solution.x, 5)
139
 
        self.assertAlmostEqual(49.1, solution.y, 5)
140
 
 
141
 
    def test_azimuth_to_angle(self):
142
 
        solver = blitzortung.calc.ThreePointSolver(self.events)
143
 
 
144
 
        self.assertAlmostEqual(math.pi / 2, solver.azimuth_to_angle(0))
145
 
        self.assertAlmostEqual(0, solver.azimuth_to_angle(math.pi / 2))
146
 
        self.assertAlmostEqual(math.pi, solver.azimuth_to_angle(-math.pi / 2))
147
 
 
148
 
    def test_angle_to_azimuth(self):
149
 
        solver = blitzortung.calc.ThreePointSolver(self.events)
150
 
 
151
 
        self.assertAlmostEqual(math.pi / 2, solver.angle_to_azimuth(0))
152
 
        self.assertAlmostEqual(0, solver.angle_to_azimuth(math.pi / 2))
153
 
        self.assertAlmostEqual(-math.pi / 2, solver.angle_to_azimuth(math.pi))
154
 
 
155
 
 
156
 
class TestFitSeed(unittest.TestCase):
157
 
    def setUp(self):
158
 
        self.signal_velocity = blitzortung.calc.SignalVelocity()
159
 
 
160
 
    def generic_combination(self, events, expected_args):
161
 
        fit_seed = blitzortung.calc.FitSeed(events, self.signal_velocity)
162
 
        fit_seed.find_three_point_solution = MagicMock()
163
 
 
164
 
        fit_seed.get_seed_event()
165
 
 
166
 
        self.assertEqual(len(expected_args), len(fit_seed.find_three_point_solution.mock_calls))
167
 
 
168
 
        expected = [call.find_three_point_solution(arg) for arg in expected_args]
169
 
        self.assertTrue(expected == fit_seed.find_three_point_solution.mock_calls)
170
 
 
171
 
    def test_combinations_with_6_events(self):
172
 
        events = [1, 2, 3, 4, 5, 6]
173
 
        expected_args = [[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], [1, 4, 5]]
174
 
        self.generic_combination(events, expected_args)
175
 
 
176
 
    def test_combinations_with_5_events(self):
177
 
        events = [1, 2, 3, 4, 5]
178
 
        expected_args = [[1, 2, 3], [1, 2, 4], [1, 2, 5], [1, 3, 4], [1, 3, 5], [1, 4, 5]]
179
 
        self.generic_combination(events, expected_args)
180
 
 
181
 
    def test_combinations_with_4_events(self):
182
 
        events = [1, 2, 3, 4]
183
 
        expected_args = [[1, 2, 3], [1, 2, 4], [1, 3, 4]]
184
 
        self.generic_combination(events, expected_args)
185
 
 
186
 
    def test_combinations_with_3_events(self):
187
 
        events = [1, 2, 3]
188
 
        expected_args = [[1, 2, 3]]
189
 
        self.generic_combination(events, expected_args)
190
 
 
191
 
    def test_combinations_with_2_events(self):
192
 
        events = [1, 2]
193
 
        expected_args = []
194
 
        self.generic_combination(events, expected_args)
195
 
 
196
 
 
197
 
class TestLeastSquareFit(unittest.TestCase):
198
 
    def setUp(self):
199
 
        self.strike_location = blitzortung.types.Point(11.3, 49.5)
200
 
 
201
 
        self.simulated_data = blitzortung.calc.SimulatedData(self.strike_location)
202
 
        self.source_event = self.simulated_data.get_source_event()
203
 
 
204
 
        self.timestamp = self.simulated_data.get_timestamp()
205
 
 
206
 
        event_builder = blitzortung.builder.Event()
207
 
        event_builder.set_timestamp(self.timestamp)
208
 
        event_builder.set_x(11.4)
209
 
        event_builder.set_y(49.4)
210
 
        self.three_point_solution = event_builder.build()
211
 
 
212
 
        self.events = []
213
 
        self.events.append(self.simulated_data.get_event_at(11.0, 50.0))
214
 
        self.events.append(self.simulated_data.get_event_at(11.0, 49.0))
215
 
        self.events.append(self.simulated_data.get_event_at(12.0, 49.0))
216
 
        self.events.append(self.simulated_data.get_event_at(12.0, 50.0))
217
 
 
218
 
        self.fit = blitzortung.calc.LeastSquareFit(self.three_point_solution, self.events,
219
 
                                                   blitzortung.calc.SignalVelocity())
220
 
 
221
 
    def test_get_parameter(self):
222
 
        self.assertAlmostEqual(11.4, self.fit.get_parameter(blitzortung.calc.FitParameter.Longitude))
223
 
        self.assertAlmostEqual(49.4, self.fit.get_parameter(blitzortung.calc.FitParameter.Latitude))
224
 
        self.assertAlmostEquals(-199.525, self.fit.get_parameter(blitzortung.calc.FitParameter.Time))
225
 
 
226
 
    def test_get_location(self):
227
 
        self.assertEquals(11.4, self.fit.get_location().x)
228
 
        self.assertEquals(49.4, self.fit.get_location().y)
229
 
 
230
 
    def test_calculate_time_value(self):
231
 
        self.assertEqual(-199.525, self.fit.calculate_time_value(self.timestamp))
232
 
        self.assertEqual(0.0, self.fit.calculate_time_value(self.events[0].timestamp))
233
 
 
234
 
    def test_calculate_residual_time(self):
235
 
        self.assertAlmostEqual(-43.601, self.fit.get_residual_time_at(self.events[0]))
236
 
 
237
 
    def test_leastsquare_fit(self):
238
 
        # for event in self.events:
239
 
        # print event, "%.1f %.3f" % (self.source_event.distance_to(event)/1000.0, self.source_event.ns_difference_to(event)/1000.0)
240
 
 
241
 
        #for parameter_value in self.fit.parameters.items():
242
 
        #    print parameter_value
243
 
 
244
 
        while self.fit.requires_another_iteration():
245
 
            self.fit.perform_fit_step()
246
 
 
247
 
            parameter_string = ["%.3f" % self.fit.parameters[index] for index in range(0, len(self.fit.parameters))]
248
 
            print("%.1f, %.3f %s" % (
249
 
                self.fit.get_least_square_sum(), self.fit.get_least_square_change(), ' '.join(parameter_string)))
250
 
 
251
 
        strike_location = self.fit.get_location()
252
 
        self.assertAlmostEqual(11.3, strike_location.x, 4)
253
 
        self.assertAlmostEqual(49.5, strike_location.y, 4)