1#!/usr/bin/env python3
2"""Test AUX data file ingestion decoding as part of CHART-EPSSG decoding and ingestion function.
3
4These tests verify the following are Fac. req IDs and Service Def. Req (which
5include reqs that are verified by the existance of these auto tests):
6 REQ_IFC_2010: MONA-A&R-410
7 REQ_ING_050: MONA-A&R-130
8 REQ_ING_3010: MONA-A&R-410
9
10 Dev reqs
11 REQ_TST_010: MONA-TST-0010
12 REQ_TST_020: MONA-TST-0020
13"""
14
15import sys
16from datetime import datetime
17from lxml import etree
18import pytest
19# import pytest_pgsql
20
21from chartepssg import project # must come first
22from chart.common.path import Path
23from chart.common.log import init_log
24from chart.common.traits import is_listlike
25from chart.common.test_utils import show
26from chart.common.test_utils import compare
27from chart.project import settings
28from chart.project import SID
29from chart.common.xml import XMLElement
30from chart.common.test_utils import compare
31from chartepssg.alg.settings import scid_to_sid
32from chartepssg.alg import orbit4ant_ingester
33from chartepssg.alg import predicted_orbit_ingester
34
35
36def print_out(msg, obj):
37 out = msg.format(obj)
38 out += '\n'
39 sys.stdout.write(out)
40
41
42EPSSGA_SID = SID('EPSSGA')
43EPSSGB_SID = SID('EPSSGB')
44
45PROJECT_ROOT_DIR = settings.PROJECT_HOME_DIR.parent
46AUX_PRODUCT_DIR = PROJECT_ROOT_DIR.joinpath('tests', 'testdata', 'aux')
47
48OEMORBPRED_FILE = 'ORB_PRED/SGA1_FDP_FDS__OPE_OEM________G20210421100627Z_S20210421000000Z_E20210428000000Z.xml'
49PREDICTED_ORB_FILE = 'PRED_ORB/SGA1_FDP_FDS__OPE_PRED_ORB___G20210415132921Z_S20210415000000Z_E20210416120000Z.EOF'
50
51SATMASSREP_FILE = 'MASS_REPO/SGA1_FDP_FDS__OPE_MASS_REPO__G20220628140419Z_S20220628140419Z_E20220628140419Z.txt'
52
53MANOHIST_FILE = 'MANO_HIST/SGB1_FDP_FDS__OPE_MANO_HIST__G20220628145251Z_S20220503135959Z_E20220706150000Z.txt'
54
55MANOPREDIC_FILE = 'MANO_PRED/SGA1_FDP_FDS__OPE_MANO_PRED__G20220615123845Z_S20220622150000Z_E20220622150000Z.txt'
56
57#@pytest.mark.skip
58def test_ORBIT4ANT_decoder():
59 """Decoder test for ORBIT4ANT aux files.
60 Compare product file decoding against expected tuple values """
61
62 # From visual inspection we have the followwing first and last value in the test file
63 # first entry
64 OSV = """
65 <stateVector>
66 <EPOCH>2021-04-21T00:00:00.000</EPOCH>
67 <X> 3.016743752950E+03</X>
68 <Y>-5.926262342904E+03</Y>
69 <Z> 2.613202547095E+03</Z>
70 <X_DOT>-2.678854791139E+00</X_DOT>
71 <Y_DOT> 1.536418802269E+00</Y_DOT>
72 <Z_DOT> 6.855073654454E+00</Z_DOT>
73 </stateVector>
74 """
75
76 sv_elem = XMLElement(elem=etree.fromstring(OSV))
77 expected_result_1st = orbit4ant_ingester.OrbitPred(
78 sid=EPSSGA_SID,
79 epoch=sv_elem.parse_datetime(orbit4ant_ingester.ELEM_EPOCH),
80 X=sv_elem.parse_float(orbit4ant_ingester.ELEM_X),
81 Y=sv_elem.parse_float(orbit4ant_ingester.ELEM_Y),
82 Z=sv_elem.parse_float(orbit4ant_ingester.ELEM_Z),
83 X_DOT=sv_elem.parse_float(orbit4ant_ingester.ELEM_X_DOT),
84 Y_DOT=sv_elem.parse_float(orbit4ant_ingester.ELEM_Y_DOT),
85 Z_DOT=sv_elem.parse_float(orbit4ant_ingester.ELEM_Z_DOT)
86 )
87
88 # last entry
89 OSV = """
90 <stateVector>
91 <EPOCH>2021-04-28T00:00:00.000</EPOCH>
92 <X>-3.627304613302E+03</X>
93 <Y> 5.946270489729E+03</Y>
94 <Z> 3.681271215740E+02</Z>
95 <X_DOT> 1.265486358023E+00</X_DOT>
96 <Y_DOT> 1.110315564701E+00</Y_DOT>
97 <Z_DOT>-7.513939797068E+00</Z_DOT>
98 </stateVector>
99 """
100
101 sv_elem = XMLElement(elem=etree.fromstring(OSV))
102 expected_result_last = orbit4ant_ingester.OrbitPred(
103 sid=EPSSGA_SID,
104 epoch=sv_elem.parse_datetime(orbit4ant_ingester.ELEM_EPOCH),
105 X=sv_elem.parse_float(orbit4ant_ingester.ELEM_X),
106 Y=sv_elem.parse_float(orbit4ant_ingester.ELEM_Y),
107 Z=sv_elem.parse_float(orbit4ant_ingester.ELEM_Z),
108 X_DOT=sv_elem.parse_float(orbit4ant_ingester.ELEM_X_DOT),
109 Y_DOT=sv_elem.parse_float(orbit4ant_ingester.ELEM_Y_DOT),
110 Z_DOT=sv_elem.parse_float(orbit4ant_ingester.ELEM_Z_DOT)
111 )
112
113 # decode file
114 ENTRY_COUNT = 505
115 actual_results = list(orbit4ant_ingester.parse_orbitpred(AUX_PRODUCT_DIR.joinpath(OEMORBPRED_FILE)))
116
117 assert ENTRY_COUNT == len(actual_results)
118 assert actual_results[0] == expected_result_1st
119 print_out("OEMORBPRED decoder test passed for first result: {}", expected_result_1st)
120 assert actual_results[ENTRY_COUNT-1] == expected_result_last
121 print_out("OEMORBPRED decoder test passed for last result: {}", expected_result_last)
122
123#@pytest.mark.skip
124def test_PRED_ORBIT_decoder():
125 """Decoder test for PRED_ORB aux files data
126 Compare product file decoding against expected tuple values """
127
128 # From visual inspection we have the followwing first and last value in the test file
129 # added a namespace to be consistent with the XML source files and ingester
130 # first entry
131
132 OSV = """
133 <OSV xmlns="http://eop-cfi.esa.int/CFI">
134 <TAI>TAI=2021-04-15T00:00:37.000000</TAI>
135 <UTC>UTC=2021-04-15T00:00:00.000000</UTC>
136 <UT1>UT1=2021-04-15T00:00:00.000000</UT1>
137 <Absolute_Orbit>+00014</Absolute_Orbit>
138 <X unit="m">+0667217.143</X>
139 <Y unit="m">+0869581.672</Y>
140 <Z unit="m">+7103154.990</Z>
141 <VX unit="m/s">+5895.659566</VX>
142 <VY unit="m/s">-4426.056142</VY>
143 <VZ unit="m/s">-0011.947906</VZ>
144 <Quality>0000000000000</Quality>
145 </OSV>
146 """
147
148 sv_elem = XMLElement(elem=etree.fromstring(OSV))
149 expected_result_1st = predicted_orbit_ingester.PredictedOrbit(
150 sid=EPSSGA_SID,
151 sensing_time=sv_elem.parse_datetime(predicted_orbit_ingester.ELEM_UTC),
152 X=sv_elem.parse_float(predicted_orbit_ingester.ELEM_X),
153 Y=sv_elem.parse_float(predicted_orbit_ingester.ELEM_Y),
154 Z=sv_elem.parse_float(predicted_orbit_ingester.ELEM_Z),
155 VX=sv_elem.parse_float(predicted_orbit_ingester.ELEM_VX),
156 VY=sv_elem.parse_float(predicted_orbit_ingester.ELEM_VY),
157 VZ=sv_elem.parse_float(predicted_orbit_ingester.ELEM_VZ)
158 )
159
160 # added a namespace to be consistent with the XML source files and ingester
161 # last entry
162 OSV = """
163 <OSV xmlns="http://eop-cfi.esa.int/CFI">
164 <TAI>TAI=2021-04-16T12:00:37.000000</TAI>
165 <UTC>UTC=2021-04-16T12:00:00.000000</UTC>
166 <UT1>UT1=2021-04-16T12:00:00.000000</UT1>
167 <Absolute_Orbit>+00036</Absolute_Orbit>
168 <X unit="m">-1101181.394</X>
169 <Y unit="m">+2063287.497</Y>
170 <Z unit="m">+6793192.289</Z>
171 <VX unit="m/s">+5943.955397</VX>
172 <VY unit="m/s">-3802.700647</VY>
173 <VZ unit="m/s">+2147.390705</VZ>
174 <Quality>0000000000000</Quality>
175 </OSV>
176 """
177
178 sv_elem = XMLElement(elem=etree.fromstring(OSV))
179 expected_result_last = predicted_orbit_ingester.PredictedOrbit(
180 sid=EPSSGA_SID,
181 sensing_time=sv_elem.parse_datetime(predicted_orbit_ingester.ELEM_UTC),
182 X=sv_elem.parse_float(predicted_orbit_ingester.ELEM_X),
183 Y=sv_elem.parse_float(predicted_orbit_ingester.ELEM_Y),
184 Z=sv_elem.parse_float(predicted_orbit_ingester.ELEM_Z),
185 VX=sv_elem.parse_float(predicted_orbit_ingester.ELEM_VX),
186 VY=sv_elem.parse_float(predicted_orbit_ingester.ELEM_VY),
187 VZ=sv_elem.parse_float(predicted_orbit_ingester.ELEM_VZ)
188 )
189
190 # decode file
191 ENTRY_COUNT = 109
192 actual_results = list(predicted_orbit_ingester.parse_predicted_orbit(AUX_PRODUCT_DIR.joinpath(PREDICTED_ORB_FILE)))
193
194 assert ENTRY_COUNT == len(actual_results)
195 assert actual_results[0] == expected_result_1st
196 print_out("PRED_ORB decoder test passed for first result: {}", expected_result_1st)
197 assert actual_results[ENTRY_COUNT-1] == expected_result_last
198 print_out("PRED_ORB decoder test passed for last result: {}", expected_result_last)
199
200
201def test_SATMASSREP_decoder():
202 """Decoder test for SATMASSREP aux files.
203 Compare product file decoding against expected tuple values """
204 from chartepssg.alg import satmassrep_ingester
205
206 # From visual inspection we have the followwing value in the test file
207 # SGA1 MASS PROPERTIES COMPUTED ON 2022-06-28T14:04:19
208 # 2022-06-28T14:04:19 CALCULATION DATE
209 # 2.536 XS CO-ORDINATE (METER)
210 # -0.129 YS CO-ORDINATE (METER)
211 # 0.221 ZS CO-ORDINATE (METER)
212 # 1179.999 TOTAL S/C MASS (KG)
213 # 166.523 FUEL MASS (KG)
214 # 1581.8 INERTIA XX (M2.KG)
215 # 3832.1 INERTIA YY (M2.KG)
216 # 5080.9 INERTIA ZZ (M2.KG)
217 # -415.7 INERTIA XY (M2.KG)
218 # 18.7 INERTIA YZ (M2.KG)
219 # 14.7 INERTIA ZX (M2.KG)
220 expected_result = satmassrep_ingester.Report(
221 #sid=scid_to_sid('SGA1'),
222 # calc_date=datetime.strptime('2023-06-21T16:00:00', satmassrep_ingester.CALC_DATE_FORMAT),
223 calc_date=datetime(2022,6,28,14,4,19),
224 xs=2.536, ys=-0.129, zs=0.221,
225 total_mass=1179.999, fuel_mass=166.523,
226 i_xx=1581.8, i_yy=3832.1, i_zz=5080.9,
227 i_xy=-415.7, i_yz=18.7, i_zx=14.7)
228
229 # decode file
230 actual_result = satmassrep_ingester.parse_report(AUX_PRODUCT_DIR.joinpath(SATMASSREP_FILE))
231
232 compare(actual_result, expected_result)
233 # assert actual_result == expected_result
234 print_out("SATMASSREP decoder test passed for result: {}", expected_result)
235
236
237
238def test_MANOHIST_decoder():
239 """Decoder test for MANOHIST aux files.
240 Compare product file decoding against expected tuple values """
241
242 from chartepssg.alg import manohist_ingester
243
244 #sid = scid_to_sid('SGB1')
245 # From visual inspection we have the followwing first and last value in the test file
246 # first entry
247 # 2022/05/03-13:59:59.228 0.00000000D+00 0.11655693D-04 0.00000000D+00 1 1
248
249 expected_result_1st = manohist_ingester.Manoeuvre(
250 # sid=sid,
251 # datetime.strptime('2016/02/22-09:29:35.000', manohist_ingester.EPOCH_FORMAT),
252 epoch=datetime(2022,5,3,13,59,59,228000),
253 acc_comp_1=0.0,
254 acc_comp_2=0.11655693E-04,
255 acc_comp_3=0.0,
256 flag=1)
257
258 # last entry
259 # 2019/12/11-12:11:00.810 -0.49240007D-08 0.13296058D-07 0.25735859D-05 0
260 expected_result_last = manohist_ingester.Manoeuvre(
261 # sid=sid,
262 # datetime.strptime('2019/12/11-12:11:00.810', manohist_ingester.EPOCH_FORMAT),
263 epoch=datetime(2022,7,6,15,0,0,901000),
264 acc_comp_1=-0.0,
265 acc_comp_2=0.16640648E-04,
266 acc_comp_3=0.0,
267 flag=0)
268
269 # decode file
270 ENTRY_COUNT = 26
271 actual_results = list(manohist_ingester.parse_manoeuvres(AUX_PRODUCT_DIR.joinpath(MANOHIST_FILE)))
272
273 assert ENTRY_COUNT == len(actual_results)
274 assert actual_results[0] == expected_result_1st
275 print_out("MANOHIST decoder test passed for first result: {}", expected_result_1st)
276 assert actual_results[ENTRY_COUNT-1] == expected_result_last
277 print_out("MANOHIST decoder test passed for last result: {}", expected_result_last)
278
279
280def test_MANOPREDIC_decoder():
281 """Decoder test for MANOPREDIC aux files.
282 Compare product file decoding against expected tuple values """
283 from chartepssg.alg import manopredic_ingester
284
285 # From visual inspection we have the followwing first and only value
286 # First burn 2019/12/11-12:03:58.533 2.091 m/s OOP OCM 17.402 deg
287 expected_result = manopredic_ingester.Manoeuvre(
288 #sid=SCID_TO_SID_MAP['S6A'],
289 # datetime.strptime('2019/12/11-12:03:58.533', manopredic_ingester.EXEC_TIME_FORMAT),
290
291 file_gen_time=datetime(2022,6,15,12,31,54,235000),
292 optim_time=datetime(2022,6,15,12,31,6,642000),
293 exec_time=datetime(2022,6,22,15,0,0,0),
294 mode='INP OCM',
295 size=-0.05,
296 pso=231.145)
297
298 # decode file
299 actual_results = list(manopredic_ingester.parse_manoeuvres(AUX_PRODUCT_DIR.joinpath(MANOPREDIC_FILE)))
300
301 compare(actual_results[0], expected_result)
302 # assert actual_results[0] == expected_result
303 print_out("MANOPREDIC decoder test passed for result: {}", expected_result)