dkist-processing-common 11.7.0rc2__py3-none-any.whl → 11.7.1rc1__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.
Files changed (29) hide show
  1. changelog/271.misc.rst +1 -0
  2. dkist_processing_common/models/constants.py +21 -357
  3. dkist_processing_common/models/fits_access.py +25 -16
  4. dkist_processing_common/parsers/experiment_id_bud.py +4 -8
  5. dkist_processing_common/parsers/id_bud.py +19 -35
  6. dkist_processing_common/parsers/l0_fits_access.py +3 -3
  7. dkist_processing_common/parsers/l1_fits_access.py +21 -47
  8. dkist_processing_common/parsers/near_bud.py +4 -4
  9. dkist_processing_common/parsers/proposal_id_bud.py +5 -11
  10. dkist_processing_common/parsers/single_value_single_key_flower.py +1 -0
  11. dkist_processing_common/parsers/time.py +27 -141
  12. dkist_processing_common/tasks/mixin/quality/_metrics.py +4 -6
  13. dkist_processing_common/tasks/parse_l0_input_data.py +1 -249
  14. dkist_processing_common/tests/test_fits_access.py +44 -19
  15. dkist_processing_common/tests/test_parse_l0_input_data.py +5 -39
  16. dkist_processing_common/tests/test_quality_mixin.py +11 -3
  17. dkist_processing_common/tests/test_stems.py +10 -127
  18. dkist_processing_common/tests/test_task_parsing.py +6 -6
  19. {dkist_processing_common-11.7.0rc2.dist-info → dkist_processing_common-11.7.1rc1.dist-info}/METADATA +2 -2
  20. {dkist_processing_common-11.7.0rc2.dist-info → dkist_processing_common-11.7.1rc1.dist-info}/RECORD +22 -28
  21. changelog/267.feature.1.rst +0 -1
  22. changelog/267.feature.2.rst +0 -1
  23. changelog/267.feature.rst +0 -1
  24. changelog/267.misc.rst +0 -1
  25. changelog/267.removal.1.rst +0 -2
  26. changelog/267.removal.rst +0 -1
  27. dkist_processing_common/parsers/average_bud.py +0 -48
  28. {dkist_processing_common-11.7.0rc2.dist-info → dkist_processing_common-11.7.1rc1.dist-info}/WHEEL +0 -0
  29. {dkist_processing_common-11.7.0rc2.dist-info → dkist_processing_common-11.7.1rc1.dist-info}/top_level.txt +0 -0
@@ -34,20 +34,16 @@ 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
38
37
  from dkist_processing_common.parsers.experiment_id_bud import ContributingExperimentIdsBud
39
38
  from dkist_processing_common.parsers.experiment_id_bud import ExperimentIdBud
40
- from dkist_processing_common.parsers.id_bud import TaskContributingIdsBud
41
39
  from dkist_processing_common.parsers.proposal_id_bud import ContributingProposalIdsBud
42
40
  from dkist_processing_common.parsers.proposal_id_bud import ProposalIdBud
43
41
  from dkist_processing_common.parsers.time import AverageCadenceBud
44
42
  from dkist_processing_common.parsers.time import MaximumCadenceBud
45
43
  from dkist_processing_common.parsers.time import MinimumCadenceBud
46
- from dkist_processing_common.parsers.time import TaskDateBeginBud
47
44
  from dkist_processing_common.parsers.time import TaskExposureTimesBud
48
45
  from dkist_processing_common.parsers.time import TaskReadoutExpTimesBud
49
46
  from dkist_processing_common.parsers.time import VarianceCadenceBud
50
- from dkist_processing_common.parsers.unique_bud import TaskUniqueBud
51
47
  from dkist_processing_common.parsers.unique_bud import UniqueBud
52
48
  from dkist_processing_common.tasks.base import WorkflowTaskBase
53
49
 
@@ -63,253 +59,9 @@ logger = logging.getLogger(__name__)
63
59
  S = TypeVar("S", bound=Stem)
64
60
 
65
61
 
66
- def dataset_extra_bud_factory() -> list[S]:
67
- """Provide constant buds for use in dataset extras."""
68
- return [
69
- UniqueBud(constant_name=BudName.camera_id, metadata_key=MetadataKey.camera_id),
70
- UniqueBud(constant_name=BudName.camera_name, metadata_key=MetadataKey.camera_name),
71
- UniqueBud(
72
- constant_name=BudName.camera_bit_depth, metadata_key=MetadataKey.camera_bit_depth
73
- ),
74
- UniqueBud(
75
- constant_name=BudName.hardware_binning_x, metadata_key=MetadataKey.hardware_binning_x
76
- ),
77
- UniqueBud(
78
- constant_name=BudName.hardware_binning_y, metadata_key=MetadataKey.hardware_binning_x
79
- ),
80
- UniqueBud(
81
- constant_name=BudName.software_binning_x, metadata_key=MetadataKey.software_binning_x
82
- ),
83
- UniqueBud(
84
- constant_name=BudName.software_binning_y, metadata_key=MetadataKey.software_binning_y
85
- ),
86
- UniqueBud(
87
- constant_name=BudName.hls_version,
88
- metadata_key=MetadataKey.hls_version,
89
- ),
90
- TaskContributingIdsBud(
91
- constant_name=BudName.dark_observing_program_execution_id,
92
- metadata_key=MetadataKey.observing_program_execution_id,
93
- ip_task_types=TaskName.dark,
94
- ),
95
- TaskContributingIdsBud(
96
- constant_name=BudName.solar_gain_observing_program_execution_id,
97
- metadata_key=MetadataKey.observing_program_execution_id,
98
- ip_task_types=TaskName.solar_gain,
99
- ),
100
- TaskContributingIdsBud(
101
- constant_name=BudName.polcal_observing_program_execution_id,
102
- metadata_key=MetadataKey.observing_program_execution_id,
103
- ip_task_types=TaskName.polcal,
104
- ),
105
- TaskUniqueBud(
106
- constant_name=BudName.dark_num_raw_frames_per_fpa,
107
- metadata_key=MetadataKey.num_raw_frames_per_fpa,
108
- ip_task_types=TaskName.dark,
109
- ),
110
- TaskUniqueBud(
111
- constant_name=BudName.solar_gain_num_raw_frames_per_fpa,
112
- metadata_key=MetadataKey.num_raw_frames_per_fpa,
113
- ip_task_types=TaskName.solar_gain,
114
- ),
115
- TaskUniqueBud(
116
- constant_name=BudName.polcal_num_raw_frames_per_fpa,
117
- metadata_key=MetadataKey.num_raw_frames_per_fpa,
118
- ip_task_types=TaskName.polcal,
119
- ),
120
- TaskUniqueBud(
121
- constant_name=BudName.dark_telescope_tracking_mode,
122
- metadata_key=MetadataKey.telescope_tracking_mode,
123
- ip_task_types=TaskName.dark,
124
- ),
125
- TaskUniqueBud(
126
- constant_name=BudName.solar_gain_telescope_tracking_mode,
127
- metadata_key=MetadataKey.telescope_tracking_mode,
128
- ip_task_types=TaskName.solar_gain,
129
- ),
130
- TaskUniqueBud(
131
- constant_name=BudName.polcal_telescope_tracking_mode,
132
- metadata_key=MetadataKey.telescope_tracking_mode,
133
- ip_task_types=TaskName.polcal,
134
- ),
135
- TaskUniqueBud(
136
- constant_name=BudName.dark_coude_table_tracking_mode,
137
- metadata_key=MetadataKey.coude_table_tracking_mode,
138
- ip_task_types=TaskName.dark,
139
- ),
140
- TaskUniqueBud(
141
- constant_name=BudName.solar_gain_coude_table_tracking_mode,
142
- metadata_key=MetadataKey.coude_table_tracking_mode,
143
- ip_task_types=TaskName.solar_gain,
144
- ),
145
- TaskUniqueBud(
146
- constant_name=BudName.polcal_coude_table_tracking_mode,
147
- metadata_key=MetadataKey.coude_table_tracking_mode,
148
- ip_task_types=TaskName.polcal,
149
- ),
150
- TaskUniqueBud(
151
- constant_name=BudName.dark_telescope_scanning_mode,
152
- metadata_key=MetadataKey.telescope_scanning_mode,
153
- ip_task_types=TaskName.dark,
154
- ),
155
- TaskUniqueBud(
156
- constant_name=BudName.solar_gain_telescope_scanning_mode,
157
- metadata_key=MetadataKey.telescope_scanning_mode,
158
- ip_task_types=TaskName.solar_gain,
159
- ),
160
- TaskUniqueBud(
161
- constant_name=BudName.polcal_telescope_scanning_mode,
162
- metadata_key=MetadataKey.telescope_scanning_mode,
163
- ip_task_types=TaskName.polcal,
164
- ),
165
- TaskUniqueBud(
166
- constant_name=BudName.dark_gos_level3_status,
167
- metadata_key=MetadataKey.gos_level3_status,
168
- ip_task_types=TaskName.dark,
169
- ),
170
- TaskUniqueBud(
171
- constant_name=BudName.solar_gain_gos_level3_status,
172
- metadata_key=MetadataKey.gos_level3_status,
173
- ip_task_types=TaskName.solar_gain,
174
- ),
175
- TaskUniqueBud(
176
- constant_name=BudName.dark_gos_level3_lamp_status,
177
- metadata_key=MetadataKey.gos_level3_lamp_status,
178
- ip_task_types=TaskName.dark,
179
- ),
180
- TaskUniqueBud(
181
- constant_name=BudName.solar_gain_gos_level3_lamp_status,
182
- metadata_key=MetadataKey.gos_level3_lamp_status,
183
- ip_task_types=TaskName.solar_gain,
184
- ),
185
- TaskUniqueBud(
186
- constant_name=BudName.dark_gos_polarizer_status,
187
- metadata_key=MetadataKey.gos_polarizer_status,
188
- ip_task_types=TaskName.dark,
189
- ),
190
- TaskUniqueBud(
191
- constant_name=BudName.solar_gain_gos_polarizer_status,
192
- metadata_key=MetadataKey.gos_polarizer_status,
193
- ip_task_types=TaskName.solar_gain,
194
- ),
195
- TaskUniqueBud(
196
- constant_name=BudName.dark_gos_polarizer_angle,
197
- metadata_key=MetadataKey.gos_polarizer_angle,
198
- ip_task_types=TaskName.dark,
199
- ),
200
- TaskUniqueBud(
201
- constant_name=BudName.solar_gain_gos_polarizer_angle,
202
- metadata_key=MetadataKey.gos_polarizer_angle,
203
- ip_task_types=TaskName.solar_gain,
204
- ),
205
- TaskUniqueBud(
206
- constant_name=BudName.dark_gos_retarder_status,
207
- metadata_key=MetadataKey.gos_retarder_status,
208
- ip_task_types=TaskName.dark,
209
- ),
210
- TaskUniqueBud(
211
- constant_name=BudName.solar_gain_gos_retarder_status,
212
- metadata_key=MetadataKey.gos_retarder_status,
213
- ip_task_types=TaskName.solar_gain,
214
- ),
215
- TaskUniqueBud(
216
- constant_name=BudName.dark_gos_retarder_angle,
217
- metadata_key=MetadataKey.gos_retarder_angle,
218
- ip_task_types=TaskName.dark,
219
- ),
220
- TaskUniqueBud(
221
- constant_name=BudName.solar_gain_gos_retarder_angle,
222
- metadata_key=MetadataKey.gos_retarder_angle,
223
- ip_task_types=TaskName.solar_gain,
224
- ),
225
- TaskUniqueBud(
226
- constant_name=BudName.dark_gos_level0_status,
227
- metadata_key=MetadataKey.gos_level0_status,
228
- ip_task_types=TaskName.dark,
229
- ),
230
- TaskUniqueBud(
231
- constant_name=BudName.solar_gain_gos_level0_status,
232
- metadata_key=MetadataKey.gos_level0_status,
233
- ip_task_types=TaskName.solar_gain,
234
- ),
235
- TaskAverageBud(
236
- constant_name=BudName.dark_average_light_level,
237
- metadata_key=MetadataKey.light_level,
238
- ip_task_types=TaskName.dark,
239
- ),
240
- TaskAverageBud(
241
- constant_name=BudName.solar_gain_average_light_level,
242
- metadata_key=MetadataKey.light_level,
243
- ip_task_types=TaskName.solar_gain,
244
- ),
245
- TaskAverageBud(
246
- constant_name=BudName.polcal_average_light_level,
247
- metadata_key=MetadataKey.light_level,
248
- ip_task_types=TaskName.polcal,
249
- ),
250
- TaskAverageBud(
251
- constant_name=BudName.dark_average_telescope_elevation,
252
- metadata_key=MetadataKey.elevation,
253
- ip_task_types=TaskName.dark,
254
- ),
255
- TaskAverageBud(
256
- constant_name=BudName.solar_gain_average_telescope_elevation,
257
- metadata_key=MetadataKey.elevation,
258
- ip_task_types=TaskName.solar_gain,
259
- ),
260
- TaskAverageBud(
261
- constant_name=BudName.polcal_average_telescope_elevation,
262
- metadata_key=MetadataKey.elevation,
263
- ip_task_types=TaskName.polcal,
264
- ),
265
- TaskAverageBud(
266
- constant_name=BudName.dark_average_coude_table_angle,
267
- metadata_key=MetadataKey.table_angle,
268
- ip_task_types=TaskName.dark,
269
- ),
270
- TaskAverageBud(
271
- constant_name=BudName.solar_gain_average_coude_table_angle,
272
- metadata_key=MetadataKey.table_angle,
273
- ip_task_types=TaskName.solar_gain,
274
- ),
275
- TaskAverageBud(
276
- constant_name=BudName.polcal_average_coude_table_angle,
277
- metadata_key=MetadataKey.table_angle,
278
- ip_task_types=TaskName.polcal,
279
- ),
280
- TaskAverageBud(
281
- constant_name=BudName.dark_average_telescope_azimuth,
282
- metadata_key=MetadataKey.azimuth,
283
- ip_task_types=TaskName.dark,
284
- ),
285
- TaskAverageBud(
286
- constant_name=BudName.solar_gain_average_telescope_azimuth,
287
- metadata_key=MetadataKey.azimuth,
288
- ip_task_types=TaskName.solar_gain,
289
- ),
290
- TaskAverageBud(
291
- constant_name=BudName.polcal_average_telescope_azimuth,
292
- metadata_key=MetadataKey.azimuth,
293
- ip_task_types=TaskName.polcal,
294
- ),
295
- TaskDateBeginBud(
296
- constant_name=BudName.dark_date_begin,
297
- ip_task_types=TaskName.dark,
298
- ),
299
- TaskDateBeginBud(
300
- constant_name=BudName.solar_gain_date_begin,
301
- ip_task_types=TaskName.solar_gain,
302
- ),
303
- TaskDateBeginBud(
304
- constant_name=BudName.polcal_date_begin,
305
- ip_task_types=TaskName.polcal,
306
- ),
307
- ]
308
-
309
-
310
62
  def default_constant_bud_factory() -> list[S]:
311
63
  """Provide default constant buds for use in common parsing tasks."""
312
- return dataset_extra_bud_factory() + [
64
+ return [
313
65
  UniqueBud(constant_name=BudName.instrument, metadata_key=MetadataKey.instrument),
314
66
  ProposalIdBud(),
315
67
  ContributingProposalIdsBud(),
@@ -4,6 +4,7 @@ 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
7
8
  from dkist_processing_common.models.fits_access import FitsAccessBase
8
9
  from dkist_processing_common.models.fits_access import MetadataKey
9
10
  from dkist_processing_common.parsers.l0_fits_access import L0FitsAccess
@@ -98,16 +99,30 @@ def hdu_with_no_data(complete_common_header):
98
99
  @pytest.fixture()
99
100
  def hdu_with_incomplete_common_header(complete_common_header):
100
101
  """
101
- An HDU with data and a header missing two of the expected common by-frame keywords
102
+ An HDU with data and a header missing one of the expected common by-frame keywords
102
103
  """
103
104
  incomplete_header = complete_common_header
104
- incomplete_header.pop(MetadataKey.elevation)
105
- incomplete_header.pop(MetadataKey.azimuth)
105
+ incomplete_header.pop("ELEV_ANG")
106
+ incomplete_header.pop("TAZIMUTH")
106
107
  data = np.arange(9).reshape(3, 3)
107
108
  hdu = fits.PrimaryHDU(data, header=incomplete_header)
108
109
  return hdu
109
110
 
110
111
 
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
+
111
126
  @pytest.fixture()
112
127
  def fits_file_path(tmp_path, complete_common_header):
113
128
  file_path = tmp_path / "foo.fits"
@@ -140,36 +155,35 @@ class MetadataKeyWithNaxisKeys(StrEnum):
140
155
  class FitsAccessWithNaxisKeys(FitsAccessBase):
141
156
  def __init__(self, hdu, name):
142
157
  super().__init__(hdu, name)
143
- self.naxis = self.header[MetadataKeyWithNaxisKeys.naxis]
144
- self.naxis1 = self.header[MetadataKeyWithNaxisKeys.naxis1]
145
- self.naxis2 = self.header[MetadataKeyWithNaxisKeys.naxis2]
158
+ self._set_metadata_key_value(MetadataKeyWithNaxisKeys.naxis)
159
+ self._set_metadata_key_value(MetadataKeyWithNaxisKeys.naxis1)
160
+ self._set_metadata_key_value(MetadataKeyWithNaxisKeys.naxis2)
146
161
 
147
162
 
148
163
  def test_metadata_keys_in_access_bases(hdu_with_no_data):
149
164
  """
150
165
  Given: a set of metadata key names in the MetadataKey sting enumeration
151
166
  When: the FITS access classes define a set of attributes/properties
152
- Then: the sets are the same and the values of the attributes/properties are correct
167
+ Then: the sets are the same
153
168
  """
154
169
  all_metadata_key_names = {mk.name for mk in MetadataKey}
155
170
  hdu = hdu_with_no_data
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]]
171
+ l1_properties = {k for k, v in L1FitsAccess.__dict__.items() if isinstance(v, property)}
172
+ l0_properties = {k for k, v in L0FitsAccess.__dict__.items() if isinstance(v, property)}
173
+ all_fits_access_properties = l1_properties | l0_properties
174
+ l1_dict_keys = {k for k, v in L1FitsAccess(hdu=hdu).__dict__.items()}
175
+ l0_dict_keys = {k for k, v in L0FitsAccess(hdu=hdu).__dict__.items()}
176
+ all_fits_access_dict_keys = l1_dict_keys | l0_dict_keys
177
+ instance_dict_keys = {"_hdu", "name", "auto_squeeze"}
178
+ keys_defined_in_fits_access = all_fits_access_dict_keys | all_fits_access_properties
179
+ assert all_metadata_key_names == keys_defined_in_fits_access - instance_dict_keys
166
180
 
167
181
 
168
182
  def test_from_single_hdu(hdu_with_complete_common_header):
169
183
  """
170
184
  Given: an HDU with expected, common by-frame keywords
171
185
  When: loading the HDU with the L0FitsAccess class
172
- Then: values for common keywords are exposed as properties on the fits_obj class
186
+ Then: all values for common keywords are exposed as properties on the fits_obj class
173
187
  """
174
188
  fits_obj = L0FitsAccess(hdu_with_complete_common_header)
175
189
  assert fits_obj.elevation == 6.28
@@ -184,7 +198,7 @@ def test_l1_only_fits_access(hdu_with_complete_l1_only_header):
184
198
  """
185
199
  Given: an HDU with 214 L1-only headers
186
200
  When: loading the HDU with the L1FitsAccess class
187
- Then: no errors are raised and values are exposed
201
+ Then: no errors are raised and all values are exposed
188
202
  """
189
203
  fits_obj = L1FitsAccess(hdu_with_complete_l1_only_header)
190
204
  assert fits_obj.elevation == 6.28
@@ -241,6 +255,17 @@ def test_no_header_value(hdu_with_incomplete_common_header):
241
255
  _ = L0FitsAccess(hdu_with_incomplete_common_header)
242
256
 
243
257
 
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
+
244
269
  def test_as_subclass(hdu_with_complete_common_header):
245
270
  """
246
271
  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.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]
100
+ self._set_metadata_key_value(ViSPMetadataKey.num_mod)
101
+ self._set_metadata_key_value(ViSPMetadataKey.modstate)
102
+ self._set_metadata_key_value(ViSPMetadataKey.ip_task_type)
103
103
  self.name = name
104
104
 
105
105
 
@@ -260,52 +260,18 @@ 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) == 64
263
+ assert len(constant_pot.stems) == 12
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_ID",
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 "DARK_" + base in stem_names
299
- assert "SOLAR_GAIN_" + base in stem_names
300
- if "GOS" not in base:
301
- assert "POLCAL_" + base in stem_names
302
-
303
-
304
270
  def test_constants_correct(parse_inputs_task):
305
271
  """
306
272
  Given: ParseInputData task with a populated constant FlowerPot
307
273
  When: Updating pipeline constants
308
- Then: A pipeline constant is correctly populated
274
+ Then: Pipeline constants are correctly populated
309
275
  """
310
276
  _, constant_pot = parse_inputs_task.make_flower_pots()
311
277
  parse_inputs_task.update_constants(constant_pot)
@@ -1214,12 +1214,20 @@ def wavecal_weights(wavecal_input_wavelength) -> np.ndarray:
1214
1214
 
1215
1215
 
1216
1216
  @pytest.fixture(scope="session")
1217
- def wavecal_fit_result(wavecal_input_wavelength) -> FitResult:
1217
+ def wavecal_fit_result(wavecal_input_wavelength, wavecal_input_spectrum) -> FitResult:
1218
1218
  wavelength_params = WavelengthParameters(
1219
1219
  crpix=1, crval=10.0, dispersion=1, grating_constant=1, order=1, incident_light_angle=0
1220
1220
  )
1221
- minimizer_result = MinimizerResult(residual=np.random.random(wavecal_input_wavelength.size))
1222
- return FitResult(wavelength_parameters=wavelength_params, minimizer_result=minimizer_result)
1221
+
1222
+ residuals = np.random.random(wavecal_input_wavelength.size)
1223
+ residuals[-1] = np.nan
1224
+ minimizer_result = MinimizerResult(residual=residuals)
1225
+ return FitResult(
1226
+ wavelength_parameters=wavelength_params,
1227
+ minimizer_result=minimizer_result,
1228
+ input_wavelength_vector=wavecal_input_wavelength,
1229
+ input_spectrum=wavecal_input_spectrum,
1230
+ )
1223
1231
 
1224
1232
 
1225
1233
  @pytest.mark.parametrize(