dkist-processing-common 10.5.4__py3-none-any.whl → 12.1.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/280.misc.rst +1 -0
- changelog/282.feature.2.rst +2 -0
- changelog/282.feature.rst +2 -0
- changelog/284.feature.rst +1 -0
- changelog/285.feature.rst +2 -0
- changelog/285.misc.rst +2 -0
- changelog/286.feature.rst +2 -0
- changelog/287.misc.rst +1 -0
- dkist_processing_common/__init__.py +1 -0
- dkist_processing_common/_util/constants.py +1 -0
- dkist_processing_common/_util/graphql.py +1 -0
- dkist_processing_common/_util/scratch.py +9 -9
- dkist_processing_common/_util/tags.py +1 -0
- dkist_processing_common/codecs/array.py +20 -0
- dkist_processing_common/codecs/asdf.py +9 -3
- dkist_processing_common/codecs/basemodel.py +22 -0
- dkist_processing_common/codecs/bytes.py +1 -0
- dkist_processing_common/codecs/fits.py +37 -9
- dkist_processing_common/codecs/iobase.py +1 -0
- dkist_processing_common/codecs/json.py +1 -0
- dkist_processing_common/codecs/path.py +1 -0
- dkist_processing_common/codecs/quality.py +1 -1
- dkist_processing_common/codecs/str.py +1 -0
- dkist_processing_common/config.py +64 -25
- dkist_processing_common/manual.py +6 -8
- dkist_processing_common/models/constants.py +373 -37
- dkist_processing_common/models/dkist_location.py +27 -0
- dkist_processing_common/models/fits_access.py +48 -0
- dkist_processing_common/models/flower_pot.py +231 -9
- dkist_processing_common/models/fried_parameter.py +41 -0
- dkist_processing_common/models/graphql.py +66 -75
- dkist_processing_common/models/input_dataset.py +117 -0
- dkist_processing_common/models/message.py +1 -1
- dkist_processing_common/models/message_queue_binding.py +1 -1
- dkist_processing_common/models/metric_code.py +2 -0
- dkist_processing_common/models/parameters.py +65 -28
- dkist_processing_common/models/quality.py +50 -5
- dkist_processing_common/models/tags.py +23 -21
- dkist_processing_common/models/task_name.py +3 -2
- dkist_processing_common/models/telemetry.py +28 -0
- dkist_processing_common/models/wavelength.py +3 -1
- dkist_processing_common/parsers/average_bud.py +46 -0
- dkist_processing_common/parsers/cs_step.py +13 -12
- dkist_processing_common/parsers/dsps_repeat.py +6 -4
- dkist_processing_common/parsers/experiment_id_bud.py +12 -4
- dkist_processing_common/parsers/id_bud.py +42 -27
- dkist_processing_common/parsers/l0_fits_access.py +5 -3
- dkist_processing_common/parsers/l1_fits_access.py +51 -23
- dkist_processing_common/parsers/lookup_bud.py +125 -0
- dkist_processing_common/parsers/near_bud.py +21 -20
- dkist_processing_common/parsers/observing_program_id_bud.py +24 -0
- dkist_processing_common/parsers/proposal_id_bud.py +13 -5
- dkist_processing_common/parsers/quality.py +2 -0
- dkist_processing_common/parsers/retarder.py +32 -0
- dkist_processing_common/parsers/single_value_single_key_flower.py +6 -1
- dkist_processing_common/parsers/task.py +8 -6
- dkist_processing_common/parsers/time.py +178 -72
- dkist_processing_common/parsers/unique_bud.py +21 -22
- dkist_processing_common/parsers/wavelength.py +5 -3
- dkist_processing_common/tasks/__init__.py +3 -2
- dkist_processing_common/tasks/assemble_movie.py +4 -3
- dkist_processing_common/tasks/base.py +59 -60
- dkist_processing_common/tasks/l1_output_data.py +54 -53
- dkist_processing_common/tasks/mixin/globus.py +24 -27
- dkist_processing_common/tasks/mixin/interservice_bus.py +1 -0
- dkist_processing_common/tasks/mixin/metadata_store.py +108 -243
- dkist_processing_common/tasks/mixin/object_store.py +22 -0
- dkist_processing_common/tasks/mixin/quality/__init__.py +1 -0
- dkist_processing_common/tasks/mixin/quality/_base.py +8 -1
- dkist_processing_common/tasks/mixin/quality/_metrics.py +166 -14
- dkist_processing_common/tasks/output_data_base.py +4 -3
- dkist_processing_common/tasks/parse_l0_input_data.py +277 -15
- dkist_processing_common/tasks/quality_metrics.py +9 -9
- dkist_processing_common/tasks/teardown.py +7 -7
- dkist_processing_common/tasks/transfer_input_data.py +67 -69
- dkist_processing_common/tasks/trial_catalog.py +77 -17
- dkist_processing_common/tasks/trial_output_data.py +16 -17
- dkist_processing_common/tasks/write_l1.py +102 -72
- dkist_processing_common/tests/conftest.py +32 -173
- dkist_processing_common/tests/mock_metadata_store.py +271 -0
- dkist_processing_common/tests/test_assemble_movie.py +4 -4
- dkist_processing_common/tests/test_assemble_quality.py +32 -4
- dkist_processing_common/tests/test_base.py +5 -19
- dkist_processing_common/tests/test_codecs.py +103 -12
- dkist_processing_common/tests/test_constants.py +15 -0
- dkist_processing_common/tests/test_dkist_location.py +15 -0
- dkist_processing_common/tests/test_fits_access.py +56 -19
- dkist_processing_common/tests/test_flower_pot.py +147 -5
- dkist_processing_common/tests/test_fried_parameter.py +27 -0
- dkist_processing_common/tests/test_input_dataset.py +78 -361
- dkist_processing_common/tests/test_interservice_bus.py +1 -0
- dkist_processing_common/tests/test_interservice_bus_mixin.py +1 -1
- dkist_processing_common/tests/test_manual_processing.py +33 -0
- dkist_processing_common/tests/test_output_data_base.py +5 -7
- dkist_processing_common/tests/test_parameters.py +71 -22
- dkist_processing_common/tests/test_parse_l0_input_data.py +115 -32
- dkist_processing_common/tests/test_publish_catalog_messages.py +2 -24
- dkist_processing_common/tests/test_quality.py +1 -0
- dkist_processing_common/tests/test_quality_mixin.py +255 -23
- dkist_processing_common/tests/test_scratch.py +2 -1
- dkist_processing_common/tests/test_stems.py +511 -168
- dkist_processing_common/tests/test_submit_dataset_metadata.py +3 -7
- dkist_processing_common/tests/test_tags.py +1 -0
- dkist_processing_common/tests/test_task_name.py +1 -1
- dkist_processing_common/tests/test_task_parsing.py +17 -7
- dkist_processing_common/tests/test_teardown.py +28 -24
- dkist_processing_common/tests/test_transfer_input_data.py +270 -125
- dkist_processing_common/tests/test_transfer_l1_output_data.py +2 -3
- dkist_processing_common/tests/test_trial_catalog.py +83 -8
- dkist_processing_common/tests/test_trial_output_data.py +46 -73
- dkist_processing_common/tests/test_workflow_task_base.py +8 -10
- dkist_processing_common/tests/test_write_l1.py +298 -76
- dkist_processing_common-12.1.0rc1.dist-info/METADATA +265 -0
- dkist_processing_common-12.1.0rc1.dist-info/RECORD +134 -0
- {dkist_processing_common-10.5.4.dist-info → dkist_processing_common-12.1.0rc1.dist-info}/WHEEL +1 -1
- docs/conf.py +1 -0
- docs/index.rst +1 -1
- docs/landing_page.rst +13 -0
- dkist_processing_common/tasks/mixin/input_dataset.py +0 -166
- dkist_processing_common-10.5.4.dist-info/METADATA +0 -175
- dkist_processing_common-10.5.4.dist-info/RECORD +0 -112
- {dkist_processing_common-10.5.4.dist-info → dkist_processing_common-12.1.0rc1.dist-info}/top_level.txt +0 -0
|
@@ -7,6 +7,7 @@ HOW TO WRITE TESTS FOR NEW PARAMETER SUBCLASSES :
|
|
|
7
7
|
4. Add a `pytest.param` with this helper function to `test_parameters` to make sure none of the default stuff broke
|
|
8
8
|
5. Write a new test that only uses the helper function to test the new functionality.
|
|
9
9
|
"""
|
|
10
|
+
|
|
10
11
|
import json
|
|
11
12
|
from datetime import datetime
|
|
12
13
|
from datetime import timedelta
|
|
@@ -18,22 +19,21 @@ import numpy as np
|
|
|
18
19
|
import pytest
|
|
19
20
|
from astropy.io import fits
|
|
20
21
|
|
|
22
|
+
from dkist_processing_common.codecs.array import array_encoder
|
|
23
|
+
from dkist_processing_common.codecs.fits import fits_hdulist_encoder
|
|
21
24
|
from dkist_processing_common.models.parameters import ParameterArmIdMixin
|
|
22
25
|
from dkist_processing_common.models.parameters import ParameterBase
|
|
23
26
|
from dkist_processing_common.models.parameters import ParameterWavelengthMixin
|
|
24
27
|
from dkist_processing_common.models.tags import Tag
|
|
25
28
|
from dkist_processing_common.tasks import WorkflowTaskBase
|
|
26
|
-
from dkist_processing_common.
|
|
29
|
+
from dkist_processing_common.tests.test_input_dataset import input_dataset_frames_part_factory
|
|
30
|
+
|
|
31
|
+
FITS_FILE = "fits.dat"
|
|
32
|
+
NP_FILE = "np.npy"
|
|
27
33
|
|
|
28
34
|
|
|
29
35
|
@pytest.fixture
|
|
30
|
-
def input_dataset_parameters(
|
|
31
|
-
fits_file_path = tmp_path / "fits.dat"
|
|
32
|
-
phdu = fits.PrimaryHDU(np.ones((3, 3)) * 3)
|
|
33
|
-
ihdu = fits.ImageHDU(np.ones((4, 4)) * 4)
|
|
34
|
-
fits.HDUList([phdu, ihdu]).writeto(fits_file_path)
|
|
35
|
-
np_file_path = tmp_path / "np.npy"
|
|
36
|
-
np.save(np_file_path, np.ones((3, 3)) * 4)
|
|
36
|
+
def input_dataset_parameters():
|
|
37
37
|
return [
|
|
38
38
|
{
|
|
39
39
|
"parameterName": "basic_param",
|
|
@@ -106,7 +106,15 @@ def input_dataset_parameters(tmp_path):
|
|
|
106
106
|
"parameterValues": [
|
|
107
107
|
{
|
|
108
108
|
"parameterValueId": 1,
|
|
109
|
-
"parameterValue": json.dumps(
|
|
109
|
+
"parameterValue": json.dumps(
|
|
110
|
+
{
|
|
111
|
+
"__file__": {
|
|
112
|
+
"bucket": "not_used",
|
|
113
|
+
"objectKey": "not_used",
|
|
114
|
+
"tag": Tag.parameter(FITS_FILE),
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
),
|
|
110
118
|
}
|
|
111
119
|
],
|
|
112
120
|
},
|
|
@@ -115,7 +123,15 @@ def input_dataset_parameters(tmp_path):
|
|
|
115
123
|
"parameterValues": [
|
|
116
124
|
{
|
|
117
125
|
"parameterValueId": 1,
|
|
118
|
-
"parameterValue": json.dumps(
|
|
126
|
+
"parameterValue": json.dumps(
|
|
127
|
+
{
|
|
128
|
+
"__file__": {
|
|
129
|
+
"bucket": "not_used",
|
|
130
|
+
"objectKey": "not_used",
|
|
131
|
+
"tag": Tag.parameter(NP_FILE),
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
),
|
|
119
135
|
}
|
|
120
136
|
],
|
|
121
137
|
},
|
|
@@ -129,16 +145,14 @@ def input_dataset_parts(input_dataset_parameters) -> tuple[Any, str]:
|
|
|
129
145
|
|
|
130
146
|
@pytest.fixture()
|
|
131
147
|
def task_class_with_parameters(parameter_class) -> Type[WorkflowTaskBase]:
|
|
132
|
-
class TaskWithParameters(WorkflowTaskBase
|
|
148
|
+
class TaskWithParameters(WorkflowTaskBase):
|
|
133
149
|
def __init__(self, recipe_run_id: int, workflow_name: str, workflow_version: str):
|
|
134
150
|
super().__init__(
|
|
135
151
|
recipe_run_id=recipe_run_id,
|
|
136
152
|
workflow_name=workflow_name,
|
|
137
153
|
workflow_version=workflow_version,
|
|
138
154
|
)
|
|
139
|
-
self.parameters = parameter_class(
|
|
140
|
-
input_dataset_parameters=self.input_dataset_parameters
|
|
141
|
-
)
|
|
155
|
+
self.parameters = parameter_class(scratch=self.scratch)
|
|
142
156
|
|
|
143
157
|
def run(self) -> None:
|
|
144
158
|
pass
|
|
@@ -149,11 +163,21 @@ def task_class_with_parameters(parameter_class) -> Type[WorkflowTaskBase]:
|
|
|
149
163
|
@pytest.fixture()
|
|
150
164
|
def task_with_parameters(task_with_input_dataset, task_class_with_parameters):
|
|
151
165
|
task_class = task_class_with_parameters
|
|
152
|
-
|
|
166
|
+
with task_class(
|
|
153
167
|
recipe_run_id=task_with_input_dataset.recipe_run_id,
|
|
154
168
|
workflow_name=task_with_input_dataset.workflow_name,
|
|
155
169
|
workflow_version=task_with_input_dataset.workflow_version,
|
|
156
|
-
)
|
|
170
|
+
) as task:
|
|
171
|
+
phdu = fits.PrimaryHDU(np.ones((3, 3)) * 3)
|
|
172
|
+
ihdu = fits.ImageHDU(np.ones((4, 4)) * 4)
|
|
173
|
+
task.write(
|
|
174
|
+
data=fits.HDUList([phdu, ihdu]),
|
|
175
|
+
tags=Tag.parameter(FITS_FILE),
|
|
176
|
+
encoder=fits_hdulist_encoder,
|
|
177
|
+
)
|
|
178
|
+
task.write(data=np.ones((3, 3)) * 4, tags=Tag.parameter(NP_FILE), encoder=array_encoder)
|
|
179
|
+
yield task
|
|
180
|
+
task._purge()
|
|
157
181
|
|
|
158
182
|
|
|
159
183
|
class FilledParametersNoObsTime(ParameterBase):
|
|
@@ -182,18 +206,18 @@ class FilledParametersWithObsTime(ParameterBase):
|
|
|
182
206
|
|
|
183
207
|
@property
|
|
184
208
|
def fits_file_parameter(self):
|
|
185
|
-
|
|
186
|
-
return self._load_param_value_from_fits(
|
|
209
|
+
param_obj = self._find_most_recent_past_value("fits_file_parameter")
|
|
210
|
+
return self._load_param_value_from_fits(param_obj=param_obj)
|
|
187
211
|
|
|
188
212
|
@property
|
|
189
213
|
def non_primary_fits_file_parameter(self):
|
|
190
|
-
|
|
191
|
-
return self._load_param_value_from_fits(
|
|
214
|
+
param_obj = self._find_most_recent_past_value("fits_file_parameter")
|
|
215
|
+
return self._load_param_value_from_fits(param_obj=param_obj, hdu=1)
|
|
192
216
|
|
|
193
217
|
@property
|
|
194
218
|
def numpy_file_parameter(self):
|
|
195
|
-
|
|
196
|
-
return self._load_param_value_from_numpy_save(
|
|
219
|
+
param_obj = self._find_most_recent_past_value("numpy_file_parameter")
|
|
220
|
+
return self._load_param_value_from_numpy_save(param_obj=param_obj)
|
|
197
221
|
|
|
198
222
|
|
|
199
223
|
def parameter_class_with_obs_ip_start_time():
|
|
@@ -343,3 +367,28 @@ def test_mixins_error_with_no_arg():
|
|
|
343
367
|
"""
|
|
344
368
|
with pytest.raises(TypeError):
|
|
345
369
|
parameters = FilledWavelengthParameters(input_dataset_parameters={"foo": []})
|
|
370
|
+
|
|
371
|
+
|
|
372
|
+
@pytest.mark.parametrize(
|
|
373
|
+
("input_dataset_parts", "parameter_class"),
|
|
374
|
+
[
|
|
375
|
+
pytest.param(
|
|
376
|
+
[
|
|
377
|
+
(input_dataset_frames_part_factory(), Tag.input_dataset_parameters()),
|
|
378
|
+
(input_dataset_frames_part_factory(), Tag.input_dataset_parameters()),
|
|
379
|
+
],
|
|
380
|
+
parameter_class_with_obs_ip_start_time(),
|
|
381
|
+
id="two_param_docs",
|
|
382
|
+
),
|
|
383
|
+
],
|
|
384
|
+
)
|
|
385
|
+
def test_multiple_input_dataset_parameter_parts(
|
|
386
|
+
request, input_dataset_parts: list[tuple[Any, str]], parameter_class
|
|
387
|
+
):
|
|
388
|
+
"""
|
|
389
|
+
Given: a task with multiple tagged input dataset parameter docs
|
|
390
|
+
When: initializing the parameter base
|
|
391
|
+
Then: an error is raised
|
|
392
|
+
"""
|
|
393
|
+
with pytest.raises(ValueError, match="more than one parameter file"):
|
|
394
|
+
request.getfixturevalue("task_with_parameters")
|
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
"""Tests for the parse L0 input data task"""
|
|
2
|
+
|
|
3
|
+
from enum import StrEnum
|
|
4
|
+
|
|
2
5
|
import numpy as np
|
|
3
6
|
import pytest
|
|
4
7
|
from astropy.io import fits
|
|
@@ -9,16 +12,20 @@ from dkist_processing_common._util.scratch import WorkflowFileSystem
|
|
|
9
12
|
from dkist_processing_common.codecs.fits import fits_hdulist_encoder
|
|
10
13
|
from dkist_processing_common.models.constants import BudName
|
|
11
14
|
from dkist_processing_common.models.fits_access import FitsAccessBase
|
|
15
|
+
from dkist_processing_common.models.flower_pot import ListStem
|
|
16
|
+
from dkist_processing_common.models.flower_pot import SetStem
|
|
12
17
|
from dkist_processing_common.models.flower_pot import SpilledDirt
|
|
13
18
|
from dkist_processing_common.models.flower_pot import Stem
|
|
14
19
|
from dkist_processing_common.models.flower_pot import Thorn
|
|
15
20
|
from dkist_processing_common.models.tags import StemName
|
|
16
21
|
from dkist_processing_common.models.tags import Tag
|
|
22
|
+
from dkist_processing_common.parsers.lookup_bud import TimeLookupBud
|
|
17
23
|
from dkist_processing_common.parsers.single_value_single_key_flower import (
|
|
18
24
|
SingleValueSingleKeyFlower,
|
|
19
25
|
)
|
|
20
26
|
from dkist_processing_common.parsers.unique_bud import UniqueBud
|
|
21
27
|
from dkist_processing_common.tasks.parse_l0_input_data import ParseL0InputDataBase
|
|
28
|
+
from dkist_processing_common.tasks.parse_l0_input_data import default_constant_bud_factory
|
|
22
29
|
|
|
23
30
|
|
|
24
31
|
class VispHeaders(Spec122Dataset):
|
|
@@ -84,25 +91,44 @@ class VispHeaders(Spec122Dataset):
|
|
|
84
91
|
return self.index % self.num_mod
|
|
85
92
|
|
|
86
93
|
|
|
94
|
+
class ViSPMetadataKey(StrEnum):
|
|
95
|
+
num_mod = "VISP_010"
|
|
96
|
+
modstate = "VISP_011"
|
|
97
|
+
ip_task_type = "DKIST004"
|
|
98
|
+
|
|
99
|
+
|
|
87
100
|
class ViSPFitsAccess(FitsAccessBase):
|
|
88
101
|
def __init__(self, hdu, name, auto_squeeze=False):
|
|
89
102
|
super().__init__(hdu, name, auto_squeeze=auto_squeeze)
|
|
90
|
-
self.num_mod: int = self.header[
|
|
91
|
-
self.modstate: int = self.header[
|
|
92
|
-
self.ip_task_type: str = self.header[
|
|
103
|
+
self.num_mod: int = self.header[ViSPMetadataKey.num_mod]
|
|
104
|
+
self.modstate: int = self.header[ViSPMetadataKey.modstate]
|
|
105
|
+
self.ip_task_type: str = self.header[ViSPMetadataKey.ip_task_type]
|
|
93
106
|
self.name = name
|
|
94
107
|
|
|
95
108
|
|
|
96
109
|
@pytest.fixture(scope="function")
|
|
97
110
|
def visp_flowers():
|
|
98
111
|
return [
|
|
99
|
-
SingleValueSingleKeyFlower(
|
|
112
|
+
SingleValueSingleKeyFlower(
|
|
113
|
+
tag_stem_name=StemName.modstate, metadata_key=ViSPMetadataKey.modstate
|
|
114
|
+
)
|
|
100
115
|
]
|
|
101
116
|
|
|
102
117
|
|
|
103
118
|
@pytest.fixture(scope="function")
|
|
104
119
|
def visp_buds():
|
|
105
|
-
return [UniqueBud(constant_name=BudName.num_modstates
|
|
120
|
+
return [UniqueBud(constant_name=BudName.num_modstates, metadata_key=ViSPMetadataKey.num_mod)]
|
|
121
|
+
|
|
122
|
+
|
|
123
|
+
@pytest.fixture(scope="function")
|
|
124
|
+
def visp_lookup_buds():
|
|
125
|
+
return [
|
|
126
|
+
TimeLookupBud(
|
|
127
|
+
constant_name="LOOKUP_BUD",
|
|
128
|
+
key_metadata_key=ViSPMetadataKey.num_mod,
|
|
129
|
+
value_metadata_key=ViSPMetadataKey.modstate,
|
|
130
|
+
)
|
|
131
|
+
]
|
|
106
132
|
|
|
107
133
|
|
|
108
134
|
@pytest.fixture(scope="function")
|
|
@@ -132,7 +158,27 @@ def empty_buds():
|
|
|
132
158
|
def getter(self, key):
|
|
133
159
|
pass # We'll never get here because we spilled the dirt
|
|
134
160
|
|
|
135
|
-
|
|
161
|
+
class EmptyListBud(ListStem):
|
|
162
|
+
def __init__(self):
|
|
163
|
+
super().__init__(stem_name="EMPTY_LIST_BUD")
|
|
164
|
+
|
|
165
|
+
def setter(self, value):
|
|
166
|
+
return SpilledDirt
|
|
167
|
+
|
|
168
|
+
def getter(self):
|
|
169
|
+
pass
|
|
170
|
+
|
|
171
|
+
class EmptySetBud(SetStem):
|
|
172
|
+
def __init__(self):
|
|
173
|
+
super().__init__(stem_name="EMPTY_SET_BUD")
|
|
174
|
+
|
|
175
|
+
def setter(self, value):
|
|
176
|
+
return SpilledDirt
|
|
177
|
+
|
|
178
|
+
def getter(self):
|
|
179
|
+
pass
|
|
180
|
+
|
|
181
|
+
return [EmptyBud(), EmptyListBud(), EmptySetBud()]
|
|
136
182
|
|
|
137
183
|
|
|
138
184
|
@pytest.fixture()
|
|
@@ -149,8 +195,17 @@ def picky_buds():
|
|
|
149
195
|
|
|
150
196
|
@pytest.fixture(scope="function")
|
|
151
197
|
def parse_inputs_task(
|
|
152
|
-
tmp_path,
|
|
198
|
+
tmp_path,
|
|
199
|
+
visp_flowers,
|
|
200
|
+
visp_buds,
|
|
201
|
+
visp_lookup_buds,
|
|
202
|
+
empty_flowers,
|
|
203
|
+
empty_buds,
|
|
204
|
+
picky_buds,
|
|
205
|
+
recipe_run_id,
|
|
153
206
|
):
|
|
207
|
+
"""Override parse task class and make data for testing."""
|
|
208
|
+
|
|
154
209
|
class TaskClass(ParseL0InputDataBase):
|
|
155
210
|
@property
|
|
156
211
|
def tag_flowers(self):
|
|
@@ -158,7 +213,7 @@ def parse_inputs_task(
|
|
|
158
213
|
|
|
159
214
|
@property
|
|
160
215
|
def constant_buds(self):
|
|
161
|
-
return visp_buds + empty_buds + picky_buds
|
|
216
|
+
return visp_buds + visp_lookup_buds + empty_buds + picky_buds
|
|
162
217
|
|
|
163
218
|
@property
|
|
164
219
|
def fits_parsing_class(self):
|
|
@@ -198,6 +253,8 @@ def parse_inputs_task(
|
|
|
198
253
|
|
|
199
254
|
@pytest.fixture()
|
|
200
255
|
def visp_parse_inputs_task(tmp_path, visp_flowers, visp_buds, recipe_run_id):
|
|
256
|
+
"""Extend parse task class, but don't make data for testing."""
|
|
257
|
+
|
|
201
258
|
class TaskClass(ParseL0InputDataBase):
|
|
202
259
|
@property
|
|
203
260
|
def tag_flowers(self):
|
|
@@ -231,12 +288,15 @@ def test_make_flowerpots(parse_inputs_task):
|
|
|
231
288
|
tag_pot, constant_pot = parse_inputs_task.make_flower_pots()
|
|
232
289
|
|
|
233
290
|
assert len(tag_pot.stems) == 2
|
|
234
|
-
assert len(constant_pot.stems) ==
|
|
235
|
-
assert tag_pot.stems[0].stem_name == StemName.modstate
|
|
291
|
+
assert len(constant_pot.stems) == 6
|
|
292
|
+
assert tag_pot.stems[0].stem_name == StemName.modstate
|
|
236
293
|
assert tag_pot.stems[1].stem_name == "EMPTY_FLOWER"
|
|
237
|
-
assert constant_pot.stems[0].stem_name == BudName.num_modstates
|
|
238
|
-
assert constant_pot.stems[1].stem_name == "
|
|
239
|
-
assert constant_pot.stems[2].stem_name == "
|
|
294
|
+
assert constant_pot.stems[0].stem_name == BudName.num_modstates
|
|
295
|
+
assert constant_pot.stems[1].stem_name == "LOOKUP_BUD"
|
|
296
|
+
assert constant_pot.stems[2].stem_name == "EMPTY_BUD"
|
|
297
|
+
assert constant_pot.stems[3].stem_name == "EMPTY_LIST_BUD"
|
|
298
|
+
assert constant_pot.stems[4].stem_name == "EMPTY_SET_BUD"
|
|
299
|
+
assert constant_pot.stems[5].stem_name == "PICKY_BUD"
|
|
240
300
|
|
|
241
301
|
|
|
242
302
|
def test_subclass_flowers(visp_parse_inputs_task, max_cs_step_time_sec):
|
|
@@ -248,36 +308,59 @@ def test_subclass_flowers(visp_parse_inputs_task, max_cs_step_time_sec):
|
|
|
248
308
|
tag_pot, constant_pot = visp_parse_inputs_task.make_flower_pots()
|
|
249
309
|
|
|
250
310
|
assert len(tag_pot.stems) == 1
|
|
251
|
-
assert len(constant_pot.stems) ==
|
|
252
|
-
|
|
253
|
-
assert sorted([f.stem_name for f in
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
311
|
+
assert len(constant_pot.stems) == 61
|
|
312
|
+
all_flower_names = [StemName.modstate]
|
|
313
|
+
assert sorted([f.stem_name for f in tag_pot.stems]) == sorted(all_flower_names)
|
|
314
|
+
all_bud_names = [b.stem_name for b in default_constant_bud_factory()] + [BudName.num_modstates]
|
|
315
|
+
assert sorted([f.stem_name for f in constant_pot.stems]) == sorted(all_bud_names)
|
|
316
|
+
|
|
317
|
+
|
|
318
|
+
def test_dataset_extra_bud_factory(visp_parse_inputs_task, max_cs_step_time_sec):
|
|
319
|
+
"""
|
|
320
|
+
Given: ParseInputData child class with custom stems
|
|
321
|
+
When: Making the constant pot
|
|
322
|
+
Then: The multi-task dataset extra buds are created
|
|
323
|
+
"""
|
|
324
|
+
_, constant_pot = visp_parse_inputs_task.make_flower_pots()
|
|
325
|
+
stem_names = [f.stem_name.value for f in constant_pot.stems]
|
|
326
|
+
bud_name_base = [
|
|
327
|
+
"DATE_BEGIN",
|
|
328
|
+
"OBSERVING_PROGRAM_EXECUTION_IDS",
|
|
329
|
+
"NUM_RAW_FRAMES_PER_FPA",
|
|
330
|
+
"TELESCOPE_TRACKING_MODE",
|
|
331
|
+
"COUDE_TABLE_TRACKING_MODE",
|
|
332
|
+
"TELESCOPE_SCANNING_MODE",
|
|
333
|
+
"AVERAGE_LIGHT_LEVEL",
|
|
334
|
+
"AVERAGE_TELESCOPE_ELEVATION",
|
|
335
|
+
"AVERAGE_COUDE_TABLE_ANGLE",
|
|
336
|
+
"AVERAGE_TELESCOPE_AZIMUTH",
|
|
337
|
+
"GOS_LEVEL3_STATUS",
|
|
338
|
+
"GOS_LEVEL3_LAMP_STATUS",
|
|
339
|
+
"GOS_POLARIZER_STATUS",
|
|
340
|
+
"GOS_POLARIZER_ANGLE",
|
|
341
|
+
"GOS_RETARDER_STATUS",
|
|
342
|
+
"GOS_RETARDER_ANGLE",
|
|
343
|
+
"GOS_LEVEL0_STATUS",
|
|
344
|
+
]
|
|
345
|
+
for base in bud_name_base:
|
|
346
|
+
assert "SOLAR_GAIN_" + base in stem_names
|
|
347
|
+
# telescope mode keys are not constant for dark frames
|
|
348
|
+
assert ("DARK_" + base in stem_names) ^ ("MODE" in base)
|
|
349
|
+
# gos keys are not constant for polcal frames
|
|
350
|
+
assert ("POLCAL_" + base in stem_names) ^ ("GOS" in base)
|
|
269
351
|
|
|
270
352
|
|
|
271
353
|
def test_constants_correct(parse_inputs_task):
|
|
272
354
|
"""
|
|
273
355
|
Given: ParseInputData task with a populated constant FlowerPot
|
|
274
356
|
When: Updating pipeline constants
|
|
275
|
-
Then:
|
|
357
|
+
Then: A pipeline constant is correctly populated and the values return correctly
|
|
276
358
|
"""
|
|
277
359
|
_, constant_pot = parse_inputs_task.make_flower_pots()
|
|
278
360
|
parse_inputs_task.update_constants(constant_pot)
|
|
279
361
|
assert dict(parse_inputs_task.constants._db_dict) == {
|
|
280
362
|
BudName.num_modstates.value: parse_inputs_task._num_mod,
|
|
363
|
+
"LOOKUP_BUD": {str(parse_inputs_task._num_mod): [0, 1]},
|
|
281
364
|
}
|
|
282
365
|
|
|
283
366
|
|
|
@@ -4,13 +4,12 @@ import pytest
|
|
|
4
4
|
|
|
5
5
|
from dkist_processing_common.models.message import CreateQualityReportMessage
|
|
6
6
|
from dkist_processing_common.tasks.l1_output_data import PublishCatalogAndQualityMessages
|
|
7
|
-
from dkist_processing_common.tests.conftest import FakeGQLClient
|
|
8
7
|
|
|
9
8
|
|
|
10
9
|
@pytest.fixture
|
|
11
|
-
def publish_catalog_and_quality_messages_task(recipe_run_id, mocker):
|
|
10
|
+
def publish_catalog_and_quality_messages_task(recipe_run_id, mocker, fake_gql_client):
|
|
12
11
|
mocker.patch(
|
|
13
|
-
"dkist_processing_common.tasks.mixin.metadata_store.GraphQLClient", new=
|
|
12
|
+
"dkist_processing_common.tasks.mixin.metadata_store.GraphQLClient", new=fake_gql_client
|
|
14
13
|
)
|
|
15
14
|
with PublishCatalogAndQualityMessages(
|
|
16
15
|
recipe_run_id=recipe_run_id,
|
|
@@ -58,24 +57,3 @@ def test_object_messages(publish_catalog_and_quality_messages_task):
|
|
|
58
57
|
assert message.body.conversationId == str(task.recipe_run_id)
|
|
59
58
|
assert message.body.objectType == object_type
|
|
60
59
|
assert message.body.groupId == task.constants.dataset_id
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
def test_quality_report_message(publish_catalog_and_quality_messages_task):
|
|
64
|
-
"""
|
|
65
|
-
:Given: a PublishCatalogAndQualityMessages task
|
|
66
|
-
:When: creating quality report message
|
|
67
|
-
:Then: the attributes are correctly populated
|
|
68
|
-
"""
|
|
69
|
-
# Given
|
|
70
|
-
task, proposal_id = publish_catalog_and_quality_messages_task
|
|
71
|
-
# When
|
|
72
|
-
message = task.quality_report_message
|
|
73
|
-
# Then
|
|
74
|
-
assert isinstance(message, CreateQualityReportMessage)
|
|
75
|
-
assert message.body.bucket == task.destination_bucket
|
|
76
|
-
# objectName exists and can be evaluated as a valid path
|
|
77
|
-
assert message.body.objectName
|
|
78
|
-
_ = Path(message.body.objectName)
|
|
79
|
-
assert message.body.datasetId == task.constants.dataset_id
|
|
80
|
-
assert message.body.conversationId == str(task.recipe_run_id)
|
|
81
|
-
assert message.body.incrementDatasetCatalogReceiptCount is True
|