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.
- changelog/266.misc.rst +1 -0
- dkist_processing_common/models/constants.py +28 -42
- dkist_processing_common/models/fits_access.py +0 -56
- dkist_processing_common/models/tags.py +1 -2
- dkist_processing_common/models/task_name.py +2 -2
- dkist_processing_common/parsers/cs_step.py +2 -2
- dkist_processing_common/parsers/dsps_repeat.py +4 -5
- dkist_processing_common/parsers/experiment_id_bud.py +2 -5
- dkist_processing_common/parsers/id_bud.py +3 -6
- dkist_processing_common/parsers/l0_fits_access.py +3 -4
- dkist_processing_common/parsers/l1_fits_access.py +21 -22
- dkist_processing_common/parsers/near_bud.py +2 -5
- dkist_processing_common/parsers/proposal_id_bud.py +2 -3
- dkist_processing_common/parsers/retarder.py +3 -4
- dkist_processing_common/parsers/single_value_single_key_flower.py +1 -6
- dkist_processing_common/parsers/task.py +6 -7
- dkist_processing_common/parsers/time.py +15 -19
- dkist_processing_common/parsers/unique_bud.py +2 -5
- dkist_processing_common/parsers/wavelength.py +3 -4
- dkist_processing_common/tasks/parse_l0_input_data.py +3 -5
- dkist_processing_common/tests/test_assemble_movie.py +1 -0
- dkist_processing_common/tests/test_constants.py +0 -15
- dkist_processing_common/tests/test_fits_access.py +7 -62
- dkist_processing_common/tests/test_parse_l0_input_data.py +24 -22
- dkist_processing_common/tests/test_stems.py +21 -30
- dkist_processing_common/tests/test_task_parsing.py +7 -17
- {dkist_processing_common-11.3.1rc1.dist-info → dkist_processing_common-11.4.0rc1.dist-info}/METADATA +6 -6
- {dkist_processing_common-11.3.1rc1.dist-info → dkist_processing_common-11.4.0rc1.dist-info}/RECORD +30 -32
- changelog/265.feature.1.rst +0 -3
- changelog/265.feature.rst +0 -4
- changelog/265.misc.rst +0 -2
- {dkist_processing_common-11.3.1rc1.dist-info → dkist_processing_common-11.4.0rc1.dist-info}/WHEEL +0 -0
- {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=
|
|
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=
|
|
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=
|
|
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=
|
|
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
|
|
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=
|
|
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=
|
|
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
|
|
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
|
|
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=
|
|
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=
|
|
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=
|
|
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=
|
|
74
|
+
stem_name=BudName.dark_readout_exp_times.value, ip_task_types="dark"
|
|
77
75
|
),
|
|
78
76
|
]
|
|
79
77
|
|
|
@@ -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(
|
|
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
|
|
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.
|
|
159
|
-
self.
|
|
160
|
-
self.
|
|
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.
|
|
101
|
-
self.
|
|
102
|
-
self.
|
|
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=
|
|
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
|
-
|
|
265
|
-
assert sorted([f.stem_name for f in
|
|
266
|
-
|
|
267
|
-
|
|
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
|
-
|
|
70
|
-
|
|
71
|
-
self.
|
|
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
|
|
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
|
-
|
|
32
|
-
self.
|
|
33
|
-
self.
|
|
34
|
-
self.
|
|
35
|
-
self.
|
|
36
|
-
self.
|
|
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
|
{dkist_processing_common-11.3.1rc1.dist-info → dkist_processing_common-11.4.0rc1.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dkist-processing-common
|
|
3
|
-
Version: 11.
|
|
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.
|
|
14
|
-
Requires-Python: >=3.
|
|
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.
|
|
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.
|
|
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.
|
|
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"
|