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.
@@ -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.basemodel import basemodel_decoder
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 FakeGQLClientMissingInputDatasetCalibrationPart(FakeGQLClient):
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 transfer_l0_data_task_missing_calibration_part(recipe_run_id, tmp_path, mocker):
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, FakeGQLClientMissingInputDatasetCalibrationPart
58
+ recipe_run_id, tmp_path, mocker, FakeGQLClientMissingInputDatasetPart
61
59
  )
62
60
 
63
61
 
64
- @pytest.mark.parametrize(
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, along with tags for file parameters
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
- doc_from_file = next(
96
- task.read(tags=tag, decoder=basemodel_decoder, model=InputDatasetPartDocumentList)
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
- doc_list_from_file = doc_from_file.model_dump()["doc_list"]
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(transfer_l0_data_task_missing_calibration_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 = transfer_l0_data_task_missing_calibration_part
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
- @pytest.mark.parametrize(
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 docs
162
- :When: building a list of frames in the input dataset formatted for transfer
163
- :Then: the correct items are correctly loaded into GlobusTransferItem objects
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 = request.getfixturevalue(task_name)
120
+ task = transfer_l0_data_task
167
121
  task.download_input_dataset()
168
122
  # When
169
- observe_transfer_objects = task.build_transfer_list(doc_tag=Tag.input_dataset_observe_frames())
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
- expected_frames = list(FakeGQLClient.observe_frames_doc_object)
179
- if "missing_calibration_part" not in task_name:
180
- expected_frames += FakeGQLClient.calibration_frames_doc_object
181
- for frame_set in expected_frames:
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(formatted_transfer_items) == len(source_filenames)
186
- for item in formatted_transfer_items:
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 test_build_parameter_file_transfer_items(transfer_l0_data_task):
141
+ def test_format_parameter_file_transfer_items(transfer_l0_data_task):
193
142
  """
194
- :Given: a TransferL0Data task with downloaded input dataset docs
195
- :When: building a list of parameter files formatted for transfer
196
- :Then: the correct items are correctly loaded into GlobusTransferItem objects
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
- transfer_objects = task.build_transfer_list(doc_tag=Tag.input_dataset_parameters())
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(formatted_transfer_items) == len(source_filenames)
217
- for transfer_item in formatted_transfer_items:
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
- FakeGQLClientMissingInputDatasetCalibrationPart,
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=FakeGQLClientMissingInputDatasetCalibrationPart,
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"]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dkist-processing-common
3
- Version: 10.8.1rc1
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.0
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
@@ -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=M7FW1viESaTfK1jLqHLp7JMGTGeoTxHtgCXRjZpDR8g,6990
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=AxS3AKjB22JZl9sSk2A5JI7-Yyb9dOXw84bTpYqbPoQ,2585
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=BBJBIBADAPQAskqS8Qh58DYEyFjY9GY9ZN8nrJ1EKHs,5364
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=dTup7mPTEmySXP0O3j4sPPY8Jqe2zf-3sr2hjeMatEY,9649
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=8dDOfnT46qavGW-6fy-FT9LVb0TXANSpk1WpACpWK70,5787
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=8KQ5LWa15mmjcoN0EgyaeLJS2qxeAowU5MC8IEIt4l4,22695
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=yTKijpQ-tNx_H2V_9HsZjMzkrzBDSQaSKkySV6VnnOM,11618
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=Rz1r2_by8aRZslSkS4AduEtpu3cpPxsAonZQyUCBPSQ,30867
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=FGhldrTdc28YD9FKrsW3lZ34LtvzecGP1qNi9fGHVGQ,22173
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=pQ01rWAkQ2XQojyHWzAqeOdrMXshNcgEVL5I_9bBTdo,9610
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=kNzX89vfrNRJ8d9rusMVv4DM9rPD3l-7HIstZsLoYBE,14033
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=B-kDsGJTUxxnamN4xjn69TFiY_TEN8MmhHNndP6bKac,10301
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=dihbnrqbmcQ-Lh34tdlwr4EFW4slGEcfBL-aQs8gtCo,22225
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.1rc1.dist-info/METADATA,sha256=rRARlrhMRte3nzFkBou8EOB8-1FONTMP2MZohKJ3wVw,7150
118
- dkist_processing_common-10.8.1rc1.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
119
- dkist_processing_common-10.8.1rc1.dist-info/top_level.txt,sha256=LJhd1W-Vn90K8HnQDIE4r52YDpUjjMWDnllAWHBByW0,48
120
- dkist_processing_common-10.8.1rc1.dist-info/RECORD,,
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,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.7.1)
2
+ Generator: setuptools (80.9.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
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
@@ -1,2 +0,0 @@
1
- Change the behavior of ParameterBase such that it takes the task scratch as an argument to provide access to the
2
- parameter document and parameters that are files. This behavior replaces the input dataset mixin parameter read method.
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