dkist-header-validator 5.2.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dkist_header_validator/__init__.py +12 -0
- dkist_header_validator/api/__init__.py +0 -0
- dkist_header_validator/api/validate.py +66 -0
- dkist_header_validator/base_validator.py +751 -0
- dkist_header_validator/exceptions.py +51 -0
- dkist_header_validator/spec_validators.py +54 -0
- dkist_header_validator/tests/__init__.py +0 -0
- dkist_header_validator/tests/conftest.py +639 -0
- dkist_header_validator/tests/test_base_validator.py +494 -0
- dkist_header_validator/tests/test_spec122_translation.py +233 -0
- dkist_header_validator/tests/test_spec122_validation+.py +144 -0
- dkist_header_validator/tests/test_spec122_validation-.py +118 -0
- dkist_header_validator/tests/test_spec214_validation+.py +402 -0
- dkist_header_validator/tests/test_spec214_validation-.py +211 -0
- dkist_header_validator/tests/test_translator.py +114 -0
- dkist_header_validator/translator.py +251 -0
- dkist_header_validator/utils/__init__.py +0 -0
- dkist_header_validator/utils/expansions.py +18 -0
- dkist_header_validator/version.py +8 -0
- dkist_header_validator-5.2.0.dist-info/METADATA +151 -0
- dkist_header_validator-5.2.0.dist-info/RECORD +24 -0
- dkist_header_validator-5.2.0.dist-info/WHEEL +5 -0
- dkist_header_validator-5.2.0.dist-info/entry_points.txt +2 -0
- dkist_header_validator-5.2.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,639 @@
|
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from random import choice
|
|
3
|
+
from uuid import uuid4
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
import pytest
|
|
7
|
+
from astropy.io import fits
|
|
8
|
+
from astropy.wcs import WCS
|
|
9
|
+
from dkist_data_simulator.spec122 import Spec122Dataset
|
|
10
|
+
from dkist_data_simulator.spec214 import Spec214Dataset
|
|
11
|
+
from dkist_fits_specifications.spec122 import load_spec122
|
|
12
|
+
from dkist_fits_specifications.spec214 import load_spec214
|
|
13
|
+
from dkist_fits_specifications.spec214.level0 import load_level0_spec214
|
|
14
|
+
|
|
15
|
+
FITS_OBJECT_TYPES = [
|
|
16
|
+
"fits",
|
|
17
|
+
"dict",
|
|
18
|
+
"hdulist",
|
|
19
|
+
"header",
|
|
20
|
+
"multiple_fits_cards_fits",
|
|
21
|
+
"multiple_fits_cards_hdulist",
|
|
22
|
+
"multiple_fits_cards_header",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def get_fits_object(
|
|
27
|
+
object_type: str, tmpdir: Path, ds, required_only: bool = False, expected_only: bool = False
|
|
28
|
+
) -> str | dict | fits.HDUList | fits.header.Header:
|
|
29
|
+
"""
|
|
30
|
+
Build up the required object type from the given simulated Dataset
|
|
31
|
+
|
|
32
|
+
TYPES
|
|
33
|
+
-----
|
|
34
|
+
fits : a fits file on disk
|
|
35
|
+
compressed : a compressed fits file on disk
|
|
36
|
+
dict : headers formatted as a python dict
|
|
37
|
+
hdulist : headers built into a PrimaryHDU presented in an HDUList
|
|
38
|
+
header : headers formatted as a fits.header.Header
|
|
39
|
+
second_hdu: a fits file on disk with the headers located in the second hdu
|
|
40
|
+
|
|
41
|
+
multiple_fits_cards_fits: a fits file on disk that has multiple fits_cards
|
|
42
|
+
multiple_fits_cards_hdulist: headers built into a PrimaryHDU presented in an HDUList with multiple fits_cards
|
|
43
|
+
multiple_fits_cards_header: headers formatted as a fits.header.Header with multiple fits_cards
|
|
44
|
+
"""
|
|
45
|
+
header_dict = [d.header(required_only=required_only, expected_only=expected_only) for d in ds][
|
|
46
|
+
0
|
|
47
|
+
]
|
|
48
|
+
data = np.ones(shape=ds.array_shape)
|
|
49
|
+
hdu = fits.PrimaryHDU(data=data)
|
|
50
|
+
for key, value in header_dict.items():
|
|
51
|
+
hdu.header[key] = value
|
|
52
|
+
|
|
53
|
+
if object_type == "fits":
|
|
54
|
+
file_name = tmpdir / f"{uuid4().hex}.fits"
|
|
55
|
+
hdu_list = fits.HDUList([hdu])
|
|
56
|
+
hdu_list.writeto(str(file_name))
|
|
57
|
+
return str(file_name)
|
|
58
|
+
|
|
59
|
+
if object_type == "compressed":
|
|
60
|
+
file_name = tmpdir / f"{uuid4().hex}.fits"
|
|
61
|
+
hdu_list = fits.HDUList(
|
|
62
|
+
[fits.PrimaryHDU(), fits.CompImageHDU(data=data, header=hdu.header)]
|
|
63
|
+
)
|
|
64
|
+
hdu_list.writeto(str(file_name))
|
|
65
|
+
return str(file_name)
|
|
66
|
+
|
|
67
|
+
if object_type == "dict":
|
|
68
|
+
return header_dict
|
|
69
|
+
|
|
70
|
+
if object_type == "hdulist":
|
|
71
|
+
return fits.HDUList([hdu])
|
|
72
|
+
|
|
73
|
+
if object_type == "header":
|
|
74
|
+
return hdu.header
|
|
75
|
+
|
|
76
|
+
if object_type == "second_hdu":
|
|
77
|
+
file_name = tmpdir / f"{uuid4().hex}.fits"
|
|
78
|
+
hdu_list = fits.HDUList([fits.PrimaryHDU(), fits.ImageHDU(data=data, header=hdu.header)])
|
|
79
|
+
hdu_list.writeto(str(file_name))
|
|
80
|
+
return str(file_name)
|
|
81
|
+
|
|
82
|
+
if object_type == "third_hdu":
|
|
83
|
+
file_name = tmpdir / f"{uuid4().hex}.fits"
|
|
84
|
+
hdu_list = fits.HDUList(
|
|
85
|
+
[
|
|
86
|
+
fits.PrimaryHDU(),
|
|
87
|
+
fits.ImageHDU(data=data, header=hdu.header),
|
|
88
|
+
fits.ImageHDU(data=data, header=hdu.header),
|
|
89
|
+
]
|
|
90
|
+
)
|
|
91
|
+
hdu_list.writeto(str(file_name))
|
|
92
|
+
return str(file_name)
|
|
93
|
+
|
|
94
|
+
history_card1 = "history card 1"
|
|
95
|
+
history_card2 = "history card 2"
|
|
96
|
+
hdu.header.add_history(history_card1)
|
|
97
|
+
hdu.header.add_history(history_card2)
|
|
98
|
+
if object_type == "multiple_fits_cards_header":
|
|
99
|
+
return hdu.header
|
|
100
|
+
|
|
101
|
+
hdu_list = fits.HDUList([hdu])
|
|
102
|
+
if object_type == "multiple_fits_cards_hdulist":
|
|
103
|
+
return hdu_list
|
|
104
|
+
|
|
105
|
+
if object_type == "multiple_fits_cards_fits":
|
|
106
|
+
file_name = tmpdir / f"{uuid4().hex}.fits"
|
|
107
|
+
hdu_list.writeto(str(file_name))
|
|
108
|
+
return str(file_name)
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
class BaseSpec122Dataset(Spec122Dataset):
|
|
112
|
+
def __init__(self, instrument="vbi"):
|
|
113
|
+
self.array_shape = (1, 10, 10)
|
|
114
|
+
super().__init__(
|
|
115
|
+
dataset_shape=(2, 10, 10),
|
|
116
|
+
array_shape=self.array_shape,
|
|
117
|
+
time_delta=1,
|
|
118
|
+
instrument=instrument,
|
|
119
|
+
)
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
123
|
+
def valid_spec_122_object(tmpdir, request):
|
|
124
|
+
yield get_fits_object(object_type=request.param, tmpdir=tmpdir, ds=BaseSpec122Dataset())
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
@pytest.fixture(scope="function", params=["dict", "header", "multiple_fits_cards_header"])
|
|
128
|
+
def valid_translator_object(tmpdir, request):
|
|
129
|
+
yield get_fits_object(object_type=request.param, tmpdir=tmpdir, ds=BaseSpec122Dataset())
|
|
130
|
+
|
|
131
|
+
|
|
132
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
133
|
+
def valid_spec_122_object_required_only(tmpdir, request):
|
|
134
|
+
yield get_fits_object(
|
|
135
|
+
object_type=request.param, tmpdir=tmpdir, ds=BaseSpec122Dataset(), required_only=True
|
|
136
|
+
)
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
@pytest.fixture(scope="function", params=["dict", "header"])
|
|
140
|
+
def valid_translator_object_required_only(tmpdir, request):
|
|
141
|
+
yield get_fits_object(
|
|
142
|
+
object_type=request.param, tmpdir=tmpdir, ds=BaseSpec122Dataset(), required_only=True
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
147
|
+
def valid_spec_122_object_expected_only(tmpdir, request):
|
|
148
|
+
yield get_fits_object(
|
|
149
|
+
object_type=request.param, tmpdir=tmpdir, ds=BaseSpec122Dataset(), expected_only=True
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
|
|
153
|
+
@pytest.fixture(scope="function", params=["dict", "header"])
|
|
154
|
+
def valid_translator_object_expected_only(tmpdir, request):
|
|
155
|
+
yield get_fits_object(
|
|
156
|
+
object_type=request.param, tmpdir=tmpdir, ds=BaseSpec122Dataset(), expected_only=True
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
|
|
160
|
+
@pytest.fixture(scope="function")
|
|
161
|
+
def valid_spec_122_file(tmpdir):
|
|
162
|
+
yield get_fits_object(object_type="fits", tmpdir=tmpdir, ds=BaseSpec122Dataset())
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
@pytest.fixture(scope="function")
|
|
166
|
+
def valid_spec_122_compressed(tmpdir):
|
|
167
|
+
yield get_fits_object(object_type="compressed", tmpdir=tmpdir, ds=BaseSpec122Dataset())
|
|
168
|
+
|
|
169
|
+
|
|
170
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
171
|
+
def valid_spec_122_visp(tmpdir, request):
|
|
172
|
+
yield get_fits_object(
|
|
173
|
+
object_type=request.param, tmpdir=tmpdir, ds=BaseSpec122Dataset(instrument="visp")
|
|
174
|
+
)
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
@pytest.fixture(scope="function", params=["dict", "header", "hdulist"])
|
|
178
|
+
def valid_spec_122_no_file(tmpdir, request):
|
|
179
|
+
yield get_fits_object(object_type=request.param, tmpdir=tmpdir, ds=BaseSpec122Dataset())
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
@pytest.fixture(scope="function")
|
|
183
|
+
def valid_spec_122_dict_only(tmpdir):
|
|
184
|
+
yield get_fits_object(object_type="dict", tmpdir=tmpdir, ds=BaseSpec122Dataset())
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
@pytest.fixture(scope="function")
|
|
188
|
+
def valid_spec_122_hdulist_only(tmpdir):
|
|
189
|
+
yield get_fits_object(object_type="hdulist", tmpdir=tmpdir, ds=BaseSpec122Dataset())
|
|
190
|
+
|
|
191
|
+
|
|
192
|
+
@pytest.fixture(scope="function")
|
|
193
|
+
def valid_spec_122_second_hdu(tmpdir):
|
|
194
|
+
yield get_fits_object(object_type="second_hdu", tmpdir=tmpdir, ds=BaseSpec122Dataset())
|
|
195
|
+
|
|
196
|
+
|
|
197
|
+
@pytest.fixture(scope="function")
|
|
198
|
+
def valid_spec_122_too_many_HDUs(tmpdir):
|
|
199
|
+
yield get_fits_object(object_type="third_hdu", tmpdir=tmpdir, ds=BaseSpec122Dataset())
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class Spec122DatasetExtraKeys(BaseSpec122Dataset):
|
|
203
|
+
def __init__(self):
|
|
204
|
+
super().__init__()
|
|
205
|
+
self.add_constant_key("XTRAKEY1", "ABCDEFG")
|
|
206
|
+
self.add_constant_key("XTRAKEY2", "HIJKLMN")
|
|
207
|
+
self.add_constant_key("XTRAKEY3", "OPQRSTU")
|
|
208
|
+
self.add_constant_key("XTRAKEY4", "VWXYZAB")
|
|
209
|
+
|
|
210
|
+
|
|
211
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
212
|
+
def valid_spec_122_object_extra_keys(tmpdir, request):
|
|
213
|
+
yield get_fits_object(object_type=request.param, tmpdir=tmpdir, ds=Spec122DatasetExtraKeys())
|
|
214
|
+
|
|
215
|
+
|
|
216
|
+
class InvalidBaseSpec122Dataset(Spec122Dataset):
|
|
217
|
+
def __init__(self, instrument="vbi"):
|
|
218
|
+
self.array_shape = (1, 10, 10)
|
|
219
|
+
super().__init__(
|
|
220
|
+
dataset_shape=(2, 10, 10),
|
|
221
|
+
array_shape=self.array_shape,
|
|
222
|
+
time_delta=1,
|
|
223
|
+
instrument=instrument,
|
|
224
|
+
)
|
|
225
|
+
self.add_remove_key("NAXIS1")
|
|
226
|
+
self.add_remove_key("NXAIS2")
|
|
227
|
+
self.add_remove_key("WAVELNTH")
|
|
228
|
+
self.add_remove_key("DATE-OBS")
|
|
229
|
+
self.add_remove_key("ID___002")
|
|
230
|
+
self.add_remove_key("ID___003")
|
|
231
|
+
self.add_remove_key("ID___012")
|
|
232
|
+
self.add_remove_key("DKIST003")
|
|
233
|
+
self.add_remove_key("DKIST004")
|
|
234
|
+
self.add_remove_key("HISTORY")
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
238
|
+
def invalid_spec_122_object(tmpdir, request):
|
|
239
|
+
yield get_fits_object(object_type=request.param, tmpdir=tmpdir, ds=InvalidBaseSpec122Dataset())
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
class InvalidInstrumentTableSpec122Dataset(BaseSpec122Dataset):
|
|
243
|
+
def __init__(self, instrument: str):
|
|
244
|
+
super().__init__(instrument=instrument)
|
|
245
|
+
|
|
246
|
+
# Remove a random key from the instrument table
|
|
247
|
+
glob_name = instrument.lower().replace(
|
|
248
|
+
"-", ""
|
|
249
|
+
) # For cryo and dl b/c the yamls don't have dashes
|
|
250
|
+
instrument_keys = load_spec122(glob=glob_name)[glob_name]
|
|
251
|
+
removal_candidates = [k for k, v in instrument_keys.items() if "instrument_required" in v]
|
|
252
|
+
removed_key = choice(removal_candidates)
|
|
253
|
+
self.add_remove_key(removed_key)
|
|
254
|
+
self.removed_key = removed_key
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
258
|
+
def invalid_instrument_table_spec_122_object(tmpdir, request, instrument):
|
|
259
|
+
dataset = InvalidInstrumentTableSpec122Dataset(instrument)
|
|
260
|
+
yield get_fits_object(object_type=request.param, tmpdir=tmpdir, ds=dataset), dataset.removed_key
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
class BaseSpec122DatasetCaseSensitive(Spec122Dataset):
|
|
264
|
+
def __init__(self, instrument="vbi"):
|
|
265
|
+
self.array_shape = (1, 10, 10)
|
|
266
|
+
super().__init__(
|
|
267
|
+
dataset_shape=(2, 10, 10),
|
|
268
|
+
array_shape=self.array_shape,
|
|
269
|
+
time_delta=1,
|
|
270
|
+
instrument=instrument,
|
|
271
|
+
)
|
|
272
|
+
self.add_constant_key("DKIST004", "oBSErve")
|
|
273
|
+
|
|
274
|
+
|
|
275
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
276
|
+
def valid_spec_122_casesensitive(tmpdir, request):
|
|
277
|
+
yield get_fits_object(
|
|
278
|
+
object_type=request.param, tmpdir=tmpdir, ds=BaseSpec122DatasetCaseSensitive()
|
|
279
|
+
)
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
class BaseSpec214l0Dataset(Spec122Dataset):
|
|
283
|
+
def __init__(self, instrument="vbi"):
|
|
284
|
+
self.array_shape = (1, 10, 10)
|
|
285
|
+
super().__init__(
|
|
286
|
+
dataset_shape=(2, 10, 10),
|
|
287
|
+
array_shape=self.array_shape,
|
|
288
|
+
time_delta=1,
|
|
289
|
+
instrument=instrument,
|
|
290
|
+
file_schema="level0_spec214",
|
|
291
|
+
)
|
|
292
|
+
|
|
293
|
+
|
|
294
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
295
|
+
def valid_spec_214l0_object(tmpdir, request):
|
|
296
|
+
yield get_fits_object(object_type=request.param, tmpdir=tmpdir, ds=BaseSpec214l0Dataset())
|
|
297
|
+
|
|
298
|
+
|
|
299
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
300
|
+
def valid_spec_214l0_object_required_only(tmpdir, request):
|
|
301
|
+
yield get_fits_object(
|
|
302
|
+
object_type=request.param, tmpdir=tmpdir, ds=BaseSpec214l0Dataset(), required_only=True
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
307
|
+
def valid_spec_214l0_object_expected_only(tmpdir, request):
|
|
308
|
+
yield get_fits_object(
|
|
309
|
+
object_type=request.param, tmpdir=tmpdir, ds=BaseSpec214l0Dataset(), expected_only=True
|
|
310
|
+
)
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
@pytest.fixture(scope="function")
|
|
314
|
+
def valid_spec_214l0_file(tmpdir):
|
|
315
|
+
yield get_fits_object(object_type="fits", tmpdir=tmpdir, ds=BaseSpec214l0Dataset())
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
@pytest.fixture(scope="function")
|
|
319
|
+
def valid_spec_214l0_compressed(tmpdir):
|
|
320
|
+
yield get_fits_object(object_type="compressed", tmpdir=tmpdir, ds=BaseSpec214l0Dataset())
|
|
321
|
+
|
|
322
|
+
|
|
323
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
324
|
+
def valid_spec_214l0_visp(tmpdir, request):
|
|
325
|
+
yield get_fits_object(
|
|
326
|
+
object_type=request.param, tmpdir=tmpdir, ds=BaseSpec214l0Dataset(instrument="visp")
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
@pytest.fixture(scope="function", params=["dict", "header", "hdulist"])
|
|
331
|
+
def valid_spec_214l0_no_file(tmpdir, request):
|
|
332
|
+
yield get_fits_object(object_type=request.param, tmpdir=tmpdir, ds=BaseSpec214l0Dataset())
|
|
333
|
+
|
|
334
|
+
|
|
335
|
+
@pytest.fixture(scope="function")
|
|
336
|
+
def valid_spec_214l0_dict_only(tmpdir):
|
|
337
|
+
yield get_fits_object(object_type="dict", tmpdir=tmpdir, ds=BaseSpec214l0Dataset())
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
@pytest.fixture(scope="function")
|
|
341
|
+
def valid_spec_214l0_hdulist_only(tmpdir):
|
|
342
|
+
yield get_fits_object(object_type="hdulist", tmpdir=tmpdir, ds=BaseSpec214l0Dataset())
|
|
343
|
+
|
|
344
|
+
|
|
345
|
+
@pytest.fixture(scope="function")
|
|
346
|
+
def valid_spec_214l0_second_hdu(tmpdir):
|
|
347
|
+
yield get_fits_object(object_type="second_hdu", tmpdir=tmpdir, ds=BaseSpec214l0Dataset())
|
|
348
|
+
|
|
349
|
+
|
|
350
|
+
@pytest.fixture(scope="function")
|
|
351
|
+
def valid_spec_214_l0_too_many_HDUs(tmpdir):
|
|
352
|
+
yield get_fits_object(object_type="third_hdu", tmpdir=tmpdir, ds=BaseSpec214l0Dataset())
|
|
353
|
+
|
|
354
|
+
|
|
355
|
+
class Spec214l0DatasetExtraKeys(BaseSpec214l0Dataset):
|
|
356
|
+
def __init__(self):
|
|
357
|
+
super().__init__()
|
|
358
|
+
self.add_constant_key("XTRAKEY1", "ABCDEFG")
|
|
359
|
+
self.add_constant_key("XTRAKEY2", "HIJKLMN")
|
|
360
|
+
self.add_constant_key("XTRAKEY3", "OPQRSTU")
|
|
361
|
+
self.add_constant_key("XTRAKEY4", "VWXYZAB")
|
|
362
|
+
|
|
363
|
+
|
|
364
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
365
|
+
def valid_spec_214l0_object_extra_keys(tmpdir, request):
|
|
366
|
+
yield get_fits_object(object_type=request.param, tmpdir=tmpdir, ds=Spec214l0DatasetExtraKeys())
|
|
367
|
+
|
|
368
|
+
|
|
369
|
+
class InvalidBaseSpec214l0Dataset(Spec122Dataset):
|
|
370
|
+
def __init__(self, instrument="vbi"):
|
|
371
|
+
self.array_shape = (1, 10, 10)
|
|
372
|
+
super().__init__(
|
|
373
|
+
dataset_shape=(2, 10, 10),
|
|
374
|
+
array_shape=self.array_shape,
|
|
375
|
+
time_delta=1,
|
|
376
|
+
instrument=instrument,
|
|
377
|
+
file_schema="level0_spec214",
|
|
378
|
+
)
|
|
379
|
+
self.add_remove_key("NAXIS1")
|
|
380
|
+
self.add_remove_key("NXAIS2")
|
|
381
|
+
self.add_remove_key("LINEWAV")
|
|
382
|
+
self.add_remove_key("DATE-OBS")
|
|
383
|
+
self.add_remove_key("FILE_ID")
|
|
384
|
+
self.add_remove_key("EXPER_ID")
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
388
|
+
def invalid_spec_214l0_object(tmpdir, request):
|
|
389
|
+
yield get_fits_object(
|
|
390
|
+
object_type=request.param, tmpdir=tmpdir, ds=InvalidBaseSpec214l0Dataset()
|
|
391
|
+
)
|
|
392
|
+
|
|
393
|
+
|
|
394
|
+
@pytest.fixture(scope="function")
|
|
395
|
+
def invalid_spec_214l0_compressed(tmpdir):
|
|
396
|
+
yield get_fits_object(object_type="compressed", tmpdir=tmpdir, ds=InvalidBaseSpec214l0Dataset())
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
class InvalidInstrumentTableSpec214l0Dataset(BaseSpec214l0Dataset):
|
|
400
|
+
def __init__(self, instrument: str):
|
|
401
|
+
super().__init__(instrument=instrument)
|
|
402
|
+
|
|
403
|
+
# Remove a random key from the instrument table
|
|
404
|
+
glob_name = instrument.lower().replace(
|
|
405
|
+
"-", ""
|
|
406
|
+
) # For cryo and dl b/c the yamls don't have dashes
|
|
407
|
+
instrument_keys = load_level0_spec214(glob=glob_name)[glob_name]
|
|
408
|
+
removal_candidates = [k for k, v in instrument_keys.items() if "instrument_required" in v]
|
|
409
|
+
removed_key = choice(removal_candidates)
|
|
410
|
+
self.add_remove_key(removed_key)
|
|
411
|
+
self.removed_key = removed_key
|
|
412
|
+
|
|
413
|
+
|
|
414
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
415
|
+
def invalid_instrument_table_spec_214l0_object(tmpdir, request, instrument):
|
|
416
|
+
dataset = InvalidInstrumentTableSpec214l0Dataset(instrument)
|
|
417
|
+
yield get_fits_object(object_type=request.param, tmpdir=tmpdir, ds=dataset), dataset.removed_key
|
|
418
|
+
|
|
419
|
+
|
|
420
|
+
class BaseSpec214l0DatasetCaseSensitive(Spec122Dataset):
|
|
421
|
+
def __init__(self, instrument="vbi"):
|
|
422
|
+
self.array_shape = (1, 10, 10)
|
|
423
|
+
super().__init__(
|
|
424
|
+
dataset_shape=(2, 10, 10),
|
|
425
|
+
array_shape=self.array_shape,
|
|
426
|
+
time_delta=1,
|
|
427
|
+
instrument=instrument,
|
|
428
|
+
file_schema="level0_spec214",
|
|
429
|
+
)
|
|
430
|
+
self.add_constant_key("VBISYNCM", "fIxED")
|
|
431
|
+
|
|
432
|
+
|
|
433
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
434
|
+
def valid_spec_214l0_casesensitive(tmpdir, request):
|
|
435
|
+
yield get_fits_object(
|
|
436
|
+
object_type=request.param, tmpdir=tmpdir, ds=BaseSpec214l0DatasetCaseSensitive()
|
|
437
|
+
)
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
class BaseSpec214Dataset(Spec214Dataset):
|
|
441
|
+
def __init__(self, instrument="vbi"):
|
|
442
|
+
self.array_shape = (10, 10)
|
|
443
|
+
super().__init__(
|
|
444
|
+
dataset_shape=(2, 10, 10),
|
|
445
|
+
array_shape=self.array_shape,
|
|
446
|
+
time_delta=1,
|
|
447
|
+
instrument=instrument,
|
|
448
|
+
)
|
|
449
|
+
|
|
450
|
+
@property
|
|
451
|
+
def fits_wcs(self):
|
|
452
|
+
w = WCS(naxis=2)
|
|
453
|
+
w.wcs.crpix = self.array_shape[1] / 2, self.array_shape[0] / 2
|
|
454
|
+
w.wcs.crval = 0, 0
|
|
455
|
+
w.wcs.cdelt = 1, 1
|
|
456
|
+
w.wcs.cunit = "arcsec", "arcsec"
|
|
457
|
+
w.wcs.ctype = "HPLN-TAN", "HPLT-TAN"
|
|
458
|
+
w.wcs.pc = np.identity(self.array_ndim)
|
|
459
|
+
return w
|
|
460
|
+
|
|
461
|
+
|
|
462
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
463
|
+
def valid_spec_214_object(tmpdir, request):
|
|
464
|
+
yield get_fits_object(object_type=request.param, tmpdir=tmpdir, ds=BaseSpec214Dataset())
|
|
465
|
+
|
|
466
|
+
|
|
467
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
468
|
+
def valid_spec_214_object_required_only(tmpdir, request):
|
|
469
|
+
yield get_fits_object(
|
|
470
|
+
object_type=request.param, tmpdir=tmpdir, ds=BaseSpec214Dataset(), required_only=True
|
|
471
|
+
)
|
|
472
|
+
|
|
473
|
+
|
|
474
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
475
|
+
def valid_spec_214_object_expected_only(tmpdir, request):
|
|
476
|
+
yield get_fits_object(
|
|
477
|
+
object_type=request.param, tmpdir=tmpdir, ds=BaseSpec214Dataset(), expected_only=True
|
|
478
|
+
)
|
|
479
|
+
|
|
480
|
+
|
|
481
|
+
@pytest.fixture(scope="function")
|
|
482
|
+
def valid_spec_214_file(tmpdir):
|
|
483
|
+
yield get_fits_object(object_type="fits", tmpdir=tmpdir, ds=BaseSpec214Dataset())
|
|
484
|
+
|
|
485
|
+
|
|
486
|
+
@pytest.fixture(scope="function")
|
|
487
|
+
def valid_spec_214_compressed(tmpdir):
|
|
488
|
+
yield get_fits_object(object_type="compressed", tmpdir=tmpdir, ds=BaseSpec214Dataset())
|
|
489
|
+
|
|
490
|
+
|
|
491
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
492
|
+
def valid_spec_214_visp(tmpdir, request):
|
|
493
|
+
yield get_fits_object(
|
|
494
|
+
object_type=request.param, tmpdir=tmpdir, ds=BaseSpec214Dataset(instrument="visp")
|
|
495
|
+
)
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
@pytest.fixture(
|
|
499
|
+
scope="function", params=["dict", "header", "hdulist", "multiple_fits_cards_header"]
|
|
500
|
+
)
|
|
501
|
+
def valid_spec_214_no_file(tmpdir, request):
|
|
502
|
+
yield get_fits_object(object_type=request.param, tmpdir=tmpdir, ds=BaseSpec214Dataset())
|
|
503
|
+
|
|
504
|
+
|
|
505
|
+
@pytest.fixture(scope="function")
|
|
506
|
+
def valid_spec_214_dict_only(tmpdir):
|
|
507
|
+
yield get_fits_object(object_type="dict", tmpdir=tmpdir, ds=BaseSpec214Dataset())
|
|
508
|
+
|
|
509
|
+
|
|
510
|
+
@pytest.fixture(scope="function")
|
|
511
|
+
def valid_spec_214_hdulist_only(tmpdir):
|
|
512
|
+
yield get_fits_object(object_type="hdulist", tmpdir=tmpdir, ds=BaseSpec214Dataset())
|
|
513
|
+
|
|
514
|
+
|
|
515
|
+
@pytest.fixture(scope="function")
|
|
516
|
+
def valid_spec_214_second_hdu(tmpdir):
|
|
517
|
+
yield get_fits_object(object_type="second_hdu", tmpdir=tmpdir, ds=BaseSpec214Dataset())
|
|
518
|
+
|
|
519
|
+
|
|
520
|
+
@pytest.fixture(scope="function")
|
|
521
|
+
def valid_spec_214_too_many_HDUs(tmpdir):
|
|
522
|
+
yield get_fits_object(object_type="third_hdu", tmpdir=tmpdir, ds=BaseSpec214Dataset())
|
|
523
|
+
|
|
524
|
+
|
|
525
|
+
class Spec214DatasetExtraKeys(BaseSpec214Dataset):
|
|
526
|
+
def __init__(self):
|
|
527
|
+
super().__init__()
|
|
528
|
+
self.add_constant_key("XTRAKEY1", "ABCDEFG")
|
|
529
|
+
self.add_constant_key("XTRAKEY2", "HIJKLMN")
|
|
530
|
+
self.add_constant_key("XTRAKEY3", "OPQRSTU")
|
|
531
|
+
self.add_constant_key("XTRAKEY4", "VWXYZAB")
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
535
|
+
def valid_spec_214_object_extra_keys(tmpdir, request):
|
|
536
|
+
yield get_fits_object(object_type=request.param, tmpdir=tmpdir, ds=Spec214DatasetExtraKeys())
|
|
537
|
+
|
|
538
|
+
|
|
539
|
+
class InvalidBaseSpec214Dataset(Spec214Dataset):
|
|
540
|
+
def __init__(self, instrument="vbi"):
|
|
541
|
+
self.array_shape = (10, 10)
|
|
542
|
+
super().__init__(
|
|
543
|
+
dataset_shape=(2, 10, 10),
|
|
544
|
+
array_shape=self.array_shape,
|
|
545
|
+
time_delta=1,
|
|
546
|
+
instrument=instrument,
|
|
547
|
+
)
|
|
548
|
+
self.add_remove_key("NAXIS1")
|
|
549
|
+
self.add_remove_key("NXAIS2")
|
|
550
|
+
self.add_remove_key("LINEWAV")
|
|
551
|
+
self.add_remove_key("DATE-OBS")
|
|
552
|
+
self.add_remove_key("FILE_ID")
|
|
553
|
+
self.add_remove_key("EXPER_ID")
|
|
554
|
+
|
|
555
|
+
@property
|
|
556
|
+
def fits_wcs(self):
|
|
557
|
+
w = WCS(naxis=2)
|
|
558
|
+
w.wcs.crpix = self.array_shape[1] / 2, self.array_shape[0] / 2
|
|
559
|
+
w.wcs.crval = 0, 0
|
|
560
|
+
w.wcs.cdelt = 1, 1
|
|
561
|
+
w.wcs.cunit = "arcsec", "arcsec"
|
|
562
|
+
w.wcs.ctype = "HPLN-TAN", "HPLT-TAN"
|
|
563
|
+
w.wcs.pc = np.identity(self.array_ndim)
|
|
564
|
+
return w
|
|
565
|
+
|
|
566
|
+
|
|
567
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
568
|
+
def invalid_spec_214_object(tmpdir, request):
|
|
569
|
+
yield get_fits_object(object_type=request.param, tmpdir=tmpdir, ds=InvalidBaseSpec214Dataset())
|
|
570
|
+
|
|
571
|
+
|
|
572
|
+
@pytest.fixture(scope="function")
|
|
573
|
+
def invalid_spec_214_compressed(tmpdir):
|
|
574
|
+
yield get_fits_object(object_type="compressed", tmpdir=tmpdir, ds=InvalidBaseSpec214Dataset())
|
|
575
|
+
|
|
576
|
+
|
|
577
|
+
class BaseSpec214DatasetCaseSensitive(Spec214Dataset):
|
|
578
|
+
def __init__(self, instrument="vbi"):
|
|
579
|
+
self.array_shape = (10, 10)
|
|
580
|
+
super().__init__(
|
|
581
|
+
dataset_shape=(2, 10, 10),
|
|
582
|
+
array_shape=self.array_shape,
|
|
583
|
+
time_delta=1,
|
|
584
|
+
instrument=instrument,
|
|
585
|
+
)
|
|
586
|
+
self.add_constant_key("VBISYNCM", "fIxED")
|
|
587
|
+
|
|
588
|
+
@property
|
|
589
|
+
def fits_wcs(self):
|
|
590
|
+
w = WCS(naxis=2)
|
|
591
|
+
w.wcs.crpix = self.array_shape[1] / 2, self.array_shape[0] / 2
|
|
592
|
+
w.wcs.crval = 0, 0
|
|
593
|
+
w.wcs.cdelt = 1, 1
|
|
594
|
+
w.wcs.cunit = "arcsec", "arcsec"
|
|
595
|
+
w.wcs.ctype = "HPLN-TAN", "HPLT-TAN"
|
|
596
|
+
w.wcs.pc = np.identity(self.array_ndim)
|
|
597
|
+
return w
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
601
|
+
def valid_spec_214_casesensitive(tmpdir, request):
|
|
602
|
+
yield get_fits_object(
|
|
603
|
+
object_type=request.param, tmpdir=tmpdir, ds=BaseSpec214DatasetCaseSensitive()
|
|
604
|
+
)
|
|
605
|
+
|
|
606
|
+
|
|
607
|
+
class InvalidPolarimetricSpec214Dataset(BaseSpec214Dataset):
|
|
608
|
+
def __init__(self):
|
|
609
|
+
super().__init__(instrument="visp")
|
|
610
|
+
self.add_constant_key("VSPPOLMD", "observe_polarimetric")
|
|
611
|
+
self.add_remove_key("POL_SENS")
|
|
612
|
+
|
|
613
|
+
|
|
614
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
615
|
+
def invalid_polarimetric_spec_214_object(tmpdir, request):
|
|
616
|
+
yield get_fits_object(
|
|
617
|
+
object_type=request.param, tmpdir=tmpdir, ds=InvalidPolarimetricSpec214Dataset()
|
|
618
|
+
)
|
|
619
|
+
|
|
620
|
+
|
|
621
|
+
class InvalidInstrumentTableSpec214Dataset(BaseSpec214Dataset):
|
|
622
|
+
def __init__(self, instrument: str):
|
|
623
|
+
super().__init__(instrument=instrument)
|
|
624
|
+
|
|
625
|
+
# Remove a random key from the instrument table
|
|
626
|
+
glob_name = instrument.lower().replace(
|
|
627
|
+
"-", ""
|
|
628
|
+
) # For cryo and dl b/c the yamls don't have dashes
|
|
629
|
+
instrument_keys = load_spec214(glob=glob_name)[glob_name]
|
|
630
|
+
removal_candidates = [k for k, v in instrument_keys.items() if "instrument_required" in v]
|
|
631
|
+
removed_key = choice(removal_candidates)
|
|
632
|
+
self.add_remove_key(removed_key)
|
|
633
|
+
self.removed_key = removed_key
|
|
634
|
+
|
|
635
|
+
|
|
636
|
+
@pytest.fixture(scope="function", params=FITS_OBJECT_TYPES)
|
|
637
|
+
def invalid_instrument_table_spec_214_object(tmpdir, request, instrument):
|
|
638
|
+
dataset = InvalidInstrumentTableSpec214Dataset(instrument)
|
|
639
|
+
yield get_fits_object(object_type=request.param, tmpdir=tmpdir, ds=dataset), dataset.removed_key
|