dkist-processing-common 11.3.1rc1__py3-none-any.whl → 11.4.0rc1__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 (33) hide show
  1. changelog/266.misc.rst +1 -0
  2. dkist_processing_common/models/constants.py +28 -42
  3. dkist_processing_common/models/fits_access.py +0 -56
  4. dkist_processing_common/models/tags.py +1 -2
  5. dkist_processing_common/models/task_name.py +2 -2
  6. dkist_processing_common/parsers/cs_step.py +2 -2
  7. dkist_processing_common/parsers/dsps_repeat.py +4 -5
  8. dkist_processing_common/parsers/experiment_id_bud.py +2 -5
  9. dkist_processing_common/parsers/id_bud.py +3 -6
  10. dkist_processing_common/parsers/l0_fits_access.py +3 -4
  11. dkist_processing_common/parsers/l1_fits_access.py +21 -22
  12. dkist_processing_common/parsers/near_bud.py +2 -5
  13. dkist_processing_common/parsers/proposal_id_bud.py +2 -3
  14. dkist_processing_common/parsers/retarder.py +3 -4
  15. dkist_processing_common/parsers/single_value_single_key_flower.py +1 -6
  16. dkist_processing_common/parsers/task.py +6 -7
  17. dkist_processing_common/parsers/time.py +15 -19
  18. dkist_processing_common/parsers/unique_bud.py +2 -5
  19. dkist_processing_common/parsers/wavelength.py +3 -4
  20. dkist_processing_common/tasks/parse_l0_input_data.py +3 -5
  21. dkist_processing_common/tests/test_assemble_movie.py +1 -0
  22. dkist_processing_common/tests/test_constants.py +0 -15
  23. dkist_processing_common/tests/test_fits_access.py +7 -62
  24. dkist_processing_common/tests/test_parse_l0_input_data.py +24 -22
  25. dkist_processing_common/tests/test_stems.py +21 -30
  26. dkist_processing_common/tests/test_task_parsing.py +7 -17
  27. {dkist_processing_common-11.3.1rc1.dist-info → dkist_processing_common-11.4.0rc1.dist-info}/METADATA +6 -6
  28. {dkist_processing_common-11.3.1rc1.dist-info → dkist_processing_common-11.4.0rc1.dist-info}/RECORD +30 -32
  29. changelog/265.feature.1.rst +0 -3
  30. changelog/265.feature.rst +0 -4
  31. changelog/265.misc.rst +0 -2
  32. {dkist_processing_common-11.3.1rc1.dist-info → dkist_processing_common-11.4.0rc1.dist-info}/WHEEL +0 -0
  33. {dkist_processing_common-11.3.1rc1.dist-info → dkist_processing_common-11.4.0rc1.dist-info}/top_level.txt +0 -0
@@ -2,7 +2,6 @@
2
2
 
3
3
  from datetime import datetime
4
4
  from datetime import timezone
5
- from enum import StrEnum
6
5
  from typing import Callable
7
6
  from typing import Hashable
8
7
  from typing import Type
@@ -10,7 +9,6 @@ from typing import Type
10
9
  import numpy as np
11
10
 
12
11
  from dkist_processing_common.models.constants import BudName
13
- from dkist_processing_common.models.fits_access import MetadataKey
14
12
  from dkist_processing_common.models.flower_pot import SpilledDirt
15
13
  from dkist_processing_common.models.flower_pot import Stem
16
14
  from dkist_processing_common.models.tags import EXP_TIME_ROUND_DIGITS
@@ -30,9 +28,9 @@ class ObsIpStartTimeBud(TaskUniqueBud):
30
28
 
31
29
  def __init__(self):
32
30
  super().__init__(
33
- constant_name=BudName.obs_ip_start_time,
34
- metadata_key=MetadataKey.ip_start_time,
35
- ip_task_types=TaskName.observe,
31
+ constant_name=BudName.obs_ip_start_time.value,
32
+ metadata_key="ip_start_time",
33
+ ip_task_types=TaskName.observe.value,
36
34
  )
37
35
 
38
36
 
@@ -40,7 +38,7 @@ class CadenceBudBase(UniqueBud):
40
38
  """Base class for all Cadence Buds."""
41
39
 
42
40
  def __init__(self, constant_name: str):
43
- super().__init__(constant_name, metadata_key=MetadataKey.time_obs)
41
+ super().__init__(constant_name, metadata_key="time_obs")
44
42
 
45
43
  def setter(self, fits_obj: L0FitsAccess) -> float | Type[SpilledDirt]:
46
44
  """
@@ -67,7 +65,7 @@ class AverageCadenceBud(CadenceBudBase):
67
65
  """Class for the average cadence Bud."""
68
66
 
69
67
  def __init__(self):
70
- super().__init__(constant_name=BudName.average_cadence)
68
+ super().__init__(constant_name=BudName.average_cadence.value)
71
69
 
72
70
  def getter(self, key) -> np.float64:
73
71
  """
@@ -89,7 +87,7 @@ class MaximumCadenceBud(CadenceBudBase):
89
87
  """Class for the maximum cadence bud."""
90
88
 
91
89
  def __init__(self):
92
- super().__init__(constant_name=BudName.maximum_cadence)
90
+ super().__init__(constant_name=BudName.maximum_cadence.value)
93
91
 
94
92
  def getter(self, key) -> np.float64:
95
93
  """
@@ -111,7 +109,7 @@ class MinimumCadenceBud(CadenceBudBase):
111
109
  """Class for the minimum cadence bud."""
112
110
 
113
111
  def __init__(self):
114
- super().__init__(constant_name=BudName.minimum_cadence)
112
+ super().__init__(constant_name=BudName.minimum_cadence.value)
115
113
 
116
114
  def getter(self, key) -> np.float64:
117
115
  """
@@ -133,7 +131,7 @@ class VarianceCadenceBud(CadenceBudBase):
133
131
  """Class for the variance cadence Bud."""
134
132
 
135
133
  def __init__(self):
136
- super().__init__(constant_name=BudName.variance_cadence)
134
+ super().__init__(constant_name=BudName.variance_cadence.value)
137
135
 
138
136
  def getter(self, key) -> np.float64:
139
137
  """
@@ -174,7 +172,7 @@ class ExposureTimeFlower(TimeFlowerBase):
174
172
 
175
173
  def __init__(self):
176
174
  super().__init__(
177
- tag_stem_name=StemName.exposure_time, metadata_key=MetadataKey.fpa_exposure_time_ms
175
+ tag_stem_name=StemName.exposure_time.value, metadata_key="fpa_exposure_time_ms"
178
176
  )
179
177
 
180
178
 
@@ -183,8 +181,8 @@ class ReadoutExpTimeFlower(TimeFlowerBase):
183
181
 
184
182
  def __init__(self):
185
183
  super().__init__(
186
- tag_stem_name=StemName.readout_exp_time,
187
- metadata_key=MetadataKey.sensor_readout_exposure_time_ms,
184
+ tag_stem_name=StemName.readout_exp_time.value,
185
+ metadata_key="sensor_readout_exposure_time_ms",
188
186
  )
189
187
 
190
188
 
@@ -215,17 +213,15 @@ class TaskTimeBudBase(Stem):
215
213
  def __init__(
216
214
  self,
217
215
  stem_name: str,
218
- metadata_key: str | StrEnum,
216
+ metadata_key: str,
219
217
  ip_task_types: str | list[str],
220
218
  header_task_parsing_func: Callable = passthrough_header_ip_task,
221
219
  ):
222
220
  super().__init__(stem_name=stem_name)
223
221
 
224
- if isinstance(metadata_key, StrEnum):
225
- metadata_key = metadata_key.name
226
- self.metadata_key = metadata_key
227
222
  if isinstance(ip_task_types, str):
228
223
  ip_task_types = [ip_task_types]
224
+ self.metadata_key = metadata_key
229
225
  self.ip_task_types = [task.casefold() for task in ip_task_types]
230
226
  self.header_parsing_function = header_task_parsing_func
231
227
 
@@ -256,7 +252,7 @@ class TaskExposureTimesBud(TaskTimeBudBase):
256
252
  ):
257
253
  super().__init__(
258
254
  stem_name=stem_name,
259
- metadata_key=MetadataKey.fpa_exposure_time_ms,
255
+ metadata_key="fpa_exposure_time_ms",
260
256
  ip_task_types=ip_task_types,
261
257
  header_task_parsing_func=header_task_parsing_func,
262
258
  )
@@ -273,7 +269,7 @@ class TaskReadoutExpTimesBud(TaskTimeBudBase):
273
269
  ):
274
270
  super().__init__(
275
271
  stem_name=stem_name,
276
- metadata_key=MetadataKey.sensor_readout_exposure_time_ms,
272
+ metadata_key="sensor_readout_exposure_time_ms",
277
273
  ip_task_types=ip_task_types,
278
274
  header_task_parsing_func=header_task_parsing_func,
279
275
  )
@@ -1,6 +1,5 @@
1
1
  """Pre-made flower that reads a single header key from all files and raises a ValueError if it is not unique."""
2
2
 
3
- from enum import StrEnum
4
3
  from typing import Callable
5
4
 
6
5
  from dkist_processing_common.models.flower_pot import SpilledDirt
@@ -25,11 +24,9 @@ class UniqueBud(Stem):
25
24
  def __init__(
26
25
  self,
27
26
  constant_name: str,
28
- metadata_key: str | StrEnum,
27
+ metadata_key: str,
29
28
  ):
30
29
  super().__init__(stem_name=constant_name)
31
- if isinstance(metadata_key, StrEnum):
32
- metadata_key = metadata_key.name
33
30
  self.metadata_key = metadata_key
34
31
 
35
32
  def setter(self, fits_obj: L0FitsAccess):
@@ -88,7 +85,7 @@ class TaskUniqueBud(UniqueBud):
88
85
  def __init__(
89
86
  self,
90
87
  constant_name: str,
91
- metadata_key: str | StrEnum,
88
+ metadata_key: str,
92
89
  ip_task_types: str | list[str],
93
90
  task_type_parsing_function: Callable = passthrough_header_ip_task,
94
91
  ):
@@ -1,7 +1,6 @@
1
1
  """Bud to get the wavelength of observe frames."""
2
2
 
3
3
  from dkist_processing_common.models.constants import BudName
4
- from dkist_processing_common.models.fits_access import MetadataKey
5
4
  from dkist_processing_common.models.task_name import TaskName
6
5
  from dkist_processing_common.parsers.unique_bud import TaskUniqueBud
7
6
 
@@ -11,7 +10,7 @@ class ObserveWavelengthBud(TaskUniqueBud):
11
10
 
12
11
  def __init__(self):
13
12
  super().__init__(
14
- constant_name=BudName.wavelength,
15
- metadata_key=MetadataKey.wavelength,
16
- ip_task_types=TaskName.observe,
13
+ constant_name=BudName.wavelength.value,
14
+ metadata_key="wavelength",
15
+ ip_task_types=TaskName.observe.value,
17
16
  )
@@ -28,12 +28,10 @@ from typing import TypeVar
28
28
 
29
29
  from dkist_processing_common.codecs.fits import fits_access_decoder
30
30
  from dkist_processing_common.models.constants import BudName
31
- from dkist_processing_common.models.fits_access import MetadataKey
32
31
  from dkist_processing_common.models.flower_pot import FlowerPot
33
32
  from dkist_processing_common.models.flower_pot import Stem
34
33
  from dkist_processing_common.models.flower_pot import Thorn
35
34
  from dkist_processing_common.models.tags import Tag
36
- from dkist_processing_common.models.task_name import TaskName
37
35
  from dkist_processing_common.parsers.experiment_id_bud import ContributingExperimentIdsBud
38
36
  from dkist_processing_common.parsers.experiment_id_bud import ExperimentIdBud
39
37
  from dkist_processing_common.parsers.proposal_id_bud import ContributingProposalIdsBud
@@ -62,7 +60,7 @@ S = TypeVar("S", bound=Stem)
62
60
  def default_constant_bud_factory() -> list[S]:
63
61
  """Provide default constant buds for use in common parsing tasks."""
64
62
  return [
65
- UniqueBud(constant_name=BudName.instrument, metadata_key=MetadataKey.instrument),
63
+ UniqueBud(constant_name=BudName.instrument.value, metadata_key="instrument"),
66
64
  ProposalIdBud(),
67
65
  ContributingProposalIdsBud(),
68
66
  ExperimentIdBud(),
@@ -71,9 +69,9 @@ def default_constant_bud_factory() -> list[S]:
71
69
  MaximumCadenceBud(),
72
70
  MinimumCadenceBud(),
73
71
  VarianceCadenceBud(),
74
- TaskExposureTimesBud(stem_name=BudName.dark_exposure_times, ip_task_types=TaskName.dark),
72
+ TaskExposureTimesBud(stem_name=BudName.dark_exposure_times.value, ip_task_types="dark"),
75
73
  TaskReadoutExpTimesBud(
76
- stem_name=BudName.dark_readout_exp_times, ip_task_types=TaskName.dark
74
+ stem_name=BudName.dark_readout_exp_times.value, ip_task_types="dark"
77
75
  ),
78
76
  ]
79
77
 
@@ -60,6 +60,7 @@ def assemble_task_with_tagged_movie_frames(
60
60
  task.constants._update(
61
61
  {
62
62
  BudName.num_dsps_repeats.value: num_dsps_repeats,
63
+ BudName.recipe_run_id.value: recipe_run_id,
63
64
  }
64
65
  )
65
66
  for d in range(num_dsps_repeats):
@@ -40,21 +40,6 @@ class ConstantsFinal(ConstantsBase):
40
40
  return self._db_dict["KEY 1"] ** 2 # Just to show that you can do whatever you want
41
41
 
42
42
 
43
- def test_bud_names_in_constant_base():
44
- """
45
- Given: a set of constants in the BudNames sting enumeration
46
- When: ConstantBase class defines a set of properties
47
- Then: the sets are the same (except for constants that are not in the redis database)
48
- """
49
- all_bud_names = {b.name for b in BudName}
50
- all_properties_in_constants_base = {
51
- k for k, v in ConstantsBase.__dict__.items() if isinstance(v, property)
52
- }
53
- constants_not_in_redis = {"dataset_id", "stokes_params"}
54
- all_buds_defined_in_constant_base = all_properties_in_constants_base - constants_not_in_redis
55
- assert all_bud_names == all_buds_defined_in_constant_base
56
-
57
-
58
43
  def test_constants_db_as_dict(test_constants_db, test_dict):
59
44
  """
60
45
  Given: a ConstantsDb object and a python dictionary
@@ -1,12 +1,8 @@
1
- from enum import StrEnum
2
-
3
1
  import numpy as np
4
2
  import pytest
5
3
  from astropy.io import fits
6
4
 
7
- from dkist_processing_common.models.fits_access import NOT_FOUND_MESSAGE
8
5
  from dkist_processing_common.models.fits_access import FitsAccessBase
9
- from dkist_processing_common.models.fits_access import MetadataKey
10
6
  from dkist_processing_common.parsers.l0_fits_access import L0FitsAccess
11
7
  from dkist_processing_common.parsers.l1_fits_access import L1FitsAccess
12
8
 
@@ -97,32 +93,17 @@ def hdu_with_no_data(complete_common_header):
97
93
 
98
94
 
99
95
  @pytest.fixture()
100
- def hdu_with_incomplete_common_header(complete_common_header):
96
+ def hdu_with_incomplete_common_header(tmp_path):
101
97
  """
102
98
  An HDU with data and a header missing one of the expected common by-frame keywords
103
99
  """
104
- incomplete_header = complete_common_header
105
- incomplete_header.pop("ELEV_ANG")
106
- incomplete_header.pop("TAZIMUTH")
107
100
  data = np.arange(9).reshape(3, 3)
108
- hdu = fits.PrimaryHDU(data, header=incomplete_header)
101
+ hdu = fits.PrimaryHDU(data)
102
+ hdu.header["TELEVATN"] = 6.28
103
+ hdu.header["TAZIMUTH"] = 3.14
109
104
  return hdu
110
105
 
111
106
 
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
107
  @pytest.fixture()
127
108
  def fits_file_path(tmp_path, complete_common_header):
128
109
  file_path = tmp_path / "foo.fits"
@@ -146,37 +127,12 @@ def fits_file_path_with_data_in_imagehdu(tmp_path, complete_common_header):
146
127
  return file_path
147
128
 
148
129
 
149
- class MetadataKeyWithNaxisKeys(StrEnum):
150
- naxis = "NAXIS"
151
- naxis1 = "NAXIS1"
152
- naxis2 = "NAXIS2"
153
-
154
-
155
130
  class FitsAccessWithNaxisKeys(FitsAccessBase):
156
131
  def __init__(self, hdu, name):
157
132
  super().__init__(hdu, name)
158
- self._set_metadata_key_value(MetadataKeyWithNaxisKeys.naxis)
159
- self._set_metadata_key_value(MetadataKeyWithNaxisKeys.naxis1)
160
- self._set_metadata_key_value(MetadataKeyWithNaxisKeys.naxis2)
161
-
162
-
163
- def test_metadata_keys_in_access_bases(hdu_with_no_data):
164
- """
165
- Given: a set of metadata key names in the MetadataKey sting enumeration
166
- When: the FITS access classes define a set of attributes/properties
167
- Then: the sets are the same
168
- """
169
- all_metadata_key_names = {mk.name for mk in MetadataKey}
170
- hdu = hdu_with_no_data
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
133
+ self.naxis = self.header["NAXIS"]
134
+ self.naxis1 = self.header["NAXIS1"]
135
+ self.naxis2 = self.header["NAXIS2"]
180
136
 
181
137
 
182
138
  def test_from_single_hdu(hdu_with_complete_common_header):
@@ -255,17 +211,6 @@ def test_no_header_value(hdu_with_incomplete_common_header):
255
211
  _ = L0FitsAccess(hdu_with_incomplete_common_header)
256
212
 
257
213
 
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
214
  def test_as_subclass(hdu_with_complete_common_header):
270
215
  """
271
216
  Given: an instrument-specific fits_obj class that subclasses L0FitsAccess
@@ -1,7 +1,5 @@
1
1
  """Tests for the parse L0 input data task"""
2
2
 
3
- from enum import StrEnum
4
-
5
3
  import numpy as np
6
4
  import pytest
7
5
  from astropy.io import fits
@@ -22,7 +20,6 @@ from dkist_processing_common.parsers.single_value_single_key_flower import (
22
20
  )
23
21
  from dkist_processing_common.parsers.unique_bud import UniqueBud
24
22
  from dkist_processing_common.tasks.parse_l0_input_data import ParseL0InputDataBase
25
- from dkist_processing_common.tasks.parse_l0_input_data import default_constant_bud_factory
26
23
 
27
24
 
28
25
  class VispHeaders(Spec122Dataset):
@@ -88,33 +85,25 @@ class VispHeaders(Spec122Dataset):
88
85
  return self.index % self.num_mod
89
86
 
90
87
 
91
- class ViSPMetadataKey(StrEnum):
92
- num_mod = "VISP_010"
93
- modstate = "VISP_011"
94
- ip_task_type = "DKIST004"
95
-
96
-
97
88
  class ViSPFitsAccess(FitsAccessBase):
98
89
  def __init__(self, hdu, name, auto_squeeze=False):
99
90
  super().__init__(hdu, name, auto_squeeze=auto_squeeze)
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)
91
+ self.num_mod: int = self.header["VISP_010"]
92
+ self.modstate: int = self.header["VISP_011"]
93
+ self.ip_task_type: str = self.header["DKIST004"]
103
94
  self.name = name
104
95
 
105
96
 
106
97
  @pytest.fixture(scope="function")
107
98
  def visp_flowers():
108
99
  return [
109
- SingleValueSingleKeyFlower(
110
- tag_stem_name=StemName.modstate, metadata_key=ViSPMetadataKey.modstate
111
- )
100
+ SingleValueSingleKeyFlower(tag_stem_name=StemName.modstate.value, metadata_key="modstate")
112
101
  ]
113
102
 
114
103
 
115
104
  @pytest.fixture(scope="function")
116
105
  def visp_buds():
117
- return [UniqueBud(constant_name=BudName.num_modstates, metadata_key=ViSPMetadataKey.num_mod)]
106
+ return [UniqueBud(constant_name=BudName.num_modstates.value, metadata_key="num_mod")]
118
107
 
119
108
 
120
109
  @pytest.fixture(scope="function")
@@ -244,9 +233,9 @@ def test_make_flowerpots(parse_inputs_task):
244
233
 
245
234
  assert len(tag_pot.stems) == 2
246
235
  assert len(constant_pot.stems) == 3
247
- assert tag_pot.stems[0].stem_name == StemName.modstate
236
+ assert tag_pot.stems[0].stem_name == StemName.modstate.value
248
237
  assert tag_pot.stems[1].stem_name == "EMPTY_FLOWER"
249
- assert constant_pot.stems[0].stem_name == BudName.num_modstates
238
+ assert constant_pot.stems[0].stem_name == BudName.num_modstates.value
250
239
  assert constant_pot.stems[1].stem_name == "EMPTY_BUD"
251
240
  assert constant_pot.stems[2].stem_name == "PICKY_BUD"
252
241
 
@@ -261,10 +250,23 @@ def test_subclass_flowers(visp_parse_inputs_task, max_cs_step_time_sec):
261
250
 
262
251
  assert len(tag_pot.stems) == 1
263
252
  assert len(constant_pot.stems) == 12
264
- all_flower_names = [StemName.modstate]
265
- assert sorted([f.stem_name for f in tag_pot.stems]) == sorted(all_flower_names)
266
- all_bud_names = [b.stem_name for b in default_constant_bud_factory()] + [BudName.num_modstates]
267
- assert sorted([f.stem_name for f in constant_pot.stems]) == sorted(all_bud_names)
253
+ assert sorted([f.stem_name for f in tag_pot.stems]) == sorted([StemName.modstate.value])
254
+ assert sorted([f.stem_name for f in constant_pot.stems]) == sorted(
255
+ [
256
+ BudName.instrument.value,
257
+ BudName.num_modstates.value,
258
+ BudName.proposal_id.value,
259
+ BudName.contributing_proposal_ids.value,
260
+ BudName.average_cadence.value,
261
+ BudName.maximum_cadence.value,
262
+ BudName.minimum_cadence.value,
263
+ BudName.variance_cadence.value,
264
+ BudName.dark_exposure_times.value,
265
+ BudName.dark_readout_exp_times.value,
266
+ BudName.experiment_id.value,
267
+ BudName.contributing_experiment_ids.value,
268
+ ]
269
+ )
268
270
 
269
271
 
270
272
  def test_constants_correct(parse_inputs_task):
@@ -1,4 +1,3 @@
1
- from enum import StrEnum
2
1
  from itertools import chain
3
2
 
4
3
  import pytest
@@ -40,38 +39,30 @@ from dkist_processing_common.parsers.unique_bud import UniqueBud
40
39
  from dkist_processing_common.parsers.wavelength import ObserveWavelengthBud
41
40
 
42
41
 
43
- class FitsReaderMetadataKey(StrEnum):
44
- thing_id = "id_key"
45
- constant_thing = "constant"
46
- near_thing = "near"
47
- proposal_id = "ID___013"
48
- experiment_id = "ID___012"
49
- ip_task_type = "DKIST004"
50
- ip_start_time = "DKIST011"
51
- fpa_exposure_time_ms = "XPOSURE"
52
- sensor_readout_exposure_time_ms = "TEXPOSUR"
53
- num_raw_frames_per_fpa = "NSUMEXP"
54
- num_dsps_repeats = "DSPSREPS"
55
- current_dsps_repeat = "DSPSNUM"
56
- time_obs = "DATE-OBS"
57
- gos_level3_status = "GOSLVL3"
58
- gos_level3_lamp_status = "GOSLAMP"
59
- gos_level0_status = "GOSLVL0"
60
- gos_retarder_status = "GOSRET"
61
- gos_polarizer_status = "GOSPOL"
62
- wavelength = "LINEWAV"
63
- roundable_time = "RTIME"
64
-
65
-
66
42
  class FitsReader(FitsAccessBase):
67
43
  def __init__(self, hdu, name):
68
44
  super().__init__(hdu, name)
69
- for key in FitsReaderMetadataKey:
70
- self._set_metadata_key_value(key=key, optional=True)
71
- self._set_metadata_key_value(
72
- FitsReaderMetadataKey.roundable_time, optional=True, default=0.0
73
- )
45
+ self.thing_id: int = self.header.get("id_key")
46
+ self.constant_thing: float = self.header.get("constant")
47
+ self.near_thing: float = self.header.get("near")
74
48
  self.name = name
49
+ self.proposal_id: str = self.header.get("ID___013")
50
+ self.experiment_id: str = self.header.get("ID___012")
51
+ self.ip_task_type: str = self.header.get("DKIST004")
52
+ self.ip_start_time: str = self.header.get("DKIST011")
53
+ self.fpa_exposure_time_ms: float = self.header.get("XPOSURE")
54
+ self.sensor_readout_exposure_time_ms: float = self.header.get("TEXPOSUR")
55
+ self.num_raw_frames_per_fpa: int = self.header.get("NSUMEXP")
56
+ self.num_dsps_repeats: int = self.header.get("DSPSREPS")
57
+ self.current_dsps_repeat: int = self.header.get("DSPSNUM")
58
+ self.time_obs: str = self.header.get("DATE-OBS")
59
+ self.gos_level3_status: str = self.header.get("GOSLVL3")
60
+ self.gos_level3_lamp_status: str = self.header.get("GOSLAMP")
61
+ self.gos_level0_status: str = self.header.get("GOSLVL0")
62
+ self.gos_retarder_status: str = self.header.get("GOSRET")
63
+ self.gos_polarizer_status: str = self.header.get("GOSPOL")
64
+ self.wavelength: str = self.header.get("LINEWAV")
65
+ self.roundable_time: float = self.header.get("RTIME", 0.0)
75
66
 
76
67
 
77
68
  @pytest.fixture()
@@ -935,4 +926,4 @@ def test_retarder_name_bud_error(bad_polcal_header_objs):
935
926
  _ = bud.bud
936
927
 
937
928
 
938
- # TODO: test new stem types that have been added to parse_l0_input_data
929
+ # TODO: test new stems that have been added to parse_l0_input_data
@@ -1,5 +1,3 @@
1
- from enum import StrEnum
2
-
3
1
  import pytest
4
2
  from astropy.io import fits
5
3
 
@@ -11,15 +9,6 @@ from dkist_processing_common.parsers.task import parse_polcal_task_type
11
9
  from dkist_processing_common.parsers.task import passthrough_header_ip_task
12
10
 
13
11
 
14
- class DummyMetadataKey(StrEnum):
15
- ip_task_type = "IPTASK"
16
- gos_level3_status = "GOSLVL3"
17
- gos_level3_lamp_status = "GOSLAMP"
18
- gos_level0_status = "GOSLVL0"
19
- gos_retarder_status = "GOSRET"
20
- gos_polarizer_status = "GOSPOL"
21
-
22
-
23
12
  class DummyFitsAccess(FitsAccessBase):
24
13
  def __init__(
25
14
  self,
@@ -28,12 +17,13 @@ class DummyFitsAccess(FitsAccessBase):
28
17
  auto_squeeze: bool = False, # Because L1 data should always have the right form, right?
29
18
  ):
30
19
  super().__init__(hdu=hdu, name=name, auto_squeeze=auto_squeeze)
31
- self._set_metadata_key_value(DummyMetadataKey.ip_task_type)
32
- self._set_metadata_key_value(DummyMetadataKey.gos_level3_status)
33
- self._set_metadata_key_value(DummyMetadataKey.gos_level3_lamp_status)
34
- self._set_metadata_key_value(DummyMetadataKey.gos_level0_status)
35
- self._set_metadata_key_value(DummyMetadataKey.gos_retarder_status)
36
- self._set_metadata_key_value(DummyMetadataKey.gos_polarizer_status)
20
+
21
+ self.ip_task_type: str = self.header["IPTASK"]
22
+ self.gos_level3_status: str = self.header["GOSLVL3"]
23
+ self.gos_level3_lamp_status: str = self.header["GOSLAMP"]
24
+ self.gos_level0_status: str = self.header["GOSLVL0"]
25
+ self.gos_retarder_status: str = self.header["GOSRET"]
26
+ self.gos_polarizer_status: str = self.header["GOSPOL"]
37
27
 
38
28
 
39
29
  @pytest.fixture
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dkist-processing-common
3
- Version: 11.3.1rc1
3
+ Version: 11.4.0rc1
4
4
  Summary: Common task classes used by the DKIST science data processing pipelines
5
5
  Author-email: NSO / AURA <dkistdc@nso.edu>
6
6
  License: BSD-3-Clause
@@ -10,14 +10,14 @@ Project-URL: Documentation, https://docs.dkist.nso.edu/projects/common
10
10
  Project-URL: Help, https://nso.atlassian.net/servicedesk/customer/portal/5
11
11
  Classifier: Programming Language :: Python
12
12
  Classifier: Programming Language :: Python :: 3
13
- Classifier: Programming Language :: Python :: 3.11
14
- Requires-Python: >=3.11
13
+ Classifier: Programming Language :: Python :: 3.12
14
+ Requires-Python: >=3.12
15
15
  Description-Content-Type: text/x-rst
16
16
  Requires-Dist: asdf<4.0.0,>=3.5.0
17
17
  Requires-Dist: astropy>=7.0.0
18
18
  Requires-Dist: dkist-fits-specifications<5.0,>=4.0.0
19
19
  Requires-Dist: dkist-header-validator<6.0,>=5.0.0
20
- Requires-Dist: dkist-processing-core==5.1.1
20
+ Requires-Dist: dkist-processing-core==5.2.0rc1
21
21
  Requires-Dist: dkist-processing-pac<4.0,>=3.1
22
22
  Requires-Dist: dkist-service-configuration<3.0,>=2.0.2
23
23
  Requires-Dist: dkist-spectral-lines<4.0,>=3.0.0
@@ -28,7 +28,7 @@ Requires-Dist: sqids==0.5.1
28
28
  Requires-Dist: matplotlib>=3.4
29
29
  Requires-Dist: moviepy>=2.0.0
30
30
  Requires-Dist: numpy>=1.26.4
31
- Requires-Dist: object-clerk==0.1.2
31
+ Requires-Dist: object-clerk==1.0.0
32
32
  Requires-Dist: pandas>=1.4.2
33
33
  Requires-Dist: pillow>=10.2.0
34
34
  Requires-Dist: pydantic>=2.0
@@ -36,7 +36,7 @@ Requires-Dist: redis==4.6.0
36
36
  Requires-Dist: requests>=2.23
37
37
  Requires-Dist: scipy>=1.15.1
38
38
  Requires-Dist: sunpy>=3.0.0
39
- Requires-Dist: talus==1.1.0
39
+ Requires-Dist: talus==1.3.4
40
40
  Provides-Extra: test
41
41
  Requires-Dist: pytest; extra == "test"
42
42
  Requires-Dist: pytest-xdist; extra == "test"