dkist-processing-common 11.6.0__py3-none-any.whl → 11.7.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_processing_common/models/constants.py +333 -21
- dkist_processing_common/models/fits_access.py +16 -25
- dkist_processing_common/parsers/average_bud.py +48 -0
- dkist_processing_common/parsers/experiment_id_bud.py +8 -4
- dkist_processing_common/parsers/id_bud.py +35 -19
- dkist_processing_common/parsers/l0_fits_access.py +3 -3
- dkist_processing_common/parsers/l1_fits_access.py +47 -21
- dkist_processing_common/parsers/near_bud.py +4 -4
- dkist_processing_common/parsers/observing_program_id_bud.py +24 -0
- dkist_processing_common/parsers/proposal_id_bud.py +11 -5
- dkist_processing_common/parsers/single_value_single_key_flower.py +0 -1
- dkist_processing_common/parsers/time.py +147 -27
- dkist_processing_common/tasks/parse_l0_input_data.py +246 -1
- dkist_processing_common/tests/test_fits_access.py +19 -44
- dkist_processing_common/tests/test_parse_l0_input_data.py +45 -5
- dkist_processing_common/tests/test_stems.py +162 -10
- dkist_processing_common/tests/test_task_parsing.py +6 -6
- {dkist_processing_common-11.6.0.dist-info → dkist_processing_common-11.7.0.dist-info}/METADATA +2 -2
- {dkist_processing_common-11.6.0.dist-info → dkist_processing_common-11.7.0.dist-info}/RECORD +21 -19
- {dkist_processing_common-11.6.0.dist-info → dkist_processing_common-11.7.0.dist-info}/WHEEL +0 -0
- {dkist_processing_common-11.6.0.dist-info → dkist_processing_common-11.7.0.dist-info}/top_level.txt +0 -0
|
@@ -34,16 +34,23 @@ from dkist_processing_common.models.flower_pot import Stem
|
|
|
34
34
|
from dkist_processing_common.models.flower_pot import Thorn
|
|
35
35
|
from dkist_processing_common.models.tags import Tag
|
|
36
36
|
from dkist_processing_common.models.task_name import TaskName
|
|
37
|
+
from dkist_processing_common.parsers.average_bud import TaskAverageBud
|
|
37
38
|
from dkist_processing_common.parsers.experiment_id_bud import ContributingExperimentIdsBud
|
|
38
39
|
from dkist_processing_common.parsers.experiment_id_bud import ExperimentIdBud
|
|
40
|
+
from dkist_processing_common.parsers.observing_program_id_bud import (
|
|
41
|
+
TaskContributingObservingProgramExecutionIdsBud,
|
|
42
|
+
)
|
|
39
43
|
from dkist_processing_common.parsers.proposal_id_bud import ContributingProposalIdsBud
|
|
40
44
|
from dkist_processing_common.parsers.proposal_id_bud import ProposalIdBud
|
|
45
|
+
from dkist_processing_common.parsers.task import parse_header_ip_task_with_gains
|
|
41
46
|
from dkist_processing_common.parsers.time import AverageCadenceBud
|
|
42
47
|
from dkist_processing_common.parsers.time import MaximumCadenceBud
|
|
43
48
|
from dkist_processing_common.parsers.time import MinimumCadenceBud
|
|
49
|
+
from dkist_processing_common.parsers.time import TaskDateBeginBud
|
|
44
50
|
from dkist_processing_common.parsers.time import TaskExposureTimesBud
|
|
45
51
|
from dkist_processing_common.parsers.time import TaskReadoutExpTimesBud
|
|
46
52
|
from dkist_processing_common.parsers.time import VarianceCadenceBud
|
|
53
|
+
from dkist_processing_common.parsers.unique_bud import TaskUniqueBud
|
|
47
54
|
from dkist_processing_common.parsers.unique_bud import UniqueBud
|
|
48
55
|
from dkist_processing_common.tasks.base import WorkflowTaskBase
|
|
49
56
|
|
|
@@ -59,9 +66,247 @@ logger = logging.getLogger(__name__)
|
|
|
59
66
|
S = TypeVar("S", bound=Stem)
|
|
60
67
|
|
|
61
68
|
|
|
69
|
+
def dataset_extra_bud_factory() -> list[S]:
|
|
70
|
+
"""Provide constant buds for use in dataset extras."""
|
|
71
|
+
return [
|
|
72
|
+
UniqueBud(constant_name=BudName.camera_id, metadata_key=MetadataKey.camera_id),
|
|
73
|
+
UniqueBud(constant_name=BudName.camera_name, metadata_key=MetadataKey.camera_name),
|
|
74
|
+
UniqueBud(
|
|
75
|
+
constant_name=BudName.camera_bit_depth, metadata_key=MetadataKey.camera_bit_depth
|
|
76
|
+
),
|
|
77
|
+
UniqueBud(
|
|
78
|
+
constant_name=BudName.hardware_binning_x, metadata_key=MetadataKey.hardware_binning_x
|
|
79
|
+
),
|
|
80
|
+
UniqueBud(
|
|
81
|
+
constant_name=BudName.hardware_binning_y, metadata_key=MetadataKey.hardware_binning_x
|
|
82
|
+
),
|
|
83
|
+
UniqueBud(
|
|
84
|
+
constant_name=BudName.software_binning_x, metadata_key=MetadataKey.software_binning_x
|
|
85
|
+
),
|
|
86
|
+
UniqueBud(
|
|
87
|
+
constant_name=BudName.software_binning_y, metadata_key=MetadataKey.software_binning_y
|
|
88
|
+
),
|
|
89
|
+
UniqueBud(
|
|
90
|
+
constant_name=BudName.hls_version,
|
|
91
|
+
metadata_key=MetadataKey.hls_version,
|
|
92
|
+
),
|
|
93
|
+
TaskContributingObservingProgramExecutionIdsBud(
|
|
94
|
+
constant_name=BudName.dark_observing_program_execution_ids,
|
|
95
|
+
ip_task_types=TaskName.dark,
|
|
96
|
+
),
|
|
97
|
+
TaskContributingObservingProgramExecutionIdsBud(
|
|
98
|
+
constant_name=BudName.solar_gain_observing_program_execution_ids,
|
|
99
|
+
ip_task_types=TaskName.solar_gain,
|
|
100
|
+
task_type_parsing_function=parse_header_ip_task_with_gains,
|
|
101
|
+
),
|
|
102
|
+
TaskContributingObservingProgramExecutionIdsBud(
|
|
103
|
+
constant_name=BudName.polcal_observing_program_execution_ids,
|
|
104
|
+
ip_task_types=TaskName.polcal,
|
|
105
|
+
),
|
|
106
|
+
TaskUniqueBud(
|
|
107
|
+
constant_name=BudName.solar_gain_num_raw_frames_per_fpa,
|
|
108
|
+
metadata_key=MetadataKey.num_raw_frames_per_fpa,
|
|
109
|
+
ip_task_types=TaskName.solar_gain,
|
|
110
|
+
task_type_parsing_function=parse_header_ip_task_with_gains,
|
|
111
|
+
),
|
|
112
|
+
TaskUniqueBud(
|
|
113
|
+
constant_name=BudName.polcal_num_raw_frames_per_fpa,
|
|
114
|
+
metadata_key=MetadataKey.num_raw_frames_per_fpa,
|
|
115
|
+
ip_task_types=TaskName.polcal,
|
|
116
|
+
),
|
|
117
|
+
TaskUniqueBud(
|
|
118
|
+
constant_name=BudName.solar_gain_telescope_tracking_mode,
|
|
119
|
+
metadata_key=MetadataKey.telescope_tracking_mode,
|
|
120
|
+
ip_task_types=TaskName.solar_gain,
|
|
121
|
+
task_type_parsing_function=parse_header_ip_task_with_gains,
|
|
122
|
+
),
|
|
123
|
+
TaskUniqueBud(
|
|
124
|
+
constant_name=BudName.polcal_telescope_tracking_mode,
|
|
125
|
+
metadata_key=MetadataKey.telescope_tracking_mode,
|
|
126
|
+
ip_task_types=TaskName.polcal,
|
|
127
|
+
),
|
|
128
|
+
TaskUniqueBud(
|
|
129
|
+
constant_name=BudName.solar_gain_coude_table_tracking_mode,
|
|
130
|
+
metadata_key=MetadataKey.coude_table_tracking_mode,
|
|
131
|
+
ip_task_types=TaskName.solar_gain,
|
|
132
|
+
task_type_parsing_function=parse_header_ip_task_with_gains,
|
|
133
|
+
),
|
|
134
|
+
TaskUniqueBud(
|
|
135
|
+
constant_name=BudName.polcal_coude_table_tracking_mode,
|
|
136
|
+
metadata_key=MetadataKey.coude_table_tracking_mode,
|
|
137
|
+
ip_task_types=TaskName.polcal,
|
|
138
|
+
),
|
|
139
|
+
TaskUniqueBud(
|
|
140
|
+
constant_name=BudName.solar_gain_telescope_scanning_mode,
|
|
141
|
+
metadata_key=MetadataKey.telescope_scanning_mode,
|
|
142
|
+
ip_task_types=TaskName.solar_gain,
|
|
143
|
+
task_type_parsing_function=parse_header_ip_task_with_gains,
|
|
144
|
+
),
|
|
145
|
+
TaskUniqueBud(
|
|
146
|
+
constant_name=BudName.polcal_telescope_scanning_mode,
|
|
147
|
+
metadata_key=MetadataKey.telescope_scanning_mode,
|
|
148
|
+
ip_task_types=TaskName.polcal,
|
|
149
|
+
),
|
|
150
|
+
TaskUniqueBud(
|
|
151
|
+
constant_name=BudName.dark_gos_level3_status,
|
|
152
|
+
metadata_key=MetadataKey.gos_level3_status,
|
|
153
|
+
ip_task_types=TaskName.dark,
|
|
154
|
+
),
|
|
155
|
+
TaskUniqueBud(
|
|
156
|
+
constant_name=BudName.solar_gain_gos_level3_status,
|
|
157
|
+
metadata_key=MetadataKey.gos_level3_status,
|
|
158
|
+
ip_task_types=TaskName.solar_gain,
|
|
159
|
+
task_type_parsing_function=parse_header_ip_task_with_gains,
|
|
160
|
+
),
|
|
161
|
+
TaskUniqueBud(
|
|
162
|
+
constant_name=BudName.dark_gos_level3_lamp_status,
|
|
163
|
+
metadata_key=MetadataKey.gos_level3_lamp_status,
|
|
164
|
+
ip_task_types=TaskName.dark,
|
|
165
|
+
),
|
|
166
|
+
TaskUniqueBud(
|
|
167
|
+
constant_name=BudName.solar_gain_gos_level3_lamp_status,
|
|
168
|
+
metadata_key=MetadataKey.gos_level3_lamp_status,
|
|
169
|
+
ip_task_types=TaskName.solar_gain,
|
|
170
|
+
task_type_parsing_function=parse_header_ip_task_with_gains,
|
|
171
|
+
),
|
|
172
|
+
TaskUniqueBud(
|
|
173
|
+
constant_name=BudName.dark_gos_polarizer_status,
|
|
174
|
+
metadata_key=MetadataKey.gos_polarizer_status,
|
|
175
|
+
ip_task_types=TaskName.dark,
|
|
176
|
+
),
|
|
177
|
+
TaskUniqueBud(
|
|
178
|
+
constant_name=BudName.solar_gain_gos_polarizer_status,
|
|
179
|
+
metadata_key=MetadataKey.gos_polarizer_status,
|
|
180
|
+
ip_task_types=TaskName.solar_gain,
|
|
181
|
+
task_type_parsing_function=parse_header_ip_task_with_gains,
|
|
182
|
+
),
|
|
183
|
+
TaskUniqueBud(
|
|
184
|
+
constant_name=BudName.dark_gos_polarizer_angle,
|
|
185
|
+
metadata_key=MetadataKey.gos_polarizer_angle,
|
|
186
|
+
ip_task_types=TaskName.dark,
|
|
187
|
+
),
|
|
188
|
+
TaskUniqueBud(
|
|
189
|
+
constant_name=BudName.solar_gain_gos_polarizer_angle,
|
|
190
|
+
metadata_key=MetadataKey.gos_polarizer_angle,
|
|
191
|
+
ip_task_types=TaskName.solar_gain,
|
|
192
|
+
task_type_parsing_function=parse_header_ip_task_with_gains,
|
|
193
|
+
),
|
|
194
|
+
TaskUniqueBud(
|
|
195
|
+
constant_name=BudName.dark_gos_retarder_status,
|
|
196
|
+
metadata_key=MetadataKey.gos_retarder_status,
|
|
197
|
+
ip_task_types=TaskName.dark,
|
|
198
|
+
),
|
|
199
|
+
TaskUniqueBud(
|
|
200
|
+
constant_name=BudName.solar_gain_gos_retarder_status,
|
|
201
|
+
metadata_key=MetadataKey.gos_retarder_status,
|
|
202
|
+
ip_task_types=TaskName.solar_gain,
|
|
203
|
+
task_type_parsing_function=parse_header_ip_task_with_gains,
|
|
204
|
+
),
|
|
205
|
+
TaskUniqueBud(
|
|
206
|
+
constant_name=BudName.dark_gos_retarder_angle,
|
|
207
|
+
metadata_key=MetadataKey.gos_retarder_angle,
|
|
208
|
+
ip_task_types=TaskName.dark,
|
|
209
|
+
),
|
|
210
|
+
TaskUniqueBud(
|
|
211
|
+
constant_name=BudName.solar_gain_gos_retarder_angle,
|
|
212
|
+
metadata_key=MetadataKey.gos_retarder_angle,
|
|
213
|
+
ip_task_types=TaskName.solar_gain,
|
|
214
|
+
task_type_parsing_function=parse_header_ip_task_with_gains,
|
|
215
|
+
),
|
|
216
|
+
TaskUniqueBud(
|
|
217
|
+
constant_name=BudName.dark_gos_level0_status,
|
|
218
|
+
metadata_key=MetadataKey.gos_level0_status,
|
|
219
|
+
ip_task_types=TaskName.dark,
|
|
220
|
+
),
|
|
221
|
+
TaskUniqueBud(
|
|
222
|
+
constant_name=BudName.solar_gain_gos_level0_status,
|
|
223
|
+
metadata_key=MetadataKey.gos_level0_status,
|
|
224
|
+
ip_task_types=TaskName.solar_gain,
|
|
225
|
+
task_type_parsing_function=parse_header_ip_task_with_gains,
|
|
226
|
+
),
|
|
227
|
+
TaskAverageBud(
|
|
228
|
+
constant_name=BudName.dark_average_light_level,
|
|
229
|
+
metadata_key=MetadataKey.light_level,
|
|
230
|
+
ip_task_types=TaskName.dark,
|
|
231
|
+
),
|
|
232
|
+
TaskAverageBud(
|
|
233
|
+
constant_name=BudName.solar_gain_average_light_level,
|
|
234
|
+
metadata_key=MetadataKey.light_level,
|
|
235
|
+
ip_task_types=TaskName.solar_gain,
|
|
236
|
+
task_type_parsing_function=parse_header_ip_task_with_gains,
|
|
237
|
+
),
|
|
238
|
+
TaskAverageBud(
|
|
239
|
+
constant_name=BudName.polcal_average_light_level,
|
|
240
|
+
metadata_key=MetadataKey.light_level,
|
|
241
|
+
ip_task_types=TaskName.polcal,
|
|
242
|
+
),
|
|
243
|
+
TaskAverageBud(
|
|
244
|
+
constant_name=BudName.dark_average_telescope_elevation,
|
|
245
|
+
metadata_key=MetadataKey.elevation,
|
|
246
|
+
ip_task_types=TaskName.dark,
|
|
247
|
+
),
|
|
248
|
+
TaskAverageBud(
|
|
249
|
+
constant_name=BudName.solar_gain_average_telescope_elevation,
|
|
250
|
+
metadata_key=MetadataKey.elevation,
|
|
251
|
+
ip_task_types=TaskName.solar_gain,
|
|
252
|
+
task_type_parsing_function=parse_header_ip_task_with_gains,
|
|
253
|
+
),
|
|
254
|
+
TaskAverageBud(
|
|
255
|
+
constant_name=BudName.polcal_average_telescope_elevation,
|
|
256
|
+
metadata_key=MetadataKey.elevation,
|
|
257
|
+
ip_task_types=TaskName.polcal,
|
|
258
|
+
),
|
|
259
|
+
TaskAverageBud(
|
|
260
|
+
constant_name=BudName.dark_average_coude_table_angle,
|
|
261
|
+
metadata_key=MetadataKey.table_angle,
|
|
262
|
+
ip_task_types=TaskName.dark,
|
|
263
|
+
),
|
|
264
|
+
TaskAverageBud(
|
|
265
|
+
constant_name=BudName.solar_gain_average_coude_table_angle,
|
|
266
|
+
metadata_key=MetadataKey.table_angle,
|
|
267
|
+
ip_task_types=TaskName.solar_gain,
|
|
268
|
+
task_type_parsing_function=parse_header_ip_task_with_gains,
|
|
269
|
+
),
|
|
270
|
+
TaskAverageBud(
|
|
271
|
+
constant_name=BudName.polcal_average_coude_table_angle,
|
|
272
|
+
metadata_key=MetadataKey.table_angle,
|
|
273
|
+
ip_task_types=TaskName.polcal,
|
|
274
|
+
),
|
|
275
|
+
TaskAverageBud(
|
|
276
|
+
constant_name=BudName.dark_average_telescope_azimuth,
|
|
277
|
+
metadata_key=MetadataKey.azimuth,
|
|
278
|
+
ip_task_types=TaskName.dark,
|
|
279
|
+
),
|
|
280
|
+
TaskAverageBud(
|
|
281
|
+
constant_name=BudName.solar_gain_average_telescope_azimuth,
|
|
282
|
+
metadata_key=MetadataKey.azimuth,
|
|
283
|
+
ip_task_types=TaskName.solar_gain,
|
|
284
|
+
task_type_parsing_function=parse_header_ip_task_with_gains,
|
|
285
|
+
),
|
|
286
|
+
TaskAverageBud(
|
|
287
|
+
constant_name=BudName.polcal_average_telescope_azimuth,
|
|
288
|
+
metadata_key=MetadataKey.azimuth,
|
|
289
|
+
ip_task_types=TaskName.polcal,
|
|
290
|
+
),
|
|
291
|
+
TaskDateBeginBud(
|
|
292
|
+
constant_name=BudName.dark_date_begin,
|
|
293
|
+
ip_task_types=TaskName.dark,
|
|
294
|
+
),
|
|
295
|
+
TaskDateBeginBud(
|
|
296
|
+
constant_name=BudName.solar_gain_date_begin,
|
|
297
|
+
ip_task_types=TaskName.solar_gain,
|
|
298
|
+
task_type_parsing_function=parse_header_ip_task_with_gains,
|
|
299
|
+
),
|
|
300
|
+
TaskDateBeginBud(
|
|
301
|
+
constant_name=BudName.polcal_date_begin,
|
|
302
|
+
ip_task_types=TaskName.polcal,
|
|
303
|
+
),
|
|
304
|
+
]
|
|
305
|
+
|
|
306
|
+
|
|
62
307
|
def default_constant_bud_factory() -> list[S]:
|
|
63
308
|
"""Provide default constant buds for use in common parsing tasks."""
|
|
64
|
-
return [
|
|
309
|
+
return dataset_extra_bud_factory() + [
|
|
65
310
|
UniqueBud(constant_name=BudName.instrument, metadata_key=MetadataKey.instrument),
|
|
66
311
|
ProposalIdBud(),
|
|
67
312
|
ContributingProposalIdsBud(),
|
|
@@ -4,7 +4,6 @@ import numpy as np
|
|
|
4
4
|
import pytest
|
|
5
5
|
from astropy.io import fits
|
|
6
6
|
|
|
7
|
-
from dkist_processing_common.models.fits_access import NOT_FOUND_MESSAGE
|
|
8
7
|
from dkist_processing_common.models.fits_access import FitsAccessBase
|
|
9
8
|
from dkist_processing_common.models.fits_access import MetadataKey
|
|
10
9
|
from dkist_processing_common.parsers.l0_fits_access import L0FitsAccess
|
|
@@ -99,30 +98,16 @@ def hdu_with_no_data(complete_common_header):
|
|
|
99
98
|
@pytest.fixture()
|
|
100
99
|
def hdu_with_incomplete_common_header(complete_common_header):
|
|
101
100
|
"""
|
|
102
|
-
An HDU with data and a header missing
|
|
101
|
+
An HDU with data and a header missing two of the expected common by-frame keywords
|
|
103
102
|
"""
|
|
104
103
|
incomplete_header = complete_common_header
|
|
105
|
-
incomplete_header.pop(
|
|
106
|
-
incomplete_header.pop(
|
|
104
|
+
incomplete_header.pop(MetadataKey.elevation)
|
|
105
|
+
incomplete_header.pop(MetadataKey.azimuth)
|
|
107
106
|
data = np.arange(9).reshape(3, 3)
|
|
108
107
|
hdu = fits.PrimaryHDU(data, header=incomplete_header)
|
|
109
108
|
return hdu
|
|
110
109
|
|
|
111
110
|
|
|
112
|
-
class MetadataKeyWithOptionalKeys(StrEnum):
|
|
113
|
-
optional1 = "ELEV_ANG"
|
|
114
|
-
optional2 = "TAZIMUTH"
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
class FitsAccessWithOptionalKeys(FitsAccessBase):
|
|
118
|
-
def __init__(self, hdu, name):
|
|
119
|
-
super().__init__(hdu, name)
|
|
120
|
-
self._set_metadata_key_value(MetadataKeyWithOptionalKeys.optional1, optional=True)
|
|
121
|
-
self._set_metadata_key_value(
|
|
122
|
-
MetadataKeyWithOptionalKeys.optional2, optional=True, default="SO_RAD"
|
|
123
|
-
)
|
|
124
|
-
|
|
125
|
-
|
|
126
111
|
@pytest.fixture()
|
|
127
112
|
def fits_file_path(tmp_path, complete_common_header):
|
|
128
113
|
file_path = tmp_path / "foo.fits"
|
|
@@ -155,35 +140,36 @@ class MetadataKeyWithNaxisKeys(StrEnum):
|
|
|
155
140
|
class FitsAccessWithNaxisKeys(FitsAccessBase):
|
|
156
141
|
def __init__(self, hdu, name):
|
|
157
142
|
super().__init__(hdu, name)
|
|
158
|
-
self.
|
|
159
|
-
self.
|
|
160
|
-
self.
|
|
143
|
+
self.naxis = self.header[MetadataKeyWithNaxisKeys.naxis]
|
|
144
|
+
self.naxis1 = self.header[MetadataKeyWithNaxisKeys.naxis1]
|
|
145
|
+
self.naxis2 = self.header[MetadataKeyWithNaxisKeys.naxis2]
|
|
161
146
|
|
|
162
147
|
|
|
163
148
|
def test_metadata_keys_in_access_bases(hdu_with_no_data):
|
|
164
149
|
"""
|
|
165
150
|
Given: a set of metadata key names in the MetadataKey sting enumeration
|
|
166
151
|
When: the FITS access classes define a set of attributes/properties
|
|
167
|
-
Then: the sets are the same
|
|
152
|
+
Then: the sets are the same and the values of the attributes/properties are correct
|
|
168
153
|
"""
|
|
169
154
|
all_metadata_key_names = {mk.name for mk in MetadataKey}
|
|
170
155
|
hdu = hdu_with_no_data
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
156
|
+
fits_obj = L0FitsAccess(hdu=hdu)
|
|
157
|
+
fits_access_defined_attributes = {
|
|
158
|
+
k for k, v in fits_obj.__dict__.items() if k not in ["_hdu", "name", "auto_squeeze"]
|
|
159
|
+
}
|
|
160
|
+
l0_access_properties = {k for k, v in L0FitsAccess.__dict__.items() if isinstance(v, property)}
|
|
161
|
+
l1_access_properties = {k for k, v in L1FitsAccess.__dict__.items() if isinstance(v, property)}
|
|
162
|
+
fits_access_properties = l0_access_properties | l1_access_properties
|
|
163
|
+
assert fits_access_defined_attributes | fits_access_properties == all_metadata_key_names
|
|
164
|
+
for key in fits_access_defined_attributes:
|
|
165
|
+
assert getattr(fits_obj, key) == fits_obj.header[MetadataKey[key]]
|
|
180
166
|
|
|
181
167
|
|
|
182
168
|
def test_from_single_hdu(hdu_with_complete_common_header):
|
|
183
169
|
"""
|
|
184
170
|
Given: an HDU with expected, common by-frame keywords
|
|
185
171
|
When: loading the HDU with the L0FitsAccess class
|
|
186
|
-
Then:
|
|
172
|
+
Then: values for common keywords are exposed as properties on the fits_obj class
|
|
187
173
|
"""
|
|
188
174
|
fits_obj = L0FitsAccess(hdu_with_complete_common_header)
|
|
189
175
|
assert fits_obj.elevation == 6.28
|
|
@@ -198,7 +184,7 @@ def test_l1_only_fits_access(hdu_with_complete_l1_only_header):
|
|
|
198
184
|
"""
|
|
199
185
|
Given: an HDU with 214 L1-only headers
|
|
200
186
|
When: loading the HDU with the L1FitsAccess class
|
|
201
|
-
Then: no errors are raised and
|
|
187
|
+
Then: no errors are raised and values are exposed
|
|
202
188
|
"""
|
|
203
189
|
fits_obj = L1FitsAccess(hdu_with_complete_l1_only_header)
|
|
204
190
|
assert fits_obj.elevation == 6.28
|
|
@@ -255,17 +241,6 @@ def test_no_header_value(hdu_with_incomplete_common_header):
|
|
|
255
241
|
_ = L0FitsAccess(hdu_with_incomplete_common_header)
|
|
256
242
|
|
|
257
243
|
|
|
258
|
-
def test_default_header_values(hdu_with_incomplete_common_header):
|
|
259
|
-
"""
|
|
260
|
-
Given: an HDU with a header with missing common by-frame keywords
|
|
261
|
-
When: processing the HDU with a FITS access class that sets these keywords as optional
|
|
262
|
-
Then: the correct default values are set
|
|
263
|
-
"""
|
|
264
|
-
fits_obj = FitsAccessWithOptionalKeys(hdu_with_incomplete_common_header, name="foo")
|
|
265
|
-
assert fits_obj.optional1 == MetadataKeyWithOptionalKeys.optional1 + NOT_FOUND_MESSAGE
|
|
266
|
-
assert fits_obj.optional2 == "SO_RAD"
|
|
267
|
-
|
|
268
|
-
|
|
269
244
|
def test_as_subclass(hdu_with_complete_common_header):
|
|
270
245
|
"""
|
|
271
246
|
Given: an instrument-specific fits_obj class that subclasses L0FitsAccess
|
|
@@ -97,9 +97,9 @@ class ViSPMetadataKey(StrEnum):
|
|
|
97
97
|
class ViSPFitsAccess(FitsAccessBase):
|
|
98
98
|
def __init__(self, hdu, name, auto_squeeze=False):
|
|
99
99
|
super().__init__(hdu, name, auto_squeeze=auto_squeeze)
|
|
100
|
-
self.
|
|
101
|
-
self.
|
|
102
|
-
self.
|
|
100
|
+
self.num_mod: int = self.header[ViSPMetadataKey.num_mod]
|
|
101
|
+
self.modstate: int = self.header[ViSPMetadataKey.modstate]
|
|
102
|
+
self.ip_task_type: str = self.header[ViSPMetadataKey.ip_task_type]
|
|
103
103
|
self.name = name
|
|
104
104
|
|
|
105
105
|
|
|
@@ -260,18 +260,58 @@ def test_subclass_flowers(visp_parse_inputs_task, max_cs_step_time_sec):
|
|
|
260
260
|
tag_pot, constant_pot = visp_parse_inputs_task.make_flower_pots()
|
|
261
261
|
|
|
262
262
|
assert len(tag_pot.stems) == 1
|
|
263
|
-
assert len(constant_pot.stems) ==
|
|
263
|
+
assert len(constant_pot.stems) == 60
|
|
264
264
|
all_flower_names = [StemName.modstate]
|
|
265
265
|
assert sorted([f.stem_name for f in tag_pot.stems]) == sorted(all_flower_names)
|
|
266
266
|
all_bud_names = [b.stem_name for b in default_constant_bud_factory()] + [BudName.num_modstates]
|
|
267
267
|
assert sorted([f.stem_name for f in constant_pot.stems]) == sorted(all_bud_names)
|
|
268
268
|
|
|
269
269
|
|
|
270
|
+
def test_dataset_extra_bud_factory(visp_parse_inputs_task, max_cs_step_time_sec):
|
|
271
|
+
"""
|
|
272
|
+
Given: ParseInputData child class with custom stems
|
|
273
|
+
When: Making the constant pot
|
|
274
|
+
Then: The multi-task dataset extra buds are created
|
|
275
|
+
"""
|
|
276
|
+
_, constant_pot = visp_parse_inputs_task.make_flower_pots()
|
|
277
|
+
stem_names = [f.stem_name.value for f in constant_pot.stems]
|
|
278
|
+
bud_name_base = [
|
|
279
|
+
"DATE_BEGIN",
|
|
280
|
+
"OBSERVING_PROGRAM_EXECUTION_IDS",
|
|
281
|
+
"NUM_RAW_FRAMES_PER_FPA",
|
|
282
|
+
"TELESCOPE_TRACKING_MODE",
|
|
283
|
+
"COUDE_TABLE_TRACKING_MODE",
|
|
284
|
+
"TELESCOPE_SCANNING_MODE",
|
|
285
|
+
"AVERAGE_LIGHT_LEVEL",
|
|
286
|
+
"AVERAGE_TELESCOPE_ELEVATION",
|
|
287
|
+
"AVERAGE_COUDE_TABLE_ANGLE",
|
|
288
|
+
"AVERAGE_TELESCOPE_AZIMUTH",
|
|
289
|
+
"GOS_LEVEL3_STATUS",
|
|
290
|
+
"GOS_LEVEL3_LAMP_STATUS",
|
|
291
|
+
"GOS_POLARIZER_STATUS",
|
|
292
|
+
"GOS_POLARIZER_ANGLE",
|
|
293
|
+
"GOS_RETARDER_STATUS",
|
|
294
|
+
"GOS_RETARDER_ANGLE",
|
|
295
|
+
"GOS_LEVEL0_STATUS",
|
|
296
|
+
]
|
|
297
|
+
for base in bud_name_base:
|
|
298
|
+
assert "SOLAR_GAIN_" + base in stem_names
|
|
299
|
+
if base not in [
|
|
300
|
+
"NUM_RAW_FRAMES_PER_FPA",
|
|
301
|
+
"TELESCOPE_TRACKING_MODE",
|
|
302
|
+
"COUDE_TABLE_TRACKING_MODE",
|
|
303
|
+
"TELESCOPE_SCANNING_MODE",
|
|
304
|
+
]:
|
|
305
|
+
assert "DARK_" + base in stem_names
|
|
306
|
+
if "GOS" not in base:
|
|
307
|
+
assert "POLCAL_" + base in stem_names
|
|
308
|
+
|
|
309
|
+
|
|
270
310
|
def test_constants_correct(parse_inputs_task):
|
|
271
311
|
"""
|
|
272
312
|
Given: ParseInputData task with a populated constant FlowerPot
|
|
273
313
|
When: Updating pipeline constants
|
|
274
|
-
Then:
|
|
314
|
+
Then: A pipeline constant is correctly populated
|
|
275
315
|
"""
|
|
276
316
|
_, constant_pot = parse_inputs_task.make_flower_pots()
|
|
277
317
|
parse_inputs_task.update_constants(constant_pot)
|