Skip to content

Commit b4bafc3

Browse files
committed
More robust testing with real navdata
1 parent 5273599 commit b4bafc3

1 file changed

Lines changed: 172 additions & 76 deletions

File tree

tests/utils/test_metrics.py

Lines changed: 172 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -21,52 +21,68 @@
2121

2222

2323

24-
# # FROM test_coordinates.py
25-
# @pytest.fixture(name="derived_2022_path")
26-
# def fixture_derived_2022_path(root_path_2022):
27-
# """Filepath of Android Derived measurements
28-
29-
# Returns
30-
# -------
31-
# derived_path : string
32-
# Location for the unit_test Android derived 2022 measurements
33-
34-
# Notes
35-
# -----
36-
# Test data is a subset of the Android Raw Measurement Dataset [4]_,
37-
# from the 2022 Decimeter Challenge. Particularly, the
38-
# train/2021-04-29-MTV-2/SamsungGalaxyS20Ultra trace. The dataset
39-
# was retrieved from
40-
# https://www.kaggle.com/competitions/smartphone-decimeter-2022/data
41-
42-
# References
43-
# ----------
44-
# .. [4] Fu, Guoyu Michael, Mohammed Khider, and Frank van Diggelen.
45-
# "Android Raw GNSS Measurement Datasets for Precise Positioning."
46-
# Proceedings of the 33rd International Technical Meeting of the
47-
# Satellite Division of The Institute of Navigation (ION GNSS+
48-
# 2020). 2020.
49-
# """
50-
# derived_path = os.path.join(root_path_2022, 'device_gnss.csv')
51-
# return derived_path
52-
53-
54-
# @pytest.fixture(name="derived_2022")
55-
# def fixture_load_derived_2022(derived_2022_path):
56-
# """Load instance of AndroidDerived2021
57-
58-
# Parameters
59-
# ----------
60-
# derived_path : pytest.fixture
61-
# String with location of Android derived measurement file
62-
63-
# Returns
64-
# -------
65-
# derived : AndroidDerived2022
66-
# Instance of AndroidDerived2022 for testing
67-
# """
68-
# derived = AndroidDerived2022(derived_2022_path)
69-
# return derived
24+
# FROM test_coordinates.py
25+
@pytest.fixture(name="root_path_2022")
26+
def fixture_root_path_2022():
27+
"""Location of measurements for unit test
28+
29+
Returns
30+
-------
31+
root_path : string
32+
Folder location containing measurements
33+
"""
34+
root_path = os.path.dirname(
35+
os.path.dirname(
36+
os.path.dirname(
37+
os.path.realpath(__file__))))
38+
root_path = os.path.join(root_path, 'data/unit_test/google_decimeter_2022')
39+
return root_path
40+
41+
@pytest.fixture(name="derived_2022_path")
42+
def fixture_derived_2022_path(root_path_2022):
43+
"""Filepath of Android Derived measurements
44+
45+
Returns
46+
-------
47+
derived_path : string
48+
Location for the unit_test Android derived 2022 measurements
49+
50+
Notes
51+
-----
52+
Test data is a subset of the Android Raw Measurement Dataset [4]_,
53+
from the 2022 Decimeter Challenge. Particularly, the
54+
train/2021-04-29-MTV-2/SamsungGalaxyS20Ultra trace. The dataset
55+
was retrieved from
56+
https://www.kaggle.com/competitions/smartphone-decimeter-2022/data
57+
58+
References
59+
----------
60+
.. [4] Fu, Guoyu Michael, Mohammed Khider, and Frank van Diggelen.
61+
"Android Raw GNSS Measurement Datasets for Precise Positioning."
62+
Proceedings of the 33rd International Technical Meeting of the
63+
Satellite Division of The Institute of Navigation (ION GNSS+
64+
2020). 2020.
65+
"""
66+
derived_path = os.path.join(root_path_2022, 'device_gnss.csv')
67+
return derived_path
68+
69+
70+
@pytest.fixture(name="derived_2022")
71+
def fixture_load_derived_2022(derived_2022_path):
72+
"""Load instance of AndroidDerived2021
73+
74+
Parameters
75+
----------
76+
derived_path : pytest.fixture
77+
String with location of Android derived measurement file
78+
79+
Returns
80+
-------
81+
derived : AndroidDerived2022
82+
Instance of AndroidDerived2022 for testing
83+
"""
84+
derived = AndroidDerived2022(derived_2022_path)
85+
return derived
7086

7187

7288
#####################################################################
@@ -180,26 +196,26 @@ def test_simple_get_dop_default(navdata, expected_dop):
180196

181197
@pytest.mark.parametrize('navdata, expected_dop, which_dop',
182198
[
183-
(lazy_fixture('simple_sat_scenario'),
184-
lazy_fixture('simple_sat_expected_dop'),
185-
{'GDOP': True, 'HDOP': True, 'VDOP': True,
186-
'PDOP': True, 'TDOP': True, 'dop_matrix': False}),
187-
(lazy_fixture('simple_sat_scenario'),
188-
lazy_fixture('simple_sat_expected_dop'),
189-
{'GDOP': True, 'HDOP': True, 'VDOP': True,
190-
'PDOP': True, 'TDOP': True, 'dop_matrix': True}),
191-
(lazy_fixture('simple_sat_scenario'),
192-
lazy_fixture('simple_sat_expected_dop'),
193-
{'GDOP': False, 'HDOP': False, 'VDOP': False,
194-
'PDOP': False, 'TDOP': True, 'dop_matrix': False}),
195-
(lazy_fixture('simple_sat_scenario'),
196-
lazy_fixture('simple_sat_expected_dop'),
197-
{'GDOP': False, 'HDOP': False, 'VDOP': False,
198-
'PDOP': False, 'TDOP': False, 'dop_matrix': True}),
199-
(lazy_fixture('simple_sat_scenario'),
200-
lazy_fixture('simple_sat_expected_dop'),
201-
{'GDOP': False, 'HDOP': False, 'VDOP': False,
202-
'PDOP': False, 'TDOP': False, 'dop_matrix': False})
199+
(lazy_fixture('simple_sat_scenario'),
200+
lazy_fixture('simple_sat_expected_dop'),
201+
{'GDOP': True, 'HDOP': True, 'VDOP': True,
202+
'PDOP': True, 'TDOP': True, 'dop_matrix': False}),
203+
(lazy_fixture('simple_sat_scenario'),
204+
lazy_fixture('simple_sat_expected_dop'),
205+
{'GDOP': True, 'HDOP': True, 'VDOP': True,
206+
'PDOP': True, 'TDOP': True, 'dop_matrix': True}),
207+
(lazy_fixture('simple_sat_scenario'),
208+
lazy_fixture('simple_sat_expected_dop'),
209+
{'GDOP': False, 'HDOP': False, 'VDOP': False,
210+
'PDOP': False, 'TDOP': True, 'dop_matrix': False}),
211+
(lazy_fixture('simple_sat_scenario'),
212+
lazy_fixture('simple_sat_expected_dop'),
213+
{'GDOP': False, 'HDOP': False, 'VDOP': False,
214+
'PDOP': False, 'TDOP': False, 'dop_matrix': True}),
215+
(lazy_fixture('simple_sat_scenario'),
216+
lazy_fixture('simple_sat_expected_dop'),
217+
{'GDOP': False, 'HDOP': False, 'VDOP': False,
218+
'PDOP': False, 'TDOP': False, 'dop_matrix': False})
203219
])
204220
def test_simple_get_dop(navdata, expected_dop, which_dop):
205221
"""
@@ -247,19 +263,99 @@ def test_simple_get_dop(navdata, expected_dop, which_dop):
247263
ind += 1
248264

249265

266+
@pytest.mark.parametrize('navdata',[
267+
lazy_fixture('derived_2022')
268+
])
269+
def test_dop_across_time(navdata):
270+
"""
271+
Test DOP calculation across time is properly added to NAV data.
272+
"""
273+
274+
dop_navdata = get_dop(navdata)
250275

276+
# Check that the DOP NavData instance has the expected keys
277+
assert dop_navdata.rows == ['gps_millis', 'HDOP', 'VDOP']
278+
279+
# Check that the DOP NavData is the expected length
280+
unique_gps_millis = np.unique(navdata['gps_millis'])
281+
assert len(dop_navdata['gps_millis']) == len(unique_gps_millis)
282+
283+
284+
@pytest.mark.parametrize('navdata, which_dop',
285+
[
286+
(lazy_fixture('derived_2022'),
287+
{'GDOP': True, 'HDOP': True, 'VDOP': True,
288+
'PDOP': True, 'TDOP': True, 'dop_matrix': False}),
289+
(lazy_fixture('derived_2022'),
290+
{'GDOP': True, 'HDOP': True, 'VDOP': True,
291+
'PDOP': True, 'TDOP': True, 'dop_matrix': True}),
292+
(lazy_fixture('derived_2022'),
293+
{'GDOP': False, 'HDOP': False, 'VDOP': False,
294+
'PDOP': False, 'TDOP': True, 'dop_matrix': True}),
295+
(lazy_fixture('derived_2022'),
296+
{'GDOP': False, 'HDOP': False, 'VDOP': False,
297+
'PDOP': False, 'TDOP': False, 'dop_matrix': True})
298+
])
299+
def test_dop_across_time_with_selection(navdata, which_dop):
300+
"""
301+
Test DOP calculation across time is properly added to NAV data.
302+
"""
251303

304+
# Make a deep copy of which_dop to ensure it was not editted
305+
which_dop_deep_copy = copy.deepcopy(which_dop)
252306

253-
# @pytest.mark.parametrize('navdata',[
254-
# lazy_fixture('derived_2022'),
255-
# ])
256-
# def test_dop_across_time(navdata):
257-
# """
258-
# Test DOP calculation across time is properly added to NAV data.
259-
# """
307+
# Perform the function under test
308+
dop_navdata = get_dop(navdata, **which_dop)
260309

261-
# dop_navdata = get_dop(navdata)
310+
# Assert that the which_dop deep copy is the same as the original
311+
assert which_dop_deep_copy == which_dop, \
312+
"The `which_dop` dictionaries was editted by the get_dop function."
262313

263-
# # Check that the DOP NavData instance has the expected keys
264-
# assert all(dop_navdata.rows == ('gps_millis', 'HDOP', 'VDOP'))
314+
# Check that the DOP NavData instance has the expected keys
315+
base_rows = which_dop.keys() - {'dop_matrix'}
316+
317+
for base_row in base_rows:
318+
if which_dop[base_row]:
319+
assert base_row in dop_navdata.rows
320+
321+
# Check that the DOP NavData is the expected length
322+
unique_gps_millis = np.unique(navdata['gps_millis'])
323+
assert len(dop_navdata['gps_millis']) == len(unique_gps_millis)
324+
325+
if 'dop_matrix' in dop_navdata:
326+
# Handle the splatting of the DOP matrix
327+
dop_labels = ['ee', 'en', 'eu', 'et',
328+
'nn', 'nu', 'nt',
329+
'uu', 'ut',
330+
'tt']
331+
332+
for label in dop_labels:
333+
assert f"dop_{label}" in dop_navdata.rows
334+
335+
if 'GDOP' in dop_navdata.rows:
336+
np.testing.assert_array_almost_equal(
337+
dop_navdata['GDOP'],
338+
np.sqrt(dop_navdata['dop_ee'] + dop_navdata['dop_nn'] +
339+
dop_navdata['dop_uu'] + dop_navdata['dop_tt']))
340+
341+
if 'HDOP' in dop_navdata.rows:
342+
np.testing.assert_array_almost_equal(
343+
dop_navdata['HDOP'],
344+
np.sqrt(dop_navdata['dop_ee'] + dop_navdata['dop_nn']))
345+
346+
if 'VDOP' in dop_navdata.rows:
347+
np.testing.assert_array_almost_equal(
348+
dop_navdata['VDOP'],
349+
np.sqrt(dop_navdata['dop_uu']))
350+
351+
if 'PDOP' in dop_navdata.rows:
352+
np.testing.assert_array_almost_equal(
353+
dop_navdata['PDOP'],
354+
np.sqrt(dop_navdata['dop_ee'] + dop_navdata['dop_nn'] +
355+
dop_navdata['dop_uu']))
356+
357+
if 'TDOP' in dop_navdata.rows:
358+
np.testing.assert_array_almost_equal(
359+
dop_navdata['TDOP'],
360+
np.sqrt(dop_navdata['dop_tt']))
265361

0 commit comments

Comments
 (0)