dkist-processing-test 1.21.3rc1__py3-none-any.whl → 1.23.8rc1__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.

Potentially problematic release.


This version of dkist-processing-test might be problematic. Click here for more details.

@@ -1,3 +1,4 @@
1
+ import json
1
2
  from datetime import datetime
2
3
 
3
4
  import numpy as np
@@ -33,3 +34,18 @@ class TestParameters(ParameterBase, ParameterWavelengthMixin):
33
34
  def wavelength_category(self) -> str:
34
35
  """A dummy parameter that depends on wavelength."""
35
36
  return self._find_parameter_closest_wavelength("test_wavelength_category")
37
+
38
+ @property
39
+ def value_message(self) -> str:
40
+ """A dummy parameter that returns a message."""
41
+ return self._find_most_recent_past_value("test_message")
42
+
43
+ @property
44
+ def file_message(self) -> str:
45
+ """A dummy parameter that returns a message from a file."""
46
+ param_dict = self._find_most_recent_past_value("test_message_file")
47
+ file_path = param_dict["param_path"]
48
+ with open(file_path, "r") as f:
49
+ message = json.load(f)
50
+
51
+ return message
@@ -6,5 +6,4 @@ from dkist_processing_test.tasks.movie import *
6
6
  from dkist_processing_test.tasks.noop import *
7
7
  from dkist_processing_test.tasks.parse import *
8
8
  from dkist_processing_test.tasks.quality import *
9
- from dkist_processing_test.tasks.trial_output_data import *
10
9
  from dkist_processing_test.tasks.write_l1 import *
@@ -10,6 +10,7 @@ from dkist_processing_common.codecs.json import json_encoder
10
10
  from dkist_processing_common.models.tags import Tag
11
11
  from dkist_processing_common.tasks import WorkflowTaskBase
12
12
  from dkist_processing_common.tasks.mixin.input_dataset import InputDatasetMixin
13
+ from dkist_service_configuration.logging import logger
13
14
 
14
15
  from dkist_processing_test.models.parameters import TestParameters
15
16
 
@@ -57,10 +58,15 @@ class GenerateCalibratedData(WorkflowTaskBase, InputDatasetMixin):
57
58
 
58
59
  self.write(data={"test": "dictionary"}, tags=["BAZ"], encoder=json_encoder)
59
60
 
60
- with self.apm_task_step("Creating frames that won't be used"):
61
+ with self.apm_task_step(
62
+ "Creating frames that won't be used or transferred as trial outputs"
63
+ ):
61
64
  self.write(data=b"123", tags=[Tag.intermediate(), Tag.task("NOT_USED"), Tag.frame()])
62
65
  self.write(data=b"123", tags=["FOO"])
63
66
 
67
+ logger.info(f"Using {self.parameters.value_message = }")
68
+ logger.info(f"Using {self.parameters.file_message = }")
69
+
64
70
  with self.apm_task_step("Loop over inputs"):
65
71
  count = 1 # keep a running count to increment the dsps repeat number
66
72
  for hdu in self.read(tags=Tag.input(), decoder=fits_hdu_decoder):
@@ -81,6 +87,10 @@ class GenerateCalibratedData(WorkflowTaskBase, InputDatasetMixin):
81
87
  header["VBINMOSC"] = self.constants.num_dsps_repeats
82
88
  header["VBICMOSC"] = count
83
89
 
90
+ # Sneak date-dependent parameter values into header for end-to-end checking
91
+ header["CAM_ID"] = self.parameters.file_message
92
+ header["CAMERA"] = self.parameters.value_message
93
+
84
94
  output_hdu = fits.PrimaryHDU(data=data, header=header)
85
95
 
86
96
  wavelength_category = self.parameters.wavelength_category
@@ -48,10 +48,20 @@ def generate_214_l0_fits_frame(
48
48
 
49
49
 
50
50
  @pytest.fixture(scope="session")
51
- def parameter_file_object_key() -> str:
51
+ def array_parameter_file_object_key() -> str:
52
52
  return "random.fits"
53
53
 
54
54
 
55
+ @pytest.fixture(scope="session")
56
+ def early_json_parameter_file_object_key() -> str:
57
+ return "early_message.json"
58
+
59
+
60
+ @pytest.fixture(scope="session")
61
+ def late_json_parameter_file_object_key() -> str:
62
+ return "late_message.json"
63
+
64
+
55
65
  @pytest.fixture(scope="session")
56
66
  def random_parameter_hdulist() -> (fits.HDUList, float, float, float):
57
67
  rng = np.random.default_rng()
@@ -62,3 +72,33 @@ def random_parameter_hdulist() -> (fits.HDUList, float, float, float):
62
72
  hdul = fits.HDUList([fits.PrimaryHDU(rand_data), fits.ImageHDU(const_data)])
63
73
 
64
74
  return hdul, mu, std, const
75
+
76
+
77
+ @pytest.fixture(scope="session")
78
+ def early_file_message_str() -> str:
79
+ return "Early in a file"
80
+
81
+
82
+ @pytest.fixture(scope="session")
83
+ def late_file_message_str() -> str:
84
+ return "Late in a file"
85
+
86
+
87
+ @pytest.fixture(scope="session")
88
+ def early_value_message_str() -> str:
89
+ return "Early"
90
+
91
+
92
+ @pytest.fixture(scope="session")
93
+ def late_value_message_str() -> str:
94
+ return "Late"
95
+
96
+
97
+ @pytest.fixture(scope="session")
98
+ def early_date() -> str:
99
+ return "1980-01-01"
100
+
101
+
102
+ @pytest.fixture(scope="session")
103
+ def late_date() -> str:
104
+ return "2000-01-01"
@@ -0,0 +1,130 @@
1
+ import json
2
+ from datetime import datetime
3
+ from random import randint
4
+ from typing import Any
5
+ from typing import Union
6
+
7
+ from pydantic import BaseModel
8
+ from pydantic import ConfigDict
9
+ from pydantic import Field
10
+ from pydantic import field_serializer
11
+ from pydantic import field_validator
12
+ from pydantic import model_serializer
13
+
14
+ param_value_type_hint = Union[
15
+ int, str, list, tuple, "WavelengthParameterValue", "RawFileParameterValue"
16
+ ]
17
+ multi_str_type = Union[str, "MultipleParameterValues"]
18
+ multi_file_type = Union["RawFileParameterValue", "MultipleParameterValues"]
19
+ multi_wave_type = Union["WavelengthParameterValue", "MultipleParameterValues"]
20
+
21
+
22
+ class ParameterValue(BaseModel):
23
+ """A single parameterValue entry"""
24
+
25
+ parameterValue: param_value_type_hint
26
+ parameterValueId: int = Field(default_factory=lambda: randint(1000, 2000))
27
+ parameterValueStartDate: datetime = datetime(1946, 11, 20)
28
+
29
+ @field_serializer("parameterValue")
30
+ def json_parameter_value(self, parameter_value: param_value_type_hint) -> str:
31
+ """Encode the actual value in a JSON string."""
32
+ try:
33
+ parameter_value = parameter_value.model_dump()
34
+ except:
35
+ # If the value is just a basic type (i.e., not a `BaseModel`)
36
+ pass
37
+ return json.dumps(parameter_value)
38
+
39
+ @field_serializer("parameterValueStartDate")
40
+ def datetime_iso_format(self, start_datetime: datetime) -> str:
41
+ """Encode the start date as an ISO-formatted string."""
42
+ return start_datetime.isoformat()
43
+
44
+
45
+ class MultipleParameterValues(BaseModel):
46
+ """
47
+ Container for a list of parameterValues.
48
+
49
+ This exists to be different than a raw `list`, which is a valid `parameterValue.parameterValue` type
50
+ """
51
+
52
+ parameter_value_list: list[ParameterValue]
53
+
54
+ @field_validator("parameter_value_list", mode="before")
55
+ @classmethod
56
+ def ensure_list_of_parameter_values(cls, input_list: list) -> list[ParameterValue]:
57
+ """Convert any raw types to `ParameterValue` objects."""
58
+ output_list = []
59
+ for parameter_value in input_list:
60
+ if not isinstance(parameter_value, ParameterValue):
61
+ parameter_value = ParameterValue(parameterValue=parameter_value)
62
+
63
+ output_list.append(parameter_value)
64
+
65
+ return output_list
66
+
67
+ @field_validator("parameter_value_list")
68
+ @classmethod
69
+ def no_repeat_start_dates(
70
+ cls, parameter_value_list: list[ParameterValue]
71
+ ) -> list[ParameterValue]:
72
+ """Fail validation if any of the `ParameterValues` have the same `parameterValueStartDate."""
73
+ start_dates = [pv.parameterValueStartDate for pv in parameter_value_list]
74
+ if len(set(start_dates)) != len(start_dates):
75
+ raise ValueError(
76
+ f"parameterValueStartDates must be unique. Got {set(start_dates)} over {len(start_dates)} parameters."
77
+ )
78
+
79
+ return parameter_value_list
80
+
81
+ @model_serializer
82
+ def parameter_value_list(self):
83
+ """Return just the list of `ParameterValues`."""
84
+ return self.parameter_value_list
85
+
86
+
87
+ class WavelengthParameterValue(BaseModel):
88
+ values: tuple
89
+ wavelength: tuple = (1.0, 2.0, 3.0)
90
+
91
+
92
+ class RawFileParameterValue(BaseModel):
93
+ """
94
+ For parameters that are files on disk.
95
+
96
+ "Raw" in the sense that it still has the `__file__`-level dictionary.
97
+ """
98
+
99
+ objectKey: str
100
+ bucket: str = "doesn't_matter"
101
+
102
+ @model_serializer
103
+ def file_dict(self) -> dict:
104
+ """Wrap the input values in a `__file__` dict."""
105
+ return {"__file__": dict(self)}
106
+
107
+
108
+ class TestParameterValues(BaseModel):
109
+ test_random_data: multi_file_type = RawFileParameterValue(objectKey="")
110
+ test_wavelength_category: multi_wave_type = WavelengthParameterValue(
111
+ values=("one", "two", "three")
112
+ )
113
+ test_message: multi_str_type = "Weird?"
114
+ test_message_file: multi_file_type = RawFileParameterValue(objectKey="")
115
+
116
+ model_config = ConfigDict(validate_default=True)
117
+
118
+ @field_validator("*")
119
+ @classmethod
120
+ def ensure_parameter_value_lists(cls, parameter: Any) -> MultipleParameterValues:
121
+ """Convert all values to `MultipleParameterValues`, if they aren't already."""
122
+ if not isinstance(parameter, MultipleParameterValues):
123
+ return MultipleParameterValues(parameter_value_list=[parameter])
124
+
125
+ return parameter
126
+
127
+ @model_serializer
128
+ def input_dataset_document_parameters_part(self) -> list:
129
+ """Place all parameters into higher-level dictionaries required by the input dataset document."""
130
+ return [{"parameterName": f, "parameterValues": v} for f, v in self]
@@ -1,3 +1,4 @@
1
+ import json
1
2
  from datetime import datetime
2
3
 
3
4
  import numpy as np
@@ -9,16 +10,16 @@ from dkist_processing_test.models.parameters import TestParameters
9
10
 
10
11
 
11
12
  @pytest.fixture(scope="session")
12
- def file_parameter(
13
- tmp_path_factory, random_parameter_hdulist, parameter_file_object_key
13
+ def array_file_parameter(
14
+ tmp_path_factory, random_parameter_hdulist, array_parameter_file_object_key
14
15
  ) -> tuple[InputDatasetParameterValue, float, float, float]:
15
16
  hdul, mu, std, const = random_parameter_hdulist
16
- file_path = tmp_path_factory.mktemp("parameters") / parameter_file_object_key
17
+ file_path = tmp_path_factory.mktemp("parameters") / array_parameter_file_object_key
17
18
  hdul.writeto(file_path)
18
19
 
19
20
  value = {
20
21
  "bucket": "raw",
21
- "objectKey": parameter_file_object_key,
22
+ "objectKey": array_parameter_file_object_key,
22
23
  "param_path": file_path,
23
24
  "is_file": True,
24
25
  }
@@ -31,12 +32,48 @@ def file_parameter(
31
32
  return parameter_value, mu, std, const
32
33
 
33
34
 
35
+ @pytest.fixture(scope="session")
36
+ def message_file_parameter(
37
+ tmp_path_factory, early_file_message_str, early_json_parameter_file_object_key
38
+ ):
39
+
40
+ file_path = tmp_path_factory.mktemp("parameters") / early_json_parameter_file_object_key
41
+ with open(file_path, "w") as f:
42
+ json.dump(early_file_message_str, f)
43
+
44
+ value = {
45
+ "bucket": "raw",
46
+ "objectKey": early_json_parameter_file_object_key,
47
+ "param_path": file_path,
48
+ "is_file": True,
49
+ }
50
+
51
+ parameter_value = InputDatasetParameterValue(
52
+ parameter_value_id=2,
53
+ parameter_value=value,
54
+ parameter_value_start_date=datetime(1946, 11, 20),
55
+ )
56
+ return parameter_value
57
+
58
+
59
+ @pytest.fixture(scope="session")
60
+ def message_parameter(early_value_message_str):
61
+
62
+ parameter_value = InputDatasetParameterValue(
63
+ parameter_value_id=3,
64
+ parameter_value=early_value_message_str,
65
+ parameter_value_start_date=datetime(1946, 11, 20),
66
+ )
67
+
68
+ return parameter_value
69
+
70
+
34
71
  @pytest.fixture(scope="session")
35
72
  def wavelength_parameter() -> InputDatasetParameterValue:
36
73
  value = {"wavelength": [1.0, 2.0, 3.0], "values": ["one", "two", "three"]}
37
74
 
38
75
  parameter_value = InputDatasetParameterValue(
39
- parameter_value_id=2,
76
+ parameter_value_id=4,
40
77
  parameter_value=value,
41
78
  parameter_value_start_date=datetime(1946, 11, 20),
42
79
  )
@@ -44,12 +81,16 @@ def wavelength_parameter() -> InputDatasetParameterValue:
44
81
 
45
82
 
46
83
  @pytest.fixture(scope="session")
47
- def parameter_dict_with_path(file_parameter, wavelength_parameter):
84
+ def parameter_dict_with_path(
85
+ array_file_parameter, message_file_parameter, message_parameter, wavelength_parameter
86
+ ):
48
87
  """Enough of an input dataset parameters part to exercise file loading parameters."""
49
- file_parameter_value, _, _, _ = file_parameter
88
+ file_parameter_value, _, _, _ = array_file_parameter
50
89
 
51
90
  param_dict = {
52
91
  "test_random_data": [file_parameter_value],
92
+ "test_message": [message_parameter],
93
+ "test_message_file": [message_file_parameter],
53
94
  "test_wavelength_category": [wavelength_parameter],
54
95
  }
55
96
 
@@ -87,17 +128,24 @@ def task_with_parameters(parameter_dict_with_path):
87
128
  return task
88
129
 
89
130
 
90
- def test_parameter(task_with_parameters, file_parameter):
131
+ def test_parameter(
132
+ task_with_parameters,
133
+ array_file_parameter,
134
+ early_file_message_str,
135
+ early_value_message_str,
136
+ ):
91
137
  """
92
138
  Given: A task with parameters that depend on files
93
139
  When: Accessing those parameters
94
140
  Then: The correct values are returned
95
141
  """
96
142
  task = task_with_parameters
97
- _, mu, std, const = file_parameter
143
+ _, mu, std, const = array_file_parameter
98
144
 
99
145
  assert type(task.parameters.randomness) is tuple
100
146
  np.testing.assert_allclose(np.array(task.parameters.randomness), np.array([mu, std]), rtol=1)
101
147
 
102
148
  assert task.parameters.constant == const
103
149
  assert task.parameters.wavelength_category == "two"
150
+ assert task.parameters.value_message == early_value_message_str
151
+ assert task.parameters.file_message == early_file_message_str
@@ -6,8 +6,8 @@ from dataclasses import asdict
6
6
  from dataclasses import dataclass
7
7
  from dataclasses import is_dataclass
8
8
  from datetime import datetime
9
+ from datetime import timedelta
9
10
  from random import randint
10
- from typing import Type
11
11
  from uuid import uuid4
12
12
 
13
13
  import numpy as np
@@ -18,11 +18,12 @@ from dkist_header_validator import spec122_validator
18
18
  from dkist_processing_common._util.scratch import WorkflowFileSystem
19
19
  from dkist_processing_common.codecs.fits import fits_hdu_decoder
20
20
  from dkist_processing_common.codecs.fits import fits_hdulist_encoder
21
+ from dkist_processing_common.codecs.json import json_encoder
21
22
  from dkist_processing_common.models.constants import BudName
22
23
  from dkist_processing_common.models.constants import ConstantsBase
23
24
  from dkist_processing_common.models.tags import Tag
24
25
  from dkist_processing_common.models.task_name import TaskName
25
- from dkist_processing_common.tasks import QualityL0Metrics
26
+ from dkist_processing_common.tasks import TransferTrialData
26
27
  from dkist_processing_common.tests.conftest import FakeGQLClient
27
28
  from dkist_service_configuration.logging import logger
28
29
 
@@ -34,16 +35,19 @@ from dkist_processing_test.tasks.fake_science import GenerateCalibratedData
34
35
  from dkist_processing_test.tasks.movie import AssembleTestMovie
35
36
  from dkist_processing_test.tasks.movie import MakeTestMovieFrames
36
37
  from dkist_processing_test.tasks.noop import NoOpTask
37
- from dkist_processing_test.tasks.trial_output_data import TransferTestTrialData
38
38
  from dkist_processing_test.tasks.write_l1 import WriteL1Data
39
39
  from dkist_processing_test.tests.conftest import generate_214_l0_fits_frame
40
40
  from dkist_processing_test.tests.conftest import S122Headers
41
+ from dkist_processing_test.tests.parameter_models import MultipleParameterValues
42
+ from dkist_processing_test.tests.parameter_models import ParameterValue
43
+ from dkist_processing_test.tests.parameter_models import RawFileParameterValue
44
+ from dkist_processing_test.tests.parameter_models import TestParameterValues
41
45
 
42
46
 
43
47
  @dataclass
44
48
  class FakeConstantDb:
45
49
  NUM_DSPS_REPEATS: int = 2
46
- OBS_IP_START_TIME: str = "2024-06-12T12:00:00"
50
+ OBS_IP_START_TIME: str = "1990-06-12T12:00:00"
47
51
  INSTRUMENT: str = "TEST"
48
52
  AVERAGE_CADENCE: float = 10.0
49
53
  MINIMUM_CADENCE: float = 10.0
@@ -94,12 +98,25 @@ def generate_calibrated_data_task(
94
98
  recipe_run_id,
95
99
  assign_input_dataset_doc_to_task,
96
100
  link_constants_db,
97
- parameter_file_object_key,
101
+ array_parameter_file_object_key,
98
102
  random_parameter_hdulist,
103
+ early_json_parameter_file_object_key,
104
+ early_file_message_str,
105
+ late_json_parameter_file_object_key,
106
+ late_file_message_str,
107
+ early_or_late,
108
+ late_date,
99
109
  ):
100
110
  number_of_frames = 10
111
+ if early_or_late == "early":
112
+ obs_ip_start_time_str = (datetime.fromisoformat(late_date) - timedelta(days=30)).isoformat()
113
+ elif early_or_late == "late":
114
+ obs_ip_start_time_str = (datetime.fromisoformat(late_date) + timedelta(days=30)).isoformat()
101
115
  link_constants_db(
102
- recipe_run_id=recipe_run_id, constants_obj=FakeConstantDb(NUM_DSPS_REPEATS=number_of_frames)
116
+ recipe_run_id=recipe_run_id,
117
+ constants_obj=FakeConstantDb(
118
+ NUM_DSPS_REPEATS=number_of_frames, OBS_IP_START_TIME=obs_ip_start_time_str
119
+ ),
103
120
  )
104
121
  with GenerateCalibratedData(
105
122
  recipe_run_id=recipe_run_id, workflow_name="GenerateCalibratedData", workflow_version="VX.Y"
@@ -125,13 +142,25 @@ def generate_calibrated_data_task(
125
142
  data=hdul, tags=Tag.input(), relative_path=file_name, encoder=fits_hdulist_encoder
126
143
  )
127
144
 
128
- # Write parameter file
145
+ # Write parameter files
129
146
  hdul = random_parameter_hdulist[0]
130
147
  task.write(
131
- data=hdul, tags=Tag.parameter(parameter_file_object_key), encoder=fits_hdulist_encoder
148
+ data=hdul,
149
+ tags=Tag.parameter(array_parameter_file_object_key),
150
+ encoder=fits_hdulist_encoder,
151
+ )
152
+ task.write(
153
+ data=early_file_message_str,
154
+ tags=Tag.parameter(early_json_parameter_file_object_key),
155
+ encoder=json_encoder,
156
+ )
157
+ task.write(
158
+ data=late_file_message_str,
159
+ tags=Tag.parameter(late_json_parameter_file_object_key),
160
+ encoder=json_encoder,
132
161
  )
133
162
 
134
- # This needs to be after we've tagged the parameter file
163
+ # This needs to be after we've written and tagged the parameter files
135
164
  assign_input_dataset_doc_to_task(task, obs_ip_start_time=task.constants.obs_ip_start_time)
136
165
 
137
166
  # result
@@ -142,55 +171,61 @@ def generate_calibrated_data_task(
142
171
 
143
172
 
144
173
  @pytest.fixture(scope="session")
145
- def input_dataset_document_parameters_part_with_file(parameter_file_object_key):
146
- param_name = "test_random_data"
147
- value = {
148
- "__file__": {"bucket": "foo", "objectKey": parameter_file_object_key},
149
- }
150
- value_id = randint(1000, 2000)
151
- values = [
152
- {
153
- "parameterValueId": value_id,
154
- "parameterValue": json.dumps(value),
155
- "parameterValueStartDate": "1946-11-20",
156
- }
157
- ]
158
- parameter = {"parameterName": param_name, "parameterValues": values}
159
- parameters_list = [parameter]
174
+ def input_dataset_document_parameters_part_json(
175
+ array_parameter_file_object_key,
176
+ early_json_parameter_file_object_key,
177
+ late_json_parameter_file_object_key,
178
+ early_value_message_str,
179
+ late_value_message_str,
180
+ early_date,
181
+ late_date,
182
+ ):
160
183
 
161
- return parameters_list
184
+ message_file_values = MultipleParameterValues(
185
+ parameter_value_list=[
186
+ ParameterValue(
187
+ parameterValue=RawFileParameterValue(
188
+ objectKey=early_json_parameter_file_object_key
189
+ ),
190
+ parameterValueStartDate=early_date,
191
+ ),
192
+ ParameterValue(
193
+ parameterValue=RawFileParameterValue(objectKey=late_json_parameter_file_object_key),
194
+ parameterValueStartDate=late_date,
195
+ ),
196
+ ]
197
+ )
198
+ message_value_values = MultipleParameterValues(
199
+ parameter_value_list=[
200
+ ParameterValue(
201
+ parameterValue=early_value_message_str,
202
+ parameterValueStartDate=early_date,
203
+ ),
204
+ ParameterValue(
205
+ parameterValue=late_value_message_str,
206
+ parameterValueStartDate=late_date,
207
+ ),
208
+ ]
209
+ )
210
+ parameters_obj = TestParameterValues(
211
+ test_random_data=RawFileParameterValue(objectKey=array_parameter_file_object_key),
212
+ test_message_file=message_file_values,
213
+ test_message=message_value_values,
214
+ )
162
215
 
216
+ part_json_str = parameters_obj.model_dump_json()
163
217
 
164
- @pytest.fixture(scope="session")
165
- def input_dataset_document_parameters_part_with_wavelength():
166
- param_name = "test_wavelength_category"
167
- value = {"wavelength": [1.0, 2.0, 3.0], "values": ["one", "two", "three"]}
168
- value_id = randint(2000, 3000)
169
- values = [
170
- {
171
- "parameterValueId": value_id,
172
- "parameterValue": json.dumps(value),
173
- "parameterValueStartDate": "1946-11-20",
174
- }
175
- ]
176
- parameter = {"parameterName": param_name, "parameterValues": values}
177
- parameter_list = [parameter]
178
- return parameter_list
218
+ return part_json_str
179
219
 
180
220
 
181
221
  @pytest.fixture(scope="session")
182
222
  def assign_input_dataset_doc_to_task(
183
- input_dataset_document_parameters_part_with_file,
184
- input_dataset_document_parameters_part_with_wavelength,
223
+ input_dataset_document_parameters_part_json,
185
224
  ):
186
225
  def update_task(task, obs_ip_start_time=None):
187
226
  doc_path = task.scratch.workflow_base_path / "dataset_parameters.json"
188
- full_parameters = (
189
- input_dataset_document_parameters_part_with_file
190
- + input_dataset_document_parameters_part_with_wavelength
191
- )
192
227
  with open(doc_path, "w") as f:
193
- f.write(json.dumps(full_parameters))
228
+ f.write(input_dataset_document_parameters_part_json)
194
229
  task.tag(doc_path, Tag.input_dataset_parameters())
195
230
  task.parameters = TestParameters(
196
231
  task.input_dataset_parameters, wavelength=2.0, obs_ip_start_time=obs_ip_start_time
@@ -214,7 +249,16 @@ def constants_linker(recipe_run_id: int, constants_obj):
214
249
  return
215
250
 
216
251
 
217
- def test_generate_calibrated_data(generate_calibrated_data_task, mocker):
252
+ @pytest.mark.parametrize("early_or_late", [pytest.param("early"), pytest.param("late")])
253
+ def test_generate_calibrated_data(
254
+ generate_calibrated_data_task,
255
+ early_file_message_str,
256
+ late_file_message_str,
257
+ early_value_message_str,
258
+ late_value_message_str,
259
+ early_or_late,
260
+ mocker,
261
+ ):
218
262
  """
219
263
  Given: A GenerateCalibratedData task
220
264
  When: Calling the task instance
@@ -230,12 +274,23 @@ def test_generate_calibrated_data(generate_calibrated_data_task, mocker):
230
274
  task.read(tags=[Tag.calibrated(), Tag.frame()], decoder=fits_hdu_decoder)
231
275
  )
232
276
 
277
+ if early_or_late == "early":
278
+ expected_file_message = early_file_message_str
279
+ expected_value_message = early_value_message_str
280
+ elif early_or_late == "late":
281
+ expected_file_message = late_file_message_str
282
+ expected_value_message = late_value_message_str
283
+
233
284
  # Verify frames
234
285
  assert len(calibrated_frame_hdus) == number_of_frames
235
286
  for hdu in calibrated_frame_hdus:
236
287
  assert "VBINMOSC" in hdu.header
237
288
  assert "VBICMOSC" in hdu.header
238
289
 
290
+ # Verify correct date params were used
291
+ assert hdu.header["CAM_ID"] == expected_file_message
292
+ assert hdu.header["CAMERA"] == expected_value_message
293
+
239
294
  # Verify debug frame was written
240
295
  debug_frame_paths = list(task.read(tags=[Tag.debug(), Tag.frame()]))
241
296
  assert len(debug_frame_paths) == 1
@@ -606,7 +661,7 @@ def trial_output_task(recipe_run_id, tmp_path, mocker):
606
661
  new=FakeGQLClient,
607
662
  )
608
663
  proposal_id = "test_proposal_id"
609
- with TransferTestTrialData(
664
+ with TransferTrialData(
610
665
  recipe_run_id=recipe_run_id,
611
666
  workflow_name="workflow_name",
612
667
  workflow_version="workflow_version",
@@ -623,21 +678,14 @@ def trial_output_task(recipe_run_id, tmp_path, mocker):
623
678
  task.write(debug_file_obj, tags=[Tag.debug(), Tag.frame()])
624
679
  file_count += 1
625
680
 
626
- # Write an intermediate frame that we want to transfer
627
- intermediate_keep_file_obj = uuid4().hex.encode("utf8")
681
+ # Write an intermediate frame
682
+ intermediate_file_obj = uuid4().hex.encode("utf8")
628
683
  task.write(
629
- intermediate_keep_file_obj,
684
+ intermediate_file_obj,
630
685
  tags=[Tag.intermediate(), Tag.frame(), Tag.task("DUMMY")],
631
686
  )
632
687
  file_count += 1
633
688
 
634
- # Write an intermediate frame that we don't want to transfer
635
- intermediate_discard_file_obj = uuid4().hex.encode("utf8")
636
- task.write(
637
- intermediate_discard_file_obj,
638
- tags=[Tag.intermediate(), Tag.frame(), Tag.task("WHO_CARES")],
639
- )
640
-
641
689
  # An output frame
642
690
  output_file_obj = uuid4().hex.encode("utf8")
643
691
  task.write(output_file_obj, tags=[Tag.output(), Tag.frame()])
@@ -668,12 +716,6 @@ def trial_output_task(recipe_run_id, tmp_path, mocker):
668
716
  task.write(quality_report_file_obj, tags=[Tag.output(), Tag.quality_report()])
669
717
  file_count += 1
670
718
 
671
- # Specifically tagged files
672
- task.write(uuid4().hex.encode("utf8"), tags=[Tag.frame(), "FOO", "BAR"])
673
- file_count += 1
674
- task.write(uuid4().hex.encode("utf8"), tags=[Tag.frame(), "BAZ"])
675
- file_count += 1
676
-
677
719
  # This one won't get transferred
678
720
  task.write(uuid4().hex.encode("utf8"), tags=[Tag.frame(), "FOO"])
679
721
 
@@ -683,7 +725,7 @@ def trial_output_task(recipe_run_id, tmp_path, mocker):
683
725
 
684
726
  def test_transfer_test_trial_data(trial_output_task, mocker):
685
727
  """
686
- Given: A TransferTestTrialData task with associated frames
728
+ Given: A TransferTrialData task with associated frames
687
729
  When: Running the task and building the transfer list
688
730
  Then: No errors occur and the transfer list has the correct number of items
689
731
  """
@@ -693,7 +735,7 @@ def test_transfer_test_trial_data(trial_output_task, mocker):
693
735
  "dkist_processing_common.tasks.mixin.globus.GlobusMixin.globus_transfer_scratch_to_object_store"
694
736
  )
695
737
  mocker.patch(
696
- "dkist_processing_test.tasks.trial_output_data.TransferTestTrialData.remove_folder_objects"
738
+ "dkist_processing_common.tasks.trial_output_data.TransferTrialData.remove_folder_objects"
697
739
  )
698
740
 
699
741
  # Just make sure the thing runs with no errors
@@ -10,6 +10,7 @@ from dkist_processing_common.tasks import SubmitDatasetMetadata
10
10
  from dkist_processing_common.tasks import Teardown
11
11
  from dkist_processing_common.tasks import TransferL0Data
12
12
  from dkist_processing_common.tasks import TransferL1Data
13
+ from dkist_processing_common.tasks import TransferTrialData
13
14
  from dkist_processing_common.tasks import TrialTeardown
14
15
  from dkist_processing_core import Workflow
15
16
 
@@ -19,7 +20,6 @@ from dkist_processing_test.tasks import MakeTestMovieFrames
19
20
  from dkist_processing_test.tasks import ParseL0TestInputData
20
21
  from dkist_processing_test.tasks import TestAssembleQualityData
21
22
  from dkist_processing_test.tasks import TestQualityL0Metrics
22
- from dkist_processing_test.tasks import TransferTestTrialData
23
23
  from dkist_processing_test.tasks import WriteL1Data
24
24
  from dkist_processing_test.tasks.manual import ManualWithoutProvenance
25
25
  from dkist_processing_test.tasks.manual import ManualWithProvenance
@@ -132,7 +132,7 @@ transfer_trial_data = Workflow(
132
132
  detail="transfer-trial-data",
133
133
  workflow_package=__package__,
134
134
  )
135
- transfer_trial_data.add_node(task=TransferTestTrialData, upstreams=None)
135
+ transfer_trial_data.add_node(task=TransferTrialData, upstreams=None)
136
136
 
137
137
  # SubmitDatasetMetadata Task
138
138
  submit_dataset_metadata = Workflow(
@@ -6,6 +6,7 @@ from dkist_processing_common.tasks import CreateTrialDatasetInventory
6
6
  from dkist_processing_common.tasks import CreateTrialQualityReport
7
7
  from dkist_processing_common.tasks import QualityL1Metrics
8
8
  from dkist_processing_common.tasks import TransferL0Data
9
+ from dkist_processing_common.tasks import TransferTrialData
9
10
  from dkist_processing_common.tasks import TrialTeardown
10
11
  from dkist_processing_core import Workflow
11
12
 
@@ -15,7 +16,6 @@ from dkist_processing_test.tasks import MakeTestMovieFrames
15
16
  from dkist_processing_test.tasks import ParseL0TestInputData
16
17
  from dkist_processing_test.tasks import TestAssembleQualityData
17
18
  from dkist_processing_test.tasks import TestQualityL0Metrics
18
- from dkist_processing_test.tasks import TransferTestTrialData
19
19
  from dkist_processing_test.tasks import WriteL1Data
20
20
 
21
21
  trial = Workflow(
@@ -51,7 +51,7 @@ trial.add_node(
51
51
 
52
52
  # Output flow
53
53
  trial.add_node(
54
- task=TransferTestTrialData,
54
+ task=TransferTrialData,
55
55
  upstreams=[
56
56
  CreateTrialDatasetInventory,
57
57
  CreateTrialAsdf,
@@ -61,4 +61,4 @@ trial.add_node(
61
61
  )
62
62
 
63
63
  # goodby
64
- trial.add_node(task=TrialTeardown, upstreams=TransferTestTrialData)
64
+ trial.add_node(task=TrialTeardown, upstreams=TransferTrialData)
@@ -1,8 +1,8 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: dkist-processing-test
3
- Version: 1.21.3rc1
3
+ Version: 1.23.8rc1
4
4
  Summary: Example instrument code used by the DKIST science data processing pipelines to test processing infrastructure
5
- Author: NSO / AURA
5
+ Author-email: NSO / AURA <dkistdc@nso.edu>
6
6
  License: BSD-3-Clause
7
7
  Project-URL: Homepage, https://nso.edu/dkist/data-center/
8
8
  Project-URL: Repository, https://bitbucket.org/dkistdc/dkist-processing-test/
@@ -12,31 +12,31 @@ Classifier: Programming Language :: Python :: 3
12
12
  Classifier: Programming Language :: Python :: 3.11
13
13
  Requires-Python: >=3.11
14
14
  Description-Content-Type: text/x-rst
15
- Requires-Dist: dkist-processing-common ==10.2.2rc1
16
- Requires-Dist: dkist-header-validator ==5.1.1
17
- Requires-Dist: dkist-service-configuration ==2.2
18
- Requires-Dist: dkist-fits-specifications ==4.7.0
19
- Requires-Dist: numba ==0.59.1
20
- Requires-Dist: astropy ==6.1.0
21
- Requires-Dist: numpy ==1.26.4
22
- Requires-Dist: dkist-spectral-lines ==3.0.0
23
- Provides-Extra: asdf
24
- Requires-Dist: dkist-processing-common[asdf] ; extra == 'asdf'
25
- Requires-Dist: dkist-inventory[asdf] ==1.4.0 ; extra == 'asdf'
15
+ Requires-Dist: dkist-processing-common==10.5.6
16
+ Requires-Dist: dkist-header-validator==5.1.1
17
+ Requires-Dist: dkist-service-configuration==2.2
18
+ Requires-Dist: dkist-fits-specifications==4.10.0
19
+ Requires-Dist: numba==0.59.1
20
+ Requires-Dist: astropy==6.1.0
21
+ Requires-Dist: numpy==1.26.4
22
+ Requires-Dist: dkist-spectral-lines==3.0.0
23
+ Provides-Extra: test
24
+ Requires-Dist: pytest; extra == "test"
25
+ Requires-Dist: pytest-xdist; extra == "test"
26
+ Requires-Dist: pytest-cov; extra == "test"
27
+ Requires-Dist: pytest-mock; extra == "test"
28
+ Requires-Dist: dkist-data-simulator>=5.2.0; extra == "test"
29
+ Requires-Dist: dkist-processing-test[inventory]; extra == "test"
30
+ Requires-Dist: dkist-processing-test[asdf]; extra == "test"
31
+ Requires-Dist: dkist-processing-test[quality]; extra == "test"
26
32
  Provides-Extra: inventory
27
- Requires-Dist: dkist-processing-common[inventory] ; extra == 'inventory'
28
- Requires-Dist: dkist-inventory ==1.4.0 ; extra == 'inventory'
33
+ Requires-Dist: dkist-processing-common[inventory]; extra == "inventory"
34
+ Requires-Dist: dkist-inventory==1.5.0rc1; extra == "inventory"
35
+ Provides-Extra: asdf
36
+ Requires-Dist: dkist-processing-common[asdf]; extra == "asdf"
37
+ Requires-Dist: dkist-inventory[asdf]==1.5.0rc1; extra == "asdf"
29
38
  Provides-Extra: quality
30
- Requires-Dist: dkist-quality ==1.1.1 ; extra == 'quality'
31
- Provides-Extra: test
32
- Requires-Dist: pytest ; extra == 'test'
33
- Requires-Dist: pytest-xdist ; extra == 'test'
34
- Requires-Dist: pytest-cov ; extra == 'test'
35
- Requires-Dist: pytest-mock ; extra == 'test'
36
- Requires-Dist: dkist-data-simulator >=5.2.0 ; extra == 'test'
37
- Requires-Dist: dkist-processing-test[inventory] ; extra == 'test'
38
- Requires-Dist: dkist-processing-test[asdf] ; extra == 'test'
39
- Requires-Dist: dkist-processing-test[quality] ; extra == 'test'
39
+ Requires-Dist: dkist-quality==1.2.0; extra == "quality"
40
40
 
41
41
  dkist-processing-test
42
42
  ---------------------
@@ -2,33 +2,33 @@ dkist_processing_test/__init__.py,sha256=t-Daj1wOIg5dgI1gklg6suSnI-xi6DKSb6DxHDW
2
2
  dkist_processing_test/config.py,sha256=LF80ReTk0ggJ3eZI4NZRZCgmR6E84adWU5iP6-JN-XY,383
3
3
  dkist_processing_test/models/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
4
  dkist_processing_test/models/constants.py,sha256=TxHYZHl3YQXN7-Voj7QgjgAajbxxB_qR8tRI9iTdERI,726
5
- dkist_processing_test/models/parameters.py,sha256=5lUvGEmPh5JnGeLpJTpzrIao56bpRSyvfFZsRoONwYg,1256
6
- dkist_processing_test/tasks/__init__.py,sha256=ZWoqlNgFrn2auTMGNX9YWmHW_3JwQzn04XE_FmCAU24,517
5
+ dkist_processing_test/models/parameters.py,sha256=OLrS1O_xZptjdNW882Otx5cHWyd4FH7nzi8fkZnj9GM,1778
6
+ dkist_processing_test/tasks/__init__.py,sha256=mzbjxWY9fdNKUyfXDC_vXuSaB7G0-iwrumCUlq6keoA,457
7
7
  dkist_processing_test/tasks/exercise_numba.py,sha256=XfMVffPUgeiPoxSgo39tIjzFBJKKt3fnIYGaDFyBibc,1437
8
8
  dkist_processing_test/tasks/fail.py,sha256=jiOiuqoX_JR5hx81REgvcSvb0GBlVKc9MIXKUO0Nhr4,245
9
- dkist_processing_test/tasks/fake_science.py,sha256=Hon9h5TYc3fuHerm_1uLW2gNr4Y3W0oBN3nmIy4qw-M,4082
9
+ dkist_processing_test/tasks/fake_science.py,sha256=-DMjAtQbtTly0PAv78lIgD8T_HVMo5mmBjyLiYQF0Ko,4555
10
10
  dkist_processing_test/tasks/high_memory.py,sha256=J3vBsivFkqs8eZZwBPpEORlHnFX1bGsbO3CjllJMRsc,540
11
11
  dkist_processing_test/tasks/manual.py,sha256=gjol_EieMbclv0ZDkVqR2Xd7abutali6KNwoqaCJiAI,583
12
12
  dkist_processing_test/tasks/movie.py,sha256=uFPWQlRFP5zzzYGT58IXebbG49su2I4AEpN2bIy7vGc,1831
13
13
  dkist_processing_test/tasks/noop.py,sha256=txgpa0DYrjYPKBDfwfjHt7X9Dna4yaJeMCabu3p2Zmo,235
14
14
  dkist_processing_test/tasks/parse.py,sha256=4bDKnPaWeZkQbUpYWCWk1O-Fjzu6WWRboFef3NFJDMs,2713
15
15
  dkist_processing_test/tasks/quality.py,sha256=9QynI9R5mkYueb46wNBUhK62QSd2n791L0_w6nVxBjc,895
16
- dkist_processing_test/tasks/trial_output_data.py,sha256=T34kGFxyR0IVaYnJhP3s9kv1_ExSNlnxx0n76cN32NU,1553
17
16
  dkist_processing_test/tasks/write_l1.py,sha256=lpNyCI3kH_pnL0Wi1LHhNRjRHNxu6q76xccCNHm7uwA,2074
18
17
  dkist_processing_test/tests/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
- dkist_processing_test/tests/conftest.py,sha256=UhtnrZUgbfX738Ej2MhxZMIjimHnUipfQbGxCLSaH8k,1939
20
- dkist_processing_test/tests/test_parameters.py,sha256=nh8znKVxFhC46LYNi-DkhV24LFYTfFQI0duV0DwNoHs,3164
21
- dkist_processing_test/tests/test_tasks.py,sha256=Yvjw8ImQO4QudC5F969LQZMoFT_959CYsldFnZh5r10,25388
18
+ dkist_processing_test/tests/conftest.py,sha256=9H8_tqNKofHnl1IRqYM2-M2_K_TJ3b6oaIfb1dVkbsg,2728
19
+ dkist_processing_test/tests/parameter_models.py,sha256=c-SqCBqHP4KkFs0_Y7HLED4mH4oMCpAYu-rYVlTHy1M,4635
20
+ dkist_processing_test/tests/test_parameters.py,sha256=KGeEUOhtC_l-LN6hjB2jgwUZIWAMBx8wlmEeIja-eKo,4572
21
+ dkist_processing_test/tests/test_tasks.py,sha256=woNEolAfahLowR7T9nTaZgNJidkGmGpfU6Xyc4LXbqQ,26857
22
22
  dkist_processing_test/tests/test_workflows.py,sha256=NqRkstqcqwH80cKJ1uDw16G4MsDOuOiZRWdfH0STarQ,286
23
23
  dkist_processing_test/workflows/__init__.py,sha256=Ryn_HXsVkZM_lLKyVteXC909Td2geylmz_1Z-8SE8c8,78
24
- dkist_processing_test/workflows/common_tasks.py,sha256=4H1TaUNa5-HyE1NJQiAc3NAN62ZOTYb7MbR1yjKMg-k,6843
24
+ dkist_processing_test/workflows/common_tasks.py,sha256=UpUTt-QhD-jkzBB3p1ECRbtqY3wjP6Lfsy4TdvxZKQ8,6837
25
25
  dkist_processing_test/workflows/end_to_end.py,sha256=XzSe7XtPF0e3fLXWL90LOZ0WKCoCKA4SL43N0CzgpCQ,2328
26
26
  dkist_processing_test/workflows/exercise_numba.py,sha256=phpPYcIXEsmc0X1yls_YbXoKS6VXxhHe_8vNd_GyajU,347
27
27
  dkist_processing_test/workflows/fail.py,sha256=KGhyAF7gKYYutP4aGa-1tDqPsC7Nr4xKYY0z-HByWi0,326
28
28
  dkist_processing_test/workflows/noop.py,sha256=k2-6BpRkl1JDGaHPavxDzIlVx11KQtxKmsHmHTNQ9o0,666
29
29
  dkist_processing_test/workflows/resource_queue.py,sha256=_jOT99O0MFN_ACne6i8T5ZIwe_lBQqGz2Ccb8JlqQMI,500
30
- dkist_processing_test/workflows/trial_end_to_end.py,sha256=wkl_gk0zQ5TJ41CY0gEREPSIldZdTtLGwPDL_iwObe4,2425
31
- dkist_processing_test-1.21.3rc1.dist-info/METADATA,sha256=VPKAoUacF_IyHXh0vT4vbORjlu0zWX_ErDBmX2ddhbQ,3274
32
- dkist_processing_test-1.21.3rc1.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
33
- dkist_processing_test-1.21.3rc1.dist-info/top_level.txt,sha256=Hs4oTIrG_r-svhk_RGFTEO4e3vqQoYlBzdv5mvJVF24,22
34
- dkist_processing_test-1.21.3rc1.dist-info/RECORD,,
30
+ dkist_processing_test/workflows/trial_end_to_end.py,sha256=4QSphBegbetDben5PdA5_J64hWJVV8ciVdF90qkyZCo,2415
31
+ dkist_processing_test-1.23.8rc1.dist-info/METADATA,sha256=qknfhMMDgkZuP1az_oncgF5cizxLlmIw_b7NX96Ys8Y,3277
32
+ dkist_processing_test-1.23.8rc1.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
33
+ dkist_processing_test-1.23.8rc1.dist-info/top_level.txt,sha256=Hs4oTIrG_r-svhk_RGFTEO4e3vqQoYlBzdv5mvJVF24,22
34
+ dkist_processing_test-1.23.8rc1.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.1.0)
2
+ Generator: setuptools (75.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,46 +0,0 @@
1
- """Trial tasks"""
2
- from dkist_processing_common.tasks.mixin.globus import GlobusTransferItem
3
- from dkist_processing_common.tasks.trial_output_data import TransferTrialDataBase
4
- from dkist_service_configuration.logging import logger
5
-
6
- __all__ = ["TransferTestTrialData"]
7
-
8
-
9
- class TransferTestTrialData(TransferTrialDataBase):
10
- @property
11
- def intermediate_task_names(self) -> list[str]:
12
- """Return a list of intermediate tasks we want to transfer.
13
-
14
- Just a dummy task for testing.
15
- """
16
- return ["DUMMY"]
17
-
18
- def build_transfer_list(self) -> list[GlobusTransferItem]:
19
- """
20
- Build a list containing all files we want to transfer to the trial environment.
21
-
22
- For the purposes of testing we try to exercise all of the provided helper methods.
23
- """
24
- transfer_list = []
25
-
26
- transfer_list += self.build_debug_frame_transfer_list()
27
-
28
- transfer_list += self.build_intermediate_frame_transfer_list()
29
-
30
- transfer_list += self.build_output_frame_transfer_list()
31
-
32
- transfer_list += self.build_output_dataset_inventory_transfer_list()
33
-
34
- transfer_list += self.build_output_asdf_transfer_list()
35
-
36
- transfer_list += self.build_output_quality_data_transfer_list()
37
-
38
- transfer_list += self.build_output_quality_report_transfer_list()
39
-
40
- transfer_list += self.build_output_movie_transfer_list()
41
-
42
- transfer_list += self.build_transfer_list_from_tag_lists([["FOO", "BAR"], ["BAZ"]])
43
-
44
- logger.info(f"{transfer_list = }")
45
-
46
- return transfer_list