Skip to content

Commit

Permalink
unified conftest for all modules
Browse files Browse the repository at this point in the history
  • Loading branch information
betaBison committed Feb 13, 2024
1 parent 9444c8a commit 352f0f4
Show file tree
Hide file tree
Showing 23 changed files with 537 additions and 1,321 deletions.
7 changes: 0 additions & 7 deletions docs/source/reference/test_navdata/conftest.rst

This file was deleted.

1 change: 0 additions & 1 deletion docs/source/reference/test_navdata/modules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,5 @@ navdata
.. toctree::
:maxdepth: 4

conftest
test_navdata
test_operations
7 changes: 0 additions & 7 deletions docs/source/reference/test_utils/conftest.rst

This file was deleted.

1 change: 0 additions & 1 deletion docs/source/reference/test_utils/modules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ utils
.. toctree::
:maxdepth: 4

conftest
test_coordinates
test_dop
test_ephemeris_downloader
Expand Down
7 changes: 0 additions & 7 deletions docs/source/reference/test_visualizations/conftest.rst

This file was deleted.

1 change: 0 additions & 1 deletion docs/source/reference/test_visualizations/modules.rst
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ visualizations
.. toctree::
:maxdepth: 4

conftest
test_plot_map
test_plot_metric
test_plot_skyplot
Expand Down
94 changes: 12 additions & 82 deletions tests/algorithms/test_fde.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,113 +11,43 @@
import numpy as np

from gnss_lib_py.navdata.navdata import NavData
from gnss_lib_py.parsers.google_decimeter import AndroidDerived2022
from gnss_lib_py.algorithms.fde import solve_fde, evaluate_fde

@pytest.fixture(name="root_path_2022")
def fixture_root_path_2022():
"""Location of measurements for unit test.
Returns
-------
root_path_2022 : string
Folder location containing measurements.
"""
root_path = os.path.dirname(
os.path.dirname(
os.path.dirname(
os.path.realpath(__file__))))
root_path_2022 = os.path.join(root_path, 'data','unit_test','google_decimeter_2022')
return root_path_2022

@pytest.fixture(name="derived_2022_path")
def fixture_derived_2022_path(root_path_2022):
"""Filepath of Android Derived measurements.
Parameters
----------
root_path_2022 : string
Folder location containing measurements.
Returns
-------
derived_2022_path : string
Location for the unit_test Android derived 2022 measurements.
Notes
-----
Test data is a subset of the Android Raw Measurement Dataset [1]_,
from the 2022 Decimeter Challenge. Particularly, the
train/2021-04-29-MTV-2/SamsungGalaxyS20Ultra trace. The dataset
was retrieved from
https://www.kaggle.com/competitions/smartphone-decimeter-2022/data
References
----------
.. [1] Fu, Guoyu Michael, Mohammed Khider, and Frank van Diggelen.
"Android Raw GNSS Measurement Datasets for Precise Positioning."
Proceedings of the 33rd International Technical Meeting of the
Satellite Division of The Institute of Navigation (ION GNSS+
2020). 2020.
"""
derived_2022_path = os.path.join(root_path_2022, 'device_gnss.csv')
return derived_2022_path

@pytest.fixture(name="derived")
def fixture_load_derived(derived_2022_path):
"""Load instance of AndroidDerived2022.
Parameters
----------
derived_2022_path : pytest.fixture
String with location of Android derived measurement file.
Returns
-------
derived : AndroidDerived2022
Instance of AndroidDerived2022 for testing.
"""
derived = AndroidDerived2022(derived_2022_path)
return derived

@pytest.mark.parametrize('method',
[
"residual",
"edm",
])
def test_solve_fde(derived, method):
def test_solve_fde(derived_2022, method):
"""Test residual-based FDE.
Parameters
----------
derived : AndroidDerived2022
derived_2022 : AndroidDerived2022
Instance of AndroidDerived2022 for testing.
method : string
Method for fault detection and exclusion.
"""

# test without removing outliers
navdata = derived.copy()
navdata = derived_2022.copy()
navdata = solve_fde(navdata, method=method)
assert "fault_" + method in navdata.rows

# max thresholds shouldn't remove any
navdata = derived.copy()
navdata = derived_2022.copy()
navdata = solve_fde(navdata, threshold=np.inf, method=method)
assert sum(navdata.where("fault_" + method,1)["fault_" + method]) == 0

# min threshold should remove most all
navdata = derived.copy()
navdata = derived_2022.copy()
navdata = solve_fde(navdata, threshold=-np.inf, method=method)
print(sum(navdata.where("fault_" + method,1)["fault_" + method]))
assert len(navdata.where("fault_" + method,0)) == 24
num_unknown = len(navdata.where("fault_" + method,2))

navdata = derived.copy()
navdata = derived_2022.copy()
original_length = len(navdata)
navdata = solve_fde(navdata,
threshold=-np.inf,
Expand All @@ -130,38 +60,38 @@ def test_solve_fde(derived, method):
np.array([0]))
assert len(navdata) == original_length - num_unknown - 6

def test_fde_fails(derived):
def test_fde_fails(derived_2022):
"""Test that solve_fde fails when it should.
Parameters
----------
derived : AndroidDerived2022
derived_2022 : AndroidDerived2022
Instance of AndroidDerived2022 for testing.
"""

with pytest.raises(ValueError) as excinfo:
solve_fde(derived, method="perfect_method")
solve_fde(derived_2022, method="perfect_method")
assert "invalid method" in str(excinfo.value)

@pytest.mark.parametrize('method',
[
"residual",
"edm",
])
def test_evaluate_fde(derived, method):
def test_evaluate_fde(derived_2022, method):
"""Evaluate FDE methods.
Parameters
----------
derived : AndroidDerived2022
derived_2022 : AndroidDerived2022
Instance of AndroidDerived2022 for testing.
method : string
Method for fault detection and exclusion.
"""

navdata = derived.copy()
navdata = derived_2022.copy()
evaluate_fde(navdata,
method=method,
fault_truth_row="MultipathIndicator",
Expand Down
80 changes: 8 additions & 72 deletions tests/algorithms/test_gnss_filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,78 +98,16 @@ def test_stationary_filter(init_dict, params_dict, motion_type):
pos_ekf = gnss_ekf.state[:3]
np.testing.assert_allclose(pos_ekf, init_dict['state_0'][:3], atol=0.1)

@pytest.fixture(name="root_path")
def fixture_root_path():
"""Location of measurements for unit test
Returns
-------
root_path : string
Folder location containing measurements
"""
root_path = os.path.dirname(
os.path.dirname(
os.path.dirname(
os.path.realpath(__file__))))
root_path = os.path.join(root_path, 'data/unit_test/google_decimeter_2021/')
return root_path


@pytest.fixture(name="derived_path")
def fixture_derived_path(root_path):
"""Filepath of Android Derived measurements
Returns
-------
derived_path : string
Location for the unit_test Android derived measurements
Notes
-----
Test data is a subset of the Android Raw Measurement Dataset [2]_,
particularly the train/2020-05-14-US-MTV-1/Pixel4 trace. The dataset
was retrieved from
https://www.kaggle.com/c/google-smartphone-decimeter-challenge/data
References
----------
.. [2] Fu, Guoyu Michael, Mohammed Khider, and Frank van Diggelen.
"Android Raw GNSS Measurement Datasets for Precise Positioning."
Proceedings of the 33rd International Technical Meeting of the
Satellite Division of The Institute of Navigation (ION GNSS+
2020). 2020.
"""
derived_path = os.path.join(root_path, 'Pixel4_derived.csv')
return derived_path


@pytest.fixture(name="derived")
def fixture_load_derived(derived_path):
"""Load instance of AndroidDerived2021
Parameters
----------
derived_path : pytest.fixture
String with location of Android derived measurement file
Returns
-------
derived : AndroidDerived2021
Instance of AndroidDerived2021 for testing
"""
derived = AndroidDerived2021(derived_path)
return derived

def test_solve_gnss_ekf(derived):
def test_solve_gnss_ekf(derived_2021):
"""Test that solving for GNSS EKF doesn't fail
Parameters
----------
derived : AndroidDerived2021
derived_2021 : AndroidDerived2021
Instance of AndroidDerived2021 for testing.
"""
state_estimate = solve_gnss_ekf(derived)
state_estimate = solve_gnss_ekf(derived_2021)

# result should be a NavData Class instance
assert isinstance(state_estimate,type(NavData()))
Expand All @@ -191,29 +129,27 @@ def test_solve_gnss_ekf(derived):
assert "alt_rx_ekf_m" in state_estimate.rows

# should have the same length as the number of unique timesteps
assert len(state_estimate) == sum(1 for _ in loop_time(derived,"gps_millis"))

# len(np.unique(derived["gps_millis",:]))
assert len(state_estimate) == sum(1 for _ in loop_time(derived_2021,"gps_millis"))

# test what happens when rows down't exist
for row_index in ["gps_millis","x_sv_m","y_sv_m","z_sv_m","corr_pr_m"]:
derived_no_row = derived.remove(rows=row_index)
derived_no_row = derived_2021.remove(rows=row_index)
with pytest.raises(KeyError) as excinfo:
solve_gnss_ekf(derived_no_row)
assert row_index in str(excinfo.value)


def test_solve_gnss_ekf_fails(derived):
def test_solve_gnss_ekf_fails(derived_2021):
"""Test expected fails for the GNSS EKF.
Parameters
----------
derived : AndroidDerived2021
derived_2021 : AndroidDerived2021
Instance of AndroidDerived2021 for testing
"""

navdata = derived.remove(cols=list(range(len(derived))))
navdata = derived_2021.remove(cols=list(range(len(derived_2021))))

with pytest.warns(RuntimeWarning) as warns:
solve_gnss_ekf(navdata)
Expand Down
Loading

0 comments on commit 352f0f4

Please sign in to comment.