From 80c1c470dee3b50c83ba94ad8b0760bd80f27238 Mon Sep 17 00:00:00 2001 From: Nathan <95725385+treefern@users.noreply.github.com> Date: Tue, 14 Jan 2025 12:03:19 +0000 Subject: [PATCH] sp3 unit tests for content generation functions --- gnssanalysis/gn_utils.py | 12 +++++++++ tests/test_datasets/sp3_test_data.py | 39 +++++++++++++++++++++++++++- tests/test_sp3.py | 28 ++++++++++++++++++++ 3 files changed, 78 insertions(+), 1 deletion(-) diff --git a/gnssanalysis/gn_utils.py b/gnssanalysis/gn_utils.py index 7eba4a1..162d09b 100644 --- a/gnssanalysis/gn_utils.py +++ b/gnssanalysis/gn_utils.py @@ -871,3 +871,15 @@ def clkq( out_file.writelines(output_str) else: print(output_str) + + +def trim_line_ends(content: str) -> str: + """ + Utility to strip trailing whitespace from all lines given. + This is useful as for example, the SP3 spec doesn't stipulate whether lines should have trailing whitespace or not, + and implementations vary. + + :param str content: input string to strip + :return str: string with trailing (only, not leading) whitespace removed from each line + """ + return "\n".join([line.rstrip() for line in content.split("\n")]) diff --git a/tests/test_datasets/sp3_test_data.py b/tests/test_datasets/sp3_test_data.py index 9fc18c7..04629b4 100644 --- a/tests/test_datasets/sp3_test_data.py +++ b/tests/test_datasets/sp3_test_data.py @@ -248,8 +248,45 @@ EOF """ +# For testing gen_sp3_header() +sp3_test_data_short_cod_final_header = """#dP2024 7 19 0 0 0.00000000 2 d+D IGS20 FIT AIUB +## 2323 432000.00000000 300.00000000 60510 0.0000000000000 ++ 3 G01G02G03 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 ++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +++ 10 4 4 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +++ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 +%c M cc GPS ccc cccc cccc cccc cccc ccccc ccccc ccccc ccccc +%c cc cc ccc ccc cccc cccc cccc cccc ccccc ccccc ccccc ccccc +%f 1.2500000 1.025000000 0.00000000000 0.000000000000000 +%f 0.0000000 0.000000000 0.00000000000 0.000000000000000 +%i 0 0 0 0 0 0 0 0 0 +%i 0 0 0 0 0 0 0 0 0 +/* Center for Orbit Determination in Europe (CODE) +/* Final GNSS orbits and clocks for year-day 2024-2010 +/* Middle day of a 3-day long-arc GRE solution +/* Product reference - DOI 10.48350/197025 +/* PCV:IGS20 OL/AL:FES2014b NONE YN ORB:CoN CLK:CoN +""" + +# For testing gen_sp3_content() +sp3_test_data_short_cod_final_content = """* 2024 7 19 0 0 0.00000000 +PG01 4510.358405 -23377.282442 -11792.723580 239.322216 +PG02 -19585.529427 -8704.823858 16358.028672 -396.375750 +PG03 -17580.234088 4691.573463 19141.243267 463.949579 +* 2024 7 19 0 5 0.00000000 +PG01 4796.934856 -23696.377197 -10979.751610 239.319708 +PG02 -19881.646388 -9206.366139 15702.571850 -396.373498 +PG03 -17231.990585 4028.826042 19602.838740 463.954491 +""" + -# Deliberately broken versions of the above +# Deliberately broken versions of the above full file. # Issue: Inconsistent number of SVs (first epoch correct, then adds one) # Use filename: COD0OPSFIN_20242010000_10M_05M_ORB.SP3 diff --git a/tests/test_sp3.py b/tests/test_sp3.py index 0daa581..5e0ff3d 100644 --- a/tests/test_sp3.py +++ b/tests/test_sp3.py @@ -9,6 +9,7 @@ from gnssanalysis.filenames import convert_nominal_span, determine_properties_from_filename import gnssanalysis.gn_io.sp3 as sp3 +from gnssanalysis.gn_utils import trim_line_ends from test_datasets.sp3_test_data import ( # first dataset is part of the IGS benchmark (modified to include non null data on clock): sp3_test_data_igs_benchmark_null_clock as input_data, @@ -21,6 +22,10 @@ sp3_test_data_partially_offline_sat as offline_sat_test_data, # For header vs content validation tests: sp3_test_data_cod_broken_missing_sv_in_content, + # For testing generate_sp3_header() and generate_sp3_content() + sp3_test_data_short_cod_final, # For use as input data + sp3_test_data_short_cod_final_content, # For validating content output + sp3_test_data_short_cod_final_header, # For validating header output ) @@ -140,6 +145,29 @@ def test_read_sp3_validation_sv_count_mismatch_header_vs_content(self, mock_file ) # TODO Add test(s) for correctly reading header fundamentals (ACC, ORB_TYPE, etc.) # TODO add tests for correctly reading the actual content of the SP3 in addition to the header. + + def test_gen_sp3_fundamentals(self): + """ + Tests that the SP3 header and content generation functions produce output that (apart from trailing + whitespace), match a known good value. + NOTE: leverages read_sp3() to pull in sample data, so is prone to errors in that function. + """ + # Note this is suboptimal from a testing standpoint, but for now is a lot easier than manually constructing + # the DataFrame. + sp3_df = sp3.read_sp3(bytes(sp3_test_data_short_cod_final)) + + generated_sp3_header = sp3.gen_sp3_header(sp3_df, output_comments=True) + generated_sp3_content = sp3.gen_sp3_content(sp3_df) + + self.assertTrue( + trim_line_ends(generated_sp3_header) == trim_line_ends(sp3_test_data_short_cod_final_header), + "SP3 header should match baseline, including retention of original comments", + ) + self.assertTrue( + trim_line_ends(generated_sp3_content) == trim_line_ends(sp3_test_data_short_cod_final_content), + "SP3 content should match baseline", + ) + # TODO add tests for correctly generating sp3 output content with gen_sp3_content() and gen_sp3_header() # These tests should include: # - Correct alignment of POS, CLK, STDPOS STDCLK, (not velocity yet), FLAGS