Skip to content

Commit 1b6925c

Browse files
author
Peterson
committed
Moved SICDWriter tests to individual test file.
1 parent e52a26c commit 1b6925c

File tree

2 files changed

+377
-352
lines changed

2 files changed

+377
-352
lines changed
Lines changed: 371 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,371 @@
1+
import json
2+
import numpy
3+
import os
4+
import pytest
5+
import unittest
6+
7+
from sarpy.io.complex.converter import conversion_utility, open_complex
8+
from sarpy.io.complex.sicd import SICDWriter, SICDWritingDetails
9+
from sarpy.io.complex.sicd_elements.SICD import SICDType
10+
from sarpy.io.complex.sicd_schema import get_schema_path, \
11+
get_default_version_string
12+
from sarpy.io.complex.sicd_elements.blocks import XYZPolyType
13+
14+
from tests import parse_file_entry
15+
16+
complex_file_types = {}
17+
this_loc = os.path.abspath(__file__)
18+
# specifies file locations
19+
file_reference = os.path.join(os.path.split(this_loc)[0], \
20+
'complex_file_types.json')
21+
if os.path.isfile(file_reference):
22+
with open(file_reference, 'r') as local_file:
23+
test_files_list = json.load(local_file)
24+
for test_files_type in test_files_list:
25+
valid_entries = []
26+
for entry in test_files_list[test_files_type]:
27+
the_file = parse_file_entry(entry)
28+
if the_file is not None:
29+
valid_entries.append(the_file)
30+
complex_file_types[test_files_type] = valid_entries
31+
32+
sicd_files = complex_file_types.get('SICD', [])
33+
34+
def get_sicd_meta():
35+
input_file = sicd_files[0]
36+
reader = open_complex(input_file)
37+
return_sicd_meta = reader.sicd_meta
38+
return return_sicd_meta
39+
40+
def test_sicd_writer_init_failure_no_input(tmp_path):
41+
with pytest.raises(TypeError,
42+
match="missing 1 required positional argument: " + \
43+
"'file_object'"):
44+
sicd_writer = SICDWriter()
45+
46+
def test_sicd_writer_init_failure_file_only(tmp_path):
47+
output_file = tmp_path / "out.sicd"
48+
with pytest.raises(ValueError,
49+
match="One of sicd_meta or sicd_writing_details must " + \
50+
"be provided."):
51+
sicd_writer = SICDWriter(output_file)
52+
53+
@unittest.skipIf(len(sicd_files) == 0, 'No sicd files found')
54+
def test_sicd_writer_init_failure_sicd_meta_only(tmp_path):
55+
sicd_meta = get_sicd_meta()
56+
with pytest.raises(TypeError,
57+
match="missing 1 required positional argument: " + \
58+
"'file_object'"):
59+
sicd_writer = SICDWriter(sicd_meta=sicd_meta)
60+
61+
@unittest.skipIf(len(sicd_files) == 0, 'No sicd files found')
62+
def test_sicd_writer_init_failure_sicd_writing_details_only(tmp_path):
63+
sicd_meta = get_sicd_meta()
64+
sicd_writing_details = SICDWritingDetails(sicd_meta)
65+
output_file = str(tmp_path / "out.sicd")
66+
with pytest.raises(TypeError,
67+
match="missing 1 required positional argument: " + \
68+
"'file_object'"):
69+
sicd_writer = SICDWriter(sicd_writing_details=sicd_writing_details)
70+
71+
@unittest.skipIf(len(sicd_files) == 0, 'No sicd files found')
72+
def test_sicd_writer_init_sicd_meta(tmp_path):
73+
sicd_meta = get_sicd_meta()
74+
output_file = str(tmp_path / "out.sicd")
75+
sicd_writer = SICDWriter(output_file, sicd_meta=sicd_meta)
76+
77+
@unittest.skipIf(len(sicd_files) == 0, 'No sicd files found')
78+
def test_sicd_writer_init_sicd_writing_details(tmp_path):
79+
sicd_meta = get_sicd_meta()
80+
sicd_writing_details = SICDWritingDetails(sicd_meta)
81+
output_file = str(tmp_path / "out.sicd")
82+
sicd_writer = SICDWriter(output_file, \
83+
sicd_writing_details=sicd_writing_details)
84+
85+
@unittest.skipIf(len(sicd_files) == 0, 'No sicd files found')
86+
def test_sicd_writer_init_failure_sicd_meta_invalid_output(tmp_path):
87+
sicd_meta = get_sicd_meta()
88+
output_file = str("/does_not_exist/out.sicd")
89+
with pytest.raises(FileNotFoundError,
90+
match="No such file or directory: " + \
91+
"'/does_not_exist/out.sicd'"):
92+
sicd_writer = SICDWriter(output_file, sicd_meta=sicd_meta)
93+
94+
@unittest.skipIf(len(sicd_files) == 0, 'No sicd files found')
95+
def test_sicd_writer_init_failure_sicd_writing_details_invalid_output(tmp_path):
96+
sicd_meta = get_sicd_meta()
97+
sicd_writing_details = SICDWritingDetails(sicd_meta)
98+
output_file = str("/does_not_exist/out.sicd")
99+
with pytest.raises(FileNotFoundError,
100+
match="No such file or directory: " + \
101+
"'/does_not_exist/out.sicd'"):
102+
sicd_writer = SICDWriter(output_file, \
103+
sicd_writing_details=sicd_writing_details)
104+
105+
@unittest.skipIf(len(sicd_files) == 0, 'No sicd files found')
106+
def test_sicd_writer_init_failure_bad_sicd_meta(tmp_path):
107+
sicd_meta = get_sicd_meta()
108+
sicd_meta_bad_string = str(sicd_meta) + "})"
109+
sicd_meta_bad_type = SICDType(sicd_meta_bad_string)
110+
output_file = str(tmp_path / "out.sicd")
111+
with pytest.raises(ValueError,
112+
match="The sicd_meta has un-populated ImageData, and " + \
113+
"nothing useful can be inferred."):
114+
sicd_writer = SICDWriter(output_file, sicd_meta=sicd_meta_bad_type)
115+
116+
@unittest.skipIf(len(sicd_files) == 0, 'No sicd files found')
117+
def test_sicd_writer_init_failure_bad_sicd_writing_details(tmp_path):
118+
sicd_writing_details_bad = "Bad Data"
119+
output_file = str(tmp_path / "out.sicd")
120+
with pytest.raises(TypeError,
121+
match="nitf_writing_details must be of type " + \
122+
"<class 'sarpy.io.complex.sicd.SICDWritingDetails'>"):
123+
sicd_writer = SICDWriter(output_file, \
124+
sicd_writing_details=sicd_writing_details_bad)
125+
126+
@unittest.skipIf(len(sicd_files) == 0, 'No sicd files found')
127+
def test_nitf_writing_details(tmp_path):
128+
sicd_meta = get_sicd_meta()
129+
sicd_writing_details = SICDWritingDetails(sicd_meta)
130+
output_file = str(tmp_path / "out.sicd")
131+
sicd_writer = SICDWriter(output_file, \
132+
sicd_writing_details=sicd_writing_details)
133+
assert sicd_writer.nitf_writing_details == sicd_writing_details
134+
135+
@unittest.skipIf(len(sicd_files) == 0, 'No sicd files found')
136+
def test_nitf_writing_details_setter_failure(tmp_path):
137+
sicd_meta = get_sicd_meta()
138+
sicd_writing_details = SICDWritingDetails(sicd_meta)
139+
output_file = str(tmp_path / "out.sicd")
140+
sicd_writer = SICDWriter(output_file, \
141+
sicd_writing_details=sicd_writing_details)
142+
with pytest.raises(ValueError,
143+
match="nitf_writing_details is read-only"):
144+
sicd_writer.nitf_writing_details = sicd_writing_details
145+
146+
@unittest.skipIf(len(sicd_files) == 0, 'No sicd files found')
147+
def test_get_format_function(tmp_path):
148+
sicd_meta = get_sicd_meta()
149+
output_file = str(tmp_path / "out.sicd")
150+
sicd_writer = SICDWriter(output_file, sicd_meta=sicd_meta)
151+
sicd_writer.get_format_function(raw_dtype="float", band_dimension=8,
152+
complex_order='IQ', lut=numpy.array([1, 2]))
153+
154+
155+
@unittest.skipIf(len(sicd_files) == 0, 'No sicd files found')
156+
def test_get_format_function_failure_bad_band_type(tmp_path):
157+
sicd_meta = get_sicd_meta()
158+
output_file = str(tmp_path / "out.sicd")
159+
sicd_writer = SICDWriter(output_file, sicd_meta=sicd_meta)
160+
with pytest.raises(ValueError,
161+
match="Got unsupported SICD band type definition"):
162+
sicd_writer.get_format_function(raw_dtype="float", band_dimension=8,
163+
complex_order='Steve', \
164+
lut=numpy.array([1, 2]))
165+
166+
167+
@unittest.skipIf(len(sicd_files) == 0, 'No sicd files found')
168+
def test_sicd_meta(tmp_path):
169+
sicd_meta = get_sicd_meta()
170+
output_file = str(tmp_path / "out.sicd")
171+
sicd_writer = SICDWriter(output_file, sicd_meta=sicd_meta)
172+
# Must confirm each piece of the SICDType is equal because there isn't an
173+
# == operator for SICDType.
174+
# First confirm that all CollectionInfo properties are equal.
175+
assert sicd_meta.CollectionInfo.Classification == \
176+
sicd_writer.sicd_meta.CollectionInfo.Classification
177+
assert sicd_meta.CollectionInfo.CollectorName == \
178+
sicd_writer.sicd_meta.CollectionInfo.CollectorName
179+
assert sicd_meta.CollectionInfo.IlluminatorName == \
180+
sicd_writer.sicd_meta.CollectionInfo.IlluminatorName
181+
assert sicd_meta.CollectionInfo.CoreName == \
182+
sicd_writer.sicd_meta.CollectionInfo.CoreName
183+
assert sicd_meta.CollectionInfo.CollectType == \
184+
sicd_writer.sicd_meta.CollectionInfo.CollectType
185+
assert sicd_meta.CollectionInfo.CountryCodes == \
186+
sicd_writer.sicd_meta.CollectionInfo.CountryCodes
187+
assert sicd_meta.CollectionInfo.Parameters == \
188+
sicd_writer.sicd_meta.CollectionInfo.Parameters
189+
assert sicd_meta.CollectionInfo.RadarMode.ModeType == \
190+
sicd_writer.sicd_meta.CollectionInfo.RadarMode.ModeType
191+
assert sicd_meta.CollectionInfo.RadarMode.ModeID == \
192+
sicd_writer.sicd_meta.CollectionInfo.RadarMode.ModeID
193+
# Confirm ImageCreation properties are equal.
194+
assert sicd_meta.ImageCreation.Application == \
195+
sicd_writer.sicd_meta.ImageCreation.Application
196+
assert sicd_meta.ImageCreation.DateTime == \
197+
sicd_writer.sicd_meta.ImageCreation.DateTime
198+
assert sicd_meta.ImageCreation.Site == \
199+
sicd_writer.sicd_meta.ImageCreation.Site
200+
# TODO: These are different because one is based on the profile from the
201+
# file and the other is based on the profile of the version of sarpy
202+
# we are testing. Skip for now. Determine if these should be the same
203+
# assert sicd_meta.ImageCreation.Profile == \
204+
# sicd_writer.sicd_meta.ImageCreation.Profile
205+
# Confirm ImageData properties are equal.
206+
assert sicd_meta.ImageData.AmpTable == \
207+
sicd_writer.sicd_meta.ImageData.AmpTable
208+
assert sicd_meta.ImageData.FirstCol == \
209+
sicd_writer.sicd_meta.ImageData.FirstCol
210+
assert sicd_meta.ImageData.FirstRow == \
211+
sicd_writer.sicd_meta.ImageData.FirstRow
212+
assert sicd_meta.ImageData.PixelType == \
213+
sicd_writer.sicd_meta.ImageData.PixelType
214+
assert sicd_meta.ImageData.SCPPixel.Row == \
215+
sicd_writer.sicd_meta.ImageData.SCPPixel.Row
216+
assert sicd_meta.ImageData.SCPPixel.Col == \
217+
sicd_writer.sicd_meta.ImageData.SCPPixel.Col
218+
assert sicd_meta.ImageData.FullImage.NumCols == \
219+
sicd_writer.sicd_meta.ImageData.FullImage.NumCols
220+
assert sicd_meta.ImageData.FullImage.NumRows == \
221+
sicd_writer.sicd_meta.ImageData.FullImage.NumRows
222+
# Confirm GeoData properties are equal.
223+
assert sicd_meta.GeoData.EarthModel == \
224+
sicd_writer.sicd_meta.GeoData.EarthModel
225+
assert sicd_meta.GeoData.SCP.ECF.X == \
226+
sicd_writer.sicd_meta.GeoData.SCP.ECF.X
227+
assert sicd_meta.GeoData.SCP.ECF.Y == \
228+
sicd_writer.sicd_meta.GeoData.SCP.ECF.Y
229+
assert sicd_meta.GeoData.SCP.ECF.Z == \
230+
sicd_writer.sicd_meta.GeoData.SCP.ECF.Z
231+
assert sicd_meta.GeoData.SCP.LLH.Lat == \
232+
sicd_writer.sicd_meta.GeoData.SCP.LLH.Lat
233+
assert sicd_meta.GeoData.SCP.LLH.Lon == \
234+
sicd_writer.sicd_meta.GeoData.SCP.LLH.Lon
235+
assert sicd_meta.GeoData.SCP.LLH.HAE == \
236+
sicd_writer.sicd_meta.GeoData.SCP.LLH.HAE
237+
# TODO: Confirm ImageCorners match.
238+
assert numpy.allclose(sicd_meta.GeoData.ImageCorners.FRFC, \
239+
sicd_writer.sicd_meta.GeoData.ImageCorners.FRFC)
240+
assert numpy.allclose(sicd_meta.GeoData.ImageCorners.FRLC, \
241+
sicd_writer.sicd_meta.GeoData.ImageCorners.FRLC)
242+
assert numpy.allclose(sicd_meta.GeoData.ImageCorners.LRFC, \
243+
sicd_writer.sicd_meta.GeoData.ImageCorners.LRFC)
244+
assert numpy.allclose(sicd_meta.GeoData.ImageCorners.LRLC, \
245+
sicd_writer.sicd_meta.GeoData.ImageCorners.LRLC)
246+
# Confirm Grid properties are equal.
247+
assert sicd_meta.Grid.Col.SS == \
248+
sicd_writer.sicd_meta.Grid.Col.SS
249+
assert sicd_meta.Grid.Col.UVectECF.X == \
250+
sicd_writer.sicd_meta.Grid.Col.UVectECF.X
251+
assert sicd_meta.Grid.Col.UVectECF.Y == \
252+
sicd_writer.sicd_meta.Grid.Col.UVectECF.Y
253+
assert sicd_meta.Grid.Col.UVectECF.Z == \
254+
sicd_writer.sicd_meta.Grid.Col.UVectECF.Z
255+
assert sicd_meta.Grid.Row.SS == \
256+
sicd_writer.sicd_meta.Grid.Row.SS
257+
assert pytest.approx(sicd_meta.Grid.Row.UVectECF.X) == \
258+
pytest.approx(sicd_writer.sicd_meta.Grid.Row.UVectECF.X)
259+
assert pytest.approx(sicd_meta.Grid.Row.UVectECF.Y) == \
260+
pytest.approx(sicd_writer.sicd_meta.Grid.Row.UVectECF.Y)
261+
assert pytest.approx(sicd_meta.Grid.Row.UVectECF.Z) == \
262+
pytest.approx(sicd_writer.sicd_meta.Grid.Row.UVectECF.Z)
263+
assert sicd_meta.Grid.TimeCOAPoly.Coefs == \
264+
sicd_writer.sicd_meta.Grid.TimeCOAPoly.Coefs
265+
assert sicd_meta.Grid.TimeCOAPoly.order1 == \
266+
sicd_writer.sicd_meta.Grid.TimeCOAPoly.order1
267+
assert sicd_meta.Grid.TimeCOAPoly.order2 == \
268+
sicd_writer.sicd_meta.Grid.TimeCOAPoly.order2
269+
assert sicd_meta.Grid.Type == \
270+
sicd_writer.sicd_meta.Grid.Type
271+
assert sicd_meta.Grid.ImagePlane == \
272+
sicd_writer.sicd_meta.Grid.ImagePlane
273+
# Confirm Timeline properties are equal.
274+
assert sicd_meta.Timeline.IPP == \
275+
sicd_writer.sicd_meta.Timeline.IPP
276+
assert sicd_meta.Timeline.CollectStart == \
277+
sicd_writer.sicd_meta.Timeline.CollectStart
278+
assert sicd_meta.Timeline.CollectDuration == \
279+
sicd_writer.sicd_meta.Timeline.CollectDuration
280+
# Confirm Position properties are equal.
281+
assert pytest.approx(sicd_meta.Position.ARPPoly.X) == \
282+
pytest.approx(sicd_writer.sicd_meta.Position.ARPPoly.X)
283+
assert pytest.approx(sicd_meta.Position.ARPPoly.Y) == \
284+
pytest.approx(sicd_writer.sicd_meta.Position.ARPPoly.Y)
285+
assert pytest.approx(sicd_meta.Position.ARPPoly.Z) == \
286+
pytest.approx(sicd_writer.sicd_meta.Position.ARPPoly.Z)
287+
assert pytest.approx(sicd_meta.Position.GRPPoly.X) == \
288+
pytest.approx(sicd_writer.sicd_meta.Position.GRPPoly.X)
289+
assert pytest.approx(sicd_meta.Position.GRPPoly.Y) == \
290+
pytest.approx(sicd_writer.sicd_meta.Position.GRPPoly.Y)
291+
assert pytest.approx(sicd_meta.Position.GRPPoly.Z) == \
292+
pytest.approx(sicd_writer.sicd_meta.Position.GRPPoly.Z)
293+
# Confirm TxAPCPoly properties are equal.
294+
if isinstance(sicd_meta.Position.TxAPCPoly, XYZPolyType) \
295+
and isinstance(sicd_meta.Position.TxAPCPoly, XYZPolyType):
296+
assert pytest.approx(sicd_meta.Position.TxAPCPoly.X) == \
297+
pytest.approx(sicd_writer.sicd_meta.Position.TxAPCPoly.X)
298+
assert pytest.approx(sicd_meta.Position.TxAPCPoly.Y) == \
299+
pytest.approx(sicd_writer.sicd_meta.Position.TxAPCPoly.Y)
300+
assert pytest.approx(sicd_meta.Position.TxAPCPoly.Z) == \
301+
pytest.approx(sicd_writer.sicd_meta.Position.TxAPCPoly.Z)
302+
# Confirm RcvAPC properties are equal.
303+
if isinstance(sicd_meta.Position.RcvAPC, XYZPolyType) \
304+
and isinstance(sicd_meta.Position.RcvAPC, XYZPolyType):
305+
assert pytest.approx(sicd_meta.Position.RcvAPC.X) == \
306+
pytest.approx(sicd_writer.sicd_meta.Position.RcvAPC.X)
307+
assert pytest.approx(sicd_meta.Position.RcvAPC.Y) == \
308+
pytest.approx(sicd_writer.sicd_meta.Position.RcvAPC.Y)
309+
assert pytest.approx(sicd_meta.Position.RcvAPC.Z) == \
310+
pytest.approx(sicd_writer.sicd_meta.Position.RcvAPC.Z)
311+
# Confirm RadarCollection properties are equal.
312+
assert numpy.allclose(sicd_meta.RadarCollection.TxFrequency.get_array(), \
313+
sicd_writer.sicd_meta.RadarCollection.TxFrequency.get_array())
314+
assert sicd_meta.RadarCollection.RefFreqIndex == \
315+
sicd_writer.sicd_meta.RadarCollection.RefFreqIndex
316+
# TODO: Make this comparison work.
317+
# assert numpy.allclose(sicd_meta.RadarCollection.Waveform.get_array(), \
318+
# sicd_writer.sicd_meta.RadarCollection.Waveform.get_array())
319+
assert sicd_meta.RadarCollection.TxPolarization == \
320+
sicd_writer.sicd_meta.RadarCollection.TxPolarization
321+
322+
# TODO: Make tests for ImageFormation. This type requires an in depth
323+
# comparison
324+
# assert sicd_meta.ImageFormation.TxPolarization == \
325+
# sicd_writer.sicd_meta.ImageFormation.TxPolarization
326+
# Confirm SCPCOA properties are equal.
327+
assert pytest.approx(sicd_meta.SCPCOA.SCPTime) == \
328+
pytest.approx(sicd_writer.sicd_meta.SCPCOA.SCPTime)
329+
assert pytest.approx(sicd_meta.SCPCOA.ARPPos.X) == \
330+
pytest.approx(sicd_writer.sicd_meta.SCPCOA.ARPPos.X)
331+
assert pytest.approx(sicd_meta.SCPCOA.ARPPos.Y) == \
332+
pytest.approx(sicd_writer.sicd_meta.SCPCOA.ARPPos.Y)
333+
assert pytest.approx(sicd_meta.SCPCOA.ARPPos.Z) == \
334+
pytest.approx(sicd_writer.sicd_meta.SCPCOA.ARPPos.Z)
335+
assert pytest.approx(sicd_meta.SCPCOA.ARPVel.X) == \
336+
pytest.approx(sicd_writer.sicd_meta.SCPCOA.ARPVel.X)
337+
assert pytest.approx(sicd_meta.SCPCOA.ARPVel.Y) == \
338+
pytest.approx(sicd_writer.sicd_meta.SCPCOA.ARPVel.Y)
339+
assert pytest.approx(sicd_meta.SCPCOA.ARPVel.Z) == \
340+
pytest.approx(sicd_writer.sicd_meta.SCPCOA.ARPVel.Z)
341+
assert pytest.approx(sicd_meta.SCPCOA.ARPAcc.X) == \
342+
pytest.approx(sicd_writer.sicd_meta.SCPCOA.ARPAcc.X)
343+
assert pytest.approx(sicd_meta.SCPCOA.ARPAcc.Y) == \
344+
pytest.approx(sicd_writer.sicd_meta.SCPCOA.ARPAcc.Y)
345+
assert pytest.approx(sicd_meta.SCPCOA.ARPAcc.Z) == \
346+
pytest.approx(sicd_writer.sicd_meta.SCPCOA.ARPAcc.Z)
347+
assert sicd_meta.SCPCOA.SideOfTrack == \
348+
sicd_writer.sicd_meta.SCPCOA.SideOfTrack
349+
assert pytest.approx(sicd_meta.SCPCOA.SlantRange) == \
350+
pytest.approx(sicd_writer.sicd_meta.SCPCOA.SlantRange)
351+
assert pytest.approx(sicd_meta.SCPCOA.GroundRange) == \
352+
pytest.approx(sicd_writer.sicd_meta.SCPCOA.GroundRange)
353+
assert pytest.approx(sicd_meta.SCPCOA.DopplerConeAng) == \
354+
pytest.approx(sicd_writer.sicd_meta.SCPCOA.DopplerConeAng)
355+
assert pytest.approx(sicd_meta.SCPCOA.GrazeAng) == \
356+
pytest.approx(sicd_writer.sicd_meta.SCPCOA.GrazeAng)
357+
assert pytest.approx(sicd_meta.SCPCOA.IncidenceAng) == \
358+
pytest.approx(sicd_writer.sicd_meta.SCPCOA.IncidenceAng)
359+
assert pytest.approx(sicd_meta.SCPCOA.TwistAng) == \
360+
pytest.approx(sicd_writer.sicd_meta.SCPCOA.TwistAng)
361+
assert pytest.approx(sicd_meta.SCPCOA.SlopeAng) == \
362+
pytest.approx(sicd_writer.sicd_meta.SCPCOA.SlopeAng)
363+
assert pytest.approx(sicd_meta.SCPCOA.AzimAng) == \
364+
pytest.approx(sicd_writer.sicd_meta.SCPCOA.AzimAng)
365+
assert pytest.approx(sicd_meta.SCPCOA.LayoverAng) == \
366+
pytest.approx(sicd_writer.sicd_meta.SCPCOA.LayoverAng)
367+
368+
# The following sicd_meta features are optional, so skip them in the test for
369+
# now.
370+
# 'Radiometric', 'Antenna', 'ErrorStatistics', 'MatchInfo', 'RgAzComp',
371+
# 'PFA', 'RMA'

0 commit comments

Comments
 (0)