dkist-processing-common 10.8.1rc1__py3-none-any.whl → 10.8.2__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/codecs/fits.py +6 -12
- dkist_processing_common/manual.py +5 -3
- dkist_processing_common/models/graphql.py +3 -13
- dkist_processing_common/models/parameters.py +28 -65
- dkist_processing_common/tasks/mixin/input_dataset.py +166 -0
- dkist_processing_common/tasks/mixin/metadata_store.py +4 -7
- dkist_processing_common/tasks/transfer_input_data.py +70 -61
- dkist_processing_common/tasks/write_l1.py +20 -1
- dkist_processing_common/tests/conftest.py +7 -24
- dkist_processing_common/tests/test_codecs.py +0 -38
- dkist_processing_common/tests/test_input_dataset.py +308 -79
- dkist_processing_common/tests/test_parameters.py +22 -71
- dkist_processing_common/tests/test_transfer_input_data.py +45 -131
- dkist_processing_common/tests/test_write_l1.py +110 -2
- {dkist_processing_common-10.8.1rc1.dist-info → dkist_processing_common-10.8.2.dist-info}/METADATA +2 -2
- {dkist_processing_common-10.8.1rc1.dist-info → dkist_processing_common-10.8.2.dist-info}/RECORD +18 -23
- {dkist_processing_common-10.8.1rc1.dist-info → dkist_processing_common-10.8.2.dist-info}/WHEEL +1 -1
- changelog/235.feature.rst +0 -3
- changelog/235.misc.1.rst +0 -2
- changelog/235.misc.rst +0 -1
- dkist_processing_common/codecs/array.py +0 -19
- dkist_processing_common/codecs/basemodel.py +0 -21
- dkist_processing_common/models/input_dataset.py +0 -113
- {dkist_processing_common-10.8.1rc1.dist-info → dkist_processing_common-10.8.2.dist-info}/top_level.txt +0 -0
|
@@ -5,12 +5,10 @@ from pathlib import Path
|
|
|
5
5
|
import pytest
|
|
6
6
|
|
|
7
7
|
from dkist_processing_common._util.scratch import WorkflowFileSystem
|
|
8
|
-
from dkist_processing_common.codecs.
|
|
8
|
+
from dkist_processing_common.codecs.json import json_decoder
|
|
9
9
|
from dkist_processing_common.models.graphql import InputDatasetRecipeRunResponse
|
|
10
|
-
from dkist_processing_common.models.input_dataset import InputDatasetPartDocumentList
|
|
11
10
|
from dkist_processing_common.models.tags import Tag
|
|
12
11
|
from dkist_processing_common.tasks.transfer_input_data import TransferL0Data
|
|
13
|
-
from dkist_processing_common.tests.conftest import create_input_frames
|
|
14
12
|
from dkist_processing_common.tests.conftest import create_parameter_files
|
|
15
13
|
from dkist_processing_common.tests.conftest import FakeGQLClient
|
|
16
14
|
|
|
@@ -20,7 +18,7 @@ class TransferL0DataTask(TransferL0Data):
|
|
|
20
18
|
...
|
|
21
19
|
|
|
22
20
|
|
|
23
|
-
class
|
|
21
|
+
class FakeGQLClientMissingInputDatasetPart(FakeGQLClient):
|
|
24
22
|
"""Same metadata mocker with calibration input dataset part missing."""
|
|
25
23
|
|
|
26
24
|
def execute_gql_query(self, **kwargs):
|
|
@@ -55,152 +53,103 @@ def transfer_l0_data_task(recipe_run_id, tmp_path, mocker):
|
|
|
55
53
|
|
|
56
54
|
|
|
57
55
|
@pytest.fixture
|
|
58
|
-
def
|
|
56
|
+
def transfer_l0_data_task_missing_part(recipe_run_id, tmp_path, mocker):
|
|
59
57
|
yield from _transfer_l0_data_task_with_client(
|
|
60
|
-
recipe_run_id, tmp_path, mocker,
|
|
58
|
+
recipe_run_id, tmp_path, mocker, FakeGQLClientMissingInputDatasetPart
|
|
61
59
|
)
|
|
62
60
|
|
|
63
61
|
|
|
64
|
-
|
|
65
|
-
"expected_doc, tag",
|
|
66
|
-
[
|
|
67
|
-
pytest.param(
|
|
68
|
-
FakeGQLClient.observe_frames_doc_object,
|
|
69
|
-
Tag.input_dataset_observe_frames(),
|
|
70
|
-
id="observe_frames",
|
|
71
|
-
),
|
|
72
|
-
pytest.param(
|
|
73
|
-
FakeGQLClient.calibration_frames_doc_object,
|
|
74
|
-
Tag.input_dataset_calibration_frames(),
|
|
75
|
-
id="calibration_frames",
|
|
76
|
-
),
|
|
77
|
-
pytest.param(
|
|
78
|
-
FakeGQLClient.parameters_doc_object,
|
|
79
|
-
Tag.input_dataset_parameters(),
|
|
80
|
-
id="parameters",
|
|
81
|
-
),
|
|
82
|
-
],
|
|
83
|
-
)
|
|
84
|
-
def test_download_dataset(transfer_l0_data_task, expected_doc, tag):
|
|
62
|
+
def test_download_dataset(transfer_l0_data_task):
|
|
85
63
|
"""
|
|
86
64
|
:Given: a TransferL0Data task with a valid input dataset
|
|
87
65
|
:When: downloading the dataset documents from the metadata store
|
|
88
|
-
:Then: the correct documents are written to disk
|
|
66
|
+
:Then: the correct documents are written to disk
|
|
89
67
|
"""
|
|
90
68
|
# Given
|
|
91
69
|
task = transfer_l0_data_task
|
|
92
70
|
# When
|
|
93
71
|
task.download_input_dataset()
|
|
94
72
|
# Then
|
|
95
|
-
|
|
96
|
-
|
|
73
|
+
expected_observe_doc = FakeGQLClient.observe_frames_doc_object
|
|
74
|
+
observe_doc_from_file = next(
|
|
75
|
+
task.read(tags=Tag.input_dataset_observe_frames(), decoder=json_decoder)
|
|
76
|
+
)
|
|
77
|
+
assert observe_doc_from_file == expected_observe_doc
|
|
78
|
+
expected_calibration_doc = FakeGQLClient.calibration_frames_doc_object
|
|
79
|
+
calibration_doc_from_file = next(
|
|
80
|
+
task.read(tags=Tag.input_dataset_calibration_frames(), decoder=json_decoder)
|
|
81
|
+
)
|
|
82
|
+
assert calibration_doc_from_file == expected_calibration_doc
|
|
83
|
+
expected_parameters_doc = FakeGQLClient.parameters_doc_object
|
|
84
|
+
parameters_doc_from_file = next(
|
|
85
|
+
task.read(tags=Tag.input_dataset_parameters(), decoder=json_decoder)
|
|
97
86
|
)
|
|
98
|
-
|
|
99
|
-
if (
|
|
100
|
-
tag == Tag.input_dataset_parameters()
|
|
101
|
-
): # parameter doc gets written with tags for file objects
|
|
102
|
-
for item in expected_doc:
|
|
103
|
-
for val in item["parameterValues"]:
|
|
104
|
-
if "__file__" in val["parameterValue"]:
|
|
105
|
-
file_dict = json.loads(val["parameterValue"])["__file__"]
|
|
106
|
-
file_dict["tag"] = Tag.parameter(Path(file_dict["objectKey"]).name)
|
|
107
|
-
val["parameterValue"] = json.dumps({"__file__": file_dict})
|
|
108
|
-
assert doc_list_from_file == expected_doc
|
|
87
|
+
assert parameters_doc_from_file == expected_parameters_doc
|
|
109
88
|
|
|
110
89
|
|
|
111
|
-
def test_download_dataset_missing_part(
|
|
90
|
+
def test_download_dataset_missing_part(transfer_l0_data_task_missing_part):
|
|
112
91
|
"""
|
|
113
92
|
:Given: a TransferL0Data task with a valid input dataset without calibration frames
|
|
114
93
|
:When: downloading the dataset documents from the metadata store
|
|
115
94
|
:Then: the correct number of documents are written to disk
|
|
116
95
|
"""
|
|
117
96
|
# Given
|
|
118
|
-
task =
|
|
97
|
+
task = transfer_l0_data_task_missing_part
|
|
119
98
|
# When
|
|
120
99
|
task.download_input_dataset()
|
|
121
100
|
# Then
|
|
122
101
|
observe_doc_from_file = next(
|
|
123
|
-
task.read(
|
|
124
|
-
tags=Tag.input_dataset_observe_frames(),
|
|
125
|
-
decoder=basemodel_decoder,
|
|
126
|
-
model=InputDatasetPartDocumentList,
|
|
127
|
-
)
|
|
102
|
+
task.read(tags=Tag.input_dataset_observe_frames(), decoder=json_decoder)
|
|
128
103
|
)
|
|
129
104
|
parameters_doc_from_file = next(
|
|
130
|
-
task.read(
|
|
131
|
-
tags=Tag.input_dataset_parameters(),
|
|
132
|
-
decoder=basemodel_decoder,
|
|
133
|
-
model=InputDatasetPartDocumentList,
|
|
134
|
-
)
|
|
105
|
+
task.read(tags=Tag.input_dataset_parameters(), decoder=json_decoder)
|
|
135
106
|
)
|
|
136
107
|
with pytest.raises(StopIteration):
|
|
137
108
|
calibration_doc_from_file = next(
|
|
138
|
-
task.read(
|
|
139
|
-
tags=Tag.input_dataset_calibration_frames(),
|
|
140
|
-
decoder=basemodel_decoder,
|
|
141
|
-
model=InputDatasetPartDocumentList,
|
|
142
|
-
)
|
|
109
|
+
task.read(tags=Tag.input_dataset_calibration_frames(), decoder=json_decoder)
|
|
143
110
|
)
|
|
144
111
|
|
|
145
112
|
|
|
146
|
-
|
|
147
|
-
"task_name",
|
|
148
|
-
[
|
|
149
|
-
pytest.param(
|
|
150
|
-
"transfer_l0_data_task",
|
|
151
|
-
id="observe_and_calibration_frames",
|
|
152
|
-
),
|
|
153
|
-
pytest.param(
|
|
154
|
-
"transfer_l0_data_task_missing_calibration_part",
|
|
155
|
-
id="calibration_frames_missing",
|
|
156
|
-
),
|
|
157
|
-
],
|
|
158
|
-
)
|
|
159
|
-
def test_build_frame_transfer_list_formatted(request, task_name):
|
|
113
|
+
def test_format_frame_transfer_items(transfer_l0_data_task):
|
|
160
114
|
"""
|
|
161
|
-
:Given: a TransferL0Data task with downloaded input dataset
|
|
162
|
-
:When:
|
|
163
|
-
:Then: the
|
|
115
|
+
:Given: a TransferL0Data task with a downloaded input dataset
|
|
116
|
+
:When: formatting frames in the input dataset for transfer
|
|
117
|
+
:Then: the items are correctly loaded into GlobusTransferItem objects
|
|
164
118
|
"""
|
|
165
119
|
# Given
|
|
166
|
-
task =
|
|
120
|
+
task = transfer_l0_data_task
|
|
167
121
|
task.download_input_dataset()
|
|
168
122
|
# When
|
|
169
|
-
|
|
170
|
-
calibration_transfer_objects = task.build_transfer_list(
|
|
171
|
-
doc_tag=Tag.input_dataset_calibration_frames()
|
|
172
|
-
)
|
|
173
|
-
transfer_objects = observe_transfer_objects + calibration_transfer_objects
|
|
174
|
-
formatted_transfer_items = task.format_transfer_items(input_dataset_objects=transfer_objects)
|
|
123
|
+
transfer_items = task.format_frame_transfer_items()
|
|
175
124
|
# Then
|
|
176
125
|
source_filenames = []
|
|
177
126
|
destination_filenames = []
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
for frame_set in
|
|
127
|
+
all_frames = (
|
|
128
|
+
FakeGQLClient.observe_frames_doc_object + FakeGQLClient.calibration_frames_doc_object
|
|
129
|
+
)
|
|
130
|
+
for frame_set in all_frames:
|
|
182
131
|
for key in frame_set["object_keys"]:
|
|
183
132
|
source_filenames.append(os.path.join("/", frame_set["bucket"], key))
|
|
184
133
|
destination_filenames.append(Path(key).name)
|
|
185
|
-
assert len(
|
|
186
|
-
for item in
|
|
134
|
+
assert len(transfer_items) == len(source_filenames)
|
|
135
|
+
for item in transfer_items:
|
|
187
136
|
assert item.source_path.as_posix() in source_filenames
|
|
188
137
|
assert item.destination_path.name in destination_filenames
|
|
189
138
|
assert not item.recursive
|
|
190
139
|
|
|
191
140
|
|
|
192
|
-
def
|
|
141
|
+
def test_format_parameter_file_transfer_items(transfer_l0_data_task):
|
|
193
142
|
"""
|
|
194
|
-
:Given: a TransferL0Data task with downloaded input dataset
|
|
195
|
-
:When:
|
|
196
|
-
:Then: the
|
|
143
|
+
:Given: a TransferL0Data task with a downloaded input dataset
|
|
144
|
+
:When: formatting parameter files in the input dataset for transfer
|
|
145
|
+
:Then: the items are correctly loaded into GlobusTransferItem objects
|
|
197
146
|
"""
|
|
198
147
|
# Given
|
|
199
148
|
task = transfer_l0_data_task
|
|
200
149
|
task.download_input_dataset()
|
|
150
|
+
create_parameter_files(task)
|
|
201
151
|
# When
|
|
202
|
-
|
|
203
|
-
formatted_transfer_items = task.format_transfer_items(input_dataset_objects=transfer_objects)
|
|
152
|
+
transfer_items = task.format_parameter_transfer_items()
|
|
204
153
|
# Then
|
|
205
154
|
source_filenames = []
|
|
206
155
|
destination_filenames = []
|
|
@@ -213,44 +162,9 @@ def test_build_parameter_file_transfer_items(transfer_l0_data_task):
|
|
|
213
162
|
object_key = value_dict["__file__"]["objectKey"]
|
|
214
163
|
source_filenames.append(os.path.join("/", bucket, object_key))
|
|
215
164
|
destination_filenames.append(Path(object_key).name)
|
|
216
|
-
assert len(
|
|
217
|
-
for transfer_item in
|
|
165
|
+
assert len(transfer_items) == len(source_filenames)
|
|
166
|
+
for transfer_item in transfer_items:
|
|
218
167
|
assert transfer_item.source_path.as_posix() in source_filenames
|
|
219
168
|
assert transfer_item.destination_path.name in destination_filenames
|
|
220
169
|
assert str(transfer_item.destination_path).startswith(str(task.scratch.workflow_base_path))
|
|
221
170
|
assert not transfer_item.recursive
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
def test_tag_transfer_items(transfer_l0_data_task):
|
|
225
|
-
"""
|
|
226
|
-
:Given: a TransferL0Data task with downloaded input dataset frames and parameter files
|
|
227
|
-
:When: tagging the downloaded files
|
|
228
|
-
:Then: the downloaded items are correctly tagged
|
|
229
|
-
"""
|
|
230
|
-
# Given
|
|
231
|
-
task = transfer_l0_data_task
|
|
232
|
-
task.download_input_dataset()
|
|
233
|
-
observe_transfer_objects = task.build_transfer_list(doc_tag=Tag.input_dataset_observe_frames())
|
|
234
|
-
calibration_transfer_objects = task.build_transfer_list(
|
|
235
|
-
doc_tag=Tag.input_dataset_calibration_frames()
|
|
236
|
-
)
|
|
237
|
-
frame_transfer_objects = observe_transfer_objects + calibration_transfer_objects
|
|
238
|
-
create_input_frames(task)
|
|
239
|
-
parameter_transfer_objects = task.build_transfer_list(doc_tag=Tag.input_dataset_parameters())
|
|
240
|
-
create_parameter_files(task)
|
|
241
|
-
# When
|
|
242
|
-
transfer_objects = frame_transfer_objects + parameter_transfer_objects
|
|
243
|
-
task.tag_transfer_objects(input_dataset_objects=transfer_objects)
|
|
244
|
-
# Then
|
|
245
|
-
input_tags = [Tag.input(), Tag.frame()]
|
|
246
|
-
input_frames_on_disk = list(task.scratch.find_all(tags=input_tags))
|
|
247
|
-
for obj in frame_transfer_objects:
|
|
248
|
-
destination_path = task.scratch.absolute_path(obj.object_key)
|
|
249
|
-
assert destination_path in input_frames_on_disk
|
|
250
|
-
assert len(input_frames_on_disk) == len(frame_transfer_objects)
|
|
251
|
-
for obj in parameter_transfer_objects:
|
|
252
|
-
destination_path = task.scratch.absolute_path(obj.object_key)
|
|
253
|
-
param_tag = Tag.parameter(Path(obj.object_key))
|
|
254
|
-
param_file_on_disk = list(task.scratch.find_all(tags=param_tag))
|
|
255
|
-
assert destination_path in param_file_on_disk
|
|
256
|
-
assert len(param_file_on_disk) == 1
|
|
@@ -25,7 +25,7 @@ from dkist_processing_common.tasks.write_l1 import WriteL1Frame
|
|
|
25
25
|
from dkist_processing_common.tests.conftest import FakeGQLClient
|
|
26
26
|
from dkist_processing_common.tests.conftest import TILE_SIZE
|
|
27
27
|
from dkist_processing_common.tests.test_transfer_input_data import (
|
|
28
|
-
|
|
28
|
+
FakeGQLClientMissingInputDatasetPart,
|
|
29
29
|
)
|
|
30
30
|
|
|
31
31
|
|
|
@@ -101,6 +101,12 @@ class CompleteWriteL1Frame(WriteL1Frame):
|
|
|
101
101
|
return WavelengthRange(min=1075.0 * u.nm, max=1085.0 * u.nm)
|
|
102
102
|
|
|
103
103
|
|
|
104
|
+
class CompleteWriteL1FrameWithEmptyWaveband(CompleteWriteL1Frame):
|
|
105
|
+
def get_wavelength_range(self, header: fits.Header) -> WavelengthRange:
|
|
106
|
+
# Return an empty range to test the empty waveband case
|
|
107
|
+
return WavelengthRange(min=10000.0 * u.nm, max=10050.0 * u.nm)
|
|
108
|
+
|
|
109
|
+
|
|
104
110
|
@dataclass
|
|
105
111
|
class FakeConstantDb:
|
|
106
112
|
INSTRUMENT: str = "TEST"
|
|
@@ -154,6 +160,44 @@ def write_l1_task(request, recipe_run_id, tmp_path):
|
|
|
154
160
|
task._purge()
|
|
155
161
|
|
|
156
162
|
|
|
163
|
+
@pytest.fixture(
|
|
164
|
+
scope="function",
|
|
165
|
+
params=[
|
|
166
|
+
pytest.param((1, "complete_common_header"), id="Intensity"),
|
|
167
|
+
pytest.param((4, "complete_polarimetric_header"), id="Polarimetric"),
|
|
168
|
+
],
|
|
169
|
+
)
|
|
170
|
+
def write_l1_task_with_empty_waveband(recipe_run_id, tmp_path, request):
|
|
171
|
+
with CompleteWriteL1FrameWithEmptyWaveband(
|
|
172
|
+
recipe_run_id=recipe_run_id,
|
|
173
|
+
workflow_name="workflow_name",
|
|
174
|
+
workflow_version="workflow_version",
|
|
175
|
+
) as task:
|
|
176
|
+
task.scratch = WorkflowFileSystem(recipe_run_id=recipe_run_id, scratch_base_path=tmp_path)
|
|
177
|
+
num_of_stokes_params, header_fixture_name = request.param
|
|
178
|
+
header = request.getfixturevalue(header_fixture_name)
|
|
179
|
+
stokes_params = ["I", "Q", "U", "V"]
|
|
180
|
+
used_stokes_params = []
|
|
181
|
+
hdu = fits.PrimaryHDU(data=np.random.random(size=(1, 128, 128)) * 10, header=header)
|
|
182
|
+
hdu.header["IPTASK"] = "level0_only key to be removed"
|
|
183
|
+
hdul = fits.HDUList([hdu])
|
|
184
|
+
for i in range(num_of_stokes_params):
|
|
185
|
+
task.write(
|
|
186
|
+
data=hdul,
|
|
187
|
+
tags=[
|
|
188
|
+
Tag.calibrated(),
|
|
189
|
+
Tag.frame(),
|
|
190
|
+
Tag.stokes(stokes_params[i]),
|
|
191
|
+
Tag.dsps_repeat(i),
|
|
192
|
+
],
|
|
193
|
+
encoder=fits_hdulist_encoder,
|
|
194
|
+
)
|
|
195
|
+
used_stokes_params.append(stokes_params[i])
|
|
196
|
+
task.constants._update(asdict(FakeConstantDb()))
|
|
197
|
+
yield task, used_stokes_params, header
|
|
198
|
+
task._purge()
|
|
199
|
+
|
|
200
|
+
|
|
157
201
|
@pytest.fixture(
|
|
158
202
|
scope="function",
|
|
159
203
|
params=[
|
|
@@ -503,7 +547,7 @@ def test_missing_input_dataset_part(write_l1_task, mocker):
|
|
|
503
547
|
"""
|
|
504
548
|
mocker.patch(
|
|
505
549
|
"dkist_processing_common.tasks.mixin.metadata_store.GraphQLClient",
|
|
506
|
-
new=
|
|
550
|
+
new=FakeGQLClientMissingInputDatasetPart,
|
|
507
551
|
)
|
|
508
552
|
task, _, _ = write_l1_task
|
|
509
553
|
task()
|
|
@@ -616,3 +660,67 @@ def test_check_r0_ao_lock(write_l1_task_no_data):
|
|
|
616
660
|
with pytest.raises(KeyError, match="Keyword 'ATMOS_R0' not found"):
|
|
617
661
|
invalid_r0 = header_after_check["ATMOS_R0"]
|
|
618
662
|
assert header.get("AO_LOCK") != True
|
|
663
|
+
|
|
664
|
+
|
|
665
|
+
@pytest.mark.parametrize(
|
|
666
|
+
"wavelength, wavemin, wavemax, expected",
|
|
667
|
+
[
|
|
668
|
+
pytest.param(
|
|
669
|
+
617,
|
|
670
|
+
615,
|
|
671
|
+
619,
|
|
672
|
+
"Fe I (617.33 nm)",
|
|
673
|
+
id="line_is_between_wavemin_and_wavemax_and_exists",
|
|
674
|
+
),
|
|
675
|
+
pytest.param(
|
|
676
|
+
700,
|
|
677
|
+
698,
|
|
678
|
+
702,
|
|
679
|
+
None,
|
|
680
|
+
id="line_is_between_wavemin_and_wavemax_and_does_not_exist",
|
|
681
|
+
),
|
|
682
|
+
pytest.param(
|
|
683
|
+
617,
|
|
684
|
+
698,
|
|
685
|
+
702,
|
|
686
|
+
None,
|
|
687
|
+
id="line_is_not_between_wavemin_and_wavemax_and_exists",
|
|
688
|
+
),
|
|
689
|
+
],
|
|
690
|
+
)
|
|
691
|
+
def test_get_waveband(write_l1_task, wavelength, wavemin, wavemax, expected):
|
|
692
|
+
"""
|
|
693
|
+
:Given: an input wavelength contribution
|
|
694
|
+
:When: determining the waveband
|
|
695
|
+
:Then: the correct waveband is returned
|
|
696
|
+
"""
|
|
697
|
+
wavelength_range = WavelengthRange(min=wavemin * u.nm, max=wavemax * u.nm)
|
|
698
|
+
task, _, _ = write_l1_task
|
|
699
|
+
waveband = task.get_waveband(wavelength=wavelength * u.nm, wavelength_range=wavelength_range)
|
|
700
|
+
assert waveband == expected
|
|
701
|
+
|
|
702
|
+
|
|
703
|
+
def test_empty_waveband(write_l1_task_with_empty_waveband, mocker):
|
|
704
|
+
"""
|
|
705
|
+
:Given: a header converted to SPEC 214 L1 and a wavelength range that has no listed spectral lines
|
|
706
|
+
:When: checking the waveband key
|
|
707
|
+
:Then: it does not exist
|
|
708
|
+
"""
|
|
709
|
+
mocker.patch(
|
|
710
|
+
"dkist_processing_common.tasks.mixin.metadata_store.GraphQLClient", new=FakeGQLClient
|
|
711
|
+
)
|
|
712
|
+
mocker.patch(
|
|
713
|
+
"dkist_processing_common.tasks.write_l1.WriteL1Frame.version_from_module_name",
|
|
714
|
+
new_callable=Mock,
|
|
715
|
+
return_value="fake_version_number",
|
|
716
|
+
)
|
|
717
|
+
|
|
718
|
+
task, _, _ = write_l1_task_with_empty_waveband
|
|
719
|
+
task()
|
|
720
|
+
files = list(task.read(tags=[Tag.frame(), Tag.output()]))
|
|
721
|
+
for file in files:
|
|
722
|
+
header = fits.open(file)[1].header
|
|
723
|
+
assert header["WAVEMIN"] == 10000
|
|
724
|
+
assert header["WAVEMAX"] == 10050
|
|
725
|
+
with pytest.raises(KeyError):
|
|
726
|
+
header["WAVEBAND"]
|
{dkist_processing_common-10.8.1rc1.dist-info → dkist_processing_common-10.8.2.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dkist-processing-common
|
|
3
|
-
Version: 10.8.
|
|
3
|
+
Version: 10.8.2
|
|
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
|
|
@@ -17,7 +17,7 @@ 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.
|
|
20
|
+
Requires-Dist: dkist-processing-core==5.1.1
|
|
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
|
{dkist_processing_common-10.8.1rc1.dist-info → dkist_processing_common-10.8.2.dist-info}/RECORD
RENAMED
|
@@ -1,21 +1,16 @@
|
|
|
1
1
|
changelog/.gitempty,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
changelog/235.feature.rst,sha256=F27MUnNkqjcmlmRQ6NQUi2wd5M9dOjN2jZ70TV95Y20,365
|
|
3
|
-
changelog/235.misc.1.rst,sha256=kQujVYRa_axHQSRFxW3SNPNMgEL-YgtnyLud-aJljL8,234
|
|
4
|
-
changelog/235.misc.rst,sha256=ooK2tbA5EEFyYNZLLvgYiMZ-Eza5UzPHN9MvpuX-cu4,92
|
|
5
2
|
dkist_processing_common/__init__.py,sha256=490Fwm_GgqpwriQlsYfKcLUZNhZ6GkINtJqcYSIEKoU,319
|
|
6
3
|
dkist_processing_common/config.py,sha256=IcpaD_NvHZU-aLlUNOTdRC4V7ADIvVQwrZ2dHhIr4NY,4247
|
|
7
|
-
dkist_processing_common/manual.py,sha256=
|
|
4
|
+
dkist_processing_common/manual.py,sha256=IH72QxdGlr-BuWq2EDrfC9yStegO-elUWrobQqT4710,7042
|
|
8
5
|
dkist_processing_common/_util/__init__.py,sha256=xf6JNpMKQgbhE2Jivymt-WO0WF6PpGt9rl604YpuTWk,92
|
|
9
6
|
dkist_processing_common/_util/constants.py,sha256=b0zlRaT09aGj2RU72OQ5J-8u6Z_RevPXtcyx5tlnf-Y,3244
|
|
10
7
|
dkist_processing_common/_util/graphql.py,sha256=qjsvLWDHqb1X7hDLA8uqbpOIDjZZ2mjsSIL0Wkt1TJc,3420
|
|
11
8
|
dkist_processing_common/_util/scratch.py,sha256=4X5K260ffBHWvyVfP0SCk_-QTWEcTougB7qu9TdF7LM,10364
|
|
12
9
|
dkist_processing_common/_util/tags.py,sha256=8r62_-x3xpbCoCu5dd09Q2u-OYzYiML6SlPUf9LXCEw,6220
|
|
13
10
|
dkist_processing_common/codecs/__init__.py,sha256=du1iitvsudSSOMENSywXmXSLOlvIocJsPbvfEcyqFNc,159
|
|
14
|
-
dkist_processing_common/codecs/array.py,sha256=GeIB6mTMZuQK4Jxn2tGmMmYgA-bLik2SAlWopRZhEO8,575
|
|
15
11
|
dkist_processing_common/codecs/asdf.py,sha256=2GHCFOZk1j-ml4EolXac_sUzk7aPYJUGqKYxZk4mG_c,1046
|
|
16
|
-
dkist_processing_common/codecs/basemodel.py,sha256=6w7OjsPLdsmY_tiwveBmDthYW3WLtAWqM3hjrQa5UhA,814
|
|
17
12
|
dkist_processing_common/codecs/bytes.py,sha256=tiVEUu_Gzc5NfW1_qsJtHDlYAZzgIqA7f4cfAwN734k,495
|
|
18
|
-
dkist_processing_common/codecs/fits.py,sha256=
|
|
13
|
+
dkist_processing_common/codecs/fits.py,sha256=0D6tDvt13OhVXok4tS8VGHdd8OSV8DrRet8VCD6Zt3g,2346
|
|
19
14
|
dkist_processing_common/codecs/iobase.py,sha256=r0ImN0CxfjAnfMflNv7w2pGDp2i6EQg0p2OaEkE82pk,977
|
|
20
15
|
dkist_processing_common/codecs/json.py,sha256=OWXzoFWccJiojkiKSeDrMdL9f7EpdNIOMvO9YBBg-Yg,939
|
|
21
16
|
dkist_processing_common/codecs/path.py,sha256=LU5Kh1ew2PQI9hcpzbnZkE47k-zAMZDDV4cgqHRcDkY,197
|
|
@@ -27,12 +22,11 @@ dkist_processing_common/models/__init__.py,sha256=6LMqemdzVZ87fRrpAsbEnTtWZ02_Gu
|
|
|
27
22
|
dkist_processing_common/models/constants.py,sha256=1Eb8RDeuCr6brl237iGKxYLWCH49I6bOUEj_Tv-zFbQ,5441
|
|
28
23
|
dkist_processing_common/models/fits_access.py,sha256=Au9JROwhVla9zb_u0dN8mIWiSJd_Pca0oOr4N1hN0HY,4113
|
|
29
24
|
dkist_processing_common/models/flower_pot.py,sha256=59C5uGYKyMyncqQYxhzDZWl8k1DRZFB6s9RF-HFp9mY,5128
|
|
30
|
-
dkist_processing_common/models/graphql.py,sha256=
|
|
31
|
-
dkist_processing_common/models/input_dataset.py,sha256=OZDxyjHZfFrksFGpas1gsB14Q77CeNsk_nI-EYo3ZRI,4121
|
|
25
|
+
dkist_processing_common/models/graphql.py,sha256=t2PYEjEwSq08zq0HcVH2RG5FX4PVXgs4BdM2gunJ8fs,4747
|
|
32
26
|
dkist_processing_common/models/message.py,sha256=DRW7Qhl01dF5KagcqLta5U-uzdOMewrsHvMatDT6jnk,1684
|
|
33
27
|
dkist_processing_common/models/message_queue_binding.py,sha256=ROQ2ZQE3TCr4gVbz4WggvUSExAiWP8SD_GjjQl482M8,1012
|
|
34
28
|
dkist_processing_common/models/metric_code.py,sha256=McXAEF1Sa0_YlR1niXYLJWLFHhdLQhmYw9Xtpr5FGws,815
|
|
35
|
-
dkist_processing_common/models/parameters.py,sha256=
|
|
29
|
+
dkist_processing_common/models/parameters.py,sha256=Ymx-wvPVMkXg5emhOivv7NG0QsAt98If4KotopLIRrw,7736
|
|
36
30
|
dkist_processing_common/models/quality.py,sha256=ONz1A6_qyEoZhQkVp9LChAgm93aGt1O5WSRneE3XCCA,2319
|
|
37
31
|
dkist_processing_common/models/tags.py,sha256=ykOYqWMU7_ffvRCv84-avjXyty9pHBo7EXwsjIjStjs,12058
|
|
38
32
|
dkist_processing_common/models/task_name.py,sha256=NL0n92A9vVYBV-yvh8d-qFOCxVy0X2GECDmLgIzrmOY,565
|
|
@@ -61,34 +55,35 @@ dkist_processing_common/tasks/output_data_base.py,sha256=CC1TnCrChi8_iuMymr425CJ
|
|
|
61
55
|
dkist_processing_common/tasks/parse_l0_input_data.py,sha256=iRMGdvhxBobNsTDQ0IEl0myDfB4P_xpxA00guuBWDj8,7986
|
|
62
56
|
dkist_processing_common/tasks/quality_metrics.py,sha256=g6MUq8s8jELDinkn6o45rfONyODw92JyVMrzb7Dd7OI,12458
|
|
63
57
|
dkist_processing_common/tasks/teardown.py,sha256=e4LKnphJDYDVDAez2tH7MxpZgCmxYsKrq9Zk0qAkzzM,2355
|
|
64
|
-
dkist_processing_common/tasks/transfer_input_data.py,sha256=
|
|
58
|
+
dkist_processing_common/tasks/transfer_input_data.py,sha256=afEW0glpCFMZRj90nFtQo_4XOQ4CuoOh86jahP6a-a0,5548
|
|
65
59
|
dkist_processing_common/tasks/trial_catalog.py,sha256=Y3DKstRfMS8nWWtJFMB0MUVPlZ1jWS_2jhJGMWwxy50,8748
|
|
66
60
|
dkist_processing_common/tasks/trial_output_data.py,sha256=aI_aRuu0qVO8zFGrr_9baxx9i3jUEHZSmsmbO6ytlkE,6960
|
|
67
|
-
dkist_processing_common/tasks/write_l1.py,sha256=
|
|
61
|
+
dkist_processing_common/tasks/write_l1.py,sha256=vwNJs8gSzc0RPIfcpZ267L6pIJWdbPQ8ZmKR6hX1BIs,23498
|
|
68
62
|
dkist_processing_common/tasks/mixin/__init__.py,sha256=-g-DQbU7m1bclJYuFe3Yh757V-35GIDTbstardKQ7nU,68
|
|
69
63
|
dkist_processing_common/tasks/mixin/globus.py,sha256=QAV8VElxMAqxJ2KSB_bJaraceovYfjHXjOdocrTCkIA,6592
|
|
64
|
+
dkist_processing_common/tasks/mixin/input_dataset.py,sha256=dkW5vf_QPgWedHO_Lf9GjBxr1QrUCKs6gIXufUTi7GE,6813
|
|
70
65
|
dkist_processing_common/tasks/mixin/interservice_bus.py,sha256=I7BUh0o8AEX-FZv7gxCts6is0uq9lycWjtTB2KqwBrU,1080
|
|
71
|
-
dkist_processing_common/tasks/mixin/metadata_store.py,sha256=
|
|
66
|
+
dkist_processing_common/tasks/mixin/metadata_store.py,sha256=dMwjlhBI89xX0Pagub2Bk09z0fToipFN51DwyQEIHbk,11510
|
|
72
67
|
dkist_processing_common/tasks/mixin/object_store.py,sha256=Vn4l2XuCimii9Fc3gM-pQGIkTKMv_ldqljlxkLesZLU,3236
|
|
73
68
|
dkist_processing_common/tasks/mixin/quality/__init__.py,sha256=Bgu-DHW7yXLiehglldOCWluEkAP5qh0Hp1F30rh5NFw,383
|
|
74
69
|
dkist_processing_common/tasks/mixin/quality/_base.py,sha256=nZ9IC-O-hsLXa5-tk29B13CZyQIdhJCv0eO9cdkAhWc,8303
|
|
75
70
|
dkist_processing_common/tasks/mixin/quality/_metrics.py,sha256=WenTfa12guIUfm0GzkrK2gduKaOHs03e6RhE6j37Les,54304
|
|
76
71
|
dkist_processing_common/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
77
|
-
dkist_processing_common/tests/conftest.py,sha256=
|
|
72
|
+
dkist_processing_common/tests/conftest.py,sha256=h_ObhpXb1S0-db0Je8XoHNLkrXxXW_0B0TMhbnbDjMo,30160
|
|
78
73
|
dkist_processing_common/tests/test_assemble_movie.py,sha256=XY_ruXSYP5k6s2gUAwlFdnhJ81eyWLSd2O9IkX4RXeo,4165
|
|
79
74
|
dkist_processing_common/tests/test_assemble_quality.py,sha256=fWSHK4UdVqgNjvxQuD40NBUnXrtmthUP7PUbISPV4MQ,16897
|
|
80
75
|
dkist_processing_common/tests/test_base.py,sha256=4ST3__jEHitEQaQs9-0OcqtyEJfIjZsk_6PRYZFV2-U,7124
|
|
81
|
-
dkist_processing_common/tests/test_codecs.py,sha256=
|
|
76
|
+
dkist_processing_common/tests/test_codecs.py,sha256=9Ln8FJs319rbHpCukO9lKLk3aDrdyDREjA4nCHsxDCA,20796
|
|
82
77
|
dkist_processing_common/tests/test_constants.py,sha256=Kc9k5TdYy5QkRRlGav6kfI2dy5HHKqtpf9qOuaAfDZU,5903
|
|
83
78
|
dkist_processing_common/tests/test_cs_step.py,sha256=RA0QD3D8eaL3YSOL_gIJ9wkngy14RQ2jbD-05KAziW4,2408
|
|
84
79
|
dkist_processing_common/tests/test_fits_access.py,sha256=tyUPNbUqoTPhQgzua_doWP9l9ee4ir_LLV-I9rHktcs,11393
|
|
85
80
|
dkist_processing_common/tests/test_flower_pot.py,sha256=X9_UI3maa3ZQncV3jYHgovWnawDsdEkEB5vw6EAB96o,3151
|
|
86
|
-
dkist_processing_common/tests/test_input_dataset.py,sha256=
|
|
81
|
+
dkist_processing_common/tests/test_input_dataset.py,sha256=AI5uqaDea4kOwpwAU5qQdzUbxMpBwD20YCAvB7nzD5o,18766
|
|
87
82
|
dkist_processing_common/tests/test_interservice_bus.py,sha256=M_iv2CLmx5TnCB1VUN4YjkQ2LEUjfCKk7-ZlkV62XEQ,3000
|
|
88
83
|
dkist_processing_common/tests/test_interservice_bus_mixin.py,sha256=8TTl0aypkq5gBPeyqSaQHbz_jmt5RmSD2oI8kT4Q1ZA,4195
|
|
89
84
|
dkist_processing_common/tests/test_manual_processing.py,sha256=wAZJztsF33jzJE3m3vJ6cJT0ujgIkMg01jGq-Ys_a4c,1045
|
|
90
85
|
dkist_processing_common/tests/test_output_data_base.py,sha256=Y9MFz5xw11tAnKjpHH7qrzsRYP1rZM_Trt4AylY0S6k,3120
|
|
91
|
-
dkist_processing_common/tests/test_parameters.py,sha256=
|
|
86
|
+
dkist_processing_common/tests/test_parameters.py,sha256=Tr0Wu8-_rj9Lp7CkUVmJjSouW7CAL_ZwhShK_U1GzVs,12384
|
|
92
87
|
dkist_processing_common/tests/test_parse_l0_input_data.py,sha256=SMNV1qyQTvnMx94MCNsiA-RyS9uxaxIABEDDxsuVzqY,10629
|
|
93
88
|
dkist_processing_common/tests/test_publish_catalog_messages.py,sha256=wB2lcAnT77yVnqO0cFWOPxGf-tZ8U62kvvpiB5roBwQ,3268
|
|
94
89
|
dkist_processing_common/tests/test_quality.py,sha256=vomy2YSPadKqJj2tG8sCs-UkQVvfKus7Cum7_Hpee4I,10257
|
|
@@ -100,12 +95,12 @@ dkist_processing_common/tests/test_tags.py,sha256=UwlOJ45rkvbfbd5L5m5YltvOxQc8kG
|
|
|
100
95
|
dkist_processing_common/tests/test_task_name.py,sha256=kqFr59XX2K87xzfTlClzDV4-Je1dx72LvdaJ22UE8UU,1233
|
|
101
96
|
dkist_processing_common/tests/test_task_parsing.py,sha256=QXt1X6DTO3_liBD2c-t84DToLeEn7B3J-eteIyN4HEM,4027
|
|
102
97
|
dkist_processing_common/tests/test_teardown.py,sha256=w2sATQHkg2lMLvm6VFZF1mNGFYHwWj_SxvF9RQu-tuY,5362
|
|
103
|
-
dkist_processing_common/tests/test_transfer_input_data.py,sha256=
|
|
98
|
+
dkist_processing_common/tests/test_transfer_input_data.py,sha256=kE-FQTcN9nft5bh2Rhtp-8ldCTvGXTvWFcsNm6DY7lk,6619
|
|
104
99
|
dkist_processing_common/tests/test_transfer_l1_output_data.py,sha256=27PifkyH3RZg0nsM-AjmrFJ-hbYuCk5Tt_0Zx8PJBfM,2109
|
|
105
100
|
dkist_processing_common/tests/test_trial_catalog.py,sha256=SZ-nyn0MXU9Lkg_94FbKER_cwiGoi06GYlzF_3AmvKg,6802
|
|
106
101
|
dkist_processing_common/tests/test_trial_output_data.py,sha256=cBCj0kXyF5NEMzKh6zPVksdoXyE8ju1opJgWgjdcJWA,12790
|
|
107
102
|
dkist_processing_common/tests/test_workflow_task_base.py,sha256=Z5aPW5LQtS0UWJiYho4X0r-2gPLfzpkmMwfmaoFLjMg,10517
|
|
108
|
-
dkist_processing_common/tests/test_write_l1.py,sha256=
|
|
103
|
+
dkist_processing_common/tests/test_write_l1.py,sha256=ahAdMg3QhE-gnV_UMhL_xne-H5nHHDVMOWrP1vonIQ0,25962
|
|
109
104
|
docs/Makefile,sha256=qnlVz6PuBqE39NfHWuUnHhNEA-EFgT2-WJNNNy9ttfk,4598
|
|
110
105
|
docs/changelog.rst,sha256=S2jPASsWlQxSlAPqdvNrYvhk9k3FcFWNXFNDYXBSjl4,120
|
|
111
106
|
docs/conf.py,sha256=FkX575cqTqZGCcLAjg2MlvE8Buj1Vt3CpHNgZxG256E,1890
|
|
@@ -114,7 +109,7 @@ docs/landing_page.rst,sha256=aPAuXFhBx73lEZ59B6E6JXxkK0LlxzD0n-HXqHrfumQ,746
|
|
|
114
109
|
docs/make.bat,sha256=mBAhtURwhQ7yc95pqwJzlhqBSvRknr1aqZ5s8NKvdKs,4513
|
|
115
110
|
docs/requirements.txt,sha256=Kbl_X4c7RQZw035YTeNB63We6I7pvXFU4T0Uflp2yDY,29
|
|
116
111
|
licenses/LICENSE.rst,sha256=piZaQplkzOMmH1NXg6QIdo9wwo9pPCoHkvm2-DmH76E,1462
|
|
117
|
-
dkist_processing_common-10.8.
|
|
118
|
-
dkist_processing_common-10.8.
|
|
119
|
-
dkist_processing_common-10.8.
|
|
120
|
-
dkist_processing_common-10.8.
|
|
112
|
+
dkist_processing_common-10.8.2.dist-info/METADATA,sha256=8bbHCAylpH-0Ux_TMjUDNRySAFXKZHStbLWMYaQSKF8,7147
|
|
113
|
+
dkist_processing_common-10.8.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
114
|
+
dkist_processing_common-10.8.2.dist-info/top_level.txt,sha256=LJhd1W-Vn90K8HnQDIE4r52YDpUjjMWDnllAWHBByW0,48
|
|
115
|
+
dkist_processing_common-10.8.2.dist-info/RECORD,,
|
changelog/235.feature.rst
DELETED
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
Add two new codecs: Basemodel codecs are used for encoding and decoding Pydantic BaseModel objects. For decoding, the intended model
|
|
2
|
-
is passed to the decoder through a keyword argument in the task read method. Array codecs are used for encoding and decoding numpy
|
|
3
|
-
arrays similar to the standard np.load() and np.save(), but with the task tag-based write method.
|
changelog/235.misc.1.rst
DELETED
changelog/235.misc.rst
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
Remove the input_dataset mixin and replace it with input_dataset Pydantic BaseModel models.
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
"""Encoder/decoder for writing/reading numpy arrays."""
|
|
2
|
-
import io
|
|
3
|
-
from pathlib import Path
|
|
4
|
-
|
|
5
|
-
import numpy as np
|
|
6
|
-
|
|
7
|
-
from dkist_processing_common.codecs.iobase import iobase_encoder
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def array_encoder(data: np.ndarray, **np_kwargs) -> bytes:
|
|
11
|
-
"""Convert a numpy array to bytes compatible with np.load()."""
|
|
12
|
-
buffer = io.BytesIO()
|
|
13
|
-
np.save(buffer, data, **np_kwargs)
|
|
14
|
-
return iobase_encoder(buffer)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def array_decoder(path: Path, **np_kwargs) -> np.ndarray:
|
|
18
|
-
"""Return the data in the file as a numpy array using np.load()."""
|
|
19
|
-
return np.load(path, **np_kwargs)
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
"""Encoder/decoder for writing and reading Pydantic BaseModel objects."""
|
|
2
|
-
from pathlib import Path
|
|
3
|
-
from typing import Type
|
|
4
|
-
|
|
5
|
-
from pydantic import BaseModel
|
|
6
|
-
|
|
7
|
-
from dkist_processing_common.codecs.bytes import bytes_decoder
|
|
8
|
-
from dkist_processing_common.codecs.str import str_encoder
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
def basemodel_encoder(data: BaseModel, **basemodel_kwargs) -> bytes:
|
|
12
|
-
"""Convert a Pydantic BaseModel object into bytes for writing to file."""
|
|
13
|
-
data_dump = data.model_dump_json(**basemodel_kwargs)
|
|
14
|
-
return str_encoder(data_dump)
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def basemodel_decoder(path: Path, model: Type[BaseModel], **basemodel_kwargs) -> BaseModel:
|
|
18
|
-
"""Return the data in the file as a Pydantic BaseModel object."""
|
|
19
|
-
data = bytes_decoder(path)
|
|
20
|
-
model_validated = model.model_validate_json(data, **basemodel_kwargs)
|
|
21
|
-
return model_validated
|